pax_global_header00006660000000000000000000000064152654746340014532gustar00rootroot0000000000000052 comment=6dd59b947a1eaab33040805eda3d7a5b18b5b7d8 pydantic-httpx2-6dd59b9/000077500000000000000000000000001526547463400152245ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/.github/000077500000000000000000000000001526547463400165645ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/.github/CONTRIBUTING.md000066400000000000000000000200401526547463400210110ustar00rootroot00000000000000# Contributing Thank you for being interested in contributing to HTTPX2. There are many ways you can contribute to the project: - Try HTTPX2 and [report bugs/issues you find](https://github.com/pydantic/httpx2/issues/new) - [Implement new features](https://github.com/pydantic/httpx2/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) - [Review Pull Requests of others](https://github.com/pydantic/httpx2/pulls) - Write documentation - Participate in discussions ## Reporting Bugs or Other Issues Found something that HTTPX2 should support? Stumbled upon some unexpected behaviour? Contributions should generally start out with [a discussion](https://github.com/pydantic/httpx2/discussions). Possible bugs and feature requests may be raised in the "Q&A" category. We can then determine if the discussion needs to be escalated into an "Issue" or not, or if we'd consider a pull request. Try to be more descriptive as you can and in case of a bug report, provide as much information as possible like: - OS platform - Python version - Installed dependencies and versions (`python -m pip freeze`) - Code snippet - Error traceback You should always try to reduce any examples to the *simplest possible case* that demonstrates the issue. Some possibly useful tips for narrowing down potential issues... - Does the issue exist on HTTP/1.1, or HTTP/2, or both? - Does the issue exist with `Client`, `AsyncClient`, or both? - When using `AsyncClient` does the issue exist when using `asyncio` or `trio`, or both? ## Development To start developing HTTPX2 create a **fork** of the [HTTPX2 repository](https://github.com/pydantic/httpx2) on GitHub. Then clone your fork with the following command replacing `YOUR-USERNAME` with your GitHub username: ```shell $ git clone https://github.com/YOUR-USERNAME/httpx2 ``` You can now install the project and its dependencies using: ```shell $ cd httpx2 $ scripts/install ``` ## Testing and Linting We use custom shell scripts to automate testing, linting, and documentation building workflow. To run the tests, use: ```shell $ scripts/test ``` You can run a single test script like this: ```shell $ scripts/test -- tests/test_multipart.py ``` To run the code auto-formatting: ```shell $ scripts/lint ``` Lastly, to run code checks separately (they are also run as part of `scripts/test`), run: ```shell $ scripts/check ``` ## Documenting Documentation pages are located under the `docs/` folder. To run the documentation site locally (useful for previewing changes), use: ```shell $ scripts/docs ``` ## Resolving Build / CI Failures Once you've submitted your pull request, the test suite will automatically run, and the results will show up in GitHub. If the test suite fails, you'll want to click through to the "Details" link, and try to identify why the test suite failed.

Failing PR commit status

Here are some common ways the test suite can fail: ### Check Job Failed

Failing GitHub action lint job

This job failing means there is either a code formatting issue or type-annotation issue. You can look at the job output to figure out why it's failed or within a shell run: ```shell $ scripts/check ``` It may be worth it to run `$ scripts/lint` to attempt auto-formatting the code and if that job succeeds commit the changes. ### Docs Job Failed This job failing means the documentation failed to build. This can happen for a variety of reasons like invalid markdown or missing configuration within `mkdocs.yml`. ### Python 3.X Job Failed

Failing GitHub action test job

This job failing means the unit tests failed or not all code paths are covered by unit tests. If tests are failing you will see this message under the coverage report: `=== 1 failed, 435 passed, 1 skipped, 1 xfailed in 11.09s ===` If tests succeed but coverage doesn't reach our current threshold, you will see this message under the coverage report: `FAIL Required test coverage of 100% not reached. Total coverage: 99.00%` ## Releasing *This section is targeted at HTTPX2 maintainers.* Before releasing a new version, create a pull request that includes: - **An update to the changelog**: - We follow the format from [keepachangelog](https://keepachangelog.com/en/1.0.0/). - [Compare](https://github.com/pydantic/httpx2/compare/) `main` with the tag of the latest release, and list all entries that are of interest to our users: - Things that **must** go in the changelog: added, changed, deprecated or removed features, and bug fixes. - Things that **should not** go in the changelog: changes to documentation, tests or tooling. - Try sorting entries in descending order of impact / importance. - Keep it concise and to-the-point. ๐ŸŽฏ - **A version bump**: the version is derived automatically from git tags via `uv-dynamic-versioning` โ€” no file edit needed, just ensure the tag is applied after the release PR merges. Once the release PR is merged, create a [new release](https://github.com/pydantic/httpx2/releases/new) including: - Tag version like `0.13.3`. - Release title `Version 0.13.3` - Description copied from the changelog. Once created this release will be automatically uploaded to PyPI. If something goes wrong with the PyPI job the release can be re-published using the `scripts/publish` script. ## Development proxy setup To test and debug requests via a proxy it's best to run a proxy server locally. Any server should do but [`mitmproxy`](https://mitmproxy.org/) is a good choice - it's written in Python, fully featured and has excellent UI and tools for introspection of requests. You can install `mitmproxy` using `pip install mitmproxy` or [several other ways](https://docs.mitmproxy.org/stable/overview-installation/). `mitmproxy` does require setting up local TLS certificates for HTTPS requests, as its main purpose is to allow developers to inspect requests that pass through it. We can set them up follows: 1. [`pip install trustme-cli`](https://github.com/sethmlarson/trustme-cli/). 2. `trustme-cli -i example.org www.example.org`, assuming you want to test connecting to that domain, this will create three files: `server.pem`, `server.key` and `client.pem`. 3. `mitmproxy` requires a PEM file that includes the private key and the certificate so we need to concatenate them: `cat server.key server.pem > server.withkey.pem`. 4. Start the proxy server `mitmproxy --certs server.withkey.pem`, or use the [other mitmproxy commands](https://docs.mitmproxy.org/stable/) with different UI options. At this point the server is ready to start serving requests, you'll need to configure HTTPX2 as described in the [proxy section](https://httpx2.pydantic.dev/advanced/proxies/#http-proxies) and the [SSL certificates section](https://httpx2.pydantic.dev/advanced/ssl/), this is where our previously generated `client.pem` comes in: ```python import ssl import httpx2 ctx = ssl.create_default_context(cafile="/path/to/client.pem") with httpx2.Client(proxy="http://127.0.0.1:8080/", verify=ctx) as client: response = client.get("https://example.org") print(response.status_code) # should print 200 ``` Note, however, that HTTPS requests will only succeed to the host specified in the SSL/TLS certificate we generated, HTTPS requests to other hosts will raise an error like: ``` ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Hostname mismatch, certificate is not valid for 'duckduckgo.com'. (_ssl.c:1108) ``` If you want to make requests to more hosts you'll need to regenerate the certificates and include all the hosts you intend to connect to in the seconds step, i.e. `trustme-cli -i example.org www.example.org duckduckgo.com www.duckduckgo.com` pydantic-httpx2-6dd59b9/.github/ISSUE_TEMPLATE/000077500000000000000000000000001526547463400207475ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/.github/ISSUE_TEMPLATE/1-issue.md000066400000000000000000000010521526547463400225550ustar00rootroot00000000000000--- name: Issue about: Please only raise an issue if you've been advised to do so after discussion. Thanks! ๐Ÿ™ --- The starting point for issues should usually be a discussion... https://github.com/pydantic/httpx2/discussions Possible bugs and feature requests may be raised in the "Q&A" discussion category. We can then determine if the discussion needs to be escalated into an "Issue" or not. This will help us ensure that the "Issues" list properly reflects ongoing or needed work on the project. --- - [ ] Initially raised as discussion #... pydantic-httpx2-6dd59b9/.github/ISSUE_TEMPLATE/config.yml000066400000000000000000000007731526547463400227460ustar00rootroot00000000000000# Ref: https://help.github.com/en/github/building-a-strong-community/configuring-issue-templates-for-your-repository#configuring-the-template-chooser blank_issues_enabled: false contact_links: - name: Discussions url: https://github.com/pydantic/httpx2/discussions about: > The "Discussions" forum is where you want to start. ๐Ÿ’– - name: ๐Ÿ’ฌ Join Slack url: https://logfire.pydantic.dev/docs/join-slack/ about: > Join our Slack community to ask questions, get help, and chat about HTTPX2. pydantic-httpx2-6dd59b9/.github/PULL_REQUEST_TEMPLATE.md000066400000000000000000000010401526547463400223600ustar00rootroot00000000000000 # Summary # Checklist - [ ] I understand that this PR may be closed in case there was no previous discussion. (This doesn't apply to typos!) - [ ] I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change. - [ ] I've updated the documentation accordingly. pydantic-httpx2-6dd59b9/.github/dependabot.yml000066400000000000000000000006351526547463400214200ustar00rootroot00000000000000version: 2 updates: - package-ecosystem: "uv" directory: "/" schedule: interval: "monthly" cooldown: default-days: 7 groups: python-packages: patterns: - "*" - package-ecosystem: "github-actions" directory: "/" schedule: interval: monthly cooldown: default-days: 7 groups: github-actions: patterns: - "*" pydantic-httpx2-6dd59b9/.github/workflows/000077500000000000000000000000001526547463400206215ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/.github/workflows/benchmark.yml000066400000000000000000000030431526547463400232760ustar00rootroot00000000000000name: CodSpeed on: push: branches: ["main"] pull_request: branches: ["main"] permissions: id-token: write contents: read jobs: benchmarks: name: Run benchmarks runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Install uv uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 with: python-version: "3.13" enable-cache: true - name: Install dependencies run: scripts/install shell: bash - name: Run the benchmarks uses: CodSpeedHQ/action@373d6868929f444bc08d901fd0eb0ad52a8875ea # v5.2.1 with: mode: instrumentation run: uv run pytest tests/test_benchmark.py --codspeed memory-benchmarks: name: Run memory benchmarks runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Install uv uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 with: python-version: "3.13" enable-cache: true - name: Install dependencies run: scripts/install shell: bash - name: Run the benchmarks uses: CodSpeedHQ/action@373d6868929f444bc08d901fd0eb0ad52a8875ea # v5.2.1 with: mode: memory run: uv run pytest tests/test_benchmark_memory.py --codspeed pydantic-httpx2-6dd59b9/.github/workflows/main.yml000066400000000000000000000040731526547463400222740ustar00rootroot00000000000000name: Test Suite on: push: branches: ["main"] pull_request: branches: ["main", "version-*"] permissions: contents: read jobs: tests: name: "Python ${{ matrix.python-version }}" runs-on: ubuntu-latest strategy: matrix: python-version: ["3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Install uv uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 with: python-version: ${{ matrix.python-version }} enable-cache: true - name: Install dependencies run: scripts/install - name: Run linting checks run: scripts/check - name: Build package & docs run: scripts/build - name: Run tests run: scripts/test - name: Enforce coverage run: scripts/coverage check: if: always() needs: [tests] runs-on: ubuntu-latest steps: - name: Decide whether the needed jobs succeeded or failed uses: re-actors/alls-green@b5b5b37504aa4183270bd3d855c52a67f212be35 # v1.3.0 with: jobs: ${{ toJSON(needs) }} deploy-docs: needs: [check] if: success() && github.ref == 'refs/heads/main' runs-on: ubuntu-latest steps: - name: Generate app token uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 id: app-token with: app-id: ${{ vars.DOCS_APP_ID }} private-key: ${{ secrets.DOCS_APP_PRIVATE_KEY }} owner: ${{ github.repository_owner }} repositories: unified-docs permission-contents: write - name: Trigger unified-docs deployment env: GH_TOKEN: ${{ steps.app-token.outputs.token }} run: | gh api repos/pydantic/unified-docs/dispatches \ --method POST \ -f event_type=docs-update \ -f "client_payload[source]=pydantic/httpx2@${{ github.sha }}" pydantic-httpx2-6dd59b9/.github/workflows/publish.yml000066400000000000000000000027551526547463400230230ustar00rootroot00000000000000name: Publish Python Package on: push: tags: - "**" workflow_dispatch: permissions: {} jobs: build: runs-on: ubuntu-latest permissions: contents: read steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false fetch-depth: 0 - name: Install uv uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 with: enable-cache: false - name: Set up Python run: uv python install 3.12 - name: Install dependencies run: scripts/install - name: Build package & docs run: scripts/build - name: Upload package distributions uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: package-distributions path: dist/ publish: runs-on: ubuntu-latest needs: build permissions: id-token: write environment: name: pypi steps: - name: Download package distributions uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: package-distributions path: dist/ - name: Install uv uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 with: enable-cache: false - name: Publish distributions to PyPI run: uv publish --trusted-publishing always dist/* pydantic-httpx2-6dd59b9/.github/workflows/zizmor.yml000066400000000000000000000011211526547463400226710ustar00rootroot00000000000000name: GitHub Actions Security Analysis on: push: branches: ["main"] pull_request: branches: ["**"] permissions: {} jobs: zizmor: runs-on: ubuntu-latest permissions: security-events: write # Required for upload-sarif (used by zizmor-action) to upload SARIF files. steps: - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Run zizmor ๐ŸŒˆ uses: zizmorcore/zizmor-action@cc914d7f3750a2d13d75c7f184a1060aa0e9d482 # v0.6.4 pydantic-httpx2-6dd59b9/.gitignore000066400000000000000000000002031526547463400172070ustar00rootroot00000000000000*.pyc .coverage .pytest_cache/ .mypy_cache/ __pycache__/ htmlcov/ site/ .wrangler/ *.egg-info/ venv*/ .python-version build/ dist/ pydantic-httpx2-6dd59b9/AGENTS.md000066400000000000000000000002501526547463400165240ustar00rootroot00000000000000- Do not force push. - Use single tick (`) instead of double tick (``). - Coding agents shouldn't co-author themselves. The authorship should be only for the engineer. pydantic-httpx2-6dd59b9/LICENSE.md000066400000000000000000000030651526547463400166340ustar00rootroot00000000000000Copyright ยฉ 2026 to present Pydantic Services Inc. and individual contributors. Copyright ยฉ 2019, [Encode OSS Ltd](https://www.encode.io/). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * 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 HOLDER 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. pydantic-httpx2-6dd59b9/README.md000066400000000000000000000154241526547463400165110ustar00rootroot00000000000000

HTTPX2

A next-generation HTTP client for Python.

Test Suite Package version Join Slack

HTTPX2 is a fully featured HTTP client library for Python. It includes **an integrated command line client**, has support for both **HTTP/1.1 and HTTP/2**, and provides both **sync and async APIs**. > [!NOTE] > HTTPX2 is a continuation of the wonderful work started by [@lovelydinosaur](https://github.com/lovelydinosaur) and the broader HTTPX community. We're enormously grateful for everything that has gone into HTTPX over the years - it has been a foundational piece of the modern Python ecosystem, and this project would not exist without it. > > With HTTPX itself seeing limited activity recently, Pydantic is picking up stewardship under the HTTPX2 name so that users have a reliably maintained path forward - including timely security updates for a library that sits in the critical path of so many production systems. Our aim is to honour the original project's design, keep it stable for everyone relying on it, and continue evolving it carefully. Thank you to [@lovelydinosaur](https://github.com/lovelydinosaur) and every past contributor for laying such a strong foundation. ๐Ÿ’™ --- Install HTTPX2 using pip: ```shell pip install httpx2 ``` Now, let's get started: ```pycon >>> import httpx2 >>> r = httpx2.get('https://www.example.org/') >>> r >>> r.status_code 200 >>> r.headers['content-type'] 'text/html; charset=UTF-8' >>> r.text '\n\n\nExample Domain...' ``` Or, using the command-line client. ```shell pip install 'httpx2[cli]' # The command line client is an optional dependency. ``` Which now allows us to use HTTPX2 directly from the command-line: ```shell httpx2 --help ``` ## Features HTTPX2 builds on the well-established usability of `requests`, and gives you: * A broadly [requests-compatible API](https://pydantic.dev/docs/httpx2/guides/compatibility/). * An integrated command-line client. * HTTP/1.1 [and HTTP/2 support](https://pydantic.dev/docs/httpx2/guides/http2/). * Standard synchronous interface, but with [async support if you need it](https://pydantic.dev/docs/httpx2/guides/async/). * Ability to make requests directly to [WSGI applications](https://pydantic.dev/docs/httpx2/advanced/transports/#wsgi-transport) or [ASGI applications](https://pydantic.dev/docs/httpx2/advanced/transports/#asgi-transport). * Strict timeouts everywhere. * Fully type annotated. * 100% test coverage. Plus all the standard features of `requests`... * International Domains and URLs * Keep-Alive & Connection Pooling * Sessions with Cookie Persistence * Browser-style SSL Verification * Basic/Digest Authentication * Elegant Key/Value Cookies * Automatic Decompression * Automatic Content Decoding * Unicode Response Bodies * Multipart File Uploads * HTTP(S) Proxy Support * Connection Timeouts * Streaming Downloads * .netrc Support * Chunked Requests ## Installation Install with pip: ```shell pip install httpx2 ``` Or, to include the optional HTTP/2 support, use: ```shell pip install httpx2[http2] ``` ## Documentation Project documentation is available at [https://pydantic.dev/docs/httpx2/](https://pydantic.dev/docs/httpx2/). For a run-through of all the basics, head over to the [QuickStart](https://pydantic.dev/docs/httpx2/get-started/quickstart/). For more advanced topics, see the [Advanced Usage](https://pydantic.dev/docs/httpx2/advanced/clients/) section, the [async support](https://pydantic.dev/docs/httpx2/guides/async/) section, or the [HTTP/2](https://pydantic.dev/docs/httpx2/guides/http2/) section. The [Developer Interface](https://pydantic.dev/docs/httpx2/api/api/) provides a comprehensive API reference. To find out about tools that integrate with HTTPX, see [Third Party Packages](https://pydantic.dev/docs/httpx2/community/third_party_packages/). ## Observability with Pydantic Logfire Install Logfire with HTTPX instrumentation support: ```shell pip install 'logfire[httpx]' ``` HTTPX2 works out of the box with [Pydantic Logfire](https://pydantic.dev/logfire), our observability platform built on OpenTelemetry. One line instruments every request, giving you traces, timings, and status codes with no other changes: ```python import logfire import httpx2 logfire.configure() logfire.instrument_httpx() httpx2.get("https://pydantic.dev/") ``` This works the same way for explicit `httpx2.Client()` and `httpx2.AsyncClient()` instances, and you can scope instrumentation to a single client by passing it in: `logfire.instrument_httpx(client)`. Pass `capture_all=True` to also record headers and bodies. See the [Logfire HTTPX docs](https://logfire.pydantic.dev/docs/integrations/http-clients/httpx/) for the full set of options. ## Contribute If you want to contribute with HTTPX2 check out the [Contributing Guide](https://pydantic.dev/docs/httpx2/community/contributing/) to learn how to start. ## Dependencies The HTTPX2 project relies on these excellent libraries: * `httpcore2` - The underlying transport implementation for `httpx2`. * `h11` - HTTP/1.1 support. * `anyio` - Structured concurrency primitives, used to support both `asyncio` and `trio`. * `truststore` - SSL verification using the operating system's trust store. * `idna` - Internationalized domain name support. As well as these optional installs: * `h2` - HTTP/2 support. *(Optional, with `httpx2[http2]`)* * `socksio` - SOCKS proxy support. *(Optional, with `httpx2[socks]`)* * `rich` - Rich terminal support. *(Optional, with `httpx2[cli]`)* * `click` - Command line client support. *(Optional, with `httpx2[cli]`)* * `brotli` or `brotlicffi` - Decoding for "brotli" compressed responses. *(Optional, with `httpx2[brotli]`)* * `backports.zstd` - Decoding for "zstd" compressed responses on Python 3.13 and below. *(Optional, with `httpx2[zstd]`. On Python 3.14+, `zstd` is supported via the stdlib [`compression.zstd`](https://docs.python.org/3/library/compression.zstd.html) module when it is available, and the `httpx2[zstd]` extra installs nothing.)* A huge amount of credit is due to `requests` for the API layout that much of this work follows, as well as to `urllib3` for plenty of design inspiration around the lower-level networking details. ---

HTTPX2 is BSD licensed code.
Designed & crafted with care.

— ๐Ÿฆ‹ —

pydantic-httpx2-6dd59b9/benchmark/000077500000000000000000000000001526547463400171565ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/benchmark/README.md000066400000000000000000000051671526547463400204460ustar00rootroot00000000000000# Throughput benchmark An end-to-end, keep-alive throughput benchmark for the async client stack, designed so that the client under test is the bottleneck rather than the server. * `server.py` is a raw `asyncio.Protocol` HTTP/1.1 origin: `GET /` returns `n` bytes, `POST /echo` echoes the body. No parsing library, no per-request sleep. The server and clients run on [zuvloop](https://github.com/Kludex/zuvloop) when it is importable (`--no-zuvloop` for the stdlib loop). * `client.py` runs one library at one concurrency and body size, and prints a JSON line with rps, p50/p99 latency and per-request CPU time. * `run.py` starts the server, runs the matrix interleaved across interpreters and libraries, and prints a comparison table plus two headline numbers. ``` scripts/benchmark # default matrix, httpx2 vs aiohttp scripts/benchmark --quick # c16/1k, c512/1k, c64/100k scripts/benchmark --lib httpx2 --lib httpcore2 --scenario c512/1k --rounds 3 scripts/benchmark --profile /tmp/profiles # pyinstrument output per scenario ``` ## Comparing two revisions Install each revision in its own virtual environment and pass both interpreters. Rounds are interleaved, so both columns see the same machine noise: ``` git worktree add ../httpx2-main main && (cd ../httpx2-main && uv sync) scripts/benchmark --python main=../httpx2-main/.venv/bin/python --python work=.venv/bin/python --lib httpx2 ``` `punkreq` is supported as an extra reference point (`--lib punkreq`) if it is installed. ## Reading the results * `us/req` is CPU time per request, measured with `time.process_time()`, and is more stable than rps on noisy machines. * The `stream` mode (default) mirrors a proxy hot path: a hand-built `Request`, `send(stream=True)`, and `aiter_raw(256 KiB)`. Use `--mode read` for `client.request(...)` with the body read in full. * `retention` is rps at the highest 1KB GET concurrency divided by rps at the lowest. A client whose per-request cost grows with the number of pooled connections has low retention. * Pools are unbounded by default (`--max-connections` to bound them), and the server and clients are pinned to separate CPUs when at least two are available (`--no-pin` to disable). Results depend on the interpreter: the table header shows the version and whether the build is free-threaded. Free-threaded builds are markedly slower on this workload, so use a regular CPython build for representative numbers, for example `uv sync --python 3.14` before `scripts/benchmark`. zuvloop requires CPython 3.14 or later; on other interpreters the harness uses the stdlib loop and the JSON output records `"zuvloop": false`. pydantic-httpx2-6dd59b9/benchmark/client.py000066400000000000000000000304521526547463400210120ustar00rootroot00000000000000""" Single benchmark worker: drives one client library at one concurrency and body size, then emits a JSON line. Normally launched by `run.py`, but it can be used directly against a running `server.py`: python client.py --lib httpx2 --concurrency 16 --size 1024 Modes: * `stream` (default) mirrors a proxy hot path: a hand-built request, `stream=True`, raw chunk iteration. * `read` is the plain "request and read the whole body" path. """ from __future__ import annotations import argparse import asyncio import json import os import sys import time from collections.abc import AsyncIterable, AsyncIterator, Awaitable, Callable, Coroutine from dataclasses import dataclass from typing import Any, TypeVar DEFAULT_PORT = 8765 DEFAULT_CHUNK_SIZE = 256 * 1024 KEEPALIVE_EXPIRY = 95.0 CONNECT_TIMEOUT = 5.0 READ_TIMEOUT = 60.0 T = TypeVar("T") RequestFn = Callable[[], Awaitable[None]] CloseFn = Callable[[], Awaitable[None]] Builder = Callable[["Scenario", bytes], tuple[RequestFn, CloseFn]] @dataclass(frozen=True) class Scenario: lib: str concurrency: int size: int post: bool mode: str chunk_size: int max_connections: int | None host: str port: int @property def method(self) -> str: return "POST" if self.post else "GET" @property def url(self) -> str: path = "/echo" if self.post else f"/{self.size}" return f"http://{self.host}:{self.port}{path}" def check_size(received: int, expected: int) -> None: if received != expected: raise RuntimeError(f"Expected a {expected} byte body, received {received} bytes.") def build_httpx2(scenario: Scenario, payload: bytes) -> tuple[RequestFn, CloseFn]: import httpx2 client = httpx2.AsyncClient( limits=httpx2.Limits( max_connections=scenario.max_connections, max_keepalive_connections=None, keepalive_expiry=KEEPALIVE_EXPIRY, ), timeout=httpx2.Timeout(CONNECT_TIMEOUT, read=READ_TIMEOUT), # Keep the benchmark direct even if HTTP_PROXY or ALL_PROXY is set in the environment. trust_env=False, ) headers = [("host", scenario.host), ("user-agent", "httpx2-benchmark")] if scenario.post: headers.append(("content-length", str(len(payload)))) class RequestBody(httpx2.AsyncByteStream): async def __aiter__(self) -> AsyncIterator[bytes]: if scenario.post: yield payload async def stream_one() -> None: request = httpx2.Request(scenario.method, scenario.url, headers=headers, stream=RequestBody()) response = await client.send(request, stream=True, follow_redirects=False) received = 0 async for chunk in response.aiter_raw(scenario.chunk_size): received += len(chunk) check_size(received, scenario.size) async def read_one() -> None: response = await client.request(scenario.method, scenario.url, content=payload if scenario.post else None) check_size(len(response.content), scenario.size) return (stream_one if scenario.mode == "stream" else read_one), client.aclose def build_httpcore2(scenario: Scenario, payload: bytes) -> tuple[RequestFn, CloseFn]: import httpcore2 pool = httpcore2.AsyncConnectionPool( max_connections=scenario.max_connections, max_keepalive_connections=None, keepalive_expiry=KEEPALIVE_EXPIRY, ) extensions: dict[str, Any] = { "timeout": {"connect": CONNECT_TIMEOUT, "read": READ_TIMEOUT, "write": CONNECT_TIMEOUT, "pool": CONNECT_TIMEOUT} } content = payload if scenario.post else None async def stream_one() -> None: async with pool.stream(scenario.method, scenario.url, content=content, extensions=extensions) as response: assert isinstance(response.stream, AsyncIterable) received = 0 async for chunk in response.stream: received += len(chunk) check_size(received, scenario.size) async def read_one() -> None: response = await pool.request(scenario.method, scenario.url, content=content, extensions=extensions) check_size(len(response.content), scenario.size) return (stream_one if scenario.mode == "stream" else read_one), pool.aclose def build_aiohttp(scenario: Scenario, payload: bytes) -> tuple[RequestFn, CloseFn]: import aiohttp session = aiohttp.ClientSession( connector=aiohttp.TCPConnector(limit=scenario.max_connections or 0, keepalive_timeout=KEEPALIVE_EXPIRY), timeout=aiohttp.ClientTimeout(connect=CONNECT_TIMEOUT, sock_read=READ_TIMEOUT), ) data = payload if scenario.post else None async def stream_one() -> None: async with session.request(scenario.method, scenario.url, data=data) as response: received = 0 async for chunk in response.content.iter_chunked(scenario.chunk_size): received += len(chunk) check_size(received, scenario.size) async def read_one() -> None: async with session.request(scenario.method, scenario.url, data=data) as response: body = await response.read() check_size(len(body), scenario.size) return (stream_one if scenario.mode == "stream" else read_one), session.close def build_punkreq(scenario: Scenario, payload: bytes) -> tuple[RequestFn, CloseFn]: import punkreq from punkreq.asyncio import Client client = Client( limits=punkreq.Limits( max_connections=scenario.max_connections, max_keepalive_connections=None, keepalive_expiry=KEEPALIVE_EXPIRY, ), timeout=punkreq.Timeout(connect=CONNECT_TIMEOUT, read=READ_TIMEOUT, pool=CONNECT_TIMEOUT, total=None), follow_redirects=False, http2=False, trust_env=False, ) headers = [("host", scenario.host), ("user-agent", "httpx2-benchmark")] if scenario.post: headers.append(("content-length", str(len(payload)))) async def request_body(self: object) -> AsyncIterator[bytes]: yield payload # Built dynamically so this module type-checks when punkreq is not installed. request_body_stream = type("RequestBody", (punkreq.AsyncByteStream,), {"__aiter__": request_body}) async def stream_one() -> None: request = punkreq.Request( scenario.method, scenario.url, headers=headers, stream=request_body_stream() if scenario.post else None, ) response = await client.send(request, follow_redirects=False) received = 0 async for chunk in response.iter_raw(scenario.chunk_size): received += len(chunk) check_size(received, scenario.size) async def read_one() -> None: response = await client.request(scenario.method, scenario.url, content=payload if scenario.post else None) check_size(len(await response.read()), scenario.size) return (stream_one if scenario.mode == "stream" else read_one), client.close BUILDERS: dict[str, Builder] = { "httpx2": build_httpx2, "httpcore2": build_httpcore2, "aiohttp": build_aiohttp, "punkreq": build_punkreq, } async def drive(one: RequestFn, concurrency: int, seconds: float) -> list[float]: deadline = time.perf_counter() + seconds latencies: list[float] = [] async def worker() -> None: while True: start = time.perf_counter() await one() end = time.perf_counter() latencies.append(end - start) if end >= deadline: return await asyncio.gather(*(worker() for _ in range(concurrency))) return latencies def percentile(sorted_values: list[float], fraction: float) -> float: return sorted_values[min(len(sorted_values) - 1, int(len(sorted_values) * fraction))] async def run_scenario( scenario: Scenario, seconds: float, warmup_seconds: float, profile_path: str | None ) -> dict[str, Any]: payload = b"y" * scenario.size if scenario.post else b"" one, aclose = BUILDERS[scenario.lib](scenario, payload) try: # Establish `concurrency` connections, then run unmeasured for a while. await asyncio.gather(*(one() for _ in range(scenario.concurrency))) await drive(one, scenario.concurrency, warmup_seconds) profiler = None if profile_path is not None: import pyinstrument profiler = pyinstrument.Profiler(async_mode="disabled") profiler.start() cpu_start = time.process_time() wall_start = time.perf_counter() latencies = await drive(one, scenario.concurrency, seconds) wall = time.perf_counter() - wall_start cpu = time.process_time() - cpu_start if profiler is not None: profiler.stop() with open(profile_path, "w") as f: # type: ignore[arg-type] f.write(profiler.output_text(unicode=True, color=False)) finally: await aclose() latencies.sort() count = len(latencies) return { "lib": scenario.lib, "mode": scenario.mode, "concurrency": scenario.concurrency, "size": scenario.size, "post": scenario.post, "requests": count, "seconds": round(wall, 3), "rps": round(count / wall, 1), "p50_ms": round(percentile(latencies, 0.5) * 1000, 2), "p99_ms": round(percentile(latencies, 0.99) * 1000, 2), "max_ms": round(latencies[-1] * 1000, 2), "cpu_us": round(cpu * 1_000_000 / count, 1), } def pin_to_cpu(cpu: int | None) -> None: if cpu is not None and hasattr(os, "sched_setaffinity"): os.sched_setaffinity(0, {cpu}) def run(coro: Coroutine[Any, Any, T], use_zuvloop: bool) -> tuple[T, bool]: loop: asyncio.AbstractEventLoop zuvloop_active = False if use_zuvloop: try: import zuvloop except ImportError: loop = asyncio.new_event_loop() else: loop = zuvloop.new_event_loop() zuvloop_active = True else: loop = asyncio.new_event_loop() try: return loop.run_until_complete(coro), zuvloop_active finally: loop.run_until_complete(loop.shutdown_asyncgens()) loop.close() def interpreter_info() -> dict[str, Any]: gil_enabled = True if sys.version_info >= (3, 13): gil_enabled = sys._is_gil_enabled() return {"python": sys.version.split()[0], "gil": gil_enabled} def main(argv: list[str] | None = None) -> None: parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument("--lib", choices=sorted(BUILDERS), required=True) parser.add_argument("--concurrency", type=int, default=16) parser.add_argument("--size", type=int, default=1024, help="Response body size in bytes (request body for --post).") parser.add_argument("--post", action="store_true", help="POST a body of --size bytes to the echo endpoint.") parser.add_argument("--mode", choices=("stream", "read"), default="stream") parser.add_argument("--chunk-size", type=int, default=DEFAULT_CHUNK_SIZE) parser.add_argument("--max-connections", type=int, default=None, help="Pool limit; unbounded by default.") parser.add_argument("--seconds", type=float, default=4.0, help="Measured duration.") parser.add_argument("--warmup", type=float, default=0.5, help="Unmeasured duration before measuring.") parser.add_argument("--host", default="127.0.0.1") parser.add_argument("--port", type=int, default=DEFAULT_PORT) parser.add_argument("--cpu", type=int, default=None, help="Pin this worker to a CPU (Linux only).") parser.add_argument("--no-zuvloop", action="store_true") parser.add_argument("--profile", default=None, help="Write a pyinstrument profile of the measured phase here.") args = parser.parse_args(argv) pin_to_cpu(args.cpu) scenario = Scenario( lib=args.lib, concurrency=args.concurrency, size=args.size, post=args.post, mode=args.mode, chunk_size=args.chunk_size, max_connections=args.max_connections, host=args.host, port=args.port, ) result, zuvloop_active = run( run_scenario(scenario, args.seconds, args.warmup, args.profile), use_zuvloop=not args.no_zuvloop ) result.update(interpreter_info(), zuvloop=zuvloop_active) print(json.dumps(result), flush=True) if __name__ == "__main__": main() pydantic-httpx2-6dd59b9/benchmark/run.py000066400000000000000000000311721526547463400203400ustar00rootroot00000000000000""" Benchmark orchestrator: starts the origin server, runs the client matrix, and prints a comparison table. Examples: python run.py # default matrix, current interpreter, httpx2 vs aiohttp python run.py --quick --lib httpx2 # three scenarios, one library python run.py --python main=../httpx2-main/.venv/bin/python --python work=.venv/bin/python Each `--python LABEL=PATH` is an interpreter with the libraries installed; runs are interleaved across interpreters and libraries on every round so machine noise affects all columns equally. Two headline numbers are reported per column: * `cpu us/req` at the smallest 1KB GET scenario: per-request CPU cost of the client stack. * `retention`: throughput at the largest 1KB GET concurrency divided by throughput at the smallest. """ from __future__ import annotations import argparse import json import os import pathlib import queue import statistics import subprocess import sys import threading from dataclasses import dataclass from typing import Any HERE = pathlib.Path(__file__).parent SERVER = HERE / "server.py" CLIENT = HERE / "client.py" DEFAULT_PORT = 8765 DEFAULT_SCENARIOS = ["c1/1k", "c16/1k", "c128/1k", "c512/1k", "c64/100k", "c8/5m", "c64/1k/post", "c8/1m/post"] QUICK_SCENARIOS = ["c16/1k", "c512/1k", "c64/100k"] PROFILE_LIBS = ("httpx2", "httpcore2") @dataclass(frozen=True) class ScenarioSpec: concurrency: int size: int post: bool @classmethod def parse(cls, text: str) -> ScenarioSpec: parts = text.split("/") valid = len(parts) in (2, 3) and parts[0].startswith("c") and (len(parts) == 2 or parts[2] == "post") if not valid: raise argparse.ArgumentTypeError(f"Expected 'c/[/post]', got {text!r}.") return cls(concurrency=int(parts[0][1:]), size=parse_size(parts[1]), post=len(parts) == 3) @property def label(self) -> str: return f"c{self.concurrency}/{format_size(self.size)}" + ("/post" if self.post else "") def parse_size(text: str) -> int: units = {"k": 1024, "m": 1024 * 1024} unit = text[-1].lower() if unit in units: return int(text[:-1]) * units[unit] return int(text) def format_size(size: int) -> str: if size % (1024 * 1024) == 0: return f"{size // (1024 * 1024)}m" if size % 1024 == 0: return f"{size // 1024}k" return str(size) def available_cpus() -> list[int]: # Respect the affinity mask: in containers the usable CPU IDs need not start at zero. if hasattr(os, "sched_getaffinity"): return sorted(os.sched_getaffinity(0)) return list(range(os.cpu_count() or 1)) def parse_python(text: str) -> tuple[str, str]: label, sep, path = text.partition("=") if not sep: raise argparse.ArgumentTypeError(f"Expected 'LABEL=PATH', got {text!r}.") return label, path def wait_for_server(server: subprocess.Popen[bytes], port: int, timeout: float = 10.0) -> None: # Wait for the server's readiness line rather than probing the port, so a failed # bind (for example, the port already in use) is an error instead of a silent # benchmark against whatever else is listening there. assert server.stdout is not None lines: queue.Queue[bytes] = queue.Queue() threading.Thread(target=lambda: lines.put(server.stdout.readline()), daemon=True).start() # type: ignore[union-attr] try: line = lines.get(timeout=timeout) except queue.Empty: raise RuntimeError(f"Benchmark server did not start listening on port {port} within {timeout}s.") from None if not line.startswith(b"listening on "): code = server.wait(timeout=5) raise RuntimeError(f"Benchmark server exited with code {code}; is port {port} already in use?") def interpreter_summary(python: str) -> str: code = ( "import sys, json; gil = sys._is_gil_enabled() if sys.version_info >= (3, 13) else True; " "print(json.dumps({'python': sys.version.split()[0], 'gil': gil}))" ) info = json.loads(subprocess.run([python, "-c", code], check=True, capture_output=True, text=True).stdout) return f"{info['python']}{'' if info['gil'] else ' (free-threaded)'}" def run_worker( python: str, lib: str, spec: ScenarioSpec, args: argparse.Namespace, profile: pathlib.Path | None = None ) -> dict[str, Any]: command = [ python, str(CLIENT), "--lib", lib, "--concurrency", str(spec.concurrency), "--size", str(spec.size), "--mode", args.mode, "--seconds", str(args.seconds), "--port", str(args.port), ] if spec.post: command.append("--post") if args.max_connections is not None: command += ["--max-connections", str(args.max_connections)] if args.client_cpu is not None: command += ["--cpu", str(args.client_cpu)] if args.no_zuvloop: command.append("--no-zuvloop") if profile is not None: command += ["--profile", str(profile)] completed = subprocess.run(command, capture_output=True, text=True) if completed.returncode != 0: tail = "\n".join(completed.stderr.strip().splitlines()[-3:]) return {"error": tail or f"exit code {completed.returncode}"} result: dict[str, Any] = json.loads(completed.stdout.strip().splitlines()[-1]) return result def median(results: list[dict[str, Any]], key: str) -> float: return float(statistics.median(r[key] for r in results)) def print_table( specs: list[ScenarioSpec], columns: list[str], results: dict[tuple[str, str], list[dict[str, Any]]] ) -> None: header = ["scenario", *columns] rows = [] for spec in specs: row = [spec.label] for column in columns: ok = [r for r in results.get((spec.label, column), []) if "error" not in r] if not ok: errors = [r["error"] for r in results.get((spec.label, column), []) if "error" in r] row.append(f"FAILED: {errors[0]}" if errors else "-") continue row.append( f"{median(ok, 'rps'):,.0f} rps ยท {median(ok, 'p50_ms'):.1f}/{median(ok, 'p99_ms'):.1f} ms" f" ยท {median(ok, 'cpu_us'):.0f} us" ) rows.append(row) widths = [max(len(line[i]) for line in [header, *rows]) for i in range(len(header))] print("Cells: median rps ยท p50/p99 latency ms ยท CPU us per request") print("| " + " | ".join(cell.ljust(widths[i]) for i, cell in enumerate(header)) + " |") print("|" + "|".join("-" * (width + 2) for width in widths) + "|") for row in rows: print("| " + " | ".join(cell.ljust(widths[i]) for i, cell in enumerate(row)) + " |") def print_kpis( specs: list[ScenarioSpec], columns: list[str], results: dict[tuple[str, str], list[dict[str, Any]]] ) -> None: get_1k = sorted((s for s in specs if s.size == 1024 and not s.post), key=lambda s: s.concurrency) if not get_1k: return low, high = get_1k[0], get_1k[-1] print() if high is low: print(f"KPIs (cpu at {low.label}):") else: print(f"KPIs (cpu at {low.label}, retention = rps {high.label} / rps {low.label}):") for column in columns: low_ok = [r for r in results.get((low.label, column), []) if "error" not in r] high_ok = [r for r in results.get((high.label, column), []) if "error" not in r] if not low_ok: continue line = f" {column}: {median(low_ok, 'cpu_us'):.0f} us/req" if high_ok and high is not low: line += f", retention {median(high_ok, 'rps') / median(low_ok, 'rps'):.0%}" print(line) def main(argv: list[str] | None = None) -> None: parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument( "--python", type=parse_python, action="append", default=[], metavar="LABEL=PATH", help="Interpreter to run." ) parser.add_argument( "--lib", action="append", default=[], help="Client library (repeatable). Default: httpx2, aiohttp." ) parser.add_argument( "--scenario", type=ScenarioSpec.parse, action="append", default=[], metavar="c/[/post]" ) parser.add_argument("--quick", action="store_true", help=f"Use the short matrix: {', '.join(QUICK_SCENARIOS)}.") parser.add_argument("--mode", choices=("stream", "read"), default="stream") parser.add_argument("--rounds", type=int, default=2, help="Interleaved repetitions; medians are reported.") parser.add_argument("--seconds", type=float, default=4.0, help="Measured duration per run.") parser.add_argument("--max-connections", type=int, default=None) parser.add_argument("--port", type=int, default=DEFAULT_PORT) parser.add_argument( "--server-cpu", type=int, default=None, help="Default: the first usable CPU when at least two are available." ) parser.add_argument( "--client-cpu", type=int, default=None, help="Default: the second usable CPU when at least two are available." ) parser.add_argument("--no-pin", action="store_true", help="Do not pin the server and clients to CPUs.") parser.add_argument( "--no-zuvloop", action="store_true", help="Use the stdlib event loop for the server and clients." ) parser.add_argument("--profile", type=pathlib.Path, default=None, help="Directory for pyinstrument profiles.") parser.add_argument("--output", type=pathlib.Path, default=None, help="Write raw results as JSON.") args = parser.parse_args(argv) pythons: list[tuple[str, str]] = args.python or [("current", sys.executable)] if len({label for label, _ in pythons}) != len(pythons): parser.error("--python labels must be unique.") libs: list[str] = list(dict.fromkeys(args.lib or ["httpx2", "aiohttp"])) # Deduplicate by value, so `c16/1k` and `c16/1024` do not become two rows sharing one bucket. specs: list[ScenarioSpec] = list( dict.fromkeys( args.scenario or [ScenarioSpec.parse(s) for s in (QUICK_SCENARIOS if args.quick else DEFAULT_SCENARIOS)] ) ) cpus = available_cpus() if not args.no_pin and len(cpus) >= 2: args.server_cpu = cpus[0] if args.server_cpu is None else args.server_cpu args.client_cpu = cpus[1] if args.client_cpu is None else args.client_cpu columns = [f"{lib}@{label}" if len(pythons) > 1 else lib for label, _ in pythons for lib in libs] print(f"cpus: {len(cpus)}, server cpu: {args.server_cpu}, client cpu: {args.client_cpu}, mode: {args.mode}") for label, python in pythons: print(f"{label}: {python} ({interpreter_summary(python)})") print(f"rounds: {args.rounds}, {args.seconds}s per run, {len(specs)} scenarios, {len(columns)} columns") print() server_command = [sys.executable, str(SERVER), "--port", str(args.port)] if args.server_cpu is not None: server_command += ["--cpu", str(args.server_cpu)] if args.no_zuvloop: server_command.append("--no-zuvloop") server = subprocess.Popen(server_command, stdout=subprocess.PIPE) results: dict[tuple[str, str], list[dict[str, Any]]] = {} try: wait_for_server(server, args.port) for round_number in range(1, args.rounds + 1): for spec in specs: for label, python in pythons: for lib in libs: column = f"{lib}@{label}" if len(pythons) > 1 else lib result = run_worker(python, lib, spec, args) results.setdefault((spec.label, column), []).append(result) summary = result.get("error") or f"{result['rps']:,.0f} rps, {result['cpu_us']:.0f} us/req" print(f"[round {round_number}] {spec.label:<14} {column:<24} {summary}", flush=True) if args.profile is not None: args.profile.mkdir(parents=True, exist_ok=True) label, python = pythons[0] for spec in specs: for lib in libs: if lib not in PROFILE_LIBS: continue path = args.profile / f"{lib}-{label}-{spec.label.replace('/', '-')}.txt" result = run_worker(python, lib, spec, args, profile=path) print(f"[profile] {spec.label:<14} {lib:<24} {result.get('error') or path}", flush=True) finally: server.terminate() server.wait(timeout=5) print() print_table(specs, columns, results) print_kpis(specs, columns, results) if args.output is not None: args.output.write_text(json.dumps({f"{k[0]} {k[1]}": v for k, v in results.items()}, indent=2)) print(f"\nraw results: {args.output}") if __name__ == "__main__": main() pydantic-httpx2-6dd59b9/benchmark/server.py000066400000000000000000000103321526547463400210350ustar00rootroot00000000000000""" Minimal HTTP/1.1 keep-alive origin for the benchmark harness. The server is deliberately trivial so that the client under test is the bottleneck: * `GET /` responds with an `n`-byte body. * `POST /echo` echoes the request body. Usage: `python server.py [--port 8765] [--cpu N] [--no-zuvloop]` """ from __future__ import annotations import argparse import asyncio import os import sys from collections.abc import Coroutine from typing import Any, TypeVar, cast DEFAULT_PORT = 8765 RESPONSE_HEAD = b"HTTP/1.1 200 OK\r\ncontent-type: application/octet-stream\r\ncontent-length: %d\r\n\r\n" BAD_REQUEST = b"HTTP/1.1 400 Bad Request\r\ncontent-length: 0\r\n\r\n" MAX_BODY_SIZE = 64 * 1024 * 1024 T = TypeVar("T") _bodies: dict[int, bytes] = {} def response_body(target: bytes) -> bytes | None: try: size = int(target.rsplit(b"/", 1)[-1] or b"0") except ValueError: return None if not 0 <= size <= MAX_BODY_SIZE: return None body = _bodies.get(size) if body is None: body = _bodies[size] = b"x" * size return body class OriginProtocol(asyncio.Protocol): def __init__(self) -> None: self._buffer = bytearray() self._transport: asyncio.Transport | None = None def connection_made(self, transport: asyncio.BaseTransport) -> None: # zuvloop transports implement the interface without subclassing `asyncio.Transport`. self._transport = cast(asyncio.Transport, transport) def data_received(self, data: bytes) -> None: self._buffer += data while self._respond_once(): pass def _respond_once(self) -> bool: head_end = self._buffer.find(b"\r\n\r\n") if head_end < 0: return False request_line, _, header_block = bytes(self._buffer[:head_end]).partition(b"\r\n") method, target, _ = request_line.split(b" ", 2) content_length = 0 for line in header_block.split(b"\r\n"): name, _, value = line.partition(b":") if name.strip().lower() == b"content-length": content_length = int(value) total = head_end + 4 + content_length if len(self._buffer) < total: return False body = bytes(self._buffer[head_end + 4 : total]) del self._buffer[:total] payload = body if method == b"POST" else response_body(target) assert self._transport is not None if payload is None: self._transport.write(BAD_REQUEST) else: self._transport.writelines([RESPONSE_HEAD % len(payload), payload]) return True async def serve(port: int) -> None: loop = asyncio.get_running_loop() server = await loop.create_server(OriginProtocol, "127.0.0.1", port, backlog=4096) # The orchestrator waits for this line; a bind failure ends stdout without it. print(f"listening on 127.0.0.1:{port}", flush=True) async with server: await server.serve_forever() def pin_to_cpu(cpu: int | None) -> None: if cpu is not None and hasattr(os, "sched_setaffinity"): os.sched_setaffinity(0, {cpu}) def run(coro: Coroutine[Any, Any, T], use_zuvloop: bool) -> T: loop: asyncio.AbstractEventLoop if use_zuvloop: try: import zuvloop except ImportError: loop = asyncio.new_event_loop() else: loop = zuvloop.new_event_loop() else: loop = asyncio.new_event_loop() try: return loop.run_until_complete(coro) finally: loop.run_until_complete(loop.shutdown_asyncgens()) loop.close() def main(argv: list[str] | None = None) -> None: parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument("--port", type=int, default=DEFAULT_PORT) parser.add_argument("--cpu", type=int, default=None, help="Pin the server to this CPU (Linux only).") parser.add_argument( "--no-zuvloop", action="store_true", help="Use the stdlib event loop even if zuvloop is installed." ) args = parser.parse_args(argv) pin_to_cpu(args.cpu) try: run(serve(args.port), use_zuvloop=not args.no_zuvloop) except KeyboardInterrupt: sys.exit(0) if __name__ == "__main__": main() pydantic-httpx2-6dd59b9/docs/000077500000000000000000000000001526547463400161545ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/docs/advanced/000077500000000000000000000000001526547463400177215ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/docs/advanced/authentication.md000066400000000000000000000206131526547463400232640ustar00rootroot00000000000000Authentication can either be included on a per-request basis... ```pycon >>> auth = httpx2.BasicAuth(username="username", password="secret") >>> client = httpx2.Client() >>> response = client.get("https://www.example.com/", auth=auth) ``` Or configured on the client instance, ensuring that all outgoing requests will include authentication credentials... ```pycon >>> auth = httpx2.BasicAuth(username="username", password="secret") >>> client = httpx2.Client(auth=auth) >>> response = client.get("https://www.example.com/") ``` ## Basic authentication HTTP basic authentication is an unencrypted authentication scheme that uses a simple encoding of the username and password in the request `Authorization` header. Since it is unencrypted it should typically only be used over `https`, although this is not strictly enforced. ```pycon >>> auth = httpx2.BasicAuth(username="finley", password="secret") >>> client = httpx2.Client(auth=auth) >>> response = client.get("https://httpbin.org/basic-auth/finley/secret") >>> response ``` ## Digest authentication HTTP digest authentication is a challenge-response authentication scheme. Unlike basic authentication it provides encryption, and can be used over unencrypted `http` connections. It requires an additional round-trip in order to negotiate the authentication. ```pycon >>> auth = httpx2.DigestAuth(username="olivia", password="secret") >>> client = httpx2.Client(auth=auth) >>> response = client.get("https://httpbin.org/digest-auth/auth/olivia/secret") >>> response >>> response.history [] ``` ## NetRC authentication HTTPX can be configured to use [a `.netrc` config file](https://everything.curl.dev/usingcurl/netrc) for authentication. The `.netrc` config file allows authentication credentials to be associated with specified hosts. When a request is made to a host that is found in the netrc file, the username and password will be included using HTTP basic authentication. Example `.netrc` file: ``` machine example.org login example-username password example-password machine python-httpx2.org login other-username password other-password ``` Some examples of configuring `.netrc` authentication with `httpx2`. Use the default `.netrc` file in the users home directory: ```pycon >>> auth = httpx2.NetRCAuth() >>> client = httpx2.Client(auth=auth) ``` Use an explicit path to a `.netrc` file: ```pycon >>> auth = httpx2.NetRCAuth(file="/path/to/.netrc") >>> client = httpx2.Client(auth=auth) ``` Use the `NETRC` environment variable to configure a path to the `.netrc` file, or fallback to the default. ```pycon >>> auth = httpx2.NetRCAuth(file=os.environ.get("NETRC")) >>> client = httpx2.Client(auth=auth) ``` The `NetRCAuth()` class uses [the `netrc.netrc()` function from the Python standard library](https://docs.python.org/3/library/netrc.html). See the documentation there for more details on exceptions that may be raised if the `.netrc` file is not found, or cannot be parsed. ## Custom authentication schemes When issuing requests or instantiating a client, the `auth` argument can be used to pass an authentication scheme to use. The `auth` argument may be one of the following... * A two-tuple of `username`/`password`, to be used with basic authentication. * An instance of `httpx2.BasicAuth()`, `httpx2.DigestAuth()`, or `httpx2.NetRCAuth()`. * A callable, accepting a request and returning an authenticated request instance. * An instance of subclasses of `httpx2.Auth`. The most involved of these is the last, which allows you to create authentication flows involving one or more requests. A subclass of `httpx2.Auth` should implement `def auth_flow(request)`, and yield any requests that need to be made... ```python class MyCustomAuth(httpx2.Auth): def __init__(self, token): self.token = token def auth_flow(self, request): # Send the request, with a custom `X-Authentication` header. request.headers['X-Authentication'] = self.token yield request ``` If the auth flow requires more than one request, you can issue multiple yields, and obtain the response in each case... ```python class MyCustomAuth(httpx2.Auth): def __init__(self, token): self.token = token def auth_flow(self, request): response = yield request if response.status_code == 401: # If the server issues a 401 response then resend the request, # with a custom `X-Authentication` header. request.headers['X-Authentication'] = self.token yield request ``` Custom authentication classes are designed to not perform any I/O, so that they may be used with both sync and async client instances. If you are implementing an authentication scheme that requires the request body, then you need to indicate this on the class using a `requires_request_body` property. You will then be able to access `request.content` inside the `.auth_flow()` method. ```python class MyCustomAuth(httpx2.Auth): requires_request_body = True def __init__(self, token): self.token = token def auth_flow(self, request): response = yield request if response.status_code == 401: # If the server issues a 401 response then resend the request, # with a custom `X-Authentication` header. request.headers['X-Authentication'] = self.sign_request(...) yield request def sign_request(self, request): # Create a request signature, based on `request.method`, `request.url`, # `request.headers`, and `request.content`. ... ``` Similarly, if you are implementing a scheme that requires access to the response body, then use the `requires_response_body` property. You will then be able to access response body properties and methods such as `response.content`, `response.text`, `response.json()`, etc. ```python class MyCustomAuth(httpx2.Auth): requires_response_body = True def __init__(self, access_token, refresh_token, refresh_url): self.access_token = access_token self.refresh_token = refresh_token self.refresh_url = refresh_url def auth_flow(self, request): request.headers["X-Authentication"] = self.access_token response = yield request if response.status_code == 401: # If the server issues a 401 response, then issue a request to # refresh tokens, and resend the request. refresh_response = yield self.build_refresh_request() self.update_tokens(refresh_response) request.headers["X-Authentication"] = self.access_token yield request def build_refresh_request(self): # Return an `httpx2.Request` for refreshing tokens. ... def update_tokens(self, response): # Update the `.access_token` and `.refresh_token` tokens # based on a refresh response. data = response.json() ... ``` If you _do_ need to perform I/O other than HTTP requests, such as accessing a disk-based cache, or you need to use concurrency primitives, such as locks, then you should override `.sync_auth_flow()` and `.async_auth_flow()` (instead of `.auth_flow()`). The former will be used by `httpx2.Client`, while the latter will be used by `httpx2.AsyncClient`. ```python import asyncio import threading import httpx2 class MyCustomAuth(httpx2.Auth): def __init__(self): self._sync_lock = threading.RLock() self._async_lock = asyncio.Lock() def sync_get_token(self): with self._sync_lock: ... def sync_auth_flow(self, request): token = self.sync_get_token() request.headers["Authorization"] = f"Token {token}" yield request async def async_get_token(self): async with self._async_lock: ... async def async_auth_flow(self, request): token = await self.async_get_token() request.headers["Authorization"] = f"Token {token}" yield request ``` If you only want to support one of the two methods, then you should still override it, but raise an explicit `RuntimeError`. ```python import httpx2 import sync_only_library class MyCustomAuth(httpx2.Auth): def sync_auth_flow(self, request): token = sync_only_library.get_token(...) request.headers["Authorization"] = f"Token {token}" yield request async def async_auth_flow(self, request): raise RuntimeError("Cannot use a sync authentication class with httpx2.AsyncClient") ```pydantic-httpx2-6dd59b9/docs/advanced/clients.md000066400000000000000000000263621526547463400217150ustar00rootroot00000000000000!!! hint If you are coming from Requests, `httpx2.Client()` is what you can use instead of `requests.Session()`. ## Why use a Client? !!! note "TL;DR" If you do anything more than experimentation, one-off scripts, or prototypes, then you should use a `Client` instance. **More efficient usage of network resources** When you make requests using the top-level API as documented in the [Quickstart](../quickstart.md) guide, HTTPX has to establish a new connection _for every single request_ (connections are not reused). As the number of requests to a host increases, this quickly becomes inefficient. On the other hand, a `Client` instance uses [HTTP connection pooling](https://en.wikipedia.org/wiki/HTTP_persistent_connection). This means that when you make several requests to the same host, the `Client` will reuse the underlying TCP connection, instead of recreating one for every single request. This can bring **significant performance improvements** compared to using the top-level API, including: - Reduced latency across requests (no handshaking). - Reduced CPU usage and round-trips. - Reduced network congestion. **Extra features** `Client` instances also support features that aren't available at the top-level API, such as: - Cookie persistence across requests. - Applying configuration across all outgoing requests. - Sending requests through HTTP proxies. - Using [HTTP/2](../http2.md). The other sections on this page go into further detail about what you can do with a `Client` instance. ## Usage The recommended way to use a `Client` is as a context manager. This will ensure that connections are properly cleaned up when leaving the `with` block: ```python with httpx2.Client() as client: ... ``` Alternatively, you can explicitly close the connection pool without block-usage using `.close()`: ```python client = httpx2.Client() try: ... finally: client.close() ``` ## Making requests Once you have a `Client`, you can send requests using `.get()`, `.post()`, etc. For example: ```pycon >>> with httpx2.Client() as client: ... r = client.get('https://example.com') ... >>> r ``` These methods accept the same arguments as `httpx2.get()`, `httpx2.post()`, etc. This means that all features documented in the [Quickstart](../quickstart.md) guide are also available at the client level. For example, to send a request with custom headers: ```pycon >>> with httpx2.Client() as client: ... headers = {'X-Custom': 'value'} ... r = client.get('https://example.com', headers=headers) ... >>> r.request.headers['X-Custom'] 'value' ``` ## Sharing configuration across requests Clients allow you to apply configuration to all outgoing requests by passing parameters to the `Client` constructor. For example, to apply a set of custom headers _on every request_: ```pycon >>> url = 'http://httpbin.org/headers' >>> headers = {'user-agent': 'my-app/0.0.1'} >>> with httpx2.Client(headers=headers) as client: ... r = client.get(url) ... >>> r.json()['headers']['User-Agent'] 'my-app/0.0.1' ``` ## Merging of configuration When a configuration option is provided at both the client-level and request-level, one of two things can happen: - For headers, query parameters and cookies, the values are combined together. For example: ```pycon >>> headers = {'X-Auth': 'from-client'} >>> params = {'client_id': 'client1'} >>> with httpx2.Client(headers=headers, params=params) as client: ... headers = {'X-Custom': 'from-request'} ... params = {'request_id': 'request1'} ... r = client.get('https://example.com', headers=headers, params=params) ... >>> r.request.url URL('https://example.com?client_id=client1&request_id=request1') >>> r.request.headers['X-Auth'] 'from-client' >>> r.request.headers['X-Custom'] 'from-request' ``` - For all other parameters, the request-level value takes priority. For example: ```pycon >>> with httpx2.Client(auth=('tom', 'mot123')) as client: ... r = client.get('https://example.com', auth=('alice', 'ecila123')) ... >>> _, _, auth = r.request.headers['Authorization'].partition(' ') >>> import base64 >>> base64.b64decode(auth) b'alice:ecila123' ``` If you need finer-grained control on the merging of client-level and request-level parameters, see [Request instances](#request-instances). ## Other Client-only configuration options Additionally, `Client` accepts some configuration options that aren't available at the request level. For example, `base_url` allows you to prepend an URL to all outgoing requests: ```pycon >>> with httpx2.Client(base_url='http://httpbin.org') as client: ... r = client.get('/headers') ... >>> r.request.url URL('http://httpbin.org/headers') ``` For a list of all available client parameters, see the [`Client`](../api.md#client) API reference. --- ## Request instances For maximum control on what gets sent over the wire, HTTPX supports building explicit [`Request`](../api.md#request) instances: ```python request = httpx2.Request("GET", "https://example.com") ``` To dispatch a `Request` instance across to the network, create a [`Client` instance](#sharing-configuration-across-requests) and use `.send()`: ```python with httpx2.Client() as client: response = client.send(request) ... ``` If you need to mix client-level and request-level options in a way that is not supported by the default [Merging of configuration](#merging-of-configuration), you can use `.build_request()` and then make arbitrary modifications to the `Request` instance. For example: ```python headers = {"X-Api-Key": "...", "X-Client-ID": "ABC123"} with httpx2.Client(headers=headers) as client: request = client.build_request("GET", "https://api.example.com") print(request.headers["X-Client-ID"]) # "ABC123" # Don't send the API key for this particular request. del request.headers["X-Api-Key"] response = client.send(request) ... ``` ## Monitoring download progress If you need to monitor download progress of large responses, you can use response streaming and inspect the `response.num_bytes_downloaded` property. This interface is required for properly determining download progress, because the total number of bytes returned by `response.content` or `response.iter_content()` will not always correspond with the raw content length of the response if HTTP response compression is being used. For example, showing a progress bar using the [`tqdm`](https://github.com/tqdm/tqdm) library while a response is being downloaded could be done like thisโ€ฆ ```python import tempfile import httpx2 from tqdm import tqdm with tempfile.NamedTemporaryFile() as download_file: url = "https://speed.hetzner.de/100MB.bin" with httpx2.stream("GET", url) as response: total = int(response.headers["Content-Length"]) with tqdm(total=total, unit_scale=True, unit_divisor=1024, unit="B") as progress: num_bytes_downloaded = response.num_bytes_downloaded for chunk in response.iter_bytes(): download_file.write(chunk) progress.update(response.num_bytes_downloaded - num_bytes_downloaded) num_bytes_downloaded = response.num_bytes_downloaded ``` ![tqdm progress bar](../img/tqdm-progress.gif) Or an alternate example, this time using the [`rich`](https://github.com/willmcgugan/rich) libraryโ€ฆ ```python import tempfile import httpx2 import rich.progress with tempfile.NamedTemporaryFile() as download_file: url = "https://speed.hetzner.de/100MB.bin" with httpx2.stream("GET", url) as response: total = int(response.headers["Content-Length"]) with rich.progress.Progress( "[progress.percentage]{task.percentage:>3.0f}%", rich.progress.BarColumn(bar_width=None), rich.progress.DownloadColumn(), rich.progress.TransferSpeedColumn(), ) as progress: download_task = progress.add_task("Download", total=total) for chunk in response.iter_bytes(): download_file.write(chunk) progress.update(download_task, completed=response.num_bytes_downloaded) ``` ![rich progress bar](../img/rich-progress.gif) ## Monitoring upload progress If you need to monitor upload progress of large responses, you can use request content generator streaming. For example, showing a progress bar using the [`tqdm`](https://github.com/tqdm/tqdm) library. ```python import io import random import httpx2 from tqdm import tqdm def gen(): """ this is a complete example with generated random bytes. you can replace `io.BytesIO` with real file object. """ total = 32 * 1024 * 1024 # 32m with tqdm(ascii=True, unit_scale=True, unit='B', unit_divisor=1024, total=total) as bar: with io.BytesIO(random.randbytes(total)) as f: while data := f.read(1024): yield data bar.update(len(data)) httpx2.post("https://httpbin.org/post", content=gen()) ``` ![tqdm progress bar](../img/tqdm-progress.gif) ## Multipart file encoding As mentioned in the [quickstart](../quickstart.md#sending-multipart-file-uploads) multipart file encoding is available by passing a dictionary with the name of the payloads as keys and either tuple of elements or a file-like object or a string as values. ```pycon >>> with open('report.xls', 'rb') as report_file: ... files = {'upload-file': ('report.xls', report_file, 'application/vnd.ms-excel')} ... r = httpx2.post("https://httpbin.org/post", files=files) >>> print(r.text) { ... "files": { "upload-file": "<... binary content ...>" }, ... } ``` More specifically, if a tuple is used as a value, it must have between 2 and 3 elements: - The first element is an optional file name which can be set to `None`. - The second element may be a file-like object or a string which will be automatically encoded in UTF-8. - An optional third element can be used to specify the [MIME type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_Types) of the file being uploaded. If not specified HTTPX will attempt to guess the MIME type based on the file name, with unknown file extensions defaulting to "application/octet-stream". If the file name is explicitly set to `None` then HTTPX will not include a content-type MIME header field. ```pycon >>> files = {'upload-file': (None, 'text content', 'text/plain')} >>> r = httpx2.post("https://httpbin.org/post", files=files) >>> print(r.text) { ... "files": {}, "form": { "upload-file": "text-content" }, ... } ``` !!! tip It is safe to upload large files this way. File uploads are streaming by default, meaning that only one chunk will be loaded into memory at a time. Non-file data fields can be included in the multipart form using by passing them to `data=...`. You can also send multiple files in one go with a multiple file field form. To do that, pass a list of `(field, )` items instead of a dictionary, allowing you to pass multiple items with the same `field`. For instance this request sends 2 files, `foo.png` and `bar.png` in one request on the `images` form field: ```pycon >>> with open('foo.png', 'rb') as foo_file, open('bar.png', 'rb') as bar_file: ... files = [ ... ('images', ('foo.png', foo_file, 'image/png')), ... ('images', ('bar.png', bar_file, 'image/png')), ... ] ... r = httpx2.post("https://httpbin.org/post", files=files) ``` pydantic-httpx2-6dd59b9/docs/advanced/emscripten.md000066400000000000000000000046611526547463400224230ustar00rootroot00000000000000--- template: pyodide.html --- # Emscripten Support httpx2 has support for running on WebAssembly / Emscripten using [Pyodide](https://github.com/pyodide/pyodide/) or [emscripten-forge](https://emscripten-forge.org/). It uses the `httpx2-jsfetch` package ([for Pyodide](https://github.com/hoodmane/httpx2-jsfetch) or [for emscripten-forge](https://github.com/davidbrochart/httpx2-jsfetch-emscripten-forge)) to define the `JavascriptFetchTransport` and `AsyncJavascriptFetchTransport`. Asynchronous requests always use `fetch`. Synchronous requests use the following methods: 1. If [JavaScript Promise Integration](https://github.com/WebAssembly/js-promise-integration/blob/main/proposals/js-promise-integration/Overview.md) (JSPI) is supported by the JavaScript runtime, the request will be made with `fetch` and stack switching. 2. Otherwise, if in a browser, the request will be made using a synchronous `XMLHttpRequest`. 3. Otherwise, if in Node, the request will fail. Synchronous requests in Node require JSPI. In Emscripten, all network connections are handled by the enclosing JavaScript runtime. As such, there is limited control over various features. In particular: - Proxy servers are handled by the runtime, so httpx2 cannot control them. - httpx2 has no control over connection pooling. - Certificate handling is done by the browser, so httpx2 cannot modify it. - Requests are constrained by cross-origin isolation settings in the same way as any request that is originated by JavaScript code. - Timeouts will not work in the main browser thread unless the browser supports JSPI because main thread synchronous `XMLHttpRequest` does not support timeouts. Setting any of the transport options that depend on these features (`verify`, `cert`, `http2`, `limits`, `proxy`, `uds`, `local_address`, `retries`, or `socket_options`) will emit a `UserWarning` and the option will be silently ignored. ## Try it in your browser Use the following live example to test httpx2 in your web browser. You can change the code below and hit run again to test different features or web addresses.
import httpx2 from js import document print("Sending response using httpx2 in the browser:") print("--------------------------------------------") r = httpx2.get(document.location.origin) print("Status = ", r.status_code) print("Response = ", r.text[:50], "...")
pydantic-httpx2-6dd59b9/docs/advanced/event-hooks.md000066400000000000000000000045711526547463400225140ustar00rootroot00000000000000HTTPX allows you to register "event hooks" with the client, that are called every time a particular type of event takes place. There are currently two event hooks: * `request` - Called after a request is fully prepared, but before it is sent to the network. Passed the `request` instance. * `response` - Called after the response has been fetched from the network, but before it is returned to the caller. Passed the `response` instance. These allow you to install client-wide functionality such as logging, monitoring or tracing. ```python def log_request(request): print(f"Request event hook: {request.method} {request.url} - Waiting for response") def log_response(response): request = response.request print(f"Response event hook: {request.method} {request.url} - Status {response.status_code}") client = httpx2.Client(event_hooks={'request': [log_request], 'response': [log_response]}) ``` You can also use these hooks to install response processing code, such as this example, which creates a client instance that always raises `httpx2.HTTPStatusError` on 4xx and 5xx responses. ```python def raise_on_4xx_5xx(response): response.raise_for_status() client = httpx2.Client(event_hooks={'response': [raise_on_4xx_5xx]}) ``` !!! note Response event hooks are called before determining if the response body should be read or not. If you need access to the response body inside an event hook, you'll need to call `response.read()`, or for AsyncClients, `response.aread()`. The hooks are also allowed to modify `request` and `response` objects. ```python def add_timestamp(request): request.headers['x-request-timestamp'] = datetime.now(tz=datetime.utc).isoformat() client = httpx2.Client(event_hooks={'request': [add_timestamp]}) ``` Event hooks must always be set as a **list of callables**, and you may register multiple event hooks for each type of event. As well as being able to set event hooks on instantiating the client, there is also an `.event_hooks` property, that allows you to inspect and modify the installed hooks. ```python client = httpx2.Client() client.event_hooks['request'] = [log_request] client.event_hooks['response'] = [log_response, raise_on_4xx_5xx] ``` !!! note If you are using HTTPX's async support, then you need to be aware that hooks registered with `httpx2.AsyncClient` MUST be async functions, rather than plain functions. pydantic-httpx2-6dd59b9/docs/advanced/extensions.md000066400000000000000000000225001526547463400224410ustar00rootroot00000000000000# Extensions Request and response extensions provide a untyped space where additional information may be added. Extensions should be used for features that may not be available on all transports, and that do not fit neatly into [the simplified request/response model](https://www.encode.io/httpcore/extensions/) that the underlying `httpcore2` package inherits from upstream `httpcore` and uses as its API. Several extensions are supported on the request: ```python # Request timeouts actually implemented as an extension on # the request, ensuring that they are passed throughout the # entire call stack. client = httpx2.Client() response = client.get( "https://www.example.com", extensions={"timeout": {"connect": 5.0}} ) response.request.extensions["timeout"] {"connect": 5.0} ``` And on the response: ```python client = httpx2.Client() response = client.get("https://www.example.com") print(response.extensions["http_version"]) # b"HTTP/1.1" # Other server responses could have been # b"HTTP/0.9", b"HTTP/1.0", or b"HTTP/1.1" ``` ## Request Extensions ### `"trace"` The trace extension allows a callback handler to be installed to monitor the internal flow of events within the underlying `httpcore2` transport. The simplest way to explain this is with an example: ```python import httpx2 def log(event_name, info): print(event_name, info) client = httpx2.Client() response = client.get("https://www.example.com/", extensions={"trace": log}) # connection.connect_tcp.started {'host': 'www.example.com', 'port': 443, 'local_address': None, 'timeout': 5.0, 'socket_options': None} # connection.connect_tcp.complete {'return_value': } # connection.start_tls.started {'ssl_context': , 'server_hostname': 'www.example.com', 'timeout': 5.0} # connection.start_tls.complete {'return_value': } # http11.send_request_headers.started {'request': } # http11.send_request_headers.complete {'return_value': None} # http11.send_request_body.started {'request': } # http11.send_request_body.complete {'return_value': None} # http11.receive_response_headers.started {'request': } # http11.receive_response_headers.complete {'return_value': (b'HTTP/1.1', 200, b'OK', [(b'Age', b'553715'), (b'Cache-Control', b'max-age=604800'), (b'Content-Type', b'text/html; charset=UTF-8'), (b'Date', b'Thu, 21 Oct 2021 17:08:42 GMT'), (b'Etag', b'"3147526947+ident"'), (b'Expires', b'Thu, 28 Oct 2021 17:08:42 GMT'), (b'Last-Modified', b'Thu, 17 Oct 2019 07:18:26 GMT'), (b'Server', b'ECS (nyb/1DCD)'), (b'Vary', b'Accept-Encoding'), (b'X-Cache', b'HIT'), (b'Content-Length', b'1256')])} # http11.receive_response_body.started {'request': } # http11.receive_response_body.complete {'return_value': None} # http11.response_closed.started {} # http11.response_closed.complete {'return_value': None} ``` The `event_name` and `info` arguments here will be one of the following: * `{event_type}.{event_name}.started`, `` * `{event_type}.{event_name}.complete`, `{"return_value": <...>}` * `{event_type}.{event_name}.failed`, `{"exception": <...>}` Note that when using async code the handler function passed to `"trace"` must be an `async def ...` function. The following event types are currently exposed... **Establishing the connection** * `"connection.connect_tcp"` * `"connection.connect_unix_socket"` * `"connection.start_tls"` **HTTP/1.1 events** * `"http11.send_request_headers"` * `"http11.send_request_body"` * `"http11.receive_response"` * `"http11.receive_response_body"` * `"http11.response_closed"` **HTTP/2 events** * `"http2.send_connection_init"` * `"http2.send_request_headers"` * `"http2.send_request_body"` * `"http2.receive_response_headers"` * `"http2.receive_response_body"` * `"http2.response_closed"` The exact set of trace events may be subject to change across different versions of `httpcore2`. If you need to rely on a particular set of events it is recommended that you pin installation of the package to a fixed version. ### `"sni_hostname"` The server's hostname, which is used to confirm the hostname supplied by the SSL certificate. If you want to connect to an explicit IP address rather than using the standard DNS hostname lookup, then you'll need to use this request extension. For example: ``` python # Connect to '185.199.108.153' but use 'www.encode.io' in the Host header, #ย and use 'www.encode.io' when SSL verifying the server hostname. client = httpx2.Client() headers = {"Host": "www.encode.io"} extensions = {"sni_hostname": "www.encode.io"} response = client.get( "https://185.199.108.153/path", headers=headers, extensions=extensions ) ``` ### `"timeout"` A dictionary of `str: Optional[float]` timeout values. May include values for `'connect'`, `'read'`, `'write'`, or `'pool'`. For example: ```python # Timeout if a connection takes more than 5 seconds to established, or if # we are blocked waiting on the connection pool for more than 10 seconds. client = httpx2.Client() response = client.get( "https://www.example.com", extensions={"timeout": {"connect": 5.0, "pool": 10.0}} ) ``` This extension is how the `httpx2` timeouts are implemented, ensuring that the timeout values are associated with the request instance and passed throughout the stack. You shouldn't typically be working with this extension directly, but use the higher level `timeout` API instead. ### `"target"` The target that is used as [the HTTP target instead of the URL path](https://datatracker.ietf.org/doc/html/rfc2616#section-5.1.2). This enables support constructing requests that would otherwise be unsupported. * URL paths with non-standard escaping applied. * Forward proxy requests using an absolute URI. * Tunneling proxy requests using `CONNECT` with hostname as the target. * Server-wide `OPTIONS *` requests. Some examples: Using the 'target' extension to send requests without the standard path escaping rules... ```python # Typically a request to "https://www.example.com/test^path" would # connect to "www.example.com" and send an HTTP/1.1 request like... # # GET /test%5Epath HTTP/1.1 # # Using the target extension we can include the literal '^'... # # GET /test^path HTTP/1.1 # # Note that requests must still be valid HTTP requests. # For example including whitespace in the target will raise a `LocalProtocolError`. extensions = {"target": b"/test^path"} response = httpx2.get("https://www.example.com", extensions=extensions) ``` The `target` extension also allows server-wide `OPTIONS *` requests to be constructed... ```python # This will send the following request... # # CONNECT * HTTP/1.1 extensions = {"target": b"*"} response = httpx2.request("CONNECT", "https://www.example.com", extensions=extensions) ``` ## Response Extensions ### `"http_version"` The HTTP version, as bytes. Eg. `b"HTTP/1.1"`. When using HTTP/1.1 the response line includes an explicit version, and the value of this key could feasibly be one of `b"HTTP/0.9"`, `b"HTTP/1.0"`, or `b"HTTP/1.1"`. When using HTTP/2 there is no further response versioning included in the protocol, and the value of this key will always be `b"HTTP/2"`. ### `"reason_phrase"` The reason-phrase of the HTTP response, as bytes. For example `b"OK"`. Some servers may include a custom reason phrase, although this is not recommended. HTTP/2 onwards does not include a reason phrase on the wire. When no key is included, a default based on the status code may be used. ### `"stream_id"` When HTTP/2 is being used the `"stream_id"` response extension can be accessed to determine the ID of the data stream that the response was sent on. ### `"network_stream"` The `"network_stream"` extension allows developers to handle HTTP `CONNECT` and `Upgrade` requests, by providing an API that steps outside the standard request/response model, and can directly read or write to the network. The interface provided by the network stream: * `read(max_bytes, timeout = None) -> bytes` * `write(buffer, timeout = None)` * `close()` * `start_tls(ssl_context, server_hostname = None, timeout = None) -> NetworkStream` * `get_extra_info(info) -> Any` This API can be used as the foundation for working with HTTP proxies, WebSocket upgrades, and other advanced use-cases. See the [network backends documentation](https://www.encode.io/httpcore/network-backends/) for more information on working directly with network streams. **Extra network information** The network stream abstraction also allows access to various low-level information that may be exposed by the underlying socket: ```python response = httpx2.get("https://www.example.com") network_stream = response.extensions["network_stream"] client_addr = network_stream.get_extra_info("client_addr") server_addr = network_stream.get_extra_info("server_addr") print("Client address", client_addr) print("Server address", server_addr) ``` The socket SSL information is also available through this interface, although you need to ensure that the underlying connection is still open, in order to access it... ```python with httpx2.stream("GET", "https://www.example.com") as response: network_stream = response.extensions["network_stream"] ssl_object = network_stream.get_extra_info("ssl_object") print("TLS version", ssl_object.version()) ``` pydantic-httpx2-6dd59b9/docs/advanced/proxies.md000066400000000000000000000070201526547463400217330ustar00rootroot00000000000000HTTPX supports setting up [HTTP proxies](https://en.wikipedia.org/wiki/Proxy_server#Web_proxy_servers) via the `proxy` parameter to be passed on client initialization or top-level API functions like `httpx2.get(..., proxy=...)`.
Diagram of how a proxy works (source: Wikipedia). The left hand side "Internet" blob may be your HTTPX client requesting example.com through a proxy.
## HTTP Proxies To route all traffic (HTTP and HTTPS) to a proxy located at `http://localhost:8030`, pass the proxy URL to the client... ```python with httpx2.Client(proxy="http://localhost:8030") as client: ... ``` For more advanced use cases, pass a mounts `dict`. For example, to route HTTP and HTTPS requests to 2 different proxies, respectively located at `http://localhost:8030`, and `http://localhost:8031`, pass a `dict` of proxy URLs: ```python proxy_mounts = { "http://": httpx2.HTTPTransport(proxy="http://localhost:8030"), "https://": httpx2.HTTPTransport(proxy="http://localhost:8031"), } with httpx2.Client(mounts=proxy_mounts) as client: ... ``` For detailed information about how `mounts` routes requests, see the [Routing](transports.md#routing) section. !!! tip "Gotcha" In most cases, the proxy URL for the `https://` key _should_ use the `http://` scheme (that's not a typo!). This is because HTTP proxying requires initiating a connection with the proxy server. While it's possible that your proxy supports doing it via HTTPS, most proxies only support doing it via HTTP. For more information, see [FORWARD vs TUNNEL](#forward-vs-tunnel). ## Authentication Proxy credentials can be passed as the `userinfo` section of the proxy URL. For example: ```python with httpx2.Client(proxy="http://username:password@localhost:8030") as client: ... ``` ## Proxy mechanisms !!! note This section describes **advanced** proxy concepts and functionality. ### FORWARD vs TUNNEL In general, the flow for making an HTTP request through a proxy is as follows: 1. The client connects to the proxy (initial connection request). 2. The proxy transfers data to the server on your behalf. How exactly step 2/ is performed depends on which of two proxying mechanisms is used: * **Forwarding**: the proxy makes the request for you, and sends back the response it obtained from the server. * **Tunnelling**: the proxy establishes a TCP connection to the server on your behalf, and the client reuses this connection to send the request and receive the response. This is known as an [HTTP Tunnel](https://en.wikipedia.org/wiki/HTTP_tunnel). This mechanism is how you can access websites that use HTTPS from an HTTP proxy (the client "upgrades" the connection to HTTPS by performing the TLS handshake with the server over the TCP connection provided by the proxy). ### Troubleshooting proxies If you encounter issues when setting up proxies, please refer to our [Troubleshooting guide](../troubleshooting.md#proxies). ## SOCKS In addition to HTTP proxies, `httpcore2` also supports proxies using the SOCKS protocol. This is an optional feature that requires an additional third-party library be installed before use. You can install SOCKS support using `pip`: ```shell pip install 'httpx2[socks]' ``` You can now configure a client to make requests via a proxy using the SOCKS protocol: ```python httpx2.Client(proxy='socks5://user:pass@host:port') ``` pydantic-httpx2-6dd59b9/docs/advanced/resource-limits.md000066400000000000000000000011271526547463400233720ustar00rootroot00000000000000You can control the connection pool size using the `limits` keyword argument on the client. It takes instances of `httpx2.Limits` which define: - `max_keepalive_connections`, number of allowable keep-alive connections, or `None` to always allow. (Defaults 20) - `max_connections`, maximum number of allowable connections, or `None` for no limits. (Default 100) - `keepalive_expiry`, time limit on idle keep-alive connections in seconds, or `None` for no limits. (Default 5) ```python limits = httpx2.Limits(max_keepalive_connections=5, max_connections=10) client = httpx2.Client(limits=limits) ```pydantic-httpx2-6dd59b9/docs/advanced/ssl.md000066400000000000000000000071311526547463400210460ustar00rootroot00000000000000When making a request over HTTPS, HTTPX needs to verify the identity of the requested host. To do this, it uses a bundle of SSL certificates (a.k.a. CA bundle) delivered by a trusted certificate authority (CA). ### Enabling and disabling verification By default httpx2 will verify HTTPS connections, and raise an error for invalid SSL cases... ```pycon >>> httpx2.get("https://expired.badssl.com/") httpx2.ConnectError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:997) ``` You can disable SSL verification completely and allow insecure requests... ```pycon >>> httpx2.get("https://expired.badssl.com/", verify=False) ``` ### Configuring client instances If you're using a `Client()` instance you should pass any `verify=<...>` configuration when instantiating the client. By default the operating system's trust store is used for SSL verification, via [the `truststore` package](https://truststore.readthedocs.io/). For more complex configurations you can pass an [SSL Context](https://docs.python.org/3/library/ssl.html) instance... ```python import ssl import truststore import httpx2 # This SSL context is equivalent to the default `verify=True`. ctx = truststore.SSLContext(ssl.PROTOCOL_TLS_CLIENT) client = httpx2.Client(verify=ctx) ``` Using [the `certifi` CA bundle](https://certifiio.readthedocs.io/en/latest/) instead of the system trust store... ```python import certifi import httpx2 import ssl # Use the certifi CA bundle. ctx = ssl.create_default_context(cafile=certifi.where()) client = httpx2.Client(verify=ctx) ``` Loading an alternative certificate verification store using [the standard SSL context API](https://docs.python.org/3/library/ssl.html)... ```python import httpx2 import ssl # Use an explicitly configured certificate store. ctx = ssl.create_default_context(cafile="path/to/certs.pem") # Either cafile or capath. client = httpx2.Client(verify=ctx) ``` ### Client side certificates Client side certificates allow a remote server to verify the client. They tend to be used within private organizations to authenticate requests to remote servers. You can specify client-side certificates, using the [`.load_cert_chain()`](https://docs.python.org/3/library/ssl.html#ssl.SSLContext.load_cert_chain) API... ```python ctx = ssl.create_default_context() ctx.load_cert_chain(certfile="path/to/client.pem") # Optionally also keyfile or password. client = httpx2.Client(verify=ctx) ``` ### Working with `SSL_CERT_FILE` and `SSL_CERT_DIR` `httpx2` does respect the `SSL_CERT_FILE` and `SSL_CERT_DIR` environment variables by default. For details, refer to [the section on the environment variables page](../environment_variables.md#ssl_cert_file). ### Making HTTPS requests to a local server When making requests to local servers, such as a development server running on `localhost`, you will typically be using unencrypted HTTP connections. If you do need to make HTTPS connections to a local server, for example to test an HTTPS-only service, you will need to create and use your own certificates. Here's one way to do it... 1. Use [trustme](https://github.com/python-trio/trustme) to generate a pair of server key/cert files, and a client cert file. 2. Pass the server key/cert files when starting your local server. (This depends on the particular web server you're using. For example, [Uvicorn](https://www.uvicorn.org) provides the `--ssl-keyfile` and `--ssl-certfile` options.) 3. Configure `httpx2` to use the certificates stored in `client.pem`. ```python ctx = ssl.create_default_context(cafile="client.pem") client = httpx2.Client(verify=ctx) ``` pydantic-httpx2-6dd59b9/docs/advanced/text-encodings.md000066400000000000000000000071131526547463400232000ustar00rootroot00000000000000When accessing `response.text`, we need to decode the response bytes into a unicode text representation. By default `httpx2` will use `"charset"` information included in the response `Content-Type` header to determine how the response bytes should be decoded into text. In cases where no charset information is included on the response, the default behaviour is to assume "utf-8" encoding, which is by far the most widely used text encoding on the internet. ## Using the default encoding To understand this better let's start by looking at the default behaviour for text decoding... ```python import httpx2 # Instantiate a client with the default configuration. client = httpx2.Client() # Using the client... response = client.get(...) print(response.encoding) # This will either print the charset given in # the Content-Type charset, or else "utf-8". print(response.text) # The text will either be decoded with the Content-Type # charset, or using "utf-8". ``` This is normally absolutely fine. Most servers will respond with a properly formatted Content-Type header, including a charset encoding. And in most cases where no charset encoding is included, UTF-8 is very likely to be used, since it is so widely adopted. ## Using an explicit encoding In some cases we might be making requests to a site where no character set information is being set explicitly by the server, but we know what the encoding is. In this case it's best to set the default encoding explicitly on the client. ```python import httpx2 # Instantiate a client with a Japanese character set as the default encoding. client = httpx2.Client(default_encoding="shift-jis") # Using the client... response = client.get(...) print(response.encoding) # This will either print the charset given in # the Content-Type charset, or else "shift-jis". print(response.text) # The text will either be decoded with the Content-Type # charset, or using "shift-jis". ``` ## Using auto-detection In cases where the server is not reliably including character set information, and where we don't know what encoding is being used, we can enable auto-detection to make a best-guess attempt when decoding from bytes to text. To use auto-detection you need to set the `default_encoding` argument to a callable instead of a string. This callable should be a function which takes the input bytes as an argument and returns the character set to use for decoding those bytes to text. There are two widely used Python packages which both handle this functionality: * [`chardet`](https://chardet.readthedocs.io/) - This is a well established package, and is a port of [the auto-detection code in Mozilla](https://www-archive.mozilla.org/projects/intl/chardet.html). * [`charset-normalizer`](https://charset-normalizer.readthedocs.io/) - A newer package, motivated by `chardet`, with a different approach. Let's take a look at installing autodetection using one of these packages... ```shell pip install httpx2 pip install chardet ``` Once `chardet` is installed, we can configure a client to use character-set autodetection. ```python import httpx2 import chardet def autodetect(content): return chardet.detect(content).get("encoding") # Using a client with character-set autodetection enabled. client = httpx2.Client(default_encoding=autodetect) response = client.get(...) print(response.encoding) # This will either print the charset given in # the Content-Type charset, or else the auto-detected # character set. print(response.text) ``` pydantic-httpx2-6dd59b9/docs/advanced/timeouts.md000066400000000000000000000053241526547463400221200ustar00rootroot00000000000000HTTPX is careful to enforce timeouts everywhere by default. The default behavior is to raise a `TimeoutException` after 5 seconds of network inactivity. ## Setting and disabling timeouts You can set timeouts for an individual request: ```python # Using the top-level API: httpx2.get('http://example.com/api/v1/example', timeout=10.0) # Using a client instance: with httpx2.Client() as client: client.get("http://example.com/api/v1/example", timeout=10.0) ``` Or disable timeouts for an individual request: ```python # Using the top-level API: httpx2.get('http://example.com/api/v1/example', timeout=None) # Using a client instance: with httpx2.Client() as client: client.get("http://example.com/api/v1/example", timeout=None) ``` ## Setting a default timeout on a client You can set a timeout on a client instance, which results in the given `timeout` being used as the default for requests made with this client: ```python client = httpx2.Client() # Use a default 5s timeout everywhere. client = httpx2.Client(timeout=10.0) # Use a default 10s timeout everywhere. client = httpx2.Client(timeout=None) # Disable all timeouts by default. ``` ## Fine tuning the configuration HTTPX also allows you to specify the timeout behavior in more fine grained detail. There are four different types of timeouts that may occur. These are **connect**, **read**, **write**, and **pool** timeouts. * The **connect** timeout specifies the maximum amount of time to wait until a socket connection to the requested host is established. If HTTPX is unable to connect within this time frame, a `ConnectTimeout` exception is raised. * The **read** timeout specifies the maximum duration to wait for a chunk of data to be received (for example, a chunk of the response body). If HTTPX is unable to receive data within this time frame, a `ReadTimeout` exception is raised. * The **write** timeout specifies the maximum duration to wait for a chunk of data to be sent (for example, a chunk of the request body). If HTTPX is unable to send data within this time frame, a `WriteTimeout` exception is raised. * The **pool** timeout specifies the maximum duration to wait for acquiring a connection from the connection pool. If HTTPX is unable to acquire a connection within this time frame, a `PoolTimeout` exception is raised. A related configuration here is the maximum number of allowable connections in the connection pool, which is configured by the `limits` argument. You can configure the timeout behavior for any of these values... ```python # A client with a 60s timeout for connecting, and a 10s timeout elsewhere. timeout = httpx2.Timeout(10.0, connect=60.0) client = httpx2.Client(timeout=timeout) response = client.get('http://example.com/') ```pydantic-httpx2-6dd59b9/docs/advanced/transports.md000066400000000000000000000336201526547463400224660ustar00rootroot00000000000000HTTPX's `Client` also accepts a `transport` argument. This argument allows you to provide a custom Transport object that will be used to perform the actual sending of the requests. ## HTTP Transport For some advanced configuration you might need to instantiate a transport class directly, and pass it to the client instance. One example is the `local_address` configuration which is only available via this low-level API. ```pycon >>> import httpx2 >>> transport = httpx2.HTTPTransport(local_address="0.0.0.0") >>> client = httpx2.Client(transport=transport) ``` Connection retries are also available via this interface. Requests will be retried the given number of times in case an `httpx2.ConnectError` or an `httpx2.ConnectTimeout` occurs, allowing smoother operation under flaky networks. If you need other forms of retry behaviors, such as handling read/write errors or reacting to `503 Service Unavailable`, consider general-purpose tools such as [tenacity](https://github.com/jd/tenacity). ```pycon >>> import httpx2 >>> transport = httpx2.HTTPTransport(retries=1) >>> client = httpx2.Client(transport=transport) ``` Similarly, instantiating a transport directly provides a `uds` option for connecting via a Unix Domain Socket that is only available via this low-level API: ```pycon >>> import httpx2 >>> # Connect to the Docker API via a Unix Socket. >>> transport = httpx2.HTTPTransport(uds="/var/run/docker.sock") >>> client = httpx2.Client(transport=transport) >>> response = client.get("http://docker/info") >>> response.json() {"ID": "...", "Containers": 4, "Images": 74, ...} ``` ## WSGI Transport You can configure an `httpx2` client to call directly into a Python web application using the WSGI protocol. This is particularly useful for two main use-cases: * Using `httpx2` as a client inside test cases. * Mocking out external services during tests or in dev or staging environments. ### Example Here's an example of integrating against a Flask application: ```python from flask import Flask import httpx2 app = Flask(__name__) @app.route("/") def hello(): return "Hello World!" transport = httpx2.WSGITransport(app=app) with httpx2.Client(transport=transport, base_url="http://testserver") as client: r = client.get("/") assert r.status_code == 200 assert r.text == "Hello World!" ``` ### Configuration For some more complex cases you might need to customize the WSGI transport. This allows you to: * Inspect 500 error responses rather than raise exceptions by setting `raise_app_exceptions=False`. * Mount the WSGI application at a subpath by setting `script_name` (WSGI). * Use a given client address for requests by setting `remote_addr` (WSGI). For example: ```python # Instantiate a client that makes WSGI requests with a client IP of "1.2.3.4". transport = httpx2.WSGITransport(app=app, remote_addr="1.2.3.4") with httpx2.Client(transport=transport, base_url="http://testserver") as client: ... ``` ## ASGI Transport You can configure an `httpx2` client to call directly into an async Python web application using the ASGI protocol. This is particularly useful for two main use-cases: * Using `httpx2` as a client inside test cases. * Mocking out external services during tests or in dev or staging environments. ### Example Let's take this Starlette application as an example: ```python from starlette.applications import Starlette from starlette.responses import HTMLResponse from starlette.routing import Route async def hello(request): return HTMLResponse("Hello World!") app = Starlette(routes=[Route("/", hello)]) ``` We can make requests directly against the application, like so: ```python transport = httpx2.ASGITransport(app=app) async with httpx2.AsyncClient(transport=transport, base_url="http://testserver") as client: r = await client.get("/") assert r.status_code == 200 assert r.text == "Hello World!" ``` ### Configuration For some more complex cases you might need to customise the ASGI transport. This allows you to: * Inspect 500 error responses rather than raise exceptions by setting `raise_app_exceptions=False`. * Mount the ASGI application at a subpath by setting `root_path`. * Use a given client address for requests by setting `client`. For example: ```python # Instantiate a client that makes ASGI requests with a client IP of "1.2.3.4", # on port 123. transport = httpx2.ASGITransport(app=app, client=("1.2.3.4", 123)) async with httpx2.AsyncClient(transport=transport, base_url="http://testserver") as client: ... ``` See [the ASGI documentation](https://asgi.readthedocs.io/en/latest/specs/www.html#connection-scope) for more details on the `client` and `root_path` keys. ### ASGI startup and shutdown It is not in the scope of HTTPX to trigger ASGI lifespan events of your app. However it is suggested to use `LifespanManager` from [asgi-lifespan](https://github.com/florimondmanca/asgi-lifespan#usage) in pair with `AsyncClient`. ## Custom transports A transport instance must implement the low-level Transport API which deals with sending a single request, and returning a response. You should either subclass `httpx2.BaseTransport` to implement a transport to use with `Client`, or subclass `httpx2.AsyncBaseTransport` to implement a transport to use with `AsyncClient`. At the layer of the transport API we're using the familiar `Request` and `Response` models. See the `handle_request` and `handle_async_request` docstrings for more details on the specifics of the Transport API. A complete example of a custom transport implementation would be: ```python import json import httpx2 class HelloWorldTransport(httpx2.BaseTransport): """ A mock transport that always returns a JSON "Hello, world!" response. """ def handle_request(self, request): return httpx2.Response(200, json={"text": "Hello, world!"}) ``` Or this example, which uses a custom transport and the `mounts` argument to always redirect `http://` requests. ```python class HTTPSRedirect(httpx2.BaseTransport): """ A transport that always redirects to HTTPS. """ def handle_request(self, request): url = request.url.copy_with(scheme="https") return httpx2.Response(303, headers={"Location": str(url)}) # A client where any `http` requests are always redirected to `https` client = httpx2.Client( mounts={ "http://": HTTPSRedirect(), "https://": httpx2.HTTPTransport(), }, follow_redirects=True, ) ``` A useful pattern here is custom transport classes that wrap the default HTTP implementation. For example... ```python class DebuggingTransport(httpx2.BaseTransport): def __init__(self, **kwargs): self._wrapper = httpx2.HTTPTransport(**kwargs) def handle_request(self, request): print(f">>> {request}") response = self._wrapper.handle_request(request) print(f"<<< {response}") return response def close(self): self._wrapper.close() transport = DebuggingTransport() client = httpx2.Client(transport=transport) ``` Here's another case, where we're using a round-robin across a number of different proxies... ```python class ProxyRoundRobin(httpx2.BaseTransport): def __init__(self, proxies, **kwargs): self._transports = [ httpx2.HTTPTransport(proxy=proxy, **kwargs) for proxy in proxies ] self._idx = 0 def handle_request(self, request): transport = self._transports[self._idx] self._idx = (self._idx + 1) % len(self._transports) return transport.handle_request(request) def close(self): for transport in self._transports: transport.close() proxies = [ httpx2.Proxy("http://127.0.0.1:8081"), httpx2.Proxy("http://127.0.0.1:8082"), httpx2.Proxy("http://127.0.0.1:8083"), ] transport = ProxyRoundRobin(proxies=proxies) client = httpx2.Client(transport=transport) ``` ## Mock transports During testing it can often be useful to be able to mock out a transport, and return pre-determined responses, rather than making actual network requests. The `httpx2.MockTransport` class accepts a handler function, which can be used to map requests onto pre-determined responses: ```python def handler(request): return httpx2.Response(200, json={"text": "Hello, world!"}) # Switch to a mock transport, if the TESTING environment variable is set. if os.environ.get('TESTING', '').upper() == "TRUE": transport = httpx2.MockTransport(handler) else: transport = httpx2.HTTPTransport() client = httpx2.Client(transport=transport) ``` For more advanced mocking, see [httpx2-pytest](../third_party_packages.md#httpx2-pytest) or [pytest-HTTPX2](../third_party_packages.md#pytest-httpx2). ## Mounting transports You can also mount transports against given schemes or domains, to control which transport an outgoing request should be routed via, with [the same style used for specifying proxy routing](#routing). ```python import httpx2 class HTTPSRedirectTransport(httpx2.BaseTransport): """ A transport that always redirects to HTTPS. """ def handle_request(self, method, url, headers, stream, extensions): scheme, host, port, path = url if port is None: location = b"https://%s%s" % (host, path) else: location = b"https://%s:%d%s" % (host, port, path) stream = httpx2.ByteStream(b"") headers = [(b"location", location)] extensions = {} return 303, headers, stream, extensions # A client where any `http` requests are always redirected to `https` mounts = {'http://': HTTPSRedirectTransport()} client = httpx2.Client(mounts=mounts) ``` A couple of other sketches of how you might take advantage of mounted transports... Disabling HTTP/2 on a single given domain... ```python mounts = { "all://": httpx2.HTTPTransport(http2=True), "all://*example.org": httpx2.HTTPTransport() } client = httpx2.Client(mounts=mounts) ``` Mocking requests to a given domain: ```python # All requests to "example.org" should be mocked out. # Other requests occur as usual. def handler(request): return httpx2.Response(200, json={"text": "Hello, World!"}) mounts = {"all://example.org": httpx2.MockTransport(handler)} client = httpx2.Client(mounts=mounts) ``` Adding support for custom schemes: ```python # Support URLs like "file:///Users/sylvia_green/websites/new_client/index.html" mounts = {"file://": FileSystemTransport()} client = httpx2.Client(mounts=mounts) ``` ### Routing HTTPX provides a powerful mechanism for routing requests, allowing you to write complex rules that specify which transport should be used for each request. The `mounts` dictionary maps URL patterns to HTTP transports. HTTPX matches requested URLs against URL patterns to decide which transport should be used, if any. Matching is done from most specific URL patterns (e.g. `https://:`) to least specific ones (e.g. `https://`). HTTPX supports routing requests based on **scheme**, **domain**, **port**, or a combination of these. ### Wildcard routing Route everything through a transport... ```python mounts = { "all://": httpx2.HTTPTransport(proxy="http://localhost:8030"), } ``` ### Scheme routing Route HTTP requests through one transport, and HTTPS requests through another... ```python mounts = { "http://": httpx2.HTTPTransport(proxy="http://localhost:8030"), "https://": httpx2.HTTPTransport(proxy="http://localhost:8031"), } ``` ### Domain routing Proxy all requests on domain "example.com", let other requests pass through... ```python mounts = { "all://example.com": httpx2.HTTPTransport(proxy="http://localhost:8030"), } ``` Proxy HTTP requests on domain "example.com", let HTTPS and other requests pass through... ```python mounts = { "http://example.com": httpx2.HTTPTransport(proxy="http://localhost:8030"), } ``` Proxy all requests to "example.com" and its subdomains, let other requests pass through... ```python mounts = { "all://*example.com": httpx2.HTTPTransport(proxy="http://localhost:8030"), } ``` Proxy all requests to strict subdomains of "example.com", let "example.com" and other requests pass through... ```python mounts = { "all://*.example.com": httpx2.HTTPTransport(proxy="http://localhost:8030"), } ``` ### Port routing Proxy HTTPS requests on port 1234 to "example.com"... ```python mounts = { "https://example.com:1234": httpx2.HTTPTransport(proxy="http://localhost:8030"), } ``` Proxy all requests on port 1234... ```python mounts = { "all://*:1234": httpx2.HTTPTransport(proxy="http://localhost:8030"), } ``` ### No-proxy support It is also possible to define requests that _shouldn't_ be routed through the transport. To do so, pass `None` as the proxy URL. For example... ```python mounts = { # Route requests through a proxy by default... "all://": httpx2.HTTPTransport(proxy="http://localhost:8031"), # Except those for "example.com". "all://example.com": None, } ``` ### Complex configuration example You can combine the routing features outlined above to build complex proxy routing configurations. For example... ```python mounts = { # Route all traffic through a proxy by default... "all://": httpx2.HTTPTransport(proxy="http://localhost:8030"), # But don't use proxies for HTTPS requests to "domain.io"... "https://domain.io": None, # And use another proxy for requests to "example.com" and its subdomains... "all://*example.com": httpx2.HTTPTransport(proxy="http://localhost:8031"), # And yet another proxy if HTTP is used, # and the "internal" subdomain on port 5550 is requested... "http://internal.example.com:5550": httpx2.HTTPTransport(proxy="http://localhost:8032"), } ``` ### Environment variables There are also environment variables that can be used to control the dictionary of the client mounts. They can be used to configure HTTP proxying for clients. See documentation on [`HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`](../environment_variables.md#http_proxy-https_proxy-all_proxy) and [`NO_PROXY`](../environment_variables.md#no_proxy) for more information. pydantic-httpx2-6dd59b9/docs/api.md000066400000000000000000000137151526547463400172560ustar00rootroot00000000000000# Developer Interface ## Helper Functions !!! note Only use these functions if you're testing HTTPX in a console or making a small number of requests. Using a `Client` will enable HTTP/2 and connection pooling for more efficient and long-lived connections. ::: httpx2.request ::: httpx2.get ::: httpx2.options ::: httpx2.head ::: httpx2.post ::: httpx2.put ::: httpx2.patch ::: httpx2.delete ::: httpx2.query ::: httpx2.stream ::: httpx2.websocket ## `Client` ::: httpx2.Client options: members: - headers - cookies - params - auth - request - get - head - options - post - put - patch - delete - query - stream - sse - websocket - build_request - send - close ## `AsyncClient` ::: httpx2.AsyncClient options: members: - headers - cookies - params - auth - request - get - head - options - post - put - patch - delete - query - stream - sse - websocket - build_request - send - aclose ## `Response` *An HTTP response.* * `def __init__(...)` * `.status_code` - **int** * `.reason_phrase` - **str** * `.http_version` - `"HTTP/2"` or `"HTTP/1.1"` * `.url` - **URL** * `.headers` - **Headers** * `.content` - **bytes** * `.text` - **str** * `.encoding` - **str** * `.is_redirect` - **bool** * `.request` - **Request** * `.next_request` - **Optional[Request]** * `.cookies` - **Cookies** * `.history` - **List[Response]** * `.elapsed` - **[timedelta](https://docs.python.org/3/library/datetime.html)** * The amount of time elapsed between sending the request and calling `close()` on the corresponding response received for that request. [total_seconds()](https://docs.python.org/3/library/datetime.html#datetime.timedelta.total_seconds) to correctly get the total elapsed seconds. * `def .raise_for_status()` - **Response** * `def .json()` - **Any** * `def .read()` - **bytes** * `def .iter_raw([chunk_size])` - **bytes iterator** * `def .iter_bytes([chunk_size])` - **bytes iterator** * `def .iter_text([chunk_size])` - **text iterator** * `def .iter_lines()` - **text iterator** * `def .close()` - **None** * `def .next()` - **Response** * `def .aread()` - **bytes** * `def .aiter_raw([chunk_size])` - **async bytes iterator** * `def .aiter_bytes([chunk_size])` - **async bytes iterator** * `def .aiter_text([chunk_size])` - **async text iterator** * `def .aiter_lines()` - **async text iterator** * `def .aclose()` - **None** * `def .anext()` - **Response** ## `Request` *An HTTP request. Can be constructed explicitly for more control over exactly what gets sent over the wire.* ```pycon >>> request = httpx2.Request("GET", "https://example.org", headers={'host': 'example.org'}) >>> response = client.send(request) ``` * `def __init__(method, url, [params], [headers], [cookies], [content], [data], [files], [json], [stream])` * `.method` - **str** * `.url` - **URL** * `.content` - **byte**, **byte iterator**, or **byte async iterator** * `.headers` - **Headers** * `.cookies` - **Cookies** ## `URL` *A normalized, IDNA supporting URL.* ```pycon >>> url = URL("https://example.org/") >>> url.host 'example.org' ``` * `def __init__(url, **kwargs)` * `.scheme` - **str** * `.authority` - **str** * `.host` - **str** * `.port` - **int** * `.path` - **str** * `.query` - **str** * `.raw_path` - **str** * `.fragment` - **str** * `.origin` - **Origin** * `.is_ssl` - **bool** * `.is_absolute_url` - **bool** * `.is_relative_url` - **bool** * `def .copy_with([scheme], [authority], [path], [query], [fragment])` - **URL** ## `Origin` *An immutable, hashable set of normalized scheme, host, and effective port information.* ```pycon >>> URL('https://example.org').origin == URL('HTTPS://EXAMPLE.ORG:443').origin True >>> URL('wss://[::1]/socket').origin Origin(scheme='wss', host='::1', port=443) ``` * `def __init__(url)` * `.scheme` - **str** * `.host` - **str** * `.port` - **int** or **None** ## `Headers` *A case-insensitive multi-dict.* ```pycon >>> headers = Headers({'Content-Type': 'application/json'}) >>> headers['content-type'] 'application/json' ``` * `def __init__(self, headers, encoding=None)` * `def copy()` - **Headers** ## `Cookies` *A dict-like cookie store.* ```pycon >>> cookies = Cookies() >>> cookies.set("name", "value", domain="example.org") ``` * `def __init__(cookies: [dict, Cookies, CookieJar])` * `.jar` - **CookieJar** * `def extract_cookies(response)` * `def set_cookie_header(request)` * `def set(name, value, [domain], [path])` * `def get(name, [domain], [path])` * `def delete(name, [domain], [path])` * `def clear([domain], [path])` * *Standard mutable mapping interface* ## `Proxy` *A configuration of the proxy server.* ```pycon >>> proxy = Proxy("http://proxy.example.com:8030") >>> client = Client(proxy=proxy) ``` * `def __init__(url, [ssl_context], [auth], [headers])` * `.url` - **URL** * `.auth` - **tuple[str, str]** * `.headers` - **Headers** * `.ssl_context` - **SSLContext** ## `EventSource` ::: httpx2.EventSource options: members: - response ## `ServerSentEvent` ::: httpx2.ServerSentEvent options: members: - event - data - id - retry - json ## `WebSocketSession` ::: httpx2.websockets.WebSocketSession options: members: - subprotocol - response - send_text - send_bytes - send_json - receive_text - receive_bytes - receive_json - ping - close ## `AsyncWebSocketSession` ::: httpx2.websockets.AsyncWebSocketSession options: members: - subprotocol - response - send_text - send_bytes - send_json - receive_text - receive_bytes - receive_json - ping - close ## `alias_httpx` ::: httpx2.alias_httpx pydantic-httpx2-6dd59b9/docs/async.md000066400000000000000000000144751526547463400176260ustar00rootroot00000000000000# Async Support HTTPX offers a standard synchronous API by default, but also gives you the option of an async client if you need it. Async is a concurrency model that is far more efficient than multi-threading, and can provide significant performance benefits and enable the use of long-lived network connections such as WebSockets. If you're working with an async web framework then you'll also want to use an async client for sending outgoing HTTP requests. ## Making Async requests To make asynchronous requests, you'll need an `AsyncClient`. ```pycon >>> async with httpx2.AsyncClient() as client: ... r = await client.get('https://www.example.com/') ... >>> r ``` !!! tip Use [IPython](https://ipython.readthedocs.io/en/stable/) or Python with `python -m asyncio` to try this code interactively, as they support executing `async`/`await` expressions in the console. ## API Differences If you're using an async client then there are a few bits of API that use async methods. ### Making requests The request methods are all async, so you should use `response = await client.get(...)` style for all of the following: * `AsyncClient.get(url, ...)` * `AsyncClient.options(url, ...)` * `AsyncClient.head(url, ...)` * `AsyncClient.post(url, ...)` * `AsyncClient.put(url, ...)` * `AsyncClient.patch(url, ...)` * `AsyncClient.delete(url, ...)` * `AsyncClient.query(url, ...)` * `AsyncClient.request(method, url, ...)` * `AsyncClient.send(request, ...)` ### Opening and closing clients Use `async with httpx2.AsyncClient()` if you want a context-managed client... ```python async with httpx2.AsyncClient() as client: ... ``` !!! warning In order to get the most benefit from connection pooling, make sure you're not instantiating multiple client instances - for example by using `async with` inside a "hot loop". This can be achieved either by having a single scoped client that's passed throughout wherever it's needed, or by having a single global client instance. Alternatively, use `await client.aclose()` if you want to close a client explicitly: ```python client = httpx2.AsyncClient() ... await client.aclose() ``` ### Streaming responses The `AsyncClient.stream(method, url, ...)` method is an async context block. ```pycon >>> client = httpx2.AsyncClient() >>> async with client.stream('GET', 'https://www.example.com/') as response: ... async for chunk in response.aiter_bytes(): ... ... ``` The async response streaming methods are: * `Response.aread()` - For conditionally reading a response inside a stream block. * `Response.aiter_bytes()` - For streaming the response content as bytes. * `Response.aiter_text()` - For streaming the response content as text. * `Response.aiter_lines()` - For streaming the response content as lines of text. * `Response.aiter_raw()` - For streaming the raw response bytes, without applying content decoding. * `Response.aclose()` - For closing the response. You don't usually need this, since `.stream` block closes the response automatically on exit. For situations when context block usage is not practical, it is possible to enter "manual mode" by sending a [`Request` instance](advanced/clients.md#request-instances) using `client.send(..., stream=True)`. Example in the context of forwarding the response to a streaming web endpoint with [Starlette](https://www.starlette.io): ```python import httpx2 from starlette.background import BackgroundTask from starlette.responses import StreamingResponse client = httpx2.AsyncClient() async def home(request): req = client.build_request("GET", "https://www.example.com/") r = await client.send(req, stream=True) return StreamingResponse(r.aiter_text(), background=BackgroundTask(r.aclose)) ``` !!! warning When using this "manual streaming mode", it is your duty as a developer to make sure that `Response.aclose()` is called eventually. Failing to do so would leave connections open, most likely resulting in resource leaks down the line. ### Streaming requests When sending a streaming request body with an `AsyncClient` instance, you should use an async bytes generator instead of a bytes generator: ```python async def upload_bytes(): ... # yield byte content await client.post(url, content=upload_bytes()) ``` ### Explicit transport instances When instantiating a transport instance directly, you need to use `httpx2.AsyncHTTPTransport`. For instance: ```pycon >>> import httpx2 >>> transport = httpx2.AsyncHTTPTransport(retries=1) >>> async with httpx2.AsyncClient(transport=transport) as client: >>> ... ``` ## Supported async environments HTTPX supports either `asyncio` or `trio` as an async environment. It will auto-detect which of those two to use as the backend for socket operations and concurrency primitives. ### [AsyncIO](https://docs.python.org/3/library/asyncio.html) AsyncIO is Python's [built-in library](https://docs.python.org/3/library/asyncio.html) for writing concurrent code with the async/await syntax. ```python import asyncio import httpx2 async def main(): async with httpx2.AsyncClient() as client: response = await client.get('https://www.example.com/') print(response) asyncio.run(main()) ``` ### [Trio](https://github.com/python-trio/trio) Trio is [an alternative async library](https://trio.readthedocs.io/en/stable/), designed around the [the principles of structured concurrency](https://en.wikipedia.org/wiki/Structured_concurrency). ```python import httpx2 import trio async def main(): async with httpx2.AsyncClient() as client: response = await client.get('https://www.example.com/') print(response) trio.run(main) ``` !!! important The `trio` package must be installed to use the Trio backend. ### [AnyIO](https://github.com/agronholm/anyio) AnyIO is an [asynchronous networking and concurrency library](https://anyio.readthedocs.io/) that works on top of either `asyncio` or `trio`. It blends in with native libraries of your chosen backend (defaults to `asyncio`). ```python import httpx2 import anyio async def main(): async with httpx2.AsyncClient() as client: response = await client.get('https://www.example.com/') print(response) anyio.run(main, backend='trio') ``` ## Calling into Python Web Apps For details on calling directly into ASGI applications, see [the `ASGITransport` docs](../advanced/transports#asgitransport). pydantic-httpx2-6dd59b9/docs/code_of_conduct.md000066400000000000000000000110321526547463400216100ustar00rootroot00000000000000# Code of Conduct We expect contributors to our projects and online spaces to follow [the Python Software Foundationโ€™s Code of Conduct](https://www.python.org/psf/conduct/). The Python community is made up of members from around the globe with a diverse set of skills, personalities, and experiences. It is through these differences that our community experiences great successes and continued growth. When you're working with members of the community, this Code of Conduct will help steer your interactions and keep Python a positive, successful, and growing community. ## Our Community Members of the Python community are **open, considerate, and respectful**. Behaviours that reinforce these values contribute to a positive environment, and include: * **Being open.** Members of the community are open to collaboration, whether it's on PEPs, patches, problems, or otherwise. * **Focusing on what is best for the community.** We're respectful of the processes set forth in the community, and we work within them. * **Acknowledging time and effort.** We're respectful of the volunteer efforts that permeate the Python community. We're thoughtful when addressing the efforts of others, keeping in mind that often times the labor was completed simply for the good of the community. * **Being respectful of differing viewpoints and experiences.** We're receptive to constructive comments and criticism, as the experiences and skill sets of other members contribute to the whole of our efforts. * **Showing empathy towards other community members.** We're attentive in our communications, whether in person or online, and we're tactful when approaching differing views. * **Being considerate.** Members of the community are considerate of their peers -- other Python users. * **Being respectful.** We're respectful of others, their positions, their skills, their commitments, and their efforts. * **Gracefully accepting constructive criticism.** When we disagree, we are courteous in raising our issues. * **Using welcoming and inclusive language.** We're accepting of all who wish to take part in our activities, fostering an environment where anyone can participate and everyone can make a difference. ## Our Standards Every member of our community has the right to have their identity respected. The Python community is dedicated to providing a positive experience for everyone, regardless of age, gender identity and expression, sexual orientation, disability, physical appearance, body size, ethnicity, nationality, race, or religion (or lack thereof), education, or socio-economic status. ## Inappropriate Behavior Examples of unacceptable behavior by participants include: * Harassment of any participants in any form * Deliberate intimidation, stalking, or following * Logging or taking screenshots of online activity for harassment purposes * Publishing others' private information, such as a physical or electronic address, without explicit permission * Violent threats or language directed against another person * Incitement of violence or harassment towards any individual, including encouraging a person to commit suicide or to engage in self-harm * Creating additional online accounts in order to harass another person or circumvent a ban * Sexual language and imagery in online communities or in any conference venue, including talks * Insults, put downs, or jokes that are based upon stereotypes, that are exclusionary, or that hold others up for ridicule * Excessive swearing * Unwelcome sexual attention or advances * Unwelcome physical contact, including simulated physical contact (eg, textual descriptions like "hug" or "backrub") without consent or after a request to stop * Pattern of inappropriate social contact, such as requesting/assuming inappropriate levels of intimacy with others * Sustained disruption of online community discussions, in-person presentations, or other in-person events * Continued one-on-one communication after requests to cease * Other conduct that is inappropriate for a professional audience including people of many different backgrounds Community members asked to stop any inappropriate behavior are expected to comply immediately. ## Enforcement We take Code of Conduct violations seriously, and will act to ensure our spaces are welcoming, inclusive, and professional environments to communicate in. If you need to raise a Code of Conduct report, you may do so privately by email to hello@pydantic.dev. Reports will be treated confidentially. Alternately you may [make a report to the Python Software Foundation](https://www.python.org/psf/conduct/reporting/). pydantic-httpx2-6dd59b9/docs/compatibility.md000066400000000000000000000231211526547463400213460ustar00rootroot00000000000000# Requests Compatibility Guide HTTPX aims to be broadly compatible with the `requests` API, although there are a few design differences in places. This documentation outlines places where the API differs... ## Redirects Unlike `requests`, HTTPX does **not follow redirects by default**. We differ in behaviour here [because auto-redirects can easily mask unnecessary network calls being made](https://github.com/encode/httpx/discussions/1785). You can still enable behaviour to automatically follow redirects, but you need to do so explicitly... ```python response = client.get(url, follow_redirects=True) ``` Or else instantiate a client, with redirect following enabled by default... ```python client = httpx2.Client(follow_redirects=True) ``` ## Client instances The HTTPX equivalent of `requests.Session` is `httpx2.Client`. ```python session = requests.Session(**kwargs) ``` is generally equivalent to ```python client = httpx2.Client(**kwargs) ``` ## Request URLs Accessing `response.url` will return a `URL` instance, rather than a string. Use `str(response.url)` if you need a string instance. ## Determining the next redirect request The `requests` library exposes an attribute `response.next`, which can be used to obtain the next redirect request. ```python session = requests.Session() request = requests.Request("GET", ...).prepare() while request is not None: response = session.send(request, allow_redirects=False) request = response.next ``` In HTTPX, this attribute is instead named `response.next_request`. For example: ```python client = httpx2.Client() request = client.build_request("GET", ...) while request is not None: response = client.send(request) request = response.next_request ``` ## Request Content For uploading raw text or binary content we prefer to use a `content` parameter, in order to better separate this usage from the case of uploading form data. For example, using `content=...` to upload raw content: ```python # Uploading text, bytes, or a bytes iterator. httpx2.post(..., content=b"Hello, world") ``` And using `data=...` to send form data: ```python # Uploading form data. httpx2.post(..., data={"message": "Hello, world"}) ``` Using the `data=` will raise a deprecation warning, and is expected to be fully removed with the HTTPX 1.0 release. ## Upload files HTTPX strictly enforces that upload files must be opened in binary mode, in order to avoid character encoding issues that can result from attempting to upload files opened in text mode. ## Content encoding HTTPX uses `utf-8` for encoding `str` request bodies. For example, when using `content=` the request body will be encoded to `utf-8` before being sent over the wire. This differs from Requests which uses `latin1`. If you need an explicit encoding, pass encoded bytes explicitly, e.g. `content=.encode("latin1")`. For response bodies, assuming the server didn't send an explicit encoding then HTTPX will do its best to figure out an appropriate encoding. HTTPX makes a guess at the encoding to use for decoding the response using `charset_normalizer`. Fallback to that or any content with less than 32 octets will be decoded using `utf-8` with the `error="replace"` decoder strategy. ## Cookies If using a client instance, then cookies should always be set on the client rather than on a per-request basis. This usage is supported: ```python client = httpx2.Client(cookies=...) client.post(...) ``` This usage is **not** supported: ```python client = httpx2.Client() client.post(..., cookies=...) ``` We prefer enforcing a stricter API here because it provides clearer expectations around cookie persistence, particularly when redirects occur. ## Status Codes In our documentation we prefer the uppercased versions, such as `codes.NOT_FOUND`, but also provide lower-cased versions for API compatibility with `requests`. Requests includes various synonyms for status codes that HTTPX does not support. ## Streaming responses HTTPX provides a `.stream()` interface rather than using `stream=True`. This ensures that streaming responses are always properly closed outside of the stream block, and makes it visually clearer at which points streaming I/O APIs may be used with a response. For example: ```python with httpx2.stream("GET", "https://www.example.com") as response: ... ``` Within a `stream()` block request data is made available with: * `.iter_bytes()` - Instead of `response.iter_content()` * `.iter_text()` - Instead of `response.iter_content(decode_unicode=True)` * `.iter_lines()` - Corresponding to `response.iter_lines()` * `.iter_raw()` - Use this instead of `response.raw` * `.read()` - Read the entire response body, making `response.text` and `response.content` available. ## Timeouts HTTPX defaults to including reasonable [timeouts](quickstart.md#timeouts) for all network operations, while Requests has no timeouts by default. To get the same behavior as Requests, set the `timeout` parameter to `None`: ```python httpx2.get('https://www.example.com', timeout=None) ``` ## Proxy keys HTTPX uses the mounts argument for HTTP proxying and transport routing. It can do much more than proxies and allows you to configure more than just the proxy route. For more detailed documentation, see [Mounting Transports](advanced/transports.md#mounting-transports). When using `httpx2.Client(mounts={...})` to map to a selection of different transports, we use full URL schemes, such as `mounts={"http://": ..., "https://": ...}`. This is different to the `requests` usage of `proxies={"http": ..., "https": ...}`. This change is for better consistency with more complex mappings, that might also include domain names, such as `mounts={"all://": ..., httpx2.HTTPTransport(proxy="all://www.example.com": None})` which maps all requests onto a proxy, except for requests to "www.example.com" which have an explicit exclusion. Also note that `requests.Session.request(...)` allows a `proxies=...` parameter, whereas `httpx2.Client.request(...)` does not allow `mounts=...`. ## SSL configuration When using a `Client` instance, the ssl configurations should always be passed on client instantiation, rather than passed to the request method. If you need more than one different SSL configuration, you should use different client instances for each SSL configuration. ## Request body on HTTP methods The HTTP `GET`, `DELETE`, `HEAD`, and `OPTIONS` methods are specified as not supporting a request body. To stay in line with this, the `.get`, `.delete`, `.head` and `.options` functions do not support `content`, `files`, `data`, or `json` arguments. If you really do need to send request data using these http methods you should use the generic `.request` function instead. ```python httpx2.request( method="DELETE", url="https://www.example.com/", content=b'A request body on a DELETE request.' ) ``` ## Checking for success and failure responses We don't support `response.is_ok` since the naming is ambiguous there, and might incorrectly imply an equivalence to `response.status_code == codes.OK`. Instead we provide the `response.is_success` property, which can be used to check for a 2xx response. ## Request instantiation There is no notion of [prepared requests](https://requests.readthedocs.io/en/stable/user/advanced/#prepared-requests) in HTTPX. If you need to customize request instantiation, see [Request instances](advanced/clients.md#request-instances). Besides, `httpx2.Request()` does not support the `auth`, `timeout`, `follow_redirects`, `mounts`, `verify` and `cert` parameters. However these are available in `httpx2.request`, `httpx2.get`, `httpx2.post` etc., as well as on [`Client` instances](advanced/clients.md#sharing-configuration-across-requests). ## Mocking If you need to mock HTTPX2 requests in your tests, see [httpx2-pytest](third_party_packages.md#httpx2-pytest) or [pytest-HTTPX2](third_party_packages.md#pytest-httpx2). ## Networking layer `requests` defers most of its HTTP networking code to the excellent [`urllib3` library](https://urllib3.readthedocs.io/en/latest/). On the other hand, HTTPX2 uses [`httpcore2`](https://github.com/pydantic/httpx2/tree/main/src/httpcore2) as its core HTTP networking layer, which is a different project than `urllib3`. ## Query Parameters `requests` omits `params` whose values are `None` (e.g. `requests.get(..., params={"foo": None})`). This is not supported by HTTPX. For both query params (`params=`) and form data (`data=`), `requests` supports sending a list of tuples (e.g. `requests.get(..., params=[('key1', 'value1'), ('key1', 'value2')])`). This is not supported by HTTPX. Instead, use a dictionary with lists as values. E.g.: `httpx2.get(..., params={'key1': ['value1', 'value2']})` or with form data: `httpx2.post(..., data={'key1': ['value1', 'value2']})`. ## Event Hooks `requests` allows event hooks to mutate `Request` and `Response` objects. See [examples](https://requests.readthedocs.io/en/master/user/advanced/#event-hooks) given in the documentation for `requests`. In HTTPX, event hooks may access properties of requests and responses, but event hook callbacks cannot mutate the original request/response. If you are looking for more control, consider checking out [Custom Transports](advanced/transports.md#custom-transports). ## Exceptions and Errors `requests` exception hierarchy is slightly different to the `httpx2` exception hierarchy. `requests` exposes a top level `RequestException`, where as `httpx2` exposes a top level `HTTPError`. see the exceptions exposes in requests [here](https://requests.readthedocs.io/en/latest/_modules/requests/exceptions/). See the `httpx2` error hierarchy [here](https://pydantic.dev/docs/httpx2/api/exceptions/). pydantic-httpx2-6dd59b9/docs/contributing.md000066400000000000000000000202001526547463400211770ustar00rootroot00000000000000# Contributing Thank you for being interested in contributing to HTTPX. There are many ways you can contribute to the project: - Try HTTPX and [report bugs/issues you find](https://github.com/pydantic/httpx2/issues/new) - [Implement new features](https://github.com/pydantic/httpx2/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) - [Review Pull Requests of others](https://github.com/pydantic/httpx2/pulls) - Write documentation - Participate in discussions ## Reporting Bugs or Other Issues Found something that HTTPX2 should support? Stumbled upon some unexpected behaviour? Contributions should generally start out with [a discussion](https://github.com/pydantic/httpx2/discussions). Possible bugs and feature requests may be raised in the "Q&A" category. We can then determine if the discussion needs to be escalated into an "Issue" or not, or if we'd consider a pull request. Try to be more descriptive as you can and in case of a bug report, provide as much information as possible like: - OS platform - Python version - Installed dependencies and versions (`python -m pip freeze`) - Code snippet - Error traceback You should always try to reduce any examples to the *simplest possible case* that demonstrates the issue. Some possibly useful tips for narrowing down potential issues... - Does the issue exist on HTTP/1.1, or HTTP/2, or both? - Does the issue exist with `Client`, `AsyncClient`, or both? - When using `AsyncClient` does the issue exist when using `asyncio` or `trio`, or both? ## Development To start developing HTTPX create a **fork** of the [HTTPX repository](https://github.com/pydantic/httpx2) on GitHub. Then clone your fork with the following command replacing `YOUR-USERNAME` with your GitHub username: ```shell $ git clone https://github.com/YOUR-USERNAME/httpx2 ``` You can now install the project and its dependencies using: ```shell $ cd httpx2 $ scripts/install ``` ## Testing and Linting We use custom shell scripts to automate testing, linting, and documentation building workflow. To run the tests, use: ```shell $ scripts/test ``` Any additional arguments will be passed to `pytest`. See the [pytest documentation](https://docs.pytest.org/en/latest/how-to/usage.html) for more information. For example, to run a single test script: ```shell $ scripts/test tests/test_multipart.py ``` To run the code auto-formatting: ```shell $ scripts/lint ``` Lastly, to run code checks separately (they are also run as part of `scripts/test`), run: ```shell $ scripts/check ``` ## Documenting Documentation pages are located under the `docs/` folder. To run the documentation site locally (useful for previewing changes), use: ```shell $ scripts/docs ``` ## Resolving Build / CI Failures Once you've submitted your pull request, the test suite will automatically run, and the results will show up in GitHub. If the test suite fails, you'll want to click through to the "Details" link, and try to identify why the test suite failed.

Failing PR commit status

Here are some common ways the test suite can fail: ### Check Job Failed

Failing GitHub action lint job

This job failing means there is either a code formatting issue or type-annotation issue. You can look at the job output to figure out why it's failed or within a shell run: ```shell $ scripts/check ``` It may be worth it to run `$ scripts/lint` to attempt auto-formatting the code and if that job succeeds commit the changes. ### Docs Job Failed This job failing means the documentation failed to build. This can happen for a variety of reasons like invalid markdown or missing configuration within `mkdocs.yml`. ### Python 3.X Job Failed

Failing GitHub action test job

This job failing means the unit tests failed or not all code paths are covered by unit tests. If tests are failing you will see this message under the coverage report: `=== 1 failed, 435 passed, 1 skipped, 1 xfailed in 11.09s ===` If tests succeed but coverage doesn't reach our current threshold, you will see this message under the coverage report: `FAIL Required test coverage of 100% not reached. Total coverage: 99.00%` ## Releasing *This section is targeted at HTTPX maintainers.* Before releasing a new version, create a pull request that includes: - **An update to the changelog**: - We follow the format from [keepachangelog](https://keepachangelog.com/en/1.0.0/). - [Compare](https://github.com/pydantic/httpx2/compare/) `master` with the tag of the latest release, and list all entries that are of interest to our users: - Things that **must** go in the changelog: added, changed, deprecated or removed features, and bug fixes. - Things that **should not** go in the changelog: changes to documentation, tests or tooling. - Try sorting entries in descending order of impact / importance. - Keep it concise and to-the-point. ๐ŸŽฏ - **A version bump**: see `__version__.py`. For an example, see [#1006](https://github.com/encode/httpx/pull/1006). Once the release PR is merged, create a [new release](https://github.com/pydantic/httpx2/releases/new) including: - Tag version like `0.13.3`. - Release title `Version 0.13.3` - Description copied from the changelog. Once created this release will be automatically uploaded to PyPI. If something goes wrong with the PyPI job the release can be published using the `scripts/publish` script. ## Development proxy setup To test and debug requests via a proxy it's best to run a proxy server locally. Any server should do but [`mitmproxy`](https://mitmproxy.org/) is a good choice - it's written in Python, fully featured and has excellent UI and tools for introspection of requests. You can install `mitmproxy` using `pip install mitmproxy` or [several other ways](https://docs.mitmproxy.org/stable/overview-installation/). `mitmproxy` does require setting up local TLS certificates for HTTPS requests, as its main purpose is to allow developers to inspect requests that pass through it. We can set them up follows: 1. [`pip install trustme-cli`](https://github.com/sethmlarson/trustme-cli/). 2. `trustme-cli -i example.org www.example.org`, assuming you want to test connecting to that domain, this will create three files: `server.pem`, `server.key` and `client.pem`. 3. `mitmproxy` requires a PEM file that includes the private key and the certificate so we need to concatenate them: `cat server.key server.pem > server.withkey.pem`. 4. Start the proxy server `mitmproxy --certs server.withkey.pem`, or use the [other mitmproxy commands](https://docs.mitmproxy.org/stable/) with different UI options. At this point the server is ready to start serving requests, you'll need to configure HTTPX2 as described in the [proxy section](https://pydantic.dev/docs/httpx2/advanced/proxies/#http-proxies) and the [SSL certificates section](https://pydantic.dev/docs/httpx2/advanced/ssl/), this is where our previously generated `client.pem` comes in: ```python import ssl import httpx2 ctx = ssl.create_default_context(cafile="/path/to/client.pem") with httpx2.Client(proxy="http://127.0.0.1:8080/", verify=ctx) as client: response = client.get("https://example.org") print(response.status_code) # should print 200 ``` Note, however, that HTTPS requests will only succeed to the host specified in the SSL/TLS certificate we generated, HTTPS requests to other hosts will raise an error like: ``` ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Hostname mismatch, certificate is not valid for 'duckduckgo.com'. (_ssl.c:1108) ``` If you want to make requests to more hosts you'll need to regenerate the certificates and include all the hosts you intend to connect to in the seconds step, i.e. `trustme-cli -i example.org www.example.org duckduckgo.com www.duckduckgo.com` pydantic-httpx2-6dd59b9/docs/css/000077500000000000000000000000001526547463400167445ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/docs/css/custom.css000066400000000000000000000002731526547463400207720ustar00rootroot00000000000000div.autodoc-docstring { padding-left: 20px; margin-bottom: 30px; border-left: 5px solid rgba(230, 230, 230); } div.autodoc-members { padding-left: 20px; margin-bottom: 15px; } pydantic-httpx2-6dd59b9/docs/environment_variables.md000066400000000000000000000054531526547463400231010ustar00rootroot00000000000000# Environment Variables The HTTPX library can be configured via environment variables. Environment variables are used by default. To ignore environment variables, `trust_env` has to be set `False`. There are two ways to set `trust_env` to disable environment variables: * On the client via `httpx2.Client(trust_env=False)`. * Using the top-level API, such as `httpx2.get("", trust_env=False)`. Here is a list of environment variables that HTTPX recognizes and what function they serve: ## Proxies The environment variables documented below are used as a convention by various HTTP tooling, including: * [cURL](https://github.com/curl/curl/blob/master/docs/MANUAL.md#environment-variables) * [requests](https://github.com/psf/requests/blob/master/docs/user/advanced.rst#proxies) For more information on using proxies in HTTPX, see [HTTP Proxies](advanced/proxies.md#http-proxies). ### `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY` Valid values: A URL to a proxy `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY` set the proxy to be used for `http`, `https`, or all requests respectively. ```bash export HTTP_PROXY=http://my-external-proxy.com:1234 # This request will be sent through the proxy python -c "import httpx2; httpx2.get('http://example.com')" # This request will be sent directly, as we set `trust_env=False` python -c "import httpx2; httpx2.get('http://example.com', trust_env=False)" ``` ### `NO_PROXY` Valid values: a comma-separated list of hostnames/urls `NO_PROXY` disables the proxy for specific urls ```bash export HTTP_PROXY=http://my-external-proxy.com:1234 export NO_PROXY=http://127.0.0.1,pydantic.dev # As in the previous example, this request will be sent through the proxy python -c "import httpx2; httpx2.get('http://example.com')" # These requests will be sent directly, bypassing the proxy python -c "import httpx2; httpx2.get('http://127.0.0.1:5000/my-api')" python -c "import httpx2; httpx2.get('https://pydantic.dev/docs/httpx2/')" ``` ## `SSL_CERT_FILE` Valid values: a filename If this environment variable is set then HTTPX will load CA certificate from the specified file instead of the default location. Example: ```console SSL_CERT_FILE=/path/to/ca-certs/ca-bundle.crt python -c "import httpx2; httpx2.get('https://example.com')" ``` ## `SSL_CERT_DIR` Valid values: a directory following an [OpenSSL specific layout](https://www.openssl.org/docs/manmaster/man3/SSL_CTX_load_verify_locations.html). If this environment variable is set and the directory follows an [OpenSSL specific layout](https://www.openssl.org/docs/manmaster/man3/SSL_CTX_load_verify_locations.html) (ie. you ran `c_rehash`) then HTTPX will load CA certificates from this directory instead of the default location. Example: ```console SSL_CERT_DIR=/path/to/ca-certs/ python -c "import httpx2; httpx2.get('https://example.com')" ``` pydantic-httpx2-6dd59b9/docs/exceptions.md000066400000000000000000000033101526547463400206540ustar00rootroot00000000000000# Exceptions This page lists exceptions that may be raised when using HTTPX. For an overview of how to work with HTTPX exceptions, see [Exceptions (Quickstart)](quickstart.md#exceptions). ## The exception hierarchy * HTTPError * RequestError * TransportError * TimeoutException * ConnectTimeout * ReadTimeout * WriteTimeout * PoolTimeout * NetworkError * ConnectError * ReadError * WriteError * CloseError * ProtocolError * LocalProtocolError * RemoteProtocolError * ProxyError * UnsupportedProtocol * SSEError * DecodingError * TooManyRedirects * HTTPStatusError * InvalidURL * CookieConflict * StreamError * StreamConsumed * ResponseNotRead * RequestNotRead * StreamClosed --- ## Exception classes ::: httpx2.HTTPError ::: httpx2.RequestError ::: httpx2.TransportError ::: httpx2.TimeoutException ::: httpx2.ConnectTimeout ::: httpx2.ReadTimeout ::: httpx2.WriteTimeout ::: httpx2.PoolTimeout ::: httpx2.NetworkError ::: httpx2.ConnectError ::: httpx2.ReadError ::: httpx2.WriteError ::: httpx2.CloseError ::: httpx2.ProtocolError ::: httpx2.LocalProtocolError ::: httpx2.RemoteProtocolError ::: httpx2.ProxyError ::: httpx2.UnsupportedProtocol ::: httpx2.SSEError ::: httpx2.DecodingError ::: httpx2.TooManyRedirects ::: httpx2.HTTPStatusError ::: httpx2.InvalidURL ::: httpx2.CookieConflict ::: httpx2.StreamError ::: httpx2.StreamConsumed ::: httpx2.StreamClosed ::: httpx2.ResponseNotRead ::: httpx2.RequestNotRead pydantic-httpx2-6dd59b9/docs/http2.md000066400000000000000000000050201526547463400175340ustar00rootroot00000000000000# HTTP/2 HTTP/2 is a major new iteration of the HTTP protocol, that provides a far more efficient transport, with potential performance benefits. HTTP/2 does not change the core semantics of the request or response, but alters the way that data is sent to and from the server. Rather than the text format that HTTP/1.1 uses, HTTP/2 is a binary format. The binary format provides full request and response multiplexing, and efficient compression of HTTP headers. The stream multiplexing means that where HTTP/1.1 requires one TCP stream for each concurrent request, HTTP/2 allows a single TCP stream to handle multiple concurrent requests. HTTP/2 also provides support for functionality such as response prioritization, and server push. For a comprehensive guide to HTTP/2 you may want to check out "[http2 explained](https://http2-explained.haxx.se/)". ## Enabling HTTP/2 When using the `httpx2` client, HTTP/2 support is not enabled by default, because HTTP/1.1 is a mature, battle-hardened transport layer, and our HTTP/1.1 implementation may be considered the more robust option at this point in time. It is possible that a future version of `httpx2` may enable HTTP/2 support by default. If you're issuing highly concurrent requests you might want to consider trying out our HTTP/2 support. You can do so by first making sure to install the optional HTTP/2 dependencies... ```shell pip install 'httpx2[http2]' ``` And then instantiating a client with HTTP/2 support enabled: ```python client = httpx2.AsyncClient(http2=True) ... ``` You can also instantiate a client as a context manager, to ensure that all HTTP connections are nicely scoped, and will be closed once the context block is exited. ```python async with httpx2.AsyncClient(http2=True) as client: ... ``` HTTP/2 support is available on both `Client` and `AsyncClient`, although it's typically more useful in async contexts if you're issuing lots of concurrent requests. ## Inspecting the HTTP version Enabling HTTP/2 support on the client does not *necessarily* mean that your requests and responses will be transported over HTTP/2, since both the client *and* the server need to support HTTP/2. If you connect to a server that only supports HTTP/1.1 the client will use a standard HTTP/1.1 connection instead. You can determine which version of the HTTP protocol was used by examining the `.http_version` property on the response. ```python client = httpx2.AsyncClient(http2=True) response = await client.get(...) print(response.http_version) # "HTTP/1.0", "HTTP/1.1", or "HTTP/2". ``` pydantic-httpx2-6dd59b9/docs/img/000077500000000000000000000000001526547463400167305ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/docs/img/butterfly.png000066400000000000000000024674021526547463400214750ustar00rootroot00000000000000‰PNG  IHDRฃŒMJViCCPICC Profile(‘c``RI,(ศaa``ศอ+) rwRˆˆŒR`ศภ„ผ b ‰ษลŽ>@% 0|ปฦภข/๋‚ฬ:%5ตIต^ภืbฆ๐ี‹ฏD›0ีฃฎ”ิโd �ˆS“ ŠJS€lๅ๒’ปศ): ศžbงCุ@์$๛XMH3}ศVHฮHšม๘ศึIBOGbCํn—ฬโ‚œฤJ…cฎ%”คV”€h็�‚สขฬ๔ŒG`(ฅ*xๆ%๋้(š30€ยข๚s 8,ลฮ ฤš๏30ุ๎����n„˜ื~†@\;b ‚� 'v$%‚…˜˜)-แำr�Hแ @=ัลiฦF`yF'ึ{��Vc``Ÿฬภ๐wย��ฟ���w1P๓†y!e๎ด๙้ pHYs  šœ%iTXtXML:com.adobe.xmp 2 0 72 1 72 1038 1 675 2020-11-04T11:11:96 Pixelmator 3.9 B�Wฆ@IDATx์�`\ลต๐๑ู�ด*–d[๎VฏVตไ"๗Žฦุธaภ๔J๓A" !„HBy “<ย‹L 9”`š\q—ฌ.ญถ฿๏\๑xฯI่–ฅ�ีฃ-w็ฮ�๎ju็�33JqC@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@เ(ดบ:‹ฆี�4M3E1ผ@ฃเะQ๑๑f@@ ๗$P`๘ีฏป�{—Ÿิฺ๎์Žwฟ฿P[๛เเ3:{o”ˆ €ภ 8๘b^E@๚T@�เ๊s �น�|เ,ซลฌ�มP๓^xโ-ฉศ฿๚ด2์ @0ข€ € zะเ๖๋ฏศ���|ggทo–f0*อhQซ5็t#ฃ–ิ@`  8hGœ๖"€ €@ฤ �ไบK3๎�อ๎ํ๊๊žfฒฺ”ัdU&ณ,–๗ฯŸด3b+Nล@bZ€ภAL^‡ €ั" 5~เ~๔ฉ็ฎ์์์œa2�•มdVFณY%นใ:ฒG๘EBัยถhi ๕Dˆ-ๆ8ˆญใIk@@ ด;ํ NXqฦก†ฦuFษ0! สh0+ปอฎ ’�ห~๏Š? †p6*#€ฤ€ƒ8ˆ4@ขY@3\vรฺ‚�๛^fฒ:l%™&“2ษฟA๑๎฿ฏ9แ๘†wEs ฉ; €@t 0T!บตG@(ุ๚์#I›_yํ�š2 3๕k:šdุTRผ๋๏s&U]3{อ™‡ขผ‰T@ ส Q^ช €Dญ€ฆmตฮšฐ๚[{5�ะlฑ™ ฒŠ‚ีjU๑NW�ฤข�3~๘‹�x™! Q{xฉ8 3 Uˆ™CIC@@ ชd้ล ฯ^“พ๗ะแ3ฬf‡Iำยสl6)—รัž?v๔w%h๐ Aƒจ:ขTˆY†*ฤ์กฅa € ษ�ท<ฟ๙ลฟ]าŒ9šœ‘™e…8งKฅ$ฤ�๒ž�๒ธ B‘\๊† 0pศ88วš–"€ €@„hตตๆEW^น�๏.ทศ|J”U~บœ๖�^4gฺญ†ฑcฝRUช €€"ใ€ € ะ‡ฒิขแ๖�~x์๎�{/4ƒ l2ฏรnoฬ9โ{g\qํพ>ฌปB@เKศ8๘R"6@@zQ qณ๋7=y l*1ห’‹ ุ,-9>๎�Ÿ]wร๋2DA๋ลฝQ €G-@เเจ )@๘jšถษtโ�๏ฮkํ๐ฌ2�์๒&ข`ถจD—๓ๅีs�cศส๒}ต’ุ @พ`จB฿Yณ'@เ฿นsศึ๗?บT–]tห0e4”ัจ5fŽ๑�UW\qp€๓ะ|@ ใ B ีB@ุะ๊ŸถMZ~แฺม8ัๆpHภภค�qNZjยM็�gอ ,ฝ[ว›ึ €ฑ$@ฦA,Mฺ‚|E}r6mฯซ๙i•ฆฏ๘66Co( �ฮ]๙ฃr[ฺฯ2™-=hเtุTZrย�<๕เ=†�7,šท!€ pฬศ88ๆฤ์ˆ4อpใUซฒž|ฒ๖;มฐม”>z๔kตO>๘ะŒลซ›dผ5“ฒEฺแข>ฑ!p่็m~ํฃู–i4™•ษdTn—�ีใf—�j0 ๓ฤF#i €@ฌ qซG–v!€Ÿ+`ะšบณ�ษCื9โึ||เ๐Oo�ษO๎~่ฎF(ฅ>๗mผ€฿H@ซซณฬ:�ไี฿ZณลฆฬfณŠw9๗gพๆดKผ๗ส›@่CาS๛›]!€‘"ฐ๚„j�พ}-Kบ<�xษ20๘�‚ํ;wŽน๙-/=�‡็;"ฅžิXh3ทๅly๓ร;$h0ิ$A‡รๆ-ศuษ<๚'ๆ5ˆ…#L@ุ ใ ๖1-D�Mเ[งฏ�™็๚ซIRฆƒม€๒๙ผ๊ps๓ฒ฿�๖5ZำkLเ†ฝ! ํูใxi๓฿ฮ …BูF“IูlV•š”๐�ิœ๑ธ ‚ฝฑส@@เX 88ึย”D €aศ\OF๚๐ป์6๋A‹ี.KยYT0VZO>๗ย๋ึkฺVkV›*!UšVk^ดvูœึ6ฯZซ�ฉœNปœ�๛ซNYwUj๎R2{ข๊hRY@`` 8ุวŸึ#€ภ@0ดkn�๎k้#†�๏’+ กPP…dzวg�๎7}็ฎ %ณภTฺ@o�v�ฆQํ�Wcฑ�“ํvปŠsพp�Œ๊+'ฏ?ทก7สง @๚J€ภA_Iณ@ ย †,฿๊ีwฆ N๙“ร'3˜%€Vํํํ#^�๋–u›JŽฐ*SขF@ำvฺ๓ศŸฯา”ฑิ้ŠS’�ณฝ*?cใY฿นyGิ4‚Š"€ ๐?๘( €X`๊ษWฌศ]“็๘Xฦ[+e4๖dhhXxว�qถฆี�0MGเ hšf\ทx�ไถฮฎSํNง2›ŒMฃ‡ง^�ƒ{ฺ"ฟg,y๚Ty €@ 8่O}๖๔ป€Aป`อท฿)ฮqS|œซ]˜,v%‰ฆv์�ึ%g_5[๏๕{5ฉQ$๐ท�พ+้ท฿ฟาbฑ ‰sฺฝcา�๐ะ.yšษฃ่ RU@@๘gmฯ&วšใg^[Uš.-ศิŠฒGheฺŒ ฅ[~rลลyJ1฿ม?‹๑ฯะพํ*ษsSฦจด`qažถx๖”[ด�uฮฯ�šg@ˆฎ"Eวqข– €ภ10Œ\ูฝnอ์ป“โŸrIjตษhR€Wตwด•=๛๒K?x�๙_:ฆ pb@@ซฏทMœฟ๊�.�าธ๘“�i๒ดๅKn1 ซ๐ฤ@๓h €ภ p0€>MGŽ8nๅ�;<กผ๘JWœsK|B’ฒXส็๓ฉ†–ๆ%ื�v�Y2d%ใ>Gศ๏‡๙ธณฯ˜ูpธ๕2‡หmNpูŸ[9ท๚’ฮนฌ๑ˆอธ‹ € €Dท€>ŸAอ*fWWผ9พ8W+สฅeืJ๓ว:uๅ‚ใ๕u้ฃป…ิ�ุคiฆีหfWIKฺQ”›ฅM›X๑สฏnผrŒ�>ฑคi๏sS" € €๔ท€<ธโย๕•3&•พY^”ญHเ  #M›X’ป}ใy๋&ั๊๏#ฤ�#I@�}ธ๙[kฒฒ‡ z%{๔0mr๙ธฯ^ทdพ�{I๕ค. € € €@ฏ ่žซ%x0ญช๔Mษ6ะ ณ†k%yฺ้ิส’งvพY›ุซ;ฃ0ขX@ซ-พ8sิ๏ฒวŒิส‹๒œบtมb๙�!3'Š)UG@@ฏ( ฎนp}i๕๘ยืห ๕•Fkใrฦ๚LฏผžYโฟ""›ลด€ถ็Uว”qูWe*Wะนrแ์ šVg‰้Fำ8@@@เHMซ1~๛[kส+หr๋Šrวj๙รดโฌ‘]็oXนR ฆ#ทๅ>I@ซฺ6sr้99้ฃฺ%hX<งzฃฆี�’mE@@z๔ฬƒห/^WVUV๘Vฑ 2†ห8๎ยทฎ<๗”ryษ฿๘œ 8�wb๕’Ysฒฦ?T\ญ-œ9้vํเ�ฎAƒ@@@O๔Žา™'/›6ฉผh[Q๖(™๏ S›>ฑ๔ลM๗�pิง�๐  หพsูcณG~]_Aa �y้ทIกํด@@๘B้0™ึŸธl‘d|\Z%๓ŒัๆN.ฟ…๔์/dใลx๔ž{็ง|"?kŒ6oๆฤ;๊๋ŸŽฑ&า@@@เ› H๐ภผfู�ฆT•ช*ษืWZhZยข“๔็ฟyฉผ่h�เewy^๖}Eนูแ9Sซ๎�๚์/EGอฉ% € € ะ‡zเ์uวฏ–ฅ๕ฬƒชq9ป.วมาg€ถ"€ € €ภฑ่ ,˜yqูธ|฿ธ�Œืฎ\2YžcL๘ฑ#งไ^hฎซK˜PX๐puษธฆ‹ึœด‚ A/S € €  i;ํวอšviูธ‚ฎ’ยœ\|ฦษyา๙bz>/ ํฏsฮจฌธA‚฿>eอZMซcฎŽˆ?jT@@ขR@ซืlKฬ^_U\ดทช0ฏ๖ยำึๆ“y•‡rภTบN&๔\2{ฺ™•ใ ƒwฟ๖๖�ฎำxŠ € €๔‡€žโฝaๅาูใ ๓wK�ฦiK<่ม>ฟT@ฯˆนเฌตEeEy;L๔๊ณท�š๙ฅob@@@ฃ™iอา๙๓* ๒”fฅ�ํ๔ๅKJ7i›˜0๑่i)ก~XณqTyanํŒ ใท�]sี8=ะ‹ลS € € €ภ ิjตๆ๕ห/šVUถซฒ0๏ฝSฯฏพ่=ผ†@_ ศgั^•ŸuKๅธ‚ึ๋พuึ yฬdž}…ฯ~@@@O๔@ม•฿:ท|~๕ฤ'ไ|xโœฉsๅ9–ธ๛ˆŸ�"P'“ฮจ(]^’ั|าข๙7๊ss๔KEุ) € € €€R(0�]se๚‚๊ ฯM.)��ญu'NาณฐA ?๔ฯใ†ห&–ๆ็˜;mโŸ๋ž|0ฅ?๊ม>@@@ސฮฺื_=|Ve๙ฃŠ๓?:yู‚™า#5�H#๎๗‰@ํƒฆศ๐„็งMฟ�๖ฏ)ํ“ฒ@@@ฏ&๐ำššQณชสŸญ.)x๏ฌ“—ี<๘jplี+ฌrL*๗ฃ‰ฅลญ—mXฟL3็FฏศR € € ะ[’ypื๕W\<ณ๚‰ษ…/œปaMบž:�[ลSŸ' Ÿ3๓q“*N.หอ๊>yษq฿ัv๎ด�ถ< € € ะฯw�X“9ฝช์ญสโœgoบโŠa2มƒ~>&ฑผ{=8u๑ygไ•ๆfิ/š9๕ัๆํu ฑ�^ฺ† € €Dฝ€>Dแ�๕+gO,.80ฑ0๗ฯ?๚hrิ7ŠDฌภ�>:ธข0๗ฟfV•oฝ๏{ืDlEฉ € € €ภ� ่ใหื.]pR๕ธ‚–วWณ$��๑pฏ—4mฟs๊ธ‚�&ๆต๗ยำส็ŒI9{ษ–b@@@c. m�j]1oๆSหŠ>>i�ฌUZญฦ2ว\}เ์@‚ๆeUซฦูฝzั�›ต={ง๕ด@@ˆ้�ู—ฯ™ฎ_�ฝaูโjฎวศํ็flา6™.^{ยไฒั#ท/™>ๅก–7฿L์็*ฑ{@ขN€4ฝจ;dTˆMƒมเ-ญฬฝ%lะvฝป}�ฯ.ฟ่Œ| 0Ybl๎>k•้พ๚มฏ���1ฌ๛ิฟ6ฉดดตฯvฮŽ@@@zW@œป~๕ธ๒ย�๚๊ช๒็~~�mCzw”6ดƒ]“‹ oŸ^Qบ�;gŸ:Ÿ,–t๔i+ € €ฤฌ€t๎L'7{iYQ^วฌ๊ ?•วŒGูฃ}์ฆํฌต/šPqํŒ’qญWŸz๒ษZ]ๅุํ’@@@๚T@ซืl๓ฆMนb|an๛าY“ฯ–เพ>=ัฝ3๙ผฮ9~ั๔ช‚�ึำฬฝE{๕U‚Oั}Hฉ= € € ๐๏zฆมœษU?ซ(ศjX9๊q๒ุ๔๏[๑ �,  พs๙ูYฅนู=ฎzโ3ฏ=๘ ร]�™ˆG € € €@์�u๓อCงM(ด4g๔‡งฏYT)B&๕ร{LZ๒›�kF”d�e๚„Šฺ?�ไฦtฅ˜`๓˜@S( € € šแก;nVQ�|EAฮ฿ฟ�ยŒศจตˆDฆ๚ืโ'e�็คฒยท~๖ฃ�—ฏX•#uB@@zW@O=ฟtรบโŠœŒ&>๚fํc‰ฝปJ‹ํเ�ฎ•ลทNซ*9xู™kf“ G•6 € € €_Q@:ฆณW/›3ฉคp�ฌสŠ›4mฟ๓+พ•อ€€ฆํดO-/ุ8นขจ๛ผuว_ iฌ 0;MD@@�Y@ำjอ+Ž›ทฆ47็๐ิ๑ๅWj๕๕ถ�‚GQ@‚JๆนS'œRUœืผ๎๘y฿ำด=ฌ 0?ด@@ะค“h›7eยU…Yc›ๆN|Rห4่†VงYN˜Sฝฌ$?ณq�๑ณ๏ึถฦ h € €  TฝL€7ฑ(�—™ฃ๗-œ=cžฆmb™ฦ๘มะ็0ธhอ’ฉe9้‡–อ›๚๔‡ตOฆ @šŒ € € ๐Y>๚@๒„ฒโ฿ๅd๎Xฑlq๕&™แณถในุ แฎ+/ษฌ,ศฉ›[=�๕‡๏๚~^lถ”V!€ € €|c�oชQ]Q๚๔ธ์๔๗ฯYฟชTฟ� ใQ#  ~q�ีฃ+๒๓žŸ>พ�๛ฎูX ?5  ข € € €}# woพ�๒Œฒ‚œ—ŠฦŽ�๋…ง–O๐ o์๛s/uO>˜R–=๚ัŠยœึ+7ฌZฆmbจJ๖ € €Dด€(ธ๔œ๕ฅฅyๆ๙๚wฮ>;‹ซฯ}ศŽชrZใ๎ …๗”็guŸณjษM�j=ชy3 € € €@์ ่๓œถzลฬโฬ๔=EcF<~�ํทงฦ~ซ^ % d›^^xูธœฑพuK็]ฅํ�ix ด@@@เ Hงาดjษ’%ฅ๙นห๒ฒ~Y๛ุc‰฿จ �‘šVk>yๅยy…ู้M‹งW�L๛เewDV”J!€ €@๏ ่้คค”๖พ+%"€Q@�ž˜7ฌZฑค,/gi^๖/jkk ฤภA?O8�ฬีEน™๏ฬ™\๕�‹ธ7-šE@@เ๋8๘:Zl‹ ๐Eฺึญึๅ fŸ•;jxWYnๆ๕๕๕๑_ด=ฏEถ€~Žpๅ%็eๆŒ�jue๙๖[ฏูXคไนศฎ5ตC@@ˆhM�iŸ>ก๒๊ฬแCƒŠ๒๏h” ๕"บยT๎sž�tjAๆศ'J r;พuๆฺeH0}๎ฦผ€ € € €ภWฆs๒๘า3‡ค„&ๅ}_�ณว๑U฿หv‘! 5lŸ?๖Gy#ต5หnิ๊๋m‘Q3j € € pOฉ,�ผฑฃ<ณ'?M‚ึจjภฌฌ#ใ้kN˜š›>ฒฑบฒ์ฉบฺ'S MF@@่+ป๎บy่ฤาqfŒi™_=Q'o๎ซ}ณŸฏ+ ๎ผ�๊ัลyูฏLฎ,�qรU๛บ%ฐ= € € €_O@S†_๕ศา‚์็ฒ‡�ณxๆฬ™›˜d๏๋๖ัึ�๋�œP–Ÿ๓ปฒข<ฯEงฎYกีึไ้#{vƒ € € hษ20�xๅ%้ใr2�ศ5l็ษห—V้)๑%ยฏi{ soศK8~๎์๏่ซcDXฉ € € €@, ่‚3N];ก8'๓ฃย๔ฑ๛gž™]SC๐ Žyญ YX]พข sl๗ผฉ“ะXB3 u@@เธฺ๒ฟ�Aˆeƒมž๛ซ฿ผ1i|ล้N‡}่ณ/พpท9๐ํแฑ�ๆhi�฿6^œฑc๗�๎ญ'.ž_cHอํˆ–บSO@@@ฬำš% WๆdvๆgŒ|์ถ�nขd(CŒ53jšฃi]ใsำ๏—L๖ 7ฌ[ร’จ9vT@@ˆYzMณMŸXq~ๆจแมโ์ŒM›๎ฟ?5fม �ชmตฮ›9ๅฬย�ฌŽ‹็_ฉีื�"ธบT @@@` h{๖8ฆN��œ‘รตส‚ผ›%ษ๘๚๐ ฯ9qฺษ+ฆๆf4ฯ™>ๅฉ–7฿L์ร�ณ+@@@พ\@:ฏŽ๒œฌ[ฒFคuM_ถVณ�฿—ณ๕สO>๙`JN๚ฐ็หŠ๓v]๓ํ‹ฦ‹=รEzE–B@@@zU ๑ƒ—�“สK~žŸ9v๗’นำๆHึิซ; ฐะ‡Šg๙nๆ˜a�5'-ั6˜�›O € € €DŒภƒ?ฟmศฤŠ’อ2aโŽ3ืฌ(‘Ž,ซฃฃฃ/y๒๒นUฃ‡œ9mโฏ๕ษัฎ(@bA@NฬฬšVg‰…ถะ@่ฟG†ณN[W&Y๕9ร†พ๔� ฮหJ วๆxพ)s”d>=ฑฒx๋mท}?็ุ์…R@@ f๔+:๒๔ฤ˜9ข4ˆ^�๏ัฒใf-ส1ด5o๘ะMตตตLึืห‡ณพ^ณอฌฎ�8ฑ|�ก‹ฯ=}!็ฝ Lq € €}'ฐg๋ซƒ๖ืี9๛n์ "A@�บี:sา„sว N๎*ษ{ฝtlYiก—ŒXWฮ›>ป47ณi๕ คํ�‰m/ูR  € €@?จ1ตฉฉ>พvอ.@ Ÿ๔`มธฑรo“’่™]Yฑ^ซcH]o’M๗฿žZ8:ํฅYUฅฏ?น้แฝQ&e € € ะ, ึ๖์จ๛๓ฆ„’์Œว วŒฺ{ฺ๒ฅU๚„~Pญจญ‚cฌr3ฏช*ฬ๑\ดแ”%๒˜ฅฃ๖hRq@@@ฅOŒxลy็ๅee๎(H�า๕—^:’ษฟูClXr\Eiฦ่'-œ{—ฆํq|ณ’x € € €$ ีึš็ฯฌ^–5|่แข1c฿ดiSjU/jชข|�U–5๚ก™ส^y๙ ‹šŠSQ@@@พL@ฎ–[fU”ฎสNฺ>y\ัOไ1Wหฟ ํˆืลหผdjี†ฉๅ….=๛ิใ๔์ƒ#^ๆ. € € €ั/ ]�ฤ�์+3‡ฆvอญžธAซำ,ั฿ชc฿=Hpู9งN)+ฺv๊‰K๏ิ4VQ8๖๊์@@@ _ถื�9ก,;๓แ‚Q#๖ŸณfE%Wฮฟ�0่Cช‹ Z0uโG�๙ใ์/[ € € € ลื_}๕่โ๔ฑฏ็๑—{nนep7ๅ˜W]+ฆลหืTๆgwnXนไœZฒpฬwส@@@่O=หเไล‹gๅf.-ฬนG�ฟ฿ูŸ๕‰ไ}�pใEฃŠฦ{้�้46~เŽไบR7@@@zM@�บี:ซzโ๙9cGwV~[ำ๊mฝVxŒ$kuy๑Uล�oฉนj\Œ4‹f € € € ๐ี4mฃผ(๗๖Œi- fN[ งๅตwฦ�VzVฦ™kO_Q”ฟํ๔ี'ž-ข๛‡"€ € €�ซภฯoปaHQvๆ ูcFพ{ูgŒ�ืื๊ใฺฺวว็=บt�ฌด††ธ๊@ป@ˆ5cฌ5ˆ๖ € pฌ๖ต^ีXRV|… ูŸ๙ำณืioฟํ:ึ๛Œ๔๒5mซ๕ื�rบีfฏœ8ฑโ็†มƒ;#ฝฮิ@@@c& Q˜=ฅraฦˆ!๛ฆT–ž3 ำ๒eˆยลงฎ)_ป๏ฤใf฿ฅํูใ8f๐Œ € € €@ดHฐภ:พ8๗�™ฃ†ํZ0uา\=˜-u๏อzJปๅ๙™ฟ™ZQ๚�/oป)ง7หฆ,@@@ขZ@ื_œŸ๓l๎˜žฟzytข Q� ฏYyญF3.;sqYAN๓)+–œ%ํgBฤฏiศๆ € € €1,  พ}แู๙ycG�#ไฐว_{๚้๘n๎ฟ5M–จŒ+อ๓งYีžhn�ž๐o๐ € € €]@‚ฆลณชeง iŸ~<ถ iงe�ไส &ธ๒‚sฆ๋A”ะnฺˆ € € €ภื+๏ึฉๅ%—ๅ�9JีชZญ6ฆS๖๕ มiซNœ4พ0�ะŠใๆ�B�ฟ6o@@@@` ิ�๙ฯ eนูฯไ^๙ูkฒb๙ |cใ๎า�ฬวงŒ/฿wใ5ื”คใL[@๐r’cิ� x@๘š5๒๗sรชๅใrวพ_’=โฑoปaศื,"*6—๓๓�‰งeŒ๒mX{โลZ]%**N%@@ w๔ซ#zว’R@ž€� 5ญ;a�ยขฌQž‰้wjฺGฌ)��๖›F๙น“*_�๛‹OงฦZ๛h € € €วT@ำvฺงŽ/บณ`๔ภ� %งH0!fๆ;ถXf••]U]R�ถ๑�3ศc&D<ฆŸ& G@@ˆIŸึ\4ช$}๘฿ŠFงํ9wลยr้`G�0@=Hpษ†  ๖ฎš7๏mO์eSฤไ‡‘F!€ € €Dž€(8yูœiใาG4•ง{๎๙๎LŽผZ~ฝi qณ'Tnš5กjฯญืl,๚z๏fk@@@๘'ญ[5๋ย)U—d T—ไ^+ม�?mE6ษ� 'ฮŸ}Buษ8๏šฅ oะ—ŸŒข๊SU@8 ˜syผ@c"PP`๐kฺ�๛&ไN�ึึ~ัŠyณทH๐เƒม:&;<†…ฺz(eฯพ�—;]ฎฝ“'T�สPPเ?†ปฃh@@@ŽภฆปnZ‘7๚Š‚ฌ๗ฏ8๏Œผhkน;ฬวอ™rNuEฉ�ิOธP›ขญ ิ@@@ˆะ;ฺหgOXYœ12X•7ๆํเAWฤV๖3*vื๕Wฌ,ฮ฿:oZ๕_ถ>๛์ ฯุ„ง@@@@เhด�๛ใณG฿™34ู7ย๘S๋dYรฃ)ฏฏ�ซgฬ™6้าษใK›/9๏ฌน๒˜ๅ๛ Ÿ� € € € ,�ผ๗'iU๙9/ฅ>x๚ส&ืDม55—fWิ?ฮƒ,ฟ8ฐ>ฏด@Oข~M้OยO@"]`๛Y*-+�Žลn3ฝ๙๖[฿_๐฿%Er%ปภ๖์“�ตมh21lุรjฤo$ื—บ!€ € € ๕าท,7๋�าผฌภœ ๅๅqD.kจI8eอ๑ๅ™ฃ‡6ฬ™^�๒๓>š๕๘4@@ ๖๔ืุk-B.P_�Z�ดสฒ'ส๓ฒŸบ๊ฤ้‘8dAพใrฦ�U”—แ;๋ไ5+ไ1YŠ�ƒK๛@@H p‰G…:!€ภั ่฿mŸฑn๚„โ‚ฮฒœŒusอะฃ-ณท฿๖IหŠ‹2G\8{ฺฆh[ขท-(@.ภีƒ� ˆ๐๖ -ยซH๕@ฏ- ท�ไ็ื�599๙žp8<ๅ�G;W‚ 3dก^ซทฝทc๛Iq๎W�ุŒ๛ิ!žฏ�H�€ € € €G'๐ะ/๏6ซช�ฅ๑๙ูM็ญ[5)RฒฌพลE9•Eน;–ฮ™�+}ษฃk%๏F@h ใ ฺ ๕GˆZU.8P9qโ•‡3๐๖ป๏^๛ึ[›๚ป1ผฐ�ๅฯYiRฦดQ#‡?dHึ�฿ub� € € € X:ญฮฒhฦดK+ฒ3ƒ &UUซiๆ�ฤ๘๑ีWŸ�ม�๊‰ฯึ>๖Xbึ…}#€ € € €€ผ๓ิSIฒสย•็f|x๙ทฮฮR�ดขŒด˜S]q�”าqฌ[ต$R†N๐!A@�`จB�๚ณw@Tัย…ญ้™™ทบ%ฌ{ใอ2+ฌญ?X:๏ป/ฑฃซ{ฝ;)๑•๋ฎฝx3ิ๖วQ`Ÿ €Dž@Ÿธzyj„ ะฟz��฿�๔BBผ๋~oภปvๅาูำkjด>�ญ�}�ีcฟŸbต9าวฆน{ะoŸํ์_๖Ž €‘"ะง'%zฃฟ่๊…œด ,DสGƒz €๔ฅ€ม0ึ[QQ๑S๙รผkฯ�ƒWT๛uR_๎_๖ek้h=ัnณพ๑ฦ๓j 55แ>�?ปC@พ\€ ม—ฑ €@์ ศ฿Aำ๚ต'œTQZุ9{๚ฤ‹ๅqŸM”xล…งWฮŸ9ๅะ๊e‹.ี๋ปสด @พฎ@Ÿg|Qฟ(แ‹�วk €ฤ‚€� =pหONIyธฝฝ�‚Ÿ—ัํา๊๋m๏พ๗แz“ัะ>}Fี๕z๔ล~ู €D‡@DขƒŒZ"€ p์ ร†y*+สo5Lฆบบ-ศี�c>Qโ๕๗�1ชนนmกห้|ไฌ ||์ZGษ € ข๑จQg@˜ธ๖?๚h่มท{ฝพUงฏ]>I‚†cีเM2,แตบบ9‹ลž“™๕ˆมP8V๛ข\@@@่%ฺ'L™VU๖๊ŒI•KเภัKล�[1šถ฿9ฉฌเ๓gV�Zำvฺ�mž@@/@ฦม€�€ ‰ำญn––vw(ฌ^{โ๑SUึม™๋.…+F �คA๑EขuB@� pะฟ�์@ฯ ร+ึŸ�Œ�n๛ ฑ๑ะ๙๏ผ๓Ž๓37<Š'%a�ป๗ใnท;œ‘๕Žฌ™ฌEqผ@@@๚R@:๖ฦต+ฏ™5q|�๊ลว-๏ํฌƒ๛|�ศIใ2?\>ฦ๏4mฯ1ั—f์ @z_€Œƒ�7ฅD@zE@ฯ:8ใผ O;๖7[[›ฯ}ๆ™g�ฝRฐRSฃ�๘ไ3“\ฮธิฬŒ1*5ย�[eS € € €๔‘€žup๊ชฅkๆMญ๊\ยโ55๒๘๓vฝU�jี‡|�๋G>ฏo7k|๎ฝ๋–ฮ|^kช?๒5๎#€ €G |๎ษว‘q@๚G@ฯ:ธๆ†k�6j›๗5:gึŸ�”๐Y5iช-�ฬย…—f ฟ๚ž๋ฏฎ>kปOŸปํบK†อ†ษCำRWƒ2;?}žŸ € € € e0œึษUีUล;V.›{สฆMš้ศ&่ห(–Ž|อ˜k03อญฅvฟrฮ้หK๕แGn๗้}=จฐf๑คSWฬŸ๔ม๏uG๎งฯ๓@๘,ฯ<ก๘ฌ y@๚G@ฒด;๏�๕›ฉษIOทn>#อ๙ง�Z ]X6ใไ Mอ—$jฒ;\สbตNzใี7พŸŸ�ซไฯฌ๑�ฝถ๖ถฮEIƒท,?๕‚Ÿน O"€ €�#@เ€ €Q ม~a�oฌV๓ศŸ�็t= Aฏ๖ตJY?๘่ฃ5Iƒ‡$Yq*ิTภTf›kแ�{฿™ฒ๙_›w๛ฝทŒฐXmใRS’Ÿ•ื��๚:@@#ฉม}@"Xเ๚sฏxK�p?เภ�RM›^ีำV.ฬ2ูฌ๓ใโ•Ipน”�งŒF“๊๊๒m๘ษu—Žัท๛๔ฆถn๛p|Zjj๛โ๙๓j๕l†O_ใ' € ๐Y>K…็@ˆ@ร˜1พท�7~Ÿทไ๔ึJ6ม๛[฿ŸkตYGšอฅดฐ2[ฬสdถชP(ค�Nwฦ๛๏ํZ.ม‚#็Dฐ6jœํดฺ฿ฉZฐถ1›I•@@ ยDุก: €|ฎ€d�z฿ฆ:‡หu ~๛Ž5ำ•rฬ๖Y๑ ส๏๗+WœK;FI ‡5ีััฉjXธ๋ญอ๎Oหผ๎’ำาTH›โŽwmฝ๎:๘๔y~"€ €Ÿ'@เเ๓dx@ุบ5ี›6,ํ ƒษฐrอ๑snK?Q2 ”ษdT๚ด‡7)w— ๚�* +ภ?๚ัMฯ ๎iŠlPฟ๕รR›ีn1bิ 55†p6‘*!€ €@„ 8ˆฐBu@๘"3 มชฉณ•แ -ญmm๋mVKขE†'่s่ŸืซŒ2ูKbAรZฺวv๋eึmQๆ€?4%ฮ๐๗ 'Ÿ��ํ‡ื@@O|*มO@ขD �ผK$ง&? {2 ,fณ บTฺะTuสบ5jไ˜tๅioWญ-ส๋้ฒtดwMั๊๊,ุ��๎โAI‰u*-ญ;JšK5@@ Ÿ๔๓`๗ €|]Cฐ ทเฉP(pภ+‰HถAPลนj\i‰,วุญผ>ฏ ห‰Z8คššVๅๅ–?�๖ฑtซำgw €๔†@ใแ=n›อโ6b”๒ศdˆฒŽ‚�Sสeทฉ้ำงช��\ีํํTm‡ซp ”จ].ฃฆ•;ฎื gญn๊:P € #ืu-ฆ• €ฤ€ภคŠฒแ--‡OณYmฎŽ๖ษ*0)ฟืงrฒฒ•ี๊P�@งj๏jSM‡ฺUภซโ��๒Zผ�iš›“๕xๅดyš€ €}$@ฦAAณ@zK ถV3ฟ�๗ฟ•ํฺถ#ัแpช8ท Mpลฉ�ผl๕�oซ ปT|‚Kd•‹ลข< Mบใ’F�foีƒr@@``ศtJ�@@ šฒ†�-aว๖ื[ํK@–]”4H575ช!Cซปถซ†ร สbณ+“dรฅOr”q ฃํฃ�ขยัิV๊Š €�/@ฦA�j€ €ภWจี4๓yฮ_ฺึ�6้ะมfตc�ๅUา $ีึัฅฺ:ฝjห;�U4)SS]ฒบ‚>๗A\|ข2ฺ]ฅ—ฯ๖|ๅฑ! € d๐1@@ Šฆ:dปเฃ—ูฌFKท?คถ๏ุฉฦฆRอ ี+ฏผช>ฺนW54P&รสืแQ&ฃI…M&Yฒัข��~ม@#pC@พฒƒฏLล† €๔ฟ@cS“กหŒ๗B*ึ”W‚ฃYูํn๕ฦ–:ต๏`‡าไฏ๛–ฦwTผ]_kมค’RSdœ‚AuxฺG7o{�.ญ๐๗Kจ €D‹ƒh9Rิ@HM•�ศค‡แ€ฆโโljT๚Xๅtฦฉ.W%ฦ'(2(งหฅ<^๊๊๎–เK=R™LีึrธไŽ�๎ฬ”XUO €|e_™Š @่G�ฃรguฌๆ,Xค&Mฎถษp…�ฯ>ซาาซย�lUPP(AŸz๓ํจร ส฿ํQญอa•2(!9=k์)ฏ=๗�Žช9kถ †p�ทˆ € €@ค 8ˆ๔#D�@8B`็��–W]f.ฏจTฃQํูท[ฝ�โ_”งซS$@ฐซ๑ฐ๊hnSAอ >�ทW&40จ–ๆf๙ฏQM˜4^ตต7]๐ศรฟฎ๘h๗ŽuR,+,aห]@๘lŸํยณ €Dค@|B� ›ูšZ�ม?dฉล z�ฏ/ซ—7ฟ ห/บT{{—Šs:ีฮ)_ภฏR'ช๔ฌ|๕ั{๏ฉ†ฦ&ตฅ๎u๏๔วค๔^�๋๓4M๛ํ3ฟธ9แล7฿I x�m๎!)อฅE“š–ฌ>ฃ�:ฅ|5d$Dไg€J!€ ะื๚Zœ�!€ p๛๗lKhnฐ'n: 2ณวจ8‡Mน,VuธฑU™ํ65m�,ี|่ฐฌฐ๐ฒฬ{ ร�xSyBeqZUAnฎš=oždLSท�๘ฝKK3†OฑYLEMาฬฦฐ%yP|ื3ฟyไ๐ญื^ณeุุQO<๙ไ“//Zดจ™! Gqภx+ €1 @เ "M@ˆMM3^ซ”ใพ›ฎK�}`Gข�ไ0์ฺ๖๎ผ๎ŽNGี„Rต|๕z5h๐p•0D�๘ฆ{U—?ฌžy๖9e3•ีnUม€Aydี…€Uฉ$ท[ MIUำ็,Tฮxท1blึGป�”•:tฐเi2฿ขAuvด@p˜ฟซc\ทo๛๊;j.}ใ/?pทd&ภbwฤซษ่l๗*ฏ/จ ~Ÿjiํ”ทไŸ[57ท(ฟืซlVณ๊ ๘”U†%hซl๋U&ซE™๔ฉ&ต๗ใ๊ฟ�ฝZ๊้*$ห9šerลฐู.a}G“2še{Yถ1–)eษวŽฎ.๐�$๏ลw�๘ชม<ธ˜เมงGŠŸ € ็XำR@ะดฆ๘•ณว]�t่๐ท6s|wซG๙4%K)R��! U—1ฌLfณฺ฿ฺกฺ์Wq 2<แKฆAท๒Mสn3ซฐ฿#%Vv‹�™7iช;Ro‡rศŠ}้™๋ Pํ�่Ce5๋A H ,๛ั๏[m&๖๙•9,A=ธ ๏ํhmVv“aอ�wึ’ภฦี2lก;ย)ฉ €๔ข€ฉหข(@๘†MM๕๑—ฌ[ycWkหe�]๖VY!! W�ห๐noH™,’7 “ v…�*(9™ร`๔จ1๊—_T?�ล’5`V>ู�d+‹ั O[ ๓ธ$๓@“|2฿AP9%๛@ฆ?P๏ฝ๓Žz๋๏oฉ€"$ ZP กžู^�฿๓�d4˜%H็ฒ๖ฬ›ะัีQ๘ม[o�c๚๋oด๙บ๋๔ญธ!€ €ภ p02MDˆl๚zอvื๗Nน a๗ŽNซรคอชฉฝSu…”j—@ŸผP2ยานื$5 ฉษ68ฐฏAm–ฅ๋๗RšBT0[l=ู“CฒLฒฝOL0HPAฒ :wจ�7จ๎`Pู�&ๅ•,ƒ`P†(Hด ”น ฬF .˜•มf”€BXaๅฐฺT‚ำญฏ�` ๛BCOO๓ิ<ภd‰‘�ฑขv €๔š€\wเ† €�' ^��ลใ[ธฤๅt›ฟA&Eด+™w@ูํ๒št�๕๛Y5มงI  ,รโ\ส(Kœ[๙%ัุาข,žฏ.ฝ๔rU^2NY$ธdทจแฉ)*N�o–€]†> ’๗น%ำ@“�$แํ๖J!hmiižฝs—ฒ�k[xŒ €ฑ)@เ 6+ญBˆ อ๐ะ฿ซดYย๓โใU|๊ษ0ฉn@ฎ๔$H`WAฏ ) Arbฒฌx`QFY*ั"–/V็_tถไxd……Vๅ•U,fซ2›ฬ’i`—!2ิ@ฒ Vซ๒๘d *dไไฉ”มรTjZŠ:ํ์sUaูD•ŸŸซฌ2pั,edฎ—รข�2งY†.่ๅธฅ^ฎx B๘<ส" ๎„D=๛ ค�ฃวโฃ‚˜J"€ €ภQ ฐชยQR@t h2ƒXฯ4`า น_ฃ 5G6ฺ่Ol}D �SZอตrŽ.๏๘ฟ๗น1๗@ฏ'ฐiซฒ์ผo�|ƒ!oIาฏ^โ@IDATฝ�>ๅ—‰ 5™kภ"s ุ%k [†่3ถ<คlqNๅไV6ทšP5^อ;�Dีีูฆ~t๗�=๚j š_ๆB,ท ฌ’‰ แๅ“2B2ไภ๋๗*ƒ”k•I“SdฮƒD5uฦLu๏�๗ชฤค$ew:dศƒSๆE+d>๕!�esศฤ‹Rท.™ัŸ(#!Œ#฿y๗�4ูIรืk1[#€ €@4 8ˆฦฃF�O@ำ๔Žพ!_�ญ f๊ภนnถ_ฉด๒๐ถmJหฬ�k|่พ_บ๖ํู๎ถส\ใ‡š\ž๎fcJjŠY–3ต๙NKxฑมํr;�Žูู้5ิซiFOทึาฬํก‚Nซี่ไ๓‡๗Œ็ ตVx�|ž2ฟูถ�โ4@rxๅ฿จฑiนเgji8่H1ผuลŠ๛s&/ ํR*,๙ผF9รm–าX)ฯษY>3’�฿‘ไR`†้C�Nทฤ*ห&ถuuศ�^q(“ฬo6๋น]สไ0จxGœ�2๏€|mศ�ฦ.ฃJ4X9“ำิฦkฏToผ๓–z๋อw%ฐเVํžNeqU0ิ.Aซd(XTbขt๖%่ฉg#ดตทชnช๐›Ÿ�\m��j{�v•— t0ษงK†3x<ฒโBP†(๘ฅ,ษ>Œ‡8W’r8l2icซdทZ�ปป\๒ ัh@ ƒxะฃขษำc�ฺพ๖J@เแฉ'ŸRป›v8บ:ทดด:ปฝ>c�œ,ืvณ{่มค„ŒM cBแpjJJ‚ห๋ ถY5k›ัl๊tุ’ใใ�ƒ‚ม %ะํณ›ใLป ‰ƒ”C.ฯ•฿เ๓zร.wข3!)Eห,ๆ~ีา๎•กผSผ;Nyไ$Zช”eหแ ฿oˆำ็3h]MKฌiaร{๏o๓๙�F}ฒธ๗wผ�๖๚๋o์ ๚.i2™MํํํN‹1�๏H> ižS%ผ?j�๒f้„ญฮ„ฮา’ฑอฎดกš’tใn‹)\2sR0-mˆถy๓_MชฑQeŽ( ˜8ฑ็ะI@$lฮ” ฯ(cKš ึH0B=ขิ ‰œ<"?‘ฬี“A`"*>๋Tr@ ผ๑ฺƒฝ^_†Uๆpห—žฃKๆ+0๚•[{exO2 ๔ฮพทณCลษ“ฬOเ้h•NพCํฺตKUหW‘งซSฅ ขv$์U™้™ชำปU6 •ฦฉถๆ6ษ>0(ซM†+ศvŸ_ฅ JRถ๐ฤWC†ŽP?๙๑ญJึc €ฬj`qจBฝ�=ฃมิณO‡,๋จฯฑ’์“”งฯึ(ษ �@@`@๔$]ˆ–าศˆฮทA๚ทF้็ทษฟL้ฟ๒ฤ�–็_yลํํ๔;;ฺใปฺ[“ฝ�ฆกๅ)๔๛ดb›kuวปย๎—K๚้รฅKื�ึ%ูฒFณีๅดว%$™ร’Z�-)ต&9ษ–ลฤไ๊œฬL.ใ{อฒ๖นพฤ˜t๎{ฦ›dึqฟ\E ศโžqภแ€ฬBฎOฎO&ๆR�]]ฒVบL4fuษ๛�๚D`’P �HHภ&'ฯ๚~lrาญ฿๔2�^Ÿฒศ๒gnท[Š๘d…S=˜`‘+ˆ_งคwชถึร*(“Šป�RGŸฒš]’์๋๎๖†ฅ^-lh0›ไ„\–J3š์!)6`ฒย6‡อ์ํ๎6ศ„gมPX ‡|�๖ 'ฐG&;7<ฎ.ohw\œณษ&ใšF›r&X�ฅฎ‡|มŽVฃมๅqล'…Lv‡!)9ัg �ƒกูŸ˜ุ&cคƒ๙๙�‚ลg^n‘%แ๓ฅื ท๗62ckฃา VHBn5ื้�‘๕ุธ!€@ฏ �ร๙e�฿๙๋ณฎ8Kชว๋W{uช=ปTS‹G…Œzฟ�“ัQกPXพdyEy���!ฟจV5xXŠš{พท4™ฟ`๒คj%“จฆ†ตํฃm๒}์™7a๘0™ท@ๆ0p9\pฐ๔|ฝžžy,2iขžฑ`ทนไ;ฮฏโํ*qPJSีิ9 WŸ}๙๋ฝŽB € q"๎ฤF…j$�šฆKf์–็ฑ=๖๐%j�ํIฺฺœ]žๆฤฮ 6ชฃฝu˜รeL4lCไjึPY๗+มๅˆ๓๚บ].—รlqJธภbิ'ใ2ษ๚ไfIฃm—4^ษ๑—“Wญงำn‘‰ร๔[g{›\ “ภ€๔จฅฯ.ใsๅฌYฦๆvษ6=เ”€€พD™I_]๏หUปO—(ณJ๙’ะณ\™ะ;�™$Lฌ—งoงG’%7ม(็�พO–6“taฝlƒฬjฎ/qฆืฯ,'�žžqลf“�zPฯ*V.9๑สcซิ็๕้คธ�ูoPžืC~e3ษU?ง]…z-๕๖(ฉ\�“™ห<�]rฅQส–:xฺฺTwk‹ฒศ๘ๅฤ”A=3ฉ๛$€€ˆ„�ƒ1’ i@…ื฿้๕z‚n฿ ฉฦอาค`ภฏuห’nญแถU*ีd4หThิ‰‹“เ|{‚š฿๋๗‡4a๓ฅ$ฦwœ.ฃ�H™ฝ฿™๐{�<ฉญM).G\๓†U็์6gN๗mกzOGn Kฅ็พ�˜�ปภ�ืœQ~p๛;ฯšญก”ฮ.ฏj>P อUฟm—ฒว9ไ[@N—ฒส๒‰ลT๙ั3�๒‹)฿[ปฅCฏิศแรT๒เ!j๖ยล๊�ญ[ีณzVึp4จฤ�8ะฟs|‘œ=gบา๔�ด4ฉ�๛ษ<]๒~ท<4AŠ—๏6 พ&J6–�}้•๏}Ž›L–(™S*ั%ม—E% NPCา†ีอ]ถvIลิ๙�ฝU<ƒ €ฑ&ภP…X;ข}�้hšิ6นๆ~ว|๗ฯ~ใฎ฿ตkจืใ๒แ’๊„ฟถตฝ�ื‘=8!5ำvคสฉgŠ/”ตย์Vgœอ78Uฎึ{ิ ™)�-€iา›ี;�z็ื YA™�ซ�็U�าi7Jถ€O2๔@€�นท�๕€Qiา)‡Œ2—คƒํIฝ๔ื=žnๅ”ดฺ„AC• ฑพzๆพ„™”-�Z้$หษด_ฦํส>%H|rb�3cน,f๑ผม@H๙๕‰ฤ๔H„�๔ฐOF96ษz่๚ไarJฎยฒญ& }ํu‹,‚z@A�ย!e•7IVฬBž ํL’)๖)‡&ฬ๒B—Lอไณบ์ฉN›1)ตฟ๐Z�Cศฟอb3ืปฬ๖ๆ๎ฎPำฏ-ๆร๋็O๓$'๎’’ิV2นฒำืัu‡ฌ‹฿ฐhู ‰%kjˆพำ!:ฏ^aตY/\งย5’ๅ 2ฎปNๆฐศW†๗$ขFoม‰[Œ˜C๒ฅb0„ป:�%H่R)ษฉ2ผเrษ๏ญIDด;e๕ *�wำข4%ณษ่ดช€G4ฐนโ•�š š๖๎S� X:zพฟ|�J`่๙ฮฒศ๗ึa๚ิ�าฎv๎๙Xyๅ{ภ$฿c๑q๒]'฿ล=W๒ฝเี'C”@…=.NพeM=฿S ฐฺe……xYžั้thษC†>R>e#ฦศ็f € ๐eŸ๔ˆพl+^G@.Wีjส4]ฮ[Ÿ{์g๎ฟฝ๖Fา�C‡‡t{�Š�: šq”E๓•AšA3'XๅRผอa7;eœฎ�a—k็=p™ิ[ฎ�UPŸ�dน1� ผtฮร’Š’“V} r‹,&ษตr…L†H‡<>>AN†e‰ฒฎ6๗+3สIต]ฟงw็5™๖Pา๔๕�ฝ~R’ Aงtส๕ืาาาไ$ืฉ๊๋๋%่ะ%ใ‚๕�„dŒฎฃงใ๏—+pš”/=Y้Pห}y—žน''ฬzgปMฎธ้mJ๐B“€AŸ$L‚๚M฿VRHXCLชฃCrb-ํึgถ่)ภfษ&s—C%ง$ฉCM{&+*ศWๅ%j�มฝา PาYH–ฑษ้=ษณPร%x ง&+ ˜อz„ๅ“=J�ฑ&้ส=ฟธ๚มŽ ntKึƒ Ÿฮƒ5.Uฺใ•eู:ๅy}97้“Hฦ,.zเE†=("„nีฺtจg๖๖๘ไมp‘ฅึคใะฺ� บ=]’qแ่‚ก/gจ]‡๖+ืชหฺ๒ จดI†ƒ>๖Z�%mื'uำ‡€่ฃf’$Œฐ_Žฅpป:=ํอ29DGb\ผ?่ ุฬ† ม(๑YพU(d�5ฑ2>–‘'96Feูšœœิึา|ุiuุ>วm ™:อ[� ม)]VwBง3.A0[\ฮลl %Z�ฺสUkบRr&๛Kza�ถM๖fชะงyŽ%๐ยCw|ู้‡Ÿio9T ศส^ฃ๊่–~Sง๊’฿1[‚[yeาD=+ส.๓ญ่๚B๙~L(๙้‘฿้ฐ|�่฿6ษLJšชถพณ]ž“‰%0้7diGMฅ$นี์๊ •”'ู-๊ฑ'^๏ุžA]๒œMลห๛๕฿็D� `อ๒+๖Tป|Oู่Iฒฃ]พGา†U ƒ_Xt�บ“+็ฟ'ข0ฉ  €3ž�ว1+‚ฃV@ฟาปe‹2——๏5?๘ใoฉ{-ำ่*hnm*ทธ�ฃ5ีhต$i&“[ฮ6%ำ�(W๏ๅชฟ\ญ๙zHV๏Zk2ผภ#WๅฅS/'ฆก �ั7๔œฎ๊pนค�ำืv๗L@จ็ะหŒโ๒šษ)้๘๊:d‰0�คึ/s่๏ำ‡ X%ธ �ำื-�$;ภ/Wื๕NผœPKภAฟ้??™Ÿ@O๛7*›ล ๊n™�ภ&'่�ž C@†8%XV่ƒ๔ไ๕}้๛p่)O?iศ?ณค๋๏ีƒ๚| ๚ 2ฉbO0ฤ' zJฑ>™Yzรมžlฃ’Q๒~�๓*ง[ถ—๙lR—ยข\ีี�*ๅ~ามืืM;z”สอฮ“@H@ฦ;Tส4ษ.ูอป+Kย`erงHE0ฅร ่2D(ศO ฒ‚�”ื๔๛zXฃ'SB~ล๕Ÿ=#$เaฐ�ฯ6z†…๔ญeI๘d{iงคa(™�Q‚Vู�ผ”%วฑm๏vต]zแ�^‹๚ว๛;ี?>xO…$SCฯ฿ะgƒือ๔ฃญ—๔,�&wไX™z�Bœ1˜4™^ฟŠชฯ?–ก’p �๚๑ึ“ŒrL=ฯiZศ'๗etG— SSrิม€A๚:’ าึีี๎๑Zอ&ƒ9เ๕…,&-่”ถ'&บ[�๐{qngSภvH์ยhuXœฮ„w%ฅ6[ญ-9-ฑำrตฤง&๙”๘2+J%uDฯ|ขร้‡๐ๆอJŸ“R{OŸhRnz๖ƒ�“ฝ-Pฏiถ'ฯYx ท:ญำ#s ศ„OHu‡d.๙m ษ0จn_wOฐOฯqj–เž9>ฎ'(้“๏ .๙~๔x%ฬ*Ÿ�ษS*T๚ุtตgฯ^ตc�~ตC~†-•ภjPพฯLฉRห–-Tž&u๗]�ฉ๊๗HV“dœLฑสฐ๙qวษ|๎xUVYฆ.>^ตท6ซ�๑–z��ท%จ,™Qฉžผ‚�U๋/น�)๙n้๙�่mสChUฎj$C๐ZeH฿ขŒ’hi๔g~๒7ToœQ2๕�e๏^ใa{—นก!คๅ็็๗๎�khnn6๎�ทฯิูนวš:ุ0ย‘๖ป�แ๎�๛Mol{หึ~จKฟjc ฺไ๚Dุิvธษjkึธไdนๆเ๔ศwY ุ�lฑวว-fนœe‘Hช~ฆ$W%Bfณ็r๘งŒ dwษ>๕&�๖?'L=๕๊้ษนฏ๖ิS*$m‘๏7พใ>aโฟ|"ะ๓Kฦ |;šไ‹�๒ุSป฿�น#ฝกแใ1อ:๓ๅR๑X3_&A‚Qฮ8gœ~ี]&�“Nธ\น—ฉั,'คา)ิำโ๕+๔ ‚dp้P๋H� tHถ๕ห๋๚ฺแ!ปฏฯฺฅ๗e๕๚žพญ�ี,w๔บ�O/+$gมaน$ญ1๐หไ^๚๋zธ!,'ำ๒C:—๚ผฒ4™\3HXF๒๖\กื z'_๏๔๋๏๙t๎��dVqปU๊ 'วz&ƒSา๚�ๅ๊&๕ิ;ฒ&นช/UํYŠLŸ\ชีำฝ }่>ฯAงLฆ฿๔ฅษ๔i ๔ภ‚A:ใ๚sƒ —ะ‡GH?W๊'W ๕�I�๔์้‘†$ุ!ฯ•Ž+Q>ษˆx๏ฏKฆAผEไD]ถq๗�ŒW))C$ˆrX NIQcฦคซคไ!า๏ฬx—,;—บ์๛@yZ(ณ,ๆSšุH%๕๊r“Ž�'�ศรž็๕ห๋= ื��ส} i]r…ณใฐ:ธฏQ†Ztช๚ฉC’‰ัุๆSหะ ณž‰!W7๕Y๔c%GV�g้)RถศP†žฮOPฒ'๔ฝ›๕เNฯ็DŽฺ�g๏=€$=ฯ๛ฮทs˜žžw6็ล‹ .ฤ”H‰”ฬp€IY%Ÿ%๛N’}ถK'ซ๊ฎ๙๎,�UถสฑxถeVIถdด,S”i&pI€ศ‹ผ ์bvwvwvrNfฆ๛~ฟทฑ’Jฎ :+0ฬฬฮt๗ื_x฿๗{ย�๙?ฯรฺg‰kวKไฑะฃL‰x5o_ฏi!ำ?ไjธ_ €#GํˆŠ9ฺPฐ๓|žaMษ8๑&"K„๕TภฺูjึถจLู€Aแ‡5Nป;ฅž/ดQr{๋X฿nฒCmsฆฏปk5“N€jl“ษฒะจื›ฝรๅฎา\�ศเ์ฝทฟc฿wะ๊๓ะึy Z�4†Šฆ‘�˜๚ ‰สhHฦฃ'ํ4~๛็8Š|ๅฬ™ิฤ์Vj`(ŸDๅGๆฬ�Lzeu%yๅๅs‰\ญ7™Mul #๋uิ_j+W[�(ฏฏฎ๗U7๋�‰Fข[Ž2JP"1แd0 rอฦf"›# ำV.ไ‹tฦ�Zฤfฬค’‰v์Ty๓ญ‘DGcBlื`\ &ไSภ…ถ2uฅ9�7j๋๙ ดฦ ๕™6V[ั๒…RG†4Tข1์@ด[•๐B๐ ล•41๊/=MjžƒW*›ตฅ•ี๕ฺ6&6eฆ^�l” ู…bพp kwฆงPš๏่.V;บช๋ํ™LbจoO�๚Pฅ๛ะ!#Tฟง�๙[ณp'’ุูพsG@;~g๛nว9C—ฯ>�ฏ�ละนื_฿3ปฑv๏‰L2}ค˜+j4ฉd&ี�]็Q็ngดบAิผุฎ�r�ร�‹ต๐๑KaYๆ3�=rไใ็ธz`Dเ๑ยฒ:ูœZ‡๓' @ชyจcภrH W่�|ึฤˆี๙_ฅ ™ฮ ,์W>�Ž9ท(บพ—ร่MŽ Cˆšs=1ต}ค<0xคŠl}Ÿค=e-ผ๙ฦXxๅ7Cว๐~ฺ>t„/~๑qํv'ญ„็-—+2>žš๏๒ฺypbkDMekธล๑dœ�,ฆ70Ž7็ฉ“0ํ&โxmด๑ฆƒ\Y๋[p™ซม8งธGื†d„ึฆใdอ %็Mฐศ๙”‘ด‹`SgWwXกข�2…5-ฏ`๛:ฏ+ห5หกP\c}ye“ Eข‚U�ช,Q\r–�\ซy5S(ฦ@�Vา[๋…ถฮฉพ�พ…|นด>0ิฑึ;ะน� ๑ว‰S'ช|ไว+œd›HF"�ยe–ืร`o�ˆKmg๛.ๆฤD๑๏�๒ฯ�mž�ฟถฑฒ™^˜[ +ฒ8ปz๛รก#วยํ๗��๓g ๅซกF๚cXฎ๑Q๕Y๘�ฝ/�เ}ˆ5žgŸ{.�ฦฏ�‡ฐจึ„นEีS–+ฌ)บ6œพ๗ž๐ž๎ วN���/�ร๐�k็Isส‡"sะ†ฬฅD*�:1ภรP=}ƒQ�b๔‡6:+œธ๕๘๕Ÿ�‰‡~เิ~์๕๏๒i�น�๘|Oตยลๆy๛}>zอ|ว�^๎ Ž~๒อ7Ÿ+ฎ^พši๔t7ณx๑“Sำฉฑ๋72ูฅ๔[cW๛*ซeํ‡ญ๚Fฉ™H๖U*๕lญฑM‰ฃF7:rจR�4‘3C!้ไๆ—ะ์&ฺำŸMe“๙ํํ*ำt‚Tยฉ‰ฉออj.™Iw็hjีLฆด™Fกm#jRdถงตณิ�ฺ@�ŽEZMGmีงาด พ ฒJ๛%ึ›โoฟร'Q†นฏเดa8rZfฃถ(๛(�2ศ+kฏคšk‘ไ+‚:ฒTbZซvYาšT่t RšSi>D†)ภBฌกฅ-›ไ8�ึถ(ลRุ�ฎoง6Vน&Lฟ5ŠEืทb@ c8[ฬ-ิ6ทฦ E๊}ƒสV+๕qjfM๖๖ฌ๕๗๗Mzz–ฺำ=•ก[?๚ฃ]ุๆฒ็่`๕ฐ`ร5ฟ\ิฮถ3฿#เ๓ณณ}‡ภ /43ฆ<๙ป฿ศ?๑๘็๚&ฦWo�จTOฏญฌ�™ศen5›}ูrZ7Ai๒ูท(˜e9AEn6!ิNeŒ๖"ดณ8‘ยฯธ้4สx*ŽN5ฌ/0ป0K}ƒกทฟ?LฯฮPคฐZ�Fฟ>๕9ฬf'ตlJEก �WแฌแhฆP :ฅฆ#P฿ŸcฏGcึ: ๘ฆN#GฐฃNจื%  ๓@ฐAgิื�ุ�ดหBซX`lลศ๙k\O†ฯM3p‹u<6ฒ�ึŒ�iต(จเu้\ส„ฐ…c“k๋hoีh D๋๒ฝ ‘;ฮม1SŒง4เvRŽ3ฎ�a�มCax ' ย68rp_8ฐง‹�ถC�ž#M‡†e,`เผ  ๐Tz๙๗�L&Eg8~ฆแ฿ัc็}ฃ #@เ๑๔O}ฺ�ฯ๔ ิ>เฤL:เ๛B€๊pz๖A™ l™Kอุฮ‘็�าู็รำ฿|:ฌmfร:ป„l/) ืฉwฐV——จ ั•wŽ ํ+‹€:๑�S‘yาFnv:O œ%ฮ‡L• Sž˜&ย˜๚ทŸE`ลoํ‰h๐็�9@p?ำE20)ฒ9€'ฺXš๊Re�\ณqmyฌห$ฬ •}Šฟ LPhฒ๚)Dน{ฯ�ฐฐฒฦฎ\ �=€6๕็ฺไ˜๕ะ�ี ภs<\~๋๋�๋ ไ๗„‘=ปริไL˜™žŽ๋หk‘ QฏT!ญ46‰–Tp�ึไ5:hฌW๋ี4-9—ช^M&๒Kุ4ค €Sm&�*wo œ96๙ ็๏Hี`BBใ,ณq๙1€…‡)šทณ}ืŒภิ่+��๘๏��Lิ2๗'ฐกึ7ร๗฿๓เax฿~Šฮ…G�ฦ฿�็/ะg๙ฅ'๒บช�๏?††ยห/ž Oœ9&'VB–๔งdNึ5N!*๋žf8y๊D่)v†—Ÿy>”;ฺBืP๘0์ฺว๒\mZฏ9_dฑฆdq!v๏�[๏่๊~ๆŽป๏๛็ํ/๒๓‰มSฌ๓mg�lGเ:8�bKป�ม If–คอ๐๏mภ๊าไo%ฒž_$X†ยW\™�x์ฑxˆH<ซxว ่ a2ฆ๑ZจNFšP๐’:jC^ท6 ถษฯฅŸ}๊ฉโภะP"ืัฑEค0มฯ*ฯXช^ฯเ…&–––•P K+™KoผV�ุJ๕lmV‹Dย)ง”ชo7ฐะ{ุ3 B)Xษํz%Yญฌ๔Wซ๕ct?๊��� #ฏQ์๏=‚๓^ฬeณTIํ‰Žpฦฤตk“แ๕ั๑๐ยซฏ…™™ฏ� งถ ;ฉ*�B“uุ@คr๓็es~Lc$I2_^XธŽrgGผN TZุาฎ‚?ƒƒƒa๏�ฝ๑ฝห—/‡W^y%t—ฺ#0ฃฃ๏�‰{ธVเGrNำ]วทื\š‚ t๙dฝk4ดj*ดS)ž๎Q๙qฒ๘์ฉL;UไYทเ)ึH๙�‡Y๋ฎ‘kWFร�โR์ ฑg๏ฎะื�ญ๓ฑถ อœข•ดฝไZถbชJ•:FA�Œ�b่4Xตํffๆ™ำ๕Zm6WฬLAจ\.ห \฿ลถŽถ™R{ฯF็p๗‡~๔รหw�ušE6ย …ธ๐6ka\p<พ6Œัย�ภ‰›ld?Zศ „ตฅปซkจ?ผ๚ ฯุ๘๕pczเ @’:K0€2ค๕๗wณถชaimฉe�ณ�สe Vย�าฯ‚ญb[rQ#บŸ็จปง;,ML‡kป‡ข‰}Cแิฝw< ‡๓ฏผ^z๒iึ=]xฟX.Pง%๎บ็๔g��_�้ฟ๕้Oœ{dงๆวwย’๛ำนŽ๑D8Cl-a฿:s<‰o�฿kŽ๑zšํฑ_๛ตŽ‹ื/ฆทถึ3ืoคื7ช9lPZR;L^Oตc3ไ––;ๆๆ‹8อษb—BญLG>้ฦนNเส%ฺั๏8‹ษฉE๙-k1›Mาj8‘ฤAOแ๐AŒ฿ฺส�&›ฉ�Lญถ‰๊�์ซ3@m� :ฐฑVฉd7ึ7บะ[แuฺo๒นtwW'Y��jั™nR#h{m+ดmีื๗P๏h๏&*P่eฦi“ดัAjปฑ™แ๊)6์๒‰�ทกšป๚๚zำ 7๓…bณณ�ษ(ฐอDLืซฎกL้๖Žฎ„์9ย!ƒฎ๎๏๋G฿ุ่ยฒ๘็“4็รyถR;ฯน "qŽล๖6Lˆ�SๆŸv’#[b฿ลPฃ3ŽŽฎlฌ’ฆฐŠฅNdG_<ญณ้ต–C8g6O'lธฑkืฃc}เะฑ055ๆยพ�‡ขŸธ~ƒ4ซ5l†it;๗ U/YV”ื&“สฐQ—c?h็ jz?ฒขMร—t�A;0็ะำ๊~>ฃ0sดำจ๗=ณห}b๓ลy—UสwฑEZค?๖C.F๛–kp…j๓ศชอ‚๔ะถธY$[S`†ฑRวc+cณ๙็€ชภๅaw8ฟ^ƒs‡š�&ณมxeภ�ออๅตZฃบ�Xฆ๕๘๙Lกp™yZ็nหๅ {ธzฯษ[็�/ lƒE j5~‰K{Djๅฮถ3†#เธณ}›ภฃpรHWK�๓�๙'บ_9�ึ๑ฅีส „ิ=เฆ'q�%า™•€`€วภดลEŽRธk่:Šึˆ_VF“ิฑT#O๚ช:a �s7…q†Hฌ*_jy74๛™ฉฉp๑อ7B[พˆ๒‚>–ค2?J`…ฃ“ชฟ†’เญPศ‹�K/ฃ …=ๆze…ข`บผhไๆb — Ÿฮ!ฌี47‘_ัrˆˆ2๓�๛๑GTXๅกโ๑o๎๚ฦb|ญภ๗~ิล๖ุติทธฟ ส‚Pผฆ^ (GDฌก๚1v(œjต ๚9RไฏYํœkรธoข,ถˆ P4E*5บบป ๗†ๅฉฅ`โ]ํแุmwฃ๔Cgนz่ฎะีE�‚bž๛ฃm#Nใ€�ภdโZ0 H์‹ฬ 0XQ~ˆ“ ฏต’๋Ÿ8จiโ\ณืŠVใตcว•ฦ{gwวR>2Tz�xS~ฐาค(ck-‹”‘„™@ฮ"_�"๓Vx๚นณแ๊๘Lธty"‚=ณำณ81053“d�h�ิจ๏8:ฮOVฆcY&ฌM."‚5‰:LKูb}ึ™๏ Žหงๅฯฝป~ซ!u†ช 6L™™$[r�Dซฃ‡C sap`ํไmฐบยยา-V1ŒZ้ฒ&dมHำิ0‰`฿ุ pไvฝบ†ํAbzHN%�{ผฤ=อU6ถถ๓mํK0-Fq๔f‡ฦ‡๛,|๊'ฒึ{๔จVƒ”ˆธ�uฦฦ/ัฦrวัk ศท๐ฟSอฉถฟ๚พw�ห๑หำŸฌAสZ_ฆc ๋›วWู’ƒU-‘RภฺJ…�ว๖…‡ ฟฏ\๋หka฿ƒ }t„)‡ใ'�‹>๘ฑŸK๔๔#ตณ}ทŽภ#D๘?|6ค:๎ ษCqQM&Ÿ|๒ล�๊[3้…ตู�ตษ๋ฅืฏท๐ฝ7๑ู‰Vwแด%a6nnWซ๙ต๕ต๚•zท๋รฉ|๛ ~fBรไฝฃ…z‡m‘ฎึ7๋อไ^๓1ุฎรMšๅาyt้ฦฦ2๊?ื†ฬLq9๘ไhiึ2šXแR�‘ํ8ฎ{ๅ5:Cณ ฃฮ.NฐรZv€€—ฒ}ฝถAบค๙๚ิQjข'Pฝ๊ฮV”YPXฝง-’DOjง˜ท]Yๆ˜œ]์V๋ $๊#า9แ0z/Cึชm}่f�kRKณIzdŠZIษ,Sญใaี0ค’‹Zl:�แวอ œam)‚ํtƒู Pด�บx%\›�ด�f(` .ลtืฅyj5y\๎}]ธ พศg ิื๊iํƒV[ƒ๗ิฉ�8ฟฺสB๗ืVอp,›ฐˆูฤV˜)1ฺ~ 'J�ํก`…นY#@ตjมG‚�‚#Šวhbฏๅ9†) �dธn6๛ต3{๛B6šฉ"๓‹๓|“‘a-ธŸ:\มypผผ�(`ๅ๘Œฃrอุ&œ‡4‘t,ˆC[ลจdมQ/ท•๘Iี+ksูFsฅXฺ๊ศฺŸ�ฟw๏ซw�y็าzศH„'2}ย“๎l;#๐ง2>/;�ทู<๒ิผฟ๒jแ�ลฟ7Œ“ถgeeใ๐ฬ�ยฉ|.w์#ฉ\พญX,ฃfq^Q*ธ๛สi„˜2Gมฅำi`G…pŠฌซS;2ว-Xแg�=+ใวbs8TYขฐ›Dิ+ิ h&Aฝq�ะ�QzฆZ…#pl&4+ .2“ฅK!์&�6FฃUPฮ๕Y#�€ใ[KAฅnš„Žฟ่m xeฃbM รฅข๑ตฮŸŠE…แ�^ณย�}ขQมมำ๓ขbb ๙‰ห1E”บQบM๖]แz๙8"ษR๗ผL•ญ7ู:ฯํไหXศแpFะ@Phฉม0่หn‘ฟคJƒภ[ฮทeฐCฌ๕ฐใ€ืT๗Bil๔โฦR5ตC๏s/สย4�xํbสB‘๚˜�ŸEแฯoวธeSด๖๕}t\��ฯฟƒB๗7sิ\_ ๓“ืฐื8OW๏0ฆE{ด฿ฎ\ฃฃฃŒมฬj ญVย›ๆฉ�ฒพฑ––Wะ‡ฐ/ฺ{(�บั{ืฎ] หุ^Žv�MG\])˜๎๋›๖CดYq๚Sษbดำdฬ ๊่จ็,,,Ri%ž“ฏล๙LJฮง=ขm๋Xiท ลแ๓5บ๎VึWXำค‡ฐ�\ร†žด'•ทl…hg๐žฬืไvล๊d=lL๒ผlพBžŽจ„ั (่ค๖vqพt๗.็็ุ T}=]?าฺQึ8‘tX† ?ว๘i0™ทlJG่coย] �Tฐ ๚ทฃดuจ“˜†^ฺ-Pˆ›w>#„ัR่T๓ต~๎zF lเ<\ƒอw˜7ฉ}MฺKบๆ8P4๖ช8.\Lบ:>žzๆlx์ทฟฆึP๘ฐ#ฒ8โŽนs็|๙ำ„jh๔_เภ๗XDiะลฯu๖oฮฉภs๋œ๚žฦŸ์‹FTEๅส{qqํR1้Ÿ ั€ยgXrU"ญk๕�ข%สณ–ํฎ‘ไ˜=ฬI�Po(แ�5ฬ:ฅๆ€•้$ถK๓ณŒeหเ”]“ไุ๋€hซฑฟ�<�&๗น�ฦิEฏั<๓๖.Œฤฎ�˜ำฅณื ๔ศ‘a‰œPฉ”==ฝt�่ Dสž�ู8Vƒฬณ,œ%ขฬRneี97๕020Z�<ั%!Cา š•๕ีmึ๕JณQ™!jV%ข2•ฯd�W8มrฅปฟ3P2{หใWoน๗�ๆ�|ธาฐภฅcs|ห8�ฐ6ฺ?๗๋�์?|ใฬืพwb|รบ#LO‡นษqŒF)ไTน�`™ฺrฆ๊[สพzธ6จeสขศB`Rn๕�xs๙K๖Ioc�`kSใฅ:๛๘ ืวXห๓กY�ขุi Lq๏ม‘๐ฎ���๎๏่้์�๖ฬฟ:|๘;์ƒ?<ธ฿BฏYOฌ‚€€”ข&ซฦ@c!ฬี.d>๗อ/ทฟ๚ยKํ7FฏŒฌฌO!pGฒQTสาRนพฑถูQ*ๅ K6 �งก๔ฃ๕๒‰tขƒr๗doฤรผ2—<’ ฃlSงo"{ำิวP7่ไ๋x)›ฌ3ร[่๔ ๒ฺ่๐6*ฤ:ดป‰rา}s+ฆ1r<=๒๔ฃT๕ุ[ซฐaŒ�ทHa,.Pไ˜z์[A 3ฏciiนฅ3ฐ | ์๖ไ1eŽy�็-4oะ2ฺˆผ๚Y๙ ฮกเ‹๗ƒfBืร6เทืฏฝไ�M์˜ฮrwฅqๆ๘z�คj`Sxอ๊ฉX€/2‘ี�พ,6๕6„บ!อ9M_0`เ๕๕๖๕Rxg•๑=่ึใ‡™8๊๊rะ๖งD๊wไ]p๏ซ๕ทcฬํำ^ˆ๛DฮŸ�˜ฏ[6M�;NŒ๛{,ฟฮ็ฎƒ�9ร–1}ั`Ccƒ๑^ž‡ฤX Uๆฎฦ�;?lู Kฬ‰‡ตใฎ$ุbถIฅ†็Ÿ)ผjZkiฝ{H}่๐ฏ… /Dฆiฌ �CAๆ9t. ๆZฝฏŽpY{สฯ,Rญmฉฃ๏ฆnฌั>0RC ปE›ฮ^^Ÿ—๓kุึอบL๐๛ัŽ๐ฮกkห�Mแะ๎1ˆฐ…=&‹ฤ`œ Bฏฏ&‚ต5�ัVq�ตฉกลฤ๋เ&#๋,DC,^ŸVตบ_๐ภๆN™านžๆมŒŽ^z[2ฅ๒ฆ+ืษZๅ�H!แฒ“ตJuขV]ฟT๎่ผžศ$_ฺี฿๛ฦ'์‡ฏž>�3gยึƒฐPvtน3ปณ�7Ž€bag๛GพึL�แL�อษฏ่๏๎ฟ?›๋บ๛ื.พ�‹gž�{cf&dQš…Žฎฐ„Rาํ(ฅฎ HถQF ์)๔ Y[A‰ฮl= a๖c_ d๔El Œแ|ppl7p๚ d)JฃะD$#๘I ภ1ก๓ยฟ)tSล‰)ทpŽRคฑฒึ่oฃฎ‰นgHผL1St\#……/=Lฅก2. 0„ถํหŠผ็g*/ƒH[3๒Bึ˜(Pqธ๙;ว๗๒๓ะwu8U4ฒ�R�ฦˆ๕xo3*ฤt(QˆSๅ๗ั๊2๗U�ห ฯ}QฑจŠำFต‰๊Fลฟฝzฮy›Dิณฐ6‰ไ;๖:๊ x‚ย|oƒ‚{�กfGฐ wฐŸจv'gm€ถ›*A๑E,�N@–~ ?๗œXoaen&Œ]x= ๏>DDz �ธz1,๑žŒ(ฐ บรโโTŒ†Wq"61ˆสYุ\k‰ใvCฏซsฏฮu{#ภ‚tฦ�แฝั)อjจกœ�ป`IšนGdา7ซฬ; Š(7ฬLj��ถ๘ˆฦ‰F ต)6–ษฝ^ๅบRแ 5�แ?๚Gแ้GqhH@ 3”L๑�œณvฦหฮฎEA. พช)Nลซา]$BเfŠ‚s~<๐ฝญu'œc�Krผฤ๋1ฮsภณเzqoถ4ท‚kTึ๕ฮ;‘VrƒY)Œธ^ภ–$เอ๑[‡แ‘มp๚{�ˆำวบZฯ>�kKฺiต‰ฑษ:ป~m บๅ<๋‹"Jœocy๖ภ๕h|ๆˆนŽ4ื่พกร&๐$ภฐfdJ$รฌศ3†]ืบ†$„�๘=S บ˜ซ%Zbฒc8x่hุCิร๕,�Q๖สา๒"y่‘L‡ฬ˜%ฮ_ค0�%‡alปQฉฏ1ง“๑๗ูฃฅ–๋˜€F…6Yu 7ฆง๊P2๙=Aำ7สํ]็‡{�งJ� …t๛ี๛x ๖Ÿ๘DKe“ชbš–"b�?์‚ะE�ู�[Fเ�นGณำ—6~ƒ๛Ÿ]บ<:๐๒‹็ร๘ีqญิฃSฦ:2oน\ดหH#ฒVซoึาRฮ'๋Hธ–\#Hๅ’๘˜ฃaศwtEนฮว์l„ฝŠเ๓>1~5\ปฦyใอ7‰6ฯG}Zขภhƒm™"ปFงว•๑[ ุ`Šฯฌ:หs2|\Œ…LsŒ <ื!฿ †า๘ุQ๔g€ซด_–แู�PB=“5zQฟง๏{G8Dญ€6>So�GoR=‚ฮภ่h้fฐ„<7Ž}„mยภฦ@@ะฉ4p"ฑ๕โฦธE}๎�ขsใ7แ๗ะว�H z#d์wA?วvษ\7ธฝN(}าึV1Tผพมแ่`/ฮAฏ“‰!X‚‘dD�๊ฅ+1๏yq~Žใฮ‘Fฒส๋ฮ0ผg/็ฏ…ัื^ ฮฝ„QVe|6ร�Cง@�อฤQเžWๆงฃ#ฺัม}”ส|๏@8p๘D่๎ˆF ใ#=T…Iญจˆข๏ผbŸสฦงๆยใgž�้‹_ ืวIg˜'ฝƒ}ผfืจJฺ๓�xS๕ษ:ค "sาึYŠ•�E�UภVd–จƒฏ๓ฏังใ/ธฮD@IDATฎ’ˆcK„Hฝ‹กฃjท‹ๅฅล’Hh|ช]cด‹uฆrึHT[…6ฉฑQdพถy�#hำูh?y๒Ž#a�กฝคŠtquอ0<4ฬ�6Iอธ๖cผmฐๆ็g8๋Cะt„NขaฒY^{๙ฅpแยa•T ๏ม5จPล้w=oฑr ]๓;ฝฏ*ฯ ๑:žWkch€ ่่sฑัh๊…n้๓c1NŸฉCGฦ5฿G๗’c>–1ถ69Ž`›)8ํDฆฎ^ปฬ๋Vคc์สๅhผXฐดk6๊%TรCฆ ฤ<…ซr)€‡4้พ� |‚๕ฉb1_ซฌUฎรชg๓้๕ฮžฮ๓8ื� ]ีR1U๙้Ÿ๙+ืn}็‡ฬฝด;„'ญญ นณ�ฟŒภ™ฯ�๊๗oTื?C1ั—^~%œy�๋#CN3| กฦj/yบ5�?�ใezฯ -n]“ใืgหเ•๕-๘ฆ\™ึฅฯO๚ มšD† n;t$|�#๏Ÿํ�ท?ฏฟ๖Rธ~}รz3<๑ตงpbRแ๔ป๗฿�ฎ0@D๐๐แ#สฤฯ๏:๘‰ฤเ Iะ;�๗ดา˜I0๏้้๔o}๙?•/^บRฝtกุฌี‰๔๗ฮอฯ๔ภำ๋/3๙ฦึf?๊`o3›๊HlฤN ว˜ut่d'๒ฝˆตr–k@Y�Vญ"o4T9ปธŠ0ฃธ๏Œ1)๔ž๕Œฌ;4‹�1ช:ˆC�ฎ๏yO,Œ๗ลลฟ}>w๑3Nxณ๎V(F}c์-t%ตH]]^�ขp๖ๅ0>N$tt[w/#‘ 7(บผFก-ภ g,ŒญŽVŽ้หั ื‹ ๏{ษ็ฎ_ู,^š`W‰โส2Ioถy๖ฒkต๕ึ7` @‘โ๕ช�<†—ฎ\ิFั๖ำ>‘Qภื๙iี/๐swt ๙ท๓›aอ™b้zอฺEฆูถึ,ตฝะซ~Ÿ3ฤ๏yกฐvฮก2๗^nฏƒun๊‡ลใฝb'h/m2ึ]ค6šยณ ณตJ๊$๔[แ�ฎWฏูอbั1e‡gผ!ƒ†ใ`'oฎอยžซnิฮ๗tฝุ�฿36ะี{ๅไฉSื~เก‡–ราxxŽcธ๓ฯ��ฐzwถ?๋เaฯ�“_�ซฯ}ใ๋งปJน๔ใŸฟ๒า0…๐๖ฝz~<ัš๛๐'~ ฅ“ฤ€;�บ4^9w!Bค'.Lแ•7cฮ==`@ม็Pจœู•…eœDiœkฝŠsŽฤแุฦฉขื้wžทQฟt„Yบv{9x'ๆ&ฦโ�ถWœบ1๕์-"๎a๗แ“แโk/`ˆABฯ€ฆR@็าต๑๐๊หol „๕My"ัฺ>k(ซ N4HฎzbtPยpสo* BM\ x;”{ฎŠ่คจฅ ฦฐโพ‚[Fํ‰PQ8๙| —UrํS )~฿c6มC+HU, s ˆ๙žhถ”s,ŠxlวŽTŽ =f4‰๐{Žฑน�ฆpค‰R˜—fฤ�3 sS� THข)"�ซะm‡dJลน—žŽฦSฆŠ๕ ฌ0\ ๙t๔s2ฎ›ˆ5C™สกžBึ>Qr/๋*๓ญ๛†w1~ยD๑๒�*‘ง —Fรน7/‡gžง b“( ว—RจAjสŒJ^ด�h<ช๔ํ๛รpิกV cPฌƒ๋ฅ1kฅD4TEํZท�‚Kพ‡�Š•LAm^�$แŸ2�ทkฤœIปc‡5�EชขŒ?๓XRม‚N��ŽฃŸขี๖6m8ฉI‘ฃฅ]Šuุลธkภ”`Œ_ฺ 5q๏พ=(dkิยก#G#๐dฮฎ็”;~ใ:…๋fiธเ@๑ะห็/ฐ๖`ฌp,Š„ซWiูE Œ™Zไ˜'1จฆข!ณฝMฤcPbี๔ฃVฌ'ๆ�g&ข  ๎ฃ‹kฑ8คฯฮŒ„2๋ึjฺฒodพlม9|่(ัภ]al์rธxแอศะๆ๓Vdๅ๚๑8ท: vFq[#’'}RPHใุ{ีศ2u'+ ‰จJŸี๚zฅF!3�€ฺั๊‹ฅโ2uอฆถ™ั�Mดw็'๘ภkธปaกถ˜x่ร?ดzึ~i'3Žsณ9_~ๆ+ฟ๛ฏW—ๆ?พHบฯ่่ต๐ตฏ~๚๎5@Ažeไvฌiหƒ+�=า๖^]xๅๅฐ�ศ-›๋aj๚F8w�zx๖ฅKazq:สฆุ5ฤGK?nณ““aฯ^จwชQ๓๖VW—ย+ฏฝˆณ-Ÿ่3ัw�ฎณฮd…ศ๐Hข|ฅ3/ฯ-รPฉมhg@�‰‚ฌภtXข†รz=&n,๑šฑ!าำฤฦฅฒ6.P อ)ฯ’k๎ถ่ป์ +็Uฤ]'VPIภมHBŒ„1Ž—i)†า -jYไ๘ŽzNJซQ๔จไ™_ W�Œฌ฿(p�™เศึp z,#W\lT๊,ึ๋œส_ruซ+ฎฯkœ๕sฦ(C็ฝL} ๋ ๏ก�ย5&Šค9์นจ:แEาI42ฎ_ฝ#-ฒDึY““7่Dr๑b,๘(ปภb_U๊˜rฐษ˜mTุฯ5๏๑0Bโฺญo9F]lsjมNึ๗อA�LigฝHญ�ค…้/ป0ฤq�dฐf]฿ถํม(q}œ}้…H�”*jื๋<ŽฃŽyฃฮ‡€„ฑใGลฆ๘œ8ฮYึ‚9ง1ฒมoŸU‹Zต�ุจoฎb-๒ษี…๕&]:(นัธฺ^.ฝะูำ�๒�=ป/9:๓ฎธz๚Ga+์s)†ณgC“ฎฺX…Zธ฿™[ณ9Q�ๆ๏>�๓ฯ>�ฅŸ}๋ี�F6I฿แา•9จฝ‹ัม2๕ฉซป;์฿7�๙ฮ๛ย�๗œฒ]ฬ˜Y ๎jงฌ๋o<๙|x๚์›แฯ<ƒฃœ๐qปiX๊% vถษBซ2ฏผฮg6ร-รแ“?๒ €€!ž7ZŠ"‹ฌนy€ฃณฯ>พ�ปOฤZ >ณ{๎ C{zย'ูO8|ไศฟy๏G?๕“8~osŸฟ3็้�๗]ต๊ „G™ี[pฟN๐3wแB๚๓_�\�S฿|jp~nๆะ๚าl๏๊Zฝ1ฟ•?ถLŒlืถสนlณ€ำŸถ;‹Ÿํ็TQNถ๊!้T]gjฬž"๛LSู�4ฮูเ$ะSฒ๏y™ƒ�86ผo^ฟ ]'อ๛TUO”a!Nฯฮ(6‘�แ๕๓็ยู็^ˆ@ญikKศxŠ/ฯ-„vd†zr‡Uู`�yC๙ส๕4 PŠyอkEžG๙หฺS^E›‚ฯ”ผลฝ]๊u?ถŸ +รl[�…ผํเษจ ปJด๚‹oล5+ˆ๎พฎ_ฯ๎๗3ศ6ํฮPbM๛,ธ2OAhaมnžญ�oปyตS์"’ tp1;คถb ำ$zกŠ.์ฃ้๛ฟ๏ร€ฒsแ‰oœ ณ‹ฆูต๎ีใjไa^:puVmำ๔2่‘mไจ,ก"cม(–ดณ�พ�{?๖๐ Vaฑ-ฯฯ`dH ภa์ฬศ&ะŽ้‚€ฮฺ(๐†โk์3#�vAา๑Lะ~sŸ8"�โž๑y)รภ?:พ*ž๑฿$<i˜ึ๑ะm๑๘ @—ราจ2)Xขอ) ดAD|โฺ4 ศษc=ฅฐaฦ‘c/ผ|!\วd\ืylO™f�ษŒ“uPG& ŒDเ…ใฉฌ[ �FkM^jF๑žฬ>m=ื‡Œํ๕ป๕ถœkpHใ5�ถLIฆแŒ๏อ:•ฌWdšฌทฅฮฮ=๒ำ ˆฯE1ีืฺL8๖ธ๎g ƒบ?ฺฌุฉ‘ศdำ !s+ๅ}ˆNถHc  ๐๔ุขฌCmJ™.ฐƒ`ท‰ บUย†ฌ‚‚ až!axx(�wื=’ฐฅไ.^ธภTฃ� ฎ1๖>ง+ไ๖9rfSวCึ„)๊qŸฑX�Œqด0ฃ7วต(ธ๖˜๋�gAyฒฦบ' นV฿XK4šฯ๗ ๕?30ุ๎ถwผ๋๒ม}lแ0Kš“๐ฅํปy”&;�Ÿึดh‡้฿�G�S๗g�ำW�GAท–�{๎งๆแpw79bD๐ ร‡ฯ<๕๕ใก๎+๔…๛)sjุwhx�/_/UZฦ!KูถŽผมy"ฮ ˆ†ฟ๙หถ๕ำ wณˆŸลxp๚ษงKโxžั๎%šŠฒํDยqBห:�ภ™#R\งEOฉ7"ฬ-$™!ชฌrQ!คถง–iึถi฿7=9Žมนฆ–ซแ™g฿€eฃWฏ‡ลUR#:๚@A…กpKI\Nจล QภjดhhD๋฿ถฒ๘สท 8ัสeฃW9F•mำHCฃขน gQj๓ุ๋ะใฺ ๊hผ �[๚๚:Ё†1Jซำท†ณฌBlฦ]วีGcๆ h ส fจ%3ส๑ฌrn:Gห ฐถl…›็แปFA>ขไB–&JณŒทŠฏILŽ็*hr>Sฅ๎ K3ะฺQP*P๓;ุ่$ะ๚7สl#2HปA B™nึw0‚ดลœm�ุSy๐mวuy~ ]ผ็?mค!”Iaฐ5•QฃrU๛‡#8 ๑ฐ๊ใk5œ�Yฆ{ฺ��œ1ŸพP 4วืเJ4qถ+[แา่๙๐�S_g�Iก ุ‚)ภํ/›ยต้ภฺXP%ี„ตเผ8^ภ,#?Ž{๛Iญฯ‘ย๒ต๘ J�16 !Ijคฒ๎4(Zเ’F )0ฤาผgฤJ๛(=Œก�ํิ้{5>ท]จi.ฆ(˜๓่ๆฑ:;yูhV  ๋zuŠฎ,pd˜,Ÿ/sLซa\ฐผโฺ0ma™5ฏัธต.ˆ*คŽ๖‘cว`์ฦุลู:|(ึQ0ขง!๏8\ปv=ผDฤ๎๕ืฮ•ร จู่DŒCˆŒFฯค9ฏ‚>�ฎ .#�ภ5MŒิ$d!ิ ผ็็ฐf†gVƒฉรDšฆ๋ZใงLtyฯCฎิ˜ndฏjŸk ฒๅER๘-hดฦw=ท`žเŒ] Š๙0 ๐T็>]7๋ฌ๋4ภ‘ืๅ˜GH8ํฮI{`žX๛)ึญใท๓ลŽ ›5šœooฯy\fๆ/qซ „aณ”ฯฟY,f{บป็n9~�๚C?�‰™งoa‚G4\ดส�๛�z;�ฬ~วู็ž๙�ืพ๔ูžๅ'Eณี ั(D-124ฯฯ�ํw�~โ/~*twŽ"34n;qข*Dํค๒ๅ/~#�๚ฏ�vXย �FŸค้‚‡ี2"Y›ญ\jjไXSu@MjkคRe<ฌ�S…ป๎น‡น๒yb[~้ล—รืพ๐QAุ ไg:v |ไcิ๎Ž5n ู์กพพž|เ‡ž�ถžˆ?Ž‹Gว?ส”�+vhn.๛ืแgFฆฦ'#g๓+๋หeาบ†Nฌฎญ๖เไโx๔๚๗ไ )Sณ<)Ÿ}žฑ<๒U™cอ๕ฃiDXIคE๙f็™ ฒฑg�ฯuztpnฝํTŒฦฯ#ซmหgTrgWyปยsฌŽ๏๏'-› ึ โ ž˜gฅฅ_Žueฺsแ„g*•�hชp๚U€SฯE๖uฮฦั%U–ุ้ฉƒ#t‹h€”6>g_�๐g;C๛ภถฮiม๖UุยUฏUสฟ-8Au#๘ฃฮฆ]ฃŽฑiKิ๚ฉa{.ำ๎ucV+2�b—ฎ_Oฉห๓คฎ4รฬiฎ•f˜_‚‰N(ภฆ$Zล˜`‹qUk๗คxอ ฯอฮ:F†Šื็š�f�X{ฑ6๏ษี602ฏS์บk8œ๚๏จgฺํ›dC๎�ทŸ๕Uฝฆ้คเ�€น�ิํฺy๋ศพV`็‹๋ˆ&ึœzึg(ฒุ฿}-NL _�ฎ๋฿kคŠฯ"ใfะCภ_pฮว rฺc˜v†ร\sŸ|.งU›ฤ QBSYอœX7D๙žem›ฆk`!ห� dธn~ํ ^ฦ๛๗^n2w=ฏkศอ  œ�๙œต ณ–'qœฏd|ฎ\ซุฝq ฐVฑ -^]_]J2Wฉฉp&‘อ=ู7ฒ{๔}฿๛ณ~่ก…_ยyd‡‘ว๘ป้Vำฮ๖'=ญฺในฟ๐ก�ย๘กลตีก�ัำ;D๐ำ">8NF>Q2 SIoำศ/๒^'‘ง[Ož [6�r๊D˜�แ๙o†๓ฏM„‰ูJ€J๗Žw�^!ง๚๒ๅKQ(‰ชJฏRV”‰4ฅŒฌ…ฃว…|!ยฬ•ทBua2�v๔€ฤัƒ>ŸภA -ๅ„ย@๙ถŠ๛!ุQ\xญกB€+„ขRA€WฎฝjKณกฃgwจฌ@™'Eขฤ๑ถmแฑ�๙๐��๑+aj ฅ�ีส}Cฐชะื"๊[G9XMXไSลo$Yๅa๔dem5าufŒF)ถำƒ„…๑ …๘ฌห`ŽฆFดŽกNtAtz�:FŽภAkC!aฤโp8ด%H…นัlเ๏จh,XT„บฏย๒|R้Uv(ˆศทน‰ย%.Hฑษน๚^ซ,šสˆ4ƒ…{ฤฉ็Pf๎%ปJ฿Šl8ˆ^ซด๐D–องฃ5ื ๐‡‰  หfd " ๛ูZส มผะ€e*rN”r๎ฺ$ฝ›1(ืA๗5ฆฒDN บศOฆฅ6Šลฅกš‹ฉ ‚\ๅบึ-ฌื฿๖<•๗�ฬ$ๅพpืฝ๏่Y ณPขm}dด€"๋ad฿ม๐๘—?เต5 †”/สฏIq@kU ฆˆfs�”น๙*(๏,ดฉ ฯ›๙ฉIŠ(mืQบŒu“น^ัฦรฑfฝน6Tะqะ‹v•Pัn2.hŽ•‘…[์(ม๗4D๗}nโ(h€*ๆกฑฅฑฒD—1ฒใRษ5bัH[D5 ]ถตงรƒ~icq>1�TฮKNŒk œ rฬญ ‹-Aั�ยะฉเHำทœuุ 7& ฅR฿‚ข—๋ะPญ&~๔่ัp่ย…‹oDpฆ`ม. O5๎้ํว$ข๕d˜š˜(a@๖Xd0ƒว๔)ž FK�4ZlK_Zas›bcŒMž{๋–ูธ'ฝ3šโ๚'ฃ Z=šjิท‹h3,"#A=คัŒุำ‰V1vf้เ Am๔r‚รฟ๗ะž˜ซผมsบkhu%–ร NoG5ฯ๙ส1Œ0๋l…๚'ฌYๆ^ฤtฏีแŒŠิb>3ฯ๋พŠ!ฺY‡นRฏWš€-[คๆย5Š>NPกzฅ\j�ฝoเ…฿๗ฑs๑‡x1ŒŒD ฉUฌ๑�ซP฿“_๘๕ฟ<5>�้5jฅ,S๓dr๒yภ็ยฅห3ไ3>ฌูBฆƒขh#แ=�>8B5whฝฬ‡ฯƒ๓QgํYฬ๔ตscแ3Ÿ�7คƒ` R'&ั$*๖๖๓"Hซlื„dƒขช87 Z1ฎ"ทนํh๘๘C�]่้fn“!œ?�F๘ยo}ๆัr่„๕v๚w…Cว"๏Iีkk�ฮ&Ÿ<|฿๗=ๆ3๙ท�ฦภa4FQ4$ž�โ‹/{กmqb2นˆCQฝฮJ๕€[_ฅบr€๎-ฐ2ทถ‘FD‰€|B9-ุฏŠ๔|ไbŒ๒ัลs!K„�ฤผižม๊๎ฦ�ำ�m�Lฟ/ะูM�๔‚ ไuHˆส๗ลใ,eGHC๊`฿๑ษ žยฉ�ฃ๎€�ฺ“ะž�ํย2=จa}˜ZฅŒตs5c6ฑ%ข#ฤAฺ‘ORชMรŠีๆ9ฎ2ฦN@สA^u'ท…�Gโx(7”ตามธ๗๖uQฌุžะ่kQงI‡4Bg์๐ม#8ะฅ0ป@t๏งnคHส`เฝ~c6|แ @น.O\ ›tํ)Žu2rฑฮ>‚๛�ฅเ…๚U�-“PูจCงR?ฌั*PนZD8p>Œ$ปŸŒEu ซฉy)ฦCCดEธ'“F�{lำ็”iฺ[Œฉsdว-า็๏๗ฌรเศแ0ิ_?๘แ๗…“G๗๑,Z๋ :‘๑YjSล/๒]ู2ฃ-’“� ฺ‚ŒŒ ั  �f„Bใc&ภฎHo) rVV xฏ๑�k๎ิ ไฬฐFV‘=๓ีฎ2๕ญS@๛ฬ:Ltๆธnr_~๓RXœฑvฬnุKฎลG๖f<๒tธXฤ.ซSท`6ฬ.QD’pห"5fๆ'ย,i-ซฬq‰เ…ฉฒฒ ิ™๋ฌ1‹v;aฆ�ิq�ตฝVว~‹๕f�cAๅ™๋ฬ G=*เไ{O|รtฮี๋รzNM@๘$k[�gZ‹๛ธ†erWX๛สSJ >โœq<}‡—-๖ikMต wถค๓;7ื“kล็@]็ตLธฟม/฿— psŸ-าU5L1ิแ7ฅ&ัD6ร(*�e‰๋ฒ�๕j|9ฯฝณcด‰ f•q]kฎ9Ÿน›LOค~€rณ^„ถฑ็ืร฿‚�ธiใ๒ภs€<ัโ\iํ[ๅฒ†`dํ.ฎ.ƒ…5็ำ๙�ฉ7฿$5๊๑ใว=๗s��฿Ÿ@๗ึ~๘�K๗ฦุ๙็<ญ•๓G�ฺฮ�ฟŒภ /43ษฯt�๋๚O�}eb๕๕d๎�ูB{gš—ŠภV|๋(rXแMl„ฆั๘,�i3<ฤ๛` 8ผ?�v๛!๐โฅณฯ…ืซแู็� uฯf’œz„Rย�c)”ฆˆฬ่HQRใ 9h๊ไC”^?ีใ๏?�@X˜บNๅ�T8x”จ}‡PD‘’ดU๛๒>‚K‹…ดIั›Tผ;า 8™-๔r1~ศ๑Gแm!?–งวร™ฏ<~๓฿™ ๛ณ!M5�๐์์r�š9ฎ•hK˜Šˆ๊๔p žน˜^ƒJWมjฝ‚vบ-DEภX้ ๊ˆX\จˆ1ฬญวขxหศm ~SAšOฏbนuฐlc&ุœ\+gๅีbณชธฦ”๓‘G™‹|๛=ม ศ&C^)่oซ๘Œ…|ฬฑoต็ภศjš�แyึ๖QM#JฮY’่œsXไ��‡ฌ�~j@;6uภ‘:ใi!อ๕mฬูี+๙L๚&โQหkป‡:฿8|่ศ›๏zฯ3�•ฟพHฦอฯณดOฐ๖i๘d(ศ8ภู๙ฉ‰๑�ฃ0wๆg'ยt฿^ 8แตRWtŒJIGรฝw๏{�{ฐ Xฯe‚—สเืฯ_ Ÿ�ทฟฦ�ข•'เ— ด‘ส ขิ2L"kŠต[,ำฑ#SIF‹r@ษu่yvS๋ๆ๗พ ศ”jฑฐVฆฆfรSO<ฎŽ^ ŽŸ๚๘วยฎ�ปขŒ๏รqํ(ดMณฉ๖น๗e–ยทํ๖(B62X+}ๆ3ํS7.—/_=—ุชW{ซซ•nj�’๋,ๆˆ,็ืV–3๒�ดูMู€e]@,๗โŒแท6ฃฮศ!•ู๊0‹Œไ™U1_ส@ๅNtv{2ธ�1รsฺFซบฯg8�๊b๏ห๕่gˆ{t_1~ืฯl;0ะ‡อqŽค2$=ฤฺF๖แ�๊TษŽp\‚๑u]:6๗>ิ?๕๎ ไุี้๐� ฏว:็ฏ\‚Mล2ฆฎokt,’B‘fLŠ่/Y}1Rฬต{/2"่ม๛าีฝ/f„1’m่5bSp,ฏ�ฯฌ5คฝ1�ถ.“๚GถฃŸทๆK†€ฒธ•sn0ขย๓k[�:in‘๑{-‰ฌ๏Dงœพ๏d๘ Ÿ�(้ \ป5e:ฑ�ฐwœ,๎>ึ%@Šฦ…#Pเ๛œืH{v›bL}…ตม5๓๖’AŠzx�<หณฮ7€๖ฮzuฒJ0M์”ย2ฆB<0Ž4ฒ'ฬM�ˆ ";Kดก—ห]ƒ1๘@ภ™ฯฏ ฟฃq๐ี#ฅ’6{ยมƒBะ8๐่Gำg)œฝ Pœษ3@๚๓sแโ…VวรY\ีMำ Mก-‡ุ>3ุ*kฌ);pจjุ˜nฺƒ�;ŒึH�Šญย8˜‚ ๘๎šเp_๏)R๓y–ษศภใำdWฑต—ๆตฅ ๔0ึ่eแDอฺ ภ ื^ฝไั๙g,๛„โ๛7๋hcธ <ˆ๐9๖œฺ#‚ใฎ็C๛ขh�,พื5#ึI‰ล™๙\ึส]ฑุญE™&ุ"mค Wุ0เ!ณŒ"�.�ลิ"ฉe€ฦ-‚]œำ`–€]็ฮ ‹…R|>ฝฎnุ 1ˆ†ะŠe0xฯZญVพ<๓0๓�“ใฟลุิh๏สN๑{ 3อ.ฮ^e|Ÿ(wถ}�ภแร/�ƒ�ซ—H3ฌ�}7 {g๛ŽŸณํyšWฎไ๙Ÿ�ญ=gžz๚ƒ๋ตฺ':ป{๏Jฺณึ>“f˜�U๐(„Œ๊ไ๛3g˜‡ำ๐ั~้D‰�คhฯ>๘^๚,๔TŒธงž&฿ญ?�ฦc_€ํ<ว<,ืam +#�8Hน… ๏�Bqฤพ‘�5 e๙žำ!…ยˆนoˆฤm1ง j๑ถE�H5HˆDฯฃฆ.‡\๗ฮl ๎g๙๚จ|œบ/L‚bฟyแZx๒๙7ยK็ฎ†ลu„7ศ๓�lซ]ขd"c@มŽไาpPจYฬMมฆ€j'S‡Lๅ๓หjำฑ:ฒ=ƒcA9„ญy๙ผัำ1—๊kpM 8ผ[Šศd „ณž ล�@@[XQวลˆ†B]al1>ง#ฃ๖ฺ,X(`aิมŠ๔ฮ]ฬCเถh�ฬcŸTธrัK0๓Qz:CๆํSƒ&‹P๎$โbž[‚‚81ย„#o~็พรG1่ึฉ”~ึ๔ว(๒e>ะ{˜๗OD๗Wq˜ฝF็]$On฿ะศžจวF฿โsj=ฐ–ค’ ฤF~ขฬถ:2สcช†ชญQ Sezjใs’<ปy‚ฺฬF]ีzm6าๅ[ข๙8x์oม'VuŒlไrคTˆOP„i•โšุฃดษZ ห(ว$็L=หฆurQฒฬณถ ฯƒ๕9รuพ˜รแ1Rฎj‡’ิŒ 82ป�/JฎNฝ >ำ˜ำ`pLwั๘๐๏hดs|จ‘งธส\c€็ญ“๕ผŒ#๊Zัwฮ3%"Œว๑ใG่ ธL�ศฎ|ุณt๛ษS�7F"ืuc�Noซv†sฯวฒีะ0อรย-วo…9ฎ]น ํถ้3ณs+แ๒ีk6ฌ ุ WYŒo๓E้ลึ—xF1๘MงY˜d8a”™๓ƒuฺ-ชกฌ๑hW๊0ืPF1|๛;ปP๔tX˜Ÿa}P<Y ๑ฑยุIWอ“ฟŒนอน่บยx�8ฦI ŸKQ๔@้ Fƒ๋g`ยHฃEภnป๏ฎ0ะ�ๅุ kfcนฤ~4s>วoŒวxวแฒภ›ุฦก’สie๖<ืฮicm6็รuฆSใ�ส*ฺˆฏTX2ทฟ<Ÿyไ๋‹ตcjŠJฬ๙�O๊หZŠ!™-dK็“๕ญg๖Œ๔อQฌฑ˜Ieฏ�}๗ํo�ศง~v๚สกC•ป฿†Mณyฝ๐ฺำฏ�ึ๔ิ๕^ป†‘>^y๑,๙ๅใtลฉB๗ลIซa<ณฎบJ‰๐—�‡Ÿ ๗��˜j๋ฬ1ลa‘ฝk๊_�๊Sแ๋_๚2Jถฒ‚””$เำ้ษธ_”‚žx‰%ภƒl. ˜ตAดšฌ5:ฑ,%(|x:ึปุฝ?L ๕ีุอAvาฎ‘@ก�ฐzจŒข฿��ท๏#ๅฃG)ˆ๑ญพa๚Jยๆใษั3/ไž๙โ7บ็ง'๛ฮฟq�ึ•ฅน[‰L ๎~h�รลrW ะพsาY;�iๆัภ6C 1ฯ๓( j™NฌES ิƒ[ๅ8#[<1ฒศบNQฆHdูŠ�ส๋2Nœ…w๔๚่R`-fˆ๔‚AฤhปŒ5uะ›/ Ÿากฟณ':qซ_k4์D/|๕ห‡+/…ตRฆ๔#qLnาซu‚”yถพำIึษๅ่จy}Q–๚š็S@฿(ฐquข’าฺ �฿6๗%'ใ ๔๘Y๖S—E]ˆvLl๗{๋ํwย€่๗ฏ�u่๚๚;ยฎแaไ#I0@` ย^๊จ�Iแss่Žฉ<บ6v5LO„฿—Uถํ4 ๓e”�๙้<ถด]†1`ฮธฌ๕ถ๒%)H€^ำŽ๐�Z๗ŽŽF�lฌหLDถdŽ‘็–ƒจ�U!mq�ุ�€๛๓�ุ›๔> อa๖=๗Oภ € sๆๆธฤ1ล้Š้ฃ่บมOyฏmDๆw…wžพ;ผ๛�;CO'ถ uฆr8ู‚�่ป๛ฤึฬCษ๛Œ;‚R๖‚j xส๛ฌฌ*ขฌC$`Q&xดMš฿๔ไ5j ภญa�แpซ๏mฯป{฿q๖้ 3ืใ<๖ํฺ m U3–K ดN$Tกปป[ŠฎR่!ปjaบค†ม]{โ�ข�Q“๑่๎Œ6ใโาบ�T‚<หคสXศ1$)j qcj&<�ิY˜T่ฎีT›”sƒ>u><3ฺญ^˜ฯ”L>"2He@เXๆY์ ืด๚PปA�๏zึ์Q8ฎ#๘4@๙ ๗aซbำต�]๓8p_Y3ฌuuธŸii๏ T8ฎ„๔ุ;ƒนัu9�เQ�h#š้นดad<บๆ๐�Ž?�วเ†ฯO–}|฿Ž ฆฐjณช31s9 ฯ‚๖€I†๋�F‡z=[�๖๛vฉบ|ู L๑ฐDฐlฐ�ฮ ‚ฝฏ3้๕2i�VVน>‹ศž˜VD—ƒ)^ท€”฿qอ•ธ.ํ†:ืฒ๒vŠฐ!#/”1ัถŽ์ ๆ5า  ไ$๖�+V}�ุ‰c_ฟํฤ๑ณ'๎๙KK‡sร่�ูพ#F@›kg๛chไ~แ/�นใOฟ|๖GšษฬG(dw —ฃ5 —ฦนxจ, „„J›‡!ฆย๕AWhูฮmab' '๖๏เ๓๐ƒc{ฝRG!Lก8›…�๐๙3ฯSงร!ฌ1ใƒm"nˆ™]ƒโf_แ ฉใฐงKj>("ˆ๒�]ท�…!nv‰ผศ[Byจ&เย8Mฎ}ถซฏ52\็๖�4ŸAeุำ๊“WWๆ๊CดธณฦผT๗ล9 �ๅ๐๊น‹แ๑วฟJ+>๎ต4H•nRึP((= ~�ุX-ูjณސujาiฮ�ค€‰&๋R�{P๐ตœ‚?Oj-uดT2ๆ•GeษX(4=žฟ�ŒฉŒ�ดUQsฯ๎็๋่ข„ ‚ ผ๖บTLFcฺG�Pi!์›n๎kจTE[2Jฯb„ดsฌ:ˆผQิ6 Ž๔u†�๏<ซ'ซ k•–ฒ๖*])#'๏ ŠX.^yญี&ๅจใ�Mพ๖พaœRจฦุ่นฉ h†ไฤsO=คH)ไfQญT‹iUQb%:`๔ํf�๑h€YtqอVV9œe รEPs4ญาkQผ5"ู"m‹˜#Sga™ุ๖ศžฬาฃฅๆQศฑป„@”๗j�œ\ข—ฌ้&เ3JQD"ฬฬK” ำrDO9EtJมฒy1ห*k~f6^Ožyถ€เ Ž6QeขnD›qทธว&J7Šๆขใ<ผm8ธ&TสK…ฌ"ิˆp�ุ%ฎ#เฅRwL10`#�UะชฃทLดต—pItPุ฿•qฃ."C#aๆ-๊ฌ3ภ\ญc,h”บ6†w@9mรxZg_ฺ2๒์น,eฎ‡๙ภน|e*Œ‡W^=‡ƒศ๓” Rมn)ถ-3อ_๔:bฑ"๎ม่…๔JฃŽ{k=ยมˆ/uถ†‰cขมขaโ�ไ`ส ๊ ก[)’ฅF#+>goGgึ18=พฬ˜-�‹ํฮXS5ๆn๛ซb€Vใ˜๊$h0ท(น2n\7ƒ๛Fยพ=๛ข์๊์าน|u<^ซใ๎ฦI0Š8 ๓ภยซ>7ฃ—i?Šh๏r‘yาฏŒฺX๓au cY893ม‘,ศ›…KgY็kิ‘(]ตhYc๙นฯmผ7๎em‡ŠœiฦL€วอvŸIึu*‰อฦ\ฉฝ/ต}้žำ'?๗ณฟ๚่ตั3a๓มŠ[๓ัGSO๊?ดบพ�^ฝะ๗]^้dt^ึะ ฟ'ช๔Yo9ถ๚0ตJLAf[gนปฃ�uNดืืoิž๋Z0XรYsยnI‚ป ฎก ช› o`ธๅ,s๎ต5๊$q]ฝ�{ฑ็ฐKฐAปHฝ๋ฦฆ[˜ฃz?้pทžข8๒~๔๖  แฤ๕1d่r dX;'ึ๐�ดcฐญผ7ฦตEฺฟnฌ’FืษZขP26‚]ตบzvมt› ็^P[&ฌ>˜*ฮ๙ซฏ\3ด–f�jŒgŠ9t๘=ฬƒด8†žร๕ุ้;๘)R+™Pๆ‹”=ฺ‰šา#ใ&ฎQ๖W�;[๊as๔]Ÿ~7‚8Œ+{’{แX4ึƒŠsฮ9"ศ\๛ฺsฉO Vฉร�‘ ˜ศ1%ธ๏› šc ๎๛>gฎฟ๋u{�๊VŽzeชจำ}S_ฉำMมํค๑Z 4Y/!H�{of้yีwพu—ชบต๏{WWU๏�๊nษ’- y‘-�x‹˜`BB 3f ๆ‰g ุ&1!0„-1ž3ฒรใ�’Z›ตtทบีญ�ปk฿๗�ึv๋�๙��ซ&<“™ไaฤ<ฺ่ญ๊ฎบ๕�๏{฿๓žๅ�็ึ†7ฦ@ฟ ัiฑคู[�ฝ4 Fจ'Šgร็ๅzส`แ๒3ฯ†,š {Ž„L™(่pเ๛ค‘92ฒ๛LZ‡(uตศ“% žE๛์p/�1ัฉœ{�•M.ยžเนปWœU7’žDศ� �2บฆงฒฐ(ฏT4ิ]†Y๛่๑;๏๘ฦO�ิฯM}์ca๋ฃ}DP4�ถพ��W_�+P( –่~๒ะฅ ็~`9ป๙๕MํU(eงŒ๐rงH FฉIนีภŒฉhD�U$:ํ8ƒ"จฃรUd5Œuส๛ปCGkcศ.ฯก$P(ฯำo…S/\ฅีAม0Pซช‘ฯ ่TFy= ฑจ๊นfŽ^scuุำƒaOGh#๊ลฉŸŒYึ๖บ.s่๋ศ0mฏ/P“}=4๗ ๅ-}<่ๆยDXธZŽ=’อฝakŠฑr ส™ฝวhภC๘…๑p๎ษ/„มมิ=c@Jชร~ญD่ขร๎๔3ฐ&=WYKW]:๏ฃœUึาฆหษFk๘Uส:[ZคM5xK4*ศ๚:ฒ”(%๋ �w Qbึ{๊�š1๖{J›ฟจภTlทY8ณ~ฦ.neคuกiํ;เุ9ฏ.:QJ`ฬ(ฐ–6fชภ›q๕ฅQp‰Eข๙h๖ฬบ6ฎ •ฝ`ŸซกTท61ˆwivšž‚ฉ&๖ถŒฆO�์้,4๑fAฒDd†ญู3ณซsำฐ็uสaๆ๚้(+eฅ1Cxš๖„ย์`ศโL่๔™1ฎg/ฬZ๏fษR“มXžŽka0Yษš7๕>g}iaส#ษ,ณ{เ๚Tฺ๑‡ปั‰kOฦฬ Fงชบ!~goเึUฆ7`’%ทQ�ึ@ใ๖ึy๏6ๅ*�C@d‡lฮV๊พืsฏํฃ sดCผVKYฤํ@_cต‚C]lฮz ธ�ณ–m๐‡ไ<ื#[ส5๓Œˆ๔Uฬพ๋„้‡fอผฆ฿w�=cพ�฿ฃŒธ{ฤ qญc“,k�qา-Kqื��ํแ๘�‡ยัใb`? ``าธ'-t|‡wYด.ูfฏzzz๘<2>3S\w;Y็OŸ฿๗?�SšžžW/_Ž๏‘แมIBฦฑ#€\ŽšญBณฒSXฟu3ด8นl 2ˆฃฬwำ)š‰ถ5…ื�w_x๋[฿�‹฿�ํ๏�…้�ษฦ๗Q��?เHp อ๔ ฆ/^L}๖หŸm=}๚ฬม™‘‰C[;›วaฬค+;ะjKQค’ฺ†44 h๋๙ณโ‚•–†้`๋ฬKท,ห@ภภ{[6 4พ :ยคฌา…ิlc“" ภ^ ิ3นF ฑึ gอ€ูž-fใ��)แก ๊4 Y:g/ภšฒผC๋ึญฒ‡„จะตฬฮB9?s๎LlŽึฺูE หp t์‰ ะ‰๊pj%�ฬ)์ฮคฃ u๒ต10เฌล€ ]โWƒž�:Q๛ๅ™)'X�aขอใžd๓ilเผŒ�เ4l๎‰ฯ*่ทฟฏ+๔๎ํˆAฎ1I;;ป:ฃ�ฺ„Nต์‚Yสืฮœ6 Š�^DพV9๓laอ า๔{"žซRŸ๑\)ึ{—ฦœ‚\9โ~ี€ฺมฬzE›ฅMx๖Yb–—็ธ]ร};ƒl๖ูiG๊™Lพ]+ฑs‚%ุ๊?ห $pJ๎'“aโ๏”จ_8'ุ€AXdgเoกง,SWs๛๑:fŸeV่ rเ621ษ๒ถDฝ™_ƒๆ฿๊™๒ดK)– ;Qฺ฿จ@6ฝฑน+>“ต�9ฮด ‰š๊ึ0‚™�QศคSn๊`=Vc?›่ปใ๚la�—ฑ'๋ฌน#ฅ+ง{บ๗"‹uยS$dBhทL,ษ์ชฃŒt•๒‘™๑1t‰}ฎ ฦ-ํƒ6ฯฯUคฒ-]ห@,๕Cugdๅ5ฆ3ญQ†ทฮm)C๔2*เ+ุ/ษ็ฎฉsาP.,1ขQDด3ฺš�< @f^ขฌปๆ2#-u=d-nต@IDAT]๏€T#๗h*e1Sมyร.h=ว๚\‚~‘ฅ€|h๛=ฏ๗สDœภ8‚๛ƒ|}eฟฏŸƒ^lถ๒แฟ•{eะu๑Œxญ2q–=cฺ(ูqไ#�iกษ~ด € "่cช3๕3<‹ส\ั7)W๖ˆ’•d–[๘ฐ~ฎ@Ÿษ{gฐ๙ศฬWหHะ๑œ;ฌEWWG่กŒp™�ศ๐(tืi<™Xkว’IY>“@r IWสœ_Vฦ(ฟล6จs"+9ฐ”ณ€?V๎=ผrฑ'ฯช๎๓ไ?ฺM'?PVUป'*v‡ลนลดฤๆ"*‡ Y;”{ธT่*dณxทU฿ฃฃ<ะ?ฤAคXฒพ6๔€N฿qไ0ฃAn‰W�ป:ก’ฯ„ฯ�ั�ž8}=d@_ฅ ํ’)0ภฺ˜U่. xlpRวแmฎฅฝฉž๎ฝ‡C{CUhฃ~ฒฒAš ๔ณJ๕4ู์„0xนMƒš๔ไq!ฦ~v8$๖P(‚๒ขฏUๆ:A๊ต—Ÿu^ ฃS‹แ‰gž%kHˆKV…)พŸช€ึ˜ง&‹ฆ‰ฎษ<Ž„สู@!IPฅ3ก…BฅแEงฮ Cฌโ5ฌซ็๗u๔๐Pโ”•-฿tPฉซ๘Uผ�\ุ ๎_@ฦห?ฏรฏถภัฐ๚ ›๊ณ ลŒ… „๗ฆกa6}TšE'†ๅ(*๏หŸุฤุ๒PH+B#ิjqฒ+ล ทƒ์ต๔jจ์ษ‘–‚้ ํ˜ีโ๏EวDš„b7ํzต๖� “ภ็ ม๛ d0l —ฦˆ๚Œ•M]4ธ็{�li�&FCF` +ฃy฿�{ ๗ฬืใ>y^Y"ql$`Tช–’œ›ีษ�0qํ2›i4qีศF0เ ีะxQ0gc็ฯ6ช|UเŒ้€-aำŒฦ๐Liค”๗�ถัwu,”ฎ !๓฿ล—uฑน’™>หbŸeำฒ2JH๊Z+Cฯ�ฎะาัชนmzqุฯย>m4„ด�ย> :9ป10XŠA๛‘ฃฃ38t >ษ๔d25œำ:๊<'ยSO็.‘ใ^กGฐŒ@ผฎ^GŽ์ๆ�๔geน‘ž:๕n˜™ๅฬg๔Ys:^<ฃฃL•[uส๒2�ะ�{จ'~เ�๐เ›฿H^œเเ99๓์Sแสๅ‹8:๑ฌฆะีžE� cํ&ฟuฅ?S๘ฯฎ6าsฅ^ถษฎeAm_YMำ€+œ๙ทฟ้M€ฃ3๑ณ์%xนษYš"@�ขฏอJ่้้‰I5tK*๔"บZ�›ฃ$ฬ๕ท๗Œs๎cว455ฤ@ุ๛๙ร4=v�ึศ,oฎมH`I3%d:46™t6ตใ`วณo฿๕qŠ�HฃณdXW ^Šบs{g_)๕…2เดœ˜แF1่Dม�&0p๊V&ณลFั†ฐง๚Vลต๑™^afฐ๖๊a_+ฐรฬ<—ยP*‡ฒŒf‚qzVa žษฐ9€~ง‚๒ฒ*lD} .q๖๔A6ั๖Sฒ9q%6�†ณิห”˜™�ทฤฒŽณZG/,zศย\ฬFp]๖ษ� ,ึdueŠžŒd๖Cิ�hm M1�ek6ใz]฿—อ.วR‡์๚zัี€Sฺ๏๚.k+ผceŠ฿฿X!@v=‘ห]|!'[x๏ส—๚ุ ทฟ8๛@–ˆpฎ#˜ ฐ]๓UzRd๑ร*xŸ฿dฦvSŽSุง˜(เอ”;u่นF††โ๙นี?B3i:่ žี›ุ”��,๔€…Mšื๑)6y�l_ฎ‹:ั๛6๑เฟ‹>ๅ ุ Ÿี}๑™lŽj9ฎ>ฺmฟx‹๑ ์ำ ช๖+ต55_��แหํฝw๑˜ิ›W_+V žญฟw๚Mt“7 …ฒ�๓วพ๋ไๅ๓ืฟgfq๙=4 ฺ—ก๋oEฉฉjฅฅ+ ล"… ร#šŒล‰ฒสE'Y๖มงฮหร?ฮœy‘ๆ?c[hY4Oฌ‡)ะืูบ:ษิใฤดvด…กม๐~�๓แ๚�ูAŸห0@%1’ร‰โฯ!udRLฉ๕าไ›๘~+๔๘ƒ๛{BO[cxใ›�Zzl0 pf$Tึท„TSฺอฅ‚�์rฟ6ฉแ๑)W ๛๐'พ .P”y๊฿&ฏผHf“๙รMญa5—?�ษO„[ƒ3ฎ|˜[ลAฉ$k ฒถ "0 U:Wห`ิฮรณ:cมฑฐ#:(5ฝ<6 ร‘•q`Pโ:ŠŠชศTNพT\–-lผj์5ช*ุ้ ‰‡3ะ๒�็ศฮภจฬใฯq<|P๋€‹ผช์อb๘yๅdไ๔๔Dล5N:dฌ@�ฏi๐ฏ‚—–™B)ื๓<]ํ ะ6xp–๘w �HKณ๎™daP“"@ืฑ‹u‘ั1%ใข [@นสิภL€-ฐ2;‚“‹AEฅEVˆ†hม�€SB"vศึšด9ใX๚X-ภ@�gะฅ%:™s€ 6NชฌoG>๏ฦz–bh ฬbพ~‡™€žlˆh๚.ื4ƒQ ภTUว8/œ‚แก์ฮ-ต๚/]€^;อฌแ!จ~ะžiž4๗>:‹�ŽXไ;Pav ิ ŽmัุS@ชœม่ธpCeชAใ0NbŠ๓dณPkjมr #d™แ~kœ�ณใ#ษฎ� �'ธ๎Q4๐\CgPเ สŽKkkK่ไœmลต~ผ ะฮ&|™œY๏วฦYึแz ท2j••;3L๖์ศ“อnmซ@จภ๙(โ๗šก!ทีฉผqใV๘๒Wพ^87@นƒ ฮ#�8สฮ์EฑKi‰ Š|?ร}ีกจoค )โmpํ9‰ ก๋ภ๛t„oY1ƒ๗ฟ„ณ[]ƒ�8ธ/�๛†yศ ๓�6Fฒz~ฎ_นชฆq๊^:ž{ว๐ Ž@cŸ&ฤ9ะq!�Ÿงฏล&2mฝฃ}Btอešมัy๗,Dภ ๙ตฉ:O*i<7ศ™๕•�ฌkŸmฆฦ€"…~๊‹ŽM#™V~%ษŒ1ฎxZ๋ƒ‡"+aœ,XSS๋ย๕ซWqVศ0P$}นN�ฐxฅดYฯ|ิล8ซ‚{฿R๎S0อZX›3๊๐I…]Zฅป๘โโB&น{ฉพบ๒‰#G=๑๏�๖‹}฿ฏ๒จz|ุ�ซฐฐP{๚๔c�๚ล—�>�5/œ />�lXค mY‡ŽOษขุ|ฒ |rฮ- e9฿wt�*qน4ิ-ณฃศŽผฯฦ34ืWGfำไไ%deกฐfŠธgGXvOg{Xคแกบซž@ฤqฉ“ฃœ1ฒn‚l5็�ๆr่(ไ-Žš�[“aฦญF_๏฿ฯTz ไ`:ะCผ๓ไ�ืฆง'ฎฟๅ๏๘๘๛�งŸ8�WตV�Mแ,ัN๗lู—?๗{UŸ�์฿1ฟถ|(ปน�A–๙๎า๒๔‰dกคžฮ๑ๅ อ”ฟ W)l„๚|ฐคธ@๖]šฎ็ื†]tดZ�ฆ ๊xทึฬ˜S ฺ๗๎A? „DS?ฌ ๒ฺwD+!0ๅQฏ*}LFq-ผ�เ๐ ตโ;ฑŽ฿y๖AH์็นK(ั[‹€ใ]w‡™7L3ห๋œณฅx^jiฺ‡=มyPฤถเศฏcwcฃ^l•“pV‘U๛๗ศJŠม‘z‚{“ั@ุUŸC†cŠฯ5xU็ุ้k—;N&เ๏๊2๕Œe…s€V๓ฐu๘AweVถnKั‘N`*eไ3„}ช„Mf}v๒ุฦueBU‡ึn›ฺUฦI๊ƒ๐.ุำฐ๑ผฯ@ŸKึ฿๒ฦ๒ K7หโV P''–่ฐูgs3€\œ_๕…๋์wd ฒฒ �อดป:๊QT๕” ขl Aฑj�ช-๖ฬŸห@๐xmb0ว้๒ฌธfZŽŽฏ“ฉb`\ˆเtห �+๏_฿ฦ5“ ˜ภN•ข3-กศpภdึ‘ธฉ#[-;ฌชบ6{e‘†ำ์ ข็๘~m›๋oVzr|„๗,๐œศ*๗cฏฃ5@๕‰ฬอGปd๒€ญGB3gSฐTี< ฃ,หภ‚ ‰Ÿ{็pฟ–ี ฦ†€ผvๆื'3ษฤx‘ใฑภฑdƒ๛ps/ตNศq:Rl๐ห็ ๖F Zูใ:ฒvฐy๊d{ล๑ฑ่6}“ี•bŸ˜ํ6 มg›4ฒ<ร>ah>๖ภ‚ตR๖๙•(ใŽtVv�s�?ูu2าฌซe›๚2‚E ศs`|yV=?๚EPก8JัปฏฒZvะ%สƒoฃH‘๓๚‘๊ืล—gฦ$“อณ่Hƒoห”K�ๆฑพ‚T๚Z�…nŠพบl@ฯTจ0>4€nYฝฝm0๗๊cขqG†ะ‘“๗0๑ค=๎ร�ุ`์ัุู๏[์_Q‚พXพฮ•™ตดFฯฅ!ภ…น(3LYb๔)ฬโ�”MŽW)+ฮ”ืฆภ…uX/สb` 2ly>ํซeญ๚tจธ็<I2�U๖ืoสฐ6&๛ฦ—,!uใ]Yใภ๋+”Z?v็ษื<๑ร��Gฯ๖๔�นยูQพ๚๚&]Wฤ๛›๔๎พษn๋ิฉBjk์ทš?๛™_�๓๓ห?Rืานตย *#8ฆๆ�C…ฉŒA ŠNE3]('S^ ๔EณœO?๕$ฮH2ด42๎๎5๗„็พ๑ ‡ Z ฒ‰L๕‘พพ h–ตฝซ#Œ@[�4�ณงก†ฅ+[Qฆ8ม%3›(ส%2"๚ํญ แ…ะ@ถณง“q9t๐=ฦHฦ",f2OฏuNจฉx™XCc�๑L‰ส8ิณ(*2�ญ=๔5ภIŒ–†๒…’๑=|x(€HK‹ulะ ŸฦgWร๏�ึo†นl2ŒŒฮ…kทฦษ(R—ˆฟฦ˜ฐ< ฒŒภu{“,+จ#Žฌ?ำ‰ั8ซd5> ‚tM/Nั\ึะ;ึ๘@™)Q!๛วG1๋i๗c๋ะํ+(ใK €):hv$�่�๙น~–๗ Q๖ฑ+2?7�M๓{f8F"ฉ๎กe‘ขๅตก๖ฑ๖|:FคHง3li5nกŽัตoƒ6^+`ภฝ „ะ{ํJฒญv^ฆฑิฑ .รhฬ_wqุ เJชlx๖ธU์‰”๋]รญีy~n0™bDา(ื-วI!hฅ3ปฆ# "วิQ{อ}วC’R‡�ล‰0ื�2NN‹๊=ีา่hc”$(ำIZ˜Ÿ‰NBKฯQ๖„Nิ๓ฌŽkฯฑX๖p๓�ฃ‘~šF`šœ~้F๘โ—Ÿเ เ�ัGรZมdฬุ๊5๐Gษ์ �ผหlล�ู4TŠ๐:,SUJะธŸŽะ3Œ9œŠใ�"uน\Z เ4 bm‹ฮ02ภ5•‰b mgQว@็4žล(5ˆvt ‘คฯรภ™๕ฬj็t�ฅ`žธ๓H< vJฎ-`ƒ$ห๎�ง* aฤ1e Ž›ฟใm-b์€ุ่}sด�ั#วp’ษคุุ๐ftdœlัf8}๚,�?ž#8ภ‘ไ�้xคษไไ r–Sโ!=aภ…ูy3๒สชNฏฮH+]๏อจญ‘ญ1ขฃ๎:”pฦRTณ๎54ใZaDjvg zu1��ืŽปƒZ๙“EถN•Œ’��[”3ตr�rแฯพ๒ฮฅe3 8อŽ;รม‹Y๎L‡/{ปัŒ'e-RC9#–9ศฒ”ึ-eq๗9']แีนง =2�=ฤมฒfVช lGWCุณท;๎›NXgืจ๘cศ4%?djอ IožF6V้j}พŽŸ๚มัT๊kŒ}eMOึุi8ฎใ%;๖›)ทG ๗@ฃ๎/ฯX1pฒo;<ŸA4Ž๕๊�์ฬ…๚๚๊ว๎8|ไฑ฿�์ฯ}Q๙.ิ?๕ใ�าฏG๙hirฑ๎ง&GF>๚๕/�งtmcS˜dดYูร๖Xย580f)‡ูeO-ษˆ๒ช+ฅฟJ35œุ่ พ6พšู}0า:Zร;�๙ฮ08p3Œ งcฌบZฆ” ‰๏‰.5ืR๔! G />๗<์๚–๐๓]t‰EตๅdCrwก“X(kqโKบฌJzAใHๅF‡๚รห/žC—์†w>�ฎ_�ฅO�ษG8‹ล:ขฟ์ { ฌงำฟ๖ฑ_ฎ?๕โ้žแแฑ{6ืฒฏt„ฤ�ฑŸัฎc3-E0ูM3ฺ๋•ี๒ชe‹พหš)ฐ ฺmํ‹kbgะ๒`ณd'/ุฏฤฆœŽดถผMฟI _Fc9 ‚Va6%ด-ส๛A~>GŸ)m†™�๑žดสฎvำณ#o]l๒LŸ&ฒ;๓iฒโŽ?$hvอ๙่k๐,า๗mhyšr,` 8ก=๑ฌสŽ๐๔ปLบJk{}ฏ`น:Rฆมฝถศ{Q7่�Z�Xคะหฮฑ�"^็zE๖M6ฐ`ฌaัึ ถ๙๒ซgFBปๆ�ฌ๓™ž/h๏Ey2ำฎ๑\๐—ธ~&C,ฅ๕็6 ถ?lYฯš>‹฿ืoq8าผดK่2?wQ‚๒Žทพ�f+๚`ขLๆjฏwœ8= ฐcูพ1LS6‰_Uใ;x฿‚hํxpaZั‰™๒=ฮBŽrVK`r€Lหs3| „Ÿๅ�r{œ‡็q†’ \˜ZXWฎ^ร.!‹$‰��๕xฦwฮ—~w” ˆkRิ ฌrหBข�ป‰A�{}*™!>ท๚@อ^ฏ.ฎ,๕ตูt๋4"Šฮฯ,:\ีผ‡๋ศSOท‹q+มุฆฟฤสเ%ฎ‰1เ๓JAิฝg{0hkพ))ฑk๗โยL(,ไก�Cy์ุว4†จ๋นญ!๖–X ำCY .งaึ@sปกœŠeศต†3‚\ฏ 6‚J฿ฺ้ ฝ๊a&l#7ณWฯฤฯซ„^น+Žฟ*ƒถผ%่€�UัภKฃ•ผ!ญ%[—ƒcPZ‚Lเหัœ ๊"“>๔ดvh�้”ใ1แ&Jkn๔๗GรฌŒ6อlP.@™ŒฮC ฏ๓bpD p4��Lน๒ฅใ?๓ฅsแฟgDืOg!๗U]1oฐ`ผžญ.ศLนx๙ๅฐงซ;Rlm,%u>•ค฿ๅ(fฉtไu,ง›ๆžt6อฺห๘ภ )d[K7 ”rf•ƒ}^N=๖L�นˆt้‚7๒๋�u@klผ฿Eฮ—ฆฯ“Cัฬฮ@ƒ&@ ใ9_žขแ:&CPž ุ‹๗nึญญ}O่์eะgyv†Lร�T๘ฺWจ7~Cnรถพ๘ฐ—Zilv์ุ๑pเุaสฎ’๙Ÿ‰ 'ŸฅBงƒsฅณŸa�+hฺๅฟe่ญยTaื๙พg แัy(k.23ๆน๏ ใ@–๑C›ฺณš�'yึ WŸ/#Œ cJ๘:มHบฺะQฺ่$�ิvถpฏ7o๔GGั…๒œ๊ส๔qฝ์ญเห๛"‚ˆ๒ayR๔š๘V์ร%z?ฤฺtรbฮฺ&zO†Aฉๅ'“ีMฏ_[Zx�>๙ฃwํm๚BG{ืใ?๚�G~๕ื็ฯฌกaํฃษ์ศk๖ฝฉ๛‡>๐฿ป4ฟ^e_้Ÿ<��ฎ๗ะuพ%R�_พp1 ัQ~œ๕š‘ตƒ3˜Jฤ  wS4ฒD�z�fฅ dๅž^jอ{๚x๖ช๐žฟ๗px๖ูงรุ๔WBษฆ™ฮ^tL }ธฒfุฯZ๏ฅ‰�›฿�ถp๚๙งF9[ฌ?[ง!ใ* v LกŒฐF์–6(ฐ4๔ฃ7€#f›9ed•ฅ‘[Z2=5^>�฿�ฤ‡๏๛า#ฟq๕]�ƒำœ5?๒ฟ๙ยYวภฬ–๗;฿|ฯษk7ไ์(ฏฎ8Œ.ํศ—”ึา5ฑ„B�Qส^๘_5�„‹รญ'wฑcl๒ำุ —OV&œFข]ฉวถฺณล k๙ซD7ีY3p๑|ษ(2K„ฑf†U:ผu2ๅqไร€v_ฯ>ฎษ:ขงฆ ‡;ฺดๆ�Ÿ~้Kแฉo<�ํ2uขŽเFยิ๘%|”\![‚'gำืภhSชส .ุgํ_Pfฑญ+7Pดๆ^ 8 ูlนAฟ๕ซ>‚มKqส†qๅ%;๘\ร ฦฒŸหฌทฅ>6idU`‡� sุั9b6ฃˆ� ฃฎ}7ณ,X3ฆ0@สศ~ปž๊O๕บ#๒bท{ู”ฌฑฉ๗๋ฆษฒณกพต&twทQ‡h๓P€t0qšI6๏SxๆZภมC๖SZูฎ^ฟฤtj๒นฅI€้|"PU๚3u†:"AŽ[ƒ๔๋A฿;๚xC๖เพบXภC[พม“/“1Gึ-จ��g˜ฃ๙ข๚W๊{Q•WŽฝ–}ํ ื]ฐฮบ"^nฑ๖Jp6ฐฐYธ/๔ญv ๘kฏƒ�M๖สคŠ๖ฤ �>G ษ“YพW‚.�`ฮP’ช?cฆVPx–๚์&ๅผW{o�™<๏฿อS๗์๋ฯ1ี;ฺR]™ZJ,7ha„s >eญao?๗JC-ฃ=๊"รj น2Qย"ะกCขƒูะ ‹N–พV๚Nฌ]ฑ–]V'๚ŸŸf‰›๊K9กม{”9ข|ฒ<ศ%ถšuึฏใฟ �šผฐฏั:%X +�qฤ๋ฅ.y>KP ฯ�o!หeปdคน'kฎ} LัวcลŽ„ ๘ฦ๒พi‹UUtG MŽ;ป‹�Hุ่ขย–zT?๛‡nŸฯ†วN=ž๎r" บข9ส—เGœlฤsช;ฅฤ๙ฝ]ฮ€เฆ{?šต•ญBo พุL‚gฮีึา_ฅšฝx็๖ฦึ�ž{๖‰‘๗พํ‹่ช��ิฉ?}๊ม฿ณสž@%|๕๕อฐE‰�fธ“oา{(ๆk�ๅ๗ฟ๋แหท†~0›L฿›ฎmAาQ‚ะC ฑฆšYU—ิ%wšตvv(๔+ึ�’ัยน๊ภุ่้_ฟ~ฺ�ฮจ@2› „๑ฺ;ธษะูiฝZ๏†4๓Cq๔,ph์?พฝฆ5�๚๕฿ๆยะ฿q|4ีdSpูc6 า๎9˜e(ิ ภฬ†ฺ๓&šฐ๕ํ�ฺŽ�ษ›i|รA/`ณ๎7‹ผ;ฒIึDื6๛lๅuฒ˜v2฿ SภdBJQาฌ๋]แu๗�Mญ๑d8�L\�e‚„ูน้๐โ๙็�ๆjšั-G9ห€Oš–‡�y๒.Ž๛ฯ=ฦ=Rฏ‹์ึแ,f‘มโT ไ9p ‡—-ะกๆ‡ศš%>…@G‹iต:\)dฮฬWฎxŸภŒ๋`ำ7๕ฆcLฃ“ฮ๙ญDG5ิัเnblœŒใdTU–X›นแะ๒๖ร่ํํๅ^ศ๊ฒ>fœ ฬr˜AuJ๐ด•k๗ฮต”2บเ’`ฯํcถHG7eฌฅtnื์�_š*ถื—ฟdb๖๖_๏_พ๓Žƒ<�๛™‹O๑้kฏ๗สw‰d�W^่—๔ๅgN�ฝ฿�๔‡F‡ฆYรฝ‡า#wม�ธ๓๗i66Kcดšp฿ƒ฿บ&zร้N‡…ณ 1{›@ a๑\8สfัถwษยhz่]๏ ฝ๕ํศ|J๓๘+=G^ไ9ี-EฐL]่Ÿ�็ม3jอ์ุo|๓›cFะเ8A3ฯuึภ( ช~๗ ฝ…Pว�ชDวิcsl fฯ ›ภnจgะ-ํ�”ภ\บ๓ิื�์M�#€ƒŸdI�ซฬืๅๅWš�|๔่ปf็ๆ�W’)ฟ?C4dณBiฺ๋ž-o�EO[ฒ–L๔œช{jVาุ-หTJะ#5M ศ#ูO@<›*–ู˜)ฮqฆMฬฉ wธๆc‚-รhไ3ŠTbcึFPบ‚ นž๋ด656ี†)Jิฺ๘S?บ)oZ็,]<๓"ฒ” 7ฮ]%(ฆ๏AS g3ฟบn _‰:ัยอ”)ทก]ˆŽRN=฿@เQz4C๊JฯN”Cพ[ฮxM฿“#€ดdB๖a;TŽP?ฑ๑ฌฟ#€fยก�s๘๐1dœ1Ž—ฏลLท๋eRขทท/\บt@}Ž}งQ^�jV�๘�๔›“Sคsวฬ<๋ฆm๔<:ฉD;j–z‘RŒy๚ฑ$mุฌ�$p/Cื๛„Jซซห`ตtแ›”3พv:ตd+bƒ9Ÿฑ๛๗ยYXdVํๅ21=AIUq‚rบบ;ƒ d‚F’–hศฌฬา@ฐ�๚�‘qึu$๘’N-ห!อ:ษ„(f€ู+�ญ=๘W7ชŸ]gu’๔}��ŸY[ๅb5?Šฯ1๖ู9U่^ฏณDg��Œน�‡=?ถixhฉ@ส๗๓�๋$kมฦดาืซjศpŠฤ,7็4ลด›Œ๔}ึ@ะFbƒd t'|:@๛ึfภ๕FXP$wb Jปไs-ฮำH–ณz่Ž;b@ซOฐ –.ิ„C๛;๐s Pอึป็Uก—^Kสำ kl@ฏŸjฟK<ฟmŒjll๏ [4\–)เธfฑ m๙.ณ}Y๚H‚k‚f๊”%ญ�”3อR5uG% ๛N๖4…ฮUฦฆฆ—่‡ลZ ณา€฿-อL4ยO2ฮqŸ‚-idฃๆ•็ศR^ๅฮ๋{Fฅ{่่๋aS�ท2TœภzVPงะ๕•$A฿๔c<ใ2+ถธ&ท C฿L™ ์€3ฎ<๐QL๒๙l‚~๎mเ`@* ๛c€mv‰eb%\ฬQ�^Sฆ‡v;K&ัbอ,Eถค‘r(ฮ‘ฃ)mlmขยe33ษšะๆ“=ท–`าฐ)7ฺฒ9ฦ๕^ป�ญJlFK๕kzl ฐJ๐�ถ็†ดxFžŠ�ใณs.ฃ“ญœ๋ pูชร์ศ5๔"ถŽท็๘ฯ๖ถอช๕฿่ณƒ^ผ1ถ“Œ� S364%�แ2&ศิTฅ๊O‘ฅงyŒ”8�@dตhCLฒฅ่oโ(xม/GHkS�\Cuห*RLtอษ—U๗!ใ}๋K๋o๛๙๙ณ—>ี๔ห}๒ใ�ร�“O†‡ฑ^๑ศ๚8ฏพ�ๆWเUเเ�cอฯž-คG_�ล๎‡๎8๑!\ฉ๏ฏnmฯH�]ƒ^˜“ฮh6_gt—ls _๕๊Dาอธฦ '!IŸฮOThอda๏ป�~(�๘GNวŒบ�=4`# Pยl*uyหl4ACYืN€†�๋WAฦงQ@ซ๛…0ฑH†œZ๑ NJว{ั ,ึ%ฃ1"i%(ม๊:บ๑ฃศ บ +hRใl๖$สo+jฬ”Aป od๐ XพลWŸํภ@บำ#ฯ้�<65D)Žซ/ƒ ศh วKcพอตD‚K1๒v—Z)์๏–ภ[ฏYยz้,๘" ค ฦ(=ืษระhพํัoI๛โzIœฎฮ.hย�ะPก๘ัl2ƒ#+ณค ะh:โ:[e &๙r�tlึน฿$Š4–žMฑถ�5XY$ปฬฝ•ใ„*�nQฆ U๒>Qp๋ืZ:qr”=L"< 2hฝ ฦษ็5KWN fะ้‹ šๆ6บ` o\๙^ป๏วr =lึฎ��ฝbึ‹ฉ7 ะCZปJธ– ง„™ฯWืQ‡�lจkcํพ†Qง“ํแ{6n�ฅแS-}šOถู๖z{x์๑ฏค๎†žž6ฮ๗ƒ|ŒŽั�cค}*}P1ืืupนฎภ€น\ษ=๗g๑ลcdXCG59*s+EY๒R‰ƒVA&ี}๗�j,cถƒg’แ™ฌขพิ๑—•”�xฆฺ™ตพ@น)ฒซีฌ‰ฝlฎ่Z�Oกœ~-8ร$vUƒq�`UyCx�ฯห.~�l๏;ๆœวย+Tb\o~W็ว.ื8_๋q8Iึค*น™Wว*บGฦญfŽช *ืWgใ9ัูสm rP‡ณoY)GฟA7D^\Ÿ๓็้ซ243+ิ๕ิ—i’ทภ๘ึถ๐ภ�o Gใ�vรศญajน[pfu๊6 J พ=Wต1™24t๏^!ˆ’ล27˜€ฌึู�b�๛R@/ูธQนๆ-\๐ Q}ู ภถLฏ]ม�ทAฮ"ู�ู…‹แาๅKั‰[เh‡m%•HัsuS'tร๑,ฺ“ก๖R%ด[ƒHA†l[[5๔๐@ E‡’kม%ึ�๑7ฌญ‰CCธุ%� ”๕1;ตu3ม}:’@ญคค.Wทบ8๕พ‘๑ษw�ศไนพž๓kศ�Wy��kฬฯ8-ฟ๖หŸ�W“ฃใ๏้=ดŸsฒำ์ะ=iไูMพdpฃbฒˆm�;�C๒�ล(หh7t2แvฦ๕4pฎiจ ๛Ž‚ C็r‚†gŠ>9งฑ่aิ—๋l=ถ/uจฏ�็ย“แ๓+Ÿืฎ^ๅ>๖…ฬ๑cแ�‹gศ~A{F^8œ�วฦZมX™!3ย=ฏฝ ‰พ8œfwรเ`L,6,Kภต๏ภATnIๅox�‹Ÿiเื‰$�หื#P๋ึ��'๗ผ�uGฟmvjแ{ส+[๎ฉ๋่N$)ฐัZคaใ�ซo<Yiืˆ2,dฉš"Rรcู 8อYะ5ซ˜Gืย†Jจญs�ื‘šmrHณgu˜ซีศฆ๖FŸ4‚›\=…ำ๔๘ฑO‰Y็กก!X“Pๅฏ3ม†๓I0๑ ๒Ÿ#tœญม[^=:ฃชZVA$ŸWสžนฏ‚ –#YBวทB ะYY�%่6๋อŽ๑พb&<อูX+๎Wˆณ7‰ ะ |m^้นwดii๗ jเƒ5 M]ีแ5w���ฮw”ทย.:พ�g_Fwโ๘Oญ†—^z)ŒŒจGห"๕Zสผ#wIlVๅž5็DDๆฟ Vง&f9 ฺŒb0u/`ผ œเ…@ฦ* 7็ืๆCswS8rˆ~๔pจk๐เ�&๑}n�์Gšด๗i@\zuvฦตฏ…็t™รฐaบ๗์กIt บvY„’Ž�Y†ฅ3ฟ1C@ๅหคๅ๊ ํœบิ้0l๋‹ ๑3ืั— €Œงม=ฯaฟ�‰™rงฺ๘ฏ๔pa83fยญ�.ฐ?›Œ๚~๕uk�‚%|xŽธญ–€l+zN’šฏอUH“ข�|b)`ŽT๏JYjftํ๛TBo�”ฆึu๏พ�๐บ๛}�ํ่;AะฬOqฎ(%™c0ŒFBV฿{aหR&•ุฏ ๋Pำ}เŒlPŸ‚ๅR๖9ฑ#๛1ญw•4โอ@o/…E(๐‘ฌH๊ส์ะ฿‡QŸ”S oฺ06_Žฦศ0ฝ่/๑ๆd�๛จ ๖‘c7W&1์๘ศุโส�๔๋6ูณRสไM,p^vv–u-Y#@]|G+สo\gB .A์}=๖L{n’ฉ"ฯศmlซฅ๚mฌj๔ฝ,=Cฒหธ฿๋เ[jชŽs฿ํงc"gGฐ9•=“)ˆฤฎ `ฅewHะ”žีœ‰โD' iฯwะk^O}iูช,’ดq�ฃ2RA‹(ป๖|p ŽU’:ึฅ๋lx6A•-ษ@("ื€&vฬชeƒL;ว�้ดeจA๕CืษDš๓\(P>w‡iGขๅ˜ะ8cX&ฦG@วโL๛&ัศ|@ู๋ศป_๎‹,ม๐+!S\›,L“ลนั๘>kญ”ัฒอ~‹ศWด๚๏b�"e›bm,E๙`%โ{ เa hศโ๗๙œbcIึ•}x-7ˆ0จิ˜ XCฌcธ ]j�F๖ShU<;1ฮ^ัฤh~•`o”q›k8”;์‡Yw2ึeศฐฌ"้๒แ18่‘M“ฏgฝ$ฟ์RB#›๐ะพ=ฌ)ศ<ูsษ ๛๖ˆM฿ึ่๔\ยบ•บ/d@ดสˆFุ๛4ศ0sอลต๔{๑๐qŸe2ก อ(๛พุ์ ‡fqi6��๗šuิัR4Vฆ0ฆ :svHทnด ๐อ๋hไ๘sๅษเฃŠZV3hึฬšั9|่œเแ"Lƒ'{ =AึGั}๔ๅ�+ ๎O์แ�หว๑คย๑oา“ทrLX(–aXƒ๋ณ‘ฅขณ3ˆ72Šัๆฆ�พ#ถ._x)๔๎k วชL๊H3Vถ…ภ็�ƒ/{ @จg%ฑOสิ่xขf๛IไŸQZŒ�ฬ$+ษVM๓ฌ Jฅ:i๐6ฤ�,วX๗@ส�.์„H3�ฏSVbๆ$ำ@ฆ„™ฬฮทYšจ^9ฝ%qธŽ๔lƒ�%š�ญ๙2เpาEšฝy‹฿%#ว^่๘ล’0ฎ!๛b`h0~Oะแศแ#1š%{–%จถs๛ฅ^‹ะษอ–ศ๖I& ฉใGฦ๒ศSบ{ €ฮบY$ฯฃใl=ผŸ@ ณน€H5ี๛๘ฬ|&฿~ห•›ื๎~๘กื�๛งžzไ—�๘ฦ๏š›๚�๓๋?๗ฃวิ>1:xใกw฿PะC*KOJคด `J{]ๅ�R�_\n pฏˆ-bขพ$�กK=Oอy] -”–?q’ภLZชc-‹}์nฎง ๐)_พด๑ฅใ*จ0ดัp๋แ๏�n—ื„ฯ|๚้ป๘ศ๑10rฯํ„พ†~kพ๋xFฝ’ณแc 9บฦbญ��๕ซ/`WU–ฝ…C�_พyค|้G�๑ษฯ}�๓ฟูะึvo็ัฃุRณฝฤฌืSูุึF๕,ย&็ฯp‹็7่ˆบ'^‘M ๓ >ี ่้mุMึ+…\y>หั๋U‚r(DuœๅILณre\S'ึ23ฉิีศๅ�๗�ล�yF‚ๅ‘�ษ๚มZ=๕ฬ7eฃัืˆi2ํอั^o่$kmœJF@›e:ธ:ะ์w>(๛pญ�{,˜8๐ๅู‘ฝฃฌน?๓๊0ม K ิำ๊~€sŽNGGiuืฝBษ†ƒ‡๛ุฃ&�Œr|xวท~k่ภงXฤ#3�๔๛แ™gŸ 4าญ€™!Hัััฮ^ไๅศŠ3�? ภZ์˜t*‹๎ฑ๗e ๋งmเhWUชฑ4’,โ:vำ^Y$4�˜oฑฆŽ๖ผ๊:2R_g‡ตTฐL$ั)�<๖‡2bY“bฝฒBะŒ *>๛2๗n0เุNz•-ฬ…ทพ�ะ ๐�ยใ_aMfยq๔R]S_<e–vส4[‹L•ภv*Ciฉ ^dม๓Zd๐LI ป+$jใ�ู47ม๚แœ๓ี�ๅฝŒa฿ขา๔ไ8=r๚aE�u๔„Bํ6ฅL ผ?;ๅนB;ฃcYg€(๕Ž=[๔‹�{‘e*ะYLšศUkŸะ!›€“›€โ๖แpิ#ั็๔~8งั�I|๙ำXF‹�dhา่ใ[}“ใใ��OไJkk�gO๚ร?|๐ม๏^Bozค_}� ญšเีืํภ@–�๊ว~�เ#�…Odทท฿]]฿–จภ๙_G d9ิœ34w %^$สจ˜ัฉฺโ@ญฃธ2ิm�`MดดถAc�>E”;Vr;ช[๗“@๑ qhจadrwาะๅWŽใWbYB๚ถw�=ŒEIVMจ †ภ์๔?A ˜qช—Pฎ:Mป็ooฌSAPซฑฎ"{%ชํg`แ0F ฟ ijฃ๋ิ‚l๖ฉ\E 8 †R(r4u|พh 6 เUพ_ฅŽ๚��—ฏ„วŸ~ 9leˆ๎R์ZปMณธG’`งŠ� ้4”1ทส,ฃPภ9ึฐซL"jฮ5cMŠืฆ)K"1Cเ๚ฒ๎%D จœ/”1๊*EPฌCฃSŸLƒ\ฟฏา0๑šRWน๏gPf"ึhช่เฺˆฯ:Bซt)›แ†F‡@ฅ่L่๕]ŽuŠNet@pv๒ลLTž๛!.ร9๐ืtช 8‰6b2#ฏƒ`๗}B™u^^˜%;2หบใ�ย8ุPA๒�"ฮ็ัi%๛…3จCตฝMp)‰ƒXื}0”ั๓ ;=HŸ˜ %+ํmh๋ก๓;ื$˜—%3@ฌฉ5d๎‘ภฬ้|f5uอล๛ๅiใWฟp�:[ลๆH> ฌ๔�]ฉk�ฏ#ฉHว๒ะ+•&จซŠก[€ sŒศฃqฯ @ึๅSผGgื •€ƒ�หCษ“ž* ;Yณv๋ิีบM้2dY้้ํฤBUgไ“Z้*\…ผ“ เ+ถ1Mญ ฿8๖<{416ฒ j๒8:™์ฯษZโg1Nส|Fฯ›๗ษ๗™a6sฃƒเฺศN๑๙ญนืpy็ษzอ‡9ฮ๛ลปฆืจนgํ'กƒžไ:ฒ ถึ`_เ,บฆ5u:+ะfq,tจ!ๅฯฮ๓ช?ฮ�๒็pƒ๕ๆ~•)‘>‡FTฏถœต0R��/›1m๓Y‘‰2ˆ5ธ0่‰|�d€‘E&j่)ฒ‘-ฒu”g+/ฮM„ž{ ง†ฎฬ๛Fง[Pd‚เh‡jwwOh๋ขY>gt/ฮอ‡ฑัั024ŠณNŸุNผ๗ยน=l@IDAT3g)A"ภfฑ6p 2€ฅijเ]„%Hผึ7ยฆ์A3T๏:€3ๅu“,0>ฯ…ร‡ณoๆั,F)™bG‚,…6P—[จ$ภ’%๓#[วนๅNipœ”บwe~%L–2มee“๚ู…Xรmk๕ํ=wฟ.LฬN…ซืฎภVŠ:qPœsหฒ่I‚Jึ‘E‡.ิ6ฐ’ฎฃเŒ8WUผต'JสธภP SfUs!xChํฬ์�‡ๅ�z๏้S_๚gฏ{๓ปงธ@|}๔ฃซ๐žำO|�=�}ร‘วฉGnŠ จ ืWYŸFึf &ืิิ ‚p๔_%ฌšb'k'eP–„ cKๆe�apํ็v…ัŸQท๒ฬvxwฒŽ/uง}‹–ช;xŽๅELข฿ขฝ&(“bฉข๗ฎ-œัVว ‘5ต฿”๗*จ้๚�yM<ื.ลWšœ“MฮENสX[ —,,๛เ^uิ๋?OเนƒŒ;>s‡> 3ุšf~n๓ฤ*@E๚Xุ�‰D๘+Ÿท‚Lิำ฿มฦ›šขežป ‚-”มศชฃ‘mเ›vฤ&˜ฑ/A=งณถh๚ศf‰ิzํ ถ!ทฑrหศ0�U2ฎ๘n€๖ต๘"ๅNฟโ>ึ–fะท๋�ศb,ร๏ฌNแหสŒƒภ3mม>หrfิฒV๔‹ผŽe›์้&Aค!๒.=<;ฬ)jใeWุเฺพP ยโDdda&žY`u0Kj9ถ`๋ฌแ‡--NDฃO <ฅญW‘h`Iy~์ ฯห9‘ูถปDศตมg‘ษ‡๏kะš่โZ๑lฐ็I๎Cๆj’๓d‰‚\ฏ�ฃ˜ๆ฿๚0yd:2t‘)ฯd อ@Œvภึno"sๅศฎ๒๏”q> ๔๐w”Cืฒ4๚8\๓,ำฅ ถ‚V:&๔~n‰ˆeณ›$8ิ ๎ฉ‰’uO0สฒ”g$ะJฯaZึ vŸ๛๚ัฏ…Zุ�๔Ž’ตก�าcต ฉ:ฐ‚‰[ฅ\ณฌช=”TA๎‚e% …Mแเ*ทฟ0ึG.�๐พ�ปu.Bi๗q~ๆgฃุใWึ ”๕o„ื0IณTึญ )‡ฮ฿ภ์N๗ภ4ฦณv๊้่rqG‘๙ลน–‰-๐b)ฏ`œ :-SIW”bณธพ~S=~‚e"ฒ9ด๕ั,3ิพ:ลC�ภ—ภ‚ๅืฎนฝสิ9U•u5๘ง๗-/ฏ฿๓หฟ๐฿�o๑S_๛ศ‡~์k?�o�ํฮ๕Ÿ�›x‘W�๓ืฒ„ฌฏพ\{�ภwพํ�็ฯž�‰๚–ŽฃตMdสศ~เผHCึฅi " ฝMฦCใ.‚m“ŠษfSR(+0Pi(จลฐW…&”ๅญ[a ฟๅˆsฤกKฺ™็ำfIfŒ=\ฃใŒูรH๊ีXŸu์@/œ(‘—ฃ3"=ีๆ46ฎฑ��1‰๛ฺรู[ฃ|Ÿ –ูภvMฎค‰aๅู\๚ˆ3$z฿c!โ˜‚� ชํ˜ลฺfฦkqr„`คŠฒ”ŽA ฯ‰ืƒ` ีใน์๎สอฦ็�@ษœฟz-|�OพN?w‹5 @นlฑ•็S2xbYสŒ†5ฮอ่่า†ฌํ†๗ฝ๏ฝแษวŸ /ฟ๔2๋ฬŒyz$xlฌษ3pถใธc+1จŽ�๓�šM28 ัฝฏ ;9)"๛รฌ„FMGR ๒@ณฎ<8XFMฝU €€…r ึ7ฯบ๙น๕์฿๛ช577R^ิฮUX~/ึ ำl๋เมCิš๕‡ืฯู]{YT้t๛ 8ธe(ฬUdทG'มŒัณ๕L๗�_>รฤt๋ Yssgซ™ฐ,าoญY�Z‡Fพฐ8วd๔,เŠQN’Nึ๖กลVิญU}รŽถ–๐�๏�~ฒyœXhญumแ๑ฏ>้G"vศ ๋ๅนF<๘Z Z_๙aQดXoดืงมgbzv<ฬ0ฆฑ�]ร9pเ€๚W…Y๔ห*๋%#ฅฆฉYf_qฐuŒ๋ษ;iCเัnๅทn\ฺ:“�๐e๓t^)�‡฿๛๚๗^ฟ|ใ{๒%%›ู�;จ๋ซฅœG6’™gป�gp’s�ป์ว�Iผ๗š[<ห–ฺษภVั'วšrฯญg!ทlAšหขGJaฅ!IผG ”Ÿ๙๐�ฎ6Ggถ’s/่ฑฟฏ๓M๓M@9ฃฉ๙iœbบฺฃำ[๛๖QJ๔<เ่t่ฟu3ด@้.`gfGงยๆ`ฑa"ž/> ๎‹–ษŒข ~ฬฯe๐>ไX:ฺ&๎ืเื�=หทวฤ� Šฅ#2]ฐr~฿ฉB๊๓R๖„ƒŠzภ–jฒฮฎ�yุDcงn ข๓๒f‹mฐ�ื��๗๐wD�W[ู>๓{ž}ๆY.‘œšใ3฿้[ม�ฌo๚\�'๖ย5�ฤฟศณ�๊.iุRณหหัฑG๖sTฐไจF#*Œณl/‚Fw�ุฤxqu.|Kืฝœ%@$ภˆJžื r๕ฎ‡•dข–ฏ่Qูœ6;žฅŸ~‚๊ึ);‚๚G‚w–๎฿KูC�`x๙า5พgSNม๚์9�˜;�žTjA3ฟE€ ล๛"qฑ0มญxุฯ‡ูh๖p“ฯŠ฿ุ"‹ฎMิฌ„ัฒฦฝ า��ถ�ฮ—t๙–ศญ�€ฎม2=J๐ทa&js.ดL‰�ˆgmjย�1ปกถภ f›๛ู…‰RŠžดดอgชดศ๑์๖\ฐเ๐Iย`C์kž าฒฒRJภะทนe€tŒ฿kอฟฃ๙"pฮๆT0ฦYv•‰๕์ ‰}#๗z;A?์–cJ๕;ฌ3ฅฅ่ๅน๔ฒR\™(ฎฉษ)jึV ๒cาEฏ์ HqlaาถD9ฮเๅg็่ฏPเ๊h๔ปธ2JใW๔3gkQ� Icvy–@ุ mํอ”ฌLr ๐<สต28ถ8๖oุ†FPู0cI~ฌำkฉŒiN๖๗ม1h€5X…^–ๅ!๓M-€(=^†œภ€v7Ep๋3F›=ั—๔์ ˆxฦจ๙ฅฟV1ัเ" �กœฑ}ลฤ_ ืIโFภ‚฿๑l๋wสฌ�@?:แศ๛อlq6ืWนํฃฟƒฝๆ��วš�๗Wฬ๗ํํ ี่โล€}t�az’ฝ� oA�Qง€A)€Ž๖4‘ฎุ™ ปุตJฤศ�Ž�Tิ‡L๛‘xธi๖ŒŸญฃทโ{ั5œP…&8S4k•™“œ›ง*Žž<ม๚›7G(KฆtPหฤ=`ั๚9l„ถปูXโ๙, 6บป€wE๐09W<3�I @sณ„‘อ์my‰‰"๖i{‹ุร=a”้Zภ#™ฦ;์ฉQ5๚��TM‘Dz@�ม๓/œ๙เทฝ�-�ฬฯ|ไ?�๑ŸฟŒฝร(ฟ๚๚๋Z$๋๏๖‹รš๚์/���7ฟ๋'ึsน๏ซnํศค ฐ6Q�ˆn4ฌล3ื6š@แ˜\ลอใภ&pธu์€lว๑27m- €๘�าฦ'้L๎ธนJ'– @ฑŠh& �ฬ๕]ฅP08‰ํ��uฒdฎQบ_๛โŸ„{x+ฦยŒY๏�พpux’.ฝ&๚Hฉ7ร้ก\ลkเDk‡๛๛q˜[Cgkด๛๗ฃ!ก หศ�Mฑn.;r๚” 43z—g4จ6ภ�F้– เfณ๙p๊๙—ยเ4ม(Tศmz>d1„Rw+ํ๚Ž๒ิษ)าcQx‡ี2v(vfญ๋f–b™†Qฎ…ฝ 4jvลฮฒ~›86=3K!.Kb›๏ซlถaz˜แ•�ๅหlLคขtl #Zํฬc:Œตฦ_ ๚ttžcG`พ–ดIำu?อ์`Oฃรgภฐ๐9|vNภƒ฿‹Ž๏ป`?อข“E๑ตำต ฿สNิ๓t‰๎"3ฅ1_ฆT  pฦzpฝ,ˆ5(—…Wce@EนEcDQZร ุlภX ั–๛3๔‹p์ั”ภ๘ป�ฒช“€~฿Œฮอ2†�JฅRึp�›้ ˆxว :ŽZ]GOœ–!ˆ#�d{qŠ-ฝxž• ๖iนาž?�2”ษ•p��ๆฬSƒธ†’'`o"Rีณ7์�ฯจFฆqœ}๑Bซmๆ>ู�2œึ0สฯวy)รี)ฐ[ดูิพ>Œ/3ภ\›$5S แ๓ฮออ!ปฝัpุ4hŒfœ�8ฑ'ร๙—N“ŸGdšเไ‘ฉ4๘๔ฯ–4kniฮค”7›ฯiˆผฎS<œ`=Nฒแ:ธ๗2 ”MwฉŒสŽ๐mt�slญ�’๛วgศ๔1ˆืษkˆtื ็TYhวัศรฮ๐.ผฬ๚&cถnูั๑Pถผ�ํR{~ฐeัมFp�20ฺฃAŽู<œjGt™�ZกYคู?‘w\•ฝุJ๎…๓oฦuOOo,ซP6•็K—/๒น”ำภฆ23ช^Sฎ /ž;Yฝ€9ไภ ๚z�ีุอ�๘‘“แD†ำฅฒฌต?๚lพ9ˆlีฬs8<�N๓:๚งขb%žห,Y&ฯถฅlX็๘D๏G–็อ,�ŽพHt:|d‡,ง`�Eฏไ๙]ฉช๖iข฿‚็Ÿ%รั•)Cวr๖dy€TOฬอR๛‰ผ! 9ว&9{e0vb ซC)(ชฆ�‚"oฉE–u4›-ฤ ลŽๅ##Cฑฑm,calžๆล]bMd4’JZ™Y๚�ว?”�า#ฟ๛กwื?Bษ6o๎&R+๋;พƒย่ามมะน—& LกQ8 F6 ›ฉ่nณป๗z%��F”#ู.ปผOูT.m`g“ธพๅ <๋J8๛�ู๐์ำO‡าzz๐พ๘6�้�๙๏�/�ฟวZR)ย‹kกิˆวย4๗2๚�ุžH็nฌgŒ��ฮ8‘cl๎๗@+xส~mr.n�ผŽ=iŒฮฃT|.`�€<ๆรมcw…—ฮtพๅ�;?ฑธ ฉzcฝมIš/ึิภฌhn้aiไ‰ฉษใ„C๋"5_มvฐงœiื๙ฦD›โ็ซใ lจ้$๕ฝ็yyลฌ'ม$บาฝทแญ๕ศfโ;`ยุฟ?ล+”มUธ \ปr•~%‹2—`็tP‚sํV์W ณd/Žด=zaุ อ๛t๔›๗ๅูตนหฯ๗X†,k{,›+QRลŒบˆg๕vท๕�๖+‚่xmฯฅ น/Wฏมๅขn1‰a๐*™บYhฬe่ณm‚�uXn5ตๅ4ฤ�Žํ?ภุุพp*ปK c6oค<ใฆ€ฬ’1Gพใ๑ ‹๔3ฉภถgนฯ“%\)Jถ�R^d ๙พ๗^€ๅSษVŸrูbLเWส๚l๙๏ู ิ{“€ฟ]๛บ~ถC`อ& ‹o๕฿$‘Bา็๑Yํ"€ะŽ< h๋=๋kรŒ%ะR'จิB์qฃ~>|p?๛ฟCv๚ฬ%ภ6GRr=AฟM|–›}ยwA๙;แ"า๚อ „๎bซ๙A”“4๒bฃพุ!–อ˜5%Qภฎ๋ n6r.์บฒ—DืaซZฑ๑kฐ?Wฑฏ&ƒj๐ลด~fHa�ฃฟถJ2ดิขœต4ซบƒอ(ƒฎ_^Uฯฉ |%ๅX6 Œำ]xŸ๋(ณ„ฬพI”๒€อสรฐ‡QนSฑม�ี๑˜์˜ัXšแ=ฺ)= dmXhฮ Œ์ผ๔}~A�ญŸrXN…4ษŠ$ ล&ภฯ&gB]ไ๛”๗จ๓ุ�_ฎฉ็ห2วL(-"ุ๗ห๛Q†”๋,๚W‘L† ‚๚‰‘[๘Žษ€Bตuฌ Vl[ฦงฌฐ=|่WK†q.ฅ�1ตR?ฮณม]“�๑Yูlfฝ+kšFš‘uสyสR!~ƒฯตQนŒ๛Z”p?+ซ๖#3เ} ˜เ‹ใ�ง)a-ๅ๛‚๊26ป@ส๏ Nh๋๙Ed ]หuถ๘l›žZโชœ™Lp-ิEymšDกŒ_Ahืo—๗–,Q%€ฯ„�ย-’/œ.๖ฟศ�Žw \๙ร…D๊Dบ t#ฒLK !fาh๒DภจS"‰๘9† �Kเ=กญฑŽ]4ฯv๏๊๙ฬlฬใ”\ผ|eAณ€ูลRฎฝrf“hลbฝฟ™œ�]q”p;#ฮ๊uี��Vํž9h5Ÿ=?'ๅ ฤœ๛บqื0~'๑๘ใ4ฦมษˆจ&๋“#ํ[ค๚ะ(.(*๏_žgF2ŽƒY๖�gฯฎŠ*‡ุกi_็จ�‚QBมYโ`7๋‡ dส�ีแp๖ยujื1.ต๊R kb n™… ƒŽž๋ฃ‘’Q‘ ๆฬnฟ�—u}*าฌก$rีหd๘1ิk8ฐ�j I็ฤภญ8vQๅ฿:&*|1้_ผ�ขำฌC‡O`0eฆVวVziฑ>ซiภvQฮ: 7Rq‘m฿‹ ส+ช^ิ9f’t�A‘2๋ษิ�€KรPนญ อแi�บ5ัt=๓ภ"ป๐ถเTเธ๖า�e3hจ|NŸ'-|�า๔๚›€พก‰เr‘`}>�,’4cinฌงฯi�กkปาb,ใ๗๒nvห์/Qฬยƒx3+K(โคอ1HปUษาE๖P‹ OŠ๊T๔eจicsซa–ฟ �ย๙‰๏/จnค&๓@u8„Q๏Œช@๖ "i”C/\ุ808:54SฤEรมฒS7ฒญa% TŠl‹ภ8/ZgิN�GŽฅlค˜!]x<ฐŸ‡#%+ศzหtHท ฒ u๎!gฺยษปŽ…s็.…'Ÿ|šš๋ ~ฺNށa>––ูEƒ;Y+ ฃŒ�;Bg$:๙สผFีGรh‚ฏ่ผล๚;žว^yไธDA`ฯ8tัวฐPืิuGกc€ศฆuหะฝgฦ็ร็�ใ—p0คG+Oธ |–์` $ฯ�ึ";œO๊�:ฺขฎXžœญNโ9%˜ฯTg๎Qค฿J็ฒ„ฎีๅWŒบgta7ูฝชVธOfkhŽzํฦUœ=22€›P–ทโ์ๆ�š๋šจนๅL๓ฟ%ฒd0dH{๑๙ะ�ป๛ษ…=•>8'wฟๆตแw��งp๚iส†Sฝ ��ฯŠsเqธVpb62ทอžsn’tษ_a&t-Œ*ๅ–'0‚‚ร•Š.์ฐž[#ซแศ:ูDจใ˜qอาธหฐซyฒžัiEGศ+3fอ0O�ณล™ytAXK+ูเ•0Cฝภบห†ฺb28๘u๕œ}ฮO[{ูญ!dว}Œวอ๙ผไ๓]็uึฉฦฒ3ึอ๑~ฆŽd,] เั‘Mำ็ฅ–FŸSร�฿๓‘}8|๘ƒ?๘Ÿ�?9uุ่ฑ๓ฃฃS+˜€ฆF‚XลG‡M=63=K07ห"ชนพใพ6ฬ๘rFRๆ์๘=‚Dmหฯ�ด3ใ�w(็ƒใŒีmi ๓c5งŽ๗ธฎ�Qถิพ�๛_|ฉdฒ์›e๊ขำ/\ จส‡“w๎'Žฝื๚รู๓ทPบฺ0๔_E็ึ(4ทฟ–€ำFœซศื(g 2#0ิ€�๔D๙๒j๎{V7n†$อ%ซ™T.]– 5‹N€-โb˜ัB1ธ`ษฝ�h›œpเlp฿%dขญฉ‘๒?jฏั'๊dศ>ภKn0,šช็ฑu6 mdOป่ัุะฦฮำ0๒2‹฿ˆlฮ„งN}๗เ[ใ่ึ่ผ๒y6พฌ เY†uแ8ตฅ้aจิP๛3ุณ‘ฺˆvu‡Lฆ ฮ™ฎมถใRWะฏ๕Œื“]g`์šง` ฉ_"ศ…ฮw?™"ึทXฤึYฆง^ธ“์ž#5_<}>สษ:q‡?‡m00ฎBgUีV๐,4alฉ๖ฆ ›�ฺป๏ฆ๏๋‚ž]กทม{$ใp`D†�'S67^๘ฦ t/—๕จMH%Pท™ใ€›ฝ’6 �า”๋J@V™๘ส“vEื^�ฆœ B๛,‘มsฉ๓<r<4ื\ภ฿จอ-ศำฦฦBู๙V์รl%{ษ4Qviณศ%dYฆู.}\HHa๘ะV๎ธnศซถw 8มแนY๊๊9๛ ิ„G๚8๗#:‰]๓�k๐o์คฏ�๗ฬๆืp๖ร‰P(I>์›Aฆ{b"'fาอ๚šะ@ท ตjึ5ทื‡�ญ่ษ๊๘=‰๚ไ�Kํ\O y ส{>มBlุุ้D” ๗Y0ข„ภ}=้ลคˆ@ี๓ัฃ=ม$’๘ูโ<™dd]ฟคุ4NFพŠำq๘�d”P†h ๒ษ�šd๐iะื๋fY6Šวฤ�เ ฯW อt)ืซ-+Nw๑œ่หฅˆœณ ™!‰gcGง˜ดณ™ซึw“l?V1‚<@ธz๕Vบ สฑ฿ฯ�๏ฦ&ฦ�$(V˜ศ5อ^’ธฤo*i๊แ652�ฏ_ใส H4ฌพ จc+๕a๙F�?ู*bˆe๔šŒ๔=ŒีUJณะัสไŒ ีณภ€ฌžc›ฏiไRญP|buๅล’ืn}a\$๘ฟ@_Fฏ ฏ๗๖๔ะฌ3ACฦkaš๓฿{ะr}c๗P}พ 3ู8VฯฉฝDHbย‘๕“‘•eMlยM๚N€ฐ๖งฯ|เํ��tcK๓z๔ัG{่ก‡fั_.ฤซฏฟ‚๘; |๔ฃ…ฤป๎�Z็{x่ใ3ำใ๏ฏkฎหฤฆ};Œฮแ/ƒ7@ำธฌ :ว,ฒHIอ˜ํKƒภๅ8ฌ6ำiii"{VNžธ+fa—ษv Œ  ฅฒDsD„�Q6–)H‡•ชไก2 ถสฌ—‡ั๎ศ้�ฉ1โ*นบถฒy/„Fa[ื>*}8l6อ+ลP,-ฬ†jƒ[ํู™i6sxQP6eิYZš‹_�o๖�;X๏๔บ๏{n๏ฝW�เข/ฐXlg'—aL[N$ูNbฯุJไ8.JฬI4๑h&t&ถOB'ฮถ%R"Y‰b•ธไrX.vป่ธธฝ๗��›ฯ็ผ„f2ว๑ไ/I๛’w/๎ฝo๙�ž็<ง|ฯ๗œSQำH–\๚"์(ค๙ห้�ๅ+ฉๆ๔eŒฦq ๖†<:V๓นrม€ตฝœ42>พ๙๏ฆทฎ�…~ฟG@ศ4 ฤ™Ld`…L โ๔x˜ๅ.�ผ— q‡Hว)ฎ]”ีฬ ?‡FzvŠฯึ๕ dšyฐ›๘8ุfpสธgxU�๊TฝวO ]๔4๏eฃ<)ญ‚Rึ0^”‘ั&P*€^‰ช ฅใhน#จฺ]ตฅ๔๒ ฬ‘Jึฝ”เ๏1rู_(Q~žN“ฦ`ห z8;ฒLvQž"ฮึอฉD๓dm๐‰ูZัี˜{�}ผ/Œq]ญcฅrT๎XQ�`ฦฤ/d. ผ’c�8คะkŒ|ฝu&:Bh๗�G F˜3wฒTถšpมiน!\ฦ๊๒4๒ฝๆ™"ฮ–‚(7ำฐ.ยyรapy์๗TV�Nœเลีืฏฅแ ึแ žWฯWdษ Lอp—vฑNŽ/4[wภyศึดf3eมrแ\zฮฃdA๐€/ฏAzฃrโ�”DhmT 5‡™@�n3นZึ'๚Dp(ถYŸoใ[้ัรq^ตYำxฺ๋uุ�๑!Xกำญำ+@ #?“‰ฯๅณ:บบโ>ถษพ๘ปฝYxdืlJฦฆฃœำrhˆๅ8๓ �fkE ณsž%ุ=+งฯj#€�\h๊žm‚#ห‚|^Y|doY.ย_pดีŠe<่.K5 4”งร9ษแ๙ปุŠ]ฟ%,‡ผn† ฮf˜๗ฒsๆzL Žฒ๏0รh\jรIƒพดลฺYฦ• ชPพี_๊sY‡‚สฟ๏ษv�ฟkŸdภจGใ๊^*G–Rh+Gปฌ‰= (#|พ Ž,-D฿V51 Z{ooO๊;q](๘p%Qญ‹9ลอ๗฿ฃ๔Fธ– ๛71’ฮ=ม๖ม‹ 'ื๎“อcMmNkfำ�$–„Z๗.Cมr &@Gูt๖3ˆd{เu+/ส“ �2l``OmL8�,คฯณ๑q-็ภ†ข˜–H^ < ึ�ส{ณ& ๓‹4#ค€็Vึ‘:๛ุฑžิ๋า.๓2๎ ยถ๑น“S!Gฑฌ๗•ห|ณ1ฅkl—@oห\[^,A™\ŽITะภ{m#w‚R,"�g0M�์@ืฏrฮึิย$COœ8�Fเร{f6โ์๎๐y ๔ขฉ@ฦVURพ6 hต„ฮ]ฆฉoิxฃสx�ูงป่™v๖พุ�^‹˜ๅฐ ๑73NW h’…ฉŽ�ฝไค€‚bๆฑ.ซห$d."๙–›Eภฦ}ํS&‘c€ฮน28ื๖ไ๑Zuม.v"‡๚|“P๊]�Š๐3ธ*AกG.]w?ณŒๆุ2-�c�WJ้ฌŒD๛ (ฏ๊์"|@เ๔จ�™œค`y•๚Kฦ๋ีv๎0๑G…มซห\„.+ม^aงฺฺ�ำ๚ๅ@�ท๑yึ_ ฃ™�F๖2rยฬพๅžl\#�26๑๋6(๋แเuqSrฎโ+˜tดำงฬเ ์๑nYฆ‚2เ9ๆ�–ถVBท˜(ชา็๊v ^๏s„ 8๑KySŽ๙uศ•>โพMyEaP็ฌ�รDำu�<�๛ป'KŽ็หbะWณšเŽ๋[ฃY�็„ว{`Ÿ๒ฐa;่tใ„Pr{,TฺmQrPIษF็Eฯฤไ๗ฒ‘.?๗<:ง" <ภ๗คigMR;ุb ๖†:#d™‹R?= „ม๐'ร‰F฿๐tPP ธNใrฯ@ขวYie{*i#ม„�9Šธbx*5๏%ฆ™J##ƒบ4„E†ํ๏b๏} n/ไqƒXEฆ—๖X?j�[ ุใพ ๖™xq ๖(g�ยถแ+6เGZŠฆOฟว>a๚nH†ฐvE๘‡ฌ๚ลฒ!๕‘ใšeซUร๒–AตI<ฎAฝ+ ะา�ึยG� @ๅ—�ษ?๚ฏ_�ํ฿�อ_y๓อ7_~๑ลmค่–~๔๘�ฑJีŸฉวT&Sz�G็ส?๚ว�ํWWW็~บจฒค ฅอ๑ลัDh9\f€๕ฟ vX€Hป‚,*ญข5๘9แฌ!ำ] ฅR…:7ทŠ>#e&&`จ‚ผ–•ะภจŽL-‡pคUฅเ*�16ึุตตด…r”\…Sbร0ฮkฏพ–^y™์ €ฅฮฦๆ6@ ว'™%อ!;6Šฒ$ธ#๘*ฆT ๆ์b8 yO)ส๘d่ŒL8@ํmuฉƒ์หฉพ้‰+/ฤT€ฉฝ๒น/QU ล.๗1ณฝษ}~ุ?•พ๖?�ฏ้๚‡LฒCี๕–ชhZำ��Šz บจฅ:ัRU�+8"๓sิ\q฿6|2€ทyRฮˆJ`Žตฎ…ฮn%Aษ1บ/ฟ๐ยsิณC•้์๎nG f่ธk๐jc0F๒i1จ\ขึษ฿9 วfx:|f}7qd โ๛?kฌlJ็๓tด�ฝ�ŽŠMgŽยp่”rฟ$�3ฒั์'" ้|Z�๎{่ไจค0-์' ‰ชˆ ฉ$[\I†ล'/ฬMโPŸ‰’vZล๒ย ฯฦ๙๒=ธf:+�๒~"ฆUmวCู‹>Wา๓ „}้�%sofสาˆชฆn๎ป„€t5dั๗ˆPFh€๏อ4~~˜฿ n0ชk+0  d=๓์์tะอ๔hxœ™ุSihtะ@„ŸYฺตU้�ลK้D_7๛ึฬคƒๆิ�ฺD––Z8z์‘�•R™๘@ :2Mฬ*vแ K•ด6�Z_ัyiจ^—Žvs{[๊>�ร๋a`<\+iืิ ฺ‘‡SUXา0T๕u5ไIรnณLk๚S๎฿ฟรู$ศg_ค฿nCแ—ชo๎ฝk�7|ฬไ8nฬ์jLฯภ i�bญผ.ฎQ็ฬณmFSใงใฺ้z&อบD ภ๕�…Yู๕�eD6)ƒส๔ภฃDมท"'ย>:2™๎�ปƒXเุ<)+yสฎ๗8{สtE4า๔:๖pE�ฅู๋ทฤfm๊GR๙ฅ๓ฃฎ๒พค๚:Rญ”ฑg…d๏kjาฅงža๏NยฬธŒŽ้`t๊Hิy:2vs�๗”‚f,ีosm“kฬœๅ‹‹KQฒ0C็๘ษ๑qุNะV๙ฝตฏuฐDึq4฿งTdgๆ๚[ฏง�~Ÿ›ฬ๏ใจ3G#:๕ร๛ฒ9ฃ™™JฎQ�`้•NR่T๎ูณฉฎฺ=ุ$ภ,O=ศฤg_๚lz้ /ฅ‹O]„ฺ<ฬšษุG0ซศ KQ�fฒดvึ�‹รg™ำฑเ(แ๓ru@A}๓ญ5ีกb ‹&ˆ� ํ๙ฬ๙3ฉปง+f�w๋H]]]ฑืŽ�$Š`Mณท%Wส•ำิK•6žM}4๕‘ฅ๗‘ล ไ�œ๊�๊ๆŽถส๎ž9dิ–q� ะคL/”™Mฌช &ัษ<ยH˜%ฝ{�!Ÿ)ฃ…ณ„l๙`†ถตญ�@†fR๙ฐ?Œฮีใฆˆฺ-c๕:โ_๊ฅ s�9ฏY?Šหอ��'zlป2?ต๎�บษ)�Yg“Flv�Dv นฤแล!๕^l*[ ซg;xํฺ้�koฃ[ษPฒ'EศA�ชุ๊๊๚ฐ?2<ซ๊DๅW[a“C/F๊๘k~VQเ™“~"“Œc c†�Tบtแ ถp)uำจฑuฌCึสา็ฆฆำ›ฏฝž†‡r๗ำิ๘ฒ๎จIY/ิ�ข›๖Xg ฅHๅTร๋Mx}–ˆIYXhji„%รุQฎณ�ข.ำ dฬfไฝl$ณ๎˜8ฯ์ํŸi�พ ฉมํ ๖Rช{ๅ่;� ไP0Z?B�T @า��๚N๗ฆ'ฏ<‘>๛นOฅฯ�3€ฝ”ฺภดฯศใฬ๖งัแ์]ห‘๋@Vcม๕‚�t์ƒขฟ  p๏ร๗๐; m:ู„9็ฒŠ๋ฬๅp•s6mจด}diŸEฦ…zFบฝน๛ก~’ๅฝ)ธWoสœvQ}้Yu4j'็*๊็ฑฏ–ทดทถ‡�Rท๊๛D—kฑ‘M๛จO•ƒ4V4๔ฒeMŽŸึ.{๋?พ๒Jฒ•๊Ž"ฏRำ •ค…๋!`ู่๕x&โ ืƒั‰ฎะฮซ‡ตA>ส™~PBูษม}+บ๔๒g้gP_%;ƒฌ(๏ำDYNWKKZ˜„5i?}‰ะ‘6N= ศี^ธ&~—ฑไUIล0šฬrเ˜%…ฅ4�ด™u>€c{" ๅTคะ�ํปฒ47Ž�ฦDพ็ญ฿˜ฝK๏ €eGxณvฒด�\�k)�•—M@`ฟ‹?้šln0mฦเั๋bฑณ๒�?ล๕๕o�฿>:๎ฝ�H)lSm๒ ‡]ฆ7่“˜8สว')(ฉ"cฝภ1 ฝถำืy}&�L|Xภล  ฏถฉ™k๔ๅ~ีSึอ€ฦี5ีq†ิ-EศF=มณSOิ‰N-ณlฤ3ดม™ฒ’:ิภsืณDฦ^y-Cื{ žAeญ}›ตํ�#2 sIฐ๛แบฦXJีr๕ฐ๏๏บ„ภ็y2”YmN`๒!เWร๕ฺl[ถญำqŠ ๚ํ๕’ฯ~์q]๖๘ฒิห้aป๘A6XwoทนOยPค฿฿ุ>Ÿ็iSly=(บt"ƒ@\้’Žq�ฤhจฬิล’รๅิ•ฯ†[dF Ba[$X#›‹Cใด-น‹ฯ<JLcVา�nฮu/ฬCw"[๋x VFj๕kN—ฏœIg.Gyแก”šPคEฉญณ‡Šr :ํY.ํpิv–`ra™๙๖{i‚ฎ๏฿�ัk้ๆG^2d q`ด"p�(%3๖@๋<hฉPญ]ำHชˆ่R.5ผ%Q �ฤ้c้ใŸ~‘์ู@ำ๎žถtแ‰3้โ• ู้OะFšA�ชฦAซฤPŸ9{"]&xจจยqๅmํlฅ[sF‰,,ฦซ…ไุฏbOedรปNKฯฝ๐t๊๊iG๖ณภS!gสฺต)�ำเิ ™'มฆ  ™ƒ !›9)—58ฟ๑žล้นe,เ็ฆ๊PHฃ+ก#พภƒ�6๘ณO€`—N†ป๏~HณiคFNƒ‡ˆqฟ �ภƒ{1pSฦ ฒฟแ๗4Gฺ(ห&ฉฒ&ฦ&าะะ๗ฤ$งn่X{i€ฃ\{uม* �'มฆTG”๐่ฌ H8ๆj'ุY๑หds-m@5แh`bq:๗(o(ไd:ป:xŽฉ๗444ฬ๘ฤแ๔๐มCฒฐ6V‚ภบุWฤ{๗ผญึC2+dB]'kบg(•(ฃ๑gy4i(–uต LYXMoพ�jzpซŸื ภษq —ๅ\6ชฦ่+ซq๊ETห iุZWN_–BfดใŒหเ@แ่•rฮฯžป€มฌi๔d�1บ๖ศใ†poฐ#ุ๗cย*ฌฏBƒ#๔˜๛gฃsๆพV9ฒฐ”๗uฌŸภฃ˜@V!%๊ฏ5‘oพŸช`Rีย3p0�*CลŒุ!gkaq‡•ZKึลเ5‚[ฮฌฮp่:O์๗)๕ึ3จ.”QJYศ!๏9E–tfr"‚ฦฎฎพด†”B)๕šqฒK ฆ;bฝ&{คŒlส4ๆ‡๏‡ไฝ่ฉใค๋๎R^@!๛'0บ‡X_—ฺอว#ท�—๋Cl้�:ฆ๊oฦ)“ˆG› Aฌ ›ฏŸ)ุ็๏vธต]๚ฅMณ๋�!ฮ '�e9™็Œuด $fsQ6จต฿ˆบs๛69{ ๛mึ†มดด]ฯZ5มA!zฦฆ™,A;A3ซ๓N9�๖Dสv๔ p•๓๏พD สนณ}[[e๚๘‹—าว^xŠณฆ<3VQ‰y‡…47ผ–n}pๆฤ8เ่kล{A�ญฆ†ปŒ=4@ญd�k j( “‘Rมุ:›ิึ๑ณ#•Yฏป ‚กWี ่๚๓wๅฬ‡`‘ซ๎ฯ‚f?gะฉ+ซ5~6€’ฮ?อ&บ{…Œด๖Fวทกพ†sYฉ‡�ำาั’žฤ.ž:ืNŸ๏ ฐ_`��FฃCมข0(@6f้ำ~Œฬ๎zบ}๏vd์หฑ7อ�‹๛j-๒>๋๛VW�›œ]๛ฦ,†žฏญฅt๛ู{Šฦi‘)&Xย9฿ๆฬˆญ.:(ุA–ฐจ‡ณ�s8kผึ๛อๅต๙ฐ์๒๐‘d”่SxุฃๆdฯF�“}งR-ฌ‡ lเุ่8M�u๛คุำฑัŽUศพภญถB`W๙ฑวŒบh‡krก3ศง['ฟุเTz}€9ผฯ*๔tงXYŒL ๒Z‚แx8น‡ž…r์๓็_[VI`โน29`cื*๔›อฅ3๔ehkซN …WURfX[’.0Šดเฆฃญ ฝสนž0ฟฯนD'�rŒ%Yc�8mˆมงมžฒŸฯนห—Nฯ๏๓1&๊xทNMNฆ-KทH:ดฐ>5๓y€๖*Zฑ\‘๛ฯEทๆ๑•ต1Yๆ€n9ey”ดC' ป์$ส mŠG)V.พ[.บ;ฏ } ‹Lู‰sŒ,j๛bOyฏ่—ฤž๊kh�<“~^€D€ž‡B2ฤ6๛<ภพ9ีก=YP�„jiŠฒ7ืสตMoซjษ๗’MEีอ~{?7=ŠำG_|žrตฑ‰ X&“0gฃy ฅ๓ึŒ‡ฦ_5จ฿B๗EI—ดcœฒ";u‹ตท๔A0ฟvœ๖ฟ=+ซร]Aศed�q๖๓ษEํขO-‘iRŒ\{Fm๐lYƒภ“k"๐$Pก?ถ�มบ`Ÿd;Dy•ฏฐCŽั…ลd๔M8.ิ/ิ7๛a/ 7vย):ต4d๗ฬ:D�ข<”๐š �ๆ๊ึผฦ3pฝ>{Nะฎ7กY‡ฟ\@้Fฺšแ})y4;ษ๔•0บ๊|˜F‡sƒŒJตค†ไžธXœ`ไ�ฝ\ฆtภƒอ `แ€u�ำ็€ลดF „Jูž ฿ ฝˆ฿);ะr Y~Mฌav"คuโ 1…ศŒญ<‡bฎี&ึน”์pa1‚ิqๅผ5ถฟ"’•๕ฉตป“ฆเฐ|ˆ‰z้ใภ!&�าkฯ‹ฝ*ก��Œห.ถ•„UBO๐&ž({o๚E๚q–Šฺˆ_ศช๓หK๓๑{ฟ๛�g฿}�ฺ๘๕๋ฬฐ=�mW€��ณ๑ศd6šฟ�ท~�_�๙๐๎ฟWZ^WQมย\๚ไ’นสŠิIะaTฉ0b @ฯ€ภ ๊ศขAฅTจ.๗BŒคN‚ˆท๐Uq^Ÿ็{ญ€ Iฯ‘k <ŸašAน l`ึ ิh’Hp;?3‡ฑ฿KWž}gs:จ{ึMาd ‡๋0›ษgผ๕ฦUใ]œŸB่}Mะผสา…‹}8u\dฝฉํผ�ˆ์Jถษˆ๗9:<ษฎHทn�O๔ํ’1|/�†ๆ�๖;ทา๏��wาท�๐uF-^K3ๅ๊Zุ๙fซQ๒vยGr8m่]ตQ 6<๑ถ#พิHณ2ผฦzภ‹OžMงOŸ +l/F`ฺล๕๔�ำฯkAค๖ไษ“‘Mร™ฐน\skkj$ณ�ำ{Œ� ห5ิตcB๕อuฬ,?•._~"=๕ิ%่ห3AmZล่Š๚nbxะฐ่1Uชอา ๖Pฦ"หE ฅM่~ัษAC.เžˆฤ['จ h0 N ‚‚๒า‘5ี™5ˆะ`่ิ่เh0ฅคJYW)WSw๊,ใ:X)ฎ‡Yฌ-XRะK‘ŒŒ gฅJgใป;;”6ษ.,๒ๅz�ํ#'ฒ!j[๓ู๙ifไภ่s-NYห ไฃ'…Ruไเ๒ฮฮต–s้>`ึ�ป#้ม:รOะ?มบphี\s='Z��เ;:ฺา™s')h%Tร๕”๑๗<‚ ฏล54ศ:8ห แฮา:มะ�ยื•=ONsฐtCิ]๊ฃNŠต•fkศโXGบu[ว�†gผทิั*œGื�5ฃf€Hz/ภข๋Šp0คพ-R8>>ยƒฮิ�}’L\7Žุ6cำ๚ร‘tคe.ูฬ<ฮ—j=Ÿ#ฅู์a8�ศ†Nq”h่๐Dพใ�ธWมม�‹‡k&จ”uโฬิ๐Gฎฯ€มืGษŸ-�ฅฃํ ออ๔”*lRบกฌฐข๑�ส™ŸUลhkk ]ฺ0J‰็ rm8#‚eฌ•Žq]#ณkษ†„l`ูืรnุf”*`Š<๑ฤล8‹Cƒั=หœ•น dM9:NภKน Q?๙oG4ZNemดบ”Mณ๗คฐ‰i๛ dํn‡2Œ1่�ซ‹:$–^ฐnœ –6ภ1ฺ5kJี)w_ํbYE‹ๅU�_๒ “dza:=|ธuZๆ8๗ A]E๚ไg>Eรฝำ้ b/๒Y฿ูBณh๊๚ั‡eฐ tฐXKƒi‹ึS$ปฯ6‹,ผNฒdKŽ ๒ฅ…สๆz8>ฅ'f๙ 1ผ–’ศŸๅ1๋์]”)ACuœœแ{Gภหž๛]๐ภฯV6์๚/;,z5DXs|ˆlบญ้™็? tอLOฐฎอ์ฎนkงฃŠG$sใ& †zสG8๓ศc<M๗Jfˆn๏5๛=๛<ื_‡Y„zัฯอ‚ีู—ิ=K��คเ@IDATrฎ�๛\ ๅ]/ Bd_๓ธฐŽ�ณeๆต็๘Iส๊๘|d]ŠดฯทdมR#vkศ2‹ๆ8ถZ๏ฦ D™B ei๐zึ��Qฯ ๘yfPe๏Xb6ฯ๓U-‘eO?u!}๊ใ#`sdMแฐ™ิ็ฯฯ,ง๗฿y—{นd}p๚ ๒ฑใžYๅ3ื`SGูJf่ี)><ใ,ศ$ดก™% >[ Iฆ“6NภX:นgฤ๗ดiกๅ–Ÿศt ข.ื…ไže—็W"y •พ]Tรจก/B)๚่zใ๑}จรฮuฃ  ไxW7\สศhฝ?a“ิK๚ �ูQฐŒ๔dlโyฐ„q๐o~b’rDป๙ลhบ\BPฑ‰?ฐksU๊้iK&๐MญฎUืs‡yŒผๅ๗ม�ฐ๎Oญ‚โ=+ซ�umภV๛๋หwๅศfuŽจ›™Km]1๑ล€ั๑ิๅ“6\คIฉมกŒ$A (AKWVธม1ฯ•l.e*D‹๔cPV”�ฐ฿lจ2c๐ หข‚liบหๆส636+ญ็iwสฑ7�›gุืฉ๛ดป€eฒ596ุ”ฮ๔ำ_๚พฦ“๔7hไผB๑ืว@๗ลZPฺุ cขป๗$~Sช8ฟ+”๗อ‘E P—ฯ(าf้‡˜๖L#„ฟ‘€2ใœAฆฦ>Lรท?HณำL˜ฆ�มภFิดูไœZRวYxVž=;๖ยฑม๛อ๑๒ุืbฎลPแKช๘ฎOฒป†?I@ŸE ศ“+ภ†อ–šŠu`_ ๑๋ฏฏ{iเ๏๚zฝ๊$ื{๗8„ฅ?๛Z>ำ๎๘yฃ}dศษœำ๏๕c,ฅำv๏n|ร6ฐ&]9q?-A4{] ๋ท0Zฺฟ%€›œcY‘๋dธงญต7ซk+่ตษ฿๗P'๘]&O#บฅ ฟQ[ฏึ—P‡น฿^อ6๚มFข‹รsซ0.—ณ ฉ๎ำ๒ย๒`ฉI‘ ๎?KdC–ƒ๋bI _ T๊พสฐz &่[ศ˜\ฅ!ใ q€�ยึ๑F‘ค:pMธ_„•๓รฺKฯrะM๊N™ฅ์aŒ,e}w่‘ๅyฐ bF฿@ึ็sถวฝ›๏ฅม7ำ๖าQU€ฉGิ๚ฑ–น€DYะ€›กŒ„L!L+kฺ ำp†ฑ๏๑…>ตด!ฅJiโzZ๏GWเ[๓y•5๔\s_ะำ0ˆ ฬัๆ{ฉœlฌซO-๕ตฉฝ๚Rุ8u4kไ8uดi/๖]ูฦ‡•yไt ม4YM1Jนšล�ุ@Fdˆ ธ™h�H—นyโD:‚~bใcผ–๛b_ �%'ูCdŸตัfธo๎!ย€๚! SํŽษฃฌ๘ิ��์~�ฟS�๗�ๆฯ���โๅ๕_�๕ฏฤK|ูG๓ d-ๅฟ๙ybŸRษ๙�ใงZ๎ง�า9>9๕ำฅฅ นปิีoB—ู! กฯฅใ`f•ฌฉu8ึ]*|*าM†สฺจญ6œG 1 ƒPต.}HGิCฏRฯ61๘ภนยˆIo5จT...เฌƒšใ@ชะึ1˜y|^ ฉžเฒŠึ๐ƒGŒ+bV9Y๚cวO€,’๕ในv"ๆkRq–‹q–5Tw๏�๙ฑ„ฒYฟOึ�xิŸOŒNฤhฎ฿�W`/ฌqว }฿พ{๚๋Pบq๓Azๅoง�ทFจห�I�ำi|-:fลๆ% ำdŒŽจ๕ดบฮ'ห ��š}‘ยจ0ซ™WL รY\‚}แดwถal �[+SWw3๗G๓(จqฎm3?.A—Yไ(ป ˜wผก—ฏ…ลuTœๅ›O๐๊ศพ}X7>ผ–�ฟ}“เ™๔ยs/2ึฌ9 s]20F8ตฎณT` ธมWvr‚ฦฯฌเ �์ฟ๔j3๚า่ณviPŽส3๋k@"�ึ๗�‡Žf (x๗ฦ†แ ณ>[ ๑แแ่หq2j`คิ7ท Sะฝคjกสt�ฺ๊;Raำ1z+อ†ม*,ล๙ร8?ฮ<^sณ๋9(]Gm`๘ �ฅฺi๔}†qลู‚†ปฒ=vj“ู๕ƒ”ฬค ณŽ‘ีุd1@U8ซ๕ dAŒ-a้๊mขAa/™�nภฐFฒ๗R7ฉ%�ZL&X:็! Fd~\ซpถ4˜คixlIคv…๛šฃYิใ๐ฬˆ+๓Žฑฬล๙ld0[Z†#n�RชธcKkก�ษถqณtโ|dw–†จ…ีwDคู2ุ2ๅHง™”ฒ–Aำฤa(F๖lŒVK&๛ยู3ั-|‡K”]cฅ/�]* S7๖น/Aฉ๓ŽgำAhŠƒํ#œSdVน๕�๋T่ฌhคtฺ›ุS๗� อqfQช ŸบNื฿บš^�แ01์‚nf‹ฯไนf,t"ึ*ธณ\ฅv2วq*ฅiœใ+อ– Tส&ฺมi2��ิ�žบ๛hJลuส\qถตcฅฬp™yฐQktm�]ๅ„3ฅ‘ฎฎfd*฿uฐฬ *ทธ"~น~Wƒ}›x ๒์Qืกv ฬVV!่แ™สจแs;eTMŽ|๑ึฬ๛ถ?E๐’๕Bอฝ.ฬLัั{)ตดทF`oน#฿vqF{ŽทงฯSšะwถ=L0มู|„~๚€๚m&= ึ7ภ<แขBๆษ.}๎ำ/EFabd”LŸ<šEส:�มบ�btŽ ่ƒาส}Ž๚]'ิ.ุœz๊hฅ‹zฎ‚๋pˆ:ฉั’Ÿ็ใœ ส^PyฏสJ–ฒ*ตZ*ซrโZ้tส~Rึ๘p๎OึG–~ฏ�tฃ๋utมธxเLsm:ู€`f �เ฿b฿ด;ภ~ฮบ. ๊sŒ|.�ะ)GJYk2g๎76Jฮ๋๕o\›๐Š N�ƒณ๎‰V฿(ฟ~r{๑:eึยฬš๚๏๔9ี๑�Ž ,3$ศ๋้:Nร้๔ฺี7ั›~ฆgว มัพZ๎’*ร5ฒ^^ำž†˜๗ถพ[ๆ€NขเืขณพEต”ฦช ตL+ฉcD่นิ ˜l�ƒ#GX��๐fz���้ืฏ[ฆ„๗*& ๘ˆLื*ภe_่2ฯNบ€ ฟศ๖>•yณ๋.„เDŸฏฃ[Lฆน€[�ๅืNฏŽฎ{`I”๋ฆ"�์ี์.,มjqjA๏6เlร[ฆœcŸfu+ณำi{ฝสHมMฒˆumœU๊v `ี&Uุ๙r3„8ห–g�๚เ=,{ลฯ‹ ู›ฮซฏฌ–โฝpำwˆ< ยš)Vถ�น›ฆFฦX‚2:ะฏ่ฬ๏sฯส3ฺ/๎!Kล68Sๆ•ืEะำ€ฬ๏NสCWษพqจะ‚6ƒ v@�fu๊%ืัฉ f{อj�่1ใg+�6ศ�wฝอ๋รญฃ 9า\,<@ง2”ชหWฝ�ู(A`o;ภหฦ’OภzJผw›้$ฐyุ ฯŒM eUิใG5รW Qตพศ๚R†`s>Xฉ{‹–Q,โ7p�ู่ƒmbxู๎ฅเจืc๗ฺ1’๚›dœ]+ฯงบ*t&ko–[ญกพณคโฯŠ>M่Aัฯ‹s.€เ—lCฯุ2a0[-HTy.๕im*ผไธW}้๏–X4ทœa†งฦฦถ(•# . ท‚:E฿n{ๆ{9uก๗ z�๎๘k>„ไ’อ0๚)ณโK8KeศณŒำ๎ฟB๐'๒ฤ’ฐ†4๊ฤ/ีnฎฏS*H=พ ๅ‡ท#ˆึ๔ฺaI!{ฺU“…กซ8;‚ก�ฏฅrฺG!Nrx�'ษต yเwkฐ#+(ิธ๗B‚๚๐ฉ‘ํ<�"}ฆ ,V๏มฦภ({F๐,f6ุง๛^ป�„ใ'‹Ž๔‡9<ฑW�#ๅภ:A˜vžหbฐ_,๒‹งq]9Nเจึ7wา‡L2@ฮ่ ณ็`F/่ฌ๊๗ฃ –aw-P&‘ƒŸx�Dwฐƒ›iŠkห๛’มโG nq๎ณษt‹Vœkๅ[ุf7R๐Y�KY›G/Diื4 x0ตเT:ง†กOภd<�งร=vtป๋ |ศๅ{.ธOd eวdผGศฐบCPว+“ฐ0+ุำ�ฝ๗“พป๚�w‡a่ฌ|๔๘�ฐฎ๎Ÿฺสฅ์๛—_�์๏�ฦฏ�ยฺา๖'k๋ฉญฃ;ซT'๋฿tฆlnf}ฆ.”ฅ ‡ึ;'WfAowบŽ‘E(’|xƒZคN๚,t^kชซP่ฅ8CHg:(ฑ9ู>C๚ดSVq�uสฏ็กQเ5ฬา็lNดUp@™ภ t๒#ภ8เ g n�๎o�๏•(ฯ&œ˜ 8ฬ‹8Ec%ง s&๔๔tฑg]้๖ฃ์ค nbป8rfูUtผ9 d?Fแ่๔|ฉๅt$}ธฏ‚:๛8`:���`RjšิE1 pาั ”ฝV9ฉqอc]•ฏ2�ฮž9oooไsl๎B ฮ๛ฎ$๔Cมwถ๒6Lึ�นหY‡Zcd๐†aยAัะ๊D๘aสใSf็1ธtว[Hƒƒใ์ษ&kป ๒ร€ว~X‡ใ�L"hะึฺ†|(@ฬc>ฑM>+1tf๗ฬฌ4™E0 t๏œ1o๐๏}บZม’Mภ7าBP๒ ์:†EวอŸฑฌ ู”'๐\pWฆ'ถง�๒‚ถฮ–t๎�y‚\hภ๘็J™4าOtt–#�ฬๆ?fฟ๏�ปƒณ…s6๛ๅ>œ:u: :Ÿ5P�>�็>“ฦษ‚(ิƒ„ฯAi๕บfก่�Ÿแฐ๘yL`u�-ม ˜ืฌ—‚๑ั๕ฌ„ำ„s`iฤ.๛ ๓``ฃbภขa5’‡๑+รฉ0ศฌํปค‰๎๙9dH^}๙:—Iื๋M3ฆ6ิใ@Qึ้6s1ยฝไQึำึ�Šq„๒ฝD–าu –4h›Sู,ะฉฃƒ๋จv้��W‡r{ม`›a^\ Oถ7Ÿ๒*G šq10ฒงNญฐ™!›7ีj้€?�ู5vTฃ์ƒ#dXฃ\ˆl๖฿นŸ๎฿�Nฯ<๓ษิXำ@Cส‡Lุ8…“ฟ•�~๕*๕˜€Eศ‡{KGGzt๗๗j๖˜šRœจภี 2Ÿ๋่|ถ˜รพณI?…G้ย…c้/<›žกฆ{Gqxx8=่Ocร้7ฏฆืฎฅ^าCฆ๎ใวำี�(๊?;ษเOŒณ†ฒ.2ะฏ–๎xMY€†s, ่ศ๏po9~8{g•kซ‚ฝp๊ิูhžWN&]trr4€น&จึO=u9Xs3K้ีW^@ ”ฬ้c๐@9๕KŠทฉษ5uu‰๔’ุ`�นLY)ฺ3้๎ฉˆทOœbฬ%:f`ีfh‹ะ�oพ๓v”ax�ุ†?~x&s๙ฌb๖R0DŒห€ภŸ�งิ#๗.(ฆ5jณE๛1m ขค(�2)`ๆŸณฃฎ฿Š๒ะn—ฒ฿ณธ๊�j�๑:}^ึื}W—iวW๑KุuJฐ›ผV†ฐ2พร๛eะ{ส’็�0T฿ฐ;YŽจกDVู3—๏ฅŸ)จภฮ๐”P ฐ๑ฺ ‚kผย หซร-เ9bM”;ห(๒ู3ํนเš6ัฯ|�จS=%kAถ๏ฃ˜ซD ตฌŸฟ~ฐ‡Lbด็ัช}ŠHึก‹H64UUMs^e€ภSม>ๅ จ@)‡„ 9Ž›ิ๐yณฌ=B‰ฒ๛‰A�E@ฆฅ๑G4_L�C3้ัไ๑Cบ›3SH6ี>ภู}๚cอ5รสฉF–๔mWHํ.[‚dฏม๗ยณ-ะ’-๏ฅว”์lตkเ:็ฦ$•พจ,คrJLVw_‰]ฮœ้ฃQgŒ^ญ,e ˆ๗o� ksUอ+2nฑ๛ํงฅฯ†ฐWศ �uJ“ภ—rh—๊Šส 3ำ“ฟ�W�าฟ๘ตฏ�ใ_๙…_๘ลทาHŸ~๔๘[M๔ŸสGfqฑ๒ฟ๛o�๎ฯ}๋;฿�7ถOำ-4‡.:nึอ @C‚๙Cศ ฅs€รPข�t๎|่Xƒ๋E(f X๋,ุš ๔ภ‹ึE”3(=ะ@ภ์Šศ€T‘s m|็rฬ�E๐ษgฺจฅต% R(lŽูa(9Aฉ่ฃ๕ธ›�้้qN‡ ƒ™n›ๆPŸEะb3>ณ>œ]jbgกค�S.PKg้บ–T"^Mเ่ฌๅถŽvทฑŽTBฦนฎฉ&ญlาt‡kษ๐ึฒJ๗5๓o'q3*^‹์>๘โUƒฦ7ƒฤ?yƒ&šHญ`MWWkXH=ิ๏ๅ=’yฝv=}๗ป˜ฎ^�1วCX@—r ยฺš3ำษิ`, 8o(�#S>ำB�6Mึ^‡ƒหC๙2๒ฒต+ฬ�ยtz�๒๓Pผƒ0ึe�›td3๊็/^&#O@”ฟ ‚5ะK)Ÿ๋๋‚$*2•ณŽซฅช†ADูa 1JR…อLx�์w3kƒ63’ŽQำY4่F$b๏”!ู*Ž'ฺAaMONQHฏใ?�7ดฒ:€Ckฬศ>drฒkdฉ,iุ!๋ฌLXs*›ม`ึ‡๋$Usƒภx�ร๏พ‘ฎฟ๑Fะป)�p*†�๋ืู}โ8Mtzา‰�ถtž~�]ญ8ผิำแ•K'ี1ๆ +v@i“<ธFล,฿>†/ผRŸว5่hGžE[รi7ื)จ%๓1Iถไ๊›ืy_๊ษษ*XฒฒEฝฉต~มA7ืธI]}uฃิทs[ˆ^8‡>k€Q๓ ณœSว[e3�๎ฺšF่ฯt๖ว ]™ใป A&;x๏qญ‚Ke‡;้ฮ�›้๛/�:์,๗ใ}š1; FŽ กFฬ^Yๆ„™ิ,ํQ0^'IำฝŒu็~อ\ Œ้่j๐ }่”8&ฒžlh9N‹๓ผ๗ 3y้๎ญG4yคGŸ็#‚[M™‚‡ฏ–ูๆ5o8Z&–X3๊uH��%๋qฺฉCฆั�ำษBždXธืชCS€ใQAo…หWždค�%ภฟvไ?mร�2 ‘MP๎๙|ๅYึลศS ผ๋"œ4;�๋๐š= ำ‹~‹&pฌๅิฤ,YฐG๔L่‡Š<ƒ‡�ส๋์…`mแตฤ8;ศทcสฬึZ๒R ณยฆฒ~ั๏ไp‡Qc•%€ฎ›๔ล0ำ�ิำฯคK—.งงฏ<ตฟsN‡๕นiF„ฮรกวูBg �ฟŸ†๎= ็y–” l™$Qjโ#�fp�Lฯธgส3{„|ๆqฎmr›ไ6๙นI6๖ จC>อ*‡ฒ\l�eๆ๚โ—‘;๎เo‡šฯ('แ3�ฯ†๏o้…สK หื.  Fบ}�ย=YB1::ภšไ#ฟ2ูฒ?บ‘เ๛๋oEฉG‚๓ร}�ไมG๑ydตะA~n]Cc8ย:ณU๎Y+ภเS”ƒ5ซ๛F‡Eฌ`ถJ,7_Ÿ็Aqฝ�๔s๚}Œ๎„�1๗ฆ์?�๒ฃตu†>๖v`�ภ๚้๋;ษudํ M๘ฆ'จCง๙&ูโ}œ|GXฌ:IGภzำ5๊�7 ~mdหฐ_ศ๗ฏžv}€0์‹ฌAํอๅ๔์ณำ'>๙,บM�ญm•Abฏ lณ–๋ัkใ๔:ๅ- ํ”ŠธfฌUุvไEนฏแผ ่ธ๘†๓ฮUไ‘!๖็ลหšDะสูา™mํhMแ/~1=๛�ำ้ๆญ๗‘Ela_ใ–oS†๔ฏ>โ3งะA6|,ๅห>ง่WPGฉโ่dสuv 0s1id7uยf`X#Œส��ะู”๊[šา‹/ผ˜�๚2 มดˆซงแˆ5Y€uตŠ?ัŠœฺ,pbl,ภbj�m�่๘_๏C<ท ›ฒHมฮ`)L3ยดิ‹ๆD฿ู๔ึ›Wƒ��`†๒ฅษ2อ›q>Mcsอ"๏q-๖ฐํ๊r๕ทŸ[ฦ๙+คร~4๛ล~ใตtถ„ŽฒTาFœŽม”นa ,๛ดŠๆ•sNQQฦ†่mu+\'ฑlD \4E‚ ysดwใ}แpbCะ]==้“Ÿ~!=q�$ฅ5ศ‘อ!sQIุ~L๕hฑ;dŠฉX�0Fnงษก๚]ุ๓ย21่�ศ”mั๒า,LdŒ{+ควAe‘๛ฐ#Aฤฺจ# ฒ ชZS.“Hrด นุG8ภ‘ษ&ว{"€†•‰d@^€„v™๒wึ�d+s๊%›๙ล™โ�๕qeซญใฯ๚ห4ˆfจฌ€A^๗mใW�ะ pPxป63O‰ I‘%ไู{�ขืเฏ๕ถw:\ @yfgZถ’ฒgŸด1:›ฯ`฿–d$*๐gd‹žR์นฅ ๊œ’ฃั7่H๚†ู5ล–จ๐ |ฎ:�ฟ้{ล=sŸ €kช์ b๊ซ;•C�บ…�ธๅญรๆ๘\_ง�tซ_ี๏ฎ�y:K๖n�ŽFmลkี1่qR๕•Ž8g›๗ภ“ฆ๏8ืŽถ“ฐไบH@๑�ฝe๚OPฒภ^ว๑ูloศ๐ƒ8slr๖฿`๎�0HTสึ›[Kืo฿Jำ๘๋‡yฐoxšภD ฌ็”�ˆ�QŠ<อบqŽCpฆะ๚๖xณฌ@?��jจV.=๎๏p�6Q"ยw!‚„๎—๚�ษK็`1ืเฯ41�ไd:}ชdR{Nพ๓พ!ฝ=๗�˜Lฉr��7�-3ลiu�)ภ,™!€5๔;‡�ฉ๗�yซ๒ญ?zๅฦWพ๚UำGอ d#‘อ�ค�:“Yญ�ฯ�๖๖‹ฏ�่๛ซชฎถ์ˆฌข žึiฎถ‚๑–BไA—‹DP๙ป‡Dท๎@ำ8DŽซFสw8์{8Š>๒p�vxN)Aกภบ‘ฟ ๆไjศDb๗PN0ะ6ฃ�Aน4งœƒBAgยxํ๓š ม›M้�๛0็}”x=‡ลY๎ฃ#รแ๔Kkฦญ็ฺษ~ๆภ2๐nr}Ž,หษ'8)#“c�$ฦ-›แ"ฐkจคnฒ‘Mวั#๊8n๏ฝ�"ตชิ๏k0Iะญ ‡ญญŒ…„๖คใฑ ๚ุ�} {7๕ำ�3สญลปL๐๖B๗ณ4=:‘๎LAI๔๙_��ฏำ�ใJๆn‚ ขทซ'kG‰r ่Nฏฝz฿F^™tๆไ้ศ~ฯ‚�่ทPฆS>ทฌชงฝhUMฃ”fš€๋,Ÿ?�ฦ‘@ใ"‹ชK š๏ฅฆš–๔๚ซฏง_�ๅ�)hl•%4ad/คอkPU)‡ิ Vฐ8›ถ4ท™(i_eŒ„ห!]วP‰ถ๏า\Q#!ตษธฅฦส‚ ก๒ืF2Z&๋gxŽuชy8ส”Jึ�]ท_~gna๘[q2ษLMะใ˜ิีัDHไใ-ธดรศฌ]ƒ๖CP๊e2‘sŒใฌฎmDIค�ท๏#หิ๒๏!ฒ๋ๅศค ฝ๊๋ซาู‹Œฺ$๛่ปอ็ศะI฿ฯc„Yg!/Cำญ5ณŠ]eฮ�ไจ”m๐นาZฬ๐่8c>Kc6;Ž8aF|+ ?มศ’YŒะxnำฌM–JYนA9๛ิ�{๙ูR๎็ะภLal™ฝ,๒ž]0)ุEv`v๎ฑŽGwื๑๔ฑฝ˜๎�ป{ฃ�ุaูฬธ(ฝ–u|ํ+QY อน;~๖‰๔�ๆ๏€žฏP�ƒafDน๋›kฝX�ฃลช*ฒัผวืฅ\†F_?Sษ1ใeฦ.๒:F:.f-�๗2ฤrขศฏ\Qป๚๐ม�๔ƒ๏�( <ฆq ะฃเฉ, 0Yw[(g#V™�C2๑”š˜อ,ศ—ก”อ†ฺณA `]๋8ิM� 5T๊ฬZOฏQ�%ฃ๏๛ฎr-น Pš๏�ม˜ฯเดๆpํฐ@Xuณๅ:ฮธ่ƒ_ภJ=` 87ฃ� เ่ธ;–4| �ดOะ~ˆ�2 0p++Uวp่Ÿ”‡Y]eูฌ™ @3์ oฬะ<�฿ืปปม>ั4ณดฑ š#ถ6\Jอg๕[„ฏ~๓w˜า๐fj้กWK๏ษtแสYฆ+\ ็I7M�๎ฅzฎ3��1T…œeN[ฺ†rdcL<7๎ฝฎย๑ๅ~ Y‹ xฒฎ•_f!ฅS*๏Rิ�เช๚B๔\ x๎EๆW"ปTI๙H-๖ภเT๖J=qฦววำƒ‡w8g0Kธตmฒ?EEิ7ณ๖าจหx~8ย6–ณtCVrAXะ<:l7ึ7ั‡โ ๖™ž8ฌฃฯฐ\ำ๙ต,I}ฅใhใH4}V๙พƒ�ชืt,ีั‘Uว”xฮ9ธ'NะCแ™9.p๔งo}ใ;กำ‡-aNข#ะ฿hภ๔๐�ํุ๛}JsJ(๑๊�I'› “c~g1ซ ุŒ�pไต Mจึร�jค GฯJœ“ ื™'ฮaSe:Rฦะฑ6ปถฑy[ศธำG๖˜Tโบ;ึอk$T3“ร Mณtgฌ?ฺๆe,๑wvLWd‚8ฦ,˜ ไ”๓Fาค`sZ๛86ฏพZถฝ|ๆ pษ\บ่„C๘RY0GฝฃŒ‚๋ �b�๘ึ6๖yŒะ0cใMž๗@ร„‹™Pห์๔ณl4*`ฟบไYธ ]จย๛ถ!ฏญฐัฆฆ'่)แ$งœ4ฟ2ริŒสt๒ฬ)พ[‰ฏƒฝฐ�ฯSN๒ๅำา๗ูฒ #{{ิฌฺฯฮ�Ag'gจCฃไ…ืจ_M™/เu่lึซˆŒ*๘โ๏xQฐkฎ}x3No๔ํโ|gkš`šาสฝ6-ีข”art&Uำๆ๘™ฝT5ลุY๎ก”iG‚๑ฅฅ๘บ่ฑj,–2 หาฆ|6{%pŽH๖์N<เฺฝ3�†;ญมŸ๖๖ณฃTYm‚สฒTY๙0vs)_อ,™1ึOั'bฉฎ`ฌA€มคๅ–ึpฟิxฐ+็#ธ๓�ธ…ฌ‚ g‚,ฒณฟM พํ(%4าว%๙U๔c"ัวูุEŽึึฆƒ1 _wศ=™ฐช$เึ_0[/XlŸฑ tใ6zพปจŸอํฅ*|ŒL–ฬž€ำ๚ฤDœใd#–ฏถฤฦต๛!C\3�LŠณนC๓a=๕x!B๎ˆศžc#D6ฮt\1€ื?,ร&ชปm2ู๋*-ๅZX+Z�ซR@๔mlƒz<Ÿ=ลธƒOn๒หผฃ,ž๒j&แWษาณTภb�๎"ฦ'็R–Ÿว™ๆ"R1ณFถฃ� ~u๊ผn4ueืŒต๕๕อŒ6ญŒน๖ๆ+LG Fฦ8ณUม,Xƒฅ$˜)3@๚‰ แ6ฌ๒ฝ�›ry83คศ9kdวt' ฎจ3ณ��qฆxN๕า๗็8ฟ›d™œD"=Wyส:แŒHไ��}Šue,_ล๔tศE/�ปs7 ๗?คษf่€฿H$0ฑSผฆใ�]˜=ฌๅcœqฯ{dBูWKรค‡[KkCำ€ gล;ฮ๕‹sฬ+ภŠู'๕Œฯ›dr‚:ˆภชตน9๔บ2b@+SD�mCทm‚‘~ภ˜cศU[[',ข ๊฿ํŽ|ญยX‡ fณบU๔ณ6Eน•…`ภnS6๕†Mะ”)uฟฏG๏็ฒพž'๊ฐฏ@้ตiๅ>g@R}คส *8{%๐'}V9ฑิ่,z๛ส•ง(๙j`ดํ‹aO|อ= œฬ“K0h]t8nศ—๚0‡ภ๊x฿‰tކณŽsสภ":ี9๐mอmฌ'ฝ@8;�WPยYฉฌ\(:‹เœ๛‘9ไฉ‚u#`dCH๔ก�ม3ƒ'iแAืๅœGsB๎Sฆ‚Y%ง…ุฤSY๖š=c1/}แำ้็�ฦ_งwHๅ$€$�ณ`‰ตร2v&ฦ้ไ ฌฃ›1nญ‘๎Šฆ]fBm*๖˜žn?ƒbA ูEฺ_~fฐีธ7‘3uฬดฅณgNฦ�žฏ%ซ_ฦพ:ขo่�›dz nั�นุ—2ภR่5ทuw!๗ฐึ(™”Iไูญb ูว^๚,“D:Bษ๖-อม XBวใซˆ ท“นส:ูภ~'1ฉ†็XJๆhEu–�drp›ฉk\ฆ่}8๛๗ฑ'[ฐalฌ[สน)ฃฉช‚แ‡ฎ฿ณฆ“]PIyNดซ��r wG;gP2๗=5ฐง๊๒ŠJหhจIืึใ;ภib‚eไ่;ฦกƒXฬฝgฯˆ†E[คฬธฟ‘ม…‘`O"ฯ =๏gšคฃๅตฑ‡๖ โ๒x�v“ \T—๒;m—๕e„์r–:�m> š=ifbพzขึX#บำคฯ '�{ูศn๓aiZLศb�”#Yqี€Gฺฉeา๋K ๚ีฑžg๕w>๗’e‡8qํ6m,ฦ็; 9TGrไลgŸJญ๘h, >—๖™xuฌป;š๚–Sสำ„~mioฃTกีื๏ฒ†Ÿ~๋ิ…O/ง้‘น4ญ|‰O฿ชึ€ ๘2ฬOe†ŒJ๙F๎ ฮ8žฝ,“๛ภujิ้�”.์`'๗๐มdสฺt7ฟ๓`e:ํQ–ค ๒แ^q1๚kKuŒiC.๔‹ฒ,/ืOฬZ|Yั@_‚ณฏžSส์kฐ00 “m]ฏฯพฟ“–ฆqต�ผทlศMu;�“๕’�SฆกึฎฃŸlค'๋ฬ๒G z6bผ+gp�ุ้Rฟดž�yฮ—$WซษE๘AsWzEษ8uฯ๕Y��ะ–�กS๒‘S9[๘˜สo๔p!ะ–ตPH๒.|ฮๆ๋-‡ฯd‚e1�vQi6 ภ)dW;๎๕จ›ี้6็cCฟส ฐMe?+ด"๑๘๚eผŽ‚'^—ก�5๙ณ็ุ >๗๋๏คกGทcาEkgc๗<ๅE�ํŠซX๓ุ,ึˆ  ศˆ๑ ฝ–&G)�ถa<ษ|7ฺู‡|Žืฅญr๏ฒ`ผ}ฐ>[Y๒KกP๖YไT฿C@ม{T“ธŽ>33‡ืสq$ฝ๋.Xฝศ~ูร@&‰ g`˜ฺoB?}|Šrฦ‰Qุะœ X�0ธ๕Sธฎ๐Q๙x{๑่แหrp๗w‘qื@๙ะำng๗D๛ส์“รƒ'‡~q๐�ทs�ผ๚ฝ[_๙ส?อfŒyีG์ d5แŸ’ีศdึ๊�ฃŸ�ย฿๙๐ƒ๗พ\U฿šท ป@ี c!‰%„:šuุใภs„าWก‹ผ9ึE:ผKงผ T๏1*fฝฑ(ฉŠPรฌัาXZ ๏฿ฌ•w๎q+ูL3r:P…l�ฯNลC฿#�รฦ,^)[�ฝ…€พƒbFซฝฃ5$ˆnnoวภu’uธG�P[R.?ืืzx6 Q;Z‚^$�–ƒ่�ฉฬlfฝืฉ“=ฉžนฤญิะUTRC…!ฮมhuv๔D >ฦgๆโฤูู�q@u41,}…^\รุดผ�ฆX—ุ่ŽำVดGz„Cูภฤ…›๏พŸ~�7~‹ฯฅฮรํ,๕}”~ ฦ‰ข2๓1f tีP,๙8TNฉ๋นะธฅmO€๔{ญ[[๗ย‰ฎฤฉทษส™Sวกพฺก{ปkแ&ŽfN๊>ึ1lS3ร้t฿น๔ฉฯ|–,S๚ –�4 2™ZใYX/)J๏:?ปE( ฒaจ•ๆ\€๋56ซฌฅœ2จ Šj€แxE๕ Y#ฌแ:@๙K)ท'DฬMๆ�•ƒฮฅm6๎Mj@k็z_S†ƒQ›ยฟ ŒHwkอgh`๘U– 0"x€๑ุศI“#cG‹ุdูtัa˜ิเฤœ;!@ญf€žŽvz`-*aร! เูa,O)hฑY•vYฯ|ษƒƒฌกึy =2€ Zิ๊-~ั�2^ซœGำ$(…^R}5๔:ฮYืศฯLำน™ฟ•Vด คuBศ^™อใšlไXJ๚)ร๏ืกฆlh +WydVนแl ๒พoศ…็ว3fถIฮ k!xdp^วTŸ# ฅŽ๚t๋�อN™ู1หปmmƒt CณJ-t็ d†Lฝอ.Lˆ…้]ๆฒำค ง!จศ"gฏ๒aeEC'�ฟวฤ}าเฤ7�ๅs/"eชน4จ�เ6c€Ÿbฒกข๊—๖>1Hต_๊คฌงBหำฐWภะY#ึY‘ฦญ3์#สc0ิ~–์ƒƒžž.ึ-@ปŸ�dgุcงWศ~RG™๕o {…ฦcP๗dmcI"\ณู eิ์ณ{f0ๆZzฟG่ยƒไณ‚ŒฑŸอeแศ๓?๏9(–\—เAฯ่ฑlข นtฌhืูพ4H`๓ฮ›ฦ}ข 1ูก‡$สจ‡ŸFฬ๙*†Žฝ:จCFวจ‚:็ฎำงำฅ๓็ษ†ืค๗�ธF}ใLษ%ศงLi…†_ํํฌฃร๖X^คL9~ฎ ีฝ%k+ณ,�˜K�Iฦณฌ�{�mโXษูธ๋—�ำฟŸ>๓…ฯฅ็>อฟฝž:W€@ษ‚<ุ6ุŒwฏฝ™๖=๊ปา๒$๕vGw=ณำio™๋เ�ุIZวอ�8–(Afุtบ&ฆ&#hƒยm†—ๅEพi�„“ณƒœถw๖ฆ[7๏ฒG‚'Ž�$Sฮkmพi ˆr( ่lๆ๊ย๙K้ใŸ�บ…์4๗cเึ,ฅ}ฑ๙ ฦ>+ณ0% œ†Rฦตสžัi›ฬ@/หŒฒŽมf„็ฯ^กWฮ‡�3eIุœ]๖ˆ#ว#—ุฝแแaฆ�\pp�%SƒXS๋ไ‘ฦT2ษธug!ฬ/'!xogฯŸ�vb * tr:๖VsVั7ฃ.=z4H6๊�ิX�šงกmsฦๆ u+ำvš/ภน�g฿s๓ัศ—๋eภhFp็>๑dฮฒ`ฒ…ฎูฃtHงy๗`)žgษ]=%^.<_ Œ๏ฌฏ ฝlนษ?�Aบ๕�ืxฎ๋‰�„iPŠBซc฿t’ �*šjาฅV9€ๅ์ท๛yˆ�šฌจ†‚๛๑ฯ|.uดดง๎g€^.%<งgs™ฒ=“o+ณ3ุๅlsOK 9ห- ศค ๆ ("ภๅ�6้=ำ๖ฉeŠร&�ี็hz87ว็Ÿผ”^พ๗>#”zีึม8 ัใแ2Ieฌำ. ชŽตš๛ๆBXPBเฅ_$่ญฒหฺฑผศถ”=5!ำาฺ†MศNa@ีเS”0ไˆbห,Žฐฃ2™ฦbPจ,„Oล๛hk•,ฝฌpฯิฑส๔6vZ9Rgฉ�,ื๐ปŸrขL�€ัknmjเ=ฑ›�ƒ๖� v๐H™ผywŸจ„ษฺ่C˜฿ุารˆ๋๖(๏<ต oxx€rข๚wX7ฯ๒96snii �ทDเt์กIƒR›�ษ–tํ•s}ถ๘Bท ๎มส๓gHy๊]๖lล=nฏๅฬ kcฐ-�ป[4‰ๆบ+™nTƒฒฑฎ*ํดถคฎ.sหฬ9ศkG‡G#-]+ฅ7‚% รi|`†้Tญ่9๏DPFŽฝมฺณุฌ(ทEo๚}PK๛f ง�โŸ์ซ๗`#8~šS†Ÿ��t™‡�งเฎดœชZF?VxM–Xด๋+๘^๖4ฑ™๒z_ŸLำi2OPo�>69Bณ๎%ภ&Pฑ'2ึdฺุKฉฎ†ž |ฮฬ‚Œ€@ุ~6ึ:ษŒฬ๖-แธNuผ”๗Bl’MXGภ๙<|d'ฺ\ย8�+�N‹่+จน‡ุ @%^ย} สS‚ช~โ,�‡ay:จ5@-"รmlฐห�จƒ] ๛pูTผžk๘NP�ื7ะw๘?”Mณพ‡ฉ‘x#0มu0KพŒmึž r–เ{›ค4~pฝํตf9ฒ,”Tฺย฿”นฒ‹Ÿ"จฏ฿Xย๐ทJx�{z™p�#c๋้เ•kุุ้%ซ'SSOoสญmfŸ  Y#K�k/ึŠ™หd:dŸ-้์9ึŒํ-Ho๐@“ุ‰ื๑Lุพ0GYzmจด%v๖ฯRŽ๔๋,Qท 8p[b9�ฬ์ู$ฬ6ฅดlPYฐ๐&2gรหG�“ศ66=ู‡ษwฐร๖ ห`V/า฿หถ์ซ๛ฤ ˜พU๔šŠฯ\ขdM[๑ุฟ=doย็:v๙�zธX]ร—ฃ�๗aัธ๎ˆฌพV{�?��ƒ�ธ๛๊ี—�แ /|nšฝๅ•=\}‰?mี_� Ÿ�ป๏ฝ๗�/5vw็,#|าซ61p›f$ ลAtdŸTY B"•ษฬ‡‡~๋์;ฯ‘2จ๒ATe�โ�‚a€ฦ3ƒคBษมn€ฬnข$J80"XjJ l|~ผๆ'H—ดฑuœmมƒ ๛,J]ฝ–ฺ2ŸใŠ๊ษจ�|๏�h,ตJ๖ม ม@ฎฃ๓่๊Fช j๘ Ba%%ฮƒP\๊‚�่–lๆhiEบQ FzŽ�˜ฦฦy๖ˆนqฆŒแX–3๙ ฦc=ัdnบ๛&L[ฎ�™ํŠสญ{๗ศผ� ๆฦ2hvU Pห2�ํŽ@dm\“ƒbิู=MgแC `fิœ=มš"ึตƒŒ๑ุ๘$�ึiœ„ฑ]aLม1…bn&‚พ\š๗9�›žy๒Yุผ/ฮ็็ุ;)žล1โCœ�ํUœป๚VfึO pŸ๗ษe]_3*ๅ]2@ึˆau™=� ”Ÿ5�”m(ะฒMvQ๐{ผ^*ญศ|^!H< [ไw~‰๛.c๏ Zห ฺtfฌมทฯƒJ�}ศฅๆห{6ธ™Fื5Lิ๒ญ’eฮฏa\โ เะDj=v<๔E}๘ั�ำข}.ฒย8A3€ิ‡ทตทฅใฝPด0‚…์•tJk๚1“Ž4ษ„๔Qศ%ใฃบ‹†›?qHิ~ึJAฌ!หTmtmษฺ4i˜ ถ๊ ฒใ˜z�2�—ƒƒU;œ^ะ�ๅภฮ€ฅ%: 4›ฑNงa,ษRhคY3็Kq]ฃฑg€ฃ๊<ƒŽฺซภเY“ฮม4Ÿฮy„Zงกมค:ขIงาLซY{Rอฝ.๋qซน6›˜อภ81ฃT‡†ฝvBy=YฎชRht,อ[าเ…ฃะXฝprอ๑a@<ท‚€‘}aฏอ&๙7ฉฅ‚Ka-๙ฮช6ึ1“›ฺฒ๓,๔ Lก*๊Fฺ๋ำxั๑‰Ocษ)>H4kyฅS/}๖฿I7พ๗Zš%ฑ•W@IDATสfี;ะ—ฐNjะตมฒ47S๓ูไ“€ฎc์๑*zฐคŠfต\ณๅ‹7~|=อ.ำปE] @h)K gคนญ#Jอไส0๘ภzPR‡\aฏ,๑่ถq(� ฝm ฒ ˜{บz >ชา[?~‹dD~D;K�ง;)ภ ๒ซ๖์?>หž‹@OA^ป{FZxอˆ Cฯๆล>ข�Wฑ�NTาฮษF˜ฦว0`ๆœง�g ˆิidŸ)1ดซ=,Qใย์๑ย#ษ99"ณi๐'ˆ0zฯ‡Œ0มdO^ม็ 2่ฯ๖dศcj–๒ั๑9L๚K!๓NdZS7re์m฿‰NlQSA=Œ-•1UBiา }{ee ๖GŸ–ฆz�”ฝฒ24>ฤ™�gO'lƒM้�”9` —ๆa)Lฒ?ุ>šC:{^๛้y1�œ]๖�p๎vน>�l3๗Eนะ ๏=91„_ภt€J‚ฤ่เœ‘%@R“S‚สš๗/�ขป qั5”6คา”w ๆ็H�`š…อ!{kbŒQ€u๏อฌw#ำ›๊*rJยw*ฦฏฉ(cฝํฅg@ฎภ&Rk^‰O•O฿ƒ#ภ3ว–ิขC˜ฮฐ<ƒภW™๔,kรีw‡fฆร&เ�aิ ๊ŸI"ญ€$ว บ€ณŒ2–ƒ�๐์A6mฌ\V๛"gช�\€:๊žห=�WขŒณU๛mfภเ€๖J:;.HุcูFฎU{ตM!`ฃw– โgj`L,p?�Gœฉฮฮ6๔-ฌ1ใuzoูo‰•ฆg‹`3๗}ฯโ”&xฆฃ(3ษก�3ๆญ% Nซzแใฐ{ฑ๕C“ฃ้๐มv‚ •uชร฿l‘ํ’›‡สพ�PาZ๛R9‚ื5ๆvC7*[ฺํC;Xu9�s†xล„\>๒ฎ2ทูW’๒ |๓ ถchk”6DŽส[Smว)ไrฝ–.ใ๗ตu“ะฤฮp๘L=มZ œณ[ฎว฿l9q>5๗ [ะA›ทnัธsะ ๛Oนๅ(G�G0ฬTก=ฺ ดฆ˜ต,า๛๐^ `–Zฃ}4~ฑฤม้N\ษฃŒมณ.Hd�ฆ tญษณ2โ7™ฺ&�Šๅ‰๒‡๑1�G[+6h?}�‡W๑ss™+ฃAป๖ึๆชU่�Œ@ฑ ~“b�gรpห^ˆr๐๛ูุ๐y]{YN๔๒ผ“ *d าฯํ๘๏›n�บ๙‹_ฯd~&G ๛่๑'8ภภๅlอ๔?๕ๅฟ๖S_~�ฦปžฬ`˜�้xภHYสมน4[‘ํ5>"cvHๅ“‚nฐ ๒ikCแ;ฎQคตรฉSฃใŒ4q@า๘ฝจฐMฒ ๘žวkํž_ˆาฯ!ณg™B3฿ท@c†aีX”rŽ์ยฟEvภ ’ย์g๊ภ๋|(ิ4ฤ37ุ‰๑1ฒ๐5d[Pp4CัฬS—ุึvŒŸอVšัฌ 6‘ฅๅ %X ]Jcบk`†๚ธบœs”‰ื=>>“�ฝ๑!NŠ@ใ‡2ฒ�พ#uาิ'ษ˜ ค‘2ถ4TZX\K?พัฯa6‹M „1 ’CGxQB/�ไ@๏ถษา•า€ฯ V'$œ]ึOzะ:K=๊๋กา‘ี…<ยแ1HจYฤษื™<ฺ…า„am?F“ฟŽใะ@kQ์(”สต‘ซ �U(@วE�ฝ�0ฝ�ญFเฏsอE…jd๙€ฮ”๋งAห เ๊(Y@๐wป์ต ƒ]ะgด๊‰�่ธ }wq๐๒m>�ฏ…fFฑมห๖{N*bอ~ุ{฿$V•+ ด…oธปูธี%:f๔แH๚�๏}T7‹ส ์˜™„บI๗�ฆึบ๔ฬ‹ฯณฦ๔B}ฌฌป.คŽัz_–ฅH-Wฌ]ึ —re^3—:๊=๎๋ š.าŒ‡�E0๓jFฺ‡kฃฒ�_ฐ”„ZS2|!สิ.่:๑6ฐิQr4“๗ขกภฤ๓oqœษ Eฆ€๒ะ฿\ฎ[j#( �ฯŽ �ฐณWยมฎ๕v๔…@.vq ศlP{lPA6ืฬ๚PูU0[6คล๊Œ๚yาฯtN––qะจ๕์์์1ฆ)ุ4 ๗mฝ้2_๙†@ฮงฆฮ,๒>3ลดพ๒ณคฐ2ล�เบ•“9๓ิ“ม4‘FษŽลywฑ\ŸCŒบเอ>ฮ2ฌฉ ฬฬฆœ4“-ด4 •๏ƒ”(�๊ฏ�/iๆัdjภ,โ\mg`Nไ3>U`�]ผŠl(๒Q„�ศ Škญž(@ฮผฯpW๛ฌXbcเ๏1สน�C—Hc?`� �อ8v๖v‘ mLCรƒะW'ฉต1kถ‘kศยx๓Y–d›EaPูณ”Rcู'=3|fo�.0Vฤž 0˜ฉ3รพฐ™ญWw เ)ฒA\DตฐVฦ‡F#cต.ึA฿Gwฬา%œนuๆก38FHŸAw›Nเs"ฟ๙/~%˜JอNs๖!ู��ส๎ฯ�๛9�๘ฺ[‘a”"ฉrdง๚ิlfrตkGกผ›Aฌ,ฺ„๚จsˆ~ฐ\อ yฦ’ืผŠ์m฿ —I7�ใ8ฦž—�ิ�^๚ƒ๔Mt1Mั๘ชD'ซใv)‡0fFฯFRบึฒ๎ใ์=๎ูฑ`–กžด„kTvฌฟn๋่Šพสม2ู|™gฒฐT.��ฦœ–'ฦนV9tˆฌC…c“›ทวgQoฬ๏Oา่๎i! nฃฏ/ฅ~cาำฯผ^�มuไŠŒ-อPอ๓v๑V�G}lํธ%vU4ชฌแฌษ$Rะฯ?ƒร9Ÿฎ_ฝŽฮ<ร€ูW‡DeV‡ ๛L‘A20๐F[=ืEฆ฿9 มn๋dh=ืล8ˆ๖?‰~่_ƒ"ํ‚ฅj~ถ๖U`Nว=l€52C€๚ฯฟ๚O Œิ๛”€ K–พš๗2มู;ฮบAdฮิnL…Šฺ†ดŒmˆฒ0ๅนดดfา@ึ&—�พYผ๓ษ<™ษฌ`ฯ๒ธA#œQ3จ–่5P’W”‹ (€ัw๋๎4ะEฏ�๐>์ˆUภ์ำ0๎`NŽดšรŽ03^HธOŒ<๔ฟ€็ๆ3ษ๑ 28๔ร๎0K~'5๗๖ฆg_๚wั๙”�ฅพz5’Ž8ต‡บo€๊~�@๘ฅ์}!ห๚HOฺํ= ผ๎r€“b๊hžI™สื;o฿ˆ.๚“ะึe\P–Ÿฺัฯ|๚ำicb‘ั}€l€me•4&ไ<่ig พ�ด‚9–B)รสG ๚Juฤพn๏อล๙ั2F 8ˆ_“e�ฅปท๏p๏ีฉทฒ‹ณุ้Nบีs†ๆm6+` ป‚€HFƒศถ๒]คoฆ|„ฟD@-( ^Vฅ@ƒ‰�G;gG2ฅ ฐิ/_`( )นดA๋!%ห็ฮM?๛ฅŸ ฃฑ$ บ�ไ‰ ฐ้๛Žu3cŽข"ตR�ฒ˜๐ฺ? 9?Gฅ&ฦf+;~6ณBผๅtศพ่7๔twำืฝ3ฯhn2แŒฬ6ฮ�b�๚Kะฅฒใ–8“fฑํMิื ธ`’ƒ ็�ูHศp=ฺžศ๒ไx�๐๙lะmp[Aาจบๆ05๊ญโีืUฆ)&5(NGฒๆ��ไศฌฐ’ิะฺˆัˆฮแ๕๘4 ่ฝJฯJ๘b2U,็ษฺบฅiไz~ •}W [Lฺท{ Pรศเ๖มฉOŽœ฿ฃg-'ูƒน!h BpH`พNฝ�6YฦR!všํลW'ˆ$P�ฌฬ+›๘‡๔[฿งน"‰พ5�q๖K฿๕ ]j๐ส9ึื2™Pยณ๎โ—บWฺบbt“ฒ&(ตฝ๑‘๗žO–งื}฿ำ9�ทsฮ“gv6ฬฮฮ๎ ‰$‹ค-สฅ*ฑD‰R•\eูo\า š2 TฐKb•สeZ%HฉdณฌฒH‚D,าb›fv๒Nžฮy:็p;๙๓9wวƒธ‹F๗t฿๐๛=ฯyN๘ž๏9‡‘อฐp ะ#ส๋ล้�น}๓AšaŒฅ,‚|ู๊ไ"G7.๏1ั€�,$H๏ย�แอฯ…>~๚๔)พ 0�jึžD‡๋ศใ=_คy,=žฦ)!Q…หฎ”ฒ%›+ั+H�พ†ฎ<„QฑBฒLฦd‘�zุš่K“`xแ๗ฤ �{ฤต ๏๓ฅO`r$�Mๅ"@ƒn=$0ฮ }xใV๘๐NNฉgผ่�ย๛L@OƒƒŒญฆ”™พ8ฒxหk้‡BI‡$ฮ6ฟLลฌฯ!ๅ:๓ำ#์�n0\หนปaNYrฑCBl€กๆศ:‚๋,ฃ์p ๛ๅ�๘P—๋ืห4ึัะ�‘m ๋ภk–ฅ็฿}บฬKzด๚ ้๋h#J‘y‹๎ม ซxษ ฏ{อถ�RฃUD๔7L-udุƒุ@ใำ๘ุ๘F01๔ฟe‚้ hJี๗๘"Q‡๘2๔}3กk?ฟฃEใ:‚msฐ�ห฿�ใ?ํ๊ฟ}๗�เz�?์ๆฯ๖ใ3Pคื๖›�หo�ณฏ_{ณํไษดŒ๓่ˆ"‘ฏ‚kร9มเิJๅ0�:O๛Uาข+ €5�Fภ2 ฦeคp{ ฬzrุU R>๗ก�ญแ`#baH๙k:�{ ๚0Fpzฦ&ปะ(กน"ธŽโำQฟ`(ฃ–Nๅฆ&…ฺูjณzฮฉ฿Fษฬ}๙ฤWา๋ฏ�9œพ๏๔7px@šqๆ&q&กวŠœูไ/Z ญ ดŽ@วฎ�ฮถqc$SAIBG+๔ถ๎Žศ๚>x๐0rฐสitSสฺl2ฃzamŽ{…ีต�Bg๒แฃ้t๕ฦํไ่“ปŸLta*ฉ� ไtmm/อ๏ฌะคชŽu\‹ o‹๛7,ญ"ิ้๐ac9ัGื ‡K`ลlเƒ{Byจ Bก0ฦล็eษธVTึแ่KGuFทฯr�)สว†ŒYวo=yBณดEแ่Iyอะ`ะfดญ‘3H`ำร]๖ฟov0$ืง๙฿CแๅpBuช�– ”“=#ŽX฿Chaฅ42๓โ๔'Iุเห@ษ2 ฌAHK‚ส‰ึYŽ rโ�Uฎ3_'gFงˆ๚ฮ*œฝๆ�nะb”& ๋ฅภ6ตโฬf˜“>ุŠcำ”N๔R:€LๅG ัPแัI/$P๑š�2ศ�!ฐR!ว(Sƒ!-Žฎฃ"ึจWเH™)ะ!ณCฏ5d�-žร:่$ฦ<^ไ�ภ)ัZ๘โ5d<1`165F&b' เœั8jท5 9฿ƒณ( P`FjXMžฟE`Xƒq]Y˜MตYฬzŒYเFg‡บ: Dล kห๙๙-วYดฆฮ€ิŒv @ม๛๗๎E๐jอ๓<™H23ไMMRีกตb€LŒ “ฑงy[)k#ฅt•�"�{[Gijd"v‘™รฐD–‹ฝu฿ฬ<tX’โ(T:จ�าkฝฆbภBiใ‚�8iตsพUGแR ขณีึ�ณ†ศ–}ฉ็คg= ภI…ทTF   37t€AS์ฟŽป๋YDฦIฝรsๆq\9ึ?ฺฮ_���E–RึLZฅู;ณ:ŽAGๅlz้zK๏ตนฉTฮRWAณดึ–๎ฒพŠˆฒ}ฬ็pำศ8L)ึK มŽ่eœล Sue-”๎~Q^8?=•–ูY’‡œญ3$‹Kyะ€ฯ)ียr๔l){PZˆำLเณฐ;•๊จ�อแX}๐�w"p?๙ยK้ๅห/‘UJณS3�7e3‹cฌ™4ฦF.บnโ8’ฉ8@"หอ>๊ฐะ/..่โฝไ๋gq๔ธ?ฉŒ<ฮ้๕��ฏ:v็A'˜์ึ:๊�ฬB์•l?ก4๖ฒ’ฆ”่๏Jฐ3:ปf ๗น{htl์wQI`?x๖ืSL‰K7๚ƒฬ˜็Yบs๋๛$ลSƒL g ˆ@ฑ ็u™.ฃ�ฌฝง'ฝp๑ๅ8ฃฏผr)๚œLฮŽฅBzษ๐t่ขุ>๖Z:๒%๚ีผ๕g?ยฐl Œฑwลป๊ทc2Qsฐžฦ(ฟธ€.ณืตเwฌ•rwๆ์ูิNำร๏|๓›ุvํ็zxโ 4?๚่jL๑pYmึ์ื~๔ i A๎1Aๅ;7S)A@1ฦ่{ยศWฮP8๔€fj(ๅag๓ฝLd2่˜�\R1อd[S}ด~l{‘“‰ิed�ะ‚ค{…ผo๔“แg› ม�ษNซ@‡„ชใ-?๛ด›v*ภWV6ํย๏ศYูV๖ ) ‘lืึาœM=�ƒฤ<€=-ํศอใง"(\rํ๏ฆkG?„ •`ฐŽ@๏˜{-Qๆ9#fนซ›วw'l‚W70'0คฏ=›.}้ซ๘๛1]ร>B•Pm๊d2šแeu’น2๖ขŠr‚jœํ(มเœุ๛ฉc ‰ ๖ุ`�ฌž z@ขูผ…ษไญ0N2ูƒ๘…—/ฆo|๗wว‡/ƒอก๗}ญIŽdุง0ฉ›7ู่แT�%ึš%ไ2สqwํ ฃ๚ก„เI฿๊๊วทpเนtฤษSƒศ พฆ ฃ“6|?ฏฝH–๕,SŸปฏ๖Vฑ†>œ RmšgV�๎ูp2Žๆ �y›งอ“๙7๐rtb๛๎˜;{“€1งถžึtๅีKฐ+{Yc3่]์๛ฺ3J=35ศ}DdAถ›};:[‘Cฮƒ~QJ๓$†U-ะม��/ชžฒมAสFืื˜zด`yiK@ษแฬ8B* -x/หฬ€)฿„ทœ‰C%ๅe๔Z 7DL!P2ุUWษˆQ&dษ`{๔— †”C๔ฯม็=��Dา bอ-0X›M˜ 6ฑ[งภY็๙ษi>ัะcsŒ์†š_l`LŸ�ฌ“๘ฯ=์ƒlฮ]z‰0แภ� r!๖๕ม9 Œ@หเW ณŠ๋ฅภˆฯ`(ฯTm–ทCณพ�J6Š`@j|ฒ*ฦLห,X"›�เั &้฿ž<ตษœฮ˜vส๗S—Aห8`๏ึY๗ๆv๚w`ปตY‚ุ–jsexu๗๐ุ”r#2ฦ–+ษศำึy๔+ฃทบ=๚OagšKš๐ตศ�aƒฐ $ไฦF‡cŸ%6ูฃช ส eZ่ฝๆๆr@šส4ะ฿Oฟž(ๅ5IY฿Bฏ—BFง7wPv�ฮูGS๎•…ๅcf|แ�์‚ึŸห*�i™^�_owkบr=j�:€Aห#dูŸศๆห'งฐฟ{ŒNt2ษย๙ะณl'‡<ศ*FwˆMt.-aสย๒-ƒGRัๆŠCรณ|ู��แ3สาษ�ๆ๔ต_�‹€c”I๎Lร|‚…JrษšดS&ณ2๗”์�T�ฌsŽv๙$‚}�Œ๑๔ฦ2,5&นํSฒgLaเญoญ?kKˆ๘}˜ั_ƒฑ'2ตŽ]7a&�8K&ŸฑW[36ู0กjiŒ๒ฝ [P�^z‚ืม์ฑoIcc๖ท>=|๘8ฤ]ไB฿ลฆโ๑€ญ 0๛.๐ฆoขฯผG|ฦ…เทๆมl“GQ–‰ฮŽ๑ฉ\Ÿ6ื๗•๙น๙๙—�›ฏฝบ|ผ�?ืิ๚ฦ๙ท�Y๛ต�g๖q�๘ธ๔๏�๕ฟ๚k?~๗_฿+ช 4ฉะƒถƒภแฐ9ฉ Ÿ)ีูั‘ข7ฦลŽกาึค Šฎหึ)ฝา‰0Hญ� c ขBrไ“ฮ]ŽŽ๗ฮ{6๋กQ+ฮบb•บ”!#lญr ฝNŸ=‰ฒdไI%$๚ฅ#jVNซAฒวๆา ิคน๋dbศ์s ณ: tำ'“!�ฆd[Œ-Œผ๋mœuŒƒ้๏=T:`5(l+เA6่`Vp{(bภ‘Q๊฿ๆๆ  pผHฟ—ืุˆหšฎ3๚FŸฆ3axŒ฿ 0 "ฅHึCฟ@ถEรกวก\Tขุ�wพ ฝ D…ฑใ๙ปR.ส ห^Ž?๗็D๎Ÿl˜๋%"์ห1u๚2 ฬ‹ sdMำ๐ำก4ใยŽื๔@(doฅฏvvtAGoฅึ ช๋๗ฒeyy‰ล98ภ~s%่T�/hฤ( ‰n�C๋ืŽน>�๔Y๖_อษฑ‚:1%(๙†ฆ๚ิ�฿c-ฅ)ฮbˆgงวbฌ_๔C| ƒhฅ m2่ิํๅdฬh�Š‘Mฉๅžต %์u�Yฒ|' O’ล๊†‘�Ml ๊๖,ฏรัึiเ๚4ด�‡A†5�RouยuJD�ฝˆธWึภ๛ึัสg,]Y�;rฌ�๋| Xฃง่5K๕ฒ้ฆฮสsgด6T;ม‰Mฒˆิ๐Yj129›๎?yJรฦ!๖œๆq๎+k‰9ร ะ์ ง��!f|5tvฝvขƒeˆ๚ฦศาฯ?›OC๔ทC=Sf6EภอTฎEƒmŒฃำRhoƒaึผกพฦLNฬEฯ’ ฐห� ๖ =xDi 5ต๕�ฐ Ž๒( nฐm๐จภ4๚ž๒@"ำ๎ปYYฃ1ƒฌ+ฤk |ผพ]dรŒ๒zgŽบ๊�๔��฿ฌลD|ถ5จ6สโv้xŒQ�๔์75S’„กฺ!๋/ˆๅ™ืˆŠŒ๋ฃOถศžYงm ใ~‹Œ[v“_ d•u๐นัEœ,K9,ั๘–ŽŽtJu3ฬฉ}๎Y#\จ1Twษขจ%จญ์s–ท๚NLุrXX๓`zhฬ๙›์ {0(U�ง>5R็†ฝล‘Ar ศgฬr•แศุห…ๅ�1แvถ€d†—่xฬ(\ ๕tœ=๊8iะถ‹3โุฯ|๖(<IŒg�€ๆ์๘t๚ไฃ t้ฬฮ=vw๗ภ,Xงดแอ�ฺ‘๊ฝงฉ‰ไ\ ภHS<€�ณMŸhŒว1q*…์ plโ�ะศBฐ�ีdAี‡5d๑šp[p๚สั็,L�Ÿ~†อฑส)ทฉฤู๖<šJยšD@UfFู‹๑ถฌBยฺ#ฏ�nPsัู::ป๏8แ\ฟlงUJฟ๎”ป™้ษt•`�บห#tœSZจp‡ฦฬž!C‹ุ“W^ฝœ~๑/�2 i'า๗พ๗็€เ 0ฮฆ6ต%ƒLzŽ�๘›Š3ลZษจ‘™pฤ{–Yƒ.(\>GฦMถ…ภŠŽ”NV๔๏แฺธ5~6“ึ†‡Gะ‡๊!๔>6Tpf๐ๅK—"ˆuข‰ ำ�ฬ4ฃ-mฃไ ฮภ�`์ูไ$Fpาื J๘ๅzฌg&ูศั=2šจ)‡i`ภoCK–‘เน8J'Z:;™Aใ‚๕โาp ิฑฃฺ|BฺBNp๊x๗UGฝ}คํ„ไ€@�๎ฌr>*�ฦ๑ั�ไซแki`p{Wš–(k{x๋Fzแ�Kœๅ�4;Aฦ”้ k๔vqญ0Ž„O\:ตfLI)ฌฮM1๋�๋ศฬb3“ŠJ๗ข*Jtะuฺ่%จ๖2ณฐ<LชŸํ๙ฐCG๗mได lคŽฐ|ขI‰ห3€์lv‹-ีžก�ฅO#v่ ํY^งxJ�-aฯฎ\y‘ล/„ฝ"‰`IŒ‹ปฏ๐}B.๙, nGw7พ2๚ิล6;฿3ะGใพ^>?`P–ณosM}K- �ภ๐�k๗giX่xำ��Aฆ6uE|–๎๙แจ ฿ีท2๒�2เtB‰๚ง-’๊(๔ƒอำ์{ใร S=,ใJP_=gŸ>ƒืยG;็๘�ล๓L•8Kูัi€ฮีัvุ=K7ฐัc!2,๐ ‚าZ์7๛€o&xjณ6�๕E09Q–ฌ ศูDฆœcVm(โL_'šฤิ›aธ�ลŸ’ๅTTJ@KึSพกฆ8ต62ฮทเูuฺ“ฅ‰!ื(–ฤ’๙f6•๕๖{žYbRร บu’Qพ@�ฬY“ei‚O3อML[r„vG7อ;œ�(ว็ะCาฮeฆLŒ>„ู๒ Sš†hX=O ฬ๕โ๓m ‹œ ฎ™3ล=( ผ j+น๐;r6}ฦ^๑ฟ�”7bGn.ู<{fŽพT+iะโัใแ˜žฐ ะYŽ]ฮาต_ว&ฉS“่ฝ�g้;สจ@ชa�่j๗|ฌPส$ญ฿ ่-๖A6B€mœG๖ษxžด 6&ืkโภพ&zฆ๙ฌYX!‚ +c๖A0น#($Hฏ/ไ{๏’hx�sา/|ๅJz๓ฯฝœ^}ๅลD†ฦ†ุK(aj ๛QฝญรGulดพC{{gŒฬํํ๊M'๚ิazฐ๖2ร h�๋๑Tั%ซ๓$Œ๊าKฏže�+vก”‰ฐ]6q jฅ ย+๘rŒ [€„qฯ•€่Cไn›W Ÿลyuƒ๕ป๔™d[8ตซ๐q›๒ๆUภ-�๊]ส—ถhฆ๘ ภ^—Q๖๐๕+๕ญฺ้Nฒsผข๊ˆ๑ดญœไฑ` ๛ี„>ฑฑg3gฆ0็B›ู่ำ่ �ูPฟแๅบt‚สฎlYC‚C๛ผฏ€ต‰&ฯ‘๗กO+cNvE(Žtf�ป๑oS‹ไ',•ฉ้Y๖s–Xฤ2 ›�ฟk;ิ๖PโสŒ๘B.”ฃhˆ๏)ใบ�™R–ช"ผ\ *๒ จiฅด๐า๗�่;ี�๘๛›๘‡ธ�๕ฏ�ท๘™{ฐชŸอว๑๑ำฒ฿๘�ส‡}๘?”V7€{Yร†ใซ แ$่jเ‹4bŒฌศธ!ศŠ*5วสb[”`กชมA!3๒‰<+ฒีŽ{�รฑ3`ซช€เ -mิัw‡8:๎๘$ฉžLy+yA_"ภx:TวชPฃ 3ฐญm๒ณ5k ๋(fGฝHทบ~ใ:”›Žt๖ยหแธ#๛t่\ ซฅ8?O=แPะh็ยั‘๖"๐ ํqh9t6๑)ข”Ms†์ฌAสPKคำjท`ษ�ƒญ โีcT๚Oะ…ฟ:ฝ�๖�ihd ข-ตีAฟcWQ๋8ˆฯ–น>š.b๐ <ˆ*๊ �ฬึดาr ฎ•�ล:‹เM‰{ฯ+njัt์˜Bศๆ‚>oไ้Š‚;yG‘ E`Iƒ๓’{:{Pž4ค7€t๗*ูา�<฿ื —ฝร>�_ๆZqdpKศX๊Hlฃ4ฆVƒ‘l„ื)*™รpœJฬ‡NA9™ห‚œ#w๎$œฮ}๔ƒ๊๊p"สูƒ%™้)‘‚pุ3ี:f]ศก%>t*๔ีm€'SคฃUขpl๏QG ษู3ญ้ี—_&ˆข๓6—tิ=๊๒œฮ;ื)"๎cฟC๚ณJX#บง�ฐ'ึ�8G0OSIฃธ1fฒ qฒ< 'ฝ ‚๔ยจKใy“‘ีเพ ฆ\hฦFfยู�ซ๋๛d–—ƒ1๒๐ั0�m0Z€(ื=œ$/ณ\:*ุ”J3C�า€bGุ็ฐ/›ฝยแdd*Yผ9œ๛‚4S7}ส$ฑz‚@›๎๎แ pอ M�z\้Lu.ฒ~kz)๊๖��๙�m•--mฌ ตาิ5�ไG?fึ๖x€8fF+ซ r .Bร.Ž‚vNณ1;ฏฟ${Eูๅยข�IiyŸ: o3� }๓|h“Zฦฟ๐ฅK้ฬหฝi �ฒ˜^=ฝฉฦEฐzู๊Ÿc˜น๗ยWIฃใใแ‹4เŠ*˜ าะ–˜ำkƒ1•โž†Ay”ฌ„๋฿ร)ใข‰3ฌ…4h�K>เl0 ร˜!ฝHๆกฏƒ ุฑ๘ŒZGญlM™0bืฎ�DA”ฦ!Gลr"รู+ˆ๘€8๖่"ฉi๖sp”ส{แLไrส )ฃ&๐๓ฅโrVษึแไšAฒ๖NŠ’ŽU €ˆFBgUศๆ3ๅฌC5่:†ล ณธcหn�ญๅ�หK�าŸ�ฺ/C๓œ"6…ฃXา%ซL*ถ‹#�€ฃฃๅ๋eศ๐k ํ5ˆ˜‹Zฺศศ.๋๊ fm'โœw2EฎAอืำ์ผ}'๊า&ู8Sd‘ ล“aX!(ข‰ ฅ*฿e� –Vฬ1€uMŒ‹oคeQฮ[SS}ช'๛ฑท1—Nฆ‰อ$ฝ]z ๓y,O\ใIฬ,ฎo%0ฉ…–=ƒั[กึบ>eบO„ญbH้S€#c:+^ษ๋น๎O‹๗b–ู€PบดAผ๛ฉไร็ๆ7 ‹ใœc=�ฝ •gd…Zุ[7›7ถญ๏  %/า๘ ‘?ƒฐŒYุEฅ€ฌซ(พNบŽ_�ข—ฦOร6™ึbฮ‘MJำ}บศNŒคำ็OฅืฏดG6Yฝž๓f“v‹3ฎ�โtt–ฅ6‚2ณr+4ำนณŽถ#๏:K5[�ZLูvP�ื_O7?ผ K3บ™๚jจศR๚ค็[:QI92�ผฟU™3:w"๛์งA=€แแ ธไZ๖ก*๓y˜EHทhะ99ม$@ฝqi์ส—_vาvm ผ5Xาgc'’ํˆลmฮช{Sผ๏“…P_่ภ"‡พ&ุ%๎๑นณ˜ศNrV-ปP7|แหฟฒ=#SO‚๚x@อดฒ'0VŒค#กMT‡x๖–Pฏ(ฃGŒšษืิ“•€์ ึ@บฟs�u�อ๊zŽlDkฟผ“\ฬJoป฿๑W‚ฎำ€Ljฝ/‘ญ#KCเญ„_”rN-91@X&ธdฑคศw฿ร!*F^�ผ#ฎ9สแ๘>ะ?wxคณ/‹อธ�เป?t[ภถ๘<>C‡PJq'มตูฐyh๓–ถฝ๑ฦ็ษjuฤˆSu๛จ“ๆ™KŽฐŠ”‹ณศั),ˆ๏Kฒ๐�Œ#๗มO�ƒถ�ใ/s]{€(๎ต๗hรี“งOฆ)‚๑W/ฟ–�็'Aป7cไYจ“้Q†๔se9ผ:==I๖r]Žฎ&`ฉ๋ฤพa›l",ญึE๕| xLฐŸ7†a/ฑKH6|๕Œnโ๔ฎ,pพYฟ2tœ็ฤ)5ฒv ถฝF{อจงยน =Ÿ/[าัT็์ฒ'9=^ไMVว@f j�UŒ๎<= ส d<ศ๘หqNซ) ๚๊W~‘้@รi๘ฮšvAk– ขtPธ‚m)'xrฺŒ,ฎฎฅ†ฎ๐ฐจฆุe?nฐุอ'่?2ภุฐl;kŠไฺซฐ”AธŽ–-ๅi๏ฉฅ GX†ฃ�&Xว6kวB‡ซ““์e<ฟ�๗sGุ�€ฟกำซ฿aึ9ๆฝœhิำีKrœ๛6(๘ต๘่ึ6XXฌk่•ำ}5๎AkYO%DKd‹žส*ฐฃฌฉ~_ ถˆ[ Y7ห_ฤ4™}ฃrฎึsฉBฉเ9UYlว A5ซ๘ {i(–/ศF($€—เžxBห?&ฮ 0Šฒš๒๒�tv `บLึ €ศytฦพ',‚%ฯ฿ �FŠจ;ืฟiภO*…1QDsฟF’eƒ0฿๕ฉyR&ส`1d8ำ๚…๓+”งQาบฮ�,.ำษ~ฯ›„ํp6Oข}กํฐ,Cฦ�#ๅ`ุC๊ฮmผ,กฮท yŠdC^ึ-ัซสฆ:ว2/ล]6ฎrlยณ๏ฯส”๒cฬ๐ะx€ ต$mดWG�้้C˜œฬQ*gOVšฐx—’Jป�่ฏณ�RŽฺ,-‡EG้Im ๛nฃFดS๚�็?_พCข๐๏Eฬ@†a›ย๕5SสR‹omcๆ•ฺ…4�h"ตŸ๊Jฝง…๑•I^ิทPยพ๖0F?ื&ขw๏�„™่๋KํgOลู�ฺz ๐dFื#๎ =ฬY™ทDG๐[๖.@/ฒก�/E^ึ๔#Y›ภำcึุFนวPล่œฑชerH,.ฆูลว”NŒฃ+9�ุ ๑LMฏ{`�\l๖i{m๒&{่ˆR€bbl๖ษbdžšt8ฤ ฑJฎ'อข=ˆ8๏ศพ พพ=฿,+ฑ\c™ธK@^†ท๛%่•ลึ ๙สนg<€ภ�ง†ฑ‘e$Š(™dอ๓=รŒ) EW– g์ฝgKŸbYสโ�บoพก @^ฯpหผ�๛gRฯฉW‚�–๊๎ ฬ๐น๊@ฯSm]้—๎�๚คc}�o�]๔๎[œIฉพ?3ฯpภ&�๐?�แฟ๛g฿�โสฺ๖ฝ"?ู‚ x)ŽqtRU™(ลdg Cส†[๓ฌฒ�๖็M ฅฬฎฮ๖P:ฮ ]_ค‰ƒ&ํ  ๚นžwณ‚z'#Gเีชะ8่(edู[zz:ๅš†bฌดฎ์ใ›๗ตฯR/ฆ#71IญHกูฅญe(ณ8&:็zฮ วcF๙๚3uุ‚จัมษ.ฮR†[ฺšกs-ง‹/ฝ’��ษOๆHฬV’„็ˆ9ฟ์>+mณ—zX3๗�ใ� สAษxึั@ฆžR†้นู๔ร:ษ4ห!ะ=แLฎขHuRั`ฌ0ฮ™Z฿ัK๚ิrษ๐€Š„Kฯ�„๒XอJ:’ืไ๓4ฐt›ไH[“J„R๐gวฝ<งแซ�=ะfo{{บq<Ÿ๒\ ่ฦ›(’๎�VhYdƒ‰I๓๐ั�๔ึ[฿g๔“Sptsข›าDQไd6 lT^@๑a˜ผจ™Vƒ:ฏ:Xฮิ, โๅJŠ{ฒI–ู(ณ€h฿›lฬตI†)ทrู ƒศu[ฆฑ‰ไNกvY+‰'0mhฆ#kแ8™   m� Uืงึบฯฃtซอ>c�r88Y€(244ขเฤฒผd็?nบ^'ฒ-�:_ว๎Zm่๔…“ˆŒูgร๕๔ค”KทสะะH๙3จ0ปฌไkuBTš|Zฑ&œGrน_พ†'D�ฑ‡ฃ<5น”า๏bniะŠ@ค�{dฐ~ฟ˜`ูฦˆf ZpZpBKŠ็#ร์0แ~ ู6๖,ฑฏอ-BYEถt8Jฉq฿ต^ฅp|€„zu๋˜KPเึŽศ่ิA65๐แ�hxขg~fv6ศ$ภใFY/๚ศBึ๙(ใ๕fxNš+ฒf4ฬฆy๗ั9ไป`Jม‡๋Pอ๋�B�GY@่�์์Y“u@jŸฌ�Cว Kรv�อš9vญ– จนฝ Yฮ12k‚‘๓ิมณ~‚ƒ1* ฝ`ณ=ƒ_>๓Fฦ†ื๋�ธ‚ Q)ˆล|�>™,}Kฌร•2�Hfจˆ‘คsใ”eŒo‘I’ฃAœำ1wlš๛แฤƒฑ:ฒ�๓๎ง™5�ญ`ื˜ –6l s4จไพtju"e$ฐฐxศ$มณrJpnกเงบTฝ อ!9[[๔ุ!;TPhฌไ‰xมุิ ฮ-ืยsdhจหทกGฎ ;Kบ}ๆไ€rF{ฮ,2ใ�ๆu(๒ฏ~พ ฬตkคœ๚^ฒ๑œ{ฆeจฏ‡8'มจแ^}ฯ’jœx๖ะ,กNถม˜;ญ“๊zM‘๋ถFธผนBวQ฿P™o’K์อYg$(Y๏g3ำi�,อ฿ 1ท๗ yfJAYน":๋ณ็ศฎ๖g‰๛ุLP:*๕ไษ3ฉฏฏ?๚-,./ข“ษ’c7ฒ$gw.ค[ทo๑7ง0ธฦ๘•ฌก% 2d๖ะC›ๅ\‡ืฏž›œš'Hyr==�NTXcญƒ ๖ฉพSV�7ฏร™๖V]oBฟ๓ใ2v‹l8็Iqmิแ2พุจgN-งw๔N4ห๋~ฮ+ฅ}ฬ‚ถตถ‡ƒ&›BPเ=?xโ™้&2ฑƒ€ๆ4๘ฐ‚๋hฆH€๑ิเฉ4๔๔Iิา[ำjภbฦ��2มPื,`ฆ,…�4h$ฯศc�”SูAฒ ‚‹n7s} ฎฉฬ๏]�ลv˜Aถ‡M!g่ˆภฬ๒’e่ปM๕ŒDฆ0Œถk๏�$�๗TOMปzศ{฿ศฮ— ะtั:$๖กฤ`uu"‘ๅY;�ิ•ฃcs8ล›ฌ $Uu๖!รึด‚s-vค฿ท” ฎฟd‡slpz/(ๅธ‚x๕ณ@‰t|\’pๆตทฺb!:ณ๊mZuบู3ฯ�ฎฃๆะav๔_พ๏˜Iณฮอ่†fท‘ัtษa๚ฏ~้/ฅ๏๋[€\‚๖|๗ก�๑� ฬื pGฉ?++6{๔3ีGŽฎ@pื—h๊ha: €ื-S@PโฟธH–น=๓๐๎=ไ็(�ฃOป๚า“งCุ?ห2ธ”œๅ%ิสWdุนD6y}+md�ฌฏ65�0บฝ^†}�Bแฏ@�.cjฤ—ฟxP�n าำ�Y Kๆฅ๗งพ:ๆsส2[๘\ส๚ฎ ฤฬ์๎ฎŸพํฯ2hdM,!/พ#^k&ำSs์ฬฬ:D'ึ—” ]Clณ๛ฅPๆ<ปป€Xฺ๛,�~ ื‰W�ื(สQ8ำ>|ฝ๖ษr&ืG†g^pษ็๘ป"`บG๊`m—‰#ฏYะลณฏ�ฮ"wม� มจ�พr–g;ŒฝE�ฬ|ฎอ5พ…Lรว-’^ใ#SจQWYถECเสika๛*ม$฿โB๊แผ— p+ั‡Kู;ยfm็hrj!ฏŸ๋23]I"ฎฤ3ศ๏\ปฆ๒ศ†ะ๏ฐซlๅอsเ�หด�ๆ ู� œฒA5๗อ๛P็ํ๑e2฿G>‰IVทำ@_/๗ฃฯ2รFใ)แว หJ3cฎุHฯ}’2ึxŸ์๎'า์สฦญhƒAFฌ019†ฯr`�yภุV’[[+�ฉ…uhnGึ๐[๔•๕M๕g\X{1ุ+D๛ย�7“@hฐ๖:Š‘ปผษ—ุศpŸ|ฤ�งh‰ธฤ฿w๙�BlณqTŸyศ๛�ธ ‹�mƒvSƒ&ฐdC .�€ฺd‹cฆ•'ู™‘mง<ธ‰‘ฑ๎(v{ฤํ`Hำ๐|_์M้l.tป จื๎50ž�ิฤะุฟ๚๏~ํ/�6็๊฿"{6@๙™x|ๆ€ƒู‘๗;�ษ?๚‡�piiต�จ D™ ขใTEZjyิ่œ‚c”ษ.‡G*™J]ฃS!ส…ต‚†WฺฅNฝฦW…+ๅYงO#(ฅO;X™ฮโvt๕’!nไŽาๅWฉ้8จ„ช4mเ€aฟษxฃUะำl Mโ๘o‡ฒ‚lลภลKฬ�็k)MA{ฤ^†cfงSง6XKŸWf%ษฦŠ })ฏ๕gวข9žw$$จาYั9๊้๏M†‡pTPฌ:€ผฑŸ๋!11ณค™i๕P5rL„ุ!Vถ„ฯ™ฤsหฯา๗฿๚fj(kMู*๊—x/ป;๎Lƒ##รŽŒ1หbงรaํ˜Y•ธ6)K-ถ ฺึๆ–ฯ‘ž'5Š๔2๋O&ฝฑLลSc�47•ฝซใฏ*1$Nฆp|อฤื‚cZ�าฯ๏คฒraฌFพซฮj9 QG� ภ.มd@กฏxLฃc.QๆศBม1ฮ๊มท฿€เ…‚ Xฌ?}พMบ+ฤ�ƒtยNถwvงแว X—gร '๋๙#ิD�\ G‡อ�x PฆšR2ฏ�m ฒ‡ฉ…U]w�]ิ�๐ˆัnหsAo–&,ภ#ลQ]Ed" h@ท=y?mฮ ๓96ศขฯ ๙˜ภ{เ"2Sn ฿๛Œ๑p์ฝ๏ํ๏4บ|‹๏86Q4ห“Ÿถเ>�Hหuม่"—9ึ&={ งม&‘ึ5/ญ€pค{w†น&š่ C8�ๅtๅ5ใ๋9›ง^pฉลฬWทs6Wณ…†?‘9ฤ๙Ež5๎6ดCร"ศ'@&+†ีเ๓หา?�qบy๕ภ � *ฉฯษžžม!\8{12ฏk๔ึๆo8ฐลŒQย1=ๆผเ |ฒr็@�ƒ๔๑ีo�ฌ„ำhะT‚ƒi#>3Jžƒrฒf๛‘%๛B/ึBลกL˜๗,ฑL๑]งีฬลลoึ{9gฦ‡ปอฺZ ผ็ดDฏ„ L9ฺฦZGm9หœ8Aัv,ก5ุ~ฎYw3แ6L5˜ท…5๙yy อBbu… “28ฆธ๚qพvp\ สึะ๙ม๖�4ƒQ๗Zฅฅฒw ่m ไู6๋ๅฝํ“ๅฺ็ฝ”-ฉษftŽ}ŽkคE คŸ5ฑ๔หr‹=j„๓Ž4FงpŸฌn9๕๒–cqM…ฤT|6๚ึ๛�†ฑbvษfฐ๗ ททt๏g์m+เk) �: ฉฝ0Jh6†„`๔ืR†,_W๏ ฉ†๖ยๅห์็Rคง^ธอjuœ‘ษม ็cŸำถ‘๕cไRฦTHม7‡ยXcืWฝใ๘1ม4k]u:`6p‚‹ศฉCšูkฦuเe�ุฉ�fw๊uฮ"ึฉนซป—บ�F๎{‚�ฺถ๙๛�ัูIถช=#�d:Œ=มAูNฟ๚๋›`ฝ&`Šํ๕@IDATบDซืeS�๘๘jjญฏ‡5F�็เ$k๐โฅหฐะฅ[ป ภ#Ž`รn\�02๕ท๏_2€/ผY7{+ŒC—๕แูW*ฝ๎ฟC”ฝ๐; 3ฮภqบ็> ์Ÿฅs็/`�‚ู3kYct๒ช�๔,ุI[PF๙?ๆ�œt๚ซขกฝr๒„:พ]n™ี`A zภ&ฆW`�ธส—ไHเg€ํณ“3@0๘ฅ๋ใ่JKั28ศRx‹ะฟv�่[]`ิ)ฯ)”ยซ�ๅZํฅaะฌnwดaกœณสYœ่}3‘่‰*{V๐6/llฅ\‹`ฅฝ~„อืv ฒQR+O4ภฆi๓ิโ;C�F{ี์ BvฐŠ๐;ึฑiฮ[?"Cบ:ฟ�)—ji|�ศ๛2๒7™…ิใ—Šิ”0 yฌฃw๚Aฎำญs๊ฮm๑�๚'U”A„-ๅ๏fgeํ๘Hฌโฬฤyใ๚}N<1{๊/ๅล:e†ฝูJ๏}๐^z-]AoqFYหblๅ"๗แž{fะ\ญซo ฝdŸ K�๚œฦม/GษตR?สe้Eค฿0ˆ=ภม6ปพIณ6ƒภ–๖F�]œษpฃS� A(~K5ภHG{;ตษฬ^g�ƒEA0v‹ลx�sHƒ ด`ฉถJเS9ถว0�<€Žใ U`Žt+ว�( แศแถฮ–Bfภ^่ฤ[rdษ"I†ุrฌ}ผฦF�๗sป๐l.๎e›boƒศKXGืHฟc ึŸ“}ชัu–โฌ#—{ุoวลMฯNg ว๒3฿๚๊ƒy๗ฺq„ซา๓ัnนพTq?๛›ml็๙”ส.ฯ#k๙)�ฺ์=„N:R้ฏสš๔zีดฏ๊j�3š ืSlรM” gBฝ๎— ^Žืๆ็Z†i๐��LณLd+˜ฐศื2ฅ[๗๎< !๕8๚–๓ษ}์lUNฎ3>vœภ๙aุย๊šๆ4:-5€›Fม„ว่€Š๋M{ั�์ซ�ฌฅ ฐ์bถzf\Oา๋๘๊”pฎƒบy• s@ั‡% ฤว์�)เซ#.๕#G�Iืtม€:ุ?Gป4๏F7/ะ+ๆ?ฅlkM๚๋ฟ๖7 ศ=gŽ฿ฦ๋๕›Ÿ0Ec6]8s1mจงงเฒ=ฬ?�$ฝ๗แ{เศ ฐ_žฐื่คบV€W(g{.คแั๑๔๎;ืา์ิb”ƒฎJฃณ“Feฉo ŸใH=OmฺŸ �วGใ›%ร �PW…Qฦ๑ภ๙ฒT‚’จ"Hึแ2ขƒ แ/ย ษg๓ŽฃฦJzZ1๛Œ ฐyd8 ‡yรq„ฆ…… ๊ŸNฅ'ฃฃ่OR#‹Žฦ่[มd)มœ–H”์��ป�ฅ@fฃœบ?;*Kแoไž t๎�ฝใา‰โศ`€Uฒdl8P๊แ็๔ฯbทฦR๚ต๋ญฑqŠ]rซ Š๋ธฯUhyycESกศฑ:ฌตณอ*h์ฮัฯใฝyฝป†ิภJ™”1พH(๎ฉiea4Tะฒ':บZPV+Œ้ย่าั�๚๕๘์บ๔W��ฟ™~�๗�ušŸ"HqDi8uŽ Bc†2ฦฦl‹๏eฃQักาvฌีดnช฿ ท”b`Hุ†ใ๏ธหึต’L�€ศ�;wAีษย@/,Bษdk[๘, tCแ๐ƒใv็ีŠg6)Ihgฏฺขค™ฝ1) Gƒ …?เร4Ž5œRึง€ขขถoz,๖…—"ฃ(KjŸ ๖D{ewXๆ" P\Lน ,˜ซe#Ÿ�‹50SแuCs‹ ™,ึIตฑุ!†� ฯ˜�๘้Tš$ใp๋ใ๛ฉฆฃdŸ=P]ูg)K๕ฏ�โ›้ฝw฿&ำkŸห็Dgx6ตžภม~"�6๒Yฦษ*€�x„>v๎5ฯ™‡&9CQFK_,•Yใ์ฌQ?^KเX‡Cณ-3ƒ๓_[YŸ= djลqdyƒอEฉyJCZ(ถ‚%ฑึ7pg›้ สlC–‰Nใ>ฬ*๗ y(ไ}"ฃ…\ธฉE6@Š๏g1eถV‚5‡๎mYQMฅ^ิN�ฒ ุ^‹Lษ โ<9–ฬ ๐c%รล อfmR"ฒ`ฬดศ8สž'ส่!{บม^nฃ—ฬๅณVœcœฃ ด๘๗ท@อไ๕ฎฒ�๔ 8›J%d“xY�n‚‘Nฦ˜ึ%’#๎[`,‡l8๎’ทไž1ภ8q6๑ำy P’็h[šมD>K0ฎวฌ“K ‚ค๒fุ_el—๋๊จ๚Œ{,็\fj ำใ9ัีXšeฐ“xอ๗o๐Qฤ๚dุใc๖ ‘l๏๙—_ŒQตŽvฌ€ฝีFฐฑ…S5อXฮร{:๕u�๑�“G‘ํ์HR๔ืื Ÿ๒{์“:็ฐย}ะ a๏๗ Y ่x�ho—์c ŽŠิ� ™๋}kฒอ8Rิ�บํ8›6œงฌ`ฆVKƒRหช๖คต`”ใR@—ชV2ั:๗–ู�ฏŽN๖ฎ฿ุะC˜Jt_˜76ฅŸG–เSึ”Kz8™ฃะk‹šเฒ}…าŒน‡��KPfa.ัŒตB๐ธ[gqy!ฝ๔ยๅ๔๏��๏รhขA#2.=็P๕าุGฦ:เำq3่XŽ่๕šsซ{tZ#ำOำซ�ภุO�พถฆ&ภ=d[ˆYอ}s\‹Nฒ|IVร€@–๑dฒa@eil๖ตม็�๓Ÿ{#˜1Jษร๋!ว๗๏ำ—=เ็LNOค๚\ภkk}gฮp>ษl่mฒVาภƒ-เร๓š|๖TงQJ้™Lƒxƒ$ฏCเ@`วฟG&S€Ÿsุศˆก[๗ฬ�xํ _๘rM–‰๓๐ไ๑#์ห5q~„ ญBUงŸเฅ]ผeำุ(ฬn๕UฌM=vั�$ ึ็่Lข9 ฬT๚ฯ2’ึš๖YำYต฿ˆ6ร๛๖>vy/งว(—eฎ—พ†฿—`อ๘�sj๐พFึr—5U&]ฯผํ‰มžZไู E+„’มใWฐH ˆธึกวOำ+W.P“(ภ†Tย ฐcyิ๓J› v--ไม ๅราFx�%ณื๛b6Ÿ”-'ซฉXปลฯปdks่ยบŠืy&ฬ๐…>!รผ  ’�_โ๋@ฏr�‡๕-_์[4๋Eท:j—s[(๋ฝ๛{๗F[wˆ๐8บynƒั}�ซ‰็๙�‡zgญกŽฟ�f๊ฃl`FJce}œลขK-๋ั๗ชFฮk>eุsร์ถภม:T}'t)?ฒc์ู Oมje'Cไz�B�*ณง~ำปษ32EŸไlทษ1๚. ฯณถ x �,หŠสุ�Z&1šฮž l"มภ=n(ฮฯฑo|๒พ :T�e 0M@O›แ๓?@V๖Dเyเใ๏–ร(–S9ฅฦ`]=ฐO’B9๓แ{๓ข83‚MŽฏิฮi/ชน�Bzบ๘~Pๆ„ซำ…NDใะFz๓”cฬฯQWพM9-พัฤ,ฅ9๛3t:ฺ1{ ?ฉn=fฅีKk?$I`ฏ''…p“Lษฒ~ศr}€/œ/-cฺเr›vฒ9ฃ{ใ๙Q‡[วn'™ฝ2W๕้M้š9yˆ�โนžƒ<€เ=�A€ฯณh“หT@Cอ#Y’„๓R� พั Eศrฯ‰๔ฦ—�Œฌ��งwาฤํ‰HLพ๛ƒ๏aหจซ?^ฉง๑#ฏก—ร…Sฎ”ษMฮ-`๓hŒ ๒lf)�ฯgœaN*}ยVawYRpL)†็kžฟen=‹ไฦ๒าฆๆœบD?Ž›5ฃaฒฐิ๖`��ยŸ_กฌ๚สko0‘ง-๕Ÿ่Œไ&�ลนุ…1ีC@ป] ุุุ �”_๙lๅผžLๅ$ฎf่+!(ฤต– c+ัcg_>‡ŸD)e$—ฒ $}Xำ}สผ๋Z๐แv’ M++"IิฐŸลfl I(ฐพ6qดd๚s,๘jLฐŽNณห@f๑ํ8O–<ฺ�F?O`ม†ช๚ด2i์1e2ฮฤ’ ฝ~};Yว‡่T TžUฒว{๋ใหlCผB�๕U์“ฤ ‹ศ~E‡~Ž:‘็X&ม39ะGŒh=&NlฦoVc�+ฯ“dไkMŠุษั�–๑qโฑiฺ �—ธจ๚๒ณ……�๕ฟ�[ฅ๛๒Ÿ๐@�๐3๑`CJ�งฟ๚K�๕ะะร@“ฉrA* ห_Tว^‰ผ* nผจdฝxท ข่คY‰jะ4- gวiŒ4ญัืฉZ;฿ฅHJi้๎๊ ง4€`ถปงฦไ):ณืะญvf้YZ�]ฃฉM uY( Cg;#mฮ{๎3e„ภk!MNNA[ฒ2ฃ๚xก5VัMUป)�ฤะQA"า†ฒ(U๎*๊wศ๖ s#ณผ>Kถฆฌ”ั->i๏‚#ง<่|X฿พJ3ป-Œณ]Š—๋รฯฒ+�"มิ๘ไ3‚จq๔(๐@ฑdแD่<"Xฏฌ“ฃ"{@ฐ@4Z#ƒMเ%:>7‘fจ‰R1uNฝื<๕ŠสฑSกkคผw‡฿5pข‚ฎา๐ฬU tuw…1ธ๒ฦeืบศ�[f0<๒‡nƒ่t:w๖ลt๛ึอ4=�Œ๗ณกภ —T :T=+ฎCด5Œ๒apงL…Šฯใ‚B>ฬ ผฒวL,Ed=*QฤลผfDzƒiŸŒ€Ÿhr Hฦญ#W ฅุฦxaXD๊ฉโเ‰"CY@ž:g‘�็�ƒvศSฅ‘{฿๙ž ็ห๋>"Kด= Ž`ุŒฒ๋YJ`o”‡๋*Kม€EtMmฮฒ‘)dณ†ฎฑ2๎}›๓sbDQฌู#œวYภฑm›91ฒm}ง˜:ลรt๓ฮm28€c0u้ดฯ|โn๊้O๗๕ ะฉŸ&|งOŸโณkาำ'๗1ฐ๔๒ฅ*�๊œ๛‘แc#$ƒ*ๅภ=2ธ0se j& ‚**F *ฑฮเมล™Z32ฒ‚VษF ๔YnSรู๋๋ํ#ะก†ฤฮ<ˆi7‡ป~๏~z44อ{ึ _œ+dร{๔Zœnเh ๗pDpพฌuu์ชrข๓�œฒํ›yฦล^[3์zmใl฿น}7�ษ�)ืฤ๙ว `cข&ึฌŽ}์่-ฤ{ี๔กœhล=์จูฌHชฉ๖ฮ+ๆ€\�ฅฉC๙n)‚์†|รFu_a‘%YDฅศ<๛ƒ๓/ุc4ูcu‚—7เlฤ€2Iv€@Ži3ˆฒฬ๊Zjcฏ,kฮ "ใาน„(tซ{้šฤบจ0ธา*’:œ rธฯYสq/เ˜dใะok8ๅ|_Ar][0Zt xฝฒบƒƒ๛M๐Hvธ "บO ฅ๔ึŽ๓่un!฿๊K]d˜}๛[‚cว‡บว{7 ๙“๕ๆ์ƒ3$h๒ฑ~:่}eH+&hCP~D‡์zฒฃœ|— ค#�7เD96ิ’6fg0ฬuณLF0ล^#Uœ?3นN>œmjmc��IบQw ›ํyฬแ˜๖ ‘^'ิื�MWะ+ฎฉใwGษx?�ไ๒ ;ห`‡k{o3uPพีH64�„Eฅ$‚ฌ๐ูSgาวฝŸ&‡hศ๕ˆฆU์�รGOhภ๕˜ ฦ๋ฃื้VืjK๒ิ_๎[c uาสŽMฮี๔๔Tšเ๛อ์๎R/SZี•~๐ึ[WdSaƒุe|“เAภr=ฒวภ ฮ~ฒดวยตต1K{d8‚Q3ล๕8ฅอ4+ฝ๔๊ซao฿ผลDœ้๖้๊๛๏ mkI�คว‡zR�#ต�ฟY2ไ~€ศ=จ[b์กOๆ=อ๓V�่๙Tฟจฑ๗๊}!  E์ณ โdฉƒ์ฆ�ฝoฟ…ฯB่M๓C3ไ๚Dลœai๒มดฑฌRg�_ภฯซˆศะ� หˆT'ZV8ึ๊flฤ"™ฮฝ6,Aผทลrgy‰S[ผ_Mฑ๗`ยมฦqสŽ~G๘u�K$wุห` ผAฐ}๕ …Yำ๐I`W` ห้P?�‡fฏ๘'า�ืฦฦั#ฌuฅ 2๏Xg๛Nyvส๙\ืOภOปe[~&็ว>ั�?ฬQฅ6 •Ii ฑCOญO๎ยŽs›Ks$Œฑซศ‹Uฐ_ ฐƒ์•๗ชqqO=ณก๛‘_e[ชwฏีo๎‰ถ*~Fด'›๘.๎ฯs_@ Gฤืไm?๛แ๛๒oฏอ�$*มCึมฦŒ2r”ลd'หuถแท3Rดณ—FฤฐCIFษZh5!`ฎา:�ฮง,ƒMJิน(#ฯตต„}›�<๏3์!ํุlมhG�hึฤƒ๗gPท‹~�4๑ง>ะŸื(๐ิŸฑf๘–‹h๓BVgk่}สก๋จ�VA3=m=lœถธœ๛๏ฤnฟ๘สK\ ห0ข็4ำ.ว่�l}ลx ึ>ฎอฯPfgaeLMฯลgษช[ฅqฃlš๕Uqš2๋#ุทKA6๋u๎�Yฎณ$}ยd*งํฃ{fฆŸ!CฃQา•ƒU้ิูฬ& J`ธxFk`;7เ |Z๒ุสฯ=]ํœD€U๘แ6iทŸ‡e_ใ“ฑ6u่#Aทbไฎ!šฦฒ;ฤCU4ๆ|O ณมงิ๒*‚U›a้�้ะ๛\–&@L}ฌS%ฌ”bhฺ==mิฬ๒…q=CVก‘ฬƒฃ'qBๆ๖1สล8+๖ ๙โCX†Aซm้มภ/Nข#u @Pูื<„ต$s%Qi—’๎รฮ๓[๋t4็y:ฯSณุ>ื†Šฏๅผท”Uฦ๙ภ‡3%€& 3ุ5Fฯ‹;ทฅ๏~็mF$อฅ:ฦำy–Ziิ��œ^|้<๓�ณA,4ฺกF=Cะšๅนฯุงๅ]ฮ™J�ๆ’:๎สบ4x]cูtส u4อ0วdน฿en(Š6ึด{นY'œ86้๔™ำว6๎ ภอสE์K฿้sฉฝ�5ฎตœj Z๓Žตr‡Sฬ๓ญ2:\“ ณํVา~=kฎฑ฿•ห็ฮš๒ูNถ๛�ูณ!_ณำ๓้แ�ว-๔hภd9๎ˆช@#ฮ2.xะฺาFF9Œ:T๖QV‡ๅ861*@v<ฏ–ŸH ฎโ ๋0้l๚{‡k้6มr `)•™โcฮ‰Y$ATฉโ• …d=^{�ตt†ต๑ฺ๗ศZบcถดnูm]dmPaO!ำfg ึt~”ณฎส4’\š โœเ๘๎B›v���1ฬ#? ุKภัิ a฿9_ฒ)Rd˜;โuฒˆคGขGค‘—’%6ภ๓L๎๐�ณบซ€=สกณ'pฤmไื�฿g฿`ตo`0๕๕ @(HุIpป8K‡t€ฆ&(ข–�ธๆฆœ}m`ฎSใ)ั๐๛฿>ูฐ:่™…่�ฺFšI่9rภ f›Œห>Jค}�Fy’T^พะูP\:่ฒNค�็tTa'9ชQ*ไ๙‹/…�•�?p"ฝIใ,ค‡ส|Ngฬพ;๎Qึย๗)KอRฉ๑‰˜๘ Žาqดมๅู—.2ๆท=ฎใํท�sz็o!q”†ะ\3ƒฬ?ฃำ�า ™™kไ๏้่(rฆžแN‘9๗Mง,เฑ๖์ +�vัKฃ7ฒดฑบ๐ยx[œ๔ ๔ภื™ฬ‹_ ึด ึ�ุ_ฉ›_๚๙ฏฆณ8ภ*o›Bึcง&ฦำ์๘็ูTN7ษvw"{f ?น};š�ฺฝ�†ฅ‚<:ฉ๊_ํ… จิt.9๊ydŸqํ‘ม „e€5ฦŽ�sเK!  xฮ{๊จoิึŸ=wc–เ๎YL‚Xc��e๔Q{w75�_L/พv%™ac9ƒ8รพร0:FูkSด…%์ูe๗�ฦ˜›”ีX๖r„~+แ<:~ืIี๔™)f<;๖๐Pื+ƒ8จ ฬชฏ�๒Zีฯ>ิo&�/ฯด๗ไZ๛w฿'œož“v €xญ~†๖-J0yŽ>N`ขฃตอ;d}อย�๙ฃw>เlร(<ดๆยZศ(�หๅy‰™tiฯณซ๏๏d๔ูƒB฿ฃ{ฐ›๕|Bืบ๒ศึฺCลsh๐ooค†Yi่ฏ_y#€ว@?ืทผ=ท'#ƒL)ื! v {ฆุj =‹๊-Kต�|zณ—อ๔สย†‹r๎๑์ว�ภท“ๅม๛ฒ6๊๘: D;9b฿ฮ๕iำ–ฦu ืฎน`•พ6บDบŽ3 c๙ด7ิฃ‡O˜^5šn฿พGiฅ#ินl8ฦ[—ต่๊V๗C�แพ �h{ช  ๔ฏะ3๔ฃภ—ษƒฒ&OD{ฃผ�๋รu๑=,SWzญม A@†1Wตปกซัญใส[jฌภr๋๓"น€_#Ž๙[ฆถฆcํ(<ุ$์ซ=—๘>_๙—มZ?ๆ่Zํง>`๘p0<หŽ็ๅdร ผym8็+Fcืึุ/๕GิขcƒิO๖ำPo�_"๊�๙Lฟห*xชYฦ';5ฏฟ j๓gD ลๆŒžƒิXฎAk”cปร˜แ< *ฐฌ +ว-ย8ฬT‘L!กง�^^ZL~�Aบz�jšž#s฿˜^x้cึ|I fY#งฏ™…ถ๘ัใว41\คแ)ฌH�฿ั›‚ฯฺทBฮ”�,,กxแยYV‘^“›$†‡้ยyสฐ•ผŸ บฃY;6vaป+ ‚dQwG2ฺ‘NŸ„ํภ~ูร๓งŸ191#Š อœQzŽ sLR.โ��wอ๕RG�%๖ชพ’Zt† ฐ€…vfvq €k3ฦ:;2\9— ด ธfiส:ื‹—รy†•๔l˜จ5v)c} ์�“Š[่€MุY–&_Fฒฦej[#ษ%ฎO2ฑซพอณฑ๑ๅ‘]ž๒กฟฆ๎ั3ูแs๕ู|ulงe๚€‘ะd=”'/๚ฺ่‹EdหI ‘Tฮ+ไŸ‰5ศ’ื๏{ๆ�’8ผŸ6F�Aฦฑฝ� 5K~ดฃ8žŸ/๙EVA๏ถฯฟ๕�?ูธu๛ว๗ฟ�๕฿™๛้||&€ƒใีี์o�ึo�๖ุุ่WŽฉEึ์?#ƒ,bฉAฒ๑™๔?ภŒjž*_ใ> ดv+(๐:ะท ฦjv†ฌB็ˆ- ŒHp# 4ŸZ ฅ4PฯCi,j\ ะ0:ิEฺเ็๊อ๋4๏ขม ใฦ™KปMfz์{๏u ู<)บiลฉ๐*kกุ"ใ‹‚S!:>ห€J”ฅžsเDซกAI�ถผsyGศAืˆถฺ™}xd็k‘Z:‚Cœ็แ9Š็|๊0ฆ€&ัค-œโิq!ฝy๗“๔๐้ฤŒฆ,†LgญนดwkŽขม๏๋ึัRi”t*TฦึG์ะZฃ†บ—MR ถ8๎|็ ๑Sิ\qbš์ ืภ๏‚œ+ƒ7‘N<N-อ๕J4Sฃ~บญญ‹บจm€™œ‹้ฦ๕๋ib|C 5eฆ"0กQD�“—l˜wBY7u๖_ Iใํ็;nษ‡ O%eถ%j|E�YCg๔Vƒาฺˆฬ์l#† ŒM| u1g5ฆ›:คWํšหG ธ+ ’ต"s%4AฌNƒ�ฐ'ุห=่�9”ณ๛คคณฅฑ๓+ุ3^ถฆก%UtŸCt1„หsฯฎ;ŸA2๐,ร‰าYึiฬ;CyzฎŽE'Cว"G]กŒ“็๔y็QวZ๐f ฦsะdEq๑้ ^QฏMำžูฅ\บu�Iบ{sˆ๓•#T฿Pž.ฝ|!ฝt�4 ะn2•dนมŒCฮœƒผ๑ณ9bCc3œ5sšb”ฃ3 <ฦgE'�^ 27dม์q:9fpอd่P)7�‡จuD"`ร1ุa�ืกณฯ$Mƒ€�ภษษเม็<œ|‚&วใ0uTผ๒สๅศ m"NeW‡ะ&Uส ย g๙5Hy๖‹jQงนแผ๙ž"๖  ey€ 5รต฿ฟ๗ฦมะ9ส�kG๚s^ฆCฆX[kƒe>ดDๆส๛วi)$+ he)D> ใฤ๐|ๅส`฿Ÿl๊^�S้ตฝp-สŠ93ฉw` u๗๖…์ไ่\เื ่hณบพ~ณn–•ิ๑๓@่‰G"วสูŒผ็มsa€gSฃaธ3‚e8-(Vv๕รเM”qn4ž�›‡๚R0kงช็ฦr k๙ํ๊^ฦษ�)แฺ�_งร˜ญ7 ฅL06<�_์_ฝ)ศp@ขมž™"[ฐ8H3 P"�‰เเณ�้ฃว้๎ญ�i ัฑ’ึ›56[พ‚S&�^6Gi†�.ุ ฉ’๙๓L-7๕ูีฐว 9ว%”Q”U ศค7?๗:ใpO˜๖c[ & รฒ‡Aฅ๔๓น&ƒŽUจฆ๊*�]f#๎\๛8lหเษฉฝQw[ถfs@uพ๊"LฐdษตSVู›วษฤ_ฟž@G {2nŠ)=kฐ’Z้๚?ฤ๖ฬ“ูบO๐}๛ใซิy?MณSฑN:อฒฤ8#:`ผm์ฉ๛์พ›}Cี๑๏๐}bฏ-9ฒนฟืX >์SZ'{nะE9ikkยUง๓/ผfงh Xnv่s_�k ปูy2>œOžL 8ึ�‚’$์๗'ภ๎นv:ส๕ซ‡}uข6Ÿƒฅn๓:ตฟfc‚…ืŽณึฺั๓=ฮ‹ต�6(ณ�หRV–5ฺ!ฆาWฌใ}t‚๕ุ๔บ4W๕ฒOmฐฏK—.v>ฃŸะพฮasŽาวทรˆOaษอฝ[7 9Lฆ๏`ฺฯ5ชCg™u–Vฝ)8…�ฐpŸ…'ฯEi อฑq๎C4DD�(C‹#~ฏ^!เ�e!z ภดท~๙wงŠตะ^๐?ืG๛กž๗ตฺ^ม-ํุŽพ”�ฐ)่›๗๔c฿Q8งK€ห•์Gถฒ†€m“e)ฒ๖gxkฎญศ—{โy 6c์ษ’k�$;ุ^XฉBฯ/…NฑY๓ถeM�ฏl�๘ะ/P—่3œ9E๗ีKก๛?yŠ�ษ7Lึ™W�/ํb�sมผจ็z:ฟ>จi|บrXŸฐD bซkbX eฑ’{ำทZb_=yฬwe‘€—G€{>Iรใ#่ล,�ถงฝ#tZ4ไeํ-ad๐น iCบบ๚ุ“”๎}๒4=ผ7ฤY˜ะ‡yม!฿ ”ืMœูฦ๛๐ศบg๎‰๖ุ5ต‘\5๗๊ฮ9t›c [=+‘Wห=w�=งํสE~ุป็‹ฝ็}๕”ฃ2๖[‹ำxุHm“`ฝLร22�ˆO์ƒ๏ชŒ๙^>ฺ๔‹ทa๎9นษิฺiม”Jฎ1Cยฤ๗r?ใะ��ˆ�ฮ}ทb๗;�Rs=ctI*ศฺต4F;›กˆ๖ยO2${~ฺCAํ?หไ๑ )๓P�K€eุ[๏U๙ึ† ‚˜ไRๆ 2 อ๛๚pต$0๔ฝ5ฯ@{'๋Š/Œ* ?ฐปงฤt,ฮv3>ๆ็พ๘|œบ(u�Aฆ๕“ฮผp>}๕k_K๑ลgงัmก<ศิJ‚ฃ†3ฑFษห&ภF{3๚™ฒ…g๔็p“`)H4eว*๊วy�7ํœ�1ญ2Vqด+ๅœ'-บv{di2่ธJ’>ฌ8อuWฃ‡ยิไ,๛‚ฎภฆ9qalx‚>ุ่ •|�$�๐วื๏ฆkc>นฯพ0.บ‡‰.€ำnšๅ๖กqตk6Œ—ัเX๘ภKด;z{ั็U๙เ9Dร๓ฮ๓X—%z@lฎ็“๎‹๛ccไ=ภ๗#@’ล๊๕6|>>‹} Nž์cด'ฌ=โ˜]คึลษ ศ†@„ฑ˜๖^{ลv๓•O:9‰มฤพž�ƒฅ ‚๙๚ั๖'0ศwญีฦ‡ส‰�Zศ:Œ(ืฺ$ณ`ฟ2c9Œ๑œฟEภ8>ะ;0&ู* แฺหh7๎ฑฟฅ.๊m?7t7kเg{†ั+VWWพ๘ƒ๏ฟ]�/พ๑ป7๏๗�]ž^ฤ{�4=Pน�e?ุŒข๑�“ฟ๔ํ?�ๆoUฃ‚œZvอฮ๊˜36ษะธuตาxแnฤA๑ภูTD๕�‹ฒ�W็ุ๏:B !B ฆ5ฮ Y P8ํ๙ฦ1ยi}šฉโ฿ $;‘#3=†๓๖๑'้ฦ‡ืา“ก˜Ž‚บYS‹Cร2 J๏�่ใ4GƒฃสฺNจ‰ีŒงชM}�อic�…cลAจฑ�รธ[วŽTF 3ิฑฺ๑ืฃนมgŽŽF†ีš๕๖Jy1ธS ืpูTฬ –็หฺq๋žอ์lFภ‡ฃใu8C:r2?์พA฿…5Œา>ธLCอ31†ห&œ˜p�ต”,M3ฒS‡u6{n}wวฌrbณมศ�เ )��O‡C'฿ฬ„ฒั€|ฎาwdC๛ญ๏|;F0j\x^1A—ำLNs.ฯž=ŽยA0›ศภก{tˆ4t:’ห$lถšmdธฏZ2$๛œ1ƒD3}ฒ1จฺ�b–ถู[Y!แ$Œy~tข”รš .ฬฯS&ห€ฆdรcขิ้ฤภI…ฤhZษ๓qgGฝ๐๊Pผl)[๛ผŸู€ม�#—d4C๏๎้ๅ์ู,๓˜ฆ“4Š…zฬkช,c@*รIฬฐ>ฝ'N2vถ#ษต๗๕ฆF&มT"Ced ๐ิ@ถฆ๏ไ bS(•jn9 ;ทr๋ฝz–Xe`ฦ(Gฅฌ‹zธ |M#ฃฟ ฏ�ดsjjJ�dบyํFts_˜fส�ฅWฯ�ๅh347ณ'าuฎมiฑ—…๛j๓ฅcFaูษพญฏ-�สฏ�R:yช]ถ›.ฟ๖ ๗ู๋+[Ag4Ÿ™ก�‚fท dq Š>-)Sฟ๘ƒฮฐูa=๚๖า•+Qโฆ“l�ผฝๆiH;Npm๙ฤ…W_Mg_ผu์๊?่)šพ๗๖;i‡> fไ‰_zํU์Y3Nณัqฤบ[SkjSY!;C[Wnา<งpธž9t‚nQ�มหyฆ+ย>J�v bœCฟƒ,ณ�กGmXป ญณEจ†์าDฌตึC3}sna๏ž"?�œaยA๎ต%๖ษlฃS ,ŸX‚yฤ“X‚!ฮ˜ฝ ์™`฿ ฐ5šMช‹ตฟ^ธz@;:71สูฦYCพNž9Eใฦณ€m้๒ๅ+IPฬฏƒ#@\ึฤ‘lf€ี‹>‹rุaไ็U{พ…m[�^DWใ ณซ33“ๆ9;+dีฦ'†a๓๕E€^ŽMฒ์๊�… กณฆธงZTq-ํญ„ญภ่‘�ฬฆง๊7ƒ๓์nืษ~h�dn‘ ™?‡œ]*มิภ˜่qจ“+H@๗ญฎQงธ‚๖๙ J›๓iเลก๐oฺc๗Qก^๓�๊[ผ (รบบถฒ3ึ}nOW7})ๆR–@ฐ`่ฝw฿O3ณ$�BTุ^๛0 ^+๊๕Mศะง๐๚‚ๆอ5\ึภฎหาLow‡i ่-2E๔…เๅ์;ฬ ไ็๙�ธ?– ิฺค๏ิ`0,แฤ็อธภu*ืข๒|…RCนV 4s๓Lไเ฿|ށซฃNบ‚U/F?ึ[?dŠ~(3ฯ&Fmj›o^ฌ^vไ๋๙๓ฃ$ห๒ด๛?Iณุ ว-ส๎ิ’๙bนภ" _ Ce'๏ง�ฟ•��: 4ษ#ƒl?@๙J4ดuฺQกฬฎ�� _Ÿƒต31ฅ=+ยญ2�)P75:Jžสbฺ๒ถž{ุ'‘ฃ>Vฟ„�B.\๗]Pฬ ^ฝ, ๔Œพฐ€ณ๒แ>ๅ8^ภ๙š|มํแฟ@Šื&Kฦ฿)Gพ.Sืœฒ]g8�M(Eœ/๕“‰ๅ�ืฑ๒d�ฬค#๔k~A�kช^pF—+7๖ SGุgสๆป๚๎‚kฒ dงํฐGสบ฿u๚bสฌ2cOYช๙ ดŸŸ/้1จ๓๓ฝ๗ธ/๖'XG�ทฟำง.็ฌz/^ณ บา,ธ …๋c/XwbฐŸ�งด^{nขฯžJL้Yเšžb`ฏzํธฟ๖—{œฎ}๔cส"gb"ูฌ/ว$ฺ;mภ—ธ˜ณŽ?Œiๆบ฿h‘—žN0“นๅ:๊ฃๅมce™ำย>นoธข�ป:t‡ƒคูภ๒]Xถ48„้81>Cษื“4�dšฦ‡ ่ๆงุšณาKฬพc๖D๑ ŽŽ ›Œ—……้�e๑?[9oŽภกคz–~ ฐ%์5@ฝษXหIํ“P [‡}6a67ฝŒอ6ƒIฬฺZŠi๏ฏฝ‘u;๎L์eฐน๘`ฑ'6cถฬYv•ุ–aL"�6\w�ก ‚>™™^ทฑ G๗Cท#Kฒ๏JูKหญดUN3ำ—2ะท�ยรฑษ๘€P†์`Iร&Ÿ๋Y4fูภoUn๘??Žฯก<ณร|ฏภWคา6>S ฒŒ 6ไ` hMJ nฒัyฐP2“)x|ํ๎�›๕๐o~๏รo|ใถใ~Š�๏ฟxเเ/|้ฮ฿�ํ฿๚นƒมฒ:.#๐Gด=„? ŠRีJภPJ+2ํกำQฒ“ฐmภค๒PX�ššš"Pฤ ๑nๅdฌ*qNUไ3ฮg<žSžr(vƒุฯฝ๙FใkœŽษPo@ำwืจe$฿ข้G#™ผ ^ฎุL ๎๘,ณฝ}ฝ�๛ู*)ŒืฃผšกŠฌ5‡ร`Hม-‚�^]๋ˆฒํ ��PV•ัตดom~:ๅB:q๊|8“๗๎฿EXEะ @ฅ6๘๐�9^_Afธฃ?xฺ2Žแ._ยA’)eฌ™hคVFฅไ!ำV๛ณ,Q_—Eัั(Zใ]œ@)่%ิ–h�Iีว*ซ4tฌฟMMd€ธฦ:ชfขUไ:9Žฦษ+$ุW™ชˆงX—-M��m`ƒ4†cลิddฏ๏ะหเฦต#@~<Ž๑žHScSฐ Wวj0ฅVU  ร˜pญ�C>8bQ mจ๗'Tมl�า*๋dก‰Inย`hเุ<ฅ12ฤถ‚ึ"G(TL%F 6 ภหVkkใv0>8ว�๔8บ7 ะ`,ใไ ฒ…TŸ%27฿—ฒ‚ฎVšา4!+^ฌ—ภฯ�.ต€Ÿ;uอ=!—BA6ร๒๕‘ๆbฌ ฿ฺb ™๋Hฐkจาณ+q:[อ{J™'~�Œ7ช ลŒใชฬTS! ”ภ‚ L 4�c<เอ›าี�แำชR;อ+ฌฃkฉH/]พ@ทเN@9P|dZวTeญqwDPnŸ3†#d'๑t{่\ทใุฯโฐmฏK_— L]#]–—pอjน‚\ึJOto าํ n†งฺต™Z's~<ฏ๛\�gฏ gซš3ฟตฮtฉ่ิ3ฺU2๋1'�†Lž5๋—aCุppbn*€ภฅ•‘`ˆ1ื ำๆ๘=ฯค๋kณ5ง4H/m$#q๖ _,x๚7�ืฟๅiบI€`U‚Nฒก’tุ"ฮ�ณนq‚สi๎Q-ณ‹ดไ๛1ภ—แศใl็Gฉยฐ!ฐฎamํ๏๏6t|q๐tฎ2๚:ภPป�_x๑%dส ™๎cฎป…ŽL “Gฐ๘ฺ^'ุ็oๅeRaซ8฿›8ำซ้ศ tฌ‘ท—Dƒ+๛ุื฿Y�@Tฮfd u•�k๖~Z�ztH”yQปดU๖ใู7ƒ+i~™–ฦจS7ะ0`ณ“~WOo| Vิ๘ >ิ Oฅๅ็X๓�ฦฤ-๐!R�อ์YกSm:Kjร� mm๋CึKา2Nำ๖ฅZ”‘)๛๛8œ–ป”sอ๖‚h๏๎ฐ็"Cฆผš€^ฺ๘ฒŽ;S^I_†ึสt๙๕—gœ(/‚๎I#ฤ-2ฉC๖ ฑ|•f…ฃO‡ห‡ร)t ฃ๕Cd$‡M1๋,X๑a0�ศฯO?‚ฒ9”ํ{ทoธ Apb_~ํตpช Z `V(ง›ภ‰!;j“]หB์NŸ=ว;ฺe‹`ฎ‚ษ#, ฎ?{ai“šื๏:�f•cึ•บn่๕vะ•‘ฉ}�‚šc@์‚abหFtฌ ’ภ\๚c&ญ๐t‚K˜_dข ัฯƒQ–!8uBšฐ:wsk5ต๖ตฆ��~‚ฬ,ื‚ฒฤŸŽ Yม Ž�๘ุ(A6ตา�w๏ีci–้ํ๐�{๏3#}eyoบซฆ› g‰’#@€ๆVHะ…ฎtร™+Aร  ฬ@D@โh(Ž4›lฒชซชหฅฏ๔‘™‘แฝ๗�่yึ้”�BีDutfFœ๓๏�{ํe�๕ฎต( ดK๘๖6 4=gุ๛ะHํ-An7จฅญƒ:พHSYUš�๐Ÿ�~๊๊lˆFมttF#3ฮษn๐฿ฺ]ฬ˜ล๙]ร?&ะg[;zษฦŸKณฐ8,+yฮ}ˆ•’}ซใฯ�๕�gชEuฺ3ฃP‹ซkฯดษYๅฦSฯฅ�ิุ_Œs|๎ๅ+้��๏“้/%@ก�yี‘ฮf/ุ2๎฿,+tft€b&KŒ“rO]ณL?$;>ฤ�TA์นO]Lr�๒p,�๑�HHรูปDGปึดsƒv]๒€F(ฉ†เแแญ้๎ฑ>'๔*:Agู„ƒ2ใYึ_ฉโ�˜‘6ศ3๙ฑ IพV LJji\[ฬู>ฆ�ั ลฯ,@xNศŽZN&#็� ƒ m‰oFท�‰น4Œ_ตkฌ€3}ๅโEt๏) ่lฌ‰#ปฬ๎ฉŸ๙&ˆ๒^๒๘.๔OไG(…ทฬ มฝฐ9บš:tKxZnฮŸํก™] ๅuŒnE—-š่w”๐{;ิ›yอ็L:efršq„6ญfฬ๓b๔-๘�๖�(�ฑN}p�๋/ฎฅฯ?�"อเ{ฌะทฤ€ wPop๖{dˆclC.zฃฦึม�:KqชdฌV�T ภc๗๒ฐอ$ิ�= ;ฅอ7 gkไdช!ˆ\�@6ฯฏฟ[„?แ—r#˜'8_ฤg•U’iงไA{ษA{ๅศต|QŽ้zD๐„�2AQV�ฤตอ]0๊r @ศเ™ต�-ฦ=๓[�9ๅ ตƒ~ไณฑำYศŒm‡e'งป”/อhจผั‰—CJŠ๔ขิ�E0ฐK๓)Mƒ5บOiฤZŒxืษ=ฦฦ[W†O6ฟ๓“fม#รc0ิ`HcGิ๙6‰>ฤFศึหม‡7ก0ษkฉ-3ฎฃG‰>Ÿษ7ม�\˜Žำ3๔zaOdJฌส ๚์x=!.ึN3AjvŽาA๔ฎฝ๚Wdiตฏ๑œ๚ œฮ<2รQ/*&‰รอ\ุcฬ&๏๖Ls ุโ*`URVจŸ‘ห๋Š8G6’WVเ?เ+Sโ4zL~k3Œ๖™-ล๖๙ฯฑ—qI0๙ฝฅq#๎�E�llธโษ๓=QL�mาSž3Ÿ{ษ>:น๚เ๎อๆ?๙_�ไซ��๙๓ฏภƒ4p@เW๔G�๘�WณหK�q>3ste4คG@ศv;‡Aึ8:r-j•)Œ d๒œแmํฉด3หdถb� ต’,Y”œฦ62“5Pซ9(u‘จhPHP$*m&ภ๎ิ7ฎ�Š๗ฺิuNรฦ.จ|ˆu มถณSuLhœNU(e„า๚Iั;…ี๙ฝ*zqด|Kต€่ฌ‚z๕๊�Aี้l ๕ญ�฿ง_‡แ�ฆัV{:G?ค‡!ฌ‚s๏I'<ๆ—r๙* esKฦy5MLOsXช ๕ู%รฦ�ฃl P�‚r:$/Œˆ‡�C% Lสะืฯ ‡6/ค˜/ฝˆ›๋} xNฉGf๕4b("ภา^พัxŠu ‡‰๛pœฆจจXงฃฮผuY““cิ•ทโฬwงฮ๖Œz'�Fง‹6ช&ผ-พ< D ฤ�~‚จถ‘ห7�๒YuดDข5��k9JIGXdTƒยฃc�Ž™ึX`[วeร2๋˜Eงฅ๏ำ�ปˆ@ฃ EVY–} ๊‘ฉ}ส6คgaศvpPฌยไnพGPฟณ6Cณ/๚dT™B†rY„ชฦn้]ั๐นฮxw_e;”2าg—l�>Aข_*H๏ำพสƒNง๓ฟทW็ำยศรp–EY�์,œ�T}ผn�ž•nfv#�ธ>พ�๕ืŒbฏaภฐ&N"้=ำŽ#�D“ะZจxd pคฝ>A�%œซก„e3:: EsŽŸๅฆฎณ็กผ๕`w1$dอAทqคŽ˜L`ใู@ึ„๋ Š˜๑๐7ฐ฿e:้8KŽvำ่`le ูฏม–… Q^qrŠผaeŒำpอฆŸRT•๓e‚ุพฮ^œ›,šh2Rˆฬh[[Kt่V์# รๅKรฏ# ดlฉ0IGค‚ต0๐”–ํ�~๓อท้”Ÿ์˜ฒ€aG๎�๛ฆlฎำqgลR3ฒึ!ฺ๊่M�ภ๊qํ:2จ็R�… ะ๎i ษฺผ๓�ศ!:™ทyแ…K/แ< &bŒุ๛‘ก!J †ศšอข‹ศ:sฏfุิ%๓ACv-7rŠฦ6ู}หr่ฉฅฮxึ้ฒ‰ฆcf=ื6ณ3ศ๐ึE @™5ฎfอฅื�ู•ZZZCKู]~‹๚^o›ว–WืEฅ็ส,RuCŽG,zVฐทR,ญ4S32๒ใม^๘�Ž๚}$ฝZ๓/ฟ3XB–�Yx๘!3Šเ�”ซ๎็f‘{œ)๎฿ 8FยBcz๒8ซ†ๆ@ฯ๋$หฬะ6ฟ๒“Y๒EงB๏(ป›ศ์lš-[Ž_K�Cฝ2jุGู ใฯG๘|จฃฌฏ ‰ฬ›mV๖q๎t89[fK"8ภ+ำ‘DCQฺ_ยlŠอ‚ฌ๋5ใจœ๙ํ4Œ่bฏ๐ u|๓)ง\ธxGอ~๙ุ•*สGfBฦuฮ›hd�ึาžfH,{(A'L \YๆCํ0ฯซŒ๊ฐ Bู (ๅ‚‚๊6˜ณคNถ‰, A๙ฅ้%žk€•1yิ/,Lแ<ๆะ�๑Iฏ๎ทฃีIOŸ<#8์โž3IMGmyฟสจ_มฦยQ-ๆ\ สะ๑<•T์เ๐3ฦ'ฤ^=ˆัป6g-& ืฎ็sflฐgvOŠ,๕๓&ฮ๒ถชฬRAgžกฝƒ๕ \k๐ร’œ u3xฒ<œกKฝ1ŒM”ฏ@ษXy Cj พ ท‘s'-ฮ๏" Fึฬฌjว๒จ+ฯ็๗fยอlฎ[Bษšธวfฌ�๗<‚‚>่�3=œ’ะวืฏ]€รqk6}‘ }ขฮ)Pาึiห›ั�์ฟต๚<ธ๑ศ %ขุŠฎ๎Xbำ4ZœB6ว ฺ๘\ อ ๚Qษ�)K?'I๘1๖ฟaŸยfiสY€–เๆ�ElธiฆP�์น>Jฃ๕ัฅฌฏLAฯ%ชkฮ"=|ะ�่?K–ะ:zฒฅต1}๐�;๘ อG‡๓มถpํฮโ9ีืRG*�๎]c}+ืูฅวฯใ๔๏�Ÿ_คOฑ”$ค฿(ะm้T๔aU๔q K`R๑L๚b;๘Qฦย}๐Y๎fbฅ0%ร†‡๚…ล”.ฤ๛ะ[�>ไ ก๛ฐKฐผ=_EŸE?M_K[g’K*ฟ๚ู3แ™ำ๓๗fkรf๑3ม\tๆ’ิ@@#~y•lDภงCํ'�xJ-Ÿภ6zŽ�rฬ ื7ีฐ$Wชฎ๐๙d ๘sm–~ฎrแ™๑�|&็^ฬi๏�ฝ๚_๛n3`ƒy5&ศ|ๆL“r'0˜”aฝฬ>Pวo`|แ๒…hˆk‰A%๖฿�-๖8ฒืLkk'�€ Zง7ดย4lฦVรเXใุY g'ฆœ ‚,iเฒaทตE2Oeฬส–5Vpํ,R~–ี=�๚พ'a๘ฯ’๓œฦBMอŽ{ค\ฝแ๓๋ืYฒGยd?"Ÿ@�ยูณ\{๗มฦฒส˜M,Mž๚3ื^ึฎŒS{A๙ณt’๖xkw๛าภใ‡{๗๎^๛๗ฉaโ8`ฃฒ�ห�๔๗_68๒/6w๖+ฐ5!@ง€‡าเกC™้Cjœ 3ภ มฒYฝCE๗นiบ€’%S‘8ๆจ˜ฆ5 „จUm% Q ”4��/5]๔XKค"9EQor46ฮ๊%ิ 0มCขณvššใ)2%งgชซ ช#มwd†๘Saดฎ~f~!G‹B0ป๊—Šฮƒๅ}˜arz‚สnGฦnฆืฎ•พ�อ7ฌoCQถดuาlฏ3„yŒฬ๕`๛8รึ%›)ฒ>อฆjอญญA1\�€ | RŽ‘ท�M„ำl๑๚*R‚"H4Xnเจล œD)ฅ:ข…ฯ*UiCJgฐ ŒD7ิX+(^n*”ฤมัมQQจ=pf\ค_ D๘ปJB)GfTน๔(ซค4Gัตฺš:œHุ8E:‹๗๏>ฤ€?กŽหฎ� \K๚ค]%ฌ#ฅ“hภiงZBc่มผQY{ ฌ]ฯํ!เJ?๊งุ๗หzpม<ฏกยEGิศ๊’yEฮœฟํ!jจ.J=ื๛ฯค๚Zjo๗ษRX"b#!๏K'ทจ>8„fมlwŠsU^ำ”ฒสjำฮ๊\ša์5' ๐ส…อŠฌW!ฝ J๊ปAฉ9Fพe=๘~ฬ(ทNX_›วHIฯๅfY_#U5‹ภmฒ[๛ Ž๎,A�็_]O˜Xp@Ÿ ๖ๆฆฬ6KuPณXณรšpฯ:H6ื๒…‘ลกะะnob–ำcj>w˜ฤฐ ๓` cคSxส3ŒOภ2ฯ&ฒn@ฎcจ…๐ธน?6te%d ะัแืฺnณ7:œŽ:+ฤูุ�ค๑ Dn}Oศ˜ฉุเฺ‡ฬั™ƒvWO โ™3�™ภlmํˆเkrj22Ž;"c‘)ษPAu(4b�ฌฏฏ7ฝ�ฺ+์}Nt‘6๋.%]ฦรฃ๏า‚Œ5•™บJฯˆz Ÿฒ– ‡Bƒศ๓ฑZfช Z.ยฐแฉN�๙฿|๗ศศK‹์;w>๚iฌณ/ฒ T|ณเˆ๛จใ#TPf• �,9p�Vฆ๒ณุkสJไW�๓ไ�=F•ŽR~ƒ๎Cm์ ๚O@4:�]ณDsฏgi๐้3๔�z.u<ฏg฿�ฑขC‚s�ง==Aณ R™=๕ฐ *ุ›ปwn๕�เPงฒษฃutฑภ‹๗_ฯตสu๖ั…�€q€;|Ÿูฆk>“Nžู–˜AฮTึŽY;u“lJษp๚ู๖ q’ญgF9 ˆ�ุ|e��Ÿๆพะั"Cfsปฑ)™ูIzืิGFนถ‚27tฏตŸ๛๓ำ‹Œ6MwพปI  ˆ:ฮ3Žkv„ฃuฤ}eฒฃฐ(ใqำ(hvJผ๕๎DuPผ๓ัG0$์ท!‰!xY…Mฒ‹ฎZ†)ฯร่น๎XO?L๏�‹ๆ–ณd~ ๒ษฺฑž~ฉ๛:ปฯ5ำรบF`‰ม6dy~Y� pฒgส‘ “็ูgศลูตพ6 ›hณ6Ÿ36�สi์Oมp€็<๛ –ิr– g๎bjo๏„กมจ;tP5๛๓|เi8ฮF‚ถฒ_ด:๋๎ว,๔Ktพ��๗}^3Œส8(เผฉฏfq๚—RNp1zdไ๙s๖V ๋คภ('ฎ‹ S=ฃ&ึ ทฑ�‚žQๅJ9ม•eฯ3��ื{ฦนฉy��„u6ฤคI,N�ุ๓แ4MF<‹๗ บ V-/Hว'ย`แ|๐ž9 a็จฆLํ่™ฑแ็‘ด0ƒซ�tำฦุ1^6ž]ฦทvึ3 4dTf• พ ๗_็Y�่:„žฤv loฐฦ6~Snฒัcˆ€U)ๅ$0ฒ‘ูe2†์m#ต�6uk$ศh๋&ภกัp{[gน†I$›6็ต%v}g๊๖C!qZ@12%ฅžHีีLaA†,s๐lfi2กภŽYFG&ข$uีrdƒZVŒ3,8‚ฤ3D๖•3็>dN'18ึ3๖š=sล,>’ิใฎ‚2ุf1Ÿ‘^D์MzPะภฆฒ2lยfฐ˜|yฮ^้ฟ่‹tdLอ.aWง'าื฿~Nt*;s–ู๔ฝ‘LษL™™@> ๐ั‰œ�0&&FfขA๐ยฃ™Oฟป‚�เฉช•bXq–ท`ฏ h2j&(๒,บWาธ›(กญญื)แนo’^๙…ว0ุ๚า‡ŸผŸ.มRษ`v‡LŒ]จ์ู9Lาš™›ย฿ภw;„ัQgวฯ๒ฺ™†ฬ่ถL_ย฿ Lœ3"*ใต1�Šืซƒ Š,UP๗ป^็€ฯuZ”_๚E‚[๘7&'"€โ…2ƒ”?๕D ~Œณ\z!3๑{dฺZ�ฬณ›Eฮค\=ฌซfzษิแำ15tฅ‰ช˜[๊$รนlฮพ%I™ว๒U๏ี๚๗Œo?lU>K&ซภ„�บ ๕‹฿–ˆTbcฝ/ขฯข<บW๚ ๊ม�<_g ^€?!("P7J้มญ[7ำkฺีู•ฦ&Ÿวญ\ื)`M๋ v"๕รฦฒˆVmฎ�ษฌ+ม+ถAฺณเ}(ท>—šั'ˆ„?ำ—๐ุGLVlž �9VŸข{ึฟ3Y'่ฐอk๕{}&uŒฏั˜ '‚% gl€:8<สžฅิึ\จp.š7[BRžฌย‡$ุฝ`…u๔Ÿ•์)!ลrฮŒKรษ‡Gbึ2€M๔wพkXฬ�z_�“เY,.Wาวxจฦ็็ง่�Ÿื�;ภ๒ฎฒRภRžล๕`ข4ยDฅq]ฤF‚ภ\wv‡๋bฌTkgu˜€ั,/{์giฏ,yำ‡ื�ขy!๗ฮไฒั๕ ๐๙์'dาฮdŒLvนฐสขwโ=๛�ฒค^ัV„Nไ,_š<Žฦฒ่ง,ž™ํTณ(ฉฝ๒ู็ฟฟ{๗ษภ๒�W&โ๘>ฦิT*œฝ�G๙ูGญRfcฎฌซลY„fe�Ti+ˆ>ม€Ž€Œ™ศŽฎ๎48๔Œ?๏ู†Jlร7ดชœš-3,ศM:OตA‘ๆะ5ฅaใไ(ƒŠฆžlš]Oญ/ึศ์ฺ ฃฐ‘Dบณ}ŒกRซTคปฆuq*œ�‰™ ็šwb อCีึฑ50T,U"๘Mœ๕(๓�๛๗Q:�ฉฅนŽฆกP•dฯpwกD‘ฺHณŸ}t๋ ๙t™Žจๅะอฒุ0ฌŠRkwK:xถ‚Sืลฬ๓ู@o/_ธ@ศ๓ง+|ž X"(หํgi0ิ7 ™uKRๆอ<ฃะ7h�่A๓พ๗qะค\ไฐ<|Kล์๑ถY83‡ึbžBนซ๔=„P_kƒ)ป๔�pะ฿ตท5b�ฒp๊SOoTฐงir๊y4{™_ ‘ูnKึx�,5[�” €„oม็Fr`5|R๛‘d˜]๔3=ุ"–า๗d…ศฬฐ/ฅ$hy๖#ใ|kอภ*Rku8อฦ้เh˜ถpnv†D.๓ั"ล%ง4+%›]ลธจุM8P8P�น8Št]ๆูe0จฉ๗wQ4P‹ƒ�G คั+clโ1อึ๐]7๊จQ+‡(แใใ…xŸ3ฃ5‘)ศฉne�;1`Ye� ั@wm‡ I…fฝg&ƒKtิบ5Q8๘(Jเโ๊ฦดฒ3—~๕๗�.=]†iั›šjษfฆd�์™๓Qœ1–วฆ”ffUขHE8I*ovV•€€l4ๅ\€อฆไแ๘V๐,Ÿ�KใำOำF๓ฮw` ฑfzEฃ#;ภkํ๔q”ฟYBฯธฦฯ}“ฺ|Yž#ึp†v)|ว8๋€X‡dNณฃ‚p>ทิ?๛ปฏ™‘ผD๐A7ๅj’ บryฯk๏ผECEJpŒryŸญ2ข.P.”…œแมแd—~็fึศฒ<"(รx๒ฅ€@ศwdX_.มgc@pb�28=/ก›zmCฆถszไiœqงฬL }๘ีื_'เf๎=ฮ‰gฆžฯslŸ_3Y๊ถ๖Nฒ‹ิ5�Œ�9[๕D6A�`(�Š,J^ฤิแเํ๐�'PDsฒiึษ็k4ทจuœ X T†3๙๘�#ใ!ฮา\8,:1๕-ะ Hptํ/0>๔�@๖— @gั FงขŒ์ฌต’›PKqžฬ?yŠ �uRqJ ๗œ้jn๎L4ŽสEfu‡฿{๚เ๐˜๕+ใูํEฑชแๆ>ฬ:{6l`ธว๙uf}…๖๘�SC๎Ÿ‡  @]๋ZxN}ฏฮู:tM๎‚a๗dQ–ใaq|ท˜GถR๛บG�€ซ้�ๅ3diิ(…จ-G่้‰:L›K‘ฝQฟlp�ญฅlAc4 •Ž)+"g๎ม๖bฐณ~}@Jหีศ้Tไ๔่p‡›‘ฎ8๘ลE6|ต™ฒ4lH;fฆืส.็ฏ1}ป๔)k๘ษu์๒`ก9QCฦ‡ลmtลำ‡wvฬ0ฺ7=หY4Šxx—ฯe}Crƒ„5อ€ำฒBิ2kค๏z]�้gŸa†ฉณX?วm)_24์ฯ2 P�นุCษฮK€ๆ8\8T;8p'่ยI๖s๓ ตฝ�›”7ีรผ‚aรz๏ๆแŒ๙%€์d{eq!ภM� ่ฑงtฦT_็IlฉใมY ๖w๗ฒ่Q2›�ฃs9L„2Uต5อQRฐ‡675™฿พƒ๓ศI€ฅ�ฑh6™๘5tถ:ฝ๏CRฝฒ paY—}DษŒ—"Wำร“”‰Œ„๓jณAaN๖Šณf�ว—ๆ่44ิฒ๏0ู rWิ `•ง๚ึๆTืาLU Ž)๚$€t;)]›.{ภ,ฌ œAทใา๖๖7ฉฉง.lภ๙9ุtศn6ฒmr:/vU๐%ฆ„ภท”j]Ko$‡]€ฉ6๔›ๅ5่๎–ๆšจๅS~Fญ<œ_g”q__OœOํ„Žฒ บฅ0ม๓3 มV \๘šb๖Ctk @S@ๆ&งฃ฿Š}Xœ–bƒZc%ๅ‚|€‡๔ิฉร+OใSะž9‹F�๖BplญŽดเž4ใ%‚ู•5”7ูChu‰kก v้อ2;1–ฮž๋I~�qMฒ>๔�ขc;เฑ6( !]�า ป์/�ฌaิŸž)๙Ž$5˜m๏mAw“)ฅฬะาM๔A+}‡๊๘l๛อ`ว)A‹Œพ์ด/�๏bซฑงนฉ‰†…อ๘wž๑5‚l๛่8FV๋g๐  0 tR‚บK™๖OmG€ฌใ.`Ž%xe๘R�ฝ=้ญท^ใ�ทdภูฝ๖T…ผฌฑฆฺถ้ษEž^ู4^ค$sp>U”<dธ ะ�‚๗๘>žใ๘)aOs93žษr|ล๒ึ~ึ‰$ิ2๒IJx๏–ม๊่;p{q�•-�ูnฑรCYL๘่_mฃAผมud�ี#๊[”…�‘eก:R– ฤฤึมgsอึ&Jคศถ8Vญ›ฮt6S†ฺ‡พฤู�"อรหcธบN}mC�ฒ๙ฬM์ตฒฦ�8ซ�œ}๗~�ม&2e™„ฬ}3u˜๋๎3ุ”Q_5ใวษ&”ษ่ิฒลฌƒAฅฏณฟ˜ฏห$ถL2ัcฒJื&Fs +่gฐษ˜อoRy=ฌ CK;q{พ `,ภฏ฿kูK6๔hw4-ฌr�ึฺ ฆฑaL^#˜eฟ v�|{ั€๋ฏy๓–w8”ม|6071้:š�ค$;มw�_฿”พฯ๔็ฑแ‚`e™^j?] ๗ฐ‚๛฿eฯม]เNX๐€ฑำˆฏ„(จ%็ Vษžx้et์ใ๔ล�7๘tฌ๚�๖ว๘แKุ๊Gช‘s€ูEแ๛๓gl–>aแœผ_-C/ƒ฿ฎญ ช/,{:ž=์95žาูฯภF�ซ€ต‚เ_Šณํ™6๖2๑dฏ\l#{ณ‹‹4ใ�Œ˜ฐฟท+=Ÿœ <ศ3“ร๏(ฃCFK๑ซdJข์ŸPByจl)q,'๖ �Šฬ8ชพ‚๋G‘;ตแธถB L�๏�แน—ผฯ๗xพe�db๖“=+ภw49งlzึ}๊ฦบึJ์ลฟ�/�ู?]๚ทงงŸ�A–<”๗—ง็๙๕_�็?๋ฝ๗๓?���ฏฒฦ]ฎฦh9ปrแr๊แเv5ทา8ใ่ฝ|ๅbบิ฿OึbŠแ5‚ œ้พ]pE“ ฐฅถุˆKtฯ‘Sฉ๘Z$•œ๕n์=_ึ฿dะMั�<ŸŠิๆ8Žiฌฉ็gแฃ�ฃlเYะbบ>;sš(PT— ๏ัLˆฐอŸ็ั PIฉ๔ š�ป,ป–๚ณฉฉ]z1ปีฬt%๕ยxFาlI฿าศŸ€~� .š“p4์ี8ใYd>Oณท˜๕]œ�xๅีtฆฝดงฎชGฃ ฃ!อR›•ํธ•ู\; <zะ=(f อzjPdTˆŽZส`ฐuŒ3€ถf6ฦ/ฅฯ)"ฌqw=OจoŒZfึRV„ิDืกŽ๕…ฟrตgขˆฌ7iๅึฆ™ัภŽ% Kฦ๘Q�`&�Œ‡Ÿ%VดV Hม Dฃศค”(ู†_ใพจ/Œ}ศ๔†Pย่"'613cifGgะคฎำฮฦ๘Š„7ัธฒ ๐LiJ‰ด จ™V9ๆp=QLณ,"ุvฐu=u�ร(๚o€P =ะฯSอxฯพงธ:ฝŽ ๙rpNPฒ'8›ง๔U๐=ัธodม&š�q=Jฆ้–�‡กrฑG; ี3dุฦศ>?z2œ~�ล4<พŠSHjck๊์ฌM�L~8�ู:šจg์_!%#.FZ6JำศฉP]ว,<เ]P์9:r/ฏ�ใhR— ๊�ิีJ†ฐYตd ;ฮไ,ฌƒร ๚ฌSbFฐ–@cน“i โ�]”ผYฮฮ:๕ๅ3c“4นBฤŽ1ฆl`€\ูดM=ข\d‡ๆE๋๋๓dฝศzB›�ภ1ไXท“tŽŒจLณ”/_พ:ภ€ำไZ(”๎yL ก�@3๛ชœ๓k � z฿ฏ~๙7้๖๕›P8คpšX06๎AะE={ิ๚VVSŽ�)o-]ฉฝณ q)n-ฮpๆธuู"f"-!Rฟ(ณfŽค—Wแ๘D ฒ.64ข�€๓j�แ:ลฯSnฌuถปฟrศ:N�q8,8ˆ8r:�๊พMา๙ษ9JFXdeŽพ+๑f�›šZ1z๕ตะ‘ปE@‹ฉ‰ษt็›฿คมGิๆs๎ๆœP@Cฆ'้หฯฯIfozt„ฉใ0*ุœ๓U–NŽะ);แ จทผg๋อ๚™๊โ@‚๎�.nฺๆิ}™k8t‡่๋ัe˜ุคJz�$=@"ƒม๙•*j๙ศ��w‚้ฅรsศZ๊&3คฎา™ษว9บG]บย—CภŽI งาPโ„sโU@‹�ๅ�่ ูรG&�ฒฅ๕์šมDu ฃ๘7"8Y€C*่l™†T�j์œอเtภ ืy�>+›ๆณฝgข!ุฤฤDฺ`ํ „อ@ฉoฏพ๚Z”~�๋ฯข๙žTใ_Rน= +ซ-XP\_็1ชณ?ฐึ)/๘จ H’ํ’Gฏ“m๊ึ-Oหe กRหL20to]๛62ไvณฯำ๑ใูตฉ™&ฐ๔8ศd€}์[๗k)”ฌ•,‘UGgO@ภา\}๖ิSฮฯq t๔ ๕ Wถย E‡ิ’…(jฤ/๙่g� ฝ๗แGฉgถ๓B?ๅ(WR=อMOะ30ูR๖’€Pฒ๐แอ7^{๚บ"zH[%# jลYื}2ด่”๊jzมบะ>๗Ÿ=ƒ>9>IwOG๊9.€ห๖xฝ lM]M๊๎๊„iPG5�š>ƒใvŸ‹az†Œ_โฟตƒส๎6ภ‰–ฟSžtg-o2นc`ภิoฏ‹†แ3๔SPุ์%3�ฐeั๛[�K์,gพ€3n’0์Aพฃg฿ปuส•ปฎโหฮ๕O™บ&\{๏#ร(ะโ๓๙2{�VO +oส_-เ•�–:\แิ>hG,?๓™๔|ฟ๒ด ทธ"?แ,๐แOœ8ห6ึต๔-๋nld8ญ๘ษ`โฒฤ5ุj› ช;๙7ถ!k๙y๚ฺDA ŸGฐN�ศrI๏ม TŸX ฦฝ’IฃŸ%5ร๗๋zŸjชwtบ==ee!๘Y๑,�H8žภ }aโ่ฯหXฅฏะ:์ฬbภิGฯา�ง้�ฃ'La —ฯ0;A™7`ํฑ�{&m‰.8‰i=๚PN+สๅ™ilจ๎็›ฑw’_– iนQึ ฿}เพ๙ �ˆk“ฐล'%wใฃมภ_@ท๘|‘ฎ†i€ฟอšG6r๛ศ˜ษ2uV> "&g]}ษ+ฦธอณ็ˆp›ู'Y‹๖<๐uNอ๓ึ(€ฐฮžใุณE†ˆˆ}ญŒ๑l,รฦ�m๊G่+cŸอgv}ฝgA4๏mŸ๗บ2‘XฌBdX{ร&บฅ�;›ซืFฟ๙�ฟ�ช๗๛Kฉ๚ม}ฑศyฏ�๊'++ ๔๐๑ำ‚3›]Tนซเ@Yณใ์๘ฺ:fC@ซยXuuwฃrำง๗ื ถิ#๋ .ฮฺoว๏(จศ‰พS}็’ช|6ศ๔KดVV‹T|B(ฉa:]ึข P–,ุatt�%XภฝŒNฅม็ƒจฯ/,ค฿|๓e ์๙|พ‡%”�iŸญ@QฏรMจ \8�A'ฃTไ:rR�คL›ีฮิGKำ5ฐีAฮฆ–ับน2>;k žฉ๋ก"ึ~ฝxพช๕ี๔า๙๓dGq„!ถ� �ฉc&ุžžGYใ”ํฎ๐ผfฆก ‘qซชยaง#ึ๚idส,~ู[‘4)•วOƒBฮU่8Lœ3›‡ษจv ๗ูT๒"ฤ–Gs�่ผKF ฑ„ษu๕•ฉ:ฅ๋ทฉ!œšLืฏ� ˆก๎Š–�RG‹๑๔Tบึn{ฅธชฤคŠฉhEณaƒœ}ฎงAŸˆิK›ดธฏขะvิวeกยQiX ๊�0†S@d yแฑ6ค$‘ E๋ิฤด�พ’บ:šPŽr๎ฏมแDaุ๊ช<U�ป€ษ๖ม ูุRไ2œ#eภฬ‘$ฺiTค‘ซ๊บาห๚sRžทq๖่ŽฯsŸ6T9๓;2Žiึฤ๊๘ฎŒบG�๗Ž๓>ZnFยฝ๛ำW7ฅ;žฃฐํX�@0[FะX‘ฮ๕าศู)/อMๅEขฝ2jฌ๕hห๚* |ตPฺ6‚sฒล ซํ#FƒŽฅน…ๆฃ๔ก๋vํคมh4km๔หW^กAุv๋ˆmฬฉ!ฅ<ภฉ๚ณ๋ก“๏ˆFืDวIGoาiz‡0ฒpN=S๛4๒:A�u8คž๐3:3ํUj'่๎ซถŠนลœซgO่aPEถง•ณ‹S†๓fว๓.๎ก n ๋QKAงtตwFฆkbzูgๆ7ฮจไ>ๅ ร7RK”J๙{ N�1zBF†{kFMใeฑŒ๏ศ6งi#—|fss+gžฦ\ึ‚ณcา;ฅบOv?x๖ d™kท €Šr'0zศฒวณŸ}�CŽqฯำkฒรs;๚)เ ฟจ*:Œ๏pg)฿šgฝiBƒภฆZd�q|fgงฉ]\ kOoึš,lิุศHบsใ&ูุง8Ž „�โ= ฃืg3ปฺJ&Zฅ2 ณัj ูำR๊uc4"5ห‚@๊ฝSไt Yฬœศฆ\ฦ9จ„ฮ[Œม/!H)ย้6v’B๗ฐC๙ษฯcมƒ=ภfG/นN๘{์ท€!g�3ฮWn๓ฉ=Œฎไ|ขศCSไœฺ๙ปŒๆŸ=�=ะu๗า_�๙� ‰มฮ<ขฦGฦำ�wำ่ƒ'ifxŒฬล,ดY(^�>z(›=ฐษง3'`อ�DโG3•ก ;€“ฦ=��ร2/ฯ้๛ฃnzํญท‚ๅกณ๛ฟ๗๑้/‘>J๕ะzCด:ฺ:˜�}žQynG{ฒ฿8-ว8†‚j*แ#‚ล\hึ€o:24่ณYำ"อภŽtt๘O6ŽYฃ ใัšำ -#“n#9Gด๎SาF ู๘O�0M,Œ์ฌ„Nd ุหzAะhฎซ==x๘˜�ำ4ฉC๏ก�Lƒจ+W^โฬ~�A~ ขžMŒ!o{โึ™�ิัาม]ซฌ+ไ�ุhฑ‚~*นุs3R‚๚,WdSื้ว๒ไษใ่_คnำA3H๑ ้?+c—’/Jธงœbu‡u�ธ{a',wาv:�e“Zbn@คฬ:YF]d ์ู3ฒ๏P†•ฦ๚ฑ�๊%™ึึ๋` ํแGt๗๗EโึๆfภดIša>ใืโพ๊™"า ˆZO฿Šศอ;Iฏผt)U�ํ"C ญํๆiฐ์:) �nFน u๕๊ซมB’กฐธ:^ํJ๏พ�~๊๊๊"ุ*D฿โณ`ำ œ:ส8ำ#ฅL์aฯ—+ถX“วw๏งqฟ_��/ฐก”’‘E}<”N่g/ะQ๚@‚`S)๖%]๎ž•2RฒVซ€๗ึๆz๘^ูYภ�๋[ ”›ะฤk)ˆๆ�†iœ๙\ ผV ศฆโ์“ gF=เ—๋ลใ๙7�” ธแุ]�ง฿พ"l˜ฯiะm๐ช~๒Ly]bฺ-ํฐื7๓มป๕๗�c}i๕ญ ๚‹ฒ›CฮŽ ถ !m�(@QVUn€ฑˆฯขญ4A'ึd•฿&ชสู}<1…|  œŸฬบG2Lี�q|ฎมฎฟ ุmJi_๛c”€Zฆ–อšgก;๖ะแภ๚ณ๚ง™้™๒U}#aฒœ๔+,+ฑ!๓าโ,ฯ@ฏข๊z@จ1’Zs‘p” ิฺูI฿Šืฃว†ฝ\;GหZ,าOลkร]ว‡:น!JŽะใส‹:šำ€Gฆ์@?ษxไฯช}3๘ืวแา่์ h ,7่gฏฃ3{ษฆkY‡CFNจชภฟ'Žp/‹ู๕ˆ=ิน&แlB-ป—Mไžษ7ขŒก7์=`ะltพSdd m๑Z<š๘‰ฒkžs฿๕ไู๊ดษณ-เsฒๆ8‘‡่M›Rหฆ๐Qพัีg(๔�ฝ฿q1ค>ฏ op)2ะ`;ห�€5าาิ ๗.MบฯŸฟs‰�YŠ๎ํcEMู่ Zfล๗XPn\g‰บ%žฺ"mข>ง>>ฃถฺŸG947ไูQ–86๑Ze�ฎI_ใ4ม๗R€C&Nfด(๛†�y�ธ<3_x๏ัเg”,ธข?ฺ/ใ€�ื�ม…�ฦฦžต‘งฮ>x<ฺฏ\‰๘ฺดfeiด›๎ิิดx่tิฏีาึŽ+LS#ฎAโ0ํ!ฅPญอ)8`ฏq่l‚BGเ pอŒซ8=�Ž•ำHlAม‹F>ˆ‹ต�flŽ RฉๆฆUั๓ศVuด…าh†b:G๗Rู"ู’สMUญƒr@†Teํ่?&aณ๕ข‰‚:ƒ*ู8@h•ญ๗์Œz๒pผqฃ‹>ป—ว}ฝ�๎�<�,‡นuVส„€s��้e e๕.YŠc€ร�-ถ๒ิ‚ƒฎ๑:š[ลฺ๕tuโ<@ญแ0Vah๛ฯ๖4uคหdโ*1^6ฑn�f€ec(g…;[žsสส€Nฮร•]—Qะ2 ‘รก๐ซ1žญญ4+๚เ=F ešu2๎ๆ•Wฏ`€ํฒ เ[cŽfฤ�� uฆ›่r=VึฬZๅ]ร จตตศfEวอฝุ_ปำc,”go็Z‹,5—ฝ๔€ �ีZŠฯฅ*ก่U€™F)�Nงุ์A�๊‹y_wK5๔�B(ŒŒก3ส^˜EสByTV€ด๔ขa-€ฮป6UผฆX^hณสg•็�$็๛‹ษB๊U˜ต<@ฮั8~d›h>e ญๆR~7ก�[๒"ชYำะ†L”N[ “ขณฃ‹lึ:ว๏ฆ…ฉษ(ตQฦตmฺ??:&ำ3�ุBณ8$>ป๛ฬ9๚ะ”ึrศ…iสHf ๙ฒค€Ž็^@I kb๐y_ๅZŒ…h/šฒ้ส๏‰ea๊*๖—qฺƒฌู~พ€ม:uปึห 33šaqัจจ�or G�อฐ—Š™๗ฬA>(ธ์๛&๕ณใ�—zัฑฅ‹๘Cฯำฏ?�U$\h๗๘๑�;ุฏt๙าKกซ˜J ำ/ธb�ฅ%๔ๅ ฒฯ๔_\‹g0{ฌษ�Ÿ�gจ2 ˆๆšj‹s‘v(Iz2๐„I๗ฑ้”pL#Oืำzb์ุ9}ง�๊ศš �๙i,๒r้Xไบz๎“sฒ2=8 ว\ว็�EfSl AผะS^~๓I”“ิyฆ wc฿๒‘็ฒhฒWฬY(FŸฎfl(ส'q]{�์m๏.ุlุ #6’ๅ#bฟ.^ธˆรO9(koะbฉˆ` ,:Y*u5uaฌี)ฯฐ‚M”QY]›–๑ฏ์)POIยUฮ`ย ำอ7(๛บๅํ้ดยH฿gO‡a5ภล^:ๆืฑ™f"<โ‡฿ลu=/๊}}ฯก ปปบ‚Yเ})3ฒJํSไค”#าฉ2œฎSFฐึืถg3Wั�[ _วš๊<ภฤ,ฮย๎ฤ“&;œbCๆdนฒžุ$Pe n e&Lbญ �๐อิ�ฺ~n5๔ก:0งG="`>;�ฮ~ โ๙Pสผu�๚ 6]p— ) แ3k/=q†ymPธEF๙ญ>–>‡พืžเ?ฯฎฯZึฮณ/Vj๙e”๚�6ะ>$เสGฟ<ขพy v  ีŸkงด�๑z^V๚(Yด็s�ŒR@>A5›I ๎้ห[Ž๗o่}•สุ๔UŸ@Ÿ\_9ฌ–แฃ-Qน๊Au‡e–Gุ฿สZz�gCƒฐ7g`๋ตDใlƒา� —ุทBฒ๕“้มฃ4d†•ร��์Q฿ž.‚๊ใuทพ•เO&น–๑]g�Vื�๘ใภ œฑŽ[๔ฑd ํ๚;ฝM฿ฺเzใu,��ๆผ ภจณ0ฃ๘นง ฐ%๔˜ฒŸ@๊ภตšฺ’ิ �2 ) ˜ุ€้ขฑ.L;@ืฤ’๊ �ˆ]�ndสž0ฎฟTbzยyŒ1ถqกิผ=`o Nr[ภy–UbBU;.ำน+3qฦู_eฯเ�g๑\…žฦ†้ฬ+Gjuฎเe€ฎพG�h฿7“ก๖ฤ8ำีหูkc}XS๖TปŒ`หc๔/e+›…เนG\ุึ3|๎WฦqฐXะ�ฮฒŒธทžูห‡๚"๎;วoๅ ถฬ๎ฮน/?�ซƒ›๗ž�<$๘ฃ�๚A๚งq�'��ฟศ}p๛wฯx`(3์}gฮฆฎฮฮศJ_}ํ5(…ŽŽ)&SD™{1ห)dฒญป`@ฺศ1Uิd#D6OB/ฃ ก1!XมfE: Aษๆf•ˆV%(๕ฯ‘$Pk”Z ด._พ˜ฺZ[น†š,ตไwพฟ“่N*ย$ข‡ข 8ุd9,@๙4˜ฬPA่X#c(?S4Aๅณ3ŸงSฉrฯ�wŽ yf อPฎ|ฺhฮบาMPๆถ(ฆ4HjmkŠZูS<ึ@�;XทY> ™s‘ำz([MŒ`ณFzื‘`(-ฉ“๏ณะฬ5’ฯ‡žแPใt๑์*ฟูธžEE์ฺๆั•ูๆQ>Ÿ๋h฿ฉ:fdข)ตๅB bาšบฺX“ฒŠ"Pะฒ3 ๗6iІ‡\๏�ฏฟ![5Ž!G๑ฐWป�NGืZnMdุu๖0Jว่สอ็ˆ€ฃ๏p(2%ข˜*7�]๊I}ฟ๋+ีฯฌ}l7ฏqำoยุ ะ ๔อ๑็ ๋ป๋pžบZkำ›ฏ]$๐n‰ฮถาํ๗`$bx*้สlภธ‚\บŸŽิ ฉะtศMยHฏ“}•žงแ6(W‰mSหฌึ`1mมิ) „ฯ9;ศšyQฎ vXว"ฯ!ฝฑ„เฬf^4ท9อฉH๎?MŸ�๚ห42 cฃคัBV*+u7Vฅ—.๕ฆ3ฝญ4สaœ) A!ธi๚ 2๔a3เ…�ฟNEUCY‚J.(F”๐Œ‘ašŒAอsผaUCUz๛�wานKฬ€&ำdเซูฝz•์็TThdƒkฯ l)ๅส•rญฬ76sŸ๔๎ท็Dง�}าY(๐,rอ,ึmง_๙•ึฆ๏…ชภpุ่S#–…‚ฎเล$๒o&๒„Lๅ-œ<ภŽ ม๑�m2๔65ด๑ฅ็UC๚๎ม๎iz>Hsผ๋ทษฮOรภP่\9�&€า๕์ ๏8-8 Ÿz7Nื ซ๏ ตะ€8ม‚ €FL็Qส๒๏eธฃDญํซ hญมๆถ z6cd฿,็ยฬ{2ํจ,YQบิ*DๅX}rภูู 0“ใHV3'u๋OฃO ็ู็” ƒป3‰Ž๙e5ัY9`BfอœdœD;ศkุห(งศมYหมฐA๋๔ไYG '@O>SnS˜_ฬVžห๎ำUศ“S9dqๅข—ณ(ลา๙818$;ผรA @Fษ้mC๔ฆ+h็tƒvŸ?ฮ๎L2่ก0๒�๒˜lนMCอดปท6� E�S+๋่€•\ั˜ดŠบl(‚6%t:^ƒำุเ0„ม�›5ใ!YŸ Sฬ @†K[OW๚๐gŸคฆฮv‚WสMpV‹Šํศ๊์tšI\วกษ‚~ณญ3์ต ฉปไ๕–จlฌ,E}นฃด�นฎ๓u๚โ๏?v‚LN/Ÿ ๓™ดๆU๚๘›dš›[�า๘ุsY>โœV…>0ˆู<ึQ[Gwูx๓ฃ๗BU‘>�ไ๖็„L�3ุfœœnฐZXแ๓.ง�เ�ฃ๔ม'ฅŸ�๎๏†ทFž6P๊๗ง*2งoผ๙6zดš_s‡ณ.ฟมAๆš–๖๕๕’mโำน{j*อL <์rO6ืฌฅy_cศอ!เK>ๅPญ”{6 ˜ฉฉU}ฺ๖q์๙(’HVyำ๙�CŽsัCูดาูลI_˜_Aฦ*โ |๕›฿D0-hเู7ุสC>u�ฬไ)(ฺฑจ�F/ูยL‘ๅ}ฒัd8)็G8อ๘ ั{ร,87]š๋เิj ๓9ฟ:„&4l–ƒ>ึ‘/ๅ>ๅ–— B ฬ—YฃE2�ฯ‡ฑั4kj๐๐ำง่�สิำืห�ช#ใUPๆฟ๚อ็Q–gำฐ๋วM(-,ฬaำ-J€6หu ฮ~๓ลงผง*5ใ(o„�a๒ำ๕฿|EIา<ฅ8ป”ศฌq†็`�จใz{h;ฟ‘ฆฅงทIฐ๎H/เู7่UภYF˜๐ ๊ฃf52”ƒB‹๒๏w๒Qอศีk๏ผ–^{๗อิyถ;�ฒ–๖V2}LะกeV’Mๆ๊:——\cAw๕ป 8ฝฆฌวา*ีิM ะ—b<+O KŽ•=„mำ–ฎพt•IM์)เz๎ฬ™>ž‰Zfภ……ฮ ฯโ�jณหนฟ�ณฝ้า๙ณh๏ะžuๆ๓ 4ŠB"|K}Bƒ~ปฤp(+/�ณศrขWดษ*UฯถHJvJD๖ฉ๛#‹ิLท !™eฎ�5t_]#‰ฮฉ๖ฏ•gy…R3๎7ฎ ซr‚r๗ศฆี&๐5น™.•่๛_ิ:ภ~่Œ]Ÿๅ˜~ิซOq>ๆ9'€๚ ™าไ™ืำV ๘L2^มเ�]#�.เzœ+�/ุ‹<,g๖WUsุ~–•=ห๔9P�j‹}ฏ:Y€?;M@rไา๕ฬโ’์;พ/๖ZCฆฅ~ญำ’ิ็๐สฝๅ+่—d ฦ฿ฒซ/อ'Dะ๊�f|>>—๗d๖F�ฺQลL๋โ,jrP๙€๐=ต็`๒f๕ๅ”A�ฯศ!eYklžูv๛p๘m๐ฝมYQจฟgl #ถ_ม’/}นก็รiพ)Y๘ะ~ฆืฏ'็3๋ ฬ3E™฿Gฟบ •‚‚ลุ�tˆ ฅ Ju็!๖„๛.4;ฎตG‰๏Wะุภ\เ]fc,ฐิI_63ฅฬ˜D`\€มo๏#Xษžk๎a—3”‹=๔yL “’ฉ_ ฒ@2๖lg๊…q*ธฅ� fOQš็ค,ห�lพ๊”(มŒ`|ฐ็ฦJžŠbสq ุ ๙Bb ' ๘ฌNฝ�ไYณ๘|6’ต ๏kkฏ"(jq?�Rศ–gL%@ฉ฿^[๐ #JH(ฟ๗๓\3�fขื‘๏~๖Œหย-?จฬำfk฿�_ๅฯ)5๚ุ�น=ึX@Tฦw”๐zห�๕ป•5™ถ–S)ฤสx”ฅข{8q๎gภด c?„”)e�W ฆ‡.AึโผกGˆr้q๔๚ฝ๏>๘ษOฟ�็��G๚ั}๙„?ธฏำ•� �i"ใ๓มร.จ€ญ฿-Gtuw#dŒDฎำ���ษคว |ใใฯ1Dฬ ๏่ร ้แ%„ฒ!โ“v๖‡…)Œ:ฬnฐ_"X ‚ฮƒJฦบ-Wฬ!ตฎฌœฬRาŸ�๔รจoื่ซDuRๆi6:๘TA๒~ŒพsYณ๐ฌค@[’ ขฅ•๑เตB’Iดสo†ย่ฝI๒™�๒๏:{f�U๒fด-xๅฅ+ัiฟฌ”.ศtKmจฃƒ3ŠฐcU€ฃ[C&ตŽ๎ฏตญฝ ด4มภ; X%c0_5�9ต๘ฦ �ะ4iภ436B ฤศ,”๓m'ฆงByxา+อ๋X๊ไfใ˜จผญ ๕ฐZ�ง"ัฺIฅ'pเ2kTื~fa,-ฯ`xœั;ฝ(ไ]œ่แงฯiๆ6A7๓Y”]Žq๊‚Rส�ฺ$)2C8ไ)E88f…ชpฌอฒฺ€Iฅ+ฅฒ„gYVู—A฿อ�/‹)• )Ÿk–�€H…เGฒฉศD9BS'€Tศ นฮถสิ�Acงrฉrิ�โฌ�่สตqMV@ฃ—fฦุg9ส$‚^Y ร๑CRุs ฎึW้ ฅะ†e�ฮL›฿V‘)3 ฟ ำ`›  ฒFeฎ•ฉฏยธ"K4‘�ไZbะซkแ8e๓ [”z &๓กบbfbฝlฌไšIaททFP‹น'6๋ฒwน–CสfPึฃS|้ษƒ๑€ร#อ|j๚A\Nk์z–"464sFGนฟtก�b์‘™9มLŸฬ่m4ตฑIเ"M=u<œหn'cgพซ์อ๚”จ8ู@Gฮ™แนงd]ฬุ$ธŽf๓หpบ์ /ฐเ๚ ๚9fŒสxN;Q{�š4์1 Uฏ`ฆ ๙Z!e‡๗S ีฬไู{ัSม„kŒ™Œฬฅ็s--S„]„\รlf  ธrิี�sƒอ~ฉว,ืฐงˆูEตฉCฆง'ั๖ัํ;ท'�•c@IDAT@ฯฉymŽoŽNsd’๗; hเ(>ืีตฑF™X…�ภ9ัItา ๗—…s๙Tะั๐Œขuย้ี๑+ๆ�„H7ฏ“™ฝ}๙‚}UDCHY(”IDW~0+u [รu8็”‚๕^่ง‡วุ๔vX้๊๋ ฟMI†rš}ฺ'่?„๑แษก�KวศฒœSd$ะฤš�1I๋O]6=ฐbCฦ$๖vœrัึ�รฺ2!y�Œ•๎๘ฟ]ุdฐ|ฎผ|™’ K้ƒ๗�Eช๓pโQบ“”9 `�j_š p๓{ํพภ‘#7--b๘ปเ}F'{�2’๖\ูZg๏xฏ๋่^๚ปฬ:โซฒ?ฎญ๏5b–ู’Q_S}v๒”‰>5’FK3“D“ฐe 0}ฏrษํr|smหž๓ณ�+Uฎ|GY่ืรๆ|–{XR่3ส๖2”นMle�ž AZฟeฆnlศ"ไพkƒพต๙์๘VV—๙s ๐็ี๔“>Fื^I=ุu{ฉ+'†Ÿงูฑ ฎ์เ ซซณ`^ฺิฯŒธ` ™|eลง1ฑ%Pกฉ}ึวำWไ„zXB%�@๔}�)X ฐ =๗y�ณšาะศฮ€่ฯ๘ภปฤ9(�7U˜%ฌบG–NุPQ๓˜‹ฺŒ๚tiK—V˜ฒ4>บ/—3x๓@เอตฒลษlNน๐\๋{™ตจ่QY พN6…~ธ ป๐งูg{ต์ภnศฅ”ƒNฑผX:�ืท (SพŠ฿ฦ^y]ฯZ0ƒ}@=ณู๔ำฺ ๙Ish๖ลไ“๑”ฬศี9€zVฮฆค6f�!แfซ>์ฆ%SฯฐKฅœ7}Nม5y็๕�ซป€,z?ฺ.�?.“ฐ๐๔รY@e{TๆฝOห!M๚ˆ๋ฑL!&Ÿิ๕;M€——•ไ๏ooถ�ผ เo�์ฯ�ยf!?บฏ฿†ฃ?ฌ๛�ใ�ๆชห�๏�ี๛OGGฆ�uŒE&ํ\][‹‘ณ&งส๎$ม:จ>yo]ปF™ภู‹sŒ<{‹ %�D๖hllก๎อŒ4ฎ™'ณ?1‘oฟEป< มผ฿*เxŠQBŽ‹ojcŽ+5fs‹4๕"[ฌbอ|ฮ�้9๚1  iv——ึุ๋้=Kิฐฺ‰4„ฯQ‰*„๐@eฏR Žˆเ6ƒ,ขHP"vWีิฑ7รฏมlสึHfนkจก{�ต7S €J#ฌK๖้�P€`�€ษ2…๙้แดH€น]V๔๛~๖ FมhZZขกŽจMq๏(-๋๔ nก+ถw๗’MMๅฝน9Bf็ํœjนAgฯ๕‹’๎9zŒฆJH๔ท$ำ†;8ี๎…ฮ’]Tซh๘ิ��Fyฤ๙hy๛ึu‚6ใํ�Œhƒฯขท๕:TG๗ๆ&ํ�Fƒf™ค(Gอ„1ิ8๐:@7 ขภ‡Y6๗ฮ‰*)QP›Uุศแ}~้์ธ* Kยฒฟ๎s-Y๙โœCฦ.๖ฆหฯ’‘ค~Ž‹ษ ๏^G๚ณฅใล์D/›@–ูZ>(2ำKs“aะuผWท?X P<หษ>i\• ฎwฃ๔ฝˆs=ป�๔อOOดโ|ฐœˆct7‰xํ๚๔ห_|Nญ3} ุK้#ัTSNcฆหฉณซ‘}&ใŽ|ุอuQฮŠPจe|ถe3‚dา�| oŒ„3 ภ๊H%›žI฿ฬ>…๒JR(๘‚ไฌ๏ตƒ"ถพ,fบ—„ฑ�์๗�เึ2dื06dผwดภ‹kfะ่:จ”ใ,ฒO:+fŠuฦฃจแีษ;"o‚t๚l2( �ุC๗O๚\<F–‹p~ยpฎถ6v2๒;�_jธkผ‰q๖dว๎q}>ญ๕Vz๚เ~{†ำ 8SNCฐ|63f–#Y—ช#๐ไณ๘fสuะ%�ป]แ�฿@่y&)–™Yšย2จm shS4ŸYq’}uคข๒จใ2ภ�<ฝ�,อŽ“�%ธธ‹gCฦํ๔|ศ=—ฒiธ๖L]–qs่ฏb†ฬ1ˆ–'๐b‰ž'0ชO<;fฬคl:}BVBNW1ภOFใŠ~ไLpY๖ เภฎ‚(=ภูท\#จ‡ธZฮpn็ื"0vฬ“๔วึฬ!ฎวfs=‚lๅœติฑ๒f่,›PW��™ึัั„.&หKฦ F็L&N3้นs�8า›้๊+/๓ฌนฐ•Fโstฤ >K}฿x๗�ิูำ ๛‰ฬตผ}ƒ‰ณf.)I@V‹่+"�Yะ)UQภำ‹Šสi. ำ่ตท฿€YTE๙ดบ kสบฃ ฒ3hGN”*MiศkMภP‹�hl้@^๓5ฃญ5XDŽp’Sฌซฆ‡,˜` {ห9B�รถข' ”ุŸ�์w"๘๎์๋K—_~%}๐ำOR ,†�๓ŒึjjIWฏ\ๅŒPaฌง•s๏๎]8^แจสำ1R`SuNท�“ฌm2O็ัั€�gฃ>้๕:ี”!,--…ี๙ิู�B�•qฉฦึฬŽŒ"€UQnดF/๕–gRFŽดบูlž๒d@หc"S$ 8ฃฅฬiWท๘ƒ&หdผ˜ญ—ฑ&EH'dฉ=๏Q~ร3ๆข“Œ\ิŸ‚F–G๘ตFp๋Yส4Zภrฬู:�lถษ๚ขWฦ้{r๋9G7�๕E|…™ชถ†#:91Nรพ๏าW_|—ฦฉษ €าเํ๗QŒ}้Dฎะพ”ึLRท?J๖m6MUฌฯฤะPธy- ?|N๐.ซ๕�9ศd†โpฉ3xn้�{ณป์วฦสเึ> ฉ๚TJ"ยŒฅ•$�ๆฏ�"อฮM4๕Ca‡�^ZXL�=็P<Dtd7aRM–ฏฅฆl�%ืR™\]Yเณถฌืโ<6p�e.9๕จฝ$˜aงvkท‘�\๖ต‘.^บๅกอญญ€EMiy}2๚,}๖ํ็$7&ฤ_Jฏพ~ ‚พ.ฌำตooกรฅG†๑uฦSด8๛_ุPั)?า๑™๕๗ย�ข�X >‹บz’๊F�.�ด้šำf์“b—Œฌ h๛{<ƒƒtห'ท 4waืไชฃ‘Yฏํx้�ึl๎ฃญน•DD'Ÿว็Pz—ว ”iู– hป‚1‰ W๑\ปฑฤiวvŸ<|J9าฯ’ “–"ใ3‰$–๛ื~*ณ๚2ฒ๔ฉ๙A่žŒผš=ๆฦ๘ฝฒ›๑E๙7ฏ๑žmeสๆ�/`HL�ฯ€=€x’q๚Z^CภB�ํZศ&ิ๖ี4u!๘ฤฐ|[žaเฆOญom�เบข„’"KOdะb'p#‚Iค?ฅ�ฅ๏—� จB๐/ภ*0l0์CึJ;*Pc’ะฤŸjส๛6‰_œึƒgึ/_'�ฬ_8ทAญ‰E™\ฅ~YพlO‰่yBPฉŽคฒ?–e 6F|๖๐!�D6ะaN[“ มd ึ`›๓0Cbฑ�ลmฒง&ีx�ฎ?l)˜�Œ=FdอธฯŸฦ&ฅ๘อฒญฝŸu|}Wใู๚ะ›24(ฉ๐หgT'jฏ๕๏�{'๒ุO@?ุRญXBn"�=๗‡�ฐ_'Iจ,dGะ9๊ฎบZd=h?ำ@]_?“l•ั็ฒฤ&ศ„ิ๒,นฆ‚.ฒ‹M*ฐึ%4Žuซ"vhโ๋o.โY�fฒ mœ+๎_c9น } ๅo‡„“๖ฺื๚(cๅษ{(๑œy�c3ฐฎฏ๛์™:แ๙ฬ^มelูXY���ป;฿Qฒภo\_<๕๏๋�ู‡ล s�๘ๆ7๗�๐้ะl๑!cš @UŽ าYšก–@`�!‹ฅณฒ-jE ๛Œ@๘ำฟ�g้I‰Y=ณ\2ฐิ๛ ญใ&8‰รส คˆภฤ?ีC๘อ~ฑห! J‡œPํ2J<�:—Ž7ฑ™ึ๕[ �ึ| œ~นŽ�‚&h †‘A@U!p’N›ฌง=๘:ฉ๖ศจkฯa HนTแŠไ๏แŒส8จซe�Y%)ŒฅdาฌS๏'#ฐ05c ดฏษ‘GA ท+๛ฮ๊ศะ๔#่„8aฮจ� ึ|gU,VQ„ยตแ‹4๎งพง �ฯG-L 5„ใfqฬบDpขRๅ๏B๏;?๑เ{ภT"ขษ�ีฬธใcttบปz‚ๅศฒžžฎP�ข๖๎?ไพๆpJยxpธbAํo๐]…#c๖ฯF+faถ5‚k� 8จ"…Pาฟ'ลR‡ขvซ Œฮ]8Ovช/ฒ๓๋t๕DPมˆทถPfภ5mโร‘ศภไ�sอถ•ๅงฮฦšิAะ�F†k›l†{คAำ๐e๛ สจศqP,ๆHกโK…ฒKะจ4nผฯfif๘ซa”ทt‡"�Ff�Raz/พ4ะ�L'] ž@8รธŽใ3‹ฬๆ�eบซ“ฤX,Aƒ๊ๆึ-/uq฿}mtmถŸnDศ‰LำHบ—[Pฌ๗ธฯP~€G: ž!ŸลฆtK€:‡์๙�q1e ๐R่ิึำ™๚ฮ’…ลโeฟžNป™Nkั`gพ/pfท8ฟส†tIม@ƒŸ�€�ฬทgๆyีัฉc]ซ‹แ”_'gƒ)ƒถ]ฮฤ!๕l‡wฒIoง๓ฉ3œลZeลูึเผ$๋ฌN< ›€œŠl'ล�ท๎Bƒฒ�$={๔0&ฌ๓Z"นp่rp๖2pฺธNŽม�ูi฿€ุฅ} ˆvd0RN$ฐ›ตฬYฮ6ฃาˆฑ3P๖œ{†"๛#บธดYๅ%2ถHx#๙ ๖: 8YR็1ฆ>ซ๕ฃAเ‰a( t4มd�‹ธพย:ฌ, uOd–ผoŒผt}8ู่ข\๎ู@Rณะถˆ์i)๚"œำp�PO ฒ0ฎๆงEC#J�8rฒ-pqช(r–a‚ yFAๅzฝ,๋ษ๚๊"๎฿šี‚"D; ฏฏำaบ�๒ู๔ฺvฉงqู•ื�xŒ5NO�น่œ�๘ษร๔t๐1ŒŒฅ่,฿…บ™{๏ร™ฌq g•Q]ศ%–�ผyงำถ พฅ๒;šS}XŠ=-E—^๛๚’€ฝ€ำฯว�; P€ฎ.ฬvฬet†๔ใ๔HzA`พ0ฬูๅู์aMK+๋@i( Q}K[€a๖P้่้Iณซณ๔ A' ฬ.l็ห7๑ห6๘�j|๐’8Nฏr*”cN—ู7๕•Ed ็œ>0<1gฌ,‰็ค,€|'tทฬ3AูQบภ5่ฑq้ฅหุJ�q9ุฃ:J-๑ฤ ท˜ิž.ŸฟLฯซft๏a๚?�อ�M‰kiabฒš™`ๅfKlžuื่lm �šfปผ๋็ฃRะŸ.œ๕ฉ ›JฮA`ชQ)gC฿อsb +๚Aช>&=™<฿์i E กแ๐ฅK—า[oฟK€Vฯบฦyฆ.›ƒ}B๐hฃพbŽI๕>2ำฟAdฦˆำPจb@า&€O‚Iz|9ž�ณฐฎ�ๆ๏m]gูGn[๕๏ุ!�Tu˜’ยสฯฐŠ๑wฯจภ€ฟd ๗ขฝ๗�๋šVยh)ฌjJ๙”: เ^ศ–�ƒ]่{ตํฎ ทอญfb!“)‚vy”หศ€“• xเ๋ ฎหฺ๛SQ๛9š1x&ฐC๔X0แฒƒn^†‰ส&g๎—{ัำพ ค5๙�Š๋YG๏<ลv่ณiŸ^ะ๓รงเ฿ฺI™}๋๘์6BW‡กลยไแ#ะ‡๏ฯกMส๘o๊cƒt˜ฌœ#ํƒ~โ�๔ะฤPš@“อแ๙3)'๘t๖�ล`!ธฤ”›œ5ม฿ฤqฯุM„ฬ’A�9m฿เฯ`ภk†ใต6ิŒา%€5'(ฌ–$DY ๋ปจฆ/ Ÿ!Xใ฿�L๕”ฯ๊Z`ืทบ€”ูYRเ“วธž–� c[Hb”UฃฬŽะบนRืฌฑงฌ/ฒ*˜ฑหณ  X&`CpeH@ฑจภR8“ณ2a`ชˆ`ะHุIse0™_~้Lz�ฝื��y›•’Sฤ3๋ŒptM่ญeณc\6d�ฒ\"ใใฑo๖ป2e฿|ฆvวณiฬๆ่I๗_Y–ก�l๘yjD/5าtื๛–IŒ๔–e9Nา‘น๎ฯ์ฯ`น‰ฅ+\‰sอ:Gฌ†๏ห^รนw!1|ฎ๋*เcYƒฟ๗D๙ๅฉส|ฑ.<ฟ๛r„NSF๔๑T799วY[ญตีeฟ๘฿�์�Z}๑ŽหŸ<ย๏๋?๛O�Ak}c๏๎ƒwหฦ&&ฏ“๕ษ'ะฉล12€1smg่eะ๖บๆvš๒œ็By" l‚ŠฟEฃถ'g1๖Œ/p๐หเํฃœ…ิ@1Ÿ๗ˆฺЉRณ๛ฎ แœฟฯธ;ๆ>ุ/๋`ืๆŽ[ฅcrCm#h/อ�ๆ–า�{๗‘+.ข›."ด‹๐nBMฒ1[ฐ ๊จ๑ใุ“AคUลฆRต šยฅ�Bˆ2๐OG๒TX�จษs"p8AุP_—ฺ โ[1š็้่�Gฆ% jxKณ๕=เยิี)ŠษT�Vใ\ข‹6BIะ๘&“( ƒฐ]”ฟะœ—�œฺู‰‘ง0œค|E^BฦHƒา�ัส๚QซพEะ†…,`-ญ'ีLุ”ศ5S๊ไ{˜์jฌฃใœ@ฯO๑Vญู– [‹็lๅน๙ฑ4::ˆ๓ัJw๏Z่^ใiy "Fะyู: v ท�k>ฦ%—ƒญsฦภ(3z ง= ‘ืๅนufกaเ1ศฌ—{๊h+gน[žQŽ<๕เX.ฌฮง…@ j,ญ7ำhY%zจแ^P+บYa†“lK€มูฮ&๊๗๛ษฎฃ$qฺt0คซ1 uMXฎธV1๗,=ฯ์*ฐ 0„ ธrฯcฏฏฤ ็—ืงฅ)Œ.�“b่‹Jฬp๊P๐`้ฮึl�Lฮ์ล}บB�ๅฟ�›4๔„Q9๋tU/`ฆ8์โา,ฒ0าซฮฆnf(ค๐ัฒXAึŒ ‘ggรx~‡Rž=วRเ@}Š˜‡N:E7๎iๆ�ฏญ99%๓N=z>Ž็{�45ะ๛กžฆ‘:ฺBY "”ยขั ิฑึYV‚[F๓F๊าp&vศ‚@ktอPzf z,ศ#บศจ’~่šXชข“ญขถ\ ธ gŸsMู๑Iฮ>†1‹}–Q๖‹’ถi%๏A.๓(-๒”ืไแศ`h–pvUพ‰�ู่o›sพLล.gDบwt]ฑฑ›œ8ทYศห๒่lk �adศฤใ�Tผ8๏าkฏง—_ƒ€ก ัูร8ุœฯs=“จ ’Y xณึ์๊XŽQˆรัH๐eW๐ีๅูฯzฒmœ�}€eย๗๛‘ฆฑKฟฌฬ? Kย�›…๕บ7าสี˜G (*ใฆŒsdนŠž`�:_=` `A|€!ซ` ‡OyญคZ3w6~U—ฺ ’-F็แุ๐uŸ๛XศYฉXาศฦ๒็Œ๛ิษxฑ๙™Žˆ าห6{T -ู ^)ฟ๋้kร้ฆ[g.BทT’฿โฌฮสZš˜Kำ8r�ีๅิึู‘��ภฒฒๆะ#C8‹—�ิXฃๆ๙1,ฌนศ@žB�อgยŒฅf๗ FญญW?Zว_Fiฤๅ7ฏฆ฿๙�฿ฅฦYๆ็: �gฮฅ7^}“{‡�CYอหW_%#ฺ…ผเ๘YCณŠ7o}‡nX‚้SใŸ>}ฮYFu๒`mม่P7^yๅjชฆ็‰Nj[[;Aต›dกX#ูs�•๙�Oาอ/ฟƒ&J`*(‚,xY]แT�๎;๏แx–0Y`สฤs€šอ”ฮ]ผุ<`oฑM29ฬช#ตษf ๛๛/ภv่Oรุ๑‰๎QG~COำ, หํ�4ฤึŠชๆP;๏8ฦp๐ฐ5h๎ YZง#�ฤฤsต๔Jh&0%รวตr‘?A*C(ฉผ ปT3๏ญ๗฿Ÿกž™q?ฬžช[cฆ:Ÿๅฺฌฺ™5ฒึุฆŠ6†<ภ‰t!}o๔Lภ@[&gเuŠ�ธ๗N่ษC~,30จr•ิ๙NrQ7Xr  * $Kใูฝ๊‘•น ฿D„–ิ`g„ b!์=‚-ะูยF�ษ ดƒ@…Iู=–ษ โf@W@ƒๅmh๖8ิศง8ฦฝ๕]M€พ}๘#dHYฯl๎=‹๓}9ะ๛v ทิ�ฦR๔fx้ยe”[ก“–a p^+ฐฯ�|]]c€ร=}}์แ>%+่P€9>†�๛ฦ=ยn�฿Y๐ฎ˜Fช]ิ�โ7มva�m˜iเfyƒภq{(ผ๓� ๚ฯะGa9�ธฅ]ี๔’†��ลฉซoฒ<ูศะๅGฯ(=JsใฑVฅ๘Y€ืปœ1ํป.�…@‡!ฌะq†9aCr)ะฮ˜h#ซaM˜M๗์ดjฃิQข†ŒูPั^4#Xg๎�ู> ุ๏์jI?�=วtพœไ3d”๗F3G'[-ŒMฅb์m)ีoฅ่=e$฿ฯณํ ขKญ/Dn๔Gšส4)`ฯŽH�lฌ็ฆAภฆก‘1ึ™ž$M ดแSr)ฏฦ™ำG๓�Eห�ๆ<*Y™€_ฟ‰€/+ใทj๋๐5๖7—S=ข๖wึ"‘ๅ๛ ฮํัคf€.;ŽfMอึ; YดA7๏WNฝŽ๚ู`ณ:ซฦk๗V้�ภูŸ™ฃt–ๆา๕ีผ~+o;0ณ ขeสไใ๗ 8๊g๛l๚มะ๘เŒ›ˆ็2u™ฯๆ�™M็(๓๖ํตKyŒฺu๔ฝ ค๗ �็ุ๕wDขืฮง71Cพปฬหx๒;๒‰E๚บบ‘ƒL" ‹3ุJฐญ๊ถg†IŠF์่6ฒžI๘ไ”ใŸฐO๋d�”ํ%ขฏญœ้‡pƒ‹4l๕พ6–ผ_ํkฆค!SZ•้e ๓@๖„Y๙ ำE;แ็X ์Ÿ๎uฑ“บฃ;aใ๋Mจชป ˆ/ฒxฟ์}๕ึz€!@‡I| šหVฑ72vๆI^ุWK�Vจ�AืฺFฉ>*B—b!X+‚o๔”kmฯธ#„ว1š6aV.ชำวฟ x฿หyh็ผvุืลุ_ืจดŸfฟ ฯข6Bฟำฆ๗Ž๘ฬ˜ฒฏ•๑†%ก&+Pp�#Ž=ฯศ~๑ณ์ฒำŒส๑›-ฑ\˜_จ[_J } ›2:>พ˜}Œ”{{ฆ๘น‚‚No‘�ฐส๔GHปถ&{)”u}e�๎=i3Huฃ E็ฯ‘ูง๖r ยํฺ/†�็dฟjj|l๓/o=บ๑ฏ~dS~ภมฟ�ำฟ\ฯ๚“ึษt๒oฮ<๙xe}—ฬq ศQ3‡„ฑ}8K–(ฬRุ@�พ ฎ์ฺฺำwGp ]gฏŒฌ/ห%gำ๚2T{ q6�bŸษRA๗C0l!คSซRศผมแ qศขvƒmฐฏcู…GGโ�oฏง�ิ{ช([TŠเš8E˜E“ฅฺi\œษฎ@ุ๋ฉ "ฐDภ<๘ุ/„N#ขๆgึ/IแQ1๓Oฎ!r• Fp๓ bซRwg๚Ÿ}Œษฃ็วฬฦ&๋dม ๓"C`#mฝฎต]หา๊4• M–�ฮ ™ภ‡ึฑk :บฯฆหฏผ…‘ยู^mฏ!H—j0“ย๐๙ึVeฮ!โ0™au4� ะ๓8vไ— €B& km๛ฉ{ฏ อำ,?๋Moพ๔>๓K๏สWWU๛žณcvดbvY  „ั "„.L์ ฤ… 6ธ`YRฐฐปฺ!ฑซu3ำ==ำำ�ำ]ีๅMVzŸ•�{ว๓œoš+P่ฆ๖๋ษฉ4Ÿ๙�฿๗ผว�ฮ๏œำ…๓�6i0˜ฝ)บ#ฝำฃ“Œ]ข7ภไL:ฆ{~๛„Fถ_‰ณiฆป€uัษ๖a ๏š(ฤRฟw<�"ขxo�K 0œ–ฃ*ฒิ๐nn-‡‚t�ตรๆ+฿dอึฃf<œk‡1 ฝ=]Qs,%ั`ดY๊๏jaf์UฉJ…ศดลš�ฌMฃAv\!k$ฒYืศzcpผT(�…"‰<`œtพอ4ใyคญล)(ขK์wฎำปสห็˜U?ฆ/…ฏ๕ofช ฌ_žคT็~๚๑๛่rŽ“  ีาI9 โเล>ฦ านูh!0จ!ณ Khะ-5\วาพ9ฎŸฦ]ร&kโœ๋ฌ&3 CวNบ�8๏[Pฏg็ฉo�๐“4<<มb๖|๐๒ๅศ๒ออฮroŽค)'M็4๘f› tฯ6ํ|อ~�<}๔็๏(๔s_*c4 ” ƒNืะNาวdU5Jสฉ{ฌ�zV|ฑฮ๛9_6*;l‰QPฑฌ‘๋ฌsœƒ\ฌรฮก�aˆศ.์’ล“E sya1โฤส๎Y^| ค#M•นเ:ƒLoฯŸ0 ์‡ @'ห.พ๙|Ÿซkๅ ržิ<Žด;z-_าคmj}žNกฮ‚๗ฎnำธX๋{ูƒก †อา<3ว‡‡ฃ๑’ฌ็_;ตApCภ#ŒิOใq๕{wย๔šU�@�%t–ถึ€@'สlŸ�สๆัPซ��ณdG–:K]iฆUO'Fp �‹๏eHa๔�๋จจรจฒ~††Sภศ2&ฏำ{…๕ค๎ž^>gึั ‚ฯยŽ?y๖ €ฦ๖๖n5ฮ12ๅšฝ๑๚ป๔Y˜c�6ฐ-๖_�ขM5[‹BP�ิ…AปGึœR31>๖ก`ษr4๏ณปท'๕๒๕ึ;oก฿ั)œ?dผ_>็„lุMฎญYF็aช ืร๊๋่่ Lฃy>Lsd� ัฺาศ4ฉฃp�ตฯ๓น๒>t ฃๅZqล๚่Cหฃ์” ฌ@ฟ3H=„)iยัmŽ]sriห^คฺ:]Hฝ–Lๆจฐ๘ตœ3๕™,,ฯ๏ฝV†žำŒw9-LMฃlพ@Š\�oˆฃอ=Q‡n9P,mi]CI๛, ุ|vา‰ิ๛Z2๚฿�…_ˆา๗ˆS #ฅ5�ผz‹Y้ฐJ:ฒ€rYพoมำ&•s๊๗i>฿๋ณDosปpตB)˜ž”ฯ-Gv+ะk~Žu๎๖9‘AXG2d PVบหั29มTฯฎS1ฃ7฿~#-กำ‘muนAซM#[�ฃ่๛๏ฝ—�{ฬ่Xฆ๗ฌsฎ็m๕๒Lๅลsค์ไๆ‚.ušถลG%พƒ€ฅฬu๖ฤ๓%“D›ฒžฒ—…ฬ1ฯX๘์‡ ีo๑g็”:ๆตg›ำ๋ฏฝu๑(€wF�J[ตฒN2บไ!Ÿเฌ;* l‰”ฺฃม ฒeฒฬไฅn๚@๊Z.9ฮ z�5๑ฬศj�?54K€<ฑถŽ‘•ีช3˜ื๕^} G8็ณp�ตฝฺXmฟบ;œฯท{kะo`ช/‚ำH€ฯ{{ฎ•v�s็C=_ฌ_๚ฤuทYb™rPX0~ดNฉzล๛UวคyvทWฆฐ 'B๊j€–Žh��W;ค}๑}๘$CKฺบบQYฬCQ สฬ$1PถœKึJžมฐ๚5๔˜๎ ึ…‰0�uฮ๗&ฒ(cYP*Frbีe$uดdำ;oพMi0‰5�ปvๅ&’๕E ๙๐ัgฐ็ฐSŽฅ?=€ฒูฎX“ฺT.ฬ๙zK- Vdๆฝบ��ฐ v)้๔์ zŸ7ฐ‡๊ ูฝ9�“[7*ห์๓9&ห์{ +Ž๑�ฦfZๆi#\ต1 YSwญำืiiฦ/อ 34?ฌp|ฏ๑ หl�$ๅ�]cŒฃMฐŒิ๒lมYม.ณ๘ฺBหง�ฑs2t7๐]Zhœzก�"๒‚"'๊ปM๚๒�<฿Dfุ;ภ ๗ฆŒ{๒์๊๛)ฃžOห -฿ิ^“‘๛ถQดษ‹-ภƒ๙•e}ฦขk:ะWีศี:c+ฐq2ศตa^ปื‰B ู3๑๒ฤฺ"Uแ�หWw+Ÿมœไ๔k��dd >ฒIJฯDฝœ�%cmvล๋q@&}ฉie์�อ้GŸ์�/?�ว๗~ใ;ฟ3๛ใกผพtj>ฮำฟž�ฺ/�ณฆ‡ฯฦ…เฟภฬ๑šc“ hฎ-“œ›c“ศด๒�*ศžu€O‡GY4-วŸ3)ฐเฬi�"›J ม‰ตช\>\^)ิ๊ต@Sb๐งา3c๙‰็T`*z›บ™E GAแc0Gf™Q2่ัXv`W`ฟืauส€จจQA(T]Š’Ÿ#โฅRูVCูSi•—๋RQชaค`ฃwอ‡๒vŠyดฮ๋hBjh๏ณทœไnฉC?KJrƒ์ฉ ZTM(=xkฐ wษ x0ฅˆ[บA€'Z�`3H6๏ๆญืรA:4ฬs์ž�Gsผ;ิ2Œ/CญาXลษCฝ๑3škึ9vส…tฯ*ศ-p‘zg*๏RŸz๗1เใK0(fนญฏฎ&+”‘!บk"pPNนkdFนฅRฮTว๊’ส‡ยmรญ<ฒW.๕งทฟ๔ูฌ~ฒY4หค๙P 5ฮ›dMŽXK;[c–Gภ@๚›3บ+อg„ำ[1–๊ˆ น]๖‹๊๙ฬR๎iw‘ฦ1 ใัธPล[RNึ…n๐g๖X„V-aงก�g_287๊>วR˜๚F๊ตYoื_GBง)dMFม.ฏต1Q,.ฝf]ฺฺฦฺ6=>ูEฆแ}จ˜Oฺ8 fLnNTkUz็ื้*�C๊Jf��ุๅ�cดุ”,S0บ˜๊pˆt€๖w7น>d”ณ๒งฒCyjศwqา/ด šฝผ �|0 ƒŸilงฉ ™ผ&ส7p๗a‘,ฉƒใ๐{o ฯœณถ=ใ‚…๛Lม MฝC\S้~R็คใณ<ศ/oไgฑง๘t0~0|Nƒiฦค%�™.\ฝFภา:%‡>ั7a yดยกPN –mˆ*ปd`rr‚ภg4@็ ฯ๓๓๎ฺ*N?4u๒T่'๔†฿ฒ(ฏK#eyๅPฆ‡5–u4>5ุ/j)ตซี—f™€ี 6^ฒฃlฎ<พPAๅ๓&ƒMภ๚แ฿„ใท p"  Pจƒeํญk'>€U๔งzDรซมทv9ๆรณ7R ƒบว� Dจ/—`lm"SX\๒t‚ƒ4ดฌฆŸๅ6ฬภfฉe4เ๚ฮ YN|ขGฬB๚๙ง้๑๓็กฟ๚๚0�่๔ซเง็Hะeฒพบฬ–E2ธ�ฃ9็NZ&‰Tิ"9็ ฦVแG=%ื.mRเศ{iํสBี๎†"�Œรจ^ลYB๎\;ฺ;ำฃว๗รก๏๏ณ9Ÿ”pJซจฅ์/ฤ�<๊=พปEำP�VHึ�I4fะ๗๘Œซท`ฝ๙AFkŒ๔บeœฑูกฃฯ`“ๅœ^ŽH†Fคf๎อ€้ห$ŒRญัุJbด�ภฅ;เƒ~ภปฬj,ถ�s_d}ูH๖๚อWZ �8�‚tfฌลK�เ๏�ฯ-/`)pM|žŽcl<๏�„6ข/F๙^€8Aฟ�ฟs/ฮL9Œ.KkDa=~]ฝ<;a#V8{:^B�gฌนสE–——™ฐC๙ูข @ื >ํด฿H™ว<l๒งs์๘ภฤไ( ‡ัดวตพK&ุ=ถ�สRŠหฏ\KWY๛ถผ๕๎�้ห_�jฬ8ฯิ–s^i †ญดฌCvˆญ:โ˜,�ึ*๚=๊๏,Qัั๗แ9ˆพ'�ห“�Mƒž—b์ฺL=ว๊่๎ geำg–ญYท4Oะ\`Aฦ–4b›‰้ฏ`g๗๙พค d-ัLXฐBฐ )›ๅ(Lp�,มrR‘:O@า,aeUA€ ๏ฒ81A0ฬZ๓พฮ}ฏอXEฐ919๔แ๑q๚!=โฐรŽ“Iลgp�ๆfc฿ฒmํ�{T‡๖ฃษ O 'ลฤั็์O3zQ ฺุ๋ ลf—๘PSใำia–~Uึ‡ำ๐ฑ€ืŸ ีs–”j ึVฑ=KC๋!ฟY๎ฏฆCเbIุŠKิ’ืP:ฑ—f&็นงMฮ!tzฮณฬ uUL=`ดkสธ6ืำบo๕–lƒ`ๅ๐{�f3พ`d๚zู]2^lฐง�yฮ Vีๅž๕่oEศNพ‰#~ฏ]ฟŠฎจHS330T็ร๗์๊๊Œuฐ�ปฅt[ิห�ศFี•ฒ(โจ‘กวs=s ไ)dJ]ฏzp์%ๅ•ํญ4ฟฆ' 2dฃิƒ-šฎฑ_cุ“กศไสโแ]8‡x|ž�Cํง€6C]็g๙0่ำ')็šนท็‡ฯ ะ๊งฯQ฿ฤ˜TšศJe๗ข,ื v$๏ญ]ื�\บNๅ€ฅ๎/ฏ๓slœ�‘B๐�3ึู๕V~eฦฉฑ๑_ท[v.(;.‚Iผณc„šํ๕ฌ้ท ๊ศ๑�}Q.แ~ช๑dฟYb~$๛(ƒƒวWฮฮYF  ตdE |f•Aa์7zฺณdฌ`0~๏e฿€R๔๋์ฬ\ฤ!2Ž(%ถaนใล๕;;:�x>๎s€=�6ค;ฒ๙ˆs[J ใ่่Z�“Z–�nศ(’๎`<gYโแฒi?s‚@— ๛วบห<ฐLก_ุžX(๖N๙ฅ! KL่)ผกฟY๛�dร kโฝตรŽํล‚Qๅsฐ%๘+ฦj6ปT&œบ$pq kศๅืศrf<-๛ํT8K‘e‚Yษ&}T�ำฤu%gษ๋๔lซฤhถ_sๆrล�ูฟ๛�d>ทห/��๋็พค๏ค�ฏ�Bู?ผ๛K 3•nšม€๕ŠŽ๒:…^ๆ<๐rrตf;ขฑว:A๑ภ€tปr2l Ž�ฉ'ฐ•jmkZljฎ_ษfkฦฮฯ๖วN*l\ณูIั"6fภ*ก<มbS3ƒ{;˜ช�ฬเy(ยเu*tƒN�O…ม:7ุ ัŽœ๛2k– ม๒…฿จ ี�็มะie๕@ุุลภ�7=GูI�ฺ๕KŒะป@็dๆพใฤT}สฃ#๊9‡u‚€ผตRวŽำU†B/DˆฯQผ5uอแ”ฺhจTปšภEบaŒลร้4dVลlฆ]ๆgวง˜7}— }d)%x™a‡ลf23dŽYŒ<Jณ“2%๊bFpœQ[‹!2๓”s^ฌน24@UJ๗0๗vuปศJ„บ43�*˜ ธ๖nฒOŽฒดฤฦLM]R2u-ะ�V1Zน>D•พ๒d‡yณ�Hฑท‡ิ|ชleKุ„สfDU8ลฮ˜w4#/‹�ืYAข๘ Zอไrฝtช�ฺมA9,HCฯGา�๛O ๖mแฤTลชvฆ%๔๒uๅฤ�.‚X•:ต�(pฝށŸrB‚โ…ำƒฬr]qอ|^!N‚ฦ^:ถtยsฮ�๕ุKP_Xฆ – Zุจy๓Koง.2PRu,ฒูvไืk|Ž�`€ ‚YWว˜ฟ๏โ4=ษจถษ…~)4|-‘ๅภ‰0saๆs๋ลrฆ" p�ภ�[Jเ9๓คฒcศ _*ตrt€ฮ:nž๓–3Œ:-15�ฃเ๕ุ๊๕8z)๐†f"tHฌw.ลธ˜นึ๖น*~AKม„ ข;*|Mlห 1:ํ�ŒŽ…ฮ[‡ƒซs`–Z#hOฉิ6๑‘I%`!๓H‡Kบkc}Sฐ?ž่nภ‚ศCฏ้\:s~ฐTะอLบฦ?šCแdpAผ,ŒSCKK8}พฏ `9Af9`[%gพ–าปส๓ั2.0ธฏC๔Ž‹“๘Œd ‡ฬฝ,ฐณผ Dิv{๎นฯ€มœ{ฎŽำธช.Pc!K�‚๋fx_๗@–%_บณ๊GืfR[W ืqžzบh„v1=~๖˜Œบ4R›‚`-Yบc๗v๕ง Ÿ™ษ@— ‚Lณไo:ฤฮmฎHะQXdทw้1ฬ–ฃ๑น#ˆโใั RŒ+p28๙,]฿๊\Wเ p[881ิ.็ฃ‹ๆๆghึท ฃห�%ˆตทu„Nท�ป๒!“F›u‚ ˜1๘2ซLffc=หฝœBa�68สฆo~๛gb?2่“\#YC๎ร‡}�ร’(ƒBืNPหฺ๑™9J3ฆฉฯฌ'อ5๔ฬลพุหฆท{0M–ผ๗ฝล>ส�โ~ฮ)1า™d;)ซ�M��่1ไ\็ษ ุ@\F†ฃ๋ฮ Iฒq��๛Z4เšปZฒ๓ืฎ]ฦัฒฌ@zzŒ แmฑผ่ฤ2@@aƒ๛žศ๑|ชืดื~ฏmu-CชอัฮฮฬLง>�€>5อุฅ๔ˆพEfฮb”p}c=_uœ๒œํŽ๎๑์™:Dู๐�mๆจ&…็Yู�ทฯศNิพ6กป ^ค W.‘™z B,ฝ}จวt9›2=7เN3 ่•+—ำ��๗ุ›ํ๔o~5kำSใ}ีคŽS—h ี�าYํ6๎๙ˆ ŠkvผดูPƒํƒ๗\Œmt]m๊+€`ฏ”#K%eร˜•ำสจ9“ส‘ฯุ[@<ึfะ 4๏ ๘๗Z‚ษ#๚CึSLC8๛-LถธฺฯชะูุC๗9 Qภ “ง็โลคพ5Kถ‰,:%Gะท‡ a=ฬGk|๒บ;Ÿ}ย„‡Q�&(ุผพพก †ูCC6มNฏ?ƒŸcŸe�†~R‚ฑธpฐF"ฦฦcŒ’h๔ีฏ-ฦt ิฌภž้่์ฆgล+ฑ๖&ฝUG ฅ�ŽMฆ�๕�6=kfฐ)ฐmฮีc‡4/&"ณๆUmkศ=K:สฑล๖[จBGjQa่.|Ÿs๚fฑ‡่eฯ‘‡Qฺศ~Eเฦ๕j฿ี‡๎!้Dภตctญ>บัทž™&ฮE[{{d �ฌrภ�lG{ฐ%ั)ฺ2ๅH@ฏฌนf,3‰บ}ึS…€GvWฝiฏGkื˜yฌ้Ž�qฮ้7žšœ˜งDงIา‹เฬััสฆใใ ยิS๊gฏ?|๎ฯ{ท@]๊uูoE]ฏh็|๖‹)p฿Y๕1xฤŽ๛<63๖<€|>ห็์�g=•ิ�<ฺคI๔ 2ๆg[JzJ@pหdโ ƒqฤLf…W๐=Oฮฎ๊ฏ8นL��„T)>ŽำธไŽ๗โ�Lฬ้K๑ฝO=›ˆ๎H�‚`ุs*‹#ุ%๘i�ฟฒ์HNว'ส3ซํอ`นr/2ew™ภ012Cผเท?<อu0ฺp€Z”-ฐืŸ๖่˜ 0>dไฐA'f,‚K“‰ฺ๛+W้๓ภฟ‡หะ์=๓–d๋7kGu๎๚๘%ุฅ}ีืึึ๚ฏ` € �๔Qdฤูใ@ึฑ6Dเลมฒl�๊ฦฦฺŸ๚e๔?โsj“J}฿ hp_ok๊สึำผผmDว3 ถใ k.›T"จ‡ƒอZ89ย>tœ1๖ึ2ฌ˜Z€ Yย ดผNŒฑต Žo้”+งJอฮ-ฅงCฃฐใY๗ ึJถ@#kช#ฉม�Ž(GกCี์๓๋$�*FAr–| †Uqํ�ุญ ๖MฉŠฯใQšwฆn$IqสuZชพบD๒ ฝyขŒ�฿๋›๓OุุลGฒ7Œ2cธ`+ก/d„ิำl��[Oฒฒฝ่ศlŸ#ƒุ†ฑย*Nัฒท1จฒˆ้G�ั๋่?๎ฌ 6ัศฟ๓�O>�ƒฟ ใู๕—๗๑๕ฟ�ญฅ฿๚อ?Xœ››nณ;ดn{ถ›9ล๓(:›ขQ#ถ๔‚ฮไ๓ิŒ0ฃถผด จุ“%š†€ภฎืิVอUืT฿ผyๅ๏ํํ\!ฝ๗w�ฮ�7๓ท~๋?‰ฮฃdoฌ[ฬcถ๓euฬD‹คฅ8xP*คฮอ†ฺเKบฃฟWq#ะŽW��&;ˆสU/aะU~นรmนƒŽกะ่˜ล“‚ไจน]t™A‰มญJ�l๓15^y0%์๊้d‚b๐�ƒ๕T]JฐรgืฉดหปAฬ[o}ฎสfž7Cเ—X—rje'ฦž‚๎/‘™kเ€.ค๎๎ซd{–pฒ—๙บ๛iงq�ั)J„ๆ”าอๆa|UT;ท๛}uU't;œุฎ๎Ž๔ึ—� ร1M)ยศณqส่H{ฬตbะหB[ฺ8D ฃdTา๕8ิ:›ึ–ู$N:žิพC�šBฒu‹าvซ Fu@tl ส DชX†๎>œaŒ‡่ซ”6๏ำ,]-(v๏ซ BŸ™ž ร�Ž฿#ณฉณฒถ‚๓(@…ม- ลึk๓�ะ @IDAT ฝSCพa…ƒล ษโ�@Gƒฌ3จqR>*ฌใรA^^˜D@—ผœ/๏ˆ8“š6จm(ม-ฆ^จ<ญณEฏ๑ภX๑�‘ภน-ฏlŒนบ๗Ÿ|Ncži๎0สณล�Oึุเ๗บq?๓ซ{ฉ5หKMศ‹t็ุ:I–<ฤฟ ฑy(ถจ‰gŸDฺ�C8๒๔YI;†/@�$่Y„a๐by%ฯ23ิ_๐,Y (็๚ญCG~ๆๆfhฬ`]ำqคmm้2xYœีqึyxไ Ÿ3ผอะ_งฦฦXCด|8mœ๋ลธŠศ2h8<#~ ,น>›dUuิ T]cm*ย~ อ๙1่๓K„�lบๆG๙ะ่๊„Q`Ÿ|N8|ขเู €ตฟg<ม0ะหƒฏ E9๋SB€น‚ะ(ฅ+ธŒ�/ไ‹�BN\s ฅ…2i๕B›4VE i๐ะ,0Fเ;66สuัyฉ‘q4�2๚Lฺ› ม6`mฬช@Ht๔๊>ŸQKฦฆcŽŒดษa†ด 'ฌƒฝ@(ํaQธOuIฮั8'ป-ˆ€ไึห�f=๑pฎอ ๓3:6จ›B:ๆ–ษˆ˜๏เ’ฃ iX ตžฟœ๗Œ ษ7eฝฃ! ฿›� ˆ�0ˆG จiฦ๓yฌซๅ':š๎‘‚4F์p8~gฐพ๘:๛.P฿\—.ห:™$๘sž๙†>Oฦบg’Lพ3์อJฺซลwGญ๚™๎Ÿ๚e fi~–๖4ภค‡…%d–e8šำฒ)ฌ6ํ:ยY:ุเwf 8—[dณฬฦลฤ™ส๊2แ/ชJาWzพฮ๑}@ๅ%WP”๎�ฟ5ล๖p�žL‡2ุสืฮษมY1๔พ€็–l�ง‚46TB๓๏@7ฆฌฎขฃut—ฝใ~eษฉคIซ�”[ฝมพข<2ซK๋4”ั`ฮ7+่92๛�sfvšqvเY6’ f=๏๊~ƒ!ฉฑN5ธ}็s˜Jํ่ cFZไ,,Mง๛ท?ง฿ ์ึ+ไ ๙(ฤ.i๐6งœ๋n‚ไEวsb์9SZำซoผšจ3i“ฬ� WX‡]tรp/=ƒบlPศ็�ุ0ฑญญ }[ 2~๔ั์�\บะg๙I_z–g๏้๋! Žฌ--Qห๗น๑fชฑ\&๘F‘ฬ„`�แะ{๖o๔๖D0ณฮ๔ Kอบบบ้sC�+23>>FoŠ[ศิ4A-`1r`ˆbขYp}dิฒ็oผuƒ@a-J฿พ๚ต/ณ~ŒI|6อ�’้BฦeHCฎร97q pเพ)๏โ�H•)6ป๊ๆฦไฮ‰ๅ พ‡ฏฯำ†ึฺด7wNqฟ‘ษ็๙+ืDะUฟว™ฎ‡ฏWง Z’เข~ัภุu“‘ฃฮท„ว2bถY T8z p=‚&เึึ–‹ŠิTญ7๋4bž˜งูๆ:kผehนๆ„P๑aJ(ร0“Nš๙ำ•PZล„7JT์#ีŠฝw,คๅ`/f7#ฉ!ภฒถฒƒ0€Žn1พ0ปn?Ÿ(‹`์‰%ศxŒ%‰ ึQฟง ึ…ภfŠ๋6ษศšศถb?ด%สoษ6Gs โd�›b๔e3eHมข.‘ฉx๘บส็ปOL Œs๘3_๙J๊้aฝื๑๓`D’ �bอว›kธ� ฦกโณภุFท หผ๛ดธŸ๐‚{œi…�=วN‘๚ร็™I 5้฿๚*ษ šŒw์Qrท“&'iธฮ๚FI0๏eIต:ยภฺ=ูฦn„Ÿลู,Q?๊f˜% ‚W5ฺแf€เ-Jผ{ฑ™3ฐฏ์?ทตผ ภnๅฺสะ™"ๅ๚ธ�๔ ยi;ซmต•บUร"๓๏=ึ$Jn๘พ&@Ešฐ˜ธ� วง๘jw�€๎สม.็ap`0เ�ูงfw‚Rž-�y“ษ6 ืN  P9ํl||��ฟ•า�ภ“@:_�วK mฬีํmทœ์Bรธํฌ.2๙Cะy๊1 ึ˜Ÿโึัฑญฝ']|ๅฦuฆ1พ฿หถu�YOืFeฆnฏใB�Vš�=ษ๋้แ„ซ฿&Jๅพใ๏}/=zBะยg8p „ฤ๓ก๕ขคvํ้ ๐hยศ1ˆ—ไ T{4�Bเฬlเ�จ˜ zฅ็IAŠXะณT๒h๊๚8ิ(Oƒด2 …†ภ€ˆ”ฬ:5QฮFฒๆgtืฎมศ\Dัืื0พง•บห,Ž&b=;๑ช�nt@>ภ๙kม๑ZYสี็Zฯtr–หF๏ฯอa\ ๏|ฎฌฬล๕์ัเF4๒1๘๏์ Iึ;4˜์TX!YMตงญิภ๎ง9ht(1k2ฅuฉ๐จ<ติWัญ� * ตณ€ed–2�Rแ›ศvTืtr€gรเJšg ฿m 6lr๎ทŠ,u�ฅ+ะ[ Nq 7ศ*v๐ป๊cษ�ฐ'ใd์ํไx$๋ํท ƒ7>1ส~”ำ ์b์ฯ&๔*้นะ5”^[๛5ŒN ๛X adŸฌ mฤแ•ฑษ(ตห1จMA“ถพฉŒ๛จจ‚R\ mฐ๕ฟฺ฿GZN[JC'๛7๘A�ืจ7ท‘แง#ํฦส฿^6a"#DcJG๒แ์�€AŠน3@ฒ ถ—FCฎNp์b_Lv&‚YฎอzDฉ_‡งLLXbN๖ฃ‡8ๆ๋d‰03ฬ-ฟ|‘ฯ„าK‡ ฒี€|จScmuใ“ษkค-ํˆŸฯฬ(z�d๘$๓น๖:P–�ƒBภฃX#(๔J"ŽQฦg๙ฅiส๕์ยฦ–ููM ศl†kšเuT€<4cใŒ8ุ๋ฝ3`ํยษ4‹็Dะโgžคักฑhผณƒใญƒcœ0ุ1gูVa๏ฒ64เสหร/ิฑแน�kไฃใ„ ฦtแHไ่�สžด9)วบŒ‡€.‡ˆzไ˜ฯ‹‰š6ก3กcŒ ยั Ž #G‹Š–ศ๘๘ZN้�^‡๔ฟŠ’๚8ณyีิ�1ผผฌ–แM&Mhดั œB;‚ึ™ศพŠŽฯLL„sdึึLู๚fไ๙s2๕0[ุ3ญแ€ะ˜•ณ_fhu ฌ=V–4คฅ fOฃv*K`W+ฏ่{=่4 lๆ‹ฤฃ_t”ฮQH\ŽฆmฌญฝฬnJkิ–#๖ฒตฑซค็ีfJ6ƒ<ฌ9ภ!7[POfD–•Žท`้ Y~ม2A™"ฤ�ึkpŠรัqฌ3๚ๅŒk ไž็Ivl-*HฤิX๖ตBภ˜ก.ณญฝ-=}๚,=} จ ล็�Jžฒค�’ตWoพส™gผ%r{ฤ™c ๔๋ำ“;Oำ�Ž๕ื๙Tฺ†แ`P\�ศจฌ๑\(็ค›ม7ฐณแกฮฐฬ0 •ๅy~�…ึ=Yฯ!ปVFAึP/e�ฉ9ุภQVไๆCsฃ5[;ำศำ'$dคoๆJ3๐�ำ.ฒ!5�zRA„ฏ� Af=Ž2M˜–8.^Š3๙be-=~4มง๋m D8�4ืrL`>ฒ&๋Dบ่ใOคฉษษ๔ฏ�ี=2ยŽe๔ษงุฌOhx�๖ƒT˜˜>s%ส๒ค’ ๘้ภjๆAฅO้/็1งLะY�‘๔เ“;พ๛ศ@7ู๏Btื)ŽW~ ฝ!�^�๊Wกย#ƒ่๓"�ospŸ272l่fี-ฅุณ๔‡†บ……่M๔ฤำวาํŸ�˜&’}Xืฤฺฺgoะใฯq"้cมhฟWo}ํJA†b b1 เ” )hฆcn@#ูำfรส)๓เX!a9ำ๒�tบ‡žพxํjผv ”cัd)l๖{@ฐ2h76=๘ฅ )Aษ†mV_T�ไ“า๓็Oำ7ฟ�ณ่Fฮ็ลๆƒูŽNจแd˜`๒ญ,สRAจ ”ิg@<9เŒr0œ๕jฮŸูRใญ=�ใ๒—h๖…ฎp“3’�ท์ซˆ}ณ‰i๘ ›˜œฉุ5ม/dบจˆาFdCFˆv๕”๛<2่"ปwฬ„L†’์ณ T ="Jนc}ม็<๔ฬ•[ทp�ั%ฌpUŒน\ไu‹ป๋้ีื฿‚แ๘*๛“ว๔‘ำุฤ0เ๔Ut#๙Œ}an}ฃ|ฯ ืQŽฌtSvฒ 539ฮuSำNiๅ:ฌA/ม žศ๒อฑ/H (zฑ0™๕\:fr‰๗f1ยœ29ซ‘เ-๒ธดผnŸp›ฆฯ ๆ่ฬNณนซัณ%ล๔เŒeธ#�รs๚w00ุ"Xฯ$oฐํฒ๒ฑ)Nษ…:y{<ืง๓ฐฬ$ภF๔ฟบไ`ศ‘ฤ{<ื๐ห;โœ“ูมV”็ฅ�ห4k|๗๕˜Fณ…=z๐่^๚๖d”ืาW�x'�kๅฏฐน๒ด*๔w๏+7X›œ�สœชฏก\€โ>ฟ|D^ตีฺG{_‘๑ฯG/;!ไh“�H‡2๕h.ษ…ู˜p,ๆWค™c€vC้๕[ืาkฏ^E๗ๅFบŽŽ>cพฟZAปกพ5๋ญ}– ใใ›ญ๏จฌ”*฿๖Eะฯช*ฆ'Um 2HOค5|ข—-)-e�ฦde7บึ็ุ ง_ฐผaป2๘๖ี�ŸvelษL 9�eM‹OS ‰ขbcm๔ูC—ฌั๋ฬ€๐ ะ†FึŸ๓ฃ?๐“ฯตฎยzมรBwโแ'ซ+\ฟ3ไU?[}ณห๙ณ�E=`“Bu๊3D ์mเทะtูื*>”aƒtลฝ‚๔�่ผ]ฮีฌนšpฬฆโCฦ__Mฏ\นL๓[ๅ๒ปฃฝ|’ ฐ ธ๎�M˜‰ฌi$Rธ6>3ย]9เ฿†kอิห€ไ๓ํ7@P. ฒŸOน�Eถถ8+2ŠY™?ซ๚„ืฏ๗สZ2d๕ฬDฝ�>�F]ฃ์๊ณ4pฉ-].๊€™kCpฮM!`ƒ บฃ—�๒Tฐ„๗ัฑศH]Meฌw้qชใœํภDต�`{๐ …[ยšzอต76‘�€%–8Xง็ศBำlฦ…_ye€คŒh์ร{PHO๖:๖P{ฉŸc"Hฑ—ุ�u๛Ž˜๘pํ ั�MภOค๐ฌšDMmŒฯฮZYซijh_ฦžฒ&ูC๖KฦS9C�Kg฿’˜ †ฎPt�mŽ%่$}$ฯ\‘�8}Q*a6 44’(ภ๎ญรj์ํ้{งl˜X*็^vถ๑ม8G‚U๘็ฒ]e!rs(tIฏฝำท�แ�๔—ญ�!`/๙�ฝิภAqMใF]}ี�๊๒f+{ีถOv ว@ซถน๙๔ตท.446<๎๊้ะ�ฺ๖แ…W.=ชชj฿@ฉ‰ร�ฟ<ส Z[[Z฿y็mะ๔Ih‘เŒ๑์ "๔:"fบE45* ฎ™$›ฃํ๑ณ3วฯQn�อรa7๐3บRคXบ๖.่“tโ๒ส"œส,‡€็QืtNอขŸฃ 0�ญะš!*ั‘ฤฉˆ5ส�[Cรaั๊.jkฟยฒ"ย“C๊s0Pืฏ฿Luิ�>y๐ัNzx๗Sจณูศ`ฮM“ังSt)Tk[' ฉ"่…Rฯ 8*อuhฉดํM๎…`kzr˜ฯn"h$8ๆQE?อ^zฌ#œภO๏�O�'ใชj่บN—Xโ3 @šy_ฏ�‡– เฺี๋d›oœoัษ�aš‹Œ‡MV4 ฅจฌT.U�•๋ืกผ๗โT›ตฐ™VBู,sฝ8ช(]c{ถ=๖F'ไ๚๕WY?8—‚ิ\FำJ๎ญธ˜`บข'”ณภŠq'@Hษ๙–ฆ็่ท–Fšื€๒ทgปาโฺ2ŽD5‡}=‘ภมไ�๚Sวงอฺรบ i๚๙=๖~8s=ๅ(cฉล๖ˆ@ห„+€dTคC๎šh,}X{ฝJๆาLญฮ€๒ณถ”ฃDป�"NQz‚šE3ข`iDธฐ†#?BฆžŒ u›…EuL้$ชM=ฝํ|ม Žl#ู!ว9๙ึf€4่ึ–tŠ,oฎฎFภW]ืrพC๖&džฟi-ั1Kฅ ศง4ีŒ�1 �zg{, ญญRžrญูklญ%ฆŽ &…Mล๚อo�›สํ>อฦฝฮู�?eูม:๗ตคอท6ำƒ;า‡๏ฟ‡รฝˆ3ฆ๑ร)*นa—ห๑ƒึญั&›‡ฒตœG ข๙ูƒŽVศฯ6> "๛ฉk%($มQ]ึZŸ˜:หWชทฦEฆ…�ฒc‰e|๑:>,28xj:EaP8ทึฐEšŸcAฯษ.ู/ �'™ภ`๓j5u‰๛;G๊•—jr ็qส๗ฦq&ฮศ�N!…์?ฃ[?๙!ฌฏ\ฦฟ   †์z!P-ภย1๚AgQงฌ˜=ฬฑ@`?P๚b#H|Hๆ 0เp!ำT เ@IษS7ู˜OfฺTยฑoฎ7‰์X‰>ยQ�ฆ๑ฅ ‘piอHSMGฮQWษ็ถRงl๖tjj6€ฯr๖\@ย �&GฎทdVe_'GชฝYชpŒ๘|GaYฃ่=eศŽIหึนฑc๖k>GPSรภ๒—RŒ{Gk'อ•j \ �ณw6ฺ|๛ๆ[ัดส๓ำฬู|›๊rP!\@9X˜แ:นƒ๛น(ืfWผfๅฦ/ณฤžจuD?จ๏#Cฦต“ำ!of�+ะ8zล 8N›“[œน gโr[ ;f' ‡˜ณRใ^So™A5ื-ƒ๋�eฏ]k2%8ธออ่๖ฮ.ฎ!@}ˆ์ห<™์๚ฒ\KMtห_˜_Iฅ”6!ฟA๓†า-๓ค�iPฉ1๋ฏร?รโ“?I_�๚ทำGฃงwฟ�e˜R๔Z\M{ศB9"“NฐŒ็œ 4Ph›ž \Lุฃอฅี๔�Ÿ?๚ฯ8m&�ึ ห‚ั‘ำ aหtช vsFน†ฮ–l™"kปd�ฯญ ™t(ซnยY 'ฏ\ว™X\XภฉkPXB_Rฮu„e •ศย)z^{!“ษ^๊ƒ˜บ:๚Zฐ๐>>ฟ ้ P฿‰ึ�ซWiHL)Z+๋ลวฯ#๗fี{๐kพ�ฮืำฌ‹c�์OฑฑMณQ๖8��ยg–๖,.ง๎^๚ZLใ ˆ้๋ไ!งdl8็&2จ<‡XปไC6โวู$ฐO‡_ศ–‰)]๔‘สc฿y‹๐y”c“r๎†@„ŒฬJฮZe“dึีุz�๓žL–Hี—iๅ|ฆ๗ิ�t–ฺ�๐)F™ธลYฐ<‹‚"๓ _=€4�kmใO6)vฟMๆๅl:z™Iฆ�๑&pTกญRF-งUgrป�–” ่'zŠ ๚Pพ(]ึ็ P‡ห1cน`:_๖W1eบ—.ะ4บžๆฐ๑™k$V`Iฏอฦ^ู,๖˜’ฑ<ๅˆ]งGG์น $:_๖b>‘`7ฟˆ5ืnE๓t๔ฆ๑Š ฟ๐kธฏhp W�YŸX }cXOัee2cO้Eำฒ\R0ภgยึ5!W™๎ไ฿…๑ๆ~ม0(!‘€อrฦš๚๙�‚ดดทžnDd2 ้บ๙“;0ัhb^Œ�!7ฒ -ญR~ิqfXOD’{cฑ‹๖bณi�wฟ�aบ�๙=&)ด…OR.Roซห\K–>์ณเŠบสณืPoขถ&… Xเ๒ึ‘mcldwC/=|๚”ไh&๕๗ฺ/‡„โ…>ุn‡้>๗ท‚}4‰ฑ[ฬkPe“ซ›ร'โ,ะ �คr/�c}uนq'ˆ;qฌ"�ว’๕…ๅp๊u^+ Zืฝ’k่่ศขCmtN�&<)†cงœสโ9ฐD๚˜๛ก<ฒ ๖๑ป๘œwSV์ๅ~ศเ{i�ฟ๙ํฃง฿��A"ฝUŽ#Rอแซๅซป็ hีk๋Wฎ฿�Oฟ�ญ_๘ฯ�าฟ๒ื~๛wฏ�๘เฏv๗O��ฟ๛฿ํGsลฮ]�ว๋ovNLM�[ฟ๓;ฟื2ทHV–เ\ง_วXaั‹า๙ถVดgั ’7^JU ยฝ @๎ฬhœ!ะึ๛ู•�CญรPLซช–,.�ส˜ฤ\ ำVู๋—|ฎ5@กpQšflฟ@5๕ 5hfcyŸAF้•มZHขŠ`ไ้”๔>uMdศWp`อ’gqDศฬูTส�*…฿ัZ' ™Ž๚ัq‘Rhฝฅ=#D๒6 � 40–ๅฦk_"0อ‚จf&QDึƒeh>9’nctฮh:Y…๓šk๎&(‡ฐyDอโ๙จฅ^า`ixh(Žโp-ขคAษน/วฏeภlTฅcTO‚#€‘ลตEบ๖OะkŠug�๏7=C)๗ๆz๘;ฉ�f๘Šนv•ชืas0ฟ }ž=ฬๆ๊ 9“v‡ฤูุsณœg6ฃตNƒš<œ"-Š5‚้pฺqp—่ˆ{ŠฑKะ˜[(7` ั๖ฦ2ส„LˆŽ*{kžfB@ภ=xโllจ1UŽ4XRๅ " *�#๖f�sl˜(๕ุ.๘RR7ก[Uีfำ4ฃฟ๛�๗ษฮ= ๘Zฐฑžฏตฝ>]พ�ƒbทฮำkj) …€ �+ฃ4AƒZีา…คูXe\ใขๅ่M@ณ�*y  สิy๕ึ3ๆiQŒ˜y‚_j‹7\–ฉ็+c__งห�•๋a–PฟO๐ะB๐62๖<ภู ึˆ 4่ธfญ(#•Vทร{M“‘2ฐฺAn@}“zgรศBณ๐*๔#”k ฿{ญึš Tุ่•๘˜ัวŠu๔0+bl๋˜]ํx/7Fใช3ฎS ฟล\I#ร Bf”กsภI์?cฮ9ิกˆFฉ8้ผE.PมHช�ร &ใผ•๛„ฯ:ฤูณแขิว>ฤฆmณฒ6v=!8ถผ‡•=Hๅœ� ๚ "ม้\XาPลฯฒ d5ูบˆฝ\็}ำ”ฯ93cษ%qOฎ„q๎C€ศN๔QพEว`�UWูฅ�{ๆธs~rŽณ†R:บิf{d�ณd˜ B†AyีQฉฉหฐง‚Vฦฝq6Ÿ,็� ุtหค์.ำœ๓ˆ5ัHš�ต†}b �ํ โ^kฅข�๛๐ฝi™Y.PW๏ฑ08โ์Dศแ!Œ‚6ว %V‹งณณณdJว�Jm-๗>Gฐา฿�A�ฃ‡จ‡ญกy๎z~ฦ$˜๙ลhz้๛๊q™ษTdk่|๙ฝ™…ตๅ•p\ํฟ`P๗mัz�hฦv8๗=๖ก,ฒ๏‡มC&C๏๖เฮํฯั)€eฃœ*2kiO๎}ฅt Œง{�t$ฺœฃj�1ฮ\?ŽNฉcc]งEueccืG-,NKถฝ“๕>ƒฝภ>*ซ่ฎู,™๛uญ"–๕( 6xฒg wหg“ูz‘�ไ�๘C˜R8mศzAฅ},๋ชๅห`-ฮ™2‰LŒq'5ฃ+ุ;ุ…ภy’Œ–ฮูVอ๒•3ฮ_[G็ˆ ๚จ‚3‡ฅโ^Jำ๔่ง๗ฑ6์5๖F™แXเ%ํ|ภ2<7ๅdรm.)๕_Fฮ>เ๛!c^F+๒ƒ^ˆnCN๓Z@d˜๒ุV๗EVC๔,alฦeฉ‹gY�Goอะฑฺๅ�f ฒ\lฎ่DiงfบฝHk^7ฐ K{ฌIฎYคูh4t‹๕๛/ฆ–i‚H3Ahษ�—€ั>gDfฦาผ๖ูฆ,ฤqค๊%S{Aๆˆ9Vฯตุ%@ส#8”ๆkถณ;แ„K ,ย|Gเต�,พำ,lTg�๗ทIฌฏ7ะ๖์๐ป"œXฯฃ�— jœ(€�Aงœ  [หm๊6ืn0s[Y pYŒท฿‹,ฆพ��ด›6š๕54ดภ�ซ�ฝฒฒF)%2Wธ&Uป(…`$‚@d^นฎฆทŠg]]+“*”๛bถ�ตP'lฐฌก%8๒่:ƒtฯฅภง�…F“%ุ๘‰‰)๔ษ)T๖6๖(ฟ[6PN๙ษ!๚W]็{จ‹4nฺbห|/ฟธs6‚ฯื๘ƒ_ƒX_งฝ๔š<๓๊ K ๗ำภ&[ๅ�•‘}ึ@ิเ8นคฃณฝค๙*Ÿผ‰_ฒcหFŠ‚๊๕ุLY;=oะ ่ใŸผOŸ†‘T๘\Kย่&P({ยณ็C="๒hSe'jํฎ/R๊@ฦ8�l<—์๛๚๐ซ๑๙2•ตฌ;ิz@�นนi@Xล9าผŸ5ฃถœฯ?ฅ ดนsนdร*๚ฎ& CD‡ฎ’�f/’Jšd’œR��sFV”ๅ6ึ;„๋นพ~๑>ผง็V฿Cโ{kฌ�ื๕ตนค๖�3๋}*+_L—R฿๊�“‚…aI"ฐ2ญ_?็๕๙ฌ‹�|€ใ่%Xฆ_%ก/ฏ�Wo &้cฮT งข"๏[ยŒีฏSงXยก�:"ิ๕Pฟศธ 9๑\}YํกeRฎcถw๖๐๑�,s๐ธ—ฦ(OkGTภ8"เF�ํ3ณณFฟภu กใ๙–F„o‚๊วซ๛”G3ๆ^_๎!8Š?)ห�Pฦ}ะžใฯ๖คWฎ_ „ฎฑC'ำoj‘‡"ๅ่ฃs๖|o—ฉ`U€ผบa๚ยฒญซ ‡ๅLi�*๋P’zS[gPH๐aฯ {˜ฤูb�โlฃkฃ‚$๘งnาึSษ:)7ๆ8ฮใผ##€๚K6…ด\ม3Sฺุ{™ ใ>2a?ˆ ๛M>๙2'`ผ@ฒ๋q…>O_O}๐‘ใ,ย€ ศืฏ*bฟ–iŽผI้ภ1ฏฑดFv‚`{บ™�ฺโ๏๖{poฝ^๕k/ณุk’กge€-เAษ ฅ]Žณืฮ5ำ[๎ษฯzuA๕ฐ}ศNฑฒŒ|ป/ฒO];}กc|\ฤO=s�ำ�๛็�๔฿�์ƒพ“{๋x�—๓�^jเ ๖kฟžๆ~�อญํฏW6E๓(โ;อmู��ƒ�ห_�ท�ฦ?hศfW N>๘�ะTโ฿�7~ํื�๛�๖7�ฦ�้w9�Rพค%Kห%ุยูPฑ&ธน๖@PYx่Cแpภ D์ฤฟM Z‚RฯG_ื˜!ฃ^S EฆฮPiฬ็€ึlSP˜ืศึrเอ.ˆN๛Ÿ–ฌหU HKท�H:ฑ up๒;ำ` uค,ฦ4…�t๙๊อ0^ b จพก แหร้Y@ๅ�ํขณ=:€ค ƒjS0‘jวv๗]$๓นมƒŸcฉ„FG็ณ‘ฬ‚t๐B”ฌlMณิุ‰ษAOcŠR@…๑~th=Dแ0Ik“ขฉV3ถ ฬ�=žำิ๊‡ ฟFcก!‘ๆฺv๖vฃจ<บ้Z�ึAึnเ,uf{PF4�›รˆ* @‡@:็กง5\ฮฯอวh#<ืql|OpFง๒˜u’mGwC๔ ๗‰โZาะ๐x๚'ฟ�ว”ฬใค๗D/‡ฒ ิ~“) ๋�ลมพิำืOPM�%ฮ‡ภUttว ะ€ฏ/ฮะจŠƒ˜$Ž%๎™k์๋๖ธ'พF'๋Kp@ฦ‹qคซ›:kะ…Ÿq�ิฒSฮ๐๚—ฟ”^y�Zj็zdWH/ัI+'#^ษ>7ฐ‚U*^๋–p=G›์ห ีูๅ๖ณ?‚ฉกแ9AฯแAฒYศCึFร`�_‚ฑD%{{ศXขGf–ำ5๗3 cฝนG๏ษฏ=๖Fวฺฟป๖8fฏ4 ฒyT€ๅG๔ุื ๙�ศฝ!sc_Œภ„|2lื—๋’+ศธษตฺ่| /ใbMฌMyศชดศ(TำํณDลY็U”ณ๓ปบ๚œ9ฦ‘ณ Bงศ�๑ž๙xึสๆd|ƒQXh 1 ม{F:Ÿ๏ศr9oูง@E^^XMKs5kf‘E๎ฯpDถษ‚๏เTL๊THˆžpบ /5BBqœจค๎ฐ‚‰?๛ญwƒฮZ‰uผฅม–`ฃ ‹#“V OpTฌTๆสqผฬุฎQS่$e�/Aษ๎q�ฅvzvJธuลฺอ’pฌ'`R‡™ีR••พพ>>7็ 5ใ\๊ฟภžๅง>�!M฿ศ>อฮฒ�ิ โ€ ฅ;Ÿ�K“ฟ’Žช '๋๓_๕ท {ญฦˆฦต8๐>ยQๅ3 ศผฯฌ`ื๊2]�ษ$TโŒธลป€†ฒฦะ%+”ุ๛ฃ?แ|ะCGz –Wg{wz๖ไq}๒ (‰v%_ๆ=–y~n_sMฌ๒ะฑซK”‘ฝ฿ลษV‡ฺ0rnšา.ฮ„ฃ<-)แ๕– ฌะ6ะหล๚_3EvภW‡rMปะwทiบh—oษอภุ๘มŸ}7��์3ฮYTำ2ฌ@Yxce&ย"๛ชร+�อ=Sgแ’ผ0ˆ~๚<‚J๕ไœ7l—@ฺ+dก/^ฝŠ ๎ˆฃพำyต†™ฦDกS์ปแ๏ ถฺuาอภ{�†›ศก2พD?e่๎งŸ#eั๏ฆ‘ฺเ6{หt,วšžXภ W><�$>ู' ฎ�3ฌ๐ฺ ิญy5ุ(GnR<ื>Gwฉ็ต!ฉแ&‚]' ช#๋k@ถŠฯ4๛TK Žถไฮพ๓#k€sอ 4$ะq‰ิฎ�๔W๊{kเ'ฒไตXe`ำ๐'\๚.ภ0)€3ธหต�ร‰ใ A)ภ‡™ต->�2bœ{;’ืมdิ~šŒ}S/x�ศตr+;’ 9Gแใdใด ำ�ข}็g�ิอlจ{บGูˆูทฃ#X@ฌฃผGขฉ฿/^ฆูn?™3วสQž…Œจ๏/_ผ–zบ๛๙,d™sฺ–m'™Ršฦู#�มฦ ุ* ”ๅ!๋ค>pํYbS:K+lณUOไ‰?ร MY่๑ž�s›�ๆฦกp+‹e:๕ ล ๛'ฐ‚ ฒ�@ ฌ็�e;ƒ฿ห $๊๛8๒Z?ล}R–ฎญ‹?ฦ2ˆTธฏ‘i็Zด๋๚ฎM�๋kx/iใ- ้ต7n![M๔)(��reoƒแั1tฤ"เj@ฟ v…ฤฏ )ไซ$mๆ`GกืA�โศ๖6R๎ �๋Rž ( ะ"H“‘ 3F]ๅฆิ�๐ู.‚\�ฮ็yN๚q-ิž�<ส ฑL๘8ปiœษFซ€๖‚ye”ฑฐL�ธw6็m~๚™�ACG„ uBย€*ฟ€สำ&GŒrืษ.yึรฆนฦœS6J9TfeY˜�๑๙�ฮ‡%œฎญ /ฯคœ‚erษไK๖ฏqeež1�ฑว[0ต่ป…฿rส�^์ฃี™Q๚ฉ_ภ9PGh๛[ภฃํ2ฐ๓็rภ}~ป๘�ฤR{ๅฤYtIห)T;ศฺฦฦbำๅ่†bNmฐ”z;ฺฐaL8�H/fฦ‚U,%ณุ๓5์Žม๚ปฑณQ๖dXฦžx%žcงอษส�ฤŽY,๘'ภศฏขT�้T๖ ำŽ ๏๓ณS.ฮv๐eN๐ตvฐ?=–‹๋k›่t=dภซ›#a‡l-ใฃƒ�ศ๘ืRๆxleu์งถZ๖ท์ก™…y๚|p/€ึ‚ง–ู#IY ‘๗–AfrXytฟ•™œฬJฤฒ”�R4|w�EฎฒญทXcภ+Wฎ†~1๎๙ไ'ก_6ัŸ=๔=่pฺi๊?Kู‰ๆคl`qอ4็?๘_ภ^๚‡’๗R?ศโˆnVทดฌWื7�๑…� ฟ๗ห?๗หŸ�ฝ��ี_�็–#�?฿ยP๑๋๛฿ป๐�?๙.ิฦrmbผ+1&*^‡ {Vดษ@฿Vทฉ ญณL–ฤF6ฦซƒTำ@ฝ~ุภ@hs…_ษ(ร72”9้4 €๚รLA-A=Y๕Y3฿น์ศ–สฌบ†XW__—_าั^—Z๋1{ซิ<ำYwฏ}๓Wำ๎ยT๚��6B[’z๚ฏล6““Ÿ'KB๊ฐcว…ู ว m�€กU%ํใ&ุP[฿”nผ๙UOŒฏัศ/ข`v#;3ง?{๕ํ…ๅ xœYš”ยช๐Zmฬg@b๖*—ู$จม)0p(Aม ๔๖GY€{'p— ฅWVP{gุ5�ฃ็๏ิ ฮOอปาP๋๗‚N๊ศ%Zๆ@฿๕t๗�g้ัฃง4Fย๑รนดƒ๋ฤไHP• .: ฒอโ๊XX๖aใ€,ฝ�0ฬ๐;6ษ์d_ื`l y)มGGถ4๛-ะภฏ–`ฑฝ1‹r ซ9ฮUˆฝFYEจA‘€ฤษN๛สƒ‘ ๅ†!ฑžE#ซcnICJฎRŠŠ'ขˆr}jpXKฝฦIอฬ,งฉ‘)2wd�p่บ๛P๊ิxร*่่C1้l0ฉฑณ>ดญฺฆฎtบวxN”Y๗ธMpทฟG–e„ำชcํ:Xa€ น~$•คrข‚tzรMvQ„G๔ใ˜™^$ขi†F‘ํ ฉ€F‘ตd จ ญมกต~˜นูอศัเเ•P๔๑ž(lืภŒ™‡GTุ๕QqJcตค฿‡ฅ a…พณGมkไบๅท์น:ลภ Š˜ี8#Cn}qฯCTB^u4ย9`อ^’�๕701๛่g“’เ{ ฏ๒/Ÿ� ‚Kห�;ฯ•อภ& ๕๓Ÿฌ๊9Q“ฬeี๗3Zqฤฮƒ฿๓๖RTฦrฃร[้ิ(ั‚1็q- 8/๑<'ฮ:ฯ๗รuD=sฅ81yNแgมฤJ g@ณr[[GผS‰ ถู:GหZZณฟEะฦ~˜ซ#ฺ์ย.Wp‹.๋Pจป๚9“@$�๒)Oฺvkrฮฝ่ Yzขก6sbvุฌXg๏@๚ษวทa1J2่ํP๖่๔ผAเo4l6ยu$p,ช ๓2�k�-3โ…8,ป8Ho่อj‚q6๕ž’ 8เ–Ž:hัุฃa๊�วS!ี�มvjจe:gงงป;�œัป๓!มfkถ}วZแP๐RฦWฎ‡ณภkniv�‡KๅสฆWนณ ฌร฿ฬt๙ลFฤ๓ฌ�tMจpŠเน’เm๏x'}�๛d.ศ šm่๊์g/bifธI๙ยตูณำLฃน๛9}_จ$๘_…u#๛ลฆQาะทษj˜9A๐=ซห=๙+%ัฤฑ“๓�JYž ขlkึธ‹฿-��?ข‰,ศ•�ตJษชะc๔ฉAำ้ิZ†R„n:$0๐kงqœ ฌbqZฯฎ,“5dาฯ=+๋œ�3^cp‘OO‹�3t™ jว_ฬเ`hxNผnืใ˜๓ฃCn€ฒแ๔„,SCฆ?ฆทฮRLฏ8ฤ‰ดฑ฿๗{k@ปเš›MS๗ใล…,ศถ[^ไผำฤy๐`เ๊์สbZ๚p =Žพnข\GถGl›}.†ชฟnšc๚ฎ A‘y?C&’_นฌๅ๒2๋IPRฦuVRr็,๕“ณ |yNvำิ๓n‹๒ฉ JŠำทพ�ํ|”ม„้™y&ั8ป๎YุY˜KC#ฯษh๕ฅฃ๖�t๏'ŸฅS@ปr์UF0 j€,ฤ0+H95ไpIภ3ํZ๚ฝ`�@O=๗ท‹ฎ5QYม๋นฏœ\;žค tึ)ˆ�!5ม™X๓”ฎ5tJ‹ฅ๊ uP)๛จ_ข“ฏ“lŒ|๔–๔๙9;J*๑>ฐt‚i๙T€ห„สงm๗›Œ^(@�๔�๚๛�†ŠY๑|lฯl^์งU๔ย‹ะ_•่ํ}d{{c�|)]ฝ�J๏หฌ฿ิณ1ภโ&ŽI>zkƒฝƒNฌ�)‡e๔6Ÿ–แ•์;‚4t9Wฅ๐ก๎ถ฿“›.่ปeเวฟw็s๎ว�Hj`… $คะฺ)ใZ9๏ฒซใ=kžw}Iๅ%0d_Jฒฒณบ* ฐ๛จ.Pง๙{ฏW5S.ปภ&”‚MฺD pฯให)7_�coญ วถ๊34ฑkyNh"Iร^๏lํง‡ซ4ŽหOoฟ๑j๊ hปFะQฤ฿F๋žฆe€ฟ๗๑Jโฉฑ๎F*รๆ”สp\6{น4O~6�๋zฉ�ขฯg IมŽH!—แภsXŸZฒฯ—aฃ’tq2าณ็Cœ‰ภo€ุ๏=…kด“n�์‡๕&\อ„M›�”๐!•๏\สƒ–f‘ภP๖3๔)zIฟM0ษพnฆ์™•65v๕hก‡ๅjลฌMq)๛A ก~0เW?{>-ี*แ�โ{/3ฤ {ยŸcmxyjย78@7�๐'ŸาOข‹~c๘ ์ๅ2‚.E่ม๖Žv�;ฅู%&)ัŒ๗l๙ณฌ€$หหNX๋๚บ ศฑ™๊ ฯอจmฯาล�จ�+๑]d๓ำจฎ^,Mฆฯ>�$l“:\=ฏฯก๏๏>ูkBF•~ํ!:Ffo@ฅ์ }ƒwดuพ@ถPQ(š—�๑Rฟ�ตt๚ฝ™ฏ�ŸM]+Mี ��สฟ๛�)‹Š'๓ท��/๋มFรฤ๔ไ:qีิ๊ไแ่Jฅัท—@i K�KษJ™ิจไๆv‚�b�ืกa ิt+&›YG†ฎ„๐œบ หŒ@#๕กรu8�ึH์ฆ™๙ั@—;฿ทฺ'ชจq:ลQ“:_@ฃต}š"ขํชškRGO–9๐�ฉเfMtแ&ะ์้บมตWงS้ไะ}พฏฅ[/YEฆTQ๏egัๆว:ฺeู่c:s ‡˜้kอฦNCรฯศศญงKW_I�=ฬฌ~7ๅa(ๆŸ�-วhฒยไiR=ใั๐8ํ(wW:ค[์็>Gy๓Œข๓ :•4pŠื0Ff‹qฬคำฒฦz ิเ์šฑ�0€เ?ืVด{‡์ฬ.tชe‰†gh>=ธ�˜Cfwn๛ขq™)˜ล(Kƒ## ำุažo>ง๘สๅ‹(”<ฦLNฑGdพ—6ูฏs�ผat์ `N๊ๆ> \,วPY,ฌ.ง๚ึ๖ิ{้4๙% ฯth€IqBVฝ“ๆŽƒ03&ฉ=ถqZ ั์ญiอด๔ H ๐฿็^@aQ"อRIฅ๛ํฐoฝs"๋*!ณพื",€\งdฒ`(๚ šอ�น};2|ฮโ>+ค„#รXลF>R๋�Lร—’๒cœ`Pะ‚jhg4€3ณ“ฯq’@�1าv9๖+Ž–ฐAฌA๖9/Jnอ;�…รษ๏p๊ํผซ๑ำมŒภ‰ฟแ‹p�4฿ค�elศq9€#8‡GฅdVY/F pŸพ] a+, ็u/พ จ!0ฒ1ข๛ฆำฎcใไ‘‚!แ‹BX9ปdํl<™1^oฆHGkCร["ƒ8ู��ˆ` ]›ŽPบฒTฬ�[ื]ฬพŸPฑ1]�sฬ|aึ™ร`ฮ—Yvณ๏‡y8…8>ึPŠŸเœ๛ณ“6�ฅฑ.– ใโ�P€ฤS.ดG4ั๔,ฃ€U-ฮฉ{~N@”)ญD.0.8 Q„ฃ์žฃณbฝ‰mv\ยŒ—ๅR๔t�Yอฎๆศส&๕ืnutฒ›.4@"(ต™Ÿ็๕–@ƒ4ˆZa›จ�pไR%MฃxRš†ฆ^ธJ6Œ=ภ๏โžOศ˜ไฺุฉ„๚๎มจ9ฯ�ฃฑks3Mญฐบ{ฺ9w$œัถl–บ๙�ฉ‚ }ฦ 3—ง‚dฮ{tฦZ˜m( –๊)P …าZsqห{์ "sis‰ฬ9gซ็tว`’›0spศธรพขฬ‰๋ลdงร˜:๖A+ใ4nโ๛�๏Œ^% œO‰ห๒.เ.ฮ ?ถ)ก!p:s฿ุsd�&IRพpDD๛๗ะ‹ถ Cํธgฯ0Vืวžนพ์Ÿ;`๗q๔38"๗๔แ‡? pยฬวฃี๛�_~d.Nน‡B๊๔g฿็,(เ––ึคะฺ็่ฆmง๋eHใ”ลหหฃ ึ๚#pฉu.bm๗`โ€ ะf—์๚๓ภ๕ฉฆพ!]~ํ& ‚O[aภ C๗Y;7:Žgฏ›ฃN@% s[ฮหj‘YทF๐iY†ดXคšห&sƒฬs๋ฌ•zูฬ)ูaภฑู™qN์2œ;ๅำเ‹mŒฯะž]นv9uะKiื•u"ศ%lœOุ้R…แ�`�ty-�ฏ�:คึ�ฑŸ•|Ž™5`ŠhH(@ญฟดมจู*๖L๙~๚๔IJฯNำิฤ {cถวBh�”'…žgจฆ�l๋Wต‚ ็d�vะณ๙€%;K4�ไต"”œlฮ•คUœnƒย<>/br|:ภ ฯแง�Ÿq-่C์๓๛|0นช/?@_๓ณSฌ๗ศ˜'ข๖€ฝwฤฒ€ฐ.Ssู[ุz่ฒ gอ๒ฉ]ภุ"|‹-ฎูF\ัKวู๋ทั‡–๗^ข<ฆ�พแž›™ŠPฦพธ๑6�iจตoz‚Lืๅ?ึ์fh,*่เูฃ„X2#ุ �วKY{�CีAใwssภพMŸ๒้p\ภด"ฎ“>ๅฐ.๒a7 คX^ศ›ง‡€ัา๙ตํk-๋ฉตณ'ิ9มˆ>A๕�่@คŠฒ#ึ]ะIช–‹]ใฃทrd ›gะB ม�/–d”"ซŽะ”มขฟ`บŒๆหj๊‡wํJ ษV•๕Gn ‚‚ฯ๏u�๓ฉO‰ •5Rp"ต?1 �(’ุŽ2€ส#€j™?6ฃฆzส(๏yŠTvฟ่CŒ‚Fํ‰™Eeูฆ|ัN�9ฆใ|1�N)�!|‰tuฐ‡–rํู˜C&7ว˜ม(O๔ฅAj1 ๛บ�ษ‹�\cค;ฏ‘ไศะ7h‡ ๎ล�K๔�LQ1 ฝoฌี7icC\}ฉRปL0ƒูzึื›‘๖ฬ™-ศd 3ฌ1U—�๋ร๋i@cjt*ญsW o๔ึ‰(!�\6ษ๕ ฒ…ฬซd ฎเ�Eา!‚i๖E PลŸsูy๚tdฺhบ(ด์)%ƒ์4,>ฮ ๋ใ=จฟด‘ ฅ:Z’aฦ!v�hq เvฯ="{๛bf”ฒ&J‚™rSI�0{Oตไล0๙ŽศT— 3E๔ภจd|;จ<ฃ1๘เล,แ:าฤฎ›1•Œ_A?๑:ฑ”sR รำๆด๛0ŽŠั้็๊�๏A 9ื122B‚p:utคw�zvฯ&๗šb\ukKฌพ$\&โผ_ผDi@/MH๏ัจp9ตำเ๗ ู]E6๔Mฌฟ—S‰ ปN่’n๏~ืะฐฐš฿W5–“๕ค^_๔หhขชตส<ืr‚.:!ก`\แ๐ๅ…ฉtแฺ›ฉพญ3-M<#a5žๆ&ะœฝสิ๔%๋Hฬ5ม@ึ็ฦTบ์@IDAT.$ฑSำU•๊——aะ-งsสzณœ๓s�k‘˜‘™่gสqO ผYŸโ2์Œ�sฮ™ฝฦ,8AžŽ8ซฅฌg%็A€๋เ๖ gส‘ว�Gฌป wถrxฬ-šYข4ืsXƒำืัซ’ษT$าzzh”ฅฤึŸ_ฦ™\ล๎5pg๊`HŽNฆ‘แ!l5บ�ฝฆ๖= ŒrhึUะเyฐtโ0ร๕.&�ณบ็JvG๔ŠAฮšX฿อ-ฯฦWFฑ–so_?cทX๋ต๕e์อ>2M=™ TS.ฃบ3๕^ธ๚On�๚™�ฺ๊ญwŸr ‡œ>้ๅผิภžฤทฮฯ‡Xษ�์ง‹สฮ� >Jkf�าฯ�า1๒|๘๏Q#ํบ`จœ�šU1ฐนี€it ni9งs%krคsay'ฉŠ ศ?F๖ๆ[d(–่ชปOฟM–๙ย€;(;‚86ํ[_๛9^ป“~๐ฝกญฝ@yLำ‡ ˆf&fำฅwCฎ๑๊๋๎ไเ”ฆ้ษฉ๓A1e-ไ•1fสZ‚–‘ŸะฑŸ&Vํ=ฉฬๆI2'์&ภ‹V”�ญtฺ]LMŽ>วi-H]mdp8) ฝ4๊J=ฝ�้ัํฅฑงรธ–๒™๚ๆ( ฉฏ๑EY้|ิใฌ๖๙CฒoKะ7�8fช ฃVRdUีoPจฑดู”tPฏ%hbœOo3ฅ‘‡mะ�@>Q�R~๓1€' iž �6จ4ภำIัaา J�3�j—�ศด‘%ฬƒF๎ˆฦฦ‚MŒNคํฃย๔๔ัc(—€tๅ5ƒีFภุ@๙‰3Œปฒ-8อEฉฃฟ ๆM–l๊BZรAฤ!ยกc‰ †ถ๘—ใมฺบฆZช"2Ifj4ฤ๖OุฃŽัฟปW:P‘Aเ{ฦl/.LKำ#ี5๊ฦ~ย๑B‰fฬp‘ฒ*€๖(Šผม~š้ˆrไZG[7ฬš�ฉ–)dฦฉP.œ ณcลศ��ั&ม ”rไDวrz|Œ &G3-`�ฃ๓,?Ki๓ฆ”œ ม…3ขำH]ฬณ>œ� ,๖h๊S…ยvฤ� ฮZ”�S‹œ8ปŒุ๋่ฌˆBไฒฯ�[Gyณ๖ฮŒจ=Eœe์๕D๗zฎเ”์�=.ส฿‚b๋(‹1lEญ Tาฌ๕๏…, _๘ฌ�วuzNNษ�โ0ŸkŒธuส:L#Ÿขc\ฺN$2ศ@ม@pˆต๑�u˜}ธwฮ[ฯใ๓ธeฒู€9ศ3ๆf5ฬ๎€™ ๐w :๖าฝ‹9kxƒ„>หJdะ˜น:n]ฃkšโซ^=Dซƒํi2 Y๏˜›\A@ห๙แ(ไYnล๙ะ็:ฮนื}Š^ปะ7 ลp( ฺยPWžwA;หNัต6๋sฟ�Lฯุต�”CืX€sฉพ4[[Pšป๖M@กBทCdhdx ๙‡!ี‘ลi.K—Yw?#‹s๔ฃ๗@Pฮ(N๎Ÿฎ๏A—dอ@™sMtา<{2T ฐี :+;dnm ๆ‰qš†ฯูฤฉ9เฺŽูื=้ทvแWpฒน3วgํใ(v Bห~ง๗idฐ,_๑wู๏aŸ๛>/F9ƒ:y่pห!�ึวฌผ]๖‘ถœkฅ™Zsฝฑ็�ูใ'์ฃูtƒ>๎‰sใ}yฯnภ {จ0€ิ๙gS#Xr\˜๗ถ‡�ฐTลLะ2ฮo @อ XTย?ย”rK–๛g–pym=?-L�Nฯ…ฃ๘ฝ?๛n่ล2๊บI็TQBฤัDโz›azX�ดฒJ_ึ�๘9` ฯY๛สญ•_Ew:1ษ,กฅ‰OžZžยY%ุญ ี‰ตฏBฅ€๚%Žบตp =฿‘mG?oคgุ๓J2ปEฆง\ห>%S๖5(ๅ> ผGว_ะ ำ:n๎Ÿ Zฝ๊Zฮ)O62=ร–ฺค˜ๅ&จ@'ฑล0ษ�ws:ฃ“ฝ ˆ๚‰ ŸE=๗bd;พh=โ~ ๖ิ_u8ฦ–’ญ`�Nฯำ3่S|ฯ3ฯ�$pชฤ7’Aธoข ๆSั�Œe_ขY'๗โฝไ)3nณ H๘ศฺ๛ณๅH:ฺ๊9ฯ™็_\vQฅฬMฮฏแสใ๓žj๘:=ฅ็Y'|ArQ๚าป7`GโWฑ่|ฮ9Ÿ็9�fl้(ไผ ๖ป็๗‚ณ~•ศRาZXL“QJ๔ิGฺm‚%มฒ˜@� ™๛3Ck`๋พK๑ds@ˆ์Vฯำ๋ษธญํณดBฏคUXK6ฬำฎํฃƒA6๘z+C" ถ่`;zเik”ไUฃOำ“แa|ŠฃTXฉ์ญัซˆลรฟรจ)ฤNโ๗…�ฃ‹๔ตฒธdกฺew๙9tTbขว)ำ์๏`Cึสc˜ฦ๘;[k0eณOL๔9๊4‡ุฮe\saAIฃศ�!ธ๗'ฃ#0ีšะ!ๅŒ‹$จ ๛ฃชCSq\?ฯŠe‘Ž(ึ6ูOอfยซ€!ฃcฯำ ฒ๎W_{;m‘ฤูฃฟ€�าF—q?M-ฉธa0�ไ๗ำ่3˜Sส๛QษY<$ถ/S๘�์‰๗ฝฑบh�)&ปต์2ญŽF�ฯรว๑ลVา๊ AT]�$Kaฐ•jูฏjŽศ{ฐ๒>[ŽN๔>Nฑ๛๘Tฒ์ํbIžeฅฒ,,ƒึ๑> ะMz…l!ส—M0๕1dj๛j4<2ŽFๆฯพธDLิBO<ส@ั…%$.3ฐT๗�็Zอ�กgม{8ภบr&`Cฺ๊๔sIY5ณ7•6HF‚ถVปฏ�ZขฝOLหteZ๋so"[‹ุ–ฉ™)๖ฃ‰ฦ˜ฌ3{#yนฟ2ภ…Lu! ฮ–๔ฺkทฮ๚.]๚฿ฺ๚พ�นzโ/าƒฅ{ษ฿๙Nข‡ม1_x��โ�็�ฺอ?š�๖ทา๘ร๛๗ฟŽeยฦ™ม0ุuvต ŸlฮeVZ็iตแ_วxŒ็ฒ๖|ƒถŽ๖T€qฮGกHa๎hหาฌซมยฑะ L:฿ฺC;39™~๘ƒ๗ศ›ฝe|ูz!d[ถ•ื๖ยJ นAI#ย1 จŠเจ…_‚E[$`4›dส๋€ŒTฉL�&T@†‹คQkhอF`e3 X;ฉะ+)ก•ะ�ื—Z๘ฬšๆN�wค!�€f—ฉย๐๑^ฃฬo�เฐUึRJ็) j ็๒ฅ—aฝDu@GrฯR’uล‘าแํ้๋A9ท๐ท=Gjด„‹รกFYktโถP�RะƒฦgฐƒQr4‘ม›5GŽสฌฆl�ผิผ3N�ฎu�d็fhHuJฦ-ฒo๘Nพเ"qJฌŸ๓�mฤต•††“q[ Šใ �,XggO์ณฦฟC'ญTฤิูส๓ำS(�fด@ร์‡NuBp�ล=ใดรู!่;ำ˜`�tˆอ$šmฒ  ถŠฃฎœ‰mจ‘๗_R่๖9ฦ}ˆ’cฦ85šใbhกฐ n\N7^นJ๓ร 8Žส` :6ั4วysy๊7c๛ุg›ฯ8jK E#nอ˜ ืaoๅQ€ข’เสf”"dƒeE็Cฃ$:j��uุ+4ฬZื(ณท /ึาไไ –ฐ@œ5d‚(EUิ#ืเp&mUŠฃ]ษ=–โ ๒;ฎ˜ฝฐ๙ณร‘kCx;ฏั อฌUฮ๙ฦ่๐9Jf๎tิฝ—ฎลภำ^บ^Ž ิQ6 ๆNงNทNซอe(O8ฑš[0| �%,Šุงพ>มNJspˆิ ะน ศ+ษ@4ลดๆ�๓U�Wฏ\ข์ง9ฮJ>@ฉTฝ:2ตuศŽฺศEฮอ žmฃd—จ๛lสjฅƒmŸ”:j8e p๓$๔&N็_{ ีzf�Lื ฎฑ� เž={Vuญีg:ผฒ tŠl่ฆ้CB‡มF†�{๏คivฅ็�๔�{๏ณ2หWตซvhะ0 91า‚ mดึJ{`ก (Q‰ Š!i1ฃ…b$*8†3 0˜Fhดซ._YY•�{๏ž็|†ึR@ู™•๙็๗฿ฝ็๓ž๗œรฅ8จPื~�f๏GRฺ�ฅI:ี–dy]๏Ÿำ†SIPหฝ„รสต#ญฦ:{62ฦg†{ฐˆดiฟG��เฦ(ค|†l9Fw!U่gž๛Pพคฮj?ลhƒ%๏�ฐศ๒{ภu�kย$๎�r6ขCศด9aฆซฏ'l ๚�T6‡่JgP[ส8ืาx†Vอ.:ื�g๖ฝโพaฐDI๗๊{”›๑L‚ž๊:ํ‰zZ�ดnzlจ ิ=๗2� ��ัSพq{๑g?Ki<Ÿaxญ}’dPล‡๔ดะ+์ณ๒สขุ๒„Oฯบฒ,ˆ ~U็สdภ4„� md%ัหผณ๚ฺ๓ชO2๋ล‘IeM“�โน๕CฐG€B}๏ูaฺ@9a%ม�!อ;"ะjใ7๕ฌ6py฿ƒ ถ=:ฺšxƒd2ผ€ก๋dๅปป:SOwถภ›ฑ1O/€ญr&l่oZบjะ$ช� ะ…5๓Œซ‡ฬ๋o &จ[๕L„้xฎ= <%vละ๓ ฎ๋จ —jฃม†ฬYๅ*์๗‡๐QVf9ฺr4*,โ~'ฦFใบล๘hๅ$ผช‰3 ”ํ $(‰Uๅ\ณวศ„ภž�ฉ —‘Švฺ^‚ซ|๕ฟ‰“D๚6&\9บศ2๋7|hO”eฤfืฎ…2ญฺCฯ ฺิฟ˜ มU๙+zlศMะ> าฮy•qฒ sฒžคš}ฟขG๖Yฬ๒4ํ…z'l(็,zก/ธตˆ้ŒK๔W๖]ิฉnห๕k7ใ>'งUxก๖ห~x๖ำrฬๆ %ฅy4จ�[EKํ\พ๖ง��_�๏ใ๑GฟF�Qใ�ฦ}ุต๒_�ห๏ฯ๎l>฿y๒ไ+๙๙ๅyUd๑Žขฺร๑เ?A ฃฌ”ู—ฌำ3A �+$–Tภžw๕๖ฑฟPม ึฬV"{w^{ƒ1…ฃY;ื๔พep•แT็Gi”ตืY0eูrฆจ+EG:ชสพ!๓ศƒเษ6:อ๓ฅใฏ™  pญ๋ดึ๓ข#ไž ~XŠิ0Xฮ9œ{‘ฆGFS1ัmc…š]70–ขoภˆ@ว:ปov๗ืq4๓ไ‡{๋๛บ–ผE๖ล?ิ!า๖  #xV!™ �cvMƒู(๓žƒภะลžwœ@๗ฯ&gฮ?๗œ๋ Fส๕ีึๅ๚Peศ +€`�^โ๚ " ุƒวYๆŽAt�ปิu้Q‚!€VรบFศภฐœFๆB•” Sฯž}C์ั ๖ˆ ขะe�ˆถฆฎ<}�๗พœZ`$ ๔ดa๗k‘๑ ์nS4u{�ไ~บq๙2ดs€L์๏—ฟ�n่้M?�เ32N3`�CคŸ› �&Pฒ™็2Žฟอฦ tดxดt‚ฟRW‚opย๓๐,%่ภBtแฉt]}€นุZ?}]1ฟฯG6  ซป�C๗ฦพ€จkถdลZsง-‰)๐FP-๐๙mถvJ f@ฺ้y๖ @-!ี– >T*๐rS›<ฟy”Sข^ศฐW์ญ‚$H ~Ufmผjyƒ™ิLธŒํธ�s`ขE�/ข_  �*๓^ฏปgฐขL ์†~�7ู๊u$IJe๏=�$=z๑Y๊DึaใสX๓ฉ้ „œฺ๘b๓ุบg#iz�ŒไP%]ุ/รpผ}ฑช—สHŒฝ˜Jc0พ”หl”ซ ุZ*Ÿู&Ž04`Œัˆœมn+dM›้kฎ/t\>~ช๛โน4‘ฅ *ฦ�พ�W…ฝ9`�wn.ๅJSS๔๒๘อถ็iv‰ŽีฐLP /ไ_�)๊‚�kxaณ\c๏อŒณgSฉnฏ|7I ^เษต€‘๋บถ‘tแkv]ูฐzaŽ™‚Xว—Œ� ^f]ท ฬJ๑ฟeมU3*๗ํw๎ค/ฝ๛`{๔๐wฐ*ถWธyใv๘ว๘ฏfš-ษฺูฅคฆHFเˆJ]=~<ฌงC]ฦ�ฝ๙ฺสz�8งฒฅKsลr@;!›:โe•ลธUVZ–ฑz้’ฒ๕ฦแยRีึ)pv฿์ดัจ ฒe6ำtผ็์๔*z_ฟ[†ตเ)๋dาญษš€rV�WeT๐2+A%aหyhhrJ›&fz4ทF๖|vโ9 ล9|=๙ฺฐ•น๋๒RXฦ|Zbฅ@!NฒฤPซฤN„พ�'>ุ#QhK—AHขA�1ฯ!oฃภ|ํ%˜ะน<‹r�๗`  O๓ใฬq6๕๗-UธSฯzถ๕!‡…โแณQั22/žNค็วh ธ‡ย]Eikผ4”าŸDฑ=tํmญd›‡1^ปฉณน)]วจtตทฆขz๊าอ๘0ฃุกCะl2บต๏ฅำผ4? %Ÿš9‚8ปส.1|yq&‚� ฤ๊๊B~้‹v]็pฉศUภR—ฯ |ฌ�ๅฬ/จIŸr–๕(0ธฬญŸ‚ ใึU๊  `Lmพ™ŽฬŒฑ73š^C'ฺ’;4๛๗Ž้Z€ฒ72:—^ฬฬั”gฑเค ร้8ืู2๋Fei๏ฏอ‡*[r@›WVVpv-ใ€ฮ‹3gvัๆœŽอ[_fิkๅ�z$5ซฮถTำmฉb:กJ{ชCง๑2H ็Y=!Xอ!หdลuโะฬ€็|š�‰Yฯdur1ส::๗ฬr๏2zฮ.__ลนG�soฯ]~�ฟ˜์ภ:"@แผส/�\Y ็ูณข๑๒YฬˆzB,ัฑfึ:N๕“ฮข•cŽNV)P.a๐‚‚ว๚Jvํqฆ,‹บ4ˆCต�ชกคi|–‰%ิŒ"#\,hาRขญ๕.gอž<แlู@(kฦ&XšงTk‘๚:J$.‚~ ํ1ฯgึร �,ƒ;y๎ @Œ๓g#Kณw‘9fฟฒq`Yะ่Ye58C่H๖มฝท’Ÿ๛๗\?šE๒Uy๖= ฅ}บถv_Žƒk(ƒ:อฒ"๙ิQี นB \GƒE?\๓ @ม๓ฤวฯ��ุ&�eCB฿O:>žbอฝ๓o3">Ÿ]\Hu›,[8zบ$�&�e๓0žy็�๚๔€๕ิ uŠŒ๋�ัู>�้Oamะu“๑k”ฑเ‰ญ”m3fสƒgf›๕Xญๅ<ฐลœKsั—ฺh๖๛ยฎ๔ฤ๚บฮฌ…ฌฌsู๛่oฤฺ๙5๖ƒ็t๏ํŸฃ/เ™ *ผ–ฯค.ฏโ,)รฅ^C�ข4ก,%@!#~ๆ๑$ศ’เย<3แg�ŸAŠ š:Mf•ภA5‰ว�5€—ณ–พo5AV)[3I•ŽฮฮิสTB น๙้41Eใa]–kธฎ™t๏™1๖›าG@ืาhท @A} ~ส@ทL7๙,ฺผฐใ่A๕Ÿ_exNln* #xๆ>zoมDเ๏ €,ป-งoŽ€|9@EQimš]Xฅึxzt๏ ษ@Hz/ิh™ศ4 ฌฎฅไ† )๎ู๒ฝ�t] ๚c1๙ฏgF=๋�๚ณะง,ฏ็ฯ�Aใํุ�ํ�๛7ฒWโ~ีต์— ˆ-์ศ`ม!I2หฐ\ฯJ|พ/|ๅ‹ั๛ภังUฅฌyบ(—s3Œโหรื) iข�–zslƒ“ท6 †m˜จžญล�ห�-‹ฒ:สL๛‚ok๓—ืaPฎู�ำŸ�จืฬุrt^o฿œ@X� '(hAŒS๑A>ฌ~ข}ำff่งBฒฆ›z๋๖Kฉงป'lฦณฑ๑๔{kV ๒ๅt ํ•ษ MG€a<ป ฐ๒*;LŸ�u\4‹~B9 �6V้ใล�T€ยLvwyฦๅ…iสG›ขืฺ๖โx่ฦ=l๗ฤ‹ก+Eœ2v๏ใ๗`ู่T�ฯŽภk)๋‰ฯ„Š•)ำ6๔Zj้H‚Žุฐ›Rdด†๕;de็‘X;�หฮŒg3ุ <:�ไ’ ฏŸ�Nฟฟ„๓ู๊๖ ๛3}?ฏUŠNึ์ก—ด–˜์โ๛ศXr d`จืeUOTs?ฒ"-S0y2‹ฌ<แฌ-#ญฆG๗ŸฅmฮW9๛’ฌ8ๆบŒ�ะ/TŸฐz#‚3พ‡€Bฐb/Q4NFSg{ฯ5$๚๐)T*�ฯูไผร^Wว๗tu +�yล�s฿_Žฆ_ƒŒ<ษ/?ะšฟ™๚ง฿สy�๔~๑ใ๛๗฿mmmซา‘Z$˜A†Q&Q�gƒฉœศC84Kฬ8ž`จN ถh,&๕>Ÿจฆงฏj“}Dฤฅฉ9ขHŠใƒฯค~�ว\GTฬฌ*FลL — ๋ภnษ:4๛4าX#˜ฯๅฐ6 ศd2๘�G6ะB€ญ•pD *boP‡o ‡bav2Œ…QG�`e :‘ข๖pfy ฉ]žO%ฝฬ{0Jsดษโ)Nะ6‡x…€๙4fa3MLฬา๔้d-6 Fkl๔ฆ๑ฏซซ็Y KsB่xหKะำ8จŽ๓๊d#5ีา่ภy5@f#P4fบ-ซPQKaฒูŒcภDขม™‡{eๆซsgฐ-ะ๋นgโJ\%%Ž”qœื.ู๏M๚ผhน฿ืA•UVUข หฉ‡V1๊พ;:ญ†ฬr_�p�ื ๚ฉ็h๔ธ‡๓ฐ๒ุ@ �/`{o#hลี5ƒdแalด-.,๑:ž ฃ1G์ฯ๎>N�โ้ำO๏Gนฤิ�’ผRะแ[้ฅ—†`i0ฒฅฏฏ•์@Žuิ™ขsyKึOˆเฎน ภฮ2รl)ด6ด้žฏsEBu�ณ ฒ†Œ‰�<z์แTฒ(�Œ้"{ธ๕Sุ&k้๎Gา์โšS9™�P๊Žพ�˜กฝม3พ›`�จk'๐“ฅcS3วเ้”ฤผ�@mฝส@(3‘*)�}ึล1gฬ R2Q่–‡”๏aคชEฃ1žษช๋คร Eื€b(NI“้๔็ดฬ ภณŠ�tY7+๘`เ “"คdaไdศ"ik๋Jฝ��|(s:•f3 ๔2†ัe03izf๙Ÿˆ&Efฎ็gf9s‹d‰ ซ็<โ๎ำ’ฉาฎฟF฿n�ye]ฯ•�@M‡ฬฮกภ_V๓oงc2™ฌฅฌ„ศ๚๒z3”ฒZ Xkiชฅ8(^‡ธฎูส ž™'?ฅFr�z˜!‚"๛[‚'™9Žณ’�F@คn‘yUm}หm‚.A0วพช๛ษ2:ำฺภษฆI6 ำ๙Uฝ?�/4้˜*"" /ห“H3|ี€น&N;ฑ<ลฟQฮ้ไ)~ืŒ —ฐ”ๅœ�ัฯภศ‡uชฮธŽฉ๗์W๗/ภฯๆYŠภๅsเ ��ไณ–Pแศฌ0์�'ภ<๖฿,l๖ าั3gศฟŸ๓+™@แ#fำsq P๑่20่Vฝหธ9�}ส๙๘�ฟ๘sุ$๖ฦมจ_๙jํ~2œxศ1zิ›๊ 4ปํ7wt K ศพฏ็ไ^.ฆฬDฆตgๅ~ š�v$๚ฯฐ๐~:lฺG LŽ?{ŽsHฆˆ์�อฃ1๛+xrฮม๐L†ๅšžีs\ูงDP8๔‘Kฤ๏คาฺlุ ๖บ|<ฑ๖ž๕๕๊8vใ�๛�|๚แsDเศ๛+vw]t๒vu๙ปm Nเ!๋ฑหู�ฑว… “ืัฑ00aเ๕ dคฆฒดผภ– 9C6uL๙&ไร€ฺOƒpeร.ูf ๔e J-Gr�‘k2e20ฬสป–้l–pnณฆRvŸ~นฟY� g‹gม9ไvๅทAฃฃฝb4๗.%ท]๓�๏�M๚ท?�A๚๙O๏งVภ๐๖Zว‘ฤ ฑ็”2œbฉำ6ด$s้"�m ๐6บูfฃ–™yด\SYx\B,ใg๎ฉge�ถฑฃๅ …ศ” –Sํฯ-์fฏ-+แŒW˜๊`๏‘qšŠรัตฤ๎่1›ศเส–@อLsะuŽิิ?) น!,c;โ{Xฯo0ฐ}a๗ุํงฅ๗ชlkhแ๓xfB๒@Žำ/‘eFXะอQณˆRš”ฎ‡ๅ=–ZXrŠ.;“๑†ฅ) I›ฌกถฮ6ฒ�_Œฮ๙ 0บœ˜%ีู๋zVื8#Oวะ_�ฅก์ตkทกฎ_ฃคH`-ฯฐm}B†ฦX7ฎOธน‚Ÿ‡\ฃ๛พ}fŒOd–ฟฑTัฬ๊…ญ๑lฤไ$^cเขL๋'๙!๘์ท‘„ศ~ย฿๓zฎ_฿ˆผตvŠผ„M>5ื�;^p“€ดk96(—gถ๙ขมพ5๛Nััv๊Cqˆใ9]kํตzHแ๑=๔วผo]]“8Sก๙แ��sๆ฿๛<�?žM ว๏3�ล๚#ฟK+Q&7pmkฤง�žI๋�‹๘oิตำ{f}} �W‚�ถ4ฮ9:jภผป_ษ™ฉd+(ใb7็:@฿@dqe!=|๒4อ๓ต–fw๔39ธKฏ€}ุ‡™บž�";/Yอนwn1๒]ฯ๕lzปC_๓ �)kโ็ธ'ทR๏_ŒOคูœSู’%ศxฐX-ก:ภ:{ืAฆ?Ž5ฤT.7๑ณหHlผ—‹tLฉ ฦ3์0OลX�Dอ}ะ“SFฉe฿฿€}ภ3^อLLrN`Z๘ |jงeI้šบ๔๊R-Sอ[ปbอฮ8ว–R[ฮ[†jO€<ฮ‚�dv+h�ศัOฦ �๛ ž|r�w‘ๅ�-ฑอlงฅุxู<_X&`.ฟืฆ๒—* žเ™สรŽศPอFดfถ๖˜koq_๎ฉเห)๗ฟFขd  ]Ÿศ‘๚จฺi๛8U*`๙‘ุฬ�!ถฑทบAะย3ฆ XƒฎึงS�X๊ฌ-�=~Œํbู{ง,ศ|๐�[^บB2Rๆท@ฉ�b0ฟ ํ๛Sฦ่•อฅซ�ีื๑?�ฏพ@}œฤ_‡�d–๗ืแN�?พG{�ๅw0�์ษฝ)BุWQฤีcใS ‚ˆั2@P`t~lฐQBว คฬOรˆcฒ0kิ๊๚ษw’qWพEศคฦฌ,ภX �oJฬา"ฟFกsŽฑT=‡ซ€V'Uฺฃด&฿sBG#VcPฌ_ฅ‘ษ'2๋ƒ�–"ห79Jฆ|f:2•รจŠเ�ŠdVN`s3S[ฎ�‚@ Ÿฑญณ;๕ ]EYึเ˜.G-๓ิจi:ิ�{|?=~๚œฮ์+ij@AงพŒฬณูtฉษ‚ฎ หม‚.K0*ๅ|žYฉฆ|F™I‹EA่l่„še”y รfๆ#ฃฃ5n8r^S'ะ๕>ๅ5Žึ�แoœ!~qศญ u�‹ำ๎้U(ikพ๚z:)๙ ‹0bญฺ<(kFกฝฃ3(YuPบ"จฦฑแ4ฐ|==ฮ1ิฯi๖งณ๕”ๆ_๙>??—มa_‰v P๏%@'ิ†aK+€๘•[ปิ‚‘ฉ05น˜&'าศร๛Œ5œ5ญฃ?@_บq๛(ŠW0dŒcกANฦŽ™5€pฑ?ฎad{XsแJ�#”นฬ ฏแิ™=0ศq�คŒ๊h‘หX �แLป/•4‡ฌกŒม�†Q*3ๅ[E˜$��Y��O‹kGt:_Lำใซใ ษ ๊—o�‚q-hำ;๎้: g{ƒ˜Uั วH/2}v็5๘5@๖94๒:็:๋3/˜œ\ฝ๑Š =oš๛สt•ฎๆQ((—5วฤ๐ีภ€{63ฆ%๑64^\�Œ๓อ๎<ณฌี ืฬgVu!kRCฉF=มoW7MD{T]ำˆะˆฌ0„`Uงq‹@]ห’ฉ™)บ[ำค ษษ$YIŠ๗’e*อ8˜A;กใตg�r ผe^sภ‰ ั—�-UV™HไrŸ ฬT@x;ูย3แžF„lŽ:รgf ศN๛ฆ 0ใ+๚)�oพ‰s%m�@ฺRฯ•ฃฅ��3ฮง+๔•ๅPoฝy'�ม๏ู�Nw๏~œ^บu+ฝ|๓ๅิำำหg๏ษ๕deึุ˜Mdvvž ฎฒ„^”ญโ์H-�…ำE&ญI]ฦ�I�$ำญำ^JKcz‚ฮ๑<กำtเศ"x4ฃฺI/YJGศพŽงAพFVบกฯ8ฃAว™6šP>jpฮJšฌGT�*Cฒ_tBย‘ๅ\ศฺฆ) “@<ใๅfฯyูN6crk”ื‹ื�์L ศd\8ใก•ิLผ†/จ"œgฮฐvP:ท=u๒pยฅฑๆp}›ส†Qp\“Zh๊‡\w�ณว�•ูะำ ล^<ใำใ1.ำ:g๗U6�ะฐ�v๚b/�๚;†ํŸM�ํ—้ฝD}ฒ๘wัฏ่X๋ดm๊hฦxN.}ŠŽอ#8‰ฌ-gAนTรœ ึ:1f๐ภ1u6†ไๆm(gรoนใœ{h๛x]่R{ปฐ^สI ๖ำrฒ8ฬศ xฒr� Y;~wยz1”Šเ›Ÿฑ.Eุท|์…#zยZจฯ๔…ดRž Lั9ภ‚ใูนฒŒ!ห|8หปHลืศˆณ฿6e๙ย–ž"๎‰ Ž๒เ:˜u6ˆปุข มŽrh9’{ฅŽ)ว;ใ฿n๚Ygู&Ž|ัึ รmํ`์โึ2๒ะภบh_ฝ eFๆร†`rฝHMนLตษ้็7ฌdฑJ•u=็}ใ—๐รv™“ ะcŒ]ส;บ;๐9ฐฉ€มเโ๚Y๏Ÿ•พ$่f๛ฆp‡๘^๖�ฉแu๘<งkบ๓ข�š™�ๅฯn>“Šธr‰<•eŸีาร*)'็$มy855C0H“X�๏„�ฺๅฬ่w0E‰รุq๕L๖์žฏ,0ึอ:x}Aํ ร๓zฅ1ฮr’•(dถะg3์GL"ใ�ธuu-œ]ƒsฒ�ญญ”vp๎�\’^}�5˜ปWย/4จm&๘U๙}4_&ศ,g�l\iMš@ŒQ์Ÿแr`YS ˜B9J#=d‘ร�‘ย-�ฎา…*€ร๚ฦŽVะลฆBู}J•๒a/”แ_˜ัึฬ8~†ฤ }บVฑ—Wฎ\Iทฎ�ˆu][hG?[บ#๘ฅšnฒฌ�ฒด๛sŒฐ‹�]�ก ศๅก๔๒ํซ<o qธงฯ†ฯeˆr๚x™5ทผ6ŸsVึ  �yy\gOO๊d๎"ฮh k+g�2;ไ“R™dSL^ภ;D'ฌLOฑ#Y‰v ฟZ ๙&f;@š2ฑ�ฺเ�w่”ธว4ดBt�1v\Y)ฤ~๒Xœษ6ภ›A๏zฦ‘U๖ ๓…9ฟ๚[่@มมY�";ฮฐL>�แ`“rอ]๖ญžDB.บ๎แใgaซ:[:R{Xจ_Šฮ(ฃฯ˜ฅsฐcฦ^Yฏ!ไ‹uั_ฒ”>nุ็Xsูฯx๊ฮจqIุ2ž��B6o.BMLZ a|ฃ�ฑฒl๒›†ฺƒ ขm(ฐqชฮ–อ”gš สK�๊ฎฟ๖ฝ๖ํ†ƒ๓๋๑ก๖��<8}�ƒOGๆฆŸ๏I๋œš/a�‰โ,Ž9๕้6 *ว!CJ‚๒ข๐๊€๋ฤ~.ฌ*—จ;–$|๐๓Ÿง{OFศฌˆ๏1บ๋ƒ๔ม๛?OO>แ0ั\EjS3ภe่Mํฉป›fˆ5 Œ3ฑ!_Š3’‡O%ฑHŸั๓ถฮ>+5_๎9P5๊ a<ุอปณ›ัญ๎ำ ทˆืูQ;ืW"ภ๓gc๔>ฏ๋Œ …ีฬฉtฮKW_I}ร706UP๊giv7JสH;:�ฏ Ÿ๐ผŽึซcฐY-ป&๊xueฆ€ูQAฃO?z>�ไk^‘*Q‚ฝ—ำเe๚V@๛Š๋ฃX•G๗� ฮ3กโฝญ�ะ /%ฯภ„เ๗ิๅ4šU_˜Mำ/žSชฐDห=า™ฺ!จถG…Ž–๔าvuฬYฯ„tgัgๅฦพR0ค๖ Dw|d๋”(คฌผ'๚ Fพซป+ฦ9ๅ„A` !›‹๓หะ†ื๙ค้}#œIoถF�40Pัั$ฐฮVgาu๓�mฎfษ‘=:GAg/4.๖ 0M*›% Buฺ 4ฒเC*พ๛ชใไ{๚ŒฑgžฮK- mPT#+†ภ9Y๐๋d๘ฅ–W‘}œ‚นa“8Y๎ฟ™T›ู�ภฑz๊0D=๎!ฮŸฮ>๛&Š๏�อยˆ™I>ภ‰ฦ"Cๆy3P๓ญ;4ํ^-›4โ"XJ3œ๛ผ˜qึ€๋้„้T�wฤูะvมศ ๛ถ XบพฒŒC€ษณUใX8VUเ‘ห๚ษFษไJภ@Yน˜LโZk€อ8OZ”พ็ล๓บG์„ ฉ2aลษ6ฌ0N7ฮŽ�*็วษQŒuญuไอ„™E6ุ�๗ \๔�ื‡๒ํ๛^|^€™“ภ‚๒w~XecฅธH.ฌAณn๖�Œ๕)`๑]�<�sN0fๆW๎—๏)S!Ÿ{ ฺ0๏2ม‹�/�l5ข็๓˜ฟ๗ษผุ%#โ-ศvS๗ฉ3ฬn8q$‚ไz,‹YศZ่’6A๔Œ(๊_๕‰บE\€Kเฯ€-๛9<ืใ๙ฏ3ˆ๔�‚ภ฿๘\g.Žฃ“2๏dNo,ึ•}๗|z๓๙.2Ž“ูy^œEDยŒuโYYƒ|cQkฎ= ็๐ปsžู๗ี๙๒…ผฟAO8{่ ู๎Q1AG>๚OคฉMŠฟแ�ญ…e‘ำ‘3ธ�‰TWฎฃ�šy,\๑๕>ซฃDณ ตน>๔ฏืR๑Lฎ—ช{"ภงŒ่�ช‡ ฎขL@V™ศ0Xถ,ม@ฌ ›็�g+ žฺา€M€=ว‘ใlึสxร๑”ณำภ{koฃyo[eCำ1แa|�95ห4cญ nฤซE฿}๗k 0น(กณฆ๘ˆ50ะ( ฑ”ฯ$–(xฟฺ ๏ห็r*‰=<‰๊^Y&๊5$วค)๗�ห: แ"gyƒฌฉ?ณอฯ‹]อส�`s๐�‚†ผ=Qฒ\ฒณอD".3๗‰ฒ!ต๗นpŸ\ขฬ! !ฃ1�ซ,*—สฏตหพ^ื๖y�77D{. š”}d3B฿ูcE�+รFฝ+ j�' ฯ€ฯ^ฤ�นwQฮˆซEะินฎ—ถ`–€ฬข"dุQ�œCจ‚ึ*@P™af,+ะฃ‚žeฏ#0*๋ฮู๒ต0=7ฒ€,ฉด๑go฿๎j~†Oภ๛Y๒3Kษุำฃ+{(ลG['ำฎ ƒ› ๒ฝdsบ‡ฎ‰6ษฝ Vkง รห5qS๘`ืฟP‡{�•a฿3š ฒn>งฏu|ฌe๚}–ขPn้4ณฉ้yไ’’ฉ]ฮพก}ฎฮhไ0cO]๗่m€� ูW;ฐg๎๏ฯ?ฤิคชศhทลWืสrฯดrๆkฝ_ง฿+ฃ~Lw”@ต�*}nฦ�z� ฐื–ข์คฐป`3T๔#ฯนศด'มกj์๒ดฒบ 8@3aฉ…“ท‚มปฐีŸ~dฉีcต��šx�Ki๑ฺ1ee‡ู้๑จมoก๙^66๕YจŒงR๚หYท–J;‘[สขๅฯc]ฝ Ysฒ›ฌ=ดพว๏อ๚ลพ„Ÿฦ~ฒOeฤqๆw๑ๅข‚R ˆฃ™Q๋จ8uwVรN๊ภ?oล๗b<*๑…`• QKBWa{Nงe�ฑ�๑:€‚อล1|กiฮ }Yฺzั…”ชSฐป–[อฬŽ>K#งษQbYŸ33ำ$ลFู]F�๓ž ํWw7ฯ� ฃŠฦ›&ุCง้ฑฏ6›u*1Žบ��42V”;ม$วึณŠ๕ฒปท�ญืRฮ๓v��~วAyณ�ƒ[฿ˆฎ#ๅ�แršc–c„ํ'` คร/T0Mjํ6มืu}ช#Œน๗ืด‹ผ*ณ ฌฉ‚ชช๋A†YG[~y‹`1qOกorKฌ=N1›ู้ตg{Tศ�้๔D# ~งๅฟc�pเต:"#•�pDรฯซ9šฉ+†5ณOฦf—ต6Sณ ธฑย�aY+xˆฎ1PklnH�—zaHk7๘าX๓๚œ%m�ฝ$p„�Aแ๕าืo^ฃษk™ฒึ๔๕o�>zZ<Ž—’ภฉฝCฒfช1โจปฃ=�ธv%ฝ๕ึkdุ๚ฃUnAV›ส�wู?jžXหฏฬฺีำKย�t]ยqgฑŽิ{ฎ�ซ:E6๐๒œปn–A๙๗pfฯ�Œ™&2Hฅ์ณLญ3 ๗q>ใ$๋kาตW_‚%s 8ู_2\ไืCtภ˜฿lํฝเฟ�{ฦฯ�ฯYถgู=(“�ŸŸeŽฏฃmn๓่p^ภWหœ่ใฯ ƒฎN๐หฝ่คfY]จ�ุ2/Fเศ๛~29iฌ็Ÿ2ซ">›;›น‘ q๛}o3๊สŸ€ง@จgว3-˜๒Š>3KoO๋”=ณ๊&๕ซLmUเผ DถพPจรi’ฎ๋{•ัฑพžฌ๋ˆ˜TืUฅฌAืภTb_ี�๎{]ัq(าข:Yม‰:ึํVaหผเž;;ฅLSKNZฆ๛ใ็้ฮe-มส ์ HFƒอน5ึ•�@v}ฯ—๗ฅ\ฦ^๑;ยR‡พฉ<ณ~ถ๗โ=ุะิgถ�PฐP!ำdQ ถ d ถท์๏€s��yOgชs๘ั™dฐัื6nถaขluฌk)เlc8มoLนหภ…LŽlฦช�‰Ry๔…ถอภL›< ฏ(#B๗ ๔šIvb‘vล็p_CV๘หG7๋yะึ๘;ƒ~ƒฟฟaฏอ2ึ“„Pีฒ?6šๆ"์azฉ‚Œ๊6ษ†j๚M "'�gูQf๔็ิ'กSธ7ูšM$!ข„น๎l๏ ฦ†r+x*จ=12Nyจ์6ฮ#(�!เ{�j๊j‘m™๖ึย'%ธีปฟž2�-ƒฬ‹xVณฯณ ๎6Zฟภฒื!‚๎WภžF‡g๗ฎ?ฆฬ55านš~g#dS‚2๚ ์0‘^8�๘ร^�๕poี‚Ž–‚:ั๓bBA[ฤ€๋3๘`�4๘ทq๓อคwศŽ_€สg๔?`ฯL‚๘7ft�eภd’l ว2๎๎Q6ธฆเZ€ฆ›”žขต_>�&ุ�rzI ณ๎ Œh€ จc?ฎป}š๎�๔C˜ย4ฆYUe]…eแ Nb๛qŒาฯ>๘ �ป�€Rโฌ_€็�โlšŸ›มoฌฅDถ=€„+d~nmDฯ�…ํำฦjื vเ๋�ศŸ{>9>ร็4>}Ux^ัีM๎U฿g[=ยk๔lฤ.H†—๓$+SmhฌN€$M5eฉทปูชD˜�/อสg=ฃ�‹�ou]พฮม�ำะํุ�šV๚แณ�OL„cใŸŽผ ั๊"zะ^”โ7ูGฅขข๙‹‚1a่คํSIš๐Cย6‚A#p$ กF๊“IFc๏ฯ๐ฉ,‰*ภfิขรีท2šm-5ะŽุ?D†\Žฬ ฮ’2Tศ๋สRโฑ’aคฦส…2์Kะ%ฎŒื8“] n  :ึ&น9ุN}@fู–l)mj๔O๐ธฎ~ข็�ข\มsŒ5ฮฆq‚๖Bฝง0ไนR9๎TŸษ้)Y‰Xqเt”จ+ฺใสฆGศh€ ๒ผ๚ฺฺ‘��ํŸ<�ื0แ/ฮํฏ๒ืฯ5ํฏ๒-��o�ํ?>๙๖?�็ป๏�่oง�๚ฏ�โmบPทาš;8ฉ[|b#8ชƒ j0ฤhๆาV9�$ั1E[ž8๘6)5ซข†Qzp๘ม MV0รCรPขgาสฺ๚›สRู*๒ใฅ$;็uvf๖)†’ฬ+สเ ”ฐH6€‡dg_ใhอOY ;J 6 ]œŸŠ ัZญํฉ�๊Kฉ{๘ztzตึ็;฿๙ซ4JำJใูไ\Z'ฦ�0PQJ�”†zฤำยJˆ๎รa oS52gฎ:นภ f 4Nธ๐ึ‡z ฅูจ{เln$าํงY]๗&4k)xพ ฌ/uฆ+kอ!๕S'ตŒgฒฉŠAำ)๏]์๊<�๚บF‚ifŽhฉลx๓^่7n�ๆ™ฬบภ<ๅ๚:>นnฐ์† ึม์อa์Uฐบธฦu๘œ&หดƒ>"yŽแๆ"ฆv0฿†"ผข+ �ฬ<๏มกฎ4tน+uw3๑‚I uU(2/ใ Plšzeวฑ‘Yฦ5Dิ[[ๆร๋`ฉจ าฒ์ a0์‡ฅ'i ฎ•NšN”`—ฮžสฬต7‹kน€ำu๐zQgˆ"“-ฅฟ}f4โ”fF€ฺl..๑aฃ†lโฆs&Uฺ=๕พอฮ;ฎO๊๚้8cกCษ๊ผ๐ฃศ xnคน‰D/ƒ�๋ ูxPJตเ… ๖X%ฮ=KซณY็\ๆŠJูหm๐4ฃวH%ภCc+่ญีหJplE{อ* rl‘!า:F๐”{๑;|บ�p1›Y~œNน๏ง‘0�ไ}fFะ€๕7@pŸt2t๚\gqŸ�฿๋€‰ ๋้L)gฎฯ็ผy3D�,‚DึBCใพUbh”}ใn๔D่1k]V_—jiยไ’&–่/ hฒƒŽQIศ0ฐ†ุฬ นRt5;#gฃ-ฝ/ๅิ)~/v‹@ะ:๚ท_…) oณะูัScq> ูwวก*Gฎ‰#ืr ึp^lt)‹รkPฦใ9v’Š็ฺg#ฑ3ยณOนCมZ ฌ•FœkณฎณAศ็]k€ย‘F๋o๎นNกŽา๗pŠ์ZบๅžDC;�]ล๙ถ!ง”ฟี๕-˜Sdฝ^y9}ๅ฿Hฅ๕Uil�!Nญ ่Z�E๙Kุุฌ•Aจamศ%๏ไ‡gC™๖ู��O†‹์[๋ห้Iา<"3R๋Yฉษœ™|ภ ASƒ>K[*ษT9VJ �๚‰ํใู}๏8.ผOŽ‹?็:์ญฟtไฎภžถchฏ๐œไแนRGฝ?๗H™q]l`NV�ูช-ฑ;adงุ็ต9ป‚Yัk#{ฮณ"�ฺ†\Y€ใๆฬq>ิ�๖“1@w —๕จfพ{๛บำ�_๘BฌGศ‰<๋)ๅ๊h‚เ Sฤม้โoYSž�ฌ>.{8uม–@9ฟ^gป” Q`A๖Hƒม’�x�“X ž—U๑๚่Mฟ&ข4๒-ฦสีขKF^Œณo�'~‹ ”ลŒฑ…Mๅžu~/œZ5’NดNฒฯisฟb‚พ}สภ|mณ4ฺู™mแ ฃซ}f�ญ์ธมflu�š๊{‡ ฤ!>ำ&พย2�*ภญ�'ฮรBไฏๆคM= `ฦ>kอZ#ห6ฌ3่t๕w|zวต4p อฝษ๒P�=\ฑ†:๊��๓่t™*๊œBฮdœo๕Œg5ฑSฟ{๎ž๒ฌส€›อี žu“ Xศ่ะ‡คœ ๙ฺญ›เ€m๐พ=แ๊ ื;๔ kฆํ4่S8๓}vv�Dv›คFร๗V†์ณท–d�ค|4z‚` mž-โz้�๚b๚u๊T0๗ำิฏž9oภๆ…2q๕2šu๖^๚�LEc -;U"dร฿๑7นœร‚?3๘ญMต<›% Gœฆi์มฺรพ.-4มฏณLล์ฝ™zY.ศะ!ภฑ๛ฤcฑ"( >ิ?>ซeM™>โ7ผภ� –น˜D‘Uเ}๘™๙†k�1ฯdะ(๓ํ„@Sส�yn)อCทำ [‰„ฆ๖๖`plF A2’๕5eฺบ๏อ4o์ฆ� e0ูง-�ณโ๓09๔Zฆิล{ุสoฬฺ OdgWŒd€ฏ$IŽ๗`มฒป๕๒uXต–R€/ ž’กิXWฯ^โ~aV’48†มำะุ[นFป6YทดญŸw%ฝ๗ฃ๗"™b ็ :��]๚ํ2ซผ*‰iๆๆฦฐู‹กฏ,WR๎–Oฟฉ<)฿ำำ๚าฯุ์ปOžภœbฺY "ฮณ๚5สOx^หสด1•ฐG,#VJL‹X*nยJฟส„Œบำฆณ๖ภฉ”5ฤf บ tศH<รฦ๊wฺWยr:หf๗‰ิaž_Y#zdy่C–=ƒE๑Œฃ'๔“!ฝรšiงกh/‘ผผ&็V�ฆŸƒŠ‰ŽฝB ๆg^PภQf‚็y~–’ุ6œ7ฑ ažA_Fภย~M‹S๓้ล“'ลห “/umŒ=�“?๛w–ั๓๘ฟาฺŒ฿~|พ7�๋�nฏfvro||�๎๎ไ$-!ff‡ํุ‚ู`0ฅcๅW3ฦัI฿Cศ�Pเ9eex ปฟ๋X…รยaVั๓g .†ภเC'HภDวภ Gใ๏…K{6…าฺ็�ืVp๔VX#i‹นิ่ƒ<ฯ‡1ฒ”ฦ%๎๕๖@[f‡x ›๐MOฯ†SพถA๐c'kY6ฯฬูr๖๗Z(˜ฑ'๗น'Q คื�†๒=ะFภ•c—๊@๎ƒ %� ฅmVP๕่šธ>๊"�๐\:ืN‡ึ5ีนืํ6‹(ฒ/ `9ฦ6r ๒“ฒ็WยŸXYkษผ_Y(6๖ิ้ณ๏AYG38�E~QEz๒๐Qบ๛ูcbrั9saจดQHะท‡“็�ˆข๒ะ\#3่ึํJ-+ า ™mา‰ วม‘Mเ๙!ยเ๒=ฦฯ2… >W่qฐยืcไ^งBฺ›ฦŽฤ>;่3ฐ๏�ป7 QาฮสถcoG๗‹C'ท%อ’ Ÿ8[(b3ๆ*n)Qzg;Jm ๏�๛้๛๔๕€ฎ9‰$ƒเ่5ฯำ<% \w` 'ฝz็Nz๓ํทIง้2Aปภจฮฟ`ƒ๗c�p>๚อqj15‚}P–คจ๊๐ฺ1฿๕ต~ฺGx9bึๆ fprpds`ด๗_Jฏ}๑ i‹i$�๒O�บh+ž๓ห_๙Zz๕ีืhL๖†หK!�ั�$—ผŒ:ฦ3ฆ~๐k8ผg€��๕D.‚l z๙า k‚์q††‡ำภๅหP2+SM๔@Ÿฑ-mmPษฺใดYป๎”e๚\JฃŽ‹ฯ‹ำซ�ห€฿๒๏ษgฦตŽuธt๙jz้๕;8”๚ฬฯ“ฤB—โจษ�ะ๑’qa๙…ŽR54hkWี%ั,{/r�”๛ิ]—ก‚šฬOy�m3Ÿ฿็๓{ํำ:”{.ณผาๅ<๛5๛Wฎ\M/ฟ� ฅb€ั4ถฯE#ถNเ,ฒั›๊Jํ&A{š จ.Taฬว>Vม|1�็๘ีBQุC…ฌ•๚[ท€K5�๖ธ‘ต!๐’5+ฮ๕˜ึรฦ้ZzA@R๓๙gสบ~’Cฝ*๎ูQ”s”๙X2cฟš๙•ๅpBณ2#3X ฌซŠ็&@.�_9PFย]#หชิ{มฒโ2eโ5่wฐ‘_z^€�lr^lZช=6P 8`ถฅ9\ว);ญ *ษย๐zŽslๆ�ทะ;du�๐ัฃ๔เ๑ำด@ูภ`�na๚ั{ �ฑ?วPต้ษc‡ฌ ชจ…ศไn˜iณ์Jnษ–ฯdเี@ฉSพOi†ฏ�#ฏำฎดiฑ‹ตเิ{ืม>N‚#ฺO็‡69t$?฿D�ฏ‘ฉ,ธ3๋ฃ|hร๗ฐ๓๛ุŠฦขy•ๅN€5 (‘sYcf+๐™,อ”Jญ,M9qO|vƒAฟ„€T�‘•cเฒ ๔๐�ษž<ึA:X/‚03แž๛์ฬห`4(…มง=ผง=ึฤs่๋e๐Eฐ ด4ภษ6JF&9‹€ฉูžํกฝ!ข~ŽๅC๊6 ž๚Kป €~„ผ๘>๚1สณrxฮyYไผk฿CWฐ6ึ„WUืฑ๏ใำ†ŠฺwK;C฿๓Lfr=�fช,ฑYชๅ �™o้- �นŽ6ซnํตมd–ภะ’๘?o้แฐ๕ฐ};ฐ- ๋aสิืเ‡`Gฐ้+GiŽไึ�๒t$ ศH�B;>!xeร,‰๕ู|v�มฟ ุLCA๔Œ‡NๆuสŒ๏๏žiฏี�ฏ€พeฆ๖ฬP?mรศ\`Jีฝฤิญญ�a›eฃ˜ (&ัv๘น�uญ๋๊จuG^ว'_ฐ—k�>QCMsบz้Vบrใ&��0ถล}ม0นi~aฟ“ญ(ำ˜Zย็ทlŒq€ OFžPา��™f���ง?ฃxP21ึิ$†~8s$Fขฟzi—D>Š2่~ฺ�_ noYž!e\ฟK™ึ^๊๗บ&8่cทขwุ็h ฬ๏ˆr้™ัำำ‡�้ i‹/รษฒR�‘z`!sBCŽ ิฯž>MŸ}�1ๅใฌq>ฯ ๓ฒน1ฃœw๖Yด/ศ)l‰]&}_ไCำO7Nฒูx๔L@พj`j–มคะŽ”โczฮŠ)ฟฬƒ}ปACุS๚ฐ˜”ณผEF–Lžau‡:ษ๓ช_ฌŽึไฑ9Oปf๕ ฐZ”m$&ญ}\•›{ิ๚๚๋o|๏��๔„V๚ซ�มJ�๖ใb�๕ทฟ•พ�ฅถ>y๚๔rŠ‹๓K  qV *์m๓›qไ™ฉฬร๊•"Lg(9น—:ฮ„ะduททฅซCƒ4,้Oƒฝ8ฦ8ƒ8ป๛R๚vขn๐>่%)Eุ 4ูม,งลa3*ัb”สแษ.‚‹3ภฯึ )Lub 'QrG(Gนp("‡ฦฦ๎@5hEMGโ=:’ฦจก›ZุH�๖—๎>ƒ&Dฦ‰๒เVู˜ะ< ูŒŸ4o๋ซะฟ<›อฃpฉหlฆหld48”ึชG† …งsฉPฤSxŒuf๘/k jส'‡L'mวื&K* ฟŸพRšœ‡ำ็Žf6|/dโม•พlŠศˆaˆuฒp|ฬZkิญ�'€(cD2kฺทณป•ฎ\พ#ข%œ๐‰‰q:2๓\{jr>MNP๓Š\W+ —R’็cะณ ะแ๘‰๚žฒ.�A8Œ๚*LแQำ40”๚ŠชktุPL์8g…ศŒ]‹›Zป๙{&Jฯตะ`jU6:cั eฅใjํฒฟ8า๐\๋|šYงyŸ‚5_ฎ‰Žƒ๕‰๖1 ‹๏!ฯ‚ั6`9์ฐ�ฎอฆคแ๛ผ‹d�lธลณb rซำ฿�๐วL™็Z”mฐGาF๛.!Sศo9๛ไ=สย‘R'm™9Cศฦ6TiKFT๒mฮwฐ6…ผAต[รiv๗ำด“ร1J็;XvP™Aบb�tธซ๋)?€Ž�ฺั ีญ9ีเdW}:ว|‘ญซฤแญiจ%„ส ส�0g๖R‡Qค[ฤู M9ูผ๊†J๖…ž�ญ์9ฦL`)ฅ žัืl’ำ5*ka๊VšEbฌัิPD)ฦ\GำLf��Œ›ต2` zรIDพ Œหฉ.ฝ’†�ณ\๑บrึJ๔บšlN Tรส ฎฟสœigป“5oP�%ณSJ€ๆX(Kฦf–ธNR{๕—๔@mญP€ฑ๒Ly†ฬด้ิ��ฃธผูั4x"1pฎ2เf?+ซh"u็eไ�)ฌ€ึิ}้Rj ดฉ‘ŽŠFZG๒™#Ygฆ *J–S;r=Aช๓์Kpป;ฺาฅกพtํฦevณ]้๒•k้ๆK7เ๗า{?y?๔YCs}d+w:‡z#๓g@(;Jห S�jฏƒb้Žา�"[ˆ๓n =u„ฅ]ลdkx�"รf˜=[8ฺงผ�๕แซ้ซ_�jz1Gฏสฑ~�๏~4{ฯ๕!†\gผ„ŒจดPu‘๔j3:๖\|๎P„ซฦ›|็R 1D‰ฦซฬ๔ng๎ถ ฉฮ์_1ŽU#มs3๒บ…ƒเ�V ๆฑฮ:๖_ฑž�9,ˆ3๋น)ำฑ.G?ิpญ|๎ญg7]?xu(]ฝz%ภฐมแ+dOpะ™ลm/AศU(ต‡ี็นูธ,ƒชผ@ŽRB์MF6ศQเ๘9๏A28t๊ŒYมฉl�žM�์ธถ‘4rูHน็Ptuฦศjต๕ดถGc1kพGGย4YEฟ้่žฅyภY& 3ีKySฮc0ยมซ9ซฅ%<+Žu5ูAAm๏๛œ€๙ไ��g้าๅk้สอ�€เm”`\P†TวZ้Œฺห@56๖@f…ฯmฃพฮk{K๊วฯ€9fy ฒœฆ„๔�Qบ๓ึ4รDก#ุ;๊NŸ h๙*Žฒ4ๅ%ˆuSŸไํ@ฟgฑ‘Cฯaว 8ชด-2(3๐”•b฿3๖�rฆVX9‡ฐศŽ`ึ ฌ 4nk1แ๕PŒ๛: Š`ฮa๋‡œ^รุึต%มยป๗>%=Hฟ๓ฮ—ฃู/��ทnฅฉY)ลPซ‘‚๖&9็๙๓ธ„5bUY3ฉส2\\ปฐ5ศ;ัhู0›๒a<ฬฐF�ฐัG‚มไeat�‚$ )[#d๙2 ชŽ๘ˆฒึฯI6�˜๛ย๑g…ญEvtฆŸ๊-' ๖์4fz*ู\X{ปวkิ‚ษ–ชŸ€a—*๋Hะฌžี๖ 4yส‚š>=NHPDภL2d9คpบฝ† ฤdแีเ๓@�oฦp“=<”ๅ1žmํใ)๒˜sถฬ๐rๆ๙฿�f—$m๘์J�ุ?0ˆฯU๋ไœW&‚9ศณ(3ฮfWซ œอไ R8’ั5ธm฿ุgTเฦbŒ๓Kน�Ž=—ถo_ ึ�ฤ๗‚fŽp•™ฉ%;H�ฏ>ำŽ›ุเ๖๛_ฎ{ื‘ ŽีG„4๘  ยภo๓฿‰6qๅR)ฺˆฮจp(!H”uบ‹_›˜|`ๆWึ@u1๚DT†^€ˆ^›Ev ษ๋ษใDoณ^X&ฎฏ™ๅๅวฑ�'�ฮฬฎฏU๎šR�ฒวž/ำƒสฦูล๘ฒ9$�ๆ`ํฌฌษ~i„9้=lแ›ิุ๓ฬซk)ี5ม หฤ„Ё๎44�ฑqšDJะุฏ�\ึขฌิ=�'ฯโ์"๛ƒฬlร๖"bH€4ดa๔๚ณ) &คั๏Jวฦโ>฿ฤไ ถ]ฟฬ;+pVˆ๊ไ.ฯ‚=Gิ;สŒg–w็>a˜่Zยจฟ—วู6้T ;m2;๗Œw๕ _z�ติ�?ศYฃิ_+๓ณ้!„า?8ภช>J;ฤ้…�ึย oeชศx.…5}€oธEฆฝึฑ#1Ÿึ/3�๛„๕qJื�ฅN๑Eฯ`ฯศ.ั�า— fฒ(�ุgต�GpIOฒ[่xLง™TR๊{h!“เ?m‹=ด�–=ไ๘C^ƒ~6ฎ@฿+Uฌ{1๒ข ๋ ผศ$ฐ<"ฮ…‚†Lศ๎(ไžCึ&b�y=}2์อ#œๆXt�ƒ •Eฮ›‰"ž7๗˜฿ฦžษ:4(ฝฑพรxdlณ%66^=#ฮ*รnŸoฅkท‡๏_�ยPญ๐฿ˆ€�J�8๘๗ถ็|๋?ซ๛ู๛?�/๎~๖ูK%ฬxล;EY[ EG hlถF@E้aฯ'ฐ๒๐o€‚ฎฃ�t>›k๋Rtž6จICƒ}้:™Gด4‚ส™ฑ5s|๖ะป`jr6hšึ\๔*ˆ‡พŸฅศ&<3(2๋tฌ฿ซ6ภธ~=๕p˜;AH๋ป†ศส๖เฬS� kcr{8W4;q1๋[้็?๛;>฿'�ฒว๔„Iฦภ€ึ๓&็ B—๕`cu–ฃŽฯVe_ภ๛:MUฤกt�กดํCœ;้ๅ,h4�ยจ๊„J+S)E ลZE7zึภ๎ทf7ศZ˜ฑ๖@jภutซP2ผ;�›ด1ซๆ‡tป้P:๖ึ* |Yฏหร—ธ&ู+ fG{;kภ>œxตv6œฉa�4}ณn}ไ้X๚เg?แ_ *จY’ฒซ๖58ฺ‡๊ำjึ .สƒ๙�(M ;)๓ำc‘ัษnภ tจฌฤ™ xi ุญ'ธ•aŸ@ฬลิH่X่ฬ้p๊ศhฬƒฦ‹C!x๋‰AีX๚๗:อ^@ฅŽ u4ฐฅท!QJ*u~WŒึB&ผ๎ุณง๔ฒ 6vt&}๘“Ÿลˆ้)Œ$ูy2œz'H”c@"ฐ`ฅ\)›ไ:Yq [ะฤxx ธzณ‰�๛๊๒2tฦ9๖†N ์ฒดaŸษŒ\y �ศาเ|™]wฎธเฑ์๔/3?ึvห<ฏ XดI”เ@™™ฤJ‚M)ลRำwธฅ•ืิ7Uฆ›7ฏpfh๖7H'aสZ&''0 ิิ‘Uืึ๒๗ทษธ_พtฺ�3&]}c|#sญ็็fใ์[บเz‹x›ญ‰, rH๐"จ–ษfvŽอฎ˜†“ฦ�ๆpFฬVI“ซ"หZM@_ส|ไใ@ถ2ี ฅฝ ‡€š@} cs๗มวำฉงฅ“็,ZI๓Rฮอ4ฌฮžHป๚C�T ภ`yŽ ฿W}ำะXรค๒ฌึเอใLอร ˜[˜ขโฐc�L7๏ผJ}๎%fฦ?MŸ|๒1Ž๐,๛I%ึvtt๊๏ฆ‡๗๏!๗Qœ๛]๎Aงโ€�ฎA๏Iวผ~ๅ{ญฅ๎™้)œ-อr :LณW 8ุoผ๙N๊้๋Kฃ0ขิร+ธค๎ฐกœe+ฮS�& ีูฏF6,GHt�ฬค๋$W ฒ4ทิ^ฝฮึ฿~YูK�แำ,์ข�ž>j„q’pm’wŽs`@โู๐ัฑณำฟ>„๛้:F€ไQร9“Yเ^sL)ฝ †๖dmฒ็ะ&-4ŠUท•ฃ‹"HC-ม8Eฎซ‘!๕ใมฃYจ]๔น๔pYf†a�”mcุ<—๛_Šy๕ท่Cq+๔*7”._ฟ‘Fใˆม2ฉCfคƒ–S+/5“ะฐIึ {ฮzหf0{/H+k)@J๕0฿gภู-ฮฑkXJเแY6K$€gˆ%ๅำเค‡m๏x็Œ‘^ํ5้:ำUดeศ€ฮeiUุKƒ ืาฎ๗žล2ฮธ}b›ศ\54Iมวษkฎใ{ k๋ะะk์“@L-็พgh8๊[e–ฌฎฎ ฃฉk…BฬR‡>ณ„ษ’Aญา ๛VLภ›๋๔žLŒ๒Ÿ�“ฐป8็ Œ(œ%#฿ึึ#}ƒัi��sC๚๘ั}‚๗fn๗ใ8S&ƒ+ะฌ QoชKต;ฺ ƒ0ŸMบชAจ{ฃL �ิCจผ%ฯ›ฅc*-Kอ€#ํmมฦ8bญด•ๅแK—Xw๋fก–จ ฅ๘ตฏฅ‰ฉ)~๙้ต;ฏงื^}•žC๓0�๘2โ{=ใอ8ร”|-ฏะไ‹ e• ^ 2iฯ=๕ณ๋ .jœตAฒiํงถ��?๚7[;0ํœ^TGะ�€#^†~sLvU€” !Sœ��ต0จัx^ฒOุ ศธ็๓โร@Py๒็๚IE์ปUฯ–?†� ’‡4`๙eึถ˜2โ๓ญQ^ถ หณ น*กiฃ%Ž:�๖ จวx6ตฅู‡@-ม.�ิ h๛‡ eXš๘[๗ภ็ฑ‰คv+ณซ&5์iEฯตcตkNแ๑๙lถ่จ?j •wp_พrเj(zOŒ*;N 0ใ๏ฝyž ึdฅ ซ—erแCySOM๘พ—rก๏ไฝc SผŽDำถSฦƒษณฃ6๎๖ ูว"&{pฏ‚f6คิ๐รu7ซ๊97ั >ศ~ศฤ{่ojซอ\kซ�ˆ๏9l๖ศ��lฟB7 ฝw-žำ0œfU\ž๒้ŒŒํ6 ‚›ณg่9™$6†,†&iฒอ็u} ์G…Ÿc™„e—ฒย บต‚gmkkO Œ^�เว฿e ูC@ะ 4ฎ,ฯ!ซ0Sธg{UTืั›Bบ?ฒZ@ฏ+๗ช›น/า�ึŠ๏�ฦ๗4Jvš<&ส3œ”€T˜cEkpกd‹ฬ‰ฤ™�–๊kS}SFu>์ฎd@ฉ�˜M'8ง‹sำ�IAjl๋‹lห๒ฦJสEAํ ,?%ห~RJGWะูœดฒcวb๎#๏ฌq๔U 4wžY›า˜ษ�jๆ@ชN–Tผ3g.๗sฤas�า)๋ใ๘ฉPะœ* ข๕‹ฌHฝ฿€ลโ:ฎญฮŒิจๅU‚vSGพqาplcใ�\่ิqŸ๙4=1Ryj|ขV˜W@r‹fึ฿�1�–+ซ3il์)]ต@฿ZคIฮN™๕Œฆ?ผ ƒcะขBMvิœoน2�%“n-ีแ�kQ๑$$; %ฺษฤ‹VุMdi* X๋™ว ำT"ฃ8 ฑผq‘u7 ั฿qŒ�›J?H็Y�&ะใีี:แœ ืMฝใ๕ 4}ฒก]=วžY�๏k๕ ิdฺ่ฬฯ’•iฯK Sุ”ผ�„@CภU@๎bJ’ฌDฯšมฒ๛แืฌ+=o๐Q ฑQมะ�<8ฑ7สฑ๗ล=:ั!&*p ๆูbญ8�š4Yf�8’&ฺa?๔ๅง[ฤš9มงp0ภKJVั+ 3แ๏\๘Œ๚6‚.๊ฯฐŠk$ บ}ไ๓ $๘3Yฉf{ฝWK[ช˜žas^{p8žฯ~C5่’b^ืŒ-โ™•cž!p�ซe‰ผ-ฯHžY๖j<?T,Qะฑ”!€.ฆ๓oLndM›3ฆฟb&Y฿D`W0ซ„ณ+˜@@ะ~ภ๛๋3ํ�-อ/แฃRR‹ตB0พƒ-)@“XY�ฬ{ฉo3&ฃvU๛้�ํค*มrpม๙0๓nฉ‚ ๑qฆภŽูฬร—๙ไษhša�gWhHŽฏำูู็ฆฎะ{~…Œ‘|dK_z“ฬxd๊[)จถพพ›Vi ŽฯbฉEู๙]ุN 2yท_8ษ”,ู+6ฒตฏƒๅ{$[สxO“L๖8Sฦ-?ิ'U>ง)ž˜œ็:dœIBู„Pฦ…ฒฉฯ~•%€zกžฑ ฮฟๅp๎ษ6ภ„rcV]�ฃŒ๕w๔•ีYž'KDุฒqช[qF'^Œ2๙๋i�ฯ๕�wะ;�Y’LwCcGvูgcmำ €๖๕ฮ�_ˆ‰iณ“ใฐ&f่qภฝ/Nฑ๎”u๒{ ราห(ืF๏ีิ6ฐำฟะ›ฺ™ฝ-๊6lH5zฉ ช4บึ6vษ&ๆฒŽ‚yฤ๙ิึwฐ™m ภน nWW[๊๎nO]=€š”้ s]=๘-๘๚y2::Z๐ปํ�!(*‹Pฟ๐๐VYฒ,J๐ƒฃ๏iขภXํ‚Y้™คq$ชบ*๖Žื๘z~cว8ซ›๘ežxพ<'ฦz๎G8ภ~d่2&s\=ซ=Œ๔p๔ใุxรฯ=คก๗ถo}ๅo�๖๓็ฟาlีo?\o}๋[น�ไ{_y�๏๔ŸๆAถEษ“)ฒ9I0”Œุฬ› ^…i€'�`36#iiร ‡†สŒgyEvะu4#�wŠ ‚Bl=๗ฯ๑!ŠE กำจแRZUุQใŽะz(–๖เb้pBwศ|ัU ฒๅิ‹8–06งŒร%‚ ":M]๗๒ณtไ)็n๚ไ.h๊g#ัoฦมน๙%‘~็s+ํ"~: Rฌ5,*5ัํ*LKQฦrึAิ\Eg๔˜@UŠถŒ-ฌMMะั๘๕๔๔@�ฏ',€ ŽฯฉฒZล๙Q•B/*่}dตซ™‘0ฃ$"๎!u]์๎]šY;๋\'ต…JT% ฝฏ)ดจๅใูบqภฏ_ป†ฃล™‹Xcdฟ‚ฉ™)z`เgVYOE๊iu€ํhฦฮ:H�X/าo€๓ํซ€O0Hฐ ส:ฺ[๊าๅซ�0M๊™ๆภผ_้๓์?q_้"ณgึOD}[‡˜๋I]ิ@ˆ๏‰G$2��&N[fY๓"‘h~ูu@�ฤ>ุLH6Œ๋jpงฒ๔{;Tุ๋d G~P๓6p2ฅ็™๕9ŸžY!ใพ–~๖ ฦmž—ฃŒ;._N�/฿Žาeใรงrิ้๑~ฝฎ „rแ�˜ํŽ]`ํ�w88Zณำ“้�งร4 “ศ^๏ีZๅt8ฬ…แŒ–Dถ๖Pืู€€iข<๖ฑXELjfงฦ†_c2rษฦcฬ‚j–Cก๑ธส=ืภ ุ��"{M Jผปป;œ:3ธ5๕ี้๚้สะUสVช)f฿Šh|ษˆขuƒว”๎ผ๙* ว"๕“ซŒ Nื^z™ฆtรd/Eฝ๑1ฦH‡reqŽื๖แTูš�หvXG"ศช`JHtฌ[ถWฎ[สaž2ณ‚ฯvส‹สpbส Š๓pฺโ๛ฏ\J]๕5ึ๐ะYฃํ๋•ท�๎^lvEv฿€นEƒfน@?มS/†Uฃท†sถด„LฃปtN�Ž,A=A1็ฒฏฟ=�แ~“`ฐ;=#pษ็ฬ�฿�oาwพ๗—t“&‡ฝt‡FlCรรฌ5จ8ฃฎฑ้ๆฆ่ผœnืo�ฆแ6R :ฤ๊% $Ÿ<}œžO=ž ึฝ � nอ“๙ฉ5ฐ‰Cจ.l˜ฐœคฏง ฃๅมส\œ{ ิคืฤyV�4cnVD:tœœ�]@น%œ„>59™~��า“ัGP†/ฅฏ|๕๗txศฑ‡�อ{u &'ฯผ๑สk8JK8sfศตดlY:ใ๐ ๗+หpศY#Gึร๋์ข1V๏ฌ ขG,1ะชdอ”aƒ๗�มกจ+•Qฅ~rO๙-•L‘‘ฬญj@เาา|‚พLolภxผ:Lฆ…ŽํeŒมE็H!ึู@ฦ>ป๛Yบ{ฆ๛ส mิำv๚[d�ศ๓>�ปฬจfM*สฃ–eh•ม"๖Iภ ๊?9�~จ‹ีฃt(ทฯG'g็๊๕›ฐ ฎฃ`p]ปBฃื~@b2Jฺ!‚่‘Ÿ@ Œdภ๔ะYtbC๛l!�4tดN:lต•Jzะก๕”ŒCๆK‘๕๖�t๓ํ7™>s•,๛ ถ๗8 t –1ไใ€๐,-.:กg่bd9—lุต�ท๘ปแ`ฒฌๆฒฟ‚ฺป‡�4C�r�“Cz.๕G๙5โร่‹ฎŽŽt“ฬœใŸ—๗$฿Oณ^ฯ็0ธ๐๕๚}ู.็ศฌฌ~@L‰ช(Imํa?ฝ๙1ึ$๖u&ึขู’5ฆ๎’ �z๊ทh?ร˜ณfฎณss‘๑ŽตCODcjDาQgLtโ์ฤ$ PไL฿จค†^Z=e?ฤจฌ)ถS€{ื/ˆ=ๆ=ด๑พˆ๐<� K๗ฃoa‰ค์}“ D†์ ฎแ: ๒ฤ5Iฐaฤ๏{๘;"๖Zะ?ฌฦ–553จ้!ผษ๊ย,ถ’>Sskฐ~`{qฝ=Šบฅ~kKP OทN’วฆz‚Hh๘mlเชOa#\ห"dบ คไะ0ผธค ฐ›�‚A9Nภฬๆ๓�œหCsc}หl~&Hๅxื"๔ูโ giY#{r'ุส2ิ2%›Gv :–�Po๋ใํ„€ฅ�oxฦ•S„+˜H“ใใLผgdแ=›ฎ\น‚O๓":”L๚๚2๛ศ{ sž›Lหสช ๐?ย>ธ{–ฦ LฑFcฐx^ม๛&€ชชฺ�ป‡๏ešศ€บฏ–kุ-ณ็–นFต์ร๑ๆF๎›~p๘e;$M๖`&ไเGgเ๓L๋€ํฏ_•aใ�-cื�n๎๏.’็"C�‘๚P�N! ฬF(*qีร�„ฟWŽธUqฑ1”ldluž่๚W_พ�ี�้�ˆW�bp๛ฟ๚p์d๙Ÿ�“ดทพถ�…ฉ๙๙ฆ9k~NwŽp"F…ฤb`ฮLบจ™^2ฒศY…มœอ5บNด!ุŒ‹Cฉzธอบ�)๙มใ‡ฉ‰ŽฆŽ…[‚‚9Nc™h€จAF๎ผถ‚jfส>Ž๚ฑ&(บงฃเซ ’ข[8ดYGู้(Zปคโy๘๙ ๆชR‚z๚ํฟ๚^ข[๋�6”เก1๚‘๓1 ˆฐส?vกำooQ›e† รฯ฿‡๑็`ฎ’-”ขc@`ฮYต Qํ@เ8”"wojฎศn่:’N4ิ‰u‘kBqฬฃL4:Mออะ๚Z85œ>คo†f;ฮ‰•ฒ$zoูƒภ‹FUด_…๋กVQd่{v&ใฤฯฝ'๗D ฆ๛ขm4่(9ดaง›C๚ jูัYTis:๒รd๓ฦฦ‡ษฤขŒEูWGศู,สฝ‹Pd#๓‰กQ‰Kถ›ฟ๗q e๊Ljืโ�ฑc8ฅ(Jฒ]Eผ_ฬRšฎม@IDATF.jq�]7ดŸ644ปไศGืZ๊ก?ฯŒข>\CmะๆC>?๚&dร†”;ƒqห# RอŒ๒…ŸI-ฅซ+€ƒฦ�{5ร 2ฌข—jZศ5ฒ ษZŽ3R่A:�-o๏J›ู้xw'Yฟฎย4เ�ทQp@ท�ท๋์ฯ•5=)ivŸaDhOO์�'้<|?ะ่9œ}3ค,2๗๓gงj็๑ฆVhๆตa�<#>“(PWNฐไg1ฒไX฿oO'‡Œ‘\์นcขสๆjpL ๕ENใต ฎSYs็๋ฬุ่ญฝ’๗6ธ่ฃแIบ}ใ-‚™๑ษK—aXP็kfื[ฐวฟฟ�๙ํ๔“7� ะ›K+4วดLง zจ]ธฅ#šฉำแา`แJ‡ฌD‡๏xN๗ญ3งŸXHVจ†เณs CจT€@๔ษ๑‹g › •]N—ฦNะญœB'…8Ši‰๕nลง~ณ�g็ฺ6Gณ9ี:™kึอะ้”บG๎;๐_ฌกณู P]ซัฉั4ม|็…™…ดว8Xรแว1น๚…ซะๆ.ฤ๙บ�๘>๚ฅ™]M๏ฝ๕&#ย๚8KœํๆิCฤฆsƒ}=้ƒwg๗qg'!เ ฯฒ�ีู‚ฝ5žกค@=:Oภ��ฯ�N๗o�$c4‹ˆbYO#zโ๒ี—ำ๔ฤู€ ญY0P�ฮ7ฒฑถŒ�ชฃ†�•ซฏ†a7ฃ}๙า‹จอู้Xื} �c–ลล˜YX0ŽฮPฆ48D=.๋๙ปŒข�/…‘ดwธTฮ �คrำ*เƒฌ"ฯUร~ิ,rุศL‡ยršMฒีฃ€ณž�–๎ั{ร&l๊šŽnšแ"GฮžDฌeŒฃเหYoƒพKWžถŠฮt7�DชTJ+u0`DP�ณŒ*ใ:ใ#ร$Yห>5์�ค�€Z�ง3ดw3—mœซsgฯ่ธ  ,œA›xj'ิฅ69t)ย)Bn=':3๖€‰ฬ4ry๖ย3้2ภสีWฏdั7๐ gO๐ำLเป?}“�8๕xy2Šค$�B‡์iฃภmlVd€ฉF…@UBว๑<ืฺiฅ€฿KWRหฉ้8ภ—เู.๒ง~ฌฅK฿ฯาcวม^‚žJตศœ๛ฮ€šงฯII:ไูกq_`ด่1ฮสอปŸก“ปะuิหr>wpุk้ษั�ฺL8B-๚†ฅ �h2�๘์3gทฉQ6{ห= _#˜ๅ Œ ฺgl}ฦั �ฬsJoท4@6LSK็E}IX๗ตี… �์๑ต/~๛ูิqข;ุ(ตddฮิGฏฝ๒๏‘ฃ}๓>5?—†วFำ'ท?#œIฮžK็ฮŸ nž฿™ฝ~า๓8}๛{฿Iํ�Qห�ใท”พ๔๊๋œ๕‚๔ใ7฿"ร8ฬ๛ห แAyFŸ%DbƒH†Dญ9ฟ3{ญŽ๐EB›œ ู‚วฑ๕๓0!๕~=sฺ+3ื�ซฅŽIvLšจ฿2เฤฯƒmlฐ�‰AปvZง�๓5ฺvปแ›…•9)เ`@eทxๅัŸ๛:๛Ixv?eจ/L`(ห๊Q4๗ยวˆ๑?3ห2 ิ๓ฑผท`B๘dุk�3u–ถYb N๐มi–bi‡,ก๔ซบS�้‡AŸถlA3๔›ุgฉ๎e่�"Jส* p-‡i:NะคอTwฉK\_็฿ป.>ฏ>ใ>>คฯหๅ~`ึมr๓็ฒ(m$YVD!M.aืvakUa7kJi๐ษtpB๔ 57–n่ ้•ษˆ1แแ}๐Ž<‹!Œข‘‘ ฟ*ฎ›~,ฏuŸd๘�qฯ€�ญVฤ)‚Vฎ“)3ภฆ(ฤH‡9�)pชฝ|(ๅ[[0ทL #87๖bษAถถ%ณิ‚ห&ฦ,GีŸqoิK�ป� ทFF7€ำ}๚dร8อะ=ภ.2Žq›ั+…ฐŸด?2Dl 8-฿๗;�ฬณฑ–มTŽ †-ท๋�๚฿๒m่JeiUน›%?2ม=ฃ2ถิ2LหsŒ’๖Vต�NีZงกก KIš ”=ฑฐ ะ†ฟzธ๏จaไHšฏ๗5‡”V์lหฆษ๘ถŽH6˜W1EO�๋†œฐGสพMWQ3๚{€่ ฿ำ{uO\Oฆ\ะ@ื2brž**๒#๖X[Own\็�’ภภnู[h|_ˆGPP†ฝ?่wิˆๆฺ๓”ศำฺดc2o๕–ํ฿02ขฏ๎ฤขฮ‚พต>ใ* ฮUdึoิNkส%p.BVๆX๗Q &๕cq๐œ(™ๆ�‘Wห 6aZ^aฉšอa8ฺš[ัฒlชพม๔˜^๎Q†R),9|#ญ+ฐQdจฉูbD6W.รŸrLฑ จ๒ฐŠ๎S=ีžQหyL›ผ๔CPษณ!ะ:Œฝู"f๒—bหƒyห๚๘!คํ‹2ทŸ๛\สHœ�N#�6~ศ4Wฤnqlœ๏ˆษClW�ฑŠ+ฏพ๚'�๚ิตกธเ/๘�แฮ�๊ใ้ �๗฿๘_ถพ๛฿บ<8<��ใnD3)้หŒ_S�ฮ|ช@D+ฉ%ณT ๚ีq:![ฟ?81ถ5œ ๐€ „ฺŒŽทcNFฦ†Aิ ตใHP‡��ย3ฉ˜ฏ“ฎ‡๐€M>T$ซ+�่pS+3ž9œ๋*kซฉ��O#8Aท?ฟห๋QJGe ฅะษะ์•bp yช pƒWAฃอ๎a€Bู ฤ์ต -1Œšiƒ€@ƒn�เS ŽF}็ฦ๛ต�ภ€งกฅ vำ ถeD—Kz ๛yรt69›Gจคžฏํ.ƒ �แ๖ m”rŒ๙>k"Hฑ'๓‚u—ย%ˆ`fFqf š•CŒŠAr]๏\ะ=๒ Dจค่กฌฃO๊0ฎฅ”yิ74ข4 าฤ๔0ฦKฺ๑cอ่ด|‚;�ใธ €pp t"tlศtbจrQtล€e ฏžG(.็หึเ�Wิื”Bว%ำ0อ๋mTƒมใ>ํ!ใ`…:ฏUG+๒Q‚ฒVyiุ 2ฦ‘็ˆฤ :)!8RRน,pคคส ‹ยณ๓‰1ูม9*ฦ X#ตOรฬC@ Ÿ�fEf�eรุาา iํขซ~`ฤฆh๘36L Œฒอ)ญK๕'ŸKวศ€Wเ€H๛- �Cถe“ุp,0ยFd*H้ขหiไm``Z@;Nๅ่}t็ฟ“F๎๗P›NภˆnถNต„ฆhๅd๚ฌม.#0*'ฮวต1”(ณิ[ัuตฝฮ 5"ฝOง>8@งeว 7—ฝซf2]Ÿ๋L��ํ 5ชฅhbZA–๕5“}œฌฏ ’Œฯ.Žž€PoฯCึ}+2ย:๐-d๚ฯœ ฃืy๊Tz๖ล‹ะเ�Yƒ‡๗”’Iก‰๋9ห{ี8ึŽm:ฤัๆ rvศJ‘๙uิ‘Mษฒ๙YŽ”j%‹Œร๎ั.A#ฒˆT4mฒฺ8U•-วา™็ฮฆ.kษะาึหฦB‚>ฎฝdฒภFr฿�้�๓Fj>ึMวไึิ?>ส9?‚0•ๆa‰Xไ@อฆแT6Hž]‹ณศ�1›ฌN4ญไผh„'& OQZL�/ฅT@Pส),ˆฎŽPM7า๔ {�จ&๋ฮ๘จ3g้�p๖jqา;o�Z๚$Fน,�#[zŽฒ/๕ห้ฬ™“ฉ9Ÿฃ^tld”คuฉฃ�$๋—KFu” Ÿdixp8�๐SœฝuJP˜่ภy\ญเณ ๚ฏ๔Oธ ภฯึN 8_e”ไXUKข‚ฟim๏ฝ$-๙�๒ๆ๗�.=น๗9gm2ๅฑๅ0มfG7H€ก|์์ั9\๙.ษK_น–šOuย6ศK]ฐ[ฮž:“N2๔b{ฉฎโ์1วน/T•โ„?�-{”พ๓�๏ค'8อK‚R}ฯฃพ‡ะ,๛6ม”™1™7yุ(™สึeL๙ผ็k\wผ"ฆๅYฎTA™IMƒpŽgัฏซ1�<€Klˆa{ˆPฒcฃฏถฮ’ ]ฉw@Ž ๅ�ษs‘‰,๔prวฟ๔:e5•้o๒F&ุy๎�ณ์Yvtoฟ๗๘1๕า=๔ฬจH�ั๏�ว€ด+้ัใG๖‚1ˆ7มM็์จ?ด าฑ \ ฒ�ฐnY?โ๙/ค3ฯœLmM€๎eiฒ2lA� ภ๖ฆcศŽ0ภ"“�,dMฬŒๆa#8b่nึ‰็ั:4ซศบฉฮe7˜xัq6ธ1ˆ•=ฅJ3‹ศ‘ย>p?๘#fฐ7ื™V„�4;šลื~_ต�ฟ�ฆk�หยู+๕_5ต๓๖ฒำปษšR2“๚๓Žร4็]‘KไmณfuY@}…"tŠ Œแืูm�†ฉG่œŸ‰gฤมฯรŽFฆ—ภ"‚Ÿ๕ต,p]ฒHd™N{[์‘ๆ0ํ‰”รz[aฝบฬย]Vะ็xว~๓oฟH4j๏ีu{ุŒ #หSณธฯึี)Aำ ่้:lฐอghศJ้€‰ฉjJฐ  <ำ˜๛f‡ 2q@\�ศฌ๏ำ5์ดผDT„ฬu{) ้ึ� 0้J๗ตvˆ!ƒ6…เ8Zผ๖#“‘้W#šAgผกsl๚ู‚ฯZS[ศุอ"l๑&zฆาฃ สe9G…๔eั฿AG—ฃŸ"่ๆ}บL 8;‡ฎœ[ [3‰M9ภ้ร9 `ฃ›wงวำุตCMJnxพกA'gอก_/๑yฐEฺ๚V4เ)‚ศc1S:œZf`๏3ถฃ“ฮโฐWรƒฃi{�วทq] VมฃX6๐3จ�bLฐ8†‘Cภ~หึไ–= จร฿ไrๆ7ื๑๘/ย๚~๛�Xงkส.ฌW{@*๐;ฎM9ภ์aห๚ ˜หฑm–ฉ์1 ˜แš{๚4P๚”๙ิ�๏‚ฬq�ƒใi‹rปi๛๑ัqึƒ๘ฯ\พฬิƒR๚%=ภึิะ๛4พ๐dœัŽN์2~ิยพ+ ษชๅฅ)� กีฐจNฃ๋๐‰8๋3ํAแ+ฤŸ>"nุเ|๓”ฬฌ.Qรจอโ<สลธGงัMเCุ๘;@%ึT€KPผž๒Lว†nณ_๛ฦhd{๕ี‚�"SูPŽทw�+๔:๗ša&ฃ๏‘)uึฺŒะˆ`ศค ืี};$=7ู€2๊1TZ€แห *ฐqž {_่k๋ซGโypคตษ_เtฟ 1ๅ›ุฒบสู‹—^�W๚็฿ๅ€�ยจ~๕ม ˜e}�ณ7_�‹?�ณ�็ดฬ์ู ƒธyฯFยร้‡ˆฐ�–žb#B๎๗ข�ญ8 'Oœeซpค{X็้&๋ณO้ะ?—๎�พAี<™ป„97�ญ@ก�V#ฬCC)ฯR‰ี ๒)�Yฐโ8‹JpXข8ดยxฤงใ�V0\;ิ‘MŒอ๐9›>zšNMีตH>๎ว.ลŽฐ1s‘ษ€KgททBอ3zX๖๘?ฮA~)Jษ€@BŠฆC$• ˆCH๖ูฑ‡ฏผz๙ลXฏ?5E�(๙'Lรhๆา,nSCsš„vนD-๎"ฮี.‡ธ,‡ญ8@ฬ˜^ภบพDfQCว๛ษ ฐŒAร`M‘#™*3แขฏข๎\+cเE�ษใh�ฤว๚วhˆ†’?เp/ฐKPปท ฅœฏRFฐDFCอs‚TNาeEจ๐s1 เ$้น ฉc-ค.Wt•sŸ™‘~"ฃ™LЁ‹ฦึฬtMตwฬeว‘][ค ย ‘฿๛แดeษgฬ€์1ฯ๎ณ˜๖}๔๙ะี86ฆฤ‰ๆwŽๆ”p์ผ‹‘tฯBƒžj 3ใ„ฌำ›ร`ฯ,Bฑฦ๑9ฬซ†J{2๊xฅ}ฉ0l:;N<ะู&์ฟื›ฆฦศฌค;�Hƒ”3�]ญูแษ4�฿ฯจFNแ�—“M3k^ฬ>•F(ฒ 8œึณซ„•5 ŽHธŽเ–ูพ ฆ๘|Ž Ns๕Žฟำ9ฒัก๔ึ5œGiุ#z(เf}/<๓ต เ๓ษญOะ๏…ม:่h๋LgNœXHฝ๓ณ”‹ฎ-ะย]ๆ๙(!Kฒว9q-๋ศ’{/�๎?Œ๕บ๖SฐVฝ๋๙‹ฉ๓๒ ฉ•Œ=A์1˜6๚|p๋  ภ&ƒ2›—ฉfฦ8ทๅ!ื๋๋๓กว ht4ฌ๋ƒมณ ุผJๆw0ษq}K8qป8V \_`๔ฮงืcVธ™ จ›[[Z)ษ9‹^>–พ๖ี฿ฦ1ทฯGEศตŒ”ีeฺ("๊ห}‚ตmœม&ึ้<,“šใU๒ญธ\6ƒํƒ,ห| ็ˆŒฺ6@v฿ฃ'i่๎zLG6( �ืีฐoวšYkฎ๏ฺ่้๑a\01์๑ะ `` R]SCฐDฒฉutํGฃ^VฆkkECM๕ย‹ื^D๊&›ตœฦ‘Ÿ€ ฎc˜™ฟr@ก–ถvjk‹ใSผn y`t่@_๚๔€ ฯ้s”^uuธ�)™�%ส@๎�ฟŸพ�ท“ฮvœJ_|๙5€_l š@ฑ, ฯžVI๕ˆ6฿๗;FIย?๘‡Ÿ�”๛ฑ“'Yวบ้0ŒŒ ภVฅฏ|ๅทฃฮฬาO–ก:ฦˆQชv๔iแ> „d88ฅไๆฯ้;3p~'หฐ B�oFMDŸCๆŽe6๕:KYัฝ‡b Bฌวรํเ4› ถ//ยมE7 ข3ปq%บ=J=�๋_พr1�๖ืพF\เ6ษ๎qฆZ „iH†ๅt๋๐šeทดฆฝ}€อt‚‰เf(�ใiiฃ6$วฑWฎฅๅEฺ1๏_}(5\&2ซ|ฏฮQŸปึ�”ถO}๏Yะืึ�cG0�3โนดYฐg1 ?I*'วF~๘`ญุ‚ฎc™๖พ`^; CPฺqw๙€mžฟข2l๖วพTธ๚้HTRฐ [m9ƒŒ:Œ)ถศ O&ฯยง Œ์ŒเŒcP[�:Bื pอาlnl|$หสdศ0# x๕Q^sฌ๋ ๓�”oึ‰ํˆC๔ฒz[ มณjRbYqค๑.ย> ฉPp?V$ ฺŽ8วู(U*ย๖t’ลeP)=^ ณพสถ�#>๏ใ~�ˆ๏ํ‡TAY€ Ž=�7ฯB์rๅฺL8ไหuq��ฝkข์eุž๓‚uๅ ข—Ž�๙žใ๔" DT๐xj|2ึDฦe€ย่F™ต%์Y์๋4=6่!ฐภ�อโซๅรZ:โ็Ož ค‘้ต4ต@ูโ–=ดุKtF]c๚ €RC› €พ‰ฮ เไฌYvRC ิ1์ญพ๓4z6Sศ•Yไu|ค"าน™EXง๔�ูึ็c‰Yฏh์ศื=~ฆ˜ฺฆƒ๙m}Tฦ๙ฦ7ๅY�?'6d;ฯ!ง‹นจฏเน`ล `+๑ ผžเƒพฌจohพ_œ�]๖ภา?๎Œ™ sAน!็๏dY~lำอ ฯ>‹�ฃ๑&๒Wฯyฎ-Dฯ \{h ํGเ=จk`Œ„รvใ}Lฮิ6ถค˜ฃ)้@๕�2อ็๑ฃ่aร� �่ืฉJ”ฎฝศ1:A ๛†ๅแฤ{Ž)Uœˆฦบ<ฯพ๏6€L๖ผœฟ�รGฐ1ณ๐�โBฐ-šZฑKชUN�ธZูSv-#s\๋๒ยZฐ‘iลบฒพสบอ•}หขZ��&แศ>kcน+๗ฦQด๎™=”œd c ƒฎW$2ต:$,ถ๚IฦŠ ŽzK 'J๘�ำ๓ฌ/IP5ซ?ไ�ศ:E๏xnJfฏฝ๒๋฿��๒/qๆ~๑?~ฐG‚๋ Sง�‡๖ฯ�ลฤศ่)ไมaiV[SJAข็‡อๅ<ฐ~Dเ‡เ+PธUPRi…  —yiเI?Mฟ–SE13dฉK[š#๓9‹ฃ"่็6†^Ryช&˜ส!jฟ๗~ฺYbฬ–่ฅF‹ฯ(wภฐ–C้ %…Ch�”}m8Rbจ@ูา็@ฮ่่ไดำๆgv>฿ฤ1ฺyvฆk1ดeณfจ>=ศPดyv…ฉฌ2_ฒE((]๚กFP*ท่ฝ่๋|ds)ฉภ™Q™ุ8๓ก—1`gf'J@ณๆwข ฎฉO[C0๙�…gู=�โฑV"นfคqz3vํ•็}š™vด^44a=tไ�ฏ๋aีน๕gxฃ Uฆ;ป26ธ}@๋ฤ๚๚๛˜ ๐qบy๋6ฦ็ ใCœ๏™ žป:๕:{:‹*=•ฐJ[ฅ`–$"€7วQ0fนP๛Tมขhnfv;,•™@Mะัา฿  ˜Kชฉ�%Kปศ-๋ม2๏ฅ๗ร}.ขŠVFะ„QาxDษ๏Y3ห4ฒ�ฐ ค�ู„ลๆCAใำa�pษbdะ"ฒ<อx {“•ฃžœฬ6ๅHN0.{fลnศ้แ�AX ฃะอ‡Xฏาฝ๋^4ฯมy; rFaP•QA3;*Sณ:ึใๅ`p|&๗อQt68Tโต�ทฯคฒๆOโรs&xไ‡ฃ‚�/žyD‰ใh,qฟ]—B˜2‚U ŒิqKHš J@ฌE^‡V$‡�บVสธฒA9ม˜™มƒjqยEœแป๗nค‚็Oฏ฿@FD๖�ฑwว�;Ot๓�๋˜๕๑๗ฮ#๗4&R-Ÿายง™…1ฎ จขผ ˆ๓S€aฮCพชBฮœ?C๐|,&˜ฌ`\ืaX๛_K ่l๗?y๐m!›ุ% ๏ฏT[๚s็๎=€ (v6ึ฿ๆƒq6uศ‰”Uว้< œ>fวtœพ๒•/Q7�uƒNU(ฃ9ฺ็nำ•๙,�n๚�๏~/]�เ:�3ฮ-็kš:�>�0�ปwฯ‡ฤฉ˜xƒF8ณฮwY๔'๔64๘ภacu3(ƒSใcdlŸVCฝ�%�‡–sีึัA6ข†๑L�†๒nณฃf@ฆ�เจฏ>€ฺ9าฯฌmtฎๅ!บC'bc�ƒŒศ„ รอ™wŒ#ณฐฤdชแXmธoจ='ำจ6†ใฒ+ลฬA”ฬ พc >>�๑›iข$ี`”ะปP}Bศูื อญๆ็฿ุn้}€(ญ�่Ži‚Œฝt๙๕/ฅ–3ยฉำ‰ุ !ุ�๋ืำ$Aๆณ็/์าฯ&B>Yัฒรk€ยณ4Z^œdLkG8>E่†]2พSะl#{ยี•9#M�เ! ป`้E%็iจ๏�ฝB:p–กูณž�d_๋a>lSsฏ๊DŒF๖ศัrรƒใ\Kp๓€์๛0@๒Yม้�d')ด…๕˜ะ~uผŠ(mฺก๖wฒ( =์O}wฐ+NŒ `a9Іl"ิSึW๛้ฐ'ร&๗+…vqn‚I.าXฎk3A'HฟถK~๛ๅ่ชฮ4JŸ^�๒฿K Œว˜"ใฒ8[fvd๓ๅGsภe@ึ‚E๔ปุ ็ๆ�ู๓ฺ้‹/ธŸ&๐=ฮ�ก—ฟ๛wศึศPjmhIีฌs7}>�เ#๎C๊ีIฏUืซ� eŸ-!7ห:š›dฝ7yฯe&Z86ถ€H›04�๙\ค$‚�%�‹Žฃa็็fYK(ํ่;ฯึส4`๙ดฬช๗ฬŒNrNส|ฮ9�n�พ‘ž�9ไ;ศ‹šะ;Ÿ|๒ภฤkUX5‚�|6t๑›?}/�น Kcj�Zื’%€ ๚Sซk�ฑใ�™:C}a‰^ฯภ#SฏงภผYžkFลต+—า+/_# nBŸ2มc‹Y๔œ�๖ฝ–ฒ*�']ุ่ิ์™บF�:‡kf๚‘Aว๊ˆ�ศอ็อรŽD3รฉsVN `�[_“arnเุˆQอ8ฺv-ฏฆ‘ค=k�#'Tฐa�� .ีแฏฐ}TŒอฮยH!€L$Lฮั��gFzŸg0ด‡Šž๛&บง€๗5ด4 ’ œ็=d3:ฺณnิฺsoฮ`ฺ{๗ฝ๕?j`‘UฤHห$˜E8ํ$2ผทฯฅกจอT/๋�( r6๘62 ฺฅ่ ฯ�ฤ{qฮe—ฐU%ู๊jิeOุ˜็z��เิg�9ไ�B๖^�มrj?ฌ5z๒xฏ2 ,�Hบํ{ุวแii‚๗!u฿ฑก�›=๔ฬช๛UฟFๆ “Lฯ=˜}>—}MฉํฝF ฟฬ.ๆไšฎe ื๚ฺeX•ฉ๋๔iฮpV^€JWภะy์ทIญEtขิ๔ ˜จ�่ไุ^‹‹4H%œ…5;Z‚�6รฎ‡เp~ ŸvO๖อณต0/›ฺj(• &ฟบ}K#ภ‰Lต ๘ฑฮZ`& ุ๑ หฃiแว๘6#ฃ3๘ฐkฉ7 ‹OฆƒSYlnb-Qฌฒข~ผ:Bฎห๔=ั –ึl 3[Œส ฟŒง‹˜ฑw&ะ2 ฦ๑3X�สZ‘จGม<}p}};มE–3RRF๏ทอต6;ห‰<ฏฒ3ซะ1‚N)๐l๑งศเ~็Hเภ๏ฦF' |UH<๎\š๐�ๆ์:า;[*€็9อศ2ž5| “ ฏพ� IฦิีQ2‰ฒฯวBŒw#vaส๛[Š�?wๅตลg้)Hpf(;๐\cทgZ ๛++ฯข_eฏ{zธืL ๒˜฿ž้‹รำMž+J–xOว/S‚�า�น๒e\$;A€!U๊๗ฐWŽ–Eค}฿ไ๙M>ญ3�AYLล`�ึ๔+�ฝ‹๗ิ_ฒ,สrRฦYฎก%แ‹ณ_[์…{่$หู21 b…\ƒC˜€Šsฯ= ขศ�du?#รž็sญ*๔XGgว�—ฏฝ๘ํ�?}sรฒy�ๆ๚ใWภ�๓๕ฏ�ำ†๚_�๒แ�๏ผ*อฒ๊’NcำŽัลXวK @j“(น@N„Šุ๏ คƒ๙aู4 ถ™๘ž๑ฑ M‚‹ำ†ฑ7KhืW์ฦ‚`ไ[$kokร?ํ๗TY„ชp k๐ฉยˆ๑s:�•€ฝํZฎฑฺe6kSR\ZปEไ=.ู� E} b5J„z:ฝeึ†C#ฺ$+ธƒc5w�ทM9F ฦpฮ‘sXัOย8`gkU<;(Mƒ˜๑๑)h๐ำ0 f‚ฎiฐงใ Vv…Aพuก~ญ$๛มฤ่�๓nทX_ฉyG"ซฌ%‰ฌ,‹๐›"ป`V+*š-ใะ๋5มิฐ›พ‡๖ฉ“RHGV๎มd=5‡ิHญct;ต„S๏ฌ๊=่aาจรใ^อฺปภภึ=D}€Bqๅ}3 โA4Ikฎc$ ต–๛d‡J\j˜/๋ฌ๖M^้fข$džจฤคฺ้๐p‘ๆ_Kใ€dร ๊U๒ส‘๗เ‡ฝ d’ˆRโšฤ^H)f[BมฉX8๖0๊7uฆยช:)๎v๔-& ลมXfv,FGmฮQ6ฐลj€๎ฝ๗?IMม#@X�Žฌ�Yศู…1hปษLฅ�ฯาฌn&๊ ไสฆT PฮศFVฏก๛c*ว™ฬฅ9gฮJอ�r0rXH่ผf„Pฺ(Kƒ๗ฮšPฏ3ิt๎ษZTeืgw}lพdท๐งฃค”oื�ฬช็O๚๘๘๘h๊xฤ™‚Nืส‚“๙ฅ+บRงCๆน๘ยซฏำซฃ5 I) ˆูJ฿฿ฌซ2ใูึุX๛›_ ุ€‘m@@”‹ำ๎ฌ้E๎…ร ็:ป:‰:—๗?‰ณ^ฯิ4นQP�{๎คj�พˆฮำ~t=}xใFะ๐ซ‘ำ,‡=ๅM`0˜ ู<Fอ,ŸฮcWw{๚า—^รฑ+`ิิฮั6zh9ฑ f‡rฉั๔ฃŸ�ˆ1oC”TคŸ|–~๖ึป่ฏfจฆึxS๓ษ�ฬ“ฉUWmhJ'-P้เ,NŒฅG๎/…3›Ž*\†ณJ๐jO‹jภœภ_ฺส) ญํmฌฃbใ�g‹ฯชr:Yฏ๎ค�ฝPE—ฃTHpศบฬm๔C>Vvv๋™ี}‘๕7Kgๆ๙�ัF ๛ ์†�ใ๛�6๔LQ^qบ�ูp$คฒ’ํ0๓'ซไ๎ร๛้๛฿�๋t@g๎2›J่‘ล”น�๖˜คŒ4ศษ…ฑ!ฅณกฉณ;XC9ุm‚฿แมA๊ำ'า๛oฝ +ง?=ก–t๘๖ํTƒ์็<ฺ/E&‹`–A๗ุะฯฝ @๗€ ฟ“์h+๒H€.Ewqšsƒณยn๎!฿๖เํก`2รY�dZD๎lhVFpไศสdจฑฑ)™‘�†yแzXgํดฺ+cttPzำภืึเ‚ภฺดชใิค'ถc๖Žg{Ÿ๐5หheb!�|๏# Kฒt„P๋๊ka,ŽŽ�า3อบคะย‚*G'{๖‘๕jฎหNS ปฆฉ)๔๖@6>!k7€s;L‡1ภ…>ค eวฯo๛ษฯ~F“ตฎใธA›^แผฃ”๔5‚…ฮฺ‹/ฝ Š,ฎS'N†lฉpศx6ส5‘๑ฑId51�ฆ™�B้ภ�ˆ๕�ย.ตม”pญ,๛ฑkฝถ�Oƒ\Sูž้v’ืํ‚i. .ฒŽํศ๑Iส$ฺ;ปธ—ซiŠเั&ผ๖#่่‹Dย0@พ๒‚�i2ศ=D'ญฆ�เ๛ม.ษขไๆษCFmา ๔๙gฯ—งGภ–bJ}b jOŸ<ภ฿1t„๖D=1#e ฬ—ต!ศภฟ0hะq >†C‡ี์™มŒTgิB่Vb} 3ec็ฯ‰>ำณใุโ-;t+งKL’@_jส8�สกgrอหโ็๊m๕ฌบ�u2qหIฦŸน†™ไC†Aเk=๓๖iฒGDe'œ5�๔จz_™๑u&kd5ท4ฒฦmฉฃฃ™๛ม๗ูYRž.^ฆ)(� ’€Žฉย œ’ฏudทํsQ฿x,Jล๔#ojŽQJƒOP฿\Ÿžฝ๔gหฆสd(9�;‡เฉ_ขว?›๛ฐ6ู`ย€ุQยvV7›นนFส๋yท๘cY‹4xkผญ}wtฑอ€…ๆ็sฬฯ๔+\ถ‘3cใAP��Eหc�งฐQแCัŽ็q์ชTn™;๖BรVฏS Y[W†พฦFภ&3c์T6ž–DฦYE_›ธ�ึO๐ำ ณ๕็ฺ5ํซ2๏ฝYNYFห`ษŸyŸAมFฺณF@Aฝแิ”8+ุ›bฒวฺ้ฒพ๙d์X็aI`“9ช�^fz฿h@บ6ฤ๋+ฒสรส]X#ภ;ฒo€‚l+tฤ8บgnq=-cS—‘๕-nlฒGโู(`RfZํ์STสฯ์U5:>ศ5f8nnข+?  ฯLฤ'œห‰๑Eส-a่Ž€ํุ�สqฆœtร4€M่้ฒ/ ดํ–"ฌเCษ(ฐEฮŸโkภ˜4ˆ2žึฮmี?]YขŸˆz„3ใู๓ร)kŽ,ยNซอdฝ;hป›œ  8a�Gœ!T�Jถเ˜]ใSฅ%ศ?เžะiุk�K˜พN€Kฒ›์Id�ซััAท„‰H๔T‚q็hr\}RYฏซŒK.…‰ำึีM๖Ÿพ‚_ตท:•Fz9ง” #KˆSฤ–๖nุ ทšุgฟqll:๚ อ(�Wkvak†ฦฐ4„u๒„ค๊ใ'ƒ๘ c��\�ธษsZ…ฎด!จ'ยsเฯSrf๊ไHF_พน ใe€฿!Xฑ่ฅบฒสด4ณภ(Gฌ๖าฒšO๒=หF™!%)œ;G~;กก onŒฑลงgDPHจD9ๆฎกMu]kc๗ล๘Cp6bHึ฿l๊?๕ˆ_ฑิKฒทKะ5ีe/\~๑~�j็{)}Dฟฝ๏�\Bธ๘/่‡ฯ�๏๕/๏[๖'�๘ฏพ๕ฟ�“‚�b๚€–:^Q%X_๕ƒ ญ๐˜5V!hะ‘%o([”Xๆ฿€ ๅ๘่่)ส๙้4†8ฬฤWv ี1ีท1฿ฎู/”ีโฮ9w™ภ6g„PCfQBดP(C๋#jˆPย๕8Av—๎๋ ๎|&๕๗๕]t$vn%ภ๓T์ขจzณ(งฯœŒ.๓6ญ�EAZฏโUำ ฺ๕6ƒ[‚๒ส(7žY%จแำ  ๔Tdฤโ�Fศ�†ยD๑9•ยช*Kห=ฬ่j ERงgก�’ูพq๋๓ ๏r]ฐ’@fษ.๎แ่IjTAEŒ{่๘_8ฌ��๚=gึื“eถซต†� Ї�๑;.œ…ถxœภฉ%(ŸR๏�zต[�๏๚ Aซh5๗hๅ๓?ฅVYถ‘azP๓ˆกƒn“Cฉจอผ_9Fผoฃ˜ฌE5lƒ<‚}ัu ‰Hผ”ภปํอjoF!œ)ƒ ทr \DS-P_i~yu"๏Cะ�mณ QK๗ED{$�ˆZฎŠฺfz-รุม:Y8ุ,XgMๆIz๛้qง/}r}ˆ์Ÿ๕_ศ Žฟตๅ–%87พ…YU™™—[‹c,ๅึ&uvmoh>bM-�‰Nึด“nฝg Šaะฌ-bxจ[็Y”๏sวุฝ–น!เ‡Ž›อตฬ0zV �Tศž๗ฮŸpศR9ืั ‡…็@ำ€˜าษ™#“'�.ไทq›ฬ‘ˆoYA”ืาษQVผ”‹sXYEฎWI๐๊žุ๐P*k5มฎใ๒Nค–ณ0>>2b Yณ.ย>11Jํ�`”ดดvEะ%XะอณK1ฬtฯ#ญ…ž�ิาภBiูCๅ3็ฮ…กตก#วŸ ‡l๗iS@๋�\#KoดB–�œ่<™.={…qง คฬcฤฉe/HX$รxH}ฅ๒#ช๏,sฌƒkฎcใว�๛xๆ5ฮƒณ์ฯqZ`žะƒ`”fIŸ�ฅ”ŠU๓ป้ฦ๕[ม*อe<™€่ญยฝIww๒pf##ย^’�ฮร๚N„) ู•“'๛้ศ8฿ฃGฮ‰–JuQc๐`FI๖ หtž'&ฦb�ญใดโฅC=ฐฆ(แ5fฒค.!ร;่ฦ}:q{f๒8ณสฬฒใYฐg‹�ภ-ัzุOž rวฑชด;3ัA ฟ@Aดโj@โu@: }uvQb$k๏u๚ฬ3LJ ๑2lึ=ฦ”yาุ฿]‚›ูฉ jh{\ฺๆผ‡� xฝ๛€:o�J=LฏY›Nู8RMต‚šP†จlโุ๓๘Žไ*๋�„ฑนd>๋้ทA ˆ>uฺin0็znR–กณm_už2๎ิƒฺ�ร†ฃt๖M๗Gฎ๘€๐fบ๘์ฅ%วlูปš{Xลมz๒ค'œ/ฯ�™{O/พx5˜:งEฬž ปัมCฝ=iภ&{3'�เ[“–ฆ—R{w๏ ะ†<ๅๆ‘Eม–mด7pv Ž'ศŠ�y:ฒNa#3ม DtๆคWW2ฎ‡เน–{๋๋y”>๚่}(ฆƒ4แ�I๋๏ใ~Z‚‘ะฺฺฬuG:+บC็™p ฬฅWทyๆ,zQญฐ‰†F†#•ep๓�]h�”ํ�{Hiอ๕`�uv1Yฃฑ)�๘๔2ฦอ`๖Pฮะลา'แ8 ˆ ชg�  หั"ฐ`ฺล้ฎ๔าตซ้โ ้�œ69าlkฆ-ตQ฿์ห0qฬb+Ÿ๊ขYXB่�œใ>xŸ้FทรO8ู�อk:xŸร.ส๊{แล็ข์โฮg7ษž=o ๐N�[ฯ๛ศikmวกGภะ}F หމf˜œQXืJก`PงpุรAjฒถM&E&(ฬN้ล‹ ~™IO�ฟ๛ตขGะuห่'&ู๔๋�ฮ™^ยžHŠ/!ณฬ AูOƒ ฮŠ,!ฟขš๘7e(ฅ2 +รกˆั.๊ำผ๒๊ต๔สฎ€L๓3užcDƒI)๓P6‚™vAชฺ๊ข๔๚ฏฝ–.ฟ๘บ}Dƒ“งNฒ�ง^Hฯ_พฤtฅซ/ฟฬ9>ƒn3�’ิลd‹ ็ฯรฐชHณGXา6ml˜‹ญ1ะ–-M?›gBrช์�ฯไึR›dโF€ุ๒={’ธฆŽH5{hโศคS_ว�ํงcฉœพโฉS็"ภั7 &ืT& ฺ] Lึ฿ฬ7พž>.Bgb ž๏a/าMฃฯฦ‡I@0ฅc�ๆKcIสM—ฯตy~žฑง๚!ฒœบ$pnR#˜œ<“�ฌ`…๚T ว�$๕฿™ฆC†ยSY๑ผO๕n�[;ร฿:!FH4šิ๒,จ+9U”Ac�@ศŠใz-ํtฏI - ๗W9‹ซŒqฌil(Eoโ�5ถFฐ.+RŸ6๖้>~M6Y|3๒ผ๒ล›'J๑u๑‹ืฑY��หๆฝ"ะq•ศš์UGป๏s๔ŽDOcณI๑ณฑค่ฆม8P†ใd๎z฿๘๋่‰-Pถ๋�)๏‚$~ๅฺlA๘/yQฮ O€IMฟd Y#‹ดญ–˜ค๐C_9€8๖„gโ๖ˆ "lโh�*Xุพ`๛๑๐e<‹~h฿ŠX g›)ทtคฝ›๒*๖QrkL3�†�*'ัr๒๔๙ิyแุn๓ia๔IฺZšแ=ฎš8ูฤWแkh—๙หJœxต…ํ]†แœ‡ใิฒIz*,๖์fัธฦหGid˜I^ใ2f่+ฤš-ำดฝ€ zษŽ-ฏGฯฉ_d\๊อกg”YืQVตIืฆ•ืด2--ใ๛eฝฤo๘k“ฉ�๑“4^,นร{`Y‡ &๕ฯธฦ'ห…Ž0ฆ#–เw๎•�ฎฅW‚๏้ต’r,#I๐U�it™ู‚ู&Q=^฿๏ั�pฒt[#้ภ94้ฌ�XA &{ต57�๑Wฟ๔›ตพ›ณ^^�e�/�GF:แo๓฿้ ๆ ๗Tฒ‡๔๊#๛ศแZaDก }ภvzr(ีใ๘็็r€VQ�f ฺ‰ศtM‚ฮF…n›^ žส_…jใ‹Œ'+๒๒฿e8yขX˜ ฮ/‡ฯูิ๖ู4ท�.กIู>ศ๒!–OษD>A�AชฮฑsVqผมฮศ€‚�๐โ˜wq8Wศ†OSิ…อฬb�Pฐv(?ยธฉuDวu$7่ {๛ึ๎ŸzHฝHกFน๕ศnฉฦJ0 …:#ะเฒ�๛#˜คcM ’K4๊™ ชf=เ&=หdตำšต@6)๓�(_ ,รI@วเ`Aคyศ6�=VR™]w๒๑�/%tเล้<ยฉฅส2B"จNาp™/ มš l8zหฺจ=ฒl(ฉ๐ทq khŠฤB*ิztha‚R ๕Tฤุ๑p*\๗Š7‹k็˜Eฅ‘\ฬิชMQ๛icฦ|žอูตyttูY†YRGsKฒ๎26Dแิ๐ € ttุtj €ฌ‹]�'ำว๎;๋�†P:‚Tv`/-อ'X!Fj”5ฑŠkr?[ ๛ึZี`ˆๆ›้ตดภ๕ซm{Ž๛eฆ.F7ฏฐ"อฑ‹0@>�ู'ิ–ัov! ‚ชCพBV0 PMm6wฌฉฅ‡โล)1“myถแfkgW๔จฐƒฏ๔แžy|rœ๚@\ภezT47ึใ$ำดๆGฺ๗ยาl*ๆyรแ"`ึูตŽืF@ึป“|:QX"ž=“…p,`w!หˆRFa๓ŸkU„3‡ฝŽ@sŽ}ถฎฝ’๗มุ้hlžฅAN=็c™ฬแ4มR Aร RCฺสฅก‘ม็ฺŽ๊:ำ€7o^:น‚lฬ6BRM�žตฎณ๓4|ฤ ฺญVE6?+)ข#<ฯb7โyXŸ฿ฟฺ�-_X Gฒ€lu)ŽโNม๔|j๊kkา!฿—ะ_ฅ๗mฆK}ล1K:qŒศฬ๐พvำL๔qทpยe Max j๖Pว> ส๊ฆ]X3๋ซm8LŽ>ี ๅ#ฒส‡ ฅr๊น๓์yaKจ�์๎n ํใ›E�aู›D™} žฟฤ›ZฆŽ6๖‚�" ค๋$หาp„—M“Bทฉฃbํ0œ<๗™‡อ็qพ7w39#:Cูd้7(งะq3Qฮค๊oฒ&6)์๏OวษJž?๛\๚�/�hSบG€ฺ�าNW�!ึ�tๅา— @วcŒŸ<•พ5๖ฟฅe�B~ึ๓๘>ฮฝCX7ณ‡๙e2^ศVp6ค,šแ˜™๗!iุๅ8ืYJYfBฆqีS-ˆอจpCฒ&*�=ำe@3•๗o�ถ%E๔ฬจจ@>8ห[Ksฉ[†™๑C'C/ฮฮ;HU๕e‚’์�๛RSห:X/pํลฑ1t�4ซg6ฟ6mฮ-ฅ๑พžิ@’ห$['GfญฝฝฝL†จL นิ๏2YGน9�ฦ็ซ�ฬ๐�ำcz|<ต6ตฅ๖ฝ๏�อ”M ๑"ิึl…>๚ั๚dปše6=(Šl™ภ@๏&Cœมฉ$ซใํภฺ S๐Pฦู>z้ฦ๛oงอ็/KxH?๛ม้IรAฦรฎุT๑ฺ@�๙แ‰ดฬ9^ 40ะ�ฃ—N~1ฟg฿kšRำ๙ ฉ๛๔ฉศ dฤุW์้ท~�ฝtึศvœ๔ฆฏ}แK้ๆส๔ๆ�oฅฎ�ไ?รN6คw�fศจ ็gwoฑ‚ืุn|‘ษT8b PH…๊oึๆG?�>A มเ@จ๓ฏ^นŠ^อโผNฅžก�tŒไฤ‰6�Ÿ๒Ÿ๛Ÿฃaงttะ”๓BNHTšกัŽvม!™a2่–&“yฯa]฿~๓&ฟ `Ÿ ฤถา_N�[šbC`vฐๆgOœ'S:J—sส0ิฅศๅย#pฐO9Rถ~›i@N• ‚+พฯมF’F`Bc.3ษ๚ฝ๛�จ%‡epผญ.lX)ฌญ3์e{ึศูตtง€ ภrส็_zภใ“t€๓ผอฯ๓)ุ†ษ"a‡๋ P\จืdKุฟbส๙ึ ฯศfช�Wีว}ะ0S!๖ธ�ฤ{mภเ,จ“›็šะuPขูฯกvx„Œ้�โ D'๕�็Bพd่ทUึ ห`ษธีU—XS&๔ฉSิรSŒtฤ_ซ…‰PNcใRm7+4;2M}|sjคน๓ถBh ใอQe�c;7๙�์ซ#์โ>ฬY๒Mฒะซ|ฺ�G}TŠฟfpZUe๖›†ร€.~�ณA!๋ๅ˜dYxkซdฝ3Lˆ`šฑฌ฿&e‡f’๕'œฆ “วrห˜NtœJ[๓ทำิb?vQ�3ฌm็�&~ฺ[GgaCKุฟW6 ”(่yŸ\~.˜๋๗[�‹๗–ฮP8bญ๓y?C่u๔��ฆ�v๔o ๓ฐฯส ์๒8-)m9Iมv%Fz5ญั„ฬถม_!ฏฑั๒6มคภณ�็K‹๑mณvxˆ'่IbยขŒฆฎ๓0�fณ?%€†ั ่ำฺ�มูฃผฑyฬ& ฝoBj?ถ&’6gŸ๋อญLแ�N็ฮมO:งH“O‚R์๕Ol(ซ-?งง6dnE๊y2ษšำ|pE@ศฦ†…ฌฉAฆู็ ะ‘๖ะGV_๎ฃทณฑG๔<ป”ล฿่ง!ค์W†พฎํีF—๒G�ป€€3๔ �ฏ๛SL๒ษdิูณ'้ฑร˜�ƒุึkLค\:Žูr>3แ6gโ~L.ไ 2mˆl#ฦCสฬrะŸ{ซFฤSถฯ๒ Nภ๋สำร‡}๘?žiJŸ๎P’9ุƒm์ˆณe9ๆโึJz๖๙—า3/|�๛0•5tฒวeii๘!=ฺ&dศลฒ_ำไ8IจyJฑสQ‰ฌไ๑,›ทuฮ๘์2ถ{…r—ฌU˜@4๚=ไ์ฮฎโSฎ#”Hแฟ��ุ็าOัMฅฐMŽ๘~ฎ˜�ืOž‡APB|vศมว.�`๕ (K€„งฑKki`”�ฤ_�ศรฤไ$%–๖•ขฤ™ตะฏQืฤZเรุ�เศ๖�% &?๙_ฦO Ÿ”)LฤQ”jX๖ถฦิƒdˆ ๖ฑ:‰ร‹ฤY&U‘š่S%ปa~}ม�ํ?X๎ดำอพ"6Jฯ#™…๚ะพRŽˆ-่Œฎl@IDATไน์}ีึฺ๙iฯไี�ื=ยม๚ๅ๘ศh€_Ž{�wr—ิ“์���ฟป;20]‘WPx็~ฃใDWoss๋ทkŽี}x้…็฿=แยOAธ/ฌญฌฌ‘[‹MฤRJถ™L๋fŸf3�นต5ั }กภ(kDvหq�ค3้คkืศ oQ‹oงhQ\วลุ€(œ~~–ฒ)CฉZj 5็€ภษŒญ 8lZคr3๓.:฿F&-‡ึ�7D0C˜Vp>vธฯจรแ~6ฌซดI˜A›ฮธ=73๋ฅo้Rธ X๓‚ววเเ)๐5่\2zๅLQฐฑ„L’๕“"ฏึฆ‹ช‰p›ษ–'ขnอ่ง „ิIๅญaฐ"ซL ฑมแ“š ๗t„"V๑F`€ยT™ไชน‹๘7ษNึ‘ Nฅฃ{$HgeSมŒ†๕ws(แ>f>-ˆค\™ตPง jกรa€nคsขr๗อ0XcอทิsยEถ5\ฑฌษภ฿~6?ป๕๙็่œ พ�#ะร8๑o3๓fส”S…AEฆ”™‘ŒNโฌ"‡๊Ÿฬูณ๖r“‘ƒwาŸโX๓: %ฏqKศมžฒฦผu๔ ฐรผu~&^ซN"ณŽ๐=uยีึ&๚^ฯ1{ั}๊$๛B๙ัe๘ ๚,œŽเลn็�C=ศB6LŠ“qๆฝ.�๎฿พŸฆqโฅ๓oTs๖7pี_:ึM๚<๊ฯi่�ื฿…3•-ฒ‚ฎอNUžKoฝ๗ ำมภB:ี}ภฆภu0Žี€“Y‚cฝ†“๎ฦK™ึI7X4๔s_9ฒ‰๋ิ๚Vม ]V๛ฬมไูษ์๒_d~๙บม๕g้ฎฯ฿X:ฤzผ๑oใณWdq˜•ฝน2ฯ๋ั?€'vRทœษ3ฟ�สมQnl;…Ÿb,8พ &ํฃำ]sGŽ�R๗Xป�าัž.แ‹‘™jP3Ceูม.็ไˆ�X[�"`%+ƒณ˜รู �’ฎ ภถณฯำpฑ=Eํ+™๏‚m๑�y/ ๗)b„”ำAฅ?DG—Pn๐โศ0AXฉ�๎ฟ๖/“ั&๋ล�mrถ'ท้=แ๋คaoS�ๅ�zฬทฌI๕gัฤž๎ฑ๋'เZJฦต bณ7™Ež็bึณ›`|`pซฎV>[[�S/ฅฐ—žฝ–^zๆ๕์๔ไม#Si ฺo?ฮิY๖&c‹8ŸxึA'E—X F<„ธฐฉžถัF›}๕าs”€๊ึ�‘Qญไl\)sLP๋ย…็ฺ่] @�‘oคท~๘V๚�ๆ๔คฏ7ฆฯพa y๖>ึz†๒>uฺ‰nJ`xfหŠญk0gขEœํ�๏�ฮ฿OํMํŒป}ภ3๛e"rNต๚๎‡:‰ฝ ณภ้Kฺƒ ƒž-dศณ“kฌc๖VูW?443๕ƒ๛xๆ™3ั#B„~‰แ ฮอโNNะ�ฯ๑yGsGดๅย’eธ ๐YHฐu„ฮ@)hŽCvlฬ,ฯ-็\ ภ์๛้Aย5ฯ๋.๙8ูงOŸ&–ๅ3–}สnZ‡ึ๎Y*ง๙]  ์ณฯ>ห/ žb้ม„฿bเั“ž๔เแ“7ƒขอ�…�ภsิ!ณ2™<ฤ–˜ุญ=‡‹ 8อ๘ฤ š3๏ก�9จฏg’ย€Y�e๙๛l—ฌ›ZnS‚YศY6`W€ZTWKC:ซpุฑYัจฯnํNฑ ด๒ซ ๊ไปjฃŽ์ึv๘ํ™m•NพŽญฒWU6 ็Xr Œก$ษค฿ๆY5ƒkO•ฺฦnz์ิธ3z€ศม_ฯ ;฿›‘Wฟ๘<&` n*˜:uˆ�ขg •ฯ€�,ฏี7๓g~Sชเ๚0Il�ฆ>–�ฏแ๙d=ธŽ๊H ูS๙๘ทสื1Xณล๘…ฐ5ิy�๋0ฬๆVำ๔ะT้Pf—๗ี๎๋cfฃำ๔‰l`—‹๏ฦ๒SFbูฎภŒ�`Šั๕‹้>e~N๊8y�Bรn&ูƒ–๛ฑgท„ฯ4\ํF)žLญlmัo VชๅสšMId!ณฺB๋โตฑ>ตI™ฎNใ๐f�Mษ‚๓๙ฃ!)ฏๅ—&ไ>‡-F6 9&กžนp2ตภจ\`„บ@๏ม�e๔๒”น>฿๓^–O[Bจoa–\?P;Xฤ๕;™ŽีLๆ^uบธ%ฮ>cWํŸฅฟl�ั ``yMถ฿&š##C้8ky’>?่abŠ<ุ47H[‹ำศ(พ=A๓โ"“…Xg๕ml๓>eVห2‘อŠ๊z|ฮๅ๔เl5zT์แฏNSr2‹zฆŒ}vdแ ่(ำ>งŒš (�|›็=†สGGห Š1ศŒ 3ืฯ๒ฐIฮ�ภ�ƒ�˜ณ่Fจ[ฺย rช[๚ufด•2^]ฃXWึEฐWธI€ฏถtJY)ภ;Gถ-�ึo�=^O$b%ฯ“2๏8l69ํฑ~ศ}5` @ฑฬs'7ุIฦ5฿โ์=กฟb“๐�~ฏ˜ไรx๊œภUศ7ผ>๋�ณ้๚ W้ย๚ห๑๑๏=pเ6}ใต๕—๚็3 ไษล+ฟ๑�ฟ๗๛�๋๚�ห๏�ฮ๏��O๚๚—฿๙ร๊์ž์์��็X฿Œc_ฌ)’&ฃณž๙*m cฃQ@xT๘Qบ*€Œ3`ฬมŠ0Fภ`ั&D"ŸพYFตฅ‘ย- (d•ด4ฆNูง ๚ะ‰ฎ3ฦพเTฤD”†ตะๅdำ9๏(ukเldC6…/H`6d‘@ศlภ((เ๚‘„ ๅgง[้*šึHG†!ห€: ` †5๗>››�ส"Xx๔่q๚์ๆฝ404NƒJgS?…Zฮงตpวษฆ4ฉ6Cอe๙ `ใ๋ษH9“Y๊ฝตŠ@^4Mƒ…แˆ&้๔6žำรฮ†Ju๒ฬYึ hVa ใnmฝ#ณQ(:ิ๖0ะ่g”ค Jวdqv”€p …ข[s CฟŠbv�ถ”3๛QU…i๖�uโœ_J๓�๗>Noพy3�๕w�KทLขผ1dEuฉฐ ‡ต(C&J*กƒัูๅ�€BรแuoUช๋�ส�™s็QพซัXn—{jง>]ฺฃR 5ะR'’`สษ‰ฉ่~ฟˆโ>ฺb�xnภู`ึH๑ดถ� �ฦ4ŽX2‹b)‚AงฦK๖Tl3๙"ร๏6+๔็*d_็บ$IณTžmฉก)รit๏ "บแWY?NL’'+ศF?สนฮพTa)ๅkœ=4้ท‚‚>›`‡์ๅิบ๔.๊แ T�ัg›^�์c๖บHจŒ‹€%%€›dg7ยi&เิyCVŽ({’๒Mข8ฏนP+| Sว๚• Vbw๔ก^�ฆฃŽๆ’ล!’= Ÿ—]H}�“กิ�Hgcฎ316NฃwŸE@PวJc๐ฆsเง็� gV�ฤ‰ใ็y:รœ3{>่�ธธึ่?mŠฅlญ{Nผgรติxภว๗]�ทหฝ๎r~อฌ$M๊$ภฺฒห~™˜;wn�e]O๐œะk›๘[xŸ�ผE๚~๊วฐรฝ™K$‡ิ 9A|o๕˜๛ฌฃํGŒด7a€dY BNVr@k}๋„ณ๔๚ต—}5™฿sPหp–ฦ†ำ‡ท>I� ญiไQošAg๎ไบodW-�‰๗็�\W{˜ลTํต"eSyUซ?กิฮ%'ฌวaภYf?†Fำ๏พร+(Ml2sทฒฐ€ฺg.{- ื]]€นภ~XzฆฌK�ๅ d�้พฯš-ไ๗:W๛8Rf7|SAj{u˜Ÿ%0–Š|B]xxˆัŒศฆ๐๚ฯผ�ใฦนsอhKCnก„ๅ7พ๖5šต.ำc Ÿ๒„ฝtๆฑท ๗หๆ๒M ษ๔B่ฬ?rœk„�"ห €ฏ€ฎžItƒฬ*ๅFว\�y„๎๒>ีY๊vณนSุˆ‚f๗$ฦุขะD์' ึฟน‘z›‘ษŸห1:h}  …ภ`Gt˜�หbฟ๎ฬR[๚ขcoj๙L๋๑ึศ 2�ฅฏw˜ฅ—�„ž]˜#เŠ ึ`@{่๒ฌ„Sํ=#๓ๅ๖ไQ)็‚๔�๋โ์ี๓/2…ไล(G๒>๏�—]ะบ;:qZiโหฺิUึฅgฯ^`ฏMท?บวนศ๔"z�๕_‹ต{r๗nœป <:ง๊ผกมข_็–8@ฺธฯำ'Oัฐฒ1}๓฿d๚ #NฉŸ6ำีซ/ฆ/ฝ�Jz�เ1็ ›๛5Xp• พฤงป๗๊๙ีฦ ฌ�sมพ&ส�…๕ษฮŸNฯœ= €fใั๔�ldฦmy��=ฮีlบ๚โ•๔์นณัTq™ภ�หึ�ฝ�ว@�sฎ์ธ›@๐ž,�i๏l็^ะœkพ3%0|๖I2‡ซบœวืค._ฤึžLํF/^นๅ–e0ด‚0๎Ÿz�ฦŠน€bลฐผb&ะตE์EsS ใxOŽg–ณฤzุlRYฐ\TฬEฐุ–ผฒหœŠbBฆ  7ภg�G;พงŸยน7ฐ*Qgค �‚๊พ=๖`อ้Fณฅ๘ฒ�ๆ้น2 ธŽxsv๗ƒ‘csQ”2๙,ss"ะ,ํ,(ฌ29bG|ม[๕P5ฝ}Zฺ่mฤตื`:lฦฎ-a€๖ŽกSาciว> €์ET2็ฐ}ดผJ…@eฮ&๋๋๛…ํฤ฿+ฤJญ.m์Jอ')ฑซ †ฎน\ภœ=V‡io, ๖#๖k“+�4@]'จTŽ=๗๚s,%�“1 =Q€ลเ8๚0๐/Ÿษ ฑ๙#/E6}5e …$ุ`๘..เฤฃ‡b‚:@฿ัืF฿1�ว2b5›znอ {ฆ_„ ๔ยๅซ)—oƒ=YŸงงAOฝwฆ .็ญฏ„pz‚c‹)�Al=,ฐื™ิเฯ ๆy๚2�ฯ:FฝวRจM๙F=ข~๔็&}ฝTw?ข;?{จปล=NsŽz†ธ'2ิ่ํ žลภา?vฯใฝะ7Yฌฒนอ๓ํก/ฐ2ผ�XV‚@B5ฅฯ=s>…๚A66ˆv๊�ฎพง |"tุ:lง˜Lธฎoถ€_97:‘ฮŸ8หไ#Xœ•โใํ€LโšLE0@๊Nกห๊[ำ2ฃ๕kหซ๊#กฑ†ดณPพŽแ�VษRฯ,ีคŠ๚6ฆ_,ะร{ฬ๙0ษjฯต่oล�ฉ๘,•ถฤงฝLVภณฮฅŽJฝฺคะƒ์‘ฌ)ew“ฝสิ]ƒaฐ ฯฉ‰'žA/๊~ๅ@๙ae| ๘๖ิ@*รO,P:ซe`ซ๋๏cS็H0,ญขฯ-0b๚Lช"9ธ‹ฦศ>ณyLUธ‚R^3ไ—�WวYช`i๊7@{npS�y@ม*ฬๅ ตwt,Ÿ8}ๆ��ใ?�ฦ/ p 7๙ซVเ�ตk‹_?:๚ึ%ิ๚�๚๘oฆ๛๚�>ผs๛3ะGs6�RDooOถŠT–š#)2ร™ฯ4ฒม•Ž‚+pเง๏ 4_3ำcs(ฒ �gฦัภท%งใi‡k๋๓ ภzีฉŠH๊ฝ็ๆ:Q้�mvDEงมd\žฦะ์’N‚tbณิฅลq(คถ?uŽœช\’M EฦŠ๓„๒มq่ญ๋หCfU๗gฐgูŒU6สXไ�๐‚qฒIš”A ก„}‡ฬี(๎คDณฌฉพขZ:ใ$Ygpใฅt็ฅ๖๖๖0ฺาPgfง่๐KM�0ชD็'จt=ถนว’๒c ไd4))ษลA98คaQ๗นTึzzvŒั“;M aLTฮ"๏ั™…ณฉัยI6;ฌ๚W|ผฎ‘,Kม`ื๚1ืMb‰บฦ๊แœงฝลl๗C่ม๋€Mƒ“wq@ุฟอฃ๔ƒ๏ฟK•,zI}สซ ;€ว]\Kcซ d$Z๙ดภ‘Rd'Šกฝ–”I๙(ศ-ศNว06๕0 jŽjS๗ฃ"^–�˜อbOfจDฎY=œ่sฌ“ Vเษ:�r๙B๗ดณ}cscิฎŽŽ.Rgฺ{Ooodจ,K0ะะก(!0ึ๑S€"ึฃ่บxสพ`ŽŸnฟฯDถ~š๗*‰ฆฒๆh์ๅkฬ๋pู�V‘"้๕=K~z^<q^x฿W†gPC&d`t8ุI#•Žฅ�ไ๚‡ั๏•—ฺ�p๊ฟ�ฆHึฎชถ6ุ+–ไเfDฆงำZ8-๔ผ”ž๔๖ฅZ^ ฏอq๒ถูฦห ู5ดX_[ #ีณLVEMQ๊';l6งฦ๒ฌโR^ ๛[]ฟIด”>xใ๛้ฦO฿‚vJฆฦ็ทฯˆ ญY$uฐŒˆQX—อญ๙p�ฒawYJฒD๖Cชพ๋ซ�T1(0#ฆxh 0?ษ p…€b1B_ๅs/นต6อฝญคสฦ6๖ใ02 s๓d)ำุใฺ<6nJƒ๖,kสพ5ฺฐภ ]าีW<๛์ุ42ณ€ฅfึA}8†{่ย…ฝ่๊>Iญ�`�ํ5'…�›๒/9ฃ'โ Oงษก‘ญšำบ‹MรŸะตˆg>คfU�๒�ฌ$fr—เ˜ม’*ไY–ั{2ึqพbยืทo์6ฃเMจ�ถาผ๗xพg๖'�m๗ie‘คf๚ฮ‘h๊wAt7๗$ำ‡/d฿[า๓ฯ<—ณว–ขผp้rบ๗ไ!:šฐณœ1๔ฏgn•Fฐ6O,ฃ|ฤFฤy่(มฎ+ˆ๎๕ตอ���—‰ฐ}XเB}โไืป0`zr6}v�f:u๖ ฬ–สิ7�›^๛ยk8พฒม๖)g๘1 ๐|ฌQeห4G[œY Sส๋๏FN‚`<๑Œซ?๏Sb๐xˆLXm๏ฃฯŸ‚€Ÿ�ธ™n�ธ๘a—๒„’+ส;��แ๏|-ญ~m!}YvzษŽภ๕Mค๋ิ๚0๊;ƒl?แ,ห€[ค�ล^GMd>Zำภฮอ›๗ก0ำพํ8ฬŒI€ไ~tjy”๗ุฅ๛DG”=uภด*dฟ๙ฏ�œา‹tผฌฟƒ•Lญ๋ๆ๛›PqM9Jั๕\๐K@!ภ.ส�|�kฏฟ�ก‰#bYฬR๚๘๚้ฬ้ำ้XsKS8๚ฺ…ž�ผgฟŽ 5j“fl”ฆ~ฐมช>€มพ ๎dํุ๖` "/?›่^‚ฐ์z&์:๓๏z๚Œุเyll"uttฆ]ฮ๏ะM ‰น๋h,šŸล9BNs‘ล<๖ฬ๕C4็uฎ‡�W-)@F_้F๎2,ฌ-ง‰กำฃ[๗๐9ฬบำ+ฉฑ)<� ƒ"]TŒชFว;6UVœv๖H_M›ค�เœ"ช˜7Wฒ�”#F‰)บำ^Q#�หฌ-Tplu๏เcjฤห ข๐#๏{”ƒ--n :yK†Ÿ>ฦ6เš“7 ํ ŠB!™ฺภฝี้”ƒ ๎ฌ8"t-@fมํƒ™T๏I\[รณฮ2ŽผGมRž�ภ{Xญ]สฬŽฐ๋๊๑๎ื๓l)ํ2`ี<@`�ษช"๕"‰6@›๊zJIน์ �2lre`�๚–ลiท๒ัฉ๊hˆb์ฉฒ Wž๓�ฃพ4=7—Žwณฯ่•|�ฆฆฦฮTŒฟห๙D<ัMญ<ใภoงพton:<ฅจธ๚ 2j+๙oฝ…๛…ž`ฯฑ>w๖ษ๓ค ข่�s–ฟWๆ•?eฬž ;ผ–ŠภัFœ‡ผ~ะl‹ฤส.51๛ุŸ\จ๔;\;.~ฟอx6uย:พš๖;z:ฐ๖ต๘ื|‰หfะวoผ๑@ๅ€‚ฒmข)ฃ๓€ภ�ฒgY`๓ณฐ(ถ็R฿เX๊๊`�๑ห—ุณึ ;<6•ฺš8;Œ&ฟw=จ๖�ุŸใ$c๊:ฐa?O๖ก#r‹VSYM}Zฺšมฦmz0ฉo(๕๓,ŒฏสJcฝƒ”ะ์—…หล๗Œ๋pฤz)Kมแš‚๒z๒ป““mอ0ถ`Mc“ R๗9zมภบs๛ภ?rง้ภw.ะ^4ฎเฟYi๘n+๘ฃฤ1ึyจPฮeVใณ�3.it#็ํฃ6>๐I|ื)}xr์Y gฝญต Fis4_ํ4Iฅœรb ›xn"›๖ S'ุดฒฤขฯ–a�เoฑ�ž1�ค่ƒ…ฬb๕� leฝี�}eสณ๓ห๒ม๒�๊ใ้ �์�c c��๎โีฟ�›๏�มO฿yฏ� �1V6PT(่j™สBาฏแ\ฃTulkpธU ށŒ฿๋ะ˜ํ‘ฒUL์8ƒTณะŽr*!ฉ`t ˜8”KKคnf|–Jสข6ๅuH๒šู)tธH๋�ย\ฬ*=uฆ9Z2ำ๗๗>ผG ( ๗ซแ2ƒkF@ด�๗1cฑF'p†=จq{Gฬ�&่ฉojJU3fๅj ๛iLd่ฐ๊Œ|`€pสฬ่Z฿jVู†o…ิ{Jื”Zž ศ!cศฟ7{ๅ4…žฝซtบฃ’&‡ป๔นจb}ฬฎ/้tู%x™:๛�Œ.“X>ง‘ฺ{oฟิHRd˜Ž ื๎s lฆ#ก�ะpนž:'Oe/ึเ@*jฆqจฟ—ฝิฃฦvRฒต”สŒ—kๅต�uืฐWมŽฐt@ลฬธฟ“ฅ"ฒฏ!4ฐ ช:๋ล๓?ึณฎsงณดq…L๑น๓gSgw7{Oู ฮฝูฏUw~๘“t๗#ฆGT7F6n Dง—(}ษu$๑ƒทg�exe@Y–$ž]pK] —ฃฦณ�OFQF•b>ปw7zณ�}x็’๛ฝ�่>•™ด#)‡๛.A X ๛จ็็Y#ะโฬDษฮถ A�Vถืฆhพ_�Pทิ�Z฿่๚ู๙)'x!“ยYึG€สb%๒๊Z๎)฿… RI™5ฒ=ห8C[็:ฐ(^ฮ,ฅiqmtฒ๒' Q^Sดูฐจ…f�rqFpฑ‰,ฯNโ<ยž9už,.อ0?� gะ�๕9,ณ!3Eฒu็๘—็รฝ�ีว�ฯ }�ู๋ซงๅ7พ�g�ๆ฿�EใEๅhอก†Wมg%ฆึ้xˆ|zE๓mx่๋twn๏[ธ�e%’"E…’-  'J„ q,@@`8NBJRm J‚DAค8J,(PbD‚LK‚-—�—ป{wo;ฝ๗�{>Ÿ๓๎6`�J�-‡wๆ7ฟy฿็}ส)฿๓=็ฤ�z๘ืˆlะฎgมncciwๅm‚žห>๏:#ฅ(ซbwtv๑๗ว�•~lคร๋)ฮฃสV#Hc[sฦ› ŠšG๊—…R.ดถฤ|พ๖g’ฝ�Kq๊ฟุห๚ฎa$�Mยd f…€ช lDA2ฃฯ\D‘tŸ_„> fฦm] ญี=จฦ[Dpฆวาศจฌ>‚ๆผGdตœชาmVไิ7ถ“๗[OŽ7่ธ ฉฃๆฏ•ฒฎ:ีRHu†t4ฐŽอŒ_วพทฟ๚็e๖‰)"ะKQ”ƒเFป;z˜ร*!Šฑค˜�็�w฿ƒึผ๙^าzmef/{k›วฏB๖kJR=3งตŽ[Hซ7jŠ๓กฦูะธ๑{YŽอน—š็�ฅv๎��ˆ‰ฦŽgmGฮ=k%wำ!<_‡:๙\K็ภBvfำผN��๓$hๆฝdไhะyJp�54dU˜ฆ2ัhฃ�e๊ยศ์้๎รq:€ั2Fp3@†œ0ŽูฟถตU™๓ฏC‰‘�> 5S‹คbttwwGฏy/๗ฐ๓(๘•‹B๖†•eคีฐฮถp3�โb$ูaเHณฏŸ{FcJyt�๒�๓ŸOˆผ๙ ็ƒฯ๚ฒPŸ”Yฃ—Fตุ|กฬ8%ฑ็มTB �d—Lฐป†บ–Ÿ๛ 3็W�๓ฬ�TPจgH9!cฉ (75[^‹๓o*Œ๛a“(ำ[�๏ซiโู็™ภ฿Ho6—ฺ๛ y�=าx�Œ*พ—าn”฿�\ม™RR”�+๎ๅL9{ฯผฤ]žั]ี€สฒp€s‘O๋ศน3ึ๑€ตŸรpjฬไDศc[ูrO๖ั.ภFฑ):cE็ชๆ๏ฏ�ท‡”ศrึิ: ฑฏ9ำาOx1š ะ8˜"Dฯ„�ƒiฒศซงฬ7š.ื*๖๋€:‰Lt8ผสฯข๕Mค๛บGท‰๒๛ทGT๖฿ึpๅ๚Vหถ๕™…tษ?=@ืXถฅอฃู้ใ'ฬ๑)‘;ภ@่ไณ�vหzฮ่X1๒ณ0ไธิ๓Œf;Isา็ๆๆ0ิLR@Vcdžb่น^ฆ`�y ซ“ซk๖ัM&mx�˜rฦ รC๕€ต`ำษP๎๓คœQŒpž]ิฮ9๕u„.ะุ6ฺๆKCžCกฐฅ1ขแี์ต €ac““้๑เำ๔7พ๑ณ€ธ30ตORWKฉ3ณ<+ิ�= _r?๕‰gD`๖T๓_ๅp๖bOฑื-่ดevฮ6s‰‚d_ั๚Œต นxฉ—ถe่˜GOqพัqณ-๑ •†ฌฒศ~แw_ธN๊$cŒ๓†์‘:ฌใ๋พr�j3>ม7ูW2 2y'่ฏฬ๓ะg Z๎ล๙`.งgfHอฃ%{าš%ึ๋๑:ฎฏ:ฬ๋ไ Šะฆ๗YเRึ•€ุˆ”yฆคธ ๔‘ฦ๛ƒ(d Qm=์:t†vŽ bt‡`ยณงƒมxะx�Do–ฒ~•8ฆใฺ๊3ู€ ƒ1มXฤP&j่8e ึ+๘ึ_�˜~ห้ัะCขŠ]ฉŠ้/}๊31–cขิV|oขOMm}ศo:ู#:Syุ<สeP {@a7ƒfjษดาšฏ”Tนh=Kd[YQW[ว�ฑmฉก๚——ภ0ย�™<cฝฌ=ฒ‹aง™ฮำ๕((ลฐฤ>ื’ํฌJ�ณ,G”๙tบ‡tๆฑXcƒA•€ลุ"ฅ8-นุ.;่}้็ถ…ถฐฺะใแ๔ฮ๗฿Kร�;�t8=คึหะ๊hT[ฯFP่้ำg้{o|bฏะmTน,บ ซซ*uu๕†มุไฝฑ’Xหข�[8ศ[Rฑฑฏิศ!ๅu)ตr ํ?.:ฅผ๑y‘ขฤหิ๓"๛ฬํ.๏๋จ/ิซแP#ืdๆ๘wฺ•+0ซื`ผญสveR'ฌฝ[ค_m ทฝO%๕2ทl` “๖ตBibf็V๓uK๙m๋ผsจ›ยหถล†ฺฦv5mภ9ิžr7ioภ†ํฤดqฐŸ{L;=Pd๖ฏ{ุด›�‹€Mn๕๘Œืะ.^!่ฐภ^Ž_,~ฏฯbบถ๛ฬฝ(ุh]Œ=๖‰พ๒A]เ๛ำ ฆ~V`ŒคFlแ–– ฉžภ†บม ›๋!a๗ซฮญ๖i.ฎฏฌX)ฺ๋ฝ๘็๖X)๒Tฦฏถ~^๛\๙ว}ฐ๐RWw๏?๛…_�๗�ื๏|็;็JวC๒�๛ำ๑ฃื_4฿�'ฟU๙xx่ฟ๚ฯ�ฟธ5<6K๛˜fŒ ๓ีู:ขˆBณYฯ# ".[๗น;D ˆส๊ไ๛+‘อsเแA๋”"&UL…hžนt1ัา„RF`ฮX#่g3ี@/_บ”zŒ๑‰9h„T€็pˆพส€XลpศGฉฺฯV!uฮ&ฐE‹J$-ะp„aw†‚ะ‘๔0ษ2h„A ‚t|F�Vชlฌš{†3]‹าkฆศฯ(ๆ‡Gป$ ฮลฅ๙(๎ดB$จ J\w ฝฒ�[SG[kz2๘$šHณhฃฌ‚ฦ††่ื:;ฟBEm+*Xภœ‰F0†Bk.–>฿ณจห ๓%Hงฺ๙๔yŽJl๎buญ๓7*‘|๊D˜งœ‹ภำXฯe^ท่๑ฌป†8C1ชัษ) I> ƒ่b฿ล0วง0๊˜†ฉBAฅ‚;ฦ5ทั่“ชŽ‚`‰ฤงTว6 7�ƒฅ>Œ^‰JYD—GRqMขค3”��™ฦ1ื—๊Wใo~๐Žี รR›QI้ํืพŸ�}�Qฺ‚พ�€ใ�ส�X๚๚฿๘Vz๑‹Ÿaธะ4qถ‰V,,/ฆ}ะM Q)ใฤ :รตoจปนœฮ]8wฌนถx=(�=€s๋rœเ๖ึพG๑ฒฏ.’๗&-�9Q่>#๚iŸศxCํ…จฐฦพ.€ฑ`ๅm#yบ‹ๆuNNzbฬ\ตทwพืD>�ไิ(็C 1๚ส๒"3jซF�q d!x6โ|(ล™L๋,ุ N#@ @zด54p-ึ8>n็% บr๖ Œˆ“9–R๊อ…ี๘ถฏฏ ฺ๘ุ8ซq>�ŸนŠe…k S�ล$kฦš-�้า•+์�ฆ๔่�haHั;} ;Yผษhb>sภt๐คs-�g•9 dœy�อY\บL5ๅึ่นฬํT๋Œ็๎๎‹ฉž�@ƒ‡?ฆV…E!I#jํฤ #jปษ™ไw**‹F$‚5t ˆ๘ๅ+{ค๓›'้&ำ๑๐|๋ ษ”Pนjไ5“Ipภ\สฎ`ZcNอ5ท่ฉ/ #\ใLว†=ห—c4kŒ๘{ eaЇ์ฅ;wn‡�“z{ฺาO~ํ+์นผิำีtย>x7hŒิmศ=#bล็—0๐tถ=k 1วe x๎u •‚!าn•a๚s<'rึ�VL็ภ1แ`๊ศฒ›F ๋kaฬ D—วจย�่iบ�๖ป!Jุ^L#5aอ๖Flฦ–N€ŠŽWฦ:PV›ฎMcต pฮฝธ) ๘“๋ภูไ#Fห4ISะ0๕‘ร8�ฌCฮš๓Rฆฬhฐ€ิโฦ ใ/QฮแŒฺ‚Ka่9—วWขgl•›ฦ?€ฒ@9k ศc.๋ซ$ชnj šgš#๘ˆr๓ๆ.ซ‘+Fš>~๘(jk|๐�‡ijt’ขˆƒ0มฦ�ภฬฏ‘x"qa<(/็฿๓’ํFํ†B0J—ถส๙๗5ชฤqฏ ƒ6Ÿkญ…ฬแo�ท}ง�WWi๎"ฆฆงขจ๊ไุ�[fอ0 Oรโcm-ฤปฑ‚‡ํtจฬaั๊๎ˆs€ไŽ=ฅcd4ิv‘ตีYkŠุษ T+๖y.r�๗ี:ืl0พgร๓๗�ฯŽ�<เs๎ี"OA๗๘”ฮถ๒I@5‹ช šr ๖Ÿ๋ฆใชฎ ูษูผ;a?‹†{uึU^XทษฤœZR7Iš�ฬNม‹๑•ศ*ภ1gห!—‘ฉ|ึ๏็ME50%ˆaัฮBไ๛ฺŽBฺ�ฎ…ใ›ƒ}ฒJ]ํšlฯTP ๔r๊ขšพ2vuƒ@ y๙k€Pป|~รk๑ .w_ุ9ร๎*ภ~€‚~๊O;๋.T0ึาตC€} ฺขน'€3L[๊๎o‚ลYลž;ˆด’›ืaฦ๘˜�Z…�^‰รY‹�_ ธ\[mมr$<ทg|ศg๔€„cื17 ษw.{ž๏k๕‰kษž๔7ส ว๎�oญ๙<ฺฺุ๘ุั…<ฯถš๕‰z๏^�์Qำ %์ภบๅผ๙�%ๅิ๕จ้d'€†์hุFฏ”QŒx†”„า––#ึˆเณCWqbW๑��ญตGAส-dใ’ึฐงป ฮ3฿พs›š$อ่�ิู�Ezญมั�็ADำŒ๔ vฉู ฃXฦ‰-ิWส@SIŸ า๊D &วฝkหlำ N)ce๓U0ื]ํฌWE3)V ณฦ=h;ฮ3tพ๛จ‘€˜�พ๎n๖ัaิจ8ล—*Vฮฐoฮ๗ธv™ผฬู=ฮuศ ไ†lijzญ๗๕๕�งท๎ฝ๘4ฅ๏ฐ*?๗ูW8€EQYurr 6๔Fฃ”ฅSๆy‰!A~ B C๛ ‰าเ�*#ฒ 9วชัฅ"}l…hก e!”ƒ๐l a‹ข ๊C๐จผŸ Ž พaA*ภรใ^จ3BNRโ๗ ๅr้อDน^J•7’fd[#H#ขCษœถ@k R•`่แ ”•IAฆถNŒืขd% �ึ dg;0๊ฉณตmŽ4-2&Kas๛Œ ฮ‘ˆU*ก[4๎แ๛รฉPฆฑAJ+ฉ�+}ฉญ‹jท\kzb„่ฤŒ๒๙9ใม6oF•5าะD่ฎ€AaBz•gVัธ> \ข…ยsiษ ๐\of*๖k{อyr�eฐŒ“ ๏Œ‚F1cwO[ŒKร�}hM'U้(;)“~N#Yblt8 (#ใ�(} ฅ้€Tม–ัQ<ิs-UฎๆZš>ใ~–eขั Xฐฦพบ@Žผ•๙= ๚38ˆB…v @๕ฮฏ‘7>Dิ‹(ฒ@dŠ}ไ฿รมะ€Sน!ิ๓<๗uwa”fฒภ&อฌ!.m์o ™žคร€ๅฦซgห(iใ+ๅ๏ทq`งF&p~kธ—ฮ$N็]Gึ๙า˜ฮœm>fเ'ร๘3ฒš9ใ๑&ฟยฟไ์ล ณท๘ผ๓๒€ ใ฿;๏1G(A[J†C ุๅz๙ึเ‹œAฏยคพ Fš๊ดMTrumPk-๕๖^คฏ}เQ{ะR'p๊Fžฒฎฆa‘ยฒตฦOVu�8๔–๒‰-มฮ ^ึ—๛b]rŸlฯŸหq:ฯฃ_ฮƒ†้๙๙๐=_Žั—Fณrฬsโyฉ BฆS์ฝฌƒโ็�ม/„2ž๙ไณสXu—ตHS0ฒตต…ฝฯ�๖พุ2ล~”M ƒ g|‹๚ฅิ—๊,[ู๎!็ตœq‹z~ต™t๘ี้2+9nแ|]ๆlฺV๗มˆ•Uk่P`z’=ม_๓ฌง[ 3:9ย�@ะ‘E๗๓ูe�Wพ#ƒ1*C ‚Dฉ๓™Jt$:‚sค๎‘M915MAaršฑ I์u>ฯพง๙ไ�ก5W์œa@š๒็~�$ภe ๏ฯ+๗๗์fซ€ฤdžN|vมh™AึฃฐK–ฉ}�ฉณซ›�้V:5LทรLจE7ดค๖Šlฒn๊ญJ@UYU่เ ํ ฎ5๛l(c[ํc{,M/ค�` ฅมค[,jมRุุ่#UแŒ๑ž ฿ดŸ๒๒˜XBึ–rlฏmJค๖ยภดฯ็�WfFpuึ)u/บWA.+หRqญทR‚�o้พภ๕™๘{ฯขแฐฮSc™T�รๆไ๗žEuฑ€‹ฯ—k:ฃIf’)ฏงt„ZภZ'—ผ„€†-/ญแ%Pคผbืs+พ8ซ�8๗าวv๔ฒฃŒgLv€NŸ@พจฯกŒ๊ํ้ฌ%ฦูม~ิ^�@N"CF')0ฝ�ษvm YOอ6ฃ่ฆ†ฉs8oต๗ฬIณ๗}ฏ_Eฐฯ�๎UVฯกฒ{xเ๒@0Wd๏เ™ถิณnZƒ}O`ฺ”“ฟo๛ภ lm๕š  €L0ฯˆ๛อN ,<๎žG=๑ฬส7#๊�”yท#Wt�แo<ฎ€ ‡฿ธžึxB๒ฃ[pธท(ˆ-Y2lj€ญง๗)  ดšš€๋•Uิkhภฮoc฿๐ญฅ๙™eาฆ(เฝŸฑkหูฏฺฎฟ๒W฿ดjู{ป่›.ž๛ๅ—^$%’4'ฬ๚๙์๗r:ถตZ�š๓o`J_KVณ6ณเ฿~@ฎไ1•-žQํ}ฯฑ>2MŸBล5p?—Xร�ภณ –€ฒํง๛]ฑˆ-&ƒij~*-ฎ.@Sยz–ๆ’qอึ�b้๕ี0F™yOสb๕ขฒGpร97Uหบaht~ข��]4�Cัฅ€๗�๕o�ํฟ๛฿|็; ๚?dฏม‚ญT�ืฟ๚k็�฿๛๊ถ๙yRS@๑ฮ"x"Ynด›”hผ•2Eล?KJq|AหL8Q7ฺฅกใ&3โดLม+็[}_ž Œ„rPTFธzs;…ฝ88F�ฅบ้่X}wวจฝญ#}p�ร ฏEๆ\เlnฑ๙ฯ ๖4Fฅ‹ฒmโl/เˆš7Y†๑๋!%4 น™ห฿๋x๐lUจ่ฐc๗ฦaร—๑ j( Oๅ๛ม_<(Ÿ@IDAT�0D7ˆts€๋k=pt–ษ54สc ฉ™™‡�,_ำb˜g ม‡Pร BnB{ข‚‡R๗�๎*‰m—ค็g,Š\(>;Rฤ0ACศ…!รaUแkฤs๘u„ฅ ขn์P˜ึHegNื™Y ง(˜b”ฃBด#ทCHยgฎ–nฒะX=„๔จŒจM๎Qน„๛KŒ>ฌฬสวยŽ•5(ย“ิ�Kมจ‹ฝทDTˆD6R ซvฦฤ่#f›๏ไ๏๓lๆ G!G�•มPI^dT=&ฺVLแ$ลท>�๐~z๓5*›ฟ~Ÿยc9ดธH7ž#ฒีำŽฒฏรYวจ…สง’ฒ%Sฝt� )šrdT�ฮนKืt*)้�:!y ฌ uœy?}L�ทย4า4๘njj*r(Uภ=Dม5ผŒยผ๗ฺiƒศ‡]% ูฟ%TeะN+‰Rq4Ro_w๊๊้ edœ๊ ฦฆ‡ƒ=8๔$XFlิัั•๚z๚ธ#†๕š4I:†ŸŽ„ก๔ต่หƒhˆ่,hXซtฤฅ�๗แ0lbฤอNM„rdณv…Šม}โ๕šX‡(xจgVฒข<žY๋y์sG‡f›๏mฝhไ2 ะ;oฟ|5H๛Lท_�~ดAkฌฅ}&Ÿำฑ>๒๊M2vBsheใ˜&แ~TQ|๕K_"๏บ @9u๎่hใ<เ\!ฤฉ#‚lhPโw�wqJaRฌH‡งฟ5ิ็c ›M"๊Fฏpฃรh๑ฆh ม ฒ๔dgัe”ฦปQh_ž!๏0 sษaŠˆฐ†g�]ฏฉ$œ ฤฟcฮ\z/ฃสสฯ›ืt=๊a+พ4โคMhAอššฒ๔ตฏ5}๊ำŸ็ƒHๅAN฿�ฯพ๛�0<๓ก,.0ฯ�:ก^GฃฺVy็”rศ๏}้�œฟ|ฯ๑๙L~ฦบ@๊ฒ,๓kWำO|้‹้�ไปid่2ค2=w๋vค-|๘ฦ›iVLน ’ฯ…ถ�ศ!ฦำฏ‘C™ฮ…นพ~iYา๛๘ฌQฐ๙ฐcJ”ร’n.Žญบ)#x็ไy“jฤ�๚ฏ^วกhg?Y$5m฿ณห�3F_ส.;:™F8ขบ4ภ๑ฉCฆ˜ร๊๕m๋ฦ>็ฬ=)xi‹*๊]๊กจ�K(ํอ ZญFงดเ rq๋9‚i[ศw๗y=M†ช ™\VXSฮA‘ฒ‹Wƒศžgcy‘ฟ5ชฑKิ :GTื(5ข๋Cฤš๒ท๎OeบipN–๕"‚กภDi๘ๆ*ซ์su#ืฯ)ก;่ซm•<ฮ{4๔‡OŸค้นyข฿PF •Zฃ�หE*ญเ๏Ž�—sF๓'gร๗ยtุซ็ลU�๗‚Q:ฅFท,ศj๎๚!๔ๅ}jˆ8๕<�ศเำ431™พ๚•ฏ‡ร524ฬป\Oชฒ)n†(=?™:ๅฆ ธง–eฦฟ�๋ฮ“ฏะฯฌว๙™8�ู฿๛ๅ๙๕,๚}ๆะHa`g็฿ ง�๔ei >ณ็�Œ9สว)๐บE๋…ป7ฎ_MOh๏๛ึ�ท˜ Ba{:<QฺŠ2/‹มิNรT,eDJ๒a๗ƒ๙pm๗ธ…แp~ะฯฆ‹yV}ฎ๎žNาgšˆภ�nํc|‘ 6‘ๅไแเƒNธlŠ�7สุ��‡^k งัk‘7ีS็SJGา}งณ.อุZ9:)V“ฯกŽ€,หy€™jIXœ ม็@0AR B5ึ€™r<็L‰SœSูต0|lsgพปิ๋ จํˆอะSฒ-�Cั:=ZDน}ฅ๓Z ;ย–ะ5kL้่๊8hม“*�L'ๆั‚Žธ๗�ฝิ S%งฉMDล‚šี์๕z€ืฎ€/ฆŠ๑›๚ขซr-?'ฦ็ฐฟV(ฐง�B>Aอaฏนvtดีทญ_MAา&ู่ตž’Lž(�ษ^ัฦ ฐ‡5Šศ\ksธ6†(๓ย&cŽ,าj๚Ÿ๓คŽuหฮŒH1๒ฯW5ฌŠb€๋$(]/ม8ๅ‚lญm‚nSำgž8 ณฬ–ภปz�c๊Ÿ24ถ/๏)—ยF`ภ๓๔˜5=5็�bฒs=๏๎'[|ฺึดfA๕2*ฑ…<ฯžิรœ˜ก~‚{ซ ป�ี0๘7�ัŽFึ ๙ฬv ๎m๋hkส๒9?ทฆ ษV’กฃ]rศ�—๋ฤY6ๅลน๋๎ ซฯ์จกมH๋ดvS๛cv‡’�สลห‘๚นDภล9 š=gฮศนuLI†dิyฒC–๓sฮ๒ม๓เณ2alyๆ|ะC6œ๛ีฮึ+# 4ฟธ๎+›J๙]O มlูต;ซsฌฯcžฃFภ%ไ�Iz๋๛oงษ๑EึŠTžm:�2l�ญMR<;ฦs๎ถึI`v�ˆม0QQษ™รฦ6บๆf็ข€=ุ๊<›ึ า�ไ>�I �› หฝอ๎)ิVฌ“,�0(ส]™}ฮ‹ฤฯYpD–rMู!ภd ศฝ&lฒ:าtฏ \`/„-๖ Ÿe%-ฒGlว-#ถ฿M})๛ุN ฌJฌ‘์=&ล่_k.ๅp�บชสณ�พพmํ=฿นtํ๖จgโ‡ํฅํ๐ฃืฟb~๑o��อ��7�ป�rrfฉฌ AŸ‡๑o๒aZArˆRqื’๗โ๋มQŠโสC[VcxWฒ้UธU ‡j €ท hŽpDกuฃ,VpŒ’…•:งนฏPg3cZbฐJ&Y‚ฑ†ฑ-b3สDงsžศดีOงภˆ่‚าโ‚ญคS<‡’นs๗6ํzฺQJ5&Y^^น„‹าŠpŒr9ˆๆ29P�š“ำึึŽ–EฃT ขดŽCๅi1‘5?Q_�0I—“�z†"�ลน_ภPล- ทฐ%ใฉ๑Yขณ ๒๊ฒ.v๗)บCฒ@!สOชจ•nโRยเLe†ขสลธ6u๕_G†cฮ\rศ‘†*#}Gฮ=‘6ช*รlฐm8ƒ^ 0้(เอ๛ฺC๙๙๗ข*z?'ยญr๓ุWDu)ฬ‡bฑ&„ีˆัiAฯดj ™ฬ•Nต7-ย˜�…‰ EF&‡ ๒o4่g'วBธฑ ดHฃ๐9�e({{!‹>* ฅีืึQˆฒช€e™จ7t�๒ฦ4Gคเป๐gP@็0สJำๅ๋—าํ—nง็^น‹n&/š{hฉณ๖ฦ๊b\ทชU+†ฦ๊โkkฤ๕�‘๖xยCzเ‰X์ฬึTฺฐฮ‘4พ5๒ล,e฿j&uฃ59�Tm%บ๑๖;฿g](˜จSํ:ไb4ถถFตูhwP๊tvŽO†h๋ษ>[Cษ์ะฤจC4W�ฮŽ."LแศkDญ4ษ์ะจu�y้ื๑ึ๐ฬ„:H1ืsŽ�Ÿ็EุTหK‹il่iดสl$ํขฅ•6ก=ฝ€ฝDธ;bŸW ฌ]ksUB›์็m”fD\{3งNค…Eท?yส�r@ยBI-Jษe฿ตatไน"GgK็LVJ ์ dัuปŠุigY–‘รธ%ขpŒRั0ำะo@.์ื ่ 5แ�•�ะq ฦห1Q‘\ๆ��pูEdFลxœOพว˜ภไ ๘Œตต5\ท–Ug,�ว๓โ�:FN๘& c šˆ>ฒwซฬ&9? ใณK†Nฝฦ—F€๋ ใ๙ำ!PNฌ# Lฒƒƒ_'€„uช0|ŸO}�az๒๘1๙‘ป…Š ดฎ‹€งญ�Œจ;�,่๘ง_Žูgา๒9œ[ 7งŒrฮ�ฒ˜˜Ÿ๑ๅ>8Z@^MMMSœs.๕๔๖ค+—ˆn"็w�—ด81EW"bฐ �{Nฒ๊รื๓)hฤลัˆ๛๐ž…š��>์;ChธุAƒ�ฺว8Sฎ•ฯซ0>df์0o@|–5ย™ทฅXฯจqQ,ศŒAZ>จ8lงfฦte �๎�."ฑXWฟท ฆdY๗ก์Œ่ื๓1'P 08mc) ูT๏QŽฃง�2l�ฯŒาส~g�า3๓‰4–ฒMt$�‚ฑฆตYGDB๓!๋`ดดj?‘ ๖—y๊ํF๎.ด ๓VำŽŸ์ฃำ2I€t(กภ`ุงvฑ<‘ม aซ#ภDฅ"๑ศๅฒฯฅa'‹iซ†ฎ๋lวsbsŠp€Œข๒,J�eฏศf0ืVtฆ*ํฑg'ฆS=ยrๆ–ฌ็�„(ื>T}๕ž/ืํ�†)k๊หตณŽZฮ๕rฏน=?:<ฬd%ฯSม^ะˆ�เƒทาีหWา—์วc�ฎ๘‡ฎ]พTปฐ›๙]ถง5R?ƒ€ฟ�š๊`หKY^��||��œ๕เ๘�ใ๎Eฯvˆ?;~๖}ๅœ้UTฆA0๛˜eฟัMฏๅ฿๘lh๎ล| Kช  ๛�็๎ภ๊AFทEฝู\ศ�ร~้s๓ไ9Rฝ๙ๆ›้� K‰จ ๛ศ1ป�„r๎<8~มŸษโy;่oU‹GณSำืฑ?ฺว›Cๆฐf่m฿vOO_๊0h๘…mฅฌ2‚Œ3๖„฿ีๅMT^จ๐,+dlยด[ท� โ2บu ฐรบ8ษๆฬ ฬน?Œ:#๎็�1kŸน/•ƒ^_†—u๊ห[aHศœS/ ถ๑G|!C๘บt้้h}A๑”`ฑYืˆ๚SิถiๆyิS๛D�๘*‚ึ.ˆ`๛bsฒ7ฑึaฬาัข‡็ฟ๓โ�ิ?ะOMฃKฉปปšยœLx`w๖)บ่0เPฅŠฝeทงาฟ ?{:‘&ว)hGgํu'rฟฺ6ูุ]5ฺ‘ส/๗คพํ}`ฯB่ๆ ˜R์?ฃใฏ#*C*>ว๛2�ฌ1ฃ ค‚เุ†Lทƒƒr%าVX/๋ฏTtจ`_y-๗„)=`๙ฬwL)๑ฅำ“S�uด๖pฺๅฆฆX?ุศ eE)ฯ"[ c๋`�y#๋:ŠฺŸฒ +‘ ธึห0อXTฐ+ฮkบEjยG=ˆt9๏uฯeO%ถ[•ฮ<qƒ�ั"‘เR)2[;9ำGฺฉ์M๎inพŸa์+ฮฆมOyศp[๓š๚;>‡ˆอฃU+รUฦ� ถš•�/๕TSO†่ถ-&—๙œฮทs%X,[ํ�;lฯ�“�ซžิ)๖KปIภล}โgSฬ~ๆ3žEฮpะ–:K!cuจ‚ลต๗แiถห,�ฦk1วY?ขํ๘=ไq5B�ID|๏az็๕๑ฒ@์ไเฌ`๏87:ฮEœQฯŽv–L6ˆiูH{Cปb๛วถŒ‘6อYะš6ฅฯฮ2ฺฮ>ำณกก42B�r:@XืญŠตจTG์#›}6ํr}4ำทe)ทชั๓ม4เ๙26‘ Œ1์ม˜ ไ„Ygณฟฏ+�พuปฯโไ๚)๘rศฦS๊ˆT ฑ`ฎv�‰29ฐร9= hฝ2๋qž๗๗aถrL':รฮ+A_j‹!๓ึ๚/]�›฿๘k�ๆิ6เ๘^?�k๖mย“�ใo�๙ำ?�“_ศ/ฏขซ(!‡Yน_AิๆฃL‡ C16ูฐEีRE%Ž[‰ิX6ผ่r฿@ฦ6U€‰&ฎ๙ืqA€+ค5ซ�%8ฉ*นNZ˜/)Lƒผ�bJข/ุ[ ๆ‰I+2G�*็ฎš=Ÿ‡rวe9mjชวฅZ4ส` คoŽ๊๘ึ"x๎�sa(่ว ้`qํŸ๕>ีH๕€ฉ0Eใ5ถpฒ#ว3‹f˜h๘๐e5vัdn0หP<{^sV( ež4>� Nyx˜?ป*((ํ—KฯฃTDAด‚S้ ๊]๋/ศ�มนc| มrๆ๔<า้:|๘;…‹y๊๙|/rhnณนXR‚-ๆ สEคƒi๗ŸO&‚9hR7ส(ะ65คœ �mž฿q[9บฃxlt$ „P_ี{�ฎ’g9WA~อขˆ�(ข(ฒ �ปยz–ชŸ‡ณoซ–Jขkณฒ7Fงฆฃhูาโ ฮ๙‡้O�๔อดถฐž๚๛ำฝ—>•>�•ฯC…mล ะ˜5— ฺฦ…เศ ย�|ญ‹—ฎDูQภนร†.gA]๗ ฯkQŸ]œOํw ๙h„ื7ึ‡bกDP[k๓p’์$1ƒ<91บ H„ (s—�ดFx'IJ4„ผ;R๚.]L]��2์Š๛ิิา„๑ตทถA๕'75ชว!Rก •„ฑ!ฅฬฝๆa/,ฮ=Qฤ^ก๏�[”HƒXฅใKชZ)๗S๓™6กแ๋ 5Žž‚ฝพถ>�พ}7œ๚ŒชžQ{ฅ" ๆiดบงฯ ์5า4oe<~,pƒณgๅeAŒ‡Gaชœ*�Nฮƒดo2UDLข ๏[uฐA%ศ5็@gุ๑บ,zฆัต‡รฟธศYe๎d๎EpŽฌด\ร^hวh6 HP๐�ว J>ระ›L�}?2Ž# ษ๎'•๔ˆฝŠ Œ‘ฎคC ‚ ๊!?k83ฒ3T” ถum•-��ข‘สฒ0Œ๘ฌgโ�A๒{ฏy^P-Œ ฎžBต3็z6•ญŠweŠ?ปdฮc{{Qฑาt๛๎๔tl0=}๒0รOฦา {]9ฉ, ฑG9JZVkG;U–โโ8\t 2๏้sYภา—k้š๚<ะฑ3�† ็qD4›๙ทฦ…E�ฮ�U*Wฌ๚ฦœเMbเคq )�็ิYŒ}ฮŽ๛ŽหBฆ ฑ?kิ˜๚’ๅ่“oฯ๕"฿Šญ้l:žาtu ณ๗drt<•ื:ฮััยตBธŒZไ3ฆr๖๋�๘3้}๖n{KฃใBศด�หWq0๊RkWwPžoพ๐ัช (giเฦm�–ฯsvธ1@)]ศ&ำ.Œุ e ็€นโ�hpœco˜พ`๏๙2h˜2�+2พ�oฆ็ax๖สุงง€m�ฑgx<"Dํ8ฝ @วDVži;่2J(Kะภ54ชn1ดุฃ\_ ๆ�Lห6๐yญOฃรYˆมXŒั๎๚๏A ว F‚=ิถฉ˜s”๙œฑkืnP�ช1=x๏ ^nฃ#™sŒb>‡๚l;Ce‹ืtฟ๋<๘๒฿l‚P\šฟs ža?๋ดกv?ๆ๐๓ฑ),fภกฮ�(PtˆฅQ7“,%{™9‹>4สทzT๏#"‡ฌ™€™๓ฮำ„,๒/Žลq:ฦsy่ฯ:ฝพ�๙˜Ÿ฿+wwะทใZ‚ ู๙V฿ลุ๙œŸw�#mฝaมแj โ ิQjmo‡๕6็ะ.9FเL#j&�ขก–2ต E?…ะ๊ซ๋8๓Ado(;ีซ ห+ุ ฬNR9gช–ฯซeUpฮ•uซะK€๒๋ปkฑ&ทn�Š“oพ๓zบ2p5}�s_8 ๕บท�vู:P�>ป็฿ขwฒUr ฌ8๏๖๎USภิ_หห้ัฃมะ��*"ˆญ-m!vpjญแะฺาฉ~ส์*ฎี@`G-ภiฝ›LฟK9ว)Gฮœ �ง:ŸQ�ฐ�”Nํ“=@W๋จ8ว8pS�ถฦฟK�ŸC€/ปขšทดšฦWƒƒd0!KQ~,Lฑ๎ิ!็7ึXr{f 5vEwWo<•๙ดŒรYฬ˜)K™‹2œฮ’2l ฮู{ < "?ญฬค…ู X1#iŠ๕ีž*.ฎ �&ค`๒(ฐ�ุรžนŒฝแs๚ณu~<ฟže็FYฉ�๓”'๎ำjๆอBส๊u‡ป;cdืาๆˆิ๎uNู’�“ฯqc P–จฏVmํŠ๎;ลyองnส.2V}}†ํ๋:yžต]ฌbšŒlำยขฒ2Fนฮ˜ชิ)ฺีถ(Ÿb ,ภn@๋?~ปrƒฺN]ญœ=ƒฟ๔cŸฅถซื๋๏ํ…้‘H S{�`ž lฐปXป|>S‰ญ#›‹v’ิฮ=�ฟฏ฿{�uvXภ้‡๒ล‰�ั๋_šNุฏ�๑๏\�ญ�แ�—6๚ŽŽ r่j? s+ƒž"qlEI R(7aKg+E~jศAฏMืo]ฃMVEšZ ฅ�ีu16ฝ่xg/ึ.ƒ�B฿ื(€ถŒA<"$ูtl๘�PิJ6ซ ัจฅฉข\ _‡ ฃ้0Ÿร5ญ–~�Dy�ฺ้LฤCฃSชšสHAฆBฮŠยสBDˆxO“Ehrƒ๒-‚ฟJžขT;‹g%Tู˜ˆ˜@rOwูUมนีะ๙ื /ต ฆ ็‚รฝOKEi๔^ิV…“ƒ๐GซDคอvWvเ�5ฬ…’*จฐฑ€KqY†kไVภ ‘ํใ[]�14จ๖๙ึเ?eNTิR"7ษ๛ฺล๘ู[[คuฯ‡R(ฆBฎ††ฦใ8ญคฌ ‘‡Uถตถ“วุห�—c€L#ไ๒ำต�Ÿ aท47š์ะ49;ADt8=z�(=œ ด๚ฮ�๋้ฮงžฃ^ภm {ฐกฉ Œ\^ฦnA6lWค(o(Ÿฆภ+ X(ดPๅ์ืlตg๓H5Bf‰am# ™}ๆย�์า"�ๆํ�Iยu6g์0C‡๘๙ฒุี†ท+"šŠบ"฿.‡ตฟeิพ�Wo฿BZM>‹`๐ฌX\Mร"F�;ุŸๅไ�5Qํฺฝiๅ๗ˆl0niฆ•ฬaWGWไฬนlญีฦq � ๆซ‰บKี3l‹ญeภ1 ฯษ2ฦ่่๘pP^q\๊(2ธP๖”น�0ย{๎๓ํb ฅgฯ๘<Š{`etl$  •šŠ:se%ุ(Eo[,�ศzI๗ถ […ณCดAๅอ;) Z)’Mฐt.t4"y์& C*=ูึpํ-1�๏}�Uฺบ� 5;6ำฝหwSCY}Zก Ž˜‘YมDF:Qnช“-˜ยฌcะำ๚”๏ืH ฒฺtdศ‘-œ�5ม˜,Fธ4ด;‰ถทโ์๐ปu~g๔Ž้ 9$�ย๊๐ึสˆศ4ฟณฝำ)็pc}—(“N?็“+}็นปŠŽ8›[eœ™;gDˆคˆ72ฎฎพ๎๔ฺ›ฏQ)� ฮ-คˆb˜�~Jš’asS'๛ 4ึiเึ•๔Ÿ๚ฉ4?9k ˜8…™/ษg•Fwe˜ˆpธ8ณF(Lฝฑฆย1๙ปุ"|�h,Œๆ7ฐํ ๆƒU“k๘l{g’n!Gึคษๅ ็cิู>า›žBAvˆp.ํe›hรหฯล๐ั@ดœFซt~)ษ‘ยภx=ž#:ๆR^๓˜วSไง?Ÿแน:6lข:ฌr‹@yส m“1’bEtb~vœ๓Jิ‡ศf…|฿ฮilƒม†\•ฮ<<๘yŠฬc�๛ฏ]Oฯฟ๒9€ฦ�iPนุv‡�N ฑ„# hoส“…œQถ9ฏลๅ€Lฅย7vบ)%ฺgt_ฐศึƒ‹ค™™.V‰C`‹;ๅY3 ƒภวHญcาํ”‡Elณ็Vำ22�ถbl‹pะ�7f~)kฅว ๘ P **ƒ�:เูีณ๊ฅk2#ฌ†.[AฆŠฎธฤ™`DKWฺมpšๅwลศณu˜+Dขน~!{ห.ฅF ๙;‹ีๅqoe†ฮพgE็Yg\ ษ3Ga'ฐป๙YGœ5๒พฬณฦ9ซม๕ัษ�[N]ษk๗เแ�0�ฅD๔แ๛ิ\xghyi™?๐2ๆ๙4š†ดEฆZžศ+r]ฅ่��ržŸ�ž: ็/ฟWgj๘Ÿƒ�๛๋”|๚l��”ฯƒฯJ‚ ฮ ‘นุŒƒ๛Z”s†|๙๛ิa๘เแ{AŸ–�3�ีึz:ศ‡Gฮ่ผ๛ƒ๗่05ฏฝณ [ลํ8‡ศ๎bบJ(รu์e7Š#ไ ๗w�uช์c฿ี�•ž๑…t�ม�จO3pๅ*m‡า›๏ฟhํtภธนj82๖ัQึฐ `seฟšSฏC==5Ž]†C^oเ(ฎฺŒŒฅฺ_ฮร<โแ™W๊ธ`ู๑ฅ™\VNหอ:ฦส™d7ชซsๅ~08ยฑึเ{ฬ๙z~“ฯzพิ สฬๆ„šRฬรใt๑๋ptิ2tโ๖๘;m*ฏ_Mท,ู{์_ผ:Nฉบv็ผ™ ๏V๎w 2๓fgg|PฮXแ�`za๛ย๚BZ†฿ถฏฺคล8q2ยฌำฃ3—ร฿2 yR!9"t ™%ยพ‰ใdฤ™ฮ�ธฝO`WฅV1๐2h%pฬ ๔ฑ๋{‰Q™โ™ฯžœดCA8๋ฃโvšัqt?hvgHSY�ศAแch฿Ÿ4า~ˆภp?j+เœžไS›ˆฑู)Kส�“ฃฌœท๐ซvง์‚ะฏž]t@ดBdฏ(+\Gk0ธถฒeธ"5ด*�์กำV˜Sv@ฮC%ฉมี|™Šชฃ+›h6f1็\€ะNฮ@Kอห็Fพษๆd ฺ%Eคฌปฟ ฦ™ฬrMอูaฯฺu@{Kสปบ�ฅล์ฃจM…ญ"Ho=ž-ภํo๊๙V็jW 8 ๊๘ผถ๐ึ.ดnŽุ๚ž{Y%ร)x4ฎฟซฦ=Žxฯด�=๗ฅ๕ธrะm›€ืvvฑ%arฤ๙D6HT/Xณc�s.ีฏ˜žฅฦ ว›=ƒ†๎ผ?a’๒ีq/‚„ศด \ธภฯื™�„Yๅ>ใK›d ฐศภ็ :ไR�%ึŽด›ก1tw]ฐตDญรe� ™UฆJoa*?Yd :Ÿห �ฒ_๔Yd ๊ธnส>m5็C[์„฿็ฃ๏หฐiดัVX ™ŸลŒืz]ฅ.๗_DNS๐�c2�‚๛ฎค9Rj&&FIํ˜ใzY;I–„๋rด‰ูv?ปq๔ร��ฉ๕r๗฿�ส�ฺ๊+�€)Cž�่๕/อภา฿๚z๓ฏ�[��K๑ฝฯ/ชฬ)CyํV”†ฒร‘B8”IฯE @])แ"šโ((ิ฿฿๗ฯt)Rs3ใQ<$Zๅt๗†ืƒ~?โ€ะ6 ฃFลด }€aฉjeฯ dืฎ]dƒB๗f๓บqอOต€�ิศb๚?�ัค๗๐˜ฑ็ะฝ‘<๕z่ท�ัำ� ฅFแญฆ/mSใ๖ูศ0ส”| ”ใตKฉHฑ€AนLำ ั’�ฎซขฐPฉzฐ�ูb‰*9rP™r ;•ฐ/้w 4QUฃตซ ๔ฦPค๙๙PZ|ิVU:ๆขƒJ`�ฦโX|ว5uธ8ไ($…‚ฟ—JศG™g I_ฒJQๅฃ@ฆส‡•ˆ�“ฅ'๐( z ดBKฺšŽปtง๊�3 /aไ๛๓,ๅฬฑ๔Dซ2๋ˆํ" lทฯmนถƒแa�y15ัYไL€ ;Pะ๗ก hTฑ;ยx1คนตe„dไฒ65ต๕ Phฌ p=“ยA๑(�ฝn9สภ฿ \i|ฌร"ะp๔ouุD็๋jˆ–๑\œcŸgt !Oj•�eฌ*ม1ิ๑ ฅล๘—อ�T hee?ˆๆดmฃจธ|Tฯ็=‹ๆIฅs5ั1�ย๙ท`งัฑ5˜7Fy�U)U‹o฿บJกฤ๎ฝลซ–ˆิปMอ˜œOwฏyc<Cใ80>˜ฏ/ํ�อด‚4ุ"GXGไ‡ฦ๔!ดF ,JQW^…‚f| uฉณ›�tึm‹žฤ'};�ด%‚˜ฒฎSไบ ”ƒ๘ฏะฉT๓ฅ๑ณ‡Aขs๎น๗ห—ŠWวCVษ2 จขภS %(�พธผ0Zาอั™โBeฌ๛€‰Q_‹m��>Ÿ�ตŸ๙fz๚์Q๊๎๋‰๋|L}cึ!dX}ขmR.-ฆlŽ�I~fผImwžM1คค์าh๐|—a @Z�@piZฎฒ๒รถF#w๙ฃ ‘ึฏ1บๆœ่ฐห$0MสHฒ2I๊มŽ,0:pึLSu๎Œ„็I[f�d†ิqF-^(ตw›{Ÿ๊„ฒ_จฤ(2zd=ำLะฑช"šัฺีลxฌypศ๛ฆN8Vืีศข๋g๑ัKืฎ!›๗[ยH.#—�)๚EฐK @ะ@š0G=Œ|9ฉา|yจ0โฌษ“๓ห๔ Aชึž‹้�็จeCซH ๆ๕๕ฅิูำ็Mฏญญ+ $:/ZQUพช�๋๓ำD3™Ksปั\sO9ภœ{N4๚�ปแ๓ฬฆS๙{ืลs$P๋๏๖ะ=:De€ส[ฯ›F™ฮฟU้2นnฒู]ใS‘Rฑ9 ่k@ุใป8๔G1ัจuž]'–๓รตผง็ล—kซQฉ�๐}ฟ็า๑~Œ๑˜~แ3(\4ฌM้8"/[—^ข์‡ูฑัhศŽโZ:žิEย ีษาภ๕lœŸ#๏๋ฯไ9๛žUภ�ู—๗?›/�u,พ�ืฏ๓k๙ฝฯไ฿๛sห5�ลฯ๙ž?{วฦ�C  ึgฒƒ�k)๛฿๚ึOSดฌ‹‚m]้ๆ›Dพ/„ล่็คn พcWจ฿mxกพ นB€ฉูpะ˜คkึล1ฏYฅพะ™�ƒฮง4Œ๘ทดถ๒.๖@‘ํซฐ[��v*ฑ0ก๕Aด ‘๕ฆ๑๗ฌอS�ษSุbศk‹�Zม�ศ! ›L6zu็ธ‘๑ษ4 ฅb1อj~V&”Au่0UmMvึ'๛ม๙wฌ๎iV๗‰zE ษ(*ำˆ�5"ฮฟ� ผœv^œ็LYKuc�แศr๕ƒŒฮ:ฮฒrื/#ๅkุ�]ี'ั�,}€}วZY�ฃ �ะยYoจ'œ็ณศB_ะฦ”gzภ[วF=่า ะ�๐bXnžCรcœ๎ฺืNอฬฆกกแดDป_�uฤงภYึ�ภz ‘๎ษ฿ฉถ{ŒA๋j9FLžง ้�๎Y_ฆA๒=uน‡I๙jg—้‰aขึ„ABšคฌธh๛ŠMlM•m(๑[['œgา0ญญ?ฑƒืี)ิด๐ฃ๖�กฯ ([Š]ลT๑ทด๗kฏผ๔ƒ?ฬ ๓ศ‰๛ัห`๓ๆ|๛�ฟR๗ท~โ›�แฦย๒ฟ^^Nํ2ด=•‡‡�๒›]$ป ะ‚ ก_UJ@gบtนhPF&ปก2;7ะ&?๊dK3๙{:2�๎๑“GPฃ>FaY‘ยSC[QF•"ob,ญn :<4Ažผฝ~ท N/ค๏�“?Oป๋ Dขƒ•ฉงทขU `€อDwEรŸ<{F^�ำู่=OQตux9ูZๆ�Zิ๐ร๛Pภ8 [–!)ท€ฦฒืะภ๔Zี�ถ‡x”TŸ ว\ร0 ก,G[ฃ2บ€Pšฟ†‹ขแฐร{ะ*P:d‚`fLฮAฮ่W @kจ :๎ญข๗พาœ5�5ŽBas ˜rฝ(วZฌRAกเi”เม็LMเ่วผ‡’G W่šrbม>าEู้hญb@o@iำ๚Ž~ํVะีh8Cy๊ยI๖w*ฒc�Vศt!@ฌPปŽร\๒ูHฃ:Eลa]๋{ฏBƒฤ่ohM- 5้สต้๊-Œ4ขถGซฦ@pOl.Q-ฆƒŽฒQJ˜ั�ฒ๚6”ฦ ‚ำฯ9ฆ=ชุ7BaIvgVPcŸškPข7V)ธ‡๓๊�๑gaศ้๘ฉ\6ฉ,l EํuืŸ=ขP5S‚ อ•ญ*=P%e‚U"eฬ‹ JJ€›ยป JkD๔0p\s ข,~'Š-MM_#Tฦ€=็ฅ�i˜จ0๋๊ >โ8Dคaฎณฎฦ฿•ซWpbtยW5š[ำตซ7โoญ`sม;—+Wฎ‘wz™ฑํ…d^ธศyตขQ+kิก๔+:^่p}ๅฬ๙`*ด่QTD๔ทt<๙žsฐั์�ฬม™w์F^ฌแ>0 ฦสุศaokJ3ilz" �ฅๅลUŒฮไฒ�šฺq˜4Q>D^*จฅโ|.ฬ.ฑŽาDu”u"ฅk;‡}vฺ่lรภ|ณภ—~"ŒลผแM๖ƒ9xึ=i$ญ้[?๛ณฉฎฑ–�ฮ๗c� ด™>ๅ๙ิุทธฦฒ คgํ�‰q=}.ปซ,ยU†�?ฝŸh๕>ฆwิ‘’A๛C�ๅT€l๋๎๏IZZ๙™ผt€ฯฉ9ข…Kณ้•—?›&วฦำ;oฝฦณ้�เ๐รLัจ2—๗ว€q–5\`Tฐ/˜W eซi\ฅD๕T�็X5๛คpหŽF’Œš !‹3สฯป€n:ฒา็๓X+ฉถ@ฆ$iภax่ฤฒมฒb>Zคžุ @V‰ัฏ}ฝsŒ๎Wพ๚5Z/2็cเ!eq่๐jธ;ู�ฮจ๐ส e G๘2@@M•ชฉ&�ิา๓ช•’้s9'>ซฦœฌ‡;๗ž‡EB฿์ัAœ'Œ]žCJ๘ภภ•ดS`uiŽ็ฒ๛QDฦba4งัC/#จ็RฏๅยgึภฌภA๋๊!ิ� ๘7ฅ*K/พ�r8ถ:–5œืร•kŽั2Ž๎1ฒcašzDƒ€mPoœmๆฯฯ+fยHc Qๅš=ฆึ๙(p>"�o:ุ�,``TYGฮyVwน>ั“=ฎ>š8BOูf6ใ #ฟวฦโภ‚ฤžฃ(p†ใa-Ÿ#RSd)‹b›๓๋ห๓t�rŽW9ใ—บส9๓Lฝ์ื๐�แ_uK]ฝ…hqฆ�ฮ๋:์—��ฟเ�๋฿{3 |ฃ˜‘bไd๐๒œธฝvด ใ๙‹ใ8��๚^ฬใ9��|�8Fฏแ๛�๋หuX}�Ÿ๓บ~ฮ฿eNฑ๛OY›อท๒VภMš}3�ำe( ุหะ3•Qฃบู่ก๔แUtร+ื‘ณ[้ต7�ŠeชฉฃตiH8#MุQ‚๓›ำ‚’Z๚‚ศRุญ�๏™ฦ5ๅ=ำnำfำ‚ถ๔�€ฝจํ เ'0'๘g™nuตึ‚& @4v� ๊@ฉฬทnow?ซรญน�.๖�L4คไ}�€�๖ฅ•๘าัr�๊A็ฬตูD‚4ณปwnณ(Fhฐ‡๓ง�ยƒDPล:ถฮ=o�j]ŸH™ฟ“\kฺเ$o�Sงร๋œ็:ซ๏ƒไž๐็ZธVส8™Ft O-Ž�lt„ฝGq96๎kdุศบม™}t’5จโ\“2(›L‡Œ r†l�jJ Aจ๗ฒ-๊น4Epฬ”๗ณ€ญ�5ไc(๐ฬ๓y<=† p„ซstบ�[๊ A‡ุ7่Mื�๓พe} ฦxŠพดŽ` ฿…ึ๖x๎Iฦ๒6๊ส*gปไ๛lรฎต ๋ฑŒฎฑH“หณfho*=wำeคษ๕^!˜ึF‡q+�]๛#วหฏ1/ฆศ*฿�ฆuzพญ5#ปUYŒU6๐ิไ2ตเ5ืgฝ ๐นฏ|&๗ˆ๓c๔1QฺKุOฮษฆ5 �๓า๐fถto™-#,s่ ‚ cb�XC#๔ถA๖หฬผu� sฎอ “j‹ฑ๑ฎ`3e9บฟ0฿[ถ๑ฮŠฏšV^b�=๏sผ– ฤ@4eX&#,์ฎฝŸeI::เ๛่ m'"Kฝlc,ฅ0Yญ?c] ‹…คWร์ฐ�ฅฦ ซO๊06‡vc.เ“ ’-์1†ษฺZะ]ไ�b6ฑM eร†ฬƒq๖‰|’ฑ€ฒรvYNž ’^3Ÿ๒๏ะ๐๛e{h9.ะCมDึS9ม&ฎk๊†@L?Ÿ5R9ะu>Ÿmƒฯ[ซƒLgp_�…นยu]C•5l�แม!ภ …ศ*์ูจ3€ค2ษ"ธ Šอโ”ฒ�0�Hiฏ)9Kท.u�ึฯ�ฟ๔Ktt๙�ƒณแ฿�ํ฿หPj7ล้๋Gภ วฆ*�วฟ๙Ÿ}๓๏�;ฟ�๗็F'~๎Bkg~>‡byu)M ๖`*€F�l1XŽQ|ๅjo๚ิKwษซพIๅ�‹8๐{ซ'=dQ็ฦ\ซีถดจ|K#oyž|n)๕uˆ๔ฯแHŠฌโdฃxBฑa1pŒ๐Œ Oฆมgำฐhป36uw.ฝ�มCนuฎ‹a[–Ÿzฎvฆ�‹ํฉˆด†zยKO็�ทฉ’Oฤ‰6~yPู#Gk aนœๅ%}๐a�{e/ƒAaัœ)Kฒย๙Fi‰๚�๚ะรๆ!านIeฆรฤฯ>ซ9ึ8ฮ‘…๖T„ๆ่9q‚า5๒๐ช)FV…เ=‹œoญGบชBNม …Žใ๒ž��hซยK%กrRะ๋8ฉ,™<„ฐ‚ภุ5Zส†;งชŒํ๘ภ0`"กp‚u9๔Rฬธjธ+8ิใ#ciaŠชฉ เ7ดภ —เž*a!Q)�Nเ@oT„aEฃ~”็Œ�ณE`�ฑ„~)ฮ‘S๖ฝ๙ฦ{›8ืญฬฃัsืศ่ˆฒTชฝ We/e็ฺขนฯ>~ภX S{wWฬษน์๕,ุฅลzCสห ใ„Sษชฮ•`:ฬKTข_˜›ลY[็๚JสJ nึŽ]ฦฏœัy#uณ MไT7ต"๗ื˜งาิE�Mt‘Itž= ส…mdผ)�r5#[‚'F่ช๋ฉฒœๅ™๒๙)ฬc5โๆœi0–"N0�-(jnฌเ€2HL#ฯg5Rง�0(ๆ�t<ะN“�n{Fฯทzฎค„bลžU๖Šบ+๎ ฮs#EถŒ๓โห{ฉ[�ืนtŽฝง2ว๏ีm็Ÿำ๏ํ"20ะ_Vาnจ?d/ฌฦ๊ไ ยXl๕€�ฃCl๔ห่้.gภ�dห3๕ง๗๔ู:ฒ>;ฏ๓19ฯŽC็็|฿1๘:�[ฟ๗ฝ๓ฑ๛ฏฟ๓u�žฯไหhปฟ๓๙�ื฿;?y8ฺž~/8ฅ๑ฌ<ึเW�ธq#๕๕๕‘R+ะลณฅ NำrEื ฦ[‘~฿�oฮง:�u๗9หqฒ๋qิ›:๛ฒฃ๘ ๋aGAม+แป6ส�‰ษIไฏฮ�QzLZัgอ*๓ะฑ•7v/ฐ@ง๙๒๋ฒLWp��]�ั๖ต'™‡cฟ˜ะีŽBศ๕่โ2m2#นตKฬ—ˆ Yg ”ฮ^์ฦjq�bjุูษBึถ๙u~ใผLปณฅเ๖ฦฒz‡ร Bo_W๚์^BฏSTkญญ,ม0ย‹B˜ f—Sฯ๊u`|6ื-�'j$+๒ื="ศฒํ68๘, bงŒ‘{พBg์ศ`pi�สอrม9u๏Yฐ/X †ๆ{ปฦ\y่�ส RYงฃ=˜ิึz6N #nิœ7๏Ÿ+๐ม�c3%ฆ๋z ูJ1g|Œ๑ ์สhส์ฺ์.ํNT่K๊ี2๊ลธS'ำ�็‡€ื๖ผHEื…ฺœg9ไlŸขswะล:˜‹ัฎy(sDY‘Kฐe•ŽNท๏�JŸ�โ็"ๆ4ย๏™<ฑ“IP๔Y__•ฆ>๗…tฑท?ุ)ซ+ฬ๑ำ1ภSRŠษAฑ ฃฒลg๑Œœ3ด5ดUk|ฦ€yyœ/mUฏ]r�ˆ‘yฤ| `ส€kABAฺฅ2ๅ#๙ž‘ZBJI�“ฉSBG๎ฎๆtํJz��อ๔า ฯล�]X\ ๆgฮ๕๗|—ฑŠฺ\ฃ ’k(ศcimee€g>=๊VtญบD9Uฤ�]#ะไ๓h“ิพั Kา�YŽMs๋๎�Tuก1 ใภใว ™R‡ฐ;ฝGM}C,Wื„*ผืR้0A๑”รนฑht๋„ด‰‹8k‰\*r‚ำJfu าjฎฃ@ Hข่ฅ‡Jf€�jผK=T๘๙ณŠLกฉcโ!wภข‡็—Tด€3๚๋5wp`5`5ใฐ๒ ยEcร9VH!cbmTๆฦr-–‡1gฦ›-p��<้๙ย0ถ๓Pš\ป @ zวr5Qxiบ˜Kaฬj๐1๎ Œ™rขต"๛‚ใOฆ��(M.0?{i*�)s_ R‹<่`jB“‹๒^YšF™’ส(Pส�;ล)XY˜ฮŒžี0zนŠป๕v—ย,:sRžคZคสย?๖xฦ๚รญฃท—k’ภ�ห/ฏ%W „šฯป6งVึ๖_s� Qฮ*ฉสFœ�]1ฯm1ฟ|A”ฯฆยใIŠ%S€าP9Swมม ่sˆืวhทsฏั"ำ`น5M@gLฅoŠ‚9ksดxœ™6e“9๓ณZ*žyชx้ˆ๋งแc ฮ ฮ…5T��Q0ม,ขF๕Lˆ< ิJXD}๘ ŠnoC3["…Ÿ P†ล"๙ํ3 ! ‚ีะ0รฮ าƒB��'ญŒฏ3ญโาxะื@Sy•WRญ-K!bz12_ˆ>p-ถbบ~๕:-$-|Z XRK‘Sœ<"รO'จ ๐>์ขน(0)‚๎ธŒNxžสษkonkN—n^‰x`�&ฺรx-ดh; ดน72าึึJ‡†fภฉถ0๚ฆxฯย”e|i|ณ?pVm๏ต@ญฃ] WฑVศ‚p0XG•ณ/�=�>ขล<ปัฯ$�)"^ถ4๗ฝŒ56�;'xื_ฒูm›๗hไY์™�€&gดh‘๐ฺ�ž&๓์๔หฉถฮ~1ย)เW†ŒMบื@@OoOบใฦ4‹ั.ฺ�ข"U3วGฬŽตi2?ŒZg-y๛ข� ืƒ~†GŸEtY37ื4@อŒUYฯ๎lo%จƒcbฝ›s{รต�(๑๘7R2ถ‰zfxt”๗hตŒŒผs๛NYด†Œ3,ฟืN’–mqะAB๔ใ]Ž”+‚ช3ใ8[D'๗กฦo๎S3 GY†๋wDบlAA็ะ๚Lาิ]?sS Kพƒ๖�u„ญ~bร�Byi๚ฆ,Suโ_d<“ณ.sM�T/ทะ€ ฝ—:าฅซ�ฬc9ตE@๖sายฤJ~@E€็“ำMt‹|t๖‡ซว๙2ศ—�[J)๕คs๋x#•€ฯสx้&m P‘˜พบ ใ๏”๙ุ�$เตธ`—%์›#์)jฺ๐a/ษN8eฟ๊P‰ึ&ฟ~�j๊๊๎ งo…๕Y…1ฑ~_#X692ง—3๙‚œ๑ฅMb„�35Rุ—[ศฑ%t†{๎ัใงฌ[[d:c฿๎lฐื}ุ~N5ฒ–yŽ+ช๖R_pKุwฆแ$๓aƒ^~ฏ=ฅNd๘ฑทชจ๗T…^nณK˜{�"พvุh fYN. bjฆ]hไL!‡K.vc; ฃ[ย.|๖,MLณoฐKนŽ vฑ:]็WFต8v๔d]ศฬฟส_ม Oš"mwืK9เผ๘@ฒด˜@ 4ุ‰ศบF ฌ_พlB๔x1ฒ๕D]“Vถr Ÿ9$€a-Sผ”g฿Y1•T๖–zฬEyตฌFX;ศฆjjๆุ9m‡sฅญ(์io[cEน(ธ๎฿Gืฎซผ2%ภลฬrผฎ‹ฒฮ”๊:๖†ฒฦเh€•ฌปsRฦ‰L่ป๐4ศ#%หA�#่ฅ~ฑk๗ด0๘ก]%#๔ ถฝๆณY]ญพŠฟใยี€p์โ“พฎช๏�ไWโ?๘�๏�โเซฏ~‡‘�ๅy�•n๔ต4�๚w~๕7Wทถ~ฅณ�bี (ฅ›ษถ†qนกฑ*๒Ž€รP"ศENwNฮ บh?q�๊OqิฬำI4:ธผ=Dุœ้ฦ ๔?ฆ`�ฬฬX๊๎๊ฃŠ๐}แง‰๑6t๗OะX๏FฮลพŒ‘@๛•žˆ๔ัฌ-U Ew๗…t๛น; ~ทศkลธเP�๗•K€ๆืVฉ๑ตOdf ฦสžนqY^ูAฐJฑE3ึฆึvฺ—aฌ๗๖ฆKืฏ‘–ขsืŽQ‡A`�ๆIธEพใ6สp…ฒห�Wยฑ+˜u4ภฬ/6ฺUG๕u+K฿ŽBˆ <ขG~~nj…nhษดตชฒ‚*H รฎ�'J)zยล'๊,˜ฅณrF๔ู๎vžXมXV™ใ�ๅ�ฦต๋"eœชร#luLlฑๅ๕,Jฆฃn]ฃ‡*้k2{DwuTญ^ฝ@=i๒๎GฃA‘สยผพ๋ดY*ภ Œฃ�UB‰8•9Xh-*-๗งณ ssg8Oซ€q+KT}็ณ~~‰Ÿ‰Žƒ*Ÿ๒ผga[๛ไ˜rTคฦฺย‡/ๆภจปc฿ืฐร๘๗9ทQ‡ŒKใ˜Gp ”œUีeQ [#k•gฺdOiDุ่• ค—8—…ค-๔๕๕pvฬฝ,เฬืsข๔เั๋cR)Hฃ๐œ @ํ€Yฏนฃ•ฺฐ#ช ำฝO�Hืo๗c`Q{ƒghmlพ่'์ื•ี9œซRุP=แhๆ�GงKWฎฆ—?๓™ิ;ะำV” >!m้รL,�vOaS ‘ZภgjaAไใฐๅฝ=ฅสฒ†k.ŠUเLmญQเ~=<1g™Tฮ^=ล“ฌ็RFงS ส–’55ทฅฝ3็ฎ$ฝx๏.X#kf'"Œ›Œ๕j๚�+Ÿฯr(‰3}๋็Kฺ#kฮ:XsขˆvIฆ๒,ใœพ๗๑Gฉ ถ‚นคฤฐ €0๓1ชใ3:"ี8ฝF™t4]G-? ๋mpฎ•%V฿,ŒHš{#hnfš๓` €@— {M€d`j“ฯศ�จเพk�พˆ‚Ÿฯ้ห้“ฃ|รฉนีz๙(PPภีภณั6 c’hพญ=ภส@&/๒,๓0,q†tlอ•ฌ&ฝI†ํw•ถะ๒ฬWฌXำ$ภRฎฃำ(#ง๐ขน•,์ฃด}tคHด‘เ!ฒ๐yๅฺ๚}gบ†–Š5uอเฮOŽ๓เ๒ีซแŒVRี3๎UXX:š„ž็ 29i Bฆล* ถ9ศ:ซศช•ล4Mw]ZฤพฃEผฟ็ฺgถอqฮq^฿ี+ฉ‘ˆV'ฬฝ›ฯ�ƒ•C�S]e๓ฉQ{ส�A.KำŒvฝŒ$ํqภฯ„ญ@e#(gิงyศ �‹0feสค8a�ebษHี๔้O=}!จเึตถHก์% BปRQpํษเฃดปธL7x๓7ยP�™Ÿ�™ิ†]๐�‹๗Hฟiฆ-#X;u…�cก‘_ฎeสŽฟŽ~ฆ๓๘ ๋iฝ๓๓•มUค๔ดถ’ฺ€ปKtkฯ(>k%h๎+‹:ซ+3ฉŒ1ล@9แuใ๗œ l๏แ\˜"•ตร1ๅ๏|๙Ylมb๓บ~๒cŒ'๖งui3ฝ�๎๛ิ)Oฯ�พ‘�œ…Z€ษRบ่ศ‚|๋๗)ฮ�ˆAN1ใฺ8†0บฝ6 .ฅ?บง cต%tNLํธเฝfคะZ4์ฃ;…€†xหนฎlƒyP�ฃฆ{สT๋C๙|งสdœu๖้6kŒ�ส^$xม฿้”S่ฬ:~ฟlท' �ย43EรBhๆ`ห ดพ‘๛JžkๅKเึVช๊C~…�Fถฑwe4๙ปฯ'ถใศุ3˜จ2Z S๛แาฅNt1,…rฦB ำ0€tf. ณšฑฯX"Ž?๖Ÿถ7ho‘qXว9‘1‰ญร\ZƒลW2�fa)ฎฃpu ^ ฦ�ลษ‚†ฒ$ ์๒L๓Pน๗ะ#ดลด็g'‡kœฮMkิธ:มN, ขck iี€edDฆ6ื†ํปถผO”�/vYs˜ศ๗ษษ �ว ‘กtํ@๗“)d๎5 Yื˜๓�ฤyๆ hsš9‹ฌ™J= €<๓๘ฑ�LiX„แดHค้นMŠ>ฒ~ุ”�่—3 ๎1{F‹‰ฮs8?)คส�ๆ<ฯ/Y^aพh๕ˆผทธ4rS--~กญ…โแค=0_ุzิฌรJdmยY&ยoฮ๚25Wh…นAtœ๛ธ'eสช็๘น ˆม‚e�’\Sežฒ๐}h๊„…uHMเ7ŒWถ็เDว^•€ิse๋้็๎�™ปLบMaqNบNสs7`w}u!ฌๆžt๓ฮ ˜Vไ๔รด›– ท R‹ฎญาพyœ”ืฎภ>ฤ>˜ƒ๙ใ๘��ุ๏สว`ฉ๗˜3ํ"YoŽ#Xบ\ฯ�๙ŒgุใL๊Lุ�$—ฝ%#mš~๗ฟgbฝปฤ9mƒ™ึืี{x›ีต+ล?ix๏้๎&+‡ตu�ท๎� ฿h�แฺYxx �Oฦ€่๊jKุรฆFฐฑธŸ2ฤš0žyๅง€‡๏i šŠqlเ“/}5;ดํฒv{ ‘sศ^‹‚zž”รบ1‚'๊‘C๔ถl˜B๔'๕pร�ฑถ —{นY่œY@rปuƒฑบฦ‡G๘?1ทศœ�]ุ9่ˆณct๒แ๚�ต‹�฿�O��ฏ�Z๋ํŸ}๕U7ศ_ฎื_Yเ`่lจ่�ฟ๗ห;{ฟดตฟ—WCหยซืn‚ด€ิาxฐ8g ˆs…ƒ B,ฏ,ฤุx!]ฟr™ภฦศถ(™ฮP{k'”บ&๎ํˆJ่ะอIีIชซmŠ‚†ณsk�ณเ|rDU~*yฃซ"ึ:O›•‡U…ห…†Frฃ[๐ถW|”Ž๊็8‡[ห'๊]Œ8…�๛๗฿cƒฅO�y‘ส cฮMŽ(RCˆ ง\cำ�h��็p5’ŽSCุ๖UVB–’จฐั9อษ,Zฆ๑ใุ}> ัT‘ีU5z‹ LA#…สร/*๏KQกเ๏Œจ๘uE1Rโ�ˆ�Uถศ‹Žข๓dTPcRpA4Rภล๑iŒชd�Œฎ~.็ี๖=า้ŒFkˆ*x,nR หบ"แ˜•‘;ถ‚มป…3กU`uvิJไ}vวงR4า”Eฒ๕*Eqz?็ร๑๚9+p‹๊[ณb c›5( š] O}K+ไ๎t ฺ๘ป›ไž1�+sะ>ƒ9€#Š`๒™ค0zm /ุ๋๖ฬ่ฟฦ–่ฐ FM••0:|_ึม&N†๊ฉQMคผŽฝ{…?zฦ็q๘ฌ๓ฦ‹pสp‹ย >็'ั}็]cภkูๆS:ฎนืฮGfภโH๒œคY42าฉ8‚Iๆƒู�yŒNพต8’๎}kg๒œˆฒ7ฒท�ฺ:0ผช˜s๗@ ‘1A+๗Š็+ขEผwฑ�"สดšฯ,“#jีu๓m-eฎœญ&M…0Š�ฺ�{fjr:MR4อฝiฤ4Š๒ฯฅฏG,ฌfNพตtผสpฺŒฒjœmp/gม*๛(๐ZขpFค�฿ฑ�˜j1A˜Q#Ÿอ3m”ึbLLZTูตXŸห+—/ณ~F”๘ู๙๚�๋oPล‹_ ถ็Wk๕C�พฤูzื๒Œ•้2ฉR5Dˆฤ˜ฎแxษ’Xž_bŠsณ3ัฎรD6Ž๙ฦ‚i‚fฬ‰]@—˜SฺตXKะŒณž๗โภ@ดต๋ไs›ข�‰&ŽำณิGๆB‡ฬ=สทฐsุ�(}#Jลฆ•P'ก9RฬzY๐L;ฏคึzื(หํ›ืa>อSุ์็“ยr์– ญแศ51‹ฆ-lฒwž >ฤธ5Mฆถ”๘O�$YdMwW}฿๗พ๏๓œ็,๗นฯ9d‘lถh žvA;แYิ.แLูpฒ๓ๅ{ฦ&&ุหย๔๕_๙{|˜พ๑อoboษxฏ-แฺŒ‹ๆ~tผ_!ำVLะ/R๓‘ญ7ฎ‡<ชซ,kY^^H�ม‡k๔Ob-ป ภ=ใฺ{๛( R๐ƒ\จ'[VFfิฟซใ#PเษeุจK๔?Lธx&b์+๒nRฦ ย,�ภภ…vŠ�ฒดษ€๙‹๛wa lะฬธ8(,bw ็Zุ๏*ภ่อˆื)'ู$เVพd๘�ฆม:ฐ)๕๗T"K๖๐ž ตƒฺ>ƒ}K<๛&4สูE™b๖Az[‹�ทDขฒช(uะถงฏ pธ€Xh—/b'๋ชRGW฿พGฦ“เว ื}mแผkw z–ษผNะU~๛5 #ฯF†�}r:|ƒ›ฏ฿ gjr&๒.Ž๏sfถษž`ฮHpe"[๊$žl+๐˜!ูฉตก‚)UฉณฅคSทhZ ;์ Ekss�Ÿ ?ญ,™ŸeอaKส>ฑง๕ึ> ธ\�ั?� lŸ`”ิบ` !cžC”2r‰_†žM๒5๊)�ž QTY‹]'1„�ญ‚,,RยจยB/8:ฉbภึๆ}ึล;R[ชเป@ตป5๘–-x_พป�›“Yz๛๚"iถF?…#๔"จG”ฐIG7๋lpzHฃฟmGธ๒แ๚’–๊๙ง>ต๚Fึ’๒`F\ยคว๙”ํ‰฿ม-™@๔ฺ–lšํ.G.,Mˆsฦ:ศ<๐พW๑—W6d่S๎’€iP;ลoD)”ฝZNN,ข4 @A@ฤ Fy eFร#์IฆฌGเS&ฮ๚R&‡>ƒ:AFŠ๚2์ ๏ท ขๅ>ฃ๖�า๏ ฯ�Tdญ|.ถ†k๋g๔จ@Šฑส์มม›0p` ตะTu?ึคƒMฅ๔๋Wผ์ฒJ‰Aท๋#xSึdJภฯk<?W'ป‡๚~พึ)eฅศ‹ Ÿ]9V� ่ ่Kป^‚bศา๚๖๚b๎•zK�ฑ๚N–+Vฆd๑�ี+]�๙ฟ๛ท�ฯXำ�บ�m~๚๓๗…ˆ�b~��้V๖฿�ฟ๛;ิvv9ขๆษะ ำๆ8ธ< Z‡�Œv!Hฐ่SBฆ ๋ีิง7�x4~6 >นOPธู,้ฎ"ฌQ3Qk€ฦชภ <|–n฿�œo๓?๕vกxqJซนItd ศข^‰ƒo^ฃŒ์ฆ4dม๋๘ญ7kฆ๓kiฦk’lr™FwŽ )Oฆ็ฯว4y๚‚‚ชP8 žฟ]ห T*8�:Niโหvs็ูY]็็e3ดŒฃc“ทLึภ,ทฮŒสลฆv�ล๋ADq>\CสEt^ล+๚’Uเแpถ^ะืหF๐`J…๔ะ๊๐จl�™hตฟ๗*mZGi๛h๊จaื™ัˆY็ฮ ฏW 9Yc&จ โQ!ญB฿ ุfฦญfwฝ”‹Ÿ้๋4่: �‡ปŒŸ]ฤ=่่Xร\@ชก’–o็_Gดฬ๊์โ�ฏ A{ฌ’ +b”Y%๗ฆ<บnZรs€…‚f.EลKผ๗ƒอดธ4ษ™ษŠงฐ‰ Œทvึ†๋q�Zเ8O`vHฆvf~:dg~i."วV๊}W)™Bึjjkษ ผš::˜”ใ:6ฦณั1QฒG2 8฿1}Y๐™ŽN3ฃ๋ฬˆฉW�Ÿ็›[ษ’ื“ฝ ;Ž3�@Fkt่คปzฅŸเฅ< ?'ปีF ะ�๕'ฅฯ[+<<<œๆpส‹ะSoพ�%ฮU1Ÿู@�LY@#ฯy^ _๚า—‚ต`ฐj`ปŽ๓mฯ๕• ีงซฮฉojnๆ\`์ |ั>‹ม๔�Uจชsำrบ๖…ELqแ�R�อ์yt„#ค ๊‚Bฆ3—Yฒ0ฅ8m]Œฌ3ฐๆu��ฯพ›–—าฅ�๖•๙ุd.œ R€3‹xขฝ`U"hไo๊k^•ู �ปๅ1๊าMJnิ32Šผ‡MtV5{ๆป pอ๘่I›ŸeJŠ4Jr�๙่เSgศ :7zเt’rษ๐œม €–ฯ>๙$=ธs;๖กขบŽฝว๑(แ^ง'ฐ'่‡๛Ÿ� Ošฒำ\ๆฆFัcนPœ ๒��=ฮŸeTfฏ‚ฅโ๔)y&๕ตz�˜ณpๅฦ ึท(�๚์6R~l‰๑ฉษิL8ˆ�าูิฬซฦ๎y/žU3Z/ื�g€ิUหZvภดˆ`„ภโ>6ฅ„ 4Jฌ#์^น๖J๚๕ฟ๖๋้๋฿x/๊๕gฐŸ๊ชฯ>�ŒsVพ��{8๛๔‡a๏๓ท~ FUSศ๙ำ`N‘ƒฏ~�=�€7ำ็ฎ๏}๕๋Pˆ/๑9”เ`7๓ ผž�๐€7˜ะึ ๔d๚แKิ ๏ุ็uฒลผฮ _‡ี†ฤ๕์[ gลŒuฬ2ุ7��o�{แ์RJ)-นœฒ0ํภ1~‚T;VมgvSgSหบป๛ZU”ฯเ�ทwt`ฃมศ�ฐia€tMJม=r3ถ;†œฟ�ม๗XO๚<ภ่ฒึWpฃ›aฝq€|ุ>W1yu<แbM&&" G^๖7`G7�ฬฬžT*ลD‘,|ƒ—l๖F;fเ%จ�ืำถhnvŽ๙๖30Vจ=ฌš"๐‡UGใCฒ&Eู7GFภหฟฯใ๏ี•็ฐมุ+ุg\S?ช—๓จNึwฒฎ\{ใ๓bห@๐w–1–r.๒ษ^ช�๕ŸbŒ5zฯ’Qหีc…ูŒZH�]?�งR์U->! %cB-+ํ์lg� ฑม๚ŽQ…ล�:&ูs‚๚ว0น�๓h–ศ:ฮQ[๏Hธ ‹๖ัูคœn@Œtฬคฮ�:เฺ LŠตะG๎แมต`A1๚ผ„ณ–ฯZๆฐ๎l�Xห™xw@m๑๊ถ๔ีฟr3๕ยšญๅ^Kกย—๐,eP๐อ—3ฒ„ฬvUA"ฟ/๘™ไžfWœtH>เRบย&2�๎ํ[’‘!Vนๆ?ศฆ ๛หบฺ›  =F?1�;จ๚่Abwžg;8EV'{*ฟฒ๕lp๊‘ป d�g๐ร4$ฑ_ฌŸ, ง;่๐นŽ<ๆuR!�C๗SฐBZง�ฒณvSKcmบุื ฝS'‡IอŒU$ใ็uอjCkv=อสHท�”Ši๐ฒCฐนAฆv“ŒืL๋Š]WoL…๗๒ห๛ึ*!ƒo`—QจcศฅqPnœ_^oฆj—2™v%wอณ ๅฑฮฎc(Kึ_ง�@ g๚:่ฑ๔Jป_4›1Z]ฌ!ี(`๐ฅ,kFAร%0&r๏ฌaัh๋Ž�ำ`�{‡ย้็kปใzฎh๎์นฏ:ตf๘•Cื�ตต.ะ€{Ž`Oc่{# โZฮ<€[$˜\5˜ฤQตง‚†Oš๙์๔ ฏ—rh�ญŒ— s&งคpฮกวB๙a}ีcไฦl” Ÿ >'๋#=ƒj;m"š�qฏส‹4G ›i™๕VŽ5d3‚tyซสgฯล%ฦ๚ 32•๎ุ”Dํ™#๏>Gู1CUAถิZํŒ�mใ Tแ์ฎP˜)j$๐jL๋{+ฉๆฃ8ษ(gเิUฆงฃฯiXT“ฎฟq=ถฎ๖ ุšู?โ^ฬJูท.}l|,�ฝKฌuส8ฌ#ไtล>ณ G;t็&.ฮ„ดhฯ™eO‚<fง่ Kซ xN่ฝฑนHyย5ภไ,ๆี‹WูcjYqึkนทi๖2๒mญ$�|๋ญTŒCŸ#+ภ;4=–ฒัฟ๑�Ÿท‰3[&ฆงำ�๑ง;฿ย™ภูวูจX2ห๋^”QKjyMืl๏๎Š ผœเม`A€6#wสผ๓ีษ�sŽK81๊ }kfอ๑}์ฒ‡6๊sœ™Œ„]ไฉบฝ%ตCฝLผฮษ“มม8/6_ห&รŸลgฮ ญฐํำy:r h$1AC'[วU รเ„์ถŽ.KJ]7vฯ!`ึิุ๐ ภ:F™sฦVูหฦธ/ฯ�ฬไถ‰>5:NPก_ฤ\๚่ƒ2Ÿœž<ห�™6ํ มšN1DožWg๘€ฉ&Cdส้•ย/Wƒ4๘๘)็—R(๎ีภซฒบ>}�แ'iวีฬึŒ‘C‚๒ศ�a‡t6?v†ฮุD'l๊d๑รx>ณ“ Š@แ๋ำีwn-Ž๋I๊์๊Š)ซฌ™e�]=ัH–ƒ “",K’ZฌhFX{a'cD;Z;ม3ฎ�ะน,|T�yŽ �฿ีmสz‹X9สฝฮ๎�{๗"ุt*Gๆพ�๎ป้ัำ'ฌ๛h0/.]พฬน๘œdฑฝ…่ษ™้ด€okiM฿{�๛ฐxV"{�าั–๎?z€ƒฯธ2ฮ‚`ฒL›ฬR‡‘*Ÿัูคาจห3 8ํ”%ŸE{e]๘.ฅS5ิ<�ฺฏ}&ะž�0A–Wฆา๋ืฏฆ๗�๛:Œฃ ฐ๊U‚w์B5g~anฺps4s๖™”๏,ึก‹u 5€QGnฐฎฮŽ ถVZ๋ฯYฺฐu2f:{:b eเ,.ฌภ�ภ๋๊่N๔y๒8}๑เ |น=t๔ณ(Q˜žุ^ๅ๙m4l้™พ\i\#3ๅา>ถล€U@*+ฮฃYV� 'ฎ(?Ž�nkmคp๊ ใท˜ผลT-;�Wa7๔ษ๔สaH6>๘ู๙ฒJ฿จœ L=๙เ้#ไเ(5ึ5qM˜y/๔C2ๅn(;๖ะฃชฝะษZnq�,�ำ�สฆ;ๆ^ทธข/kK=Ž+ฮY$เศ1 ฦฐศ2ๅ๔gส:ฺ&ศู†iPฎ^jK7ฏ_ฆ'ฤ9‚R’7Pคึ�ป W0� {๛8=ขjๆปฎ‘พ*”5ํpพ็๐–(™Xc]Bไค๕Ž�eฐ>\์{`‰™=ดœ`ๅ๏�๋ Nฉ ๏[ร็|ฤž}๖S9˜vFนึฯณ*ศ„\ เ๛™๙๊T“aฺiVˆ�็œk[ณนw{่่๓พ@O๋/จ•#ำกKํฒŸล3่GˆšP๑�๚Y~˜:]๛ํ†ุƒหr/ƒ[งจ?�ผjก`ฒๆสฎ_๚2O์พฏฟฎฏจฏ๋็oQบๅ3ฌ๊{ํ๘;ํIyS7๙บ( 5`�ต_{ใถ9&Ÿ์�$xobO–€�•มoUy ๅs;ศ๘`๑|œร๔ญ}๕ห ทrฉ•๖liใ�๖�r้}L^Y~๔”ฏ16๑l๚<๚ฆ๖ส )่-๓F๖ข2๒๐ู“42>’ž Gนฐ�w,ชมNi�dศตG–{i๙Ÿ�rh ~๋ฉฟซ๏yศพ๘ง๋jVฟย=V‡หhสฐ”3๗%ธฎต�๔ŸตะŽOฌ† ฅZ UูทKนtโ9ฆt๗๖ะHงŸc๖”s_�ส5jญ ์าฦัฑ�A๙Lช$ใ-จ๊๐ตะีโ�๏ฃgั4ธ๎qN——34tKo”‰ >ทูšวู�็~`œฐo๋\CuฃCขMpก ‚$ม%#ƒ4๛ฌฅท‹๑TEศ‚อ๊hะฺ่ še#ื‚๗>นvั?6[=ฃภึฆ�2ŽฒAt†า}ช๓Ovู^, M>็QYYš™ŠฺfHฮ:nซ�๋8Wส๚์๔(S}aฑXwn–>�๓ขฆ๚˜ @fŽ;ตธD?>z—ฯัMVืฺCGjบ๏๕Kgึ฿Fึ›ฮโ–/ ฐh{ดณใใัA†gฺุฤ9'ˆษม‰ฒ<หLœeoิ,sข�%2ถ���) ๎K%”๙ž‹�้๚อ7#ธ9ัำ� u7ำXW'Xะล`ษI0vฌ–™ฐพด™+i์/ณP:โ5Uีฉงิz้c๔„๚ส}ตฎ�2Žr่�ึฒV0 ฦuจEฯ:Z๓ำ;Ÿ3๊k!๊่฿ฆฦŒตฅ 6]๋=9+KรฯŸง‰นษL'f'i V”ฮ๗๗งฮฮฎ•๓�ฝุฒr�๛ฺ{.*Nr:พ™L�J่QeI�fpž๓3vซฮญบๆ„}ojiยฎ7…รnVฏ„^)ฟ�7�Cdธ1ฮ^UMyššxสxำFcถ“แ�'้ตื^็^ฺx�9|…ช˜”ฒG ๛.ยW`Bœ?!=zBฐ?C0 …พฃ Eฆ“๕”’อัˆะS›g)‚L3%๖o��อ฿๚อ˜€R]YCd8=xx7๔ฟ”่งฯŸE–_๐ู์น๔แต5J>y”F๘ฒŽะ•6I”)aธฅฎ–๑จ�YolP,_uฟ"ดั ๖ 9ฬฦ'ณA[1zธง็<,4&ยภBธ๛เ.zfู,€8~PCCS”%์ภพ<‰E(I`Lฐษ> ใ�ำHษ˜>„zO[™)อ๐E�”!ฉช =oื็๊ฉ�GวๅbG œ K`~ฎ-ั๓1@6เ™X๕‡}Mtธl†��ดƒฐำฝ�!Œe…žใ>;^VVจG๐ >-_จBวY:#ะ‘b๙9z๑Ÿฮภืฯื�-Q ปฦนุก��ิ`‹็ฺ=�eํySC-:SfŠณด*hฺ+ง›)>ฐผช ถ& ศดก`ลE0ัมน่`eV�ษI">ท‰ฑmlGื=ลฌs�้ {›œะ? หโYab๓ฃ4?กŽ็U@?Ma‡๙9{i-น ™„๚IE…4ฝLœํ-๚•ะ7aฦวkv‚ฌšพ9ๆl่๓Z†$‹€ใ …�โ�ยเ�ขผ†=……]•} ๆุSIy>E•}-�Š=ไK�๗ณŒl*3™ž2NMัO0จ๕ป๐G@ม์9ว๏x/็˜�๓ผ2 2T{ํFŒๆว๚โฒ�”็B>MuศShq�J{>เธ~ฐฬๆ‚bFบ3วiMY”น?ป0บ<วNMจฏi!‘ณ“๙Nš˜QIPฏฯฦ๒นรฏย‰ฉPฎ๗ต๏ssOป<ฏบ_ูGะญฺKส'่้uฦขฺภ๕๙ฮ}๒~ด๓9–œUภ(ฑDฺษn�ฝฐ˜gูV–Eสยiki‹^FU�{๛ฉ�ฒถ๖hR/ธF�๙|vฏืO๒^� หฤข�yฟ&oข๛/ุโžษž6ูŠƒ?|fAV๗!šโoพ�7Y‚ฎ/ห๏-cๆ๚ฤs~†ื`๐หืxx]ว›ฐuyุ฿ Xแ�ฌ�DpG`7๛@ฝเp�Ko_�oพ�7�‹๗‰-}ืฯ๕ื/,pเฎ�ั}๛๔ฦ๛?™๛�z๏ม#Œ2ผ\_SWญฐY[™เ„Lก˜ศ9ำŠ์)สซ็ใ๚๕๋R �ู|๋๙“‡8*•ก ;{.่ืซ๘ณž ณmLƒ๓•l ๔KEd€คะ�Bฦฝ)ผJญsg ๗๕ั้šฺข,œu•ณA๔ƒGำ{wiๆทลด†ๆ8อŠf"่ใX Lฬ๘‡หŽโฑฦ…ฟT๒<&‚๕ฦวP† Am9;MuKeฺ้+WQ”•(๓5#ึp0 lฦe&ี็๐~ �ึเ่d0ภ‹ `P+0๊u(ตฃpf ๆl`rOงมฒ ี้:†EGUลแ็ช๐ฬิจlฃ$‚%j„�‡ำnฝงŠEQเภ น 'c1z($k๓ถษ^hˆฃฦŸฯUE”ณฮฏVNp„u.ค�j�็E[�d หยaฒู †O4IAัช ชqฉด6ญฌค.จV„ญdรจ๑/งk;ฅ52 aชq ๋{ฏค<:FŸ’964Xส๏kฺ‚ ๐bFa�ฯ๚ๆ๚†Vึ.ใ`ีต๕ฅฒ๊ไY/๔:&�J8//3m™ŸฃˆUถ|sญ\่๐…•(Jžโ!Ÿ@!ู’"มŒ2VณOั%ข๐f๘D๒�ฉl‘{ƒJ+{t์H_EคๅZW[ ภก3dfสFC2]ฌI‹ๆ๓ผื˜งิีัฌณ&]๙%?:๔ํ์a†ั&@f‚�฿ŽŽŽpvu๒ํnvHC—)cะ‚ต?C^-ลxA6สIžศ” รRห--1ฯ•Cค2YๅฒŒ์ขฅlูXš0‘d=-ุ„ ๒้r| \ณV2ตž>~ฮ0C๚�ึง้๑ำ็iู่๋Cเร^fมฒZXก�8๏sบ->ฌ„จภP~qฬทัฟpˆขข็’ถ)Ÿุ0ิIŽf]œ[ฦมง”3d&�Oi@O๒^ไ�Rœสๅึไึศ FฆG<—็ิ๙7€3ภพ�ฮ;ฐbศvโฌ ศš๙ตคร2ว—Z:b—pฯ๋เ่0อj9kผ_ะทœg7›™‡๓ฉ๓ฆ.ทม�ˆทOŒำ‰d็`z#ศD�`ซOุ}A*ฎU Kงฏง›ฌk;uๅMะฺshไ๕ L™lz=4ฅ๎�bท้๒™๛jMญญm้ทฟ”^}�gโ(�ษ๗�์*ูIู้ƒO~”ฆฦG9om^v8•ใญ7nF6๛ุl1๋M๗8็นฺ6ฌ<WหฆLq&qARkG€!N;๒ถMI[5ฯ3FYศะ8๋sฏc๑C์  lY26?วไฆ๕%žฉ-ฮี&%4๊ญl‹ ซ`\2kRj �B๚ๆ7ฟ`็Z}g—?QN่า ฬ๓/ 422สบำdtหพ%ฒG|่๋S (”ยB ‹ื๋;ฦ ๚K‘Gหุจย-D็‘‘G™๎ข‡•ƒe�๖˜,€|๋ิ{VNล๘พญcL๓@Aฏฎํะ,y4ส+Iิไร่H?คทศ8 ษอี�431๛ฏnqิใ‚!แป๊ญ๒์dœeฯณ ‰เฅ�Œv๐q%&”@Q)"7เx•ญฅฮnๆL\ปิ‹lืะ'�™ฝณJเcŽ}ทar#6\ดณฯ™A�ๆโ3ษ"ณq๘ œ9ภbโˆ=�ZKนูxุธ|Xธฦ>3ฟˆ†๔'๘ส_€œMb6&Uื™x๑ตุNŸอ๘BYเqใฟliศฬ ’NฬฐใTŽไRVZ‚Qใพ๋ บป›qาzq’pศpฤœลžƒXแ๕ฆฝ๕Esบตำฺ้2ฬ๏๑3GชL[XีะkqŒ–vyผตJgำ€’=5฿ฺฒน˜"‚AB๑J“•")-ฐ๊ใ๖D ๅ98™รPAกซSŸŒมฺ\_ๆ™Qศฌ.ัu›S๚pRฦ0(f�ํ�aK๛ศDฐa›ฏŽฦ1FE`AGฯ,ฮ๔ ฅ dไ๘5๋†ิqŸ„rอคs!๎Eอ^Iมณ์Ac๊YำˆฎคหV‘๒/จ0:2ถ๗นaถuv๚๊ ˆ7ฦw Mชž๏๓หr ณ8K๎ำ6‰†5ๆื“๒5C.@PNFฝณเ$}‹F\f]�๙ ฦยsk ใณ;nิบaง„์o#TŠ่„m,m@gด ร‹< ๊(ฦ๚๑<žGืยŽ�yฉ๙สทตยžQ ]าk—RGow\yc1ƒ}ํ�/“ ห!ำ0‡ !\ืภม็Oก&›uุ\jŒs5=3I–�1ฅฉณณ“Œ �Pะ5f…�ใN"๒็–94H อot‹ฉ1�้ฟ๒NP@ญ‘ถ�Qฦ@€ ฤ[๗_Mฐn2zU’epœ—๓ห——Wก5/ฒ็๊ฆเQo฿๙0�– ˜ํ(’•b@?อ>{>Dฯ…•ฤ฿Lภ-ธUO=ฌ๕„�OW็4‡’jผษ2–B�ญ๖�ฐคึ^B_™‘�ฤฑำ1ณผ๊<ภ‰"ว6ิึGฦ6 ฑcซ‰ฌ�>๛ZฤgธfMา“ีMžoวฃ๊hA[เ,ฉะg�๛ˆฝญlmLg์ฅฮNW{์F้‘…qญฬœ›Mดฑึ–YA@'๕ฑงุ':๐Rงœ๒sงŸ์q.Nkฎธณฐfู‹�dณ9๛<›๓lg๊ง์ูvฺIA›€h‚"ฒโีc$๋๘ ้ะ�ิ๋p‚?$r�šx๗.๒*ฅF–๚˜ h”i� ๔ค U๛<๊,มoหa๖N(™Aฟๆ“ *งฏA{g3๒ำC&˜� U™ฒMํก™นพFะๆyvƒj}Q}†่ ›ฌเฃฑืผิ““”ฉV'ำ๛ O“ฬ๘vy<อL-a กต งษ‰qส๚ฆจ฿ง6๚I[ฝส8ปฅๅ48>–วฦ`ััs M ฯ z[AะลDƒถQ›mˆ(!dิ๕ธ์๚฿-z ผไอ ชZฺl๕ ื�ไ�๚˜&?ด (!๖BLW็+ ๚ฐฺl�H;้ จฃ}-2l™—Œั‰>Q ~คพ‡6ฆˆไ :™—๚ืั”›}Sื๊ ุหฌ�%{ยEU๊ซ๋‡z-!Ÿaำœฤตฦ:9แa•ัƒฃำi~f‘ '+ศ? อ“)๘7t5|Xง๘จฺ+ูห๚‹‘�Gุด�ƒ๋dสE|ฎ5ศ#0ลแ„žล$ŒŽ™vไTฑ,๎กิxwาX]C9อปa็ิQา๐อบi'์ฒ Pฃ^<mVIcอฎฎ๚,!๘U’{ฯw๖๕วšNS�โ๚�˜ะฅ–œf&ัฯฝˆHฦ~ปŽๅ๚๔ธใqฎdฒ„!ง2Uy*ึž�`�=Sž‰ˆxV™๊๛x๎�7฿q{+ฃO{จ�๑O'O่ ศš0๎ส๔ด3†al0{VHUg/�Wb|Vrภฐžj~๐ป�ีo�NA�๕Œรษu~�ฟุ’_~นฒ�ื๔Oฟ๗�?šy๔‡�ยWฟ๚•๋[฿๚› Mต๗ŽŽ๗N@ฆ›็gๆ —hฦ1=5BภดมX.้ ‹+ำฟ�แ0้ัรก๔ƒ๏�d^Jy(เ~ƒiQ•ˆสฤŒ‰J�๚O•–ยlฦ[e่ธฦbุ=Œœจp3Ž‹h� ^ค˜ตทwโ@๔ฆแฑ ไftปU)ฦ!เPYŸ๊ำน*ึqโšf^ ๚ชqžPSQ๋้1jถ�Yร๋wอ$KZ`Žธใ“๚๛๛#ภ2gFลCฟ„s์ษี๙PAl�๎—FสzG{Iุ(GวYJค ูใ‘Aแิxำ604€Tฉ ˜3๛ฆ‘\'0v“e fO7๙ท่ฆ&?”ธฦŽฎg(J<w้ี:฿๙<ฟhฎ๗๊}้๙ฌ‚>๏๗wาZๅม๑7žMX2hผ/๗ฦg”5"jํ>ุ,*‡็ฐถอฝถOhl%ม}5†๛|o d_บrํ2?ต$0a๕๗pศW(i!`—Roc!!๎‘4ˆพ ฌ”๗จQ��๕ๅ็fd"8~ฮi Gdกw\;๏อ์@ฦ)Vฺ}xฐฑะ๒โl”ำ๐‰�[๊�9>™ขq'OCNz‚็์ค๑u/,ืฬ5RFuŠ5ฌa0Yำp�{dอฺ6๋๔#ฦฤ9ผ่๎้ c๕l�,ุ7ผ฿ๆ{๖XXDฦffงใyคp^์เ๏Elหฒัiะะะ“ACซŒ[ไyr|ใ4ฮษ์ฬlฐ๖8kž)ฉม–Qุิส๛6ณํณภWเ(4TืFแˆร7�yQ‡dL@ม้๊๎nง๛�ฮVMฅ•ๅ5ห™ศ 5‚ฤ;–lใŽ8„sbvBdพิภGC๊$'9ฮYๅ&pึว,–Žƒk%•o‰ภOJฆAd3ฝ™)39G‡ูŸ’t�ตkฐhNล๚{๎ศ"ฮเW—ง‰๑Qฮไ บฎ`3‘€qLฃผorf"š(vttA�#†ญ!ะฆฌฏ@|ห2๐฿6ร\#ˆช lAเEง๑สีkษu8 ๕aŽุœคqAށY &‚-|ธKtจ*ษ˜*�่N‘hM๐ฏพ๗ซŒkJŸ~v+-"ท6uuฆrบKGd–Ÿ|~;พฮŽ๎tk[ข�้ ˜ฌ!@Œ2�็”‡�ท?Mcฯ‡า12ึ ;ฅ �`*}๐m†}Šl˜Œƒ‰ษQภˆฆ พซ“ฟ๘ฌ,†Cญr๖� „qGgw์งำ�๛Xปล็ ๔$๐็ฑWๅะ–๋hฺhะ .R?ซg'่ผ?4<„ใsล€]l7๓ู๑1t&”eฮt>๒“ฯ~�š S/& เ๙U€< ะE—ŸEฆฮ๛ๅ=ซ"sศใ๕ga�†!ศgDณๆฅส›ใงTมอŸ}i�๚‹�์Ÿdฆ๘ัหืลoy฿‘6 ]ธว๚ž่ภศšำฒศ:ฃЇ็็ฯ–ธ*๒”ระกฒธMtฒL7uJ.keฟkd๎ํ/a“Q'ี( ภ‚๖NQ^?น๕1znƒ5ข\=+จๆ{lv™™Cฐฤ9ื~ฉCิ•ปุทศPw๗"›ล8‹d๛~A=หIlŒ็Xฑ)7›^นr%}z๏4สศ”อ[ /กพฮ�ฯ9k฿�แŸb3งาปoพM๗๙&ฮ2อb‘กแGก„—คี…}-ภv�จีๆfs3i=‚€ tฅๅN๊ฮ$ด๙'<“ฮ๒!v-ุ\<ำ์์ถภ,ง /:g� ํmฉๆŽ L :๋เ”๕@/มqkŒ ่:]3)�–1Yš$#m›PNฤz>๔,ุ\2j›[š)E„ไŒ4�Eึ–=”๕c้‘eฺไๆๆV^�Fน$ฯP๔ƒร#่‡Y๏Rd“d19ˆ!AไN4�หc ไd๑\ป‚jุR3’6lป ธ รำsฃห๏ู๛โ1%3œ-๋ฌทฬ€R^นF�*`ม š,”€<2๚ŽŠG63uึKหหผศD“Qค@„‘ไกWv:vทa%น�/vศ`“ฌซฏิj`tถ’ๅ|žw™™=pˆlyv ฺฌ/๗บ๎‹๕๑Ka+๔dธ�เaบu็s๊ย‡ฑวฐฮVูsฒ œk}ขศHHฒ/9ศภบnต�…ฉ‡” ๘\๔ฟำ]Žิ[ศชgL๖AQe ”ำ•มd„ูุJ†๖VŒY„ฝVUNฃนเž-u”=ก�ขฟ`p+xฯปฅญำ™/Ÿวskoืฬ๒ มuU9rึะุN†)=€ข๔GวfงฒNl�9`�`’: ท˜„ˆAฺ ๖ญC๚#Qข77ษAnฐ˜๙>& �EN]SY{�๚พ๚A&ธeดDขKตม{ฐ2ท_jBฏ็k�gG?nบพผI฿G=่e[บ๚QJหบ ฑ0xญAฌมkL•แ~];t หว|ŸE6ข๒‚็ฯ๗YB ำงŽๅ์™๕G–ะญg€ญ[›ศVใฆฦ�บŽuสๆ็ฦพึ‘ฯ‘8Cๆน?ฯ˜LF๏W—eะร~แืqำฅๅศf!ฅ:ศร•^ส›Gi M"ๆmฦสพ�ฮu|‡|bฆ�๔ภศj;—::่ก„,Y8ทผฮyค�kศœ,c้—�z“3BI*%U๚PyŽ8ุ€s|ฉeOสฺิฬ6ๆ(k-hbขO&” อส �ี…ฒ8๔งํ{ภƒ๘�ุO๕ฆๅ�Yค99พฆ�f์3ฯ๎xpO>ฏ๏‰fŒ\ืธภัํ๖เ๙K;ย๛‘_ง˜ˆั–{„/ฯ~ฺ๏ย๑ัe6 ตœฤXล๛m‡kun”n“ks�8ืพวuถVะ ฦ5ึ ุ&�ร 5[กrFLx?†ˆ๛ิ–}pศ็mณwฒDดR1ฺvo^K๎!ห ผศ@>rญอ˜r<Ž{jG Ÿ;C็&Kข~น฿a๎ณ†T#่}XJ`เ้๏lU/ƒเ+Jุƒ< ฟอหฒ’*ต5๕มb0gจ‘—5p็7€จhdธ}†`'prpR�YŒๅ~ b]7›็Eฏœๅภ58ki‘ \D <qkN šํ�@ถษZaวอาN#Q\X รg‡r‹kqVqv7i@็�dƒ'ฯฏ'ุ& Ÿฟฆฆ,๊h ช d”ฃp„8+๋|žNbY)=๊่ฯzฟเLุ๋๐~3ฃ 2;>ก๙฿รปา๒4  uโหสเ#ำอ›oZœ#ห9>�๐งaDฏ฿ธ ˜p-dt WPยL �๒ใ LอLs†ํaเXะ“๔�้cไ�qwงi#ฟIๆ�ฒ๏_�ใPฯo3N‚ TuฒŒอร๑rฬไเ๐(c!—#hูงึฺ`ะ ี!บโ๙ศ3ภ…dพ1uv๖D)‚็Uฒฉฉ%j“ฏ]นŠ.]J๗ฟ๘‚ัฒ๗่3Œฆ�Ÿ�ฆ!เ™œO~๔บ…“ฉ ซcฏ,ฐณพึ]3:๖”u๊อd๑๛.ฐ7สLภึดท’6Q!? ^ ุ๚�€ ้๛ค�Ufสฑ_ื_๕)ฅฮ>&์ญ�‰rใ— “๋ฅOคช#Ndต#›ŒL>|‹ไ มQ$๘\Lื7@šfGs+ ๖ภt•ใ ั3ศŽเู_ฺB}�!๎m–�#ซหะธ้_ธ8kcIdœภฏ €~ผก{เ<๒<‘ญfฏ\—c|<0‰”รฦš"๒;_csึ-ฌ?™OฆI4ZึB&4›ฬq =S._่ฃ—ม๙ิ�BsKJ*:iˆ[��K :$๎mหp‘M`i‚@0L ๔พ†™kฟ๔A ๐ด๊ขฟ๘FHk7hs๊hฬ{–ๅุCจๅศ๗>u฿/่ลSฬ9/วฎิึ6ฆ๋oพห}๔Hc๙EI)๗ึฮ4๔ธ€ตฌ ว1ฺไpƒDม*Saข๑*๋#x๋(ุmสHิr‚�๖UtŒn��ฟพs่8”˜ ถ๚$9า์๕ ๔-• ํฎมข๚ฮ๕ฮ$๓2ูt{ตx*ิMAฯื๏โZ‚�ผๆ…�;วฯ๕ตน?์โ๖มk†^ๅN•MYสึ๐� [ฝc YW2 ,ƒpelˆŒœ ึi‡d†š,ษ<ไ6รn๋๙�฿ยวโ�ํฯฐป2๎Ÿ็๕ฌฑไGdฒpo>ฟ์วฦฆ�๘vl=&(qi\๊่hแ,ำ›r4๘๕7ฏง^’\�}�${:šฑำ6๔คค�ึ๏CtจI›r@B'ฉฬ/าฃƒiX‚u€ย๖ัŠฒ1๖Sฟhฝ33;ุุ#Hydฮ* :พท ๕ทrจีN๑๎�X๛ฬ˜xr��7� #cืFูEต‡ฟสฌก2 p๎EX5ํiุN๖Qฐาu2๑L~/X ˜เ˜๖2๔‡€˜“๔์Kf2bŸค�!6�i#ีLษƒu`ำ๋ฦฦ๊CฮีŸ๐๏วฟ�?�O#฿๙ฮw4ฟฟ_ฌ๘/ฟ�ีฐนล?๘_�๑ฦw�็�อ๖ห)}๛���๗๗GทปฯึžอM\�~ฑR/zwฎฅฺฬuะ้9‚…ใ4รแ‘ฎ™๐จU@ญณผ`'ะpš›Pd๊ซpl9ษ์ ผ†�ฅb๒˜)1�h๐˜0จุUBf์tL์ ฌV1ซi๖UIฅ…~ย!U๖0bxy‘NQ-]`PDIB จนฬ‰:‚ตPด\หZr—��uฬœM|๕๊e20Eก l�ถBว๚ญจญใ2ม8ืเบfXผฆ†ำNห*<น๙€ภ ๅจBำีฑ๓ไ ธlฏ% ะ{‘Žf=๖"ุc ;$กXCมศ†๐~ฉฬ๔œ722"JX'›ฉ5ิึqMฒ]\3‡,ใ8k,3MY ฐ � \๓ธ_๎'hfhpื�ši)Oฮอถ‰ฅส๋ {6Ÿm-ซ๕ถี(อ ฒYล อ…4jfl฿น:ฒง[(ฅfีืSฃ[๕eUตMผพ @ควeๅฤ>F`�&.i=\'›J๚๗@UYKืำ@ร�–ษแZkฌฌ‡๔฿*ZืU#ฅาฬผeo4pL���ใรFำฝ;ฯQ์ะฏ1�ยVkิาY๒’1ˆ‚:จdรX'^หDำuิฬ๐*?ู(k•ฟ†า,oฅ6!ดๆSิ[ekฆ� YTฃš๎ลภ�ฬฬ�<ใ๔ศ2ฎQV291ืˆ&x๔ฐฎึq\dูPึ `Eี•๏OงG‡๏ˆ์Žดs3F&ญNX๋๙RJ4ฬ๘•โPืใP9~ƒ ๑‡ห™ีาi=<หOส%๕ี๕Pล-ห`%+ฃ ฝภูŒเ’,๒ƒ่วผtD�ฅฆ๒+?ภA�L dH™“•ฐ‰ใc฿๚ฺฺX{$HI ศยศษ|0๒|8M Epฒฟอ�์๋ฆบwkŒ.ด)ีะ0ฅ'ศmtfไcjr<œKƒ�\„s„Œุ M๊จLAสัั็8ปR์ ธฦา}Ÿแก พก”’%* C���ู.๛…8ำ{›5ืy6Kiฃ83/]AEh๎O่"^O6ƒoGfeึC=ถ‹ณQ,ƒ&X2˜tยd95ใn8tut‘i+L}�ฝ้ึ‡ง5jํY3)Ynิ ฅ]ถNฉบ—u~๓อทbJ„ฮ—[1Ž�ไ่0€F~ฌ๋Ž๋>๊! ภ!ฒ{Šฮ�ขฆTฃŽ๕sา…g`งว ฺ ฎg‡ด;็ท4]|ํ•t๑๊@ŒลmtT$ฝ%ัภั›=ฐ๒pค[6อขZํ=9๘<ํ๘!ร6ณ3บ`เYdัO๊@ฯzPj๙ปeYl„`่ฏ�ลฦƒู าฺ}Vมbิ๚ศฑมL-Ag ๙~๕�๕ึ ƒ3e ๚8๎F‹๐��ŸŽVจ๐ๅ,6๑ๅ{ใ๑Kฎร�8‡[`)‡ฒŠ<ฎํฬฒ9แ0rฑ{™œ`Cpxนม๐ )ญ0๋s~`๊๊ๅŒcŽ\€ใ๐ะ›๊-KE,qฒฤ๏๕ซฏฆ‹็/Dคล้i๔N8z�ษ6zีแฯลษs6ฦ3eA้พภ3ฒวฌgPq‘ุ2ฒ๕šฑ“ต”๊QฯิgE ฃ฿๏asๆ††๘ณGร๓ะฃ'4VอI €�ํ๔)โฝ๛Vุ์yั า�ฝOƒด฿วฉฃซ3�[ฟ๑oวืT–ึเะSสค–Yซj๔ใ(บ๛9๖ƒฮๅ<‹ใ„�4๛˜ฆ/S‚c@WBๆXนต7Œฃ๛V้Sิิnฤ_‡-ิ6ญg^=ฎำ_LP๐้ฝ[ฒŸั+อilv2ภ๛์Vs{3ฝ–๚cšฬเˆ%ndม ดp—-Q1cรูU‚˜์�ถZŸH๛c&�3- 0ldrกรฎ�ฌ`bD;์ฎš Zถ๑๊kฏr6าวทn…ฮ8๓KŸ(Ÿ=1ˆี�ฑญa์ƒ$+ ~ภ=8S}ปvฬg—มึ Ÿ ิ† เสฬ๔^ Ž-_)$ี๗1 ฬY๘ศr๔6@_Zฺ'เn#ู~‚8๊๊ง&‚[๏�i�ทgS๙[BO�๚ษg้้�‘ด:ฯ8Xสตษฆ->ื~Gต5ฦ=ืฮ๛2๐;@ojณ fิŸๆพ•ŽSฮ™rbฐฉo๖b™fง”_ๆก@ xr);-ฦ๎๔ด6ฅWฎ\N�็ธ&มฝฎLGK>rซ›Snอ0A2๐M�ŸL›)อฒdD ุ์s†m€ฯฤ}ธŽ@|่4Sฒd;อ๐ฒ"gฒu<7๚๖_Xคโะำ‘ด05ว๔‡๕ด€›พฑ2dฃ@Ÿ_'%ฮม6๋ฌ6”ˆีgO�_m–๊ฌน*‡n/{ื52€ื๎g|oีŸ}Sel๔–ืั—ึ_ถฬ�=PถE4‘ล'FPฮ6#W;2ชธ>kแต•}MD ž๚o—�/*ย?#ศv‘Š๙�,kaa้า้Yvž aๆ8„ฮF>ฤY)๎ษ3 ช34Pจยฃท81‚…+xp�นAE(4–™(ฅAู[ฟUnfi?ึzI๕Qุ5œ~™u†ญušว๙ฏu0ฌOzใ๕W"ฐK“dิžห™๘ะw�Šฺ_‚ฬ:NU† ฯjPูZ๖Qอ9ม/์ฦŒ,ฒV"ึพฦŽฦึMปฯฺ#m65u๔ŸOฝ8‚�}ํL•a ึึ–x)๒ึฺด[:่/>ภ๐„�{mmmฉ›ั2˜(ณ‚žG/บอM)“4๗ยyV6K8—ึ"j ฒ}ฮ-€ฯซ็฿l’Ldถู{G Y*275Cวํyœf(2C vkธ/^GLวส@ม์ฝ�ป�A€ๆๆึุรu๓้$:žQI&†rํGQ{๏ป”uนIะ]VZC9= œ>; •lŸต๑v ฬ\ไ๗›€)/ะw๙xiร‚›–  KฅUึ ดดดXแ[uะเศN�0F`†sfำด้น™จ _%ะ1@lljN�็๛ำฤ่xบ๗้ด0:ESC@)จน:‚กuํ:fคฉ ‚๔ไŒฆปท?žmเ„c35ษ,f-)A7Y‹ฦ๓็S ?›แฺkะาฅถoRE�1บApA๖gวyู{์…ฅ P๋ัลั\ ™;Tด)e�นๆpD„ ๆบ;บาย๔Tบ๓ใŸค|ฮ“mุ ฮ0+>หฬี Ž’zRา`ฯ ŸFFZG�”ต?เ๚ซŒ�G—๘ๅบ{Xuzu|ิฅฏ]นˆc�“&(e‰SหYT๎ซ&จ(หฯG�h�ภ=ซsอjq=ฟ=ฟ�ฬฯ%�jเเฝ๘m†ˆ#G‚nวQ+Bqัำุ๎�๒’˜!ฒ#8q“‚ถž>ฯบL&ไ •”'2Jฑ�ฅr๋ย Nv๐ว:6<ย4ฦพมb1c'8บ‹\์bc ช\;A|K๋ฬึ๋,vtt ทฬ;วFน.๊q฿ฃ�6Hั‡�Uห�kq�K-อŽ-lD'Nฅ‡ฯŸฅ2ุŸ=M�์๛฿KฯF‡SgKc์\x๒๔a๚•/� N,oK{z�ƒ?KCฃ#้ˆ๓<�่!ถๆ6qjd,ๅเฤ_~ๅี๔ ฮะ๐x+U•Žณ<ฌ์@อF@ูM€K้�๖วฐ)ช๎ฃ'wcšŒ็ฺ่+ฏฅ&|,ฯ“€‹ G่_tฟz^ฆข๛diิŽปท"ฮƒเญe"Y(Gฏ+Pฎ2;ฆ๖�I๎~q7ุ2žG๋พ:๐ฮ[o‡ฃl’'RฬŸท` ๆSฤlวzณ€6NตDก =d’`}ฑMณ>ƒฝธุa)๙;๖บQฦŠ jจป�๒—ฟ”๚:; —าcึ�! ฃใ>[ฐซf%.๔๕ส\g_ฟ?-้)ฃDI*ด2aฏ—ึยษ'สl=Y ^2ๅm€�ศฌ๒g ‡%pฺ7ง(hฏQ!๗๊Q™ ย> ~n%`ฯ7�ค,ดF&็ยO['po`j๏B๗ิณโu๗16ษ˜O<›M/ๆตปNHก ฿ฺง ์ ;Wจœ$`ฉ„ ญGฉ๚แ˜ณ*h–รตpน-ฯข>‚c) ƒ>ญ]฿อๆ�/_Hฝd๓ทIRะ#๐ง€ƒู๊–�ตวH\:Nฆ:๒็•ีฆ3Jฐ/ู‹๊ม„šP.๊ƒa�žLrB‚ซC“ืUศ�๓\ (gนศDvS‹“ €ำ่น}ๅ  €้๎ว?%sK๓ำŠบ๔๘ษcJ{๏Nใ?ณ€๐;่d'หjdัDฺ˜ี๒9�ฎอ~1fX฿2ฌ}ไLฺ�๚}Ž2L!^†ฏƒžc•{FGmส$ำฯด๒K?หภ\๙,F๗่3ํฑf๊๕ƒ•U?#X�ฒf๔…|ฝฅ~–`ŒฺMฦŒ ก-ฝฑ฿X$m๘ฝ๚}M�›‚๖)Rฯูดฯ�๚N&ŽN`๛"‡๙๘,๖3Ÿ?ŒŒ|>๛ษJ 0แืHKAS;มIฐภฝฐœB_ึ์=Gฌ›R ฒๅต4๓ํํํ YŸ›[ ะ�R�ๅ•E| )ึv|j,�žb&k}๔๑G้1`ธSoถI”{X",ใื{^^\K๓0VืW๐ฝW![RSk“บ�FtนษS|Tพ�ตม๛?ป๗เD9`I1พ &eM“ฅb=‘y^ฏ]w=ถ`+w่+W‚่ปOฦ2&๐�สี>ฏซcูท์#ู‚มQnฬฝ{๎๔]ฯXL{ฤB๐Z๕ฆ๑ฬฑท6๗6แŠˆ+จ็น�๏!3ŠR†์๙ล๙;�ๆท�ึ‡55}™๚B…๊เห๓๕หฏ�+แ๔�แ�พr็้รŸฮฯŒŒ<พ๏•ีญส-๊ฎํ<}’Eะ”รด‚#t4t ‚kˆRโp่G‰tYฟ'MMฅ?G่5^�]ŠธCƒง!ญ�๚ฒ#ค3•ฑS19Wึ:eƒ]ƒ‚|�†9,Q#,ปN๏โค™ญœ'b]˜๔ผP^ ฐ�ๅmžb6ฑˆ์c †€O”v“<ร8๘jฮ*–๊ฉฑะ๘[[ํธวผ•–ง†ชtzคNู}Š*Jฬ&mสKS๏ซฉคใr:y8ฒ:‡L@“fjœ—ํ๕kภคืZๆ`ฆM+หc…Tถ"ซฅqใ‡ัร‰.eพ๚I๚๐ณOำำ้๙tš_ฝ็u<ใษœJ๖S๐เ„๗; ๖ƒญศ๚่œ๋4๙%�ุฌW€^\K๙=ฆ“๐)NQK[#๗YZ;ท`L{d#ุ่ษ  „€RฆˆŽฆ๓จ จ…ฌ…‰ก์’œ˜ๆู๘<„mฒŽtl„–๎มrพ๛๋ ›@=๐๖ฤญวX k๙๔9แ~wดœฃ^O\ŒCฺ�ี•jรฬฌ@�<;กฟ2ณด4C—๐ล0พˆึหkภt^Eก5ย์ฯภูœฮฮศŽ?}Nญ=๗ใตOภ$ ฒห=‹r็๒<fฒu› Zฃฟ4‡Lเ ตจ„…ac= ขŸ]— (,ฬžญ/S_อพyถํQQฦ๙tพท4ูๆ&2ก8š(๒š้ฉ™�:ฺ;blแม๗ใ'‚ L{Vงงง์แ$ exey…ƒA๎™ฌ;AY#ป๚า๋?:2k้Œ๒2นcฉ๚ิจ Œ์โุๆYืฐ็เ๔IตฬaQYว๘•W�ม @ศ`Pพฏ๔ร^ข„เูุใœ๚ำอื฿„Iฒษ๓Aํผ!@˜ใฬถžc:kา๑rC๏�๑ŸคC€‰rฮ`๚ร,Šrณ…ฃปย>Iล–แbฉยุ๓ม๔ั๛๏งษ'OR๗ถƒcพม3:™๐Š์฿,อ—a›ะุ‘๓yผฏนp๔ฃŽฮ†2tŒ ็ะ�๏ˆตส2ำฯ4’สŸJh2ฦgๅฒทรc8/d‚๋จถ\฿D9ฯH0ว™แt๔฿ะƒiไ�รTฮ~I ฐษฉ฿9๊<ttK|‚MFž‹ฎๅQqิ`ำเฌู่PปยKใ>uธX ‰‚TY„cร๙oิr„เށZ่Yi0+๘ D gย`XPœmr|q๔›[i|ฆฦูฌัแดับeฯ๑v\N[•Q‰–*ž’Q์Cbใ7ณkgojW›'ๆแะ"Z€<ศ1:ธปฏ7œ@iๆUdณ-ุ๋ฆž�‘จEศŠ€่{บ‹N^”;่<ด๎› ำพอz ฐzตtถวธิM˜:”gุอฅนYุ]•Aํ7ธญd"ภ6YPฝ๐r์˜4ิr๔๔!Tymภ๊สR4 &@/ไี“‘ฃ }[w๚ัOnม*\Š�้้qFช๖าฑ-�๔'ฆปŸ}ฮศๅ2}ศo๖™๛4X—iเ$  ;œฉ จบkmณ ฅฅ่5t.๋”Ÿล`oทfรญ"ฮ†ม๊๋ฑ!ุ่ั�าJ0ต˜รžเ++ฒ…ึ‘uูv>Ÿ๚^pl™� ฅุ mศ฿๑ฑq์veBฯiฎYHƒา>ฎ]G.—9ิm๔ฅUL๋h๘šƒ=y๐ึ๒๕D-]๒งก�?žโ:ฌฯh�เEะ4fอไ๘91๕ฝ"รO็�Œฉใ’s\้�๙ศFi™๕ห›idz$ q†สYƒhšฦ๓ถณ๎'ฤฮ“ห ๘yฉญณ;2ฟ›€f2G t๔€ ‘ |%ฮ ขz๑€จ๕*ถ๗ฑGว๑ =.ˆฎฮ0˜3ภrอNFตกน 1\ฯ™e‹�.8bg-�rฺŒQ ฦЁ”๗“)#ก>ะdnjฆฬSQ เ๓ฺM|ฐ(—แ๕ศษ% ซ3ค ™๛ฐŠ ๒๖ะฑ€ๆlP$qrัซ`๗Sึภ^;;kฐV”Wฃ/�(5y5๏ฎO]อ๔๎)๕”[NJ“>>ณนQOฮeA”ฅ\ฮN๘n๑ม�G`B[ฮ….ๆฮY'–‚ƒoฒD= d�€^�แ�- ใ—มฦ#Ÿบ๋fƒ~EdๆS!Œซƒ๔๐�ฝ4�๔,RฦSาดจฒหZo :๎b๛�ถ”Wปอy7)ฃฝา฿<ƒf๏ฟ๓ธVIY 1š๑Œ;อd…๚@�ญ6ี฿๖พœศขฤ’i hค–ึnขK G;o`ชl8™กœ๓“O"NŸ'Wyัฑ`M๓ ๔ถัg๖tฑAถ๋โ8gY6Eิt ย'(!Hอใ–Ÿุokข๓ฉYำทHศรpXŠjr'นtบุ&�ฝฅ>(O๕ฏIH์ธ?F–๛ุd�‘จ–z��H๘zโyL๗r|้พเkป†+dอ์งQT›“kฎฤ—#9‰F]พธ€„N๐ส>ฐQtŒeE”A�Lฯ๏.~๑@7�ม๚/f๖๐”Dอ๕+๔้์{–ย‰‡ร�ูWะฤอา—ฯโglS๔‰+ฬ๐ณณ ษ9ู!36?คฆxa^{ธ;อฆฮŽFถ pS'd49�Fตฐนืxฎ๑oฟ๙๕w�Q[}๓ท•ด_˜/#ค_~�kฌ€ฅ �ไ�x8๚ั�๙•ฒฒบ+$Nษฒเ(ฃภOQ‚ลฉิ`™‡Ž�c€ฐ†|E6Wcƒำ2i t�๖ฝ*fƒ๘r‚•ฎชู`=^3วมฑ๓gฒT.fิ5ิRzTถไ\2Œ€H�:tI;ซhผ'ฟืึ`ชˆ�นิVปๅๆใDฺLไฦ๋ฏGฦ\dฐฏง'่’บษ‰‰4‹า9D๑๏’ๅ๔�3(-ฮฯฆ9ŠNซีภีlฅฅA5D1šyN�nบkโณ๚�*cW29ขJ๊›™QฉใEh3ิา- 0)งQœฟสฑ€ ส#Ÿูw•-ฯd`๋๚พผžl`๙Ku(ศ์™เ่s&ฃ/ลL๊�Žพ7"kfNGี†Mvl/aํ Q:ๅ"ฃ<ใพ<.ฬ˜๕Q‡ชๅ็:ุฆแœ} ก ๛aๆAิ{�™Mงป›ฉฒฉ…อ(NœG3ำnฌวuฒฤมgฉชฉ๕Œq็Eอฅ�๒O๎ูฎห ฺP‹ทAิGฆ่ล๑l ึ‡��#d/œ+Œkt€s็gป‚�‹ŽถF4จ“ฌ%?เ~5คฌF�uำจๆณGjtฉฤซฒšษึ”ำuืšSŸรl˜cู ’๗1^‹d] ๘:ษ|ใ๔ฮฬฮฦg์z�ดป8เ‚#ัิ“5[_ฆ฿ hj{<œ๘Bฦฝ ยVYป&#ก์ŽŽvhf€omิ{Jm��_…>\šฎมิ๗ี@ูณ^_บ|W{'ืขฏ20Gาาศ8+† ถ92ำฃฃc4dคD ะE2†›๓ฃLxIžnA7wืlผ†9S—ฉ<0dhŠ�™ูW‚;ณฌกฅ:ฯ:l–ฎ๙3ƒ�นนฉุwู=กDยl๎ฉ|๛๛‰ฑ‰4๘t(ยfุNI0ำ62:‚cท๘PGecjj*�ืT฿F–้ƒ}ม�ๆšu�:M<gฮัฉ™ๆฆ^ˆ6(�r$\<�ตžR๙ฤ4€AJxu ?รฝ�๘ู�92Š€kPัe.(ณ๏�๐�t๛ณฯาณ'ฯข๑ใze๘๙ำ๔/�ู?;J ฮ็บ^;zvpVิฉŽ[ธt๙จƒIa-๛)NWู_iฯตะŒke ‡‡ฃVspๆฺ{{" ™\˜%๐o ร‘ง„ �X์ดKู…’J ไ ‘{€ฏ>UA7ตทอ ๎ถ"{ิาา€ืูฒฉ๑Itข็ุu@sอB„b์�#iG z~ํsฃฎ4˜ส!8q�5/ๅา€ ๊SVฮOƒฅ7ˆ5Œ จปœWทฦ8(z€ภูื)ญmศ#๊ Lื]�Tu•v้(ฮ5{เแs�`jT็ฃฑฅห‘&ึj— ^@สถๅ@^{ Mxq�z:้šMœ&JฐH,Usผ—Žท๚vะๅrzฦฟฃhŽ๓—ร–„`แ€Wpเ๒Ud”ป ƒ๛<›Nป 1ฮX๔~Pžjุ๋/้]ฮTฌƒ1ฉแpหฌั^81แ%*žป๓ำ7 ศ@5ย(ฐ๋ฟ๔๒ —X$mqQjๅ6…๑Y|ฆอ( ˜‚^-�’ณ!M� ิ้ %่zมๅm>ƒ˜�๗qo๓ฌ๕@ค�%2ฒ๏`•9sพญ `L:�HWฮงK7˜r๑ฒ�$ฒxณe ~ :;–๐ํŒ6…,มg•อ(หว’ห2€#G‚สVSFผพ�H&Œ�เG๊v0หฌ#้๛ๆgา�์(kุNภ|pศูวnŸกƒM€ษฤ#QAy#ฯณฐฃoQฤ(j^w|ฦ๙ ` ฿—ต—!ไ^่wส๎0ภTวฉ[๔smาห™ŠrU๖?สNฐ9\;?eอ‘bM ™(r!ี�>W”hเŸšภด๗฿๎e”1โwrณqŽQlผ�-ŸฉฯฎeR์i24x4˜‰จRt\>ืpj˜เซฯ ฿ฎŸ!ธ—ืึŸ๒๚&”ื}d;eข฿}ฝ%ถN�*@ึอ๖๋฿{ฮฤเ฿ฎ•Gอ๋หเ๕~๗๘เb|s/~†eก๚ลk” cKธ ๎ุD‹ๅ<–ีูด’žc�n`ah?=>:V„Ÿ-ซ `โšอY�H่ัCฅะ"+สษi๖ H6>=‰œด๑ูS่J'™4ŸkCึ,W3็c{�ฒW๔๗g๒I†จ ฯUฤ@œ ํ ž0 ŸWgฮไต,bž"zGJ8ๅฤๆฬ&Plสฌ�นฐˆ่sฒ(๎‘ถฦฒ:ŸUเ†“ฤ๓’:๐ณนŽ2๊ซ9ยท[*f‚ฯฉgK–ˆ2ก]li•)น9[Y]๑๗~๗w~๏ฺ๊{iZ๗m>แ๋K๗๖—_�š+๐|๋kฅ๗๎~���=ฺuW‡c€S ํ˜เหoEUƒf0็ก3@W`�ฟ�3pั8 *Aฅ‰ŠหTP๐ ฐqฤ�ใpธซ(ธoQHฟญห๎joBะํบชƒล๕๙X็๋๘А/0.Jƒh@ˆ-‡Gสณj› ำ๖๖๖bDŠำิโ$†v” Šี‘[๚ฮวˆฦู9:ืOM ์@ TSฆ>6 Ÿ›FA๛oฐฃ“Šกสตงถff˜ใ€๋ด๚l~ูจFกศ์ษี€ฒ&*ิศึp๐ฝฏ5(xใัจฤ†R6โาุ ๒4�กf๐)ศต๓Eใ…ญ๊snแX…ย`� ^\Kˆ�ศฌ}คศoƒ>K1|ฟฬ๘ๅeิ ทั‹Ygšู`ษšะRงYC@ใ่/BMNviๆ„�œส[L0เ4Ššte“Iฑ6ฎ๛๒๋ฉช๔”ฯ\งLม๒ *v๕\ไ๓pฤใ� "PฺRี*šz xiJ5Aฝ,ŸภRIึู | Fˆ_y(i฿/�ะื๘L‚"˜O$ฏร(a ศ �ไำ;้ษ(5�นŒฯE�ฅแ †ฦ1F ๓~eึตTG3กR2ภ–†ิฯ๗:hiL7$Gน„{)ล .Bž[[านึ&�f‚.Fณˆาุ rEช x ฬญ/'Xข็ม“Mlฺ�:‚’ฟHฏƒ]๖ิฦŸาK-M8ฦมฒ3ฝ๕pf4‚–ฒ์#˜ฃจ}ฮM๖pfชzŠ ท๊�8^พะตณฝฯฐSส –::บSฮณT8eF‡Eฺ๓๓ม็|>ฬ „๑๑qวฆuaเa:เxถ๙Œ<L/เO{�y~\Gฉ~๊;ฅ ฮ`ฌ์ฬk9‡FO็ฬ3 |้ิz๎ka� +“fวtข�}4TeฯG†Gล8ฌ G’U’A�๓็:ญf๑WMฉŒ๏ฏซก;ฌ kู2;คgณมŒ9์ฃŸภN๚้?M“c‹|ฯ ฌ๐�fศ  tษ๚ro�ภฃฯไน5HP†ขก)จ| ฯฉร`_ หlŒทhฒศพ•มฬฑGฤ๗9ฅ�†˜Ÿะ�จŠ์4™Zฎ�ึุœj(Mšœ<"Sื�า•ฒpจู” ๅ�ฦ…f๛ขฟ 2`ืๆูู้ J ย*้Q�l๓ฎDg๛uXkœง‚ิ‰N+b� ศ:๏๑eœmงีdท๐๚>รษ ž9k<๛ถL็๐]ฮGุpฦq Zฎาฬmเโำmฦ ๅึˆฯ“ตญ ‹“ƒƒ4๒„ภs|,ฮi)อ"ี“ึ๙*ฏนœs!ไdล๑PG€t�้ไ‘m7f๛X_หผฮ‘ ื9ญไบve ฝ๕ึ4ว|#]่ [\‰~Jฝ`•=4d—ตตถ… ›| fj“์—`,pV†<๔xdขูsไู็๗‚ฅU€_2>3Ž์ำgก๗โ๗๙9๚x๘€ฺ[ํ8ภ‰},#๕^์'ULvด€๓\’ ๘W’:{S5 x^# ็Š่œ(9^ซ;›_lฏ๕ร�อ�{ฦXšf๗}ฯญœใญบRWว้ž้ษป;šไR%ู!B๚ H6`ถ`x-Š’ธฐ,›X›ย’>P”–i "ติ.‡z'๖tOO็T9็œne�~็n�– Aah}0๛jบป๊ึ{฿๗yฮsย��ฯ9€ฉ๚•ฎŸŸoยฤ/_ฺ%� hพ็S|›ใ cงXS ูุ€Jeาุำฆฐ๊ํฬ&ฝr๔UๆI�๘ห€ …ศศ �ว๏๕g6 Ÿีฉำ@IDAT…๋FษบUอ๏ฉg๕ม�›ุšแทiฒ‰)A~Yาc๙าเ–๋eึูuืฟSำ‚{๒Lหเ๔ห=_Eฮื‘iๅT฿ะ฿๓K––zรF†ฺMA;�Ÿ"?ฺhฏห๊ฐ่l™$๚็1มฬฝโ็๚H~F๘��พgoวฺYฦ%˜ec๏U๔ณภ†#7KัEฒo=3–ฺ/FY๑wƒ๙‰nต็หŽฑฟsสฟm๊ธ=๑Oม~Ÿื€�ฆั๚2�B่#“O>งLA๏ูๅฺ๐อš„ฎรโC'ศ๎q,u%gบฏ‡$ 2?ฟผฤ„”˜๐b2ย‰^Nh่๎kใ{•€G๔D(ฺG—ŽOŒฆ๔IgฌฟdยiO”ค,\˜่,'frlนƒพฒqผ )�rิฃŒ8ฯฒ๛๏่หUโ—ข\z๓ญ—ำน‹gi`K�0z„ุp{` ะซŒdโH0!,™@,c�eBช�๓ kใ~๓SKฉ<E€๖คฐ!ขฃ้ซ๑[ศ๗ค,~ข=Rbไ4๖‹ามiคๅืzฯ๔�ย/�ี_๚ง์้โ?œฏ|ิ๔‡๓ูฟ๐S�อ�๚ฯ>๏…š๖fŽกŠc †vAฉGEY:าร?E)ญMVจ„�žมฌ€ส$ƒ๛zฎd ๔ย›/EQ˜ัD'‡"p.k(5Œ’ŸpxSบ๖๒EF’•ฎ,ฏ gอSSS‘‰0{o=พม•`†h ‡ำ ๆ„k•ูˆrk|lเt�์ ”์KD1Gญ\dV‡ลฦ„‡uฒฤsำฬ—]^ฤi 3ส][sh๋๙l็8ตๆl iชส#๎๓จุ8ณZซ€UžกุUvj8๒m,vO5รdถg *ๅฃ๗1ส jEmœgฟ†FŒŽ2จฝŠ^…ฃโp=#Ž#a“ง6YC…‘B™๘s�๔฿ขถ"ฺพt. H4ไ^ื๕rๆ6Yoณถa„๑ๆ5$ๅฌa–Zำ:๚0๔vทB๏์รเ“uหม,€ข฿�ี *M ่ณAเยฦิำ45๚˜{ืY~ฮppŸ๓ณสฝn5 HM=๎น๏ูgท+๖ส ๖ ฉๆิุsฐ‰Nฦdj์ั€ข๖…ต‹6ๆฬ ธ)ูล(oBช\M\ฟ‡‘ฐ๎‡น:†ZŽ๎ศ}&X๐‡=ฎยIดใท�2์ฮŸiทbC5k›5De�๋U€กชเ:ŽG*ฏe<e9fอ*ก k๔ฃค ˜ฐ&o†`MgYV …ดyY฿kะc#แแ‘(MะษSFŽ๙�)ˆผM%qนV…5เทุt -ฅBห2Œ]z 4๒ฦŽฆ˜n6หf7็16็0~ะeไHJA๐ Eณ6=3Poll ๋TŸ~๛[ฟMฆ�N”ŒัผQj�<†ั์จžfW"H6กQถ–ั฿ทFq›์wnฏ”บิJไARฮี ฒ†ชคข�์Tวภ}–}"Jžw<ฌ5ฅโฅ15K`‰ลŠ๋่์lลY'[์๗m�8x้`Q&j?][I–5^6Dฬ64(.†ใeฆ๕ร๗?HsSŒ^ญƒICจภKลใธFC'ว!ฺ—A@ภ=๔�m‚่Xฒึีๆwว�ปŽ€]'�sd“Sf�.่พzํฮเ'Ž€ฺ๐่kdG๖ึti๐e ๔NมมŸe๒มg g’3pคผ๐๗2- =@฿Jqิ™›™›šIv–ฌตc\^ฐL๐(x`?…9ภฉFุœ/มฌ3�่โ=@งœe›ํU&™M์|v๛6ภQ๊H๒<šAฺVgx†ไ˜๘}<ฝtํ๕kP๚ค ๖T ?~๖2M๋�~Žlไอ๏?ฐ?:ฑG<ณ๚‡็๎˜��cํrd|tโ\๓‘ๅ1ู๘3C�+่฿:F•ด๗๗\๖าวแAอ�8#่ว…นษ๔ฦ—พใ'gั�,็œบvก,kQ@€ฟK)bตพ<]พr%]พzj)rNYB+๛0x~…m0…(ก�ง> ํ”�ฒ\ง @ฒ1\ท‘๏๏ฃ;Fžฒpะฃ�z”กq„ใ๙šศhZzD�ฎ™$B–}Zปสe)=2s:53‰\ฬ /Œ<~š†?KŸ�๘4จจฒำFอ*+ห��ฎ kฐฎุ—Fุ_6�\Aงš–ฅ!˜=Hฐ,ำฤ5•�฿ึู.wูs�t?2fM๔’”Zณ—m4:์?;๎<|”ฦffS�Wถa‡ว&รฒฬ/,.Y{ศ๙3Sjๅั$จเZf�d9Zู?ฒิœSห0|ๆrไH]กญา/จ"(�ลi/Eึคอ 6๎๏n2๑ไvบK›nvw๗ฦyŸโหไญVง๖œฑ๏ ืฦ6w๔2�t‡�ใ ้ม9ฐิอ์โใว๗ำรทฑฑ4อเ,Sำ�ื;ฆ'gู@‚,|ฯ‘}Nน์๓"(omทAฏb`YJ—uง—ๅ*fzs่บ]พ์IƒโŠg–vด[`Bล๓/ำIฦฤ?ฝN†r4ฝ๚๊๋๘)‘˜N๗}ž>�๘ฆ=<ฮภะ2˜ั้)p€.@่๋ม๒ข๒ถม ui1อ•�O�A๙ะ–่{y.รvs/ฒSด�[฿MFwฟ/(iใหelม๔�%ˆ6.*/ฌ๖๖QฏH�vT๊, ชuภŽ๖^ฺnภƒ€ถjK_%ำผ‹๏Cฉ(XŸG]ญะvjฎุใBฝฎ�ศทไE&„zVV‰Aบ™ิ:ส†ชฐญE<‹uไ-๔ˆhฌฃlQภ/๕cซŠศ้[C+�ฆร5๚`eพน�คE0ฬs๓น2 ๔<›๊sฟl�lเ Vษษฺ$W�u๔3™เ9”y`โฌฟจถฎ)ุ2อmฅUะฬ—LขpFJๅ]|"ว�n#ฆBพ๏๏ิ9JTyัง๑บžูฐfผ๑HโึMะ™T;€žฏOซ9ำฮZซ�uฅl2ูถYหeJแผ฿`โr�ม`ƒ‘‰ 0ัeO!A๑ืะวqโฟต3Ny`_๗?ุ�Wศบวsซแฝฤ~๊Ÿ oชฑ‹ส—๛หฅBฮดๅ>‡ I"{ํ<99#Ÿจ@ไๅ‘๘ลฒJฑŸŽyVŽMœนภป\#๖๛Eฐ|]3ฯ™{ฅNูแ=๘ไ๖ ๑ณต9มZๅ™๕'๕ฑx>NฯฉgผŠ}1†‘ฝW]ทsๅwŽิDฐญFถฝK–m&ช)�?ฺKฃำ�>?~# P#พj๏™�Hnุ<๑ๆฬ`‡Ÿๅžฌ8†ฬฑๆข�ห&~% ๘^/]ฮ€œ2„—bi!uสศ ŠฟŠzๆฮพฎิB�ถฃดฮžํC– ฺ0ห0>ฦ\#{ลC›q^ฆฎุZ<จU˜:\6ฒฯ‚็�lQ5™‹๔Ÿ ณo7hk…\s?6�Qถl๘gm?p _4ˆยฉ1ศ๕9<ใฎƒD๋ƒ•G8Afj”_{’จ๛ฅฮPn=ร๖วฐ๖Q}ะูู…ฬมขเ,ตดำ ฝป#šฉšA“ล�ภพ๔!#สw=@`็ษ€bvz†{๓Œำด, Kuท�€4dณj�gžช‰ฌ๑�ป™:&๙,[” ฉ[|๙<ัวAใฮZ่pญฐฟOF˜๗NzŽเฮFU6๑๚c๔gd๋า�ปŸรฤก$g7CึKฺง๛!ๅVูwี]Žไ�ๆz๛ย{86า3p9ๆ>ซ8Wฒ›ฬฤฺ›a=ฑฯ^lL๕๔Q–Boˆmฒmส ๎&e>ู`_5ำ<๊A๙ฃ;wา0อ0uYซค๒โคš•�็yํำRJฆOฝn—็ZฆzำA๋๔`ุTู๙‘ƒ๎{6๙๛Nแ Ÿฟฦh>eY=ยรเ0“=E� jwqfNนถฟƒ(มrbน?iฝ๘80ี้O�ฉŸc/86ฬ๙ม',fO;ป:‘ษZœค4xa rkvแย9บo3rภเe˜^ง๕Q6T, ฃฉœ๓า‚cWร™.ค๎ณƒ}h๏ Q ิs–ฟmำ@man:š๒๙s!๏ห ฦฬo5ฒ3><ฬ{aฦT๘3“?+ ๚K•ทtค}ุv|bฃม๘€๊X•ชjfK๛7Cv๙ูะำt €†•J€–จ๛3ส&k๘CƒDไPถQ ืภ๙s๔รศศ)vฌŸ{<Œ }#ภuŒ)ไ�ฅ*จdPeฐPห�#ฌ'-‘กTV œค ฏ1 ไˆ5’•๒ณ_�ฉ4Gฉร4Y3ƒน €ใm�๔O�: �ฌ5gUq—Œ›@Vไ„๓น ่–ท๋่ItƒภฟAฃ6jภฆYPyพไˆ‰:ฌข๓๏�ฟหe ผณฯฏ]y%ฝ๚๒—‚/ฅทวู๚_2๖z[ย๓ศ„™ Œ๐�รป?ƒ”dกW9�5ฝฐmถฏdy๊›hภK‹”่H/ำOe…{ี6ชทด2‹ฆmๆ9ฐษ_)gYีฏฌ.‘%ตœJ aj|š๋&G@bMฑด_หdEjฃถ`.ํ( �อoฬฅ"|˜ืฏQฆภy’zldK์I3หš{๏พ๛.#<ัk‚sKฌ•:?๔ JงWงY›n€’c/ข†š๛�dO๖ Š(ี๒ู”7}…žžž๐ลฬผป‡พI๐ษ,๗vtƒ3`“h๛๋h๛Wa~Ctฬ3(/ญอศ� Y%์ด1๚aLง—/ฟ@น๒โ� บ!฿ฃรฯ๖ŒK๕ทฌรฝ0#L2ึฑC @พwชฬ"Ÿž}@›]dืuŒr ฝฎพะ†ษ1�ํyศV†„gฑŒŸVึ#o?<QE๛‰fใถ`|ุยฝV~*๊่๕ยฝkธ|ฌฉ6‡[e๓kฯt๘Kส+_๚f�e˜hใ๋OOaP2ณ˜ถ ๘bหฮž^|B&T:�”ท@๒*ำมณ‚นƒษโTฃ฿@ฐ_ฎ‰๗!ซฤณลอ๐;€ €w…๘ญ๚I๚‘�แ�&ฦ\ŸH q�ํฉค.ตl+Xฅ‚Ÿช'�#่l"ศq�๎y#บ�๓บ‡m๑ณCX;}w�n��. ฃ�Ÿƒ๋่›{฿‚�ฒpฬโ—โบ.ฎW$ษธฎ~F๋ศŒ™n'R โๅุW๕ƒฤ&gSvY=๗bi“ถฦz›D‘ฉgฟ><ฎ-)QHฝถ7X?3’๘–Œส<ฐณlไ๙ฝ{^์qยm๚๘�๗บ[BYฮ:๊‡nะGczp’u๊& (หลต6ั$X้ตF976lฆฬ@x9ื'�ฦพอำh$์eๅŸ฿ฝฐถใษIIี$W�zํี`4tQ"๐ๆ›‹—/” a&Ÿงฃห๕ๅˆ5๚{{๓ฝ`uญสบ‡ฒ"๒ภX$4i$+ยE-*^`ฏXณ’R๔ืฑ๏„“vkv๗7สซ+พ๙๖;o�ีฟ๔�ส ๖R8๘� ๏ๅล๋‹ฌภื้—๖฿๛ญ฿ฝ๑๑@5฿๑$\!vม๑Va”`ELอd hไtDํu><�a8 พ�ž™CฅŒ ก6ฃ'ตZวู™ฎ:๔ขdญํ๕ฉทท-�ฑŸ�i(u’‰Ÿdl�|ิ�ุ M�ซ๒ำ8z๐Ÿ- =2๒|๘6ส๘ๅkfXtฯfp๋PฅกK“2รค!ฑ๑ำ2๏�๙<}๋;� ฐ”ษถžl‘•ฎn$ณ “ƒ~@กZ่ฎ .^ธฤฝWB\B)8Šฦ[๙๎ฅล<V<(yขŸึ�™‘qอฬ จ 8\nฮ E ง#< m}•๛t๔Œ�ๆWCYซ$ 1P*ยMŒŒ�tฅLซdAตทฃ์\|^Rถรx๑ณRณ^Dฅๆ๏ช์ ˆ‹1งtmฺ฿#ๅykhšRFเโ�ย:VO–ฎ‰ฯ9@q๎@i=! =D๒sฤ ี SCธฟ:Kวeh\Tฌ๘ถ5฿–:ู�ฌ•:~ูb[4=�8lL& ไ9hd‡�Jณnข๗รณ‡wXgdjฉ`โฬ�d:dM-ฟ๑ฬyuŠ‹ส(ะ๛6”�ด)มโส๊"tv๖jvf&vว%Z’ฆ๓] ๋ห์ิฦส ™W&ื๐G๊0ว่๐9ัคŠ™๕8v–3d +šขf�พH–Xฎ2ีฆ^๖ณูE–,ศ`K1�N=V็G^z�ฑถ ์„1s%œ๏#ฒDง่ช6ฒQu๔(ร๙ต‡‚เน ‚w`'ุ˜Œ‡เ�ฃห`e ๖Z�:ูิbMhธ„X=ๆ�ผฃ็rศ�z็+_y'2๛7?๙4๕"Pแ5ฐ�W/_Lท(  เ™�รNiัีrฆโฌ†มๆpq^ฅS#4ฌcA2Ylm๎œง9ฝคภ2๔Œ จห/]!ใูณขส>สฑgI@ล๛ิV{›‹@—3?lซ�,`�Œ�จd_๙LY '์‰~S `~ไ(r}๙่…ิXrc€ญŸ-{@'’0ฅฏ๛|Zฯ†ดม’`ๅ>ช ฆzO7ัพ2R*ัwฒ,� ูš~วณ๊Tหโ6ตีทสpฌโฅ�F๕D�ŸC0UpษC†๛าๅA@ปท‚ๅโธVK=ฯ,s0u ผ“œF‘๛ี5ุ‚ศ้�ฤ๗ ฤy/เžWh}รGžะ์ƒL้z์#z฿สฉQ'4•wŒd)zะ๑ณ๓ซs้ฝฏ#[ &@ฯจ?ณวูpถ|ฯu+SวฒL๎?ข|๙)1พ๋ฃ}ฒ�@ๆ† Sฤaุ �_ถ…—ฌ“=&weฮ– ๐QŠส> ็ฮืพ๖฿�๏ฟ๚•ท_Ÿ„e ขy๑bbู^ฌฤ[ฏใ|๒ฝ[ื๐ƒร�ํฏ4ทด๊0šก5pึษGฎ#xWษไ‘Q:_*•ทFD%˜๏ฮซRด�ˆฑ„80*5ƒJƒ`3๔fXบฯดA๏ปL๖ฌ™ŒS{3œ-อํ้๖็7าฝปwq ๑“z1XP1"–"พ|ฉ>U(z.MOใ�แ์ \คqY�ธG†w™ฬKŽ?ีา@0R“ีำ้ v-=ำืŸ�|๛-“f‚ฯฆ ƒฺจฉฝต=2๖h•ตฆฯf€ึ�TKjฏˆฒFำgิˆD๎‚ฑ<r#ช6xž%ฒ"ป‚ ฐ0*@9ญปตขkง!4‹โKhถ]šg?Waชใ=?r๒œ๛@aชุ‹ั4"ั:า๚#:}rฎa�{ ฅ38uf์ไชAฎฅ3y%ชด฿๓ƒ ž€EŽYl๋่L—ฎ^CchQๆ:Xf]rซ3J+8ตูhLTำ{5ธๅษ'๘+์; ชกฃึศชศ๔โ†�ปิภRhร�4kr\]1ฏFl็ึ—ฯ‡Oร ฤ›,ๆฃfนx๋ึร45พศตคทใœ’kUฆl ฉAฌฉม8’ฑ่่๏ad7H/#ป(ฃ0C`3%g๋p–รชจเY›:ษp4RK‰ท@ฆฒc์กฃuzJpp+jกฟ๔•52’,ซg@gDl—{ถfWYyย๗2้•W^ 0�l„1•”-๐ฝ-(฿;dห�งpน†šึะA฿Gžอ่CSณbฉู`ๅณ็p8›q๖˜า ๆ่k –ค�Dึ`[vอ:Ÿa9Žฑ eํฎYŽ9ž๏ Yะ้i2jศ์ฬไ4H2s�  Sžg@O?๖ลn๚สค`{)xง“hCb•แœ๚{:ef[4๔ส›๗ฃณ$8ศ>ืuค�+ฯ‘ฉไwฬคyoผ3ึT๕ZQ/Œ|Kต1pšžžF>ค[z^ชำgท๏ฅ๏��P�g’ฝ ††'ย€G“>nƒqK&œฺขžD‘ํิ€แ6ƒฏ)ฅ•ZZ)หาฎEฉค-{ฮิgf'|ฟฯ.๘`/”�>ฒOสR๗ซC[ˆฺgอ๎�xŸฉ๔!จ“โ่:ฌ/#ณ|^ิqฯ่ฯณภนษž้lจGmPYO  ฮ๒>ฏฝ�v|v Œ)มึO๛vŠถย:zฉพŽ\•1 จชฃกพกN๒มอ[8:{!GfบtบB จ ?ๆ,q.Š๚Z{ปจืฅ็z๗�ฝ\{1u@้์๏้็ฦDฉžฆž>N+“ำœzg๐Ÿ ]ว ๎ฑวฯ๕ถ๙มปtQ(ฏฏt|ต๔าK˜@ถ›๛1่—๓ฒๅp˜—a;˜�ำ1RฦZ�;ษ"B%ๅwฉšq„f ู๋��น๗0=ฃฉ'ฒa3ปM‚ฟัั๑4 ปธบ๚ณป๗,ฒƒเ์5$77ถณOศOืไUp`� ม-�M@ธลฅไV ?7ำFฌ8ภs ๋[šdXฉ› ๓8ฏ-ฺ้koฤต๓งžw4ckมiˆณูŠ^ฐ™oว�๎�k์ป mœง฿ัถ•่Kศšฺปา@’ฝzp๒ซqไ๗FO๖|ฆฮๅE๛0ƒ;่žš=ˆhข้•:f|,ญž5ภtฒ‚฿4[eซ๒3x6ฅใO†`—ุ“ๆnุช๋๏{i#=Mส�,/}eTถHฎŸฉ^0+ฉxfร�,ณŽพฯ๚™ญ„๎mส d�|8‡m์e+rjฐkนแ ์uXž1u๊๗ๅบyฦดc>ซt5|ถ}์คํXgM'ฆฦน>€7{™DNฦฐ›zHเ@`_}ง�ฑi’AUฅHYส‚๒๓อz๚๛ฒ>ด๙RฎืนW‡xVTŒฒ๊ส›Ÿ�Lื?๘A่Nm๚์ย,์‘!�งHN:ุ,[cิ/ห่›.หณ๒Yไi €Kœพuฐnuฑ'วฎว์”๚sˆไฬ˜G‚q๎๗IG—2อ„`Šeไูัwฌk๔\เพ}6TืDปก.ำ*G� ฬ๕‰"ภw�Yงr์–}•ดฅl'6#‡|WPVฺฌpOž๛r�uˆwMC[ศ�‰Œ่ษค<i[”?ห๕ŽะงปKำ$t๐ม‚‘‚�ืV#Fˆ-rห—l�Iห๐]•\ฏม+หข๚fตuอศ gŒ@�๒ฒj�wถI4ก��<v€้๚ฒฎƒพ—บX๙ Œ‡Oว5]gฯญ HL3๓ž#ํ’2ว[โžปu๒๛ฎฯmY “(ธ9ฏฅฟ#`cฟ!}MŸG}kำB<3�r'B�rฅ˜ˆ„=ฑœ ซเสพ,2\ปH€h๋X#…๚2๑df๒ใะ ฺzมoฯB– S}ฐMภี>�ำ7GOtId๐1 ๚I,‹๋oRQ�&[อ3YŠ� mณ_“‰#ๅฺ‰Ž ศr=�=~o_�๓›/C „๗ฐปสu%๗ฃŽ –ฯขฏแ๙๕ณ_นฦศ็Žๆิ‚]sปฑƒ,JKผŽ`ฉหl(m฿ฉว๗Ÿ‘ มฯ<ำŸฑg[9“ัธ%ึฯค”-ผ+ยŸ๊Q๗™อg ู/�ป‰M+ ๑bรX›๗๊oX๎%ธ†ุ(dู„>ฌ๒j"q]๏OR{ mขc|ฦS˜ป๘~–ฐ ถธŽNณp tชโd{๙์MMอ�ไง~๒��ี_�onVWำๅ๑ล๋_Zถๆล๋bœฒ๐้ญGทn}๚�cจ€็สJ ซcช™G็Hก็�HูJ)ถn^p€@cๆมVˆ†j ฌoRŠผk์ƒฺŠั‘๎iฐQG†โีื/งห—ฯฅ�žฎPš>�ิ>tวKสŸมฃ5?flฆbPฃr—2ฑg�๒%ฎGa�@>ƒefัยิbค๗�ล๏คพ๛ม ฿pD'&วษ„a์0^P{/‡พหXBqฅอ{=~ดQœณ}�d ้dฬ3hœ-=ฐ‹ดtั0Œ<ปŽYะxน/•ฎ7'ชo–D-a�ๆยใ#YKQdห 8Unฎง๕zืKg)Zะป"ศรQC‰i8|Ÿ/�๓—…�yœฑ_H๋ ฅฟi คƒณm(w)4^*;ล 4RขpP]H'rKณq8ษTRธ V์^‚ณVBๆบ‚ฮ๕นuF‘eื™“Ž]ฤ๘ป}ฒง6DllํJๅ-}หก๐ชศิqo6+R™ป4 kไvQฌพ4๎gฮXCŒ”YตุฯF–าว๏฿ƒnF]๚)ฮ&ŸฅSYย}Zk]Mร7์ต๔ี?๑ำฌ‡ใด(ภ๙ูกa•4 ยŒ^ฆqฐึ.[Mถ:Uิใฐใฬฎโdํ6็วIๅฒjอ,'ฉฤ‰kฅ๖์เฃEำ$๗QzJ Hบฉ”?‹,g—�ฑ�์ ๏หค'ž1ึ‘�ƒQฒ“ƒ๎อ๏oGๆ™ณยuฬ"J%ี๑Hrฦ})HKGwj “ูA–จญป#5Sr#ภฐฒธ„ณฐๆ^(wŽ2ljjdmฺ้K‡๕uฒฑfK9(ญูษๅ”=X๏ฟƒ“,hcถ*‡๓ณŠsฎCJ ษบcฤkๅ\วึ3hC"ู5>‡Ž ™3)ฮ”7�ๅXถb่x~ถ๒ฆืe K[dd˜%ˆzGึวฬญ:"o,1†<ซ2l–Z@Kcฏ#PE@ฺ๊Žมi4oฬ66ะึS5ชษฐ 3๋>Ž&ฅคณOศ*ศฺ('(”ฒม YH›y ๘ž[3ำ็/ะ@ ก๚Epม,ปฝ– ’ศภ–S๖dDฯคŽุท/๘sƒั๓ฤฒ3;d›g&GศPmคR๔‚ูfื_0ลษ๋่3‘=ุˆ,ึ"}๖๓}ฒบ๊XŸWy’�n?‰Z@')ณึ+N: <๗๛+%W�ะB�พๅ ซ+ฌ ๗4G Aม˜ตู ำ๓i่มC๖mภ�ุTt“ร,‹ ต ๖YฆNkog:เF+ะš:แU€ €#2ฃv)o ๙;bฟ–งฆศ„หไ‚}‚ฝษ�mYc้ Žœrชc~Bิm฿™8๗lม ๆฃงP:ฟŽiGG%]daป‘7ƒJึบm๔W…ฮฯ™%fอ�น๎�๘,�๘ไณt�ษำ˜ฆ’ใ๚2ha%6ยฺลaำy^EฟฯB)� [eฦ9ZCŠJ›;: :a์ฅ้‰qx6ื^บtc;วBษRช7๛ž47Q›สฝ//ฮา “๒9tฯภyฆ|เไZส๑ญ๗~—FZำ่`dุฦ†m๐›dฑฯพŽl8vำ์œฮชel6ต฿ฮž:็๗ฺซฏGcฦ}ภ„Vฒุสส&L(๗EpสZG้ีbงฒู,๗{ หไsฆุะE”q฿2คlธM€zŸ3c ํษ�ฤ,'}^ *PŠ6�ฺ�ปfฎg6�sฝ  –ฯา2ฆl‘šz๔ธ™บศnr>|Vฯ2X]8ด:๖จ”pฎ7B T&YYžม ภว–ไ1z&แ@ฯQ[�‡฿…ู7ฬ4’{”อฃรน&ม›บLๆ‰LŽE˜6ŽนD�๑5tช๓S=ฺัƒ๕๕ั๓a‹}ฯไ:จ$& D�@Fว�๓เ= ่ซ๘< ่.j_{ŽŒดhhฤตษฎ—M–-54(’อggviฺ2 ฌ|>$9jน็VภY5ŽˆT’ฝ53;อŒyฒšบVห€B‚ฺ?๓ีฏchVPฮษ.Pห๖AdHส(๓<ทอZ-ฝโ!ฑฃไtษฮ๙9ฒ%,๙icฤŸv[๐ืQฏ‚ยฒิฑ๊giุ65mfโ†๋`3ฺภธี bฐไ,—™ššPคovษqบฎๅ,ฎqQ๘ฒ^A๙็ฯ ูณพ๚J๚h๎‘ถU%’(๘C ๊ฆCฒฎRั 8›`nิะ$‘ๅๅบฏ่ภZ2�ฺ`ฏ]TQ‹� ฃฯ๘:@/ล๘fฎๅz้‹ฦg๋ขWหZ๛R!์’ฐ$yฦ 4นะ๑%ฐ-ุA†^฿„s.Xจ|hOxfYi–Llm1๒v`bคj†�‚๐9ไถ ?ค„3๋ณiGw}ๆQx.?วภ^๖’6>ึByย�“j/ะซ,ช�ผ?AKGี๊;kW�Aeฯ”v"ฝœ1ญ5ฆโ˜ˆำŸ’ๅ+ุI*|€�D“=eศ‡e‚&ŸLLพส ด�ฆ}b‰ƒ�๔I พี�ˆ[~M๐=ฝ๘Ÿ๏~ณDแใืโ*‹2Hต๋2 ๐ตใ๖ ‹๛เน๔!Z๔้\c๗_ ฤg€Wฬ^๏ณ๎ล๘๊…�ซฒP6ฎ0w-ฃ� R๎ุvd๐wํ(_`ผั๛ผ๖ี๕ฤ๔s็็โ�ษ.),dƒ%‰`'๘C;”Ÿ,ใ—;Žต„8czt–็อ62ำ๙็@JŒde?ฅM*ฌฃ3ตฏ๖6ะ฿—ษ'dรฒ์}  ม 2o“๕ท฿|ะฅ ’3ุใUlง ม"Ÿล�‰C๘’m๚ศมใGyn์ม[�-xmCZFึ าL�`œร�ๆ�ง๎ฏ�ษ?�'็`๐๓ฏu๒Zไ_�๎‹�ญBv๘แ'w?]]™ผพฒ4ฟฑ0?�อไšf ซNฬji€b4J$t4;_#โKEช๑•*่V้9ฤ๎์ึฮs0:VA๙็ คKซSX‹ๆฉ€Dฎkอ� ภ77จŸ‚ฦmc ฎ25+ต ๅ:+ดมYAV3™5(ขPโํ/๐๐๎ฝดก•ฮ+…ตŠ,น4ฃ}”K5า_y'}๙?y—๚ืNึฺ่bํ|Tฉภ…ต}ํtG็๏fคJeษt€.ุ•gt–ชมˆมฏฯฦˆ๕8!`า „cม๏mPš ภ"Zh`oCล0จ�พA–จฆ`JDา.C™ซPJ € ฺโ(็Š:m๎Uร šฯ3@s�%�“๎Qvํฤ๋ฌw&ฝDข3”‰4TรสhkJ_z๋5ๆ'wม(ฐ†5ลX wศ:๊D6˜™'ุ(ข“q†๋bLZฮเ<|๑Y=GฒŸUŒ>หmฎเp็Ru�หฉ๖ ฮ5ฮ๋้Aœ l๒ๅ๕8,u็L9เ,A?ไ4žRึtŽDswpฆgึำ๕๏฿N‡ฆSฆ j&ฬ‹ �—N7กjB†aะฺNฦจ นิQB4#๘ณGC)ม‹S!๊ฉ)หํmโTั8๎ ฝ/จ“ถกY+›:พnŸเYฺ{+๎ฉเ yšžXฉมน,ฦˆh่ญŸ“R*ณฤ�ะ8uuไำ๛กฑก gm;�น{?ออ่า‡งด –C1%5›R >aู๙YLœ‰c(ทe<6Aฬvtฆจ็งœ ๛jณ7{l!CตŽ5| = ฃโค†ฆฌuคฯ ไA‹ฦyๆ๛i†ตch๖™Ž3#šbัอภl๊iถอKกี�ZฺซŽนhปตว6๖”Ab@Zธฦ?งณ†ฬ*c:า%ฃw‘(pnu]SK$‚=@ฐฎฌ๋ xM๗]pGgาY‡–ๅŒณ�ีู•^ขฦvGํ้ใgirt‰~inj:Q�ฮศ๔่ศ่ฌlโ่X{พ”cฯขเ‡‰ฬŠ5j๘uบ�ปฃ”\ฏ?�ฺmG�.๘iฐhๆิ€T‡ี๕๕,ฺ™�3๖wiq9ฝq๕kEเสˆธfภตNฒฉ•l9๔†๏i˜#ะิ)ฺB�ไ4d9n ีฦณ�?Yƒoฯพเจ็ฬ ]ภิ3lcาNmkคฝGณ๓fxเ๔^บG™ภ*€`7:p™�ง^ดgเม\%C€ซแ|Y‚cY‚ฮeศ5๚ฦ2L๕ฟ2^ย๗e.}}[0`ษ™ๅ5O=Jฟ๛�ฟ Eอบ�่RFึ ™ŸฑฑQฬ}†ฮ%xE7ฌิ™I—�เˆD66สk!/€ฤ฿ฺ9Foะœpt„ฆท4Ÿeonc&Pku)ฤw˜€1Oฆ�ฐC๙4xž˜"จ@โ\z๋‚ๅิ‘6g™€c ฦฯmDYuน ะฎ†@r2>5ม๚ŒF#ึ)D&G๎ŽQ�aI็ะ@MŸ๏ไ‡"์@[eตม>w๕Ig๏f฿‹ฃTฯ๚qว$Žฤ bต —โ๐ฃ฿ึัป+ํ��ƒa3‚ล<. sf-}‚.ฏ-ๅ N ํฃหฅาฺœฤุRจฯœƒญYุ<,'ฯZ‚^Jjฌ�Iฬฦq�ผpŒฑน‚�S Z} >�c2€Y8›๚C™ ‚”Rงฟn`ถ๕\}if]`#ศ‡๏ลฺ—รl�bดo_ฯ9’ อ้๑@ขแaฮฺ2gXv’ ชูlืi 2V์[ะฤิ‚,๒ฝ ซภLด�pdI>†˜at-ี๙Uึฤ Bะฎ,JŸ„เ3 [๊ท ๔4หยบ์๑w˜’ผ_[ _ ด97�<<ฌ™€–„a/ะ –2ฝt๑r+R‘eา่งศRธt�b0'eOY ๐่แCไb99d—�ดC‹|69CึMp �BBภฤฯ0Xฒf9�†>Š`ns,BL[๏๛ld;GMทใR}๑ภO|"สวจ<ุ็C}f–ด๐ฉ˜“๋่ฮฅ%๔ ๒a๖v—Šฮฑ‡NŠภฬ๚iO พื yQฆŒฺฃJ9b…ยฯ1ะ๓ย๒}ว„บ fR�KฐG–เ4S6x†าผJุŽฒ ˆ ้q@ณK/ƒ�-(๓=“X๖+ะOฐฟŠ j<#{jƒnm’,$%ฒ‹`Gjs ธc‚!ส}DถŸ฿ะณaขvY}ฟว�ํPFe๏˜ฤUภ_žรา/ �๋ฬ‹™YC}ม}@mšฅส˜€œถI`�s-5�>3,k. U– Gพ ะอŽ@•�็๚๏y†}mrค_ฤน6oศ�[C ‰๕vK๐uดgพWzป>ค,\Hๆ๐ปdX่kkฝ7Auฯ–็U}'๛G— ‚ถณ›%hแ}ภ&ิ๗VV zอz Lx>๔๔‹ ึ}้๏j'ี Nฆ๐Oeำ8ม๗Zฦ่Qiมฎ๎N|x๚ Gิ?สฐๅท–-;„฿{โF+ธงbRฌ‘��H8้ƒhงkBVฑ;๎'฿ฅฯฯŠ่อLฮง?๚,�ปg‰lQŒ@ฟs็ ฦ�i_p†(�w�฿ ฿.2&ภเZ๚ ฎW๔TเใœLๆ฿ฌิ%๎Ÿo)Dl”1KRouยณ/|ฎ(ืb‡WV`82Eง๓Lฐ˜]ฟ�ศ฿ฤ๗้ลน9 Twj|:�1งษQๆต฿ฐ—NYงr@ข2โ•�ฮ6Jp ง™เ๒w~�k�ํ฿�าk๏Bs|๑๚7ญ@^R�M?}๑�๏<8๚o}o๚ำ�ฏ?{x{†nแoๅr�5งXฑฒ6ึ&เฉtž#ท�กT@˜†D๚ฝฐš SฯAร๙ล้ฉ!ซ�ฦ[4 มHฯ”š]๐pJuฎ^'Z>ลไ‡ž๐ป(œqLณP6:R™‡าEs6S๗mXฌธs266ย\้šศ0ฯOa@1ผณ๓“izi CลBŒa๗ึ�\บp้สšฬ ู •นช<ธฯ_ลyฃฃX“Mะaว).,`ฬPฤึ…๊๘น>o(+พ๏=‰๎ฺ`อlชHฐY……ูUŒV”ฝฯ™อZs.?–š1๐:f ๒ษผฒอฃโ6?<ภ˜HE7c็KๅซกTแ๋๔๘๛(DAฃ—ลy1ศีฐ™มฐF๚”์ygKCj†ฎ_mช›์J–•�gฯ_ฦˆa�@ุญษท ‘Ÿํ๏J็+n=“Ž1โ+3Caศ๖pHl~˜[[Hต m}้”Ÿ‡DS๏.Œง๙กฯธ7� •ฌ‡c๎&RตdXa(‘ั๑M�งkฒ‹มแAำอ›ŸฆฯoฅB2ง<ฯ1e){๛”I0ํก1[Kณ2;5ฉงF˜•Œ%phย™kkมฉ็ูOqะฺ*\ืำyฝœ์†ๅฝG‡…iŽฑ][vลลYs� r ๐mˆไ ็v2ปฝ็ศRS]Kํต`Š๒เพ{Ÿฮ[—ึivdœฌอ่pŸœIฯžLฆฝ% ฮ Tธ€š4-—ฮ —7,�i†ู ๙„>ํ0o:{@ฆ์วRkg{4ภcaศด> ็�IมvมกpดP#Tq3คKdตk93:ี:ำ:๛ๅฌ•Y|3ะ<$Xู ลโ#ั`@ฬ#ว„จศY Œ}qq…ฝฦqCv�ณ'สฒŒ~Š๗d€หSฤ�H๑ฏยแณดFถ2hgdF3y‡A9”ภaะะมะ€[฿,kC'E#๊๗u�ึ ถ[ศฤ๋H=˜Žl‰,ข (ตž-UูrฬM€ %ฯ…๒ไu<‡:�๖Yฑไศ๓ซ๓ไ๙‘f์ฟ๓YœƒธW[๏฿แฆฉ๓„โŒž giŽ๕^e�ํ^ผ‚3ฐFฦฝ‡>ŽT*วกดnฺ๑z2RN`8C�g฿ใ� บถqยmๆZ*e‘g$=w6Šsศ}ฦs็จฯ| `ƒŒQl#ƒYฮ๓VS๚ๅฯaxฦ{บz AถฤT‚g๗ฅฉgฃฉ€fvช฿ู ๐*€^อ๓šฑt๕๋„ฏžž^2๔k้ฮ“ว4‚ๅส)ีFp]ฬ๚ํPำ[‡�}™า'\ =ผkช/u๕œE'“™Cคญ&%ซฏm�ฮ8ฯทรบบffธbแv้Šฌษ6”ecท>๚งfPECPึ=|˜๐$�ฟs/Œศ>•1�BPzy*,`E ?mY2งd่D–ัฉๆ=†‚Xึz fLฌeฒึธฎ๔๛m8VpLะใฮอOาไไB8วฺิC�)'xk„J��ืŽ-`}ึhน›๊่_ จฐฏ•Qภ๊ษ'รd’fฑ%ฃุ Gw์ๅ›ญžเF}ธ‘+็รfVœ5;w[ม�8ธ๘าžFฮฃkT‹<ฤจB๕_ฏ^M�ฝุฒy๑ิƒใ้Œ๔[๔ี˜KปŠำ์๔€ฒŒcฮ�!ม4‘r๔6F9ุ๗ ทญ‹&ตœ“y2nNiฅlPฝ&ธ"ฝY_'�๓แ}I•7`๔œฤ‹฿5๋]>๖๗ิŸ๎y๗ผ็˜ฯ8E_zี ? <‚โ์ ฏเ8๏ฐ๖ฮRœ๏้ˆภn0~}ฆฑ0 ๆ๚X{Yv�7CWŠฎ-g�ฌ †œ(c‰RlŠŒƒ9ภง"๔…#Že|hke�mฤd3รLๅเ>ี็'ุฐ#พส ช ๎)1ฐw’jB�ก]๕#ฬ฿อ๐[ฟ‡co‚ฃำƒtๅี+œ‘š8“Uiš�?+”ํ๕tu#‹R‡#ห^๔ถ“Mlฮถฤlํ6ไ๒ลห้ยน ุ#>ฐ1š1หบ“}aภญžvฏ P์2™[๖Bๆฆ †U2ะฤYI/_l ๗ฐ๐…?“ไ๊์่"่’)‡ํๅ šลุw�ษ๚Vsฏูุ็ื� Pภ็”%'[ษ๓ํ(_u>—ญcnีลฺ ํฃฝcิฏQBะฉดt)�พ”+ํT  ๗!6com’๛j Aกล็โlธ๎Nๅ1๗3+้]QVำฤg:ฦ–1ณ๊xฟ๗•gปๆ๕›Œ=�kฬ_s๘#>ซ  ?ม™๐7๘m?รฬt!๖ืkl G6�ฌฤž zoฌ.!'ุIZ�ป„~AN ณำ.�jศ=gฤ}ึfx๗A6�ฏ ‡�`>!†Cซณjะ๎ก@„ฅ›Iฎอ�๙Tุํท๗*g^}1:`f�„ตu"†kๆ>zoฯง)จg�LmO”-ลZ้ปไฯ„Ÿ!ฆŸนdinเซŸ! 2|๖ัRณ๎พ/@g๖ทแsx}UX&์ฃ๖L�ซ wฟ๕gŸ�X+พ|&ํฑอว{{ฯคื_{%zmqๆjฑี–% ๎๛Y&ค๏g‰NYkว�žฐfN‹ ‹{ไ�]7แจžืืฝpO�+Aฬ5ใ–2ขใDว]šLiA๗ะU€ฎ็ฮ3 0K^ะฒEDฮMA๖LBฐG<Ÿ ภ`ฅ๐Y{œั ๎‡ecmีๆ๔?มฟฎลoฬัHัาf๛–Xช76� }HศฝvvtฒN]ฌ›LNeŽหฆ๏�‹oรฒ\M‹4f\ž‡uˆ^=F๗ฒ ๏งœ งEิ! -ู†ํ๎ŽถHc๘ฏ��_๛ล_ollอำx]์ฏํ ผ�ตห๒ลฟ €p|��ๆPฆฎ๒๗–ๆง่๘�"#� ฿%—†u\žภ๒r�HP5K t ๕ฺผOฅdfo%๊ ๊hU”ก๎‘q;mdน[ €ฟ๚ฺแ™ูw”�:จMŸJq >�่s~u€ฆYฦ(ฺYY ’.™#หa]{w�™Q:6k2;9::™z2x"ฎื?บžfก๒––Y‹?{�|(ˆ:่ฌ6ฎูลฉจx�ไa:ื;z เD้E~อยYใg@๘dh๕ะdฤฬJใฒ–w0CeX‹qV{ˆพ™%^^ด;*?Uถ�:m}ƒ2ปฃŒtL ,|ฏฦG0BEไKงณ–#“แ่/•ป(นnttญทด€†Y)3ๅ*P9ฝ ฅฌy%ิLvY๘38๑d}Z1๒8?์`%ฮฎŽ็อzฺC‘I{5cUVGf‚QM€sCกHป.})๖5gDฃค+Z#ซyzด•ึฆžp็&0ฌฏฬG€–ฅ๗๕€ป์๗า™Q€#ู@ƒb๏tๅt,๙ฬ�ย๔แ'ฉ]ฆ๙AAic5ๅ$0pR›)M้lnL/ฟ|ž๙๓�4=$ณc6„kYo^ษฟอย้€โŠ_๕ภจ่?{cEcF+{8zg ็า@XงWpฆับwฒบ:ผฎนฃ๙ ,6ษ@ิำษรลŠ…@IDAT_mFุlG=ฌ๊๘๘hP่ 3ะฎษ�ฏ/ำSฆvvืลOมQำ~hs:hiฐ๖yฦำ"�x=‚(ƒๅ\g!J9>‹Š๓ฃS!ฅM‰๗u$๛TX$[ภเZ‡†ฐทาaˆB)+K+้ั�๛ ์๏s>จOOžMs๏๙nใึ=O48pDYt7CA๋~ร‘ฦัฒƒดƒ๔Jๅตš์@KฬึU` ๏L[ว‹Pฤc–�‡ ฺ?ภ†}จ†ง'าT๖M๔๎๗ปฃฃฤ๙ุ"ปพร—บNฆŠ7A'k๗ื็Bั›เฌ;๊ลํษ�ษ�ป ษ�ำž�8…หdwอž;โqj`Ž๒&.Avึ �๓ฑ้5ฎ/‹กใLถGU€เ‘�H็.]N+€Cซะั+ุในeส ศšฟ๛ๅw๙p๖™uฑ—Œ%C–mุ!“�ฌภฌgกŒฬ 5ดNxัน5 ฟ�U><:๕fฒอเ๛;์WAกvฉณฉ“๕-Šฒg๗๎l"ฯฝศ™๚�”{v ƒ“+hjรตxJพๆ็็๘{Y๚ ุv2mฦวง๒ ‹นAฝพž ๎Žบl@AืZg�k#(€๐๔ฦAๆWeึ๐๏M ?;ไ๓๘ธR~_{d`)เ/รก ป~Jึ~nrš:โjŽ›ำนsƒQณม๚Œญภะ ย{9หf้งฆฆุ_2รฌปX$8/RŽ ศ–•ั๘๓88t *l‡๒š*์ฯณพ>ห๏ฺX@ƒgw^z%‘A�bokณุ์ทฅdหห๖2ฺ :แีM@z‚ฑ:๙27šHXธ๛4ุ๋์๎Hoพ๖ZL.0.ัftwuRS� ๐ู๚ศ‰๖ั๐�‹aXฌโGXJcำOA็ล ษrกฆˆL<เ=Ÿoษา9J:ƒืฌMCK๐ฬ๙{ฑวฦM1ํbเQOUหI:;;๐ญsษ๗eฅ]}๙eผ5ส๓HŠi�๒MT8ฝม>/eลุ�t6๋ฐ8ว4๔พว.ๅ|ฎ[ŠŽ†VŽn`?ฤ+กI[9๋เ—2ื$hฃดˆณtjึJ๙ผq฿๐vข„AตLึ๔อ&@‘ฺ๋L/Ÿ*|๛Z)ใสฟ�‡~็.ฬง๔ฃธ/ว5??�f๘ต76ฎSfผ็ใรฝT™ํdญy?๖ึr๗าิณฎN— g) ั฿ฤ2สr๎ษFีต€๓�‡{1eปŽ+�ฦ_ดล$“?ศ;พฏ๋ฉฯภD ง?็็y�ฝ™Rฒb๏๘eม�\๕„`‹S<ž๊�"ฎๅฟ๕iอ6k3�++lp>0G๙Lฌญื<ไyถ8g‚a&ืlF^่)่ฐ`ฟร๕ฒดอ๒%“x'๊ึ”›<ัภvฒ~–vQ;๋”จ^{ศข+ง=ดdGM�$ุ Tฎ-ส7ๅ›ผ สHๆp•`)ๆุ�ˆ6]฿)ฺ'้W—ฎ]ฃฯ๒r„o;ุฯิกK6‹+”บฒ๗ฌกำ %‚Yรีd&›๔ะฏ0ห๚}ค‡Bช โ}ส„,ื=K~[ˆาฐ�*ใ @`}‘i4›<ฃๅ๚X–๗ข$ถwฑmhฏฬฐ6๎9†•๏YŽอS!'8™ฌŸฌูฉM๖Mม่˜x@(Y…y…ฟA๕gr-’ŒNๆš ฐI‡u3˜๚ฯ\IOž<ขI๒lุู=์C1�dสกญฎš�๚o�TXบfS“ไ7, ซำโๅS•๊d›u“;8ๅ*i;‹ J•>|๓ึ ฦ--a๔)Chlaพ๗Eฦ6^`6๑หQ๛oภ`ƒ;๋=๔8ฏ6 KC8”t& ‡๎ำ[Ÿ๓=j <28งฮ™U5=g8^+”&Šำ€฿๚๊9่ฒ6˜าXpI+ฌ!T1ูiน42@œZ5ุffฬ๖ˆิ�ฐฦ{าช�ำฺJ†ชสืฯจB”ยhVKjน์€bˆฦ‰e tC“+>ณ '^Z`…ฦŸ๋๖aฯ#ส�าw)m,อM`<์�ms!ƒ2Š ๗ีะ �๗Cร"i|ฮHo่H…์฿ๆไ่ฏ3(s๊ฎ� %ปuา๚sL ฮtq2G(Cƒu์ืาษภYโนฉ/ปCm๓ฏ๓wาำ‘ีิา�ฝ'ฒะƒ/ 2ฺ฿,ไ›๋+ก฿ทโB฿ว™ึ™รt†ฮk €Xw๎ยนt�าyจ๏WปAญค๏๏zะธ1uหBฐq‘Ž๎>ฯW เQM=Z3ฅ k4rœšeu ๒4ผ@ณ‘‡1deŒ€(@S3ยZ๛ฒeวัฑYGOCn0uŠฃ‹‡gฦัfํทqpศฺA�n์hง|†R ึMlL้Nนจปฒญไ��!b‘ฑๆW๙<{6jZอจ7BูตฤGบฒ ��{w‘(€0mJห๋znเฅ,I54’โฺfๆ|ฟ_v7๖ t†”I)::ส)ฟ€\เ<้€`,Yฃ15ณf่t0 64ฎf๓"3ลฏ๊H๘ณๅแผTD€ฏ8 ฆI้ ฮ 'Zม�ฬN์ oAV0ฺฮ�. ็ˆG@fผw›จzFฬ|!Lq2<Ÿสภ™มป™ู58ง�[5@[ถ™zUฟ“ใส•—จ‹„2O ๆธBƒ๏ูg๑฿_~ใUJG–‚:XO๖?›m`”Xg์ล‚%2โณU.s๏f•๙ผc‰.Pิ9“Š(ซ%Œqฏฎ-็.J ุ๛-่่‹4Tdษบฎ–ข˜yCถ]kภฮฟะุ?ืร-�‚‰ศ๔–�ะuj8‚ฎ“=vY๎ฝ น8jFv+3%ฐ‰f๔ๆกP/ฅw�}—� Œ6ไฬแฬ4๒ณžkซ4’ยัrฯˆํม€.๐ฐO™R!๒.•ตš;�dวtำˆฑ€.�“๙‘ž๊�๛คYพ5t ธC8Yแ$"{–“x฿~เ<๙7Ž้ฟ๔๚�ำฟ?�าuื›๒��,ฃ�p่๔1evdalุ1n‰้แH�๒�zฒF๕ ”�P—ศ\^Q sd›8Cฝ€SำS้�ฃ๛i,๓โิ<ูkXsd…ฺ;;�2“`(5`ญGีร{�๛ˆภฦ2ูE8�๑ฃSฃฑู`y˜ฮูท้ข‘Ywƒ้�ธฎiŸภ๖๖'7)�™ 0Cl_'HŸต�:=dpQ€ฃ}ย๚�_'”็dqq9lซ`ทถ'๔๋d&UะM{ฆŒ P;��3*�ํท_Pฅ<ˆ๓'hP&่ํ9–ี`ฆLBูฮ—�\r๗ตœokพ] ,K๖฿}˜fฐฑฅๅศฒ#กฅ {Ž e ๙g’ฐ๗ข/ ๋งJ2ธฑิO@ว1รฒศZVำภ๐�์;จย@ #๏รูฅž\ู5kipฎฌุ0neF๒์T‹‚~Kง์bpi@ฆ>๑e ฅ‚|Uซ๋๙Ž}=;คO๋�๐g crBfฺ{[ภ๙ฒ‘šฅ“0(Vmf `๏€๑ษฉะๅ่„่อ‚ฏฃฬศ่์็์VY@gแ ๐ณพผ›ฆI๏–้aฟ ู‹R๓=36v53ํ๛ๆ�ปผ:‡œฆ!€;ห|v;ส�‡`ู่Xบyใ>ห@ฤ kณ`b&ึ>ฎ—๏ƒใ…๕Ad—๑Gฐ[ช๐ด(ห ‹ž=จXG๎ŸeZ”ด8ฺwษ � N�“�b4-�ลฦฦ ำZนๆบjœgงมcmCV2j› vgaqดบOงœฤjณ�} m:N�ž�XDฮ๒mžg •}&ƒcA�„ŒŠ!pผก ซ๛ฎ` –ผk7ิE‚j2N:ป˜T1ะ‡Œ˜a๊ �ฐฅ2Ž๔{ขไ”kz2เdg*จฟ}.๋�=สข� Aง‰ม}\A๖ธ!tU< Ÿ๏�™้vฯผwvห ธ๛`ฤไ๘ม-›)บ?‚g็iฌ์฿ีซฏ`ื:IG๔ปpœ 5ฅ๑l1บ5ำn้ฏชํเYkฮึใ_‘� I`^L›ฐ์6๔sŽ}ญB๘28แใ�&6xexฦxkLภj qU\U˜�๘ฯ�d”ๆ"แaข‘>5๘ฬ[$ี,ั์q‚„๗ค�Qโ�rฎY“๓FŸฝ)�YืH�S�e๎ไ8๚H.ž H๕เœ•ง]@ไpr…3<ทผN)ั\šฤnณอฐaˆdู7K-‹ฑ�๊�ฯลg95G่>Y>"#X�h๓มmc๗ี9่ง-3๔ฐๅi๚�†ฯ_eฏIb ำท้�ฮ liไb”?�{Hจ l |ล๕žฎ–�๓๕k�ื�๎ึuู๊ปW_y๙็�๒๗ต_็ว�y` ภผx�;ฎภ เเ฿qกพศ�พ�ท�๖ฮo�รo^ฟ��{•”ผ.๒ฏๆฌt ่๖6‡N๏ฌ'Hลlฦฯฟใ)cL]} ฦ‚l7ศ��ฤOA๋!๛ b':iy€ส�เำn฿wกx~๘ังŒAกฆชฉM|TZ…:ฺ(PZb‰†•{Q‘–๓{67ฒ;ธYNv”ุˆฉฝญ‹` \ถ9๊jซชซษ Eขห๕ส� NLMๅVงวๆ๋";ย€ๅ€:0มQแhžDQk่๓…žถtกฏะ€Lนต:ƒ&่‹g/Qณ�•Vๆจ+%@๖๙ส`Zpโœปm0s‚ำ/`}–kvธ`‡เ–มWSQC[:\%่˜|ฤบด€*�šฆn30*kdฦ์QŽ X๚ถHช๔K•จTมํm่ตj™๔ฝ๏�0-4ึpOMmmฉฃxฐษ w;๛WIฆƒ]ว%9 @ฦnตั0‰m0P’โ&ญัฑ{-ูฦ0xŽิ๚๘ƒ๋้?๘>Fm_'\ๅึ0ห๚(ล˜W}ฏฆ‰งออฤWัธP็Cหๆd�~C“ศMEyM๊eๆ๘ A„์;๘ฮฮL๔A)†"า\8ย"œC>ศ๘ ญคˆ้ džณํฉœท†ยฺฮfะ�2ฌ—ฮf?ฮ‡ฮ‚”Meฌcจ=4 ส.=Z‡Pรฏร/ภแYา(54!f-m‚TG‡อ‘ฬ0้ค(?ส“bงƒQC lถ,FUyฦ๙ž2ชำ)ชAฟดDๅ%šฑ=ก9jถูK{cะdเšRh5ฺO3 แ p]e} ว�น๋าํโgZึc“9ปะ�lJ™๓ZE\กDV�hวรomิ‰ึ๕}Ÿ`–ฮบAพ์๏I๖ช์Œ€ ฏ+�B'H PŠง™”eh๓w?……ฒฮ๗๗ฒงA}๎ @๖dฏ  ๓นฌ%Žผ2งฃ`ฦcye‘3OsC(ูึ๑๋Œ?}ํšเ€ฯ1Kวขท�™Q%๊@3'–8Hธ�W‡ฑว:ึ๓–Bx�ีน6โ4Xฉซ…ญ ษ3Yjcน ภซ฿๛็�œ๗ัXœ@ฤ:]…ฤf_:ฏา*mเi €BM…ศzscgวIg๓ฐ ุ้ศ?'Eล™Le_o@ัvšB็D ‚ฬฑ–�ศ๖kๅ่Y-๛[@)@žpgู‹zึจน บtํ• ใoโ|;Js;a&n Jถำ] ฿ิ๙r�L๏�?ฟ๘K�๒ผ1RT๙ะมทฟMd1๙�� ๘โ�y ~ฉN�F@#๛ฦ้ ๖A™ม&ด#ฮŒ—QฐL‰ฯ�๔l์์g๏ สOอภทdf—€z€E›ถ‰g6จ๗sŸืl['(&P�ต�ๅW_ฃ๛:A:—ญNำณศlKศ“ม�Y็๙ สกP‚D|H)�็%รฝก13๛จ๚”bดOด[›ห่๓fฎOำ9๖G๊vฯ!/‹KyR… …�ๆ‰อdef(gฆ QŠย 2ฮยp‘ฮnษŠM€หฑฯ:๗’a๏ n*#xa"Hใอ$–D›ๅลi~�๙=จธ่ šนš@ +8€-ๅ dฝ5\3๕š_‚˜‡�s|O๖บภฯ๒�์ํเGcGRf7 ถคท�~ƒ}`กtŒ[E�ะA๎ ื8ภN๎าฤm฿฿ๅK]UˆฎRมหhX‡มฃŽ{็H|ŽL ๕ฎg�๑ณง€“่งกUg�ูˆ—/Cล�6_ณส:ฯ?22Nฉ eญu่eŒŸ–bฯR:ิ‘_vG๚5ภฺย†ุ�ฤ ษ๛ิFLฯ เ>�z๓ํt๑โๅ่วS ป“๕ญf$ๆยษ๔‰บE๖>‹I™๓Rฯฺ|V]๋ž €Z:ข ๗ฬ ฦุ?ก@�๐`ฉ`ƒeG์"ฒ�๊YวR;โืฬต‰%ื@Fฦ‰ห&์�_อz๒ํ์ฌฑWlk~@ŸŽSzneญ‹hิ|ฒท…€ตไB๐ฒ๔วฟปž๖R>�^4lๅ�ฃ„†ฯ6 ๕Yd›jKl�[ภ~km็:YgrH _?*งอƒUิั�Kค๏eาบyŠrว#๖ีrฏB:๕;Q#ุ\฿ฯ—M``ฉv5t�บ#ฯLต'ฅศ‡v`}!B M�๕\'r›ุฮ็ะ{็†8ึVl tuถง~s–๎ฬ“xTP�`ฯขน(็๗่`‘�่A‡ตัฬัฬ+€�๋์ปzCภnลณฎ๖UษชดŒQป-ศฉ�๋f &บ๔1ŠPอoxo”๊ใq–” ๏Q฿สา G๒657ภ4:“ฎ]ฝย๗ฐๅ์กฌฒQtŽOฦZ…m@จc=๋)๓‰Ÿ%2Rl$ksแCe�$ะฆฌFณetŽ@ดŸ๋={ฅฺ'>[ภหฅ)ๅ‚Œอ%ซYXร‘ฑฟ�ใ�)ชงo,ล4า๑.๗JŽก(ชฮ›นˆ๕m๎>G1—Nf‡๘Yš o๑PัUดŸำdw˜�๖w&tLค{I�sฯ,uถ3‹ พSSirŽlGM tฯt6๚ะ็ฅเp=1 ฃ คŸูิ+ฯงM& ”"ี๕88*ภ%dฏŽ`g บ3S ค9ฺษ|ˆฑ‰ฌแ1Nศ1Hyถึ ฤ๓ ต”E0qขŒาŽl“ำจฝ;ี‘ว“8pŸถศjš้๚=B=66B“O1Bh{j�์šnƒฝฉg#ฌ1J2hM๑){mฐRL˜A�38ย|_GึWN82%ั๛ƒ,"–ว@ฃVƒ๔||:ัtŸ ‡†์๐ภ@?%d‡๙™ฅBNธย8อ\ฟž&zNXฑrำq_'์…e6โ*ฤแ)O”ธเหxH‰ภ‚๛4+cC@ว‰IY6 NVณC^Mฏ วšฅˆ2n`฿ร L๋8;าJฃkๆ�k�ฝ_g'h†|พฒ.ปภIล๖ƒเeoณแ๗ขฦWz%ืี๑4pัศ๋ศ่่๐ rœ/๒ €”Lแ~ฅ/๏™+‚ะภข วฌ[.&ญฬฏPOH๓-ตา๚A๎ล€วณิ3จตi–5ซ๔ขYzช็ฬฅะI:�Rฬทกซ›แ3๋/�ผ„๛™™Kร๗กฃซน็๛}บPก“ �e˜…2ณ$๐N7็ื๓ chรLG�9๒ิ,�2mCc“>8ำLth`*บkŸu๘์ู €œ%ไเr�`…l�0+dยš�2žห^‚ธ|œ'j๓ว&ขณพ€#*�สซ ฯึ‘ปs๓Vใแกง|๖|jน|'ฎด™ถ๙ŒC7ฮาแู ‚แข?๛ ฆฉ†ตo๏่`ํpœY็'n3แ€ƒณ๋ั�@9-ภQร7N OกaYiฎp�ูx›ดqปเ/DŠฆ๙ncต�ณ้๗ฟ��yฺBsำfdyn@—ณ่zุ่ิR<ƒoKAข)มŒAบ}E�้o�SคLจ`ƒส aี6ฬa>��๓ฐ‰6พ2t;ด*€ดi3{วฒววRส)ใ�I'7๐�#0บxแRPทฅกป-ฺCwึ“�ฤfฑฝ9t™๚HูqRF| ฑฝ[�”HเX๛ห0?๖a๗ "ต6ืCฟš��๐S`n2มล้ งilb=าภ๛qภ ฐถตั�“ม๓ภ@,”ทา7�๑oบ}4ย�ฅ!-6ธL'š /็Q๊s!l@iฯ‚@๖†ศƒž่SdC�แฟe+ฑ^๙ภM็[; ๛OฐฅVถC{gุ Oข>‘สn0ณ`fิภอ3ฤ-p� gXส€ะฝs๛3@pJ:ปา“ั�zษ๛0 il#ะF.o€`yฬ�i*<ฑ ”ฤ �Hฌร$TทLุC๚๑ ‰้ๆ1 ]ฦ;™ะ•4๙sํ—exๅY‡ๅip`€๑‡ใ่่\๔6ฐ,Eะ€QุแcิSQ<1ล๙JcํdY™%-ว�ซCXCมณิฎ…}n N�ู4–:E]ฅt์wd‡#xt$๑I๚่ฃ๗ัseฉฟ๗,ๅ �๘T4m&ณฺŒ์ตมฒ๘๖w�K‹ำ[่ต�(}8*FVฝ›ไiฟ�r KXง๔๐‘ฌ€‹บ XHP\z ๐ฮแ†5ต�์‹{GGุ9๖L็งฌ[U›ลืƒ!๐ู{4™mO_บ†c�ส,๛Ž ร†,`dŸฮฐ฿ช2V๒ก:่เG๒ฅ ี_ัŽษB qRCY[?๚Š Eณร๑^๗\_ะ3ญ_b๏‹ฒLE�žM5MF่ท๐๖Ÿํว�q6๐ูlคบผ�’�;FŸ—(๏ฐj๗‘%ๅช‚g’้'ห@y฿ดห๑ง   }-�7}VeJR?ฤตี—U_โศ่ำVษ’๚๎ฝไํจ๋H’ƒ๗[2P- ฮฯFฦ†๘7‰ขfุQ€ว2ฺ*Zฬw˜ฤรh๓bJlX/™๚|"ถ้>๗ษ=กธี ฺh สะ [%{๏3X ((/#๓�ฐ_X!6ภ‘ซ�—ฌ[K+ P๊>ƒฬZสJ๕๕,ฟ9ยฺกQ็สโaุต€ฃV|( qy้๗ๅฤ-h๙œ!๚bฮฝ‰ ๅ}R`ทขศR.3๙๔ HLฦโ<h้_๏ ^ดแฺึ2�๎SPเ]๎y‡g�ฤ3ฒG๐nรA๗ส็ญ$ic/Kฌ”ฃ}™(…<ท>—gอบมผโณ•ž1‹‚฿a)ฅ2ศ“ฏ*ุพ–˜ žh ke”ภศI์๗;ำ๐–^gE\Ÿ�ญฌ.=\มฦฏใt1พ๑ร7�ผ๚k๖/�g฿ฎj}gปศษ SN๐โ๕EVเ�ทโ‹�ฮ�ฟ๗W��฿฿บ๕�๏๘มG๏ืัไ่5�eKbyBะา0"า‹๓# u�ฉวDGึ„ู8็็บฝฃeZใธ๖pD9ฅWฃL๋pธ~๘�๛้“Cใg๖3ั:&จ5ฺาบฬ„่`h่ธ‹โ–xoa�TT*ฯ}� g„`อlQ_?ณา๋iีNๆี›W’Rมอ�š)ด‘ึSš๘ดnkZ ษ เTXร/ส/p]ๅGaิื lโณF“8k฿อด`Pl๔"ะhก่,0ฐั๐i คdE�จŽสูfGื0b<ƒทฯ{ค>aฅ๐าt�0“8hdX๘ผฮ[I)Š์ล…—^J๏ะXฯ@รๆZๅ8j|lgG-“ช้Œ�ฎ^| Dฺ‘0Œ์ร ”“}:% _ง<ม5ฐ\กFN u8^%”C”๒ฎ1ฌkjล@9†Gดž{&8ฺล๓จ์c$�บf๎EpdฯสดๆUž“gB�H ฤ๎วาT๗aญ,IซŸZ†านH๗s&@={ถ']บะO๐ๆ˜+›Jึฒ฿vไI=j†ท ใ'Pต‹1r�ๅึpฏ]=d๚ษั‹‡b ฺ๐8ฮูำ œ๛(’6ปQvข3ฮะ๗lcAฝพฑ™ ำ0<หt์7ภญซหฒ๒dล‚Bป|ฯLฯคฮqา{‹ำ๋oผEIJ{š&`”พ จw�g้˜@กสRX9อ�9ฦcŒ}94Nั|e‰นs$š žh.ฤฯlTZฦ}Jกœฐ๖]วbjปœผg้อSS3้ฝ๏� �ผ}'MAมณƒตN�:A๒&l'Ji7sd6m‚p)งvC‘๋๚<‹0 Žl๘ดฤ=ฅ†}|Œfช์K}cKฐEถ8ฒ๘0tขฟิชQ>>พBp�€�g@[†๎ฟxๅ2zolอ6กฃWžY.ถผดฤ๒#ปdะลํ๚ํXฎ*ภfŸฅ%ฒฒ8ฉา๓ี็u ฯuศ๙>M u0�r’‰u�žYjส€�dภZฯชI:ํ ฮะ)l2Œ� เyึฦl=Cฃ`lืฬ์ ฃ ๏#kŒeๅ,>}๐เฦ’ฏ-:…ร”ร†ฑ/�hศqŒ$ไ*fEmะXŠ��ฺล3~–€ฌdี^ว่คeโ๚yิศไveัศฝ๒๒Kมฌ[XX ว][<ƒ^Q_jƒ=า‚โN ัiVG(ๆ‚œlzŒงๆKแŸU“๊ฎะ�ผัฉž7kๆ ๐j8งจgฦXฎ๐3ณธŽ[ต<"฿@8๖ม@�ษ,N;ฒฏ’๎ฉ๚•�€-)%ั@$K฿–่‘ฒฐศ™™w NI ์vXปš๏Ho I–‘ฝดrี‡�“Œ:IPฺ 2fๅKฃฏกู๎๛c€๔ฮ—ฏฅ่๖G์ecถ Y™ฯห4‹บบถฬต6.๒dธWษ*่4bo<ฑNษๆ*์fBKุถvํSณณ (Š๔,จK ef)ซฒ&์kณx l,//S�ถ๎ซˆFžำำำŒทžๅฝPร๑_ฮœEguฦ๗Šะญm�K@ kฆž˜žžLk$dQyw Xำฃ„=์p*ƒ+?ส๛E“�[ฝn6U y}%ภ6: ปณ_รษM‚4ฅถมซื>V/ใ๗โglm-…ฌ:�4‹faa†๓ด ่I9‹&e�ฒ,'_92Xฐ@?P!S–โOdฟฎฉ#� G า๙๗จŽiOž?mhIKO*jคไRก rœ_Xฮi่d—‡~nฏดY~_}/ภใตN9ฏฎƒ ด๚tจอv_œ`@ฏM๚ฅž๕ญฬ,uนฝนd่บท๎Wถณ‚eูf๔x6_๙ฌyžูฌฎ็5รวA Œ}>มw?ว€–฿—ๆšศฌ@‰2ุ;KVฺ�:๘ฅ่‹ใฯn3mf ๙คs<ธ๖ฦQย 0Cถ8ำ^DฐY?ีืsŸVึPœc•€ฯสsฬ;ัชŠ`�๕L น`ิ–xU$€ซc๔‹M:ธFฒNL(ิ๒ป&7ผ_{l์รH“ ข}pm|J&c๒�ฐ[xฏภ˜‰งึศ@6ม&ใA6‡๗jYŠืึถฐl๓Lป์ปหงูืงฮ) ๘“ธ–่��:ป๗๚$|{krญf}<สo€ล์ง๖X–”Lkม‡:๔€๏฿E xศP=…กW-˜‰“แฃฤ�ฺ�ก Ÿ๏€=ณ‡V%ฅ}ํูน๎ถฦ_๘[ฟ�ท�๚—�ฤŸ�ดดบgfวํล๋h<9/^�Wเ๋�๓�ถ๗ฯพ๕>ฝ๑�ว๕(งWอŠ่ ˆ ๙ŠZ^๊๛ส่ะ_ˆ\ ล[  –เ๎์ภน๔๚ซoคž�^)Ž—ะ์ยwพ๓ป”(�…ช๓ลหœd2O2ศZ  ˆ B pu่TผAIๆz EVmjำา_oำัz๋พ๗กm`ะฯ] 'DงุHjee>ฝ�ร฿็z9J&้ฎณรเk�ฝขN–ืฅตปพŠY*ซฮ‹cฏaX[‰#เK#ีL5Eป ๋B๊เ™q eŽโำเสคะม$ะ00ำi)e๕%ธก##ญ=ˆR—peS่_!fw�๛๎sอ อิšศฐะ8ญ‰์ฒ =อ้,5ฦ�+๘<ณ ƒ๕œNNp�‘AฦูญS๊�,Q`๑Si}ŸŒ๓ต8ฦ2ัฐฉ…'ํ J7S*๖@�s ุ๛dต ๖คQื๑ณ๊ลfัq๚r3Oา�ไS๖ Žซ™ก�…–ๆ~ลฯqผตLฦrjy7=ร �ง๔ขง”Œฟ€A{ซYWšƒ‘uฎม่๒|ฑฌhRN‘/E ฅ˜}ภ ๋๚หqz˜๙�โย*cฦฐ—8Xฌ�YฎMขี5‚€+ูBึ:N0ว2 Vฒf<์/๐ไ้Sž!‡๑7“โŒ๎ƒtŸ์๒ศศ0๋J@ˆดถP^Aเt๋ๆMํฉ@ธ ูง“Sšศ•ื1*‘Œถู‹2 ค๛ชCmc,k�ํภ.t |E6#ถCฐ"๚nFD๐ศภป sooŸ‰#8ณฟ…ฒฬ•gkจ[iฮตNpืD†ฺz๓ฉ™ุ3_z ็!ฮpิ…rึฬ(ุ9�@UFKh&ะ�ƒ{TฮdŽhPuจ ฌWW†mคฆ๓"`๓:ผ๕ฏv’.ฦ3›8ฮ„ณf0ค ทถ7q.™ชมD ฟmtJj�ผฮ–ใ””ํj2lNb‘๎[ม๛ฺŠ#kC๖ม๛5€ชค!dๅ<อMt๏ฦ๙ฑ)กšฮฝgฝ†ณ฿ฤ~it\›ค:b๋ยน‹์_Ašขฮ}A{�ู4O€o“ฟ 2{ฤ™:เนO‰Šd ุZ‡I‚ฌ๛ญ#คl๛o‹๋cเ8ƒสฒฅH:�žฅ-‚;ฉฦ‘ลF_� �น๏–*๘}ฏkร๙ำ‘W6็Rw ุ:�ญB`นิ}*ๅ=:zœQฯาŸแ^ืใ�wตuC‹'ุๅ~mฬูH๙ม.๒๘ฑ๗ๆ1–ฆื}�[{ีญ}฿๗ญซz™๎ž}ใ ษR4ตPฒ%Kˆƒภ�‡&J‚A` ‘@„ Kฒ%‘โr"ษ#Sถ,Qค8ไpz–๎้uบป๖}฿๗5ฯs.;A; Š”พdOWWีฝ฿๗ฝ๏yฯ๒;ฟsŽkปAt(ะมยข/‘ะม Nฎฑc๘–าญปำ�ฑ9d ึ! Œtแ'žƒ๘–ณCฦB๛�~ˆลK5�ƒz๙Ql๋Af€p™$;ไ‚+tม/อฅว‡ษ&ส‰ Œซq)Sฑ'‰ภ”้ ฮณ ทฅ4�1ฒsˆ?จ.tO”งศุ ศxัV ‚koซอ์y† pี๑Ž-์,Aพซ์ณ2 ุ_{)([6†<8�&+ˆL๐�*สHšฉ‡vดกAzิMs›€Bމ๓Vฑั%xฺู๒ลฅ๖3หš ˜Q=P‡p=ํ:ŠฟฑmQฮย~๒�ฺiƒฝ๖97uุFep�Qมน๓=ฮต?"ˆ๔eตุ้Z˜4XR็˜้TๆิI&6Um2œ-Cฬ'‹จ์ ,� ๎”Žy่้"X‘‚ถจ™ุWuค็ืตฑYœบำ'มEK 6iฬ*ณIภQ;•ƒผd`•!Žฌ!๛)ํgfAUMIz๎นหฉซ›^4ืmiiŠณ$ฟทซ'ไgl|Š€‚เ’{–’n ?#JVื)็zt|รŸt‰vQpฯพ<ญญ-œ F”rฯ�ํ]4L์ฃQ"=หX'มุWก[gษj/ส`-ys฿ผ๗H8pžeเH๊‹8%ษ=‘ฑaษะ2lเฏ^”s?ŠY�๎ื>�wฌAึ9๎Ÿ๖Y=# ใ&๋›ฤ  UํKกฬ๑1!›ž?ฏobี็ฯฺม•์gธž20< ๙ฬ*>ฯฅ!nๆ์ดฝฅ๖Ÿฟt๕…�๔�›฿๘ฝโสถํง€K�g๐z �,๊��G�๒/�ฦ�ฏ}๕—nŽOOuPทูI็�ยZ(ๅEิา็œำ˜ฺย S๑31ฮd51รy(‰ต•ล42�(ฝใฝ˜Eฏ›\Jy๋ใ›้ฃ๗o‘™6pาู‚Fเ่Ÿส8›ตเฌqจ#ฐๆร5 fใค ู)ู NCˆbSัๅก`ค‹สrŒ1่Pฺ8ไ๓ิ-CSตF�็ลš�jjๆd5lฌ์@…สค9 ร ปษJ�5๘/ล8ซDTจหdaœฦฐ ญิฆw:"K"•fฌ๓Qฬขฦ:c‘iR้smผ`D๐\fคrŠฌfม,“น-สจฤD็24†\‹็ี่ห๔p=ย]ร‘ชฉ-/†ข> ๒ 2%ฐ(j'ค ่b๎ผ๘ษ‘G้ฮG฿ƒ~<๔A Bgฯ@87…“ส็จูร‘ฝ๛m\c๙s๊’gPr…ฉขน?ึฟCZBๆฝฎ๗2ุ(ฐŒ๔‚๎[Bฉยัๆ"๋ฌญ&XA้kpq์oเผm๓}๘�‘นt๛แt๚๘๑Lš$^Cท๐Ž6€œK›9Jิ(6ืืฑ€z‰ำข†ึ)0ศ‰ฺ5œ่ x!”JWƒคฆฮกTู�EV� ๊๐71Jแาัzym7�x๏&N๋Gเ€ #ฝ‚๘’N๐\๋า3ฯDฝๆ อ้ฬถ45G@ฎณฒ‹58—พ,“ažiำSำม€ฐำ�>ิแ{wn“ู_‹ฯ4ป˜ห๛r ุ•ม`จคตG‹อฯaœjg^Ÿโ่;ถวLน BX#3h�ƒžิDฉ�๎ � นฐiš†Jƒkฏว—๖†ƒุAฦด†=}�c?–.]"P็™-X^Zฃq฿Hศฑ๛ขƒะฺF,Žณ็ฑะ‚ธ,ฦฒฺ”ชš?:).๛€‚f32๔*ijkฆ‰`ูฑ]ฮตฝR*ิA์ฆ๊8�๖@p‘Iฎอฝ:_พ�ตมšฝ�]žƒ๕ค„๏”บ/ ฅ2ไี~ว์— T๖ูฏ|h๋(Bไอfsžแ˜�ฮ๚˜Œโข่2ดd‘Ou์Yชš๚4ฐถ&•žฝถ�)„z๔%Yฤqc8Ÿป”cYz%pเฬ™.์cิ[ฒ6,uVงrŽสœ๐œโJก{)๓aฑ4<Ÿ:Jy9†์›ŒƒR€ดRd02 ››ส˜0๓ท‰ผ๑Ž์*ใ9ห2YtบงคA:๙ิโv0|d;ไ!ทผ‰gฮNูY๏ธศ<ฃม4ทฬ3s“O๎3๛ๅไฟ~ฌฺ๋H›|ไzpDฐฤฑ--u้sฏพสxฐ—q๘˜<ฐD–l์4Kฆdฤ๘Yื“6,2r'€’u�ีู2—๊8KžNiำ๎ตฐืด ๖.๑�˜=ณ“พฺ;[S๎”#€ํ!2ม-มŽr„์@๒5=ผu/�{@๐Kฮ็8ถ,Ÿ=1ฐ4ะึXซvQภ^ฑฌผ{ย}™ฝญ๔‘^mt›็ูCP$[NFะฦ็๑๛‚fGG™$ปAv…g8ฮ+rไน@€g2ฃง*๐9ฒ 9.สตผ6หอ )แ=‹ฺผe7มO{�๘๓#ภํ…ฅ:f6m|‡5%ศa๚`ญูCืU�ซพล2rŽฐฏ�พ๕ม6>SพZT-ส%K๎จบBdUฐ��sภ™๎@ื/Yกง‡๗dเk0,>ึŽk™มต‘ฝOF- าn�HM‹�ˆ;ภ79ะš:{รd(iษIƒลํmm�šพ‹ �D‚�Zฺ $ฬJVE@/่!ัQฯาต—a์cืdnฦ˜=’f๑kx6x ๖L5k!ˆ`y„6@pยิLV’ดnuจL4ภMdึ`8_  ฌฉฅ1๎CะXE-xขฟtศZ^Šผ Bฮฯะู] |�ฎmุ6(อN)Kํอ‘j‚มU‰ฯืHซบ›ฦVข3ณ} ˆ�้ฉฤฯi๒–Z›j ง�ศZภ๔a_ซ2”ณข ๙Uฦˆ๎ง9˜I‡ฌ�}ฉ€˜ใƒnศAฮชฐก–ลšฤะ4ศึภ`!sฺ&ไ{�๐œศUVีๅg{์;ส)‰’ใ]๑`ฌห*Qฎขฤ}ณ?€dšบ–๚>–า| xญm๔_)vจ๕lมFTแฺหเ�™hไ<�O๎[ูถ็Œ�œำ‚*aซ่๗ฉฯ=WพŠ™บ#[—็�ํcภYฦN๛”{Pฆิ'6ิฐ พ๚2@ฮaqดฟ6๕V‡ณ<�ง)€M|Yi�๊์ฮๆฆไิEฐ=1A2aaP—D�dญ˜Lp,ฆ oeห`ู^Iัืวตๅ^vฆูฯซสCg–#ฯๆ๊ฅ�ืภšŒ<  ง ั=ึฝปท3๕๖uŽ1]kภ%ฮ+ำพ�dPฎ!ฏ1๙„3ๆ*nฝAษ3{กMWว์!ณ<0Wํ‡ฟรึลฯ๔QŒิ…ฺถ*€ ๕ต6ฮฑšลฐฏิง›€ ๘[ๅ๚NA��ur}}๒~ฟ๖9ิ•ฎณฌ ๅžํBNdwr|†ถึ?๊ท�ศฺฉใ ๚�Z-o _Xถg?Gคๆสš=Aำ๎โตซ�ๅฏ��ฟ๓_\y๑ง<ํ][๐g๖Tษำืb��o�๖๖�|๛'ฆ&๎P'Jƒƒใ–ยยœ�z๘z2vŽฯฑ–ณๅทตถHฆc&อMŽฆล™Ir}่ใK4W›"ห?E}}ๅL๐๚|�,f4™ม˜e๋€UฤbฐZ ฿ืุh( .UฺQŽข(!ฦ๙1+ฟK`i€$ี๐มfO3~lฬ7ฦ ๑žj๎fฦ–•q‹dU่ฑ วว็xญrx ณมœอฐtอZฤDŠศฆ๗ข๒ฐYคJ^f๗v –txœ;ซ5‹#\…d gA%ๅ๏๙ทY‰@61ัa™งึ‘ะyห:8-ๅผืฌsข จคญ๋(XทuŠR5›๋ผi{Lฑ˜{•v—๑PŽiยฑe๖~ฅฌgฉมฎ W'FญŒNป๔ุ&k~Qเ�a4Pถๅdอห{R!มy1M ซ;cญV&ธ�R*ฎnกฎซ.mฯ1ž&•}Pจ›๋แFว๒ส มhz๗ใO่d z๕ผšฦNƒWR3c6�ศฆg rE}<{—OuฆมˆนF๛$k<ศถ„-Eนืทuง๒–~œeFฟ�๙0œ฿ ึTšฺึuผ3`P Eๅุห#ฒำ1อrา’:ำ๎oฑn)ฑ๋Rfํkภ-เ`เyU‘๙•6ฌaบ|๑๚F™H๔c(ฦMวว�,ฬW!”๖*›tส`ัษˆ}ไsd›ุณ ฒ™\KCฆC“ญI01า ”(๏‡มฑN๘ =~<‚๑Ÿภ^๊แ<_{ฏ~ๆ‡๏S26Kอ๊Fบ ={ํjŒใlmmHWH– ’|r!ะถŠc/r_E6_ภJ็หZKrิ๑sฯ62ปท]ำ์Œค ๊ธ@D6Œ฿๗wยlะงƒ$แg˜ทa ST ขฬ&n!ปœ‹\๔F ฮr†{’Mq๕y‡น”2˜9๚I8Šฐงซ‡ๆdR,์~\มu๋q�d5เึ™Eเ‚๑;๙xfี5ๆ๖/9โ|8ยสf\ํ0.C]4:ฦู9ฆ๑!ฝCxำำฒฆส�คีส(ฒ็Šูeed{ุ4ุŸ›Iฅ8™(ฑ�ืฎฅb๎ฃณฏถอLš˜ภ™ น~ํ1ฮขมŠ™(ฏฃ^ ™Eวุ/์+>_GQ€ำ ่‡ธ„ณjณฑ=๊่ห5?ƒ[ตฑ�@  ˜ฌžŽ๏ฺ�L๋อฃ<…๕๓๛ึA+?๊ีpv๘ƒP็ฤG0ย}๊„�$Sง�F—นฌฅYษจYgฯj`ฎ˜อ4™G�ะมFV4จโžŒแููำ—ฎฟ๐J€0[Pฐห ์๘ฯqฃf�๋fƒลW฿|ƒณOŸ3๑dx €uH~ะ/]Bแ”? +mœ ฐ฿CDาฅžŽ๔s้็ข—ลศุ#@…ตa�::–ืช(0ƒ็่ฟ#๎3@Tฬ#m€็F“%’�w่ร่m™0R�ณg=T,่ิJ๑-bMlิ;ยš>y@`ป XฺBรลรt๓�ำว๏ฝŸึw๕]ฝ7ฬRK‹Žr1๖S›$CD� �๘ทบK;ช=2๋šฯ™(E–*กZฺ˜jDึ9šว๑^ื[ฝ๊ฟw9S%่ซฆฺl#ั- ๅEฆ›ด‡ฯข๚๙2่ด=ู๗gm–#lญwV ุธj๏|e๕/?S/ฬXส๊2(•ๅYLไUYะึ>ษคซ— l”c๏ษะม`Z]ฌ`/ฏใ4ุฐ›ุ๕“๖ำธZdุฦ‡�T อ~u€ลRงeFธw‘ีๅk๗SQฌ841p”ด|ย5พ4>๛ึkg้ึ‘ˆจฉ#ซอบ8ตโ@ฯฬ ใˆY7n!๖X€ีฦอ6Aิ๖Zถ`†ี`ฃญ… ;๎‘แkA#g ŒQ<gศวš�ฦ6|�ีำU‚ �ฏๅfs�oooO๊๎ฦโ่งWซOฅR›˜‰d๚}jƒ††f.@p‹ฎ9ฆิc ]๐รฝv฿”฿ly‡vห’`๊ณ๛{ZRGs5พTulh๚ฑะฆB:6€E ์ƒz๊ึ๋)๛*ฃ�AถA=ใo[a�ี@ื gk๙๛๘ศ&‰ุ๔สฺ�$ฅ ๔?@ฏฃซHP๊ศ�Qงูั—r๎sปgฒ ผGA ะ!ฌ“kแฺ*c๘ ‡๔ุƒadYใ�ฺTิฏeฬะ[คŒe๐#)�|ๅLj"A_3Cขข ธภทญEnKถvสี฿–0นว~ฒฒ›ํป€ฯ‚q7‹6�ฏฬ ~ภ—ื~E๙ืีŽคชcดร>“๒ํนืCะ7๓�๑�`tสhZ“มฃ>Pฟ›2๘๗�x#ธ‘ ฒLa“็4aำฟ!น๘0M�ไZ๎๔[‚ฌ�tา‡M�`๐์Ž๋€`ฺ๑ฤ~๔>%&ณ:[›c2}‚บ c™@IDAT ม ๎(ฟNˆiBฑV0๗d]บ|™๓Wรซœ๓ส}cƒ๚{(1ล?’™l้เฌg9๖Kษ^บQพวZ!ั ๕ZCGป†‚Š1}ƒ�๔ฑ๐dฤjkํy xศ๏ูAlยR;่็บ/[๔qัF๘๏už[`Ž คkฃฌศฦฒDว๕‹Q๔|-sแ}$=ูำr๎๋ิฦ3ุ ฯsB ็ ฎฆ`๙ว?�™�ไgแ๏�fmmต4ถงฏ?ใ`[žพ~+"–พ๒ีฏ๎ฟ๚ฯ<๘๗z�ฺ๏/-ฯ�;;�ฎ=;�o!#™“ก•ฝ]^e!P ำL 3ส๊ค5ƒ‚.อะ`‹ฺฅiฮ™ :๑/QcDจšฅ�ใXB‰4`—"NTรฏ‚ฬ:ู ฟฦLEขb ร€๒ฌ0ซร9ฺFแ‰์ชถQฆfuํ~Hmเฉ5=xH™าุใฉ๔ˆ?�ฬ๋ud‹Y�J=ณ�[, JE' เร+ฺญCฎ‚)ต๎0ƒฒ“สg&Q !็m:“dT�[O$ak•• ˆเ‚ฦJ#ˆ%ึEE๕D๙G 3ฯ' โ5ณAฯ [@†ƒ‡รQวแ%€ซ%0�ฆi^]žkiยWฬ�4’ลท ดH๘6อ�ฌป�&เ�d<ขŽญฮล��tบ๓{PiPHUBvคˆ:HQ๎ภžขJjŸษrๅ˜�g/Y์X฿ศๆณg๙ฦํC4�ฃ^็า5“โผMนmะfƒ™ผ’Xc้›๏|7-มฐ(ฬฏ‡ฎ—y๕8heะ›œลMึh{รกล๙+ๆZYy0ำฮืq๖Bใกร'ำภ{.*ฌjL{ cะ{วจ5฿Hซไ›ะ|ว&gำ์ย ๏q�ฐก ฯ็RฃฮC' Ž]ี?&+า#ูLŠโ�„ว`�Œ7>x7MMSถl ๔ “i๊ค>s9}๘มM๖‡2 ึ šผYึ@–vภtƒๆq6ผgๅ@0ข€ฏอhš๕/f�ƒ เjnyŽŽฃNƒ™:Zู�ฝN๙…e'::R%ซhˆฅSๅ8มƒฉ™้p$ŽใrxKดRG.ฌ- [:0y�œ8็:5–l๔๕๗โ่P’๒oV%่–|ฆ™))ฬ>ณ:SOƒle›ฃ†_ข๓กhเ์pฯ[\3"fซD๓์Xำอ๗ถtp็ืง dหŽำ›~Pิpา�|Žฬบิ๘ููน๔๘แ๚c&ิ_k!C Žฒ–๚P˜ษำa$?€“ภhE2ญญฉฑญ PยๆHtฑงซด5ๅ‹+ซฐPฒฃุ XGDY:ะH9@พภฌๅๅY8ะุšJxถี™ ฮ#๗ˆc|^ฬึo‰L๛๒สJšO{€0้'โŒภŠฬ†gแœ}ณK€’ฯ๏ข็ย1…!คs'-๛ 8cญ�บzำ6��OpฮBF๘Q—ฅ™ู น๋กlpฆu๓‘ตb@ง•˜™ิY4+-9Q�ณบ‹ญ‹s#ำ 0u,z(K๗๐<ˆๆs8rป”]ะGฃฃทŸ’ค์„e˜6ฒUุKWฺž0žŽƒ•{๕๚๕t�ล#๛:3…Rฏm จg้zา›o0h–{€BืyŸูษ/๏๕๒ฃ$˜โฌJU�ูณ#{ึ)<ภส9�I~๏Oำ>ฯ ยPA ขŽ_&จk �hภmไ‡ฒท#xณ �€ฆ=  r้Uโ๋Veนๅเ ๆขkฬXjำ<>ฃAE4$ร~๑]ถวy0ธ•๕ะึา‘ๆ๏?�๚ื้มฐ๋ึ%Sfมต lX๐:๒๖Žqก”๛}๔œฯ้๓ฉื–Œ;๋๋ี!ฺ&#ŸApไŒ๕๗ฺQลณล˜5~_า™๗๚‘ๆบŽค:|๎›วง~šg๔฿ฺpM ฯ๓L›๋ป1ŽW�d€ อU†ฝ`่1u”ๅKฎงภฒใq�น, ฎะร}ด–{บ๛)บuzfภฑ‚kฐ�/ฮmธใู >+ไ™ฤ40PU—ZŠฯา�ูลตำ�O>แ9๑๘ZฝฐฮูPV�ฺ๏๛�–ฟxONPฯ\ึ`ห63˜”Q็ bi+=๛สปศ�า๊B\฿@*J›๘,๕M1์ฉ"˜†ฟ๖Vg๏wง๔ฑ”%u†ฏZ+v%”–A?/${ZภD•*Xbภƒ"lvgขเภ้4dX+‘+Kส��S‚~อ%ะฌƒบ๎$…๚F›U�4™๕วฺ}~ฉ[ณณ3๘Rพษ|ณ��”R่3้๚=ื%�6ี2ฯ–มพ?@฿€ณลฺฌ,/ '4)๕Lฒvฺอสyฎl-ฟๅ2:อ�_?`ำย�ฤ– (๋$q^9๋ปL Ÿ›a*}Dd%ไ‘4ะ:มวดคTyุPฯษTRฮีeแ9๚ิ้B๖<แVCvฒฌณ�‚–้๒<ฃA๑>,�–๏"ฉ†Lf™ฉ|&๛%cC๑eฐoูA0ว๐Oน,๗ฦ9โgส Z"ภ}}ณไ|@ˆeB๊tjฎฏQV˜N‘g™.,zƒบ~สIหช˜˜ะT™^|แZ0๗6Œวงฦ)…>ุ�ว฿DW(G,D$ฎa#šฐษ6tีว๒Z&l์#c)~]W{'ฒIน2=88, Mุ:๑โ๗*ž๚๛8– ศฒ I-๗ ]|†^ฏขYปr6M3นdIb1มพ ฆeฎ]Lตb๓•ญ ฬ<ื$ฆฎฐ�žAeAะฦ8ว„ˆ/›?บFฅฐFNmŠhณไ"ฯ ็DI๘Hฌ1โI๒//]ฝzแ๚้Ÿ�•_ํํอUx๚๚aฌภSเเ‡ฑส�ื๘ๆWพy�฿�ƒฐ�wพwฏตฑ์_r€พU[[�๕ฒฒ๒SบrŸตถต–>๛์‹ต5 ฟฟ2?ฯ˜�CJ๕+)ศ‘โดCƒ:' ~8 fอh D6Oใคก็ผ‡UQšแิ{€Ea=ฌ*๐,`€รS†Lขฺ^*โฦฯOq œจข™้kพ็%าื7�xํ ภ(๓w๎าธk %u”Ÿ›Qจย0+dก�•fk]ทิm๏IิTไSะ@ม๗๘=๐#ส์./:ส‚๏IวUม๋xูIูฬซ๙@ Jหงึ˜9?9‹8‹n๓]ฎk}˜ภ„‹ขq0b#˜Rฃ3—jะ๚R่�ข฿็งึจmr2FC)�ึ๛?พGํ�TSืณ€ m่ึรฌี5hญฉm๘ลTัw%•ะ‰ธ„†B™ึม”‹ †‰9”vxฟGKS1†ซƒ“Gpแp™ๆwพ]Š!kนฝjp8ฉ3ฉี@โTิใ๘’ญ๐yฬยธ\k๕T�ุZธprjศ–ด ฝ ๋บ๐•ฉญcดไuฬซซ4,ฒทม์œฃ@ b �้ธ‡AฦH"K:๖~VvŽ=๏ทcySs {J_ €Žc ฦ์�BฐC._ผTSk–ฯ  ~Waจเ/ำd &อDฎฬ~ฯf:œ†0ฬN8XZdJ tะmŒ’ู ณ�พรšYจ-Cฮคด๋๐hตัฆู’้"๊ž&XJภฝCmฆ๛ฃcๅˆลfŒwwwk๊ํjƒข\†}่ยศxฒ๖6๛ณ๙ อ๙ททcHT|k“`D๊"อศ0ถส๒๛,ƒภ3งณํ๓่ฌู1^ะ เฯฎ็า�}‚อuฒฌ™ฯใ�โ€ณuฮ’> Sฟรž�ดuด“๕ฃ‹4๒_ย9สC.eJq๔ผ๗๔๔ #๕์'ljๅ๋ ๚#ล™|3`ฒQโต็ฏฅ‹ฯ\Jฯพ�|ฺ?g-1เ2้Ÿ��็าฬ๊bบ๗เ@4ฦ฿]]@ƒ8ภ�IŸถYZ แ๖vจ“€H2  จอฐ-LMะu๊%ฮแ๚�,๚„m รv‚ฃ\P^Ÿv8—๛#๊์๎บษฦ2xtwx๏๚_๊นŽ’tฑณฬฯ�นEูŽอei*ŠŽำF)›{ศ์:็ยฬดตภž}mE-ภ‘4๙ธ2ญ�7ck/!G์}๖ำŸขy็,zศ [ฐP�Soผk๏$๕G Aร@ฝ ˜A 1o›๊�D๓Qฬ9PXๅฝ(;๊๕@#zAฌ^tส‰}’d๒iง}I �่ห๓9Nต  Zฝ$KlƒLํ.:[;kฃHmฐ™LฏcVึ@สต~าwศฦฦ@"้ส๐3ุ่2’ kฮ>xO่™žฎntW]œ หภn~�qฌMƒณค�‚ณ็ฝ†‚ฤ}i็ecนฏตฮ‚Fึ‚Ÿr/ฺมืl3:K=a} l…ฯญN^'ณพผผB๙_%\M4 ni'uM<ฅ ุAฏ'ญ�qด7o฿กQ๑} $Vwฐ/๛ฐ๔ ๚PEdC ย�,')‘แ๙ฅ•—ฑ–2ฮd>:๙EŠL’Rึญญ๒ร+ฯXfRฺqภำุCƒถฃ3Dุ{›f(M“ฑj ฒฝ'งd} ชล๒|?ว๕a่}ร9ŠภŸ†f�่b๖ต ˜ฎ�๔๙ƒ1ˆœ๙ต๛ๆ^หบฉo๎L5�—cฝผฐg๊Pกพ‚๎o`ส^่—c[ ฃA#฿8Pw๋Sษ0YYฦ†|„า5๘ี๏”ๆฌ�๋g ธ~สฅ€อ~-4ค�ซธ}�ึๆ ]xvหh �Kิ1˜ภxmi !๋��L=%x$_`O?X–Š{mษkข?~†๖…๛๓LšฐIก~j๘ฟพ—+๑…ญ๔๏&ส *ซ˜าSYฎ_ฝ~๖งฟ^x�rบpq ี6"ตœฃบLz๖ู๋0Nad œ ณ†6::g๖…ๅอ3o0๖ึgีัฮนฦ–}:ํรQ่*n5–๔๘{s€ ‚ ๚*ฤ}ฮm0ฟ๘‡gUะ3JL-จmฤ็ื์๋tš{ฤ�fRฌภ=|ฺสr@ญC}7ึX?*ภ\ๅS9โฎŸ0เ~x้‡ ~๎ฒฆ๊#ๅฆ{›@=๙Ÿ S} mฎ{ช<ุ'B–Nyy! Iใ?๚โ฿~ฯd์ำืgหžพ�ฌ‡I฿aึ?<ิส๚?ƒฟZ๘Oฟ๖;ฏ@i๘kฟ๘�รํ๙��ฟ๗GMฟ�฿�าตดฐ๘w Œึ78จ9db9ะิKๅั๘œฃ\E๚uždํ �ห่ฌ(/FัNGX์ื่=”‹ตE8ต(Zฮg(ญั11ู>ณŒˆฉฆR5ฃฏ@ ็Aดญ#nลธฏ,สฃ TmสๆGฌ9OธœฦH[๋f•TพYดฺ ฬn๊� ณว�c€ABอ0ฃ'+๊ใ• พ�พสFJขugAgใ�vหwฌกJP๛%n'๔F‰ฌƒŽFLฅeCง@ฺy>Ÿซเภฌห)ศฮ|E%`ตŠvYทv>,๋dŸ…�กgา3/พc�๒p š.ง๎–ฮิึ7เ“ง|”vผfˆฆจ] ำB๐$ุฑร8ฃmฐCJ4ฆU�๎ึcฤZzรเ์ฌ-ฆน{๏Œภข\;บ๚ุK ูื้G˜W๛†g „์“�ด ษ�š๙7›b6๐ไ„ฺs:ณ�œL็ฦั:�fNt40Rุ ไ๋š™ฤะ%ๅlœƒlIaฬq0‘‡ๆƒฝ๚ฬ€ิ๓9dไlบท2Dt์5ๆ*~ Dd}จ๖~ถ t(rฌMฯต‡tC๖m‡๗Vเ(ึแทa�Hบc6฿ป๑๛BƒI๖ฯ๚ใsžiร]‰Aฌงƒฐ‚(sD'`›3 Wx(mhษ6^3ธV๖ๅฤ๛ำ)ฯ งจ r‘[๏WbฯŽฐNe ฿ฯวT3›0O^}ๅฅGhห "ค๔๑�{4Lz•ธูฦA$ภีฺ�ฒOAA่้L�งอijbฝFE;sŸปำG7o1ๆ์Y#าำY™ วC9ตEww7%?‹้ัรัŸ…LCq$ž…�แศ.ฮ9 “ ฮ �๛sฮซ๕เ2*ห—.&v g†i”ฒ|ใOพcU;9ฏอ--4ŸœOwn� ‡ ‰Ze<ž{##P*SWOwOkศ฿w>ธ๒P3ก„ณาัNp†ฎYก\ฃ„`ก”๋pŽl่Xธงใล&ม}๊a’ั6ทA‰ T  แุธ๖น€:dณ < x๖pHฅแG�>gูฒ›ำ"~ฯ@@ว�์พฮมฝ็=?2†่+œuGงv›€\&E6sซŠ๕OL4 ‡n`ึศž -ๅ›ิI[๊ฑGทf๛TrO:ต๊JN{ศ่Tgi™Bต์‹ูะ<(�์ฉฉ:0ฒw�ิY4ฤ�†อกฃ^ษ~lŒ3–“™๗�่`ฮi-�ำ+9vKŸฆ'S,Gsถ5?�?œฏu่คไp€swศzฌณฺ.kแWศผ‹‚P๙— j_๘w๖ๅฯร๑}๒�ห฿พม'ศพb�๘๒˜3#€YƒฮูžๆพXKJพ๎Lงมแ~–R&ร�V;wศพ„#ป์็W‡‡›ฏ dไ2Žฮำ๙–!ๆํ๋ศŸ (mฒ฿„๛รถFcJ3ล๊2GจฉSe&Aา@WD/’๒ ƒๆ,3ไ@�A0ตwฒ๛ถEo#V|๕ข“T3–€j2ง‰hZ(}†c+#์ 'pไT @ ›๏฿เ–Oƒ๖”๗ํฃw‹ะ[6ปฬ@kioDธ๔๙8‡�Nฬฐู™๙ะ=า ๔ ศ�าฯ�d๚“oพ�w‘๛gh๘๎;\รญd ‚o�๘(‚n๏#‡uธ’แๅy5hŒภษ=eŸe�jguๅืaฦ…\๐suตป+ก=�!{o?—W^บœn�ฮˆ I•%�'0oyืQ)็พ๏™๕wjญถS�.:ณŒ วค ™ื‡0่,>+J๋ื–จ–wศ7hiN9ภ๊โ<อ39๛ฯWฟ มŒฦผ่ภo�I—. s6ต‘;0ผh(ส�ุ ~็ๅย\$๘4ˆS๖ีก.ฑ ฺA V*ๅ๘๙4ฮ|฿eƒ,+Rธ&6@�!้2ฟดD#\'M˜นกืQ3ฬAƒืRสๅe;่ณ๊๊H‚ส,RNj™คมพสฝI�ู†๙&ฬบฒ‡! ์ฉ๗rŽผsฯ�ฬ‰Tส tpm๒เT.ืฐำ~ย–ิs((EุYF'ฑฃœ9›X�Kภ๕ๅรhlฌHป}่eF?xH ๔๎๘์j:4c hว�*๐ฬโหœŒJPผส *)›�&“ผ+!€ึTuแY๓œœษ๊ยไบซ3ˆึ—4ต:IฝฌNษำ—dmw6ฅศ๚ูEEไyt-‘ป<�งSศ๚ตแ;ๅำซฑ•๗VงnQฆ@–รy;>%e_•imH ๒fc�โ๎‡ฯpŸต6จ๔2‚ฬฺะ;์ฑ†r๐@ A฿ภ‘ฑ'๙ุl}AฯŽญ็ม๑ขสง ๘”)“[ร๋0ฬฎkk‹9็&ํฬจ{ฅํ[>จ"ภฉฎuไs.ฟ_‹พP €e=๖๕ทฅมพ.ึ€‘}v•ฯ๒hธKR้ ‡คŒพCๅƒฉญ“ฒX,๚6็ฝณ{7 \Hwฮ๎฿ฐ\ล฿lc�vIj้้ม&(ฃgีีœ™'๚a3$j,Ž5ไ๎<ปสqžg†5€ถ4A[ๆIษ)>�4ฏ๔‡ฯฑ‚ช~ฝ<4œZฺR�`O๚ญ฿๙ZZYdฺ`;{-ะฎฎฏข ๘Y–แ ศปGฦN{๓�mSสsŽn๒$*”’0˜)ฃ|ศโ แรem™k]@ขŒาš–—drฟ58xแŸaร\์งฏา d-ู้bO/๓�mขŒแ+๓๐+_�ๅฝ฿��ฏ?�ฯ�ฦ�qcใ{ปล/ํ�ใ฿��ๅ?�ร+๏NMŽ๎Nฯฮ_f1MKก%C๗t|ข€AะฅQxถึฝ๊ธชฤ4๔ฑ,ญNว‰,สUงภ์G!= ฬฆัOไิzi~!สPˆชมi(Lฏฟ�B๔A˜œgเc~ฯl+ูqฦsีโdŸC=‚—ƒaณ๖ฮฦ1*+ิid^ ˜mv‚ށฺGถ0”ŒYWฆ?I+ณS้ฝo;�ฟ� �ณํi‚ฤ๛Ž1โ‡8UŽสร๙�ร ำh๊�ฺ•:จŸuœ)Œ7‡”ฺˆ–�O1ๅลfrvƒ6๓~ใฦ๛8?U”HS_Jใ3Œuใ3J3จ<ฟ5๊๛า•DG mG�œฮ?S l.ˆ๕+แ็žห@รL๘ฦ\qฒ๔D–ฅๆsœถ@ญ!ฅแ๓พ,๓„ญEะ,mPัมUม ้™A"้{œLฐถบ8ะŸžฟv:�Iฮา1ฅ8œ!ƒ็๖Žfฒ(ิะDโ|Xo่่Dkซฅฒ๊X;::ณ๖๐ˆฺ?žซƒ=ฝ6w5# ฏXt…ŸLaิำจฎ•.฿vv๖\แ๛PๆยHHฒOฒ@,e("ร==;“พ๕ํ๏ฆYhใ/ฟ�rบp๕ba{zาsd-&Nwžฬ4ไ„อIฃ4่่J/=�"๕”fฏฮาsืžeNxkšฦ Y'ศz‡@gnjงุ�๒ ฮ7Žo5อฃ.^ธเ3ฝn฿บsf‘gฐั+Ž)ฮ]>t๖Sค“=ค4 SืุLmq็y+ญBm_[^6บŒ2ƒหj”eฝฤczdAAฆ)มม๑vlงe4น8ข‚\Rฟฝnิแ"“:ผž‡*(ภUต”e๐ศศว!ฬแ๏}บฝเคlส˜‘%จ)ๅำ~v7จroฃ8ŸwB๓T_่ฉ๓3:|่.Nํrqjํ่ วQ€Iส&ณ›‹‹@ฐ (แะ๑ุr์เ SSๆ‘ณC> ๕ � คrนpฮ^}ใ 7๔ยิN[พodbทnU™fฒsค>ณ€Dํfœ๙ฐะ…บส�๛Ÿ`v๐^�6ำวQ ํ;=ƒmญmiŸ@NฆLNเ ื�ูฐgc�h�:39K�Rฯ(9ฬ‚ไ๑๙yฮ%6ม4 {อฝ'œ\V4œอlุหฯpDu๔ ฅ ฌga1pL–+ะm๖#๚ฦpถ‡ิE{ศ%p:ฒSc#ด G่KA ศdŒํฃำฯo( แฬห ฐฬภ H‡7Ÿ`œp?์Ž๛,ฐ3้ฉล7s7|๑2:ƒQฦ]๊O{Up–;ปปŒnยถุ$ศ"จnชO�”&ศ8ฦ>อฯ-ล3ๅยผ#8Tุ�ฯฑฐ6S�่�=จ็ต๒0~p�อ�;O}sR/ึรบe3|๘ EFฦ@๔€5ฺขฬPšqืธต—‰™RY ‚Rืeศ ฌฺ“ร๋ฯออˆ ฯมQ็eะฺ้�เ(�4`†,ไšN=ฑผFฝไธิj˜n2( ผฅDห:า6eมlYก{fญ3 ]jนฑu่�€ฬ—_{FŽTh๚ืฐงฒ$,MXAืx/สษศjืmภJ๖šDBvจฌ'นm::!|†l9’Ÿe^�€X":�Ž#7Yˆ๏๗#ัโผเ‹Tิ–qžVข๙š# 3mๅฐจWำ�{ทกัฯก–?A+๛ ™\03m™‰็7ฐี i�u๖�D‰ฌ/rยM"๏UŒY”y”`ฆ?rHic1๗“‹oQย>p~ Ÿฬ3t€๓์ฯš6–œะรั,”฿1€ญoํNต�ฉ3๐ฆผมk*ธ\Ž,1{O น ƒRz๙ะ๐ละ๊ฮ ฯล!@#›<ยฯb ั5Ÿ~† ˆg� ืdขƒฟ†ศ}์๔kใeิyn|Ÿ็๗™ฏจfjอŸํษrB้šื|•ๅe@_ 0_!ภ„œ๚o99ศฤ a๗๐�์+`ๆ�I็3เ.z๑‡๑สต+่ํชฐน๕&e,w๒๋ืjs,‘มdเC0๖T€™—1 ž4่W๏ †ฉ(๋1ž—�๐พ๘ต๘lํ� g@๐z]๋”›†๘ A=มฏญ�ช�˜wX~?ซฟ์•/าiŸ[Mz ‘‹ฃ‰๘พ๋ฮ9๒3์U`ณO4มญป๗่ท45สสใ3๔/.ฬฆ‘G) ฎDทt„ฌญqสˆ:k•†ฯำ3ำ๘Uz�บ� &Ž Ai†P!ถ^�hฏห�s๗Y6’:ขฦํ•k—าะ3Cฉoจ7ฒH+๋(kฤ๗˜ง‰โญภฃ„{€L}Žฌช�œN$ุ็ชซ,Wuไsจใ๕ทeห“’ิฑฤYpฏ&~งข�ุ๊4ฐ๓ฎ_ฝ๔��ฯ�๛Ÿรรขก ่์ƒG๗cwwgส€Œ8TY "hQแtnโ”8‰` จE[Oฦาf*j•8NRณ5@*`!ูฉูLŠู'•Jูgณ~ำ,ฒFMสYวฮ @G\zฉ/•ธณำอชฉะlดA † ฬ4Š5dธ%Œ4 ŒkšฎฎŽ4xก/๕๗wฃฐiTำูCษ$2ธzsณฃŽm>ฃ:��๎7าว๏'ฒ ำ“ะ‹ง๑Gpฤิˆ8 MิMŠผŸ2Vํ”>SAŸสฬ˜�$Nส4ฆ›ฝ ๑ ป์F/c8ทAยซjš@œ/ฤ>MO.คฉูอ๔เ๑<ฦƒฒก๖๎�ิ�ฺŠ๐จ๓ธžใoZ[Z1:แd฿๙žŸํุว ƒ[ ƒฮb#}j:‡S^]–ˆ ๅั-d"7Œคษ๑qŒม;๗�ูำร๏vcะiว~iŒ—ก๋ธš%T^โ…)์ใซฃ(EปœตึI)6 ใ—ูf�์ฮ๋ฬ\˜,{8บS ิเo0ัม˜เ^t[H#โส๘ท{ถŒ*'RewƒEย�!�ฮ7ถ3ฟ4แpp1@‚d:สvฌ๗=��`/ุ,xถfX‡ ๙ว)•๚)9z"ฐ/ฮM๎๎๊bM�"๘ž…zํhั:(็:+}=kะS๏ะ�`๗BŸูฬ C�ˆต83—ศžLฮฬ„ K็?มนฺมฑT๐LNMฯ๑|8\82๘ว0[<ณ–ํ่ฤp˜y6ka9Š™˜z‚|ฒภ�{›๓ืฺู+จ2�aํั`w๙> j~xxˆ๑t#ฑ/SCฟb#VXy่Šc ~Ÿ�"ใ.+ขtเร�w,ม)Vvพ๕� rURฺ@ฮc%ภ€Z@d[yˆs,คtใ๏ผ๛N8ฺN0รyฃ่œง่C@ณJ:�๎YX๗�`bavY&@ภฉt์ขู*kู]ึCฒtfฬ,…8eั �”Gๅ� QY๕~”O›x�ตT]ำฦึึ๘�๛Zฤ^ขs๒ ฺฉ mb�ฆู2 ณถสŒ€ˆอ๎<ฌ:‚:�v๑>9fไ๗`€ํตƒ^uoฯYO๛งุซŠuถ‰ฆ๏q�8ฅ่.‚n:“ืิีf›7ฒ[8|ห8…fsWถxV’n่ ƒ#๕&8 Y฿ —ฏ•๙�]€Kœ=ฉ฿:ใฒ0†q๗|<”ไเธ;อ �9%v•yŽ๋@ชุ๋`Gํ)7U8’‚ฅvศ๎ผ€ฃJ3Pภ1้ท๘|6๛ฯ:”“ัŒๆง<›๗bZ๏…etŸk6ต&Bฦ็Z๙‘kPไ=$ชV นอ๗‚ํƒœ"ฑwุ๐ตฮฏ๛\P+ณฬ\™”]%Pp‚๎WFPใ๓Yw฿ซ ฐœฑ&ส†ฯYAฮพ�&ิ%๖ฐ@` “รŒCz๙š>v`'–mฒaaz๑์ƒะij|4tส!๗ยร#7(zธฌคปw๐q่!๎{``0uuuก?คiฦฝํ‘ํ”๎ฏ�4ีิฆไ๓™g.aO๓าร‘ัะฅ—ฏ m~žk;Nี"–้ศrุวŽ๒O˜WฌำR๖๘c๏ฑx`B๖œ๖=š�aW ์ โู@_� ;šp–ำn€—�ŒY็� ฤIื.�XีฉE>ฟkhf฿,บ๖พๆม†็†7ส’Zท๛Œะธ6ฺŠ]์กททX'ะ �๘GYฐVq }:ƒƒPLยไ `ฎ‡Y^Zฅ “^ธ#ฎํYฐฯK0๑%ิํQ็lfฆุ 46yณg}M�พ๔!�š-dว{75ู'่ญม๎๋ ๔งŽพ.–yb•K3ศ๊4 @c,น๗ส(Y์X.ภ›‰{ศ่วฤณ#ง๚!2,ส* iXNื2 �Zพ€ญ๒•,vR~–›sถ–ง`ตถFญŠ€g *9{]QK9`ฯ@ุ&ัะง]#ภ(;๏`e‘3ทรKm๒แCฮ:—๑Œ;€WผŸ�„bั�๒l๏ะุิฏ=๊จ}�๖๛สŒฝ_์ขพ๗๛nค6ฯ{Rงจ�๗1ืpคงcŸ=Gฺ–๔ฆฝ”Š\›วข๘_Ÿชนน#ฮฏ3฿=ฌ„vo?Y1š7lฃํฑมฑŽp๒ม ฯ.ะ”A=�ณ๎ู{ฒŸ9๏q$.�1�b์!€a| AึJ|•`@กซœ”=_๎ก6Z?ยๆ“๊.�TŸว ุฯ,ย�+ห6sี PŽ๗๛ฅ$<3G&L’oาt[sc‡�๗ ฒณ€.€’อi๙ก ŸC D`ฎšR0Gร๒ฉฌ+พ4:eŸ๕™šK65hชkขไEฝภ$ฃ๚†hเศ�SwWo0Pa๚xeƒžแง RXx ž5–“๕5fุค�ุgไ'ษ“ |ธZ€�B์ฐ:ย็QŽัหc›5ฉย้ฏ|�๐P€+น๐๙ƒมม� D�๔ŠŸฏ=ต”Iฒ`ุ�0ส#�i๔๑(F—่ใdX‡Fส,ขคด8็;Ÿ}๛S_�๙Ÿ๛>dผ‹งฏโ <~ˆ‹�ƒผิ฿��_9�อ฿๚r9๐ฟชZVˆ3ฃ z "FIyเpุU‚4s ฅๆ๊ษฯ์ๆฎั๓Pซ˜คกๅแผ๏๊ b”tเอฒKกฌ%ธ~๋ณฏฆื^}‡บ™@ภ E…Cm1ฟ;1ษ”… š่ญ,Gวืห—้œIำใL >{ŸlฅF†,จ๓‰ญYeทิกฝต%ฝI–ก ๚๗.ƒ7ำk†IงB€@๊ปสLzฐ(x&ณฟ•žJUG%.โ ๊@�็2["๒๊sซคtศคQkิ4ŽXฒฤฃ‡ซบš�}›ฉ๙<>pิะ2b;Tญ็ศุlฆฑG#tืล(U๑�ขt๗ƒwA|งฃแ\S:๒ป๛/‡qด)GyŸŸ’Y&4ฒ3๚6Ÿaำ5~D )Ž@Bตuํึg:[�ฑƒRz@ด—0๘dVถi„92นes,}๗;ทY2่ญmฉณ—nฯ4๊ร+0 ‹ฤCู�๖ŒHŽช)์9โŽAามo$kb/งŽบ๙ยs8Pq,๖ืจ;‡ชนฮžอMอฐถ๔ร(%๐็๗งธ„C1ซƒ†๓ธLฦyvŠฌ4N™ฃ‚rษ์œ) 31�8n\):ฯ1‹`หŒyd8๊๘์ๅ๕46:(`=(FฑŠ๛=`‘G๗XGภ�vถ;นู† Ÿซืy%nยูglฒ"”ƒŒ•šQเ๛fฬlD&uT:ก,_fฐ์ฆ์ุ5ฉฯฝฌํkŸz•ั‹Œ—ฌๅqฒ�3YŸน98-/ำ฿`ฃ9–FFGBฦ๗่—เ5ห0ฐสx]ญrดG}๚jฎ—qุฌ๓$๛N((f}ดภ„Ÿๅ$†+W.๑ฝช•.@ซW_•@ูQฃY ทh}ŽŽ#kู.แs,Aฉ…N[หl๏Lu เV%_+Qy8ฅร=ฝ\C‡ฤ็=O38d+ฎ\พฮK5NิŒ๔๐�C็ฉๆ่gะ;ุฯูHiš&‘ฮจ”“™ัภ๙hชฎ PฐGฦบmณ็�›+ลู…5ดMBห-ก:ฒsเ'D™yล๔๒เ๏}kู6…d๖t$ *u"ฌ;ฎ&`•N+ต��ฆ_ฯ๏๐๖ศw฿qุTbว8Z๙8ฒ–ž8ฎสŠบฐŒ{๔ฅSฅ่€™‘ฉiฌ @b&ิM#k˜’ัภ๙๏บ@๓2žŸค˜ฒœe๖ฮ์u5mย|ฮด7 ล=ชW| ูฃD‡9ฒC\K`ฮ 0็27บz1ป๘sฏdลjuธ ฬชุซก งฬi-ม›+๓ษ‘ญวs”+œศ0โ1D–ฟu\ซน�มหรQฎdปผบLvฟ&ฝ๒ฺ›้yุRฏกW-3zx�พK็BYB้ฤ=ปN�๙ืฝžwŸ�๔้:ฝ,ŒŸ}�:ฒVe*f�ํc–ฺLžฯก#้ž์๓\‚ทสผถ"Ÿ1^›ศžAKNe3p+๎‰MFU๒ว่“pึน-Yฺ4มํ›eQ–ซ4–ๆ ๏บ๚๛ะ 4ECฯZฟล:šY๒กสˆgV ร9ฦ์ฺ{ลฯ`๒�๛s;ธK—Šฬ๎m‡™ฑ.�'ฅIฌaฑ๛สฺี7w ืeœšixฒˆœใrฮ9๚a™๕ุ {๏ศ�๎ี\Z\J๓ฐ- ฤุ{๛บฑฃe๔šภP‡�รf~e3Scˆสาวท๎ฆปw๏+uศkmz�Wฐ&g้แฃวดข�ฬฬ๑ท๓&๚ฆ €��=ฺGู๖ ย}p๎ดฌฑ™lˆฯฉฏไ38VP–ฬาสำ‚ะ]^๑ฬึษL9ฑ"{ณ –Q5ฯืูึB`ๆ�KH gKmํื๕๕•”"ถฐVudปmถศ\ใุ+๔ {ไฝๆF‰6}Sˆ๎สŒœตห:A้๙)บŒ๒ ณมีุ A\๗ฬŒ?ขgื”๛o‚ม>-1–‘ฯ๖>iN๊ฯใฺศ‹oC8โoถ8๖ูŸ[ฎSVำศ๛้๓ณฒภ/ขrฝ}˜m2๘L*ฒ๖วœaๅRf็บพœ€ื,ณ|Dร[oๅลฐvวฟ๙�-๎m€]ๆฃฝ € ยFH•ฯ๖@@๏#ฏมเyตสJฐฐBMŽ9ุ z—๊AฯŒ{ใ˜�*zศhc• eE๕Vฤz๙ 0‘5:โ|™ค‘‰ จ-lเผƒฃ,ส€R–<4&ษัjขห1Š&๗์ใPษ๓๊+ŒŽO†hฎkdํ�ำ,hๆ้ำพ ค:qวาA' 9e?~ŸFP๋[œ4รœ›Cืฌฤ};ญ—ไ’#i?gํ'hLบธดยxe๎็>E�C๕R>ปบkภฒฆศzภqžLN:A๗.ฯ/ยT ดฝแธe'<˜HikจIผwrz†๗9)R�?}4_ฺefKะ]็ืŠ๔{qd๊ฯb#D™อy^�56XEzก6m@z1ฟเ��ืŸyๆหฟ๐—�๚-๖S!y๚๚!ฏ€r๑๔๕o่ |๙หตqnr๚ฏ@!/ทA่ขˆkK8๐ึƒฺแ�šฅ˜wฮืัI,” {xรฑBah๔,s@ํaDqย๑า ˜คšZ3w๕๊5’�†Lƒ8 ภ pงuรTัฉB๗vwคฺฬใOจ‰คqJฏŒ ผ’Ÿท@sา&ิึืs=ฒˆว<ฮ•JZcฝ…B5€๐kญH๖‰ ฃagqGœ�๋ป"โ๎LGณGKฌ๑๐T,.^%ส็๕ฝึ็‚Wฝฮ็>3รSœฏตEœ<‚๎™‰ัดถฐฬ่บ•t๏ฅPา1| Pส;ขX),งMฬLD@ึ`ฬj„.อN�Bgมฌมึ๒l8•8ำ„W�Œ ญu~ู@งฐƒ€‹KwศN�ฤyX!KผHfZภ^ึ%šGCL e Q� ฎ#ฯ่R\so-j%8งT˜๔^~‰ŒN?AK๓…็Su็`šผ�งiไฃw่”พgฬYฅ๖ฬบดS‚ฮญสช็ษฌฯdอ1ta]ฆ รภ๚DŒ&g•5FฎDช�_Zฺฺร€นŸ1:ํั†ไŸ าฝป#ศ๕แฌ‰ูกdL:d6๋H]$†Tyต[ท๋่๐˜eฒ4ลาWS‡N+o—f3ก ะBฅฟ๙ๅ�—_{฿๖W0›` c๖โDp฿ล็Šภ>`fqe‘,i��P�€ใฟ“��เ= #๕ฬ�ขๅ๕€+�ฝ�ฉฮŒ'?ทมุฬฬ 4Afฉ๓{ญm้ล—^BvqPศพ ๔qฎ๊p ๋q,๒1ๆ‹d—ฺr ษ๘lD“Sšžฎฮtแย(ฑ0]`-ว๐�9แุ๘l—T–คสFœ๎ฮFภ‡!๎Fgส์ˆำ5 ฆ>~ฬณŽ„#“55๕|ฝ‚กฉ(|๛#žน0ฝ๕…ทาO~้‹ะ#๓ษ(�๓�‘ิฯ}ผ๙ @ l3ฃScใ8ฌฌ3๋ๆ็๋คหŒ๐p�คซฉ…Q•ืฏrjpX<ฃ@6รแทop๔อจ˜=‰พ&œkณหฮใพ๚ฬU“ึ่\ฟ41ล๙ไ ๓ฬโRแ2๐ทืŽr$๖@ศ๒Œ(อโพฑhwnuƒ� te'ฌsช8๋{0>ฬu๖งWฟ”ฉ‹๎<ธ]ึeขŒMLDึฃ‹2ƒ•UBๅŒเ�ฌtX]fูmŠฅs๚$๋fVญˆ K๐่i-ˆ- Žzฆ{hSOƒa๋Œ3ๅ4ฬc=X+ู:ห�ป\ฯˆ"Ÿuอƒฎ[D้…\…2ฒc—ฏ_c=e๗มt{฿"ฐ|#�ไO}‰�ญ‹‰!Ÿ๗WM๖ดซ�r?ธึpnฆO ื” ภ`ใ๖9�ฌU›Y*เ�ปF/6oห(8จฺ&�X8”ฝ•lษ�ศ–~h' าณžฒ*�/ถ™jb ๋3ศ0‰��ŸL•,๓$ป‡€Cfะิ ‚์๎ง,;ˆPฉส%ะtฬ_9๗1“ z๙ง฿� Y๑zFดฮ๛c๛งŽยvะฟƒฝพx‘`›ละ�+pฎ}Žcฒ๚9tฯ๏้๏ม>5ฆภW|m�็พ๐้ิ�L_zแS/RžVœnก7Z8Oyi0พั'cใฐgdFƒอ†อˆ�wค‘ฬตฬ8” ฺกฃW<›ๅœฦ rs&"˜b=|๙๏zCั@Y�ฏฝฑย}DMฦตd;)ฃู๊ฌอ็<ป^่™bฮ–Œ=�%มu็�ตฬ6ฐฤ/ๆšส“�จ_+k[๘@>ช@๙1ภE%C๑ sึญนศน�žญx�ๅsySž๔��– -๖:1A„พจg<๗ฮ�{Drj’�า7��.odŸ` Vบ2dtฃ๏ึุ฿๙Lใ�จ�ง๙šฯ›_ๅo|๓ลี˜ ๔woคฉฉ’LX|–#อใ—ร0โ}�บฯJน.ดๅ&2ส,›„|๓อOู„ะMN€+๘้ฒฏ,฿ณDงก)\”f๎"NMฮ“Dแ\ฒ/‚ฐD6๕,š�Q–\Sฯ€็ฬ\฿—๖ฃ ‚Šึ ะ?ฝšI5Œ…๑ฬฒn}ญตซแฟ�ื�ฦ๖’Oz๚๚QฌภSเเGฑ๊? k�สฏ�ฦึ๚๒ิlEYํ]ŸKษ,4iเฃbG]ณฬั<ๅฆa7�ตƒ‚ี€iอจL ฒ พE„w1ธฅ:ฃึh5�๔๔ถคกกN2฿k฿ฌณๅ (N‘ว�a๊ž;‚&Jภดผ4G็ืูด ีถๅ]F–ต™ฮๅ๕8J�}้สีg0Hz=3ฒใc(ธฅp@DภCy๑า’ขฦ‡ฺฌš,œž๘ตก2๒Yt4T>ฃ IEˆ=ฒเ„ตTึข‰L‹ ;ฯv�ƒC›ัๅ#โฌุ3GณUtงฏ"ศๆำ�›ทษšาไ“~DฆA„� ก๏ยpิ฿obPคKša<ƒฝะู3€๒ีpู›๗อ› ตœ์g]}sPจwpชurช๊š[รก‰šg‚ป fqŸจำฐi…†P[ฎ-€hj4‡))9%ฐัy&+Kš]š�)๗%› kfL๓i˜ฉ#ˆฆๆ90ฌ›หtzž'่Tฟจฑ= Nmk?Nfw{p‡ u=ด“หใ~ญ+\ƒ-ฑบ?OŸณŸา๋�็ศ�~?1ุึนด4&;2ใฮ~มz๐W”G๛Pdไ#:16ณ†กƒ้ภs:>Jƒ่AYR๑๒Aหm์AN”ฦ\ K-'K‡/BtดžPีห+`6hภ‘y3ีYfel�ฅhดC(-ะ�ถ�ภ9ฮดŸํ$*ฒ๖-mอœ ƒ�}kข3ปFเ95=ษ๚ฅา,�…�˜ะฐยฯ61่ž;kก5ถศZvz~&hรๅd'ํ\ฝF†ิ€bŽLไ:]ษ๋คชำซb๔มรh`xŒmิูx๘เ1M1Rฮfขeœฃ@ณ7ะ#Kqย(!:Dชชc”ำณืำ๐เฮืkhำ๓8ฒ3D๘๋ํิlเdฆื_{% ^ผ~๒g~'� ฝ�ั๛้๑ฤฃh๎v๛๑#2์3{j�์Nวใ{Ÿค=@มSฯŽมฮ‡>›TnS๏๎ื๕dไz๚บSWoW8ฝ��€ ง€jSœ3ƒ:ƒY–” Žส)ฮ�นั ฏ ˆb‚™E่ษ‚~‡ฐ.ึ‘‘pฤะI:วสŽkE8๗นœIZe^ZซŽ–Žขฮฌม— œๅ สP5๛$lร4จfM2ิOfฌฏรมฝ0x ง“L�F€า”๚ � .ฬไš1S@ฬZ Xช ฤํrถ๛ศผ่(ซgะซาLฝพ2e@ซฮR้€ ๘‹“ูหFF7^`e78G‚h<ฟ/e)�ึ้BzแๅW8๋ตPย๗้9ะ,'Gี™e�ๅŒึภ Yฦนl"(q 6Yป๕หปส]@๗ํษ�k„๏œิ๒�มa˜GN" หgช#์�`็๐]ๆjœ๎นIท๒\:�L$Š๗ "”ฦrิ๎‡Aฐภฒe,2อบ™e๓พ8o6+ต.น8ˆภgœdx~UL฿ูHฌD์Iฃ�ั&๚Y‚ฎ๖มฐ็ฦŸแXAm๋%€๋šๆ ซ #—VWา{๏~H@‰~ๆฺŽtu:J๗`7๛ `‡<5ะมๆ†žEœuGŸ–ข›^yแ๙๔๖g฿Œ`g j้NoWz๙ล็#Ph\ศีะา�่ฬ๏`…ฬ~ชwตูี€ ๅ|–AฝŒ0ู]ูR๖Š๛18r- ๐ พljา@}*sฯฺ™ u€aM€๔–™I+๖=�JLkhfLเ4Aด฿ฐฌB อาŸj@eศาฟJฮ”ูm๗ฆG ฯูา�ŸQษพ›๐˜ๅตํฝ”`q“^qœ๓ะA่!ฯบ>EL3ฑค ถ�1๛๊๙สศา—‰ฬ-{กญ*  ดใpmห6๕�ฺ# Pฅl €LLM–1ลธMž;‡ศฦr &ด €@IDATฦWมZ๖ผ–6ืเุ€p‰Œ+ม`6เธEaํ์�dฟศ่ฐถœ�AO oN2ี์o€คBow�b†ฯCว0v๑ wg‡พHฎ&{ใ}๚Ÿlnœะ วRช-ุ6•�Cw*๏๙…�\๋œuุศ�… กฬ๑ม๘X&ศfc�Šะอ�4�iูใ™|Fฯj!บ)xฮ๛ไ�ซทโ๘นฟ™yl ฐ๒ขฎ fŸ)ม๒าฤฏ–ต#;]ำ€@Ÿ๎ื&ศ›ฒNิ๐ ๊หlฎ-s_™ิฺ*ร‡ั›ศำMถั๙็์;7ƒ๏˜ีWฑข๔–q )…`ซ)2ฒ:ลฬฝ:Yๆ3Ÿ่_}_ํ–ห-€m)š ฏ 8-_‘Rฟลy๖ŒศH”�jผฌkชอQbำ”3�สžย"ิ’-dฉฏำธ|ฟeR๚ฒฎG”bา ืษFฺฯ#์๘ใGฃ์ ฅŽ0Yศส[*#ำฒน;ะ�์+๏M�็^f\�ฯฟ<4”ฎ^พฤ็์ฮ`๗a pg$ด`ฉ~t'๚ข€Uhฎ๒๕z๔P)ยึชณ\'Jฐ๖nศ–ะฺ+�w@“แ”ฉม'โ�ซ aจ๊�8} ง‹{LAˆ็'f)=ฅ้๗&ภ,ฒ^ชลŽ;๚าj,พooฯQ->–JYY’|(ใ\ฺ'ƒŽt,: ๙yEYๆป-ํํ_�ท�ส_�›?๕ใ�ฮ4= �งฏั dฝดัลŸ^๖�฿ pxN�๑?๙�ฟ๛๛๐อ“อีoฬLŒa]ฮฎํม.๏ฤP๊ห‰Z;ฅ(Gณษ*=g(OŸ‘ƒา฿ยy1`๋๋n'ศจfคU5sฑฏ๐=ƒTs ‚_ช›ขฉว•:้ๅUิ†všงM2ี8}Cระ๗‡Pจ ส86ศZงแ�ศ๘c‚’อ่(||(x!#ภeไ่>้‰า�ฌ=ิ่"ฬgจOQDึค่i|ฯ™*!๘กัUy—clฑšกฤ5`งก๐E�ํN�อŒtฉโfU๒1ˆXฦ1ROE-w ฑ‘์GSK[4:ย' �-จ7Fย,ๆKฏ}& วXFƒ}�_;ฆWื4ฒNฅ|nิiข$;Ÿ!;Xb}ู‚สฒฝ8Ÿข๋๙4’ำ)7“ฑA0้L๖ฤ=Œส. 'G'าไ๘2™–๙tNฆซš Q๖†J!k า[ฦ~Uqฝj๊งY ‚ไLtE6P,ะฐ1”Aข๓}ญW,ฦ™๖Šช๊‡ƒ_Zถgฦำ�ๆ{D- Š5qW6Pƒw˜้ฆฝ‹3$š.%ฯ,ฟ๕y0FtงdLธTiู RฟŸหฟฯ1 .ะ4uไ๗<ŠฟT๋7>6ว�rฏ'G˜~FHE%์=œDว,Jซหื๑ึ๑ฃ‹v.อ ŠC–SŠB�†tQGส๏ณ†8ผe์ล™&›YUแ ฺูZใX.bŽ3ดร๛—ก๏IW4aCษjจฯe8Z2 ฬ~ๆ8%ฤ~v7ถa฿๗ฤ90๐� ฆ’I'i๓ˆฯฎk บ@Vฑ/-ร0YaZฤ ๋ตK ้,ySๆRpฅ.ฬฎฅ้ ฒ–x/ึอZ๗x†%๎้`~w;ม-†{‡ภณfใ*มตCœ พH—บาะต!€ฝ^š$ถP LIฯ}L๓ใqšu’]ฺภ้mฦ�‰/�X๚ิง^ใ�mค;๗o๋แน็^ @iภ๘Ÿง๙ํoคB๎ฟ G/Oะƒ๋=;|9ฏœ�#อœฉ*ม)tXณบึผ ๐6บ,sฉQeftt@๓‹pLh<ฺศ็ๅฑห๖C)aŒจY”#ฮ๒ฆ“ zฮQ8ฆHG-gi ฝฒ๛ง€ฬ ‰kจSxฦ}่๑้จEM%ฮ๚!ฒ่้UD€ฤ=œœเผ#ำน9ึQา#jy)a-zMะp๛`=5’Io๏๏Mu]-œฝึ “`\fg[+)๗OๆtzrMG–ri�ฦฅd ž8ƒ�ฌฑU€ฦQœ๛|ฮA ็�ต8งLกœ ^งI0ฦŽ๑Yก๖aะyX(4�โณy6x™ฒ'h#ะL้ ‘Ÿญ›๕"ๅ๛นศW/sนฉฉGmRWˆ>ฎ2�ŽผฏLฯฆ™๑‰๔าซฏกร›a฿ 8?‚ูyA˜๏๋�' zJ-DG6Rš๖3?๕dฯ{ษš๗ภ>๚ผตAึูƒตAๆีฎัiu ๖ไŒ`Vภ ๒ดฝว�#ห9rf๛�๛ฆบา฿•N6gืฌŸ2d#FƒE๛ว๘;�ฐxต=�„์{;็๓EฆwaฦW]]๊ๅ๙eฌ-‘ISN2ฌงเล ‚ๅy:ู!qฎm7 ีฺAlกจ1ฯลi= 6x(bฏิ”€s@X฿�˜†ฏ]K—ฎ\g*ำƒ๛€lผ฿Œl4Šภ)“ม ŽD฿:Žฑ&‘อฤ์ูแ… ซZl…},ษYฃ�A†x3ญ.ญง�ส…^แY€ผาŸพ๓�4Lp๐S?�ลhโ๙›�๓?ฒ� �rสh";‹.ฏคi้3้“วฃ”ณ}œ>๘่}WึcœชOญSžค๔Œ ธ€๋ณฑ…่;ฉาXUŽC€…=3{.ฐ%@เ๗{iำร6ฮ…์Gฑู�ต๐ •๖TะEถ  Rmr๛xdฤฅFท‘qฤ hษ&:Žf}4Ÿ์กดๆ%ไ๘‚@ฃกฅ•ณ ่€�€1ข|uถทsV`nฐNVvฝท‡Ž6ยŒฉฝPAผ9ฺMฆŽ� ๔0๔ม4ึ‡ฐํ„๗Q�ว-…-ิฒtฉˆ๛28ึwะ็ศๅdบi๎‹~๙��o35ไ=EZรG‘yฤshบถซปkŒo�&ุด—ลใฒี…น่ถH* '๙]ๅู— 5๗๔ฅชXใBeJฯ.+wTc96สฌ8๖=ใฆ,รู‰€œ�9๗ล3๐|�ณAฏ`šฎ็ศI6๙4นvชเศ[ฑ0�+�Sต}xxN)ลรปถข›"<ย7ฺุ ŒฉJ๊TSบfRๆ|tG‚ŠuดŒ!หB0;อBq]๕Bฐเ`—ฺtึ๛;Bงๆเoyฦ2M]ฉ ฆ‰ว๐฿YgฏœศQว็žำz6๎ัEw‚€ฯjp๊hแ\l‹ภjwog๊่aํ`ภRก่ƒปb‘-+ๆqv‹นืhPŒ�cbZเM= ‡ี,น6D@ั๏g๛7˜„ธยพF;†ZHญเ~iO,๗t4ไ.:^ปŸƒ฿)เใPBŽ่๛มพ ๋หช+ฯ  :1 วFฮว”šนV$Ÿตฒธ `aฬ†็์{zฃ ิ‰ทœAF…ภ{๔=ภ[ๅ๙ดฉ้�๒ภ,ู~€ชฦeชlภAนไqR.ฝm<3'j๖69ฤ*หิ";”๖pMู(-ใoผ<oR|<ํ้่Jํ๘๓่›‘‘‡ฉQŒฯY‚�ชkM–LŒอ.ฐ�ต$d|ฺค�$/QNํื�C {%[ฃ˜ฟeอŠก†žแ4๘*สฯูซญฉ�ฅ/}้�๓ฟ�o�ปZWืบ๔๔??าเ?}�›พg�ห?�ฺ๊~๋๛ึG๏พืHp�็bา˜E0ƒฅrด๛ณิ‡\‡L็�?*EA‘Sใ สภffญ-PีRๅd:ศ`Tutสค\šiQ‰ ู‘��๚เฝหVWUG๖žฮศŒ‰ซ&8u>�.ŠXฃfg�5œ<›ิ8 ยฑ/ั5ุ�ŸNŒฅ 3อุˆ@กu`ฌ ็‡a0๗1ผ!ƒฉbฎู=›cY++ขjถว~ ฐZ(๋�ญขิ9 งˆEึขฃ�Š๐hทbu+๙‡๗๏๐ฌฬr'ะUrู0Ž–i�ษฟ๘ฝt๛ฃ๏๐9tbgMe46C7็�‡q,ํmะ—ฉj„โ @ ีุ�FeV†่ฑJ9<HM™ƒATY#_O@‘žฅ–•qJ๋6žช"ำHํzz‚~ภ†˜"œ๔œ้ฆAดใ` Hgดsฑภ‹”:k๏ฃ3:ูฌS1Yฃบ๖”=๚l†ˆw฿O7พ๕Gi๔๑ภz20ษเ”ไๆวwจ‡งๆว์Œ์บศดŽšฒdๆศ@ใตฯต�>๙Œ “๋H9bส Rswu๚ศ(,aเค๛ต4ต2  ู9L?i฿ตš]ะu� Œ@๎“;"๚ึ]žโ€Xืผ…�ษšผล�+YŠoไ&์zํ 8s�ฐ6�ฯ ฐC†jccอ๛สศ๐ี“ฉฌ!&า`ƒ๕ญmm4"๐ะ@๊์+ึีพ�ฺ‘ ญ# �ฦi“Yมืา“uLlาdS/|ฮt>:�{=›)นZ๛๛ิย"แ—ƒ.,5˜S…“a †Y�dญ�%›tฃว2lFBp/ง’&ฃะลauะ(ูฑcตภุ €ำxšย&ฐ๚�g?Nˆg|—ฆž–ตทvัจq.ญxuย�ว็MŒŒฬCษลY+c฿ํฬพพผ ˜ยemธอ(ภษ้๖ฅ=ไณH ?ฬ�ƒR�ูึœึfgR.{ต%๓˜}ศม๙�;ขC�๘์“้pเ|xŸ฿็Qฯข 9G�Aฎ2ฐ">๓ูทƒzo�z‚ทๆึถ่)aฉฮ‚fu<`ฺ๔ฬT๚˜�žืZ}ผƒ~ดA[@ˆฅf™ n๙ตxู ั—gลา๕uœwฎYx ฌ�ิั์ฉูlki-ม๐O=“์ัฺ ธ†œ Ž๘Dห€แไใด;•CSŠพ`ฬ4ๅสZxP๎}Wิๅัธ๏ณW–ˆEฐฉฌฃlฆผ‘yป๚�หd“—ก:สฮ–6ฌ(›…์ป�๑|’_๛ศD%€Žู๚จKๆฌNMNLตำxื@จ]?๖ห>7ณำ3้ัใOBUีRZ†ฝํ€ฅv@เฃ�wำง^%๗fู�เL-ฬ/ลณ$ŽลๆZง]@ภ๒�sฯงGScถ#k>ณฟฐŠv<6J%fหีe�[]l�ท uJ!ฐฯ,ี*ร�œฒ—๔–™m—y ฝ๐{3ˆิ�z-Y ๊ มั€ห}2อา e สคvบŽLŒณง!ป†๊มn�D`9่าgd€ฎก˜,ฎ›๛*๋ �& ํuี',J˜์=ํพr๎gmoR^„=—a!hจฬdu ฟw์ˆห2l[)ๅd๕ฉทง/@ฤSไฺฒŽc‚.ACงฆธ>๖2ชeŸš(+AŽ•*ƒr{�iB}๋ึ-ุ๋Pๆ บ ”jะ5๖W2หZBภh_ค2๏R“!54ธซh๋Oฬ[ฦไxGY\2ต €-;(%ซ/ส^ ๖ั`นCฺoฤ ฿†’{[๖๛ุœDชฃDิ€๙Œkๆฐhฒ"�oด||ฎ@ฌ €Yuƒ|ฯQฌ๛ฌฯร�y™Y?S‚๚ื{’ แ™.‡ฝฉŽ“้ฉrN€ํ{LGึlโXIจjึปF‚์ชr€ร–๖nž๚�ร{0้7ีL‰™(€๑<Ÿฅš๎ฝ์ฦ,{- ฮฐน<ฝm๗�็๐�ํ…bฉ ๖Bฟ0�X[™eา‚์ ญŸFเX๙๐นีู’8๙ H3ฯภ2n’ฮพ ๚,Z๏F*บพืi6ขVNะ๙ฑซRรษoBd›คr[�.๛/xๆศž�n๔\U0hึ`ฏู๋ižฒจG#œ_S€BœcG7ืB.คฮ2‰j‹�–Vl`ว9&แฯ๋ง’�ั‡UหคสลVnn{mu.`๛V…�ื�qฝ\ ํ๊�ŽL†‘วา�ิdฺฦ†ข“…,7aฃ,ด)จ˜ฺไผyq๖ลตH8f„;“Wะฟ‚O•๔-ฌถฯ™MU•A}Z'+Tsฆ rฯ`8�๊๔k�๐—.๗๕ญ?e xN^Oƒ?'๑ƒธฟ๕ท��ร๔?�ฺ๛ใ”แ pf‹Tค6dฑ2jqQด"ฆW*_*Tl‘Qiๅ}]้3oพžฎ]คถš1?ะแOqถอฌ…ƒ‰มะ(ศะjุฬห†:งd•�ฝฦดทqwกbํ2ฺfz„c!ๅฯัLE8O6Ta๊hoใ€xhHฝ’ฮศ{”ยค6ี่่ฤ์iˆฃ$C› #๕ฮ”U ฟ�DzY]t5ีf> ะ๘�FฉผlไโYg มพ�ช“ฏ{c&น3ซvBา* วฦส<ูฯ-FีvธJ$KภKD]yภAๅ4„๖ๅ๐3ธE๖€ ็U/bณ:หV �Soะn .dท0๘l๘Yแุ6Rƒ* `'�๑ezcึ:Lูศs–มยา"�๑œ™�ุ}๔๑G�ศ9๕ข8ฝžAหR6` pY>�๚MRxF็ฒ� =”๐\"ฆ”2K_ถ(Ÿฐqโ) e๗ต๚ญตีˆ|+๊‘๋ๆz2G๛�6.MLOแฌ@E6Fง'ก�’%ฝ0Lฐ~@IQูšR~ISs้>เอ��Yz๓ฅืโน}๖�ะลt‚รฐDษQYตs„hล‚fษŽๆŽศ^P๊€ูpฬ สบ็\ไฒ†็23tฒคฦฺ๊๔ํ๑iŸ5ิ)“บcใˆ€j… ๙„uฑ&\–”g�๚v3xำ<ว$ๅ:–�ฟ/บ รtฮdฟพษ๐ ฺ,ืตหท4๔#ฯ*๛์หlrk๏‰ณœริึ�g�€ฯ‘rnฎ้ำื฿K๓tจ–rx�ฟ}'dปWKm“ฌฐzi'N็wppท ็“๕ญbอ‹PRวdV+ะ7็8eป>#2hi„Yjƒ|p3w€A:�v 7เ_ลœ'pln%ซFfjuู๒0ฟž๛–Ee๐=22Jศ…psฎ๐†ณบJ[8*เhะkๆqƒ�า๎ฅ5๗ ข?t’ํ+Cฦ‹๛๕ ๘™๖u1ุฟqใFุd๒ใศลฝœt๔ฒฎ8G\G็X�ซรฮฃhBxh๒}ืT‡U]ฺ`# ๋๊ต็bฝฬŽปf�=}8฿d%ูcหwt์ว'ว ัฅœaงpXz—ญ็"^ˆkf)�:ฏศ๏๕yT#บ�‚Ž”ๅ3•qF,;ฐYฏนlเ‰อt้�น@sXวฑฺl6)๎ู ึ์ฌฃน{\ก/ฮ`�™]ุmioฃ”f›ผหฑฐž—=@ถ�ส"lษE๖Œฉ8ญMiฐณ+uณnWŸ}6J16–Vำk/ฟM›i==ะ—�า?๗น ๊ PN˜\ฝr1�…ฯฝEŸS3๊๛�;{๏ซyz�๗=ท๗�{›;ฝ๎ฮ6ึ%eŠbqœ–ห€ „A ’rฬ•‘81aฤฉดeล€คD’%หjTกH.นซ]๎rwgwf๎”;ท๗���k>Ÿ๓๎� @๊,sษป3s๏๛��฿๏yฮsส๗|ฯ9iJฝฯ๕ฎ"๖GPฏY_ฝฝiI…eฐไ8Wๆํ๕๒ื�ฺ็น�l�*>(ucฯณฃ๖p“ฯึฎ๚lGฒgtํ2/8ฃ�nฦฆฺOG�.Kว’หฏฮศคoมฐ+จokmJืฎ]‰ฦรWฏรชAญวw�ไๆฮVš_ZI�{H€UlxN๊ไดyฎฃz‹ 8CŒไดฐษ„�ฐŸ/ฃฌ}4yฒฐ์ ›๗ฎ *๔YฎDb_ �-ฃ8Fงฉc๕GNต{ศˆำQ.sฏg๘'๗�c<+Œ0๛๐Iฐ),…ย`‰> ึ.F†ง  ศ@ฃ็ ~ี้‚ฺ'}?�ฟ;ฎYป#pะ��ฦฟ9ทุBื$[ณ�Ž องDรามCX‚ต m�ภd{ƒ}fฯต,‡ิ๎ �ุlถˆ$zR0ฒฅฑ=:๒ห$ฐฬ1—d…ฝf=๔ชจฅ—๙U„N‡โ ๆว้เรทโzž &=dž˜k‡๑ซ�ฑGLSญj๑++๙ง�”Šส˜,ั_ฑ%R‹ฏˆฟฐ˜-“ฬq์(เฤ>ื=„iเ™ะgt฿๕‡พs|”m"ซsํ™n‡y(xเšธฟHh์gฌ#๗]หน�ิห/ยF๎ ?จนต5| 6>ึ๋ ;k05A้ฅเ๛lIฏ@F” ฉ�9 �Œณ๎sGi(เบLๆrไต™2วšสชฝฒชโฏ��๐฿�GjZ@–ž}�(ญ@ุปฅzv/�฿Vเ�็ฟพ�๖o.ฮฝ U๒”fQ็ ฎฏBMี€ ๔rศdJmำ!33ุัWั%บฒบGธคฦ>YGgk~ํฏ“๚n h64ุ  ท*—ฉYšฅ@‰ๆใ?ก02%PFq†sPธ`๛‘Y<รฑ7Kฒ†#ฝIะญ2wrร>JWๅข’1ˆ3๐๐�tะอ„5ฅท]ิูีƒ*:ƒ†R๊ eทzฌ{‡*)S ก5V�2เŽ$ืิ`kdfHฏดaZŠ�^ี6�:ไ3T๔fฌผV!udYใXฬ฿ํ๘^โฺ�ูอฏ6‚้5จŠ:ค-ะ-อ"ฌ๑ต!ะ1†฿ื4œป…#บ•f&EVฅ…o–da�๒ฺ2ฒX#้}๊ฑั)œ%jษก�ึกะอศ”RชเD 8\h๏4ฆ!๐iก Vฬ๋ฮ�' eช–Žnœk๗ ฦจๆYŠ€Zฺ{p8ึำ�~#lLเฆค๊ฆž4Op—!`:อ‡zZ„AคC˜ฌiิ:fดmvฦGฟ]ณ๘ศUNM Ÿฎูื’22โ8šฯ,ฏD็8Fห–กœ.-ฌ$YKG Jะ–qxtL• œ๔ร˜แฌ‘!่'^ภA8€^lldุYsกA@NLqp-Yœ[ฎ Ÿ0~/0 {oกYO;รd๋์ฐ€\+[ ข์Hg฿ฐษšB„p++]ˆ ดT:๑ใุ4C๕4ฐ์$€ผvํฯdO š(˜�wญค’[’ฒฝmำฬฅ?ีu%้๓Ÿ� ์FF".�ฤมk^K4 \\ัU^ ดlษ’E€ฒNtฺุูœ>๛ูO“™ฟFทz{jdวY�ฺ €qฺ๋ d˜เMg['ฦ์ๆ0870‚ฬ’ฌf6b๔ฃแQฦฝ ง žท็~jx0แฤ็œqึธv;๔}3:ณf'6ึ�<vฮœ€%<{:`:Jีœ“6๚š๔แdŒ ฅ™ฑqœ –—๗ภbdt"ิZฺdEZg%z!ูQeIชณ@’ i Wฎ\ฃฮ�"บ€fO86ซำญq?œบ`y ทมN“1%8mp€Sfผ”,j€Q0*ศย๊Œ๊ฐกS#`\EM�p‚ๆaษ์0ฃฺ@๑๎�{tEงฬ™Q�ฅ๔No ˜ฒ|ฉ“็+#8Rฟ^่ฟ˜สำฬิ :)›ๅ&ฝ†ƒg]5๚งLฑ๐&h ุXŒณ๏—Ypฏ9?C38ึฒัt ฏ`šŠ๛ pG�โŒV๒™_�7�™ฬบะอ-PO .ั�๔8ูจž๎n๖�$�ษ๏�ห4�d^ gฉŽฒ xŒ๛#ซŠ,6“kD๗ขงชะ-%€ ล'œ ๗‚57@›™Ž ธ„๋๏แXฎ,รA฿ิยาฑ `’2 ข*๖“� Tม2›ุ๕Bmpf7)1pทlB‡^‡SะWว�ัcั-%ทเห ชญญ=€&ื๋7n{BTง฿f„ฎกฮ}Pไษ„ = งิ€R`มพ/Y šณไพฑผสk4Qใฺ^ร{;รก@0›+@%hSษด‹tA)k�เZ#=ึั“ฺ'›ฉJท••`™Šฃ�2ฐŒด{Uต๕\w_<A๘zf&ฺUสMt�r€=๊†%‚์e๖ฺ†ฉฺƒŠ„kbz๙(ๅLค?๘ืDเG‚๏วCรฌyqšฅ7Šาๅ �$=w๛น่0 B`๔๚k”8œงŸยrิ‡—ะฎำฃf�Rˆ ”#{Rัm\๊g,Rยฒรzmะหfตผ“ๅg $`ใ\0šฐ+ผ�ฎ$qเq(•jŽฉW._Š^F�ร‰zฐ—%Eร~ธ ‡๚sึ€ŠA๒ ฅzWฏ\arษเ;aI๊ถczsะRวง(ื+€‚ฏ�๒�Šิ?�—c”ะX๒‘,ันต์ฮ&:yณ{|ŒŸฤ9‘9ฆ h ูlฦ่ณฺ�ุ`฿FŠ�YZ ภตฤฮ๕๔{ชฃ7DLžF๎๓ks๒dJ!ฟ๖–r\โ<อ้&ฦfธ3๕ศฒ(่๎yะ็Š`‘5o$H ูๅw ๐จœqtฒ= " 0wฐั2a ภv๐แ๖)๑�$ˆึ๚ห’qš‚๒๏ู๐฿–TฉปlvW รJ๙6ู#่*8!๓๐ฝcƒู~—sJ?*J—jชลฎ^พ๖ะ}ณOŠฅ‚ฏ~๙wA{?/�อŸ๚–,šEv ิ•ลุยjส‰ยฯ$ฌ๊ผH ‰ z4ใฐw'ฐ๑ึ˜ƒ.ทg’็ษพ.Ž vาRd�นVK+]รภuฦ@๚ส*,LฑN�_G๕šrZ‚๛ขq37yB��1๊ํ>ฎfœ[2`.ฎ—ถ_฿“eG&๐%\žG@3ฆ+๐:๏ฟญูWู๐า‰&๖ทQฆขA7 ขk,ึ>๙฿�!ƒฯg่ณVWWp]jไSS†/นฝF8>”rtฦg(ฃ|kจOญม^ไัc’}(ผivn™&-E)“s4s�,ฐง/%RŒํ(*แs๎ก ��rร�๛ู๊v“็Q�รhCPม}๖—Es2M5Lฯแsแ >Љ(Q.ญฎลๆ7ึิ\ะD|เ ็ ถฯ๏ตM๋˜RM\)U—โ›ดษ~ถ“,`7“ˆชซฉ^nlฉ�ๅ๐ต�๚Ÿด< ุฟฝ/u๋ณฏŸฐ€าs๘'๑ฦ่๎|๗;oฝ�zมส๒ยงห8ิfjmvฉโ7ศะxแHAก.ๆ Wะ=�€ š*$�ˆญŠYใ$Šm#ฉlฦ]Ÿว…a†O*้*Yูู…™tใ&ˆ$Žข๓„ํr~Dๆ�Žฃคค“fศfNLL„QQฉ™mณ๛ธ๕U U š=��({_œฐPr(m3v๋ซ ม8 f8�Ž๚;”(ด=คC๊ สจPy๛%mQ;—ut€ Pl^ ภ่p๏ตŽฑ็p-Cภ†แุ$3ฃม—=ะฺูJ_ƒOร–8ุ ซw=�ผ�r๘่=j|@๔…๓ฟผ8K&ฅ%|šฆ‡Ÿ`ภษฐฃภ…žFํ๑ผˆ๚<ฟีษH8H4,dํฉK�ฆ&ฒจคJๆcบfSQyCฌye%ตหตฅ8€d1iผh&S#V(ห็ฯ~Fฉ๐{{dึAF†9ตp,Žk�‰~ 8ไ๏ฟ๗Wi~v†ภท•๕ษฌ๘+‚ะx๋ง๗ู๏FW™eเŸฑ๎‚){ณ›d tฦdตธฮา+^ฒ ษุ^ฃผ‰รYœถMmฌั๘G 'ู ๏ „@V'Gศ น*0‹A๖“=pt”™,ศcสฒBeg็ฝฒŠผฏุc3๑8r2”�่้€๓ข.(กใๆuex(Krp)ื‚>6‰’ฎmP{ %UYiฌง๗*ยฟƒ#—๛ำAณธ…`า2‹Uhษฝ]ฝ<=L#ภ†iึwฝญ#S�๊g?E๐�ะS+ก-ฮY[ &2='uk˜ฟ<9;•ะ€p}‘ฦUœUห^ึ‰l(๛ณห�๛๗"2”%4€์„๊,}Vล๛sTb ูฦบ:0๋m<ขทฤ มPbJยd๚๓ื� ‡q•์8์u็87!_ฏผ๒<ฮลVzr็�ิNษS`Y �&‚ฅนะ4๋๕lmโ™MSpึฝIGyฯfวุวu2แผ๓v”�ผ|3อNฬภค Dล{3ะwค"Dhfอ“กqz„AŒ{imุjฆ็ง๊๑ภ]2ใฯ8:�dแ๔+Ÿ–้เสาaDจ €DP.l งBh)Eึ?๓3?CsศซQ?ฟœYL>ˆR…€>k�;ฺ:ศถมึ8H๘šบ๛๚‚^n‹๙•eฦ“.ค๗�%xป ฐR™๏ผ— m ssก{๐kF dšอรแๅzfค}Qv‚€Nž_œ=d]*๖�่X่mNB:8=a๓ฌ—ฉฒ\šญUง.�อDNOฯ0ฑฮ8ี5Jƒ~�๗~‡๒ฃ|�๏ฉ€3eฏ‰6dิQd็`„๔๗๗ฐ๖าหเ"ฮ_ถฮฅ�7ฎค&ภฃฅษ๑”AW ม�&YON}… ฆฃO|2ผแต ^๔mzฦNy&jŽ๔ล๚S่Œ…*ลฟp๋:ภ /า�ณSึูฤฦใ'4‡�‚EB๙�๎M™๙ŸMข p ขิ—5˜ๅ่‚+™์A/gyอ“ตƒญBŒb]k8_ž} ม-GWื๖\NลM�”ฏ๑น๔ ๕ๅD`๕_&โห=9๖9 †๎:Ur�-}๑wฒ{ุ-Jๆf'็ั‘›ัษพPZ  r]@พณฃน#>_]ซ๎ีๆ{๕œบYฦI k์ฝ>VU=� (‹, ˜ฯฅLฮ>[ร๎ง=l@ษ �7๐๗fงf‘ &`;——ุ๛e๖ฯf…๔+มg(แูqŒŽ๑อ`'๊็9•ศฝ1"รG๐%šcsถ๒น'}V}BหB6IVธF๚ ฺ}�&ฯn€่Aวˆ*พ^฿4�Ž_ซๅนw๘ไZ‚ิ1๎“~๖�ศฅO–S2va฿บ๗มฺคO” *�–0๚�๚6fเ‹๙นฅจ็บX—\ฆM’hYะๆผONม เฆ,้ฮฌใบY‡ุ#Uรcำ4๗อ„ฌ;…รd‡๗/%ฮ๛ไ~mฺm๏fูš&W์ณแ=-:lฐ�[๘Gปœ!หINฐ๓–jf240฿ร'ว/*'‰ ๋rฆษ๔$ŒZtีภ ์hˆมJาšก6s-+@ซfฦCcฎaท6NGฅˆ}f้�;‡<‡}ด)fž๛Ÿm฿ฑLูI�ื+ศs฿`‘t”< (ฎˆฯ๕ป'C'{Žภ1ฯhS$ห#ฒฮ ๕ฟกe์…u๑๖LPฎ์d_Sำƒœ่pเCฑ—๔0 ๋๚๚ฏS๗=ฮˆ4๊Rhจ–ศŒOއฑิ‰ษ ๐<สฌx๐0m:j่ํโŸ!cUศ~<ำ!ูฒ\5@8ž™๗qฯ%ฐNiiณฒฮŽ6ภ (Œ6ำ€w๖ษX!8่l๎ิม!#;ใ8&›]:jตp็ฅ๋7าŽˆฃ}ฎฒ_Ž?j€)๘ศใŒYrภๆว<๓JN๎?˜เ:dฤะ ฒ�cƒ  ๚5dู้œC ืoร†Š‚”kศe>๋ฑc�œขC๖Aษ1ฒ:€:๑ •ฮคื้ชBน9K่ ๛Aำ ล!สNbPJ๖pN พคfpร๙็็Yv•0ฮ"gฏšง๋uzjYดudธฎŽฑช์ฯภƒ{�wอฯฑœ‚ˆ๎Nสต`ฮุ๑�Œำห/ฝL“&๎—, ๏™…Uด™็ญhหๅ oฒš€Qy€);dึNึนšs*ซ‚ณ…0ChเaySKG'๔cง;Pสม๏O?pN—็dx^Ppก—t’ํฑ`Fq‰ฬำ๏�๖ฟLฏฟ�ฝt๗๎Gห้�฿M“ถ“ƒำย่`y0@ำื์9h๏๎NudNŠV.—˜ษLGcพฅ™EสAV ้ณ่่ฦBณfศ๗็tt" �f}๋45ต๗นถใF๏Q‹žีต:าœy�'s':‰๓อ-ญ #œaภฮฉK%jœg๕ๅลหะ้ R่ญฑI๖]ภซJ๛ะศ#EœY‚Uฐ“ะ฿ฮy—vฌ๎ฑLสI&ี�L€กฃฝ“ฝ>Ns€8๎ž '๎#/ฺธ"J>Y;๕‡Mv๓-ทแ์jCv;ˆ }žY}‡œJแ— "[M]\อ™�dชˆอตU20rฑ_˜W๖๕4่๕ปณ61๊C ั~+๚๚8B๒Qนส€เ‡l:A๗Jdฒ๐๏��ิฯใo็ย๐aฏ�q€&ZฐNฤ&ฏ7ี‚ฐ/ฮF๖คท๎ผ˜ีkm�ถ็ฅ– GjณMˆ?๛2ใQ‰oฝ�Nศk g,Ÿ็/@&ัyศตฃต๑�qชง๘��ณgRๆข…ืฐ…N‚9doeFุP�w:ฎS&k4Wd�,Oๅฆ`ศq’ }]lฑ~‰๏ต๗“ฅˆสŸำ“j(๏ๅxกTdัR๎CL;ฅ[œพW]จiuА7œธถว:9…I?J SFฎอ—็ะ‹‚b๖•(YXd}๖™น=Ÿe G†แ ป~บ%;๖๙2sภ^+��ณgY�MF‰eฺZ} m/[ฬฮNฤศe? irhูg=eฐ}ฝ�Q‚ด�9ฺ๊ตKแŒ ร!ลgBž๓:`L::{Z1๗nยฒฐ8'ีr}ํท~{>F `~mฅ`ziแwฮŸฟ๔Ÿ�ร�ไฟ�Ÿ^๘�KOH~ฒ{ฯพ~TWIz๖๕“ผ�์_�ๆึ7�ษืฬฯM7ญ,-4เ”–I;?D9ฉˆฅขQ1_6๚ฎŽQuถt#ฌู•ฯ>št+๔ †'Š Iฌณ "ต;ผู`็š๗’u๋่๎‹@y ๅ?ƒ๓ฝใ๛�7พ—�'3ฟ0MMต~f๒ผFPฐ๑ฌ4ๆฮึั1hŒ์ตช_EงF๓^ฌ‘D�วฝYฟงาถI6EMG�h๔ฆ~ฬR+้—Y3˜๘กจ&lๅธฤ5บ�kฬญ“ึ้™ว0ี๑� u8๓๔hฤy2๛ต‡q�\_มAษะภฉuูNใ8ๅญฝ8”ต(wบ็ฏ,D]žŽั2TณC”f฿…kฉšQ‡2ฆว‡าไ๘841ๆšG"‚Xทbšnะิๆฮ๛ฆ?’š!CQ‰ใ\NŸYชzT”+ู™�ิ�›ญo]ฯุ3@๋hฆหz53ั0H9ฦส:Rf…ฬฺึิ6เผทใDะฤ†/3๑�rl, {SRIฆ้0M-mr๏๚ะ’1›: .พค%){<ฟ๕จ๎c?ร  �ฯ ๊ ฒb)๘คƒaiˆYžlv…;วฑฺลq-ฌYึ๑ฟw"„F5(ป8‰:w�ฆิ)ะ๐(‹�FZ7Wช+ูMะmƒw™4๒f๋�*pPอโฺดวyส�ณงฬ๎ศ6ะ๑“~ฏŒฌ‘‘0 € ภLง`Œ‡`ู็ึึVdUว๙ร๛ƒ}ี‘“n๋}๘๋€ูฒŽฺ�>๖๋๒ๅK ๑๓il|,uุ๐�Žo๕ิSฮ3OผUœƒdoัฺM•2ไ๛ˆพ�  žพะ โม |๙.‚Vฮ๚ศhiBF��9(ฟืpะ/๕^Lผ“JุŒr|ƒ}Y :d:-ต8ถฮŒž˜ขy๛ZD0jfO'ษ>6‰dr<MuึฬฤUำไ้ึํ็iวฤI9`ฏฌฝtษฬLœ  ส€ฤ๖ฒFfb\Wv๋ํ‰r‰๔D4Tcฟ"ปอt†‚‹Rึบธิi~&ิZš{<ีภ@`๕N™ค๗ห*1Hสร9ฎ‚[B n๙At Nทฮš๒หXพดN4hก3iP67GF”๛1pP\ ผa ถOL~ˆํ๋?O)™X)�Cฐk/[hฏdL 6Žh&ศ้yา‘ํ๊ํ็sฅะ61œก^}ูหใ฿มๆ@4ฮBึะศ€ิุ)€Ÿ{~D Kเภ๗)kฟ<07—–ฦง` ฃ8ฅ%์yฅCR้— ่–aI,มPฐ—… ฐบื~�ศศ๚*็๊ชมŸ:๏17‚Dฮ!gสกf]ภฃ€ภณ2==gาLn@ท็ะsfนะ"็Azถ๚5] x{ศž�ศUะุฦzๆf๒eO\ฅ)ๆ5€ญ5š่ บo}ฌ‘=,m2(4ร* TฯฒจBXรyด‡ฦgi0คฐTmmXศ[.vŒ^.พ_อ‘Ofืบฺv๒ ฆฌกw‘๋Rึ+‡gๅดฅb^cอyMC]บ��lฮง_รถ๓ฤ�<#สกิ\งท่ิŸq&lธ'รคผš†u :๛%=ธr„j^{พxๆ� ]ำ�Tw๎าศฟท“ytยG>$B“ำณd&ภธ็n^‹๒5ฉ๓%ข�6YXJะอ5bฒˆžƒ‘าหณ5๓l–S B/V๎ ๘ํe‘ 8้ฦํ�WAO–ถ~ศ9ตฎ�๒ล ฐ�จกวFผ๘าmž�ฯZ*ทสS$่$`^0ค˜หzzแ…็เบC7รภ�5{� @ฦ=ซ็—2&06ฌOฆ4๐U€63ุ%ีฮ—_‡ฮ-ใ*ลkA3กƒfsฒ ุNt7บ‡๋(ƒ‘เ [ฃiฒฏS€ปผะัƒ�ฬŒฐๅm‡€๏จกw๘ฝบ�‘ี>‡ …บวัŽฝkF_(รcSœ๖ึ…ูแ6์๊<=/ฌ ท๗ำบg‡ๆt๛่6KP๖6ลสu#ูย™0@ีึ8ฉงจ’ฑ›๕ส-เ๖O ผPถ“ฬา:1H=aOA1{8ฉ ฐ+Y*ชiแี4“ฤฮUถvT2 e_ู &EHฮ$ฬ.lทส๗ˆgw|ฒ™m๗�~Œ��‘ฝะป•‰ไ‰๕๔สŠkคrฏ\tฏg9รำ’†`ฅฒ–‚-ฅ0สaะๅ๑^V5ํgfั๛žžE&ุส2บHถิฬLš›ฆ'Lฉr€ฆSt†vC�NX_hI์)vัต ๔ณD?„สภY9sฝฐใ๖\”y Œj3-เR�ณฬฦ ~ƒf๏7สYู_`ฯF0=x>u—_‚“›”ซE?�ญพ˜/g?”{ูLสR๔Aแ ษlิN „๊_ู3F`]™ฑ—„Œ1๗ะ’[ห!ํปคbBม1ฐ>�าฺRz<1  ฿”^|�ุฆq=ห:-� ี ๙;� ›๚G_๙ฤฝๅ|P ˆู้ Vษ3!fฒ‚วยŽX*ŸH }฿B่็…�ซฒ<'€–๛ํง๘ ใฃ€7์วเหQzDIยโ\†{์ภy�…ฌีฌ˜x๘ร๊บoงบชbฆ2ดคz๔’{ฺูึฤณ2m่ฃŽ๖๖o�๕/๕๏�ํฟ๕ท๎ผ๖๕ืxšg_?๊+€x๖๕“พ฿๘_~s๙ฦฯ}ๆ/VวŸ<œ™™ๆUี…( i‰*œ่mPF้†Rจคะู�่:�*Ž%๖.ะAgR[žฅxั‘c(ฎU•าoc)k#‡‡ใิR Œย}อ๕๑ภรTฒ]zlV^ว[ฃ แQนaโฺ:t~ฒz  ๘•c‹ะึ:๗8๔�ั;*งึ`เ๔hŒu(uิ &U๒ญ�8ฦ*mฉํhโผ˜น\ ภ>แพe4HS4˜ึŽใ8๘$c VHถท3�gฦธ>uwŸ#`“vœEžทษฉค๛ฮ]‚N�KF@v๓ง'žคๅู1จ\ห๊๊1tป็y๙ๅL X#ˆฃ !อrFก™ฝ๕๖ป Œ.ฌ‡Z 6lzสi‡ข[„ฃP†"ทrฦฆžLจ4gƒyi_[fๅะ๖v&ึ;า �บงงJ๛9ž๑,จ๖-ญํzŒPbsŠ๙|"ฉt๎โ œฆ#ฒึ+8j41ย€:ใ[‹ฯงัค0cdฏ3 3๙๖]pฝขV™ฝŽ}ฦกtr‚ž.๖6yNˆNใฅ �Tสl›๗yณ,nˆึ.ฦL>+�ซVLใฏง?Gิ?ฝf9N”อขฌ_ฐะ9ึi‰ฯBF์9`ฟŠ>ธ3<ึอ"&ศ•ม0ƒ๛tR0L)+5ัฌ(;=Aฐเแ ิม๙F‡๕เ:qห>Yฎเ็tถwล™ณฑ\%ู็|ณ‰>กž™VG)ญ@ท'+บ…ใ)]ื@ณšัG‚fhอnJ!ึฑ6พK๎๚4 ย”ฑ;๛ฅ๎~j๓wา�๑Ÿำจ” „เวัฅi€\•|พฯ๊์ๅซ็๛p–ำ๗฿|3ฑOี8t๖ซฐ~V'Uเฆ�\dŽ฿ตSๆ$3•ž1”5‚Nๅฅ€lฒไะ n„ฬฉ™�•8ฦŸคsW.ง�d@ื(Ÿ!�*…:›1๓ฆปงcฉำ‚ิล^่9%d }Tฯนฒf0ซจค".้ซeRXก่ๆ๐ู@ ๊ณ <ท‹!์3ๅ.์Ÿ๓ฤซqฦ._ุร๙ณ'„g(ƒำmmผ@j+e(๊œ•••์ž๓�&9›K๚ŒŽ–‹๎็8ท�๙๓7žO฿๙๖_hะDฑ:7ต๊1ู†k็ ื|ถ3cง?q6ษZB๖y่๑ใภ3Kห€—ำqQj ๊Ÿฏะ›1“ ฃ?f“Sณ_E\StNg+๒ฒLฟภๆ๕e<ƒภŒูV�2๘ท@อLอfู฿N)บหL๗ฦ“œ˜i„ูg_;ฮ a‰;โ,ส8:#๘ฒมฃูBi์สy ฌž�ุ๔x:@IDAT8ฯi๔*แ๊z๏ป„๛ฑ|่YDฌCถ”ใ๎ž>�#‰ภ G&ฮภƒb่ฐทaxผ๐โ+แ€�4อ ก€ต๕่Žฟีfจ‹ผ—dฤžS“ใ!?;่dWศ^ํ๓ƒ'•*่ฤ๚ ค9 กฝง;๖s–ณc@ชยฃ5P*A;)Gูj๋๎H—ฎ^aofำ M:�dษ‰ ทn=ชฝณJ €ฎL0ฯ.็aฉ`�:๋R�…ะ‰��ฏต�F‘]ลึบ?ŽxดฤะAฅžทซœูฉiจใ€ี�ศซ{่๙F(ฃข�vdปธ฿+W.เ40Rอ ่โ…๓ ต YฯผF๖�„€ี๊๊ถฒ ม)MB94Gไyชt›`๐ู?fVฦสr†RHƒ]@Tฮœ |๗h}ป�K_๊pๅศเ฿๓)ใ—2่gส>๐O}Œ`&๐yสiถS�…oมท“z ฐคoหJ3iq€อ๖ณš9�ใฏ•ฦั็ ร’็>8๏mญ‘M>ข‰หีr1ณPobฉ”ถส@ิVnฃe,Tขง์+ีภw9k–� trKBx^AŸษž2žW“6่�•™จ]ฯๅL–ต๔ฆยjz Uั' ก5๚•ใG;H๐พAฏ” ๖ัR‡ฆ–Ž( เr๚U.ื๕�ํoฃswY?�ŠๆNไฏา�งx�ฺEK๓ฒฒลย+—>_๚sั‚Š[พว�+้x‹?ajศ†X^˜NKณ3dฦ)ๅ}6?41d9ฅ@ช๚ฃณท#u๗1-นจ#aฒ  ป€>”ๅsFฟงzึ_›ฒ\4ิีาปง+ํ-ุ-ผ2ฐN2 Žธ_K,P‘|ฉ—(;แ|๑Kพณฒa?ๅฦ’} G.๚oมrม๛B !๘o“ปฐ[์kภK,ฆqN•A'Ž�ปว^ห�[�ฮiHYเ&'�ศ“-”eeั�bฎซ๒ช]‘‰มป๙@41๏-C6๔•[M›I๊uถuู฿ม;ษuท‘Va}้+7bห์็ ผš„3๑มใฐ๘Y่lu‘kฎ๏�td้!z@฿cYฐฮEw์“x๒ฺ–dnยfXฆ9i.๚หฒm๑ �1(•ุ€yถN๏;๏�Mo�ๅwาt�าา ฯม๙Gพ;)<‡๎,/+9Amึ7ีN /พฺฺู๒๕[ทn�ฃ_๚ฅ_๚“eจห|๖๕ใฒqœ~\n๖ู}�ฟ[ ”*n๓ƒณณoๆ��� |เ�เ7*‹Šหr0Kิ‚ช0ิ<ขตfฑ&ฦฦP@+dงE8ซาฅ๓๘Gย@…f-กu\Ž๕SแัPkyy*ีVะ`Œเเร29&mŠฬื^€zูPึ@ภI`_„รN0g�ถ� Dเฃฮemย?QฌP่P๐๗๏๓œjดŒQ.ส๙cnไrหx0…#%Šฉ$ใ ›Pเฝก8อย๊”9K}ค�๐ˆฦ†ิ*ึ˜�กv‘`ฯqEf~mฦehDนฃง‡ถ+�ฝ๗FP จ›จknh๊ &๚9เ–4p๏ฃศโ�)ถšภอ€c๔ษฃดตบูษถ๖ถิฺี ญ@c๏ฬ๏2^‚ำ”>ะdŒy�ปึ�๒๋�–‘ญil๏ ๚jYา<่ถงฐ –9Jฃ3wŒ๓ฯฟญฎฉmงซจธEฯœๆP�œk€๒ŠZŒo4่sฉฆ๗‹…ƒา>“ฦฟ81>v‚uฤภ@‰฿�>Nใฬ—^XUSฦฝ0I€ŒƒเˆมŽhฒฮ‹{ffรfL:ฎ65Ttขํƒ–™4|^;’+}fฌŽ‘ฎ™ ู:xึๅ—eณB:R–T8ษ๕6๙๖0@:เ�ื๘-ฺoญจฦP ฌc(=ฮ,’?ื`k4ฅƒ๚~)นมbภ@ž\้Œ๊@rน ๖้,X–ณ ั๗๋D�-นดœ.ำ\W๏Ag[‡_ I™,แwv๖Gh…ขg&W9vฝฌษ4๛๔4“h9†ฯ?‹ผ™ๅY%ะฮฌ์Rำ ]œณPฦš‘–f฿แxn๏ฯููz™)ŽA%�โe8PM�ึุ์ไ\๚ �M2[าฤ“ฉ๔๕oคRžูฬbiu!� ‰"›วิ;&ฬs“c"]u่�C’{ฉถ,ฅุ5D†t์h'}๋™ qฎ]x™ช#C�ปœม๛lะไ'ล๙๔ฒDt–]_ฯ๐j†๎�๕นiœ้ ƒ“ใd/ าs|†ใ,‰t ๗้•อภุw๕็A GีY›9ๅ„ฬLฌ#๓ฉๅ๖๓้ZGŸผั„•L:์•=๖d0ไกGญฐEq;ุ3Lข€6œ‹SvzLvณ”FL8ฎK™t\ฟัEZขY^skKf`mxูB]ฉ@Tu3aหdส\ฯf&X˜m_ ป�ึิฌ%มœ\ภฬ*พต้rœg+dณ6ฒฒs˜eญ-า gLz(€—๑2  �lถฝŽฮD^e;( eุ w๐ศงฅ•8�๙ๅศ}X๖v๑ฟฺ ชธR แิู>;ฝvH7ณt˜Ÿอถษ๐8TธธฮษA&๊3‡sพkศ2B�฿Sœ๐uda‡{อ9�I๋h–ZYommsธ‚ƒ_H€AิvAแ๔| j nUฒึ:฿าูOอศ๓;๕mเฬๅkื‚Ž๛๐ม@zผ‘z�Qสฆ˜:Cเไt‹yจบO†S7ใl/๖_"Šเฟ’ๆ€w๎|@@ืLI]๛ฑ/็/\J8kKำ“Œ&Nƒตอโดอ™=A๎ม฿p‘+ภ’]ณ่BSUœซ<มfpT�x”qฮjะ๛�ฝ2้*‚%ะDู…๗%M�RZ�˜rย๚ฎ’^ @h$#}ภพ๙y5ศฤศฤHใ,ภ”ฑษภ@€๐�9‚แฑ›ทr  งฮ๓=๔ฃhH๛ศ” y‡ฅ*มฆ|๐รว๙Bz๔pๅ&ุ#Hบ~๙2e$+้อw~��่Cึซ5=ฃ?2ฐHPMุ#@)ข?ส๒าzœ_{ DPอบkหNื้H๗๛�๊‚๓ๅ/}9ŸNณฐ่ก( m๐แธR๗๘b;vท•า ห�N์Cฆ2ณบ”n฿~.-?z�8OuฎทYTQมณYXP{fGศ๏ฌDiึส/๛aอบ`sฦ˜vมฆ‡%๊EฮทŠฝผ+3ฟ‚ฝู๊P๙ศญ?ำWแญQ็m๐ๆk<ฏ5€.3S3ก;j FM2hS�=ท_๖ุ;�DgPŽธฒ˜:ปษt3Nxx2ีแ;ิโ›?ซทW ด์-QJFทœฯฮ;6�Kะ +%tWTwๆPz�ฺฮธMt‰๗งฆP< {,H “Cภ}วฉ:{ฒ๙>n.‡ž”ฝฑฟArG}M๙b`๔.๋ํฝ;"y{คซ„yšdXB6๒i’™KยH�lีFุ๙ุžตฅ =˜˜ฆฒCF๖sƒFšวm ”T /eษฒะM gมํฌบI›'˜`IiจœŸ*Œ|ฮ�็฿=Ž> ผฯ๗XrQื�ž๚/\`ชbzฯต๑3ir๔ ๋h,๛†žถaj!๒Vศ(ษบ๚.˜˜ฐ3Zธ฿โ่F€ 2�e์'ึ3ตทvrล€ุ[0z244ศวF๑;ม&วZŠเฺ๋/จ”!eG9ถ„ฒ@r‘Cเ^ส>๚™t CŒˆโ5˜p์ญ�หฯ� ่kฟธ_์๖Žษdุฯp�›`ฌม@ZเพœJ$๚k3์นูE๔4 ;@ฃHxฉ๏•kฮr5~Hฒ92>Jฃๅฅ๔•/~1"2Zฏ]>ะ�ส ืX[ฅฑ)พ๋6ฤณ)๐u‚�ๆ�๘^๖#b<7�เcรฆjฏ=#ฒ†๔‘ท3๔'d„`�™ษ ฅ^ ์;ภ*ll.๗W€>†ญ๊h๔rึi~l ํ“$,ฤhhชษ๔_ฟ๚ํย†๊j+j?‡ผฟSX๔€2ฝ฿ก\๓^{{๗โWพ๒•9�8ค�ูืใ Rฯพ~ZVเW_{ํ๔[฿otyjtdeeฑysmญฃ”PบšY`า�ฌง;J{๑าฅ๔™วฦีBŸ๑4k7�e2Ršค›ูQพ วบฃฅิ“`ฅ}ฐƒL–w ถ๕ี่i”R–ฆhฦVEfถาฬ‹Nจˆณฦ:~Nfล Dร'ญ3๒™q'K\ ีLg:ุพ'b(ตXอX‚ำๅ—ฏuื๘›อด™–๊šš๋1ุ-ชGั\Kcc-บตฅ�0ฒMฮ^๎ย!Šฦi�็0ls8Š›uุd^†Ÿ0z’,๓Tๅษ‰ก๘ŒึถN‚jะ{๏ ล�{๑Zj้๊O#๎ฅฟ�ำ•†FGp>iศ4..ฏ’ุวูอc=Y7๊ิ๒ห˜]Nฯล ”rAA@น”z\{ึป”€ศ%๑ฺWฎฝ@]๐M�"@…y€Š*จซLxภท ฑvcS+†Ž �ฏ™IฉีำO>0˜โ๕5๔$hKM]า"มำ4Ž� ŽๅฦฎGƒˆ‘€ƒฬ๓ๆ[ŽKˆ็ฅƒ aำ ›ง‘ี)ูL™Ž้!7‹* ฦ™ A:Tฟ-: ›•jงใ`๐๊>JลŽฮ์M9ฦL‡ค'x๐รฺ_y-)ˆฮ/ฅภfYRf\sƒ์ง€€เฬ1@Šเย6FQGมMาภุšIทึNค฿์™=,ผŽ !�`Thห{ฌ/nCฮึpzฬFIt ๆ้็K_ดqdY  Eส�ฎY nƒฺM{|ฌเ”Œ-’mูข?ฬ่‚g๛8๐”Tp��จนQœ ึภ’ข๘ๆ�W๋๓E� HฅาึSึฒJฐNM๔๑A ศF†€XgZะว�Y ž๋3Ÿx1uP†300ชน^N…cสlt™#'M–{hค\gy‹๑lฐ[บ๛zา๘๘dบ๓รฮ‚๛Sม๛dฅXร)UงKg)ฮซู[�ถ ุลœqื์ฐBะฃ˜๒ืiัŸ๘ิธ L๊|š ึ‰R้่d:ะIอmํL2้ภูงใ>‚ฅxn“ณ4^ไฬz>+kฏ‹2€}ึปh5ม> ห>@g)4๋>‚ฯJาปอPOLŒEถถ๏\_XN9 ๋2>6ž�ฟ๛~ฬ—o“ำiุTŽ*ิ้ด�dฆ}ทn<P„#ศ�–q�`กd–๑โ์ฟม“!_:ฆ'�ซcี๖ธ/ฏŸC)Cv�ทrWŠ�ฌ;FOx6,� มeMอไฉs(อL[Nแ$“3ล๒&€JBฒbn;Ÿw rศu  a/˜UดAื)= Jญm?&€๐๗วy��ุ{…5rJŒ‹_แศUไe•,32ฎLg๕๕ต<{4zไLฺ๘Q—ห� Y V rชlิrlZ*8ฌ.้๊๊Ž ๊๗ฝปง']บ|52Ž6๙sjฬY4ห ชะฯ–๏8กๅ\�๙8[๊>๓ิ‹๖ฺQ Jะซ๓wX�t˜U_g $๐#๔หฉ=ฮ4๘Cสjฬด;ขe“ ก ” ึC๓ฟr“fœXึq๏~Ž6ลฝิฆธ)๐ลYศNi0 %8รถ]ฟ}“ษอฉRŠ2๗งญ๕ฬ๏o’๕|�\q…ภ=๖‰oูกKฯ๘{feจ4!รVุ้ืพTฐ *m๒OGอ๓—~๎ ‘กŸšพ๒าKฉฏ›ตฅ$€h‰ภs'|ส.S?p๎ Ps้ ยšุ หwถx‚ ‘เ ๛$XฆŽณฏ‰}…6ท6ะk€w๘>ฟv๓\_/A 6๚พฏท†�€sfŸ‹O~โำLลhแ}ฃฅœwไ@�z๓ฦ %€O๖ฤณธ]];sแ�yzTtฑž€M่Tู;�'2+ ถ6O™# hnฌW6เS๗X†€b ™ิwฐ์ฯ’๕qะ็ัg๚+๊NuผฅŒภ–Hd�,KAk๎ดEํŒ๖ฦ+mฃŠ2 @O8งฉ & e%๓๔y๔Ph|&ฬPฆp‚N?cอนถB)@-xงžtJ“�ๅ=3–P”ณ6น๔โเฒ๑ุ]~ŽŸอ>}ๅ™๊A๛ฐศ—:�๓‡ฑ‹$ยใW็&ฌ๓์i‹}VN™Zฒ\|fืซ{์ู[]q ‡€oyศ๔2dcผ]^'๘]ง ฬ‡หล—ฌ๗Rะ‡Gโw�ืตe ะ-‡“Š_UKSว๖‹ฉฐฉ“ิ๖๛ฒW†ถT๐Iy›ๆณ๕+Jd}ษvฐง„๋๚…? `F"%ฟ=l9ห1gธฆบ>‘๓H๘!s์มk{ฮ็oแc>•`_ฐO�Aห‚ |.๗Y๖€ษ&u[–9`ƒn9ฺO†'เ}ญz_AŸยs™ 3ษ/`vิ—Cfe-p–๐XŒุ๗<šs‘ฐ‘|ถพ‡ำ„‚q€m๐ฯšFง๘�ำsณijfšณ�’zณXlฮL๖ศย๊<๋Pฮcฏlt{ย๙]ว‡ิัwช@*kลœCn ๔"ษ9ะFโ3๓;ง@‰ฏ9V6ีอฒ= โ}&ญB™|ฌ้ษฉ}ว๐ฑ๗ฐ๙J ‘›�ใณฦ†Šก?๕๒ฟ��Wฟ๐๗~๙?�ฟ๚ฅฟ๙‹oV็~ถใโ๓Ÿ�ี_๘…ฟ๓ึ /ผ4�[ฟ๕[k๔0`วž}�ธฎ@Vฺ\๏�ู}�?^Œอฮืพv๖��ฮฟ๗g๏�ฦo�ฺ?ฅ^์“-…ว(>GD �Hfršแe2๊ต([Œ0อ‰๒๒ ฿ก”ค‚W€ž:6IEท ์แฃวะ&๗า›?x'�ฟ�ˆ€eLVลฆ7ฮำฅžฟฺ='ึ๋๚o•นŸi—๕cŽ’bหหีA‰l4สอ>‚�2Pp�ฒbฒy่ฝ @ ›ู˜๕qf๕ ™ˆ-‚a•คAณฉ๛ํlฯŸ+ข๓fฏQ่f@5„8๒’4คJหฌmชNษ„ญ จUชน(โฝwรจ๓ฏTƒ๑�ฬ็_ๅฮNq˜pท™=M€ำำ`w3M>น›ค m>ฦา๎ฬe,ญ๙ีiymฌฯ“6 *๘y=]฿yฏ3ธสša9๕จ(j\Œ,M๘ศRฯฯพI๐]N๓šž‡ฎไ=4Šf‘4๐�dฮ,5ั€ณห<;”r^'ฝZƒi‡mฉ‰�ืYm-s!Ÿ‘ƒ“z€bณึ+ฎRว>•;ƒผ1:'wzz0d=2ฉึ7ม8ฐ้เ!ูK ฺ�:8ิZS˜ ณsŒ3สศ,ไำŒภฑY2ฮA…ดO3�8L380^ีืฉ$(.ˆฬŽ.ฯcฅu”ง8™อฟ<๊ใ;ำห7าŸ~๋�้�แ๛ฉŽ{ซD– žฅšKต/+— bฆ๚$ตผ๐�ญ–Fวงฦ๐แ๎0"‘kป–ฌEๆฝา9ผ็Jz้•›ฉฝฝ3ฝ๕ฝ๏คฑ‘T‹ฃณAถ|Ydญ9^ฑž9dุt6tฺ Iโ ศ2แ�w‘“rสlึ)ธ๗แ=๎:๚๗ rเ้x_งŒ๛e}L…9ล@ฉŒ,๏ืh!๋�ศXRๆuภGืๅนsทƒ๐๐๑ž— 6ค๗`*ฑžฒtถpฒ๚/๕ใ0ษ่!pไ�ถs6 œนญp€๗ษส7“�ฌ%0[ม๙ิtbภยฬLชมi^%X4 _Y^ขม�Eภ˜(8ิึ7qO>`7อ้‡l.ปN๘ย๘xสE๗D€ใuฦ94Œฉ <ƒฬvณBŽจ*DChโ๓ฒแl้๘+ƒA7ƒ&จทl ๐ภ๑น๛ Gฉญบ2 "iจg่Lฆๆžั?u่ญ`Oู[ฤsf‡~ณŽน4ู”9d r4ษใ^‹ม*s บ— ฬ๎[ЁญŽxtyG_0JทูY4�ฮ ลฆr*qƒOAaŸฃ r†๕ไฅฤดQ�“MยŠศ.ึฺ่จิฆqธธœญzt็Chึ‚€LฌซSฦFFา—พ�‚ธ%สsFูGด/๛k้ิฅส�>เA]s[ฺ@—iKชJษข๏กฟสฐ3Ž;๎D KŒ๑(ข„ฌะvูญ|ญlจ pแ ฉฅญ-ฮ‘—ำ6–ู่ อ’n]9e~6>ธชไูKัCŽหCF('œYš�šICFำ�4c{ษ ;ษ'JH‘”›แ ๎˜สY(G็ํัผ�๎‚Lฦ๏"/งh๋`uุย๑แั๔kฟ�ฟคฟM`฿ฝ๓Q:฿ืY�Qe}g๓ส ฝ็p๒ฉ๏ฎมฮภP›fjOi—ฬ!ฎe5ย™>"เฃDฦ@Aฝz4‚๖ฮฆ 6vณ อ๓ƒ…Ž>/7่ฅเฤ มs}}d@aแ0]ศF—ก‚ฅ}็ฮqฎ้)ฤฟญฑทtcq‰f’”ynพ๛ๆw9Oฬซฏk‰&น๚yค@ต๖‘R๎œ{Vๆฤ� ืj3๘~ašyVภ6ย๗˜ตQ_”ฃ ฃLˆ่ปHใถฟ‚ ’ฬg ฎ!Œj,ึพŒsใ฿]7ƒ;ํŸมyฬƒKYQ™%4ฐa6๗ ูƒั๑๔ไษ`S#Zy_ašฅ~Ÿf~จ๛ผ.๙๔ณ-ั“ !Eฝ‘ฆse$eE็<{m‘พ#]=ฺา<์ขู_ม”hคว>ูTณฝ๛Vœ™๑แ‡ศ$ tUe[_€;€‚ e๔๙1�@gžฤX๊VŒ?f)โฺ�๏๕Y97ธGฯQ>เ”œ}€แ๕ฬQz๒hฦ|3c=k9ว, zฤ@>Nมฑwˆ‰๕ิภR>๋fใOํ๐. ฎ�ว?ไ3ุ๖E?ฎฅต–$ษJ”S _ห‹oขฦŽ๊ƒอถฮ}ฏฎ,ทั/ซ;สUช้ตd๓ษแแA๔$�ฬˆUF†๎xŸŒิŽใJRbbI๕ @ {ุฤv ขVaฑ,ใ[V›ฌเg–0ธฏ%๘˜[๘๊&งuTG3ฯฌ ณกฅฒ!H+ภ`ษู!{็Hl�ญŸa ‡r๊—Lม็ูฏ์๛ฒ>Kz-๛ะHฟ?O€Cเม&ฟ๛ห$I#}{๏h‹๚ฮ๕ะ?ซ…ฦฎ&�\โYKhj>9= (ด›ฎ\่ฅiฏ#/SzoไA0™lBXJ ์:เš‰1|่U†์�‹สา›`Žržฒ“ฬ|V&โ?แฃ n*#ภK��†ๆ~ษ�ฉ+ ย�ํก—˜ยv�uฎใ�๋ืฏ�๎ง?๛sz๓3_˜ๅe{ุMซ_sว?ž�็'cดูฯพ~สVเ๛฿ํ์Ÿ�๚�ถzพฏ๛ป;๋™“ใƒ�žพ�ฦ๊ชช๕๑‘มผ๕•5,Hฝ%๚BC– ฺ๘ั=z<~‚๑ฮฮu~Jษ6‹๚๎;oA้‡ŠnYิ=(ฝ'(t!š%ณะlต3ํฆnฬ'DO4WEฌ๒ึศEง`ุŸ๋ŒŠzZ—ชกqทรพžวc^kpฒ2lF)š—‰cฬž"จขเ5{Cณsำut&`พ�Bzs#ฃi“LK9อฟ๒‹q|yํ*†ฌ‚D�็ฏ่Sณ‡CW€‚u๚‚ฅBŒจ†Sj `ƒดิ@ฒ#ะ ‹ฯ๚lbธสช1ศPบWษŒ‘ตx0ฤ}๐;j๕Šp˜๒pœsyฟดต"ๆ9�}�ภษUฒหrCNI{;ถ€ฬ0†HงีฺPio;0!\;�gฃ- �"@A3k�ฯe)ิs™ึืUา๘ศ‘;G8฿‹้มภŒฉŒ„š@ซฅฟ๋PH…ิ้Vฬ.›ฑ;! �ก๑e>ž ฦFฉt<=vสฦฯš ฐ!อ~jฆใ๒นืื(œ6jp เp”ถผuS,RN�Dฉฟ%��ฬƒใ๙์๓ห b6wY`�ฅc็�A็LฑซบŽb9ฮภั ตฬpXท*5ฏG�.฿ft†อNค9๒Š8KˆŒR฿M  “˜“O ๋fo›‰m†ƒOafูr…ฆ†๎ฅ็e3>�ฃ–ปHน7๋่๛ญซ๔๘acึศ@rญศ^๘:›aIมต ธŒ๏M๐มlฆŽฐ5•:•ึ?บธ*๑ฌๅิ_�q๙๎GS แh�ีRฦณห9ูๆป‚@v›า–šฦสtใึEบ!_N˜~๘ร4cฆYแSxถbbCฬMg-ƒl8u๎ฺฅิํ|๓#Si๊๎ Ll‚‘-ฦ|2no gหuัน-`pๅใœ™=ตๆUGฮ3kVฝzดฏ3`ฎซg]Yjki� &เข~ฐ:2๔œ3๗ว๒Ÿูgu”� มˆต ‘๕ไ์.@‘/C†*kaO1ู`็d–Dsjลัš#ภิษkเ฿ซœ�dรฯ(ฐ„;�“�ฑ�ojngZ6cกข'ฤ:Žšฬ‚Vส๊๕ผ๗ฃcœ๗p.กแ๓~3ูญฐ2บ{ป#ำ:3= pH`@ ล>}&๒ฑฆœ8 Wf ~ช>-Œไ�ฦR<ิ ฒgYบ9ยหฺฑ/่Ee�lœฆ@@Œไuo‡ฌ‡`ฝ์A`OB>฿:๛\Bz;จซณ]ป�"ฮื]#h4ภ?Eๆิ๙2tˆyN€5๖๋€ŒดN๎. —ทp`tฦkํArF†ซ[ฬฎฅ.T๗้ฐ  J๋๗ ๊ˆส�ฑ9žฌ!๕�!Ÿ]N†ฟWn0m๋Dฟq�]i๐Rag @‡‡OJท๐žž๓่ฒฆ;mํ1ฅd’�r\f€„zื^3๖๓๐พฬd๎ฑึqp๖vjq€ ๆŠH2Oh4šK฿;Uœ€_ภ๒ศใ๗ี-Nน€",dผ�ฮ;ฐรๆB฿๛Y‡€๛œ=5ำฅ"fฺ‚oะ-ญ,Fทy)ืfGว9Cซ”›k่lไฤเuQฐcs ๖ฌOฮœ3ˆ๐,ศBZ]Z†มG)Nฝ`Œตืสกบy›๕พKนห�`ŸœคIz5ุ๘๗�ภฝ่กำSชทณ'&ุd–LŸu‚Eug) วีบฯ˜Ub3ฌฌ ๋fPc9็ฮSฎ�•Au๓๊๕lฃBt–ceŸqด`ะd’ŒRซ—iธ(XOIO฿๙‹ั,ฒŒ๕(2ณk&?์็mPศ๑‰์แS03อ,Ešฦ๎๐•”:ู่ํFคa-C†] `ษ3(ใ๊’|ž�”5 @ ปฅžฑ "ฐkPซLbG=‹ึย บLษ^@ีฤท �ไƒL4ฯ์Z ๕�‡�EพxุR๖็˜ฯ;=อล‡ธDVธ‹ฦฆ”t๐�6}ๅ๐ŠYWi฿ฺsYฺ2๎ดซท9ุะละ๓ %๔ฆก�“=ื็iคื„Œ)๕ี๊* >„™โ๋OaXFบB0�Yำิฎ$มhB2q‚Iดภm๓IŸฆฆ6สตด[Qพq€์าื๊”็rถ้฿ํ0{g7รyPธฒท‚gฬ3Lลซ+ศy็šฌฃ๛ฅ?f �่! ณc�‰“„ม˜2ธฃ.xAฦิLญŽ๘Pศ`—AŒฟืYด9‘gรต,#@ณY›!ห]ๆ‘๛ฉ้)๎‰ชKไn†,ใศเ“4๔h?.ฯ8๋ F6ศ๔~รI!ภ ็„๛4Pnฝ=i–ส™Y*๙eFCVช๐:๒dS6K9|Ÿูิ  บ ฌน›h›‹Yšฯ5ิ CNž ณ2Ÿ๓๖wพƒ3 =๙9c2KฬBwฏ๙X;bหูฃ&7ฌ›”M(BKE ฏ‚~f�j‘S�ๆฑั1>›,|eส็QวtถwDฆาๆk่หzz{\Q?˜้ึ๙ญ‡pŠผT‘มปqใfzๅ๖‹แ$ ~๘Œ€6ไษYึฌ+๗(Vอ€ปกถž€ณ› อแr€:6˜joiงgAk”Zน�ี5 q๎สะ!‹Ff‡P!Y*5็mžRกo๗[ะjษค•V๑�Ž”™ฆ๛=๚ฤภPpAฝgฦสฌดŒ“MKฬj–ข_d=ู๙Zชบด\๒B>OJฐtcห5 �{ณAัค �ใ—€๛-่d !pมฅXi๔ฉภMอ็�ฑNŽˆuRŒM;—ะฟ (!ฐ&ใ์™ Z�X—.฿บŽSพ‘Vั99:ีgงฒฯBƒซ`}ฌำํcฃฬ*ผfฑผณZN ]“๋9ซc�9COม53๚•H‚7 –)œงA€ภxะต-—Rท๏ข‡œE๏็จ3;่Aqˆ์{&3=๔~;UฦFถว์kzHPdำฟS‚โ\S๗พฅฃ‡`ˆัŽิ‡�$X�SMk2�I_ธk%๘จุฤ™ƒa๖ฟุ`’'Ulมธณฃ๙ ๗ๆน๔Tฦึษภึ0ํใ AถuษS“ำdง'ะAณœต‚—3ึำ>๛œtฯ‡๖ะcฎlซsิo�L9อG�}๕ซ_D้J๒ีE่‹‚^z๑]„อYOƒ3“ฐ˜ิY์9L’‚ูGƒึJฏQโ0รyc9ฃ2%vณ "ข๗ ฒฉm>d1:"`7ซnิภณฤu๏?คฯ ภุFศ๖ม� ๓+ฏผ‚�าด—5ดไ`อืฐ‡ ฐrฬ {ๆว'†ฉ๕฿CงPHๆhMฯz1�Xvaช ฯศไ’ํD0อ"ฤˆH๎Q[ฏ qk!๛5v๏wอd Hศ๖ฑฤ@rŸJป๏ณ�๑WฮเYแU๔ฆเ„zี์๓Ÿ+›ฤ�WgeุูD†A}T,%า�ญb3์ื`�m@g฿ ฒฯŠea๊w™๖bศง์%Op�็ฝše๖ธXึb \ @F k`_…–๓wn˜ฬ8ฬ1yG้9I†ƒร�๑{ย1ฃ/Ž|s]ฯฟ:v†�zฐsาะาล=lง๙™)t2rYdึวเ�$B-%n”7บ8ฒฮท™Jƒฺเš๔uฐD์ๆ9้ม=ุ6เtณ%T&•<�ภ�ลฯซฤ/ชฅืเ…`‘S)ึั)+™ึFษ”Pู๐1c๋xฯ2ภ‰2๚,9 r� +0�VIฌ*ฐ–งdฟํฃs†ัq$ใ!kX Qธท‡ฮ1ูdCdํส"๛๓xh$lฒlมUห/ุ�Gม‘ะฃ€dž;๏[f“๚Y90�๎ดu˜� ” ฐY<๗ฺiฯŸ>Œ๖W6Ycต‰e€\…ะ Z่Gา�ำอฯ่[ย๏ สฝถkๆ— ?รW–lZbะั�ภน:@ฎ๛p จd’Sภถูำฃ(z๐4ึ7โซoaฟื่—„ฟยฯ๕ml๔ฌNา� •๙9๎Ÿ๚2ฎ‡=dตนฃ%Yl?2@ษ„ฯส�:ถผ †n๘€|ถ#n;บZaํ5 ป�ha๋ฟy๕*�๑ื3ะเ้J�ไ�ฉถy๖๕SผUbธณฬฯ฿๙ฐฅๅ๙=‚ฃฟ๑๋�cรฬ๔ฬ/ฌฬ�-<>hEGC9œ%ˆnOืn^A้ถcเ๖@F฿{๏t๗ฮฒG4<#HฬQr‘†hรี�Q:”๊:™ Kฅ)าiฉร"๒๋๏ ˆaฃ‚ถœ†[รŽฬว Nิsƒเ8,P›฿0eE'Zl) lPx:ฎ/UฏŽป …ู‡p4 izฃ'6๑›ยฤษ7[nํฅ†ั 1}ก  ]ศUผฅิฬjh ศ(;ปvnn&ฒ{#\C็2๊?qุส1hฮIŸ#+zBGเ32y<+Œ9P\ฎGญ*่ัfD}Fวด fHห–jนฑLร(ึซ0ๆŸB‡๔๚+8!‚0=H„��—#Pผ๗ัป�๕๎Eixt Dป#zœ�}�ษะQฆฎึ=:ๅVpv๖TCSคmF1‹ืZKŠCร�šฐ๎ึ0Jใ$(e��]> A”s`๘ฮ"pเ9pxฬ‹ถ๏อบจ๏ฐผ1OPBะ—uล0e'rไค^ๆ„ UใX˜%2xvข‘ ‘CVMึ<œrไฌc\Oc&ž�บ๎R(ซ:ตฒ�gณฌU”อ ส‹๒&`ฒ*``ื๊l�ชuส๔ฑLp้˜๕Tฎ5ษ๗3‚฿ 2่–Tœ@ๅ-ศ$NูQ๘*j†‡&ุSบฆททย"yฤพ†ฃ\‚+๋��†Mศศ๋๏“ฺค!ข#๚jpฦBbญuฦG8™fF5ุ�)ใ9ฑGv}" †ƒงnfภ>":Aค�9งผ‡*(œ›ถ๎ถิB‡๊E:sื’”z�d0ํ-เXฐ#ฟ58�,9”Z๗ิ:F๎ฅฎ�ก~ &ล)๛o}iว.AdMCsj$รqrHcG€1\5๖ ถ ฒ%`p+…ซฐ8^8ห๕๕dฟy๏&�JŠ่ฃฬ-2๋7๐ตสท4ษ]ฒ๛�TIงb˜m5#ๆ3ะ{Ÿ;�ๆB ูู:�R€/\:OPภ‚Xš˜K๏ผ๑k๊sฉ-ทDA`IL#์\2(,#๋Jvะงนพ…ฝฺFL ็๙iŒ=•ฝดฒ@9ูฒkXนฑ๎�ๅ|ีคึอ–TtDBไnq‘2๖ฎชผ–เัw ฮ๐X๖)…9CH๙g bKจs7หyH@% ฎSฮ๓ J †d0ุ™]Šฏ๚!กชคฅ'�Ž@W ˜sฎ*f–ฬR ด\ศฮ๚5–ว๖‰ู(๎‡ืถตuัตผตƒ’›ษถ8Y‘ปy‹1zฯs3ฦ6แ vฅo�ั{ ฯถ z ็Cฆ˜rv|ข!๕w‡LP’uภdฌX=/~๚ๅธ๏G๗Sy.ำะ/Žะ�"p]ฆรบS‡jf์‰ิา�œn>w“พ>~ A€ย๘ไ8า…ผ"OKุGeืuoomMฃฏ ห4]dM๖ัว–ŽbซDRด�ž#{�จฏvaฯ™ผ8TŸa7ํต“ฯ3ูฯ%+“ฤส†€@/Œ๖�’H.z�์ณ:J]๋—�ฒ‰ ส||~^ธAะj YY๖ม๛8ํู„สฟY†@&ึๆำ่ะTwุw่ ›๋ฆ2ึn_ ~ vึsฮŽ๛)Pส”’•ฆ ikwฑ;fฯ ะ�UM–๎ิค�)ฆ[‘`ุ@�หiฅ\ค™๕.ข<ณv'ถฺ„Šฏ๚bvv:๚F˜ๅ~ิ @๎โ3•–zOOŽฆัแิM9ฃฌฏ๕M2๗ศฐิ{๏+'เVะ�๓G†–ฐuž7€สž&š`V ซ6>uฬ ฒR„.Rq๓�นSฮ†@’�ุฦิ82\„ฎ8ๆ,ฺˆณ0ทบก€e> >€ํˆ]w\t,IฌYู ๓S๎#$d ซศฐื๛ŒŒ๕5วๅ้ะ๓๖เ๊๎์Fo๏จQ6 xฆ‰gt‘ฅจmฬเญ์;ฅ“ษ5ุO~ธ†}ฑฯ•Lk�mฬ[ˆ*KM`@฿ฬrŸหเฺ๋�Œฺ๑Š‘ฝว�ุแ์ิ6Šyž‘ทะหˆึบ@�๊ํศชดำ);๚‘๖๐ณ๊820ู|ˆบ444˜zO™0A .Kฦท[bล-DฃCuƒภีิ ฃ@ัIํŒ9�^�Hcรณุ}aG‰ข“8Gสž๐™>”บัDœ‹์KGf—จ๋Qส์9ใ�e+\๏\UŸขCJ4สuD*kOชช*๎WTฝ๗๓?๏iaž}�ดฌ@VS�ด<ํณ็�?]ยณ�๕Hค๐_�ๆ๏l}p�ƒื��˜๛ไ๚๊RAŒฯย1ถณz‰๔I”ŠN๕ไฤดห'8jะ4ฯชƒaฐG0N-m HD1ช%5ผfหํฦด( ธ™B พ_"๐ขํ~iฐอ๛: ผ ZGWลํ— €๙ BะŸฬ@&(โ๚f‘อT`๙น:พNฃd฿�mV›†<๛9ิPs=ฅ6(ช#›UAเ๓_๘Y2Kal�๔�‹ŸN/}๒ี43Cฦ$�2 —ฎฆ —ฏใะ>NŽ [#ใๅณๅ`@ b\%ฯ:kดo“2Š Nั"ด;้x"ํ6ฬRฉkus upOpž๗wศ๊ขฤw ฬYV‚ฤ๐š�๖ี๋dsๆatฬฯ/ฑใะษา`E ะึ(ระู?ภ้ฒAฺ้0ajิส^ฟ๑†šLฮ[ฯ'•ำlŸ๔Gg€›แฯง]X๏๊|iœ‚a๑e~3{6s+ืษขmCuถŸ…ฐหช W–ž˜’ฮรqt๏ฬ ™6่“bjXฤฺ[ƒ* 5f8ใ\\8ZŸ‹๛#3Nmฎcีฬ�h8 pเ ไ5ฦ2>๊๙ฌ]‚Aณธf หศ๚ว‚fƒๅร๕ Šเฤ „kชx๒็๙0 YสฝHEฦ@4รษkฌี]'6€5[c๖a…}ๅQ(2ฤ�S[‰\F‘Yษ`�‘ฅ704OM(ฮ] gห8”O{ ุ…� Rกึฐ๋ด*ซ‚!สF๖ผนวIัูฐžา3 Pc๓ฟศ<ฑ0าŠ๗Y;{”S๎ะ `ั์|บ�ฮปizhj5๕‰ฌฃuต:๎หหL@AcํXO์ฮ‚ิ๎���ิ�N7มญซ`ๅฌเqศ9[šถ†งŽใฉL๒ึ&ฦk!hhฮ๛”ฝRlpถอผ่Lบฦx2<ฒ#a:ฌBๅyxI˜ ‹‹P็"€@X&(,ย๋่hGึ-žูžฎUซmjY๏ผ�v๘แ6+ฉ™nŒ€fK'W]ฤฐ>�,ผปูููศธ”เ8ญ,0ู€๓biส ‹•ู<{Wณ�:bฏผ๒‰ศ ตตตว:อB7 ถcท์3ไณ8หำdฆ 8‹m›!: A'’�tตA+ฯWA€U‰,˜TT’กฎ"๐:@/"ผ™๗xmu ๗bื๛mฉ๔ศ๓.๊|ฦ๕2ฮบ},Xร]ฮฏv�Sฮ]พœฎ฿ผ“@0กนฝ2Šา๔ัร๛ภœเc๔ksW'ใ ษร๒‘ํิฐฺ\ฯจฯแV๔6ฯก˜ๆBSษfdY�ฯหŽต๚�๏ฎg6kน7ซๆ&•๒g.ฌฎๆŽานศ‚URŽไ๕ฅฬ๛9,ภึ!ฆฃซณ_cใ/TBjk๐dฒฉN�€ู+KKF‹ฌฒฟส๖๊ฐW‰,‰`ฐ&;๎SgงG–ฯุๆ๖ชi๔[ ƒHfT๗๕+Yzl}mฝ|9ฎY๔hฺฦ็ุhฮ†˜ปœc6A“  ฃ/๚๛/ฤy๚๐ƒ๗ฑณœณLdคอค›Eu]ิ‚^gžyู9N฿ฐษcgมOณฏf5]ฟ  ํณž‘๕แ9‹Yฯ ๅuJ–บDฝกฎh@Ž่ฒ?;Aทu‹52ถ0€ บ‹‘ ้�ง|ถ>ฟๅ#–upy�ฬ^#+d^y•ฑ  w๑sัปfE_|๑6�h|!๚{ิc‡hXZž6ธฒAoWGGŒ–4Sฒ‰์Xย"‹ว3] ่ๅ๓�|Qล7B฿… ฯภY ๏‰~GdŠํฏ�นF๊ƒธ %>ชฒ7ฒฅขฌ สkฉฏ๕\7฿'#L;[๊zX*"L!#f^ ๎}mจ*pใ{�ำื่ฉ(K�—@“1ถ”ฝ๘ร<„fฅ'่๋$—  ๖/ˆ^ ์ก`+Œœd๛Hจฏะเ~�ฬ:€t`ฐ"‘…,ˆ.dx C^]๎ด(ฮ“g๗ู˜w y฿A๖ึ จหฤRว๐ l9ฒอูเณคั๒ ™’–?๙น๖j‰l<7"#GำbำJวP�]฿ฑษ&$๒Iž๐Q์ณ2*ณŒฒ ุ–Nก๑[๖]ฒY$(‰๎V?ษ์‹ตๆNดmฎทฒไT)�ฎน%N*ฃ4ณ�ผฤพ;ๆ๏€GฆD เฅ›ฺ'@ bX);L›ฺ฿ฯ๘>—ู|Ÿa€PฝPษ๕ภ]ฃวี๓`ขgิ1ต๊cู&'ธ |Gฺขr�รdุ๗_ภภๆฃ๚Š๚&\ื�sฉ\ปn%์3 ช"กญTFLLฉปyฏ๋แ/M2y]�’๎O๔yืฮWยŽ–ุ!๏วๅˆuฺ˜/"1ะ��ลww๊h#ป฿ั ฐ@9 ฐŒGmž๗.˜P‡m’‰งํv๏gๆH๒1๑ห’”|e‹Kว~X6์ศX_งi1๙eVd}Œ#tถI&ืศT qเW1ภฉฌอŽN�šŠยƒ๎�ฎ�๊o�โฟ๛Ÿํ�?�แU‘ฤg_?U+เฉ๖๕l�+๐ฺk�อม๏ผq�ฟ�^ัฤ๐๔'๒rKsT๒-mะ†๛ฯไฅ' บใ8’eะr #%rf~ … J‰กWฑ9บN&ฟ“ :;A“QnQsŽำิฉ� ดณŒ]uปP6kฌฑ๓฿ะf �ฬ�˜ะA2�ๅฝง(A38ว:พผฯo^อ—”m4Œ`A-Nชด- ฿#EฺZศ:จ์‚]8ฮ…์่œI23า ฺ ๚ค3=ˆ๛”2ช_ลเญ๓ง๗Yศ:Y฿†7a‚IฝฆูŠ5€ƒ#,ƒตมmถั&OUu (โlgcขึ`Tšจ#™,ง0Koภ+P Cฒ{มfafูKษ๚\iศ]sป;ฯฦEH“ษ�aฆ๔ิฬ\ิปn๒]=�ผฎ8 4ุแ฿ฌ“Žakcํธ]ศmฤฃQ1(๐�N1Z{žฎซืe#ฒv๛&ฮำ–Aฐœupœl3/ึPBภ g\gXถ›ร� สญ้อึูตทถ€h“i%เฑิZZf�’ู‡†ศwงRฌฆฦ <`_:Zี�ฬ๋›ึ0<ศXชจAตฆP™|Zกt$ไ€๋*wgาWu’อF๋่œ๐ผ๙8(G\งชภ‹ฝwo-ัแP&}๕ฆ#ใO7~hP]งe…r%ึฮฆFƒd๘'&G"ำg ฉไˆ �ฦธ› 1‹fทrฟt6”qห ภ� ๑Kึบ๛๖X‹mถยlกQt@L2ดKPZXาำ�ฐ1w�๊ญTภ™ฌ pฒฎึหฺก^เaฯ4๛b“I;f—p>ฌํถk๓ซŸ๛เสt๗ร๗ำ<ร่้ฐ�tjtวjt5ผณฒ2Kๆุ อฯำน�วฉทผฤIR ํ๐นW?๙uู'œ๕E!ฒษ๖ู้ใ–’id=คK›Qผ�โ‹ฉงง8ฮ%ฅ ๕๕แ8dUEๅi๐ร๛้ฃท฿Dจ4hŽเ๎€=’นัาัอฝฆy@>k�อย้บ�J<€AFฬlว™ตน_9SwwW,ฎ�๓dOาByะฑดŒฆ‘†คึุ;ยา&ค›8่–Mู� I๖‰�็# Tฉc2๚จ™ภ�ฟ+—9ศฉ ๋6งุR^Kะร} *ุb“`4EuN?�k8่fUu�]ฟ<ื;:บ|พ๕๒?๗ฅฏฅ~>•รย่b วgงาภ_„ ฑ#้ˆืฯฬ\บt&V;gต‚†dร4‡}˜ๆ ~ }๕ŒOใณ`๙ๅŸžeฦใqN u๓-•6œSœer›ป ธ�[?� ผ†N้่ฒสj๔;2gฦ�oืG]+€ฉ~+@ฏฬษช!’ข9จอฮ่Qร๏ํฑ ศj๖อ ลฦ…OK^ฒ,ฒ์'œฐ ๐“ฉ.กN๚ๆK/3ชฎ>@พZ๚T4PพQำลฦฎM€'E€ร>�†,tว๋ฝM fท{ขm‘มขผฎฏฌ„œ:ฅยๆŠ๎cKk:g†\~ส„ŽIjป'ซง Bมพ๚�Q>�๓ ]nฐ€้X@IDAT๎ˆ6™X– ฒ|Œ6ปภkฮสฉ=Z2�_>่…K�x0"ึ๖ำ?๗™TMฟฬึ\zXฬฅ๑Z gล�€"ภ|ถ,2e]้�ีƒส๋'CD9 f gน”g>FG@]ผt1์•ฝ~m๒gฟ '&ไrฮš O[ชฑ ะ.pฐอ>EƒXึื ZถฯAโ}ฒฮ3�ใ>๋"@ฐศT๐^„ฆุTฯš๗"bน™ฒฎฏกn7[๋ฟอะซ7=Kg์ณIŽฐa<ฃ_ส(ะ2ฃฎE"ศ!#��@�ื1+าจŒๆlฉพ.–ภk` (s,฿ฑฺ๊_hTA˜m๔ฝซ Ÿฎ!WŽkซ฿ƒe€��$ฯ5ืfษ0ฉโ,ศHส8ุg‚ำ&พ�„xƒz}๏1ณ‘=ˆ2A๖Gถ•wขฺ ษ�@๖ Œๅะwrm๖ข+ฮŠ จใFM‚พ[ฅ�ฮร†8Eb›ฯVoe๎ุX”�ซฆ์ศ๛ *!๛์๛‚A เYธ๒>ณv2�ล ี๘:ศมฬ์ภ;M%๒8ำN2il๎ˆkl๏l„�ฤXรŽZr3:4อ�|6ฯฏฬต-Jฝ4€N๕๒๓,{ฐTr~i%๖U ีN๗ษ/฿/๛Iyั‡{ไ�\K d#่๋€ซง,iQ”�| D)๋๙ฌg฿ฅฑ Dฆ‡ืTw๙omต% ฺX� ม.ๅยฯfE๘™ฌ9‹์ฅ๏ฐ K‡Mš'๐_^ฃy*> Y}ฎYH#p๕ ืM๐L�B~=๚2›ฮจCžฟ�๏"ใh9Aip ]ƒฌXข (�ธ‡)yŸ�d๗!'hYEŸ ฯ†ฝ'ลDMM `Z ๚1'๗xฃทฏ๛W�‹ฟ๗w�ปๆๆพ•฿#้ศว<๛๚)[gภมOู†�฿}�ื^๛๚แ๏�๖?�แ›o|–zม–3ฒศ:คšฝ๓ƒท้ดห4jก>ŠัPฃิnฺ96๔wŸZภSะe5Š€€ฦDj †X*˜A�Spภ?Uฐ*e�žฅํโhcจ dUœj<ฟใˆ#*;�็aํH-อะฆ„1>ใFiฉ์ฌlำ9ต๛>ฅู/3•f9ฅSZ~Œr–>liยา�ฯ˜LqชปBWq–'่P/8ขS11‡ฺ*ฃ †:N๏e{{-่eท_๙Tj�฿ู{ำKำ๋พ๏นต�ฺ๗}้ชฎ๊ฝ{fznCJ#šขeI):@ FŽ#(‰ฅ@ฑœุNdDdณ $A+6โN ;’2์ฅ2ษ’Cr–žž�k฿๗ฝ๎ญ{kห๏w�้0‰้H‚พ™u‡ลฎๅ�๗}�g9ห��ฯ9ร#yืhา ศกงฆ'@ำ7ขPเ!ฮ•ˆs}3ฮ. ‹จ๚ภp*ž  ‹•ขeุูยถฮKo฿ ึN้:๚ส—๛ฝfbL*s[ๅตฝ่ฟ4B�๘N"ะa177ษ�ๆ๓Pฺค#ฺ'{cc+Mฯฯฒ†V‹ทv€Bา20ๆ ๛pบiGFคฑšuu๎ฬ๑4ืSไ\ช^gp jเ.๔Aฬ8 `"W\ฟvŠย>eํช0ชu„ฬปิุจ@้ึA้์pํอ�@j"šgฅํ-ฃ=ฟ ฬ—ท&\T‚วaoย‘=cฎ(�ŸPdi„��…๙™`Cิแฎ‡๖nD›3Œต6�ธ@ฤM#XะBฅ/๒ฎ‘hมฐŒ‚(ปง‡q๙Œrw™ปซ Ÿ;†ขถฅœ”Š@ž2ว:อณ๓‹ไaโ์ฒ่๏bhูึหsถ ิ8o  ๆ๏?ฅ{E๛WŠป Œ/๗น๙•ๆ�:6\วๆ�cIหโ98b*ร)้•<2'ฒ‚ž:_}ฉgจ—๑qชฎทค9ฟ…‡`bใะ๘ๆใŒ็ต –FN๋Ž*ฯ+Iดฯ๔}์ซ—q”ษ��ฝhwvZๆ็ึา€X5ฦmฌ†Sr{MM:`œe"r๖qฯAฏจdฟ':Iœ<โน8ธ‡์‘Fา‚>Nิา*�ึB™ŸŠg7’-•ำ๚!9œัผ-I5๒0ฮ๗qฺVื–ฑ\ฅsา ƒF'๛ซ_๙�๔�ืฟ–&พ๓9็tC้tV1œ8ใ›VQ?‡ฒmแ?#`อ8ำํไาึz6๘-/,ณท ูsป8ค{ะv9�htt4ฮTๅN `™EVๆทลiŽฐ…,–ํqฦ4"สู�peqž4jๅ๚3Y์ƒฎ�;ิ’^|ๅNบ๓โ->_ฯพ|ฤ(ี™1ุ"“ฎ�Q9eญฮŒzG;-ฮ‹lDtๅ“{บ cฝ—l฿&ŠZŸ#d7rCgถศ฿*์งM"`—†)ผWŒ๙ฤฬG&e5ฬ7Ÿœ™I฿๚๚๏งw`ฉฬLNฑ‡ูซ์;#๓๎YK_ูฟYUoAm#ฟท๛C8ุqฅ๙ยbฌีนRzํฏ๐๓yz�่!Nไ ๒fPGpDJ?—bT้แฝtqA�ฐo‹t ู#5ภN(ํศงmz{ฤ“ #`ย�ชGฌกณ5 L�8ิdฮj8ื็Šxaag‰ ๅ�lไฟLมG;์U?$W�œด‹๗ฺeอ5่NQฆy žhyˆAฃ2j 7๒!š/ฒ4^Py๋ˆ sm�&0คฑฑฮ“†๏�"ฺ๊้๏3gถi๋a]คแY฿ช�ฎฉ}œKx~�ขXอบžจa5ั!sจ]w๛G+,พ๗yญ�“ศ�]๐{ฃฮ) ~‚ฆ/^ฏ:�~Fc[๊c(Wž'ข|VCมฯš.sNd@fฦใŽœ}žญ’I—๎.๊mมศ"ตร7VsฦMูp.tบ<'ึR0 X)€ๅ7 bT#แfรนสไI_ุ‘ฺั”^�ิ+้ณŸ๙L๊ฃฒ๛ฝ๏}/mC็ถ BŸ9มaต†„ฉ,‰€_`8๑|ีQ�ด๊”๕ย่่fŽ+์�ิำT‡W„"}�ญw(jตO$๘(Špๅ‰ฌแ|เ$ญ>`์Qdห=ฮ�๊tXLำS'ฤ�mิุึ}g/L-ฮว<ฯ ๘‚qฆ9ˆใkkˆ3,›d‹ _๎‰กกกX?๗าํ;wุ i™ไ9ฝG!ฤี‰ง8ฆJใ|Vฑu5ฆ์P XvŒรh]%ฆšhdฮฯ/แเะq5ศr˜kHปZb ๕�Hง๒ส9๓™dh่=”ณิลz๎ฌl]อธ�g yฤ% หฅ‰gAื7อAึ€๔๔J๖ๅว?๓J๚ูŸ๛้t�๖U๖kน๊ำฬ—Ž6ฦ2ืb๊pˆMSยI๙ศK1๚ไ๚;qš4สส0f�;ค.p†t,ฮbฏ’sฯฟFฆ,ึ๗มฝ{8œ๋ด7mHKtwฑKŽHฮ฿2๓ฉใy}�๕:๎ง…‰ษˆ”ๅแ4P�ใˆฎฎ,๚มหy$๖ฅSฅูhุสะA?0„Žฃท็UPP0=1ลูลQgผ=D๏kม‹_ฮฬLลsmใxaิPฎเ,4Sฌ๋ˆk7B1 ูE&็FœSYฬลถe฿วผsๆcKS!Lนrmป‘๕ตห:หRงmyูึัŽK ฌ)6ฆฉX`ำฯ—qŒ4ฌผึzชพ,ล”Œ]ฝ้0E"้ญฬ็ป์ษ‰'O#๚|ˆd— ‹z=๗ธ ๏kงๅฌ_ส'ๅ^5้~๎ก*XD‚่]|ฬ฿:c<Œtํ›[qŒ8Cถ๒�S?�yฮP  z&R”๓žตSมI)d—๚คŠณfื„"gฺุu,ณ7ค๐glำ;JyŸŽŽเช๋k JวฯธM[ฒ๐ๅๆ๊&2{#Šุู๒ฑภู]LX[_ Gๆ{฿๚l•๗ำศศ•˜ke[๕Qฺ่R4??็rฐ‡–TjสสP7›vเ ๘›พๆœ[ฤถzม8เL8&™€ž+ืาtำe�Z?F0L๊sธ”1ฆๅ‘ใ\๑˜๑ฌQ็€=l„ู36ˆ้\ะา+q•๕๎p๕บา@…Œต่�ฤูะ;ต$+€qนฎฑถ�ฑฉตsœำˆ `o๕ม๊nk=่lk๛๏o฿พ๑[ฏฟ๑๚o�ย—�ํฏถI+พx�Hฯภp๐#ฝ���oํƒ�ใkoฯ็ฮ‹฿~๗wฎฏฏnŽ่T1€ฌ |Lq ำc้faqง@ำR็5�ฟ�›9๘าfC#ดร 0งeฉ๐๖�€ �#อŸ5VTฤ~้ gT/-BXไXเ!่�Mƒ_ƒ@…ล�P่๛Dฯ#:‚2๑พFr-0ur_cิƒเˆ~๏ึเcU"^ะกฬP�V—f!h๋ึ7Q0 ั)๘ฅ๙7CE•ฦงSฺชCˆy���๔�{๏†Q359Cวƒ Xค&์เผ[ซภ�ึFขฮญm1'ท‡ะ๓4ศƒฃเ?็YNPิ%cฦƒ5�œ”^๓�Mฑจฎ มม;GQj$ฺยว�ศ*_)}E"lŸNกQ’DYU�U(†๎๎�4:v•HxV9ืชไFXJ(ฑศK…–mฤ๏wพใ6opŸู ขต*ถXซแE%ปฤห FญรXb=ญzœรYฒ•žs๋d1A้ษๆๆนภโqํฬyGวฒ‚ๆ๐ืS$ ZŸ˜žฃNTวล}.coภ80]E#ฦ57wาิ๓ื[;aK๔wˆ…#ฆจร%uZรฦ”Œppธk(iฦคเ๚[ษส�๊R๋+๘wฃ@๎ป='�ร[ƒc›๖jŒO:bG\ถเชƒ๙ะUX๖†ฉ0ๆE›Vaq*a ˜(xษฟŽรHถQ๖ฬhaoG—ย˜์เTฅs"-=ะข}g็h๚?๙Fบ}๛:E ำื๗๗า๊๔T๊‚ีb๊H% }จขำำO16Œ^ู-–œน•5zฯSัZ–lƒ:Œฎ:ขข-PQ{{ฺ1"zำ์“™๔ไ�‡ห8ก*Dกˆ‚:?ี€oFึpRU8D™้{aด`๚:ื55๐R0พrศ‹จฌCF)จโm๏„‘มผ๎‘ŠัฮJ�–�ฬVHWฦฎฐO3็ฦโ—]žc•[ีgตธg84yŒไ*ๆื|�ฬpซฤ0ฦน:,uW'ฬ†๙๐‘Zฤ�าyีเt?Y‘]yโนtฯy~�ซ}Dโ�ฟฃ:œI7ฏื฿?€L" ‡มmqฑI|๋ญt‚ใวฦธญR~@่๙ie>?�3Šbณ6ลh›YNSSsพ5œ;@็QˆQ๐ญ yก0ั 7FGyไหณ"mู=eฺ‹rIƒี็๔}‚6ส`[2qฉD^๑๒�lE4bl๕�zๆ฿ฝหq&ยฐแณ[9=.„-5Y…่�ใๅ๚8/Ž#[w™ฮ ร�ˆ�‹ำF4ใQพW#รญรRฤˆฯืม@ภR เ<”ฃเฌฮ๚Q้mSjะ:๎�ฮฅ|Lsื @}ถ๋‡‘sม ไ฿.2Œ†#jๅvTS8ะถ<[Zšฃใศ>K็)Cไ~„฿ฯงgŸ +ถู'ซ€8ึ€‘5c8ลาุ:ZA:ฅŠๆ7!|r๏>K:฿๔cnŽ.:A&ZGๅฐSฝว�bM” ืษ๙v�œำณt,+ุwVR728L:Œ dฆ@‰ยužSนROlW๚ฑW_ ภrnn)bฒDLฐ.Œ“ง๔�๊dืKึQo‹* Œ่ญ}๎่†รอx,˜g�)†g‹#˜ฯxะท>†…d]ำ%ฮd2ฒ‰ณธGDz )•|yอ{ุ“tu�zPั ญeฐDว#~o-‹่ๆเ>ล๙<โY]GOƒต\Hืช…ขuคDXœีBบqฎ„ฮผgD]ฏพัV๐T0e˜๓Zา๔\ew๐หศ๋ถฏ๏��Fื3gU|2-Z(ๅ›ลแ๙v˜ปuูH�ฌA_Šhง,ธืœGๅ‡€ƒภต๋9Žฃ,ม+?Ÿ‰๙Œpํ}o–ja๑g@z๎72:Œง@p0S3€ๅ๎0จUิ้•�kซ œ/ภฏN@a๖็์’€ั=๖a}mMก:ํX|ึบ ฆ�XSเ€ ŽNฅELืX';ฌาศTุฤกพM‰๙;ดฒ�ซ‰ฝโAพTlีฌ38แอะภ�FdC่œหz 6ศSร9l๋่ๆ๏ž�MEKปชjฐQn๐๗^˜ด „Uf0ภ3ๆ�˜GvM={ ;ปo๛ˆน6Hฃ�ฌg�L…2…UD \y&Cภ�dส‰๙๛ึฒxฯjgdz฿ต—AเZ๘ฌE~๖9ข~ ๋๕ƒณฺสS๕€฿{fMซ8 ภ„9pฃช๓�/2ce%zฦด?ดท๎พt{ซ&=˜๏์I/ฝ๔"vPsศุYื"vi?vฟ�…a-A0ู=ึ2ก|UnX‹‡ผ1€แญMใษgณ3iึ†`@ย4สuI%6p ,ฤ๊F๖!U[; บIUฺุ_บ๛ย ๕?�O~ใฟzํตOฝ๓w�ฮ?Xึ'เ๊ฏ๑ธ~ฤ7ภ๔๘ Š฿�฿ฟบ๒Ÿ�ฦ~๑ร๛��๚สnE-Š�๖€‡ขถg2ŸCHIiWX)|5€4ฺuT„:๛F๗D๋UŒศฺx)\-Šๅ๏Tผ \ฏ๓�=�๋๕Œv็P:ขี|Œ{ฉฌฝn–“.]าŸ—็ษEลXใsC•ศRl!ฝ๚๊K้…ฏf&qaชœc|i�๚ศ"g%จผCไฟ b~nFMฒ‹จX? a^LPไŠ ะ8]O=M?c<ฯ‹ึaVๆน7๔x”‰cืญซง_ปyz<””ใ})ษๆ’ขk$ ํธP‚q๊|ฺซY'ษ–:ตy่bื�๔๕ีI™~๒ G…u„2„bˆ‘d6+Jฯ/ญฆœ‘Uhฝ !า4�u๚Qx๎;ล :*๓ฉRำIย8i†ZปF„v็1 œ- จมIสฺ4†ม˜ซภ‘CอX„I”�T ข3"GฆaH๏sํย fe�RwQ„*^k่DIฑ.E-†šQw (nFฑmZืืเX"w9ฺPB ์ะy๙ล—XฯDค๖iไC�ชฌEk๊วฎฅ�ฏ�f็ฌ•”Gre1ฑยฐิ`riXJ/5โ(รECฯ�?้|‚mฆส๐ฝ๙๙:-ฎ›Vก†ฌญ๗1สๆW"Uธ„ƒ"0ค‘qฬ|Z]฿t )๑nvู๎usซอฝ•žญแ<๐wพOƒุT„0L‹คลœ,v'�ภขŠto‚yัFฎ$น‰Ÿ}ใ3้ฮอไ„>Jฟ�?��Tข0ใm ฌ)€+ฯŒvีจŠทg""$œW#๖F๗)ดj%-ค’„hv)Ÿหa$ฆ๛๏=„6ฟห�ออ”F{Œƒu) _นžะ&๓\ย(๑ฐi8 p แ›`�ะa๏ิ๒ทzๆฑˆฮsR•�ผMภ#uฦํgใู:ฟ2pFFF#บ๙อ7ฟTฬ€{ึฐ†`ฯฌ@}ีฎฌ9ท๎ s/ุTษ94Ÿzเ@รู Vทว�ยIมxznLqOu@–!�mZ1|•aŽอ*ูž?™ฆ�LMM…qืL๎Z)Hwฦžšน๗njฌ–Rฮๆ์TฑฯYkม:้มฌ๋ย์dz๏๛๏า�n YAŽwถศ™{รฝXมคษ’<๔ž‘ทิyUพ้jธสZาฉ F›5˜6|Vบฝ๛ื ๕™Vูึมาโศ/œ O๕ƒYุร4…ำๅ?•€รUฌŸฮ๏�๗ฅlWๆ+รณ”g˜๋๓~#๋ln~ยˆfฬอํ €รbฃ5š—X฿ฉgOาร๗‘i{ิxB]arๆ‡ha8•๖t:”˜8ฮ2�9เ9๚,Fป hคZร\y+๘็s๚ลmฉY@1Uไ‹ขrม”Š8Lใ—ฉัŸf”;‚&ณ“Oรศ๖YtŠ<๚‚ƒx€คค0GpGผืถw;0ป:R,…ว๏ผ“ึˆgq๗ณ2มศนE๎œu๗ฺsฺฒ)‘zย�๔YœCป สaา“สาภ๛๋า(ำt$2Gšฯ ฟ*ฮห้&็�ชํM|ฦg{๓ญ๏†ฬฒ›ˆ,0ิฑj�OŠ{ wว� 4[X‡Gว6๊ร ง\OeOนัrฮ[œฉ_ฮง์ŒVภaTฃGž‚q�ฐ�:ษฟงี(gคซฝ‡@j?pL][Yณ๛ฤqšX?๘8ฃหรใงO•์9kพ˜R$แ คˆหˆlxžffZADซ:อuิ่ฅ ฝ๚มโศ‚_,Œ๋—g�6|g7ž•žR๛›edฉ;'‚pŽถuศHgหFฑe% bบNสฯZRงpตNป๕LA`’#ฬฯ่”šขi็ี"–ฎwฃL(๖&vQ 6‡so8]iem;ู8žุฌซ‘๛TŠฑyฎ+ด_|V™22ธ]œ-ะ5Xภ๑๛l])่JqP‹1o<*ย2€ J็Œ6๊udบg๙_ิ}jAWj๛ส8Sฮูนห โžqใ;ฮ,Vƒ@ฺ฿ฅๆฯ ภ‰‹mุ‚–5iไYOะษ5Uค•ฯ3�ซƒ”9~LC=o~�s?๑—��ฟ๙หฟอฝzฏ‹๘ม \?˜‹‹๏~ศ œŸ�~ีฏ�๙ยเ฿�๏�๋_BศฟŒ9š3zกัjฟ46s+uˆ|ฉ UผFGž ;ฟNฯำฉฯ๒_1*„ไ~ึ๗*๐3ZัŒM‘k5›Nžส;มฏ€Fกbศ๛9ัa)โFlฅศ)ภํ๏|Ž`•ฦช๓ซ�zHฤ่ลnฏ�uฺ~ูBบ^‡‡@aฺEšC7 ๖ฮาอ€ Sฯาฝw�Tegพˆํ&ฦf8ี–2†cB๎_žโlธใŒ‰ �DOdcX@า\GF–็I!?ฦlš€…ีฃ5ฬ์U฿BtQ4Xบ]=tร&จ‚�ป‡ป(PwO'Fล้ศ]ญฌ„’]ยร€12PษJิ|฿#๒ึบpBชา๛๏ฟร๛Pœด?…Žษeฎ^ฝ"4*H{="ฉ*�จใ:�๖]>ฦ๐“Zจqmํ‚0ˆ1,[ฬห0Zฉเ๚x/# �฿/ม๗ส่ศ๗B๑bุFพ sb ม H๊4Y_N‡3œ– ฬ�`ธ”qึH๔วน ’5๕*ฬแฝ4>�‘Lฐบ5]L^{…[b=,�ิ…Cๆ>X#๚+ฐดดธๆgฆwฺา๗�z+}-ผRง ทข–vฉ‚hิa9`ฯZ”ล%r฿๒ขfƒsฉƒฆ1jฑInv?(K4"Mญ:4าpum•A›ฬ‡ิฺ6XGถ ‡žน๋ฃฅชmY๙L™๛• 9ๆOวูsyฮ„ิ‘\‚zJ?@R1F ญฐ=  “:ภ1e์าPM�๐~aพโ\v๑�ฒ“”…q=ฯ;็A๙:๛ฺจœบŽบ)c!C™}Ÿลฝคc ์1ลวxeDdู^งD~ซญ u�สึJ๖ชเหน๗แบxZAU?ำ๚�่ืE~E10ฦข๋\*าrู๛ๆส (๚�_g€„เlm๏Ž�K—วมyชa^Lเฤ๔ะๆฐร 22โˆg_ภัฌRฦpฝrศ�ไจฎฌ็^ฏ�W‡CRฯ��#iEœใ,o=ƒ“xฮืตRฟ๔๗}ุUkปkฉ‹zต0/L‹:แผ Jš๏,ซล—Nขskสฬ ดpำ‚กฤ{พฑoFpเ๛๘�ž žป@ํ=3�ศ๋€ธVPืษัูฤ2ฤ๙ใŸปธฆ;8฿ห€ๅ"K'Kญ9N“Rญp]ท2ฒo“N๖ํ&เiGGg๔ฎ�์O�XDย็ัศ�Sบแ 7ภ]Cฎฑ-cO๏“ถ ๕_ฆ—2[ะ๒นฉ>๚/`ข“ค์ุŒL สโฺ;ฐเ!๛r‰ถฆ ๒ˆB๛ivz>ไŒŽKEf๗ัa“X=งPฦ&2gนl}Qญj๔I`b{‡่3็L&…:(@๖Œม#๔๊kŠ˜�เgM{.Gฝdšโpขฑภz๙L|ฯ๕ผ๒ิึฑm€,�=ฒ�|fu‹4ok ญ\ฦ9ดiํ€๕Cสs`+=ำM๖(ุใ:ฉFže๕XH€FGNป$๖;฿{LงLpT๊ Ypยบส�ั9ไŒ๒ทr๘˜=ลOฌqJ/Bทฟqm� ่NAจ[ฐdFวฦี๙๕Tใii:4”^ธs7dฟ๖Šต ”'ต<ง/ม[ูlฮ‰)+คŽx ๘ธ�Nม:ฃ›Bvุ2ป}`ัe๊˜0KคO๎๓ณgธ…. ข๎Gืว”A�่๎Pไo#Aƒ>~ŒY#5b{‹  `๏ �น๘ sห์+WงYMX+ึศpŽ๗xฯ6เภ:)Aฮฉv•r@A‘๓ทก ดv„ d?บopp า“mํญ-pD฿ฝvส�ฉ�<Ÿฆ�๚จo]�ˆ,œf๔ท ฝvaฯ%ณP;ภฯปคฎg๒ึ/๗Œgฦ€—:Qะ–7†์ท8๖--‘W๖ iƒ|&OJ$S F*(kบถนk` ื]า๊นNgo7๛ ฒ�๕:โฌkGhOูšUๆŒ Yd์Naบง6š@ูglฉดงcd†lแ0yN๋tมุฉ…Yุ ๐4ˆ~ฅ>ิ๑๐ภเ�๔ซฟ๘ห๑ำo�ฬ;ศคz7ฯล๋b˜Œ็x13๐/˜\zƒาˆ'==ฃ5ซ๛น๖N”$ส�VH•8ข'3‚e~Vแ8d@บaฺ *‘w ๔fW ค์ [๔ุฟ๛*ƒบ๚๛ŒาQ�4ฎtาโบ(V[ๆ4 hpเz RL‹8ฐ/ญ1ึ๕]F1#ำ* cmฎาฬมFF9ลFไฯž;8R๙Pr้)Žื�๗�ม9 O2)ณSO1h๖ำ�์Š *3V�.FBŽˆRs� F…ีN ๚ก์ฯ๙{ %j/c]ต ”$ŠญTŸ^D=4ยฮ ใU <ส0jศ-ื๑2แนp-Xววฅู--ฬขRf–'C‘ฏำiม๚ๅฃฬูV9ํำKy GLCณฺQ[ฌซJz4๋ผทJsK*�0FtLp$PV๕Zไฌใ�dFอ\ใR c€ฃC๎ Fื�HŒสีB—a|๑ปZ4ฎ ิั>๐Zบ3ดเ€šำnTฉ€!3ฆcตŽ๙ษทะci›จ�Aj"šขS,hS"UEร=ฃ๐bHc่ i๓^F��ฟ^ื‘เ™žG~ "j•ฃ้ธQซZj,รV@ SคY\X ๚จณฦ•”G6‹CRlŒ่๗>”Oว ฏัkิ4หฑt/ํภฑ02vTMไdศ๓ัŠ๑|๋๖ญ๔๒'^ๅฺ๔ &โy+cๆแ�ิฤ8*1œ๗YฏC๖ฺ.Žq-นจ;zœ˜x›็€๊†y๓BDผ-�Xว|r�:qnH'u8@‹iโท�žป2 า‹|n™t2y๛ศ”†vdฅL,ขงD๊jt|กณpžฉer6sสz๓๛ฦ$ˆa—™=E"๏˜t/ุ๚์œณ{L”‘mIก@ฦZ฿”ส|๎”vm| 9‡a�ศyฬsF*Ia”ัX4RmŽฑิ๒ฑฤฒ6I%_สS4ชr8‰8>�{Š_`$๘Ž:็”ษa=00J�ง:]า๕œี6 *n~้ัไัi•ฬๆ 5€G9๛Eœƒ] ๗nๆืยq๋ห์ษ"ฮ+l�H์—ZdมสำูTฺ„ฬฝšำสMFžอ/gโY€ฮผ�jR„๑ฎฤeฟห˜Dศ…™ D์เผ๑�า็-j*Pๆ�ถ๗uฑVviXg?ตเLเ\เl Žˆพ–็ั?u<`sฑGdผฅฝ+รŽชใLu]เฆ%@ฌ  827Œo…็9.›ช‚ฃ‚?ึcc>ีL�็k—3 C@} รจ|Tๆหพ/แ0!ร*Yฬแnjj‹z:V๎3€}›Fdอ๑1ภ๔& (Nำ๖๐๋ฏฟ–Fฎ_N�cฐ5S &†&ธ82€R@Qy&?�ั}ƒ๕ฤะ๊)\j “Eq ีญL:.ผ?@ึgo/:ํx! ๚{ฟ๗ ๔M:˜:๛๋ฉ�3DzE3Œก๙Eๆ—โษ}ญฝiำ”๖ฟ2ชฬต—I1Eกศุผ—้+‚V•่ฅ๊:@<๖พ้KuœY?ึ&าa?ภ�ค~“มล ัCฒO่$$ุมม฿ฃฝ_g�.'U์๑cจ๐๕|€€พทท3ต—›Cๆh{œๆ+ะœmkฃs r่ˆ๙๊„ฦ^45ชiจ>ั็=X�อgm%ญ‹…D^ุา8๋vา่9‘� ˆศ-ธ?ญ}yž“ฌ$S*|^ำ�*9็‚์ ฬซเˆ:n‰ดวฺ]€Iำฮ`Eย๏ นP‚อฅ“�K๛ [Q์๎��Xร]ฮห็d‘†ญญ๕4z้2ฉ 9dใ๋ฐ‘†ฦว)๊|•Tด๛ค @฿ญ‘สtภUŸฒ q6eAqœR‹้'œๅ†–:๛ SืึฑฯS'๚(UšˆN!^ƒ7€>งŽ์;มป้ษg!Kƒ1˜ะฤพุž]„•ษ|q†gžอฑM�หGGŸ=R-^อ‡CFV1ASำ[@ฐำ•*dชutฌ%๊`ร^ฅถตชdษบ4ิ์DMz๐dš๕5๕ฦ}-ต�ค<๕ t�K}ZษVOฺmๆœ}PัM๗ ่nปTlย\กV็Eู๎หqFxŽ#@มฺซ;๒ด4๔ไหำึญฎีB6s":ฅ 3 "‡Vั#อWฦR/Kภ<2๏Œ1ฬObwย>ศณฏe‚h c๏HY…LkGg;๏็!6ตซ�zW<ใi /�K__y“”-:Y0ุVj+X€๒ดŠ6ฒ0pkุk”ผ 5ก~w๔าฅ฿�ๅ็ื~‹6ผใบx]ฬภ ฦม–‹_�฿3๐ๅ/':,์�ูํg–ๆๆ~ถนฝซษ^๖ggะึฌ‚F6สRak!y…ขฮฃ฿kPน๋ ชœ|ศDˆ\F„ฎ9gกดlขบ~๏gD˜�—หˆฟ‡Q R๕'#ล*iฯฟtเฃ�๖Žrฃ�VฎลX>มแ89ลAยก–:Wษ˜Œ@g‘ ขไSVส6็ท๔I‹ฺF „๋ๅศอ�‡.™รฺL˜Ÿ[@"๐ทRJ8S€*yำ๘œ�้ฅ—ก™PฤY๔Y EฅฒฒŠฑฤฮก‹cชฌฺF–ๆˆbฎp๒้pะ (ษ"Šฉhec˜y"@@–“านJžจ๙๛วฬฏ-ยd‡pๆO#1c6่˜ภˆุ$ุ†ุ =n0๒ŸญV?หbf๖—ล ีแัยุะ9ฦฐ1ฯัศงci‚Š_Eฎ\De(*&ศรv`ขธMระ�t^๘>๒=qสฦPฅ—}’)PsฏUฌฮ‡Jืwข…ๆ��Mjเี๑ซ3ง5ฯ;Wฎ�9ภO5ฯบร็ๆgฃศ™cํm๋ŽจสำวO‚_ฤ@ษ3ื ŠJศXฏŒี�ๅ+ภ)~แžŒ2ฟcส F†c3G]@Gื8์!NตŒ #GอŒ-�ฦx�ˆ„ฐ9 ฌฌo^ฝk" ีH…TJ R#ฺ��ํ8P ฑฆVอึ่๕\ต๐ฏ๕Œ๚™Fq้๒H๚ไ}šศHkT|Ÿธ๗ =y็�tฐนส>'Ÿฺ๎2@ย]@ฬรnฆฦ![ขฒ๋|พวz€์1 ุT๚ำ_๘Bบq๓zZ_™'ีฮด€ฉ$–'บณŒAiŠอ1 ฮ๔`Rtv0‚ldrุึั็ตขพsๆแี8ฉร๐3๗Tบบตt�ฬWอแ„5ห`ฺ๓�ฮ\ๆœo)ฐ?.\NWฦฏDงe ,jPy}/ญฮ/ต๋fจB Sวtฯฒ+ž`žทE-#š๐amื�ต3bฅฌ‰จ/{I‡@‡3จเ์W๗8๖ฦj&หZงŒZ ๒8ึMๆvะCงค‰สๆ‹ St™`�วDคฏ:่ท•Z�ผย!๑,ฒžถ#๓˜xฦ•๎!ม‚Zภ็<ภE?ไaRธ๐Rฦใ€9�ižี๔๋_ุบณ…๔ ำ™๖1(Ys‹๎E}ฮ–ภก็Iะ >ฟg฿1eฑŽOท‘๚/(g‘Ÿ3ปฐ =ง5Œรฯุ"๕ฏ�ๅ�(�ษŸ๚|ดๆปu๛E"ส“€ฐ##ฒ'@…ไพฯ`QL h๏oŽํ?‰๖‘EvูดฑŽ“D4าœ๚<๓ฺEิ]FjM•,ฐUญ๛สšธcŒ ‹โižmSl�ฦ&ห"ึสt‚ฒ‰ฐmฅ ๒ฝ2(w˜ คCๅiแi~� Œดeจฤvฑะ‰Qฯ4[ญ^G@vscƒ:ิq#ืศj[•9>๋ ธง๚Cอq-; f;็ธŽœๆžŸี3ฮฟฯเšz^<+ส �5\J่วง17�Vฎ�t�ฑ  ŒปํธN�[&I:Kู5LKแั+—ฃ๛Lื`oบO B˜YBG้tฑgx[ศ4™:ถ~N™ฉผ๒ฅ�4อ^ฌsyฦYRฆ๛}Œ•๔{‹โE5๚+่๋|ู�8๊รเ›*&๐ช์๐ฌ™O/๘๊s{^ีaสX†ื;็yฯ‘‘b?ฒ\‡"@“`sแ�<ƒฒตl}จ<ต+…E�ฌ6o‹รุ฿ศ๘ฮฏzRjA�� ๆ8n๓๏�›ฌ#๑uA�ฒํะีํ๙Lwgg<[V…sๅ5L๗Qฮ{จyภ๗�อฑุ(l XOA}rิู๏ฦyžโ5::i๗ห\›ฎๆQ็ƒ1>Ž%?๛ฌ่{ุFถ‘๖ฬ� ชxDZขส๋lฺLฑI&$5ะ—ณณ๓iƒzD7–Hี[�ุŒ@€9�สNฤNRผ๚ถ,บ๚FXษ า๎ๆ8ืฺR8ฬฬyฦd` ,Œ I™~ฮฝ�,-_Gฐ.ฬ ๖5’}…}ฤ&—ŒณE็ฃ+ืขณišี—ฬใก{ คฝร6ฬ9ๅ\ื!Ÿ๓่Dฃ้7n�I#ใcŒE6"EชY๋6XlY ฿"ผ‚iL+k/ เษ™*1_๊๎CƒmุDึW˜[^ˆT…หcใ€คbข๛dฑ„ส^r? N :+Kb�cWลน$ๅQนRล{ฮX฿ฒD}ํห9rฎ|Yซc ฐq‡๕wƒ๙ย~ ป‚ลVซส€l1mำฃ่่-€œูงCื๊สbV5ฅษึฅถ]E9฿ฺZ9€ืAR™๛ฒƒฉฃ$ุ-ยœฺฦryy;—ยฦำ3้�๏พ ่}uR‘๚ๆ/ฑๆC��œM 8พ4p†zปป๎ฝ๚๒kฟ๚๏�ฺ—�A}}oFฑŠ'บ๘ฟ‹๘็g �๙��๏/~s1�ฏ๘ว_๙ๆ๖��์Ÿ^^฿\}e“้9��ญขส'Fšฉ‚+{ฉ1๊�ฌ๒T8gCฅh ๒g ?ขเ๖}$าผT ™#งa› wฏ ƒFั่nŒd•p ƒHว~ye3�5‚#่๐œพgดJ,ๅ๖ŒH†ฮEฃํeˆะๅ1าฦƒC—ข™ํฝ๚0๚Tิ฿{๛�แx๕๕}บ›…p‘#Z]Fimแ07ฎ&ๆAeษ3 X ุm‰ฃqi/ ฯ(hฃc‚a €ขแe$ฑedkพ“Œ]ุ*ค.ข–ฆLOOE‘A.,ซย;�›u^4ธฌ6ผถƒโRแ่๐ี;W2ฆ†„รŽAฎฑ*ยฎจBิxฒsOo8GVgมP3ขˆล}ทกน๛๓ ;?งหeบˆ‘S*LฑะนญมฉีasuฌตDโใ9รP†ถฎ‚f�๙พc Ku`5่  ่์}ญ๒ำ™i…‚๎�ฬ_ŒฝฤผX›@J�๚๚ฝฟ?Hkหk๑L—1’ปˆ  ฎ˜�ฝฅYมŸ% ฅu: hŒๆŒvุช ๛ะ–ˆๆจJEี 7สฦะุม8[สฌ‘ภ“๛T ป†ข\€Q›ฮ๋ฎS้฿๒ฌ‹sXŸEฦ…ืt๎�หฆทH็ฌ๐p๖ก*ž`dY฿@ฆƒิQ้“-Œฉชd%{พzจ_y๒ฏ�ผJซธฎิ�฿C๊อ๔ฮ[฿HซP˜sDšx๏9‘วฺcฐ=๓ฎ๊ๅo๋ ี# W‰ตฏS;0bถ …O=}ศ\ง๋\�"›ถ๒*1g<+Y”๒hฤ0๓ืuD?๗‰0oรL8BœMด”4P#ฆฎปŒŸืณ็|j่ŠุBQ]ง]๔?หWOะL{#ใg๒้ณว๑~‹ฎonค‡ŒQ]Ÿs?u�รด/˜"ะ•วั(ุ1 ก†�_Y :œ๎p’L”ัj#ู‹x=็WZ�ดk@–u@ฑ๑๎หคŸผ๏Y]‡mมู,ฐrบ๗ท่์�ูj์๋ฬ๐m<{D?yOศ�uฏk ็ลbŒ2%ยYD&XLันy ถหKw_Œ}8@„๓ฺีkปj=|ภอ+s*�?N๓ฅL‘ �Žฌ57p€ฌๅ"``ล๔]ฮ†l[Y†j‰:ถWE731๊Itแิˆิ๖ข[d๔ "€๐�0i<เ๓า€๎•๑7Z:ิ>ณ6Žม AืZ–˜6P่>ฯฯn๚ƒ f–บฦบณ_-fw๗ลblึQj จa-Žu%uo+ถ’k้]ei(Oฌ;ฐม๙™š�H฿}็�4;ทยพ๏lํ็�ฺ๖Qบๅ{ำ6ฬฆlฉOfฆา�ฃ�ฤ$œVCส6จ…็ุdd)—bs€U์3ใ]tถ-r;กฝ#*/ภ66’้dึฟ,o‡กc้า�B์qf>ฎฝAJฅ้Lต€ƒฆ๕ ขุีิeท๖D›Ažตฅฝ= ]C–มขˆชๆ3ิUgฏ…?!ฝC$ฺ^๒;ํฮ๎.@„2Œ5๎ ;ง…ำฆอ1๕€๕:‚A#ˆฤ3VฐL)๓*ไผพ5]Ž8k์nHW่6ภ•c” gำs์:{`ญf BDŒR๏ ศ’๐=ม`dฤ $นo์:vส๓Žคfๆw๊4่ฌ2ฌJญaaDJๅj^9Iผ�จ�Zhท๕P›๛†Fษย๙ฅ;ฮœ”ผ="VFนqHฬ- ิ Pเ่y ' ื คฃ�<ื๖Q‰Z‹�=i•*#๖\Š๋ส„๐yฟbP ™ ห3X8P�_lฦ1๙เฝ๗0Pd0TŠ[0J ฦๆnWใZห@ๅฆ๑gแ fŽฯฦœG4Ehฤช–Hžั_Fƒั3aะA็+ :งํ ๚๖Z๎Bฺฺูqnปต@IDATa.ๆLๆƒcฬ5sพฝOฌŸcAแZํWkKวภ—๓แง™็ r<:F Uๆ:.Dดธฬ�NZa�ผไ]ภฉEขuSิœะภ7ืXJท๕%ๆˆF๎๓ณฌีุ5Œ:š�๒KฏภLธศ`4fŽต]"™วจ…า—๊๕tLฒ็ฑ�_ฦ ŒUพฏzŒX๗จ๛S0สW8[~ƒฑQU๖จ‡ัX {kBธOkกLj4rŒT|R๏W‹ัWCQฉŒfšํUls>GA4A>'h SUวณIoฎฦ ฎ"Sm�ๆ ืำ'?๓qภ!ขo~ใ+คa๋ฯ5mปจแz๕ต„๖Y฿œฅ}�ใQิ"zซซ[i�ดวจ ว>ฮQจW_{ งฉ%=~๘�ON3QV๗ฦ>ฬš ผฮ|ฯiKาe"ป'ผ็Œh_Žf๑าqcz8๓๎๓0๔ู๋ˆŠ คˆ"bˆyสaL้x่จipYk€šฝ‰C-ธ`่ŸzŠ%ด~๖ฯึ๚ x. M.NิัฅJฮC^งf€-๗ tช์woŸ๔ชœ \ฬุ 2W„ ŒฆUเ๙Tโ”›๓jt[ู‘ว": หBะIY'Sค‡ฟ‚ˆึTู]�ฤ1ฆ…(ฺยฤ#Xฌ7 Xพ‘n-8‡คxq๒œณzจฆž ว`KV sป>DMๆBƒ>ฮg<=ๆาˆZึป™ห๗๖ค—1vๅ*€มk์ฦX๎ŽTŽ๑๋WขŽษไฤdศ�p๚y๏wŽผ6*งC#้Ž,{”1{n”-๎\ม ejžณ.Kฌ™6m~5แ}๊๕ง�/�ฦ(&zHJ‚5)<พฯฺ ย๎bุ!หฅ๛<ง€$9ึจ‡ซจง๓X๐w�kg๓ Ž��A@˜EฮŒ{ษ1\เ$จ#์\‚๋sbดX'Tเ'X@๊ฎmW�‚ฟ็Lืp�SV9†:ไ†๒KๆŽภC€b#ๅ"ธ[่”ไˆฒห‚นถƒ5Rk�‹แzM?/[หs๊ฝ.Œค�์รiou3จqpj$‘๑JRJœ‰3dธ:อน~~.2ง#+B้๏�2ตI&๘$kะa_y�{X'�าศeขธใDม"_\๙.‹รึjภT๏mร(;็ฏ฿พ™†Bฎ \นr™”$ป†0‹์c๋ฐX�EฐLe$฿ฑเ;FๅทrQ๖™ “ฒl—Bk‚๔ึm๑ฏE๔ธcœส๗‘ tฐ`˜35G-๛R@4cU8+ุ%์•ุdžC‹@ชcœ�mฦQไY#-’wZWข *;^rz1ฺ‚๊8บฆF”™ไšŒฅ๑ฑ1ไ8๕˜mœ๗j@หj˜ˆตy“-ค์ค‡ž&๋\่[ำ้ณๆ>l๋ ลqฏLรbz›tฏฺ^ป๙ Ÿฏธ‘tษ6t„�ฃ3\)็ภ๓“แ่๎Œภ#m@…œU๊ซฐœGZ`ƒ™2hืƒฉoe�[dา‘@—ํi๚งฌ. š—ฟผถฦณ“–ษื>๗ฺH‚5\�œผL‹gZ๗ภBผ‘†Lซr�ัm่‰kืoภ&mฐฐ— ˆŸH[[�M‹db)Kส�[๛ะZZ๎ษ"๖ˆ๛*oส ฿™&(t็ฦ๕ิ„�2ห:Yึ7Q^E €kcํ"ืลน๑Z๎•ฌ8ถ็ฦ=ฤ�ฉ๛œC๗Œ้”QคšSSห\๘ฦ็”�ป…�Œa‰�#ฃยขฝฑ็9ป‚ง�'ะ- ฆ‘Q&ุ[ƒผy๒แร4๑เ!ตO6า!A€cภMสr`Gั†ำ YmีAk[ำ฿ฟu๓ฺo�ปฟ๐Kใลฝ>™า—น�ล๋b�เ ผq๑บ˜?� ���๏|ํอ�๓๋…�ฯ,ฏP๙Ÿ�ๅ3S ๆ12฿UฃณU†F๑แoา�t๎ k4i€๊4๘;_:™*‹ษ *8ฦ‚BRะ!Sบ) 0็Zื–„ำะ๑Dฝฦฐ A Ž–tn)ƒ^oด:œ-€t๔Dฒ1ƒBQไ4๐f็a€˜wต๒,(ŒI#œ�8^:�EœU 9�สฺัคลดtถ}ฑ+นฏ–‰฿n{ iœ_€Zœosi{็\ว่ตนuงDe"…พQ ข ง’9๕YR‘]Ak฿(ล๎–าสๆ “DคeQ๐‘4PI๓a+C[yš่ฆืภ๐1๚ค29ฦyาฑั™หhฑLืท˜Ž๓xFส‘Žลีๅ49?ฎ_ฟ๋ขกw`/iพš๊š™†Xชˆโr:รgg˜‡\ว๙ฑุ”†นฒธ#mะNูšฤใ๑q )ซ–2฿�ๅi5iั๒ย1นสะo๗ˆrืนถยฐJุq]ฯ้ตpวh๘iฎeฝuฎOษ›ฏแูฯp๐V1๒ž<๘ๅ ะ‚ฑป…cฬลเูAž&ฦ3ฤ”(น›๚ณเ––ฅU๗ฅำJ#Tัห$8ฃš) Qะฟ๋ไZุ*>‹(ซc'ฝyฐ๕ก๗ูมyˆ9bฟy=ށ`กO€ๆ /bภ<˜๗ุม๓ูีฃพพ•nซY$ช Š4ฯ—เฒโ�๐่`บ�ย- Cขฎฌ๏&lŠŽT{Ck๊‡�ล๙ฌ0|๕zชX™ร@�N=ฮ'|๎#ข็�ƒ{฿ šขฦ+0ธˆeฅv ผฉGรQ๎์dM2ฺ†Ž3ภ\`ฏ๋Y�‚*นฝๆnSไ“่ �ฬm†kไ๙ำฐื8๖นYช0� ฆ~เะKใด*ปฮ๋.4q2sกฅ%K)WFดVเ rŽžMNDŠJ3ฟŸ#"๑8ฮS?”์๎๕ี๕phศNอD`สะtีqŽ่�ข3^*Qyะ�O^*,†๗4’๋X„lฑๆนะธื „9…]#โa]ๅ•๛"ฯ๙�ูงž๖`q7mต“๓ŽCมาฤร‡ฉธั@ฦs๊h˜zMม8ษโ2 jZp„ุ฿{ค:ุUPม‚Š5๕ดฬยˆ๕oM€6ŒVํฏยฑ•uเ>5hM D็nไ๒H๚ยพๅQ'ๅๅ๐ศ๏gฌDภ,ฎjTTง^Š๒๛LฐLเแนั้{u�ผถ2œ„C.�Ey”Qคษeo7ืตภ่เ์รtเ890|pVNyV1Wฎ]Mƒƒมrฦ๋œอ' %๋ะL ืFq8ๆv ภแ�›™Aึeฅ ู 5คโบ>�อn3ถปs คๅไ*คำ* ๙ฉ๑oAH wๅ›{Mะวgq�q–�› !?{]CืฃL=�ษU#“๗q–kXใ๖�ัW!}ทnSwŠฝน๛ัจG๒๔าๅห8&ณAvZ•๛†ต(ร2i�ญ#ส[%๚ัฤำ "ƒ]น,๑สb็[2™฿:6_๎Ce‹ ‹ฺ*Ÿ•tt46๒๛‘)xO&ŸlคถG ๆpโ7qœฺ’ลณ–X็FA�ฬ๕�ใgฉh ˜yศวjTpftฌNHpXดZŽyQฦ1ฐUŽ…o‹ภ๕ุ—ตศnฯฑเ‰}=`&� / 8qตคBQๅ…น@oาuฆ’9jlเฦiึแ/๐,•ศฟœF๛ฯหฐูฃ๎Œ๗p.B/๒™rPม3�พา6–ฆพ`๚9uพฬ%ืฺ่ญl‚ั‘~ฮ7เ ฉ~�Dำk]]dตมฏ฿Mก9;๊š|๒ใCf฿‹๔ตร"�%๑ฺ0ฒฺt๎๚%ฯ๎�I~๘„5ำแงๅs0ฑบI�KฒYฯ9>cํ๊qb]็ ๎ซำ๏�eฎัUBฐั/Sจผฏ…e3tb4ณŽน*ุ๓จžTแœสŒฌง&J'r~ชน6ดภ_Uฉg๋๓้�ƒ79_mŒ{vCม•!@yืZK๋Gค)่๊,าตiŒฺฺ*Dฑั-‡ŒS�‹ฟ๛ฑQอฺ$zƒ ๚6 หำ3ภด3#ๅ[€vFt๎>š€น]ถ๖Ÿ๚�๖๊็jlA/ำ"ืนื  ม^่zjFดuลy8‚‘—ฬฐ๓ฦ๏�kŒน~ใ๔๔(ใhิ[�›&ํอ-< หWค ฟ›[๔c.๖a8^e‡‘}๗ฟ6TN›A๙์l[ึญฤ:iG-ำฅJภ]ึš)  bak4Žฉ'ิํŽ�uฮ€sSรชูCฺH๎mฆ3lมwYsg�ฌฤsY/jgKฆ%เ€o๎@†ุ ถ yำMŠFVฐโ๒ๅฑ8kุ๋9ซ่ยอJกุ7ฒหฺI‹�€9535ษ^5(cืlภๆ๊4:68w๓๖‹� uP†iฝ๘kฟ�ๅฟล�)�{ฬภล๋b�๐3€ฝx]ฬภn~ใฏ�j๎�๗�^^^~�Hq‰D PQpg|้”ู?YแX!Eลhwiก‘~)X5”4J|ฉค55.54^tศšˆศiึิ!8ฅ”e*#P5ฆuT5~mฑง@๖Z~V"่ง�9ฺDฒํฟm4Eล�‚‘qฅQBz+&:4iŒPŒHsณU่‚ๆAWฃภฅปYี\G๘ัขฐ%ถRQ๘,h๘ˆ’+๐5blVa-kกฃล'Rๆu4Xณ๑aดbไ”ˆ่ฬ้ล•ฑะ฿qjˆ่Pิศลีu‹ฌ™ J”ฬ๙a�^Oเ@Eผ€b‘:\TQฦX2N‡ฅ๔ฺ�ๆš7ๆžc‰๗ฯ,˜QัาฤœŒาจŠ'=‚นn™";๚(Š๔๔nzา�=<๖9ke…r็Hšด‘<ืLg "ทฬฃŽ ๓โบ:7ๆ‡J๛7i๔ลCฃ;‚๚ัi<ศœ{([฿3 Gฮ้"ั@{>ๅฑ%จผuŠZ้F1ฆ €ตด8หN9‰|พ6"ืƒ2~ฐพnŸpv8€&ฬOฆ$ฟžหฑOeAฐใtXฟN•Š฿ ฆAกS้˜4€อs6oู็:[แ๐ุาQŒ•๖ญเl4Dรฏ#ุhˆ/ซัk|ปวอ‹=b�whƒgแN[ข5@ฏ=ฤ—Š*ฐaDำ–TR๙ต:ฎ^ปย|ำขŠ�ลษ?Lฯ<$ZJ๎"F๑ภเ †e> Ž �งล€ภg?๗yŒ {คOcxแฤc�ฎรˆูมฺPaฌ;`�ทœฦŸlžz}ๅ่$๓pภXะิbไY—Ÿ mฮ ฆ1ืgŸ;f C้ฃฬie๘EHู1‚ดPNพ „F ฌัผฝิ72˜๊Z1้O_%ี ณ=}๏^8gปQ‘ณเ~ˆ๎%\็่ฃ�้3€คึ. า6R๚่!€“ฌ”<ŽLCฝฮXCŒ7็ิฝไ7ฒEคฑ+[4๚"…q Œ้@็)fฉ|ชlื-€ฝcึชžตlศ[Ÿ›KGะG๓์หfb Tนo๓ E\รข_ณ‡0%˜3F�Oxfืฦ๊%œPeY5ล อ๙•š*MXGRZบ็^pIึP‘z'ตDŠฏ�yศ�งC�ฺาศพy๐ธ๎แ๙…ๅ`Q˜ƒn$Tg axBm˜K�+•�นฬฐใ‡8 xศzฮ3๏ฑ“A"“ฅยYz๑ๅ้๒ุฅˆึ ึ*wMฑฒNส[฿๙็Ž+ฐฏฮี๗ž�:๖€i:ร—ฏŽq&ษล]ๆ๊ มdŸ฿nดbe2,เjบ†๐า yฮ=u~ƒY€�‹ส๐๋2ฌ — 9dล๗zๆN!ว�0ฯ-๎ €‹3.ˆ[ลน|ฬ๑นsZ6น์โ Ceฝ ฬ=sฏพ1 hsC๚8{‰�ณผธ๎ฟ�6๛'˜สๅMt!G�ดถƒCลณ€ญยล็๓๘z ”)'uจิ๊ฤSRรPqผิ‚ฒNpฒ ึ‹1J)ƒฦ๗ี™ลฟฮ๓ :โ่ ม.MฮคgŸQปd•๎)ทะmu้�ฎคYเM€ึvlศ2žร฿๋0ห์ัฅชb�-์1ท1็๘;ฮ*sฌ9๖E™sภf‹hlึF˜}๎ยiฯฃใ”ฃV}/โฺฉ$N๗�ๆ„๛�ฮC–๊—E‚M9pข�1zณึ‘-;ฯขญ*zฯ็U็ท๕แlNxN‡.Qp` าฑ”ฑF eS๔RXU]kล๚ว“œE๔o"0aว–2เim-/E˜"ึทX`Mีูmิุe)‹ซ|v๖C8„่[ฆ8l็ว=๊ผX<ำšO9�๘ป๓(Xwh!s่lbฌฒ,]ืdT๗๚ฑซป%]ฝ2–๚(4y๛ๆ-@€ฦ@+Kœ^ำ*‘๕•UWย�’5pzฉ์FซI‹s+้้ำI A›’€ฬFž�๏ณ7ญ๒oขCRC์*ฐป#๓Žqs%rใท9;ซ†ตฅ๓Ÿ bๅูณ€฿ฬ‡ู>ณ๋ ใํ™�ฃ�้”5�O€ˆ7๐~๊3กืw8ฯฒน,่*ณฤตซyต•v �ณม฿#๋-ด฿j'ส>i�ฆคฺb๔ๆอฐY์บั3�OซมE'ํฏม ปฦธส้ฝ{๏ณ7™žameฆไเ๓<๛Bภ1ซ�เ�r-L์{ฦญP`๏W๒œฒwdฝดbC"8~ูIg์[e`ฮ‰์๎g ภฑฬ;ฦฯฆ ฺI‘ฦ‚>จะ‘ืv๐| 0ไ™NL`์�8K่S๋=ํB,ยn˜šHณ๓S์Wd&๓)ห!B€ ๐–๛ฎRฤฺ4™Wฺ` *๊2M>›\3่ฒ,hZ๙�Ÿ�ษฏ�+_�โ๏�โฏ�นฟ๙ฦ็�ี฿�ฤงGฟ—หต๖ปx]ฬภ}ด˜.^3๐ฮЉบUู”๏{๔ม๛och�ศใศ๎cKุkMถ“€ฮœy�<ฦ€4ข ัYK•_'๚€WๆLFฤ!ช๐ถ8 ฦ” ‚ฦJศ�ๅR�คฃ๛;••-ๅ,e^`Dไ|ฦˆญๅC”ƒ๙˜ๆ™sฉฏGซฦQŒสถ ลAฌฅbฎt4บq๖ํ!^$zฆฑฏ3นmฮ<อU fก๊ก�ธ‘Tวo5�ZฦญQd~YeŒ•‰1@„ ว0{1uภgz4 Š P‚ฯ่ผ่4ฉ“Zฉ"–ถฏขต"๔ 4=Q๔Sฝ@ท ZŠ}ฐ0สp๐ึQ.‚0^ฮŸFฌ๓m๛6#B:๓vx‡™๗i‹VโŒ5c0�ฝ{7ๆb…ˆ-SL๕hœrwํPะั�™z:๛Pดๅ๔ไษ$‘| Zก\นf†N ‘Zๆ]งA‡Jcส5ฏกŒ…๒dอTrV!v,‚Vแ3๐ฎฮ�ฒhฦ†ื6‘�ธJาbUR}^#๘ฆn0฿0 ไจ๖ฅ+ccฌUW 3sำ8ฤDwYO#G‚(t็DuŒnฺ๒ _3พ9า_ ็]›๑`รว^:ัษb^ rduธ์}w ˆฟ9/` ฟ๒๒ŸJŒsา๚ป(ศูFๆN"†ไห6S[w[บq๛Vบv๛F’Z~ๅฦีจ†}๓ฦuN๛–๙๊‚jy๕ฮUR0^ CุVKฯ๎�O‹P�ฑ5 Œ^bอฟ๚xvๅมก! ดFF#ฯำœn]ฟ‘ษก�ก4žำ๗ธ/{ ์ตmœGซฃ๋pิ๓พนy"๑8Ž‘๗๏๏{แ8Yรร๋๛ Mผ�5c/มผปŒำฝยš1GฎศLsŽีแภ"“ezน฿|žVbปBDํ๖“2ำต๒_ๅตใ3m!œožอสMซ‘W๒†sฬzVp-h็_0งŠต-ฃ3”Mํ�ต�f}„]0-›Cเ\—ภ {BGoถึ" ‘�dM9ถ-$kmq#‹Nซ€$ทS๘ฦ:=Uu~Ÿหoฟw์H"–เ!ำลŸ Z) ZะgTT™E5‘g่ƒkืIIเ์ิม2ะ!๑~"ธRฌ7Y›yชึฟ�๚๋ม=ม@บเŒู๑็Œ‰ะษถเใ‘g”ฟ าKŠ๘ฌห92ฬ—๚T‡X@‰‘ใ(>ยŒชX;ึก‚แว‘ ๐ฒ™ˆp=ฒR6‚ฮ: YXG =๒‚๕F[๒[ฯ@†˜ดํ‹uฺ#MŽ๗h่hฺ‚V r6ƒีบ4dMFปYุ๖ฎึšฐ่ดhe;sถ‹ู8ซB็ 7XsูHึ"ถฦย์�< �F8นŽINฺ‘]eLg๖"๓ ฬทy-Šนg�g๕R๒C"�,š[…�cกVูXญ€ฬ๊.ฯTไษ3๎ žนะB�๊šƒอ›รึัพO0DPบ‡:& ฝมT’•fOa>M33โ”ษ๕�็จP‡ธŸด+,†๋~๑{๋‰,ุณถ$ฌW)—eZ๙”็‘!๊๛ญ๏`”�ฯฃโหmjสEœEŸ])ฐ`:ฆv—@P‰ณ๏�hจหธ^ฬ๓… ™gSMLฑบ<~…ZKดผFFศŒ †k์•)g_3kะ„}ฒK๚แ&l‚"ฒTะByฒม™“1ๅ)3=cŠvี�ž‚คอ—๑้žQึkจป ธx๎C o๏”๙2EK€•gL‘‰z�ุฐธ–Ÿ}พ,ญA€มิA!Amฒl##�สืมณ ืcƒ†ŒmเฬXcAY๛ุ๚5คะึRคีu˜ž›โoลt๖“ฒZ�่แฃG๑eพูK็��ˆบ!vใธn|๓อ7ำ7ฟ๑๕tฐƒจธ•F/w๎�[ฟ๒็�ƒ_�ณฟ๐_Ž�}๑ป ง--รG_�๒ค็๙โu1ิศ,๛?๊ง.��#79จ\ุษ)อ|�๋ฟ๓๏�ปอSณ‹?��ูT]Z“Vง#Œ!ƒาฬก+0ฮ: ฺQไHใ ญ๐“‘ ภึ™P ๊ิjด๛}™ฉสg๏0พHd�gห™Vข@ะ�1๘VqtWV7ย รkี=ะมฬ!ฐฯ‰N>wbฝฎŸq jV่€K“ฆจฏ๓940D5โT-ล2฿D…๗9 ้ฬฆฝ๔*๔�!œœY8–Gะ�šŒPYœz๒ˆ��]œัLอCy”N( 9ฉณๆาk*0™M � + ๓ฅqbฏ฿�}Šกภ`6TุV ใT@EƒุŒำ๘< ส฿›[]รผV ษ�W*้้GNND�PbFK4r�อv 4h ณน™E”‹{(ฆ3Z5๕qmPyข&ซDฆ& ?พ๗ๅ�ˆ,๗งฤฦY E"ณžฺŽ=6ใมฒf 2€HธC0ม็ – ใ วJชH} #ˆ>แุ๋ฐ4A๑ีH๔ๅ�นŽ�๋pฟxAพc=)tˆ!SAEt#ฐซ+ณ)HŸผ๛ Fy4พฏ5_ dผ๚Jz๖l:ญฌะโcTฉฑต+rKดํช6ฉข#"€*kชแใ�‘45ธš :๒y‹ำนuZฺR๚‡๚ำภฅขZ๗1พำตDdป^ƒ2น5ฎ]ปNช@1ํž๏ฅห/ฅ—๎ผ@›๛~–}ๆ๕ซ๗า“gOา&เBล วฎ&๔‰ภX†ึธ๋ยผEซ#ทฐŸํin/ๆํc(ํDๅZˆd72O~€!yœ๎พ�์ ŠDa˜ดŒ๓\t`ŽS4laz–\l EŽ๐ษฉฮW%ั>€€ ",? �ย ž—T @sƒ—ก Br_๊๊่ลYษฅ๏พ๙VZ|๖,]ปr+ชkoฑ6๛า]๋aV9{™Pv”8$๚Z !Q๛ช=ฮ…ภV๒� ๛ƒณิ\w็๒ˆhm#๗C‚ั�o=s.m=จSทi{@ขc^KฐKŽEท4 อ๓๎์่ก๐�(ฝหงนŽ๓yฤ�V:ๆคํ./d@!๛๐˜kXฯค‘�_;Lh€ณึศ0<4’(xถF๗Œ$วบ‡ณa{Hฅf7๙�_�โŸ ใj๒sปสrๅฅมS/€๗ฦณ๓ฝ๓ฉ œ5pพนŠฟำษีi๖�UำNQถ— ž�ƒๅ๔;�๔Ÿคหวp”Wฃ๖ห๛S‘E+\ๆC*ฒcห Bๅฦq9ฅฆ‹็Z€Qใ_ถ…๕tz-€)๓๋}ขAญ�jภฑRF์ัRดƒ�๓๖9&ๆHƒkไฺิืJ‰&ยหz่X™ๆa‹ห:@bŸCถหๅ›s�s๎ูgXเ vrุย—0าd|U6Ÿ";�124บ;;"ตgck(u ็ฦใzkK| j(tบซผ`ๅH฿hไนศ:‡ฅSL๋8+ž‹็ฏ˜ฦๅy๑หŸ…lœkWŸ‹?ณšฃ่)@MSUtpbwฯ—ฯ>Bตใผ^ฤ™ๆะ`YฆๅฃŸ)2ง๏พ๓n%2๛ Š�mฌmค๏? น�ฐ๛,ŒศMุk่WLœw�hV๓}žH6�eฬqเษ‰ิ~๖�ิแŒณฺฉชฮ>ฯ)ช{†ฌ+‘๎•ง๐ ๛_ง๋`‹ยฐด฿ฃฐj บฺ๖ภ๕Tื๏lค+ษ*๗็D!Ÿญฐว๙f‡„Œๅa7-ฎJŠ่9Oถด�ใ�หiB/\bึsถ๚ุ3ฅกื(ศ๔‰๗ำ u(nฝ๔๑๔ษW?l> (์T€seSฤ9(ฃ‡๛zฉร๙™ฅเ้AeX#ํuŽอgืัn"Uฃšhฝ๛ืZฎ›E ฯ›pส๋ œ ฺฺZเฌ Y'ฏ �ฌ&““>ƒvAฒH “‡b฿็ำซืฑ7z`ตP/ ๋hฎภs5๑์พฃะi ฯซ๓�LPฅ–4กrษbชเ)‹dŸ=แx�i%)X๊yTฐi๚; ;ปท๎�ฏ โฃ3™๊ส.;‡tกC,J์5\๓XA==8๑ฐ d‘T:นg-๔ง์ุ#Sลฺ |๙ีaซก+uช•{ดCฏ‘เูgM7ฌวf4—ๅฤ_าภะ@P๔ญดฒฺX]J—ฦวฑ�ฑ้ZาถสฃGฯง‹“n†…›๗wฑ๓`ท [ื, xะމb–3ื-ไ; †/eMS#๖*{สฟๅ9ฒMŽๆ Š1?พ‡yซE~52๗G'ถหล�โ๗ึฤ’mฅ หc8oึ3ภ1EึAvฆ๓์'าีfฐ_lc-๓Rภ[ˆ,’Žฎ‰~l ๕ <�"•่5Kl‘m-จม6๖ŸทCัฮV!=z8™ž>~ฬฤRo(๓L-“แูฯ�‰7�‹?�ฦO�ร\๗-ะiท—}๑บ˜?� \ผ๙๛—๊ำ •‰‰‰š๑๑qlU3๖~๘๋•๛้๚๛พ๔ื~๓ฏ�ล…ฅต�ฐปตฑ๊๐<+|ทBฏณ"ฅVฅhnู �สOEgtCGK,�๙Uจ๊€๘จJ„ฆฌ๓Xuk1Ž๐*‰ฒIดโฑศ�ฬศซ(/jE ’U‰จฯS คทchh้,หfจ#GMใ2ข๑(0i๎฿๘ๆ?Cเ^‹ศย&•iอฝ1v#Œด}ขuถา;„Yะ�ขš‹๗ฟ�vฺฦ)ด�ฏEมN0(4ดy๒p’U”RาX5ทDูผg๋ ˜๏+�ฬ๙ 0ฅยฮ๖฿-`<Ÿำgห-ๆM:ลส 08�ํ (๎h}?๏฿คYG�*ฦ๘ކ2sํ๓š3[ญขฦ๘ญ4ฒJใ>*์”พ9“|2]@ฺbŽ๗,อ/ง{๏ใ�โPํฯNฮ!ยjrๅผwฃฮ๛บvŽGg&ึ”Ÿuะผฏ …Jูฟ้”ธ>‚าป ˆXBสฟ<)†Fฟ5ˆํvก’ีนฑ>… ]ถ๔ึfขLRำ`˜ ะฯิQPชˆm&—ฆขšณ…์ฤศ€ฯ\JuB;ญงทxWWฦ#้ะI?๛ฦฑGชำNr”ืS่กะ�1vฆˆ-เ„]ฝ}3�}้.Ÿi ‡aku%-`ฤ.ใ์tฬ5tต@วงbu…�0ฏ@แด+I†๘�,9ใŒ/_{)Œม†�โณงฌงนซ)-m,๘%mฟภท[๕ชqŠ%EžรjJ��& p๑ฟo๏igหฑพ๎!ฃ��๋๚V`y gฝ้\j„EQJฎkt[Gั”k+ ไ.k!0พสฝW™+ฮำุศ•8ฏ๏ฝ�]ข(�คฃ� X_DคฐJ 4ฺGพXXณป›บ€๕<ว1yฝ{ไห{‰)ธo-๙ฒ๎Kืต’Hฐ,#๗Ÿภข"โวธƒ5รณ้q7�๏าตež˜_K๔๛ƒฯ๙‚ก0Xฮ1|y4/rกqฒS‹ๅฌ‘@�sX(ถำุ์$2OิcYTฤซฦPdฆX7๎ €ชม*๐ศฮฃKoDใN คI ฟ๕ๆืฉ/อ๙z๚่> ขW0ุำ7฿zถฦ.๗ฦ.ˆฮฅ}ฮ\็ปPร3ฉ<๑์ธ~:จ�:ื~๙;Ÿ7“ี�฿๙~ฯ…sๅ{Kค.�“๔๕—R||ืY‡ j๕Iั‡ฐ$ŒZVฬyŠ ๊4[[ฆ{ ;€o|ํ[๑์jๅ g_ภฮฯศPพqCMาฤืฯ&ี��^Y!>B�Qชkธh*ฐG�b~�/ˆฃำืWVsํชpฺˆ–ใไZัM๘o2ˆทhM๛แ=ึyฮนทภe'Nจy�ฮƒบC�"„P ˆ่nค=๔?็‘นD^ฦฺ0ฆœฝา™Kญv็อg๐ๅ๏�Y*จ��(˜Ž๐ๅฮงซ”ฟ8ิพฝผฏ@‚Tws๚Mฑq<๛์ลจ‚l<ฆVL{฿š1|n๒ษ#Šถฆฑ๑1œ๋์ฌฒ——ึำฬ�b8ฑuฬภC%ลY†@ฺ {ฒญฃ)mกฃช๓v‹ษ#Kqู๊Ÿฅ}Šb1ซuŒ™b˜๘Ÿ๔Tไ›ไ^ภ๙/Ÿแ๐wยCgwBv๏๒RฤQฏ(8%rlฺุ๐HOฬ‡บ[fำ9s ฟแธ„œG�Kƒ฿โพ ๊”ํร=šจ%R฿@g|…š.e๔ูIŽ–จ �ฏีตUฎy’FG.„OฆI,` *ุBRˆ�‚ฌHmjญKs‹๓ม€S~ส\ทตไ ‘pฃๅษฏ‘yƒ�T_Z๋Ay `ฯdFปJม๗ฑ๖ช ๙ŽณษX6๏`7T0็�=Zฟฒ'M…�ลั €๎๑ฃ'izโ๛ญ 0|(“UสHe%๛ฮถฅฃร#่Zาชุ{5ฌฯ9ฬ žxUฐ,ถซ3jฏo0@0F�'S ๔ณ@ฎ3ฬx<ีลส่2—2๛าHƒ ํไุท’ฒฑฝpศuLฑfJ[G7vึL์kํ9eˆฒแ=ณ.ผข\,ฒ/LIฐR-เ‹iœญ่q๘A0f},์Zก./ฆ"๛ท`ซต‚ยิ�฿=x wJแ�1ึp“ณ฿��Yไฏ5ดŽhญธษs—ูรKl<าyุO}ํิ@งํซวo‘gQžš6#;G=ฏ R`~”kฺiฺ&ฑŽฌนฒVนฏ-ฺฬRฏS‹๋ั+ฒจ,ž{ฤ|ฑSaยŒeบทb8สyฯ“€ฑrู3žา� �ด˜่๎มJ0๏Lใ\_bOืฤีRฟbaj)MSFfŽg๏�G฿Ic7n#ฦ๔ยํuX!œ‚อีๅ4<ึ๛�ฯ�๋?�~๊็�า�<ŸˆVผ๘^1x๑บ˜?ึ \ฌ้๛—๋ร5w—�Ÿผ๕‹7Q ้‡ฟ>>๋ลํๅฟ�›�ู—�ฬฝ๛ฎYA�L็#่าEŸˆ9‚[��พŒฏ(ทJ�นคa(ีNรฉBึ€%/sฤEbw‰D5#ไ�k‰’aR/ฌ,D—Tvlดˆi š›ญถC�ว่๑ =j[0ดค์ตbœพƒ�๛^•p%Vฅส›ผ้ล•ฮ0โ็กž2.[เH‹ื ถฒ|นห›K+ู้๛๗R#DŒ8žก(Dข —:Qฆ}จ๕าlัไ(UOศ�์ๅn�ํนค~๑> ”j‰๗ํ์-"VID]Fyะ„™็ห๋่Œ๑๐YZ NJื7Z-๕P�Šฒณ๒ท‘6B–๑์R|-ชศTeTOฎำๅป›สๆKD๋5ฐ:� wฃุื่๗|�ๅ๏@ฟX+ŒFd\;ะZ uV`ธ—)˜ศ xNฎอพp*•๓D!IKเ์„สYคU็/A์Q2D๎,ฑฆํ€™ฬ๐ฬQถลd#๒จ‡็>_cฟ";ฌ๐oฟฐฏ~e!}�[฿‡SํญZn1ม-ๆ \ YH๑.dšฒ๒จ†ฝลs๊lu—๏td�๒ Z๏ฤผ^�๎๚:^o ฯ๖๖:๓c{1"cหอ<�‘N"{ฉะ@0j›๚,๎฿x1�ๆ ป+aŒชŽŒs- Y๊�๋ก9ว�]Wฦ9VVJ!ฮ: dเhญo4uเ๒ๅ˜ำUAkคิp>xFวฉผาQ1ฅห3.ฐ'X%ˆ4๙Z‡€Hช D†€&ฟCŽpVคื็๋Zำ.…ฦ–ูG-ค/่@ูฦฎฟ0ษศ๊ไฤt๚€ต‹็๏ถ Nฬแ!N^˜ซsj ฅ๑กํ)ส-{็ะ9Q.f๚Z;kก�sฬ:z�{oci–�๗\oฎ7๗}ฉ\+kฏ๊ฎฎ^g#{ศ‡&ฅ1ษ0�ไ'ู~ฐa๛ล†ั0m –’8cR–จ•†-า ‘’3ไ์=ฝUwื^Yน๏๛พ�\�๛ลค฿ ž@˜ผ=9™•y๏๗๏œ8q"�๑ŸUูh%E`\ฐ,:ๅp&๙l2H�c:$ฮCด๎ป/ฟž๚z;าwฟ�'0ƒEpยท๏*j~๐�๏ฑ๏ำ๕๋ืใ์™„ุ!bJ‘ีpย+าKอCฉhˆJ�€™‹์๗ๅe˜rฌNEK-๏รMBฏd-Mฟ)ฎ„’วƒร&#๎ฦฦฟ/dm |ัY€|Y€ฏZZฮNฯnBษ.ฅ8ฅ์9ฬห>{ๅ=iศฅฎ๖ดN๕๛]‚"2O9ณ•5็วศsพpฒบป๔;OไAฬ&ฮ‚ฺๆฎwœฺ. 00ะICืฎ„�~c=WYืต๙ X#ไ\๔|›™Jฏw�MM7oค%ž[Š�4ฟ›Ÿงฒ?2!จjŠ_^.ญ�€พูอื 2ภdหาดถ3dอ๓ญœณสด ฑRไ� ย‚ฌ):Sู–ฅญ ศ๏>ืFxตๆษ.ŒนฦFบ๊p=์*?ำฤ๙WณฑFงj*๏oะ’ๆฦๆฆ้g™Rถว\ูu่ด‚๓™„,ต 5b“Žxฏ6ZI‰,L95_?๊™๐3ป†_RloŠยฯ๊ดkq†m2O วย๕;˜ป0‚๏๎9ำw‘klม,๗ฅ๒_๊Y4;›6H -šิ�ไe๋1yถBvธ�ฮ} ›ฏฐnอึหŒq•=่zถ5ตQ฿`%MŽ๒ฌฐX™wY์�=า:šฐ�(๘ห8ฌqณLญA&M์Qž0€ไ “a`ว.OCงœ๑่0gฒ �ฃ๊"๗œ฿X ำผJa1ญเ๔#›E่๏ฮ๋U2วeค ุอc•๓ฤsฐ]็u-w8Kฌตm>#Hๆ๘O`ฺ๋าZ2ุ ๅœษ‘>จƒ‘Sำย5Š ‹�ฆฦ POjklJ Sำœ™ิ\UฯZมp,Y๛ฺ฿๘๗~cป๘ฟxฝG(c–/�๏b~:3๐“S�งsฑ‹ซ�[>๏ผ“�ใ�๔ฟ<ผzท�๘w~[๎�๕๕๛ฺiจ.y�ผouuญˆZบ‘}QิC”ญEq์ko Cงฐyvาา8]ร‰”V็+ขZ8˜2ข‡=Ÿ—–hE`ฏŸม`ž›ŽP� wฃRNKPฐถY27ิšV๎ง?๙?� ญ<#๚CชŽAฦทUผ+pXด0—ว0q–fฆร‘4oฟฤ่ เฤยิT๚่;–f=NๅคY๋รbŸFฬฦๆ—ำ นฟงฬs) “ญ8}^วๅฺ ˜o|ๅลน „*�ๆาNA'^ฦ™(รภqžฮY#สฐu9�ฝ๋]Ž|”๑Œ:nฒ^ย‘g/บgDJงญ@œฎIทใตD–W"ส๘ไั“๔้‡๗ฃฟ๏ตฎJฯBv,ภๅxe ่P์…�ƒ5“�€ท|t–ง Z|ั4  Fจ•็A์9ฏƒ)ฐฅฬ œ˜0ูoสŒฒ(ใiUGย๗ษฑ3„ภF๙>๙ฟฆ�๓ทmเ1zศษ(ฉข่Y=lซˆ[ไJ๖Ug฿Q฿กด‹dynภ cYใ•=^Mดฬฮ(ุ—ศฤv0 Œlก"#h;G‹“š๒ ฑk6ฦ]tึ่่xšž˜แ™dkๅˆ\-ข฿vbฟๅˆtส”ธk๏่ =$8โ>q�้Tธn๊ตnบสไำPhoH„�฿๙wSชฮิ/ฐ(ผžฮ�ใด(ฤ๘-’๎ฯ3จ๋�๏^ำจšฬu‚ฬณ ›Jล~๖t”ฟณ฿ธฎ้�ศฤนEงEฎณาย�์L!ศา…ผpฬ 3€€8^[�ฆž<3?ŸE @ยดH'ียˆ^ฌŒˆ)ƒ{2$ไ–2ํบฉ›}6[ ฮ=€9q‰๕*G๊€~Xwzr*Mง]hะ5t1Xฆ�๔xe(๊~p_4D€ธะไdใฐpH็ล5=ฤ/ฃ%!แฟ! ะญ�ฬเ๘ ดดwดEมผc™…่'฿'sฮ๓หรส๓๒๖ฝ—CWnัMๅ�้–Bm}X;MLŽEd�อ{ฏ…ฮ~6:†cอฌB๎QKค(!Ÿ่‡%ต8ฺ0[Hดš:$ ฐŽฮ5œ฿๒š๒T฿V—:๛a0ภฒjคkIwฒ#X ”q‘�cฎต-,O“๕'โฌbNuœ—HCฬ2†jrฝKธพิuŸ฿T Aษ่๚๕ดŒ- ฑVi อ๕ฉฟฟ'�ผq=�Œm0‰9 รเ™˜ฆ8คญ๛๚๚B–่„ซ-ˆŠ3พฮ™q`�ำ\ššOใcฯIOœ‚นถฮจน?kcqพMl 5ZTัณB9“ฎ๎zนwtJห)๖งmใsZ_รZO๎/"0เหณ/y๖ƒA๗…ภŸS๗YฐขB๖ Q�ฺสHEs ซ<นw ถˆŒ๓™Y๋•งั๑žwPน๐<ณ–ฮจฯ5 ธ๏y=~`ฉv†ฒcซZm!๗œL๗ผเƒ]ƒt˜มjธฯภl๘œ~iปนงถGกD�ŸOeR/ๅ;v ูฐ์๊ฬsฺA@GมzCv#ู@้นX(ช>2]ะ{˜ขก eŠh_Oฺ'ps๘`ฺ้ gภย4ฯ �s s™†fผaSมมฉN“qb*v)ญ่Œ&@oๅศ4Q๋S9/โ–‚ ฺ~ฦšŒeร๏vOฒ�2งlฏ่๙ต‹n•ๅj= k+™า`Z‚ม $๏ํ=ี;€~—� ฝซ๎Q&๖๘ท€mฑญ`qN:nxืร"ใ�ณ}บ �n™/kh9^YณK ำฬ๏nฺฆถร1๓Yyบ—zzšฮ~๑—฿�ปoํฟ�ื_วุผx]ฬภg0ภมg0ฉ�6_๒๋_�๚ษ�ะภg|็wNฟ๑ฟ�‹็ฟ;๐o��เวY(lwจ‚k:j:ฺแะ"ทาจญนp๛าะ5jรY14rL+�š_wDtึƒัร�CVใพตc…ฎณQ=ี4‘ำ]ฆaส๏54vฆ ธm๎ีๅ๗Pkฤัฉฌ3B ๚!QBZ…Žscั*ขฟถลณxT5@#ะ�F๘ห084r<@j`LqPอฮL กๅู& NฉŽหยโl*˜h0ว˜๋mmฎFัฐ"ล๘!ฦถ ฃ�9‘๊โ up>๓ฦ”4ไ<ยœ/ษุp8บ@�e/”1%GRฺa1ฯ\€1Vศมžๅ~ๅะ5ฬกi!ž|…‚D/9|t ขุ๒สˆ•‘ฯR�ฎ!ฦแลcล!f๕ฉm๓Yi#&ปภร�z+ฦฒFLˆถy<›�คํ้”™&ภ‡โpตฺ๓Nำ‘�) ๒�ชฌZ๊ใ:f์:๙œโฬ ‘!ŒŠQiฌ::%Y:ึยสี‡ถฮc.ผ~8l:'8์X QuY๙ะ‰๓ภีฑX[ง=็sNชซc” ๒Z‘,cแ8"ZฒนAk.Œ็ย2ข๖ค�ิ™ฏ&ฏป˜๛M๖ภ:Q6[Jž1฿ฌ‹…โฆ๓ƒOงr7iกft?า\Oไส/Aฐา–ŽNฉฮ็สศGmc#ท�<:ร?t๕๓ิุโฃ:Dส40R˜oลฺู!:MๆŠ?yส�ala0๎kะ"Oางน${9๏hูสTC�นจ@V^น ๋๙ฦธ'ำฑะฐBไซคล# 6๗ฎu/N‘ศไฉ‡t(ๅ`qi…็!ฯ—–ฮ†�)จ*๖’QBd�"ง:gd2ข�ึ €F]Rฬ—์"#Oถ—37ทฏŸ่ธษ‘aฦsฉ๑ˆnฐˆ�ฯX๘e�ณReƒึ๙Ÿ:g] .๛<ƒฎฒตค@™Nญฯc/z3อr0™ิ]ฅฌฉc–Tiึœ‚h�~๙์ำhื u๏œ;�NYะ!ัฑ‹n0|^]mญ ŸีNM่ร% –Egฎ{€c nึ๘ึ!9ฆ.ƒ๋•ลA-"…รZ Kะlืpl5j๚“�ๅ)ฯŸใ3…ฌ‡zอ็ p™ƒ#หษb” b ฯ–( ปฟDTš9g›๋[ไึ๔"ป$œ k›ขUฉŽ$’†ฮณK`ซSภ๚q.xF•0งถฃSุ๏ผ็VB{฿Ns}ิ 0}j‡ดผ๏๋Oยฑญ<๕ŒหณฑL@0‚้skD–€�Gก็๓pภQn OซAAว_}๎‡@ฌุ๑s�ๅˆ&–ElL7(๚ฺkw้ะDลuฮ;ฃ(:‰์XCH&[ภ‡ิz พฎn-qŽ”’ฆาื�ิX์'4ฉ5[ิ ุˆบ<—ˆใ”กXฒœƒถ?ญGฯปึฯ&ฦ™็bอ ๒_›๖N/‰์gณ€cœงk่ŸCฦ_แํ/พŽฮgฌไฝ_ฝ2 Z8Žึึ:็ฮœ๓ฎsl�"ๅส‚Œ‡ฌ—ภŸ{™:ฤึK8ม์€ฆ฿�ูzถ˜}g žH{bํ์,S‘†)L@IDATJย�"๓สภxww[t&ฐฆอ1i%:mOžำRs‡30ณฑ๐—7? ็หn50gแM}so[˜q“๔ฌ-ุ69ภ๖‚3.`นง#ศ�4ฒŽ„๛BQ6SฐBx.4e�. ž)@ก”Mฌท3�‡9@ฟzลโงฎ™mต…ด๊๋หa^ะeก’:8–๛ŒQ›Eึ›gj†๚&O‡วำG^P ถ *1่๗�หtวฃl๛ป=ๆื‚ฐvั9ฦAXXkบ4๑<:งฮฝL>ย�L%5•BPG0‘๋ณMŽxvgPh๙8แ�‚˜n!ญ mŒCฎEgYŸe‡s>ฯ แ �ฯตV…Ÿ"๏ฆค:Ÿ~E๊"๒?o ปล๙๕์5๕๕4ฯฮ๒๑™IŠ .กร*)�^ก+ฒีะึ“ฅ‘่v1ชC๗8ำRญEg<9๛อW ๛rุJส ‚๏ะQ^ํ�ข2ˆP๏พ›ชฅ.uฝeYWงT�๏xฏม^‚HสŠภ„มฯำ�œ์๖ะ�พ<‡|f๋+ูฌ„ณ:RK`) ห�๏ข��i9ซฆ!Ÿ%g›ฉญน๔๙—๙�แWฟ๖W�Qkw/น†ฏ‹๘lfmv๑บ˜�3๐NJ๏�d๋ใ๏�๘ร๛ึํๅถ๏Zcเ ‡U‡C)ส�beeๅ*m#?] ๊8) ไ*QQ้r�ฎ6# ูขo===qุ ิแxฟt๕ 9‰8๖ฏฟ๚FTgšรxงึสYjบ๙๚ี|ถšจ…ัB‹๏Yxศbƒ ภ:e๙ Yผถ8คห˜ ,ู7ฎ�_Fl$ |้{FAฦษX฿Xฅg6ญ˜h=ธFDbำ่๗ฒ6BUe6ขIฯ1(ื—ฬmฯFapa้$itDไ๓฿ˆFj๗ยภจ†}!ะ!่”ฃk‡ผท —[ซ†B`ๅ8ซk+ิZ˜I—๛/“vPŸ~๔ใ๗กQVฆZDYGยg0๒vจsส{›4jYใYฦ[ށฝญ๘๑฿M‡ฌC=Uม&#ุถQ�p!Š~@T์`›่7๓๐๒koฅcๅxŠโš7ซ33PC‰.šต[ย,๎@ˆ5 kh”โ$Rฒฒ๘6ืฃีjDBฐQ1Zซว r๕nภซ…n?๑b,ฦเฯ.p€๋Lไฺ:EๅEe@ฝดB3‚ธ :ช๙#ฃสR9๓ฮ*๛ฬตืPฌ”*G?Tso[ฮLN`ภ[€Š5xภฐT.r#:ฬ›ัB‘๏FบŒUWbฟ�สี๔ๆฝ;้๖ว,rЇ Q…ฝfkSจกศ— ›ra|Dบน~9cํ่์`พ,i=Œ|๕”ัuะ`.aไI๋e๙ย๑8#บ*_ภๅX=้z ~ #Qgฟ�6ซจ่ภเeึผ)MŽQ\๕q8<Q8fR˜`์ฐ ฉ- mcgT‘ W8นeฎFฎulYห2ไu(๚Q=[Œ3d”^—อใ|ๅyŒ^ขo~นŽ~7โ่หจ—๏q]ฯute๋hDv€ม?#�44�ํ}lU่^•JošƒN‰๗P+ห›‘ฒลn‘๏ sฃ>ะŒvพe2 ผฦsฒ6‚ี<ข’}tdu๘บ_Fว†m ‹ฬ*ำMP�หฒpŽIฝR(kฒภ�Ygว‰3•E�3J๖–๔๚h ˆ�ุ๚Rฺy฿•ซั:๎“๏3ฟTzฏK?}€# ฦ8•ูcๆPงA'ำ5pฯYา  ว<—t๊ฌ์o๋766 บผ&>(f;;ิิUฆ;woยhขcŒภฉ5‚�ถ Uไpฅƒ๛œฯ3๚ซsคผ๖^๊qหp&P๘‘๏ถ๖s™†g=Ÿ๙๕7_‹H�ฮ๒๔�lZ”ฤ้r�5oหย๖๊’๑pนผ‡ูpmจGผ’๋ัgฝk๗–พพœ๔ํจยฟลตท`�Tภ˜3x`wžึอฮ๑ต��\ฎ”Oe#q๔ƒmt�Hม2  hnZƒQ๋ต-˜sคภœฒ^:ฦๅ่‹๓ข†ๅะฦ+—•EAห"C™eซคh”Rืd›\๗@ฆcRIึก๚[…_๙ท%iD๔9w}^eวR‚ฮษแ”บ {ฅwMดG”5`บ˜{ƒž->ง๏1*ํR+‡>‡}Y.…้สะ`tว)แน_็i2๎s[S๎ฃ^ŒNกG ๐ป ๛Œเž „�- ูตม‹ฟ๗F�l ๛9ˆƒ๒ฏ๎8฿ใ๊๗‚๒€?ซ›ฃFB่๗ฉ)ลฌท cfŸส*se๑™^f' m akืธฏิDฺ\Žว๛TL!uศ|ปฎ‚/]ค�ดWฃ0ห๙Z�ŽG"ฐ˜8ซvถา26ไ&@รยโ*€<๚นี๖q8๗™/™Jฎำ! R ห5๐™�ฝ Y~k”ทYฌั#‹Rะำ=„�๒ฌmคBzํึ€aพH˜๗dพ b;(ฮฟ]Qดuคๅ>๊>Y+2ิuพ|฿!๗(็}`seI€2l!nz„๗{ฮษช๕Lดj�nkฎL7๏�๚฿~๑ฏ�ฃฟ�ๅ4ˆIฝ๘ฟฯl.€ƒฯljพ.�[ฟ๓/๗~๗Ÿ�“วฯž}tวณ�ˆข†ฏญœยA็ะ/ฦQฐฐ‹�ยTไ"ยฒฌ�ฆ:จ`Uฺ8แF”sD๒ส)ผิAมด7ฎฆ�พิy0}Lล๗�?%b;ีŠธศp(ืh๔ SŸshh\้Xฐๅœˆฎ‡‰ŠX#รƒ3ฺก„๙•œกa 5_Vย่ศ *ื>ล1ƒŠŒ!oŸๆU ชpึpˆิใ่ht๕tใภ�M=ฝ}Mk๕�า/|รใNบิำAณ'ตa€ฑ฿�ภกก(TŽผฮrฃ=ิvˆ5ิใค‘3{˜P€gD*—ใgค-Xqr2?:ํ�๓{”ZOซ™  ฤกษกจ1mNฅัslฮฑญ=$‰NฯฬฬF1ฃTCZ —p›(AFgฃ5�T‹ฦ]ตHa)จbธู�ฝ”ื)ศ๕kWำ�7{* !.3‡Dมงฦ1ึ่‘Žฑoˆ<�Tภ(Oน�Œˆ9ั7ๆ๐�ฉ #+ž `ƒ฿k\้8eqศbhT„๓กใ‡รd0\ฃูยR=Tี–�X ะS[�zบ๛ย8]งูฅฎ~ เบ0\>}๐(อS‰พ˜ผy n�ๅq๘�๎ำถF,•ง=ๆฌP@ฆ Cฉ#ฺโJ�F6๗จ �Aวƒ:jXฟ@ะKน-รจฯ`�m‘aํฑ‰Y๒Dง#j`�Wฎว\๋Lพ๒๊kแ@�บvฝ…๑aฐ.ฏฆ฿๙เ F“ฯj นCdtwฦ k\ŽมU3fมง3"2ซPw๙œ์iโgF5q4‹#ๅร‡่ลฬข`,Y3F๕mGj$๐P:5๋ †๒p�๖๕ˆ,ทฐถถb•9เžาะดf‹y�ศ‡Žb–Zg8D[+Kažขo‚อ‚j๔�[E่5[ :o:U8๓„๋า<เฮุ๓gฑ๏ชหZ ณ…ล%ญณกžR'™Wฮ�ร)`พค Kอื่๕๙e๛ุฒPวฺ�"ุe[3ฃm™ ป๋ฌ ŠๆS ิ{Žล—ฮ›ถrเ—/ฟปีล~ๅฉไ๊!dD#Z…6น์่`ภ~P'น๊๊น7๛U`ฦ๋yค$Lๅ๚บฆญซsฑบ 3„็๒%Xเ==7œ๏๘โ๗วำˆฯย�่tiio˜#=‡๖คAฉV฿sฮ๘๒^ถฒ“i @ (˜4ิ่vm|น็fอ•๏๎ฟฝ–…U/;รั(cfz=Oต~๖คํM%ซ`o<ๆœg8/สƒฌ: `:Iั=็r.uถ\ˆZy QาbูStŠ`Œ๛BL#.ๅg6Cไพฅญ!ตv41Wๅirb, ฟxŽžฐๆ]๋คIzX@ ึศง๓>teˆฎz~hพ๙๒ภ๎oDaŠศท้8Wo�mbv.Rพœ'ๅใ๎›<Iบ~ฟ}๋{ขG|ภซ6€�*jซX<ฮฺ?€ณ่‰K�]8}ึ’)M>AŽIŸCํ๘Œุฆัธถงไซ‡NGฯฐผ๒ั็]t\6ลา๘hคฺศ ”�กNหึท Ys'’�ห๏์๐syฐ9G็จxž j™‚ุL|cC+gร๗จxlึ;ฦุ๋ป�:พพdัธ7ฌ„/ ๅบ .zŽชŸฌไ๕๙u|Nก4P^„‹d๖๙<็Nซ�’๎/i4฿ฝ,๋@jบ;\฿1 €์˜ถ˜ฃณิ๊‘u˜ŠUœฉ2zฬ•4'^#‡�gส๚บlฟCRศๆฤI@O >š๖้9๏5M้ูใ>๔๏2งดฝlQhชถ#โูq๒ญ€#ฏƒoม็sฐ6"แœ Qป{#@๖•gฒ์!๕ฟvŸล9 €„๛[LุŸcอทcr_ๅcฆZhŠMbJ‰”~�ฮ๑&ฯโsฎ Ic]”#;ฏฌQ�ฒฅ๋Rณcำ์l๗๗๗‰ฌฏเ^๐ef—จ}่6ๆ?฿ๅ ๗“๚u*โ}ุศผ:DpAฐ4t†จƒM๕@-ยึa�8Bํ0Fืฺู6ฺถ๊ๅIต–ลn๐)$aท†ข#�ปฒใK@มkyo?ใyฃญlชญ๓'่็ ด‹�›vช)็ฝ™ข}ฺŽ6:”ึoฎ}4�ว๖รIุภy%Wพ๘ฟ‹๘้ฮป๐โu1?๘ฦ?�ว�๋ฟhy๘เ“…žึูฦด†›‡ฎ— Q4ุBMจ*t•ฆjSล|Œฃa๊๏5$j 8GŽiuM�๚ข“•ษu†'ggpj pqษ7ตธN N[9‡[)‡t๔l็๏:'ฅึ3ูเaข’ึ9๒€ัa7๒ซCชม$๚๋!j4ฬฑษ–0oUๆ„ˆฒฦๅพฦ๏อ;…ฉ“สวw_น—zษํŒjุ:ญญดภ��ยษ)†Š�BDšขl๛Œ฿ข<ต8>ต8ไูJ(‰ฐ(ฌศ�าาลk`_ฌฬ<'ฺ9Ÿ)รQ_™อ+ิ๘ิ -ข?ผ‡์‘ุK€)•Z&ำˆจฯๆมc๔Tc#oดใ3vฉ�ปPL1} ค’ sฬt�dŽถโฐิ้.งยtE]y๊ป:๎พ๚2yซ]้ฦํkฯu\[Mื1L๛Jค๓ ๔Eชb]uH4ิ#ฉ' ๋nmKไLa๐7b๘๋เอฑ~eY|ึN Dโ‹ฏ dร|B;n{ฉF,5ZฌญPส—uvฬ1‡ัะึึ๙’kD๑็ Nฯ Œเxuฒสดฅ-๊TL[L�Rส(‘a13๏ซ!a”ำ่ ๋๏�•kฐqศ๋y‚kผuvต“ง�@LOW'ฬ’่ฒ]ั7�h๋1Fุ8กแแ1h�ดC~ฬ๙o$:'ฐ519}ซ;/uG#ซ3s€:Lฯ฿/ํ@ูดศก๙ๅLA€/;ฐkN0ฎjpค+ก๎Kฏ,&R™กโ๚1€ .ม�จa,[ปkฉ‘–ามGž?IKฆžP�|g�ฺ8n๋ฎ1k„,o\]:ย•™ขcๅ^ิ์๊์DNณhc€Wด๚bO Lธถ~ึ9 รน/€mdAฮr๖?œ๊Œ˜^qฬ:ฬะยอ” !ึาˆช6“๖๓ํ๚ื ~iุ ๘ฝ‚น”6ผ‘(hge~ GJปีˆ:`Ocฮลu0ทุ[,ัฮ4-qผสkาำฉ%2‹pผyGGฬZถ’”e Pคกk:‰๛น€ส4]าฆบ.uฤm:ู_�ฑn`|K!-eร˜�ชฃฌ…+ ธ”k Nสj๒ฅ๎ ะ^ๅe<‡์็s๊๛‹งถ‚{Nบ%ฦ€S‰L™•ยkดมB๖่๒€<่z็ศ�p†ณne๕ผำ‚SŠ๎rญฬ��ห๕@GY;กŠ\~ื๘|o้ณ ึ0พ4เ๏ฃ�็ฏpจ}ม#ฃ…๎ �ฎ๎\ชwอG'Šต”Mฅณ!Pเ{uบิFhีญ^ฺฑํcผ�–. ƒE™acง๕ๅž‹9 |ฃŸ๊n฿ใž์sXน๗wœhใจ™:†˜วตึXง๑๑Q€๋กt็ึ]ไs#}๏ฯพE)?๊UYœvuไ๐ge*€ ž฿3ฮ:6ึญฐฎˆฌ—Z๊›)ชiม6ึ™ี…อฅท5ชณัL[พW_๐ญ‡ึ€0๋ฯH_ณŽPŽ6นFi๕fผ_žœ ะป'Y๋tำต›Waฆqฮขฟ ˜าิ>u�๓แ'ivVo_€ žส$]i‰uQWทตQ„š๗Ÿฑก--"<;กวอ3E๙ฑž†์" ืฤ<๎ภJ_ ส(/,ฃ\f�›�่: j)›jY"gQสื>๗YูXมIฃ๐/`„ญํuu ฃ8ฯีจา@แึ-ึฒ ะ�h— 45rJ=๖ญN›๒ฅ,หฮS‡9o‚ภฺ:ˆฆำน�…ะฟ;L]๑p\ขฎWL}‘กก k{hŸhหจCdwTยไ0Rฌ ฯๅ฿”e>‹J†ƒ ฃ์—ฑต)๖ิ/��ืc/5ร๒2Xr@Zิ!ภ gž๓ฌษ�iฅ k2&bบ‡zอ€์‘R‡c.cภ๎"v0QVdศ๔2=า๙1ยmJbคQpo>c“}fGื(l"ไEZf๕]�^{฿tึฤฝฮฌลพสณ๔Lƒโr��'{ฮ=yt@ซiไม3\@38฿๙๔U?:†y,ไ�6[ศˆํ็—ัแœoฆfีฎgชา:ฒ–c__๙e€ฤภ ๋I1่A]_ัIŽ๙v.|ู ๙5ฯ>ฆ“๘Rึhd๚ สฃzUpอu1ขžฑท�jœk;eisลxO‰บ‹ตpฮ\cฯ็า็–9โณ ณ�ŒA-n€‹๗–e๋Y*ธ)ฅ Bภร฿[�Xซ * ฆ@diYGืŽ7_zๅคใR฿š�ชŸ�ฟ๓๒Ov๑3๐ำNฏ‹ืล �ดfเ๔๗๓Ÿฎ์n-ฬNŒŒผšก้๑ ดJฃ�๔๑pฬ*0LV ธhฮp€Pภ�งRฌฤภฏ"wั>ส๕ตAฏ!ื/ƒฎ!VAดkE็��๊W/ำ@ฆ(ฎQB[˜ลaOร{yhจศ5}i e๔P๓p๗%๘เม˜ใP๔ะ0งฬ๋็8ค<เ 0ชt:lณคณ{๓๖- บKq ่HSอ]Z๋ฮ~†รชjด้"าฉท ฮ_๊์N๛ฉฦPช…ฒูHTคญํRะFฝ‡”รJ{Y“Cฺึู–n�}5’ฅ้EZโAY็ฐา๐(#z_ฃต Sม~ำV4ะ8๑ ๓ะ๒ภ C๖‚Qฉ้ฆX�ึ–๕ัj0โ)อ_วผZ‡เฆ„œ�r๒|ซ(าtฉง3 �…๕œะ…ิลsu๐|ํPั-บฅ/(ใฃŠHงL‘fŒหพŒsฦŠะูัN5ํฉ๔เัง8๔3ัOน*ผลŽ4^4<๓(\„qงใ๙แF๏xษ 1Uม๕ษ?%ะ†)ฐˆŒet๊/แ„›๖ ›aƒ/้ะ,yฺซ๔ิM#ฃcพ ๛–๒…นFซฒกเ�่hภu‹9่5(”!ซi;�๊:€Ÿฺ2žำโœ[ะ๒[‰p๛ ‹ K้��้๙ณ8I*ิ4ั€{ม๘VC๎z๛R้5ปท๏�ษŸฆ•#‚ฺ "3 ’#gืฏ} จ- ๕c(ทXเศฉ 9ฺœ– ำศV๒x�ๆํ๔ส›oQะm$ต"c%T†�ษƒtคณ^„ccMๆ‘ฐfyงฟ C฿อyฉศ‚2ฃŒi๘‘‹(6�žš gIjฌ9�ง  h0๛]0_ รŽ*„MSEช‹-ฮdX�|�= H‚ํaเ)/�ไ�ฤEแx'*f„O‘w์๓จ€ฎฃcฤาuฑHฒ=7=๗=pอtๆ,ช1žนg 5BŒLE•๔ ๆGณyึ0”Qaa.. ี]B๓โ๗‰๚[ฅ€bnvdBxk:๊,T_œi#<Ÿฒ€ใร\X_Aู4’จมŒขŠ}ZŠ�tjฐVโฤ อแ(฿สeD๕\฿ใšX—D๐R o%{ษ฿ซŸ”ฝ {Eวื4)D๗ญŽ๚๙�cjใบ:๑ป่\ฉิั9ƒUงษH, ื\=ฑEt—ม่ฟว็\Kืาฌ^นw"sณแ ๑V๔#ฯฬ> j-r๎žuoิYิ`Vง๚\‚tแฤ;ฆฏฬ"d๐์X‡šฑณ–ฆ์ใPHี็Š�็ฝ|ๅ฿”ކT‚ ]อิnReพ“บ ห8t๊๔ฎ๎žะม2œู)็�œรi๘ตV‹/e( ๖ุฬ๓jฑQ็ู๗ โ8�<๐ƒสุ2”ตR_ค�;๖G�'๕็Šu:@ๆqFธžแ€๒ๅ๕๘ฏ<ยrqฆ‘“cะ‰bœ kูTq� ๆ˜OžbCฆP–=žท๏�nIฃ/&าป?x๙ฅK‡ป>—/^QQ;eA=์8vhqห˜lฅjบ›๕;ู๊Oึดษฐ็w9ใฌ=Qฦ>ZGทLม>ณ.@gฎ,๎)๊-ญ.8ฎค‡ฆ๎V˜]มtุทLƒาFฒ์)๗ฅ…Me=ิณ็)vhคWpเ€๑x๖›๎wฆˆอ‚ฬฐW ๘%pa*Ÿ:H*๘)็o! ฏ๙ใ›8๏๎๛rR็R)็ {—&P(‰5ภ‚YXซ€<ณำ“้ษณ็œ€ อ์อb�พฒU‹VK:ร žภ–p ส—เ‚ฉ1๎า๗ฌ๘oฐมsม}๊3ZŸ)ฦอ์}ฝจตค�๋�E+h๗?r๏๚ "๚~๕‚`‰6J ฯฟ…ฮฝฉ�q]™n\l"ศะึ�œ๎ุ@-HSl=ธส�u(ฒ.ฦฦgaณอะ๛ƒ{&šช่�Tg(ฯ๊`m ;&8๕ญฯ*hk฿{ธ—d/ไกํเ�L–] }แœx๋ศpŒ}ฮ๘•รฌ๚ นืถsป‚@T฿‚ำ=ผฮถ gน:ุ๙ตฮ`2เ๚ห.‰}ศž?AฑZจตซะ›ƒณz†ิปไผฆก>RM็ฎ"'๊ ํ#ืJe LA$uSซอ=ฌSฯผณF2<๗\a Z๚Ÿู๙ำ\p|!�๑งŸวบพŽ[€7บNp�œŸ��/K  @Oเภ9=ฏก œฉ+Mgธ’๒—sฤ๛์X%จ!€a@ฦฑ*?Eศ}†๎mฆ!’�RY๓็�ษ๖_�๗••M"นx]ฬภg7ภมg7ท?—W–"๕{๐งฯ๗—ฦจv}ZdS1ฺนืBŠ�~Œ’5 vู8o*uoi]F๏,"ุDTจฟฟš1ัz฿��hฝ—G‰Qไ๐D#<6฿บvšMš ๏ี�ฏ9Z'zˆzู�์KใุรภƒIร<ฯD๐ ฯSัย๛!‚jคK4ฺ1v๏ีB•๔kืฏง^จ๑9"๋+::0jl‹…‘ฤมีA๊F"๖‚฿>ท<;ฮ0ŒJ9(‡ฤกLJœ ้ษนฝ๕ิวตช`dก6ตำ% ญ=� ฒuB-€~๋ปฉ˜โu5ฬOกNs&€PLสภ €bœg ๎๎แpm#ขะOIu8ยฑ)ใp1ชn๋@�ถแxะq$ฒเ ฝ2ขS€QT=ถณป=]ฝq…จz/ัfz”oะ๋{<่๒/CซฏดpMสIa๎mU| QืMเว"[บjoฅ•ั›ŒOiจ:ษ=—xvฺ„q@Gป"ยP˜๙&ฑD‚"ู,•– จํแ| 1ฒqฦšฺZŽg๎ภกว8…ปlีจั๕๐ั}้3า'nqจ2_3#/&น>‘่๚1ำ`ฐbณEฎŒ( ~๗eDEฃม\mฃ“Vร๗หจK1k#=อญน1ฟบHž+•ว1Tญ?เ๕vษ{}๏ฝ๗กก/Cใm‚…ะm˜2tปดฦ๋๊ํI=ฝ๔ฃ^^&rNT Cไi7๓cD๓q‚ต หpNlSจฑS‚Aณถ4™ฑฑNฦ‹Š4ึ•ฺ๚สิูZ€“ฅuโUX๕8ๅิvXบบ’ž?™ย&"…ณปOtฉฃ[ง๓‰ืรร4KD1ท(‚h๔๐Š็ฐ“”ํF€ฃตV–7ebmqส/ ฉ ฦา ฮXุใ‘ƒัW@šBฟ+ๅนtฐณศZI9 i":ฑ๊‚"j=”ฌ้ศ ๘2๕ภย_`ฮA=Fขิ฿อUฦF”_+€ ๗#NNF…00�ร๊bึญ†WA๑<ขป|๒ˆ:์ภปึศŠ๔:นkTขึธV�0q1ROำ•ห�€sPูฏFwwซญ๏์0เ=๖(Šj4ฒs—wnNqr�/2JŽt�#ภึR„`LvญะšVฯยฌ*วษ*ม9,gm๔?dF!_D›ee•เ8–ฑิ>{`ž๚JPำ์ุp xžˆhsu ฿††ฆ 4z5œท—Œ43:NPG…=f‹ล]ฎiAฮ_�๕_�lID–ืpฦฝf baTํญ_๚…Tำา*pbฎฝ|;]์cํqv�ฃๅ‚d็ฦ๔)^๒!n+ใฬ;เ, cG7๓๋"๖ž5F”i๗พN…z�ผฑ๘›ฒ ƒศ็$,ใšuฬU฿ญ›ัŠำ๚ _�+ฑ�ณ่ำ~)บr]ŽV์ณ�> z"83'Aใ]ว@=•ฑๆ๎}วmR#ษึ1ย๎เิณีฒฃs1ŸฑฃL-,[ภ๊�/อฮsœ-๔‰sญ3fฺ…ฒiำ)๋แ=อM7=E6สŸS0Oฆั™ฒท‡ซ" ว๚ูลI.*ลฉYจ@ๆฺ;ฺSŒ6sวŸ}�8MAO0„๑:ึ&XvQtษV๖,ๆfD�…ดเct(ฐq LˆtU†€๎5Rิ/สeaTxXX:ุY7้ๅ{ฏฐš%้ )Jk€ๆ��zSฐwzrf†นˆ(/$์ๆฬจยฉฏข˜โ6็ะุิ8๕่xะ�อน^ฐy}ร*!ท‡FตzNะ#ๅU€I๎ฎ๙เ,PNtFZ gวเaVa็B6฿�ษ~ิŸฐละ•^t฿PS •รฑYƒยดฉM‡ฬซN๐>{_V„lƒpะยe Aัi‘ๅ&…฿t“จQก�ค๎Dณลy.ฤˆ�๓�V๋็ˆ ู2zฎ|หDะYP’นECP gฝ 8ๅ—E๏ =ฟqvฝW†3จ‚ มiAพๆG6€ฌ8๗ฌiฅศลไิi3t˜^ŸPaฒวฌ{ไ๚˜baW(ํt[ หฌ)ไ฿ฮL๏“ภ็ำh�๊SŸยณQษ}ล๙œฟ3วฺ็L# จa}|}ฅ”o—Œlุ๛€นŽ&• ม$๏iWฃuฦWOŠIm บŠ"ƒ€2์ณŠ*ž_ ฤิ๓๗ๆVฮvlฉ.‚ฺ:ถญถฃ‘Œฑ&ึฤOล€ู�[‡i}FkgAf๔|๊@(g�1็{NF* ƒ~f~tฦ™ณ`}P;ร`“:ะ”MืPภ3๊ยธyฯxม9Aๆ๖qLฟ9L!๔พ^วu๗หgU฿x.บฮ�’๛์At‚ฒช^฿$…ฦ�๏CQzฦ œ; ึ�ผฺeœnๅๆ” ล‘ต•Z›ฉ1RE]�๎v^�็ณSŸ�๓๕ฏ�ษ฿$๎t๑3๐ำŸ เเง?ง?๗W<8��?�ึ‹…นั๗i7v”บMCA%]F=i๒*d๓”5�ฬฤ„โpeๆ๐ศG}9ฌq,Œ ทuัIช%ย›ๅ๓{8‚FŽGธ”ฝFŒP๎-V � "๏:E2r์K!�ขŽม%uฯตNฅFjฺ(๒@ๆQ๘าฦtBํf|ธFช<@5 ฬ;?ใ�#รรไuฎ…ƒœ%ฑžšG$9 ึeq jQ๊๕<็1Œฝœ5ึŒryบ†กYŽ�)Lxฑฉ๊�ะ๕ก๔๒+๗h�ท†ี�ไี9ค(ฐwส<๘ยแ`‡>‡1ee๎2๒สEัฅศ๑โŒรQŠs4Qฮ%๎)๕<ฯจเผ งอuูa�๖Hใ8รแ;%ฺึH[รžžtฉฟ „ฺ|v‡Wฃิฺ่)ิXsุmk…ํ๚-8B[*�ณฐ“y KชF1ง€†ฆ๗ฎa,พด&ƒี๑MัAlˆ‘‹wM/_‹กฑžœtฬVe$๘มัภ *@I}ฏงฬH/gกˆ ‘ั>33ล๚ๆ0จ)ส‡‘126ŠAƒแCถŽƒ H”?€ql™ร0๐0เ ŒT("๚:Fส‡†ƒ70ฒcD=จ];,|ู|jผ”‘{lU๙rๆx ๙ณ๕_yฆ*�พ} ซŽศื3Œ?Zโˆ๗_ปนน9Œ๚"ฐฯ>ผŸž�q:ฺฺฆkHs…c็9แ๛๒ วaZeUฺenz:RGwkj&บ�๒K/ม�hลูฉขลโ^๚ถรว=˜‘๎L�6ฮ//‹ธํ"…ศฬ’ัgs…q ๋๊f๛˜ณอไ 'FXศลI”eใ^แ-์U่๙G8šฑ‡5n๘�2Yภv(ย_ึ!_ค@a9ิtl�ศK5งิโ’งฎญsญqญ์ธ7�ฌฮฅ”๚p๎yŸŽ:ฤ๑i�i‡ฃหุฅ`k(!๗๕Iปฬ๕2Nั"yภ[%ศF €Iเ’2dฤฟ่ซ2d„-ขSฬั@†jcjƒ&�น7�Lทฏ฿Žgพv๕\nงgO†1์จk@A8 !jlห’8ลy,ภะ-eณ๕?ธ+f\v�ะ€Œ|Uฦฒฦ็ข FชNๆ2`N ›็ะuท๐Uะอkไ็ฃKF๖ก๋*‹nก‹7>ภ<ๅ žสึ‘9ไKงลตu~งฃ)Vw_ป—�๊ฏ�:เy/_N/แ6uuD๑W้ณXๆ=}Qฤ7:ฝ๕ฦ[€` มคYค6ˆล๕O8�฿Ÿ5‚�;:+�œ�wะั)๒฿Fอt`ี2ƒŒFšoŽg€ฎฝ๋ฏฎuฬฑพq๛%žc=ต เ|e๋ฦmtาUึฅช�๓็ร1‡^ณพกน@^xn‹ˆ– S”/€.‘ Xdไใ�๙bj๒2ลXWP่ัKฮญ;ทศว ะUบ8?™ึ–ฉ}ภุ์†ณBD=วzหะ๑0J,€iD�ฏ_หธ��>Nภ zฯ๛ฤ}ูKว่๏tช Dก๚G= ฑ P[ ่๖ส็฿’Bฬก'|B4œ”+d฿k่ลฯ�W <ข๚:1ฌ‡ฌs!@o”r~f6ฝx๒<H�฿;๛OyeาัZไc6t๛ฅœ3ไYkฌoŒ.0ึvio&%ย} Bn#‹ฌ%.Xบu�F0ส’\ทbๆ_Padd Cgบ:t5๔†ฬฉึณำ qDYoมn/ฮ•i<-fฬฆ<ก:1"ใ์ปEฑD�o—%k๐\LŸ๋๓‘๎ถ๋n๔ฎ`ำ๑�[่Sฉ�ž[๛ถT”e„Kฯsพrอul๕™2๋W8|ศž็พc‰(4๋'ภฉ�‘ๅู`ษ๘^e^;ย�ุ๛‚hฌq>Šฏ/์~ฯ3�ภพฮฑc—มฤ s’‚–ผo[็Ÿณ�๑ีมฌ๔\;b ๒G›>ไf~~�ภ็Lี™ขH ์F๖ฌrเ=ดIt6ฤ`y˜ฅC๊>ๅ Š'k0ภผ œ๘œ๊P_F�C?1๗ู๊ะY|@ขŽฟi]ฒx‚Bฯ๛๓เฌ6Žษ‚”๊ๆdSเย—ฉA9ไ�ฝ_…}โ\;'2~ิO„๖šฺ‚พGYด+A um�[eœฟw๎�ฆKว@ฌMฎฟFํ(k*W“Bทห:LŒOฆ%ภ`€H‘ัŽ๐~ -07ั�แuVœํ@ํมq๋(๘;๕ร์� ฌœƒ`�p‰ฐKผr”Ÿ'ภ%ฎ๏น#ฃม Œ๓้s ๘ฟธRง ˜ฦโ|ห>ฐฐฎ๓,{ซ‚๛๚9ฯ�gŒgค5ิ…ž%พN 2จฒฐpGs6Eฅ๙&ั๐฿�ฅ฿๘ตฏ.ฤ/�๏b>รธ>รษ�yพ4เมูฝื�b�—พx๚๑๚๚J?jณงœžeFŠˆTกฌํ?o…ฃป•9˜2WWฅฎใvฉท= ^ฆิโ‡hไแฉ.า“ูพ๊๕–ธŠรน†ฃžัฺ๊2ดโUŒคฎ‹ฝวA์แแแ„^ๆๅมฟพ�า1T๑kthิ๚7ฟ4ฤ5U�8ๆง•”JWใะแภำ่4œฺปง๗ยqy C�๊ะPฺ�Z†AP”†ฎQ4–S‚๛lะJo&ขะต ฤ[ฐ%n�๛\บ๙ๆ/ง hg๋หsฺซ8�il”�g]สฒ๊&ช@C_ว‰5า่o%ฦƒ†‚yณ:AลX:๒V�5/�็ฐ˜†ฌนบ:�:g>“…)!�ฌ!@‰}Œq[F6DฑGซo@a~6๚"=ถธ'9œsDo 6‰<.-Rแ'ฝ’ยyถ|4๏w›x�Xูฦnื(ฦภฮฦ!t๛.ฌ‚Tƒใ�๊ฏฅJŒเGาš๐I8aF.N™รbฐ๒L5)�FNLง]โกj๕uํ ถ‡mkรhหbl—แtฯฮอEQฌZ๙™้I่ดียX่ะVŒ์Iฑ7wฺ\ฤศงฤ1"็�…๑ภฺzฃzตv„ฐๅž'ู-K<“QฒnV�ฦSก )] จไm๛ฑB ฯ/ศ^Š๋v๖tฅ"yซ€MอMi 9]M ค2`ฎF ŽQา่†ม1๗�YZโyฒู6Z“uแœฒnt็ศ6^47คv˜8W/ใ์๒]ƒโ๑ใ'izqึ”ดลฃmbฉ 9๖€เk_AšลNณั ฉฏa(a�dฝซm๏t>ŒI๏�dŸโ(ฏฑ–�๎•ื_gO0 ฮx�3šฤžฮทZc˜;‹biฆฏาž๔€fg�š-•พuฎYKj:มๅZYิ้h&๕E€๋*œ"sธcฒ^:�สต๙นY‹ฒท•ฏข6Rp๕ฅ2๏ZํณฮฐN0พข๒9ิ้&(ฎFzjIฝ้๋๋…๎�Iบi 9าฉชyˆดvต‡ฌMNL„“{�ใำ๗พ๗}๊UŒC'ุภa/ษพ} ใP ศ๑€๔ k]†zM;Zc�ฌษ@*ว๐•epธe งภŸี๚๙hิ}p"d�๑ด3€ฦธNŠE?#2ล5๘|้P๏Rjฐ๎ณฯ5N5Jฃุฌฑ5ZŒช—b`ื.�๚_๛k้ตฯฝ…�ฝเgา_|๏ป่คลt�๒•X“E˜0็ฟiHฒผ๎�ปหซบJง�๋™jSŽ>)A�lลx ๛�6๓ใ†cร฿ฉ“ƒหฌ bi5ฏงžซ—ำ_๙2 ฅ^@๑๔ไ�Ctl�มv~t8�?;่eA )žฟ `ธ{œฏ์#�.ปGkฤ’"ฎ�ป†๖œ‚'ุ่R@ฅ๚|โำGiฝ_ �ยฎ๛œFš+y๕yT8XF^W)สุŒฮศ"ฟ ห‹ฉ›<›ศ๗ๆ�B์ฆตQjv–bฦขฟ@ฒg™๓ฉgt?ฐภV€\่\ซ์แ๗–้0ฒ>๒ฉŒฐ˜3๗•rฃฌAอ_\YENd†@1Fำt@นX8๏สดคตw�B=J:ๆ�w„1M๔ฑmcตwt*kxt0-rz ฃŠ๙w,:ๅOฌ๛ฒอูบK= Kปˆ0<ภŠŠ2Gง<‡็†ัjลหด*๛"�&�ลฺ(รุี†ๅ@cP ”);ๅŸ�๙ฯ๏A�†i็—฿็>ฌˆฝฯรฝWฮๆิอผ=˜5q–๓~1��ณึ=ง-ๅพsฬ{ ๖˜ใ+&Šฟ'S P ฑตภQ kท�q"t›k"ˆo*ŒฌAT-kฝE€`Vีnุ๎฿ใYๆ๚Uรv๑\W_ ๛ L|์ S/ฌ%$xะ ณาŸีŒูN!ก#ธง๋,Sรy๕๙<ŸI�๗�ย:ึ1ˆฝษ๕p�นา3™๐œ0�R]` ฿ฃฆgงม,ืJc๗ฏ8Cœฦ๏5œ/‹ Ÿ๏3.ฉœ๗-M5ฉตฝ –Zqบ๖๕�o�‡ฟgะฮก]ผ.fเณœิูล๋b>›๘ฮw�9๛���ๆz๛›�t�ลpั้๑๎+ิE…ำฒณcวที๖�ŸŠ๛ถnย่Eํมมช‡&่;ัูษู)5slQโ8eP๋0วว'ขฝž-z>�ไchงๆฝขคQโาบ,ะewiร'ๆ”กCA h,ๆS8”4�9 d๘สhไs๒{ �4ูaTขิฉเฮaัŒ™J"๏]ํT”&็ฌฑกŠฏบดHรZ"ิีFรq๖อรถาzค p๐yุL>�4ญฯMนšcN,žธ?๙! šา่๘Sชะƒ‚ั๏ ทฯฉŽ0redHํห09Œ zฃKฮiŽŒ0๏้แf๑%-ŸMใV#]'่๘€๗0ŒฑาไVl๓ม…3œ_Aๅ๙ๅˆฌฌาๆIฃษ่/†‰&ูกใ8๕๖๔ะVํฅ`\ิhL`D=}๏ว้งHฃF*ฒt๕#ขว|v›จๆ.cฒนิ�๊‚”-�'2™pšpฎ ๖3o™c� Dฯพ๙ํoง‘qฺO๎ำ๕#๓P็VC+ƒ”`าqาฑ๊i฿๗ฌLึฅก‘.ศ…Nซ‚kWNไ๐ˆ(‹{.‹| ]ฟ๓ผAแB�๖๎.า00f™#e๋G�\]#jXŽฌัQœ‡#zoo3_8ห6๎7�Zjธ*K|˜ฉง Eุd่˜ษxุe]d้u<–2ฬ็�ฎๅืk'AgEc–‰b฿รเ’@#<ืxseXOู.ถ์4eช พเทpผwq‚dPฌ :$#ฃรด`มHญLฃ์%Aœ*ๆLyิ9lรxkคึว๚โ|:3๒„Œ8ว๛ึ฿`>ƒข‹n(Bf23๛€‡em่"ญ<๓ฅu„K๙›QU๗ค้#ป์9sฟ™@ƒ๓4š|ฝ๔ฮฏsว๏สšrdJƒ`๛]ฝฑ‹sึฺั‘พ๚k�Nฺ„ฯ"…Q๚ษ?L+3ค&uฅO>�”ฝ�“Z ฬ๕kC้: (i๚‚ต8งK€ }๘q|Vฃึ{บW�Yภเ�฿:ํ~๙ณฟุ่ำั๐๗Qฉ�5FNท™/Sฐผแ์ตhIฦœใฅP Žฝvโ‚Aแ@�=7?,#?#ญ{๔ด๕ต•ฅญญsคฃ‡,ษJ9/‘yt’บรq[|ี1T คB+W:~28๖‰ใฤฦ=™[ำL[ฒภใ>๕Fxไž๑ ˜€X๕ฎŽ•๕qZก›+๓[ฺ2rŒะKต4p�•มฑ:ภป๋C�ฉช˜5'๊�ฦ�oงก�ทาฤฬd{2œถืBถ]O็ล่คญ_!3ศš@‚ ŽXw†Rมน€ฃฤ‡<งJาŽqN&GGา&๛x}–๙"Wพyสา4รตท˜ฟ]€ศZ๖ŠฬถKศM†5ฐฯ:ภจIVds ฦผ™โ๐เัใ๔tx„=y(5๘ฬy†“mฤ๛ฯRไn0…=ษ^#ษ๚%žFฯMo“กž-‚zvcง˜SŠฑหฬ8  ฮน{ฯ"ปฒ5sฯa๖้@AGgg8~m8๛[2!่Uฤ�ตๆ?ป ฤ้ฤูMๆ�แบ+ซคU–}น๏t]OŽ-@JำผJนฆเk™P�ณŒ฿4Dป:•ฑwŒ {ฦส3๐`ฝง*ึXนื‘/เ�ฑWนถL]FŸญ=a Rvwต“ฬ4่็aS}�๐ฃ42ตŒ<N€`ฦ<ฑพึ!P6ฬำ—๑็s–q?ม๏cXะIB –ไม=ฉ๘ค‰0Nƒ(ฒ๑ดW,ฦฯ่๐๚7SHฅ๒ Ž)ฯส”g “๏ี๐ฝ2Lวฑ€ฅri;ย›œฆ> บA<#ค๛Ÿ2ฒ่ผ†gŒT�[ฏ\KƒW)ิ 3ฏo๔Mtต)>vŒr-,ด์ืโสr9.DV”4@ฎถคVH๋P฿๒ฬ๎๓ะ5ฬƒ€‘ํmปญ}%ญำ=่z;ฮฝ LY็l… l&/ฎczŠ๛Zv@ Ÿ•กเ™ฌ“˜Oอ็เ=๊ๆ<($ฃ"ๆOถƒเ]��,ๆ ษ^w…L{�M‚WฮM0_๘ท็†khฝ(u&"๛ิ€ำ:๊+UVฒ๖2o*ช~๔๖—ฟ�฿๕๖-…ภ^�฿ล |ฦ3p|ฦ�๓~yะ๔›ฟ๙;;?๚ใ฿{๗ฃO> P{|ท๐๔ŒTVZvแธUq�คะ!J[c odJ1K�หB�&ฉฆv6ฦฦฮณงฯˆ~5คพ��0R>ธ�aš"Bxฦม…†APpศ›yy@ี๒ž%8แ:็จบ gUผ'฿o\ิXใล(_žBญC‡ค”;ขbตัภิbื UถŠ๚'‚ตดฅสVS๋ดฃถžผํ"ฑ=ซ—ฏnฌ,N็*ฎวฉDฐ co#h/]น๓*•๖)ฆ˜ล‘kภฉ^฿ƒqั”๎ฝ๚ด๔ž๔ไม๛Ž‹ 8š๓V™ทย๖6sโฅแ่แฎm๔มˆˆ†’…Ž‚kฤ,3P๎ฯมjiEp๒H๛Fw‚a`ๅ็Jr๎๋pบ{๛Rw{�ฃGฃๅข์kWฬ@‡ฐMยลษ9ภ๒๔q<|&&ฦ˜_‹๘tFฤปcด™\~฿ฺ^O/†ŸRYผ!}แญฯัป๚2ฦˆเˆP~�ŒhW’7kUafeม�`#ว:‹๖ˆ๖ฐ�†šjŽตŽว>ื6c์ู]–ฉม๙ฺ|B็ฤyฒZผ†ฬ†„ั&ป Cb +ฐส=ฬ™LoiœๅHƒฬ9๔3 ำi๐j•‚ˆRซ-g๓(วuณŒปŽ(k?sงฑญ\ญaT?๘มR †ณzpห\ฯ�ก ั%ญฑ" หห€5ฉฑ์,๕P๛โอW_MWz{่tะAิกŽ�^Šเaฟ�Ÿ฿๚NzH!ภใ@ Šงๅ0MA(C‹ุGY(ว-8๕ฬปฮŸtLม€[w^”๊ f‹ŽkŽu—Zmถต้นดK”อHญ์[ัี‰ผr�:�๎FWŸหWฎเbl4ฬำฮS„๒@BŠŽ•ฒWพt&4จtxฮซTk(้jู�ดฑƒ๑้ฌY�Npขง]—SเIภ-ไ™kpฦ�)๗aŒ3•<๋๓ฦ›`P�็๒๙ฐ๘เNท้_๘�Qต|–H่ใงZlบฎ—ไ1ทฑw#,ดฆฑz๛ๆKดถkภP,"ฺำ’tD‘อมกAุk3Qด๒ ใSŠบ�P2€ƒ๑ŒatS81๔+ุ฿สก, ฃขg‰ล่&‡8[€M2žข›r.เ…t4tRฌCย`๘9ไ๗ฮi:‚:Q8‘๗ L/ธ-ผ(ำฤฒเ‰i2™UŽLŽง๚ชฺ(ฉ“คŒทณGน‘f ใ]v�r8พ๗!>'bฮwuM8฿�์\้tƒ๎3v|Ž[ฃyOF'%r๋™>ฺ๘Fดิส๑พย็s`กy EZq%ฌ™F:ศXแ�Bq2งtเ๊‘ู๚ผื7�� ]š6…ŒW'G€JฐT'ยy#ดแ2ูญํ!W๎9'ึ๔Nํ>:C=ค๓ฌ“ี๖@,ฮ‘ัK†จMมzMu’ิโPุล8‡gœ7Fฮƒm€<žเTY๘อฝฦลcศDKŠซ^ขํb'๓.@น๓Xต•โƒฃ๗?M›๓�›=`๚หนฎฏbŒ” •1แ�’�.ƒ็]จŒ๊€ 2O,๊์าโrDœ๗q๖Œ` ๔y^Tฐ†EŒ{‡น››Kล8‹U€ษฅ��ข‰“S3€�ะหนพทภCi=ฆlY€๘�งIซMฝ€ s๋•i `'ห5^ฟ๛2ม€บ๑�เ|ซกหส@.๚ฎ‚๙ฮŽœs/ซฮTu”ฒจ่K'9|ฮ?ฃ๓2Mi“™ฃ#บ ƒQ�"HdG„••@8ฮ<"๚‚J:๕ž^ว9๔g;0 X˜6'po€ม(ษวท@IDATฑ้5พวนuํM ุIงC(“$ŸโHํฦขœ;_์qNyพธ|&eฝšt6ฤYฒ(-๕ะ๓:แQ™�'ถฯ.ฟำ‘5mมšถผ5j�lไ)5 ฆRo๗@z™ธk€๋;�—{+šฺ(j?๏zV"%ศฎํ€90ใYtไ็žc“แุ•cwม8Ÿู=k5฿หฃเl“g(ชเ฿�๓๎9mฅ'๔zคX1ๅ?ภฎ๋๙YL gAฯํ]‹L ะฉxoฅบƒ๏‚ภส“ใฉmซ€บ0V0J`฿ตฌ\ ั/ำ–fๆVะI€Tœฝd2arศАkCCกd)ฏผ๔ูฌeก๒�‰ฑ๒<>‡ถ„b&CLV€AY+กxฯชญฐ™ดผอhJ-uร๙zs้๘Y�า"‡ฆ)X�๋๎วุ๒๒ฆ�๐๐่'1ึMศ[ž5e๛f2?ใ�8>k~xฏยขS๖้Gtป"ถ†j]cใ�ฏ�ฺฟ๛ทพ๒•ฏ�g9/^3๐3™ เเg2อ7y็�๛น๏ฟ๛เ�๕ๅ้‰ฝญต.๙ึฦ†fšXๅe‘ฝŽCผ[ รนN UตF� 9lจ�Œฒทบ†ั่ศ‡ฮlY–VRcDษ>AมฏC\ลก6ย††C,TŠถ= ภs8Ehํo๎Ÿฝ‡ฟนฐ‡…_Vฌ*a‹�„กASฮanป-ปI#ๆ˜ส}P#ก‰ยR…7* จแัL[y™๋AlฒึŽ.ฎO1ฉก[ฉ๓ฅฏ๒๏6่rดผ๊ฟ•Š์ธ !315†aItuฃํb5ล�่:]„๑RJ$�ไˆT„c๚Nใ�x k,†Qร�ทF…‘ฌUๅษ,ยxิ–พiมฉRœ]ป(˜K-…w�H น� Ÿำhฐ๚นโ๊2Qrl็Sร๏„ —qQหุŒ"zภฮใœZgยVzFŒ‡n�ˆฯฯฎ,คสฦบฤHาkพถJฮ4Q ำ6ก๐ฏใ๐๋ะb์žPHNงฝ˜Cำ6_‚๖1฿กNF!ฦ|‘)Dง,ิH�#Œ\ษHsจ€:�ƒ๓Cิ †„ฦ๎N€/)ŒnR™e4ฐ$ฑ�-พN0อืŒโ€Z๖:lF+Œ"9ก'1ŒKใี–g‡U'Dtv ๛๎b|:็ึ›0j ำ๛สซ๗p|1ะp+ฯ�ภe๊"เเ&ฝ<,ู‡{ด๋| ย่ขก99ลetดhN7/wคฟB๒๊ะ@jภˆ7*$เ0ลZ|‹J๋฿�๐#nJju `้sWึhG)_W๎�Šศ†tุE ๙ฅนY�@@”�ึ�Wาต[ท‚ปวพ„š™„@MMXวD‰‘‘า@๎5Fค๔�บfปg”ัŠด#�ภ˜�[eํq๐Ž0ซ0จe Uรผั๐to9ฆจŠPษ�cิส–ฉๅ=m์)็‚ฬง†ื!๋|‚Cน>5ษf…˜—#Aญๆ6Œp~^'ยz �9A@ฃlถด’ป๔R)ํMิฅฐ@็๛ณ'อ"v‡่žšC๕ NฅฮtE9?มY›|๓*>๛…ฯ�BศพฉQ;์ฟcึอZ {{TzวH—ูฐปณ‰รfj๒€1ช.าษ๔N>๒&{กฉฝ•=สœฎญ,ฦ~3฿ื|`็C๐L%p`{1 g™๙œ่ฬpm`O-ึcำˆฅิ�Œy็Xฑด„้‰่aผ๒ๅ๛เ�๛ฆ]€ฉ}‚ใˆ!Ž}๗�ำไYณ^Wวbnำำ8ฤ๘8€: ฿�ใoฆ๏ฯฃฮt�ฯ_>Ÿเฏc๔UTDzขe:…ฎฝบH'�Œhz!Fom–ตฆถห ล฿x๓UŠ� ฐ/>ลษd€ฆlUGฃ๘ฆญX#ฅ’yณ+A@^–hs๚๖*Žกฉd=}}ุ#…gํมร)ฺ �๊ฦ9:Hภ‰ฃฆฒก�ŸŒW0ก๖“‘้X:Wฆ JIๆ3>S‘>Y=ึษTrฎ๐_์•ฅ™ุฟžcžœ5งฐ ขpโะ2gq‚ค[ฏํใ|pFMว]G�B฿FฟQะ๖†ซค€นฎใlฉ Kc•”จeฦUZNMˆ .Ÿ/ๆˆฃMแF๋ ิSWึRDHงŽฏsๆž0ฐŒ๓D๚?Kภ��คณู๋ล๏y:_งY อณ่+-s๗๖Q€]& WpqŠฮูข�1€3ไ2 ซ๎}อง%–ฎมฌ่ก˜ใ(L‰Q๔๘2gเ8๚ๆ๖ตซœ‘Uัiฆฅฑ9ูh J๚.๛ล๎1สzDๆ‘้}ฎ-ธฒฯzั/Dึ’ฦQUอ™ว{ๅฺ`P๘ฮ}ฆ,Š�(67ืจี0“ž ?Jำ�SPวตทพ๒j�ƒ-ึึศฒ๋ิ7F˜s์Ÿ%ฤ`G๐yๆฌ”†ฉ€‚ฯv0๏>ด›…Mโผ ™ยA>-เ|`๗™์๘PaQ?ฯ8dฮ{s’E(ศ`๔ภๆเwฆuxWูH>เlๆฟY2HRยZ[ˆฒกฑฐV ภP ็2*%ไt ฐ5๏๔ับN LŒภ†ห9‡� ธ�>ฏ0จXงืD็ิgดXฉ€˜Žต๛G ๓ฝ ]พน> hzVฉSKฐช๘=Sฒ(kA�า_6ทฐํ๘ฯŽ+Š,b‹l"�Gศ2็อoภ˜ใYJจ๗ๆฉ๕4 p@ป๊ัใว™ฬC–ื๊6Iณ์‘9๊่pyไร5�Œl#C๊:N๐T0)X@่,ม7ํง u&Gๆ‹ํ’•#ำ= =ƒ“]lิt@–sภ@’เl#,ฝS&สv—๊hฆ'ฦ_ ๐ฌฮาฮp?x=ป"(7’0 ู“ึ—’1…E๋ณ๐uB�&ม–่Te ‡€@X—BชpšvQTžญ�๘ล/�สีำ๓�ัo�๖;,์ล๋b~63€*นx]ฬภฯf`�แ}๛แ@oห‘“ธBมฆ Œ… ”l…JX*\ด7;3‡ซ…ƒค$ƒVขH‹ฺd8ะ3˜†๚ฏะ๎๎“4�|4ฎํข4ฬZšึQ5N`ั3ฃZFsƒถMSCVห1ˆŠcภแ, $ˆผ{๚ …–boDB4ผŒภขxๆkl—a์ุ^'wขฃ}CภJิด(loไเ ›@{7N8UซAืZ‰Hฮ…ฃ‘6‡ฮม›ig‘ยyฐ๖ ๊ฎŒ?ยy) ชโิไตฺ)RxqAฦqบy็Œื�˜{{ุ๎๏ฌล3dสศ๙ฦ๔ะษ•nŽtTจ็‰L]ฐฐ”แ;ำ4‚4ภะฉจขp$SF‚ฦ›Fคฉ$งต๖z� ฿ภ)Zวa2O�uฐ�วožnˆqq#v ?K^ว€ิจ0’dฐŽยZDmืIo€ P…ฑ=ŽA ^C�ตภเเe�L๚ั~ˆ™ง}Jว3฿Xฝ–๙รกีIต๐Uฦ"J<ซF๓บ‰ใใommƒ…@ก&Œ™ Fข€ฒpจฤƒr๘�Ÿ9ไ„ฑW`LWixณ�Q$ ใFvG-U ƒฏCGnฅ๔ํปฏ 7ห.ุ—a”๑8ไบ'*}_ cQฐ šy^ลˆn#ตfknGx*•๐ :"Fžiน4Mt๖อ)9ๆุ8{G3ี’)ึื��˜พ๘…/&�’ฯ'Mšฃค†�แฟ๙7้ป๏?#๗›T๚v–ุฮFX}k;,`œ ๋]XP์๊๋a�œ2ฦ^L[จลs|ฯ๗ฟ๓็ค)C/ํNหำ3ผร‘๙+!šฌรณฐ �x; ๖…CฟNlfq†t"@ �#;ลb›ฅฐXถ‰�X9ฟะหœ#ฤ๎ฉk#P%Eนใู๏ฎตCด†u‚1ค๖1ž5ฌฺz{b๏บ7[›x>dŽษ–ฦฟA๊J}#]50ชŒผVแ\สะ –๊ntYJธฬ ๗�มแv–Zฦi7Rm ’�>hโ่ ๑ฑฑpข›"บŠ!z๛ึึv!{GŠฏQb,อplตๆ๛Kฌ๙์|ฦ4LqE่Rk‚่๘าAถีm{dtx$ ?}ŠaM>พฮ๗๔:พމ‹ฆWฏ…‘๛ˆฒ‘|๗c๒Kงย}ม@ะ=๊Mข๏ศŸ๛V 4"จ่"๕‚บต็ZQ™U€มƒ�-:t 8eพวฺhฉ4๔*๖–LŸ ๕ ์…N"�คฦ˜‡l มู)mํศ97eํl๏ธผดยฺภด"]ษ๙ิyึ9c%bฬ:ฅม@`]\ฃ{:J:FญeXฤ5"ุ��+ๅม �๎ซ๓แ8ทqt*lงŠ>ด]ิต@w9'พ›ฒ˜หาํV์Hม™d�&๊,SƒJ˜ร พf)๒ฟŽฃิ ฐT[o๚…aœ‘วBAม5ฦ^่ิ‚๎กฅ1๏•…ฃSV€#�BสŒs`[Hมศุov—Q๖• 5f‡EGะUร1rBž)0oไ�9๐�ฬฮ“iU€2…์G .ZXovศ<�‘ไ๚ี!t8kDt๖ลุhไ}o2&>]พ|%}้Mฺรฒฯ>x๐qz๘ไ9lมaj„L�ะด ก๓o:˜:ืCrAWsภ๓็n{šยบะป�;š`๙ต2Fd•A ž0ทห์ห‚W๚/ง๎~ “ชฦ>ฉใ|;แ0o=R›๘๎˜ุฮท‡”ฅ‡Cษณๅpศื–7C/หp‘rN42lัGo๗ ส:บฐ8c_}N�้„๗`X ๔Hแ~ฺGึ๋�ฝปw8็ต�iลLฎzWw{ชธG‘Y™,่๖ช` ZศจPฟ<1’=}‘V7`QแX็ม ฯ|ไyQษหg4ตB4ี๓า๕>bฝsิ)โmฆq:฿สu่ฯ ฦ๊›”%7Œื๖Wƒฅ์อ}๖฿:ู๚๊[ปš –Œ3�กฃุD$๑ปF๖ญฌธE™Pฆส 4เž3jฏ๓ฎ.4Xc $Zำ�nmฃ< Cึ]hรxˆ•#€“ษxๅy๛ๅฯ}&dบผ!ไh ถฮุ่89�ސ{RY็ื๓‰m้Œrasล:"sฮ?{F๛iŸ๑œก฿v8gKyฦฮงฒะษฺ‹๙ขบ๛ฒV(yภ5LIˆ ใbฆ2จ?*ผฟvฅ Sค๓iO k‚Iž‰ฮw๒dฒe—ไ™ท2A�,rฦ{enTฑ๗j`ถีr ˆ฿ธ๑าื�ฃฟ๕Ÿ��ŽŽ@ฉธ๗ล๋b~63p�lๆ๙โ.?™ภƒณ๐?�ณํo}๏�๗Zป[�uEa๚๖)ุฒโณ�ถึๆr๒Jw7ึŠP˜…นตœ-"๕D�7pภm]๗๚ซobุง�๐‡” แ(๐'รO๘;ิnพ9|Fม4ศD{ฯฃ_Aฏ๓๗Dจ5zฃJ]ื๗๙ชร1๔๐ 7jPบหŸqhy�้S /N •*Œสบ๚št…HY|jˆ†ดแ่56ัzNEO$_cจฎฉœศ$ฮ›Žข‡”H#^ญ]}iz๘S:(ฬ�b~vŠt†… ูWB�$2X…แำึAQ=œ@๓pฅ_zPoRXั๖:G•`G>างs`"s์#RษxJ‹6฿าH๛ ฯ$š.ห@ฃวgา`9g+x๐›วi~o)ฯmNๆ6ืำX6ท๓Œƒ฿�ฺCจ›ฦึ 0ถ ˜{iฺึr‡˜ฌ`… ‡ก†Pฺ ‘๖*Œ๒jŒWฆ‰”Ž๖“้ uPจŸ?{สm�œ,@š0ๆ™�ฅๅuŒRj`ไุฯ�ล)f์>ปŽหyก'b�้-ร๒ถ๋—เKžFh •ฐ1X”ฃ…`*4HAN tX9ฮร`๒%[ม5ิHp^-NfQ()‘‘�! ‚,Zฬju‰๚ฐ(วฉ0�้ว้`ฃŠ9ู…ฮส๛๖จฟP@^๑ฦาZšz~†yo!สะำY—:+Rs-FๆPLG3—v˜๛e ž๏พ๗Az๔b"อ.ต#Y�ุหs`ฌDTj'ลใฐ^gช˜Ž`$mFd๎5 ^ฝz5ขฌถ'[^6WG“็YคฃFึxไ?�˜^c>�sxDTฆDน&2s๙J?5LX7ถฎ๋dาnแฎ3ึ`Ž:ถโณIS cว|lๆ[pภฝk”งGจŠผZ๛ฏ’aค\ึ‡…6•%�๓e๎ผิ๎๛œˆE–:ุ tำP3bฌใกมๅฯฆ‚eกY๖ธนญMต‘;ฌผ;?MP฿;;/…,H็~๖�{ท<ฝ๕ึ็ำKw^†jšฃ("N�&9ฦาž[๘ฬ.zวHโฬศpšz�ˆhฮฌ#อ5งท<†ฐ #Sฬฏ้K้W~�+€Œi~n*-R8ณฐfS๏lšฒ Sดh"teD••q๕šLœ|+[*ฏ3Wฐ`สˆ์ป4|•= ๑•จ˜_.ฮ็ะส/๋ขฃ/ˆชžดm]ดzTdT๚ๅหนณศฅ]lึ �๛เ}ุ8ไ๊C�ใพqฏป‰G<‚a%‹*๔$๓๊}ฮA„0€ัy๐€๛ฃ?ี+ŽA๐งgo›นœŸ วดyฉƒฆ/๓EH9 n; ‡นใWฉฒ.{D=ฎnหบ‡R๔)z5GดpŽ}ถอ—mทaซ),pLาฺ• ŸA&V]Q,bjZ…ษ”ฉ]>๋X#ยสธeบ สุG�@ฬฺ2\2"[ฐllšAY|4(฿ส0*โŒ๓ฦ^๗ๆ]๏แ@ไะ“*U•0ีH฿ฑ่]SsTMŒk๐ึิ�{™ณำฬƒGค~อาฒ็=ฑ�ฆขๆL'ฮึฟ ค+ํฒŽ๎ภอ•5Nช๓ฃwฟ๋ตDุ๐45! BฒV‚ณฎฃ`‡2ชพsMƒa‡>ทSรยฤ EfgS!ฮŸ)o+ซหDI‰๎ฒ~œ_ธ“๕ตŒ�๐zญœy ‘C—cฌ-ฬ๏พ๛gj8๋j(โšO†I‡ภท˜จ_N7"ซy็ี(s {_fZ`9r~ฉท+๔‰Œซ…ีน๔แง๋ๆ็ฌš=ปฑHgœนtˆuR––`Ag฿E฿˜gฎ™pŠ~ื™ถํจภเ๏.{Fะุ9“ฟAŠ›ฒ ซฯn8‚๒ž#LOไภฯษfแQWฆ<็ฌฉ ภhQJฏ฿�าzบH๗:�‰b~ดใดจฅเRx้่ล]dWpะbฝฒA…ืa;์มผD8ฦa—E*cฤทึฦ6d%รฑฆฆฉ5ใวโฬ้ลศ8)r‹คsฬยาœไฬlHฝ�!฿ึ๓(เz•ุ ‚l้3  พ9ž=%GดE๊XMถ–ดธŠ0๚๚๛๙๛qZฦ)ศ๕Y^ข ึำ๊%Tศ๎‡V{9 ีีฅ้4๐mย8ศv1เญŽžๅเซ=/ๅyŒาnq่NOŽm้Ž่๐ุ๘c&RSBั"ฦf„QฃGร๏รHฃ2๏Dcฤ๋`๐hP–b\Y„ฌ‡ำ˜ƒ_Zซ9ะyๆ…6คึQŽƒ�(ผฦธQ [0๙p๊TVD.ภ86ทPใ�๊อ‡"ฬ` iL๐?; X๎ ใ!หฟ7(`ฆS ๚ฏcg~ณโ%@")�F์ub#๊‰๑ถว{•H+ั/๒cพฐ:ฬx(๋€h�xh1๔gN ๐ ๅู$ิ}d}=์-ดgง)ื—ฦ๕Šธนล9uNu„${š;ฉัิล�๗๔๔bเไsŸ—7่!]ื(๋  ฦ่>ฯu๕๊u"!ิฐh#†’๒†ี”ฮ˜ป}~œวc  Z(ว-u)}๑ํ7ำ๋o�ฆ0� r#J๚NYyuขๆaม`}๗ƒำ๓)j+ฆ์`bŒ[@้#ฌŒh-y“อํฉญณƒ1wยhุชฆ้าญ-aฑ๛GฃฯbP฿/บ<ฬM2๎�จAa‹ฦ จCไสpR๛ฐ9ฎแ~,@๚๔ัวฬถrlTภวภi'๚kฤaij�~ฮญF’†š‘,๓รq;S[wฦ5AฆPว\cNcห}ฉ๋ งSM 4ป!˜ำฎ“้๓อ•Qฃ\(7Vร๗ฺ:B2t–tj�vL1}ย๊ำuค@]ขณลตkWHUhaชืvไฯF.dั��าLะš์�ŽNLŒฃ[จ+ัษ8pd˜7ู‹ ณzอ์WบU Wฅศ%KD�œC็WฆŒฉRFEํ๓+_๛๋ฬฮ+๗ฅ๙ฉ4๚โ1น๋T—ีมC+‹ฆ˜โ`qฝ๓�_็E๋ิ=iฒ œ(#zๅขฆcน๑jƒ>kt<"ฃศฆOk่$Dฏฃ� ŒG} ๕ž{Hƒ6"ฬ›ใ€ผภ]At,fฎฐ๏๑:~นท0-�Vฦ%<ฆ๘ขเ€›C]šaูsbแ<็�็>๗L’’ž!๋=pq6^Wz๓ํ‘ซJถBl 6$SI๖ฮ,พ<ฒณล่.lq�l๑ว์Ÿ<ฮณCฮศ\ฦ€h1�„๖Œทc"X-ะํบfฉ3†ฌฯ˜…ฎqฯ�SพJ ๆ—UๆำชuฦSy๊๎ifmVc_ฮแ Pv˜‹ุe m2ฺ;ฺB$ฐ™Lนd็eŒ(ถ้็ฌqฟkุe…๓N#eพsำา2e^์ใส-ฬึŸHไ>๓ฑ5ปฬฅv2ภ!ึ—{T๛เ�^Aฤ1Ÿตg๙Š๋6ฃ„ี๘๑yNr vKถ‡็fvOs,๑o_ฏ/a}ฝbY�  %šผฆ”=๊˜๘:�ฯxฟชyฯŠRบ]œ|๎'nฅ›/]aญกpบฃซ'’สm^ตมณc€%MหœƒX7ึ,๖ƒรพ”ฝไบุถณิ*€ญเฮำั1|$ส๙์S�}{ํŸ@ bพ[\๓ภ๕@ด{8รฺ †cฃฟ }่๚5H฿b�pฆX"ต›C’…๋ฏkF„ฑV๑�๊`:,ร|�t4ฦ^อห\ดญ2YดพทสsCDmA(ื“u[๔๛๔M๖๐“ฒ�ฺcAa’์ๅ๐ 8b€-ป‡Tp๖ด0ั�าr๗๓Ÿ�ยฟ�ฺk?�ก‰ธxใณ�;�G@��์q6?าx�W�๋�฿��?œ��o�ฃ\บ�•_๙ู?�๎ต๋0๖ไY๎โ๒๔อ๒;ษhg๏�พCํ฿&5|;,[๓WNp่ม)ฒkฐY9^ฯƒQfยไ8h โo�NC , Bpฬฐ๛fˆ แ�6ใ„‰j›อดO<มm๖๏vmฐNฝ–€jq+k;ษ —A]5;&๕๑๑ใป0 ๆp–หฉฑฦกขฃภ6ด� ่•G„™AฯdชเUซn๏Alะ•แPSไฯ๚ฬ๎๎>j"{า[o}‡๑ๅ๚ฒฉD7X๖๚" แpฯษณ#K6ƒj๖0~fœ๖ฬZq@…pYษJœ*ณ.\Žวq€(‚0ŽEd"๘"R2 ค) �(รa�r ๗*ซBet0ต& šk๋้๛Mถ)๊œ�„ดึ`TL�ฟG&h.4 ์๋�GเฐE ฅ’u†c#(~“9� –ึ๗U๕๚`H…Žp�9lwฬ๙าฑtt’73)�ฮ มC\gุ'K40�?ษ%˜b> f|/์ึ›4XŸo๎ุ๘ชำ^”€}ฦชgUว>jVuฺxNKoบx�Zz้3ฏคฆ้“๕๔OHF•` D‡K‡8Ÿตฃ(คฬ•ลั2@นจ�7ฅ =Uฐ0ชษฐิ ฆข’,'๋zn&M.ฎค;รำ๘"ู:ฌmย*)!;‰sฏฃWeม\ยŒi"›%ฆŽภ<ว goวt ํษ๐รดAm๒์}ฯs=]พt…ก$�ฝ๛Q ็pLฆ5จ7_พ‰Cบš~๘รw‚iัย๕4ถYง\ =aK๖€๋FAฝ 4๚\3ช8‹นฌตผBๆ…Lฺุฒ,ฦ ็๑ฃวฉเ๓PS๖มงฬวฺ=+=ึวsTฑ8mƒ{ฺฬ7oฅXeภu๕@ั& บ†€f)Žฑซส๕‘Aฦ5030rฌ�๋๎\~wปožgมT'ทณƒูz3˜^ฎต8๘|มท/๙K� บ€,•ิ[>$u฿q๐��Hˆf4�\U๚-G”๋€M"ญz๔ัฟl3`สฃ\ฆ๊๘=ฑ^š’tWrˆํPSŠภYk€ค\ค)€ƒ2~๗โญ›h\ๆ5dzฉ‹/AWโ๗ฬมฮi7์FdfWญ๕ลิีืK “ƒวำ(ฯ+ฑก5d๛ ผ2e|yฏฮ๙T จ็„=่ณ๓ใาพqo�ฟภƒBŠึิaฅc๖์>c“ษAด†D{W;c�‘ๆีชแฌห`Kํ^บ�b0Œ>@d‹ž๑™qๆ“๛ๅ�›กฌช[˜แฝฦ&ฆ‰)`�ห‚”•™aง"ูmกEAๅ2๋˜ส6�%;ฟ ๋a€ิ2“ C็/ฆž๖nXlhผว16 ›w‰2ˆ —ฏ๒ฐl\†ฬMd้Yร๎)9ถำ#VŒ๋p,Š'mผkดœึk—โ/ภu€ฮหษ‰:9ž1‡ฉงงะฐ>ฦkฐ`šฑท ]€กุuฏอฒ&<ลHy#~‡ร๎‡ธ&๓ชญ:–f^่ }y…ฒหmึ@ฌ72ีฐษ๖wฒฅf฿d|Pภํ0F&>ถ9�p6ฟธOjE ํช’P•e$Œ 1พฒีื‰N�YœฉRe4M์ฦ)žห๏ฃฎž}ฅฎvธ€ฐผ’๕‹Mก†ิ��œฺAพX#๕ฐๆ._"่ฎJ˜-+ชe]ฎฑGO9Ÿฎv๒-#ต4รLพŒ”SZโœ8 xึ›ด๐^–ั*R+วฒูLF์Uอ—ฬ,ืˆ~Aกํ~๙]%ิฌ‡rฮจ‹W/เfw>2J๕oิ�‘yท€’(Tษu๓ู;2๋–ฑแOžม8ะN”“ฤQ�W+“Kัโ‘๑V“ว‘๐Z|_Aมป็@ฅI๗˜ฟ� ๔ำไ“€ค�ชใฎ “)ฉŸโ๛$’Œช‚�ั h ˆfcCำ{?๕ฺŸ�+_�๒Ÿz็๕ื1๔gณ๘Œภp๐#๔ณ�—ภ๋ฏ�7ว2๘:๚ต�้wV��๎๏Œ�ฟ๛ัOํlฌึos ŒNMขoึฬ€‘CใlๆJ็ศ,Š4ฑฎม๛;�u๔้ัะ๋,Yช`�ขŽŠงc8เ;Mpๆ็ดŽaq�E*b(ๅ’‘ษ#0W|Jzฅuถึพ›�็Cpส q˜Vqึทpb—ฎv"Cพ‚“ๅ็Iu�ูก&{Uzธ}อkธ†2๊d‡Cๆ˜ฌณœฎหฎ�•$Kม3ค‚Œ์ม ๗ยพuํฑ๘^„ จŒŒด๊๊k” ฟ�A”@ตt๕+i{กB{ ๋ท‚Lญ๛\รุ่Sl*ฅ.�‹Zปฐฌุ๊-ํํiz๖Aฝ€‘�mภ& -เ.8ม \า6F�^ฎUื˜๖�ˆ gyู๕D[^XaุSฒฬšŠxฎRrย™๓�ปa’bLx๓4HฐvV‚์ƒ~l*ฎmถึ๎๎ูbฒ�ฬฅOฎdฏ™u~:�(JN˜+ฯบJภฯŸู�Bา Muœ[ป+˜™.โฝใŒalคๅ๏>xO2Ž g�ฑม๖ปฝ็zg๊ธ�๊N๑ฺmภ„ฎ—#๎ๅ„{=†ณฮš4Xี_q-™A_แLทdฤฺGtTถ_ภฌฯ้”iรฉ‚‡ุํuส…\หœซี€Ÿา� ดทYcมขC/5Oว�๑u Zฮ๛oูŒ;eb๘5%ะ�Mจศtroธ–ƒตวฯ`]�(D๙ู๕๕&ฒ ฎQหšZุ{ดnฅฌhฐ"พƒ็{าต+Cฉซ†ยน๋ซ‹Œ'€x7@ใhท!KถY‡3ุPู“]€ฬEŒกko!^.u`ฉ“ /L5ภZิR์eฌ วิsZŸNป,`ๅYฏล ช?๗๊ฟ#กP@4์Pืซมฝ~ˆš :F‰ใep/xฐ‘A๛�œ.€L�ฑๆแ|oื:—๐�Jnoo�'_�ลฟ๔Kท>๓ฺฝ3ะ€แ;{�ศFเ 8๘‘ �ู�๋Fเ็�๎ฏmิoMฯ=›ธ0=;�XBถยRLUdƒ]E๙๘g‚�ึCœ€:ึ\ย&ฤ™ƒถ,rอแdn๖หฃลรFRXภภ‡฿rศ2h�อช้ HจR\B h› ๛|Mณšล8ฦfแืัe ๕vGb“์ckkG$S“#แtท#�dfฬรJ'/�_ฺฌ™c>งงo€CœSMKJq๒€{BYร;o—๋ภ๏:‡ -ง8œฝณ|žR•US ๙G8y~…{แศ๊๒”"œŽRh๏:P�ฏ— ‡žด eƒธ`mpเy๛ฦาอฌ›]ฒ�_‡ซง฿บ{ฏuƒู฿J2ฤข๘ม�ภ๙า๓€=‚ฒxH-g๔w้นปfีjQุVธฮ�ีoพ๑FZงU ๗ข ^Nๆ)mน28‹:ดพOdxOฏEภC๚ฝด๏•_สฮฃ็ื๛๐ž �}žื•Y๐q�อชฌ™aR,ส;V<ฬŽพ‡ํ+อุ™•ฝขC)›$ฤ็;�„lJเ:p๕r*‚v<ฐณc=$ภม"tvจฬโ—r฿ญิd—’eฺFPq~๔qZx๖„,Mๅ ฏฆ[ฏ� �*<๔ฤdifWถT;JžŒ"<ธŒc>“VqP*^ฌK mึiemŽ*ใฬ๕”B™ํขžึถe:“ซ#ฃฉgo่ย๕T฿ึ™zฮฆŽ๎nV‚๐%ุ˜+8ณื.\E|1CBS˜แŒฏ๛ห์ฃŠ๖ึ Ÿ’9ี-.ทฎ7/u๕vrO-6P…ูึ๗Wขฯัั�ล>ฅ~`d fะ&uฉ~w๖๗แ˜1'‚0 o>฿_:ƒ;8๙pPS3ฮg{%dฌr ๕ืิืฅW_๛”dkฺ›ิe˜L์ Zื๋<)„iฆษ^้ถb<)ๆ�J`C˜ฉ•ูbภ�ฬ{ธfๆaุa—าƒ๊w?x—๎[ดZ€,Kw?บC=-ƒ,ฬ!– ^ืาฬ:�คึ•๎ ์OmF)@7ฦฝCg฿Yล>Epษ๚ล9.(ฅฤ '|ร:l^ ภ3รš?%Jำ วA0–)๋†๎ฌ� ˜[’ง|6@฿ี(c=�ฬO�้s?๙b3ใq”n�ธcโrt&y�ไ%>AŒตฮฉ5พ๎nv�|๘�/๗‹_&0�มbb/:–!พฦ฿คw๋ฌ[p@Pฐวž‘ฎ� s[{๖๋›5@8F`[ƒh˜Ttร๋RRvŸQ๘/“2X๚โืฎ_…Q2ž •ฌm`wฉknm‹>ฌ๋jfN) Wฝ6C…{ษ ›ส’ขœ‰Lไ*mำ`บุ‚าŒฌเG!6โ” S{'ภจธโถ๖Š5๛ูฯฟฦฯEPu๕tว๚ณ�ฎ๕�๊—์jตอ2…l๕&x™\6‚๏@,ธฐร๓™ฒ่ะ‘้ฑO{L–�๎/‚\–E`—ฝ�๒‹|f}ข้๊ —Cx7ซฝ“&†'าไ๐�4�เ^ุย ฮ2–Dุจ๖ž>ึ+์ๆฺsฐ` �ยW�€M kกA‚ใbฌF2เv‹0ฐ๗ฺ�š๒mภm ้ ณzูLณgj–ฑuฤ=๘oK‚w=e์e3ไ@“Ÿœ™Ž๑๊้9‡์ ู•4> ‹ฃWเ–Lˆ9T‚{—iฑ ธ0;K;b€B™k์{H!9:ํ‚Ÿj†(ฺบรž5ญ@คe'ถ ๔ู"ˆงฆใว็<็&€ฮz๓๓ถ^เล"gƒฎึุ6n‹ฌ{Œ5ม—ฉฮ›็=�yFุy%เAึ”๓k†ฝœ2ฤ๖jgo[๊้ํA‹ฃ๐พ‹ฝึ Š!aYe๖ฐY“Šฌชk$%€Tยบ‘Jึษฤไ4๓WE‡„Z| ม์<6๛แƒ‡ู้3DU9sส n@ทชvezf.�#@�๖ž๓ฒ]�ฤrุ๙ž›aป—ูณ2ŽlตY8๚ ์}Ym2 =C๛X%&'ด#Qฒ/c— ๔#&ฒ˜ฮฒ'ิดเ�ศฦ‰“คhฅ์ฉŠ ลนฉQ่k�=้ 5ŽŽั5ุอฌ†ก๛„ฯ67๋ B€โ��n"� ่า�ƒซศ๎-jwธWฟด•๒ž่4๖ะy�fฟ:žžuKฺย๐Iธ฿#๖ป๖Jปฬฦ๐๓) สsศulRE๖าิิtzž็~๙ข`ฝ๐ž2a๔4v >๊Xpฯ็ฯเlVkฃา3ฒCํ๖ๅy#kD0L6€๏ฉQ“ห๗Xวฮ[!sฦ6›๚/>Mึ…ใฯฒFl?*ใƒ๋ฮCL›I�ฑ(ฯ๋๊์~ึ��๓๚Ÿ�ู?๕ทฏ_�๔$‰5^t๖8�œ?บฑ?๛ไอ�Cุ�มืฟ๗๘jUมฒŸ_Z_อ”-a„Uz™ k+ฒ์แfฅŽฑY3มฟ๋๋๘]็จน็๔1่ฐ๕8‡ >Wd:จ�q@rHb�uคอฐpเ^ใ โ(ฒ{tพH�ฤ{TM.&เซE,ฎZญŽธeำPภ=๐,+(†VnM�ฬไืD0หณ \ ภึLฐt^Nœ*�šFถ)˜›'sฒ‰@ญ*ซšq†ศพuเˆโ์ƒ{จ^Vjฦถ!ฒwีŠฌๅ๔Eฉ๐š‡œAฑ่ผAศ๓๛ึืฉP@* ๎ิL~ิGใfธn:ฒ็™EฃฦวH=i่ ผๅ่ๅ๚ใ€C�†œP้v 94BUทอ'แ ๋˜ใ/Bฏ23I™…Ž•๗ค "~Ddีฝ–˜Oๆฺนต/ดAƒผฟ๗ ๗บฌ5๗แ|(�ไsฝGYl๐z็ูฟ็A฿f๘{ถTA๊ , ึ"๊\)ภ๖\ใ@ว�6%ฌ‘PปวKจภaoฆn~ะ`‹9›กญ�๗า8€€L ?WแสJœย�๎hฉ8S“>NEฌŸk/ฝœ๊กwท6ฃฐ™Z์ไถง๏=J๏}xึ–+ฌ™ูดะz๎<ื†r>R.๋�Cฦ๋qผ~Š๎ําๆS!sSฬs6ฦ'‚ษb ํ1์ะๅ+iไูณ4Jฝฆ™๑&‚ธ—ฏง๓$98A*ั—A๛-ๆ=หะฯ(7่รฉ�2ฃ Xกศ LŒ๓�็(ศœใ`ฺ[:€ ึ‡NšA๎8YbJxจQy๛vฺZ ฌ…ํ†6จ�dฑฬ�nAuŽšr๖ๆTPkW-M)C๋มฎ ƒCƒฉ•ฯ8eัT@“V+ภšrEณคฒฺj‹šOฌJสGฒcย| " ๔๙0“dXQD0เ}ุ“^6ศ๘ุ(N-ืฒAึูu/หG–ล}สK&&ฦบdํ�&4จ๖8ฑี\‹”x3‡Š!>y2b’ช�๏n!ฦว๛lSขjQQ9เšYEฎ‡5eถXฑC™@Vฌ๗๔ำ|เa#ึqม๙B€.^ร=ธ6žƒ`ฎuA0ีไฟ๘…/ฆ[ท>…]Cนœ Ÿ๖hนœ๑}%e|“/)๕Y ะ์"Œl`ภฬŠ:^�ฮ‡{ไน`—D€์ผ›mลplE>t๑*ึฟฝไ_€ฎ-sDวพ“ฌฉ๊ศฃ๛ด)e฿2๎‡ภ;‡)็หn‡,ๅ๕๔ั๏ณwๆฐซ @�ุืถŠmhoว๎ศQ"รšฮก ช;{ใฦ‹€-ดz#ภ๒<!“ "ค+c_�#QFฤ‡y]–-d…๎เ๐ณ{�ฌป€U_{ใ#ฃ(Œ�๓gืฉ] ฒ%IŽฃ๗ใน’ห๛j/Ke\งž ถิึ ฒ–ร ซ(ญฤ&ำจ๗ฺOฝš^ธ `ะHหRุุ=nuถ™Fงํลๅtย^ข‚�ง�R—›K€Q์cฏฉ”๓,GฐŽq่๊๎ z๖๔๘XZ_^N““ฯ$–9มSCฬMๅ!ช่ซรcu†�เAqk0ใฯํd ๕yN1f~ตง2…ZZ�ีฎ)H—.\Lƒ็ฃTeŸ๙ึฎ{พ™I—ํ%Pเ{วต$ลg$๑^v1๐฿ฎ๕,uฮฺ7[^vณ$(๊ข•ฺ^๓“ญฝฏ.ซขv�ถรNCึŒ๛Zบˆ.SN499ร=p์e๋ฬ™5ๆ}ŽฟeYDœ็\€ฐsTฐPย๘|Ÿ@?ๆ|ุคDAะ�๋ทฌ๐DPภ�ยีKฐฆฮ คธjgพ๚ถJ^ฅŒf`dz� %น9fค๗yŸ‚B„8k่ฒดภพไš]5U์็jZ‰>L?x๛‡v๔ภ6ฉซฤฦ`!&5‚™ม=ฐnaท’๕๚๙N9S7ฐ฿žณ:%ฺu6L4€y�ษ๐L฿cš—E$dPˆฟs„6QtCa5์p…ฬŸbฒฌ๒ŽŒจคณOm5ctธ–ฺ ฎภฒK๛t๖ ่>Fำa~v[ธฌงึ๎ุ—€ร$PไX�ฆฝธx้J่4•๓~žใ2V�ฝศ:jฃ•๊(bย^w\3ญ wn›DykQฅฏขMt��ูR–hณษฝช“ ฟจข๕L ธv}#ปtUSพเœบถeXถq. ฉ}ฃ}s•`›ฯ๕vรTฆŽพ�แ,e–ณ๓ฌ!|”2๎a…}š#ฒวz)มฟช�HVถ€ฉแบฑต\ฌ๖\›ข^เ’>Œ,็ทpK?ก็ฒ๖�…กม;?�•ฏ�โWฯ]๙�๖W>*y๖8�ฐœฯg#๐ษฅ ตprr�ฯ--ฌW-,n„Q๖ถ]˜BO"ฝ:‚: q@p[,ูls–�ฆC์กTl$ป†�็๙z ๕ ยy†2'’ํ{7€�’จ_ูAหtNฅ}ถpเˆ2ื5y๘AO_ฒ.š E‘ื Aิ“ว๗"ฐ?" ‘’WE†^tผ์ง๕จณ3“qจoฃฦŸƒ#ะึGป็mฒ"‡8ค3ณห“‹‘มYXXแ๐ƒfษนAveถม:T๑b=ล”ฬx�o[มถ๊u๒;i�:fฮฒ‡‡)|ด0”‰๎ผฟcขใb`mwŸl‘๊��ฟฮฒzดปนWูฌdูJส์8PB1ซZdฐฒ;ดx๎ฟ›ฬU4๘ฑ‘งF!tฅ“ตŠC{Œรup ‚๋ฮแs์q๎<˜j่กkP%๕ะฯฯ‚ :พY1C†Mดผ๎ฌร$E'ฒ�O(ป๓]เ)hษ\ณ”Ng3ฯ:ถP๑z†ืฐพtช๙|�Uvvtฅs†R;Ywƒ)กฅ™47๑ŒตPภM#Y้’zzฬำ5ฉพก3จ0ว8i‡.!€8@ฒŠฬ~Z €.‚A%”ฐ��เ^๚�;gๆย„`�Šจนฎ€2*bตO0AJึย๚L*2D/ผ๒R๚ยOžl:ๅ+dูๅ<๕r‚#™b�lz’>๒ปQ�jPYฉ3ญsฯฝšuœd�—ั<F^ P ำH›ฦF–@kx‡ณU•๛aƒึ‘ง๗*†[ช"…U๐ห}ฅฒฟ๕ตึก๏›˜ึGงา! ๊:ZษŒ๓ทU2�:พฒ‚oข2ฒ|›Iป�kQซ.eW๖‰๛g› �เL0ฦ�ํซหK�o- ™V๎M๛ื@ะuช~ย ฟฟS๗aจ=ัeทิ�;ื+€}2vZศ๖ULœฒo fค›�_=kT‘/ebฏ˜*š˜$›ฦUจป�3๐ตๅE‚™E๖AI๖˜|R 4—๋*ภvXฺเ>Ppl9ฒ€๗-km‡Z็ุภV๛เ9>ฌ๊q”ผ dŽ>ๆ^aBAี_็พC๎฿ปˆdw๊hCH•k›Ÿฦษ%0dฟ;/‘e>ฺ9ฏ฿€๑นํt�;ึ�์๓โ‹ฯ6sฏฝt*ฦแ�ฬญ[ฉฝ•qร ฆ๘>๖;—…2|๗ašแzTpทดI0ภ์ฝ›ฬ‘ภญmWฎ^I฿๛๖ทำสยz่^x=�o5ด๐๓Cฃ”เๆg>ภAOouไ1NีุNYBYมฑโ(ฯฐำŠsนh'K$€๖ซc๋=x?ฺ‰ฯEึN†ฑ฿€!ดŠ�T„V€DอƒMํๆ`dฐiฐวv ‘ํฆM๗์ =f�ศ|’qตซFะJ�.\ถD Jมฅโ~ฎนrฏก+�€`Eฌ�ห,ฑญoG''ั�Xฤ˜ะqฝ์)ปN(z[ล๚k๎lวๅฅ๓€5m=�้ฝ๏7}๐๎›\*ฌ1A็~ฦŒส�•kต u0†, *fฏh?ดiุ@A-ืงถิฎนฬ“I_…qmIgฐ/%ฅผะkภ{}ำ†ฆO5๛Eเ(โื@IDATฮsL๐8Jo,9$ ฅ”แฤ*l•euฅ2kู๓‚+ฺe†2ฎ%ึใฦ€3l€ุ K*:\'4_ {a%_Oฝผ๖cbbšฌ5v๗]Aคryเ˜5P ฐๆ:0 ”…bซ^A%€�ผงLธOƒฯ"๎yต๋ZชFŒŽŸ*ี-*เ ํ€๗ทX๋ฬs�jl๙!ื)เฌ">Kฝmฯ์ุ์ฤง้ฉลt็�ˆฉ�ิจฟษ5� พ๛แ0ฬด 4*8/ฆJ^cํl!x9—ž์0๗‚ฬŽ•๋ฃปฟNนว&kฑนฺ<ฺem!nฬ}ษ@ด์Qแ^ห=;๔Wฒsแy€� ;nง…A™ฏS๖พ๗,ำ ฟฏ ฦ^๋ฝk/พ๐7~ๆ็�ํoๅ๔๔p็gณ๘dŒภp๐ษ˜‡ณซ๘WŒภŸ๛นฯท�๚�๘~&'ฟจ!ŸŒ�6YJลท žฌWึษ๔aำ ฑฏฆ‡„ฮ9ิSƒฝhว4x!ฟค‘้œ่ศx˜๐ฟจ�ท�ฃ๖˜ค”จ๕ฦฆFฤขจ‹พLๆกžบำถ62ฃ๒ฅ8ิfงฆฦฦ8%r๘[k8™:Ÿf,ฅพ—’]๐เ์ํD๋:WฎHืŽ_โo8a5ฉฉป‡;K�ž›zต ฃcS๊จ‘—ึr@V@eœ…nM›'ฅe@ ๋%Oกย๊ sพฦgเขล๛K;ิ๙ต-–T@i2%QPƒฅ\iฦก`L ม\ฒ,Š๗HY>แ ็ื�dขp@�๋Qใ�๘�ศjค)ฆXฌใ่M๖ †ฤ*`J” aฯkˆฌ๛ไCS{[Aกญ๏หำI ทG)€ekaU็_รนwฎฅว{เห6Pwโyะๅ�|8๗ฮกูณy:2$๒‚aอขtC…นtšE�}}63@"มมภ;ยกั้–ูbษฬ๙มกT�าฐ‘ ำ๒๘hš|๚˜ภIต๔*2็8m�{ฌูาิQ_ว|•u„ฉเ๒Aว2ํ6�ำ…_E0l= “ฝ^C ๋ํw๎เ'กG3^N�x๏เE2z่ ธŽ!~๏3ฆฌrฦžrั๊t`*Œ=บ›rจีธภZj‹ฺ�Eส๚o�L9ะ๏Cํœุe�S�\ต็P๘ๆšํKม้วc็ฝธ๊”.R)๒ๆ_Uฯฤภฏณป;๛œฟ"ฒ&ำ“S้ร๗�Ooๆ}วi'Vƒb|ŒŠC๖ไ6N๕.มฒ4RA&ษฮ�.AŽM‚‘Š �๏ gKWฎลชq `ด@อฉฅG โ=}�˜เo1บ ่ด‡ธŽ%�๋ว�ฮ�ƒb–ษPX'ฯŒ"ึVฐดต๓ €&ล€)yf��D<)่–Pcn ๙๊+ฏค›7_&‘ ศ๕ฎGภ411จEI cดGpv`ใตG_rZ้iผ6ŒU*c.‰กX�%2๎Sย331รzฮ:—–/`šยแt�๙มี ฮugะ_ฦฝณ์ษXฎกN2lอถp*๐#@ƒg€@sฬมํ฿–’™:๛ฎ›QถFุZฏษู`ฺต ๛Œ‰฿�›6ฯ๏แh<๒oŸk–ŽX7‚ทจ‹W/ศ4‡ยนL-iึำ*๗๎~��ฃ๏oF†ฺ์ณY^C6,Yนฺฐ”้๔ฐ~พ๙๛_TDpณฏ ‹ึ‚ุ์R€wลa›�้ดภ�ซdTธuzhmฉlgฐ{d:ํx644QzณูwใฅXŽฅ6พŒเ�Žฺ ลๆ,!ฐ5๊&Twื}ฯknGปขฯ’2ึฦโrขqฐ&\ฦ:ฦ‚ต,‹+€ ุา8๎หŽ/A[&X–๚^,@E–|ƒ ผŒ์miEaบ�๒e‚nฦŒ1�c�ี‡™G<๐[฿๚ฃ4<>ฌแœ%aํ้ฯกe'ฯ+,cโ)�X�ƒ๙ึCiˆ๕ุฮฟึล+—f�4ฃ ภLฯŒŒ‚�q*pi๙›Aบืฦา ฯs'pฅฎ;ึ๖@„๗mๆ™ayรgดŸ๏™`ึ�๓ขณ“เp๙€s์ฦี+ฉาไำgษฮ3%ฉ[%6ƒอธs๏.s~t<-rkWตm๋ฌO๑*u&HpYœ_กKg5kU:�_všฐ,Apรk๐ฺๆƒžฅmฏษหd‰ln"–ษEo`ฝNฏ฿{)ยฎ tห60`๖},ู%จฌrkหณ8#ฯธจ[Rอ�8ฆ�~ฐ๐N*้Œะwฎ›&จtC`?ฃ๐‚น‡avฤvๅ"€9เ'๕ก”q๎๓ŠNถดtค–žO)ย1% %tใ`๋‡ขZMLhฏฑถXท–„O �ฌ~ฦ๒็{&๔ฉad์ู$ภAฎ�ฮ%>,ืP‹Iเ฿5d�ย*ึต>Š@ฎ๛สPืš~Ÿ]ดLŠธ��›เf$“ฐ๚‰ŽกkฦณศdD!พ]|l๕$ด‰ฒmZศgู …%™ถv7ขฅๆP_'kกวแ๋g็lEฬฑƒ๏ื+jร�hƒ-๕jxฏJฮ=mŽ  rฌ…๓�ํ้๓_๘ฟ๙๏�{้ซื^�ษwธ‡€ึโฮ�๏l>#p|&แ์�ี#๐ซํoฌm,อ-ฮ~anq•ุEd ้ํู`ัืฉ>m&ำzPk*m5g+0ฮสขิMถน‹ ˜ค4๙นฉ)T๔dE฿จ…33ี�uGนแ‚|ฎ�๏Aฝๅฐาy-ฆ๎๙งZgฎ‚.าyu t�งง้๕Žร‘ ลตชQมฒZ‚คšจ‹žž!ำH�'PmลŸJŠ+นY+2ซาPอบูยP ภ๗๔žฅอgi~ธŒ�› Jฺtฯi๊6่ˆ๏€z+�่AnFูฬ”ฒ‡ฏ ม!Nผ™Ÿœ|ฏW}$9�ฃ†ำบวf€ฉ€Žํ>ิE_oะ’ฯญŠด‡ฟ*อKห บ vะ;qV ‹กyใใ˜{ธ;พ�‹t ผ/็ิ็{๘W1†Ya?จ…:M ฮ‘s๎CJ|8Œ{ะyํฉB�หฑp�x๖”ถืถฌ4\ต,Z`t๗๖ฅ*๎‹Ž�พ�ฝ43�€u‰ย{[ๅ-ฉฅฃ5๕œ?GฯสT‹;๕ม[i‹ ๑`WwzAภho#egyฟn2YUidb2��ืส๊�45ฝI=9ิะๆฮsŒ5bƒ๊ไTใ๊Kห<d*.อM�ƒฉตXK0ีH@,•�๒ŽIึc ™.žD_jจข<Wžr…'!"Vศธ4‘1>eฮฬ๎๗8 #p�ฮํSy็วฯ�วม9ศฑ]๑0N>c eO๋QR_'›ถMง‡…้Z;๒51›ทC,ฒฎญ (ื8†�d‹�3๋ะy ๐G๋L๕“*ฉ๑,B?แยๅK้ฦงn์TRŸ:{ฺ,ณe&=��ฌั“4�๐Iฌ%ืขฒAv0|ๆฬjZฺ$ฤREF�ฌซๆัuฐw๚๎ี ๗\อ�๔> 595D ฌe฿๖ Œ‡่YOะ 'u๕มZญ๒šซWฏG`พ@v_� ์okI๏yS– ๛ฃ„lฉ”imษ๙~:O8WdFy]ะkน6ƒจ €๒u.�[:มfŸ‹Yฯ2๊จ!.ฅŽ{‹ฌฺ6{f†าŠCุDf ญร•�lKพฌRพโtิ&sOาฒี)‘๎ุP js?้ธ:ึ�^›แ�qฯ๚uผ์ ๗โ:ษู๋๋ศHบ๛ƒ๔ฦท� ๋DZœL฿�งฟ Dtyฑดหน8$๐5\4-cN l-hภ๑/พ๕๋2N!Z•ฌแœ๋ŒฬXC‚ฤŠปZše้ฬ*o๗งt฿๙นY˜๋€eฟІช]<๋‘ฤฯ์il๚‘h(๗uภนฺAผวพ:์u;๋๘�MฮฑYำFภข}lคญSหKต๓Œ›๋ึ๕’=g=ำ'�9ep{ฤ=n1ฎZฯ_ ลํฒaZ�`@œˆ(#@ีๆ B)�YD0+๘ํบ-Gกž 8?ึp�|^0[ๆ��ฑžนฯ4ฏQ–Œ8ฏQO‰}_B ฮงnฝฬ�ฎˆ@�๒๙บG”ง@�1ึv�ะ… ซ 9ธ)๛zšr˜ฃล™™๑vJ]—ฒW�งvฐ] ์<ม๙|ๆœ� ]…]l)ท{ฏrFวOะตคถvร‡"ผฒ"uภ‰M์จYx๗บ�u๗งๅ^ WXFPฅศžฟH๒ปcฃ่m@�sหะ(kู^†@ฟจ๖Kf}Z"Šนฑ:e<]mฌญํฉ&ื๚ บž?ุณ >ร–ั]ฝƒ์ก @5l ๖\?BะาณbฦDี�๛& ด7฿z+�4 h€OF๖จ‘Qว�ฃงฃฑศ็:ml�™ฒ…$yไ™_pไšั—q|CทโcฟO-ตH—‚eภ฿eบV๔e+:ฬ€ส ๓’้‡ษว๚M!จ CภnฺจGl@zทตฺjอSnถดH๙{F;๋9ณLวตละว—vว๋•สMเQ‹xcša2TU—,พ๒้W�J๗ะตG่๐์ณวู|ฒF k‘>Yืtv5g#๐�ื��฿?�฿��?gฆ๎�ญ�XYนuŠณsˆ๕ƒรฎฺo1A†ต–ee8ฃdgƒโ\เu‰๓�หคฉ๛ีCภEA-๛�9€s:พ�ฝ‡*ถแฌ�fั๖^ึฟูซžw–รมมŽต๚�ฎ–:qญญ ๎ t+hฑVSืูช5t 6 PV ฯอฮ๕lK็๚†‚jํำ��หg XH_ƒโ๚ส*ยySใ�ตœะ๖?#•็Z=๒ไiบw๏adฺอ4-“๙ษา? ฺษFfp>ญํ”B้iuŠs4rดศh…ฦ฿ข’Qฐ0;oWOoฏ7ฺq็เœHWฯช๛f•๏# ๆZรQลyะัตŸx-๕"zห๏‘9ษ!ณ…S$…ทฅE~�zG�ว—�ฌ[��!ฐ ์€Z†ำ๙Go~?j4-OPˆง๎ฦqŠƒ›รVT฿ @ภ"9^ ์u$ฅv›‰๔๙๖[7เ’b.]RgำvgึœK“TŸAGCGึŒจ๏๏�GTม๏๘ู้(๕8:ภตตedzRe=ฌzุ#8K“S้ัํwY3=€D]ิ-7ฆึฮŽ >ๆ ง‰ทำ*Ž็ีกซ้๚‹—ฉ“ทc๕ปิ๊NใpQ�ร๗฿„�HMs1:•N8df�W่U3฿'PVmZ็๓๛0๛UL qแjzแล๋8‹0Zิ28X:1๗๏>œiH|”�‡ั0—�๋ณC8๎ิ์�) เ~๚U‚*ภ+ษ๙iZ4Tญฒ๖ู่RE6ร8์ยrะก/ยAฏi ส^ฒ%�2Ÿ•G�๑1มา$š Puงวงก’fะ่hHeจี เฤแ0ช๓qtฒห๘›๏ฤแรS�ยฉ,&{ํ…‹้ำŸy9ึDc8O=้�;ฅ12zญ\๋ /^ICด™|๒๘~๚฿�็฿ฤinคง๛@ฌฏ5ฬ�‡vฏ(fOณTข๏ป œ‚k๊w5ถูถฌ–์[k{0_@๎฿ฟŽdW‡ ฏmˆ–j:ฺฆูํŸ_”C{ฌ&๎aเˆเŽ@M็๕˜`fวบfส๑:ๅD้ฤ`ษๅ0ยบTฌ‹(<่ๆ•ะกe๕๖๔ม`ขn™เn@ฬŒeๅ*ชว๏fh?‹€Xดศำ๑็=์ณฯZว‡e๏•ณ›ˆ_๙Vศ€ส๐‘อ 3@uku‰ พบ ศ’•Sm~‹2#[�ล๚็yฑ๎}^๗‚_ู๒ ๖็๛ฮ11ธ3N>€๙”ว>�Y^I;kh4`a+G‡า ‘6—ฅะฉ)้*-ทผ‡=F�3a˜ ุฑหJ8_ธ~ช๖l๚่ฝ๗VซQiวqวcWชa2ศfช`ž.h‘�@ด“อฤฤณ่๕^ =?[WSQ–aยh'K๊ิ\Ya์ขŸ`Aหฃศš@ซŒ’j(�–*ฌ,.P�5‘zXGฏ\‚อฐœ�{๏2ฮว์ี๋<ิญร‚*ๅ ุ&XฐŒเ—`อ๏ุK็ |k\ท$“๖l[˜G�ฮถ๎Jiนหyฤ Fภข vMฮ‘]C””ฌ,ดv[{39\;�>lุ1เห!ข|ๅ€ึ }0�t (‡ณov’Œ7เำ�ัมmoะญ—ฦ)—ใฝ�ฬฯ�[้2๗ถดผฬพ(1(็ฝ๖้ˆภผ �บpwKAฮYืm.›”มŸเa ฅA�…๓uŽ%์�Xt8`^เkg๖ร–รF,,,ฐn™{�€ํฦXeต:�Š๘ะBp1#@ยฯฅœM–O(f˜ห๕ั๘o๓wหิฤุ๕น�>บ&18;0Š6ะฬฑปมล,ป ็Ÿํ>`{ะlg๗„๛US๏Zถ๕ฎ “%Zั‚˜฿yฎ<T์€–฿8,˜%#byq…�นL�yื…ฦ`RW=�p๚ำ%ุgQZ nฉ7ผ๕~‚Sฒ๒๊kX๚ฑ…��ภfสธ`ตpX๖H๙ปCภฦ/A~.=๖ถภ{Oฦœ`Gร�์โฐคAญA@K…ฃิ%E @(่ใpOš>\ตฐuฺถ@ถ2-5๊๎jHƒz กส“ไhญฏK—†ฑ‘-๑๏R์}#ถ�{ัภ๙{ธฒ<ร๏ฤขซ1> x s‡น+�xoTย˜ฉฉ#iภnn๋ €๔�๗฿ๆ|ขkk‘eฦ๋๓`i0ž;œ๛QึยZ“w€ํuฯrsœ1ฬ™spRศ�UณวL<รeŽ ๘ๅ™"๓TL`ฅ”kๅW๘ฌaฦฯ1q฿๎ภ[eฏœ๏a�P ธํ>{†+€dศภ�•ฑ6'ฎฎณ]ุOŽ�ุศXzFษ‰:ถะ”I"P R ำ์TYV–ะY๒( _ {ก‚าผ–F|Eน๙ง“]ƒ็ๅ็แซ฿4p*ฯg#๐‰3เเ7%g๔/ฟ๕๚฿:��ฮ฿ฟ�๐�+ไ 3Xึ้“1๑ ˆ>6ึžyJุgืƒBDXํHa>Ÿoด‡ฑ}ศ ฤ †uEฮ�ป�6(็cถ‚=@๐ฆๆ‡A‚fvP0ุ0๛�ไ้(ืl๛šน�็9รOžฤ{จูฐAๆPškoฯ9V2_ฬ�๋�3ฯvgุๆ=ฅ%wทwฅั‡ด†Lษ็�Oธด%แฤbK๖/;M๘\ิ๋Qonn g๔๎ํทำิSฒ—vS1lะ›žโฺUหuqึฦ.NฏA‘A“€˜Aๆฺ ต๒ฎซCX[]*พšQ‚�P\�–ฑYฃeฆsกxŸmuขต…ฒt�_ฺIม@Kผ‚๔๏~hiฃ กีVะA$ฟํTึศH6ื7’ฌยึตแ —D ใต ๆ๐ช{’C4�P�ฤฟณ"eŸพ๕j๚�wฟ-7บํ้้ฌ๘s�วF!่†ฝำา ณไu4๎M5g œG[ดฮkr˜๗"Jผ-'Cห†ห6ณ�Y�fMด๗๗‹ฝาฉทdjj*ถฟ@จ๋จ›kุ&(˜P4๑๗fหีฅศ–nฑW T\หD=ฑf/็สŽy(5”aฬlผศR)…Eดภœฝ๛�mๆ๖˜ฮฐoฐ”"X.` • 5>[`œ่ฌๅr๖ภBˆ)ข๎œธ>อร4ฑ�ฌŒ5ำ๛m@Vกฟ ่ใlฏeา 6ภฎฒ ผฯ�B์2NMุ1RๆWe?(Š่พ‘mแ™1/ยŽ0v‘=วถศ`4ธT๖์'ฬ™มมธ�์่ งึ€ถl$(i�„ลฑฆˆ=ส �จฐC�ze‰ƒƒฌG€L'mw9Oy�"].vฌ˜ต๖ๅ@#ฅ‰ัQุw#1 KCšฝ{อ3GFฤ6๚FkุUK*lฉjkห�&รMฅ๛ห๕XKึ�VˆฺV”๊.(ฌ'ศ่ ผxศ๊�˜Mw์ดmv%1˜๖s=(ึธเ ๅw–†Hbˆม?๐gล ‹ธž“cDi�ฯำAโ"ปฎ๛Vt›๊,ยl/ฯŽย6Y็œx‚]™ ›ฒ–’ืmKแฎ๎>�Pา๋*ภ_}เ๗โสFุ ฌƒฺึ`j)Ic<._บมุWค'#ใุdๆ’{ฒ4,ฎ—ตnูEdๆ™ฏR์~vŽดcvษ|ŠkW;+๊ฌ6‚ฅjคไz๙ณ_:หF†>ฯ |Lž่ฝc‡ดฯฉ๖p'พฬGDh›ƒEแช๙™I>›๖D=ฦDLtŒŽ C?ฃ�ล๙Iะ๗F2œuธm4R์gฆ'AืKษQ�ฬAฟN�jถ๏๚ -อฦ9้9|ศฬMฬฅๅ%๊R}-็.ฮ]ovO็$ุ�ปAy9‡—ะภภ เD่�ศƒ•l'3๘]ถ]+a�<œหธฆ@ฮฅ2คf๊Ÿ-jจ็ฌ&(WqHว[ก0๛_,(๖๓ภ๛ ,๘๏;�ฉO๏"8œD^ิ…lฑ๋ถม^)@‚4[ซRdณตž™…(แ๚ ฝ~มƒzธ#ล$;iิ:งฮƒื„:U%8t*'๋€ช้ ๓ิy๗`ฌBฝ6ใ)`Pณำ?ะึมฒเ‰ส�ึ€/OO“กูaฝืFb๐%ีำ{l6tlม6ฮฅ:Wฏ_มัฃŸ;๓ปด0ฮฝำb”lt฿๙กิืw.ฒ4~–€ม๐ื�ููวz-จ" ณฤฬ!๓ฅโปNฒ €�กgƒ3{Uม.Bหct1ždทํS UVึ€::RิฤŒV=X็ฺ m†ป��~๖zŸOฐgp@ืัึดš�๚็oเลจฐ‡ด?:๕fBIะณดCl‰4๗๚:t`งจย]€Z]˜Kุ‹fจ฿-ฌฑี•%๔ฆ�์ใz :P\งผฦ ยฒ‡]ฟ3ฯ|ึŽ@ซZ!ุŸ(๛‘ญ‚C~ศ�[Cฏ๐c๛ม�ใ�8๎ma=ม€ …% สฺNmŸˆฺ๗sYš/fหุ�!�”dมด’ฅc9ิ๖๊"ยƒซAoฯ5mม@๛ฉฆอz๊๎๎M=็zำ�์๋ิq�//uฮ„z:cšƒ #ฤรฦ4D‰…Ž�์ …-Cื PํŽฑ0bฅ�๑3ืWมร คeTศfต|ŽกvMpัษั~7’m48–dอพึ9&ฦฦbn[]ใŽนc%`j‡ ม<n ว.A7vHี๖ฟ{ฌ%๗ฬะ• กุ. m'ัy€ภ๗ฃง‘‘)‚ฦบpe•นฏฬ‚3%\#A๖ชฉญ๗f์k๋อvึุ�—R๑I>ๅAำ0* FูS”ธค•SชฒทฝวนC+Tๆat์)e๕้ึOผŒm….พโ๙!๘Žํ ฬH&Q1ž๚‚ฉjXฮa {ฤw]ฐ&\ฯใ๛€WŽ็ขœŠ8 L”q*๖๛:ํ๓๘l*ภลh๓นf๏'/ท๖�xOƒLEู บ‚ึต๏˜๚plr๖ซถ@1‘h›ศC‚ัbZ oq๎Ÿนฑผƒ! €P†ƒ�FkG?>ฟ็Qฮ�0A’P!h่=จตก�ต5็)q๐mnึnฬ๊ษฦ/ ŒขC€M๓ฺธษX–0h�ฟ{Žท ฤu€1วe›๗ุ�ดT„‹cSnlธ^ีผสŽCฌ5์จถ\Fฦ. —GOะฏtๅ฿2”๓ุณ‡X—0<<‹Y“vุRŸ็้ำงกห4๚d„r ;ฐบ,เž๑“*8๓žk2˜˜จx,ฬ�Ž2KX†…ดฑ,a์kj*Žบ{:�มอO}๊?�O�ณฏ�–lทˆQ:{œภ'wฮ€ƒO๎�œ]ู�gฌ๗๚�o�K>|oˆฺ‹‡:ิŠO‰{*N&F[ZฎY็็ข8ฯdc�mใw๖pึ1–eเฟ�ฝ]!ฮŽŽDY๑:œfฉม”5ด YC�ฅึบzX3k-‹ษ่x› \รม]แฐิo๋่ๅ@…šGิุ�NFพž  0กฉฅ-„ežฏ“ัึัGz=ูอuลฟtฐtฌาีF0@Dู"xต^rวFิ�~ฬfฎคฅ—2Fถ ุภำใ๐ฯข๙’วŠฆqญR~ q6N yd้๔ˆดgpบฌ๑•�ฟCณฝื^วูฌŠ€‚ิื$ปฝY!vzฉฎ9•๊8 ^(|๗าอ[‘ๅ�ฝ฿๛ง8>8Aผƒ™Iu&!Gฆ(v$ณ> ๖ ŸTYภ(๋ธศ™ด^TG—k `“‹b ฬุิf้œ๚;:Df หqže5E๖ฬ9๓o�x ฅ1#O๎งwศ’f~Ž,ซษฺกภD�‹๓�iŠ๘4 ˜‹/Qห~-h๑ี�fฝg`ŒŒBฉ�ฦู3;c+1ƒแ 2�ปป8๊�ข๓ช›˜รบ)†ึjภapSห ‡zi[HI�ฟ{็Cฒ&sฉฎ!9’uกห—_ˆ็/3gƒƒv”3,‘กดƒ‚*๒ง8๑f่ถC�ย‰�g|อ๎แด๙”J2$f*�๊&T์p๏‡ผฟŽขโS+d์uบ[คตvดฦ p]#:๔‚g๛PuใTWBJ็ู๕‰ษQ๎ซ˜ภˆ‘�เ็๚ปxฉbY‹์!:(Œ่™ูฤV์กg#ฃ!*๋Mย`ฯฯ2๑๓ŽXป๖kืI�ฒ†1๖ณชํ5u“๊่๘ูฃ{‡,ิถA [ลฬR{�ยะลXฯw๏รโX^ˆ๒๗ฒtึ‹/วฝ:Œ๙�ไ,ู9Zgฒ,Ÿฒ ‹๛�=rJภฃXˆ‚ญ�์ๅ�ˆV‰pฆ5ว๊ Tr–!์ขาJ๐ิG;็;ˆฯน–] ใ‚–A™ู53ร+์ัYœ�พถศfnิูŠฯ/žm์ฺ*๛OaXY${5๗>cค 4+xเ—{F–วโ"๕สผฦ๛ {h่bŒ๗ฐ Eฺ์Œต๏+h lฒภดŽปปำ@๖{)„ฌคtซ๐LAิ ��ฏ฿ผA๊฿๚f€ญฐด,9`m(Bบร๋ ฑั%ุ\[šนนiœv€ึา"@‚t๕๕ ุษ%ๆ1Uๆ�€4ดQ็๖yท )ฮ๎w…*อ๘ื๒:mXดa8๐๓ ะี•0ภจQ๗‚uัA๖Uำน ๋ฬ€Hต�'l›A™ใโz“ dว+‚]์ส@pW?bs€dZง้i:ฌญ!ฒ�ย™า&วนฒ๔��liž๖ฬ๕ถุจ{ฌ�ฅyจ๒d7ท”:{{Swฑ9k้'ฟ๐•ิP�ภg’=ฆLง๊|wO/๚!+:จิ๎ํฎ!dy…๋รฦcฃึX w~๐a:„้ภภ1ๆิป ิp>ศฌp฿jg ศ๙๗ฐฃmภn (จท >€ฎZkˆ๛อLS๗Nt)‹O†Z{{k๊‡๖พ0ผ ฃฮ=Z(บท๏™“fX[^Y0€gฌฅ๐s<hฒ9‹*ณหฺ #*๗s`9๛j‡5ฝ!๘Shฮ๓ภr5uขkCฬMv]\ .mฒ ชOืˆมๅ๋\�„์WII!ู`์gW๓ุŒ>…ๅtั ;+˜m]��๔ ษ‚Y˜=Gq%Ž=ฬ.๋ส V<kIภอG!�‰v[P�ฯทโ(ื‰7ห\ฤ €,’˜ฆœq_ย1๗ทธง ฮ3ืฒ7JAbŸrฯผŸ@Ž๓ดKึ]††็™{:ุ R�ฑฮk‰ƒ<ส,R�ฐŽภถซฃ� › ]M( iฎ…ต(%~ยบp% ^dŸs�6ญm]”ฝ�Fฅ�BJYOห€ไv’ธฉชoa-ึโPาIYT V†๓b‹า+ว๛0ผž2UฮŽmส1—–ท"p๗ผฑlฦn‚2 a ข)๚|ฐ‡-ฯฐ>ุ‘)"ภ๋|ปiฆรบyxฮˆ ฺฅฤฤ‚ ๓ฒˆๆู็ภี e2ž ฯํž๛ว™�ร๗ย๖๔tw8ฆิ;Lฟหsกทฝ;ีcรงฌVW&ึ.ถ”• ธ Pอพั‡|X๘=@ฆ‰๒„ƒขขœัมมม��ฟ๘ฺ๕หืฎฝ8‚ซ3s๖8O�œŸ๘):ปภ�็|ํkฟผ_”{8�x๘ม‹d_�j๋š"˜โคเะแลฑNํAb๋ม2 f#ืศ้ศษ 0X๖กใ็แฯ~—e``TRžoูB!ˆท�jษฐ5’E.ล‰ตx�๙พ็‘ษะ€Cฌ ธ�l+ู ƒง๖ฮn˜Bมpˆ ฦ=TซZ"ะ�€F\สฯ;‚ hทjงด!�ยน_E8๎‡oฝ๐@{ซ=ะq}๎AG�,›YQณ;ถaหx��aPศฬไแ๐๕ซศ~ฉฎnึล`^GQฅ`A� †21?zC34ห๋๛๋(ฺV2ƒำe$ ์>Cฤ ŠN˜tNWญ[๏อzbา>ซตญ-??ภ˜AH้‡๔ปผว๛ใLqุ›‘:แšณŽตba ฮIEวt๑BAฏO็HpB„฿L„L้ฅŠ3๙p^"ะcMเr8๙8&P๋jษdpุ3ฎ๘‘8Sะใšณ”"|eะฑtZ๘Raygk-�ัท~—ฯ ‡๘y่�ญฬ!"Ž8ff฿*ชะ-XžOฃ� Uเ�tถ๗๑{œ5>ปม5ƒ๋_gษ๎เธฌ๑zZ=™‰\^†๚8E๖ ‡XMต<ฬน. Lค[;ฎฎ๙ส!๊›h๛ˆ—=3=eด…`•1'Dฌฏ™๒„;ท?Lกะ๓�ซื.ฒnฯE€ืุIŸph๕�~— Žบ��กTra:[bIณ6xิแฑžีq—>k@‘!sŒ�!ซ�Bิ0ภฐtขผญœอ<ฦ๘ฺ -(Mme๗KฬHบ�N˜'๔ฒ0ญm๕้‹_๚Bะ๗[ฺ@pTทq>k๋๊ƒi๐์ู3@ŠU~—Œ = ืฅ !‘M์]็WัNY2ไ๔X–์aœg�. ศ„€›4ii๗Š๘ๅยดฐฦต 6‡๚ฒg,sro บWฅกึ(๕œ;ืo๖lmy‰}O2ฟG8ว%ผ�ๆ l(‚ƒ๗โำ�๛d^ฅIdHkWEš(]ัษืู�{๋;˜อLYE0H ๒3Œม6เ‡5๊ง–}ช.YถSๆฑ†7A0ƒd๐~,Z๙AC็ž†!๖‹ŸeV฿ฝ#๖�แพs๎u|wฏ-ภ7๖xุj์�gฟnS๊d)M€ร๛ีมxX�;‘าNะษ<(’&ซฤ๛฿&ญkjN/ฟ๒jบw�nz๗�hํ์๎ ะ ึ�ƒyฃ#k@!>๗ถๅ_๕ณSำL๎)?w`�ึขชํปzกLd๒7;"8ฯA็ฆ3ุอ l`(ๆc70ด‚ผ%+ฑv�PหDั4ํeeฐ;d,(ขiDk;น–ถึธฯ•ลฅ8;ด/v[๐กCr9`�๔3ฺ&ำ ม*ๅ€ผว_ฬ™m  ๖9[�=Ÿ>nสd‚g•Kืึทษ ีW๐^+ยต‡aงดน์A๕ผn�>ึ~96ˆท[เ›๛Z๋�}žƒ๔็Œเs็{ฐ ใ>eฺ•ผhp๖๑9J้|PIฒใ jฐŸvŠ$sณcุ้MุC ฝtJกใฮ;ฝๅ่€�ˆ๑ษฃUcๅBŠ๗ ฬฌa ต–GZN๊:ซjํOe �\{.Œษฑฌlw๋ตอฮMฅ๎�f/,pภ@a iฃgภ7ย?;ิf๒\)oฯ5 œ;5— aMh;๗2dŸ ศฬ๓ฬ,b^หG�lํ˜,ซ]Jธ|ฮ`…๋ส๗*ดˆุลๆ,ณ๏ๆะlม�<›žN/qฏ๕”ŒF฿>Qu0ล2}�ท%g=ม>ภพมๆศ(Pวภค”็ด็ตฌˆZ�ฃ€˜ถ�o_บ|แฏพ๘า‹��—�๒ฯ�AMNอs๖8›๘ฟ=…›K>ปะ?ฮ#*›:~�ท–ฟœs๘ฮุ๘๐Eฤ๖บถp�=mkT ฝ]šจ5Šา์w jDเq.Ž8œ#(ลัVฅ]๑=3T2%B›ษfคํ˜ะP_Tฒ|๊ะฏ้๋๋ล™ยมแ ๒ภฒ๎ท !CVฯ@\%๕uO;�ผ๕c™ๅ(i˜ๆ0ลัโฺชจํ-#sv�สK(kS ๒/๕ัŒŒNขตีEP/—p๏��(ฝ๓ึ๗ำไ๔h�เํศภU•#r7@kKภ kฅ\zฐวธเlY2ภ[‡#eozL•ึuŒฬย่เ�IลTคัถV‘mภ)ฬ'8<ฅn๕`ฃ‚ฝ–€ืๆZ–p|JV”l\>๓|Uำ๗ �๖ ๎๋�wพOvp%u๗Ÿ'pงซNp^>€F ๔]๊5q$s™ำrน–z˜8อพต๐์!ฦYLูร>ืx@บF๐;=1‰SmฉH%ฌiZ1hK 'pภI.&ะ9ึ้‰ภGุ๕Z�Z•^ธy5‚z้๔œ๗ฒส๚4ฯZฑ๋†Y็๏�NฐŽJbT฿€rฺBภฆ\ภโsำ่*,/“อ ‘*‚z‚ฆBฎMฅ์|ๆฬlฒมด^บTl(–Eœ"ŒตK@ง,Hิั—อจnh™ื‰e๘ู_Šผแtณ6ืฉแ>";#€เ *ๅใ�moัึญน6ฝ�๒‹˜7๊|QFojkฆถฝ‘y, Ž‡ซ,NI๔A_&ฒ \cYซ่*์“rM$štM[sj;3ƒศ*2kf็มt6C�ย=ภ๓}] ™Mรจ9fŸ RIวŸ'ซm ื๋2ะฐQpิุๆแทCฒ†lT,•น'OศŒe':p�๙8๐:�ฮฅt|ƒƒ"kํK)ืpฌš[�"จ•V?79Myา(šŒ1๗ฐ ลL๗1มศ1YบSE( ด)ูต-Xช๛’ภฤ฿รy“V/ฟุ9 ฺ9?ใ†ง\ุุห+๗ŒŽฮ๕sฐภ19yแ5~หๅgVD<“‰ญ!˜๒ณw่:“a็‚ะbฎCNKŒHgรศ๓ะ๓ภœช�ภขทอข3ช๋aฟ์ฃAฑฆfยฅฬ V‘๛Jภ>~6Eญ฿Q‰เพฒอ๒.u�ึฆ™p0–ํร2�ผโ๓eๆฐ'xนฃ๗ อุถ; ฐ  ธ5��l๋wวฬนs† $เƒ บIsๅ €YV๚Y์ูฮ�E<;ฐณ_��ซฉงฏ‰Œด!%แ148ภบ/Os3ic~.pN?}�€�75ภฐ@เฺ:ฅ“บb )๕<เ๚วž˜aฏฬ@ฝ ณฒฆน+m.อะ็%9#ฬบ%hา๖๑p๛ฑ-{ล}Šmภ^ฮหเมsฏๆ๊ฑVelแ“ไP๚ ณตล�n ^˜มf˜ผ•งmxฑฬP6ฆบ6."‚Uซh e“Fœ4ฬEุ?>—R@m๓)เมภธ k>๖vž†Q@“R๖hKc+kFอ›ีt๗๖๛iv|๖ำ็์;ุˆ››ฒญ่0x� xfขฉฒบ๔ธคข่๑ลษ๖ถๆ๐Ÿ{๕W�ย/�ล7/_ธถ๔๗^�{|โูใl~ผFเ 8๘๑šฏณซeพKษยo�ึ,�๕�ญวร๏%'ธqฮB ƒฉใ:a fน+2ปhไe a�พจ{๔๐ลPฯ๚]i–:–ขํ�ฎงง7]บ|)cณ์ขอึุ*fhMน-ฦf9X8•่”0�ต6ฝ๗๖›๚ฏCWทฦ‡ฯ–F™uดคDฮLAต†Žจ˜ฮRUึุ5p8-“ม|t�!�†q&�‹สชฉแ.ใB‹Cีl ‹#›8uqฎคฮ*UฤXsล8บึ);แไ์ตvv๛ภถdึ‚z�3รใยa8วซ๛�2‡ฟูฮฌฃฉ•†ฆฆ,3ปOภส#Kค€S”!€๒๛<๕ t‚�l�ญsUŒฃื�ึ�ท=^ำNVผ›พฯใ8พฦƒ�^ฮ0~yM:ฮ:๚~้Œ™ณงปมŽ/ร‘ยAเsฬะ๔ธz_ข�๑œB)K6สษส๐0C�Ž…š U84—ฎฝบฯ๕ฅ.พTฮถVต‘w)า๏�๐ะฃ› ๖ศ†sRKน๏๛1็�ๅ!�TMถชˆน่ƒๆ~แล›Œ8WRHถš<*—ำ้o�3่ึfJo= Cบž ฅGฬ•๑]Jw68ร‰็�ีz(ภK+ฬชฃฃC=ฮ�ภฤมย�สJ๔1ฯ'€บ๗เA~Bfฑดฆถt€ำช Ÿ�‘๎ภ2˜"จzx็>ตๆฌI2fฎฝIjยอึๆSGmภ`ะ%{ภ ฃP:…ดœiะ ๋Uด•ำNส1_‡ฦฟKฐlVส2![ฝษ๖) 3เคS—ภ์l)™ฌ|ึงe=ต ีิ•RjภฯR:Ue7TM Okซkฅว๓Qzp�>[˜kไฺ&Fวษrญย AAŸตhMฌิR˜ึŽ6:I ‰ฐU–€ตนีู'“ L๊บL �™ๅs)’g๖า:z;Hน6เtฝุห^—ึฮ2I๖qชkชนฦถŽK[ภq6ห ‡pฅK8ป�ป‹lŸเZFˆ�!kฤตช#lเ#Eบ๚_�=lมณด`Xงก 9 ๆ"g;ฑ็-Qeฤฺfเจ=ท'ฮฃ๚2rิ,;p—่Lฃdn0,่‚‹พ/vR๛แZ“�๋�’ญไžใ6ขCezม‘‰v“๑๙fžณ‘Beิo๓ตง๓h‹ฯ1่#ศฤ\+x™ฅŸฆ๘ม l๖๖^œwฤ+ษL๏b7๓˜›๚ถ6:xิวXIถรม�๔t*มั/-F/€ ๋@Pเ:&&ฦ*ึขœภ€*๊ฬY+‚ชฮฝBJฺฯึ๖๖ธ ำญนีด x๋sŸก฿งธฆ|lัZœฎ—#nขฑฯOีr้้๋M—ัๆ˜šโ=x์ปใค-๒�,SศQFNึม”bLC้aoฮ“e5h1ศ๋ขC]‚E3๖ุ+™q2ฎ,_ฒพz—าG=g‹ฑ [ไJต—ฦ~ฤซ๐ฎ-�Dภ.ฐอ–‹“ฯbบW ีอ9เฝึฑe�,ํ€7v šใZศเr฿'d๎=?KฆM|ผึkฌUb”ef�5าุN›a˜Iy0๑ิ Xc�eŒดUd เฬธyุ9†ฎ \�‡๖;๏ฐ#v Tˆี๎)‚�lฯิCูJOG'Wˆ�$Yfๆ๒๑ฝ๛dฮฅงฉB–KWw0=฿�L็ิ’>๗UœีŒ]œคใ ฆ&ฤPห้ˆฃ m +—Š, ๏ฝฐaาร๗cูรฬ ๋ว5€ฟs]๚{%AQ๖,Cฬ๓7›u/dๆCๆ€คd@IDAT‘=ํฺุฉกแๅOฝฤ�f^ ๎kiYสEิ๊+0Vถกmi๋ค-ใNZ0;DOษVถœีถ‰ิ ถr —RŠPฮk�‹Y–ๅ,…q๎Š?ด@žฅR๙€๕อดd/iฏำ ŽzS่ผ �๊zถ\,ึ5ถJ- >6ุ_งa“X3๚LŒนI—ƒ@™ยขf�(qEฬDZ ปNล_Šyž๏ตE๛L็ว๗*˜“eฆ–7(-iaqz1MŽŒฅ'œฏ+“tR ๊ถน’3๋๖•อU3.fบ:ฺ1ข'๓C‡N@ฟLgŽ_}้ๆ๕_๛~้?�'ƒ�็L€=ฮFเวuฮ€ƒื™๛ใ~��฿๚ี�ej๘ูGำ๋kป�๙น…Mช“[{šฃ-�ภ์ฎทฎN‹5ฆ:ัข๒�qขrะxh่T{ะ{ะญำ�R‡ฤคLฤaD๐aฦัพไ[d ๋C�์ฆวฟนฅ9ฝ๕ๆทรูซฉ!K๘ ฅท็ซ(่น]�ฝQf`๖Šh‚รŸC๚ฃ��'c/r็รpพ h๏’U‡ZW•]•}๋?  ุl7ฅƒt~ฎQง?ฎ•๛ซ%˜ฉช*†ขฺž๚ำา*™จ˜mํŽˆ‡‘-ฺๆ๚ส*ส8ภํ�   ฬไ๊๏็ใฤ™q๒s ฮชษพี@๑ืก‰~ำ8e:+ฯบZ‚Yฃoฤช- l‘ง3WศาK7oภิฐ;u๕oซซ˜�|m‘yอ~–S'ศฬฆ€@dƒqxผ?๋Du$ฬ(˜‰‰`gR@G 2สX7)ฐ: >ผF�iๆIOC:๔ฒ.ฮvuญ�อ{์ฝt‘€เฦ…zd~ œฮู�ฬT๚�w�ˆ@ึLi ข€vg(ฤ!�#.ๆ๓JŒฉิlD\ช ฉ5๘œ์\Uฃทิ+€%2|� ตฌ๓ํ•ฐ8ม;fUXr,ว† …gO]๛m{O…จจืtŸ# ‹ˆV%บ`ฬAKl–JิซqษT.ม6มกm๎LๅP!ฦŸ<ญ‹Cฦํฃ>‚UQ๐ะ  : jป)ฬัชGฬเุฬฉŽขY:[fฒC)ž{S€Sล�mฒโ9ฦฌ—z่ซฒ=,ฝฐ›…™p‡ลšmkŸup๓@ฬW›�ญๆžZ�›ƒ‚]^U–††ยy3C;>6Šฃk“ฎมsN-3๏นJpํลpr�ท๊?X ๓ฤฬฝ{บนตถ‚™ X ์A,Nฺ�`/เh#žƒSฎลุ@2=vsตธgภตฑ เ]ึ, —W ถส"8*dจ‡1โh์#ฦ‡K90\yอ5ๆ`‚—–L๘™ถ‹-็5;hbhd -แ„�{๏‡dะง๙Y-˜@ฐPXภ�'k™5ฑY๛lVXเฤ๕๎—cฃ= \ {็ๆ๐฿.j�” „„@(k฿`๕ยะฅ”1จ%’บv!‰ฝฺส2‡=$8uสบ |L0ฐd8ล+ง c:bั€ฤำ#ฐ13+0ไoณขุถศ๘๘ล{3สมzํrp๗๖mุุZ>ท”}ะ@‰ิๅ[ซหำ�;ฅUี0ฟh�ุ��‹เ๔~ƒŠ}Xงิ;็`�าnpญ2ป=์ฆm๋๖0ฌBบด D �dงI้ถœk{ž๎�ˆNๆe5ง[\ก=โ(๖ช&<{ŒFอ|zๅณŸล$‘ฑฦŽฐึ—็ ,Šฑฯ–“X�เรฯาžสบ*b?ภ๒�vต๔๔%๓Mฺ|ถ‹Žๅ๖zgšฤ ๛F๋๚m!์—บ;ฮCCYbwห_Nm™ธว�”iQDเUมhูY&ƒุA�† ิ€}`ฎ)๕^ธœฏ\ €,s”ํพใzP�Uš�"1ณฦ�xฒ6ฒบ ์]>�๛Xg?—Vกภ`ษ<จ‡ลTห{ิฐ๏Gดอ^ถฃกฆ>]พv•า)˜ฌ'K๋V:ž4A0ฦ-bนqฟ3–ธW}k>ึƒ๐V$Oเy“ ’—ฒv.xั6็‘ฌ้๙๋œ—|ื˜๎:็9fฺ�›โทŠฒ|dร๙zืœ”~ํ…ปฺ> $ผ†Rฦทฯญ4l้h ๖„gขj๛๊zฬ“M6#s~๓ฤ5_ ะ{ฤ™i‚ยŽ+�์m>š๓) ข๋‡$ูNšKไ<‚อกhžฟI}kๅนCฏษsฬsอq๑}ํ�$�Oฐ#ห˜’ฆฯนลฯK๑�Œ‰มณ ˆ Œ๚Nั•€�๊š,�มฎู๕Iaๅt†ฮws๏ด>ญD”3งp@ๆส“๛ะะ (๖Tk ŸVยMํS6ตJrรD„7YHiาา์4"ปะ๙ฅB0”3[@WHa฿mึKพeW์ลRุ[‚vถใ}x็Az๚๐1‡•ฤ},Pžฉฦ‰ใ*Cค8ฎ{๊(snž8w–lษๆy~พ;Nฎwy$Rฐ'ุ$วำ–�[P‚‹ŽณŒPAw}KŠั-ฒดM0งฉ™Ž%ฌมcฦ\ฟE๖มแเ๏ตG9XFฟ เk›r†#ฮฎผc‡kJŸผt๋ฅฟ๓—๑/~ํีื^๛_�ฺš{่โภ?�w��/�๚—�ไ—฿๕3?1๚;ฟ๙ป‹N๐ูใl~ฌGเ 8๘ฑžพ?��๚฿�›�๙y็๎KJ�๙๒โ๔�ล�›>ู™ž็}Oฏง๛๔้}฿w ฑ €ฬBฮ‡ิbFฅH–T‰ญาUL9’ณT%•8•R๑ƒํๅŠสชDq$หUD›Uก(ล–iQไgม fฐo�่ฝ๏ง๗%ฟ฿}:โ�D7‰ะ8}ฮ๛>๏ณ�ืu_๗u7๏m._ศโ8#[.๓ฝHถซ~ OฅศD‘๕!(Pฦฤ  f+Be•ึ=dฌ#ทหc๊S‚d-ˆ"P~๘๐5‚ R2จ8f8Zฝ$มBHไ#ุำมณ,๎ู Ay!ิลผ`โgฐd}�npa`๋4i�า็ม`ุฑณuๅ1%๕จฮœ%ธฌๆzศ"่ (hท๘J ฝž{ธ. /cRฬลV”โjอ๕rฬ$มี™“tๆ�0ํœจ]XJ๗วแeฐ’ž ฑŸA~�ม๛7BaQ’ตด†.ฺs^sฒ<พเีLฉ5ํบศ+ƒ.็๚น}๎รฬcŽ{!หศ_Z;ป �„Hีm’7ษสf ะ๎Q?=๑i(Aทe4ถอบ๚๑ง W_„4‡L[้ฎเEฒGๅู๙C23ส‚% BjฯI�X๛LTล๗สSm;-% f๓€tขC$ภ”ํ0ญฬ{ณ`kหŸA„U‘qิฃ`:สฯ|^ร=กL˜ขฝW€่๙ซWาฅK—ะ๘;ี•ฐ{๘ถ†ธeื7ด๘]X\BE@kFฦบRเ จะโš�jๆhะaญซt1รjฯ๔EžJ �H4ฅิหDืrฮนbะiฦำถŽAF07,‚z 4ฏ,u’Yต#‚F}อ(-*หฬซrภ‘ู๙<ใท ‰"Hu�อM!ๅๅฝอf๚| nEŒงูo U0ˆœ™ภฉŠฆ$e๋[y?\ษ๙นึ�๗ ฑ q Ht#'`ž@H‘ํถฆXpๅ\–,5 ์ผีœัŽ3ฎWหซr'gฏ<—†/žM?๛ณ?สŒ›ท๎ฑมf้l—็์ี_ฤฤฐฐผลqย๘บ็*Yพ$ๆ–{ˆ‰uษzธ);–pเฆดนงš๙<ไ}๖ hท˜งซตดpฬ1—๕žุคlภภฝ๕WP$�!wwž†8@ึ\kกy ~šพ™y—,ฐัฃฤ๖|ฎ!kฆท!46•่ฑ„€ชคX๋b@๐B–ภ|์Z#—FRIถ ะ๚เฝทR�@z๑•—๑8i‰ŸQ๎�ูี‘ฎ@,ชศpญธ฿/อญ@*ีC€ัลเ่@๘,4;ตlค@โsˆ˜d:OW ๘$์ถX‚pฟ็`้ญกทD๋•žฃ$‹}2K@X‹y]†๒3๛�๑�ลจะ๒ผ�rง’bศq”•<_ฯ7•_~•3ใ8นxฅ0X'าRใ”‰eX๓žฎื!๎ตทฟ%†›ธจ๙g ลฬืฟฅ-*ถูc$ป3Œฉl-„ฃY๙6ฦFำNŸ฿ mpชแc-€|Kภศšผx~$ Bฬึภ•์Kภtไ๘Y•?บJPณ�ฦ๘yh ์ฺด�$ฯ๚ฑlDc@ฯษ๊0!e.zฯษ}5ฉO <ปyฮฯX_Œ�ฅ^ณฯฮb)sแ›EศvีE!JZVข,กไDฟ }ชH|0ๅcOณk‹๛ห›9้บฎ๙๒า๓ำsฮ@*ฐ็1พ%\ksC †สจ$4ตwขP ิ`š์๛8ฑษc๖่i�„R HQ•—’�P5แโบ“Dlย๘๓�ๅ๘ฝƒฑฤท‡ฝ{Žฒ‡ฦวsื‰ฅฉเย“%ผ1ๆ(ฑ[L“ฌฃˆ5ท N,้hไฌ“,‘ฤ7ถ๑�#>?‰๗:‰V๗pc1U0ฎ!� ๖bฟTอภk์ฦฦzพqa%6๎ฃ�ู/๗j�<฿�/ูละณr9ผ—๋คŠใ‚D}}๖�‹ฏ}์๙ูฟ๙7~๓�ล�๔็ฏœa๖�๐หs_�6๑ๅ/m๑‹_�โ�ฉบ †๕๔??B#pJ�=ฬg๑Vพ๔ฅ/้ห_Y๙๊?�ว฿ฝoฒ๘๘ Ivณ4a35R2N4œมโ›yธ<ฆŽ›RีFฒ่œ7๑:๋ N”\G�-ณฺผฦ์จmูtแ^1ซ@ไ„ญSนr�w…z7Xฺ่ส,$™E2ํบg[ใnFฦะ d†ผฆ‚‘๛ทnpฐีDฐT]C�)ษ‡F1๛ย†ป  AJ)า‰มืๆ=˜�ภŒ™mะิQyถ†Žถรซ&ำ_Trˆ!ีXx\บt9ต๐๙๗๎…q™-ฮThค5?3ต˜ Yt3ข;ศdืRnผ™แ�‡จPฒ^ฤุI˜Wฮชำฒ€œ?|้M€Kpf&7K๖IEƒ๗kฝต5Š๕ื;€ใว๑Y‡ibฒเœ฿ุ8T( ฃEž—RHƒม€ฤ,Œ ู7หTHdฤ3ไณ}-K ล๓ ˜ษแR AืwHฆSpwภX™•>"{(๐l๋์2ศ`T� Mิl9i†ใม[Œ*€%‚’ศฌ์–ATRำX*87ิัๅ ฏฎaนฤ™%ƒฒJ  }‘:z‡SM['[j5์CR‚‹4ึภJX›Iผsศฬศ.๏iฯt]ท๋R๕H๛Q2Tv rv@๒ฏ*de…– edw๖ศ�9ำ๙€gแ}2ง๚ำว^{ โb*ญใvoญๆภpbQP A่–kถ—ญŠ๏AL0ร46u�ฝ†#�K#ษฮฮ๎ €ŽpM?9`/`_ะMxะr‰œb %�๔ๅฐฌมฝส=มนfy K'@)มะูV‘*ญต้ๅื^I—_\ซืๆ*NธทบFม1ช3ผ^–์Cุ-,ฮR&๓ฏ�วอ<ไY†รt[k๏�b’ฅ>:หวg๒บrส:$Vผ๗<ใศ๑งยr™๎�วฃใ๑~Eoๆ1ฺใfˆ! 3”8Po.Aตรœดป€ญณŒƒeึซฌฅ…I€/๓�ษฤLœ ฝ”Zุ�ฅ‚ื า�ฃl‰็ป2ฟ !ฬž1แ‘|s๑†๑ ๋˜๏9‡T’e“[ž็:#*แถ^4ซ\Iนะ�่ƒwาŸ�๘<`Žlฐnณl}”จุๆณ44^ๅ5Žผ&ˆ›์W’aa ศ๓“4ห,ฆ�c];d–โxVKว&ฦu๊อฐ๏u๒:ฯ ฿C`ํƒ๒‘ uพomP�PJHp{ฦธ�]g'(ปบ{บำ๓/ผeYˆ „วccศั[Q๚ฉ6YŒ๋ีืFตO๐บI)aai_o�&˜#Œ_Eจ8z น6ๆP-ช*หC์ธย ๐ค๙b฿–\ุฅ4ัRม”่q…ฌ8ฯ‰{$›$ฐีฐ๛{aเ๎๋5๑”1ถูๅ~๔ใ`›0ฉ`_ถใฏำ ึ็*‰ืP]ž.C b DI (ๆRญK๚)ปคlRยกˆฃ’sัฎ šH{]๚๊Teซ9‡๑Vbํช.๙๚‘�(ไำzOŒŽา–‡fr*ุ€)ห5€๑p๖Zอ^ึŒlๆื�Ž!$0ษC [OFQน๑ฬไ"5ๅ gFQสย#ƒ ภ๗บ Ž‚;YAšม wh@๑=�`fยš๙#ฦ9Z฿ f๘ž’†^สDน ศฦ(QF‰2�fฒ@Cgธ&HƒšU2$�~๋&Ž๏C”รYQ?fG‘๘xu9฿_[J$รรศ9‡ฉ‹ว‹๐>g๛ง22ธห7@”T‘iD~^Aคfœ[ึฝ[Ž๘›€ Woฅีฆ‚ชm$อๅH๓ซ*ไ”อf์Zp+�€�9ฟti�เํwำ jงื<€[‰i%๗zๆ� AุVš'sd+7ษ…5T9’#k้Žฟ์๗pชช š{+.ๆ๓L#ซ @sm—6$ฑร’ฦอbpXSผO6ตะฟAFFŸฬ0ซ๎ูž+D˜ูี ณ3oญ/ง—_y1œษซฐYภตพํ€ Œ4KK0CP˜ํิˆ๒rรฮ$>ำ‡PฯŠO ๛๑‰qฎ‰GหŒุฌ8wœศMฺF*MีSC๕งฆAกO2Lโภ9RGถึนu ฐ็�ฌม•๘j‚ดู€Lb’‘๙๕�‘๖Rถ`ฦปiฏเ%๙cๆsะcฦQUŒธ—ชiWmK7›ๆ2ะž๛ฃ•กืส|ํฦ\’lœ HฃWM๋ฌ'7ซฆ็ž๕น�o)๛D๔w๐,ฤ‚3ิ๗7A‘ตูx�ฮ2…น๐ฅโภv“ณ…๎�z๛G(~ถX๓๑zึ•]F Šวค.ฝ๒าKi‚าชีu.�8MNLลx๙็rฎี์จm๘‚,เ3��_šJJ$YฦdF๙t\ IB€ฎZFU‰5็ฦ๎Gฬต๖LAบ†šสšm[้ผฬๆ c๐”มqK?ม)เย๙*!ฉœHฌo—�’D’DYง ยRฏEEjจf๖กmภซู๐6ส. r9้9,mจPจe^Zเy7๛R3ชฯ…๐ฒแ}TiY57ซๅ(ไไ๊๚"`e“็R‡lฐe>ŽพJ6‰OU:Lฟ๘ป™๋ๆฏ–ๆ๎Yyึ6!TAณg๙ห}Oƒ:ฝV็Yฏt"ก�o1`ำ๖š]�ฉoห˜สdv[ยทๅrมggaMๅ๖๔ี<๗AD1ืิ‚’รฎ[ฬญh๏ห^47>ไห๛Fยzๆ3‡4ๆ,AŽ.("†9ทหฝW๒=3ผ{%แ•A ีฆ–Fศฮ8ภฆe์oใฅz๖ผJ�m ฌŒ4ธๅ,vฉ“ Ewฤุ…3>Ÿ!!e{ฬCป x�2ป(ทbMqฏ‚�่�งj”~ฦน+yไ\43ภจํZ„— {‹ภณ‚sฺื ��&eE+ฬืญฉไŽgญฅ;Cgฃd฿๔ิd”;่ เžุƒ’p†๗ƒdมย#-C�ธGYส•๐๚œWXOš35)mbc}•H๏Z7g(!“�‚HXมgfƒถ˜ปษ๛�ฯ฿:๎Y?$ ๗3‘ฌ`฿2 ใษfI6ษื~์ฯ�Ÿs฿ณธ฿‰_kเ:๖$๖=๗sc9•‘‘ก44<†ณm�จ,เTLHฃˆชภ‹จ‘„I”gRฎฐGgษอKU%อNOFyO]}3e1-(๗Fb^~t�t็๖ ส—Qฆ4…�ศ่ฃ‡ฬ/ึ8„ว่่ํ๏ง bŸ –y–dJ\ฉฺLqฯt่ใเณsoๆฏฑwบ๏3?<๓|พึ_�ท^ถื�bo�ฺ€Œ`ฎ๘� 1ฤ:& ัฒ‘1ด…ขcœ•\๖=๘z๚Y‡œ�์%%ปGU#g{�่๓๛ื�‡‹/�ิ๘i๙A ี้žก8%žก‡�ฃ~ซnเ๒ีฟ˜�/�๗oNLL4"aผฐพนVlฯhๅขฒD .�]pฬ๙rJ‹ศN,ี�3?fฐjxBZฬs๑๙+‘™V6฿E}w{ =$�}ถ5"[ศ‰ถบถธkK็ž{‘ฬB ตฒฃศ�f‘l6๓พูจนใ๐๔{J~ื–(SOณHWซ•๖ถ๒˜Hw"ซ€7อ›ส^ท†|‘ฑโg•IWTบ=่�]Fภh�tๅช็ฮ_ ำ<„ฑ_kคS˜8Zฆ@Zฐ 0QJn`bญฟ$‹R_AฒYc ๕N๏E|F–Cุภ[SทcฒทJ0•X:N%\[‰ภฦC๐ง‹พ,ฝ ฦถ˜flอLๆึ๊๕ึŒS๗>๑˜บnJ2ถzท 4ฤโhญ7…‡ผTMฝขิ„๑5˜ทณ€A@�๏๛ห?๛3,‚2# n_dฯ81ตdNJโG�‘~48ถ6ู{YCย๎|˜žŠ๖SsOฆ ๐*"๐6 2ƒgฉด:ƒA`เb>4R3ู�G{&žม& `Œ � ๙ฟfˆคSซšำ�Jื�}ŸV{ จSฃ‡๓N ฃ๛ถR;จ;ฬ๔@ึœ8ฮ\Q `งณฑ)ีๅๅธo‰ขžm๏๐€.„’฿๎„๔�z^]�'>ฤด _ €|[[S๊cž6เ+!6;1™ฎฝu !ฒ% ฐา{ อ์ „ฝxฮห@rdŒ”K~“ *�#เ&V+?ูNƒ ้��;(3˜ย๘m•ถ’ๅ5z/, "=3}<ส|ฏŽ๎vๆfw”)HVูๅย,ฆูต‰ษ้0ผq๋6๒ึ…0ม3/ๅฺs4ฮี%€๏ญ๗�็ย แxe๑ำิQ@$ม$i%จU†๚…Nฬ9ๅอฎ|%๗‚?F`‘Cad้‹ไ–๓Hิ€Jงฒb@YŽ้งjƒ๎ฮฎ.�Œ'%šอนฟฌ`†บL[2jๆ&่8,๋‰ยร1nๅณ(‘)็š๑ ะ€ORฉg 'ฝˆ!ŸŸญ1๊ำ>๗ฎ%วฯ์ซ@ฺ5/ษ่ZdV�เ�น…,ซผrvI5ชเิ๙eฝฎЉ<‰ƒ#‚๒<๗Qฬ7ปึ$[าฅ9\ฏู[K[$Y่J็��ŠqŽน;ไุLiฉoสšsอ่Ÿลฯxอ~พ๗wX %Vข้e5k$์ ตึIUจR๊0ฺltŒŒ�•oฑ๐๓G'?›[5ษ>ŸUฮ˜Y`๖ัk๑ณ๕MYวงฦ๋)จ0 ๕๓A$ฑฦ๗H�ฒG๙‰Y๖�wฏใž�„๒ฌEบบ4ฆ^€‘Ž๓ั๚/ฦ‹A“4‘,ตำ‹>9\>ฯฏเwpH&Vฉ;รฯฯ,i๛ฆ๕แU�ฬาx�๒์|ถ็meŸ9wŽ:๓%ึ{…kโw›็ึุ�ฉ†G ซบฮฎ”ƒ๔ึ‰_๓ื,gา1เk’ญxŸaฏdŠ๛๊b‰ŠY๒cึŠฤณ๎Jึใ๎™aฉŽํp�ื?ภ8โ็Y&ั–กิnš3ฐภ���ฤ0.n v_ศารขŠฝถ†๗,b.Jฦg!฿$„% *™�ชc$ท๕จ ๒ู๎๑;ำ€๙(แฯุ+แ—ค๗Y๙ฬ% UppึH`y†z.ฉฮsฟqพIน�š(็z๙*๗\่^ร‡ฤ๙ฐHI! ;HN็๖ิ ๅ„”มaฺ๊BดŽ๎„๘ฟฐ๏qฆ0‘!ข4าDqย\>a �6๋kดญœงฬ็Kย๚า˜‘๋ฑฃสีFžmแร๕ธฏีPrP๐B9I –Aq๒K€+qd:?#qฅo† อcO€8*g�สbJขCt@ะeQ!ฌ.อฆ๕ฅ™ิฐWiถ<๕ฤศ4๊F…๋.ง}ด๛๗แcภXYr•#ฐDลV–๘cจะ›{‚๛ž�uŠ9ฏZ�บƒ —lnํ่จ๏ˆ�โฮk”PN๑ฬhส43ปL‡๖a sึ‰fฝ–lH๖จคPๅ~yคหxฯ๎กDเyH< •Rb‹_W™[™$ญพ4ถ๚๕�6NP‘๚๔Kc^“OIษbป~87Mฦxฟkด`ฎ”ธฏฏL?๑ใŸœ�อ฿�ปฟึึ๛๒๘ำ๗8��tžฅ8%žฅง�Œ�๋~๙_mผ๗ึwฟ{ํ๛฿หแ6�RYฆฌศฌ….ใ:๖ึUnW๐„Z,คแDn’ œฏ!I-ๆf@ smŠ{dL88๛{บ: ฒ‘›#25ล้ฟ•“n ึ]ƒธyศ๗�~+ฺบ้(oึะบRฮyสฦ9œ‘๚"w\ฃmา�Gผ zฬ๒:I๋U‚น}ภบ่!Y 8ข< ยษ_FjvJร7\|5ํŽHZ_๘เั�ศภK>(lGธ†gร.Aju=]"([่ e๐o$ฟJภXPM`@Rแa]ฎA๔*.'eจE�ฅด๚3MฃC มญ&“JU‚ ๎อššUัศ๋์ˆ]'p ๏๊„ฐ SหพF6fq~เ‡Œู]คจ…6่!#ง๓ท@wqŸ•เH€%™๐๔ฐ๗฿Ÿ~เ.ฏ$ัvxลbaฦg$ะxฎ‚p่้ํ-šผ—ญณ|?ณdเ,Aด†ฌๅพ% เ3ผ&ใŸyŸ]‚qฅมE€าZ@†ฯ]เ/ุ˜';ปภ8•ิ4เฺ]Li‹*าฤ8m;ษD้ธ~ˆ’ 1•4ฐ๋‚F™ช*$ชŠ1tาฬJ)`fd˜2ฦรq-โ๚›{‡P/ ฅ•็๔ฬ๓i/ แซ จฅfw@)0๙AำฑX�“/ฝ๑/ฟN€7C\[ลณดฆŸ๒๋็Y#J`อฎ*ณึษ: C๙=Zบฑf *3LEežต›ๅ๙Tsดžฮ๔ถ่งฉฉวิ\kRH}9ฆํ75ํR1`ญw%™ซK/\„\kJcc๗ธ†C‚สv�Ÿึ“\ใไไ4ฯa๕G+ูฐ็˜๚h?†d€xค๐>๋KZ>C>A †ƒฬ*:0,$]—f�ื! T-8wฮฟาหšœ`้"ฺAีแฺŠฬ๋�Œ”ืญ"ษ�ไ๚FTQG�eาfKq�Hฌ›ื lft4ผ>๔ŒะG ฺโ ๊อ ู�๕ๅลX๏๋ ฎ3น’{EถVไZอยฟ๔๊วำ๋?๕9€lSบ�y qN ๔ฃL!€$ฒ_A”๑๏’dJถ�ฝ reึl� จฬ2J D‰ฯุื๛g๏�5jภ@ฮ5ย—„ƒืZ zv0๒ผฤๆ�ิ,ๆ`๘O0OKP˜mๆฟ\kก4ษŸu�\Ÿ‚2š*(ฟBมue @ช0B,!UซK;t_ดuฎืฺๆgวcฝ๎ฑ~— kZฺqฌo๎๐ฑม�”8 hฝ~ื —B๕ฦSา‚oA~aVศ?๚,ซ�๛จlj่HR‰โมฝำ_9๚ญผ�า+์ ด�=ร5–ฆ›ผ—ฎ}๛ฏศฆ“EKBMO<Bม5k•๑šš‚f]บ๚Jz‘๗ฐ3ย{จฯVw&วมuฎฉกmH]WnYž/๎a–ดHI`zoไEษ๓"ษgoู8šอjิซฬZrˆ�uยj๒เ„q๐CJน–ีฅ๙4อ^ฟ’'[™ƒ`ชใ�™Gr{ำ;๏+1อํ;7ธ-ดชs�›™wพฯ&Yt;*l,ฎ„๑ "{๛•{u9cYย~zซE-ฆ‡†ชปชs�ขg3ฝ�œ-้<7ฃVœตจjเฮ[(hwฬe1`�sน–r �lฎcx๊๛[Rเ�๗—๓IPRุ8�,C๑™ % ๎อUฬ!ณาฮ_ษ2�$U ชsฬืน๋:ว^*่uฐ$fณะgไ^Q๒จฏฏ‹5ตู๓กข[rุ ๔uJ๔-{QS™Wฦ่|ิผrƒ=GsQ;มD›Dึืั>๗“๐ณมฃcืoP3ฏ‡ ห’ณQฯH"ษ/��{๓Lต์%ƒ‚N๒œปkทอง~ฦ*g’ธฎ_�Z{ฦศxฦ$ศภŸ‹ …]%Ÿe๙ฅ%[– yธณ‰yr_”&ผ๛๖wXใcจAธ~’ณ ƒะป๏S†F้Jนนฑ�x…�ฌ”๓.Kie kฦ{ฎk`�ว$ิฯถLหาใก!Z,๗Sย ojš29H๕ื>๕™4x๖g%Ÿคืชขek“uอณ๕ารษ=�ไ€๋ลRL๏ีu(้(iไž ฎี6ู๎‰’ฌŽ—ฤญฅฦYพถ’n ญmu,Hฮ^cืžๅ ’Jvฺ๒็<O'จ์�™*ศโb”t ฤzีดฆF*ำ�ึ๕็๐ฅฏŒ๓ฑง_ง#๐ฬภ)q๐ฬ=๒gใ†ฟ๐�็?�'ฟ{z๊๑+dอป p”์[Ÿn†_I›มœ‡‡]8UิBXํแb�พ&yJ #โต‚่ๆf๚3(kNว‘Aโ@ั์ฃเQ`~ๆ<าื๖Nฬ�๎ง} ƒJไข�ƒgใP๚เฺ{ษบ์9ฒฆ๋L[—Mอ`Z\'ะูๅ�จึRš-ะ–"ํ4“bฎิ;2๑จJ๙e}ดู ƒฌVZ%ž;žC”Cเh`ปŠภฌ ™ญ �Yตf<<ธืจ^^œk๘nำZr"\�ร˜<รgื64ดx€๒y7[fฆ zOR$�โภfิ๐ฮ๊ศคdฉ{4๋๐�NเetsDŠz™ฃ#oะd&qฬ๚j|IA’<…ƒ\เฦŒŒ‡aO=œโŒƒสณณฌ|—q •`ฺL?B@ค�ษ;๕ฅƒ�!ึ๓, าQ�61zาซม’“•ล'i``˜ฑl#KUPXd ผธฆ‚•-ไ๚Eฬษ^�$ฏ) �ํS }ย�›อ๕ฺ๖™งฆ@นZๆ9เ‚? xŽ๙ทŒˆ๛wLlW ƒ{2{*้ฉ)ฅ  &%ๆ—๗nแ žy'฿วตcืŸฑฌห‰้>้= ผหX฿ฃ .ฃœ?๛๚0oใ=bอ๑z๗ืฌฟ?|O๗{พฮฟซ.Pโn๖“Iม:คต- Q`_แฅYคฯ๎ุ๙‰šคฎ‰:kบ€ธ๗๒๖ฌ›อศดบ๚wฏำ@_าภ/ฟ฿ q๋�i*ศสขˆ’์8 ฐิ“)ญE�bห“jูW†!ๆบXC‚T฿ุฮ!:ปทตu!Mคฤ้ฦปo)ีีืOYXƒทnฝ0eอ@X67ตฆ;ื๏ะยŽ็ฬs๑~x�ญ๓ชz ™{Ÿ™�5ช&ส๛ึ๒o๑๓์Ž�—ฎ +‚@ืคV}๎fQ—˜ำฮKฯ๗=Q(๖ ิ๖Yฏm}์ฝedt—าDc@ฐฝณ“A@”V3๎ถขužnlญว5ฒำฑ’ตๆอขœ„็W้eงฝ@๘็่.กฏๅv�จไ}Uโœฟx๕ ฉม:4+ฎาB2xŸ็q๗ม#ฦฎ‘ฑขล&ฤˆj7Ukฝฌ-�Nc”ส5ฌ T"ยyๅ<๔�ย—นณหพ็:g;ŽyPลFซX�mโฮ๙ ™™๛฿ฏ†,ษqžนฆœผ‚๛ธrŽ๓ณfหG็&PtrN๔Aพp\_๋งถฅH�ปษ,<ซfr&สaชx๏:๖€:สl%จ‚ฎ ’‡ฯœ/œPาuD'ƒ<ฦze๎?\�!ฤg‹็ฌๅ~^Sdผ!$ช!ถฮํIรƒภ�ฏษ€c์\Wฮoฏwแ3Q‰ฑ๗นีณOzv�ุแ —่8a fPw@ฆณฯัูˆVŒ๋ฌacnZr>a>เฤ\l๋้‡`ซมฐy‚๙5“หฬล{฿8๊€ฉุWj! J๐%Z็ฬ4qPOู\ฎšฎJฬ#ห์$ใ[ม:1–<ฑA„กb็๋9ฎ#Z๏ข ่ขไม5ฃJ#ฯ9`๙‹ฅhศJ.Yvช:สฝฤ3็ƒ*๏ำ/ฯrฉึฐ“^จM?Ž็๙ ดีพ8ย฿K0ทค,ˆฝล/๗2ง—ฤ–{gฬ5๖dP- ษึี–‡ทPฆ‘ฬฑฏฟ๔ส+_�ฝ?๘“ฅxƒำ�œŽภ36งฤม3๖ภŸฅ��G�๛lฬ>พqldฦ\gฬ:/ญฺ3ลaK&a ำบAฉr\ึ�2๋]ลกmVฺฬRcห4bฬ๔ ]k™•Ršนิ[ฏ฿Bbอจ �๒€e 'ิ**ัณรร๛wQLEWพืษ�ml$ ฤ์ูพF Z\ฎ�AY7H4˜/ๅ…Cฮkื1�๏ym*'Jษ`ชขq_X@ยบฒ@f๓<@ทณะ๚4˜ญL(Sœ››!˜$ภขํ๕๗ส^'“ไฺปYyบYฉ ู0฿=มมห>YlNํ ฒUudž0Y$ ๑ \)mี”อุอ๏s.3eปก6(&3mvิ๒†[7๏ฆ๋�‹ฌ>ฑ%Ÿฑร}›e๐ŸJq‚Uพง๒Bc_c†ำขศ.่๔T$•aอ$ฦ…ีd์t‹๎Fั†Kบู(วฤLฟาkวUe— ุ๋ฌ•!{`K"”qSEถไ:::Zญ.7’)eข ”!7๐<t=x8ภV๙พ2pƒF๋ฎŽf๙C’#ฉฆิค0ฉทม.fz4ุึฌ๋�นT๘�ๆYิ๐ฏ*E&PUJ~๓�๋i์ฦ�ดFM๔�ฤlฺโ3ถŸ“๒๊ดN–p…๙…„ภ’ž็sD…‰ภ๒รJ]๐ณฬ_‰ ืถ›ชQB"๏`๓$š`F๕๋มbช+�J—††าู็.ฆ[w๎ะป}6ํUฆพ๓ !›˜�ึฬฐํะ๓ณJ›ปบ� 6‹SOด•ฌ4/“‘2pอ“น‚b^๊&oฏs[Ÿ*=๎์์ฤt ต ฅใ�ูำดNๆY‚�ŽŽ๎ศ4:Ž�ผAก๗)`ทฝฆJ ูฬZน8n… ™๕ซ…€ฺืH"dศ๎Sวa{ืeHถ-ๆ๙๔ิdหA1&e›ผ�ฬปื'่x21 I$I0๋อW– �ศ(C.2™›� ๗ฎตg`qฎ%Sผš–๐˜XeŸ*bp}จ"2ณถƒ,ฺ๋แ‡๙๐sเsb�iฆ/|5ฯMCฐกมaKT[†แฺP6l�ตh9Jty`= ่ฬ[.#jqฟ๑}#เp\?/Ž็.๗฿]‹พ๖้—฿ภบO๘Y…`�5ZPp๘ป ฝ'X"`N@�G๊ศT�๓—า�ฎวžฃ๛พปืษRฦฝถก` pgึQส๛rŸH†9c`fู5,ภXZ\Ž๗เe1ทญ;ณ�*ซ!™ศ� fฆวQ’๔F๖แฝ;ฬปส4=>–?zHZุฒ�ป๙!ฟS~โ๚d?ืh0CนS#efdmฏ›Žสำป฿{;�x�#’<[็๛›ูmF>Hj7C?GEŒ‹sิ3วฌ็jื eŽซฆŽศโQท9]\'๎ํ ldDฃTˆg๏8k4j้–J'๗%�=ฝฉg๘-๒ฆธถ]ฬL[x„”pH"Chil'นrฤ็O�ฟวณcฎ๓�T>-/2WyฟjˆมธFHU๚XRQ.ห5…).ืOŽŸ๏ั}€๗žึ—รฒๅ�ฟJฝBฉ2rๆณjž฿๛0๊แ%๔%าŽ�ฮŒพm๕8ุI�ษฦ ธN-C๐|ฺf์T ”5&ฌ(;N๛K50กcผ-+‹ฝฒF#MืœฦŒ�สันNฆฅS �ฌm‰fต—�TzๆจfฒŒ๋„๋ฑต์2๐ตwo@&�ว“„�f,แšQแไ�jw M5MTAเ/‰{ืˆ๗!ธ•์ัฐYJ— ~cO’lาŽ๋ฏbL�+,ฃ“เŠ}™1ตลฃ�'�ํ6๏๏{iœแYxzฏธ>h1ล}ฒฏ{€๓œyNฃ1uz4ฃ>™šฤ๋ไมๆ๋ cาW#เŽž~F’๒A�ผร=i,�DูํN%ถ–—ึร#gโi"�ัƒ{A@Gฉ{I-็''yฌรU๖ต‡œOจŒ!ิ%๏V็ว้ด0ลำใดภžzฬ๓9ไ5ถฤfลšเc�%IT8๎ั�k(#� ๛น๊Qcˆ.žƒ?WE,ขษกdB‡n>M๎i>๓-m๎>gใ=UFพ—kชบ ฒ�ŸษTHdRฆฤU•ฅo}�๓ฟ๖k/พ๚๏=L้ Oทฟำ฿OGเ™Ž๐ำฏำ๘ั<าW�ีO�่�ษ7๏�๙จ ์า6‡ฟ๒Eรอƒี Byฝ๒ฝjไศP5Xขึภjึ็น^K๛ค��๖`ขsC[ ู5ก‘€ท‰์j3ูP]ไ ๆ†ฬ8U฿พuƒ์ฤ85�b€C[Oาํๆ4Aอไ$C8‰sฎ””เ@ุเ�iFิภา`จŠฬƒคต{:@dYg:08Hvฟณฃ3�ๆะ5เL‘ั+ๅ�$tDWฺDเ`Iย๒โ"™€9@,rA‚ใภ›ฦUdP R•ํว๏0i3dYD%ิ™5Su๙fKม‚`Z๐cK2�ญำ=Ž์?�๎ฝG!W4๓!Tฑ;…ต็๕ดฟ3ะ )[Av”+๐™A"จP | ฐ๘+�NึIa3ูกj>ณ‡’’ณ๖ู๎ฃ X FˆH โW ’w๑*8˜iXๅ๗ฺuต๐1W�๔o๐>ฌต=„L9จ—ฤ…œuจ'‚ห),ณะ๑˜`ฃณท๙UNk,3่ิุ>Ÿๆmๅฝิ@/ไฉH—˜_ปSฟ%dแKQJญq-”,`ฬD‹:ๅ๗ูF:@œ=ห|ฉ'€ณฮ#Eม? แ;฿๚Fz2>“สญ'›Oฐx `ห๓y�cๅศรอh.ฃ0ด(ฦคฮŒซjจ‚S ยŠศh[^าD{5kฮํฮก G2งฃ…พ๒€Tk็๏>Lว๋ำฉฏฉ†n ?†!โR๚ฦ7฿H•”ต4v 0.ท|ถ H7๔"ๆภ&ใน‡?C†`๙ฺฬcpจ)UOWWศ{ืญ ฐอD:iร$ ฒIฐ`6ีฺaหA ‚ฟž•%Hล5ฅ๋้๎+๔'๛&If;D“ื ฉe;สศึ >yBฺX๓๗gk}`]š๊Xf฿อ”€| ี„J’ $฿kห๘•yณ}ใj3ฒ”N‚\ด๐_๐_M6ซณฏ/u175U›ž^Hซ๋g๖�ฯ๕“Mไ๙บ/่ฬ`[ฺกแ„{ฺ�ูJ?�๏.�ไO|6๕๗ฅO|๚“iไ�M)$ฤr�ƒฆo’˜fฝ�Sภ$šข2`Ÿฑœสq ฑš Re็ใ็šd๙yฅ์T|.ฃ"ั`'…ุKฬ‚ชๆ*BIไ�-w–c@"ฒ^UH์๛น๎[ีHƒ+>€ืlUIบr๕J๚่ฝkัโ/C6{#ถอ5ภ{t–ฌ~ieกํ?ฮgKjะ. โศข‡ฬ�`‚{ศB ธ' xi*,๓ฐSC„ฉ`ภŸใัล8ถถทEYห:ฤ•?�ีีอฟ†1๊ไ๘xว๙ฒaษ‚ ฑ–็ะภJ�xฎT@�.#ษื๐R%†{™๓EยุฒG่�‚*p• ๓หตฌฟjง%ต๛*†hฅสu;n 7๏€eQ[ยAM%!]ส|ิ๓ว�ษ9&IX†ฟ’~ �ง๛—~1Ÿธ_q”j0Oศ/ค3(า†{ปƒูฑ๔ฑ–œYลฟ&ฮFฮ$ 5€ๅฃ๐@ํร็<Hใ! ๘>kบŠณM:ิ^3((g็&ู฿Bwยฌใ2Ž{t๙ั€‡B็(ส<฿œ›ž7ฎ“1ƒ{ย:็ค~ีu-ฌJ6Qตญ,-YขGE฿เpชbฬชชP ง7!�ๆf(ฑม8ฺ˜สฒ$ 3)พทc!๑้>คqฌไฅ{–ฯา็&™FฟœMฮQว฿8ฯr”&ฮจ=ฮ‘'ณOœFัBำ›R�ฃา*k9‚qq‰ฅ(๛์ฏ–ฉ๔k ูะาTK็ฌถo�ตฟ๖ำ�ู7^�™๛o|ม]๑๔๋tžอ`�9�:ํ๘Gฟ๛๛[ฟ๗ป_��ฺา์,™ƒ=ุๆ3ย$‚Pp ฦaฤกS†IŽmแ฿ๅ์๋ถ]Rเก�ื฿ 0็&๓lอ๘6˜™�:ต"้ึm๛ัC| žเฮzมlงRr3=ถHปdณห šฬฐnR_ซ๛vด�d|Žจ฿ทๅ›๗žม&@p‡๋.Cnj]d mpจ%mษ”™�%‹ฺฐ๎@,ู$ธ[ุฯาfj›€žมŒฌๅส�,ฏ'๛ฮต›ม�ห#o็^…feดซไ๛˜๘ี– xTy”ก๎(งt"ืี ีศx�ya'ตQ[ฤ\$ฒ#Kิ›๚!IJฌ็์๎มก-]{�Zšž_ 0ต…,Zะ]ข$๖l&AจS3=ึ๓Pqวงื<Ÿ�iแ<[|nb(gp�‰ฐc{i ๕ลJjg�|๊SฏsmUฬ}˜ึ่ช๊š™ปจ0ฅ:bG‡ ภๆ<ู๔สšช‘เ๖๑ฌ*าซ๛x!cลCรšsbEไ‚ัŸtฯ@นฑA฿.่ฬจา@IDATŒ%:หK‹ะ�ฝuเน ถ”f0ฅฬ2oหxฎ emK ฌษํํ๏c�1#c4)ุ่ลB-eฒ&fฮuL~นง:†–(TfํHฑz‹5ฮ๓พuํ6ถEAT]ฌ๕U;๎aภู�-7๔X๒ด˜+^fwอเzิ`q�ŸIึะึt่ Dvฃข๛฿{รา�๕ต…™ชilฉ_LeฌŽ4v๗๛.ฤ๛ด๛91ฟฯ]ผvผ-๑ฑถ~}�oZwํพช)žตฤมS๐๛ƒแˆZoฟฏ•๐จ๏JทL<แ๓ขต€ž>:ืRZ\Ÿ€Iฅฤื ›f~๓‚๋๓yz. Žส e \)•มS0I+{@6ฤ „›ํ›Qวู.ฏฃ—ฒญฆT.์ด�ตT็ษิเg"๎X†ณJC<็œร2�๗๏:อฐ$�5!ๆFยtwˆrชณg†ุsQKฑFŠ({ุๆ�ณฏ็ƒ%;zšw๕๕๑�€j~ ุcwQ,L/ฬp&ๆจ~ชศ๒ผว@ณŽ1;fl,งa*™t @iF[”\(Iฐ์ˆ3$ฮ ˆ[ฮ`I—jy็ฐd”sTW�hส>ลสƒศ�M]๐��งzฏXbทษสo“nŠฎ ‚u–‹KKŒ—l‡๗ทวCำWDาญUๅ‰ๅW ็DกไะNŒ$[(‰Iุ๎ ฅ\—* M8w ฌl3้๕ชธ3NุเLX‚xquฒWkเฉผ_ตล:พFพึn:’†y’v8‘HีOภr‡Xงœ-ชc$ถ˜{r_+แฑ<7Mปู๔ยี—รุธRถ’vธช‹Tฅู–ถ™�oƒ็ปˆฑจืฺ�ูบ†!)ืำ‡ื�‚˜˜LŽณฦ๐hl'Viธo…l �9T /coื฿ฉดM๓HJ•ŒqŒQTไiุ์xJ"่“เ็ธฦ%�GU[˜ภQ-็s”๘q_๗฿ขฅ(๓็ฝScEอAืึhJ,!‰วๆgDM1ชอ~•’ˆั'K�”#vฉFฝุึ��~๏`฿๓‹�แ฿บ�บาฟำฏำx†G pข?รpz๋ฯฦ�ฏฟ๗ว[�ๆ�๏ฟ๓้Wฎ�ีฝ;๗2•e'�ๅ%วีYƒ!ฏJH'ณlœ�$ฏอvr˜ยา๋lภิDบกก– 0หaฅ;ฟม’ฆL๕Hฅk๘ปFHเ% ส`�ง''ศๆ9Œkสห‹kิ™*E^ ้ฑ๎฿๓‹ิ๓‰๒d฿w <—J้ื.ฑ`์ฒ`ยŽ> $0DP‘อใบหษชX#พˆฒพ~‰ภ๚ฮƒ�!Cท ใ์ะ0‡fe๚๙ใฌj bo฿พใ ฒๅขtw�EjG๏�‹ปเd็ƒBมฃ.๖ถq|Jr ^ƒ^Eจ$ยจ)2� $”so ถdม ฎฅ7วถ ศž{ปๅ9๎ rฏเa้…kฦ จ™ํ5ศ"หŒtlุเ�U๏4p:‡็+ €“มฑ‰@�€#Aวw˜G…Iญ,ภNsDKL)ฺ@ …๓v ๕ฮ`Wล…ค€�า์$๓YƒšqY�ยณ @ถ[A#�อ/^พŠ"d=aรนZ†อ™ฮJ10&–œ๐wฃ*œVT!�็.9ร1 .จฉผ+‰8ษ’(ฑ�จ๊ ๋พ55ดs‰kซ `(xธ�\๋๑Y์i�ปco™ ฿ฏฦ;?ฺ ิ[ผ�G๋WbZชqnไ ฌ&ฬT•ใXชศqND›Gฮ,๗็†ๆฦtๅฅูEสPขeNะฉc๊1๛ ฯฝย.A*ศ2์u9j�[{ีต |†๗Rว๋*้๖ยผ�fCpย9่™S/Dtู`๏๒๓TซX�"แaัPย๐บ(๕a��< ณฑGwXJzดE‰Œ?ฃั-ˆ=a/อ |ซ"หฌูจcํบซ&ะฺลฆั ํ'ซ'Aกู๓ๆ‡า|ณ๑Œ2s๗/�. ”86‘ฌไฤ�มu;fOKw๘๖ส˜‡’>–8๗]'s๚`x~6†r ƒW�Mu{ิ^ M อฌี๖T฿g-!ใฎคชภ๓QRั{ำo‰x›ƒยาภMๆGKฦฦดณœššๅ๓!ม]ทฌฯ*@rUฌ H ฎ�n$ั”๗vMืฒ๕•|๓ูฦS&TdžP๒‘gnฺั@’^uไ๊<็ ~šฎg่•a'ฉ5ฮƒUg\4SOพ� P’�ฅ‘๐ž๐ผ%�| ฝy'#ŸCeาœ&gfธž �Qฆฒภูl9‰ๆะ–†4๒,T^Vq&H๔pษ‘ tsŸฒ$&�L�ฆŒฯXEš฿3‰PEูฯ„)ม0ž@ศcฬ๛น�Jฐ0ิ�สๆ‹�@๎0-”Žีีป�๖งฎ\~๎7�๖�_‹ฝฤวs๚u:ฯ๔x"~Žภ31”.œ�ƒ๘;๙7฿y๏�';oญฎฬ]<��้T'3oF‚ฃวhฬ„๘ญษ฿ห#๋d9๘;ยๅญJุ พ<ฌฬnศ>ุ� เ;๐Y MŒqายงต‹ƒ“€ใ63.๖—แฯSsพNปฆz@C=2M=tไฮ"ฯฎœ์8x่ฒฤfะ d ถ5Cgฮคพมt๎�y@{G˜๖]บ€‘ม—Aลฬไ$œ๕ฮชBKำ๗�๚fธ2ืเŒ\ยเฏ�โฯษ”าIƒฃrAY7ŸภVS<ยj2เd7”ฎึd ่•:j�ดG@}ˆ\ู GGGkŠ=2๐ิฑๆp2Ÿ\๕ Pƒ=๒ํ*ส๖!ึ › ผ%Qˆ-"˜4@๖�ช ผ?ƒ๔RฦC`PL`ศx0มQ>QhฆบกขSนuํf›จ[ ^‹หธ!ูGผวxLคMLๆ…J,c]๐‹๙Œ—_~…vƒ;้ม๛๏คCฒ9Yส8ชkณิy6 S๎g\l๕1ˆeฏZ…†š\\1ป4ƒ2‹'a$9ณ ‘ qQN€ฆฬ^Pก’รzaeถmI}=ฬศ–ถฮ.�UˆT0�Kวู3ฉ ะ,ธ€�€/!#นM†มL‰’Cˆูอ›ทา\'pD}@ฆวqS*฿ขgใiนดค"‚๘2ๆuŽคU(๘#-8‘œ† ฺQZฦฤ๓„`? เQูฐฮsฌ็y‘]๊๏#kิœ๎�ฟ›๎= sฤมfŽนf๘e”eWยุ™)“d@ฅัำูNฆ 5เํ�อา�ฬs฿†จ&`ๆู๏“ษ*็น(/ฮ๐ปๅ!>MIท)ใ`jฆซWHฌฑ[ทoGภผŽyใฝ x%๔ฌฏตW}=sภv† v$`ค’ลgพJHDFG‚Gื™๓ฯฅ๛‚Xƒ]3ฮ’5จZ จnฦลsจZำG‚P๋๓๓dน?K $ช)ƒูDEdiŒ>!ฆ ืฑย�ไ Kl ญd4oเแ€Wฯฮ/ฅ์ฑ�ƒ|Ÿฟ๏กำ{WW'�๗า$&f3˜ซZ๗ซ๒โ›฿~ƒเ}'ึ๑ฯ|๎งฉ1~^b^"๏f. Š$Y�๒~Ÿ’โ�ฟ๋ม?๛=๙ๅ๗WณถฌFึ์nบ|๙b๚ฑื_MWฏ^J�]้ ูๆ๖ถๆt�๚‡๑3�'€.๏ ส๒W?๙ ๓๗ถš7รืC `”ตaYMEวv๖ŸuษชH”‘suถ“๘โy;฿๊>K?ห๋sฯ*ิI ยฬdชxPมใ:)C‰Pรผ๏ํW�’ใš)S๒๓ธgฝ5vศPฒ'๏Bฮ"ฎ�&๖hKg$Jlyบวฺ�ฤY_ขPฏU�œ*A$ $นvว�บwCUศY๗{e�’ห*)9- ;Au"๘ฟ0ŒBฤ2• ่ฟ �๒ฏ�๊ฏ�—_็=ŸN8^}๚u:ฯ๎?ž~Žภ35‡C�t๚sŸฮฟม๘ˆƒvีมฬtฎฑ.Wf–๗xŸZPzˆฏโ&œอะ…มƒ›รVฃCณ\{๛k)GPoๆวโI‚ด'–)@˜แ6โPe05๑„ภ~šภษ๖tธฤ#ๅ5“TTJFเ`Vณฝซ’]˜v3“!qไP5yZืo๘แŸฃ’CNถ f†lนฮลซd`อ8 twึธQฉ๘ฬฮศ€†ภzs3’`ไe‚ ๋๛•่฿จ์AbTž๋›ษb4นvƒCYd2๗ตี‹f`+†๓˜๖•!ๅ+GŸkจN-อศN; .Z Ofjdl๑[;จฌฑ›:nAŠืฑ €พvํ$ปd๔๙l•ำŒ[9ใ[ยkBI -ษ‘% 22xˆžหภfป๑.จ˜e:w&9Gฃ•„cโฯ่˜้Ÿ|๔ณ๗ข�ำ€S™n[g€ญ™@{6dยeดbชไj8๛๘ ก*5ด5ฆZ‚๏"” yb[ฒiถทqb–ห๖dvทจ ๓>ฟฐศ� cมp~`ˆภrฌŠ๒Wฝฬx๏จฑ“ำป๐฿†W[kJ‡ฝ,mง6z�Qฺๆ1ไx�ส.๊Y+™‡kำ“้�‡๏b�ธž:ฺบx+U@ฤ์๔tบyใf˜?e1ฺ$gd…`หฌšู~I ฎภp—ฬP dHmƒuถJลื œ๙\ัWf๙)8ฯL�"ื_ž^�์gR+ฯ๓„mrv"�ฟ{—Lj™bไ�ศ๕‰บ˜#ฦืrAIAดฆˆyฎน ๖ฺkŸไ๗๊4}�AสQ2ัธฏg๎–0ทซห•๙ิŒRQiส2ใ˜฿ฐถฎฎ๋$�ปs‹ ฯห๒ ฒฝ~Yzข™˜Šƒ<๓bฦเธQา„๙kfP๐แ"สŒ๏ะ�ฮี๒}I๋x?�ฌL\ฅ†u�5?ศV)k—�0ฃ�เ‹Ÿ็๔8ฐ%ฆ% yษGึ[MJ$ฝ]…,พ~1สฅื’M]�˜Eัขr<ญ0FŽmลร^ทk'D>รนf๚Gวาฝ{๗ำ(5หทn�…Dน›n�บ…ขc&}x๋&YlๅหNุ๖็์ผโืืgํ๑} ถ�ๅŸ�%i๐๔๛ฎ�๎u๐#ผN’่(]น|>}โฏrํอจ™4 ิ_ค5ม d… b6ฦว1ชeฑฬ็ฅ‹$ภ๋Ÿ�Tบ น0�hขสถk๕Ptฑถ—ู:TK*ำนg9‡๗2–]y�qํฬiKM๓y๏Oฏ A†@i ir เำu'hซผœ1วุŸ๊kาๅ็Ÿg_„ๅ฿7(หyp็C�“Pเช‰ผO}j*๙๗bพ){��ญlืณ'๊oำ€Oอ�`ฅM9๓c{“n mc๚zศBcฤธ ะeNฉ์X'๓_�า…‚ ]Hฯ]H๐<`ฑ2d{_”\.� sภ—พeพ0ฮNKzT่yใน LBฅะศ์๗c๛\(ฟZ๘Œู้๑PXตดศYq\Lอ$๋RŸ�ภ�ํ<ทŽ_Rฯฟ ๖วY7๙x/‚Z หพ|�จฎ”™ปฆ๘|!•งฑVcญ๘*ฎำŽฮฟheษนญ‡‚e �(/8ว�fฆ�<;•๕oBšุลgrv*}๓๛฿Bัทz:บ้สSฯธh๔บ&ว“ใำ”c@ฎ@˜๊uSRชbะ’3์’‘” @^จaาลu๑Oฑ–$EUข๘:ว-ƒาก–sงศ๒ฦ”-‹ฑ…ศไ�l ิ๏็›ๅ?ํ๓]mจ5ž้ั ™��ู y‘s�_0ฺ!ฅŒณ2ง๒ขTขร3=@_C9@›'ชสย๎[‰ŒOา‚แ •—�AOfงƒ€ิ๘ู๖ฮ>๋ˆษ๗ฉฉqbฆ40|>ผ๐k/'ฤBl๓ำฤ่8 ดyๆ ’ย็Xkv๔๐�…๐|aเญ๒ม็  ๓๊… —ฏคื>ษ๛๑<Q”m3�…�ตH,คgžใซzฯN 9ึBดฎe<I(I 5=/\๛~†Ÿe$Œk%๓ข„5]ฤ8ๆีŒwuuษqss�Ÿ�๔�ฦ/�า็%  ฯใ๔๋tž๕(DEฯ๚(œ��37oผ๑…“๖�้๒็�ฮ๗ฎ�ง�ีฯ�YcE้Wษ<}ทนนก3ฝทz๚:�คฑฎ๚๙ญƒ๕ณๅ0ญญงด#โPิhH&(nฃwl์>™‹,ู�๎4Cภฎiะูs—"๑๐�*ไ•0ถI4kaป1๋W๓[ั2o’ *ฯ๛žD`C@ลk (d� tB๒ส๏‚เศไD-zWG8ๅ�ึMฬฑrวฉ้‰ศfฟ๙ฝฟข{ม๛ส( ฦDfE`ณC๔!฿ทๆ�{P’ซดZ'g ณ[fวฬโ๋• 4฿Œ“@พ�Q…้ฯ5Vง.ค๋-ํดvBฑต‰`‡7‡๑ะเpชEEก��Œย†ษฑว้๖ตd๕”'ะ>=�อ�๘%I!;$“lŠ ˜* e๕Wฎพrศ5๋‘”6œšA’4aำ์ฬ“h‘ฅDci๏€๒4q๋vZž˜Jญ 6ซ"!H2R~‚รbฺe๑ฬฃีโ! ะ๑ฏไนืขœ0ำvโ:QB@J๘oอ<�!ไู๖œ7Mz๙0FเONฯ๎C€„ฅšF*ฏม Jc7ฃ*UึR๖แp]‹ฒa1ญ†D ะู]Em€Lโกพฝ;(> ฬี2ฃฝO๖uBื‚”rgjz.}�ท!u0tj้ศOw๎|@C_Ÿส๗ใ‡ศ€/q๏t'ภtฑณ9ฝ๔๑WR฿`?มŠ˜๕ฅxีdรธฑ�ฐ�J`อ๋ษr•ะ’Bขญน•วถyydฺfœชศข๋๗ เ6sฦ›ุ„หNฏพ๚ ๑ฮ4๕ะ.ณdCษิE”จ–,ๆ e๖ศา—๑ฬ*Pœ�อำ็ev <7c>:6สบฌK��ร ญฌ+^H)ฎdŸ=ม5ฐณ�Zฒ@—vƒN"ห๐/Rสkะ^ocฑ�2อ@[?nVุฌXžk1๛ฌ2ยa3+ P5‚sญnธ žOธๅ€Š�ศญ฿‡ะ*ฯ๚ผเbึS” ทLžฟ๚"sจ8�@EaŸvมฎั� ฺ๙ h‡IEษ”—S๓ ำฏฤ๎ฎีr๖•“ใฌ/ืr�#ฟซ6ˆ1bภ��kyช,๐๗ณ๊�ทฆlย@ฬ>ฤ�๗s‹๑ThI?๙“ฏง_บJ&0ม�๔}๊๋šฯ�๔อo~‡2ชึฎcท ค]ˆย��๔าK—ำ_�zZ{ฒฦ> 0ฒร—H3€ๅ’ ฆ˜e๖ฉP๐ุ๔—๑ห็ไธูYม๋1๊kผFeศfศอ,—ฬฐWำ�D5ƒญDญัn| ‘๙\‚ฬ๊ฦ๔ถŸ=I6kj๚n6ฦ~๗Œ… g'ฟYฺร-ฅ้Ž#Wภ๕™ำ�พพ˜s7ฏณŸ3 k$ห)Mpฏ๐fห ก๗ฉƒ็็๕V้๎์F5D˜ณมฯf0/ูใ๘LษO3ะ'zฌ๒ๆgนื–ฒj ณๅmfv„๐๛‹๘ง`m๓นใฝfษl3วถQWeY๋lAA *%ฒUcโ}}>07ฆ*3 ศุ“T–•Aะr)9ศ�Ÿ๗�ม๙ฤ๏พ‡$ขŠŸ‰J3นMญ‡‡y๑ูศุป_๒“dขk  ฎ9Uฏ”Bข—๑น๓ oAุทP‚Sสตฒi8ซฟOwW'�0{”แฒ‘-œsฟๅฬ;ŸฝคLpฎวึ›vL‘่๓:]ฟf˜sœส�}ž–ผdซ,๙@a0P1W�งlYว™3>�ฐ[ฤ^ฺย™Oื ึp;ค�&„ร{\‹ณฃ Bpfj@ส˜;F(๏œฑ^๙lอ�๓.e6 –G˜t๐๛ผ5�ๆnH‚็*จWQ"aกฏ’O�„ๅ™ฟ–Œœเฎh๋ฅi๚x,]ฟ{'ึฒ๏=‡akks๊๏้)\ไšุ€ฬ e๛0_ฦ^S-kยไ‚„†ไ“gณ™๛}T–�ฉZ`๒๒^t็am‚\ณ�ยมืwv๔ฐฃŽkla?ภK’@[’c‹`ห3œ ฦชN)ฅัKภgUืิ*FใฯึZ $64ไอฐ†S๓จ๔4V�aฯฐ|ม๕Fอ ๑ฬCฏ‘wd์QKฑ‡๛eูh=žU*็\ร�นไzฤ ๗ฎถู–7๚์:ฺZ ฌ๑Œ่l�gฟ�+ใืฟ๛ใ?w๊iฃy๚Ÿำ๘ท#pJ��ฑ8�ำ38_๙สNP ��yใ+_๛ื�ฏ�๛_�ๅ {�/^๙ฤฯg๙sฟ๐๖�๘ื?๕ํ‡ฃw๖ๆ/ๅท๒™ตอEnj’ืถiรDึดถ…ร่8ฝ‹LUน�˜๑ฏ฿N"้�เ@— ‚ …^ y>ี‹M+9kwwฉ#-ข”ก‚~ศ•ีคi"ลแFPi@ษนHcŸgฒz๒ž—ฦๅ›m”'์“y[ๅฝษจNŽ>L๗o�€EฏA^�2ๆญuk�‘š#-�ฯเฎ�‡lบ'๐)นท๖786˜ฺEFxH Cผร/€ ใ�๙ˆŠพtฉณJคฅณ•  ม">‰`a2ลฬๆ;o~+�~�๛i}~1ญ๑หŒ{ฃ ฯb ฐ้แ:.ฺลผw๏•kKsarุ ฑƒ4�L&Vภ ฅฅ^ฮฝ�ญNํ0กด|l‹฿ค\eŸ‹%๘S.n— ƒ@fFฌ1ฎ$ำUJึถˆ ฟช ‡๙Rž5 ฐณ์Qฯpz<3&‘P๚ <›ฯหZส@๐VŸ†ฯฉk`(•๒lถx�*Y2HJ›ฺzำศเsศ=gำ�ืฟวตฦ๙9๋P]๓S[”Mh*VK;ผถ๎ฏฦ๔�ฅ็ุ�ฝ๓>Ÿ‰A๏ีL›ฮj„ก+ำ™๓gา6๎๓‹c”ภๆ็ษŒg T.G'ดR4็๚ยด „aM4N`ูƒ[ก„[=Š= V‘๙>นŸฒjpนGฏŒAดฤ s�ˆ ~•็ (*aMุ๗๛nU&ส�งฉํ�ฌ๒œำฉฉ้P� พฬ|nขู KVมŸ5ฝ3sอดL๒ๆณsฬฺ]ษ�,‘ ๐ษSJ$ะ."Hๆก1gฅ‰DGŠพYช๖‡ืำ Oyล*ตปค๖cWฃB˜y<ฦ\เฝ๘wKqตWQฃ!ฆYlื�{C=f|9ภส…KSWOc€zโซ”๕sL6YB+RงrภฉJ„Užฃูw.˜นh็T.(ˆ$ Dwึ’›1gถ†�X+q ธW๕เ�JD๚}๚}วอ`[าภLmศภ™๓Ž/๏UUนก`Ÿ๊๏ไฝุ‹(้YYฺโylAT�L฿��›\wกผ+ )ฉ<ฝŒ5ฆู่ว(โึา_~ํฯภ(์์A‚0ผีtปœMจธ๗่;ใ<ะ�ภ’ซbฅ2๖ ฌuะ–p<�y#”์ป<'๖ ๗�J๙�“ท#�พnHฬyผ":SkgGZFr}�ฃฺ๚œ@ $n4-cX�e@r,‹qฺ‹-็y•ฐgฆfgา์$ž-˜ผmำํ"•นฑทV&ศ4T=์0Bฉ๒ข ฟ•†h” ฒ็aจ)h=ภั๖žศๆ“ฅbไŽS0v `IœnrfŠํ`™›ฆ™Ž›๊ฒ<{N%d�1€ซ๐]ฤX6ข๘j๊เUH฿๙LU›xผT`ŠXอuฌQข *G9๛“ษ‡iลQ5๛š†บUds๗๙UCGจั$t๔ฐฮ]P๊๕š5๗๓%ฐ0dพbˆ�Ÿ}"%$ํžEฬืƒ ,‰ ž0ใYI)รƒ๑‡)ฯ�ำ1ศœb;ฐญฑ๛y {งdOฝืŒ*dตถฯ๚ุ›=ึ<3รนd[า ึฐ`�าƒJๆŒ.<35ำeถD๙ศฤซž{�ๆ—ู๖�P5HDก�ฒฯ‹Wฏ2ท๑ดa[ช มไฯ+‡๏๏๋รh8ฎ๋ษ๔ไป Cฦฑ“ฌิ„Vฒ%ˆ,ฦฮ๓ุl™L = ห1Jชช๗\?’๕NJ๖tกฎR๚e๖! f}v™#mญ”�น%1งZ๐.aO๊ขฤฆbฅ˜ส๗jฤ็Fv‹ โ•b9ึ๛ืXm�?๋D2ดˆฑ(ๆWŽ5j์ก9ข๛C”uIl0n9ฮี%=ฝ}�ๅ((มZ�บxฦ™Pถุ�e›9m$”kFฦvฮๅl}Y˜ฟึ๒ชฎ–YsำsSt๛ูลœน?]x๎ „9๊"๎sล‹1ล๒ฑิา�wโี9–^H๔P"ศ|’(๐ห’�์ๆบท�ฆ ž3๎๋Ž๑&ฯฆœ๏ๅ8ว<‡ฑeขฌ’ฒฎ‘ทค$†าห๖šสขG๕ 5_๚์O}ๆท?๛ูŸƒ๒ึ๘ำ�œŽภ้�p ิ��z๚‡ำxถG จจtะฟ”งอ,,œ�ฝ๚;�ษุ๕ท฿�๕ั�๗.ดun–g้q]Rิ˜n}t0I‡ูๅ K+ใศ ‘�ฏ“น 'ะิฑ|‹บL3CD|�Ž๙ปํ๚L9ไHฬ ฺ"Oภ๒ร'{(@7sโกh] 3Ž�n‚ฯ #็‚iŸŸ� ผ?ž‘0๏"ค>ถ“Zะห้ไ�-ฎี:U�้_„f"หว๛;ถq{๗ญ7‘M �ษ~‘%—๙/Cฒ]lpGป*๊Z;�ำศศzLOงF๐�^>w>คซ๓dฐ”ฃศTษ—˜Rˆบb3ฮส� †ฬ2D›ีšGVYE 9xv$๎WR`wŒž�d๚3d"4pฌ ณ~ดƒ”—{ูXiL#ฮ“AŠฮ๛OOŒ‘น#่„ฆข,ช“.ฉ7Aดฮเ3ำื˜eญYeน‚เฺฒก]” ึ…w๐^�ฬซ˜—Nง™y็D)ณi|br'อcžHP.81ณm;Xvณx*๒%~I’˜ฅึศฮ8[2@rภฝC %‰ )เ๋ž’ฑWYRS๓C AึŸแใ๘ ๖'~�๚๛7๗�9มˆ๒ลp~qi1๊ไscณร๖Lฏส0—๙lปmdN�mซท 3y.ฑ�Gt/เ3,8/๙ @0�2h)๖=เ-”!<œMว<#“ ๎ีฎ?U’ฃซ‡tไ ตข{œ_ซห”hp6เ\„b‰ืr>.,rฟ�ใใ‰Iศ พ lฦˆ6X/’Eเ*tฬฉŽพN”inโVZ™ŸไฌeŒ!รŠ;$œ�/Dฅq๛ร>D jŽm’ ฌ_�bVHZดAตถtงรoฝ—็งู?Qะ0nฆvฦฐtA"ำgฆJรคุา„:”2>๓9’๎ํ>ฯg๗:ฟฒฌฟCฦฏUCฎ โ7Wน>4ุ๛�ฮ|๙—๙ืว™+ถs:�:ำ๘�๗แำฏำ8�Ÿ๘ญ฿๚ย�_~๛�›ฟ๘‹?�งcwn,ฮL<�ฑŠสฒRฯอ๎m“ตฯฤ๐-X!.ฃญPMŽเ ™บ5œRึ{dิอR[ซปตกRลCตˆดyฆiJk 4=ˆ ภ=�”๘z(๚๓JŠCRศŸC Rภ 5�๋ั&ส,–†O‡|ถ2้๒I3๘‚M�ศู บ๒[i@พBญ!\†ผฎพ™๛ศ‘ ฦ@Ž Q2cyณ€ย์V=Aํฅ็/ำ†pVd8๚{า�ัปd6ศ๔ pะw่QO ˆUN���ฮ(ฏ…Xแภ^^@ม@ ขป๔<ฆ]�H7อPj�X,นg๏,ืA�Œ์=ตฟิ9ถwท€!๘6";ษq ฦk:ๅŸmฐๆฟœ`a‘{นw๏6๕าจซผOi-2ฉฝผ๓r๘‘๑้ 466ว�ภมHุๅ`+?�!@ฎŠŒM=„ƒ`ำฑ:{1ต#�ด6rยDะQหฟKด4%>ยkbf6ฺop/vQศ@ฮNN3? -Žg ใช‹๖™-๋ฮ7Qnญค†ฮ๔ส<5h+Aฦ�ๆoฅ…uŒ'O& ztF7๋SlวuญQc]‹เ>ูFึkP‚-œ๖๗u…/˜ฒ้�Ÿ๕่:ู†ธ‘„้่Mญ€ฃ คฬอd:o฿ธท„ส๛ˆฦฌ: �‰A๐ฌ�wŸ๕ถJTQAR*๕ืtNล€;๋ืา็งe ช)�|Z�เฟ{=Olวลฟ?�ๅฟ ฤ˜O๚+„ ๛ร�“Eณ'�šฃs‹j+๗.๛  วl}€(ฦCฃมหxeX๛�ฯฟ๔GH๋W ภŸq0sอFc๏•๑ผTŸhrฆ๒hkUๆ cๆ…ไไฎ ภๅ<๓zร� ฐ$YฅˆG{aฏ<น—ฺ^ฏ„๙ิ�ืวž๖|”RLc.๙ๆื� šรคP#ูถmๅษ ™v„\ฒ�j@Y-{ฅ ฎ*’fึZู�ญM;ฦฌณืQทอ^Qฤœฐ†ฮ+ˆ=ชุ7ฬ†3ฎO]๋ซ•�šxฎ.R*ิหฟ—ฅ9@™r๙–ฆฆ๐ค@�ะบ/Y๗>ฆํC5ำu๎bJH4{Ž˜ต�cŸE‘=ฯ ผุ�B1ััำว{@Šฑ~“๕€โk~ญข(๒=T0ี๐kŽ๖ฆ+”nมxๆิ@,ฌH:p๖(;Kฒ9ฏvศ:ปf-'2+ญ ?ัฅym฿0๛4{k[W;gฤ6my๙s7เ‘’ีyฮHฃS“ฉ"`UU^ž�ถ%vิJRฦ�ย�XOGฆ*ศ�H์MŸccs�ืธ๏†ยฯ}ศา๗ ^_YZมต45คP๘ีaž[ส™าIะฬ�ตMค๓\mcZ็๘ศcศฝuŸ’4‰M๖%ษฌC��=JRSe„mmนํ8๏UGx†P^ง™`จ& ๗๓�…ฌ~็^gwW(Tรฤุฑwุว3g‹9/๐฿€ผ”�ำX๔๎ญkq+จD4๛์ค;U๗ิ90™ิฆQ๙lsŽ๙Œึ9Cํ�ฬกš(ฝ[ •ฑ*ฃ5บคx}{(๔$yƒœ�P@์ƒxศปxOŽAฤMŒ=~f5ฬ>๓ฦuQห\อ๑Œ- ln sัม�สs็ฯ�ท�๏�๖?พ|๙ๅ9จeง_ง#p:�ฎ8%�]#s๚�ำ๘‡ษ๑��omฝ๙แ��“ฃ–oํlŒ,อOgwT[kŒแA-1AฒC]ฟ ไ „ญญ&ฒๅPฦ ›ˆdŸ€ื€]ๅcฒw‚=ฟ4;4เ)<�ฎ;ตm *lร5œผO%fXT;่nฌนำ�ร�›I–็y'kหชฌ}฿๗ฅ—๊evฬˆ…"ƒ’Lห :h› FP๋‡lูฒฒlch…Hฺ iŠ)Jค‚ .ฆHั0ภ`€™้้™๎้้ญบปบ๖}฿ฒ*ณชฒฒ�<ง0!๚‡,‘DdึDOwUeๆฝ๗�sฮ��๗{ฟ๗๋๏้คแLŽ#7ฟโMฦ•เค”เuh๐\ฌ;œว(qyžบk@†N๛๐ีฺ hใ ๓safj*fไP–˜�ญ`ฦค"@ง๋๙2 d‡Fฮว �ภQ`&ขฬา๖”Jž .ึึ&ฮฮแ์�Ffฃ*�ฝ{Ÿs$#ณฦUงๅbƒ($ขƒฃ}แ‰g.†#�วศ๔ ไ๙L�m-4*>�๑}p�>~355€‘$H+0ž–๊"R(:vึึ1%\Œมฎา^cuf๙>๘‘>’8ชb ึ�พ&> #ทฮ๙า�‚7Bค๐dมKฯำฌ „"‚ทzTใSำaเv gฆ5M€ฃ”๕˜:ฎkšจฉิุฑ˜Œมั มsช่ฌJA>ศ� ภn� ๏aˆxRึภLกํ™๓†vŒyิ dแ”sฆ*j ึฌฉ”“uœ™YJQOjpฏ’d6�วูpํ฿ 7^{#ผ๙๕ฏ‡ูq�Rดข"่ำ�” :A&‡ศ‹,& ฦ๎าฅงc›ฟˆ�๒j/k!ศd�•ฌถ‡sO<… •qฤ,.,ฤ:A iภJณRf๓ๅํ๚ัy?ํq๏ญo†๔ส<„ ๗Žน“EzฌtV€d+Iๆuูป1 "DD™7�$ื๒�หžgŸf~W„;7฿EัQว›}ัอ์P;�์iฎก—j ฅ๒‚โศ็ฅ$‚(ภ€ิืŸ™!€sƒ฿ฯ>๓พ3๓0ึฉคkัฒ=yV2ฎศกญ๛$Jdๅ bญรทคก ผมํ๒v�,%ฐ+„าZษ2ฆU4พ‹k•ต–dœZ:ปhฃือบฮpอ5kแ[/ฟz–)Enฎ)™ร+ุOr\ถ€�ะฬ"ฅณฦไณFJf2% �WH๊�เ^#ธŸ$x฿SD#u=Kธว๘oฟ�ณ$$ํjขู ฤ ภD>Mฦุร[๛Jฦ˜m ^{q<Ÿณ๖[๑E๙�“ฟฬ๙dรo�สฟdข$I้ t อน ์๔จlnŠฝแm+A้~a๛Kkิหู‡H^ป%$zฎฤR็?œ“ใ;ฤฐVœ๗$++ �>†Gฮก:c๘…ฬ>z �`~Aถ’ีฌc฿ำ•�”`ฟ.แ๚>ฅ€bๅ�ปศ๚Ok็1qปtๅ ฎก:ผw๋YSL !(”ษป_ซxRmเ>^่ำY฿ฒF]oŒ์�N๔}žฤ’#๖WU/•ˆŠธŸeซ(Œwšน�€ภ)๏uิŸฦŸI|Hค่~๏|-†(เ/ถNๅ๚ฅดj„ณ๏๐Q๑๐่ฅ๘Zว�Vท–Aตะoฟ{#Lเูcš{ฯ,๛ฺ�๒๒ต9ฎ…ฯโ:4&ต–?๑ตศด แฬ5sำPch ZO\/ =ร}อใyึZZa{ึ ๓ทŒฝ�  ž9YอœRีc9RฦvดœS{ž m-ด8Š๋~ay)LอฯDR๊"ว9ัว5k|ynxึหƒ\ว1™๖HBธ7,ณDUฑฅBฎŽหฯ8Ždf๔เ^ปz|๗_็-ำ3๎๓๛”z=๚2ลฯrํqn•ฬ‰หฮ††/ะUa˜ฑก5ญ~ฬำออe๎51ธ?%Œฝ‰ ฏ็โีKํถR�ˆื d๗ฅ8’›:ช`์-ํ์>ืฎฟC‡žuๆ•ชžq”,$ ๕ฎ”๑๒“š’ฦฤ๓ภ๒ป4Yขแ9ถ’hฐœล5_ฦ๕‘†”ญ ๅล‰วฯ~เฉ�ๅG�‹Ÿ�๕๚zฺรพ #P๏ˆƒ๏^P;‡ฏผ๑ส5บผต<ปtบฝน�ƒ‚ bix–‡ซZทษ € J๔28ภTอ,ร)ภQใ#4›2ำmฆAูฏD_oถฬฯเ^ hภnโ๏.ส uลฝ –@ษื�nMV�๓y‹<Qํ๖Hผw๋&%ณหฬูJ>'eถ‚B€เgDๅเฆ…A๛๊SWษ 4แ@^G†jCบ๕๘ _[ท6ธƒ HC$ ๆึ๑kN(๓/Xั‡AไFฒ�f ฏฟ}-Œ�็3 ศไํฉ\— x๑แ�ๅ‘ะ?� pขะ0ะืzป R‘�จ\้n}๓๚[a _<7œ้ษIdนฉฐถ8+๚ํฐC๖[E…’Dƒ"๋y v !ช!?tย฿hภ4vo,œะ _ ๙A2แ!ู&ฅ฿้ฐบ8KJx‹ `5eKƒ฿2ศš}~žๅ>r๛ เ๗ยึส:J ๛ื—!ฅ%Uy™=ฃูnฉ5–ิ9ย!Ÿู t(ธ๚ไ(ไห่‡Eอ๊>Y:@P”“ลฒmgš,K†{“ๅ๑ส๋ฆ+ยไฤ$ ๕ฤƒฒ๒rnc˜ŸŸc.3;aโํ{a›เ+ BAิIะห\‚Pช$๓ญ1c9„ฤ ๗�ฮ สUUฏœ’"ี ฒ@W Xฅi�ำ…ฆ๖ฎะ58ƒ฿,'๔x๒1ํถAณีdq˜ำ‚'Œ@ถ–920ิ™^[8แ<ๅ<I๗nb€*†>฿)JาจJ’€Eฒฏft•ซ€่$๘,/Ÿ==ํฐdถN๐ํ(0l,ฏ…•๑iŒีภ$Ž$Š๋)๖zl‘ๅ3 ฅฝ ิŒ•uอึ^๋ ๏z{_Y#4ธ&ฃ$ž™šฌ๓‡ีษณbฑM*s�V•ฑใs h9`>2†Jญki3*ุดฝ่sฑืtฝDฬŒEc?ฮล๓ธ™1O๏ญ แญƒ##9๔RGaA\LซฟฬฏD*๎ำQฦ๗žอgึพ{„ฒ †-LวHจน็๐โธพิ’���r25วsOั3@Rภw‰k!๘#ฑ๐พRม฿ป฿.๔ช0›,ู ฌ^ณI ม๐ูGpLH/๋พ-OษŸ"Ÿ'ณ™ใž~�{?>๒โ แอืฟฎ_ปษ๕1�ฅผ—ตuยžTล\ฑl@0Q†าƒฅฯQrิ9ญ$�/ _๎Yh0Aฤ–็c=น๋ิา 3์^ว}dd(<๓�ณแ�›o`fษ๚€tฌ,‡ฌใ�XZฆ)_‚�V๐kVำ}Rƒ๙…ฉฐ4?Oญ6{-„f๛Hž[&>|4@ฬGฟ„-J๔˜๐,•าGCKึ—c๊›G=rŒ ˆณuK ๊‚์-[gย…+Oฒ�ถ ฐ9 l`;์mฌEๆ<ิ‡มtำ�9’t๚;ฤฌ:ร๎�uพžโOม๑๒์[% E€สh๊}g_tึฐฏปO้9Pู�๊๘๕๗ ก Z › ณtYภฏJณHž/šืนฆw™๋๚„ธฯซคา๐3v\�ฉžชฌ`ฒOU5Vโฝ‚ม-วTQษ~Xฦ^;;9฿๛  rŸ`ŒQHฑ!ฑOน� [Ÿ—พ�}าQ๙�4�Lv ‹Žศส;gใ3ิ๋เ€vRก#H?`Ÿะ์QSDถD_สiXO5`์ ’CืŒ๋Tb—G† ‹Fžs•6๓tษX <ร๓ผภ~ฺ‘.‰Ÿๅฬ#KsŸ4พHถ้ิ0qล๙}xถŸ๑ั Eขqฆfญ�Lวxชฆ\๗%ฤ(ฮ) ]VAุeE฿x˜MT–›จR4๎ ำP$88�-๊5SM"ย�5‚d๐�ลHžZ~c{I็&ห ยพŠ’�ะRšร3ธ„๛เณหDK3†วMt์ฉเ™ถO‰ำโ์k€X†5$yแ�ข*ฬ9กๅ}@IDATใ~ๅ�#้ๆฟ“Œ™&•อดcFฝXมšตาŽU��๗ะRŒ2zi?�����?ผ๔kาœ…ฏยFเ?` ฤมภ ^R?</ฝ๔�๋/พ:๕�๘muv|nvn�{ทท6ห0ำ*6๘ P> 0UMภำ8>๐ฬ.˜�ร–- ง�“ >Bณ‚สฃuŽ;๔!<แแ~€$ป˜฿ูอเ˜  ซn๖ฮ~+๊๓ษ๔ (Šqชฦ+แPEs ฦ‘–า4B™๑j€ ส0วoฝfง&B+ว#๎๙™T>ฤ"{จoผ๗M”ฌจpฑ฿ป0…)]/†._Dๅ๑"๗n%\{๙�„บฒ[ฦฮบ�<5ฐขฯ<๗j'ฌ1—%•:๛;Pค<šiGษฒ้นv่ต��กˆ [ำQ๏๗(XZ‹๒˜@]_ื„7ภ.๙๘ษJ2ศ’Jƒน๔˜ัฒE— .ษ›%j๎wฬพ ์]วอ=๕"8„40sฎมa๓wŽ๘oฃo;^วR@ภฤ์ธPCฒๆ�ฉ2aIวศ~j๊U?’ �eณ”8ํG‰x5ใvˆšไ]:LMOฤ,x-EA3ืๅ�้œ{)็kI‚คขJ$ฅฏ#P&Cjๆป‚,๐s/~0ผp๗�*ม๎๋๋ฆ}ใ-๖šซ2Lะ ฎž:ใ๓ศฃYla…นอ๎ ”8นoK๏๗คค„{Šใ่~–(ธ“ี,ฮQฎ50ะ~เ?3ฌ�๔ ฟึืใ=eXหDจ!ห฿ !•ฦำภy^ย�ึy? $a Aขม$ฟŒฟWี!แ™e๎ล๒.ึฌฏS‰ฑ มน…๔ฟ RฦLงหฝฃชๅkทw  ยBข) Qd‡ezjœDท็ฆใ˜๎o“ๅo#k�ณข^งj,f sะ aXE;ฦแั dTG)�๊ข-ๆx$‹3–(CdCๆ๊ฟrยzญDฎ-ูกrจนU’€’=ไˆนuยu4rฌอ๙น%cผ ภ๐ท@จนฅ9วXึ&ˆฏ‡,แs%6Ž๏%xm$Hžถต๗F ฎk}3„ขพ�{E•ส‡^ˆ“j:7๐3Mw6™Ÿฬ๗NˆZี,tcฑV>ƒRFยซณoz๖EŽ‹o๛กmg๋ศ&ง!ษNธ*d\Cz|่c‘ๆžY!)ฅ’`}eo€•ุMมฌz๓[ภk็‡cH”^EฬAหmขยŽ็จ%?'{2๋ „ชz$ฒ$๗|พXje๖ปšjๆ๖.ๆŠ‹งŒีm‘พถ%dBฦ�;๋ะษ�๒ ]…"้ฬธVQฯ;๎ณH=HH ดฑ๗uu‡อ0ป4•ปฬ9Aฎฯฑ d๘ซ๓+๒5ฑฯX ๑ ซtล‘ธำWฒ'ม=ˆKฆk๘ฉI๕ƒ$Bญฯvณๅ�ฬ}@ย<–<1.;จ˜าS๐cํญญRึลฅT[จถะ3GUเ1๋��”s<ใ๊!„zP$8Wืv้๚ƒRส2.‰หฬ–~ชฐ,1ฑด‘gฯD9๗=ๆvš�็ะuฮfcา †ญ>๋8-๖ิ H Y็‘|ๅฝ�›๘แp฿ฒ�ื๗eฮนตต•ไŸฉ2ใbศkŒฦ�ฯJอผFู๏g1๗6มฝ˜™ oฝ�.๓†’<ƒ$.TIl$!!Tm•ซŽ(Ž-,ซkx~smิAlกะ๓>s)+�Eฝฦ|AAI๗'(ะ๙ฺ๊ส๒7�ว�yccว™!ฬ๒ �.Œ@a�#P �CS๘Ea��Fเฅ€๚เ่Ÿ�ณŸIะv๐?ล”0ฅ0v'เ!จqQฌก& 2ˆื…Y49‚ภ ึิ1๒ใ1วCWžAฑ`žึ\<ˆฃ—ฅ๏506ำ^G�๑o›ู฿kเา†ด;ณทจกD,ุฤภ›�ล`@๓!Aณw‰ญ`หถMA’c;,-ฬ‘ฅJ…พZ?‹Y�`{|›Aฑvี`ผ€rpˆ‹gฏแ,kCภh ,เโ�*๒w฿ป�~�ม๒e;1ปQMอw ภdˆ+8๕w’ FF{BเฐJญk ู-[�ivธ@๐๐uB5ม๕Yๆ6ฟ{ญปd=ฬbิCด์ฎฎ‡ษ{๗ยไ๊๗o\งŽ’ „-๔สล70&˜๔!Ÿอo’น�"ธูc &Ž…w฿~;ฬ“๕ส"4เU%P)`๖ึ?fp ศช–kt !%๏L –เ'ฆถู:B&9K-๐ฺ๒2cY†*ก)ิ463>*r%‚"อะ๖!+ญƒpQข+ถ�ฏ๋ีฐล‘๛ด2’–'h–ง™ฅๅ$’D9๎k&ึ‘าr฿˜ เ๗�อ{ฟW—ืณแ›_๙Jxํๅฏล ๓'|๊BcgGu:ธ' ๎5;ฺ^ล?€ถ’ดO์๋‹rื}<ข9โ ’โG๏� ใ๏� +™ั'ž =ƒ#ฬฑc๎ฉสqฑฎ 3ฦใ8ฤ,?sBฒสlr�๎aœ�ษ”—ง8ฅuผพˆ9g๙H‚`=ƒ9ฅ}฿0]žŒ oๆ๑$˜]Œญี8วน๑[dาF”ด๓บๆแมPNถท๐า†Œนเ ๊เ๛เ‡โZา�ม˜๙๙iฒฅึจHTย˜‘v�Š XธJ�“€8วฏŠเ�ฺbฅถศŽง ูฟ]Nๅผ&šภ๐„ไU�ฎP.‰ภ์็u– lA๖1/˜o“ึSžcpปร�0*ทw>๗^�มฯ �OJ!ฌ้%ฦTqcc7ผ�ลCJฮื€ฺx8ฯ็)รuษฒVํv๗ม•_‘``๑฿ม6~ผๆ๊3O‡๙ฯ$œรไฒีMท๒oึ๔ทฎฟษy–น'Jม�,ษม๏๙ไ'รgพ�/ล–งkHv5ๆoe-ถฃDฒ ˆืTฯป‡xM๏+g๗˜ S์๊า…ฺไโฅ‹แล~(ผ๖๕ฏ‡WพYวzSํ"‰"Iชชช /b�–l9แz5อSaใธESAวŒ๋w๏ณtDBะ/‰�[Ž๐ุX (Oฤ‘|eL”k${J&�–+W/ฎV(Uขฤˆy๖„�u=62ิพฃ„โพZ–Uส฿nrส�ํ=o๗”} ฮ๏>฿ฬฎ€mต฿จก�x๓:ŠŠ๋QัSรš?J6แ฿‘GYกwB„์๛- จ šู—Q)๎บG.ขVกmSะLm{…> ‘Pฤ็ rŠี�รฒุG๘c@&ฑ�Gb™บ�Šภฒณ�์ ฯณNGึOC[Ÿ‘p/c� Kณจ (�igอฎ,BZ ž;๑2w‹์ฬ?e�W5ญจฐQ;m… ˆgหn\๋ 9Xศฎดa=h‹1l 4ฮ์ดD™xžš๐=ฌMื1ึsspp ๔ จฑ+ั*d๛T/~;†ฃ‡Yx[๕r=ัฏƒนใgV8๗$�3็ั> �ฌŠ๓wพkL A!™�สึ2OUูีPBWOIš ำVOเ�ัิRpNณฯpฯธV3แ*$ผ7IฮหใI H=น^ฝ7>๛๕ถจๆžุ้ภ็็xžป|ึ"$ฑDหSWฏ„็ฎ\ลคp.ฬใฟั„2,–o๐™žงชฑพฎ^๖M�s*”ฃ[f–vๆฐCF)๛F’u™งเฌ%{สw๎‰ŠF[tJp่… y` Cื^ ๛ezถ7tฏ๔|��?žภศw6>็สx.บ้9Tล/i47?มุpฟุ'œณiT8‡�ฏอ.)–ถP*จฺม1๒|U5,-ะกda๓f�ธ&หSvvT•ุ:บ�b9วcŸˆ{๛ญ{ฐsŽ๋ึ˜ล๋Siา‚rใ๘๘`�SŸ๚ุ฿๘‡?๑นi ไง๐Uย�F @�ซ๐าย�แ๘์gO‹ฺ๊ฟ�@ฦmน�๕yญลขNHb‚‚ฌ7–"Pึฉ9•ํฝส0าา|ศ‡ฌ_พฮLš~ƒำ(ทๅ฿fCอ๐`ย:lK๘ž๗Rศฮร[“˜�#่7pถvี๗Y ‚ฝKx@ทฦถภษƒณ2l�ณLญกว7›ึHP$ ฺแœ{P›…\ —g๚พ�XปOถfui)LL<ฤ4p= ๏&3cvaff6ผ๖W_"�':Fw)07๘Wข8ะษb{ภ—k'ะ4ฃ[ A ”•g?jIฌี_ฤ<ษ๚�‰๑๛�ฮ:�TธjมLืฟห2c๏ผŽ๒เ0ฤv<จๅ*:f๕ @Fฉ��็—กุgš5n-oˆ˜‰เž Ÿ,#ฑ#„�พอšQึซม~ืงdไทO๋˜ะแ 6k}ฆฯbภ๘€@›ž๎›8Tง0k‹N๘fามœ fl>ึล—#�Zš ฝ}d5ษ�ธฦ'&ศ๒Pž@›Lณ’2ณ‚Žน`Q/ƒcฒ_ึว›Dsป]H*˜ก<ไ~ฎ"Iๅ[ิ%แฺซ฿Scถ9ฤCาก˜เ�NลdcNษ๎ๅvC มj-Yๅc‚�ฦfไยU2Tีก…ฺฯ^ถMำs`2f๙ม�P ัuแา3(,๊ษฆ�m’�"˜ฎ๏� ณw๏@#e–�ขฆwˆ H•6+˜ซ•N์พ<9NY9rๅ efหfงh[ Jชฬจ6YœŸ%p\dcp@ุลa�`WU !)ำัำฦi�vL Y‹,Uู๔๔ย,๙€ ๗p€๖Y@[ฮiสล้0๖ถ'ธๆ>ฌฉต•`ม>1+c Qว฿9j˜–ธ“ื๓Zม‡ม~1๋U๐Ÿใพผ�}oๆ ZO๙ ็ญ™Ž5ึ�U’q’ ›จ-Tฉ?๑ #ษc˜^ Hถต Jƒฒ€ำSavvŽฌ ๅJ๓าNส๛uฮฌ๛yf!c&’๙พร๏_โš› ไ]3^“ูีœ„ ทe50ณฬoผ๑mภ'+8วN9Cอ.Ox�‡^�p,sŠeAรg๗฿ป%๗1X็๓=ž็โฑ<�ํfฒล์i-� †Gzร%J‘�๚…ฯ�<ฟ+ฦ๏‰ ๆ7ตะว6��์’\+๘เˆbฎธ'2จโธบ๏ \$ƒD†ฆจfฅ%UXBขคc{้้็!>ห,+H2&žS#†ณ์ซKฌUฦณ ๅม๎ฦ] P aTงชฉ”�i›cน5ดwว6ถ3ฦXณ˜rl6Iฦ‹ํ‘s8ๅ๓–K0มใ9a”จ'H#๋U�[ีึฑ?ํ@ุl๐�rๅ่ผš๛6๘ศx�๗ุw๓dผ›นๆHc=’<ใสุW๔ธa&ฤ็i”ุ๓ปf อ…็yV-ฬแ�3=อ9œyq�4›UPฯ�lษ–{€ฌ5ฌ๗ศเcˆ4�๚้Mกบnuc5ฮํั๓—๐ jไ5ใ,Aษ7บ„Ndถ๓(�Kห้ึ‚bƒ‹f�4œ;์�fหk๙<๗7NฆชH$”%ฅj™—๏ช%ฦŽ| ็e&พ„๏K™O;๚ฅฐ6ซุSJุฐZ(W˜™c๏3ึ`k๖ช—‹$> ช$BฺQ‘™้ทิลญcI ืวzอZ"!ม“bฝ๚L>d/ดผ0๎  ๚HฌชV๔�u@ศ4A"i<15�X ฏบˆŒขŠ,ฏฏDฎพž8‚kZXšcn@ฐCfซ˜ดีฆฤx,ตc’ฏญAฯอs\ˆวJ/˜ว^ซ-P9]ฺฃh`�Kๆธฐ๔fฒ|ส๘Hีฆ%ฑlŠ฿ym๚๙”๓�ƒ์ฮ$๛ะ�๚๗�๎O|‰ธจPžภ่พ #๐Gq๐Gฑย๋ #๐x๕ี—N้Wgํฏ�฿/๛{๊๎>x0� œฦ�‹อt76Fนฅ/5่4H?ฐ ไcMณŠ—3`คส�[ฒภm,Wเ=„ษ1� ™แ!ฉgGึ_งwž‰1˜0ศU.ฌa๑Jฬ�Z2a ~ฦโ€y8�Z@ A“ฒv {S›้ฐFQ อ–*ัLX_ธHo๏ฆp๗๖-เ{แi�*คฃGƒweƒ1่ใฺฺฺ:1PZ Kd{—่ืœ l“9\ภ\Kจ}พ ”ฌE๎@iPƒคะ๏7ึW ฎษf†LUฌ-.็ผ:P& ˜่% ฦˆล๛™ฉ‡๏๐gษคูN‹์Ÿค–ฮ^aำ1๑#๛ฅหพญ ๐4อJ’ลท`”ุฬ็q‡7หipa๋ซRƒฦใt j๕žะHฮ บ‡D‹’วMฒ_žq‰™ูy๊Wจw�Š@YB็iฆ๒4o=&5ะ”%ิc0จรฟฦ€ฅDึ'๛�kaŸฒ…ษฉฐGPvภ๕j• ช$P—d2(RfZIp ๘นช ฬXฺนBยHrม. ’SY๓๗�าPjภ]‚�22‘I€„๗ธˆน“$ใZMฦ{pาัEfqn เG xZœ{0ฅo6ไŠdO�PX|H<่]PLVwbๆqฃ^‘เ‹ฯhp0 !‡;K‹ฤr^ฤ;fƒ‡ๆLŠ๚ํแั‹ฝรฐ๔x<ไ8–ฌฦถ๖p4ไ์!รฬ|h,B๊,“yO2นEถ้ฌiโ๘xO๎฿ฝMUI2tำ๑ยเ๖๚›฿ฦืโ~ฬิฅศเv0ง5k,ƒ�:8e‘วe#P—ภ‘จณ5Z)@ชpk^3ลฺุZNฑาkA˜eC’p‘8 ธgุ"1‘FCFtฦฯ๑๙ผ“9ฑฉsL3��=ฅ๔’hธูRืๆ>sY 2Kœ=ภ�YอŸ<๗�€หจ^จบgิ4ตcะ (,ฬ๋H>ffXชเ๙Qฺรq$�\๙๚% "ˆใ@„ว qIฏ๗Xวฏ๓5ฺฮEuร!`y์๎�ุแฤต์gI๘9ฎ‡KฃฃŒŸ�๐ํเ<฿y๋-ˆฒ{๑๗œใ– wŸ๓$*฿"งyส.*‘b๏nฐŽ›ยว>๑๑๐ๅ฿�ฝp็ํ๗\ๆœ๏ g๙Fอ Khqj›นrศI—c ศ”Sว’(q�jt่9zฎ]ฟ$ ]วฎ?ฯ {*Fj์;ž›ฮ๒�ฯfDšฆูB2๖ปๅจSฯณe1 �X@}…‡‰{V‚l“N HฦฆŽŽd5/ฌคุฆตตณƒ 3ช€ธ�)ศาๅNถะdา“e†จrnq~ถ๕๋่u๏KQ๗฿ฤ�ศrOทูkP4 Bฮ]†๋”3�น ๅฺ๊•Y'P ฐŽบ†FP@5C๎-ณ6Hฦ.ั ขAโNษถํ๊z{ข™ใ& ทฝฃ›ฒ0T:<7Žx.คุร-กณฦ\™�€าyผหตNŽ฿‹ๅ"Iฦn%E–=ฯš๑cึฺ๊�<๛ฮ*eิขทu1–˜…rฒ์’8š๘ชา(a๎จฆ‘๔’คำ#D…ˆ๕้๕”?้/ณจ‚มgืkฤrผ ็ฏฑ„G"Hยซ„๓+Kฐ!ทฆำ’”ฑ/al๘-ใ ฑฤ๛ฃธžgh\�nฎ5๖ะ7oฤ{ฮช›<z้ำห๘2Aโ:qฎJF/กร=ฬPพbY‘ไต*ฏ ๖Pฟ5�;€dี"’ถห<3kฯz”M๘EUฺฅั aš1Jณf{บ่DC๗กjฦZ’5ฅฒร…หWฤฐ{๛๊*F†์u�>ืนํža๖฿—๎2/หfั๏๚\,B่จ์ณSC„W)๛bัwˆต HปeฬฮcVหณทž=๔�เPๆ�๛|@๙ฺฎ-Pู;๔Uะ@r@๕RŠ’ ช�R(ˆฅvQdุฏc<รkํ(”CSฬf,โไWQK ษ1ฏหไ�;๏27(ํj+่*๒�—G‡�๖?x้s฿`p๊พ #P?ฦˆƒ?ฦ �R?<ฟ๕ูฯ†_�ฅ�้ฅล…C.Zb๐šๆ!˜"Smหช}Žข3 13‡\Up๋ขฑ_ู๗(ื%�ญ„ฺ€Wเj�๚(ฝๅ+ฒe’A†ฒร"ข’ฑฅพ ฤถ]1Gะz@@G @P_F I›0H 3Xf‚  wฉ'ถ๋lƒฆVีu<๕C3uฝKศฟ๏�%๋TE;D\คฟ“ฅฒ%œวต ภ่‘`[+ีำI ณ4=ฤ๏“1เ)็~แย9Z,bจHํ:!? Ž($ต๐–<ฌฬฬ†;oฝVfgย๔ร๛aqr"tb๎ุEญไฤุ�๐๐๎ ฒ฿˜ šq@ึ›็๖ศฒjNf&ษv€Jtศx[/{LจCป™ีฒ.:bkœE�3›ีdฌ%\์ฮ3ะ์Š \ฟ&pสJK9'โG|่|@@ฺแ2ตฮ๔?o…HH1Žค��Lcท 2‰J(ซpฏ.ง ฉpฒ์โเL–™%XฮะJ m(†ฬ8เdvน/ ~Ÿีp’(pi ฃTYE€Gะi+ฎ}‚+eดYŒี)9ฐŽ˜แ42v’)Sต!˜2เฌ`ฌ•๒š๙ฌเ8๕ซmœgOOž�aiโ>“๒,๛]Gฐg๖- )dฦwy†ึz๋(๘™Y๎mDืokC[Q6�อ^็tcoฝJ•ุำ&rใธu๎‰-ฐษ|\ธžz๖�%–ย๖�\8ภtm2ย51๕๐.ใD็ๆAš๓�ๆx๎C๘P‚ำE�_ Pูม€’,!๗ข”๑แ๖…วฯ1ๆื�บฦn�รฉฯฆk(Jวf!F‘๙#?'ปอ์Ž๕๘ มฎ๒ึb๎g‚ตRษ:;s7ง$&’|ˆtYw +ภO€ฮฑอjฎ%i บ ่› '๛ S"จˆ๋�…วgจ8`ฎtBvm๖4N๕�”๐๛๛ˆ� �น.ื‚คbv3 Bฺ5wubบwy9dkR คูZt๘gฮG9=Ÿๅ^#q ๗‰ Gยรต‰ฮวตกys% ฃู R๊@้$$˜{‰๋4๎�ํ5งน฿fถ]_7ฎฟพ�ๅฏ„วว๑SAIภ˜ ฺ�ใž:cใž @1๛WŽ้กช˜คะ˜จd�มo�>ูq2ž€•"ึ‡i?๋จนฝQP[ก$>ช€ti฿Gฦn)ๆhqฏd�J<๊ ๎uFย„=ื�3รBvึณฆท4Sไ �ฮœ๐หฃdพปๆM%Yีž�ฮ\f&[?|[:Žf๙5ธmไs<ๆญU �•ๆซ‚RีฅiฌฏMa๎๖ษ�ม0‚!\kssšcฐ—ฮNMq/1ผใ:sฌA3ฃMMต€|Pvb„–พk‚'มฟตูYŽ_ม:…ฅbฉ๛จ2์๕mmกฎฝ…ฟ�# ,ฌp’๐€\eาภVu€ฆƒ-]-˜�>ษพ�AศL้8ž%์-ฮ๓๕าci�qุaฏ๏่:kYปl‡ƒูแDฅ�๖ฺ&ฦฏtŒมเตาYฏี![ฤŽSคป# 3€yxy’v๎ม(ป ๓{Ÿ๋Vqั yํ|ๆ†ใ๓ะe๋ฅฬกb.่ฤ๚zึgNเ ปup6ชtึYำ๚@lณOบฮn๐Œ™f_id‘@u�™eฏ\ฯ,ะ�‡�๓ฉgž„จด}.ฯ”๎‰Yฦษc๛R=zฒอc”e’ึgฯศ$ษ*ฦ ZEše3€เN2ํ๘�Tช$โ<์~า.กฤ\ทlห๎?๗™Sู๛ูg;;[ร�ฺ"{|:*ด|–zถ๘eมฑ^ฮ€๘ูbœPj๘ณ}žฅG์ู’€–3˜•ทK’%Œ�n=ฝ๎MM†EผBlนุศ๓ก’฿็๘ร‰ษpํฦ;แๆ�;๛›๒๗๓?�ห๏c๛ไŒฒธ่ยWa #๐วŸ …ฏยFเO0ฐืง_๚ญ_œ~๐่ัRล๒โ";fษ([G๋ขfึ ณว,Ÿ3�A–้|@ ใ/A`{$�O  dฬ4I ˜�&ซkf‰ƒmฏ|ูคW�มผษšใŠฒฦ˜!ิPhŸyb‡`Žเ�‡qฬศ ž   FฤBJ2�ทฒie ส?�P5f3ฃ฿ุ7‰ อ๒[งHA�0ž’ผ(‚T๔lh[๙สฉ5ศš™žŠAY;ฒัหO^  ึV™ฉ™ฟ,ูT;P(๙>^งอตoฝ�ํ0E เผUQˆคšZ:CY[YfถืC1มaU๔BPพ^Bง|>Kfc—ฌ่๕์๚ œxnfฝAล˜˜.ฬํขpฐ^ดผฎ…cะA€Œผ%%fxKษเๅ Š*•ร๒ณ,ฒำ5 มŽŠมud)›Zปck2มฯ 5˜ง9ZฮฉŽ๓(ฏโ^Q‡<8l)วๅฎ“‰ฑิ ˆึ‡ศ™7P`๘•ฤ๑๓jญอาt๔ “ฑู ๋T๘$FฐZF^ 9T@h๋ จZ + หัLyA’€)๑•ดสถ’yฅd<อา๎PPƒโแ˜๛Vyฃl]ะบถfฯณŒ‚๓/ว…?ดอ0aVY๔ฅ฿�"^ดื$[h‹ฝ๓ำฎ ฑŽšหั� IŸ๗q€’Cตค™$ฃ็ๅ�แ?ฮR"กJมา�@&[๙�6™aษย#ิ”้ะRฌIปm”B๊^e@Žc๋ธตๅUZ�=`ๅ๗dAบ๛ย1€�„{YN E r๏๔mVำบVๆ ]y ๆฑต2ˆŠŒ�J!a1ฑ� ๏พK)fน็†/ฒ^vยิฃi2ช”.๘2น�099†แ^คศ*๊ฆ†ะ7z%๔ ฃ๐้แพFpnหน*|;๔ฃi๎๊ 3ใQ5`T˜ฉg�ญRŠ“ฆฃศRฬไ๖Z#“�ป5”cฑแKึyšฬI๔O˜^˜ ฿๓‰๏ cทรƒ‰ฑPื\วLส…]ึ฿๖ไฃp ™„ำGX›_d๋ lจ&,M>Ž�.2ปHโ™Pฦ>_ู€ํ๒qXœ˜โzlรฉา„Œy &ฆศึWๆๆy๖ะB๏”ฑ*แ~p?•ศKภกย*e~d๗r‡”ยด๐๙oีŠป]์‘M๗�‹ฉ9ละั2ซ3ใJิ ”XE๏ ๆ่โ$วg/๊ํ†ใsา๛ม7๓ฤฮ*ณ>๙™OQ‹ฟย3ข6 ใ?QนX…บ ๅ๛’fŠG””่‡ะลพ~RNูๅoี™BY�้„ใฎฃBภ–1๘ุ‹๏เsi„NŒกฆมถN�่วž็งร๔ิLTิ่ล�ˆ’…๒”Gว€g/nŸ๕ZวœP QW‡Šซตซ=์๑�˜ž_ยฟa"vำ๙่Ÿ๗[?‚b”5sณQ๚ฟŠัเ๚ยฤ e,ฌ*|�>๓Kฒลf%t,๑9b?ๆข!H8žๅ๛จ0ชชP’ัe(“eศ๑= :KๅๆูGถy6W’๕ojn็ก� LNA@9ฅH9โŸูลiJ�6xฮVขn\ CCB/๗๎‘ ๆ—?ฏไตศ๎ั7฿นF<GD'Bู1JMหฉT๏P๑ว>ค*‚„ D‰ๅ{vฤจญั0บ˜RฏƒรTEษW;ฺ๚�ฏŸ�ษ/|“�!รพ #P?แyพ #P?มฅKผ�{ฟ๑ไๆฦฦ ปป{GH๊ชํR จW2l&Ÿ็`ฬi\คไฐ,C€gภ� ิน`]็e� r@"๔ศ๖[f`iซฌh‚ฦ3ิลฺZeิออžz๚Y€u˜‹d€ศธ5ด†พกa[O่ํ$ศถn|Žฬf|ชp~Hn%๙ถโ2ฺ"�l-�1คย๐0’XฒnoตX™Eฐ๋‚ว๗-หซ6ึV๏P]{๓uฺœฝ‹๛็S†ฮ‡็_๘ืˆa|ๅใ‡จ�ฌ[ทoฤ๖gถ๓zDf5Mถอ๓A†>0x.ับุOข>˜ผ;ํส[๛ ๛ฯGy�ไไdlนง,Vฉฎ™e๚ส9จ๑์๊้#รHภHv^ยDฃฏr|l}็— †c›<็คB ฐUEเ, ัแฝŒ’Š62Gต€ผbฦ�:๑kฏผฦ๏=`๓{q}uฏ�๎!ธ,ษตรx-บ•ฑ“” ›‹๓˜ŠQCฬ=ฺงŽvcVk€t?ฏIz/’าr>kq~ Iะˆ�c ๗v�ป๛Qว๒=#ดJj คJ+jนnฅ฿คwมจqxohม๓›F2—D฿ฬป=?.๊€H็^#ฒึŽW$ถปdŽข๓;sขš^Uf�lหถ4? !ยxดwกXHฃ ™'ฃึF? s‹ห�4šตฒv:E–3†ฯ …๙๗รYธ>ิ๎ฝ !�)Aตขˆ5!ะฬrœ>ณขบ<ด’กŒY:ฃRฤ(‘T๑”s.MMแ๊ณOก$iฟ๕kฟฎ_�F4pd่˜'”ฐ67tUๅษP็็9ฒWฎMns8ๅwŸฉ”Bผxั)�œš)›‰?†เ;ๅผJH‹WTกi๘ck๚ ข]‚ฑฯA ๑ึ^ส$Xpฌ?2ฮ|�!j. ึๅ๚๙Lฒ(ํV%a)’J็ฏ๋ๆโฯ†�ยฬใ‰3pAธ 1Sส๙๎ใ๔ฏฺH’จรอ†ๆ๊p๕๊eึE_ฬ:J&\z๒ษp�แCฬ3๗โฮธใพฅBลvl–>ีb๐ฆฺวฝล/ม—๓ยฌlŽlงๅUฎw๗/IหRฦ(ฮฦัา†(I๗}!Q}ภI่e™Oผ#f�€)aาK7๙@=�๓ฌ >ˆ๋ย2’Žลศ๖YSฮ๑#@› กˆŒด™qIUAš)บ•ฐ/ลL7็๎9jฬ็šPเ๛”ป›)—�JU๋ƒ HคO<™็ฬ๏A0ePUฌอO Qข์์ว€ˆผˆ€PV8o๖๖ะ>4€น`3ื›ˆนˆ๛ œ๔ข~โฟ €c๗M—}ฝ6T=ธ7ขšP/0ๆวˆ€iSS#ใ๙ยธ ?.^น [ฝ สธฦ*ˆหrึ๖๎๚ฦ™3=ส†ˆุ•นJdฌลง\Œ,ํไฝq*)†๐3Kฯ˜$ุศฦซˆฐฝข%i“s˜๖ข(่fพC‚1๗–ษ๓3CsM#�b๚ �ศะBE/ž<[2์็๛ม๚หจz๑น#ศผุ ั#!‚]ๆR‚๛T A่บณ$ย๛U ญโรg ์Z„ย1B[7q:šiปฺ้Gํ1พ>5ห~ฬšแ4ฤ-โœN˜๚%ภฦฑ†5ๅ3\O�๋๊ฆ๚จžRโZ5‹๏<ฎเพ[J"‰%YฝŠยiภฏฯศะ`@4 `ุๅ"ร#}แโนแXฏŸ–le์์ฮ M!ก๗ ฑำ๚–๚0CY�ฟT78็UฺYาฃ๗ฯี žm[=ญYถa\Aี—ๅ๙ย’กD/ ๖uหTทุกมฟmI˜ƒhq^ุUย`ฯ�†”ท”ฯŽ ั˜“ฟ๕Šจf�z }m=๊˜Lฯฬ‡|‡ข‘0„{?๗|ธ า๚ผY˜Y็38yŽม–ฯปHcศ\.t๒(amภr„ัˆ—Ÿ0ฯ2ก"›-‚yJLรผˆeJ์+v)ูฦ y~n …ูฅ‹+‘v?ฉแyห `LOนgƒ$&ฺxL„�๏Ž๑ฬXโฝ(6˜7ฎoŸฉp{ฌฝJ~Pฝ๑Œ`๑ผค�.s‘ •ดAต5oog k5E‡:+•ไg ฒ~ฃถก๖s?�ื�๚็๔G�ซป/ฝT๐3๐๎พ #๐�ณ(แป๑I…ฯ(Œภ_ะ@๚�ล/�๊Rw�ภi�๔›”ภเ?•"K๎๖F-^ึ=xฌ@� ฟฮใ')๕SznYq#}‡{c`ฅธ0�ิ ๊๔nะ็๛ฬพ)=๎่๎Œn๑๛G/ดP๛ JฐUIท�{‚ฬัๆ๚&<ม*•อ‹z:–,˜}7เ๖็‚+ๅฟi€ญํ-สˆฺ8ฉ G—n>g… r5rี)ฤkื�o_ฟ‰Œpzศg๑3“ญร&ตจ†‹z/ฬ/-`ช๘ˆเง ษpฌ‰ฝ๒dธp๕ ฒ๕็โdŠ็gย,ฆˆ‹[m‚่ะE�Zeฮž๋ฑ ฆ˜นิฬuR๒AV๊0งฃxo๏%๓0Ž!mCฆKๆh์Q Zw“d5$พฒw๛วonฬ…]“jฒx@lฒงc˜ภi๊‰zcไz`$๒�S�ร5z๋แ’แฒŽ›ัา!'w{hŒ[ ฒคฃˆม�ข|t๑ยd,จ ฬๆซสู�Bnั }ร|žํู๊4ถˆ+g44TcะFภ‰บA o็ี�ฃcJ,อฯศ|โlืัAY -ภ\ปปฌวdT้Hข1^€‹ฯ๖ส•นจศศ@"๎๒;(ด๖กNƒ่8bฎ๋O‘DอโZ”ฌr�8fึญฏ@$)แjlล๔”9Tมsrib2ฮ!^}7น/ฑ‚`า=ž}฿}กโะ๒};ศŽ;ท๕eั Pยt}L_ หw$ท$เc็žฮYฑ�’ฐกแน๋#}žธnชcห�Ÿ<ฏฉข^ƒ�‹fๆwJฝZพื@๚Kขt†gำฯล๖฿Uส0ฒœ๚๙r๎ส๒ท <_หbู๗Sยbccbบ+ 9ไพีsผŽ1)ฑม3กฟฃ+ฦช๙๖Pj•ณ็ชบS tส๕d/}+๔}‘ณิ"หXDม”>›Ÿํ:UฐจŠ”โะœ*j3Mpฃ™+Ÿทตอ’9AMฉ:เˆ{ฝธฑม2$AC] คผd>ฆอผ�ฯއh€๐เœT�Su๗๖]’๑šL3 ๓!K(*์Ž$๑สpdสŠNฆ{Z๋าร�me- ี๓•ษƒ–ๆบ๑ฎฮถ_ธ|q๔ณ�ใ฿�ฉ๙ฝŸ๘พ;ฟ�หƒ\ฬKœqแซ0…๘n@8๘ndแs�Bภ��ณ?{๘Kฟ๚๋ฟ�•oฌ�ำŸ๛Gw�� มJƒ.ษ2ํf/•Wะภ็๘ž€™‡w” “๙4“ฅ์7AภP VCพ่Nฮฺ่สH…‚†BfXฬจ๔ ˜•ใj<ณHzฌ#ญ}8�ˆใ!l๐๐ฐฎฤ8ะใ ฿7 ๓ฯฬ}๐ 4/%บณฯฬแยKEwgWlกh ตe~&xู�M๓฿&pฯ…—ฟ๔•(;,!@6@ด.SRไ๊ีงภ{Ci5@• ฿:า�ฎ%1บ::# mšฑทตšค†@xaj2ผ�๒‘z3&\ณ/ฤั\#ฅ8๋+รหF,2ฐฒ…Zฉว|๒้๐๔ณฯPOพ  Y4่"๘�ภ[�ช๒ภเ5O๚ซ’%IYˆํอช †อj šํฮ oC=u๛;€ยบ๖ฮ0๛x&�~ํzุ[๔5ั Sƒ)eœ•Hศ๘“JYsn๛*Vฮs�ั#:9,วš{๒ค€"๏)3 ,Y (ศdfฦง”QเŽอ8sฯ๊;oลl๚‘ม๔™™#™7d šHe nำฬJภ๓Ё"์ไ v๕t„พžnช�ม#GซŠkc`!I™�จ(งHt’3šX9เ‹ำใa‘นฅo„ Œu ฿– 6Nฯิ�> ใฝ�ทร2ืUF[ว๓(`*‘BO๓บZˆ”มฮ6ส˜W('4��„ ฐ�Ÿตฤ‚ๆ ย ์ํถ˜TQnษ@t�„ >\KปจXศึท€vำdต๋˜;]]dฺ‘Jkฒ้|๊/ฒE๖kษz ~U�KหkŠ8NืVมบซP ™ขE9ฒnK„\%dผŽi‘YBน…ฤŠYเ‘sƒ�9‡"d!GอฺŠผdฒmองัgŽ๑Ž-9ชoŽ™5ู1 ๖บ #“NไKา1ศq=ๆ˜‡IฒŸ๋92 ฮ } z๐i ณ{�๎M๎3ูTˆAีอ|f9๗๎C/~8|โ{? กำยขPb.บวTS 2ฯyพ�๖5พง๋rmI> r$๕ะหร๛์—„ม๛‹’�'9‰6ื`ฮ`>f,aFบใรริ"S�C๙Hฉp;†‚ื|_9๗]๗�DH–=%Kฦ% PƒคA?ข„] AQ ะอa๙รมุ }ฟๆ€บฝ‹X$$+$ํ ู*เฑ�กศา$ศ•vFฑห…ฏ๑ต’5utS(.ฯNฦ็|/ebNa๖ษผ)ร[มึ„uถธƒ�+Oบ฿œเƒT3มๅน™ฐพผษ้ก`๐œธ๏#ฃฃ‘ไU)ขขปง/ฮAณ๊๘}์nโ;ยZw”๓';แลOษ{๛ภB๔ึะ่ะR–พ�ึ&Š ฒจชy–&'ย&๋๚ย,„Š%0Jt™บ�.%Jiฎท’,?'สœ9ฐ9–P๛ชQŠใง๛ฝ_‚e๏CK+†คฬ�ฯ&’šฎฌm„ๅ…ฒิํ |Ÿฬกrb ฐvศสณ–dFใ1๙{/šค�อ˜�ฑ—W๑‡ฉ็ด๊บ&ศ" 1็ ฿นu€T�;I8OK!ญฺุšษ<๓–H๚ฎัๆqเซIo5คญภTาหฝฬ๓ตTO๒ภg๓$ร8ุพo ’ค%‰ฦฟมZCฏ�€_–ืYFเ~�G‹J@&fง˜‡ดƒ…Œ่๋–ซ€์c\™3vdู€@qmBnๅ๙ฌduE8n$ถ|ะ�e jห็ฎฅฎŸฃ๎U๒ž‡,Etฏืุฑ๏ ๖ใJ๘�“šP|-ฌญ๘WŽp‰ฒ†ฦลายJส•Šุ{๕าQ! งoรล^วžสคฏ^ {€๐>W{ หฺ4K|๔่q˜Ÿ]ฆcฦ:๗—yฤuชโฑ�แ˜ฑpญ๚3ว3&.ุำŒE4qฝน๘�-‰<‚๘sฝf8ฆ๋r—Rน#J+ทท2์wtq�ๅœ“ ๚+ ฦŒ{4Š๙l 8%#[1)}๖๙็ ๗R์Wำว�q�MC kXฉBŽฺdIบฟท�^xแ้�ํ‡�ฺ_�้+ฃฃฟy้๒๙๋๙ศ‡&YY๓k็ฯ�ส�อฟ๓๒OฟฐD2‡7พไญ/|F 0฿ๅ ลR๘*Œ@aพ›#๐๏๛k๎<~๐3wว๎�Cฺช•ืีVฯร˜—šฝAฦjๆล�/eŸ”ฆจ๕1เyƒ�4“ใ๙นXgo-๙Iอ)`L๋x l โ5๏๊้๋w๎�ย…~…เ\—oZk•เ)p๙j ๘v๖;bf฿*b•‰๊ฬ/Q ท–vŒ‘ืf55d^”ิ65 ฯ…˜Ÿล�ƒ)๊Tง'ๆษ๒ฮฌฬv.คิึR' IขฤุฌขฦEJ๑‡GBg_+ูฃ่ฦํunRiG5ๅJa—จ56[s๗�!K–bo•๏ ฮ๓[ฤร�gเฑชพ9‚๙C‚ฝtา‚ฯดU•FX‰Rผืญีต๔”yฮอเยMึy{ํ ‚6๋mm�fI) ?C`าNฝ่ฯ<ๅข๗nszdYhU‚๐mำ$$Nšzำป฿x3ฌOsnไZ2Œบ’'yศ=๋kหศPa––กk@7 ฐ+#@OA๚t‘ ฏijCฮ�ฦฯฬ™ฤู@$ุi{c๊๑ZHš~’=ŽŸ_C@^jc‘์Œfd6™+็พTNo fวO3ธ9œ�K๔Eฬ•ฦVZŸ!+�^!ƒQb ~E%Y0~ฆ7ƒe }ร-ณหอ ฦN)ฉ ตƒฬแอ7_…xส†ZH™ัพ'�พs๙๕ระ�7๚/^BŽหฝ_Zf h๏XA–‘y๓/…๚\ณสงd๓ษจฃ๘ุYš ๙}ส: –r›-dฤw ‰r๏”y—ชM„:ๆษโ�"๕�ใ€บภd•� M?ภ]ช#$ฮF/\ A"็gJี<ฬwอ5๒l`žo๎BRธ ˜ฝ�บถkXศ๒3ภ'j˜#๎Y@๘ู"|๕฿|5�~o‚ "ไฦjDรฬอT˜›œ k๘Kค9g]ใKศŠf๐a�ืr๑9ซฝE๖ห๏ฬ˜'!irŒ}เOะv VHVir‘“(ึP/\L†SŽฉษ:?ฦX๏s๏นะ?ะp"‹0/ขE™Vข1 >๒๚x�’Iผ@Tฌa:4๐—ฐซŠ]]J˜งGŽ7 ฯ1Uv,ฐค ’�'ฃ๒€=I1พ?๓{ @š) Y>๒ัยน๓็รอ›a,‚๏S@ี๙๐ึ›oP๏u €ั|ฎˆฯา”QขT๓'วpย�ฉ†\(E#uธ—ถ์Œ�‰�L‰ปŠ/3ีฑ› {ฌ-tkฏ* ถ™šฮฆžฑ7on 7_œ -�ƒ๖�ฅt%๋ SC?=ชฟX“ ํ]*”% `า_b›ฑีกžา“T;ถ>,-C ภ|�๑aU*่าีKanvลjžnQ�ฏั+แ„้ฯ#k๔-มcมsฝiฮ`ส~ฯ๐ใOCWศ‘ ฎkไ๒hุ„Œธ{็N๘T�'#๙็>แ|ะ,ุ5ิvˆ@IDAT "’‚œ๗ €XsLM %c๚s=ฌ›RๆA๗”R-žg”�ฟ๓0ผ๖ s9ฮ!T& _{�uˆ้Kแ…<ป”'ตB�xŒ5ฎป \’Dฒ@EAค‹๓/ร<^‚ด๖ู_‹รฒถ5”RLฌ๐ม็Ÿ%_�๚+œWe�GNูVyn%™0s6ขj�„˜�ฬ‘�“”ศq^ *วะgeใฅ nb+‰naข5ฯ๚๕y y.‰๊โฏซC‘qsโFภž™GiPล\:อใ'ย'ไ๐ž`gd�SžฤiŒข9คฟิว`7*\Xใ(บL”q?,มณ๋ฤ)Uq–?Uซฎโ>๑xœ=ไ$\†d�bู.ตษฑ*9€P๏ ฃฃ—“Tx๙7�yึšฅ]ฬเำpแโเ�WฎŽ�ไ๓w��W^jJ�pB=W�๛ฮ฿฿๙๋?๛�~[๘ฎ0…๘ฎ@Aq๐]าย�E]{๎พ๐จ(๒ญึึึqฬ�ฮ้OS? Tสใ2gพภ™฿์˜มฐF‰“๑TŽูAk์ฯฺ7&๐) 0แtt+5๕=ใบๆ‚>ฒAรCƒ<˜ฏลชใ3สQŒ…woผM˜T ๘p—HBDP›กฒDAม.™�-pn‚F ๖ฑ�€ไแƒqj‚วย:Yด‰‰)�ณ ศคฅๆRf1” š_”*ข"‚ภ�Lฒมาฺย\ว๖ขพqํZZ�]�ั๊ซ_�b๔h�์,QI@oฐRภŸ™‘‚rAzM}฿“้!ภ้ฆฎป…,๋.„’SๅŸD8wqฆท5�ฦ๊ญ•�b4~”8ฉย|สืถ๗Z๓‹œZำ=ฦยZjวม ๏0k๛สCˆšฮม!€O&ฬ�โ่8Sาส้qQ+T†^€g 5ญzXซiฏํตูน˜i5ƒ~๓ํw L( ฌค เ้�ญ๑[;ต�{dmษvE@ีฬ^า|ี%kk๓Fa!ุJXํŠ!(๏วŒํี0*ใผฆL”ิใ6aH&6Kอ๖ฮี9ฦC‰Z‚ะ๓รผŽ2ˆudุ�3! ,I(˜kBถFถs{ki}5วฅิ•(ซ=I2Ž�“3`@ษ๘N=ค�uโิŠ>J8‰2ๆty’@=ฝ พ๘9ืฮ็HT์ึี`ๆว+cT‘‘๎่ไบ‹q?oไ^คY‘nญฃ๕ยTD˜ๅห์Bาอ}ฉ#kี ข ฅ‰Œ๊ญwฎลut ‰ฑCูร*sต jFูค’z;fhดY‚‹บา๎rฒ‰š‚mPS.pศ#ง.#sฯ b6ธ”เ_รย-HญุฒŒ๓6`ฮ1o*ษ– ๑8`žq๏”๋[oม8คPcUส๙Kœpญๅ๊น๎]g‘ฬ€@R$˜ฎD)เ๕f!>MFC็Fรตoƒ{mป2Iภ˜j.Fฤ๚฿[7o‡;๏�‰๊„]^ทH ๒sี ๔‚M % T•่ฟ!ูขT;vdL�s^€ ‰=Ab;Oโu G1Eิ?๛�s๘ซ<๚๚zQข|๘T9O๗“dๅ7๘K0วDฉณN&๙„นกA` ะ็�ฺC�๏y”ณŸY6S้นฮห ^![”ŠsRŒ+*ภfฤุค‹๊ A ็.‰sฬฯ์-/˜า[ภฬจ{b)ใฉ‹ฎ๐ถ’ณเ๒ๅ+ึ' wรใ๛ท๑ฏุ ื‡ ๊ยqลŒjˆญ9�ƒ!l3@’าปท์`่วZ�ง#D๗ถต“ถซHxjน๗Iฬ"c–›๙-9kึ›IP#ƒม��&^$�ง,็iYSฯP/*บฐวฺต˜Mคญณ —1 ำtเeq€ืLrห๛ทปนสโz˜“ี”มeศฺ๒^IGฏ�ฒช}ˆ >%๗™?U๘iฤL?D„ํi�K�3œ[zAhถkW–}ศ฿}HQ?oใ:k๛w˜ซ๎ใ] 'ฬีrufŠ9„ตF†๙พ:7%ไ๖\IžrL|I:ณฬŒ > \7฿qQlP๖ภํŒ >มฝ5�-y=M)š.ช ํ�ฒ๑ง,]oื“|TH0๚ฝคคป๋CS�9ฦ>d{9sy’h‹}Vใ]ื „็เผŽึrฯฮjž–ฝX&ฃz ฎฎMวํ‰K—!>ซยคธใ์พณร\�†ฤi‡<เ�šC๒hŒศ๙์P้M ™ื๏“r’]v|iDๅyS>h9ฤ$‰�œ7;�‹ฉ๙ฟ๕yฐˆ฿ๆŸฌY�ภ~YŽ’็ˆฑม๕Wb‹^I?;ลพ˜อจjกคWยuๅ ๎ฉ๛ฌ%2œ›% �–…’5œ*ืG้"sBีœ%U–‘ไH จชPiๆ็ปnMhXbนคŒ?,๒%โซฝ๗$ Tgลฎ*จต|&IB�˜‰A@t}'6ำ&ฐj#๘liG*Op18ุk. ‚ึ6‘ใ๓ �4อฯฬล K $8ดj4…‹#๎�›˜ๅ�[4L‚@“แ�ฤh<๔sd.cถJi�-ปlม”B=‘ู8LKฤ^ฺ:ปวL.ภLWs"0E‚ภษวน้ง๗ษยmดGษ๚›๏Dท๚*ฎiƒŒLฑต”ุถ�๒\4มซ€PHb2่˜(–!!ฎoHQ6๐ f4หฉื7๐;\$‚วิeZ—ฏิั์เ!ANู/[d:�]สข�|_๘�ฯ|TQฌำ้`kำิซซ8๛ปŸ2n €ัnๅลฉE‚ศP ะจm่0ึญ””ิwี‡nั;Q็• h^Opี4yค๐^๗ูท"ฮ๓pฅค5�บ๓7]พxฏ‡.Z*NaภF‰ฺ6ฎƒ1ฮZFPฦฑ |U`œ2Fส^5ฝ, Ÿ๒9ถ_ใ@dัŒ7/R�C€QŽ๑hฌฃ•Ÿ›'CZK›*อธฬุ๏“ม\ๆ˜๗ฎ;‹๖“X์*N™+ut<ศ!=]^คฟ๛F@Oเh�ญฏ๕ฟuจ@6ศถmmุ๓pฬน‰’ณช0ะี8ึ6,:@ูYฎฌฃฦžวd์uปท๚D…@ชชบ>ฤ๕ใสท•.›ฅหrm**๋๘žภv๛ผKF5บ`‹ฺ๐[๏ฝเ9ๆ�ถ\ฃฦภฌฬ�นT gง1^"5€๗:#AW†yJJ>C^,c &Pฐ#ร?Ksฝkิzd[P๏๒:e้ษJ€ „CฬŒข๐ไ™ฟEฬ๏TG�ฌš6qm�}1€6ใk๛Oศฤvญ๕7€ฯ๐ู€&อเช jM^ทื๑�๓ ว๎่ย๋“ห *ษ,[œ!K:5k�ฝ�w้r1็Š?๚+ สYืฮ›2�V] ?�ฎQ#iข9[0เ<หฑ†m Xย๕ุแฤ/ฅdy@ป#~Ž`ชฏท—ตAู[P9ๆ์์ิ-5Q*ยต๒™อ ญ! !XฤนJฤ(ๅ>:€HByข1)Gฤ1�'\ืณRz๕ญ ฯAl•C๔ีำฒ/ษ฿š0ึ”,7:โ๕ฟ<„X’k2s\ pQ‘$๓$ั�B่๊๎\ฏ‡o}ํๅะ38UVซ 1DœU,ฺ4@so‡�‹,ฟ&กff]๗*ผŽYซŒ�r์ฒ*)ล<*ฌ†ธทะ%ก‚2ฅˆปD“2�#Gร็ฏฐnึยj'ไ)สค}ึ_vŸฝBoey:z่ัยฺ4›ป85EI๛๓< ™จ"Con^xp๏}VXาฦ&+fจb2ุฑฑอไ๓้8มีG_†ฤ!ฯ–<~d‚�ฯ๖๘ฐํxžฌฌP \ม<ษณŽ$5ฅ–YYๆน็“…<ส2gŠธ'5u- ฬฉุ&ฒ‘นJฮOุs’ฬฅดพ*ต โ’Uลdํ๕PQa"!รพ' รฝ�•”ภwess/r yž1Ž]ฯฐM>ป„๙Yๅ} D นไsลฎ.’ชb6Ÿฯั็ERWๆyRo๚ฮ^+‹ฬYฒ฿�l์แฃpcbœrณฎ[c`^ฯr?uฟ๔oพWตb6�ฟ+ 0Tฆ๐$โๆ†-Qก01)aยz€ธ�]฿ +ศ��PiuvกŠb?’ุ—ˆถฌBOŽ2ๆžv €ถนŸ{,‚f๙%,์bำื�CYW�ƒ|ฏ@Z–ฒ�๋เ*)ุ๔4‘‰็ศ9ืFSBU4d�9ž—Q…*Cc`๗ฃศฺ@ฬž |ชbSxJSฮVN›B‰6Iv=:4มด‹ฯiKพ�„2� $s~ถ>ิcA์”๙!%aj‰'t๖R�[ฯEฦถช|ส;ศ]ๆ€j �1|Hฌ•Pjละp�๙ธวฅ�oxฟeo๋ณิฬญC&BKgใ?๘๑�O�๕KŸ�?k��๖kฯ}๔� ™aภุพ #๐ง=โเO๛Ž�็z~๎e๏—�ูoฬ}�๓�$�[ฟ๓้ืฟ�๒ะๆ๚ฺSิ๒&คึ’จไj&–G‹>d%”พ/ฑิDNฉc์™L iึ`hx8<๕์3da้ ฌu‘ึ1ฺ๚u_ปCXOฆณœฬ๕’วจ^`ด]ถ'ำ0สlqS \ฬฉ.0@‰.๊ ��Œมช`าภฤั˜-Dโสง๑^2ต/ณฏ๋ˆc+D ?[.Z+ฐา(ฑ•:ฺz8%าf†หBO>๕\๔B0๘�ยฤq‹l‰�œku€PQnkถิ ‡ธูๆ2�z_{ํๅ˜ ึุฌ†lžูส]2ตฆ%Y^ป6=บ;มgŒA<ิ6�6ฅmฯจ้$ๅ%3๏^ึtBฎุ๒ฏ2ann†`9 �ผ7 €ฌ่*�๔๗…็?๔a˜$่๏ส๗i•Up3๓>ฅ*1T#pืไ1 ุ7@�#(ตองบนfœfฦT$VsH^5 ิXm{e…{ลฑฒ#—žd�P›LOE๙p%ื�H›In8J #ฃั*Z$ูธ#ฬ=& [รฝ`žœr[lฌ .4L\฿\ใ=?ƒGหj๊YOญ‘ๅsjษ<%ฬฺฦN1–Bๅหh5ุž๚ภ•05~›๏ณtpx"ก;”�TVั'๒`C jฆbXยk!หนUฺชPc(>โ๖ต๗~๎‘1�ฅไC�ฅหฯr>ิ'1K—aœrำํสด+˜๚$ฬ�ฃIQo�=2Jปฝ๊0=ปศฝ?หพ้เ-`ภ2ฮฒ—ฤ็้|Ÿใบช่บมK ภไนท'KคX$9ภูัฤฆiภ�1ฤE ภ „yํซภhฎ„ ,๘'šZ�mํs†lค�&O>๗Aฆx)๖ปผถฒgฐ˜Œuษพ ๅ@ อKอศฯฮL†ป๏ผณ–‚ค=@ษ:eyภžชA$ธH ณ)If/`!'8Ÿ(ษ]%˜+Iึ3(„ฟฉ‰‡QะฑธŒ๚sฒรฎร���ะม๘ซ*š\™žG๖�๐�}�G�>ฤB’๎ใ2?ื๙ฬql�v(ีX2*๒๙ถœ=Dํ!มSCf�vจJเจjZ�t5ˆsœ�LU•๗โ”๓tœNโฟqšบขแZ”okูุ�ภo€ำŽซฬU็‡FPผg�, �ๆุdssศ๖OQ$˜฿๚p*w๐สh`f��Œ_๋u‰Œ{FŸ๚Vๆ€N๒@ถ0ฟ‚)ํ.`ž์7็aŸ๙2ฎษV˜'y 8!œ[,b๖๓๓Qrพ>?ฬ9;BhV˜dํ–๓' ด<'M›฿ชšฒสดJe\(ืสc”YTJ ?sc‡ึv'ฌอำ ฬFฝ–hp %Aญแ๊*ฅEvN8dOZ็฿Yสlืšg�๘Gฅ“]Lู•น31ขJญ\C<•Y($d:z๛˜ืธ�qฦ๙œeŸฎแgอŒyS}ฅyึ™KBฯ›rศB›[((xฝ„Š�;vWi๋nฃผญฒ…ฝ{œaL0rจลฬš๋m`ห]ณโŽ�†Tด1(ฏ€คไ๗Iฦs#ภ}”p'ฦ<’h[ุรqX๓E์“Œ#ŸฤV{ว็>๒’จ๐นฯ5ซฬQ=0=3n฿ฝฮ ฤr„•ฅีฐอ#�คTf|r2ดัฦ�TUNฦ="cž{๘p�a�นฯZ๏ฑค\ผ|ฎฯ\็ฉ{€eถ(A8dŽู%ฆžgx'ๅ€uฬ๙จเTUOHJ๖'ิ- ˆภ›๓W1ภncI€{šไ–๗อมัร isfrŒง๛ดชอQฑL‰1QuT y๎ฺ9‘L‘ุแ฿ฎ๏ื&1็๛|�KPฐ๚v]๑<์ภcทi๊gJ่Kฮ๒”\{|–„ก๔ €ภไ๗7Wy8์่้บ๖ไsO�ิฯ�ฺฏ�ิ‡>�#๏}๎sฟ๚ซ/yi…ฏยFเฯศˆƒ?#7ขp�GเณŸ�l�้็ฏ�Zš™\�Kฏv๓0ฅ\Qฒ„šek}\๘G@Tลร[iฝเEฦ^@`‰B- ฬ�฿ึ๐f OyxทR/ุNF.M6วฌๆ๛๘ฃวdฮ๖ฃ๒ภตๅ ถŽ๒Ao€`ฆDเb‰„�์U๎{ ถ%|๐{<ณส�='ณ;งธ'๋โ �ฬ � ฤxQฌ1๖�%$jB#๊u�+ศๆ็ถu+'x�ิฌj็ ิ6ษ€ู ยVb\วJ$ญษนpŽ๓$ำG๚s`h(Œ\%@m /]แิerสขŸ~แล03๑(�๏ฒ^ฺ H๏.4{๓<D”Œ�_{i~ฺัWŸyฐVKปช9HH2!’r;L-เSq€„ณ„เผถฝ†�ฦะูำ(กO7ใWษฝษ9ึ”F่�� Iขl~jโ>๒�ศ‹Œ,/Dาb—ฌZญeิQ/ฯ>Š ti~*�นy2•0๕๐!ม.า�� Y!ฆ ใŸณHz%, แๆ1ึ3d+“�]็OA€ตฒ�2ฮ�ึ)‚ฦR€I€P]PY“ —žx&t๕๖‡๑ปทPฌฤ9ะุย˜ฌ @5แ�A-qHp*YYX,œ;ฬ f�qQ็\์nๅฤึฉKf˜•Rvฎ๚เโFโ@€zศ`f๖Oจ•ฆฝ!�ฝรดSผถ–ง้ัK" 4 พ ��ปbfŠ,* \rฅตซ;‚3๔ชc.=๕4๗ )9sด\โ @44|1*X๖ Tœๆส นRฎ!ๆh2ฮc@‘J๊wO pาวvญ8ข–U „$ˆj็c˜Aฏs�yญฯศ)วฌฅศๆiฒ—‡ภณฆ฿9-i`†ฎˆใฉ*ฐ�œ&Ža’3ฎGืW�โ๏จ๖T๒3nฬ|@cอฑ�;{hื๗d๘๊| ฐ 9ร=:kฅˆณ:F“;€ษMศษŽ4ส…้ ฮ%Kvx•ฌ๋zฌ?B| (:โ 7'ฐf�q� ษ่!อ<ฝฆS@\ ็[ D*ธฏ5\G9kข˜5ค�?’3“ำแ�w๐ฟo~๓U๓:kพœ2ซ^ฒ็^๊•ูK EŒํZ#V@˜”p�ƒ6šฐ๎๑>Paฬ`jFhหฦผ{DE็47;Š>iส0low“ษ@ธ2ow ซึส!N๐)Ž 1‘fืณNŸฅ.ฝยตฏ‰9๓8ณตŠ๘‰kŒŸสฎK$—�%�+7๑Aฐ5ฆs'๎ฏฝ‘TLoฎC*ฐQri`™e-J<ต๕„กKถpญg๏•ฤฆ�‚ตข็M/†jบJˆ�}ž[๚2H์Bฯฒถi ฺ\Cg‹์wลafz*ึม'xึุeลฎ๎๚xฤ|e1ฬ็NŠ๕eiT‚s‡W‡„„PูD]ฑƒาƒฑนzๅJุ„๚ึ�7)1hกพฟž+Iบฦฮ’๔๑yวyฺ=ภsจC้vฤ5ZŠ0ยผ/ŠฯH๎ v˜˜a>ช|‘xjnข%ฏ๏ใYงbKo๗มj”II0ˆฮŽu `๐3๎Ž๑๋ป380ศ๓ค9L?žS< U+ค!O$,๕๒ั�‚กไฯZœ{žฎ)ฅ�ีี”Z€ย�/| 3�‡ืBR๐^“ *Gา์m‘Pƒ๑ู๐พโยคCี‘”agYฃšฑพŸlPต$ 9"กkีฅ๋฿ฒD๏๏K๑lŽไ8๓,ƒ๑Œ>,๋”5ืx�$ฝ๕�p G๘„์/oโำŸ�๛�เง�ั�\ึ๐co๔๗ืโส๙#S๘*Œ@a�ฌ@8๘ณvG ็๓็v”ฺ�๔O!๛ตื�ี�|๘ล?˜zt๗โ๎ฦ๊๙6ฎ๙ ”“]3#.ุ–$๐กn๖฿n�" ˆ@’a �˜ H ๓มNคธบๆ+ŸJฒ;kซ๋d_ขโฑ“@ษšEA์BP`0OfU€ๆˆซžŒฎ †ฬ4H\(IUŽXM$ญรธ™Pƒ�}Yฯhเม›c†ษฌ แ7YU‚Š Mฮ€ึqŽ~x�~๔^Pส]C๖W‡vKfgบฦ#s4 ีกฝ Paท �์)}Bๆณ…ึ]Fฯs>f„‹่-aๆ๑X%ƒ>r�ต�7ยญทฏ‡wฏฟEฬX%hไb–ฑยฅg`0’.{$E|พูMม™™8kCญำ="ภ�%๐ษ ูvุ๊qฌw`dv�๊@ฝาzPฒ–ฦ๏(T ‹3j–}Šฑw�กํ9่ƒ๑ZไW๑ Hc 6๛˜.๓“x H–ชฬ2E�2-‘หข%Keบd‰"ห ‰ฐ ;i'๗LO็œฯ้“๚ดฟง‰ฟAุ�ำ@๏ฬt8็}Ÿ๔�ืu_๗usdS!ฅ๔งhc]˜ํb้ภชุ#yฦJcศ,Dะุ่๋>���ŸฐญPLฐ^5`;Dzญไ�฿ซณฆณŒ7ร�"w—8`~ ่๓จ4UP˜]ฌฃ4pOฦ6y–Z˜ ฎส์ฉYผ๎>T*€ฺ*๊‰ /อ วL-ฏ nไzฉฃ&“hŸŒ๘็๎ึZ$ฌV2,่ัลืเฦโ$m]ว�u๚ร'�๘‰0ฟH ภฃ๛d๕ฮ)ั(q}ฒๅm4พ?9ชใฤฯืจ“��\'Pว�@”Hะžƒศ�H™ๆEoฑv–†”‚ฯ�0� ึ๛ฝวHฮOK’‚ฦ“ีฺู‡ ส_N8o6ุำท๐ƒ๐>{ny~!’‚k‹๓}ูะรœŽB๒์m>ภsถqถ้ดˆN๗ฒI’พ�ฤิ๗ัŠAเ2๏a้๙ฤžํยฟ"๑ดˆูคทข*šAโm;9�} ˆฑฃ…๎:คi>&๚์mCAfชbเ:d๘'ฆฦ ๘ุ๏œฏ[฿�%8�Cl’Anใฬ˜œdพPd‘Y†}›พ8ฦ(!ฒœhsc‰ฑ์ +ฯQฐ จTF๐Z)qEฒฦ�ƒ์ฒั�#ˆฑ๓gทฯj}`$ไZาt7เ ่ฯำ‚ึฎ-`5,ิภ๒`‹. ˜]vไz๑X krยœDำย4kู5๏พI1&vอษp=ฝจุ๎�ๆฬmgM FRH฿!- ‘”ฐล{โช”�lพ-Gm/ฏq๏tก^Rีtˆ๚KฅYMRA�:kตภ๋ซJ’ด.๚โพโฑยYปฆ.AๅQ&p>LŸC!ย~URƒŒ8VeWใ„‚tIs]๛”D2ƒ[ชก@ฉทQำฯ3<ฤ˜ำ‰G€๛ไั#ฦEg};ฯ“NศษEืฉฯศX*ศMp}ฎ๙์i็�ใGขbBฦs} ใ_ึ�ูัแ02�iโ้ำงด*< YสฌY__ฆ็๙>ญฦธW3}�๕Nแฑž>š ]gฮ‘#{OVฆภฑ„3สn H๕CH0ถร:c!Ad&ฐ YtAปc้Z#ฎแ\šyQ_bซซ mP\@ๆฬ5ิb–l{ /}๊'—Zฌ-ฤน5“ฟ\ธ@6ั~ํ›+๓€้ถ0q�`U ฅ3-€ช4™พNˆ=ฌ� ณ‚;.7fa๓€วvึฺไG CiGp‚฿dškf=ลน|“์` ์„๕ะ้dเ`… บŒฑ�:&�๘1Tห”�เ๕`‹=�ํzBฑF›ภฦ๑ฒ~ืฌื�{ทน&pงcฬ:�$ๆ‚A๘”๏$4*ฌเ๖�ี[“ฃ#1 ถฤFPQ„piƒ@r\4ํณ~YเฏŒบณยi|(ึx�๑เ˜{g #จฐฯ�ฑ๒`ๆ! ดLฦ๒ ี=v>qŸฎฐอDs5๑5$40อฤ,ฆฉC�rง?\ฟ๑*ไึX๘“ฏ�1%”มp JDHิTQghrงsฝ1พue�๋ช#\๗’yึ๛ พyภFP! Jขส ู‰ร(fžQ7˜๑ฮ๐‚ึT„C›�ธญ[RPƒŒ๑bมqผ•ฯomะaƒ}ใžžšœŽ€ป Qฆม)0!รฎUlภšaŸKZ๎ขZeํk๊/ะฦšซ1‘�ด–f๏r†XŽqˆษšํ ๗๋šyf๑าศp6๊ƒกิป5ฯฦ‚ญ€้ฤ]9Oย ชjฦkฺ่ีKฑ$ฯ็ฅxv๘ˆ?๘ํ}ฦVTีชษ$ๅ%e$bU)h~ธŒฏสzึ_รฝIYbŸฏzณ˜Hุ๋�ณ�œi๚>pD๑Œ#มภนklP†D๔์†bG฿ำcERลgดฯl‰ผฎมkัฯHณัส}/i_^2žy๑/ะผžž{>gโYโ Bn˜xะ็&รX™Œะ๋A5‹J„ุ*ขBข@ีเฉฑ3็ฅa9ศkJว^บrๅม/�๙ฟ๐ผ~ผy็ื��๏์7ฝ ๘ๆGs~„G I�ON๓า>บ#๐ๆ›ฟี๘—_๛ำG_�…oพฟใ;ธ~oVJ๛‰ฮlj|๔L/ 7 ฬtควฝšLZ;FRE‚�zฝ๛ฝ*ูพ* ค@ฆึžF‰9� f๑zQŒNPJาตปนIงdล'จาž€]9ท™ฎuส.2(๒…”+,–˜๖Pฐปพพ๛ญo’กล m@SQVเ�#SY† ฐG€ู5€ฬเO9yตข"ƒl7๊ม„-ฮภ_!ร฿�PXรNJ8f"[�‹7้<$ O๓Eี-��Hžษ๎/<ฃ!๚F' จ๒tฅX_|)Œอ\๗๏ผฆศ๖Cเฌ..„VH(ใ๋Vภค`ใ€:๋ ช�% ผฤฑq-๘fิ๙-ฮ/’mถ“WL๖Bšเžฌ๊มกํพ;ฬ%๛๛ปร+?๖น0s้zx๒๐ึฉฉฏ›๊ขอfšถ–ฬYhป $X{๚zX“ํ๚๖{!\ณ‡x7๔ฮฐฌรต ˆภŠƒ_%ˆ…�0๋ ‘ํ/Pลqฬ8าใž๛ณ|$B7เ>ƒirเƒษ25ืคีุ—mฐ^™<พƒd‹• ำ�lญ†ยน ๊˜6ภa์ะR<@Ÿฤฺยm‚ƒฃใ8<$vvญี/แ^ฏ์ผXจ@๖mํ”"”Juะr๎*ฒ�ฑp‹ฬ�*e3์›V|"Zำ2N�’Fช{$ชdwป )ZนฮD‚ฏ36ฺeไฬ>r�ูNณฯdšI&…l/YA}<X�5ภO;_ใ๒C'ๆ˜:‹ŒๅศภBH%!น^ๅใE:%ธื�ฏ้v\ี8 ,wธqใ% W?๋์‘#9›H๛)uHr=9ึlwg*z~1ทซ๑z(บใcมxeษLฟtใeึ�/,pหv�ฬkŠา“Zัฬ*>dปa#„d€! ฬ|ถN้Œะ?=FwЁ๐™ืoHต๙ะ^ม`Zeฏ.o ะเ}wธŸๆS•ฮ๛ี์๎ ๋š2H#ค๘�็ฝ{!า0๓ไฝฉด8-ฉDR, ๊ไผNฐ9ฬŠ๋ป"ชAฺœฐ'ำœู้\+`:^๛ฬ'รี^„,จ„�จcŽจ�ฏ“ๅoเฑเผx็ …29Jึ่ธ๑W+ใ’฿ีŽ!.†z๎!�C ธถ๒(๎…4ฤยึgRi'*žฒŒ›�kyฮlฮโ–=ศฒใ๘PŠฅdผ…?k€๓*?งว๓Q%O‰1ิTTฯฟฏฏ`฿ชdรฬ…ซัXถ…ฝ$QVแนฒIฦฑi:g 4‚ฬ‹ฯ๖i‚ฝงJฬ๊ร.T)E2s/a�Aด††พ;จe\๛”.=|๘ตฦ:%/œใ\‚ฝฃqชฤๅ1ฯ$"*โ,ะ(pRำLพ๋E๗cยจ ๛pŸไ๙ุ รฟถดžฮฮก–มว†gะ๐๘ธฏฮ=๚\รsล„็ˆช็Qิ„œjg]ด2F›ฌฟIH i�๙ช8(ัbPsD�Dๆ–ๆ(ใ:Œ๊ Ÿท’์ชŠ๎=‰…}žmyสi�ณ–อI|nขjุูฌ†=žSf์5XิKF ฿ฤห&d—$‡ �}"ฉ�FœPฃ›$ภ.๏ฑหน฿ษsxŒฮz"ไ!VQ ’8เฆ8 ^<7C;ี3๐^tKy้ธ�๋œฎ{ฏลต’ใg$FL>ุ:ึN*ฑBˆjห8˜-ๅ –N๐ดOฃx๐๕�พ„bณเึl"ผ๘ยฬ�_�~๕?ล$๒;{‡ตพมษฝ&qเ@5?š#๐ฃ;ฦอๆ4Gเ฿ยภฺ�๘x}๘•““ฟ๕�{๏wพ๛อฏ�ฏtA๘™N๐yo:—2xL8ฟ0๓cกcตo�้ทยป๏|—เaG6˜์�.-ยJcใc€ใSู้K/�฿๘ฦืษจ“ฅX่Dmะ ศŒฬ\ฃ$= ์omึภ@ษ Dษช-c™ฟK€k=อVดG“8‚A36ฑฤฤ%'€GdˆK๔ฉดไHF€‰โŸ�๑ึœk่–6‹L0”ฆ.ท…L็t?Y่V@‹ูภ‰ c€fฆxcy o€…ะsa*๔’L]y!�›{vซผ'’X.!ีb–ืฦฐฬlT ‚ภ`ุภำ,ป=คง)ฯธ‹ิ๚& ‰บw๏“ฒส„๖B็r๙]‚ๆ ™:{6zA�(-’-ซaี){ I€๓็>uๆึภ แ‰‰C&ีบaAMŽถsf›“ศๆU@ุ_^‰mฆ`�Y.ํถถyo; 9„T!ซo_sณyึาืธFปoคxm[–สศฦ‰ิฬiŽห8˜หEb‡๎+อื; เ/_ฟK™ใ3O>ธƒฌ�22จ๘ObภงEูฟ1ป-h�ีำ3ึ—"Iafฮ บ\ใ}Yฦ:žป~\c'f่ ฐ•f์T08–T(E>`ฺAM๑์�รจุP@�@a"<ฝ๗7y93MKฒท ์ษ&sŸiห()p๑8~ศฺ9Ž\ž ž>�€๚๑๓็c`šBฆญDขe+นvP›1ƒM๐หฦพๆ]ดสtU๘5ีม=Hต}}ฐ๋ฏ/๑พํ฿kลฐม�Yฃ� มยqฒิฌอภฆz ,‰5Vฆ�ปJ�ฝdBาO#> 43r*emฆ?๑-๑ถ๘ฯำษc’uงrไฬ>€�2‹h�ฟส”›๏พ}1์‹žƒ๘ศR7]"Sห˜;ษˆฎอบใ.7k“U$”RKสน7ฌษพหh4ส4K�ยžn@Ž1yqพ์๊ขQ[รส6๖z+๗ิ`Nฒ๚{เ’฿สบฬv9ญฎฑจมHB:Vส�ฑ|ก๙L“•ึผTUS9�๖ๆ ๗.™B๙u๗ ิA��ฬd‚๏˜lฝฆ้[zฺ™ƒrฦ-ลšึ฿epof๖“BฯE?”ฎ��ย%)๎1ษ๙gซQM่vv4=dน7ณ๑GR~๗O�8ไNธVฮด”‰๓ร^๕aจ>ม(pŸ5Evด~}ฦ์f�€ XYX€ะบฬ5R๖„Rวqษ&;cƒ”``8‰|฿ุd฿3ฮำํ0�yŠ’…9<08m๐:ช]*์+ Oป(M*`Vช)^‹ฎฮ™U…08ช“yF‘a,้  ‚dh๚ใŠ’€์8n๓(sฦkสUhRˆ" e๊ญd+ํ�๐r(A‚ฌ={ฦ._ƒŒาwหLjdคXบเ�v=บo•™{๖�N/ษ�IvA‚,>|ศxใQpฌสฬ8฿๋„ํ๋ํ ฿}+์ฑW:ป&)/ยฬ–�ีI}พๅrหฯŸัพvŒืภ‘น‹:์%�Xะ‡„๗๏ฬRฮม>ฌ#ณ‡๘,CRž0๖˜ฒ0ยdช�0:๛ซŒช”iํษ�ฮาชTๅNฅ|YB ็Jd๊+J.GœUฮy3้ฉไuฒ๋J‘ท•๘ฎmE#9อวจ —_ฆ $ฤ>Ž๒็ฏ\ง}แUฒ–ญ8ค“ั4๓ฬkๅ๊ฒอš*-W[็3–yI~t๗๔1V๋แๆ{๏‘Y_Š-อ~ู�ฯ~แ๖hqF‰eYห@ฉฅ ญ�{‘r‹ไ ็yvฒŽ<&Kึmq๎Yฬโ เ[knตฏ”บ^วU3P�Ž2าVJJบ �ิภ๗1ง�ิ�?…}!ะ'ภˆธš`‘yข,Cูฉ-๛N0จ๓Z•ดV4ฐc{‘๔[ใญIฅ9Rdฮ2nย๕4`ใ๓?๛็1ปn}�Oรู่๓ธM„๏}ใka฿…AžŽุkdณ‹O๑็xa๎ม}ฦ`DfํตPไ�—ืศZr๏�\Š๗ต๔ฤ2–d„๒X3‡ชWบ‘ลW@;1�จ�ทB0ทหผญฯ/Jศ€‘๏ศใ~฿7LL†Žuๆฝ z™หS‰/ม4๗+Tzny†ตฬ�ผ�:Fde^ง ๘ูแu‹;ฺBิuฟรฐ’ ๆ~ถ;�–8 PZ“X. Sฦฌฎ,๐g ๋ ฏkืC‰r!I ถU”‹๏ฒVถ1�฿e�zNpศไKdฃ๋$๖๔1oฃƒ1ฟ”ต@J>2ว๘Qโั ฉปษ™ฅA็ศ๔(๗Ouทต‰%{ๆ‘๙f�๘,a*ื๙pfdš‡aแแƒะย8n,ฮ“$gฝ3ๆสพ๗˜c3�vzษ˜=งl�?ย8๙A†Bฬ๎ฏEย�ทฝบ@7™™0ศ:ำ ags rt‚ =๗ว๕ดใ{’dฟj*Q ถ��g’ูgฝ"‘�kพ+™ซิ�์ถ ž…uศภ:เทโ ‚šขศk๖A๎ชฒ9,ƒDSลsย๋จ8qm๎๏ฎsฑŽyญƒฝญธืุSG(’(ใ$‹}i๔K™ณไ#gฯ…iภ�่ไํำŒฯ"W@g�š้?AYU&ป�†oƒf“*น”ะC๑z๚ฟHค๊ศมkO�œV๎ลจ(C–‡!ฅx+๗Š™-๊5ฦมฒ0ื—^ž๕็ุzM*P4_ีlP#Y}K,‹Y๑น ๏ณา1๘ฤซฏP&x™uY‹� –ูตจ’ฤ–žaชƒr ฑ {ฝ‹—#/”B/๓l;„‘ด'ˆ$b$-ธ6ืญžz จดฒไar็๚ี™๐๓?๗๙๐*บหฮวg๕w฿z'* Ulnb”ส�์(/ขกblซฬZำ3ม็ด�|,u๒|r,,�p|,”ศ๔ผ๒š$ผ[#{ึI.ไ!IปQ†้อเ๚๕:kฬฟ~z/จŽด4*บ(‰zฌ„ฺู่๒า]8๎w๗w�™๕Iอๆ4GเC0MโเC0IอK�๘Œภ?��ตvใŸ|็�KŸธ��่๏�๑gฟ๔ำ�ฯรO~๑o~kcyแ‹W.^l๛�ฯ~9|ๆs.\ ›ฐณ๑<,ฮ� o฿Knง๚-่.ม„Y2%…%Yjฐ(Y`เILDPH@Hpะ Qaเ๏๘3A ”�์ @ฒvXษจ’ไœฬด˜5๑฿บFคi”ไ{f P๕jฐ�—ภลืPVnฅAš`ห ผ‚\t#,,>?•ผCFDŒ็TRฌแz~ŒVWระุd˜:)‚^ษ€ฮ^z„๓;G"JบPQดŽ”ฒิ ๋Š๏๛4:ฦฝ'd%%‹:P(h:i๛?๛ฆ[zก7€'R dx L�&ฮMF’ม๛๙ูGx*,„ฒŽๆ๗Y;‚?^‚Œ[ƒ.gศ~ฯuŽrํ่IQ,ึpn฿'ธดdฤ`\งpƒlBอ(ฅ–4hQ๖k€iKOjิทฃŽา|โ\KJฅSvOศ"ลŽA5-3u฿Xฆ"้‚gj‘ฒป ๘r —x๎ซฬX•ป๋ดฟฯ�.Bz$ษุฅW’VS“็ย๋ฏ�x๔ฐc‡šy3y'วš*ไดUฺจuฒ& ฎpทท�ึŒ�c€�Hฒqส_์ Pโ^หqุD`nนYณc3ฏ”3่วPAI`๙‚ถๆฐขฃา ตั5‡—ฒโvบž Gำฦใk  โ ึm!ุษ�[\x•8–ฅ่ฃเ?4ษ”‹�)XŸถ5�c-)ึœz" Iๆ\๒&q%ฐ7๘๘ด!›Hฐ๘��Cล๊AZ‚๛ตsE•9ฐl€…ล•ž�,˜“=@�พ ้c�๛ บ|ๅื‡ด"5G•ภ1ฎ๗rl๖y kฺ๖sxiLอœรTpœ๗ ํ"คเฮๆ็ีJ‹ร}อ �ฬ…=&0–@พFุIYPwŸ๋›๕รuํAfJ6ูฎัŸYz:\‰3ข‚ Dcพ|ถ…ืขฝ�สs2๗ดค๒�%ศย_ปzŒ/ส#^K+9ถ‹ไ]Bฑ…�ดร๙a‰@Y๗TAd๓ป(ํ) ๑n`ฌ่>ณ ขku0s”ฟ@XL_มŒ)๘:ญ.๐™กไฦlm�$‰๏สzฬ๖Z�ฏ‚Aล•Šœ-ฺ31.ซฌ๕g (‘4/ฬAะน"ฉ ’ฦฒƒฅ๙59เ|h”ฬ;ค-2v๋๔=ำ4ตหฃ,Q‘ฆ$�9ึ—ฦ฿๋=3ย๙ี›ห‹์=ิhgg8น_ึ\k”ฒuชช�ิใภึœfฒ5˜ดิgยึ=14e‰ ่cH.{Jlู�ฯ>ภlPดฉJข‹�3u๎<’w2าt{ฑb~{už฿ƒˆฉH’‰fฝHชฉx9แlิ๋ฉแตH์S๚”่ —nผrvญแฬX™็^ขUHŠ-ศ๗ dN กด˜”ึ8N˜'}Vฬศ��W˜ส•ศเX–x=†ุˆ-;ู�๋จฦ,ื�g�gอ†GOŸQาC ืดล๚X฿Deย๙๏sn 2ั�ฟ\2 -YXa��ร)ฦไแฃงแ& ฌ๛ณ๘.”$*ธ๎H๚ณ7yo‰ภุš–uฮ?yž�œฏฎใNผ ��โ๚"ูt8{แ,๑y��8ไ#m��hŽ@s~TF€‡2!ี้วเเuาง๗๏ํf฿พ๕ฝw–็๒5ลม๓ฏ…/Œžฏ�๘O‡Gw� ฿��พพ๖G฿!P๎งๆcC€•™�(ฉ'Kฅ� wนE๙xศ.NLOFภตฐ0• ‚Teว‚ีmฅ๗€S3Eภ†€[ไฯ+Ÿถ4ม Œจ�ฬD7’]อ์”๊+#V�เ๏ิ•ศPฺํมl‰€ฮบG†}‡M@IDAT™มW A‹ƒTq‡>€ึ๐๘$เ{+fh^|๙ฑฌ`#ฎ๑ั้˜Mีaพ�-2?ๅไ:2Vฒ“o nH�ทV ฮj:ˆ%ฒt๕ฐr€!3Tz"คษ �0ƒBˆณm!รรฃaๆ…ซ1ำฌืƒA!‘ฆŒIˆ‘ไ๎:‚/-?fbฒฑYภ .์—ษt๓ฝ#ƒcJJ๑ภZ ”ษู๊*…OยC2“˜27ํๅ #ั๛a{2<-Nศฦ $3†1โš๑ทศ+7ึ(PPgKฅAkฎ-\87ฦP,,ฏ,„3gถ+๑�Œ฿๔่vจฤ=›{สxv„‹/ฝๆ๎�&=๘`Nํฎƒ`ธ�ƒท(ข\ฃจ่ย ฏ_%kฺฮ5)73ฯŒงY4. l(L=.$ะA~ฝฒน_'�gpJ?'๏~๏Oขœ|˜V}๚ATืน' >‹ซ{แหฟ๔ฅ0z๎B๘�ฏ฿'+1ฐั’แžฆ›ํหโ‘@ kซ/Zย"�ฟ 8็๐มHw(78บˆืก ”จ๔Qวž"`คจvˆfo€ณULำrธ๙yd็d—ำfฬ,k1เ_Aั‹2คC98๋tำล �๓—/P BนลฮjcMnฒ�๖ฅฌ“า!๋›๙s~T\Xะงบ‡ฝฅrว์บ™~ƒsีษ>eภ4(kฬ�6ธoƒ๗-HบำR*=ด�‹ฺQมm�Eถ�ถkI€5o Bฑ ๊‡ตํ>ด…ฃ๒แvื+ฟ ูฃคDื=fOZืฎ<ู}๗/dภ์ร๛ิUภ‚�}iฬํJEึ\Z…eิ~ืw‘†'ปhีษ๛A๐ดเงakื‘คซ˜๐=ญฮชฒฮฺุCz$ ฎRœ �ฏuาŽQ„Lพถx-1พiLญน›˜Šใๅz“ส๒;›ห“nภ้}ฉ^2Sž'๓)Qt"Iษ>้โโ{vมˆYS‘+๗k‡„ำ€u2๑T[ตฒฮz ”;”;Tr”๖๔โา ฑy7๔๚12ฃ”#Y˜‰าซQฅTc=NะNr�๑|x~™�ฅ‹ผLูฃ๔ก8ูฆƒฤม!jŠื�ja™2ˆ็V!1มำYBลย.๋…ฉคฅFG๐yฺ>ยq~"๘C่ญ’ษรS#์IZํถะ`r†5ศนมูZ€ิฝx๙๎p�c๘cL…ฅเณหZEu๘U‘%™ ๅUม@ฦ’ฯ5ฏ„�าm‡๗Rf†ฝotโ‚ื฿‡Tc~ะm ศก|ฉq‘6MwhG{‘ึก]œ špB$lฌ๐าyึฯ%็ฦา6ฯุ ฤ…�$9ˆCปDลำcฯ>ูรGฃ‚r#ีมรณใ˜๛b,’g-'จF€/ว=ฆขกฬิaฃ 'hผถ6@p o›"ๅ>k,ฅETผฯฬb;๛เH‹ˆมลตFXXYaนpm*]˜WืŒF� �๙ ”๑V่Sƒส็ฦ{?x�{n|โแ<สฎ6JKแ|&ปฦ๗!<$๓-ซadx๋๎รจDษx฿๘XผFžgHg{Ž๓A…š^�N>L#ะT|˜fซyญ�๘Ÿ๓ซๅ/}๗฿๔ln,�น=ŒฝRญ…)wL`*w–ญˆC๔#ภ{7๒p2>˜จu sท6ฑร์ฟFQdkขดˆJ‰นuะ}dษอl๎“E“0p3‹ข‚’fI~‰Mฎฬฺ›9๐๋9ไฃf<:”ยผุ˜a0 'ลุ,&ษ~ŒแVfk๛J๔]8@ึฝM†Gน 3+(ฉŽHR{ฌˆB2ฦฯ…๓d)ศบ ํ‚ฒ;82“ม h!๘zXดmžา~๊DฮFQ’์u[—|Lฝ๖สาbฬ�'�Ž,u€ŒตRR'Œ*๏™ฑFว๖h3็/„‚@�‚๚ !4ภา˜Œืg�uV๗Žอ›แ˜v๓i‡‹๙ล…hrล€a๘w9L“๙ณ๙dร3[u)ใ&0KเY ฎ=AV๋\†ศฑๆ6fษœ฿…`5a&้k ธE“@พžณ…`Žy“ฏเsๆา%”˜ b�W็พฟ๗๎ืcvn„Lไึfi\ฟ}๎�โ[ @-iQ†฿ƒNภ!๗lฐปภQZlญ*LG4{l}สศZศึ*3>€)?/ฒฎเ ขฃน~ IZภะƒ ฃ%"ฤŽผ๏Qxp๓๛ดฎDึฯšจT>(??ฤล]’๋ส‹ถ‡œ ๘๛�†l;D๏–bMท)™e๎:หใ๑gX„˜!{ า†Ba›2ี$1ฯ๕›![|พHฆL‚ hsŽ„qJD€๚ฺg? y6…)%@ŽqูX)๗๏!c�๘bขฃฟ„Ry%นvแh@ 5 [๘้‘\KRPŒŽŽฒO:™ฏ0F€g~ฮL^'kืฎ!�]I๓่ฤdcD�€ฉ‚’ภฌj;๋^� ƒt๗ž�ฺหญ6้ ˜๛ฎ"ลฏU0Ie� “�bŸ DๅK#ฎ'คุ˜ฏIp๐ �/{”Okดญ/ก2ฑMi"จ phT€฿IŸ†๎“พฏ'hPตฑFU฿็่โ�ด ็ ฏูžยศฝ`'„ ็ย ๊š6H™"{]ล$€ู}JฌG๒�Hถ;ปษŽ ‘ู�…ไ้` ˜ู“ƒcธ๑ P_Žฟ5๚3W.ณพเd=}$๎5ฮ2kิึค‚มvHž4>rœG;œช์‘Bฝpนฃ�ฝฤXmo’ๅ)[็}LY วซ†ีgซผต๗มHนร YZ_k“>• C“gY‡Gภๅ�“ฅฐ{ภ,ฐ๚s์ืYฺสก8HํBฺJRXึeV6G๙‰k^€+ธj iด๊0๋k` ปJ›2cิส^mo)B๔qmœ )ศฦํ5ฒิd๊stฅ8ฦ ฒLI‹ XQ~฿0’&sCฐv X[x‚๊ˆ๕ยุ๋…g{{%–ฏTู'žท๙\?๋ ?ŒVึฃคjฬึทq๎ขvฐt%อบmc}AิIู:โehtˆa�s� ฌ3ูVฮฒฆ •˜�rNฑV m Oจนdฆ3ดBๅซ;xtฒry2๖์IK!๖5ๅlgyE?Š-*ฦง€สฃ๋TYฒธบถQซ•3Xฯช ๐]ศฦืJAJ๖ี๙Y ษฮ2%F ฦี9ฐ�FDฒPยDObouc‹�ฉ•dะ!ื ‡gฮž…Œ‚๐c>บTฏ@ธฬฯSฉีาi“gั*žฑ|€5~Œ๊/ร<์A&ฌpiๆม}•g-iŠุ แ”„ไY„จhม(ฅ’๎2jiq5t๒�G๘Sฒ~๋์�ิชฒ|^KœXR`=l๔�ฯR“็ฌํโ}๊xดCŽopŸ ฮ๔<_bฏฝ๐๊ ฬ.|๐ไATdYƒE๎M�}g,qนีนิ๘�๔™�เL็'ธ๎vˆI|A8=›ฒ<7Žy”S‰UQv?*๘์เšซจ%(\์าŠ)h'ๅ ฬU!ดžOO�๏�ห_๛‹�g"1มมิ�hŽ@s>l#ะ$>l3ึผ�็ ๅ๛ฯ�สฏlb66U-/T่uฟ2w—ภ™์มย๛๏}— ;nเFQ ฒ&�”*ฬ(เ•€l?Cึ”lvš lW/yฬฝศ ”ฃyฃzZjŽเ(ถl$PฦซŒฺ–Rส|�SโมO3˜Mข“#zI…cาภำ3g!5&cะcpถดธ (# !๐QF-‰$๘‰2R2ำสี?๓ูฯว2[Šตทt�๋‰ูร~dซEœํ zŸ�ฟK�ฏี˜u[˜%3 x[็ตฏ^{™ &ๆ�ๅ็ศŽ‚ ฆฝว™‹—!C่WMธจง‚ฌฒคJ@fFึ๛Lzฏš6…^�0ตาๅ}{y=d �F1�ไ3Oี|VBฆ•ภT‰fž,}มฝ€@๗์Zkๅ‘ญk&ึมก<ดึm–r<�เ` จ ฐ1๛š t†x- ”fพถึ๖ท]rC้ปญ ้&ดฅฃ๋V@kใƒ+�LAพhฒ826ม5ยหHอืร5ษล๕๕๐ไ�wย๐เ(เl;*<ูx๙#ฦำ@ะฬฌตืU๎นยk_x๙ตHฬ=}ธม๐Š:ีdปื• ›TzX›แ๕kdkŽ:`QoหQ„7\k๕5สผื Eถqฯ฿Zร?ƒ๗VAฐ ุ7๛YขC…*Žฉ™ฆ)๎�ดญฆkฬN˜TœZŽQC"�E๖ฌฤz:\ดf$“‰3ศ•s๊ิฬ*S.๚็)!+wLเ�ฮ่$ุžAย�ส+au{#|��_Sdไุว]’f” k7ฟู๚pk‚yo�Tล”x-.‰.H๗ษดv๎u|'\Ždlฤš&˜8คCฐธO$โ๔&๔X+๎Jœ@ฏs/™งูh†ตy"9ว{ Œ๚‘ซ1ึใ๛fิงฮ]ไฺง‘าc2ศต ฎง/\‚ ๔A`ฅจQึ(Tเa7 2ไ Y๛๊๋!ซŽๅfะๅะtฌ7ซ(ฒฒ๖�๒†v”=”ŸX฿Jw€*+2ด๊P๗`|g— 3�‘„ „\_šc�9c@$G(-ZฅœคPใพฬ(ฒฌงj๖แ�+4ฝผžตใU€ั_+ฒŸ$Zฬ@[๎R„ฺก 0์ ๅ๓ฮC†n,ฝิ�๏R.d๛พc๖u๕๚iˆŒ้‰ 0%*(๎aŸ๖ฉ9LWck?๗Tนœ#Gภr’๙>ฆใBฆ–ฝdหื–wรณว+ฑi+ช’}�๙7ึ๐Eุใ ใ์์0๕ฆบh…ธQh'”8ศอwร-ิเ—9oSมxCฦา�ณูh_�Cพ้้ฑ qนบ{xO�.X{:็ŒN8i5ฺย^๋8๑�–ฐ‚ฯร1gpๅXีD*ื๊8%ษk่พษQชะ < ๕$œ[์tใYaท ธ3๖g™๑„ธ:รše฿ฑ_๕‰i@Pž œ’๘ฐœF@๎ูซสจBทrn‹’ฒๆ+ถ‡d„ถQ�$h}นษ๊ธฉŠIฒŽ4�ภฐ$M฿‘$g "z–ฉgธj6๖ใ)ธ=B๙RFฉRฎ๊ษ‘ภ{วฌ8ฏgท‰ฬSbฮ๚}T์๑-๖)ห–๓ฅฝSž-.ฦ็™็ูsฮญ!แฆซ๏ผ๛~ธ๗เ1mJีGvฯj*5ƒฑ“ค”๋ต•R;ห๓2ฬู csภXK์แE๔๐Qx�”ึŽ[ดฟ…ูตซ>’หv9(s~Y‚ฝLx&™,๐รฮsi๎[ำรี•e:ฤt‡๑‹3(ผบPOญว"’Iˆ™*#รazz<\<>l๎a�ษฯx~z ๑ :„ผ• อ2ึ*˜FฮCจi~FEœฯW็อƒA•”eP�œ๓ิ*ˆlฟlyƒ�ธlb|+๘๔ฒ[ฺNพ�โต�๊›_๙;�:‘่๑•›อhŽภ‡pšฤม‡pาš—�๑ฏ�ำน��ล_์F%๐ณ�ฯฯž>”๔D้Aหหฏ}:ผ๑9ฝรyบ LO…‘adฺธีืษ๚4pๆ.ฐ X”>‘$lžEe™ ,%ŠJจu…Vrจtิ@หจJ`์ๅ.|[: $ฬฬผtใ•0Š�x• ๕ฝw฿Š-ไ๖ษค`๐งมP'™น™ง.H!ฺเ๕๗Ÿึ—ฉฃ.อัTฉFญq@l[ญภ›เl ‡~ฺ€‰วท๏Š�c”3L„‘ษฉฮว๑9ะcAe7ึจ%=�;’xข"-‰‚ใง?็�z�ึqถำำ={|'m �นp?3D้xo[˜ ๆ™ะ›ภ–,'A!Q& eฐUŒ�๐ฤ9”{aƒบ๚พก ภyทขc-TiJื เ�;ะc`ŒqUb_ ่™œ‹ฯžล@W9ถ„‚๕ดŽkKˆ฿%รXิ�Plืb:ฺ{ฝp๙…๋จ p๓ฦแฝ@๖)วœ๖^ชศค‹ไ‡”lbื?>ฎฝ๚zธ๛ƒทQR…D>�7<^�ไ‘๔˜#จํภ=‡Ÿ7๓ฆมdJ"p ซxhท<bเ ›?ณง๚™6{6\_t'“'้๒eฬ!px$…% EฎหNš"ZsŸ๏ฮฒf*แฝ?�v ขญ�ถ๕b+ -Gฏ๗–VjmR้v€ (™๎Ž อNYภ`T0ฐ&๖!^ป„ฅุ‰Y8€ผkญ’cู๛�งฯขน’็ฬะ(ใ๒lธ5๐I๖G—sืฎ๓ีFPฬ&‰ตไ}K]d๒ZP $$STั‰ 6�ศ’IทV฿บp๓ฤณdHOใย่Q@™„N๎Ž9�“{Žบ‰Dาฬy>�ฐ"€HPfต@+ำ‘๑iค–๐�;฿ก ภ๓P83ษฌ๕๋็Q>u›?UIฎ@m@คธิ๖qฏvtˆFg\w €ศ5็~ืPŽุ?JฆI ฦ๋V]#ูf‡Oแงร'>๕ฉp๎สU๎3ƒ฿ส;Œ Š ึL ม6}๎uFŸsก"Œs‚7 z ๕EK;&y€•่ ฯ=iW*ํล๕ํJ œ ฯfg๑I@&ฯพv�ฤ๒(V�>จ `ํZำ'|ไน— Hฟ†>๖ฯ�๚2๓ษผRซžxqฎgEฺZp–ึŽ๔๐จ…๑ณQฦ`บศน`{ฤ2�ึึ‡ฐXS•$0š>{6‚yU3kซปŒ7ํ5[iำ‰ ก…�{ˆฒFฌRDb0�iฝ?ใ{ฬXฆ8�Z็ึwg็ Zธ๎ฉKWุ›๓B,๙Iฒ๏+•ํp๎๊%ฦƒZ€ถฤ['^ŠŠ|๗@$,œs;aจf*#ํๅTyฤ=‰ุ๋Fีƒ(‘๋ฑ„ง“6ทฝ์๕6าฯznคG[ท*_oฐgตชฎj D`ฮท™[๗c้๕d ฑz!Jmnkน‹ญc จืSวถม>K๔/h็๗4”ธ*๑|ฺcnOศ�วฝƒrอฉž7OŸ<ใ}ูƒฮฟlปQ k%.,—์)๑ฑœ+ )์๙hซฦธท๔"`์ฺ9#$๐,ำGเ” ;%;Sฬฟฯ/U@^‡—š๚Ža~น…ฒ`gc'L…+(วN่˜qŒˆ‘%Œ15�๋ใฌ฿ TDr@•GL,›ZYZเ� ช๙฿ํ�„o็ป\็ส9ส˜ เcขšงฦY�ฮ:v๋5เ>๔SBมN%ฮขธ7ปvๆ'อ๙ฎชNฅึูหxKPฺฃLDฅ;zส๘Œwlบxึ๚œ๒๛/`Ž qฉeฯcMําแงฅ6ํœื>ใ5Cด‡>‹-ู“ผษ๚LFeิ๑ุล{ฉจ8รkJ"tA$ถ@พ%“ญ•ฉษษ฿๙ห้/�๕_�ๅ_น๗ๆ›ไอๆ4GเC;MโเC;uอ �ธภ๊๊ญ�“›wพ (~๋ฝทฟ�๙๘�ญ2ร€ํลo„l฿E2 กน๒๘(ู๒6๊‡บร�ไ็ย$Rl�ฒ“ศ‰ซั฿l#เ† @c03ๆJีh�ท@ฺบz3P�dNณd ‚=‚d%ๆf๒ฬ> jึ565ฎ]‘งพ๓ญo„๗ฟ�}Hๅฐศฏ•ฑ(ฺ›�ž๊�หyภW„ฉ’8ARuzž‡๚!@0˜X•๖€yฒrUฒ�‚š.Zr @RุVฯlษ์�ย�์ใ žDฮ\ทญ้Jƒจ,ํ _๏I$ฃ’ ฉvdฏ™-€UZM˜๐Y ส'‘^Zๆ <๙ฝฝ-คฆบ‚)^`�ถTิ)๓ฺหK("๖Žศ !ฦฬ์ผ อ๑$๓3yแBธ}๋=2ฉHำiศุa„ป;ัP ฉ1ฃฒใ gมฎm�Žwyฒ ถ 3ฐีฐญ5†ภล๙ํ%hคMgฮฺX‚ฬ6พŸแ�N7—bภN๛ซ0}๕:bฒข�KPํหx�6ศ(�}็mœๆ7ใตีธ&™Vy=ฬw%์าฬ„ืหฌŸฌตษ ™}๏WWํ*Y๙Vส1ใผ๎oญว๚n��!  a๘ไO�Tฌw��ม'ภ $sP&pฮ")ท+ภ>ฦ zœ@ช$˜ใl'ฆ›๔<7C90Œั ๓งูAyp.ศHงธk๋�Y�ง],๐ค`�๑ลXŸc�„qบtใ7ะ  on`ินุ&ki�๕(2๙3๖"kfei‘D-&_�JšU€ธ๖� 2ชlจธฦ�3๛ิ� ภ=d j–sๅฬไK�\4f๓g%K6Q~t0ฮ+ซดว„�*’™ฤา”หฦน�?!น\ำ ภn ฒalj†rŒYิ8ท(8Šฏ#๓;ค0๒cึ”t*;*dุ5ฎู}๖Sฃงพ ุแหผ�ฉษj›Rjพข<ุฝ Lาˆ3ร4K}้๊UิE็ขF@๑ลOž{ao#ฅ็ต,™2ปฅ๑์}ฏฟˆ&A๋ฝdู>mอh โU' `@ค€ผxใ“ฬM/บpฐ†mMy@iƒs/ศŠ-YS๎ษT z–,ฬอ‡$kจO=ฒyzฯSฆ0{๛ํฐ‚F งษจ,j•?vรฐพฟ ULU` yQc,_‡;( –ื`ูhˆ;ข๕�aฝ'๐tศpฆ๖ัA"ˆ…‹ kปฬึ๓�QO‡#ฒ๎z3ดฐo$*%M<๗pr!C‹Jขฏล]eโ]xC์nlกะZC%IุณJ๓ีgOั"tˆ๋&‹ Y—dฏ Žžดsซเฬrฮn1ถaลC�บ๚ž€d€ คฅ E๊๊๋|= ุ8',๕A้ฃJงง_2ล‰*9<�๔ๅฐรJ%L๊ึ6—™ง"๓uZว.h฿Z™Xr.ธmฃzฬธ'XปIฦา. ๚Yจข‘ฤˆd+{คƒฟส๓ศ2๚�์Yžํญไd!vถ0หฃ-W ฦฬฅมŽมฝ>’v+ฐใมอ“vฟ�œ v4zา_ภ~ุJงอาศ่P�โ‘๚๗†yฒ็฿�W’f(ZI5Z ณณเ- @ฐbllP๐<~}hd$ŒSฝDy|bŒ6ˆ—bfิšุ52…�นCyพ๗oลฬ�J��›?ˆ5ใs„ูฤงP’83ชˆ=ฺญ%CO๖ุ,s<„ฟ@ื�ฮ๎พจค8ุค- ฅย @หษ‘)๊็ ri�d๛Tซ`i-พตมmd�‘'0kดW๙&@ฌLขหLe€eึณ•๗๋Dfญย {ฐS~%�ย ’ฉ>Cเฝ ด๘์)k†}�ฒ้r^_ฉฎ}โ] 7Y‚ฑ†[ŸปJtCpุjP‰ธF’๚B˜�K๓:*;หaฬ<2฿Yึ‘ฎ๘‡”๔qU2๓ ึŒฉdษ‡๗�…*E,บฯGฮ๎ '‰ภภฤƒ%+ํ๘Xฎอ�P“XๆแœYคาA Iฉšฤ™zงq_DkหR"�‘๛Bอซง9��]ˆ*ฒ์q‰-ห€ผึXr8๔ฌXžD†~�ฯkp BT]ไP๎ณํๅฅ˜d1/EฺYgธฆfฒ51U†พ9็ž4ใ\Ez^-แ€/*g์; ŠbวˆsjูIฐบKfธ๐ัำ!Gฦ;vNธถ4@.ฯบhg-$@bš”&Q1ณว7!ท(X4ะฌqฆuBRI ญ=[dฏQ�มZ้ค}g‚ŸNิ9] aำต01„บdส่๒๛-แ1]Y็z2˜=(M ๊ŽP|Y*"9"หฆRก‚MŸ3ี’“;๓+Hสz ˜ ๖3mL›�ิ๏ข"Xใฅ™ใอp�๊ qจพจ”ษฬใYเYาส|ด0พ}”#ญาqว๙OXขร{šม>ภ๓BยภาฬXJ฿1ภๅ�=ป%—จ๐wMHwOห <‡8๗�]nาLฦ๎˜5Ÿ†๑”ด‹:ุ<‡ๆ9ลูศQˆ‘‘foXŠรG’ะืณ|% ™Ms~ข๏฿C!eอ่”giเ๎mH€3Cdฒยณgs‘๔ๅ่าแ„ดํฃ]ErœƒัํŸ๋ถ$ๆ„r9หยบ!›9žY3์Sh•D’mเl+ภnโšตฤฟ๕๏‘เœ[ZำมบIJ ุƒนส๐~E”ฯ1^][Yค‚j$N๐˜ี—๔\h'น๗ืฉg†DŠeB*ŸŽ9cm[*1๊:ถ4ฮr•}š-V๑h๐฿Gฅ"ฉcษ”ฅ– ž–ขเเตๅB๖�_Gณณแูๆ ช•Nˆ๕_6ฎหธnAŸ�wฯ๒w฿y2c‘๓‡๙ๅ฿ฑ์ ยฬR6I†xŽr^่๑Pๅ๋�Ÿ-%๚ฃฒbN๓CŸใ- JUz3แส•™�กป๛›?๛s?๛�ฺ_�ฏ�ูg>๓น๗ู�Mฤ8‹อ�4Gเร?Mโเร?‡อ;๘˜Œภ฿�‡�ค๒��อ�s’''๏�ัีฃR๙ Yค์II$�๊‰ห;งมP+dข ‚5ภ ษำว7ฉA?5ฉบw�.Yษ่ผmยs2!f4ข!‚าF ซป=ถŽฌT๙uFฬА4้R&ูNvl‚:b`ภตเ\x�„€x‰ถศ 0ฌื4›/Y`g€$้z]Ÿ๗€ึG++อ“5�@จrฦ=z๘0” d‡šส๏ลใ oHZ๒ S`()@ฬcŠจ๓๗>ม๕๏]gžบๆฬ^nออ…’$ภ�๓˜}หฑVœKkTp;C==�diF�คนJพœ๛ภžœ:u็พฟ��๓}ปสไอส [gฅ๓dฑ  มฦ1NขŒฦ�ฎ›9W๖p9ํUˆ˜ก>ฺMŽฑj0ะไšRd7ึ^๗7b๗ หMบฝ(4Tตฒจ`HbญBvXsษ…๙ว€ฦ เkP�ฉฯ}2ƒถฬน3*`’ไ2ใk�4ย๐d˜ZTBNญ}Wy ์๙„๕ˆp=๔p7ฐ%%Xk%J0ภ2ิ €ฟ}‰ .ฦ2ซมดภมuค™Bศ<^ +ม"๘ีิsok+f7;!%!Š”็ผ›”าXวฏ๒ม๒‚}ภ—๕โผ3'ถX4{�O ‚ูZzอOI,ˆฦ๊T-p9dM!ฑ๔๓`ฝ:6พŽTณ๒‚}[FZ็ญQb•๑Eธ3”-�]Uํ�๛�฿ณC†{ฑlFใT๋ %% ฮ]ผD‘ร๕™ฑ~i—B้‘fŒบธOอ=Wz‡#จบ๓๎w้yฟล:$ำ‹jก?€`Wlทช@ ซOG{ฑ5)#หฑถ&! !;ด$ิ"MFท ซxส-iภžูิ"ชS\๋�;ใฎร|Š5™gxอ*kจR�Ž๗bI‰]?l ุN…แ‰~พม๘ใ5qตฟ‹๗๛itfฐvJ^ดธ%2อฬ�›~y}ž๖ฆ:�S‚ดW†<ฤฑฟAM;.�ป์ฃฤS๗ซูi "B๕‡%N๚ไ้–กd< แSfl๒œs๔u$๐ฦRโIาf“๎Žuภ‹–ฐ๗n?D5ดDyส™p้ลWx�:’œ#็.QrDD๖€†ziภโ ๗^wqB&ถ๒ŒHภ�ดqศIlจTTบฏอ> bง�;‹ขBขRo‘:‚�!–Ht1๎Wฯpฯn�,T โG“fo[>•ๅ{m–ฤ1Ÿึภปf]Ÿzซ˜‘฿\]d.ศ"็‹uู IนN‡œ:คYฉXลŒrฏ‰ึ3O๖™ื$ั�ซฒ�UลฉPัฅม่q$Xƒ9�ฌJ4ษ;KZX ’ฑ’‡>l*ๆ†"นmฆเ @f|7X#์Œ>ฌa ]ใ ˜6UM๊qvQqๆ[uฬY#Yษtฎฃฮ฿=๏หฎšอhŽภGdšฤมGd"›ท๑๑๛�sฤ�๘ท�แึ�ำgฏnฎ/hŸŸ9จ$›บA;>jZ๙้„ฃอyd— ฯ��รrN{Cืฃ๑›เ๚้์ใฐตN].@หฬ�6มปŠƒ‚ฎฺfไK€[k�O�ศ™ฝ%ˆ"YbํนRd{~_ฝz-๔L*I5cำN]f‘@Ÿ๘ƒ ‘ A™ฅ jป1ุ™ม`๒'๛c‚ฌ,™*๒ˆ่ยต—_๎��วTq‡ @€ฮฝ^5b_่S}ณีm;fh% Ž*๖/ฆหoDˆ( เPW”‘่ดE?€W0aฉ‡ืn[Ck?mป—ฐw๐๖Q/Z๐kGด; “้!˜ช‹€ํ+dลถจฉ�&� �ต 8�๘ูF”`lGะJฦ9ฐŠ�ิ์lso#lPหN :26M@K&˜1]\ธฤ�[�`Rิ€ip�œ�ญ[ญrนใP ๓3ŒtY€ฝนธภ;๑}{˜�ส6ตว�.ฏ็ �œ™ํี2‘%‚�Vิ E �๒˜ *฿%เ฿/ํถhร—ษวŒŸua”พ๐ฌ…ีๅีธrdOธท|oพ= ๋ ”(dำํ=d ๚)1ฑ\Bp`6rkล๒อp๎๚e~eม๐H ผoฝ�@b3š๙™a[]~J Š™uuœh0…ึฏใเ2โp—ฎ �๋‘ิ๊ยPาตบฐ4›^)`ฆš!.ณ๖ส|ฏ•`�@งโDำหvคฯYJOzศ๔ฺฯ=ร�hXฅ)ฏhLX_� Q2@‰ก�ปย๚dๅ’ฮ0›��1พ|6j:�;†P”>VŸsฬcb6SSฟcœ๊มŒu๕vึPๆํ๘,<ื รลฝีP~#‚�*€ท ฑv๖�E๖๗หฺึฐฬ=ๆ๛ืศ o ฿wญ0 q�ปGNๅ๛�B<tม๏ม5 ่V๒>H็ ๗ธืh&=9 ป๒kษธBW฿L?)G๑,น0“ฏฬ_ีN,Iœ๘๕$dAr๏ๆ{‘$ฑŽ�๋”h่์้ƒค๋ Cต�[ม—YืV�DZxป;3_�(œ˜๏dJ+๓2}๑2DๆŠ์5ืกeFGช'˜f’์/%Jหw!�บภรšhฺ2นF๕าเš� Jโi:ฺ๐K!อฯŸ €_ยGeHkacบd;$�ห‹ณXgHฌฅc@,m!้ ซzยžูD}ฅZF๒FภšCลU‹€ธั€ ‚H�กSC/ {ฒฦyาห่๓!้#‰d†Y๙=jp๖=๗ฮนg+ห8 ฺ~ิ5�x2*�ฏž“=dฯ€ด๕�•CหJR�ž~zjฐ6นง็ P ERRbาฒา!�ฌ9ษM๗‘�s็˜�YCูQ(๎p�`UึU"๎•–dgแะุ ].ฦ U X ภ$ajœyถ€4�]่ๆ^ศดs_>+๔9ฐuŸ5๒วœ“�Œๅg,ฒธW�>oีšฺอa_E…sฒ ™™–xf๎ู~‘#ผศš)— !lT์ฯY'V‰U”.zX๎”คิคป›Žฌ)หfZy/วEห ็6›—kณฏTNT๔’’–ŠXnแ„K๔ฅ™ŸขŠ3g™kณ๛ž-ฑ3_ƒๆฝSH ีึฬI0ฺ๒๒+ืbw-=$G=$ป]ณถชฝw๗ถฯR พY^P%“ฐค`$๖ˆTHูjฒƒนLs๊า๚q๕าโเเภW๚ _�๏ฯ_~๙พqJ๓ฃ9อ๘hŽ@“8๘hฮk๓ฎ>โ#+�๏ปืfย ํIฬœ๖‘ํ๎˜&$ใG@บ5๐[_NTN๐อืt~ฟ0s‰šOฎLaฦr ไ� ~NภX%cงTำ{จaำดั{ฬA$ธฦภ3Kฬeฦ=๔จ/เ๐w|„Qม’ตช ฦH˜‰< lฆ)ึ!ฤJฅAอ:๏tิ”™ฌ!›-E={.ึ์*)�c4นฌL>y๔0,?�พห=j2hkB ผb>ณอ,ฮืฅdXd d{iน56ส=P2ศ‰ญท!3"8#`ญ}ซP๒ยซฏำoœ1ดํใ๎๎^VชZ๐_��ฯDYตมฆm/ฃ‰Rโ]ศKW:Z iPh�rเLฉ| ะ]'๋v‚กปปWv ๏˜ ณR)ฦย๗ฮQ{้•—ECผํโ€n๓g!ž’tลx…€฿น? ็/’u-PVq"iƒ๑จฐท 9ขค– ู์;z$ ศ” ส�ณ˜ื " ฆ•„ณ˜g�3๊ ‘&cืำpๆ>ำf ม‚Xฎ .g?2๊Œํษ‘Œ๕ม�๋Z/‡`๐€ืQฦoh/แ3Ÿ�^‘u&8’lKpฯ๚_h<๊พฐ\F ต ฉ‹Z�#ฎUฉถชKG๖POœš—ีQฺฌ๑uิB ๖Yยฮ5Yeฝฺฉd๒�e| ฝอคLˆ์o`�ฉ4ฟฐฬฝใWภ๛›ญ–Hฑžผp,‚[ีฝฝ�”6Eจ<ป“}ณ‹�Qg_ืื3•�dฏ๘์ƒฬ6บ=€�๋ี AะซัชIAี –฿<๘เVฬ � มš‘lผฺขt%ศฺาธะว}E่wยฯฆุWชV์จ ZI๙{žs$ม3�่NฬXƒร๐ิ9ฒ่ซดบƒ@ $ –'H*ฐภข‚โ`าŽ{/ †๎ท 2c{ !ก?‰g™„€dBฅƒ๊;Tฒถถื๖ะ[\7j ฦ#ฯuXง_Fษต}ธU ภcZBTTW๏p,…PEล+ร’ฅ%๎ทฦ™’S•บชaNX๕|เ�ฑ๔ศตฆ…H`nฝ9JII�OMsk–np/[n.’M]ฝ(E˜รMฺWขิ่B9าส๏ฤ�ร2Ÿ*%Uป›a`ršฃกฦฝlpฆŸŽ็_†u"เ๕ฌ;a฿6Xฏ*๔ะ™ฟมšbฑล,น๓ง๒ฃ ๅ� ตR{๗”๐“ภKpตa4aววัvฉถธ�๕DR[EZถ&dืืง?'แWfจ82ปญ2$กy!†ฟแ ไ‡k_OKถ๊ภUkj#ห.๔แPํK…˜_=k$ฟ}/Aนๅ^*roU|#’ฤ’ ชœ sอB3dๆ-wxแ๚ตH€7�>ืฎ:ŽA‹ืฎ‘คๅI’ึ๙KNิ! |&:_ึ�;ฏš{ฆ q๔’ิtื๕๎๗$…,-ใฏ๑๗�SEˆย?%ษ1�‹๋ฏ@V๓zฒ๑+*ˆ$ส(ฝเ9ฅ์ ฤ5oA  ๗‡)ิฎ5๏3ล=X’c�]ฃkx6XสP…่+3F๚ีX•Mœ=~/O‰‘ฅI๖ง‘ฝœ�I”Zจvw่W‚ๅแFนทะ}๏พ�‹�ูฏ�ฺ๓ฮžฝธุ$ ˜žๆGs>ย#ะ$>ย“�ผต๎|๓›ožฬ�ตฏ-พ˜|ˆgV๏gBYdฐmิ +C%�@lavOd๗Eฬภ43�&ธฏP^พ~#ฌ ฟ๙oVฬ8w8ัข ฐcํx?มl(1สภi{35ิฆ’uฐ5”fƒฉมแบ9\คพ�q”xkง๗$ืgFFcVG0dVฅ‰๓๘ไD L•ฦ�/�‡Ar…,พมŽภ�ถ]fฬข�:Sี าw™๚๚จญE%` vฮเ“ฌ €ำD์ฺ”7|{O Aเผ.ฝฺษถ[็j'kEmํgฬg&&:ดฐตR๖ก)b'๒ฬ��iLา฿>แHR๐3ส็•’๗Bด่Ÿ%‹ปMV/PI";KVป;สbํ”P่ง= ุž๊}(C—žGภ3<2Iฆy6<ผs—์@„ฬฝา�V‚ห\อ๗B9Rๅ฿๚จh์šํท}ๅู‹ย+Ÿ�ฑข๎ด08@ฯ๑™ฐ๑|!<ผy SฒSW{3i�ผคŽ}3N%‚K๏ฅBฐm๛น‹/ฝk่๓…ซื_"ำy๊m๑ฦ็ฟ= ๋Œ[‘์ก€�:heวผlTIธหรฒ๓u.kจ้ท�ุ. U‰j{ง๗’ฝ<�*K4A ณ5”.๋x1ฬ†S๓‹ง…า๕หืiˆ|y๗p'Jกf๏Gฯƒ|W๗LK์ฏัเุ่$]FœQร WฯuBšI.ุPดBnhTyD๐]ๆSย!Aฝqsแvญ+m๗๊UฬDใ>ฬ%ฆฺQ„อ1Sภ"@จ”'y‚ืŒ%;บgK๎‡Cค YT๗mLซผ๙ด •�๋ขf'ใ’€Tุ็w‚ ะD ‹pg Gณขฅ๛ร˜#ฺ†Su‚m๚$cบ่ชph{Bˆ€ฑไKwไ`�6 f@aVนI@ๅ8(:$M�g5H%œฯูS�‹tึ€ ๊โฺปถ[vร้ัฬB�็๒,ืึ.*ฝ"*ฯช�พNฮ‰?ป,<8ฒF(�ธ/• mtแ๊ร…Kg7>�๚๋ož:๛ท~๙฿๛ี›"์ศๆGsš#๐Q&q๐QŸแๆ�}dGเ�๘+-ว๛ห���๎ฦหบeใธž๏#.%Šˆ] w"hะ3เู๓9$ค๘�Ž@?xพ๑ต?!0& �ู>อ–Šบ้๏Hhเๆว6m่ta6ไuฮ�ะฅค9K aฐs†์ไ@๔w�๛™-อฬRฎ ษใ.ตญิ„'๏ผ‡B‚–vžv\ณภ�)ต้:^%่%๘?!N2�}{{ €ั& g•ภsq๖!™Lฺ/€vท๐Aเšz๚zC`>,GPฺ…๙œ๒Yณzfห ˆญ6๛™l5๐„ุบdHฤ‡งงB–๑\ ำ„F~€ฌแก๑ž็ž=D…กฉค™�€A1<|pPลz&ฦUN\E[ช๔ทธ๐ยuฎ@IืE ?ๆ@o f’๎ fSyฤ าธ๗=คพฑ>Ÿื/0Žฎy็^ม"ฐ8`๋ผถฤAY€PipAถWณ&ู e+ฟ'04ฐ7ศฆข|๏ˆฌh€lอ:ก?kผฤ8๔r฿ ฌgวF2ภพ๏f]•๏no†^ฬ.ํn Pถฺฌค}๎ฟม`๙C9y m|๚d[/รuฦฌy ฿€บf’Gn�ˆBืHฆ›’‰Œภธฎ2Fศ<—)ฅู฿คำไ^”'dš‚ ๎ข‘)€ีฒฆญๅE^า…ฺ๋dฌอš๋ƒ`YะฏฑผฐˆดขยFBJ_๗˜ฃœ3ผสŸฬฦชRะ?ยš๖6ึv๙พฅ$:๐›ม•,ิ\•‘b=1'dSมŸ๛x‚ล.ฮq‘Ÿฤ๛;‡›ถ3NํœIึ�ฏฬฯว9ฺc-ˆ็H•@e๛ษืOŽ๙ณ›3`yiน+Avb,ˆ จฒ๚!ฅZจ�ฉื1~M2ofk™ื|†าฦผƒณญเ[gฮ้ฐณo:DNŠพฟƒœ%K้ศn:๎=ณอชฅRฑ#kมถณGบCร๑|[6;G!๛๘ZdŽ-e๛P๊d๒ฝจ4xฯฺ>ืะ๖8C7๙��.๘นษKืBไd‚ฉ3)ž—Xˆฅ�…ๅดSผซ$์แePฦ@ิrŽบฐ˜�$*+‰h;์“‰ฎ�+H๔ัฦ+R’ฃ#�ซีJโ-!๐ร}ชJรฮ/fํ]ๆE“^ปๅฤ6Œ…ไ‚� ฬŠ๋Y!จต� FฉGส |�ฏi^k—2œ kA…ค.`:˜HV‰฿Gฯ๗%/ฯ–6๛O7€x>ั>3Ÿbฆ8�*Xคq/ถqฏ�œ*ค์ฺ"‘“g\0–KIŠ1&*dา-๕ะ�ย฿ท“…~ งŒงฅ’ŠœหG๎_ฎ9’œ�!ฑ<ณ’‹ใwU)œžA�+_dซH‘ฐG‘ล:‘p”„๐‹v€๐w์d?%m๐ฐDฉŒ"aฒ•CKฒ๘฿ค‘็‘ž+‹ Qอ7;;–0&}ข๚ํw฿ [ ‹(ำTRH8fx]๗†๋ฝ uVJ– ฤDš2ฯญvพ.Y๔โ๕พwๅสฅฟ�‹�๎—�เ๊๕Oฏข2p‹5?š#ะม๘ุj~4G 9ย๘๙Ÿ�J๋ฝท�ม•ูGwขงw ฅ ะ(ฎฯ‘้hด…๒ๆณะ–ฦŒ‹เmใผ ๚‘W๑xDiยอ๗o…n?ฌ๎#ญํށI™€ๅ4{CถU C nฆจƒฬฅ2ฯ|‘ท‰a ไั7YX‚e2MึD๋ิ|๙ลรุ…๓ฑฃฮ๊�๚2ๅUb ›’@IDAT ร-€[ธ)ี4Pน๚ยต0:> š ณ๎ฃ<ฺ–ษ.๕0ฟ๚ฺ‡ม‘1jŒq<งๆv  ~๎์…ฌ”aŸ9ำO@ด๑2\J๛œ™|Aู[�วล-A ช๛บr๐<&ƒf™c@DดT€ษ!ฟ<ุา฿ จฒ๎�ฌฬ�po‹ฐ.ื�๓d‚Ž้OŸ<ภq%l ล’ƒฅJ(ึศA@ภ�}b{e‰`๖ิ˜๐0ก|ฝ)๎ไฬ๊hวยe&;›:๊“='ด –jo E@žLdŠl—_Wฎ\Wฏ\d"ๅ^ฬ.>}a๐nุCPTYฟmkฌฑsc8ฐ_!0Wฒ y‚*B๒@0['บถ„พฦhZ&"จQพฟัtqš๑ฦTŽต˜šxๆิ1Kะg|G$•"I€ๅ"พ)1ฏ“ั๋0ปลุG'pdฎ‡ท…ญ%€A?™ญ3ธ{ำท ฉ"ฅ 6ฬ˜B,}โตฯ„—^๙_G&k72แ๒หฏัๆoŒ๑\@|‚ไvy.อi�๑๋๘_์A|ํ‘ฑดผ ‰„฿1ผ๐ย•H ฬ=‹มv๋]ื~=6zwฐฏศๆu�G๕๘ฎ%๗Y‘Aฝฦž�\จpCถrำฬะ_ต #zp,�`‰ืŠY�,ืํ๘บ�ทY‰1ณ+ฆ{]ฬ๏�> Jฌ-๛X{�˜�Bถ•}™bM–Y‹9๎“ฝ}60‹[]d]ฉHเs}ƒM”]˜�ลอหืxฮ์จฦqŽQ™3ส๖‰๑>ทc3ป�wDฬ ืm๋ฝVฒฮัGย0‰ม)ฃz๖žvYจqฯ/ฟ๖ˆ}aku `ฮ�†เชQบSฐ๕ ภฑ ™}‰ชCKZ๒\าqุุZำ/ผฮB^ฝ๔ษืรฬๅหa~๖x€ส๙ฐว�ฺ†€m`’XฏC8น6”(5ๅ+ฌ๏๑ดU$ œk์d,ฅJ๎SŽ`Vุ’กณืฎE’เ ๛c๚ฅ๋ฌSไ๎œ•�…๐“_�e&uฌู=|S$ ๒Vx&Hฮ่กแ๛์m�'ฑdIRูืFมq�B&œ๑ฬฒึ้ฃวzฃ*็@Š3๒"จl†ืQqี‰Šศึ‡ซ ฯ8'(Q€H ^ljv(ูe—๋ ƒ?ŒdขW3ะzใS„๛†ะ=@aดมsษv’ \$ใƒŸฤฉe/z\h6™ƒภ่ฃิ%ถบๅฺ$ษ๕Q๕ลQ๗™^๎น$ฏๅ๙ตฯฝ{|ช\"a)Vbพ%จŠฌœgหpธ๚าต0M๛`�z }CCœ›*ฦ$j๓aุ5ˆ5(‰m+อH†2ฆž#‚๛ฤ›๏c๑„s+Iฆ2IQ~อ็d€ๅr�จkby?'ูQไ|ކฤx‰๘:?_•ฤแ๕$D8V!ศ4^UศF#ะ$>F“�ผีึ�ึoฝู๘๕ฟ๓7g็–ๆ^'x[|NfฐX!@฿]z฿zƒต53๊„็—้�]!P�_Gep๋ัBX@&^!@œ๎‘-5 kp้`ภฉดvภบ0ถ~_c2kะ{ฒ€ฦ.ฒว– llะ†ํม&R]‚ห]ด�๏ฝž=ธซ+ศ฿ฯ]š ็/แAภ4จD›Œ’๖ฦ�ฯ�›=Iž^็y_feๅRY๛พwUW๏๛6รn €ฆHIัขMST„|็๐…/ta›ค#ฒ#Lฺฆd)ไ,ฺ–i6C%’H0 0ƒžžž้ฝ๖}_ณฒ2ณ2หฯ๓Fพ๐ภ™, ฆปซr๙�พ-ฯ๛ž๗ผG"ีA&w‚\บ‹ภ0,c wฺุฅรภายR‚ฉ} 2ใ๊s Hv�๒฿ ผ๗้๖ไศFธ�ฝ๏‡/&c ๒ฮึมœฑ =ฏQ,Pฟ~๊ ไB…์ฏžuข˜Cดฐ๊ข3EํI'ส,‘๕ภว5jw�1`�ฤ oฑCwjๆy›Lxบฒt�=ภ1ๆ|‚-ญถl๋Œ!‹&s†ฤ‘๐บ(cธ|็^๔”ุ#87+5�:ู @Upฯ จศ\CะดโMค O3UI‚ฯ•0ุำV&Ÿ‡็฿�ZHาžd๒i9ฦrWฯ‡{Ÿ{G๒Gฤ9|�—,c๘–1$[…œy—5rH๐hภฺ q๖โEฦ‡ึ€Œตู๎LNท๎~‡ŒP ฆ‹๊ตpคไ›yi0ุีลŒฟ[%Sก&?วjฤ5yป๚าหa`U#๘Tiq๓๖ฝ่w๑์แ๗ร๛฿�*€ก‘ฺ๛a��d้ฮ"O= +�็+?๚…ะ92Bฆ5L#สe วฮ' L7(ฅม,๎ิกุฐi`%!Pž>ก>vถ4้4cX ‹บƒฏ†šษะ3<€rZ82‰f๛“'d[X7)ฒๅ์+ห|,(0gf6{๑Kศ@ˆข„ะ=>‰ิW๒Dฦยu�7=4บิก™–”ฦี ๎็่��ํPpŒทOb|ร6Š €‹AลB/ -�:{ Ž้Œ๑Qโ-(Z�“๛ˆž><@ก{“Š`อ๋4๐o็};�๛ใ”๘ฐ~T•’<ถQŠqŒ3ภ2”#ŒO-)H5Uอ(K@๘Œ=าv|’ิ„'๐PQ:^ ปษ๚๛๑iO„‹(†Fฦฦ) ม„๓คส}[6qเพeexcฬ�่sA"‡ 6ฯ^‚๐ูฆ 6 สฒNา‹*(žz‘()4z&™8O } Œฒ๖๘�ๆ^m }-˜'IะถมกHp้5Rย<ด›ฮ:ฤcดy„?Bฌkฯž„—^ฟฮžํวd๐9๏หyXฦฯ„užg˜˜†)‚ดkวH๒,ะWฮบ`ะ—๋8SVa�ซR;zl{Œนe7[+ด–€ด)g–3ŽsหาŸ2Šจ๋ๆ„�ฌ‰ฃ๓ฮํฦ๎&้ม‰1สnศฦ6ืP|5uงย��ฯ‡ค™q‹‹3๑�:!‰‡ฮŸ ƒ—ุณฬ๏"ช��V ฏ Hขๅ=ึศVh้ำ,—7ะ„ฑธวดสbฏr6Vชถv”rึ$˜๓D’>/IฎM%€ฅสชZ c›บ-+แzk…XV’ฃ\ขƒ3ฮ�”b=๙๙ั ุิ‰'ŽcวYVโต๔‰ฤ …ูxหๆRจT‚น�ํ๘"ณvฬ<ฅธH`„จ฿e@�ภ`?c†W ํ„ถPยHdk˜สตณN๘ ‘์์ไZคํ<ทŽ ็’��•ต�j7%็ฎ�‹ญešTZ@ๆrFtข�าทgb,Gฆ}xbœ2ดพฐว|๐ๆๅ๏9ั๕M�Hสxคฎ;™๒}้าQšฃl.อ~f้pั3†ตฬ๖‰$e�ซ€เw�า#’œ žๅŽ}…ต,ษโฏฃjq‹�์E},%Œ*'ฯยaฯ๛แๆ9ƒท„ผญ,Y�|SjuB)Ÿือ�ทีP๘ธ€r ฿œชฤ๗ิ˜,„n๘šK#ฝก‹ณkรZ�ๆ3ebt(๔AœUซ’‰‰ฌ#ศ —๑‰๑BoฯWŠลป฿๙สW๊Jn�ซ>ŸฉจŸฉ้ฎ฿์งmฺ�ั๏.<~๎ฝw��๊qฉ6$�ตฝF0เโสKoศn‡๙๙Eภ6n๏CgศNะ–P7๎FŒษ@ุส0A`ev4fม๐TดQ{=08Hฦฉ_ˆ.๎fduฃถF๚ฮปฑฦ� -าฮฤ๗กฐฯ๗ วฮfiWฆงมิฬ‡ศ&PZณk–UG๗e$’šœŽ^@ฎ?Fฯ`|ถฐพ�ต?ๅ=—ฦkศ Wย3d•e@“&Y{>๊„�ฑv๔ฉจต�{‰ซPภ�สฦF8„ู'#ช<บL-gล ๗J GฐFtฦW๗dศ,Zตˆ?B5๛]1KNPo;ลัฑsแา๕;aŽ{z๒๐ƒp%l%เ hทwa–๋ำSd:1\๋T@X‰ฒWบฒ๕cภดRnsˆใ—ฎ@ข\1ฆƒ่xAkมๆl/ญฝNx^•ืฤม~ ’EBกึ;ถจฃฦ4 ๋P?>๕เA8€ุษ17f™ฬดš๙ี๔qา`y๎Eœ_�นห7#!P`ฎบ๚ฯ@$คbฟv3���Cd�0์C�พ03๐ภเภเH9ๆส~%^”า๐›แฟๅg‚ต"ๆv;ธอ๋B�ภ˜F‡~DวP_ธ„ Eณฝณ็า�1ก[f์ศ๒�๋๓sิC$t ฅ^ k“/ยสฬLx�่QX˜ž ใ็.R =_๛�wพค[}ฒ๎\X๐qธ˜ค์fsฦ†lพkู\� dQท>f๘$ชฌ%�fฮ$”87C ะo�ฌัneฮ�ษ7C๔BŽู /fปนO Yัำ@ีธ!$๒I2ัfŠ™$๖ณŒชรLจฦ€Jญqhl{›ขLH?• ๛ฬึ˜[( l7ii–% –†BJลR6>ซcห‡�ฌrฝฉœQ™ qฃญ,Sผo3็ฬ(c๚๒ซฏัอf„ถฤK˜Pn`๊�ษYธ^L=ƒ:Ž�๕๘ฌ€Ÿ๐๕ฏ๚ิGเฏ่|ƒฺยK๗พ9๓…ทา_›|๑์์๖ฮึEฅบญิ๙๎๎lA์…็ฯžlำ�jŸ CจLGx๘d:’ภŽ�hV iง@/„o‘ฝ^�ภd {D€^%‚ฉุ)—ฯ ำ aืทปƒL—’u%ฤ-ปล/ศ7ฤe fญ“6[ฑIนยG๗ฟ&ŸOข\จๆธZ>ภ๓ฉฐŠC๙Ÿ�ษืรs~/Xœ๏ฝ�.ม9เp`ะ—AาeญKถีฒNผ@P(มQโ๚ จjฅู›ำ๋VฬcษฤฤWSญG%ถ/ไWQb[!ำjห)’๋€‘b@ขฺŒ|ำพใอHฤํ001P4๐*น๔จQทŠŠเ๗;3๙4ึฌทไปยีปฏeรภ €ตhจ+9ื๐ะzn{บ๛g™1๛๘ใGฦอก9ำึ–VQ,Mc C5ส~ €^�|5&Q P� :wvœ@ต5์6–ๆน ิ“fด;˜�ั๑sqฬ_#ํใ.8�$PึTฯ,ใ&ฯต<ม–Š–ง,ฮNย?€lศฐ xK@5�1์ซพOดB6Lโค ๆ!ƒM ณศ”{\fศ~๕ PงŒR"A�p฿ศp”ำ^<Qช๑มป฿}Y*Cย*‹ม}žตuL`ฝC=|L็ฒ็ั๋7ว#Qฮ��๙ว์๋”v rPฟQำ์๎•ยา�๖P ว>ฒฦฉำฟคอA™.ฬQนx3ๅ’+-˜If๋เ�›ฉsM(‘งyhำฌZ รƒxh\A๔€๘ฎ�€ฝ*๓ห Dc9�มij-ปูOฐ๘๙ด\ก%‡ใh-ฑc฿ ภwlc›)re๊ี-ƒiๅ�4q,ณง[QดAlBŒY6าzมl๒ๆ€‡็Fบ0œ์5ˆ๖|‚tSๅ๏วฌ�โ>D{jlt �ฤO|‰{Gญร๓%๒R์งba3\ผ๙J่žธŠฑg"<}๐~ผฟLš๛ฮ43โถี+า‘รฃ^ผzrB:‚ฝึ6฿ฬ_4<ไบ�3“ฒ&yK๎Šsม’˜]‚‘3#จ$Rbาzำฝฤ˜ชžฐผ๎ - `๋Q=_,-z�;฿Šญ…Oศ�,๙Š{…็Ÿ%คZVะiั…ฯษ,็wžs>ล} �-ApŸJจฒ�๋YPๅ•ฬ๔:‹�ทตฬCลR %G$ฤท{—๗Qต !"‘ฏG‹๏ๅ9๏๙’D’F9gฃ6ฮป6�pz! ๖ห_�๑฿๚ี๐+�ม/‡Ÿ๙ฟ^๚�„แ๑ซฦg Ÿฮ‡แn”จฮŽSšม�./ฌว’‘อญีธึ]—๚utu}๓sŸ�าฟยื€;ฏีG >ŸตจŸตฏ฿๏_้89๙�†_�ๅ�:}๕7ยWพ๒ใŒ`‡…�ๅ๗�ๅ๖฿๚ต_^X]^๚ษแณอ็ฎ^% •๗฿�.^dฬ'๐พ…™™ๅฐผนpธลื-�€ชlฐ@tBฆ„ š@Q บOฐ�Iะฃ‹ณ.ัท#2Q ‹๓๓usผD2ผ๚ฦ›แ๒ตd…vรฬ�Yaภ9A�™%ฯd๎็–ึย Aเ�!Š@ัฝบืษOฯอ„ๅuฎ cev&,ฬฮภŸึ~rQ "•%�;p™Md@•2› ฑฌภlq…€๒ˆ€RขยเผQ…™“ %�š„ไ๛่#E'k$Xึื K†G ;4†๗ๅพึไGุ้�€Z]^Ž€ฯŒ๗>~�ํจ:Ž๔Œ/-Lฃฤ ž€ไ{N\นจโ๚ rร H๓ฑ��‘0Kึ|ƒฎ 5ฎ๋้๖ hฃน—zlj่อ๊^<|๏ฐนCYา”d“ณI๖dš5~ ย0?04ี-ซฌ'‰ฝP…P%ฤy�ŽŠมฎ0jคš~พo#๏๏นd๛ษkื.mฬ�2a€x%ํ‚^ห\โY !ุAyHG—]/Z!แš9�๚ขฒc์าๅะf”n1๓ธ๗๋]ฐฬYถ ๙EฉD“ร|ะถ“=6๎7‰ๅUฎ฿6”�0šušมทsH ฒG�@[/%วGึJ๐๙ดฑนqรฺ—ˆ…;‹™๚&ฮดSe';๋ŽคŠืqc Oๆ|~e6 Rกม็2Š˜้™tตYD)E+BH๊DC'l็ฏฆŸ>‰™xฯ อำŒฉˆŸ=�๛_Sอ:O ตU คนึ*ห$$ $ TDƒFฎู๓R_ฟ% M’žO'�๎2�ณ@RSณJ�ส=ฃด@อๆ}$`.6(‘ฉRณำ†ฏDคR?mWน๖nฯ ๆญา๏อW๎†ฯฝ๒ Ÿมถtmๅy*’Œ ๘ฎํฃฎข Š’‹*๊ห๑6Q+๊กช"รผI<ตดuิ๎�y๙ฟr�๖ปnล๚W}๊#๐:q๐›๐๚ํ�ี““_O>�๖™ถอโ‰–สๅ฿��฿๕S�฿}�ม�๙{G๚G�ื—็ฆ – �?๚ฬx##ฤf3“Sxl† AนแU• &๑ƒoใˆ$5šdษ๗ษฒe ุ‡†qฑฟณ๏f๊•—๓€/1< JJฎมิไฬdx��Q4๓าฅ_G๐™๙™ฐˆ˜tฏoQ7I–ซX"ำRล1žฬตA5฿ ๏e‚้bšhM๎@J‚ฎ�ฤ5ฺSŽ)9`๐i{ฏ"Aฃ†U^Œ™˜F‚ณ<ูฬพมx�GdBmŸeถ]ฉฝ-ต”ฅ›ษ1kด˜แ"Kภทะ,๊อญ!ก%฿%‹ทJ`ๆrG€ ๋ฌ}พกA2š” V่„ iร๐/J� ๘fŸcทzฯŒวn�รฐ)๎k;‚๔4ัจัฬ`gGx๘๎๛˜GธW ‰(Cšฬtžgว๚ร�["b๎ถพ4I6ถ–gง‘๔C6๐๘475SNq;ถ{œ›|Fผ@เg บuฐ€p€า็�๚`ซJ&็ไ;น—ร(ง�š5๎่7m/๒๛C€ElใG\x�ซ๒ุE] เi๎B– ด ้“่ต"*€m3๏@qํ์R€๔3W.E5ม`๊€๒”v‚n&%*ฎP�Qf�k�ฏs—%ƒนG6ฆ$tP“ฃ‡|๚ๅ&ๆ>ด�ยฅa๖ูฃฐ67�ฟ“๕ภตQฏพgG ฺรeณ< ษ=›}หํ`Žึ(Q^l‰JGGs$]ฬฎ� „Y� 5๋+ƒOฤตห\ญa‘ฬoฒ ตต์‡ +ปGX†‘FbKHˆYyณ๔ฎGk�mํxZ๚ƒR" หผD™2ค™w•ึข€ศู๋^œ`œสท3‚Mึ˜โช7ขpๅ�ิwA…‡%!‚ฯพ!€$Y๙X3 ฤJ2>ื/gi๓๏�”Pล— 2ใE™Œ๖๙–V;’ญวัV‰IฦABMcNฏCะ ‚@้๕@ซเฑฬL๋qั ๑5rfŒ฿AR6ั�‡*„ตUR ฤ๘๘ˆcฅ^’ฬpZBๆา�•A)v>�^—~HTK"ฅ•{฿2(๓ว*�7bฒฑdล!ฑ œ_v|H๚T(UO0wษV�ุQVด9–งภ�แฺหŸ‡$ฌb�nRป~�;฿ ?xŸ} o~๑็ยี;ฏPz0Cษ aืีˆGI*�!ๅ๖ ธ$ยv2ว๒„ต๑�ฃ‘๔…Mˆั4gTบ‹&ฅ9ิKถ๋S‘eฦนฦ<ˆŸน=สฃ8ร๐ ษ๐z‡ศๆ E๕1็ฏ_ o�ฤ_cŒ้ฎ@)Kณ& Aด1=M�[Zฮฒ>บศ(7q๎i’™…@�[ลc‚๗ๅ"0ฎm!‹<ถ๑1i‡ljรE2ืR๙ล@'๛๕#9'ศQย™h้ ”})ib.Z๚๐laOHDุVฒ=๛ฮKัhฑฦy)™ะ�ูวผศ{ู]ฤ๕!ญงม>R��+งค ซ+~�@์mภ๐|ิ)eฮ ‰–<๛�2#^ ฎใ"ค]‰าคX rรฎ8zŽ$ํ’jญœC%T‚๓ำึฟฌฮ/วึ}‘a��†QE‚„*w๋‹/D5“„้8@4œCกw@)•Š–ึฌ�‹ใg๐ีเ�ถ!k๖0!tว/ŒทDฐ็ˆ%%๖T"๋“3วz่xฮh*ุ๙=@��žฺค๒YำีmKM๖>๊ [ [ฆQd-ธถ%๋‹<฿ฒ�]@กYงๅjฑณืๅณKC%8Ž ~กlจ�น€To๑žนื ki๚ษ‡aƒ.K#๘e4ฃ๒ตยั*ฤŸŒa‚ืชขLม !ฬโ•๑ฝocถห}๐-Q’‡„€(_ผ{็•฿›ธฐฮสญีG >ŸมrฌีG >F ‘๘uบ.์D�/Ÿ'?๘“�ใ^c2ณด…Oฺ�๏พ�Bˆ‡-�d๓~Uƒ๓Fdฃ:I/ฮ‘ญภศษฌมฏตู่ vฬ๐™กe ฺc หฺ๋šO้๕0`9ห๋’™ฐ๙/พ๖Mฒ\d–b^z๙s1;df๕ฬญศ�ฟ๚'e฿Wต5๗ล๚rU 9ฯJูluซ{ิ ฆบx�fJตm9ม@sd„บq‚MkD“d\Z�17ค_๙ฬ‹็€คึp๑๊๐์้c๊{๗"iP ›MT‰�œ2๑QพOšj“๘@ย]ะห€LW^ƒฐO)ล. jm‘s'9ศW‘@ถ…พz(;ค�ฺย`k+๔„8่็ฝ�น๗๎0r�JŠร๐ฏ�ีd7`ๆv–๛ซ†G๎วl(ฒ:l„\฿Nธrํ-ภq์Xฦะ yLะNZ๘9’๙…EผGแย๘A6u�€ขlิ8` @ู�e๓Mยsฬู:ๆฮ’ฺ,ณๆwศˆ�Z๚Bqปf C\t ฟฆD`t�ๆซ4+ซF30[V@NX๗›'ซN0‹ผํ )F.ค-ฦ‰ ง๎.^็ˆ,d/ใ9ˆมุ…ซด๒Zฆ eฅห๖ึZ(ย๗S‰O@›sฯŸB–`๘฿\]พ-{Gฯ…๓/ฟV Zษxงษ๘�ฃฃ‚1๎มj!,uา!„1TaPa^’xvิXฃ™ve�,nะ2p|‚บck2‰yฯฐฎม€‚ฏ*๏q(qู "Cgx[žY_ža|pucค›‘uณ&wศl&ณvnภ=วEงs@xl;ศบ จ$Q)P7จษผ'ษX พ“€8•G�ข๛ยงSy:t ‡ยึ:%.ห(?ธv$เ”(‹�€๖,>ฒงๅพ(–ัQ‰ฒ™ัNbI็xkใw)kตฐWศ F‚Šฺ@?€pฑฯ�d"!ˆP'คนvมซเ}฿62ศ<ฃฐXAuQk‡FฦQภCฒป•] :;x>*%๖ง๗ะ ษSญ5ฑu‹ง�฿.@฿‹‘ั+H๕๗#ฉขฏ„Љ่KAp\ไLaM7ั-!‹ฯJDฦ—‚ ˆท3๒x๐Z<ฅุš‰&c]ลศr#5&˜ ๑Aพd e6 ิ- '์ณC@x๔;เ=š97ŠGEฮผj{WHQส๑ไั๗PCPŽ4Aฆy2ฌ.P"ฑ้� ฉ๖๐๖ื�(�ฤฯ�b ฯ>พฎ�|5ไื฿ภJ๓^eˆ–็F ึŠ—๎น›2€”7;vถมlc=ฆ–‰)๋#มY*ช’ศPsํ๚Ÿ4jrวฺŒต๏ฬU’๕xภ9d๖7C้ภ๐นsจ6ˆ=ฌ—ถ๐๘�{xjTiwyžqฃ�๋ใa‘ืณcHgG_XฯSŠมYื”KฒVรcฬ7-อู]X }ื{X๓ดL„z๋อ๏็„ษyบภZyต’ืJ›"eศ`)โ@3ณั–lP๎๏ไZู^CU@g�dบ๏,[kลำCsศ๖('ะฏ#฿Œ์Ÿr‚ื�FฉึrŸ‰ญ;ทึ.ส`๖5ค\ ‰ญ –$ฤsํxฦ. ผžฤ•D"œ…œqฏJ่Qพ‚Wช‹‘ณcaโ�ฉOk็ใ–๗ ็6CRWSภ$ม๘น๓ฌ=฿ว 9Cุ[�.รน—@๕$้iY„„ŒW”g๐๊าะVe_–ณด‰๕%ฑ…A dผญ7ำัŸวr$ห›$U4� lOrฉ น(Yทษxดwฒถ8{2ผ—�-|Nฤึ—จ๔แฑDBu€ฤTš5wย’ฬฯb)ฉ~�า%ึ้nPฯฏผ�์๕� &”Œภฑืป†Z&†Aฃcฃ‡๖o‹๔b์i`ฆƒRฎA&™๒ๅ๙ู(>ญ–P:&ซ…l•L™ฒaมอฦโ<๕ำศ฿ Zห^฿-ศฐท๖ทขBฤvcึก—†5สŠ’{ฦR} ยˆใ้๘o‡ทึo91dJ™ภ มฎ€ AำผN วศ8œ_พ™ฒIนฦ่ํpแฒล�Y "้dะฏYฃ� 4?k๊@Q` ฏยEใดฅ…yไผ-ฌฅ'1งาoKlๅ €็Xข†๛ำg€9&ะŒZ;ฌ๏„†t)‚l •Œม:7หชD?Eะ฿ยฟ!9ถ๔K�ณห”(AR9v’0ศO๑ค‚zืกe:9K�-A86;ศุบฬc๋้๕ฐึ>M์”`` vc<8;๙”ใk idy ฏw@ณคสž*a�kดyEณ๏<฿ถ†ถ…ิ4ษ Zฒเ๘ฉr�ฤv‘ฌv ๖ฬ๎๊ๆฏ™žคYฉŒผIด*ภๆอŸ�Iๆน๙่8%,Caqe p…ฺˆ๕f ี’#~ hdU4๏Sขe๏๕ ŽD_k๒Uบธ�lฉYคตฺ~o๒~Ž›‰dีช‹’์ใkosฝมcZWI๗+ฟท‹‚ฆrq>ศSฉ7YQฦณย๚?ฦhฐไŸ‘์ค"ญu„2ใ˜ว˜=ทึผ„กฦ๘wต7†!ฒฝญkfƒ๕ูbํํB�$ูhO ๆleช�c๎m.E ๘ใ?๗…ๆ‚&ฌ);ื€�c๖yะฺอY0ฤนเต-ฬฮD/่ํL ฅGฤAกŒ|‡๙eLนe๎zzH†บNZ๑�8sv”๕ˆวF/ูgJ$๚GF SJx0�Š ะ.9EฮHื๛ข‹ณถฝซ'l.ัQbXฝฉคกฆ๊ห=4”hT}ฒ ะ๗อจ“ฯŸE๓ศ~ศููZs2v\0ฯก”2;๋ะfำV ฮม.�cึPษ๛โ,ะ๋ฦ๎ –ฤุ.Qข@? ฿ำ๒„H KUlปu๐rDษ”�,หh`ŒK(Qฺ วฬดณ˜๘Sษพ "ผ~žฝงqซ2�*$`‚ณr/“}ฦอL}ต�ฮฆฆšง^žc‘เ?ชญ\ŸŽณjส๘I๙Œd๓0I<หผaฺซjฯข<>v)id�œ;ษํ0ms{QBก [\๗฿๙หpผK9sh)ฬใฃทD3duŠฝวB?�๓q s๑๏Sล$ืœๅ>�œ�…�ถJD๚็>�ฺ ศ4๖•q๏K�YชPbWQzxฮ”๙{–ฯฺŸ@ญr๗�0†jํโ๙sœyฌ7J†๔%’�=Iฐ!?๘@คฌ‹ณ„shmi>|๔๐Cถ)ฮ๚D$/�ธIื”ฟum�ๅwyp�ซ>๕๘ŒŽ@8๘ŒN|�ถ?]#๐�ู?;mํ›๛็ฟ๙�์ฬยฏf๒� (Œ๛~ษ๚Lฯอ†™™y1™Zฬmfเe๛=k‚'งฆ๊่snึ’1{8ฐ&�`ฟย๋์‘ํณญšฯำี9O€#pzพ สย•ลฺ]AณDa<ฏ)ใ๕ฦ K'{ืn;พ*๗ึ่@>ฺวทz3O?Š€ศzVK ‘™๎‘�n€qูžŸ ฝd.*;iipl๏๏ทพ๔saโาpแึฒXยwพ๙'ศ€ื_�e้ŠO\ จ,‘ีํˆ/C(<'€๑๔YฬXู9BำD‰”=ฤu0ฟŽzb5ร�๎&ฆ“p‰?ใ็รลหื๘ูVLบะŸp โำิb[†a Y!ฬžz aผ฿ๅฅ9œษื๘{- s7‘k๋ƒpฤ๘ํ‘eU๘ฟV�่ป;{pง4ƒ๑ต\๋ั7P”๙G ๒่kคPคปบร”5ฬ�ฉuาภขpท๎V๊m[™Sษ€ว>เA้ฐaPผPabเซ‘ก�yะ๛บ€สMศ…้ฉ็ฌRๆP„ สฎ๗ศๆJ6ค4‚%๐e๎฿Œฝเ^‰…œ7ฦ ถตวm\‡@ศL>—qToฬวึ�Žฎ PJexฏJ’dึั4D@ฏWภ {"fs็ษฝ ฆ˜�๘!ไย.ฆ ( ”JKเฬ;J–H.Xฆ ูึ ตคg UI‘์ผฟjฟ4w4;A1cRe~%C€…๑=5Fิyฟ๔~cนเษ๛ึ›B2วฑด์@ร:�„๒ช\ณ ศฆB"\น{7ผ๒C?ฤqAU‚Hฐw5r[ž~ฦ๚ัวb‚๑ˆ> ฌ๗ฆ$l๋81ธฯ๚Yœ~ ‰ณ}ึf™๋r>w้‡€JฏตDW๗กส =Cด\Y˜eKฃFเ~uิฏ2]pฮญD‰ƒ+ŽพžG(J\Sญมฎ(\ืใySfŸI>f �k๎ท๕P’ฟทuคCO> mL_ qlK๛แ์ฅ›'ฃl�h]บนพ„\}'–ูŒO\ Kณำ๘<9ฝOิ ฎ๋ฅAฮแ:เuˆาšFฎEˆ9ษ •R*ˆbง ๎๋sั-ZฤJฺxVšกคc!ิึšฃ;M ’uฮ*มg\ึฌ2๋j๘ยเผ'4ˆง ๗ฅแช๋œํG€ใ^฿=�ghu+เต$Ee™๛‰mฤžs�ฎ๋€^ฃ=ษ*ิ#|Vูxrชชƒ]ฦดภฝYซ*ฌ$]<๏,k๑ณสuเw4Ge๏9>ำฬฮ๋อร๑เฦŠ฿m(s๔๐}๖ น๔ฟ9คm…ฯฉ}�ง‰9ไq_ญqNN�า๓B†๗Pฯ^หฮ: |%�’eใฉ2ฅHูผŠC‘฿axๆต๕ดc4ุรน�วZพ&)‘‹:ศฯ`๏EยC…‹ฏ+A๏:O1งฑ๓?๓บ]ศ‘;ๆŒ‘\(ท็™“ฅไไ์๘ฅv!)F“ฤแฑ‹‘ไณ๋ลIst{:4Bรด20ถ>ๅuQจฌฬฏฐ�>‚kย ๓�ษภุฤ๚ภศฤ�๔�๑๏ฮ๑ภ๚W}๊#๐:q๐๘๚mบF@%Bโท~ซึ๐๓ๆ�a้฿ฃ7wยV2B‡ˆu‚ibฒŽRqmิอt่6�bj…™เ1๚Oิ๑๗›<๐M2๐ว�พL@uB๐จฤูภ/g–„ภ^p`ฌ Me๛ฎ#คยฝdŒ _ย,ภx๒ม‡dศ ืรตWฃ๙ึ�๗�Gzkeอz$Ittำ.์[0฿ษ฿uŒ/W ”"๔†‰‹ฐ›ร_~ใซae‰ฬ] ฬfj˜„๔ข’่Dฺ‰‹8€?‹ฃด๊๋ฯ Qฃ[w ข $@'๐ฮq�Y$ฅT‡a|*#s/l#37'x๋tw๑Y~๑$” �ชศrk€ึUฒ๛้\ เl ฅฝ<์<.ีฎ’]ฅญเ๒<๓,ฝมO �”+ซ6hีก�ฤsz-ศ�๙€W~oนˆฎ๗Dˆฑu�ซื@ฒGaŒภ\ำตศˆf��๓€Cอะ๙žzPOL๐iหD3„ึ฿ ถฬ‚.ญ.…ฒHeภศ1 …t2์๓ฑn:P�ม0Yณ}”+ำณ๘'ฬAA๑3Mหศ๋ห!d†Fc—ฎ‚Mจฝ%ศ/“มKQž oFี๕อญ}@Lฆษโู%A'�'”j์bฎศ"Œ’z!-Oศ `ต!knA๎lVผrๆ€๕นA6Z5ษDอ่๘D4ศ<5�ฃๅ&เ4 ‘e` ,r™ำไ‚}}1šzVชSd0UŠS‚,o_#ชXห p}�i3xใQQๆ†kMp�‚4๏Y �สSฯ ม‰–คIเ_โปi&RI’�ฤ=ถe๐{m�๓>YK�$ฺMa}y6ูุ๎Pfg…5๚faU๕”จyทณ…ŠŽืแ}ท W `ษL$‡�็อk˜h฿v 7%4แณฅ@ง y(HฑE้ศล๓แฦK๗"i`นว ใ—‡€ ฎ-,F๐m7‰•�^€ี†โ@iถ{�ฦ๓฿‹๊ษ;ฯUBž#�~cy&ฎวจจ {œงTมึ'ุ"s-iีฤšึด มรPฃ€”a\5q๓ฺ]ฃ–฿ิ›ไ.EึP…o๏I`j‡Šย๎>ำษ9Fk”fฮ8‰`�'0“์ -ๅ J/์ิ’…`TQBYcfป 0wแฦ5ภ้.`x)fก๓ญ]ดž}•se˜z๚ฆ๏฿ ๖•‹ํ3๏ซ7๏qŽRึ„ก\7kิตnหภ6ิหศ๎;ษ`—(๛‘4ุุ ดˆvญบ๕ปฆ�r]ไธ/AˆH-๖Kฐ_๕�Y—iฮฐfjแ[์ฤมาึ๛?ฬย๓ง์ู"€‚r ฯ4ศ`๖~T~q�z�[ฦโฺะ%฿sย3ฯณBsษH]A๙:๊*IฝฮkW›ผ.r๖GIฒ‰๕"ษ‘์LCh๘:‚pฟ=๓ฃk} )ฟฏกJiyq>vŠp์U 4pถmTฅภ!วx๓<� ุ„ื๑บ$ˆ�ฎ�T _Š๊” ๋(�V9Oก‘ขc•ฯƒ}”ดฟ-C๐œpf{ฟŒ…ฦˆ’�‘เ:]Ÿzs๘Yg ฎg‡ไข฿�ฃฯž=็QR:AไuณV[ t_๐๗ผฺใ^ู^‡ y>‡— ฌซC�๏ˆำ—qิd๘ิณBัตแๆ๖ณา๗๔kxศ๐ฑgCฟrฯ ๓แ๖ญฌกLุ„X;wn"ถ,žsข้ฏkษWูก๏…$น*ฃ ๛Aำโฮ;q่%ก_G‰ฯh๗�้yF๛KJล,รDญะฯyบหจา~ถฉ๘ษข๖ Œ02�ษn9ฉqึฌฯฒf+”๐<ื^zm็๎o�”��KWFพ๛�ฟ�ONฅGq๕ึ�S๚|ึF N|ึfผ~ฟŸฺฐ5ใฏ�า—ž๏K@ดพrj(ีN€oฮฬฝม:M‹ูํMnถ\Rแ๕z‹์๚~˜~1�๛ห๏ะlคะ๊โ~ฺBC8=–0`D9•:… rˆฮ#)rŒิพQฐมsˆxC+๏ีCf?Cpuด‰ ๗์#๕[Z:ข*@W๒�ย!J ึ๑๑Kผp-์›ๆนš*…MS‡kIลยฬT”ๆN=}Lึ—ž๐( ฆ.g�บciWมvฬ�2พ๖ ๏ฆ{รุx ุ Bฝ‡ุ๋›๛ฯ“๏T>|๛[a๑ลSไ�จBศ$ฏ@(QU–LŠ9ั#‚บt๐’\ฝ)Rx%dP €7Pม˜™‰vฮึถ๒๎GI๗:าt๋l๕ด8B>kvฺนeุbuฒฤ์ดญ-•๑ช2Ÿ˜ศŒKฎoฒg—ฏ\Žภ‡[ฃีื™ฤบภ��{กL ฮF˜œ,ทSM๒ฌ=มŽ๗2~๕:�ทษŠ.ณžำฏa˜G6๒ึฝW!˜:Pะฐžนฯ?ฤธ Bกrแ˜5ฌ/G“ั0‘@]ลAผO”&šข้cPbพkฌ๏ �ถ๋@Tฒ„{ฃ’ไYีะ‰ัีF&“๚฿ oRงุไูQFฬnิ$Cฉ๊A-E‰™ฤฒ^\K‚{aยใฯ>i=hถะ 0�1^o;๛วyถk€D•ญข›C€c่ผ?o{JจŒ€(g6Cฌนข-๎šะ~ั–Ÿญศึ-S0mปิ2Tก(แfwŸ„ฬใ1`+fปฐ”Ndู็Qตภธ5#…Nฐฟ๓อo…}kุ]Khุ*Hฦฬ�ฏนžืณฝนม�4“œg(9'3ฺ’W‚V3พๅ#ˆ8ึc#Rsืhš5�?p&4pญ“Sดgภๆ‘[ฮม๐DEห`sš9ฑฦฒ"†�T�ยXง!(์๎Q4k&ห;pชส5dฺ8ฬgศAฺ๔ ๛FB๚ททฝๆˆ[( v6V™ำvคYํ›ฏฝŽ*ฅ “Cˆฮ %Cจcฮ;ฯ�ำ้5ิไฬs€้ฉ ซEฮ kx‹Ÿ�]`r๒1g\7๛�9�„่ƒ@\\’๑gฬXGวgฮ”Xฆภุ๘ง_Š5“คิ้ ญ๐ูt:๎OถS[>จ๔ฬ–0h—`B๕TคฬDT‚ลต[@qeY“sฤฑว๙็HZ#%์‰_€,๋R�ค›k๔นู„ˆKฌ�]J;้xใ๘T-๗jเ�5ไณs€dŽไ›gปD฿ะPธr็N่ร๛erฒ€’จฯ<ฟwgi|หVg฿qพ ๆษฒ6z๛๚Y?œฯช˜ฯ}ภ๓ส์4{ภาึ%๛URภsกน�าู๗mSรยž๛›Œ|�g\(kซฌw ๛ฦ๖ฟ�ฃ†›MยVๅร1ื฿ั�ฅก"� ”ุH่จJูX…๘Y†4ดoA๎ดโ tฬY9?3ร๘ฒ๓ใ2ค�๒ฬ"^ .PYพ์<แ~P้โš$cำ†9ก๊ฉFฮ›HHr‘pg,ฒฌ�œ€๘ฮ]I&ี~>�0พฮ:ฤvถ™ฯ-ส่8๋%โlญ์ฟ%}๔APatโŸ2mถผ”ดิศr;Uุีax„Ž�ผk`ๅ$|Žฯฃ”*ึbœhฦ†:ญ8Žl4ฮHบํ $ฺ^วฑฑ๑๑๘w�ณฟ{ํ๎X' โดื�Sฯ๔ิ‰ƒฯ๔๔ืo�ำ4ฟŽAb๘๊ฟxcau�ฏ็ฺฺ{d™tดN% Bษ\ชyMย๔‚pม1‘iZ‚ณ“X๓ฅฃDŒสชŠ{d):7vศV’‰่กk€rศœพT›7“คดว�F€‘�ึx=๘ Pƒkฌฟ5k$(ฺม่i›:yำG�Yไแ๓ำ/ย๒� rOฬฒ”cvฦ๋โฝข‰ภsui5‚_๋Kํฏž&ปlซล,ž lf๓�ถถู๐%�์ [ธiŠ.—๏R�|๑<ใ€R„uฉ:aaj&ผ๛ญoโ�ฑOyƒฒ'ึ— 8O�rˆc๗D‰๓ขะQ•ะEฝฟ$š,ย˜=฿B๑ขIชญอt7๚[,[`pE[(@t�� ม฿I<จไ(5P,3>Eึ๏1ืศN�MŽงพชGJ์Wื{F@ส�+_/Qš“…ุI–vP5dยYˆ€ก3cdGๅรุๅ�6Jธ*‡t™ฦ�€‡ลhh้y๑่Ixp�ƒ๐�๏ั†ฝ้fฝ�เ๘๖gŠืEฉท ศร8’๋[_^ŠืeฉC์Lภ=ะาณˆ™็‘@�€*$ฯ๘ฉฎ๊๏๏-๔ k F_ฒศ”O\ปw๕ D0^'~%‹“ฯฃ๒จ‰=.(.An:ภlYŽฮ}K s;ขคูว๖๛ d˜dซ ZZใ ผ€BŽL�"*ฃฺ1j4e”Wvศฉฑ†c—ึadažฝ‰aๆู�’‡œ9ํ*Jซ‹ก‚W?™งO้๔ภu6rถธ�Tฉ๎‰-2๙œ๑์ฺ^รซ„=ืหy–‚ะ๏ใ˜’’•ษฌWึฆฝ๎ก}:.XZิฮgI‡5@o๒•d8๛™Ž0l+๗ฏDฉR bำณOฅป›๓›•หYาศฝ”)Sp�xVบ�—ช„์dฃ?A•ณฉYดฝผEูะฟฌโฑŠmย`ž๕ษฝpe๖žg•ŸU’xช^์“ƒธVEถตA9รcษ]’๕ง๊Abœ‡Aฉ,;Ušํ3gฯ(รฬ฿พu;ฬณ–Yำฬk฿3Jต†$Bl‡ษธXฦเšK๐bmƒKพœxV่ษyฃ D5‘ฅ(ฌด๐ํ‡œก{หฮr8wžฮ„้ฮsพ(y}>ผๅ—ธ_Hข๒vุš}6f^„ฉวiyนณ>t�าo^~ํ‹ถ_ไ ๊_๕จภg}8r๊_๕จภงaT�ฝฟ๗_<{1๓…ฅีUR�K ฟ*�f'ฬด์“%-yR๖[Cโkๆฤ์ทMดšqrๅิ๙๖๗v†Aคซ�@ํˆํ—.]‰lผ‚  ำ่ฟ๘‹ฟHทƒqฒ7XDณ&ณ#ํ˜:ลf›rดu๊๎gศษv!!_˜›จฺ:บ#ะ2C–€ไ0'ุ.\$ร& Tกฤ๙ิ๓€ฬฌŸ†ุหž{4`ฒื์ป๕�ฯ‚ฝ ไ‚a5Jๅ˜๊jN‡ฆ*๒Hš ๒๚:�ร๖)h#หฒŽ|ฟƒ�กผ�๚�็#ึืVศXQRq˜=ฎO0Rk๏ํึss๖7K�5L็ฒ5๏ฟC ศ‹�์JXŽa0 ฺ30ฟ๛๚็#ybƒo�ฯศ`!aจๅhอีQฺเ™แ˜ู.Œ“œู&ั์ชn�‚ีสร‡,7@ถส?ศ*[Ÿผi…ฤธz๗5ๆ คอ2cC&–Œ› R‰ญู�vˆ‡ั‹—รอื_ ˜ศhoญะ�„บดผยl1‚�ƒ„‘l๔ะq?วฺ0 ศ‹“mคƒ`ไ% 7ปป‰ &Cถ_p{jะฦ~S* ฌฑ^?บฐšlc) ฒ์ง IบภA฿ห\”{�†0ษ5'’?จg�#]f_7Cd™�?€<่Š5�Œ0ชHึฅk;;tะ‚ผ ภ}๏ศPธy๏% ‡โ5>๚4| #ี•ฉ้พSศ฿UMจ0,YะqŠ€ี2Šmิ:ึนF}ณ�MJZญ‚ถอฅyฒษธไำำ–{QUภะ,ฎศ5ค๕%po๛ีy"Q"ม–ไš]ร ชFJp๏[ผ–๋W๗โ\ |๖! œg3ี)c�–~‡ปtoมh6Aาญส^ึะNูฃสฎมี fŸ Œ‰&vl ฅ,ЇŒ๛e}Cswศ ว฿ZGฮฯkXส”c�K”ถ4ส›ุS ฌฃฎฮ^@ื*s•ย•�ิ{eษ�ฺ&”YH”!๓ผงเู—f์s{๋('์uT(*{.�พ๒๘tฬ<^<|Y3Œร!ืPใJM‡�IธKT๔vHฑ,!จ0%ฒแIึž$ฎ#[ฆy�{�ˆ5–ฃไd�สuˆ1<_8ง๒๓-oฎ1ๆค๚งmUตBF™มฮ3/ฺ<๙๙ˆช ฟผผh.ลถฝ-์ฉŽจa)a,Y้๙์Zwอธฦ‹ิึ๏Rฺก*ฃ)ฏฒ"ŒsๆˆตZB‘ ฒM๓MษLIๅ๚z‰่มpภ8๎2v{Œc"Fsฬ4s}ฺๅ˜sบ$™„บAลM#๋ฒI ๚ิT’V„ผž๛A@SVU2ฎ ี<ภ�R+?Tr๙บ{t็YžcฮXำ์ึธ›ญ0๕ฎเ๙โ๎๘y‘ว์์ฎฤ๕ฌสF’B"ิ5mษˆ�[์‘3cแึ;aูN&�ƒฦฅซ[qMชpฑs‹Š� v9“r(ใc? ค/H่Kd๐w๎GBึs[Š„; ๓t=Œา2t„๏�0ๆก‰ฯจ5.9วŸฦ\;๋BำDwแ>ป<9๓พ� �้฿�อD"Dฏ�U๚ิGภศข�U๚|jFเ�ฯ�ผ๘g�� ก(x™ุD‡v2#จ‚iƒ›uฬํNม"ภ…@าLP;๒I฿rฯAืศp_ ผ5qK๓๓+Wฎ’ู6รBึ‹บs3ข=ƒฎ&j…/]พkp฿{๗๊ƒ5™สฤšl]หTJcอŒŸ9;ฒ(�ๆ}ื 4ฅ๋VฆM–Rฐแ—กผA๗ภะp Fืฉ7ฒ.�zUฟ �4ัฒฏถ`rแ,6qฯไHU†ฑŒ‚ŒRc ้(มu=ตZนฏ;ทฎ†3gF๑/๘˜ ไร๐”:ํM๊D @5�บt็nธNถoš~้๋ห๓\ฃ� }ดฐ\ฦ�{?ไyฯ$@p๐ฬ9ฦWsคควŒ฿ๆฺ"ญๅ๐F่ ซศึ [๏%๙�‡Dอะูณ๘#� fkภแ�yxŒ<:Ej๖ฏ ้s?u๏แS<๋ำ“งj3ๅ<฿ ึ,–�หญSVสjG "�]l1ศ}š ุ;:zใ\oคjดgWภY@.๋š๔ ศU›ฌ“!^ง{รยไ,๗ฝ๎RŠkฦr…S€^๘‘I>๑whE‰ 3ณ�O=y?žส๕—ษเฎpณ&2�g’9ช lฑ˜p~Œอ�Yb OE๒„kC cฆ-"‚ŽYG!q =8d?x๛[a{e;€Hdhสผฆq| ๆ}]พ-ฝ๐บอdZฏoฆZ๓0ฅฮ–ตจˆ-Sศ—ืK30เ;i �\@หฯXภ< >มผ๒i�อ๘๑�ิุ‘๕@ฒฆ]ูK ฒ™zNธQ๓3วพJว9 eiเศyqO๙e›7ื?O`.ษ&ฒwmqgiั ภร{3ำ/ศi๏ฦี ปไŸ]+f๖‹H๗อ �!ฤrณ‘ฮw…ฑŽm,ูCeฦตm}บฅFša>{๔qุ }qใผ4 ฯ0–17„xH” /์ยัูัร}Rzฑmง2ลฬฅ%Ÿ”’ไจ�็ํP โZ\๋lXผึขด�–ซCvRฑ.�’‰*๗sเ;ํ๏ว\A\ h#ƒ ไa๘4˜E‡ˆ`Ibo€’ 3เงฅDŽN!„� ฅ/์ูธFX{”,ธ/ำฮฅi๊มแ๑๐า›ึ‘แลณiZv„ฃ$ญNw(ฑโLณ� K9–x4๊U]ผr3|แ‹?K็9Jึ1}5œปx…{ใผ„d:ม/c›Tybหณเˆ๙–<๒ผpถS–ิฎฤƒ•iฮร$U^Ÿg\lY€ิ,n@@phz่8ธ6สผ~๑€r*ฮป‹จำ๘ีvฉš]ณ&]ใ~3�€m|J˜o ภ๙๙ูภยC—/‡๎ฅqซฑแพ„k%อผห›๕๖์i็yž๏7o฿d/q†/†2ฟ฿แฺถืจํg�๓�Xjเ›๑%ั) œ1ปอ>ั‡BU�]˜> ฐ]ำ�นวฺ‘U9“p{ถป฿TขคุƒG์‡>7*หNฌ๋S‚ย2 ;”YณHโธDื\ใŒาP๕šc๋>‹ฅR�“็ gf< `UๅU0hŒfฆ.Xๆู/ืy‘1—ุRแ:Ž'\ณ�/�k‘ด”œำ P^^ๅœคHT@1)ๆฅณซฃ]๖+ะฯMฝj๔uฐcอๆ๚ทDi๏๗‰?ˆ๊‰Cๆ[มN ž?๎;‡XBล@ว๕๋{๙™เพ๖sQ/‹ ช†V๖��;|ฮ5AV๋ƒะั7โค๘.|sŒฯ฿!vถVยร๏ฟ๎๏ฯ!มฯ�๋ฅ_๚ท��w~ใ๔`Šจ�ง>๕๘,€'G�ซ>๕๘”Œrยส?๚๏�ปf็fฎัqเBฉฐSฆNfI๒ภ ต€ฤภร@ร`ฌ#๑#-ฅศ@p4๒ฎNd฿kz‡“รŠ�จญ7๚ัEฺ p ๊์T`@��Mop๎‡ผฯ{,‘น#(48ำy�,ค#ุ7ื๕WXAานF‡๋8s๕�Jฟ+BอdผฬขKnXnฐ6+งฤึl}”&D)?5ร๏—=ๆปพึ๎ ฐŒ๕”[ž8ห'ถf—B ูyูAKๆ8 t"๕ฌ’นขYSฑพ‘ ‚?@จ'ฃ&Qš+&$ ่cฝC?๔ ั`Šเrี๖q๘ŒNœฃ—๚-�๕RW~”ฆ„Fo+^‚๛ƒแยJ.ƒjAAYF�˜�แ๏…ืGJฐk$ปซ|ดot(œ ›ณ‹ิ3oGcGkUอพูjหเี ๐'�–›pš� *ฯm๏$ซ]ะ8ึภฦzp~'ฉฃโD‰|ภy๎โ%ส^„‡๏ฝKฟลีฐ”3f gถฐ๔๏f}3d[,ืB+ภo„๕K?๙ล่����฿ฯ~บ�ปษtฬ395ฒ�M€iE9n“YpmูƒFLั4�3Xถญๆk@ “ๅฺqญ฿ุขฌ‚Œq_�P˜ENป๔ƒ8หnศ๚iˆXุG•๋Niv–.’[ฦชT Xยa ฎ๙ง{แด•#๗็ˆ8\ฉ7ภาฬธคh๐ฅฬ๘”ฌr\ฃ,œ�ัภœ�อยUx๚>�…{$ำง๙›†e�‚ฝธ {Q�‘`ึณ36๗ะi‰ำvบฆๅeืŠmAw�ล{๓:�ภ@X&H0[?€โdื�ส{”+ฑ่œZฆฃู�Hภp ถงtฬ blฆ๐่มGัฌฑJฆvภlหถ,๕ฮ’Ov๖ทc J ™h3ฎ^ช �Œช5๙{ผ�.-7ฃฃ=ื$มธM)‰คฃๅอqวีsภ๒ฉ *Eฮฅ„[sชYจ$b<[ผวS5 ็ ใ`Ž+[peป>Aเsษ p-‰xํถท;ƒRgโาEˆณ�ธณMŒrn;l fว�ฯ!k+ม=ePei}˜ยณ$lพฦพ/!‰oไZv๑%ุ€,ุ�+“ๅฆคD9ป็ ;ร6ญถผ,p†‰ฦฃ“?{าrฃrM=ฑถ์”ผชโทฐWD๊ฮ8›แี0’FNbล5')ๅธงTฑ>4๛s�์๓๓"Yx จฅ&ž ฎ›Mฮบ]ฮ๗Dืุ™ะาAิ‡นฆ€~ieƒ๕ฦi8.@~H�˜ั๖\u/]พv%\นz5‚้jCพ๕ˆ๋Š{”๖ผvoว?#˜e�xฎ$™๗น†๚ฉ3(แ!ฑ• Œฉฐ{}ZปP^Aู…รณC%Z$ซ 5ฤtฮSฐDชำ"๐Eึ�น@%J’ณล9๐3A“Rป๖HBฐ{ใพ๓๏~yn๓รHXุ6S5žds�์O๏ีวZfไ~‘๔v?I†;ฟšับ6Uฺ]็šV&!ำJv^เ=ขฒˆ๗ุ็พ'ฦรYˆ๘uๆTT๗จข` Byq%ŽUu_žฯ๚YฎV@Y"™ชbค‘�”ๅ๓Zฅม1คˆไ…ชŽ4•@ะ๏ยึ—isฉฤŠฅdn\P/c›เฌ ”K๑นห`๑n�‚iu>Ž@8จฏƒ๚|สFเ�“�ํp}๑yหย์�—Œํ Zฬ hŠhะd$ธ=•ธ๔Ym`ํฯํ]!๘>"ฐ9.“U'หณNึ|{๙1 ืฬ‡Fk’JW+d[Vจ]]มqš€ษzseถz(๐N(ุ๖ส์จ$ภi&ลX›๗"hบ๓๊๋แ2=ข'._ยลž† hwk—J L ฐc†า Hภk๚•' !ธ30��ภฺ{z๖d*'��)+m‡ˆ8&cณ7ณฒุู45ฆ้eแึญปam~’@ี–b~Gปa์ย8qธาะ,Ž�ณกซซ?\ธv ๘xx๔มƒ0;?F/]]ร<ฎ–ไหs3ก›ฌพs•,_’`ถษ๙า๑อฅ9;ภ:TI{ฌ๙%ศ�`อOใ‹๐b†ฌ� Fp”S˜eรT๑ฬศpธˆ_"[�เ;๏Fภ @อ™‘g๔Ud่"ฏฺ@‰{ #1$QPƒ ‘ HI ิ๎oAˆ0ฎ–uŒ\ธณJhอี�ีIดsd�น�ิท7•ทKย๐b๑ภฤ90ท๔"ล๕๚š�yศ‡ o• ไ|Ž%—.ะEใส-Z{ฑ6ฬ๓?ฏ๋T‚kŸyq๎K“Aƒ�บPข๖จpญI@ฟYW Fœ็�ม‘X"P$ป้=m#K ำฤไ‹ะ[F!ธใe"ศ่�‚าฌพ GสฺoืLPmทA‘ญ1(ถ'ในM�{‚š’$'ฌ!อ,อhCpํdธ0�มžข๗•ญ่4บำ4ฮgูrP b๖QYผ_ชฬชjZ1 ฉฤH$๕x _Zขกtˆ?๏ม�y(�ว’#�b:� ฯ3Co‰G›ฬ๛D•c�‚…-อ๓Uypญl}A›@ฤvšฮƒm�๘!mR7ย‹'“ศ“gรณ>ซSณ๐b‚E^?ฯ[V’E๒฿ู�ล๘3ฮ^ง๓ฦ�ฬpป7Vf„ถi<นžJ Šyฦ8ห~P…แ๊ภ—แ๊ํ{แแGะZ“ืๆธvวใ น`แใrษaF๘๔L`’ xJ์T๘ฟโN�‹{ —+=V$ห\็eƒใc‘ภะˆฎ์k๑}Q™Aytษใ:ซ๑ธ ๗rย8ฏRๆ1รฺJไhษว��แŒะ็Eมบ@$ท9๏,-จบ�'D฿ตซคuฤn HK? ชŒs ฯœ PaCY~JI08vƒฐ“…ช ๗ฃเ�NถAtุ (รูงนคj"ษo•[�ฟ{Eขฬ็8fงeGžๅ#–8p]ชพN_ไสƒุA…k:„ฤˆพ5 tฑ8„DนŽท„Š˜ูนiศ:กุุม๐ฒbะ๓ํ€นณœGาภ๗;%„kั�ำ9ฒ$bยn ถ�๕30^3๗ๆ๙ฌoC#?;aฎ<ฝบุทvR5T: ๓Pkgb?ใskŸ๖ฃ[KผึFXมuฟXYyๅว�ฦ฿��ม?ๅ ชีG >๕8:qP_ ๕๘”ชƒ๐+๓หฉงO�4ช’XH' j‰ปb?{‰ _ ฉฑ”ฟํœŽ0ำdซ๗jeฝM<ฯl๐ะภ`tภnC๚\ ($‰มฐA^#5�ฑๅ ซB€b๐j–Sนgฒ‚่3\ฟ}๗๗d�kกp฿ ศS ชr€CณŒบvo Q,ค.ออล Yƒ6ู`บฑ••y"E.‚/A@ŠklFโ \>�๗ูŠ’g๋ม/‘ใ’E….‚นVฎk` 3ผ๑ๆ อka๘์D่็ต‹๔๕วพˆŠเ ฌ3Œœฟ@}?๏’ “ฯฆa�†$ภ�ฎอำˆ6—.ถๆ�ร’~#๙�ฝญ08v6|๙็�&คฤl,ูx๙‡ฟห7 _’ศพmรx๎u—ืW –3dD{0ปr้2 eภ=‹6ิ)9๎ำึš๎๖7ษฆาZ Sฆ>>–D�Lk ~Oฅ๗tใ d@‘เ��vฦ�็lฃ๖0ฯกpˆY8ˆคฯแ!’v>n�}รด๙~†Z…เW๐ฃjb{SfŸ๑ตvZืฬ<บJ(!q๗ท๛C+?ป๛า็ _ย๊์4คฝA77+hoฐ%Ywถ฿ำฟBะงDDƒฑTYสRr๔žืTOาH ‰’&ฆ ฏ ่กMž] �mk€]ƒๆส' RIIฟd x•yย๋zฯถ6๔บOธ%วงญ2{aถœTI‘4[ฯm™ื_‰s๋ผf|€กc+I†Džื๔็'9ีf€�[บัฌซˆฯ'รyŒY๙‘ ศ“ิฉ�Ž‚€™M[0บแผ^็„ฮ~˜ANQษ:เ�>๗S=รผ.ญB—ฆC[g/ H๋EN[gw‰Žงๆˆบน๏pO�ใรr8„<�ƒ,ฒฮ_? ;342!ƒบศF[^ัŒ3{Ž}ไ:<„X๔ฬpnŠ\๗ๅ9๖ณ7ซ/�ฅฅa�aๆS@ซฤปน๘™ไ�#หบŒซ|"$รฯZyžJวP์฿]+>Wr3ลšpอjด็ูฅYคdQ”‹๛<�gทž„ƒkBรศ.ญำf$แฑไƒ็ฒ`B ฑ sฯ,„๐ะ๑ๆ€GT -}”+ญAฑVQDyึ•่ฎโJDไ๕'‚FึXช… ฏ%ข้่>kข IฟJื!บบถC=;ๆงžw<�ด๔B฿ ิ�Kcา<๋อlทd P‘๛ูฅR=(y<๓Zyn๔ซp\ศฮ ,%Vห�wŽnชI$ นHๆ?~^คe- ใ;nนHป-๚XLz จ>’๐ุ…่ตdคw ึแ๊žk—ฎE…ะ�าbฌง/ํ้๐็ฺ4Œ]/-/Pถ๕"vคฃ 5t€ZกฤS–๏ูฎใื/p.๚w�2ZฏoนC“�fฮไfศŽ4Ÿ7%ข#ฝI\�ฟ>0ผL$า�ำ๛๒๓ฦz;Xถ#AฌBโเภญทม>Dš๋’AŒไ—๔g4t2_‚I‰€NH&UcLJœ[หŠ๔๐�T.๘งญNืQฮH>๘|ษ‰_฿}ขbหv‰�ๆ!�ป(/๑ณPBห1ณ Šgใko�ฅ'ต�ฝยYฒ‰ ฅค‘ฏณษ�Kเ๓†t๓,v ;OžQyภ’ด๊€ไฑไHฅžIฏตภธIา๙:ฑTล=ว๚๐sฝ“วท๓™๎็เ๎Sฏอ8+๘จvhศQVv,ห�ฒทฆง'๙œ[E้rPธ๓ฺ›�๋o�ฮ?ฅn�ซ>๕จภ้pRึฟ๊#PO�����ว[>|ป ษ้ํโัQฆŠD฿oo๛ขRชโSฉๆ๖ )c3Yคถถ| ๊4&k&coF้1xfœถcP‹ฤ'dd‘Zวl?@6ฉโฤฤ9๚‘”)•ฬ‘|ๅ๓ฏ‡›whฏ‡$ตY๛”ึi๎ˆYš ฐ™ /.ฬ\ี๑็nโร ศ„๐ตฌ!พ�๊KH๙ำaqi&ถiหSฏ~๋•ืย@้ฦ+/๑๗Wรw๏ฟp@fA~‚a฿ตWนN ghณG€J0ีี�ฎ^;.œื`oตภฦWฯMหศ†qฯHx/๊�฿�๚7ยณ็3ิ8“ํศๆศd^พk›yŒ†W^๋ึฺf˜z๒ภ้/ใิOพบดDึl<๔Œ †๏}๗mค๔s56ค™ฑคœƒภž‹eไม– ใฮ#O�ยŒkaf#7ฬ�๖ึ1ณั`Xฉ“w"x฿^ˆnŠ๛ิu\ฒF‘ใน1ๅuRfaIั5œ,ฑืรๆƒ�‚ ซJฅ๓€่Œ$ผว๘( ฿ฦ|ฐ`)ศ›ฉถ4คR%jข @Žใๅ:ฤlํ,า‰ฃ= AP�๏ษ–D:Uณ ํ€'ฮ๊˜Jžช\’แ^ง_ศบŽq ‚์8pศ:€œจŠแ็รฃธฬ฿ผษx/…ษN[˜ีXำสศ�ถ4s,HMฐž๖ z เํ& ภ{ปp �ํ//(%F„€ูn.–ŸCŠpญชโ}sUำ๗ŒW‚฿+กOณ—า๊�yๅะ)ึจzƒูxๆŽ"พ้ะ๘<‰ดc:N๘�š ›.ช;Z0ใt>ผษ;ž( |‚็˜•>vMmำ  ��A"ศrุ๔0ษา ^เำ‰๊ภ=พˆTh�—เ>.^ฟFฦว#๙ณ‚"dZ๔ำฒึ n๑eบ™wษ.ม๚Or๋xnl๎pๆtAlดqอ3!โF�Gูต๓ีR&zF๐b\!๛›๛ิฌ|์Tยš+3g€�„‰cbiL/]šOŠขฒGi|†๑ฮA^5ฅ๋ให<5‘�e)ฑฦQ๐๐ฺชkNP็Q ะฺดศ�:ฦfธ9lx<,่—วต่cเฌq=]žeฎฑยเ”™_หRt"Ir/๎EหY๖–gฯ�ๆะสœู”ษt‰G๐ฏRซภxฯB€rCr฿ต นม๙œฅ๔Iา๐eฮ�vŒ\๗ ๖6P(�ฝ6‰ฬุ‘k`�TPšลR"ฉ ้—p?๑~Mฌ K]’œƒฑ›uรƒqฝtr>ซ`ฐDฦ฿น>5ฅิPำฮ"{”ธ์ฐ๖Š%ึ+ ‰"๏oท—่ƒมhHp ภ2Fผ = ็(g„ืšHฑฦX �…�ฤ๊ๆ�ทํ"รZ’E=แ9๎yŸ๑)r6๙<J]vบษ@คIภป—ฃข„ฎ๚๋€ณSล›† ~ๆJt๕ ๗‡ื฿z3ŒŽ‡Eผ5Z0–=C™ˆ�‡บ�ปPž-GO [8j‚‰xๆV2มาฐ<‹๒อณ‚3ชw ŸืีOˆ�ศgeT‘p(ฐย x$mP!0ึ‡NVY?]˜Ž‡ฑซ/แKQวgQๅp“ณ ‚‚uฒ8=ลyˆbใ˜ ‰฿�‘Ÿ�ฅ๑ฟ๑฿r˜ีฟ๊#P๚œŽ@8จฏ„๚| Gีม๑Ÿ�ลW฿฿Z��xm}ใ‡ŽšหUJต ฬา˜ล'๚&่ฑ๗7ฎ�ิจw,ๆxŒeM�i†๋soผ‰ya7’�.i๋ก็=๖ใ =k%œ}€ไซ€“uฒVz˜1๊C]๐ฦ�H‚Pƒว ภalฦ มhGGw ๋๔R7[bF[`นบŽ<ท`ฺุ๙ูœ[wPษ˜8�zๅu��/†‚ฏ-^w`๋„๛฿{?<{๘ฅมฤ„I%ง€†๙™P�ฦฌ์๚ะ ศฺ�˜ร๔๏ไ๛[�}#<�เํ0๙๔Aุ„ Yข$ใัำ…๐เ๛‡นน%๊‘Sิn†ณw^ รdตiๅศฝD๔ฮ� Jru‘_x๑$|3Fj€Ž-2ช‹ด œ_œฯŸ=งw‘l$จ„๑ท6G–๙โ[มิN 8 ฝŒู่่น0;=Cํ>า^ฦ[๎Fภv3 €Adษด�ิ›bึN2ๆ!ƒQ&lVWpffฯ,พ% 2–ž4Az���G บฮ5q1›k ช+น@Sะ x�% __^ๅuจƒ% ฎ0Ÿึk2ธฉa–W@&จUbฬM๑ฉp๗๖p๛๚5Z฿a.นธpฺ�€)(Lู[]g๓่ณเ2Jท@ภ,ฆ’๛Fฒฝ0‚ะ" Wr �ฯkำ_เc��า๔t(:ํ AŽ™oภืุภZ–ฤะ์N๕ŠAฑหฺ๓ŒP^รฒ๋ต"‚ษ)ณˆ*qฬ&{]&๗A„r/c.ฉb ฮกะ‘เY›nVะ9Ixํ�g‚็๘แช,ฺŸKH˜…ท��ื0+์๛jะ(iาF9ŒYhณ*C”ๅk\ฺH฿๚l็ำ1c2โŸวศ๓ HAปใช’AR่˜ตาคื†e Iๆคจ?ผ�ฺห‘˜��ํ!‡^™›ุ9ฆ˜ ฒง”œGวx@ƒ™XฯมkรI6๔ะ2๕ฺํ+dร!ตุฟ S๑>5‚ิk ยห๒^รใc&wฏ ุ,_q�๔H๑�šP+ธฦ2(,:)+:{้j๘เ�ป์ๅุy๖ƒ_ร็ล{ๆlŠqฮ๏๕u‚`N€ๆcŒ‘Ÿิฯ@zcํิŒ•ๅมฃู{kม๛8ืQ?ฅXsvฌ๐k�ศ*ใŒ@)ณฟ็o�ธMหำศฤ€9sใx๓š๕Iไ่/QdŽ-ryH้;ยA$ก@ Q@…แœ �฿เlJฒ&ฃส#aาˆœŸ๙ท$ร5W˜kฮ'1กd>ษž๊@‚฿ฤ:Mขpธq๏e$๙ดRไพ78ฏ(ŸPีBdQŠร˜ุนBฒK…K์๔เ๚uิ™ร*๏ฝK๛[K๛งถ˜ี 2*’ธƒc อpวะ^aou-ฌอL‡ีฯQŸ์ะžr๒ฅ:ฝH“ฌฯ%ไ†~ฤ”Wผ๚าห/9TbณฑtE2ฮr=ฬœkŠx จ–<๒ฬฒไล’•&๎?%iว\dy>ทเ1ยุ „‚เ๓>๗8W8;,‘”๐T าซAฒฯูbฅHฉl‰ %I”Vี˜ษJ‰‚จJเ๕๔ฐ‘`u|c้{ฦ๋ifฌUปEโ๏„ฮ�Xว็ั้�ำ1ƒ็“ไ@4†ไถ4ซฦ๕xฦธ๏ž-ฎc๗{$XˆฎKrDK|v.J–ฑพ F(ระ”ิฑฺƒt๖๘#ฺC๐™‚RศŽžษฌ-0�ƒU็ี1rŸซขXcฮผ&ืS$P่โzาฏGo!??ธ]>›๙ฌEลR- ์ ›‹ณa๚๑‡an๊i˜งL้oผ�๙ึŸ๓Yตป�ึ~๖?ป7ว›ืฟ๊#P๚�ป๐DชีG >ŸยH$บ๖'�เมฟ�Kฅโ/ไhiV%ุ:!ภUlฆ‰šY๏6Lณ7CศไK›˜�YŒฺพฯท๏�ŠศF‚พ๔+ด$ิŒyื6™ล๛฿}‡` ๅภ์45�ปแโี›d‡ tC เเh๘๘มœฦ—c๋ลษ๓Sฐม๛6"ู๋‰=บํพ`;ธ ฟ‚ญ]€ใ "M๑S/ž…G๓ j}‡&ฮ†{ฏฟR~๐ม‡๗ร๙ จ h๏}๗�J<ต฿ฒาทยฺ ~๛ฃ๏ำ R Lฦชe๖M?$x^ZZำผn ุีฯ9t…๏�09E{,ไฝ…†Bุ;ž �็iˆส`aeเ #Xอ"ญ��Xมๅ| ๖‰ฐ 1ห•o๊$e fkแdม:rmอ็Zจ%Fwfƒj•pํ๎�ฐฒEอ4แm~D`œล<ญ๙iW5๗•m@ญ๒zจKํŠ2๚อ…Y‚หU‚r@/ื�Fตsล3ใgc„$๊ˆ ๊‹ s๘ +ม}o.ฬ��ข-z่Œ/kแฝฌห5่ญ$ฬ6“Xโ�ฌ6›UKY~ข์˜“ 4›u dึxL๕ึB๖[วญ“�ู ็BoGkธ�๕?"XG ˆ8Dญ’C]!€&B๓o�ค้"ใ‘xฝ๒๊็�Qx๏ฝ๛\�)@>ญร$y4hFท”K“]D๖œ<�C~N6ž<ฒสฝ’)Z&Fฦœ 5"๔šญ?–(p=5i๊ศ๐ฺ-1๐[u ท ทวฏ4€ท"]yด*”กžNึvx2สจฤ]mak 2viๆฝ๕[5� )ะภ}๛šณY.dๆผฦž:ขผฤšašI= kšjhๅ=น ๖ูjื‘cัˆœ๗ขื%๐ึฅ_Yดื ^Tg &Iqอัผ ำฅไภq ๘้้๋XดŽย‡๏ฃฬแต ์ 3fม›ถ€ณ^]‰ดใUƒ่ฒ๕dฅ@Cร�แ้ใขW(\7EสR$4†ฦ.Pz@้ต์'ญ”Iจ r�3ผ–๗-ุ๕L1;k๙มch) •฿�œ,-ใ/iใ฿%p�สSVขทŠ ์4ฃKึ \ใ “, Vi7ชq4ฤ+นG9็สd ูkนึ&น�pผ6`eฝใKb้IอŠ1“หนH"ทsF�ฺ๒<๕๚�Œ�s\#๋ ๐R"๎žr~๒”oX*ย›0ฎฌaU บ@ฒ�ฟ์ฝipฅ้yž๗žเเ`฿๗}i ฝwOฯฦ™ก†คษุ’ู๒’ุ‘ขJไคโ�ฐ+ฉค๒รU๑�ศRQEI•ใHqbEŠT1cY %QRฮ3===K๏n}฿—ƒเ ื๕‚t)ต”�…< {บœๅ๛�ํ<๗��ฯ�dก`”บฮฑฆŠย�nโา‚#�lf8{Ž%Nธ_ฦ;ถeFฒ b‚7b๎ ณธฏ kไ„’™ �๓ฯ฿k“a๒๖!]ฤูภุHŒIฎX2ฤj#ใ๎XŸ๚Hžqc{G…š �Bก†ต๊๏๗พ‡Dž*ถ<5"*๋ŽY;v‚h๊์=Cœฎ฿Dxฦ�re”\ญฦ9:Lส๒๙Sล��BมbYั.e"ลๅดยค�&ว™%™#yk�PUX~Žg๖9#%12‰>8[ู|ึ%นง"ึยfษžLฦ๎,=C—B๛ลื๙l›€ฐxฬ8ฒู?กฆน้—ฏฝ๚ยS๗`แซ0…(Œภq๐GGฃ๐๏ย�เภ�`๏�051u‘4ฤ9’T‰hต0™ฅKฬ+หฌ.oŠฃYฝดตโ(็ถ�ช&Hฌ<ิ’อx๖t”@ใภฅ:œฟt-tt๕ฤถkQ๕�าธชฃซ—Z฿�p๋ฝ›ฑไuTDiแƒw฿ށ >�่VฬฦYƒ!๘า”kไยฅะูีฦŸ= ๛id�ิW—64Qb@ซ6ˆ [.ฮำ.L9้ /ผฬc{ร Aื&พฦ”&sธน$šฺšCภ;{D๐Ÿ%๛7;Šษ*EY*ูๆญ=%Bถšฺ"^z…nœ๚ฮY@? ไิe๔บ๎์k'Cณฯ�~ษpŸq๘์ตB2”NFฮ_ 3OŸ:ยU€ ฦ•1De d%RJ๙นชี'ค I•ฯะb๙ฮวเƒบํ!j8sO>@๒<๛ไcสธ…งภำปwย๚�$�่k‘t7D0S@ฬ‘�็พ/_{.ฬ>ก…��\ ’นˆ„เ*=ท๎ 5 \>+ `ถV(ํaไ๘ฬ2.ฅีดนe-&�ชK,o’eP)ื=g\ผ?ฦดยI5\Ÿ‡kจB2ผ_1{ษตสQ#ษ�) ‡œ}็/›ำ““oGaP๙t๔ู้ฯถX๊ฐH†JsDตุnCup้๚ฐˆ็ย2`ฉsร—>�๙0|ในะD๊V๊�;z๚Hจ”Œๆ‘รk๐๖ัGD™rฝ†ed_[ศ๊ผ๐๊+tTภเo๒1’๖‚2ฅฅษEใ0 FJcษย��๏†ปท�ฅ๔7๚jฺ:’ีาัผœ �ฎญํ�H}ปc๐พEF๒้{ูJ�ี๗่ก,�1ฐvx{s™ Žr ฒ\fKฃ�XฤxjิฤŽHอ๋lมณฌ,ภz^kkq €C{Cภฏ%๚?ฬjjk›Nƒ]HKIr€R๓พ๏&5๋:ธ7ตw—’U�โ‘ง2JŠcK2€“™๏ๆฮnภ^3ฏ;ฦ8 แ9ใh๏?AcSx0�(4ัqแ,ฤะ�<&hSdkyˆz๒า�™|}ณ�Eดฒ+Aฮ4†ถฆV@€+็ฏ0›1xœไ๕‰f บอ4kศจหพเฤ>j92ฑฏCV—g ฬ‚๋ทก$^ะณ�ๅถ%m/Y“‚�"ม „•cฏ#๗M ๊�;lžฤqQhฆt็๒sื ฬhฏ‚จ3ซn�Rื�\€ ศR"ฝ‹1งฅ.ถ\+ซฉ`EใEมัฺ rjภL�ิฺฤc|›แ๑ƒั0;?C ฺปฑsiิzุ&๏ะตลธํCไต๕ด„็^พN๋ฝsั ๏๗~๋kแฐิา‚g ท ะmฉ„dŠcุ่zฏ”�hส้W1฿ซPฦ]รใญ๙Ž€Pปษุ˜$ญ‚Tqm:�NโARว9“ศ๔9ึึ+{ทž�{๓h66ห9vศ๕บ>ๅBv๗ฆ์บฦzฦ -ส— ฦค‘ฝ๚™ฯ~!\{�:ฅ=อd‹+C฿ะ™ะ?<ฬุขpz�R%ฮ}Z  6i-ฉ9_9Dˆ๕โฮณำ Kำ”สฬp>Tัšฒง๚š๐ฺซ7BgK-ฤ�}ึsศฝ่ฯฐฯุTา�ขนg Lณฏw!เQAม๏S์eห*9gXั6ฎnฤฎ'f‹%Œ˜ซส0ŠQ�˜ี6�ผพดภVค”ƒ?aฟl ห@Nณ๎๗โZ# M‹ฤฝสy ]Ž!#Ž9฿™ษ˜๛NฅeBฅdฤU%9† ฏQ*�ปรLR๛ฯ_ 3๓ a}nขO™ผ&„‡ิื7„—_ycอLุ +ฬ��t-ๅใ,`ฏฉxชยธตŠๆ‡๚ฝๆ)ž'ฉˆdO<_›”@}�“K)„ถ๒ี฿ghไ<๗PAi�\x†ฏNsS3ŸณตQฉฐ@iš�a๔0๕sV%‹†œลŒ‡ฤ›ฅ|•ฌ9M%�\งป|e™๗}H™mHหตฒ�ฝ กLr๊„9“ภฎๆœฐ˜€|๚๚๏�^x๓ซo…g ”ฅLณึŽว�Ÿ�™�ธgไต‰ธy �)Œ@a #๐วF @�ฑ)|[ด๘๒oœ|ใ;ฟ1๓๎ท฿ฃt}ๅ2ํช ’ 4sว๛Q�h”' �  (#ศ้่ƒCCQ^ipบM`ต๘žจ=#ฤฅGteA2fgd=Aw‘E1@ำPฉตๅfjšฐlอN�’๏€@ซ6ิ๛3dึ{”˜ลู‡„ะี�,ฯฃ'ยฝงร๓Ÿ๙\ธŠ ตu๔ฅิDšอ™ดX"ๅโษฤ?๎฿G"ปŠฬฟ>‚ž๊ฦ๊0xv !2c9^{wi8* ม‘Aฑาzƒ:ฟt“฿ .ปธFถ๙„L]ช ณวณgษ` @ 7ษ|mฎฬ`ศต 'ธ%ภณ}แ1 มlŸnึ;f+‘+—ฆ19ใ>m‰g–Dศ่Œ‘E†ฺG6_รฟT;d|ˆั`์S™ฐหWฎโ”พฉฺ^š$bดล�—’!$ข…เฤฺ]=™ @x9ูฯˆž]๎ว,iMC:\�๔‹1รฝ2?N[=ฒcd}Kp’฿�Z&จ˜า 8m“&˜œ˜šภฤฑ4ด ž|5แAVŠ1W:ฌ‹�sฆj"‰^  i๑y่จซ Ÿ๙ิงB=ูลUฎYดขฑ๑‡จZ ž4(ดไACBล ถู[ขๆw)๎๒สZX๔™๏Wๆ~Hฆ”)‘ก%ƒ|Dฌณ~€ฃ‘d�ภ`จๅ๚า€ %ู'๓4!ั/eฎsศข๓�WŽืX*iืหะ’ฅาftำฬกํ๏ศ+ฦฬ^เ =1IŸN@Vไi•ๅ)ศ‡"2สUำึcIy„ษ(& Hศ@ โฐEโB3Jkช‘l3�>วŒhžฬyqŠ>๊ผ^ต€-ํศ i‘Dฅูฃ�€๋Cฅมsฌฏcว1‘๐)2ำl6น�๗–ฐzoษ๋’์๋๖2€›Œrโ ‰"ฃ”ฬพc<๖l"<›_fญb๊ษ๛I ถผฎ (พˆตญ,]กฑฉ*œŠห์า|๘ึ~;ิpV๔๖uFสcู‚jƒRˆ ๙$ฑvถื"‚ฅใัป $*หm�j$Ž๔ฑP8ฐF�}1ํ%ํภเนa&WPhฉฤ1{Qc;h†}ห}‹)ๆB๐tฬk�Y‚มรt็ฒQต๘คT�0ฆe*\xฏ2ฦ๑�๙K`ฺงบ‹|–t๕ „3Ÿcาi„5a [ห.ำ.U…ั฿��“‡�H@IDATp๕•ฯ†้๛†ูงX๙'‘ˆ้ฆlHŠื_{1\8wพ �jšฺ#HƒU ๕กc๘eO!<›ราŒ่ส‰๊*$#ทว4ปฃ0(ๅ๕,~5SbAว๎'ล5(I฿CTf�!yƒึ่1ๅ,vIฐ?T8i€[Za"้๖�วฅส ”หร# 9ซ๋์3ุIŽhภh๋˜ส™ศEว๓Xาฃถฟ74ข&+ฐ;ฟ�‹ดhLb7‘อณืŽช’(…Zร>เtƒ๖}ึำSv“ูCม•ฺEDฟ8ฟŸe\อ๒s†qnK*1ื ๆo’cด ]สqgฏฟ Q�ห<อ‡*:X^Wฦ๚—p”0‰ฅ"2l\ณๆ…๚9d ,ˆ๘บถ…๕<8Aฦมัv ถ๘SัPฏM’k3๒˜ณO…‡gyTqKPqD๑ฑG —ei’โๅŒCฑคใ|‰Ioˆ*v–เ0|N&ำˆ๗Œๆ฿r%%#ฯ_B!D็Ÿ‡wย์ Ÿ#์ลZฬlŸM‡ฑ;๗B~ฯsหฒ)ฯ"ษˆiษCHwUv)ิw๚ศx~Zยกzไ๘Ÿˆ้จภเ ั�ภs-ปƒŸ ํ8Gฎ”q๖sƒ5‘UIี50ภ&JQ�๗,ถๅุc–ถึ^๛�๋�Yiใฟ๗ฮ/�โฌฐยWa #P?9s…ฏยFเ|�xใKน›ท?๙๘ม'7?^Z\ผJ mณmฺฒpizƒ๐]‚-ณ6j;-ดษŸ[ข%ู�––70uสั6ญB€Œ‹ ทŠ ช…‚ญฒ{H‹M•d๓”ด�!มvnš!Fi.`(บ� ฒร1{จ“?I‚�"ดชล�ป– c๏เ`hhoกMใFx6>4˜–f7oพž=yJ‹ฟi‚ศe<@Q)RX‚9ีๅิฝ๋ฤ��;o‡;”Ilอฮ„ l�ล�ิ˜แขG6&Q‰ค™6ภ `H3ฉ dภEEศ�ถYkk1C๖๔แGศ1K$ศm๋ฌVQว�ฮ]Fzฺ�ƒ”wš–@• N๐�น๖หš๓๎พ0rๅ2ไ=ๅษ๎อcrึ?p†ฌ5๏ะฉเ๕”ะวพ๏ตถf›งอู� tฦ--•5JRนO๊ใ–fป๛†ใฝ์�ูXB L๐uบ0ˆgwืp๋nฦIป&ช1ถ๐หสขผ~ccณ0ฒАฑๅ! �Hั ฉญ๎ฎ^{ษ๊ๅ(ษž}ยRSฯ5n๓w`'ๅrL@ฌzEi7™ชpยุฬ@๘L…-2ท›˜ซญฏ’ฅŸ_ฃ™ฮศ~3ณ™ฝT*๔ <๏๑�&`่,ฮ่๛ึ้:ิV fฐ ˆd”€�l™ืธŽL|ฅส: ฌi฿๓�7o…[฿~’Œ9Y—VJdษฤ™�?ๆu2๖Ÿwอ*ƒ7C(yๅฝ0@–คƒ๏yกu@฿๕v‚ฤ‘ๅ!–SฬฮN‡l‰Uๅ\ kD๙ฝ.๖Cgฯ‘๙ง ฒtศูKQˆ4Pทผฬข๘๓?Aq €ทธชจPฑวR€+k๗-ฅš?ฦ๖šIอ"%ฅ4–ํฤ๗,Ž™c�›ฝ%‘ T�์ถๅ ๚o”AขTื5๚๓(~๐ ๅรำGOย8๛e๔ูTx๐h4ฮซ{๏˜๚nต ืว|Z�'‚ฅS๓>ฒแฌใ] ฃแW๒$ด5@ˆUP Myล>๗๏= ,cหHฦok ŸฦYƒธeแผ ๊]ๅ]ณ’–‚๋๔ํU฿sๆ\่้ ำฃ#๘’ Šๆž�ƒ�ฮ!w ฒแoๆM)ูศŠ Y^WใN™๋  ๒ํ ]4ช9‹$12yj๊yL kถ”๑ึ{bีศ*คI๛ศๅฐ„Aj3๛ืบ��๛Fผ—c]@งบกŒ{{�‹#ด\ ]xtฑgฯž/=>�c=–d�๚ร฿E0 ๙WU kฌอo[G,qJ0gฅ5a‡ณs~‰ฝ@fุซื�LQแฯUซฅ8Wv!ะโz็�vถ$9ุหถอUูอ๙�๛ๅฅX—zP<^ี†$น%e๎'U!�}˜™šภฐด�ญ๘s�็�ั‘ฐlแซ0…(Œภ๗q๐}‡ฅ๐รย�เe วoฟ{{rialszjโ‹F๏ฤ–˜+‘5@’% �&;๓ไษ8FIบฃ๋’ 8 #Ÿขfุภำบ๐:‚บ�พพN53ฐตœแ่ะ็(น$ธE’๚C[ณ์ึึ5 4๒|๛O[-�ฒ% m็ �:ั „VVV�oGUมญ?|›๖~แ,ฃ…�.&zG<'i†Œ่0Gmtเบ•–W็ฯ„'โ�ถำHc โ”ส#้ฅU�žzœ์ฃวl™8`+@1ฯฝ5ะ๓บ/œ:._ฟ>�๖›ัO๙4ใ``)Qฑ†${q–rudฤEƒู#ภ@)บฉ๛ฬY‚๚ :5|pฉฑี60ภ `่)~‚�ƒห2ภc†,์ฬฤj €>นHƒ2ฒัฉาเ"F™ฝฮใfมfฦGcหLโี(�ญ.��ํtรx-\€ฌ˜x&ษ,ฅหจgHx฿ลgŒ' ์%tสP9ิPขฐฯkW๒๏^~ Y๛jx๋อ฿ฮ๐%”d ’wวj�]Lึ�เุž๎อHื59�"‹fูฤ .์�›๘8ฬฮ6ฮBฦ‘๎?ฤศ์‚@ีGท ‘’e^‹KซX‡w‚gA‹มl'\cl3Fo๖๚€ŒšภฆŠkT œ~Š2ŠEˆปt่“! 8dm0๗Jณ๕GŒ๏ืj$m&›่0BvW@๔]Yผฤ‚ญ๑๔ดุ�Zยบ‚™€๘ ^ข+ hฐ๏ผCœซ%@ข2|{ท ผrจ1๐Ÿ mอM!c€avLFT๕‡ๆ…‚ณศ 2ม„Œ€=ๅ]5*7tืฯQg,!็o!๑\sึฃ ฦ“Œ8!lฺ%5#ป•0xd๙kทฅซ7๎ญ5H5๛ะgIํ๏1ว‹xŒฯ/…m@—๛LYท๗๖ฝ/๏�ืrL๊พฟk๓’mึq‘๒gถ)‡มฟกชŠqฬจ8ชfฏD๏ ภ”gˆ$S๒ะvŽฆ`อม<ฦ‘ส๊ญ๋5ณฌ9—N๒1+นขOƒDฦ~;น‡Oาขr#fศช5a;โ~:ถฯK’�ชBYrํ๙kjajy9ิ#M^ž™ฃ Žธ๏ื' ##[œBู€มNMmMศ๖PีZ‡๚e)1 ”5Wอ8”ำป> ๐ŠC[gw่๎๏™พ€`{{3+๏8�๛n#ŒkฤJ4=ฤ:nึหไ‘ภG’ฤV0ชLœC‰…<ค“-ีT)˜-ถฆ†k>NาJ ยำNื0๗ใZ>vา�:{"9'ศฐDc๕ทล๔Dq?ฺŠีN x"rŸnึT�โ�#ฌ๊!ศณS”ฦไUัณ{J’๚{:›VฎA’ฯใฬิoa^๚ฝrหw˜ลฌ๕Hิ้ญ!�วฑฐeฉฆ“ 3๎Gข’๎หuXP”;ํค pโœโฑ–วKฎแ/qdึ—๗u=JsH@nฒ‡ฬkN(y`{ฤ ฎกเZ/)ว’Bqาิ�ณูkk‹a๖ู}“ Ÿ��OFะ{ฐV\bssu5‡พ†yฯฎ/‡ษ‡ย�7‘wO‘ัN†)ˆ…ว> ’%fnฒฬ›ฤ5<�D๕๕�A#ื_แ<<ฉ็VTฬธๅ5ฆ�•4ƒฬซgฎ4ธฃŒŒ๏1—…ˆบ|ํ%Wร”8Qcฯk>ฝ๗ ฮ๗งYe ณฮ ษXฯA_ฯ}c๛BK=”�K๎ž๐ป4ํž1 ะzบฬ๖œ�‘PP`kั๖'่šssG[ฯ. …2๖ŠฟS6Q๚z{นฮฺฐ81 )F้T๔3ฝก•9]ฅTae˜ๅฎkมถช‘}ฮ๕๙้ธ–Tdh*jฝ๋&แตs_�ฌ“๖�ณtร8ซbg†bง‰ฑqสค&๎฿‰~2๕ต;s<๏ิX๒ˆ5อ…FR`cyžฒ†U๖%=xj”ืณึYฬปฤkร�ฒซส�SW฿‰:�%ธ\ึฌดๅฌQพ‰ไว>dทŸ…ฅœตއซ�๛ฒคLRหN๎–ุfฒGo Xzย=ฬฆd๗+ชุpป‹ล7อ”_d0ž{Ugž•ฝ๘mT@„IผH�3^Jผ_์C>/h�ˆGGž๑]Yaฝ3 žnB ฟ\�ั�เฅK,‘๒5ูเ ๚9U‘0แgฅmี5ๅญ|ถ”�ๆoฟ๙ “ ๑… �)Œ@a #๐วF€ำฆ๐Uย�0ภO�ออNN>)IงRต›+M'ฎ kท‰ช ช*ศย@*Xœส-+>สg�รฤ2๑อ˜b�—.Ÿ'W)โDุ\_�==แs?�ืB฿เY2i�aqa&‚c�Z‹ญ„บ‰ฬ•€D/„ ณบศ=ขฬ๐ �U H(a์ค�๔๗2FE{kป.L็โฺ:�ฃ๔ผŠkต›B AํูวŽก$ผHเทฉ“'#”%ำJ|3L"ี๔อ>sแjผืbโ,3’]d œศ Oฆร๐ๅ+�3-ใฆŸQืZฦ๎฿…Xฉ ec_๔-จมุjuer ณฦ3ั7` Yท�ฃผค‚ €8Xœ›็Zˆ๚gภม�1`‹ึu%€ ฟeŒฝ>fบ๖;ณ_:ฉืPk!Zr[€Mฃ=๎ต‚๎ สบ[:{cfษvb~OภPลdฐ�ส/�/ds๓แ�‹Ÿ€z ็ˆy๕MํO๛นhklนNFฬƒ่•ตฅะF๕ๅW#นฐ00ด>@่่๎^J&ž$๔ž้ ฏ^1ย o�3๓DนY๊ฉ้&Aญฎ5ต‚ษCฺ@ ˆอzZ|L<�ํไiy‘P]„โ"O&ฺ92“Mไ ฑห}!หg<ฬคqแวXา}ขฆซต S7L๎˜ ห‚vษฐoฎU eษ ซ8ๆฺ5“”�PE QU_฿ฬ:j@‚X๎}�!{A#น3#็Y#zƒbน•Žฯ!๋EะuโฝRR%ชฮq]’LYฮ‡ฏญ๛| g‚%?[์๕bึRm=ญ'!ส๕ เ1e,ˆบj”p“ ฺfcyฤXLŽ=ฦY~๕J‚ฐ#z62ถ�|3๐v9ไ๕Pj<น�ˆ6–ทุ๗(ก XวGa:ึ้Lโูภจ‘๑u฿sึัทek ฿Iฮว†๖>€>ฆw$žฏS3ำธูฏs.ฺฦดœ2…าHœTเ’ฌษ5ฦ4ว�์Lฦฝรพ\กฬไฅ’๏a๙อg{4ŠSจ๊Kฝซžuภ~b้_b”2H>=Pb�=s[LชLเนY•ชfี5�,ผั˜๏ �:g๎4%Pป;vทHC .DeาญXฏ\ฝภ~=@YC—สr๒~Eี‹หณ๙„๋�฿ยโษR‘ฮืV%„Cืู €{:F0~}gฯ“w^๘,h†8ล|๗๖GakrฒvŽ๕ฤ™ม๋๒{ห,#P9plน๋IŸส2<Ž๑:ฐTแต+!‘f�อสg8ปœ฿bH:�ู๊!ฃ2ฬ’U š•ฺ.ำ”,๐Vฉไ๐ึqฝžฎ3๗ฐkิ}`ทC~ฆํกRRษอ QyจŽิ๋ฟ:PiRW†GFk˜c_๎บฮ๔’_ชhX$๑1ฑ]$ใท๑ปวนฟ›U�ฤ^โ�nแณ๏ˆM<ฑธยzลˆ’rฏผพg&*ษ<.Z5™7sa์พtMk๚่นแบเEน•=ฉ0ะื{าะะ๔๘๒ต—พq sQ๘*Œ@a #๐'F @�‰!)� 0?ุ#๐ซ��+ปฟ๓ีg๏ ิ�๖ฤณGฒj7S›ี4ิ†‹t=ชคภ['`จบ2ปšรฅ แ'�ฮO‡ ฯi-Nำิ{7#ฅ๒่CภA}่ค๓ม๕๕cO๎„Zฎฦืฌ#C’Jำหœ`gia…ฬุ“,ง/2ดฐ‚๎ujŽํR`6˜˜9S&ปC�ฒาๆ‚"ƒ*3€ชjษ4+w/Cฺ+hํ๋ —^ธ  ซ•HZำฮู๋"2Bfwญ—&�LPl>vโดžŽบ๐c?๙ืร+Ÿ๛™ฝ> ใก˜ˆฏฮM„‡wo่ljjVŠื@3H H }Mฒmซซk˜ ’%{”hํ�๎PฯlCฤ<มไ.ดิ%€{kป‰žy.2RTO�bšY์"ห�ิา8ฆiูo๚ฝmz|ิZ7}ฐทEถjƒ! ฬ5๕_ไบ0š#pทพue azcSw๘ไฃ›ดฆL†ตตmˆšฅ(—ทบภK๐{Hเฝƒฌin.—eŒ0ต�รa๘๚s$45ีซ ‹ฦVX™[$MJ ษ{ํjฌฃฏ"ร�ŒŒปณป#<�๐ฃ0~๓}ฒƒ(ว›`6s๎ํขภ`]ภc (5�R9!’ล#A0oถ/I/‹๚C�…๗GTฮใ(‹@ู’’๎๎ญฃd ใฬuj๐ทE๖Sฉํ6�d@ืx~สอิ”ห�๙ย6Žบฦ ซฌa)@เ(1ึไ’ฬ6j“J{Qx ๖s�9�=ฦงG™ฃSSฒ „A'ฟk่ฅ&ฟŸuPลำฦŽkทV�ฬูแPI๙Ni้๎D1ัภxpฦ_˜xภ>@!ั�3~วศศ)v‰@าu% ฐิม�gr ๛มึqฎ tดฐC1ภพ2ฃ^TTโ•†ว์งlgŽ W (m๋๋งรร xแึ†'OOืCฑฟg�๔ฐc1สƒ2ฒ–'ˆ"^ห๑,Iบ€่cษJฑ \�U฿ด@HtขฎPจa7Kฆุ., ^O b—Aส�ฎฆs€-A(?จคw ํƒCจ}ศ ๓ฟbภฒ“ฐมTล˜ี7สธ็�มมHi2št ŸcํSฺcง €๙ฦฃGŒ‹%FY=(x?ฏ9zด@Bf87์“*€`=คT๊(šoาก$‰:†v”„[[ซaาruJgO?e6ฌํษจŒฒคฅถฉ#‚ใขขŠSย‚sDSื2ท‚E‰หYTKd(Pนณฐณ)WIฬ"ฮ„cฌ™hUU#jญNๆƒGฎo‘Rฉu•]์๏ธnทธWœ…iึธ�lJ!z,o9ไฉƒœ\x:Žงหd๛ฐv๑�๑ŒรPBฬ๛ทผDนพ ]‚ช ฯU1‹ฝ*Pฤส[œgLภบถ๖๐ci‚Dฮฑฟ5_ิ|ฐฃo€ฯสZุk๚h‚™‡นิ; ษ๙ช๊ก$๏}ย9ฎš.ม�ะ1ษzCtEฉ‚ฆซดๅฌซ ญƒ}!นyจ{ฏ‚็ซ0ฐ์อ2;วี๗อpฆg(�หผๅชฒ์"ั ็ๆsJุร‚rป๖Xฆ 1c -p?๕ฺ„^๖ใยฬbaฎ% Tพจ$R&-ห&{ํ|*๙^]š#+efศด"ถG€�๖ส:sxฤฺ9ํ:J%๖*ฅ็_xY�~˜ši2ษ๖กื€Tขภา“X๊ม�บฆ[ษีถ๚ณผๅ8‡๔E'คง”ฅ[˜๙ๅน>PฏฝG/lฒ‡ŠŽeฬgŠ{ูYƒจ๘๎^xปW] พพ`yชnรปฺ,‘4+ฎฯร!ฤ‹ฅ#๛+๚@�4ค#๏Km๙ ›าๆ8�gSชœื s”‚๔†_|9tำฅf Po�ึN˜~๚(%ผž ฯ,ป(,ใเ๘�ิล฿qทๅžsฉ์]Rึฎหดเคตa3ไ‰w{}‰฿Ajr†Zำๅ๘ฐ5โ;@”S ฤ�๙^  ]ใ?ฮ&ูž#๙ี�ืรŸ^Z๙=#๓ ฐๆqจWษ_�}-q‘4ปึ%?NฦจHP  aฉL„xถ?แ3ไ๓ฺ3gึชœเซโ๎‘m>WxHเไฬ๖s~ศuAง„tmc4u�๘3ห54 T�b�Y^ฐ `GŠ+ฯ?ฯ ล2•ฅ…™Pฑ่|๒šชx๔‡`๕uvY3Žs^ฅค�ฮAฉิะ t‡%I…ำ3๘"@Tจ hEกsมคf—ฯF_ฯ2ปญ๕]>๖8g ๙™~+ผg%-=,‘ั 5–}๐ž$ถd<7r1tuu†Fศ#ึ๑ิ;~NzŽบสOK๔vp‰Z ”โ3�‹ `�S๔wAกโด๔๖ผ๐สงณฒถ๎หƒฝƒ pแซ0…(Œภ๗N™ยWa #๐ร:oผ๑s‡ฟ๒๋w๏ํฌ��šžฝRMใ๗v๊๚๛ษจ ถึ‘ฬช6hกลแห/= …น๑ปa๒้�(Q^[˜% ]—ฎ�๕ซชO� WpๅืleY+มม�ุ๊๏�#@ข๎™@[Ih Nเ๓3sV™ฦอY ๋ร�G้ dธึ้l`฿i]�ญแ�ฤภ™xU"ฯ>!Xฯ“+%3š Xฟ๙ต฿ ›SSกžภ๋ส๕๋DIจVWb3ื๖$O›จU1ฑ07๎ฟ�u€%๕๒mฝแฅฯ�ี Cz 2฿Kฏ�ก†’Š๛€์mิ)ฎ%I€nœt›น>Q}@Pl–ž‘`�บm3รธํ+ษN$k ฅฌี ัฌ–@|z๚๚ใ�mSย`ืn4‚ิRฦสฑ1\˜ž‚  ต›ั™/ฟ7๋Qี1ฑฐฤ๘‚kBi5ญ/ fณmจSwKW_h๎์ŒR�1:!T์ช๋Z?dๅธV%ร�oฏ{๏“{\�'CFpส}้[pศล”์Z?œFฮพGkฯ�ู%ผ0€„€ ม‚เฤส‰๓Œ…f’ฦถ5ซfn�. ˜0ณn,&)V&MO`๊—5๙วdJ[ –ฮ_D=ฑ ๐ขž๒ฤvŸฤ๒1ำห ‡:n{{GlืนGW๎–uอf�xM–สhบgVNPตตฝABv›,žต๑ต”%ฺภM<ูล.ฦชŒ๋ญคใ† sณห฿ YๆงwเLฬำsณแ�ท�ร ‘้Yftw‘ณณฬhท6อ•;๖ํ2งว\“ffJอคงRe;lP็ฮ‚ศ1Žฟ„e 9€ๅ€๙˜Vz.1#ู$เะ0าvฅIฦ ’=UOY@cG�ฅe•cOŸ<้ต•จR฿‹้‰ํ URจฦจ€0{Ž@$ึK+ืNA|”K$๐ณZL+gพืฅมกkqว๖€\ƒ๎๙ข+ณำ‡€ฟ๕ีฅ˜=-ๅ%m�}เท_วึlm+cบI๗>cะNหฟพA๊ป1LB�]ผ~-fQŸ�กฆŸ� ��G7^{Œ,gHD๗ฮ๗L3Uตx.(#฿X�ผ—k0‚TภRืQN+ป$ใง€{ ฯa{ศ]ฒู[‹‹์a2์Œณ๗ตว๋[Fฑ๒i‹{๘'#Xw_ ฦ™I�Kฒฦ๕%ธถมš�bสdt์gพTVHhคiอ๚”ณ’N‚฿ภฺกD2ฬ'k�ฬนญ�าŽ7ฏฉ‘ซc]0๔Œ\Z˜ว€LX�ถ`•�p\WfgYc@t%9%kP๎@šจ๎‰mF!ุ�‡Y ทv๐PแlhEQ&๙ฐพ:O‰D{๚€๛˜O๗ซ™๖Dต ใ` œฅy2�™M~O+] f6œ$q฿•qvดvvล๓tย$vT€๒ณaanŽ๙c�<คX“เฮทgถ๓bD์์ย}HŽznธฃO๑,‘๗oKฃ4ฎฝ๛ ํงf(“™ <Žพ’sGx(DCEฯf6ฎ>~Y"T]๏gd&๏_ฬ�N0G)Jุw�]๏��้?๘๗GzGโ �)Œ@a #๐งŒ@8๘Sฆ๐ใย�ฐŒภ/�ยGฟ�๕_ฝฟทบ�™ศํลูg=ู��๊�mฺ/b$X‰ฤฺ ;Ikณึๆ@๖.]{>fร rt†DŒข>0๓qDฆใ}ฯป๛ศๆœ=๘๘ิO€ต jc „๖†วGŸ"เ$7#]จ6+๒๔ัฃ0“ตฮd_t7ช4๘I๘{Ah เฦLฆŽ�c˜—epูo"Hoฦ�พxา` ฯ8€า๕ข( Ži�gv๕์•็b�พ๔fq.\) žฟƒ็[๏ผฅตv่:ฮAˆŒO< ‚สbฒพส…UIุ_�„๓ฑ8๔•ฝL๚าdึ ๊๖ษช8–S~แ2mัƒฺJƒ}kŸ•ฤ๊ํPe๛ว˜ฃ‹@so3ว\ุถฏ˜lY?๖ิ=A3€๙#ฎ้nฒ‡� Z#{fpŽสc=&ธอ`iœV‰์\เญคึš฿�>ม์* � ž� jQ‹ฌSƒ๛แป7 6‘ั3{yyฦ=แa7dG'ฅ&ี€ค•‰‰x็Xฏ๏ผฉ8ˆ†cฤฏG†Cึ‚ ƒcฦฃ Iพ™ฺXปL๖We‚rcถะ์HNXV’*ีศฑ! ฟFGiQIFTƒIk๙ ๔ ๐}Ÿ9๎ีZไž๎�0๖ต๋f ‚๗จโเภงขภkŒฅ+ุJ._นDYN[ฤQM˜œcฌsแๅ—?XฏD‰ง kl‰{)cุฬcuT2:Љ%(0Y �าW็YkิณB5ด€d๎f่8ย๛*฿�ƒฒ4H ไk๋ขผ[iAต2bฦ"ฯžาgคเYVVR”,ฎšศf+วฐJXปlถs—วWpญๅ_5MWฎ�๘™ห#ื�๗ลๅล๓ณ๓๓ƒQน@้Kšใฑฒ{๎]ขฦก็^|!zตจฦqฏK�ฬฑ.ถ >๕˜ูsY๙๐˜ฯ#•ร็ฯฒNNb๙J)�ue๙”ฅม•จ‹ึ1ตต[‹ชป๓ุ>ตšVท๙โใจŠจoj‰ฅv–x��ฟฝ'ฝa˜ฎ๘9!๋—DŒsภภxq]�อพ9}<…C|๏ฟ]sฎoห๏,\ภ3g~Bbvrr+Žฏ †=ึ…ํ9Selง๘|พถŠถd ช&ฮมJๆงšqฑํlŽst๘�0†™ }๚โฏ��?๏U๘*Œ@a #๐งŽงUแซ0…๘a7�๘…ฃ฿๚๊7็ฟ�+ท�_๘เัไฤ๘9สZ@Fฤา'a %ย2ไ๙ูI��ย ฐ7‘๋ช๏๕|ื หภ่5ฏ}Cร˜ๆ�cดฺ๊ๅy}รgยkŸ๛ห”-ด…?�0‚"R†�€‰l NO_Š-ิฬ�Œฦƒึ=+ 5๘ณI€U-gไต ƒƒa�้j�฿ QวN`Vƒ��•๙< ‰ฦฐ46Eูภ‰๙\ลwCKCAk3ฎ๔อฑa“Œc5^ซซ‹ฑ,ขฑฝ;I$ผ %�ƒมฟŠˆฒฆgGฮ Thมซ‚ฌ%๗ฆฌzx™4Wb,P’R?5;3ฏ๑sำsa ใผฉัฑPย˜ณRC*ฯ๘pฦ-LฯBT‡V2žบ� ึ‘ชgภฑ…ŸIj  ˆdŠ2๓*H ฆ‡N e�ํ\2ฏ ฎiŸ๑Rชm!‘MวJpcซG%ฅฮq=ฆs=ป˜•�ณ๊ฆ๖ัŸ�าฯ�mhn๚ฑ/ผTณฑฑ†šh้;e๎ฝh€5˜ ๕o�ํ‡_๘ย_�ึ๔๘D ส๒ฎY Kb0Kfด†๛5mษct*ฉ�ฒ2”hุFา5gฉH฿ˆบฦ6ฤ่ฏฅ!ชšBว@{a'„’๙bJุงOว1�tส€8ห้ณKmป{๐3ๅวร๐…KฌK ;YใzWฌAXข‘คู/วU"ม.:� บ4N%๑ฮŒไCOํ3[ฯfศษ จKjษเš5?�งฤ ‡9'-Saf„K,W`๏ไ]ธ?‚๒ฬ๎บG บ‘q—ฐ9 ฮฟ"E‚@ภ+”@0›œณ‚๋YGqภZ๎ๆŒชภร็>ผ�€uสzๅ?fœ5+ญdัเฤƒ4]T๖็��ะ70H ฯ&g„Š�]nS‚B™{sŸkี€๏�bYS ๛ว6‚ช•สห,๗ av|‚`‹๙ฎใบธ><,ี‰ –ืI$4ไฬAIrฺ๑„ว๐๛ฎž>6;จ’Vมฺ[b;xXฎ9!aภฺจ„ะฒหษูก051ฦ๋C๖ „นOK[ชX“ ๆI/มด็ gบฆŠ�ŒŠไ•kC•†�.1ๅhGฌซฮเZึt=๋ษป�ฌa�™ฆ!a-s)ฃƒ‚cฐM9€&ƒ๓”Yธถผ6?c,oโฆ!3 hธพฝ=ิ+œ%{ก฿ž!๖ฤ>{BS^ฯ ปฮจฆะ า9๛cาr t‹R\vŠ1:‚Lว8„5ฟ,งั�‚b#†sS๖WTศน@!v% =cํยKฦqtฝh๊หฒl kฉ™dh$/8ฃT€๘:;œ๛“HญYB>�yำ�ว%tภผ;งถพิาRIKๆk์ขาชฤ ณŠq+๓3•ฑฏลห่ยล ๛—o\๛oฎฟtวฎK^nแซ0…(ŒภŸ6…ฏยF 0ง#๐๊ƒ�โ›๏Oผ��๚๛“cฃE`‘+=ล)ฒ* ‹fษธA‘ษo'‹ื^Œฦedใซ‘ฅjถ‚์ณฆฎ‚ ƒ็ฬEษoK{g๘ทๆgqฉ๏ ๗๎�ก็๙ 5พ48ILุz๚q5ด:{@ฉ&$รNภบMฟ…คุ€ฬ๚Z%ย็TGีY.ฅฆ๋8›ญK“a”ไุ'่�ไร[แCHา„๑•ึ+ีฐ‰ฌy-เดฒb๖้Dธ�ฮ{แeฒณY”'Uผ๏๒�|8{fˆVrB–5ธฑv ุgอ)‡�EŽญ#ผk�9fmญƒฮ3W~ฺู›‹ำฺvๆใ˜ฒ[3J\คPฐ๘%ัb จL"Hc์ศุ›1ฎญkถๅ�ฝžกแ_�า—�งญ�ฟ�า*Fˆ๙žพพฯ\พvฝ่น^ =รCดฐl/|๊ี•ึฮ๎ง/ฝ�โ฿}ๅ๙W�ฏฉน๑ฯ c๎ฎ๔ธn$ƒš่vRสœ้ลแพษqญฮIškฺูXfCึนฟX#ฎcืฉเล}หs8zฯžืœๅ๗gฯžEฺ�f!V Ž™ใYส9ž=}Œ‰็๗%96‡‰`e๏ร๏‘ู`–บ�}j๋หหj8w\[8ๆ;สํ๕1sฮ~ˆIุœœ-PkPู�ัŽ�ŸVก›‹แ/}แวร9ฎi์แZxRฦมœWA(๊อa‘คŒฦ=หk"qษฯ,Q8โ�=Gv(ษ๑x Z๗3)�[K@$ใžœน๎eฮ2กU#(๗ิ๘ืศ@œ‰*_Oฟษ�ืsล๔‘yHpoqํ๐ท5๘e์};๘s'๘2pA๎DK–ณ๑€๓ยฯ„ฮ๐2ฺRชSต6rํลx&.ฯกพ€lˆ* •(� ใLฮวR•Rˆ„�พ�!˜gzฑXpฬ๘)�—จ<เ์ษlฃุbŒ[ชร ็ ฒ‰HHtUAศn0_ั€–๕lษ†fฝ–2YVฅGฏ†็eศ�ํcฏIโPxร�{ำ๎# _Tษ๘๙ๅพWีB\sTฮฑž$c †ใ)akV ƒCฎ[‚HC@RฬฟUุhจxŒฅไˆ๊'Ik�บ&๙ผ– ศpžIzHจ•A๐๊น‘d-ฆ F\]ํกฎน๑้ฟ๙7~๊ฟฆ„ฎเmOืย #P?kL๗พ #Pย�ซx=;[“''k�๐๛๏฿๘ธฃต๓?ฬ�˜œ~�ปฅุฅศฑwึW"ธI44…ฑG๗ยศฅdืV:‘1#kตž;…#�•k/„e|พ๑ตฏฤ,ฯ�oฝIฐาAY%๛ตุ ดvlji _๙�๐S^|�Gย(ูฅQ2s)Ÿ ฏธŒL๔๎ฉไSBมlด5แ‡ฌ 2ำฑึ3™Cฒ ้#๊W&OŸŽ…ีบต(ัMxฅœ๋QP”ฆ&L„ล�กg๋ Lำขขบ‘`ฺL)ภ”บไา�‹ศzญ-ฏกภ �_�ดูร�ฏ๊] หหqๆุ๗ฝ๚โYแ€จP`=ฟา็PJฆŒ๗(ๆg‡tค #C-ฒ�CJ4ฌใ–�(Œ) �๔~ ณดž๐ญoผ‰๋;Y,3‹\ณญ์Š‚›q˜_CV?3อ{Uย${ฎบkp �่g?Ž! พ๕ๅ�›ฌ$ฒk€@์ำ~ ็~wน'A“Al `”"“šยํ]€นN�๏ ฝๅฑJd.™;๎'‹ยยzเ+>๙ไ่ผฮอ๏ผeถ–$!|ณษ๎โ๘^€ษั‡งm,qฅฏฌฎกผ €พ๎ฏ฿ผ”‡-Z?๊๔ฏ”ปˆ์ฎ๏+1Uร<^บ2:0�ด‹ร่ฃO0ํ์ ็Zฎ€E‹จƒ† ™Ÿฃ?๚ 4๐๚]จhv!*๎~t;–ฮ<พย๔ฃัฐƒ|บฟง+”ำ™ฤn–.4ถ๐=ฆ€v ุC�~ (<์s}QNŽybฎˆฒJาŽฝํe~ไ๙„˜™>5$ƒษ5๐ุ๋š/ษ|$  (oPJ€9Š|†& ๆ—qoU/QŠ๑^m[sบฅฏฏตฑฑ๙ห7าฉๅ+W^{๔่ƒWA็๋ (‡$G@�t‘ด#สžฎฌnBๆ�6vฉีฮZข 'ใ*ฐ>โ{ู๋ห8’dfึ5้3พ8๕Œ6ЉะืัIw@g}q†าง6สƒh‹7หบฎฦo’p†วพ๔๊๋กlฆ๒j•L3ํ! V2๙Jmpฌ‡ิ�กt'yŒฟ‡ๅ3(d,‘*Žg๏อx&๐GX้ซIh๎ฆ๓ล|ุQ้sธ~๒Aธ8| แม=ึ5{^ภุJ[c6โษ`›ฺ-ˆ1หNช๋šโ947๓ศ˜ de…ฒƒV}ฐึz์-ปท$PYสข…ง�Iึ{Ž๛�ฅฌชบ๖nบH4‡์ผ žหพฉจ F�Œxฝ„)2�;{›จZŽยย๐d+ศ๒&!ฒSฬูฤ%V๐Sใแโ…หa~|"ฬR†S[Zพ๓๕ฏQ—พฬฆ~ž{™~8ถ˜๋jฦษviM๘@จจ ‘fƒMกตป/Lr}f—fงikz๊qฤZTช3จ’8จ์Ÿ2‡I๎�„5ฆฝกพ fฝmญ่ˆ–˜ฅ<ึึถ„พม!สˆบYฎ9Vฯ้ไมๅ๘๎๓o‹ๅ,๘ŸF’0>่;o}ๅย๘ใ๛u›3‹์B๎Œ9ฐ˜�|Ÿ ศ๙๕Y5 Lํ{)(ฏhlC$าSdง3ฬ๎ {ฺ[ ๒ไ�'แ'��Ÿ…ษ‡{๏ฝ`กล+u๐ฯ฿ฅ[Bํ#Ÿc�gย[o�uโ+p›จ0-zศก+BGwh„ \X˜gnU,@BฎfNASe€ไeฦฅฮ,3ฎ๋€ ฿M”Dมด๑yดIนุ๖๖�๏…�๕ฺ� …บYณฐ”—๔<*ฆ๎]็ม๒(ีCฅœG6{พgIฒ วž(Bmกท„{๏Du€ทuCkอ]ภcl ptถt„‘๎๓แ7๓ซ๚m2พ\)]๊ช๖gv3จ†ุปt้r4ฝ๛ื‘FMƒO‚bฮIื˜ู(ฆQ�คPไŒ�$g‡็nfฒ~ำ้�@|Zr!1U*์ฯ{Ue@x๓E พขxฯ(c mj๗�งž’E้yCg†ย1คเ3ภธสŒ5|?P˜จrŸŸฐทสj›bฆ฿’[jxšๅ9วนH•+tM‚ jdŽ!]ฯฬMฒทกฝ“๓mฬ]hเsค‚๓Yณฤร5ฯษมฺุอ&ณ~ˆrA_�[าq$ กpTd ‡๓Uมดฦs,ษQvV.�x>TN„Qฌl@�e!ซพ�ๆ„ ึ)N ดอ�)Ÿ๙‰ซ+ชWฒ‹๋๘@ณฎฑืคT sำk�ูm!ฯตฮNใ#CซZห'๒ล(X8c-๛ศ๘นE'˜2ๆำ$ฎซX^ร*ั :ญŽฯ I=oNฟะ`@†ูVSข!ปฃท ฤOD9๓ไy๊ฐ<${xๆื"ู`—กc>#ํ4กd[[ ทดrฝฬยˆไšๆว–‚ฅ*ำ๙�‘แ๖ำ?�w฿๚ฃ็ภw/ข๐Wa #P๏;โเ๛Kแ‡…(Œ#๘Gฉ�—''ใฃ๏ๅฟ��หvพ๒้�ฝ๓�Oaภ๕ูe�ญปฌqฏFฎ‹ฑ ~pค‚. ‹x|1|…ม ๓ฬ–ฝนSŒd‚l7›ˆu้:็k�7?G๋0W€ูฬƒ์rhฦ-พ็าๆŒOย4ตž[dยญ�Tๆ}B Zœn‰ู�uSญƒ/ฝZนพ™ฑ‰0IะFึฑ” *พ7ฏ)j3˜หฦŽn“33แ@&CะUู8H�AูรฐMpVKฦสบj 5จฐโ{7`๚f๐ธ†\๛„เ=(5ธณถTyป~๛d~60เk%รc6˜ง�ๅBู๘ุX�‹ฏ9ณ†˜VUแIะาP†บ;0ฎ{9ด๕‡ฏ��๏†}+&–3-ๆ’ศ๔‡ร ืฝตฮพgเBB~ุ|6๙ YืpHฦฺ††๋ฆฆPPํ๗ŒQๅ@ฮ” 2ื€ ณmfิญ 6ˆ6pVŽžูมŒ’ฬv1ิ]ๅั1๎๘จฬะ๓ผ"t /๘ป,doๆ˜` HุI๐lส™‹็o\ ็ฮ๔‡ั;† 2œcฃฃ๎ภ€ฑo„Lใรp๋�oล>๐,ฐp„$ผดŽ. •๕€๒~”HœS๐‘�ู˜ 1GLpฟ5”8๘uเ{@šุสsRhโม=2ุอศšKลน่Qัู7yU6––ุ#*+ศ ’พ�ƒhฐU่žๅๅฬq)๊‰�yฦ% ?oม;ฃ˜๋x๖๔ูศฦ(3฿ƒะ(‡ผ�#+ขfฟฆก๎liX‰๓��XภฑฑD�ษ '™Lว7พ๑[?้}•แkbXAฆ?œ์#™ฏCI@ถ’’’eJb,ฐk‚๊ึ\vWำ8L6�๓ฆ๙eC๓ไ^-.��anv<–ฐฬฒฏwๆžA6T†๚พก๐ฮ{฿ E(>�W~O”=‘ู ๛<0p&ิRฒต†ทญ๕>ฉƒHฌน|-LณWื๘๙Q–=l=๗‰~fq!๚IถิKฒfฒ์ป�‘‹(WaCฤ:ศŒ *ศง๎� )๎๋…D–y<ศุ’๎ลจmX“{๘pจจ(…ŒไฅYฯ}€ไข$ญ๖ศ” �K!s2j๙g™ูo@z9d—๕ใฒ6i"ไส ๋ธเช‹�๘ุำPัฺ >7ท๔:ฑ@`ั+.(/จฌฃ$…่ฬฒ …ํถz๕ฬHr๖ไธN)pฏdฑ9+กjศlำv@ซcส$ฝ*ช;ู๓K,_• ชP,P๒d[�Cึงฆ‰ส�แ่ฤ็cn—|Ž๙ใdŒ$ฃJKb๋HˆŠญี•0ลฎซ4M–œ%ฅ฿ฑJฐŒต�$fภํ`kFห•ส9—O๒zษเ๙กทร๙]๒๊€ตด-้ส๓#ฉมญ„๘8„ผZืไ•Ew๗$็|"D ื\Q…a)0?KG7ถฅYyส($็Š˜[_็๘ศึฏt!แ๑฿ปž๙9”CฌใuHฏ“"๎ฐœ1<๎ษ�๛ดข…�ฅ,g“ณ>ร๕?ƒ X__E๕กRK?ส?ศุ_€ไฺๅ3g‚n OงžฝฯATฟ?ข�ะ\\วป�›]aŠ!jU�”๐w4อdถTโฉ’:`,U"XŽ ๗†6๔ฝqญ๑`n‹๓šตญJฌข r•ŸAT•–ฑๆณXJpฺr฿๖พŸ=๎G/ฮ‰m๕V‘„H;9ส๒9ปŒ!โนะั�97r้๊o�ัs  …�F 0…๘3F @�ƒS๘Ua~ศG@ Aภ�99๙�ํ๗o�‹Ÿฟ๗ฮื�ๅ?ฅ/๖๖ช'ึ/ั�ญ์N&๏ฟ๙ป้ยพe€]ป9hถgฑ{q�พ6~n]พฝ็Kศดู๎4g;.ไผ.กุ๊#(�[{@�๋ปด=$เ= •ำ"ะฬ“ู็ —Ÿวo€Œ$๛�o|Gq ˜iฺัแ'@๐ๅ�ฅ€ูุฦŒเ4‰ฬ9‹bCu€ <‚ใ6ม฿Vw Ž˜ ฮฌ1็�_Y=Roอ ”K+Pcฤฒ…๛ศv)ƒ๊ํ/Pห�ๆ’mษ�ฑ^””็๘w ’กฏง'œ?3๎ฐึ>A]ฦต•Qš‘C๎�7฿ “(1ถศHW@ิTq,Tg3๗m>}r›b๐uYJ �  OX �๙rฎื๛*ฺ}F฿ ึouฝ่yŒชื`ภฺeแrฬEe;9ˆ#%็,nึ๖k’๙CŠmหผD๊0ะ๕$,jU%*%๖A ตL Pฑ“ษ,ืิ7���~eP��ฏƒไ^ๅ๔ุ“๓’{�D šฏY๋ฎQœ%3บBr0dฌ1ฒ›ดศฬ#๓ทไbgS0ค‡%$Hีน6๗คc‘b-คษF฿�ึF2ดR?�?2HดฃชX!{ษ2๖šRํ๖Ž.ฮ…^๖`E่หr&์…๖๑&„ส ^"ืž% R2b๋ห๗ฟี,cี>์ณทšZบคม๒ƒ6Jฃฮฟ&�yี็ื”ใฬโC๑‘ี๕่ไฑ'ะkŒ\ณ๐,Fศ Uw@~2oช�#ษ–aอ&!v ฉgงh-ูวœข:ชL„ีษI�[™>C˜–8ณSว"1ฉฺๆะ… eณฬ–้R �0พTWU–r"ขจHž”c`ySภ'!_<}X๖y_.‚}ฦถรsก„๒คZ๚^่ท`iBฎดซR—uสKบPP ภพ�g}0?™mๆป/e๛Uษ๓�–9Uๅฏฎด+ๅ0”I&ฒuๆwea#มฃ8ฏvjp฿ง8‹ข k „ Ž์ธืS*ฮ(ปศรT–cฎ™2S!Tส็‚ฆฃ’-ั$–๋ไJNญ.ฬ„าzฮๆ1]฿JgŽ๖ธ๏ฯ๋TYมขัkBรา8†Žฬ:�3ŒEช"‰ฮ39ิXšz6J\€ธ๑4ุผ๓uศชHJžช๐ฒุจ`}งX{็ฮŽ„/ผ็B…B ๅ*œiL‡ฯ„้ฅฉ0:3N™ึ ๅtฏ‡฿๙&'&89๑? ดศ1ฺb|%™Žู“Y>'$„๔|0`ฉยไ”เสเaซbMXaโ๖t*ึ,ไุ6ํูณงแ�ƒ�ดส#`mmค4?,“ํฉG2Ÿ„6#นœœ/DภkKม สเ,�]Iดู๏ภe nใฮํ�HU๓กs ?4|V‘m๎n๋ท฿�Nxx๋ฅีYศg๛dรb)จ5ฬz4h(h๛ฏ#cถอ฿Gเภ€ ศ์ธmธ…?x?fD5‚‹u�(d!0ๅ<6ะP•ะAฏ๚=ส;฿&จ#0ไ™ฆฺุ‹ าla3าlƒๆDQK่ก�ถญปƒฅ๐ึ๔YKิ โ๕Hถ/ผ๚zq๛ƒร#Wย�w฿ฆ�mีZCฯูซฯ๙๐ษ�7ษบWลvddืท2ซHq[–\งL‚ฺ}๎Q&ศ@า`U“43๋kหฑ๕` ๙yฒkIคว‹k[a…`ต‡Œำฃ;wYk�' ง”uกšไ™ธมณช฿{iq>|๕+ฟฉ( ฐOข*ษ๎b* ›คท�xš๛/ฤุ\็๚ไSด?{2ว<H€ญ ฏจกv2สบgณวฎํฒeอ: ฿c&�ฑoํ์แฺPฅp-ฎ;iดS0�S„„fHย๙Ÿœถ�u<๚=์Q#^ ภqๅซE”1จุุๆ๛๊zdแฌ9eโ้ฒ2:–ฒ8�‚_’ฤ7ฟ�ๅม๑GำqีrํชE๔)‘�จB้๊ฏƒ�ใ/$#ZŒฒฆฌ9{i6๗›เ฿`™8ฟvฐณฦ้ž…aพ๒x5”ฐf)ฑดฉ5L {เ“�ทย,ต๋Yฦฐญต=ฮ›m�4๒Sอ2;C7 ไ๘Ož`^Y๚z{!~ž†%*f(!’ ,g>=ฬxžu�ืฏญm0<8z/๏,…rJd’x”ณพQ๊‚ฏ�ํb9}’ŸkฬWม๘ๆษพƒ๚8/๐9`œ”๗€%G,ึCคใf•๗!8สช4T�็g @l�K$@%O๊�๏2ฆ=”๕ะนeคƒV‹w!UณฌAd๐\{ž„ภJาฑคชธ�ˆuโx–ATไQุ์ฃะคQ/‘่)QYูXU4^งЉๅxฯํ=qYาฅแใส�4Z’2สยศhkบY„7†ฆ’šeVะ‰ภ}%€๓ธgๅ sN๖•๗#qR@•\ืƒ๙คЁ"ภ8CŽ"ส นญ#Q๛0็ถ‰๕ฌษA<ฺA Œ?•๘Dฃ&Š’„>G๒i}a&d&Gแจ I0งญ‚d.โlฑ#ส�5 ็๕คภด=ŸHCข ๅoใณฆกต bc๗ภso9=ษLฏต˜๕็\ใ,ฌg/า๕fณW>OVWึยอ[๏กึ:‡šซ.|t๏vxํลO‡W?๛—ย7ฟ๚�”ฟิ†O‹ึŠฆ60Ÿ~�3แ+_� ไไW BŠ3 ƒ"สฯŒ”€Ÿฯ �๕nc”ุุูŽฏ ฤ)ใXยฝTฑ๖กๆX๏จuุg�/{o#y~ž๗}๋พซบช๚พปง{z๎kg๏%w—ญlˆŽYmภK†ƒ'0k $1Aฆa†ม‘81‰Pผ•].๗�ูkv็๎ž™พ๏ซบช๋พซ๒yพ-r !ปKา�ƒีไ์ฬ๔T�๊๗๛^๕>ฯ๛ผฯkฝ ิฎV„ ศC๊๒Pไ •ายvซเ5๒ƒษq6TQ*E™ง&ๆฎึ‘ฝWฦ๘ เขฏฮc?ฤqˆ๑ญก’๏ม`O_{ ฏ๏;ฟ๕;KeKZจฏฮtF 3{:ฤมวชฮ ;#ะม†@ษ�3ฯท—9๒B๗โ�_ฟ๒ฦ�่t�t C0w“= rgฮฬปLžภl{s‡Œ)’]ฬิิโ1J๖i‰๘๛๏พ Hw˜I2๋}�—lw๖ึ ๓ั๛WM฿๘้๋ฦt๊}ใA๖ฌ๚า2ฒvฏŽ๒ฟuธดํP8�€zณ—Sd ิำOWบฆษดฉฮ6ฮฯŸ>sม๎๏ ป฿ฒ 6N&SภV๓�ึŠถชqฎ’Avะi )y<�a*pUฎฬฆญ‡`8ณงŒฌภ2‡ Tิ‚jฒ‰ัlถืEณ‚ ๛pาŒž~๒i๓๊[Wl้ต‚dY0?ฟ{™•{?lŒ�ึึ3œ)P’ ฃเ๚„ผธๅ›มS๔…'รZูli5พ„ฯ€7€9™k™๕ž;kบษjf�ฐe H•ญไ‚�Ÿ~Œ+•แ-๑LXฏณ2๑uXv›q#cบŒšb‚yQ2ฌจ ศšœdฅ ULๆ>ธiŠ)ฬO]E'/^ภฉ�†ู��$ใL�GๆUฦp…๊ปh|U๎ขEŽํnำ๎:]ใ˜eTห`ข.ฒ�Q๕4`„๚๏rA.�(DสPฦ!P๋Dถฏ!Wupซ,^iบk?™ะ2จ@ถทSษฃ�๔$เX{’ “%0]|๔a3A๙ภ›�๗Lnฏภฐ%$Rwป่N  ๋5@†�็‡€�ฃ€@ณZึQ8ธ'I‡nฃ€šบH'Hๆี‚ ‚|b�Šš๐}๚ษซฮ<,้?ฯุ=0hษeฒ5๎z—v�ตๆ…ไ–ฒฎ€ร^Šฮฌ�&&^ฎ]B๕ั�P��ภค;‘๘|\Š‹|�/o,�๋}ฝฝฑ…}ฺQ’ฉUหNeqyH@ ฅB/ศ{v'Q„�ุ ฃH`Ÿถ…2์S‡–6Yweิ•แUญฟU ฤ�”๙Œ`๎นlถ<ฐ ท%ื @ดC๊–โ.๋Œ5้pซใ๛>iƒJ‚๓ลษ๚–ฝ้ปรฮXฬ‹ยjะอZฤ_ƒ…b๖–Wm ะ^ฒ�Ž2$ผW%ฝฮš ›ไศ”ฏ-yฯไˆGUค๓ม„โมeNdส‹ฌ๑ ฤ๊ไฬ$๋ญศsทP% ฐŸ0๏CEใDบเฃTH๊จสฌ5๕R[x|์^สX“ฑฎnณฝFWZk5ฤz๒3_U{…9ฌฑvฺฌk 'ส/$>HนRzƒ}นAyIซด2*2ขฤไOป์zปวš์ืmKจส“C-qt!‘๘]ž*?*‹4ใ�•สBค™j"ชด~ ฐVคuฎY…xSW jเžภฯB\Aศ๘y_�์๖า,khŠqฤ@†Hฺ๓›ฯ &�ถž*WjณgS›ฌ)K จิ๏ŠvˆKbfศุiAg๋y3r๒!s>>iฎ]ปร™ ‘ล9_a๎ก0R๗™ ฟž�ย/™ใ3'P๖์ัR๘œู��0?�ัท9ำbๆ์ใOQ:ƒื ๛5‘4„๙i…C@e ฌ{e�ีพฒษ็ƒJuผwr-วy$๒)ึ�อ๚ย›ย3 >7.AWเH�RF$จฮpฟHO�ฝข>…๏ซ๋ %ฌฝฦ 9ฆฯ•๚D€B2ฉ„ฎยูไDeแฦ�&€'J‚%B๋ล~ฮฟว[uu}+โˆ�;ฅL๗ฐ่ผฎ3๘ลq๐‹=�ง๏ŒภงืŸw4^�ฺ๚ท�๊�‘๗๚{ื�9uง._ค๙mVƒ&:h๐9x +fn�„8X#หๅ3วO#ฝง–z o+ตAง5N๐f0ใรUIๅลGŸ@N9l%๓ไษ‘Q‚Nภ 0Lู7ต-ไDชฎ“,+฿= p%ตWzซJึถ๐๏ง>Zูขพ‘๓ฮฏ„B@nŒONQ7=`>บ๚šI*#็๐ีิސ?ซVYเ%†เ6 Gfd๚’ษ—อเหˆ/I’$[VภKZWc5คp—€lpฃ.๋[ๆสซ๏bž†‰] Kม A!ˆV’}?Fn2d‡– `ัAื…r9ว˜!ซFฆ�=qrๅฎุ—d้Q�?@ฺ=fพŒทeKssf๐ฬ9s๑ฉฯ“Gฦ›ฺฦ์’น๛แX%q@ฟ@&muuู,�ปgบ‘ pฉ‘ ,ภร๕•ลo0K‹ จ†่ฟฬ๗แใา-I๏0ใฆ`u @6ศฯจะ !id~ Cํฅ-@ƒ[�ฬห๊% ๓ศฒ้o๏ย๘_u๊„ภ+ฒtdiญิ_$  Hm�ิๆN„†ˆˆ2ต๗Y<%<Œ—๔jyงืy๘aไพ9H„&_นŸฃก�\ห\}๕ ๋ภฎ๖บว^ &}๚q๚—Ÿ4 wo™ลี-”ดpฃLกIๆดช@‚สรs๚+ส€๋ะT•GŠอ/าฬฌ;Rึส๖—dุ(r "•„Œ>›,emU‚แฤ๔nea�ึย ไWธW๕งWˆ^€๐๖๊Š ฦ*d–Q�t.ไ _.bา‰ฺรฯบ.๐X.žE†oสVFบ!<„‹d` (Q๙ะแ,ูล๚1�C&“n“t6 3)/Œ#๏ีˆหิ2 ะ)l1I„ฐ๒1๗1ิ@๙ ึˆคู)jฯ%y— V#3.�’ ?ซ็ด›•M)ษu‚ay~ ฏบE0†Až#sศบa i_U(วQ๙ัๆ๚*™j๖:ในธพbŽปdห2d>ฺ34ศฺ\5[[Hฺศช้ฏคq่g”นึ—TSใ'Lˆ๒ก{”8•ู+R8!†˜ +OณฏUrDf^)r~ฐ>•ื�ตๆ|xฐf<.™‚”!ฦฮฑฏ๓๘zlXpk P๎Gฦy5L7—VศˆใqD2๒Nhถํ\zนku๑ึ]ณtk�fฆKH็�D/ภา `จŸšBeีลณ-๓wฦD�J่า`_9Q™ศh›A๗Goˆ ๙Hช.ฏ jณ่…ฐ @ใZfL dล+จ*=aŒDjI= ๚๗@$ฤ\sฒ’อ–ฟ1๛�<ฟ< \[f‘dศYำRaต1™uฑ6*" (E`• B๋Aไ\ร_Tšoๆ฿๙&Sึ67yฮษXWg™F๙/xศ"ฮn�>ฒ๎^Jศุ�M•#– (qฺƒั>๎๕eWศDภถฒ๓"บดF๓ีCณH‹MุVLj9›9�u?2 ls.๖P๎ฑ'?ห^้3ฏ๑y วU)œ ๑|๚lบ๙ั �ฎVgJ‘1�หฟ๑ื๐Tฉ™[๏ฟg>x�Uใฆ�ๆฉฯ}r„†m๓™�;ด$ˆu€Ge ๘"ฐt-ข-h๓ิ)คึ–a)ุร!>7ไ็ฃ–‰5>�ค4เ&นuๆู€ส>Dื่+ฤg†Gํe”xT^"“D HŒฏฃ‘ ‘๒�ะ3ณ†4Ÿ:$๔žฝ�ษำฮ/]น๓฿ฮtF 3Ÿl82;_่Œ@g>�8K[๗ฏ�_]๛ํž[ทn�UO �Tำพqฺ^ฅrๆื^ทŠ"_„G�ชฏ๕สฺ†ูฃ,ภPฉŽ๗‘ัZp‰>ตซdต๒H1[(ถ^cปŽIสZ%Ki%ผ|*YP–K๖Oชญ“ูjฒ‚GdKฏนq�]๗™ท^~ัดJHdษšOˆญ›ิฝY$๔q๋‚Nœษ\\าผท�Až์f"ฆkxศŒNaPฉsHvร=Œื hศฒnั…aw &`L`ํ"จUo๚Cฒง’>ท(—PF^ฝๅทWึีRฦ@–฿หs1-<'ูฦ"5ฯิQ;™?โ[!ฉฃ>๎สVจแ @’„Q3ศPฏ(s‚ไฆ.ย๏ ๕าดค”2_ฎโAฒำeศ‹[~dฆ.]@๑rึผ�ส+ฬ-”cคถw*c‰๗jcดicŽœบ. d€\๒ี๚L๒็*€ิ.ํ8 า=(&Tืฏเ�พ?ฯ รื�xษ่ตdเ๐ฑ`GภR‚0Rฆำ‹:ฃhษ †Žu—รู”y๑L"ฝ<\_Nฎืd.หdืUว^!๋,R*œ่#ƒŒ"n๏~F๏Qw๑|ฉ]^ฬlsฃgTึโE˜ๅ“|ตQ?ิไ‰!๏ N๓’;+ซ.๙๕�๎ู[ฺtBยลู�Grkๆ’น—ษ €ฆ$FF‚๎๊๔ฅฆPg…e=สl;P#ูŽะC…ศ ญฦGๆ‘ 7 ™%๔ษปm๋?ศ$7ู๓ถตต‰/Hิ?s� �แ{8#P˜ฤ )2ฉ๖ f˜€$eภหHเ๓���ู๓tsY kส"ศ?ท เ0ตฤ?„๕์ขอก:ฟ๔Ki€๏Žช6�`Bƒ2HฤI.%�AœดQG•ฮ๒H3\‚„ต‚t> )fkไ92”๒จ†ๆŒเŒPุ๛*5จE,ฉiJฬA‘sฮ‡W‚Ÿฑ ‡U็ฎRT`œ•e^ฏsKFŒlYฮ2ท้ย{CgŒ0n”’ืซ… ฬT3์๏แtˆƒO8`—wF 3�๎ ฮ\N]ฝฺ�ฝืพ�ีต๘ย�’ฯง{๒dฺUื�C+DI†ี*ฎy๖I‚�2A ไถnค๒‡dวไ6ฝKKฉ0ํ,ต๔สE0wR-k “ล. ๗าิฌ–๋ห์Li 'e*VPๆ›(ูGษU 2pณม1eže0xS�ฝj\•}R-ฉ2L‘ `F|@F…m=จ jยเ�ซWฬโ} ุีสฦ*#ชฏxฒ ฒOyร†G’ค๊^”ูjqmo,dฮ<๙ค’ญวp ฏT�w๎แsๆ>ฟษ๓ป šชไ€J้pBนm[.๙ฝ ํๅ6ึ0vฃ†\x๊ไyƒ�do’คฅYWŸY]^2ซ๓๗q�วง€:�ถŒตศZ๗ฦ€1GfKฟ0ใQ0ทn]g Bdถ‹ฆJ๏งกd๘u‚็] ฅ2ธ๘ุิ‚w่‹H—‘ุึปsco7ฦeUJ ถถ๐—นฦ†€-ี-cด5๓AŒ0uภฎ“า_„ ูั:ฒ p์ัuHšตjd้ษ€ชzข้9K€ฃ”มัžฑ๑งง์ธษSBm๑D8ฐ•—Ÿ‹ฌฉิ*špอซZัฬ2ฒ๔y”Ÿy๊YวเฌBญRlaXฆป$sœ%8ฟ‰โ@kS*ต0ซีn/ฬœ)ƒž† „ภ๑Nv ุeพืDย^'‹+ฯ…Z…ˆต"๋ฏuD•ื@ขd�~�%ฉ5ศ!™„&ฉ‘8Pง‰B!m ป2†-ฒป\Œ_ศ�!Š�'uๆาสภน†ž[ภะว’ฟ?bษƒFฅ�Aw2๑พ�ม�Ÿ๚P�ะ7 นร/fRปฑๅ$๖`%Š›๕—�[็~j& ษา=0nA”y หŒY‹1€ฒณ๛Rs 9uฐ”ฆปŠฒก๒5R^ภz ฎ”Iึ�“ข V1F6ลC€็แDอ๓ ๒ˆadn’˜;cn�ฝcJŒƒสˆขฌมq�ฝPบM‡…}ซ:jำS†sA๕ล Pcเ ภฝอœขS†2ป ” )ร\5งฮœ`oำ�_ศ๎B`Aฬp๎ธQH�$?‹�T–uุ‡Qfศ�พq›q๎ฦ80n๏,™พพต๋˜โqOmd๑ๆj�'•ŒZŸ๊>ีjตถฝฯ3ข�`NฒSฮ(ฅKฏผ๐cHML ‡t}ต™ไf†ษ^บYJ8Š˜ปึU‚รœ๘ƒt?@ภeŸบ0๖8็ภXŠ€<%Yฮ‘ฆZwjY„๐“งA@|I์C๖๓zิ-<<{K-i)aโyU†ร›1จbtถCฒz!i๋%ๆxo'o&G‡!Iฐ[d์ไ๑ภโภ˜–=AปQ1"ฏำŒฅrS๋M„ฉพ'RSe ๖3ƒkห"ฦzPgyHด8/{zzฟ}ๆโร�ย1�๑6๘๘วc็•่ŒภŸq๐็Gฃ๓็ฮtFเSภO8ส๋ํ๖ท‚แ฿ผ๐ร?๙g�k๗�#fเุ ›Tๆ‘๘�ฬ�นCฆ I9ๅ”�จีฦฃ€ิY]ทนตsอ|๘ัGๆZว^ฦ๔!ๅ๖เฐ^ฅŸ๊กAKb526j�ผ2ฃU‚ทfyึูเVู3iO๋€ฬ–ภ€ก •“ถCž™:ฉ+WTไ๒|‚เา!มๅ�.#ฅ„~k+Kึ๓@ึ>ŒN งคX˜ป}ำถC์5;[ดŽl+ƒฌZ�ำO>a<�]&B6ผยs๎ํ›ู7^5ฉ…e๓ฤฉญ`@ศŒPu๎~jbสฎ`ผ€2Qไ‰+y?ค๓r ๗#ว}�๒ใๆกว67oผaR‹ศข‘ญ‡�&ภ{อฯฯBbะSqŒLLš�่�kŒ*cฦ4‘ก…„ธาŸี…ก^ฯ™**ฃ๛'ศ>ฎฑวค ้™41 DfŽฯXƒึ+/�•ภ)3{•ตˆ\rF ™ฆถ3Q<Ÿ{˜sฃew๏qrๅ์Oีศ'{h1ศzuศ]ึ<F6‹ม.Zs ๔า$9้เ$c#I-ฅข๑FQซ0ถ5TYส’�Eร�–+Jึะ~2 t0'๊lแโ�์ญ๎„Iีำ์สrวษ�)ˆ.Z๊ eภิ0ฆaŒปภ}˜นไ›r$๔œc*Qษ‹งฎูdฯI�ข3S [ฅมิ"DT)#Hšี’U{"G้X”๓S]fไ ก2‘๕ๅ5ิV œ#ช็W‰„๖ฉ2๐นT ข‰30[ษณO9๗ผ๘y$บูืL oTฏ S’มพะZW{ิฃr ฒ๗์ญA)nิตD+\zV๖]™ŒxEๆ‰Xิ๙o�ผฒ๏ฅˆ๊๊ฃ‹gี"Dภ> ‰ว�,Cไฆ�,%#ฌฏŸ/"ˆdŽ*UŒD;็ฯ]เพ๒”–ฬiXฬ์.% ˆ.พ&M;ํSญๅr–ิUฦUส ^��Žo’@{�E9”i„อไ–> ๗ู฿gฮž1ฃใfn~ž21งม’”uุF96ฤณ1 ”Am๐˜ฏ0o�o…30ˆสฯ�cyิTEฐ�ไ�c๗!QDตbAž4"์t~&‰�_๛k�อษ‹WธฮWg:#ะO5โเS [็‡:#ะ�๏ำ ž๕๙ป'ง'วํt%Ÿ9๐์ําึI21Pป4น.ะ•า„ต#ใ�@� x XkQ๏_(K ะ"๒ฉŽ–ฬu†ฬ’ภSU€€,ฐ“_ไtธจZีUu�ศขGF†ฬ›ืpธ�ณฆๆeาR๖›ึ‡Y�ฌVe ชG๗ˆ?�…/แม5{ๆ๚•ืlฐ\„pฬวz‡ธ ’ษก๓ถ�z› \�ต›‹๊˜ะฐLเ1PI!ำ๗วcฆIะ๏ใu 2N+ ‹๘ฌš[ฝoห/หธ†“!ญR›ฦC™ƒ€ซฺtฉวท� ภ"HrBคร 3€„๕ิฃ—Uฒ้7อฮ๖*ม๎ฐ้A*;8bŽ;ijฏพN้ยู้8YB$ห�gฝ8f>ผ๒ฎ5ž๓#3/c’!วญูภW$ŠZ|•1Sซ"}ฎ8<Œz~ณ|wูfห�GศM๖นA€ ภเฆพS0ฅmส,Y-ฉฃฯํ!๛)@"เ%™ฒd๋พ0๎๐ม~‡ี‰‹๛‘ฃภ� (jq3mL$]�;้8}�๕(Ym œภ˜H\@F  ูขo่�\�๛แ�ฆฝ^ ‘@’L@๎abl‚๗Eภ๋}elq#W–y˜ษ อฏ�ฅฟbฎพ~ีf}A*๖9ิส,ฝ‚BไฒqL&Xท*หเ็นฎฬ+ศ�Cz�ฎ~+/“ฮฃX๑ื่มะ้7่Dฦ๎T๗ึ“”"kUพ ต6ไ๗กฬฆภg฿่1๓แ{๏ูv•lึ&—(/Zิ6ท$"1ด^]dไๅ฿เc� „ซ๎]�&ผ/a: ึg:(์ใ*œผ�ƒงฯ๐„ว๔วYทe"ญฅ9ƒS&Bๆ2๑แภ$ฑฐฟJ้cƒฑ^m‰: QŠ™๗*"„[4BIะUvก๙E‘9cข;dPUัTiภ๘ฯZ ๔ 4:๘น$`"ฆY�Eฮน]1K�ภ„้ฅ+‚ค้jsG"œ๑ฦxฏ…bจA—ศน $T ฿hคอ�ƒ}:`tA ๎q=JPฤD๑ ˆํอ์mšัม~sžฒนแซcล๒โ๊H€P�๎๙ ]›{”ํ`ะชฬ/๗‡0่ˆ›gž๛ฯฬ;ฏ~‡kSง�Ÿ0�ƒ=จD$‘๐‹�๓˜ฬ๊&ูu๖^+ีร]ณทฝc&fฮ›8ฅEซ++ชล๗b๒ yท_4i2ใM€aฝX3 @jt€}ฦXUย’หGใQ@+JฬEไE’˜ๆฝ<“|ฒgภไ!�ฺ,‡ ฯฎ�ึ† ๐โภ/D–yŽ๗A aฮAช�เ๎๛f�ๆฌœ[๊๒ภ•,Qแtล8Oธฏ� & 3UๆOm=4ฎYƒ�pใํ lน“}์f=ๆv๑UAๆdN�:ณ {(ย~ ณ^d๔๛๐jับจกŒ‚โเ�ใว,•ฆฮNึK6ตล4ญ๏‡“าต]ŒPถำD#EA4ษ๚cOJ#zCfŽ˜ฒ๘dคง$มม™Rc฿ฑ๒ X“ๆ‰‹Lrlˆq ฿2็๓›9ฬ'eภBRส` ‹๊@{,อs„”ญทชฮ$ๆ|ๅมื‡(•�B* ญ{^�• ๓น™ฦ๚’2J-\๕9&ฒูถ๕„๐๚ŽJฏ่ๅภฯ—๑5้รHtภLšAUๆฆKCย$ต๗,ะMGสน็HŸ ScL๑ึˆ„b|. ญQTฌcไษ๚ ืไ7แ€ภ“2ฎทณ‚4ย็_<Ž-� ป'๚ฟ�สฟ๒?@ฌ�“ก๓สฮtF 3��i!��๏wพำฮtFเภ/?})Nsžพใฏ�•฿�๋�๋ญ๋ท.ั61i3`ส|HVฎ Ui�.rั<๕�JiJา\$;ฅ๚z[G จ$!ิ็บšๆ8�มa•ฬ‹-Q œRญ๙ะเu”฿X]ค 2&`๗� ฬา$™?j#&3ชแefอ‰Sgm้โ�ตฅ�6›'๘๓@จฮ�ฬฅหduŽZาลh๓ฅLœ:(0” ™q๙น/™ Oึ8ศทือศ๑i324f3๘๗gg้Avฒวฌ.,ไLsํ๑้ žนa6`H}/ ’d&ต๔�>HvlrๆคญฑF>ฮ๗y๊{‹dฉๆ(MฅฆwoณA7ๅ€ทก“glซสฅ›7์^ำี?jฅ฿›k”6vึถ, ฒูVfT@ยv†เฯ๒s{7Œอ๘บน?9๔๓L ฒz‚~•y(kุT๊™๚้ตั3วง จc†„Qซ/q�ษฏ��=”,ศญ�A๖-"ห�T Lนคตd�%ณญh~y/&Iี๓6ฦ�Mฆ DFš๏จ[ำIทŒ๚t’ผ;y/. ๒nษไฝr1๘o"��'�z๊๔iHขŠูย่Mจ$@น “JํYIz?‰ล{ Œ‡๊…i a>เ�”ใฒ.ฟŒ F2fe๕ช\K๋Nเฌn•ฌ+ภR5‡‘#€หบช ,C08Xc2ํฌฒฎๅ_ ็!ฆVŽ๒๚Hฐ.ิMAs‘„คโ ธืuฺ๊ $+]€มศ*ขXเ็ี"4ˆ*J โuฮ�Pง‘ม๑1๓ะฃื๑X๔‡ข฿��฿�}žโใ}�๚_�์$ฆnฯ/�Ÿํ�ก›†ิ ส�หาม›“ฦƒตIดP'cผฟ‰<›,งๆก)ฐ‚T�ว�pc๑^ฦBgjRr ๓PตJดๅ�ณL�TvฃLทZษษ@P็B๑ี“ฉฆ”ชWหCญN={‰Lv†kตธ‘��~๓ศc™กกฺป�g~ื่ 5‰ฎฒพQฎW3—.œ7 T.ป๗X ต๎ำu}”ŒŒŒŽA$เสq ต”�]เ9ห3W 2ษ&ํ)D†่บP%�ฌณฉุ ๅโ‘ั3ุลkh๗Hg†‡Ÿ๚%ฮ‘Aึ"*)สPR�kfkmŸu—dˆHฟฅ? .#cPๆ^g”:LPnฤ1ย”สกอžคu๓ฏ–•2”๕2"YZฌ5•?่E˜ิ ๛Tฟ�ฦ[มว�‘๗Gƒน๑B6๐†fqT;I;ถฑ>�D&pจ˜™ i:aถv9ฏdศ‰ฉ"๗.ฅˆฬ๕๓^๖ฝญ9ส}ผแฃ๎+92๓ฺ๏๐๘-ะึ•๑.R%‚เฬCqQ๊ลฅฎ2„`C@ฤฉฌKต5R๐P…,Uฮ้MJœwYฮฤk@+-ศ,ชF�FdN*EK“๕โƒเาgƒฬซ์ฉ"J†ึƒ„K๋ไพจ0#�ภซภฝซ ‰,มขตมไ#O%๚อฏ�ฤ์nฎ^‚Jษื7ๆฬยญ›ฆฏ Y9๕่-=žอPฯ๙lz@35™Nึ”-$0–”ZภFฏS6ol๊` '๘๙9ฦ๐ใ#�อ=8 ฦิ}dผ”ษw๚$�u๓w^9ฺƒฐ ‚ผ€ร ?�ิ3"ณ๖เ€�ะOPผlRซ์้๒BhSยง=โฮ๖&๏I๖)พบ3hmˆจ1ทนฎส"T\ฦtOฦz๚spค`พ…‚�C๓๎`ลP,xนฏCฒ•�ิฏ คฟ�๒+6ซฺค� ˆาข„c9ฯ๓ูๅJเจด8„ˆฒฺ๒0Sพข5คถvB \€†oภZ๏๋g^หิํื ปส_Lšุก~€M“gด�7ฦีE=x›บt™: Zินc|๊ธู�Xตภ�KIMKูZ2็>ภ_ะใ>!Ypสภ พิม‡$นฬษีซYเ�ปธำ�ั�๛๗\ำ>ๆŽn9�œŽ๊ษ,j7ืvaœ]0Mึ$๚�ฒะูคใ&l J]œ^ภ('O้‚Zs:!K V์t’] qoˆ™รmฦ นป“ฑdื(๛ฺb�ฝ�ฌy๏อŸ@เรกา €d‹uฃŒบ@ฑฦธฉ๘โ _€bซb&'ฆฬcO<…ฑj @๊5ใใใt`�ถLyใะT๋ทศ๓มm)€+r~7`S�9D†ศo!‡D|๕มผ6X๓์��6อ้‡ฮาพ3ฬ($ธF{ะ,u๒j'šIqฦมfฯ™าdฤ%Yc–ญIญs02ไำำgฬ�า=s้แวLw�ๅ๙ซ&Wˆ๋\หl็~„33<ˆฆ›˜๏M>ห]ฑP�4XJไ[ ภฤ+C„šึฌ‡๛Q)�t^ๆi9๋"G4–˜ท4>#~L ฝศ�k5ิ�%@ผ—๚U…ุB›`ฦŽŸ˜็(่5Sใ&SIณๆtฯๆ:sB๊œ๗�Bœ”ุ_Nˆ{(jšuJนจ€~‘๒Wrึสื$อ๙š†ภ๓&ป ๛อฦส"+”๐pXฒฝ%„2]ผ��ฦž๋:sุH˜n๖๑>ฌนฮTฦ.—CmI์โ��์C‡6{BฤงJ4<(ูDsl1ฟน�ุS–„)rฯซ2sRำต™็ n0že๏จฬeysอœ:q๒จ…3ซ„eoฌŸ5 !ร=k_' ‹$�ืู่‰จ Žฒ1ึ+ซำ’5RCซถ๏@IDATH้Lะš‡Œ9ฅ2ะฺีูi�n8‹คJYฆ2ƒ๗"ชงU ๗~๙ฬiซาJฤ๛ญฃฮุจ+‘ fว๚'อ�ูปฦษy23s�L?eี0๋๋‡Jœpz3Ž*/JH้aQE๑Pยท!ั I�ีXxโ™'�‰รั…yJ็ซ3่ŒภO?โเงรฮ:#ะ?ฏ}}๘๐๙็ญ๋o|�‘H,<DB-๙น‚>d๏ผ๛`ฃ ]CŠ ฐ “VB"Zฦ๘ฐŠซด ?eRฺฆ2คSP$งoe�ืืทไฉ7&ะำuUS^–B€t๙�,uะซฦ:ญOL˜อuฐˆj]‘sŒ•ต*” ข68s๎ข% dุV!‹จz๎�ืฏq?˜๛‘ํ?qยœ=‰ŒfV�Œ‚Peจwi)(2c๚ฤ)ณถด„g@ฺดgฝIs��kfŒ๖‘๗๎ฯแŽœ–lt_ข‡S\ฯIหฉEW•ภs#ศ๑ๆ•7M9E6€ชŒzร<7มณZมํ“อ{๙ฅฬฮพิdน#หlP\้ฬJƒ–yไK_4ฑ�nณ3x๕ฐ>ไ๓้สชอฬ…ศฒ"ฐฅ$ศ‡้Xฅ’X#�ืบี*`Pcข–sช‹Yใว‘]ตฤRU(3)ภ๊<8w�‚น�ญษrฤ dิrXฏ_Sีห—AฤŽ:,TŠi;?qฺr*C86๕0ํัn˜,ตย#ฟN'<๖š%รษฦ37�“3Hใf๚ฬy“ป๒†)‘ํ๋BErฐตe�ML�ฌาxiี ี:’idโzึ ูp€ƒJS€�’”สr?jๅ7OFQ%1๎๏หœขjธ|๙!LศŽ™Wi*EBฬนœ�›ฬธP<เพ ๔#ศฒ๋าู“p„5จ[นธ| ฌดฐง2ˆYB™Bบ2จฃา„q X@ฌตฬxQSฐ๖(2`_ธฬึ๚�Cำ 1ึCษอ=สZโ�ร€ํตnXƒLๅ๔�"E|ชรื 0=g‚ฺ๏ลZู๑ผฆaI(–†Ž;หK–ฐ๋… tใหก}พ๘`‰๕ุJ8M„uฃ2c๚( ZฌcqR-41ช“|�ยgŸ4™ํYBฉ๚ิ้Sd‡ฬ*ฆ: b~ๅลŽ๗K?Aย็ฒ3U @‚d^IสงอขŒผฎ_{ภถn‘ูฦษ�"h ก20ƒcใึT๑๕ฟ€S6e9œ+ฎz๙m๋๔{a7gฆฦ'Mดฏวf�oฝsๅC�$c�fosเoƒฌ�†Yฆd!’$0๊7x;?}ย8หy๓๎๗~d‘ ู78p'sษฝm’�L๏lrญ@Aใ#Sฌ $™0€�ฤฬ ฅโAบ์๓hศิ!B$ึАคi“ธะร๗P1s๒ขy๕ล๏ุ็ณ’^< ๔3mฒภEjื”pQ“.\ว๐g ŽVf^mฒy@N๛(ศ๓‘าFQ hฑG�6มชะ๒๏๊i.Cถ<ตไ>\๋ฝ~ภ"Yd)Ap�2�DุLBDจ์แฝ+ฏ›:๘g~ํฏbเ8lโrFโสyQdษๆื๐ญศิศBปMด�s}ฏ๑ฃษ`Jูƒ5zฐฝnN\่5<๕9เ~,ญCค%œ4€L'็Ÿิ&"4t.1ฦco วfP-ค—ฬํ;&ๆrR^@V[ส�WQสไ!$ฤภ1บ‘เฉฐท–hKพ‰ว9๋ๅk‡์K๖ห่๔I38sย์ะฮตN๗šไม์•ซfƒ3r๚์-tธaŸ‹0›`Žฆฆ:7m๏'ยห”2ษ?๛Oคšิ6"้4_R1”Vน“„�Iาอ$ร|นุ�Pฤ์c)ผfDZHy"ต€Ÿ}ฉฒ2gPซ็ $H’dฯ ๋ �ƒ คญข/ส๏ฬ‹ @^c x‡�ฌ+ๆvํมฌ้†hPฆ๓ชฦ=ต๙l‘ย+I9ภษมasๅ�ทอ ”ƒtQ>—ิ]&วy�ร™m๗8๗๏Cษะ†œU๙R3CญYC^ตฝไูYม*ฯrฑ—ฅ=ษ&ี=S๕~�ฒ_|lI™วJ%ๆแผฆDๆก‡.B$้�:)หgLžฝ3€๏๎์ท!>ืฆ'qึHษเร_#gฎ_ฟyM |šˆ‰0ฤaฏPRIP…ณ r‚�ำฤฬrpค›ฯ ฐ™™ž๙ฦฏ�ฦWฟฯฝ้(๋|uF 3๘™ŒภQ”๐3นT็"่Œ@gŽFเ฿๚�Ffwฃqฐฟ�TฅŠซuบi ๆถ0�วtชช:b‚ฉšCํมจY|{šŠ€C9G ฦdd( !0—'#ี,‚[ €nZ7db…=๒๘“V%Dn"u—ฉTเX"–๓ด€๐A%ฐฑบŠ:aฐ ๘Kั! ตป@‰"=cึ๙๗ู;ทชEZ๖˜“.ั;�,’๊€ู฿�ดŽษ„ล‡อ%R9t“IŠbฺฆพ๑;›�ึ]_FŒณd‹T฿Jv?เ๋ๅ,ๅŒO›็Hญ.Rท=aโ�o/A๑มๆช้Šฦอ๊ˆๅE‚[Zน”คฎ ฺง�ป“€zะ p!่”๏ƒ‚์nฒz๊*ฐŸ:0wn�"ณ‡L�ญl>สๆ*B‰Cz>๏”;จญž€ู ห765eŽž1n`I"gภุž• ท š#”~ ๒š๘อะz๓ภ L3งNš`"N‚ฒeวฆOุฎห+fyแพlศ๊šO‚x๎}๒ไ)ปฺผ^=๗ฬร(y๐œ`pๆ๒เษ@6Ss˜t๏q‚p&Œ—นHf?in�๚Uศ2|@D@ฐ Œ:œˆ ิ2v2ๅ&๏ุLฟ1ชต๐โฆZสธKRญแๅj ฺฦุฯหš–i �4�ถ๓‡ึU,hT‚F&šวM T Hฎ.�#;~”ูU–าADžต.โ@ฯ'Cสxw2sF2หa2�“วg�ีุฤ๔ปŸๆ�๙O`๛��๋฿�เ�G”๔%/�ฒ™]ซ(8Rว‰aทศ ี•K .™6eI์!Kคไ r้ฏS๛ฏ�๒%�;ฅ ห คM�,A‡jท๓”ัไhAฉื้g˜Lภ/ฒo๖n@ูย๐ฯl^Luะƒปณf^E…A้“€๔๋ฦOเม�;d�นw๎3H;6 จІ-๑ตปผ dm3WRAธ8wชฮ€[ ž98œฑ็ ฤ ๘vศ`/๑›‘ษ1^�2cdไcฑ2†‚ ไ๔ :ูน�์!™ฐ2แฮข5’บ‡ผy:ภLpmmžN Mศฉ*+”BภdeZปu๎ตˆg5•j้แO@ฅฦœบxมœฝx™ฑO๑kฅๅบ?•P]ฉซ€%คฤ‚u9rŽ๒�Ÿ}ฺ„ป1n%;/…สๅ~”E็z˜3๎ธ=;wv(๛b๗˜/ช„๏๒SJกnบ ๗˜=ุcฎelHwž!‡2ฦบ๘หwrฉ D,ˆ@“EB1ต™•สg!H๓”•H•คs[j‘ ”42ฌ๒3~"ษชฌ;™๛ษO!„J^2""E†ไyๆคF/–ฟ0‘๙ย˜ทน?6่^แ๙วฉฎLผ:.ธxฎ ฅ ปจ-bqˆิ™“œG%ณดฒ ษณgRkk–ภ'ฆP%๒*iฉฌC„๛@็คส�Tช –บ*=ฺวร/‘%ส๖ซLงโ์มฬvโ!œ=ผึ:ฃแฆœ.A๋N<.‚ิI๎Esd!ซu?59�kบ“=จ0ท…๘ิ็ึ%nซtชHa@ช99dd๓U๖(ช=Hต†J†Rฆง7ŒPยŒตG�ไ๓ฯ~๎wO๔ํ}š3ก๓3่Œ@g�ข่ัศtพ฿ฮ|๊๘ฺืพึ�๎ทฟตt๕ํื>๗เ�ƒแๅ %Cี +ƒ%ปŽศŒแzM€%๙ง›Vf๊M-iญงฺQ•(จ5X€๔mฐdฅv\ภg‹€=Iฝmฏ �=2๛Mไ้%dฤ9€\yผ๊ต•�j vlM9!ž‚๘ฟZ4ฆถจ—๖:_S(๚อoฝ ๐๐ใ˜�o>�ฅ็฿'ฬ๎�6&lw,! R"`yๆน็L -%„ฒD8ฝแุH`Nื‚zฐส�IJไน๚ N฿}� L็ิ�g0b๓cะ๕ภ์ขฤ(แขฎŒฅL็�c›`ตNภ๎คฏท\ล}€(IX[บฅ๔ši๒๓!2จ=”Eจ4C†er? รƒคๆU€ษฮฺ ฎ~TKp{i 3ป�cวmฟ{็T๚’โใ7|�\lpRdi�! โB‘?ž q–ภ %ดนฒžEฤC‘พ๏๊Xแ|T˜/๗ฒธu9๑s?Y‚๖พม!~ฮกฑ„L{� Ÿถๅส\ส˜LfŒปdFฏฟ๗.ฎ๊€;๎U˜JrfIเUร,€มY ฒฟตfIนœร106d ษ˜3ฮœ:y’๑]b�!ขYg/œFž=๙\ุ,�[จ๓ผd๗ิฆN}I€sYAฟหaก,%Uฤ๑c�่”C=7ๅaŽ*� FฺM–R š๒ฒhาจ+xฌY๕TW็`ะGVน€WAฒ…œ 0y๒คUน(๛ผจQซN™ ชฃE“�ะ`Œ=<๊๖ก็”๊ลG‡…�๓=}฿|์้/�ณ฿๛ฝ฿ห�I�„�๙ฦ๓ฯทฟrํ๊๑ปื?�ฒถ�eึE5 ส“B๐C–u็fŽ�์S?a‘O๒fp+ ซึl๋E™๊ kฒQฅ6ž.)"6คิpฉ;ฅ NJไกญbมVา@&—ส> < ป((Qณใ๏tงŒ๊นu”ณHี{ฌโๆาSc๘ธู�ฺ4๗n^ทๅAUฦX*#*VP0u™�สd”eภ)"RเN„ลาพ�๓Bู”ภp2๛ฬฟ:8่(10:ยsนฬฮสฌ )Bgฦฅ€ฺษษg˜:Oด๘ ์โsฬzFฒjw U„_ฮ,๊ธtแ9”Šฯ*uคฤุ�M[ตBย6�4“ใC(ฬ่สŒNฮœ๘Ÿ�‹ฟ๓ท�แฬ่ลOxt^�ฮtFเ�wˆŠ:_่Œ@g~#๊=Œ'ป�๙๘๔ฑhฎP=™สWศธ`๔F-ฉฺ�ี Gzฬu์9\๐'nิใRข1;ดเ?ศกม\‘๐”ืˆ‡n[ำ™อนM” ดิหมบkŠ€‘#“ช–อ6$ฉฝศQ_ ๎`NX“;5ื‹ฤ#ดQ ฆrPเ "P��\ฃF~–@ีg}์‚f ัx 0ว์+เฅพ5AVo �๚�ฤ tžkห‹gฒc๘0จ}ŸภQหL.ๆใำ๕}ๆ๛฿๛ถ“9TmL๙oƒ์๕ช>Z฿ฉCƒY ต Hq9� 6‰ญนfะŒŸ2Q‚๎๋W_" ˆง @5eฌC‘nS„z –‰n!Z4(zฝCบฒๅ& TฒcฟUใ&ˆศ™้cV๒|็๖-ใฅฦ[ูP)๖`]2}2.ฃ[eไQษ๘็2„หมq�ฌฯฯZPเ€\ขo๐ฺถg€ซ๓จhŒ๎~pอlAˆ$้๎ฒ๕ั›Œ็๔้3&r�ฒiRFp๛ฺ6จo๐ถึ!ห“กSŸ๕`ผNเ�;2ษ�36ˆR()Gูะ6C#ƒๆว/�„ฌ.tฬไTโ�B€‚ฯ�›็๐$ผๆhน'0 ็Bj!I�Œm1เง%จT‘(†PNิ ญz๎ปdฎ%วฦ็€g๋๊OฺRตsl3—ภ!V ย< ๎;I•งF]๕ัAิMึ"…ห๎, OW`W™Ks9ฤ๗tก\4สศRค ะV๏๐ศ?ลlmห.๎O๑]ๅปๅสe%šฉ%”YืZU6W>!^ ‹Š็ฐ๒<ส๛”e‘C6fข&ž์ฅ‹�อ“ย๋ขŽwDฑ!๓ฦ,@ ฝ ฅฺ๚*{Kพ#๒ˆจS^…ˆำ3ๆจUฤไณ0cŒ�ดแซณŸ๊€- ธํพฌ่ฦพ" ๏?ธวผZrPๅ#+สˆ6s๛๖ Œ7์˜ ๑*“,3Py$จ™9 ืษH0MI’ๆAเwŸบ�H๗„Yzpเœข„GฺวHฮ)Ip0u1เฌ(sๆ,��ˆ๓Jฤdละจฉ}ภตy-IaT �ƒิIฃ(SุฟdŸฅ^i6ูLaึ“”hฏL…ตกNพCi~>๊�Uาๅh@dฐ๒้|ไ'ข๖QZนข๘iBฺฐž|ด฿ E๚™J ุ“oO1[[+จAzอ๐ิดษฒwู/qศญS}Pฅ,Žฑฆxs“ทๅ ๒บp!�ˆ-bร]=ŒkAช ภตศะ{J�eฦP]hœbEฮ—ก๘ ๙โพlzG9ฟอ^(<1tฮˆุถ�๊"ฤjxต้•๒ษอy็G5&"GfซLO๕ผ%ึ>/ดcQฅ�ขํศr>œƒTสšิา}ำ ฐ–๊teมหฤม9ููŠ9โ8Dสeฮํนทฬ*„ุ�ฏ�ฤœ:u�œ=wษœB}ะฯš}๓ฅำ6wฮ!zๆค&Qณขลม—�ซฯ#kQmฅk’?‰,ผ�ฎ=cข #W}vจˆสิVTJ.ึึ)h_Iึk˜qำ็M5›ข•)ญ5๏CฮฅDขŸkˆ$†$Gฑดƒ?ศฤฏฬZ3ฌหC๙ฑธ cซ˜ํRฎ6ศพฦ$“’ฆ ๛‰ฯ>๙๗ใืพ๚๎ๆฒ๓ีฮtFเg?โเg?ฆ+vF 3ŒมK0๚อo�ม?ฮฟ๔าO�ษk�O€G\E]'ู/๚]dงธฅ‡iธxmf‘ŒญŒฅ6PญบZทน บdฦๅ๕อ]Z›bฎ[Ys P๋โ฿" 6O"8‚0�ฬยZ:‚:u[€G’S�c› ั] {โ3ๆW^'@๔ฺvฒ\s”,ŒNL˜„€๐สŠฝ๏JbๅE๏Wฏฝ€฿AŠ �๋ห;uH][yผ€/า๔h’�Qค๒Qžmm~ž็FR๏*›๊†6ญี`Sธkไ่˜ปม•XOใงฮะ…เ13w๋†นˆm๑ s=ภIorะxจป#บ‰ูbŠ@� ๑โ ’iเๆถ†จฏWfฮM’ิ฿‹˜ฉี [Y>๎R™๖#pŒ๛‡” กฃ”จฉg<๔2 M™ต2y™ฯ%0“Dฟ…„W’๛ �‰ใ'l๖น@ฆNDLา"ษฝ2dฬƒƒ์ุฐ๓Yส5ฌช‚yRw^™ u"kcŠleย#ปฝcษนžx52ฺส�W!+{Œ_^uนŒ!rะ\X7{/๋ฉ๐'bhe}อIชY‡zอ๙ณ็ญ‚`v๎ฒh<.‚=6๋`})‹) 3ทาnasทิฑ.Hศ.?ฯXลฟู(p\งพ8ˆ ๙ศฬณnK*Zศ‡ๅเ/ฉฒd๖ช2๖jœZ’:mmฟˆฎn< r”m–FคY/Š ฿\ �:�มƒ|\คN‹๋EX๋ใใx@‚ัžฐK$�a๒นแ์@|ฺ�”J‰๔��น {NŽ๗2ฬศxp/d]Eeก’ฉ=ฒ๘Pจ%dqmเzฏึtz๎ธสu††L…5XศP็ฯkdTโGข—|ฌ�…a้&„ ค๛V.๓‘ถCื•zB~ ชฃฏกเœ‰>ฺฟึŸา€5ฏ6ƒสk ฆ!_v๖ษQฒ�ชtt]ืqB ŒŒ›{‡˜‰ถ )yฯ0Ys( ฦ_ูa•[ฐVศา tKERฮง87(€ุศf{ญR@Y~wค—.�œ5˜ŒFPี Pจ็wQฮŒpอ”?��Sล�ไ๛�†็ก๖Ÿ}ิขถ(ม+ตcๅ…๙S&ผ ัUซeฉUชี‚T‘‡D•Œr‹ตๅ† ”Rษภyญ‚Bซ‚ูd“๙–ขH„W…ืmญ.C|แ€�ฆU‹ฮษ&™mค๋ sd้‘ถCฌD!5ำd�'ว‘ยN˜‘œIi๙‰„"œNฦชท{cWๆ jฬสเฅ:iื\H ๏ gฬฅ tแ^ไ ฃ�ศสธocu"w—๎ จKุ—e~6ค’€ฐส‰ค,Qi€ู r'๊šŒTš…OƒฺฯชSŠึฤN F‹ดA๖บศ=๔=|ึฐGูkื*f~ฮz‘G�-Yซ(r3zึ2็^฿ใ"yกŒฌยCgmJ�:Oš”เ9!‚�ฝ%ต?็Œ•al‘3{™๒$ฉ๊j•Wรคฌุ/�๗ธd ep)P/ะ'ษoA}ฅฒฎ๑<วษ๔eษึฉnทHm˜D$!fฮ_0‹๗๎™ต•U3=m๑๋๏ฟkv‘W2xbpj ็g\ๅฟ ส@fŒ�€7้ พีพ/„rฤMYG๛ส3&ม ๙ฝ|)$�–ิ{msอfze๎๘…gŸ1ณทh�–ก๖PI่d€I&`WU1พb+J้ฝู๊แ•^#™vŒzดIฦ+ฺ—”_~*ปIPห\gฝJ†`ศฟA๗†๐“™๕บ#Vž,�ˆ6เL†8�7ˆา…uJIOตY@T‹<ๆƒ�ƒj ย�.ZC@ฝL๕�5uป`ญ(ำ lด2๎ฒwง%J๚ขŠูื4 pT#๏ƒ4XY^6ก1ฺ๗1ฎ›ิฉ7Xำ"•–‰`Wืฐ๙ฬgž6งฆ&อ;?�ก)โmขฌธ›�(•ˆŠ%Šิ…‡ข�Vกะี๓ง% *Eแน R qํ6—ฃฃ'ฌDเ๔๑g~ษ\ใ๋นัGW“ช\ซฎ’T%(?(^žฒ�ึLS™^Š-ฒ†er๘(SFQ*‚ท๕ึ<—S๋ฬฃŒ6๓(ร4?’|ูน๛.๎ฯอฝต๑WPป57cT‡ ๑ขฌณ@เ<ส–ฒภ’์|า๚-ด z๏z้pหšฅดCๅ&)$๋Qeฯศเ›ฦฤ>•ฏมŸ?˜ุsํฉ“งPFืY็ทฉ‡P‚ฏ่†„’ กŸvšหƒํMฦD Ÿ@”^ก�=v‚š๑ก๖ุ<ไฺ:qศ Eา)ซผฝพ@ษฯŽ๕*0 zๆ:e#~ญๅ€�๋GPก€ซบSจซˆฦสธP TEสิqŽ฿ม$บฺGw•ณๆํe™ๆXG5๑mๆ_ไOƒ{W๖^ภฺอ”ฑ.Aฒใi|QZฬฑว�H‚K๗๏‘9FX๔qž๑iำ=Ž'@eุ�|๗)c†Oฮ˜๔๊}œ๖ ๎๗—ฬw^…๔)aฆป0%1ั(พ%ฌ9y†๙;€m9›โ”jฉํจฦฑฮ�๛ร”ฐ'3T™์‰PW› ?NงZภฎญุ“&‡๒Flkสว๓9๑H๖rFิ๕YeแQฑธ์y961…ษiŸ%Zิ%Bญ ฅาฯkMษgFdซศญีaญ ฤฯสฝ9ณMูF vฌ›ฒ+•ŒhŽส์๑.ŒD�—ฯey_๐œฬ{Vจฤฝ5X๛Qˆ;ฉฌ๒๘D8tžx//?ง2ฏ&ชศNr�ษฦB<๊ มŸฅ^แ{�๏ษพbญk๕Qฑฯเๅ=UJฃ๎&’๗9k](DKูฃ๖ŒRQํS>ดตปAฉHฺ<�๐ฃfxdฤlnm˜o~ภ{BZ๓ฯxTJก–‘a€`เ\m )j6ฮ 7 งยz‰3‘dฬ|� ฯa"H–PD)ั ถ\ญUฃ8C,�^&ห˜กึ9ษฺใ�!RคDpิฏศ(#ิ6A KkQH๋ภ‰Kบ+าJใำh1ŽZT�—ผJYJ-ฦขฮu�_ยฃส|ีจSV—7kฟมZ;T๐$วG’”k”ป:ฑ•e,^`›r%mbฒว6#“Hถ๋๓๑�o„ฝ~ชฏ๑‘‘นน›,-- ฉP&FW ๙tไ x"dซฅิ๘Q�<ษนYDุ7จ!o3๖#วf,ศVถJšจ4ค"`iXeBด-%บŒK•‘"mษRฏW*J๎a,%็;Y…–�AภC-๖ฃjแd�U†`[์ฑถ��ส(Šˆ mw‡uห๋JaTKิ…ฟ}ๅŠู[พg*(…ภ$U{H(kขม'… gๅhDคnฦEๆˆบ7๙ยXนM`jXเ�Konา๚ข(ม™ ้Qร#C๊'๛W�zšœ \2Ak7ฝoNž8อน_‚ฤZc๏G(๓)ขเกK…”}xิI„y๙ยพvฐ~› V{P้D(Jษอ*ํwฎ๒3œ3ฌปษฑ)s•ฟฏกz‘‰h!"=ไแก_:cueR�x)�ƒผŽ›้™(1N๒:ˆjฮ"?† ˜๔ฎ/,˜[ื฿ง,n‘›โม™G๗�‰s—็�ฦ฿�ฏ�ฅร1บลฃ้_�๘่ทฮ;#ะฮ�q๐pฐ;oี_ิx�yG๋wทฝ๔แ•k�๔ฮ;�าีๆษ&งk+@•โ@ํPTาค๎X=ณๅ†ฏ`PNษnmเฏื"�T]x›:แ‚๗วŸ~– œฯ�เOพkƒฮฒอR 4KีฐฟฝKq๒„^GG�ะ#"็ํ3ืลซถYRhตSGeุฅ\P๋วญป ่ํ‹บƒึ�ฐHเ`@3๋ถ@ธH๖iuc5A6กdท^ŒุZ€ฃบฬY‹eฒฒฃรf>ฝ คฆ`P4m,-\ซ „~ฉ—xู‚� 2`^๊9ั €ๅธ_/� T‚เแ�ิ�ฝiขNy�฿S�.9ไ‡!6™ฐษ„LWฦ-ข3ใCฝผูdX[Z2F'อ“O~฿†ŠIอoZเฅŒ๏�๖ญื ศ˜# bDๆ'[&ะฌn*ƒ`๊ ฒt5ฦ�Akฒ6๒�:ฯ#๕ ูf๊๓ํฯh^dยWสb6วฝิh5V!ำ\Fmฐพบb‚0 ชO5อฅ• „PPM:r_๕ถ—1brมรธNYˆสcTฟƒิ<งฒณ๊„กฒ๙Hมะ มพ ๓k]F�LM๊ฒ•-ญณf”ฅฮ์ัV“ oCHO๕ู๒Ž่ไไอญw฿ตาใ&บƒิศ˜r”6hฝeณtะ€ุฉ•ศ@๓wำาบ ˜8Jƒdฒ7ํ*�งฟNฒX~๚/GWW๖ww�Eโ�•2@ZB^ธ8X๒ฃษ>จI‚อX4๋RH0๗จ†�<{)|฿ศ8๋(๙„…ภp ฉ7ฯอ]๓ฅ๖v๘‰07�Mu)Tไ ภ_์๛h#Š่+Žิ/ชwฏา]ฤC6ฝVCbxX"ๅtไอ๐bYT %ำO7“ญต-Sวsม ่€ธ‘น�๖๖ฆ%pิลฤฒW�ภฎเ}ˆ2ขฅvŒR„0๗$โl �Fฐ QีC{ี6s/ย5YŠ=ำวxถ๒ป€Vo�T๗—โs๑๒9ซ`ZG‰ดฑ๚ฬw่”g๎๑คZ@"ํ‘"„‘‹Qจ-#› BŒฑyข �t;ะ8`Hœ ’") ผจŒคJะูฅlถ”2“tJฅŽ9ชท/cRf<–LฤXเฌฺ~ญE‹ฮ#‘:Rจ๓Kg๒ลษ๘p๎Vท8+t@กT๒@๏#3U E�ฎฎ3jW�โ\A8bาดr๔โ[ ๙ๅๅwฆคRฦlฏเัมบธtCJJf฿”93ฺtƒƒ "ษ+R‚๙Vฆ]๋E>ฺƒZ๓R๎ˆ`า�ฉ7ธHz7๏แฒg๙�hA:4้Lกr*'ฤฆิd^๖็ภ๘ ํ<BUตCY@?“๊^!…Qึ์6็‚ ฺใeฮ 7ฤฏ”5ˆยไงE‡ฎW‚<ด]'8ฯ=จ‡"์ี4 {ปRˆ›ž>ev7i‘‹if๒ฤ ๖ณ,ฬyเว"tาyCHˆอUำM;ฦ$-'ฏพ�6�6ว'OB@ณนบd๎\y�šJŒ .�ๆฏ�็ฟ๓G'/<ตoLWA;ช๓ีฮtFเ?ๆtˆƒ�˜ฃ฿y๏ฮ�`ตี>8๘ม��;ฯ๎๎งKo]HX[ �ฌQ„ศส)cธฝ T ฐเ!  ด•๊ŠEmMฐjฃนrUj™1Œ"/^|ˆเ.j�{็-‚มš™>yฦLMฯ˜ท^{-€X>cาทจ๓%ศV ] ๙ ๊6ืืษH!‰'8,hข˜ฯI~ซ€8กa�ศผ5IืีQ”ปŠ€๒–ฐQ€’ƒ๛ทo’;ดFwส4๏๏ศEภ/grษ�แ?€@@ศ๔๑3flr„Ž]Uณ8{kห๐ัM˜ญd๓ดdS-‰pl•HŒ:@ �F๐KพNYnภm€ฬ{$�cณd๊‘@ ๔ข�X2๑๗ž „–่dก ๊%K–โA2i}ฅจmW€ .$?…ทB/dี“c&S’์" Jภ ๚ก|เ�ฉ|Cฦ‡99ๆ็Psขฌh7q9'๓[eฬZˆt�"6ฎฟwี$�“—โ{”‹PW,0คv๒\ฦG`2๓กา�บ�;~�Ž๗›?F-ย:ฉ]ฃ;=Rศ`[Œ0h�‹ฺฆฬ�๙{”TPRภ*ฉ[Aปฏํ…�h™ปw๎๔›f]’wคฮ9ฒ‘" ˜aTฟu€‘LZƒ"sdž&7 ท dอ dš�*๖†˜hpีว๓ุ:2�D–!T‡ฐZ ›จ๏>T Mๆซๅ!�ส฿s(HFฦPZw˜‡ž๎^๋ ๑–„^_uฉP-ดถB6�G๓o�W�็ฯBmภc˜k~่?๙™ใ;๋ซf�๛ เ& +ภฆ:๕$`q{6๎@๖q5€—า ๐8v๙}?๓dœ๛-ฑ.d˜ว2‚0€b จำณ’yแzJ{�ib]1ŽNภํ/๐ใ€๑ž|™8D คึทั้$…‘ศด0%ค“ตuภžป~ใ$ ส!@z2G>m”๒E8u๊Œน“C)ล"†ภCrฮDช|ˆg L,>ภ๓@p้,BAค๙Qšืƒœah๊„น3๗‘5๖๓Iญ –ฯว๚โœ aVwl ‡๎(˜๐A&pNน}K�Nืƒ}ฬ2ฃ–hRGŒฬม–‰๕ ๑|N๖นิ+์พ:ๅ CƒCฌ‘ น†,�–๖0ถ๏ฟ�Ž9}้<ฅMQ“ๅต~ม๛�Ÿcฝ๙žฺv8๗d๖ว’7‰แฑ#SN�/ฬ9RGํค.>ž'่@ใUyL�ชeDdB>jn˜^ฦ ‹๛Tฃ๐j@ฤ”Q๘ธงฎ(�A8‹YHพd€จ๒!?ภ:�ำ%ํ ๋ŸRฮฉ"ภ๛c?ํEฉ D—(ตุ#๋ฏ�{�๔๖:„!�(ˆ†ถ๖ˆบ˜p^ล�ผฺๅฺตยu5๏R;ตd�!˜dN*าร9!ฟต@”"ฬG๙Nป๏ึˆฃVญู*ค=”\O๕?mว4หณชLayqgึ๛๐Yกะ�?DIไฯ์%ใ_‡ ฉWQ q"�5Fะ„I[zฅ๑rณ~˜�ž<�,./™€ฮํ ๖$]�๖�gฆgz๎๛ุ™ู�ู ป ,@�AขBชLู.;RJ‘•”Uึe%vbหฑDbูr‰ถขฒฃ”‰ฅX Yoz8า้ฅฎ…ฯ‡K€dะžซˆืh�a;๛ไฃฟ.[+ส ‘D0ฌ.Hศž;”oAtN฿พฮ=๏Qั๕•Ÿ๚�ฟ๐…ำ/�๔}ึนœ~k_ติ"P‹ภG"5โเ#1 ต›จEเ/F<ษไ๎ฟ๚_�แ๏พ๙๚๋ฃๅŠ๗Qฺญ๋จi–�V`%“แ$ห1NFNY๑@Y™F๖4™�0`#€QœฺdษศojŠรฺdัŽžณ�#Gศ2ฯู=�ถื1+‹’ัั=๘๊‹ ูๅwฯs†GJ ะ[&ƒฎ๋่k˜ฺz•)Œใบ]ฉถU#e่๖ไlŽฬVfŠ2_“ฉ`ธท=็ฺษษO!Œ๛} ท� _"c, ฎŸ,˜Zึแ’.ึF ฎG{7๘{็ืญ 8๗y5ธ๗ศzสภฌ˜Gฬก_|�jส[;ฉ%&[™h‡0ช“d[ูณ8}่C9™๙า่Rภn9ฌJ@2&1d๚2%ซnๅf/๐็< @wrฮ็Œ(: gย\C��ณ ฿pฮ๕ดyˆH]ิŽž>aiZ'�\šล๓q่พE ๑’d3ศบKฬ•!ญpภW ณ๖๎nJ:ศย2ฎŠฏOอ8eวษs็œAขภฟdำ:8ฯโี'ซ~์๐˜๙–0ฝ[�ต^z‰๋ๆ์ฝื฿ข�]ม)(/e$ƒ2‡#ฎ@{€ำ๕ๅ€H ัวNููO~านืู๋)ส.ฺ๊ศพ2&๊๗~ผkศ: Tาฉ7้]„qแไ�>(บ•d]DŸ˜้3” �ฃ„&O†3†วF‰ภl.PฒA•œฅ…ธFq+ร๋๔<€'ˆตUซC ก~๖›�^ื#/ e3%{ฏfˆ!?฿E•ฒวsถb48r๔ธ5RูTE< ม๎ํ‰ฐC7‘ฏฐ6d ๗Pพ’1_ื๔๘ฬ'ค|Q)†,K5rl”<žKo)/M้ภฏ “P*€*ฤV €)N=sbe•ฑใ๙=8G ฐoฌRบBผBิจซuฆŸ ทภ_ๅ‚d๐ษน5—สฤš™"_•ไ่5Rืธาฒเ�๛uะ70ไค้{)Aีฤฃxแ51ึซŸ๘_ฟv?&|๎Aว ”"l%� !\Q+•ษ�ฬ ้˜‡สฮฃ๕ฑอ๙ซ“Dฒ1ทบศ๚fผิ]๕=u�} —Ž9‚ฒโqƒh�q`0G—“e 22�Gi nQฎูDปPญU†lJ็��Z5๋Y]Rฤ9ภ๏771m„9rุ�\๛SW‘งสˆ๊‹ฤA™ตึDKสฆถHKฺ2า9Bชญ๗ ึš—ธฏ.-Yฒ›–ˆ[kถภัz่ะจ# ถ!ฑF+›”ฅlฺ8~ึŠ \ตoI…E-ณปฝส>'G|M Vร์ษ๕ธ<%ช %๖จpBส Œ]y>?“G� +๓๓Nึ�E dุ6เ� ‰;D รร9ฦ’ioYXีzฒ”:"DคzQืH“ค.Z—๒V`Sdฏไ๓์9Ty>ร้์รจP%-^บ๖ญถฎNปq๓Š}ํj�}Cถ‘#฿•ฮŒŽŽฑ†ำv๏๎mF›นฦ๕๛ioH\s(04ฯ‰kฃิ3ฬป4^,๒ซู�ง‹K๏H?m ุ.-oŸ}แ“ดฤ\G…5C+E”ฬOๆsm-vๅอ๗์๔™Qศˆ�ผ~๛นcง’uA Saฐ^ถD �+ืญƒถ‘š_้โชut}๏๏�ส?๛ฅŽ#ฯฯ˜�Weื.R‹@-ต<ฌpZฌ}ี"P‹@-?ธ�้Ÿ}o๑ำฯฟ๐๕›ท/.”s�8ชor`q˜๖)kผMmตHี•K*ูฎซ1็๘ L'๘ฦ�ษj[G'๓%ภฏว^�ฯ>g-�Y@a,SŒ,โำ/~ะณฎžnkฦี๚ฦต ^ŒึA @O@\F‡ญdWL84 ˜๎‘y’ใปdซชที๋”I๕A^ศ๘LJศ•V9ลย�]ไŽ์•๋๋ะฉap"ำ0ljฐท฿๘–ํญฏX„๗ี!�ๅpฏ ฟ_ฝ�ษ์I9Pฯฝ?ƒข`Ÿxแe—yt๎๋dKKิ—WศุfE6๐ซT dฺ’ใJ^โp=7yฯ™tตrp?46ฦAu‹Zy™‡)๑ Lโ�ภUƒŸวrIqg;๕ภ@IDATo?@%oญิ;OOS�O6ผo^ฺ;lง;cห‹s€ฺ9k หืษ>/P�x9�็2ฬ BFจ}]�ะญMNR�O7Y6} ดuvบNส๖ฎrิ1* €ฮฎห|.?ฐ ๊€u๊ีg(แ˜™˜wู่V๊�}€•4เAตร"Vิšอี|งeoพดรDQ ~๓KิฆCด(ซฬugO'๒โQป ‰ฑŽไ]`จฤs็x`-6ฅ8(Qj‘ฃ{€ๆ_EŒดy'"Kญ๔ึืiฃว๏Ktpภyƒk–yญS*0พฝGhผ/ะ!่.cž‡ P์•ํ�ข�ป็ะ!๋<๗6*e“ร2Qƒ*๋j@ Pญ๗”ๅญŠ8P?ฅ)2ิt_์ฺ d$H]=ฌๅๆwŸ:q™|ศึV‡‹๋{ฤ6ŽVผ˜…ผใณใ\๋,ฯ๘Šะ๒๒๚ิ๗ŸQ†ฒ�E†,คคึE&pงฤk Dๅ‘Y_d�ณD)K๒sฏdฦื&็1,� ฃร‚-ฯขZยผ๐๊๛๏Z ตL(ฆ›”h0ฏตฦD�ฉž?Žษก ๘ช๚3ๅ)*CRlาฤ.ห_eฉูal๔่Qศฦฐ�ฟ}“5ฬ^จgg/a‹aNb,)o "™Dํ…ะ๓ในิ!๎R›+<;DํB{ W4๏Dฮ554น็าผSๆ]๋ตLxm ?w๗Ž ๗าๆฏลVfน�AiS เ ยฬ3ๆZ *๒ฃิQวใึ14l็žxส๎>˜$Ž>จ v๑Qะ~ิ A'ตDŒq‹ใ็ฒ‡ƒบิˆฉใzjI8|โ8Jฏnไ�๓๘‹ศหDฬTภบ‰� Šu’ั๓หำD{สWJ�๘๐ฑ1ž�@๑@ัƒ#ฅNำ.7N@ฒํ๘ุ)๋๏ฒ%๖—……�O(หRว”aฺฟ๗yv0‡ab/–ึช๖s�<ฏ1ิžชh)นฤ>�ำ฿OŒhsนพa]อํ�;_ŽHdTyT Rฃ฿พวœ\F๙B�—P6x(uำพ8q�>ธzรฆ&ฆ!Ž=ฮG็�๗พeใ๗.[ข%�๕Ÿ�้Ÿ�;Cg?7n๖สมจ�-ติ"๐Š@8๘ FํVj๘‹W^yฅ๒?�ฺ?M�าฮ�ƒฮž๎ื�ฺ�ี_ฟvํโ๎�#๛ฒvœแ™VŠ" บ-pบๅ+ภแอR†)9ตฎ!€ซฬ�*ิฬ*ปs๖์Y2:y›Gq ์Sœzๅcว๖p๗ฎ,อ�ๆฝ�yคๅ’ญสศŠ„:‡IไปdLspญ,.q(่ิšo—์“ €šกรG\Vฮ๗R3จ&ป@†1œ๔{ิP` ื!\.๑~ฒb›K–โ€\ฯ๋B(๘h๋๊?dG{�0ผณ ๊“eางฏ:๛Aภ�ย์ค;ˆห€.Gf7 rp๗๒’็๎“ํ�#ณKฤญwhำ?๊oษDถ๔ฺ Ÿ�,2�ภๆYaŒ!=a@ ๋+;.YธŒทโK๔l฿!šHดƒ5›Ÿ™q7– œ{z;จK๖ุ�ƒiสฦ(สม:Hญธบ จทyฃGฅUฃxAศ/`,(X€oศล1v!ภท$ฤ^@|๙�ฝkWhธbYZTฆ9d๏ฤผrLิแ/€ 2†น]ยภ๛ยI$ใ>ฮ้ณซจVdvVฌW9ธฏำ™#โ[ožGผ)Aฦต2ฅ%T-vสฎ฿™ฦิฒ�๒ZH‹(€\ัผq่— ~ฉ{ โGfR>ˆd)Q\T-6ใ,''u็ภs t ุyAศ-ฏ“แ/ถ4ต๑eฒฏํ-ไถอโi7ง�L ‹ณd;‘šท–=๋บQด`ข~?ุ�ตO�่qท<ดฏŸ๙•_(„rีwท6‡$ ฿ุํ ฬ2V2็L"ณw@ŠนถJฮ.ษGkสฑGฮ’ynq€N~ uฌ5๏�†ฅHโู^ร๑ต ใ๑ll๏sฤŒบ จฦ]e3zฎฤŒิ%Jœณ~Dูk‘0ฌต1„…€jเ๕€�๎&L4๋๒7ธฒ‘;w>pkXู}ฉt’โGฯเ๕Z‚มมS �๙mxชธVฉX2ี …คXAƒCYT…=B`R>y)u �๐ จCuด0;eำ ถห}…Xc~_ีทP:‚™žj�Wwืl‡นแ๕ก€BU`Šษz™B%ไ๏g/ˆs�๊ฦก็ีพย๔กฆ…_™/ซ่[*ฅ<ฤ}๚l|�ฏอ9๒Hเ�ร�3fณ;ปO ฎ[‡•ah/JC~d!&dๆฺ@<ป)eh˜๛ุ?0W๎Pเนใเ๎i`ฝรs)#สk€,๐.เฟถบŠ"$็<:Dˆภ CjจฤจQ–ฃKศ:ญhC(…Vืำ” dM˜ Š)s฿ํ]˜ทข วใลรEิฒ๔๔ำOฺ้ง>ม�ฉsm5—็—,ฝ•ขล)๗ษ�(•Y‘_gP|œ=†!a#e1˜ุสƒ€}ธ๋่จ#Šw7ท!ั‰@ˆ”๘ผ"าฆ Jนื้ฉIGDƒ(๘j๕+๓ลฒ”)"…๔œ๛Œ}็ช๒3ฃdoQ๋ำ๛4!๔(d �&lC&wb :y�]บ๔พmRrฑ9นตฝG—›5~…ะิ๊eฏ^f]ฃdC๋`aqัV๐ู™Ÿ[ฐUHง…นUบ๙�ต{ทุ่ใหไ๎๛อฟ�~๕๏v}yŠ7hfิพjจE \jฅ น!ฉ�P-"@๛จฯWซWxาซH๏�ส’zพ๋เึHฆฝŠ๔Xž’ๆ D45ลศฬ‡]ฟ๓ชน:Ševณ`“/ภค€7o\ฅA–’jฺ‘ูnKb๔E;ฦUrX?}๖œG�๖ญW�ุŽ8CfตhหKtHเ€จ Y /MฒษjฆษŠ+�™ฆ5` ๐!Ws�Y�้e‚˜็ปZๆ€ศ้_๕๓^�jgะGษ–y๘ฝk}ˆ4:W@ฒN�ณ\ำีซ]~๒คr|aX฿ึ ภ]ฐฅทt‰ 3*ณ6ภกV`Nท2๗หนXr @เ”ร?‡Lฎ"v๊ฐ43E†CC‡Jt(�๊W~?‡i$ร�.ฃsฒ๏,…3„๏Q2ัึูf�#r—h๏˜ต$ฤ…ฦภฑE}ฐษมxŸ,พ‡xธ๎e่œช‚๛ญƒ\ƒส?ไi “ปิ>QU}ˆ?@)€ู›šทkท๏Sn"gtส5้RD‹๊~ eB„,ๅ๎nB5ฯR†H๐Dล ‡J&ต?‹เรฐฃฬ$�‘ใGํฤูGmjeษfiXOห=•ฺวšใึšlq&p?�bฃ�บ~ฯ&oำๅ๐– ]gIภ˜kชึ_ I๑V_zษฺB�Lชศ2ญช ฿ฏRo‹@ˆคทษ–b�Xย$ภธ1š_Bโqส"ZPa๔๕ บ v/uXQฯพ a&๓7ืๅ\I\๑ี$Nธ๛มu>Uช–๏ิ‡๚5{๕N$Iฏะ๊‡ล…ภ�A]น (%ฟึs6QRฑมB”โFพ-dบต�d๐ฺฺุใสpึถๆQต,Y๓2_Xต}jฟv—yฦNm'ณ”๏ศทcwk•Jข‚ไ๑\ื %เซ๎"]ชคเแ ธพ*�™_€7\qนใ7v4�ฉใ'™ฯx|p฿๘ณฏ3NจO˜ƒRฃHYา”ฤฤŽ๑“:„ŸบkIกฮ*SRY†d๑aค๊2Jฌ`ะ(โฆH7–*@8ตK{F”ญ”ฺ ฦQ;1Ggn -็™`ฝe์6ฆฅล,%+ดqิ\ัQ œ แPไ๚2ฝ๔BŽษ�tkƒ๕รk2[x/ฐ ”ษp็WผB�ณ/a๊่๏�นษภธ•ฟŽหฌห�?ภ�…šX3ป™tm Dก NžZ}๙Lิ7AFแ7`ฏุข�Z9๚ุ;›1‹ํ;BkIฦYช›dู& บฟฝ"ฆห๘nั*uืถ๐BQๆ‡‹ฦ๋ญซo"BพŒ {ฎžO๋‚ัuู?s:ภ�-sีงž{าฎ|๗->wŽ-‰็c“2�ศืC. ุVbำ๚0 e�ับห8{Z฿แห๗v�D๊�๓ฯัb–NฉMTIจ†ไลเล€“ฯoกD+ใ/•—(&Š%(๕ุƒ4\ฯคม7‘Fฦ}FQY๘xฏƒBfว) |�ณBG๛๋~•=…๙ ง่žM๋?กโƒ ๑#%ˆฺ”†ู�–f์๗�OL™—i aแ_ŒฤฃสFข(ใt?NญเHtka�ำ#Dซ๋”ฤิ๑>๖ฐx ๓่“O�ฟ�ล_�WOห�็๖ชusจ]ฌZj๘๗"P#�ฝ€ิ�X‹@-?˜pๅ˜ฦ9Shะู๋ฦtญยAะ›&˜งด ็๒-๊†า”I�M‘K#‰o–36‡i€™ภœคขQ€Hœ๏‰{w์๔ฉ#๖๔“Oุ,โซ—.ูญ๙๊ๆํ์น'มโฺฺข #ห๏:ds’‹๒_3% ฌ็gฆ,[r\สx้�Šี–N&Š[€๙I>วิdห_‡�-ฺB๎sจ๖๑�aกCผzล‹Cํฑjผ]’ฑัgส—@e'ฦyศ–น'u™ไปต-A™J:J$:ฉ�ฆ—}$ดK็฿v๕฿c#”" bคืO�‘xt“๋�b-คึํฒtŸฒฑ�ล‰]‚z๐ ู๊Fฺ๊๕Pฎล m%1ฐป๖่#ฯ�}ุซ“ฒ›๘ี+ซหหd•ป�%Lฏบ1S‰‚๊ํๅ8ฟŒOARม™ุี6 evQm(&1$เ@qŽฎฑx“ƒ 3ZจาIฐ[ยO 1G%€๏ฑ†ทˆAๆH> Q'ƒม:ไโ(‡ภ๐ฎ^�ซlผืาผLCจศ*๎™๘vฬํ:)K#~ฏ}๓5ฬ๙่$ยš๑ณnำd… ˆR(ˆ๖๚)า:R }ฐภH4ˆ%ะŒฏ2ฬxPfฃ,6ทฬžใฑตฅUJŒ‚ศ�ืษXSฒƒJ'LiLu�์!ีณgพญ ๔๒:`}ฉญ บ‡(ป@ล B*Z๙,G@2๗ผce๖Ÿื†Y�4m#€^yธ์‘ม�lภซ;z์„]y�ปdค)ท`T�•)มร฿$D|ึ๓>I72Q…ชฃ„ b†๛ุ— ‚}(hO๒�ปฑ1ฦ ™ธIqฐC{มu/สขูeJ” Xฃ๒'P‹L ๒‡ฯQ r‹4j$�ทJVd‚จ๑Rท่m๖์0[†•๊�Hง1H๘)Y8m‡ฬศฐ–๏Ž฿ฒำงฯ hjr๗าีีๅสn}๐�ธu�>�ษ—ํ๐แ#๖�;๏ุŸฝ๚'(<  �ึ1ฒ๘๖U�โZ2ธ วšX๗Yป๓มmไ��‘� „ณJผ๊๚มุTำ”#ฐ?VซD<ƒ”\1X\0ฦ์ผฌcชˆ:dQ\ิทเ;ยจe‰u€๕*B2ŒOษ๖ไ4{� ˆ3ิ$L( xค่๕๚R็7]๙น1‘นศ((*็Zฆๅb0€…gุMฏุ‘ใƒ๖าง^�เ�ๆฯ�5าเ †ต�ฏE vjฤมG{|jwW‹ภ_„ฯ=��oั=แN๊Ÿ๔xฎ�๔6‡็๕๕-kะๅศๆษ๖g9J�~ๆ�ใแyืVฑยกOญ่D#›P,ดB �wf\{[€2Gt ˜ฟoป๙๋N๎;z๔˜]{�" #;ภF.์'‘^ฏ#หอ"ี๗๗9ชFYฆY:�หล\ฆbสึ7ถ๎ภ3ห ˜๏Œทษœ*�<ุว์�Oeฬ9@ pR�Brซรชฺข5๗๖��ข๋cQZ‡ b~ุ้๚ฝงฉ›�ก�gu2ฏ€+คดU€~ฐฯซฎ~Ÿ๚�f‹ป€\‡|ูJษŠ9หrุEยฌG‚ณs/พlณ“ทฉกฝฬaท™ร>.^'“+`2Gฒญทงx2œw๏โ��hฒ|==�7Q;lา๕O5ๆ‚๋ต1€คP+ใถuโฉ–ˆ^ภ6p๎๗:A~ไ12k;67;R M{Eะ–8ุห็Aูใํตmw๐ืตUx5`”ํเ#cฌvk^�yฒถqาภ(<0ซฤ9Ÿˆ"‘ณ๎พ.ˆNj?H†ฅT‘ผ๘์้sถ”๙ญ๗�ฑใวO90W,NAีซu&๗ง๚sฉV?฿ผwš๔ˆ…s�Œv™›d�‰‡ฺpfC2ไ้ คVs๛NJRH’ืฌ%ตŒุะภ]8�ฎ“ฺง�{ดชfrวฮฒกฑร2ห‘นtn๗€ผSd”'่ืพ nƒภ‘: ฺ่Bษ2=1nƒM(ašศผcRจDR~�ล๏แ~{๑3ซใื.Nขฐ 3พสภช�s๓Wfvม‘P๛dHรR  ›่�Z_รyพb ฒ+ŒA˜าชD@ต’ƒ�lBzจถ[&€9ภ๐>๊๙M๐‚๒1ไWˆ7yQpฃ—โกฬDˆศ{!PD@Iน"B/Ž'๋Y฿;ถฐผˆ‹�sึI3>%e€ฃJpYWๅ“�๕ฅ๏ธ5/ —eฎpMeš‰ตสr้M|Gบฌฬ=9ต0ิึS~9X„ฝ2ฆ™(B>8�mศถ>HŠ"�T> ”H�=˜งฌซ*๓ณ ตป gL{†นฯ“DาAํ EXI}PิชCJ˜ุ…!อfฆ Hx5ูjลฆฝปวํ9!€ซH•สศDV๗"๒Rส•”3U@จ:Œ4๖ฃฬฉ\Fฅ ฌsžญภz�ล�ลq"3ฮz๊๛ฅ�(ฒ†}์C๒ ธ5yลฦฏ�ๅ”pํ dckEญ5๐"7ณจ  ฬ๋ฦŽ^๎0ฎอ๑vช ๎Yฦ)ื๏�ฆคrฦIfปK…fส๖ๆMออ~!ฃฉ๙;8|ศffg์า•+xฝ`,ศ%Fz๑Ÿนย>šE vย๎�ผe็฿9—ฦฐ=๚๘ถ~g ๒ใI‘”Gม}ฏญŒฯBr(œ�ช€เsๆš์UHสฅaๆ†‡ฯc+e€ภฝ�S,ตัJู%%P…นU‘วs‘งณ<ž~๎YWช๐DF–=ฃศ^เ๓๗)ฃโ๒ฬq‘ฺ฿e4‹ฟŸฅ?หะิC]•<๔o–ๆณ 1ฅJ“1mาทTูต�Cฯmœ<9v๑าฝ›ิใิพjจE ~(๒�}ึ๎ฐZ�ž๖ญ๏พฝ๓ำ฿~๋^๙๊�-ด;•ฺ��Ž’ูก>์lTศ)‹แp,ƒฤ$mฒ”ฉ(—.ภ'ฉ3ฟp๘[!:3=adn‹ ›š;lq‡q€f{฿5ฉ�H�‘ ๓w@‰Œีšla~† ฅ’>d2จฌ4gZฒจ๕dX—]–U*ต'” ึบฎรP พDV�รฒˆB‡H�›z„K!yพ2F๓ัึkqcม†Žู๐#็lV’0usHTฯ�ะg�แ|ya�e�ฝ€Rด#{–ZWฦVญํศสSŽเAj-p-ฺ"GฆญLœค| ดก�ๅฐหAVไNๅJฒ๛e�จึƒ<ื*†<Œƒ๊�f‘ewฺเเˆ�พt�6V๎Ÿ˜UAHŽ}/ๅ„[ษ nฬฯ’…U E,๐์ูฃ1Tฤ%ƒ1๚ะg |<๏B�H�๎gฌŠ|nz“L01*3yˆe่"€๖8RjีR+Cklไ๗๒ˆ` ๘�๎^ฬ+D9๊ป(๋ด๎\แ;€ำํจ'ตโGง Aฟฝ๑"€Œ๖}9™'š‘iS>]ฅ<ไนงŸtAT๐93sBิNC$๛%ญWษ Bfr’fE๎?h'OY๏`ฦr๕6vb2ภoGตถ๎6kแ[5าลกkฤํ'ž{ฦšhZTlฮิู! qCส�8\dพF‘ณืษฉ^1 ฝOน*%1ŒK+ |’็)กŠฃ�ะš‰ข4P+H™ž*#ฌr eษ#(vท–Yหิ�Cฺx!๎ศK;ำBŒ0\rบžV‡Jgผ(($ลฯขlจ0Oไฝ!๙ฟ&Jjk…�ฃPmBaัไๆwยo€,ะฏvŒฏ2Š๔Cยิทด&ุ้ฒบแŒA๒>มใ(ชจ‘แริยฯบ๒‘nn?b=y! ๖๗ณึฤ{#€]ฉuXVึ˜lๅ5๘ญเ%‰5:CŽ9—�หxpี€ิ2bž'พท฿=osืoั5LบฦB "ี๊จf:ภhฝชƒ๎ท …G๋^ฅH2‚‘มฆโ๖ฮ ๓ก๗่a๋ข๖ยทู*๕‚|โฌอFฒ๘1ๆวu๊๙ซ์'ITA๕์กb_g๘Yุกฌ๎U ~meSิI�aฌœม!jก�‘{์™งlsห9|PฆyฃดzE!„ศrตฌ๐ŒZณ9g—ฺOดŸหdS{N‘็ื3I IL<ตoว’  \bQ% จ—ž{๑Eฬู๘ย‚}p‚He8ฬAว์๒o1/ใ… ๖พ"pดKh�ชคA�$๒ณูี��ƒฒค๙ภ๏ƒyใแo’ Sn‘ผ�_�—๓— 1ืฟ๔ฅ฿cd_yุหปvฝZjจEเกF F<ิpึ.V‹@-�o#๐_๐x๒�วๆ›[š�เ๑งŸ๛ืAฟ๗ป;�ห•tj3์ฉVb-อ.ณ!2ฦ’P+ /5‚$๓rฺฮpX–~ด30<์A#™ฎ๚์็ญภkBศw“�น…รํ‰ppkj"\‡wo�@z[็ไำสธส”บ‚รsฬ::{8< 0ฒ SสยQ>‘โ๓ƒeH�ำ็‚F คฝ�˜ห”บ–oลA ฬ�FคSยYcณ*Emโd8}๛YW\สษ–^z๏ขญb ˜W-ฯ+p%@'ยd—Œw ~$žไ3ƒdฺ๊เฏLm•็•GC‰ฌ ฝ€VีtKมนีีค็ษบ๚ษถซ]`,ูhรงฮPฯ�pผiื.\t Uว*2�Fฺพ•‘—หฐกw|Lท" bชฮ ejยๅ˜ฎึ˜9๚ำ—ภAฬเ”9U—);$ืUษ†[•ฬเึฺบปW/^:ๅ๛จc<P(ำ,ยAd‘J๎ช•,€ำc}��LŸํ โ@ AฺGๆE@p@/๐lMILื๐ฏธv้šอAจ๕fขขžr€F€A•ฯ;}๚ธฆฟ๛ฒอNฯ8Ÿ‹f็๓+ภศะขฎ‰ŽŠ=จPาd?iQ๙kิ'Bดแp�!@[™ฬ4A฿ภ^ฮ'!I๗ŽzT0eb�ั‡๓=ฅ๔ !�šFSo๕”Š์ ‹†�แ!ๅ ธส™=ฺูAž๒•‹ื)Ÿ8h9ˆE฿9๓ษO�ฦo�๖ocž๐pฟ~็•฿ฉ�ิO�5jŠ?z๛๖†บpส†\Fฺ•ู0Žjญ)U‰JuBO‰„bูˆ""A๛8eด„้…tJฐพ�aS3๓ึ36fจZZ๚๚\kว“ใŒ+ํ๛3™ชด ศœ’ื€ศo๙ \บเ0็ช%-สบณ†๙; k_ๅฤ0Nฬf!ฐาิๅณXน6cล๚Q'๓MPุ0dG•๕น๏+r฿”’0๏ะE6ฆ๑ีะ� ก eิ#จ$t�ขŒ™ž๚*2ฏตCฑJMัฬ—ต๙)nS„ฤง))rxศัต์ 8ๆ1\�—ม&ืั:Œ@‚…น~†}ซฅฝ_…Mqb}–ื๋ย๖ิณOC3xm๑�็๋$c"ห3ํฑWaิศ„|A๎ร|Q;e่าก8๊s#ท—qํ ]C$�ฺฬ„ตึัa€rฐ5ฦ)ตน aภ�‘ฮwFณuŒฑศ8bแG!ฑƒ A๛X]ไiRคmฌฤH"Bsฤp9ป‰?มaบฦŒaธlsำ๓u”–๑™ฉ;ุw– oง&งœ ผ b์yaฦฟี„>ท๑Ž˜œ”๎ˆ5�‚ม้*"�#๘Iคล<ฦฉ›๋›ึู’ยoe20L2ษี�dBQบvฤ€�UАLฤCา‰ ’าGญU5ฺ'U&%ฟEะ eoฺa_=v๊ค8sึ๐xฐD—ๆZ2p๊ม 0.{_Ž$โูw!F๓yศ`๖`ํณ!ˆ_ตa•๒@พ.šฏEๅ ๅ ~ž7ฯฆฆ–’ฑ˜฿ฺ;ZฏH๓ฬโ๔ํซWๆ๚oฐiืพjจE xุ๚k_ติ"P‹ภ��๐xพT4าฌ๎[74…ฟภ�๒ๅ/%/_ป๕โ�w�gŽฌแmวล:(*CนCfะcฝ�ึ38  NY;๕๏ห๓“d8W�ตžฌํ6™ท €ทบ ่PŸใฎvY{้-'๕เW๏x9�ห์Puษ/[;ดyใ ^HŠ"…^งฎ>Nfl๘่1ื“๛๊w�uuฤ2,กIUU๖วส ,9|ƒy)dฎโ9p๋ฦึ‰ไพ133k ท๎Yja‰๗๚lawq2YT)P๐œ^€Hล—แน9$ฆิท> ‘"ฅ…ไถสf+๓OZ‘็่rˆ0๓8”5U๙Cp“ ืxฯ๑cv็�->}สp๋7?@จ 8ธt๙‡kีัถฉร@ž_�1L�๚0X ษตร€//^ตžฌ๓ึนฌน@–�œฬœ{;1f๗o�ฒ้{‹x;๑ำA›CบJ8"จ‚ฤFืวค�r๔’—๑คJBิ_ฝZอ๒M๖๛•฿C™wEม��ข“~oฌSฒAmWฌ’ ฅ6™ฯขปEึ :Q�s€?�ฟjฯซ21lŒุ�;w)ƒA>=4Œ‘Yศ9๑ฏ,,Z‚ŽMฑLื‰ฬE– G๑ุใgจEŸ$ป�, ˆODQB์sฦo๚;Y๊๛ณ":� บฟ@Fจ๔@�~/€��u`&จ๗ศคดฅฃฒI*<(ษ)กFIQdฝjnฏ,-"Qโq�# #ตล๑%ล‹ฺ8*#ฎึซชท‰ฃ,ˆE ๙rจผGๆฒkหณ๏‰P„๐สbXวgงP;ไ)KฒฎฝŒบˆ�ผ๐ฯ�ฮ�B?คŸึmR!@…‚ศ eๆ][Qๆb,Aถ๒akฒ>งB|•มหfๆKี“ภ„tฮ3ˆฟJ^�I��6›x!@๓—>o‡Žžด ฏฝFทžƒrยฐux—๚ม(‘9]`B tเ|๖ู''F~อAวydฦd ๗›”d๓|ต๓A$ึ^Jฃ๔@ฝแณd•๑n@ูฑ0‹น$๗๎็a’ภ~ษด€?๓ศeˆE:ศ pภ๒�ล7‘Aฏะvฒาใํๅ–ญซทร>๙๒‹˜gถ�๐ุu ด–“W๊หyา D€„ศ GP0Wd่(s5ตึS-u@ฝ8ฝ`้ b_‰�˜ำั๎q#ลัฎุ4@šฬอฯY’จ7๚•u&“grไิุ?:v๒$ ู‡๓๕+_๚วฅฏ�ฮo?œฮฃ~้‘ฃ>\ 9ผา๘ dPKHกฝ˜ส>{ˆ�รGpหOežฅld‰L<ต๏B2แ๓B.ํ‘žY ซอœ๏‡ิูฦ|rcฬf'�N3_ˆ"ณŒŸ€ไ๘š2ลd9ธLฎŒ*eภยฟ$€ฺ€:Hย>�ƒ2"i๕—แ ฤ;OvWิBฑเ—OFzƒ6ซ2„ aฉ_ นฎ•ีจฃ”�oอ{สkP hŽV“* ๖พขoV5ต��V@”อฮ๑Y๚’ฉฆฺW&1`yEฝ R%PZ๓Eค๎๒W0๋๑Ji$ŽIบTฌRrณฑJ้„U=JคF Yใฌ™ Iฦ!ม˜cU๖ฝW†•!ึJ€u'”Rท?ไs”ˆ xะ}ฉMhตˆ^ฏ๙ฉyชRƒ J•ุv6h}บ•qๅ("�”<๙ˆMข%ุงฃ๋ธˆ฿€๖มฤุšตฤ‘ฒ}Fถจ๛๑แ“2h>๓,„df‹ำ0ฃel๖!!U๏/o‰2eอ๘1ศD๕3ณพbำณ“vค๏ต@๘น"ฌŸ:ๆั‰Gฑkืฎุ*dj2JmLีu‡r™๋?ฤ˜กa์0'e�)7าถ+š�1ไY ’Hฤm๓อ*๛“๋๐ยฏ}๔™ง-ู�iท๏�ฐ๙ปSศŽฉืFžV่ทฝIๆ%r2�ธฏ_ฝtี^x๑E;4<ฤม฿N}„RZ" คXQ‹ฮมcฮข{ฐำ&:นํ,ฯ&UูŽ>ew๎Oัเšผ-ฬ‘๎ŽX€2ศ$ฦ^’๔��*u�ถ0ตเ@๑๓/๔ iฐ[ทว้�ฑษ๘ฦliy‡๋๊”D{��{๓mKBv4“๙5ฤ฿๘ห?�ใำ๖?๑กํ่#สk๊‚ฉž‡ฌญฺVŠqํ@”"ฟบ๐ญa๖เัFiBŸต๕๔ธ,ฟ@{ส‘Kญ€เึ\š•}€hพ…้ไ‘‘Q@+ต๐ิฉหิฏ,๎ยฤธฅ๐xP]=V๘aŒs% ˜Wฟ _ๆl5็ฑถ&ศ ภฒฺB�ธqตKง Q€tŽา)\ ˆญ:ศฎ5ˆ—m0s‹<9ใVt•€ฆิ"qศ%I�ืวุTฆ\ํUืŸ'[Ÿ`]Jต#?‘a้�-:Hด2็h1ษ}บŽ �Z„ภT‡:^/…O๕Œˆดฦ–N'‰ืฤ+๑s‘ @t(]EP68q �l๏^ฝ‡๘C๑(ศ้ lฆQŸ4ก.Bฦง*7ชc ๓Z� RWศศ•มrDขซซงtA X๒๙šศ<&d dฑ‘„_2it� S๒ดฌg ึพ๚ ฺD ๔†ศคK๙”IaRห—ikล“มS„9ณ2kฃ‘Gm$ูgำดใ”๏SIหๆโq…หi`  /า้‡žม�{๛-›ผ?n Œํ&๛0ฟุฬฬ$�1qซ็y็ๆ,QfŸำ็๙ˆs•ต%ืต๋d฿,r�jŽ๛ฺ…$ัžภz“‘ฆH‘ภR{นฎ0*SP;KฝFeg๐"จ … X๙hž‡X๐™*บฒ*|aึึ‰PโZ๊�RคTAK!Jฉ๖w•นxBŠิ3ท๋dฌชkqA^fk๋p}ฬษ$d‰ืฯ๘2š[QDeŠG†|แG>๛W——=๔๒#ฎY๛ชE Z>”ิˆƒ%ฌต‹ึ"P‹ภรŽไฮw่กma†__�—��W‡็ฆ,Q}ๆ๔นว� ฏทซtแ�๏�<‡๘ใrณข"ุคถ6U™‚ฒกส0*๋|�ฤI;�ฝ๏bภu‡ฺ๔.็ฺฏถk๗๏าŠ" @�tžC_œ,ุ(Yี๕รN’dท#•v„mง>eหw8yน?ฦ!”ร๙>ZญภC5๕๎$ษ12ภ�Hjฏz[น"( %“v๙�ทญตฝ0Eืส&b อ๖�ๅ๗:p๐�จƒง\Vำ4ธL” ”W‡ไ‚Ÿรฐ$ฑJหจ86S[C%oไใฬ“ V›์WŒฺเ�ฃGlzqฦn�ฝ้\# E]8b” ์Szเม=P†~?ฆoJฏ‹ฅ`‚Vƒดห‹ใภๅl ู~)D†’>๋%ฒญzœร•iS}qเ4?�€฿SŽ=ƒฯ3_ใ> �๗>_อHšนqP„รี—๛0ฯหใ๙ ฯWื ี0ซญš—็่“์9“ฺœSว�าdCณy๋ร8ูัƒ๖rืo“ีF๒(P ธS ไแ�น]Tร'ํะภจห|f้{d๔ฐ�ศ็L0หn�พ��-ไ*[Y 2ถ2ญC/โ (Vtqa็V{5ร"…œŸg์ช6ป %Œ�้ื  ผŒuA@Pzแสx4ิู๒๑ๅ9dxนZ�ต๋ใใ6ะ฿mฯ=zฦFฺ๖ฤดโพO&/๓ศjF๒๚๕ปO<๕B๎ึญ;ๅ๛ทg๓#gBๆLๅˆDฤt๗บZ๚๕-H&โ:๏ผฺ�iqศธฆ่ค1=7cท๎�ดฺ{>Byจณฯ††mƒฎ$J^ฦOดSึ6ะoG‘ฉฟ๛อ?…8ฺs2zl•jฤUฯฏR…ึM™2›\ …NK�}๔)jหณ\#>ศ;y2\Yฟfๆ\p-PภXสขG9mYศ†I€9){ๆ�R3๐`ฮ'าp…’ž7„ขGฅJ� U๓{๊ŒfžJ…P"รฎV*จ�ฌม{ƒฦ^ืา๗๖{Mฒƒ }e + ๊หฺพTสคิ*ฑ•ด_ง,(ู�C�˜Ll‘Mก˜e๖ฒถN+ศ๖ก(พ Uิฺ๊T�<๗_�‡�)ั’•kฉl  xUืญญมxC‹หˆK9Q �ํใฝRDYฟT9e|�ิ๙(‹ˆ5ะ=rงˆษ_Ÿฎ+๏Jeุs๐Žaž๚๙3ฒ&ฺR>ขลŠขเ่IˆA๖˜…ญ=ป;‰Z‰ C ๐ Аr๊‡"MGฯฌL์๓๛� ‘|ื้าRดmึlX๛+{ัล๓oนkจ”ภ‹ ฬ๛Eฺp!I‡ธwLaYGพ‰”E!รผs�ฤฯ‘\\A$q๒ค|.ูรsบ�‰4ฦ๚€Xแ๘K{ลGไd R@m€Uช–‡ …&ใQ(g‘™ –ปNฌขR�ƒิฺNยต8"Y$„๖ภ‹&†ฒ+Yฉฎ!žซ‰N !ศ††ๆ&ๆGไB‰ภ7!Ž>ด๒#�~ํซZjxุจ;ขต๋ี"P‹ภ‡๏“ค)ํ&$ย�™_olุั�oฟ�฿.฿�เฺ?™Ÿz0:qg�นพชAห๎ฌrภฬุะ๐จญQ3›ฆฟ๛ฅ๓฿3/@ฒRฦ•œC็.‡฿ลตd�P   จBืA€y[]ป…ษ„ส์าKFXdzฯKb๎!žภฟGdสh’iโณWN�๊6ๆmเบ้ญฺ1๎ฦS8หpธ๗D9๘ฒ๊ศ Fwi>O.๊ซ๖:๕ฬ)‘5ดฆ์l้pฤR W๚#GŽPพB ัฉ„?€wd๕๗651e๓sห6ฟOVŸ‚ˆซs.๒<Œ6๓˜พQrA–z‰๙1]˜ภ%ๆๆsj๕x‡ฆ๎(S๎ทๆ&zฤ๓�cƒH๏ ”Œ4#�n$[œ[A “ฺน๕ฤษCฏ9ิ๙!ฎชSงžหฑ�ฟ�๊ืzACgƒ2ลuบ 0—U๒"ถ$๚ไd๙k9๒CL๗5 ํZ[ฺฌŽŒ�<ญIUชั‡bœฌqใสฝิคu`๖ุŠ๛�์๔4คีผ+‹ฉCŠ/"N๓ฐฉปห๚Oทษ ซi€,|ช'ฟษ|๖แ[ย+tำXยศฏญฃEHƒM�Ÿด๗™[H๎‰นคใ‚ไ…iบ„�?aMŒย+ผ>ุฦQ8๛ž†tธR’h#thn”yG #ตƒ์๎ๆ ๋าฑ0 ขFษะ‰$Iก ช 1๓หใ9(WPwƒ {ศ๖ฺ$%N}ฬoส ๐I‰แหQฆuk9/4วฺํ> ฝเท›—n–ู˜๗~๎einษฉชฌ…kRš2xอโw)ั(’�ฯ ฎึ^ ฅ Iใ๕- \™-Gc2ผ6วsจ „< ิถึฤX2A่ว�„๛,.“ู—๏Šข&TลยžตuQja�xฌก Sd ์*๋้อu|บ‚`|นฯพฉ}ข/…0ŸฑA&UZdฦ)UัZึ^โ*ทธyแ}ศ ท“"๛œŒ Eb๐ิNPoŽุP)‚ึˆ”H%€WJJฑg1•jlQ€vโฅึ–๙ �ค� uส`j๏๊e(ฒฉลซฬ ๅE"#อื—gA^J)สฒ6wถ(๙hไ>ุ๋ˆ”yJJQ9L#E&๛ƒsลช[๋*QQQวตฅคRษ‚๛bžฉ๛Bุฑฬ* ช[�ป๗{๛บฎ*rษŽ–ฏ�า฿๚•‰�ๆgฟp๐๚ฺ�ื"P‹@-“ิˆƒษ@ีnณZ�๏#‰ๅ„๘�ฏฟ๑‹_|ma๒ย�ึ?�g?๗เ๎�Ÿู^ฯ6Œึ%1ม๋ํฒู™๋ง.wK๕ใdื’๖"S-qภolnง แตถ8~๘ีrQฒ๙Md�ํmผwv†ฌkŒl1T�~๔๐จอU‡จังw}^™>ฒ[สฬZTสu@ˆ„9e†$๋ฅ์š)ŒึT+ใฏ-๊, ฅกกัžy๒Egฆ ๚ฺโu๑ดฒ˜ไiว›�uใ๕เน๒sๆซ๖iสเ*kุCfธญาk3‹ณ68v”ฺZ๊›Qk๋d~7ํpืi�!(Y {{แ๚Eปuยb”ย\‹๋yศ๒VMฮP =scฟK๏]s`ฟทฟ Y}ทEบ!>–Vํฬ‹/SZฐaซ”ศฬN&`^jธCผฉ[mีw—”มdฌช”U์jช)œ 8hW”U&ซ๐8ฐ+k*Gvตช@ะ=Iฑฦัฟงงืบ ฺิาœ/ฯา๕ก™l(1'0พ˜�<มI’%›/@Nl �—LY`TŠ ฅ๏�รแŸ๖d�u๘"u–_ €๙ฤ“�ัCGศ6’‰…๐P๛%Tใw@ฎ<ภ3๋€ ทใJ`ฒชฅๆ�%q& `FŠ^เ5o™�eณ€ะˆ_5ฺ๛• €๗ฃ ๑`?„คยฤไ”M|pหz��๑}H(Nฏ๖�ฅั๙7ท?ฌ_YCฅท฿�6. žะ> -BV4Œไa'Ÿ8Eหะ�อฅญŸฌ๙�๛๗ํ๎ํ;ถŒyžŒใd˜=ฬ• .†j อ๋n y๔ไ)๋ภแ%5aๆ‘ˆ<ไ๚ท>e2*ง๛2kิห(ข๐ูไšIๆTP)pฅฦฟธN™Pžqุ˜d๎๎ 0ก Š84ฐ7H๖."ข่ ›ฌฅซ›�รk›หๅ6๖žB K�d.("Fcฏ�aŽ}E�G(ถ๑‘ยย฿ฅปๆ‘”M ขDฉoŽ�า๔4sฎ 4กPส”:l%Jg4dVจ็ฯBจด@mlfใจถ(+`“`LุƒI™Ÿช}jน‚z"€ไžuWd์”ั—าbeižฒFg>ซŒพผ#�|†ภณ<"ั&k๏ฐ c60Šฌr-ิ;xXtถ63ฌF‘8,’2™ฉ:คฺุ‡Pบ๙ฮ%—‰฿@ตฒOษ‘u”<[๖ีฅขชr>Gปฃ๛�็”�wDฟ…ๅeํˆ�’B%)พJศmผ3 f๘L•„ า{R|p๏`ฺ}W๖d๐Hนฎ†"$ฤ�‘G•ขrK ฟ‚<%8๚’฿ŠŸy#r@DŸฺ์&่Ž"u’ฦ3ภWืฝ2d”โ*Bู‰Z^Šิ่ํ๏ใ}มBWgฯ+GŽพœ๖U‹ฌ9‰0j_ติ"P‹ภว*5โเc5\ต›ญE �ง|ŸH˜จVื�มO}ๆGgn^ป๕๗=พJsผiะgศ|ฮ‘ม*bvตุค5^C ฺ‘‘ษชB$$”$ฃ(ษฒ@๖:๔•Mผw‘ฃWฉ๕–L7เ,,?�™ฯุสิผ๓D(qp๕ƒv๖๑บr๕ณR 6!ํU]v™R]�zใคษ=ฆ๛8ๅ2}Y ๔:ศ๚ษม ภฌฎก,�ๆd6ƒ [&l2้!์%2่j�ๅCัฐC๕:ตุ%ฎ฿�ืใ|tˆ�+ฆiม์ํq‰’mญฎ๓ฝYAฦ~nหฮ=c ‹sฮก�O,|€\). €%™ฆฉwน@มฬิ,o€†ฟ`ฃศ๛ซtdPF}m2ลAH“byฯLMYขฐไC†”ฅ…$ฯฎbคE#J ˆ/™KJ†,ืz/๕ศ!ฒ‰ ๎$ิ๒l~ฅ9ฐ ๅศZN�บใ2„u((^zษนภหรย่Yป=‰4›ƒ;ๅrฏODv –8ฤ€/'ำ6ž?หX„๑ˆP :”๋…�ฮ!ˆ้\jkeส€ บ ews5ฮ9ป|๑†อฬoX< 3Nื ฒ™yMฎ™จว€g[]ุt$”�็ำฌฝโฆีหi}Ÿฺ}M…๙ข~Z)๎,@+„šใ�๗/“Y…0แž๏dN เู์์�ึYฯูตLแ฿ญงXฒ.XŸh ฦ๑จ่9:Šše�Vน๗„Q +ื๚|”ต–šFFคƒSษ–f€�š-า†O€j R-Q$3พzฦ0‹ZGพ0J๒ํุx๑ เz@ Mฃ(ษฑ6‚(-ZŽท๛W�ฅณ…ว:˜;U�ฆQห<˜™ขKCฏฤ�า @IDATตt๗ฺ™ํ*ใผฝEฦš{kล[ก@9LŠyฌน$IบพTK๛˜r}‘fฒๅ*'ะZูๆ:2ภ๕{ใžpe\ฯ[ฏ�u-ติ"๐Žภ+ฏ|ฑ๘•๑น๋ฅีู๑tfspuqถ“3.‡้๎ๅ[8ฺ๏p€(ึW6สซšบ๙Dฃห4ฯฮฮ:ษช3ุโ=80เถ๋(ิช๋�#gํ๐๐ฐMAFHช๎ฒYซฒถป�ฝฎEฒƒ€ทŸƒณ€ฏ“ฮชฆ™ฌ<•ตœษ9ธ๚%อW>ชƒmร�5๔ |�mฬ๗TโK’ฬถcิOืัRูwNขึ~hˆNํวT1่(‚…7เํฝฝึ?2โด0_xUV\ฮเ�๎ุ… ้ ฑi2ก@Ad๒8๙c8่Cr์ึ๒E๘‰‰ห๚ภd#=€ทฺ ช.ผJ–5วAYY@๛ฅh+Xๆuidิ~`n^YReทเคฮ20Sฆ?ัึA@ขCRpโี]mEˆpQึ7Msต}@‰ฒ‰�๕j94เ๐g๎?ภT๐Mป�ฮyะไqZ‚๐Y[�ฤํ€cNฮผKฦณJv5 ่ฉRื ŽBjณฝ�ะ!๒|ง0e�ก�มโฬ"=์w,ม”ๆ๏gfื qfXํeD*]๑œขว-8H-$๙ฆ”�ฆ�ž`j…xmaโๆaœu/Qฒ|ศ'I๒=€ydศ‡!B0พ๛๎/��ฯ�ๆฟ๘ลƒด็xช?”ฟ๙ญ�…ยลท. �ฃ�cณฟ•%สธ๗"sUำO&™๒็นœ๑;~‚LkฝS,ฮbIธส�ั๘U!{D„HgYส&waฦ9?9c[ดั[^Xด้้—)์ฑว)ˆ9๏‚ถฎ~ๅ^@ฏ&J * แ$ณ,ภšL6Zw_'๔ๅ#Œ’yฑ{eŸw™๋๊&ย ๒sˆิEU๊๛-I๛ิg”ฬ>%ห+(y๊’€Mึ\0Hู sป €”Yก uฌ›:๖ }…™๓*ะผีe‹์ไ๊*#��ล\ตqท}ส3สf•Qจ�ม:ž๋t@#€‡ฆ~แชŽvสiZห๎ฆwฌฝฃร6!DP5เ�เ‡Qg™*๗%5ฯ>๗ฃ5ฅgSฝฝ๖ขฎ sีyƒะIEฑ2‡”๗‚:‘ค่ ฐ_f�าUFฅ9ึ0SัๅcXBน CF•dˆ`PPŽา>8ไ O”ž4P:Rๅ๓=2”ฉค๐ž%s๏gษ‡ภrๆ” T�๛t�Pฬd\YDฅฃ2/อญ™$lŽ1ุฆฌ,šG�)ซ{ํฃZ๗๊š 0/๏ฉขurฉeœ(pž๘Tฉ•โเศฑใv๊4mUg'๙w€(ๆฆ‡น"ฯฉŸr(๔นิcบ') ธด�ฏ�"ฅิฒQf ฺหรฤ#Hผค,*0jแŠศŒW่โ๑B๘$ฌrำฤ"๛ภ๏u}๕�๖ชPฉ}ี"P‹@-หิหaซ�t-ต�y"0เ๑ไ_ฝ๚๊็๊ป7๎ว�๓ฒxs้G๊0Lv pะ+“ฝƒเ]‡‘X๙๑�4R`ไฟ+๓” pิazCด2�9ฒํQ2๐{HจCMuุา์œ]XLฯsXฆพ=ฮAดเๅ๐N=sRเO}โiป๓ฎM๐ต†ฟ๊๛”•ƒuฒ ™4ŽพฎฎZ^’ศFษชพw‡๚้ฆhc”LO>เ@‹LŸ๖lอิ8/ฯNY™ly฿ศ(ํฺฝ๙i{๒‰ว๑8ๆdฬ+++ธw7ฦจล&ซV๒•์ึๅK6woภO&�x` ใพ๚‘ฃDฉ่›Œ:—$ท่9ิ๘ƒq‡iษ๘<ฆ~-ํMดk‚|Hนบa๕‡rHn่hs™ฯ, �รA{~9๗-๗z”}�DPซ9€ ๘ฬLR;;nH6‚€Ncขฯuู`๋๐dฅ‘�ถ%ํฉ^๔ำณ๒ฆญปห�ฝ๘Žอ.๎]ปBMมกฟพ‰บ๚๖.[y๐ลศšW\ฅฆŒLn{@v@‘"$)0œู-3โ”K๐{@ฤฺš๋์า…P{จฅจข …j#ม\=^R{(›.†ขK๗'(ษพdา2K; ˆฑฏำXว3 =๓๐ณ"Y่ฎ๎n;::j““ใ2ย_oiiษ�yๆ๙รyMwพฅตe๎ๆ�”ญฃ6P)M=% ปิทซลฆkนIเ:๕,H‚๋Zงu€ฦHไ DG๕๏๋k;Ž์QyN?„-ฺ9๚ˆษฦ:ืbN•ะUๅ)Wฏ\eŒ๑๓`ฎ~๒S?lทn|`i�อ[ทm’ ‚ิพณฃ ๙xึถXจใฃ*ฟg�P—.้ผ@ฺ9J้ _ ฬแฮŽ!ส๒iu ศฮฎ-[ji,๐A›R!ผ}พซฐ8*)๐ Qท MN)ฆp�B,ชSB…๋GP"Iๅฐ ศ3ฦัภธHฏLF3d๗E‰<ฬ“นŽcŒ้%C�DK?]S๋�ฯ:Tึ:Œ™`�ฉcถ;1๎ZVฑFPอ#อ ฐy๗pๅ:”ฺ`–ํฑ“ุ‘แZKnุอท�ดxฅ2ฏJ์Qฐ/)ฃ-ะ๊ศน๏“"mด๎ไซฐ/ๅ€&:๗ฒณฑฬ๏้<มบ)ZdอTY_2NTฌหฬ�Mศ‘ ๊X ิ๓๒.eิๅ7ฒŠซŠฆ .!iXถฒบยฉ'ภ ƒ๓y๏ฺ๋ฌuต•๙"ŸัŠ ˆp� ๑็ํ�ช ๆ@‘8๎3พA|#2”jศŸ!€tภyธ [)Œ๔8jป(u‰”0ๅ $G9A„BSD)LPตวบฌ ยณ…=ซ)ูdฯพ๐’ฝ๙๚›Ž๔ห2V๊.!–G–"4s”็ˆpJ๖•j }โ๏ๅg!o:ณˆ4Pง/ๅ�mc2ฦ�Aฐ0ฅฎ™ƒ’aํ`O๗ฟ�ๅฟ�หฯำะฐลKk_ติ"P‹ภว65โเc;tตฏE ?Ožž"Xซ>๘๚W~๙ใ�๚=ค๎ณ้ญต‘ีe| Tต x+ 6P�ํ"ูFษx‹€BNฟHๆส–q่r€\€(ˆI* I0ƒผx|všC"YV฿๊7�฿�eGŽต Jษ๐6™�Ž>ฯ๚‚3๚K4'Q7ฌ ErO-๔ฑฑSt{XฅTbล•F่ ํไ”ฅใ๎ฺฺฺญ™๒ฬิ๗I�8‡�บFี“ฯ8`Š�์dิ>�๒gหM\ ภฦ}ฯกTXๆฌ;๐ุูหู�o_ฒฝ๙'4ัNQตบผ~%๏$ฯžTYผึy^ฮะ๖Uห ล9˜ภ_E๖DแเGf_คfvRd�„๚a@ณLนG€ฌ๑กฑ1ืfR&gช!ฦ98๕๊dเๅ%!Rคบ‹๚žg)เŠฟตฑb!ce2ฌญพ9yสXผ.ศ๛ณt^ˆ“ั”มฉ็Ÿ!kxฬลr๛ๆ ป?~ื6็—lib@•‚ ภ sษไJ&}wฆ(K!kวTฮ‡ <O—2%ฦ:ธแษ ‹v$ะ€ช ฏobŒy`ๆE–9ฑ๐�ฒ* •YHžPฌ^’h‘H฿‰‹SŠRใ"เญ@ %้w�แฅฅ )˜uj#ง7า’R$†œ�ีพฎตญลžy๖@K๎n]]๘›Hฑ…ี~ _<š�‹_‹อ*ีB  aนง]‹ฉV�eƒ๗ษ–gQg xi`œQณLฯฯบ์ณJzขdYUS.๙x‘ŒดHตธซฤไๅ ๕u—$d”cฬ#uœPw€๛x €2ั’Pฦi–'N#a ”ฌๅืˆuฝ;~ฤฟำf˜GEˆณyงZ๐#M฿ฃ4B„Cˆq*๓ห็หว@ํFฏ`^*™์8กŒ2Na”/;Uสยkํ๎f��gรภ ฯZ€่PวŽ/ธ"ศจ2 7 Fcb)ิJญXA>ฏ์aNฃ$ฐฬCŠ@‰hžr้\ปDˆ€$ฅG๛&*›|—i—๋ึใ‡R2F@บศZHpošKฎ]}๖์“ฯูฅ๋๏ป๛ะบ�ค[Gw๏€อ5�ฤ"๛ŽEย E—ศ�—Xป!ิEP8e„ศภ(ฤฮAKXbรๅึถQํkต[D]BคZ>ไpdฉ}ี"P‹@-�ฉGเ๛๒ฟ๙๚ฮƒฅ_xห๏Kฏ~็ฯพ๖9์ศฝ ฒ๒2ณ‹ะสOเฅ‰.+ซ๘์"฿/"G๎ชš`ฯ#ธปs8t3•œฉ9&Q�ช๚—#/SใTญ;‡๙g;gY๚kปdH้๛ฝCหฟ$ูวnJๆ็�มU๎�;›�ฎึXสืส9%ฃทฃcวภžŸ"ณ& mฮ&g–!2ฎญืฉGฯุ ’ใ็ตืํื฿ฐ๗๏โ]ฐaํธูืฮถ‘cใ[฿ต‰๑Kฦ0|ใP~j‘?OQฒ ŸƒนŸฯ’_gdwฐ—œผ„Š%‡V๛:�^rเ2๗Q$Cฎ๎รรv๘๘1@�$•ดนvvd๗ๆ——ํธ€ล๕ต ๒”ุ–�] Z5ฬEฎ)ย!@]sขงอล„ง{�Yี‚‹ ’๚ 850wถ0™ฬ—Šฟ๓๗�ปฟ๓•W^yๅF˜ฝbฟ�ํW—�์ฟzsสC’๛—ษb๋[ไUŠะƒ :t๔8€)aืQ จ5bž1คุฦนƒz๏ƒr=Iส+ M/@0้ขq /*฿}jW4๏cิ์ืQ๚’4wtSzุ ะํb2…F”3KจW��ๆ7m‰qMSf”%-#ฟ"kJ แd„S0จ–กิž๓ํร{#:$‰‘ฺ็วฝ๐ikฦิo๒๎=‹0D”1Œ#€‘ฬนฺ–ชCB‘u_a|า|™๓ม‘ล–9)J บฆ$zu‘ฬขˆืG!~-F|์jทฉŒฟ2ํR-aฺ๊:ป,98`+ฬแ๊…< งๅลHJFุธจฯsฐเ”* ซCฌj‹+€ ไ[ำ“ถM]}`rๆ’‰ฎฺอ�7์่เa›ธ}—ƒ&๙๘R€,?าxœหu–1—ฯek ะ3o"ูVด>Kh4GV’3*-ู่N]�า-๛r๏9Bโ์#น์�ต+W�˜Z� v้˜pี&9ิื#้˜ฐ•แWŽznews หโ”e๑•ˆฦ9ุCย #Vœ<€ีBซ6ฝศฯใ”vtŽŽฺ3ฯ=Wย:�;ึ9ะk/๕ต์๐" `šš๛/๕ํp฿ =s๚1ฒอ˜;bฬ ืฃ^ � 0�ๅ}พๅ)@ )ฤ}+#ฌše=—๙(ศ'A€Fส =ซฺผ…1ผrI๑zต’๓’–_C0 A0”ก,—ศ\C่K1Qซ9ญ=@ฌ2๎aๆB=๏™ฒ—ฆฤื๚2พ ๑(2t'U7X๒id฿ใfกฦีUž{k3hh๐Mฎรh�`ฟพ๕‡๕ฉฦ๚๚ฏฬO�๙dgOฟฟๅF™lvjož๛Oษ๐Qyฌะา4‹ษœโเ 5…b™มƒ@m/‹ฬ›ฌŽฤˆx)K,`[=P™ปXฉN=ฯš๒ซ\€ต319แž—>๕)0ถ•b>จ฿*eAIฬํค`Q==?b,T�  OๆZฅ Z?~Hžฝ\๖[š\ ั+๏ฟc๗''ญgdึž๑S6;~ฯถŒ ‰&ภฑj�๑›V"ไฐ™2ไc2๐3๙ศŸRื!ภX2v’๑‡qโ/m๖ eฆๅฆ/?‘ ๓Ysญ‚‚ˆž|ฬ=ฺ๒ๅท๘3ฅH ]ๆํL�cฝnฒv;Pอ๒wYขLQ๕Ia2�ื)/zแS/ฒv(9โูโ [›œbŽSJย<ิB”�€GJ%€ท—ตต‰ŸB–ภp ฌ-๎็Š๒!ชฃษ€ฟ™฿ฏžQSjŒD $]> vtMํGช^‚สdŸขTK@฿94l™ฏฟ๕ฆŽ'๐J้ฒkทฏำ‚u�Žฐทํb :?E ฦ=H�๋!ค4A =G]ิฒS๓@พZ“น�.Dสˆ[อ/�๛จฒงJ้ข ํ)*ฌG™+ึำqฤฉ|D๐็TOaฃb ^_ๅ๙E˜จCJงสไญ›ผว็ิษึ๋ฅkk3ณก#‡™k๏ป9เ5๒|ศ;ผ CฌaU i~ศฃ†ฯ‡(�…0‘ยF”กึFค`ฃฃ…๙ษรถ64�ใ{ๅ'�๗1ฯ˜ใrธ@ํซZj๘ุG F|์‡ฐ๖ติ"๐ฟ�ื�ฦย�ฤิฦWฟ�ี6ฅœ๛†Y{g'๒ฮq;Eข ุ O{œV](ภH�g‡5i‹:o “ึŸๅๆŸGvฎดv}ดมบ›;์&R๚_x�ฮ}โ �.๎Yืเ� lbaั’Mmdช$Ÿฅ�šŒ›ฺ๓ภUd๒3\”์qะW-ฐ€ 9;๕€ผ Nๅœพ…๏ย๊6mรŠ€ปx�ถฌ'j)@�k๏^มdŽ{(ะ� ‚C6=ี�ส0_เ Lษ„ฬส"hgVDeQOฦŒวu€Lถ LAd€ีง^f‚)jห†Œ๗ฦๅ[ผ7ฮมž,�ฉŒ…ฮžT.B T์์“O[;mS+ซ๖ฺซฏ’™„เ_ๅ๏จ�'T€ผ Š�}(ฺ๚จj˜ช‹-าPo[ฒ$ฒp)R('ฮฟ๑ฆ๙hฃถ�`มพ9ฟe๗ฎ^ณ–†ค#?าdnฝf—ี๔cˆ&`!P*๗wล/€pF‹Œนภิม฿+sy๐gฝQ Jงฬe๗x!V�ญr฿%ฒ๎ief‘รง! ]�) x๙(s.B@„…ย EฆOH”๔Œฺ๒<1ˆ(™บน–u\ฏWK:เี&.๓ณ�1s๚aฝ๖ฏ�ฯ�ื�่๗ฏf3)ชeRuภP-5ำป[A !_ˆ=สh6ผส^ซ$!Ff_“พีP8ช5]L™r2ึšใ`ސ6rวWง๏-ๆSœืF\g/]-ฬๆํโ…๗]™ฮุ่˜“ดซอ้ไีห.;p d จป’ฎฺ๋,น+bฅpมึ1��[_ฑ“'วศ�๗bˆ7eหด4-๓ู+kถฏนฯš “ฑXV—eฤร|N%-• ๊~ าIJตPหD)LดN˜"ผb าง„A„ ๊อ‹žหรฺฤ&N�ฬ๋ย^ษ๚19Aน‘Ga”^$k9ฆ๒mPUโ*ฅLภ๎L c™�ยG6?i%r„AณkJ™t!คถ๐ณ์ขŒŠำRS™s™%*Eภฐสธสh•šP8ภZlท�CCึ=Oง‹้ k่ทร#๖ํo�่,S$;_aN์๓]D!ก๙!BUื“tŸมr-O๖e�)ฏX(+[_‡€I6ุ /ฟฤ�E�สน)=ิXว่bทqสb|ซyจ2ฑJG†ŽŒZ2F]i‚Cw้ฦฒIวืFŽฺ�ส�g˜ฯVW˜Šส›ิ…{kMึa˜šฒฆึ�‹ฝ7ณ-ญส4ื‰3ฦ9'ๆyž#๎<ๅ<‘ "ˆถข€ะ*ฅ]ขจี…Mโฃm‰ ฅUๅ„%Š-ะˆ)fBr๓�œof�yŽแฦ<ฯgŽ3๕๛�Aถ>ๅำ]ถI&™๛@�7โœฝ�ฝ๖�๏�ฟo}๋[5ึีูฬ1(ต ๖~&^› ๕uOxคก๒^^ผผฌ"ภvว{y๐"เEเ•~๔็ฉ•ผ|๑โญ$ฅ€"2ู+˜ฅำิ'#๗�$)'ู}'{น•/ก Pถq‹pสช Œ*kฟNฏภaกL†“$q'`Y๎๑c“ณ6ะ฿kHำ €ก(cnzฦ‚dJCdถ%qU ดภ;๛_ภ*�hฒป๐ผ๐`CญทŠ6๚e์ฒืๆ9†<8ฯ๛sศภีs\Fq บB๐ปYฑM ฯ2W�ฬqไ[เ  ภDv1ฒc2f2พ qฬ ๊ƒuํ>j๒ตมื+CvP€[๎๒ส„> ภ”ZCŒ๖eูตm#9๏๗๕๖[K{ํ.Q0p�ฦถKข�_E†^ฆ9J)ƒPฃ๔ F]cW‡ฝ๊5ฏต4ฒ๘Yl]tOg—sดO KGฐa~ํ์๊…ห–œ_ทJCฆฦ1บDuw๗ธึŒซิK๛ 3€๋ฤ๐ศpฅKชe ]งฎอนยK%B,@„lิวฝก"c=epๅeๆ‡ธ>2ลษจA8จ’ƒ€™ง ผฤจ�นมญภ’5u ˆc†”๕ธ‹c<')vๅB%๗^วFญฯ๊>hŽTFยO�ย‡?๔gฟ๓;ฟZ�ฮฟ>๙ปฟ]้\พtช3•Ncฟ@ํ7 ‹๛ ๅG,@่ˆŸ•X&"MrS9Œ& +Hฬ�ฤM/ฉkีต;“Eๆ›ฒ๊ๅjอวmd๎aŒ' HŒRdxO=uส•.์�c8i—/Ÿท’” œญ’R€?pฃ\ฐฉc็X—ึช๙ื=Iฑd๐(ฟ’ีตeމ๊ข*ฦ}่B#ู��๔”ญำmA^*กCHhm1iY๓R–ฐnภ76ำŽuL€‚’™bผฆ†๗โซ@iƒ๊์ต^+๑าูงิ,r฿WSตHอฑฎ&^ำัfUx ศTŸูข\g|l๕F†็s ๐žOAL1™DศUโฑฦ๓จƒ๕ /Œ%%Hภ๚ฦV:ทฐ^ ณ` ค็1ฒร3ด”ž@f†~=cˆQฎ๒ 4พ~ๆค2๙AฤPŠ๐�ฉH\ ๗P2-็ํAlD$ฌcJชŽ)บ—.]@MC™พ—.PถBปอฯ)y„คDr\gพH,ต�œชฑจ๕กD�;ŠRDฝฦRAนŠสผ�ฌ g�มผศ๐ฌๅโด.�=ัT“ฒ% น*๕žแ‘M”š4ทแmา�๚ โJ:่^!๏—4sAช่-็QำึำK�š่’2c็Puฅx~Nq’ฬ!(ฮ'?ZVB๎Im!r*ฎuช#ˆlา๓eC …V็™h%\ื23็K}ฝ�พ๗ฟใ๘๏�๎‰๑^^ผxxูDภ#^6ทาป/^�%P›ฦ฿�๘oŸ�ๆรoœฝ^/ Y ฃพXI'sl(๋œXfี /’AW�q‚ ์:‚@[q@#ูF6๊ช.c(นv–�~[k‹3S�๔-@p €ฌ kูศ6$มQ€ศิ๕q—ลฬะšMm�๔R›3egE8.@ช2ไ๊ทฎMบดฬฤุษ"อลลžq@b ”cN–Nuฤ!ฐœงๆฟBCู�,ๆƒjฆผภšœไ|น‘‹$pํืุ+ลกS€$ฦ 6�I๊ฉE(ำšbS- ธฺษ8LYueไD"p GX€ืqแ_ฑ๙ูYปฑ0ok˜ฬี64XW5�dฉw\‡nปูmๆใ˜ชํป้ˆ5wถ“ษlถvศƒDEนต6็7&&mzzึึจGžปj';iํ๕2-ฮศ‘ ว‡ย๐qจฒ•udืศษฅUˆฤ(\3”K#ำŠ:ภIŠซ@”ชฝwˆ—?%}ึ๏Uk/ ศข4มษฏ@ฉ�ฃฟeŽ&�@_๗ ฬโโ'ภซฌฏฌไ๔Šrdฉ{ฉฐ๒KA )ต$๑๒IๅK๗LŸค๖?฿าึ๚‰๏๛�7>…ฟ;ผŽ๗|}�ฟŸ8px๏ืพ๒7ŸญX]Yป‚ŠฉSf๎mS‹N& ฟŒไย๒มpฤ’rj_'I�nๆ^เ]-J u฿U�]•Ž~.#H�#,ฮฅŸซw ˆฎบk0Ž^ปd+tUHr๎ฅ•U+%ค$AลุU'อ[uOP�สR;0ž2?W‰„ฺ“Eˆม้‰1'‡V“ฝpญE่,mฎธ๗่�UีตฮDSžj ช๑ฉตbd`Fฤื<ๅ7d;›VŽ#|>ฌuวNJmW]>หTใs"UhGHkKกฦQฦด๗ ZЉcก�ฅผชm–๋›Cๅฤšา/ฒ”๕ศ ต ำภ-�Qึ7Vœ?ม�=%ข–q�˜œฐ(c่€œง๛ ต‹ๆ 3–yช๙IY‹2น TTjMQภ1t_ด\KBพ�<ัผ—๊A'eDญฬลฉผHๅซป�ฟฮŽู-7฿ม๚+ฺ9บ™\ผxU"Te "โX)2�" x@่OG�‰(S'•ฃ(ฎšZี๘z๐-j!Wฐ`9ฉ8งZิVแ๛!"A๋/K�AรgDฮDQˆl๋่เJPEp๐2Ž “๒'ห๕๔๎ฆ|#`M(ภzบzGG”ฒ†*สS2Pื._ณ ็/ุฅsWํฤL 5˜|n—t”ท„ž๊ข‚(kจฏต:ๆฒิ1ต๘#ิีล๙ชf.ีฌ2ฑžl๋ํผ�๗�ใง?ฑถ๖=งoปญ๕E!�\ภฝ?ผx๐"๐E@ฯx๏ๅEภ‹€WT๚Fnž>x๔ตๅอ•ษriฯ๎#ฃH>ฮ6ทจ%F~-AE0f›ด+,’LัฎPาd9•KRฏ o‘6nส, XWใฬ> hฎญก�5j๓”2ดฃdุ;ะkห“s˜šmุ๕็.Xu€ฒnสnษ่*;พ›9ุเิ๎ศ 6�•l๒๕rต๙สœFTsจกํ˜ศ†2ช‡"ŸI+ร่UY‚2ฏิค๊�€gIฦำ”@ฐ๓†ไ`“@|^†dj*O๋z„์ๆภP5’M=๛์y\่xีดคT2›qdกpฑ 1† ็ฯกาุฦซก\JX{#Ž๙xEˆคุ^˜ฃ[ฤ< ฑฟ-ป09j�l๒ซจืพr๙*€pMฆO ฑ‚qLOฯYkcณ�ธ1akหหึOVธฝฟ฿=๑Mไำ๋ฉ้Da”“แ-ษจใ฿ฑi�ทศฎBiธv˜|9Yผ2ั\2เBŒ:g–�aŒ฿$มV' ฉBสคำ)แ๎ื�egฮกj@aแSฆ˜ฑ%xเโ8๒Fˆ$|”ต$6ำFw=V+!wLบ8•%ˆฏƒMศ—%?'qIM5e7%ชqFEดิ7qlแฌ�™๏{๓�พ จ‚ลyq^œ›ั�๒ง�๐“๘G�๕“฿›ฬ$๗วฌZ�u�+t~:`Tะ‰ฃ I}€XหŠค”’‹]ZDD€ˆง4ฤ“ผ:๔R—‰า�์ฺU2Ÿ .ŸBbฯTท€ ~ง๖จ›kEฮ‰ดŸˆฎHณme9Aน   ‚ j‚-Lw๎ตฬ+gR €—BF`]5๊~^ฦOไR๔(€oตฝŽn#็ํ่ฑcvเŽ�ญ้๐ฐ“๗ฏcพ8๚�:lกภ่a�จ5กค@๓““–X]B‚Ÿprํ�Yํ k`ฅDŽv…„ลง�c๎Lำ9žฺ~�ผทภบœŸ›ถ๐Zฬฺ๚Q2๑ฟลEˆ)x†Ha I|^†yT�LEึ}j+eOกบˆข‚ด;๏ธ��๐ถทฺZz‹5ตฮฝƒถ6=oWh฿˜EiปรฤGูโƒ�ัฺ @Eวtb #หค#^Dช9ฒƒg†สs๔%ล‘X•ิิ7 – �ิึšuC๎uึถะ‚qษJ๗UžiO>๚˜#3(•"๊บIเ“ี“>อ=ชเxRˆT“ชJJG@Hฉ"Aฯ5)ถ7๓‚u…O VK€t•ฐD ิๅ"—ฅ\‹๘๚!T*‚ธศ๒�Sปษ}Fl}sฟ—i๋…D ข ˆ๓9 F๑=มc…Eจณรยtlฉ9LyYยฎ]ปJป�ค^œถ์� ฬฑzŒ uํc(ฦต0&_ˆ๋โภํtVฆฤค–gฃˆฦjฺถ๚นOmํ-g‡†‡?๚ž๗ผ๛ณ0ม๚qœ Ÿ๐^^ผxxูEภ#^vทิป /^�ฟ"€์”ฝ/w๊๘C�mfj๚5ื.]9ดCุ้่์†ษ:*‹ิ`MdถฯœฝLึoัmj๓dฬTวฎฟตษvuย์.•g.H๒ห†ำษฌูHo"C๐‘นkTๆƒทS=‰y”ณธภธฒ�ฺ<3Pท จน2๚สVช-ฃjถตแึ&{q~ž 8D๎๒ฺ™k3^‰,ฟศๆlถ+†8PึTyฦ]<‹œ฿ซT@™_04ืมฆ˜ใI&žวMส ็ษ๎�aฬ๛Šผดs”คปะ?O‰†ˆIฒำิ็ซฆฟ†Mณ #“€”JศŒภ›แฒ฿ดกcG8›vฬ๓ถD_{๖,ฤษย™O:9lฬ.ŒŠ6zg{ฦฃW ฑฺno";๋๊ฌฃ:ณนoูtษฎ/Ox x(๓hlจv�"PTฮภ}ๅHป_ป=ู๙€E๎๛ฑสR+ำ๏งฎฝฤฝ๋๎ทฆึ:ฺAฆ‰%ฎ๕ธฎGT—ฯฑd8ภDฅณ@่c๓o` ศ ะ€()ณ2๊QิฮysธวO ๙~ขIžƒํฎ$Aฝ้�hGjง„๓M Ÿน๓ฮCkŠว‹�z฿n�๘ใ฿\Zš_�_&ึMษM�*”ั/แn(เ)เฏ๒9ไ'ศ๒ P � x๛ซะฤ$i ขอ•!ฌๆR๏JL�ํ‚Lน eฦ๎�~+[Ss‹Sซ/OฮX-5๖โส>sZ๗ฅ2อg?คM0š‘W็—‡‡H8Ÿ๊@|*+R Fเ]9†Vช9;{ั‘^]‡FฌฎงC:”Fอt7˜งอ๊exlจMฃฦTf�—)-๐s•Y๗3฿ล์ˆ\ุaฎ(จไ’ใ๋�เฌ4k๎ฑp=™iJu"Zป๐AUจ‚คฦี๕$ษ3"ฬตI�๏:—๐lq๓†็Kˆ๓I‘ฒNy„ึ–ๆœศ:‘0Wฎ^ถcท�jอU(! Hjš้–B|*_’‡fผ†1ิตค๘Ÿ๊๏‹ฌฃฯ็)ยฺ ‡!|žฯWpe๎้ภ=`\ฅ R&ิทขฐ�กa[e�6ttป๙[ƒโแ�iLWื-›„ธไ#”สคฏƒส œั!kำ]๑’๊@ฤงT *aˆแmโƒไIกFชข|)ไ>า a‡q…˜S45คŒ ม=L[ส…4Oดฎ ๒,qTซk+6ฒwฤG†iนผบภฝˆX%Lถ.ฏT �ƒ_จ$คุ๐—๑ูพBว—MŽแชึชศะFžm*!๑๑�ะณMพ2Až๊|"๒ฆท•G*นD™�Ÿ|฿;~๐ำทzี๗�E#๛ญ๗๒"เEภ‹ภw$q๐ ณw/^^*`ƒ'Xhทผ๚๕็_w}์W7ถ’z๖ยนึz2šรร{‘[็ูฦฌ‰ึ‰๋๋ถู4ฒYUฝถzyK�+€>q€=Žl[[eCK€B6 *ธฒิ๕๏ิฆฌว?เ\ตฝŽ•ใ!ภR/5นKKslย1!t”ุ Œ3N—�๕)3หฯœy˜ฒถ" ศะJ’%๓Vศซ]ƒaณํW> U›๒@JuมY6๑ทqAูฎ€\€ฑ)“&Iw‘ฬ6๚[›(fgๆบ ฬZŠZ๋ๆlrBWอด2ม€ฎUฑ0.)สฦูPKบพดธfหจิี ม0u‚ฌ๑ํ*๑ ภญ| ง๎Jห๙ซZร้x!@๘่† โ0Tc“>…ูš2’I€� Y`ตษ3LืVท‰YLP:")€ข n–sq฿Uo์ชไDคŽส>พ‚” H™‘D1ะฺำj๗�{;๗"kkkk๖ท_}7x:d‡Trw็๒\์EGHuเ&*“ฐˆไA$ึ)b#„L#�ต$�ีาฎN™ุ]toUSฎ.Šฟิj้‰QFP๖]ผ๗๎W‰๛�’ศXNฺไฮ๋๎}รŸP�Ÿ|๐๏ฟ๚ึ&jยW‡9@ๆืฆ9D‘#AFกqŒC๎ค,�‡ห.3๏yฅิXแฆRIึuฯ5—๔~5ฝGณKๅ12ค;|่ s.m_ปแฒื0fฌ)I็๐ ย0ถ“ž2๋"๎Rฌฝ8๗นB%9�ฏ€"(Aน˜5�๛ถฎNๆ3 ฬ>7ึํ�“ฯ@`๘mภ?บผ`อจ*›v๘UฏตฦจT1็๑�Xw*†J€"ื—a}1 ี8ีeB„B1Upฯฑ๚`ฝ2ร๘พชพ…y›ด-:”t7tYใพใŒrŒ8m,ฏž>ั’ฦ�ฃว6V7˜W'ฤฬ(ฤp›gH…?ๆHต:บHศo@ชฉ้ย ?ŽqHพ~gšฅกฎฅล)ถs�vธ๓V๋๋ํว4po‘๑%�z)˜TJRคฅd‰xฉ3‹Z gPN”ห_ กถซฤUลพ‘�๘5vn๛<ไ"„!Ÿ)@Šา|vํ™ฑฬ(ืๅ9ณ…"AsBใคต']Uxข>Pว D9žMบui๎ต์๎{๛�้.ัbำค, �dฬš#ญ6^K_ใ>bผสุค๐(ศื€๓fˆIsฅŸญฮƒค•W+ž)๒;ะ�ฉไ็!๊)Mhjh"ฦŽ”|M฿˜D%…฿ O!=+œ^1*Q ’žฎUš:อฤhฅ[M{ลถึfฦ๋žUง’้ํห�=]_�•_๙ฟcฝz]X�ห‹€WF๔฿?๏ๅEภ‹€W\ุ๐‘.?ดผถ�‡nฝ้#'Ž?rุ๋่›์(hใฏ๋ฤHฦฮ^ž 2Pซ<ฑฒiสึซU[ …`FN๒`ฺฤAPึเ้‚sŒ/“qีฆ›Œ—ฒค•dฺœ)ๅlH‹ฅœm“ญQฯu๕,W67ยf™o+๛�™ {œž๔:Fฎ]สุ+ห[ึุjm—ๅ็ฎNP#้oœsg‘Žษ๎)k'r$‡ม]๐*0'E}d>ซศึI๎ผๅหย7ษฃ$HeP]td‚&‹z�ง3ึื๚LŒU�ซ“ณๆP‡ฉ฿nฬlf็Wศ�*(Qv˜‹ท RaWN๎สขR@ห {ฮจ>` ๋aก2�[ร|M$Z%f! d\–—ำ9`cท;ŸยqU�,0ช8G†„EตmMดซฌณAศ™•๔†]™ณป๏ผร‡‡วืู๙๓—๘s5ึศว#๘Wdˆ™b,5คใ2ฐซ‡„ภ ๗!‘ณM์ึ)ฝษก^1Ž็�จ๓‚ฺสUa„(BGY์0j76�X 7•,777|๎ญo}�ฒ๛๐Kเ>_Ÿt๋Ÿ๘แฏ=๛•/~พ7Ljbฎฮ-ะP\ฏfN๏fใU๎`�FYŠ๛ % บ"sิICŠ๑RธึฅฤH๓N๑จไ^Jฑเ$ŠคSXž|๊i€4*ผ˜~Š0‘ก^M’yฒz๎œ1็KฅiหบพํˆB‰yŽ)jme (J-dศฉrŸJˆ‡ŽŽv[ค”g +‚ฆ eฤุ่˜ตŽ๏xํ๋,@้ย…™หถJ๗†ๅๅ% sฬ:ิ"ลฆ:รฬา.•างะเฑ‹ื;EF-?ซคผJ-8oเ ฑ†R*‘—Odlbkิfฆ1pคฝฅ%Gž๛@5†Xศ๓์’j"B|J?s=ฦqd จ5ฉ็œH"ก @ฐI๖Je Y€นœธืศt๚)„ฎฉ"›วฆYJ„ZF…สLkฃes็็ฯ]`#.`ฅอ5` ๐UCถ฿ีrณน�˜Ÿใ{ี>(Ÿh$Cํ-ŠT�ซlขภฑ>ง m@ใPห๘-QG/๓`1`หlบE8้8็c๚–้ซำรqฦvบ4ฐmโจฅๆบDHยk-Bbข๙ต€ิ62มuQDฮ๛ศ๒j.a€X€ฤ๙6ฦ3˜$๎ๆฒR ]๛B �ŸsJ@„ฦ^ �FฦX‘้๗S0-_…ฤLพฐล๘(/ต๑SKภใ—๔™a:!Œ๔ไ!„ 1al๊ฏ๗้nบ/๒:Pœoป๕&{ํ๋_mงฯตEคฮ2–ซG*}ำ-7ำฅกฯ๊žถGN<˜`\€ลJ๎}Žใf›๎ฅภ2””คจ�\ภ็šณผ'@œย€a•’่|.[ ฐฌFฎฎ6…eๆC๏‘’DYเ` โสฝ๗�๚๙—๑•kjสำ{๖�๕฿mlnช&ซปŠj$ฬ๘‘(~dศนฺหิPงL3kAๆ†ิ๛Š‘eดรx่^ŠDWใo@|D0h~๋˜สพoฐ~’2>ิ�“้�$๛Eฉ(ล,1J้Hˆ๗๓q้6c@^Oฬ bAศฝ๖xU=ฟWyDšŒ=] D๐0~จpึฬืณHฌคnภเHu‘i=Mmz$€q%็แแส3ศ๊฿y๗]–g�ฃฃ6@�๒ฺาŠ“€ 4ไ‰3กra™ๅQฺLKถJ�Hnธ์ๆp~ภี3ง‘พง6i3‰ฯม‘›�ฃฯž#a ธ็ฟ’�Œต ไะVืd~ฐˆ,roŠท3�”Yซศภ"mVw]ฟV8:…Z-�ะWภะศœŽŒ+ Sต(t[ศํ�ป�O~่‡~hๆฅณ*�q$7฿์หŸ>๕X๎ซ_�ฟ๐Ÿ˜D๗›ofŒ0ญIื3ึฺ‡@๙ม�U{าsหiๆcbๅิV@J0 ฬtKUDฐKคฉ~?z$Œ[ฟึŽๆฑ^žjKHh‰' Z๖ี๔–:ผืJ(ๆfงQ@ฑฆv8๖nทVƒ๓427ถ9n‰๓๛8็฿ซsIฯŽ €7฿„ุ ฮ`žฬ–ํ<>&ซ”*TB^จŠษ็ศ%Fษ|(ฒ.”ขˆŒ H€๓xgฒศ9ๆvvGCฌึICO'€พฺ|"1m�sไฐ๋p๙"ส‚<1ภแย™gฝ$๘}†h็HŠvฯmทๆK�Oภ๓.7ทuฟw๏พฝ~เG๊๗ฬ6ขฟ๒‘�fvซ็ภƒO�ฬ๋�ื _าซoฝ~ํ—~๋๙oฝฟฝx๐"๐ŠŒ€ถg�ห‹€/ฏ่|๙รฟ œ}๎๔ฉ๏]]YŠIค„• *๓ํ€ ูฒ,Y�Tf~6ซ\@uฒึส.—ุซ�œ๊f•)S-ฐ Sภฉ๛ษ๚;PP ถ>ฮฑุคBTศ@‘ฺm>Sฅzbฒ๐Eœผ•ตหคิ7#ลmจwYุ<`A-?Fg.ศน•ญ#ว็ไโ5๕5ึา� ศยtฯึะ9ก™�๑-อ vวญวW#�ฆ+*…Zˆy#TืษŠส ๑.™r~ฯฯWศvRฤlCƒ�H๏s•ศ„ณŒ7/U†ZฆฐTกL2(ฮiฒฮช�v†y€ษุี28L’๙}>&๔2K“ะจ€LpๅO๑ซงขฝฃฒ‡คหิ7@Nดuทูญwณ�ัฒ๑๙i@Hะ~โ}๏รs eWษ๐สฌ2˜PๆS๗0ŠRโฎ{๎ด�ม^ฎ๋D้>ฉ~Ÿ‰5€ึๅฑ+�Gj†;Ne‘สไญ…0ฑ  Hกซใ๔›็žช{ถƒยข† u-YN]—H'e�u]R4ˆ่‰ซผ…ุrYŽ0) aง์โฤฏ�๛_�u€ิฎ�%ถ™ำ>Œ3็/œM=๑ุ‰ร--Aีผ'๑ฉโ"ภตชเา๔-T%!•#ไ}๒ภ๛=™\ฎžน 0ฯ๑^n-ˆ ฝš@IDAT7TŠ07Qช0วไะฏฮC%๗I—ื…ŽฏLพJ "Ž ,ุ$๙™ฉ9งฤ)€$™ภฬe;�VvผฎŽ๑q“ศ�Gฏ^ฃตใ(ูpผ จ‚š็ฆ;C๋2ฯ๕Uฑ�nLŽŒk™ท๕€้%›ฝq�๊(๕Y]šB“tR?qขบ�gŠcH.b>eˆฅ#cพ�ย‚ ภ,ล„žGRฌžiนพ‚A!-ืืl#ำ(๋๐*ฆตYฺX.า‰q5ะ�[ 7้81ฐ ooํเ–Tุ2ว‰ก๒Y_fŒ+๎ุKณ‹Niฅ˜VฐฦUv ec—!ฺฝๆด&P โ1Mœ6(ฉP;ล0ส#‘F๚;นWึœR…kiฆ�๊w�ษ๗~๋ฅ{ส`�/ซฮgb“๛Zอฺ“Gฬ่•ซ(ถ�บ“ฏๆ…ผvPhqrป๗�ืะฺต…”:ญจ;ยš5าjQ_ฃืlynฮาฤ็�ฺโิจMM^ฑฮž�ฏ�ฤO}๘ื�…/�/?�ร—๙ืงK�๔ก=‡ฦ}พh๖ฑ“ฯŒฟๅ ็ฯ�ปŸปg๙�O�/๛๏ๅEภ‹€/฿Š€ง8๐ฆ‚/ฏ๘๘^ใฃ“[๙๔฿>๐•o"%ง6ๅU‹Mไอ%’๏G9ฒˆJฯซหฃ3”K?›hนqวศ4ŠEo๚jซGโ�ฺึˆqaฬฮžนdij]ทถหE$ฬ6๛หฤ ซซ"#dGo>„r๐ะง:::ึ_ช‹PŠฦvŠ๕q๙‹_๘ซฬ้พoph/m—lmc‘๛ง๖zป[5sDค‰�)๔า:ุU•เO ิฅ‰d๙!ฆƒ๓ปPฝฟŒGEบE!สฒฤF๓Xเ˜H>dฑ\ุๆ–fํฮท|ฟ�ขŠUuจOฮู๘๔,%7^ด ฅ๎วS"#๔ื…ศๆ”�$D"่ฬS_�2�แ~ึข$๑ณ–+ย๒ำ๐•ฅ๔h`nž>๕Ÿc>ยLคล๔ิดฦ�2๗u6|dู�œีvต:/z๙˜ฤฃตด๋ค\ ชยษงuธ0N@ ํ๛l™ƒ-:ŒloQ^๙‘ฅ�Š:ˆๅ:ภ\Dก2AํwTึภ.ฑ(าฌ=F|น�ฯƒˆ๋แo”@K v๑ิYซoชw?วข_ ”5{NŒฑดn�รื2C�!อ-mฃๆฌนฎมฦ.\ตqž b.โค’ ฐัฯ๘ถ�}ะ๓oƒCต3uD๑TKYGœฉTลO�ซO“h\ž(ฦRr…โงV›ื†T๗BๅStnั�™šXท#จ3Fทฎุ‰oNX-JŠ+g/P:ิ`>”!ึ‘JŒกJ�DŠก˜[%{�ั“v๐ๆ›l ฃ‡V“v๊น็ Lfํี๗�kตt‹9O{สฅ๑Qbฝiร‡\ู๓ชc_|ื;�S๛nŸv”?�๚ฦ๒(�I๔�๋ฃี๔^^ผx๐"๐฿Gภ#�๛ˆx�๖"เEเ6Žษ๛�฿�ืฆฆ†๛Š…ฦ 6๕ชฝ–ษš6•r๛g—ฮฆ˜ =Yฦ vใฮ$ ญ@ขฒ่๒p(ƒjSฌฯIe r€*Z‡• d�ฅถ†ัสj๗น›โีๅy|;=ษ2Jv`฿{่ฏb*HkB‹ฆ๖.d๕๛๙.“Yฅ$ Lc\๘`ืf\เดฤ๙”ี[Y[ต2^nร๛Gl?5ฺ> ฺTR1ท8OFผฺFzQ ™ฆ%\ŽZ่>mม:Lห่ธPhฉ[”฿ ศ7ตีู�๘*WSฎ’Šึ๎FŽ*๋ง�ฃO?‡Vvส�ๆ�๔•'S  ‘bB*wLห@ฐ ิถ\ฤ‰TYฦ)ƒI๙'•บzwŸRpd8bฦo\FูตบไฝM- ถฒพb›ิyซ๑ค3ณฺฦ:ป:~อ๖ _๊œษโ๗ ฺ๗ฝๅ-VCv๕Dโq Dฅ%[€ฟsใใฅœ#ชณgŸ=อ๑}8ฆทุ� ^€ุ:$ิƒํ( r("d†ทAโŠฎ„l7ำ€�"‚R\๏sW.X ฤส�g)@๚ต‡O’•Eฦฎ๗ฤD’ธQฉMB\‹ๆAOW฿?๐{€yโฎVW�~ฅGF๖�๑f2} ชšึZaVPBSค^ผXเjy ฆaUธ๛*ใJ•้€‹(‚พฅฎ)โซก๕ขน…sYmฺ ข�PvZ๓8ย{ๅoะ@—ƒ‘แ^ป2v9Uถ#‡�*Y๓žพ>d�9;x๛อถ๗ถ�mflสNŸ<ฉ$uฮ.๙คต'โ@€[sสฉXปrาOFƒฌ�<n้hฆ|�@qญ:žhMใsRb์๒Vะ=ฃj ภ x—๑(ญVใฬ›mิ๕ศ๛›[ฺ1็ห!ฏใ:ฅDูฑiฬA••฿ม8๔้“Q๖ฐ‘กkt@ภ$4‚ส%˜่b—ใ˜!�Jไ{R!•ฯ๒*|>˜˜Kณ ฤ�O!ๅ๓]ฆ‚zI�๏งด@ๅ๊ภภ uƒ97-X!ŠŠtษอmMpงเHr �X็Uโว,ณb%ษ๚ุa”๘น+M`ฬห;ฎB”nะfฒ ใษฮฮv{๊ฉง\‹U™อnqL5Wม๓Œ_-8‹4.JฯฦdL5ึม#t�`ž<๒ะื้โ2มWดื.นฒฐ์2ฑฦ็`๕DM4:}์ึป�ไ-๏๚๑ฯว�_?=0ไใb�๑ลฺIภ]๖^^ผx๐"๐?Š€Wช๐?А๗{/^^18�ศcณฮ={u ํn™V8‰0›fQ%›ุ๕๘ส*;'™ฏบจOฝ@ต^j&c>eี\นƒศภ}„๚]I�ปป�ํŽ;๎ฐ��~๋้ํณม!ศƒe'mW?๗ ™ะœษ7้Cพ๐๕ู.๏ร{๗ุก#GํภแC6ฟฐh๓ำ‹Nž-‚Cๅ สT*c(ixฐ^โ\ฬวุ๏ž$ี.ั~อีw๕t3Zภ=@๎ฦิŒ#vจูV๛ถV@[€๑ฎ๏ค )*lWC๙…ฒมธฦ?q๖;sๆ‚]w$ไ๗EภKj‰กะV %”Y”!K”ฑtv@ณข2ฟษๆˆฤฎž’ a™Gสy^ Oๆp๚ŠGก ฿ฉ<ก•ŽY\�e,ฉ>ํ1ฒ๛2‹์๋๎ตœ๏9:Jpพ*ภฟภัฃO=Ž4žr ~ๆง�ํ7฿LzX กQi+ภ…—jล(g๚ฑ๋Sถ €สั crrนuึสš‹(bฌึh๛๗c”ม AS™oู@ับจoใ›^o#{†P=๔�Lๅnฬ,Xูๆ‚j€ั K]-ข˜)VFใw�y๛‡๏บ๋ฎ�'๛้&ะK๔๛๏ฟฟ|๖ย๕้‡�ร$ฆzฏkkoฃกGฅซงฯค {ศšซ4$ ลtp@VŠ‘E*ƒ๒2Ÿ5 -ฯpฏฅ(ฉV‡วAˆ๕ค,ธ@ฉZ~Šขน้–›lpOฟป~ม๎Bึพ�ะA{๎๒i`ตฯฎ\ฟb›”ฝ๕ํ�“Ucๆ๗�3g๐ฝว�Lนๆศ�ต๕T็ญฯ,w�์TCR  ซE ฦฎฅeญh—˜ฟปŠ>ฯบ–Ÿ‚ˆƒc[]ZEaDๆ›lz”Œ~:นi3ฌƒ…3ื ไ๕ฃฌeZ’ฮ-bg‘f.eญฟ|Hxh,ฏฌก0ฺf<”*Aถd๘ ` ชXhmธq?)TV!SA™$ๆˆY•ฦฯ#ฬiผ"ˆซJ ส�-Rหฉ6(‘ZAsVๅ9ŠK’ฺy@„ฉDชŸสช…้9�ฤืe‡ต-RB Vฒ@ฯy‘่9ฆฑI)คฬž8จฤ@ๅ*—๒3—sจiœ™%ชฝ๛ฝZฟึS’fMส็CVTฆด‘ฅmm-๗‡gหศรก๔„ศŒUา*อ�ฑขg™ฬฒxN™_"—ถ˜ฅrN•‹U�5ึ๑6*ŽcC๛`)žq8ZGgื๔[�๕c?๛•��ฯ๏๋\๙O�้~Nเฝผx๐"เEเ_Oq๐ฏœ๗9/^^vุ์ฐ๙�๛ฯ�ท?™�ฬg?๛ๅฦ†บ�ฦfijjใ๔๒.ฐq."� ฉ‹šdผฮุJNKf$ Y6หjฟจN สxfศผohcผ“ หAreค๔l†ฏา+^€B5บE•ูNbFฏฑ�oฝ uต�ท็M”% ฟN$I˜Ÿ!{ni์ฐฮ�.ปxๅ ™ั�๚hฐ‚หDฒป&‹สฦภ21AM5@๕–[Š"ถธดlcิ_=pะ™žมcpด`C…0=บ@iF‚ึ‚๔˜ฯุภ�!ป๛{๎$%!ศZJmะัN—ƒ*ปใ–ป,C]บ๔ๆฯ^8gดV”€ณฟ$r�*2ฯY€Š6๑��€๐iz g(็ {ุศฆมHN•กi���.ถ)โ€‘โ!ˆ˜QfZบ™ฎ]�เฺา‚vjใ๋1iฬุโ๊’ตทต6Jdฉi“xQ�๖"๕>๎Kxไ0กซ-.:!y๔Q+!ำ�"๋ฉ›@ศRํš@ต-S&�บ˜ aลฬnะึIIว>Hƒ๖ู@oฏ?๑lŒูพํMV™โaธ‰APtาO~4x,xฅญัB๓รO<ไdฯภ๘X 82ฒ็ฟผ็=๏น๐�๗พ๗ปfฑ>rฌ/}๐g~ผ5 ฌฅตฑzzf๒Œฬ2ๆtjwXม|TพŸ/I�%[wฆข@~G<7้ฆDo3›h9ู๔d‘Fiฺ Vัrดฟฟ—ฺ�"Š™CึˆฟEโๅ–�๏ขV}ฦOเ๔O(gึๆQฟิ[ฯž>ป�๔Ycน{–‚ศ(rO5—ค่‘นf}s+๗ผเJoHซCŒภ!ดdพงLฟบ\ˆดp–)ฆๆฅึŸๆฉ˜7ฦYง;ใtj�–จŸ—’งˆ)ง� ะฅธฒž๋™‡หธ๘ห(“ @&LX5�j+ฉn":ถ(gฑRฺI;โ, กธฉ5ฉ�TึRfฎศ42‡ว†sฮ็ปlซ5#˜�Mย›"d (€ฏ–ซ‚–‹SBษท๙Ž๎‡ˆบ’œG!๎œฉ*f‹โดนนฮ�/j๏*ฅ†ศSŸัใ๗�อ๛ฌ=๚๐qิฌึm€๕jŒปา)tTถKnD9็ฆ#์2ฌ๙%*aฮ+Oej้จฎ2๊œก๒ ]ฏศŠXœ:Eฯฮktb7C3DTm] •**‘‚\เ]พ :ะดwL๏ป๕–�๗#?%E็U๐]๓”๑๊Eภ‹ภK9q๐Rพ;�ุผx๘ŽG€M&{�๒ต“Ÿ๘๋�ฮิฏึา‚,•ฺ* “�8&b�” [ร?@ BflA@‹ฺžก๋ue %@m [HDYreใีถ m2flำ6=uื๓kชibณ�—ฬ๋กฃGTป„47ฑฒbอ๔‹8ธBƒB2ำิ๚7๗ucˆภุ๐เั}ึ]Oฏ๒๑Y›ธฑ„Y[œ๓กt€จศSŽ-ู|žฬf,ภใ  น2jคฬuฑฦง�›๓๙ฟ2zร&&:ํ๔{�;LIร0๏ษะข๎‚หฬw๔ึ8w๙�ร#ศลำ6zใบ�uวjฬƒ๖เ๑S659ฯ๘ฆ2พ]ํ-+ิ‹ ญ”m—*Bฆ‹y•18BVPํ�ยjหธร5Tโั Ÿรไ-˜๊ธใลP|4P��€K๛ิ์ด๕v๕ะ‡�[]/8‡ภ]ภXฤฟ๖ฎป์๓_๘ฒลQ|ศคqœ๋Tฉษ:YOuบP9…สM*ŠกฺhrO‹€4น๖76ืแะ)คร`{ซขe�๐žA~�D={ตอฏ.PCฅห@พ” :} *‘J*วP‹ฦ๕ญ K๓;:พ[/ฮธชซหอ-5_๚ภ�๕™๏F@ร˜Eฎ�้ผ๛๛oG.�ฮL g*็mn~i๚&๗™{ษ�:RFํ3ƒ”ณ0ตPฯT๗หuษๆ‘ฒซๅž)ฎฎŸ๛d~จŒccsอ:†;ํ่ฑฃถŒiฅภxGS‡ู(_๏�แ๗`ะu�{zm๔ยeป9ยขศ)€tป�๖รv๛๗ุ็�์ณฬ_ตหค“„^‰9ข�>Œฉฅฺคฬ2หู!๒Jช ‰บฅ^@?CKA ้&๗ฅAฉะ ˜งฤต{’ ทฺ�ษฃคqงรย๚๒ ไW‘(r˜o9ึำ�yฆจeiดฺAeFDN Y%Zs*๏Q>„�H9ฮLๅ9Sd\jอ(r!9e„๋“‡ˆ €<๋V%!|‚”๑ศณง%๋L�!e]๋Rืเ฿›)ŒJนWRD‰h+ัu"งดƒ8HฐรXตn‹‚*‘๐†pฝด"•2Uาีyซ˜ ู��!ซnoด`Kฬ†G๖ูฅœ—มYgCซ�๛oฺ่่จ๋จ โAcีšูX[wฤ‡JCค‚Pง ฝ*QFศฟEd �ณฌY+ฃล"ฤ‚Z,‘ฌพ�Œmกึ*d‰ฯฮšนฉซฏoเฏ๎xํซ�๚ ?๐ก'ฟื˜ €๗‡/^^‚๐ˆƒ—เM๑†ไEภ‹ภ‹ฃฯ�/>=5�g‰ฤฦ ๎ ๔๔ำ |ืi\็kิ้ช…š“�ฒษ=œฌฅไถปft) ใœ%sWD&ํg#๏c3œ`l๐ฝŸ์]8RG2l้ฐ^:{‰ ~Š}J้ฏฎ.’–”BK€\ถฎฃฃำใรYOSป;uสVื–^€ฒ}~2‰ญY?€เ๘๑งฦไN๚ฟOd@ข€ฺแ ใ‹aิถN๖w 'rœโรu๚œ๕vtุžAถ€ˆ™G! e•—์y‚๎O<๓$ ŠzฺRถั†ฑีjฉ฿›˜„8กˆk“บ๎•e2ณ€ e๙ฟ+3‰`‘ .รล3 Fึี‘ ?คˆmะJu1จ!๛xำ‘c„#k1E์๊์ œฯบ�บ\�๓Š;ฌI 3 โ†ู�๕๋$ ๙žาHŒuคโIIๅqช(/)[ xี๘ถษTว*’„‡ ชpยฯAฌI;OอฮZ7%Iฐ�๖ฺ๏ˆฃ,ฤ@%๗žำ'่™ )€Ÿส7Jd@ฑฺs๕ๅ"#ฺ๋ญพฆ๊๏yฯ๛>�ูนwํลๅ�๚ณแ –ญoh˜—@ฅม@%fv @�$๗M~2๓€'ฎฅดํ$ไiถืพ๎U–†ดQw€a< }ไQๆ]ญช3 ๓nnpง˜ทE{๐แ‡ํmoฃล`+ˆ฿คŽ>„LฟŽ๙Y‹‘จZ์EPz๔ PRC=>e)Rv”จGˆ0‡(ฐ๗fง�k7ฦ,€Gur7ำฏŽ%ด์Aณฦš(Wื๙dธฒ€บ:ข9žŒL•ี˜-œ�w*‡p�PวHฒ๋sP$sๆ}ˆ„ํ:ฅœIาM!(…ภ7ŸุKYฉค E@:ฯw<h๚!(ณxŽ่g ศฝ'ฏr๋B ฝDค(-’jI„›ึnHคs˜ ู!Rฅ‡๋๊ม˜y.ˆดแขS…p�ฬ:-1‰ั๓%DRN์ ฺI3F?ฯ9ฉoคNว‚Ÿu$•ๆ:‡ฆ K๕๗A�…์๘ณ� ส…›^๓Z๋ภ7กญีๆ Nฆfๆฌ โภ‡ยC•๊4"e„โฃฟีšQ฿ห๓@/ลณšฝW฿วˆก?-]U‚’RLXsR<0hˆL.ท๙,1ฌmŠ•Ž�๚๊��ž๛�NCƒIิฯนczx๐"เEภ‹ภท'q๐ํ‰ฃw/^^fxว;~llsj๊฿�ยGybu}แ—iม่‹V๎พู์“Klๆm‰ฝZฎ- _€T(ฑa๗w3sP™™mโ‚ะฒZ๏ลm;ธพ+EKษ\คnWe%2ˆ.^ดฝG๖ั:mรฎ\›ถภปz™็ศยMNŒ�<2๎}gUญฏฏ๑™3zLำซึo72ถศ๓ษด:“B6�;�;‰‰]ข˜ ฏ{ฬฦฎM’๙„ฬ`ใฝI๘๖๚�(o wจ�ฏฒฤฦ–=�๕ใNVaฃ_‚,ป๙ใ_ฃฬข…^ํy{๊ิS(ฒ6[ZCeฐ`]ึศ†LgHƒ ฅๅ*ฬ�”มe\Aโ&…คสะฤ U ฝ“ตŠ�๚ษ๐+ฒฯ’)็QGLLฮ8BAฆpฝ}/ฟMLฯฺuค฿Wฉ'ฯ3�w@ชจ �งŸณ;฿l+Mพึoซazั—•Ieฎe?ƒถqrส0k<’c+ปšGึxึSบก7([g|ส27ถ6[#%กช(๒่F็!ขH&aŽ-ู๛ไOึ‹jใŠ|([(เƒฅ3€J๊ชช.ดทu�‡ƒฮ|7/—wผรW�ร?�ไรWฎ]๙Aผ)Fj!ฅDํฃd`‰N“๚�•ฎmฉZ6ๆ!P†๗ํกร@%5˜[โQถฝดาŒ�‹dใง0้–ืฝRฆบDF™ฮซ[ำฐKผOฑ‰1[ZXฑW��ZๆOุึ–ึmฯž=–iย˜7i>—!B;9ส~Š…$ก™[�}=vddฟ]ภฑ�™็NcV˜ฦ#ƒ.�อIฦl‰yก๕#ยJ€[DRY”#ฮ๙*}(œฬE2ˆจy CC+ๆXะ’ิK?ะบƒl“1ง�"xจtFฟ+๒3)ค(xี‘ ค็€๓ภ2„ 9a'ขB 9ศ!)"@ฤ]”ฑg่$QM‹Qzงฒ)ะ๎5Eฎ€Ÿc‘JB$„|ฒK<7J! ‘๋ใ9ลœAPช4@ฆ"gŠ,a@4Y๓ฌ]uธ‡๘Yภ•*่yมBฤ›)5้ |i3ฑa{‡๗[‰๛ohฒถฮnHต›ฅs‚ั๑หื๑ภ 6V๋*—…df)2ƒ�<ำwฝt.ลฟSฉžW&่gZซ9ิWj‹*ล“R�ฤ๋!>ˆ้ฃ‡ฆ>๐3ฟ๐ีŽ4p‡๓�๐"เEภ‹€oc<โเ�L๏P^ผผผ"P�ำณq๒ไษO~ๆ3�น�๏/ฬWว๋j–~J วŽึZ@BW๒6ปv@J†L)๛oท๑U ๓%@uะม๒ลมเˆl;›๏(ภ2มX$@ะŒป�ภะสภ›๙……U[ุห€qbrาP=(3จ—Œ่Z›Zlpp]<{ๅบ� สต,วฆเ‚ฺhP๛๑’d!(pตมz/ใPซน โ จ˜(‘ž฿ฤ8s๊Œ๓ |:€BขฏตีŒ{|t 9ฦe ซ๊ฉ?ฆ^ฑ‚ฑฮฃ^ุ€40๚ฒw‰`โ`๔ฬa์”จ…กฒธjโe ูD)F‚!วxส€’mิ*กิ: €390Xงึ–HสO<๒ธ๕๖tX;ญไฦ&fQe&นcืง&msy�ž}ๆ4ู� GšฌขคPๆy‡๖y -h•ๅ&›J�Š]5ƒศUงห\ธ่๊ล๙Ÿวซ‚ ถbจzxตๆ์ฆิฃฬ}ุ^]ท๖ฺFk@Šพ„๏ฤส�ผ+)‰�N<้€ืพA[่ยSaั�ปฌ"กณญํO๏ป๏�a฿พ}๚ะ‡�=�n�ใƒ�น�ฟ๑น้…_ฮ็ oฌŒP�„p!€K๓๘ ฒูษฉ�$e50BƒฝD˜XS"p๛ญ”ทฐ6๖ใy‘ฦ๋เ๏พ๘K!๗฿†“qฅzyuฅธxnฬบ;ญซฏ๕†Œw์แใ'ํuw�ห๗YK�˜ดมฮ.{Šฺzง�ฌ)ฑ8C7€'IEฐŠ’�† [˜ลร"l‡๏ บ์Jไแ฿๘ฦ 2บ%�B>~mสHอีz.H<+–ธฆ(�บถิr‚{#uร๋�Iฒผ๊3ฯีธ{ข.ส�>P"\k„ ้๔๕ หะืพyํฒ“ฯ฿y่ฐ�v์˜]บx�ชš›*ใัวฺ{���๛guO^/ๆำจ�"๏ฯ{พ๗๗Pผซ 2จ ต็\Nฏ@ภฌสจ+ำ~็�wั-Dศฉs=^UCGƒดอRา2|dฟ5Uกิธt9 ั Ÿ[มg&Žป“� …! ž:ศ‰(Š€h)ช๕แฅัQ๊เ™[�(�?๒�7~�›m�‘ฝBd�YRฑ”2hฌน�๏นร๎{ใ}๖ฦžีd๗*—gž:ใด ๓ฝ@‰O‰5…$Cฦ%1 e๒เUชขg)ฎƒ]ๅฺŽ๎ถE่~ผ ๘Š S›VuPKื eึr็๙ก9.Oq !<JLฬ�vŠŸ X๋yฅyฅ zNจ3Jผžศท<%็ฯc ‰า‡8“U™J!`.bLใ”BB$กศH‘‡z๙๕+ญสSj๑แฯ2H@ฝสฺ<ึๅส6ฟ8o#หธญoSGŒต‚€�๖f†X๎น Yฮตอ„S`่”i™rื,ๅ.้๗ชก–๗Dฑคk็zk+นๆ( weWyฉ„#ƒฏ๊�๛K7&_…|ิŠU*(;:๊๔)D‡ ภ}ศ8†l3 KŒPฤAซ๘c ฃฤ๕ฅ+ีั๘Jeผ๚ฮ™“_ฃ“ภ3}##อ=>า฿9q๔่kไ๘ฒz}kmฌ|์ท?๒›ฃ—/ท.--ผช>^๋๏ํฆK๓นภ�ฉธฏโ–ลt/^O฿ยZD—ู/s฿�ึท3+lowฆกsถ0ฟh1ภrŒนถ>;gซำsฮ๛BY๙TP™\vส•*T“ื&อว=qRv๎ŸสJ††๚ํึ[oฒ2s\ฆฆH๊ƒ˜mby๛ป‡ฟfCjv๕v�[�๘&:ฃ$์}�ึr ‹๛i›ศ*๐ฃxก;"ฌส๚ี๖!‘‡า‚XRฟฦซ9ฅŽ(๒)*ภyžp�เ_ ^�–๊Eภ฿•_เณ‘ƒ๐ะ1Žี๊QฅH >[9%ฅE‚n%•ฬ;\Qล ๊Xcš5ี”_๐๙qจผงฒบฮ†๛!าฎXฦ—ฅ…jณํHYฤœ/3v6j|" c”H „ ฌซดย-]…d ($Šd๐CŸ:ศ่บDิไ} sŽ‘รsE>ก(ใ†ศP7ˆ‚.เ[ ‰< *QTm3๎<*_–6‘Œ๙๑ฏ=โฮWธตฝk†่ฬ9–ศ)ฎค์Rร๙b0.Q_R"จmฃˆ†ธฒ…kืฎน˜‰”อกL +•8Dbึึ�o�}ใฏ๙žท�%Ÿgเ�ห‹€/^^ˆxฤม U๏˜^ผผ,#ภฆT$B๙ฃf 6แ�๒—?๛่7๚ฦฝฉL๚ฝต๕ตm™Tชขพฆฮeฎ—i}จ๚]ฆศฅ k(™ญzดซ๎�จaSภผ”P$lัขฌญฆo�ๆู\ฯ�˜ฐ dึ}์ ฒซ-ฝYkjฎด๋ฃv ir  EdBŽอผฺ.To+๓ ู„(4โLตฯJTท/ขฃ€Ia๖ฦ�฿ษ’•ษXZ\^`‡jป›}2‘ชcW๖ืŸ�–ร;€ ัๆ?`W–>ขฺr2๐ฝ]�\o’็ึG†}GX•ฺฆa„ท‰!�4~�}ศ๘[๛ผZย5b๎828เbต0ทD6rFDRxd์ธศsŽ] s‡M[ฬห…>ฮySิb‡ธFŽt“PปIคภˆ,e”8l‘�”�~ZŠ๕๔zฟZฺ‰เQ2นขAeEzษว+ƒ( tญ�ว%ฮนฬุSฤึฏšŒ๗ดเ[ŠVV|๚M๏ืงbฑšศษ‡O|า �G�๗มวF€9สzyฟ>’�ุ•/ฝ๛K๏<๓๐‰wb�๙ฑ@ฤ_S ์`D‰™!๗ไl็ฮœฑๅีk ƒ|็wบนฆŒ|ooฤNM Pถ\ฆšL}ฬ=“Z‘=[ฆฃˆHกs]ๆxQ:5D๐ลจเ�ํp฿ีŽP†—ี๘h)Iธ9ต’ูภศ2ฮ�Gฏb-ีB?wฺ’˜›Bมณ‘ุดํฤ– ฺุ๕iJ‡RVแFๆB‘ยQ5�ฑฬ*ๆG %9‹Yปต�nพ ู๓kW๒่ี+ง์>ู๔@š?™ืgฝ—/^ผผ0ะ ฝ—/^ผ��Œภ�๗฿Ÿ๛�็�f�้gฮ<1ุำ๓ ’ไดœ…BซlยฯณŸพDถ฿๐ฉฌซซ hึadVSW…)�าฃด็# ซ๏๐ศPžฌ�c!_�|jeฎqqf<šกW|.ฝŽ�ขอ�˜ว—‰2๛0›๕SO>Eo๘+lœ›๋ึฺ๒ส&ูK ›�ฐŒิุYiy$~e@๙™Z,สห@;‚,|ฉข”#HึฌL}PฆL <Dธ๏ฬสt*Cบ“Cปคลi€ฝภ‘Ž [ฉ๖oq@ถฒฌdวฐ€’€ตtดX฿ž!kฦeฝ@–`๓ฟˆู‡ŒUƒฺ�U ห€‰เคzํ›ฒ‰‰ถฒบl++["=2จ( บecเกzrษฐร’คฃ"‰ทdฎีุท๊ตE† ศUพ•F N๙Uะฝ๋%ฏ–vRfฤซีศิ%1jิ!px*l CJ•wิีEKM 5Ÿ=r๘ภ/}์ท�เsWฏ�พnv9ิ�ูq๎]๏�ษงAEๆy๙ฟ๎ไ�๒็�๒sฉ?์ฉsฃฯ=ถB‡๛zz๊7)Gต…0Tgy|tฺšZ/Aคฆy{‹ญำีไ์ภ๎‰วžขต!>�ี๚K^/Lๆœbิƒ‰ ˜E‘C–[๏‘สGส jN1๑PิฺสuๆZSCฃอ"ฅฏ81w๚๚ƒถ85k1J]๊ใuึ��e‡๗ก5jฝ๋–ขถกŽ(dซE H7อ y”˜ื๊Pว<�ปา… Š•]น=yฦšีั�d^‹ูฆฤBฤยž{Yฏีvm์š+RษPw_Ÿํ;xุ&๑้ธๅ๎;l�ญ7� 5๛9”E|ิrฬำ Dมพc๛ํศ-GYkt$ c{w›ต๑€ไ“๏ยf&ฺ้ฟสซAJคd‰สฅไ1"ๆ@J$…Pํ๕i ็TFbฃulCIS�œJGฯ ฒ๚ŠญZLส“A$ˆLMนT: ค‘kj;หณฒส-d)Ÿฅ”* ‰กgาฎส@คŠส2Pu ยะ๗โcŠ*aโนก็ึง~ฏฟฃ\ห&dชH‡ฐL๙ฝึ:“…๛ถฎžŽ๒๐ศศ_��ฟ๕ำw��ช3ฏ”๕Fผ—/^^”xŠƒ%์�IฝxxนD€จ์9}ฑู��fงฮฮvaม๗ะฉ +›[ร๋๋ซw•K…Ž้ฉ้#H�*ซชk๊๊๋j67ท.๙|�/ ๖๕_๕๋๎xชqฐ%๙อฟ๚โก•๙ๅกน้�้Tz›ฝr�้gฎ�ท87v๋๖๑m฿W��ฦ๘O›๓Œ๚V๑@Oฯ�-�" j(๊’ฐE}ถฐ#`ํ๊œZ˜๖mŒๆดOgฦฃJ6ๆNnอเ%MNธ:k๚ฉ“ฅh3ฯA}l๎•yLo'q~วิ1ไๆม(}กy$@,ฅถ์0dมพ‘!ภLฬข€’cเํdQsึฅ4Bฤ‚H ‘ไฮ-t.๘๚ƒ�`-ิบ็ณj_็ณ†ZLWทน^คใ()B2#Iฒ@ำ5 ดม)8‚@†uvแZ‚a๊๊Q'(S)P"™…สส่ๆๅw บsySศลพ๊รซBD@W1”OCคฒ0ƒ?%๗ฝๆ^ตฒผއ?๒๖ทฟk๒ง๖ื|๛๗_๎�๗n๚gฺึย๑r๙ฯา�…'›๋GŸ={๑B•ทuwธRƒูฅy”"ห๖์ณO�e8}C–l่ฐ€3‹&J–ฟ?7Iนwฉ]’จDค‘JGฅ7;(ldถฉ9+@šฦ ONิฎ0O๚>‹“ฟT>ีx�Xœณซ—P3Pšฒƒ฿พพ~J"”ภ$์ย™๓ถ<ป`Fลiค<งฦ:ศbฏ@d™/‰uง’‘้aี‰ภฌ^jQZ…9f๏xAิ(”พ๐~-ผ�:~T,[ZWiฝŒ—์๑'uไ^MSไaฬฺ�:Pํ@BเU๕ดฺฅนI๛�#oฑWฟ�ต๖๐—ฐู๑y€zฬช*"(ชญฃณ�._ฟฬg(ื@qplเ˜>v”rคญmmฺ �]๊"ีช.�๊ฤ2ใ‡"BŽrvy•'™0JuภœูขMZ)†ซiฉฮ ” ญnเ/ม‚-SŠ ๖“ญ#uŠ  ๒Gญ5ฎ]\„ศ„de|ๅ๖vย‘zRh z)v๊ขขœI&‰Rศbg'้H)‰Dh}ฒ~\œตถE่็""๔;1"๕บบ;ญทฏ๗ ๏{�O�ๅ"+๎�^ผx๐"๐‚Fภ#^ะ๐z๗"เEเ•6ผคC)๎�ว)<›aำ�๛Ÿyไ‘๚KWฯFbต๕G+ใ‘�oบ้–?hk๋ะ�งŸ9ษ๛}๎9 L�dฅ�|.<~๒�ทŸ�ตwOฎ�x'ธoนช๙Mไ�Y6�ีuญศ†Q์ทK^ี"‹–šฒŸiLeจ๖nควดtx9ฑื์eฬgCพฝ)  !ŸSMน e๖ณH–ตั—B฿Gํz†Œจฺฬ…‘๖(ร6ิอAฎ๖ฏX ๔โ(Oy’b~ ่9˜tีลซษ( ดซl 4ใ*�3ธปซtโ๊•Kd79mเ‡ส–ส]�ๅFTnQๆ\๚�ํeเ&™ธPŠ ๒DH่๛ฐT ธาGxRX่ฅจส"‹Hจชฌv=่ณ บฮZบ7Pผ€Q%dว•raธท ๅ๖ฤส ฟพถบ&�ีำ�GฝmงทถD่ฌผ—ฝฦา4ป ฏO|โcฯ]'๒แ“O>๙wq๒ไ#ฑชšO\๙งŸบ`ฃใk)Ž๑’2yrf—็YZg–6�aฒŸ*9POweาทไทยู๊Œ็๙ฝHI๙ีฯ]ŸฃHตอ ` คmdmh �ึ7ถ "P*0Lm์kX%ศ„อไฆุ;d{F๑จฤ3เG๎ฝฬ{ช" ช” ไjศ1Šœป๗เ@ขญPห�ึิeำ›๔ดง6รษ Ri๘ Glจอœฦž�ฬโP Qื‰j เฅศ4ซV›r@‡ไ�YฒœAฮใ๗’ฤgธ�*ˆ ˆ|%Yk€M!+0Šมe KF—’OKี€) ขบ€tx๊ฆรว~๑ุฑcYzฬ_๎๊๊ส�๓;็�ไŸFเ็�#Wฏญ^๛‘๋วO5ž|โ‰ฏ –ฒถนชeeuอ›tม8๗ฌอœเGญบฃฦ“—ฯ_ขœ…ถœ๘Vlcช—A./NฐฅUะ๑ E้LE€ฆu•4`ฤ…  aš'ลHšฦ—@yy{ฬ\Kำ.ณ�•ีˆ Jฮo9P๖Aั.0ศgJyˆ'ึP3ฯ2s2'"  6_„ƒPฌา ษ๔E@กย/€0ท๒Z3ฃRjฦU†ภRF? โCอฒฝžฑีR‹ตuต[p|ฬ๚Q„ฉ —R!ภ{�@ศสึTsLˆ†(ํ�dW*ฃภ >Qน๑็๓W8�o฿๛�๗>Gฌ^๏๕/ˆฑ้E/Cg&๚›๗฿� Oตืv~ไํo�!4๚ฅฎใ฿๘ฆ�อgพBท…F๓-ะั€๛’„�!eํฺํแ›GkMJN ไ�Ÿใ�๘ค,a๎฿GeลŒ3k�จQ(!Iษ€๙•š)�”ฝž›Yดzฬ93w&(ณ‘สEค‚JไํฑŽGH„Ÿฉnพ‚์ปิ1โด–ไ“ม4b�`ศวผ’ง~ bN~๒ุ(ำAํห~ีโ @!PืTํ๚dˆ”Šc)3ฟ๙™K3ื๑สุปo?ไไ^ ส๊Wฃ�)r ~ๆพึS โ*์฿‡ส๘๔”Eนฦ$ื0?KปT�บบปlnvษe�—็W์i:ญ4…j-ป แ‡ รe๎kŽตE%ƒปVธ ;x๘-ทmvfฺ•utw Š†ŒใูH—!i{e—ต๗๕โ'RI้ศ$Fง“\ƒ:ฒ๐BมdCEuhP ‘b –๔6?‡,‘\IO!—๒% ย€ท;bฏ‚ธ๊{ลOd‹๎โcƒj�สรFฯ$ฝGKป€?F2ฉž๒ซฦ๚ฺ๒พ๙ั�›Oดy% ฤอ{y๐"เEเ;8๘ฮลฺ;“/^พ-hn:�oo~3>:11๓ณำ3ศ๚ษบG( �@'๛ ว�ฯ๘ŽW‡œ๓ผ2{ส๚๛iwุPWํ6๏ต5UŽ(Hฮี–ญฤ&_Y{r$ตง …—+์โe๊ล6}�ํถI ๏Y fa$^นภ%k-ี –ฅ•โฺ๊ชuำo'ณnŽำาุbใฃS>ฦภจชฌยnล:�ˆ}๕pดฏก„DH @ฆ’gxH)G†s๛Y!ศ €ฆez— ๐ผ@Œ๗H^.™ดŒA„–xศK‚๋&๛ษฑ๊qวืEดิีนr„]0Z่t!†|*|“ u _oii๚๊๛฿��3i๐ฏŸพฤ.จ๐™g9]]�ุ�P��ฬN�mใใวVืท๑ซ€XS-|ะj!HESƒ&„N" ‚ฐไ�*›ฏถ šำ"‡€]e�3x!ศ์Sฤผ|( 4wฅ@‘zF†˜`[~ม|Y็œšชj�นร��Fjงฮ_z•พ„�1ภพภz–/‘yึUSK“+QPy‹>Wฤ+รiฆ.jƒZJ%ส:m€B€ศฌ76ตฐY'H(ฒ[จ)ถP6เษเลle~มu}X˜ฅ#ฅ\.๋.’$ื�T่Qุฉ ”ยฌ\iหs ถ4ปb5tˆ”wษ‘ ๙ฐ†3t›9‘‚ จเ�*Oh๏๊ฐCG�l}ใkฮ{กŠn'�=ฝ(bvแางP)P฿ุ€Icาš[�lia�•ฉE๋Jืญ—ิI"7ดฎิูล‘rโืt/dj(r๗ฝzฎ์š+ชS…LKห�7ถช Š๎›ปw,L�g;ยšT‡“ZบG4A๚utถ>๘‹ฟ๘Kไxซ๎ �^ผx๐"๐‹€G|วBํศ‹€/฿ž(“›HŒ฿๚–ท$“‰๔๘�๙น/จฮ8Š๑Xˆ แ6nชŒAH๒[J�ษ้]jm�s€‰j“ซTRD้ช้Wใ6mๆ• tuษ{e-ี*.( (W†3ŠŸยฮ๊?f]•�ฌซธnไHฐ,ะฺnะฐลฑ)ภUฺึฆg0“‹ูา) `ฎ&ฟฮ๎„}ใ‘oฺื๚†%hี่ฏ`!—qvpี<จŸ�น8ฃ๘๚ฟ�; ปฮ๒L�w_๚�พ}{ouซี-KฒdYฒdู๒พacA0`\I›ห{ซ๔&๏๗She(ะญ-ถYr ึk)ขอ4Y?ซ|Vp[sมd�ๆToeRlEึ๛เ—|[•ตฯญจb“BฏO๎]ฅ hร{sF*ˆ †:ExnrฮอŽŒ;?ŸฯŽคสQ”�๖Ÿ>์fŽu;v žo�b6{็ฮ�ฎภjs๗x3ดณQ… +ปedั�ว3นsŒBรโ9�โ’1 +ํ�ญณ™tsนฐสหๅzฆˆ‹z]gšfF?‡จ๋ฤำ ฆI วig5;Iฑ็งัห๗ุX+ฦyสั/ ฝ๛�ท�๒EJ˜ทSํ๖8%ฮ๗๏ฟ�๑#[พณ้hฅZน๐‚๕',v๓ศฤ4๊2…0ฦž์VDถาฬjpOX, ุ๛m ฑ„๓4่'๑uFZ4พฬฌฏBdbฦ“แ“~แ%T)`อT1ภ๗#: ธg�์หวฝnFๆaยt/A๓(ง@”cฮe็\ ั6T็Sผ็Hfh0ŽpฦรLS�ข3†\'๊ƒฃH�‹$ุ(OcCฎว+ผq\๔%Vฮ[’n–ขzr2ห๗บ ใีlลงr.3Cฃ๕AŠค†0สkฺอแsห8K ษั ุ{xฟ�ฑ{/†’ำŒeคห( ุอkiPเณ`อ•2ๆขฆผฐ4•p˜ <>๓<1รAFh ฌนื /vธ�>ฮ{>’ีฦ’Œ้ขมEx70มsk‘ํ4 ๎ใฆฒไŠใ$๔\๘Yb๓3˜=ฐŸฆบˆ ฮฐฯ‹E๓80๓รyต‡ืศx๎๎4ณC๛ป5ฌฑใg‹็ืยตฤhาP r‹แ�jiีนkธ๒ๅ/�ิŸนรฦ_ด‰€ˆ€�ž ๐ฃ^›ˆ€ˆภฉLเ‘GXs๛ท�๕ศ่๘…™\nธ\ๅ{V๔Gง2ูฒJhv„ขม ฑMŸRฌ,Z1žxฎุล…}Š�๔ ซงืๆซ[5€๛9Mk˜qขI‰-ี ŒiœU็Š“พN "โ|ฅ‚ศ2o,ˆV-Zุ_oFข_0ยY0gPฏถ96;—ฏ•ึว ถŸ™ก๐๑G�Dfล QuV@ตธŽV $FB48ๆ‹ข๋!สn�tq~EีOเ˜fฺ–ฃศ๒SุxrvJŽ43ั ๛ˆ~ฤง ‚ขfอšๅgืlีL„FGœ(HV•kŒ0|ห�฿๓ฮ๗� ปป›ฅnmว›@๓ฑf่ถMพ.Žx&[8{๓–G(พ๑อ`Ž>HQi !‹ดธF๓9ฐ1SŸ๘่XมoซิŠ๘ฦt{{ธOx�i`ๅ(|ญ๙eE์ผgด?jส‹)ด”†๙ฯรฌœ[G; QF[์^ฒbทฅ5‚ฒ ํz๚ธซฏน†c:w่ะ>X“mŽ๙^ทฐฟืุป฿ฺท฿uuvปM[63rื‚=œฃฉuŠน 1ฅ žžป 6ฮกมฝ@ก‘๋hsMžห� _:>>Aาย� “<ƒฮ%1SœสŠนtŠ mK s –žRๅY#D5R��ตYฃฏ…Fb‚Hqื^m�๒ี+�y]่า=iš"qฮัš ศP4ุฏ v3NdI$[ทa^y่สค ' œฯ„{๒‰Ÿๆ ฉฃZ†ก5:ฌ๙hJฅyๆœฃM6๎`�%ฆh*ู๕6Eฐฦ ี Rฒททื…P/#ชฒฮฟ[Sข5ฮ๘”Ÿw๑�wะฬ้๎wƒ‹}๏บW�ษ{ืฎ]�คิ?ว๛ฉิ�E@Dเ๙ hTแ๙น่ซ" "pสXฟ�’ํศฐ฿�…/|zูท6n�b6WY๐c8ะษ/๖uwŒkิ1Lใทsฬุ?จR,๐หy‚•P“›็@ ซ‹f(Wร‰� ๕:ๆfV„4}aฯะŠ.ซ—VุwDpLงh˜/ฦŠxT‘๙#?f��K\_g๋ckื-๙8๕�ใT๙�Pฉ^ ัดH-_ณz�E็ž3~��๚฿kž~r็ห'ำล?fอr 49K‘‘f>ฑ‚ะ๙๒˜ฺตา( f‘j/Nใย [%ฎฑ๊I-ฤวผ‰๕…๒uŠไHืi’Pจ๔0/๏๓5ฆ๊มภท‰o\\ศ็ฏhเ`Pซd™๏n$Z{[ข-Oโั๐“ืฟๅต_;kแส฿ว>มมต�>๘ฮ๓Uoฝต๙ญ5k๎ูปiหƒŸเ�พึนŒ฿Œ๕l…>Œฐ๒žรƒชขุๆ๗sฌช‡ฝูw”/žwEฮ{z3๕4J“34อ(\น_MbPAโoJk™๓ฟล<ๆXฉทFw๗zรตฃX1…Ž™๑ี๑!0o �ฌQaๆ…ƒX%ๅใŠ™$พธ ค!ึ•ยฺ5ซ\?f…ฃว�?๚)อจ6๎Qž�)ธษ๑I—งแkK“ถภsE๓a’๛=ม3—FEภพ'i�ตงQaP8Cำภ๓tเ9˜Ÿb_=FIๆฝxU[ๅoP`�Z#ํฤVฌะgs๓ฑฃ–>b >ฎหิEึฃ4(0Baอ‰>"3… ฏC‰dš06๎dใ•Dั;๊๚ บํ??Iู-^ผิ๕๖ ๐��Cm๓ฬXmผษ๖ณข%๙œฯRW�AิGถ฿็DฆN0ตu8ๆrs๐ง™ย๛Yแ}ˆF j”i•P(”Q˜ฤ]7MฟE��.•N4าฝ]๗wูๅ๏>๗� vฺ๛กMD@DเฤPใเฤpืQE@Dเ%ภ*\žๆมS๛�฿��ทm��‰\>ŒE‰9ฃเ n-Oใ๓ื1#$šBง–ๅ~–Pใf^fE:�Ÿโz“๑7รu—'Šฑ)๓4E[ุV์)@โI$อmMŠy+:‚qS%ิ)ชna{‹‹ฑชฺŠy๙Šฅ?\๚ฎ๗�๛Uๆฆ๖Ÿo?:p ๙เ�=_œ๙ปอ[6?r๕†>บu๋ใ69=๓j๓8 ถc๒ก˜มž+ธฬ”#kNต2mEๆLLลŽvHA  ๑nIŒ๒๚๛z๑|pีT[�ƒนํ๎ ฑฒ๊แผ1��^{GWณฝฃ;ฑlลŠฏฝ�ฺ Nฑร๙J๑??_�หq p๋ญ๗ง�๙3��ื�ฉ๔7ทo฿๖ฆl,t~“MSะ= ะด ›ฉg^ๅ 1‹ๅ(Gธ'3Yา3ณŒ'๐พ‡)ฐCaึ‹๓๎�–�as๖�๘e”<ํืšb6wฯ๛ฮ็Œฉ”๋.[šŸรว ฯ ‚…}�ค D™�ง๐็�ถืLโ-0y๔0�17 ฟง฿-โ™ยˆฐDŒbธีS:ไ‰2ดฆœอ๚‡8฿"ฃ 6f`๑คึ˜ฅก`ณ7ฆœฑๆภฤTีมฑ1 K“ˆPx�XEƒFŠŸย๔8ช™ ็YvF…\GธQ+เอ[ภฯ> ณ^™77ฅํ9"ํ<ฮหิFf�™™u“์ƒงษ�G–Q 3#2สร‘ˆfคŒง `ฯ–)>v=ณำ’„bสฃYพื$3.LIsณq"31ตQ&3/5EOŠŸ–ะ`)๖�x�ŒyX„j †๒…QญFฬcผƒŸQจ,�๐๛yn1@\H|ๆP'&ฅญษr�เภG^๑บW|nีช ฦรญง]Š€ˆ€�ิ8๘-`้[E@Dเd&@T�ถm�mษึูlพ๐โงŸ~๊u xq‰”Eษแ.ฯ/๑ ํ8’l๊l~ษ/๐ ;EXŒเBๆกgi(ส๓E_�ใ4"ศ‰หฤฌYrA ซ–ๆ_ฅP่!•มหฏw%ิษJw"QH๖๖v{p้๐ฆ+ญ2๙ �ะซo}`A@์ัK.ฝ๊ใฏyอ›ฟs๗�wฮ9v6e฿#ใc?ž:6๑�แ๎ิ[16“ท’์ ๒์Z•cฏbs�t>j๕f[*ๅ‹วฎซ๙ยป~eh�๙_„MqำฆM๛/พ๘โ�–.=็ศo8-�๓ ๐—o๙K[Q�๙ผwvtt์‹ ๚bแ‡!๋Gƒ’�3+4BณBค_U@‘`+ิLโxใ75RฒคX!k#Vtว)†ฝ๔๓�0U wค™$š มA ะ๐ n็ๆ๐ Hb.่l–hŒ๑\LŽŽ!ฉ๏๒F`4ฺB4:Yญทฝย๊}{oงv3cใ40ฒ๎ฬgน‡�ฮุ@ €ซ๊—-ฮ1มศ+๚*J+ดi€5mฌ‚G$Hใย<,•ำโธ<ŸaK.จRˆำฌเlขฒkn`ฦXตq .k๏y.q๏[ฯยยR&Lฑ`วฒf‚™VQูณŒ‰ว!š˜Lขไ8ฐ๔พ65“uฝƒ�nีšต˜Rฦ�ม}]69Ks`‚T…‚—1v๘สF4)ใู`พ�๕pl๏8ึˆ ยฦŸ‚44ฌนัไ}ณฦ†=›๖^ กaRๅฺ๐–@GตไCมg_ฝ]˜ซš  ฺSจข�.ูีzื;>๚ั��ๆ๓อœ€�Q‡๘%�คื&" "๐‡B`ํฺต$ถป;›อย}o�‹ทP7„ฏษๆ3!3N‹…Z)ฃ˜ํฆˆจฑขˆ๕œ็JocUไูXฤ!k&&�E‡5RqVnซืส<ด$๕Fมฅ1œ‹ค1d๖ฺŠซ@0พgํ9็| +™>ุต`p฿e—]6IกNu๖๚฿ˆu๋ึญฎ-ูqg{บํ๖ต—ฝt๖ฦ7๘šƒƒ=ฺ฿ฟ๔๚E๋/้กนใ_>:ฐoฯK3ูนณปบป –๊ๅu-ฑศดญ�"?๏Gzพปปฏ็ซฌvอNฮผ>ฺŽ-^พไoฏ{ู ๗s"�vๅ•WNศ}่7ž“พแฤเžกดw๎[฿๚าfš<๗W�kz:Qม xแ~4ีฬฤุด—ช@ํZ(R-~ิ$๛QL/c4•lี�gJ๊�ืฆR๐Vใ)#�A��'ฆๆธ๗Qุม-จnจS)ผํ๏(Lนย็~๎๗E๚ถ‡u‹—-s)Vยg'˜f&ฟ•�/Yถยs๛฿ฟw‡›žภƒภ๏†††�eW\แ�๒‰Yาœ‹qn|œKž็ฬ”Vฐ�๑#Z#‰มžC�~vฮ&๛7‹ด4'Uญะเ™ใฉณ้ฬ9ข`ฯa“yณIa่˜G-`‰ถY3%Š๊b.3๋๖ํ�ํส…฿[๖ขWŸsฎซ๏~Dž4‹9ฯุ๔๐žg� '๐ZศMฯบšลF2๊‘มr�‰R!oŽiM{ฬูx๏hNฬ7 Lู‘cฆ๊0Uจฝ๗$ˆโ ลB˜ฟง42C�—Q"ฎ1๊๔š&~š�ƒ�3ฝ�tฦส3?งฆ‡Wˆ€ˆภIA€฿ฺD@D@� 9ฒซใ;฿�ฮ๒้ฬhดฌ`rd๖-˜�ภb_.Ž|ล ๘�UๅJyaฑ\ขน€๚5ๅฟณT๊ญ^–)ึBฬ"‡15k‰aศ๊aช-�uขิ็ ูล้๖ิSmฉถM๏น๙ฝ๗Sล�iซ� ช๕)ข หศ๙ญฤ.ฑjo_ณ่Q“��Hƒ Z“ม๎g/n|gฅJ+โKฑ(E^C๑;รธฮŠ๓ืบ%+Wธ'~ะตP$๗0ฏ฿ต วนfต›œqปw๎p—\~พUทgื762ๅv<ฝ“g(เฦG'](†) r™U๘ …็ ๐ถชฺฎฅ†B`~cค€ฦา kิ ืfโhM3ฌะ€ฐ‚� ๕0ซ๘6RQกHท}˜๗k๘จ,PMPฝW9ฐๆCˆ„ƒ*€j=ว„Gี 1z‘ค๙gซW\yต‹โYbsŒxf;ผ{Kbยh Ž"ฑŒY rณE7ใ+aฅษ@ห1’`<ˆdิฆ.ฐfG…kฐFžท็ปภ‹hดใิ์ผ1O5ลRwšhEL[‹ฒฦBรSLK`ษ๚�H :|ฦโญ/๙ฃ[พ2<ฬต‰€ˆ€œ4ิ88i� ˆˆ€_›7฿;�๘ฃ�ื�ก๒Mฏ}ํ]__ํป฿�๎’�Gฎ�ตsืKŠนู%ฉtr56r๘ศ™)ถ*ฆัxผ ถฤZfbมะก๓ื^๔พ—�pรaฮึTkๅใั08พ$ด๗S „ุuืฝไํฬ��ํ๐ะP[…U๔)Š~๓ฐqO5ภ็ถyc ข5V�m!Kqže…�ค๒fุŸ+˜’ภฬ}nzfฦ+พฌ~[ฺˆใิ๔.'ฉ€ฟ๛h&‘ ˜‚ ˜ษฐŸuซึ็ึฌ?฿m�ั=fโb˜‹ถ๕“โภธN“ม้ฉiVแ[)”ใ4-ๆผ๓(ก.ฐฆF3G;Nž�&RI/๖ิฦฬXิ ltยฤึGจ[ข ฿BฮoŸ›ูง™ฺย=} j๐6ปN๛>“.‚๓ l?ึP0ฏƒฉ$ถk˜ฯ€}P%๘่ !ฅn 0�ำ๋บ๚ $ชน๑ฑ—›tET–jPmv‚JภๅฒŸหฮ๒_ยไ่TOฉd ศ,Š5ส~mt$†ว„ d\5D‚ฏ…ƒŒM๐ย MƒถD’ิ†>Oา*ถืhไb‰ไ่9๋ึ฿t๕หnุย�ญRืฯ(h“Œ€'ูขำA ู<}๊P6ึŸ่ฏSฐ๊oอใ๒ณณฟGย˜†๐<`–Nbฃ LO-าฒD๊Jฅ’GI0ํโจP1ิZ“แr[{ผM&๋/บ2ฑ๊œ ?บี��ตปœ/ฬˆ~~iโผˆIฮว”ึ$‰F|คกะ”Hถq.ฤ0ยดฝฝ“๋ฐ๙zศOSฉ๖‡ฮXบtฯŠ+E้Pป๒ลื?อy�Lvq๚�่บb8ุj‘6ำœ€ฯ7lฒเŸ—o:อ‘่๒O“ฤs67�u๏]<ต้แ…•Jse6?w.iฐ=�ฺW-Wื้liiษี๋ีัฮฮฎฑ–h�{‘Xไ0ัˆimMฎ6€q"ง๙y๒�0ฉ >Œ‹(".ิyฆiฦฬ๏ ‰Q€๕|อ^Œ ๘™อO4†�๙]้žPkฐ;nึ‚ตีฏฺ�์Ž�ฝFP6ฐ<ŽขfH๖๔8L:=ๅB3AOmภ8A‘U๗L–ไ6b` k~Pว๓ต–^HcภSI ช yภ ,๑{Mณ05;ไ5ึdฐๆ‚ฅ@˜ฏV๎ฆ`ฐอš!oฬ4  Vฑืญqกh%%&e†y—  ๐ง\wGzผsูŠ zŸYธฐ{ฆVฌU๚ฯXิ\ฐpษ฿ดฅ:.อื๒๑้K8DทOgf,ฺqธ”mฦ‚�`สš1ต*Qฏ๑vŒWQnุ˜ž^œซkV—.;3ำึึนู oZ8ฐ่�‹ฏ|ูNชฦ๛๛‚7ู๕kxแ จq๐ย3ีE@D@D@^ —&_Ÿ~๎ใ‰fsำืp8๐น๐=w~น'�lจซฟan๕ลซว—,*vuUฐC฿rหปš““ท-[ถ4ิ_้฿ตo�พ ๕j-2ฃA*m[๙…P) >จิบ\;Ÿ! zฆs*ษdbgฑT่ pB๐ีb+ฯ\|ว›ozืงฌฤ?๐hจปkQใ‰งถ �ฬำoˆฦŠื3POGSŽLผฌY ๕V‰Œ ณ*ฅxob\˜gd!Šฯ@œ‚พ„๗‚ฉฬมSpฎึ๐L)่ํ_–P@C F๑]e,ใฮŸk™”šึ1ฏ�ฬWภึ ฑ�š™ขฅIุ�ๆฃผ„จ1•ฺูœ V1ndcล๙g๎_|ลY฿8๗� �ใฒ?๓ใ�วuๆ�วฯ๓4mBO?พ๑ำ๕fเ+~นไ๊หƒ—lธfK'ฦ-๗�ฐwfl2upฯ3ฏ›หฬmH$’cํนถtGฅ”)<]-•ศ„Eูะš8๘ขoxfษŠ ๗ร�ฬ[ต‰€ˆ€œ‚4ชp พi:e_O`ำฆf๐ศ‘�‡‰Žฤ๕ื_เๆ๗ผใMลrๅๆ�[�ำํอ\.S›ห0 ๏Ž ,| \ฬ—ซ•R7๑Œ›�๖ถ7|cวŽกPผ>==�ำ‘ŠW^�ช7mก๐�9=…uหฟ้ถๅฑ`k๋…ฏ๙ำํoล ฏ›๚tอ‹T๋xะ$(#๊gีฏ„ ‹๊s’�c 6Nภ๑1Mด&อ อdฐŽ‚!eฑ@”|๓;ฐ๘ั:#ถ™ฯCตJไค%I๐:๓0๕„™=ฺ�,กBิa๑ k"ดเ็PaิกBŒjชฃี๕ด›็Ÿท�›o}ใ?ผ๒าW™‰จน�สฦ๙ู๏‰�๓/*์๋lึะqใอfbb็ใฝญ�ำญฬvุนา‡ฬ€?nฝ๕_kฏั&" "p๊Pใเิ{ฯtฦ" " " ฟ%f๓ฑะ'?s�Eฅb>940ิ(Uช๙งžzขษ’%Oฝํต—�ูพ)1+ลฟ� ๐ยน€๖N":“�ำ‘L.›)�฿�}์_w=ณ๗ฒ c%V๙K4ฆฆ-ษกF4# 33s�ƒ๙๘�aผJ๓c4L๖๏๙ฺ�[Owง็ษ`ฆ.เ\‰˜HK’ˆใฑ€Q‹yฦh"๘‚^SY๖ห8ช‚&ฎŠ Bะd0eBลญYuถ[ฑxฐ๔’—ฝ่ๅW]๗฿~เไท�ใฑว eณูๆUW]๕ œ~ห�่�E@D@N!jœBo–NUD@D@Dเไ#๐ฬ3?Ižyๆ%ฤ์๔๛�;๏น็ปฏžšœ|g!S่jยnv6Oร€XHŠ�9K| Uม< ,rvฮšุ22ฟ`สS8 �j๐รH‹็—`ใ fX"ตภb-1ม๚ 6โวไะ|*…Šซ [3Qrฑ–€ ๘�F�๕๕ถนฮฮ4ฉ]ฎงงsjpจ๛ž๓๕Ÿ;ฯwžฉด‰€ˆ€ˆภฏ% ƒ_‹G�(" " " ฟžภ๒ๅ—f๎;๖"ๅ�ว›o�‹ๆั‘ัิพ ฅ4Q๖Jฆbฎƒql6G”โผBภFLeะ๔3ฒ �'4 P |จ0ขเC9`~ ฆ6ฐฆA•๑ฯxก€"อ‚สƒ:‚‰X2ๆลKฺ(ƒETV๑D่๊oqฉถค์ํs1ฦ-^�๕ฟdร''ว]็ึyใ?w๎๚TD@D@ž—€ฯ‹E_�:7ฆŸ}v๗+}๔‘ทf2… 3™9’H5ภ ัผ LeหๅH'({ฆ?SXฒB6StA?อ” šATd8•ัSTP X\#๊ณI0๕ACฦ‰�@ƒtˆ—nmฅQp๑dะ๕๗๗YสCฑซณ๗K/ฺฐแC6\๘ฟ~ezฅˆ€ˆภ้H@ƒำ๑]ื5‹€ˆ€ˆ€wf"x�mทญูตkืฟ0Šฐ˜xฦฎL6ใ2Œ+˜‡เไไ$AUF�ŒดเOP๓<Šลผ๋์่@m@‚&‰u’ชฅšซๅMIb!ไ๒นi 4Wh4ซฎ%rษึๆ‹e๕…�’กa7tF?ฉ E>*O,9s๙ว฿}๓M}พฎŸWGw:€ˆ€ˆภ5�0�G]…ˆ€ˆ€ˆภIH€ๆAเ�{๏ฮd2‰๏พฅPศฝ>@aŸฯ��์ฌgิ โyดฤ'Ny 8เ|ค#Dใm4Z\ƒ* ๘!”ส%W6ฏKgจ•\w[�ฅ’—Œว]2ัBBCศuงฺ&Bฑ๐#็^ฒ�}ฏ�ฃ��4ฃM8 ๏’ˆ€œ ิ88�%ฃˆ€ˆ€ˆภ)Oเฮ๛ไาญ?~๘_ƒพภ๚ษ๑IW'.q*WรศฐBB‰ Œ-ุ๘A๙ƒ\>๏fณs.‹ธถ๖v‹ถ8„^jB™ฆ:๘0FGHY(d]_wฺ /๊wล\ฦ๙"แ'ฺป:พzึโe๗^tฮๅญ^=sสรำˆ€ˆ€œPjœP�:ธˆ€ˆ€ˆภ้BภF�ํฮX1r๔ุบFำท`โุ๘†ููยลีZ5 <B[:๑aศMฯฮธฉนYWฎ–Ehบp(N2Bฟง6ศๅsžQb๏ƒd*!b‘ืฦ{ปฺ‡�๏\v๙ๅ_ธ๖ๅ~…โO—›Kื)" ว™€วฐv/" " " ฟL€&‚�ถw�{ฯท/�{`ฯuลl๖ิq>ZขัX Ž|i&3{ด^ฏEปบ:ฟ1ีš>7Žo'Uแูู้๋"ฑุ`{OฯL[ชํ3=�]w-Ztฦ‘—พ๔ีs4 *ฟ|<�]D@D@~j�.๔๔Z๘4}‡›Gขท่๏†ป๛๛c๙l~ ›/�้o�๊ฒพuณถ๋๛๏wn๛๖ฟY=2:zๅชsV=๔ขื�๑๖o|๒๖ฅำs“+:ำ�Goบ้ ๙| ‹ฟำi่ล" " " " " " " ง3T�ี3m๚Lฅ๐ซ_ืWD@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@Dเd$ ƒ“๑]ั9‰€ˆ€ˆ€ˆ€ˆ€ˆภiNภาh@`MŒ_›ง9Žz๙š•;ก๘up็#๐\ณ@ ƒ็ƒฃฏ‰€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆภ)J ูl๚์ใ=�ำ๊ด�งีี๊bE@D@D@D@D@D@Nึ4PMzฒผ:ใJ ูl๚Ž๋ดs8กšอฆฯBฯ@8ฉ �_  ซ'๎eIENDฎB`‚pydantic-httpx2-6dd59b9/docs/img/gh-actions-fail-check.png000066400000000000000000007433041526547463400234710ustar00rootroot00000000000000‰PNG  IHDR ˆ๕8gŸ HiCCPICC ProfileH‰•WTSษž[RIhH ฝ‰"H—B‹ Uฐ’@B‰!!ˆุ•e\ปˆ€บขซ"Šฎฎ€ฌum,‚ฝ?,จ(๋bม†ส›ะี๓�;๏?gๆ~๙็Ÿ๏/™นwjžTšƒ๊+ษ—ล…ณ&ฆคฒHภธ&/—ฒccฃ”ม็?ๅอUh ๅ’‹’๋๛๑�*zกœ qบ@ฮฯ…๘7๐bพT–ั๊ญgไK•x2ฤ2 ฤR%ฮTใb%NWใ •MBโ]i<ž,ํ&จg๐3!๖uˆ]%ฑ2ฤ|Oqฤ#rsง+1ด้_๑d�ƒ3}ˆ“วหย๊\TBหฅ9ผ™�g9�ทไๆ(}ุมFษ"โ”9รบ]ฯžฉฤ4ˆ{$้ั1๋C�N,PูCŒREŠˆDต=jส—s`อbW/$bSˆร$9ัQ}z†8Œ 1\!hก8Ÿ› ™ปX(ืpVหฆวล โ ‡ญ™[ฯ“ฉ�*ํO*ฒู�๋"!w�u‘(!Y3F-'ECฌ 1SžฉถมlŠDœ่A™"Nฟ ฤพBIxฐš›š! ‹ำุหrๅƒ๙b‹EbnดWๆ‹"4<ป๘แ ก“pcšxก์›|X`<่„ย49ง3nY=๐`�๒Cnœ‰›| ๔ฤฦกoจๅh"Wf�-๗?r๘ช๊;Š+ฅ ฃQพฉํคํ1ฤขฌ้ืRวš>TWฮะศท�9_UZŸ‘฿Zb‹ฑ�ุi์8v;„5vkยZฑรJ<ดŠชVั ท8U<ูG�?žฦงฒ’rื:ืnื๊ฑ|aก๒�8ำฅ3eโLQ>‹ ฿�BWย9‚ๅๆ๊ๆ €๒;ข~Mฝbชพ๓�]�1|Jก2๓‹Žg ภมG0�|ัYฟ„�c‡�๙ YZ‡+; ธฃŒ9ฐ07เ �@ใ@ H)`*ฌฒฎg˜fƒ ”`-จ›ภฐ์๛@#8Žƒ?ภyะฎ€[p๕tg ผ�‚:ย@Œ ฤqF�o$ Eข8$IC2 ข@f#‹2dR‰lFj‘_‘ƒศqไ,า�@๎!�ศKไŠก4ิ5CํะQจ7สF#ัt š‰ๆกEh1บ ญ@kะ]hz=^A;ัgh0-Œ‰Yb.˜7ฦมbฐT,“asฑRฌซม๊ฑf๘?_ย:ฑ์=Nฤ8 w+8Oฤ๙x>_ŠWโ;๐�$~ ฟ‡๗โŸ t‚)ม™เKเ&2 3%„rย6ยย)ธ›บoˆD"“hO๔‚ป1…˜EœE\J�@�C ๖‘H$c’3ษŸCโ‘๒I%ค๕ค]คฃค‹ค.า;ฒู‚์F#ง’%ไ…ไr๒N๒๒E๒cr?E—bK๑ฅฤP”™”ๅ”ญ”fสJฅŸชGตง๚SจYิิ j=๕๕6๕•–––•–ึ-ฑึ|ญ ญฝZgด๎iฝง้ำœhฺdš‚ถŒถvŒvƒ๖ŠNง�ัƒ่ฉ๔|๚2z-��.�6C{ค6W[ =OปJปA๛ข๖sŠŽญ[gชN‘Nนฮ~ :=บ];]Ž.Owฎn•๎A�kบ}z ฝัz1zนzK๕v๊ี{ขOาทำี่๋oั?ก�€1ฌŸฑˆฑ•qŠัe@4ฐ7เd”์6h3่5ิ7c˜dXhXexุฐ“‰1ํ˜\fs9s๓*๓ร0ณa์aยaK†ีป8์ญัpฃ #กQฉัฃ+FŒYฦกฦูฦ+๏˜เ&N&Lf˜l49eา3�`ธ฿p�๐าแ๛†฿4EMLใLg™n1m5ํ337 7“šญ7;aึcฮ42ฯ2_c~ฤผ�‚a`!ถXcqิโ)หลfๅฐ*X'Yฝ–ฆ–– หอ–m–�V๖V‰V ญ๖X�ฑฆZ{[gXฏฑnฑ๎ตฑฐo3�ฆฮๆฆ-ลึ�Vdปฮ๖ดํ[;{ปdปํํžุูsํ‹์๋์o;ะ๒j.;ฝณ78ถ;กNN"ง*ง ฮจณงณุyƒsวยŸ’5#ฎนะ\ุ..u.๗F2GF\8ฒqไ๓Q6ฃRGญuzิgWืืญฎทF๋7zแ่ๆั/�œ�๘nUn—�้๎a๎๓�›�_Œq#ณqฬu†วx=Z<>yzyส<๋=ปฝlผาผชฝฎyxวz/๕>ใC๐ ๖™็sศ็ฝฏงoพ๏>฿ฟ�\�ฒ�v๚=k?V8vุ๋�V�<�อ�ฌ€ด€Ÿ:-y5๗ƒฌƒA�‚ณูY์]์็มฎมฒเมo9พœ9œc!XHxHiH[จ~hbhe่�0ซฐฬฐบฐ�p๐Yแว"‘+#ฎqอธ|n-ทwœืธ9ใNFา"ใ#+#๏G9Eษขšวฃใว_=�vดmด$บ1ฤpcVว�‰ตอ‹�}qB์„ช โFวอŽ;ฯˆŸฟ3�MBpย๒„[‰‰Šฤ–$คษIตIo“C’W%wN5qฮฤ๓)&)โ”ฆTRjR๊ถิพIก“ึN๊š์1นd๒ี)๖S งœj25g๊แi:ำxำ๖งา’ำvฆ}ไล๐jx}้�๔๊๔^>‡ฟŽ�L$X#่๚ W g๘gฌสx’้Ÿน:ณ[(*๕ˆ9โJ๑‹ฌˆฌMYoณcฒทgไ$็์ษ%็ฆๅ”่Kฒ%'ง›O/œ�!u––H;๓|๓ึๆ๕ส"e�ไˆ|Šผ)฿ุ[Š๗  ช �อHšฑฟPฏPRุ:ำiๆ’™‹ยŠ~™…ฯโฯj™m9{ม์{sุs6ฯEๆฆฯm™g=ฏx^ื�๐๙;Pd/๘sก๋ยU _/J^ิ\lV<ฟ๘มแ?ิ•h—ศJฎ�่๗ใฆล๘b๑โถ%๎Kึ/๙\*(=WๆZV^๖q)้นŸF�T๑ำภฒŒemห=—o\A\!Yqueเสซ๔Vญzฐz�๊†5ฌ5ฅk^ฏถ๖l๙˜๒M๋จ๋๋:+ข*šึ�ฌ_ฑ�cฅจ๒JUpีžjำ๊%ีo76\�ดฑ~“ูฆฒM~�|}s๘ๆ†ปš๒-ฤ-[mMฺz๚๏_jท™l+�๖iปd{็Žธ'kฝjkwš๎\^‡ึ)๊บwM�ีพ;dwSฝK�ๆ=ฬ=e{ม^ล�งฟฆ�zu_ไพ–��๛๋ณ�ญ๚ใ@iา0ณกทQิุู”าิqp�ม–fฟๆฟ�}๛!หCU‡ /?B=R|dเhััพcาc=ว3?h™ึr๋ฤฤ—ON8ูv*๒ิ™?ย�8qš}๚่�3‡ฮ๚ž=xฮ๛\ใyฯ๓ ญญ�๔๘๓@›g[รฏ Mํ>ํอc;Ž\ ผx�Rศฅ?.s/Ÿฟ}ฅใjโี๋ื&_๋ผ.ธ�ไFฮ7 n๖฿š›pป๔Ž๎๒ปฆwk�ๅ๘ฏ=ž‡๏…�kฝ�ึ�ƒgๅ?v?ข?*l๑ธ๖‰�“C�a�ํO'=ํz&}ึ฿S๒—�_ีฯž�๖wะ฿ญฝ{ป^ศ^ ผ\๚ส๘ี๖ืc^ท๔ล๖�}“๛ฆ�m้;ใw;�{ฟ?�!๙รใ�I+>9~j�๙๙๖@๎ภ€”'ใฉŽlhF/ท@Og‡vจ“ิ๗<• ๊ปฉ �„ีwA•xฐ=€ฤ๙Dม3สFุl!ฆมง๒จžPw๗กฆy†ป›š‹o<„wฏฬ 5๐I60ะฟa`เำV์ Žๅฉ๏—J!ยปมฯŽJิึJ฿สฟ(ำ~a,™ใง pHYs%%IR$๐ŸiTXtXML:com.adobe.xmp 2582 1160 Bย-คiDOTD(DD๗m›Cฑ@IDATx์�|Uืว๑#Ez๏ฝwQชJ/*<‚Hณ+‚ˆุฐ+v, *ฌXAA)‚‚าAช"Mzoา{ั็žf˜�์&›dูอ๏พŸ7;ๅฮ™๏„ว$๛฿s/๚ฯ4ก!€ € pžสUฎ~žฯศ้@@@@@@@Bธˆ`a(L๔A@ทมยp‹2 € € € € € € ‚…แqd@@ ,L �@@@@@@@๓$@ฐ๐ฎ @ˆz‚…Q�ˆนA@@@@@@ˆP‚…๚เธl@@ าF๚ไ๚@@@@@@@ ZF๋“ๅพ@@.@ฐ0…? .@@@@@@RญมยT๛่นq@@เย ,ผฐ�œ@@@@@@&@ฐ0˜ �@@’U€`aฒ๒28 € € € € € € h‚…‰ฆใ@@@ค,LŠว"€ € € € € € €ษ'@ฐ0๙l@@ ‚…qเฐ @@@@@@ธ€ / >งF@Rณมยิ�๔นw@@@@@@Hษ S๒ำแฺ@@( Xล—[C@@@@@@ˆ Xั‹G@"W€`aไ>;ฎ@@@@@@ข[€`at?_๎@Hฑ S์ฃแย@@@@@@@ • ,Lๅ฿�> € pก^(yฮ‹ € € € € € €ฤ-@ฐ0n๖"€ €$“มยd‚eX@@@@@@@ ‰ “ศแ € €‰ X˜87ŽB@@@@@@’[€`ar 3> € €@@‚…Yุˆ € € € € € €\p‚…�p € €@๊ X˜:Ÿ;w € € € € € €)_€`aสF\! € • ฃ๒ฑrS € € € € € € Q,\บl…L›1G�^ป!ฮวSฎLIi\ฟžTฏZ)ฮ~์D@H‚…ษใสจ € € € € € € €@Rข*Xจกย}‘ “ปo๋Lธ0AbtF@ย#@ฐ0<Žฉ}”J+HKซหฬูsdำฆอ)ž#SฆLRฌh{ซ�^“โฏ7ฑX�ส+$_พผ๖๐3gฮศุฦ'v(ŽC@@@ ล \tัE’9sfษš5‹คO—.ล_/ˆ €€#p๊๔i9|๘ˆ=zT�๛๏?gsุ^uฤ‹ไ?๓ๆี~น(lc_ะŒีๆV๔ž์ซนห@-ต฿ ถE–@T _8Tถl�‘ 'PถtIyฐ็ :†ฮ € €Iˆ†`แ•๕๊JฦL…ฑm�vYฑrUขŽM‰ตnuต”.YR *(นrๆ”C‡หึm�d�บ ๒ใ„‰ษrษUซT–�_ตc�๛๏ฟr�]�eวŽษrฎp ฺณG7๙_›๋์p�{�'๋7lŒw่ฆM™7&ฒํw๒ฤ ๓ฝดZ6lŒฌ ƒ„yวฏ?O”"… ปฃ6iัZ6oู๊ฎG๋ยuืดฒAืโลŠIม‚ไ๘๑ใๆพทศFz�๒ซodวฮ]Iพ๕,ๆช ฎ’ี/‘ชUชH๖์ู์๗�ฆอ›eฺฏำeฦฌูI> € € €„.6mษ›7/ยะษ่‰ Nž:%��๓œ9๓oุฎฮ ีiด0บ››.๔นอิ~�>ฌDฌ@T ๏ํำื}^|R2y“๗ุฑใา็™~n฿!^p—Y@@8?ั,œa Ÿ|๖…ผ�ฦ›>�ฒข็�ึษ™#Gะรๆ/X(ฯ>�’ฌYป.hv € € €„O@�&’แโ๔แ‘@ธ@'Nœ�{> pข6X_XะBŒฏฏƒล+ € €@๘^ธ`a“F ๅ๑Gถs�ฤI๒๖เก‰zฐืทฝN๎้�-คcu …7�dƒo!B'๙ญ7^n่Œ™ฎแๆ;บษž=�ธG>ุป—ดjูยฎ๗{ตฟ�:}†ป๏B,ไอ›GF}2าžz๖œy๒�‹/ว{ :ƒํ�ทOz?ะGๆ�พภูถืw�~Cฎn�ฬฏฏ ฐ}a*๑๙ทิ,ผดz5๙�ใๅโ‹/๖gธ��‡หk�ืฦ›บt’'{DางJญปvI›ve๏�ฝq ษ>@@@$ ่๔วนsๅLโ(Ž €@สุปoฟ9ๅ\W‚R€`กั'Xx!ฟ97 €คVhvํ|ฃ\œ>v˜จyณฆf œ<๖ั�น์/Yf�฿ฟ้ิจS�อ๓yYืi‹ธ๏^{ฎษS~–&๐—ะฆ๗๗้ศ๗%mฺด๖ะcวŽษฤŸฆศ๔ณdื๎]’ฯLิธQiูขนdฬ3]๔)3•B๗žฝรZ=Pซ�•,Q\–ฏX้*ิ‹zย„'›ฅถ�฿ {ลD;pพดmsญ��ใn{„uล`ร$&Xจc้4ิšต 6lขท:H4˜๊ดg_xYF}๙ตณ๊พฆฆ`แฬ_งH�๙�{ื…3gฮศ฿kึJ&๓ฝ_ย|z›N�}Cง›D�ท!ิVญj๓๕จX�=f�ศ็�๏ทร’ฅH‡ฮ7{7ฑŒ € € fช†”แ@.ธภ‰“งd๗๎�IบŽ�ไ?3๙qดO˜H๏][jพ�ิz๏ฟ#"+มB๓ F�72w€ €‘' มย`๊/<๛ด่”ฅฺ†ผ;\ฦ�0>Xื ฒ=มB‚Xง"ึฆS๐>๚ฤ3&�ท"ึ�Tฟคšผ๔|_ษ!ƒ�๗๑งŸษ็_ฤขล:0 RZฐ๐ล็ž‘:ตk‰Vo์ุๅูเ@ผw(Xx๓ํ�ไ๘๑c๖ุ�่yๅ๕7|ถ%u…`กฏ`๓fMd่ sS;•9ฟ๓ฝ[-๐ฦฺ‰>๛4iาธk•ะwฬ�6„ฺFผ;X7lเv?iBบฯ<๛‚Œ๙>f:๖’%Jศk�^หj\๊๖ั…ๆญฺศ†}ถฑ‚ € € >B… JZฯ๏{แ™‘@ธ0gฬฃทo฿‘ค“๋฿Iuฆกิุlฌ0•฿๊|๒ั๛�Nฐะ<[‚…ั๛ ฮ!€ €@ส X่๛l*›pX๙reฅdษโ6จทvํzYฑj•l2• ใkb,]ชค,P@ด* Nƒบ์ฏฑ‚~zŽ"E Iญห/“FgCJซV�-ใ~Œ >๎3S,Xธ(พำู�ฯ<๙˜ิฟ๊Jป<{ฮ\3ญoฟ ว=�ภ}rตฉ\จํ๗ ๅฉพฯป}5˜ฅmห–ญฒbๅ*wปwกh‘"RฉRปiๆฌ9ขีึ �•6ดx๐ภAw๊฿+๋ี•ฬY2K๛�ต•าฅKูฎฟL�U-Yb—ื˜Jr๋7lt†p_sๆศ!ีชU•ฒeJKž�นLeลmฒv�:k้=ง{@ฦŽ�R2eส,๋ึo๗๖้่@มย@�vฒ˜ฉ—~š0ึงrž=�ถ๏dฯำ๛�{$Ož�๎9™๖ซญ.้n8ป ใ<ฺ็AwณVื{�ฅWค�ท™๊{™ค�๕mฅpแB๎~าyแขลv}ๆ์9ฒhqŒq Š…GLuฝซ›7•ฺต.—Š*ˆ~ฟญYปVพ�]ผี๛๔{ทYำFRฎlY)Sบค๙ฃTYoต*เo3fบ็u/์์ย๓}Ÿr7�cฆึJ‘Z�Oซijศณ ฉ4่<็w�แ†�ƒโYะะlวํ�^cว�(}?wNgว ��iนu›V๗์�`gwœฏส—“พ๛ฦ็qzฌŽแm๚ฝ2~์h๓=–ษ�ฌฯ๎ณQ_บ๋, € € €„W h‘ยแัQภdVlKฅน•่†‰ะฟ™&ฉ้�Hฅา�ฒกJลKอ๗ŸJ๏=I�fR๐ม อร!X˜‚ฟCSภฅMœ4Y�๛๐#)j�จปฟWO๓Ffฬ›ำ)เาธ@"Z P8*ขoศs๑ ฉXจกนgžzLJ•,้แ�โฯฟL“ื฿8Wํ�‘KซW“{๏้.%Š๛Nต๊๔Yaฆ~ฅ�ฒcวNป้อฏJ•ส•�ฑ^uzƒฎท�k{  �`แฬYณๅ…—_ ิอnำภ^นre์๒๖ํ;�ฉ๕๚_ๅeป]งm}๔‰งŽัใ๎ปค��ฺุ}๏}๐‘ ขq๛MžSฑํ€ v่|“��ำ๘ฑ>!,ท๓ู…_›.�^เณ๙ๆฎฅKว’6]:Ÿํบฒืา^ใญ แตXุPำ„9๛ฝ๘œ�3ฺTณ��‡zล�jฐPผๅฆ.ขฯลi†ผไ๒บvUM4|๊ดๆ™�ัํgี}ํl ๔๛ืiZฒ๖ eษ‚9ฮฆ ฏ_|๕๔}�%ป฿?XุญG/้�ฺหข฿ �ํ๔้ำฆฒ็ˆ �๚}�ฏ๛๘๑ใq�›ูณ็ฉื ฆŠฆฯ@I\™:y‚๙ฆˆ;JฟW๛หศO>sืใZ๐7ะ๏งŸ!Z]๒*cฃ ušๅีฏ1฿WหbU*kl๖!€ € €$M€`aา�8:๑ oว‘ ฟมย๘่@jˆฺ`แ€Ÿ4oะ~“๕ุฑใา็™sSตฅค`กพiงo�%ถฝ๒า๓rCป�%๖๐w��y๓ๅy๓ฦ™NWฌ�xC;y่�๛’%`8๎ว ๒๐ฃO๘œzล ƒVK๑้ศ  €ฤ)@ฐPDCZฑP›žพ๚ๆ[Yตz�Yฃฅ™:๘Šzu\ร?�ฬTe๛ฺ]๙…gฅVอหํ๚พ}๛์tฦ‹/5ำ_lฆxญmงฌu:;U� ,`ฆKฮo‚ZWสuืถถป�0ทฯพ๘า.๏5Sำ†2๕ฒv๖†ํมๆหŸห�’iฟNf7”ฉƒฝc„ณbกN)9s&น๕ๆฎn…ฦ๏ว� :eณถ 6ษ�์r‹fME+โ9M๏aŒฉ&wยT๊ำgsS—Ž’={vป๛€9ฆC็›ฎ z�`๘P)Vฌจ>|Xฺ�ุ%ไc,ิเโ€Wc*@๊ 4 YฑZL`Rว๙ๅง๑>•๚z๔บ?Vuพลฟฯ–ฌYฒธื๗ะ#หใ'สธ1_�)งK–(๎ฺ<|ไˆ์ฺต�๖�vฬwข฿kฺ�+ฺๆ‹V�ท�€ฑ-lวsถ๋ซลV-[ˆN!์m๚๏ไฏๅ+L•ย�LHถRฌPฎNณ�๕ท็*Z๚ u, 1jX๗๔้3ฆRh I›6ญ๗6t๚แGŸ๘lKศŠ�ดeห–ีNญญUฯu:cง้TๅW5Š™�ูื๋ฤพณำs;}ด2็�w�!MLิ�ฺตฯ๔ณlๅEตฆ!€ € €$ฏมยไ๕e๔เ ƒ�ฐ’.@ฐ0้†Œ€@ดDUฐฐ฿Ce๋๖ z6eK—”{�‘ c’ณ๓�{ฺ7‚{Ž~/>+ฺทK์แI>n��฿ๅึ;ฯUBั7ั๎้Zี�“xs ๏�อื/พ๘b™0vด”0ot†ณ9zT.ฏs•}SVวี๊-Zลล��๔ŽนฮsSู}๑้Hฉqiuo–@@ €@j^฿๖:๓sR7+ฃaฉ^<+ิืณG7๙_›๋lŸ#&ภีๅ–;�ภ�็Ÿ|(๙๒ๆต๛t๚Y�@†ท�ืณ‡;Eซ��<ิ��บีี๒ภ}๗ฺ๕ษS~�น+1ํษว๚Hฃ† bชSำnุธI4,8w�<๓ธ:_r  zโั‡ฅqฃ˜๊{�พ%S~ž๊์r_ฝŽ:๎kบ๛t!o�<2b่`ษš5ซ�>๊หฏไ#3�mBšŽ1๊“‘๖ูsๆษs/พ๒แ Ž�ฅTฎTษ{ํบ๕า๒ฺs:๚๖หฯค๚%ี��฿Œ�Nž|ๆ9wฝA�+ENำŸ…/ญYฯYตฏร‡’&gMuรณ/ผ,ฃพ<xu:๛ ๕{โตoŠุำ€๋GŒ2ฅK9‡ุ)ป๋7iแฎ�๖๓$)\ธปฎผ;๏๎iยท�m%K”ฐแ\o%@�Šƒ�มB B��ะ#๎๏\ujี”๗†ฝใP๔wq/ „…@N๏aฏY#=ูื†pฝ�ใZ๖{ฮ™;_๊ีญื!ขำ>_฿ก“l�ฒ5ฮ~์D@@Hšมยค๙qtโ&�Ž#@ ~‚…๑ัิ"rฐp๘ศQ๒ว_+ไ’ม„ฝ๚>ึ[rๆˆฉ๐‘ ƒัy้ฒ2โฃ/tไ�๗�.ๅหœ{3+A'C็H๊๔w�{๖veบwปS๚๙lT@ฉฏG}"9sๆด๛}โ)7ค๗ษ‡๏‰V ิ๖ี7ฃๅƒ‘�ๅPพ„+Xจ็บ๓๖[ฅ��ฺ˜inำ=๕ึm�d๔˜ฑ๒ใ„‰>}.tฐPง…ึ้กต฿% ๆํฎAสSงNIิิ้ฝmมยEา๙ๆ�ฝ›XF@@ณมย0ƒ2\ศ Cฆข#$B€`a"ะ8(9Xธ฿Tvบฟ๔้ำู)ิด๒ฮ3ฯฝไVิฮฯ<๙˜จอ๙l ฯง6็Bˆ&ิ,ิ#ไฯŸ฿>า฿6�6|ผ:MฏVfำๆ ฅฝ�สK>Aฒuฆ:�ฤŸ&ห,3�ฏ†โjแ ๊y2eสd*+^+uอ‡+ส•+cฆr2๔ฏึwกƒ…^‡๕6ศA*7–)SZ์�ห’๎�ณGบšส‘ iฮดี:oว.ทธำ0‡2F €๐๔�ตฅK—.เ0Zฑฎล5mํฯอN ฉ-˜;ร็˜k�wƒ[๐—I?J๑โลœ๎hชไฤ {›*'Mvวึ…@ก9ญจ•�C‡{อt฿uฎlไsผณ2u๒Q'ง๕y์I๛รxป๊,๔�ฏำฟC๛๋ฅ฿‹ฯ9ซถาfbงผึŠ‘฿}3*Vศฯ�,่t�w๕่ๅ๓lผ๛ฝหŒtฟ†Bชฏ�๗ฎ๋๚ฟ๛ฟ"ีชVัUท๕~ฐ๙฿…)๎:  € € €แ X^OF ]€`a่V๔D„ ,LธG ญ! @{ฃว๙V Sฌhayด๗�qพก์ุpnฟทO_wธ!^p—#mมฟ:ว 7Hซซ›วy๚†�๒ๅ+ๅฏๅ+Dง�าiฤ*Wช(Z™ล™6/ฎtŠฑลK–ส๚ ๅ๐แร๖๘โลŠI3ฐพมๅmZAp๏�d๖œ๙>ำวตนถตฉ๎r‹ํš+g.)Tจ ๗ฐ€ห๛Z๕๘์[8wfภJ„?�2M๎น๏ทฏ�๔mำgฬ’ำgN��yLEC๏ิoฮA๊คS8;ญLฉR๎”ส๚†ญพ9�฿ฟ�ู�Z คB๙rvYง–;qโธผ๓๎Ÿi๕ž}๚ S5&f*ไ"…‹HŽ;�๙gฏญvณl๙rูถmป”-[Fช˜gSล<[็บxE@ ฺR{ฐpโ฿‰VcNH๛f๔y๏ƒ์!•*V7^๏0ฤงแทล‹—ศ„IS�สm�๓xuI™ ู;ฆwนฎ๙ฬu๋H�:ต�j‹ฮ�a#�ที u�B ป�y›th฿ฮนด^๕็C๏๔ยก4v๔W6|นn�้qoยชy ฦwฮ“ฆ‚†๋�ƒ|z�‡๏ฝ+๕ฏผยb๐ะa6ฐชมด)วน�๗ํ฿/ตฏˆ™Fฺ�h,lwcŸJ9cฎ๘cกOะั ๊ณy๔แn๖X#P๛ุLฉ|Eฝ:๎ฎw�๎N�ํ,tฦw;›…ฆMษฐw�v7้�‰ ๊ ๎ำ ž™2fดAM�จๆๅ—นใ๋‚�žขี๊CiKฬ•ฬ™3น]ต๒a๛Ž7ล๚ทญฟGL๛yขไ:[แTx�ร}~?sa@@@ , รยศ ‰ X˜4A†LEGข^ AมB}ํ๕A#d๓–ุ๕ผR]t‘๗ขฬ_ฐ0เฑ๚๘ท�"<|.ะงแ> ๙ลี๔อ>}ำ/พฆAฦญ�ธ�ฒfอ*‹็ฯrืฝ ๚=๙ส๋ไ๔้˜๛ิ7^๏0ืๆ4o`กtฉ’๒ำ๘ฑฮ.๗ีŠฐ›ปv–พOลLo็�†ชNqฌี…ดUฏYWŽ=ๆŽhแ๑Grงอำ�๚<พ5XF|02Pw;อ๒€ื๚ล x0@ˆ0๏ง#์าใฝ�ž}ฺ„๊bชK1!'งzšs`ฮ9ไ๋/>uVC~�ัL';hศปn�๒ๅสJ๗nwฺŽ่ฯเฺoำgสหฏพ๎ณ+นƒ…�“้ิบ7u๎$iฯVึำสŒw฿sŸํrกƒ…�ŸดŒ็ร:�{q–�ถ๏pสdgฟ๗ตVอหไๅžณ›ผมPoŸธ–,ิP�O?+kึฎ 8ฌN[�Zฟ�}K–�iBt7I๗ป๎ญŽ้ดoF'O>๓œณ๊พ&6X่žุฬ, ๊ิฮ๗๕์แv๕�™��aFผ;X7<๗มค‘*�^`ป๘ �๏Nธƒ…�ks–๕๗ �=ร�Z]w}ะ็ไํ7้ว๏ฅL้R๎ฆ9s็ห-wtsืฝ ๚!ง›บtr7้ฟ�ปz�๋ฎณ€ € € ^‚…แ๕dดะ†nEOHธมย„›qั* `ก"l2กยื฿.:Wฐึธ~]นกm๋`ปฯ๋๖ิ,|ช๏๓๒๕ทcโuึ้…ฟ�๖KŸpแฆM›ฅU›vr๒ไษxื7ฌ๔+mแ ;vL.นผฎฯ๙๕อO}4กอ๛ฦแ…jฑ}งฎฒfอฺxoใ๖[n’'$�~t@@ ’ผ�Žไ๛tํ๑ ๕˜พ๛F2dศ`:์=ูo*ฤลืVฎ^mง@๕๏Wฐ`ฉSซฆ V‘*•+I�ผy|บ๘ฺฮgฐP/ไึ›ปJืฮํ52ี๔ฎi��.{ƒ…�๑ง๔y�)ป��K๏{๏‘kฏie7kลFฝงMžSeOง�ี€œท=๑่ราธQLีฝ�฿๒ฉ2ญ�nนฉ‹ยZท~ƒ|๙ี7�ร.Ÿ8yB4ุj๋uOwis�5ถ๛#ๆ�–š๛LH ,��‹ฏLๅ์๎0วŽ—ต&Hธbๅช‚j� x๚ม—ห๋\%๏ "‚tฺอทw“น๓b฿็๙ ๚ 5ฺผUเ฿ฦ|=สg เ^~U>�� {+)%Xจณ๒ฯE>ฟ{yงlv�ฝ๚W™ิฉuŠใ@อ?ฉ฿o7t๒�w่8ถ!€ € €$N€`aโ�8*้ฮ[๕A>kœ๔0คj‚…ฉ๚๑s๓๘$8XจG;v‚L›1ืg g%ง™๖ต๏ฃฝอ›ค;›.่kj ฮž3Onฝ๓n๓ฺ5/ทo0o�พC~š๒ณฯ> ฏiˆอiฝzฤgส4ญฆำชe )bฆQึ †:e—ทอž�‹VY+‚h#G๘T๑ำ๊†นsๅฒ‡4kฺX๔M๖PšN…ฌS"{›Nc�ฑC;Sคaฌ7หฝ�ผห�ภBธƒ…๚Ncผw฿>Ÿส:MY–ฬY์e<ึ็Ai�ๆZป�ฺ€v*2๏๕ฉm�๙D+ลhuo7ๆkั)i €Dซ€๗ฟำัvก ?>TŠ+joฝ๏๓/ q%ึฅA�+ๅ๖[o6?รลT฿บm›�~ืน๊oI fส”ษTแ{VาฆI# tฎฟj•ส2ฐ�ซฮช8�ผมย›6Iทฝ�>�…~/>็N%ฮ`a:|�„ตญ�๛o้uฬฒ๗�I]vž๓กC‡ฬ๔ต]<\ `aR�ํ ุ฿�Œ๏\LฟW๛›jไš้{ำูM;v๎’๚›;ป}^�ƒ…Z ๓ฃO>๗้ฃ+ฟš)y๏?]OhลBNXƒNำd๓Vื™๊๙[M๖5w๎�2c๊Oถ๒ทณใถ;ปหฌ91ฟฏ&wฐะาิ๓7iั:ึ5:ืๅ_Q�G~๒™ณ;่๋๓}Ÿ’.nt๗k๖๊kฺบ๋�…!ƒJ‹fM�Mใ'N’~ฬ]g@@@ ผ ร๋ษhก , �Šž p‚… 7ใขU Qมย'Nส ฏ2มฏƒฑ\๎พญณTฏZ)ึ๖ ต!ฑมยฅหV˜๐ไ๙{ํ†8/ฝ\™’าธ~ฝdฟ็‡ฬดฦ?˜เžำฝ9 ึtน:-pฃๆญdป :ํํ7^}ใุi-_!�ปก“ณj฿€›7sš่tรฺช\ZหงZแด)คh‘"n�7�,รFผ๏ฎ๛Wœ๚๋oาฝgowฟNอื็มs๋๎Žxฦ|?N{๒™ ฝ4๐จำ7i�PZถh.ๆ ิผoบ†;X่œฯ[Eท้Tษzm�ฆฤ†อZบ›.พ๘bัเ wJณฯF})ฯฟ๔Š�ว�อTw  €D‰€๗ฟำQrK๎m„,๔๖๙sู_๒๐ฃ1• �Aฮ.ิซ[� hŸ๘“;ฏ~@A�แรGdฦL฿่vohNซ�]w}�l›7Xืน��ฏ,ิะ—~ˆD�ภทษคษ?๛wsื;w์`ƒŽบแธฉฎืฆ]LHJฮิjlฮ๖Ž]ou๏ฯn4_๔็พ>n~�หl7%6X8๊หฏbเJ•,!ร‡vN%>๑”�ภ‡ปแ์‚V€ฌ[ปถdฬ˜A๔**๙๙ฃ๋ZI๒“฿ณปfอžใ๓ณ^ �ถ%GฐPฟ74 ่ด“&zq๚๔ฮช|๒ู(yฑ฿k๎บwม?Xจฯ�พb2“,ฬbž๗ยy3�๏1ฝ†‰“&‹~ส�4tฺก�๕๎&ญฌ_ท~ูปwฏ�–�มยŸฦ�=รicว�0hซ•+๏ฟฏงำอพzวำ๛ฝ�ThืŠฃ๚;ี”Ÿงบ}+”/'cGๅc๑๚oŠ�[๐ถ+๋ี•‘๏๏ด่ก†ฝใฐŒ € € บมยะญยั3‡๙;‘ถ'Ž›ฟ1›อ!c๋Yฒd–t้า�‚"‡ืฐษ2มยdaeP8+@ฐop,ิƒ5x7โฃ/œq์๋%U*J๗�ป๘lปะ+‰ บท๘๎#น•�7๔Z ๕Mแv7ž๓ฟบy3y็ํ7b]บๅ<๏ิZีkึ๕ฉ8๘หคฅx๑b>cœ:uฺ]O—.ญฯWแ ๊ ž{๑e๙�‹ฏ�s[ะ7ดต‚‡Vtฆt๚z 2XจaL e:ํฅ็๛š๊‹ํU๗U฿๐_นjตป�ืา>o๒บ;X@@ ผ�Ž‚�๑นohpศปรe์ใ}๖๋สe5.•W_~ม��ี7ฃๅƒ‘ป๋บpsืฮ๖�Zyl๙Šข•œ๛ฟ๚ฒณY�v๔่1ั฿ฝœ6๊“‘>SQz็]•50zM›๖ขำHำ@@@’G 9‚…ูฒe•ย… �[ฆLอ๛piไุัฃfึฐฃขณR:”ฒoษ#-v†ด+ฏจg‡�ว| p๖ูู ยyพVWท0รJ'��๗ฏŒŸ0)œC‡},‚…a'e@๐DCฐฐX๑’R Pูถuณl�ฒษswัทXคhq)Tค˜์ุพMถlZ}7ศ]PD ๕ช‡%�ตา�@Sญ๏cฝME‘์๔†�Ož˜`aฟ7†สVOี?�1ญ—-]R์yG ]aูJฐะฟ:FืฮcU5ิ‹™3wพ 6ยฝฎgž|Lnน)&่lำN6kLีรZfJๅยfJไธZ8ƒ…z}Sn่ฐ๗dมยEqึ๎+Tจ L๚แ{Ÿ๊…�ภย… jขqg฿ี‹ีJ’y๒ฤ~#wุˆdฆฉfใด‰?|'eห”vVyE@ ชผ�Žช37JฐP๏YงึŸฑœถ~รYนrตญŒWถLwชd��ื๒ๅ๒`Ÿวฎ๒อŸIŽณ?{Ÿ>}ส์_!žหž-ปTซVลญrจh5hoี้ฒeหศะAoบciEC ฬ-๛kนhภ1”V�ส+ไษว๑ฉขถy๓;ฮพ�๛%{๖lrIตj>ี�ฮœ>-?�ฌ,�ใO๗ฎิฅำtšืต๋ึ‰VpซRนฒ{ฮ�„ oผก�uวmฮกrเภYผdฉ�6}ฆ;Un๙ree๐[oธ–Q �ูs๏�}ึ_๗;ีu วŸ๊+‹/qวŒkมyพZYผ“ฉฦธ฿œ?ก-น‚…๚=ช•$��ฦ›ค™™r8X‹ซ"๙_}#:ญทถp ๕{เท_~Š๕=์ฺ4ฌืุLE์„ต_r ๕๙Œ6ี;sๅฬ์ฒn��2เอ˜ช‘๐œ;cช๛=จฌYปNZ]wฎฃžg’ฉŽ่ญ,p`ฯF_ฯCC@@H>p uฆ„*•*IกB…|~G๔^ฝ~ะl๛๖ํ๒ง๙ฮษ“'ฝปข~9wฎ\โ ๗๎�k>ผ:7์๗ฌPี‚&๊�ใ„‰a?œ, ง&c!€€ฟ@ค Pก�ื)๓�ษา…๓�o1ชึkิฌc�๛SภpaT=ฺq3I ๊Tศ/ผ6HN˜\�ทi%Mฤ|J$E�ูู‹HLฐะ{ฬ€Ÿ4•R2ผฅcวŽKŸg๚น๛† xม]๗B(มยฤพqคo(๊‹ฺ4ศwGท{‚^พN9�ฌIcDิJ9�-�มBg|}spฦฌ9vฺนน๓~7Sะmuv๙ผj@ญ่4o`แB �ถ๏hช ล„pk ๅU฿๐o�ฌI(]้ƒ €@ฤ x�;qฯ‡,ิjxฯ>�ค่Tงq5 ์้ผมดš—_&ฯ=๓คO…ฒ@cฌ0?ƒ��๐ฃฑv {็m)]บ”ฯ๖�ปwKื[๏๔ูืŠV“๋v็mquq๗iธ๎กรc�QVง#~็ํ’�3ฏ{YะะไยEKคNํZvsB‚…๊๛ม๐กถ๒กwฬ_Mีป~ฏ p7ieม;oฟ5่5hG�ƒฒV”�๚�1๎q๑-Œ๓ต ‰f”u๋ึK^๗วื=เ�ไ j˜๓ซฯ?ŽuN�J��4์๗ณฉjฎถ�-�มB_ฌฏ๖{A๒็ห็:Ÿ๕ฝ๛๖ษำฯพเ3…ฐvH๎`กžฃNญš๒มˆกฑชง๋พ@m๔wcm@ีปoษ‚96L๋l›7�wน้ถ˜j—ฮ6=ฯ�_‘๙๓;›‚พ๊›� rะŽ์@@@H’@ธ‚…fkX�*Sฅ0KHืs๐เA๙mฦฬ๚FK'‚…พO’`กฏk ^HzC…ชฒc๛VSลoCxRุhลJ”’ ปWตc‡ฉ\ธ‘ส…. IHRฐPฯญไืจA}{ุ‹�^“3gล9ฤ]w�*5”|y๓๚๔ำ {๚ณู—ฆŠ` ฉŠตš^—NM่ฎฆOๅ@d็ฮถRกNSจi0ฌ๓คQร๚vบVํณห�Œๅf tฌw[e๓I๚�n้*—Vฟฤปู]ึ@�\3EฎN ๋bุํ`ด‚โCฝ{ูWgปNฏฌี G๙^ฒfอ*ฝ{ล|๘ๅตๅ—ฉฟ:�d๔WŸ�๋ื๛ฝ๙๖n๎vgAฏฏC๛�Y#g:ๆiฟ�&ฏผ�†ำลพ๊5�wOwถฬ!ƒปOฏ_ซ9๊ฯžกTัvิุ‹g?๐๒๕ทฃๅ�c‡๘œพqฝ,฿T�›ไ>฿“ฦฅJ๕šq๒พYฟ�+ฐืผU›xงฮีฐใท�bฆ™naงSึJ๚คฯF})ฯฟ๔Š=�SลฏZี*vY [ดnp�E๓fบ฿ม๎MรŒฯ›B5lp•ฉŸร็�<$ณ็ฮ3SXฟ์Sฉะ้4oึฏvช$]ื฿oช\Pu๖๋k�:ตๅำ‘๏น›fฯ™'ท�yทปส‚>'๒[ง+ึ)“ต?�\&o b?ฬๅฟ�ก๛๏ณี5ำงOg*k”>=)ฟNŸแ฿อ†฿|ใ5ธ tžm�ถห �^๕๙7k6 € € €„M \มB�ปJฑขE�ฺ๋`ฟ� ข๓!S�}X? š3วนŠ๙Z„CgfH-`ก๏“&X่๋ม„W Rƒ…�ป;ถหๆ๋ย‹“BG+Vขด ž›tง n&\˜BŸVd]V’ƒ…Zyd™&,€Š)โอกสšu์ฅ”+SRn๎ุN๒ไ>๗Cw kLHX0!}+ิmก &ƒ†ผู๋ก�๕RตJew=ุ‚พ!ญoผํิฉำข•\&Mž"๓_ ;v๎๒๎v—฿x�ismkw�| ._ฑBฺถ๏ไฌฺW๏ค�ภBษ%dสฤq>}uEง†พๅŽsoB฿�ตณ๔}๊q�Oง๑ซ}EC๗ญ”๓ูG๏ป๋บ๐ยหฏสงŸแnำ�NEgใ n๒™๒OวืOŸลื๊_uฅ๙EฒH|�ุ €@D x�;‘7 )S&SฝฐฌฉาwFถlู๊Sก0พำ-RD , GŽ1ฎMƒˆมฦะ?Nง3ฆ={� ึ%�ํTิŸทŠ.$gฮ�k+ n฿ฑStj]็เ๑ ข๗_ชdI๓ฅ‹์ดฬ๑๕O่~'”฿๕/^ฬ๎v™ Ž›6mN่il�๛z๖๋ฮ�œฌ?ห๋4ำ)ฉ้ฯ˜ใวŽ๖ฉๆจำi�๏฿ŸญSา5๋ต่ดมฅK•�=Tฟฯฝำง„kี๋ำ฿ฏดgมไ€ฉ ฑaรF’�ฐqcœ—จวๆ3�ŽtJ๓PšVิ฿๗N›)ฦ๗™Š+ฬ4๊๑#”q้ƒ € € บ@ธ‚…-[4wgRะOฮ_ฐ0เEิฎyน0ฟojำฉ'�4%`ฟh�Hฐะ๗ฉ,๔๕` ย+‰มยิ*tž>แBG‚ืp $9Xฮ‹IŽฑ–.[!#>:๚J่9"ฉbกVณ๑Nsง•rnฟๅฆ„�rภ�Z5ใ‡๑dฐ™พฮ๛ๆ]ำฦ eุA๎1แŽ๚๒k™0iฒ;ๆc}tซธ= �ี'�๘ฝ”9;ญŸ7ฐ •nฯ]-ศ;e››มย'ž~Vพ5ีvœ6a�h)Wถฌณส+ €ฉRภ๛฿้T ภMGตภศ๗‡™ea9t่ด๏ุ5E�ซV|ส�ฎp๙e5|ฎ๋QSตLš5k๓ิใขำ'�ณwoผ3–้X๚แี์ูฒIฦŒEg"ะ™4šฟq์ฺต��Tv]ฯ•ูฬ8 ~�a‚‘ฺ๔w๚ATญธฟm๛๖Xว๊ฝฤ\cv๛มวใว›ฬ53€ํ–ใวOุ1ผ_‚ ๓ๅห+y๓ไO?pปืฤูk>€—˜ึบๅีถ0ˆ�๓&"gฮvV…lฦH›��G?ศบ� วxwไษ“[rๅฬiงพV[�ฐฏsอ๚ฬฒ™๗4�3�ทu๋6๏a๎ฒ๖ษ+ท9>ณน�4๎๓ูa>ไKCย!iมBB…็ž:แยs,…G ๊ƒ…ส๔ษ—cd�‚%‰‹ค`แ๊ฟืศ5m�ป๗้?mšณCซฎLš๒ณ�gช|hkึด‰ โiE–้3ฮ๏*Uฌ U*Wrณฏ๓ๆ�๎3=^ๅJe์่ฏ�>�มย+๊ี‘?แ๎eแƒ‘หซ�บ]ฏบขž่ณšN๕ีฐYKŸ]KฬฑS„้ฦ๊5๋ŠNอๆ4ญสขDผญU›vฒfอZwSRƒ…?๒�y๛ญ๎xบ0๒ใOฅ฿k�mืทฝN^ๅ%w�YะO -^|๖{๕ข‹ไฆ.�{q๚๐Š €@ด,Œ–'ษ}๘ ่฿?๙๐=ปYงมึ้ฐSBำŠๆฯ๗}ฺT@ˆ=Uo ŸซSย5s  € € €คdไN�๕Wฐ v฿JK“&&Xธ{๗žX�4ะW�’j6h็ฟ๓฿ฯุŠ๗๋ึฏ๗฿eื‹),•*T๐™แภ�๑€ ฯ-�s™่ซท5iิะ†ไ4ทxษัฉำค97sื๊ฟ�๖ฉะ_ถL;k‡ท3�™3glE�ๅ+V:›์ซฐPgธ๔า๊nศา�YƒŒK–�afี8ใ�๏r|มB ๒ีผ์2ษž={ภฑ4ผนะผฯ,ชวื2U'ณe $z9u๊”EฎB๙r&™ื๎๒�^ศ˜1ƒyถ—ุ™6�;{๐EžAŽ;*.๛+Vˆำำ…E@ $H *Œ�HK”*#๙๒tw0-ฒKมB"REฐP]Vฏ]/ใšๆN‹ชU$ ๕žฺ�ุล�ภ่�Ÿ~jฉ�ซ/ปแดต๋ึ‹Nห๋�๖ำ‘๏I�:ตล?˜จŸfš<~ฌ่Tpฺ๔—'Ÿyฮง๒^หอd๐[o8งณ?คw่|ณปฎcผ๑z?๓Iซ†๖˜Pฆ��{อi�ๆ\@RำpaงŽ7Hฝ:uฬ๋1?lฯ˜5[๚<๖”OE-�๙'บ็o�พฃx๑ะฐๅ›^“J&ฉŸ๒ymภ@Ÿ0ฅ˜ะ`แ;๏—ทuฯYจPA`ฬตŒ�bw‘ ๖–ป๏บร๎ืฉ�~™๚ซ๔์� ;ŽZ-˜3�|’,ซป@ขI€`a4=M๎ล+ะ �•๒๔ูŸŸ฿|{ฐLš�ณw๗[๎ูฃ›<ุปWฌ๓kE€[๏์.‹œธฤ๊ม@@@$Ž`กŽ{M๋–n@Nซ jก„†โtœre5ฐW�พ๗ค๋มฺๆ-[์{z��ลŠตD}_+ฎฆGะB#�๋kbf8ห’9‹=Lร‹�AoฐฐvญšR �ธNa๗m�ถอ็o�`แฟ�™โ)ๆ}K�๓x�ฒuซ 9.๕nŠw9ฎ`กVFิPกV`ŒซฉหยE‹e็ฎ]>�ดส`ฝบต%}บ๔>�ฝ+Z๑Q+:}ผมB}฿ฐa�ซl€S ,ิํz�น๓ๆปu Hจ@ค �C…ปwํ๋ฯ•J่}GKอ๖”,]–paด<ะ |ฉ&X˜็{๛๔uปGZฐะ?่�Hั"Eฬ{}ช๗้พŠสห฿}ใt�i…u‡ซUW�0Ÿ@:y๒ค�WF}2า|ฒๆ2w›kิพา]๗.ิฟ๊J๙pฤนžwŸ�ฒ์ฆ�<ีณ]ฯg>ฅฃe��ฏEwjจPร…N๓ฏ่l๋5กมยŸL๕ว^๗?pH๏tิŸ|6*&wชก@IDATVต-หฎถr๔�ฆƒuป๓6y๔แsAร€'`# €,@ฐ0‚—ฏ€VษึOšฏ7ŸžO)-Pฐpๅชี๒๚€7E?ดCC@@@„ „+XxEฝบ’'wn๗ไ๚7 ฦ้ ฮน๎ฮ :qใ†๕�ฐVฏ๛�ฬvฆำ งOŸ^ส™ฟU่๔ฦฺ4p0{ฮ\Ÿฑ››ฮt๊cm'Nžญธo฿~๛�•พ—Uชd w์ต๋ึ๙๖๐ ๕x n�ฒีT6Œ™ฆy็ฎvzc /j5Cง้ิลZ=Qง>ึJŒ8ฬ’%& จ}ด๊ † ตyƒ…vƒ๙ฒ�ภ~Yฟ~ฃ;~ฬY)_ฎœ[mQ๏๑ท3ฬ4ลง•vฦ๐พฦ,tช2j 6n�ธษNaฌ๋นs็’RฅJบแPตื‚"�Vฏn;eณณMซ*n฿พCNŸ9mงE.]ชTฌะข7XจUuถ9mz~ฝoš๚ิ้S๖{G�ฅฯY�N3ตฮ’FC+ มย@กย ๋ึฤฎOฌIค—ฺร…O=�จ™ฝต‘}lcพ'ƒ‡‹๗žฏcโฝึ`a€โ x๑I๓hฬั�]๕๑>ฯ๔s7วBt;&bแกG—ฦOt๔ๆiuusw�ป๐ี7ฃๅู^ŽT๓๖ัeญฌ๗�ื_ุิ}kึฌ•ถ7t ฺs๚8ฏ๔พW๎ํqทณ๊พ>�T_��Xw�YHศดศ'อ/LLeEoตAgœ`ฏ�^|Ntz7oำฐ^ณ–ืู_พผ�ฝห�^|ึTb|��”ะ`แฉSงฅiหk์�๎ gผำ"kUยง๚>๏S๑ัฟฟณฎ•&›gJ…G็^@ˆ4‚…‘๖ฤธ�Hจ\ฉ’ฉT^K�๙็ัŸท7n�l~�^้ทล๕#€ € € pมย,ิูซ˜�าแ^Sลpื๎�ฒอั�P€š—_&… ฦL{x่๐!™1svฌ๗ u†ฐ\นrY/ญŒจแBmz�ฆMู`œ,Zd�~ฐื๎sพh%D ฏi�ณgฬ1U๑œๆ jะmๆฌ9>ณง9�ผแE-ˆ2w^์สŒ�ฑผ็๑ ฯiAฆนฝ?—-3ำ*orN๏kฐ`a™าฅD�ฎขMC}๓_ �ำPka”ฺตkบแย+Wษšต1UณtŸฮ็ดUซW�™ไœu}อ–-ซ\Yฏžิm�`แe5.•"… ๋fั`็_หWฺeงภdแB…lลI�x๔่Qชœi๗๓HŒ@JๆฬGส–ซ่�šV*$T่rธ ย…kVฏ”�๛�q๛Dใ‚oปฅซฯญ 2L yืg›wๅ|ใ=gค,, ๐ค๚ฝ1Tถšฬาส–.)๖ผ#!‡$จฏXo๘ะAvzแ`ƒlฺดY~์I;-ฒ%<�ๅคGท;ไฆฎ�)’ฝใ่' †ผ;Bพ๛Cฌ_8ดŸV์๓ะ�Rใา๊�ร�e�…ๆ�1฿หศ?3?ฌotท๋”p ญbกคื=ๆ๛q2เอA>ำปž]ะ�ใ}rงl๖฿ุ|ฺู้็_’q?N๐ูฅมส^๗tทŽ:Mฑำ๎ผ�Vั@ 6ย๘๒บW9ป$X8rฯžไcS‘๐หฏพ1ŸŽ:เ๖ๆษวไ–›บธ๋บ ี`4`จŸB๒oฅK•”^={ศตฆไ}|ฅๆ�e@H XiOŒ๋E@@@๐ „+Xจcjฐ์ฒ5�ช‚�๓8หZ p๛Ž๖ƒ‚Zๅฯ�œPœn›5{ŽO5BงŸNวซFm:ึ๘‰?9ปโ}ี๋kิ ํง•u:dงyร€-_aซ:๛œWo00ฎj‚Zนฐrฅ˜ฐˆVิช…ฺผวkธ๏—ฉำlฅCg|็ต๚%ีคxฑbvUซ!๊๕„ฺCฝพ'œ+๘โญ6่?EณwlญฦจUตiprึ์นvY๏งL้าvู฿ฮn<๛ล[•P7yƒ…�cฯœ3ถ,๔Žร2 T”,ฬ›ฏ€๊ืนO‚…Ž„๏k `แบ5ซd๏?{|;Fฺูขy3อฯU1Uš[ำTใๆญีXฏ็๋˜X'Ž€  <คฅหVศˆพฐ'๘ฆ๛๏น]ส—)ผC๗่?xญx็ด@ŸXr๖y_๕ธอ›ทศZ๓ƒsŽ์ูฅhั"ขŸŠ %ดฆ•๘v˜Rู�ถm3%ฤ�)‘‹™ใ3dศเ=Eœหz~ญ์จ-sๆLq๖ ถS๏[?yฃU6m�,GŽ•"E K‰โลlYq�E"”ฆG�dะž={ๅ’KชJN๓หSr4 D?qBางK'๚ษจ`M}๕พดิyม๙องŒŠHŽูƒug; €Q'@ฐ0๊)7„ € € €ค*p 8}ฏXฑขvz[gjbgŸ๓ชU _ธะญ*˜1ci�ดฉณ[ฆฯœๅ.๛/8มB��หด_mu;�>บฎ๏E๊ธ.ฮ ้าง“ฬ™2IตชUmื#GMฐpZเ`แtS)๏ภม˜)ฝใ–(^\.ฉsผทZขทO\ห�`a ฉ†cห–)mฆ Ž &๊๛ŠK�๘ำู๏kฐ`aณ&�)–gฯ๋บ๛่ฝฦใๆฝี)ฟLต]ผี$WฎZ%›ไ‚ตk[ทr฿ว๕ +”/g*F–sำ๗_7™iขw๎ุะ�ํศ ”,ิ[*QชŒไหSฉWื ชยน(TจFื�oะนฃ#{)PHP?ะจYซ 7vพŽ z)xมย Gร…Sงฯ‘5๋6้ณY+6iPOชW)ggv"€ €ธ ] @@@@"P 9‚…^†,Y2K�คPก’3gNwš]ํใ ืๅหgฆฺญ}nช]๏q-ฯ?฿gJ฿‚ Hฉ’%$[๖l6P์ุธ‚…S~๙%`%Aoีพอ&็T" v�ํ�ะžท ?o€1\มยkฬLci.JcO๕ำ”ŸƒNGญaL 'jำ@‡S๕ฐa�ซ$ป)ฃmแขลถ่ˆ] ๐ล;]ด7Xจc7nุภ 8�w๖ุ‹ฬซ3]ถด  Hช@$ ๕ ~าฉ9Tจ"ฝ๏ฝG๎ปท‡N|S!Ÿฏc|.*BVFศƒโ2@@h XmO”๛A@@@R—@r ฝš:q๊ีอ์W็fไrBj:ำืe—^๊ําฒsผvพฌฦฅfvญย!—˜`กwŠโ๕6ศฒฟ–‡t.งำ… zร‚z-?ŒŸเ\Rภื๋ฎ97อขBlิฐพdห3%ฃVš�aฆณึš6idชCfถปฝมB� 3ฅUญRูฬ„V@า˜ ก6 z�AS-๒๗…‹‚Vข๔๖e&)มBฝ�@แยิP•/ุณKํกBวEƒ‚ํฎocWว|7N yืู๔๕|๔R่‚…)๔มpY € €@ด ,Œ๖'ฬ�!€ € € €ั-p>ƒ…*ฉ!7 ž้๔ฤฺV�ฝFVญ^-�ะ�ฟ�ž‘ลK�ฐ๛ใ๛ฒsื.9sๆŒ๘Oœ๏๗฿eืฎ�๎บ.hย†๕ฏ’,Yฒธ�ฝมB -ฆKŸฮ& ีอ,tŽwยฅบ>หT,�k*า@ฤDbฐP๏35‡ &ๆ;cB XŠ}@@ย.@ฐ0์ค ˆ € € € pย,,hฆดญe‚kN�ณg,\ผDNž<้lฒฏ_|ฑญ๘—7Owป†5Œจญb…๒RฎlYปฌำ/^ฒTถ๏ุaื/ujื’�๙๒ูีSงNษคษS์๒ฅี/‘bE‹ฺๅ@ำ่–(^\4y‘–ว3-1มB=ฮ�� /–�ป๗่.�ฒeห*W]q… >ši[ทm“EฦB�… zซ5๊ตlฺผY–�๑ง.บํ’jUEœ6w�|ูmžฅำ7l Yณfตซ๊\ฑrตlูบี>็|ฆฅ๚zC…ฺั,๔Nวฌ. ลธœ}$vชerูiqMู์๔แ&ฉมBฝŸโฆj_~Oีพm[7หถ-1A๚`๗้�‹-.…Šsoc—™ zS* ฺE`!l รFษ@ € €  X˜-๚"€ € € €ค4p ๕žฎบขžไส•หฝ= žํ4ํ44จ•้ดฺ_�๙�ภv�ฝgทฬ๗ป{Œ.xซ๊บ†›)y3fฬh*้ๅฐฏบ]�฿kึศสUซํฒโ4็4 ๎�ฟ_Nœ8!๖sช๐9๛,ิ`]รWIš‹าุกtฺๆ}๛๖ห๑ใว%{๖l’5KV7ผจ๛ๆฬ™็V�ปมBฝXoีB]Wƒร‡bBYQ–ฬ็* zซj_m š—]ๆ�_ฬV฿ฏzฯŽ๎๑ �ฯฟ�ภูปW+�'นs็2~ู�cƒMgํ{6ึ@เ‘,ิป๒† O>%Kฮ~ณQฐงFอ:ฆ๒mL(ŸPa<ะv  Sุแr@@ิ"@ฐ0ต๏๒Ž;ๅ๗ ฝ›ไŠzu%O๎�>�ผ+;อ1LuEm‰ ๊ฑZฑj•ส>!I�๎฿�\ถฬชY๗]่`กVŒฌU๓2sม๔:ตโใ|c๋_qR๗iuJญ้LYญ�œฆกยล‹—J๙๒e%[ึlvณ7X˜1cนาP3gสl๗™ผฉm15$ฯฎ˜—ใ'Žหœน๓�J–็๖ฐ„„.้มBฝำB…‹Jพeงฉ�ปs๛–ะo>{*\ฬ�kูฝs‡l฿�๗'โ/™`aฤ?Bn@ˆL‚…‘๙�ธj@@@@p ฯ๒ๅสJฉ’%EClš†ฦึฌ]'๋ืoด�nำbKซ‹N™์`;t๘9vฃl�{JH=ฎB๙rRฒD S๕(ญ;�ฑcวDƒˆห�Z.ญฎnal�m๚ ทSqQรq“~š+๐่v<ป /ฉZUrไฬ!้ำฅww�gส3๎�ฟOVฌXๅV*tvฺj‡๕ฏ”4iาสฎ�ปe�|฿jNฟ"… ™pe ปบ~ร{�ฮพ๘^›5i,™2e’ำงOหฤŸ&์ฎFE‹‘L3นี๕บ?&[ถl“Uซcช@<ุlิ€`แB…%งน๗tฦ๙_s์?{๗สฎ]ปไศ‘ฃาคQCwJdoฐPวำ๏ �ัpfฺณำE;มBญศตiำf๛�(ิ์zุŽˆ†`a ๛b$\€`aยอ8@@  ร€ศ € € € €L �มB็Fr˜i‹ณš๐]:บK“6;zฬNiฌS#'คiˆMซ฿4S๋ฑ�ƒฅมฟ4iาˆN‰|�๘‰`�ยฒ=sๆฬfแฬ&˜w<ขช์i๘2k–,&๘ฏ5ฯ'T�๘ะฎi�าาxส/ฟ๕ฯ!ƒ ^d’…‡ฬ”ฬ„ ใ“e?$D€`aBด่‹@t ,Œ๎็ห�!€ €)V Zƒ…3f4๐;žd๗B…‹˜’๕[“< pก ,d>mฟS��๗฿ u œ@@@dHฎ`aฒ^4ƒŸwญ4ุผic{^S P.Z,;M…B�Vก|y[‘Pทkจsาไ)�]�uG› i €@ธ†[”๑ˆ\‚…‘๛์ธr@@ ขข)XXขd)iู๚3UJf;Šฉ�ุ?ัฯ็ž^๗›iQ2สมไƒ๗†นใ�r�’�Lcs`�~๙มw{r-”ฏPQZ_�ฦ?๊ำmH,”sๅฬ•KŠ)oืM›6ศกƒ‡โํJ‡ฤ^k(cำ'แ7v๊"EŠณŸึ6dะ๙ิผ๗๛Pง$Z�ืฒ8oDƒ•ซT•| ˜ฉˆาษŽ�eีสฒes์้กโˆ € € €ฉF€`aชyิIพัๆM›ุฟ๗้@\ณvญ์�ปฯVขิส‡%K–0S$rงW�บm›,Zผ$่y ฅa„A€`a( X%’�@@"M Z‚…้ำง—&˜ฮLโ4๚dะ›œีฝf5ำำt๋ัำฃaจท�x�=�ฎป๏‘lูณหกร‡ไ�aC�ํษตPฅj5iัฒต�‹ฯ?•�ท…tชk��Oส•ฏo฿?–.‘_ฆ�oฟP:$๖ZC›> ่ี๛AIo>ฏm๒ค ๒ืฒ?>H่y฿�’!CFw”๗ฬฟ™รๆ฿Žำฉฎ๛_;)Uชด๛ว{oŸ;vศ—ฃ>ฅ๒ข…e@@@+@ฐo„PŠ+*—Tซ๐o�c;vLฆฯœ็5 ๚ซฑŽแ XNMฦB ฒF๖๓ใ๊@@ˆˆ–`aอZuค~รF๖9์6S˜hˆJงMJุ๋ๅf)`ชฆm�ธAฦŽ๙ึ*R‚…z�… vฏ;ุย’E eฺิŸƒํNะv‚… โJ๖ฮš4•jีkศัร‡}ชn&๛‰ฯžเฺถ&�Zฮ7�,Xุ๕ๆ�$ฟ๙๗ฆMรผ๚ว๛3งOKfS- ํูภ๐๑cวe๘ปƒ ž๕ๅ@@@ F€`!฿ ะpa… ๅ%ฃ็ƒ�ใ๕๏;v๎”ๅ+VสัฃGฝปb-,ŒEยฃมย0b2.@ฐ0ย — €Dช@ด []{TฌXู>žx�พ}ษ๖H"%Xx๛w‹NCป{๗.๙์ใ‘ษๆแ˜`กW#u/5S0฿ะฑณญpฺTuช‰ ึธฌฆhR�ษ“'ๅ๛1฿ศึ-[์zฺ4iๅฦฮ]ค`ก˜์Ÿ,•Ÿ'Oฒ๛๘‚ € € €€ ,ไ๛ 1EŠ–lYณฺฉ‘uๆ 1Aย={๖ศกC‡C’`aHLtBD ,L$‡!… ฃ๐กrK € €@$DKฐฐM�vRฆ\9[ษ์ํ�ใคื)W๓((วKT1ิ`กข๒,(;wlOP…ต�๙ ศƒ๛ๅฤ๑๖>ึ๋�๓>ษœ9ณlฺฐAF๛Uœ&‰�™ุkฝุLฯซว๎ูณ�<‡ใ‰=}ผวi-ฑฯูp;Gฮฒc�v9๓๏��Aื๕Bพฺ5:rไˆ๙�ะ�˜ํ|BึำฅK/y๓ๅK๔ต๚Ÿห๙�ำ?ฬ�iฆ�พ๔ฒหm—@มย�๏่&9s็ถภ�ๆซQnจะ;ฆ;�้32dะ›AŸV8ฬeต;w์”ำงOy‡`@@@ JF้ƒ€�"X‰KD ‚F๐รใาณมย0ƒ2 € €@h‘,lืกฃ+V\4,่ด��ื.j`m๘ะมฮfฉwๅURร„›2xฆ9ัO"0ี ว�8.ึิษwt๋!ูฒeณ�F}๚ฑ;N|มยf-ฎ–Š•ชH๚๔้�cด �‚๙๓d��ู๎6๏Bถ์ูไ†ปH๖์ู�{9qโธฌ^ตRถo�&-Zถถ�ฟ๘�ำƒ_๗=๐hXl๙_หไง‰ใฝงKาrbฏUŸQฺ๋๋Hฉาe�๊uz!๚ผถlฺ$?�๘ฝฆlCG)Zผธฝฮร†ศฑำฮดmื^J–,m๛ :ศ=ถr•ชfZ์ฦ6Tiwš/๚œ�๙gL�ƒ์ูฝ�ู๏ซิZ]ำF๒ๅฯ๏>=HkZ9๏ืฉฟฃBลJาดY น8C[ฑOฯฏ๗0{ึLษ•'ทิจqนใด ศ๙Pฑri�ธ™9๖b๗œฮ�ฟฟŒ�๚ห… u*โ2eสษ)sฝCฝๅž๊๎{๎•L™2หฺ5ห?ๆS๘๚ห˜1ฃป�่ั#๒ใธ๏��Nq,4kัRช]R�๖˜5sบค7฿‡ต๋ึณ๋‚…๗๖~P4lzิ„(‡ฟ๛Nภ‘4n"—_^ห๎›9�7๙}�\ท_†Œค๕ตmคx๑’ฎ™๎mช�—@@@่ X}ฯ4R๎ˆ`aค<)ฎศ X™ฯซF 9&‡*c"€ €ฤ+้มยŽ]n–ย…cฆH๕ฟY ๓ie3mu๊^!W\U฿ฟ‹ปฎมญF ๓ muฟืT�3แซ}๛๖สGผ็๖+Xxซฉผ–�T^ ึ6lX/฿}๛ตฯ๎"E‹Jป|ยv�ปwํฒม6�–`แ�=bCVsgฯ’9ณgŠžGƒxX\ตj…:xศ{𐖓rญŽ[ฐ:|H�6ิ๎ึpเีญฎฑหK/–iฟLŽuX/FKฏa4‚>4&ŒVท�•6@ซ๓ู ๆ๛๔ใCชT™;w้zหm&œ™.ุp๒๗฿ซไวฑ฿๛์ฏ฿ ฑิฌ]�g›ณโ๓ๆอ'๚=7่อฮ.๛ฺฺL้]แ์”�>;ฮฎ่1ใk๖๛oำ€f๑’%Eง"์9Wฯ๛๎ท�CJVžฝ่ข‹�ตฯ฿–เ๏ c�r๛]๖{Oร#฿.W^ี ฮ`ก๓ฝ๊�oอ{Qี.นT4ดซmๅŠๅ6$ชหXํึฃง ’fัี€Mบ๊FC@@ˆN‚…ั๙\#แฎFยSโˆ\‚…‘๛์ธrย-@ฐ0�ขŒ—lc'L‘ษSgุ7X฿~ตฏ{ž-fJธWพkื๛�ืMJ•(ๆ๎c@Rฎ@ค ต* V^kjG%K–ฒaจ‘๏ฐเZฅMซฤyƒNgฬ4ชsๆฬ’ๅห�”’ฅJษฅ5.ณำ"๋[ทl–ฏฟๅ>ฌ„ 6n*—]^ำฏ!น)“&ฺJ|+W–ฦMšูœ๎�~๔7ฒ~�:๗+Vช,M›ท0ฯ)ฝญXฉ!ใSง˜ูข๑@@ˆ2‚…Q๖@#่vFะรโRˆ@‚…๘ะธd’I€`a2ม2l๘พ�nผ�6kž}C๔�ฯป'ุฐi‹๔๓&��=n—๒eKน๛XH^ƒ‡หๆ-�Lี™ Rถt‰ไ=ฃ#€D@ค าฆm;)Sฎœ 3ฝ=ฐฟณูพ*TH™`Ÿถysๆ˜@�ป์|้�@I›.ญOๅ;�—ะ`ก3N เW๖์9ไ๖ป๎ถณƒศ๏ ณง/Sถœด๙_;ปผ๏^๙แนสˆบ1�าๅๆ[�0Zจมย‚… K็ฎ7�qฝ_4ฬๆ jฟร�qƒq�พ�หIนึ—_.M%>=�ธ๏วˆ9ญPแ"าฉหMvuƒ \~g‚—ฺฎฟกƒญฐจหรฬ”ึ�้ฏฟแF$ี €๏y�^ฟศ4Œจ-P NฟGt็;wสฯ“'ู~q}ั้ง๓ไษ#’๑fZ`o๓N๕;yา๙หUต้๔ฬฅK—ตห Ÿ'ำMHิ�t:` ูi๓�ัญปไศ‘ำ๎๛า„ๆถ›๐œท้๗‰>m๓ๆฮ‘ูfŠแ๘Z(มยั_%›6m๐ส u5ม\๏tโ>ฌ\Vณ– q๊ฎ?�Xbœฒฝโ jeH�^ืๆTุด+gฟdสœYบ��ำ�;ีMN%D]๎ุนซ.RTล๒ิu}๕ฎผReา„ f:์�v™/ € € €ั%@ฐ0บžg$� มยHzZ\+‘'@ฐ0๒žWŒ@r ,L.Yฦ ปมยฐ“&yภฯฟ+ณ็-ดA…มฏ?—ไ๑@ u ค†`a|Oดซ ๎ๅ/PะV3{็ํn๗„ ฝแธ™ำsซินƒ™ 0็๑NK�สL}ซ;m_๙นฉšธล.{ฟ8ว้ถPƒ…—TฟิTk‹™6VรwK/ดa4 ็eอšM:˜j|ZUN�Ž�ๅ‹ฯ>ฑหq}Iฎkีs:ำ๏ฺตS>�ไ#{4ำภ™6oUB]w๚๛‡1x๘Qยอ.฿ีฝงฉ˜M๔�ƒ฿:๗ฝไฝgb�`a๏MภีT•�kฆ๛L๕๘‹อดฯZูOซ!๎�ฑCF}๖ฑwุ€ห๑ ƒoบๅv;�ถ๗{5เ <5ุyOฏ�ถ’ใฑcวdุA๎�๘‚… ’N&ซS2๋๗๋š5ซeฮฬYr๘ศAฉVญบ�ZวwšNแ��ˆ˜j้ืท3TO5ส‰?Ž๓ ฎ:ว๐Š € € ฝ… ’4ๆwJ €ั"pฦฬjณ}๛Žhน๎’(@ฐ0‰€~��ฯ�่Tท�ฟ์๛พ๏๛.Q”VEHIBvJ+B-hO?=)% i/-R"’,ษพDvฦพอ0๘}ฏ๏�9ฮ}ฯ=๛vฯฬ๛��ฯ�g๙žsพ็uฆ฿3=๓™๋"X˜rึqฝมยธJ1@ ˜@F jPญnฝzRฒdiษaBZYฒg“lYฒI๖ูmXK�ค&4X่ญDw๊ไI[.ะ;W๎\ถ-ซ๎5๒U{ธK๗žf>ฅ‚VZtฮฟพษ ryฃ+ํf\ƒ…—ิซ/ื�pƒ=็%K‚๛xฤ8ไˆ๑�ฮ๔3)ๆZตjuฉVฃ†hซ�์9rJถlY%k–ฌf=‡ •yƒ…zO'�้m‡\ึด'ึ`ค.๓~๙YV�๙ง]ื/�สwบ}ๆฬิ;(�ถn•ลฟ-ิ]๑^ด _ูฒๅฅ@ม’=[vษjๆฌภf�บxƒ…�~ฬ๗DwI๖#€ € €คbลŠ™�ใโคฅ“วโ1@2ฐ@ฤ™ณrเ@โ:ฐ่�V๊�๏ฆRŸ]—Œ��๕ูำ๋๗:มย4๐f#"ฬ/%‘R%Šว{ถ'Nž’ˆˆ)RธPผฯMศ ฺา๎่ฑใษrฟ”ž5ฯฒ{ฯ>)^ฌˆไส้๛ๅญืD!ป๏@˜”,^ฬผวbZ?t๘จไอ“�T~Iนั�ณoฟ6ฟ อaย qY๔ฟ์๖๎?`Ÿป`�ัžBฐ0Z €ฤA ฃ ;š ZH‹iILฐ๐ๆVทJญ:ucบผ฿ฑษ๏—ร‡‹ำ�๖ฌ ภฝ5f”฿gฃ๎%๕คyหVv3ฎมB็�˜>[š9ื�oฮS&MŒตMlbๆšำ�ื�๎{$Ÿฉ–ำ,ผฉEKัค.N;dงEฒ7˜็\3Kๆ,าขี-RฝFอ(?๊ฯศฏ^-ฟฬ™ๅ ๑S�่�r[Œi 7X่T๔฿ฯuC{ๆ็ุ1ฃ|ก=oXrฉisผ(š6ว๗�฿�ดK.`“cฃ๙~๑�/ถ`a ทsฎkiๆ‡`ก7�ง-œต•ณw‰KฐPว๋{ปษ sx~๎ื6ดชๆิ/>“‡d฿ซถ3Ÿ๖๕W๎-jิฌe‚‰-�ฐง{ภฌœ:}JfLŸฅ�ณw ๋ € € €i[ w๎�Rธฏ3Cฺ~f €€Oเะแ#ขgณhด.ฃึ๓๕ล 3๖๓gิwŸ˜fB๙\‚…!๚v๔—•ใ'*๋7m5ํฬ"�Yๆ2UBฺดบIฎฟ๚ wŸณาoะsv๕ก๛zศฒซeล๊5&Txฦ9,U*U>๗v ’๛{�F\,R8๎�๒ใฝ฿แฃวไ๛™slจPoจ d�ฉ��%ลŠv็ +#฿|Oถ�ปSJ—,!ƒ๏๋wL7�ถT4Dจื๐ถืMฮ`แฤพ”ๅซ�–&Dุๆ–ๆ๒ูWำๅุ๑vnื^ีHบดฟอ็t๓œฟ�บุฯVƒ‡m[ทk7tวyW๔ZoŒ›$๛ด•y๔X�|yๅฆฎ‘ฺ5ซษฐ‘cํ๐็ŸzDŠ๑…@๊ไ�W฿้GŸ#วOœtvู_N_~i]้ั๙wŸwEฯ๙ฤด7ึpจwฉTกœ��ตƒ;ทOง~'‹L d'mฏcิน>๓ฤ๏้ฌ#€ T # ›6k.—6ธฬ>�yำ>เ˜iฃบ{ืN[ี์ฤ‰ข้ด-pb‚…W]s4พ๊j{ีญ”“ๆKข_.ศาล‹ๅ�๙sn{ไ`!9็�kฎo"W\ัุn&eฐะ[eqฦ฿ห๚ตkœ[�tZ2'dฎ=๏พWŠ-jฏซํu……™Jrปไ๔ฉำr�๘1นฑูMพJtžVศ:X‰ฝ`ฦqฺ!?4เQ�xืฮฆ}๔'A็ช^qฅTฌTูTG,bว;ทn�bBiSอh?๛?๒˜[a2โL„์7ํ‡๕/Dต"ฅV ผ๙–ึ๖\oฐะis|�Tฬ›๐๎�Aฏ�ำ,‹-fซZ:มBokๅตk�–Ÿf�๔\ง‚ใI๓ณๅ๘qoใ�™RมยN]{H้าฅํญO2;อ?g�E+cj+g]๔ธ��บnอZท…ดwฌฎkป็rๅ+ŠV)Tk]ส”-+;wณ๋+–/“ys็ุu๏ h๊?๋ฅLรผฆ%ต๓ณฑ�s?qย89๐๓ต๗\ึ@@@าถU ำ๖๛c๖ €’ขZก^ํ‚๙™2hดPŸ]—Œ��๕ูํ‹O‡_†เKีŠvฏผ6VN‡‡G;ปšีซุะžwภCŸต›ๅส”’ป‚ท�*?Ÿผ๒์ ๏i6๐ถq๓?v฿รฝ{I๕ช•�ŽGทแ�๏๒๚—ศŸ+Wฆฟ˜ำ ฃฮืY^๙–์ูk*่™เแKC|mืœc๚9{�B๙๖{_5—ฑ#_t%gฐp์{Sdํ†อถŠ`คฉŽขฟtoฐp๘่qฒc็n็P”Oตธง๛~๛w๎�##�/๚‹์`ห• ๋ห๏หVฺCC๕s+S&ิI/๔๕๔™2g�oมng๗.T@^�˜๛ O�๙๋โ?l 2บ“๔—ไฯ?๕ฐhรIO5แีฟ‚ีใรž๔;@๐ d„`แ}๔‘|๙}ี?�`ข„ด่u฿ƒ‰–7!จ๖;Yฺล‹ส’ล‹ผฬัฎ฿z�ํถJ›˜2๙}ค ‹2ึ[m1ฎมย[Z฿fCu–Œฎen+3ฆfอฺ๖~ใ฿kย'ข��ป#1su*อ†7๋ป•�‚…zผื=๗KAำ:Yf3พŸ๎ถAž๚ลงฒใ฿Kฤ๘ฉUตีฎ�\yV��zŒให•//:vฑc์฿/M™ไ7^+๔u้ึร๎๓ ๏%�9v��c$"<ย๏<ญจจมศ,Yณ๘ ucfยtiOฌ็๖3aG}†˜*"zo˜RมBงฝณ๗�ฑญo฿พMพ�๒s;Lฝ‹)j+1jฐ2ุโ /~๚ั[ล0ุ8g_ž ๓Fค X˜t–Ivฅcฦ�Š~zมŠๅหสญ[šฐY1๙{�F�:czฺ๋าณK;น๒r_{6�v‚~บฎย๎ฐU 7�ณ]&�ฅœ4UYtั�5ฐ๋๚ๅฑม/K„i๓ฅห5ฆโ^ืm์zl_ผ๗ำŠทถl*W™๋jตป้3~–uทุKไอ›G^}�I๗r ฬฅDฐะ™dญUm๕ม|f๎ฺFZรr3็,ฐฯฅcŠ),ww๋ โิ@โdด 7-งuุ�~ั ฮ๒ยซoุJ…บญ๏ณ�m7�สˆK—�%฿|�“_ˆ1)‚…ฺ๖๘ๅพ*2ฺnน{วถri�Zถm๓ไฟ’�{๗ูฉ5krต‹3ฯGž~ษVKาwฉ฿.ฟิT๑9)฿™w๙ว๒Uv˜œิ*šงN‡หิi3lจTษ์„ ๕_œsๆฬแ\–O@ขศมย>=,9Mลi�ƒ7G๙Zฯ: Zอฎ‡ฉ ง�=zsชร>|H&ฟ�žsŠ8Aลใ&่6aœฏ*7๔n�0ๅท�pว;+7ตธYJ–*%แงO�ถฎบฟVํ:nๅป`aฑผฆu๐ฝ๔ถ๓ำ๑q 6ฝษTiฌ๏ซา๘หœูฒrลr=�o้gnูLน˜*zOHฬ\่๛9๔ะกC๒มฤ‹–z�—5”š6ณท ึšW+J6นกฉ=ฎU ตฅuDDธผ�ฆฟฑถัmpy#;nฮ์™QคNีD �ฝ๑๚;.บ/�9�ตjฅฬ™�“฿ะ;›Šz์>oฐ๐๚&7ศๅฎด๛๗์�mZ่^งฎRฎœ๏gิ@๗๛z๗ตญขตš฿”I๏หกC�ฮ๕ถฎ^�็2™�หฟใม6R*Xจี/+Uพ๘GLsษo‚ฝ๚ฝฌหพ}{ํ๗�๚ตkeีJ฿๗eง.�คt™ฒ๖ธืำ๎0_J–,%บvท�;zT�oœsHฺดm/นLหซฐ๛ฃผง‚… Iฏ{ฐc7ฌ_+?š`*  € € €@๚ะ฿ญh[d�XถฌYำ๏ƒ๒d €้N@…'Lงm์ํX˜๎”B ,L[๒๔ฯ๖ถUฐ�AChƒ๘~ๅ�Qซ>๑์pFำ๖ป#_์rƒ…ZYnไKO›๖i�ลE[๐jภM—หL+�{{ttฯ๛๖‡Y2๛—…ถZ฿ว๛นํn�ัฌxƒ…=tฏ 1z‡Ž›๘ฑฌ^ปม๎๒†C=Xุข้urปi‡์]๔ฟ@y๊E ะฐแpOPRวiซใม/Žฐ�E[ฒxQท๐ฆ-�d๔;ํฅ*”+#O<� ๗ฒโ ๊คพ๒ฺ�ฒkฯ^[๐ๅก�Pค๗ฆOฟ๐?;_ 18ญฆ5(๘ฐy>]๊ึชnZfw๗ž"›๖ศaa‡คrลrr›iลํ,บ�7ำู{-็Ÿ €ฤ&‚…�๏๊ๅV-�ฒyณฬ�y–ญ~งAนf7ตฐแ:uJLฐPฯื*5�ซxไศ๙๖ซ/ไ๐แรRดX1น�ใ*TจจรฬŸ๛Wค{ฐO?ษ'=ถ{๗.�๗ˆ9O็wS‹–n;^ื`ก&{๖บื�,ขAบ฿�*,]b๏กฏŽ&ศU @ปฝeำ&๙nฺืv=ถ/ ซำVXž[dๆฒ�ฅถt“›I}ำบVŽั%XฐP๗; u]—`!ฑ*Uซ™Y;{\ƒ‡_O�R๖๎ู-๚syC๖ำ๐›�็ธi…=a�;v\t_๒็/`z\ฟ/f�4ร�shหโึญ�J๙Š�SƒpNซf -‹w๎�nว–-W^ดŠžณ +Wฎ*ททkokv�œŸeอ฿™Pl.นแฦฆ๎๗ึ๓วHcวŒr.ใgJ cœ„9x�๕7šึิWุaZAำio์œ็ญฉ฿ฏห–-•eๆ๛U+>ึ4�ดhัสVyิ๑ณfฮ4.พ?ธัํ๛4Lำ๖XmC>�—น๖i๋ไ›ฬy…MตK]~˜>M6nXoื๙‚ € € € €d ๆI3ู/้๛‘อ๏.˜?2ศ๘”�๙=ุN“ C์ต}=�'ำยึืพ๎™'ˆ†ิ—)Ÿ}ํถฮ}}ุPษ‘#ปโ�œชr็=6ฤT&Œ8#มn๚‹V�kช๘,ฮ�J—,!C>ๅิ'Oษ“ฯ ท๛๋ีฉ)๖๊jืC9Xจox!สณh•ฟa#วฺ��Lภซฏ๐Uแ๑|c�$ั–า่|c๘ณ๖ะ฿� ๓�nืฝกA๏yฃ�ž(›ทn‹2&กNž|มVbฉc‚}‚z“_~]b* �h๏๗ยำบAR็}j•ร๎๊"Zต1ถ…`alBGˆI # +Uชl[�~ฮ๒��n*kEรฤ 5ดv๏‡์_ฦ;ๆ’rBsบO�๐~๒แ‡r๐เgˆh ฎu›ถ~ใ�ƒfE�#)๊๛y4ฎมB=�๚n”ห๚ย\บญs9�œ_P1ย�มฬ�Aช+๊๘`KB็๊ญ x]๏ผข z�A๋๙ฦฟm‚ว/%N+b็@ ฟn0i‚hp3ถๅฎ{๎3กด"๎0๏๗Œณgฯaฟงƒ… lkพ฿4ะธจทKต๊b`ฐPว�ักฃTฌX)๐4w[็�๓, ึญv๗ลด’V‚…๚ ญoo+ีชีpGฝ๕?�~‚…`5€ซีฝ�๘�๓)AฺKป7c@@@@Hวๆmตูย &Žโหฦ/—ฒ4ๆCึล<y0๛�ƒN5ฃ?Pvฆ)‚…!๖บ�zoŠฌ3ญu๕—XN5นภ)�นrตL�่Kป{@๏ปฅFีสv� †�vs3น๙ฆ&งูŠzฺฆธl้’๒๔c}ฃ๏็~MฎนR:�qkะำ}Eดสข7|˜ะภ\JดBึฆ†5—EK–ษ'Sฟณป *เW า{ไ่1qฺTk8Qม๘ๆ๘dฝi ำ๛œ5๗W™๖ใl{o๘0!NZฆX++๊ขฯข-ฑ—pS}E+,๊rwืา่ฒzv�pิZณB๙2ถ๒uW5๒๛…ฉ=ม|!X่H๐‰ ๔,ผต๕ํRฝfMž ึๆ๖า๚๕mี4m�๋,Z-xๅ๒ๅR `ฉVฝ†œ5•เ�๒T‚{ฐฏฉ$˜;mI๛มฤ ฮinxํ๘qำ ๙�ท��ฮІรส›6น�@”ค˜VญZ5-XจM[ฝถmงไ2ี้œEซึ�ป�Yผpกt๋yท��้GSd๏�=ฮX?ฏl|ตฉิืุ/L่œคm…ตชŸ†ใณ$tฎ-nพลVa๔บh@๏‡้ำฅyห›mีน`ํ unๅหW”๖;ูiF็ฎ๕ฺ๊Xฮ„๛ผ๗ัcZฉP[�๓ฯV�ŒuษnพWฺ฿ูษดฏ.ํŽี๗จื๙ไใ)๒@๏‡์=–šสz‹ฬwว่ŠV6lูชต+Zฬพำ“ฆ}…VOœgฺ฿|หญ& ุUช\Eส˜นdฯ–�†ษ6›ฐีฉ“'ใ{)ฟ๑ kฉาelๆ�ูb[�๚]4šz—ึ—fอ[ฺฃK—,6ํ”D3๒โ๎โลKH ุ�jบ,\�‡�=๒ๅมถeญnคVฐฐ\ูา๒ิ#ฝงi+œ<>t˜�_ทVu้sowป>์5S•qฯ>ษmฺํx้้(็M�dช�ฑ�/ป?T‚…�w์’�ฝ๑ฎS็๖ท‰ถŽห๒™yWฟ�๗ฎข{ŸcM๛๋ตฆ�ต.�`aB๚?๑ผญJTซz้๗ภ]q™fŒcV�ฝฮY?ทืฬž=›Œzๅw< ] V@ @ฐ0hœ’"•ซVตm‹švยZฝO—๕๋ืสŒ๏งงศ�rญ0�ท�#nๆฐฐถZฅV,_กขไ5“)“๙ ณฬ�๙'YตreBnร9 € € € € € €D€`aˆฝ่ ›ทส˜q“ํฌjTซ,ผ�o†‘ฆš�ใC†™ึ\็ฬ/9�C^‰ j{ๅขE ูฐŸ฿ cุp๎งC† |HJ—,แ7zสg_ห๏ห|ฟฐิІZูP—q?–ีk7ุ๕�ฝ๐”ไษ“�ฎ๋— .ศภกฏHxD„�*มBm�ศำ/ูp]พผyd๘๓OบsvVฆ�8[ถ�ณ]๒™_ฺ�Wgป๛๏uๅ๗?ฒ๋ม�็ัcวe๐‹#œK๘ ๊๔��–ู_kKๆ๙๓นืืmฝ�f๚Oฒdู {zฎœ9E++:หฌนฟІ๐t)^ดˆ๔7แIญฬธkฯ^[o�ƒฮP •`กNศiลฌ๋ข|่�๖ฝ„๘LVฎ^kฏ�—๛zv–๕jป‡‡4-ช๗^�Eณถอำgv�~iศc~มมa‡ไ๙แฃ! =ด@IDAT๖ณpก‚vœ฿N6@"@ฐ0 ป@@@@@@@ X/!ุN‡‡ห›๏~ ฺขุ\หj*6mrต�~K๓(ง9Aฟ๖mZIำ๋ฏŠr\Cq‡5 �C‰N;[ Ž ~ผฏญTๅไ ;œ๛i๑เก#ฒ่๗?�ยyr็’พ๗๕Zq๏�0๓|“�‰Z๕ฐvชrี—‰VQิล,�z๚Lำฎ๗ท(ํxw๎�#�๗๚;v�ฃ}๏ญฮ฿ลi;ฌ�^6$ฺำ๕]L๚xชฌ๘k_่NOจZนข๔๊ึม/x็\Hรขฺโ๚ุ๑ฮ.[ๅฑQƒzRปfU™๘ั—vฟ7Xจ;โไ�`�ย฿ๅ›f๙UDิcลŠ–ฎn—๊U+9Cํง†๕ู4่ ๊AญTุฃำRฉB9ฟstc๎‚ล๒�ŒŸ�๛h๋em‹ฬ‚ €@l cโ8 € € € € € € : Sว=^wีPฺแ#วคBูาขmj“cั ฃถฦีpa\oฐะiฝฌCo๕*•L๋ตlฑ^J๏ปีดx.l*�i๋�คZœ Œฑ]/SๆL’-kึุ†=ฎUท๏ุ%ล‹ถs‹ถ�d*5U‹+bฏ๛็สีั 'ฦIฯ�ดy›��)WฆTœ�‹ถฃึ๊…ิsฒฦมH+l9z\ ศ—`S็y๙Dศ 3ฦ{ๆ)@@@@@@@ ํ ,L{๏,df,X “๛อTN�๘หiqžŠท*bœOJยq &แํธ €!#@ฐ0d^A@@@@@@�๚qฐP �ฝnฃL๙๔ซ8=ŠV��“q›\ƒ&—,ืEu‚…ก�†˜ € € € € € €dT‚…๕อ'มs‡jฐ0 -E/Aฐ0Eนน €@ , ก—มT@@@@@@@มBซ๑Xพ๊oนpแ‚ิจZY๒ๆอฟ“ํ œ—ต๋7ูํ๚—ิ–,YฒธวXA@ = ,Lฯo—gC@@@@@@ด,@ฐ0-ฟ=ๆŽ €คa‚…i๘ๅ1u@@@@@@Hื ำ๕๋ๅแ@@ะ Xบ๏†™!€ € € € € € €@ฦ X˜ฑ฿?O €คšมยTฃ็ฦ € € € € € € €@Œ cไแ  € €@r ,L.Yฎ‹ € € € € € €$N€`aโ�8@@  วi € € € € € € €@2 ,Lf`. € \€`ap๖"€ € € € € € €ฉ-@ฐ0ต฿๗G@2จมย ๚โyl@@@@@@y‚…!�Š˜  € >ฆฯ๗สS!€ € € € € € €@ฺ X˜๖฿!O€ €คI‚…i๒ต1i@@@@@@ศ 3ภKๆ@@P XŠo…9!€ € € € € € €" ๙.@@H‚…ฉยฮM@@@@@@@XฦJฤ@@ไ X˜ช\@@@@@@Hผมยฤr@@,Lง € € € € € € €) @ฐ0น € €@T‚…QMุƒ € € € € € €„‚มยPx ฬ@ศ€ 3เK็‘@@@@@@@ M,Lฏ‰I"€ €้O€`a๚{ง< € € € € € €ค‚…้ใ=๒ € €@š X˜ๆ^F@@@@@@ "@ฐ0ƒผh@5‚…ก๖F˜ € € € € € € เ Xศw € €@ช,LvnŠ € € € € € €ฤ*@ฐ0V" € €$‡มยไPๅš € € € € € € €@โ&�+ € €$@€`aะ8@@@@@@H‚…)€ฬ-@@ข ,Œjย@@@@@@@ †ย[` € €@ X˜_:Œ € € € € € €iB€`ašxML@H ำ฿;ๅ‰@@@@@@@ },L๏‘ง@@าœมย4๗ส˜0 € € € € € €d‚…ไE๓˜ € €@จ , ต7ย|@@@@@@@ŸมBพ@@RE€`aชฐsS@@@@@@@ V‚…ฑ1@@ 9&‡*ืD@@@@@@/@ฐ0๑†\@@  €ฦ) € € € € € € €@ ,Ldn € U y›NQwฒ@@@@@@@ ีฆ๚+` € €@ฦ X˜1฿;O € € € € € €ก/@ฐ0๔฿3D@าฅญำๅkๅก@@@@@@@ ,L/‘G@@าขมยด๘ึ˜3 € € € € € €d‚…แ-๓Œ € €@ , ม—ย”@@@@@@@#@ฐo@@T X˜*์�@@@@@@ˆU€`aฌD @@H‚…ษกส5@@@@@@@ฤ dฺพs๏…ฤ_†+ € € ?fอ[ฤ๏F#€ € € € € € €คˆมยaๆ& € € EุF@@@@@@BC Sแ>ซฉX๏‚Y € €J ๐ผn๊yyX@@@@@@@ ญ,L+oŠy"€ €้L€`a:{ก< € € € € € €ค‚…้ๆU๒  € €@ฺ X˜ถ�ณE@@@@@@Œ#@ฐ0ใผkž@)‚…!๕:˜  € € € € € € เ ,t)XA@HI‚…)ฉอฝ@@@@@@@ธ ,Œป#@@’P€`abr)@@@@@@@ &!&—B@ˆปมยธ[1@@@@@@HI‚…)ฉอฝ@@\‚….+ € € € € € € €@H , ฉืมd@@Œ#@ฐ0ใผkž@@@@@@า–มยด๕พ˜- € nฆ›Wษƒ € € € € € € €@: X˜ฮ^(ƒ €ค‚…iๅM1O@@@@@@ศh 3ฺ็y@@ X"/‚i € € € € € € € @ุD@H‚…)ใฬ]@@@@@@@๘ ,Œฏใ@@’D€`a’0r@@@@@@@ ษ&9)D@ˆ‹มยธ(1@@@@@@Hy‚…)oฮ@@ŒมBพ @@@@@@@ะ Xš๏…Y!€ €้^€`aบล<  € € € € € €คQ‚…i๔ล1m@@ ญ ,L๋o๙#€ € € € € € €@z X˜^฿,ฯ… €„ธมยAL@@@@@@2ฌมย ๛๊yp@@ uฆฎ?wG@@@@@@ข X ๛@@’U€`aฒ๒rq@@@@@@@ ม Lว‰ € €‰ X˜=ฮE@@@@@@’O€`a๒ูre@@ฦ€ร!@@@@@@@ ฆ">ทF@2ฒมยŒ�๖yv@@@@@@e‚…ก�v˜ € Žฆใ—หฃ!€ € € € € € €@š X˜ฆ_“G@าฎมยด๛๎˜y๚x๑นกาฎmู Lž{แe๙uัo‰~ภหิ—š5ช�๋ “ู?ฯM๔5น € € € € € ฺ ำงOห™3gR{*ษ~‚…ษNฬ ’K A…\๖า๛Žž•�G"“๋6\@’I€`a2มfภห–+[F๎ฟท—TญREส”.%y๒ไ‘ฝ๛๖ษฮปไงู?ห7ำฆg@•ธ=r๊ีไ๛oงบƒ—ฏX)บ�ๅn'te�;oสMฎทง๏�ท_ฎปฑyB/ลy € € € € € €@ช ”)[Vฎบ๚Z)YชดdอšU2eสd็r��y9~�˜�4ใูตsgชอ/9oLฐ09uำเต๋•ห)5KๅŒvๆวรฯษชOงz๏Šสนeฦภสvž‹7Ÿ’ึฏovฮ้แ@�™ๅ�&Eคj‰์Rนxษ‘5“�{๐ฌlู!฿�yTึ๎ Oิc–.˜Ušิฬ+Œk�ฒน$๒�ูvFึํ—7g‡%ฺ๊œŒ €@t้!Xx[›;d๎ฯณไไฉ“ั=&๛“Yเ™มOJืฮํฟศEwซM›7หƒ}ศ4LŠฅd‰โาท๗๖R.\�eพN%ลฅS�มย•ซ�’;ป๔H๔<&𐠀 € € € € €@<:๐ษXg๑วา%ฒpม�Xวฅต Sเ=ykqyย�็นe่ิ=๑บใ[=สH—ซ ษง‹Kฟ“ๆก1M`มชRงL๔มB็�#งฮษk3ศ�s’'tVฃd{ซ {#œ[๚}zƒ…ฟo9%ทผ–~ƒ…}š•AญŠK�™� œศ๓"”งฟˆ฿๗–s~ว+ ส่๎elXัู็�“wสKธ�ฌ € ๔,t<Ž=*sfอ”ํ�ท9ป๘Lb�nm%ฏ๎^๕็9ฟHŸ�ธ�ฮสำO“^�?ฟำ๎ป็.yธ__vฬ้ท_7"##eโสˆืF๛ N�๚้ื็Aฟ1บฑc็.้ำ๏aัwร‚ € € € € €ค%J•*K�๖wฺ)1ฟป™4๑=ฟ้—*UJ:t๎fZ'g๑�๏�x็ญ7$<<�ป+dึ ฆเซˆKธ05C…J—`กŽซP4›,zฆบhปgยฟฆM๎1ษ›#ณด6•๔t9|๒œ�ด:j0ั4_Vส%UK๘*ฑ,XBสฮn+"6ซOฺ5,`‡ญุ~Z&ฬ?hื๗”น๋|ี๚ขซXุฌN^นถZ^)œ7‹lู!Kทœ’%ๆ?ฑ-ะปด|.ฉ[6งญฬจ็�ฝ#\–n=%ฬ็\K็ Ÿ>/?ฌ:fw7ฎ’[š˜J€e e“ฯสบ�แ2}ฅ๏˜s^\?ฟ}ค’\W=��7{ๅญูaAO�ธwนน^>{์cำj{@Zmื.“S˜jˆฮ๏ o�ฟอ๒—y�`ห็Uj%|ฟD~o^˜ผ3ื๗>‚e €๑HฯมBวAKข�:๏S‘ํคณ+]|f.‘Mrv,,็๗ž•๐/ใ^/)^ซ ~�๑ล �^yuค|๘๑งqพžฏื‰i9u๊ด�ุโไ ฅ`กฮ๙�นs’%šUVทต‹Z ๖ฌ1 >๖ฐุทฟํ–ฅ;#"ยๅจฉjx๊๔)ษ—ฏ€*THดšแป๏ผ%งN†ๆ๏ ๚ฝฮไ฿ˆ)\˜ฺกB}๚ธ u์Œ•EรuบŒ๘qฟ �~ฟ4ฏ›O>๋[ม๎;{๎‚Tธ.ฺ`�โgซIu่ำๅๅi๛คล%๙�ู๋_v>+๕†lฐ{ƒ…๏/8(o฿UNฒ๚บ๖๚ฉว๎ : BŽ้QFnฟฬd๔;ัl2แศG>ฺๅฝว—>_]ช˜`แำ‚๘zำ‚x๚ฃ•ค iธฌู.ฝMฅฟตๆ3>‹† k”๒๙|๛็ัh+Bzƒ…ใL่oศิ=ฑ�ๆฆ แฝฆก.n;--�ท%ึs€ €@R d„`กšE˜ฟ0Zธp�ตrERฆส๕4T˜ซG1ษ”+ณœ?)ง��›*๓ะ›ฎ\ถX๒˜ึล�ๅ๔้ำฒl๙ Yน๒/๙}้๒๛หผ‡�๕�oปUFพ๚ŠปvP&™ส{บ4ฟฉฉิฟดž{lฺw฿หภง†ˆถ"๎ฺ๙N๓YS.ฉ[ว=พเืEฒg๏^ 3%๋G๋๎ถ’T kkKdmฟœ;W.นฉYSษ–-ซsHf�4[<:ะ�Žn%บ`กถ?ž1��bู9w‘i}ผ|ลJฉQฝšดธฉ™ณ��L|A:wฟ�ำม‚…ปv๏–๕6ู?nนฑษ๕n•D��คd๘_eF�fA@@@@@BY —๙ี�๔•,Yณุ฿“|๖๑‡ฒw๏ลฬŽv‚าฎMบhจ๐ํ7฿๐{œ,™ณศ5Mšศข๙๓ๅ�๙ค้๋wƒ$ุ X˜ˆ๑ฝDฐpกถ/๓ถJ�lษayhสฎ๘^:ัใใ,�คOiiย€บL�๕<�้nปพ๑ตคˆฉจ‹๎ำc‹V�อ u9o‚y—Y/๎-/WšŠั-;•K‡F Fš๎ภ็ฬErd๕o็ฝฮ—ฆ}ฏ†๛ผKQ3วนฆpS]0ถๅตไ•้๛�†�๙buฉX4ป�ท�„KวpญฮHฃ็6๚ŸZ9r�เj’/ง/QูoสN๙tI์ญŠต แMu|๏nะgปeโ฿;r*.ๆษžY6์‰�žŽw 2)ž‹k €d Œ,ิทy๘๐!™>ํ9ผqZyใ�Pแ…๐srzJ˜œ฿w6ีฆ฿๋ฎ2๘ษ˜ƒsฺ2๘[ ๓ึ;~๑ฆ}๕™ :“o�ถƒ_;�…๓fK‰โลํaญ�Wซ�ๅฮP้tg{y๙…g�ํvปส๊ฟืธ�1ญ$eฐp็ฎ]าพSw[MQ๏yอUๅ�๑oปU ฯŸ?/—]q฿s›[tมBo๋e=o๊ื฿สำCŸs/1 _้฿ททปํmG,\ณvt๋y;—@รรๆ/๔ฎธบ‰{-V@@@@@@P่y๗ฝRคhQ;ลM7ศ๗฿}๋7�"EŠIฯ^พฎP๚๛ชฺ$๛ ั ‚…ฉ๔bร…�iคVจP็Ÿ`แoฯTs+๊=oZ๕พ๙_ซ�‘]JKฏ๋|ี๐ๆ™วํวl๓>ž]าฆ„�๒+ฟyฟ๕ฦkาฒ๙M๎พ��w–ต๋ึน�มVข N~�]Vิsฮž”kol๎๚9ื๙}ั<)lJ๕๋ฒyหVำ~๙ป,ผ๛�Eซz—oง~&ujืrwีox•�%S�?RQN0;ยฦึ5‰h�#{Fสคeำพ)–/ซฉๆXะฏโโš]แr�ฐอ�'ฑ… €@"าkฐ0ย„ซ.\ ญ\‘ะ95-„ ต๒ไฮ-ทดj)๗๖บKชTฎไv‚o5ชW“๏ฟ๊๎หสภง†ศ4ำRY—P Vซ}i”ฉkวW_yษ�ฌชก{๐ฟ•่‚…K›/… ดฃด๊ก�� ผf7^la์ฬษ,%M5ฦภsีN ๅษฯwห„๙‡œM>@H”@z n6U4๗็Yฆ๋ษDูคฤษ9๏,"™Kf•๐/ษ๙}ม�e%”C…ZuฐL้R–J+โmุธ) › [0ืmyฌฎ3ํ|?!+—-vวk›ไQoผๅn[ัj‡'O๙~�Kส`a`˜ฎvญZ2ํซฯ�)L˜๘ผ:๒uป��ะงฅ{ื‹แพึm;Dy๎~}”‡๛๗uฯฟ๗มพฒเืE๎vฐ•่‚…฿}�…ิชYรžฒ�ภนฆษลหฮuพ๚�cทe๔กC‡Dซ(๊โ jy�๊u๊;งธŸร‡ฝ(ํ๏ธ��nฺโูฑ3jตrw+ € € € € € €@* Tซ^]ni}ปdฮœY4T๘ใ๗ำโUqฐH‘brษฅ๕คFZ’;ฯลยb[6o’๏พ�:•ž*ๆ�,Œู'Yކ ?]rฤ�งKc_5�Hญpก7X�ร;}^ž�z|ธ่p”กฺ†xอ๐Z’ีt!l‡์ญfฌ�r|ƒ…1Uผ๛บย๒Z—าv~�`แOƒชHรJน์�>“wสK}๏ สƒ˜�๙jปemปฌ‹7Xxษเเฝี,ด7๕|ัหด,.mไwซ~ฝ์จ�?ั?จ้9ล]�๖zmท•ฒถ9พ๚ลA+>๊ ฺึZ[G๋ขN๊ล‚ €@Rคง`แัฃGe�/sD๐O+K๎�%%sมฌrม�Lw๚รQย…ก*Tใัฏฝ*ทถบูr๋ฟผ5iึR๖๎‹๚ว"_~๚‘ิฟ๔๗ต8ํƒตฒ†u9q๒ค4htต;ฦY)Yขธdห–อnzoมย๛{๗“y ~uN‹๑3ฐU๑๛“>แ#|มA=๑ษษ}๗�ๅ^#ฆ`แงŸ)ฯพ๐ฒ;VWfฯ๘N*Vจเ๎‹KX/บ`แ›ฃ_“›[\ �}๏ƒฒh๑๗ฺzŸ™฿ใถ^น๊/นณK{�,ิ#^-ใ฿ŸไžซกฯsgI��๙์พศศHฉU๏r๗8+ € € € € € €@จ”+_^ฺu่dC…ZPa๖O?ษšฟW%xz—5l$Mnhjฯืถศ�};มืJฮ &งnk ๖›โ jํYF:7๖ตํีSS#\,<}๖‚฿Sœ2ี๐ดU๎฿;รeฤ๛$์ฤ9ฟใ�ฏT’&5} �ว?�-“=$� ถ�ญ๓๔z๏)v=พมย฿Mฅภ[Lลภ`Ktมย%ฯU“j%rุSบ�.3�๒…ƒ]cึUไ๒Šพ`พ+'šฺมBgฎร;–’๛o(b7ต‚dอ'ืล๘^t 7,๙๓šใาi์v็rQ>๛5/*/�Qา๎_๕oธ4N;ไ(H์@H@z>�ุ Yนbน,2ญ#ฯฏ๚— œ8ษ{•L9ณD †zจPy๔๋#�๛๖vฅ6nฺ,ฏ แ฿44xW๗ฎาท๗�๎˜}๛๗หต74ท�ฦ•&ื_๋{wยD๙๚๎๖งN’๕/uCsN Q�ู�yๅฅ็�ฑ3fฮ’ง‡>็V4tYนแ๚๋ไฝqซ#jrไ๋ฃeฺ๔ไสF ๅืGH‘"พภฃž๎ V,ิ0��FŽ’IS> ๊ฝ�โณา๚–V๎]ฝ�AVข ๖ู๊]?5ศ=c๛๖ๅ>ข�ถ}ป eพ�๎Xฉ[็b%์I|(ฏผ:าŽ ž:uZ†>๗‚L�a†=wฬ๋�“+ฏhไ^{อฺuาถรลjŒ๎V@@@@@@T(Yฒ”t์าอ�ั‚yฟศŸห–&jFy๒ไ•๛{๗ต-•O™Nh๏พ}๑wG‰บpŸLฐ0‰Acบ\LกB็ผิzƒ…มช :๓ŒหggSqlฯฒvจำY�#;mวอ=(Cฆ๎‰rฉ”~๓p%นพ†/๔8ะ„'™ะctหส—kHนยพJ5mF�#‹6๙Z†JฐP็ฝ๏ญบถ:คฎk;ไภึิบ฿ป|ูฟข4ญ•ื๎๚ฤดˆ๎�_‹h๏gฝ}ฃ2พW9ปน๛๐YนdH๐ถำฮx>@ˆซ@z/QR๖๏�ืGนqมย…:ษ\=ŠIฆ\™ๅB๘99=%,J5รPxชU*›–มŸK๖์ู�ฆ.‡‘Rฅ|แ=8q๒๙ฟ�ฝfw้๙ำฟ๙Rฒfอ๊ัช„วŽ“ส•*Jฎ\พ?,ัƒซ�Z-:wwวi๐ฃ�wทuๅ์ูHัp�].Ž๓๐฿†�2�TBผx฿`ใœ}1U,tฦD๗ฉAI LฦถD,ิ๓+ juH�.^ปC‡Kำๆทธแสภ`ก=ม|ั0d–,Y์ฟ(;๛๔ณ฿รหOณ๖๎b@@@@@HU\ฆฐร}๔q'ฒ�>ูบeKะ9%ญ_^๑Q‡บฅธ<ีฺ๗ฬ–˜๊ทFS2บ{ฑ@่าCฐ0บgKK๛ร…:๗P:พททi-#�๏ๅ(!5็ธ๗๓ฯๅ+คs๗ปฝปlลร~}ดe๋�x6ยยJ^๗ษๆ-�?/อ๛y†”)]ฺ3Rไˆi‰�่ช๋�๖�xf๐“าำTS ถh•AงEณ)Xธw๏>)YฒDฐหุc\+ฦ,ิๅุ1ฃค@�A๏ฃ;OŸ>-OyVดrฃณxƒ…๖�ฝปcงฯKฅวืบsN๎`แ๎1u$GึL๖~ๆำP_ฐฅv™œ๒๋ช๎กธT,lX)—�4จŠ=็ผiŸฌื_บ5๘๕W™Še�ซุ๘��C๒ฤ็ป�{ฑ‚ €@b&F/iฯ๕† ๕สก\ฉ0๐ษ_y… >(W˜\ฐๅ@X˜ ็iตย`‹ž�์'M•ยJn {!฿�8Sฦพ๓ฎh%รภE+๖พ�^น้ฆฆถ ฑ?x๐4พ๎ฦภกAท>๖ฐ๔บซ‡dฯๆซŒ}๎�9ูดy‹ผ๐๒�ษ่ื^•��•ZLมยๆญฺศห/<#๕.ฉ๋VX'W_uฅ{=ฎF+W�eZฟd�#{ฯcZ:ทบน…�ตtูŸ2โตQ๒๔m๋ไlๆ™3eสdฝ>�๒+5&4ห๛{Ÿ‡u@@@@@ศxฅJ•’ฮ�zฦ้มฯž=+oฝq1Xจ• ;t๊d~ท’;h‘Œใฆยแ์™3d๛ถโt�ิDฐ0ิพ]ืฝK\B…ฮเภpa‘พ;‡’ํ3ฉƒ…ืTห#฿=Z)ส|Ÿ�fฏผ9;,ส~�แmฝ{&๒‚TดNNDœ๗›ุ`a�™eีฐR0ท/ผ์Ÿำาํm~แยปฏ3ฟ@ฝณ”๎{cึy๑�}๎<’;XจมI}N]v™ฤทฺ*�รฮบ๗ืญจ๘ใภ*Rฅธฏเแ“็คช๑rญzุผn>[ฒ๗คฒao„sHผํ�9pฦ<�vฟใj๔ฎi|sฝ|๎9]อ˜ŸVwทYA@ 1 ฃ—๔็:แBฝrจถ?Ž้ฉK–(.ีชV•ฒeหHฮ9d็๎�๒ฯ?�ขTŒ้—ิญ#๙๓ๅ“]ป๗D สลtžหcJแŸ<�5b:ทF๕jRดHะ‹ํ�็†>-�ปvv/Wญ๖ฅ๎zํZตไ๘๑cAC๎  +๕/ฝDพ�๔#๗Hฐ`ก{ะฌ”3พนอณFDœ‰ท‘s}Wบ์�ท฿ูล' € € € € € .ฒdฮ"UชU“"E‹JฎœนLแ…ƒฒsว๓šU ฝ/`กW#™ึป4.(ฺ y��ƒ2d๊žx�ล ~ถไฐiqตRJผ.‡มI,ิ[ฎxฉ†”/โซฤข�‘&#X็ฉ‹-…uŸwฉW.ง�๒๔ล |ZQ๐ื 'd‰iูซแ>],ิkxซ๊๖‘S็์=ฒšฌa‘ผYฅA…\บ�.๛ŽEJํงึ;›๖3นƒ…ท_V@�ฟทœI-๛nซ!หo—•U�žS UดRa๛F%w๖�˜aรฟ฿/#~๔�‚ึะิ+|�๛้๛มN฿ลฬW}พูฆ5ตs�pใ�๕ฒ#rิTfิ+ถi_Jบ๘�ฆ™{฿3a‡{>+ €$V€`ab9?ฃ ฤ,Lˆ…^ฏนฉธ่TGิkผ2|„Lšr1h˜๋r € € € € € €@ฺ X˜๖฿a’>Ar ‡�^BmYฬ็œ5'คใุm๎vฐ•๙ƒซJ�ฒ9�iีพzC6ุ}I,ิ ฝัฝŒtฟบ฿}7๖”'๎E›N๚J๎`ก�l๐m%ไ๑Vํ�&ฐ๑ษโรา�ร‹แำnW’1=สธฃ‚๏ธผ€Œ6Z0ฆeํฎpi5rk”ส‘1ร1@b X›ว๐Hส`กV �๕—ู~7—[ฺด‹wีCฟ‹ฐ € € € € € .ฆ‹ื˜t๑ำ สาฐ’ฏ�๎ญฏm•%[โ฿ฮ-p6ฺฆw้๓ี��˜–ผ_�qิ�ถRบ`Vyคeq�ูiWผ๓ะYนtจ/XXฃd™?คชdห’Iๆฎ;!wพน-ุe�ฺ*ฟ7๏ <๕EิŠ‘ทีฯ/Oถ.!UKdทืs.t๐ฤ9™ฟ�„<๚๑ฎ บŸU1Vนlฦ*ฏ :ฆBัlฒ์…’ู”\๖ฯ)i9bซs๙8j+c j%ว`‹ถ7~มด–ึขxฮSUคŽฉlจฯา๋ฝe้ึจ๏S-ว฿SฮŽsช:๗‰0UตJไซฆ"  €I-@ฐ0ฉEน^zHฮ`แฐ0y้•WeฦฬY้‘็C@@@@@ˆƒมย8 1$qฏ((๏�]ึ^ไ่ฉ๓Ryเฺx]ฐh�,’=k&ู}$2^็%dฐ†๗"LKเƒ'"%ฬ„๑Biั€fuฌP4ปh�โƒว#eํ๎pูฒ�LŒำิj„'"L๏ไXwUต<ข�YLrฉRธb๛้Xฮโ0 €  X˜p;ฮฬ˜… –:ตjฺ‡?y๊”,_ฑ2Q๎l/แฒcวฮD_+Qแd@@@@@@ Xrฏ$�M่ฏa5คLกl๖มฦ›ชOฉ˜�žš'B@ุฦ&ฤq@@@@@@@ uฆŽ{บฟ๋5ฆ๒ถTn{yท…oค)šื`่๚ฉ<˜๎y@@ามยt๐y@@@@@@H— ำๅkM�‡Z;ผฆ”ศŸีo"ฏฯ< รพ�็ท @ศธ 3๎ป็ษ@@@@@@@ ด†๖๛Iณณ๓ ฯD^)‹ห“Ÿ๏Nณฯรฤ@@ ้&ฝ)WD@@@@@@’B€`aR(r(อ๋ๆ“๐3ฆ๗ฑYVl?-'"|๋Qฒ@2ฌมย ๛๊yp@@@@@@q‚…!�‚˜ € ^ฆื7หs!€ € € € € € €@Z X˜ึ฿ ๓G@าจมย4๚โ˜6 € € € € € €ค{‚…้�๓€ € €@h , อ๗ยฌ@@@@@@@‚…| € €คŠมยTa็ฆ € € € € € € €@ฌ c%b € €@r,LUฎ‰ € € € € € €$^€`aโ น € €@&S@@@@@@@ X˜ศ�@@ ชมยจ&์A@@@@@@BA€`a(ผๆ€ €d@‚…๐ฅ๓ศ € € € € € € &ฆ‰ืฤ$@@๔'@ฐ0�ฝSž@@@@@@า‡มย๔๑y @@ อ ,LsฏŒ #€ € € € € € €@ X˜A^4‰ €„šมยP{#ฬ@@@@@@๐ ,ไ;@@ Uฆ ;7E@@@@@@b X+@@’C€`arจrM@@@@@@@ ๑ oศ@@ @ฐ0hœ‚ € € € € € €ค€มย@ๆ € €QF5a € € € € € €   Cแ-0@@  ,ฬ€/GF@@@@@@4!@ฐ0Mผ&&‰ €ค?‚…้๏๒D € € € € € € >ฆ๗ศS € €iN€`aš{eL@@@@@@2ˆมย ๒ขyL@@ ิ†ฺa> € € € € € € €€O€`!฿  € €ฉ"@ฐ0Uุน) €ญc@IDAT € € € € € ซ@ฆ3g#/ฤ:Š € €$ฑ@ํz—%๑น € € € € € € €@R,L Eฎ € o‚…๑&ใ@@@@@@@ Eฆ37A@ X(ย6 € € € € € €  Cใ=0 @@ ร ,ฬpฏœF@@@@@@4"@ฐ0ผ(ฆ‰ €ค7‚…้ํ๒< € ๐�์�ผŽ๕ว๑++[ถฬสฎ‘ฝทˆ"’BfJ$ QR**D(2’คศศ�#{‹Œd๏ฝŽq่_ฟ็฿็~ž๓œใLฮ๘��ฏ�y๎=�๗}ฮ+|ฯu!€ € € € €ฤ‚…qๅIr € €@, Xห—‹ € € € € € €๑F€`aผyิ�( € ณฦฌ็มี € € € € € € €ถมB[‚O@@ป*@ฐ๐ฎrs2@@@@@@@ ฬ รLล† € €Q)@ฐ0*59 € € € € € € u ฃฮ’#!€ €„C€`a8ฐุ@@@@@@ธ‹ ๏"6งB@ Xdม € € € € € € “ฦคงมต € €๑H€`a๒็3๛=zL–,[แcE๗Ž๎k=u๚ดฬ_ฐ(บOษ๑@@@@@@  ,ŒลKG@bณมยุ�๔bฦตw๎ะNRคHแ๗bn� ”C‡ศžฝ�ศฦM›�nรย; Œ6XชVฎไl๘โหme๕šตฮ|lœh�บ•๔่ึี\๚อ›๒h‘โพ‘฿‘*•*š�๗�ป_jีmแcE๗Ž๎k=~โคTจR#บOyฯŽ_ขx1ษ™#ปdหšUฎ]ฟ&ืd๏?๛d�ถํrๅ๊ีhฝ. ฎvxต #ฬ่wว;ฝ›พ;ฅHž\:vxU<]W2gสไปฺ™ืภ๑ฟ’ูs็;หขjขIฃ†๒Nnึ๗TJฟ‡ ”๏F‘/ ๑ปž… € € € € €1SเมฌูคFอZ’>CFฏ แB[‚O@ˆ+q%Xh?ใวษผ9ณไฬ้ำ๖">ฃYภ, p‚:ษ“'“ฒVEบtiฝซ~๏ูปWžช�\4_U์9|xร[ฑ็ฮBพRm๋ฌํํQ๏™Fข-#:FT.๔�ย๓n๊3:๘K'ะwโไI๙yาฏ๒ำคษr๖์Ys"ญf˜?>iิ๐i๘L}I˜0กY~๔่1๋gBร(i<ํทŸญ๖ว[ผt™Lš�›ศ—OžiPOส•หY๗๗ฎ�๒๔ณy&@@@@@bฎ@รฦฯKฎ\™ ผt๑ขฌ[ปJชVฏeๆ ฦ�็ใฏฬ7T˜$ฑUyฐVุ+š�็Z•ญ :ฦ๘Gฮ"€ €@8โZฐPo�Vเ-ูธaญฌ^ฝJ��฿pแ aำp ธƒ…K—ญ6ํ;yกV๊๒ี€ฯผฺ%?QขŒ"z๙ฅญ€Qณฯ�y ‚U.ซVตฒ<�' ด�ฏฒzอZณmŽ์ูคVอ๊f๚ึญ�๒รุ๑&4TนRy)Vดจ�บ(๛๖ํ—฿งฯvLณำพh8ฉfช’-๋ƒ’ฦชดvๆฬY9lตo>๓Pงมฅ๒ๅสH�<นๅมณศ้ำgไภƒ2kฮ�`๛iปุ|Pบฝ๑šs5„š=gž��๏?™6}ฆYž?_^)[บ”™พv�บLดยZพCC[ีซW•|y๓ศรึ5\ตBž{๖�#�ท�ๅทmฒ�_ู2%อa๔�ฆN›aน=aฎ]ื;wNv[aฟฦ�่{*g^ฏKŸAฮ์ู%U๊TV€์œ9rT~2UŽŸ8้l็;๑แ๏ษ M›˜ล@+_น†๏&ขU‹=QD๒ๆอ-ฉฌJวŽms&ธไ^ฺ๔ทCพ–๊ีช๘�$00PฦŒ› Ÿ ๘2ุ๚.;HปถญE™ษw่/*�h��งŸ{ฎYb‹ๆอ๒�ฬk�ฎไืฃ[Wi�บ•ณ.๏ฃž@•ฝ b…rา๏ฃ>&เe/sjXฑ็{ฝฝ‚^ฝ฿GZผะิlฆๅfYaF{�ฝ๏‘ฃGฅMปNมBk_~ั_๊ึฉฬ[๗UฃQVะK�:๛ fฯฐ~ซ0งYฅAถ๎=฿s6ำpุง(ujืt–น'ฮZวO>เเtoฐpํบ๕าดI#๗nfZƒ‰mฺu ๐ิg๑๕ภฯฅpกวƒํฃ ิฏซzำ–พ๎ูk๕ �j€ิฉ4ิ๋mุธ™s�6ฏผ$ฏw๎่ดv_‹šถยต_ �ฺฝXึฌ\โT cw_{ฃ›ื๚๗z๖ 3ฺC฿ญ๐ผ›บŸV*ฌYฝš9„พ/MญPก�›~W(_NฒZแูํ;vศ‚‹คeœ&uj9q๒„?~BfMŸbGS™}ปผ๙– ีพำฃ›ผาชฅYฆ_��\3j„”+Sฺูฆฮำฯสu+t;oึt'˜ฉ฿๗“ ๚๙ข�๚๓Rคp!g?wศูYศ € € € € €@ŒOฐP‹<4jj�b��;้๘ปนoฟ$ืฎ]๓ท๊ž/#X  ชB…๖ฅ.ด%๘D@ธ$—ƒ…๖sฺนใ/Yพdฑฮนb/ŠŸ 2'–คMาษํใ7ๅฺdOซั{qca Ž5าชŽ็ฉธงืุพ๓๋ฒpั<ŠhฐPซห �U˜n๙ผ2ญ\ญถะ mงw฿๎.ZE๑Nใํw{ษ”฿ง;›นƒzฮB?_*C‡ Wx+ด`aซz�จ‘รไพ๛๎๓sถ EZEฎzงaฝ^�Aƒzอ_j๎}�ป|CkoพีำiŸญ'๐me๋œิ5ก!บVญ�9ี๗�มBืf~'ต๚ [ํกแภฅ ็ZU)S�‹�~๎ุนS<ืิk]dฏี,๔}บำญnฃฃ๛›ฏKป6ฏx฿฿ฬŒ?f‹šฺ#บƒ…๊ทvี2ฆีะgฃ็››เๆห-[H๎]Ÿ^พƒv TC“ต๊60-‘?๛คฏน\;dชUีึK�TB�พiญ���f“๖�+ต๋=cฆต*a’ฤ‰ฬดmgG?ื�นTา>๐€YD[vท ำ € € € € €@์Oฐฐ]วื$น๕๗ู:ฎ_ฟ&ฌNGWฎZฟ๘žFาฆMkŠ(Œ๘๖นz%f�["มย(~7ฃ:Th_�� ^ป๙Ÿ\ท�าH‘4$๒.ฤาฆับ�์•[R่ฝ�ๆON%฿ฝ’=Zฯพ๋๘uูด?@vฝ.—ฏ฿–�/…ฒ฿/ฅsงฐ�17|Whu์“หืฌ/แzŽิษbภรว5ณ) €@ฬˆมB}ืญ฿0Zฑb™l�ผ)f?0^† “ฝ˜Q๎ณ�ปเ๖๙@น:ไx๗Œ๚อ๎,ิ ฯส%๓ฝFZ]L�ถFฆbกฟ`ก‰VฏY#O)lฺ"ป๏ึ_ศอฝ^งต๑ผYำœ�ล‹—ฌŠgSไ๒ๅ+RฆtI)๙dP{Vmษ�โหmอ!๔>fL์u`�cตจี–ญZ!อ��ธyS+โ9Žถฮ!ฝSํMถk๗ูผeซ�พ}[>๛โK† -X8gๆ๏’๛‘‡อu่ Yอ_ฐะดnิฐพาuƒ† “oพก“โdำežำภ—ถถรWบ\‡ถ์ตƒZ๎p–�๖�7รFศพ�๛ฅธuฏญ_~ษณƒ๕ีmd/ิภูป=฿2ณ,Qบ‚๘ิ๖ศjb]?mฦึo^—๒eK;ก4]ฟu�vyฮ ฑ้๐,�fต€>lตeึชvฉญ6อ๎Qช|งzใ'}{Kใ็:ซี`ๆฌ9๒ŸีŠ๚ฅ[xUtฟCQqญ๊ฉฎZๅฒ{ื.ฮ5h@๏๙^’�˜eฦิฎคำ…+ญึว7mmGmW ิๅz�M[ด2๋t>"มB�/ฌ๏ฆ†p5ŒซใปQcไ๓_™kš๖�$ง%ฑY้๓ล๊b๛w�ฝK๊7๔ดศvฟืRธxi็พ฿๛C† ญXzงัฑ}[ฺ้ฅณณ™ถ๙�ค�ฮ< € € € € €ฑG ฌมยคI“Jซเ… โ�m)a‚„RฎR%Yนtฉ�บ}+F,Œยว]กB๛๏Fธฐฮ€�ฒ้`€}JฟŸi’'วฒ&•อ”‡3&๑ปMt/<~!Pž่ตวœฆ\�ไ๒�kนข๛”๗์๘�žบ!ว ๑นdJศ Vf“RxฮaนะKฮJ๏)'ยฒฉื6�, ษ‡3ล่uf@ˆ/มBฝใs็ฮสŒiSๅฬ้ำAฑpส*�๏ฺ- wZnŸธyฯ๎ฤ,}FสTฌ๊lงAำ๙ณƒชRบฏ7*ฎUƒ…_ "�๛}ไO/[ฟ ูา ฌj0าพ!ะ_ง�.๏ผ฿�^-ฺ‚๛ตŽํ๙ K‡ื�0๓vhOgยฺ ู>PX�M๗ป]ฃN}†ะฟŸ4จ_ฯF฿นQึ; มฺึV+g;ฐ๊N7ZJ–(.7n�วžxา์็{Oํ:v‘EK–šuฺ*ปQCO…B RVซU7X{k๛์ฯบujหภฯ?qยŽฺ6๙™FMƒต๘ถท็@@@@@ f „5X˜>}F๋๏�_17s๖์Y;๚ป˜}c~ฎŽ`ก”ˆ,Šhจ๐’Uไy‹อ)๋ึฌ"ฉRฆ๕๔ั.ฌ�๙ฟฒ�๐ตPฏม^ฉ์zีฯ$ซฅทEษ็†�WฅแเƒๆX�Ÿส ฏUฯ์ธ๑%XจU +บฯช�Œ ุ‚IrJฅ�กฟ?๖N#Ÿ‘�S=ญอ์ea๙�7 €$OBฐ0,Vlƒ pg๘,ผxK6nX+ซVฎŒฑฟit็'ๅู"ฆ… ๕ช�มย;�‡Vแ๋๑ฮ๛ฆ n•มBปช} %Š“‰ใฐgญสƒSE+ฮ…whลลิฉRIบtiฅsวv&,ฉวะj†ลK—7‡g�!T+๊ะ๊je*TuŽบLlm�ผ,๗Y�ำ1า ^นzีL‡%ผRฐฐS๛Wๅ.ฬq๔‹†้4T็฿*•*zฎS—?QขŒ9ทoXอ]Oท๓ vu๏๙žจฑwZืภถเ]ณvฉธจหB๎PขoฅนmืˆRulูบM5mแum‘[ซ†'ฬyล เๅyพพมBwR๐๚kฅs‡vฮฑ๔œ:m†UูฒLž๘ฃณ\+๚Vพ1lฐS)ะ<Œชkฝy3P�ฟuฏ†�ฺด๏์fี‹3j„ฉผจำบ}yซสก�ๅ‡{ธ„Z Tซ‚๊p/Ž`กm๏�6i‚.๔ธ9ฟ]ลPg�ํœ�มย/๚,ฯิ๗ด้ถซIj•ฦ…s�p—๒}๏ƒอ15ˆซ฿7:�ฝ'f…๋Kีส•dศ ฆ]ณฝธ๗G�ไงŸฑg๙D@@@@ˆea ๊mฝัญ‡๙๛f�e๕}�์•ตซWษ๑ใวbอ,ŒขG5๑ท™ขt$IœX๊ีช"้ญผำุธๅ/ูฐeปูฌx‘วฅX‘ ส!ํ๋.ิ0bำ†žช !ํึๅ๎`กถฮ’&‘ณ๋ซu๎�ใ7d๋แฏ �ิ.9ฅLžฐฺœƒ…2ฑเฏหาbฤ!ณE›Š้ไใF™ƒm‚…7�“ข์‘3—=ๅNณงK,}f–rySXม„�dัŽห๒๖/วM[dJqู�Iพ0U�z๐šŒ�๓|0W฿ึy&ฎฺ๎ะW$qB‚…พNฬ#€DL ฎ :$‹ฮ‹๕U ๕้ฦฤPก^WXƒ…ZQฐ๓�ผBSQ,๔ชs_[Xƒ…์`ตLญXพœ|ฬํ„พ๔^�ร,\<–dฯ–อฌึVบ žk๊�4ิ้ศ �•แ๔$v(ห}ย.ฌjv‚ชู5{๑eYฟacฐŠ…vเะ�ทtฉ’2�ชvhwฐ๐๋Ÿ‰V€๓7๔9/Yถ\ฦŽŸเUuOทีJ…Zฑะ ›ผเlใ๋0~ยD๙จ_{ำP?ํp›nค็/Qฆ‚ื๖Zน๑วฑฃœevฐฐแ3๕ๅณO๚:หร2‘๗ั"&ิๆฎ2ัk๕=ŸoฅE{�ขyณDƒv:ด=ฒV๔๎pซถง.Tฌ”ู$บƒ…ฬิ€ฆ๕�ำฑ|ั<ษ’ล๓็GwีษjU+ห๐o<-&�มยฑฃFJู2ฅL๛๏�5วะ/“'Ž7mอuZซกVช^�ดYž๙๛ฏบศ meฌ-C&T๘๕I’$จส�ท#พ—/ญJ‘ @@@@@ุ+ž`แณหCyบ-ูwฌ‘.]บ$+–-–=ปw�‹cไ'มย(z,฿›ไฉaฝša ๊ ๊~.œ23จ"H�–ฯ๋โHwฐp้ปH�,๗;ๆฉKาdุ!ูyฤSู0mŠ„ฒ๓ำ|มถ‹่‚…น้›.สซ?13Yำ&–5X�ธ์๊;y1ะ„o�๖์3ก}ฉ๖hสˆา�oภ์S2`๖iณผvก”2ฆmŽ`�ฐ@ˆ ฤี`แu+Xณbล2ูบySDibิ~15TจH๎๐^`` ,\ผฤุ)Tศ ้‚น๓H็ืป™u๖—จ ถnืQ–-_iฺ|บซส…%XจกยVhษqyฬgฦ,\๛็RงลซVฝ{พ๙K>[‡<๋จ O+d iiXหz๓ฏดj)๏๔rท[ส๚V,๔�ทXั'dา„ฑฮแ�มBuาvดujืtึ๛N่ปะซO_ัถฝ๖pŸำ]�Oื็ฯ—W�ฑฐดฎถ๋j{แ VE?๗๐ญLh }m�๛„4ญแนŒาGษต๚žCซ�5mัส [ฺ๋�๏WHมีแCKต*•์]ฤ~žั,��ทฆŠง�LBลฬ๙�ญงต�ธ>Kฏถ~Y�๊๖†™v �\ถะ2อ 'O’r•ช›๕๚ๅๅ–-ไ�žA-ญ๋=ำHjีฌ๎ด}ึwฌD้ N๕Ogว�OTฎXAพฑ*�ะŸงว�๘“๔�ไ3฿M™G@@@@ˆeแ ๊ญ-VBJ—-็tNr฿๎ฅ‹eฬ่๏%0๐ฆ{qŒ™&XEย, Oศ/ขมBฝ์ˆž3ด[KฐP๗ฟp๕ถ<��nนy๋?sธ๏ๅ–<™“˜J†gฎ�2ห๎OtŸคJšภL๛๛rํๆNตฝ4ษH Žปr�ถ,ูyY:?jvyพT้ีภSq"iโ๛$ฅU•OGH 5`ทf฿9r6P ็H*๙ฌ`คถlหธdUd\ฟ?@N^”'rY๛f}฿หึต๊=๘�งV�๋่5)˜๕~y4kRIb9DdดsDฆmผhv๚bVy๎ษ4~ำ~์๙}ƒgป.52ศปOg๔ป]x๊ฝๅ{—\ท*'๊X฿'hีD €Q%ƒ…{ญ฿*Zด`ž6๑TฒŽ*ซ่8Nาฦ้%A–Drํ—ณr๛„�?ฌฤไPกšธƒ…K—ญฐZนzZ๓jPLF x��Q� ืoุฤซUฎoฐะ_%ฑuซ–ษi<� ถyห6i�ฬำทF๕ช2l๐Wฮc‰Š`กปUซXรƒซึฌ‘m��’‹ึoญตฒ‚N<�ฎ๒j…์R:|Dชึ|สl–/‘ บƒzz.ญdงํ�CC… ณ‡ถศีVนพ๛ฺA4{ปะ‚…๖6ภฌ๛Tyาj;]ธ๐ใฮsฒื๛Vœ3๓wษ�ศรf๕ฬYณฅk๗ž๖ฆๆsฯŽ-ฮผokkg…Ÿ‰ˆ ๋ิช!ƒฟเq๑าe๒วฌ9ฮผ๏„�fฯoGลต๚_็ล�,F},Œขวั_l *[รมไฯฝWเ ๆYEC€ปŽ]—JŸ๎3หา$O ป๚็7ำ�พ4z@–ํ๒์�eณeส๚ ฒbg�฿๖น2hีพู}�บiAผ๋ณ�๒ยทdฅu�v๕@{๛ถ•าIŸg3Kยเ‡ฐ7๑๛9฿j ฝํฐง*ไซ•ำ9กJ฿ป�|L~�[ใ๎u2H๗:Q,�tฦ)4฿SญP�bn“�๗ิฬ#€ )ธ,ผpแ‚,]ผP๔?�cหH�ZI๐@"๙/เถŒ?,\ำC…๊RฐPืihKร[๖๐ =”+—ฬŸ=�^-[ถn“FM=มA]่�:7บƒ…v๕5๛‚4 จAA{ธร[๎Š…๎ •nkทถ๗ำŠyŸ~�‘=+[ำิB‡oxkิcฅ�_:�๊Dn]ฅm๋V:i†�zฑy3๙เฝ p�๐‘฿หภฏฝ[ผ.Y0[ฒeอj๖sW•‹LฐP_๖pเชUญ,~๐ždฮ”ษ^mชjA฿๛tW@ด7^ตl‘dฐช๊ฐƒg๖:�lีฒน<฿ธ‘Yค๗๒� -Mตบˆ }ƒญkึฎ“ญฺธOiฆํ –Wฎ˜–ฟบ0*ฎ๕๒ๅหVP๖E3j„—™†ต…ฐ=†|=Pj[•๚์กa:๛�ัe๚}4gๆTI˜0กูd๓–ญๆธ:cWิ้7oสcEJ่ค3ถoZ๋Uัฯ~ทt฿gๆ๏�์hต ๏ฺฅณ9ž†๖4ผงกพ๏†ใœ#ค ญพ˜-k6I“ฦ๓็ฤ/ต–5๋ึ{m๎�žิ@์รๅr๎๓๗{{Uฤดw๔*�~๔X๙l€๗๗•ฝ=Ÿ € € € € €ฑO ขมB๗+๑คTช\ี,าถศ฿ๆ^cฆ Fัฃˆมยื'•Ik.Awฅผว��-g.{ช.่๑ฐ<ž=i0eญN˜๋อ&„งพ} H๓o:Aล`;X rXี๒ึYU๓tธƒ…Es&“Cgoศ้�Ÿำlเ๓Eƒ‹/”yภgฉH›Q‡eๆ–Kม–ป$ณ*%�ิ!‡”ษ”ึ๕e๛�#๛N�]�ไ#ษœค{_{บๆใ)e�ซQ฿F๘?ซ˜`ฑ๖ศ1ซสขŽIrJฅ��ืi_Cx>ฏ�๐T+ด+Rn�0h;f €Q)‚…ฏฟ๙–l�ดQVZญญเLl&8ุ2ƒ�—4aฐpalชuhมB <อž1E%Jไ<฿Pิ฿�6:A!mm:๐๋ม2๑็ษ’*UJซ้—Rคp!g฿่Ž5Rส–)ๅœฯjฎ�ซญญ�…ฮ�มB฿–บด*7v6ีี`ศืค@�|ฮqตUฒถLึแ�าฑ/ฝาV4Œg‚…พU!ฏZมท7{๔”…‹–˜]?�๔cyถมำ๖aL‹]ญ*ง#ขมBm<๘ห/œc�๘ำฯ๒แวŸ:๓ี{ึ๑Ÿ๕สEŸ,kย๎ค†‹—*ฌ…ญo;_ญ ๘j‡ืฬฑJ=YBF~๛$Ožฬฬ_พrล[g",ิ}��๔บฺwz]–,[ฎซLK์Ÿฦ1ฯH็๕นVฏใ๑Œสkี{ำpก๛๛คO฿~2aโ/zฺ`-�๏Wบt้dิˆก๒๘cšm๕หcวห'Ÿy*1�๚๓^฿Cฺšzฤwฃอปฉํฌ5|ฦูO'B ๚{75tน`ฮLS™T+%VญYื<ืฏ~&u๋ิ๖:ถ๚.[ฑRชTช่ต\g&Lœ$}๚~lนพฟ๚๛Ž€€)\ผด๏bFึJฆ๎๖วณ็ฬ“/๙:๚V๘ v@ € € € € €ฤHจ๊1ฺถ๏huaฝOฎZะF ๓�wษ๗€`a=๘,l๐๕ซํฐงยเYฅqIO›ธ~ำOษžJwอห> ›>LyฦๆKาv๔aณผ|�ไ๒๋kนd—U�๏ะ™›ฒๆŸg ษตตช๕้ศ”*‘ฮ้ )บƒ…fฅ๕%ฏีบ๘ีสi%ที’y๏‰๒้ฬSrฮี–๙oซช †ํ1nๅ9้1้ธ=+๓'—g‹ง‘,$– ๛d่ยำ`ตึก-wZีนชฺมB๛z์7ญЁOไL.ง.สฐEgd๛�+๊6๓บ?์\ฟฝOd>ตUqGซ ๒ฌญž`คปขcdŽซ๛๖žzRF,>cSฏH*๙พ5ี #kส� €มโBฐ0Sๆ,r๒DะOฟห˜ฝฤ_ธPฏ8ู‹ๅพd ไฟkท$`�้`ี cส]…,ิk๔ ท�ตcง<ำจฉs๙ณงOqฺฃ: C˜ˆ๎`aฏw฿––-<ม;ฝ ฦ\ณฺธ&๖ }้:wฐP็ฮ�Crๆ๚๏5m�|๙๒I:•ฎvฦัฃวคRu๏ภี_›ืY็Hโlฃ,l�ดน๙ )Xจ�}ั�cyฆพ'์ฆ๓:๔บฏ_ฟ.I“z�ป�^๖BหWD�แ๊ˆhฐะ7ฉวาJrz_๙ฌ๖ืบ�{๗�#u๊74ณ๎๐฿ึm�ๅน็›�›9ŸHœeฝ‰Qตส^เอ@'Pho์nฅ์>ถบUจT%SทืŠ‘“'�h๏*=�y_ฆN›aๆ[ผะิXุ+ีnื๎=Vุ5U๏!ฏ็๎ฎุีืฺฅsyญc{๛2ไฺตkฆzง^‹w`S็๕�า�๋pฯž;'Uk<ๅ„6๛๖้%M›42�…ๅ‹;Xจ�฿้�ิm~๓ฝ”*๙คNІ๘บXaojซUGณgหjฝ#�š6ำs็/Nํ_5ห3eส({ฌwd�‚E2๙ทฉf_ถฌ_์๙๛Vuด๗�ถqื{o/้๓อทzสŒ?f‡ดšๅ € € € € €1H ภฃษi<อ’�ŸDŠ—(iฎ๎๊ีซฒล*Bbm[ทศ•+—อlฮœIƒ็ษแd้’EVg"OG["ืฉ[O2�ฟ ำกƒไื_~ถฃ> Fัใˆoมยฃ็ๅษ>{œถฟฺขXƒm:�กฟฺ!ป� �ุ.‡T,ฅ๓$X-€[Œ8dๆ�TL'7ส์ฌณ'�็ะeuญ๐�(Ÿ๐›๏ ๖�ๅ„'wฮ%๒yZง๙ฎ๛๐ูLาฎŠง๕™}ŽณV(ฑฒีึ๙คิัญvFy๋ฉ ๖jงbก.Hyูิ7ฏ :X5ฟ๘Wถบfuฎž^�ฏ๔๎ํย2ญี!ํผ,u็\ณ๙ล}๋฿M%L่ตl‚ีม่๔ฉSฮฒ˜4Aฐ0ŠžF| ๎:v]š ?$Gฯyฺ�eI“H6[ก:๗จ�Ÿ�}๔บYไ�ู�Yซ��;ฐ€{W oฐะ*่!ปฌj„๎๓ฝ~;!฿-=kปรƒ?ฏ>/o�tฬ,wทX๖�ัŽ+๒ย๐ƒfฑoHา]ฑ0คVห w\–ๆ–•Žjฆ4แ?3/M‡”%_ ถ็“'—ัmฒIFซขcTŒ๗~=!ฃ–yฬž~"•|๗JP๕›จ8>ว@@ภ XhK�๛OwธPฏ&ฆW*ดล6ฎYแ„้–.[aต๎dฏr>?�เ=yกig��โV6จ_O�}ปปคK›ึูๆศัฃ2zฬx)Qฌจ*Zดdฉดุ๋ลlSฌ่2iยXg{ปmฑณภšXทj™๕›kžŠ�ใ'L”๚๕wฏ๖;]่๑วคOฏwฅpกวMๅ?-า๚ƒไ๔ณ$เZ€SU๎ฤษ“Rพฒwe< &~�ao)๙dq' ฉ'ั?คฎXนJ>๘• ๚žXƒ]ญjuOืซ#™��›q|สช๖งี�ญ–ตแใE=ฟ็>ฮ;=บษณฯิ—ดx~SOืi0sฟีพทฟ(ด�๛ฺ๛hีธ7บxž•  jญ�h›ๅS'›๒�:๏ไาึฦ/Yีsๅสฉซก๗บxษ2ษ�๓m‡์nƒ�|ฉ42จyV๛Pๆ3ผมยะZOด„]� |ีjฉ�QCO๕ร�SNศˆ%ž๐œVDิสˆ!ผ=v‰V๑ณ�]WŽ *่lๆ†TีO+;๛ภำBฌpŽค2๏ญ‡�ร;๑ฺGeส๚ f7ปš ๛=๋e”7jUTtฏ ๋ด>ใ‚๏xช๊�nฒชjp” €@t,Œีˆำ๊br๛ใˆ฿a่{ๆศžMดล์žฝ{ร< �จ[ซชTฉ<ฝร‚ฒฯฆ๗ก๗ฃกDปญฝ๎NŸznwp๎N�ปืk๘,]ฺLฐัท2ข{ปจšึ๓eห๚  p;~�!}�nฯทไๅ–-ฬbmี[ช\e฿MBœืjxiH#’C‡„ธ]TญP๛‚ Hย ไภมƒแz๏ๆต๊ป•�บึ๋ืo ๎…dกฯ*_�๎>vM>yJ๔ํ๑๙๓Yคeน j;๖๒ฐ~v๛๙˜L๘๓ผู�้ขฉๅป—ณ…uWถC@ � รMฦ N?ฌ*|hำ1{ฮ<้๒ๆ[แ<›ว <พ�นฃTฏ^ีซลฒ๏๕1๐k9๊฿ลฬ#€ € € € € €€มBˆฮFGศ๏Nื็ผSฐPร„ฺ:ธ๘รษไใ†YDCƒ! mฌญ€uุํตา^ฮ7wšภแƒV%ผM>-”อถVPฎล�ร€ZIP+ ๚Žใๅ‰^žJ€ ิp ฟRฐะ�ณWny$cป›eM†eปฎšiw๑^ �;`ึi0ว“b๖ืZฺฝmhำ็ฎ�’G฿�mต�S‘j…กiฑ@ *F…"ว@ดJ�๊ๅ‹œ๖๏ผ฿[~๒{H›ณ< ิฉ]Srfฯ.Yฒd–ฌช“็ฯ_ƒY• ษšต๋"\•3q+ € € € € €�Q€`แ‰ยถADC~GŸ”eฎ5'ฉXถคdอ’)l'ดถŠ่9C;;Xธ๔]ซš`๏j‚กํ๋ปn๙๎ซา๘›fฑ�yๆ–Kาfิaณฌ๛Sค{ํŒพปIx+F$X๘ย๐ƒฒh‡งjโไฮนคBพ+V�dŸ์>~�\็๚>y$ปฌิS‚…z-น��[ฎ[U"ul๋—W2ฆ ๛โ.Žส/k<ญ–๋K-#[Qญะ€๒@ ฺF-FK@[็~�ัฦ" @๚}๚2� @@@@@@ Œ รuงอ�!ฟ†๕jJ๚takG;๑ท™r๙Š'เ–*e iฺฐ�NeึŸ9{Nฆฬœ็l�ถๅ๓ฮtd&ข2Xจื‘็ญ]r๙๚mSูpW��โnAผ๓ำ|’6Eย`—{7‚…}ฆž”แ‹ฯ˜s๗y6“ดฏ’>ุuุ ์{ธ๏>‘cƒ‚ZGwฐPซ�ผ)ฆBd‹rุ—ใ๗ณDŸฝr๘ฌตฑ5ฆvษ)e๒ค๐ป]H O] ”ย๏๏กZaH@,Gˆ‚…ัยสA@@@@@@@H ,Œ4ก็๎€`’$‰ฅ^อ*a Ž8Enhzฬ)Sคfฯ�9Xจกย™๓หแ�ฯsฅก๊`แ;“หหฯ™“ฮ้�ิ�rฟiƒ\8GR™๗ึร~/ฦ,|บhj๙๎ๅlมถ‹l+ไ฿ึ]NใšใfJHถ~œ7ุ9tมŒอ—คํhO…ล๔)ส_Ÿไsถ‹๎`แร��–€›�™ถฤ�( I[ษF?ร�^ZW฿ฉตณŸCH๛ฑGไ๗ อชgŠง–แ/7๗ทห@ˆŒมยศ่ฑ/ € € € € € € } ฃศึ„�ๆZaฟ�‡ร.ิVศKWzZ!W*w็Vศพกย$‰ญcญฐ…รrซQ,�‹ท%Ÿ๚ณGฌ๗K“'ำHมlIฅJO‹฿ศ ๕ุ๎ช…:ฏU๋[ำYํ™ทพ&ใ�#}ฆžtะjJ)cฺๆpๆ�Mธฏร^ฏมบu}๒˜ูจ๊บ�|L~ด„กTIศ”ืrI!+x่ั,ิsฐ์zป์�็๗~ฅBZ๙คqg๑โฟฏHณa๙&ฅาศเๆYyะชŒ%๚xย‡๗Y–ต%tฦTT+๔Bb@ ฺF-F@@@@@@"%@ฐ0R|�wŽ๊pแ� ๊�ิฐ_6 07๖gฏ�๒Hฦ$�o2K/_ฟ-y� ช@8�\R๒‘ไกแิฅ@๙dฦ)๙u�งj ถR^๓'Xx๚๒-y���ๆ•๒งI�ท v‡ฺ๋WI/}žอ์ผบMื GEรŠ๎qข๛ค๚c)ๅซ‚_ฒฤV๊ฮgT�tŸ์>v�T1<6จ ฯZฯฌถ\ฮ�ฦN3S4g2™��!ฟ�…ถp๙๎ซาcา1ฏช๎ํณฆM,ƒฌภ`…|มMซ|๖ฏ์ึเใู๏—|Y๎๕2ฯ^นeฺ;‡บ+@ธ ๏:งD@@@@@@ย @ฐ0 H�$ฒแยธ*Tป็†•{ฎฦ๎ต3J๗ง2D””�@@  ,ŒC“[A@@@@@@8%@ฐ0šงoธ0ขงK’8ฑิซUEางKัC�ี�ฎ�๘OŽžป)?,?'ฃ–5็N˜@dฯ็$y’่ซ:xWo’“!€ €@คFŠ@@@@@@@h XmดAŽlธ0ถ… ๕ฮ‹๕�k‚…A ">›IฺUI๏^ฤ4 €ฤc‚…๑๘แs๋ € € € € € € ฃ�ฅวฃแยy‹Wสๅ+Wยuฦ”)RHอ*ๅbMฅB๛ๆŠ๖ฺ#ว.šู๛ฌ…ฏVJ'6ฬlฏๆ@‚…ผ € € € € € € €@ฬ X3ŸKฌฟช…;.หฉ‹’๙ฤR,g2I“�๊ƒฬ@@\ ]L"€ € € € € € €1H€`a z\  € Ÿฦงงอฝ"€ € € € € € €@l X›žืŠ €ฤ!‚…q่ar+ € € € € € € งฦฉวษอ € €ฑG€`a์yV\) € € € € € €ฤ/‚…๑๋ysท € €@Œ Xc‚ € € € € € €x ,๔โ`@@เn ,ผ[าœ@@@@@@Ÿมย๐yฑ5 € €@ ,Œ"Hƒ € € € € € €Dฑมย(ๅp € €a X6'ถB@@@@@@๎ถมยป-ฮ๙@@ŒมB^@@@@@@@ f ,Œ™ฯ…ซB@โผมย8�ˆนA@@@@@@ˆฅ c้ƒใฒ@@ุ.@ฐ0ถ?Aฎ@@@@@@โชมยธ๚dน/@@ † ,ŒแˆหC@@@@@@x+@ฐ0�>zn@ธท ๏ญ?gG@๔[@IDAT@@@@@B X’ ห@@ขU€`aด๒rp@@@@@@@ ย #LวŽ € €‘ X=๖E@@@@@@ขO€`a๔ูrd@@P†‚ร*@@@@@@@เ ,ผ‡๘œ@ˆฯ ใ๓ำ็�@@@@@@@ & ,ŒษO‡kC@โฐมย8�pน5@@@@@@ˆี c๕ใใโ@@ุ+@ฐ0๖>;ฎ@@@@@@โถมยธ�|น;@@ ฦ ,Œฑ† C@@@@@@x.@ฐ0žฟ�> € pฏ�+yฮ‹ € € € € € €„.@ฐ0tึ"€ €D“มยh‚ๅฐ € € € € € € €@$F�@@"&@ฐ0bn์… € € € € € €Dทมย่ๆ๘ € €~๚ea! € € € € € € pฯ�๓Gภ € €๑S€`a�|๎�5 € € € € € €ฤ|‚…1�q… € €@œ X'+7… € € € € € €q@€`axˆ� € ฦฦงฦ5#€ € € € € € €@| Xž2๗ˆ €ฤ@‚…1๐กpI € € € € € € €€%@ฐื@@เž,ผ'์œ@@@@@@ธฃมย;ฑ € €@t,ŒUމ € € € € € €D^€`aไ 9 € €@F]@@@@@@@ป @ฐ๐. s @@เ ƒ›ฐ@@@@@@ˆ  cยSเ@@x(@ฐ0>tn@@@@@@b…มยX๑˜ธH@@ ๎ ,Œ{ฯ”;B@@@@@@ธ!@ฐ0nd๊ดฑ�žธเU+W’,Y2››ทl“;w฿ˆ% € € € € € ขมยiX €  ฃS7~ปs‡v’"E ฟ7{๋V :|D๖์�G6nฺ์w�Y`ฤฐมข-{ผ๘r[Yฝfญ=+?�ถn%=บu5ื~๓f Vn @ˆ๙q!X๘t�geั‚yrๅ๊•˜ฏpว– ’8qข;�™p๚๖๋/kึญฟใถ๑m ุฅL้ gN๙}šhe7๗๙ํฉRฉขณจU๋vฒrีjg>6NŒ5Bส•)m.}�†า์ล—๏๚mdษœI:ถีœ๗ฟ��“ฯ|e�นzืฏ#ถžPƒvีซV1—ฏ!ปฏ์VึฏZ.iาค6หccฐ0O๎Gค]�WคF๕j’"y๒`๗ง ๔�ัเt๏๚™ ก฿"ฑPฯ๛แ๏Iƒ๚๕ผŽ2๐๋!2|ไ๗^ห˜A@@@@โฒภใ… K๕šตๅพ๛๎ v›ทo฿–ู3งห๎�ป‚ญ‹ํ ฦ๖'ศ๕#€ €ฑT . ปv[ฎ_ป&+V,“ญ›7ลา'{/;ฌมBฝCญLืจi ชlนท†�–/ž๏,๐ๅ ๑�hg^'J/&_๔�XRงJ-ซืฎ•N]�๔Zgถm\#I“&5—�๕เก2t๘ศป~ฯ7~N>�๐็ผ ›ผpืชฯ9'ล_~ั_žฎ[ว�มๅห—ฅhษrม๎&6 _l�L�๎�U๎ฟ�~ฏ๛บpแข$ฒยิพAC�ญุI“งศฃ. j๏gฯ–อ๋t†`a0 € € € € €@H‘"ฅดm฿ั >tH:(นzHฬ๊๙;T ๒ต๕๏Q7ใ”มย8๕8น@@ ๖ฤ•`ก-~�๘1™7g–œ9}ฺ^ฤg4 ธƒ…ฺT�s๊Hž<™”ต*าฅK›ึ๋ ๖์�+OีฮkY|ž Kฐ0ฎ๙h[gm๏lzฯ4Š–Jo๖๑C๚$X’Lุ–วๅ`แ[��W[Uั�ฑsง�๘ำ$ัช‹๖H—.~�1i�ๆe)Y"จ•๗ยลKฅ}ง.๖f�ิ`ใปow—D‰�W„%XaZvD@@@@X(Pง๎ำR เฃๆส๗๏�Wฆ�๚‹sญZท•ดiำ™๙อ7ศโE œuqa‚`a\xŠ� €  โZฐPมญภ[ฒqรZYฝz•ฦฑ฿HЉฏ˜;Xธtู iำพ“ืeึชQ]พ๐™Wปไ'J”qZฮพ�า‹’0aณฯ�y ไะแ#^๛WซZY~(—Yถ�ฏฒzอZ3#{6ฉUณบ™พu๋ถ�0vผ<”+—TฎT^Š-*ทnสพ}๛ๅ๗้3‚ำ์t‡/,(5kT•lYดZนฆ‘3gฮสaฺ๋ฆฯ�#ิใ้5”/WF๒ๆษ->˜ENŸ>#”Ysๆ�ฏมำuญm”noผๆ\อโฅหd๖œyr�jฏ:m๚Lณ<พผRถt)3}ํ๚u™8iฒณฝ=กีำชWฏ*๙๒ๆ‘‡ญkธj…<๗์�Gถo�หo�dฝฟฒeJš�๕�ฆN›aน=aฎ]ื;wฮjฐG~๗ฃ}Š`Ÿz]๚ rfฯ.ฉRง’ณgฯษ‘#Gๅื)Sๅ๘‰“มถทh[ืš61ณ'Nž”๒•kุซฬงถ=�@rๆฬ!3fK—.ห๑ใวeั’eฆๅฌืฦฎ�^ฏ+SฆŒr๔่1๙{ืn™ฟpฑumg-๕๘•*”“JหK�:ตๅ#G� {-3m๋ปdูrณ�ูOK๚๔žฟŒุถํฏ`ญผ�Žงฌgm?3�น†๕๊ื?X่ๆ๗_–ว-hฎ|๓–mาธY 3ญao 4ำ๚e๐7฿J็Žํœ?8ฺ+ฎ^ w{๕1A{ู>5TTฝZฟ›iปำ1ใ&ศgพ ถพK็าฎmkIbน|ว›7ๅG+P๔้็žkึ๐ำขyณ|7๓šท+๙๕่ึUฺถnๅฌห๛hgZ'4จี๏ฃ>ขี� +๖|ฏทWธฎ๗๛๏ˆ†ัth่n–fด็�ว8r๔จดiืI๖�ณฯฝXดZ]�:ต‚y๋Fj4jฬ8ัถฮ�ฦ‚ู3$Wฎœf•๑บ๗|ฯูLCl]:udษ’9ห�๚�่๛ใ;ดบ�๋ฏu”$I’๘ฎm]�๗“�2mฦf]๓fMคOฏ s๚๎ มน'หT4‹ืฌ\โT�œc__{ฃ›ืๆ๏๕์!ญZ6w–นŸอ๔)ฟ8มปVธ๑Š๕—&๕Z ฏ]ว.ก†1}๗๑฿ณc‹ณhศฐแข฿2๕jะ�ํwอโาฅJส๘พs6ูธiณ<฿<(Dจ+๔�5b˜ณ>/5ฎSปฆณฬwย]ฑฯ,ิjฆ<�๓�์�o้ฒเกd]‘w;ฒ?V.]`?3šหsฟoิ,^ฌจiแฝv�z>ี๐h‚๛˜ e+d9ฬ๚ห,๚sงV�๚ๆ™�6i‚.๔ธYฎ_jิฉ/๛pๆubำฺ•’2eJณLรศe*Vu~nžณBกฝz๗•SV%�Iฦ:๛,t(˜@@@@@8.(Qb๋๏็฿4w้|้•ถข�ใซŸนgM‘‡FM›Kข„ ฝ–ปgพ�f\ณ ฤฤAฐ0&>ฎ @ˆq9Xh?พ;�’ๅK4ิsล^'>dN,ษšค—['nศต_‚ชฑ�ํ› Kฐp์จ‘Vuญ�ฅUภ",ิ@โนำ=kPฌrตฺN•ฤะถืึฃZ‰ํNใํw{ษ”฿ง;›นƒzฮB?_*C‡”จ V(WVFๆTW๓sJณHซ&Vฏ๓ดณ:ฌืซ;hˆช๙Kญรฝฏ:�ญc๕พ๗�ๆ[=๖ูujีA_~qว{๑ #v๏ฺล: aขc—ฎฆ2�ฝ†pIฮโรGŽH•O9๓แp ๏ด๏ฬYณฅk๗žfณKๆKๆLž@ชBK”ฎเ๕}ขL๕ฒ‡ Ÿฑช๓E$Xh#คO฿ \D฿ํศ�lะwp๐Wฬ%n�ฒี 2{~ธ�>�ื๐เ!SUS็'�6ล 0(�๛}$ฯYี6uุ๏ฟ†‚5l �Ž๘~ด=+zŸฃฟ๛ึ™�ๅื)๒�J฿>ฝ$[ถฌV๔=�ีŠข &&@@@@@  dy0ซ4k๎๙๛ฺใวŽสฤ ใอ�-VB*Wญfฆo�ผi:๘่ฬwร‡ษๅห—ฬr�าฎใk’�๊โฃใ๚๕krม๚…๎ซW%Uช4V ๅดฆˆยˆoฟ‘ซWbๆฟ%,4.๚ฟœฑZsอ_ฒR.]฿‹*e ฉQนœคO—6๚/’3 € €wQ > •๓บ๕F+V,“ญ›7�E�่;• ถฬ(๗%M ทฯ฿’ซCŽE฿ษ๎pไ; ๕ทฤVZแฅD‰9Gช๓๔ณฆ^T ต�๎๊5kไ‰"…M[d็„ึ„๒q/๓ึVบ๓fMs‚m/^2กหึŸส”.)%Ÿ,แ์ข-™_|นญ™ื๛˜1uฒื=jฅณ={๖š๖ยE rŽฉ• +โ9Žถฮ!ฝิฌ๎๙CฏL�j ้๖ํ�๒ู_šWh ็ฬ�]r?๒ฐs]�์๛ื ฯ-ด�0œZ5l`ต๐ดวี  &฿|;ยl๋/Xจ•๓๖�ป_ส•-#ixภ9ฆNTจRรฉจท๖ฯฅฮz�ํฝo†}๛๗Kq+๘ิ๚ๅ Šwn#๛`/ทl!๏๖|หฬ๚ู†,ีชTฒ75-Ÿี1{ึฌ๒Zง๖ึ=ฅ2๋ด๒ŸถำึกUฬ™้�ง๚Ž�“œ9{F ไห'ฺขึvธR�ฟ`ตึvพ…ฬ^-ห–ฏ”cVหๅำV� €๊ˆชŠ…๖Iดี๒ซ2 ถHึЁ๎๑แวŸส?�์^ๆiมยUซืสมC‡L•=}Gํq๋ึ-ัj˜Z…ฒืปoKห/ุซL;cm‹m…–ญถคึก•๓J–ญdฺ๖๊๗CๅJœPขฎŸ4๙7�u6:-ก� uถจะ6ำ๚๓@�!'N๔sแเกรRญVPEวˆพ��‚…a�ู0�๚ิjU+๋ฅJ๋vอ;แ~gอ ?_์`ก๛gš>K}ฆพ?ืญ฿(/ด|ู9Š๏๗bณ_–๕–ก๏ X่+ย< € € € €ฤว/"5kื6ทป�>™๚ซ�›Lb้ะน‹๙๛ๆณึฟ ่ฟ>˜5›ูfฺ”฿d฿พฝf:iาคึvฏ›i โ�m)a‚„RฎR%Yนtฉ�บ}หlำพ,ผ ODC…3็-–7nF่lI’$–z5ซ.Œ;!€ €@Lˆ/มB๕?w๎ฌฬ˜6UฮXํ$c๓p‡ �ปv[ฦ’�'"๖฿ธQแเ=zL}ใi›ชPำJ\ๅส–๖jkk‡ป๔�๎Žฮ‡งฒoxH��VชVหฉถ๖ม{=ๅลๆอ๔ฐfŒ๘n” ๘jฐ=๋๗3…๕�j๖~฿i๏ซ•ร4gwu7mKZถข'๘‘ตOณ็�›ษ„‰“คO฿Oœyญ<ึดI#gพKื๎2{๎|3ฏมธๅ‹=ำบภทš™. )X่�๒u็฿ปค~ร ๊rฅฌ ไ8ซีm‚ ๔0r๖�9)Uฎฒ™๖ 3๙V%œ๒หO^กปVญ�ษสUซอพ[7ฌvž้†›คi‹Vfน~ั๊lน๑„ุ๖�๓|?:จuซฎืถบฺ�V‡ป"œฮO�ƒ”(^L'M;ๅ‚…‹›i�Rตr%ฉYรใ}�๚u้�Q?ณฮ๗9kซ้ัVf{hปluฒ‡�†[็Ÿo�œ|�แ๖*iุไูถ�/g^'ข2X่�๎๗.คS๛W๓๙>?gE&|ƒ…ฺ\["�cฬจขญ|ํa‡�4d9ํท 0ใlซ%v—7=มO ฺฮŸT•ำฯูวpW๑ป|๙ฒ-้yฎ๖z�๔ บร“ธ[aฝ๛vธPƒฆ๖3ฬป™Ÿ ณงO‘�กD พiฮฦŽ๒ช y่๐๙}๚ ๙sีฟ�t?m!ซV{t~ฝ›ี�เฒ=kBŒฏดj้ฬ๗�ไ3 ำw3XจUkXญจ๕ž�CCฅ๚่ธt้’+ๅyV;ด“*•+บ7๕š^ดxฉiฉm/t ๕UkzทUึ๏ตYVh๎พ๛<๏ ;ไ่ฎ จ�V่MGปถญE�L�ฃ…ี{ี�แ ๊๗FแโAแF=Ž๏3/UพŠi๛™w�7XžŸ VฏิฉS™wนEซ6ๆVwm฿ไ„sํ*†บB�kุO‡;Xธp๎’3GvัVษีj{*f6iิP๚}ิ�lซ_์เพญมG�0V๚[•J� ‚…�TX† € € € €๑A b•ชRผ๘“ๆVw�ต]v๎�! y -lุฐN–-^$๕Ÿi(น๓ไ5��นbนฌY�งC๓Fทๆ๏วตซฮพ๖สฺีซไ๘๑{ื ฬนฐ0N, #TD6๓ &IlUฌ๖สƒf�นVฅร›7อ้ Fไ)ฐ €ฤTธ,๒{๗&L#€ € € € €qR ืC; 5˜0aBั๊ƒ?+'Ož0๗��ลV’)ณ็฿ฅฦฌ่ˆ†K—-็�ป‘๊าล‹2f๔๗ึฟm�t/Ž1ำ ฃแQDUจะพ4ย…ถŸ € —โbฐpฏ๕[E‹ฬณฺฝ^‰๑*i“t’0s ๘ๅŒ�>แ�+19Tจภ๎`กป"Y�|ye๚”_œขฺน~ร&^ญr}ƒ…฿Ž๘^พ4ฤ๋นนƒc๎ `‘ yภ5ำ�อืMจอ^คแมUkึศถmษE๋ทึZตl!<�Yํ๊},฿,๗ื†ึฌแKd‚…๎ žพF๚ฒ�ภฏ3iจะ� ุฎˆๆปox‚…๖ ดk�ง๊ศ“V�้ย…๐sทีี}�-wgฮš-]ป๗ดๅ๕ฉมล๚Oื•2VีD=nถฌYฝึ๋ŒV…ิ๊3ฆN–๙๓9๋5i�m‚3๏;ฑe๋vว(ผมย๕6ŠV|t฿VำnG๗{q๎�y)Yถ’{W3=fิ)WฦำX�2ค@!O…@ mชkHCซB.[พาYํฟ-ดฺ$ท๏ิยุ�hห๚ี’๛ฤYo{; ฌ‰่ ๚พŸแyท#๓ณa๎ำฬ๗ธถำ.Zฒœน�UหI† ้อ๔œy ค็ปฝคผี~[Cกถง�ณฯ]!๔‹_หศQ?8dujีม_ pๆ_i�A†ไ„hฟ<ิซฝตณแ�'๚Š0 € € € €๑E yŠาฎCgฏ��๕๗™5s†ณ์ี$EŠ”f�ซŸ9ห}'างฯ(…ฌฟฯ�?๖๎>Šjํใ๘C๏ฝw้Eฅจˆ๔&Š tฑ ]ฑaน๘ข UE"EAŠ(**U:R)าKhก'ผ๓ฬ:ร์&›พษ&๙๗sณ3gฺ™๏ู{?/ไฯsส–ฝฏี�=ฐ_ๆ�<วฺ๕ซO‚…q<q*ด†_แย›wไบ๑o-S๚”’:ฅทฃ๑ืxํ–Tz฿U๔๑๛ฒศW/Žฟ‡'ะ“๖\—m‡ƒe๗ษ๋r๕๚m)W T*œN.™ษจ๐ปAฉ็ฺ}ืไใ�ว.�”โyาJ…‚้ๅั2%s:?˜๐ุฝW#€๘ฉ@R ^บtIVญ๘]๔�๑O,-ใซ$evใ_U…�–เ้gร„ �=Tจฮ�‚…zLC4ฆฑฺบ๕ไ…ฮ�ฌ]qV๗าฮฟv์”ึํ]K‡๊พ็านพ~�ีxฉe†ฌVฟ๑ใขAAซอ�แ[นฏREsื,;๊3iา่๎rถึrรึu๗WฎdT๘๛ศฺ•AC>ตะๆ,œ=ƒ…]บฟb.ใฌืXอน|๐›7ๅ�สีฌCๆ็ฎm›$]บtvŸำั,ิ<—ไU“ๅKฺUตRกzลค9ƒ…บltญ๚Mฬชxึฝด*ขแฌๆY=P—๔ีฅ}ญถyหV{d ซjฐฯณ9ƒ…7o†J…สU=O‘-Fีรlูฒš�žฯิNo c๓�ŽMฐะ๙ฟVื3œๆ%}�ปv™�๛:ujq�๏ƒ๓|งว�}๛Eฺุ4x]งAณZฅ๓|็ถ็'ฉX่ิa@@@@’บ€ฎฃ• ต]ฟ"ใฦŒฒ_9eส”ๆ 2)ŒเŽV๓น๛๏Y์=6ชTซ.u๊บVšัe‘'M็q†์,Œรy๐Uจะb|„ ›?,�Ž[ ๗3[ฦ”rฏ:๛์™f-�“|�p)T๎๏็๚ล}อาe๖ซล|�ฤ„ป�กณ7ค็ด“^็%oึิFฐฒ5‚?‰ฉEŒ่˜?ฝcDมB .\0G4hc5 Zก:ํ๛g็V๛‚บ|๎gŸ–™฿ฯ’,Y2หุQ#ค๒}•ฌKลืมยi“ฟ”Gjh-ืญว‡~๒™|=uบnšM�K[�๚9nยW2r๔Xg—น=|ุ`iัผ™��๑๐2้๋i๖พn8ƒtั ฦๆป›`a�ึ-e๐Gš๏ฐqำf้๘ยหๆาศ?กbญฐ๊lบœ๗ษSง์ฐฑuLจ}ฅบ็-๘ี๊ฒ?=ฟวึจ,กNฐะาโ@@@@’ฃ@ปg:HมBฎ‚gžี kืญ'Uซ=hฒ>xPๆฮ™%"ญpุฅ{OฃX 2VB›8.์฿…G้F>>‰`aว4Txๅ๊5๙uษ sO4ฎ'Y2฿-u�ะ|.l๘ษ!ูu<$ผG‡้ำ*y�š็•ž \K3…9!†’–ฃšW๗y<ทผฺ0w˜;%—`กV)ฌ;๔`ธก?O”z•:e#��8ฏ ฝmTโ�ฏ4‚‹‘ตว*e–ฉ]ŠDvว@ˆ–@Rๆอ—_ฮœˆึ{๛ำษแu|:ๅ‘Fฅjoี �ๅ" ๊=รm๏�#Oตnoแ�9RชTI{?ข _ ๛๕}W:u|ึ‚ใ‚ƒCŒฅJำธ…#๕gฐP๗_�ซ-rท‚ทV ปj�9#kึ,zุn'Ož’: ณ๗uใ๏ํ›ํๅPญZฝฎM๛fภะ[ฐPฯ�tุ yช๙“ึeๆงŽ๛๚๕๋’>}zป_๛žํ๔’่rพฺb,๔ B๊ฝ�{P๔ฝสีื๔ธีtI�ฆอ[šป_Ž#๕๊ิ6ท=Cƒึ๙ฮ๊Šฺw๚ฬูท�€ศ—OJก.�ƒฝ6ฯ`ข็uบ์๐ัฃวคˆ19sไ0ฏัผ|คv};ะ๘P๕j2cฺd๛ธnhๅ9�ŽถyฦU9s`�~าพmkทs"ฺ‰(Xัu:?ญฺu0ช��ัi^y ฝžh8>PฎU/ฬ)žห:['„ท ฑ{ฝw/ณโ už~›•$U9ตล4Xจืฦ๔ป›`ก>w›pอœูต\F�ƒๅ�™?jท่R้�_Yฒfษ"๚ึ�€ำง ƒ.๒ฐฑlทจ5ะฉ�ึฯฬ ?๔ผoฆ|ๅ่qmj8WCบ5‚…้p @@@@’บ@แ"EฅMปgฬืิ฿ม�พtฑ์ฺนC๎ญXY6nl.˜>uฒœ?wฮๆ(Z๔iัชต7ŠAฌZน�Xํ็ผyL—Dn๚D3ษ๓฿*LวŽ‘Ÿ~Œ๘๏iํ›ฦ๓มย8Ÿ9๛นzํšyทดiาHณ&๕$WฮปฟH๒๖˜ญ�-�ตห<\ตrEฉR๙^oงฺ�žแB #ถoyทZƒ}b 6œมB]b8ถป^.หไธ!;Žป�ๆ๖.*5JE=ะูฐ–�}U:Nร๎ึŠ|ฃŒ*Šึ�ํŽ ญ†๙�dฮฯ๓ฝ"žกD=xัXVฝz WR}—/๙ีฌZ็vแ;Z�ะน„sDมB {:—Mv�oๆณไƒƒœ]ัฺv ๕ฟ3ฮ�พ9oคมษ�๕3ช้อ�ลูmnk๕AญB่l”kั๊nุyL—จึŠŽiา��๓ชwV^ŒMฐ0ฆ฿ํุ ี5๕ฟณใ%ฦตjc\ต5+–บpตยแƒฦ๗อY)3ผg, O…>@@@@HNOทn#๗�ใพบŒ๓�๗�๓�๚หมยU}KHู�้ย�๏์•Pi;๎˜์9แชl˜#S*ู3ดL˜๓bฺAฐะ%7�e้:ๅ„นS0Gู๘AIัฅ‰ํฬๅP3|xหจ>จํ�๎EคAW… W๗Ÿฅ฿ู+WŒฐจถQ Jป‡ฒ…9น��32a…+1]ญxF๙ๅคปไt˜—ง@ภ็ }Nๅ8ร…z‘ฟW*ด^l๋ฦตv˜nี๊ตฦภฝฌC๖็€�—g�ทต๗WฌZ-]{ผj๏k ฉ๏ป}�ชห8yาXช๕ฉVๅัๅwต-_นJบ๕์mn{†lฌe‹อƒ��ุผ~ตdฯๆ๚�ฏพ๙vฆ|4x˜๓pธ�•*�+�๛๕5—7ี@žVษ;c�Ar�‚฿$8$X^ํู�ผNซ้=Zท‘�=4˜8hภ‡๒`๕ชvROะ?ฎ]ท^>๙lคtปศุั`ฺ+ฦ}ŸlึT๒�๗/ใ๔ูี�ด sฉe งU|ภUฮ฿y]๒๗้งšป-wซมฬรฦฒฬรŒeoWฎ^ใ<�ฌ4ง็ดixชR•ปK@kŸ.Eป`๎,ปJ`ฯ�oศาeห๕ู4|๕ผQ�ฑXฑขV—๙ฉ๏บbๅj�ลณz›vึฌ๑ฐL<ั>OซZCป๓ฟ h๖่ึEชWซโyศฌ$จกฤลK—…9ฆ๖ร† 4ฟ/ฮ๐ž:�ฑaฃŒ7‚a7o s.o�ฝKgiุฐพ๔ฌ่ง฿ ]๖XMฌv้าeYฒ์wใ�1ซ?jฟงใ�9?ฺK๋๛ŽŸ๘•ผ๖j)Sบดžิ๏ัdc๙`gPาzFt>มB]Ž๘สี+า๊ฉRดจซโน~:,� ืมz–sirํ>rดฑ๔ณ{UG๋\�ิ`pฏ๎]ฅd‰’1ฃ+ฌ.ฝzฟižๆ\[—‘�ŸฑDฐณฝุฉฃ๔}๏mณKรŸีฎ&`�๏v\�oร็Ÿ},O4}ฬ๊�dิ˜๑๒ืŽnห”๋ บฌ๕ฑใฎ?3ฺDฐก๏ซ๏m5ฯ�=ด๚=?๕ป:฿Xพร r๖‰L�ญ็i์#€ € € € €IZ y‹–RผdIปBกพฌ�nโŸ=ปe๑ย_รผปV&l�ฎ๑{›Œ๖๏<œ'้฿ง/]ดPŽ>ไ์๖ซm‚…q4ฮ`atB~1 ๊ฐc๚ฬˆ^9*มBฝ�Rะmฉ๘�>นy๋Žyปต๏—”R๙าš• ฯ_sUุK—:…d1–ะ๓ึBn�ฑซํeหRti�kืoหส=Wๅ•oNš—iุญ_ Wลย๔F%พฬFU>m�*jภnใมkr"0T๎+’^สมศ�V-3ฏ‹่‡†์ถ–3—Bๅ�bฦต๙"พ๖ช1V}ฯ๗�q4D�>"ๅ ฆ“ ำKZร!&ญ�ิ2oซซbเฯ”Vีร�๔พ�งŸ�tืปQn้๛džHงี‹พ๙yžV8<๔Yนpฏ 6�ฏ๘[ฎ๓ิ�ภงeร=N@b"@ฐ0&jพปฦ ๊‚งŸ•�งo๚๎a~xg ่�Sฌ˜hˆG—Nศฆaฟ,Y\�X$&cั๗ะ๗ัPขVŒNำgGVฝฬ��ดส[ฮูอ`ฃgeDoืฤฆ_ŸWจ`3ภy* ภ Bz�ฯค ผpAชYื๓”0๛jPุ๐ห›'๙บŽKDีฤW๖๚ฎeJ—’ ฦ;DeN=ƒ…ึ๒ส๚ฒ๗Wฎ$G0–\ ๓๎1้๐ ~<|„ysั"…ผ9ฯาP็ื_ทป4่Wำฯฦีํวp#พฟ�v~�นn9ฅCืUN:%ฉRฅ6*ๆ3•Vuัพ—!€ € € € €DS DฉRRคH19|่ <้ีฉRฆ’’ฦ?�ฯ•;ทdHŸAฮŸ?/ว3>�ณJก๓…:5bฑำ_b *UหัGไAฆšU๑n๏ฉ๋Rgจ๋ฟ4ู2ฆ”ฝรผัฺ~qDV๏u]ฏห์ฮูrIึ๎wํ‡7ลrkีพRๆ!ฯ`แ I�/Žส�ำื�–iึะ฿ศg JหjYรปฅูงแฝทfžฒCŽึ‰H|จDF™ึฅˆ่ปxถฺCสพ€๋ๆฤ{?.+ฯŽ?"๋Œ๑[ีญ๓ปิษ)�Ÿฮ'ฉย�ย:%�ฯฅฦ’ะ;ปชBvญ›ำUzž�็๛S2ใ‹fwŸฆนฅOำศƒ…F๑)๐ฺ๓ ๎�$�yržGฐะSž}@ุ ,Œญ ื#€@dฟฮ›m๒๔ผ…‹–H๏7]๊"ป.ฑ(Xื๏ๆ-X•็ิฏ[GชV}@ž2*‡jำjฟ.\$ฏฟ๕ฎต›,?5lู๙ฅ็ๅก๊ี์*“แA่rับl4 @@@@@ธ XGขษ1X๘ฺท'ๅ‡—LAgฅผ{๛๎“๓W]U —ฝS\*NFYซ{sยำ฿มแๅคร๘ฃvP1ฬFG‘œids�ฐมยŠfc7ไ�ฯ ๏Z .>[#{˜C/O>.ฟ�u%LฟณC+๚}ืฃˆิ(•ษู- �Wžฝ!zผz‰ vHาํค�vWฬ,ำปบ– ๏xL๛4๘Wๅƒ�rสจฒจํ‡^EฅNY๗qzปทsž–พ]\*=›VBิŠˆฺ*ษ ‹฿พว�ๆ €q!@ฐ0.นxะ*sึ,ท—ะฅpuI�ไะKฐะJดๆ%88XZถ}6� ”ึ9ษ้Sฟว ๊ี‘๙๓K�ผyŒ*…% เดฑ๒q9t๘ˆlุธ)9q๐ฎ € € € € €๑(@ฐ0Žฐ“cฐฐล็GŒe‡]วt,(mt-ี;x�Yณ์œ)�แ‘์๒Y๛a”lฟ"]พ>n๖?Z:ฃ�๔j1ูkT�;v�ฆl�7ุพ^Cr]Œj}ฺ๒fI-๗u…฿œ อƒฦาฦาล]๋ๆ’ฦ’ฬN฿กฟœ• Že™�1ช jะjำื]w~ฐvฅvูŒ๒tีl’?{๙๓`ฐ|๑๛9ัฅ€ตiUฟ=F๕ลิŽชƒVฐะบ�๛Mฃbเ�E3สูหก2n๙yู๕_ลA=gIŸโ๖๘ญkb๓ฉห0๗4Bฟํp#ฃr฿ฏื\พณ\๏ฏีง•k•ษh_ชกย^฿œฐ+0ฮzฅ˜�q๛D6@ˆกมยยqDI@—4๔ัๆนV<๔ำ(/iฅ๘๑I‰5X,๏ฝ฿O.^๊วบ @@@@@ไ!@ฐ0Žๆ9น O^ •๊�๗�ก3]ขXƒmฺœก?oห!;—Ažัญˆ4ผ7ณ=หŒ%€;Nfm8Ÿก}OTฮ"“;ถ›Ÿผ+��^;่ ฦy๐t^้V/—�๕F(ฑฎฑฌ๓#$จํญว๒ศ�็ถฯq 5˜ทm`i3€hŸ`l4�๔์8ๆZฮ๘•†นไ�š็uŽึถV‡\พ็ชhิ๑ธภ�๛Dˆ\uหไO'฿v/bVuŒฮMฟ[Q��แ”=๚Y3ฆ’ WCm7ญ(๙๖ใyไอ&w฿=:ฯเ\@ผ ,๔&C? ;R%K˜๎๔.ง|Z�ฏZี*’!ฝ๋€�ฝ็ Œ๒เG๘T.\ผhV•F•ทOs ท~TZ f์ำสŽU>ุo^s_‘๔ฒไํโ๖๕ั�xuฦI™ณๅ’yูญ�aฏ~ฏYyฝqิซ n?,O:bW&ิ;ฆI•BฒfH)ƒnูU ต?WๆTฒศXสYC˜4@โJ€`a\Ir@@@@@@@ nฦ‘ง/B~‘ อฯt #{พ†ะฦt,(OUอๆิฦฝล๛�c†ำ<+�ต๛โจฌฺ๋ชผท๊%คltnืG7X๘HฉŒ2งw1ท{X;Ke•Ÿ๛oYๅ.urสภVฎ`กณ๚฿์W‹IอาญKย|:ซ/n๚ฐ”อๅ ื9ƒ…ฃ๏7ธy๋Žyใณ+ถมB็}ต๊ใพS!2๔—ณข๏hตOฺๅ—N5sXป^?5$Z�{ํ๐`น‚้d�sฅผ# บf_๔�ๆ„œบไZ :GฆTฒ{H3`้๕ฦ@@  ฃลฉ € € € € € € €@< ,Œ#l_„�"š/žYฐPร„Zตฎj๑ 2จe~ัะ ทฆK๋Rภฺฌๅตา^ั7๗˜ถฦส�<–P6ฯ5‚r� j%Aญ(ู่Œฐ���\•5จแภ๐šท`ก3,๘Gฟ’R"Oฺ๐.7๛ฺ~qDV๏ 2ท!ฤ„ :;�ทs2|ัYณ+ผฅฅ็Z�}พ?%3�ธh๎–ษŸN4เฉ=[ะ;R๕ร�rแฺ-๓ะ6๙ๅฅZ‘=๏ร> €แ , O…>@@@@@@@ แฦัฤ4ไw2เŒฌ�c“9Šฺ<(๓็๒ˆb๚ฬˆเ ฎ๊kT4Bg1mZ๑ฎอุ#ๆๅึrศฟ�uE^ž|�์๋๓xn้๓Xž0ทnลย˜ ŸpT–๏vUMœ๕J1ฉUฦ{ลยฺCสพ€๋ๆ8ท๔/%…�[ุ_‚…:ฐbo�#ื*‘ฺv.-yฒ„]–ู<๘฿G�+N฿0๗ๆ๖.*5Jy_‚{า๊@๙ฟŸN›็6ฎ˜Yฆw-โผ� €ฤX€`aŒ้ธ@@@@@@๐ฉมย8โu†�Z6k,นrFญช�ฬูฟศีkฎ€[–ฬ™ค}หfQั๙ภ 2็—%๖น]:ตณทcณ—มBGฉท๗สี๋ทอส†{‡•็ฤ{†–]^ืณลGฐฐ��32aลy๓ั�Ÿฮ+�๋ๅ๒†ฝoฝƒV๔;5๊๎’วพjย›7ลฌูฑfv{<แmT๋@Ž'-ฒ  žS๚ฝr%ฤ(i4o๓`4~่ฒีบ|ตถ2ฦฒีซ๊†4@โB€`a\(r@@@@@@@ ๎ฦ‘ฉ3 ˜6miึธ^”ย…ำfฮ‘š3ZๆL™ไ™V‘ 5T๘ห’rใF๔ฎ‹สซฦuฐ๐ณdสš ๆฃ๕นGžqุ\๙พ"้eษ�ลร’3X๘ไYๅซ …9/ถK!ฯ�|Iz}sาผo�ฌฉeว าažก ถ_‘._ป*,ๆสœJ�Rฦ>ฯืมยโo�#ม7๏˜K^Nาง gญbc4ฮๅฅup‘-ํฌ็8—‚�๊ฅย๒ไ�Yด;�๖ฉฑิ๒g�-ต\ฝxFY๐F๘หN‡{1 €D @ฐ0!€ € € € € € € (@ฐ0Ž๐อฐ฿b#์๗_H0ชแB] yี:ืRศujFพฒgจ0m#ฤุ$j!ฦจผj\ œป)}tภ|tฑ�iD๗ต้XPฺ<˜อ�๖�ฑ้`4��ต„ฒg˜ฯ:7ถมยPฃX_นw]ี๕žฝๅ–พOบ/หฌ|rP.น*๛๕k‘Wz5ธ[ูะืมย–ฃศ‚ฬWฎW>“ฬ์Qิz}ทฯฎSOศ�ญ—อ>Oฏ๏ึ_” +ฅV้Lขใทย‰}ภ็ื�>3งK)[?*-Y3คtปฏ๎<{Cjห&kxQ�ฐถ๙ๅ…GฃVำu?@๐.@ฐะป G@@@@@@@„ X‡๚1 Fuพ๊8โ:Xจ๗ฌ1๐_9dิฌ–สศฏQ^R‡อฑ™ง\พ-eŒะŸีสL'mซg“๒…าKฝr™ฬ๎ุ ๕&ฮช…บฏU›sห3๏:"฿�qQn�บฃ‡D{ป—1ซšฦ_ ืํ’Vc\K}f‘œiไฝ'๒H5ฃj`Jรn๛ั๙๘ื3rเ๔][g๐๏่๙›๒เWจSฏw#ี๏!ใุ๕Pื๛ฅKB๚<ž[šTฬ"Esฅ•ƒgฎห›.หคU็ํF‡@IDATPa&#€ธหจุ˜มKๅD} @่,ŒŽ็"€ € € € € € €๑'@ฐ0Žญ}.ŒPกR๘"X8aลy้?๗Œ-�Xฅฬ2ตK{?ผ ็8ฌใฌ��ฟ”นมBฝQŸ๏Oษ #@Qห’>ฅฬyต˜T2‚‡ฮๆ๋`ก>kขa๗กรฮ๙|ฯํ—jๅ!m๒��+�น&ฯŒ;j๏ท}(›Œ๎Pะ�_เšดsT๎ธฒ…vxiRฅe๏—ฒ๙ำ…w˜>@b$@ฐ0Fl\„ € € € € € €๘\€`กˆใ:\_กBฅh:�ฐl;lช�ัฏค”ศ“6ึBWฏ฿–Ro฿ญ@8�๕b๒`‰Œ�๗์•Pฒเฌ�ด๙’]5P—R�๘+Xx๎๊-ฉุwŸy:e3ษฝย_&ุฎ๋^/—๔:o˜็๊9o|{R4ฌ่lZลฏแฝ™elงBแV้ซ=๔ ์;u�ฌbxjTy็ฅ๖ถ.น\๘๕=ๆ�E3ศย>๗ุวขบฑf_ผ๓ร)ทชฮk ๆH#ฃŒภ`ญ2aM๋}|H๖œญ6ธไํโR2ฏ๛|๊rฯ๏�xJ–๏พๆผฅฝ"…HkฃZไ –๙%[F/%&ํณู@@ z ฃ็ลู € € € € € € €@| ,๔‘t\… ใ3T่# ั๐Zต�ฎ%y5œถwXู(?๊–ฬำแ cษ��ูRKZ#์็ซฆฯฺm„๐.K1—7–_ฮm,์OM—<��฿พืาวฌX8”‰คŠ`เต[ๆ๒ฮฝ‹5wห?k๑ยต�’7[*ฉP0ฝน<ดVlค!€ เ ‚…พPๅž € € € € € € €@์ฦ�ะ๋b.L กBลi5ๆˆฌ�d:๕y,๔y<ทW3 € €@๒ X˜|ๆš7E@@@@@@ฤ%@ฐะว๓ๅ.Œ้ใาฆI#อšิ“\9sฤ๔๑z]ะ;r๒ยM™ฒๆ‚L^h>;•Q๘n�'ๅ$cZ฿UŒื—ไa € +‚…ฑโใb@@@@@@@ภg }F{๗ฦฑ &ถPกพy•˜มยป "žฮ+�๊ๅrvฑ €ษX€`a2ž|^@@@@@@�Z€`a €$^‚…‰w๎9 € € € € € €$m‚…I{~y;@@ภo๚ํิ00@@@@@@Hๆ “๙€ืG@J€`aBษ๓\@@@@@@@ bGŽ�‰๘Ž"€ € ๗ 5Ž๛›rG@@@@@@@X ,Œ5!7@@ˆ‰มย˜จq  € € € € € € เ{–B๖ฝ1O@@G€ฅรAก @@@@@@๐‚…~0 @HŽ “ใฌ๓ฮ € € € € € € &†YbŒ € €@ X˜'•WB@@@@@@$!@ฐ0IL#/ €$>‚…‰oฮ1 € € € € € €$‚…ษcžyK@@ภ๏๚�”0 @@@@@@@ภ Xศ@@ A&;M„Uธ_ส•-cŽ�์นsฒtูrs;SฦŒาขy3๛-Y&๖~L7<๏๛�๗?ฦ๔VI๚บบตkIม‚ฬwต๏�๑๙ฮฒq๓{Ÿ —ภo๓gK้RฅฬM[�”^Jt4];ฟ(oฟ๕บ=๎qพ’‘ฃวฺ๛l € € € € € ”๊ีo(*V2_๑๚๋2iยธ_7W๎�าธISษž=งy�ฑใGไ—y?GxMb>Hฐ01ฯcG@ฑ@R>ู�iYพl‰\ บ–ˆg"๑}๗_Jš4ฉอXตzญผ�ฝW‚ฝL�|yฅg๗ฎๆ๓๏�น#Ÿ i|/‚โd< ใ„1ฮo’ƒ…ฟš,รGŽŽs+nˆ € € € € €€ฟ ไศ‘C:ฝ๘ฒคL™าฺญ[ทd๔ศแแณ@มBาจqษ•;�๑๓็ฯห๔)“�๚’ามยค4›ผ  € ˆ’Bฐ๐>๏ส๕Yปvต์ุพ-้'ก๚Sฐฐ]›V2hภ6lหถฯสฮ]�๛ฑู X=฿]›‚…บ๒ิษ_JฉR%ไ่ัฃาญgoัช˜4@@@@@’บภ‹/w3*fท_ำ[ฐฐAฃ&r_ๅ๛ํ๓œ l#€ € GI%Xhqœ’%‹~“๓็ฮY]|๚X€`!K!๛๘+แํ“Bฐ0ยไ  € € € € €IT ๚ƒหฃต๋ˆฎBu๛ึmI•:•x ถlำNŠปว”ธr๙ฒl�ด^๊7lb๎,Lข_^ @@ a’ZฐP5o…�’ญn’ ึK่อ› œ žQฐฐMซง%[ถฌฆยโ%ห$0๐‚4nิ@zฐบdษ’Y9*+Vฎ–-n๕*ฅ๗(_ฎฌศŸ_n††•�NหถํษยEK์krๆฬ)ujี”:ต•'š>f๗9yŠ8๐ฏ\ธpQVฎ^c๗๋†^ำ๚้Rดhษ“'ท\ป$วŸ?6l” 7นซ;พชXXชd ฉU๓)[ถŒ„„\—›6ษ๊5๋คถ๑.ฃG|jฃใ๓eใๆ-๖พตัจa}ฉPพœ”*Yา๘รvจ๑พๅฏ;eอบ?ฌS์ฯ ๅหห#54๗ฯŸ”น๓ˆ.]ฏn)f8คK—ฮฌ๐ธาXา:00ะพฮsใžbลไัš5คl™า’7o9y๒”�ณwŸ,�}Eธืลล๗ i“FRฉbE)P Ÿ์ูณWึ�ฑAv๏ู#Q jE@��้๗จhัขฦ๗แ‚์�@�XฟA๖๎�๏๙zใตŒJ—*iŒ9ฟœ;w^Ž฿๗฿-–cฦ๗ฬูtš6ilw�๘ำœp—๐Žฮ\[7๓�ž_นrUdน๑฿ปญ�ถ[ง๑‰ € € € € €@ผ คKŸNบuี ๎฿ฟื —ดiำz >ัฌ…ไอ—O–�พTŽ>$™2e–ฎ=z™cŽJฐP—Zฎื ‘,TH2fศh^w�ฦu 4–Q�บeณ๑;ขc๑๚�ัyK!GG‹s@@โL ) -œK—.ษ๏KažรVŸ>ˆ(Xธ๗_๖งฯ๘Nš?๙„dฯ–อ๎ำ �WhSฆ}#C?๙ฬญฟถ2ฐฟไห›ืญ฿ฺ9z์ธผะนซา๊๐L[้฿๏}๋P˜ฯ‹ฦwกzฺvŸ7zห‹/t’ดiาุ}ฮuFเ์…ฮ�œ]> v๋าY^ตงคNฺํY๊›>cฆผ��๕b=่,,Rธ|�ู'r_ฅŠnืZ;+Vญ–7�zื- ๖แ��O:>��b”�ฑุŒWoิ๛•ขs�๗๋ฦอ›2ใ�™n฿wใไ‰ใ์1tๅ5๙}๙J{?&sญฟ�า๓าปWษ!ƒ}/็††O_๊ารูล6 € € € € €๑"๐L‡็$‚ฦ฿ี฿”/F.=Œฟ(X่9จ่ ( ญ�wิฉRy�ฦ�ื฿E„„„ุ๛�ดAฐะŸfƒฑ € €ษH ) ญi�ณ๛oYณr…ฐบfu%‰ฯ”๙าH†ถนไึ้๒ฃ๗๊rพ~ูจ #‡38ง�–�6฿k สบืัฃวคมcอ$:มB ฦฝ�ึ๋ึ-ผ~ฮž;O�{�๛x\W,|๑๙็ค๏ป}์๛Gถแ๔ั |ซ~_lWƒ๔vญV๔kัส$ิsœมB�ืๅRy๙Cด†๎š>ูาจ*yDO5›250Yู๋๛ Yบlน}š3จgwzูpพงžฒvๅRฏแRฯ[x ตไค‰_ˆ�+ฤˆฺ7Fะ๏ฃมร์Sb3^Oc๛ฆŸ�Bพ˜๐ฅูQฐ0ฆsญG/=Cฃรy๓‘>๏yๅzžฯ> € € € € €ฑ(Sถœ<๑d ๓6+Œ „�ทm•^ฦ๏|,์ึ๓Uษh�nE�๕๋!r้โE 2Vืส&9rไ00q�X บๆŸฟK$XhN?@@โ[ 9 ี๔บ๑/Œึฎ]-;ถo‹obŸ<ฯ vส#)าง”�oIะ˜S>yNTn`ก�KฏลKญภ๖ภ�•�BOฮ€“Vฤ{ฅว�Ёฌ฿(s~žg�๒…NฅLiW…:฿3ฯฝ(AAม๒l๛6ๆ’ภ•*�k[—>e,๛zฮ(cฏA.mฟ/๚ล\�XทตZโœŸ็หมƒ‡คB…rาคQCปz ŽตR•‡๔4ณลuฐp�๊ๅ’;w.๋๖rๆ์Ycโ�ๆrฦ๕ฅ‰=ซ:wC~h,ื�าพV„ฟ�ถศ|Ÿ็Ÿ๋h.ol์�ฏฟฬš=ื� /๔ฆK"๋2ัชv ิ—4i๎VO\ธxฉ๔~ร~ิฐ็2รN—Kึฆ•๗ฆ๓œฮ๊ำขฃGtQญXจฟ ะjˆฺ4T8nŒ๛*FฉRฆ’šu๊ศบUซไึํ[‘>7!N X˜๊<@@@’KฐPง๚ย…@Y0oฎœ?w.Qฯผ3Tx'ไถO?+ทO฿LฐwŠNฐ๐นปุห๋6jX_ฦi{๋ถําฎร๓ๆ�[ฏฟ*�ปพlkู๖Y#๖ทนฏกฤ^Žะแใ'šห!๋มvmZษ wซ :ฏณnึฏ๏ปๆฟ>ำ}}ฆ.งkต1Ÿ&5nhํJฃฆอํฐY\ Ÿn๑ค|2t� โต5�]—'ึฆมย _ŒฒChฺg ต‚�– k์๐ฺนs็ฅFํ๚zŠู4lทtแ|kWถ�ตCฺ<๓œน๏,<~โ„ดjืั~nอหไ/วูU o฿พ-Uฌi.ง�ม๛๏ษsžฑ๏ซKWm,#lตฑฃ>3ƒ™ึพ.ฑซก:mžAฝจ~–-\ ลŠตn)Ÿ~๖น|9yŠฝ��๔)RฝZ{฿,๔�~�พb•t๏ี�>ทSวgEฟ Vำ๛๊�ตลtผ}๘๒Lป6ึ-ๅ�™?H�C์��๛I๛ถญํ} mjุั[ฐ06s=๓›)RญชหFซO–ฟฏช�\�~5nิภ�ฟ~�บ|๘ั`๛ € € € € €๘R ๙S-ฅdฉาfฑ„ฦ฿๓Ÿ3 /h๓Uฐ0Wฎ<า้ล—ฬg่๏aฆ}�•น˜~,LLณลX@@$$‚…ทBoษึ?7ษ๚u๋�๖_E๕+ๅoกBwTƒ…bซื่qทW�พeฝhxJ�มC‡ฅษ-ฬmฯŠ…—/_1*๒-”UซืสฦM›อ ›yขวจ =.1ŸŸ'Oฃ‚[fiฺคฑt้�‚}Š.#ฌีตลeฐ๐�ฏHฯ๎]์็ผ�ทŸY9ั๎๐xž๖[มย๛+W’Y3gุงj8r๔ุ๑๖พnL7ฺฎ,่ z �๏รไ‡Yณ�ฎ๕ Z_5^tiaซฝ๒ฺ[r๕๊Ukื วฝ๔B'{เe๚Œ๏ฬ}gP/:฿็wหณ ข�ธB๙๒2o๖�`จ3Xจพ๊lต‰_M–๕6Yป’5kท๑ธx้2ัwาำ๑N7�2ขฦรš๗–ต๊ป}W๕ป�ๅๅ%…๑ฺพœ๔ตy�[ฐ06s�ํดษ๒`uWED}ึฑใ'ไ็๙ Dซn๙sซvั@@@@@ˆW� J๛g;š…��๗€ฬŸ{๗wพ ๊ พ�ึ;ๆ3u%ซƒฦs7mX/ ทXtั FWŒ๓@@โD ฉ ;&ห_’่ซ๊d๛cจPวๅ i๐๏ๅ๎ฝด�lฮ€–.ล๚ม€ปU๚๔gล9gฐP—”7็GI›&๋FŽŸZE๏Ÿฝ{PึT๙uแ"ว‘จU,ิ ฺดzZฺถn)ล๏นGฒeห๊v็Žชำพธ �xˆดx๒ ๛Q=Zฯฎhuพ๘�sา๗�>ึฎ,l๙Ts๙xศ@ป?*ฅ+T6O๓ †๗\ญJจี ญึ๛อทeแข%nKH[ว"๚�ๆ�™๒ัเaๆ)1๙่าหkV,ต1{๎ดปฌŠ…Z๐๏ธ*ู๋#ูฐ„žมย๐ž๋fณชn^ฟZฒgหษ“๎ž5{ฎ๔ํื฿์p๕ข๚=([ฆด�๒๓O๖ uษ๊ƒ†ฺ๛ึฦสe ฅPม‚ๆฎ3X8แ‹ัา ^๋ดH?฿ฟ˜ŒWเ 9:—๖Ž์แ�‚…ฑ™k}f๏WzHท—_’ดiำzยOs~–��฿�๏™ื9€ € € € € €@,ส”)+O4สผรล‹%เิIทป•)[NRฆL)Z`b฿�ฬcฟ๋ปt้’�yึNฆL™ฅkWฑ‹๓็ฯห๔)“ฌCแ~>Pฅš<�HMIŸ>}˜ใW._–ฉ_O2a๚AมB?˜†€ €$Gค,<`�ซขๅห–KŒ^๓๛)M฿6งคส—V‚�jป๕”ีkึษ‚นณค\ู2Vท๔yฯจ†g,เญ�ตc—>rฤ<“ ž.ฌKe[m้ฒๅาณ๗ึฎ�นs๋F๛/œมย��๚J‡gฺู็=VNœp�K ๛ ฑpฺฌโง}1ฏ^7฿จฒYพ\Y�4—ฎ฿ุ}้o๓@8?ผ c3ืึcิฑนQณฦCส}๗UดC˜ึq�t~ฯ�l#€ € € € € W๗Vฌ,{,Zท[ฒ่7๙{ืฮpฏ‰nฐะบIฎ\yคRๅ๛คlู๒f๕Dซ�฿๛e�ฯsฌ]ฟ๚$X่Wำม`@@ไ#”‚…๚/–Vญ๘]๔�๑O,-ใซ$e๖Tr'ไถO?&\่๏กBu๖UฐPQฺฎ™Ÿ๚#gฮœ๒ๆkฏˆญ6o�/ฎ›ัแ,์า�Yนzuชt๋าY๚ผั��<์™:�[{_+j•8ซ9Wqนrืฮ/ส�oฝn=Fฆฯ๘N๙ุ�ื฿�*E‹ถ๛ฌ`ก†+.˜k๗o�ดY:พ๐ฒฝom)\ศ�ผl/ณ์, oy๊ฅ ็ห=ลŠYท ว;~ยX’`ค4jX฿๎ๆนeหŸ[ํ}�ะ๙ษ”1ƒูงืX-ฆAฝ?7ฌ•ฌYณ˜ท –ต๊ป}<ซ::ƒ…/v๊(}฿{�‚Œ7AFo๏๋†~วrๆฬa๖iฐิ๚ฎลtผcG}fVฺดโitๅJ2tะGึadฬ๙บ๕ฤ[ฐ06sm�๗Gfฝ—nW(_�X๊๚]ฉZๅ�5›V–ิ “4@@@@@|%PฒTiyผYsฏทO:ต},44ิ��๕—yr๐ภป฿นำ`ก๓UชU—:u]ฟ๛ะe‘'M็<์7� �f* € ผ’Bฐ๐ต7฿–ํ�ถส:ฃzจQ.1ตˆ‚ƒ๓งw๔Eฐ๐ืyณฅL้Rๆk^บtูX๎ธฝnำŽฆ5–ั#>ต fฯ'๏ฝ�น฿ฆีำ2d`๛ุยEKฬe^ญ`ีซ=ป›หรZ'Œ›๐•h%;m-Œชnƒ|`Wฟ3๛Zต—�{๖˜วใ2XXๅ๛ๅ‡oง™๗ีZ9q๐ะOไป๏4รnร† ”ว7ด๋†,ิํ๋VJฮฎ@�ญ[ทค{ฏื์ฅ ฟ๛fชไฯ—WO•#GŽJรฆOš�žมB�ƒ๙'รGส”้3ฬ็๚่i๖xS๓\�(บŒฒ6ฯ0คโ^่�อ<ฆ?4”๙�s์Š’ฮฐZLƒzฮฅฒ๕��ฺ)ฏพ�ฆœ>#๕๋ึ‘O†’lูฒ๊!ณ9ƒ…•*�+ณ๘VRคHa;u*@:ฝิีฎขจ!ษ‘Ÿ“t้า™วี˜Žืs้bตูทjๅF kŽ๙|ธ[ีวvž]2ู[ฐP“นึPแึM๋ฬ%#๔;v๎’Vํ:่ฆู† �HZ=�ยฺ•�o๔ฑซZฺl € € € € € ฝŒU‹าฆM+๚{็สM�†มBฝG—๎=อ฿%+กM็๚‘ทg&T?มย„’็น € €@2H มยผ๙๒ห™ำ‰v&ร ๊หd่”GRคO้ตšกฟผฐ/‚…ร?b�ฌwผz๕ช�ฝ{K/*”“ดiาX‡ไ��Ÿฬทภ�จz5™1mฒ}L7n� 5ฏm๓LGiPฟฎL;สํธVยK™2ฅ0s๔UลB}ฦŒฉ“ไกซ;'๔ำฑ่<›3Xุ๑ู๖ข!Aซ�1–$ึ%SฅJ)ล๏นGœ�ชo๒”i2์ำๆฉžมB๋zoŸรGŒ’‰“พถฏ\ถะm)� /สัฃวคˆQYั :๊ษAF•ฤGj฿ญ.ำ ^ตชUdๆ7ฎeฎํA:งiา��—‹ึ1gฐP๛๔/œK[‡„„˜KNgฯžM rUtดฎํึณท,_นส�้x๕bฯJ“ทo฿–ซWฏู•ญ็PฎUฯ�ฮ™3ง๔7ช�51–ึส€ZํOƒw7n–๏�Iพšเ*sฏ�oa/;tะi�๒)๓บดmฃฆออm]zxแ‚นvลร>๏ฝ/บฌnTš฿>3ย_๗฿Wษจภ—ฦฌ"wฦ๘C๋ชีkdๆ?น-ๅ�ฒํณvอบ๗ :ศห/ฝ ๙�๛ืtVฟพ๏ณf�ห<[�žมB}‡A๚ษ}•*J† ฬำ._พ"‹—.3‚v�ญห�>uฬบTsต*ุ๏ฌ'จื6ส๘ _ษฦอ[�ฎ‰อ๗@oิฅ๓ ๆ2ห๚ž๚œะะ[ๆี#G•็:ฝG/#X˜!}ธวœห–,–;\มBญLุบ];ใ๏๋3ฺซ๙8ฯฝr๕Š,]ดPŽ>ไ์๖ซm‚…~5 @H> �kฎญpกŽ*1„ ใKOC†…Œ๊}มFฅทรGŽe๊ฃ�h Z๛‚ๅถ € € ,Œุ‡ฃ € € € € € € €@B ,L(yž‹ €$s‚…ษ� ภ๋#€ € € € € € €€฿ ,๔�ฉa` € €@า X˜ด็—ทC@@@@@@ฤ+@ฐ0๑ฮ#G@ตมยD=} @@@@@@’ฐมย$<นผ € เฯ �yv € € € € € €$g‚…ษy๖yw@@ & >F@@@@@@" X‡@@|'@ฐะwถ�@@@@@@ˆมยุ่q- € €@Œฦ˜Ž @@@@@@@Ÿ ,๔)/7G@๐&@ฐะ› � € € € € € € €@ย ,LXžŽ €$[‚…ษv๊yq@@@@@@๐s‚…~>A @Hช “๊ฬ๒^ € € € € € € ุ&๖d� € €@" X˜H'Ža#€ € € € € € €@’ X˜ไง˜D@�S€`กฮ ฃB@@@@@@๒@@H‚… ยฮC@@@@@@@HFJฤ  € €พ X่ U๎‰ € € € € € €ฤ^€`a์ น € €@ ฦK@@@@@@@x Xศ<@@ ฌมยฐ&๔ € € € € € € €� @ฐะf1 € €ษP€`a2œt^@@@@@@…มยD1M @Hz “�œ๒F € € € € € € 4&yไ-@@D'@ฐ0ัMF@@@@@@d"@ฐ0™L4ฏ‰ €๘›มB›ฦƒ € € € € € €ธ๒M@@H‚… ยฮC@@@@@@@HFJฤ  € €พ X่ U๎‰ € € € € € €ฤ^€`a์ น € €@ ฦK@@@@@@@x Xศ<@@ ฌมยฐ&๔ € € € € € € €� @ฐะf1 € €ษP€`a2œt^@@@@@@…มยD1M @Hz “�œ๒F € € € € € € 4&yไ-@@D'@ฐ0ัMF@@@@@@d"@ฐ0™L4ฏ‰ €๘›มB›ฦƒ € € € € € €ธ๒M@@H‚… ยฮC@@@@@@@HFJฤ  € €พ X่ U๎‰ € € € € € €ฤ^€`a์ น € €@ ฦK@@@@@@@x Xศ<@@ ฌมยฐ&๔ € € € € € € €� @ฐะf1 € €ษP€`a2œt^@@@@@@…มยD1M @Hz “�œ๒F € € € € € € 4&yไ-@@D'@ฐ0ัMF@@@@@@d"@ฐ0™L4ฏ‰ €๘›มB›ฦƒ € € € € € €ธ๒M@@H‚… ยฮC@@@@@@@HFJฤ  € €พ X่ U๎‰ € € € € € €ฤ^€`a์ น € €@ ฦK@@@@@@@x Xศ<@@ ฌมยฐ&๔ € € € € € € €� @ฐะf1 € €ษP€`a2œt^@@@@@@…มยD1M @Hz vN[�N--%ต,’P๙&ehดำอธถถqํjใฺ‰ัผ6ZJf'ืฏ[G๒็ฯgพ๕ฮ]‹�G[ฆŒๅห๑cคZี*ฒc็.้ึ๋5 4๙๚G•๎—กƒH‘ย…e๑าฅ๒FŸ๗|�ศxฟฟพcนฒeฬ็ž๗ึญP9v�„์?๐ฏl�ถ=�s�ญsำซ$G๖์ๆฐ~]ธH^๋]sปk็ๅํท^ท‡;nยW2r๔X{฿—ว w'ต"๗WพOJ”ธGŽ�๋ึo4K•,axึ2Oฟ|๙Š่;Gง้�—-[ZJ•(!)9>v์„Yญา Ÿ:๏^ฐฐRล{ รRก|9นx๑ข�ณwŸ|๗�ฮห�ถตชคพ{๙reฅhัขrแยูท�€�a,ญKqGิb:VญZYซ^#ท[ฟะฉƒคNํZ�๚n:Oะ9ำ1ศŸ_n††•/Oหถํ™๓๎<m@@@@@p ฤ6X˜2eJฉื ‘,TH2fศh�๔๚๋x�ผl�ฒู๘�ศ1ฟฅ&X่ทSรภ@@ค-ุƒ…™ณd‘^|YาคMๅ‰Zนb™l๛๓ฯ(ŸŸ'† ิ็ืWHIทWKจLLช›~ั" ๊ G&อoj๗ฅ.=dอบ?Dƒk ฬต๛?ใ;in„ณgหf๗้ฦ#คจมหกŸ�๕า~ โ0ๆFCžํ๏�{d๓–ญข!9m7Œ@๎ฝ๗W๗<-�}ืŸณM-o/mึ{v๋"iำ>(%Šu๖๋”ฝ฿~ทฯ�ว๐'Ÿ 2ม;+๊E๔ฏ้VญYg‚‹9^~I$Hเ\[งbn฿ฉ‹Yฯ—'ทLŸ2มูง ?์? ฿�ฐ_ฒ<Yr็ส้ฑฯ฿`แŸH™Ro:็�a�ว๙าe+$uชTRฐ`yเ�๛}ญ*‚vE_มBํหฉำฟš๐cชT๗9็้BพoXำ>_0�V.Y O[}ถ�สUkฌ็๘ARฆH)๕๋ึ’คI“š]ืฎ_—2oUดฆ‡>nึฃฃฏvฐฐIฃา��Vvไ‚5 sีuœ{ตnู\Z4kโ์�สšnzมขลึ�๐qUฒฆ<“ๅig_๕Z๕ยบฺ9@@@@@โ‰€;X่๋‘uZใe‹ษ‰ฟx์ึ฿4ณfกาvี Ž๎9ปQข„‰$กBฒmำ&นy๋ฆวนมฒBฐ0XF‚~ € €๑L . uศ~8ฝT{ทถ๕EทCT�C๙อื_หฆฎ๙vะ@IDAT๋ผ7ๅzl �๚๋:"dบ`�5ญ$—�ตW<ชด?~BŠ•*g�ฃณbแ_�-…Š–t*เu๋าIjฝ[�฿1ใ&ศ€มรœ๕ฐข#X8r๔8Ÿ=—s{ญdทeรg]ง๋3~ขณฎ  kีkd…+w™๓ฝร—฿์�Vชพ[ว์๓žžz๑าๅึ๔ฤอ>�าฑ}[iX?ไX]๗'Xจฯบw๗WN˜๑๏ฟ/ส�•ช:S๛zWํ;๔ใOR๎สzy๑ฎ�rตดj�ม์ำ/๎้ฆu�žN�๛ืmุ$M฿ป๐ซ]ณ†tํ�QO1m์„I๒ูภ!f่่่ซ .�๛๖rž๛’๕ื‘ตญqะ`ค�ฺตi)M7ดWฅB•ฮ~ญ^๙ž+t๘นUี๒ไฉำฮฑ, € € € € € ฿์`กV+ผt๑ข�ธyS๎KyŸ�g6ฐ�๕kืdค5ฅฑV2ด�ƒ>d�o๖๕อช,˜2qœฝ+ึผ,Œ5CEG@@ธ%W‚…:*… •œนs๛ ‹�-S&M๋ืฏ๙�L}… ํ�cีBwลBปŸaฝ๊ศ}๐แGข!6mั,tWใำkkลฝ™ำ&้ขiZญPซFิข,�๏ฟ�ค`‘ข3ปM›4N^ษ—ื^๕จถมBw5D๛f฿~ฝ�„่t�่ฑ_คค5�ฐถ๙ณgH๖l/šๅซWฏJAkชhป ูh}ูถiญค{่!ณ๊Oฐ0gŽ—e๖Œ)๖้2aา้oU]tทR%‹หsฯ>k6�t๘gYพ๒Kณ์,ฌ� ‰l�พร9ีปโŸพ.^*อ›6’๗[ตpŽำ้๖!มJ�จ•‡ เ์_ตfญดh�Nขณฏืฏ฿$I›{จeรฆ-œpง}c๏�k่rูŠ•ฒi๓Vูนkทˆต็@@@@@n dx์1นl�a�ŸึŒA๎๖ุcห;•*[3g%1›๚๑,_บุ}ˆดi๗) ฟร9zไgูตcปœ={ฦใ˜`^!XฬฃC฿@@8,—‚…I’�#u๊5๐๘ห${่–,Z G~>lฏํซwจPƒ„ฺ JHhI—ƒ-\่oฐP+ ถhำฮ#pมBญnงU๎�อ�ท;,<�๓ฯRฺšnื�4๘ฆ8ปนง๑ฮ`แฬูsฅ[ฯ>๖mฬ๋S'Iž�!ำปƒ…;ถlLcŽั€_™๒ž}ึฃญฟ๊+Zคฐ.๚Uฑฐrลwค_๏ๆx�าผี๛ฒfํzg=ผwฐP฿+น_}�ใp๏ฉ›ํ`แง๗‘wส‡Tภ๔8!Œ•J๙Šี$บ๚๊}๏J‹๖~}ฏ/^0G๎I๒?lุ�๕Uท‡~�QฦŽŸ์-�๛YF@@@@@ฐž!ซผYบฌ9เโฅ‹2~tศ์Z๖<|โ‰ง์U๓zำชxxัช|ธu๓9�ำO๛‚m…`aฐ�A@โ‰@\ ๊e~:‹ผ๕vั;r๘ฐ,Yผภc[0ฎ๘ ŽI, o฿�~wxOง๙]ทaฃ้าKูฒI๚๔;�ณ+ล9ฌ…่ 6hา\6oูๆพผ|�อNั)™ต�ฉ`แท฿}/•ซื๔่GหๆMฅU‹fฮถ˜ ŽŸ8E>เY!pส„ฑ๒ฺซ๙ฬฝ�มย=;ถšj~บc�ƒึ”ลีœ�ู ร}&ฅ�,aV�ฉXXฏN-้�ฑฝ}บxWtv๘Xp ตฺใ๋o๗8๊ๅ—ฒษ�™ำmvฐp๔็รค่…œํ-ุัีW๏๛ฉSตšuiŽ�๛K/&=ปuq๎}๖๒๛ศ;•oOแmo็@@@@@ยhm H˜0ก่๏ช†๊ภ9sห+ฏๅw~oไ>@g>›ุต'g๎l”(V4yูท+™PZL Ÿฮ�”Œ1ฤL ์}๓s็ฯ[�แ�‹ผ’/ฏูๅoฐPv‡ฝฏkฏฏ^ปN�k2-๗9ช|�โ๖กๆ๕ๅ—ฒษ�™ำm๎๐พวfL™(3>๎์๗ต0w�้�ตงวฎ่๎๋๔ษใ%_�<ฮ=ดeษ2ๅ๑ฬi“<ช9:น�U]›YD@@@@@ � hฐฐH1ฯ฿๘ย๘้วCฒ|้b]O=๕ด”ฏPัูv๋ึ-น๕฿’8Q"m3ฆM–฿�๗?g[0-, ฆั / € €@< X;†๕›[ญi‹๏3W฿ดyซ4l๚^จ;๕์ึEjTซโl฿ฐiณ4nึาY/�VY้�ฑฝคฑชLฺํ๔ฏฟสฤษำ$wฮขSลjำJsZqN[ฮ/ห์Sฬฒ~ฉ^ซž|ฝ็g]vo฿,๗งNmถM›1Sz๕ํ๏ฑ฿ืสš•Kœ �ผ‹ไรBฆ ~แ๙็eมœฮดอ๎)'O#๙_}ล\nวฮ]Rซ^#Kืฏ[[>� ูv�๚ ษ๓๊๋r๙ส็˜ษ“K ซา]นฒฅไแ��หธ�ฌ�จ-�VSyฯ}�ีซWๅล!a?ฝภื�ทH๊ิฉฬต�ำ��๙0)๚F!ณzเเA๋ฏ๒nW‹ิz๏:ึลY_x^2eฬ(ฟž9#{พ๙V/Y*ํ฿o-:6ฺ ๊๑:�อ7”‡ญะŸ=Mฑnฟpแ‚Œ›8YฦOผ=vบ�ใ>=ฅR…ทuัLc\ผิ[fู�๒์3Yd้ยนฮตZดn'ซึฌตw›ื�=บJ้7KJชT!๏G{็ฯ?‘‰Sฆษ�๙ ํMฏ๖Uง-ถ฿“:ๅฒปฏiาค‘‹็หƒฆq๎ัณฯว2�‹Yๆ}ีบe3)Qผ˜G…B=Pƒœ“งNๅโ\„@@@@@โฉ@ฆ'ž”roฝ-Iผfฒ9ฎ_ฟ.›ญj„๛พ๛ึ�ไผjeยJUซZE,’;ฟcpvZ ญส‡kพ\)ว9ๆ�Tห ƒj8่  € ฦŸฑŽ O๚๘cL๘๊๐ฯ?›)€cCŸcข๖scโ€+Uฒ˜s้•ซึšะŸณมZpOS}๑โEษ™ฏ€{ท_ห๚,ฯ>๛Œ$IœX[ำkฐ0ฆ›V0ฬ�ิS–แe9|๘ˆ฿–wฒฏOdส$}D�ฑฆK�ๅ๘‰;โำ๎\@@@@@˜ธ฿*P‘)ำ“’๚๛Mลม฿๛]~9vD�๚๋ฏo›(a"ษœ%‹<˜6ญ$KšL~��w9u๒ค๕œU �Dฐะญม2 € €ภ XxวจนA% ีตJ �ดšaฯ>�ๅว2S๙Vx็-)iUึณ�–m_I�Fอ์U^@@@@@@๎€มย;€ฬ-@@B , mยโƒ€V็�บiญคL‘"ยวฝqใ†™บZร…4@@@@@@;'@ฐ๐ฮYs'@@—มB‹ฤ3œ9^–ฑ#‡K๊ิฉย|๒ฟ�พ(�?(s็/ ๓v € € € € € €ฤŒมย˜qๅช € €,Œˆ�ฤqญ\XฅrEษ�๊+’.�Cr๋ึ-I˜0ก�๚ู๋เ Lœ@t@@@@@@โญมยx;๔<8 € pw�]๎Ž € € € € € €„%@ฐ0,ถ#€ €ฤจมยๅๅโ € € € € € € €@คFšŽ@@ข"@ฐ0*zœ‹ € € € € € €ฤœมย˜ณๅส € €แ, ‡] € € € € € € €ภ] Xx๑น5 € Ÿฦ็ั็ู@@@@@@@ ˜๓่ะ7@@  ,Œรƒหฃ!€ € € € € € €@ฌ Xซ‡ฮ#€ €ฑW€`a์;zŽ € € € € € €q[€`a�_ž@Z‚…A;4t @@@@@@โนมยx�เ๑@@ป%@ฐ๐nษs_@@@@@@@ |‚…แ๛ฐ@@ †ฦ,—E@@@@@@ข(@ฐ0Š€œŽ € 9‚…‘sใ,@@@@@@@ ฆฦด0ืG@๐)@ฐะ' @@@@@@@ป.@ฐ๐ฎ@@โงมย๘9๎<5 € € € € € €ฟมยเ#zˆ €ฤI‚…qrXy(@@@@@@ˆ ใภ ๒ € €@l XG>#€ € € € € € €@| XF™gD@‚P€`a ]B@@@@@@,‚…ผ @@๎ŠมยปยฮM@@@@@@@FHฤ € €1!@ฐ0&Tน& € € € € € € u‚…Q7ไ  € €‘ X 4NA@@@@@@๎€มย;€ฬ-@@B , mย@@@@@@@ ร(ะ@@  ,Œ‡ƒฮ##€ € € € € € €@ฌ X+†‰N"€ €qO€`a�Sž@@@@@@โ†มยธ1Ž< € ๋ฦบ!ฃร € € € € € € Oฦ“ๆ1@@` Xl#B@@@@@@@‚…ผ@@๎ŠมยปยฮM@@@@@@@FHฤ € €1!@ฐ0&Tน& € € € € € € u‚…Q7ไ  € €‘ X 4NA@@@@@@๎€มย;€ฬ-@@B , mย@@@@@@@ ร(ะ@@  ,Œ‡ƒฮ##€ € € € € € €@ฌ X+†‰N"€ €qO€`a�Sž@@@@@@โ†มยธ1Ž< € ๋ฦบ!ฃร € € € € € € Oฦ“ๆ1@@` Xl#B@@@@@@@‚…ผ@@๎ŠมยปยฮM@@@@@@@FHฤ € €1!@ฐ0&Tนfฐ คI“&Tืฎ�๛ฏ\พr%ิv6�=๑cGIŠ)e���าง_�ปื‘;xg๛ฝ๏วนณgJาค๗ศื{๖Jฯ^}๎เำ~ซฌY_��z›็ฬ™/ำf|๘E8@@@@@8(@ฐ0*„ €ฤ‚…ฑa”๏ใ=๗�#ลK–’ว3f’ึ�]๙็ŠL™8.๐ ลก3*ผ]^zt๏๊๓‰�๚๋o9qโ„ฬž;W–,]๎๓6�9ov๏ฤ‰[มยRฝfํฝqญwkH๒ไษๅ๐‘#ฒ~�†ฝWX&หำข!ภ ศัcวไํ •ร:4 ํ๛๖~mŽ฿ป๗[ฉSฟa@็�้ƒ .$ร4ท5{Ž๔๋�้๎๗C@@@@@ (ๅฐะ)@@ ๎ ,Œ[cฌU�JผYJ2fzB&L่<�7d๘ะŽณ1H† �L๚|�‰�๖�o1ฺฃส•*Jื.Fxํ;wJ“ฆ๏Exฤœภ ฺแปoฟ�Njืksฮ•|๒ฑ”(Q�1f�x๙|ไ่pŽ๖—�l �7ใH@@@@@‚M€`aฐ�A@โ‰มยธ3ะO>๙”ผ๕NE@ก�tม,ิ๐ำล‹e๐ะแ2o�ปหั�๊๛ๅYพbฅ$J”HางO/๒ฟ&ฅM๋�sุˆ‘2~ยDg…;+ะชEsI™2ฅ�๙ˆฬ7?Fon‡๏๎Vฐ๐ฑ dษข๙ฆBใ•+�Hัโ%ฃmjn๛ูฦ่[ˆ‹#€ € € € € ฃ c”—‹#€ €„%@ฐ0,™ุท=[๖—ฅX‰’ฆใWฏ]•oฟ๙Frๆส-I’$‘`ฺฺ{๖์•๎ฝz›i‰ํmั๕๊.[ถB:wํๆq้้S&I๖์ูฬถ:,•ซV๗ุฯJ�ฐรww+Xุ๕ฃฮRนbƒ�S�ฯFฐ0nพwy*@@@@@๘!@ฐ0~Œ3O‰ €มย ’Hwู่็ž—"EKศ๎]�ๅ๋�ปฬuZดnซ‚…ฺ้kืฎ‰N;eส4นv�zค=ผOŒ(X˜7O?v”9ํ๊ีซ’็•�ฮ%2eฬ$;`ึ็[UWฏY็์ำ=ทAƒบึ’ศจัcECjvk�ฆตผ˜๕น�ฯ๙ไ“าฌicy๙ฅ์๒๘ให_�-?ุ/=z๖–s็ฮ�งDหkŠไษฅQฃRฌศ’.]:Iš4ฉ๑�ใ๗ ๒�พ}2{ฮ<ูฝgO˜๗าJzอ›5•,Yž–Œ?&ษ’%“?�๚KŽ9* -–ลK—…:๗๙็ž“ํ�7�งฯœ%.\๒o•“|y๓ˆ^๏๒•+rเภ�๙(ฃฌ–Oำ&B]๏ะกรœXฯigูj›5wฎไอ[๒ๅหc๕5ฃ��๗E9p่ Lž4Utjkw+[ถดT(_�lJ กไส•ร,_ฟ~Cพ๛๎๖ธ้ฦ-�ถษคษSอ~๗ญpYทN-ษ�TfI“ๆณK๏y๊๔iูjใ๏Tฦ:F๋ืฎ2ถz�าๅ� ๗}่˜ธƒ…cวMชU*Iv๋ฝ—ๆฬ}ถm�สz๏๕q?šว๒ห/ฟ$ukี”งŸฮ,ฌ๑ปy๓ฆ=๖‹์ุฑS ๊qฌฏ}/ผ”=ปdส”IRงN%��๓œ,Œฃฬ3"€ €A(@ฐ0%ปƒ…๖ใ?q\บ[กงoพูkoŠาkDมยฬO=) ็ฯu๎‘=Gngน`2b๘ณฎS$๋Tษ๎V๓�๊๒A๛vfSฯ�}e�‚…ฮ๎S'Kถl/š๕“'Oš@กณ๓�~ทย~o+แฝ9J๋Kฯ D†ีถm฿.อšท๔นปF๕jาบๅ{&๐ๆ๓kcรฦอdื๎�ปK”(&>้oถญXนJ *(ษ“'๓8FW.^"�{๔rถ—/WVz๗๊แฌ� ๛๗๊5k�ซฏฅK•”��๚zl๓^ัฐ^ฏ�}ิ็๚šต๋ค]‡Ž๛4Pจaั๐Zอ:ue฿พย;ฤ์k�ช…4จWื,/[พR:ิ5ฬs"3&vฐPƒฒ��๗Ÿ —z฿ ฌ๗Aณ&ฅQร๚fŠf๏st�ะ?Iำๆ-Lxิ{ฟm๛๔์.้I๏ฝหYื ใˆ‘!A^�^ฐpศภฯคˆีฆแิึmฺ…z๏™|A@@@@@  ,Œƒƒส#!€ €ฑA€`alฅศ๗16 ๕ฉ5 5แ"4xจ\บt)๒ึ™ ซUญ";…T%ิส| u๎]มBฝเ๙๓็e๋W�ๅพ”)ฅXั"’ AsŸมC‡๙ฌŽ็t"€…ๆอšHำฦ!5ˆ๕ตU™๐ฐ5ฝsาคษ$ปrิ)Ÿต’_“ฆ๏…บjž\นd�ธัNฟด’โW;vศ_�e*ๆทช๕�{๏ฝ ํ kจํเมC๒็Ÿสใ7U็ผƒ…ฯXUkืบ๖{ซ\sz มยM[ถศ™_ฯHž<น๊v๚�ลŠฟ้Tว{5_>+คVุ\?aย„ๆ}ก+/^”+ฟ4�ํ/Zัq๕๊ต๖ชy�๙ี'p๙๓‘#๒ํw๛ไ๗฿— <*ฏฟ^ภTๆ๓7Xธeใzs�ญ[ทคbๅชrไ่1{ู+‘;Xh_Gร€๛ฌj•ฯdษ"ZะnUซื”ƒ‡ูซโˆ๊ฦ�สห"yŠR๊อ’ข•ตญ^ฝFฺw�ะ,�_t฿ŠๅKไ๛๏7›ดJแฆอ[ไื3g$�C้LUษ‡าฆƒ…Ÿ*ฏฉชU![ดnใQําพ/ฏ € € € € €ฤU‚…qudy.@@ ศ๙Eฑ{ฑ=Xh?�๙��O๚~�‰lุฐั�๐kXมB BฝYฒ„ผoUกK•๊>s]๏๊qั,<๖ห/Rใ�ฺNศญIฃ†๒^๓ฆๆžŠkู๊�€Ÿหื ๎0ึะa#dยคษ‡้”ลษฌJ‚พชAฮ›3ห ž=mŽืjvํ�wt๚ซต bปถญeเ กขU%�อ;v๔ุ1iื�ภœs๙โeัk‡ีพูฝรTส $X8jฬX3 ต}อY_L—žฮฌz๏ณัW;|งำWืฎืภฝ+ิฒ�&Œcถ_๘ใ)\คxจcด’ขVkŒจiฅBญXจ-ขฑ์˜ุฯฆ๗๐ฎพ8jไpษ�๊ซบหL+8H~๛ํ๗(+นร\Zmืฮ�’๚�ิฆฒŸVด[๏พห�y๓ํU๓]มย์9r{\WW6ฌ]->˜ฦธผร_ก๖sCๆงž”™3ฆIาคICกU่ฦ/ซืฌ ตฏY“ฦาฌicณ}ฬธ๑๒๙ศักŽ oƒ;Xธp๑้�ฃWx‡‡น/ะ`กปโž๛ข[6ฎ—ิฉS‰V์ห™็๗.gู฿E๐ณO่ืป—”-[ฺ^u^5ภนุ ู3.ย*‹ฮ“'Ÿxยœ�ฒu[ูด9คjฅs1ืBTฦฤ~ถ}๛~ฐ*6ึu]UD฿# ็ฯ5�t๊ๆNCBคu๎$U*W๒86ผžผu�๖ๆ—_~IฆNš`–ฟ�๓ิo๒^ ๏|{_xมย%K—หG�บ�‡๒Š € € € € €@ผ Xฏ†›‡E@‚G€`a๐ŒEL๔$ถ Ož<)={๗“]ปwG‹;Xธlู ้�ต›smw˜JงH.^ข”\พrลูQฐะ]ๅญงU๙mพUฮn3ฆN–lู^”[ทnษหน๒ฺ›ื˜๊ล58ึบUKั้{“'๗œ๎Y๗oดยlญฌP›ปตn๙ž4จ2e๐ศQcd๔ุq๎�.ปƒ…zฎ^#2-ะ`แ”ฉำdเเกกnตgืI’$ฑู๎+ิฉ;์๐ฟมB=งD๑ขาจaCy๖™,บ๊ั4`ุธู{aNm์6:�๓ฉXนชว๙�+Q๛ู๖๎�V๊ิo่q้ฐ‚…๎j—Zแr๓–ญ็yฏ�๘ใOฮ๗้ซ๙๒ษ˜ัŸ›Cถ๏�iM_�ž๗แaฎ{ ��๛ขคJuŸs|็บสฒๅ+u@@@@@ˆ/ ใหH๓œ € €@ , ฒ‰ๆ๎ฤถ`แตkืdยฤษึ�O’kืฏGซFxมBฝัย๙sฌ0�Sๆžณ็ฬ“พ๗w๎Ÿ3g™X‚…N็ญํ)kšใโล‹IšpvUญ^S:ไฌWxปผ๔่�ีฌปงวuˆ`มš5zฌUฝolg๘�hฐ0ฌŠvvฐ๐ฯฟ�’‚…‹๚ผ™พ $Xh_่แ‡ำI�๙ฅ\™าขี๚tฺem[ถn“๗Zถถ๓xี้‡ubm]ป๕ลK—y์๗^‰ส˜ุฯHฐฐIฃ†๒^๓ฆฆcวM#Gyw)ฬu๕X๓ๅ ณ?ะฉฝ�มB}Oึoะุ ฦถjUCฆฟt้’Tฉ๖ฎœ:}:ฬ๛ณ@@@@@ธ(@ฐ0.Ž*ฯ„ €ฤ‚…ฑ`ขะลุ,ิ zŸ}6HNž:…'๛ิˆ‚…๎`ำีซWฅd้rฮ”ถ๎`แาeหฅKWฯiY�TŠ)bnŒมBทสš•หๅแ๔›M�ม6๗Tถgฯœ•ฅหบOp๙n �๒‹”วs๚^ ๏iˆO›N�\นjuŸ�ทรwแใ๓Dฏ€๋�้ณ๕ฤ‰Rถ|ฏ#D��~�๕Wyณฬ[กŽ๑�•1ฑŸ-`กVc๐้'ฆZ1ดaใf�] w}็W[$Yฒdr๓ๆMฉTฅš9z,�ใํ๎๏ฟYณ็Hฟ�Ÿš]sgฯt*C๎฿@ชืฌmŸย+ € € € € €๑B€`aผf@>‚…ม7&ัูฃุ,\ฝb™๔๙๘kสี-ั๙่กฎQฐPOp‡˜ๆฬ'}๚…T-tWb;w๖œ/Uฦน�c2ศโ…๓)wƒ!Xจำ�žต๚้žฮู๎๐‚yณๅ้ฬ™อj๛Žd๕๊ต๖.๓บeใzI:•Yk:ใ๒ๅสสฺu๋C]�n ตณอšท”m�ท›~๋—~}zKู2ฅฬบ๗ิืฮAึยฦ๕kLว+W�‘ขลK†z&๗ฑบฌE ธyท"E�!?3›u*๏2oฝใ}ˆŒ=R^ษ—ืl�lภ ™6ใ‹Pว๘ฺู1‰Lฐ0Mš4๒ๅ๒%’4iRำ•-�ศๆญกงCN‘<นไฯ�ชฌ^ณฮฃหใฦŒ’|y๓˜maM‡œ�ีWๅ์นณกรฐ‚…๚^�ย ˆjXQ�ิiำeภ !f™/ € € € € €ฤ‚…๑a”yF@@ แ DกK=๖ธ<๖xF็ y_yU%J$ทn�’�ฟrถŸ(อ›5‘t้า9�†`แผ9ณ$ใใษ†›d“ีืใ'NJ† Jกื_—reo‡"‹ฟYZฮ;๏๔]jTฏ&>h๏l[ฝfญฌ๘r•ฉ�๘ิOHล ๏Hถl/šJvZัฮ�",,Tฐ ๛22|่ ณ~��y้�๗๖”ิืฌJ’VำVบTI้฿ฏฏYึ/—._–!C‡หI๋Y‹YU๗*W ฉ๘฿�™j…?�ู9ึฝ๐ลด)๒โ‹Yอ&‚wู๒•๒วฬ๗ฬฯ?๗yv5ฟฃวŽษาe+ไ€0�็๊ฟ’+GฉPแmy�ฑวฬuพ\ตZ>่ิู}y�น็d๖ฬ้f�…?�ยEŠ{์o%ฒc™`ก๖ฃE๓fาธQำฅ7nศ�y๓อ๔ฮ_�[2fฬ(y๓ไ‘’ึดฺ๖{5A0ๆ3Yž–Y_L—ฤ‰›๓�๘“L>]ดŠc๚๔้ฅ่oHฉ7KŠ๗4หa ๕"ีซU•;v0ืำฯฒญฺศึmท?ฯฬพ € € € € € Gฦัๅฑ@@` X์#X�*Wญa ๐ควห�นณ"<..เOฐPŸw๙’…๒๘�ฮž3O๚~lk๗~kฉSปV„$ม,ิ€WxmมขEาฃgŸ‡Œ1L ไอ็>{ฃN‘มBฝ�ฯ฿fูผƒ…a๏k๊j๗ฑo–,!Ÿ๖๏็�ไ,ฏYปNฺu่่ฌ�มBgƒ…�๙G๊ึo$RtทŸ}"ล‹5›ยช้>�{92cู`ก�{๚”I’={6๏n„ZทวรฝฃY“ฦาคqCI˜0ก{ณวr มB=q๘ฐม&ซหฟ�๖ปTฒฆถพpแ‚ฎา@@@@@ˆำ ใ๔๐๒p € €@๐ , �ฑ‰Lฯ*Uฉ&gฬแฉว�" ๆฮŽ๐ธธt@ูฒฅฅ_๏^ๆ‘ด[๏พ๛|ผชU*I—;™}gฯœ•ฅห:วนรaบ๑ๆอ›๒ํท๛d�ฦาก�๛ๆธNปศŠ•ซœs&Œ-yr็6U_ษ�บณ�^Xน|ฑdx4ƒhผท+Tถ7G้๕�ึญไอลๅ‘G uฟ�พ(ณ็ฬ•แŸ ตฯฝAš5mbฆ voฟ~�†l�ดษ \~*ุUฐ@1ี,?q\6mฺๆดฤyrๅ’ฮ;Jๆงž uฎ๚ :ฬร้ี|๙dฬ่ฯอฑ&M–กรFxœงS//ถ ำ=๔ู>n�ฤ฿ร`@@@@@X*@ฐ0–�F@bปมยุ>‚๔�N <�p:ษš5ซ™*w๗ฎ�‘ ˆ�ฉ>k_3YAำt้าสฟ�^ณฆฃ=๎1ตฏ?�H“&ผ๐�sr��ฉๅิ้_ๅ๐O‡ƒโ™�มยa#Fส๘ อณfห๖‚�jB5ไ“-kึไ!+ไ–2e 9๎ึtำวCM+m฿ฟG๗คย�o›ีYณ็Hฟ�Ÿฺป"๕zงวD฿Gฯ=๛œ�w_ 9w๖ผœ8u2ฬg๕~ >๛�ณV่๓๙ใ๗?ไ็ฃG�>ื๛Zฌ#€ € € € € ฦวQ็™@@  Xƒ@@ `_มย€/r‡Nุ๙ีI–,™\ป~]ส”+Oฐ๎นs@@@@@โ‚มยธ0Š< €  ฦยAฃห ฑ)Xจี “'M&—._–ƒ‡1z € € € € € €€฿ �ฆโ@@@่ Xš\ ๎”@l �)๎ƒ € € € € €qO€`a�Sž@ˆ cล0ัI๐(Tฐ  <ภl�tภ ๙bๆ,ฏ#XE@@@@@bฟมยุ?†< € +ฦสaฃำ € € € € € € ฦƒAๆ@@` XŒฃBŸ@@@@@@@‚…ผ @@๎ŠมยปยฮM@@@@@@@FHฤ € €1!@ฐ0&Tน& € € € € € € u‚…Q7ไ  € €‘ X 4NA@@@@@@๎€มย;€ฬ-@@B , mย@@@@@@@ ร(ะ@@  ,Œ‡ƒฮ##€ € € € € € €@ฌ X+†‰N"€ €qO€`a�Sž@@@@@@โ†มยธ1Ž< € ๋ฦบ!ฃร € € € € € € Oฦ“ๆ1@@` Xl#B@@@@@@@‚…ผ@@๎ŠมยปยฮM@@@@@@@FHฤ € €1!@ฐ0&Tน& € € € € € € u‚…Q7ไ  € €‘ X ดXvJ๊ิฉๅŸ�‘kืฎลฒžว\wณgQ๚๖๎in0~�$Yผt™฿7{�น็dิ็รB้า%)[พBจํw{ร�ู3%iา{d��Cาฉs—ป� บฟŽๅงŸ๔5}š$ฮฏWฎTQjืชaž๓ƒŽ]ไเกCแ>๓๘ฑฃ$EŠ”ึ๛ฟ๔้ื?�c�;S$O.อ›5‘็ž{VาฆM+ &0ปงMŸ)sๆฮsjนvญš’/oyไ‘๔’$Ibณ๏ท๛ค[๗ฯœP'ฐ�่ะพญไฬ‘Cฎ�๛ฏิmะศ๏๓8ะท@ึฌ/H† JฺำสีซWๅฤ๑rเเAน|ๅŠ๏|lีŸฅ/พ˜U%J$gฯณ~6}/.\๐qdไ6UซZE�ญQีœ�ๆ�๖rไ่ฑศ]ˆณ@@@@X,@ฐ0]G@bณมยุ|จผ^ ฟฝ๊ผjะฆf~;cแ‚† ผ๖š้๙๔_>Š…p—๕ฝS๓�ฯูอ[ถF| ๘œ “ฦ“\นr‰์9r#I1ฃ?—/ฝd�แAาPWะ?Dั �ฐแŸ‡๛=�ญk)[บTจk่ฟ7'Mž"Cญ๓ฃฃต{ฟติฉ]ห\ชIำ๗d๛ฮ_6*฿›ตฌ๏้ไึ๗๖แ#Gโ์ฯ�จ๘<ัpB‰โEๅษ'ž”+Vvš๕ณˆ† € € €@| XF™gD@‚P€`aJปTญFMyไั a^e�ึอฒkว๖0๗ว‡Q ๊/_ห–-ํ05kฺDา<๐€,tHbอมยX3TNG๏DฐฐY“ฦาฌicsฯkืฏหพ๏๖ษฑ_~1๋kืฎ3ิ๒๒ห/ษิIฬq��๗Ÿ�t๘g๙มช”x๋ๆM๙๑งรV:4'๙—ถmZK�:Q ๘๙#Fฉ{๒ฟ&#G„O'Lœmมช(u*ŽLฐ0zt๓ฦurฟUั:ผ๖๕žoค~รฯB๗q๚๏ แร†H๎\9�›=–7n�$ญ�o็ฑ-ฒ+ั,Œส๗ฆ�฿~๛ิฎื ฒิ็Eล็n<ุ๔)“Eซ๋ฯฺ—rๆน]เž € € €�q‚…wœœ"€ €จมยธ๕>จ\ต†<๖๘ใๆกดbฬู3ฟสฉำง$ก๕้yฤ >*�ฟฺ&ปw,ŒlลB๏wฬฌ/ฆห ฯ?Gฐะ&ฌ,Œƒไีล@ƒ…ญZ4—”)SสแŸศ�y๓ฝฎๆ{uะ€OคXัขfงNพbๅ*฿zmีj’ZUR��…‹คgฏ>^Gฤ�U‚…แal ็„�4มนทย�ๅอๅ��๓oธีCƒณ๗มำซตซVXก็[ฒu๛vู�ร~๙�?ไ๙gŸ•�ฏฝjถฒ9�๘“ฯdๆฌูฮบ.t๙ฐฃTญRูู๖ๅชีฒ๛๋=๒ป5�๑ำ™Ÿ’2Vร�๛J็บ:วDe`aT๔�;7ถ}v,๔o\9 @@@ n ,Œ[ใษำ € €ฑF€`aฌช;ชำู5i�าL}|๓ฦMY0Žœ:yยใ<Y‡ม�ดข`+ฉUย"š๊42ฯ•Š…�๗#X่-{ึ ฦžฑฒ{hฐะ>/ื้S&9มšW๓ w*P๗u�ดn)๕๋ึ1›>่ิY4lืมย๐G4ถ…sย๖ฦW^=ปห�o•3ฟz๕i฿๑C‡Bซฎ]๓ฅ่ซ�{ฒ�งdึ์9ฮ�˜X XชžืŒmŸ] =ว5@@@๘!@ฐ0~Œ3O‰ €มย ’HwจLน๒๒ฬณฯ™๓wZSeMy[�โ…๓ไษ'žoพู+u4Š๖วp uบส)RH�ผyฬ=/^ผ$‡~<$Sงฮอ[ทFx๏@‚…z฿B_—œ9^’‡าฆ“ไษ“ษ•+�ศ/ว[ำฆ–!C‡หซโOxM๙[ฅJ%yส๒yิช@ฉaั฿~๛Mพ�แซชะ\ูต{ทว้๖~‡~�IชTซแฑฏชu’ล‹›m—�น"-[ฝ๏ฑ?6ฎโใ,<�ฟ฿คxฑ"๒bึฌrฯ=๗ศ‰“'e�‚E2uฺ๔0)t๚�บตjสำOg– 2ศMkฺ�ฃว~‘;vส !Cร<ฯ�ัก�๛๒R๖์’)S&I:•�๓ฯ?r๒ิiYฝfฬ˜1ำ#ิฆี๐ด*žถ6ํ:ศ๚๕์ห˜วว�๚HJ๋ฝฌm�‚~Wฺs.D … ”ฺตjศณฯ<+๗!�ฮฟ6ๅIDAT�—า„Œw๎�%ืฎ]“:ตCฆโm�ขUจเqึฌ/Hำ&ก?3๚Q>9ฺ็fส˜Iบwํ์์ำ1Mœ8ฑY�ฺชยๅn�ฎŸ*ษฌPทถฬึ{เ๛๏7ห'Nœ๓็�g–๕ห๗VEฐมCCฆศu6ฦ’Ÿ๑ฆ2jcM}z๙ส็ษ~8”-]Z๒[Ÿ[™2e4ำฦ๋gึู3gๅ่๑_ฌ€า:S�ั9มkแ๙็ž�ั6}ๆ,๓๙X� <ๅณ>ฏณพ฿๔^แŸฆิ�บuํ"yr็”Œg�\�~�2iาTฉRฉ‚�›,ฉu�A5zฌ๛ณœ&Mัจ�๛ษ'2™๗ยฉSงdฟu�'Ÿ ๕ญaหญ๗ถt้’Œ3šๅ VธฃGŽše๛หธ๑รœJ�>&ขWทษ–m�dาไฉ>Oั)ฝ๓ไฮe๖๕์�OŽŸ8๎q\d?ป�๗tLชTฎ$+ผmฦ๎พ๛๎3Ÿ—�๙—UQ๔g๙๒หUฒ`ัb>ฺ+C „‰ูซๆ๕๊ฟWฅ�<ถ๙Zั๗Oฎ\นฬX^ฟ~C.]บ(‡‘qใ'ศพ}?„:ฅlูาRก|yณฝ๏ว�ๅซBbž<น%หำOห7ฬ็๛P๋g๕๖;Cู ]>์$™ŸzR๔=ณh๑๋ณฏฆdห๖ข$ฝ๗^๙ล๚‹]ปฟญ่n๎ฯญ}ึฯ�๗ƒฏๆ~ž9VีVฯ… ’aƒšห้๛พ๚ป!ŸนบกAฝบาบU ณO�๐C?‡cบนƒ…-Zถฑ�ฝ–�ฏ1‰์๗ฆ�,A‚„ึ๛'‡yD}�|๗็็Œ๗๗ � jg}&h›5wฎไอ[๒ๅหc>‡��๛ข8tP&[ŸC�๏ŸZ5฿•7 4็ญ฿ธQฆ[?�ฝ›๛{๚K+๐9g๎<๏CZฌ๛&~^ฺ็j0ตQฃRฬ๚wqบt้D�8ฺ๊๕๋๒ว๏ไป}๛d๖œyฒ{ฯํŸฟ๎๗ป^#ผŸำgฯž“ฮ]ปูทr^๕อ›5–/ฝ$iJk>�๕฿เ็ฮŸ“�ึ๗ุธ ๅ�น๓ฮ๑, € € € l ƒmD่ € Oฦึj…ษญ_ิiฐiุเฑ๚ม๎dฐ0,( |6ppจ)ฝ$Xh‡�ผฏaฏkจ๐ƒN]B…ํ�=บw•wสฟ% $ฐ7yผjŸsๆyลc›}O๏`กVVำp€^๋ฟ��“กรFศฤษS<ฮm+๚ธƒ…�๕ท ๖๙zๆ#GษุqBํา_๒7jX฿ กy ๆM›ทDาใ๒ๆษ#}ฌชP้I๏}šณฎ๗ิ{�-ฌ`ก�bา„ฑVpๆ sจV๚ฌื ฑฯ๛ฺื ๆืZ๏ึถ๏ท–D‰<ƒD�}๖,,_ฎฌ๔๎ีร๛PkZฮRฝfํP�uƒ๛}เ๓ืF qน‚๖๗—๋Ÿ‹๛๖}/5๋ิ๓น/ุ7๚๛Œ๚ๅสW๔ฐ}ะพิ|ทzธธl๙ส0งL-Qข˜ ๘คฟ9_งค.lo4ํ�Zaฌ๎=z™อ๚�0fิ็V(5‹๗ar้๒e'|ซกฒšu๊zฃชžึ็ฌ๕ุiญh๐ซm๛L่��7c๊dณืร{๕5ญlxว๛ฺงด…๓็š]็ฯŸ—b%K๛:Lถl\o>ำ๔๓ฝDฉ2™จ|vEfLดƒร† 2ใ็ณณึF ‰j…P๏ฆในq๏๊Ÿูsไ๖>�YืP๋ศรญ@`fg›{ACLฌŸ๑�ี๖�!ถ?��ำ็{Aึึoิ$T˜ี}�@–-˜+O=๙ค9ๅ๊ีซrฏ(๔n๚~mาฌน�ี็[นl‰๙๙ฃ็.R�ู็>w๖ฬ้&$ซ��ฺ]฿อš66—๑บงŠoูบญlฺ๒G,๚พ&z๏`o๚<+–.‘$IB*�๘ำaูปwฏ<ž๑qัเ…ป๙ jx vญ�ีต�*Wฦœ^ฐP๏ูฐ�ํะ_™2ฅ๐ู์9!.๛พkึฎ๗�jลงdV๕;mvีS]ึjT'ŽŸะEำt\ๆZียbc๓๗๕ณฤปชš,�๗฿eงUM๕ไ‰SVธ๏’#๗๗™ !ชƒ™Ÿu๚พศ�ิSโv๏๖‘T|็ms-�Lิเฯล‹ฅะ๋ฏหร้v๎แ,ิ๗ม’…๓เ‰Vฎฺฐqฃ๙Œีพj…Dmง=-ฅส„Tดำuญยg‡ืžฐยฝZMQ�‘ฃGลปโๅ‚…‹E?ปฃฺๆฮž้'4lโQูKฏญปโœVrฌ]ฏsKoำ@>ป๔"�็๋ถˆฦDƒิใว†„ค5่ธวชFฌ๚3Vซฝพ๖สซV5ภ๋’๏ตื๕rกZ๎IโDIฬ๖"E ;฿Ÿแ |ฺ_J/fฮั ึฺu๋$‘U-3‹8ตCุ.ิjฯ๎*e�ก2}๏ฎ฿ฐI�ฝ๚ฏนž]vำ–-N•฿œ9sศ๘1ทCเๆฆ|ูฒeซดn��ๅ๊ํฯf๋๚)Sฆดช่uย๋�มๆQ#‡;Ÿ‹:%๑VUOws‡P5ซแร๐ฺซ๙๒IฏIีชUไž$!�Ÿ $ำf|แœๆž*พ�ฅf’ีช๒ซŸู๚‡-๚๏(ญฬ้อ9'Gr!2cขทŠ์๗ฆ:)Rุบ‚˜ชะ•+U4ห๚9ฒbๅ—fู�ขU๕Vฏ^kฏŠฏ`กพWฮ�zฦTYิฯ+mค-f…฿�^[พื��ฑ‚๎ืใ+Tฎj๖kธvมผูฆโซ๎ำ?™0iฒ.FฉEึGoูฯK=ทyณ&าดq#]4ฯ๗ตexุ๚YŸ4i2ษnU๊ฬž=›๙ฺค้{ๆ�ศฯi�wด๗ƒL7ฦ�;Yฏฅl� :nU~๐มๅ•|yอฟกดช๑˜qใ๕ € € €A)@ฐ0(‡…N!€ €q_€`a�ใึm;˜_€jฐ0UชTfู๛้ฎZฟ ื �… ฟ{๏ ช๕;,ิ %ZฉฤnำงLถ~ฑ๙ขYี้่>0ะ�๊5`กtด๚๗tลzQwฐ •5่ฦ›œ{y�WกฌฟXv7 ษUฎRั :ุ๛์jcvลBญRจSjำะM๏>�L(วlˆฅ_"๋ใ,t(4�ทt๑BI›๖AฃRตzM@ะสๅ‹%รฃ!A# Di0สn@š?w– (iˆฆFญ:&Hj๏๏ฺๅCฑƒ งฌFหVm<*=้ฝ;thkMงผหcฺJ๏Š…?Y๕—ๅvีC ฯ5l�ิ#จ`฿3ถผ๊” :Eทถฝ{ฟ•:๕:]ื)MuบHป๙ ฺ๛์ืov๏0กœ๐‚…๖ฑ๖ซ��ฏc๗Rฮ˜ฝ/ผW��ฎ['$ิจ๏ฉ.ร;7ถ์ ๔5 “๕ลฌ2ำ <น4๚ผฌ)fตสจถVPฐZšfู�ล;ฤฆก์vํ?๐๘~ัc._ผ,ZแJ8ซV,u*พi๐iต5�ฒ6�7�๚๙งŸฺผƒ…>๙ุ อ…ฏพ�๓๙พt๗ูๆำig}UxีฉุGŽ™๒zยฤI2t๘็ๆ^ั�ฅaƒ๚าชEssู‹Iž}|จผ^ ฟ้ฑฏคNทžฬชL๛� ซู฿ร��œ�บiƒ๕฿F๗™หUชRM4์๏nฦ>x๐ GศุฝŸe@@@‚A€`a0Œ}@@โกมยธ1่๗Zฟn�ขวรh•ำงNI‚„"ญ้ฦดšก6 N™<9๔ˆฺw2h€ฉฬr�ฤqฺ้ฝ—{—\ฑฆฒ๔�… ว~ฌ)๒† ๘™9าฐOี)็†dV�|D*ZUcยj๖/‰ต"Rฎผžำ‡uŽฏํ ฌŠiญ[†Tgq�๔ฺุตjJ๛ถ!ใซUž4ไๆoณ!ฎ•฿ดข^๊ีฬฉฺ฿.]ปyื�ฝfxวi@$f‡'4Lwoาสo�œฏ!Y;๔Ywไ„Uนฆl๙ ทv�aO๗/เีตrีะSฝ๖ํ�Sส•-cฎ็Bฺผq�Ÿ:ตูงก ๘ำ�มB ,UฏVลชp๘9ีŸภƒ?๗pู1‰์yzo๗๔ˆ: ข†ล�mวถ-ฮTธ๑1X�ศ~oบ� บฯ๕ต�ีึMฆ๚\Xีิ�!6 TซQห#เ๋}อฒeKKฟ�!?3|M?ํฎึ๊,�๛๕NDำ๊{%K—s‚]๖=t๚ž=บ™ีฐย=๎ฯ‚…‘=o�š/อ๘ฒ�พmณฉŒชŸ๓ญ š�Y้๎_d>ป๔แ=ว]‰ํหUซๅƒNusคš?มBNฝC๛ถๆ๚๐uW>ำZ�Tซ�i๓ฎ@้ฑ-Yบ\>๊ึ�gัสqvUc;ุจar{๊`๛ธˆ^ฟ�aฟ3 ณ;X่+h5๎lง*ฆ๗็�:๋} nตฝSฑฒG่6ผ}v�4 ญ฿ื�ํ���'u๋5 ฟป�ื;ฟ’{๎นวู๔็_ษ�๙ ฌ๗b"ษ•3ง๓GZมด๚ปตร�~u.มBdฦฤ๛’๎๗พ?฿›๎๓ํG๙๓sึ,T›‚…‹บ/ๅ๑�ใ๋3Jฟท็[กุ ๙ท”��$cฦŒๆ็ฮž“ทญ1ถฟŸ=.ล•@}ข๒y9yย8ั*Ÿฺ๚๔๋/sๆฮ ธ๗ ํ?2ะ•.[>ิ๛:เp € € €wA€`แ]@็– € €" ใฦป UชิาภชTfท‹�ํL;จ�4ธืุช e‡ ต๒าฉ“'์ร๏๊ซ� [;qๅส?๒J~฿ำ%๚{ wฐpร†ฮt„๎๓ํ_ž๛ บ 4X˜'W.yวชิ๕จU๑็กtษฝ�� z�erโฤ‰อฅตzขVQด[ื:KๅŠ!กท�}?hJีฐ|5˜ฆฟ\ฮฆีว*XฯHำjZซVฏ‘ kWI‚ �>ี=etd}�มย+WIงฮ]<๎๏{๊>=F›;ดข๋:eก6w�uสU{}ั’ฅาญ{OsŒร4๔ฃM+S•(]ึ,๛๓ล,tฏUฃยšBิ}\ ห๚~Œ์˜ุGน_น๒ญi หฮฏถ˜ Xa}Ÿป+yl|�ฯฤ…Š…Q“ศ~oฮœ5�ƒ52มB}ฯkฅษlึ—้าฅณฆ ี๊…u]›e^อ_ะ,ปฟธClZฝชnƒ้3�วธ—�มA_ำZ๊TูZษN›;X่ž2V๗ู฿ำบl'ฒฆzต\พ‚ศzl แœจމ;œำขeง"Ÿ;ุไ€Œสg—>Ÿถ@วDฯั)ษ๛๔ ๙ ิ€่W;vศ–-�ฌฉขฟ๘� บ+๕i•>ญึ็�พฺฒัL5ฌำ!็ฮ๛ชณ�bู๋ปฏฬ_ฐะูง Z‘RวY+�+Y:Tีใ`?W�มB๛ณะ}ช๛๛ฮ๛฿๎�๊Tศ:%ฒ6๗H�`…ตrฎฏฆฏชึt�:•๑ฃV^�ฑ�-ขม�ฦM›{Œ‘�o#ฝึ%๋=ชTญแาrW�[ถ|ฅt�(ค*ฉฏ{๛ปอ�Œ‘“@พ7ฝ๛e�;*ะ`แj๋฿6ํ;~่}9๙vฯ. ึ `๑R!€เ>H๛:bุสใ๚~ซ฿จ‰hbขโีฯห^=ปห�o•3กตvํzูฑkง์�ต�๏Ё —-^เ4๕฿_~นสชพว|ลDP3&ฦˆk"€ € € @ฐ๗ € €ภ] XxWุcไฆ๏ท๏่\w๎ฌ/ไิฉ“ฮบ.”xณด5%e6ณmฯž�ฒyรz�wkล�…ญฟ๗Ž•;Xจ•RดbŠwsW๚ฑซyฃ๋ ‡ $… …ฯx_wะก2yส4g๓ธ1ฃ$_�i๐4l"ปญสƒ�ถฐ|9"๏T ปฃฟืwง•ยดbX mภ !Vฐpตฌ๙rE ง‰ปPd}�มB๕Vwwซ๙nu3•คns‡>๊�IชXA ›;ผ๚๒ห/ษิIฬฉ:}`�†�ฝŒ„,ิ tํึC/]ๆ๗ต":Pง‹์˜ฌXถXด‚W Mง&<}๚W'tฉมฎ’eB‚๎๋hล8ญง-พ ฃ2&‘��œ:mบ›฿T6 dบg�๋฿ฟฏฉJ่q!ฏ๏)^ํ�๎›๗”ต๖1๎ื�?ฒยอo›M�{๔ 5อป;ุ๋บ๏ใพ^Xหพช๊ฑ„sข:&:eธNฎอเfU�-lU�ีึูชJปlูํฯึจ|v™ Z_�V�Œ‰}^Xใ฿~๛]ฆอ˜!“&Oต ๗ีŸ`แเŸJั"Eฬu�ีf�vWG-\ด„t‡ุ|}ฦธฏ]�๚wีนs็�—ิฒ;X่๋฿๕๊ึ–๗[ท2ื7~ข �|คs�ฌ]พt‘ ภ��๛yฃX ณoะ€OคXัjyT…ำะุ'�?6Cฝะn+�ู ัํ?\Yปj…ž6}†|6pฐำ]p�\��๛ไ�ฺu=๖Gf%:ฦ$๏M๏>ฺ�Ž 4X่zบฏนeใzI:• งๆฬใปาuทฎ]คR…wœำ&Lš,Zอ2ฆZ >๎ฯ๚ใ�yฉ๏ฑ™3ฆYำo' uบVR7~|„ำข,ฌ๘ฮ�าฝ�Gก๎งAg&}ไศ1ัR]3ิ ุ€ € € €@4 ,ŒFL.… € เฟมB�ญ‚�ศึm;˜๊&:��ะA!ำ�บ๛�� Yๅอ�ฏŽ๖ห/วdแผะ|�ว฿ฉe ข�{็TศํฌiSฆH!็ฯŸ—Qcฦytๅโฅ‹ฒz๕Zmฎธƒ…Z‘Kซๆy7{ŠN�ฎ•ดยชhโoฐPงIิjZv�ป๗[๙n฿๗rแ r๓ฦMษ“'ท:5zฌ๕�cํCMMiฺjืkPล๛โzฎ>Cา{๏5ำ}๊๚‚E‹คGฯ>บ-M1๋�งท๓๗‚+ญช1:ต๕{อ›JโD‰�=อ �a…Qพ0วkP/2>๎„VˆิJ‘๎Vฐะ]mG+์l�ฒี}Zจๅ�ษชŒณ�l5_>3๚sณ์kŠฮP'ป6x /^ผ(๗�wŸ9Bวถr•๊•ฃ\งFj1ฒcขง๔?์๗=o�๚O&Zก  {ใบีๆผ?��S ฝQ,ิ5�ี)}…~ผOˆK ๕ู";&Q๙�t›บ+ง้๔ฒ๚ซiˆoอ๊•NจPรƒ๋7n4•:/]บdNk�ช…™VUซVๅ}ต@จKน,ฃวŽ“‘ฃฦ„:ฦฝม]ะWุ6ฌ`กปขžN๛ลฬ๐>�๕ืŸขำไzท@ย9Q}–Mึ?�,ศ_๐ 3�๑ฦ๕kไ^๋s^ซษฝV Gฃ๒ูe_(ะ1ฑฯำื๚u๋HMkšโดito6หZม๕JUย�YkŸเOฐp๘ฐมR่๕สฦ๎jŽ๖5๔uก5ฅqๆฬ™อ&๗ิจ๎›ฏ๗ธฏ`กVีชด–๕๋7˜S" 6oึDš6ฉึฉa_ ไป›ปJ`›vd็Žbฟยช�๊>฿{YรŠKญ o‰��gฒ;์จฏŸ}&‹9Eงดึฉญ�M-์ฯqwะั}L ห‘๏{๒ฝ้}ฎ�๏จ@ƒ…SฆN“ƒ=�`AฏฝgืS!R—�ถบnท๑cGI�๙”h%#ปต๏ุ)สAM๛Zw๋5ฒ>‘ 6iิะผ๔yวŽ› #FŽ๒๛ั�U็Ž=*๏Tฌโ๗น๎`แ‚E‹ญPhoS๕'๋ ฯ›kป์ฮนƒ…�Œ‰}ž๛UCEล‹“RฅJส“O<แ์2tx„ม‚…๎joพ~�๊ 7ฌ]->˜F๔1^ฮ•ื้CdBl๎Ÿ%ฮ…"XะฐyรฦอฬQ๎`กปzข} ๗ฟ4T่]IT�@Cjำ@ึ๖ํ;ๅรŽฬบVฌิส•ถ5+—หร้CโZQVฟ‡ต=R^ษโฅ๏นีkึy\ฺ� ๋s�ใ?V"3&�—ส๗ฆ�๏จ@ƒ…>�จ[w๏ฎ8มยฐ|ผ�ลพ€ฏฑท๗E๕5Ÿ่๚ผด๛ฌำq—*YBŠ/&ixภ�l�=ฃ�ฎ๑ี",ดฏฃ๏ั|ฏไ“2ฅ�”‚ฏ0Al�gดํใxE@@@ ุ�ˆะ@@ ž,Œ;�ฐIsงz™V,ิ_–ป[๎<๙ไ๕B…อฆCศสๅK�ปƒj๙N Ož<)e�บ=�œBธร'วO—rๅ+†้ใฎ–งกฎฐ~ บk๛V3ํ›ฏ*Rz๑‰ใฦH๎�นฬ}ผร๎ฐฬšต๋ค]‡Ža๖ว{‡� ๑CVีผ*ีj˜�:œN งํ๏ฟ/Jล*Uฃe:Gsมป๐%ฒ>๎0H  K/*> gบร!�>๚ฮฏถHฒdษไๆอ›ข#G๙uช;XจUฉดฺ•V–š;gฆ ม๊Eยชภ้ื ‚เ /—/‘G}ิ๔Dฟ๏๔๛ฯ��a‚…n™;ณฌำฑ๊ดฌฺฺถ๏(kืy†Š�ฝะ๊Šdำๆ+ไ—'W.™0>คat ห—++ฝ{๕0๗๔5ีxƒzuญ*Y-ฬ~๗Tศ๎0TXำ2›“"๘โ็ฬš=G๚๕�4‚3ขถ๛M+Œ๓i�~ๆ"๋ึฏ—)R:ก/_•๚ข๚ูฅ7ŠŽ`ก๛ฉ�aแEK–Jท๎�ว�}€GUง{ Ub$4)WAšYคŠฎฎ4uAšเฒ*u�•KUCWคฺ่�lจ€%าฤ .ˆJคJI0A@บแž๗ฤs<™9i“ษd2๙�Ÿ‡ฬ™ำฯ็?sfžg~ผ�1ฮล^ำ ๖๋�GฺsฎนRลJ๒๎ชeๆ๐ม๑'NHหึmํใ๘bkาธฑผMญ๊ฃตnZr^น|ฉฝŠ[ฐื^ศ € € €9,@ฐ0‡;€ร#€ €yU€`a่๔�M›Iƒ†w˜๔ํฮฒnอG).๎ฃZิ๕%#ฬyัŸ*�ท&อšbฅ yศ`ก^๒ cธตhฃสีดส–V�าถfอZyj๘Hk‘ืฃ�€ฌ?$kำสuZมฮญm�โ3;๘้�‘^ืmึดฉฬœ>ล�ฬ๓วz็๕ํg Aj ญkmค?๔jศd๙สUึ,๓ั๚A�,ิ–ฑN๏4†d๎ึฃ—NๆสๆซฏมB๊QpEŒก{ตนxtพ๖I“&ฝ*:อ›๓ฒ4j˜<ฤก3\ข�XMC$วŽK:t ๊๚�Ÿ่ฐฺt8ฟมO<™โ๕l.ศ%ฆO‰’ๆอ๏6ฯvษาe2nย$๛ฬ&Iฐะฆ ุDwc�งŸJžR‡Œิ sฉ5๖๖‰!ƒฬลั๋ืห มCSฌ๊ †๘+XจA?x๏)Tฐ ๙^0pฐl�ผู<ฎพ5„ซa\mฮ`ก>_ถd‘*ืiทแfuพ6N3ฦ]‡๗lฮJ ๎ซฮฯ๋|Nœ๘EZดN�\ฒๆ้cV๏]บ็๛ะ๓ณJ—ป5=nQ#L}๘็Ÿฝ;‡7Oญย›sฃŒ !)ํงศ๗KBB‚ฝ็ู_n๙ส๘L`/๓5ฤfฝฎ์ฅ3‘˜˜hฟ†œมBฯชxบ฿wW-ทƒfm#;ธ�G€ั#‡Kื.ษUฉญCป�t™๎ณ^ฝ:ฎรy๋r็ggีfgตบธ๘xiีๆ^�ฤnQฯM4^#ญอ็kึฎ“ง†ฐ—๙:แkŸ8—•๗ฆ+ญ•๔tX้–ฦ๛สํฝoห,ิy� ฒ๏A๚|ยธฑา>2ูฬณšคพO–.^ %K๊ช2๏•�ศฬ—fษจรไมฎษี9*t๎šๆ9˜g๒Of}ฒrฟิc;v�๕V,[,7�1DyZต฿<�.]ปvํ๖ZคŸ Œ๏็ึฐ฿›4u=/ฏ ™ € € €@,ฬt‰ € Bฐ0t^๙ร๒หใฦpศaaafตย๋ฃekฬWๆถjำVjีพอœึ!{gอ˜&ฟ'�ดo…�1ฒ"่ลำfฬ”๛H‹wง๘q�3จ๋;[—ฮไŸฃ’8ืPืฦM›อะ_Rาู๙ํทข!mฮVฉYพbฅฤ๎•�ิ—>ฝ{™Akฟna พธUห–ๆ*ฺ‡oฮ�ทl•KฦtีชทH๎3C#žร1ง,ิa™฿zใ?RจP!sŸฏพ๖บLŸ๑ขu น๎ั_ƒ…Šฃีฐด*–6ํฅห–ห๚ ๅิ้Sfฅ(ญ:t1ฌŸV&๔�กZ+bฺ๊Z‘H›†>฿œ?_<(eส”‘–อ›หฝm๏๑fู๖ฐ*š;0�L~แ9chัไืG‚Xy SืAkฝ`ฌS็6ั* V›�๖BYฟ~ƒ�tse4p€้i-s jHืูฌภn\\œŒ�gH๑โ… ขกNทๆ๋‹™&ุํธนaž๓=sม0\i ษฝgฯ๗r�ยyนlTเ\ณf}ฮp—พG๔ž�ลz)Tธฐ๔ํำ[ฌ!ผu u_ใวŽ‘ํ#uRฌsLfๅ�ฅ�๛,=r„t้�Qถn�&}ผV~�ปWยฏ*j~�=ิตซ-z•๎ฺ k ุูด_๔>jตแรžดรก:๏… —ฌE)ีK-jฦgฃ6 4พhด~=yJZทii„ฑ“+๖๊ฒวŒ พ๓^เ›๎73อ,ิํ>�B–-[!W_.Cถ‡$ึ*ตz๏wkฮ`˜ต|ฦ‹ณDซ๑zถG๗฿เวˆV็�,:Z๖๏�/q'โ๐\ ๓sซ–๑Zทšพ†‡>9ฬzj>:ฯ766V^ž;Oฮ�vVฺตm+:,ณีrtบ๋9dwฎ์ฌFฃUฎfL์\œ๊ด[ฐP+q้pษ*THu; ๏d4Xจ;qVำayตบ—3`‘๊‚p/>ฮTf†Bถ.฿ตๆน=z uพ๙ฑ~šA`ทmtžVฟิ*˜VK+Xจ?œฏ\ถDส”-cฎณuซ๔้๛wkำ\๕่5ญ๗ :ƒlimg-s๋]Fฐะr\พtฑTน๙&ื…žรW;9ž่=วชๅฯ`กV�zํีนโ ZวึฯีแแๆSฯ`กฮtพวฌm�ำ :+๐yn;๑นฬแส=็gๅน�0ผ�z๔Lsธิฌ�ป| vํา)อหLญบžŽOsใ?jะpอฺOฬg๊2mj”6‚ฌฉ5 ๐ 6�C†ณ๙+ฤๆ�gzำฉ}‡pnwๆฬู้๛ัA4็r~๛อืล ๊๗V๗ดs ฒZมBฯํ=Ÿ;zL�ฺฉ‹Wทฦษไษฯ�๏%ฯํ๔น[ ัmฝŒฬ๓WŸ๘๚�t9๎yพkื}"O>=�žํ,ดxLผ๗�2๚™�s_ |v๊๚`ŠP฿ฝxแ|;„ซaEญ๋ฯ–Y_๏—ฮj‡ฉ�ŠUซไู1ใR[l„ฝKษ{ซVุ•ฃ+zon ๋ธMzๆ_ข฿�i € € €ซมย`ํฮ @q‚…กืม๕oo(M๎jj6ฌ+ิjRัŸฎ“;พฑfๅูG�Q|ฮ์—ฬ๋ืสN๏hhV™ณ@๔yญš4้๙(kVš๚ฃๅศรๅvฃ๊Iูฒeํ ง†"วŽŸho�นSGฃJะ@น๎บkํyzฌํ_-+Œ!ŒuXemQSฆ™Cqฺ+9&tธร๛�ทƒืฉ๚C๔ซW{sฬ—อ`…g๕k—๊ ฺฒซBคuฌ@๕์ำื|อZ—ใ์Ok^j/^”��ลuฑVญำjLžC€บฎ์˜ู�๏�ฬภจฮJ/ุๅุ,ืMjp๏๑�สZ๕Œ๊}ฅ์jr๔ฆUร:์ฌ†ผœM‡ฅี ฉŒ๊]„:๙๋ฏา๔๎ไŠ›ฮ๕œแ฿ด๎‹ฮmtZ๏ษ�zfดิฏWWJ•*e๖ๅฎ�฿™๗๕็'M0W฿b g�๗ฑ�ž›Šs๘๐งคB๙๒^ห๔ผ7l�,ณ็ฬuึืฺ@ซะjีัาฦฑ๗๛?๛ฒ๒wญี�๖ธ๎ใีๆu๊ต๒i๛๛’ซขฅu_๏]พ๔‰Vฑ๋ัฝปHีชสฮฆŸZล0jสTื�W›7x}�9ทwN{†ต2๏ฤ cฅ๒7:W3+Yพ�ๆ[๒าฌู)ๆ๋“๔�วV…ศด‚{^;Mg†,ิ๊ษ๏ผ๛ฎ๑พ่( &WดีMตO‡ }Rbฺ—ๆžœผ 7™รลปm ๗ทว๚๕‘Z5kบฺjฅOญ0:ำจx˜ฺฐฟ–ญx๕?ฐXM๏ญZY�ƒ„ฟš?๛ฤื๗ฆ�ร~๘AฉkTี 7ยษึ5{มBฺ[ฟ–+Wฮฆธt้ฒ,XธP&Onฯำ‰ญ[6ูคY็Jฮ๏$’�หอœ‹�2Y_๎—C‡ –ถฦpูeห•๕:็SงNW—šC@{-๔˜กaห^ฝบห�อšษuื^k๗9t๘ฐ9�นs๕ำฆ}W'ล�ุZฎ๋ฯ1ชnjั@@@f‚…ม�;œ € ย CทsK”ธ^ช�Z�ธภ+ฒ�งX9z๔h่^ฌฎฌ� 7Hํฺ5%>๎„1Lฺ6?์1๕]่q*•ใŒc}“๚Ši,ัTซC๊†ๅฯg ฑwXtx>ฺŸ๖ัUตชีไc่สใวโไเแC)ช �yf�S‚ชZญช>(+‰ฟ$ส^ใ�z�xœ๗ŠypŽ`J–,aV_ำแLiนS@๏ฏ7�t“B,"��๏ฎ4Cy�พB}Yแ(ฝ๗jEJm+ŒaœŸ3ึœv๛ฃ�ีจQCJ•ސ“‰'ๅะกŸEรยกึฒr๏สฌ…šVนฅŠ‚Œ๙๓›ฏƒุฝ?ู�“ู�et} รึฌ^�Zุsฺ่Œ๎#;ืณ‚…๚:ีJชฺ4ศn|ž์ุฑ3รŸฮแrS งy^ว-ฦ๗ˆˆ’R�๚โrๆฬoฦ๗‰ƒ้๛ะ>ญ[ทŽฎF[็นbฺ,ด†ขึ๏#ตjU—#FH�กุ|น_๊ฝGmJ•*)็ฯ_4ดาฌศ้72\�Pฑโลไ”14บรŠ๗uXฑ@@@เ X|}ย!€ €yB€`až่f.@<# ทp๎„qcฅ}ไฝฆCv %šg€นPฟ ธ 3{€V-[ส”จ็ฬอNœ๘EZดพ'ณป`}?ธ �ฐ[v € € €มB^ € €9"@ฐ0Gุ9( €dƒ€Vภz๏ๅ๒ำพ}๒๑šต๒�?ี๑ยคMซVาฦ~S›ทyฯฝ‘ู^)/.]† €ฏมBญฺขEsนญv-น๋ฮ&๖ฐฦsๆฝโ:ฬsา�%, บ.แ„@@@‚…!ำ•\ € ปๆฎ�โl@@ u+X˜ฺIII2้๙(YดxIjซ0€ ๘,|่มฎ2r๘ำ)ฮ๕ป={คwŸ~„fSจ๎ มยภYs$@@@๒šมยผึใ\/ € $ ƒค#8 @ศฒ@xัข2qโ8ฃŠ[m)^ฌ˜ฝฟs็ฮIl์O5ušl฿�ต=Ÿ rZ`แ�7ๅึ[ซษ/ าฒu� Ÿฮ}ฺห˜g�eฎ๔ุQ๙z๛?qกย ๚ลfM›ส๔ฉQๆŽŸš" .๒�Aุ# € € €ไI‚…yฒ�นh@@ ็ๆ|p € เ –,!็/œ“ใวใ�๖ˆ € € € €@€`a9 € €€ทมBoๆ € € € € € € €ม @ฐ0zs@@๒ มย<ุ้\2 € € € € € €ไ ‚…นข›8I@@ ๔†^ŸrE € € € € € €  Cฃน @@ ื ,ฬu]ฦ #€ € € € € € €@ X˜G:šหD@‚M€`aฐ๕็ƒ € € € € € €$ ,ไ•€ € # s„ƒ"€ € € € € € €้ ,L—ˆ@@ฒC€`avจฒO@@@@@@@ ๋ ณnศ@@| X่› € € € € € € € Xd € เ-@ฐะ�„9 € € € € € € €@0, †^เ@@<(@ฐ0v:—Œ@ˆ ไ“+Rฐ@~ใฏศฅหI!z•ูsYุe+{E@@@@@ ซ ณ*ศ๖ € €> ,๔‰@  ฉ.ฟ]ฮ/GโOฅy†… „I๑๐"๚œ$%i1gZ‚ฅHก‚’t%Iฮ�v^$_ฮœGnดห)ŽŠ € € € € €@`ึ›ฃ!€ €�!@ฐ—Bฐ „-*…‹ฑO+!!มžv›๘เฝUข�8�#'๖X�๒ร{ณSL?7qผ4jุ ล<}2{๎+ฒh๑ฏ๙ู=ฃsงŽ๒H๗‡อร >Zพ�ณ'ปฐ�—(QยM~ร.a�้ว6็y:er-๔> ๆษ‰ดiR qโD๐ =‚ฯ•x๖ยn ฝ๔อไx+[$J– *OwธนนC�G�ืCฝo??\พrฃฆoภษ�๛ำ™ำ„+ฺ9๕ู(@ P€ (@ P€ (@ P † 0XC_งM P€ bบƒ…1� พz�žž^่�ญ‡ ขน๋๐ฺไ c_}S4\Qจ@ฬžT)๐7ด[ผd&Žฃgฒg฿>tํ๖ล+gๅ๊มยฆ?Gฯ/บซJtก>‹ฃ`แุั? \ูฒ!�ทiำ๔๐ญอ๙^j,#ฌ๘เแCฺดน@HภฐU�๖8y๒”อฉฤ‰a่(_ฎœMป๕`๋O?ฃฯื�ญMม๖_gฐ๐อ๘~hV4�qOƒE;o›‹ั๐F"Oฬ�.>ฬใ‡้s0f™๓*cศg๎rกEฝ’ศ’)-�Hš*)7U� เ๙๓็(๒I‰Wฮภฺ‡ซ-…œ&Mjlูธ^^ž๚9��๋Nœ8Œ™2ขXัข6ฯf,”J…�๚~e^#>xˆTช‚`ม�-g.มB ›5X(mR r็ฎ=x๑๒*V($‰๋K7ฟ้ื๕๋ีี็e)aนๆโลKศ˜!ƒ 8–ัAU9)•—ฏXฅฏs๔ใu {๘ฃhถฤ๐๖z ฟ�ฯqฐ0Iwดฉž ํ�&‡gผkธz. ฦฯพ‹ ฟ�s4�HตตiV›–E {<• D€ ชภ �ิ�พP}ฟTมมp๓{ฎฒ„*$๐ n�j_ป๙=SŸ๊ŸฟZสูO]จ†‰s" Eq๘ช.พน�ฉ๙Yov5;๋�ธO P€ (@ P€ (@ P€ˆห ฦๅทฯgง(@ P€ั(ภ`a4โฟฆก;t๎†„ ๊ัfอ˜‚'Ÿผฆ‘ร7ฬฆ๕k)S&}Sญ:๕pA…ุfNŸŠ"… ้ถฝพฤฮปBํิ•ƒ…�ฟ๎‹๕ƒ‚z'NœD๓Vmฬg๙ฒืhฺคฑyl,�ถe�Nด”ต.%xilึ~eYๅต‚ฦ๓ึ`ก^jYyๆฬ�๔ญนsˆE๓็้�ว๊;QผTฝ/?ฒgหŠ•ห—ยSUำ๓๗๗Gฏฏ๚ฺุVฝ*พ2X_/•K•)o�kฟ๓:ƒ…ช`ส$๑เง‚|Ÿz#yข๘x3ฉา& ฤ�ษ�‘! ไ๖@žย /ฑ๖žซ้zโั์�ล^๖WU�p๏™;nหฟ'>x๐Lฅ๘"ธีฌ\ ƒบTT†/TแAo*Tมต๔ฑ฿c5๖C@… %8t๔QU }จp†ฟช\จช๊ ขดธ่๐aผเ“ฆ>“ๆฤ๔›ฑxM่ฟแ™ถซู…g๎ผ– (@ P€ (@ P€ (›,Œอo—ฯF P€ \X€มB~9N˜Z† Qฏแ็บงวa๖ฬiN่ี๙]dฮ”ืฏึ฿พuซTำ๛ญ[ถ@๗n]๔�บ ๑ํภ 0[H3pๅ`ก<Ÿ<งl;uลƒmใท๛(QPิ,”฿ฺี+๕ต=F‰าถห!ห’ล;w�l†G+|Zw๎�ีื[ƒ…6nฦ7฿ดsอชๅศ‘=ปnห/จชฅ๔์ั-š7ีํRPชฺo›7ฌEฦŒusƒFM๐‡ช†้h“0ฅ„e ฉ/G๗EถอหำIโ{แญ$žศ�–'Š˜ๅส'Fฒ,j9aฏปx�D�ิ(*Œ่ฯพ�๘เแ๙8vา ฟ]H€3wqํก eโˆm็ห„;eTัEU‰0ภO…ŸรหSUv0@�๕'TEHตฒ�‚–D๖WaD,๔SBีฎฎRำ” แs๘ผY ~)>มา5ฟ`๚ยŸ"6ฑW�ๅ vฏ˜"OS€ (@ P€ (@ P€ โŒƒ…qๆU๓A)@ P€ €k 0X่Z๏รูณi๐yคK—^w{`�^�อ6ฬๆ์๑"ฺ_ปถญัฅSG}ป5@h ี�}๏สU๘4ิ!\9Xx่ื}:�็ํ�+์9&Oล‹้vkฐฐt้R˜0vดn฿ถ}zซ๊๖�”IPผุ'บูบด5X8x่0ฌ^ณึๆVใ>???”ฏT๗๏฿ื็ว…2eJ›ื�บyK๏K่อุŒ Šr<เ�AXฟq“qสๆณbล๒52(˜8sึLœ<ลๆ�๋<ศ–ส?MƒzŸg@�Dwแ๗ไŽ>��ฑ\e7ื�๊๓wƒ‚ฮ˜Wฮ,oa|๏ฬH_…%ร๘^jนfaTนBษ�0TมBw7u^�๓๐RIBตtr@บฉ ฉG"ธy%Qm Tผ0�ใฅƒŸวXธjf-ู๎Œi†ฉืmฆI๑" P€ (@ P€ (@ P€ @`ฐ0ผd>"(@ P€pE ]๑ญ8gN๎๎๎ฺ่ฃไS–ณ0v”s:Ž‚^อŸ‹�น?า=๖=ถlูjŽฒuหF$O–L7kู'Ož2ฯู๏ธjฐPช <ฐWOWBz•ชVทŸ:๚ตj|ฆ�ญมB๋RยK–.รˆ‚ฟG๋ฝ มฺ๕t?ึ`กตOc๐ฑฃ@นฒAญ•Wฏ\ŽwrU24ฎ ํ๓วQcฐp๑‡—-RำงMึ็ฦŒy๓:ผ.*“xนร]U.|๚ย’โS›ส๏แห&™ัฒต ํ๙�ยใซฑh]BLุ๐RW/tๆ<าฆI†)}s!�jูeUwะ#ะ๎๔JคŽใซย…๑จƒ:<่ฎ„*D"T็�ค=พšŽ‡ ช:ˆจ~—}T%ร˜:–ฎ ๚N9sฮF_ัmgฬƒŸ (@ P€ (@ P€ (@ธ.ภ`a\�๐๙)@ P€ @4 0XM๐ฏaุbลKข๐วE๕H7o�ภ๒%‹^รจแBBw๛๗๎‚‡ \ฝj“Pš„ำBฺ\5X˜"E ์�e›ž๖ƒ‡QชL๙`0เ›~จWงถnท†[ตhŽ�ป๊๖๙ b๔ุเฯoฝ๗ปแ#ฐbๅ*}ฝ5XุพCgค:ก๚็ๆฎ๖UเPE %)• ี�๘ซc?ตฒ:’ฅ“U01ภ฿*(�ใิ•ุดใˆำๆj฿Qt�ูฯ‡ว (@ P€ (@ P€ (@ธ*ภ`a\}๓|n P€ (อ F๓ ˆยแ�u่‚ฤI๋VญXŠkWฏFแh๏บNํZ8 ˜:ธpแjีmโตึ`กฃ ]H7Z—ž5{&Lr�rฝว�//O<|๔%K— 6kศฯ,ฌRนF  ๆm�ด� ๕�.]{`๏��๚šˆ ฅย T”ญMปŽ8|$๊lz(๚Q9[ฅH…ญ�๗�/� &‰๏†oš'Cญ*>˜2รใทDอ’$J€y๚โร\ูเ Bƒชja@ ”เ ฺWว& *จ(มB+TaCต ํr ๘ยMชช^ผ_๘`ุธeุw่LิL\๕�vQ๖`์˜ (@ P€ (@ P€ (ร,Œa/Œำฅ(@ P€ฑE€มยุ๒&mŸ#u๊4h�ฌ…n|๙โฆL ^ๅฮ๖Ž่;š8a,J•(ก'๐หฮ8๓ฟณม&ำก]ฤ‹OทWฉV#ฤ๊x�ปvF๋V-๕uใฦOฤœy๓ƒ๕ๅจมบ\๏พ�ะนkwG—Eชํงอ.]:�G๕upๅ๊›�ถo�Œ4oงัmึ`a๎�bั�yบ]๎‘{ํทํ?mAš4ฉuณต๏ˆ ๛� ๊ืี�Mž2 ำgฮฒาฅ=<�฿�_”{‚ิำa๔F?�ผ๗\…๓Tล?ๆ‹งŠcถช”๋ปใปIฯฐ๒จJ๓Eม/žf�E๒ๅ„Ÿช4่'หซฐ ฟT$” ก๚๔JJƒŠ ช๐ฃ "เ…Z๎๘9เ็ญ.๐†›๏#ตl๓?๔}฿7๒แ๏งž๘ใb�q๎šำgํ*vN0vH P€ (@ P€ (@ P€ˆก ฦะวiS€ (@˜.ภ`aLƒŽ็_ง^CdสœYŸ<๓๛�a› žน๊v่ื}H˜P- ซถZu๊แยลKมฆ:gๆt,X@ท‡ดV?พ:\ ช๚๛>W�žฉ เc๘ฟ|ฌB„ŸวTŸn�Oแ๏#�T 0ภGี8๔U‹$ซJ…ฯมฯ#ณ6รW_`ภศx๔Dดนš“‹�P€ (@ P€ (@ P€ bผƒ…1�๒(@ P€ @ฬ`ฐ0fพทWอบ[�๐๐๔Pั1}๊$<๗v^้Uc‡็ผu โ;w๎ขยงU�.UฅกlวŽ@ห6m^—9Sfฌ[ณช$ฺฮฟ€ญ?� �พs�ถํpxŸ4n�ฒ oง}[Ÿฟw๏ฌ฿ธ<„ŸŸ–,]โ}a=‘7o,˜;�ผ|ัโฅุทo?ฒ็ศ†ฎ;™มAนภ,”ใ~}ฟา=ู��9&MžŠ?�:‡>�;ด3ซ9ฺ/ใั`กŒ3wึL(Ovuุrฎช�x๒๔i}œ=[6”-[Z/—|E-ฑ]ฃVPuC}า๎วข๙s‘;๗Gบ๕๑ใ'(^๊ฟเฃ�ฅN9๔pwCโxnจ� ]บeC†ฬ ฐp๚ฌ�๑W๎๛ม�GUT[ัœ๑ัญZ| ]๘�ปซJ Fมๆฅ~~ัีสผ‹�เs/ช@แCU˜๐ฉ๚๗L‡ UฒP…}ี๏ซ��แ็ซ–HVำtW5 =�ิ?_๘?~ทไภ๋ฝึXทใ&L__� gqึิ]ษฮYฯฤ~(@ P€ (@ P€ (@ P€1]€มย˜�9 P€ (C,Œก/.”i*�1Š—,ฅฏxจชฬอ33”ซฃ๗ิมQ๓ณ๊z7mF�N({ถฌXปzฅ>'AฟฅสโYaIkŸึฮฎ฿ธYF9คญF๕j{���‚]"G >Fv;๚”+๛๊jˆ๖มย)R`ลาEH:uˆSธq๓๊ึkdใ™`ก˜O›2ู\b9ค/]พ์RมBcžžn่ำ(�ห– ฿ฮบ‹‹ท}ŒS๚3ว�๑ะค๘˜ปใ>ฎ<Œš`กง‡:^5>€ฏฯ ตด๑s TŸ๐ำU%๘จืE�7, TCฟ�*`(แX7ผP!รžบแ�_� ฬ‚ป�๐�ษsธp้–อ๓8๓ภ์œ๙<์‹ (@ P€ (@ P€ (“,Œษosง(@ P€1X€มย�๒B˜zห6ํ‘ ภฝGx๐,ทเนO |ิขศ~๐๑U๗ซะaTnัm•ฯฦพ)@ P€ (@ P€ (@ P€1I€มย˜๔ถ8W P€ (‹,ŒE/“ฃ *„”)S่€คTS ฯ–?>คK—ืฏ฿ภษ“งยsk„ฏ•eฆsๆฬก๒lnธ}๛6.œฟhS1ยGแyำธแค๑q๔ฺKxฟ ด)พ— &O€Ÿใฅฏํ9› #q K 7ฌ”๕>๖€ฏ๏Kตฤฑž=๕มƒ'xไํŽ๛UP„๊฿?O�p๗ฑ/ซc€ ๚I�PMห_~Dร�vั๐ศ’ (@ P€ (@ P€ (เ’ บไkแค(@ P€ @์`ฐ0๖ฟc>!โชภ �เ้๎‰‡ฯ}uHฯฦA-C์๎แกB|QSญะ๋ฝฌ)?›=๕ว฿ีฟ‡/U%ย—ชกT,UๅมY9z๒ƒฦ4ƒ}บ‚]ฐIฑ (@ P€ (@ P€ (,Œƒ/L P€ \A€มBWx œ(@ P€ (@ P€ (@ P€ (@เ 7a (@ P€ ภk`ฐ๐5 s P€ (@ P€ (@ P€ (@ P€`ฐ0hผ… (@ P ๒ F�=P€ (@ P€ (@ P€ (@ P€ˆ  ฃB•}R€ (@ ผR€มยW๑ P€ (@ P€ (@ P€ (@ P€ั"ภ`aดฐsP P€ (@ ๙ (@ P€ (@ P€ (@ P€ (เš บๆ{แฌ(@ P€ @ฌ`ฐ0ึฟb> (@ P€ (@ P€ (@ P€ (C,Œก/Žำฆ(@ P€1]€มย˜�9 P€ (@ P€ (@ P€ (@ P ถ 0X[฿,Ÿ‹ (@ ธธƒ….�‚8= P€ (@ P€ (@ P€ (@ P ฮ 0Xg_=œ (@ Dฏƒ…ั๋ฯั)@ P€ (@ P€ (@ P€ (@ „$ภ`aH2lง(@ P€ˆR ฃ”—S€ (@ P€ (@ P€ (@ P€ˆฐƒ…ฆใ (@ P€‘`ฐ02zผ— (@ P€ (@ P€ (@ P€ @ิ 0Xuถ์™ (@ P  Cมแ) P€ (@ P€ (@ P€ (@ P€ั(ภ`a4โsh P€ (—,ŒหoŸฯN P€ (@ P€ (@ P€ (@ ธฒƒ…ฎ�v87 P€ (‹,Œล/—F P€ (@ P€ (@ P€ (@ ฤh c๔๋ใไ)@ P€ @ฬ`ฐ0ๆพ;ฮœ (@ P€ (@ P€ (@ P€ˆ� ฦ๎๗หงฃ(@ P€.+ภ`กหพงL,๙›oโ้“ง๐๓๓uJฏป“)R˜C�ฟ฿�wด“9Sfdอ–างร“วOpๅฺ5œx#บ}�6่�ฉƒ9ืŽบโภมƒๆฑฑ“=[V|๕Uo-Rฤh2?%Œ8}ๆl,]ถ�ls๖Nซอัฃ{W‡�ๆฮWะaปัุฅSGดk�Zvํ�{๖๎5Nู|.TณfLตi“__?(�qฐv6Dฝ@Tฝ“๎];ฃuซ–๚:u้†�~๔ร|�็K4jุ@๗ำขu[?~"า}Fe๓fฯD~ฆฒ฿ฆอ˜‰)Sง�7;�XB…๋ืฎB๊ิฉƒ๕=w�Œ<ไ+๗4QNู๖๎�๏”@hฐมc`รโ๓๐ัGชPk๒(Ÿ zงผ`๎lไอ›GOโU�=‰�™rt P€ (@ P€ (@ P *,ŒJ]๖M P€ (ขƒ…!าฤศM[ดRีตR…8w w,]ดw๏� ๑W8‘!}zฌYต $0งำฅk์�ฟ฿<–ฉhธr๙คRลB�พ๙c”… �ฟI'ึร฿พuGว๓ฯU…ฉ็5f\hำBXƒ…Z’๊†ฦึฑC{คPี(,4D^�gTฝ  mfอšYฟิ�}„๊ีช๊�ื,์ุพ:vhงว๔๑๕ล้Sงq้๒e}ผcวNk่O5i†3g�gžwฦNฑขE1uสD�ีสีk0๔ปแฮ่๖•}8+ฤ๖สxA˜œ๕N,ด%Ž`แข๙s‘;๗Gz"E‹•ฤ3oo�I98bฐะŠjbฐะฑKX[, ซฏฃ(@ P€ (@ P€ @์`ฐ0vฟ_>(@ P€pY ]๖ี„{bL๔๏’ผrบu๓†Mm;tB’$Iu�สๅKq�ฺU›๓ฎp หหn�ฒษ“%ร_็ฮใ๏{Cย{ฒ9 n�ธUuBู†}?หWฌา๛ฦ?oA๊ิฉ๕a๏ฏ๚`�๖_ŒS�์ูฃ;>�เ}}๊ิฉ)S&ฝ�ม\ผpั์๗นช’ุนkw๓ุุ‘*‹3อูh“ฯQฃฦแสี+ึฆ๗รb“%ฃ{t๏ชC˜Yณd†งง'ฎ_ฟŽ3�๛#๛๗๏;K�G�ถญQพlํ(KSหาฐ�นSงOk๏#วŽ9ผ7ฌฒ์๕A฿๊หท�ผ +Wญ~ๅญsfNืื:|ำgฮ2ฏoุ พฎ™={vธปปมืฯOฟ ฎ]ฟมผฮุ‘๐iฟ~_้รี*j��%y[ทnกฯO6'Ožา๛Ž~„๗”*Yอš~Žœ๏ๆDาคI๔Rป‡†š7kช‡่ิฅ๖๘ีัpแj๛บฯ—hิฐพง฿€oQZ7On�N๏�ฝซท?Ž‹๋7l�fXฉUใ3|Zนฒgห†ิฉRแษ“'ธ พ๏๋7nย๊5kญ—:u?"มยผy๓ Eำ&ศ‘#;าซ๏—ฟฟ?.^บŒ฿~;„1ใฦ›Ÿ|่gถห�๒;"�ัฃถ฿๏Ukึ˜ ร๚ท@๚™9kŽร%”ๅ\x7ฉเ?aœRK4O™๔ป`๔!ฟณ?�0žุตk–-_aœาหฉืฎQCห฿หZ*ฤ]จPAผ“#�ไwE?๑•๓�ฒืศ“;72gฮŒdษ�ะหพ_ป~C��lวโลKm‚˜ึ`aตฯj้%ฆๅป—1cF5%Jo๏็ธ|ๅŠ๚๏ร9ŒSsu๔ทหx/ฯž{cไศQแSpZทl สk—ภภœ=๛'6n�ฌ–ŸO๗?x/Ÿฟ@๏>_›ฎึˆ�žดjัส—ร;๏ไ€๚�ภู?�ฤๆญ[QนREศ๗Qถ�๙lซ๘Zวๅ>(@ P€ (@ P€ (ป,Œ�๏—OG P€ \V€มB—}5แžXณ–m๐ึ[o้๛๖๎�…cG�๔ัฅ�๐ŠOทM4^/ls Œ�~*Z hำถZดh†ล‹้™9 ฮ›=ฒœฐls็-ภุ๑๔พ�€อพ=;อ€ณ*As PvA6oXซC5๖ทuํ�{๖๎ตovxž›ณซ o&O๎ฐ/ D๖์�Ž?์ผ,๓,กซถขcงฎ!S{๖lYอ๊ša้ฯZ%rำฆ- œlcG�€reห†8ฆ๕Zใข’ล‹cาฤq๚pึ์9˜0iŠqJส2�•m๐ะaก่ย๓Nš6�=ฟ่�wH?ข"XาX=Bท=ƒ…'ๅ๗h่ๆาภŽ๎฿๚ำฯ่๓uGง"��`aว๖ํะถM+๓๗�~g�� :uฑ คYฟ๖ื�[�ฮ„็oม๗#ฤาeหํป‹ะ๑้G๕}'NœD๓Vml๚ฐ�>ษฮฒ”ณฑ๕R฿9#ด๚เแC‡$`ุชm๛`฿้C‚ถ฿ ˆทำพmt์sฦฬู˜4eชูn5บvํšรฟ}�จ r™๒อ{Œใ9c๛O ~ีท?9bs*2c� ฒ้ะม�฿๖ศ�žŒ๙=*Vฌเ`�&๛1mฯ๒ˆ (@ P€ (@ P€ˆอ ฦๆทหgฃ(@ P€.,ภ`ก ฟœpNญ่'ล๑๑'A!ผGBBwบ—๗��ŸVฉฆ๗Ÿ?Ži“� เ…s˜(ป�บ”จTšใ™ๅwUAt๋&v[6o0รˆ๒฿‘={๗แๆญ[ช‚ej)RHUL‰ะ‚…าŸ���๋A$M’D…Uหชโ|nz …Khำบฯy๑า%]USฦJค�–U(Wฮ 7�}๏สU๘ิz›น�ฒัึ1ซจŠœ#†3nำ๏Yชrๆษ“๏ฟ—หl—๛_DOไฟQร‡1๛–p๕ตซืT`>?�•๊…–อ~Lห)๎R€ (@ P€ (@ P€ฑ\€มยX�‚๙x (@ PภU,tี7ฑyีญ฿P”‚*ฬIจ๐๑ใวj๙ศDˆ๗oฅBi“ ูฅK�-ูฑ‘œืึอ๋‘>]z<}๚ีjิึล^,”Y �๖ิ�ฌบY�M–=ตV‚“ฅ3ฅ›}U+g<5 9{ฮ\ŒŸ89\�v้ิํTRถจZ+a=v\……zุ,S*Kb็|๗=พ,+:g�|ฝ/?ฌ๖ใ'Lย์น๓ฬsฒ๓^ฎ\Hจ–&uT้ะๆย0Xว’hhK๒Nœ0ฅJ”ะฝVฏQG/ฝmห&3h$ฯ ฯbl�ฟ๎‹๕ƒ‚q—._FZA๛r>:‚…ึ๙ุรd‰ูฆMSGT ๅ๗CชJ€I6ฉHน`�l30ึํ‹^ุฝ{>'ี๏ไ;"หห}ฝพ๊ซƒป๚ค๚๑Y๕ช๘nศ`}–Pจq_x>ร,4�†H� -†,๏llข]ฝr™ูJ@๒๓ฆอuXอ8o�\4ž ฮ~จƒ”y๒‡ญ็ํG๖oฃ>Cj3w๖฿น>ฌ ๕’�ชฺแ™3�ำรศ๓สsห๖๘๑/UF๏?๔�๕๊ึั‡๒๛)K.จ€ฉฑI๐๐ห/{ชๅฆใ'ตคนฑYซส๏฿็›™ƒฺทmƒฮ:่K…eIcY �ั฿๎ukV"[ึฌ๚^๋wV":ฆ๕๏ก,!=|ฤบ๙1cฺ|\คฐyl ๙Eๆ๗dีŠef€pมยE5&จ‚ช 4ฮ,ไห—ืแ˜f#w(@ P€ (@ P€ (@8!ภ`aœxอ|H P€ (เz บ�;‰์Œส”ซˆผ๙‚–ถ๖ๅ็็ซBBหp๛ึMkณK์ูป'dyXูฌ7kเฬัRศrฝ†~�a>x�=9 ถIุOBQฑE6LีมยG้ฅTจซTฅบอ๒ฏโQซฦg<(h)แ}๛ sื๎&“u™้๏†ภŠ•ซฬsฮ�ฑŒ|;๋7nา๏u�ผูzจ ๊Xยฒ�ฒ�']อX>ีคz๔่1J”ถ]YO;w�lVmฌ๐iHๅFูข#Xh]^Z–‘6~zB๊วo๖ฉ0pP…ษจ�v่0ฺu่d ง?ญฟ๒žๅ}ห&มฎอ›๊�ๅ+VAชฺoึฅฝ4jโดช|ฦ8a Zฅ dฝŒ.ฬฯaCฃzตช๚ุ๚wฦผเ฿ธ,�ฐq3พ๙v อฃฏYต9ฒUcต็ไ"ฃชจ์๗่๕ฅMภTฺBฺฌ!?ใw�ธV~7ุซฅšฃ|ยบตV&ปw ช–๚ใจ1Xธx‰ykDฦL‘"v�ˆ”jŒeหW2าq�ผyฐ`nะ฿#9ถ๚D๔๗ฤ~ฬ"ŸฆฅูŠ)‚้ำ� ซ[ว บ‚?)@ P€ (@ P€ (@ธ"ภ`a\yำ|N P€ (เb บุ ‰ฤt<�=ะธY ผฅ–ฃ”Mชr๙๙๚ยอรž๊ŸlRฑ๐็ญ›q๖ *Uบ1šHๅปล ็้ชhฒœpญ:๕อฝ*X๘ม๏๋สz)�|S฿#งฯž!ภฯi�Nc๖R(สผ ‚;ึ0“ซU,ด๎ไ๑n�ผe>ฅฑ�จ‡ZŽW–/•ํ๊ีซบRคqัมu%H9–%Sw์ุ‰฿ยกรGฬ`žqmd?๓็ฯง—๎–~VฎZ YโธQร๘บฯ—บkY ตfํz%kท�ดEทํ�ณWWขดฯถm฿�ชชž�6eาศป’ญu›๖8ข–ว•-:‚…‡~�งCŽRI๓ใbถA"™“๕;มB๛–ŒYจ@ฬž5]v๕Rวฦ2ธใวŒB™2ฅuป�0พCฦ๗Gฺ�N๛ถ|่อ>8fดGๆำ๚~งอ˜‰)Sƒๆi฿ง“% ilŽๆ*Œนฏ�ฐ฿ ชถh�c|ฦ…`แเกรฐzอZใ‘๕ง๑{โ็็‡๒•ช˜Adk๐๖ญ�จXฅšอ}กXC~ึPฏqฯฏ๛๗่%˜ํ�๖็ๅปYซf คK—ฉRงB�ซ๏J(O*iส6aาศRๆฦ‘1ญมม–x฿ท{'’%{Cc ๙E๔๗ฤZ%2ค1์�…คI“ำxV~R€ (@ P€ (@ P€qC€มยธ๑ž๙” (@ Pภๅ,tนWแ ีRมซ,ูฒ้๛<ธe‹๊@˜4�ธ(>Q!& ีHธpสฤq๐UกCWุ–/]ค—ี•นดiืัfูKkศสQลB#$๗J%ถ/z๖6ซLีฉUพ้www9ญ�:eู^�ูฟ?\9XXฑbyŒผยœu�ึ�๛ tู f“—ช๏P‚ ฬ6cG*ยอœ5 �ถ�b4E๚๓ศo?~|œ๙฿hิธ)&Œƒา%Kš�J(ฉPม��P�fTœkาธพ๊�Kท-Yบ #~e�c์HUFฉฮ(�ภACฐv�ฝ�บƒ…ึ€–฿*Uญฎ็a�akT {๗้‹m�vX‡ิห!K%Eูฌี�Vฏ\ŽwrUฐณน!„Gกล. ssXƒ…฿๔๋‹๚๕�[ๆ๚U์ฺต�ี฿ G›๑wEยูฑu)dG฿ญฑฃ@นฒA?ญ!@k่N–Toีฆ#6‡mึŸ5Œg\ผkว6ผ๕V Zต�}˜0N� (๕฿฿ใ๛ฯ1ใฦc��…fsDฦฌVตฒ๙ทeใฆอ่?ภถšฃt�ำๆ *เ˜Nc}–ˆ�žTฉ\ #†ำ�mู๚3๚๖๋ฏ๗ญ?ฌNญcZฏแ>(@ P€ (@ P€ (๛,Œ�๏˜OH P€ \R€มB—|-šT๗ž_๊ฟฟ?ฆN,8Xซฎ f ž:q;ูกqœy“ต๔kฟ,lพm2$T&›}5Q�๘~Xƒ…ฒ�ญ,{๋hk฿ถ :w๊ Oอ˜9“ฆLutY˜ฺ\=Xx๘เ~]IT‚ตฐตnึ }ผ^_tG๓fM๕ๅแ Z�N‡ดdฑuึ�ˆ„�ไ~k%[k•Qฃ๏N�ฃCป ฟiฮZซ2๎?๐+ไwฯ~�ณk�Lž\7[ƒ…�=ฑ�7ฬXฺ�~L#x)ํึ1ญื•-[ฦ&๘-หฺหwƒ(@ P€ (@ P€ ({,Œ=๏’OB P€ b”ƒ…1๊u…8ูไ*pีฒuPuง'OUฐpZ๐๐MžผyQถ|%�ว�ปw ่�diุ… ๆยรรรแT2ซjiฦRฦ=ึีชถl๙ ำgฮ‚5”q็๖Tจ\5X-š7EฯAaBk`*ุ…lˆฎ`แ‚นณ!AูB ๖Y—�ปฅหF๐)ƒ฿ถ}๋fคy;>1เ�AXฟqS๐‹ยูb ษ|“%{C/]ฝhษ2Œ5��ฯแฉy๑ผผ` JZ”Wฎ^A๕u‚lญ4&็ๅ:ูฌมBGกDkศ๏Uมยฐผำบœชu.rN6ซmT =gำ&๑eฏ/๔๘ฒLดนd๋�u_4จดผ๐ไ)ำ๔๏>๑Xƒrก…ƒ+V(‡Q?U$=|ไˆBFtš‘ .[พBWุŒ่๘ฏบฯX6�ฺ๕๋จZฝฆอๅึฅม,”�บ &„Tฤญ[ฟ!.\ผd3nH แษงฯžแ“โฅ‚u?gๆtTKฃหๆŒ`กตšจฃ1ญแ[ำ๒‹่๏‰5ฐy็ฮ]ศ๒ำึ-sฆฬุฐn���tณuL๋u'6�;)ํึฟึ๋ธO P€ (@ P€ (@ ฤ\ c๎ปใฬ)@ P€ @Œ`ฐ0Fฟ>›ษK!ห’“ณฆOลณgOmฮืo๘9าgศจ��8๓;~Rแ0W฿&Oล‹้iZ+อIƒ58'วŽ–x]ฃ–‘ฬ๑๏2’ /มฃฦศฅN�ข+X8b๘0Hฅ>ูค2›ThsดญZฑ ๏พ“CŸ’ฅlG็่2Hจ๏ˆZ>๖™ททy^–Aพญ›ึ6ใคีตwŸพุถm‡q*ยŸ๒>์�m1žํ่ก_/^<ณ๏ูs็a�„I๚X๎�นใgz’YNT–56๋งRอณXษ2ฦ)ฝฌฉ„eณงส๒ภ๋ืฎึีๅ�ซ‚…a}'ใวŒB™2ฅฅKฌXน ฒ4ณฑUฌXฃF�wมByŸFป�พ1,ฌ๏sุ๗#ฐ|ล*}ฮึ“ฐgฺum๎3:ซŒ2[Zื8™Ok๘*ด€ฌร$ด™ A=œ�฿ c๒})Vฌ(ถm�ลh ๖‘`ก�พฌ]ฝR๗uZ-ู�คyห`�:ซมงส฿๚ต๊™AY้�š•jษ๐ฌz(g gช�ฆ)\H๗RHปXัขธ}็ถM่0ขมB๋R่๖แ้R%Kbโ๘��–;#Xhog_sยุั๚๏คP?ฌ!ฟศ�ž์��3Rฆ|Kwk�ทTชํJี]cณŽiดษ'ƒ…V ๎S€ (@ P€ (@ P v 0X;฿+ŸŠ (@ ธผƒ….�Šย<มึm;เdษ๔๕��ฯ กฒ๎�ำวๅ*TB๎ˆฟ„Ti ฤ้�๛?œ wF`์Ÿ๎ฃL๙Šr‰นอ5 ไำว์›;o>Nž>ญณgห†ฒeK๋ๅ’ฏจๅWkิ ชnจO:๑วถ-›๐vฺทu๗๎�ฃ*dnฤƒ!หN/YบฬฉKงŽhืถต>–sฒไณ|็?yŒLช๚ฉ�>TRหjKๅฝขลJ: อสอ ส}ว�OOOูล/;wโทC‡!aVู~;tฤa(SŸ ็๋฿EY~สิiบ‡&ŸnV2•g ๅoืฒ%‹ฬ็;๛็_Xฐhdู�ท฿~ๅส”AๅO+้ณu๊ˆ อŸk��–฿ๅีkึโย๙ (XจZทjฉ+—lฮ ึช๑๚ึ่�w�‚ฟิุ๙ี๗฿X�8i๒‹่๏Iว๖ํ๔฿(้W–xงำ—/]VแใRๆ฿ดฦ4ฺ,4$๘I P€ (@ P€ (@ุ+ภ`a์}ท|2 P€ (เา บ๔๋ ืไRคx M[ดฒฉ๘&หVสRยฦRŠาแ… ็ฑAUb‹ ›5@c&“๙Kุe๑ย๙ˆ?~จc]�5ิ รy2ผมB#ฐ–a–ฏX‰a฿-ํ๊่zke2๋๙M›ถ ฿€�ย1}ฟ๊ฯ5ด^โp฿Qฐะจv่๐ีธf�: �]Hงร�>hเิฎYC฿w๛ึmTฌRM๏[—ด–ภX�B�๔-ี๊V,]dดน@�ธyu๋5 &๋๕Ew4oึิ�๒`วฏ ส a}'ึ%–ƒ diˆช`กesWชรGŒ4ซ'ค฿ด)“uuGฃอั็ฅห—ฃ,XXฃz5 <ะๆ๏˜1๛`ซ5f\ใ่3*‚…พ้‡zuj;฿�K—-wx.ผ%‹วค‰ŽซZ๛rfฐP๚•\๛vml�cO๖ฅzช3‚…ึฅัํวฐ?vVฐP๚0n J— {�c=ถF๔๗D*hฎXถ3UถŽaฟo?ฆqžมBC‚Ÿ (@ P€ (@ P€ˆฝ ฦ�wห'ฃ(@ P€.-ภ`กKฟžpO.mบ๔จ\ตšชภ–<ุฝ�~�8y๊8๖๎ฺ์œซ6Œ�q$*”/งงืบM{9v,ุT%�ึปWO|\คpฐsฒ�๋ŒYslชšป( ๙๓็รผู3u“งLร๔™ณBํMชJีดฐls็-ภุ๑BผT)_๗ํƒ‚ชšVฺดiอะ•Ti:์{›๛$ˆิงOoฝ\ญอ u F๛ฤด้3p�ฦ ๓๔�ปแำА6]Zณอุy�๘‰  ญTU๏ฆMN๙”ูะ!ƒt_kึญWกลกz_–ฺ�ฒiฝ�—๊e๕4า๛ึโ๑ใ#๐Iัm‚Oฎ�ณg/๚,Th�o�žI›�s๒ไi์�ฝ_๖๚B_ึท_]ฮธวัgx�I�ฏ๛ขNํšf8้OยyGUลM#œึขu[?~ยัPแj๋�ตณฎ๒&7MU๏นษ็4iRณงฯžaธZูZฑา<ฉvไน๚}�•ิ๗มบ$ต\cผฐุ@IDAT#ห๑��๛lฺฒห–ฏฐ�ๆิ�ฒeห ญชT—U-๓›(QB�ท„LหWชฌ`ซอัชe ผ๑ฦฯhLFช5๎ูณ/ฤeมๅ:ใ๗T*ศ๙ค„qk˜>ฅšžT๎Kฃช]&S•Smเ !€ณณถ6ญ[ก“ชฦiTH”~ฏ]ปฆ�fLยจพืฟซืฎรเ!�ฅzง„ekาผNŸ�]๏?†Y:<$WนฎP่ืฏคZฅ�&•RวจฟYFลT9?{ๆ4*XRQ๖ใbม-ทn^๔๊ฟ[Ryฑfํz6]ส2ภ�บtถq”น?qkิณษ๒ใฒษ๏R๑ีุ"3ฆ๔!•Cห—/‹,™3๋๏๗น๓ฐqใ&ิฎUCWT}๙๒% }\ฬฮ�Œ่๏‰�7qย8๕ท<ฟู—�^ํ;p‰&Bม‚๐โล .Z�๓wBฺ๗๘UW;ต^ร} P€ (@ P€ (@ P f 0Xณ฿gO P€ bฌƒ…1๖ี…:๑ค*P“)SคRแ–gฯผq๓ฦ5�ธ~=ิ{b๚I gผ๓๎;ศ –๋}๒ไ™ชฬxม&(ำŸฯ๓ฃ>๘ฉำคยCต”์ตk7๔ฒธก๕&Mjdฮ”YULฉย->j้ำ+๘๋�๙ะn‰๖s๘Lง‘ืฏ฿ฐ 9…61yNฑ‘@ฯ‘รGB !†ึGDฮIะ4eส:ไe vFคฏ๐�๓ม๏ซ^�ฅ–ด ฯ๛”๏Bฮœ9 ’ฌธ}๛ถZž๖โkณ ฯ๓ษต๒NsๅฬฅB”‰q็๖]\ฝ~อiหv‡w.Qqฝ�>็อ“ษ’ฟc*€๊ฌ%ษร2W;gฎœ๚๗์ม?p�โ…(?w๎ีฒ์q๗๎=ฝไ{Xๆ็ŒkไŸy{›]�บo7’$IขภฏZ๖;"ฟ'2^กย…t(๔ะo‡lฦ6'ม P€ (@ P€ (@ P N 0X'_;š (@ Dฟƒ…ั�8 P€ ข_@–U—*ฎ๖[Z51๐�ot๓พ�ะนkw๛KxL P€ (@ P€ (@ P ส,Œ2ZvL P€ (šƒ…ก้๐(@ P€qE`วถญ๐๔๐ภถํ;p๒ิ)x?|ช*dใฦฯหK3t์ิŒ+$|N P€ (@ P€ (@ Pภ,t—ภ)P€ (@ธ(ภ`a\|๋|f P€ ์~ู�RฅLi฿l�๔๓6|ีทŸyฬ P€ (@ P€ (@ P€ฏC€มยืกฬ1(@ P€ ‚ 0XŒ„  (@ ฤAo๚๕EฑbE‘>]z๓้���pใๆ ,Xธ+Wญ6�นC P€ (@ P€ (@ Pเu 0X๘บค9(@ P€ €ƒ…6< (@ P€ศ>=<<(@ P€pQ ]๔ลpZ (@ P€ (@ P€ (@ P€ @œ`ฐ0ฮ@ P€ ขG€มย่q็จ (@ P€ (@ P€ (@ P€ ^%ภ`แซ„xž (@ P J,ŒVvJ P€ (@ P€ (@ P€ (@ P า FšP€ (@ DD€มยˆจ๑ P€ (@ P€ (@ P€ (@ P€Q/ภ`aิs P€ (@ :@a(@ P€ (@ P€ (@ P€ (@`ฐะ^ง@ P€ โขƒ…q๑ญ๓™)@ P€ (@ P€ (@ P€ (@˜ ภ`aLxKœ#(@ P€ˆ… ฦย—สGข(@ P€ (@ P€ (@ P€ b…ƒ…ฑโ5๒!(@ P€ @ฬ`ฐ0ๆฝ3ฮ˜ (@ P€ (@ P€ (@ P€ˆ ฦ๗ฬงค(@ P€.'ภ`กหฝงN(๙›oโแƒNํ3ถv–8Q"tุ๊นrๅDส”)แ๎๎ฆuแขฅXฑr•๙ุ๏ๅส…ฉ“'˜วฦฮำงOQญFmใะฉŸ|๐>F ช๛\ฑb5.^โิ�_ีY�ผy-K$H˜7n�ฤ… p�ฦW�๎๓+—/E‚๑p๔ุ ๒]ธ๏็  (@ P€ (@ P€ (@ P ถ 0X��(Ÿ‡ (@ ฤ cศ‹ ว4?ญR 9�yžžžpssC@@^ผxŽ3ฟ�๖๏�Žžโฮฅ*\ฟvRงN์ก็ฮ[€ฑใ� .TณfL vฏฏ �8Xป3J—.… cG๋ฎ–-_แ#~pFทฏ์ฃU‹ๆhฉ�%K๖Fฐk๗์�‡‘#G95`x๚ฤQ=ฮ‰'ัผU›`c†ฅกiใฯ‘Hฝฯs*�ธs็ฎฐ�ขฏ‘๐f๑O>ั๛‹Tp๓™ทw˜๏IVฌPYณd…ทzพืP ฏS\y'แuแ๕ (@ P€ (@ P€ (ท,Œ[๏›OK P€ \F€มB—yN™H›๖4iา๛๚๋์Yl�ด>ฤ๓q๕Dว๖ํะฑC;�๘>พพ8}๊4.]พฌw์ุ‰ƒ‡™4BฌVญŠy�ฑC{คP•!c[ฐฐM๋V่ึฅ“๙œŽvฎ]ป†๚ ;-„็Œ`กัวษ“งะฌekGำvุึณGwดh�TŸk฿กณอ;wxC m\4r็�ศ“ฟK?E\y'.�89 P€ (@ P€ (@ P€ˆv ฃ�p (@ P n 0X{�{™ฒๅ‘7�@~��8z๘7\ปzูฒgGพ�ีาพ๎๚�ถŸถ่๊…ฑ็ษ#�$cFD๙rๅtG}๛๕ว–ญ?‡นำeKแ�๗rลช`ก„'๗ํูฉซ^ ฤ™3�รšu๋q็๖”,Y5>ซŽ๘๑ใkฃ้3ga๒”ia๖ ํB#™Š…F :–fฐะฑ [)@ P€ (@ P€ (@ P€ฎ*ภ`กซพฮ‹ (@ ฤr cฯ ๎าฝ'ผผผ๔-]ดทo฿2.Sฆ,จSฟ>�็�=,˜7�<็Š;eห–A๚ดiuีภ�~๒).š?WUq๛HSดXษpUเ‹มB๋rฯRูฎbๅชธs็ฎ๙ฌAฬ}๛ sื๎ๆนศ์ก@ #ฃ๚ฝ †๎รณ (@ P€ (@ P€ (@W`ฐะี�็C P€ โˆƒ…ฑ็Eัป~˜gฯžbฦิษมฌm‡NH’$ฉ^uสฤq๐๑๑ vซ4ฌ_ป Yณdม๑ใ'ะขu[งO+sฆฬ8 Ÿูo�ผyฬ๊|G3�egีš5กV0 OฐP“ฅJ–@�|y*ej$J”��ฯq๙ส�u๎ฦŸˆ๛๗๏�Œ/ฅK—ย„ฑฃu๛ฒๅ+0|ฤ6ื๔�บฒgหฆ�N��ป๎วzAŠ)ะฃ{Wผ—+—rอฌŸ๕๚๕๋8๓ฟ?0๒วัมฦฌUใ3 ๔ญ๎โัฃว(Qบฌต;4จ_�ฟ๎ซ���๋๊5hds>ขึ`แŒ™ณ๕8น๓ไึKMKฐ๑ภม_1h๐w6�หฒิตkิะmnn๎(P Ÿ�—ฅฉO:esํพ0w�ณm๒ฤ๑H˜ >ฮž#;�Lž\๏_U•>๏���ผฮ? =พ่e8•็ฯž-+๎?x€u๋7 Yำ&๘่ฃ‘@Urผฌ–ั>|ไ(พ๙ฃู‡์H%ศ๑ใFร]อ๓ฅฏzซ฿ูg��6ืคI“฿  Uaิื฿ฒ,sdถ๐|ืoซŠ”�ฝw๛1ๅ;๑iๅJ๚{–:U*ฝ^ฆ�_US}๘๐ฮ?Ÿ~๚YWย4/V;‘y'F?แำธŸ (@ P€ (@ P€ (@W`ฐะ฿ ็D P€ โ€ƒ…ฑใ%งUี�6nฆๆ๎�Xผp~ฐk๐ySคK—Nทo\ท็ฯ�์Wiˆ๊`aษโล1I…+รฒIm์๘ !^ž`กœ ฉ3 ~ีทฟ ฅฑน$ด`แธั?B‹ฒIHญ{^6๗หฝƒ0Cs6ซ ฦ๕์�•q็ฌ _ผxยE‹ง๔็7�๚Bย[ฒEEลย—/_๊l‚Cz 8x;u5›z}ัอ›55C�ูพใ๔๚2(€+ืฝ๊}X๛ช^ฃฎ\ฝb6ญ[ณูฒfีว2_cih๓ตs๚๔๏h฿ฑ“Mxpฮฌ(X ฟพฬ‘ตzฆฃ๓ึ�รฒž๏๚฿ชšiน Ÿฺt+aศกCšK…�œ�๗`ซ ๖๙บฐSฦA้R%ƒต ๒}• กึ-2๏D๚‰ศ˜ึ๑นO P€ (@ P€ (@ P€p5 ]ํp> (@ P Ž0X;^txƒ…๛๗๎ม‘รฟน์รGuฐPชยตiีา|�ชUซ Iโฤ๚x๙Š•fป์l฿ฑำ&จgsRD$Xx๑า%œ9๓?�ผu ‰&D…rๅ๐vฺทuืŽย]! ฅบ[‰โล๔}?A—๎=p๒ไU๚ไ97ฌ]„j ูค๊฿ฎ�ป *๐•T•ฅŠœl7n�@ๅชAU�tƒ๚ฑc�VHe:ูVฉŠtsๆฬร๕7Pฑby๔๋�GW”sC‡}•ซVหnค7๛Pูู?�Rแผำx๗w U%ญAฃ&๘ใ์Y}XดHฌ,ญ๗�U•ฟzu๋่}ฉจทe๋Oz฿๘qไุ1l�ถร8Dฯ�•MPลยย… Aชdสv๐ะ!\ฝrU๏ห๑ฒฏ>h ส5bปw฿>U4 *”/gVภดฆJ๕ศี+–แญทRศm3n<ๆอ_จ๗ปwํŒึ�~/๏จ๊5๋ิณ %๊‹ย๙#<฿u๙๎IฅH๋f ‘สฒุ{ิ3^ผx 3d@9hsู†}?หWฌ2oต†Sๅพcช๚จผ3ฉ”šCU‡�ไใข๐๓๓E‘OJ˜๗ศNd�IDวด™(@ P€ (@ P€ (@ P€.&ภ`ก‹ฝN‡ (@ ฤ cฯ›6–B~๚๔ fN›์มฺจฅ“ชฅe;u๒8v๎ุ์Wiˆ๊`ก�s.š?นsจซไๅษ_ศ�tจวแ Jhj�_ญAตnjู��ป๗˜ใ: ฮœ>ETN6ฉ:(U�Œฐqใจ‘฿ซ `}x๔ุqtํึร&จถr๙Rไ|๗}^–až3oพq+$ค5๐��:@f4ส2ถ๚ะฯฯซVฏ ถ,ณqmD>ญมB๛๊‚SงLDฑขEuท๖sตŽe๔!หf-[[O…บ/๏ฆE๓ ส‡ฒ�ฐ„ C�ฌ๏๋๖ญ�hุค™นคtตd๐ˆแร๔ํŽ–’–็Š™b้ใ๋‹ๆjž‰%ฦ๔ฉ“t›ุถj��&$ฺ\ยs.<฿uY๊Yพ#žžžw฿๋ซพุนs—9�gีซ๊e›ฅแมร‡(UฆผyฎSว๖่ะ.hsG•%`YP-[ฝm๛/ๆ=๖;แ}'ฮำ~<ฆ(@ P€ (@ P€ (@ Dทƒ…ั�8>(@ P€ˆฃ ฦž฿ตGO๒าดxม<�ฝ{ว|ธL™ฒ N�ๆ๑…๓็ฑasชฬ™Fp็ฝ\น?A|›ปวฅ+โษาณฑ9็�์�:w�ฆ-ฒแ [ูž`ก�ฝึcฉT'๋d๛qิ,\ผฤ=†ฏฟ +๕ูœˆฤ ”`]ๅjŸู๔-•Gก{_ฒtF�0สแHFฏ3X8~ย$ฬž;ฯf>ซW.ว;ช2ŸlบtำR๋�บtB›ึญt“„๒<�=๐ฦAม฿๑'c๖œนึหถž๏บ5ุ'ีฅ*ก�ถyรZdT฿Gูฌ•$ปv๎„ถm‚ž๏งŸทฉ%พ๛ู฿๚สc๋๘a {:cฬWNŠP€ (@ P€ (@ P€ ^ณƒ…ฏœรQ€ (@  0X{พ ๅ*TB๎‰™มย ใฦ tฉ’ฏ|ิ1ใฦc��…ๆuก 7l�Œoพh^k์X+�mก}สrสฅหVะ—”,^\/ี+พพ~ช2แ7ุถm‡>'ศ cGซฅฃ?าว‡A›v๕~d฿…ำงG“ๆ-lบณ%ทl�}๛๕ท9o}ผฮ`a๎|แอฯ–-šแ‹๎Aม™ณๆ`โไเห“‹ๅŽŸท˜R๙n—-_ษfนjณC'ํ„'Xhญบ–แํ+mKš�฿+ิ…‹c๎ผ  จ�yใ8ผมBน/ฒcc๓“ (@ P€ (@ P€ (เ* บส›เ<(@ P€ @`ฐ0๖ฝ๐ฯjึAๆ,™อe‘��|ีฒศwq๎ฏ?QชtY�ภป~ูŽ“'ŽปฤรWซVEUํณ] นWฯH’8ฑž๗ิ้3mๆ๙ไ้3ไfs"แ [ูึŠ…;ดCว๖ํฬ�Oœ8‰Sง�๗�‡ฟŸ? *h†งN›ฉำg˜ืฺ ?~b.›+๕SKoฺผีผ^vฌี�n�ผ%KWุœท?x๔่!$ค(�wC๋๛eู๒>โู5ท ้ำcใ๚5z™ei,ZฌคSยpF(PlšทjcŽ';1-Xุฉc{thืV?ร‚…‹0jฬ8›็‘ƒย… aฦดษf5Qฉ4ฺดE+œ9๓ฟ`ื:ซ!<฿๕M๊gส”I-ฯp็๎฿กNcืฎ�ธ~ใ†อ5ญZ4G“ฦŸ#eสทlฺๅเ๖ญ�จUท~ˆ฿ˆ ฅ฿ศŒ)๗sฃ(@ P€ (@ P€ (@ ธ’ƒ…ฎ๔68 P€ (‡,Œฝ/�ร�CU(L‚ว้‡ฌ๖YMผ๓nNฝ/aธ[*lๆช›Qu์๘๑hั:(œ•s Oุส~FฐPBa๙ }lฺ<^พt�ห•K4kืo0ฯษŽ5ˆZฐ๐ณgัชu;t๏ึ ิื}<}๚๕6ถ uๅฮ�!ไนd;v์Zถ ปใœY3Pฐ@~}ฏT” ๖�๖ญ›‘ๆํ4บนAฃ&yEv‹ฉมยาๅ*โ��๛6o}Ÿ*”`žu“j…+–-F๊Tฉฌอ%ง๋ิkbุฮๆโ„็ป>]…‹)ขG‘ช”R2ข›C+”/ส•+!k–,f7ใฦOฤœy๓อc๋NDƒ…Fำธ—Ÿ (@ P€ (@ P€ (@W`ฐะU�็A P€ โ˜ƒ…q็…wํัSW1 ภฤqฃ!Ÿฎบลค`แ‚นณ‘7oMZภ๎๐ม�H ž>{†OŠ— F?gๆt,X@ท‡,ดV\น|)rพ๛ŽพGช�5jาฬ์7qขD8x`ฏ>~๔่1J�[ญาผ ”๋\†๛+Wญv๕��ฟ yฒdบฝn�†๘๋�๙`ื„ทม™มย?�:‡z …y ฒlฑ,_,[ฯ�}ฐใ—_Bฝw�š•ศ–5ซพฦQลศฉS&ขXัข๚ผฃ�fอ˜ช+สGC�๘๑๑ัG๊๋w๏�‹n�{๊}g�X4ฎนŒตฃ%œญใ๕�บ/ิฏซ›&O™†้3gYOGx์่PฎlP๕ิu6โ�ƒ๖�wโฐ“ร:fh}๐(@ P€ (@ P€ (@ P :,ŒuŽI P€ ( ใฦ— โงU๐ม‡้‡ฝ|๑"ึชP”+o1)X8b๘0TQUุd›4e*fฬœํ๖ภ�]Hš4ฉ>g@,Uฒ$&Žc�ึ`กTd[ฒh&Lจ๏ต_rwีŠex๗ฯ™ƒฉYj๙ศแ#f•บqใ:ฅKŸž๒๘B)R| ๔ีซW4eโฯ๔เม}Ÿ>๐ทIXXทNm๚ฆw/ƒ๏Ž฿wสฑ/_พข#G‹ฮ8้Nq์ฆทh๑:s๚ ๙็หK-[4ง่ัขษz�ใชฐ๋6จ_พ๎๙gฅ e๛Ž)pว๏r�“|๙ˆ๑Tฺธƒ–,]N�\�‡’%KF9„C^•ส•d8^�uฏTฉ’4j๘Pต}*8-ฃ'�ข'OŸะBฐม๎ะta!oุฒu-\ธ˜โฦ‹C]:v4ยDoฺด™:wณฎวก…ว�4†ขFJ|?vุ่…ถ๒&ชPพ ๙qฬ?�ตl�…q�ศย๘้�ต35ilŠ^ฟqCŽ๙Š‹ฮั�ท๎ุ‰นป้S&S�ผนeฯ,.œ.D—‡Ž‘๋้>๚ˆJ•*!้ยล‹Tญ†อ�7ฒ8ตnZดo�~Zปn=:}šโฤŠ-ฏŸ๕๊Q์ุ61์ภA?า� y‡ไ๎9 ‰>g†๓ @๗    Y @Xฑฮ|งฎ_Q”(Q,ŠEL;ทำ��ฮส,w ‡ยfMK4เY…แ ้!อ™9C„‡อ.…^9๓ไsปyณศL5ฐrๅj๊�็[นสฎ€cFW›‚\บ#,ไ†ฦŽIล‹•m�ธq“j‹ภทn�’๋ฝztง† ๊ห|P?บฐ๋ �แ{ชXมๆฤ่l?๋\ท^CKW:g๛UยB]œg๎k�†ิํซžๆbc}ั‚y”!}:c]ฯTญV‹.\ผ`9;็F‘y๐เ5kัส3ฒฃ�Bพ:I’ฤฒฺœ_ๆาa๖ืDฟ๏พฅี>•�ฏ�s•jิฎ๋ฒ๋ข�ทณ|ฒd~ดb้b–�\‡…†ฅหVฐ+fWฬ ใBT?ปr๓สน๓็„…*ŒฒนฎZ7๏ฃส๕ฅ;็Dwฺิ�ะ๓ฎ๔ฉืG@@@@@@@@@@ย›„…แ}ะ?€€€DRFฌ฿บํ—'N\‡ƒz๚์)ญZพœ.œ?๋ฐ $]�ุ�๏๑ใว”ฟM ็—8ฑcำืฝz’ฟpvKž<9ฝ๓ฮ;rwE๘�ฃฉ:ตkQว๖_R‚๑2vŠ;p๐ -^ฒ”Txแa#F‡5V‰]๎&N๘IฎN>ƒFง6ษ%๗ฟL„�๕KšTฎOž2ฦ�4�จรฮo={v—แjยื ๎ุI&Nrถhึ”š‹๚xี�[ทoงaรFู‰ํิ6O—{vJม‡็ๅ0ฝzโpป+—/‘ยูE‚Uฟ�๕อv๙ย Rร†๕)wฎœโ~ˆcœ+Wั�๚X‡�ๅX๘ื�หถ”ฯ?`้gธ2Z…3VยBนผL�[ตkี’แŒี@. ฟN]บั™ณ็Tuํ�‰X4ห‰�9$ถURm๓6ณศิชพปeฉSฅฆๆอS‰โล)A�๘า=‘�ธt๙2UฎZ�ก9พพz�“ส—+KัฃGท��๒ๅK๚ใcดr๕๚m�|c[•*•จiใฦRจi;๓5ฯ.†รFŒ4ฐฦŽฆŒ;็$ค๚4 ซ           ฎ , W�่@@@"/ #�นO”(1ฅ�(ƒ% kื�ฅฟNง็ฯŸGผ}‹ˆ�SฅL)ฮฯ 69ฌ…bูฒe#ฟdI้ฮํ;t้า—„,DK๛QŠ+ฆž9}6D]๔ย๊๘Cฒ%�{๘่,\L6อ‚ฦ8"๒แรG่฿ฏ…dw>ำ_ ™2ฅ'กึคซWฏŠp�A_ |อeศ˜��’าป"�๓ๅ+W‚�ว�ƒ >ฝ3๖g ,tFๅ    กJยยPล‹ฦA"(+aa=T€€€€€€€€€€€@8€ฐ0แฃkˆฬ ,Œฬgว เ) =%‡�@@@@@@@@@@@�!aก;ดP@@@@ ฤ@Xb(ั€@$"aa$:ู8TG†#|t    ‘™„…‘๙์ใุA<%0wฮ,ส’%3�ผu‹J—ญเi3ุ@@@@@@@@@@@‚$aaxฐ@@@@ ด@XZdั.€€€€€€€€€€€€€xGยB๏๘ao @X่!8์             กLยยPŒๆA@@@ฌ @Xhอฅ              � , ๏3€�A@@@ ’€ฐ0’žx6€€€€€€€€€€€€€€ฯ€ฐะ็O   “„…๓ผโจ@@@@@@@@@@@@@�~พ�็G   o% ฿สำ†Aƒ€€€€€€€€€€€€DF‚“ŒC_$aก/žŒ @@@@@@@@@@@@@ˆ ,ฤU    . , ์่@@@@@@@@@@@@@‚%aaฐˆP@@@@ 4@XTั&€€€€€€€€€€€€€xOยB๏ข@X่4์             a@ยย0€Œ.@@@@ @X่ศ%              เ  ,๔…ณ€1€€€€@$$aa$<้8dท‚„…oลiย A@@@ โ€ฐ0โำท๑ˆฬ›K1cFง}๛Rฟ�฿ฦCื1ว‰›bฤŒ)วp๋ึญp :X%Jไา=}๒„>zไR�ˆVษUFฎ�›๚ฝ์*ำย าห—/้าๅหt๙สŸฦหs}�ธฑๅ;u๎F'O๖้๑z:ธิฉRำ?ุže .ขEK–zฺ”ฯ๎็ษต^“%sfJ›65%N”˜n฿นM�s•8^ร ถ฿๐บOฆL๚™โฤ‰KวŽฃƒ~ vœจถๆอCฑcวขƒ‡Žะท}๛…H็๊�{ืฎฝ๔�8็!5‚5’1Cz>lฐ<ช9ฟฬฅy๓Fฐ#ฤแ€€€€€€ภ�Cยยท็\aค    ก@X่�ง3q’$Tฎ|EJ˜ะ&๎นt๙ญ\ด@!A‚TตZMฑOBŠ=บœ<|๘Ž�q„v๎๔ษ>rpŸืมƒ‡จi‹Vฑ\ูา”6MZz$ฤMณ๙ีๅ6ฒeหJE ’๕็ˆ��Fqิ†€5ไ—4)ฝz๕Š )ขวภโ‘FŸ5”|ถmคใ'Nธฬ฿n#‡กาฅJนtw๏�ฃข%\ซ๋RƒขRŽูฉUหTฌHŠ%Š�ญI๓–t่ะaW›๕z�๛บ'ีซ[วฅ~บ๗์Eœึๅ{mลฒ%”$IbY‡“ื*q�Q#‡S�<น้�w฿5ช\ฟqƒJ๋7eV™ ๅหQ‹ๆอ(sฆŒr๓ใว)กขVUCด์ภ�]ฦxฟh๓%ํ�ฝ;ุ๖฿ฦ9๚“|๙ˆEZœfฯ๙…†์qพmทnฆ๘๑ใษa_ป~ส”ซ่s‡Pญj๊ะพ๙๙๙9Œฏ๙}๛Pž_;}fz๚^แะ™›ž�'nvaY]๕{์ุŸิ Qห:‘ฑฐฑxŠ-ๆ�SgฮะฆM›ร มแ{้w�ก#G� FM›…ศ8ิ๛๗žฝ{ฉU๋ถ!าฆซเ�าURแ[ฏ`��4qยOr3fฮฆฃF‡๏€ะ;€€€€€DbFโ“C๐$aaxาw�w๒Pูrๅ)q’คv•n�ผIณฆOฑ+ำW 7žฯš4ยhzฑ‘?r๘m\ฟฮX๗•Œ๚ฐ้ฐpฮฬRˆฤโบœy๒น|h];wขfMห๚ฎ ]\n< *ึซ[›�๗u/ู‹$Zดjขฝ)\ˆฦ#�œ:m:k๛ธข 1Ÿ$0f๔*Qฌ˜Kcปy๓•,SฮฅบมUโุญZ5ง|��UY๘ภ_I฿๖๙ีฎYรฅแ๔๎๓-ญ\นฺi���๚R๕Oซ��๘ใ5l�ิXWcฬ˜>•2eฬ Š์–��๗}๛]?Zนj]9ฏิชQš5kL์จงง/^Pn��zQจไ•p‰wuพ}็่ˆ.,d—ฬŸวตปFX่ฤ‚'_ImZNํฺ~์pjิชCgฮžณฌ็้{…ecnzrŸธัผำชช_ ํฉwิ ฤ�๖{„ฮZDโ�2tฎ“nยย&Š๖@@@@@@ภszฮ{‚€€€xAยB/เ…าฎฅห–ง9sYถœฐฐm๛N"คฐ-$๎�ปw่ฏใว…sแ{”!S&้rยฎ]ฝ’Ž�yฬฒ�๐*Tm!,t� ฌ\ถ˜RฅJ%wlืพ#๎๘��F‚ุ~ƒ€ม7•*U’>ฮ–ี้Q6n�ˆขGณ‰˜.^B�|๏ดฎซ’%๓ฃ๕k‹๏|YXศข“�8=ิE‹—: Uœ/o^š2y‚1Os#ฮ„…=บw.ข d?์บ6iส4bWฺJสSฎ\9e๙ƒจPั2ฏ~XTุ๗�oิช�ยB;^ฏpx์6ญm๎ป›7ouษ™ั๋Nรฐoz๗ขบuj�๕8}ฦ,9ฺ&Bท�+บs๎/s(Z4››็_'OQ`` ธ?J—ลœ9rPี*•EX๎ธaแ›ิQธ;2“SงฯะยษF@ฝฃBXฒW�/C–ghตaah‘Eป      เ> �g†=@@@@B€„…!1„›จYงฅNFถz��=ฺปg'•*S^ฎ%,L-ยืฌ]Wึ{๔่!M?Nๆ๙งŒp?�8‡MฌxS„สœ5cชฑอ2๊ฃ-„…๎ g:ไวArงคบ๕m!‹�k%ฺ่๘๐4Ÿศผuหฦb'›ษ.W�&]Xx็๎]š๛�<ช�ใณหฆ}YX8tุทยฐ๋ฌ–-Y(Bนงั‹œ 7ฎ_KI“$‘uฟ๋7€/]&๓|.๘œจิ๗ป�ดdูrต*� •ฐ๐�๙๓4S„4์-b,…ฐะภ„Œ ึฎZN)RคฐซyZ„‰ญYปž]Yxญดaพ;ul/ป฿ธƒพ์ะษa(์�YฅJ%š7กร6Uู ีqciO@ฝฃBXhฯล�5ผ_zK0l๖‡ฐ0l8ฃp…„…ฎPB'aaˆ#๕บมสUช‘_ฒdดiใzบp�ล‰—Zท�Rถ”ฐฐ^รฦฦ‡�-›7ะม�๛ฑด๙ฒ#ลŠKฎsจเ๑cGัณgฯŒํแQmYX8i๒Tโ๐พ9rๆ D๏ฝG��{v์�พ๋7ะn˜สณoŸ�F;uฝ๛ฎอh฿พ7วฮฎ^�—8 ฉJ?Mฑ^;;ฆKŸŽ�K˜Pnบx๑"]ปv]Uฃ/_R็.�่แฃGF‡N๗QZบu๛6-ข&ยตEO1cฤ ๓Bฌณg๏>๚a๐Pฃ>gXภ0zิpŠ๒Nz๚�u๏�ำฎMฎร‚ช�๛Qิ(Q่๙‹�d˜P.*อ›;‡ฒdฮ,ซ๔�ฆe่ำ ๖wถCfํT็็—ิpDไc>{ๆฌ�n“…[ฺฮ�ปe‹4jVซ&๓ /ฆีkฌรnw๋า‰ฒeต9แ๕0ˆ.\ผ ๗™8แ'Š๕]ฺ+ฮ3ฏ(„“™2e$ํz๒ไiZฝv-�:๗7ป�๕พš‰๓‘^œำ>๘@Šฅฮž;OปvํฆฃF๋Uํ๒|-ตk�šr็ฬII’&‘ืัฃG้฿k�า^q>'O&ฏCป<\ษ&ธv|9�ถ`}"ย�ๆฯŸRฅLE๗๎�ง?OangLU7cวŒค8ฑbำรวจCว.ชุnษืฅ ‹}๘ศหฐี]:uคฌYณ๛-Xธึo4ึ]อTชXž~ds( NPฤcรๆคสํ๗๋?ะฉsŸ ๓ปvํ:š:}†_�a›“ซยBw๚” {๘ฃ‡B๖TXศ.aญZถ#˜6c&ตhf lๅXX\„ฆ+BTsบvํ•)_Iๆ๙‡Eƒ์Jจฯƒ-> –Eํฺ|Aณๆ�Bkืศjป฿.Ÿ พ&,๔tŽึ็.}nQLิRต�@ˆ๐;v๊*‹๋ิฎ%็œW๔Š&L˜L ิฅœbN`็ีฎาัcวhศฐแN็f_ขdqี…ฑ\ฑrl0ึ๕Œ>g~�รTฃz5ส—ฯŸ2คO/็=žฟF๋0จ6J”(NM>kH™ณdฆุโ๎�9ฺฝg/8tH:๒qฝaรFsฌฺฯ›%ป.œo›‡ภ8ยแN…ๅฎ$�_._นโะผ:/< <ŒฺถiMนฤ3>eส”t๗๎=๚Cธ(ณH–Ÿ๗*้l�}ž �แ{ช(<9้โ[ีถณฅ7๏z›&:Fด่ดWผ‡-^ฒ”ิฏG ไœฤ๓L„?��๒หฏvย_}’˜ห\ ฎ๏๏jžŸGmพ๘�ก๚‰ัOใ'8”๋ฯ˜kืoP๑์J(�Ÿ�:y’๚D ๊ีฃ’%ŠQl๑ฮsZผ+t�ช—�ต็ํ3žCŒ7kฺ˜2คKGฑใฤฆจโ}ฏ๙]โd๔ุŸฦซธsN๔k๏๑�–7onูิ๓็�ัแร‡๕fi๛ŽฤnVฉร—ํ(Ÿ^J—๎#Š/žœณO ๎ฤISˆEŠฮRŸoz“�<"d}*z$�…x๎แ๗‚ ?“ฎถrœC‡DR๏฿{๖๎ฅ-[ทQ๑‡H™ณd"�W8u๊4ญ฿ฐ‘๘นdN�Pญฺงฒx€x3฿๗}FEŠข�ณ=ฟ6�yี\ภ;บ๓~i๎฿uพฏ{๗๎!wYดhฑร;_W-[6“�ž0ษ๎�จ๑บ3wqC�๔)"~ุถVอ๊๔กxŸๅ๋‡Ÿำw๎�Žขง‰฿‘ิจ๚jษdะนS๙�ƒดiRหwฺห—/ำฑ?ำเกร้ึญ[ชช�’ว�ตsโyมฯฯO^ฏ‡กย ฝ฿wถ�Cอิ๛ด]ƒXq†8R4    เ  ]กพu\ถุ๋™bD!พพขฑ#‡ Q� 9pซะส›6ฌฃรBxเ+I}ุ|๚๔ฉฟ ็ฌoวฮิถ]ฃจX‘"4N$]Iื…Kc้ฒŒชช?ฃ ˆLีjต์>Œ/]ผ€>J›V๎มใ#†ร��ั๗‹ถํŒฉ\aฺ”I๒C1็ญ”ๆฬœN9r|ฬ›-ทห ฺOแ‚‰?”sบ$>Vฎ๚FPคU๓(๛หฌR,้สฮ,ขdW9N�1~ะ€�2o%Šโ ,�*„ฏัฃG—ยF๑GN.฿นc›�7จg!w�~ัš>oีย—š�`Gว6ํฺ;|Pe‘ฬlม^ oอ๛๑๚˜qใiІDาyฮฺc๑B�iูŠ•F•หษี\ะพCgฺ&ยzšSฏ�ฉaƒ๚ฒุงนsfษฦj_๒Ž�ณZuy9iยx!*๙Dึ%„OVยี˜๙~sUจ๖๗DX่mŸช๏เ–� Yจ3๏ท_ฅk ;F –|Ž8Y�C_|�ŠพlืFn_นj ฑ ˜‹jgLLQ„0Yฅ›7oQษ2ๅิชๅาW……ๆ๓g9๘ื…๚อโ‡ฏล.ณfฯกa#Ÿ,ฦ#ž‘œฮœ=+Bแึ•yณ0Sš~๘Yย๗฿๑'L[H ร?ญZูก|ถr>ากœ Xd�ดIcนํ๖;†ศ]ฏฬยjˆš…H,V๋ัฝซWEีซ;ไ�ต๏HBRฉ]�/D˜g›E8qใฦ!qโPศV"+�™r้า%)(4ว|ฝz๓<6ไG*WถŒ์b้๒๔m฿~ๆ๎,ืฝyฏP ๊ฯ2>g๑โลยฒtjณฑdA=_ปV)ฌ„…ีชVก�ฟsปฯฒ ญ9้ยf๓6ซu25๘ฬv}๋\ฌ๊ช2gฯ.vกไนO�‰ชฏ–�;SZ‰ฆ๔พ]9'๚}ฉฺwถdแ]ทฏzฺmfึ๐aƒ‰฿/ฌ฿ำ,ฮš๓ห\ปอ,›๘๓O†PW฿ศa๏ี{Jh ๕พฬ๙5Bฤึ๓๋�ู๋Œฌฤฏ#‡กาฅJษ}สVจdˆ†๕นภฎA‹��าbณหE๚}อ๏r�NงงFŸ5si7Yิoภ๗ดh๑cณ>^W็.�ู›>y�1ฃFP‰โล8k™๘o v�ฮฯท~}๛X>Kธ!�กฎ�{‹ย๕”'On=b8%H_/vศCX่€      ฆ , S�่ @@@@@€ฐP‘๐�ฅซยยŽ]บKมำgOi�›˜"A‚ิฌek)6y. ฃ 1ง�๛๖ะถ-›}ๆ อ"Žk3d‚5ะz ‚v๘kีขนฺD•+Wขธqโศ๕y๓ๅœa1 จTb’XฑljŸ|’TRv�ปxแขชF/…cกู}Prล…ราถํ�…ธ".•-Sฺ๘่อโ YจฤŒ —งฤ‰mกc๙ฃ2 ใิฉร—ิ๒๕ฑ�+�ซืชc'JTm่ห)“~&vYแR_U๛์’’Aธ�qJ“& ๅŒ8ฑว์นxษ2ใœpm[6RBq�qช!Žใฬูs2ฏ~ wญฏ„†“.ฐิ?�ซบ,�aป�จcๅmfกLนrehุเีnา•eฟpŠŠ-ฎvญโถ9ฌง๎ย9GOำ&O$แ(ฤ‰เ๖‹ญ„seโฤ‰ฅp.ๅ‡J็ฆ‰“ง่ปyœทnืฯ?�#สา}๔‘l›?—bXๅ–ษŽv์lวiรฦโรฐฝห๕น๚ฝย�T a!฿{๋Vฏดอ+BYฌD)cœช}iพฟ#ชฐ็;v๊‡nไ>$ๆด?Œu•Q‚b“rูธ๑โ),์�ซีฏgย้sศโ…๓(ฝ/q;ัขูœ[Yผ’'_ี•ๅ2ฌ……ปvlnf6๗�&อ[:ˆๅิ =ฃูiI 3ฏ]ฟNeสUTMหQร‡RฉR%ๅบ.Š5 Yศณaใ&z๖�9•b vะๅtไศQแ๖ๆู# ลฯCลŠ•ซ~‚XจมษUa!ื}๒ไ mฺผ•ž<}"…q๊™ฦs„๎Tส๗เชหค •๗;+\�๖งย๗“ฟO%„ซฅžฬ๓ฅพอ“�oฟฮกฌย!‘ฯ3<฿ณ๘—ำพ�จEซึ2ฏ�่โ.็น6๐๗O<7ห”.%]ุธ�,L๔๔yาพ][j�yKnR2(ž�ฟ ผšOๅ‹o�+TsVฯ2�๖ืษS๔ทpsไgK๖์ูฤ\r*,t๕>Q}zบdแ[“ฦ6แทก„ฑฎ y~9|๘จ8–ฌฦX๐;ำaแp–9s&)‚ใ๕ยEKH๎V\\}ฦณ›]2•ˆ–]r•{2฿หJlศก฿9ผ9Y๕อuœvศ-Uช„จA๒9วnฆœ๎฿ฟ/œ˜ืสผ๚aWJณ#้‚ys q ฯ#๋ึo ;ท๏H—Nsb~u๊5ฐ{G๚Nยj ืRN<๏ฌ[OOฤ;=฿ำI’$–ๅ�šยB~�>x๐ ฅI›ฦp ๆ>ป๗์ewœž ฝyฟไqx’ผ๙y:wyำ'ฟ๏๒;>'�c1~/ๅ{…ๆู‘ปP‚โ๚yN๙ ูž7Š ฯ_ห—,2จ��“อ[ถศ�ห+VT:r�+_กŠ•mื™ฺwู’…ค�/ฤ�gb๗สX1cษ็Z๔hัT5๙�880'aa˜#G‡    LยB฿ฟ\v๎ึC~œ$B;N?NXณ–Ÿำ{๏%’ ๖ํ�C –ๅ'�:!E พr๔บ๐ศ์�ยฎ|์ฮวI˜ว>gๆ แ๘—]~„ห™ว&„3ืฑZg ‡ึใdๅบb�Grxฬ๚ยีG9ไ่ข1๏XTฎ๔ฤวม.‹�qœ?7ยš8ฑใ‡šqฒŒ?4[9S้mp^ฯ�ธq“J•-oฎb๋>u�8›@r๊ด้ม†�฿ื=E(๋:ฒ�ู"ิ#‡‡ี“.J้�ํ+ฺดษ&p5๘7;T๊ขvvcqšJkV-ฃR| Wอ"!ทhมo๒C+ mุธ)ฑhBฅภญ›)~�xrตv�๚tR„�ำปฟ?~�p�ัทy’ืฏ��็‰“ˆ]ฟTา๙่�˜ฯV!ฺไผ�qนxษ2v"�……u๋7TMฺ-CBXจ aทl�f„’ต๋H[ั๏o.ŽจยBํฒVฎi์8๗uฯฏd]uฏ่๗ถ•cแฐม?ˆ�eๅ>*ฤซ๎bศnL5kึ0Dp%J—3ๆ'‡A‰‚ฐZ!ธ2w็h]ิำA„9�*ฎQ•ไ}๔ฺ1•็เโ%J๗‘>ว๐\�F8ไ๒\ร‰ศ~™=ร˜+๘ูjv|R}๐R†˜็$ฝž.ฮแ๛บi‹Vฦ�ฤฯ3~ฎqโ0้EŠ�ฤผฎฯณfก#ปบ๑5กRH Y ฟY8ฟ๓ฮ;ค?{ุm–ู2ทขล…ฦบ8็�๙๓ิ๐ณ&w�๚5 (๕ใT๗ˆ:.^๊๓ฅ�<แ๓ตp�ฏ†เ๋๒ุ�ฎv"v`ณrไzz๒ไฝย�,c1Z฿~ฅ \ต%sf๙พ2o�BUไKๅ”่ŠฐŠ๙๔P๎‹Dุguฯ(มฯ N๊^1sq็ฏฯ{{๗ํฃ–Ÿ�\[น}� XX]ฉ๊งฯks฿๎ž๕ ใ?t`AtP‰…฿,็ฤโๆ–ญฺุน^๋ฎช๚W๐ฝตn๕ yอ๒ปJวฮ�Œน‹฿cุYY�aJh อ๏Vบ�ฯใ'จ~รFฦกฮ ฯz@IDAT๋s—ีปณ3วBฃ‘q๗�R฿ืผ7"?O็.o๚ิ]a๕kD3_+�"ฆ๒zh$]XxG�ซล„ฐIO๚๕n ๑ว�’%Kศ๊,ุdกJ๚5a�ฆ๊๐R9ไฉ2]ผจส‚[๒y๐๓๓“ีt1ณ�๎�m8Mq%4qV฿\๎I(do๛4มูบ ูY.7;i๑๕ผb้"&5žtoใเœ‚๒�žฯ฿_ึe๖'…ˆT gYฐUญFmZต|‰jึJ,+w~�……บ+* —™“JzศK๓6]Xh%ๆ๘ฆw/bท-NfGZีพZz",\พb}๓m_ี„\*'J^ษ‘�v�9ฏ‡Fo+,าาำŽm›ๅตลeVฯ!ฝฎ;y] ซ‡G�i์h*Zฤ๖‡ }พ�ฮ.Œ;ทฏ‹sฬ�๕นŸล~์‚จRPฯŒ ถ๑�ๆ๗๋^= ‡LีฆZ๒๓โ฿๔q“ซํผ๔ไฝB?nร์ยศeพšิ๓ะaแ€๏  ‘ฒš฿ฯ๘=]ู”“๗šนธ๚Œ็6ถlZoˆฅ5mๆเ�ช?ื”เš๗Sษ�ทป็Dฝฃบ",Tื ๗�ฝGO๑ปสญ]ตB>uมฐฮัช��1ด„…fYๆฦ์cฤˆ!Qr่]%T‹ŒยBwๆ.o„…พlGŸทj!™ฏ]@=z๕–๙เ~ิ{ฯำงOฉ|ฅชTPฃฺงฤยVN๚3Nป๒�i๘�6zš9m ๅฮKAXจ“A@@@@@ยž„…aฯ=‚€€€๚�eเŠฐ0~�ิฒตอมๅŽซอ™9ฺ|ูQŠฐn�ธNณgLฃŒ3QๅOซห�็๏ฟ…ำฯlŸ9x๕ั–รม–ฏ\ีn\บะfแโ%ิภ๗v�ีŠ๚˜หN/aๅXXตZ-;'‹.TT�ีีr๚”ษ”Wธ่)pว๏Rข—Yๅู‰i้โ๙๒ฃ๔ƒจฌ$ฉฝV๕ฝ-ำ…{ฎ8rบˆคc—nดeหV9 ฬขNณfฯกa#l!ปy]�๐ฯa2•ะŠทฉคฮ1ฏ+ ."โrพ†8ฑฃ–Jษ�Ofฌ›ใV.[LฉRฅ’UYนV8Yํูป_„|�*\uaกUhfศก�{d๘E‹]ถขMษๅ๚‡j]€ฃ�็Pช%…Kณk‚๋พ๗:ค+ทฉ\i8๏Jาuวฒ ๖e]์Xถ๐ทฯ�{๎เ&ิพผอaกท}7&ต]rv n•.Š๐ฺ๚9ัEขฝ๛|K+Wฎ–ป้๓•cก.,dัJญZ5eธJ9สnง์ขง_ำ‘QXศื๘ๆฤ‚{ณป็�_fSถฌY$๋๖:ำถภ@ใt้ยยA?ก฿ๆอ7ถqFŸ uQ]ฅื+ž ๛‰g�"๑Œำปลrฟ,บ็9Qนใ*A่ฃGฉ@a๛p˜ผ�˜ั#Œศ!),ิ„u‘>[…jืŸ e+Tr˜~�J๖๙ฬูณTฃV]Gฯี;ฝ5hP8”5็อ‰8,tึE์z๕ฬq็ฝB–๑|�Iม"z“>wGXุซ๗�DXเu"”ui1ฬๆvฦaˆYDอ๎ฬ|ญpR๓›ฮลg<ทก�…7ื'NžB?ŸภปI๏�“sข๚ท�ผฮ่"H๏ แขศIฝ“๐’฿ITRฎฒบs'ŸCO๚ณ!4„…ทn฿ฆฅlnธzฟำฆL๎xyd‹~•ำgdบ3w้๏k์$Š.�{สƒแPศส*eส”ฤb“ษวำฃ‡ํ ฯœ9Mห—,๒™ƒWmญ>–๊ห๘#6ฬถJžธ]hฮอ�—๎Xจ;Hฉzอ›5ก.:สีษSฆัุŸ์?&๒�}ื?~Lฅส”ทqนU๊฿ฏ/U�ิ&พด iต7eบ˜ฦUaaฺตจฯ�พ–�ฒจล…œ6ฌ!ฟคIeธ๊Oซืถe๊�uัœ�๑๕ฯุ1#ฉxQ›ˆF…ำี]ฤ๔บฮ๒›7oกN]ป›kีจN,(2'�˜หขฃ๑ใ'าอu’8ฑ�,1‹vนข.,ิัฒ๑รแk็อ#WYภษ‚4gษaก•Pw"Uข}ฎผt๙2Uฎj๛ƒ},ƒ *•+ส"ซv๕บ๎ไ๗๎ฺaธ—ฑธ๛ถ#qJ“6 q˜uN,x/Tด„ฬซ]Xh๕��ผ!@†yต๚ใOž'ช_}ษยย"ยUฑL้’2TตฺvP„FๆิVษ“๗ ��\ธx๘�–ไŽฐPนี๊*%6ฬ“'7อ˜:Yถ๊\�yฦ๋๗ญณ�tทฟ+Wั�๚ุ;๊}{rNิ;jpยBฝWฮ9ฟgฐห2‹ล๔๙ว,4ใถxN็น“ีปฒ�เม:ถSงฯPญ:๕Z>t0•-csV๎*�ŸมยaN‘QX่ฮ�ฅ฿๎ ™๏ฒ% )mš4œตK�ณ๙Eบๆ๊tทkฝ�Y^’.Y4_<?’UีsF฿Oฟฟ ,ิษ      aOยยฐgŽA@@@ }�2pUXุฉ๋WาๅŒล„QขD‘ถ{ืN๚=p›ฬ)Vœ๒}b)>t€6mX๏3ฏ>lZ}เื?*ฟ ยยvmฟ 6ญm‚ณ+Ÿฮข“I~2ฮปQ5nึยฉk’ฺ?,ฌYIัฃG—N\ๅ*V1ฌT^z",ไ1(ชg"wq๎ื_„o+\ด8Yg�ƒ�ัฃะgMšษบ๚ฯดษE;ye‘rำ…–ป๗์ฅm�฿8้๛ช�_"t์žฝ{ีช\ฒ _‹ฆM({๖lาๅS฿ศ�9,�ด3๕b๓บฐpๆฌู4|ไh‡ถ๖๏ูEั„ณ '๓‡์/�ต!v6โฤŽj์ฌฦ‚คqrE++z๐cฤึจUG8Œ๓ %๗v‰hยยA๚ห๐กL#/็ •'JL™3e”ซฯ…ำีž}{ฅภดCว.ฒฌwฏTฟžฝฃปqdๅˆธoฯNŠ-šฅ0U๕ฃ–UX˜/o^š:eข<ฬโžฏ[ฟ!}ีญ 5n๔™,ณz่ย5ฟ(Nผิ……VขOฝฎ'ยBซ{ืJXจ Œ.]บ$œˆk่]ห�Q…๒ๅd>ค„…๎Wฬ}*a!ฟŸไส๛‰รxƒrewŸ'˜ š4nD�ปv–ฅ��5 ธUuo……๛๖ํ—Nขช=__บ#,Tโ[�ก{ฯ^ฐ‚บ๓Œื๏;g๛๑ตฮื<'+qฝ�~แษ9Q๏จม ๕{“ฏซ‘ฃmฎNฯปxฟเ?แคฟห(1ดพŸ~ ก!,t&ฺTฎฉ<u~9œฐPwๅตซq๚ตใ๊ฎ๐~๎ฆเD~บใชYิ้้�ๅMŸ๊๘Z4k*œ R’$‰U‘ฑผ๚ฯUชQปฎ๑�ื]ฏ�}E„$ทw�5v|น{๗-_ฑJฎ้.วVŒ ฿_šIb@@@@@ย–„…aหฝ€€€ผ&aก๏_ ฎ �w๊*ฤHัŒบ๏M™๔ณฑ�iZ”.]zนพ}๋fฺทwฑ-ผ3๊ฃญ•เฬ—……Vเta!‡๚eqกž๘ร๓�฿~‘ฮ}z๙฿"อ™้�{…�,๓DฤๆlผaQVยBwž๑|�;wl#ๆ๊l?=D�ƒ‡า�฿ๆูแ๒๖œจwTgฯdฝ3๚ณภ›“.ฤำ๋Xๅkีจ.ร!๓ถ€€๕ย๐kปju๋ิฆoz๗’eก!,ไ�7X ฎ•›(wฌฟ้ยB๎Z๐ฦ๕k)i’$ฒศู�ๅ้๛ฅ�+y]ไg*[w† aกป}uL๚X๕?0าฏ๑ปw๏Qัฅ‚jฦn� จJๅŠฒŒ]ฐ๙๙ฆ'�ยB ๒      ๖ , {ๆ่@@@@@€ฐะ๗/W……�๙๒Sัโ%ไ™� “'ON๕6ฆw�y‡=zHว๓ฉWmฝ๊aืฺถ๋@;v๎t้๕h์�ม A%]XhvฏaจๅKI79�Uจ\ีฮKw3ผy๓ีช[_†ผ]4ลOv;r๔š>c–รtท8ณ˜ศกr่ป#GŽŠๅอ]n}มผน”)cป๚V‚ฎ ๅu๓นะ?บs๘ุJUชq5bHˆฤŒSฎ[…0ๅ �~แย g7YY�ฐ`ๅุฑ?ีชฑไ๚�6SิจQeYมยล,�$�็่ยBnุ|ญ๊xู๙ฐwŸo1ฉŒ.ฆTeฮjปZ๊a“นฬU—ว‚๙๓ �8=y๒„J–.gษCV0�จ๛[%ผTu๔ฅ'ยBo๛ิ๛*๏‰ฐ0จ๖t•ณpปึŽง๚G~พf.˜Kค๘@vaๅบg๎๛mบ;Gซcd[…ภŽรB๋ษJฮ�uaแฝ{๗ฉ|ลสvืธ๎€hๅบช๗ฺยย๏๚~C5ซW—]šคอš6ฆฎ;ร aก๎ึศฯฎ’eสํ๋u=qปDrxUN� น wž'ฅJ•คชB(3i๒4c �†J<‡�ฃ|'rๆ๚ศu=yฏเ๋Ž…pœ ,๗ีw�iษฒๅ?ใ™ฃrŽ”๙_ๆาaร9+ป๘ฎZพ”ขG.ื›4oI�nฆ'oฯษ–M๋)ั{๏‰๗็วTบlyปyA๏‡๓�๛บ—ุึ–ลV๏ดช~ฎ\9‰฿ีฯœ='‹tทY~ฦVจ�ฉ�Wฬ�ํWสœ)ฃฌยBn˜ร26B๖ม?UชTขA๚ห๕�ฝF,TI'3 !ซUญB๚งชส�xs๒ๆ�า�VP๋|ฌ_ปZV๙๗๊ฟTVฬํ*๑{๛ฒ%‹ไป8—…”ฐะ›>๙ฝ6vฌXฤ๏บๆิ็›�TงVMYlvฝึEญVฮช-vณ�ปgฏq๋ฯXsHl๓;ถ�ฮกฺร@@@@@@ ์@Xvฌั€€€€€FยB †e3gอ&�†l๎ƒัcDงผ�Ÿศั=z๔ˆ<`Œ๔่‘ร๔๐แcฝc—๎†๊ฃGhำ๚๒ิjŠป๊ฃ๋��{i�ๆMฦ>พQ" ซฐ๚‡วีkึQฏ��ณr๗ฎฉIใFr�uแิธpแbbg#\�พu‡v๎�mน_ฑ"Eh�ุQr�ำงOi‰ั{โฤ_๔ไ้๚Oˆ6ุํง y‡ฤไพโฦ‹C]:vคd๏'“๕7mฺLป}e์หยฌ๑?‘็็ีซWิกcฺ(ทW(_Žุ„‡ฯkู๚ ‡ใ›ึฏฃ$Iห: 5ฑรษก๐ฃ\Œธ้›6Iฑ;rฺต{ฏ�วoY๘๚G�Xฉส]�๐ฯu™ั๔™ณh๗ฎ=”)sFj฿ฎญq ๓‡o�ฎok�yKนส็›๘ถ๎ŽZ๗(UชTา!ฒ|ู2K|จี‚ชO)ผj๕แ๚u€ฎ_ฟNYณdกJ*P�ผนe›ฆš?๒[%o……,ja1๋ฅ‹—จŒปจฦ|�u๊5 “งN[uKบW`!-‹ƒKž ‡ ๙‘ส †œฬ"‚เ๚T๗ทชœฐ0KๆฬTฏžอ๙Œ๗)]ฒ$%H_๎ฮ.ŸE8LN,`—FซไnŸVmธRยB=$๚ณ็ฯi†"ณ{\น2ฅ ืึPกข%]‰���๒šีm].ะร“๏ฺต›ึฎ 0๊…gฦ�9Zซ. ใ๒ œœta!ื={๎�y=}๚œš6iD�y๓p1]ปvM:ชส•ื?,พเp๏*ๅ.ดŸทj!W๙ู๓๋ฏoิx%ธ๋ึฅ“h�R�‹6_:<งtw*�๕Kฑs'G�A;~ง๗“ฟO,๊‰%ŠŠe˜R�่ฮ�ีซGwjุ พl“ฏ‹ฝzํ๋™๑ใฦปqาEห!!,t็yยฯ~.๐<๚๛ฎ]ฤ๏็…๛งPRก‚…;W%Cpบu๛v๙<–ƒ6�x๒^กž+�”ฏ ูUO.œ_ฃพ�ัุ๔Lผ๑uฌ;ฆv์าถlู*ฯ7ŸwN�{๖’๏LบCœ3aก;ฯxŠŽ>ิ;ชm�ผ•'ML;ด—!ฮyฃี;$—{{N~=“ฒgฯฦMษ{—ชo฿พ%รชŸ>}ฦ๎9อ}ญYฝยp ๅyd๚๔™t๎ยyŠ'eโภŠ+ศ?บ0�กลค ใฉ@~�๛>‡‹=๎'z๒่ }ึจ๑;คJก%,ไ๖YถcวNJŸ>uŽฏ๊6๔ฐป\Oมณ�แฬYsˆEฮูณea…›๏k\WŸปx]Ožพ_๊mธ’ืฏู|แ‚ล๒š�เวฯฯฯh"ค„…� ง}ฒ8ตnZดO8ัฎ]ทžN>Mqbล&�|yฉAฝz2ิ6ท?pะ4มBฮสค ฺน€฿ƒ—,]N�\�‡’%KF�\โนฯ/iR2 ์๕ฑ๒๛ไ\๑ฬŠ;&u๎ุ๘yฃ„…Š–      > , ๎่@@@"= }๓h�พ“๑1/จnฺฐŽ:dTaืย"ลŠKฃPห�ฝ{—fL$?†jลแžU" ซยฎ ูdลาล–�XhXบlงวนhม<ส >ขZฅชีjู…6 ญ๖aQOณญŒอ,:Y(�๛”0pŽษq‡�่๗�ทTฃšMผฦa$kิฎkธ‰4จ_พ๎i)ฒฐชล็_XujeบCŠนซฐƒช`฿ผ1ภ8'gฮžฅต๊ชอvK�รฟ�ำ คฏ^๓่LmึCVช2ซฅ•ฐะชž^ฦฎ์h•�็๐�fวBซ6นฬ*tž^W$q9 nYx\๒DXศ็†ร *qฒ34g}ซ๛[mNXXฟ^]๊�ซ‡ช๎tiทชWtทO}_w๒แ!,ไ๓1Mฬใ,ภดJ,N๎ำทฏๅ๕ ‡ ตฺW•ญYปŽz~m-โVuยr้ฮญK%r๙ยลKจ�€๏๕*F�,,46hะ 8ˆ-Yช•’tdง@W’NUฟ�r?-›7ฃŽ"์5;•œ�ฏ๎ฬ]z่e%ณ๊S�้ฮW!!,t็yข„…Vcิหn�พM5kืs*Ž๗ไฝB–๙ฒฐPCซ3q–็g'‹’•๘ะ[aกณ~œ=ใงL๚Y�‘€ณ�?~Lm�wค:T๑๖œ่�an|�†ิํซžvล�œ�๎�>ฦป�Fmล,,ฬ‘#;M๚๙gC8ฆUตห†ฆฐะฎฃื+็„(ทZ › ฃพ]�ืz™U>(aกง๏—V�UฆฯตAี Iaกง}๊ฎ—ฮฦ๊์œ่"pg๛rนYXศsw๗n]‚}ž@XUlะ'aa่3F     ,ด€โEmฟยยXถะฎA gCภ::zไฐ๋ๆฮใOE‹• จ๏ฺBธr;ร�ผyƒfฯ˜ฦซ>—๖์ ”`ญ\ืุ)cๅ๒%า‰ล�๚t:�ิฉRS๓ๆฉD๑โ” ~|รฝ๑’p8ซ\ตบำ�X๘ื�หถ”ฯ?p๒๐“ฮv\ู*œฑrHผeห—SํZตŒjผฯล‹ฉ“p๒QแํธŒรR*ั‰.ถเmzRmsูฯ&nlซV,ฅ”~(ซ:‰่ํ„Fพe‹ๆTฑByJ&œ]”{๗”ศ„ท๋žG�‰ฆN›ฮลI�๐ฯย๐ไaJ4ฃœงบw๏i.อดhึ”Zฑ +ญoฟp๑m�บ†ฅำ˜Q#(wฎ\vวค*๐u3qาdโpsฮ’•€ล™+#ทก น]แŠ˜"E ฃy…�:w. 9ฺ(ณส่‚ฉ;B0\ฌDiซjeำฆL2œืxcP็Dํฌ๗”˜Oี7/๗๎ฺA1bฤ0Šƒโร•ฬaMgึนšป}ššvy๕ซ๎]‰?ศs2 \nDซศB๊ล ็ห๋>(1฿/#F %�i�จeศ^:๐q่ฬ;wัป"�ณช[…†ๅ>�™ป๖ํ�] ‹y^.%D๚์๒j•๘yฝzๅ2นI1ุัธc็ฎzs>“ื]ƒิณgฯศ?!าCb+!,‡๔5}ชlข}‡ฮา‰™Eฯ๓ๆฮ‘eสล0$ž๑์ Y_�ก…9ผ9‹u{}��๎ฝห|L�ž“ยย้ฒaร๚โ}!'ล๓‚z7q๖G|�๔�ฎt‘๕อ๛8‹C๏�ป—~�ๅ7—RfวNฅ๚{๓g็&>“๏ง{ฤพ,ะ‰ค๎mvคไ๛ปPฦฑ๑{ืn2ทKื๎–๏]|ฟ๏P๚ๆฐภsฅp€Ž#fs—>๖–พ_๊mธ’>t0•ฮพ*๑;�กCย�}หb'`Nๆ?า๐v๎๒คOž๓›6n,น๊๎ณ<>9w รa#F:‡๙ญgฯ๎ฦ�x?•x๎Ž”„�ณ9ิ2?3zwZพWUb—฿_๛อxพฑK4�� @@@@@@ |@X>�ั+€€€DzF�Kภฯ/eฮš•n ทพ�I/^พˆธ†GฆฤEXjv๐แฤœใฤ‹C‡ Vคเ๎P9t้ ไn'�:Iu๋�DL๎ถ๕๙ใคrบcม\ฑฅ,?N๓ุtั˜rYAม๖น๗บO„ุcๆฎ$v™สœ)3ล็ไ฿ซืD่�Kมžข$Ožœพ—๎�น'\*/ู9Uบาฏ+utaแ˜qใiสิiฤ„?ฮJ งJ+ท%ซvูั�8อ›ฟพ�แMุJซ๚(‹ธ8Df‚„ ่ pฏ N$q)X™B•รŠืฎk ็kU[*"‡๛L›6 s/๏๏ห‰็K5GNœ๐“:ตD้rN(พ|<ๆฑน๓<ั๗e๑‹ด��’ะฃวO่ฒ1๋๋็RDษ‡ไ3>ฃาrจ�ปโY}่๐aใบ๗UVrI“š<|D ๑ฏ+ื_ทYณeก๛w๏;ˆC๓8๙<ๅ/Ÿ^�๗ยๅ๗.~โฯ7n�"=๚rโ๗รl"\3‹(๗ ัคš3Csฬž๖ษ็"Cฦ b๎JJ๏ q* ฯœ>๋๒˜y>VฟdI้ฮํ;t้า—�kY�š.�Gฒ/�c($฿!aก๏œ Œ@@@" #ี้ฦม†+aa4๋ด �aฮบฬูNโEr๎ฆ—ยฝลโำ�6๔๚บ๘mห–ญฤก%+ัณบosน•ฐะ�ใแิK/4\eX,ๅŠPม�~P�v์šฦ" NC‡คูs~qzH}ฟ�†jีฐ9�*aกำส>ฐ็LNfa ’–/]D๏พ๛.ฑหbแb%}`ด�ม็‰๗ฝก…&Yž๑!อ ํ€€€€€€€€"aก"%€€€€@˜€ฐ0Lqฃณ@ ฌ……์f็—4‰$ทw�~—.˜7—2 —ORีjต\r4qึ6‡WไะยE ขO�ชƒŒ$ƒ,ฯ๘Hr:q˜       แ@ยยp€Ž.A@@@ˆ ,ฤU๎kaก{ฃณีOaแ๐กƒฉl™าvร^บ|}�ทŸ]™y%ฒˆ<ฒภtลฒEvุ๎�ฝG-?o ทB;*X‰์6ฎ_KI“ุฤุฬ‚C^๖๋?–,[$šทMXh5ื๊xแโbก๘�œฌŽั•็ษ�|ฬu์‘ๅQฯŽ @@@@@@@ � @X�็#HIยยHyฺqะ^˜;geษ’™n�บEฅหV๐ขฅะ�•Eh‰“ุซ�้…8‡vg‡บ�๛๕ฅOซT–bž3gฯI7ญฑ?wจg.`ัมึอd๘ฮ›6SทฏzšซDˆ๕โลŠั่‘รไฑ 6‚~๛›Kวลแืฌ\NQขDกป๗๎ั‘ฃGi�๘‰t�ฤ —๖G%ˆ,V.[L~๘!=}๚”Ž?A —,ก•+W{๘_u๏JŸ5จOฏ^ฝ"/ฮ๓—/งzukSํZต(}บ(jิจrจ<๖kืฎำฦM›่ว!ถyฦ—!ธฑy๚< ฎ]l{‘ๅ๖dั#€€€€€€€@d!aad9ำ8N๐1๚ุ มp@@@@ภ �ฝ„ |^ ้ฦ!ก*€€€€€€€€€€FยB ฒ    aGยยฐcž@@@@@@@@@@@@@@ภบC uA@@@BŒ„…!† €€€€€€€€€€€€€@ˆ€ฐ0Dqข1W @X่*)ิฐ%aaุ๒Fo    ฏ @XˆK@@@@@@@@@@@@@|“„…พy^0*ˆ๐ ,Œ๐ง             ๐–€ฐ๐-=q6€€€ผํ ,|�ฯ ฦ             Q @XQฯ,Ž @@@|œ„…>~‚0<HKยยH{๊qเ    พ , _�่@@@@@@@@@@@@@œ€ฐะ”ƒ€€€„* C/ @X่1:์    เ  ฝก‡}A@@|™ภ;bpQ�แ_ข/_ูฒr?�ˆ๚š+ท๒โ•`‹         * , ฌh@@@@ 8G�A@@�Fฌ!)๊t๗า“/œn(bE}—F็+lฮสห็i๙ๅ ฦzxgxN9Rตž1ŒซQู +Œ๕ศ˜,ปtŽV]ฑžใBข?_iฃvชจoฮ|ฦp> \OGnCXh1eF๘ขธ๏F“ฅwŸ=ฅฏ์2ี฿U�๙+อ'๕‚๐z ,ฤe    . , ์.wš8I*Wพ"%L˜H๎sI6V.[์�ัฃGงฒbฟ”ฉR ฑึ;๔Hˆ)fN›์~พPล e’(‡2�ฯCt๊�=๚,m*๊—\– ;v˜N?ธ๋0ิ˜Qฃา(›ภๅ๎ณgิ๓เ.Š#D/รลว|NwDY/QfNuSงฃ>9�อลt๋้*ฐฬกฎ˜R ๅOšฬก๒ฌ3ัPq^อ)}�ดคdsฑ\g1ะ™๛wiๅ• ด๖ส%๚๏ีKหz(ฐ" Z4 ฌPำiwลื-ฅ[B<š)aด่”6^|ฃ‹ฃBิึ๗F’1hsน๊ฦๆ?E0ึร;ใฉฐ0Gยฤ5ŠMYu๋ษSบ๐่พำC13˜s๖/|ฬqŽsฺภ[บมaa4ม4ป`ซาY1ฏ฿}�\ญF่ๅQMเ๚โๅKสตjAธ/ฟ3ๅ~/ K–œ*}šลˆiŒ็�๓gThํc๐'aa๘ŸŒ@@@"% }๓ด'O๑•-Wž'Ij7ภ›7oาฌ้S์ส๔•8qโRน )U๊4E8jฉ๔฿�ัุQรีชO/7–�”�bฦ’cฌณuธw‡หื B,ษฉๆ–5Rl(WดŸ�‰’ะฌยฅeษ™{wฉ๚ึตT@8ๆM.XR–�u๗ี�ถN�ร–ต๒G�๓๎ห6v@K†ๆ)@e“งคw„6G…!ๅ 3วOH Š—ถํgยฎๆ–uA }‚m@ภKพ ,l‘.3uษšำ8gsฃQ!2fQ]Dฒ๘ํ@ๅบญใwnS�ํฦบ9cfaก™ะ›๕L๑ะยโoไC…s–bF†ไkยยjฆกน฿„ฒึฯ?g๓ฎ^จ!        ฮ , ็€๎A@@@ ฒ€ฐะ๗ฮ|้ฒๅ)Gฮ\– JX˜6ํG๔iZv‚Bีศ�",Œ-tvWชญ†MyVอ'3นCsหฝrฅ+Wื,9ฉy๚ฬr฿‘ฆigNP๏์yจp;ไ4ไƒ4๛�I™ืฬยย\+็ำ Pฏ…ผ7tA…ทยBว'Od8ำฐvg๓†๖`DŒ๎ฬ 58OA๚Hs วB �Af>I์Gั^ ํูอ๖ปA‡๋…ฐ0HœฦFvฬฬ๖ฺM™ ๗฿บl๘o m๘|มฑยBใRF@@@@@@@� พง ƒˆGยB฿;ง5๋ิฃิยqำ�{๗h๏žTชŒอษ-(aแว9rQแrศ้ฉมy่ภส“ืŸข‰o‹ฐPw<%\kš\�พAŸn”วh�ัkmYK'EˆE�้ฐฺๆีtVธš„…f"!ฟ๎‰ฐpฯiิ๑#”8zLช“&ื˜ยn`7ะแ�7ํส|bEฮD๔q$g"(Ÿน>กj)ำG aกโญห@Xzงฬ'„…แ4้ฯA_ปsหN$ วยะปะ2€€€€€€€xJยBOษa?ฏ@X่พPูนr•jไ—,mฺธž.œ?G�ธu�/e_A 3eฮBฅJ—“Bฤ}{๗ศ๚ํ;u๕yaแGqใQ<แ|ฤฉนํY:๙‡2ฯฮR_๎ูFm2dฃ"ษ’ห2vช๋ผ/.=|@๗�{FY$’ๅ‰cฤคั๙Šศ<�|{h=|๑ ฯ[ศ(๋น']~๔ŽฐM~y*,ฬ.๚ฎ๔Aj*”4ฅแฏ>~D๛n\ฃMWฏะ๚.�๕a Bพส–K„ถ•œBวฅฯQ’ฐ๊‡ฉษ_„nพ��m๙๗ �ใ�y•ธฟสฆRซ4แไ1๚ V\น/—'กขฯ�ฟO3EXษ%—ฮ๕8“8F j˜&#H๊G9�KBทž>กื�ก๕_ฆอ��mWW_ฉ“*pa‹'‹^ŠฑBฟbโ\TL‘’Jฝo;O‡„ุs๘ฑร๔็ฝ�๚ฎvy]Pแชc!‹ งž>nด3ฺฟ0•z}mpแ€#๛h�…3ฦvo๘ฐจ~๊ โ\พOŸˆs๐โีKฺs๓:ํธ๖-ธpึา!ำ่Xd๒$JJUฤต_์›J\ฯฯ_ผคำBุบ๊สZz้,�}�\ฏ.๓�g�ิ้ล>ษdศ๎่Qข กไ ฺw๓q(U��๋;ณƒgCแยY๊�”I„Ž!ึ๙šน(๎‰m��C+ฏœ—y}•�Xธ‹ฑซ'ณJ;ฑธๅ๊“GtL„z ๘็mืmhธuzสวsยŽฅฬ๔๑/่าฃิ.SvŠ๓๎ป4C8—ฮ>{Šพ�8/•O‘Jฮฟž;EO�ฉฐP้๗? �ฤoยฮ9๑‡ธฦS A๋G”=ab:|๋&ญธ|žๆ?m}_‹–<๒ฝYO\ฤuใฝฤ๔Xฬ[{ลตทGฬ%ฟ‰�ฬฎœํ_ž็ŸDb๎S‰ลA…kœJงฤ5ธXฬ/ๆไnŸrq�ืO›Ž*ฅHMน+��…Sด๛๚5Z[ฆŠั…ทก“ลŒEอาe’ํ=ื'ฯAฅYs‹p๋bp"M๓ลองO)ฉ#ทศ`sฏ5๏๛ฯใว–กw“วŠMM>ส(ซ'yใฎ'พ'๕4�ฏcโZฒ�ืVก—‹๋ๅณดๅuฤฯขอW/ำ๗Gะ3qL!™�G˜-3V้๘��ด�๒ตJ๕…ˆ;u�œฯ…็< yฤu�:ตฯ่$1฿\sชœ—Šฟ^ฦ๙ยb^-โ๗พ,ฮ+ฎ,ฏŸ�\ภฯ๔ตฟ้�…xะ Žร๚3Z๎่อธ<ชคLMล�’‹๙=™ผgŠsวื๐�๓งฤ3๐ =็œ)y๚�,$๚จ›&=��s๓B๑œšqๆ/ฺSฉ–ัƒ3aกG๏Fซ๎e๘Y’อuฌ,ฆ^ศyŸ/…ฐฑ๏แฝB”x�ฎน๗…เi]้สNฯ%Wพ(ฤช•…;ง]š™Q๙ ข]ปmฺJ�ญt<จVีฅฌง|�='|OฉZฯฅ1ฉJ๗าF!ๆ4L„1ึฯแ!Š๛Z์ฌ๊๓rซแv๗Šฃษ3a!‹Qฟฯ�‰ำ๓y[8ฯ6฿ฑ‰ฮ<ธg Cฟ—ŒB'™?๎�ค�7ุm๕คOๆ;น@ ส/Dิม%o……9�KDฟ)kt“CฬeVผนBt1งํฏRวจ[sห:u�๙ ก๏๔ยฅŒr=ร๗sู +๔"™g๑�„ลส่ธfaกณ}Xะ]"`™ำใqถŸณrOๆซ๐ท%–JAfŠXqh&ๅ~๕๛„ืu`^ืำg๋…p฿1ฬt฿�T;u:ฝj๙�+8jƒ�!ˆ|nฆ,eฆ�\��,แํž>7�eฬFm…๘ืœ๘!RŠ?Qษ,,๔ๆฝBต้ํยBo b]†._ด    เ„„…Nภ๘P1„…Ž'#<……2}Lญ3fu”ฉไภอkิ๔๗อvฅ,ด2 ํ*h+ม ตชY%,ฬ/-*Qมaปน€๙ฺ์�f.&ณฐะกย๋‚ฐถฮ…:dฮa aฬ‰#4๙ิGCณฐะจh‘Q|X˜ดณbMŠ5ชEญ7E,4+บn™ƒุeจlVโฐ ’YXศ.Q;+ิ จQฌ…žz[ี7ฏฑ•m.[อฉ[˜ฺฯJX˜/ฑM+TRUqบ iaก'|<9'ž 7 ัng!�ๅd:$6tยB+—Ow อ:g}>nw…ึ,กgBlสษaกง}Vnช?ไ.เlˆvๅ� ฿‚ฮmโ�Pฉฺุ%N�;ูyoCูOUU*ฐz‘s๛ชฐฺfืVแ{ีณงoๆ‘ ๙‹Qaแฆงา6!˜�R\ืs —ฆœ‰’จbา๏U๘6 y^ุไยœiz๚�dืห€2Uช —faก7๏AvไฦF �€…ช         , ่่@@@@€ยB฿ฟ "บฐฐFสด"_bแ˜[ฑซิย๓‹ŒY 7ฏDcๅเ(„p�ก&3Qt!ึk™แะoลๅstM„Wl™>‹qrน์๒รGย)๊• !ฌ;`นใXhฝp ฮŸกียฑ/งcฺJƒ๎tึ(pƒo+B/ฟNฮ„…WD่ึๅย๎๏ว)[‚ฤ"ไhzrUXศขพ=7ฎ‹†QฉvชdXf)œนฌdE;งฆS๗๎สpฎ,ศ๙�$ŽฌปmpOผฃ†*—VยB!นL„Zๆš|�8|(Ÿv,œ|๒Osโจ�Eก�B์2Iธ‰้ฎ‹fŽ3aกS>โป‰๐นอDh`•‹cใpฯœพ!Vฃ‰พU2‡fN7-)i/ฺ<#๘Ž๙๋(=ํpX�/DoNy…KฆJ�r๚SMbZฅหยษjœุ็ฎ/6ฎ”…sšJg…๛Z5แยฦ‰…Dz(MœU฿ฒV\๋ลถจ”!^B๊‘-ท �kv,�ๆใžžณฐCโ�โb�๙ฎจpพK3&-.QQ"‹~rŠน‚“YXx๘ึMjดรBุJ๔๓‰8'ล9ั“;ยBaปฌd%cwy\lํR">‘’FI›„˜O%yใ7งBุีEURก€ีบพ๔ดOž‹+ผ™Kนอ"k !์s9�•โ8Ri"Hฏ……ข�ลล+P†๘6!ฺื"ฤ๚J!žž_ดeI๘ž<$ๅฐฺH<zพŽฑ0ณๅฮ-rป�cพ6œ ๕}ฬ๓๔๑;ทฉ๎๖ฝŠ]�JX˜_ˆ‰‰๙;]�๘ดTผUฒrT�\]z3จ>X?งHต๊ฐlฐm=�qW{ถ8ิ )d๏›3Ÿฑล™ฐะจ 2™ฤy](ฮฏJ�|ไ็dhค]โ@OŽ.ท“4—[๎3YŒX”HŽ•จ�›็ๆ�Jตํ�oฟืใ๏โบไdžuaกท๏ฒƒ๘ฐ0 ข E†"\4     เœ„…ฮู๘ส–ศ",�Vพบt๋b๎Jเฅ‡]ฌฒq5]xd}้็†ฉฆพ๓ชA’๘ัไ‚%e5vŽj๒๛&}ปผ;ยยAน?1ฯธM๘๋ฝร๊‘ุAซดชt๘ึ !PฺจVฅ่ห Y PŒJN2fแ\pฮWy%ฅ™…Kญ™E์ะตKd๊๎xj'ณฐฐqเF:$ฆ�M!-,TยS}๎๒1?ป V฿บVo’ึ‹ฐ–บ[]^!DS^๓‹•ฅ, ๕+ ป‹BะTJ$�่ถŠ๋\O?�q€X๓ชฎกฏฒๆ2œ;น^Uั. Eอb'ีปPฮ9{RXฎJ76Uฎ/อlx %^^>OŠ๙ฬยB]ฤ•ง,a็ฬW&`9�๛๔ฑัg�–bำ1Ÿต�Ÿฏiu ฤˆีN0ศญฤั๎ =ํ“�๛V•ชlŒu“ธ^:ฝ!อ…Rคขกy �CBXศ๗@“t™d›ณฯœBไƒv็WŠฒฤฝ84๏›Pไๆ๙M (<„…,j-น�ๆ†[ˆ�๕๋%��ลผ@IDAT‹ฐร�$oๆฝ฿žูrQ#แ’jNฮฤ฿ๆz์๋ซยBณ๘’็ป|kฺ ๘อวร๋ž>7อืู3!*อปJ8ีพ~7`ใ†roยv๋ยBo฿+ฌŽร“2 =ก†}@@@@@@@@ ์@Xvฌั€€€€€FยB †f#ฒฐฐะ๋0šIEh�น๓g`ภ‘}๔์ๅ  œึT๊xqศเ=B(๘~ฌX”*v\น‰(*„ใแ์ีm฿๏2ช )หn_�Eูี'่์Gaข;ยยU&w.56gKณหYฦแl�…เษ•d‡ตฺน™v฿ธๆtืšฉาRฟœoB€Zีื�ZฉFอยยBkำ}แ|่nา๛q&Zqลฑล฿�O{o]w‚ป|8<็šาoDfvแ0_ท>4ฯแ้‚ฒรยyPอฬN™ม9�e.ˆ๓5D‡ƒฐ(ะC>›Cmšซ๓�ั�๗อ๔Uซ'+ื=};็9ดํธB๓vwื=แใ้9น&D~บฐฐ�†t็ู3ปะั,,ไ0ร๋4aaŽ๓คkฃYXศ๛๋ ;g�ุ.�บ ฯซ3qGXhv ี�q–W.๚vw„…ž๖ษ!ถงkๅ�ณw'p6ี�ว?!ฦึ”ญ์’}ษž5;‘l!•๊ฏR‘Jห/ํซ"‰BูฅTdู๗}cW‰(๛ า�๛9ใ็žู๏ธ3wf^็๑ศ=๛๙�็๗4๏๙|๚™ sc\ๆผ•ฏFฐฐัM๙e@ต:ึ[�๚ฯ1้iฺฯkr%”ฅดๅ๕›I๓g‡.ั}}ำ��ภWRT,œdปo˜?ฏtษh*ฎwU)ีสฆ]Leำฤ,‰�:b?[m6ถ่เdึ?ณช˜–า๎jฆ๖๙�ื`zซH๊็H[ฝวต๘๛็fึ พA�'�ฑช๛ฺฯ๓�มยฤ�ฝย~Fb_ &V๋@@@@ภ , ฌ/wG@ˆA€`a 0Aด;5 �ณ๘’kๅยn%หJ‹…ใ{‰u�†cGไ!บ๒. .nฺZrd ๑�"ึํ๒&ผd/�`แ!S‰ฎนฉHŸลœ‹ซUฅท’ุรหศ:O ฯ๋oญ์๑xƒ…U~4๛L �„.๎็ฤ7Xจ๓๕ษ๖-rึ�6ํ~ตฐท�ฌ{ ๕๑V๖ซ๔�พู}Kyว3�˜€ฆฝh%ผ฿ฮ‘่Z๖zํ์k�ฏ�jX๎c1ญw_ฝT๙�:ฌA \-รฃปF[�ึš5YฮxZ๕ฯ~ 7U�บQฦํ�้�ๅฌ1AฐZน๓Jซ‚E|�›}B|*/ฺ็ฦ๖๊ฟsrฮดu‡ว[ฑะฺ�ฐR นำdvฆ.€^&,๘PฑRฮoีC็€Yie๎๕žนงฝh%ฮกปถู›Q^�3Iึyฆ๑ฟฺ3�ต$$X่๏3ต"แค๚องŽ5กนพ—Csบณš๙ŽtU4ผมยŒ้L•?SIฯ^ดง�^ำ0–ถ‹ึJกœ=#yMีQ{‰้s›ƒ…Wๅ๋ˆ๙(ฏ�Xส]Ÿำ&t^7?&—™๊~ŠหฬมB�นึี ]+ื2_ฃใZ��sำ๛gป๗ฯSo›wwฐ0ฑฏˆ๋=ล๗8มย๘Jq € € € < “วง"€ €i^€`a๐Rsฐฐ๓อ%DC$ฯ–ฉเLฤท{รไฐฉ@ึำณo�™ศ6ฦM›ษ’ื]/ๅM โ)Sน0› ˆ้ขแ“q{vษำฅสIึหA+ญ๘๕�]ึ๑ฝงOส๒ฃ‡ญu๗/ ฉX๘d‰rVตD๛๚k–สย?#ซษู๛์ื์f งMต=wศ>dฐฐp–์2ฃั๖pไ€i�bแLg� ˜o‚K=ื-wŽ๋Jjฆ7 ฅMw�ใ๓~ต]ฎ]1ิT๓Zๆฉๆๅnํ ›ลTํO[r�e*.๊โ ปh๕4  น?#ฮ€ฬฮๆฺใ็#ฏu๖{Wฬyw**oUฌๆ™aค�3Aาธ ปL6ํd�ญ๚sฆศฑหใ๋๚ุŽ๛ใใ๏œhุ์j �~ภ]฿ขO�๋่Z‚{[ w[ฝX–‰๚๕Fอส›ฐ๊7&ดj/S๎•W7ญฑ7}^๕kF†kา;ŸK๗ม‹–”สVtvล๖๕ศ฿gๆ4ŸมEM�8ฯ8cพฆี˜9ษ ๕ฏZKšไ-่ฟมBฝู*S�อ�:n฿\�•็0ํฌ๏ศ_ศ�eฝฦV…๐j O›PZMS4ฆ ทํn +^ฏ#]n))ฯ—น๒ู๑5๏›–๓ใ๗…yw๛l๛,ิสฉ๎ ๊๔C{ๅS‘2‹ท๛#ฆj๏ZOี^�|d1_ํ ฏ‰๙sำ ื๗ใฎขyGพ‚าฏJ-็mบƒ…‰�{…sำDฎ๘,ฬf์ฦีi์๓ไ{–ฬ‘๓ฆ๒%  € € € €ภี Xxu=น € €@<ฦ*OKอมBeีoLฏผณ#ฌ•ง2›jC๎ถ‚g|ฅZ—^๐ขซ-์[6ศ7๛vษ�สU’๛M`Q—๗ถฌ“o๗ํถึc๚%!มยJ9rษฺุœ[]๘๗’ ใ-3U ห…�“ ้%ŸฉJืญDYi–ฟฐxƒ I,ิ@ิชๆm%“๑ต ฟ �๙‹ไฯšUพ2๏ร]้๎%S9oๆ๏์Sญืิ,ิ78ฆVฉœ3๓žตRWตKMˆLdh๕๚R2๔z็ุผ|ฦผltS~PญŽs\WF˜ชsฃw๏0U/ษMๆs๐j๙*r๋ 9ฅสฬ‰ฮyณถฆj ฝฬ�ใ ๙œฎ—cแ’�|�็5ฒ฿„ˆu|แฆ’ฃ�บ�฿gjุsฝฉ�–�|ํeโ��๒ฉฉ(Z๏ฦ|๒nฅ๊๖n๋๕j ?ญZ[ๆ-เs๏'V-–P$w;๋ �ฯปถ๘ต—์2šฯ๘]๖ฆhซ฿�šโl๋สIOEP�็ ‰ 0s9ใท�Nภำ}MR u|~1ืบ[M๋ฝtynํrŸฯ’๎๓V�ิะPฃฝt/yซO‹p #�hŒ์ๅ์ลญฯพฝญฏ^+๎k–ษึŽG๙}โพฮŸuoธYร|Z!vฅ๙ƒtๆkmษ์ืห๛ฆล๖ยรฟษ๛[7XHฬŸ›�ฏ]๚๛ฑ๋สE’+sˆŒซ�X2บ์�มยฤ�ฝยฝฆŽ๙sฆ„1ฐ๗x่>�๚e/aฆ:๒Sีืปไฮ" ฬŸK๎ฅ†๙๚h5�๛YG@@@Hœมยฤ๙q5 € €€Ÿ �„ ๐eฅส”•๋/‡š2fส(Uช�f=๑์ูณฒycไ7ภuว–Ÿ7หS•ฯ^ (( ^ฉๆt[š’�|3๛’๙†๚๊•+์ำไเม�๒�กCฮvrฎ�f‚]#LภK—Ÿ��K:-›/๎ ิๆใI็ๅ๓ฃโ’;ฺศ ฆ‚•.ญM5พ=&Pณ์Žถš1ฒŠaห?ส>—Ot7IHฐPฏ[ซกTส™;บ[Eู—œมBL SูซOๅ+aง(ผผรช๘5wz”Š\ฉ=XxcHf™ืคUL,>๛๋š6šป[›ไึ๔†wJำ*6ถๅผ wนƒ…�Š]ฑ]๋ำพำo\ญ๎๙ฯ๙๓RสT�tฦด}g}ำ�šsn”?}�™“@ czซถน๛ื(‡ฝฉ('˜๎vฝ�jƒัo๏kยชั Kd•Lลษ˜–ญ�“๛–š–ถ—Ÿูณ๔ญ&˜ZฺพMฌฏW+Xุ้ๆโ๒rนส>ฯชg™ฬŸg�vโฝ7ฎ’i‡"mฺบyjƒ+•Z}nร†ปลน}สคzอค๘uก๖f”W๛ฯ=เ๛@W,ิg๚๛uDƒs?™ ฅ๛k†�v�Sม๐ASษะ^๔๋D๓๙?:_ฦ฿}๋d๛|๏๋(d๏ฟ�J8M{ร๕�kt��๛$บใ๑�ง?ดฐ�„๋ตuvl‹Vยดƒ…zžฟnVผ!—|U็สฤ๖LwฐPฯKฬ฿+b{NlวF™0zUJฯฒ�ฏฃาeๅ‚(ง,ŒBย@@@@ ` Fห@@b X›N๒๋๖๔3็ฬ๛I6oบRษชCว๛Mฐ๐J[ส˜np`�~๙aยท1Nา�/™VžMKO]์๖‹ฏ˜@ษ}&Xขหป?ฏ—๏๖Gmษจ•�ผU ณf0AW๛ฺ˜*Z7พ�KBƒ…ื›ŠY๊�aUคs฿'บ๕ไj"ไ๓๊ทK]SY,ฆๅœimฺa๑\ู6ฒีด๛ผิ,ิ๗Ÿฐ•Vฏ›lฺีzญJจFvี{\ทฝมB�๗tษr๒ธฉjื[ฐ0ฆkตR^ในำœJuzž7Xำต›Vก๋<ญBc:7>๛�๕I่œ$UฐPm๏˜7รฉZ็5๘ buนซ`๏ng�˜า1Œgฐ'ฆ`ก�ุ๛{ิy˜Y๑ �}ฆ~ญ�คe”ึฤ๎gู๋W+XXมT๚tทXี๊ฐ•œ �ถื๚�v‹fหNฒีๅj oฝ>ง|m‚t1-ษ,ิq๙๓uไญ[ซษ�…‹:o๋„ ื3UJ��๏?ษhx+฿�ฺพPQyฃB5gW S๑@ีํ“๏*PXz›ฐf6Št/KL›ึึฏ๐ฃ๛ธ;x มžjณ&F�’ฺ}Mt๋๎ถข1…ค gษ.3]ฉ4Ÿ6ึ๎g%ฦGซ}~[]ษ›%ซ๛–rภTภ์ถfIฌฮZ๋%ำถธ}ก[|ช�้๔๚~ฆ…ํBใ์]๔๓�ืT“,{}๔!m‘��พ0Y๕ื็าฎลKK‹|…ๅ–*ฉอ8ธO>�eฃ�ใฎฌhฎ.`�ื3ฅส[-}�ญฑํ�.l]/sLป็ซฝ๘๋“ 91žu-ฺ9mฟต๓ษ๓dญูงีสด�jUำŽZ�่.lฺฦz‹Z๑ฑ๊?Xฟ™๛™yธรT๗ด—Nฆส฿�ๆ๗š�yว‰ไA๓5ฦ�๛ู>฿�ฺภ„x[ผYดฝiŽLWพ†kภTว`†๊ณิฮ}“ผk‰นข ’k่๗‡{dœi‘��น3>ืูZฎY�‚า�ดbพ9�u’?KงB�rำบ๔‰ีK์SWžฉมง๑ท7๑iใญf฿5ํoฟ7แZ{ถ]ด^b—ฆํbS‘ึ^ๆ›ฯfฯหญศฝ-g�ญW๓gฮ๊ำ๚ุพ>ฆW�lhkkปeด๛<�=๚Pัฆฒg)š=ปdw}�lfฆ๖œ„šึหห\๖/Lป๙ฯvlตnฅ๓ณ๎ฮvฮืoKu๗๓�YOศื‘ฬ๘—4k๋๓m/ฝ�ดถ—ฆ๙ สวUjู›ึซํ;ดz]ำฆ=ฏฯฑุ6š๖�รvmzŠ๙MPีT�ฝทH1S๑๕:๓_6็๗ฎ�9Seๆ„(ฟOข�$�{๔ณิฟJm็๏๎+๕๗ศ[6F๛w ��ิ?ใ?1mผ�ํำ๕๏�V-‘ฑu:Ÿ!ญ[ฯT‡u/��ฝย}„ฌ0ใlไi7ำ๕1}nฝŸ}ฝพš๙:งmุY@@@@ฎฎมยซ๋ษ�@@โ)@ฐ0žPœ–jผมยo๖๎”cๆ›�GMุ*บ*u^ N]Ÿ!“d0aม3&tฮ–.\๒ฦ‡ผW%ฯvฦt้$ง ;ปxัj…k%$4”zy๒IษะP๓ˆkไijณ—˜‚…๖๑ไ|ีPNBนdชwฟ‘เefำzS[sŸฟtQN^ธmX)ส๛3•lฆาfจน.ย\wๆโฟึ�ฤ67:ฮฬฆ%ls]zณฎ• ฯšฯV‹k ั๋ฬ8uฌ๚ผำๆณT!|;'qy่qoฐฐึฌIrส�^ฮbฌt^�Š8๐฿ำHบฮTฬb�;kž}ฦฬgtaท๘ผŸ๘žใฯ3๕๓“3cˆ๙๚xNฮ›PK๘๑u$HFžtร0FืeผVฒgศh�Yญ_๛.ฦใ3์ฯŸ›๚{+ทiQฦ�9 _KบคคฟW$๔ฝq> € € € €€ �sใ*@@D ,L$ —งxoฐะ~CัUฒ๑ทภ๐๕ฅz๎ศJ”๎ณƒ9X่'๋iG ฆ`aฺเ"€ € € € €ณมย`žฦ† €คb‚…ฉxryk๑๐ถะต/:b*r5š;อ�ไ51ตอ๖ซ|ผ}s๏ฦ้N€`aเlน3 € € € € €@โ&�; € €๘!@ฐะ4.I]ฆ=bFำฦุปh7ใ๘ดI๔^วvค€ถ‚ิ�ผห…K—ฤะฒ 4 ƒf* € € € € €@4 ฃAa € €@เ�˜' €ฏภซๅ+K๛Bท8ฌ9{ฒœ๛๗ขณอ  € € € € €ษ)@ฐ09๕y6 € †ฆแษ็ญ#€ € € € € € €@P , ๊้ap € €@๊ X˜z็–w† € € € € € €)[€`aสž?F €คX‚…)v๊8 € € € € € €คr‚…ฉ|‚y{ € €@ฐ , ึ™a\ € € € € € € ึฆ๕O๏@H&‚…ษฯc@@@@@@@8ฦฤa@@ภ, Œ+wE@@@@@@+@ฐ0ฑ‚\ € เ—มBฟุธ@@@@@@ธมย€๓@@่Fงย>@@@@@@@ ๙&�0@@ M ,L“ำฮ›F@@@@@@ @ฐ0LCD@Rฃมยิ8ซผ'@@@@@@H  Sร,๒@@(@ฐ0NCF@@@@@@4!@ฐ0ML3o@>‚…ม7'Œ@@@@@@P‚…|@@’E€`aฒฐ๓P@@@@@@@ N‚…qq € €@ B•{"€ € € € € € €‰ X˜xC๎€ € เ‡มB?ะธ@@@@@@H‚…I€ฬ#@@ข ,Œjย@@@@@@@ ร,0@@ ,Lƒ“ฮ[F@@@@@@!@ฐ0ELƒD@RŸมยิ7งผ#@@@@@@H Sว<๒.@@'@ฐ0ลMF@@@@@@4"@ฐ0L4o@6‚…ม6#Œ@@@@@@ˆ Xศ'@@ Y& ;E@@@@@@โ X'' € €B€`a Tน' € € € € € € x‚…‰7ไ € €~,๔K@@@@@@@$ X˜ศ<@@ ชมยจ&์A@@@@@@‚A€`a0ฬc@@า มย48้ผe@@@@@@H Sฤ41H@@ ๕ ,L}sส;B@@@@@@ิ!@ฐ0uฬ#๏@Hq S�”1`@@@@@@H# ำศD๓6@@` Xl3ยx@@@@@@@H‚…|@@’E€`aฒฐ๓P@@@@@@@ N‚…qq € €@ Bีฟ{�Rฌธ3�eฟ.TBBB$wž<ึŽ9"แแแr๊ไ �%ปอ, € € € € € € ๚ฆ�9ๆ"€ €A)@ฐ0yง%44Tjิฌ-E‹—L!๑LxDธ์ูตK-œ/๑บ†“@@@@@@@ ๅ ,Lysฦˆ@@T!@ฐ0๙ฆฑFญฺRฉJีx ฝ#ี€แฦ๕๋dีŠๅ�Cl#€ € € € € € €@* X˜ &‘ท€ €คD‚…I?k™2e’๏wZ�#8qโค์ �iต;Ž0กAmฌ‹ถDฮdชj›ไขลJHh่u๖%ึซž7แปoจ^่ฃย € € € € € €)_€`aสŸC� € "&ํดiHฐ}ว๛|ช:x@Všชƒ๚Ÿฅ@มBRำT;ิW{ั๊…ฟ๏„ํ�ผ"€ € € € € € €@ส X˜r็Ž‘#€ €)Z€`aาMŸV*|ไฑ'|B…‹ฮทฺ๛3 mฃ\ฟA#็R Ž�r(• V@@@@@@Hู S๖�1z@@ ล ,Lšฉ๓ถ?ŽiS'ลปJaLฃิช…ญZ฿-™B2Yงh[ไqcGลt:๛@@@@@@@  ,LA“ลP@@ิ$@ฐ0ifณfญ:Rรด/ถ— ฆmq|[�ืฤ๔ชแยฆฝฒฝฌ2m•WฎXfoฆฺืw฿z]ฺดบK�๔K0๐sg;5ฌฌ[นTBCฏณ�สณfKฯ็_J o+ม๏Aจw}TŠปErๅส%วŽ“]aปe่—รๅ๐ŸG|ฟ๘\>_๑qเ@@@@@�(YชดิชSWฒeฯ.าง-2q๚ไIYผhก์ูๆ๏mƒ๚:‚…A== @Hฝ ?ทM›�)eห•ทคU ตZกฟKฝ ฅr•j]UBญZจี u๙e๋™3{ฆฟ‰๗u_!ทUซ็๙gฯž“ัcวษ'?‹๓�๘œเ nุธI:vzศบ”`a์‚ E๎hาX๚}๘ž„„„Dม:�ผ๔z้™๕ำ�(วปƒ`abน@@@@@ - ”+ซ4nฺLฎนๆš( —.]’Y3ฆษฮ;ขK้;ฆ๔d� € €@  X๘‰๋ึ�งZabZ ฿aŠe.uิŸ๔๛ะg๐๎–ศZตpศ O}Žb#พมB๛ู}�‰ 1ฺ�Lิk฿>๏Jƒz๕ไ\xธผ๖ฦ�ฒhษR๋~ cgM๋มย9rศ�ŸfHถฌYc„:}ๆŒิฉื๘ชVูิ‡,Œ‘œ € € € € €ฤ*5k6้๚ฤ“Nจ๐้˜ฅ= )"y๓ๅทฎีpแเAไย… ฑ�+ฅ$X˜าfŒ๑"€ €ฉD€`a`'ฒXฑาฒM[๋!'Nœ”‘ร†๘๕@oจpใ๚uข-•ฝห#]ป9mnงO™,aa;ฝง\ีmoฐpะเกึ�ฏอAชTฎ,+�*ื^›มyๆŸGŽH๚Mœํ@ฌ,Œ]5ญ [ถh.�๛๖q>๒… 7aื‡์$ฯ๖xฺู�ฤำฯศ�‹œํซฑBฐ๐j(r@@@@@ด(ะผEK)UบŒ๕ึ๗ํ�+“'~๏0tyดซ�pCk{ำ†๕ฒpม<็XjX!X˜f‘๗€ €ค@‚…4wไ˜ย€qภ*Œญอq�คR•ศึฤ�>/ฎ๑ธปƒ…งN’สี๋ธKม๙eฮฬi’ม ํฅbีšN%ธถญ[Jฮœ‘�ะ�ฒๅYฝv}š๕ช-kีผอZ?๚ื1™:m†sผuซป$ว๕ื[�ซืฎ—m�ท[๋๑ jีบF ๊Iนฒe$sๆฬฒ~รFYl*ž:uZ6ญ[้<ใ๓ก_ส€Ÿ;�1ญtพ�^ำV7“u๘ง9๓ไเก฿คvอRซV ฌผV�๙็Yฟ~c”๗็พŸŽฉ}�ึRจPAษ;—œ9sV™๛ฌXตZVญ^ใ>5สบถ๖-Yฒธ+ZTาฅO'�fyL�qV”sc �tcนห๏์ๅฯ?ˆ๗ ๋ื“jUซศM7ๅฑNำภ์��ไ๛‰“œyตฏwฟ6oึTn-Wฮบn๛๖ฒx้2ูฑs—ิฏ{ป+Vิ:u็ฎ0Yฒtน๛2kฝHแยRงvM)Yขธไษ“[~��๙uวN™;ก?~<ส๙ฑํx์ั‡ๅ…็{:ง/SมY฿ตmณณ�ฦ�๏ษ7฿^๙Ÿฮxฌ$๖๓UฑByฉ\ฉ’”(^Lฎ7Ÿ๑ๆง.wซ‹–ฤ๙~๒Yฐ฿Šฮถ4/?Ÿ๕y�๓ศQูฝg|๕ต�m�ํ{๓Š € € € € €ภีxาtห”)D�๛๏?๙|เ'NUยะะP้๒่c’.]:๋1gฯž•/Š๒H=� Qษ—?ฟdษœล:q>BŽ;&ึญ5฿“9ๅš`ูAฐ0Xf‚q € €iL€`a`'ผCว๛D[๋โOไ„„ ๕๎vศZ�]Ÿศ%ฎ`ก>๛๋ฑ#ๅ6Dณ—๊u8แจีหIŽnฐอ6ผ๎=ŸทOณ^{ฟ�ขt1•ไ์ล�ฑuฃ๓ฤฑใพ‘w�l Wฐฐ๎ํตฅ�G}œสŽ๖ฝ��๗_y๋�ไํ7^ตwI|ƒ…๎@šVmิp—†ยผหิ้?Jฏ—^๑๎–^ฯ๖‡ป<(M1บe๙สUๆลG9T์–ขV๕ฝาฅJF9ฆ;v……™็ฝ๊„.u_LมBญฆ7iยx)zs=อZfอž#=ž{มZืฐ�7f.o)z๓ๅฃพ/0ิ0�ณf๛ะPเƒ๚�ื>aย“EWซZฺูฅส๎jถ^5๘L๗'%cฦŒ>๛uCŸ๙ฮ๛}D]ใปT7บqcF8ง?๚๘“V˜ั[ษPฝี=กKb?_}�{[ฺ™€it‹๕~?๘ะ'`kŸ็ฯgAƒคC?(eห”ถoใ๓ชaแ�ฏฟ%ณ~š๋ณŸ @@@@@’R C†kอ๗žณ้ >๔HWั๏aธ—O๚E~ฯศ�—7o^io'ษ>ฝฝ+ส๋ฯ>•๐๐๐(๛ƒaมย`˜ฦ€ €คA‚…๔ฮ>,น๓DVv7v”5ญ€ใป$4Tจ๗ีg้3uัg้3นฤ,ิฐฺ์SL•บญa>�ง��ฐฉ3คฤ �aพ๘ ตโ฿๓ฉ ่ &š‚…ั�ฦgืŒ™ณไู^/;๛ผ๔œž•&O•—{ฟ๎์ี$/œ3Sฒdษ์์‹nๅฐฉ:ุฌEkงš`Lมย ใว™ึีๅ[xรŒฦeตถvNˆfๅ�นsา๊๎Žฒo�~๋จฮ�‚น3๐h4—๘์๒ 5p๙xืG}ฮ‰nใษฯส�y ข;ํพe‹ๆส—_jxnูŠUาดqCI๙(„ํ�#อ[Fถ0๖1์L์็๋ปฏว˜J…cธ๛•�ฏพ๑ถ|7แg‡ฟŸ…Yำ&™j‘ท8๗‰n%""B๎jำม™ำ่ฮa € € € € €ธ)o>นฏำึ#�๑ปŒ�๚+kฝRๅชRฟa#k�ย… VW�6tฐœ>}สฺฏฟ<�dw๓�”หU #ยๅ„้4u๖�Yษž=ิดPพม*d๑ลฯไ์™3ฮ5มดBฐ0˜fƒฑ € €iH€`a`'๛ู^/9๐�t”s šB…๖m�}ฆ}}B^�มB�)ฎพ�?ต.ฟ�๚PฉZนฒTธตผ|ำา๔/�๏UŸjkI,>๔sฉW๗Jปf M-\ผิ๚‡f•สๅzS.฿ฝ$&Xธrีซ…m•ส•Dซษู‹VFผซM{ั๐š.๓gฯฐฺ๋บMš2M๖์ู+eส”ฒ*ฺmคีท|ๅ๊zšต ๘๘Ciัผ™ฝ)›OŸ1SBฏปN๊š๗xรๅ6ัzยศัcๅƒ>ถฮ.X่uู�๓๓“{{?ะ้>yฝ๗•0ไžฝ๛ฌส„™2e’ฦ ๘T#ิŠ?b]�ณวS๒ิ9๗ั๗ทศดœ>bZํVฟญชUญะ9hV�มBญฆ7ฯุ่3t9o�‡ภุฏพ‘cวIฉ%D[a�‹ถbn�ผฅฝ็ซ†๗พ=<ฺ ‘š@n็‡�ฯฏ ื1!Ÿ/m �ั๏:cืฯษำ๚๛๐Ÿ&Œ[ป–�ZพœsL�?7lฺย ‹๚๓Y๐Vn^@@@@@H*ฒๅ*Hำf‘฿ูทoLž8ม‘ธVบ=�ร*&q�|๏ ย|%oพ�ึฆN๚ม|ฏ%ฬZ 1็=cญG˜PแเA‘฿หฒวž>]zฉ]ฏž,_ผX�ฝ๔ฏฝ;จ^ ีt0@@ ํ, ์\๛๒KLจP฿?ฯ๔Wม,Œ๋๏ุOF‰� 2๛�ค jUทีหฺถ‚jt๙?ูฐq“ตฏ`�๒�7c%wฎ\ฮ9� 5Xงa,{=โ ฉ]ณ†ฝ)ใพ๙ึjปฌ;^{ๅ%๋งแt]วขว์eะ€ฅYำฦ๖ฆ4i�ส ผi%ภkWศ5ื\c;y๒”ดi฿Q๚อฺึP�œ™ำ$sๆศj†ฟ๎ุ)-�vฐŽนƒ…ฺ๊๘ฌฉ2่nฝถ� ž9{ึyฎ†ะ:�ำ�ฺพdo๏›ข†�tัVฦsfNuฦโniฝtมงZฅž๛๚[๏ส๘๏&่ชตx??๎`ก5ะh/Œิ€คฝ|๖้วV๐า�~คk7Yบ|…ฝ๋k‡vmๅ�w�Œrฮšu๋M+…^ึ{๋�ไาใ้nึ9๎๗ๅขห;๛๙š>y‚”*Yยน}ฏ—{๛„pGb ํ�๏ำWF'�~๔๓จŸK{๚ๅp๙xภ {S�|ํั�ูขหœน๓eมขลฮ1V@@@@@HJฺu๋ษmทE~Ÿๅื_ทษฌำฅ�=๗JมB…ๅาฅK2r๘Pi�ธ™)Y่aษข…ฒ~�kˆ9sๆ–~ฤZื๏mŒ9,)‡~UžEฐ๐ช0r@@„ ,LจXยฮ๏�Pษ;ฒ p|Z!'6T่ำ ๙่Ÿ2nฬ่„ 8g{ƒaฑ]~แยE๙lศP<๔ส?ุ’2XXฃ๚m๒ีจ+ฯž๋vฐะ[q๏ษฯส�y |ฮi#ถ`แs/ผ,ำœํฅZัQ+๘UฎXQ ,เ„$ฝ'�มBm�YAk}ๆŒiฒใืํฮ�ถ๏ EŠDV3ดw�k:4:uJ–-Y(ปv๎ดwๅ+มย œ… €ค~‚…ใฆอ๎”ฒๅส[ูธ~,Z8?ฺ^Pก�ธ~ƒFRฉJี8Ÿํ �ุ้๊?พ*Wฏๅ.อ›5•�๛:๛ต�oวNY�I,|๘กไ•—z9ใˆ.Œ็ x๙,�z�w๒ๆ;๏;ฯฑW�A9 mี3%๙u๑ถ;ถฯ๎ีz฿K—G—ๅ+WEwI”}ฑ <$ญLหdwdฝVห�ี(ษ”)S”๛ywุมย2ฅKหิพu๛ตผื็#g�^YถhฎSํะห้ฑต+—Xีํ๓โz๐รdyๅต7c=อ=ZY๒กGบZํฃ‡�\๊ีฝ๒ู]ณv ™–pBž}�‰ 1:ึ{{็$!Ÿ/o 5ฆค�d๋/�คm‡๛ฤ๛�„|4�ูฟo)]*ฒฒeto๐ุฑใานหฃถ{Ot‡ู‡ € € € € €@ภ นูฉPจ@-hกีฟ๙jŒ9๒ง๕�Nt‘<7Fv;z„๛๋/Ÿqi8ฑFญฺฮ๐ปž:yRF./^p๏šu‚…A3 @H[ ;฿ลŠ•–mฺZ9iชฃ64ส�a@=๘หึ-2g๖ฬ(็ลgวฃ]Ÿ๋LkZ]ฆO™,aa� ซ๘ u,๎0�๑ฟ�–๊ต๋๋nŸŠ…๋ึo๛ธRMN{_ลหTะ�ึฒk�f{ีjซญpu้๚hy๑๙gญu�E�kˆฬp|ฟO_5vœsžฎx�ร๚,œฟpฑ<๑TŸ๛๊ฦๆuซ$K–ฬึ�M›–๗= ตkึั#พpฮ=แ‚l4มห5๋ึ›vฤหmีชšvศMœใvฐฐIใ†2xเ'ฮ~ ิiฐ.>‹{.ข;๖œyาฝ็๓>‡ดีฎถ�ต F.[ฑRv๏ูk�4ŸV‚ด�<�มBm้ผi�J๛‰ฎ�ณžณ~๕2งขฅ;X8}๒ำสน„s}ฏ—{‹๙ฟฮถwe๓ฯ[e฿����ฮถท‚b฿ศ—#F9วฝ๏ั9`VโึK์็k็/›รY?อ•ฯ^ มฺcqท–ึ •^LฬgมพฏฮmS๓™ชTฑ‚”)]*ส�Tฑ็ิ>ŸW@@@@@’R Kึฌ๒xทง}นใืm2sฦtg฿c�ž’ฌYณY�Ÿ๔‹�ž‘sะต’3gn)o:•,YZ๔พ๖ฒ;l—L›2ษ� ชW‚…A5 @H; ?ืO>�S2…DVz‹ฎ๒ณฝ^r‘˜Pกป rDx„ �l€s฿@ญฤ'X˜รดD^nชาeศมฦ‰'ฅjอ�ญuw{` ี•ญYmั๏ึk|ชไ%&X่ญ ทm๛vั ž{้๗แ๛าบe g—?มย๓็ฯหํ ๏0มภใฮ}ฺถn)}ู&Zw�8kถ๔|�%yผ๋ฃาู๋+!Dญ่ง•�์ๅ/>/tyะ�ดฦซใ.Rธฐฬ5อู๏ไู;๛๕yOส–-cm๎�ปฯ ก้†;Xจว ’Qร†8๓ฃ็ผ๕๎ขํํE‚ิๅศัฃRป^c๛๕๚หๆu’๑ฺkญuwอ�,� ยปฺด๗ฉ|็}๎๗กมI อู‹†N5|๊^๔ณ•๕rXSรฃฑ-๕๋�.ร†~ๆœขญ†ตๅฐฝ่๛๛ึ(�aF=ฆ•๚šทŒ �็F๗šุฯ—๛๗ย้3gคŽ1vWŽผฏcy๛WGkEญค˜˜ฯ‚=งzS๗ณ:฿ฏผ๖สK’.]:๋yjซ]@@@@@’K@ _+๊.ƒ}๊ E�ถื"Zupะ€�ฮฑุV*Wญ&๕๊G~/B;s �bplง'�1‚…ษFฯƒ@@ด-@ฐ0๐๓๏n‡|๐ภ™๘�xŸ‡ึฌUว*ฝ[ซdŸ bุ่�เร’;O๋hbŠ1�>ฺ�ฑ 5ดTญjyแ๙žRขx1็zwxlโทใคยญ‘ญข๕ z}1lคUy๎ƒw฿’๖wทqฎำ•ฤ ๕zwะMทฟŸ8Izฟ�–ฎZ!ฟg{<ๅ�ฃT๗๙,ิ๋4�๗๔3ฯ[•๋�^[4ฐxร๕ื๋!k๙เฃeไ่ฑา�ษ'ควำ�์�2x่0๙d`d๘MŽ๏พ๕บO๕8ปbก^ฐrษษ•+งsํ มCeเgCฌํ.v’�/ฟ่ำ6ษZuOทp์๑T7้�ิฮ๙าฎc'ูฑs—ตoห†ีฮ84ZฏัVMCmฏผ�Kิซ๋\๋jธฑuซปœcZญrภภฯๅ์นsRญJeุ้กsLW�Ÿว}ุ๚์ุ'ธ฿ƒ๎ำPโCtrๆ+ฎชB\ฝlก};9๔�oฆฒไ3ฮ{ิ�j—บo๕šตฆ๐�้jœ‹�VONศ็kศ าธQ็๎ ZQpศ OD฿ƒฝ<�dYฐhฑต้ฯgแญื{ห�๗�c]ฏํ"บ๗์%?อgm๋sV-]เTP�ฟ�€4n�า~4ฏ € € € € €$น@ว๛:Iพ�ฌ็zซึญ฿@ชTฝอ:ถoฯ™๑ค๕�รฯž=#_ พR  ^7Hข“&4A@๐ X่๋ˆญL™2ษฃ]ป9U -œ/"ผšKฅ*UE[*๋ขี G˜ t ๔โ๊ณ.^ผ่<าฎP่์ธผข-mงN›amฝ๓ๆkr๏=ํฝงฤธุ`ก†๘4ฬ็^.]บ$๚_tใ๕7X่พฟw�ุฑใRใ๖ศYฃ†๕e่gW~ขNฯ=gBw๚“u๚น๑.๎`กท‚ž{๖์9ษpmงz }�๋oฝ+ใฟ‹�Gด;�f ๕ผฑ#‡Iอ‘�่ึmm+�คy+]•ฉ?|kZไ–ถึ๕ญสจ3gŽlํ์0+๎`แM7ๆ‘๙sfF๛|๗บ;Xจ๛อ›%๙๓ๅsN๙๛ŸไภƒRฐ`ษqร ฮ~}฿ต๊6๔ฉบ็tญx�+๋!ญฦง๏ตpกBRศ�7บE[fk๋์ธ–ฤ|พ ศ/ณgL‘Œ3:Qg�้K๛'0ํ^'> ๗ดฟ[ด…ตฝ\ธpQ~ูถ]ยรฯIู2ฅ%{๖์๖!๙a๒Tyน๗๋ฮ6+ € € € € €$ต€ปs—~_g��Ÿd๋–Ÿฅlน าธiSง ฯุั#ไุ_9ร+Tจˆ้ี^™๏,^ดภtœ:fำ–ศอ[�ๅํ8x`ฟ)rฅ›“sƒ X!X“ภ@@ด(@ฐ0if�ฎJh?-บ–ศ๖ฑ„พบ�!ฅืฎZฑ\VฎX–ะ�๘uพ7X�Mด*ฺ่ฏพ๖ hieดs~tฺ์zฏื๖ฌ๎vญ‰ ๊�ฃ —ูฯีสl… ฒ7�ชXจa0w8ฬน™Yั๐ึ�^{ร V๊ฑษฦKนห-‹�็Fท๎๊๑/‡ ๒ฉ�5sๆอ—งz<็Š)Xจs๑ใ”‰>Ugฬœ%ฯ๖zYš฿ัD~าฯน‡{E†๎เ›;Xจ็้ต๏›๊“ูฒfu_fญฏYท^ ๆฯ/y๓�dm{sZํ๑ำ�}ฃฝึพ™†Yต๊ไค)WZC�วผฏZaq๒„o$[ถl�C>�ัอกป"คฯษžฤ|พ~่yัT๘Œ.ไj?ๆ?หƒว‹-&ญ๏พาAษ*8aพg•แr[e=Y๗}�ีh๙๋่QŸkƒeƒ`aฐฬใ@@า˜มยค›๐ฮu‘�นoด.ำงL–C$j*lูฆญ„d ฑ๎s๔่Ÿ2nฬ่D�3!๚นิซ['ฺK4œu�ย9|๘Oูmสฮk‹ใ-[‰rn๙reE�—,Q�9ฆํv5ทm๛ฏ๒ฦซ�ณ๖‡‡‡K๙สีsึฌX์ด๚ๅp๙xภ ๋˜ถ�ีผบh่ญVฝฦๆงฯŽ[�๖/}๐ฎ4nX฿ชสฆG 0n�ดYzฝิ�T›์�ท_�Oๅ‹แ#ํหb|�ตmณsl๘ศ1r๊๔)iืฆต*TะฺฏใุปwŸผ๙ฮ๛ฒzญoตJ ๔ฝi�ใM[?Mgg๕๊ต๒ํ๗eุะศฒ๛บฟ้ญฃสดmทว�On4ีฏนๆg๚ž‡-:๗ฒlั\น๑rหlm=�ฟWฏTญปฝv-๋y๎  V-ิŠ~ฺู๊๋gDซ=8N˜@IDAT๊XtูoZ{6๘ iืถSํpึ์9าใน� ๔uh฿ึช„—ำผ฿]aปe�† ๒๕๘๏eแ�™Rภ„ u๑ uŸ>ฏฯ๛๏Hีส•|ช8๊VฌZ-C†‹bชืลดheภ็zv7วฆ>H=�๔™3ฒxษR้cZU(P@>ุ฿ง2b๓–m%l๗ž˜nํ์Oฬ็ซb…๒ๆ3�Š”*Yย'`x๊ิ)๓{bผ๓^Ÿ+3&๔ณ ก]m�๎๎6r}hจ3~]ัส™Zฉp™_๏๏Ÿู@@@@@@ Zตพ[nพๅงBก>Zƒฟn฿&?อ๚1สHด2a๛ŽMฆ,>฿GฑOิ๏้ฬ=K๖๏�k๏ บW‚…A7% @H “nžฝ-‘๕ษ‹˜ถศ|ƒf๑Qฅสฆ�qรศ๖วzMRถ@Ž๏rž์J/&��ท์ุน+!—๚}ฎ†ฬ.\0แวDVc๓ ?์ื฿“พงB๓หฆอ[โ5F เi+Zฦฃ!ฑ’&Œvm† ฒห„฿ำ๗”5Kfs�ฟc ธูoVCrฺVW—‹�•๏&�`ฒ^๕^+ฯs~๎ึฬ>'^�Pณ#ๆ'ฏฦgDรฌzOm�๋Ž~นG7N{_b?_:> ฅž>}:Ac๓็ณ N Sjตฤ฿~๛อjmฟ^@@@@@6ขลŠIม‚…e฿�ฝ&wQ€๔้าห-ล‹Kฮ\น$sHf9v์˜)rะผg•Bท7มBท๋ € €I&@ฐ0ษจญๅ6•โ:�sฟd ษไ<๘ ฉ๚ถjๅ๒xW/ิ*…๕4ฝ—ฝhจpย๗฿ศั#ด+ตM’๒5ฆ`aRŽ!ŸีทฯปาฆUKghSงอกรFˆถ๓m�ฌฉ<ะ้^)S:2xจ'i ำ[aัน˜@@@@@@ ,Lƒ“ฮ[F@‚A€`aาฯ‚V.์p๏}N[d{'Oœฐฐฒ;,ฬTP wB‚ ฬdZ฿b~๒ชXฑrงeฉถ?ž๐ํxซ๊š}/^“V€`a๔�ฺZyฤ—ƒฃm-เฝโ๗฿�;[�gD๏ul#€ € € € € €ฉY€`ajž]� € ฤ “orjึช#ฺฮุ]ฝ0!ฃั*…ฺFyๅŠe นŒs @ฐ0fิ.v’—z=gตุ้ฌJ๗g_m�ทวt ๛@@@@@@4)@ฐ0MN;o@H~‚…ษ;Zฝฐžikฌ•ใ0ิ@กV6\ผp>U “w๚œงWญRY2‡„X�ฟl�UŽ?๎cEไฆ๓ศCt6mKIž<น%<<\.^�ืดD�C–._!~˜  € € € € € €@4 ฃAa € €@เ�8พOะpaQำ๎8ิด:ึa๎�7Z—jซc =rDƒŒ@Hก S่ฤ1l@@@@@@H๕ S�๓@@เ Xœ๓ยจ@@@@@@@‚…|@@’E€`aฒฐ๓P@@@@@@@ N‚…qq € €@ B•{"€ € € € € € €‰ X˜xC๎€ € เ‡มB?ะธ@@@@@@H‚…I€ฬ#@@ข ,Œjย@@@@@@@ ร,0@@ ,Lƒ“ฮ[F@@@@@@!@ฐ0ELƒD@RŸมยิ7งผ#@@@@@@H Sว<๒.@@'@ฐ0ลMF@@@@@@4"@ฐ0L4o@6‚…ม6#Œ@@@@@@ˆ Xศ'@@ Y& ;E@@@@@@โ X'' € €B€`a Tน' € € € € € € x‚…‰7ไ € €~,๔K@@@@@@@$ X˜ศ<@@ ชมยจ&์A@@@@@@‚A€`a0ฬc@@า มย48้ผe@@@@@@H Sฤ41H@@ ๕ ,L}sส;B@@@@@@ิ!@ฐ0uฬ#๏@Hq S�”1`@@@@@@H# ำศD๓6@@` Xl3ยx@@@@@@@H‚…|@@’E€`aฒฐ๓P@@@@@@@ N‚…qq € €@ B•{"€ € € € € € €‰ X˜xC๎€ € เ‡มB?ะธ@@@@@@H‚…I€ฬ#@@ข ,Œjย@@@@@@@ ร,0@@ ,Lƒ“ฮ[F@@@@@@!@ฐ0ELƒD@RŸมยิ7งผ#@@@@@@H Sว<๒.@@'@ฐ0ลMF@@@@@@4"@ฐ0L4o@6‚…ม6#Œ@@@@@@ˆ Xศ'@@ Y& ;E@@@@@@โ X'' € €B€`a Tน' € € € € € € x‚…‰7ไ € €~,๔-@—�Rฌธ3�eฟ.TBBB$wž<ึ“Ž9"แแแr๊ไ �%ปอ, € € € € € € ๚ฆ�9ๆ"€ €A)@ฐ0yง%44Tjิฌ-E‹—L!๑LxDธ์ูตK-œ/๑บ†“@@@@@@@ ๅ ,Lysฦˆ@@T!@ฐ0๙ฆฑFญฺRฉJีx ฝ#ี€แฦ๕๋dีŠๅ�Cl#€ € € € € € €@* X˜ &‘ท€ €คD‚…I?k™2e’๏wZ�#8qโค์ �iต;Ž0กAmฌ‹ถDฮdชj›ไขลJHh่u๖%ึซž7แปoจ^่ฃย € € € € € €)_€`aสŸC� € "&ํดiHฐ}ว๛|ช:x@Všชƒ๚Ÿฅ@มBRำT;ิW{ั๊…ฟ๏„ํ�ผ"€ € € € € € €@ส X˜r็Ž‘#€ €)Z€`aาMŸV*|ไฑ'|B…‹ฮทฺ๛3 mฃ\ฟA#็R Ž�r(• V@@@@@@Hู S๖�1z@@ ล ,Lšฉ๓ถ?ŽiS'ลปJaLฃิช…ญZ฿-™B2Yงh[ไqcGลt:๛@@@@@@@  ,LA“ลP@@ิ$@ฐ0ifณfญ:Rรด/ถ— ฆmq|[�ืฤ๔ชแยฆฝฒฝฌ2m•WฎXfo๒Š € € € € € €)T€`a 8† €คt‚…ŸมะะPน�ม.N ไฤด?Žiด๎ถศIูนuหRชdษh‡๕฿�ษ‘ฃGd๗๎ฝฒaใ&9s๖lด็ฑ@@@@@@๘”,UZjีฉ+ูฒg— ้ำหล‹ๅ๔ษ“ฒxัBูณ',>ทHq็,LqSฦ€@@ิ!@ฐ0๐๓ุดูRถ\y๋AZฅPซ๚ปิkะP*Wฉ&ัU%ิช…ZฝP—_ถn‘9ณg๚๛˜x_๗๕˜r[ตชqž�๘q0hฐŒ�nBœ็&๗ />�ฌdห–ีฦค)Seำๆ-ษ:ค›nฬ#O>๑˜5 k~ิ๏Bšษ:#<@@@@@’C \๙[ฅqำfrอ5ืDy�ฅK—dึŒiฒs็Ž(วR๚‚…)}? € B~โบuฦฉV˜˜ศw˜€b™หE๕'�>๔ผป%ฒV-2่SŸใุˆoฐะ~๖๛}๚สจฑใ์อ {ี฿า…sq๕๋�ฉ|1|คณ+;ด“w฿z�y๔�๗�/[ถ�โlณ‚ € € € € €คvฌYณIื'žtB…‡-่QธHษ›/ฟ๕๖5\8xะนpแBชโ X˜ชฆ“7ƒ €ค‚…ซbลJHห6mญ‡œ8qRFโืฝกย๋ื‰ถT๖.tํ&กกืYปงO™,aa;ฝง\ีmoฐ๐๛‰“ฌ๛ง7ฅ็ซTฎ(E ๖y�นs็ค้ญไ๐ŸG|๖หมย`™ ฦ € € € € €\h�ขฅ”*]ฦฺฑo฿^™<๑{็`—Gปส 7ไฐถ7mX/ ฬsŽฅ†‚…ฉay € €@  XุIsทAŽ) ืผกยฺุืoะH*U‰lM์๏๓โ๛ธ;Xx๊ิ)ฉ\ฝŽ๛ฐ”,Q\†~�ฉศ๙“bzฐืKฏศิ้?Z็ตm�RrๆŒ�‡�–-ฟศ๊ต๋|ฎ/Sบดิชy›ต๏่_วd๊ดฮ๑ํฺ:!สŸๆฬ“ใว�–ฆMI๕�ชI๖์ูd฿�ฒpัYท~ƒsMl+ญ[ถผy๓ส๓=ป;ง-\ผDfอž#—L b๗ณํ*Wช(U+W’ล‹I–,Ydฯพ}ฒcวN™�ใ,๛”(ฏ9rไ๖m[KกB%w๎\r๊ิi9|๘ฐ,0c�ฐq“sพžW๏๖ฺRฏniัผ™ณ�หฃL`tท��๗?ฒhษRgฟฎิฏ{ปีšบ@�|rํตืสŸGŽส๎={ไซฏ�oฟํ๓6@@@@@@dxาtห”)D�3฿ณ๙|เ'NUยะะP้๒่c’.]:kTgฯž•/Š2B=� Qษgพg•%s๋xฤ๙9~์˜lXทV:ๅš`ูAฐ0Xf‚q € €iL€`a`'ผCว๛D[๋โOไ„„ ๕๎vศZ�]Ÿศ%ฎ`ก>๛พŽไํ7^u†กมธพฐถW/_$9nธมZŸmย�{>๏œง+ฝ_~Qบ<ุษูWผLg}ืถอฮ๚ุq฿H+ ผ��ใัฝ่?.G๙J>๘่c๗๎(๋ ไ—sfFู๏�qW›๖ฒc็.gWฟ>๏I๋Vw9�๎•ฐ�{ไ๙_‘m�ทปwห�=๒๔xช›dฮœูgฟฝฑt๙ ัช“บtบ๏y๓ต�๖ก(ฏ�œ8!ีjึต๖kฅลกŸ”ฒeJG9Owh่ณ๗๋oษฌŸๆF{œ € € € € € €@ฐ dศpญ๙าsึ๐ผมม‡้*Zฌมฝ|า๏C๗ฆUXข�ฝ$ƒ้ธำ2ไณO%<<<ฆรษบŸ`aฒ๒๓p@@ ํ , ์�w~๐aษ'๕qcGษั#๑oœะPก>DŸฅฯิEŸฅฯ ไŸ`a๗'ŸOG†ๅt,ฃว~-๏๕๙ศึี ฦ๕;?๔h”jˆ๎k,�๎๋1ขี c[ฮž=' š�i*)ทNk~G๙ด_นๆškbปฬชŒุ๋ๅ� ฮš6IŠป%ึ๛FDDศ]m:˜JŽ๛c=ƒ € € € € € €@0 �”7Ÿ�ื้kH‡�๘]ฦ�•ต^ฉrUฉ฿ฐ‘ต~แยซ›“n :XNŸ>eํื_ฒปีyJื#"ยๅฤ?�ศูsgMฌPำB๙ซฺแC>“ณgฮ่)Aท, บ)a@ € €@ฺ Xุy~ถืKฮผ?ๅˆfลŸPก}Ÿi_Ÿื๘ gMŸ,ลn)๊�๖�>}eิุqึ๖ี ๊O‘�4wพhHฐRล >>mcฌaฝุ–ท^๏-นrๅ”ฆ#�ช็j…ยM›–K—.ษ‡}๛หS>_[&๗๛๐}็V™อZQ—&Jล ท:ว�ฯีŠ‚ิsŽ�n‚h…ย๙๒I๗งž0�xอnำgTฌZSด ๔�๗v0ฏฅค|นฒฮuK–.—?L๋ไฟLi�?—๊ีชสธ1#œใ”แฃฦˆV4l�๒.Ÿgษ่ฑ_๛œrต‚…ฺV๘๕ท�๕น๗7cGIตช‘ฏVฐ0GŽฒzูBŸ็ฤต๑dge๎ผฆญ๑=ขํ–ฃ[ฮŸ?/ซืฎ“ ?L–Yณ็๘œWฐPOž�ำRจ`Ÿ๋์฿�Cฦ›@งV2dA@@@@@Rš@ฅสUฅ~รศฮO๛๖์‘›๒ๆ“ฬ!rๆฬi๙rศ็ึ�้ะ๑~๓}ฒ‚ึ๚ฬำdวฏ�ทูถ})R$ฒšกฝ๓฿�•SงNษฒ% eืฮ๖๎ |%X”ำย @@ิ/@ฐ0ฐs�ดูRถ\y๋!ืฏ“E ็G๛ภซ*ิืoะH*Uฉ็๓ข„;ฝมยŸๆฮณ๎Rฐ@~ŸvมZ5๏๖Mข<แj ‡#๖๋๏s�1#พ”Z5ซ[๛ฎVฐฐd‰โ2cสDŸ็ฤตั๋ๅ�2uฺ ๋ดOw“ว�๏ษ˜1cŒ—Mœ4E�๗๊ฮ๑๘ ‹�RT๚๗ํ#ฅK•tฎ๓ฎ;v\:wyTยv๏๑b@@@@@ZยEnv*j 0}๚๔ขีฟ๙jŒ9๒ง5๎Nt‘<7Fv;z„๛๋/Ÿ๗ฃแฤตjKHHˆฯ~�8u๒คŒ9\.^ผๅX0์ X ณภ@@4(@ฐ0ฐ“^ฌX iูฆญ๕“'NศˆaCฃ<ะิƒฟl�"sfฯŒr^|v<ฺ๕ น.4ิ:u๚”ษุŸฐr ๕งบ*Wฏใ sูขนrcž<ฮ๖๛}๚สจฑใœm]q ต๐}<์s|๘ะฯฅ^�+๗,^ฆ‚s|ืถอฮzR ตตฒถXถ—฿~�]>๙๔3{3ฺืy๓ส™ณgczV-[Hอ๊ทษญท–“�๙๒9ว์•ึํ๎•m�#’.>มB๛บส•*Jำฦ ฅRล &ุY*ส?Žšษu๋nŸฮ+ € € € € € ๔Yฒf•วป=ํ3ฮฟn“™3ฆ;๛๋๖”dอšอฺ�ค฿‡ฮ~๏Jฮœนฅ|…[ฅdษาข๗ต—�aปdฺ”I๖fPฝ, ช้`0 € €@ฺ X๘น~๒้ž’)$“๕ ฺ่!?�๋%g‰ บ� G„Gศเฯ8๗ ิJlมยฮ๗฿+oผ๚?็ัว—๊u8�บฒbษ|ษ+—ต๏�… RถBdตE๛คญืHฆL‘vบ/ฉƒ…#F‘>}}+!j+dm‰ฌห้3gคRตZึบ๛—›nฬ#ื^{ญต๋เก฿ฌW ฺ‹;hXฆtiyฝ๗KRฅr%๛ฐผ๒ฺ›V[d�แ v}โiYดdฉsฎฎฤtoƒื^yIาฅKgฏciุ๔NŸkู@@@@@@‚] วณฝฌJ…:ฮˆˆp<่Sgศ๚}=~อ5ืXU ๐��ŽsขgฅrีjRฏ~Ckฏะ�ล`ฯมฑIฐ08ๆQ € €iN€`aเง��๙เ2๑๛๑>ญYซŽUz=ถVษ>ฤฐั๙ม‡%๗ๅ ‰ (ฦp๛hwว,ิ ฬ™)ฺู^†~9\>0ศ�”‰฿Ž“ ทFถŠึฺ๘‹a#e฿��๒มปoI๛ป�8็๊JR ต…๒Ctmๅl/�*Š_ )�๚_๙ว๋๘ฏFYต ฟ.ฆŒ— k–;ฟŸทl•v;ูท”>๏ฝ-ํฺถvถ๕ฟณ~škmwhืV�็อ�g๏> ฃจ�>Ž? H (EŠŠาAบ๔*Mz•""E@E์ 6_P”J้้ฝ "="U‘ๆŸNค๘ฮsืf7•„$ป›๏œCvๆNป๓นฮI๒�็:๛.ZlฆJถร‰๔zGZ4kb๖kู�n/๗{Jj @n\ณ�� ญ:tXชิฌใ\‹@@@@@@ š6o)Y|ศtีทZaน ฅhฑโf฿มdๆŒฉัz$ญpุกS๓w”K—.สˆก‘ฯRญ‹ฦมA ใ•K"€ €D-@ฐ0jฃุก๗ฺw่์T-\นb™hˆ๐v.…‹RYญV8๊๋aึงตBo็-ยฝVTมยฯิ•ฯ>๙ศ9๗าฅหRัช˜งี u๙่�๗คY“Fฮ�จVโ:Xจ๗฿นํGน๋ฎปผบขมยฦอZš€a๎\9e๎ฬฉ’4iR็ญx๎�9ษ๙pI™2ฅำพ�—าจY+ณฝr้Bฏi�:qB๖ํ‘ฬ™2I.๋š๚):]ฎ_ฟ.Eญ)ฅํเ`‰'‹ษฤqฃฬ>๛หีซืd็ฎ�าธy+iาจ๔๙ฐทฝK์}Wฎ\–'ฯ+iำฆu๖MŸ9[�|ง—ณอ  € € € € € ๎™ปn�ธ!ห–� ฟ๎๘EžศWPชTซๆw?v”œ>uสyคlูrHฝ†ไจUิbีสๅึ฿จN›}:%rอZตขGฒŠƒ|็œ็O+ �i4่  € ˆฦฯ`�U ํป…7%ฒฝ๏V_�?H้นืฏ“ ๋ื�๊ebt|TมBฝ่ยน3Eรx๖๒�ด๒NฏฬฆVิ[พxพืTพ๖q๚ชแ:๗4ฟ๑,2๐ ฉVลาt๗ฅ๖3d๏พ�ฆฉ[—NาตKG็‡T๗q๖๚ฉSงๅูvฯKศoLSอ๊Uๅ‹~}ฝ‰๖ฑ๎ืO๚๖“1ใ'บ›ฤ7”จ;�w๖ฌS�๊๔วSฟ›lฆเตฏล+ € € € € € €พมยภCž@H‚… 7lฅJ—ฮุ]ฝ๐VzฃU uๅ ๋ื�สi‹ € € € € € €"@ฐ0@Šn"€ €ม&@ฐ0aGTซ–ทฆ5ึJ„ั j P+ฎZฑŒ*… ;|�@@@@@@8 Xงผ\@@ "‚…ษฤป† sZำงทฆ:ึa† ™L'tชc ž#€ € € € € € €@b X˜F™gD@�P€`ก ]B@@@@@@,‚…ผ @@D€`a‚ฐsS@@@@@@@ J‚…Qq € €@\,Œ Uฎ‰ € € € € € €ฤ^€`a์ น € €@ ฦS@@@@@@@x Xศ�@@ ฌมยฐ&ด € € € € € € €� @ฐะF> € €‰P€`a"t@@@@@@B€`a@ D@‚O€`a๐)O„ € € € € € €ม!@ฐ08ฦ‘ง@@N€`aภ F@@@@@@D"@ฐ0‘ 4‰ €๘›มB๚ƒ € € € € € €x๒N@@H‚… ยฮM@@@@@@@(FIฤ € €q!@ฐ0.Tน& € € € € € € {‚…ฑ7ไ  € €1 X4NA@@@@@@โA€`a< s @@ฐ รšะ‚ € € € € € €๘ƒมB๚€ €$B‚…‰pะyd@@@@@@‚…1Lt@>‚…ม7ฆ< € € € € € €‡มยเGž@8‚…7dt@@@@@@‰มยD2ะ<& € เo �mD่ € € € € € € เ Xศ;@@ A&{ธ7อ•;ไถ�ฅM—^RคH!2f4วิ๏^ ๚�ะ!@@ q,Œ�qn�ดน่ลบฤdไ[ ๊=�ำ!k๙wฝg\.1 VฏZE๕นำตƒ‡Iื.๚์—.]–ท฿{_ๆ/\dš~�qฝ(ดqฟ๖0PF|=ส4i`๎‹~}ฅPม๎Cœu อฝ�ึปฒใืN›oฟfฮž+๕๋�ฌ†xล ๋ๅ/RยฏAพO?�ภ�œ ธVฮ��ทฉะ8{ฮRฏnํ0ํฺ �z๕๕ทeื๎�แ๎ฏฑf๕ชา๛�ทๅพ๛<Ÿฦ๓=fี๊ต๒RืยŸฎผิต‹คH‘ย๗นvํšŒถŸ�>�า์ำ็�ผaต�•ฬ,”ดiำzํำ้�zทท๔๙ฐท$Mšิ์ำ{้=�หํK๗ตYG@@@@@ฑ~OŸLบฝ์๙{ƒopฐอsD ธ—�?soJๆฬ™ฅQณ–’4Iฏv๗ฦฐม_‰�ศ‚…�8*๔ @H ใv[ตn'2f47™8~Œœqฮ;u๊ด™Z๔�๎๊ŠZ้ฐ็›7๏แœไณฒ|๑ัj€๖ฒ?$DVฏY'9s>,ฅK–ฐฆHn๏’บสสีkฬ๑ ็ฮ๔ฺงjงS?Wซโ๙!\Oิ็oึชญูWงVMSาพเะแ_ห€ƒํMq/X?|~ฒดู๗ษGฝฅqรฮq œท`‘นv›g[y‡=ึzฐ๛z๖ษjถk๗3�ใ&L’ๅ+WษฒE๓ฬ๔วzŒ๖W฿�.?�˜h๐า~ฏธƒกz์ค๑ฃฅxฑขบj t.ฑช,�ฐฎaOปm๏ำWwฐ0.ฦา}/ึ@@@@@@ภ#๐Dพ‚RญF ณq๐เ™9mช๕ป�dานkw๓7€3gNKจUm0sฯ฿Kfฯ˜n� ฤฏณ6u๎๚’YืPแะA_y.๚฿ื$w&ฑfh*/๋Vญ’๋7ฎ{ํ๓— ‚…�2๔@Hd ใvภc๒‹MจPŸ&&๗Œฉ‚oฐ0ฒ๋|๔ษg2~โทๆ฿Ÿ�สWฎ๎Lƒ�๋7ๅู–อห้๔ฦ:อฑฝ,]8ื ๏๙Vโำ๊x?m^็TกำฐXฝ†Mช„ZฮŒ)’้ฟJ’zอšu๊›)ˆ}๛u๙๒eฦsWิใฬ™.yr็ึUณtฅง,�a‰ฝ)๓gO—G๒x๖_ฟ~]Š–(kžอทสaํgษ�}๛๓ึฎ\โ๔Kซๅๅ-p3๔ๆไZฉYฃš �โf˜s๛_…‘๋@IDAT/;ฌR�ญœ#jีฌaM?|ณ��คษSไ�>ฑฆM~KZตธYpฺŒYfฺ_๛ฤ๎];Kท.์MYบl…t๎ๆฉ๘ณe›&Mณ๏ืปค~cฯ8ฉ๋ฦ5หๅŽ;๎0๛์J‡:[6ฎqย} ,Uฎ’sm ‘.Y8วู�ถ�i��๓ฉC฿`แ"+@ฺํๅWcํ•๗�~รNu[ร‘ฟ�ฮ�%ƒพ�\jTป9esีšuอ{Aร˜สดkฝฏ=บ�;ซบdฦ ์Cผ‚…ท{,›ฐ‚ € € € € €^eส•—โลKšถ={vษยysฅQ“f’5[vนqใ†Œ�fธTฉRCrไฬiŽYฝr…l�ฒูฌ฿w_i�ฮ3ƒ“ฮ5n๔ื^ื„ ‚…0J๔@B‚…q;จญฺด• 2™›Dg*ไุ† ฝฆB>๙—L76N๐v }ซ๓+ZฤLQkw^ซj%;{‰,XXจ`~™:yข}จLž2Uz}๐ฑณญ+:ฐN�k/๖”ฝพมB฿@ฃ}�ŽŸ6‰~ยM฿0Ÿถ้ษีซzช�]ด*๗ๅ™’z๛–Vฉ�”zˆhญsW๏้{{X ไฯg๖๋;็4๘ฌtั พx3hW$t๖�sm$mšดฆIซF๎๘uงŒ5Bส”๒�~๕๊5)[ฑj˜i—7ญ[)๗Zๅ�u ๙ํ€ _๊บV\ิj}บ่๋ฅสU6็๚Vqด๛โ;�ำ)Œ�หˆก๊‰๎เก;Xจ^Šz๚์>7ผu 3fฐiำฆ‘šีซI‡๖mรtชeญ˜Xก�S๒๕๐›ี5Œ๘มวŸ:ว้Jป6ฯส�o๔tฺ� o๗X:7a@@@@@ผสUฌ$E‹>iฺv๏�Uv๏�% 51�[ท�(ซW,—บฯ4\น๓˜ถ๕kืศฆ๋kผ�๊๋ฆ0‚ฮztเทูผqƒ?�งณ฿฿W๚๛ั?@@ Hฦํภ6nฺ\ส๊™w๊”ษr๔ศแo�Pก^X๏ฅ๗ิE๏ฅ๗Œหล7X่ฎฺ็{฿ฑใ'šjrฺ๎เ๋�ใ5Yธhฑื)ปถo•dษ’šถ[ 6nX_>๙่}็Z:ฐ�K‘ย…dŠUฮ^์ภ˜oฟบtลšwน}˜yีi”ืฌธYpยคษ๒aŸพ^ว„ทก�6ญ]�ฎ�ยปฟ๛เ�}๛Hฝบตฆ<tึ#[qOŸ|๐ะ!`๔=~ผ๕‰ฝR%‹›f๗ยๅž*#ฃF uท๗‡2e๊tัp Nฌหikฺ่’OU4๋ žฉ+Ÿ}๒‘Y๎๛9�มย�{๖J�ž_„w๗&ศร9rH๚๔้ย;ฤดูมยถญ[ส;oพ๎�{Pง…ž7kšsŒ�>‰‹ฑtnย  € € € € €x .RL*T๒t8xเ€<9‹คH™B.^ผ #‡ 1ว6nฺย๚;YVณพ`�ูปgทs๚KŽžj†vฃฮ8u��yYปz…์฿ทฯn๖หW‚…~9,t @~‚…q;ฦีj<-Oไหon๒๓ึ-ฒrลฒpox;B…zแ +Kแขลขผ_ธˆAฃ;Xจ?|ฑฆ�ฮโเk฿ฑ‹ฌ^ณฮ๋TwUภ[ ๚V™ /œ็c…?้�/Lเ1ผ~๙žQUCฏ‡ฑ6|ฯ๓��vxกH๗qร%•+U0MZ=๐ั|…�ป#\฿ผ~•�s๗�fฟV๏ำฐ๏2|ศ@ฉ\ัิ}vุOืืฏ^&๎ฟ_Weู๒•าฉ๋KฒmหัJบ|๛�๗า๛ร>f�นถญๅญืรN_lvF๐ฅDูŠฆ ข;Xธm๛kชโ›ำ<ปO๕๎ุฝฯw�พะพผ๖๊อŠ‘๚ ๚,๎ลwšf;Xc้พ/๋ € € € € € pS {އ …L’$‰h๕มo'Œ“'�2ถ|ถญdฬไ™El�ุQr๚ิฉ›ฐึ4œXฒtgF*๗ฮ๓็ฮษุั฿ศตkW�อ~ณNฐะo†‚Ž € €‰K€`a�Žw๎�Hg๊››œ;{VF}=<ฬ �a@�น๓ืฒxั‚0วEงก}‡N’.}zs่�Y3%$$n?aๅมB฿ะขNoซำ�บ฿ip5TจแB฿sร ๊u๖๏ฺ๎\ฮwgg‡ฯІ๎4|g/ว�๘C|5ุ� ๗u้ฒr๑าฅp๗ic๏w฿’V-n†Ÿฒฆ4>�ื‰ทwธ{'Nž”2ๅซุปœื้S&9ำ2Ÿ9sF4์g/๏ฟ๗ถดl�ิl^ธpA^}�mSฑะ�ฏ@ ๊RณzU8 ฟฝKVฌZ-๓,rถ}W�๙็ฑ+_บ๛QฐPงtึฉํๅŸซWๅgkบๅอ[ถZแฤฟฅ๘“ลL์�vฐฐfj2๐‹~vณ๔�โ+๑อhg[WชWญ"ƒฟ๚�iณƒ…q1–ฮMXA@@@@@/TฉSKวฮ]ฝฺ๖๎ู% ๆอuฺ^่�ขคNฦl่�™ำ๎ปr฿}$ม๒่ฃyEฏk/ฟ…์—9ณfุ›~๕Jฐะฏ†ƒฮ € €‰G€`a�u—ฎ/K๒ษอย›๙•žo8ˆMจะ= r่•P:๘K็บqตโมB฿*s[๚Yšตj๋E0 _ฉ�tMงอF7Xธa๕rน��๛ฬ๙gฯž“bฅžrฎฅ+:อnำฦL›~rฎi‹ึ& จS!๋4บบ\ธxQ ?Yฺฌปฟ่Tหษ’%3MGŽs๏ ณ�บU y๏ํ›๏;๘fจธqฃGZ?H{~0ž7ก >R|+�ตm฿QึmุhŸ&jธh�L๓‰?m�ถ�ซZเณฮ��๙ž฿๋l๏�ท฿Tdิ†รGŽJๅ๊ตœ}นsๅ”…sg:�›6�(ญฺ>๏l�+Yzะฌ^ผtูT+ิ่ ;vh/=_้n_F๚๔�?;~’ณญีตjขฝุมB฿ชƒ๔ฌPๅๆ{BŸ:y‚ฒ~น`/n฿�=–๖=xE@@@@@ฐ�_้้��"4๔Š ๔•sะw�)บ�Ž;๎0U}๙…ณ/ฒ•"ลž”๒*™CtfฎoF ์๐�Gฐ0ม่น1 € ธฦ�๘ปงC>r๘ฐL๛~ฒืMK•.kJฏG6Uฒื lดj�N2dฬh๖ฦ& มๅรmv 5@็Ÿ๙žp์?ภXt|1 Y๏๋žชWท!_ ๒�0ุฒyy๗ญ7$iาคบK._พ,ฅžชd‚ั้—žใ;MฐVแ{กs7�%%ฌ y#‡ –TฉRšmw€๐›แCค|น›ำEk…<ญ”g/“'Œ‘ย… :?�S�๛}_ฯ›WfM›l~Pึ}Z�ฐGฯ7e๙สUfZโzฝ#๕๊ึvN8x˜h8ฎ]๋V๒๖›ฏ9ํ‡–็;u•ƒ‡™เใจC$฿;๛วŒ› Ÿ|vณ๊ ๎Xบpฎdฯžอ9ฦ^ oj่M๋Vสฝ๗�cั๗Iง_’•ซื˜m ~;aฌh RํK•šuฬzt‚…�บt’๎];›ใ๕หะแ_ห€žJ๕๊ิ’?่ๅ5ญ,ิc—-š'ูฒeีUณ่ดะฃวM4๋Mึ7ี��e^�มย�=–๎๛ฐŽ € € € € €�M›ท”,>d}ซ–ซPQŠ+n๖ฉSฟฑi‰N€/6มยF ž‘O?�ภuwb7I’$Nhฯ�้‹Eง_zžV๔[0g†UYะNิ6‚๗ฺีkN P�t™ท`กผb…�tั๊}sgNuBฺฆU ฯ;'9ฮ!)Szยˆฺพ�—าจY+]t๑ญพจŸ;w^าคI-๚ ={นvํšิฌำภ„ตmษย9ๆ9์�7n��ง‹บิ๕3�-•ช>fJๆ/u“ฮรVฌZณฎs=_ฎYงmถ—��Wดสa’$wสร9rx�oิ˜qาทŸ็“„ั VฎTA†พฮิ{hXTŸ]ฟ๗|wฐฐ~ฝ:๒Ÿ~์{H„�๎๗J\Œe„7f € € € € €‰\ภ=s—�=cู’ไืฟศ๙ J•jีœฟ‰Œ;JNŸ:ๅheห–C๊5l$Gญโ ซV.ทŠ`œ6๛tJไšตj;E;Ž>d๙ฮ9ฯŸV๚ำhะ@@  ,ŒŸมถซฺw oJd{฿ญพบาs7ฎ_'ึฏฝีหฤ่๘[ ๘� TฏUฯ�':พุ ๕&พำ�†๗€[ถ�$อŸm็์ŠNฟ์ƒ;ฝ๐ผผ�ญK˜ ขฝ__>"u4๑ ๅi…ฝฎ]::?เบทืO:-ฯถ{^B~;`7E๘ชS+O™4ึ+$�มพSkeล!H๚๔้ย;�ดi@๏wzษยE‹รใ;ๅด �4ธ�2สš> �Seย�ๅด้”ห:-ณV^ิ%:มB=nๆิษ^ต-ขล,ิctๅํ�…;ณๆฬ•g๊zช'๊ฑ๎`กn฿๎ฑิkฒ € € € € € €@๘๕5–9r†ฟำj�ทgฬŸ7�kฮœนฅ^ƒ†N›)ด`@Hjฃฐm›dอฎt๊ไIปษฏ^ ๚ีpะ@@ ๑,Œฟฑnีฆญdศษ�๐J่™;kฆ=r8VะPag๊KŠไ)ฬuNž�K&Žซk�สษพำมFv๎ึŸ~–fญฺšCŠ.d…แฦ9‡kธOC~๎ๅว ซๅ๎๔้Mำ„I“ๅร>}�S'OB ˜ํ%K—K—๎ฏ8๛�+ žฉ+�^์$fษโLฌ๛OX?Ž?IFŽใ>\ขำ/๗ ลŠ1•๘ดzปสŸVGœ:}–๔๛|€’sŸWฒDq้๕ฮV•ย‡ฝ‚‰Zer�‚E2ฤšบY+�สข๋ิz:LPpHˆ|�ๅ Yถ|e˜หi(๑“{K้R%ผช%j?4ไ๗n๏ยTt_ฤ7ะื๏๓/ร˜บo�บฅ<�\[ษ๔฿”�๖พำงฯศ”ฉำ)Œํ๖ฑฃFH™R%อๆฦM›ญฐe{—ืซ>ว๛ึ๓WฏVลต"ข†7m๚Qพ๛~š|=�3uถW{บ^˜gา{TญRY๒>๖ˆU…2™์๘uง่�~�ถ]ึฌXโ�ห7Xจ;โb,ฒ‚ € € € € €^u๋5‡sๅ๒* มภ=ปwษ ็{ซZ™ฐQำฆึ฿ARy�ญศ>๐�…๓ฒdัB9t๐wปษ๏^ ๚�ะ!@@ q,Œฟq๖Y๏ผrน5-๒O1›นpk๚ใJž้๕Z๑9ฒ�/ะ–ว๓ๆ•๋ืฏษQ+ฐgWฤปฯ ืฟ็๎๔r๘ศ‘[ ๆฯ๗„คK›VŽ�๑g˜ภ[L๚ง!ปG๒ไ–+W.ห��ฟE๛Yณ>๔ 5s*k ํnK?"๋{j๋>y๓>&Iฌ้Š>,ว�:ูแทดO+)๊ณG็šZก2c†๛อ๕๕x฿๐eZ5ๅ‹~7ญฝ?์#฿~๗}„�น�cแุ € € € € €@"ศ™;ทdอš]��ป Œzจ$w&‘\y๒ศ}๗฿/)Sค”ำงO[@ŽXฏ�Yฅะ=ผ �ฌ#€ €ฤ›มยxฃ67ส`Ujk�ค…$O‘�น๑+XตqรบhW/ิ*…*Vฝ–ฝhจp๊๗฿สษท/ e_›W‚U`ู๓%[ึ‡ฬใi5รพ�พYsๆI๊T)M๕ร็�ตต>ษxฏ๓๘ตŸi${๗ํwถYA@@@@@โZ€`a\ s}@@p†หงZนฐqณๆฮดศ๖อฮ=+!!๛ไ7kฺ๊Pkชd;$จยไึTวนฌO^ๅฮ�ˆค๛oz`๛<�x๊w“ญsBํ&^@ =_้.;ดฦ‘"ซVฏ•็;ฝญc9@@@@@ธ] o—$ืA@ธ%‚…ทฤu[.Uบฌ่tฦ๎๊…ทrญRจำ(oXฟ๖VNใXp ่฿Wj?]ำีvuำๆฅc—๎ัžV:์hA@@@@@b&@ฐ0fnœ… € K‚…ฑŒๅ้Zฝฐผ5ญฑV"ŒnภP…ZูpีŠeT)Œฅ?ง# … ๆ—ฆIŽ์ู$}๚trํฺu9�ผ๛ใO™1kŽl�ด(@@@@@@ A&;7E@ X่?๏ ๆดฆ;NoMuฌ!ร 2™ฮ้Tว&ิฉ‘9bB…�ำkz‚ € € € € € €q%@ฐ0ฎdน. € €@ค #ๅa' € € € € € € ` Œž#€ €‰[€`aโž@@@@@@�W€`ก�Ž =C@‚Z€`aP/‡ € € € € € €,@ฐ0€ฎ#€ €,@ฐ0Gพ#€ € € € € € €@0 , ๆัๅู@@? X่วƒCื@@@@@@@ Q ,Lิรฯร#€ € '@ฐ0แ์น3 € € € € € € ™มยศtุ‡ € g ใŒ– #€ € € € € € €ฑ X+>NF@ˆฉมย˜สq € € € € € € ท ใึ—ซ#€ €D @ฐ0š@@@@@@@ X˜ภภํ@@ฤ*@ฐ0ฑŽ<ฯ € € € € € €�.@ฐะ฿Gˆ�!€ €A*@ฐ0H–วB@@@@@@€ X๐Cศ € €)@ฐ00ว^#€ € € € € € €@๐ , �1ๆ @@ฟ X่—รBง@@@@@@@!Xศ›@@ A&;7E@@@@@@ข X% € €ฤ…มยธPๅš € € € € € € €@์ฦ�+ € €ฤ@€`a ะ8@@@@@@ˆ‚…๑€ฬ-@@ย , kB  € € € € € € เ �a่ € &ยA็‘@@@@@@@ ฤ0ัI@@ ๘฿˜๒D € € € € € €  ƒcy @@ เ�ัa@@@@@@H$ ษ@๓˜ € €€ฟ ,๔ทก? € € € € € € €€G€`!๏@@ X˜ ์�@@@@@@ˆR€`a”D€ €  ใB•k"€ € € € € € €ฑ X{Cฎ€ € ‚…1@ใ@@@@@@@ ฦ2ท@@+@ฐ0ฌ - € € € € € € €€?,๔‡Q  € €@" X˜GF@@@@@@€ XรD'@@เ X|cส!€ € € € € € €@p, Žqไ)@@€ XpCF‡@@@@@@@ ‘,L$อc"€ €�&@ฐะ฿F„� € € € € € € €‚…ผ@@D€`a‚ฐsS@@@@@@@ J‚…Qq € €@\,Œ Uฎ‰ € € € € € €ฤ^€`a์ น € €@ ฦS@@@@@@@x Xศ�@@ ฌมยฐ&ด € € € € € € €� @ฐะF> € €‰P€`a"t@@@@@@B€`a@ D@‚O€`a๐)O„ € € € € € €ม!@ฐ08ฦ‘ง@@N€`aภ F@@@@@@D"@ฐ0‘ 4‰ €๘›มB๚ƒ € € € € € €x๒N@@H‚… ยฮM@@@@@@@(FIฤ € €q!@ฐ0.Tน& € € € € € € {‚…ฑ7ไ  € €1 X4NA@@@@@@โA€`a< s @@ฐ รšะ‚ € € € € € €๘ƒมB๚€ €$B‚…‰pะyd@@@@@@‚…1Lt@>‚…ม7ฆ< € € € € € €‡มยเGž@8‚…7dt (Rธ|๚๑’๕ก‡ไ‡%Kไ•žoล๓6m�P’$Ibže๖œyr๑าฅ=ื™2JฅŠฬนWฏ^•ฉำgฦ่:๑q’ปฏืฎ]“๏งอˆ�r@@@@@‚J€`aP 'ƒ €Žมยภ+ํiปึญ$cฦŒแvOƒOฟ��ป์�นKB~;๎1ิุตsGI:uธ]พ~�š9zL๖‡�&?�ผ-�chŒZ`ฤะRฉBy็ภg�u›6;�ธ๒x�ผ2{๚wNืŸ๋ะYึฌ[๏l฿สJ‡๖mๅ๕W_qN)Qถขœ9sฦู๖ง฿พVช๖ด๙๑ง>�ฎพไฮ•S๒>๖จd~เ็’๚�ฎ�ปๅ๘_'œถธZyก};)�d1ษ‘=›�}๗�rโไ 9t่ˆL›9K–-_Wทๅบ € € € € €@ผ <๚X^)]ถœคI›V’Z่ืถ_8wNVญ\!„ฤ{โใ† ใC™{ € €„†`az๕e๙า%r๑โ…0ฯGC� ์ฺพU’%Kๅ.Z,oฝ�;ฦ•ฺขผA4ะPVš4žpเŒYณe�๖ั/บมB}ฯš6E๎ป๏^sQ�ฟ`ึœy2i๒ัjฅ๖ขS`W(_V:Xำง๙o u 7mูZv�บำ>,ฦฏฝ฿}KZตhๆœฏS/ตช"ฆI“Fjืช)ล‹u๖iเพ๐“ฅผbฌำ!V@@@@@[จYซŽ<–๗qsึมƒฟหฬi฿;Wh�พƒ�s็wถ�~ฺ*+–/u๖ร มย`Ež@@` ๊�ธ~]ถn๙Q6n\/ื‚์I�๘s‡ํยซ๒ีฝkg้ึฅ“ำ๕ใว�’ง*Usถํ•Jสห็•\นถ*}%•~—=๛๖‰Nกูาธa}3 iๆซืฎษ๑ฟ�’Ÿทms^ฝ:ต$sๆฬ๒๊ห�œหญXตฺwร �ฬถ‚AQ-Q=k๕ชUd@�ฯœ™^ฏPฑRN˜ง~ฝ:NiวŽaฆJึ R้RลM7Nž:ํี'}ฮ๔้ำ™}?,^*gฮ�-ีชV–ลŸ”ดiำXี หŠ•ซeหึŸฬ1ท๒E๏[ญj%yะชึ–>}z9}๚Œ=zLๆฬ›/Gฌืˆ อUฏVEษ“[ฒgห&—ฏ\‘C‡[฿{›ร<[t�ตยจฅK–0ทผbU'O™๎ํoๅ�ขแVํง.ืฏ฿1ใ&HŽ์ูM่ซHแยV�5๋�vะ ‡อ๐y๏ฝ๗^iTฟž™r6C†๛MUบใวหrห�งŸท…�GmฌYฃš �ขŸณ_+vjๅ:๗ขU‹*(y๒ไฒฦ2�๙็Ÿrเ๗ƒ2cๆl็ฝc^ฐ0ตl-๗T)\จUฑ๕†์฿�›Lณฮ=sๆŒ}Z˜ื"… I1ซŠขŽ]*k<({๗๎sยฒaN๘ฏ!6}ญTํi/฿Z5kX฿“7ซํอณ‚บว�:แ�Zวญl™าฆZI๐ไษSฒoˆฌทช>jˆฮw)Yขธไ{"ฏi๖��ัF}ฟ6oึุ์ฟ~ํบŒ?ัฌ?e�ใ�๛๏“zฝ#)Sฆ4m‡ฌ๏'{๊โUkึyYN<ัชT˜฿งกยบ†yฟ›�}ั๗NŸzI•สkWฉYวฌ็ฯ๗„๕=\ฬ9|๒wSรŒนŽU‘ยอ17n�+ฃวŽ7๋ำพ›( x๚กc]ฉZ-ฏs็ฯžn์์‹๋tศ:-2  € € € € ˆ]บฝ$ษ“ง03— 8ภฉJจืh��น๓ฮ;อc]บtIF ๆuลสU%หƒJช”ฉฬ�ะBๅฬ้ำ๒“๕wลฃG„9ว_๚หHะ@@ ‘ cฐะยณgฯษฒ% ๅ˜a‰;จยvzgwภลทr–†‡พ่ื7ฬ”ขv5@๔๚[๏†ฉ๐ฅAชO>z_2eฬh๊๕z๘ศQ๓ƒคใ๔ห/๐ฺ๏ปQ๛™F^ีฦ|๗๋vtžu@�พR๛้šฮ้๎0ฯฆu+ช†‹ฌp`ท—_uŽำ•w�|]ฺถn้ดๅy�&า†�ปถ;ํใ'~+uญ ไ�ึห๎Em54๗้�}๎nŽt}˜5%€x๒=๐šิ;~’h•=฿ฅf๕ชา๛�ท ค๏�UซืสK=^3Aง[๑�ีWฌ omหน ด1&๏ |�๊ฆษภมรคk—Žฮ/์›]บtY�~๏}™ฟp‘�d^Ÿฎtฑณ:๓ฺimhXKว9ผฅoŸฅกHิE฿‹ฎณ บ}๚๑&|hทน_ฯ��ท|๒Yฏ€ฉoฐ๐“พ�ไอื_ ๓,็ฮ—ื�|ว >ฎr_าฌ๗๏�G๊ีญฆ]๔๛ํีื฿3…๗ํ่ซ;X๘lหๆา๋7>จ}๓g�9๗U๓—บv‘)R8วุ+๚พmฝฯ๛}�ฅ�d^�๏ๅ“งNI้r•ฝ๖WฎTA†�สik฿ฑ‹ฌถBƒkW.‰๐�=XฟŸ์0Ÿ~๊๗ฉ.Zกตsื—อ๘kxฐJฅ ’'wn9๖ว1Yถ|ฅ๕ ฎไ’+gN๓ห-‡™S'[มววอน“&/๏ิG�ฒฦ๎นถญM›~๙ฐO_™0iฒณญ+cG2ฅJ:m5๋ิ7ใ๔ร�ู’๓แฆ]ƒั=ญ๑v/oพึCฺทkใ4uทพฃ j;ณ‚ € € € €๘‘@าคษฌฟฉ๔0=๒ ถyฎƒ่๏h�‹p/ZxขQณ–’4Iwณื๚0๋๗วWฌ �ธ,๔วQกO € €@"ๆ`ก=|{vํ”ีซVสล‹์ฆ xฝ3S2Iูไ>น�ื?rๅ๛ˆ+“ล๕รF'l็�h์Ÿ†•V-๛มฉฤQ_�นzUjYS �•�t*าล ๆD๔ฒฏs๘๐ฉ\ฃvผ วiU๔T�ำ~t๊๚’ ้๚ํ ๊ต"[Zตii5๛�ท฿่)ํฺ�\ธ}s7๊Tไ=^ปNt�?Wมยน3งสc>bบao—xฒ˜ ะฯ๋WZษ๐โลKฆขฌ•K3dศ sfL1�oู!Sตต ไ>฿้E{ำผ�๚๓fRิ฿ฌJฎ5j?cฺ๕๛Aซ•๊r��ฏqึถCŠV๖ิๅบUษทh‰ฒaŽ1;๙‚ € € € €๘นภ™ณH๓–žฟg�๓™ำ4 2P*W๔„ณดAงfึภไCYฒHท;YฟtHkŽำ๐ž†ว�‹พ็๕ฝo/]บฟ"K–.7›-š51&๖> ฮž;฿๚4dจ”-]Rฒgฯf๏’_v�* ›z*Y†,�ใ?eซ5sแBไ!k ๗๒ึปฝeฺŒYฆIงฃ๎�ู'ฮn j…K]ิจPมฮ>๗{่v๕Uƒ…YฌO…Ž9ิ สiเM+$ฺU"๕}ฅf๎๗~๏๋tำ:Mถ๛๛W�/iึชญ3uLƒ…:U{&๋�šF žqยŽ[ฟTZl}้ขะฟ๎4๗Ÿ7kšiำ�77๗�ห5;ร๙bO‰n๗ั��เขyณฌส†›ณ4X ่อ๊„พ๏�AC‡‹V�Œjั)ซ'Œ๙ฺ๙ฟ่ืปค~ใๆQฦ~@@@@@ภ/žศWPชีจa๚v๐เ™9mช๕๛ฯdึ‡ึป›฿ƒž9sฺ๚[เษœล๓;๒ู3ฆห!ๆxG?�ฎ‹† ‡บ9ณถ%น3‰”)_^ึญZ%ืo\ื&ฟ[๚�ะ!@@ q$–`กŽๆ฿ึดข๓ๆฬ”S'O๔เบC…�^น!—วŸ”]MฐgŠ*l็;ี็ัcวคbีงEซm�ดy3…ซVIซืฐฉS•PCzZ�ห=ีฑา{๕ๅnา้…็gnะค…3Uฒ“^t…‡ aฆ ีƒ5จธfล็ผ�_|%#พํlGตโ~V s}5xจ9E(}ชLi)cยRฆL้\ๆะกรRฅfg๛v 5่ง?]|รGยjฺฒs฿๐Vิ�ƒ�๏:�฿O›แ\OwO๋ฎ�ฆีๆZ�์e๛/;ฌ้Zู›Rซf ๙๒๓›S Lš<ลš๒ีf‹ŽDมยุผ_|}4ภZพru'HชS๒๊ิผ๖2โ๋Qาภ@ณ9yยั–.�ห[ จYื/Z ฎZUOPUงลํ�agŸฎt์ะ^zพา�ด้�|…‹;๛ฬ™nฆอตบฟาS�p๓ฝ้ž>�]mฮ7XhWๅดฏ๓๑ฝคiใ†๖ฆy๋๛\฿ชƒvๅP๛`๗˜ปŸ๕v๕Uƒ•}?�Pาฅ๓„15\๗มวŸˆN l/ฝ฿}KZตhfošPค†#ํฅ{ืฮขA@{Yบl…t๎๖ฒูดC{บแ~ฯฺวF4ฒฝีาE’%Kfณ^ๅ@๗{�žฒธqร๚fJv=Iอtใ฿ฒ�Oอผฦืพ��Eyฑำ ๆveQ฿gุ๊ฅป3…ตN•ญG]ิซr๕Zฮ�gฆ1œ/”2iฌWล^|lBฑแN € € € € เ๗eส•—โล=ส�ณg—,œ7W5i&Yณe7ล#F3\ชTฉ!9rzŠ\ฌ^นBถn๑� ๅพ๛2H๋vฯ™gิ™zฦ�ฺ๏Ÿืทƒ }EุF@ˆฤ,ผaUฤฺบๅGูฐ~5ไตxqซ›๘[จPŸำถปz๕š,]พย<พ†‡๒ไฮ%ญ้?�ห`+่๗ี กVuด�2u๒Dg—V‚ำ๐‹{ั้PuZT{ัiOu๚S฿Š…Zmo�‚…ขa M›tc๖y๖kt‚m๖ฑแฝบŸ5ผ�๎6ญ‚๘๚[๏š*tv๛ํ ฺแL๛บ๚บmหึิ๕ฟ”๊ต๊้๊--ๆLgUเป๗�{คk—Ž&,ฉP฿ข%หškuั vY•๚์ลฎHho๋๋๓ฯต‘ดi<แ1}?hต7]ขใQฐ06๏฿`กปŸ๖Kƒƒ ดญVจU u™4n”W๕FยvึœนฆJฆVยŒlqŸ๋[๕qวO›Dฉบ๘†3ตMงศญ�_h๑ข5๕ยศQž�๙ ‡�F>�ržb–wขีg{™>sถผ๙N/ณน}หFkชO๐U+ใu๎๊ ไูว๖ฐป๒็ณ7ฅjอบ&่{ป๚๊\๘ฟ•/‘!รGz55Bส”๒�rH�?)[ฑชื”ฬzฐ๛๛(ไทขc]โ:X๘B๛v๒ฺซ3ปช;8ํฎbจAใั_฿ฌ,h 5$จaA]์)ฦ5 ฝ์‡๙N๕P ๙พำหsŒก๕๛F—๐�'f‡๋‹^๋� cst—Vƒ|๙ี7\GฑŠ € € € €–@นŠ•คhั'Mงw๏�Uv๏�% 51�[ท�(ซW,—บฯ4\น๓˜ถ๕kืศฆ๋‡|๙ีือ๏`๕�~ ‘อ7ศ๑ใ 7˜ำฑhฎ,Œ&‡!€ €�^`;zD–/[๐U uิ�1Tจ�บ•ฐฬดบ .๎J_บ�๓อwD_๎ฅHแBVๅญqN“= จN1;{ฦ๗rWฒdฮ>{E}{๖๎•‘฿ŒuฆWต๗E'ุf�ktŸU+โu}๙Uฏ €z=w jัโฅาอ:ฦฝผ๓ๆ๋ึTฮ-ฆ<tึ๗๏ฺ๎ฌ‡ย�v�yฒ˜งฒ^tƒ…ZฐsงRฎlkช๊\’,ูอ)œ›Y+๎`a�พ}ค^�ฺฮnwฦVขใQฐ06๏฿`a๗ฏษยE‹ฝz้[wฐะw`๗I��๓l๚q‹™6ู๗zz�ฮm?ŠNฯญ‹ป:ฆฏƒVนำ xัY|ƒ…๕6“]ปw{๊พฏ,ิะ่ฆตžะฏืม‘lh…มึ4ฬ๎*Ÿฑ้ซ๛V8!e+Tu7™๕ๅ‹˜้ฝuใเกC&�่{ะx๋ำค:]ท.:%x�"%ฬz\ ฿ู่ร„f๕fv๕ิ�๛Jํงkš๛ปซsjƒ๛{ึjตEญPจK๛Ž]ฬโบ>u๒g*jญ†Z�๚dญN�lOฝฌว|าทŸŒ3Œญm๎EC…“ฦ–ฬ™pš7l�,ญŸ๋เlณ‚ € € € €ข@แ"ลคB%ฯ B2g‘)Sศล‹dไฐ!ๆ‘7m!eอjึฬ›#{๗���y�F%GO5C๛๙uถ ๓็ฯหฺี+d�พ}vณ_พ,๔หaกS € €@๐ kฐ0๔Jจฌ]ปJvl฿fฆ ๔‘๔ืPกบบY9๋กฟ"}๚�ŸsHป6ฯส�o๔tถ5ฤดd้rg[W|ƒ5ชัp.ีซV‘zฝ#๗�wฏู๏หฏ;wI�ฦ7งธ๕ tนร^แ๏�ๆ~V}ฆe+VšC ๆฯ/<ษ9�‡%Kฅ๋K�กA�yป‚…฿Œ'Ÿ๕�ยนŸฎŒ5RJ—๒ฌข,ิPแ�Yำœ—ืล|6�มยแƒฟRV q>šฏฐYฮ—่๘G,Œอ๛ล7X่tู�vWๅs uฟมดzฆดฯqฟN›1K�S๖๚�ำข้9พ๏k๗ิห๎k†ท๎,ฌTํ้0Sใ�ฒuฃ3%ท,๔ฝgxื๖mำฐ๏ž={ฝยmฑ้ซ๏๕๕�ƒฑใ'y5o^ฟJ๎น๛nำฆI N๚.ร‡ ”สห;อvธ5ฎƒ…:�บNรฎ‹]ฉำ=u๓๊5๋LXP๗kลIzฺ^์`แ /?—ีช˜fป"คnดk�J�~๓5๛pัiชซ[วูำ>๋�7ลJ>i5ึ)“ฦ;S9๋…ข3%บsCV@@@@@?ศžใaงBก“$Ib��๗ํ„qrโฤ_ฆ็-Ÿm+3y�V3~์(9}๊”ืi8ฑd้2ฮlB๎็ฯ“ฑฃฟ‘kืฎบ›�f`ก฿ A@—@0 C๖๏“ๅK—˜O)๙๛hฆhrฏ$ษt—\��ด�๘+�V�9Tจพ๎ฐ�Ÿ—oญ)ํ%ิช&ฆS•jภๅโฅKvณy๕ ^}๐๑งV๘๐fGชP๎)๙z๘`็ผ๐*vีฌ^UสZำŽ,฿ชบ—ำ�0้œ`ญ๔๛�Kgู่��็๚ฎปŸUง]~พำ‹ๆ mอฑ*(�y็f[wu4‘ฝ๛๖{]ย,ิitu:U๗๒อ๐!RพœgสamทSบ๎ฎ~v;‚…:ลด†ๅ์Eรƒ6mฒ*ิํ”sึ'๔ฺZAงœ็0ป�มBwJw>eMU{�ฏๆธจพDว?ข`al�/พ็�jฐPŸKƒ˜u๋ิ’R%ŠK๙ไม,Yย<ฎปz`Ÿ{K“F ฬ1v:๗ ๎๑๔šู}œ๏zLƒ…ฺ.�^Ž�๑‡ ๘๊ๆ๗–�๎~]บl…๙พฝ]}u_[ืตโcใๆญฝ*.๊๗Q�ว5‡ž8yRส”๗„๐�็NŸ2ษ™ฒ๙ฬ™3RขlEณ�,tW2ดฯuOeฌmพ๏ƒUK9ม<๗๗ท}พV๊ิŠบุกไึญZศ{oฟaฺ.]บ,ฏ๔|Cถ�ฒC>~�=ั๗ฝ่{ใUq้ขyr��๗ษ™ฟ�–e*ุปอ๛๋ว kœชก:]|y๋�?\—u6J�๖ใ�+๚}ๅ*�๚ำฯาฌU[๗aฌ#€ € € € €+*ujุ้นซW�๗๎ู% ๆอuฺ^่�ขคNฦl่�™ำ๎ปr฿}$ม๒่ฃyEฏk/ฟ…์—9ณfุ›~๕Jฐะฏ†ƒฮ € €‰G ˜‚…:�์๊ห$$ฤฟห•ป฿]ฉบe–;๏ถ>Uuๅ†\2Lธะ฿C…๚,…ํ�ฯ�zŽ์ูeษย9ฮฎ๐‚0๎iF๕@wHƒRบธ‹:�k—บJำฦ อ>�โm๙�F'}๛yW�sN g%ฒg8 ฟhศั^ย ญ_ฝL2�ฟ9ไŸซWๅ‰‚ล์รอ๋ฏ?o–ไษ“;mq,�๕0yส dฺ‹oๅ;wxห,tฉ๔\{zj๛::.ใFด~x๗�0>o�B2|คู�ˆ‚…ฑyฟฤ&Xhฟฯ๔�๏5ญHื๋7คh‘›฿~๏}3-ฒปbษy่มuU|ซj�†ีหMภLื๕�ฎbฅžาUgั)ฑ›6ndถ๕ำ—M[ด6๗iฐP/คS!๋๗ˆ..^”ยO�ำh}ั1J๖฿ใGŽ3อทซฏZๅฏm›VRฆTI๛vVุ๎ฐTฉYวูvW๔ำF ำ้๗’ฝ่๛`ัผ™N€x�๖_ฌpโณfท๏นvUA๛�ฉ“':A=ms�ข�๎`แv+ุจY+mv ๙้5tYผt™ผุฝ‡ ฎณพฏ�๏็ืสแ#GๅŽ;๎p*„6B4<่^�฿“ศ~8Gv็9ตฆพ|ฏ๏ฌ้โ�Aือึ๔�-�ด๗=”m@@@@@  บฟาำ๙ih่:่+็yด๐ƒ๎ื฿รjีมA_F๏o?EŠ=)ๅ+x>$ฎำ"3ย๛๗ถฮ x…`aทG@ซ@0 _๊๑šl�๖ณฌ[ณJฎYaญ@Z" FถฯŸž1ฒฐ]T�tํ๔Xwุฆe๓&๒๎[oHาคIอe._พ,ฅžชdยU๓gO—G๒ไ6ํสช฿ธ™3lอีdเ�ฬ>�bOซ๋พม62ธอsข]q/ฒgีภำยน3œ�๊�|CQำพ›h*+๊>]4(4โ๋ัrะชd๖้วHฃฯxv�๗5.ƒ…๎ฉ“๕vZ=Qซ(j@ชำ ํญฯ;}q 5P7kฺd๓รน aป=฿”ๅ+W™suzjญ์f/3แC�ŽŽDมB=?ฆ๏—˜ ีโงอ๋œJ”ฟ์๘U6mฉ]1K฿>Jร๚๕์M๓K‹…?,฿ค�2C��‹๏tพ+Vญ–:{ฆู-๑d19lฐคJ•าœโฦ&X่[sฤ7ฃMๅ=ป_“'Œ‘ย… :ฟ˜ัJ€Z๐v๖๕ฬ™ฟeฑ(ฮ˜!ƒ}[Yธhฑtท�ืลwJ` >o๕{DC‘ฃF ‘|O<๎œ;f�๙ไณ�f๛อืzH๛vmœ}Z)๕‹/ษ&+hืผicy�ฝทฑิƒ|ƒ…ห/p‚:๕pskฺŒm�w8ืำ;0ชUI�Xกว›6Kซอฌ�ซ^w�์ด๊a™า%ฝ�Oะ}ฺฏ็:t๖ ชj{�zuไ�>�XWฝ�ฟฏ@ั›aL{gxกB ƒ๊4์—|*ฤ๊9'ญ ๎pฌ}^@@@@@@hฺผฅdy๐!ำU฿j…ๅ*T”ขล�ฟฝ๛€ฒซ*��‘ $๔Z้U”ขาC/„ะ›ิชข‚ H๏UBh Hว€ %กKฏกา�ฉคคH��'�ร™ฬL2“™นๅ9k™{ฮ>m๏็ปqญ!๏์�ใ์�ˆแรใ๖�n™ฆ!ฅ่�/๛7qใพŒ+.mzฅŸizh\$XุจI€ ะผ@5 ป-ผHผ��ปอถLฏ˜Z€0uต๋^ ฦL]:5:›aน งฉฐ]s}LAบจ+�า๒จ;wnา)๏์3N‹ž…ei‹�_|ฏพ6ฌ0�_—Xyๅc–og\K็{์|“๑›@IDAT๑q๛฿M…�๊ Oว,ณฬRผ5๛LK๙๖ูe๗f†อ5…‚R8จธฅ>mฟใ.ลร8ฅฐ<๊.;M™….olbง-ƒ…i๙ึ4๛`q๛ๆ›ob�๘ ›๏5B• ำ๕๕g’Lm้š9ๆ˜ฝNp+…ณถ�ถW Kืคญ9�ฆ‚…-�พด4X˜๚๛๐เufƒ{�ƒโอท�ŽEบu‹e Koง฿~L[šUpอŸฌŸทJรS›™2]Ÿย‡�ธ๋ถ|้�ิ–ฎ๔ีคๅ�‡า์Ÿฝ{๕Œe–^:ฦย˜=�D\yU�H}๊น�ึฑโ๒หว่��'ž~ๆู8�ยK๊ผฃ๔เลgžlP�JMแิ๚�_ฏ๏_gฦฬ๚็๋฿|๋mq� u��ถ�5Ž  @€ @€ Pฎ‹w_"๚์ผkึฝ๔฿Œtผ๒๒KฑสชซGอ6ห�}b@�ซb์GๅรXb‰ฅขg๏cLแุ‡<�`แ๊วf็า’ศ[nฝM,ธะBู๑่Q#ใึ›�š฿WN;‚…ๅT }!@€ิ@5 ซก\๕ร…iL•*L�l.l—ฎijซฟ|้ิฎM3้ฅ๕Š[ ฅูีX`�bำT?งถ๑%ž›๕๘yƒ๋ทู~วxใอทด—647ึ4ƒุ๗฿['ธ๘ซ฿w฿;0{Lšqํม��่ฒฉi6ฑา%U�2X˜๚z๏ทล\sอY:ฤฉ๎ืฆq�ํ†�Y8nช7|�x๊้gF�7ินค9�ฆ‚…้A-๙พด&X˜–ท>๗ฌำฺ๋๊ ่�ƒำN?+ฎp}vT:d�๏n้ฝiVศ#๋W'`Wz>ํ5:ถ๋ตSžkMฐ0=/…โํwP�XR[�ํฃฦฦžฟุ?าrผลmF๗๕ศร‰C๚X||!ิ:>[า8�L36^rแy1๗�sๅ็๋๏ค๋>๎„<๐W<วญUV^ฉxX็3อnZ๚ฬ๚มยด�๔qว�ถฮ=้เOgžW๗ตงฟŸw��oฑไ’KdวiFรใO<ฉู�๏ศ.ž†?าlซiึีาญ฿แฟŒAƒ,mส๖๏บํๆXiลด7ึ0ต%นปV; @€ @€สQ`‡๛ฤRK-�hื�|�๕ธ๗ž;๋œ_z้eฃgฏ�y[๖ห์…ษf.LrQ�R� ื๕ +ฟ”ใ&XXŽUั' @€@ –O‘Kร…ฉW฿L˜ใ|“฿/๏ๅŸ/,;วsd๗�spvไQำฺk๛ํโฐC๚f3รg€K๙ ๐�ต…`ฺŸฏบฆม3Sธ๐ˆรŽอ6ํQg†ยtašUฎ!ไ๕—ซฏmp_ ZWmปอ–ัํ�฿BKณ๕mต]ฏ:Aช7ž{๊ั˜sฮ)Aผดฬ้�}ipYZ xท]vส�K—ธMซญบJ6Kใ ห/—_“O��@ผ6์๕8๑๘cณ๖ &ฤjk�$ฟๆ™'ษCQฅณ7/(]ฎ๖ตaร ฟ}๗�L‰ลk๊ฆพคๅaฐฺช‘ ’}2ฟ๋๎ฤ๘ ใ๓™ู’็๚oZ�๖ฌฏ�nฝU�ฏโoฝ�vœSX‚๖.6ๅŸอ๙๏ปฯ^q์oง|‡&Nœซ�hสา๙ ;ำ๛}YใG?,!ฟ๛.—}.}ๆำO yๆž;kบ๎†›โไSOฯOงู่>่€X{ญ5๒ถโNš•๒ฒ+�๗\lŠ—Ÿ{*บt้’งู้.น�ฯ๙น๚;kญนFๆ˜f,/อ�yห฿๏ˆณฮ9/ฆ{ำ2ำgŸ~j๖˜4Kโบ๕ศ–+.}๎S=๓อ;oึt�“�๘งาำ‘f <แธฃ ณ~ฟNจ1y฿๓๛โ’หฎศ—/ฝqz๛š–3�ร๏ห1ตพึŸ!ฐtfพ^=ํไc�u~’ฯพ˜”๚๘ย‹/ย|งิ™ ณุฯโ}›�lฃ|6ษ๔w)อภx๎gไN:e—Oํ{pะ�๛FŸ�;ฤ"‹.’��J�€l๚ป{หMืๅ�๚ช0หไu7�w��คฟ{ฅ[1(<ญKoฒ๑F…ฅ6.ฬ๑ษงŸฦื�(?.�).]]ฺึิ� 7�-N9mฺgtl๊Yฮ @€ @€ @ ฃถู๋+พฟฬ2u~>_๖Z�?๐��J3๎ธ๓ฮ…�ฆ;[�฿K/๚�‹ฯcะ}cไˆwJ›หj_ฐฐฌสก3 @€ฺ,,ฏZร…ฉW•*l ฝ•WZฉฐฌ์คSXขuZร8)dธX!4พ 1rTƒ US�LมŸi}OSฯ™�s)ต�rหฦ'…ๅ\››)qzŸ=ฝื'ƒ9็œMหBO๏Vห„B๑ญท�=]žญ๕oษ๗ezวWผ>๕u๑ล‹…\ฐฐ�ํ'1ฒฐlB�๏N�`ุดฬ„Y|~หผ๓ฬฃFžjฐฏx�Œ�Lแาน aู��฿ปS ๊5๖ฎ๖์k๗‚๙l๛‰�7อ}LตZa…ๅณ๎?๗�  ฃษ๖ฆพ›ษํผยL–ล™ ‹J�๑๊ฝ๗�ฯ หณฯ=ื\ัญ03h ิ๏๐โ%>  @€ @€ @`,ฝ์ฒัฝ๛’1โw กภ๏Vเi์ั;uŽe–[.ๆ_`ฺ่ฅkŒ;6ฦ�{�ุฑๅ9Ka้8 K5์ @€ด›€`aปQ{5 P:cec3=ึCอ 1-�ฝ�ถ[ๅณŸNmเ๕g-ฺ5ฺ @€ @€ @€@c‚…ษh'@€hSมย6ๅ๕pjL`๐ภป๓Y์๎ธ๋๎๘อ1วื˜@mwฝu~ห–H^ธ0Cแ�๓ฯŸ-ูฝwˆใ=:f›ญkฃ�9rT�๑OgฦรCi๔šj8ัมน…ป-�๚˜๑|๓อ7qๆู็ล—ใฦต)W�`แ•W๕3ฯ9ฏี๏l ŸVwส @€ @€ @€ฒXuตDอถˆ™fšฉA?'Ož๏น+�|๓็*ฝAฐฐา+จ� @€ จ†`แ/}tLœ01}tHผ�โ ‘BWถ๖8้„ใbท]všฆ—�๏ซฏb๏}ฬf0œฆ*๐ขถฮํ�งw�๑คr^;ํึๆK,งฅ๛_uE,ป์21z๔˜8๐เCgศRศmแ“รุ!@€ @€ @€ชN`๖ู็ˆ๚๖หC…cFŽ1ฃGล’K-‹,บX6�.ผ๔ข๓ใซยฟEUำ&XXMี4 @€@ TKฐฐH��{๏ฦ ๛ฦG~Xl๒ูฦ?\}ตธ๙ฦ๋๒ไา๋ฦŽ�8†>๚XŒ5:–Xข{lฝๅๆ1ห,ณไ=I็ทู๊;>�๘ใผญšvฺ"8ืมยถชI[๘ดU_=— @€ @€่x-ท�6V\iๅฌ##Fผท฿zs�ฉ}๖; ๆwพ์๘…็ž‡œŸซ†มยjจข1 @€*P ฺ‚…ฉ“ฟ�:ž}ๆ้x๒ษวcR•�FR9~ล�vรตฑฦ~˜wํตaรโ๔ซ์พ๘bqำ๕�ฃ�B ๅื|๊้q� 7ๅวลM6�(VYyฅXf™๏G็ฮ3ว๐แ๏ฤ๋oพ๏๛g๑’:Ÿi ๆน็ž+kป�Ÿƒ ห-7๏?Y{ํ๘โห/ใ‘วฏs๏Zkฎmฐ^,ฟ�r๑มฦ๓/ผท�qWgฮ7฿|ัk๛mณถฏฟžื\{]คู๛6�p�๘ัWฮ:ลศBh๒๑'žŒท�=ผฮฝ้`Z‚sK-นdฌฟ�:ฑBก -ด`�฿�ฝฏฟ๑f zเก:vฉ/ฉฟ�ฝ๕–[ไ๏๚๓Uืฤ�o�;>๙ไำฉ.-ฝiMbๅ•VŒe—Y&พ�zRแฺแ๑โK/g๙CšูIc�u—>๙Uน๚ฺ|ฟtgzk65ŸT—uื๙I|ฉ%cDaษ์_|yชใ*}ฏ} @€ @€ @ 6๚vDฬ:k—lๅฒK.{�–vR`o�๚ฤ%ž›๕๘ys้เู็ž]๖ุ'oOกผK ?”ท๔�฿�๎่˜sฮ9‹Mู็คI“โฬsฮฯ‚‡ฅ'ฆœ+=เ~ฟˆ#๋Wgวโ๙๔ฝ=ๅดำใฮป๏อšv฿uง๘ร๏+žn๐๙้�kฏณa�žฯ?็ฬ๘มjซๆmฅ; ฟ<๊่Bs\i๓T๗ื[็งูRศล“‡qT�?่ป฿๒kiอJ}�9๘˜ฝPฏ๔ฎ๚�ใO<�;rš๚Z�^ว @€ @€ @€@uฬ<๓๗โฐ#• ฆ~pp๏}ˆ4IC้v�ูg”ฦ"‹,;๎ฒ{ฬ�นs๖าƒห.พ &L˜PฺT6๛‚…eS !@€ิ–@5 ‹•|�ตWc่‡ให/ฟ(6Uลgงn฿‹ฎ;อ_ฟ�ฟ˜psว,)�k๛ํโŒำNษ=o๙๛m๑ป฿Ÿ”ื฿9๛๔Scžyๆษš_๖zœ{ม”฿K3ใ yเ�|ๆม๚๗�๗ีWฑ๕vฝ 3ฺ,6Eiฐ0oœสฮวŸ|๓อ;๏TฮLiบเขKใโหฎศ๊ ฝ้�'œ๔วธ้oทไ—•็๎x_Y๒ท_�๒๐8่€�Ї~๖;�—1h๐ƒ1=มยiuLณJ๖์ฝKฃ๏.žh*X8ญ๏šZอJ}Š๏j์๓…_Š>ป๎ูุiํ @€ @€ @€@• ,ผศขฑ๋๎S�ญเฝw�/nบแบlฤ?Zcญุx“Ÿg๛_� ้{฿๛^ถๅๅ—ฦ_|žซิ๏ฐ˜ญ๐oQi›8qB�๗ำOc�๘q… %ๆ.,ก้)เ˜‚Žล-อlYฒ|เม‡ฃ๏ท?๔ฏ๑I€ @€ @€ิ†ภzn?�๑Oณมพ�๚k1๐žปcวv‰๎K,“'OŽซ�ry๔่ฑE,ต๔าู5C~(ž}ๆ_ู��๓/{�b฿l�ใ?Žkฏพ2�ฏค? +ฉZ๚J€จ"ZNN3ุ=๓t<๑๘c๑๕ื“*บzๅ*Lพ์ขย์}ๆฆ›lถUŒ๓Ÿ�xZv~ธ๚jYHฏxmZR8--\บด�พ๑๋_M๙mฒิ�ซ฿w฿;0ปค4X˜fฝ�q—=๒[๗ุm—8๑๘c๓ใ๚ณ๔�rำu๑รีOณ$ฎตฮู~�`azWzg้ถืปล๏๗�วgs~�๙ชkฒKJƒsฅมยซฏผ,6Xo��1‡qTa*�๏–่�pƒ๕b฿}๖สฯŸrฺ1เ๚ณใๆ‚…๕Sˆ๒ย‹/หŸ•vฎธ๔ย|ถฤ๚มร:~{ะXฐฐ�ปฆทfฅ>i�๋oผi|9n\�…\|โ‘ฃkืฎY�๋oผ�๎ะ'?o‡ @€ @€จ ถIฌนๆฺู€‡ฝ๚J ๖Z๔ฺqง์๘ูgŸŽก=�m฿+–Yvนฌํ๑G‰งžœ2qCj8๒จ฿ฦL3อ”ญ๐4�฿oวฟž|"�{ฏcVห:8N'˜ห  @€fŒ@ต �3ft<๘ภ ŠŸฅ0Uป�B…ฉO'p\a™�)?ธฅใ=๖�/Ÿี/Oหึง๗qฺ)ศ/�๕1วลw�“ง4๋`š}ฐธ]t้ๅyhฎ4X˜f�Kณท4๛_šฐธีŸQ๑ผณOmถฺ2;�Tฐ๐ุใOŒ[oปฃ๘˜์ณ� €ฅแบาเ\iฐ๐ย2ศK,ัฝฮsš:ธ๎†›โไSOฯ.i.Xุk๛ํโŒำNi๊q ฮ-ท๒๊ ฺJ ถถfฅ>�*ฬน{แ{Sป�–›bีUVฮš?๛์๓X๓ง๋ืฟฤ1 @€ @€ P?Zcญุx“Ÿg#1|x,ผศขัฅk—๘๒ห/ “`\’ต๗ูyทXผ๛”ƒ๙ว=wลฏหevุฑO,ติ”ู ‹_&&๙�๓ฯใักล[oพYl.หOมยฒ,‹N @€ช_ Zƒ…'LŒG/ฟ๘B๖�G•^ษr &ำ4ป�ฑฟ=*็M!ธ†›žํ{๏ฟ;๚ื๙-ฅK WX~นธ็Ž[‹‡qอ€๋ใดำฯสŽKƒ…น๚ฺ8ใ์s๓๋fTฐ๐๐_�:�?(nฺIK)?๕่Cy[้ฌ†ฅมนา`แำO yๆž;ฟงนา%‚› ึฏEsฯN็ฒ�ฯ"M๛฿ุึXฐฐต5+๕y๐แ!qPฟรtแ†WวืZ3kOKQฏ๔ƒ)๛ .ิ@€ @€ @€Tตภ’K}?Ÿก0;w๎œ�๛฿ื]|๐~6๖�๗�'๊ึ-�ะ�ช๛ัGuLR8๑ง๋ฎ]บtฉำž>�์ณ่๕_bาคฏœ+‡มยrจ‚> @€jP ƒ…oฟ๕f<8xP๖[Jๅ^า.;อปอใo“฿Ÿ๚+ๅ*Lถ›lผQถผnั๙฿ร฿‰-ถูพxุเsศเ๛b๎yฆ๋^~๙•ุ๓D�e‡O๚ใŸโ๚�Z็�7� ฎผ�โผ-… Sธ0mํ,Lณ ฆูKท๚ณ(^yU�8๓œ๓ฒKJƒsฅมยปoฟ%V\a๙�1ivฦยOพ๙q�_z%FŒ™57,�r๓Mใย๓ฮฮ๑ะกq๏?๎ห๋๏�๏�k–ฌMcมยึึฌิ็ตaรขg๏]๊ฟ:ผ;–\r‰ฌ�ฝ๗� 6ูฌม5 @€ @€ @€๊˜m๖ูใ ƒญ3ะ7^-�qฯ�y�ณฯ>Gv|�ูgไํ๕wๆŸมXm๕ฤ +ฌ้นลํ฿oฟw�q[๑ฐฌ> หช:C€จj ฆฅl‡>๔@ผ�vyOW^๚ํšํฐEขำ<…฿ชš09ฦ๘ฐAธฐœC…iณฯ6[<:dpฬQ๒ƒื)งฎฟฑt˜ู~ฟพฤ/�๎‡พ๗�3�ีoข�’ยฯ>๗|์ฒว>u๎/]ฒ8ุ๏ ~1๔‘วฒkฺ#X๘ๆ[oวึ={ื้ำ้งžฝw่™ทx๒ฉqใ_oฮŽKƒsฅมยK/W<ฬ>ำLˆณฯึ5�=ๆ?๙น๚มย๚}$?ฟ์2KวภปoฯŸ๚ืำฑว>๛็วล๎‹/–ํ~9n|“ณฆ‹ ถถfฅ>้=ฝvฺ-^~ๅีด›m?Y{ญธ�ฺซЇ๑�๓/ฤฮป๏�!@€ @€ @€jK ญ.•f*L�ฤ‰โา‹.ศ:u๊้�L3อ”อ:xั๙็ๆ็šฺYcญตcฃ7ษ.Iห"�ๅŠK›บผรฮ vฝ @€j[ ‚…Gยi/ผ๐|<๖ศ˜๔ีิg�+ื*7l๊\9็๐CŽร้[งKW]sm๔/ฬ(๘�๛dKz๐ฑวnปd?ะ/<๔ˆฃโ�Aƒณรว‡> .ฐ@๑T\|ูqมES~x�}ืโ๘cŽ™gž9;?~�๘XgƒMโหqใฒใ๖ฆ�yื=‘อ0Xุ฿฿ฝใจ#ฯ๛๔Maึมmw่oผ๙Vึงาเ\iฐ๐ภ�~ฟ9๊ศ์š๔วcO<๛์wP~œ–•�{ฯ�๓Œ๗๛?DZ9m}z๏ง๒‡l?�‘‚™วb๎ฺžz์แ˜o�yำnคฅ๚rD>Lยฏ๋ w[(;?rไจ่ฑๅถู~c4,Lืทฆfฅ>้YฃF‰รŽ�uคู W[u•ธ๘�sbัEIงฒญ�€โิำฯ,๚$@€ @€ @€jL`็]wE[<u�ู 7�๘gฑๆZ?ฮฮ>ฉ/ล-็{฿› -ถฅ ้ฦ›nี์์Šล๋} @€ @€ @€ี'ฐx๗%ขฯฮปf›ฑิRK7:๒7_=๎ฝ็ฮ:็—^zูู่ซw�–B‰“ ��0๓ทห*งฉํ†ยชO}๘a~]9ํ–S5๔… PC‚…ๅS์าpa๊ี7&ว๘ฦไ๗+gy็“O<>ถ�v๋˜}ถูภฆ™๙ฎผ๊š&Cbฝถ฿.[V9อ่7ำL3ๅฯ๘ ๐ƒ�ต…ๅp�\ธฟ�VRซ?›แ๋ญW_9evร๔Ca-ถ‰ัc�“?โดSN,,1�+;Nห6o๐ณMณ�M{l—^x^~]ฟร›๗๘ylฐ�บูาฮ้ฤฤ‰ใ๙^Œ฿s\ถไs~qagะภปbฉ%—ฬšnฝํŽlษโา๓i9โำO;%ึZใG1๋ฌณๆงR๎๑'ŸŠห.ฟ2žz๚™ผฝธ“œ}ุ/z๚W4;๖ใ๘้?+^’}๎ณื๎…ๅš๗‰n฿�–]๑dบ๖oท�=ฮปpฺฆ๒/๕Kฯ(]พบ๘ฬ–ิ์ั‡ๅ}ปไ๒?วป๏พWXzทXf้ฅ๓บ.,|ๆ9็็หe฿็“ @€ @€จ]ํz๖Š๏/ณL าฟฝ>์ตธเฝ `าฬ„;๎ผsa‰ู๒ƒ(ฝ่๓/>A๗ Œ‘#�)m.ซ}มยฒ*‡ฮ @€jG@ฐฐผj] ฆ^UZจฐTฒ๛โ‹ลV[ญ๐C�L‘f฿{ซ0Ka้Œ~ฅื6ถฟ๒J+ลื_OŠ1… `s3๋5๖Œ–ถื๎wPฟ๚ศcูใR`pึYgษ–n้๓K๏KฯK^)<™–-žž-… ›ฒI็WZiล่\˜�ไจQ อฝ๋พฦ‘‡ทฤs X�`ฃทตถfฉฟi๖ย?�คษq5ฺ' @€ @€ @€šXzูeฃ{๗%cฤ;๏B฿ญ*ีุเ;w๊ห,ท\ฬฟภัตKื;vlŒ=บ๐Yžณ–ŽCฐฐTร> @€@ป ถตU@Sมย F‹ปšfT<๎ุฃณ‹3#ฆ‡mนํำmq'�H€ @€ @€ ‚…พ @€" Xุ!์^Zๆต,�นO๏๘ใI'ิฉา๐wFฤๆ[๗ฌำๆ€ @€ @€ @ m �ึืำ  @€,lFsM ึ {�๘อ1วM๗Rอ5�%2x @€ @€ @€ภ ,œˆA€ 0�‚…ำoๆŽฺุ`ฝu๓>๒ุใ๙~-์t_|ฑXฟ0�O?�4FŽฏ V ร6F @€ @€ @€@ู –]Itˆ P‚…ตQgฃ$@€ @€ @€ @ ๒ +ฏfzL€จ มยช(ฃA @€ @€ @€ P…‚…UXTC"@€T‚€`a%TI  @€ @€ @€จEมยZฌบ1 @€ส@@ฐฐ Š   @€ @€ @€˜Š€`แTP4 @€ดฝ€`a�{ @€ @€ @€Z" Xุ5๗ @€ดZ@ฐฐี„@€ @€ @€ @€6,lV%@€hN@ฐฐ9!็  @€ @€ @€ ะ1‚…ใ๎ญ @€š,ฌ๙ฏ @€ @€ @€สT@ฐฐL ฃ[ @€j,ฌ๖  @€ @€ @€•* XXฉ•ำo @€@… VxuŸ @€ @€ @€ช,ฌฺา @ ผ หป>zG€ @€ @€ @€@ํ ึnํœ ะก‚…ส๏ๅ @€ @€ @€hT@ฐฐQ' @€ฺR@ฐฐ-u=› @€ @€ @€-,lน;  @€Z! Xุ <ท @€ @€ @€ @   �ืฃ  @€,l�ฦ @€ @€ @€tค€`aG๊{7 @ † kธ๘†N€ @€ @€ @€@Y –uytŽ Pฝ‚…ี[[##@€ @€ @€ @ ฒ +ป~zO€จXมยŠ-Ž @€ @€ @€ Pๅ‚…U^`ร#@€”ซ€`aนVFฟ @€ @€ @€จuมยZ�? @ ƒ ;�k  @€ @€ @€ ะŒ€`a3@N @€ด€`a�ธz* @€ @€ @€Z+ XุZA๗ @€ดH@ฐฐEln"@€ @€ @€ @€@› ถ9ฑ @€LM@ฐpj*ฺ @€ @€ @€ ะ๑‚…_= @€ิค€`aM–�   @€ @€ @€จมย (’. @€ชQ@ฐฐซjL @€ @€ @€Tƒ€`a5Tั @€( XXEำe @€ @€ @€jB@ฐฐ&สl @€๒,,ฟš่ @€ @€ @€’€`ก๏ @€@‡vป— @€ @€ @€ @ Yมยf‰\@€ ะ‚…mก๊™ @€ @€ @€hฝ€`a๋ = @ ‚…-@s  @€ @€ @€ฺA@ฐฐฝ‚ @ ก€`aC- @€ @€ @€(มยrจ‚> @€jP@ฐฐ‹nศ @€ @€ @€T„€`aE”I'  @€ี' XX}55" @€ @€ @€ชC@ฐฐ:๊h @€Š,ฌธ’้0 @€ @€ @€5" XX#…6L @€@น –[E๔‡ @€ @€ @€S } @€:D@ฐฐCุฝ” @€ @€ @€อ 6Kไ @€ถ,l Uฯ$@€ @€ @€ @€@๋ [o่  @€-,lš[ @€ @€ @€ ะ‚…ํ€์ @€  šh!@€ @€ @€ @€@9–C๔ Pƒ‚…5XtC&@€ @€ @€ @ " +ขL:I€จ>มย๊ซฉ @€ @€ @€ P‚…ีQGฃ @€Tœ€`aล•L‡  @€ @€ @€จมย)ดa @€สM@ฐฐ�*ข? @€ @€ @€˜" X่›@€ ะ!‚…ย๎ฅ @€ @€ @€hV@ฐฐY" @€ด…€`a[จz& @€ @€ @€Z/ XุzCO @€h€`a ะ�B€ @€ @€ @€v,ldฏ @€h( XุะD  @€ @€ @€สA@ฐฐช  @€,ฌมข2 @€ @€ @€! XXeาI @€@๕ V_Mˆ @€ @€ @€๊,ฌŽ: @ โ +ฎd:L€ @€ @€ @€@ึHก “ Pn‚…ๅV�!@€ @€ @€ @€ภมB฿ @€,์v/%@€ @€ @€ @€@ณ‚…อน€ @ - �Bี3  @€ @€ @€ ะzมยึz @€@  [€ๆ @€ @€ @€ดƒ€`a; { @€@Cมย†&Z @€ @€ @€ P‚…ๅP} @€ิ €`a �  @€ @€ @€จมยŠ(“N @€ชO@ฐฐ๚jjD @€ @€ @€T‡€`auิั( @€' XXq%ำa @€ @€ @€jD@ฐฐF m˜ @€r,,ทŠ่ @€ @€ @€ฆ๚& @€tˆ€`a‡ฐ{) @€ @€ @€š,l–ศ @€m! XุชžI€ @€ @€ @€ึ ถ�ะ @€Z Xุ4ท @€ @€ @€ @  �ู+ @€ 64ัB€ @€ @€ @€r,,‡*่ @  kฐ่†L€ @€ @€ @€@EVD™t’ P}‚…ีWS#"@€ @€ @€ @ : ซฃŽFA€จ8มยŠ+™ @€ @€ @€ P#‚…5Rhร$@€”›€`aนUD @€ @€ @€ 0E@ฐะ7 @ C ;„�K  @€ @€ @€ ะฌ€`aณD. @€h มยถP๕L @€ @€ @€ด^@ฐฐ๕†ž@€ ะมย น… @€ @€ @€ํ Xุศ^A€ ะP@ฐฐก‰ @€ @€ @€”ƒ€`a9TA @€5( XXƒE7d @€ @€ @€*B@ฐฐ"สค“ @€๊,ฌพš @€ @€ @€ี! XXu4  @€@ล V\ษt˜ @€ @€ @€,ฌ‘B& @ � หญ"๚C€ @€ @€ @€)‚…พ  @€" Xุ!์^J€ @€ @€ @€f ›%r @€@[ถ…ชg @€ @€ @€ @ ๕‚…ญ7๔ @€ถอ- @€ @€ @€hมยv@๖  @€†‚… Mด @€ @€ @€ @  หก ๚@€จAมย,บ! @€ @€ @€ P‚…Q&$@€TŸ€`a๕ีิˆ @€ @€/=ˆTถIDAT @€จมย๊จฃQ @€*N@ฐฐโJฆร @€ @€ @€ิˆ€`aฺ0  @€ๅ& XXnั @€ @€ @€L,๔M @€่มยa๗R @€ @€ @€4+๐�E`v…ฒIENDฎB`‚pydantic-httpx2-6dd59b9/docs/img/gh-actions-fail-test.png000066400000000000000000015003361526547463400233700ustar00rootroot00000000000000‰PNG  IHDR "~ภtฎ๐ HiCCPICC ProfileH‰•WTSษž[RIhH ฝ‰"H—B‹ Uฐ’@B‰!!ˆุ•e\ปˆ€บขซ"Šฎฎ€ฌum,‚ฝ?,จ(๋bม†ส›ะี๓�;๏?gๆ~๙็Ÿ๏/™นwjžTšƒ๊+ษ—ล…ณ&ฆคฒHภธ&/—ฒccฃ”ม็?ๅอUh ๅ’‹’๋๛๑�*zกœ qบ@ฮฯ…๘7๐bพT–ั๊ญgไK•x2ฤ2 ฤR%ฮTใb%NWใ •MBโ]i<ž,ํ&จg๐3!๖uˆ]%ฑ2ฤ|Oqฤ#rsง+1ด้_๑d�ƒ3}ˆ“วหย๊\TBหฅ9ผ™�g9�ทไๆ(}ุมFษ"โ”9รบ]ฯžฉฤ4ˆ{$้ั1๋C�N,PูCŒREŠˆDต=jส—s`อbW/$bSˆร$9ัQ}z†8Œ 1\!hก8Ÿ› ™ปX(ืpVหฆวล โ ‡ญ™[ฯ“ฉ�*ํO*ฒู�๋"!w�u‘(!Y3F-'ECฌ 1SžฉถมlŠDœ่A™"Nฟ ฤพBIxฐš›š! ‹ำุหrๅƒ๙b‹EbnดWๆ‹"4<ป๘แ ก“pcšxก์›|X`<่„ย49ง3nY=๐`�๒Cnœ‰›| ๔ฤฦกoจๅh"Wf�-๗?r๘ช๊;Š+ฅ ฃQพฉํคํ1ฤขฌ้ืRวš>TWฮะศท�9_UZŸ‘฿Zb‹ฑ�ุi์8v;„5vkยZฑรJ<ดŠชVั ท8U<ูG�?žฦงฒ’rื:ืnื๊ฑ|aก๒�8ำฅ3eโLQ>‹ ฿�BWย9‚ๅๆ๊ๆ €๒;ข~Mฝbชพ๓�]�1|Jก2๓‹Žg ภมG0�|ัYฟ„�c‡�๙ YZ‡+; ธฃŒ9ฐ07เ �@ใ@ H)`*ฌฒฎg˜fƒ ”`-จ›ภฐ์๛@#8Žƒ?ภyะฎ€[p๕tg ผ�‚:ย@Œ ฤqF�o$ Eข8$IC2 ข@f#‹2dR‰lFj‘_‘ƒศqไ,า�@๎!�ศKไŠก4ิ5CํะQจ7สF#ัt š‰ๆกEh1บ ญ@kะ]hz=^A;ัgh0-Œ‰Yb.˜7ฦมbฐT,“asฑRฌซม๊ฑf๘?_ย:ฑ์=Nฤ8 w+8Oฤ๙x>_ŠWโ;๐�$~ ฟ‡๗โŸ t‚)ม™เKเ&2 3%„rย6ยย)ธ›บoˆD"“hO๔‚ป1…˜EœE\J�@�C ๖‘H$c’3ษŸCโ‘๒I%ค๕ค]คฃค‹ค.า;ฒู‚์F#ง’%ไ…ไr๒N๒๒E๒cr?E—bK๑ฅฤP”™”ๅ”ญ”fสJฅŸชGตง๚SจYิิ j=๕๕6๕•–––•–ึ-ฑึ|ญ ญฝZgด๎iฝง้ำœhฺdš‚ถŒถvŒvƒ๖ŠNง�ัƒ่ฉ๔|๚2z-��.�6C{ค6W[ =OปJปA๛ข๖sŠŽญ[gชN‘Nนฮ~ :=บ];]Ž.Owฎn•๎A�kบ}z ฝัz1zนzK๕v๊ี{ขOาทำี่๋oั?ก�€1ฌŸฑˆฑ•qŠัe@4ฐ7เd”์6h3่5ิ7c˜dXhXexุฐ“‰1ํ˜\fs9s๓*๓ร0ณa์aยaK†ีป8์ญัpฃ #กQฉัฃ+FŒYฦกฦูฦ+๏˜เ&N&Lf˜l49eา3�`ธ฿p�๐าแ๛†฿4EMLใLg™n1m5ํ337 7“šญ7;aึcฮ42ฯ2_c~ฤผ�‚a`!ถXcqิโ)หลfๅฐ*X'Yฝ–ฆ–– หอ–m–�V๖V‰V ญ๖X�ฑฆZ{[gXฏฑnฑ๎ตฑฐo3�ฆฮๆฆ-ลึ�Vdปฮ๖ดํ[;{ปdปํํžุูsํ‹์๋์o;ะ๒j.;ฝณ78ถ;กNN"ง*ง ฮจณงณุyƒsวยŸ’5#ฎนะ\ุ..u.๗F2GF\8ฒqไ๓Q6ฃRGญuzิgWืืญฎทF๋7zแ่ๆั/�œ�๘nUn—�้๎a๎๓�›�_Œq#ณqฬu†วx=Z<>yzyส<๋=ปฝlผาผชฝฎyxวz/๕>ใC๐ ๖™็sศ็ฝฏงoพ๏>฿ฟ�\�ฒ�v๚=k?V8vุ๋�V�<�อ�ฌ€ด€Ÿ:-y5๗ƒฌƒA�‚ณูY์]์็มฎมฒเมo9พœ9œc!XHxHiH[จ~hbhe่�0ซฐฬฐบฐ�p๐Yแว"‘+#ฎqอธ|n-ทwœืธ9ใNFา"ใ#+#๏G9Eษขšวฃใว_=�vดmด$บ1ฤpcVว�‰ตอ‹�}qB์„ช โFวอŽ;ฯˆŸฟ3�MBpย๒„[‰‰Šฤ–$คษIตIo“C’W%wN5qฮฤ๓)&)โ”ฆTRjR๊ถิพIก“ึN๊š์1นd๒ี)๖S งœj25g๊แi:ำxำ๖งา’ำvฆ}ไล๐jx}้�๔๊๔^>‡ฟŽ�L$X#่๚ W g๘gฌสx’้Ÿน:ณ[(*๕ˆ9โJ๑‹ฌˆฌMYoณcฒทgไ$็์ษ%็ฆๅ”่Kฒ%'ง›O/œ�!u––H;๓|๓ึๆ๕ส"e�ไˆ|Šผ)฿ุ[Š๗  ช �อHšฑฟPฏPRุ:ำiๆ’™‹ยŠ~™…ฯโฯj™m9{ม์{sุs6ฯEๆฆฯm™g=ฏx^ื�๐๙;Pd/๘sก๋ยU _/J^ิ\lV<ฟ๘มแ?ิ•h—ศJฎ�่๗ใฆล๘b๑โถ%๎Kึ/๙\*(=WๆZV^๖q)้นŸF�T๑ำภฒŒemห=—o\A\!Yqueเสซ๔Vญzฐz�๊†5ฌ5ฅk^ฏถ๖l๙˜๒M๋จ๋๋:+ข*šึ�ฌ_ฑ�cฅจ๒JUpีžjำ๊%ีo76\�ดฑ~“ูฆฒM~�|}s๘ๆ†ปš๒-ฤ-[mMฺz๚๏_jท™l+�๖iปd{็Žธ'kฝjkwš๎\^‡ึ)๊บwM�ีพ;dwSฝK�ๆ=ฬ=e{ม^ล�งฟฆ�zu_ไพ–��๛๋ณ�ญ๚ใ@iา0ณกทQิุู”าิqp�ม–fฟๆฟ�}๛!หCU‡ /?B=R|dเhััพcาc=ว3?h™ึr๋ฤฤ—ON8ูv*๒ิ™?ย�8qš}๚่�3‡ฮ๚ž=xฮ๛\ใyฯ๓ ญญ�๔๘๓@›g[รฏ Mํ>ํอc;Ž\ ผx�Rศฅ?.s/Ÿฟ}ฅใjโี๋ื&_๋ผ.ธ�ไFฮ7 n๖฿š›pป๔Ž๎๒ปฆwk�ๅ๘ฏ=ž‡๏…�kฝ�ึ�ƒgๅ?v?ข?*l๑ธ๖‰�“C�a�ํO'=ํz&}ึ฿S๒—�_ีฯž�๖wะ฿ญฝ{ป^ศ^ ผ\๚ส๘ี๖ืc^ท๔ล๖�}“๛ฆ�m้;ใw;�{ฟ?�!๙รใ�I+>9~j�๙๙๖@๎ภ€”'ใฉŽlhF/ท@Og‡vจ“ิ๗<• ๊ปฉ �„ีwA•xฐ=€ฤ๙Dม3สFุl!ฆมง๒จžPw๗กฆy†ป›š‹o<„wฏฬ 5๐I60ะฟa`เำV์ Žๅฉ๏—J!ยปมฯŽJิึJ฿สฟ(ำ~a,™ใง pHYs%%IR$๐ŸiTXtXML:com.adobe.xmp 2594 1662 ›�1iDOT?(??๎&€ี”-@IDATx์�|Uืว๑C“�{๏D”*ฝ จ  าEEปbวBQAฐ จ(" Eฐ ค*า{๏ฝ}๎™0“ูอnฒI6$ป๙�๗๓ฒS๎�™๙ฮ๒˜ฐ�=7ลฆ @@D(]กJ"™ำ"€ € € € € € €C Aฤ`02 € €@\"ฦUŽใ@@@@@@@ค!@1i<ฎ@Hถ“ํฃ็ฦ@@@@@@@ L"†ษƒไ6@@P ˆชOŽ๋F@@@@@@""๒N@@HT‚ˆ‰สฯษ@@@@@@@x DŒ7! € €ฤG€ b|๔8@@@@@@H|‚ˆ‰� ธ@@ Y DLึŸ›G@@@@@@0 ˆ‘[@@BY€ b(?=ฎ@@@@@@!ˆศป@@ Q"&*?'G@@@@@@โ-@1�„ € € ‚ˆ๑ัใX@@@@@@@ ๑"&�3เ @@d-@1Y?~n@@@@@@ย@€ bJ๙reฅ๊ Ud�ยEฒs็ฎ$ฯ‘>}z)\จ u7mN๒ืื ฌW็fษ;—u๘•+Wd๒ิiqŠใ@@@H๒)Rค 2HฆL%M๊ิI�zน@@lK—/ห้ำgไ์ูณ๒฿�ู›ƒ๖ช#ฆ�ฬ�้ิญ๚GŠ จซ�ฬญ่=Yฏๆ.}ตไ~�พLุžaD|{๐pูฝwฌžXฉลไ‰�๗ว๊:#€ €ฤ_ ‚ˆujื’t้ำล c๏�}ฒn�†8›jี๒)Qฌ˜ไฯŸOฒgห&งNŸ–={๗สึญ�ๅง้3ไ’+Uฌ ƒผc�๏ฟ�ส}๖”�๛$ศน‚5h๏^=ไŽึท[ร๕์�˜l�พ#ฦก›4nh>ศศไท฿ล ฬ{iฃl฿๓X~ ๒Ž9ฟฬ‚ 8ฃ6n�Jvํ�ใฌ‡๋ยํทถด‚ฑE –|๙๒ส๙๓็อ}๏–&$๛�ธ๑ฒ�ภมx฿zF๓มV�๚uฅj•๋ฅRลŠ’%Kf๋}ฟsื.๙}ฮ\™ท`aผฯม € € € คJ•RrๅสE1p2z"€$A‹—.ษ‘#Gไส•ƒvuvOฃˆแ�œ4ขวm&๗๛๗ภ`%์ย2ˆ๘H฿~ฮƒ๘ฦ ’�ฯ‡ย็ฮ—พ/๗w๚๘บณฬ € €ภต‡ โฌ้SโŒ๕ฯฺต๒D฿็โ|||,Rคฐ5D|ซถh�Tบv้dช฿ๅ๖{I‡–/ฦ|-ณ๙อoŸธ์ธทk้าฉƒs่>๖=j๕Aญส๗ฏ๙‡“�{’F๎ำรDํฯœ9#wถ๏ไ\ปฟญž๘�ฌ้�v{lฟx๑ขฬ๚ๅWyฉ฿๋rฦ|{5!ZŽ9คD๑bฮะห–ฏp–� ษ-ˆXซf y๑นงฅ\ู2nๅ &0:ๆ๋oๅฝA๏{lอŠžg่%[ึฌ~[บlนผ๒ฺ›ฒyหVฟ}ุ € € <�7‘ดืฅ �€Œ„ €@" \ธpQ๔฿๓i €@lย>ˆSธะZŒฉolq้ € ณAฤฤ "6nุ@ž{ๆ)๋!M›1S>:<ๆๆฃวmn—‡{๖๐ฑ'๊&าaะ๛Cฌ \ิฝq�ขำ20่=3“C นbฆ่z9|๘ˆ3ุ}•–-š[๋�฿ sๆฮs๖%ฦBฎ\9e์˜ัึฉ.Z"ฏพ๑VŒ—› ข=ุัcวคฯ�๚ส’?—ู›‚๖๚ั‡ƒไ–fM๑๚™ภ�ทฆาŸwKNAฤชT–oพ�\ฎป๎:oŸ๋Ÿ~�ฅผ;pฐฯ}ัmผงsGyแูง%Mš˜ง๘:p๐ ดn�AŽ=�์C@@ˆง€Nวœ#{ถxŽยแ €$ฃวŽ[ำ4'+โJ@ "บช'D …ท,ืˆ €แ&Aฤ.๎–๋าD 5kฺฤLษ“ำzdฏ๙Gึ˜�๗n:U๋os�๐�|Mึuๅ�=๖ˆuฎYณ‘& �ฆ๗๗ี่O%UชTึก็ฮ“?ฯ–น๓ศมC%ท™’จQร๚าขy3I—.b๚๊Kfj‡žฝ๛ต:กV,Vดˆฌ]ท�#„จ๕ผ [62กKm๔ŠŒึภฑ๘ฃM๋�ไ‘^YGxWo๔7L\‚ˆ:–N‹�ฐiKรฦy๛ศแCDƒฌv{ๅ๕ทd์w฿�ซฮkr "ฮŸ3[๒ๆษใ�ป.\นrE6m�"้อ{ฟจyบ›N#~Wว{D�ท!ะVนRE™๘�ุ(�ฯž=g�ฃ �ฟ7๎ซV�%ํ;uuob@@@ ศTC 2(ร!€$บภ…‹—ไะกC๑บŽ�ไ?3sธOว์›H๏][rพ�ไz๏พ฿ษg+AD‚ˆษ็�ฮ"€ €@’‡ ข?ุื_yIt Umร>)“งN๓ื5Qถ#ˆจS"๋ิศฺtJเgžู„ืEนŸ*ืW–7_๋'iำฆต๖}๙ีื๒อทQƒkQ ย†คD|ใี—ฅf๊ขี!;t๎&วOœˆ๑.}ปv๏!็ฯŸณŽอ™3งT,_^บt๎`*0d๗๏๓/ฦศ�๏ ๒ุ฿‚ˆž‚อš6–แC"งZถ+ŽŸ๘ฃS๐๎ปฺŠ>๛”)S:kาฬ�6ฺF}ƒl�ถ]z=า' ฃ}}��ษhฆ‚๚y๚dส| mำฎฃuž><,9sๆpฮ๙๋๏sฌ๊•ฮ†ซ :ฮ3}Ÿp6k๕พื�|[zSษะ~ฮ}<ส :ลฐ !�ํ�9ฝ&O๙I๚>yN{วมœiยu›Vํ๓D_{wดฏeห”–ฉ“ฦ{�รซcธ›พWฆMž`�c้อ๚์พ๛ณฮ € € €@p ,� Lฦลjษ4็ �@ ฎ๚oฆ๑j๚?Rษ๔ ฌฆโ%็๛Oฆ๗ฏฟ3ap0AD‚ˆa๐6พ6ท0cๆ,๙ไ๓/ค๙`๏๑G{›>#>ฬพ6g็, €„ฏ€ฏ0Uธ�ml*"jศ๎ๅŸ•โลŠ๙ผ�_~�]�Yqอ�้†*•ๅ‘‡{Jั"žSฟฺ}ึ™้Š฿0H๖๏?`mzเ;RฑB{w”WnกหฝDู๎kƒ;ˆ8มBy�ญw|uณถiภฏt้’ึ๒พ}œฉ™๕๚฿{๛-kปN#๛ฬ๓/๙ฃืCJ�;Z[๛>๙์ \›่๔›5=ข"� Dl฿้k๛ฯำ&{„ถœฮWๆ�1W๚ฟ;ะcsื.คs‡๖’*ujํบrิุ�๔฿ฐ[”|lจfยŸ�฿xีฺ3มTห๙้็>zE�hQ์vOgั็b7 O^S-kUM4ฌjทyๆ™�฿ใa{ีyํd ๔�k7ญvYใๆฒjู"{“฿ืoว—~ฏฝiํ๗"๖่๕จ x๗-ั๗‚wป|๙ฒฉ:สo…ภพO>.�ืMR๛x6:–†%ฟ๙vœฯ๗เฆตซำ้{ไท฿•oฟ้๓�q๊ิ)yฺผ5ดhk฿๎Nฑรดzฬ—cพ‘&˜๋�^x๎i้�-โ�ฉ๛&Lš,ฯฝุฯป›ฯu Sv๎xทณOปญ�Fฎ;;ฬBŽ9$Kๆฬฮ&ช!:, € € € "@1AX4‚ˆ ัโ,๏ bœฯฬ ช“h๑าฅหV›ธพฑาฅK๋1ๅW\วIjวiฅžญ[ทY•kด’IแB…ฌR+V(๏Qู%ุืฝw๏>iะด…3l…๒ๅd๒„qฮ:  € w‚ˆ"Nำเ˜ป‚™/ั;wŠน�ญ|นฒf*ึ7$]บt๎อQ–5„ุำT฿ำPฺเ๏HฅŠ�ƒˆM%ล{๎{0สพ6�o‚a๏พหฺuๅส`‚zฟอ๙รWWฟ�*ˆ8๓งฃ�™๘ws๎)‹5 จฯ"บฆ๗๘แะa2sึ/ัu๓ป๏‘^I›ึทY๛Ÿ6๓V�๕ท฿พ๎ฑ "j%ศ/>๓œ๎ทf�FV๒๑วzหฃ&ดj7wHั�ฆฏ#† ‘&8›~7กอ‡~L�>gงืBtAD�='Mšจ!O{�–hว{๎‹๖��“ฅ^›ํnัพj5ฦ]๎๕่ใ}�็ฯŸ๖๏ฬแรGคv�ˆ*ลsๅทYำอ๏0Q๚ฟ3@F๙ฺYnม�@Cฟ_}๓ญh๕สบฦF+L๊ดฯ7m6๏ซ5Q*กF76๛@@@โ'@1~~w‚ˆqทใHˆY€ bฬF๔@Oฐ"|ใ๓ฎ๏eฯ;/}_Žœ:nุภื=uqM?ไำ๛โฺ�~๓5นซํq=<ษทxษRyอ|ะฆำ็๙kw฿ีVž|�ฑ $N๙iบ<๕ฬ๓ง^๗ืrฟีX<:ฒ‚ €ั Dั€‘VDิฆฉqใ 7[?kด0S฿\ปฆc๘ๅW_›ชo฿;๋oฝ�ŠTฏv“ต~์ุ1kzๅ+W›iŠฏ3Sฮึฐฆะต;�U๓ๅหkฆoฮc‚]uไ๖�ZYป�2ธฏฟ�ฮZ>jฆส d*hํ์Z›?�^๓�>gฎ่ดฟLe์#˜uŠ๋ าหฝ]ป8 œ2Ut im�ท๏”ใ'NXหอ›6ญธg7ฝ‡‰ฆZ�S PŸอ=;H–,Yฌ�'ฬ1ํ;uตปฦ๊๕ณ‘รฅpแBr๚๔ii{w็€MQƒŽ฿‰จ0ฉ'ะ๐dนสK็ืŸงyT์๕่ใQช�ญ�sกdส˜ันพ'Ÿ~NฆN›!S&~oM]ฌh็้3gไเมCV�&N}ฏi๓ฎˆhm4huษcวO�ึx๖v}๕ฎาุฒEsั)�M�ž�ณvฉ‚๘Ÿ ี–โีiฟฟ�!ฒbฆwQวาะฃ†{/_พb*‘•TฉRนOa…T?�bŒวถุฌh@P[ๆฬ™ฌฉพตชบNฏl7:ฝnรˆฉสํmัฝฮ˜:ษš.�๎ฃ•?zเ~ilฃ�ืฎ}ๆฮ[`UvTk € € €@ย DLX_F๗/@ัฟ {@ �ใoศ$7ฐ "๖4\๖์�ซgYชD1yข๗�ฑ:&!;?ะณท๕มQ\ฯั�Wค}ปถq=<�ว-Y๚ง�๛@dฅ�ะํแžUี๑>๙ภ๗‡ศศO>๓�์s�บ๋ฎ“้“'HQ๓มh0�™ณgๅฆšuญqu\ญฃUb�ํ�!™๋ŒœZ๏�ฏFKีชธปฐŒ €>’{๑ฮ6ท›Ÿ“zX2ฎz๔OE ๖๎ีC๎h}ปี็Œ |u๎vฟ๐๛fฬ็’;W.kŸN‡ซ_เpทวz๗rฆŒี`เ‡C‡;ป[ตผE�๗ุ#ึ๚ฌูฟˆ��—๖ยณ}ฅaƒ๚Qีฉrท๏ุ).\ผd‰y๕]�/ก‚ˆ๖=�ฬSาจaDuฟƒ?ูฟ�f๏r^�Ž:%๏ป;๛t!Wฎœ2j๘Pษ”)“ต}์wใไ 3�nlšŽ1vฬh๋…‹–ศซoผ๐แฑ "Nž๐T(_�{หึmาโถศ/)�๐�ืRๅ๚สฮ�๑&ษ /ฟ๊ฌืฏWG40i7�Y๘†jตํU๋uไ๐!า๘ชฉnxๅ๕ทd์w‘YปณwQ฿๏|_์€Ÿbฟ๘l””,Q�>ฤšBผ^ใๆฮ๚ฟฬ”๒;๋เ{เก�&ฌปษฺVฌhQ+ฬ๋ฎ4่]ัะ;ˆจมษวŸ|ฺ๙ซf๕j๒ษˆ<�.ฮฐเ+๐้>lำๆอ๒์ �ฌะฎ{{tห�แะE‹—JํZ5ข;Dt๊;�w”]ป๗D� € € €๑ ˆ??ŽŽปAฤธ�q$ฤ,@1f#z €€ง@ฌƒˆ#G•ฟ�Y๏9J kiM8ฌ฿ณ}$[ึˆ "1t๗๎ีkึษจ/พี8?�]ส”Œ�๐+V'@็P"๊t|={๗qdz๖x@๚>น๎์ˆaaฺŒ™๒ฟงžาK+~ไ6ไ๎?p0สพ9rศ์้SLลšฬQ๖ลgƒNg8๑ว)’;w.is๛ญขกGwณงFณท}�ลงฆ Qu{•W@๐#�ƒˆ�yำ„ยฎทtพ๛Œ๙zฌOฉ๏วŽ‘lูฒY๛žy�E'ิ7ๆ๓OD+j7~‚|6๚Kk9?‚Dิs=ะ�^i{Gk3ํnฟง�ณwฏL˜8Y~š>รฃObušjฎZ�ษ“'ฅk๗Nะำ}กฺทณ๎Sทญ๙gญh•ภุ4 “jจT�>Žโ�X1ต๚�Uo>>lชTFผŸ์๑&Mž*ฯ<�’ฝ*�ป�#/<๗ดณฎ?็บƒฏพ�ขt้tทณ฿ืฯไq "jUEo7 4๊xvำฐbูJUญU_๗mWgด๛๋kร๚๕ฌ ก{[›v้‰ฝƒˆ๚%ขแ#>qw๏๛ึPฏพโา๔==�[฿S._พ|Y๔wย:ะฆฯwีฒE~ปk๐๒าฅK’ื;uzfw[ถ|…tฺ๊�ฝ‰e@@@ D 2(ร,@1`*:"€@"ฦCHๆฑ"7^wˆ5EY vํZท”ฦ๕=+hzl\๛i๑ทน‹d๓ึํัก•๕ฺชTŠฌํืh็บ๕dฯžฝQฮ6|ไ'U3บ�ำYjืŒZใ๚๋+Iž�นฃญ6+ˆxk›vฒqำf็ฒห•-#ฯ?ำืš~0Mšิึ”nZู็ๅW฿tชj็—_xVิๆZ6‚ˆืR›s!€„“@r"๊—๒ไษc=าƒ?4w๘|ผ:mฐV~ำๆฑฝ๗๖›มณญฆ๚�ŒŸgษ3�ฐ†“ขkม "๊yางOo*7�&ตฬ—1J—.iฆ–๖J๔ฎ˜ุADทรถํ�eŸส%K–'๚๛‚Lž:อZ๕"บ๏ื๎฿พ�า�WํUซ’g\งเึŠ”“ฦ t7 :�๗ƒฝ๕x6๎�๎e_Fบ_Cคฯฝุฯ๚๛ฎ๋๚ฟƒผ-•+UิUง๕yขฏ๙฿…ูฮ:  € € €ม ˆ\OF \€ bเV๔Dุ DŒฝG �bDT0 ๘M˜โYลฤdแBไ™>E๛Œฟcƒน�‘พ�œแ† |�Yต๏๊C�(-oiํm่xkืฎ—ึฎLง5ซPพœhๅ{ฟ่ะ)ฯVฎZ-�ถ๏ำงO[ว)\X›้‰๕1wำ …G‘…‹–zLgื๚ถVฆzL7ซk๖lู%�|๎ร|.?qBชืฎ๏ฑo๙โ๙>+�๒๋๏๒๐c�s๚zO'7w�น|ๅฒต?งฉ˜่žŠฮ>HtJiป•,^�™โY?เี๓�๛๗?kทV)[ฆดตฌS�]ธp^>๚x”ว4ฏผ๔ผฉJ15sม%ซŠ GŽตช้ฌYปV๖๎�'ฅJ•”ŠๆูT4ฯฦ�ึพ.^@7ไDœ1u’hต็ุด๑&ส'Ÿ}aRพ\Y๔^Ÿก? หญ\นJฆฯœํT†sŸวภ‹ฯิฬ๎1�หตฬfnฎUSjีฌ๎Tsด๗๕ฉUmZื;ˆุใ๛ค}ปถ๖ฅ๔ช?บง;ไ ษฦYaอญ�ถKฏGbW-�W1ฆs^4๒4Œ็�ำใ>�ไcฉW็fgˆกรGXW ฒอž1ลู~์๘qฉqsฤดึฮFณื b�ป;{|ฑสs�_ห=‚‘vQŸอ3O=awณŽี1|ต/อฯ7ืฎ้์๚่ใ‘ฮTไ�AD{|งณYhาธกŒ๘่Cg“N)ื ขขa@ญš>]:+ุฉฟUป้Fg|]ะ฿Sด~ m๕ฒล’!CzงซVVlืแž(ท๕๗ˆ฿™!ูฏVPี>��K฿ฯœAX@@@ŠAฤ 02H"ฦC@ `‚ˆSัฎ ฤ)ˆจบฝ7d”์ฺตbŸ[6EŠ๒ฬใ=ฅˆ #&vKฎAD�ะ๑ 3e�•+W|>‚‡{>(?ฺ�็‡฿ฐ๋๗๊ฒtูrŸว๊ๆ�ืMž~*2จa@ Fื๔รA�0ฆฆมวๆญZ;�2eส$+—.pึ� ๚ž|๛ฝr๙rฤ}๊ต๗›kณ›;เPขx1๙yฺd{—๓๊=eYื.ค฿‹ำํyซS.k๕"mUชี’ณgฯ9ใ๘Zx๎้'i�tฟ>ม •QŸ๖ี�š๖yเป�c ™๚<˜ €„˜€๛ฟำ!v้1^๎๋ฏผdBxีซ‡™P”]อ>0[ึฌ๒�ท_ูซฟ�dฆท2์cง™าฅคgฌ/š่ฯเพฺs็ห[๏ผ็ฑ+กƒˆ๎“้Tฟ๗t๊(ฉฎV๎ำส=�˜ี%ฑƒˆO>�˜ดˆแห=๎{ฑ—�ด๋เs g{ฟ๛ตzตๅญื_ต6นƒค๎>ั-ว6ˆจ!บ็_zE6oู๊sXF๛��o8๛Vญ��„๎๎‘ž�/Z}ำnใ'L’^~ี^u^ใDtO—์ f�uช้วz๗rบz�ฬ๎์0 ฃ>*D~‘i๔—_I�wZ]ผƒˆพ�w'ุAD๗ตูห๚๛…�žแn-oฟำ๏sr๗›๙ำRฒDqgำขลKฅ��=œu๗‚~)๊žฮM๚๗�ม^8๋, € € €W€ bp=-p‚ˆ[ัb/@1๖f@rˆSQัvšโ{ŽVฬ_kTฏ–�ีฆ•ฟ�ืt{r "พุ๏5๙�‡‰1:๋tว?�๐Gq็ฮ]าฒu[นx๑bŒว๋\๚A—ถ`ฯ;'ื฿Tหใ�๚aฉ~h�ๆ� 1ฑƒˆZlืฑ‹l�ผ%ฦ�่�ํyแนงc์G@BYภ�฿้Pพ_ืSQ™:iผคM›ึ:|๘ˆOไธฉ@S[ฟqฃ5%ซwฟ|๙๒Jอ๊ีL ฑขTฌP^rๅส้ัล;w-ƒˆz!๗vํ"]:uฐฎ้’ฉึwk›vึฒ;ˆ๘ื_K฿็^ดถ{�ั็‘‡ๅถ[[Z›ต"ค��fMจโงSk ฮ�žๆ)iิ0ขช฿€มxTฑึ~�๎้์„ถถn�.฿๏>�็๒…‹Dƒ`ถG๎)ญoฟี๊�ดนฟีๆ>cำ|ฟ๙vœฉฬ}มๆ�๙๓ฒลืญ฿Pฐอ]aOฟ(sSอบ๒ษˆaขกIปuํ�C/‰zŸื*ˆ่˜ิkณ–พ˜๘�X)‰_๋๙๊›oญ[I*ADฝ˜๕ฏ๐๘�ห=…ดํ๎๋ีปŠฅNตฌS.๛j�N}ฟ�ีั๓๏…ฏใุ† € € 7‚ˆqsใจ๘ ุี๛๙nr�Oภ ฌ"&๋วฯอ#'8๕l?Lž.ฟฯ[์๓ฤูฬ4ด�ž้c>Tฝฮ็�kฝ1น.Z"๗>๐sj7YH๏�ท_~ž�‹ว> ปi่อn}ž|ฺc 7ญึำฒEs)hฆuึ ‰:…˜ป-œ๛ซ5อณVั =gฮž๑จจีsdฯnาดI#ัๅi:5ณNั์n:ญr‡๖mMต“Q>\w๗s/ปม"๊z:ญ๒ัcว<*O๊ดi3dด.ใูพOH›ึทYห๏lMๆพ>ตอ›'ทh%ญ^ใnS&~/:ๅ" @pp�w:�๎1 โg#‡Kแย…ฌ[๏๗ฺ›>C_quฉ_ฏŽtฟทซ๙.ขB๙žฝ{ฅ๛ƒ‘ีๅโDLŸ>ฝฉ๒๗ŠคJ™R4X่/@h_ฅŠd๐€w์Uฑ+ บƒˆ;v๎”ฝu๚ธ๚ฟ๑ช3ตm0ƒˆMH๑9Vิถqำ&y๔๑ˆe๗นใปl?็SงN™้tปฤz8_Aฤ๘��2x€๕3พ}1�฿`ช?aฆNmmฺเ ิkิฬ�ํ๑๊Dิj›_Œ๙ฦฃฎฬ1S�๏?]mED�X†vำภdณ–ท›๊�{์MึkŽ9d�o?[•ลํ๗=ะS,Š๘}5กƒˆ๎Pงžฟq๓VQฎัพ.๏๊๊>zฬื๖nฟฏฏ๕{Q:wผ�ูฏกู[nmใฌป† ,อ›6q6M›1S�๗ิณฮ:  € € €ม ˆ\OF \€ bเV๔Dุ DŒฝG �โDผpแขผ��;ล๑ก๛:I•JๅฃlOฌ q "ฎ^ณฮ„-ษฆ-�ฃฝ๔า%‹Iฃzต�žŸ4ำ,O5A?ป y`”้{ušโ†อZส>8ด�‡ƒ�� ูn�ฌ]'w�ีั^ต>ฐ[2�wั้ตUผกบG5ฤ฿gO—B :�}0TFŒ๚ิY๗ฎT๘�œ?คg๏>ฮ~*ฐ๏‘๋ฮŽ&�8Ež}แeฟฝ4 ฉำ$7nิ@Z4o&�๓ี�า;ˆhŸฯ]qEท้ิอzm๎ฆลM[8›ฎป๎:ั ก{Šตฏว~'ฏฝ๙ถำว๛รWg  €„‰€๛ฟำarKฮmDt๗๙{อ?๒ิ3•ฆAฎ.ิฎUร tM›๑ณ3%ฐ~กA�้ำgd�|ฯ/‹่vwศNซ็�~g{�l5w1บs��ฝ_5ˆจ!1�า‰ถม ‘™ณ~๑๎ๆฌw๊ะ� F๊†๓ฆz_๋ถก*�9Sซฝู�;tนืน?kฃ๙C๎๛โณ‘ๆ็ฝ ึฆธว~7.J`ฎxฑข2r๘P๛T๒ฬ๓/Z_q6\]ะ “ตjิt้าŠ�ŒฏJ�ว่บVช๓๙'ึฎ y�ฌ็ซฟฏm Dิ๗† ํvั„IฏK“ฦ^•1_•7๚ฟ๋ฌปผƒˆ๚�๛_ิg|ƒˆอ๓^พdพ๓ำk˜1s–่ง�MCชํ��้lาส�ต๊5–ฃGZ�:ˆ๘๓ดษขฟgุm๒”Ÿ|sต2ๆใ๕ถปYฏ๎฿๑๔~๏4เตขฉ�N5๛—฿œพeห”–ษฦyXผ7่}ัฟ ๎Vงv-�้qOำhุั=ห € € € D �*=ณš'าvแยy๓oL‘ณEcl#cฦ ’:uซษ้ำงƒ5l‚ŒC1AXฎ Dไญ€ฑˆWQOฆAฝQ_|๋q�๋+–“ž�;{lK์•ธ}�[L๗‘ะL๗‡Tz-พ‚ˆ๚!r�ป#�oiึT>๚pP”K๗ฎฬ็ž๊ซJตZ ๙“)RุcŒK—.;๋ฉSง๒๘ +XAD=มซoผ%฿|๛ฝs. ๚ธVั๊ƒ๖๔†v_wภ!1ƒˆ�ิง��|ญŸฉ๎ุฮ^u^5 ฐ~รFg�Ÿีห<>vvฐ€ €@ธ�;ทใq ๎แฐGสไฉำ<๖๋สUow�z�ู>n�๙l๔—ฮบ.tําษ๚{ฃV6[ปnhฅ่๏ผeo–†“้&ค่n๚…vwFTM;|๘ˆt๎ึ�ูํ)jECญ๔|๎�9g ZyญtฉRVWCรˆฟ��G”C›˜/Žgw•๑฿~-Yฏ�์}๙๒%ณhุ.Kๆ,RนrEงŠข ีฆ�UญK•*)ร‡ผ๏Œฅ5`ทๆŸตขศ@Zฝ:7ห ฯ=ํQฅmืฎ�ึ8วŽ—,Y2ห๕•+{T‹ปr๙ฒ<๗า+ฒ๚ฏฟShSC™vำigทl�*Z!ฎb… ฮ=ฺ๛cDผ๛ฎถ๒เ�๗ู‡ส‰'dๅชี๒ว�๙ฮิฝeJ—’ก rพ\ฃ๚ณ็ัฃว,�oWcิž{ฑŸฌXนส3บ๛๙jๅ๒Žฆฺใqs�ุถ„ "๊{T+Uzท;vJS3ฒฟ]ล๓oวf\[0‚ˆ๚๘ใืŸฃผ�]›†๛™ฉ‘ํ0ค๖K่ ข>Ÿ ฆ:h๖lู�]–ฯํ#?๙LพQ•Rก‹็�ๆผ๕€อ[ถJห�#+=๊yfš๊‹๎ส•>vmิ๑๕<4@@@„fQgbจXพผไฯŸ฿ใwD๗ี๋ำ๖ํ�'›รนx๑ข{Wุ/็ศž]์ โัcGอ—]�ž๕ ญZEš>#่ใs@‚ˆมิd,๐๕ ขBิ๛บd>?Yฝ|ฉ๗-†ีzีj5อฟ" >F ซGR7” ขNอ�๚ปCไ‚๙Aท]๋–าธ~ฤทP’’D\‚ˆ๎cพ๑‚ฉฤ’ฮ็-;w^๚พ�฿ู7lเ๋ฮrฐ "ฦ๕ƒ&�R?ˆิฆมฟ๛{<์๗๒u ไฆYมEญฤใ�‚Dดวื็-XdMƒทxษŸfJผ=๖.Wญ2จีํๆ8$fฑMปฆzQDhืพถ@^5 ะฌiใ@บา@p�w:ไ.>† 4ˆจี๖^y้ัฉWฃk๐ำ/6ธƒlีnบQ^}๙ hพฦXg~y�ฉgข์๑ั‡RขDqํ‡’.๗>เฑ-บญVืใ๛ข๋โ์ำ0�GรGF๙G\๙ฃKืิภฮAfAC–หWฌ’š5ช[›cDT฿ฯFท*+บวœcช๊๕w ณI+>ะ�^ฟื ๕ ตbๅ๗?LtŽ‹iaสฤ๏Mจ4l�บMz=๚xL�}๎Oจ ข†?ว}๓e”szW๒๖๎ แภ_Lีtต๕nม"๊๘x}ง�๋’'wn๏ำyฌ=vL^zๅu)ตCB๕5ซW“ฯF R]๗๙j&Mถญ๎}ซ–-ฒยท๖ถ%K�”{๎‹จฆioำ๓ ๐ถไอ“ว�ไ๗U?,q—�vd € € €@ผ‚Dิ๐[ƒzuMฤŒ]ฯษ“'ๅy๓๊."z>I‚ˆžฌ!€@pB9ˆ่!ชส�}{L•ภํมJbฃ.Z\๒ๆ+เ\ี��ฆ2โ*#: ,\ ๕J›ปH–ฎX-ฯ๔yศcชฉkrœ$ะPก{(๗11… cำื}Žุ.D|๚น—ไว)Sc;ดดlั\† เงำ๚=mฆ›‹้›T๎ฃ}pBํ๑ํืส๘ “ฌณฏ\นboถพฅด�๏ศ๊‰๎€Cboฎ฿D>์\g  พฆz ๔X๚!€ ิ��N๊ื�๋ำJ ๋ืณ{ฃ�ป2o�‚h‡x๐�{ฅQร’;W.~ZมO6๛ฮT)๔5uฒV๋๋�ฑƒ ้U๓จLจƒ8pภช„จำๆ๚j$๋tw{iุ ž5}ฌ๖9h~ฦ๒?๙:ึฝญ‚๙ฆ�}�บศ Uฎwov–5ภทุLูซSีบง๐ณศ‚>'‚\งOึ)œ|ตฟ�^# f}๙ห{�“?fU๏L“&ตฉ�yR๚>๛‚ฬ™;ฯป›V|ะปV@ำืy๖๎�'ฏ๗วใ๏H”Aุ€ € € 4`๕฿U *ไ\ื๑วญ/6ฺ_Jี฿‡๕ ฅูฒFVไืข:๓Cri=Ÿ4ADOึ@ ธกD๔ไุฟOvํุ\œ$:Zแข%L1r†ำ&Œธ‹0b}ZแyYA "je“รfฺฒ<>*b$บ๗‡.›ทnท.ฅtษbาตC[ษ™#๒‡t_ื›pal๚๚:W � "6B† ๛ุฒ}ป;ฅRล ฮบฟ�[+๊ธ�ฅK—E+ลฬœ5[–�นL๖8่�ํ,z๏mi}[+g�Zํฎ]ทNฺด๋hฏZฏ๎T�‡bE‹ส์S<๚๊ŠNU�ํ�ศญปv้$�^|ฮ๊งำ ึธนsŒVโ๙๚‹Ou]x�ญwไซoพuถ้~ปbฝ๑ฎŽ๗xLAจใ๋ท�bj๕๊ึ1ฟxŒฉ๛@I๗งC๒เขำงOoช#–2Uฏศ๎�{<* ฦtบB Jพ|yๅฬ™3&๐ตำgpั฿๚ูฉM๊๐แ#�บฤธ]ƒ๚๓Vม๙ๅส•ญJ†๛๖๊ื�G๓˜ั๛/^ฌ˜๙‚S kš่˜๚วvฟb‹้zŠ)l๔š ‘;w๎Šํiฌ�๕๎%ท_�9Y–ืiฏ“RำŸ1งMžเQ-Rง๗พใ.ฯŸญ“า5๋ต่4ฦ%Š�=T฿็๎i˜“ยต๊๕้๏WZ้3_�ผrยTจุพ}‡ช�พcGด—จวๆ6tŠ๕@šVติ฿๗.›)ฯ™Š๋ฬด๎1#q้ƒ € € ธ@ฐ‚ˆ-š7sfjะ/[.]ถ�็Eิจv“ไ5ฟojำฉ&g�<�gฟp�Hั๓ฉD๔๔` ‚+ŠAฤไBดŸ>aD[‚ืฤZ11.>6็\ฝfŒ๚"2$›cตo(UDิj9๎i๗ดO๗n๗ฤ๖–}๖ืชSงM—กf:=๗‡}M5ร†8ว#ˆ8๖ป๏e๚ฬYฮ˜ฯ๖}ยฉฆโlt-xWœ๙ำR๒๊4ƒ๎€ƒVาYน4j5"๗r:lBŸ้๙มT๓ฑ�๔)คtฉR๖*ฏ €$K๗ง“%7ึฃ?aB™ไิฉSาฎC—$uฏZฉ๐E๓ปยM7V๕ธฎgLUt4=:ฒ‚ € € €–@0‚ˆ3fฦ :ขฟ›B!งOŸvึ� ื]w4kฺXRฆHimžkฆgึ/มy7-†กมฝฌๆหง™2e4_X=/:๓‘ฃGcœMวา/ปfษœYาฅK':ำฮิqา�วมƒ‡ผOeญ๋น2˜ ๔หr๛MR›~AOฟธช�๗๎�ๅXฝ—ˆkฬb}Q๒�๙๓ๆ ถgอ c‡ไ�๙ ึ๎?�s็ฮ%นrๆOฟ {ิะ9jพฐ—ึชล-V!ฝ็Ÿฆฯ๐;DถlYญY2#m๚๏?๚ลืใวO๘=ฦฝ#gฮ’=[6k*nตี/�ืฌฯ,ณ๙L๓?๓{๖์uๆ,kŸูs˜ใ3˜๋M้<Ÿ�ๆKม4@ กD$„๙ิ #FZฐtm’MQYว|7Q–,['แP "n�ดYnmำฮนO๏i�์Zีeๆ์_ไ?SED[ำ&ญเžV|™;/2จWพ\YฉXกผ}˜๕บd้Ÿำ๕U(_N&O็๔๑"�\ปฆ|๙ู(g Ÿ�R�0ุ้Z๗ๆฺขไ๚j:๕Xƒฆ-ผ๔๋ว|�‰ตYงๅึ้น“BำŠ้ฏ๕{ษTXˆ:uฐฏŸซ“ย5s  € € €$e„"�6gŽศ๓w฿bK™2"ˆx่ะแ(�4Xๅ๚สV0ฯ{็ฟ�^ฑ*๊o�ถอ{—ต^ฐ`)_ถฌว ๎Ž'Lุn๕฿kD_�ญqรVจN|+Wญj:eสศ™ม6nฺไ1@ฉ’%ญYA�}์๑ฎ\นbU�_ปnฝฝษz๕"๊ 7�Pล eบ;k๐qี๊ฟฬฌW�›c\Ž)ˆจมฟj7�(Yฒd๑9–†=—›ฯ๙�I๕๘๊ฆชeๆLF๗ —.]ฒfฉ+[ฆด pๆฒvyฟาฅKkžํ๕ึL�]=8…kณ็ฮส฿k�‰๚tuaH ”‚ˆ„ฃ>าขลKJ๎<๙œLำ์Pฐ€ษ*ˆจŽทl“i?�๎Lำจm(๕žฺ��ู๚ำพ?�Vิ€w�rยl[ถn&ุ�๐Wฃ?‘Z5kˆwQฟ-5kฺdัฉ้ด้//ผ�ชGeฟอ›สะูงณ~จo฿ฉซณฎc zฏฟ๙&W๋ž@ฆ#�ดyณดjจิม4Œุฑร]RปfM๓ร}ฤ็๓,”พฯพ่QกQKา3ๆs็�mฺu๗/*ฮ|เปR�(๕[D๏์พิcD�่ใ‘๒แะแฮ9๓็ฯ'นV˜ั_S˜@แษ“งคv�ฦ฿2๋๛Dy่ม๛ญ�:ต�ฏฟอ‘�}žpฦQซe‹ๆšoชerถฑ€ €@8 D งงษฝธ๊ืซ#/=�ฌ๕๓๓๛•™ณ~q๏Nดๅ�ฝzศ}r~ญ8p๏=e…�…˜(=ุ€ € € €พ‚Dิqomีย ิiีB- �ŽSบ”�สXŸ=้บฟถk๗n๋3=๗�ย… YF�\+บฆ�Ž …I�ืืุฬ –1CF๋0 ;z �AฤีซI�ท๔>{ะ�{๖˜Pไj๗ฆ—ฃ "jๅE !j…ว่šบ,_ฑR<่ัMซึฎUCาคNใฑ�ฝข%ตข�วDิฯ ิซk>๕_AD�ฎ็_ผdฉSaQทั@ุ „Jั;„x่เ~ูฑ-ฒUl๏;\๚kถงX‰R„รๅ†ศ}$ป blžห#}๛9�C-ˆ่&ดoคPม‚ๆฮฃีu_นฒed๊ค๑v7๑žๆXw่ฑZีๅ/๓ ง‹/:}ua์˜ัๆ›;7:�4เXตFg�ฝPฏn๙|Td`ฯฝฯ{Yyณ๙อ{ณตž�| Hหฬ{_‹๎ิข†ํๆ]‰ะ��klƒˆ?›๊’>�”ฯ!�ำc๙zl”j8Z&^m5้�…M๋๑ภ}๒๖*ท@IDATฬS‘มDŸ'`# €!,@1„—ฃ€Vแึoฒo3฿ฮO*อWq�†๒�ภ๗EฟไCC@@@ุ +ˆxsํZ’3G็ไ๚o คำ ์){~tjไF ๊9แ<ญŽทษฬฆฆำ2งI“FJ›ซะ้–ตi@aแขลc733จ้Tฬฺ.\ผ Zq๐ุฑใึ็W๚YV๑bEฑทl�๊QฤDิใ5Œธk๗S91bฺ่Xำ-kุQซ%ฺMงRึ๊Œ:ณVzิ€bฦŒFํฃU 54ฉอDด6˜?ŽŸ8.�ถํs็ฯYEYส”.ํTsิ{�c�<3mฒ๏iฎํ1�ฏัํชฺ_ƒ;v์ดฆTึ๕9ฒK๑โลœ0ฉฺkwซ]ซฆ5…ดฝMซ6๎�ท_._นlMำ\ขx๑(!GwQซH๊lvฺ๔�z฿:U๖ฅห—ฌ๗Ž�[”>gmฬ๔ุ:  ˆซ@(}…ทo�c?ฎ&กv\r#พ๘�3fvุ†ึc›8iŠ >"ฦGxญމ๑BBดAฤhœ;ˆ8๐ฬฌ?t{ข?ธ๗}นฟณ9ฆะขำ1 O>�œL6ร9rศ๛ฅๅ-อœu๗ยธ๑ไ•ื฿Šls๗ัeญ�7้๛oญ์ํ}›7o‘6wu๔๒ณ๛ุฏ�๋๓ˆ<า๋!{ีy}๎ล~2aาdg�^ˆอ4ออ/XํMๅFw5C{ฏ�฿xUtบ9wำp_ำท[ฟฌนทป—๛ฟ๑Šฉ๔๘šณ)ถAฤK—.K“ทZฟ,8ƒ\]pOำฌU_์๗šGEI๏�๖บVฒjžq $ํcxE@ ิ"†ฺใzC] B๙๒ฆzu9rไˆ่ฯ�;v์2?oฏ ๕�โ๚@@@H4`uvฌ๚ฆ ‡ฏฯ…4”xิTIwัWุN €4iิะ ๔�ฝf™ๆyง}๚_�K–(.๚๏*ฺ4ธ๔ฯeโ=-ถRฉQฃšF\ท~ƒl�Q•K๗้์tv�ฐqฃ5Sฝฎฏ™3g’:ตk;aB�ๆ"�X๕)X €n ‚�ณvฝตlฐ,?ฟUัR7ž={ึ„0็[๛๙ˆ‹@R"fห‘SJ•.็�šVB$„่p8 พยˆ›7ฎ—ใวŽ8}ยqA…๗u๋โqkC‡!ร>๖ุๆ^นVวธฯnหฃyข� —=ๆ๙ุดR%Šษฝ๏อ!ฑ๊๋๎9|ˆ5�ฑฟAv๎�%O=๛‚5Mณwฅ=�eฆW๛ๅž.œ)›�ใ่7ฌ†}๙ธTฝกŠ๛0gY๚aโ2๚หฏอ๗;œํ:E�g#ซˆจ้uO�qŠ |ˆว๔หฮ€W4ด๗\฿')คฝ๗Ÿ6฿ฆzๅต7eสOำ=vi๓ั‡{ZŽ:mฒ�่~ฏh€P›Nฉ|Sญบ๖.๑ฆ<|๘ˆ|i*~7nผ๙๖ี ง�ห/<+�๎้์ฌ๋‚V›ั@ข~หษป•(^Lํ�Kn3%๘c*}๏},๋ €„šAฤP{b\/ € € € €€[ XADSƒh7Vญ๊T-tŸว^ึJƒ๛๖ฐพXจU�อั้ถ yT;ด๛้๔ภxิฆcM›๑ณฝ+ฦWฝพ†๕๋[�ด’กNฯl7wx๐Ÿต๋ฌ*‡๖>๛ี$ŒฎZกVFฌP>"\ขี ต*ข6๗๑�๕ท฿ญJŠ๖๘๖k•๋+K‘ย…ญUญถจืhณ ๕๚~šY ฦ]อะ{สh๗ุZํQซ>jำ ๅ‚…‹ญeฝŸ’%JXห�vึฦซธซ๊&wั{์๙ "ฦถƒˆ๎qXFโ+ิƒˆนr็ตฆถ๏“ ข-แ๙๊+ˆธu๓9zไฐgว0[[ฑdพ๙น*ข ด}kšƒjิฌ•ฝๅ๕Zๅฤaด b4s๕šu2๊‹oฃ้uืใw—2%‹G�ค-๚?ZQฯnพพe๏sฟ๊qปvํ–-ๆํฌYฒHกBEฟuHศM+�ํ7ฅป๗๎�kJšŸทฆh.lŽO›6ญ๛ั.๋๙ตrคถ าG�ื฿Nฝo�fVlูนk—œ9sV , E‹ถสœ๋/4 H๊7>*ื__Iฒ™_ถขi€๒�… ’&ujัo^๙k๊ซ๗ฅฅื๓ๅอcพลTPฒfอโฏ;�@;‚ˆa๗Hน!@@@@ Y 3ˆhร้็x… ฒฆ�ตงJถ๗ูฏZ%๑ฯๅหช…้าฅ•fMšุปe๎�ฮฒ๗‚Dิํฟ�>วชž็�Gื๕ณH7ํui%ušิ’!}zฉ\ฉ’ี๕ฬYD��wqฎฉฤwโdฤ”ฬ๎q‹)"ืWŽ8�]ั�'บewัืิว๖ฑฅJ–0SG๕sลี�m๏Š๑ี_ฑiใFฮ”ฯ /v�ฝt_ใy๓ู๊์_ณบธซUฎ฿ฐA6™๊�ต�Zตt>วuห–)m*R–vำฯ_wšiซ์฿๏ำ�้ศ คDิ[*ZผคไฮQ Xื #ชBd๓BTฃ���7(๒่ะ^๒*ิ/4lฺา๏]ซc�^@์ ˆรCิ0โosษๆญ�ฃํฉ•ืฏ-U*E”ใŽถ3;@@‚ˆ  € € € €!(AD7CฦŒ$ožผ’?^ษ–-›3ํฏ๖q‡๑r็6S�ึˆœ๚ื=Ftห‹—.๕˜b8_�ผRผXQษœ%ณ@๔wltAฤูฟ�๊ณRกป*เ. ณ+๚;‡๗vwศฯ]mะปŸ;๐ฌ โญf&ณ”)RZง๚y๖/~งวึ๐ฆ†ตiฤฎชุ ^]ษb ฦh[พbฅUคฤZ๑๑‡{๚jwQวnิ พˆ�๏๊ฑ)ฬซ=}ท‡ด ˆฏ@(๕ #๚~าษ9„จ"}yX{ค—NLS3_ซc<.*ฬV"†ูๅv@@P ˆjOŒ๋E@@@p $tั}.นj•*fvญศฟ์P›ฮ$vใ 7ธปดlฏoฌzƒ™ฝซ@@วล%ˆ่ž2y�๖ํฒๆŸตห๎”XADwธPฏe๊ด้๖%๙|ฝ�ึศiํะbร๕$sฆˆ)"ต’ๅ~3ฝถฟึคqCS}2ƒต�Dิ :[ฅŠฬLky%ฅ &jำ ขป4ี(�\พยoฅKw_–@กDิ๋๗FLU��=ปไBด]4Xุ๖ฮึึ๊ฤISdศฐํ]~_ฏี1~/ ฤwD ๑ศๅ#€ €ก.@1ิŸ ื € € €$okDTi ลiPMงKึถqำfูฐqฃธCz��{EVฎ๚หฺำ”+Wฎˆw๑ยล rเภA9sๆŒ\ธpัชธ—*UJVฌj — b้R%ฅ\ูฒึ๑ZตOCฑi๎{ผึํ)›๕zฃ›ฮฺ=Eถ>‡i3~ถnฑF๕jฆฒek๙Ÿต๋d๋ถmึฒฏ?�ีฝƒˆv}ไ5aฤœ9rHฮœูฃฝ�ุฑc2แ"{•W@ ึกDิ›๓#ุฟOvํุ๋๛‡ผ-’หtฬแ๐์B�"†๚ไ๚@@ ˆโหG@@@’น@0‚ˆ%K—�๙๒Y’ปv๏‘;wFซZปf ษ•+—ีg๛Ž๒๗šฌ€ข=%๐ฟ��+ำฆฯŒv ๏๎j…วO—y๓zw1ทrsญZึ๖ธ ไฯ/7�dtO+ๅD~6$fั]ัpลชUฒวL์ซน๏QCœฟอ๙ร๊VนRE)Vดจต|ไ่QYธhฑฏรฃB�๕`3๓ณีR˜’ˆูฒe•๒&ไiฟ/t‡]1ข"€ฑต ข�w/9† -!y๓ๅw6!D‡‚…k @๑ s @@���ฐ@@@@ ้ #ˆ่ฉ>}Z~�cnด7�ฌicI—6ีGซ!jUDm-š7“4iาXหvฅDkล๋"… I๊ิiD+๖m฿zt‡ืญ฿ ›ทl๑:Jฌ)‹+fmK1cฦ าธaCg�ี�%;wํvึํ…โล‹Iฅ ฌUw˜/1ƒˆ5ช�dU ิ‹าฉ�˜7฿บ>๏?๊ีฝYฒeอfmึj“K�\f-*XPช�Pล้พไฯ?ๅเมCฮบ.h•ร๕๊JฦŒํ๎ ข†SงIm%ีอDดทรจบพภTDiOกญ�์ฆ!ฤ•+WK™2ฅ$sฆฬึfw1]บดRวV3คฯ`ํ3๙TซEิจผบb^ฮ_8/‹/u*eF๎a \ ิƒˆzง๙ ’�y๓ษS๘ภพ�฿|๖ฬ_ ฐนืผr่ภ~ูท7ผ๏5Oฒนd‚ˆษๆQsฃ € €@า ˆ˜4Ÿ W… € € € ˜@ฐ‚ˆ๖ูส”.%ล‹ ฝ๙j2�ผeซl�ถ�ืnk›†ซ�PEt g๏ภ�ฉำงฬฑ;dวฮจST๊qeห”–bE‹šชJฉœ๑ฯ;'\\๓ฯZiyKs+@จAศ?ๆฮs๚ุ5L7๓็ูQ’Nวซ Zแ๑๚J•$kถฌ’&ug๗ฆ�ใฑใวd�บ N%D{งUMฑ^I™2•ปซQกB%}บ๔NuCฝ๎s็ฯษ๎�{eรฦˆ*“>65PX ษf๎=ตq�ื{ไ่Q9x๐ œ9sV7lเLั์"๊x๚พะ๗ˆ†9S]พฺ"jลฏ;wY๏_!Hืรv@ภ—@8}��@ แ"&œ-##€ € @1$บ € € € €$Y`ํอjฆQฮdยzฉMH/eช”r๎์9kŠeช96MCoZ]๏ข™jY๕ฎ ่o, ฆL™RtŠๆ๓็/๘๋”ํ2d0ำg0Aพ๓!UลOรš™2f4Aยๅฌy>ฺฦ„vkซฮหณ�ีฏฺดiญภb “D�ถ๙ 4%๔๗ฤ{@ ดBCึlูไฐฉh@C@@@ T*ˆ*๗ฯu& • ›5idu6e๙Š•rภT@๔neห”ฑ*๊v ฮœ5�ป‹ณฎใhำ " ถAฤ`‹2แ/@1�Ÿ1wˆ €$ip "-V\ZดบีL�’มš’ๅ฿�•ˆณ�ร>nฆiI''Oœฯ>แŒำํพ$‡™V็ฤ๑ใ2๚ณQฮ๖„Z(Sถœดบญต5�ุฏพ4Sฤˆ๕ฉ šฉbฒeห.—.^”7๘=>ƒ๙yีช7I��๙ญo“9|Dถlู$๋ืญ๕{L|v�ึ๚)UบŒ\6�จ๛ั๗ใ3วฦS GŽœา๕พ๛ญJ 7ฌ—iS'วsฤ่ืjeห•‹พ“ู{๔ศaูทoŸฯ~๙๒ๅ— +I๎ผyอ4Jฉe��}ฒa�:ูฝ+๊ิV>`# € € €@XD ‹วxMnขY“ฦึฟ๗้ษ4dธyห9z๔˜U้R+++VิLูœ฿™๎yฯ�ฝฒbๅ*ฟืFั/ ;@ ƒ€ศ$3‚ˆษ์sป € €@R— ขVr๋e‚ƒฉอt,vำฉX†ผ?ะ^ีk&3]N^ฝญc�3�ข๘ม ๗œใ|่aษœ%‹œ:}J>1�ูžP +U–ๆ-ZYร๛อWฒ฿�X๊ฮปฺ›D-a]8ณvบRฃfm+ˆๆ}‚s็ฮษธฑ_ษฑcวผwลk�ฮvๆฺŠ—ฐฆอ‰๋ณŠืpฐ#PฝF-ฉ[ฟต~๖์9�#g_B,”,UZZ฿ั6ฦก=*_~�‰G?–๊vslq๓�Iแฃไภ�๛ๅ;๓~ี๗; @@@ �"†�3ึ)\Hฎฏ\ู็ฟ'xŸC�=l๎�ัNทLั[uฆAฤ`j2ษC€ b๒xฮ�% € dย%ˆXญzMฉื กๅ|ศLฉ2kๆ๔8Ut?จปJ^SimวŽํ2yโฮฎP "ๆษ“Wฺต๏(้างsฎ�_ฑ^�FRญF ง฿… ็ญฉญ3˜๊’iฬด5ฺ๔ุ๏ฟิฉช ":ไ‰พ ำu๐!น๎บดฒd๑BYบxQ‚^SZตฅN�๚1žใศแC2ๆ‹ฯ=๚u้zŸไ17ตiPX?ธr๙ฒhEฯTWรศ็ฯ—‘%Œ่!ว  € € žร๓น&ิ]iฑlู2’.mไฟ™นฯฅ�ึฐ�ภYปnฝœ={ึฝ+ส2Aฤ($l@ D "&C!L"&“อm"€ €IU \‚ˆ-oป]ส•ซ`1๋tษวƒ\นฯ��B!ˆจ•ํnชVรฉnxๅ๒I•:•ส๒žฎ:[๖์ro๗ญพ6œ?๗Yพlฉsห 7‘ช7Vณึ›๊tฃฝชำ9ใฐ@1harHณ[ZJฅสืหๅห—d่ƒพ+}/๊{R�E3ี๘วหž�ปญ๕T)Sษ�:Kพ�ฌ๕ฟ�Z-ฟฬši-๓ € € €@๘ D ฿g›wVฐ`ษœ)“5Uณฮฌขฤ3&xx๘๐a9u๊t@ง&ˆ@ Žใวa$c‚ˆษ๘แs๋ € €@R— b๋6mฅd้า>ƒv�ฮ:ญkžผ๙Lลฟsq ,DิPTž|๙ไภ�}ฑชสฆ• Oœ<.ฮ_ฐ.=.S3?ั๗Y๋X .Z8_Š-.… ๖้ำดy ฉ|}ซ�Šๅหไ฿๕&“;๏บ�L๏\�ฺ>แ๛qฒs็๖(}ู 1๗ิาuช์ฌูฒส�ฝ๛ไสฟW9Uฌ๛่๔�yอ๛โศั#r.†oป2xฮœน%Mšิฒ฿<�@›V%ฬ–-{œชyฆM—Vฒgฯ้แ่yใาOŸ‰ž๓ˆ๙ว๙ธดถํ;Hัขลไ์นณ2rุะ€‡่~ษ–#‡๕แภ๘qcข{€žฝ“ 2˜*‰Wdุ๗�พgด‚bvฤ=ฐ�€ˆtม2 € € €@่D gnWJ1�ž(๗ƒ@า ˆ˜ดžWƒ@(D …งฤ5"€ €a,๊AD 3.\ฤฉ�งJรwฺฮŸ7Sณ 8ีฎSืT๖ปIาบฆ]ัo:Ÿ0ีง�4%J๘๋�ฝ$sๆฬr่ะA๛ี—ึ˜๚GLAฤฆอo‘rๅ+šZ็ญ�ถl้kส[gฃk!s–ฬrื�%K–,ฮฝ่๔ศ7ฌ7S!๏•ๆ-ZYฝฟ�ๆซ€‚fD<{๖Œ�0nœ9rH๎๊ะูoฑ๓=๗J^˜T‹ฝ็บชศลฌYณŠzh�ปwŒ๛uไฮ–J–*-อoie…ึRคHqu*�ณVๅล2eหIฑโ%Dฟu>ไ�#i@ฌๅญญ%wž<މvะ zZ้nฮo‘ษžฝ5฿^Oo…KG�ศc{ๅมžฝ%ฃ žiี�Gซ๋i3u๊ศ็ฅืณk็™:๙วXิ๔^6j"™อsิ{ต›N�วœ_eํ?k์Mฏš47ี+9ื ๏แ“'Oส”IฅEซV’+w๓m�C๒อ˜/<Žำฐ๋]:šภk~I}uJb}Ž—.]’ห�ดBจฤฐ๒๘“O[=VฎX&s็�๎๔ถทฯœ�“”ซPมผ—Š:๏o=฿แC‡dยใbเ์z฿�’+Wn9~�ธŒ�tคsฎ˜้๓„™>๚:9{ๆŒ™zู๗ณฎ฿จฑ�tSuk(ญ๐๙็าลฮฐžlu[k)Rค˜ว๛๊’๙;๚ื฿ซe๎๏ฟ9}Y@@@ ‚ˆก๑œย๑*อ?‹Xอ๕ฯ@แx›�$’AฤD‚็ด„ฐAฤ~x\: € กD์ะนซ(1 ซ๗๓ะ๐ŸVCำVณึอrs�z�]œu ž}6j„œ99ํJฯGLUต๔ไุฑฃ๒ลgŸ8}ฃ "�kชตๅ0ีฺ�ตํ�ทษคพ๗ุ]ฐP!i�พฃ$๓ุiVฬKmw๒บiำ๙ษต�ูถฝ+QยZึฐ�มƒฌe๛wr๛๖ญๆŒทv��ฑณ,Tุ๎ๅ๕” ~:๊ใ(�}mศgย€:฿ใn๓๎งAพuk�๑ุ�ั“ฟ@Am๖สๅห—ๅโ… ข•๛ผ{jิ้žnV(ฯ๎๏�ชีฟ�zŒ๗fฟ๋v%อฟ�Ze�??;�์ํ๚w!{v฿๏๏ณฆŠค;๘๋์gแม^ฝอ๔G™ญŠ‘z<-Uบฌu?›6nˆ๒ ํa4ฉUMฝ�^ฺ๛๕ต๒๕7ˆ‚ตญ_ทVfL›j-๋q=ฬy3dศhญ๛๚CรฟำฆN๖ต‹m € € €IT€ b}0ษเฒ"&ƒ‡ฬ-"ˆŸS#ขC๔ม%็หž<}ถฬ๚mž๕ก๐‡๏๔s(v›i๒�๑!m฿วzH๑ข�?ะub@] ิƒˆZu0ฝ 61ก#:Xรmฃ?eน^2•๓tŠ] 8u๋� ^าฉZ-Z kื�m*๑—ช�hMำฌ์ูฝKพ�nฌ๓LbDl`*แ�xS5๋๘SงOษ์™3d๗ฮVนF›JSลM�ฦหถm[ญe�ร๊ฒ†ซๆ�1ว„ฐ๖›0UUฉ^ฃฆGฐ-ะ ขŽๅnั�aผแ}เL ํ>พ ๋ต7ก=mZฉq๘ะ�ป}.k…ม�=.ฉฎV๊�บuณ,]ดะ„�•๊ตjK™2eใผ+"บฏI+0๊qวŽ“›ชี ตr`D@ัพ�\นsKื{๏ทฦ�ฒi“L™<ั[ZดผUส›ใดูAE[รŽฺ๔ž~�๕+$XธHซ‚ฃ†3ตอ�y†ฌ๙๛/k9บ?z?๚ธฉ๚˜ฮ๊ขAพU+WH:S}๓†›n’RฅสXaฬ ฆJ็๐"ํสUจ(-[�fฃZนoฉส—หL๋|s�๚ๆฝ™ื9ฅwฑ�}Hฮ\นฌ�:=๒‚๙sMตฬ}ฆgsl]งบขV6\พlฉ3Nt vเะ_Qีฉ”็ซm[ทH‰’ฅคqำfN•Q}๏.๛sItงp๖้{Cซ“jลO 7ฆKagwะ ๑tt�]ั}็tฦ9บ๗ก๛yป+xึoุศz้8j๖๋/?[็Wณ&อš[fZแQฬZU’† € € Cใ9…ใUD วงส=!t"&gม• *CๅIqŽภ๗“ฆษ –Xค~4เ5g๛๖ปeภˆ�๏ี]ส”*๎์c!aNž:-ปv๏5ไฆ•R%Š&์ษ@ ์B=ˆh?ึmฺJษาฅญ โ‡ƒุ›ญื�๙๓KCิถdั"ั@œป๕๙__I•:•5•ฑ{ส�ุํqtJ่]a3=W–,Yฅ๛ƒYกย“ฆขเgW+ ๊Tพญ๏hk]ฮ๑ฃGe๔็‘•uฃ†ๅ:wฝืฉ(˜Aฤz๕Iต5ฌkุฟoฏUuัZq�aWิM�กAW7ล[ok#eส•ณถ้Tส๎ บฑN�RฃF-kฟ๗˜:uฮœ9ๅไฉS2mJDีCซฃ๙Cซ=๊Tสฺfอœ.�˜Pฉ6žY+�๙ จ๕์mช[fศ ็ฮ“ร†X�ตZฃNืญอ;@งAท;�ตทž—WฏZe๕‹๎ Oj่Rซ^.Z0฿ฃkwS)3›ฉ”้=�๕Cฝ•Œ™2Z�u๚o๏JŽ๎ŠŸ๎ bq3๕ๆ๚ดi nฬŸyœ/ฝนื‡z=b]ฟป2จG'+1ตBใว ๑˜ฎฺ่�ฑcปL?ฮวศQ7๕yย�ฝปRต๗๊๛@ซฺำZซืิษ“dหๆMv+<ช็ิถxแ‚(ำO๋ฝ๗xจท๕wZ๛ธ�:t๊" าอ&๊บ-Qข”y?ิฑ๖อœ>�šา�Zแ@@@$/@1ษ?ขฐฝ@‚ˆa๛hน1’„Aฤ$๑ธBJ€ bH=..V"&ฝ๗ม7ใ'หย%หญm‡พ๗jาป@ฎ@ I $‡ bL ‹ ๚ๅษ›ฯช€๖ั‡ƒ๎ฑ "๊ิบ:ลฎถ๙s�ฐ*�9]]ะ@a^s๗ศ-oป]ส•ซ๐๖๎@ช๒๋ใ๘กปปปSQ@)ฅฅ‹ ฐล� "*ข(* RŠR‚ˆ„า%��Kพฯy†{น3;ป์ฒ5ป๛ฝ๏๋ฮํ๛�ฯ�.ฮoฮฑ{|3aผฉสธ#๐0DิใtŠ‹ ขฟดส\ฺหุ/ณMลป�;wJ‰’ฅค�wุบฮภด๊d`ุำูๆ}u*=jสร‡y7น๓๕yย^70ˆ่๎d&]๚tาณW_ปeษโล2o๎ov�๖L…ห๋์ผS๕P4๚ะฃ�ํzo ฒ‚ฉFxืๅj„วMเq๒฿… ฺƒbแGmS�๐FSRง>|ONn์hปฮ๛#ณi]�pท6˜็ ิ�ูธ‰ญ ฉ๛j[cmม8ตhูZJš็งS`่.p_g๙jAฤ`ญล๕ุ^?)Z๔ะกƒ๒ู่Qฮ้"}uฎฅ;ํุพ�ผ็fฺPฅ.{วv6L>1\W�I[`ท๏ุูšhPqใฦ๕ฒp�9q๒˜TฉRอ†Kตง3y�k{[x๋ฝL๛iฒhp˜ @@@ q ,X@RฆH‘ธo‚ั#€ เธ`�;�๎�{ป�ข…˜vั๓‚�o�ี‚ˆ�ฮมฎqƒˆฮq‘ฝ2aฮถํ;ฺ]–/[&ฟ™Š‰�ฉlน๒r‡ $ฆ๓�A=ด:ไฤo&ˆ๓�ำV์“พ�ฮ=ด\๙ า a#๓;y๘ฟ[่3Ÿ6eŠl�ถล�Ÿ@@@ะศhพ ˜3G๖ะ(#D@ Їฑ_œโ๎Awำ(^rญ์‹!&๏๛Oฎฯ>่†dด’ bˆ?l น}<๖+Yปaณhธฯ™2dH/อ฿!unนัYๅพ๖z๊E;�ุรeษฒeูฟซฬกg�ํฅJ“u ช[นfฝ :ๆส๕ฟ,yฏw๘่1๙i๚ฏ6„จิS๕/^ฝฝ_๒ไฮ้ŽAg†ฝ๛‰lูถC ๆฯ'๚™j$ำ�?�6ฬzoป฿ธ "Ž�โ[Yบbฅไ3กรๆw7” ฿M‘cวOุ‘�Zซฆ�ืช™;ส)ๆ>›ทะฯVƒŠ๗4m$ท�\ร�ฯ;ฃ็zgไูท� ญฃ�ฒfษ,wิซ-ห—‘มร�ทปฟ๔l_ษหฝV'็บ๚Lฟ๘๚9n>ฐw&m[wCตสาน�ฝฮ*ฟW=ๆKำnYรค�ฉDฑ"๒@‡ึ๎ุพš8Y˜–ฬNš_๗u>@Wร็Ÿ๎ใ=œy@‚ $‡ b}Sฎšฉง“ถ>v์˜์ฺนCดฺ SๅOซ๎ูPW *"ึช}›�\๋{ ฎ4_D‰xบ$‹.” /ธm—#kM\ปN]น๑ฦ›ํ้โ2ˆ่ฏVŽปh~�ทoฏปบฯ�mu?ญ6ฌฐปใๅง"bฐ ณฏำ;๐�{๗}าญฉญy๗ํูcฟ�ฉี&Oœ8๎ถT ฦyซj{fญ~่ดež7็7Y๒ืb็า~ฏูM๓๚jHแ"ล์{Aซ:ำฌำdๅฟ�8‹A_ ัะ_{๗w1็ฮ];ไ˜ ž0๓ ’2eสูc ขVิ๛ิi�บต2uส$;๘รฑ๐::ี�ผวjล@ญจำดฉSdํšี�อA็C)ˆจ+5Lจำๆอ›L˜pbะ1๋~EŠ7m๗�๗†๎ไ 1FTลQƒ ๚ฟ ฬ{=s–,๎ณำ�=jค๘]<่ลY‰ € € 2TE ™Gม@@b(ีu—ฬ�ฅHฆQDฝw’๓�'ื{ท>� ˆย_+ๆฝ�ๆ๛rฺ|xัTพl)๒๓nฌ� vฑHกฒ}g๐ึ^ูฒf‘ื_๐}จๆซน๕�ณ‹w๏*eK—p6E๚๊\๏†๊Uไ๏ๅ��W?œำ`คŽื™^๖ž์�c*๔™ โซ}€:�๔uึ๏๓ๅวŸ|UG�๖Šป).ƒˆ๏2NVฏ�hซž7ีw๔C@g๒‡ )�w์r6…{U‹;ต๑[ฟcืn๚ฮวr�| lบฉFu๙s‰ฏฺอ งzน•/ฏีIฏ๑�”้๒๋œ?‚]ฮฎห™#›ผ2เI๗CO]9oแ_6€ัAb|ู้วE+$Ž?ั„]ƒ(ฎ�?฿?ขำฐ@W 9~ด‡dษ๊ซ.�๙gฃๅ@@;ทบ\ ‚ˆEMชU�vึuแ‚๙ฒhแื8ฒ™&อZˆVvำi�ุOM˜๊@ธ�ฝีใ"ˆจ•‹™ช„:i‹`mร8y[OฏXถTf�:+p—pหw๋iช+f1_่9'๏+�v]กญ‘ตข7P็ญไท฿ดI�b�ฟc5$y_วฮv]`QW๖้k“ฉSษฆlU๒ŠฆRฅ๗�~' ฒ ฟ;ืฟฃกTฉZ�nJ๐๒๎ฆอค\๙Šv�ฟ�๚Sๆฮ๙�๏ฬ๎บ[*Uฎbื9AD]pย\ิ๕Sฑโ%ฅek฿๏ต� bใ&อค|฿๕>=J:xจ4i~”-๋ ?Ž�เ]9mฺN_mŠฏ bฅสีค๎ํ๕์pพŸ๘ญ์1ญ‘'๏ŸฉฟLลศ๙—+F๊๛#Wฎ�๖}ช๏ื`S;ำบบ i]ญำW_ŒณUƒํ็ฌำJŸ๗็'ธpแJV"ฑ� ใF๘ ˆ�ๆQพโะ�Ёz@๑ข…ๅ�ฆwšpZYนvฝ Š={ฮžซห}-ๅฆ|R๊ 'จ๓8์�๎^ั*ˆ��*cว+'OึMv�อ5ฏณ๓๚ใษฏIุๅ}k›Š~Z7wทE6ใฝžVรkrg}ฉeฮซี๔ฆL๛Eึฌ฿dฯœ9“ผ๑า3๎ฉฎ5`ADgส•ถี ณ˜ฑk[k ืM�uฎฝ/�'Oฎœ๒@วึขกO 0Ž5มผ3ฆถN�{?"ZAะ™^~ใ[ Q—๕yถlv—ญผธx้?๒รO3�BฑDิ6ฬฏ ๕}˜ฌํŸ;ตฝGชUฎ`�H�์ฺใซ.ิ ๎-v,ฮ8๛>๗ชh[H}–๚จyC59~�คL6ฯ๒ฏฅ+์nNะRซtž:}F&NšfCจ๚กน>ิฟhงOŸฮ9-ฏ €D(‚ˆ={\า›Šึ๚…„w฿ๆg‘3g.้�ภƒถnLZ3งJ™Jz™๊v๚๏cญย๗แ{๏๘]G๎ht—ไ7-€ฯœ>m[ว๊บ +นี�‚ต0ฮœ9‹ญ่ง็ี).‚ˆ5j�$ทีญgฯฏต’ wาส}t๏i~ทHogzฯ„ ตšใีฆ-[Kษ’พ/ย,^ดPฬŸ๋wˆทzก7(จํ๋ีo`๗�gลr๙uึ ฟใด๒`‘ขล์บ`AD'ธvฦ3fฬ$ปvํ’ฏฟ��๏<ทีน] š๖ฟ็ฮตญงฝ_‚ั{๗ํgช2ฆ6ฟ‹—Q}เwlเB๋vคH฿๏žมยฎ�๋#2dฐ‡yƒˆบt•พคœตJโำ/ ฑฤj;เaฏ p6นADญ\7์ี็์‡—ฮFm ฌ8ฎ7ญy๊�ึู$?N)ณ~›oซ์ืหmฟ๋๎มŒ7ˆ๘ไcูะฃwื‘ฃวหฟซืูUŠtยกDlT�6iaฺ3{'�n฿g_ฑ! '๑+u?mฝ<เ•ก๖_ฬ๙๓ๆv[oุดE†8ฺžชX‘B๒๔ใ�ผงohP7ฤF๑๕7?ป๗ุ@แkƒ๚ูฅ๗ขฯฝ�?;^�€ิi}ญมยวอ�้TนBYำยป“๗oฺ58pHJ/"อLkpgา๕˜อ�s9�xE@เjษ!ˆุ้~๖บ\้lำฦ2๛—™ถ…ซ†�ัHา˜ภ—N1 "๊๑�ชx๛๑ปoไ๐แรขกซ:๕๊Kฑbลu7๓๏๓�๒๙X฿๏&บ�ญG/ษ˜ษ6�ตkงฬ˜6UŽ˜ใt|w4บำmQฌ๛ฦEQฯ๋Tๆำ๙ ึษS}Nวฎกฎ-[นaธ-�m–พ๛Vwป๊คฏGป?fGั฿ใ�Yฑฬ†/]ผ$7฿R�ดBฎ้V†๖ณfอๆถSึgขญ‘ืญ]c*'ฆ“ฆM๏‘ขล‹ปืDำ–ปmฺwp๗ัญบทuหfฟuMMฏฬๅЁZyq๒฿›ถ�GEฏ_ง�ํ๎ถจ„าt�j�hฯฏฯ~๚ิษฒ{๗nคkึโ^ษš-›{mo1W.ศ{ ซ๋ ๏}{๗ฺเlำ&Z�NแL� ขฎ{๐‘n’-[vปyง ้อ4N๚พ)Yฒด�ีค‰คK—�n๛ำ„@�ฺ A~ฤWQ/�ณO_I—ึ๗ลmMญํฃ0่ฝ-�H๑’%ํ›V�ฃF^ ‚z+f๊�K–,–%ฆbbุ™0)o�ฬ4jิุ0๕เ™ำงหช•พ/๓่ฒSฅS็ต…๚œ฿f�?๗ฺส๙s\ฮœ9u“m“ญcbB@@@@ฝภ%s)์D+‘�€๙โ’๙RBŠภ’๛�zฐœค"†่ใ�~ส ำRืืN๏๙ง๛ˆ†ฺงqพw[๙พ5x๙ ฯ๗ถ tชึ๗ไ@S๙0์ฌ ฤ้ด๚mญ่Lฮ๕ ๆฯ'๛?๎ะ'Oษ3/ฑ๋ซV*/�บ๚>” ๅ ขผ7๔ๅp๗ขU{฿ฎ๏h* �rใ๕แ๖qZ\k๕šw†ผ`ท๓ใT™3�O;๏ z~๛ƒัฒq๓–p๛\ซSŸg^ถx*™@aฯ€@ก^ไทy‹L%รŸํ๕^~๎ 7x๊l๖}8ฎaF�`๓�?“ตฆEudฯsๆ์y2้็Y๖4�ฐโต8iูdญ�จ“�‹ถ่œฮ˜Š-ZมQง:ด–šืWต๓�@คฎะŠ›ลŠฒmoซuฅj�๙๒‚ˆ^ ๆ@ข+T‚ˆMšถฒๅห�Pั;o วPญzuัVผN๕C�Aซ/_บTฒeฯfซ฿3ต๗<ตn=MฅB;t่ |6z”{ฮฎwณแนˆZ๖��บญ5ญƒฝก( Iํ7ํ`งN™dซึน'ป<ฃ•๏iีฦm฿ซซต•๔ถญ�ษย๙๓m›Z]งกฌ={v๋lดฆ–mฺูŠŒบ ๆฃ'ซZญบ�Zงฎ[Iฯน€Ž}ทฉิ๘๕WใUัzีฬฺ๚ูาำpเ_ฆŠ]ึฌYECฮ_รฏดอึถฤญฬ˜๓(่^Kวq�ุ1๙r�8ทาโbsญ�8yซSฎ_ฟNฆN�1pปฌO}๏8AOg'ฝ–†งNždซ$:๋#{ี``“ๆ๗ฺเ ณŸz๏�นS–��—i �าฎ๙มปrฺฝ“�gc”#GNImช jeฦ-›�“ys็}Dิใต๊dำ:‡i+์}ฟฉ็๊ี+ๅ—™ำฝ—น๊|฿~O�฿ŸW,_j*‡๚~7ึƒœ€bD�๎ฃ|ิpฃป๎v+‚zจพ~0UE5ˆlาV็+U๖ Ž๊~jฎ�s็�์0[5ฑฎฉ`้ดผvvา๊ฆ์ŸQgฏ € € € € € €@b ˆขOJซ๎i๕ฝ๔้าษ›ƒๅถปไแ#ํถถ๗4‘บท�d็``หfwJƒบตร;๐ีaขaนุ"ถj~—ิฏsKธ๋้Š็ฟ)‡›6sY2ห�ฝ๘ด�็Zvz`BฟŸ2�Tช�รŽ?*??฿฿ถDv๎5ฒ็นtลJ๙๔๓o์icD�ฑkท�฿[FeˆvŸฆ&ดฺ๘rhU?�แง2gมb๛!ช๗$ฺšฏัํทJใ†๕�ชธD๔*1 ]คDŒ๊}k•ฝผ๙๓หž�ป‚ฃzžจ์งื*\คˆฉ~xภ๙v…๛w{ฐshXฏDษr๔ศัpUเ‚ํ๋ดตoแ"…m n๋–-6œืษ”)ณh[�ํ�ถษษ“พ/d\ํผ๊Qดx1“.ูผyใีvwททj�ฮmแ<๚“‘ขี#›RฅL% ฒญy๗™6อ๚�ธึIรEL{่“ฆšโฮ;ฎ๕4๎qฝ๛๖ณ_ภั๖ั_Œใฎœั dถ์9ขๅxŽ„Z.Pฐ/Qยถล>dยŒ›M uoีะˆฦฅ๏2eหJไ<แผฌ_ป6สA�๔ๆ ?…ฬsJŸ>ฃ๙๓นรŽ#บ๋@@@@@@P ˆขOhฤGce�†อถบฦˆ7^ :สe�ฌ–Qใ&ุm=าE*^nก›PAฤ�oปYZทธ;่X๛?o*"š–ƒฺbZ[M๋ไ„๓ดฒเซ๛…;n๚/sdส๔_ํ๚๗‡๙ช๛้BBตฝฒถYึIซMfอœูฮ�aส๎�zs ๛ vอฺf/ข็๙ห๏ lPฯ<ˆu'mฝญ-ธu*[ช„TฏRัฮG๔ฃrลr’+gvฟอZU๑?�–Vญ•ญ�vฺŠ–ฮ7ีจ.]ฺ๛*๊่:‚ˆŽ ฏ €ื"�‚ˆืbฤ1‰K@ ]บ>dฟธqไ๐a๓้ว!{๗š*˜E‹ทm…gL›*๋ึฎ๑๋อตjK-ำถYง•��#ณfL๓�ฮ € € € € € €*@1D฿'�,ฟอ[dGง!= ๋N_}7Eๆ/�หฎ๖ฺ�BW*ˆXคpAyถo๗ภaŠถ๎7hฐ]_นBY้๑P';?๘MS๕q๗^ษ˜!ƒ }๕นpว�rข�ต๔ป>T‚ˆ[ท๏”�ฝ๓‘S๛VอD[Geš`žีผหฯ*ข็๙พiวฝฺดใึษDผVง�OฟdซU([Jz=zT†้>+Vฎ1มืฏํ9ำฆM#oฟ�ผป?AD—‚@k ˆx h’ตnนUJ–*m�,๋Ptš�ใ๗ฑVั1.nบBลJrื�Mํฉตฅ๐^ำv{—iƒ#gN)X ฐคฯ��๖ู˜Qq^ล3.๎‘s"€ € € € € €ฤฝAฤธ7พฆ+ฌ�ธYFŒk-Wฆค๔้๖€฿yฮ›ju�6ํฟ.H`(,&ADm๗œ;W๔ป`$ ฮ๕t—�“‚๙๓๙ํ=nย๗๒็’ๅvVLิส‰:=^�]ฝฮฮ�๏ๅg%SฆŒv^\บtI๚z]ฮ„…ูuกDิถล}Ÿ{ี†๑ฒdฮ$C^zฦณ33้็Yฒ้ฟญ’ลTK|ไ�๖v๕ส5๋ๅรOฟฐ๓มž็ัcวeภ+CS๘ฏี้ฅ�.๛ฒ•xดEtถฌY�๓๋Œถ‚�}พ/์๚่�๗Ifs?kืo2ญงุ�ฺตlf฿ �ƒ†Ž๘Xถl�aฯ๙�ะ—�M_Nœ, -ฑหฏฟ๐Tธkน;2ƒ €@‚ˆ)0๏‰@IDATAPX•(บt}XrๅสๅŽ}�บต2uส$w9Tgš4m!eห—pxP�eๆLYตrE„๛ฐ@@@@@@ y D แ็๏ด.ึ!V1ญsต_๖lYMศm›|4๖K9y๒”ฝ7�ง+œ``หfwJƒบตํ>�_&GŽ“ย๓หsO๖t7}<๖+ัชw:=ี็Q)^ดฐป-ฒ็zบV~้ิ๖ฉq]9eZ1�0e†,Zฒฬž!}zัสฮ4s๖<ัะžNys็’�&lฉ•w๎�c+๏ํ�ะูUB%ˆจrZC๋ผ†.{คณ}.ถ๗ฃ?J/*�z=l็๕‡ใฎ๓U+——๛Z57aลL๒๏ชu2z�ทr๎�9�d'oEฤkuฺธyซผ�มง๖|้ำฅณ•(K—,f฿7 �ZๆถN—6ญผ๕๚ ปŸ๗ †>ั๓A)/ฏh›ๆ…‹—ฺ{ืh>ำb๛…ห-ถ๕@๏5hฉm›๕ฝส„ €@T"FE‰}ƒ@��Hกย…eวถญฒ๘ฯEฆ2๘™ฤ0l;ฦขE‹หmu๋J–ฌู$Mšิr้โ%๛ฅ }{๗ส๔Ÿงศูณgอฝ0P@@@@@@๘ ˆ�ๆQพโ๎ฝ๛dศ�#EซF4.Xภ„ {๘mv‚ั ">1เU๓ฃ/ wหM7Hว6-�ฮั‚s= žiภ1ข้กฮmๅ๚j•�อhำชŽa|จ™'WN[ัOฅ ขV„๔ฺ›ขU )EŠถŠฃณฌU*๕๏-นrfwVษ๚�ษˆฦ๚ํ็n43ย�9h…ล=๛˜๛๋`ิชŠห•–Z7^/ZฅQ'o๑๛)ำM๛เ?ยต�ฑkท�฿[ฺ�Ÿ่๙h๕ฟ่NNdญ ๘ๆเฎฯbฬ๘‰ฒ์ŸU~!== tษโาตckฟ žs" —jหํcวO8ซlษšืU•ŠๅKห่/พต๋ฝAD]q-Nฮๆฬ�S~˜:ำฏโขnห“;งthmฺ๐•.แ์j_5hฉ๗ฆF๗NZ ฑsป{ฅDฑ"�ีv~๖�…2yฺ/๎uดดถifB@เjฏ&ฤv@@@@@@@ ด"†๖๓๑†ุ9&ล m›“ตUฏ†ฃ:yƒˆN+h $๊xห–*!Z๐j“^wณi9ำTิVภฑ59ฏvพ)SHšิฉฏถ[ะํZลp๋๖’7ON;๖จุiซใ ฆBbnS๕1ož\๖ผ/�7ย ขsแ˜8้ฑ6nฑ๏"… D้นh{lญŽจกB=&uŒด‚็‘ฃว%[ถ,ืl๊�/ฏ €ษC€ b๒xฮ�% € € € € € €$]‚ˆI๗ูฦ� "ฦ�ล#นะฆ2ใ๘o'Eฒ‡�&oีE�-๑ณ• b�Œ„ซ € ฟใื›ซ!€ € € € € € €ฑ-@1ถE“แ๙B5ˆธrอz๗ีwQz"ZลpศKฯDi฿ธฺ‰ b\ษr^@P ˆ๊Oˆ๑!€ € € € € € €‘ DŒ�‡ญQี b†RปD ฉวม`@โQ€ bฦ„ € € € € € €D]€ bิญุ@@ "ฦ*งD@@@@@@โQ€ b € € € € € €AD� € € *@1A๙น8 € € € € € € c‚ˆ1&ไ € €1 ˆ=ŽE@@@@@@^€ bย?F€ €$k‚ˆษ๚๑s๓ € € € € € € "&‡ศ- € €‰Y€ bb~zŒ@@@@@@!ˆศป@@ A"&(?G@@@@@@b,@1ฦ„œ@@ &cขวฑ € € € € € € €@ย DL๘gภ@@d-@1Y?~n@@@@@@’€Aฤ$๐น@@ 1 DLฬOฑ#€ € € € € € €"y € €$จAฤๅ็โ € € € € € € €@Œ"ฦ˜ € €ฤD€ bL๔8@@@@@@Hx‚ˆ �  € ฌ"&๋วฯอ#€ € € € € € €@ ˆ˜"ท€ €$f‚ˆ‰๙้1v@@@@@@@@„ "๏@@ ˆ˜ �\Wเ•Iห{šหพ�ไล—_“y �pท]๋ฬ๕ืU—๒ๅสฺร๗8 ณ~™}ญงโ8@@@@@@ dฒeห&งOŸ–ณgฯ†ฬ˜z ๚ p� \W,ƒ=ว�ฃ็dื‘๓1>'@@๘ ˆฟ�I๙jE ’G๊*ฅK•’B HฆL™dฯ�ฝฒcวN™1๋๙aา”ค|๛1บทreหศO?Ntฯฑtูriื๑~w๙Zg>�๐]นฝn{๘žฝ๛ไถ�^๋ฉ8@@@@@H0B… Kญ[n•� J๊ิฉ%EŠv,/^”ใวษŒiSe็Ž 6พPธ0AฤPx !8†ชEาK๙้#ู๑3dลถำ �ปฑdF™ึฟค็ยงค้[›#sRุ9]Jyจn.)/ญ”ฬ›NาฅN!�ž“M๛ยไ‡ฟส๊gbt›ณง–บๅ3KMใZนp9แ’l9pVึ์:#๏ฮ:ฃss0 € $… bณๆ๗ส์_fสษS'#บMึวฑภ๓ž‘ํ�ฺฟ๘Etฉ 7Jทž}dป &ฦฦ”?_^ู้�Q{ชK—.ษ�†ฝm�งbใิ๑~Žภ โ๒�H›๛:วxcLศ @@@@@@ ž่�ฬUG๑ืโE2๎œซ๎—Tw ˆO๖™&yๅi๓ฯ‡ณส ‰ปฃuๅ๗:’๛jๅฏ–^Ÿวฮง‘ `๎ภาRฉPฤAD็ุ#ง.ศ›ำ๖หฟฦMHญ\�t๖R๋๖„9—๔{๕��tJ๎~3้{4ศ-O5ฮ+ู2ฆ๔3pฮ_=๗ <๗M๔�[ฮ๑moฬ.ร;ฒแFg๗๕ะษ ๒ส{ไ๓‡ฝซ™G@ ฦI!ˆจ๑;sFๆฯŸ+�,_cN='๚๔2ภGขtะ–ญ[ๅžVํc%0ุฎM+yํๅ�๋ถl�A�]นส]Nl3Cฟ" ๊ื“ฐฐ0yแฅืd๖๏1�‹2Aฤฤ๖.`ผ € € € € € Lภ "j;ๆฝ{wห�={%uช”Rถ\ษ’5ซ=Dซ#~�ีxูณ{WฐS$๙uใ๑� ฒ{ต/M ฐw…Nั98Wฯ•ฮlœฝF5ˆ่ .ชถช™M>๎Zฤ^โณ๙‡ไษ/ร�!M.Aฤ๕sษkญ 8�‘พ~hBกƒพ�้>Ÿบ;ฏhP๖rีุภอ๎๒ลK"บ]&-=๊ฎc@˜ $• ขใฐgฯn™9�g9x nพจแ\‡ื+ห—,”L3บ+–ฏ๘Wๆอ_ {๗ํ“š7\oรu™3gvทฟ๛�H๑�‡๎๒ตฮ$ต โต:DvAฤศtุ† € € € € €‰Eเ�‘ล‹�5ซรฅ่๒ภƒ’+w{+›L‡ฎษ?~—Xn+VวI1V9#?ู`$๋neฮ•0b`qยขร๒ุธ๘ญˆ๘หชใ๒๗งa›Š|ฉL[เดr[นฬ’!ฏ฿นn|k๚~าร]ึ™–๗4—7^ี]ท่ฯลานk๘ Šื_W]j\”-SZ2š`ใๆ-[d�บ๕2e๊4๗Xษ™3งิฝญถิญsซ4i|—ปํใOวศฦ›ไ๐แ#๒๛�y๎๚`3E ’;�a7้๛eฬธ/ยํึฉC{IŸ�W!|ฦฬ_�–า+T[j�h๗?x๐�0iŠh›่�๋ี•bE‹Hบt้leฦ฿็ฮ—C‡…;oD+๎kืF2e๒:๙๕wั๊‘“Ž๛ึฺทXฃ‚ ศ��d�†๒วยEฒqS๘๊ไม‚ˆฅK•”�ฬ9*Uช(‡–�])ณ›+U*วห2 € € € € € ืฅK—•f๗�k/sไศ3๊ฃp—L™2ฅ�� ก,TH2f๐}v6L<(K—�%;vlwLb[A1žŸุ{] ห}7gwฏQภNwHจข^�[ฑ�[eึสใบฺo*˜=ต|ึญ˜\_,ƒ]๖�%ฉ2`ญ8qมoฟk] ˆ่“{ฆฉi้m*๊ดๅภYฉ;xฃhะ;iX๑ื็Jปมะ็MEฤจถห�ฎOqฉW�W!hำพณrฯ๐อ6Œ่=�รusสํ บซzŒ�!฿,>โ.3ƒ €@L’bั๑8z๔จ�:sบl�บลYลk, 4kาX�:ฤ=๋/ฟ�&=z๗u—™็ž๎g„9์โบ๕dิ่ฯœM๖uุมาขySฟuฮ‚์๚==@VฏYcWuผฏญผ๔�@gsธื#ๆนืฌU'�z๏Šฎ]:ษ€gŸrW5l�<\๐oร๊๎v๏ร�ฒห/zN4คจ“ ‡ฟ๛ผ�ย@S�๚ส—„œm๗{F4x•i�ชๅ๎9พ๘r‚ผ�ฺ�๙๖๐ƒ๗หใฝzšpdzฟ๕บp��y�ู็2๔อแ~�ƒˆฟ�Az๕่ๆท.l฿ฑSz๔z\๔ู0!€ € € € € €‰I D‰’rOซ6vศGฬg7cFโ7� H๋๖M+็T~๋ฝ พ๗Žœ9sฦป*ัอDL€G•0bB†•$*AD�ฏX๎4ฒเ๙ฒn๎มQ�L��c’9]Jij*๕้t๘ไ™๑o๘ ฃ�h~ิ(‘AJ็๓Uz™ป๖„ฮ™ึV\lP1‹ดฌ‘อ๎ถl๋i5็ ฿w๔ผฬ^ใซQEฤ•2หญe2Kฮฬฉdำพ0Yผ้”,2�\mา@_ตขคrแ๔ถ๒ฃปr๛Yผ๙Tธ๐Ÿs.ƒVˆ<~๚ขL]qฬฎพนTFฉk* ฮ‘Fถ<'kv‘)ห}�œใข๚๚c฿r[ูLv๗ุ#๏อ:๔ะ๑�‹ษ]UณุmใM๋๏>Qh�]ฑPz™kช-:ŸY฿�ๅsฟมฆฏ+&e๒๙>t�ไ๗๒แl฿๓ถ/๋@ˆŽ@R":Zข}�๏ฟ™Šo'UIโ5eพ4’พmNนธ็œœ๙6๊•๗b๓ๆตŠแืใฏ„ 5๗๚รไ๓๑_E๙2zผž'ฒ้ิฉำr{ฃปm๐/”‚ˆ:ๆ .Hช�โช›ต r vฏ‘๛?๙ธt{๘ม`‡๙ญำ๊‘O>๕ฌปฮDtWF0sโฤ นต^C*#Fเรj@@@@@M;7‘Š•*�มญYตRฆO›๊7ะn={�n\บ2,์Œ5UO>%Yฒd“9rˆVK�่ร๗ไิษฤ�Y"ADฟว ‘…:„จ Q "๊พำ๚— ใ้4๔็}2ไง}าฐr™ะณ˜]w๎ย%)�M„Aพ…/”‘ฒ&จำk“๖Jฃ*Y�๓ู•?v>'UฎณkƒˆŸฮ=(�_DR๛บ๛ฉษ>Ÿ๏: NŽ่\HZ\๏ >๚h™0e฿/vบAC๏๖ล/••R&ˆxษดDฎcZ"Oyข„d7ํซงU;ฯHwSIpตyฮค!ฤr|>?�}4ยŠ“� โH8q๗U/๓?Sๅ๐!SํPงฟทœ–F��tีcุ@ุHAD5 3฿`š?ฎ�ณ|Yl&ศ๙4„˜กsI‘!ฅ\eฏ฿nฟRVŠ็Nkืํ2!ษ‚‘œg๓�ณR๓ล๕~ววฦ‚Vฆœ3 ŒdI๏K`๖ทCพZt๕ึษZๅ๐ŽJพg๗ิ„]2zฎ๏93ฅM)๋v‡ษฒmงฃ Œ๛โ €ษC น๕i>|HฆL๚A^แ8ฑy๒ฎXวw�‚ 'e่ิ}vฟ}วฮหบ=av�[ัฎ0?Vl;#›ึมฺนDžด๒t“ผnศะฉZ่ญJ๘qื"าชๆ•JˆฺF๚Sy๐ะษ๓Rษด.๎�0ไฬไ Tjุฑฮk�๋๋5ฝAD]ึ๊‰oO฿/�n?m[CwฏŸ�ฏยใs฿์6ใ‹ฝถฦ๕สg–กฦบคนW�3aวQ ;zŸณฺ฿sC6้P+‡d2"ง๙๋OJฑ�e—ฉxฤ„ €@l $‡ โ…๓d้฿‹eแ‚‰�›LกBt�‹-๏i.ฯ๔Brๆ๔��่ฌ|ีj|-�vtC{+–,2ฅ๐3ุ�ดŠb^}�yฒooฉZลWJ_74l��msขKจ โ _‘ฏฟ�ฮo�๏ฝ๓ฆ�ู๐w]‹Vํe๕š5๎rฐ™ˆ‚ˆc?�ศ†๕˜s็ฮหญท7t�œ๓�นเwษiZ่ดqำfำ๚^;D|เกnขีฝำ'HฅŠ�UีkิrƒŠ๎Jf@@@@@@จGCฉV�z;*�œiไ๛#‚Žฐoฟงm‡(ํ,ตyำFYผhก_ีฤ %ย•Cเก #&dQIผต๖l•Y+•jscv๙@aw›† 5tจำuล2ศ/ฯ”ฒ๓ตgึjˆZQงภช‰]nอ!ow(dท}น๐ฐ๔�<|eศภ ข†;|ธีใ�ะЇฟZNด�ฒN�ส:ฦ™O—’”—‹(พe„ƒ'๛W<,˜=ต��ฟ”ษ้ซ˜๘๋ชา๖�-๖\๚รDcฺWน�&;๏ "ž={V*Uฏxจ x๖)ั ‘ฮ•ะคณ/ฏ € € € € € €@B�xs-ฉ}k{้๓.ศc?5�ัสฝญ�H๑โ%�ถ]0ว?~\ๆฯ�M6ฌ�๎ช~‹ง‚ˆ๑ูe‚ฟ2มป^A‚w‘'6ท]-ˆจกพž rK๏Fy$cZ_Šฯ�2ูKdACo[ๆSg/I‘พซœร์ktƒˆLตย๊ƒึญุ7ขs!้h*�้4r๖A8ัื‹�ูฆyๅฉป}ญ๖ถ™ Šื=๏k๙lw๔�่tKyง“๏รW Uๆ๏}eฌ� โซ“๖ส๐๛=G๚f;ืฮ!ร;๚Ž_ผ๙”4ถ9�>Q]1ฉo นตlฆpปkตฦง&์”q๓ƒ�ZธฬŠ๏W6‰k�-{Žž—1sส†ฝa’'KjS-2ป_EวU;ฯHม�b @$ี b˜ cอŸ?W�Yพ,:กshb!jeส˜Q๎n|ง<ิ๕~)Uฒ„ปู ส•+[F~๚qขป>*3�Ÿ(“L‹gB%ˆXฆbตpCื ‘oผ�ชป>XีDwใๅ™ˆ‚ˆ‹�˜#9ฒgท{iUE N๚ ฟท_iฉ์ŒษD"‹�\์.3ƒ € € € € €„’@ฅสีคแwฺ*‡/^”‰฿|%;wD^”์บ๋kศอทิ–๔้}…ฬผ๗s�ุ1;z”œ?ฮป:ัอDLเG,„่ )!รˆ� ขV๙��J;�์Sู€š3N}ี–วm฿�"ณื๘ช!:�๚5ฮ#šๅณ‹sึž”–#�s6ู๕บ]'ญฦ๗เจํ๎6‰nq๛กs&ˆ งšฃsM :ถyw‹œ3ษฤH& “๊=yง…OI{Sํ1๐XตSCgzๆ๋]2jฮ!g‘W@b$ƒˆอท–f�2ำด—=#›๘88}›\’2j9๓อ!นธ7๘_nB9„จU ,`ฉดโ�บ๕ยฑi ๑นณ�ฬบรmฆฝ๐๑ใ'd๙’…๎�ฺถ๙ํw�s—ƒอh5ล“ง|ฟ๏ลf10|WฑB™๔�wฃF&o {ห.ฟ8่9้ิแJฐ้=ญร�wฏ�ไ๑�=�ใ๊ึSๆฮ[เ.›‰(ˆ8๙๛oคB๙r๖}๛๗KํบWZ>;็๙๎๋๑n ๋C‡‰ViิษDิve+Uwq_‡ ~EZ��ย]ฎ฿่nูพ#|5twf@@@@@@(Sถฌ��ด…คL™R4„๘๓O“ขUั0Wฎp[Ny๓พ‚v|� โŒงJI์๚cwศ7‹}ฯ �˜�๑j๛gmญ“7ˆXe@๐ŠŒ�๊1 "ฺ‹z~hห็พwๆ•ๆืeuซ~ฟไจ<2ฺ?ุ้9ฤ�๒VEทตณถ]พๅ•๕A+Jฺ๊f[[Y๋คN๊ล„ €@l$ฅ โัฃGeฮoฟŠ�E!ฑL{็—”ูSห%๓;�้ฯ๗‡ #†rQ‡ฟ๙†4i|—ๅึฟ์ีmpง์ู�ห%฿~๕…TฏVล},N;cmอฌaFNœ<)ืีผล�ว™ษŸ/ฏคI“ฦ.zrAฤGบ๗’฿็ฮs‹๔5ฐu๒งc>“!C}AC=๐™�Oสร�๏ž#ฒ โW_+/ผ�šปฏฮฬš6YŠ+ๆฎ‹Jธ/ข โปร฿”ป] >๐P7Yฐp‘{nฝฮ๔Ÿ~p�`/_๑ดนฏณ�๎ "๊Šกo—?ใซ!ันณgJึฌY์บ๓็ฯK…ช7ธ�™A@@@@@BE Hัขาฒu;Bิ ณfฬU+W\๓๐ฎฏQS๊ึซoื6อฃ>๚เšฯ DL ง,„ุkœ/ุ๕~—Bา�f_a^B„ƒˆงฯ]๒“:eชํi๋�•;ฮศะฉ{ๅภ‰ ~�ฝ ฿๗)!uห๛ผ�พฺ%c็o0O[Wznญ๗;� โŸฆแ�ฆ"aฐ)ข โขหH™|้์!Fn•i�๘ย…มฮ1๓้RrCq_OŸ•M่ ข3ึ!m ศ#๕rูEญPY�™5‘>�ัฎ�eีqi๗�V็tแ^{5ฬ-/฿›฿ฎ_ฑํŒิB{ๆpHฌ@ธ&คD|�ษงd๙ฒฅฒภดb>.xUมkย‰‡ƒlะฐKnI‘>Uธ0bจ‡•งOฏาปgwWj�†๒๚กnPNC†๗w๊ =ป?โ๎ณw฿>นต^Cป|D ๐}‘ยปq๔ุq๒�{ำฎาใง�๐ญคNฺ�Eซ;vLJ–(.2๘พˆขW�๓ฏดn฿ษ�Oƒ_|๖ฉปฌ3็ฮ ำตน๏ส~~;\^ะ€ไ�฿f™J‹Wฎl?g]d}"zี`ฅ,ฏ6EDิใ+,j๕I�G'ฏ�กร‡ฅ~รป�0f`ั`~hx2UชT๖/ึฮ:}ํ๕x?™1๋๏*ๆ@@@@@@ศ` A<�h๗3‘}๛๖สๆM›‚Ž้ไ‰ใ๒ฯŠๅ๎ถขE‹K‹Vญe‡)๐0็๗ูr่ะAปM[47nาT๒ไอk—ทo�*ฟ™เ—g"ฦ๓S‹JัRB†c3ˆจ๗ใดvฺ3kuมr|•oผQV๏<ใ�ถ๛Aฤท;ฝŽN_�qX�bง{}๏Œทลดฎ/๗๔•jƒqD�ข{1I“Jไdุ%ypิ6๏ฐยอoVQฒe4}ฐอ๔˜ฉฺ8แrป๏p;^^1ผc!้\�w� 7ž’ฆoฏ(ฉป?uw^yถฉ๏�™๊“M"จ>ัตX €@DI!ˆัฝ%ฆ๕aD{จ‡฿อ›สะ�{-\จอู๎}�{้2i฿้๏*[QฑWฯnถŒพ฿ฯยฅsื‡eใ&�฿—~�eš*Xะณงศำขปfญ:~๋‚-}Zž๘‚heHg๒5z๖์9ท ณณ๓๚๋osค๛c}œE^@@@@@@(Pะtทํy g ็ฯŸ“w‡ฟๅ,Jษ’ฅฅEหV๎ฒ-๖`Zฆ6œIื�|ฌุฟ฿Y•(_ "ฦใc�บ€tฏ๏kซ—ีึพN;ๆˆ†‘Paฤุ"~paiwSv{›�z@z4ศm็ตตs�ื7ฝ}o1ข�%3สด�%ํ๑ืาšนงวซญ|Urด�t๕kƒถ3~อ<ป—Ÿ�ฑำฅDฟี๎˜ใ:ˆธkD%I—:…ฝž†�4lชX(ฝฬXฺ�•Šˆ5JdO•ฒว\4ํœ๕�‹7?� Sฒ๐ๅАŸฮ9$Oฝหฝ3 €ฤD€ bL๔b๗XoQฯส•๏�ๆ›n4ยnrฃ ฬ›๖8`ร|Z 1ุควฟ0๐Sฑ„[R_๗ “Ÿ~ž.๏๘‘hฅฤภI+*vไ!นใŽ๚ถ-ฒn?x๐�|�ํป]๎�ไใา๕�ฮ’6ฏ๒๖… dรฦM๒๒k�'ร฿|C๒]�\dAฤ†›หk/?/UซTv+8;v�V๐�KAฏlๅ†ี+�ี_|9มŽม]af4๙๚+/ส-ตnrฏฃ�ีh๙ŠLหๅWmปf๏1#L‹้ฦw5ฒซ/๙[†พ๙ถ<๗t�ส9น็)RXฏฏฟ�N�‘ธ� x๏›y@@@@@H: ๖ปD้†ฮ;'๏ฝs%ˆจ•[ทkg>[ษดจฦqSAqึ๔iฒuหQ:(๏D1Ÿฮม*ปW‹Jัู90Œ˜ซ็JgSœฝฦvฑv™L2๙‰แฦ๛า{ไ�Yยญื�Vภgฯ_’2Oญ‘a�๖i1sบ”ฒbp9ษžั—2^๒฿i้๘แฟ0โท™\�pร€๏ฬ�/ฏ�ธืG\5hฉ๗ฉำNำนู�›e๋s๎๕uF+6��ฟ””ส๋kIx๘ไ)mผœIซ*6ฌœลVž์>fปฌ�ๆlo{ๆ�๖Ÿ5๗ฟีoป}dZ2฿U5‹{LณฯŒปหฬ € ‚ˆ1ั‹�c0ขž9T�1Gvื๙๓ๅ•2ฅKKแย…$}บtฒcื.๙๏ฟ-แ*FvŽ*•+Iึ,Yd็ฎ�แ‚u‘ง�2™า�'O�bGdว–+[Fr็สe}W;�ลAฯIงํ�ำ•ฉXอฏXก‚?~,hhา�)ศL๕jUไ�ฏพpท "บอLใ›ั�kXุูh9็ัgฅำžฝ๛œUผ"€ € € € € €IR UสTRชLษ•;ทdHŸมj8(;ถo7ฏ‰ป ข๗aD๔jฤ๑�}7gmอ}จˆIE๛.ซกฬ—•�N‹ฉฬ*Z ฑUอ์’1ํๅฬnC~ฺ'C๖} ๋ t๊พ�๓ˆ๔�l‡๏dๆง�฿,ำ*�9�ใ��’#rิT~ิ36ฟ.ซฬqๅนM2ื~pิv๗xf@ˆฉAฤ˜ r|rˆ,ˆx-zพ†ฆขฃS}Qฯ๑๚ก2f�•`โตœ—c@@@@@@’Aฤไ๓ฌฃuงqDิ"Ÿ)/ญ=Ÿsขƒ'.ศœต'ไ‰๑;ƒ๐f[J*™ส‰z/]?ู&‹7‡žj๙๑ƒE์~NuD็:aฆ ฃVก|รTZdB@ ถ"ฦถ(็K๊qD�เ€ผ๚๚2m๚ฬคฮศ�!€ € € € € €ฤขAฤXฤไT‘ ดฝ1ป|๘@aปำัSฅd�ี‘ฐ5wๆT’6u ูuไ|ภ–ุ_ิฐ_˜iQ|๐ฤy9`ย{ก4i ณฌ หVด๒มใ็e๕ฎ3ฒi฿ูH‡ฉีO„™^ฮW™tฟZe2‰zง2ษษUฆ โฒญงฏr›@ธv‚ˆืnว‘ษS gฮœRฉBy{๓'O’ฅห–วข]›Vr&,Lถo฿ใsลh Œ € € € € € h"&ฺG—๘�ฯเrR(G;๐MUย็‚T%L|wลˆ@@ ฆc*ศ๑ € € € € € € €@ย DLX�$๕ฺฆฒžถxพ็†lnKแ๓ฆ(฿uƒึฦKeร$ฬ "€ "&‡ศ- € € € € € € €@ฒ ˆ˜ฌ�฿�๊!ๅ%_ึิ~zk๚~ฃฬ่๓ภ�ฝ›�ฅJ™RบvyN?๚ˆdหšี{ณณฎๅ๗‡(sYเ๔EืB๓ฆMไ•พฝญ๏ฉิ>O,ŸN๘R>1ส็v:@@@@@๎N9sIบ๕$Sๆ,กx๚๔i๙๊‹ฯB๕ลว‚ˆw๐ฉkq๖�%r๕๊ต(]U+(4ฌ[ƒ0b”๔8@๎VธD์ี็eนr๙ฒฌ\น\ถn�tทRวูqE4ˆจZ๙ฎi‹ึฒc็ฮ8ู๋หž-ซฌXฦ๖ม�ู็กNฃ•ๅ�๚–คM“Vึฌ['�zพj{ ฎl�ธV’'On†�ัศ12f�'Qพ ‚ˆQฆปๅy7�'(๗p��;aˆZ�๐ฺตk’>]:๗๎fYตพi*ง†ู…Ž๒ๅสสŸ~,‰฿>�โK�dึฯsฃpA@@@@ธำต๊ิ“โ%๒yY‚ˆ‚ˆ>_่๏๔7„hˆ0ข-ม' €ฤธDดŸว๑ใวd�ผ9r๚ิ)ป‹ฯpƒ‚‚œ`Oส”)คขU๑.c†ะUล๗์�+�k๔D *pNูฐWเ�Y๘#ีiฆuบiป5|ฌฉhลฬจ6‚ˆQ•ป๕q‘y7๕™Ž๙<๑๗฿๒ํิไ›ฉ฿ห™3gฬ…ดZbแย…คi“วคษc$QขDฆ�่ัcึฯ„&ั2]๓Œฟตฆc.๊�ุ’eหe๊๗?J‘B…ไฑฦ ๅž|๙œm์ฺ->�ฬYg@@@@@เ๎hา์Iษ—๏3ภ๓��+๋ืญ–šต๋™u‚ˆž็Fัใฃ_ฝCˆI“X• ๋Eผฒก9�ซ’ขUมAaฤ}\œ@๎ฐ@\ "*฿๕เ๋ฒqร:Yณfต�๗฿pw˜5^]ฮD\ถ|ฅt่�-ิ�ืซS[>๖nจ้›*Sม ต{ๆi+”ะ๓ห�…a*ฃีชY]๎ฝวฺ�๛NYณvู7O๎\Rฏnmณ|�๚ ๙bโ$2ช^ญฒ”*YRฎ_–}๛๖หO3g…9ง9่6_4ฬTทNMษ•3‡คณ*น>}F[ำษฮœ�๓-ฯงAงส•*Hม๙%GŽ์r๊ิi9pเ ฬ™๗K˜ใt๚ฺ9rH๏z8ฃัเิ�y๓ๅฦอ›2cๆlำ_ธPAฉXพœYพ|ๅŠLฑย]�MC^ตkื”B ศฝึ.Yกะ={�”ํ�๗9ณ�_ล eอi๔�ฆฯ˜eน=dฦฎ�ฮž=+ปญpเ_}ํ})g]วฅฯ o๎�’&m+pvVŽ9*?L›.วO�ํ์็ฝ๐ฦ๋�ๅฉอMทึ*Wฏใฝ‹hศR•‚๓KซไฑcวDง]ž6}†๓๎ุ๙ "{๐ฉTฑ‚J+"��๓h่์›oฟณ๑๙Yว๒ำ� ไฯo�Ÿฝ{๗ษ–ญ�dลช_}๎owFuฌjTฅF่{o�ฆ•ๆณ฿k๛:๚ฉ๏}ๅJอsฮiฝ›'Ož’�{๖สฏVeมฝ๎s๏j–o�จdส”ั,o�๖{˜ฉั�๏มI๋]ต฿นˆพ›zb ,ฮ๚้งโกพ๏อ[=ใอลฝพ่๓:ไMsบ้็น๓ไ…�/›ฝt[นฒeœ#ฆ|๛}˜gฎ๏jฉ’%ฬ>7n�”ฯฟ�J๔{`รฺ•Nภqํบ๕าบm็<3f”•V๕Q{*yญะz‰าฮv@@@@@๎^G6–ฌูฒษโE ไภ�ฟ$Uชิ๒\ฯฟIE$ˆ˜0aBฉQซŽไฬ•KRฆHin๔สี+rฦšึyใo๋ญ:t๗�|GF1‚PQ�อ฿ข}]ยˆถŸ € ืโbั~F็ฮ“E๓็Y!ฐ�vŸ1 pป ข^๒รaCฅแ�8Wถc๎*�>™;kบำ�ๆก2i๒g]~๚แ[yเ~O…ณอ[ถIณ–ญอv 8Ž1�ูwไ่ฅ{ืNขtทK—‚ไีƒLะษ�ซๅG}$ตkี๐นKppฐ|๙ีdywุaถ๗์�E:ul/๚หO�Mฑ้k๋��yฯ3f ”-ž?ว{ทP๋vฅภพฝ{Iว๖mm๏๗ฐ์ŽชU*ษ7™@˜�็�ิpcฟ�Cรพ๖Šด~ช…ูM+ึอฑย๖บ๛ุ#GJ‡N�ย„�>xจ<า ^o=V&Xม0fฺW[8w–๕[‹yอ& พ๕้ื฿ูMรd๏ผ๕†4จ_ื้s/œฑ’oฟ;ฬ ฬ้6๏ โบ๕ฟI‹ๆM�‡™e 2v่ิ5L TŸลGร฿“โล sŒvจ_/+$งS ป›ฟc๕"Ž�p˜4จLิ๑6iึานn‡gŸ‘็ปwuฆดvEอ?ทยธ๏�ศ�-kW-uช’ฮณ‚พ=^่j{�~}Eรvำw+2๏ฆง•๋ึฎeNก๏K +„จ๗ฆ฿฿U*W’œVุv๛Žฒpแb)fงK›VN�}BŽ?!sfNณ‚ฆiฬฑ=_|ษ„p_้�[žm�ฦ๔้_?พœ0^*U(๏์ำเัวๅŠา?gฆไิ๏๛๏ ๙๙ข;�๐ํืRขx1็8w(ฺ้d@@@@@เฎˆLQ‹B4ma๘oฆ_7๗๑่r๙๒e_›ฆ b >ช่ !ฺC$ŒhK๐‰ €qI .ํ็ดsว๏ฒb้+ฬsั๎ŠŸ ณ%‘ไอ3สใืไ๒๗žฉOcใฦ"Dœ8แซ๚žงขŸŽฑs๗็eัโฅ&จี ขVฏ;๒ร�๒?V(ตzญ๚N ๋Vฝ๚rั*ทk/ฟ:@ฆ�4ำูอ์s:},|4rŒŒ๗Iคย^ท "VฑชใM๘dฌ$HภวีBบดJ]ํ:ฏ มพVฯด๔ฑพ‚`�!ท_๊็L็ญ๐žZืนจkACwm�wrช๛นƒˆฎ�|.juC ยฺMร„ห�bUฝLkw๙��ฑsง4~ขEจm�ŽีD๔~าำะญ๎ฃญฯ‹ฯKงฯ†บพฏ•Y?ฯ5ต[Lีo�๊ๅ&|ซ!ัฆOถ2AฯvmZK฿>ฝœP ŽG฿A;€ช!หz46S4ฟ๛๖`3\;”ชUีึnห|TZ�พi$K–ฬ์๒็พฟค~รวฬฒV=Lš$ฑYถํ์๓่็บ_—I†๔้MำฤปeXF@@@@K 2AฤN]{HJ๋๏ณต]นrYฮY3)] บd�ข|:ษ!ƒ)บ0�ใัr้b`�["Aฤz‡ฃ;„h๓N…/_ป)Wฌ�‡ืR%O(‰Cz oืํ?s๑บ๋ฟ�\ใลำศงฯๆŽั๋� '฿u�Šlฺ$;Ž^‘ WnH‘ษคX๎dR>*๋#7BkAนpู๚‰ฆืH›โ.x๘‘3ป"€��๑!ˆจOเŠ๕L+W.—ญ›7��$‚ฃำbŠงณH๋ฟ n�,—Fเ‘ัฟ�ํ‚ˆ ZตtAจ@’V/ำid�ฉˆ่+ˆจมฃ5kืสC%Š›iš�w๋+็�ฎห:ญ๒�93œP฿ฟ�žท*ชM“ .J…๒eฅ์ร!ำล๊ัOท๋hNก๗1k๚๗ก๎Qo{ฌ)su Yญภfฏ^ป&”๐œGง(ฮœ9“SMNOถk๗ูผeซ�ธqC�}�žผUq�์Ÿ$�}๗šq่ e-XธศLg�ดIc'ฌฅ�FŒ+ฃ?ฏ‹โ|ำ> �i@Lง4ถรZฺฏMงถƒ]๎0—�vเ่ฑใe฿��Rฺบื๖ํž๑`}uูP{ต฿KfU…eสWqข:]ณšุMทฯ˜๕ณ๕ˆWคrล๒NˆMทo�ถ]žฐBoฺ|ทYSRถฆ‰ึชyiญiฃ�ญ\ๅNuศท”fO4q6ซม์9๓ไฆ55๖3OทUeา�EวXีS]ตŠfŸ^=1h ๏ษงž‘�˜> oj`ื�i็*k*ๆ›6‹NmW#ิ~w‹ึmอ6]JQ‹่ปฉก] ๏j๛tย—๒�๐อ˜f�8ี™"ูl๔๚bต�ใฮ?vIฃ&ž)ป�๏uPP/]�9ƒ๗๗�จฑใD+ข�ฎuํ�Qz๕์๎์ฆำŽฟ=๔}g@@@@@ภˆh1y๒ไาล*กMCˆcG…žอ)QยDRฉZ5Yตl™\ฟq=p|Œ” ขปb*„h๋N„ �/›ู—๔๙™.eBy gr�2‡�›%ฉฯ}bบ๓๘น`yhภs™JSส=๒ล๔%cํ�ผ*]' ๗นdM›ุ bๆ’r๗yิ่๘ฅgdเดู5ิ> /")’D2๕๊ ฌ € "_‚ˆzวgฯž‘Y3ฆห้SงBpษBผy๙บ}uJnœธkwโ"=zLFŒkฦขฐำj}•ฌYŠ)œ๑น+๓Eg๑�นฅZญzNจํ๕��ไ้V-๋Ž�t‚ ๛pคณ๎kAซปฝ1๐5gบแ๏~˜fยt๖พ+ญ@eถฌYอ๊I๋=ชXี3ํ›ึ1-Ÿlf๏&“งL•Aƒ฿vึjชเžฝ๚ศ�_˜ํูณe•K<หฺกำ�์s็X]/ˆ่==ต;ศฅว•ณ‚“_}๑ฉs?p+Wฉบn D๔ฎz8ํปoคุƒ˜}๕‹V ิ๐›ถญึ8ฯtรฦM&๘f6X_:ถok#๏3ซ{��S>๛|ขฝษ|N?Vt*imธlึ2ค๚ไœ™?Jมฬ6�โvา๕Ÿg�(… zถ_ฟ~]J—ซlžทwqฎ5อดN๓kท™ำพ“ขE �ซฆ"ขE๕y�ถf… =u๊ดTจZำูOƒฉ ๆ†Tฝt7:ฦชAฤGŒ’กC�t‚ชฌ฿ถlc\5Hi7๏ะ่ำ~’W^hoผGืฮฮ๚ยEKคKฬบ๒ำ•ˆNอlŸ("๏ฆ๛�ฎำ ‘ O:D7jhNฃ๏�๋ะ n{kji;เ๊"N�๊s)[ฆด\ฝzUx่asœ๗=uฺ๊S/]fถ้ิ�M›x* j๐ฒVฝGยLทm฿ƒ�๙Hƒ๚2�ฝทpคNใ�Xำaฆท๗็@@@@@เ๎ˆh1Sฆ,ึ฿ป?knๆฬ™32๑๓O๏๎๓ct�ภ๓uhTCˆ็ญ '?ฯ_bN๙H�’&u*_งw๚b:ŒX๛ฝฟd๛แหฮ๕nต ๒4ส*]keบีn‘�ถa�%i2๒ 9ฎฯ�2Kฺ™รœ#พต b๕w๖YีEย„้˜ฺ-ฏT+|๋๗ว>h�’ำ2pบgช5ป/"Ÿ๛†‘”I "FฤŠ}@n/‚ˆืƒฏหฦ ๋d๕ชU�›Lw[Q฿0w๑voœV๙๋๛สkฆส๎AD{ZW{ eJ—’)“พฐWญส†ำE+ฺEถiEวดiาHฦŒค{ืN&\ฉ็ะj‰ฅหW6ง๛ส๚CซVLิฆี�*Tฉ้"ตOo;ด“ึ�ด}b /^บd–#๖ /ˆุญ๓s๒Bฯnๆ<๚Eรwยsทฯฦ‘jU=ใิ�‡สT0ื๖ทนซ�้~�Aฐ>�๚‹ksO‹ซ๋ะำ)ืฎ[o*:j_xอb๔ฎdทmใZัซถ-[ทIำญCFง์ญWว�ผh๖>™เyพ�ADwhRO๐|ฎาฝK'็\๚NŸ1หชœYLพŸ๒ตำฏฝ+๋;าฉD่*FืXฏ] –$�M%ฌแธป‡ ฟ๊เพœ0�Tvิe�ฟฒUEQ�ฒฤ��Cญ6ชUGตน๛c"ˆh�ปC„?N,ล‹=hฎoWIิ๗๔า๎ โ๛C฿’วyฆ ทซUjศEฟ�์45��๕7ฬ95ธซ฿7ฺ|ฝ'fƒ๋Kอ๊ีdิˆแf๚hป{เ›Cไ›oฟณW๙D@@@@0ˆ๕ถ^่�ื�}ณ�r๛พ?๗สบ5ซๅ๘๑cvวท.Aฤ�Ej)?ฮญ ก-i’$าฐ^ ษd�ƒแํฺฦ-ฟห†-�อnฅK<(ฅJ„T�๏X๏0ข†[4๑T}๏˜ˆ๖ปƒˆ:ๅq๖t‰CฯYS๙๎=~Uถ Œ›�3ฏT(ฑœsฒ[,,��‚ดศ์ักjFyซiถ0{ว‡ โีเ›R๒๕=r๚‚ง�j๎ŒIdp“lRฉ`*+ศpS๏ธ /w�Lำฌ@ฉ’%”ํoŠPลยญ/หค_� ใ๊�l]gสš�}XD’$"ˆ่ํฤ: €@ิโz๑๐กCฒxั�€ฏ‚จO๗n !๊ธ"DิŠ…�_่*dAD_!<๗ุ"Dิะ`k ืช•+YAษ�NHL๏ี��Aฤ% ๆH๎\นฬfฺท๑-�ป�rูŸ ขป๒œ^ฤqน/ุณ›U-ฏ[Hตผ–Oท“฿6l Sั(ฺว–/WV&Yีํๆ"~4�]ั sพš>็ฅหWศฤI“CU๕ำ}ตขVDด[“ๆO9๛x;Lš;ˆุไฑF๒๎�ƒ�ˆ,ผฟ„ มนซXFuฌ�ื๓ฎไho_<Žh0O›Nืฌ•ฝ›; ซำe+Uฮ์ำAD rj Sƒ‘๚�i[ฑxพdฯ๎๙๓ฃปชeญšีe�hฯ”๎ โฤ ŸHล ๅฬtไ…,iฮก_พŸ2ษLณฎหZmตZํ๚fฺ็ู?� ]ฆ้ิส:ลrxอ„?&I“†ฬ"๐๑๘ฯไซ% @@@@@ p"D|ผi3น็ฯlN๖๋ฬK็ฯŸ—•ห—ศž�ปํ๎€�$ˆอ๏ำฏฆ:glาฐn„Bˆz@T‚ˆzœ†งอฉ8าฑอ“ฺํws—ฝzŸฮž,ฬ9Ož–ๆcษฮ#žส‰R%’๏ ณ_T;"zไfn๚Wž๛โˆYษ™!‰ฌ}�๚วhฏเ฿�›ฐโ๕žc&wฮ#ต๎OU๚0ว ›{R†อ=e๚๋K-_vฬf:@ˆช@\ "^ฑ‚8+W.—ญ›7E•ๆฎ:๎n !*’;์,‹–,5v%ŠsยHฺ๑ห‚…า�๙�f›�%:ƒˆํ;u•ๅ+Vูง6Ÿ๎ชu "jq–rฒC_กNๆตโ"ฎ๛u™3ๅฌVี{ฒี3^{‡ฟ๊ภ‹ฬิฬ๊าp—�4$็�žm�F^้โnOq๋]ั๛ุR%’ฉ“':งsีIงวmPฟฎณ�{A฿…ƒ‹N#l7๗5�ีu{แBล0‹ศTฺ๖y�AD๎ธŠU1ะ�ผ+ฺADo๗1แ-kุ.KๆLั2V๏khUมญ�:แL{ป๛� /่:nฬHฉUฃš}ˆุฯ3ฆƒˆŸ๚ฑฉชaSคX)s}๗Tุ:บ>Kmฯตo'/๕~ม,ปƒˆฟ._d™f–ฟOž”Jีj›ํ๚ฅ]›ึ๒jฟ)ถ>ึT๊ีญํLCญ๏X™๒Uœ๊ขฮ�-TฏZEF[•“% ๙๓๔W_#ƒ฿~ื{Wึ@@@@@L 2ADฝต’ฅสH๙Š•œ™™�ท{�฿ๅหฯ?“เเk๎๎€[&ˆอฬDŒL(0ชAD~Tฏyซ[HQ?w้†<ุท\ป~ำœne��R [RS)๑๔ล๋ฆ/Yโ’&yBณ์๋หๅk7j~้R$”`+Lw๑ส Yบ๓‚tŸtิ๒dนt2 ฑงขE๒$ $ตU๕O[x5ทv฿E9r&XŠ็I.…ฌ ฅN!‘v�ช๘๘�� ๙๛\ฐ<”ฯ:6�ญฝ`U๏ม๛>ตฺเ๏G/Kัœษไ�œษ%ฉๅ•ึ้ห#2cใฟๆะ1O็”'N็๓4'‘Ÿ6x๖๋Y'ณผ๚hŸ๛EถS๏ญ๐หปไŠU™Q�oƒ ˆVeค!€ ]q1ˆธื๚ญฅล ็[แOฅ์่ฒЉ๓$o–IfO,—ฟ;#7N๘�รอ�BTwqู๒•ึิฒžฉ‚5Xฆค„ =�ํจำ27jา<ิิฝ�AD_•สึฏ^.้ำy�l๓–mาฌฅgบ�:ตkสุ‘:%:‚ˆ๎ฉc๕ฤ6\ฝvญl�๖ป�k�V\[+u฿ฝ๗่ฆPS3ปƒW‡‘šu�g๖‰ศ‚ˆ๎`Ÿ^K+ๅiล๗์ุโฌ{Oตํl๐ฑี bƒzudไ‡รœ3.Yถ\~ž3ฯY๗^ะ เ�_˜๎่ซ๗๙u�เมCๆ๛ฤžบ[๛�๏—wXOทksO‡์ฎN่"j%Lญˆ้n�Swป฿ƒˆผ›o$อžx�œาฎpฉแฟzu<ย={๗Jฯ^/Y “ษ๐w‡H๙อพ๖ปแ~ฯ�??t' ผฎ_ฝยฉJ:bิXkš๑*ฆฃn_ตz่4�พšฏโ—_M–!C฿๓ต;} € € € € €&ู ข}{™2e‘b%ŠKแยE%eช™g��ปGf�4อ�- ? "F๓c‹j(0Pƒˆสืdไ๙u๏%#9ขUNัะเฎcWคฺ;๛L_บ” eืะยfูื—ๆcศ๒]žใ?h™Cฆ�vNV๎๑ฌ๛ฺ?_fญ Xภl๒"Ži“Kš9({N\ 5mด†?|*ง4)“ึื)MŸ†�zO9ๆ„"ํ5ภX๎พ”2ัชจ๗โ�ชพฝOvฟbฆD�๕nay๊ใฒสฟ]ะ�ฟcตŒ2่๑l’(์)์]|~.ฐฆจ�vุSu๒น๊ฆ๗ฮ}พ=&_�7อrŸ™ฅOƒ่ "พ3๋คŒXเฉ†จำt�!ท๗ฅYG@ภ/ธD‘Šส9ืณ…ผ๋�\{๋�!!5wั{Š฿Z•!ป›๊„j0๊ฃaRคp!็ผ:uณNแฌอ;์ฅSึ>๓lGั๐ž�ย "zWผdๅ^์�O-^j}๏ทไ๑ฦฺง1S�jี:mQ "๊tฬ#?x฿9็ื฿|+oผ๕ŽณฎมRฝgm7ญ�P.๙pEt‡&5DXบ\ๅ0S๊zO/ฌ Ÿ๋ารœซ�รeไ“GKส”)ฬ๚…‹อนu%ชAD=ึ]1Pวีน�๓ฒt๙ �dฆ่�fา—ๆ้บ>ืฺ <žั9Vฝ7 #บฟO "“ง|ง— 3Eฑ๛�ส˜1ฃL?F|เ~ณฏ~๙bโ$y๛]Oฅวพ�:ิ๗N•=�ำฯอปฉำk7m๒˜sœ.�*ˆ่๋�ิๆยyณMๅSญฤXณ๎#ๆน~4�]yคA�P็V฿ๅ+WIjUC๕๋สไ)Seะเทร๔๋๛ซ๏ฑw ’โฅห{w›๐ฒVJuOวP�้ŠAฤฦฐฆA๖T0ี:ง4+๋™ถnศฬ“2jกง’^ซŠ้ex‹ahgm>/??l๚+L)?๔ศ'ปฌ๊‚‡N_“ต9วkจฎฃU P[ึ4‰ฅx^OจัD4ญ/ญฉ”ŸซžA๒[SD๏=qU�™}Rฮบฆ‰�รชZจกAป}ต๊ฌ๔z�^•ช…SสใฅำI๖๔Idรพ ณ่”Yำkำ)ฆwZีปชฺAD๛z๎ญŠ„ๅM)'� –ฑ‹Oห๖�*๊>๓๛�๋Œ฿>ฦŸO:นซ5-๓œญž ฅปbค?็ีcN�[ฦ/9mNำฐD๙ฌ=ี�5ๅx@ฐq!ˆ˜5[v๙๛DศO„ฝหปปวWQGœโ้,’ EBนy๙บ}u*LตฤปๅฎnDิ1z‡แ~฿ฑSkฺย��™ำœ้Zฮpb:ˆ8เี—ฅMkOPO‡ Aบ  หึดฒIB…ฤt›;ˆจ๋‹~๙Y๒ๆ ๙๏5Š๚ย…‹’6m�์ดฃGIตฺกZฟo^o]#ฉณ.hฑY‹Vๆ3ผ ข๎๗�ะทไฑFžpœฎkำq_นrE’'๗�wป�๗T›gEง็ีี ขwpRฯฅ•๊๔พ Yำq๋vปํ�๛ง4hิฤฌบร‚[ทm—'žle๏ๆ|j€qŽ๕>$I\ี*~มื‚ขฝณ{jg๗นีญJ*œบฟVค�~สื๖กา๗•ืd๚ŒYfฝ๕S-Œ…ฝQํvํ�c…cZี๗๎ ๕��ฃ{ฌ=ปw‘];�รห—/›๊ :m๎€งฎ๋๛ฅ�ืๆ0ž9{Vjึ๙Ÿ๒งZาdIฅt™ฒft—.]’-Vัปm�บE.^ผ`V๓ๆฝG?ัT8 ห–.ถf>๒ไptŠๆ4”,�อ๒t่เ๙แปoํSไ'Aฤh~l๑-ˆx๔Ÿ`yxะgb2Yƒpฺ�!ม๐ฆgvOห�uง๙ใ่ำๅ==ณ{Zfญ"๘ื๐"๎C%ฒADซ`ˆ์ฒชjะป ๘๑„|บ์Œ้v‡ ฟ]๓ผ๐อ1ำ๏ž๒ู๛๘ล;.สSใšn๏Pฅป"bxS?/ฺqAZYVฺj�Ÿฺ„อJพด{P–�q1ฬ‘฿›R>๏KฒX#ฃฃ๕�แ„LX๎1{๔ก4๒้ณ!ีuขใ�œ@[€ ข-๛Ÿ๎0ขŽๆnฏ„h‹m\ปา ฿-[พาš’ธ›ฝษ๙|ใ๕�๒T‹ๆฮบ{ส]ํl�จกผ๚rษ˜!ƒณฯ‘ฃGๅ๓/'I™R%าโฅหคSืžfŸR%’ฉ“':๛�ำ(;ึย๚ีหญ฿Œ๓T Ÿ4yŠผ9dจ{ณฯๅb> ƒผ*ล‹=h* j9�ฟญ?xฮœ5G‚.9U๋N��ทTฎบ๒ž฿zc ”}ธดžิ‹่jWฎZ-๏ �ะ ฝ/ฌAฐ๎V5ผG6l��ๆ†�gUิjƒ๎ฉŸตาแƒ%=ฟแ็>ฯ+}{หใ5’ ้=ฟ จ�4ศน฿šNxจ@ดงถัชt/๔๔<+ H+2%ต๎ฃำ>ฯš�ฝ™Ž@ืฝƒ_:ี๒3V๕ศ|๙๒๊fง้ฝ.Yบ\FŽ';v๎4�•*”7S�;5kฺู (ฺ}๎ฯ2ฅK™ d�๗…ช๖งกิ๏�I�ท�@๗ร:ีn�ง s/�Ÿ๏-Z™ฯ�ฺถi%žm๋๘��NŸ>#Sฟ�Q>้{:†ศŽีช๓ซ†็ฬ๘Q2e๒Tฃื1่ดื:�ต6��๖›อ๔แv8W๛๕ะ ไk›)—ตฯ�๔V#}ฆv;w๎_™ฟp‘๕Œ�p*B๚zn๗nฺ็ำ๏o�>ท�ู�‘Qึ;ฐbๅฏaฦค฿'๎ฉวํcย๛ฌYฝš5ฦHgณžปlลjฮบ{a๋†5กBฯ๎mพ–{๔๊ใ3ะ่k_๚@@@@@bW K7+ˆ˜"๙mฑp�/ฒmซ'ˆจ•›>๙ค๕๏6)๓pŸเ�…๓ฒ`�\9ฐ�/ww@.DŒๆวี โykสดูฟ,1ฃiXฏ†คIํฉิ‘แE๕šท:wํ๗�rฆึ€[ฆิ!แพƒnศ~ซŸ@ดฯณ๘ๅ{ๅ�\กฟูพ^๕๔™๊ ๚yOฯ์ž–๙ษr้dDซœ๖ฉฬgdƒˆทš’xŠ8์๕_เ๐9kŠ็7›xช+œvBฦ/๕„ํดโขV^ ฏ์ปKดJ ๕๏ภrlDQg7w1ผชZ9ฒิ๋ž)อŠ็I.๓_บื9>ฒ =พ>*ำ~;gณซบฯัฏayกnHลF๗ถˆ.๋3.๚Šงข�๏&ซขMi €ฤ„Aฤ˜P๚9ํ0ขžแnžŽ9๊wx๋#๓ไฮ%:ๅํžฝ{#Tบ๕YฃถUXiาx*†G&4e_M๏C๏GCŒ๖๔บ๖ถ�}๊ต�Aป�ํ๏�ฎaตŒา› คwๅE๗~ัตฌืห•3‡ |;~�'ฝฯ�jฟ—ค]›ึฆ[ง.Wฉบ๗.แฎkตฝ ้ำษมC‡ไะแ#แ๎]ิพhั"’(aB9p๐`ค�ร;9V}ทRZcฝrๅj˜ _x๚ฌ , gญgูwา>็ญ�อ&Vv@�~NๅK๛^๛จ,ึ)ถ3Z!K ฟ;์๙์๓‰๖.|"€ € € € € ฃ‰&’� Jฆฬ™%E๒r๚๔i9l��ร้ำ]ัFัญ ห1 ผ�ฐbโš๎ โํฎŸ$Qี:งสU?ใท‚ € € € € €@ด DŒ6Jฯ‰ข 5๎ ,�แฉส๘}๗|RฅP๘ซพฝOvฟbฦ๙� ’� bjป[‚ˆ:–|/�!Wฌ*”ฺถ )(YาD~:ๅž“สwk=S?7*•V>iK5Dส@ ˆcดœ,ส๗ญ7_7AAA2ไ๗  ๑f € € € € € €ั,@1šA�กภ& ๋JฆŒ›wสณๅยEO .M๊TาขIร์๔™ณ2m๖|g฿Žmžt–�Yˆฮ ขŽฃภKปไย•ฆrโฎก…ล=%๒ฮw I†T‰ย ๗NM�[ฦ-9mฎ=่๑ฌานFฆ0ใฐ;์{H@ไุˆ)˜c:ˆจUฏ]Sฒuฅ๔๖p|~–ดWŸฑvถฺ๔žyฅBT>๗ ฏ๓ไ๙`)�ฺช!†D? €@ŒDŒVNŠ € € € € € €�1‚ˆัLํ&MšDึญก0โฤ)ำไชฆอฌ–:U*i๙ฤํƒˆBœ=‰\ฝนใ"rหัD|ๅ๛ใ๒ลŠณๆา๓๚�#|ฐ฿Lห\‡ไ">Z2ญ|ฺ.W˜��š๙ว๕็ค�คฃๆผYำ&–ญo s ํ˜ต๙ผt��Sม1S๊D๒๛�…œ�b:ˆxo๏?$ฺ่M3M๒_รŠH๒$VาGsOwญ›o7ีดSH็‰Gไง �šM•N+ใž k๎๋8๚@๐G€ ข?z‹ € € € € € €ฤพAฤh~&๘‹�/Tั0ขNอผl•gjๆj•n?5ณw1i+๔X/bกวˆ�rtœบ&ๅ��k./sัumฃZ็”feำ™e๏/๋๖]’Fyฆt๖�ู๛๚D พ!RไeOตF=gฯ:™ๅีGCOญkฝทOฮ]ฒvถฺ€ฦYฅ[ญส‰1Dl2๒€�บ๗’นvขฉdJ—ผfู๛หs_‘™=!BoฏoV�#ใ–ž‘*S™๑๛ 3ชeษืCช!n\P4œIC@ ฆ"ฦด0็G@@@@@@bV€ b ๘F5ŒักฤtQว�AD=g…มส_'ฏ๊ขi‰Š๘ จ$ถ>}ตƒnH!+$hท"9“I๓‡ำIั\ษฅFฯ”ร�๕�๎ชˆบฎUY3ZำEo?|Y&�๚\ป~S7‰�ถ)dชš๋KLWํน$OŒ๒2๕šy2&‘~d‘2๗ฆ”„–�ๆƒ—ๅ�Ÿ�–ฝ'Bl‡6ฯ.m+{ฆ?x๚š”}รีใฝƒ”ฺงญร„ร2{หyณ�x™ด๒qช! พ €ฤธAฤ'ๆ € € € € € € €@Œ DŒ!�˜ #�‰ข’ฤDq�’ำ2h๚฿Žx�bฉๅหŽyœu_ ๎qุ�5ˆท~PณAD=QŸoษืVเ๐V-M๒„2ญG>)f�-ฆƒˆzญ๑–�@—๛๚�หฯVษ o7ห๎t/๙ใขด{ะYo^.Œl•ำYืญ๚Xf'ฌ˜ภš๙Yงจฮ’†jˆกXAˆ1‚ˆ1Fห‰@@@@@@@;"@1™ฃ;ŒxงBˆJา`ุ~ูt0ศ่�: ฟ�—%ฉ฿Rฎ�/…T8œ๙B>){_ส[ž๗ไ๙`y{ึI๙a�9ง*กNํผ๖uO๑ิ…๋๒เซปอ9ชN%Sป๙žถุฦ๋\#“ zฝ& 7บ[ฒฤ ค๖ฉeดU!0E+ฅ็ีชพณOvปbช$QิkซgUง€ฮ�ยNณR2o ™�็Ÿ๛�ชsล๎Kาw๊ฑPU%�๛็ฬDFXร*…ยšึx๗/ูyไฒคJ–Pๆฟtฏไฯ๚y๖ด๎๛ปต็ฬ้šZU'G?:จ่พห €DทAฤ่ๅ| € € € € € € €ภ ˆร�ัFผ“!ฤ˜"qW�K—2ก์Z8ย—บn๙4”x5๘ฆdO—X’Zแภ˜jzญVh๏kj่ขึtะ™ญ้˜๏ฆฆS0�no๗qฯTฬ*|0w2)”=ู-‡yๆโu3�๔-wb# €ฑ @1ะน$ € € € € € € ฃ3ผS๙FŒ !DตybิYต็’a๊S?‹๔๙_ๆ๐ศ่G@x$@1=ln@@@@@@โคAฤ;๔XฝรˆQฝlา$Iคaฝ’)c†จžโŽw้๊M9z๖š|ฑโฌLX~ฦ\;QB‘=๏‘”IcฎชแฝI.† €~ D๔‹ƒ@@@@@@@X ˆxฟaฤ@ !*mฉ{Mัอ�ฦใYฅSL๎.–@@  DŒวŸ[G@@@@@@8!@๑?F #ฮ_ฒJ.\ผฉ+งN•J๊ึจ0•ํ›+9`;lVXŸซ–Q�h’อ�ฬ' € y @@@@@@@ภ ˆุฯ๏ฎ�ขไไฟม’-})•7…คKiอหLC@\],"€ฐ#)—@IDAT € € € € € €(@1CF@โ’Aฤธ๔4น@@@@@@ˆใใS็ž@@ปH€ โ]๔0  € € € € € € ‚ˆQ@ใ@@่ ˆ}–œ @@@@@@ˆ ‚ˆฑกฮ5@@‚ˆ  € € € € € € €@@ D ศวฦ @@ธ#@1๎Y่D@ธSq!ˆ๘hฃวe๑ย๙r๑าล;ลฦu\;ถl$Iปz|/j`g๐กฒv�oพwˆวฝศKฺๆœ๖ำ ัสq๎๖ษวฃคFตชNW�๖dี๊5ฮz .|9aผTชP� �ท ฅๅำํ๎๘mdฯ–Uบv~ฮ\๗ๆอ›๒�ฐญŸ#—๎๘8๕‚ฬซ]ณ†พ†๒>9:ฬญ�ถz…คK—ึ๔bฑ@�๛คSวgฅNํZ’*eส0๗ง๚๎hะzเ›CL0ั็N~t๊u฿xฝฟ4nิ0ิY†4Jฦ}๒Yจ>V@@@@@ธ,๐`ฑโRปn}I A˜�ผqใ†ฬ=Sv๏�f[|้ ˆ_ž4๗‰ €�ฅq!ˆุซฯหrๅ๒eYนrนl�ผ้.•ŽปรŠhQด๒]ำญฉโๅz4 ทbษงgุ#d�gŸ;๋บPฆt)y่[’6MZYณnt๋๙bจํธฒmใZIž<น๚G#วศ˜qŸ�๑�xฒู๒ึฏ;ืmา�ฉ;V�ฮนh/|๐�Py๔‘ๆ.\ธ %หV s7D|บUKyนO/I–,Yจ๛:w๎_Il…ฏฝƒ‰๚[ทSฟŸ&๏พ@ซ�ฝŸ;WฎPcะ‚ˆaH่@@@@@8,*Ujุ้นซB<|่>tP๒�sไศ้๙;T #Ž๕‘๕๏QืโฐD๘ทF1|ถ € €�ธDดฉŽ?&๓็อ‘ำงNู]|ฦฐ€;ˆจำ•๊tกฺRฆL!ญŠw3d5‚={๗ส�=ช/>ฏD$ˆื|tšinฺn k#•ไ์๓‡๗I1<™ˆ๕วๅ โKฝ_็ฺ‡T้�ฑsง|�อTัชŽvห˜1ฃ๐ุ้ก”-2ต๘ข%หคsทž๖nQ�ิ ไซ/๗‘ฤ‰}Wœ%ˆeZD@@@@h๐ศฃRค่�fไ๛๗�%ำ๘ฮน‹ถํ;J† อ๚ๆdษโ…ฮถ๘ด@1>=m๎@ธ โZQ‰ฏ_—ึษš5ซ%8ž�ฦำ|ี�AฤeหWJ‡ฮ�B]พ^ฺ๒แฐwCM฿�P™ ฮธํžyZ%JhŽ๙e�B9t๘Hจใkีฌ.๗�“ฯ๔m�}งฌYปฮ,็ษK๊ีญm–ฏ_ฟ!_Lœ$๗ไห'ีซU–R%Kส๕๋มฒo฿~๙iๆฌ0็4�ๆห�E‹J�:5%Wฮึิฒ้ไ๔้3rุ�ฬู?฿๒|:†ส•*Hม๙%GŽ์r๊ิi9pเ ฬ™๗K˜ใ?๚ˆตO้�Bg4K–-—น๓ๆห kบื3g›�ย… Jล๒ๅฬ๒ๅ+Wdสิ๏�ํญฮVปvM)Tฐ€�kแ’ �ณ๗Oูพ�wŸำ8๋�UฌPึฎ๗6}ฦ,หํ!3v�v๖์Yk๚‚=๒ลW_�—๓ฉใาg7wnI“6œ9sVŽ9*?L›.วO�fปCง™}ชEsณzโ๏ฟฅr๕:๖&๓ฉฏฆ7–ผy๓H–,™ๅ�๙ r�๘qYผtน™7ิฮฎ�^ว•5k9z๔˜�ฑkท,Xดฤ�gO=ต*•คZีส๒Hƒ๚N�'พฝ–™N3ผt๙ ำ�xใG%S&ฯ_^l�๖{˜ฉล�Ž'ญgm?3=ธŽ๕<๒Y๗ อ~wu�*•+JV๋พ‚ฌJฎzฮ_๘�"ญŸjaU˜๔T๎ณฟt๊๋Šห[฿{IไŸ�‘ 6…ฟพ3-[43ใำ/พ๎O๛;<๛Œ~˜ฆ๛�s๎œ�_ดˆ่๗nั"…ํMา๗•ืฬ๒ฎ�{ชงพ*"๊”ฮๅห–ตžon๓พ�ถq“,Xธุ9๗Bd฿m6่ฯœญ฿˜ตง๖Xดxฉt๎�ผ๗ฐBญ๋ดษ^yู™†Zงi�ๆ[ฯ_‚้ฯภ-[o�ะก0วZAฤ@{bŒ@ˆcq1ˆh?ขsVXfั�yVlฟ�ลg �.ˆจ—๔ิ<�ฑ‹ฌX๕ซศŸฬRa์อ!Cร„t~๚แ[yเ�ขfไ›ทl“f-[›e ๗Œ1�,๋—‘ฃ?–๎];9ะด7\บ$ฏd‚=v฿ํ>5„TปV Ÿป้๔ซ_~5Y�๖A˜ํ=ปw‘N�KR+๘ๅ�ฎ^ป&_[คw�๓ŒYรR‹็ฯ๑�-ิบ])ฐo๏^าฑ}[g[ม๛K8หบ มฎ!oญฎ่ซiธฑ_�กยx_{E4ผฆMCzsฌ๐ฃฝ๎>ว‘ฃGฅCงnฒ๗ฯ}๎nัjx4จฦ[wRฃ _~%:อดฏถp๎,ษ—/ฏูคมฝ>�๚;ปi่ญgท.’"E งฯฝ ๏พ?�Mซื=฿ฃซ$Mšิ{“่Tบƒ฿*3f�lถตjู\ นฆ๗ด{ธBUำฝvีRงช็<+(�ใ…�กv๏฿ฏฏดmำส้s?›™ำพs‚z ญ0ไE๋/?4|๊�ดฺ^งฎ=o�๔>ฦ{}ฯŽ-NืจฑใDฟ?4”๊�ิ ฯหฏš๎๒ๅสสค/>uvูธiณ<ู*$tจ๔�š0~ฌณ>/5nPฟฎำ็ฝเฎ่"jติ๛๎ฝว๙~vทlyุณnสปํ๏ฯ†UหZAั,fx๎๗MƒฅK•4SŠฏ[�› ซjุ4a‚„&xYฤ eŽต�๒K›��ฉ๗H#๓Lœ:YŠ{ะ๔๋—: ษ�œu]ุดn•คNฺ๔ixนBีšฮฯอณVˆtภภมrาช๔;u๒D็8‚ˆ  € € € € ว'Nb���‹ๆ.ฝƒ†ฯ<�Qดป}8์]๗ช) ัดE+Iœ(Qจ~๗สวฃGศeซ€@ 7‚ˆ�๔; € โrั~<;w�.+–j่ข�'>fK"ษ›g”วฏษๅ๏Cชฝ�้›‹Hqโ„Oฌ๊{žŠ~:>ญ.ฆUฦ� "jศ��๎ž5XVฝV}ง ใญ๖ืฉPตา�ํฺหฏi?อtvs๛œN #cฦ}"ัDฌRฉขL๘dฌSฝอว%M—Veฌ�เQgsDวซh่ชี3ํ#}ฌ@�Sู๊ ผ๏๛ล—๚9ำy7จWGF|๐�m๏ล;ผุงWOuฮBืžฝLๅฝุ"†3$ง๛๐‘#Rฃฮ�œ๕ศ.ธƒˆท;v๖œนาซO?ณ�สฅ $[VO€UคeสW ๕}ขM๕ฒ›&ณช�E%ˆhŸ#ผO๏`]T฿m~6่;8๒รafˆ›ทlต‚ฯžŸ๎iจํ๑c�›€�[`Žœนฬ>3ฆ�(๛๖ํ5หษ“'ท๖{�,kq์จะณ9%J˜H*Uซ&ซ–-“๋7ฎ›�๕ Aฤ;๘ไ4„8{�นz๕Z”ฎš4iiXทaฤ(้q €�ญ๑%ˆจ�gฯž‘Y3ฆหikzห@n๎โอหื%่ซSrใDิ�7:�AฤฃGษˆัži\๕vZ้ซRล๒กฆูตร`zmwhGื#35ณwุHง฿ญVซžSอํ๕��ไ้V-๕ดฆ�t‚ ๛pคฝ๊๓3•๕�po |อ™nX+“i˜ฮn๎๊q:Mjลชžแ›ึ1-Ÿlf๏&“งL•Aƒ฿vึตฒY‹ๆM๕žฝ๚ศ�_˜u าญXโYึ๏jiฺ^ั{ ฺ์’FMBชื•ณ‚“_YS๏&L˜PO#gฮž•r•ช›e๏๐“wีรi฿}*คืถ}'Yตz9v๋†5ฮ3�ฐq“ดh�ึ๔๋ญ�–�>O่m๏ŸสgŸ‡L%ซ�uš_nW›ปโœฎO™๔…”)]Jอ๔ฮE‹—6ห๚ฅf๕jRทŽว๛ส•+2๐อ!f›๗sึฉฏ?ทฆ…ถ›N฿ญNvณงื๕'›=!oฝ๑บฝIš4Jถm��Yื…่ "zO?�Bฯnาญ๓sฮ๕ผŸŸณ! �ADช\งhถ�—ฦ‹N-l7;$งกฬ?†„็ZSt๗|ัี`๎‚น!U?ํฐ}w•ภ .Hษฒž็joืO๏ ข;lฉฝ•ึปo‡5˜j?s�m~6ฬ9M ศ/'��[*WฏcnEงPืJžฺ4(�ีื฿HแBญ0ks'|์ถูพi ฦฎ๛mƒดj๓ฌ9Nงภถƒงืฎ[S‡TžTcตึฆSกWฏ�ภ,{!ˆ่-ย: € € € €ฤJUซIูฒžฟใ�ใ2w๖,iฺผ…ไษ›ฯv๘�ณqRปv}น็ฟŸXnอ”ถแ7ฯฟ๏dส”Eฺด๓�]ํ™3gdโ็ŸฦY6‚ˆw่ั๚Bด‡Iั–เ@โŠ@|"^พ.7ฌ“ีซV�o2�m!D�>po๗}กU�๚พ๒šฬ˜๕ณู5:ƒˆ�ำ๕j Mƒmvำ)‚ต*bd›†ฅาZ•๘2Zีัปwํdย•zญ–Xบ|esบฏฌ?ดj…8mAAARกJM'ฉ}p์ุก$ฐ�งํkZVญ๊งอŸ ข†ุ4ฬf7 iฬ�>7FชU๕ŒS๛ต’ ^�;ˆ่]1ฒg๗.าฃkg็T}๚๕wช�ูA+{ฃ g�ษž#ง$O‘\.^ผ Ÿ|<ฦX4{๒)ษ'Yž3{ฆ์๚cงc๔xำfrฯ=๗9๋บ ด@ภสๅKdฯ๎�กถ๊ Aฤ~r�†ํแFด%๘D@ธ&WƒˆW._–•+—หึอ›โฤ#ป[CˆŠ๋๛้ิช‹–,5ๆ%Š“์ูณ™e�โœาพ่ "บ+•้นตm�ธึ �D$ˆจaกY?�เLร๊9‹๏ฏ๎ โบ_—I†๔้อŽ7m–'[=ใ๛ ฝ�ว!ตjVwฮ๊IูZ ๐•พ!ตN]{สโฅหยTD๔>ึ;๔ไ"ชำ;oฝ! ๊‡ฆูืิO} ,?L๛ษ้v‡O:-ชึtถู Š๋ิแYIš4ฉ�ๆSฯ๙สkž๊r๋W/—๔้า…ู'ผ๗{p'ƒˆ์ฺ->�,ฬฐ�{็-yผ๑ฃN•uไ๘‰ฟลŸ ข๗ิเ๖ษ�กMFฝš5M…6}—/ž๏TK�bโ$1jฌฌ_ฝย โ~๙ีd2๔=๛Tๆ3ฒAฤŸ็ฮ“zฟ๊�•ํ ข?๏ถw12?�ฯ�}ภGQต{่zG�D)""ฝ‰คซ Rล†ๅล‹‚ ขb”"าQTค(U:Rค7้%๔žPธ๓ฬ2ร์ฆ’dษ๎ๆ7๗๓&3gฮฬœ๙žลฯ…�๓œ๋VšL7m�"อ[ปB†V8Q๎ ฯ~?lˆิฎ้ชZiหY๋๒๋บ ปต �ตุ่tำๅ?๔]K6๏ฺฝGžhโ ‡Zื8ฟ{�™�๒›!2�๛œ]ุG@@@@R `กยvD ฆH‘BดบแOฦษ‰วอwnำ๎ษ•�๕sฉ๑cGE(Rขaฦ‡ฉf��ศ u๑ย;๚ใgือ~ทOั‹S–P!Dkˆ„- พ#€ €@ bq๑[K ฬ3–Ÿฝ์๓S•ถevIž'ฅ\๙๕Œ�8๙_n|9„จภฮ ขณโYษลeฦิ_ํ%MuYๆฦอZน-�๋D6โ๙jะทysอœฦโ6r{€ใ ว[ฏ›!8ซIร†+Wฏ–อ›ทสใทโ^h฿VŠ.džv๕=K—*iถGถ,ฎy"Š/๑ ":ƒ}z๛๚ห��žค!D็าฤVล5ฯk๏$ˆh=@—•}โ๑FRูX๛�๛หF:—๙ีkœKฯ๚sถผูใ}๋Vn฿5ุ่๘ฉ'คชQ•Q๏›/o^ท๓z U'ต๚ไฬi“ฅTษ๖y L�๚`{๎�ปi‹mtงAฤu�ฌญ(้�<—พv::?gฯ“‡ฉ้ผิ�;j„Tซ๊ZฎX�๑คT9WB yชkT›V\บl…}ฺ–๛หXถนKท�K*[�]ทJ‚‚า™‡บœvหg�Yงd๒ค ๒@๙๛อใ={�“แ#Gษภฯ๚�็-oปมุ๑fั๓๓y'Ÿํ๘�ทa๎ำอ?ใบผ๗ƒU3_wๅา…’#Gvsฮผ๒~ฯ^๒จฑธ†H-O๋ฟ}ฮ ค_|๙|?jŒMึจa}�๕@๛๘ฅŽฏศ๐๏ูก�o็ถ�ถ�๑ึADOŽ@@@@@ ฉฅO/_yีํuw๎ุ&ฮšiทuzฅ›คOŸม<�zเgvป็N๖์9ฅœ๑๏แ%K–ฝฏต�ทgทฬ๘}ชu่—฿ "ziฺ:„h ๓n…ฏ\ฟ)W�EตฅO›\R&๊์�k?s9\ส}เ*O๚๘�eไK๗�ฝ‡'า“v_• ๛Ce�ัซr้๊ )uO)woyธhzฃ‚H�ฅžหw]–ฦฝฝ.…sฆ–2yำสฃ%‚$C˜๐๘ฝW#€๘จ@ ฯŸ?/K�%๚ู‚^ห#ษณค”›ก7$tยษaD_!ชsTAD=งก ฿X�Š•ซไ…ญCqVำฦ7m–ฯธ–2ีcฯฅ|ฝD=r˜T7FึVงมใขมBk›๒หrนฒๆก3ˆ๘ํ /ฅa��ห๋Zห[ื=PพœQA๐c๋P๚๕�LิB7ฯ โจ1ใdภ_ู}u็�ท฿”Ž^ะ]sณยnํฺ<+~p;ฬงีัดJšs[ผ`ถไs�<ƒ^ึ=ญk=COžญ~—CBฌ]ณ:ฃ.ญœ;W.ปอช๐็๙žฮ๛Y5€hmฮ๛–)]ฺxฯ๗คb…ญำาณWoั๊†ฮ*szาำ^�ฒeหfTนs๐œ๓้D์ุๅUsYiฝฦฺœห_ป~]๎+_ษ:e~฿ฒaคI“ฦns::ƒˆฺมs‰`5Y8oถ]uP+!ชW\6gQ—ฑฎ^งกYuฯบ—V]ิเœตyV'ิ%†uฉak[ปnฝฝ,ณ†[5่น9ƒˆืฏ‡I™๒=ปศ:ฃชbๆฬ™ฬvฯgjcTใ๓ูŽOั๙฿+ด๋ๆ๐’Fƒพ�ๆ-[ฬ�>คL™Rœ�}p๖wz์�ต[4ฐญ›ตkึmhVรt๖w๎{�™ค"ขS‡}@@@@t]F+!๊v๕๊:d�สษ“'7WจIfwดชแo�ฮbw๔ุฉPฉฒิฌๅZษF—i�aฤP�uHั ๓ๅญข5ิปFl4pฟl8j=2า๏™ƒ’ห}FHํหg๏1k‘v๒rc๐๙0y —๋�ีŠษ”ื z๙‰‰w๛}'ฏIืqGฃœ—\™RAฬ|Rฅศํžฦvด!ืnJ฿้วe์๒ณ‘oI•"™ผ�0ปผู งค [V๚!€ฤR ‚ˆฏฟ๕Žl�ฐ^VK1‡A!ฺฬ a๛’,ญQB�#Œ่!DตŽ.ˆจAรู3งŠsฌMƒˆVO�vl^o�ลQ—๓�๒›ม2้็ษ’1c๙vะWR��rึฅโํ โธQ฿ห#UซุฯณBm๋าฉƒ๑ฟ—ํsฮ ‘็๒ว”—P›ธิ`ศ7�ช๖้าอบ„ณnžฝฝ๛๖ห๓/ut $ED๔ฌ:*oฝ๛พ�ตpฑyoฯe7oูj.-ซ'ใDิJ}ƒฟ๚ยผฟ~™๘ำฯาง฿ง๖๑�ู3ฬwึ]แมสีICฤ,ำ@dล*šํึ…jผ~อ ป‚ฆsi\ํ3เ“ฅyำ&Vw๓t้�N^”w�~รn๗ ปjˆ์๙vm์ฯ˜`ิ Z6o*�๛๖ถฏ=gžนไณ3๙�ฯ�>ƒบ,๔ˆ‘ฃอนีๅฉ[4{ฺพ^wข "ž9{V�2ช@๊ตšไwฦRฝV%Mฝ6ชJ†z.ฆอDิพZ-๒ีื฿6ƒด่ี๊†ึ๒แz�ำฯฟ”ัcว๋ฎนฉฟs)fซ]ฟ>Rพ�ญณษ�8เiา๘Iป�ณ_ษฃวูวบใ ��I1>Ÿํ๘[ตh&Ÿ|�‘๙ซืฌ•ถ/ผl.ี�›Bึ ฎฮM—?z์˜Nถฮi`ตงฑt๘๔™XM๖wฯฯฑu"6KบDดด๘Ž € € € €IQ ๕ณm$o>W4ฯjˆ5jี–Š•2Y๖๏�+ำฆNŽ‘VP์ุฅซQx,™„+ญ๑฿ยcu#้D1'"ฎ!ฤ‹—.ห๓™ฃyขAmษ˜แv้อศ†่ํ0bฝฯ๗ษ–รW"{t„6ญยืซq.้ZืตTT„ql๘gˆ4|ะผบวใ9ไตz9"�)ฉต bญO๗F๔D๙ฅ[ฉY2๚ฯ๓šฐFฅŸO�“ฝFะ1ฆํฑrdlว�1uใ< €w$Aฤ\น๓ศ‰ใมw๔�พิ9ฒ0ขŽ/]ปœ’,]rนy%\BวŸŠP-ัW�!บ ขŽั3 ทu�vyบล3๖๐gฯ˜*ลŠตฃ�๑vฑWฯ๗ค}�็์!h.4๔Šฑtj*ท0ฅvp๕๘ฏนH�ท+„k…ณKฦ฿32eสจงํํ่ัcRณ�c๖ฑ๎l�ธึ^žี:กี๑Z>ำฦ $FDิพ_ ่'O7~สบฬ�ฎใพz๕ชคM›ึnืถ็ฺฟ$บผฐnq "z'๕^{��+๚^%Œ๊nz�ฺt‰฿F›™‡฿"ตkึ0๗=C†Vg๕Fm;~โ„์ฺฝG๎ษ[Š!0�‡�<ƒŒžื้2ศ’�ฦ|dหšีผFฟhP๓‘u์d•ส•dโธQ๖y�ัสv๚m๙ฌซ2g฿�ฝไ™V-�๚Dw]1บ๋t~šทncTี�]ท(ฯyฃ์hœ8}๚Œ<\ฝv„.žหL["[Yฯฝัฝ›Yัะ๊ง฿CCCอJ•}ชŸบล5ˆจืฦ๕ณŸ ข>wƒˆอมต|G๏พŸศ“~ีfัฅ�| ผdส˜Q๔3ฌํมวๅacq \kT�ญ?gๆ…Ž/ฺoย˜‘Žืฎ†y5ิ�F1:ฮ!€ € € € €@  �›ฟ€ดl�ฌ๙š๚3˜ฟๆฯ•-›7ษ}eหKฝ ์BใวŽ’ำงNู ’&อ[ศaฃxฤ’ล ี„N›็t‰ๆFO<)9oญ๒t่เ๙ํื่�ึพฉ๎DLเ‰™4e–\บ|ูผk๊Tฉไษ†ต%{ถ�?xŠ๊q๋��*��ปล<]ฑ|YฉP�พจบฺํžaD />ำ์v5ปcvœAD]๒8Oๆ�dฮ_น!{‚ฏษฆรกnมธi� Hีbฑภล4ฌ[/I�‡ฬn/ืศ&�ZไŽpIR"^ 3ชธ|ธ[N_ 7฿��lฉคoณ�Rญxz ฟqSnป$๏�l.ำฌาK(o้_Bาฅr�4šGร�&ห˜egอV�นj็ZูPi6ั ‹O_—O�8!ำึ]ฐฏ๚สจ€๙\ี,๖1; €ฤW ‚ˆ๑5๐…๋=รˆ:&!๊8c "j0MCzฉSงึ๎ๆ๖ึ;๏หฬ?f›๛u๋ิ’แ฿�.Ÿ๏๊แ๚ช3]f6]:ืฒบ�"๊X�˜>5Bxะ9&k฿3ˆจK:๚๊sฃ’ฃ{๐ะ๊ฏ฿ฏ\นb†=รf฿ �Jิซ๋์j๎?๙t ัๅ[ฃ "๊ฒร?Ž�!ฺ0ง†�ฦŒ›`Vมณื ข^๏ุด๎้�ฎด๖FeG3�6ฌ�[2คw�}eุˆไซA๎KHk]ฦ[—๛uVะิvฯญ�€/dฬ๘‰vณV�dTiด๎oŸp์hตอ>์#SŸแh๑ 1๊ษsฦ2๏•ซบB“๊ปp�fU<ท oh๕D็’าั5๊\ฦูyฟIฟL–๛๔s6�ัพ3ˆจfœ�œ7า ๅ�zี๚fฬr6›๛Z�Pซ:7 ึ5i~;8์<งKfkลศTฉn�}Uฯ;+;ฦ'ˆืฯv|ƒˆฮ๊๚gv˜ฑไนV…Lจmูข๙n]ญ ๘๑ysVโŒ์Y#Sก @@@@’’@ำ-ฅP!๗ีkœ๏ฟkว๙cึtg“)RLš4knทiˆ๑†๑s“”ท–yึฺ๖ใ„ฑr๊ไIปŸ?๎DLเY9�๛Žอžlซข^— ข^งaฤฉณๆ้ฎนul฿ฺฺืwgqIฯ"R2Oš๗;y1LZ =$�ธ*'fMŸBถZ"Bฟธ6DtษอุpA:9bไอšJVXTtฉd็vโB˜V 7ช๊๖c—�RทŒซ‚†ซ%๊ฏล฿�)pฉnƒฺไ•ึU2G่�{ฺ พศ•ศฎT8HfฝธK`Gxy@ผ.@ั๋ฤฑ~€3Œจ๙z%D๋ลึฏ^n‡๏–,]n,I�อ:e๏๓แ๒�3ญ์ใEK–JงW^ณ5ี๓ฝnี๋Ž=j,;A*UxPt9`�.^"ปv7๗=C9ึ2สๆษ[_ึฎ\*Y2ป��ซ ?N’?เ<้~นฒ๗I๏^=อๅV5ภงU๘N๑œ1๓O ฝ*ฏuํb^งี๚ญU฿ํd์ื็#yจrE;<ฉ๔/ฐหWฌ”ฯฟ�ฺ บ]dhํUใพO=ูHr฿๚อ;}๖ใF5Aญ6่\๚Yรlet-/เผ.A�๔้ฦnห๏jsฟฑL๔c�ลK—9ป›•์ดขnถ*Wแ๖’ิฺฆKใฮœ6ูฎBุต๛›2มB=enึz�จYฐ`ซษ�ฎ๏บh๑R��pณ:œ6Vซ๚ฐŒ5ย๎งีญ€ข�xkGฏt๎(•+U๐Nซ-xk‡ูO+(๎๛ฒTคื„๏W๘mW?ต฿๓EษH๛ัˆ €@\"ฦEอ{ืXaD}‚//ว์- ๔*XP4๔ฃK'ๆฆแภŒ]ฟ\—ฑ่{่๛hˆQซ�ษฆฯŽฉ:ZT๗ำ*rูฒf1ƒž•ฃบ&>ํ๚ผ|y๏1Ÿว‚ƒอเค็�œมซ3gฯJ•jต<ปD8Vƒ{ ฟ\9sšฟvภX2!ถ&�ฒืw-Qผ˜œ5�!6s๊Dด–{ึ—} |99x่ˆฑฤ™๏—ฯ โgฟ2oฃc.?_”มO็ณ4:zไ0ปIƒีŒฐmBัพqw๎๖g[รัฯทkใ๖Y:t]…แุฑc’"EJฃฒan3€iU/ใซq € € € € €ภ )VL๒็/(๛๗ํ3B„{cผ:E๒Rิ(=GI—6œ>}Z:d|๗๏*ˆฮ'ˆ่ิH€�ธ†�5ˆจdอฟ๗„˜zVEฝวฎJอO]ศ2%—ขฎต๚๎€,�้บ^—�บ๎ผ,฿ํ:ŽlJ ๆะช€ลฬSžAฤ๏ฺ็“V฿”�วฏบ-ญ!มฏŸห+อ*eŠ์–f›†��žtฬEZ5ภXฅHŒ๋˜_๔]<ท�๗สฎเซๆ’ศ;?+)ฯ ; +Œ๑[ี ญ�kf“�MsKŠˆทฐบD๚}พฑD๕ๆรฎช“jeณC˜ž{�|L&�}ฮl๎ั(‡๔hsั(ฮ"๗ผพ�ผFรขป?|žœ�"zสsŒ _‚ˆ๑ไzˆIเ้SฬŸ๖›=gžtหU/ฆ๋��|tAฤ„~ทจ‚ˆฑyNZ5ฅbลๅiฃ2ฉ?ญํูsไท฿ณ“ไw gvx้yฉRน’]ล22]พZ—ฑfC@@@@@ ฑ"&ฐ|R "พ�ใQ๙e๕ySาY‰๏พžปไ๔%WUฤ๏–ฒ๗ฆ ญี พต� ํiเo๏ภRาfุA;ุแฃ!ถTฒถwฤ โƒาษก3ืไิญgFvญŸซš%ยฉ—G–Y�^Œะ๎lะЁ?ฝ’_ชK๏l–G๚�'{O^=_นH:;T้ึ้ึAƒฒd|'ืาd‘k›+|ธ[ŽUu๛ฅ[ฉYา}œQ��9O๓฿),ๅŒ ’ž›VZิŠ‹บ•ฯŸNๆพSศ�็  € !@1!นD% U์V-[h/w K๓๊ฝIa๓— ข3ฤhอKhhจ4k๕\ค.ญ>I้ป~Ž๋ึฎ)๗ไษ#นrๅ4ช Ip๐qcIๆรฒo�YตzMRโเ]@@@@@|P€ bOJR "6๙ๆ€ฑ ฒซ‚แถyฅๅCฎฅƒ?™qR†,8e ทy$‹|๙ฬ=ดgnผ(G6�-$ฟฝVPvีพ.ซ� ตฏืP]Gฃ nน2ฆ”๛ ธยrฮŠˆๆIใKqc)ๅNตฒJQc‰่=วฏษงณNสYว2ั;Œช…ดถ๑+ฮสปฟ[‡Rฃd4ญ˜Y๒dI%�์ •๏�:%บ4ฑnZ5pปQ�1ฅฃชกDดn ๗~หจH๘@ 9y!L†.<-[nU4ิ>๓zถวo]Ÿ๏บ,tW#$๘็&WาY126๗ฝ์ฌ๔œ์zญv8ฦจ�XฝD}ฉ†ปM8bWxœ�jAท๓vGv@ˆฃAฤ8ยqฤJ@—X๎๗๑‡f_ ท}๒้ฑ^b9V๐แN�D •๗?่%ณ็ฮ๗a]†† € € € € €N‚ˆNุOjAฤฃ็ยคr๏�vHM—Lึ œnฮ`Tห3;—ežุ9ฟิป/ƒ= Œ%‰�Ž8dฟ\#›๔k‘�>gํ8ŸกmO”ฯ(ฃ:�k6ฟkPฏ๔๛;ํ0ก3H็yฎOำ\านvvท๋ฯ!ฦZฦ2ำ'ŒPกno?–S�y<‡�วDิ ฿†พลอภข�มุi๐ล>ูtศตผ๒ซ๕ฒห�5ฮๅ<}G๛Z}rแ๖KขัศรF`s๋‘+r5ฬ”,‘'�ุ%ฟY5๒Nn๚ำสs๒ฮ/ว์yิ๗ศ”Bฮ^ ณ�ดbๅ;็”ท�~๗;y}@ˆJ€ bT2ด#€๑(VดˆYAO๏r,8ุซี+Uฌ ้าบ~al๋๖rๆฬ™X~๐W_ศูs็ฬช•’I?ON2aัX#ั@@@@@ ˆ˜ภ””‚ˆ;]•g‡’ฃgฏ›Šy2ง”FฯนีฐWvฝj6y.ฯ์\–Yซ๎๛ฒ”๓Rนำ b ฃJแNฃฺก†่<ท^SŽหศ%ฎ„9ร†?ฏ:'o�tฬ์๎\๒ู๓๚…�.หsรšอžกJg1ชฅŸ�ฺvIฺVบี-“ม šq๘๒ฬะƒฒxวๅWV.$ฃ_ฮ'9Š‘wบ]ฝ!_ฮ>)#G�รย๗žศ)�๊f—ิ)oW“ผำ็ะ@ศ"FฆB € € € € € € เ?xฎโDผx้ฒฬšปศอ“ kKฦ ้c=ฒธ>3บิ๛|Ÿฝœฐ�ฒgธ๎ำะฺ~ฃŸ@ด๎ณ๐ฝยR&Ÿซ†ี6qล9้aTฺำอsyf็ฒฬญซd–Am๒Z—™฿๏4ˆ�’ฤ“Œภแ›ท‡Œ%ž?nๆชฎ๘ัิใv๘N+.jๅลจถโ๏๎”‹WnU:Œj"ƒJ��œAฤ๕—ผY"ตrd…w›ื�Ÿ?ญฬ{งฐ}�๎ผ6๑จL]w�ผ,�Fฤซ฿2งผั ๖U 7 •ฆƒุ•๕ŽฉR$“L้’หนpปJขถgฯBๆKKkh“ @„ ˆ˜P’�@@@@@@H‚ˆ ์๎P`LC๔ฦ3Aฤ˜žฏกต!m๓สำ3E่zอX2ธpf˜อณ’`๋๏ส’ฎส~K�WDJ�“ฦํ๚; ">R,Hฆv/่v๋`พฑฬsป[หฤU9ฐW“\าญ๎ํส‰�"6|@��bพrํา้eา+ฌืw๛�i์™ฑ�‚ูๆ้๕ำสs2|๑ฉ^<ฝ่๘ญ0cO# :๚V@4Cšไฒ�ใโ’)]rท๛๊ม�“ืคบฑŒณ†uะ*ผ๐h์ช}บฎเ+ €Q DŒฺ†3 € € € € € € €€?D๔ย,ล5Œ�กx;„จใH่ ข�ณj฿�dŸhณถF�ํภWฅ%eฤ�›ูๅB่ )a„ญญT�4าชrf)/ญิ.•�lŽoQoโฌŠจวZฅฑฑQ1›ฑ\๔–รWdย฿็ไz๘M=%๐�๒I ณ:กู`|๑vqล๎i>ฤศิgๆฯ–J�"งT2ช&7์6ผ"Ÿ�qB๖ฟm๋ <}]๊ใ ๊๕ฮ ฅ๚U1ฮ] sฝ_š”ษควใ9คaูŒR {jู{โช�ฒๆ‚�ฐไดBLoท!ำEQ™QŸม† €ภDผ-๚"€ € € € € € €พ'@ัKsโญ0โ�!*‰7‚ˆร–�ำNุโ•ห c;ๆท#�qŽร:ฏAผตฝ‹™‡ Dิ๕๘๙˜L4‡ัmำ&—ฉฏ”rFPันy;ˆจฯaุ}ไฐs>฿s�ฅ๊Yฅหอr[ง๙Ž €AD> € € € € € € €€ D๔๏๙๓๙ั�ตํ’œผ&นณค’ าIๆ c]f6@@ภ!@ัม. € € € € € € เ‡�pา2 € Hi6y@@@@@@HŠ“โฌ๓ฮ € €€ D๔กษ`( € € € € € € €@"ฦK@@N€ bยYr'@@@@@@@ 1"&†:ฯD@ฐ"ฺ์ € € € € € € €~)@ั/งA#€ €#@1pๆ’7A@@@@@@ค)@1iฮ;o €๘ŒADŸ™ ‚ € € € € € €ฤI€ bœุธ@@ ก"&”$๗A@@@@@@G€ bโธ๓T@@[๙( € € € € € € €�-@ัฟ็ั#€ €~/@ั๏ง@@@@@@@$.@1‰x}@@ ฑ"&๖ ๐|@@@@@@@ ~ใ็วี € €๑ ˆO@.G@@@@@@Y€ b"OG@’บAฤค� เ�@@@@@@@ภ฿"๚๛ 2~@@ภฯ"๚๙2|@@@@@@H๒“�G@@ q"&ฎ?OG@@@@@@โ+@1พ‚\ € /‚ˆ๑โใb@@@@@@@ ั"&๚0@@ i DLฺ๓ฯ�#€ € € € € € €€� D๔�9ไ @@ฟ ˆ่ืำวเ@@@@@@@!ˆศ‡@@ Q"&*?G@@@@@@โ-@1�„�@@ >ใฃวต € € € € € € €@โ DL�9` € €@’ ˆ˜คงŸ—G@@@@@@Hvเp๐อx^@@ภO๊ึoเง#gุ € € € € € € €*@‘ฯ € €@ข DLT~Ž € € € € € €ฤ[€ฅ™ใMศ @@โ#ภาฬ๑ัใZ@@@@@@@ ๑"&�0@@ I DLาำฯห#€ € € € € € €@D €Iไ@@ ˆ่ฯณวุ@@@@@@@‚ˆ| @@U€ bข๒๓p@@@@@@@ �ใMศ @@โ#@1>z\‹ € € € € € €$พAฤฤŸF€ €$i‚ˆIz๚y๙;จ๐เRชd ๓Š“งNษ� อ�๔AAาค๑“๖ๆฬ[ gฮœฑใบใy฿Ÿ~�5ฎท ่๋jีจ.y๓�cพใ�}๛eี๊5~๗พ:ื฿"•*VM›ทH็nฏ'ศgศ๏ 0 € € € € €@’H:ตdศั๘7๑ำI๊ฝฝ๕ฒฝ%ห}@@b%@1VLtŠFเีW:K๚๔้อ›6o–ูs็Gำ�OiPฌvอๆ ?!ีkื7๗ห”.-ำง�lฟุG" l๔X�ี๖}�>฿AVฏ]gณใ๘sฦ)^ฌ˜yฐf�?าฆ�K~Gำฉร‹๒ฮ�oุใ:|ค|=๘[๛˜@@@@@A Ož{คv�z’5k6Ie„“'Onพึอ›7%<_�า๚๙ภฏฯEH‚Œ‡ b‚0&๘M1ˆ8bไ(๘๕เทโ† € € € € €$ฆ@•‡‘Gญํฎ_ป&#ฟ*Wฏ\ถŸžlั๚9ษŸ?ฟ�o�ึ-2w๖๖qR�!ˆ˜ิfœ๗E@|L ‚ˆo๖xฯ๘หศYพ|ฉlฺธมว„8พDl�ฒน๔๋๓ก�ฌีsฒyหV๛8>;ใฃ็ฝk!ˆจK3๕ฝ+VD<(ปvญบษ† € € € € €@ hฑjตG%ฤ(.|์˜œ=sVn�WคHQษ–-ป]!๑๔ฉS2~์จh_ฝH‘bาคYsท>ฏ‡�tแ@@ป((AD‹,8๘˜ฬ›๓ง่_Pุ๎ŽAD–fพ;ŸดศŸAฤศ฿ŒV@@@@@K@—bN™2ฅ\3ชzn3e”—^๎b†o�ธ!ƒพ๚ยณ‹�qืW_—4iำš๗Jm,๓ฌAD‚ˆn@@๎ฎ@ U/<,\ึ�ณFVญZ)aืฏ฿]ะ$๘ด่‚ˆ-›7•ฬ™3™*s็-3ฦoถ5จ_Wช#ำฆฯ]ฮบvญšRะpH“&YArฑฑฤ๖™3g"\o5*XPญVUJ–(.นrๅ”ฃGษŽปd�_‹"ฝ.!>ึ—reหส=๗ไ–ํ�wส๒ฟWษถํ�%6ADญ8จŸ;�(Pภ๘<œ•]ป๗ศ฿+Wษฮ]ปญืฒฟ'ฤx-ฃโลŠcฮ#งN–ฦ็�ฯ9sๅ๑9sn:6ฐ›~�mjคKŠ฿ษ\[7๓�œ_ผxI‚ƒƒeก๑็n�†V7พ#€ € € € € ่/พิQฒ?ฟัํว๑cๅฤ‰ใ‘ŽฉัOIฉาeD‹7ฌ— +™�ข "jฒv�๚’7_> Jd๖ฟzํชœ9}Zึฏ[k�Œ่Pคฯ๒งF–f๖งูbฌ € €@ bัšฆ๓็ฯห_๓ๆแŸ�V฿ฝ ]q๗ถํ'ŽŸ๘“4~๊ ษ’9ณ�ฆ;7o�”1ใ&ศงŸ้ึ^ร๖๏�[r็สๅึnใ›!Cฅฯ‡Hฒdษœ—šaยืk# dv๊๐ขผnŒู๚ํB็…็ฯ_พ�ศ๔™8›%>Ÿ}ฯa฿2Cn75&�๔ณjญ$ล‹3OญY๗ดi�’[7�}ฺฏไส™ำญ]ยŒ`๋จฑใeเWƒ�ฮลgผzฃ๎ฏพ":ท‘}พฎ]ฟ.œไ๖yื1Ž1ิCใท8�Zธุ>Žห\๋ล/ฟ๔ผt๏๖ŠคK—ฮพ—sGรช/u|ลูฤ> € € € € €‰&ะ้•n’>}๓๙ร‡‘ะcษa�{�๖/š?�๘็ŸตFQ’0ฉ๒pUณ_TAฤ{๎นGZ<ำFRฆHแ~Vƒ�,โส•+ึก_~'ˆ่—ำฦ @@ภไ ข5K�ทm•e‹ฌหVS@|Ož;•คm•Mn_—+“ฃฎ^็ํ—m1ฆq8ƒvZ!n�Ÿ3ข PY๗:x๐ิ}์Iน“ ข้�y๛ ๋Q~Ÿ2mบผ�ม‡๖๙„ฎˆ๘โ๓ํค็{=์๛วดใ๔ั K�škW›Œ๊Zญุคน+xจ}œAD=—Q�ฅ[CzžjfTญ< ]อMœฐ‹iฺ๋�M™ฟ`ก�อ์ณฃุqพงvYพx~”aTฯ[xตาไ#พ3—q๐์๋<ž`?�d€�Ÿ๑z�7๕ุ๙f๐w๒�๐๏อึ่‚ˆqkญ ฉหVx†L=†!ำgฬ’๏Gโ๕์ฯ1 € € € € € -”>ฝิฌ]GJ•*c�๚๊ี+2tˆ{๋™/w๎jฌบ•QBCCe๘wƒๅ‘GkฤD์�๕5 2~ถข›�๛�นsb�'ณdอšี�9ยˆa฿Jศe��Y"AD๋Sยw@@DH AD…ฝj�ำ๒ๅKeำฦ ‰โœะีbบv9%Yบไrใ\˜„ N่Gฤ๚~wDิ฿$›;�/ั o>P�-$ๅ DiลฝW_น]‘๐๏•ซe๊๏ำอ*|/ดo+%Šป*เ้ Ÿm๗ข„„„สsฯด4—(.W๖>{์บฤ๑1cฺSFY} ~้๖ืœYๆrฬบฏีง�>C๖๎�'eส”’†๕ู๋ี uฌๅ*Tัnๆ–ะAฤ•KJŽูญ�ห‰“'e‘ท™ห+ื1–JN™2ฅ}Nwœฝ�}?’–อ›ู็5p8๋ฯ9ๆ๛<฿ฎญน�ฒuฒgฏ�2yส4๓0ฒœ.ัฌหVU๓๊ีญ#ฉR�~๎์น๓ฅ๛›ฎฐค†Cvบ|ณnZูo�„Ÿไ๔™ำRชD iา๘Iณ]ฟ่ฤ๕=e{๛b๛9ˆ,4ชU�ฎ]ฝ&E‹]�ุนygฯ˜*ลŒฅ‘ญM฿g๓–-’ม๘mส—^h'iำฆ5O้ป<ัธนบŒ๋xu™ํ™ำ&ปอŽwทฑ t…๒๗—ณ?๓๚ฬ๛สป–Šˆ.ˆืนึ|ฉ[ปฆ๕๊2้—ษๆr�๗ๆอ+ฏu๋b�#žผl�6้•\ฟ)jwf@@@@@/ 4mัJฒdษ*้ŒซOs๋฿๋๕‘œ=kฆ์�ท7ยชกร‡nU?œ>uŠ๑๓=1๕gฏ+Y๗๖ 8ฆHžBชีฌ)+–,‘๐แž้O �iถ+ € €I%ˆจSw๖์™9}šœ>uสฏgาBผy%\BวŸ’วฏ'ฺ;�Iฑ�‹ํๅ~๋ืซ#Cm{�†าบอ๓ๆ๑�oผ&]:ฝlŸkึ๊9#@ถี<ึc7GH๑ปa#ฬๅ™๕d๋–อฅ_Ÿ�U ืY7๋ี๓=๓ท�๔XŸฉห๛Z�oพ”วิณฅ~ฃฦv8-!ƒˆM›<%Ÿฺฯ~Ž๗Z๏ฎห%๋ฆAฤแ฿ ฒCkฺfตB�บUห์ฐ�ฉSงฅj:ฺล�4œ7๖ ๋P6�ปIZ>�ฮ<๖ ">rDšทnk?ทZี‡eิ๗Cํ*‰7n� U3รj~๐พดk๓ฌ}_]J{ดฑฌฑต};่K3ศi๋’ฟยำอ3ุ�ฯม‚ู3ฅ`มึ-ๅ‹/ฟ‘๏Gฑ?F*Wช`;ƒˆžŸฏฟ-‘.�บ�}�ท}N๔ณ`mz_ฝฟnq๏ว�Ÿ<�บฅuK๙qา/าปo๛ธo๏^๒Lซ๖ฑ†<5U1>s=iยฉTัeฃี-K฿_ั~ฎ~พิฏk_ฝzU>๚๘๛; € € € € €� ฎ�฿4ฉ]ลฌ็]ปvM&Ž-็ฯŸทš์๏Z5ฑฃQ 1y๒ไr�(B๑ำฤqๆน˜*"fฯžSฺฟ๘’ูW3n๔H๛žถC1ะf”๗A@�L )รรยe�?kdๅŠ~�›LพBิ{lƒˆzซ]�qท?!ืญ [้ถw฿~i๘Ds฿ณ"โ… ŠณeษาๅฒzอZ3gv๔๘› ขว%ๆ๓sๆฬiTˆห 6Ž^ฐป่ฒฦZmPท„ "พู�Uฺ้ฅฃ�œ๗z๖2+3ฺ ฯำv+ˆ๘@๙r2yาDปซ†);ฬ>ึC�• AEฯ โ�}๔ฑ�2yŠ�ตžBห`๔ศaขK[�ซฏฟ-—.]ฒอ0�K/ดท๛๖�LฦO�ษ"ฟฯ˜)Z]t�?๋ต‰ @@@@@Dhั๊ษ”9ณฑRS*#˜VRคLaŽE‹$ฬ›๓งl฿ๆ*Pa ฐm๛%gฎ\ข็GŽj/ฃSQฏใํwอโบRึ��๖ศšU+%8๘˜u๋€๙N1`ฆ’A@�S ะƒˆ‡’…อ๓๛*ˆ๚้๒ลขŽหำ เห]บiณน9]บ4์‡}nWิฮŠvฮ ข.q;}๊ฏ’ฺ๘หง็ฆม�ฑsงโ+ฬžใv:ถAฤ–อ›JซอคpกB’9s&ท{8ฌžถ%dqเg�ฅษSOุช๒hmป*กี๘โ๓ํค็{=ฌC;ˆุ์้ฦ๒Y�พv{lvŠ—)ov๓ "F๖\ญzจีญญ๛[๏ศ์9๓�–ดถฮE๗}ย“ไใO˜]โ๒9ะฅ —-šo?bสด้๒�ทซ]Z'ึ�ฝDฒfษb:ƒˆZqR+Oฦvำภฉฮทnqฏ^ทh�Ÿroพ|บkXญ๛™ ั|‰*ˆŸน~๎™Vา็ร"}ช�F้๊ต๋ฬ%ปunู@@@@@Hl:u๋K๙]+�่ฯ‚†๙Fฎ_ฟn๋พฒๅฅมc™๛�nXo�์๏๖ฯbDlฺขฅ*Tฤํรรรๅโล‹ฒ|้"ูฝk—�9= ˆ่ฏ3วธ@@ิ โี+Wd๙๒ฅฒiใ†€˜)_ !*nlƒˆ?Œ'Ÿ �สm>ฦ๚^ฉZลlsตกa�zf*{๖lnื8ถl�&M[�^.86ADฯๅ—๗๓�๗Vq๘ทƒคnZ๖ใฌ  �`์hP๒“?ฒ›ฌŠˆZu๐๏บ*๗ู'cุฑ‡žAฤศž๋~ณช&ฎ]นTฒฟ™�m๒”iาณWoณป3ุ�ฯAษลeึ๏ฟูำ%ด๛๔๛ิ>ถv/˜-๙๒ๆ5Aฤแ฿ –บตkZ�b�๎��ลeผ๚g(านิxL*ˆŸนึgv๕้�๒K’:u๊(‡๐�ิ฿ๅ�w๛seGN € € € € € เef-[Kม‚…ฬงl\�,Zธภ�๏ุฅซdศQดขแฮฎ•ฌฌกไ0Vฝส‘#งyx๎�9 >vTN:%kWฏดบ˜฿ฌPI~คšคM›ึญ].^ธ cG� aaฎเc„~า@ัO&Ša"€ €*ˆAฤ=ฦo--\0ฯX๒๔ฒฯO[ฺ–ู%yž”rๅื3rใxไน๑ๅข{+ˆhM^ฃ†๕ๅQcIเ๒๗—ญ”˜"…ซ4ฟu�‹/ฟ‘๏G1c "Vซ๚ฐŒ5ยบTฎฟIทมXฺXlgฮœ5—ฒี็Y›ท‚ˆZฉN+ึY[ฃงšสž�๖Z‡ๆwฯๅฉญ ขŽฯนค๐ข%Kๅ?�+C:oคี๏fฯu�f g๑ษง[ศฮ]ป�ๅีW:‹>�ฺ:t๎*K—ญ™ำ&Kฉ’%ฌf้๑�b�฿>๖�๙wำูเ€ู—`Ÿ.cฌKw[�� ฅk๗7ญC๛๛ๆ๕ซํ4p{๗๊)mžmm๗๛z๐ทrไศQ๛ุs'8๘ธY%P�ใ2^ฝn†Qลณtฉ’บk.…\ง๛Rไๆ‰HพDDŒฯ\[QวฦF๕อชU’๛๏/k‡6ญ๓๚�๙9wถณ € € € € €ภ�(]ๆ>y์๑'อG9|H~�๙'sฟsืW%((}ฌ‡b�Œpฤะo#ํŸ={N)W�~)Yฒดฅฟ}ฯ�๖์–ฟO๔i$ˆ่/3ล8@@ค โ๙๓็eษขฟD�ขเ/[ะky$y–”r3๔†„N8!Œ่๋!Du๖VQTบ] 1ฟ๋—lูฒษ[ฏฟ*8ดถ้3fนBqFƒgฑc—We๑าeVW้�ฑƒ๔xณป}�ษ€ฯe์๘ํcญ4จU่ฌอะJศฅ™;uxQ�y๛ ๋12~โOาท�g๖ฑ๎�5๗)�^ปอ "js๖ฬiv๛๊5kฅํ /�วึN�{๓™ป—CBํeŸ=ƒˆ‘-—=๖ )Tฐ uั0�กรGd่เฏฅ~ฝ:v๛ณํ^”u�ฌทuG็'}P:ณMฏฑถธ๛�Yต\2eสh�&44TชVฏใ๖y๐ฌ้ "พุพญ๔|�k2d่p�ํ0๛Xw๔3–-[VณMƒจึg-ฎใ�vะ—f%O๋!žF”/'Ÿ๖๛ุ:-�Œ9_ฑr•DDŒฯ\[~๔aึ{้~™าฅฅท฿“ŠิCsำส•Zม’ @@@@@ฤจTนŠTฏYหยกC‡ไท_\Aฤ๖/ผ$™ณธ�=฿s|ษ“'�Ÿnบคณ�๏�นณ2~์hฯฎŽ+Tช,5kน~๖กห4�0bh„>�ิ@ัŸf‹ฑ"€ €(Aฤื฿zG6nX/+–/•0ฃย?mfะฐ}I–6E„0ข?„ีฺAฤ?ฆO‘ล‹™Sy��c๙ๅgฬ0œ64zฌ �๊ ๓œ~™2mบผ�ม‡ๆqหๆMฅ฿�ๆพ~™=gžน์ฌฤzญksนZซระแ#E+ๅ้ึฤจืฏฯ‡vu=ณญ๙3ฒmปซฤB+<๘€�๒ใ8๓น๚E+3~๒้็๒ำฯฟšแธ�๛สc ู๊็uว "๊�๊‹%[Vื_ธรรรฅKทืํภฅš0V๒ไฮฅ]ๅภƒRฏัSๆพg1,,L>๘ตŒ?ั|nฟ?”'od๖ี/gฮœ]ึY7ฯ๐ค่^่ะู<ง_4ฤ๙|ป6vลJgธ-ฎม>็า�๚Œ�n–ื�xK‚Ÿ:ตjส็Ÿ๖“ฬ™3้)ssห•ฝOฆ�๒ฃ$K–ฬ>ฆ b…คI๓rุ(ฐd๑Bฃรi๓žบDsฃ'ž”œน\…t,ฟ�๚sŒฯ๓ๅ}yv € !ˆำไFิw๒‡ขŽำADญงด9ฒ๋#ข�<ซ๒iGฯ–ถ3~ปฎrีบ+ำ&O’ฒ๗•1๗c๚โอ ข.‘;vิpษš%Kคระ Z�ผ๗ุ็œADme, ถ่ถ�n2ซZ!=ƒˆมมว%Ož�‘�BƒŸOทxฦํœ>oQ2C๚๔nํฮ S~๐a™๚๛ ป9>ม>ฯ๊}๖M ‘j(ัZพู3ˆจU!7Z ศ๏ผ,ย�ไ)Sฅgฏ>v{|ฦ[ฝฺ#†ั็’1ฃkIi๛ฆŽ D>ื�%ูผeซู]Q;ฤeฎ5€๙•Q๑ัJu ม�ํ?เ ณ"ฆ�ภ € € € € €^ะ bชิฉcผ๛ชฟWศสฟ—วุO;ฤD,Rค˜4iึ�พ—น|ณ~L™"…[�ฦjSงNžด��q‡ ข?ฮcF@H€ ข๏Lฆ3Œจฃ๒๕Jˆ–�๚ีหํะ•s™d=ฟnๅ2{้�!C‡หเo‡Y—™฿‡7X๊ึฎi๎๋ศ�ณ6 #พ�ฺ+า ~=ท ˆz^ซป5–�a๔8ซป�ฝ˜QํญKวRฯXzW—จีํ๔้3๒p๕ฺๆ~ถlูคทQMฐกฑ๔ฑVิ฿ดำ �๊ีkๅ็_“‘ร]K5k{ƒว›ุK๙~ฺฏดh๖ดy]jท~ฃฦๆพ.…<{ๆ4ปขb๗?]ๆ76›ๅพ4ยb�_ฮจ๐—สฌRwย๘K๎’ฅหdา/ฟน--�ฌีsvpอบ๗ ํ�ศห/ฝ นo�ถžีฎ๏๛หไ)๖ฒำVปgQ฿ก_Ÿ^rนฒ’.]:ณ�… e๎�F0ฏทu™�wณ.]ฉยƒ๖;k๕๚{ีj6|คฌ^ปฮํš๘|๔F;ผ`.๛ฌ๏ฉฯ 7—ฬ�zะทาฎอณfฅKํทd้rc)ไnบ๋ถ๕ํ�KฌกXดN๎ู๓ŸŒ7A&O™f5™฿ใ;^5๊ื็#yจrE�Uoฌ�ธฑ|ลJ๙�หฏอ –ึC5”:๕ืํeญuษk ู:ท;kฝVC‘ฏt๎(•+Up�ส�ื ้ฐ?˜sแ$  € € € € €xA Yหึ’ฯXฑ(eส�+_9s%๔Š,]ฒPถnู์lŽvฟjตGๅแชฎย [6o’๙sgป๕ืส‡-Zท6�ฝ>ศ^-ศูแโฅ‹2ฮl9ฐŸณู/๗ "๚ๅด1h@@ p"๚ึ\ZaD•//ว|ที4”˜ฯจjT’�เ Q6�Lฌ‡ aDซ" ็Ez฿+WB%๘๘ ฯSw�Xรkบลe,๚ŽฅK—’Fฐ๒ภมƒQ�ร3ˆXผLy๛=5 w๑โ9t๘ˆ�ำŽ๚iSร“;wํŽฉ{ผฯkˆ4ตฑ$s\Œ๔แj\ดHใ๓pYv๏�/สฯEผ๊ธABลvฎC0น๗๓”+gN9}ๆฌ0‚ดQ�™p^ว> € € € € €�ศš5ซไอW@ฒdห"ฉRฆ”“'NษแC๛ๅผฑย•ทถษSHัโล%{Ž’.m:ฃˆลiใ™‡Œ๏�]ั้Eัฉม> € €ภ] ˆxืษy ‰&]1ัลƒ@@@@@@โ-@1�„�@@ >ใฃวต๘—AD�š/F‹ € € € € €ฤV€ blฅ่‡ € เ‚ˆ^aๅฆ๘คADŸœ… € € € € €ฤ[€ bผ น € €@|"ฦGk๐/lูฒษ}ฅK™ƒพ"๋7l๔ฏ`ด € € € € € €‘ DŒ”…F@@ป%@๑nI๓@@@@@@@ภ;ฝใส]@@b)@1–PtC@@@@@@|T€ ขN รB@’ŠAฤค2ำผ' € € € € € €ชAฤ@Y� @๐‚ˆ~2Q @@@@@@ˆB€ b04#€ €�‚ˆwว™ง € € € € € € €� ˆ่-Y๎‹ € +‚ˆฑbข € € € € € € เณ}vj € 4"&yๆ-@@@@@@@ p"๎�๒f € €€_D๔‹ib € € € € € € €@”ฃคแ € €ภ� ˆx7”y € € € € € € เ=‚ˆ�ณๅฮ € €ฑ ˆ $บ € € € € € € €>,@ั‡'‡ก!€ €IA€ bR˜e�@@@@@@Y€ b ฯ.๏† €๘AD?˜$†ˆ € € € € € €D#@1N!€ €x_€ ข๗y € € € € € € เM‚ˆ�ิๅ� € €1 DŒ‘ˆ € € € € € € €€O D๔้้ap € €@เ D �9ๆ @@@@@@@ ฐ"๖�๒v € €€ฯ D๔๙)b€ € € € € € € €@ดฃๅแ$ € €€ท"z[˜๛#€ € € € € € €� ˆ่]_๎Ž € ƒAฤ€8 € € € € € €๘ธADŸ †‡ €บAฤ@Ÿa�@@@@@@]€ b ฯ0๏‡ €๘ธADŸ †‡ € € € € € €ฤ @1 N#€ €xW€ ขw}น; € € € € € € เm‚ˆ�ๆ� € €ั DŒ–‡“ € € € € € € €€ฯ D๔๙)b€ € €@` D ์๙ๅํ@@@@@@@ ๐"�๓† € €€O D๔้้ap € € € € € € €@Œc$ข € €€7"zS—{#€ € € € € € €� ˆ่}cž€ € Aฤhp8… € € € € € €๘AD?˜$†ˆ €ฒAฤ@ž]� @@@@@@’‚Aฤค0หผ# € เร}xr € € € € € €  ‚ˆฑ@ข  € €€๗"zฯ–;#€ € € € € € €wC€ โ�Pๆ € €Q DŒ’† € € € € € € €€_D๔‹ib € €@เ D �นๅอ@@@@@@@ iDL๓ฬ["€ €>+@ัgง†!€ € € € € € €ฑ ˆ+&:!€ €xK€ ขทdน/ € € € € € € pw"�gž‚ € …Aฤ(`hF@@@@@@�D€ ขŸLรD@U€ b ฮ,๏… € € € € € €IE€ bR™i�@๐Q‚ˆ>:1 @@@@@@ˆฅAฤXBั @@ภ;ฝใส]@@@@@@@ป%@๑nI๓@@H"FสB# € € € € € € เ7�fช( € ˜s^y+@@@@@@H:“ฮ\๓ฆ € €€O D๔ษiaP € € € € € € €@ฌ"ฦšŠŽ € €� ˆ่ U๎‰ € € € € € €�=‚ˆwฯš'!€ €D"@1š@@@@@@@? ˆ่G“ลP@@@ ˆˆณส;!€ € € € € € €@R ˆ˜”f›wE@|P€ ขN CB@@@@@@๎@€ โ`ั@@ แ"&ผ)w๔o:ตjJž<นอ—ุผeซ่�tK$฿"•*VM›ทH็nฏห™3gฬs��Rแมไำ~}$�ฝ๗ส�๙๓ๅอ๏{๛‘w��๚ŽฅJ–0Ÿ{๔่1Yผtู]Cl่๋ษSงd�‚…ฑฝ”~ € € € € € €€W"z…•›"€ €ฤV€ blฅ่•ภซฏt–๔้ำGz:<"ป๗�'๋7lŒดฏ5ฎ๙{‰dอ’ลึณ็ศoฟg๎w๊๐ขผ๓๖๖p‡)_�ึ>๖ๆฮˆกƒE’ึึ๎ลŽฒj๕๋0 พkศณvอๆป์�ท_>ัฤg฿ห9ึเใ'คzํ๚>;V† € € € € €€ฏ TญV]ส�ฟคHžRn�7q�นt้bดร-Yชด<๒h ษ1ฃคL‘Bยยยไา… ฒd๑"ูปwOดื๚I‚ˆ>รผ € เใD|ชqSYธ`ž\น์ใฺ9ผm��#ฉRฅŒ๑ๅv๎ฺ-}? ซืฎ‹ฑobvXทr™dฮœษBtAฤ#Gษภฏ'ศP฿}๛Mษมๆœ๚๛tู๘๏fท๛:ƒozโ…eลสUn}��ภ๙Ž�}6? € € € € €Q ิฉ[_ส”-g�|)•[ง๑cFห้ำ'�ฺœeห�/๕<&ษ’%s6›๛7n�ูณfศฎ];#œK* “สL๓ž € €€ B๑อ๏ษี+Wd๙๒ฅฒiใ•�aล6ˆจืฏ‡I‹gฺสถํ�}$ช ข.อ}ุ้ฅซB<|่>tP *$๗ไอg�BรˆC‡|c�<๊บuห$๕ b’šn^@๐=@ "Zฒมมวd�œ?ๅ๔ฉSV฿ฝ,เ "†††สฬ?f›O J'T}Xฒeอ๊6‚�{๖ศใ›ปต๙าATADo16ADo=�—๎Kั—fƒฑ € € € € € เ7�~ื †‡‡ห{vK๖์9${Žๆรข "6zโ))UบŒูo��}2ํท_ํพะกฃdอšอ<�ธ�Yดp}.)ํDLJณอป"€ €>(hAD% —๕�ฌ‘UซVJX�งป๙Qs—,]./w้ๆ๖๘†๕๋ษื?s[พ๙JUฅดCฬ~/>฿NRคHn๎ฯท@>โv}�:ตคpก‚f�–ญ�eี๊5ๆ~�{๓Iร๕ฬ�๐๐2f�)Tฐ ิช๙จTx๐A “ฝ{๗ห๏3fFธ็�ณw฿๑QoวBoขt,ภ"‚tQคืH“*ฝ#ฝ(ุฐAŠ4้E้กwคJ้ˆtAฅ…–„฿>wณw IHนป|๖๕27;ณe๖=๋แพ™1Oบหป50่_ฝš}ึฬ็ุฯPตJ%ษ‘� ณอ๊cฅ ๅฅL้R๒ธัฯ3g�”]ฟ๎‘y๓ฺ็kกnํš’-[6้ำป‡]ฟzํ: XฒLB๎�ฑฯ๗d^)]ชคyฬ›7e๚ŒY๖๑ิณ—’Vฟ‹�‘jU+Kษ็ž•ดiำศฑใ'd๕šuฒ�—๖9๎…ฒeJKั"…%Wฎœrส๐฿ธi‹้œ'w.รณฌy๘ๅหWDŸ๙^6๛|๙๒Jž\นฤฯใ“'O›ณaZaU็ต" "*๘ดa๘ผศ�”�๛๏ฟrเเ!๙�‡ฐXpžฏeตRŸ=�S๙${๖์๒ฯ?�ศกรGไgck]<ฒ-ฆ}ีY1หVฌ๊r้6ญšอบ\น๕n:ะ1ำ>fหšUn3kž“ปv›ใ๎<Ž2 € € € € €พ&ะตG/#€xDV,]"ม!มาขU[ษ”9ณ๙˜‘๕ผไษSศใ๛“o‡ถg=L—.ดi�Š๘๙…~ืh|�4zฤฐplฺ^ัX๚ัว“T)S™ํ7o�”‹.ศŽํ�Œ๏GN†;ว�*"z�ˆั_@@ภว|1ˆh ัฅK—dๅฒ%r�๘1ซŠฯ8ˆ*ˆจทฏJว๖m์๖ผŠุๅร๛v�ๅษSฟ—:Fธ๑aใ—n็ฆฟ”kP๓๓/รผด]ƒ{ƒŒฑัะค๛ถw฿~ูถ}‡hจNท[ทnษำEŸu?,ย}ืA_ ฐM�าY1๛พ๙ฎห�๎Aฤญ�ถK“ฦ �O•ฃ“บ† —๊๘|�้G’9Sฆp็aฟq'‹.{ํพลถฏ๎Aฤกƒีฐ`ข๖ท~ฃฆfhU๛๘ู'J–��Aลฝ/'Nž2�ฑฤ=Œ๋~๛ € € € € €๘Š@t‚ˆบ”ณ.้ฌ›{ะฐuปŽ’>}่lˆ–‰Nแ�tRˆ†MŒI'vVป”G"7n�pฉ๓ถ‚ˆ�6b๔@๐1_"ZCต฿^YฟfตบfU๙ฤง_–ค’ขqz 9{[nฬบoฯ โคqcŒešCg๔ำŽZ!พุuยฦ_ผEg๛ืฅVจ\รžม0ฒsbDŒ์ฺฺ6|ไh2l„ฤE1ช{ทh�^ถ?k›8nด”yพ”ต้gtƒˆ๚ห�j#`ฉKsGถi€ฏFอบ๖˜8ƒˆ‘งmbี0ซต้ŒŽcG.„jต[Ÿrีฐซต�พ:ƒˆผ๛ถดhึฤบผœ={ฮ ฮ๊1:ฃๆฒล๓%eสศ]Nœ8)•kิฒฏA@@@@@_ˆN1kถGฅi๓–&รู?ฯศ๔iSฬrฑโ%คBฅสf๙๖ํ�ฦ๊\Iอ๒wฃFศีซWฬฒ�่ิต‡๑ฝลณ �ผ!—ŒU˜ฏ+Kฅ3&—xฤ�~a๔ศแxอปฟK$ˆh9@@๘HADuฝi�ำ† ๋ไื];ใƒ๙พ฿SCˆ)[f’D)�$ไ฿ v๖พ฿#บŒ*ˆจaฏk–�Kี๊u�kื“#ฟีŒˆ5๐ตyหs™a]ฆูน้ฌˆณf�ไฌŠฐ|ฟ‚ˆบฤฒnบคr๒ไษํ{:}Z*V}ั��่�w$cฦ RญJ่/ษZฉK๏ฺ�ซ„„„ศ_ 2ƒzัQฯืฟึ[บ|ฅt,Vดˆ$J”HซอM—†๎๛ึ;fนไณ%d๊คq�ต„~�ถwŸ์๙mฏไอ“[J๔PZ๛<-”|กขฑ uh7`�ษc๔ฺู–.7žใ7I“:ดkำRRคHa6�2�ขfฦrีวอ�๛ัW+ˆุฉc{้๛jOซ rัX๚ๅfญํ{๕๊ัUบw้dท�l,=g๎ฝ{H็W:XปRฟq3ป]gว์ๆ)~kฬšษ๒ฬ6@@@@@ˆNฑLน๒๒�sก+<8ฐO.†›ศูs˜;Œ;JชTฉ!9sๅ2ฅึ+ฅ�ฒ=๔ป’ 2�f฿ฮฌื &�ฮg5 "๚์ะ๒` € €€w$„ bpPฐ์๘eซlฺธั๋�’ษำBˆ๚–;ƒˆQฝ๕:ห฿oฟ+zำํ~ณ�้ตuFฟ้S&hั�t6D1ช-ถAฤ;w๎HนJีDjึ6eยwRชไsึฎหl~๗3ˆ่œmับูฎํ›ฬะ๎�ใ˜T7–Cึm๖ŒiRธPAณ|๓ๆM)g,]mอ0hV?6ฎ]!™3e2wฃD,^ฌจฬ˜6ษ:]ฦM˜$ŒY›๕ช๒Tพ|fีกรGdQภณ์Dlำพ“l�ดู>ี}FA}~šท@บv๎(ฏ๖์nงำM›C�qA+u&ลกƒฺํK—ฏ๎ฝ๚ศ�์๋ํ�AฦrIฬ{จe‡ฮ�ํ0จuc๗�kHsแโYปnƒlูบอะZว๓‰ € € € € €@BˆNฑ\ลJ๒ฬ3ฯš๛๗�&๛๗๏“๚ ›๛ฟ�ฒMึญ^%u^ช/น๓ไ5๋~�ฐ^ถl�ูๆ๋�็ s2�็่๏Gd๋ๆMr๖์Ÿvปฏ"๚สH๒ € €€— ๘z๑ิษ“ฒjๅ2ฏŸQ_/O !jฟขDิ ป๗๎ใะบŸAD=Ogัsnฮพ=จ โแ#GไEc๙_็ฆA9 ฬY›sYแ๛Dœ>c–ผ�ังึmฬฯ๏'OgK„.ณ์ "n^ฟZ2dHoฃภšu]๛ฌ ฃ†‘ส•*h1Z3"6jPO>๛ไC๓x�ัต็ซฒ|ล*{?ฒ‚3ˆจ๏J‰็หบ๎พ”ดD�๒๓Oฅ^�ะ6]Nธหฮพ�๛ฅnƒ&rฟ๚๊~๗™ญv}ื็อ™)ษ’&ตช์O ่8xPฦŒh3ํF  € € € € €๘ฐ@t‚ˆลŠ— •*› วŽ•ฌู•)SศตkW—พ5๋ฝ�Lโ ณผxแ|9x`ฟญVฏa#ษ™3tถDซ288Xฎ\น"ึญ–ร‡Yี^�Iัซ‡ฮ#€ €�/เซAฤ›7nศ† ๋ไื];ฝŒ'๐ิขโ:ร~บ์๐สีkดZŠ*$Yณf1ห๚รš‰ฮฎ0 ๗3ˆุพSWYท~ฃ๓๒ฒgวั%ขu{PAฤ]ป๗Hฃฆ-\๚ัฃkgู้ฝ‹]WAฤฑใ'ษ]g œ4nŒ”~พคyog๑—อฬูตa๏พ�ฦสM์�Y…กƒพ�ีฬ�่ฬˆุถuK้๗f_๋tqŸีะnˆ เ "๊l’e+Vu9ชh‘B2k๚Tปฮ "Ž๚vจTฎX�ฎช`�ฏพบ฿Ošดhc/ป์lฏ^ตŠ|๔�;vิูf•�ปO๊5 [R�ช็@@@@@_ˆN1Gฮ�ู3 j€0qโฤขณ~?e’�๕ื9“ฅyห6’9K่๗R“'Ž 7I‰†K•.coไดผr๙ฒL?V‚‚n;ซฝฎLั๋†Œ#€ €พ%เ‹Aฤ#ฦ_-ญZฑฬX๊๔šวVŠFฤ/kน1๓ข„œ‹๘—O!*ฐ3ˆจหฬv่�อtฯ๗d^™oฬ็็็g๎๋ฌou๊7–ƒ‡›๛๚ร=ˆ8r๔X4d˜�ฎ…m›ึษร้า™uฮ_ี*•dฤะม๖ฑE๎%ˆธh�ly2oำ/ขตaมOณŒe”Ÿ4‰Nั}Lt)l €Fg‹i๑ร๗๚I๓ฆ/�ท}ฦ�w/œ={Nถl�.๗ซฏ๎ืื�'Nš๏๚ตภภˆšE—ง~กLi)Rธ๙�€�ƒ‰s๛๊๋odฬธฐeลm”@@@@@๐%่SฅN-บtwy์ƒ๖ษโ… ์บWบt“ิฉำ˜๛ƒ~aืป2dศ$…Š–|๙๒‹^ืฺ~?rXๆฯcํzๅ'ADฏ6: €๘Ž€//]บ$kWฏ�Eม[ถT=ฒŠ฿รIไฮ๕น>ๅ๏paDO!ช๓�‚ˆฺ6t๐@3tฅe�6nฺlฮ’บ'’3GY0฿ฺ•�ฟ๎‘†Mยf,WถŒŒ=ยnOAฤq&ษ€ฏ\g5|ฃฯซาฑ}�!o"v๙๐พ�v๙^‚ˆฃG •Jยf�ธ�™2mบ}ญ ๅสสwฃ†�๛ั "บ็ๆ-[ฅe�ฐ%ฉ๕b๔—งŸ.`^๗?Ž™ห7๋NLƒˆm[ต~oฝn^O 1J†i๏k!uชT’>�#f�ล‹�!ๅภp๏^L๛z๕๊Ucฬ–2q�hษ’9ณ}฿€ฅหฅ็ซaณCZ�ะOg@1}๚๔๒Zฏ๎๒rฃฐฅฑ็อ_(}฿zวพ@@@@@|U :AD}v�7w๋๛o�ผ!#† ฑItR mO”(‘9ซแฐo\ฟgฑt+/๑ฌ”ฏPษฌีešว:พ“r;ิ+v "zล0ัI@@ภw|!ˆุ๋ตืeืฮฒัXŠ9่vฤณ z๊šAรV%Q c yท0ข7„ี5ฒ ขำฬ‘$I’ุCเพ\๏=;์_ui็ฏฟ*ำ˜%iำฆ‘แC™ณฦY''„ ข.�บ]Gัๅ‰ญ-.‚ˆึ—�`�ย๘ลำผฏ๛ ”๕5‘“งN›mบ�ต.ƒmmณš'oฝ๓พตห' € € € € €>+� โหM›หฃ=n:ธฯ†XฎBEyฆฤsf�ฑฃGๅง9ณขๅฅ3(v์�ี�Ž!ะXim๔ˆฐ ขu;ˆ ข‡ �A@š€/3gษ*;๋ตCQQ&eหL’(ฅŸ�น,ื'Ÿ7[ขง๐‹ฯคnํšv›ฮคจ�/$OžB xสลๆท฿•Ÿๆ…-'aŸD@@@@@/H“&ญ,Tุ~ŠยEŠI๊4ฉอ��ฦฤ#ฦชFบ�๛๏?r`�>ณฌ?"ป4zนฉน"+—/•฿๖�*O,"UชUQทษวษ…๓็อฒ�ศž=งิmะPNฌ]ณJ.^ผ`ถ้อ�5kIฆ�V;:yโธ�8๓๛๗ฌ}แฒzอบฆ๑๔)\f‹ดrœณD:ช)"€ € € € € เลžyF*Tฌๅณ\ฟ~]F};ิๅธz Iฮœน\๊œ;‡E ็9ซ$Wฎ๎?ภฅ=ขๅ๓ํ`�sๆส�๏†._\ ~™3sšฝŒดs‰้‰ใFK™็K™—�ผeซดl�ัๅาํฺด’ท฿่cึ�พ$ฯ>_Vฎ�๗}Z™:U*้nฬคWป–ฟd๙๏/๏๎ฟฟXงพ9ณŸ๓�›7oJมbกแ@=w๛ฆ๕’.�CZ็2ศf…๑CIฏ\ฑผนปo�~ใฏ�ยfฃิJฝwkcษไง ไ—ูณห™?�”_v์’y๓H฿W{‰Žn๗DิใuผปผาAฒ!มD‰i•น]ผxQพ?QฦŽ;m๘�ำคa�—ฬctYๅช�uฬฒ๕#฿“yeมOณ์ku๏ีG–._a5›ŸŸ|๘žผXฃบ<๔P่๛h59๒ปŒŸ4Efอ�ษชr๙ผืพ๊2สึ;้�ื๔้ำหโyณ%C†๔๖=>๚๔s™๚�ๆ{ีซGฉVตŠห ˆz ?'Nžฮลพ@@@@@|@ hฑโRฑฒ๋d=–ฮŒ8zฤฐpMu๊ึ—�ๅฮmฯ€จhธPgO\ฐ(�๑:๓aร—_6&ฝHeวเ<่สี+ฒ|I€?๖‡ณฺ+หฝrุ่4 € เ;=k,ญ0ข๖ส“—cŽ+ต'ฬ k>rฤ\’8ฎ๎ใ้ืีp 3จ�ีภœ๕ฐฟ8 XบยXŽเขหญœหf_นrEŠ—|มฅ=:;๚,๙๒=)I“$‘รฦrษ๎๗ˆฮ5๎๕!1wฎ\†แ59|๘๗h[>ศพๆฬ‘C{4›\7–o>v�ฤqนWGŽG@@@@@ภSrๅษ#O<‘CŽ�๑‡"<e7๛%–�y๓J†Œ%eŠ”rแย9u๒ค๑้�ณ :œ ขSƒ2 € €ภ ˆ๘ภษน!! ณ๊,„ึฆณ%~๔้9x๐นดp�zuคบ1sŸตญ฿๘ณดุ๋ลฺๅ@@@@@@ภƒ"zะ`ะ@@ ! DLˆฃฮ3#บ$๓†ต+$M๊ิQr™Kik‘ @@@@@@ภ๓"z�˜ะ#@@ A DLPรอร"เ"PผXQ3b˜คK๗Kฝs็๒ๅ+2เซฏeึ์Ÿœี”@@@@@@@t@๐u‚ˆพ>ย< € € € € € €๘บAD_až@๐p‚ˆ>@t@@@@@@ˆB€ b@4#€ €ฤญAฤธ๕ๅ๊ € € € € € € €@\ DŒkaฎ € ฉAฤHyhD@@@@@@<^€ ขวD@|[€ ขo/O‡ € € € € € €พ/@ั๗ว˜'D@ฝํำGŒ๚Nn๎k@ฑb๙rf๙์นฟคlลช๖qQ�kT“กƒพฒkับฝlูถ��๗๖B�๙e�์์ว๘เใ�โ‹aK๛#)h`ต™สฬ‘#‡๑ง”3gฮšกึก฿ŽŒไฌุ5๙๚๛;ฮF@@@@@ bJ•ซJฮ\น$M๊ด’8Ib๛ นvํšฌZนLŽ9bื'ฤAฤ„8๊<3 € เAพDฌ]งžฌZฑLฎ^๓ ู„ำ•}ป‘คI“D๙ภgฯž“ฯพ(K–Eyltp"Ž�nœ <ิ<• โ� "†ฺ๔{๋uiำฒน=3คSLgั|นY+9y๊ดณ๚พ” "�F.‚ € € € € ภบ๖์-ษ“%๔ฉw๏ฺa|gธ<าc|น‘ ข/.ฯ† €x€/_ํ๛ฆ1ํ๚ ูฐa�บkงจ๛VฃDิงพu๛ถดlำAv์�k]โvโธ1’'O.9qโ„tฺ๊St๖C�"�— ขHี*•dฤะมwG2Zvํ�U5m้11i$ˆ5ฮA@@@@H่DL์—X.“ �๕ื9นt้’dหšMฒ=�˜คJ™สไั•บfฯ๚AN฿%ฤ bBuž@๐ _ "Zคgฯ�)ห–,6 ฑ๊๘Œ[g๑าฅห2yฺ๗ๆ ำฆI+ฅŸ/)Oๆอใาฑ็kฏปิ�๏‚ˆw%ˆ(2xเฉ๕ขฟ‰$�zพ&ป~�#๐ŽTฏZลฌ–ง ฟ;d ["ฦŽำ@@@@@ด@Jc‚Š๋ิญ฿Prๅสmถ>|Pฮ›แqพ^IัืG˜็C@<\ภื‚ˆส,;~ู*›7o’ c>ถธpืฎ� :wsนaใ†๕ฅ�วุuฟ�Cjิzษ�o�บฅ$N์g๎/]ถ"�rธ•+U�ๅฬaถ�ถwฟl�ฒี,gอ’Y�ซW3ห๚cๆsŒๅนCN1O๎\RถLiษ—๏IนqใฆlูบUึญ฿(ๅสฝ C}e_ทE๋๖ฒe�v{?ขB๚๔้ฅ�Kตอฆเเ™0iŠ่ŒzญbE‹ก็'วOœ”Ÿ7m–#ฟ่f†ซUญ$=šMาฅK'.\”Sฦ๒ภ๓. ็โผˆ�ซzต*f่3G๖์r�˜!๔ธ๑ื~›7o ื๗จ‚ˆล‹•โลŠุ—฿ฑswธ,_nิ@๒=™WฒcrGฮœ9#๛”y๓ฺ็นิจJฅ R๐้’,Y2๓š๋ึo0gฑl๚r#I:๔ฏืฌ]ก‘๖ซD๑bๆ3ฆ2ž๗่ฑcr๐เ!Yฐ(ภ�VQ๎๕ญ”7ฦFท=ฟํ•๚›™ๅJสห่กห{kEฅj/F๊nžt—ฑ}ฟด/Oศ/นs�ฯ๘�#‰5�ฟ9p่P”K›฿หปเ์zฃ๕$�S๙Œฟอ*ทpๆูs็d็ฎ�Q�ฯy ส € € € € €ฤ‡@ๆฬYคyซ6ๆญ�๙็ขฑขึwแบแg|WSฑrUy๔ฑฐo�บ)/\�ท฿วœ wŽทUD๔ถฃฟ € €€ ๘bั"’}ๅฒ%r�๘1ซŠฯ8ˆ*ˆจท�ณc‹คH‘ยผ๛ั?ŽI๕šuอฒ†ต�d–๕วว�ศ”iำํ}-ฬ�๑3ฅๅ]ป๗หๅถะข”+[Fฦa–๕G็๎ฝdๅช5ๆ~TAฤN�K๏]%I’$ๆ๑ึ‹/สไฉำฅwฯฐ0et‚ˆ๎K�พ๑๖ป๒^ฟ7%mฺดึฅอO}๏หฏฟ1ƒŠ. ฦฮศa฿H•ส�ซํ๓&Nž&_ ฎ�ฟzU๙เ�~’!C๚pmZกแะ^ฦ ”VH3ฒ bก‚Oหิ‰ใ$Uช”๖ต>�คฟL›>ำ�ื{}�แ{๒ฐ’Œh;v�ธt้�;\P}พ่�q8y๛�ฬ ช5รFŒ’กรGบ\~เ€�RทN-—:kGƒ}�่'๛๖๏ทชข�ิ๑ํึ๙๓8ลณš๑>ุ๊k`Vƒณบ�พ$Šc–}˜๖G๛ี๖fฟ๗dฮ�๙๖aบŒ๐๐!_�๛w+ฌ฿๘ณดุ๋ลlพ[1gŽ2ใ๛I’�‘G์ห 9Z† {๊8jH1iRื๐ฆ}๐ ส๙ืฎgW๋yำงL�Kรˆ6 gZ!Dmw"ฮ˜6ษ˜กฑhDงฺuืฅข1{ก† ฃณ้lŽpต๎{ย˜ญ๒๔™?ๅ๙Rฯูงฯš�“๔{๏C{?บ…ุผ_:›แฺ•Kู0Š๔vทŒ™^kึi �ดถ˜ผ :ซ่ฒล๓%eสฐเฉu=็ง๚Tฎqิye@@@@@ด@žrฤ\^:Wฎ�I้R%_บ“[MาฑswYณnฝDD\b,‰={ฦTy�XŽภฺฆMŸ!~๒™ต+_~�ฉิซบ�ดVn2–}�h,5�hถฌโ_ฃš<๒๐ร๖ฑM[ถ•ํฟ์0๗ง!ิ็J„อ,จกมๅ+VJศ;ฆท{่ฮDฌ[ปฆ �"ฌ็ฯ_ฐg“ิYณ๊ฒะ}฿zว๎CT…Wฺท•ื๛๔Ž๐ฐm�wHณVm#l‹ช26๏ืcึศ๕Bg ี๛่lsๆฮ“ cน๙ฺต^ Z›ฺทi฿ษฺ•˜ผ ฝŒYAปw ปฦฯ›ถ˜๗ำฅณ�ดja.ƒm�ภ9ฆVŸ € € € € €ฝ{H็W:ุOPฟq3{ษg›nސโทฦ์˜'Oถฅ€ € € € € €@|”zพŒ<_ๆ…pท>v๔จ�4'l5*๋€ 2Iซถํฬ]]Yiา๘๏ฌ&Ÿ๛$ˆ่sCส!€ €�%‚ˆมฦlb;~ู*›6n๔๚ฟd๒ดขพํั "๊ฑ�๙G�|๛=sf>�ะAฤW{v—ฎรft_๊X๛4fไ0cรrZ4ท˜, ื^ ๆ้…Zตh&๏๕{3๔ขฦฯฏพ�FฦŒ›`๏; :{ศ๘+พ๔้‘๎];Iู2ฅอf-๑™Rกฟ\๗์ึEzt๋lŸfอxhW…ํZKฺ4iอชซV›!3๗ ข๓x-ฏ]ทA:t๎ๆ^แพ†ีาฆ}Hrไxย%i=[…reๅปQรํsง~�ƒ|๔้็๖พ�—2vฮˆธ{๛fcฉ„ะeƒ5ฤุฅป๋ †ฏAบย… ฺืซ๊_ว๎ู•nตีฅยsณFFด9ว.`�ษ“'ทy˜/'Lžั)v]l�ฏขE ™aU๋bบtท.แํ�:uh'}_ �ซMญืwL๛ำwม}FD}ฟ4„ช๏ภ–ญ�Œๅ์ทงŒ € € € € €@ผ ไฮ“WสWฌdฬˆ่'ษR$—ไษ’�}าษHฆNž !!!vz๗yรœ„B'อ8๚๛ูบy“œ=๛งห1พฐCัF‘g@@ผXภืƒˆงNž”U+—y�,ˆ๚ŠybQ๛ๅ "ž8qRฦN˜คี’8qbsฆปฒ/”–‚O0๋๔‡ฮ๔Vฝf9{๎ฏDิe~uน_k+๙BE{6Dซฮ=“ โ�๏~ ?ฮ™k]า�ิ%˜—ฬท๋œA3 ฏ‹,๗Bร$ท$Mšฤ>ฮYp่/u๋ิฒ›๓(b—#+DDŒศฤบ^Ic™่Žฦ’ฦO=๕คหฬ|Vป๕i�ดj.๏ผ๕†U-=_{]–,ณ๗ต๏ษผฒp๎vDิภเ– ซํ๚่ฌY&#;vึ๔).K::|DRงN%=๚จ}ฺ๗?ฬ”>๎/›ืฏ– B—ิ๎�ซ,]พย>&ขBl�ฏF ๊ษgŸ|h_V—™ึๅฆ[๑bEe†1ƒคตYV1}4๊3๊�ŸVเR๋�ท฿๖๎“zšบWณ € € € € €€Gค1V‡j�Jg๑๓๓“   ๖อืแ๚Uฌx )UบŒคH‘"\�•ห—eโ๘ฑฦนทรตySADo-๚Š €๘ €/ตดjล2cYัk?b)eฟฌIไฦฬ‹r.โ_n<9„จภั "บจVฌ\-]z๔7#โศัceะa.ใถmำ:y8]:ณnื๎=าจi ณ\ฎl7z„}ฌ3ไๆ\^Yg^,[ฑชyœ{ าฟv=9๒๛Q๛Zp_ฎ6&Aฤฯฟ�ZฦOœ์r]๗ู์พ7Qพ�zฐนิฎ.นkm6�ดe‹์ูณW.‰ืฆU ษ๕ฟœfณ3ˆ๘มปoK‹fMฌำฬgิgj‹*ˆจ็๒ู2y๊๗.—๚m็VIžCฃ3\จAะ™฿O‘Œ38ฎZิeก ?S*\ฝ{El�ฏชU*ษˆกƒํK๊ึบ”ตss_ฺ๊Z.:ฆ๏‚๓ฺ�ีซส ฦเE 2�ฟิM›5ฆฮ:ส € € € € €xŠ@ง.�%U๊ิfw�โฎ�ส!“*RX๒ๅหoฏ�~ไฐฬŸ;็ฎ็yCADo%๚ˆ €๘ฐ€//]บ$kWฏ4Q๐–!Kี#ซ๘=œD๎\‘๋S�F๔๔ข:G'ˆXปฆฟ ๚j€=,ซึฌ•N]{†› o๗ฏ{คa“ะ ก์6Œmั}†> �i่ฮนญ\บHฒ?๑ธ]“ ข.๗[ณn๛Zะ�ciPฏฎ]งK�๊ภใฟ)e˜ตUช๖ขœ3ไ/;vJ“m\n3xเฉ๕b˜_๛N]e�๚ำwA/ฎ๏‰nฮงšฟึซปผ�(์ึeขuฦI6@@@@@e‚+Zฤ~�ƒ…ึqึgฝบตๅหฯ?ตvE—ฃ฿{r๑โEปnฺคq‘๖ษ>0‚‚ปำฝพ_?ฏ[)™2fดฏ<|ไh2,tึฯๆMหปoฟ)ึ;คณ4>_ถ’ Œ้ปฐh�ly2o๓~—.]6–_nb‡9�gณœ�ำ้/xบ%J”ศˆ™��ะ•ฮhอ^0Žไษ“�yศ]หฑ "๊…งN+%Ÿ{ึๅฺg???๓?—c'ฆAD๗๋8๗5ืกs7ณ๊ฝ~oš3ฺYํRผ~�†$K–ิYmฮ ขึนฯงuzLš4ฉ]žEŸฯฟv}9v�๘]ƒˆ]8w–KnQภ้�็Mฝฌ�mงห5ฏ^ฝ*)RคืG=ึDt�i{d›3ˆ˜'w.Y๐ำ,—{่{s๙๒esน๊”)Sฺ—rŸMำnp๔ื,_,ฮ๓ิ{�r้าc†ผ’�‘Gg„ี๏ตื฿’€ฅหรตนWฤๆ�jX�%๙�u:ท[ทn™�Ya]ซอ้คu1y~๑™ิญ]ำบค13ๆUูปoฟ๙ฃ <%ษŒ%ทญํท฿•Ÿๆ-ฐv๙D@@@@@เ ”)W^ž}ถค\ผpA๖�ถGŽ�Cฮ��ทฑชRyถd)y*๛;ŒำงNสฬยVyสž=งิmะPN฿‘ฌ]ณส˜œเ‚ูo]ขูฟf-ษ”9ณน๒ฤq๙qๆ์™โโFใB•k"€ €D[ภ‚ˆั~X>ะ=Œจ]๕†ข๖ำ=ˆจuw�4„๘๖ปŠ�ฌญrฅ 2j๘kืๅ388X4ˆeว๎GQg›8n”<๒๐ร.๗ฒvฮœ๙S}4›ตฃ ข>งีg๛B�t๖ฝๆญ�ห‘฿š5บด๐ขysย-์~ž๎ป5X7cฺDs‰๋ˆŽท๊๚๘R&Nžf๎�mFDmิวแ }�ฃOe๚ŒY๒มปoK‹fMฌKบ|๊lzฮ/AD=ฐ๏ซ=ฅc๛ถ๖?8Ož;ผT'tๆEญwุ๕ฺ่YบwํแนึuฮŸฟ -�vฐMญ๚ˆ>5xงผจ6๗1ิ๗ฐK�ๆRศ‘�๗kุ7_‡›•ำ�~:cฆฮœ้�b๒.่rะ:ซdฦŒœ— W�ธiณดi฿)\= € € € € €< ">๗\ฉ(ou๓ึM๙nไทr�ฑ‚Zฎ\yคn�๖น!!!bLR$qb—บiS&šแFปา ฝpะ่2 € เK=g4aDํ•งฯ„hษํุฒมXF9ญต๋๒ฉaฎ[ทnห้3งEC„C†tYื:X—๎๗f_—ู่NŸ9#ใ'N‘ล‹‰.ซ›.;�ฉkOณฌฏ93งูก9 Ji`J7UNg—ำMgฌ๊_ว,[?4�๗๕WคhแB’ิ˜๕Mgo�ห๘หนต๋ึกปe๖Œi๖’ว๕7“=ฟํตN๐ณj•J2b่`ปญkฯWฅz•สR๖…าฦ_ใฅ7๋o�ผ);wํ–ื฿zGฮž๛ห>V … >-พืO *h.�l๕g�‚ลr�ฦuั0žn็�๚K^จPี,;hHฐvอ]ย€ฺ~๘ศcฉ๋aฒrี๛p Ÿ-]4ื๖๕5๚ฃหH[�ซ=ปKืฮญ]—{๖้�CZทln†,u&ม  `s6ม~๏}(ณฆOฑร—}๚นL��๕ฏ5ไXี0ษ�ิ“ฆนšn�ฒี4Yฟ:lฆA๗ ขvคTษ็ไ�w�4fA�Ÿ=�Zฏฆ /‘o%Œญ6ต>ชญคฑt฿ืzIั"…รzแยE™5{Ž้ึฑ}ำ� •j[ฉฒรใ^�๗ซ�KuคGทฮ๒ุฃฺ๏ก�C฿ัIF tฬธ ๎ทด๗๏ๅ]ะ“๔}่ีฃ‹TซZลeDmำ๗mโไฉ2v�$�eC@@@@@ ^rๅษ#Uซึ”ฉRน�ปนี�ฮโ„1ฃแโ๓ฤ}๙f๙ฐแห/฿aD|๎•ซWd๙’9~์๋r^๛Iัk‡ŽŽ#€ €พ!@ัณฦั #jฏ(@ั•Gzเ‘xg<์†+—.’์O: € € € € € €AD^@@x ˆฏ��@@@@@@ˆตAฤXr@@ุDŒ็"€ € € € € € €๑/@1�ว€ € € Z€ b‚~@@@@@@|@€ ข "€ €xณADo=๚Ž € € € € € €ˆDไ-@@ˆW‚ˆ๑สฯอ@@@@@@@X DŒ5!@@ˆAฤุ่q. € € € € € € �ใ ่ €  "&่แ็แ@@@@@@@ภ"๚ภ ๒ € €€7 D๔ๆัฃ๏ € € € € € € €€AD�@@x ˆฏ��@@@@@@ˆตAฤXr@@ุDŒ็"€ € € € € € €๑/@1�ว€ € € Z€ b‚~@@@@@@|@€ ข "€ €xณADo=๚Ž € € € € € €ˆDไ-@@ˆW‚ˆ๑สฯอ@@@@@@@X DŒ5!@@ˆAฤุ่q. € € € € € € �ใ ่ €  "&่แ็แ@@@@@@@ภ"๚ภ ๒ € €€7 D๔ๆัฃ๏ € € € € € € €€AD�@@x ˆฏ��@@@@@@ˆตAฤXr@@ุDŒ็"€ € € € € € €๑/@1�ว€ € € Z€ b‚~@@@@@@|@€ ข "€ €xณADo=๚Ž € € € € € €ˆDไ-@@ˆW‚ˆ๑สฯอ@@@@@@@X DŒ5!@@ˆAฤุ่q. € € € € € € �ใ ่ €  "&่แ็แ@@@@@@@ภ"๚ภ ๒ € €€7 D๔ๆัฃ๏ € € € € € € €€AD�@@x ˆฏ��@@@@@@ˆตAฤXr@@ุDŒ็"€ € € € € € €๑/@1�ว€ € € Z€ b‚~@@@@@@|@€ ข "€ €xณADo=๚Ž € € € € € €ˆDไ-@@ˆW‚ˆ๑สฯอ@@@@@@@X DŒ5!@@ˆAฤุ่q. € € € € € € �ใ ่ €  "&่แ็แ@@@@@@@ภ"๚ภ ๒ € €€7 D๔ๆัฃ๏ € € € € € € €€AD�@@x ˆฏ��@@@@@@ˆตAฤXr@@ุDŒ^์ฯm’D๊KY"A2ล/่ž.ุษ8ทœq๎:ใ�ั๗x๎=�ˆƒ@@@@@@๐ คI“J๒ไ)ไ๊ี+ิซ๘ํ Aฤ๘๕็๎ € €@‚ ˆฟฏภดv๎%Ph…ญ“›๛�ฐŠ�ณ{—N’:u๊๏$'O–รG~—;wEx • € € € € € €D%๗ํ�E’& {†ป�ใเกร๒I�ฒe�๖ปโ1๕o๔yUาค Wฮ™;Ovํ�ฏ}+WถŒTฉTั์ร?��+ƒ‡ื�ps@@@@@@เA คOŸAšทnk�๏"kŒ0โ๎] wb ‚ˆ๎o๛ € €T€ โๅŽ๐f๗,ผ—c#ผYTF7ˆจทพ};H6i!๛๖๏ƒž�ŸKfอ’Yึฏ^n_lเ !2z์x{?> ƒพ ตk๚›ทพz๕ช{ฎL|tƒ{"€ € € € € €๑"ะชM{ษ1ฃyoqำฦ r้าe)Rด˜ไฮ“วฌื0โˆa฿฿G�Ž—>ฦ๗M "ฦ๗p@@  D๔Œ :ร่Oใ "^ฟ~], 0ป‘*UJ)�|)I�ศ#.�:lL‹�b.užดCั“Fƒพ € € € € € €@Bxุ๘ฎฉm๛WL†  �2์›A.$ีjผ(O,dึํฺ๑‹ฌ^ตยฅ=ก์DL(#อs"€ €*เํAฤ:u๋K๎ผy๏I๗๖ญ[2qยXนzๅส=ืG4Œฌ-ฎ๛ี๕Aฤต๋6H‡ฮ�\Nฉ^ตŠ ๘…ห๒อEK}ziXฏฎdฯ�„dส”Qฎ\น*gฯž•UkึษŽaKไ{2ฏym5ส�T>๛:oผ�ฎY>x่Hธู%5จg›-kVน$gฯ“ปv›ฯ`_€ € € € € € เ%EŠ—JUชšฝ��˜๐b��ู.=๗๓๓“ฝ๛ˆ~฿?1ฬฅ]wดญbๅช๒่cIช”ฉฬ๖›ทnสล dว๖mr๊ิษp็x[ADo1๚‹ €๘˜€ทำคM+mฺvคษ’E{dึฌ^!;๙%ฺว?ศ# ๊�หIป๋$HF๛ู๛๑]ˆ*ˆจ�”EKœีแสl\ตlqธzgEญ—สมC‡อ*=�›ฏฟ”ย… :ฑห`|ตฯ›vเาj่ะฎต๔์ึERฆLiUน|j€Q}t:่+๑ฏQอฅ�นณr๕Z้�ญงYUฎl๙์“%KๆฬฮC์๒‰“งค๑ื‚๎AO๛  € € € € € €€ Tญ๎/ 6{ถu๋fูธnmธ^vํัK’'O!บ<๓ใ๛็ฆ“P4lา\’$N์ฌv)>Dn�ธแR็m;ฝmฤ่/ € เc�Dิแ(๖ฬ3Rกb่ฬxQ ฯ9cึนพŸl�r'ชCใญ�=Œ่์ˆง…ตoั "N7ฦXฆนค�(ป๗’•ซึณฦ<ˆจ3Ž:ุพfd…/]’ •k„ :ฯน— b๊Tฉdํสฅ’.�CฮK„+๏�ฟ_๊6hbื๛Wฏj�๒›(Q"ป.ข‚ฮผุ๗ญwขDิๅค—-žืpฃu'NJๅตฌ]>@@@@@@p "n�$7ฌ ืg+ˆจ บR—s๋ิต‡ค2พ�ัํๆอr้฿%๐z คM›N1–}ึูG.ืฎ9O๓บ2ADฏ2:Œ €๘–€/��I“fญ$‹ฑmd›†˜6Yฮ;ูaัQัCˆŠUQ—!�ธfน$I6ซฃํzrไ๗ฃ๗=ˆx๖�_ฦาอ[คh‘ยๆ2อฮมิYgอ›}ัูf•?z�ษ˜1ƒTซRูช2g@�ต๛W๓/่พ๘jf�์“คQƒ๚๖18\ธx‰�1–on�ฒ…h0ะฺœ๗๕ํPฉ\ฑผี$ำgฬ2g†|�ัGฅGทฮฦ/ผiอ6]ถZ—ฏฎ้_Cž/๕œฑ�tY—™gฬ ]r`�/;ฬๅข{๕่*�ปtฒฏ๛๓ฆ-2g๎ฎR…๒Rญjh๒ๆอ›๒มว�ํถA_ ฺ5�อ�ซWฏJฑ็สุmZ่ำป‡t~ฅƒ]Wฟq3ู๓�^s_gz์ๆ)~;r4ห3�R@@@@@@ภำtึย6ํ_1ปt[†}3ศฅหีjผ(O,dื-Z0O<`๎gศIZตmg–/^ผ(“ฦg็k‚ˆพ6ข< € เeพDT๖๒*K๑%"+—/หค ใไ๖ํ[ถ{ReD!Dซž8+ขsFDซŸw๛ ‘7�~Wๆ-Xdr?ƒˆึrฦึฝ5๐งม?kำูuvยจถจ‚ˆE‹’Yำงฺ—ูฑs— >า�ืย่C%y๒ไf3จ8mา8y๎ูฐw๔ไฉำ2w�ั #›ฅ0ช ข๛Œˆ—/_1fh ต๋6ศ–ญ�์pฆK'ูA@@@@@ผD uปŽขซp้vํ๊5๙yใ:c)ๅ@)Xธฐไฮ“ืๅ)–,^(๛๗…Nุ  ฝ๛ผ!‰%2Wถ:๚๛ูj,๏|๖์Ÿ.็๘ยAD_Ež@๐b_ "&MšLZทm/iz(�ˆ่ํฟ9ฎ�ำ*�Cˆ<ิญœ„-k์iaฤ่uฦย๎ฝ๛K'oตู๏gฑ็kฏKภ’e๖ตตเ์�� "ึฉŽ|๑ู'.๗‰j'o"ๆ!อš4]�9ขํึญ[ฒe�vs๙h๗็ˆ*ˆจŽ๓ๆฬ”dI“†ปด†?<(cฦN”EKยตS € € € € €xบ@ๆฬYคIณ–’8IโปxํšคJฺl›Ÿ๏แร‡eํ๊ฒํ๛๏ถฅึ‚ˆฉต็h7 € FาRQปDฟ๑ิเฮFฝณ}�6™7wvภบH\B•.*ˆ�ถณ}/nุO‡^ถbฅmRฑ›n’ห.หใ7๏ร%Kๅ‘.��eIส b›๖d๕šu็�bหั!ขuJช b๋V-ฅwภ๛ธhˆ…ro-๗ฏS็G:J๛ถญ%cฦŒ!๖ŒZ5s๖{า๛ษ��๖ธ‚ˆบcญีmศ๑าKฃพ ่์ฬ|๙ีืrW“�†ซv61‹ € € € € €Dด€ 7i&_œร$ž๘๛o๙�๛๏ไโKrศีW_m��๚ภ—ฃ�G‰’ฅๅ–[+๘Ÿน;่ศjฦ๖95OSs๏ัv@@ คต ขvIƒ†$มจ์�˜*sฦ‘#ๆM‘<ล'hŸ}ฮฦ=บAD ธm‡‡m3nธพ ฬ3U๚าฅKg—ต2_ƒFMๅป๏�ซLD|cิ4dXภml\ฟZ.พ่"ป๎ณญ_H“{Zุ๙ีซสศกฏ๛๛ฆTฑvญ2๔๕�uWฌZ- ฿นา V:\๔แน kViPฟฎ”/WVnพนจ\yล�uกแ�อๅ๋oพฑ๋ใD๔N ํซXแV)v๓M6่™>}เ7_}mฐผ5๖ฟ!ซฝใxD@@@@@R‹€WˆโoDิฉญ)X‘={v[้ะ�'๘~.ฝ4—�T์fนแ†B~E�GGVำึR๓D15๗mG@า€@Z "f3o2Z=ุVฮ7็VฎX*Ÿn�ั=Nภ0œ}S๊ฆc "๊๕๕žใผi�๚ฅU›๖�ข\{อ5ฒdั<y๋็_HใๆQAC]y[ฅ 2vิH๛ู"Ž�ถ xu฿†เ๐ไ†O6J‹Vm�ํ�ฬีW]ig;๎WCิข7=vฬ›•ย… ษS}{Jฉ’%�u}๚=mซ8๊ 7ˆ๘ฯ?งคpฑR�~�Œwn๗ผ9rไวป<"อš�ํํ&s็-๎ฝ๚๚หฬ € € € € € €ฉYเาœ9ฅeซ6๖�:tHฦŽ~3^ทSฒtฉ\ฅช�W‡iใ|&ฏDุN#ฌCh € pฎ คล ข๖a‰RฅคPกข2๕�wไฬ™#ถ[๏�7ƒ�a�๏Mซๅ”xร1{๋‚#-Œ[Qƒ†‹ๆฯ– �ปG "j ั›พ�b‹xU๛th็ื•)Sg˜oญe“แCูส~�พg#ˆธใว๒@๋‡ไื}๛ฝfศ†u+%ว%—ุๅำงOK‡‡ปศสีk์ฒ฿8A.ห“�.๏ฺต[ชืฎoซ n๙d_!๒๓/พ”ป›�็Ÿsภ ฯส�w5๔—;?ึ�ฏค8pภ าฐA=�หษ˜qo๛ห ็ฮ’๋ ฐห‡�e†_n.{~๚ู.ืพฃฆ ๔ชฟ๏ฌ9sฅW฿ง�ef@@@@@@ิ,๐`›vfhๆจฯm>\ดPพ�๊หx�ฮd“‡:t’๓ฮ;OŽ;*ฃFืq‘บAฤHํฺ… €œ#i5ˆจ�w‰yร๑วDtON>“ูo_|Bˆ�ฮมaฤ๛าE•๗ถงไclADmว+/=/w5ฌ๏7้ซฏฟ‘;7๗—อ›- ไ๗—c›I‰ ข^�ซฯ6JFSQำ4ˆุค๙}6ุโ�ๆา�ษ��ๆ��ื9>}:น๎ฺk‚—nEล•K รผo�~๙~�ryž<’?>๛FWOชแฦRๅ*ŠW�ฐk็‡ๅแํ�๋้ฬ๑ใวmลฤ็^|Yพ�ข44C={ำ‘#GD3eส,… ฿(ฯ?฿�$=z?)sๆฮ๗—™A@@@@@"] w๎.… •ฒท�"ูฒeทอ?a†i9|Hภญไอ{ญ44ว�ดk—ฌZน�Œbuภnื!škืญ'นrG–ุณ{—ฬœ>5เุิถ@1ต๕ํE@า˜@Z"ฆ†ฎช�ozi๗๏๙๒มyงdข๙8“F 'ภฮ๙ใปo\ADญ ธ์ร…มพวŸ่%๓.ฒ—จVตŠผ๔ฆะปถ๒Nž<)YฒdฑซR*ˆ8b่ ฉYฝšื �ฑ�mเPW่ั:ttlำg[?ทCQ{BฆZ‡Yv+D†:�ลฏส๘w&๙›t่ๆ™S'ษ๙็�WYR7.[ฑสTc์l‡ธž2qผไฬyฉLจ™เกฑCํร:@@@@@@ าฎฮ›W7ฝ'ฦf:๕ฬž9]~�้ง€}๒ๅ+ �ํฏ;sๆŒœ1&2คOฐnฒํ๊๗฿~๓ืฅฦ‚ˆฉฑืh3 € †"ฆกฮ\ฒิ_็อh`Sซ"ๆฯ—Oฒf f.^บL๎�ธ�E‡ม๎๒hGฉYฃz@D�จ•'˜`ฃ;œณ=ˆ € € € € € €@*ศ‘ใRน๏„ฺl��ๆ๐_ษิw'ษัฃGข�‰V>l�ฌ™)z‘ี™ส�้๐‘รฒไƒEฒk็๎๊T9O1UvF@าŽAฤดำ—iแNฎพ๊J[�o�?ุ!#ๅž4˜่U5 ี&�^จะ’>]:ูต{wผฺฎว\e๎7wฎ\rเเฒห �5B]7ฆuJผ๒Šหๅธ‚`็ฎ�f˜ƒ1ํสz@@@@@@ ีheฤ+ฏผZ2gษ,ปอpส;ฬgJ๑™างK/๙ ”Ksๆ”,™ณศไง={ฬc๊ฎ‚่�;ADWƒy@@ ˆ˜โไ\@@@@@@HR‚ˆIสษษ@@ย ˆฎ๛#€ € € € € € €‘%@1ฒ๚ƒึ € €็œAฤsฎหนa@@@@@@HcำX‡r; € €@j ˆ˜ฺzŒ๖"€ € € € € € €=XB@Ha‚ˆ) ฮๅ@@@@@@@$ ˆ˜ฤ œ@@ <‚ˆแyฑ7 € € € € € € i#ญGh € pŽ D<ว:œ�E@@@@@@4'@1อu)7„ €ค.‚ˆฉซฟh- € € € € € € ,@1X„e@@ ˆ˜ข�\ @@@@@@Hr‚ˆINส @@ย ˆŽ๛"€ € € € € € €‘'@1๒๚„!€ €็”AฤsชปนY@@@@@@Hƒำ`งrK € €@j ˆ˜šz‹ถ"€ € € € € € €ั"F7a  € €@ DLAl.… € € € € € €$ƒAฤd@ๅ” € €๑ ˆ+๖D@@@@@@"Q€ b$๖ mB@ฮ!‚ˆ็Pgsซ € € € € € € &"ฆษnๅฆ@@ิ#@1๕๔-E@@@@@@B D ฅย:@@ ˆ˜bิ\@@@@@@H‚ˆษยสI@@โ+@1พR์‡ € € € € € €DฆAฤศ์Z… €œ3ฯ™ฎๆF@@@@@@@  DLฃหm!€ €ฉE€ bj้)ฺ‰ € € € € € €„ ˆฺ…ต € €)$@1… น  € € € € € € L“ –ำ"€ €ฤO€ b�œุ @@@@@@ˆT‚ˆ‘ฺ3ด @8G"ž#อm"€ € € € € € €@š ˆ˜fป–C@R‡AฤิัOด@@@@@@ˆI€ bL2ฌG@H‚ˆ)ยฬE@@@@@@@d ˆ˜lดœ@@ >ใฃฤ> € € € € € € €@ไ DŒ�พกe € €ภ9!@๑œ่fn@@@@@@าฐAฤ4�น� € "ฆ†^ข € € € € € € €@ฬcถa  € €@ DLd. € € € € € €$ฃAฤdฤๅิ € €q DŒ�ˆ=@@@@@@@H ˆษฝC�@@s@€ โ9ะษ�" € € € € € €คi‚ˆiบ{น9@@ ๒"F~ัB@@@@@@@ 6‚ˆฑ้ฐ @@ ู"&;qข/p๑%—ศ๑ใวไฤ฿'}.N6.ศšU2eฮlo๎เมƒ}“O๗RJ•,ažำ'คi๓{“คญ…nผQ�14ฺนŽ9"๕6Šถ>%Vคฆ>I ๘^C๛๒•—_ฐปOx{’ฬš='พ‡F�~ื, ฏ |ูถkาไ)2m๚ฬˆk# B@@เ\ุ๐ัษ’%Kภํฟฟ่C้ีงoภบคXธ&๏5r]พkๅช+ฏร–]{๖ศgŸm ๛ิ9rไ๐I๊๗�z๎•ห๛็๗fF'รFŒ๔yD@ˆp‚ˆ�A4@H๋#ฏ‡ซVซ!ืๆห'ู.ศ.้3ค๗xๆฬ9z๔จ,7�๑ร�zoฆ@๋ฅVบ�bศวSงOษจรBn‹„•�jq_T8m๕šต๒อท฿FBณblร�ฆญYM›ทm฿.ห—ฏˆqฟไ�ฐt๑"ษ+—�๛๏ฟrkลสr๔ุฑไพd‚ฯ�ฮ๘ฑRผx1{�อ%J'๘<๎eห”‘1oฝแฎฒ๓��sJJ•ฝ%ฺ๚”XŸ>)RคฐTผ๕V�œI“฿่~Kฉืๆm+ส๐aƒญษ˜ฑใd่๐ิ๛W๙rๅdิ›#์ฝLx{ข <$%žz\@@โ!เ8(O?๛ผ=bปyo�ำฯ?วใ่๘ํ’?฿uาฃGwั๗ม“ G+SฆN �rน�CmๅแN�m;=*๋ึฏ๗—uF฿ท•.]Zr็ฮ%�w์-[> ุื‚ถ3cฆL๖หƒญธ฿๎N1.5ถ#€ €‘%@1ฒ๚ƒึ € €็œAฤศ๋๒NปJฆŒ™bmุึฯถศ๒ฅK๖)VผคTญ^#`]๐‚ีฟ๖J๐๊ˆYฎXแV9<ชฒ�ุqใeศฐจOฤ40จ!ŸบษฎัJ-lด5e›5m,}{๗ฒ�ดy‹ดn�.e.œภซ$GQ?lฉWฏŽ฿ขŽฺKSI๔lใ�'wํ"�‡;ํ;<,๋7l๐๏!าfR๊ตI1าzž๖ € € 6ผ โ๗�~ฦM›'๙Mj…มำ�•\9sฦz๎—^~5ฮ0โUW^)ณgN“ฬ� AO๘ศฃ]e๕ฺต�น๋ิฎe�6={v†ป?ัำ„๔ืลgฦ}_F1>b์ƒ €DŽAฤศ้ Z‚ €œ“#ฏ�5ˆ˜>]z9๐๛๏ฒ�>9t่\~ูๅr๙UWJึ,Ymƒ5P8kฦTูณ{ทn๑ะก?m๕Dใ�gNž<)sfN^1ห)vJชŽ„ โ‚นณ%o�ผ๖–:=าYึฎ๛(ฉn/Yฮ“Aฤเ†N}w’.tใY "ฦทO"๗œˆ๛ฃ๛ฐ@@’F นƒˆ=บw3#>�c{�๘q™;oพ่ศW]u•�ug)tใv�฿�-eหWŒ๕ฆฦŽ~Sส˜J‡๎ไต๒โด)“%cฦŒ๎.v�ว;ฅแ]ฃญm…๛พŒ blRlC@"O€ bไ๕ -B@ฮ)‚ˆ‘ื�YLuทใ1 ญ�ฐQcษ—/ฟm๔ถm฿ษ‚น๏๙7เW._&Ÿn‰ชึ็๏ f"†ืIwิช)ฏ xั๔ํw฿KำๆQรZ‡w–”�;ญร้‚ˆัŸ{๎^ฃ๛ฐ@@’F นƒˆำฆL๒ร†๓,”พ�๚๛ ฟ&๏52๎,๙ž-ๅซฏพ๖—�™Fw6”ง๛๗sWูy7ˆุตหฃาบีrๆฬ้ัปฌ[๛‘t์ะNZ�฿ย๎j็h'tVธ๏ห":0ฬ"€ €ฉ@€ b*่$šˆ €คe‚ˆฉซws็ฮ#๗ตle�วeยุั� คึ ข†ฑŠ)l๏#w๎\~uฟƒ�!;ถ๏๐๏Og๔เก†ฏี!๔๏ZQเบkฏ‘ 2ศO?�$_}�ผ�๊kr๐เม€๓x ๚ว�N�I‰bล$gฎœ๖ธcวŽห>S‰rใฦM2z์8ูทoฟทป�ทQร†v๙ผ๓าIฉR%์ผผu๋V?YณnŒŸ๐Nภ:]๗šัNเฌp?ุ่๓d?Yฐp‘ฟU‡*ึถž6D9rXn-_^าฅK'›ถl‘J�ง๚สอ7฿$gNŸ– 7สฃ๓ugž่๖˜นฯRึU๏Sฯตm๛vำcๅ๓ฯฟtw ˜ืAjTฏ& 9๏<๙๖›๏dแขER�„'‹/f๗ฝนD`E๏w5l w˜aฅ๒็ห'นsๅ’ร‡หv๓\˜;ฬš=ว�-ฦวp+"ฆTŸhƒG "Y�?œV�๙ๅ’‹/ถ๗ฑ�T7�ฟ�7�žด฿บ>ึMކ%'ิGƒพ:t~fฮ‘ใ{ญฟ�:,?��ณฉคนNFŒ|ำฟพฮ$ลk3เ„๑Xp?๐า โ�฿~7ฯฃชๆwD[�c๗ž=ๆ9๐žผ3qRŒgำ็W+๓[ใ{ฅย์ดyŽ๏๘qง|�๑4xHศใชVฝ]*฿VIJ–(f†Nห-Yณf�]ฐsื.๙~�6๓๔S๖z�ž๒ฺ ��ฅ'}cไ0ษt~Fูธyณฬž๓ž�ำผ™”ฟฅœ�p�๕rส�๓ฮปd๒ไweฮ�y๗๎๓ เเ0tุxญฮขฟฯ฿3ํะBoบฉจdฮ”ษดoง|b~ฯ๊Pt๎คฏว��๚ุUŸ๙ฅตwท{๓�๏8]ž>s–|๐แbo € €ฤ)�Aฤ…๓฿“ซM๕C^xi€L›>3 MK?|฿พะ•�{๔”ลK–lื… ฬUฝ?_.พ่"๓พไ๙ํ๗฿ค‚yoฏ“D์ืทท4i|ท}/RฝVป]xฃ8ผ๚ฺ๋2qาd}\3๎๛2‚ˆqiฑ@ˆ,‚ˆ‘ีด@8็"ฆฎ.ฟแฦBRง^�่�๛~•ษ฿๖o ต'ฟ3มS�‰eF+SฆN ุฃJ•ส๒Œฉเบ6š ภ<�ฝ‡lู๒iภฆ๋M@nโ�ใ%K–,๋�…กรGІกผฉ�c]ไ–๗{‹ฑ>.YบLบ=ั3`Ÿ„\3เฮ‚~๘ A$๖˜ะe�๚w:[E4@x‹๛ึลถ0ั–^8ศ฿%Ož�2r๘0)hย\กฆ“��#อ‡SงE๊{เห/Iอš5Bฐ.8ˆจฒ<๗lฉ^ญZภ~๎ยข>”žฝ๛บซขอ‡DLษ>ั†zEktˆ๕�-ปv๏๒ท$ฦGˆ,Œmj๑@ซ€pib_›ฑ]+ฆm๎^‡�%]taศ]‡|C�=6ฺถŽํ�ษCm[�Pqดf…Vํะ้‘hกยธ๚Eรฬ=z๕5มนง-Yฒ„ ๔ZŒํ๔vDL่๏.=ง>ึฏ[mO�ูg[%{๖l’?๔ืช>๔yไM yxว&ไ๑ฝู3$฿uืูCOœ8!™L1xา@s๛Ž�ะญ�๎Yด`žํC=ฆJี�6๗X7ˆ�ซO_yั‡๎fๆ@@ˆU นƒˆ๚ลQ}ฟ “~I๑๕!C�๖่ฟ็ืฌZ๎ฟo‰ฉ"โห/ฝ ต๏จ%��๛ฏด}จƒดjีR*Uฌ`ฯD|ฒ4นป‘๙โเนตRปฝl™22ๆญ7์|๐uฅพ๗Zฝvญ��ร}_F1X‡e@@ ฒ"Fv�ะ:@@ อ DL=]\ ภ๕Rณvmไศlฝvอjูธaฝn๑ไษ“ฆ๚�yv�๑ใหศ‡ผoซู๙DศLำ&�ฐ�ตื^+ๅส–ฑ-�พc‡lฺด9 •ณ็ฬ•oพ�ึ_ง•ysf๙aBญ^ธbๅJ;ัmฆบูUฆšN?�๒ณิฎ�ะ?Ngฦ%ฅK—ฒ๋ด‚ูfT�eชา]z้ฅrKนฒถrVˆ5zŒ\๙rๅคjี*vYซ jลดb฿๛‹>ฐ๓�ญRถx๑Roั>&ไš'p๔�`AงPM7ˆจU๏ด๚˜V";ฯT'ิI+ํm๛~›+vณ]ท�T9ผซq3ปM |e€ิฌQ�.k%ฤฅห–Izsฯฏ/(ื™~าIรˆu๋7ŒV5๒ล็žต�๕วบ๕๋eฯ๎=ๆ˜’ขก?w ">ูง—่๓A'� eีš5ฒcวถ/ช™ŠujฎSจjvร�„DLษ>ัๆi0K–จืpY๓\๗,ตา็๎]ป��ะ!ต‚+ล%ฦว๛M/๐ƒ้kญุwภ�^ธ๒๒+คRฅŠ6HDLฬkำฟ‘0g�ผผCืฌ]'ฟ�๚ซ�bช�yE8(ทWฏ้ํbkึฌ._เฏำŠจ›อ๋0ุ๋๏๔ร>/^"�{๖๖๗ำ/ˆธใวํhฟ์�+YMHน† ล^v๙ev฿฿~�]ชีธ#เธนsf๚}จ�WฎZm*^f1A�๊’๑�๓�}ƒƒˆ‰๙�ฅ'uƒˆ�Eฬฬwๆ5�‹ฉpฉฟวŠ-bBส{‚ˆ yธ็w� "๊ฑ๚;zตy]gห–อVLี๊ต:0ซ!kฏาห€WสปSฆฺ�ผZeqฮฌvQรๆVdB@@ ๏฿ฦZiฐqำๆแฏ}4กมวบtถ๛๊฿^4_ฌ\พ|…%ก�Cm์ˆ บQ+ิืฉ๘๗ ]ฏ•ฬG /z_ศำ ๛ก‚ˆ5kT3๏แ_ึรDฟะตร�=ฅhัขr�๙ไ๏ฟ�–;๊6ฐ_ฦาฟ‘4oึD๊ึฉc�3ไฐีววMx�็�p฿—Dte˜G@"_€ bไ๗-D@าดAฤศํ�| Hๅ*ี$ Žeหž�ai‹๗๏�gช!NhผD ุ๐� 6mX�‘|ผ~]จอฑฮ�C๛ุqใeศฐฑถหญผทi๓3ผpื€สY3ฆM1ร”ด็ะกU�?ฐฏ]ตB.ผ0ป�ฆ:่‡๎คีสพ๙ๆ›€ป]็ฝ๐’V$k๙`›เอั–“โšzRvสคw์๙��€TญQ+ฺต� bืnOุ<�7FJ”(n๗๕*ˆ้๊ฎกยาeฃ†xาฯฬ้S%}๚๔vX�.]ปTJ˜๔๖3ฌsQ{๖ต�ำ�๕8/pจร็4ุo›{}]้๕šฺ_Lากtป๕่e�์� ~]y�ูg์โ�)•o Iz��วp‚ˆ)ู'nu^C‰ZกNง๖9์ธ�h~$ฦงLฉR2vฬ({ช˜B[uฬPุฑU” ๗ต้ต;�G๗/=VซtjตN4|7๎ษ™๓Rป�์žมไE ็ส•WD…uุ1~ฬ›๔ทY3ฆฺะฒ†\๏ฝ�8๔ถk_ฌ5C)W<ิํn˜ฎ๓c�dๅสU๖0๗ร> F��ภƒ๖CD�จฟ?† ่ƒƒˆ‰๙�ฅ็"jบ�3ฯ�ภฐnืI‡ชืืฉ7\R<ขฮ�Ÿฎ�ฏ{•ๆ-Z๚ี(๕97เล์ษ๔ราJUช๚'vm5Pzฯ}•h{t๏&-๎ปว๎ฏUY_๐Š,3 € €ฤG นƒˆฺ†�O=)w6จo฿[๋ฒพืี๗ู�t์ุq้�๕๑๏Cผ๗7Zๅฐ^รF๖฿ั1๕|๚ok�7ถ;:uสพ'�๓ฯ?คั]wJi๓�ะ๛‚Ÿn{๛‰!�๎โพ/#ˆ่Š2 €DพAฤศ๏#Zˆ €คi‚ˆ‘�ฝท”ฏ ๅ+TŒึภๆ›ํsฬp—ม“D7ˆจCญ•-=ดฎ๛นSR<�๓ลg� "zแg๗8๗5๐� /ษŒ™ณ�อ�๋"ดŒช„จC3๋อ:Uพํ66d�๒หฏluKปภ@@ยH๎ ขŽd มม—\b[ฅ_ึ;r๔จœ9uZ๔ฝ‰7ัL+›๋๚dปG �›@IDAT๙"๊]wG}qP๗+ˆจ๛h1T๕รu๋ืหŠๅ+e๖{suทX'๗}AฤXฉุˆ €DœAฤˆ๋„ €œ[SO็ฮG๎j�TฒšแIu๚�ปoeแ�ธ�€ฌ๛jHฑm๛Žถ2ขัำ฿ํคืื!kตB[จษ "z?7ุใ…;vh'�ทณง๐‚ˆnลEท๊œ{๙sg‰†"u๒Žs‡Z "ำ}�ใผv้zท2š.ว5น•้‚๗ 'ˆ˜’}�N7„W1ฑ>/>๗ฌิซW'ธ ถr๊\ส{cิ่ซa่Aแผ6ฃ]$Œ๎^nxฯ;…วซAYžy๎™5{ŽฒO/iฺคฑฯ+VJ—วป๛ปฬ—?Ÿ/Vฬพะ@คŽั�้g�๖ุ‹9?�๗eม�Nwvc@@ "F`งะ$@@เ\ ˆ˜บz;[ถ์าฆ]๛ว๊SงNษฐมฏล๛๔ุ^Uฤ c฿’?�๘#�วฆิŽแ„ิฏ+ฯ?UัL�ธ�๎”่U๛�v:๔งฬ›ฟะ]%UชT–ึด”ขE‹๘ฯผ4จC‰Ž›๐ถท*ฺcธAD=Abฎฉอ/Z Mฅถ“'OJอฺ๕b … "jเGƒ?:ลD6๔uฉ\)jXๅGํjƒ™๖ ็วœ™ำ$��v7๔ณ�'+Wฎ 1O๎qn0ษญL๘ฮฤIฒo�oม‡,k,ฆแดร "๊ISชOnภ,„DL Ÿš5ชษCm�ส ื nŠ $ถ๋๘ฐ|๖ูึh�tE8ฏอ'ˆ็J๗/ญ<จ�)ฆ ขะ�๐ษFYฝfญ{Xด๙๏พ๛��@ฯ ใ๊ŽŸ~๚™l�� 9๘วA9mช•”)Sฺ)บCกป}โ…q� �Qซฆผ2เEปส "บฏ“„�๎rƒˆ›6m–ึตw/๋|bžฑž8ฤฦธ‚ˆ:ถ—ํฒG๊๋~เ จแ฿ผS๓–”.Uา.vํ๖„l๘xƒฌ\พฤ 1—IŽ;.ทT��;ŽG@@โHฮ ข[�ฤ‰RซN�h๏��/ M›>C^x้eษ“'ท,๙เ}ฟ้ZละJ+nพœšลฎฺ๑ใฒ๗ื_mะ๐๚‚คYำ&v�?�œ’ตๆห•3fอ–ต๋>’๑cFKฉR%�ำุ๙๏พ฿&Mš�mฝฎp฿—D IฤJ@@ b"Flืะ0@@เ� ˆ˜๚๚น}วG์pหฺ๒ืMeจ๘N-[ต–Ksๆฒปฯ{oถl�a[|Mฑ�ย ;นรo��ฉ<ุ6*ฬ’ฦjจง�-ๅคnํ;ไถJmศEฯฃรXWธํ๖O™ ขwฒ„\ำ †Zึ;ท>บ๛zฟ๘Ÿ๊ืW7บหžNซ$ฬ™;ฯ=ต_ฑtฑญด 6‹—*kื้ะถcวŒฒ๓+Wญ–ฮ]๑8�เตK็�anƒซ>่๖p&/ˆจa�’en‰๗กษ�'ม 'ˆ˜”>๚แVล ค~�:Rผx1ฟ ‡Vลx๘ั.มอดหแผ6Cž ž+�ผย "ถจญ<�ฉƒฝส[ฃวส๐‘oฤ๓Š"nล‘Pฯw7,็�\ใฆอํื๎E�ะคDLŠ฿]nQซซด๋ะษฝtผๆ๒<จZ๕v�ƒOฝˆy�๙็_ฦx=7ˆ*ฌฺ้jQรˆ๎ไV•\นzตฌ_ฟAz๗|ย๎ฒ`ม๛าง฿S๎๎I6\=๔ณOทฦ|v/ชฏงซฎบา_uไศQัPv|ฆ„^3�>๑ฺขUsŠ—(ๆ-ฺG5ฯt6ฎ™PŸณั' ฝfj๋“„>๊ฃฯอ„>โ๓ผf@sO 9ƒˆ๎{c �ู(*$่*7i|ท๔๋��ฎ๒�‹��cšŸฟ`ก ๖ํ�K–-[.ำgฮ๒Cส——7Fณ‡jจqษโฅRฉRฉVตช]๗๔3ฯ…ชู}_F1&yึ#€ €‘)@12๛…V!€ €็ŒAฤิืีLP(SฆฬถแรฬpขงN�ฏ›่๘pษœ%๊ธแCษ?�ฤ๏ธx<‰vrรNSงM—ผใ™� ฮกCIฅ*QH๑€xnศŸ๏:3ไ๊ ๏PแoฃDŒญ’€ทol๑นฆ�๏’฿—lูฒษ้ำงอME‡diJLฑ�Cmไ‘Nํฉ5„จแ,wา!™็ฝ7ำ™๚�๏ฟKตwุอ๎‡&๛๖ํฎึ�ใtฝDิMš5Zwฤศ7eิ่1๎กaอฟ3~ฌ ุ้Aอ๎i็�กNž}|7๚x๗žฒtูฒเ]�ๅค๔๑Ojfš7k*}z๕ฐซ4TVฏa#wณ?ฮkำ?(3๎^แตส฿ภWข‚ูŸl�h‡0‹๏ๅ?YฟV2gฮ,GŽ•[+VŽvุธัฃคt้RvฝD|๑๙็ค^�ฺvฝ�ฎา฿Y๎คีต*ขNn1)~wน็Hhัmk|ŸŸm�ฤฎ๊๑q…ภ� bŸ'๛ษ‚…‹�หฺE๕รQbz ฌYน\.บ่B๓฿ฌSฒw๏/’7o^ปฟ;|]‘D?ส—+gƒั๎้โn}{�)Qขธh|ระ‰นfธ}โ5ฎ๓#คm›ึ�ข}Œo<ฅฏ™Ÿณั' ฝfj๊}ย$๔yPŸฤ<ž่, € ๐” "๎๛uŸิจ]7š{ซ๎ทU๒uร๚ ค}‡‡ํะษ฿/้ำงถฟฎธฦ�[8]บtv›�Dซธฟ��1พึ๗ุ๚^R'oT_ฝr™\|ัE2s๖y๖นtUภไพ/#ˆ@ร € ๑#พ‹h  € ถ"FV�๊ป๚Gๅฟ��;dรฎฟแFฉ[ฟก�<4s† ็วJ,^ขค�^ญฦ�๛ว ้<(ไ๙ฯ๖J7�๕นตลฦฺค™ำงŠAคSจa=ฝƒu่�fธึฃวŽyซคH‘ย๒ีW_๛ห�Œ|ึฎ^แ�แ฿�cฝท๗จC„ๆธไ;Dhตตฮ๏ํใ>&ๆš�ทBV'–ธหใ��SG›OLั ฉY�๚w๚๔BO๗๏'๎Œz‡ –/๙Prๆผิถง{ฯ^ฒุT\๐&ญ๖ Uผษ "บA2�@ฅaฃฦื๔ŽัŠQW_u•� ฦ[�8เลคNํZvตVฦำQLSJ๖Ip๎ฟ๏^yข{TีH|๐จJม๛้rb}bบOญh5๘ตWํ%๗์ู#uDUย nCธฏอเใใป์~เNQ‡>๛`แ<(ิkล4คธพพ+T(/‹—�๚\g^๏ูณgทM ฎVพํ6f‚��ไ��๛ๆ�om่ี�/ธ=nQ๗Iฬ๏.=>กAฤฤ>ย นAD๖ปๅƒmด๙vาื๒ผ๗fI† lธ๚Žบ๕EฬมS฿�=�aๆผm?๎�) ๏Š .{๋’๊11aงณฐ ทO<งิzKm}’ะ็Aj๊}%๔น—PŸฤ<ผ็= €ธษDt�ฝฎื์ฺํ 3„๒ ๗๒2{ๆ4)?ฟ]7q๒ป๒๊ภ��w์่,Œ6D*Uฌ`ืฤ๔žวู]๎i�ฬฏ(๎�mcํชrแ…ูe†ฉž๘� /น‡ุy๗}Aฤh<ฌ@@"Z€ bDwC@าพAฤศ๊ใ ทU–2eสษมไซ/ฟ]ป~”฿๛MrไธTส”ปEn,Tุ�๖๛ฯ?ํ‘้S฿๕o หใOศ_�%_~๑น์๚q‡์฿ฟOr็ฮ#en)/ ^oซื้ฮ_|พU–.�ภ?.าfถl�ุSด]ห–/ บ้ษ:}ผac@8ญl™22ๆญ�†`ีแŒๆผ7O๖�บW๒ไษ#7฿TิT,ซ#นsๅท—๗กภมƒeแ๛‹dใๆ-๒›q.\จินใ)Uช„ฝ�/ฟ�"wิm`็C�xwโ�RดhปIƒHZํ๋S‘@‡+�แ‡ํCต&๖šnภ๏ž-C†(�6&&ˆจ็ั็ึ7\oO๙ำฯ?ห๐#ๅะŸIšีL๑N�RZตAซ7x“˜<~�ธ :\v�ธSnฟฝฒญพ็ํงnQ—วํ�kqผ ็}๖๙็บI๒็ห'UซV "์2•๛b !5mาXž์U๕แ฿�•uญญ’wๆฬฟ๒๙_ˆขtJ้>ฑu~ธ๎œ8qยR๔๙‘SbยNg#`nŸxfฉ)๔–ฺ๚$กฯƒิิ'๚‰yxฯ{@p’3ˆจื™6e’บ๑F{ษcวŽ›*้๏˜Šโ[$ปฉ๖�๚–�{�!๘}ต=(ฤpƒˆ๎๛Ž/ฟ�J–ฏ\%ๅo)+eJ—ถgghๆศฌB@RนAฤT�4@Hํ#ซ5ˆXถ์-q6๊ฤษ2๚ร+?f†vk๚๋ะ!;๚อธv;ซ�๛=ูGš�zxุ—^~UฆLะพ^=บหฝ๗4Xj!T1ิ~๎บ>�ž’&ธำครฎ๊๐ซกฆ%K—Iท'�๋78jo]จkบU 6mฺ,ญj๏ํใcbƒˆ:\๊เืšaภ3ลx u๎Uัฯ�I๏s๚ิษr๕ีW{ซb| "jเ่อ‘#Lˆ4wŒว่†๘TC @y'ิ�TcRบOผ6ธณfL“‚ขช`ธ๋uพ~รป†฿Nจ@ >ฟปฌกัVญŠu๋p_›๎๙ใ;Ÿ˜ ข^ร ฦvMทˆVL๚๚kฑํ๎o "jUฤ๎�๓ƒ��ŽA3มAD�œ฿]�i�็nธAD๏กใz„<Š้u่^๛ศ‘#ๆนื6 ธํnื๙ษ๏L›Lฐ\' ™VฏU' ”n7$ัฤ„ฮFภ*�>๑˜RS่-ต๕IBŸฉฉO๔y”ะ็^B}๓<๐ž๗<"€ เ $wQGo˜lพผ�{jmฯœน๓ค�ำฯบM‹q>� ขž่‘รD฿฿OมU��ํ๎๛2*"บ2ฬ#€ €‘/@1๒๛ˆ"€ €iZ€ bduoพคF;$‹ sw�yังี�v๏�%๏ฯŸm๘ๆ๖‘ฌY/ˆvŒฎะ }_๕ฅ,๙pQศํ‘ถRซีพฃ–ไษ[.2ีผI�8ฏคž๔ไ={v๗+ปน�ต๊แฺu๋ๅอQo‰V๖๓ฆกfx๊ล‹œ฿�ถ็งŸdิ[ฃe��…�ช๕๚๗���œซ˜\pม~ฟอ_ฐP๚๖๋p\Bฏนp�{�ฝuzคณนŸฮjแแNค�CmE+ํ•น%j่&ฏZแษ�‘าeฃ>ˆxฐUKyฌKg๎ฉTนjภ๐าZฝแฅŸ“|ื]p =็„w&สˆ‘กCญ’6tฐ”.Uา?NŸƒkึญ“ ฒd•าฅKู็oู๒�ํ�Œ�ว ลZซf ักส�IฯกU˜*–SงMw7E›ื๓๔๎ีำดก„\~๙ๅ~ฟ=•’}ญ‘f…แ๛ศรMEŠ’ฆrgn[ญO๗;m*"†ช6!>๚X๏ž=MซH4Sฝึ–-Ÿสเaร�J‘บ.ฆ)�ืfL็‰i}ษ’%dยุัvsจaตuHp\ง^}๚ส๛‹>ด๓๎ึญึถฒCน๋u~—๙�นjี8hpภ&2ผ๓#�>ะภ�–O?•ูs�๎['=N‡wงป6&ญ}ใMZั๓�ฉSE_s:ฝa~�hˆ1xJศ๏.๏›>Yoซ5† {๛ธI๑<๘x�๓฿™,�i๕w‘�NŠi๒‚ˆZf๎ผyา๘๎ปๅ�๓3๘ป๏6ีMป<ึMถ๏๘ั_jฆ�c]ไ–๗�Mq]3ิ๑แฌป๙ๆข&ะ:!เ!รFศุqใึ…Z�๗ศัฃrkลสกv X—˜k†�'�…ตzจVuง๘T�ี�S๚š‰๑9}’ะkฆฆ>Iฬ๓ ก>‰yธฯsๆ@๐ผ ข�อเ้็ข�ฝ�รถ�nเํ›ะG�7x๗nห-ๅสF;…^๗ญ1ใไ�)Sฃm‹iลkฏพ,5ชWณ›�ดmoFwุำฎ๋{t๏&Uอ(๚�XGƒX๛ัG๒๊ซƒ��๋+�*LE๘2ๆฝ��-๎ณ็ ˆ@ษ € ๑#พ‹h  € ถ"Ff�ฆK—Nฎฝ6Ÿไธ4‡ ำ\$วŽ“_LˆN‡c>}ๆtŒฮ”9“ไฯ_P.น$‡ 3fฑC5๏ูตS๖๎�ใ1iiƒŠ)"น๓ไ’?�๘S๖์๙9 ข\จ{ี*s๚ว๘‹/นX�2C๏ฺฝ'ฮcB'œuแ\ณ^�ฺ๒โ๓ฯูำ๛�๗าด๙ฝแ\*I๖ีฐ\ัย…ํpชมCNวvํ2eหุแฤ7|ผ!ฺ‡ฑซ�ฎษ{�pC1)B๙๕ื_อpน;ย>G\ื๐ถงถ>IจO‘"…%—ช<[ถ d�พ฿์s}฿พ�Cšzิสš7�pฃd7ร๏๛uฟ์6ฟ?ใบW บไ5ี<๗๏��็ˆw๓ศgŸงZ]$œ)!ฟปย9๐พ)๕<๐‚ˆGอรด ฅN�พภ๔ษึญŸวู^ป�กโป๗่)‹—,๓6๑ˆ € €@‚ผ ข{ฐ~ัIฟ๐”ิ“�{ฟเ๕ๅช+ฏร‡ส๖ํ�“4๐˜ํี๗�+—-Žv*‚ˆัHX €DดAฤˆ๎‡ €ค}‚ˆiฟนริ-0nฬ[~eAwx้ิ}Wฉป๕๔Iฬ�ืฐ~=ษหp�1yภTYพ|EL›YŸJBรฝ•๊ีชษ /�ร~��€TญQ+�Sฐ? € €ัV,]lพฤyqภ๚ู๏อ•g�_1`ร9ฐ aษU+–J† �U0ื�6โxU?ˆธE@@ UDL�D#@@ด+@1ํ๖-w–6ด*`๎\9ํอฤwุฅดq็‘{๔I่พัฎึฏ[zck๛�wฉf†ฅgJ[ "^uๅ•Rต๊ํR์ๆ›คRล ’9sf 3j๔˜‡„O[r�  € € € € พAฤ๐อ8@@ "&!&งBฮaฤ๗�๖›TฏY๛ึK›ทžะ โ=อ›I๏žO ่pืญ�ดKถแู.ฦ € € € €  "ฆยNฃษ € €@Z ˆ˜–z“{Aฮฎ@‘"…%S†f>๔็Ÿฒ}วgท๑\=ษฆLzG บQt่ํp*^๊฿ฯ<�”mฯ�_๗สง[ถส / „˜ไ=ฤ @@@@@ - DLKฝษฝ € €ฉP€ b*์4šŒ € € € € € €8 f@@R^€ bส›sE@@@@@@@ )"&ฅ&็B@[€ bุd€ € € € € € €D”Aฤˆ๊ƒ €œ{ฯฝ>็Ž@@@@@@@ m DL[�ษ� € €ฉN€ bช๋2Œ € € € € € €D เ`@@ ฅ"ฆด8ืC@@@@@@’V€ bาzr6@@0"† ฦ๎ € € € € € € €@„ DŒฐก9 € €ภน&@๑\๋q๎@@@@@@าšAฤดึฃ� € ส"ฆฒฃน € € € € € € €@Aฤ @@RV€ bสzs5@@@@@@@ ฉ"&ต(็C@K€ bX\์Œ € € € € € €DœAฤˆ๋„ €œ[ฯญ�ๆn@@@@s]`ๅ๒%’ใ’KfอyOžy๖๙€u็สยYณสšUห%C† ท%Vคฆ>I ฎ € €D’ภ†ึH–,Yš๔�ขฅWŸพ๋’bแšผืศu๙ฎ•ซฎผB�uXvํู#Ÿ}ถ5ฦSป๏'cฺ)ฉ฿๛็ศ‘CV.[ํrฃวŒ“a#FF[ฯ @@ศ ˆ™�Bซ@@sF€ bไuuีj5ไฺ|๙$�ู%}†๔~ฯœ9#G•ๅๆร;~๘ม_jฆ๒ํีไฮส’%ซคK—ฮ๎ขว>|X-˜+{๗๎ uุY_งloq_T8m๕šต๒อท฿ž๕6ลึ€๛M[ณš6o�พ]–/_�ฎษบm้โE’;W.๙๗฿ๅึŠ•ๅ่ฑcษzฝฤœ�๑cฅx๑b๖7—(˜S๙ว–-SFฦผ๕†ฟ์อ�๓ฯ))U๖o1Eใำ'EŠ–Šท�j�5i๒ป�oฉํต™ขอล@@@ ี xAฤสำ�ฏ‚ธ�ผท�้็Ÿ“์^๒็ปNz๔่.ๅห•‹vN Ž=VฆLm�๛ๆ๏6W]yeด๕๎Šณfหsฯฟ่ฎ}฿Vบtiษ;—l฿ฑCถl๙4`{\ ฺฮŒ™2ู/ถzเ~ป;AฤธิุŽ €D–Aฤศ๊Zƒ €œs#ฏห;u๎*™2fŠตa[?�"ห—. นO๓{[ศๅWฤ�๋ukWห'ฏy์ู^Yฑยญ2rxTeปฑใฦหa#ฮv“bฝ�็Ÿnฒ�ต’Aห�ฤบormlึดฑ๔ํ�หž~ำๆ-าบmปไบT’œ79‚ˆ๚aKฝzu�๖u์ะ�ฑuถ‚ˆ๑ํ“วปv๏ร๖–๕6๘๗i3ฉํตi~ด@@"Kภ "~ฟํi�ดy’7N+ ฮ˜๖ฎไส™3ึsฟ๔๒ซัยˆK-”<—ๅ‰๕ธ9s็I�งŸ๕๗ฉSป–��@๖์ู�uF์�DOJ�ั_Ÿ™�*V”แร�] "ฦGŒ}@@ศ ˆ9}AK@@sR€ bไuปำงK/~�]๖๏฿'‡’ห/ป\.ฟ๊Jษj*๊ค•๏fอ˜*{v๏ธ&อ๎•ซฎพฺฎำ ˆฟ๎�ล|›�'Ig�wูๅๆW\!๋?Z'7D €KเB$ฬ-y๓ๆตwะ้‘ฮฒv�G ผ›”9,9‚ˆม-Ÿ๚๎$)\่F9[Aฤ๘๖ Aฤเžc@@Hไ"๖่�อŒ๘pฝ™ใวห�y๓EG~ธ๊ชซไฎ;H!3Š…N��ท”-_ัฮ{?ผ โ้ำงeย�๏xซ?๙d“�e6ญผ8mสdษ˜1cภ>บ๐ใฮา๐ฎฦัึวถ‚ bl:lC@"[€ bd๗ญC@าผAฤศ๋โ,ฆบ�๑†ึmุจฑไห—฿6z�ถ๏dม�๗�ศœ9ณด๏๔จŠ๙๔ฉำ2{ึt๙iO`PQ‡iึ€bคNฉญฺู๊"�Qซฆผ2 j(ฆoฟ๛^š6ึ:R๛W�•ึƒˆแ๔ AฤH~ฆา6@@HหษDœ6e’6œฟ`ก๔ํื฿็ผ&๏52๎,๙ž-ๅซฏพ๖—ฝ โ��๛ฅzญ�ช�๛;อtํ๒จดn๕€�{O�}d�ฺคc‡vา๒�vฯŽๆoE๋ึว� ฉƒ€YD@R‘AฤTิY4@H‹SWฏๆฮG๎kูส6๚?ส„ฑฃ�จ[ฟก\Cิ7๊7˜ก—?2C0ง†IรXE‹ถMอ;—_�๏เศŽํ;nA‡ 5|ญyคxืŠื]{dศA~๚้'๙๊๋oไๅW_“ƒœว[ะ?�wุ๊NJ+&9sๅดว;v\๖™J”7n’ัcวษพ}๛ฝ�ํ๐ฟ6ดห็—NJ•*a็ต๒�ึญ[��tfอบu2~B๔สแ^3เคA ๎}ž์' .๒๗ะกŠตญงM๐๔ศ‘รrk๙๒6คบiห0` ๔ชฏ�|๓MrฦTXุฐqฃ<ฺ๙1�Xwๆ‰n™๛,e]๕>๕\�ถo—ัcฦส็Ÿ้๎0ฏ‚ิจ^M , r�y๒ํ7฿ษยE‹คถ O/^ฬ๎{s‰าวx w5l w˜aฅ๒็ห'นsๅ’ร‡หv๓\˜;ฬš=ว�-ฦวp+"ฆTŸhƒG "YLhXง�๒ห%_l็w›๊ฆ๛๗�f็๕‡๖[ืวบษักไ„๚hะW‡‚ฮoยฬ9r\bฏ๕ื_‡MีิŸM%อu2bไ›�๕u&)^›' cA+z่�… ’ห๒ไ1U฿Gฝ5Ft๖˜ฆ7F“L็g”›7ห์9๏ษ=อ›I๙[สษ ื_/งฬklงi�ไษ๏ŠŸๆฝ6๕\3gฯ–๗}๒ด�๋"E G�n|ๆนeื๎]vฟQoސ๓ำg›6�็‡พฆnธม\็ิ)๙�๛ไ�>wงLvNย\ƒฒ•oซd�uฉ๙—๑�๓ๅ?�”อPmŸš฿aC†vœทBฟ๊๏&™๓๋๏ี† ๊Kนฒeไช+ฏดm๙๚๋ฏeุˆ7|+๕ฎWงŽT0ฯฝkฎษk‡Lื@�ฏ{•ปvสา%หd–๑r'ํ{oธ๙�ฟ�.ท”+#›ืษw฿/ฯš~ปงY3นฝสm’ี�ฯๆ๗B๗'z๙6๎yš6i,w7บำถM๛Rซษ�๙็!ู๖ร๒มส์๗ๆบป'j>!}’ุ็Aขฬม € €’�Aฤ…๓฿“ซM๕C^xi€L›>3@}้‡๏K๎�นํบ๎=zสb๓oco 7ˆุฏooiา๘n๛�ล .z_ž|๕ตืeโคษ�้ใ|$ˆ'; € €+@1bป††!€ €็†Aฤิีฯ7�XH๊ิk`ฝ฿ฏ2yโ�� h5D fhุb่๋�๕‘>3๙ rำMEใีฬ—^~UฆLฐo•*•ๅ™���@WภFณ ฦวป๗0!ฆO6]or฿/Yฒd X๏. >Rฦ˜0ข7i0่–๗{‹ฑ>.YบLบ=ั3`Ÿ„\3เฮB,ิ๐“N{L่ฒn�;ญbC๗ทธ/`]l MH๊ีƒ�]4@4r๘0)hยrกฆ“��#อ‡SงMถyเห/Iอš5ขญ^Dิ ิsฯ๖—๊ีช๏๊//2ขžฝ๛๚หกfย "ฆdŸh[ฝ‚Bต;x]�†wฌใฃD ฦ6ตx U@ธ4ฑฏอุฎ�ถ๒ๅสษภWุ `l๛˜ๆตWซพ/U6ฺก+–.–K/อ!{ู+ต๊ึุฎaิืพ,๚|5iศoะเ!2i๒”h›ต_ึฏ‹ ~kX1{๖l&ศ�uฃABํS  ฝ๘�ณ๖<_~๙•�{�!ฯนjลR;ดš^[?LิเŸ{ญh9+fšภ๎ณฯฝเฌั฿•C_-`]๐ย7฿~+ป>ภ๖๖ฉYณบ |y€]ิ๐d•สŒ�๛Sร–�ŸŽบ?w8:๏<ม ึ ต7Uพํ66ไฟ฿E�๚˜5p~ฯ}ฟ—‡d�ำ1๐-_แถ˜6‡ต>ก}’˜็AX dg@@ษDิ/Ž–,Yย^[ฟค๘๚ก~;๔฿kV-ท_†ิ•ฑUDlzO ษi�ว��๓/!ฟจฆว๗{ฒ4นป‘๙โเนตR]%eห”‘1oฝa็ƒฟธจ+5lธzํZป=๘Aฤ`–@@ิ#@1๕๔-E@าคAฤิำญ \/5kื–L™ขชฉญ]ณZ6n๘ohGMx$C†๓Mลง?e๑ ฅ์-ทสe—].้ำง—c&tฑw๏ฯฒhม�ˆปaญZๅ…�ฎฝ๖Z[]Kน}วูd*~นำ์9sEƒ2�คaนysf๙aย}ฆzแŠ•+ํpDท™ช_ZฅKงŸ๙Yjืm่fว%ฅMๅ3ดู๊fT�eชา]z้ฅฆWY[น@+ฤ=ฦ๎ฃ?4 Uตj3'ถบ VะI+๖ฝฟ่;๏�ะสh‹/๕ํcBฎpgA?Pะt ะิสe^Qซ�ํ�นำ>ฯ3ี uา ฮถ๏ทIฑb7›‚…็™Šƒ�ๅฎฦอ์6�1๐•RณFuปฌ•—.[&้M%ณ‚ื”๋L?้คaDญฤฉ๎�ไ†kt�ดg๗๓Lษh!ฏเ โ“}z‰>t๚๗฿eีš5ฒรTjำ*ีช�nอu[จjบ�›ย "ฆdŸh๛4 ˜%Kิkธฌฉ$็Yjฅฯ�ปv{ท`Ÿรฺฏ๎”๏C6=฿ฆฏ?�๚น8p@ฎผ� ฉTฉข\tั…DLฬkำmwธ๓^๕=n�oฟษ† ŸุŠxZัั{�๊ถค "ฮ˜6ลT ,จง•ใวห‡K–สŸ�)ลอ๋รซเฉภ&อ๎1ฟ›~ด๛y?b ข}g^_ฟ˜j“๚;ฅจฉิธ็ง=6ˆจวญ^นL.พ่"{Šป๎nํœ๗฿wฏ<ั�qป}อฺu๒๐ฃQ!าPืา฿‰€ิ*Ž�๏=ฐำ#Mฅห์9๔‡Dิื–๎�ƒ๙๛๛๏ฟ�*‘ตjึด!G�oๅสUาูTใ ž� ขทํฤ‰๒อ7฿ฺ�๎\๗j[ล4T๑๏ฟ�ถ•W๗์�IŽ="7,(๚;Z�๛ค“�—nQอทn�ย๘6�ํหd๗ี ้V๓�ฝ๑ฦ์๏~]ฎ`>l๕ช‡บธ๊ฝ๊๏v5:y๒ค0ม๊[o)oชG�#ๅnญdฯ—ุ‰้“„>�fŽG@dฏˆ๘`ซ–๒X—ฮ–Z�ๆ๐ขyท|๙ ั/Aตจ�‚’nิ ๕u๊�ฝย}Oไ๖•~ัr๓ๆ-ๆ=๑ห#?ิฌQอผ‡ู๎z่ะ_ๆ}๔๓o่ขr�๙D�-~G�v�I๓fMคฎฉZฎ_าS q‚ทhป<�„�Gƒˆ^xaภ��Ž'ฬ 5คu๐เoUD=jะhไ๐จ*cว—!รFฤฺ>ท๒�&๓ว๘G;w๕ร(z . �๛ฺU+ŒSv{�ฦM›ห๗�~ธ–†vพ๙ๆ›€]ภfมซnงกž–ถ �m9)ฎฉ'-RคฐL™๔Ž=�๏ฟช5jEป–D์ฺํ ๛ว�ใฦH‰ลํพฝ๚๔ตCยชทบkจฐtู๒v›:s๚Tา ›]บv จ”0้ํ fX็จ*–n่Hึใผชr๏Lœ$ ถ็ิ๎๕uู "๊5ตฟtXmฝfทฝl›u?ิฏ+ฯ?๛Œืกd+฿’ด+‚~„DLษ> jฆ %jฅBฺwx8ไฐใ�1‰๑)Sช”Œ3สžJ?ธชR5zตส:f(์˜†ึร}mzํ๗ฑั ๅiSแTง}ฟ๎“ญ๔_ƒn8Oทปแ5]NhEฤๆอšJŸ^QC9k๐ฑM�•(Ÿy๚)ัแฐurCv…๙Dำ`r�gžทแ]oึX_3�pl}{๗”fM›ุอมีHuฅ๗ึy๏๕ซ๓มืา oGS ื›๚?๕ค�}WTuTถบmปŽ�&8ผทys3t๔�€๛ำ๔ระำ&Kf3lธ†�J–นล?ฮ› "๎๘๑G้fชอบมL�็่แฃ6€ฌวix[‡หžb†r๖‚‚�๙�พ�ฺ„›฿�ยnrƒˆZWน:์v�6ญํvส๙™gŸ—6ญ”.>lืตj๓_๕ถSว๖าก�Cv}จ�ส‘#‡”.U"`่;ปs$ฆO๚ฟณA}� 8๚^ื๛2Ž^๏ุฑใถ"น���b "z๛hๅร'z๔๖��ญ๋ผ๘‚่๛:wา�๋{๒?��C™๗ ฅอ{C๏oKบํํw&†�ป ADW‘y@@ u DL]�Ek@@4'@1rป๔–๒ฬะ‘ฃ5pง๙f๛œู3ึgสœษTฟ๊ฐNฟ๕�ณฒ๗<“_ฬkB&Z-Q' !j ,งpรNŸnฺ`�ˆฏUนjีฉP@๏OรC"า)8ฒeใว�0HZ}@ซ„;…DLŠkj_ํS!ฐชm๎oพ%oŒz+Zำ� ขwn ส๖WXฤาษ บ/ญิง!9wr‡…vซMjภgๅฒลvWญ*\qLCIฃ��/\๊]OะJ^(OรZZ๕0xZ8oŽ\}๕ีvuณ{ZTวt๗๕B\ZษฑTู่*w฿”์๗บ:๏�s\ADw฿p}� q๎ซQปnpSโ\๗ต็ cุaศ r๛ํU์ึ!C‡หุ๑๖\ดpฎ\yETฅำค "บมฺ๎=zF จiๅีฮทฟkดบhลสทด)8ˆฆCฎ้ะkฑM,3+๊๗๘oฆ*aตw๘ปวถ-๘ZมCธ้kp้‡๏๛�ฅห๙็kฦ %๋~กช4บADญ4ุ��๛c| ฦu-o๛GkWIถ .7 ๋Ÿ{แ%™1sVภpึ^(๏š`cUS%u๐kฏฺS=ฺๅqYตzuิ�รไกถญํ�.–ฝ๚x—K–วฤ๔Il}�ถdนNŠ €œc)Dิ „ฏšัŠ.RWฟ|ฉ_ย ž4ˆxกฉZฏีแ๗˜ฟUd”O6n6รAoŠVนห?(h&� bR\S+—ฝ7{บ Ei„ต๊„lฏD,_แ6ป:ฌRญฆ�ะกk—Gฅuซ์y๋zt๏&-๎ปวฎ{qภ+2uฺ๔ ;๙hอJษ–-[@%Eญ๘ฆก.Bu�บี+$ปฉ๐ฉ“Dthบอ๋Oฏ/u�e—_ฆv๊๗ิำ2w�o1เ1œ bJ๖I@#อ‚.Œ+ˆ˜7 ชmะŠK—.“Oฬs}‹ถ6>S8ฏอ๘œ/ฆ}ฆLž่H็h�}๛๖๎e* F ฿TAฤ•ห—HŽK.ฑ—ัŠˆงM€U'๏นงy.หcื้๏uโญpƒh/[>z€��ื}๔*8๊: Y‡DึI‡dึ0ฐNมUE�k้๐nีอ๋?xrƒ•ก ึฏ'ท›Šฏนs็–œfุ่t้ำูS่ฒ7uฝDิ็V!Œฯคmึaโoบฉจฝๆ%G Iญวzืิj‰๚{J'7ˆ่Unญ^ญš 5ิ\�งŸญฤ๊ข๛๔{J,x฿๏VOีภไG,kึฌณฟ�๕นŸิSb๛$!ฯƒคพฮ‡ €œ‹ษDิ‘ F โฟืะ/๋9zTฮœ:๐�"ิอ๔๏ฟš/‘Wืห๋ ฝช†ม#?h?j1T๕Cญฆพb๙J™���8ป› bœD์€ €DฌAฤˆํ† €œSO?็ฮG๎j�TฒšP‡N฿๗ญ,œ�฿๋�ำฟ™S฿•Ÿ~ฺใ/๋Lอ;๊˜!2oฒ๋6o�(ซW,ุ แ„�PL|ฺ๎V�า�u๘R&)xาเส๊ตkeไศQqV๛ 7ˆ˜ื|๖™�vh'mwจ!]ฝ๛qƒˆ^เฏ�c]ไ–QC{แฤŽฺIว๖ํ์a^ภสญธ่คผs๋ใ�นณ์pฎ:๏งx่pP:้0ฟ" ž�ใผv้>ณfL“‚๒๏ใ๒ซู๛ตC8Aฤ”์“เถ†DLฌฯ‹ฯ=kซสทAƒss็อ7U5GวX C ็ต|p–—-๙ภปฯ๏ํj#tŠn8)‚ˆnˆฬปFl๚๛กIณ{†rwฯฑk๗.ัjฃ๑™š4พ[๚๕ํmwีขพึtZบx‘ไฮ•K๔Z ๎l0Œฒ{ญoพ�Vด2h๐4l่๋RนR%ปZ‡f๖†yำสŽใF๒ซŠ็.‡ช8๊�ฮ ’�=ึื0 xมV=tืฯ:๔—TชRีฎvƒˆ�ฐิ๎ก^8ฑdษ2a์h{ŒN๔ฮ;wฮLน๎ฺkฝE�Q‡ฒŸ8yrœ+�โ1“˜>ัำ'ไyfฑ  € €@ษDtฟ ๔ฑฉl๘ุใ��`กพํ๗d?Pจ_๒‰๏—ฤ�ฟ ,2_จ์ูปฏhๅลๆอšH�:uช๊หM๘0_�|RผX1ัปj RGŒะC=2๗฿฿ฃวŒ“a#Fz›xD@ˆp‚ˆ�A4@H๋SWgห–�V>ิoฟŸ:uJ† ~อฟ.?a�ˆ}ๆฬ2(jธJฃ™)Tธˆ�Qงž]ตs็2gf๔*w๎�gc>œฐ“[๕J�ธ�๎”ุ๏็ะก?e��…ทUลTk�@K)Zดˆ?Lณทƒ†€thุq�๖VE{ 7ˆจ'Hฬ5ตฒ�โE $cฦŒr๒ไIฉYป^ŒแฑPAฤวบt–[ตด๗[ั 2=๒hWฬ พ๙93งI��QมAฏ๊š�'nฐส=ึ=ฮ šน• ต �พ�ฟน‡E›_ฑbeŒรi‡DิงTŸ฿D8Aฤค๐ฉYฃšฒถญ�p}มเฆˆ�u|X>๛lkดmบ"œืfศฤseL3ฝรu๘nuำ)� ขW๙ะยฬญฉฟS_2ฬปT่G๓{Aภ๎ไั6mฺ,ญj๏nŽu�š๘ไ?�Hๅ*ีคt้า2lศ {ฬงŸ~&ดnpผ{ญ/พ๘R๎kู*`ป.hุฐt้Rvฝ๛๚}{�)Qขธ]ฏื[ปfญ�ฐ}‡:tศฎktWC�5�๒ม6ัž n๑อทFหศ7Fูใb๚กm]bB•:๔ฒN6\พrฅ่PpZอUง.ฑฟฯ�J’nั Bปฯฟ๎={ษโลK%ถ ขž[+ฝถ0•%sๆผT&mƒ๛c๚เ5`็8ำ'�ฉร}xว๑ˆ € pไ "บ๏3Nœ8!ต๊ิ๖���ฒุด้3ไ…—ข*€วuG๚พnเ+Q๛~�อทา��าทwOS9พ‰=๔Sแ}ญ๙rๅŒYณeํบd�˜ัRชT‰hง�๎๛m๖KVั6˜Cฉฐ@HSG?ัJ@@ อ DL}]�พใ#’๕�มŽื�?Tฅ�ลฃ]ทC/Ÿ6ร� <0ฺ]sm>iิ8๊ำฟ�๒‹L{wbด}ฮ๖ 7l2v�x2lDŒMr‡�ผ๙Syฐm�† uB ’”ปฅœิญ}‡�Vฉขdส5 ๖แร‡ฅยmท‡:ฤฎKHั;YBฎ้† ฿3U์ž๊�Œwบh๎พ^เ/พAฤง๚๕•ฦ๎ฒ็ ฎ4ๆ]hลาลถา‚_‹—*kW—)UJฦމ 'ญ\ตZ:›็d๐ไง๋ฝv้�จ7GH๙rๅtV�*nvE˜?ผ ขหJ–น%�G'wŸ7$œ bR๚heผŠ*H�บuคx๑b~ญŠ๑๐ฃQ!ฟเถ†๓ฺ >6œeท’Wiำ=�J<8ˆ8v๔›Rฦ๙trŸ[�๑[6~lวnQท}ผnฉ4›E๔ปReใ�|๑ฮ๋ัดาIปผMq>๊ฐjw5l`๗4xˆ�Tดจิจ^อ.?�ฬsั†Msฏตgฯฉ� ๊u๊^ศ "6nฺ�Voิ>_ผhกnZC€ญLภ1x˜b๗ธธ‚ˆoผ๙–ฉข๙–{ูh๓z_z:้ตhี:Z๐oำ†’-ˆ่5H‡ตซQฝบิ6[�*‰ก†ฑ๓ŽฉWฏŽ7k?๛tkŒม็„๖‰{pŸ๎ฑ ืช9ลK 8��:`eˆ…ชUoทฏoำ๎�ปๅ๓ฯฟ๔c|Lฬ5ร้ท๚;๎ชซฎ๔W9rิ�_ษ  €œ“ษDt฿๏๘๑GนณQิ฿b\hท2vl๏ล�ct��โŽ&ิ๓๔ํ�K–-[.ำgฮ๒Cส——7FF}ูJ‡f^bพะSฉRฉV5ชyจ๗z ‚ˆชภ„ €คN‚ˆฉณ฿h5 € f"ฆพฎ์d‚B™2eถ 6xฉŒ๘o�พ“dฯž�ฮkED ˆนS้2ๅ�ว�Y€IUตq�ฅ[a๙” I้้nฅAบ;iคคฉ…ฅปปAบป1่้�ฮ{†s9๗ฮฬ๎ฮlอ์�ฯ๓0๗t�ฮฝ—น�๛พTจHQ™uๆ๔๏ดa�ฝุ#โบุiแขล4x่N็ฅ‹?tทžNฑ€E++–-1j;CฉB%DT?�ซ|WA“ืปyใzŠ?>ฝ~�Z<ศจarูj38BD��ญ#ฌŸค�„Vฏ\*EM๗๎฿งฅสสแY์ด๙็๕2~็ฮ]*Uึ,ๆั�q%],ฦMjึจ&�Ž๗ŸH“ฆL•qw>fฯ˜&v�ึ‘‹ู ๔{bW†~+\ซoูบีZลH‡$ฃSฉUณ๕์�Ufฑ˜จbๅ*zฑwๅฺ4น™2iๅอใ+[*ทผz7zนUˆ8u๒สใkkkฝn๕�ด —.^HŸฅK+‡ฉ� aU๚œ๔{‘ซBฤฬ™3ั‚นณewlู5๑‡‰ฅฺ™Z‹…ถ%ห”72ช9ํ�ฑ&|O&ี5ฆ?eซ(ญ�ถWีๅ‘๛�(„Š๏ฝg๛?$$„ˆmZทคอlYTฮโr=่s ‹ˆ๚X*ฎปw&ๆfA4 ๕0yส4็?Aฯ2โ๎๎‰ัˆธz่m�ทo�šš6iljT๘‰ฃ‡ 3wิ—�ำี=ัฅ[ๅ|W๊z_ˆƒ€€D,a%Dผs๛•*Wมžnํ}�มƒิขeป:Ž2๔ฟฉ6m�B]บvwTMๆ๑wl�.ษAyEเ๘ฎ[้�„ i้๒4`เ ฮ2M8ฏ"!ขWm&    „ˆžตง์r—�.ณ(รQ๘,}ชPฉฒ,โ‡้บkๆ‚…‹๏[k^ฟœ:I[6�l๊ขพฐF๕aโ$2oงช;rุT๎ ],t๊ิ/TทAฃงฅ ˆุ๏ˆ‘ฃึgืป‡6Yใbแวoฟ�nWŸE%{vmงhัขษ2�วzkeๅ๊๕ล‹—BŒWฦิฟต.งƒ3fซอฉUหๆฒ[vK�แ�.ކ0๒‚#DิEg์บดBฅฏLbง~}๛P•ฏl็กUxตm๓Fรชrกช&ีงWbซ*(‘งu๗R,,ญ\ฅšiLี†-jฅHžœ๘Aณ0t๐ */ฌŸq`๑‹ˆœ…ฐ�๋๊ ทฑ฿uฑYdเlกอY.g๋dหfฃ.‡ufa ]ฝ6ญ#ฐ�ฎ]: wบตe5ถุัชu;ฃ YW._l\›V!โเRล ๅd}1ณ˜Y…�๛าW_V’IซQy:r‡ฌ๚`+#O��“.^บฌฒไQขYฏSE'‰%‹ุนห^พr%๕๋�ƒ] },.ดž7Uฟ�Š๚~฿[ถปq๓&ฑ�t3d E ๆส๘รGจh๑R2ฎ>๔๛็…„‘]#ณK;w๏ฆvํ;ษธ๚˜;keอ๚นL†ค‘�เลวกร>ฝ{R๕ช6ฑํ๊5๋จ๗๗}ีtŒฃซข7w๗ฤ๐mฤ•๓ภฺึด�[ต‡Q‘ภ@@@ 2M!ข๕oDG/Y-_บˆาฆI#Qฯ™7Ÿ†)ใ�’T์8ฑพ ลesฤ฿ัqฤ฿ปุJ9[+wjืชI=บ}'‹๕฿6๖์�._BZ"ฌ'4ฤฎ9„ˆvH   ^CBDฏู*L@@@"&=k_ ฐ˜PX.|๘เ�๖}ƒำี@IDAT๋/t๕๊eบ๏%J๔!๙ๆ�‚2dฬdX!บyใ:-^8฿X@ดจัจญp…หBFถ†ธw๗N:r๘,/Yบ,}žีๆ‚‘Œ�cGำ๋7ฏถžQ๎SyN[ทm#๖ฐu06‰ำุ๚[AS�ญXนš�ธ�%Mš”ฒ~žE“ส“O’$ิณwZปnƒฌช <|๘ึญ฿@‡ฃ{‚sฆŒฉ|ูฒ”+WY]X—ญ`s›ชฦะ๓็ฬข,Y2หฌำgฮศ�=z(๙_ธpัไ๚4ธc๊ฟฺu๋;Q๊sำ…EJ๐ง[เS!X�ศ"Gบ9>ท2ค�Lๆณ i�xz๒๘O*Uบ„!~%๓๙ƒญ6่ข@]0๙๒ๅK=v]น|…Š+"ญ๏ EDอKๅอ˜:ล`ฯbฤBœwโิ)Yœ&uj*^ผจt฿|UX๎ซ�ตอzขjซkTฏFฝ{ฺฌ>�๗฿ดw฿~:t๘ฐุ—�่ิ/ฟะ‰'e๕ฐ�}Žื๎ผz๕Jœปซ่ฬ™ณ๔ืซฟ่_a๕r“p›ฅw๙(#ป[ณv=�.ธ/ลนrไ *Uพ’ยN็็›จk๗ž๚ฆธ+ืฆฉก ถชน~อjŠ#บlตfํ:Zฒlนธ&ข฿uกค�Kj๔f"6iิ:ดo+ห๙ž1v�xบ}๛.•(Qฬ!rกUˆศ็ม†๕kคE.gN3fฬขหWฏP‚x (ฝธส ทํ้?K'\%� ีyฤm�"๊‚T๎ƒƒณk\‹๋๑๙=cึl:xเฅฯ๐ตm�Jบ:ๆ2~ษ4Uะ๗…๋ฤ�๐ษใ'TYธPVย]U7$„ˆบ ™�฿Y&ฌญ์�ต›bฦŠEอ„%พฬ™2ชแค๘>Oพ‚2ญปšk฿ฉณtฃซ๗ฅฮ9sๆ ™ำฆศ6บ y–ึจ^•Ž=*ฮ้อt�ยŠ'.ๅ๖อEตkึ4\ �0x(-^ฒิ˜ƒŠWˆ่สžจ1๙่สy ทs7!ขปไะ@@@ ขM!"3โ๘… �๒โL๑w๛Q๑�Caฝผqƒ๚ฦK9\ฎฏ6d•+[†ุ๓ยžฝ{้ึญ?ธ eศž*‹—ซbฦˆ!ำ�‚Q๑โฟ<่,่ฟ™�๚๋oดmวNส๗E๒อ[6kfgไ   �KBD๏�;ฬ@@@"=kYˆ˜็ญUร€f๖๊๏W4eยx๚็›[fUทpฑโBศesMสy,HŒ%Š�ง๊์�ณ[ˆV๖ฉควu‹Uึษ 6œ,\dส๎�ต ีฉ]ห”็(แHˆ่จžžืณฯ๗ดVทœ…ฒeJำC;,�ผe+u�ฎ›Qf–ˆฃ1u+GŽฅฦอZXZู'ƒ+D,/5Bบ‰ต๏�–ณc็.j/ฤฏzเu.^8RคHกg;Œ[…ˆluoข�x!"๕qX_e^พr%@!"ื[น| ฅ�๔Sีฤ8๒~2caฝ'ฦ$ดศฒ%‹(]Z› -[F+Uฎjrฟํ.%Dด๖ฏงY4ฺฐq3bAญณเ๊ต้ฌŸภ๒ูU4ปŒ,X…ˆผŸ�ถl4ฌƒ่ํY=บM�h"r=โ๕๛พลŽms{ฏทีใก!Dไyo฿บษ๛โฅK๔uUว๋๊9หbสฏชTืง.ญoฒุ-(!$„ˆ<Ž.ึถŽห.ๆ•ๅูดˆจ[ธดŽฉา�C‚+DTcXŽ๖Dฏใสy ทs7!ขปไะ@@@ ขm!"[/œ'^^Œ%^ฤ (ฌXตš๘ล”Qฅ๙๛M๗^ฝํ^^sTw‚ฟ๑๗{kเ๏~5kืตfหด�า�”ฉำษoผฟรzศ๐<"z�ž`F    ฉ@ˆ่Y�:mZ*Uช,ลยZ[Zบvํชฐถสฉ๛ๆ\น๓PB… ‡๊ƒ-ฌํ�ถ…N<กฒ<๖ุคq#i ฉ%ึTะญ^ฉ<>๒ไ�บu1,ป้el๕pฯ��4Qธ,bห~*Œ=’rdฯn๊_•]ฟqƒ&MžB์บ3ฐภ?่ืฉSK๔•โล‹g์๋ีว์๖ำ�1ืญYiฌญu�๖b= I�ดnI-š5%ถด็๛Eน eญ๐o!`อว๖ ขQร๚ฤ–๙AFก"ลMึุzรมํ}�็ฬูshผ�D‡xXPใ'ฌnๆฮ•ำ(gQ์naอAZ&หหdอจ$"�ถgnTฆt)รฒ›*็>ุŠรZaลRwปซส๕#๗ำฃ{71‡๔ัG๛bu=–{ขฯOลูา_�6ญ„EŠœยrง!ขc‘Vู •่ฮปชช<บร‡€๕่ึ>�<ณS๎๔ุฑใ4ฺoœa)า4 %แ๊ตiiไ$ŸฟMล}@ ีธ![ษ�"ฌคฒ๛aV!"็ฑๅผ!ƒ~0]ื?ฆฑย2gำฆ(ูวษคลCซH�ฒ๋็�๚Hห$๚ธ\ฦBนƒยชๆ�y M@นŒร‘C๛ฅeGโ\[€?็อž)๖'‹ฌ4ฦoรa���{wษ2�7พ&r‰๋L�ม�G์;p€บt้fบ–Ug,๒ฌ&\+Q&็ณuพ_ฝV2๋ืซ+ญ,VฏY�dั•๋้#GŒMณ็ุ\=s™ณภขbvๅn}๐ษ๗ๅ1bOx.ผ๎วOžPแข%d7พนrัดฉ“d\Y†aทุณgุ\ฌทmื‘vํูcr7ญฌ$rฃŠหSƒz๕คภ—-๋๏sl%qฤศQ&๋บzฌYณะ�Y3๕, อ=ั ๊y ทq7�ผYiASo๏ฬง^‡ใ๖๎6,Krš�Oโ�› ๎Ž้๊ž่๓ฐ>x๖�9ๅ/XDฏ‚8€€€@$% „ˆ�ทiฟƒ$… ็/˜~7.�.ึฅ๓ท๔E�LD๏ฝ—PE^ะ-!ขcwฬAuฉฬ๎œำ Wฮยy']นt‘�๘ใฯ\lฮŠE:™3g&ŸคI่๑ฃวt�๚M“E9GCฑ•9�1���ง?…๋แซืฎฺฦQ?ฎไน2fล ๅh๐e๗gฮžฃต‚fัฬ•๙V—ลrY2eข๘ โ‘ีๅt@my?|๓๘Jwแด{ศP[.caX๚๔iIจฌ„‹��t๑ย%—๛l U๎m{โ.Ÿฬ™3Qแช<~�xt๗ฮ=yฎ[ลŽŠ‰'Yภ–,y2:s๖ :๕ซp ^Y �xnŽ„ˆjฮ,\K.ฺืฬ9๑0ัีภœ>M๕ ={nป๗บำGPวไ๋d็๖-R$๚ฯ?� AžYฌ๗ฃ ๗๎฿OญZท“โ�|‚[ศ=rไH ืˆ~Ÿไk* +˜๚ุม‰'O–ŒาคI#„ถฑฅ˜X…ง฿€ฺ๒:ำ wฺ>>I(zดh๒rh�CBbOx�OPฯƒ€ึ2 PBDฝ๖๚ ฉ{ฯ^zVˆฤี฿ฆษ“}LOŸ>ง‹/*xไ๏ร>Iำ‰�—฿ฎ]ฟช฿‰๙{�aฉ� DดA@@@<›„ˆžฝ?˜€€€Dx"F๘-ฦฝœภ๔ฉ“ ห‚บ{i/_–WO{โ|๛*WชH1q=ๆจ๕a d�ถํŽŠLyA"šyxBwEฝcวNj฿ฉณำ;ฝ9ญŒ‚0!R{โสy& ร    ม l฿ฒ‰>/$๊a๙สU4เญuD=?2ฤี‹1บ๕t^ท฿๘ N-ถG.X#€€€xฝmว0_ˆ` DŒ`ŠๅD8ส /์๐ัฃn}�ธ ์‰ใ]ำYŽk8ฯฝw�>•n้ Eˆ˜3g้พ`��”3gvรตr“ฆ-ผฮuฦส"b`ฬPบ‚ณ'๎žกป"๔         เญ D๔ึรผA@@@ ‚€1‚l$– แL@dน:•ป๗๎QษาๅmQ„ˆ? FฅJ–0ญwๅ๊5๔}฿�ฆ€€€€€€€€€€€€€@ค'!bค?@@@ย—„ˆแหฃƒ€€€€€€€€€€€€€@p @ˆ\‚h    ," ƒ€€€€€€€€€€€€€@ธ€1�ทศMBฤศฝ�X=€€€€€€€D6;ถmฆD|`Z๖ฒ+ฉ�€Ly‘%/n\ฺฝsE�ดไฑใ�i๊ด้ฆ<$@@@@<—„ˆžป7˜€€€D "z�6ฟ/~๙๒ฝ๚๋•็O3 �ภ V์ุr์‡†ห‚:hฟพฝ)Wฮโœ~E5jี jณ๋eฬ&ŒkW็ูณgTฑrป�ฐศ๐ฆ= @@@@@<‰ภม}ป)Nœ8ฆ)ญ฿ฐ‘บ๗์eส ‰ฤ')?กOSงขไษ>ฆง>ฅซืฏำ‰'ƒิu๖์ู(uชT[ฬ๕ๆอ[t๑โEบq๓fฺบR)QขDดc๋&ป&SฆN'ฟ๑�v๙ศ๐L"zๆพ`V    i@ˆ่y[]ผD)J•:5ล—€ขEfL๐อ›7๔�๙sฺ&~พtแ‚‘ฏ"mฺwRั@{vmง“'NZ/ฌ+ฐxซ๎76qฺฎ�{่๔™3a=—ฦซ'ๆWฬ๙ผxฐm�v—ฺ†dๅ-›6O’$๔฿�Q�‚E่๙‹!ู}ˆ๖5{ฦ4โ)ฒๆศ"}็๑๕ฅฉ“'ุ๕๕ฯ?�Rฎ<_ุๅ‡EFP๖$sๆLT0~9น๓ๆ{๔พy�ต{์อc”.U‚>M๕)ฝ๗Š9โ�CศF@ ๚฿G๔Q๒d7N\9aถ|ทlษBบ~ํšฑvsE…?N&‹ุฒโธั#้๕›ืฮช†[พท‰>I ๋~=ขK/™ฆภ.นฏe—G�ร;[๘4ี'าrภ7่ท฿Oำฐแ?ัร‡M�จ�๘฿บUsส‘-%N’Xถ{๑โ%�–(>BSฆM7�เฯ๎ซTฎ,›G‰•rๅส!ใly๏ไษ“ช[y�ฝw/อ˜9�”ว Wวด๋@หะl๔์�‡ึฎ�`”ชนพ"ž={J๙๓ๅ#vแ}ไุ1:t๕�พ—pอ๚9ฝy�š>Lํฺw2ฺ๊‘๏:w๋ฬ%น๒:นฏ๓/า”ฉำ่ิฉ_๕ชฆxใ† จTษ”.]Zข(Q่ฬ้ณดnร*'ฤ“ูณg“uณๆศmjฃ_W�’ส ทRiRง&Ÿ$I่้ำงtQœ ซึฌฅeหWจjNฎZD ซ=แ ๗Cqbว–sO“6 }๐�๛2~MX7ฝ{๗žŒ๓๏[วN 7[Fˆธห‡…พ์ :3'J๔์๒ฯ?Ÿา›7…%อฝา’†>NH\›zฎฤ๙Zๆsร� ๅ5ฬ–?๒ๆ๑ฅไษ’I.ฟ��;๙Ÿ@์]|~5�า พษD�ืโฟt๙ 8pFŽฃW5ลูŠป๕ฮ”)#�/iRบ|ๅ*ืหๆ-�จ^=›ศwฮœ๙tH\/*Œ๕ลŠ[\�งศย$•-lษd๘C)Z๔hด}๛NZธhฑฉœ๎�ปธ๏fอšPษโลศวว‡b‹s๊๏�กGาษSงhัโฅt๘่Qc<>ว๛๖้iค™‘ฒฐrไศปz\แถฐดาณฯ๗F] ษ๋D๕้์˜Y�ŸะY�฿ภaแ’%”'wnส›ื—RฆHI|ฮ�~ๆ4อœ1�๎��œํ?p0]ฝvีแ๊:|๖โ9ต๏๐ญร:ศˆุB[ˆธnอJJ!ฌr4dจ�]'บeใz๙ท<็uฺ้6m�*‹๙๛^�~ถฟวŸ<๙“ -ฎ7ฃš5ชIฬœy๖�yช^ณ6๕้ีƒชWซ*พS�ฅ’eส๕•‡แ?ข9s็๙E D ŒสA@@@ภs @ˆ่น{ƒ™€€€@ค !ขwms๚ ฉ|ล/ๅคƒjู0z๔ิFธ{fฺ฿�MใวŽ๒จEฯ›=“>�† หT(,h�ถKW!(:n*๚LไๆฬšAqโฤ1ๅ๋‰ฑใ�iช#ชะนSjPฟžJx�ผe+u�ฎ›ฉŽ;cš:ะ„ฐp‚ฟŸฬน.D—*}ฅ•’qีซ๛)/ ฤœy๓i๘ˆ‘F•คI}ศœฅb.GEO#ฤร Gโชร†P้าฅ53ๅY…ˆ,ฎ8 ฏa�มT๙mbรฯฉ[^ŽŠŒฃ๋„ž ๗฿็…๕„lูฒ ƒ…Q„ลม‹๔uตšฒŒ?FKnฅK•”i�lูบ•ข‰5ง๛,ฐŽ˜JๆณฑBฅสvV#|' cAิ๕kืล˜œฤb&=X…ˆ๚vAตs๗nบt้ฒ�‹ย๒3็เศš„�ฏ+Bฤฐ�ž#‹ใ z๒๋~Š%[๚ผv๕šฬ็>‡y_๕>๊!๗wA์๕ aม๏มƒ”์ฃฉPก‚”0แ{d"็ฺิ็ํN\"ช๖ฏ^ฝขำงฯะใว)Eสาbฆ.Dดถa‹จGลu7^<*Wถ ๑ร>›6mฆ.�zจnๅq๓†u”๔Ie�๎ฝ{t๐เ!z_Xซd+’๊šแย"็�ีบU jูผ™œ+_วGฤ๙ZŽ;eขnถtส็S‹–md�เ๑š6ndค+T(O๑‹�ฤ’ช…ˆ“งLSIy ษ๋ฤิฑ“„#!"฿�ธ๕๙๚ๆ–{ฯMy�%…h’ุ’โ‚นณeœ๗ฑd้r2ฎŒ�iธธ“Yฃว๘ั๔™ณ๔bฤA@@@" ๕้�๙ TญFญ_uฃ†๕ฉS‡๖ฒ_�อaฐ๘~ทm�v๙BQ a�œฝp` ๕ๅ+šฏุฒiƒ๔ภๅK…W€้ำgสz�งg๗n”่ƒธˆBK–.฿�Kˆ๏๐รd[Qผ$~Oษ’% ลˆXฬXถย—๒e,ถ._ซfuชPพผ๘ํ#9๛{BD‰    เ• D๔สmรคA@@@ โ€ัs๗2uฺดTคh Š*Db๑…•.%ยโ฿ฝs‡ๆอ™คษทlำ�๊M์OO…(อS‹~�วูฌL›>ƒฦ๘pชบๅฝ#G ๗ย A 7\ฒhฅย9ึุ๗์�N๏ฝgณ~ฦ๘แƒุjึ้ำงM";ฝœใสป†ญ฿จ‰ตุ.crงบุๆ��TผTปฑt!bวฮ฿ษณฆOฅ9ฒหบlญด1oๆฮขย�y๒ษ2ถไถt๑BŠ-štk�กcg“ฅ„นณf ฑ“อŠฅ.ใฦ�N ญษ๔๑นฎ.Dไ1yฟขG.ว์�ตปœ3ืใ๐eฅ ๔ร€�2�HัŠณ‰$e†ๅร!bX๎‰ešR”ศ– 9ฐhฬ‘�qี&8||…kํiSmnƒูBhัโ๖ึ*Y๘ล็ƒณเ๊ต้ฌŸ ๆ[E…—._ฆฮยฒ้E!LU๋<๚œX์สaรบU”์ใd2ฮnวX4จ?p[ถdกผฒศตŽpW��oฟหโ*_Uฆ~ยช*‡;ย-q�†Œ๋พ�7u่ป.๏\๗†”18๗.v+\จ`9฿1cวัด3e\}ฐ[๋8ยzคี ฌ*็ฃบ†™Eถœ6Aณ^n‡ิubํืYฺ*Dœ0i2M˜8ูจฎฎqฮฐ–้๗�vยํ๒ฮ]ปŒv,F�น} ลŒS�๓๘�X%b4*!    )„ถ‘!๖�พ7}๕e%๙�šำฏ_ฟ6โœ~๑โ%ต๏๘-:|˜“Fเ—๛~฿หpํฬz���—–.[Nƒ‡�hดa‹โ�wดธ[ �๘U๙๚+ส-พช฿–ธlึ์9wQงˆ8€€€xฝkฟ0[ˆp D๔�-�"_สW  �ฏˆ7�W,7[ฐฒซ๔6#y๒TฝV™๚๓ษš6eขณช‘๏ชุ้๘‘ƒ๒G|ถ”Vฆ|%;wซ์ข“]urP.‹ิB>`ธoe๋l…ภีเช1$ฦไ9Ž๚้G*Qผธœ.‹sXˆc บQญOw[ช��๖์�UXDฐน&Uย@]|eตฌฦใ่nกuk“‰%ข[7ษฉผ|๙’๒ๆ/dš[”œ4๑ธTว•ุR ๅ-ZผTZ=45‰uซWPŠ)dvอฺuMึ1๕บJคฤ–sๅ๙B/ฒ‹‡ๅžXืื˜Qฏ๋*�% ํJ•ซ`J iWฏอ@; ค‚.Ddฑ\ญ:๕œ๎7wฅฯ๏ฌฐXฝfmป ์O•*ฺึฎ “วŒAลŠ•๕ ๛tcH ƒs๏า]ผ�0x(-^ฒิnญeธ*D ฉ๋$ฐyฉr]ˆ๘X�฿UX๕ ŸงN�"ฌyพณ๖จ฿ฟุโ ฑUจ๛Mmฺ๊ฅณLZหTA@@@"ฐ"๒ Qร…ทฬ™2:„ส/_๒K˜ŽO็๏๋Ž{่ัป๑•ชรGศŸŸ k‡o^ฟ5b kโiค๕CU็๖ทiีฺตด`แbป฿PT A@@@ภ๛@ˆ่}{†ƒ€€€@„"!ข็ngšด้„ีทโย"bTŠ;ลŠห˜์แ:s๎์า}ซ‘้ RณN]๚๘ญ…ฐฝ{vัก6หaชzD–.& ฬ""[ˆ[ฑ์ “]vช \ฉFnˆ’$N,ณฏ ทห+WQUhํชๅ”2eJ™fWค?�ผQX!8*�A ฒ…,W…ˆ!1ๆ')?ก•หKๆณgฯจT™๒็ซ ๓(,๋่ขรข%Jห‡;ดฃฦ H*…:,ุแภ.Z,ใ๚วพ�;(~�๘&KŠl%‘N 9๏ฎํ”@X๘ไ  u1—ฉ�T{ษy�๛่|กฯ๗�hีšต*i:บ"D ห=1MR$tqa`Bฤเ๐ัข<ถ�นeหV:$ฮ๕€ฌๆ้๓uๅฺิ�นื…f<ว†Mšุ•.>ใŠŽฮvฝฌฮง•ซืะ๗}m6ฬ›c<Tข]}ฐ^=บSอีdVHƒ{๏ะฟฏดชยb7k[ถlฃ‡ามC‡ํD๊๋ะใฎ Cโ:ัว,ฎ นาๆ๖'Ž’ึ\ฌโZถzธ]ขcวŽM��ทดžชฌ๊{�ถ]G“ฅืภๆ„rˆE ด…ˆ์ษ€ญ™+7ส�ฒ�ณ็ฯ้อฟฏ‰ฟ›จเ่E3�%*ฎw๋ึ-Š!ฌz'฿ม๙๏\์กY‹–&ซ๑œฯK;ฒ~ศ–ไทo�AหWฎโjฤƒB๐h"z๔๖`r    ๑ @ˆ่={์ใ“”พฎVƒโ ‘‡sgฯะบ5ฮ@fw;ํ„K]>ฒ ŸฑฃFx�b];้Bฅ ,ฬ๊’ถชpKฤn’ฌญฏํฺณ‡��'h�น*D ‰1uาœy๓i๘ˆ‘ึ%ศด.DT‚ฟฮ:Pƒ๚6WภJœุชesjีขนlฃ„ˆบลล๖:ำŽ;ํฦXณjฑ(’ƒjง‹‡ุอ/ปถฝšืYถdฅK›ฦZ�išือ๋w\"†ๅžX็๊Š1ธ|@+–ทNA ูV Q�„ISœZรเFฎ\›vƒธ‘ก_฿V๗฿Žบ๋�ณ;ีจn :*ทๆm฿พƒ:|�Efo��ณ!XึฯIีฆyณ&ิถu+™ !ขพ65F@G๋ฝ‹…Œ,จS ๕ถl rสิฉดi๓V=�.๎ช1$ฎปIก฿Kๆ/XHCด��k๗Žm”0แ{ฤ.ๅr๚š-Ÿ2ˆส•ตนฅS{ฆ @ญโลฆ‚"J ด…ˆ๊onฦwเเ!๊$พจd๘๏๋>ฝ{n’๙ล+๕’˜.d+�=z๗ฆM›ถศ]เ—ฬฦŽ๚‰ฒf�\ฆูฅsำๆญˆ-/ึชY*”/oฒ~ศ ถ ๑a๊4ฉ){ถlฤ/ํฐ ’=F๔ํ7ภ˜์L๛ะ็0e๊t๒๏ฏ•"     เษ D๔ไ�ม�@@@@ €ัป69~�ิคyK๙c5‹/�F�ไt ฆ<_ไ“ๅทฤฯ‹ๆฯuZืS \;}Yฉ�0ภfัŒ\Ÿฟภ�jŸพฎ'Oำ๊5๋๔,*Zด5nPŸฒdษlธiVXศnZงฯœฅฒ์Žฎ นƒเŒษ6mXK1…%ถ๔Uบ\Eงโ1GBฤNฺSฃ†๕ๅ:"๚EE ู�*;ณถb้"J“ฦ&TVไ๔=a๑"‹ญAoง‹พt‹kณ็ฬฅ;w๏Y›šา,$sๆN�!"wV{bZ€Hธ"D >ฅK• fM›R๚ฯาYง"‰อ[ตก'Nฺ•q†+ืฆร\ฬิลz'O!� “์A่ฒeภ]ป๗X�์ูsย๊aYว™•Nีป ็ฝโ DmชL�Ž?A 7Uู๒จ ฿taฎ~ธ{๏โพ;ดoG์v;n�8ฆq9ฑcื.j฿แ[ป|•กŠ๒}.[N_•เ18ืI€;(ิ…ˆณfฯกŸFฑซu๔ะŠ!ฌ�rะ๏%œ๖อ•‹ฆMต3gฤ^ืจU‡๔{โิiำi์8g@ˆ่ 2A@@@ภ+@ˆ่�„I‚€€€@ฤ%!ข๗ํm‹Vm)nผxrโฃFุ~จvดŠๆ-�Rผ๘ถzK/ ๋ย5ฑงWฤNบเฃGSฃฆปn hํl ๏yฉBนฒTธPAŠหๆ๛้ำงT p1งM•‰ล[๕5qZฯQ;c๊B�ตฌฃ�๕บJคT!โ๗}zQต*_หnูJ[คณ†ํ[6IK o�ผก์น๒ศb]�ณcงBuดBฉv�@อ‹ใ“&Žง|y๓rTZtP"1™แโ‡":ฒ”PWกฝ'ึฑ]"†$ŸคI}„ฐฐUชPžฒgฯfXแ`ซmฺูwึนบrmZ�บ“ึ…ˆ&N'ุM‹fMฉM๋–ฒฮไ)ำhœ�„๋๋…ซV,ฅOSฅ’Yสบง^ฎป/ท ํ฿#-ž:๕+ีmะPo&ฯg�7บ1$๏]�wฮœ9จ\™าTชTIรํ็ืฌ]ืฉUWw„ˆ�'wฎ~Xš=G6[o?ืฎ]oJ๋ ]ˆศ๒�฿๗ี‹e\ ?yB…‹–ฐ+ืญฏ2 ฟ1#ษวว‡๘žUฆ|ล ปฑถ๋8€ พž’'Ofิx๖์นC‹ฒF-bตXzโ๘Iงbkญ/^ฬ$Fฝ&�ฏ็๓1ฐเ๊ž่�…ว˜๎๒ =qwLo�wฯ�\B@@ย“@h ๕๏ฦ—._ฆฏชุD‚๚zซWซJ}z๕Y๚wฑ้S'S๎\9e>{เ๏ึฐyร:รฝ3�ญ+v,๊ีฃ;m�บ/]fˆ ไหG��dsvอผYXV,Tจ•(^\ๆ๕๋?ะกซfญฤ‘๏!!ข๗์f    ’„ˆ�ทญญ…P(Vฌุrโ~ฃG ท”�ุ-‚�8Sฟกฬ๕ื_ไ?ฮ�š”]#ศะลNŽ��ืงศb˜�{wษฌ'O�คBEm?ค๋u�‰๋Vฬธฝ#a’๊W ฒ$ ๊t ส˜ผ�อืS�๘๑ฅซํฏชิ ซืฎ:ํ68BD�ญ#ทธ์’y๕สฅ%Jบw�>•(UVฮƒn›ถ‰‹๎�นKฅสš]๋ํธ.Dไ‡&5kุ\๋Ž๗ŸH“ฆLuบถภ fฯ˜&v\/ 1V@�„ฦžXวำ…ก฿v้F[ถ:wง’|๔yิชYƒzv๏*ณXภTฑrฝุˆปrm‚qUˆศึG�hf+๗dA~สค ”7อ*`วฮ฿ ืe�MM๕rซ๑๐ฝRธ|�ฦ ชP้+Sปบ฿ิฆฎ]lVAu!bh�ปxp�dŸ๏๛ัช5kMsR‰นณf๎�๔๋P•๕”๋„๛j฿ถ55mาุิ-ปs&8ึ…ˆ—ฏ\กส_�๎ ชƒฬ™3ั‚นณeาู�—วใq9\ผxัฐเ๊๊๙!;โวฌ้S)GŽ์Fํ ŠกY„ญDซชqPต'Ž2ฤฤ�6จย|W๗Dอ‹a=fp๘„วžธ;ฆ7ํIpฮ�\B@@ย“@X ๏�พCฅสู,๊๋ี-ฏ๏?xZดl#‹งO™Dนs็’๑ƒ†ะ!,ด†];ถา๛ ส์j5jัน๓ฌUdšฟc๓wIส+วU๛ฅหWะ€ƒ8ห D4แ@@@@ผŠ„ˆ^ต]˜,€€€D<"zึžฒห�จQฃJ7ฉŽf๖Y๚ B์RYไšนj๕Z”๒“Odฝ฿~�…6ฝ‡9๊ำ“๒tQหฉSฟ cœ�าล ้ณtiev็;bไh‡๕ูฅ่aแฎ๕๙‹F9 Y~๛ํw#ญ",ฺณkปษอ‘�NีใใŽm›ฅฒ/^ 1^S�z=ฮ˜ญZ4งV-›หฎุ-q‡oปจnƒ#DิEgผvX=|๘ะง_฿>Tๅ+�yxเเ!j�า&๖แ �6oคฤ‰?”uปt๋N›„ลฺุ[}PA@้B2–VฎRอ4ฆjรฃR$ON� ฦY:xฑ‰[ฦcAณ–{bCฝo„ปุ.6ซ‘์|๔?k#\>ฮึษญF�4\Žs�๚uช๐ฅอฆ1๐�ˆซืฆตฝซiW…ˆ์๚์็uซฅuBห™Kqพพ ศG›6ฟ}ฒXEƒุJHซึํdœ?X<ปr๙bใ~`"๒˜�ฑดฒW๙๋๊&q๐สๅK(๕งŸสพt!"g็�ล{q[<ฬtt_Z.\ฆง}๋2�z�ษ‰ผ�3r+VTฆxฝผ๎€‚ณ๓'จ๗KWVบ‘็eใเRล ๅไ”ูฒbฯ>฿�MŸ็ถS< #†ฉฌg๏>ดv�S^H%� Ghึข@fึc‡Ox์‰ปcบz่็mX๏Ipฮ}�ˆƒ€€@xM!"�-ช^œไ5:zแI��}ฮผ๙4|ฤH‰C ํ๗ำgจVบ&L๚฿สฝ๘RปVM๊ัํ;ู^"๎ูน�{/9ฒุั DดA@@@ผ‡„ˆ�ณW˜)€€€DH"zึถ(\„|}๓ารˆ„Wฏ^ฆ๛๗๎QขD’o�/(CฦL†ๅฃ›7ฎำโ…๓. }ว.-z4๚๏ฟ�hา„q๔Rเ9lเA™ว ่ัฃหm�ถX่ฦ.’98xุ$Nหใ๋KS'ฟsมส๎ŒVฌ\M��ƒ’&MJY?ฯ"ฤ*ๅษ'Iาล'๊ก‹๋ึญ฿@‡ฃ{‚sฆŒฉ|ูฒ”+W9�ญ[ทจl…/e�ัว�9ณ(K–ฬฒ่๔™3R�๒่ัC)Jบpแขษ*Apวิ~ต๋ึw(ขิ็!"๗ร็V†๔Ÿษ.o�ผIใฦ๛ำ“วRฉา%„๑ๅ7ถฺ ‹uมไห—/i๔ุqtๅ๒!z*Bl}Oบ‘๓gLbฐg1โ !ฮ;q๊”l’&ujแ‚ดจtw{UX๎ณZH“•�~ิจ^z๗ดY}เk`๏พ�า๒ฺ›7�ัฉ_~!vฅอ!ฌ๗ไํ๔Œƒ�p็ีซWโ�]Egฮœฅฟ^�E�พ~mqr#w๙(#ป[#D[ฟ ๎K1Fฎ9จJ•ฏคฐ“๛�yใ&ฺ๊ฝ'GWฎM‡ธ้ช‘ปn�บฑ5O�@Ž-‡๐=แฯงRส”)‰๏e„๛โ8qโ˜ฌฐ%ฯ๕kVSŒถ๛ฮšต๋hษฒๅโพ›ˆz|ืลpyฦ�Z…ˆใ�ฦPก‚ธˆ˜ฏ�„‰2^ทNร*'gX…ˆ๎�ปธ/1ฆL‘œถ๏ุI;wํโว๋”,ูวTคP!ชT๑ฅถHส–I….฿vค๚๕l4ูช้าฅห้ๆญ›’�ฃ‡Mืtpฏ฿U•�p•�?{�\ uฏ‹ต–ึ/ซWตY๎ไ๋ปzอฺฆ{-ืWA\r^HZฯUc่Gwhมฺy“อี๓@ฑ Ÿ๐ุwวt—s๒ฆ๓@ํ+Ž   �BSˆศk[ด`.eฬA.“_^œ9kถฐ^}Œ$|7จoX(็ ๚๗j�e1.;~�อ˜=‡ž?}Fน}sQร๚๕ไw.;"๚k�ิ๖ย"งญA��๑๋ฏฟั6๑"฿yศ7wnYฎ™ญฤ๏'!ข๗๏!V   ^MBDฯฺ>"ๆษ๓E “z๕๗+š2a<�๓ฝ[f_ัพ ่‡รc!ด›1}J �yR…>ฝ{"๋ผ† N .2ew๏ฺ…๊ิฎeสs”p$DtTOฯc+[lmหY([ฆ4�8tฐรโอ[ถR็๏บeJฬcd8‰8SทbpไศQj�ฌ…“ึ๏ฒƒ+D,/5Bบ}ืซ9ถc็.j฿ัfัO•๐:/œG)RคPYNV!"[z›่?^ˆH}œถแGฎZญ tktz™n=-ฌ๗DŸ‡Š/[ฒˆาฅMฃ’ฆcฅสUM๖�ๅฃ„ˆฆฮ- 6l�ŒXP๋,ธzm:๋'(๙๎น_�ๅp@ใ่ึ@ธปงถ eตท u1ฉฃ๚*ฯ*Dไ|w๎]�NทฆศiGa๙ส•ิฏ�ŽŠd_ckV.7,H๊uw๋œœ๋D๕๋ชภส*DT�X,ํีงฏ5�H[๗ว™๋9ฃA0#๎ ะ‚#ด๓&šซ็ฺŽเ๐ =qwLw๙0'o:ิพโ  แM ด…ˆ์ฝažxy1VฌX.uลชีิท฿SaCQนฒeLyึฟฌSฃfโ ��ˆฟ฿[๗ซY�lmQีั�Žž2u:๙‰@@@@ผƒ„ˆ�ฑO˜%€€€DX"zึึฆN›–J•*Kq„˜+J”(v“c๋Oืฎ]ึปV9u฿�จi z��๗e�ํ[7ำ‰ใว์๚๑๔Œ&ษ�“๚๘PBa-@�qžคท�‘ผ[ท.†e7ฝœญ๎ูปŸ&Nšl๚~์่‘”#{vS�ช�๕7hาไ)ดzอ:•ๅ๔ศ?่ืฉSK๔•โล‹g์›#Œปcฎ[ณาX[๋ถํลz๖9*hำบ%ตhึ”ุาž๏6‹mสZแ฿Bภš;ํADฃ†๕ฉS‡๖าZก"ลM๎^ูzรม ๗ฒชo๎sฆฐศ0�฿f�Mๅซ# —�ฦŽฆ�นrช,i%r๗�ฝ/N\ส;—<๓ไ+h”ซทํูฃ•)]ŠุUน�ผyClลaญฐbนpัbฝศ.ฮ�๔่�Mฬ!}๔ัGฦพฐ•<�๕TX๎‰�$E[�k�ฆ•ฐH‘SX๎๔1,[ผหVจdgัฮ>�ฌGทn๔๙็™ํ˜๒œŽ;Nฃ�ฦ–"อSๅนzmชvฎ๕_์r]ฏ54nุ€7j(]Y�\๗ฯ;w;tใฮืLSq๏‰-šัŒ-่m–Yซ~mณj"rลฆMSkแ6]Yrๅร”็(q`๏nŠ7ŽQฤ�?๐�W๗D๏/ฌว Ÿ๐ุwว๔ฆ=แ๓ม�๓@?—๐$ „ˆ�›AฟƒไT.œฟ`๚� ธ๓ใ๏b]:K_ไอcื;Yˆ�ๆ/XhWฦ�ฝฆ‘๘ง�&ข*๎�-พำŒmzqM•9:vํา™Š /��˜ฝA์ูท†i๚�ฯํ ศOัcฤ _๑]พ^�odW":"Š<๐\"z๎�`f    )@ˆ่™�5jTJ•*5%๚0‘ำ$ค/^ะ-๑–;ปc~�ๆตgNฺfล"ญฬ™3“Oา$๔๘ัc!บ่๓leŽŒ�ƒ๗้Oแz˜�œฒX)4ƒ+cVฌPŽ�0PN็ฬูsTฃVะœšรพY,—%S&ŠŸ Y]N;l๐6“๗ร7ฏb#�c…�M`๚ิษ†eA�ฝดwฏสปg=qพ•+Uค˜ธsิ๚ฐฒm�vGEแž!bธO2‚Mภ‘ั%.Z0—ุฒ+g"Rw๚E๏'ฐ}ห&๚@ผจ‡ๅ+Wั€ทึ๕�ศgฑไฮํ[L–�y�~ใ'ษRwd`„5‚€€€€7€ัv sLBฤผนXZ„ -ž%I,ืr๘่ัฑ&o_๖ฤ๑๒ƒซ�{w9. $๗��๛TBธฅ๗ฤ!bุ๏Jp„ˆlE6ี'ฉจTฉ๔iชTr๒OŸ>ฅาe+„šEีฐ'„A@@@@@@@@@ภž„ˆ๖L    † D Cุ @"0เ๏�ปG%K—๓H:"†�ถGˆธu๓ฯ”$ฑMผอ3๓ๆ ๕๐ญXต:์‚A@@@@@@@@@ @ˆ†ฐ1€€€€€=ํ™ @@ภ=™3gขXnธf~๒๘1]ผtูฝACน•.Š4d(-Zผ4”GD๗E ฆ1ฃFH?ŽI๓, 2”ตซ–S๒ไษ้ีซWt๚๔Zบbญ]ป>ศํQ@@@@@@@@@ผ•„ˆ�บs˜7€€€D"Fฤ2@@@@@@@@@@@@@"-#ํึcแ    เ D๔Œ}ภ,@@@@@@@@@@@@@@ภ]"บKํ@@@@B„„ˆ!‚€€€€€€€€€€€€€€@ธ€1�ะc`&!"ฮ๐n"z๗�a๖    เ๕ D๔๚-ฤ@@@@@@@@@@@@@"9#๙ €ๅƒ€€€@x(h?@IDAT€1ผwใƒ€€€€€€€€€€€€€@๐@ˆ<~h     L" šƒ€€€€€€€€€€€€€@8€1œ7รƒ€€€@d'!bd?ฐ~o'!ขท๏ ๆ   ^NBD/฿@L@@@@@@@@@@@@@ า€1าŸ   แKBฤ๐ๅัA@@@@@@@@@@@@@ ธ D .Aดƒ…A@@@@@@@@@@@@@ � @ˆ๎[€ €€€€@ไ&!bไ�ฌ@@@@@@@"�6Sข>0-{ูŠ•ิภฆผศ’ˆ7.ํ�นขGnZ๒ุq�4uฺtS    žKBDฯ�ฬ @@@"=›฿?Œฟ|๙‚^�๕สๅษr�gOŸัฟ��ใr[4๐�ภ V์ุrย>๔่‰๗๋�›rๅฬ!ฮ้WTฃV™kฦ hย๘ฑv}={๖Œ*Vฎb—�ด'aมc€€€€€€€'8ธo7ล‰ว4ฅ๕6R๗žฝLy!‘๘$ๅ'”>C:Jšฤ‡._นBวŸ ็/^น๋ไษ’Q๖ู่�„ ้๎ฝ{t๖ฬyบzํj�ฅbขD‰hวึMvUงLN~ใ�ํ๒‘    เ™ D๔ฬ}มฌ@@@@ า€ั๓ถบx‰R”*ujŠ/E‹อ˜เ›7o่๙๓็ดM�0|้ย#฿)TธeอžbฤˆAQขD‘ลฏ_ฟฆ๗๏ำบตซ่๑ฃGึ&“f๑V�olโด]ป๗ะ้3g>I้›๚ ๅค=zH3งM1ภBรธ๑โษ4[„๛ใึMฃŒ#อZถo��\๔,Yด€n\gMัT1Œ,ฦส’9“ีว'‰a�-\บxษ4��‘๛ฺD‰�๐ž1C๚4ี'=ztบ!~ฬ�ํ๗ำ4l๘O๔๐แCS?*๑IสOจuซๆ”CX$Hœ$ฑl๗โลKบ#,Q>|„ฆL›Nw๎�Uีฅ๛฿*•mขD‰Jนrๅely๏ไษ“F=Ž์�ป—fฬœmสใ„ซcฺu e,Z0Wฎ™ณ๘ม? P]๓\_ ม้ณgO)พ|5jT:r์ :‚๚~฿‹ฒf�œ�ผ~Mฆvํ;ฉฆฆใw;‰uๆ’\y�ื๙‹iสิit๊ิฏฆบz‚‚”*Y‚าฅKKโ้ 9}–ึmุ@ๅ„x2{๖lฒjึน๕&F�๋ส_RYแV*M๊ิไ“$ =}๚”.Šsaีšตดl๙ ฃžณˆซรjOxพใ�ฦPœทฎนาคMCผ�พ\ฦ5a�๔๎�{ฦ’x฿:v๊์ะE—ป|X่หฎ ำ1sขDศฑ��๓)�ธySXา�Kใ�'ใs$$ฎMS‡.$๘Zๆsร� ๅ5\๙หJ”7/ฑ‹3v]๖๛๏ฟ“฿๘ ฤฎั๕ภ็WC๑ภ-ญเ›Lิ}-ฮ๑K—ฏะiไ่1zUS�๓`าฤ๑#Zt:|ไจœŸ฿้ำF��๛/;wึ��3อ๓w๒๘๚ส=I—&ธวฅhขฏห—/ำแฆ�™kzu่ํjTฏFUซ|%๗Ž�๑ž<~�„ฮ_ธ@?�ผ‘–ฏ\ฅWVœ]ีณE�?dๅชี๒แ๋็Ÿgกุฑbัa ๆธท6�4†บ_rๆาๅหi�†ฆr•่�ฉeฮd๛�ช�ภมt๕ฺUU„#€€€€€—M!โgโ{๐าลถ๏ฮ,ฎ\พ„R๚ฉคVฟQใ๏้ฬโ๗‘smฟ%X�/;C�งWช^ญช�๛ผd™๒F5ๅลa๘Oฃhฮ�yF~`#„r๐\"z๎�`f    )@ˆ่]�œ>CF*_๑K9้ปwnำผ9ณŒิoิ”>�๐C™�ตc;=rศ(ใH[!4‹๑ึMฯ„qc่ฏฟ�2•‡Wb�์™ฤ"‘ ,XธศTตhั"ิฟoCะe* ฃ|�ฅ+;v�Tฤๆฬšaธฌ6พMŒ็OS…Qก4จ_O% 1าจ”4ฉ๙๓ฃtBฬๅ(��ฯ?4B<ฬXธhฑ]๑ˆaCจt้Rv๙ึ ซ1žฐ�9p@_*Yข„ตช‘� DK�z๔2าŽ"ฎรrOxฎ๊Aฃy[๓*Uฎj:‡ YXPจ� กI\�k3 ฑ++]บ$6TVcQป4‹7Ž]ณBhึท฿#ฟU‹ๆิฌic)*62ต[mูบญ8ู๓€๗c��]Z๏ŽฃK…xvภภAv…M5ค6ญ[:+ ฉ�ด๋`7Wuฝz๕Š�๛๏?Š�VุชภึNุ๊‰5ธsp,า�iฤ0bNŽ /Yไ9w�ปb�%]กศ`Qiพ6—uŽส]อำ่2ฃXB€h ,ขnัชต!๔e!โเถ๓่ื_ฃ:๕X›๏๗ฮํ[คป;^/?เu&rทkŒ #šBD�N;R��ฬ_ฆlัฒ�๚�ฦŽข"… ษ�>฿๗“/�qขNํZิฝk™ฯโArเ—mn฿พc� +3฿~๔้�“ชWญ"^|F๙ •น�าำิษd�๚โ"gฒุpืž=ฒ�๚!ข•า    เ= D๔žฝยLA@@@ B€ั{ถ5mฺฯจtนrBT[Nzฯ๎]t๘เ~c๙๒ค/๒้'OKk‰ส�rฦL™ฉl๙Šฒ์ๅห—4q�Xฃ]xGุR–ปฅJ•JZ<ใ9]ผtIX๛z็บˆ๓–ฏXEงฯœแจ ,–[ฝb™!&dk`�w์๎ˆ .$ญoqล›ย:dน •m�~NŸ2‰r ห^ุชืQ!Tผ*ฌาฑ˜๓‹ผy(E๒ไาB�ค)S฿ถ ส—7//^Tฆูบ [เภ๛ึo๘Yฦีป]ฺดi‹Jสฃ;cš:ะ�@,pp$ะิ…ˆl๕Ž-ฑเ3ŠฐNศล?็ฯงlย’็]VฟฎVS–๑วˆ‡R้R%eš-!nูบ•ข‰5ง๛,}*๖‰‹+Tชlg5R zธ ขฎ_ปN9sๆด1Y…ˆฝ{v'>8ฐภj็๎�t้าeน%Š“นlะกดh๑RŽ: ฎรrOxฒ,Œวv ็ึ�K~8uํ๊5c=|ํZญถ‡zศฦ\{}โไ)z๐เ%๛่c*Tจ %L๘Y…ˆมน6…ธั…ˆช •>}FXา{L)Rฆ3u!ขต ๙ŽŠ๋-ล–+[F ษธฏM›6S—n=Tท๒่ฮyเHˆศ๗'ถะศี๕ษดn�^X�gŒษูBJดhัd๏‰ฒ[\œ๋ัฃG—๙๚๚Tc%DTiWžึ?K—ฮฐ6สe5kื5�/9ฯ๓€�ฑ�๔โฺ็ภ�‡l�ผ…?zLูล�CY8eq^๕šตลฝ๛ฒฌว๚รOพฆ๙>หŒ��๛oiฑ2�๙„๕ศ(o~�Xฃa0"บ‘ปแ�v‰{I�๘๑ฅ•Vล–-ึŽ๓๎�ย];ถา๛ ส‘ฟฎZ�ดฮฌ๗M๚ฎหทฒ|๗žฝR$*๘๐J๊oใs็/PตตBt l…�œํoอ#GQใฆอํ๚g๋๊�‡ัc�h๚ฬY2�ฉC{jิฐพŒ๓ห‚y๒๚Rฎ9ไ฿ณœy๗�=ฺ ~๘iิ;k๏ฅK•฿แmยว'O�฿ฃ/Q–,Y(FŒ่๒%ิฒพ”/ัฐu๙Z5ซS…๒ๅลo‰Lใส฿~@ˆจำ@@@@ผ‹„ˆ�ต_˜-€€€D8"z๎–ฆN›–Š-AQ…H,พpeษย7๎�น#ฌ!ฮTIใศ?žง–ซ8ฐ้ฯ?�VฤโJ N*…{—/›]ห๐ก�X?m๚ งฎIีTuห{�ใ~ป๖Mึt๑Œ�ร>ท฿ณs;ฝ๗žอU5sใ‡z`K‹งOŸ6‰์๔rŽ+A ุ•R`!$ฦไ1tWM๗๏? โฅสุ ญ ;v�Žถm�NณฆOฅ9ฒหบ�{๖’๎G๙แsgQa๎<๙d™.’bช:v6YJ˜;kฆp๋lณbiJฑธJYM›=g.9ฺ˜›>>g๊BD“๗‹EBู2Ÿ5 ุŸ*Uดญ�*าs็<ฐ k ม›.nไ๋aหฦ๕†ธ6Gn›ตžืŽm›)ัศ)Z-Qrๆ\แ6>kึฯeyฟ�i๙J�CLฮP๗~pXฎขYคจs›ฟ`! �q„์ƒ?�=tแq—ฎ�์Dƒl™๖็ukไฝ˜ญฏ,Rฬณ]›ึาU6g�ผquํ�ำ( ญˆ.D3vM›1ำ4ิฒ%‹ +ผบฅJ๛ฎXf๛ฟ๕��๛TขTYฃ]@eF%D@@@@ผŠ@h „๊Ÿใl‰›-rซะก]jาธ‘Jาšต๋จWŸพ2ญ{?เ �ป…๘>๐Tธ]N�๑วTบ๔ปหFŽC3gอ1๚ac�๙)‘ฐv๘ๆ๕แQ#ฆฐ$ŸFZ?T•๘eUkืา‚…‹ํ~CQu DT$p๏#!ข๗ํf    Š„ˆžปiาฆฃ"ลŠ ‹ˆQ)f์X+f,cฒ„Hb๎์า๊กสŒ5}Sฟ!}˜8ฑฬb๑ฮฟยส]แ๚3๚[๗Ÿl%qใ†utๆ๔;K`ชฝ'u1Q`uaฯ�[KP๎‡ฃ 7DI�๒ธ&�.Wฌ\ลจณvีrJ™2ฅLณ่ไ็Ÿ7ากรG…;่#&ซŠF% ช1$ฦ�DXผ\น|ฑ�<"J•)๏pพบ1_ยฒŽ.:,*ซ>คŽฺQใ† ไ๊T^ื.ฉ๎76!ืเก?ายE‹ํVฟo๗้JทคศVYดฤม‘€‘๓๗๎ฺN „…OบqฬศTฌXQ™ฯj?ี^r��>๚d่๓}?ZตfญJšŽฎรrOL“ ]\˜18|t(ฯญnูฒ•‰s�˜p•”เสต”�ซฃ ๊xŽ ›4 ฐ‰.žๅŠŽฮŸค�Kjธ&_นz }฿ืfa“๋ปs่BDv๏^R\‹ึ ‹๘” ˜๋จ{[,Yบœต™|(ษ'9ฐ{๘๑�:ช-ฏฑL…JF>GtkฉK—ฏ ๅ๎žบh’็๛Z|9จk“ฬVuแดnษ”�Oฺwเํ�ฝW�gญVhU๛เu!ข\๋}๊ื�ภAChษาeF๑ผู3ฅ {ฮh฿ฉ3ํุฑS–ฑKf>ว8่ึjd>@@@@ผ’€ ๒฿ฅ!ํš™Xล†[ถnฅ'โลค>>าโผM�~b"v้ึ6mฺbTื๛ฝu๋ฑ�e=ฐั‘๕Cถเพ}�ำKNz;=!ขNq๐."zื~aถ    แ@ˆ่=[๊ใ“”พฎVCบZๆYŸ;{†ึญyg%๋๋*ี)U๊ิrA=ค…๓ๆะ_�%ำyพศG๙ ’ย#๚๛ฆ„Hัำ‚+b']จ”uX]าฒหTvj ,–ูตg๙๛O ะทS‚   Cbฬ�๛าW_ฺฤGŽ�‡ช๕่BD%๘๋�ฉ5จosฌฤ‰ญZ6งV-šหfJ@ค[\ิล8ชo>ฎYตŒXษAตำ�žฒ›_v�l z;5/ฎฃ[)ณถq”>b$๑๚W„ˆaน'ึน๊‚จภ„ˆมๅ3xเชXั^(ว๗ˆUB”7aางึ0x�ฎ\›ึuบ“ึฏoซ๛oG�๕๎ูjTฏๆจศa�๖ํ;จรท]Œ2wฮ]ˆhu‹ฆ:๖;ŠŠ*$“์š™]4๋"jgํxฏxฯ8่ึQ8ญ๎;งN�JlMQz฿ŽฎAWฯ}๚8ฮโ|�dk”บศpีŠฅ๔iชTvMุญ�œy๓L–a์*น‘ก ๕{Œ๊ชQร๚ิฉC{™œ2u:๙๗WETฝZU๊ำซ‡Lณ‘๏ถlฺ@>I’ฏ๏หฏช™\Sห ๘๐:ก-Dd K/คฯาฅ ”�w้ˆaC ซ‡lq-ฏ๋�F็—…bลŠ%_Nอž+ฑ+่Z5ซS…๒ๅMึูƒม6!>L&5eฯ–ธ-{/`}๛ p๘R#!ขNq๐."zื~aถ    แ@ˆ่][?~jาผ%EUบ็๑�“ฑ€฿~'๓_ฟ~Mฦฑ~]MSู„Š'ฃm[7m=%โŠุIทดล?ฎฯ_`oตO_ื“'i๕šuz-Z„7จOYฒd6�4ซ ,8aทžำgฮRYvG% ช‘;ฮ˜lัlำ†ต3fL๚๛๏ฟฉtนŠNลcŽ„ˆ,พa‡€„ˆบxชmปŽR˜)i+–.ข4iาศe้M฿]ฤฃ5#ฝ.า-าฑลฑ;w๏้อ์โ,$sๆN�!"wV{b]„+BฤเSบT แ&ท)ฅ�,u*Rด�ผUโsูQpๅฺtิ�ี<]ˆ8q๒๒Ÿ0)ภ.t๎มC‡iื๎=ึ?{๖œ๊•\=t‘�/ฟ�*-า๊�q|๚”I”;w.™ญฎฅŒ2ะขsežณveห”ฆ‡–uฌ.ี}็๘๑ิ qSYG}&DไzฎœบEv 7jŒŸส๑Q�7 „ู๊j]aQ0qโํฺฑk8ู?๑ยฎฬŒภ„ˆญ[ต –อm6Y7�ทg'ลฺุk‘ข%ฤ�ๅ&ฟ1#ๅT1wgŽh    �ยBˆศซไ‹-Lษ>N&wธ~�:฿Y๎฿ปO�b ‡ฅลK–สxฏ�จf๊2พdูr๘ƒํ{ฬx๛ก?d+เuฟฉeด๙GX0฿#^ฎไถ{๖๎ฃSงPฎ\9๔ๆ2~๖�y๙‘]ศ€ัไ€€€€w€ั;๖ ณKBD๏�ฺญฺR\!’เ0jฤ0yŒ#�joูบŒ?}๚”ฆNzgแIfŠ,Ÿgn|m.@o�ธN‹:ถ&ง๊‡วัฑ“๎๘่ัใ๔๖๎^ฆ๚�ใ๘วž’ๅฏ�Re฿ฒf_Sศฒ๏QRฒต')น๖5…สNฒ๏ษช_*Tจ์!K"�็๓ฮqfป๗ฮฝ�;sฝฮใ๑3g?฿๓�ฮ�_3๓žฯทU�่‡n๎~4PTขd ฉUฃบ”+[ฦTะ�ีฒtนG‚j‚B "ฺ'‹ห5�แB๗ะM๖9�๎}ํภ_lƒˆ/๗{Qิ{�œNซ$hE:฿iๅฒ%ฆา‚Vุิ :+RDฦ๓ฦVญ^#�žyฮ๗0ฑำ vปt~๔จRชD ปrœYˆร?vQƒS…‹•Œ๕ฎuŸ๘6$” โี๔ษ–M‡+-ujี”‚ ˜ณถMซbtyบปo3อr(ฏอ€'qฅ;ˆ8rิซbใ˜hฯะก][้านฃูgฬุ๑๒Aิศh๗nclŸบ฿†๕kฬฉ๔หฤZz^3๎sปƒˆ:�›V ๔:๎ภฉU็1๗!f^‡Fื!าu๒ หูw…โbD4'ต�‰ํ๓เซ๕kญJผiญp๛E)R<๖ฏ'๛:๎Gm_•ส•ฅ†5\œปJโ0+เ,๔]ฑโ#ๆ๚๖y๖ํ�'Z 2ุไ"ฺีZ�๛บƒˆC†3พ๎ํผ,ื๕ o7tุ{๒`��V›+™] ซก์�็‹ํผoลาํ_๏ถvŸ3T๛XญšSฐP{ั<.X๐นืrฐ…ฤธf\}๔o�w�๎�ส้ำgœ!ท•Af๚š‘ึ'q}ะ'Ažp�ญNŒ็A$๕‰2ล๕ตื็lb๔I|ฎWŸฤxDRŸD�สekค $Tัํฃ๏์เŒ�ž”-Sฺlถดค :bPœ๑ษง๒๊๋žฯ}�็qWื๗๚ั‹/๔‘ๅหWศ'Ÿอt~ฐXบT)ๅ๙1‘อผิโนlูาRฉbEsบ`�}Kัญอ< € Y#ซฟh- € ไ"F^—vถ‚Biา�`>|ุPซ2โน๙–[คUฯ/้�:mG๙ ,(+W3ว>|H>š2)์n�vš>ใyํท‚ถัๆ9y๒””ญเ๙ =่ฑ�เ๒่!‚,๖ฉ์@Pt•์}ฃ{Œอ5๕~—.�\างO/Z๕๒ฑz ฃ4>Aฤ๖ํฺHืฮL“ ‹ซC2ฯ›๓™๊๛ศัฃRฉJuณฏ›–~แ ฒ:tXชT๗ ุ}œเ"๊—&z†ึ5JFgฮ—ฆLovzlฃ&อbb;ะ5ฎEŸ๘^ว }ฎgoYถ|น๏.ฮ๒ี๔qNjอ4nิP๚๖้eViภซv�z๎อฮ|(ฏM็ xฬ„Dิ*C�๒|Aงรk˜๕jLั=�ƒ4๔ZนZM็ ?๛ฺkWญŒo2‹๎็ป๕๘`วน‡c{�อทeฺ๔๖)ก™ใDtNhอD๗ภท+่6 ›|๗���ป™y ญ[ณา|! +�ึ๛๎ผjลRษd…@ฯž=g…๑ชy฿w_]Žฯ5�UtXโ๎ฯ๕ t g]|‚ˆ๎ะ™šiลถใว;็ะฟŸิ{ฬ๓<�jใ&i฿ฑณณmลาลฮ๐ซ={๗‘%Vล{๊๗โ ๒Dƒ๚๖ขWั$ำ`i�z ผฎiคb๎ผใูฐqฃฝส๏๑ื^•šVล5ด2žz‚M ู'พmhn U๛|OOีHญงUแ‚M๑๕ vŸZ‰fุ;o›หซ๊งC}mปุฎw๙›Šˆ:„๐ ็ษ 7xBฺ๎Š"๎k๊๋ปt้Rฒdฉw่3˜Ott›]Qฏแ�‡๕L๚ฟ�’นผ#ฎC˜�ำิษ“Dซบ๊4๕ฃi๒ึw์MฆRแยysฬ์บฒEซ6^Cf�่ธƒ�gtฯw6ะ5ํ†k%ฅฟN’={ถW‰๖หiำฌ์ื๏ฅพ๒D}O๐u��…๒าห�ใ�3ก†�AD฿jต๚๗c�œ™fH< tWฏUG44ํ;}:cš฿ๆณๆฬ‘_๑�๕ช,ว'8ช�เธ†\๔๘„พf||#XืkFRŸฤ็yWŸฤxะ'๖_Œภ‰ั'๑นfB�ํŠฯ๋$ฎฯฝ๘๘$ฦk3’๚$๐ซ€ต‘.XAD}1zd”๓~ ะ �?hา aำๆOy}vแ�ัแ#GคrีAปขIใF๒B๏็อv๗g๋Vฏ”›nส ŸZีฟ๚บ฿๑�HX €DŒAฤˆ้*Š €$M‚ˆแีฏฅห•—bลJศ๑cวไปoฟ‘_�YŽZ,gสtซ+QR๒��€Sสwxๅ6ํ:สMึ/ฺu:{๖ŒhH๏˜UญN' ษ=TเJE i}(�๘�l ทถm�ส„Dด]หWฌ บi%*พฺธู+œVผX17ๆสฌ:ด์์9๓ไƒXažl๒ะƒ๙ฅถ5�lึ,Yฤ]หiธnแ็‹d๓ึmrฤr~เ�๛ฅf๕๊RคH!sฝ฿�� ชx†่4+|�๙๘รษ’?>ณ๖๛]ปLๅญ?�<.�ฝ{†ี>$พืt�š4kแ๕E„} ๗c|‚ˆzบ;ož๛ฬ)5D๕มˆ(9yโ”TฉZษ !^JถCว.^ก@w`๒�นs2์�ไ—Ÿ‘G)oชฎน�่ฎง๋'Žุ๋kqขฮ�พsง9$WฮœRฑb3|๓ฏVๅพบ{ช'š>�4|ขผิืS๕AฟธY�ๅั*y—.]–฿|ใ„บบO|š)๎/wด ฦ์9seืฎไ๏๓หE+$ๅq๊ฑq๕ฑCŒ{�Yๆ[Cฏ�ฯ เžณฎQคP!ฉW๏1์ิ๓ฑx‰๔๊ำWgNกผ6ž „•ก๕ิZลSซy๊คAm�RM�&œ๚๋”�uื]ข/ชUฉ,iญ`œ๛Kธธ>์ใฬญ๔น6q๒ู๘ี&ษ“๗>ำ —๋๔๖ก๒แG›y�ว�ำeญปrๅjน5หญ๒ฬำ]%kึฌบZ�โDŒ๋๓@๏sั็๓Mลm“>&Nœ,?�๚‹dH—A๒X'jXรฺ็น๏^kุb๏ฐž†>Q_ถl�j=ฟ–สOปญกฉำ�(E‹‘&9C.ฟ๒ฺ๒ษงŸ้้�ฆPC ๎ ขžL‡‰�์ณY’>C:yถ[7ษ๖ูฬ5VฌX)ฯ๔๐|)๋{QwHุ�›ฟป๖พก>ฦ'8ช�ถธ†\๔๘„พf||#XืkFRŸฤ็yWŸฤxะ'๖_Œภ‰ั'๑นfB�ํŠฯ๋$ฎฯฝ๘๘$ฦk3’๚$๐ซ€ต‘.AD}๕ํท฿ษ๊5kๅฤ‰’#ว=ๆฝ€�@F'}QฏACฏ๓่z�A“�ฐIงSง�2?ฐ�ป๗g)RธดiำJRงJeถŸ0Q�>ยฬ๚ว�™‰ถcลชีRชdq)Vดจูก™ฉฑ@ˆl‚ˆ‘�ด@ˆx‚ˆแี…D,^ผdŒ:�ฯy;r„\ธpมูWรŠอ[ถv‚ŠบA+>i…ลdษ’9๛ํูณ[ๆอž้,‡�ŒปJ–o�|‡(ีํ}z๕”ฆM๛๎๊ท(ˆ่ท“ฯŠพ�^–Vp+ุTฝZUy๋ืn^บlน๔xพทณอ7ดไl๐™ tMwƒ-[ถJ๋v|Ž๒_ŒoQ‡.๖๎3$ฉ�ู=k4เำํOE?{ฝฯOฆ$w�้ฉพiฏ๔่Dิช{ฃขF˜Šp๖ทื��ห/ัu?฿0’}ฌ๖ง๋”ะ}bทม�8๓ำro๎\๎Uฮ|บ๕ฝ†฿Žซ@sN`FCฃ-[ท‹v๋P_›.๋Uq "๊ษงNžhUy0ฦ๋ "ฦt๏k3ถฯ ๎=V๏ ฟำkˆZฟ 6iŸtฺ๊Mถm๛ฺk—๘ฝNๆณ์y Fผ�ฯฉ8้s˜ณ(ˆhน๎์ไ3ำ๋9ิBฐืพ๛ฒงOŸถž๏mฝยโ๎ํฺท+—/q๎wฯ�ฝ๒x�†๎]ฎ๊||‚#ก๚ุ kศEO่kฦว'1‚5qฝf$๕I|žq๕IŒ็}b�ล�˜}Ÿk&๔฿ฎ๘ผNโ๚�‹Obผ6#ฉOฟ X้ Dด��=ี?ึ็9ฏฟ�ฆฬœ=วoณ�กE € €ภu%@1ผบ;g๎�RฅJuIk… �แAป•๚k๙}๛~•ฯ็ฯ 8|s๖�n—ตjKฦŒ7�‡8�^�Wถ๏ุ&kVฎpึ…๋L›ึญคF๕j’อช –1ใMN3๛$ณ็ฮs–ํ�ผw๏žNe7{ฝ>jีรu๋7ศจัcผ†}ุP)Tฐ ื๙ํใ๖8 ฃวŒ")ฆI?ะoฺดฑuฎ’.]:ง฿ๆ/X(/๖๓j4ฎื\8Žsoญ`าบ๕_ฦิ,้านฃthืVดา^ฑ’ฅอ�vตB�ยฃhqฯญZถgปw3ไส–ฏ่5ผ๔�y๓ส๋ฏ –œ9rx]Oฯ9iส‡2"j”ืz{AC<ร฿&E‹ถW™*‘kืฏ๗TC+Zฤ<‹—*ใlทg๔ุพ/๔–jUซ8Cำฺ�ดาคVqX`Uฑิ rัMzž๚๔ถฺPHฒgฯ๎๔‹๏ะS ู'ฺซCืvําษชHQุช�™ีT๋ำ�‚ Ÿ๛๎อm วี[|0ŸŸฉ^Kƒnร†เTŠิuมฆP_›มฮำz๗_C†z=ถS๋–OI๋V-อPcพว�j��\ฝzญ่9�S\žฺ๖ะฬjจฯฯ"ึs���ญฏฟ�๊+ู้ณทื๋ส}�žฯ=#ญแา์Š&๖ถ~�I๚ผะืฏ2Šn฿ดa ศญ฿ฐA:u~ฺ>ฤQดธ>่“€O9geb<"ฉOโ๓ฺŒ๋s61๚$ฎืŒOb<"ฉOœ)3IJภ"๊gฟj๎m๗Oปฝ>7ˆ๏ ปGQฐฯฅ๏๕~ฑ~\๗ฺ๋oYฃ3lตW๛=๊๛กC฿–ข…‹x�๗ฌพฯะ>๊็#gฮž๕;.ะŠ^={HEk”}oฌฃAฌ๛๒Ky๛ํก~ว—)�ฐคดช-ณ�ื4o๖ค9Aฤ@ขฌC@ยW€ b๘๖ -C@ฎ ‚ˆแูอุธ็žœ’้ึLV˜&ฃ5ิ๒Y๙�W‡c�๗าฟ16:รMฌกH๏‘,V๏ฬ=vฟu์‹๔๔ƒ๚|๙๒IึlYไฤŸ'd��฿ผ*สบ?ญ2งฦ฿|หอrสz๘ื}๛c<&ะyBYส5kืช!ฏฝ2ุœ~ื?JรฦMCนิUูWรr๙xภ m๊;ไttะ�(Vผ˜ Em�jฃ฿—ัซ�4๘”'Onฑ’]r๐เAูณ{oศ็ˆ้๖๖H๋“ธ๚ไห๗€dฑ†*OŸ>>tฤ<ื:l3$ฉGญ"’7O^ษ` ษ{่เaูg��Œ้^Cyธƒˆv(Pื•ฒยษZญvห–-ฑ~พjH0ทUS‡?฿พcGฌ‹k‡ล๗y ว็ธ็n9m��ๅท •ํ๖ฉหฝึะอYณf‘”VˆQ‡{ฟVฏg;ˆจ_สjๅK40žฮz์ุฑ3ฦ็€๎ฏํ]ฝr™ ๎^ธpQสU๐i๋>L € €‘-`�w๑๙ขลาง๏‹๎U๑žื๗%นsๆ’[nฝลผ�d�€'ิฉ ๕รว;๎ธ]๘M~ฒ~ด�b(ืั๗�ซฌชเพAD_–@@๐ ˆ��C๋@@$/@1ษw17แฦq* บ‡—Ž๐�Š่ๆำ'มปฏnฺ’:Mšเ;ูrฬชBฒbลส [รsu  bxถ๔๚jU  bจ}๛๔’ฦbไ5ญ~=ุr € €@B DLHmฎ… € เ'@ั„„•€Vฬš%ณiStร6…Uฃ“xc่“ภ์ๆ�#๘ฺ#GJ%kX๚Hš�๗kWDŒค๖'ีถฦ5ˆXธp!)Tฐ ”y๘a)\ธ 3ฤv›ถข2/ฉ:r_ € € € € y#ฏฯh1 € ค"&ฉ๎ไf@Dp๓Bmฤแ#Gคrีก–จ๛ป๏— bขv…ืลใD|็ํ7ฅJๅJ�็š7_^๎?ะk  € € € € €@ธ D ืžก] € €ภu"@๑:้hnH|๙4qš๙ไ‰ฒg๏ฯ ะยซw "ฎ^นLt่ฒๅึฐา=ž๏}๕Nฮ™โ,0m๊น��ผขร}‡Resะภ�๒hํZr้า%๓\\ณfญ5 ]Tœ�ม € € € € €@B DLhqฎ‡ € เ%@ั‹ƒ@@@@@@@ โ"F\—ั`@@ i DLZ�ษ� € € € € € € €ภ๕'@๑๚๋s๎@+‚ˆaี4@@@@@@Y€ bศd€ € p5"^MMฮ… € € € € € €$ผAฤ„7็Š € €.‚ˆ. f@@@@@@@ ˆF“@@ค$@1)๕&๗‚ € € € € € €ืฃAฤ๋ฑืนg@@ Œ"†Qgะ@@@@@@@ ใ€ฦ! € €WO€ โีณไL € € € € € € €@bDL uฎ‰ € เDt(˜A@@@@@@"R€ bDvF@’ŽAฤคำ—�  € € € € € €\Ÿฏฯ~็ฎ@@ฐ ˆ6]AC@@@@@@@8 DŒ!€ €\-‚ˆWK’๓ € € € €D‚ภชK%ำ-ทx5uๆ์92pะ+^๋ฎ—…t7�(kWฏ”)Sz�๒๛Dษธ๑ผึฑ€ € พรทoh € p]D �nพู๚`��นณr�๏๓!7V=๑็Ÿ!ว‘% _คนแำ่ใว‡uใ๔IŠ.d=งฯKรฦMฏJ[๏ฯ›WFŽx฿๏\งOŸ–ฺu๋๙ญOˆ‘ิ' แ๎ืx๓๕WฅD๑b~อ5fœLŸ๑‰฿zV € € €@d l�rญคM›ึ๋&>_ดX๚๔}ัk�ีZธ๛ฎปๅถ์�gNทaใฦN[บT)นt้’์?p@�๖[Hวฦv็L™2ษชๅK�v;n‚ ๅทž € €แ)@1<๛…V!€ €ืAฤ๐๋๊Š•ชศ=9sJ๚t$EสN๕C็3gฮศ ๋ƒแฝปw;๋}gชืฌ-น๏ฝฯ�Š=Yฒdๆร๊ฟ�>'฿}๛ฌ[ณฺw๗ฐZึ๐Vณ'=แด5kืษ๗ปv…U๛|ำ�j๋V›ฺณGVฌX้ป9ม–—-Y$Yณd‘ห—/หรeสห™ณg์ฺก^hสฤ๑Rฐ`sุC…Іzxภ�‹+&ใฦŒ๔�vแยE)Rผค฿๚„X›>ษ—๏)๓๐รฆ9S?๚8ฌ๛-า^›ก๖๑ค๑cฅฐ๕F+Q#G๛ฎf@@"\ภ";v\�Wq๕�>Xะ/[ถฌาถukyดN-'ภจ๏๔=Ctำใu•๎�Ÿ๖ชพจ๏Uฟ�jƒ<�ํู ‡๊{ฐa๏พc~ศ็ฎRxไ่Qy๓ญทeษาๅ~ว๊1E‹•ฌYณศžฝ{e�ถฏ�๖‰nEฉ%$uš4ๆš-Ÿjnv%ˆ�@@๐ ˆ~}B‹@@๋J€ b๘uw็nฯHšิiขmุŽํ�dลฒฅ~๛ดํะY2dศเท�^๑ฃ์[ธ`ฎฝveJ?,Qx*�Ÿ0Q�>"์ฺ่nะฮฏท˜ลํ�wH‹Vm�›lพQร๒โ }ฬ๕ถl�&ญ�ถOฐkวๅBื"ˆจ_ถิฎ]ำiNงŽฬ—<‰DŒmŸ<๗Lwฑฟ�้ะฑ‹„Zรนแ˜‰ดืfจ$fอ‘ใnsุC>(ujื2๓C•d@@"Cภ"�๘ำniะฐqะFk%ร๖ํZKตjU%uชT^๛ลาk๘D้�ง—$Ož�๋8{a็ฮoคCง.~?Jำ๗ธ“ฌ๑ๅน๏^{Wฏว‹/สหส‚…‹œ๕5kT3Ÿ ธ?า0bฯ็{[กฤŸ�b3SฎL๙`๘0ณkL๗›๓ฑ € €@ย DL8kฎ„ € @€ b”D^ฅAฤษSศ1๋W๎‡’“'OJ๖�ห.ู๏ธ]nL{ฃiVพ›๙้tูฟoŸำฺG*V–‚…‹˜ๅ‹��+[6}eถ็ฬ•K .๊|๐ฝไ‹ฯMuD็ภ0š‰ดฐS8ฬ%w�u—้ลฮ]ปษบ๕_†Q๚7ๅZ}ฏ2�ใฉ๒ภ�y%ฑ‚ˆฑํ‚ˆพ=ห*”—๗ญส#:D >ก € €\mุฟX8Onปํถ€—.คงaยี+—I๊ิฉอฑ7m–ๅึH oบษ 6ถ•TฉRš๕#G‘‘ฃฦxฟWฯึhMฬบs็ฮษkxd!ฃf๕jฮงOŸ–‡หV0๛ไส™CfL๛ศน–๛d?�๒‹ิ}ผ{UŒ๓c$b@@ l"†mืะ0@@เ๚ ˆ~�œึ๚ฐ๚\กu๋ึk 9sๆ2�้งdม�9ฮ tํ�œ๕Aถ็ื๙ำฆN‘ƒ�pถ�uื=Rฟa#ณฌว)“ฦ;�ยi† bhฝQ�ชศ๐ึฏ™ƒv�๐ฃ4l์ึ:ดณ$์�I=ˆJŸDLุ็^lฏF1ถR์‡ € €@ไ „D�็ย๙|ัข? ีแ–uŠ.ˆุ�ษฆ๒|ฯ็ฬ~Z™๐๑๚ อผ�3์ทฅbลGฬ๒�คVวœm:ณ|้’%sfณnภภม2kŽgd‹L™2ษชๅKœ}๛$ณ็ฮ“gฌกŸ[ท|J.]บ$ฝ^่+๋ื}):ถ—อ›™};u~Zึoุเำ Aฤ˜„ุŽ €„ฏAฤ๐ํZ† €\#ซ›ณfอ&Oถhi�็Ÿวeา๘ฑฮ <�ณท™?sๆดŒ้?คqปŽ%}๚ ๆC๓(kˆ�๙ว961g4Œ•?฿ฆ Yณfqช๛�๓OูปgฏWำ๔C�@รื๊‡๑๚ม๛�y๓JŽ{๎–”)Sส๋ร�๏�๗ฝผ๙๖;r�๘qฏ๓ุ :ฤR็NํฅP’9Kfs�ูณ็ไU‰r๓ๆ-2v�9t่ฐฝป�ท^�บf9YฒไRคH!3ฏ•๗v์ุแ์ง3kืฏ—‰“ฆxญำ…Pฏ้wืŠำฆš{ึU}_๊็5,“Uฌm�ื๚"โ๔้ฟไแRฅLUฬ-�ถษo ‘�/ฟ(=๔ \ฒชgn�ผYž๎๖ฌ๋ฬWfŸ๏๑ฌuŸEŒซ�งž๋ง={ฌ/\ฦหฮ฿^ูัgNฟฉRน’�{on‘dษdื๗?ศยE‹ค†ž,Xฐ€ู๛กBE}Ž๒,๊—:ีญaฅrๅฬ)Yณd‘ฟ�๚K๖Xฯ…น๓ศฬYณใ^jEฤ„๊mใˆแ๏Iฺn0ออ•;—�r๓อf~ŸU�๔๐แ#f^�ั~{ๆู~Ct้ถธ๚hะW‡‚ฮe…™3eบEO%งN�%~๛อชคน^FD2๋์ฎฦkำ>Wlต/๚๖ํevŸ9s–,Yบ�๋PBนM›–fV ัaั}'๚,ทU ๖ไฉ“๒l^ๆ นRฅJJม™ฐ๖a๋5ญฯล`Cฟ'D๑‰๕อkแฒ\–QฃฦJ“& ฅ€๕wHฟl<๘วA๙ๆป๏ไญ!๏x��ั๛��ป’ฮชŒ{ๆ�ู ฏYญ†bืพc็ฮ ๗้๋ฦ2 € €ื“@lƒˆQผ/ฟ��ป๓๙@ว๖ํฌฯ:ช่‚ˆำ>๚P๒=pฟู๏ต7�’้3>1๓w�~ปแ"mฺดw›ถd๓ึญfน|นr2�ฝกf�๐แรRนZMgฟ�/ฟ$๕ฟZ�ฒeซดnืA๚ฝ๘‚่{ ฿�ํQ�~็]๙p๊Gฮybš!ˆ“�@@๐ ˆพ}Cห@@๋B€ bdusžผ๗Kอฺž_�>tP>๚pฒน์ูณKใ'[˜y๗z๗�๑ฉฅ-nIDAT5jฺ�Nh�œูฒ{๗๎อ‰6�ั”I๒เƒ๙cu�ื฿|[ฆMŸแตฏ††๖๏็บผ6Z h|ฎg/ูถํkฏM๗Yน'O๗‡�^;X ๏%ใฌ0ข=๕xถป<ีขนฝํใาeหฅว๓žpจฝc\ฎi๋๛Xฺ ŽŒnVช  ยๆอž๔=,่๒‡},o๑|ูก;eห–Uข>.๗Zaน@“Vƒb}™a™โ�gศ›ฏKีชU�ซฮ๛u่ชมƒ๚KๅJ•๎ฏ+}ฑXzฟ๐bะํบ!” bB๖‰ถอ�"H็cš๊ิญ/ฟ๎๛ีู->>@ิ`atSณงZz…Kใ๛ฺŒ๎Zมถนฟ๐าืžพ�“Oฆร”้4p๐ซƒฉ3?ažท��ท่๋ฐNํZ๎S8๓*U RNˆ ข๏ˆNฃ\3Gฌ๊ต]Ÿ~Fพ฿ตหY;๎Lfึบmอบuฮ6{ฆOฏžาดIcณ๘™�d91!€ € €€ท@lƒˆ�G‰ฤ6ˆhŸ_ฏRฝฆ๓##}ฏ๏็�“�i๊Gำฬชึฐอ]:w4๓ .2?:ิ�AŸ�5y๒ไf›�s์ุqyคrU้๗R_yข~=๋‡ƒW†kึq3า์๋๛รE]ฉ๏ฝฝŸฐท}`�€Uง่ย–f�A@+‚ˆaี4@ธ�"FNŸ็ฮ}ŸTญQCาค๑TS[ทvl�่Z'ิ โบ5ซe๓ฆฏยโๆ>ัภ ป�sฯ=Rขx1ำ.บH�๏žfอž๋สัฐ�ผู30กV/\นj•Žจ\นฒข•t๚ํ๗฿คFญบ๎Sษ„ฑฃฅhั"fV ุjตชา�z๋ญRฒDqน๓Ž;L…ธัcว9ว•*Qย>ฉ‚Yึ�ตโ€NZฑO‡hrOZอ`ษ’e๎Uqบฆื \ ๚…‚~ฑ S €ฆ;ˆจU๏~๙ๅ๘LfU'ิ้Œ5�๗O?�dUa{ศ*X˜ฬช8ธGoเพ[ทy๋ ฉZฅฒฮŠVB\ถ|นคฐ๎๙�๛๎•V?้คaฤZu๊:_จ่:ญฤ๘ฺเA:k&�i�พ�RธpaัะŸ{๒ "พิท่๓A'๎j๕ฺตฒw๏ฯฆ/*YรVู_ธผ๚๚2ใ“ฯ�ง๒š%ˆ—็ืล\ 1๕‰๎ชaภดi=ฏแโึs�ถิJŸ๛~�็œM‡ิา~uO๑๑q ถ�๊๋ํ;vZ_Z“�ณ฿&eห–‘Œo฿ b|^›๎v‡25ƒˆ๎๋jญไ™&uy่มๅฦำJ8ฯ;gฝฦV˜ืิ#Vธ:ำ-žŠ•;w~c๕K+็Vฺถi-�บv6ห๚š|๎ฟJธฮึŒ{ทFMšy�อt๏ว< € €ืณ€�้วŸvKƒ†ž๒ฤฦ#ถAD๛Gh'Ož’ฒ*šSืฎUC^{eฐ฿e�?ยา ๏y†q:์=™4๙Cณ�ฌฯf˜ส๏๚�C'„ฅ->|่U q’Wใํก™u่�ฑฃผซˆ้Žmญก™3XC3๋ดc๛6Yฑlฉ™งt่X๖Hง๑&ฦ8คจป๒�–ญ�ฌกJŸ๑ส๖ำำ$œำษ๗๖uซWสM7y<๔K�๒ม=iUด๏ฟ��+d็�ฎ๓๖ :™.)Rคญก›ป?ำรซRยิษ“ฌa=U,gฯ'�\ ๊qvเpส‡SeศPOฝจ๛๚บ์"๊5ตฟtXmฝf^}L›u?ญSK^4ะฬ�yโ„”ฤ’4+|� %ˆ˜}โำLJิJ…:uุ่%เฐใ๖1๑๑)f ญ=~�hs*ญZกขตสšึPุ๚|6…๚ฺ vž˜ึปฟ๐rgJED=FญฃฦŒฦูžt(wญโ��๔1ก+"๊—‡;?-›ฌ!าuาแฉ๕๏ป�๗ฉe›vNEWญŠนzีrI*•�๓ฯ?ๆu กb{rท}ื?JรฦMํM<"€ € €€KเZ๕ฟ้ตšนN~๛อูขฎ่หฯŸ;[2gพUNœ<)Ÿ~:Sฺตmm๖™5gฎ ่ (บ?็ะuบอ]%Q฿'ีซ๗ธ๓ใ%๛Voผ๖ช่๛:๗ค๏5๔=๙‰J=kH็ขึ{C๛~บm๒”~๎โ~_Fั-ส< € �รฟh! € ค"†o๗–,UZJ•.ใืภ_ฌ_ถฯž๕ฉ฿๚งŸyฮ qฅ2๋uHีร‡9๛�uื=Rฟแ•jw{v๏–ys<Š;;…มLจaงฏทl4aน๓็ฯKตšu�†Y}ผ๎ฃ2pภหๆฮึฎ[/]žพ24ํถอ_™ะ›nิ/๔หPงPƒˆWใšฺฦw฿yK*U๔TTะ€ีศัWBV๖=ธƒˆ๖�ฉ…š่d๛๋ฎถ`›?ูTž๏๙œูO+๕iHฮ=น‡…vW›ิ€ืชๅKฬฎZแญฤรe�‡‰V”=j„ณฮพžฎะJv(OซjีC฿iแผูr็wšีัUz %ˆ˜}โ{?๎{Ž)ˆ่�7T๗\‡’*5j๙6%ฦๅP_›1ž0ศ๎/ผฎFQซj>�ํู W ผฺๆำcิHOˆ3๐�q[๋šู๗o“žั]�rโค)๒๎{ž€ถn{o่yไ‘ :k†Sืaีํษ�ทA‡Zwoณ๗แ@@DฎeฑpแBfeuถ 4 ?ฉ๗˜gค ๊๐`บbีš5าญป็=๘๘ฑฃคXัขfฝ�จ๐G๋F3?nF‚๘ู้ ๎ใ ฤ��ุ�รJ "–~๘aษdU;ผ๔๏%kDิ’+g.S�ะœะ๚็เe๎‚2m๚'~Ÿกุ๛ธ฿—DดUxD@"C€ bd๔ญD@’ฌAฤ๐ํฺ\น๏ตช]Uด*"&—ิ7ค1CŠฺญ=v๔จL2ั AlฏซdUล{จ€งฺ�ฒ}หฆrเภ>ษa}่\จpQ็W๏บฐ0ฃ}ฎฤz %์คโfฯผศ�ใ๗?œf�รงฐ†+ส’9ณYฟฯvนv�zฮ> ๆฮ’ป๎บห,ฑ<ฟ๘bฑU‘lซ5๔ฏชŠฮfB "^kje…9ณ>1ฬำงOK•j5ถืD,Uบœูว:ดซ&<ำ�ii�๒)sw๖บ^={ˆVžำ้ต7�’้3>1๓๎พ\ปJางO๏UIQซ$jตDu�๚5+%ƒUแS'wัฎาmvฺ}ฉ๋�/๛�้ƒ™๚ฝ<@ๆฮ_`/z=†DLศ>๑jคตเฦDŒ; ชmะ๊Ÿห–-—Mึs}›5$ylฆP^›ฑ9_ฐ}�_x] b�๖œJƒมฎ้ป>กƒˆ^cn๏Eึ฿ฆ�/ผ่4ำm๔�ฎ]ขก\ดยสชKญ/ำˆฟ๖Hฅช�68'b@@๋X ก‚ˆ?�๘“ผ�ๆ[2a์h๓นฬฦM›ฅ]‡NRทNํƒˆ={๕–๚V5w�Q฿ฅK—คuปๆ=œ๛}ฌ;ˆจ�ฉaฤ@ีืoุ +Wฌ2c๊v๗{‚ˆ1iฑ@/‚ˆแีด@ธ๎"FN—gอšMoะPnดย&:�๘ร.Y8ฎื t่�ีฺžฮkฝpๆ๔I—�ณm๛ื_หส�*ืู�รแัพ‰ihๆชU+ห7�ซๆป฿!i๋[รiU2฿I‡r]ณnDE ๙D7…Dผื4ฐฟ<๖hำ,ญvฆUฯM๎ ข๘๋๑lwyช…g(`;œุฉc{้ิกฝ9…DtWU๋๖lYตjต฿%t˜) E๊dง_x่pP:้0ฟ:�ณ๏ไ>ฮn—๎3๓ำro๎\พป]Žฎฺ[(Aฤ„์฿› %ˆ_Ÿื’ฺตk๚6มึๆฮ›oUีด†สkำ๏"!ฌpแu5‚ˆ๖s3„&$๘ะฬ^c๗็อ+3ฆM5อึฐจฯ์ž/œ/ูoหnVู_<6mาX๚๔๊iึ}ฑx‰๔๊ำื}๓ € € เธ–Aฤ;nฟ]>_เ๙ผๆ๐แร๒ื_Iฎ\นDGจ�Dc3"ƒ{$‚`C3๋�4„จำฌ9sฌแ›_1๓:�เL'}ฯscฺดาธัRซfMฏ๊‡:‚ม +|˜3WN)X €๙๑’ถAซฒ๗0(่—�๏ห"f�A@"F€ bฤt E@’ฆAฤศ๊ื๔้3H›๖อฏ่ต๊แ๐a๏๘�ภฃี—ป๏น�ฆ๙โล ึ0อ‡ๅง๒<ร๙ฎ\พTถฝอ๏ุฤ^Jุ้ั:ตไ•AM“๕ร๕ง๙Wํs฿ฯษ“'d��…๎U&pิ๚ฉ’?>g˜f{ $พ๗�2aาd{•฿cจAD=V[‹๋5๕‹†%‹H๊ิฉๅŸ�‘ช5j  ">�ฝ›ดjูย�GtAฤแ๏ฟ+ๅหz†U๎๚๔3&˜้{๓ณ?›aพHั๕๖ะฯ๎>ั๐ขฌ|'๗q๎ ขปขร”งสกรG|๕Z^นrUะแดC "๊IชOผnภZ%ˆx5|ชVฉ$ํฺถ•<๗�๋�Hl฿ฉ‹l฿พรo›ฎๅต๐ฑ\้�ย+Pั�e�ภมฏสฬYณ�ฮl‡6/\ธ(EŠ—๔�ำŠ„ฎˆ่5ๆ"~๛ํwาดนงjฉ�๖.;J‡vmอขV,ีชŠำฆN‘|๙0๋bชฐiŸ‡G@@ฎWkDTS๛๓ทฏ~ฦ0~โ$ณส�ฃ@๗{๗H๖ฑ๚™Žษ|ๆ์Yณjหฆ ’:U*ัฯ… +)/พะ[5|ยlำ๗A๋ฌW~:s–ฌ[�ฅL7VŠ)dŸสyิJO4๒Œ„เฌ�oฦ�พŒ ขฏห € €@x D ๏�กu € €@’ ˆy]�ก“U๕0งฒแปC� z)’งฐ* ฆ—SงNš}j?๚˜�{_3ฏAญ?ฌ๐^ธMก„�รo�๚ตดj๋]1,”{ำ!MK”,!ตjT—reห˜กM๕xญZPบ�#AOeฑ แญญฺ�/ะ†ธ\ำ.œcUฑ{นฟ'ˆ่�๎}ํภ_lƒˆ/๗{Qิ{�œVซ$ฬž;ฯ๏+—-1•txจ‚EŠ›ํลŠ‘๑ใF›๙UซืHทgž zœnฐ�ฅ๓ฃGp*=ฤe8]=‡=ูAD๛K{}LืบO|ฏJ๑j๚dห–ี ––:ตjJม‚œa�ต*F—งป๛6ำ,‡๒ฺ x‚Xฎ,\ธL?ึ์=i๒‡2tุ{^Gvฺ๋YฺถimึลDิแ‰‹—*ใu|l�AD๗‚ัซŽw�qปณหiซm Jข๖ZUซq๊h˜๑˜^Kฺ‡‹ฬ3๊ใวK๛ŽๅณOฆ›๓ํ?p@jี๑œ�ฌธŠ�Tฌ๘ˆUu7ญsF๒~็ฮoๅ`3Zฆ`ก^›,๘�k9ุBb\ำทz่๖ฏw >ป�๊๓ภ}l\ฏ™>‰qอธ๚$FŸฤ็š๎็๓ € pmฎuั>ฟ}:โBฃ&อ์EyุPฉPพœY~ใญ!ึ+=�=ฏ?8าน'ขyษาๅfี}๗ๆv���่ัcRฑJ5๓พ๎ล๚ศ๒ๅ+ไ“ฯf:?X,]ช”ŒŒnŽำก™—.Y&eห––J=?R0ppภกš "บ๕™G@"K€ bd๕ญE@’œAฤศ๋าฮVP(MšLร‡[\kลรุLO[กฐ”)S‰วด’ข>†�ไ;ูUพ‚ตQCcึฏ1›Ož<%e�ซ๖l�ุฎฯ•3‡ฬž๙ฉณ{tCปฺAฤ่* 8'Šf&6ืิ๛]บ๘sIo…K��๗_yฌ^C๙u฿ฏAฯŸ b๛vmคk็Nๆ�Bิ0ข{า!™็อ๙L’%K&GŽ•JUช›อŽZ๚…'\t่ะaฉR�{(`๗qz€;ˆจ_š4jุภœgDิ(=vœ™ห?S&Ž7_ฤ่ฑ๚EOLClบฦต่฿๋ธƒกฯ๕์-ห–{พX๒�O—ฏฆ๛�5ญธก“†สjืญ็�์ฬ‡๒ฺtŠรŒ;ˆ8มByฑ_ฏณธ‡ ฟVAD๚LƒŸ:Eฮt7l๒„qRจPAgUL!Xwั=ฤš} [j่Rง` ๕ E�bQง={๖8JGŽ##G1๋ฏ๖?�ทnr‚ซz๎ุ†ภ�RปMฑ '๔5��oทuฬุ๑๒AิH{1่cจฯ๛D๑นfB๛h›๚š๑๑IŒ>‰๋5ํ็ € 0vP๐วŸvKƒ†c}ัŽํ�I็Nฬ�ัU tW,ื๗O6o้๕�t�๊•rำMฬyZถi'�ถ}mๆห—+'ร฿๊ดGG่�\OgนM๋Vา�้.fy๓–-าฆwhัูัšั๗ุ๚^R'{T_ณjน�œ1ฃ|fU˜dUš๗"๚ŠฐŒ €DŽAฤศ้+ZŠ €$I‚ˆแีญ:ไn๒ไษอ0ฉZv_žผVฅซบf“~hhๆ@วUตa๙๒?h6�ฒwฏฬžu%hh�ฤZ็ํ�๙4{ชUดMั `Z @'ฮwศะa๗ื g›7mv†1าtำ๏พ๛Ÿ฿�๘[ทfฅคH‘ยlsX๏ป๓ชK%ำ-ทศูณ็ฌ0^5ฏ๓๛๎ซห๑นfงํE‡nาษ๗‹ณา็Ÿ๘�ก3๚Iซซiี5{ะฟŸิ{ฬ๓<�jใ&Sอ�ถb้bษœ๙VณุณwYbU\ฐง~/พ O4จo/zuุเ!oy*|jฐดnฝ^ืดาสjw�q‡lุธั^ๅ๗๘ฦkฏJอีฬz iˆ(ุ”}โ�๗0ร:๘ฐ๗<•*|๗ำๅ๘๚ปOญl6์ทอ%๗๏฿/ต๕Tย๔mCจฏM฿ใcป์f=xHชิจๅช}?w๖LI•*ฅYwญ‚ˆ๎6ฤ6ไj๐ศD&ท฿ๆฉฦจบบ9่ฟš4n$/๔~�,น?�ฐCŸZีฟ๚บ๛3Oั„ € €@ฤDŒ˜ฎขก € €@า ˆ^�Zบ\y)Vฌ„?vLพ๛๖๙๕ืŸๅ่‘#’)ำญRฌDIษ{�N5ช฿์—Oฆ์uญญ_ย๋๚ฏทn‘ฃGHฎ�นฅpัโr�R_พ|Yฦ)งO�ๅu\8-l��•nT�ด|ล ั ›‘ฌำW7{lŠ+&ใฦ\ h๕ฒูsๆษ�lูฒษCๆ—ฺึ๐ณ๚~฿—๚ษ‚…‹ฬy์jŠฎ[๘๙"ูผu›ฑœธ�~ฉYฝบ)Rศ์๗๛๏ฟK๕Zš๙@�|�แdษŸ?ŸูคU๗๔��y�T›�ฝ{he{Š๏5�ฟ&อZ Qฺืาว๘๕x}nๅอsŸฮš!I?%'Oœ’*U+Y!ฤ+รพvุ่ล+่L๊—-ร��@~๙๙yไ‘๒ขี๗�“ป"ขฎŸ8nฌcฏฐ‰V8o๛ฮๆ\9sJลŠฬ๐อฟZ•๛๊>๎ฉžh6๚�ำ๐‰๒R_Oี}ฮฏ�rƒlฺผู๊—หฒ๓›oD‡าึ)ก๛ฤง™โ�r็�๙๓ึswฎ์ฺ๕ƒ�}�oนhUฝt‡8๕ุธ๚ุตฝ?�,๓ญแp�gpฯYื(Rจิซ๗˜ v๊๙ฟXผDz๕้ซณงP^›Oห•kWญŒo2{ฏZณฦ๚ขm– ทjี‘ฌYณ:gนVADฝภ’ฯศ�e�?s-๎l๎�๙ึk๛„ ๚ูCฆ9 ฑfโDิ๓h฿D%็ฯ_งZ4“ขE ›ำ>|ุ อB€–/�Bฒdฮ์lัแึ:u~ฺYพฺ3„�ข ๕y`Ÿ->แG๚ฤV �˜}ืkพึ"€ €ภตˆmQ฿7๖่๑ฌ๓YL‡}ชำฯฟ�"_�๗�RG.�สkNs๕8�๑bš4iฬ:�ฑๅ๒•+%mฺดาฆU+็V*šป฿ฯ�sแ‚Lš4ENYŸ‹Tญ\Iฒฎฏำ้ำงๅแฒฬ|ฐ�Ÿ™|๛ํwฒbีj)Uฒธ+Zิ์GO๎๗ชัU} v]ึ#€ €$žAฤฤณ็ส € €–Aฤ๐zhฑx๑’16๊�?็e์ศrม๚@ฺ=u๎y็รq๗z7ฌuke๓ฦ พ›ยjน฿K}ๅ‰๚‡‡}�อทeฺ๔^ํํำซง4mาุk] …@Aฤ@๛นื๕ํ๗ฒ,ฐ‚[มฆ๊ีชส[o\๙ขมฝ฿าeหฅว๓ฝUv่อYd&ะ5�U ถlู*ญ�ur๔•ี๎/.์ภŸ{(`ป‚VYิ๐ N๎aจuศืa๏qพ4นrๆ+sซVฏ‘nึ฿๎I๏๓“้ษw�้^p�n—ฝQซ๎Ša…Hฏ„อ์m๎G�ฒ'บ ข๎;gึง’3G๗af^๛SuJ่>1๕๙gๆง3ไ��น|ึz๋ิญ๏5�v\}์ bภ‹�ทRCฃ-[ท๓*ฬw�P_›พววvนวณ�ญ0^๓wฟ–Aฤบujห �อ๐ใพ ั!วu่q๗j๐ศ]ั}๗�ฅK—ฬ™3gฯqฏ๖š๗ต๊ำ๗E๙|ัbฏ}ฎๆกท่5C}ุg#ˆธูฆ๘Ÿฤ่“ธ^3เอณ@ฎ™@lƒˆZฉ\+–วfชYปฎ๙!Ÿฝo�z›ษู#.ุ๋ํG�‘\‹Vm์E็Q฿ซN?F๎ฯ›ืY็žนpแข๔๋฿?V�ํ?2jธ่๛{฿ILูจI3฿ีf™ b@V"€ €!@1"บ‰F"€ €IW€ bx๕mNซ‚a•*ี%ญ๕กsฒdษ�งaย}๛~•ฯ็ฯ 8|s๛N]$]บ๔~วipqแผy๒๋/{�ถ…ใŠ6ญ[I๊ี$›U�ฬฎŒฆํ์?`ฬž;ฯฏษ๚!y๏�=สn๎ด๊แบ๕dิ่1^_ผ?lจ*Xะ๋�๖q๛ัcฦสผ๙ ํUA๕�ฆM[็*`ูงs๚m�‚…๒bฟ�^วล๕š ็ฯq๎ญsืnึ�|้u�@ ]:w”ํฺZึฮKฑ’ฅอ.vตBญจPดธ็‹ˆV-[ˆuHืฒๅ+z ซ_zผ�ฺ`ฟ@Ÿžsา”eDิจ@—6ฟแ๏sชบ้NชZป~ฝคK{ฃ-Zฤ<‹—*ใwผ~แา๗…�Rญjักส�“žCซ8,ฐชXNŸ๑‰{“฿ผž็…>ฝญ6’์ูณ;�โ;๔TB๖‰_#ญ™2e’ฎ]:Y) [•;ณš๊บŸVำจ^ซŽ_เ-.>:|๙ ฝ{หƒๆ๓3ีkm�๖ต �S)Rื›B}m;OL๋฿y๛MฉbU๛ฐ'๕ุพ}งUมc•ฉ๖ฉ๋ƒ…๎>š2ษบื�rโไI)Wแส9์sล๖Q‡ญng�-สaZoผ1ญ9,ุะวพ_๎>sF.S>่ฅ�ADVพž๕ez๋๏‡=iุฏผ๊Wำ�n?บฟ Œ๏�ฺ็Œ๎๑ซ๕k �O�้฿ค˜ฆ๖ํฺHืฮผv‹MeW= กฏ๙ะC๙e๊ไI^m}o๘?aขืบ@ ก>์sฤ็š ํฃmN่kฦว'1๚$ฎืดŸ<"€ €@ยุAD�ฬ`ภเWอEw[ฃ๘ํ7ฏ่ๅพX8_‚… ํƒฝWxดN-้�ํiฏJๆ๚ž�K๋ฟฅป=๋บู>‡๛Q฿๛ ๚ถ-\ฤฉžจ�ตj๚kึ4WฌX้�=ฺy"บข5Jพ7ึั ึ}๙ฅผ�๖Pฏ๗�z‚2ฅ–”ฉRI1ซB{๓fOšsR1ZZ6"€ €a'@1์บ„!€ €ื—Aฤ๐์๏ไษ“ห=๗ไ”Lทf’›nส(gฯž•฿ญรuุๅ/�mฃu็9sYปŒึิ‡ไ‡]฿๛UNŒ๖ผQ?จฯ—/Ÿdอ–ENXรจ๎฿�›WEน@ทฆUๆ๔ร๘›oนYNYC�บoŒว:O(๋BนfํZ5ไตW›ำ๏๚แGiุธi(—บ*๛jX.�H๚ ้ฤwศ้่. �Qฌx1SฅsใW�พไˆ๎X�ฆ•'๒ไษ-VŠP<({v๏ ๙1]ร�i}WŸ|๙,ึPๅ้ำง“ร‡Ž˜็บou?�$ฑ๕ ?}=ku๓ฆอืฌ๏ใ>�AD;ง}“#ว=๒ฃ๕:w๋]๛๚๖้ๅ y>ใ“ฯไีื฿ˆnwถ!€ € €ภvั ขีล๕Oืbบใ๖�ญa•๓ห‘รGe๓ึญ!]B+Dgผ9ฃ5 ๔vฟซ…tขhvึ๗�ซ–/๑�ƒ ข +@@ฐ ˆึ�Cใ@@ค/@1้๗1wูฦq* บ‡—Ž์ปŠ์ึำ'ม๛O‡4N&M๐‚l9fU! ฅขGำDฬ๊@AฤPฏAอ9ณ>3H๕ุ ว:ภ๊ตุ@@ค&ฐrูนล๚Aข{š5gฎ ๚ฏ:ข{�๕0ฏ?$\ฝr™คL™า๋v‡ซ๊เ^ฑ€ € hž #€ €จADž„ท€Vฬš%ณidจUย๛ฮ"ทu๔Iเพำ/ฎ6ฌ_xc k=*•ฌa้ฏ—)>AฤfO61ีBซTฎh†๖Vณ-[ทI๋ถํฏ>๎@@@@@ €Aฤ(ฌB@H8‚ˆ gอ•@ค,Ÿ โแ#GคrีI™ว๋�โDิ์�น3ฝฮu๒ไ)iำฎ=ีฝTX@@@@@ฎ?‚ˆื_Ÿsว € €@X D ซ๎ 1 €@D ไห๗€ค‰ระฬ'Oœ={Ž่{ฅ๑ฯ๗|NžlาX._พl†TŽํฝ๋pฬ‹ฬ“ไษ“หษSงd็7฿HTิh๙~ืฎP.ฯพ € € € € €IP€ b์Tn @ˆ$‚ˆ‘ิ[ด@@@@@@๐ ˆ่oย@@ ˆ˜€ุ\ @@@@@@ธฏ*งD@ˆฝAฤุ[ฑ' € € € € € € ŽรฑWh € p DผŽ:›[E@@@@@@$)@1Iv+7… €DŽAฤศ้+ZŠ € € € € € € ˆH…u € € &@1มจน € € € € € € pM"^VNŠ € [‚ˆฑ•b?@@@@@@@ <"†gฟะ*@@เบ ˆx�t57Š € € € € € €IT€ bํXn @ˆ‚ˆ‘าSด@@@@@@,@1ฐ k@@H€ bAs@@@@@@@เ DผFฐœ@@ vc็ฤ^ € € € € € € €@ธ D ืžก] € €ภu"@๑:้hn@@@@@@’ฌAฤ$�ต� € #ฃŸh% € € € € € € L€ b0ึ#€ €$ˆAฤaŽ๗ERฆL%mฺw}ิi�ึอฒa�บ€็อ˜1ฃิฉ[Onพ๙fI•:ต\บtIฮœ9#฿}ป3่1OฤJ@@@@@@ˆ‚ˆัM4@Hบ#ฃo4j*w�yงำุ�}๗ญ,^ดะYถg2eบUžl๑”Xดื�;wl—ๅK�‹<"€ € € € € € €@ ˆ˜:‘[@@"Y€ b๘๗^ฮœนฅnฝ๚^ D์ิตป�pร f฿“'Oศ฿oUFผE๎อ“G’%Kfึ๑๙๙�฿y@@@@@@ˆ\‚ˆ‘�wด@Hรฟ;[แย4Vธ๐Ÿ�‘ิึPห: "�}Oฉื กู~๖์๕™ื*Wญ&>Tะ,;zTฆL๏lc@@@@@@"[€ bd๗ญG@"^€ bxwaZu$๏�ศฅK—d๛ื�คp‘ขฆม‚ˆš6—�nปอl_ตr™|ฝuซssปt“ดiำšๅห—/Kิ๐a&ุ่์ภ  € € € € € €DฌAฤˆํ:Ž €$ ‚ˆแ�™ณd‘f-Z™!•ทn�,/\”%K™ "v๎๖ŒคIF4h8��wไ฿K�š}+Uฉ&๐TCด๏vลฒลฒc๛v{‘G@@@@@@ˆ`‚ˆ�y4@H รท�v่,2ds็ฮษจ๏หรeสED์๖lOI‘"…œ�็ผDฝ?ฬ�XฦŒฅe›๖’^_rๅสm–ืฎ^)[6orถ1ƒ € € € € € €‘+@1r๛Ž–#€ €IB€ bxuc‹–ญ%ใอทl”V9ด+jีC�฿ษส”Iฬ�ญฺv›oพูฬ๋ถฉS&ส1ซbข=นCŽS&๗ฺf๏ร# € € € € € €DžAฤศ๋3ZŒ €$)‚ˆ‘ำ—)'%J–2 �฿w฿สโE ฝ_ดX )[พ‚Y็[ 1{๖์าจisI–,™ธซ(z€@@@@@@ˆH‚ˆูm4@H:#ง/c "๊t{ถงคH‘ย�ิท฿์”K—HึlYฅ�%u๊ิf�ึญ›eอสfž@@@@@@@ ๒"F~r € €@D DŒœ๎‹MQซ"–)W�T> tg'Ož”Iใว˜amg € € € € € €DžAฤศ๋3ZŒ €$)‚ˆ‘ำฅJ—‘’ฅJ›kตรฅ‹l|กยEฅlน ’"ฅง2ข๎t๙๒e9v์จ|8iBภcX‰ € € € € € €‘+๐���๘Žป@IDAT์�œิD�ว๑ฝƒ…" ุฅK‘�‹tฅWAš€่ƒDล.H๏]" " ฝƒ”ฃ(b้ ฝ �ฬœ‰ูฝ�ป-w[๎>y^�&“I2yOvoŸื}™It๋๖{ย‚ € €@๒,ค+sูธศœ9‹ไอ—O�:wN์฿/���'ฎ/ษ๙@@@@@@@ ‰"AK"€ €X- V@@@@@@@ฐ ˆ–�Fฃ@@๘#@1�๔%w‚ € € € € € € S€ bย์w๎@‚ˆ!ำ4@@@@@@๐I€ ขOl„ € [cK’๓ € € € € € € €ม ˆwฎŠ € ๐ฏAD@@@@@@@ ผ"†w�ัz@@ ์"†}r € € € € € € ภ"&๐€�G@‚-@1ุ=ภ๕@@@@@@@�"๚็วั € €~ D๔ร@@@@@@@ D rpy@@ ก DL่O๗ € € € € € €แ.@1�{๖#€ €a.@1ฬ;ๆ#€ € € € € € €@‚ ˆ˜เ@@เ D ฎ?WG@@@@@@� ˆ่ฏ ว#€ €๘%@ั/>F@@@@@@‚.@1่]@@@„-@1a๗?w € € € € € €แ/@1�๛;@@ยZ€ bXwG@@@@@@„ " € €@P"•Ÿ‹#€ € € € € € €~ D๔› € €๘#@ั=ŽE@@@@@@‚/@1๘}@ @@-@1Aw?7 €„ฌภ<เQ�n�ธ!Wฏ]sY7M๊ิ’"eJk฿๙๓็ญuW+ž\ำี๕์ื‰้๖๋šื‹๎Wu์ืณŸ/บ๓˜๕�k๎ทฟบ;Ÿ:วใO<.yrๅ’”ฉRษนsgๅฯ?หฯุg@@@@ €ˆอฅ@@ข DŒjŠ%I“&“v;‰zUหฎฒe๓&ทMMž<นTฉVCrไ|D�ปv�šL›<มm}v € €ก$ ‚n›7ฎ“ฤ‰วุฌ฿”šบฌ7f๔)]ฒคตฏN�†rไ่k�พาฆuKyญGw{‘ห๕?“Zu๊9์›1mช,X@—5mึ�ฃ@^ีช•eะ'๋cVฌX)}�๘Ÿร9ีฦจรไ๙2ฅuyงW^•-�ถ้๕๏/”‡ณgื๋๖ทo฿‘ำgNKฤŽ2zฬX9}๚Œ}ท^Ÿ4aฌ+Z4Jนซ‚ึํ:ศฎ]ปvu๏ฺE^~ฉ™ค2ˆฮ‹ .~ทtน|:hฐ๓.ถ@@@@โX€ bsz@@่"F๏*{5}Irไศa5g�พฝฒ|้k�\I“&ญTญ^Cr>’หแ๗w๎�‘C๙ƒฐ้ฤ+ €„ถ€ "nูผมฃF�ใฉ[ฟ‘หบ[7KŠ)ฌ}ฃF•q&Z�๖•๖ํฺŠ ูลดœ:yJชึฌํPm๖ฬ’๏ฉผบฌyซึฒgฯ^‡�ฎ6jืช!พ?P๏Zฝfผึปo”jใฦŽ’’%J่๒ฎ�zส†M‘�eฅ๑=0หCYขิท�ผySบ๗่e…อ}ำ&O”B…ž57ฃ}ต‡UE{{�x�ย)_ฑŠป�”#€ € € €ฤ‘Aฤ8‚ๅด € €ž D๔ฬ)˜ต๒ไyL๊6h่ะWAฤ�น๓ศ ๕:อƒ"šผ"€ €@88'Mžโถู'Œ`เ�y๓ฃ์ท8h๎�ณ็'i�ชน้๐๚T�ผRตJ%ซฌIใF’.]:ฝฝbๅ*c๊แ?๕๚้3ge๖œฏฌzj%˜Aฤ™ณf‹ �ฅ7ฺชฆK~ฎxqI”(‘n฿™3gtHำ>uต=ˆจ�แz„Hu‚‰“ฆXำ^ฟุด‰๔{32,๙ฯ?�ศฮ]ปd๓๗[ไภฯฟHึฌIฉ’ฯIลŠไาๅหต>?@@@@ภ D ฌ7WC@p ˆ่‚›]บ๖)Sสญ[ทDMนฌWAฤง >+•ซVำ๛o�บ)?.\คจ$K–L"j~ € €@˜ุƒˆพŽฐงFTฃฺ +Sถ‚ฎณ๏s^Ÿ๕ๅtษŸ๏)]ำ(‡ม "Vฉ^ำa fฆ�ฬ˜๒ู #๖๊๓†ฌZฝฺบ={ฑ]๛Nฑsงต/บ๛4ัรFŒWแP5]t‘ย…dแขลัŠ} € € € €q @1P9% € €€็=ท Fอต๊H�ง๒ษ�ปwๅ‡�‘มBีWAฤ'๓>%+U•ˆํ[dGฤv��ฎฦt|ƒัs\@�ˆ โ๚ตซไ�๛๎“7nศwห–Iƒz๕t“~๐‘ห�ฎADuS&N"E ้[3nผŒ;�บ=_ƒˆ+พ[,#ชฅผ๑๓�๙๓ึ9YA@@@พAฤเ๗-@@ดAฤะํ�Œ™2I๓–m๔h6;wFศ�wคฤs%uƒ]]� ADW*”!€ €@จ ๘D,VคˆLš8N฿ๆึm�ๅห™ณeฤฐฯ๕๖๚ฅ[๗ืb$็ โมŸJฅŠ๕=ชiค?�๘S๋~} "ฎZฑT2฿Oีา�ํw๕ะe@@@ ‚ˆกัด@HฐCท๋�w๊"้าฅ“๋ืฏหุQรฅT™ฒ๑.ˆXุ˜บoโธ1^uยฦ›คGฏ>2~์h)Zคฐวว�ป'Fฐณต”/WV:ดo๋๑qชโa#d๚Œ/ๅ๛M๋%eŠ{้า%=bP็N~M_}RฅN๐>๑็šแิ'พ>๛๖๏งO�ผ๋‚๕� ท>๑๕๓€ฯKืž๙๛ฤŸฯฎ„า'ฎ=+ต๏่ƒ‡ syเ;wdๆฌูQ๖๕ํำ[šฟ�L—5~Ož:Mถoู$)Sฆิ฿ญJ”z>ส1ฮแD\ถไ[ษ–-›พฅAŸ•/ฆฯฐnฯDœฟเ๙๕ื฿ฌ}๖•ฟฮ�%+VฌฒŠ์ฃ,ž>uZ&ห–ฏฐ๖ว๖Šฏ๏�›|ฏp�‹�~�๖งO|}๘ๆบ/๙ๆฺล^๊๏๗K_Ÿู`ผO�น&Ÿ—๖งๆฟ๕`~^†SŸ�'ฦ € €@l DŒmQฮ‡ € เ•ADฏธVนด:,�๏่‡ ฟž/‡�/ƒˆeห”‘‘#†zๅบ="Bฺw์,3งO“๒{ul๋vคb๙rาฒEsฏŽ3ง4�ณ{‡Wว�บuKŠ–(%}z๕ ๘5}๕I›:Mภ๛ฤŸk†SŸ๘๚์�ปŸ>q๓ฮ ึ{3�๚ฤืฯ>/��ณบ/ส ฟรข8๘๛�าืg6๏ฎษ็ฅรccm๓๓2œ๚ฤc@@ ึ"ฦ:)'D@๐F€ ข7Zฉ›:M้`Œ†˜8qb9}๊”ฬœ1M_8>Žˆ๘p๖์า๙•Ž^ม�ดwŸจ)U˜๐ษ'๗๊X5šR|๙คZต*^ท๐�ลข� ะ�ญ�้‘”<=๘ส•+๒ั'Ÿ‰ \๚šพ๚คN•*เ}โฯ5รฉO|}Nœ8AŸธyำ๋ฝn}โ๋็Ÿ—n<ฃX�>๑็ณ+ก๔‰{ม˜๗๘D|$็#ฒhแ|}‘S'OIีšต๕zป6ญฅG๗ฎz]…ๆ�๐nด — โญ�ทE�ใ5jsาคIญ{บ{๗ฎ 1Ji+ฯœ‘สีjฺ•~o๖•ฆMKขD‰สี†บ�บu๋ๅญ�ไ๊ตkQ๖{[เ๋๛ฤŸ๗&฿+\๗’ฟ฿ฟ�้_Ÿ~‡น๎KUส๏0๗6jฟ฿/}}fƒ๑>๑็š|^บ~Ž‚๙yN}โZR@@ุ ˆŠœ@@ภg‚ˆ>ำลูอ[ถ‘L™3๋?ๆN7Zฎ#อจ%>ใ ‘#€ €@X ุƒˆ7o�”–ญ�นผŸ[ทn๊ัํ;;vh']ปtึE๖ภก-pม�นบ�์นsRฉJu๛aQึร%ˆฅแ�tญท:๏ทีดอ?�๘ƒsฝ�๗ลห#)š• .$๊ื—็Ÿ/#2ค7‹ญืใ'ŽKZuญmV@@@@#@10ฮ\@@ภAD70A*ฮ_เฉZ=๒โ?๎�%kVฏดZBัข`@โน€=ˆx�ย)_ั๓ัŒgL›" >ญ…~๐‘|๗�RKk้w‹ไพ ๔vห6ํไ‡~ด๖9ฏฤuฑfj๒๑‡่หฎ^ณF^๋�ืน 2n์()Yข„.๏ฺญงlุดIฏฏ\บDฒ<”Eฏฏ฿ธQฎ^น&O>๙ธ<š'uŽร�!u๋7ฒถอ{ฑ]๛Nฑsงนห๋ื�๙๓้‘ŸซVญ์pํ‰“&ห๐‘ฃฝ> € € € €๘.@ัw;ŽD@ˆ‚ˆฑ€‹ง่๐JI›6�ปwO~9๐ณร™3fส$3fาe/^”S'Oศ9c4Ÿˆm[ู๊7บ๖่%ษ’%“;w๎ศˆกƒํปBb�ฆฃ�<บฦ�๒�oฒfอZั๐ฮ�฿�ฃ;FํSฆำg|)นr็า0ฉพ}ฟ �๚�๏าบU I•2•}Wด๋—ฏ\–_ฮ๓๔ัVvฺ้๏5}๕I‘2eภ๛ฤŸk†SŸ๘๚œ๛๋<}โ๔�07�}Ÿ$”>๑๕๓€ฯK๓Is|5Ÿ๘๓ู•P๚ฤQฮป-_ƒˆ๊ธMึJ’$Ibผเิiำๅ๓กร�ึ‹๋ b๙๒ๅd๘ศ๏g๊ปMฯ�ฏGi‹=ˆุฅkwูด๙{]วDฌRฝฆœ>}F—?๑๘c2qย8+l9ํ‹้zV๛‰c3ˆh?๏ะมŸIลŠtัž=?I๓Vm์ปฝ^๗๕}โฯ{“๏ฎปษ฿๏฿�๔‰ฏฯฟร\๗%ฟร\ปุK��~้๋3Œ๗‰?ืไ๓า�ิ�ทฬฯหp๊“�ฤXC@ˆm‚ˆฑ-ส๙@@ผ ˆ่WœW๎ิฅซคNฦใ๋\ปvUฦ้ถ~จห–)##G u�~W;ถGDH๛Žeๆ๔iR @~WU�–ตnืA*๔oูขน�:ฎvŒ7^ฦŒ/{v๏pต�mูญ[ทคh‰RางWฯ€_ำWŸดฦ๓่>๑็šแิ'พ>๛๖๎งO�ผห‚๕� ท>๑๕๓€ฯK7žQฌ~Ÿ๘๓ู•P๚ฤฝ`ฬ{| "6lP_๔+ๆ 5<(๕5u[7Aฤ›6หซ�zDiห”‰คH‘Bบ\=wปvํึ๋๎‚ˆjgํZ5ไร๗๊z7n�๊ต^๓็ฯ๋m๕#ฎ‚ˆjไFœTห™ณgฅrีz�ืพพO�yo๒ฝยuo๙๛��Ÿ>๑๕9เw˜๋พTฅ�soฃ๖๘๛�าืg6๏ฎษ็ฅ๋็(˜Ÿ—แิ'ฎ๕(E@ˆ ‚ˆฑกศ9@@| ˆ่3]œุฒu[ษp฿�.ฯ8qbQ�ฉๅ๎�ป๚ฟฟ/^/ฆNvY_†zฑtษ’2f๔ทํwตcหถmา้•Wล>ํขซzฎสšทj-+Tถญ[นฺํถlิ่ฑ2nยDูฝc›G#,™'บ~�บ”(๕ผ๔์ั-เื๔ี']št๏ฎN}โ๋sฐw๏>๚ฤ|S9ฝ๋ฝn}โ๋็Ÿ—NœmS�>๑็ณ+ก๔‰ฬ๋U_ƒˆ#†‘rฯ?ฏฏงFตฺท�@”kฟาฑฝ$Ož\—ืฌ]WŽ?ฅŽ*ˆ๋ b๑bลdโ๘1๚ฺปw� ญฺถาŽฏfฯ”ผO>กห›6k.?ˆผŸ่‚ˆช๒์™3$฿Sy๕qs็อ5EตนฤUQtฝn๕ }™“'NJตZuฬK๚๔๊๋๛ฤŸ๗&฿+\w•ฟ฿ฟ�้_Ÿ~‡น๎KUส๏0๗6jฟ฿/}}fƒ๑>๑็š|^บ~Ž‚๙yN}โZR@@ุ ˆŠœ@@ภg‚ˆ>ำ�ภReสJ‰็J๊๋๎฿ทW–/]cB=ˆจnเแ์ูcผ{… .ศีkืD๎ฟ฿uhำ^฿พn ผฝฆyœ๚{๊TžOอ|อ"š#๚š๔ FŸ˜ื ง>Qฯขฏฯทว™>มx่๛งฮ๋ม์“@>|^�ื็ฎึ‚๑ณO\xZฆž�-›7่๊็฿�ๅ+V๑่ะm฿o”T��ฎฎ฿ฐฑั๕o�ผ)ีjึฑพ“๘D์�ต‹คM›VฦŽŸhหjฑา๏อพ๒bำ&บh๓–-านK7๛nฏื๙ูeพ7๙ๆบ›LŸ`๔I ฏฬฯK_Ÿฝ@๚ใ9 O\ฟ'อา`๔‰yM_ŸYีvo�ฟM0Ÿo�j๚ใฝn}b>วผ"€ €ฤฎAฤุ๕ไl € €^ D๔,ˆี= ">�py8GNซ•ลเb’$I๔ฏทm๙�*�๓ฯ#r�ุ1k›@@ ”ิ๐ฝ "–/_N†ฌoใ๔้3RฅzM—ทิฎm้ัํUฝo็ฮ�าฆ}ฝ^ธp!ฉW๗๋˜jU*[กF5ีโ‰“ง๔พ“'Oส˜ฑใญzjล>แถํr๒Td]‡J�n์ุฑCพ]๙J์S/ซภๅŒ/gษ1ใ;Z๎\นค๙หอ$]บt๚(็ฉ›c "ชƒพ๙zฎไษ[?็ซy๒มG๋u{qวฮ]nG„T•}ปX"v๎ิวฉQฌีhึ*4นjี=:ใŸฦh’Œ6ึ4ฆƒVS3›หaรeสิ/ฬM^@@@@ @1ศ\@@ภฝAD๗6กถว“ bใฆ/Aฤ16�่‘#2๎์๋Q@†€/Aฤ๗� ๕^จฃ›ปh๑yซ�—M4OnY0ฎ�w็ฮyพ\E=ฺr๛vmE๚ำrส$VญY�กš=ˆ่ฐรลฦชีซฅWŸ7๔ี–ฏfฯ’dษ’บจYt�a๙…๚ E…+อล“ bƒzuๅ�๕!*ฝคpกBr๓ฦ i�ฎCX฿K(5~�ุQRฒD ‡&Oธธ+bซ๑�"ฉD�/อšทŒฑู๙๓็“2ฅJ้z3 Ÿซ†Sจ.iŒgฎน๑์ฉeรฦM๒๓^7uสฤ RคH!}\มBEฝ>>พเ๏s`"พู๏-นz๕บœ๛๋œ~ใซY ๎ซk—ฮาฑC;}นn=zษ๚ โไาๅส–ี็}๑ลฦRบdIฝN1Nจ9) € € € D๔˜ŠŠ € €q!@1.Tc�œšพ$9rไฐNผ฿^Yพt‰ตญV^yตปคJ•สกฬyใฤ‰2gๆt็bถ@ˆS=ป#ƒ๐?�๐ฃดl‰ำ ๚q๒ำฆJม‚ไ�ฝ{๒Lแb~œ)<๕6ˆุซgi�ช…พนNฏผ*[ถm ู-Sบ”Œ9\ทoาไ)2lฤ(ฏ�Jั5™ฟฯ=ˆXฒtูดบ�า@M>ฝzJหอ๕&ADS…W@@@‚#@18๎\@@เ_‚ˆก�(ไษ๓˜ิmะะกกฎ‚ˆ_ํ!)Sฅ”;w๎ศ้S'ๅฬ™ำฦ4‚7%W๎�๒Pึlึ๑�ทn‘อ›โfd๋"ฌ € ` ˆhรฑี๎]ปHฺดiๅท฿ส�y๓clฟด/‹b#ˆุ ^]ษ›๗Iน~�† jŒล&†ํฉ�}"ฦ]ื.\HชWญข/0iสT9}๚L�]ฬ83Aฤ8ๅๅไ € € €x%@ั+.*#€ €ฤถAฤุ�๓uฺ้CRคL)ทn�าS.ซ+ธ "6j๒ขœ9}J6ฌ_ฅๅ+V’B…#งผz๕ŠŒใ�ˆ@QNJ € D๔* ช๙@ ไ-ฦF1ํ งk๙๛D ง�Žพญฃ๗a/ € € € ˆHmฎ… € E€ b’*จQซŽไ}*Ÿ�ฝ{W~ุฝK ‰ บ "ฦิ๐ฝ^—ฤ‰ห?��#ร‡ Šฉ:๛@๐Y vํšา n]}|ขD‰ฅH‘Bz�๖ํ;๒ใ?:œwใๆอ2e๊eๆFทWปHฑขEไัG๓Hบt้Œั~ฯศoสธ๑EM๓์niาธ‘4lPOฮž]ง~๗]ผ๘ท1๊฿๏ฒlูr๙๚›…ึกไ|D๔๏gm?๛์3’4iRฝฝcวNซ\ญœ:uZ๚๕�กฬ� 5แณฯ<#w๏�5iLK‹—_’ ๅห้j}�๘Ÿœ?^ฏ?•7ฏผ�๛5ฝ>cึl]^๗…:Rขx1}฿Wฏ]“�๛๗หˆQcฌ๒็ฯ'ฏt๊ๅฒ�"ฃFRฎ F&ฉŒก–G{T๎ฟ๏>ฝ~๔่QฃOฮ๊u๕ใใ๛JฯืzปœfWนถ6ฆo}ฬ8>ปั/ชO�Cถn�&Ÿfร฿+`�ฃZ2gฮ$9sๆิ๋็/\C้u๓ว„‰“]N-=์๓A’8iณš~UฃL๗้๛ฆC™นa๚œ9{ฮธ๖S๚šวŽ— &Iบ๔้ฅลKอ$หCYไไ‰“2xุ0Yฑb•yจ๕๊ซO–,™E�ณต1SฆL’ฤ๘ฎwโฤ ๙๙็_dะกึ๓b]ศXQฯ`�๙ๅฺีซ๒Z๏พ๖]z�ฝwˆ:๏ฑcวeเ๛Z๛อ๛Tพ>ๆษ< "ฆIZชWซ*ๅส>/O>๑„<˜)ฃ$O–L.\ผ(‡–�ฦ็ษฐแ#อำFyUวw่ะN*Wฌ`<™%ฅ๚ว=ทoห…ฟฮห{๖ศœฏๆIฤฮ��็๖็็�ส‘ฃGขœS˜Wฎ]•๎=z้:๖ฯ’ูs็ส๗? U*W4ž‰�๚�๓O™�๕7๒ล๔.ฯiชm“&$Oฎ\’-[6����นs๒ำ�ฝ2k๖\ูaVต^๛๖้-9r>lm›+ƒ u{f๕9RคHษ๋QŸัWฎ\ึŸณ&N’={๖šี�พDtKร@@@.@1เไ\@@ภ.@ัฎZ๋?&7oูF%J$;wFศใƒ%ž+ฉ้W๑ŽDJ1ดz›ึ €๑K ๗k=คUห�ิสUซฅ๗๋o8ิUžมƒ>‘'ฬก��ธs็Žฏอ๘r–Ydฝ๚น”/Wึฺv^Qฝ’ฅ��_ถL9bจs5—�g0Pฅ*ี]๎๓ดp่เฯคขŠRK๓Vญc ๚|1e’จšZชTฏiMณZตje๔ษวบ�ปฅห๕=งNJo�,X๘ญ x็=ซจnฺ2๐ฝwฌmse฿พ�าฌyKsำแีัากะอFบ ฃŸ:w๊(ฺทตžฮ‡๘ๅWyฅKW—ก9็บ1m๙ลTy๚้1Uำ๛?๚ไ3#ุ5วก๎< ๋Vฏp(37 Š�!ๆถ๙๊ ม•+_ษ!ฌ้ซO้’%ๅใ> า›Mqx=w๎/้๓ฦ›ฒkืn‡rำH�C—g‹wุง6ึฎZ!>๘€NV3�QŒนxsŸฎž๓<๊ีำ by#„;|ศ`๛กQึ>p@บ๗์eฝ7์-œ/๊๓ฤ�ฒyห้�ฅ›ต๛�w�–๚u_ะ�*08่๓จŸ ๖6Uุ๗อ~ฒlydุัŸ฿-–‡ฒ>คฏ๓—1ยŸ)ฯx์ฅTฉ็ไพ t๙แ?�บ๕้u๓‡ฏADž๓ฺๆซทAD๕~Vฃ �n๔ฃP…่ชUญj=?๋ึญ—๎ฦhœ๖ฅK็N๒Jวศั?Uy‡๑��f๔Eส”ฉค V-X๐i="fงW^ตS#†ฮš9B๋™ณgฅrีึ>sล&:l„Lž:M๏ฒอบ7m6FR=%ฯ=WBr฿วีข๚ชBๅชf๋ต๓+E…RอE=K?�ธGฟฏžx�q)jŒ๋.ˆจŽS#ชๅูgžถF.ˆ8่ำฅj•ส๚5โชีซ๕ˆšŸฝๆ{\…kีฉ๋2ไฉ4~D4%xE@@@ ๘ƒ฿ด@HะCณ๛Kกรโ�Ž~ธ๐๋๙r่ะ๏~ีิjj@ต์�ฑ]6ฌ[š7Nซ@โฅ€9’š ตlำ.ฺ{|ฑi้๗fไtฑ*ิฎ�+#์ูG,S!ŸWป๕ฐฮg9๏S•ิhwEiขWฌ\mใผ2cฺT# Tภt�“g G†ุœ๋๘ณm:ฉ0š ฅน[ิ๔หsfENใ๊ิsฐ:|Xz๗้๋ฬTuฎ^พ*jิ7wหฎˆญzคย่‚ˆ๖cUM…)ีข\*Œ�ฒtษBษž-2 ฅB—*|i.j๊์๙sg๋ ฅ๒~ฉE+QํˆญEMq;zไp}บI“งศฐฃผ>๕”‰ฌฉลc "ชเXำfอEqUะN-ช_๊5h,๖~3nผŒ;^๏๗ีวแ}bLY�บmQำAซE8m๊Dcjเ๛๕ถšN|๑โ๏๔บ๚แkั:ฑโํs`?Vญ{DTร—^|QThิyšduŸs็|ฉง[vะSำ'?_ฆดพดšพyา”ฉz��ก�_ฉŒQDGŒดกƒ|*8ป~ํ*=ีฒ๓่–ฮAฤฯ}.ำฟœฉ/งŽ[ดpPUฯ‰z^ฬE�็ท ๆ๋๗‚*SmužrZฟq“†าญ{ไ”์ๆฑฮฏ]ปt–ŽฦtิjqnฟY๗ั<นe�Wณ%I’$zš๔={ห†M›ฬ�b~ช็0ณU้฿‚ˆฮ"l#€ € € <‚ˆมณ็ส € €†Aฤะ{ ิAŒัีRงTfฮˆeลื+Tฌ,ฯ.ขoTD5q�่ะปiZ„ ฏผ "ฺ0}๚พ%4จ;ห–,าšK—.K™r,ปnฏvัSซ‚˜B~ึAN+ๆ๕ใ*ˆจ.ทe๓=’�ัฃGฅv�บ��ฏŸž^๙ž1]ฎมNเึ์ลฆ๒ฟ7^ื๛?4X์SQ�ƒˆชญ/พิย!ุค๒เG\ํA@5* มาy๙`เปRงvไจŒ๖ัๅœ๋๙ฒmฟ~ ‚ˆK—-—7�๗–ผšำ;ซQๆz๕‰œz�|จpš ฉู�็ญฯฐฯI… ๅ5หจัce�„‰D={t“ถญ[้2BTaDs ง ขูfwฏ*hชีRฟac‡ ๎ิIคpแBz฿๛~,_องืc๚ัโๅ—ไ๕>ฝtต5kึJฯ�‘๏AUะ�ๅfาทOไศ‹ฮ๛์AD๛{�ผ^�ท�gซFoTฃ8šKหอ๕ศ‚j� ดš๛ผ}๕$ˆhฟG&ถ ฉฎงฆ�3z„พ๔๑วฅFญบn›Aั- ;@@@ธAฤ€“sA@@ปADปFhฌ7oูF2eฮฌงa›`„ฏ]ฝชๆK๑ัว—:u๋KขD‰๔๙พ˜2Q.\ธ7J+@Œ€ภ๒dDฤukVZ#นฉ�1ฆ U‹๚]fพfy(‹^W?สWช*็ฯŸื�jšแ๗฿{Wฏซp�๗[ทสฦ›)ywศฏฟ�ฎหc๚ˆ ขš>ZM#ญฺXชL9:\ฝr™1ฅoF�ผ7๛ฝeLaฝ\>| ิฎ95lฃ&/:�ƒ=ˆจFtk�.r ฺ˜๎ฯy\ํa'u�“'N๊ห›}ฉ6T_š�฿|ปH�ูบขŸ?์Aฟ@็/๘F�}๏}�j๓™_ดx‰ผี€C™9ยœ?>ณgฮ|Oๅี็ญSทa”ัํ#0๎ุนKฺถ�oส฿p "ึญS[*”/งงทฮ๘เƒ’8Ib}๏™๏ฬๆาฌyK‡5฿{w€ิ{กŽ�}ใฦ Yตjl�พMถmˆvชa5zแฺี+๔H‹jZ๗rŒ‘E`ฐZf}9]๒็{JฏwํึำaA{Qฝี๛ุพดk�Fzt‹œฺ|›๛UนqรศP๒ภ>’น๓ๆ›ปผ~๕$ˆจย”*Tฉ–?�Tfฯ๙*สuพ฿ธNาฆM+jไวขลKFูoD4%xE@@@ ๘ƒ฿ด@HะCซ๛๓xFชVฏฎ๕ใ๎]ฒf๕Jซ�ณfอ*MŒi฿ิศŠ*่ฐjล2ู๛ำ๋|ฌ € (3”SQ€ิhž.๊๗›eฯ2\ธ`žไฮ•+ส)ฮ๛ห˜&๕K™2๕‹(๛์"ฺGnTSงžีซ้M5ธšV\oม�นบ์๔ฉำRฅFไHžๆ1๖ โิiำๅ๓กรฬ]๚ี>šโปฦ31฿x6ฬeยธ1Rขx1ฝูฎ}'‰ุนำ�ๅ๕ซ'Aฤ!ƒ?•J+๊s;ฮh^pัย๙zšoตm|›๛อW‚ˆฆฏ € € €_€ b๐๛€ € € Z€ bhu‡Wบ#คำมม_�์ะธŒ™2IฦŒ™tูล‹ๅ”Z8w๎œDl�โPOm���าผU[Iš4ฉ�ทuหf#ุฑ)J= @„€สŠ)ˆhO�นsG† ‹œิm ขšๆึyQSา67ฆWอ˜๑A็]ฦ๏ฯSRฟQk„3็ "ฺง=8iฒ�ธySTxศ\ฮœ9ฃงg�lŒHฆ�AซฉSํAฤฑใ'ศ่1ใฬรฝzห ข}D:5 �†ั๙ๅ—_e{D„Wํฎr ƒˆ3gอ–?ค›d>๓jd;5ยZvl๛^’'On�๑ูด~ญคOŸNŸืUั๊=}๚ŒTฉ^SืU?b "šฃ’ช,ซีŠQะ:๘฿•^={H๋V-๔–šึW=ฃ�,ใฦŽ’’%J่CJ–.๋๖�8m๒D)T่Y]Oฬทษx†~?xH��๛o]ึ ~]y๔ัG๕zห6ํD}ฦุ์ัฝ›4u๊T๖]z}�† า�;/ลŠ‘I#฿SŒ็ฒษ‹ฦtอฝ_“อ_ึUี๛v๘ศั‡ูƒˆฎ๖GD�bส$y๖ูg๔๙\�‡ร…bุ๐$ˆ8b๘)๗�๓๚Lฮ#;šง_0oŽe[ณv]9v�ธนหแ• ข € € €U€ bP๙น8 € €Aฤะz:u้*ฉSง๑ธQืฎ]•qฃG:ิO“&ญด1ฆgLf�ก[-{~�AVฏ\๎P‡ @)`†ฒb "ช6m�ผั๘]˜JnS2)�œ_อT!ค*•+KีFIj'Oๆ๒�"ช ›@เJ–$ฉ-ZD–.[.ีซUีSซัิTุK-cฦ—1cว๋u๓‡=ˆจ๖ฉ:พ,f;๖ํ�/jj�˜oh:ด—WปผขO9~ย$9zLLงี�กD๔วgม�ฏŒ๚๒h/WฃีูG๏�ปwŸผิข•e;iยX)Vดจ�vb4Ÿ‰`ีhˆ+–.ั๏‡+WฎH๋ถํF?U7 FKT๏ตฤเ+\ธิ0�_UชTถฆWว9คจสิbPี1์s=5๔�ปwฅZอฺQฆw๖'ˆ๘แภ๗คvํศฐจ๓ดอ‘ญ๑�ง'Aฤท๛ฟ%ิื'๐ฮ{ขFUu^ฬQ7ี�>[คธ๓nk› ขEม  € € €A ˆ๔.  € €@ย ˆZ�฿ฒu[ษp฿�.ฅFDR�ฉE�AP�๗๗ล ๒ลิษV�)SHป๖ฏHŠง ๛๕ภYฒxกตŸ@‚!`ีtจj*ๅ่–y_อ–'LWi�ชต์ูณ7บ๊๏ณOE๚อท‹ไํ๏บmฒ7m˜2q‚)RHโ๎y0ŸooGD๔วgฬ่ขFึTKฟ�o‹šฮ�พผุด‰๔{ณฏ.Zนjต๔~� k๗ฤ๑c๔ชภ9ฤh0FD๔ๆ9ฐ.l[๑dDD๛จ„›6/]บvทAD๚ธ�*š#CฦDดผา8.หCYtQ�ท฿‘…‹�w๋๕๖ํฺJ๗ฎ]๔๚มƒญั�=ห�;w๊(_้จฏๅ�_QC'AฤŽฺYฃฐบšฺ�‘œศท฿ฬำ!ะณฦ์•ชTw{U‚ˆniุ € € €@ภ"œœ "€ €ุ"ฺ5B{ฝT™ฒRโนศ?8๏฿ทW�แี�โคI“IปŽฌ�8|HฬŸkฏย: €A0งzฝvํบhฉๆvVีธท�๗ฆ4mาHทs๗๎ค•1 šซEMcz๙า%9x่ฐต[Mํœ:U*—Sˆ๖�ฟ~าธa]๗�EKไ��`g_๖๙ ฉPกผ.๊�ฅ›l�ฒลพ;ึึ฿๚฿ฦ}6ถฮw๙๒e)]ถ‚ุ^jงšŽถh๑ศ฿�Vec%XAฤฦ”ื*,ฉ5ชค]า�ข๚cู’o%ๅฟ�@ย�ฐ*PVบtIYฑา}จั�5ข+ท‡๊๖์๙Išทj]u—๛โ2ˆ่}dสŸ~ฺ+/ทlํะ�๙s็ศใENY์๒‡คK“Nž|๒ cชๅ๊zิภฏฟ๙F�y๗}ซม*ฤุคqCูฑsง,[พR~๛�wI“*ต-VDš5mชง|V•฿�๐c๙j๎<๋8๛Š=TฃF›7๏k9~โธ�นsG.œฟ(j*ๅุXT ่ำ?ดNตvํ:้ัซจ€ๅS&YๅฎBfjงฏAฤreหZ็V+jบYตœ9sF~๐ฑ^W?n�ผ้๒^ํaซ›F฿,”~‘7oศ�‰่ฒ‡ข”แ�y๓eใฆอr้๒%ษ™3ง™ฏš1Un*#@ZฒtY—ก1ซQ>ฌ˜ำ ซCWฏY#*TฅBŸjูบ-ย!|ฅสŠ+ฆ�ขึี๒F฿�๒p๖์zฝO฿7ไๆอ�z]�Xฟaƒ^๗uDDuฐฏ>*ฤธิ๕ZนฉE=—3gฮ‘D‰I›–-คPกguนบืชีk9ธถkำZzt๏jํ>r”ุ;#•*Uz/ิัๅ๊GtADoŸ๋ค�ฎxDTUํ�ท~ใFYb|v�}๑oฉ[๗ฉiLนn_œƒˆjtีœ9–ต๋ึ๋พ:r๔Oษž=›”{�yฉSป–uh•๊5ฃLณl๎ด“Uู฿_’็หW4w;ผฺM&Nš,รGŽvุ฿�ๅfาทOo]๖๎ภd�ื ๖>่ฉ\ฉ’.S๏•/f|)�wศmc]}๎ตj๑ฒจ~/\ฬqสz5‚lึฌูฌs5lXOส�๛>�b๚ ‰ุฑหฺwเ—ึฝ~5{ฆไ5ฮซ–cวหศQฃ �KRฅj%#„Xฯ:ฆ“ŠŒ๎sฯ�™้j๔V๋Dฌ € € € €@œ DŒsb.€ € Aฤ่tBk_LAฤ๎ฏ๕ัS;zา๊ cGห•+‘„๗ค>u@๐Gภ9tg?—ซiHUภ่ท๛[#ู้๋�ื]อัํ๕์๋‡�๘C๊ึqั^nฎgษ’Y}๓ตหkว4EฉyO^U h�๊Vี|คCzช`�ฺUr�ฟ�ธ`ฦ—ณไำAƒญzๆŠ/AD๛(hๆyข{u ดถ็||บ ๅศั#ล๖้ฎv8mธปžS5ฏ6ํ#a:๘ั'ŸษฌูsŠอPกCก› LTฃ8šวx;5ณyZ_}ิTพjJ_wหฝ{๗dศฐแ2uฺt‡**์ปfีr+ฤh฿ฉpI“&ีEัUoŸ๛u< "ชั7ี่‹ž,ฎ‚ˆๆ4๏๎Žw� qฎgช}๓Œ๐เ{Fˆะีbฏ๋KQ}๖Lž0Nrไศแ๊๔บL๕sqฦดฉฦt๒�c฿1็ซน๒มGŸ่"5ต๗ะ!ƒ$EŠ๖*๋๋ึo๎=#G@uุa� ˆhร`@@@ D rpy@@ ก D Ÿ' d้2๒\ษาบม{ฺ#+—;N ืฝงDLšฤฃ?f”\ฝzลฃบTB@ 6T่ๅฅ—^”Bฦˆiาค‘D‰้ำ.ZผD�๊ušไGr>"๏ฝำ฿ุ<%hใฦ ู!3ฟœํ0RWํฺ5QรZ่)i'N์ะlเQฃ$๚|H”Q๐*ฺ๊mฺด๒ๅสI†๔้ญ๋�y์˜žยินพฏ�Kพ] CG*0Vกr5ซ]ƒ>๙ศ๑0rฺ^}�UซฃNYl= ๚|จจ‘ฯbZ์ำฟฦTWฎ\ดD)—ีTˆฒ๋ซฅXัย’9Sf+ะ๖1"b๕Zuฌื์ทm�Jฺ#๑ฅOŸฮ^ฌืUpq�๚F฿ ฒ/6 ฺตm#5ชW“,™3K† ้ญSx็=Yฐ๐[k[ญl฿ฒษeีกาฟ]บv—M›ฟ—ˆญ›u˜ห>�๖�Fํข๚ลผฏ๋ึ่๋ซั8ีจœ๖ลW๕ฬฟังร}ฉ๓ชiv฿�๐—ฯŽฺX†dา@IDATฏBฉ}๐พรq.^”แรGJ๛๖m${ถ์ขF#ญืเฟ้รีq๖ล—็ภ<�DTำค_บ|ลh๓_ฒgฯ^ณŠ๕ฺ๏อพาศ˜V� Hชjšw๕ูqำ‰ณe‹ๆข�C›6s]UMs^�xeอ–ี:—นr้าeQกผฦ(€1-fะTีkึผฅ์�ท฿ๅ!๖๗ืศัcd�„�F6UจฉŽี”วjyณ฿[๒�าๅz�๙‡šถฝฎ12ฅ9ฅนน_ฦธไป๏ไใO™E๚uโ๘1z$O‡B7Sฆ~กรฉๆn5�๕G”<นs›E๚Uv:๕‹้2j๔X‡rsC…Y‹/ฆ7›ฝุDJ–(กืัโ@@@เD Ž;WE@๘W€ " €„บ@��๙$wฎGไสีkrย˜B๔ื฿~ถษ*$๓๘Kๆฬ™$i’$zฺัƒฟr˜ž6ฺฐ3ฮิจoyŸฬ+้าฅ‘ำฦtภG�้2ธg ๑๛๊ฃฆฮ—/ฏ1=๖]#(ทฯcS5๘รg—_๙5ฦ๗UlาูƒˆๆyฃQฝง๓็ฯ/™ณd๕^VSผ{บ(S.ฮœ9ฃ�ธqKŽมื˜>CฬsWฌXA†�Loชc5yั�็ฏชอำ.'N’H�Ikผ/��`Œ>*๛แภ๗ข\† b @@@จAฤ€rs1@@g‚ˆฮ"lR qฃ†>].eสฦ’oz}lฆŒสูsy}œ:ภืkช้๎ิจ2พ,พ^3ณ1โำ™3gผพค ๋�1Fณ๒e๑ตญ�\3‹0:}ๆฌือ FŸ๘zอไษ“๋gO�ไํBŸD/–P๚ฤื็เฎ๑Y0ม7ั#&เฝ*Uณf Ÿ~๙๕—ฃพ๙tฒxxฉ/kึจ#ุลtซ<ณ1 …ึ�!ƒ?• ๅห;4๊ฐ1c�FMส‚ฝ1gึ QฃชๅณมCd๚Œ/ƒ�คธ~๙๒ๅฌ€ฆฝA/ทlํvฤH{=Oื}�<เ;๔ย�|�๖๕{}z}โฯsภ�‹พ?}}Ÿ$”>๙หตyอšตั#ฒ@@ภg‚ˆ>ำq  € €@lDŒ Eฮแซ€}ช;oฮq๙สI—6ญ7‡ญฎš>ิyjฝธnฬ;�ำz6Mทc[๎›‘Sฅ:–วผๅ{Ÿ๘~อ˜[ๅบF0๚ฤ๗k๚๎CŸธ๎ณ4ก๔‰๏ฯHบ EM™หU j•J2่ำOข๎๐ dๅชีา๛๕7<จ™0ซฬ3Kž4Fณ๔eแ™๕Ecœjืช!นษ%UŒ๗y๎\น๔๎ห—/Kี๊ตUี+Žท�๙<ˆใฆE9ฝ๏฿+ขœสใ‚๐๚ฮ๏๑mลZE๚$&J฿�FLgvท?}โ๛5}๗๑�๛ท๏ืtgSน๏>1ู��ณ็ฮIฅ*ี�W` € €€_�โใ`@@"๚+ศ๑�$„ โ๕๋ื%UชT�0y}ฌ๏”๔๚Rึพ�ฑล:EภV‚ั'มธ&}�#•P๚ฤŸ็€P—๛gจrฅJ๒๙ ‚ˆ๎…|฿ใO๐ˆgึwwŽ�O`๕สe’)cFซเ๎�ป๒๎{๏ห‚…฿ZeฌFภŸฯƒภด๐ฟซใ{฿๙�๓wตFŸธR nY0๚$ื๔็๛w {(>gฮž•สU}Y<ะ>\@G‚ˆแุkด@ˆGใQg†แญ.\ศงV๛๚Gทดฦ(ŠWŒั}Yิ๔สj*Wฏ—{ฦจ‰|eะืkฆI•Zฎ^ฟๆuSีฺ'N์๕q๊_๛ฤŸk๚:ตฎกO�นฆOBŸฤฬๆวs๓ษ]ืฦ๛ฤŸk�๐รฎo„R-เ๋๏ฐ?�8"็)้X\ <’๓y0ใฎwFSช~Ÿ๐ฬFฤ./�Z~๘aQ฿ร~�๙€ฬ[ฐ@/�ฮใใฉ{พ~๐?๚>๐็๛ทฏ฿+่“ะ๋ž�X๔�้๋๛$ก๔ษ฿/สมC‡ฃGd/ € €€ฯ}ฆใ@@@ุ ˆŠœ@@@@@@žAฤเูse@@C€ " € € € € € € �รป�h= € ๖รพ น@@@@@@Hเ๘ภํ#€ €ม ˆ์เ๚ € € € € € € €€�๓ใh@@?"๚ ศแ € € € € € € €@"นธ< € ะ"&๔'€๛G@@@@@@p ˆ๎=H๛@@0 ˆๆH๓@@@@@@@ ม DL๐ € €@p"ืŸซ#€ € € € € € €� D๔Wใ@@� ˆ่#€ € € € € € €A ˆ๔.  € €@ย ˆ˜ฐ๛ŸปG@@@@@@๐ ˆ�}ศ € €a-@1ฌปฦ#€ € € € € € €B‘‡@@ จƒสฯล@@@@@@@ฟ"๚Mศ @@� ˆ่^h›&MZIœ$‘\พt9ดJ๋@@@@@@@ภ/‚ˆ~๑q0 € €€ฟ� ฬ๑I“&“v;‰zUหฎฒe๓&‡‹?]๐Y)TธฐคฯpŸQ/ฉ$J”H๏ฟ{๗ฎ�พ}Kv๏�)[พw<ฦแl € € € € € € €@X D หnฃั € €@� ˆ}ูจ้K’#Gซฑ๛๗ํ•ๅK—X�jๅล—ZHึlูสœ7�:wVพ˜:ูน˜m@@@@@@c‚ˆa�y4@ˆCฟ๓ไyL๊6h่ะPwAฤ,=$—.^”SงOษล $Mฺ4๒ศ#น%]๚๔ึ‰?๎�%kVฏt8 € € € € € € พรท๏h9 € /"†~7vฺ้CRคL)ทn�’ไษ“๋ป "ฆ4๊�ธqรๅ ๅ/๐ดTญ^S๏ป|ๅฒL;ฺe= @@@@@@@ �"†_Ÿัb@@ ^ D ํ๎ฌQซŽไ}*Ÿ�ฝ{W~0F2,\คจnฐซ bLwาฝgI’4‰�๙็1dPLีู € € € € € €a"@1L:Šf"€ €๑U€ b่๖lฦL™คyห6zJๅ;#ไฮํ;Rโน’บม�'N,�z๖๕z�Yqไ๐!ก{ใด @@@@@@ผ ˆ่•@@b[€ bl‹ฦ�๙ฺw๊"้าฅ“๋ืฏหุQรฅT™ฒ>3gฮ"ีkึ–3fิ;yโธฬž9#๖ส™@@@@@@@ จƒสฯล@@"†ๆ3Pฺ�w๔ร…_ฯ—C‡~๗*ˆุฆm1†?”ดiำHาคษฌ›ผy๓†L›ไ@@ฐ ˆ>�]1eส”านkนz๕ŠุฟO<('N—TฉRK�งŸ–bลŸ“ไษ“๋›ฝyใ†Œ9,|nœ–"€ € € € € € €@ดฃๅa' € €@\ DŒkแุ;ฟ'Aฤ˜ฎฆฆtž�ีl9v์ฯ˜ชฒ@@@@@@ยD€ b˜tอD@โซAฤ๐ู้’ฅหศs%K๋๏�iฌ\พิj|าคษคE๋ถ’>}zIœ8ฑUn_9�ผ,]�ญœ9sฺ^ฬ: € € € € € €„นAฤ0๏@š €„ปAฤp๏มจํฯš-ปdฮœE2�Ÿˆ1โฉ“'ๅ่ั#rร˜’™@@@@@@โŸAฤ๘ืง� € Vรชปh, € € € € € € E€ b @@)@1ฺ\ @@@@@@ˆ}‚ˆฑoส@@ผ ˆ่U@@@@@@@ ˆ‚B“@@„$@1!๕6๗Š € € € € € €๑Q€ b|์U๎ @#‚ˆaิY4@@@@@@p!@ั E € € ˆ8kฎ„ € € € € € €ฤ…AฤธPๅœ € € D๔˜ŠŠ € € € € € € €@H D ษnกQ € €@ย ˆ˜p๚š;E@@@@@@๘)@1~๖+w… €„Aฤฐ้*Š € € € € € €ธ ˆ่’…B@@@ D ”4ืA@@@@@@โF€ b�ธrV@@"zE5@@@@@@@ D"†hวะ,@@ กDL(=อ}"€ € € € € € €@| ˆ_{–๛B@ยD€ b˜tอD@@@@@@�DtC1 € €@`"ฦ™ซ € € € € € € €q%@1ฎd9/ € €€G=bข € € € € € € ฒCถkh € 0"&Œ~ๆ.@@@@@@@ � DŒฟ}ห!€ €a!@1,บ‰F"€๘ Pพ|9ฉ[ง–dห–MRงNฅฯp�๚Mi๒โK>œ-แ’&ujI‘2ฅW7~๓ฦ นzํšWว„Zๅx@žz๒Iษ‘3‡�ฝ{WNŸ>#”cว‡ZSiนsfIส”ษe๋ึ๙เฃ�ิ๒ฌ๘�๗�•gž) Wฏ^—_j๎ูAิ Iา%K๊๗๔ŸวŽลษ๛ู›ฯฬ๓็ฯวhไษ๏ฐ‚ ศ฿ี็š8qŠ,\ด8ฦ๓ฦV…Gr>">–G2e|P%J,'ŽŸ_~๛Ufบป†๚|๕d‰อ฿%ž\ำ]ฤtlLํTวศ—Or>’Cฮœ=+;v์wืŠฮล�OŽW}“-๋C๚”[ถm‹๎ิ์C@@ˆgใY‡r; € €@ธ D Kš4™ดุ๋IิซZvํŒ-›7yิ๘f/ทฬจ๋ž>uRๆ}5�ฃใจ„@8 ดx๙%#p–Z~3BCkึฌ ้[ศŸ?Ÿ”)UJทqฦ—3ร>ผjุm[ท’ž=บนlVมBE]–‡SŸจภKsใyWห†›ไ็\�“?…ป"ถฟw’zuŠK—.K™rผ:&ฎ*{๛y%KfyฝืkRฅJe#T“(JณŽ=*“&O• ฟฒ‚ะุณ{‡nะ๖ˆi฿ฑณ_›9}š(_�๙็)Tด„_็Šซƒ๙์r/ซ>+‡,E r๘<;{๎œ|๒้gฒbๅj๗{นgํช๒เƒžํึo�(�บฟๆ๖ ž�ซXฑ‚ �™>ฯ˜qใeฬุ๑nฯ้n‡๚์k฿ถญผ`๗SฅŠ ํ3NฦŽŸเ๒�^•F J† ้]๎_ทaƒ #S'Mฤ‰๋�“ฆL•aรGบช*๕๋พ =Œ๏>�ฟต�๖ํ;๒�ึ-ั>oVeV@@@ย^€ bุw!7€ €„ทAฤ๐่ฟFM_’9rX�ฟoฏ,_บฤฺvทRธh1)g๛#�ล‹eสฤq๎ชSŽ@ุ ˜แ“~๘QZถiา๗ำซgi�ช…ncงW^Fฌ‰�๎๚~ำzI›&>้ฉ“งdวฮ]r�ฦuน~�บ ๚|จห‹…SŸ”)]JFฎ๏cาไ)2lฤ(—๗ไOก๙~๒ๆืฎ]—็J?๏อ!qVืlฟ'Ÿjดฉนsf#{E๗�5jํฺuาฃWwป)ณ๏J‘ฯ.ืž ƒM2Iž|โq—๎�น#oฟ๓ฎ,^ฒิๅ~o 7ฎ[ใ6œ็|ฎีkึศkฝ๛:[�ž�๓'ˆจFอุ๋กญTซVU’'‹�วNf&Lœ,#F67^‡�\ส—+๋Pๆผq๎�_าจi3‡ั�†3Ž+�qๆy�๚๋ผTจ\ี�๔๙๕แ์ูๅปล c<พ_�ทe๑bวภโ'} 5ชW‹๖XถฌSทa”: ๆ%ๆษฅ�,PAหWปw—={๖šEn_ฯ๕ล๔.ฟว4i�H๚ฝูื ,:ŸpฯžŸคS็W๙‡/ฮ0l#€ € €๑L€ b<๋Pn@7‚ˆก฿cy๒<&u8�ห“ b๒ไษฅำซ�%i’$ึMDด(X‰งf๘ฤ“เQฐ ย)8l+oฏฏย‹ฮื‡:|X๊5h์ั)ยฉOD์ิกฝ1ฝm ป2eสXกž�?-[ถ8์ฟt๙ฒL™๚…CYฐ6ผ๙<ฐิuๅ๊Uใพถสๆอ฿๋)Fs็ษ%ีซV•‚Ÿ‚ˆม๊M๏ฎk๖}lี(qนsๅ2ย;ืeโคษ�5$@ต๙์r �ทOocไุfzง ก7ยuW๗wM#\ฆF™Sห•+Wคิ๓ๅ๕บฟ?Z4ู‰๎>ทงiืถต๏อ~oษwK—[�๖o~‡๙D\ถไ[ษ–-›�าึztAฤAŸ|$%K>'�ถo7B�ปๅฤษ“’๕ก‡คTฉ็ไนโล%EŠศ฿+Wญ–�ฏฟaSต๕้�๙ฌm็•-š[ศy_/๗~เ\ล๋m{๑ฤ‰ฒt™k๓๙_eบn{๑›oษ_ฦ(šฮห ใ:ฬ๙}ร�ืาธ>ฝz๊MvU–๋ึoะA๗ื_MT�ชeวŽาถC'ฝ๎๎G็W:J็Nvป "ชะํ๚ตซD��?ตl�!ซ‘ม3คOo„M�Kฒd‘ฃ๛:jฆCุ@@@i‚ˆ!�=4@ˆ�Cฟปtํ!)Rฆ”[ทnY\๒$ˆุดูห’-๛รวD ��ฆ…� ˜แ‚ˆ�9†๛ัฅK–”1ฃG่�˜;�k๘�‡�až˜™ิtืjสPตจi;ี๔กบx๓yฐe๓=•ฆ จ`ˆ๚ q^Š+&IŒฉ1ฝิY&๔ถอพ b่�]ิ๑ูีD•ฌ^นฬๅ๔wสื฿DŽŒงF@]ท๚ฟixผ๓^œOน�T�ผ2gึ �ะ‹�-eหWr�hฃิ›฿aฑDผu๛ถŠ\&๗๎�ำS๛ช†EDt�pc‡ ๎พ��ปบส™3gคrต่ง6ถŸK๕‰๊ต4k�R๖ํ�o฿ํำบ=ˆธbลJ้๓ฦ�<>=ˆXณv�(AEw'š๕ๅtษŸ๏)ฝ�๙๗ค ฎ2žK๕z๗๎]ฉVณถผป:— ,ฮ๛jฆ์4๋ธ "ถx๙%yฝO/]ๅเกCRฟaณบžบ[='j๙๓ุ1ฉUงžต@@@๘'@1�๕)w„ €„•Aฤะ๎ฎต๊H�ง๒้?T�ฐ{—.RT78ฆ โc=!u๊ีืuW._*Uชีะ๋�ฯ�yภYMฌQ�CQšX)6D,,4้ฝƒtTzคจ  JWค๗Š๔�{i‚(6:าTค*โ{oฮ,็ๆๆ๎�ฒ,ปหn’ษฬd๒Ÿd~9๗|๑YˆˆrM›6–๊CYบt้” —_ชฃฟฉะlป๗์‘iำgสถ;< -!ŽมG�L–คI“ส1๕กํ๋o๖IŸ๚๙„…ณ@๙7�ฝฎณฆL�L—ซ\ฉขไy.ทเรๅลK—ไ›oพQก้†kQ ย=š9ณ.฿บํ๋žกอะ8ล }ต๗k๙x`T่Tq๕O๋W[J๎\9%sๆG$u๊ิ‚ต?์฿/#G๑ฟ˜บๆ๘็ฮŸำแ� ‚#อณฯ<ญœNn‘ำงNหข%KฎIˆVำ‡๋ฝฌ๚BeฉZๅ๙Iนฺtx๛ฉPกœTญ\Yw+I’›$gฮ์z�๏ฟฏศ๎�ป}บปaำฆ€NmแŽ ยเUซ๚‚พ^0–��๓œ={N~๘๑GYช\wŒ่มtd่เ’B]�H™อ,w�ๅœtไศu�lŠษ?๊ใ๔kฏท๓ปฦ"นOœฦร\ซTก‚ๅ‘L%mฺดrๅส?r๒ิIูผ๙s™๒ษTAxBwช]ซฆr’+ฉฎ๕ฬ*T`๙[‰ผ์? .๒}เฃ{ืฮt3Ÿอ˜กœฅ๎–’%ŠIถฌYต๛ศัฃื"|„w'qฒerZJ—.ญ<๔ะCบศ™฿~ำว4ๅ�๘๓Oyตu[ณ)‘Ž ชRน’”)[Z‡aLงุ\Pฎ€๛ีyฮ[ฐP๕wŽs,๗ \ ž;๓#™•๘โ.ฝ๛�๙ Z์ฐQ]ฏC‡๐ฉ์9ขD$ืB0Žฮc ”Cิฃ๊š@อญธO<$ŸพU๚่sŽ๖ฎ‡–-šI๖gž‘4iำ่นกŸO>%�ถm—ัส๎”š๗L w>ศ�H&™3k†nๆงใ?Iู๒QsŠi7ุeธืA55ง•/WV�ง�๋๔n�|(ZคˆไฮK๎ผใ๙ํ์YๅฮธE…โ�Xาซ็ฃynE7งมA ฯค๎={๙�ŸแŽIจฯอ`ูEWP�'Yิ<’2UJน๙ๆคrP9~พukภ็-D„Y™Rฅี๛ิใข”V๒ร? œฺฦM˜่yุRฅJHํ�.ชฟ_บ(mฺF }<+^อ ๗:@uฬ 5kV—G2fิNu7)แ๋/ส…ํซฝ{e๊g3ยJ“bc๎2m…ฒ„ ฉpก‚’#๛3Jไ—NRฆL!ธ/>,฿�๐ƒ 8ุ๏ฝ๋zฬ]…Uเม*0’[ืตหป‚๛ฮ$�™ฎ†Eฏ†^ฝvญ~พ™rfi฿_K•ธm๚Œ™fWภe—ฮ๏H๕ชU๔~8่๕|?๊]ัT–‘๛f วŽ/ฉRฅ’็ิ{l&u ]ธ๐ป|๛�ท2iา'ฒ~ใFs(g9lศ K ™K_iึTอนQ}แ ัธน�ฐ�t๖จป`=บTN=C{๗Šr@�QฝWญ^หณxจ๏�ืCˆธ~ํ*=wใ๒ๅ/ไ๗.g_๓Cฌ่•&Œ-9rdธyฮW๏ตjFอK^BD[�ุซ๗‡๒ูด้บIœ�ฌŸIŠ)œC4nา\�› ฯ�›eๅชีz~๑zs*q…H€H€H€H€H€H ม 1ม ;J$@$@$@‰“…ˆ๑w\ำ(1Kz %I’$ฒcว6นข„Uy๒ๆำŽIˆุR‰l’%Kฎ>^�,ำ>"ฏถy]ื‹ฯBD„Q5กสผFe“ �ูขekฟ]EŠ–๎];;‚.wˆ�h�–์�นหฝK 6่�งทฮGxผ"๊ร3>จปำœy๓n9๚}$ฦQฤ�ศg—o�ฐดmำJg-\ธX:u๎โ์ฦ๙๕๋�Gห๒จ“gฏภ‰ ขˆบผาฌำ$‹๒�ฉ„TQTฌP�ซ˜)^สOเY0d‚W-%h+]ฒค�~{j�kใrี๎๕ถRฟ^� ฮฤ"•"“A๚๋k&ะม!dลh;ู็ํ|ฏ๕Š•ซ๙‰‡ยฝOผฺ6/}๚t๒Q๏œ0–^๕vจะŒ ›4๕ูe‡บ๕ูquร} ป ๛;d๐]โ�น๓rวท_-ํป2lธŒ=ึ'๓“Iไฉงฒ๙ไฺฐ…‘Œ „ก={t•ล;[! $Dณ๎a„'ัฅ:๕ศž={"กœใ}>Rย‚iN�ุZ UˆมNำ&ดˆะซ฿~๗ฝผาฒ•฿œ…๛~๒ฤ๑>โ w�AC†๙„ส w>ภ<`ByรกชXษ2~�q��Žไ:@;๏v๊(5#A Tฃz5ฝ๎�ƒ็ษ>%ฐ7ขIทธส.ฟaํj}�ภแฌTู๒>‚อpวํ‡๚�ด๛ฮ:žฉฏถ|%เ๕ƒ@X|ๆฬŸๆƒนฏ�›ญZถPกL๛ด‡ hณ็สใ—o2"ฝบฉwˆ๑�็•๐ސ#w^gW0็h {=OฬพP—1c๑Vวw|D“ืc๎Bhy\;H -Q"฿ฮzโ+ผ ๒4้W๕ฃ—ข%J้Mธโ9t๓อ7+มฝฟC*Žƒ๔ำใ„=4nๆํ jฺ6ห๋ึ8๏0ต^ฌ#๛พ�ึ์าหPูฯ0[ˆ่ำ ต๓๘จ฿ว1>bCˆพ“ฦG=Ÿๆ�๙…ญž^5b˜ไอ๓œ.1ซ—P8œw~!โŠ•Z(›,ูญฒ�ภมภนบวvD„CใŸJˆsฒ๐^˜{ย<ฯ๔+‚แYŠ4ม"yทKWฟ2xt~'สฝแ”/�uู๙๗…—q๋ๆ ฮ๓ฒd™rNแkฺN๖ํง�ญaฟsแY'เูsๆ๊QุๅนN$@$@$@$@$@$ฐPˆ˜ฐฦ‹ฝ%   DG€Bฤ๘;คMšทิny๘ˆ5b่ ๕!ฏPPBฤ๒+หc?ก]วฅDkฤ{!"�W๐๑ โญํส๙๐‡๏Pฎˆ)ไi%,z๚้งดณW๓W^๕0คๆฯ™ๅ|xร‡ม5สฝB’Bสญ‘9\ู‚ ำ๐_�%๛๖}ซ\ํฮJ†‡2h‡3#D,Uฒธ๔�ฐ.บ}วNiิค™ฉๆ,vŽQHNB@iาŒiSๅ๑วฒ่MŒ๋2๕A๔์ogตฃ!>�"แcqZ/z~ 5BD]๐๊8ูภM1ูญษซงด2!"œWฦŒn"ฦ๕ 6J�7ฺวX.ิๆ@”‘๕ชห]้ฒๅJ่ะI๒ๅษฃฤกE๔.ˆ Œ€Žt3h'8j._พาฮ’pว]cFEqยว�J่ QBจร๕ํy%พrๅoฟะžฅHๅˆh‹ะ!8ื9|ฤ้ฎaษ์๎}bทฮ๚ุั#”ณZ”ฃฮu๓็Ÿห�๗+gฒTสฉ๎iํv่"ย ž&แ�pญรI1Wฮ&[ u!H4ษ�(n๒6l�$'Ož”ผy๓H†ิูถhฤ”ร๕ก.RFๅgS$„(„�•I�๑ง _$cb ศภf�† rเภA�ฯโส5ฬ]�� ทvu5}ภา ภ�้ห�{ไื_•๎ป_ , Edn!bฐ็ˆ๖gฯ™็'tA~ค)!ข{Ž…hl‡บqํ”-SZ‡ฆDผยeŽ=Rr]u๔ƒเ๗ุaๅzฯ=๗hฑ ฎ8FŽ=ฦ9ฅHๆƒํ_l‘[•ณ,ฤ�•›ญWxf็`ึJ$ืšฑ๋›fบ๕�oฟ“ฟ.�ฅŸ)pฺ„๗‹=og+SKˆu}�Ogแ๊5�WTษ˜ Aw}ไE๗�ฤ�pœ*gN�L ยะ๎8ช"A|•4iRฝnžัzใ๊#2yผ๎ฺตK2fสจŸ&ฟ}‡Ž~ฯ<ห–Žฅก\๙๒ๅไ6uอฦ$Dดว1ิ๙ ล+อQ“๐<ูญๆ< ห’E฿ n!b$s—9N8Kร๖€rฅD่�ใ'NHJๅถVR ฒ๏ฝ๏^�ไฯสลฑธ๔št=ๆ.<ƒ๐,Bย<&Lœฌืgฯœฆ�ญ!"ผๅ–จkศอ.ษP#8~Bชึจฅ฿Oแฦ‡๚w฿ๅ`;pะ;~‚.�ธ9ChŠ๔ฝrไฌ^ณถ_๑`นŸa^BD<7๚้'}�'oผŸ”*[มOดkw$!"ฤใprญQฝชv6Gปkึฌ ๊�๏๓ห/ิฯLŒKก"ล�\ร}็ท…ˆ๖นโ�:u๒”~ไฬk ํบ๘ท �่9ฑk๛V=oแ\r>—ืฎชืmฮ+�ฅpอ›=SฟUNะๅ+U๛‡N^BDs_โG?ค ๅหJฏ๗z๊u๛ฯ˜ฑใB~��๏�ท�zซฝ[ะฦฒๅหตำ'ฎW&      „E€Bฤ„5^์-    $:"ฦฯ!อฏD‡ฯ]u?œ7{–ถ�”1]บ๔๒R�๚ฺฅe฿ื{e้’E๚ใR|wDDxม‚๒๋ม๐๚จ a_ ๅT่v5D8ฑR*์+„ญ�ผๆ๓แาkxนซธ๘จ�Nน'ฺ.)(s๑ยEGPh\ฆ H(^ชฌฯ]�UหํTe ณN��ณ4n๒Š�]๗n]ด่็โ๕Q๙ถ"„r>bv้„—5ชU๕ๆ˜}ม.ฝ„`1ี5๎„1• f?D‡=Wขx1-�ฐ๋เร่สีซeฮ�น>.qv๓!ึ-พฑห˜๕Hฦฤzฦ"— ฝ|ล*s8ฟ%D$pลC‚ศ6ฆ0บแ�'~!รพGเฤู้�ฎ*„Ÿ๏95lPO‹2๚}�oˆ�ๅJP`)p5ย�gา;owTcๅ�v๐ะ!ฉ\%j๛�ื฿G}๛หไO>ีUแ6ถ`�I“ๆฝํๅ(ฅwจ?oА“HU9p๐PฝำŸPฦ")ฬ1Ca>h๗VGYฝzsˆJหห{=บ๋m„ึ-\ด„ณ/wฮœ2vฬHฝ ืึ"ลขๆ1ง€ZA˜J8ตJแžc ๖‚อEˆธdัฯS.’๋ภดa ุทv�zy๛ํw}އpฑ๕Sโข&I›V-u๕ูj>์ึ�=ำ”^ฺฯFท3f$c‚ฦํ9�ม<7Q.œdŸวถํ�ฅqำ(w;ดe๗bŸr+๙\ f์Qึ�Œฒj฿จิ~ฉŠLŸNž(ูฒeVˆษuเXAุ†w!;anฌQณšzฯ‰rธถ๗a=”นห]7ิmkใฆอ>އฆนณgศ#™2้อ6ฏท“ตkื™]ฮ2ฎๆ.๛๚้ึฝงฬž;Ol—DˆฑชชPษFT่�ว8๕c#œว��Zป7๕๐C$ฏgฟs’ฎ8šœุขHW1g3Fn!ข™™ฦฆLœ ~ะๅ วmธแJถ@.˜ะฬ˜ว?�d’t�โหM�G”pผqณW|๎Kณฯฝl�๚Ui�จกฮฦ�็�ฯP�๙ ํ> ฏ๕6๑yงว�@BDSฯ~ธบšWจฅฟ7ฝ.ๆ๕�ฒ฿็๖๎�Z?�L›X๖๛จ”,Q\gตVแเื)&ั ํเQฎBe=ๆ ย๖3f9โZ� ธ'๐nUU…)‡เ๚?OF�J๏ธ๚็ซฏ๖ส�๙ ด[ฏฯu      ๘K€Bฤ๘;6์    �(DŒร งจฆส NZง” ุงS&๊Nใˆุ๔•–r�mฉต+�ะA๋zpนˆ๏BD„ศƒา{ฝzkฝรใ87ฆาๅ*๚}@„›~H^Œm!„0ต_ชฃƒX๎]ๅ…Ju›๎ษˆ�H‰j;ฺู‚�ฟีมO !ยาE ดƒส๙๓ค@แขบ๛-D„๓Z A‚]'ิu|ฐ…3S(้+๕๕ณiำCฉโWถฮห/JๅJ•วHSyฟP” ๊ะŠ&?ะาˆO‚"F2&ถ[’qg ิง@๙ก GยฝO?˜|;�ด๛šT‚:ึvๆ1ๅ๑ั{๕สeŽ“ฉBะ"BPกrUSM/ฆะธ^น `("๛กŒ‰]vฺ๔™ืCwZ4ŽdศAg�ยI�QŽL%หz‡Ywทgo‡{Žvแฌ+Dด๛๗rŽ‚ำซ;ฝ฿ณปb�-฿นํsว๑ข ˆ+BMกฬธ.‡์ˆ…�ว‚‹-ฦูํœษu`Ža �NrฆŒฝ„ะy๕Šฅ๚=มKศบeำz-.q;‹E:&่C8ฯMป๏กฌฏ]ฝย‰น�AัฮบŽษHFhฆ7ิ3๖ุ†#คํn‰ฑF�ษ’%ำล๓ๅ/ไ#๚ิ™ึŸ`„ˆ‘\๕๊ึ‘๖oผฆ'Dฬก&๛๘ม�Cm?ุ๒“AT†d ษํ๚๖uŠP�n#˜u�อ"ย๏•+ๆฌŸ้gม�sด[0†๛l–rไผ็žป๕แ๐Lz่ก‡๔:ๆํชีˆ๖บ1}„Hl��™๚GB—��[ )cฝPูBDฏ๗G„’<ฐฟ๎ฮ?๎—jส�1P UˆDธ–z%# ๓ฺ็ฮ[นlฑใขˆฑฒE�ฆlธ๏�Fˆˆนu๋ึmสy๘น�Ž;”ำsNว9ว0bSs<,!D,ญ~๐ดsื—ฒ_9ฒb�Rn้ž�qj…›ๆหu๘�๛ม3 1.�WLB˜ไaส้�„`?z์˜”ฏ๘‚ูํใhkฟ๋G'Dฤฟก๐Žˆ๗ืšต_าœpโDย�ˆ๗้ž=บ้ํ@bOผฟแซTษ’ฮ>t๕็๗฿—ๅ+WษงŸN๕๛a€)ร%      @� @!b�๖‚H€H€H€nX"ฦฟกฏSฏกคM—N‡ใ=r˜\บxQw2&!bกยE$g๎<บ์RๅFถ๏›ฏ๕zB"ฺโ>ธฎญ\นZ>�bซl�b[@'[์„E่<“ฬวฝ›Uศฝดiา่l/Q“-จ€�bƒฦMM—ถ€ศํbb;ฝXงžป—-จ€หึ?สม ษ๔Kใž‚|ท3๒l!b“f-<�ˆP.ก%[|f๚‘ภๅ7}ๆ,?ฉ)ใต4โ“`„ˆ‘Œ‰ํv+ยoุฐI…�๔ฺP…#แ�'^ŒBษ›ฃBPfฮœYW V f‡…]ฎยทWN๎ทB-์ะฒ๖ต7ภŽ�๑ฉj‹\ฐ/c`("๛กŒษภ�}ฅhั"Nu3™{;Œ+$ึ;w้&๓”  —ตซ–๋u��฿J๕ข[ท๓ซSศต๎9บš y3X!b�—_’7�ฟแด๏ลsžแวฅ.]ป;ๅฮ›ํˆ~ Yบt™š๓v่{ a1ƒIกฬฆ=��/(Q๔3ฯ<ใ„m5๛ฐ\ฅ\Y_o๗–“ษu`ฑ…ˆมธกž-Lnี๚5YฟqฃnNšฝ{ฝฏื��Hว†๓�ิ ใ?<3K(bwฒ็„่Fจn“L]/ก&สุnwถHุิท—ม#น:ฟ�Iปใ˜=฿� ,็ฑPๆ.๛�ย]‡ซk%rบ��๛ิ;kZIv5ด+ๆถคส% ก_แฮ็Nq5wูBD�คšrŒF๘v„ไmิดนžkํyฦ-DDฟัื!ƒhัฏ9ฯP฿ทš}^หŽoต——^Œ ล์ฅy•G^(Œl!b Pศ�ทnึ้^BEปก !๊}งำ�*ฌ}R-$|T ฦ œบt๏กรษ�วpฏ�๏ ฟ�๒ซ+Yฺ]D"}็‡�ถํธk`฿{ศsฯธžพ๛ิฉำฆŠ^ยฉ}ธb?’{ฎ…ุp๘ฐ ๗์ู+?ุฏฏฃ๒eห๚<[��>1Žา๘๗Pี๊ต~ฐBD�?่๓กŒ=R�–jฺผ…TฎX!F!ข>™ซp]ฝ ๊<ฏ๎[•ใฅIn‡Y“ฯ%      @�!@!b� ๖„H€H€H€nH"ฦฏaฯšํ)UฆŒ๎ิ๎];e๕ชNฃ"ยแฯเข๘ซlLš0ึฉ—„ˆ๘ภ8๕“ษ’๑:n(y_lูจ๏K8ซๅ|.oPUแn๙V๛(๗ŸOง~&ฝ?์๋WฯEŽ๛๗’}-L˜8ูฯ}ฮnป{ฯ๗eึ์9~m##‡�@(cb฿vึ�๎`^ก€QโƒyJ”7|ไ่hฏ�pฯ1P�‚อVˆh‹๋‚i�- ฉฆBEvํ๒ฎ_Uฬ� 6าวสฏ สv>๐ช‹<ˆI .จ�กJ8‚ไ�Žs‘^hฯfีฉs—…;จƒ๐ๆsŽดpั6ฝณ^คœฯŠ(4$w[๖qt�ธวลร}nฦp(ฟ�ถ๐(K`… ๅ๗า‚…‹ไฮ]vฬุr€ณCŸพัพƒ_ศyง!ตŒ1’๋`๔ศแ’็นจpฟถ0�๎CL๋กฬ]1ตำ~�)7บฒnืhS6ฎๆ.;”๏–ญ[ต}ฐร™Cnฤd�ซบt~Gชซฮ&y…ฮ6๛ผ–๖1ขs๒ต๋†ยศ"NW๏MpwงUสAี�0็้์น�ปํP…ˆNลซ+xท๊�ตณš'J๊ธ"—)W!Zศมสมฝpม‚บ| w{�qำk�๋฿ซ๒์…"ถr๒ฤI)ฅฮำNถใฏ๕฿ีฬŒ`ำ�!”6แž‡ ๎TNˆh\Q๘๔้ำrแย�#8๙VซQ[�;ลข�ก™xฌ”(^\๊ผT�qญG =@1‹H€H€H€H€H€โ ใู€ฐ;$@$@$@$pฃ 1~ธ ญ กลw฿๎๓้\šดiU˜ฌด:๏์ูณr๒ฤq๙E‰ทm�"•^จ*™อข๗:p@��๋Oง.ฤ‰=�„�พ|๙ฒุ�ฃ�ญB‹ญ\พิ)V :h�ฆตภq0eส~]r‡ณ?�t�'๙tj๔กฯ;+๓,๒iื�ฐ9bิh6|คฯ�@p๙ย=$ๆ†ฅร*"ผ"’ป-|ไ6๎gpˆ๙xเฟ.)บ‚๛�ษŸ|๊ฮuC…๙5C๚ZซF๕J๙๎�๎‡<ร่๙– ผ…ฐ…๏๗์ๆ„ุ4%Fnวฮ*,๓"วIฮ์ ด4โ“˜„ˆฑ5&ิ—:๊ZH“ๆฟ.แรt•๊5~€G8๊}โืฉ3L(D|ฬฮ๓|”P ฆ&ภb5ค‰“&Kฟ๚Uฑ]ˆ์p์ถNZpิฒS|"ฺNZ“&O‘Sงถป๊ทQ—;ผpฉ’ลฅi“&~!ษQ‚ฤf-^ ่บŠPลฏ3d+Dด<แศด~C”c_ CงยIBเ`'8e5ช_Oฒeห๊ธฌ™�xN4DฦM˜hฒ�–มฮ~]ืLŸ๖ฉdx๐AฝวD(iคุธl`ฐB4๔i�š•ฺๅ ข“�…Š๊pฬ&ไ0„.ฯ(ฌ๛h�ฤฦ˜„๛�4}v วฑiSง่โ_}ตW^ฎืภฏj™าฅไร�ฝt�าeหๅญŽœ2f์‰mWึ๖:ส๒ๅ+บ๎•`„ˆ‘\“ฦuB‚ปรHป๛h;œ็I ถขหo๑J3iัผ™Sd— Yป{ฯWrๆท3๒ฯ•$w๎\Rคp”ึผ9…ฏฎฤี�e‹บL าช\ฅบ๓\��ลํ๖†wณนฝล๖cF ื๏ฆฆต๋ึK›ื�u{5๙^K�ก4˜ฐ๋ฆPูBฤฉŸMSnx™fœๅๆ๋แ[tกศ#"šฺ๗C Pห(‹w1„eNzีEณŠ wฝ�ภAำŒณŒw~ง1ื �v#M๙dช|ุทŸซ„๗ฆ�ƒ<žษ%&ถK#4rํฺตไaฮ9EŠ๊>๙Mv์ุฉusญ=w-^8ฯ ฝM9$#ดIfzฤqNว^พ๛แ{9zไจ๔๊�ก.bๆ1�3K8ˆู้ห]ป�ฤq๖�%‹ๆษ๗? ณข/ุulแ…�ฅฬ”๛Xอ?ล‹ำ›vXY๛๚๓๚PŸ„ˆ#G uถ" •ž>}:ๅโ˜_*–/งI#นร=๊ฬซBชุ๕ฐ๊u`ืVˆุผiyตๅ+บช�ูษn/˜u>๒ไอ#ๅห–‘B Hฒdษt5#ภ ิF(๓A 6L~�6ญŽTHvศ๑ุธl!b(B4��กgSงพ]บ*๗6ค%*”u‡ทฃึu†๚c๎sำ๔!ุฅ-๒9z์˜~ฎบฺ๋๓ฤภ}๛pŠ˜ฑ๗r*C!„M…ใ%R๚ กSฅ`„ˆ‘\ถ;jt!็๕๙‘>Oขk��q(„JHถ›ญ)ำฒEs˜ )ะ{U$s—9N0K๛z7ๅqŸ,_ฑJoฺ๏rB�โ-ำ–ธึpอล”F&y๓<ง‹แ&pฦ &…ยศ"z�๗8\นqOล๔ฃ‚ุ"๖๙เ})ซ�ๅ9cbDญ`Œ๔๕7๛ไล—๋๊u๗Ÿุx็wทiถํ}6mบ#์3๛ฃ[šyebzG‚่๒ฬ™3บ9๛๖�e ฃ;ฎูgฯ[7oะbGณฯ-ยถLแT ๗I“ะท*U”rๅสj‡w“%B™ใGAsๆฮำ๎ป๖>ฎ“      ฤO"ฦฯqaฏH€H€H€Hเ†!@!b�๊z ษw�+ผณ{aŠงเฃ�?w๖7†yœ”.[�q=ด๋่๕$I$้อ7๋Uˆไเ2‡บCU(ด„Ld๔ตs—nŽ3ž-R@่ท‚EขDMกœS$‚Š93ง้ฐg8^๗๏9!D97อœ�™๓q/&ัC sˆ !"„h„’๒กJc3A(Uํ…**�ณ’D]รvย‡W|ธ6}ฆญือGa„๔Fx๋่RlŒ‰W๛ถศnฎ ฑ�ฅkwฏb๒z�6าฐA=ฝ/ฆะ ž X™๎ซˆอA,cง˜bถˆ.Kp[Š)ู‚รGE)@๎@IDATKลสี�ชฌXบX พCย~”Cบ�BฤPฦฤvQ:l„Œ=FŸCคjืช)p๒B:rไˆTจ\ีณI[จŠx"_ž<๊u`w X!"�๛~ุGW-ฑ2ƒ่wฮฌN—…SEPๆงม+vจ่ีซื\พbใ:Wˆh;ฎZฝZRฅบอ=ู_sJฑ1&‘<7M?‚]๑�๊J”.็ˆxL};๔ฎ{~2c๗า*d๊ฉSงM5ฝ\ณrน�sฯ�z=บk‚"Frุbฌ+WIป7;่~…๒'”น+”v�eฟุฒQ’'OฎCหบ7Qv�่‘’+WN]-!b(s—ป/1mV!สซPๅ&นC7nิPฺถŽzw๛\ใฆQยiS�#ิ๛PRๅึ‡w็ษS>•๚๕๊่w8ี5R?€‰NภŠg�ฒล ww๛YgŽhiฯ๏cว—ƒ}Ÿ�v=[ˆx๔่Q)_้฿0า(g .=“M{ฑ%D;z„ไฮ๚ใƒ:่-Z0ืqšu‹ใLŸฐŒw~ป={}โธ1’=๛ณ: ๎‚ธ&ƒI๖ณCฬ#มฆ@Ž‘ƒ>๎'g|ุณ™๔้า;Ž๑�๕—?qB<$m฿hฏหO2Iฒf�^วœ๙r�1ขIืญ‘�oOญ74n* ฮoซ๗|J่๋�Np๐\ผx‰~ืvป9�ๅธN$@$@$@$@$@$�Pˆ�ฦ„="   Š…ˆ gธŸ/PH9BEน๗|๓๕^YถdQPฟ๕ึ[ๅี6ฏ๋ฒ้<~ฬศ ๊ลe!KNž<ๅ„สณ=[ �อœYgนร'ฺB2�Qฤฎu„๗�ฆBƒ^ผtษgW$‚ [8`7 ทฏฐสถHก ๋7jbWsึŸ}๖นp�ผghบธ"ข#๘0J๚M…jsณ ฅ~teถนfชRฎlYG4‚๒„MK อK—�โ%KG�ฏHฦ๎1)U˜=ฏณvุa„ทKWฯSDxo8๑ ูก^= ซฬp๏ำž�ั�ไล$Dดฏs„ดฌ๙b?1ฦ(ฃ๚pพn�z�,ซW.sœyฺผ�Nึฎ]gฉ�๘เ†ไvดป�BฤPฦฤuA ]นju?68G�O้ มฎ ๘๚๋o์,ฝ“จฤTฐy{Thิ:๕š]ั.รน์ƒ"โS,DKH^ย8ไใzษŸ?ŸใR†<ค@|P~ใ๚5r๓U}t.Tกฬƒ•8�ถ]ฮl‘‡}฿Dzเ\ร"ข๎&ล"u๊(q ถ‘นปE:&h;’็&๊‡’เz a3’;d*D^‹ๆฯีกฉฑ฿ํ$i„ˆุ็vขƒะ�ฬA(–,ใ๋‹:v Fˆษuw� cG๋CB8ูL ๛�aสq�Cx:kฮ\ปkฮz(s—S)Œ๛zณ]ชั”[๘Hˆ๎�Fweๅ๒%’.mZ]uยฤษฺเ9sฦTว๑ื�ก ๖ใ^™กยฑงM“›2zฬ8๏/ศGยพษ“ฦ;�>๙|๋๊พmต3†ฟ]”kmuu\ค่~lเnŽผpๆE๒๚7ํ ็หb%�}nPฟฎvME][ฌjฟsaท_(Q๎ฌYณ�žษุฯD$@$@$@$@$@$0Pˆ˜0ฦ‰ฝ$   DK€Bฤ„3ด‰Yˆˆ‹exPึ(ฑฤL‡•ธ_ ,(+”w b�ีn5cF w๖#Œ้œน๓ๅฤษสm-ฝ<�T6ฉ Bโ#tงw;๛…‹DPฤr%ต�๚เ@Rฐp1ฯฉ๘hนd๑'ไ๐ƒe�๘‰r๐๐!I*ต<�๘c*ฌoy�ฑ,2{๎\้ึ�=็ผฬJ\ อ๑โ�"ŒชU^็r็’ํ*<3ยแบ“Œ N0 -‘฿~;ฃ]@�qฟ ”ถI‘Œ DŒ5kTำ�Xบl…�ศ*EJษ•;งผXซ–ใZ๓^ฏ�2}†ฟs#๚`†ป ย�}๛ํw๒็_ส๕1x๙๒•ฆซz๎}bฑ?๚›<[Pe๒�หe‹ศ}๗฿งณฯ(ั)B&ณ๏[นM…‘ฯ‘3ปผTป–ิํ๓ G?#ึภ๑!C‡ \*Ÿส–U‡a„@ษ~ูfโ�‡๒๖‡๖๎=฿—Yณ็ �/…"โฐ+�วfLฦ-9$ˆวO˜(_๎ูฃท3?๒ˆ+VD;QVฮ†•ซTื๙๘cDK˜,\,฿(Aโj�sfฯ.Uซพเ8D-]ถ\�ุ๊ษฉ็^ูนํsวลŽxC@�‰๔๙ึmž"‘pฏs์`…ˆ(฿ชe iึดฑฎŠ๙qฦฬY:�๔๙ ็ๅก‡R๗rn)]ฒ„ญฺ‚B�›pรƒหิ"ๅศดmวN๙๙็Ÿๅ?O>)ๅส”q˜?~\ส”ุ˜�ูหPๆช"พ+W๊น๋xแ^$S&�4œ…!(ฒEคแ^ฆฏ‘ํฐพฆ=ธลพ�Aoณ้ณ wLL#‘<7Mม.mQ.๊ภฉlอšurOฺ{ไตึญ$]บtบ)/qฟ-DD!w6mฺ">šYZทj้d ฌ…เบกฬu‘N๖\y”๕C๐ๆ4ุฟo)Qผธn๗สค)ŸจPl—ฟี:�๊ื}Y‹ใrไฮ๋y�P็.ฯF‚ศœ2qผ‡>ฅKbNวผ_=[๑์ƒ่๎ึ[nqZ $DDpๆ.งแV�l๗บิญ๓ฒฎร &ษy5G–*Q�9฿�]ž/XฤงU�ั๏ห/wkกซ)0�ณOๅ 5&H๋6lึW์c๖›ๅสe‹k4ง=ิๅๆพO๐CŒƒหแC‡๕3จVอฆKโbฎmงว๕gิุโู…t๐ะ!ูฅฮ ื~ฯ๗z้uˆฤ!ฬ�๛๏+ฒi๓fูง�0งPmๅส™C]วลœ๖NซyปDฉฒบž๛O฿{ซga “@…ย}็‡ctšดiดภ๎ห]ปีŸNJช�RI2�ฮ0iวŽ]>๏1[v~็mม9ภM๓ โ๙‡๚Aำƒ๊‡ีิsbU$<^m�V6nฺlšาKฉ๏บ๛NYบtนๆƒ๙*�๓๙œ๋…ขs๔iLmฤ$DฤXB|Ÿ,Y2]?PXตf~พ6nุPnน%ฉฮ>r”›Ž 3oเ฿V .”i๊}ี�w–ฎภ?$@$@$@$@$@$@ Ž…ˆ nศุa   H\(DL8ใ™ุ…ˆ] $ฮ๋๘V{y้ลฺัUี๛b[ˆˆF'+p04iำ–-าขekณ้ท,Wถดt๋าู@๘ธš่\ot!ขแ่mฉRyบFฺกJMyณ๔ y๎˜ุnŠฆ}๗๑m๑™{?ถอ˜zํs‡qด�€ผส#/ะตƒ}แ ะ ˆ๘ฐฯš9ฺ๑J๎๘๘@?}๊G„แU็งใ?I๕/๚wอGq”ฟBD7”1ณืˆaC0ำจ๏•�ื‚"z•5yp6hิิ'ดขูg–ถ๛ฆษ3KwจZ“๎u`๊‡"DD[ธdฺ๐Zz ฝสูy:w‘…Jศ(…2!b ถLพ�™๙แ^ฆอH„ˆ๙๓ๅ“แ*|ฌ๊ิomศุpฦฤด—BD?6€)Pย}าขUfิ.ใ"ฺ๛ฬบ๛พ4๙๎eฐBฤHฎ<ืึ8C† ๎ร;�("ขP(s—ำhˆ+p˜F๘ุ`RtBฤpๆฎ`Ž้.qึธฑฃไษ'žp๏า�ำu๎ฺU/Yๆ์ทลบ˜WฏU�Gœเi๊๙–2e ]วKฬjsrปำ9Šf%!b f—,]&�~วg7ฮeมผY>y6สUจฌ] 1P9“แ'\ุ0.๋ึฌtM[ช{ุ-ไsืมv8๏�"ฆฟ7ฝWsN�ูs็ไฅ—๋๙ธ\!ขS(ภJ ๐โธF]whjฆ๑๖P?จ6ล$DD;pxฤ๓ฤ8ป�v‹jฑ๓ซ�ี]�$@$@$@$@$@$@ ‹…ˆ kผุ[   Ht(DL8Cš/ษ›/ฟ๎๐�ฏ๖ศŠeK‚๊�-สฆ• ำ†tVน™Wdใ[zฝm)Sชคใบf๗๏�๙ 2m๚ ฯฮทื!^๊ะกฝใ"f๏ƒฃึFๅ‚4B9€ธรฺ่ขงพ� ษiทgฏฟจœเ�๎๐ฆ“ๅํ็์ฐV๐ัทGทฮฺล�กก้ถn�&Ÿ~๒™_W4๑ษค ๒”ryฤำBEขœ“ฌฆนz•„9/ฝT[ฒ+‘h*%X4ฎ• .’w:๛‡IgL*จะž๕๋ึ•,ส]ห8 ™€X.‰}๛์้Hgสa ม^ซW[H๎\9”sg:'œ1�‡ส”ฏ่#~ˆ๔>AˆS8๔ุiเเก2v�x;หs"™�ปJ๎œ9>S๐่ฑc2v์x%‚œgฒ๔Bƒ”ใั๓๙๒๚0ยนญ[ท^…; ฃขtศฐแวF;U}กฒtฺ๋Ygu์๔Žxฤ.gท3tุ9zŒฝ;ฺ๕Pฦ แ<;ฝ�AJซ9ฬ8=š ฬ*Br.Tฎ~+˜แ๕�:จ๛9ซ_”pcภเ!ั@L .deห”–๔สm้Ž;nwŠwํึCๆฬ›๏l›•Hฎดa‡๋๖เ˜ใุหF ๊K#V๒๖�S�ูz�๐‘ร๊zุ ๎—>๛ ่ฏ๎แg}ฮษภ57rิhA่๓˜Rฐ๓\ำJ*'/ฬฑ๎นวภ๓cดบฝ˜b8ื๊!ต{ฝญิฏWW;kีจ๕ขskT‰่�ฺฮkม†๚ gLะ‹HŸ›ัŸ‰๗�๖oผ&ตี๓ึv�CI8๒u|ป“ง(}๛ึอ๚�BHt�‡ฯ็อ๋< เ`ถ๕‹m๒๚ํ}„ะ�G™7gฆdส˜QปยE็ˆˆ๚‘\จ�ŽšK*Wช่๗ƒโ-^ฌิPฮ+…:wyตLZmZฝ๊soโนทsื.™ญBG๗๎%ฎŠ้ฝ*ิน+˜พy•ม˜๔๏�‘ไส‘ำq…CนำงOKฏ>ษjbุNๆฺA^๛ท:x†จตŸEฟ_ผ(ฯ(l7แ�ำศŒษูึงโีPžaถธnจ๙๒>งgMป83ร}ฯ๐l_ช\ฝๆ<ป,ฺ(Qบœ~งมuึE9fW!ล๏บ๓Nป˜^ว�งศสmt�ƒ~๛‘aฯ#'Oœ”Rๅ*x–๓ส ๕ฟฯ๏KกB๕ฝ้n็fฏ๚๘อเฺฑใ›๚�wืร6~Lัฏ� Yนj•ืn}/C˜4i”ก)วม‰“'๋p๓&/˜ฅ�oŽ๊๙7l๘Hฯj•*–W!œ[;aลQขะอสฑฑอ๋ํ<๋0“H€H€H€H€H€H q 1q'ฯ†H€H€H€ �%๊ใƒ(Da้าฅ‘?�ผ,G”@ลฅำษใcsึฌY%]๚ดJtyVŽ�I…y>Sต๋ถฎ2™2>,ฟ_ผ$ว•ศ%”sฝnNไuLpอeQแดำฅK+IoพY‹•๖�xภ๏ƒvlb‹๔>‰ด/p๘ษ”้aน๔วŸr๐ภก ๎1ˆ*๎Wแ๛)(q]ค}ผ^๕1=�ธrwM’D‡ ๆZภ5—V…ฟM…Š<}๊gอ3ฑ†Fฤต๛ฤใOH๊ิฉไิษำrไุQฑญืธมe๎พ๛๎“;๏บSฮŸ=ฏ๘ ๊š๓j+˜<�ำ -Œษฉง‚๊ง�v8ื]?.ืร“ธ์Ÿ},xZ๙œบพ�ฝ;คyใš'o๙็ส?ฒ}๛๖๊~ฑeฃยู.ฯ๓ํ.Eปษu€บYิ๙�ts9zไXดฮจัvโ๎„จ๙!ๅเx๚๔/ ฦQ โฒ;๎ผC…�2ฦน็ขปๆM?๘ภ๊/ูไg56�v์ธfวรq๎ป๗^น'อ=๒฿��W_ซCปdp-:๊;?ๆดiาช๑ฟ]ฎจD:x(จ๗n/3gสคฯ๑ึ[oัLฟ๛แ‡h‚sFโqนW=๛.^�Cพฺป7จzฑม+ฎฎุ่+�      ˆ]"ฦ.OถF$@$@$@$" Cฦโ$@$@$@$@7�m๎ภมƒ๒Bี7ฤy๓$I€H€H€H€H€H€H€H€& ๆธฑื$@$@$@$hPˆ˜h†’'B$@$@$@$„Ÿ๚้งt Yฒd‘’%Š;แ|–!ฯ™H€H€H€H€H€H€H€H€H พ 1พŽ ๛E$@$@$@7 oๆi’    DK ฯ๏Kู2ฅ�ส�~๑ขTฉV#Q‡๓๕;if        $8"&ธ!c‡I€H€H€H q 1q'ฯ†H€H€H€H <]ปผ+U*Wr*�zๆŒ|๛ํw๒แG�ๅ๐‘รN>WH€H€H€H€H€H€H€H€H > 1>Ž ๛D$@$@$@7 o มๆฉ’             $J"&สaๅI‘   @ย!@!bย+๖”H€H€H€H€H€H€H€H€H€H€H€H€H€ผPˆ่E…y$@$@$@$@qF€Bฤ8Cอ‘             ภ5!@!โ5มสFI€H€H€H€‚%@!bฐคXŽH€H€H€H€H€H€H€H€H€H€H€H€H€โ' ใ็ธฐW$@$@$@$pร ๑†jž(             @"%@!b"Xž    $"&”‘b?I€H€H€H€H€H€H€H€H€H€H€H€H€Hภ›…ˆ�\˜K$@$@$@$G(DŒ#ะ<              \#"^#ฐl–H€H€H€H 8"ว‰ฅH€H€H€H€H€H€H€H€H€H€H€H€H€H พ 1พŽ ๛E$@$@$@7 oๆi’             $Z"&ฺกๅ‰‘   @ย @!bย'๖’H€H€H€H€H€H€H€H€H€H€H€H€H€ 1ๆ“    ฤ  ใ3B$@$@$@$@$@$@$@$@$@$@$@$@$@ืŒ…ˆื -&   †…ˆมPb             ˆฟ(DŒฟcรž‘   ภ A€Bฤb˜y’$@$@$@$@$@$@$@$@$@$@$@$@$@‰˜…ˆ‰xpyj$@$@$@$Pˆ˜FI$iา[คqณๆz‰๏�ฑMถlฺ่ำ๙G}LJ—+๏“็�ธ๒ฯ9tฐ;›�$@$@$@$@$@$@$@$@$@$@$@$@$@ ˜…ˆ x๐ุu   H (DLฃXฝึK’!Cงณ฿|ฝW–-Yไlcๅ™gsHฑ%}๒��๛฿�d@ฟ�ู�&            Hภ(DLภƒวฎ“   @b @!b�ลGyT*Wญๆำั˜„ˆ็ฮ•‹/๚ิมฦๅห—eฮฬ้~๙ฬ             Hธ(DLธcวž“   @ข @!b�ฦ–ญฺJฒไษตˆ๐ึ[oีŽIˆธv๕*ูตs{�?9๖H€H€H€H€H€H€H€H€H€H€H€H€H b"FŒ     DB€BฤH่]๛บeหW”'ž��๗ฟ�•/wํ”9s้ƒRˆxํู๓$@$@$@$@$@$@$@$@$@$@$@$@$PPˆ˜PFŠ�$   DJ€Bฤ๘;ฐiาฆ•:๕J’$IdวŽmrๅ๏+’'o>�a ใ๏ธฑg$@$@$@$@$@$@$@$@$@$@$@$@$ื(DŒkโ<    € }pฤซ&อ[J๊ิฉๅ?�Cษ๓ -Dผ|๙ฒ�tS}>�๑ง�๖๋ฏฒl้b๙�๗ ๑ู๊             ศ Pˆ9Cถ@$@$@$@$ #€w ซๆWขร็ฎบฮ›=K๘1$!ขWื�y๋–อ๒๙–M^ป™G$@$@$@$@$@$@$@$@$@$@$@$@$@ Pˆ˜@Ž�&   ฤB€Bฤ๘7’)Sฅ’ฆส ๑ฆ›n’S'OสงS&๊N๋ˆ๘ืๅฟไ๗๓็ๅฯ?�”T)Sษํw�ฉ�B#�๛฿�dฺง“ๅฤ‰๑๏ฤู#             ฐPˆ6V"   ˆ-"ฦษุkงNฝ†’6]:ƒแ่‘รไาล‹บ๑˜„ˆฉR�&iาฆ•ร‡๚tยฦ—^ฎ'ฉoฟ]็_ธpAฦจv™H€H€H€H€H€H€H€H€H€H€H€H€H€ ว8๒,H€H€H€H ม 1~ ]ึlฯHฉ2etงv๏ฺ)ซWญp:“ั)่ฑ‘b“ๆ-ด3"Ž๛ไQŠY$@$@$@$@$@$@$@$@$@$@$@$@$@ ‘…ˆ qิุg   HD(DŒ_ƒู๔•–r�mฉuๅ๏พ�็ำ9ธฆI“V็={VNž8.ฟ�๒‹l�บลง\ &อZ8ฎˆฦŽ’฿~๛-PQๆ“             $ "& มbWI€H€H€H 1 1~j๓–ญ$eสTAw๊าฅ‹2rุ สืkะH๎น*dœ?wถ์�๑‡ ๊ฑ             @�&@!b�๖ŽH€H€H€= ใืC,xวwyv๊ฆ›nาก•ฑแ•๑�นณฟษค ใ<หป3[ผฺV’งHฎณ‡ ์/��ทปทI€H€H€H€H€H€H€H€H€H€H€H€H€  เ ฑห$@$@$@$˜Pˆ˜pF๓๙…$O�|บร฿|ฝW–-Yไำ๙คIo‘+Wผล…ฯfฯ!E‹—ิๅQf๐€�>uนA$@$@$@$@$@$@$@$@$@$@$@$@$p Pˆ˜pวŽ='   DA€Bฤ„3Œ1 �พ๑ฆœ?^๖~ตG< งOŸ’t้าKn%^ฬ’ๅ1I’$‰>ูฏ๖์–•ห—&œgOI€H€H€H€H€H€H€H€H€H€H€H€H€ข%@!bดxธ“H€H€H€HเZ ๑ZŽฝ๖c"พ�พCŒ;๎œŒ="ฦr,@$@$@$@$@$@$@$@$@$@$@$@$@$pPˆ˜pฦŠ=%   DI€Bฤ„3ฌ๙๒ผ๙๒๋ร๕pลฒ%>o�ฒ•คL™ส'ฯl�๗ฟ�„svื1๛น$            Hธ(DLธcวž“   @ข @!bขF็$’%O&™3g‘ป๎บ[RคLกC5=|HNœ8แ”แ             @โ"@!bโOž    $8"&ธ!c‡I€H€H€H€H€H€H€H€H€H€H€H€H€Hภ‡…ˆ>8ธA$@$@$@$ื(DŒkโ<              ฤ. c—'[#   ‘…ˆ!cq             ˆg(DŒgย๎   ภF€Bฤmฤyพ$@$@$@$@$@$@$@$@$@$@$@$@$@‰…ˆ‰mDy>$@$@$@$ภPˆ˜ภŒ�%              ]@ธI$@$@$@$ท(DŒ[�<              ฤ6 c›(�#   ‰…ˆ!แba             ˆw(DŒwCย‘   ภE€Bฤkผyถ$@$@$@$@$@$@$@$@$@$@$@$@$@‰…ˆ‰oLyF$@$@$@$ Pˆ˜ †‹%             ?"๚!a    @\ 1.i๓X$@$@$@$@$@$@$@$@$@$@$@$@$@$๛(DŒ}ฆl‘H€H€H€H "†‹EI€H€H€H€H€H€H€H€H€H€H€H€H€H  1 ปD$@$@$@7 oคัๆน’             $F"&ฦQๅ9‘   @"@!b,v•H€H€H€H€H€H€H€H€H€H€H€H€H€<Pˆ่…Y$@$@$@$@qG€Bฤธcอ#‘             ภต @!โต ส6I€H€H€H€‚&@!bะจXH€H€H€H€H€H€H€H€H€H€H€H€H€โ% ใๅฐฐS$@$@$@$pใ ๑ฦkž)   �ˆฒf�L?N’$:|คŒ7�Fฤภs&ˆ#ฅJ—�ฝ�ืG{ฝ�[ฒn�๚8:2C$@$@$@$@$@$@$pฃ ๑Fฟx�$@$@$@$p Pˆx วwศ�!—/_Žƒฃ๑$@๑‘ภŒiS%y๒[ๅ๋ฏฟ•Ž�‰]ŒW}J•2ฅดlั\žxโqI“&�t“Rฐฉ4yสT™>cfภพ>�ะรา๛ƒ๗๔�™3gษฌ9s–ๅŽธ#0q�ษž�Y}ภ๋ิS๗ม7~ฏ]ซฆ”*YB็ฏYปN๕'z�ูgŸ‘6ญ^ี๋ว~๚Iบtํ๎W—$เE€๓•„‘ืตหป๒๐C้ฮŽ9ZพุถMฏฟXป–”,Q\ฏ�๓„๛ฌางO'Kฮ—คI“สมC‡คr•๊๎"�&       kB€Bฤk‚•’    K€Bฤ`I]฿rI“�"›5W4oัูนc›lูด1`ง -.?๑„คH‘R hnาๅ�๛฿�ส… ิ‡ัyrโฤ‰€uนƒldีy๙%ต~รFู๗ํท๖๎xท^W๕5ฅ๊๓๛๗ห๊ีkโ]�ฎW‡๖์ฺฎ�ํw฿KอฺQใyฝ๚฿‹k~�œ™’.]:ฟฎŽŸ0I>8ศ/฿d<—;ทŒ5\oBศ๖QฟอฎX_&ด{3ึู œษ๚~ุG—�๒ห�Rฏacฯš๏๕่.•*–ื๛–.[.ou์คืซTฎ$�ปuั๋งNž’’eฃสx6ยLฐฤๅ|`–ซB/อŸ#2dะ-ฝืซท#@ฟgwฉX!jXฒt™tx;ฐฐ@ฟคXฑขบ๛๖“)ŸL๕่ณH€H€H€H€H€H€H€H v Pˆป<ู    @ˆ(D ุu*^ฝึKฮQtแ›ฏ๗สฒ%‹<{S๛ฅ:r฿�x๎Cๆฆ๋ๅ‹ฯท�ฯืžย„*P@ž|๒ yโฑว$…>=zT๖}๗ 6Bฮœ9sํ;ไ ไ^† ‰^!œ้ภมCƒฌy}Šม]t‚ฃ๋ำณ๋{Tร…Bฤ˜วกE๓fาโ•fบเๅฟ�–=ป๗hG+dฌ\นZถl�ฐ‘ธ%ด{3 ดkผcสฤ๑๒๔ำO้ฃด๏ะQ–/_้yD =ฑ03q9Dะอขjจ๓elsไศ.ฦŽึ|;&ๅ+พpCฐๆI’       \_"^_�<:    �๐(DŒ�—ภ#<*•ซV๓้h !b %X|๐ชƒ Ož8.ว~:&7ฉ�๎ฝ๏>%Pผ_ถl�$�ถRˆ่47š5m,ฏ4kชร๕y๖ทณgฅSงฮฒiK�ฃP?�{S\ๆม…ˆพิ  }นxm๕๏�GJ ฝ‰0ึ‹—,๓*ๆ™w๗�wซ๛ป‰�ทfอบhE‹ž „™ะ๎อN-ึŠ>–ๅQ™9�3��‰ใ'คt๙Š�ฆ1 ๎“@\ฮav๑†ฉ๊|BDภ6uŠ<ฉส‘Zถj#7mึ๋�C$@$@$@$@$@$@$@ืŠ…ˆืŠ,�%   Š…ˆAaบฎ…Zถj+ษ’'—ห—/หญท�ช๛โ%DLฎส4oูZ‡b�็ส?2{ึt9v๔ˆO฿ฆEฆ๋C``�พRดh}pŒ็žฏ๖ส7฿|#/^’<ฯๅธ็ >}ZJ”.งืฏ๗ŸP?�_๏�ม…ˆพ#aธPˆ่หลkหvะห—ฟ\ผtษซุuฯKh๗ๆ๕ึฉใ[RปVM}hธนยี5Pข1ๆ“@ย'๊|[Bฤส+Hฯ�4ภ+WIป7;$|˜<       xM€Bฤx=<์    $~"ฦ๏1.ซ�›žx๒?Z<๘ๅฎ’#g.�a/!b๙Š•ๅฑวฃ\Wถชะห›Ufฆ๘C ^�:า�ืt‡N��ณด}ฝ|�๕7>l�ฆ•4nุ@็ >RFŒŠ ้๗ฮ�%๓#™ไฬoฟษ�y๓m=๕T6Iž,™:tHพุถ]>่๓‘O[*”“ช•+๋ผ™ณgtuk๗z[ษ๚Ÿ�่r�{๖’รGหฏต•l*|4Rบtiๅก‡า๋8��๔บ๙3zฬ8Oื78Aฝึถตvส”๑aํyL…&�๚›}า็ฃ~รOงRaช›*ืศลŠชcงl๗ท_ฯศ๎={dฺ๔™ฒmวsxฑฯ3I’›$gฮ(1็฿_‘�ปw;ๅฐฒaำ&?a’O^8ว�<๙ค{ำ฿+Yณ>)~�]–,Y*kืฎ—๖ํ฿G3?"็ฯ_ูsๆสวฃB[›cS็VธPAษ‘�I›&คL™B.]๚C>,฿�๐ƒ 88 ด1|ุ`Ivหญšฺฑv-ษ—7<ฎย|_๙็uM–O>๙Tๆจkลค่„ˆตjV—า%K๊ข�ธ$ญ�ผnช…ฝlำชฅdอ–U.]ผ(ฏท{หฏ�ปJ๚๔้ไุฑŸค็{ฝ�๖?�ะราฒE3ษ�ฬ3’&m}�€ัฉำงd›บ�G'งN๖ซ‡ŒgŸ}Fจ{ไัG3ห< �(&’ฯ?฿*� ๔ซƒcuํ�ษษG�คI“๊ํํ��ฝึแu/Uซ๒‚)ZุฉoV,\ไแZkโuOt๋�ำTq–EŠ–z/ฟคท<(๏๕๊ญื#น7ห•--•+Wาํ๔T๗๚ฑŸ~rއ•บu^–ž—+๊�yซร�~Lธzฝู.ฺ๊˜2๕3}VฎTQ‹จTœ!ุ„ฐz๐ะแ!ฐBS7’๋mฬš1Mฒจ๋ฉzอฺ๊�๚Qฏ{�‰Dˆ˜Uอ—ธ‡๒ไษ-๗฿wฟ�qวํrๅส9r๔จTใ7๙“ฉฒs็.ฏร๊<ˆคิฏซๆ๙ฬr๗�w้<ฬฃj�:l„Sืพ^๗์�ซ็ gงตbฯำgฮ’ฅห–๋ฝๆยฝ�งO_†�ูgž– สM๙�น๓ฒ๗›ฏ๕5่�2‡ภต๐ฬำOหร?ฌฯ๗?�ฃ๊~^พb…šฆ๚]?ฆ^8หpž'C”๊๙็ฦ๖ํ;๓�ำ๊<๏พ๋.=wlฺฒY็{>�มฝ\พ\Yู่†�>๊#w�yงxอ—กฮv œ}4sf9w�œž75จ/๙๒ๅŒฯ-ท�"งีœทhษจึN˜K1ฎO<๑ธคM›VnV?:9~�ธ์�๗๔�x€็๓$œ๋๏!xA:�๓/’W]๏w*฿}�ฝ๔P๓๘‹ตjIั"…ิ3-ฅ�จ�ฺฟูQฟSุ}ลz5•Q๓QๆG‘tชฟ.\�ช�ผ eึ์9๎โ>ฯ๙๗?่-U^จ,นs็R๗๖ฃ๚>ร�>P=7ทl�๊Sืœ#2C}—‰-!"�iถlŠz�Uฝว-Qสง�        ุ&@!ble{$@$@$@$@! 1$\qZ8๚8[ง^CI’$‰์ุฑM‹C๒ไอง๛เ%D„">�Bt3่ใพqฺW,fkV.—{๎น[~:�“ผ\ทกง0ญฬ›3S2eฬ(ซWฏ‘ืฺฝฉž;{†<’)“^�๋ฏฟ$Yฒdz��ณgฯ^i�ขฅ#�€ฅWฯบศ�ฝ_หKu๋�ล๕:>ฏ[ณR;mB4ฦ3gฮศ'“&hกฃ_  ง~6อgDT�ปvึB ŸW7 h|ฃ�[žยœ๓f „6BVทPืบIRึฏWืlFปŒ-7ขฉS&)๑a”P3ฺ^�ูบํฒn}”YFจ.ฦเญŽ๏(้6ฟ"ถจbฏิฉo“ฬJธโN”Vฌ�oHwsLท#"„.ภbž๙฿��' ‘q&บ› y�\Cp`}6็s~๕อ�เ.แt'O/)Rค๐ซg2 &c”ัZ4o&M›4r„„๎�8�WZถ๒น� ( Cp๕�†ี-,ตlvฅษS>‘๚}lg้uˆชfฉpม˜ภ|์๘ zฐ๗�w�ก๓์�†ซS8š๗ฝi฿+อ_yีOด๓qฟฅxฑbบล’eส๙ =K•*!}๛D "ฎบHaŽ�วุฎ�ขๆ4ฮ˜ ^$ื๊ใ^ูดaญv tขœI๖8Bด๗Vว(q*DS�ปuัลN<%%ห–7UœๅgŸNQโไจ8™ึ „ั‘I“งXนQซ B0]ชSฟ`ŽG‚่lษย๙๚ว๓ Hฑ’ฮผoทa‡„ตCŒ�ืะQ%”„ัขLAH๛ž฿{฿ฝ๎jฮ๖จัceศฐแฮv$+แ>OฬœF˜� jw'๗๓คฎ�พฉ„ไHห—ฏ๖J๋N˜๛๑ @‚Pด\…ส>E์๋ศ�h>ฐหแ์Ÿ�)x^Uฌเญก|‘โฅœ9,พ|า๛ƒ๗ติnหฌ�๒หฏ๊<:๚=oรน *$ƒ๖7Mวธฤ^|๙฿็3๎ษž=บJ‰โลึ]ฒt™tx๛Ÿ�๖�๕�ูณž๏x‡iิดนฺ>GŸ=6�๓el qจ kW;ใSฅZ ูเ G˜E$@$@$@$@$@$@$@ฑC€BฤุแศVH€H€H€H€ย$@!b˜เโ Z“ๆ-•ศ(ตภehฤะA๒|Bฑ๕ko(aย-rV}ค]พt‘<—๗yน๗�๛ไๆ›oVnk—ไฤ‰Ÿ”xaA๔œ‡p€งล+อtv๗๏ษ,ๅb‡TUน๚ิVnvpบrๅoํ'6ธ‡�๐ใ~ฉVฃ–.g ‘งช๕6ศmท�&%KwDWn‘ิ๚ตซ1“ืวo[tฑaใ&yตu”ฆf๊Ž‹XF%ŠDุhค�(g)_‡ธูsๆษพoฟี๛๑"™๙sf9"2๔uอฺตฺีณr„s™eห๛ 8Zถhฎœโš๊�pW�ฎœ๘�% I!O+ศงŸ~J‹ง ข2)_žทผyž“ >จโFŽใำ?[(‡ม์Pcž2U*)[ฆดฆ!฿-0ย5�คQC์าฉ|๙rr›ชƒ4m๚ ฝ4Vฌ\ํ'ลq (จ‹<๘ภ�Nˆ๕่„GA�ˆ๙"ต†Mš8Bณ cG;mุ๗%ษฝi‹y""yํ�๗ญ~๎dx(ƒพl!bธc‚๖รฝL฿r็ฬ)cวŒิ›˜‡ ฎŒ.u~ท“ิจVU™ฟ`‘ผ�ฅซ^‡“d๏^๏๋๕#๊:ฌP9ชŒ�–"Bภ‡k๎จบ•๚Mr็สญๆญlNQ/Wฦญ›78๓ๅ๛๗ห—ป๗ศฏฟ�*�wฟ,X@ ˜l!"ƒ+*ฎ!$�ทŸ*‡J;มนnฮฌจkยoˆM2๗ฆูฦ=ถq๓Iญž'%Šำขd์ƒเึํ ‹๙g๑ข๙Ž ๏'๋ึoะsXบด้ด#dฺ4i$ถ„ˆ‘V&   ˆ”…ˆ‘ผ6๕๓+ัแsW�็อžฅ>ิ�ฃฑํo๊ธ"�~๛ํฮ]ป‡ฉท๘ zๆฬฏv6ืฏ1)'h1Šํ�†ะตM7 xd�iษ"žZ PQ}~�ทnึฮ’8Pพ�…t�ๆ kตXt�๖ําธ้+Nเ~ถqำf?A ุc�F…๏^ปvS+n!"—]Uxั•ซV9ๅภ โ'[ศaธGD; 8%l‡rv sลˆย"n\ทFอaฉ๕‘ฝ„[pH�ทoŸŸc฿’E๓ไ๛ฃ„ฎn ฐณf|ฆล1ภภ!ิ�œชน_Q๎™Q"\ณ/ฆ%�โฦŒŠr‚s๗ม]ืžpฟืจ๙ขิW๎xFŒ A๋ ส= ข\ฏ๊ฝi‹ybCˆ!m;ๅljป{A„u๑ยEำR$c๎u`Xู"ศ;v)ฑgSณ+ึ—Ž0ไ-๋N๏๗์๎8�M๙dช|ุทŸSฤKบƒฆๆx8PฺฉTษโา๗ร>:หํ:‡ฬทฺท“:/ฟจ๗C\�ซ๗‡zฬฝ‰uิ^zนžs5oฺD^m5WนE](฿๙ทฑ7ฎYฬ๏๖๘c~z๓อ7T๔/œPะจnŠไybๆ<�ํ†k 9�ฯ!{Ÿ—hlลาลZpvแ: ๗ู@)”๙mุBDฬ?#F–แ#F9อร-bY#ยฎ]ซฆ œ3„„ 5uBฎรYxโ„1:5๖w๊�E.\ŒUยนl!"œแ"hฯc๘‘~lัX ป�ถŽ๚ม@ƒฦM๕3โX<�“ช[เูู๎ญŽ>๏•*–ธI"ม๕ฐpัz์น๋๒ๅหRฟQg�ฦณs6ย™(\Tฏป�„:_บ๋Gฒm_วxร๛        \+"^+ฒl—H€H€H€H ("…)N มฝซฉrC„3ฬฉ“'ๅำ)๕๑ฃsDL–<™ดl๕šO?แ๓ำฑc’Dฬ<ค>Hร- "ฤ‰ใ|ฤ|*r#ึ ฌZฑTเ5aโd้?` =<[นํ�rKRมGu|ะ?{๖œTซVลq $D๔ู่โ…–ญฺh‘Nยvลr;์Eทฯ๊ว๛]�ทj—78ฅ•.WัLš6ํ0งnท7� ๎ฝ^ฝe๚Œ‘L�˜–F|BDˆBK•ซ ปdBJ# fฑ’ฅu�๔ฯ>•'L;๓ูแ)ฃ;[ภแ%Xp ฝ\หผฺ7\เœว6ใ่7พw”@กhc3‘K8Bฤ�>w\>๖๗BLษพNqŽ5jE‰ฐ์zถ ฬ->ฒหล•ว?fดไฬ™]๎š้ำฅื็๎fิ๎#ึํsF$l‹y""B$U๛ฅบŽ“œปo๎�…3&แ\v?l‘–ํph—‰‹u;”๏š5kฅํํรฺBต@aŸยฎ๓\Aถ�๑6บ}ๆ�D=�้ �๖�ง[ธฺษvู $^ทหGบษ๓ฤฬyธ—สVจไ#\ถEชp“„ซคI•+VPแƒป้อต๋ืK›ถQกš‘a Gฝ๘่Jึ{|c&ฃš�,๗‚ZM๋ี�๛JัขE๔๚ะa#ข)๗Z�ึาจA}ฝ "ฤˆ&…sุBฤž๏ 3fฮ’ สIฏž=tณฦณ˜r7ะ๏#ืZ๑[ง8B€0ไHษร๕ะ์pศถSฅ=wy�หxŸz4sf��ำูsน›ี�กฮ—ž„™iร่1ใd๐ะaaถฤj$@$@$@$@$@$@$@$3 cfฤ$@$@$@$@ื…ˆืn˜MืฉืPาฆKงCฺ9Lป,กฉ่„ˆท฿~‡4n๖ฏใฺ…๓็W.ิ…Pฑ™ gkฤˆpฅ9v๔v1ล�;ท้p—F\g;™๙่�ŽV.[ฌ…H„ˆ^L๖~ป=ดi‹ l‡ฝ7�ฟ!อŒ4i๒้�€^w� ๅใฝ-nD;p€4)I’$z๕f%พ„(ษๆดG๗ฎ๒BฅŠz„ด+U�ฯฟุ*[ฟุๆ#"ั�1โ“ธ"ย๎…ชQŽ“ฦ้๑จ�–ฏ๘‚๎�”‰ใu8i8fa�์AKš๛�๛๏S๗{Zv๓Vฝืฃ &cฦŽำ๋ๆ-ฃ็๒0ปข].๎Bˆุb;™๋.!โยyณ•x๚!�%h—.]ฆ�#wจฐเ�็6wํ0ใุgฎ=s�!/�ฝ้ฐณั…ิŒK!"ฦ{ถrjฤาN^co๏วz(๗&ส�bžH…ˆp%…ำYt)า1 ็:ฐ๛c ,\คท]ํ�ฑพือzu_–Œ3J:uO›๐�ษ’%ืแ•q@8Eถhฺู96ฦ}ํชEภ฿�๐ฃš๗Vษ๊Zฮ๙ ุใi‹้lฑุ�ฝ_k๗O็€jล�›ศCธj„ญถำๆ๋t฿๗8 Ž5]๖�c‹ฐฑผ้๓ฤฬyถฑ้ข-9{Ž๔่๙พูฅ—Ÿoฺ C ใ‡pๆ3ฎค]ปผ+ีชDอ๏^? ๐iDmD"Dlาฌ…งkฎ} �ีุ๋�ภ>O87jาฬฉฮu`_[;ฝฃ:K/.�๛FนsvํึC;๋"l8œ%‘Œฃ-šDพื}๏}๗b—NถHึพึปซฑšฅฦฬNpmฦ|ัi‰าๅ�~ฒกฮ—v๛‘ฎSˆ)Aึ'      ……ˆกะbY    X'@!bฌ#จมฌูž‘Reส่6v๏ฺ)ซWญpฺ‹NˆˆBฏท๏เ”กœุŽ;๊lcฅ”dอ๖”ฮ�ฑc›ฌ_ณฺg?7ฎ วฒ<*3งฆ‡B”~๕‘’%Š๋ๆ sD(dา ฝ�~6จ'ฏทmฃแv�ฉQฝšง‰๓ 1"าสๅK$]ฺดgณJ/T^2”๗ถห”>H �กH!<™๚ษdIž<น_M8ช3F–ฏ๘7ฑ_!•aฤ'q!D4aŽั#๊ฐล;cG�นr‰-NDูA๚K‘ย…ฐm‚{&\4ํd‹ผŽvY{�pฑ๓ฐพ�~ฉRฝ–;;โmร#!"„>�ธฎี๕7สฐa#�œ๘�ํิQjึจ๎ฎp�ํLgZs‚@IDATŒK!"Žk฿cุ�๊ซฝ๒rฝX6ู๕โฺaผ!:Š.E:&แ\v์๙(แค]7ิu8™พฺขน#"T฿ํฐ‡rp“ƒซœ;Ahrดงฐ ยวE ๆjqํฏฟž‘ข%J้& ƒ8 ษˆ฿๕ฦี?ๆ�ฤฆื๓dอสๅrฯ=wkกX้๒Qยp”}๖ูgdา๘ฑXทจMgฦ๒{�‚iฺ�<1s�ž={ฅN�>Mุ"G„ฝ†จฮNv(]„FศaคตซW่Pว-\ผTYฯqฑ�‰DˆXคxฉ�7c…czฅ-tu?‡ยนl!ขqฤ,T € ๕C#Nฬ‘#ปภแษˆmทGฝ#†?ถ#ฐ-Dด]ŸM๗๛PŠ+ฆ7ฝฤตุ๊|iฺŽe฿{Kฉ’Qกฆํ๓Šถู        ธ Pˆ่&ยm    8%@!bœโŽ๑`M_i)ท�–Z‹รพ๛vŸO๙4J4–&MZw๖์Y9yโธ�ข�ยถm�ข๓ฺพ๑ฆ็ แฯภ�Q!๑์ž�OV)s5Œ์กCeฮฬ้๖nฎ_#v(วz  rฃF “ผyžำ"ˆ ์4t๐@)X ฟG‹ฐดHsgฯG2eา๋^bƒ–J๓Jณ(w2/wCใpu๙๏ฟฅp‘โ’K‰ใ์ฏ��ต๋Kฉ฿จ‰^๗๚สว๛Jหห{=บ๋ff๖ำฉั_c็ฮ„Yด"m�ดึNR)Sฆฐw้u/!]ศˆOโBˆh‡ๆ4๎‡?*a_ีซยพ1ฃ†๋๓ฐ -^i&-š�๋J�ป๗|%g~;#�\๙Gr็ฮๅˆ‡ฅDHฃ์ำ๓ บ}๛iิดนฯ�@† ๖ร�+yฒd:„6ถgฯ+�บฟ‡ีXKFไHˆh=^ne่D‘"…ฅQ�z’-[V?q‰p#7aขำ_�Mš๋7lt๖yญ|๗�๗�ฦโZˆˆ๋ื…Ip›ซRฝฆ@ู์ณ—ก�›จg‹yผmว2/1- 1jด >า๎Ž฿zlŒIจื� {๎=}๚ดvJณ๗วึ:ฤf#‡q๎'8ฝnฺผENŸ�Yเจw็wJำ&๔แ>฿๚…r'n้w่R%‹ซ2Mไ๑วฒ๘ํƒ ฑY‹W๕ณรฝs�˜Q’+g aุึฯทjฑ\2u_บ๔‡ไอ_ะ]ลMบ7ธอ}oๆห“GFŽช��ฒuซเบ–)า็‰™๓ผžq1 mม3[p์�ฎ๑๏ฟฏHฮ็๒ฦˆwใบ5r๛ํฉu9ฏw[ธ็K�ื&ล4G{]6ใฐlฯCํ;t”ๅหWŠ—ัv8ล{ส)uD— ว2bšปโปqฺิ)๒ไO่s้๔ngYธh‰^็       ธ(DผTู&    @ะ(D Uœl�ฒ• ˜*่c]บtQFขหท~ํ %ุนE‹™ ่๋ืฦรQฉจ0ฒว—iŸ๚:ญ๙U`FฌHŸ>ฌXบXทe�‚บw๋"U*WาyUชี�:วZ4Ždศ! ัห%ษ""ฤ2>๒�ษ>\๖žส–M;2ขLท๎=•mž]�g�ฤไบ๖๔ำู".ค;vIร&QโHฦˆส–.%%•“ะ�w�ๅดP๋ล:~ŽxfงŸ„*D,Vฌจลiฺ˜NZ^i๊”I‚—แmA‚qŠฒaeLBD#ฑ๋Z7\ฮ;/ 5–L™qยiขސช7ด�ณwเQo�๐Š–ฅ-ะโ๎๎๎๎–—เP(ฅธS4xฐเ๎NะโP(ด”โ๐/ฺโn�๙ๆ˜ํ�ๅ.9Kธ$๏๔ivwlg~3ป›็ษห๛ฅJ•า(~๒ไฉtุ42,N”$g[ศœ8zH -ลN�Hแe�๙ฉrล TฌhbงวSแb%๊mZ๙P‡๖mๅ๕Œ™ณiฒ฿Tฃฬั“ฐ"ฒPiša�C8n5ึ�{๖Rg๑N.9๒lr?บึšซุ<�Y”3gyห„ˆึ๖ฆๅX�น&,จฒg่cเ6๖ํ6๚9r็ำ‹�v�}๏žิฐษU”…ี?�hZD†๔ฬ๒๗ขHแยTตr%้@5jT9ฮ}๛P‡NพAฦฬNŠ์จศ‰Eฺ&ง 6ษฐธ๒B๛แŒ›๋฿2�๙Uฺ๋ญงฎ~Oิ;ฯ!"O„Cfณฃ ‡๛e็โ�?๔ฃJหห9:œ–ฏXโ|"ฒ๘4_ม"!๖ฟzๅ2J›&ฌgํw]piฆ�™}เŠ‘Eฌ,fๅdOุiY๑ร๐.Dิฃ–ฟ๓้๓ฤ9€€€€€€€ธƒ„ˆ๎ ˆ>@@@@œ&!ขำ่Bฅaณ^”เณ�W๚MX D ์dฤ�?|pŸๆฯ๕—ี|ฺดงx๑Lฮ8์ˆศๅzส“7ฟ๘cz ™u๎฿i๓ฦ๕z1ฮC‘ภแ_๖Q์ุฑฅƒ;‰5i�z๕0…Hึล"์Š5fิH9[ก™ญน้LBฆย สv�Dˆ๎;wšอ†Es,žใฤN…I'‘‚.K1—Yฃบุiษาe4lฤ(kีdž๎พฤ‚ทข%Jูฌ๋hม๖อ้๓ไŸหf��‰ึฎ฿`ต %>แPฮu๋7ดZวZๆฏวฯ—'คtEˆxไเ~z๚ษำงTจH๑ C๑Ÿ9]8Vๆ–๙ึฤ^:ใDMz็Š‹Nšรs๘[N=ฆฺ๕๊ปfYKบHหYœ“+ฏmว.ๅษu-2บ8&$!"ทWIoวyzฟ๚ณsไ่Q)tQํ=†•‘ENห—.ขคI’ศ!ฎXตšสАบ ฤ—ืึBs๋sqไูไvบัšv็๖-ฦX�!Dt็š่๓n่๕๘|ลฒ%๔�ท้dvz ่�_,ซธ|ญnนฃ†Mšัูณฟ›๕ฉ‹‹yfิฏG}๛๔’}ฑ0บJ๕Zf�ช‹}ปwษ=ร.z7…Sr๊ิฉeQ ๏Vฤ!ฉ-“34ี‡๚–qhbๆฉ‹่Uw๕w3฿๕ฮsVˆุ�‡พTทถ‰๙ฯ&R+o/แX�)ฝ|๙’J”*ขc)sm!ข�ํ๏��G)>ี๙๋{h๛Žิฝgoฃุ™}เŠฑ฿๗}จ~ฝ:๒�S�ฆั๔™ณŒฑ„tโn!bHฟห„4Gส๕}�๏ฟ�ส๏–#ํQ@@@@@@@%!ขฃฤP@@@@ภญ Dt+ฮPํฌP‘bยส$6๛�์ฺ*„Yz*Rฌ8ๅ�ส๏ทำงhวถ-z1ฑศ1q’ค2o.œ8vิฌกG`ีŠฅ”.mZ)dก ']Xว•…ร�ท้าb8[BDKงฟT)Sาบ5+ฅฃ‹C*TฎjULถ|้โ a?ํ ษซ‹~N‹ยMšท ”.�ฑ&Z5ๆซGE]ฌ฿๋ึญ�fyชL1ไ๋เ�๛Tศ_KZบlyซ}ฉ>๕cX ์ 4ร–ฮŽบศƒวฺBDพวฺี+่›ฏฟๆSแi{}"2˜ชTฎ(๛e๑* ?TาC๖Z"ฒpึRฬลmYะฑ_๐‹-š์ช`แbฦ๚ฒจoหฦuRไษ…;uกฝ๛ƒ†gๆ> .H�ถ›‹ue‡~„•Qk;~‚ผ|Z“.�caYKฎื–3งฃฯ&‹NY|สi�ถํโ9๚�รŒ‰ชWญBƒ�d\ปCˆ่๊š8ณŒ |8a!‹ฑ8ฑK&ปeบ;M™4Š),ป?a’Yศpfฐn๕J#|ฎ5!ขญyฒK๋๘ฑฃeฟืฏ_งสีjZzฟ๏{ —ษํXUธ|ๅ Uฏi}ฉ•๒็ห+/m…gfQ�ญ�ท�"Rtๅ{โช‘]`็ฯ บ_8dฐoท Iฐวะ"v๋โK-š7•c๘ํท3ิธY ณ๑ฌ\พT�^ม™–฿g๖�r44ณ�ncai๕Zuˆ…y–‰ง๙2U*โ�ฅ’;„ˆŽพ/ีฝ]=ึชQ~ะ_vร�HD�่jฟh       ถ@ˆh‹ ๒A@@@ย„„ˆa‚ู-7 Iˆ-j4๊(Byฒk"ป!ุท‡Ž="๏]ฆ\สš-ป™@์ุ˜] ฎ๎็ส๗Dฝ๓œuDไ1lฺฐ–Xงงฝz�2;๛>P�+แ ฝก™๙~›ล๙ฦIฝsขDB-›55Bญ๓;ธ\…สf๏g๖+BD฿œY3w8‹็ฬGฟž>อE2ฤtฉR%d๘ๆซb?้BZw๙Žผ/นพ;าฒ%‹(C๚๏dWถ๒๎ธ๚EBDEGBBฤ‚�ฉ›†$DไN‹•,%�ศkr+โk›D‰E�ฯืœ~ูฟ๚ลtŸaB€E‡sfอ๋ฐg฿>๊ินซผ/‹ชUญ,B‡~Gฏ฿ผฆำงNำogฮPคฃิถm;dฝ5ซ–Sšoพ vฌOž<ก^>6…v,์ �นอpŒปx้’?�้‡B]eY๘ศัดxษb+.๏ำซ5jุภฒjkkBDF5Hๅ!น8V(_ŽFfตนehJฝRX ู rโฯc๕[�<ท&๖R-nd)jฒู‘(PขK!"ท๑jัœบ๘v’อูUณ}‡ฮfnT\เจ‘วนkวVC #;�๐ƒE‚ัฃG—Wถ„ˆz}k็ึยr=]่iญสs—Qw$S}�:ชpแ๓็'ฟ)ฅณใ๛๗๏ฅปฺn!พี“$qž�ฮะ๋๐นฃฯฆY๖cyํ.!"๗๋ฬš่๛�rl๚ตญ} ืั๏ฯb>๕น3๑{\w=ด์›-cฤ0ํwหgV -�่ืฯŸ?๏๖V†ˆU/S็๚บ๒๓Uฆ|%Cุช๊จฃชหฟไศOeวภ�(qโDd๙lช ํฺดฆ6ญ} ๗^•ฏูyาBD๎ำู๏‰z็น"Dd15‹ชU )Dด3๏ี7ีsoฏ‘�่!ื๙ฺ2๑;†CKฯทภฌศ™}เช‘Eณำ�ฆˆ”ฬl,––Žž๎":๚พด—ฃื�ป฿�ู3eณ๋7nPๅช5ํ๕A@@@@@@@ภa":Œ @@@@�IBDwา �พ .B šย?ž๙ํ4m฿บู๊ s็ษG…‹3ย—ชJo„ภhฯฎB์๖ซสย1 Œ=’ส–)-๏่จHC 9�๐ฺu๋จNํฺ†ฐ…;d7*฿ฎ�C …ฉ„�fยค)4�Ÿฺ•ุญฎ>O–Œ$ˆoด๐ำ ZฝvqญNŠ)Bฝ{๗0ฝT>ูํn�ƒ4m๚ b็G•ุYฌBนฒ๔EŠ/T–q|๔่1-]ถœ&M๑3๒lphะFPNZ3n�ธ†w�†ิฏ�ซอุGqโ˜\ฅธย�ฟP๛Žญึ๕ขา<นs‘.pQ!Kฯœ9Kš6—ํ&M�Yบ9�%k W;•๊ึฉM;v0ใศโก'Oาชีkhฤฐกฒ๊˜qใ‰ร[[ฆcGJ็Dvฦ์,\PํIG Xฑb‘ehoีv๚ด)า‰ŠฏOœ8I-ผ[ฉ"yœ๊7‰˜ซJOž>ฅBEŠซKซว"… ั๐กCฬๆษ๎…ใขOKJ™"%ฑ\Zๆae'Ž'ึ.‡Y;usLŸ1“ึญ฿จฒ‚YX้%ฤC๑ใว Rv๕ฺUฺณg1[[I…LfX�BEmU“๙!‰€๔ฦงO›B_+วE.[บl >Bฏ&ฯYฐณ(`พ!ไlึา[ฎ]Š"ร‘g“��&พ^%ž็แ>;ึ'TฅJ%้�jMศฦฯ๔ไI&nถ๖ฆ๊ำ๒่ฬšธบิtฑŸญ�ฏ๊:{dมั€��Œ0็ช�oกำ�ฌ>ณ,ผ�พwoสš5ณ™#ฅjฯฯโ๘I“mฎฝชง ต‚{wq�ู3งQ�{ึtูU›ถค`]aญ�ุiw้bำทซG๏>"ผ้UpC๗แฤห‹oฝ๎ยสe,Žๅo(ฟ–,]ฦY2้\›4o$\�ฐมƒ‚}wฉ~๘่ศ๛Ro็ฬ9‡V็๋œFG .rฆด‡@ˆ่.Tp7�Mิs๚K”(1ฅฯ˜I ่=]นt‘n�ผ้9ƒ‹„#a ๕kVŽ„วŽง๏่Oทo฿ ‘†">}๖L†”ๅ, ‹+B3Ÿ.Š๖๔ม�฿ธC�แŸบŠ•(eฆ1ฤA8Y๏›Y„~M๖yRzp�]ฟ�?r๙jฐฝ1+€$K–„^ผx%„–Wm:=�‘‡fห–E„ข�R„์ฝGGŽ๕๐ั:?<ชคJ•’ฮ‹0ฎ็�บ`wG,ฦ๛โ‹/่ณ„Ÿัฃdจ๎๖Ž�9๏ฃ ้3P<๑œ�aกฏ�ธnืณข๗Qฯ™mz.๔�ฝรt๏9ณ&ฎ๎^C�ัณ~ร&มบ บฒๆ<ึดBไ๙๊ีk:zไจC๏XT„ฌ�๔ำธt็๖]๙žด็�ฮใีรฟ:ุ•นYkห๏๗๔าS !ฟ�ฯ}บ ~ืฐwฬึ๚ )ฯ™๏IH}FคrXfส”�ผ}Ggฯž ีตp7�ฮงOŸŽฤฟ [ทnัล —zf�1†ะ๊ƒ฿u›7ฌ“๎ฟ–กuO๔        LBD์JBฤŠ7dุMh่เ”�‹ไฦฬ๏�น#ลY�‡jฏ���{!byE�s็uฌ B;O๚๖้E ๊ื“ต9 l็ฎ�ํl‰j  พ ฐศoม\้€7ูoอšํพ'คพL้า4nฬH™s๏�?Tชlyญ๔ใžVฏZ…b 'VGำ?ยษoืฎ@G›ก>x �๛๚QŽงK๗žฤฟw!€€€€€€€@X€1,(ใ    6 @ˆh @ TฐฃำเAˆล#ม%�ตหY!"‡ ๅทE ข\นr!Šฝ}ฺะัใวƒป=ส@@<”;฿qศื์ูฒRั"… ง�้3gั!ด๔„ฤ฿บƒ๖:5”ป๗๎Q้ฒœj‹F         ™ @ˆ™Ws !ข,†) pHย์ูณPฆŒ้�oำQขD‰(ฮ'ฑE ํ๗๔R8"v๖ํn„0vVˆ8v๔H*[ฦ\๐ธf�z๚qภภHษ“ˆ@ aƒ๚๔}๏žfS๙ใ�9๒๒nํ1กm]"�น{—ส”ซh6?\€€€€€€€€€„LBฤก€€€€@(€1แขkpล๓)cฦ ฤแ*q‰4pUซR™�ฝ{G/]ฆฝ{๗ัค)~nบ๘๔ฐฏ7o�ค“'Nัะแ#*Hนป2Š)L•+”ฅไษ“ห๛qฟ/^ผคๆ^ญ�u ๔ใแRงJE?�ุOŽrํบ๕ดvร&qุo๒๘1'N\:๗็Ÿ4j์๘ฐ@ฝcพ<นiย8ำ๛ํ—C‡ฉ{ฏพtฆž?ญฅ‹ๆฟ ^ฝzE ›zั฿7oz� 1Bท€ัญ8ั€€€€@x!!b๘Xฉ่ัขSรฦ)z๔hrภฟ�Ž;j6๘–-ฝ‰ขผ7หณuq๘ะ!๚�๗฿m#"_๖์ (QขะูณOปŽก2ทฆP๛ถญฌ๖]ฐXiซ๙ฮfฒใVƒบud๓ัŸ็�rถซ0iื ^Š;6]ผt™๖์�&๗�X7ษ+'ฑะŽำโe+์rC+Uฒ}๚+z๖�9-m<9eฬž ว=NK–ฏ gฯž;<�}�(zดh๔วน?ษซu{‡�Gิฎ๎ƒ๙�3้�ti$ž.=๚ะแ#ๆฟ#DTnž8/~็๙vl'‡ถg๏>๊๓รOž8LŒ @@@@@@@@  @ˆŠpั5€€€€€็€ัsืFY•ชี)EŠ/Œฌ๓็�ค�ฦuT!ฒ๒i�ฦธ้ไ๐กƒt๊ิฉชก"ฐ"๎ุผžโฦ#y�พ}‡N�zZธ!>ง็/^ะฤ)ำ�ส‘…`ใF—}ฮXDSgฬvk�๎๎์เ�ฒKvคlำกณปป๗จ�œ"ฮš:™2gฮH๏฿ฟงBลหxิ|,ำฑ]kj�ฐพฬ๖ํึ‹Ž;nY%ฤkญ#re่๏„K—ฏPใๆโ& }T�6ฎฅx๑>ฅทo฿Rอ๚้๎ปu<ธ9€€€€€€€€@ุ€1lyใn    BBDYˆ`†‘Z8eUจXัฌ†ฅ‘ ซUซN5ŠY=�"๙็ษๅๅปw๏ศ๖lz๗๎ญ^ŒsˆฐB[ˆศ!89'ง+WฏสPœก SAˆšค๏;aยฯศซySูp฿�_์๊น"@s|„ฎตp‡ฑm+o)ฺฝ(skึฎwm@จต+๛`ิฐAฤกแ9แฎม๕ใoŒnพฉnํšr /ฅษSg|�Aa        aFBฤ0C€€€x=i5ฌฅy‹–+V,z�๚ลˆSVฒ&Dด�ฺ”ซ‹๏�ฝKซVญ ฎ:ส@ Bm!b�|yi�˜’ู๊uhิ˜ŸC•„ˆกŠ7ฬ;wE€ึƒu‡1ฌว^๎็์>เPํ[…๛‡ป~๐๐!UฌZ+ผL9B3iฒคดj้Bน.w๏�Cีjี‹ะ๓ลไ@@@@@@@@ฬ @ˆhฮW    ‘„„ˆžฝะฅJ•ฆt฿~+� ฿ัูณg)kึฌrภŽ kีชMI’&•mทm�BWฎ\๑์‰Gะั/Z„ .Hูณeกค‰S์ุฑ้๙๓็t๕ฺ บp้๙M›A๗๏?ฐ9๛šีซR๕ช•e˜๎xŸšB>>|๘ˆ.^พL�w์ข๕7m+”/CU+U’ืk7l m�we๚Iง๖m(C๚๔2kไ่qtํฦ y>vิ0๚$ึ'tF์ป"ฬpํU)K–,”๐ณ2ฤไมฃGi๘ศฑzWAฮS|๑ต๒nAiำคก/Sฅ O>๙„>zDW._•c�ธek6ฎd๔๊ั•rๅศ&๎•Šž ฎฟ�qŽ.ZJใวŽค("|๙ูณOปŽVoัฦว‹rๅฬA฿|๓1�ปw๏ั%มี�โย–‰Y3dูI“&–๗ไ‹๛าeแ๔ฆา‹—/จ{ฏพ๊า้ฃฝ๗ใฬ[ฐะชป๕ตo�šา‹wสWฉSQ๔่ั้�M็ฮ�E?Ošls๏ฑะฉEณ&TขXJ*�#ŸHa๔kQ�>�v๖wZตzุ#�…zื๗^Tแาš#{69๏7o�ay๐๐a kไJb7ธธq?•n”ฃวMฑซ~฿๗ขษ“‹ตบO? lิO��ทินC;yฝlล*Y^ฉbส›;'๑^~๖์9�๑็Ÿ4c–ฟู<ชWฉDEŠš�่Œฮฤษ–-�hgเ=Kžณƒf๏ž�Œ�lโ}ภ"2N'N�ว‘ฏ๏ˆpฎ‡šยp๓ตžชVช@eส”ขoพ�š’&ILŸ<{๏*mฯีฺ๕๕ช.ซww’&อื๔Y‚ฒฟ๋โ]q๗๎?F฿๏�ฟฅ�}”œŒLq’1Cz๒jูLฯ’็็ฯ�E3gฯ ’�อืฉฉGื.2�žpๅอ“‹$ˆO]ธH#…ศทNญย�ฏล๏ฯKbพ?�8ะxo้eหš™5จGiพ๙Zฎ‡ศฝrํ:=z,Xw:ฏ�ธa=J+ฺลŽGฎอ•ซื่จCm+ :๏มXโ�vๆฬ๏4ำฎ> โ็gศภ)šXcvษ\ฑj,wื>(]ฒธ์Ÿ;�ท�๕k`Orไ{bูŸฃ๏Kีพ{—Nb=พกวQŸ~ขฆPพ|น)kๆ,โZD—๏�ญ�wHฮ�\•+k Un๋ฦ�4@์๔์ลsู๊ปŸบ•qt๖9Q๗O๏ล38‚r็ศNล„๋dฎ\9(A�๘R๔y่๐Qš8eชอw็ข๙�โ๙�JŽฅQณ–t๙ส5c\ถNF*�ฑฆtยu†G฿ผiซ:๒A@@@@@@@<”„ˆบ0€€€€@่€1t๙บา{ขฤ‰จvํบR@u๚๔)z๓ๆญ๘x.ูฅ#Bฤ่ัขS //Š5ชtUœใ๏๏สฐะึ๗๎ ถ5‹๛BวOœ Ro๔๐มTคpก ๙*ƒERฅ+TQ—ฤbฐ�พ—ื,ศ๓nำม(S',ูผnลŒ“�‘;6)!ค๋ห—ฏ„ ใฝŸฉv๊x๘ศQ๊าฃบ4;rHส๖m|ค๘ะฌ@ปุ่ฅ‡ีนjU์:e�„ฑฃ้�ti‚ิ๑โ…1kBD <€าฅ ฺ–;c.“�ฆำาๅๆ.ขณงMกL™LBฤ 7ตศ(XฌดEŽใ—Ž�o์„ษดbๅjณ›pุึพฝป"2ณBqมส๏๛ Sง~ณ,’aง™“ญdนX�ส0{Rเ๎ฝิWษ\I›ึฎ$�OŸ>ฃ2ซ†ุี�[„่)†๗ิฎ฿ฤจฏ บXธ[ดHA)6*|8Yฟi 1ฺศ๎฿ท7UชPฮธV'‹—ญ ‰“งชKใXธ`#ฤF๖ค{��CUkšณไ็ถฟS–(^ฬf�wาƒ†ุ,wค@ฝ ์iSฟQ๓ ขภสสำ}{i�วน?ษซu๛ ๙… ค1#์๛็ฮ‹~LRี™ท>ฒxV }†ฺt๔U�ษ# +อŸ#ฯy_ lZ{W๗บIฯnพTซF5yikฯฉบ๊่่๗Dตs๖}ฉฺฬ%„้฿ะ‹—/)0p/UฌPV™+UฏMๅ…ัทฃi]w๎6 ซส,r๕Ÿแ'/Yฌง?ฯฎ>'ฝบw!krโPื5>œห ํ …ทl�กๅ�wสขย"โy็4~’_๏ศ5�;S{Iๅธ๋;ฉ๚ร@@@@@@@@ l@ˆ6œq#!ข‡-ˆ6œฦ›P\แฬฦBช๙๓ๆRžผ๙œ"*\X8ูe•=_ผx‘v๎ุฎ�งaI@ ฎ\ฝJ�qžn�พ%…Nฅ„ ่๓ฯ“ษกXฑCืไ๑cd๙๛๗๏้W!๛๓�y!,}M฿QGผy„P๕ •,Wูl:[6ฌ–ฮMœiอฉAฝ:†ะใ—C‡อœ๛ิXU‡,�9+�๏ุ�ฦTjแำVŒๅ/u)น„sิไ cฅˆ–3๎ WทCยM์‘š*UJ*/Ÿ7“�%ฐ่�ปUญ\Q�›™์�ต‡^ผzIE…๛dโD‰d>�ฐ&Dœ๏?ำ0๒ณถC8ุ=|๐€ฒ ๗G5O#6k้cๆfลิp๚๊ซ/)ฯ‘๐ๅ+W…ซ�ฏ2ŸpŸ“งฮ0ฎ=ฑ๗~�?;c๊kย!B—ฬ5™ผ{„s๏ฅย… Hท8nwSyjiย<ฮkๅี‚ผZ4ๅS้twโิ)บxแ’่+eฮ”‘ฒdฮ$�}ป�'4ห—'7+ZXถ‰&ะJภรŽ}�ถ›‹qO 'Ekฎฒฑ?F ัZ!^ใิดe+บp๑’อ–ผฆำงL”ๅ–b=]ˆจ:`!.ณ|๘๐ุปฉˆ�อ,…ˆ�ฎะฑQJแœ˜=ป้}kKฦ๋ั\�TชPฎฌptŒ#/Wฎ^ซฒๅ๑Ÿ�ฅ9๓ฬ๒tฏแƒ‡ฤ�ผJฉRค โยต’E็œุrีšufmน`7Nv3ๅ”GธC~•:ตใดe๓fบvํชำBฤfอ["’E ะ“'O?�‡ฐ&ภ‚žƒ"”ฃ5วรล �้๋ฏL!9ด&‡ุTIƒY นปมฑe—p˜าSฎฉvอ๊2k‰pg›`แฮ6gๆ4–๙[Y�ง฿ฺณoฟั\CXบึ3‚๒็ห+๋๚M›I -1ฺ๑ษ‚93 ‡Avหcว;vlT‰]ต:uhC“ฆLโžฆุ๊{ไนฏ^ถX Y”ี๓๛�tเ—ƒฒ9‡ำ9u%J”P^[ 9ฤ+‡ ๅtW„€ํุน›ูx๚๖้)ย[Wๅึธห๑ฃ`�|4n๔py9?`‘อ๐ญชพซGG๏7d`*]ฒ„ผํIfปGŸพf๋ก‹‹,ื“ร๒*_ถe‘‹}๔ฤแŒ?‰�‰U'EUOํ%q�ฆCg•ํถ#ปุฑ๛&ง„X ถ}�Vฒ๎ุ๑“Œ0นœa)`cมp฿�?™ Pนฮแผศ๛ฺZาE^ถ„ˆ–ํfML™3g”ยะBลหX›]ณXnพหฑำ‡๎๗ใ ณ็–E~์ะศ้�VฌZหฌฝซ�k�ฐพ์†ลง,Ft4ํ �&วo‘=Y�ุถ•75oฺH�jํ†M4bิXjึคตkํ-๓ฺv๊b์มUK่ ๑์sฒ\~',œ7K~๙}มNฑ<N๚sr\ˆ‰;๚v—๙�C฿,๚ฎี ‰Xซ ฦwภQตUGG๖jรว…๓fห๐ำ|nhอู๏‰;�—บ‘๙๛ฯ]@ณๆฬใกหฤ๏๓šีช’�ผ๒Z�ึ "œท™;ฎ[ฑ„XะษIwใtวsb)D�/พ+ 5{w6b�=๛ุ ฌ3�+๊๕๎๗ฃkp?ิ^Ru์YSUGฯ!!ข็ฌF    † D Cุv�*v์8ิธI้jลฮeซWฏ”-qDd1Fีj&!ฺใวi๑ข…vŽียš€.ชaม Ujใใ%ยŒ6–—;vส๐อช,ธฃิาi1ธ2๎S‰!ุ‘ฌV�ฦfข]”ณ\…ฦi.h์~ฦBDN์ศmUธg™้ๆzjkB7]ภd)DTยRฟƒ9Yเฒz้B้๖๘๑*Wู๔,YNมQa e{Gฏฝ฿~!�Š&„k์๎Wณ^ร ๋มbK]rฒ\N›4�p๘ Iไgkj/Y[[mษgฏ%ง ›ทาะแฃไ๙�Yำ(ฑq๕ฺuCT6lะ*Yยาุา%T฿ื,’jูช™ณค์4„ก-Dิ…€์vศฎ‡–i๙โ๙”*eJ™mอฑิฒพ#ื๚�รBˆ8R8�qX\�9็๗ ฟwŠ-B#†”ร๏ั็)@ึŸฟ„sg3/“่TŸใ}๛!uแํ&ฆ>แg dUŸvฅƒช�ŽEอ์สiุศ1าyT•{�#ืญZF์ฬว‰Cz฿:๛=qว๛R"๎Nž={๗Sญ๕ฐ�,์)ึY%v�2qœผdืR�๋*้๛ิู็D"Z~?ี}B:ฒ`Ÿล”œ8์= fCJ๊}ญ๊้"[•‡#€€€€€€€€€็€ั๓ื#"†Tปฌ]ป.%ข7น0 €ž?&{tFˆXญF J�yrู�่‘#t๒ไ G‡ๆฎ`๑Dีส•่‹ไŸS’ค‰)f Sธั„ยต]ฮ8M›9›ๆ-Xd�Jw9cิ‘ฃวD8ึรฤamƒ Cหฬž6…2eส ๛า};ถ#อฬi๑าๅ4qส4yฎ~(aอญ[ท…xอไDฆส2fHO�3�ไๅš๕iไh“„3ส”.Iƒ˜ฤ"–กoU{wฝš7ฅV�-d—3gฯ5œดิ=๔ฑZ uแ;"พNgœขD‰๒แH”,™)d6gุ๙่โ'OsDิง<^O•ิ<ฃEFI›„Lืo� zšซ*ิ๏๛^Tฅbyy�B„J�ฝ{=~œŽž8i&N5X9Q{)ด„ˆ|หภmฅห‡ำm��›ุus้"“ำ?3•kิ‘ญUBX๚ลษ‰CฌVจb ้ช†ฌ ํ ฉถฺ๊Bฤ‘Caฏ๙žj=ีZrž ๓ฮ็C†ข[ถ๒ฉ[’.๐ !โ€มCE8๏]TB„ฏ>x€œรฐฃexl]ไฅยใ๊แๆนฒ5>ษ„ภX๑า…ซjŸ๒ป ZญzAx้bqv์ใ๗Jชญ#ก™U[uTB?�ฏ!9cช6|tTˆ่์๗ฤ๏K]ˆhฏำ฿ฎญdธๆW"rลjต Gย>ฝบS๕*•$ KทVw<'บq๎�…4}–ฟŽ�ฎs}ฺ๛NaWศุŸฤ–�ฟ~๛ฦ๎๗ฌ]B%0#!b˜กฦ@@@@<‰„ˆžดD้ำgคโ%ŠหA=s†๘/TฎฃBฤจBLๅๅำJ:+พขฦู3gxึd#แhFLE  qๆ“งฮ …‹—šี[0‡พJฺ,/�๙๗_้žฐศผพชXฃzU๊��ไยฤแžYŒศI‰WX๔า q ณฤ\ฎ„5–โ=.ำลm,bฑJ�-›‘OK“อRฌฃ๊ธ๓จ‹QFAไZ!Œิ‹:6ญ5นŠ๊s‰'6ํ�ฒAฏ์9sjๆีฺช๐ำ“…ˆบธ.ุ ~(ผ�เ!Ub•xญ�E๏ObลRYฦ‘็ๆ.XฤIาจ๐แDํฅะ"N๔3ๅศžุมณhษr2|0‹ๆTb;vTS{มา๙‘๋้ฌึoฺB,xs4…ถQrู36KwU{ฺW'ฌ…ˆ*d|แ‚hฬHำ{F‰ณgฯJ์ุษI‰u๑Xp๓Pe*\ฎ�NณtืSuuWฦอ[ถำ a&ง;.7๖๘GpDt443ืั๏‰ป�—๚�ต%์ๆ๑้I™อ!น947'%ŒไๅU…pTw‚ิ๏ฃ๗e๋�ฺsข๏%%tตี�Vพ3ก™m๕…|๐EBฤ๐ต^-€€€€€›@ˆ่&n๊ฆq“ฆ7n\bัำล ฬzM$ห%J$๓ 7ฏ;ทoำฟ๗�ฅ_Ož4ซง.๒ๆอO9sๅ”—ทn฿ขukึจ"?็ฑHO%vฮ๚ํ์Ybแ )r็ฬnˆgอ™Gณ็ฬWUcำF จ~ฝฺ”๘ร>0 ฤษํ�wจQs/ร-J/�ฑyฝุWq่๕๋ืTกjMส™#1DVฑๆเลฮ kฺต๖&vใ4ำ_8ฮ] ฯC๋‡๎ุ7Q„ด^ฌ…ดๆ{๊]ˆจ Yผๆ'ฤŸมฅ๗ขP—ญื๕d!ข๎~v๓ๆMา6๘๗;nฺฒMŸžžถoำŠXd;ถษฉKฏ`2U/ใsc/�v–ฺt่lY์–๋๖m[?œุฉฏQƒบฤnd*ํ �M์ะฉB๙Zsฯิ…ˆผoy�:šB[ˆธLธ<~)�9ฑ“้�ป๗‚โž}่oฑ๎๎Ja-DT.ฎ๚3๖ร€Aด3p n)Dิ฿วNœ _~9์ิฯ_ธHว…ปg๚๏พ%ๅอ้๗฿ฯ‘w�Aฺ้nฏ;vR�ฆw(W4๖๘G"๚M�Yผำณษ๑rจnElOrไ{โฎ๗ฅพ๎ณEK™œVCkแB๏ีัใ'จsืžค SOœg~อ˜5วฎ)๋‚ๅ���7ีi`zง่๋ืญM]:ต—Y�žัรูn฿$]C-฿1\™ื‹ื“ฅƒฌฬ�๐รูะฬ=บvฆฺ5ซห^Xˆอ‚lG’ฝ฿wผ/•‘รผ—,k ซlฯXูษ”ล,/_นบp๙ํ&Ÿkn;r์xZณvฝY7๎xNt!" จูัีั4Zธx)X@6?ษ–.7น๓:ฺ๊ƒ€€€€€€€„?"†ฟ5รˆA@@@�@BD7@tcu๊ีฃ๘๑โ[ํ1jิจ2ฬ2พก–๙�GัŠeห‚ิO’8 ีชSGๆฟ๐Ÿ7ื>1FŽแ6Jจ๒๔้3*Sฑj~งLGน„+"'GDP#†�Dล‹•ํ6l�JC‡›/2ใรŒา“� ?yลฎx‰%ฆXฑbาใ'Oจ\%“€Eฏฯ็†xฬA‡ฏlY3ำ๔)ew์าXฃnCหฎ�z]ฝJ%โ๐ฬœุ๕๎‡ƒอ๚ฏ)BSณ „“ฅHhมœ™”.mYๆำฎฃ,—�๘˜Bฤซึะุ๑“lŽXX=z๔˜สWฉaณฎฃkW,ฆdษ’ษfC†ข[ถZํBํ%ๅ�ฬซ•ี:ฎf๒<ทm\KัขE#žg�๘๑ˆลNต๊5’aศฃ‹|v{L?>ฝ|๙ŠJ”ญไ–Kˆ8s๊$ส’9“OมbฅƒŒKฯู่อ—jีจ&ณฌน:๊uCใผC�ึิคQ}ู๕๗�า๎={พอพภmฤ๋๑วน?ษซu๛ ํu๔มc'Lฆ+W]๏�พYพSญ‰ucpBDG๖qcqขฯy�_จ็๗�๕b‡ฮƒ๛žธใ}้ฌฑWฎTณZ9—)ำfP๓ฆ้Sแอฯrฅ๊ต‚8ปใ9q‡q๑๚๚ซฏไธ5kI—ฏ\ q=8lvฌ˜ฑŒz�z๕ฑซั'        ABDX @@@@ ฌ @ˆึฤฟ_žผ๙(Wฎ\ฒƒ๓็�ค�6;ซ\ฅ ฅLi ฿๙็Ÿาž�ถฺ๋์n%ฐmำZŠ๗้งฒOK๗8]xร,…ˆ์๛“ุVCฌ๊ ฉ;xุHซใž๏?“พMg�ฉ ม…ŠTโ1kก›u—AkยšญึH!฿วVˆ�สสSเ�ฝA$jl๖YHศNJxv��ฃ๙<�๔]บด๒ฺRˆจ‹UฌอSuยโสว�ƒ„ตQ็ๆ์๏ิช]'5TซG]@d้ไฆ7(ZคฐS{ยlM๘^ท๏�5หSmฮ›Miพ๙Z^ชpนชL?nZทJบ'ฒƒk•šuญ๖ฅืw๖�r>r”บ๔่Cบภ‹๛fg3k!ข?–qไะATฌha9m/�VาEg,ธlะด้๛]ตK๑ล”*e :r์ธสrหฑAฝ:ไ�ฑ์‹�Wู…ีัšBD~WฎZถHบ๒ธz๔๎G 2DศŸ—v�'คTŽ„\™ุ๋มNฅคษ’าŠE๓)fฬ˜2หา!oีา…๔ลษๅ?hุค%]ปqC5%]Œfํ}ฉ*:ฒT>๒\ถ ฎ�Vจb ฌืัฯ�žธใ}้ฌQธ๋sู+B๗๎๗ฃž%ฯ�๑œธ*DไgCDณ8๚�?�Pีš๕‚ŒำZ†๚๖ชฒแ|ช๎#€€€€€€€€€๓ DtžZ‚€€€„c"†ŸลsDˆ่ใำŠขŠ?~ฟ�ž,˜G/žฟ? #ีลP์ ทnรFบt้ฒpAฬAอš4ค1b3ท"ฒ„�N�zŠv์ฺ-ฺ]!ผใPnแ XงV #œ๗(ขrตEˆJีฉ. Ry์Fฦฎdึ’CX่้B8kยšบตkR7฿ŽFทป๗ะถปDx�๛2”tชU(Sฆ าญŒ]ห\MMys›Dบ7�๗?š6c6ฝx๑’๊ีญe„ฑๅ{X Yภรข%vษใtๅ๊U Xธ”ฎ\ฟ&�ถ>•ฦฒeJKgpขอฐ"๒X•˜‹ฯ๗์�'g'่ษำ'|IGลน.Nำรs๙/‡‹p�[่๖ํ�”,iRสœ9#U(W–’&IL‡ ง-�vp5™Xฤ˜*UJฺท๏ฺ๐บ~�”Bฎ ,H+”UีจZtWญฅูำงP&œ‡o�*๚ฟ�เฝ{�N์ๅ+tแโ%kอฮำEน�x‚QปD„ช๕nูŒ|Z67๚[ดdM๒›n\ซg„ˆ,๊ส”1ฃ๊‚ฒdสH-š5–ื,\ถโ?ืผ{๗๎Y _�นC[j(BIsbมาšu่ๆอ[ย™๏ =ธ�0ˆ˜p๊คŸ)G๖lฒ>‹„ ๔‹€u@IDAT๐๔YSุุoพ�šJ-Ly๓ไฆ๋B ื@ˆโ�™๔ุ์Fท~ใ&:�ืz๙๊%ฝ}๓Vธ’๎ r;Z๋iฬˆ!๒๒๎�{2ฌฎ*{�๊•œซ.ฬvิ‘๛jํำ’Z6k"ปewร5kึ‰=„=yL_Šฝœ[๚ห”,.Cw—ฎPลฦ/Z„F จ†C์6บo�/”(qBj฿บ%MšD–Y{'Ž5Œ ศ/ห๙=2ำฎ<ฏ/œ‰YDง’ต๗ฅ*stจv|ิEŒฃวM Ubฮถ’ณ฿wผ/"๒\V. ๏ž/ฬฆีoภ@31ฉ^่๊sโชฑ{—N๒๛ฬcฒ๕ฮัวซฮีทW]CˆจHเ       แ‹„ˆแkฝ0Z7€ัM ร {…ˆ9rไค|๙M‚ˆ‡B์ณt้’0nv›5lPHีdน5!ข วjซƒซืฎ+:bษฦต+ งฐหWฎRฃf^ถบs:4ณ๊p�่แฤฝเ’ป,ค›4nด!ศดuOK!"ื+Wถ}฿ซ‡มลV[O"ZŠ๎๔q[†ๅ2†ฒ@4คdMˆจยW�jnSฆtI<เซอw๏ฅพ?�'�ฒZษฮฬ ๅหะ€~฿ตkืo"]DuืL.Tโ6ฃโ‡g„ˆ�ตฆฦ MกŠ-๛ณผถšš�๖–-œguZsRc!๐„1ฃˆ�—Bz'ื6ธ2%&ณVง~ฃๆfn€บHืZ}ห<ๆฬ‘ƒ”XQญ•�r฿ฬž=+M›4^v1lฤhZฟi‹ั.�62ญœ่BD.ž<~Œ*ๆดRำ”๕โล ๊าณ:๕›Y] iV`qœัั} w?_^?f„ฬบt๙ 5n๎ญ›๋ฮ†fฺ…ญฝใ๊๛Rํvฏ-Yถ’vวO�ท๑กฆC 5๏๊sโชQน ฟ{๗Ž๊6lfีัุ˜Œv!ขง        Ž @ˆŽCpž„ˆฮณ ๋–y๒ไฅ\นsห�ž;wŽ๖๎ูmu 6aqMo์งณgฮXญ‡ฬฐ'PCธถkๅm„-ๆฐcืฉSง‰ล\๛๗“ƒš8eq]•X`ีจ~}J›ๆkŠ5ชส–Gnฟcg Mœ2ีฬฯฌา‡‹ูำ„3p"ไ4UธฮX๔ก$่!p๛&)ŒRแm๕์Jต|๑|9–ต6ัˆQc๕bใœล“>^-dX^#Sœผy๓F:�yBˆcึ�wž�ปoi๘เŸdxTU๏•pX XผTฐซ+�ฯุ}‘ล–)uชTิฏOO้ ศa4๕ฤ‚™cข�๒ๅซ‚8ำฉzบ jๆ์นไ?o* ีcณ&จฌ๙ฑซa�๘๑Œ{YŠฒT‹ฅบ๚v ”)Rจ,ใศŠกูsๆ› f:ดmMeJ• ไษ?7๊ช“วŸะสีki๚,•e๓ศBฉzuj wธ,7NŠ%Šฌปyหv4ฬ$ ฒูุฮv'�$ฤถœ,…T๋V,‘ย=•ญTอpมำปึลd–ฯ ^O?gงEv\ด'F›๗`ใฦ๕ฉhแย?�ง2œ+๗๙ฟฟ�ฆ: š้ž…ล=บ๘R้Rลpมชฯ๑๗?ฮัึํ;ฅซŸสwื‘9ท๖๑nฎู)Y’$๒ูโพ฿ŠwQอ๚อœ1๕g#ค๛๓๓ZผLEส•#;M™8NV๗ํึK>wzh^n™Ÿ๙นณฆษzJœจ฿ฃiฃRธO๐ดL:๙ภƒโฝijฏ—ณ3!;อ๊.ต\ฮBาƒ� ั�ผi#๙พใษ*ฑC๋”iณh่ภ�!พ/นฃ๛@�‡zh๒เB|ป๚=qๅ}ฉพA=ขBH๋sใsพ๏R๊Xฅ ›ทาะแฃิฅีฃ+ฯIง๖mจQƒzาYบ™Wk‡œ[uโ=๛๖SŸ~ฌŽฯZๆ๎ํ›)V,Sp.ฮนุZ{ไ€€€€€€€x=c0 0&!bวํ@@`ฟ/Sฆคป๗�!GBณจ‚��’ ๑Oด่ั„H้&]๎Wฯž=‘+ท�ผn•-ฑฐ|•vต ฑc;*ฐp)รw฿Q‚๑ฅศC๑ฺ3f;บR…E’3|G,’ใะธŽฆŒา‹๐ั_าSม๔ๆอ›‰Oฝืวชฯ{!c† "ิlbz๘เ�๏›นุYปตฑˆร7ฟ!yo!—ปB*[ป๒์'ภ๋’๎�4E�w๋ฮป฿ ๖฿!|ืไฝ๛]บt๏ำธtG„ฟ.ฤถยˆ๋3ๅwm!�~๘๐1�&�๖ผณ๘ูสš%‹xืลฃ“ย5ัž๛่๗tๅ<Ÿว=aœI˜วแืป๗๊lwฎ|OTวแ้}–ฯ &๙~ฏ_ฟ–Nล‹o €€€€€€€€@ไ"!bไZoฬ@@@@เฑ@ r่�ฅ“t๙โู๎�@†ง3ว,ร}eษ’ูฉก8x(L_N ๒#6โฐฦŸ[qด iH๏…ร!;ž"…ฃGฅBbฝŸ>}Fๅ*W?@#eแ๋๊ฅ ฅ๋๋๒•ซi�$ฟ4;L@@@@@@@@ภ^"ฺK ๕@@@@"#ิrb2 `F€รขfฯš• ๆฯKูณe5ยแv่�N�zสฌ..@เc่ัต3ีฎ้œpj์„ษดB~ฌะC๖Zฏa;ท~ฃๆ!บeฺnˆœ DŒœ๋ŽYƒ€€€@ค'!bค฿ 4€J–(f6ร ›ทาะแฆ๐fธHBฤะƒ!b่ฑEฯ          `„ˆึจ @@@@ ย€1ย/1&‰ ๔๛พU*_–�ฝO—/_ฅฟค้ณ�#1L�S $L๘ฅN�ฅSร;u๊7งฺE–FฉSฅข„‰:<�๗๏�ั้฿ฮ:� @@@@@@@@@@ ฒ€1ฒ๏ฬ@@@")#้ยcฺ             n'!ข�‘ขC๐@Bฤ๐ฐJ#€€€€€€€€€€€€€@x !bxX%Œ@@@@ภํ Dt;Rt             I @ˆIำศNBฤศพ0w€ั]$ั€€€€@ธ"๐ฑ…ˆแ               H สซืo�{เธ0$HBBฤHฒะ˜&€€€€€€€€€€€€€@„%!b„]ZL @@@ยรว:a”              `‹„ˆถศ @@@@ L@ˆ&˜q5"†Zt     `ํก„:              เน D๔�ตมศ@@@@ R€1R,3&               @ˆS๐@Bฤ๐ฐJ#€€€€€€€€€€€€€ุ&!ขm6("†d�@@@์$ฐ}ห&Jœ8ŠD‰9<ƒ��ืf›*U*Qใ† e๙€Ÿา๙ฟ.ุฌ‹ว๘v๊@�^-eฃ 'ำ์9s๋ kc฿ฐเ๙ 4xqใฤกผ๙๒า—)Sา�‡่ฦ�ัฏฟžฒู่๓ฯ“ัๆ ๋(z๔่t๙สช^ณŽอบ(ˆธ DŒธk‹™€€€@ธ !bธX&๑Gลไ�บ<๒ˆO?J์ท:๘ขลJRถ9(FŒ%JY็ํ�ท๔ฯฝ{ดqรZzp�พีvศw`wžoพ�†ž={F .rธ๛|y๓าฌSeป i๔ุŸ๎#"6`qB“ฦไิ๖๎�Oœ;aฆYฌHšrh{"„(ฬœรRฤแŽ๑:า„ˆŽะฒฏ.?GM›ย(๋-๊ิฎM ฤ—Y;wํข+Wฎ๊ลาis�๖fy๊‚ล.ส••—:๘๖ํ;ช(R]}6wm฿*�1Abโox๕šu้๊5๓5๑4ธฮ์ƒศ$Dฤ7ฬ๚Žu๕9ฑ�ซ๕�-ืQŠ)ฌzš‘๗หถอ(fฬ˜rผ��7ญ]ฟ�๚๋"ล› *Hล‹ฃ๚ ›๛nXบ8€2fศ ๛h฿ฑ3ํ?๐‹ี๙#@@@@@@@ b€1bฎ+f   แ†„ˆžฟTํ;๚R,แŒ๒๊ี+ใ“ึ„ˆบโ•ห—h๕สๅฦไb‹ฅmฺu4B5O7Z Œ 8P เช1†!บ KGXƒ1์ˆฬ›#Kณสz๛ดกฃว‡�อ#่\y6ห”.MใฦŒ”dX8ฤขˆ˜"“1"ฎŸ;ๆไสsโ่�•๑ี๋ืดi๓้ะ\ณz5ูง };w$๏–-ไุฮ�yžฺถ๏h3spชWญBƒ�$ซl฿ฑ“บ๗์\u”€€€€€€D0"Fฐลt@@@@ ผ€ัณWฌbๅช”!c&)�๕ไ ส•;ฐ5!" ใฤ+ห—,  ›�ฯlrญฺถงO?'๓–/]L7ฎ_3+วธJ€C ่฿ื่&GŽ์=zty}์˜นศ้ึญ�ิท�F]uRปf *Qฒธบ4Ž๋7lคm�vื๊คGท.”)cF๚๗�}J�yrสœ9#=~๒„6 มม๎�{ฉGn”.mz๔่1ญZฝ†~ž` iฌฺซcงํ)ož�”Vิ/ž_~‡�บx‘ฆฯ˜E�ืVjPฟžt†K›6-E…^ฟyC—.^"๏๊ต๋‚4cF}๛๖’๙+Wฎ"Kว9Gํํ�B–O6รธ7‡ ฮ’9“ฬO–,)ฅNZž๓ผ๙~zbqEx )l)Dผs๗•-SJฬ=ณb_ป~VฎZC๓่S&gYซzu™%JTส;ง<�๚ :eพ~๛ 9s็ํงLš@ฑ?„มL›.-%�์3Yvํฺ5ฑ๎๕� —บ.]ปำำgฯŒผ้ำฆPŒhั้จุ฿œ_Q„�LŸ�;z#๖ม๙๓hำ–-ดh๑ฃ>Ÿ๐+งฯk"tๆO›•๓E‰ลฉYใF2�าๅห4dุˆ u\อpTˆุซGw๚2uช ท3fผUwฎ๐๖lVชXžช( <Œn�ฯ�ฺดIc*Rคฝ{ชW๏๏}เฎg๓‡พ}จ^�:’๏่ฑ?ำ‚€…AX—+W†ิญ+๓วŽŸ@gฯ�คŽž‘7wnjืถตฬšท`!ํูปื(๎�ง—x7ฆฅ‡Rื๎ฝศซEs*Xฐๅศžbˆถw„หๅฦอ›ƒ„~wtธ๒lชมฒS\฿Nาๅํ›ฏฟ’฿•โู9๛๛4r๔XงฤZชo�ˆoXฤ๛†๙MžH์,8sถฟtnm�บตoืF.ป=BD�=ฆEำ&”N|R ‡๑ทo฿าฅหW่ะกร4N<ƒ๎L{w฿Ÿ†Mš…๘|�บw\๑0=๋��๓/•,SฮVUไƒ€€€€€€D@"FภEล”@@@@ <€ัsW+IาคิคYK้bx�๘Q)~ศ_  ฐ5!bณ–>”8qbYพww ?vฤlr;wฅยฝM<^ผxaVŽ p•€." ฉฏป๗๎Q้ฒ‚T2h UซZ9H>‹rXœc™ฬโC“@ฯฒฬฺu'฿nfbžŒ.d฿}›ฮZu)(cฑAภยลAส;ŠJ—*$_elุฐ)ˆุRg4K#&N๖Sีๅฑ‰กหBNขปี๒|แ�น”5kyาแ#Gำโ%KCชๆ‘ๅ:Ÿ‡กƒ-;ูo*อ˜9�ศ๎�ี—š7kj\wb้ฅฺ‚kฃสชVฏmˆ๎tฑ‡*ทv\!ึpXK•XTตrู๑พN$ณ&LœL�X%._ณj9}– ีrUฯีฃฃBฤ๋Vำ—_~ไถ–ฯ”ช�žM}ตi�!ˆ˜W�หVจd„ฃvืณนB์ ๕ฒลดฉง๖โjN–ฯ€โฎu‡5ผฎZณึ(^น|)}+ฤU�ป?Uซ}๏rๅฅห™ ��:Wใๆ6N,ŸMy!ส8 ฟ!ะฒlสb์n=zั‰'-‹พึ฿?!5ฦ7Œ(<~ร"ถkำšZ๙x� ยrOธโZhู�.ฒ~ํJ™อc"rJ%ฤฏ฿ผ6�72ำŽ๛v๏2พŸ5kืฅ‹—.�ั U@@@@@@@"#ย*b    Ž @ˆ่น‹็ำฆฝtf{��9M›2‘ )Fม  *B –z๘๐อ=ำฟœ1SfชPฉŠ,S�y๎ฬ1ฒ๐Jเ๓ฯ“‘WKc๘•+WขOใš\:—.[nไ๓ ‹8t!™*dวฏbEŠสหT)SPฎ\&g;{„ˆ�. /^ผคดiาจ๎่ถp^|$Ypรiนp!K—ง‚๙๓SฉR%d“จQฃR�:ตๅ๙ใวe8Ny๑แ‡ ึ�5ูั.v์Odi>ม๕ม—ฏ้ตซืไ9�x'Yไฉ’5!"sgMvึd็C•8ฬ.‡�Uฉpม‚4yาxŠ-ฑkcK:}๚Œ,ๆwทฺ๗<๗|U3ท"ฒ(‡ม8ๅศžีpๅด%šำ…ˆแแูิsŽ�๕l?rH8šd+Uฉฤ‘‘นณP‘‹œv๏�C…Cgpiฆx†ีปยฒO%Dิ�ณs;มฦŠ‹ฒeอJqโฤ"Dttธ๒l๒7e�๊•โ๙Œ-‡y[ธ4๎�-ŸลbลŠJ‘๐�ชXนบ>งฮ๑ ๓ผoุŒi~f฿ิ๖�{�ˆง…อo ฝBD�]dฬศ�œhู}๓ธ๘vฐ๓xล ๅ‰฿�œถm�N=„CชซIWฝtู Š+&ฅษ’%“]ณซ๓ฑcวhะะแfย`[๗eg๔L3ศโพ?๔ง 7�ชŠ|FBฤถ ˜€€€„7"zๆŠขร|�ืฎZI—.]Qˆศ3ฉSฏ๙•œ‹f=z$„qdHSฮไ<�ฃ�ๅหๆก\e�7˜7—ฒeหB๏…2 {ฎ�DY๖�†…\ณf˜ฤp! 9\b‘b%eธิc‡1๖|มยลd�/๛v‹ะไŸŠบวศปU[9]Lx็๎]๒๖ikธ�q…?�H5?„jต„m�ด’‘\๖ใ?wŸ0Iž๓~฿๗ก๚๕L!V/_นBีkšฮนLฺ9"Dไถ*้‚…ู�s‚„NU๕\9๊ใดทŸ#G’O๋v๖VทZฯ๒พฃวŒฃ ษบ,�Xฟv5%I’X^ืoุฤฆุDนฒ(ฐYKoซ๗ฒ–ษขฤอMฮŠึฤhzK!โƒฉ]๛NF•?�@jœ“56;ถ'o/Yฮa€๋ึkHอลฝY(ร‰Eด5„“• Zธ้‡ฃBD�ถ�ทฃึญL\C"†—gำY!ขฮลูgS฿Kฏ^ฟฆ<๙L๎วz฿๊�ภ�@๙X”วฮŒมฅ�{)~|Sจ๙2ๅอ๋๊BD~GO›1“8ผJ์ฬYทv-š>s–ส rดgX6rไู3r8•+WVvq์๘ ๊ิน‹ู๓  ษ๙ฬ๏bw&|รˆ>๖7lั‚y”%Kf‡–ต…w+›™๖ 7o\K)S˜„ื–ฟฐKแสๅKค@–ŸFM›;FYMฌvญš4 ?ui๓x�มjึ��์wk•๕gG�ŽZซ‹<ˆEBฤˆตž˜ €€€„;"z�’ฑ�J+แ†ศฎ^ท… ุขำึCrDT3))ย(ๆศir‘Sy||#Bป-_บ„n��[ฯฦ9„ฐq�บy‹ส}p�ไ๐†ๆ๐�ฝจTู๒r~ห–,ข ้ฟ#v5jุุ$4Sใใ =z๕ฆm�wšฑ`wฌ-ืKื:v#*Rผค,O›ๆZฝาไ๐ศแƒ‹–0ฯฬขข];ถ.^zW]h็ษBDZดk�ฺŒGHฟ9KK–. ฉZฐๅ:ŸkืฎQ•๊ตฬ๊๗๏๗ฝแvศnp์ g-9"vา�ป"DไPšRS%rํุบI†๕d1^ฮ<๙U‘qœ3k&ๅฮmz_ณซ�็ษ>—๕ู…ำซU้ฎhTv๓IX รหณ๙1…ˆzXึ๋ืฏSๅj5mฎ๖๔iSˆ]9ฉฐษีซVกฮ;สผAƒ‡ษ๐๓zŸ;wํขฎ��spๅŠบqฯพ}BไืUถwไGh O;,฿ฟ/_พค๒•ชq‚cก8 ฦ9YŠล™‡ญบ๊b๚๐๒œ่๏่ฐ๘†5kฺฤp-ถตN–๙cždฏจ:๖uA๑Ÿ็�’Žศชฝ:<ะgฎ‹`๙ฝ๏H๚๗฿eu��ฒ�จžxO_ธp‘ข งิzยๅ7VฌXฒx๗�ฝิูืข]ฏฏŸw๑ํD^-šหฌ™ณ�iา?ฝ็       ˜„ˆxq15 D๔ผUjาฌ%%กุุฝpๆt?z๖๔ฉdHBฤhQฃQcŽ.q’$ฒ>�แ�pVŠ"BF�sโ>ทn�H็�๘O,# ๐B@XŠ8.]พL5jี•ณP.Yืo� สUMŽtJtu๕ฺUชZ�ถw๗ฎํ”(aBู†฿ŠนœขD‰b?O�น<็J๔SขDqš๘๓X™ฟM„r๎ัซQG๘MžH,fเไํำ†80งฐqศ›†ฃ:ŸM›ทRŸพๆQ�"๔ทoงrF\ฦuฌฅฐ"�นs‡,็x\๊เsหะธœวข•UยYหRผ2qฒฑศ'4“z&๘๚ต็ž๖ะThๆ๐๒lzŒQ{oY[ ]ฐิฃwf|์่‘TถLiY}ๅ๊54pะ้ฦษฎœœฦŒO๓ศs๕C"ฒ“)ปv:š์ู–}ฺ๛l๊‚o๎ใๆ฿7ฎิ;:šh%�๐;5แฒัภษ๕�†…1ผ<'๚;:,„ˆN.อf๖›6nD={�'๔S{Oํ;๎œ7Pืkึญง ค*U*ัฐมƒl��Zม๖;ฉ{ฯ�R๘ฏ —-_AC†�šลว,BVI�*O?Bˆจำภ9€€€€€€D."Fฎ๕ฦlA@@@ภใ@ˆ่YK’9Kv*Wก‚ิฉ“'hืฮํฦC"ึ"ฌฏำค‘๕๏฿�—–,\@/^ผืๆนPแข๒ฆ,F๔›4ž^ ‘"„&ฐqœ๛๓<ีkะHNgแ�น”5kบx้ีฌ]Oๆอž9๒ๆษCJœจ‡Bต‡ Q๊ึoH็�บ@M7ค^=บหf‹/กฃฦ้B๋<เงAดzํ:Y'ผ‹8‚Lิอ:Ÿน๓ะธ๑ฬ๎ ณ8x(ญ\ตฺฌ\]ุ+vR๕ีัYGฤ?ฮ#m™&M�™Š-*ณm‰ฝt๗-ฎ๘�ogคจ�ฒ/w_‡•1ผ<›Sˆจฟ^ At๎|l.ทYศzถœรฎ๎ �A ?๛Lถแ0฿,z�iภTซ†Iˆm-Œน.DT"k›7ตQšBฤrๅสะ˜‘� ฑl มศ�๗�}*Qสฦูศt๑฿ฐj’`D๚†ู#D�กoชWทŽ�ป'0p7๙v๋!ž7~๎๚��Ž+๎�#� ปtฃ๕๋Q฿>&ืR���อŸ>{fึ—ฆบcง.ดw�~ณr�bฬจTฎl™…ะฬ:œƒ€€€€€€@ฤ'!bฤ_cฬ@@@<š„ˆžต<ญฺถงO?G,z๚๓�fƒK’4)%I’Tๆ=x๐@†Xพw๏=|Pๆ๙v๋)ร9sะฉ“'ึฌ#„Š_›„Š–"Gณแ�D ,EบL ฌ.\ผHต๊ิ—ณ™5c*ฑ€G ูn๗ฮmฒŒรเ��7Œฉiฟ1�๎jฯŠ๒๏ฯ ฺ|ฺ#D4pีจVU�๎๐‘ฃดwŸmมW๚S�CvM•2%ีฎe�ฺ3Vฎ๓�ู฿ๅwณ\ูา4fิHู์ข๘�ฅๆ‡฿]๔~๔q3–.ึ‹อฮ—. Œ2ศผพ?๔ง 7›•ใ@@@@@@@ โ€1โฎ-f   แ‚„ˆžตLmฺwค8qโฺ=จgฯžาtฟษ;Nj��$Œz�๘1อ!-S–ฌูจl๙Š2๛7ฎำฒ%&Q•e=\ƒ€ปxฒˆƒ็x่ภ>๑ผลข�เศ,yTชXžF *ณืoุH�๚ฐฌB?EฅK•’๙บ-Wฎœ4w๖L™oอ๑ฏsว๖ไใํ%ห?ฆQ™œ bฐ๋Ÿ+Iฟฏ5กฆง ฏ_ฟN•ซี 2u]ˆXง^้จฉWbq์4ฟI=บI€ฆส”K–บถvฬ‘#;ฅJ•า(z๒ไ)ํ�ฝวธ้ฤS…ˆ<๎๑l๊!�w์L๛�b†pž�,ส™3‡ฬ !ข )ฯ7่ไ�๖์�kv�B9ฃ={๖\ˆ‘Q๋V�t๖๗?(�งq)u๊ิฤกฝYเสยF[ฯฅ"ฒ๛Zพ‚E๔๎ํ>M!bถlY ๅ๑ใ'ฉฅO+ปวๅฎŠ๘†}�o˜ฺ๋Žฌi ๏VtโฤIซM์"ถiๅCฺท•ํgฬœM“�ฆZํห™�>Ÿ?gถ์๒ฯ๓Ifห�ูm‘]9Y ทฎื฿ฟ'โว'ณjึฎ+ข/๋ล8ˆภ DŒภ‹‹ฉ€€€@x !ขgญRณ^”เณ„V5jT้xศ…^™�๘เ>อŸ๋OŸ%LH-ฝ[หvŸ!โด Bฤ์9rPฉ2ๅe;wn‡ฏEะ$  ฒๅฬใ๐ญฬB ‡ฃัcาวโ€๙”9s&rิu;Zฑl }๗m:ูg“ๆ-่๔�ูป 8ฉช6Žใa `#Š ŠEฉ€tŠด(� Šโ‹€‰ŠJ ’ข`ะ�]าขข&(จ„’"๒�็ฌ๗zfvfwjag๗w฿ฯปs็ๆน฿3~ๆฯsถlMด�@์€ฬ๗?|/Z}ฬX4ฎ\rIn3Y็๋r:ุAฤ@!F;ภJ๑ƒ ๅ…~/›mว๒ฯ=ล‹ห0' ฮฐv�zi�ฆ}8ซ$Z6ึAฤ`ŽD;�wยฃ;Iำ&ฬปฎ�{ศโ%K‚-*vwบZUณl…สฒo฿>ŸๅW-_*9rd7ำ�๏ญ:9iย{’+gN3ฒำอtน2eผๅต[j ซ์`œ.ฃm(\,x—พ��ฑ๏ฯิTQ�y&๎M;ˆhwE๋บ-Y4฿;Wกรฝ7Ÿz๒ ฉW7ก;ุไBFO<�]ฎ�iฺมƒ˜kfไจ1’-�๙ฆ‹ืส9r˜๙ม‚Tg:ˆ˜�ฝi฿_zŒ๗•Jลน็ใtผฺ๗ˆ��ส�๙ {^ฆ8ฯ5�มฎš�}bŸ�ํ{Ÿิ็y(ADป:aฐ oฐ}G:]ฏ๗U+–šP๚กC‡ไ๎๛J%ฺ”[ูYgtzด[ะเน}๏่g’vฝฮ€ € € €้G€ b๚9ื) € *"ฆสำฐQw฿[B๎ผซธ™๗ล็[eม<฿.�ฎ™5 8j๘09|๘ฯv๊>๔ฐ\qๅUfฺ—ฮ๚๓�ึ๗Y˜7ฤ@ภ๎สดญSฑsอฺ„nฤC�tJ‡8์เvqฺธY‹€MำJE�๑‡WQHไ_บxdษ’ล,๏จZตฒผ๐์3fžV(ฝงฤ��v5œจ!E๖�ฒGสUชโอำngL›โuฯ,ˆ˜๏ฺkdฺ”Ifฝ-[>“›z�ˆๅˆถ'œa���Aปร u;ฑ "._บH.rฺZ1ฎLน !ทห๎{ฬุทe@]v�a=>�ๅkีxPz?�?s่?ํฺeบ�ต์PษฆอIณญฤภhฅฮฆ-Z ศฆๅ โ™ธ7ํ๓ตpแ"้�ใI๏tUฏVUž}ฆ๗>X1š{ณt้๛eภซฏ˜}่ณRŸ™ม๛:q—ั๐U๖lูe่A๎$๓์ู{ฆ‚ˆแ�›v ๕qใM8Ÿƒ๛๗MฉR%eฃำ…๎แ#GอŽxŸa"g๚3LŸณ:ฯ๒p}�B "jH|�œ™r๎น็šอุUํํj�๎นงธ,\<ฐn/Ÿ�ธ†�๕่ Ÿ=๚™โW็นZฆO(™2e2“์เเ.ใพjีDญžจƒ†้5Tฯ€ € € €้G€ b๚9ื) € *"ฆสำฐQษ›ทl#ู�ญ€ค]6๋๘ฟ�๖›ู–qnฝ-กKI๐�ปใไ—Ÿw�ˆ•@๗ฎ]คQรfsฟ:ืโไษSeื๎]ฆr��}D+ู่ƒ�๘หอ7{“nฝๅfiูข™yฏหพ๗�o��ฝ{Mฤh*"jˆ`��Y^ๅฐ฿~+oฝ๕ถ|๛�w’-k6ษŸ�ฉTฉขไฟแz™:}บ๔้๛œท�žO๛lณl ๎…ํ*yห๎W'Oš*9s^,ํฺถ–�นช(๊สม‚ˆ:๏ฃ๋ผ๎|—,]*๋ึo0ทn�ฦD•๙tz< ฑ "ฺ�yjตฬูsๆษ��๛L%ูํ�w$๊"ูตฑ๗�๘q™6}†l�๖•;~L�>yR.\์.๊SQ'ž:uJ�z๛Yฟnƒไ/pƒhทต๎u๐J�ืdœำ…ฎ;hทŸฺ�ง๛ต๊z็ฌื�zJZ5อผŸw�,5๋ิ ฐ:ADญzูe—›6้ŸZต”R%J˜๗�ธ้#o�ถฏถษž={%�๎MญฌชmึA�oฟฃวตIn.Xะ้.ฝฉw.u~ฐ ขฮ‹ๆ�tซ.๊�ซืจใURีํฺƒ>ป>\ฝB2dศ`&�UฯึฎYiฎM‘T•ฬH‚ˆ‘\vปu<œ{ำฃ๋บซVฏq๎ษ™๒๓/?;g/�ŒจZฅฒไฮ•Kz�ฏ—นฯuนX |†‰ฤ๛g˜�+�บ=๊Uฟํึ[$฿ตืšKไ�๏พ“?๙ิŒŸtž๏ฯ>๗‚wุ้�Ž๋}4i๒s��๑็ฆ๛sฝ6+”+k�AB๑{J|F{ qคrฅ า๏…็ฝ๖Œ�žฌ]ปฮy๖^*ํ�ท๕*ฒ&๕'tๅ‰ผ'œ๏/: Qš™�A@@@4)@1MžV @ˆ‚ˆ๑sฎ’ "^tัลาะฺ้Yปpv�aU฿ปaพcวv™้T]c@ ฅด๚฿ฌ้SฝชB๖�4˜Xฆ\E{’tําYš4n่3-ุท[ฯhยNบm�แฟฯำฝถั�ทQC“฿๏ด—ืq ]ึฎS?Q@ก�ฃฅqฃไ3ฉ ขV๓฿๏‹/ฝ"๏๐_hำ~j~o`+”——๛�*ฑyัโ%าํฑเข�€–ฝŽ;nWกา€‹†พ’4เ๚`อ:�bล๏ผS†พ1ศTถา๐b็ฎ�uฑiทaลชUาฑำฃ�๚๎ศ้ "Ž{ฌh—ไก &N’็_|)ช ข๎็L�›๏พ3Vnqยmษ Iฃน7ปt๎(อš46ปŸ4eชO0สฟM3ฆM–k๒ๆ5“็อ_ =ž|สŒ๘š�โหm๒ะร ap�๕�k์ุฑcrG๑{�g|ษuเฟกp๏Mปj�mู๏S"ˆศgX�†i%มY3B๛ฮ[นjuฑซ)†ฺ-tฌ‚ˆz=z�Uั Ÿม†ฟ�๚K6nf�!F e .$cG4ณ~�้'ฉRํม@‹1 @@@าฐAฤ4|r94@@ "ฦรYJhc๑{๎•ปŠ฿c�l�l‹,Z0/Qใ/ป� ฉTฅชไศqAขy'�>)Ÿ|๚‘ฌ\ถ4ั<& Rhฺดก”*YRrdฯ๎u+่rญ$ุถuซšโvIำง—ดบลkŸ;_C:๋7n”๗�� QG ขฝ๒r?นป๘]‰ภ+Vฌ”งz๕NBtท๛๊+/Iนฒe�ทขกแO>ู"K—/—วœ๊M:<ั๓)™;oทŒ�H๓fMฅRล r‰SE1GŽ์�์�}ž‘i3fz๏ใiฤQ :LFŒํำ|ปหษไ|ด‹ห‡~H 9]kgอšี dฯš=วœŸ [o4dฺมฉ>UฌhaงาZnฏ n=GซT3ี�tq;ˆ๘ัG›*zEœkั ~kศ๐รu๋คปำ-ฆ�eฌๆš0qฒฺ๋gํ=aTป๘}ฯฉฮ็v��จis็๚Hจ�ๅ.lwใฉำ>,w฿<ภโฎ็พŽxsจ�u็ๆm�ไ๓ฯฟpg%zตป‘N4ำoย[c฿‘ื’xผ7ต;๒^“๋ฏห็•V<=wžd9็\ัnืต:Zู •ฝ –�‚ึHค๗ฆ^{๓fฯ0็]ฏ™ฒNX�พvฌ]ศsฯ๔•ช%tํ�ณืำ2{๖\3ป^�ฺข][๋๐ม„‰๒Bฟ—อธ�7tyเเA)Q๊ฟg‘�r๖๛Hฎ{}w<�{Sส=zt—ซฎผา�„๗ชี WฏY+oแ"๓ˆr„ฯฐ#ใๅ3Lรค๓็ฬJ๔ู๎Pม๎k 7k๊t{ž=›�*ฆb้Šซ‚vžh…'hลๅjNw๐๚cZ�ทืำ}‚V๔ีeต{wํๆ]�Jผf"@@@@ อ DL๓ง˜D@RทAฤิ}~"m]6็ำูเ‘O็ะนc{ั ฃ–1c฿>ปOี๛า{NŸ™น/ษ%๖�ด๛๊T} )ุธำyŸคงฯ0=ึ๙ HถlYeฯ/{ๅ‡Ÿ~๔B้)u:�็ะ�)Z�TCทI ฺฦyณgJๆฬ™Eปฎ^ฃvR‹3@@@าจAฤ4zb9,@@ ^"ฦห™ข €ฉI P15ตถฤฏภโs%gฮœ๒แฺuาฎCง๘=ำ�rฝ'+Wฎั^ฟ๚๚+ูฒekD๋ฒฉA บSEฑoŸงMSบt{L–/_‘šE@@@@เ4 D<อเ์@@ภW€ ขฏ๏@E€ b(J,ƒภ้(_ฎŒ๔๙ฅˆvธh๑้๖Xˆึe%@@@@R‹Aฤิr&h € N"ฆำฯa#€D%@1*>VF ๆeห”‘ื๚DŒ9,D@@@ˆ‚ˆqsชh( € 6"ฆอ๓สQ!€คฌ€W,[,™3g–%K—QM-eนู:! .\(คๅ�๚๎ป๏e฿พ}�“y € € € €@\ DŒซำEc@@ด'@1ํSŽ@@@@@@า—Aฤ๔uพ9Z@@ ี DLuง„!€ € € € € € €a D ‹‹…@@b-@1ึขl@@@@@@8ฝOฏ7{C@๐ ˆ่ย[@@@@@@@ ฮ"ฦู ฃน € €@Z ˆ˜ึฮ(วƒ € € € € € €้M€ bz;ใ/ € ส"ฆฒBs@@@@@@@0"† ฦโ € €ฑ ˆ[Oถ† € € € € € €œn‚ˆง[œ�!€ €๘D๔แเ  € € € € € € wใ๎”ั`@@ m DL[็“ฃA@@@@@@๔'@1�sŽ@HUSี้ 1 € € € € € € €@ุร&c@@X DŒฅ&�B@@@@@@NฟAฤำoฮ@@,‚ˆฃ € € € € € € €@ DŒร“F“@@ด$@1-อฤวrม…ส�๛ฯ`  € € € € € €ค‚ˆiๆTr  € €@| DŒ๓–9๓YาผUkัW>ฺผQึฎYฐ๑+W•๋ฎฟมY6ณdศA�๙็9v์จ|พ๕3YฝrEภu˜ˆ € € € € € €๑+@1~ฯ-G@า„Aฤ๘8ต๋=,W]u•ืุ/>฿* ๆอ๑�ป#-Zท“lูฒนoฝ~ฝm›ฬ™=#ัt& € € € € € € €@� DŒ฿sGห@@4!@1๕ŸฦkฏฝNชืฌๅำะ@Aฤ๛K—•� 1ห�}๒คlฺฐN~�แน6_>)Tธจdฬ˜ัฬ[8ฎฉŽ่ณA� € € € € € € €@� DŒ�SGร@@ด!@1๕Ÿวv:ห9็ž+�๕—œ}๖ูฆม‚ˆ:w•ณฮJ่บ๙�๑๏ศ/ฟ�์\ž|HF {#ัตlำNฮ??›œ:uJ†`‚‰b € € € € € €ฤAฤธ;e4@H[S๏๙ฬ™+—4hิT2dศ ›7o”ฟO�-w�U�4ุ?ˆxูe—ษC42๓๖๎๙E�๗vขซ๗pCน�๒หอ๔Yำงษ๖ํ_'Z†  € € € € € € ใ๏œัb@@ M DLฝงณE๋v’-[69z๔จผ๙ฦ น๛�1 "ฎ^นB6nX—zž–!€ € € € € € €@ศCฆbA@@” ˆ˜ชัo๓'txวฟีgL";wnO2ˆจ{tปf>t่O๙ๆะDhแtอœอ้šY‡O?๙H–.^”h& € € € € € € €@� DŒฟsF‹@@4%@1๕ฮ๓ฒf•–N5ฤŒ3สž_~‘๗ฦ'tณœTED=ŠŽ]บJๆฬg™z๗ฑฒw๏๏เ๒ไษ+ต๊ึ๓�๏ุพ]fNŸโฝg@@@@@@โW€ b�ž;ZŽ €ค ‚ˆฉ๏46hิTrๅฮ-��๓Œ>TŽ>l™\ฑLน r๋mท›e��๛oูดaฝ�๔ำrอต๙คPแข&ุ่ํw;wสดฉ“�ทผ"€ € € € € € €@ DŒใ“Gำ@@ด @1uล‚7฿&ๅ+V4๚๔cง๛ไ%�uŸœ\QWj�ฎƒœw^ึ€u๘ะaษz~ยผO>�X–-Yp9&"€ € € € € € €@| DŒฏ๓Ek@@4'@1uา–mฺษ๙็g“SงNษW�พ๔i\ฮ\น$gฮ\fฺไ—Ÿwหoฟ�&ืฏ๕Y๎kษีyฏ๖บi�๛๏N7อ{ๅ›ฏฟ’’ฅJ›e—9วOœ # € € € € € €ฤฟAฤ๘?‡ € ืSื้Kชขa –9rX†h–dส˜ษฉ€xพ�๑วA3ฟ๊ส๕7ไ7ใผ7^~�ฝ+เzLD@@@@@@๘ ˆ_็‹ึ"€ €iN€ b๊:ฅš4“\ฐQ3f�ฟ��๓๙�ม๛ๅฑc.๏?ฑc—ฎฆJขฎ;xภซf}�ex € € € € € €๑'@1�ฮ-F@า”Aฤ๘9w฿[B๎ผซธi๐Ÿo•๓ๆ„�๘๒+Kม›o1หทsงL›:)ไuY@@@@@@RทAฤิ}~h € ๆ"ฦฯ)%ˆุฌeู๕ำ๒๑ๆM๒�oฟJพ๋ฎ“ยE๏ห/ฟย่ฉSงdิ๐ar่ะŸ๑sเด@@@@@@�ฃ๗@IDAT’ ˆ˜$3@@RZ€ bJ วn๛ก;w}ฬ๋พูฯB\ณz•l\ฟึ๏@@@@@@@ Ž"ฦ๑ษฃ้ € €@Z ˆ?gฑ๘=๗ส]ล๏1 �๚ูYด`^ขฦทj�^ฒf=?ั๔ใ—93gส๗฿ํL4  € € € € € € ฿ใ๛�ัz@@ ๎"ฦ�)Lt]tฑ\sm>ษ‘#‡์�ปGพฺ๖ฅœ8q"ัrL@@@@@@@ด!@1mœGŽ@ˆ[‚ˆq{๊h8 € € € € € € `"r! € €œQ‚ˆg”Ÿ#€ € € € € € €Q DŒš € €D#@1=ึE@@@@@@ฮผAฤ3h € ฎ"ฆ๋ำฯม#€ € € € € € €@ ˆ˜N"‡€ €ฤณAฤx>{ด@@@@@@!ˆศU€ € pF"žQ~vŽ € € € € € €D-@1jB6€ € Aฤh๔X@@@@@@8๓ฯ�9  € €@บ ˆ˜ฎO? € € € € € €i@€ b8‰ € ฯใ๙์ัv@@@@@@@@„ "W € €ภ ˆxF๙ู9 € € € € € € ตAฤจ ู € €@4ฃัc]@@@@@@@เฬ D<๓็€ € €้Z€ bบ>�< € € € € € €ค‚ˆiเ$r € €@< DŒ็ณG�@@@@@@@‚ˆ\ € €gT€ โๅg็ € € € € € € €@ิฃ&d € €ัDŒFu@@@@@@@3/@๑ฬŸZ€ €คk‚ˆ้๚๔s๐ € €@\ ,š?W.พ๘"Yปnฝด๏ุ9ฎฺNcHK=Ÿx\jืช)GŽ•jิ’}๛๖ฅฅรใX@@@ˆK‚ˆqyฺh4 € v"ฆsษ‘ €ก <ึฝซ.THŽ;&Mšท uต—{ฆoo)t๛ญ&œPฏ~ƒื‹fม3ฑฯhฺฏ๋f=๏<9็�sM๓๕๚9|ไHผJŠถปX‘"r� ืหฑฃGๅง]ปeรฦ๗7gึtQS{8uJคu�v๒๕7�ํษIŽWญZYฉ_฿,ำปO฿ฐึMrรฉlf็ŽํฅyณฆฆU ‘ัoM๑ฆ๔๓2ล€xW็นZ๚ฝ๘œy?y๒™2mบ7‘๐จVEž{ฆฏYq๚ฬY๒t๏„๑๐ทฤฎภ ศฐ7นoฝืC‡Iี๊5ฝ๗กŒ๐์ E‰e@@@ด'@1ํSŽ@ˆ+‚ˆฉ๏t•ซPInศ_ ษ†ํ�๗ปผ?�€หไศ‘Cช9?T]pมrึูgห?��#‡–ฯทn‘ตkV\‡‰ พ�5RŠ)d๚ึBE“=x J5xไaณ�สUซๅหm�’\็�wฦส-ท�lž?ทน#ษec53๛,X๐&น๗๎ปM“ฦฟ๛^ศ!ปp}buฬgb;ซW,“์ูณ™]๏�๕W)[พา™hFช�ง 9ฝ๐ฌ(_2eสไำF lฮš5[^่๗ฒฯ๔7ญOดฌ.ะผEkูธyณฯฒIฝ้ะฎญดjู�,าฑsWYฑreR‹Ÿฑy ็ศyฮ๓ไ›;d้าeaตใข‹.’yณgH–,YฬฝYถ\ลd๏ัX�›แ>/ร:จ8^8า็e4‡\พ\น&๏5Nศ�ˆŒsžัแw+&ฃF 3ซ�ฎผ๒๊๋แn"M.อ}ฒxม\ษ;ทœtXFผ9$ั"]tฑ<าจฑdฮ|Vขy:aหงŸศ’E ฮc"คpœพ๗žปe่„ =ฃวผ%ฟ‘$V,BI๎ ภฬX์ณk—ฮาคqCณ๕ึmฺหฺ๕๋์)๑คp}o!>ฆ�Sผธ :ุงฑ 7‘-[ถ๚LKoJ–(!ฯ?�ื i2ุ๓ห)WฉŠฯ,ญdจ! ชUฉ"ท�z‹OซAฤ-o2ว๗ษ'ŸJฃฆ มI3!„?v๎$M›42KNrชู=๛�‹ษฎ‹{3�็eฒJ# D๚ผŒๆ๐วฟ=ึนGn–SNูะ�  {Svศ‹ โ|ั�'m�ด’ถญ[™อž=Wz๖z๚ฟ 3ถ€~่็‚;ดmำZ.บ๐BIซAฤ3๑qmyE@@าชAฤดzf9.@@ N"ฆพew๏�ฐ{๗์•eK&šืถCg9๗฿.3< _}๙ฅS๑Bน>~ษ!ƒY~��ู๒ๅŸ'Z—  ~j>X�Tm;z๔˜ผ>0q€�แ†b ๔oCr๏cฑฯHื'นcIญ๓�ื๓ ฉ[งถO๓�๛NHืฯJi์V๊[0w–œsฮ9ๆศดRไ&ษ6งr่๙็Ÿ/w�QLชWซ&๛~�=Qัฆxผ{7ง๒hB๗สแ .$ห—3›ำ๎Š๗8฿RใMqฉ๓)rๆผุTZญ^ฃŽ|�ร๗ษb,๎อpŸ—ษ6*,้๓2šร6ˆจ๗j›V-L–-[rุ<š6วรบั�'œำ�&ั��8๊tE_บl…d+•ฦƒIjiใ๏—›n,Q1ž]gโ9’Zฮ-ํ@@@RJ€ bJษฒ]@@"†ฤtZฒƒˆฏ๗)ไ}_ํtUWณv]ณ�‘#‡e๘ะ�*&–-_Anน๕v3๏๗฿~“wฦŽyป,ˆ„RˆE(0\๕X์3าฤร๕ ๗ุRห๒๓็ฬ”ห/ฟ�ง9�.vkึฎ็3-ฝฝ้๙ฤใ๒Pฝ„ฯ฿Ÿvํ’Vญ�‰พฺƒv�\ผ๘N@qข=ูg<š ขฯ†R๑›Hƒˆeห”‘ื��Nดzอ‡าฎCงŽ2ฝ�›!aฤxกHŸ—ั4#ฺ b4๛Nห๋F{Ÿ<๗L_y ZBตื_zE��`BZๆ:ญวM๑ด64ย‰็H„Me5@@@ n"ฦอฉขก € €@ฺ ˆ˜๚ฮkคAฤz7๔"ห—-–7o๖ฎM๛N’%K๓^ปณ:x€�๕ื_�|Fˆ•€VฦฉXกผ”,qŸไฟแน8WN9๛ฌณd�๒ํฮoๅใO?•ƒ� ษ๚๏Wืoูฒน”-}ฟไฮ�Tุ๙๋ฤ ู�๛>๙tห™0qฒlดฎm�๓ๆ‚7™อ๔}๖… ฒ�[~๘๑G™2uบผ3nผ3}�๋๘u๋ึ–k๓ๆ5๗`ฦŒๅ7'๐๛ูึญฮ๑“dรฦ>ห‡๓ๆส+ฎg๚$ts8oมBั๎H“ฦŒnYฟaฃ 9ส[|เk�%cๆL�{9~์ธt� Ÿi๎�6w๎\’'O3k฿��ฒsวNw1๓:rิŸสRv(ฐ๊5Dปnผ�ถ[ๅชซฎ’ƒ�ญNUึ>}ŸiีถH๗้^z ๙ฎห'^p9ฆ~๘A๖๎�ีŒ๋Ÿ“��#]ํๆUzŠฦงNํZRษนON9�{๓อ‘Rฟ~]นํถ�$Wฮœ๒หฯฟศgŸ./๗5‘†=.ฟ์Rำฆ!ร�”>๚ุkŸ;๒rฟ$็ล›ทŽYทษ7\Lž๘ูฎ๎7ซS้/� ื›๗•ซVOผs�ฃฏZEฑVอEฏ็lูฒษษ“'ๅภƒ๒อ๖ํ2�™:}†ทธ}_nq๎ก}ป‚vิฎ+kVฏn�Nt๎‹๙ฮ�กƒ{^="/ฝิ?ขkO�ูฎmน�9ๆ?๗‚;Y�ใิ แ�า}บฺBูqต๊ตผ€—ฝฟไึ๕๗้�๔�Dร1I ฟ:aึปˆ�/๎ ม––-š™ท{œะอƒต๊๘4@ำศ —้ ฦN•�รGŽ˜๗ั�iืถตำฅiKณ ณœ~Viุเ๓^ป๗ 4เ5)UฒDะ�k๛Š฿๓฿| ?อ›=ำ„DŽ?.ฅJ— x �/7(`ถ๛Dฯงd๎ผf�>/‘\{ืH:wl๏ 5ผEซถ^ภุ~พhเบไ�eญาดpƒˆsfN xoutยึ+Vฎ บฯถญ[™๋ศ t๙/ธํซฏฅMป>ถHŸ—�ํ,5๔฿Eภ๗‹/‘n๕8OCฐ†ี!นใณฏ€ณ&๚฿›:+’็e8ฯ ื—,Uฦ็บŽไœh[๕™฿๏ล็ƒ~~�๖�๏าฝว‰Bหฎั?Nภ๚๖"w่ฆ|†e‹สล_d‚“ชT๓ๆ…sœ๖๓า�@˜#๖u—�ช๚ฬ,Sฎbขล์j}๖L ณjจีx�;N๘0แ8๘ฯ ๔��zิ๏0ฏ:ี;�๋ี�^ a฿๑๏พ๏?K^๕e)Sบtข้๎๛s�frยtƒ† ug™Wํ๎]Ÿ-:๔}๖y/Pๆ^fF2�'๖*๚,ึgฒฑ�lw๗c?k�i�ฏมพ_๊น๗๖[I>ืีM�b9h๔9'ิ{้ฟ�€ ะถ๕๛ฅ~ฯ 6„DŒไูฅ๛ี็ณฯ๔ญ<l˜็�ฃO>ๅ3�~พ๋็Ÿ๛9์…๔zoึฒต€ีyฑzŽ๘oว�lถ�ภ8 € € �"ฆท3ฮ๑"€ €ฉL€ b*;!Ns์ ขvฑ|ถ.ิŠตjอ๎�ปdมผ9�้ั๎’)S&9�ืq:(!\•#Giาผ•SQ%ฃœp* žๅTyำa๓ฆ ฒr๙ฒ€�a"ัธ?k V+�lw‚ZPรEส—7?v๊๖—/_!œ๊r๖`4œดษฉ|๘อื฿8Uณศญท�,ท�z‹ฉชาบM{o5 hh@‡ฝฟ�*eหW๒ๆน#^}EJ;uะ๊jcฦพmฦํ๏อ็ฯชีkœชJฟศ]w�)W]™Pi,ุ๊ZๅOร#๎ ?€๚้sฟ�p�๕Rิฉ„mQทฝr๙นภน—C 9i{ด]:<๛�‹>๛๔�Ÿdฮt–™Wบt)9?kV3,ˆจU์ฎwชฅ้ืฉ๖x็ลฬธ†9�+QM6ร'0็pะJPซ?\+ูœ*zeห”7ธ™T€อ์,Œ?‘๎SซBeษ’PQ็็ฏqŽUญเ๓ร๗?˜q�ฃฯa cธC4>�AฤฃGสโ%KEJ๗;a�‹.ผะ์fห–ฯคAใฆ๎.อ๋˜Q#คh‘ยf|น6s+|jeฮ!ฮณ฿<๏jsอ[๙�๐๏ณ‘�ธa]ต^�ๆš�ๆfK›6$อZ�w/ธ›ืฦจ  }&lv*)๊}ขyต฿�ww๎‘r็�๗นซ˜W ำjภJ‡~/๗—๗��ภŒป์€ฎV-ำฐข;Dz่๚ลŠ‘Q#฿๔ฎฯ={๖ส‡๋ึษAงzฃVFผว1>็œsฤ;4|ไayฬฉฆรฒeหฅsื๎f<’?แ๕~ืj†:�~�-^ีR�`”�–๒ๅหJ�—๚y“>�โKู์ปuะช‡Z™�์ ขN;v์˜,]ถBŽ?&ๅห•๕๎U�^วNบซ™ ฎ‘|๏๒6๐๏ˆ��ีI๖gณ�ฒผG@@า“Aฤ๔tถ9V@@  DL}'ล"j gOŸ.?�๐ฯ์.Nืz๎ั๐โ๐กCฬผ&อ[ส…Nwณ๔ุดqƒ�U�3�๋ฏถษœY3|ึ็ ฑะะภร=ไtW8รซ็nWซMš๐ฎ้n9P@Oปjป๏�„kTปo�ึXwU๓ชwฒœ—%Qe'๛G�Ž�ผย้ช\ปZ๖ฏBe�xฏ;xฅ�k2๎�๗ฬพtฝY3ฆyA ^iธฤ๔8gN›โUืัถ๚w9ญ�ฏSท–ฯฏ๎๚แผฺ.ษpด›บ’๗%.’ชF๕ึจ‘^ฉม‚ˆv5ไ6tศ 3i๔˜ทdเเ„šฝŒ=๎†\tš†`~ค‘Jh�ฒ…ดoืฦ,๎�ใดฝpวcฑO ู4iœPฝMฏ�� kSธ>vQ๏…6N•Oท oฝO�7Vฒgฯfvงฯqป fญx4ลฉงีสtะ๋vŽ่š์„_�เ“ž=OฑtŸหœJบ๚ฃึJ;•vuXปfฅ ฎ้1�WฒดwŽ��ฺแb ๙ถ๏ุูe^uปEฎz�ป-_ฎŒ๔๙%ณŒๅ๊?’pN�•ํภ�&ส �^vg๙T๒ ๗ฺณซ๎iา๎�{๘“ž›n];หซฏ ๔žov[�I^ฃBฑทีผEkŸn่“�D‡vmฅ•ำญฝ�ฯA{�ysfศ—'„�ƒXฺ%๕”I˜็š†QnุX>�� ณz4ฯK{�npDƒ๊š&ดืžh\Ÿวzญ้ ฯ๑ขw$„T-๋?-�{ำ}}ส๓า=.�œะฯ `บA�฿~+ึฌcช์นม๙aรGˆVี!าsข]๘บม5 W5iึา๋–TฏีทวŽ๒Bอ�แ5๗ynั4๘฿?ก>/�ฏ{มฦ๕yจก"�a��c”pณฉ�}[แ„pผ�2Iฝทรั�ืฟปžž#�Gฺ]๙ฝ%๎7ฯ€M๋?4฿#t7d๗แชๅNeุ๓eใฆMาผeยgšฯ9q�qD๓mผg…ฎkWq๖&ฺกR�vท๔O=๙„ิซ›&๕–ฺพแต=๎‹๛d๑‚น^ะถ†SญืYบ๛‰ๆ5š๏—ซW,๓>S๕ฟณพ�fปOS4ไ๘ๅ—_ฌิํณ`oz=๕คผึnฺ;:•๋m}ฎ=๖XWYทnƒฬ_ฐ0่–� �ูน#ผ �ก<ป4ุฏ฿ฃตBฎ^๓�Bด{mwx Zัชข:๘�ƒ;ˆจ�ภ qณ�g†�งzฟ๊ �˜฿[๒~3๎�'ิ็ˆ�z๚�}๎บ๓"บผ"€ € €@z ˆ˜�ฏŽ@8รฯ๐ ฐ{7ˆจยCNล ฟ…ฒŸMฒe�ฏ�Xญn8tศ@SกK7q๎น็J� ?”ัNEงBNeงR�vนdั9แ�x_ฑrUณว]?�(?H\h“H1 ณ้�:๘�P=v๔HฏRัs/๔“‰“�ซบ’Tƒ์Šd๚ใi—ny‹�]๚ฯณผ�มฉŒSตzMo=ฑDึ๊Zลัด๛[ํW7xโฮ‹๕ซ�๋๕t™1kถh`่ํฑฃอฎf:๏�ไ’E๓M…`U�ถ…๒ใดปฌพ†RpC.บฎ�fืมลา.๛Œ๔๑p}์ ขE์๊DฺๅฑVŽดญจ�Šk\�๑�พ�rษฅ—˜Emฯ^7’๑๚ี“'{$�Wv๗ŒvHึ�<๋~์ฎค5hกUเB�kY—๗V$5/า๋@ป๎ิ ขZนชRี๊>]›�ผ๚สKRฎlBw–รGŽญช้าAD๛:ี }Z‘อx�ูพRญj39XูpŸ—๖>�เH8AD ีอš1ลlFป�ฎ๒@ {“IŽ�วJˆ:ะฦBy^บวๅ�vฉ‹—,‘ฎNจUw9 ฝkˆุn_ธ็dเk�ๅ�๛K™ํชๆึฅsGiึคฑ™๏฿ฅฏ{ŸœŽ ข~^น•zMcB๘๓ูึฯECฦ�ร้ "j๗๖ๅ���ฌืŸ^‡v[ฟGศƒุaiท}ฺ๎๎๗Hฒึ0��9ณฬณ�gูU^�C๎+Uฺ็ะ๕ssฉฯ’%‹™^ฎbe/4g—9“Aฤw�-nลว3K๊๛ๅGื™ โ%๗:|เฃxใVณึM่๗R;�ฮfS:ˆh๏ัj‡Z๕ะ˜3sš\uีUfฒ�s์ โฬYsไO๗๖Yu๊ไ r]พ|fZฐ๔b๏?œข�xำzs/น;๕�‡๎t^@@@๔&@1ฝqŽ@HeSู qšs…ำ ึaงๆNw“๖pๅ•WIฺuœาบVตซfฯžร้†3กหœ cคM๛NๆGท฿~๛Uฦ#7�฿๙๑�AณษŸw๏–�gožqb*PฝZUำลl๎�น%งำ๕]ฦL �บ้{wจ฿ ‘W9Eง=ำทท<๘@53[ปw[ผxฉฌ�ฐ^ึoุ่�เ๎ฎkฟ๊๔ห–,4\ e•tธn—€๏ฟ;N �tฃYผCว.ฒr๕joU๛ว๛น๓ศ=Ÿ๒ๆ้Hsง;ศฮ�›i:O—q‡^�๋)uj%�ป@v—‰ีซv#ฉ!M&Mžbบ\ถƒanต- 8,šŸะ]ใ๒N—ฝ]บmB(ม{e;,J˜ว น่6์ภ„ปอWฏ0]๖i7ฯ5jีu'G๕‹}F๚ƒxธ>vQซ๙๙n์ํนม&ฝ6๕ตํJ๘มšตฝ๋฿žอธ�Uฒ8ดCภvุส�—]II+์i7วซVญqบ๖�”จ"•ปŽ๛jดkfํขY‡’%Jศเฏ™๑ญNXIซ๖ูCคืAล ๅๅๅ~/˜M3ท๗ใŽ๗นŸ้‚R฿'ืลฆปNฐื”"ฺ็K�๐๓๎ŸMS�ฎา๕Z�๗ำgฮ’ง{'TยŠๆyiv๒๏7ˆq๑งŸคJต„๏2๖vƒ�๗R(ฯฎ@� ๅy้ื”iำฅ๏3ฯ™อธำfอž#O๕J่ธำฆอ˜)ฝ๛<#ัœ7 ค; TWซ๚น�ปOw๏“ำD d้47่งฯ“”ฎˆ่~ถj[�สห?Zื฿๘ท฿rช3�b*ชฟห—.๒ชP๎u*"žtชุ้เ�S๚๊†ฦuzฉ2ๅMเูํvXง-tบr๎๎Tฅ๓์ ]1ีพ7ฯdั๕ะvงd1’๏—ณgL๕บฎื.ผ็ฯ_เT!�l>‹�๏‹��ัผท�ม…hd›๎}žRํ@ณถ/ะ็ยฅ—]๊5��`N๗}๖y™2ušทœŽธืฌVM.[กrภpค฿ปt๛๘>๏฿p๎‰ฟO$๙฿ บ< € € ^"ฆ—3อq"€ €ฉT€ b*=1AšuใMฝช†๚SFฝ9ิ[๒ัซํh%Eญ†ฆ•+๔ๆ‘ร‡ส'ุhWH�ฑcป้Vึ[™b$ aธ1#‡{•S’ฺฌ]UE—ำŠ@ิ Ÿ�ƒVŠ9jTข๊B๎r/ฝ๘ผTช˜ะ]์+ฏพ.ฺๅข]ahฯ/{ค\ฅ„*_๎:๖๗c฿'ฏ ่ฮ2ฏv5E�XG&w�‘ะ-ค๐ู@ ฿l\ทFฮ9็ฏ๒า 'ˆUส dนƒ†�Š-"/<๗ฌ™dW2s—ฑ_C ึุห‡ๆqC.บ@Up–-^hบึผ+TIŸฺ๛‹d<๛Œ๔๑p}์ ขตM=vํ†|ย๛ใ ƒvหฌU~ vต!ŸRี€�๋O๗กีค๖�”ฯ{M^/่t่ะ!น๛พRบˆฯ0cฺdน&o^Ÿi๚F+‹{๗]ัŠญข6gึtเฑ+|พึ�%)[ฆŒY%PๅิHฏƒถญ[yU�ยฉl๘XทGฅaƒGL{&;!Œgœ0FคCJํJ›กดqูฒๅานkwณh4ฯK{_n/œ ข๊ 7Œ๎ฝiทีๅy้—�Uธ;อพ.6mX+gŸu–ธแฤhฮ‰๛ีvzฮฺUํ.๏�'_WŸมํšy�W_K�‡6๓\/;<ฏีว‹-*ฎญ}๚l0ศ SjURํ&ุ�พaฏํUํn5ฤชaV์{๓L/œ'นsๅ2m๒ฏbk&F๙'š๏—ตj<(๚น๋?่9ะ 2t่pS�ฺ~ค๏ต2คVˆิม?๎6S:ˆ8eาน�บ„ช…กดM+นjEW์ bปd๕š}6๑๚ซ/K™า ี=�ฃ]8า๏]>;โ  € € €€AD� € €œn‚ˆง[<๚�u๎๚˜dฬ˜Qดบฤเฏztง๋ส:_‡๕๋ึส‡ซWš๑{K””bw�eฦ?�ไ#ง‹ทEfœ?ฤRเํ1ฃคPก�อ&�rบ_ฝjตl฿ฑS:]†๋PณFuษ๗o7mš6 ฃุƒ†;w๊(w+&็—ะก=๙Jงา_็ฤ•�Š9]‘5�,๊†์€P ็ฃ๙๑�๎‚0ะqุmŽลธ[iH+>ฝ๓nYณr™dห–อ�ดVีป๖šผ๒Pฝ„๊‚ 7‘-[ถz๓�GB ึุ๋„ๆqCั„\์�‡2‹}F๚ƒxธ>vัฟRงซD T๕O—ัะหฌำ$gฮ‹๕ญ�ฎ๛>ฏๅห—•�/%๎ช1ะถt9ํถม#๛ดี]_ซEีจ]7`ว1ฃFHั"…อขฺตๅ๚u๋Mล1 ๅ9rT๎บ็>w3�kคื]ar่ฐแ๒ๆˆ„*ค�†ƒŒุขไ*‘ู„79ฅƒˆvีYญ4ปาy>'5|ๅฑ6l�h‰ๆyi๏ร ็…Dิ๕7oX'g•ูl*œฎUรฝ7ํถบใก—ะฝq e4h\ฎlYฉไlฯฎ’ฌ‚งถS๏54„ผvํzyฒวcๆ�์ูsฅgฏงอธ�'า๋ ๆƒีฅO๏^fSv;{�ฦํ.U�๘ใOนทไ� išD ๊Hj#ฺต•V-››E::฿V8^�C๋–-ค}ป6frธ�HG๓ผด�แ†๓ย "บ]ใ๊ถ‚Ÿฝw<�{ำ]ฯ~ ๅy้WธAฤhฮษด)สฟืšฆบ]�ฺํถซ๛š�j~บ| ใGื™ฐVRฯ่PŸ—๖ตcท/ฉq ภj๗พ�Cj"j[ืญYe�Eธ•;๕ซฯZ�j™ๆ๕วuูv�ฎ4vtBp:Pu็NฺI‹ๆอฬ–�ฟหธ›๖>ฑร๓v[w๛ัพฦ๒๛ฅt๏ผ๋NฉRฉข”ธ๏^SmZ�๗็Ÿส=%"~�วจํ]4ฎ™dWัด— u� "jธตpฑ„P๊บก<ป40ฉมIยํR› bจg‚ๅ@@@ำ+@๑๔zณ7@@?‚ˆ~ ฉ�ญ5ˆจร๑ใวd่เ�*ฆ4mัZ.ธเ3OƒWใ฿yK~�ํ7๓^�ดnืม๙q4ซy�ฮุั>๓ผ…A ;<ฅ�ณiu4{ะ8AEท‚SrAD{�Eฮz—\z‰™(ธฅ3๔‡v�ม]‡Nี"ท๒bฐ@ƒŽT11ฉ ข�๋ขลKค�c=ฬ~S๊v:x๐ษ‘#ปh—ฝใ฿๛@ดซZญ—ูฉฆ]~n��ฑ4uยhI ก�8mฏo‡์ฎGํe์๑Hร`๖6ยล>ํ�Iš6idv�ี้๎~๑’%!5#\;ˆ8u๚t้ำ๗9Ÿ�ุืr ๏ถmœn„ฎ„uุ๛๋ฏฒ~�ฉVตŠyฟ{๗nฉU็ก ีจ์JMf็ORกดหห…�~ถhศๅ'ฌa—ไฮ%๕๊ึ1“ดบay'๔ส`‡jฆฯœ%O๗๎pตUห—š๋]ƒ=?�ผ[๒ไษc– ึ uคื�•f8วกฯตล‹ๆ› •ฺฐ`ฯง€็7ัฎส,œ้ทŠ๗6” b๙reค�ห/™u‚=ฝ ๚D๓ผด7ๅ๖พ๚๚ำ-ญ=/ฉ๑งž|ยนฮช๊๕m€hๅฎP†p๏อ@� ๅy้WธAฤhฮษฐกƒๅžโลM“5”ซแ\{ะ น=Ÿx�L๒�œrซ๙้L�ฃ`L*ˆ๊๓R�จm gVEฮญLจ�  LnZmู�G:ใฦฟ+ZEึpปfท"ขng๒ฤไ†๋�ัOr•‰ํ��z๋อNีลฑfา๗?|/ีชืฒg›q ถiภMฏห้`…ํgm(Aฤ@Ÿ9fGI�ฑƒ”K—.ญ`ห!ฅพ_ฺืบถื�^ˆๆึธJฒdษ"'Ož”ฺu’;ฟhsv๎`�'ุ†Cyvูฯึ7†พ)รGŽ ถนDำcD ๕9’h็ฮ„ำ&หนgŸใอjืฑSฤฮ�FA@@า€Aฤ4p9@@ ž"ฆพณ—)c&9๙ฯษ€ ำpIžซ*พ�๚๋^ำUœป`ัbwส}%K™ท�ี/ป์2ฉ๗pCSฉ๎ศ‘ร2|่w5^ˆ™€]g฿��Rชt9Ÿm�]%๋ � ข� �ห/{จฆNž ื��ฅs๗Oศย…‹}ถญo4ดb๙ฦณg๖�_/™=gž=ษŒGฌฑ๘ืเo+ง�=ท SwGฺžŠNEว)ำฆป“"~ีmญYต�๋v]74d่0 sป๚t7>๚ญฑฆ‹A๗} ืP~œถืณฌ฿ฒๅ3iะธฉ=;ัxคaฐD cB,๖iwaฉ]4j,”!\;ˆจU๔*Tชโs��ี=๛๔}VฆNŸแ5Cƒ„C฿$™2e2ี>�w่,kึฎ•๗฿'oบั,ทbี*ุ้้Qo{$œ ข�Hชส•ธะ�ุA ํช๔<'ˆแvใhทร๎ftๆฌ9๒ฟง{�ณฝ๑งž์แ�‰฿~๗Tฏธซืhฎ7๔จ๛ัฎ™ต‹f�กzตชN@uฉฯ๙zฌ{WัkG †ถk฿1Q5X �}W๑$ป|ฎUณ†๔๎๕”ูŽžำถํบj5’๙JQฯว�93ๅ�sฯ5[ณซชู›ื็อ=๗—…‹� โF๓ผดทํv๙ซแ้2ๅ*๘8ฺห๙—.}ฟ x5ก t86แ�›�๛ี๗กย›�ยsฯJี*•ฬ๛๚ฝ,>sปป่ค‚ˆแr$ัฒ_๋/๗฿_สLื๛Cฏ…p†”"ฺกฎ?�D;•ก |ึ๏๊n8M๏นฅ‹˜เš.฿้ัnฒ|๙ oUป:ฌๅ>ป๚�็;T9็๓ฤิ}ฦด)^ทๆม‚ˆั�'v•่~/๗ ไฦrˆ๖๛eม‚7ษ็Ÿ‘จI๊พzๅ2๓yช3cูฅด]ต8XฐVCบฟ์๙ลป5ะ™`W%vฟ๗Z.ะดPž]vZ�กK๕šตe฿พ}‰6งืาUW^)z,๎‹ b8ฯwฟ๎ซ๛�u฿‡[ัั]W@@@ ญ DLkg”ใA@โL€ b๊:aท�^ุ o•‘ฝ{๗ศ–O>–๘A๚Sฎผ2�Wช”ำอlBE8m๕๔)“ไ�ow๚@งGป{?ฆm�l‹,]ดPr;ีSj:ฦณฯ>�,ปy๓FYนlฉฯzผA VnwŽบ= Cอq€”๊ีHิฝซQ+ ๅน๊Jงปแฆ[ั๏๘Qฎธโr)y฿}^ต7�nนŠ•uณฌำuฐC ๚^TฝฏTiM4DฌัJ„eห”1�ี.๓�qช+m�ฐIN8ใ๙๓฿ >"2 ท+ฝD �wย4'Œ้VyิI5jี1?^�?v๋๔@แ" _hew่๑x7qƒ!�๏แTX=แฮ ุฅซฮดฯํ’ฅKeS…O:ฌ[ฟั็‡๋hย`fƒ�‰ล>ํkโ๘๑ใ2อ n�๖•s*ะ�ํT5 €u›ŽDิ๕w~๛ญz{ำœ‡ฦHั"…อf๗๎�+e+$tฎ๔zš<แ}ษ™๓b3�ญฑ๏ศ๋™q=Ÿ'ผ'็gMจ|ฌข^8Aฤ'๏.ืศl�‚…๒๘=อธ�ŸกC‰Vžำมฎฎจกœบujษฆอ›e�‚E๒อ๖ํ’5หyRดXฉ_ฏž้ยTืy๎…~2qาdM4ุwๆ !CEซ˜ขน๔X๕˜�aแขล2w�sm_›7ฏhP๐–[nNิ}ฅž—yณgx๗˜>wฆฯ˜!_}�ตœ~6)๊tZถl๙u๏ฏ>!!w?๎ซv-?}๊D๏s�›ํ;džณ�ฟ�๚ห„U์๋Oซฎ]vูๅ๎ชRซึƒRชD ๓^ซn�๔‘7o�W�ผgฆXิ็ึคษSdี๊5Nฅห?LตI}VT(Wึ‹สฑ๏p+ศz qF�๗ถ�|sA3I+ฮiH|��}&Tป�9�ฏฟูn/๎3พฤฉ<™+gNณl๕uผŠp> xฮฝฉซG๒ผt1แVDิ�EzN�ฏ; ฝ๗�ษ1ƒ4mิP บ]7ožำๅ+๚†›7m";u๐ๆ๒†๓๖J™2๗หƒT3ำ๕ORAD๛š๗y้ํ ฬ‘๎]ปHฃ† ฬZฟ:Uฟ'Ož*ปv๏ฝ–๗๏;เ’า…ิ่–›o๖๖rซs�ถl‘ะMฑ๋ๅฮิ็ญ^“ัTDิ`�ผนณไ‚9ฬf๕ู�ึ[oหท฿'ูฒf3฿ *9]็ฟแz'`๎[ WซWjKŽ=*C�ๆะ�g‡จต๛ษ“ฆšฯ‰vm[;�ํPEQท,ˆจ๓ยฝOt๔˜5`|ฮ9็˜v—.zภ8a ก�ต�ฮ๗Km฿ฺ5+อs|ฮ�yฒq๓G๒ซฟ้ฦฅrลŠRคH!ำญ&\ฑสก5&„ฅ๔ญ�*gฮœู,ฝํซฏ๏‰ใๅ็ฟํ.ฝ๔R)s��RฉbŸฯฬ@›ญ[งถ�ฏ็fึฉSงdอ‡kอ?|๙็ŸSฒๅณฯDปนw‡Hž]บฎXิฯฏทœˆ๑ษ–-fณฺ�{้าฅL๗อ฿;mท�@,‚ˆัtงูฏ”ฑฃG˜๑ํ้Œ#+ป2Xr� Dtป4 ถฎ�๗�หู?h๊ผษSงษ3ฯ>๏ฟ˜yo/่‡�คบfึ hข1#‡หUW]p๛:Qรฑ "๖้�Kj>X�์ห๎:ถIใ†ข•ฑ’ฺŸ�ตfแ 4˜hWBsณ+ุนำ�ื_zE��`‚๛Vข ƒy s$V๛ดซˆ๙7ม๎ำ^8>�AD�m้{ญด๙์s/๘Tิิ๋ญhั"f๑@ะ์ชYฺ•q๓Vญ}B บb8Aฤู3ฆz]!๗๎๓ŒL›1ำ์��]ัศ๎ฮิฎๆฟŽ๛>ฉ๊†๎2๎นี๗zOi83Pล&๏.ซ~ทนC'๙ ห/”‹/พ(hภสU๚ฌhฝ vะศห�ž7ม'kQŸQ�je>3�}cWฃณ็kUษสU๎ฎ�ธj•ลP† 'ษ๓/พไ-jwo๋M 0’ADญ๛rฟ์Mฤฟ๛`�…บt๎(อš46“'M™j๎�eฝ็�ิ๕#y^บ๋DDิ}FrNt=ป›v}๏?hpIรสฺญบ=h8หฎภgฯำ{ฬ O%Dิu"}^ฺ๛ g\?wgMŸ๊U๕ดืี`b™rํIๆณQ?#C�๎ยฃ "๊~ด›โ>O๗ ุFป�฿g449๑�๑>มA{yืะeํ:๕U‹ดa�ุ๋๏“ "†{Ÿธ�ตฏAํ\ป O‰!า๏—n1น6๊�<นu’›฿ถu+i�ช…O5k�u์๐พ�<๗�๔ฉ“ไฺkฎq฿zฏ��๎sศ[ ‰๛ปž�฿๚†ื๕wฐี�?ฏํ๋ฎu›๖‰‚ภvทเI�#ขHŸ#�ว่ณ9ุฑ0@@Hหำ๒ูๅุ@@8 ˆ˜บNาีyฏ‘j<(g�[ฝะฟu'Nœ•ห—ส–O?๑Ÿๅฝ/Tธจ�Wข”dสœษ›ฆ?D��๛o2nlเ R�‚Œ ญ๊SปVM/ศ ›ิn8gอžใT|;fช้5Yง^}Ÿ๊Wv๎$ห—“ห.ฟ,Q+ด๛Z ำ ~chขy�์&๋7hฐ;>]ว๎^9Pww๚ำ๐ŸO๔|Jๆฮ[`ฦ��hืฑี Rnwง๎|ญ*3g๎\ัn c1h—ฐฯ>ำวlJป๊ี.{uะJxsjl:ธA ๓ฦ๚ณaํ๊Dํณf๛Œถ๋ะIVฏ๙ะgš๛ฆyณฆฆ‚ฯ%N…ฅ9ฒป“ล?ค6zไ›RฌhQs�๏บ็>o9wd�œrลๅW˜J€ึฌใNŽ๊5V๛ิ0H‡๖m๖–�นr{U๎N:+VฉๆU– ิุP}์ ขVฏซ้Tฺs+๊vตาd฿็ž๗ฉภจ5$็ฮื.uylw‘ฉU+[ตigึq�hxMCl๖0p๐2zฬ[๖$3๎v๛ญกพาNภ'X๘ฯพ>,w฿[าฌฏมศฦ š๎a3fฬ่ณ} ;i•ฤ�ฏฝtป๎ vุAฏMฝFƒ ฑธ๊ีญํผZหE^่ณ w._ฑย„๚YhHู๊พ}ไถ[o๑ฎwฺต๕ไฉSๅกoบ“‚พjxEปหฬใTH<๋ฌ„jZ�w์šต๋y๋Œ1ฬT๎๓&$1bWฮtำ@_3ง*^๖์ู�I�๋๗?|/+VฌrฮอoZฌž—บAํŽ๔แ‡’BN๗ดY ž2d0๛ัฯˆงz๎ข[ฐ+jทฝek2P๗ฝfc~Bฝ7uตHž—ืญ1แ์Pป�eน�ใฎฅ[นN+€j%P{๗œธ๋๊}ึฃ{wŸgฒฮำk๔น^rบ_โ.๊๓ชฯ”Ÿฮgฝ�ศ ACคE‹ฆ!=ฃฃy^๚4&Œ7Z9ดiำ†RชdIษ‘=ปWA๔วŸ~’*ี๔ู’’๓™เอ–-ŸIƒฦMeฬจฆ*ญ�ตฒ[yx๋ึฯๅแ† aุมƒ^7›ตriญ:��›บimใ3}z9aแ[ผ๖นปแ5��Yฑbฅน?‚]๓ฏพ๒’”s*ฏบƒฎ๓ษ'Nu๔ๅหๅฑnšษI}—ัยนO��,^8ฯ๙ฌฬ%บฟz๕๑๙^็.ซืHฟ_๐š๓ผน�็Zw�คือ๐#eๆฌ9๎ค˜พ+RDz๖์!ZYะะj†ฏ9Aaปชก�2๚^ฏ‹'Ÿ่แ\—…œJธ—yฯLญh๛์๓/zซD๒์rWึ}๔tพฯVpพ‡ปี7�y๚@ฏ�ูNEIปw๛�jะธ‰lูฒี]ลผบ฿G’๛‘>G�็ฎปำคพ๓ปห๐Š € €ค‚ˆ้แ,sŒ € €@* ˆ˜:OฮN๘แ๊ซฏ‘^ ™3e’฿๛]พ๛v‡ำอ์มฌ�8ธ้&g�฿d�_ศษN†ผ. "ญ€� Yฐ`Aงk๐\ฒc๛Nำ�aจ�ิ0�ˆŸ;wN9v์/งป๏C�aปt้๛eภซฏ˜]iŸต๋&t+๊พฃYN�|ฝำ_ฦLœnี ๋˜ฃู/๋ฦŸ€Dt8/X๐&นๆšผ๒ตำ}ฃ^ปiiะ็ม๕NWคนs็2Ÿi ิ็Bฐ@�ฑO�เ=)เtwฎƒ]ลษนXฟืpฤM7 .ศแ„>wห7N7ฉกถY+LiํGŽ“�ฮ๑ฆึsชฯ�๙ HถlYeำ5๏?�˜dุ6ึฦแnฏsว๖&,ฅ๋๋~<�mฆถๅ#='พ้ฆN7๒�8�ฯC>ท;ะ+ฏผ"M>{Rรน5ฯ๖ผWหกรGยzh๘๗r็f�๔ำฎdƒj๎q๊ตฃ฿ฝ48ถqรฦŸW๎๚แพ>PญŠ<๗L_ณš๙�๗t๐ qธ�ถ|4฿/๕นฌAพ œ�พ๚ใภN๗๎?†�ล{ฐ๖„:]�ฟ@~sN๗�พ_ถ๏�๒=๊>bตœ~ŸอŸ�:qN—ํฟ„๕yซ6ฐ@@@ศ"Fnวš € €1 ˆD6ฉF`‚ำญแ ˜๖ผ๒๊๋2n�ปฉฆm4W Pัวซฏ@ู2eไต� � �ๆ„๒K—ซเป๏าภโs%gฮœ๒แฺuIVวLw00งY@ป’ j'p}Tช>P#ู๊ถงนy์@@@t)@1]žv@H=Sฯน % ™@ี*•$๏ีyฅœำ•้5y๓šhืถๅ+VI๑j@‘ต˜ตาปAฤคฏญ์ฆีMต‹ใ๛๎ฝว๋V|๘ศQ!umœ๔ึ™‹ € € € €คM‚ˆi๓ผrT € €@�DŒ›SEC@ ˆภ’E นšย@IDAT๓%—SหดKยพฯ<'ำfฬt'๑Š@ช ˆ˜๔้จ�P=yฒวc> }นm›4k�Špฑ o@@@@@�"�gม € €ภ ˆxะู%ฤT`๖Œฉrๅ•Wส๑ใวๅห/ทษไiำd๖์น1�C –u๏*ิHN:%ต๋>$;v~หอว�ถชWซ*}๛=4@@@@@@HV€ bฒD,€ € ’SR—m#€ €@zhฺค‘tl฿ฮzร&อไ๓ฯฟH 3„)0แ�๑r�uืษ—_n“G5 smG@@@๔.@1ฝ_? € p†"žแภ๎@ � TญZYฉ_฿8๔๎ำWพ�f{LMชWWyธžูf—GปหŽ฿ฦt๛l pF&Yณž๏๓>—็^่ฮชqณlึ๓ฮ“๙sgKŽูe฿��Rชtน€m็� ศีฤ‹.บศฌ�ุ19|ไHฒ�r—฿ทo_ฒห†ปภีyฎ–~/>gV› ๅิืด)“ฬข_}�ิฉ—Pi6ุบ5ช? }๛ธlูАชัฆ๔ณKCฯ๗—,้{(Nๅ=;œจw�aแข%Aซ๏†๛ๆฟํด๚>š bฉR%eะ๋ �€hห–ญา q“ดสฤq!€ € € €@Œ"ฦ”อ!€ €„'@1<ฏำฑดD|ฝ�K!๏๒–[o—ฒๅ+˜ๅ�u\>๙่#)\คจœuึYB1dFD ี DL�ฅt˜'๙„พDz "†.ŸKNš๐พไฟแzำxํz๚๓ฯฟz ƒาD•ท์ฐS‡Ž]ไŽ;ŠJฑbEๅ๚๋ฎ3!ๅ฿~'๖Yวgƒผy๊ษ'DปIี๖MŸ1S5l ท�rณœ{ฮ9๒�w฿ษ†›ไล—^๑ู๒ีyฎ–�ฝzši[ถn•N› UซV–šีซ›YŠz๓,{Z† ฅH‘Bfพ†j>�๔SŸอฌZณF�๛Žฯ4๗Mว๖ํคXั"’/฿ต’-[6ูปwฏ|ณc‡ 1Jด›็@ƒvล�ฒes)[๚~ษ;ทœ{๎นฆK��ฟ๏“Oทl‘ 'หฦอ›ฝUํใิ‰ท฿~›dฮœูฬ฿ด้ฟๅtย/ฟ์‘žฝบŽ5 ฤเOญJ•ส•ไ”๓ฟž�{ฺ๏�ฅJ™kโ‚9d�ฒfอZ้�ฺ๋^—ยฅc+Yโ>)\่6ษ•3ทœw^9rไจ|๗�๗๒๕7฿˜sฌ๛แ‚ฮu�ฆuหD-฿ถํ+ั*tI jีฎm+)t�m’3WNใค๛�ณwltฎก‘ฃวญ ชฎMœ๋๎บ๋๒ษW\!'Ožฝึืญ[/ฏ tท๔�?{gีั…แƒC)ฺ-.ฅฅEŠSŠ…@pwwง—R�‚Cww^œ๒—–าโ-๎R�9ณฬํ��ป›�อ’์&฿๔y๖Žฯ�w๎ฬ]บ_ฮaWว™2fขคI“ศz=ฆkืฏำ~๑์ุ›3? ๖…HหฤฬฑX๑’6วแW๗ๆ”IO{&๓ยฒOxปŠsˆร’ๅห)�ผT @>J›&-1Ÿ฿ฮ�NมsๆY#l!ฒxฑขฒ�ฎZฐpฑŒ๋?ุ*!๏;[ถmงeหW่‹Šฯ˜>… ( �Tญ^Sžี)R$งฌYณสผวi๛ัจฎฬ•}ยmนOq ‹ƒ"Ÿ]?o�ถCuฏ]รฒ&Z'"โสูฅo๏ฌัูw˜zf๏��[ผหพ–๏0�Sย�s‚„ ฉaฝบ”โณt๓ฦM`ศŠ-Lvุ๊พฮ’…2คO'ฯƒkืฎั™฿~ง‘ฃวj็•�พTœญ”ๆษ“Gถใ๗ย“'ๅู4‹ุโ e`หญYณeฅgOŸR็ฎ=,‹‰฿ํ�\]ปvฆ•ซ๛ไ g๖ฆึ.าฏ๏OTฃZU™3zฬ8šฟp‘ฎิ8สฯSๅŠตยSโ�g๏ฬา*"       i@ˆi–7   �IBDฯ[7W…ˆFw!ขไ€๋B„KtC<โ„๏ [‹M,{>&„มฑ…UR\”ซ`ฯq๋VSš4i,ซS!�ณwฏU�ยyมRศgU`มฟลK–j%zฑ‹ฃ”hIซ "l5ตYหึ6ลv๚บŽฤืฌZN3dU_พ|Iq„ั2ฐ๘ฃu�všHŠE›7ฌ“โnใใ๋ง•้�.]ผ@ Q8ฏW๏Ÿhำๆญf‚.}]ฃ๘๖;ฉk๗žfE,x+,ะ~™๙ ณ|•`>,^3Qญ_ป’ธฝญpเะ!j�ฎƒV\ดpašแ† H•*–ื๎_Eๆ/XHฃวŽWIํ–5แNยrvi“๕L๑8bัูw˜๊_?ฆญ๘ซืฏฉ˜pซญด\]์฿ื๐�ลๅ,z๏าญ8q’“Zเ๗สิษ“„๐>“–ง๐Xcฤบ,YบLŸM๊๛ฏ๓ๆฬ“฿ฌŒปwlฃO>I*…“ฅห�'�sๆ>๕{ำj‘ัดI#๊�ั_ํ�ตหPiูŽ—,�Uแ๘๑“ิด…ต\•ใ        ๙@ˆ๙ึw   ^EBDฯ[.ฝ๑ูณง;vโBู*หืi๋ๆOBD‡Qก"8D`bภ8๒ยผWฯ�๙—อvl‘m�œYฒ|๓–ญิ๓วŸดบ,”b+mr~›]ณphKˆศย1%คHŸ>=ศŸOถ=แYZั[ตz-�~๖ฌ,็Kกห‹/hื๎=๔โๅ !œ*Iว/๋๎ูท:๘wึฺ…%ข"r?ทo฿กฝขถ&้Wฒ„&cห„ใ&jCM›:‰Xธฤaฤจ1ดh๑ญŒ#leq๕สๅ2…',Vไภะ|}}DŒค5:%ฎ{�๘ฑ*n‘๙๊ƒญZZ&ำปำ}��9m�พƒ� ึ&‡ดXศmYŒXณv]iaM๕ีฎmkjำส$๒`ัฬ1ั๗Ÿ็�VใQa2GŽ์าB\๋6ํUiEซEณฆZบ|๙rฺ,]fบ7UศBฤ™ยb˜;ƒ^`ฅ๚eq[(|๙๊ฅy&O–LZbด"^ธxQบพq๓&}$‚~%JะgŸ&ปฑ%šdAaฃ† ีPšH+4ก�์ภ”๗ฝ•<ถLy\Œ. ‹Ÿ|๒ }W ฟtฟห–พfi}sคTฉ’4fไึJูZฺqฑ.‰็ผl™าฤV 9l–๗๔VJ9๏๐ม}š๐๑/a ๓ิ/ง้Ÿ�กTŸงค"E SขD ษžฑ}ป6ิบe ๎JZ๊์ัหdแSf|ธบ7Y,/žษ"b~qdg‡C‡ำ•หWdœ?๘ปƒ�๒hX๖‰‘‘ฯ ถ`วVYะว๗AI!žี‹ศุZ C9p�j5kหruฏZฑ”’&1Yž ˜8™fอ –๕\�hXฟu๏ึE66b”˜้-r‹ยY~p_ˆ<“,…โ\ว•}ยํ๘๙+ZธG)uช””;w.ท%D หšpวฎž]rRบ% sTˆ่์;L๕ฯC๒๛)ูงษ่ำO?ัf๐‡87“$N$ญสr&๏ถvหล„๋Vฏิ๖&ฟOv ๋š�|–ZSฟ—^฿‘ห–�O๐ฯmวŒ!฿s็{�ฑs'ลˆ2 ๗้j฿ฐฑ|ลสfึU]"บบ7y~–ล—l…™รEaIธrU“ภึฒž> !ขžโ       5 @ˆ5ืw    CBDY m"z!ข–ฉ‹ฐPdรš5tๅส%]ฎqBDc.ศW 4oฺ„:๚� ›6ยฎ ัfMK7’\Y bŒฦ�ก][j%\๛rฐ%DิทcืฑS'›ฤ{ณfฯก€IS๔ลVqฝุ้ีซWิธY )&ใŠ9rdฃsƒevฏZธXq๋‡^ˆx๋ๆ-ช#,฿)ืฝzAำCแ&ตˆฏ6œ™E9! ซ[�?Wbw  ๊ื•๕ู‚s5 J๔ย๎”55ฑ5ชวyujืข�ฝLฎ7๏�ฝKอ[ด1s=p@?ชZน’lพo�j฿แ?‹y์†ณHแBฒฬHDล.Dใ 7ฦ–Vบdƒ๗ฬŸืแ�ปw๔mn“ภT_๎๎ธฅภ*DXเ�๑ว>fย1ถจต{wˆk๑๘,ฎูเ กลC�Z๛ 7ภ!!{์N๙ฤัŸฅ54!โ�=ป)aยฒ/#ั/‹t~��w3๑W�ผq-ฅJi๙ZŠฟXฐดr๙)hb�๕6ึ๖B>แถuVะ 9ž^ไ*3�๐ณห8m…พ?�จY˜d้ไฉำlU•๙๎ุ›ผ6lษ‘ ^YŒ่hpfŸ่๗-๗?mฦLš6}ฆ6ิ’E ่›ฏณศดegฮšIy๓ไ–ๅปvํฆN]ปSะฬi”?Ÿ้™ท�[ฒข ๚๓Q ๗†์$v;ฎB฿~„ m:ฐWf13ฝX˜3]ู'ชuๅ{ใ{ไ`๙,ช:–Wgึ$,g—ญq"๊�;๒S๗ล"ฤฺuH๑8 D9ฐภนJตšย}๖7ดxม<™ง†ฦŒ.ž&ั๙ฑใ'„`พ“ูyฅcN˜Dณƒ็ส>Xธพbูbkœ์šฝcงฎาBฆ,๊์ๅ๔๊ต๋จ�€Aชศe‹ˆZ"–ฝษ�ฐตKถธหมึ™$ u"๊`       Q”„ˆQtแq�    เ) D๔”•๘oJˆศึŸk^oฤง >N@ &ิ*ฝbขฉ“ค5-ำ !ขd@่…{kึญง~�ส�ุ]๐งŸ~J—„ีขๆ-�ศผฑฃGJ๋œจZฝฆ™%=Yแ�‡#"}}ฝะฦY!โบ๕ฉOฟ�๚๎คEฒ/2™�Vๆศ•ืฌฬี„^œf$ะ[น|ฉfแฑ��Rไฆฦฺน}‹ฐ–๕ฉLZrณWฆฺ๓U‰^"๊ล(�z๔คm�w๊ป’ึธถl\/ล,–bอเYšลณะ„ฉf๊j�ˆ"ฺฒbจ›^จัๆยบcว&‹ฃวŒฃ๙ ูmใจQีใฮ”;ป‹B��` klมา2 <*V(/ณ๕ข%ฝh์๖ญ�ไWึTวฒฝฝด�๚‹�๔.Šฺ้…ˆฎ๎อฐˆœู'z!ข�ฝฑบ/ฝ%สำง�',G6UE๒สึW QปณๅpEXทL›6ญŒ3๏*โŒิ[Q”.|ฐ๕ผํ[L.ลูํ$แพ{ำ†ตf=ฑK๒+WŸ�–-_Aผ๕A/DtuŸ่Ÿฉ!DTgฯ�ูณKฏWฯย‡"*๋ภ�<„์4Y๗วYฺธ��วu}}ŽCˆhIi;ๅพ•]ทVซQ�ฬj‹ษŠ—,-…[6ฎฃ”)S’‘hG?‹๐"<”VฎZญ^ZWdป.Yบœ•ศรฌฒƒ ฝฑbๅ๊fน ฝ@c๐ะแฤย ๔โ,vอฬ.š9.ฑ' ืุ~�๕Œดf'Jฬโˆ1dืvอ5,[D|+�wrˆ-švM๑Y ็Ÿฅ4Fƒ๖ง*•*ส2vyฝcว.๚๙ศa:|ไจ•ฅ>ญ‹ˆE„10h6Mš2ีbFฦIถXตJe๑LNษ’'ฃ8ฑcหŠ,(Š3ฆŒOขฏ Yณ;xŸซ†กYD�ฐv•&Tc!ุ!*;r๔ธpE~ฬฆ`M/<โแุ 0ต–็ตTiฝ˜X/Œโz์v}วŽtDŒgฯข%ืUA/Dd๋jleอ^ะ?๋ฎ๎M�^ /‹ˆFnญ๙>O?"]ฃ�r๒93yโYGqแsงYหึฤ{ี]Aั'Ožข•ซWำA&ม8ฏ#ปJfw�โ90vดาH@ซ":ณO๔๗๐ก…ˆa9ป๔๓ไธ:3?ดqๅ๊54pะ9ผs�†๔S_“@^ๅ) …lีp๕สๅฺtีžๆ ตcฤŠฉ‰ืYเZกr5Y_oAื–Ubๅž›�3็อ_Pว[…ˆ|สU5ว๏‹KธCเห}!€€€€€€€xฝc0Kˆด D๔ฎฅ�๚›ฌTฆ\9้วOSะt๛ฝk}1[๏ 0'(๒ไษ%…{น๓}'�ขฒH…Sศ�}šต'ฝ…&UG O!ขฅ๕Ažว๘ฑฃจ„ฏษ=ฒ_™r ่๔๗`ื ฌ,ฒล&ถ�ฤมRไร"Š๋ืH‘ษ?��ยฮRฒ�ธ1#ฉd‰2š๕A%f Mˆ�ฃ4๗ฌฒใP>X,ศV๖XคฦE2‹ฮงธqใZตd‹|AAV-+Fคฑw฿~ดaƒษzœๅผ๔้‰ฦ‘Oฑข๚,ร๘ธ ฿Vœ�Ow์าM+6xUจPNKซ‹Lื จำfj"TUฆฟ๊]3[>ื๚z*ฎ"บบ7#Bˆจซ{แ๋พ]”(QBํlิ—ฉxฟพ?QjUU’fอ &ถš๊ฮ ,ฎฒ•ป�๛QํZ5คลปฅหVH4ปจŸ:muุ๊Akฤ^�,9บO,๏แC รzvYฮU™Zˆธd้2bQ 5ๆ !Ž$D๒Ž9Dฑcล"%Nิ[ฺ”B๙ะป0ึฟ�lนgืว์™ƒ^d๎ BDW\3‡‚ล       Q€„ˆQ`‘q‹    เษ D๔ไี1ž[ว.�ฅ5!ถ"4iยXใJ๏s!Dด‹… เฏ4kาXถe d7 v๑จ[ �ดu›fmkสิ้4#0H[]รSˆhd1M/ึ/!bปถญฉMซ–’ลผ๙ hฬธ f\fอคผyrหผN]ปำแŸ[�Š'={๖œพ+TฤฌพeB \B"๊ญเ๑™:>ภไฆำฒ?--Dp–ฎ‡YŒุัฟฑ่่ฃโiUU$d๏^๒๏ุE%ญฎ)Dl�ข5=~�jN๚ŒถmZQ�ึญด,ถ2๗‹pฝ{๏�=z๛ๆ-ๅห—W)N›>Sˆ๕fju"Ž นญO1jึธeห–Uณบจ๚dA" ุfฯUYคทPษV)๗๎�ฏ•E�๘ใœฐฒxิฌจ”_ jูข}๕efณ|Nฐ ฑU�๖6ญ๗ตoื†Zทl!�ูฒจ๏T/DtuoF„q๎ผ๙4v|€�Vd�๘‘Ÿ)–ฐNวมH€ฬ๙A3งษฝยq!{ฤ�่d{˜j9๗0n /๎Clๅ๎œXc~~x=ๆˆy/^0Ovv์๘ ํŒ1:๗๔BDG๖‰ั ?คัg—~ฮ๊ฬ�ะBDฝˆUษqู2.‡c‡RlamU +U,ฏYดda้ขลห๔ำถŠ?|๘€ุอ9‡IวSฑ"ฆwล:Iณeƒี+–RฆL™dถ�|hBDe’-4–.oฒŠkูwX๖&๗ล็฿ฤ๑ฆ๏๙/]ขสUkX4€€€€€€€X€ั 2@@@@ย“„ˆแI�=cu?ุณ{ๆ��—ฦ™� ฺ๊BD[dฎ(Zธ0MždฮฑภฐQƒ๚/^<ฺดy+•++�2 Wˆ๋ึm–y”&อ[ฺuํู…ˆz+SŠบ^ˆศ"D#๊[ฅc๋tXศw่ะa๚ฑgw™f ~lกฬ^P—ะ„ˆ�วฯ๖Iก+ห9ฐ�ืฒฅK‘Ÿ_Iอ�3ืฉ]ท•๕>ีึU!bฮœ฿R๊ิฉT7๔ไษS ูฃฅmE๔ซFM›�ีฉ๖K/ ฏณd‘I#wร๚ตtทQอญฟ๘ฎ•/[†Š),ฉ\๖๘๑c*Tดธช&E€,ไ03pMž:M+s6’"Er*\จU,_Ž˜u๔่ัe๖,œฒˆqฬจ‘ฒ^hฎงน’ท Y่ีงŸษ•ฎผู๗JˆhหฝฅจUต5:T™บZZชfฬ˜๔๖ํ[šฟ`5nิ@บ`gห…อ„ภฬึ�+X อ˜>E?uปBS#ท�J <'(๒ไษฅ๕๕ื๙๓TญFm-ญ"ฮ๎ีN ‹ัˆกพoŽป๓์Rฯ‚ง ๕.จ๙}[ฤวืƒอtซ–อ‰฿ฏVฏ]G,Fิv}ผnอ ๙ ��๛o*แWF+ึ[๎ิŸ1\Aู"†eo๒8์šžŸeJH+v>ึฏG ๊�๗ฮ;|์๕๋?ะN €€€€€€D6"Fถล�€€€€€—€ั๓,F๔๔๖฿ท†ซ^ณฅM—N–�ฝ{GX‰™cXOeBˆจHเ ๎%ฐ|้b3ืญขถํ:ศ=ฉDe<ข#๙œ"๊Eง…‹�›ฺฝ9wˆ์`Pจ"Z2H*•ฌิIe„[ห�ท๏X๕๒ำ=ฉvญšf๙F(ณ ๏สm&ปq.แWšž>{fTMๆ�๔c/1Žษๅ%ปn�ฌ…a]ถŠ๗๘ั#:แขVฮkq๋ึmร�W —Ÿ_ผw๙ูญg/แv‡ึNQnd9Ÿ!~– แ%D< Dท $SRb.5ฟbE‹าค€q*I๎"ฒฐญ Zฝ˜ห *ช๑gwต[6ฎ“ยI.ณๅŽ•๛(Tจ m�n.€ต5ฆฏoqอี๚ีซWฉ|ฅช�ฝaXถde๙๊KYVทA#ร{P �ฑ7Yxิฝ›ุ้M๕„ะ�‹ซมลี™}ข"r–ฯ๊ฐ!ƒฉB๙ฒฒwKซฅผ.ห—.ขdŸ~*หƒfำค)Sฅธ“EžXะUญfmm-eๆ๛g…ˆผW็อ™ฅuกัฒ…9ถ4งย๎�!ิฑK7•ิฎ%DtfMยrvi7๚>โฉBDžž^pษึsู‚ฆQ`WฦG…Kvu�๋E๛œWพbบw๏žึt@�พTญJe™�๙๐jีฆVฆž‡E,๚WA๏�ž1,{“วฺธ~ ฅIZ[ฑruบ|ๅฒš‚อk๗ฎฉกฐาฌ‚ณV$U;\A@@@@@@ผ—„ˆ�ปv˜9€€€D "zึ2~›37๙๘– ;wnำ้S'้ชฐผ๔ไษcแ~3ญฐใCษ“›ฌk๑ฌื‹P/^0ปิฉำP๊4&ซa\�ป‚าjปq>|่ V๗๊ีหt�ฺ5-€€s๚๖้M5ซ�gMY+j�บฑ๛Qๆฮ›Ocว›[.e๋{ŸžRUก๊ีซtq`‘ลัc'ดฒณœ5้)ท\‘]6ฒˆ‚�ิr๘๙๐Q3ฑ…;ฤNฒc'>๔BDnฒg/ญXฑŠ>NŸ:๛๛k–wํฺMบš\.[vฏ\ชฒ‰“งRะฌู*i๓บh�\ส–-ซ,��์Yi‘๑��{า�ๆ_งs�ฅตeQฺๆM๋ฅKฮผp๑"อ™3—.^พD โ' ฏ„จฌฌp �ี—™iีš54`เญ- dาฆIMป…Kไ=ย…๔ๅ+W)Uช”TฌHชXกผVฯฏL9รuไ �บtขF ศบl•‹9]ฟqุยแ�{่ะแรZ?๚Hx ๕ูJ�สUซ้ผ`˜7_j�ฌ)ลŽK›–‘‘ลŠ๚ „‹w๎�กมCGhEฏ„๕Puฏส ‹†6nฺLGŸ ปw๏า7_Mๅส”ั,ฺ�ธqCZ"ี:ฝฐ—._ฑ’ุ๒ฃวคUMถRWZธฮfw๊zฃฒฆศ๋ฟ^ธ��Mˆ Ÿ หรyrๅขjีชh‚ -[ทQ^ฝ๕Cšล๕โฃm�ถSทž?š•๋๎ุ›zW๑lu๕šตt๖์๔Bฬ�ฐ›,ƒ3k–ณหr\g„ˆฎผรT�ฮบfๆy๊-Krš๗๓๊5๋่ๆญ›”"E ษน‚pกžส}64„Vฎ^#๋้?\"v้ิ‘š4nจ๏ฦf�–๋egึ„;w๕์ฒœ˜ :โšู•w˜๊฿!"ฯตWnTฏnหi[ฅ-…ˆ… ค ใวPœ8qฌ๊ช ส๛w2YUy๚}ฌ๒ิ•฿E์bœƒ=!"—ปบ7๕โ� ผ๕w~๎฿2@ˆhIiˆz DŒzkŽ;"!ขG-ฅKŸ*VชBฑbว6œุ๋ืฏioศ.:�ห)ร๒ต๊P๑ฃ~hแฒฐ๔ตJ@\#ภ–ฏBvn“-�o฿ฒIŠหุiก">š›H5Rะฬiาย“J�ปฮ žGใ&Vakteห”ฆษ“SขD ต:� ขีkืiiถะศ–94h�„NŸ�U+ใ *YX้Œะฯฌƒ„"ฒkไต๋ึQ๊ี)V,“pƒซ_ึ^; ‘ฆ�อฑA7fBญ�Rป�ชๆฑฅ^ฝ:”Kธi?>E‹MึณJฉฦ,ˆ4 ฏ‰f—–dU>__ผxA‡ฅE —˜Yอ๊�ัŸส”๒ฃฯS~ฎฏ.ใ=&’ฒ ฺะ�ดiC๒)VŒ%LจUXฎewขFaฺิIฤ๗จ‚��ฌส3บ*๑›‘ๅ:ฃ๚œWณFu๒�กฝูsฦฯห‰“'i•q6T6e—ฉlีS…�นsQ๐ฌ@•ด{}๕๊ๅ-๐ฝVgโ„qbํršฉ ™หŒ™ดn�F•eue๗ปอ„Uณ„ Mnฅ๕ุล้ž=๛ฬ\ผฒ ๔วž=…๐5+ล6xŸ8q’&Lš,�ญ๋๛2Š๋�ŠฯšL'U“ึS�ฑ7๙<๚ก}[ส—7ทฐ —\Š yภทย"ข-ื็jBŽ๎ฝ‘น็อ“‹RฆLฉบ!ฐ-Zผุส์ฑร5ž�z๔ดr‡อT๎qูM.ฃ็˜…�,~ำฒภะVะ‹˜-]tฏ^นŒ2eฬ(›6jฺ�pM]ู'๚ณึึผT�้ำ�็qS•4ป:บ&ช‘+g—jซฎ‡๎“ฯ [ึ-Tดธส6ผบ๒;๚๓)d‹ถlู–ƒS๏nyŸ๘Žห๏ณeหWะa�YLๅ๚laฐgฯnšuRฮSลพ๛ข้3fส? P๙|�:K>l0eฬAŸMlA4XX-ž2uบYพJฐz๘ะ!fgะ�hขุฯ-Z4ฅT)SI บUชีTMฌฎฎ์Mถผjล2๙ฮบ}๛Ž3[ul#ฃ}ป6ิบe ญิู๗ฆึฏ%!ขื.&   ‘ƒ„ˆžนމ“$กt้2Pข$‰)fŒ๔ฯ฿�ะฅ‹็้แร‡ž9aฬ @t”๑้ณgา�-ฑธ&พpอ�ห/งอ,ข้šYE๕n5m‰˜ฌน!#kึo(C๚tB๕ŒnK—๖ฌ6๒plีล@ษ“*D‹ฏ„ะ๒rจm�0อp๏‚ai…ี�;w�ฆ#B˜E9Ÿ�9%๏รGยฅ*ปฟf!กฃื&หWY(x๖n ืชWฎ] ๕๙ใ๕O&�ผ~�q|บs๛ฎAŽถฆถu๓F)‚ผw�>๙๘†nุ้ัพ#ชž^ˆจ\ค๓3Ÿ=๛7tใๆ-bก&Bฤp๖์Š๘;?�_Yณfฅไ)’ัƒ๛่๊ี๋ , ฬ๖อ7๔ฑ8 �๎ๅC;ืีฬr 1{๊ิฉ่�็nฃฺบr4ฐฟๆ�นoฟดv�WบA(JBฤ(บ๐ธm๐"zสJ`  y ฝป’%Jะธ1&ทิ 1ถฏ_igป@}ˆ0l‘ัฟC{9~�FM่ฬ™฿"l.๎ุHˆ่Ž~ั€€9 kW แcjแ�ช[฿1W฿ๆ=        • @ˆ•W๗   @BDXL@"W…ˆฉSฅ"_฿โ๔ญp\คp!Š7ฎ$3#0ศฆ๛ฬH†ทIBD\L @@@@@@@@ฬ@ˆh† ๐&!bxวx  ๙ ธ*Dฌ[ง6�ุณป ฿ฯžฅfอ[ปyFˆ"F wŒ         ฮ€ัZจ     เv"บ):(O`๑‚y๔๕ืY่Ÿ{๗จ„_‡yTฎX่'๋฿ผu“Nž๘…†ขรQ> bE‹Rภ๘1ฒ๓QcฦัขลK>ฬ@่@@@@@@@@@ภe"บŒ A@@@�ABDwPD              q DŒ8๖@@@@@€€€€€€€€€€€€€€x7ฝ{�0{๐z"z�โ@@@@@@@@@@@@@ข8ฃ๘€�ˆ&!bDฏฦฐ€1l�ะ@@@@ Œ D #@4&!b/†จNBฤจ�เ�A@@@@@@@@@@@@ผ„ˆ�พ‚˜?€€€x9ฝ|1}(OBฤ(�€€€D,#–?Fฐ€1ฌั@@@@ L D >4'!b„/&   Q›„ˆQ{�q๗             �OBD๏_C�€€€x5ฝz๙0y ๑€€€€D(#?0€1ฬั€€€€@X@ˆzž�6�GQŒ่1่ษ“วž=Qฬ@ภ+ |™๙ ;fคœ๛‚…‹i้ฒ^y�6้ๅKS�ธฑ้็Ÿาะแ#ž~ฺตจ”_IYwศšฟ`กŒ็ฬ๙-๙�ะ^ฦฏ]ฟN�๚tธฯะ*๖๏ื‡าฅM+ซMŸHGŽ•๑บuj“_ษ2ฎŸKh�E๖๒tiำQสฯ?“ทy่๐แPo7พxฯ•ๅ+J“*%L˜ฎ฿ผI็�บ@—ฏ\ตญe…คI“jY๗๎�ำโQ=โ์š0ฏฌYฟกTฉRRŠdษ้�ƒ๛t��E๚�์YงQbMŒ‘นฒ&ชงB าฟ��KWฏ]#>๏@@@@@@@@ ฒ€1ฒญ(๎@@@ผŒ„ˆžท`~ฅหา—_eฑ;ฑ{๗�กล ๆ™ีI0.๊C้ำgคุฑcS๔่ัe9�เ๚๊ๅ+๚๙ะ:yโ˜Y$@@ภU  ำงศๆมs็ำธ ฎveุŽล<…ฟ�^–-Xธˆž>{fX/ชež>i:วYิืขU[‡oศ TฉbyYหึmิฃWoฏZน ะOฦo฿บM~eMu๎ุNล๋VSš4id!รFะฒๅ&ฑ๊ะมฉbำ8›ทlฅž?�dง๏)J‘"9ตhึLrŽ/žœ๘ิi3h๚ฬ@ป7มkะฑcJš$‰V๏๕๋7t๐็Cิมฟณ–ง"๙๓ๅฃ๕๋า๗ฟ“๏{•ฏฎฟ�z†FGงN�ขฒ์^YŒ<+P๛�0kN0Lœlทท†ืšคbะๆอ›RI__J”(กž�ท๏ะไ)Siํ๚ VeFXk*ฮ๎ี v'ŒKyr็ข˜1cชlบ๛๗฿4rิhฺถ}ง–‡€€€€€€€x;ฝ}1๐r"z�ึจU‡าซH๖ยำ'Oiๆts‘@›๖�ค„ถฺ�ธqƒ–.šoซ๙  เ0-D์าฉ#5i�Pฮงu›๖ไˆ…8‡'๏ล!D๔ผลc mญZ6ฃาฅKQ์Xฑฬ&4›& šญPซf ๊�ซ‡&ดฌw๚๔�จu�๖fB�Q#†Q1–ฝ๐ๆอjึฒตCbฤี+—QฆŒต๎ๆอ_@cฦMะา� ๏5แu์ำปWจจXเษBฯะึฤœ+๛„{`b๐œY๔ี—™อ;|Ÿโ}าoภ@ฺฐqณa92A@@@@@@@ภ�@ˆ่m+†๙‚€€€@$#!ข็-จ^ˆxใ†ฑ�ธ;ยฒฮ๎�ฬ&฿ถ}GŠ/.๑ชทo�ค;wnำห/)}† ๔ู็)ตบG„…ฅ๛๗jiD@@ภ"บB-์m D ;Cw๗ฐeใ:J™๒ฟ๗ฌพ{BDIํูฝCณjx๘ศQฺนk7%n–[ตlAฑb™ฌทM›1“ฆMŸฉuซ„ˆฯŸ?งญ�wะoฟ�Nw๎�•bซF H๑Wพyใ&•._Qkgi�ฆตm�สฌ(2ร{M”‘ญP๏;ภจOัฅ+W(ูงŸHAuช”ฉ$cถtYญFmป๎ณฑ&fฃ|ž]ู'�Kn]ฅ๕PŽ๓~™)„มOŸ>ฅreJ[ไ๐ไษ๚พˆŒใ@@@@@@@ผ„ˆ�พ‚˜?€€€x9=o๕Bฤ๑cF:ธO๚•)'EŒ<‡iS'Qก‚อฆ3jฬXZฐpฑYžญฤถM่ณฯ?“ลํ~๐ง�B4lุชb฿Ÿ~”ู์๚๙ีหWิั�™vงkb"?r๘P*+�s˜<ฦL4่>ฑ&Su4�‹บบOZ ๗ๆํ�ต‘้฿7์’™Ÿสj(W๘็Ÿ{Tผdฉ�E @@@@@@@ผ”„ˆ^บp˜6€€€D"z�J๊…ˆฯž=ฅุฑใะฟย๚ืณงO…ลฅ๋ดu๓Fง'*ujชUงพl๗เมš4ร้>ะ@ ๊ะ[Vป๛๗฿ฤ๘โลGฅJ•คุฑbi@l _ผxA‡ฅซWฎัแ�ซฬ™ฉhั"#F ูv๔ุ๑4มBญŸ.: a–ษ"b��๙4ซn‡ฆ+—ฏh๕๘Ld๗ฆ๚ „ˆฮŽฉ๏รั8 4ƒfLsดบฌทo฿~ุ๊ฅ›SmŒ*[ ฯ�ฏ0ฦŒ@IDATqŽNžิธaŠ๛�ฅ๖๙ จju“๘GV ง�๓สC�~๖, >‚ิซGeJ—"vอ|„ZตigY…ฦŽI~%Kศ|%Š๛BDฌ‰ }ืฮฉq#ำYv_�1Hน๒•ฌฮEฌ‰ฑ1,๛dฬศแB4๏'๗๏!%ฎๆL๗V‚่คI’ศ:>%Jัฝ{๗d        เญ D๔ึ•รผA@@@ ’€ั๓R ูโ“ว้อ�ท”เใšg�๚ี+š:9@ZJ ํŠ๛–คœน๓ศjEA3Œ-ฮ„ึสAข๚Qีส•ไMฯšL'›˜;;ˆrๅส)๓,…ˆf ๗๏กใวง{๗๏“ฏI(bYอY!ขe{หด#cZถฑ•f €m�ดฒUl˜�ฟ_ฯะ’ฅห หœษิ 5mNงN�ข5g![ศฎํ'N™WฐPQ+ม“Vู๗ืฎmkb—ฑJhศ–รbฦ4Y{๗๎&FeกโสUซi’ฐฺงw์ภ0nซย๎Œ���ำืYฒศ>ูrฆ��๊[๑>Uึ8�8๗งxฆ'บ-๋„"ฒUMvหญZึชSO tYจห…S<฿มƒศtˆฐ ็/,ู้ z‘ฏAอZu5๑ฐjว"โ‰ใวสไž}๛จƒg�BD๎8ชฏ ฏ๓ฌ™ำต็ฮาR)3ยš รฒOfNง|y๓2b๊ิต;๛lๅ๒%า๚ลK—จrีคwฯ฿ฟฯ�๙—ฌ๐V"z๋สa�    I@ˆ่y ษn”Ÿ 7ฬ„@GRงNCUkิX2๛�giใ๚ต๚*V๑L_dฆŠ•ซJก 2ๆอ ข๛�Z5B€3ฆOั\�6h�„NŸ�ีŒ‹^ธd$Dd[ร๕){๖l”Y,ทyห6 ˜4‰n฿พฃฒ#๔ZกB9j�บฅ๏Sหpใฦ ้:Zน‰ถ,wGฺY!"‹"‡EณgHแไแ#Gฉe๋ถTนb‡…ˆ,f',*‘่a#hู๒Vทฃ\ณ ๓j5jkBE�~ž7็œลOซ,2ขโšฐ`y^๐liแ’qlูบz๔๊mA†kโ˜ัู}ข"v๋ั“ช ื๔l9—ฟ7kูšNœ8Iึฎขดiำส5ั๊ัD€€€€€€€€€ั  SศDBD๏ZอฏฟษJeสU“~�DX7œn�บแ็ŸNต„…ญAฑีช�ถะฏ�;ํ]7Œู‚Dี+—QฆŒๅ๘~eสY‰ฬXX4l๐ Yn)Ddืล#F •Vํ�ภร‡จˆฏag…ˆ๎ำp"–ฉ„ˆ�užชืฌm5;ฝ‹ื.�zJ—ฤV•\ศ`‘'ฏiฑ"EฬZณห์.]บG˜Dณษ่ลŠฅIใt9ฆ([F�ตkทUพ;3"ฒHmำำ�นs‡ุbqฆL™่๙๓็b]๋H`ร๚๕จ{7“D{ฎ™ูj�ดษฅฅ7พ ฒั2่]wฯ œE“งNำช|h!"•ึ„ลป๓ƒgQš4i$ใ3g~ฃบ iผUkาZขฐe1,๛D๏š™ฯ)!rXตfฐ8:DฦCvn#^+pอ,1เ@@@@@@@ภห @ˆ่ๅ ˆ้ƒ€€€€ท€ั๛Vฐฃ|ฐธ�cNš`rฏhyI’$ก›i–‘~>t€ุoY iฐI@o)สH Qฆt)5b˜lฏ"ฒ`m๛ถอš‘ล†ปBB่ึอ[๔ไษYฟฃ�;vlbซl๙ 6œƒ3BDwi8ƒLฎิฎYร ฤvึ�้œ"ฒฅCถxhฆ AZแB฿หl#7ฐ–๕Iทh�Œ7l@‰%4ฌฮ"บ๙ ั๔™&Wร†•ย)“�2wึ ไฯgsฤcวOะุ๑ˆลa"8"DไqีZ๊็ภ.ะู:v�อ–9อšM…�kห๐eๆ/hvP %L˜@ํุน“X€jX๘ศย.GฃWฏ_kีพศ‘R|–Bฆ��๛๚ใฯst๕สU6b”VวีHT[>‚็ฬขฏพฬ,‘]พr™๊ิmh(ึลšุ"2@W๗‰^ไฉž]�ฒKfๅ>�ุ‘C;V,๙:wพ๏T5\A@@@@@@@ภk @ˆ่ตK‡‰ƒ€€€@ไ !ข๗ญc‡N]ค{fv-0nดี ฤ�15m�’b ‘‡ำฟœข�ทZีC€ุ# w๑kไฒฒA�บิฃ[Wู…^ˆXตr%8 Ÿฬ?๗็_ิธI3M๔กฦ;v๘ […ˆ๎Sอ/ด+[_œ<ษ9ืตGŽฅญฺ†ึuจๅJ”รยฮR๏-ไ๊M›:‰ ,(ณŒ\j๋๋†ฏTฑ€€€€€€€x2=yu07ˆ D๔ผEŽ=ฝ�๗ญแฤชืฌCiำ™Dw๏�‘VwTE)6oีZ โหฌK/ะ๊•หU1ฎ  เ†๕๋Q๗n&แณฅฅ6ถtถeใ:Š๛^๔ฌ"6kา˜:u์ วฺณou๐๏l6ฎ^�fOˆจv๐\š`[๘็ฎ1อ&JBนธ ฅšV|��}+หZก%Dไ&,ด=fœึบB…r4l๐ ™fข_™rZ™+‘�๙๒Qฯ�„จoฆfEŒ๏›ญธq`!ขY๙๚—n„'L˜Hreธ0ทa ‚O?VGhฌ•`V yv�SXO�D<วํ;t ๓ธ–8*Dิ[}��9๙–,ญอปIใ†ฤ๎ษ9\ฝz•สWชช ร๛o�œ i้‘3ู๒c“ฆอตถZE'"อ›6!v™ฮa��4fœs?m Uึ„๏ยุัฤ๛€‹a[ถnk&,•N|`MLฐ\�'�zวถอ”2ผ‹@… ๅจ~�บrา� คs�ๅึจSปีฏW[๖ูฉs7:แขห�ว�่#ฺฒi%J”๎�ฟO>พ~.๗ๅ) yioฯ]@+Wญ�เSใ5)ๅWRŽณ;dอ_ฐPฦsๆ�–�h/ใืฎ_ง~�:=—คI“ส6�]แ้ณgNท7j0r๘P*?ŸUั๔™Aดd้2ซ|d€@D˜9}*ลŒ“�พ}K:wี๖ย€�}(mšดrzำฆอ ฃวNตRล๒4di�ญYท�ฅฝhุq8fึฌQ5ฌ'G์ั๓'๚�์ูp�๓‡๚2๓4vฬH9ั ำาe+<าvf˜"Erฺผa|๎/^บD•ซึฐSE   žFBDO[ฬ@@@ข=oม�J—ฅ/ฟสbwb๗๎�C‹ฬ3ซ“=GNส•;7%L”X�ฯยhัขษ๒��—^ฟ~E'ล�?tpฟY$@@ 28q๔gyฒuฅบ …zซYณ~#-สqล i?2†ฺ0+ฐีจ–BฤcวŽSณ–ญšษœ @ส“'—l“#W^งฺ†WeoXwฐ`ซ#าg–ržั|๑์9–/]L_}™Y6k�ฎ8tศู.P? ศŸ/ฑP�2ผ~�†๒ไ�ฮ2i/#๐Cปถิชes9๋ป„jลˆล€ ๊›ฤ%{๗ํU\าตsGj�จก์ฟu›๖t่๐a— �๔c/ช]ห$n˜5'˜&Nvนฏูฐกเ๓‘เ๔็๙๓ดkืnปC-\˜&Oš ๋อšM'Oต[฿…,pbก‡-[ทQ^ฝeผjๅJ4p@?ฟ}๋6๙•5ี‘|ฐฐ†฿/�๏ส /R•j5hz•เY”;ท้๛‡พ๖๔™4Uˆน@ภ“ฐ7d็6mJๅ*T&๖rุธ~ ฅIZฦNหWฌ”qฃ[7Q๒ไษฅ˜ฑv�๚n‰้ฮผŽฺS๓fMe—ํ~๐ง�บณ{๒๖๏�๚? ž;ŸฦM๐z>ฦŽ&_฿โ๒>F+�}ผุญ๗„ฮ@@@>?[๔     เ€ฮUjิชCiาฆณ;๊ำ'Oiๆt๓๊๊ิkHŸงLiท�?฿ฅyมณํึA!€Dฮ ปt๊HMปG\๑กฆ๏‡๏พ3YŠ;u๏ฺYY…ˆ�ฐ&๎X๋sƒ)GŽl๔๎�;๚6ทต•({c.๔=Mlฒn๗—ษTซaฒTfฏ สข6žฑี<ฺถiMI“$ธ!ขbโอWg…ˆ๚3dึ์90iŠ��w—‘Ÿร];ถRผx๑่ี๋ืTชLyuWz๚ไ1ษไิฉ_จQS“ศำคศ$D3r8•*ๅ'ouF`M™:�ึm;•ฯb่ L��อ‘=;Uฌ`HBˆ่FT'๎"ถmำŠฺถn%gฝaร&๊�ื$ง�๓0Zˆ่ํ฿๙?ด1"๘ฐ`œ…ใฎ^ปFๅ+V ๓s„@@@ย‡„ˆแรฃ€€€€ุ !ข 0˜ญ"�ธa๚K{ห้�น}‡v๋�*ŸหYˆ˜โณฯ่ัƒt๋๖-z �›ล�8>ฅK—$L(-Ypฝ_Nž ];ทs@"5�ฺัวL�u�ฎ…!"~เQcปzUโW„ˆีชTฆ,Yพข็ฯ_ะ๘k7ญฎฮษํผqM\น�ฐ'ŽK>>ลไฐกYใqenh๙ ,Yด€พ๙: „ˆ‘dฉY8PๆฝxŒญ ��nฐ"JˆุฐA}MLฟyหV๊๙ใO๖ฆกe๊]•„ˆฉSฅขukVJหาฯž=ง~ฅ?ˆฅh~๑{Œ„ˆ๚˜cp�%Dd๑5�?œธqใŠ๏�ฯษทไ‡ูS6n#ฬู"ฺG…ˆ|วK/ ฏณ˜<ถ|K˜๖ฉข@@@ภU"บJํ@@@@�BBDท`tk'z!โ๘1#๎›�‡๖‹/ ๋gอ–]X1Yพy�ไ1M�๐.ย '‚L๐`�(zSโW„ˆผฺิผqMดษ;qUˆศ?j๏�ณK E๎‹?D(Vผคฃข*˜@ˆตŸ„ˆ"๊]สืmะˆฮœ๙อcBฝkฃ’ฑoŸ�Tณz5น&K–.ฃa#F}๕๑ƒ`Eงn$เ.!"OI๏F}๘ศัดxษR7ฮ๔รv!ข}พ‘UˆXนbŒ3ฆL๓Z๊รญ[ทmบ๏+Uชคxš๖ZHศ๒ฯจ#กVอTฝZโ็ื๒ญ๘n๐เมCa=๔/ฺ",“ญฯžญเ์s ๚้�ซ}‘)=|๔:wํAอš4ฆ‚ฟ“ฯDฌXฑˆญ=o�ผYบ…ญ^ต •/WV6 šM‡V�˜]วŽ)๗,?c�Mnส๕ชVฎDeส–ฆL3R๒dษ่๑ใวt^์-�W+WญึW5‹ซ๑๙y่�งŸ|๎‹๛๘Pพ|y)qขDฤขฯั˜qใmžGfฺIฐๅึฌูฒาณงO%หช|NฆH‘œฎ]ปNƒ‡ ณ,–Vj”‹๖‹—ศ๙TฎT‘ ไฯ'ื๗้ณg๔�oฟัค)ำ ๗)w�Bฤ๕๋Rั"E(c†๔”Lฌห›7oฅ5๏ƒฆโฝb๔}]น6i�2‹g่ฃ๘QŒ1ๅ{่g๑lุr% ฏ๏2๎"–฿IF *1์ฺต›:uํฎxฬตXัขิจa=๚๊หฏฤwฤ้โฅKt๘๐z๕๊5nิPฮำา2OฉPฎ็Aบtiลz&‘็;‡พp๙ํุพ“Vฎ^cu๊]สฮ�;ฬูงZ ๎b?ป]:u ?y๒ไ๒฿Cงฤฟ8จทมs็ำ8qๆจภgj๑„�๛ี—_า'ษ>ฅุโป/Ÿผ(��|RผW&NVีตkX๘ธบ&ฺเ๏#<๗CLgแ?��ฃโ%KYVA@@@ภ @ˆ่‹‚)€€€@T"!ข็ญ๖‡"๒|:u•�3๘ต๘ศ“'Ž๗ˆื�P๗๎�;๙๙*๑?จC�xฤไ1 ˆ”8ลึญ๒ำ“&k?ฆ‡wc�c�!จ๙พฐษUฌญถœ์ศ!๙# �X]ฎ‚้%ฌณีŽE‹=z�DGŽตชขทุ /d+Klmษ(„6žพMลสี ๚:ฮฤ๋ีญCl]$^ผx6›ตhีึ๐^U5G„ˆ–?คช>๘š#W^}า,ฮ?ธzฟbIฃภโT�ฑD๚ฐp^0eฯžMf]โU Zฃดิ=Yึ5JปkM๚๗๋C,ฐ๎��7ฑ่ๆ๗ณgอชฉ๙žฝ{ 8,_ฑ’Xez๗ํG6l2*r8Oํ“…ุ9gž�Vํv๏ุFŸ|’”n�ธIฅหWด*ื‹Q๙ใตeทe`qN�ƒ,ณeZ๕|ฆ็ษ�awd๒โฃG '�ฺ วŸคฆ-ฬๅอ›6ก๖ํฺhb]หถg~๛ฺw่h& ี�pnY_Ÿ^!ฉƒ›D!œฯข-�p`กุ˜qd\�กNฟpชVฏฅ/v*๎Ž๗&ธq�jร3ถƒI‰ฉิs็ศd-ญv้…ˆ,ขP~}_�^hึฒตM๑k)ฟ4fิHูฤ�;Z๕้Ž3Z๕ey5๚^กฟGห๚–iK Q๚๓E๗�GFa๒ิi43p–Q‘ำy๎"v๔�x฿qุฐqณd๗•qห ฒจี^hะธ >�ซอ*๚�ไˆkๆ๑cGQ __›�๑™ฬg3‡†๕๋i๏Gx๋๏›�Pยž(฿ๆ, \yŸ„ๅๆสšธz^ช[ufMT›ฐ๎“๐�.c๙�™�อย฿;8l\ฟ†าค6‰ภ.ฟ3จ{4บฒ‹[vuหม่;ฐQ›๐ฬใ=ำฅsG!๖7�ฃ%ห9X Y ฯd`/%๊;ดฝvชฬ๒;ฟ๚๎ขส-ฏ–�Nต,w%;w. 7ึๆนฎ๚ด"๊ฯ9Uว๒ส�พ๐๏ิลL๔>ฎฎ‰ๅผ8ฝ/d—vฯUซื”thTy   žCBDฯY ฬ@@@ข$=oู๕BฤgยสJ์ุqˆœfK97n\งญ›7:5้ไษSP™r่aี‰รMั�O[O�CtะŒiา:ˆ~>�ฃ�ึm�hู๒ยฺ_๚"ฤAย‘€๚‡(;~�8]ๅ�„h8_�|”#‡I`ฦำแs‹๗๊ฤ!pV4๔y2a๐ม๛�ำ๐zA๚มๅ‚ฐธศโ„7oาGBจ็'EŸ}�™์ษ–0‹…r6ิFซTั$tฒ'rเะใ kv๒ bาง—qถไtๅ๒็>‡YŒแฎภVw‚งSดhัd—ท…5ธƒ?�L…U:ถŒศEโฤ‰C๎"๒@๚๗ก˜1bษ1}}}่ใ๘๑e�žQ๏>๓๙๓็ดu๛zp�ดdงE,:ฉYปฎูS–Bถ ธ�เ!J ฌf–,แซ�๛๘€‰fึค"bM,E.|Ÿlญ๗ี๋ืT�ง˜ด์ย NŸ�5h�T2S๊™uFˆศ‚ฌอ�๋ง|๙rฺZ,]ถ\u-ฏ�ผ�ซฬšIy๓ไ–๕† !฿›f-lU.hๆ4™หp\X4ๅ>ูสอB$๘�w…EณืTเ๛"-… o้baล%ณฬwๆ9P)!ขJ๓๕ฦาชf๑]'G๖์R@วBฤ—Bฌจ\NณEิ๏ YฯงWnฤb^ณๆ›Y’ั ?๘>๗์�G.\”bย๊*�ถ�บtู ื่�ซ|ถTสึU_พz)ญฒ…EO"ชนพ|๙’~��ฌฐr๙@XษK#-Bz‚q–8๓๒ๅอ+งษ๋ยg�๙ฟฮ ‡๑)—ฐ–สึอ,…ˆ,ๆ]ฑl‰&Š๘KXaU๛ุาฒ$jyFย~ึูz+[uๅฝ ‚^Pกธ�น{—J–*ซชiื cGอญ๔ฮžซ•9qว{“วl�บฅN9ไ�6ปfแะ–‘…ถ, ๆ>}ziA“ใ,ฌดดสบj๕Z3ถฅHลลป„ลื/_P)ฟ’ฺYฦ๛ฮศR)รยาึ-Mยmฝ?.3 ๎8ฃ๙^ม.6}}}ไT๘ผPbdถชบi๓™ฏ>ŽŠ๏G�ถํPI3‹ˆ*s฿�t๋ึ-๚๎ปšhษR„tp�Š+�๛ކGŸ—๔n”ืญ฿H}๚๕—๙z๋kl้นBๅj2��์]�ีื>AP ฑ”‘๎–N้”Rบปปปป_๎T,DภV@ETฐ๑๛๎s—;œ��}c_9‡฿ogๆ๖#'"š07๏ าฦ๗Z๘์�ณSฯCx'Jซ�[มบถzๅ2=วโผgฏ>ฎ>จ|๏ฤQk Œ?๐H4ึฆ›ึฏฃdษ’๊ๆ|rๆS:y๒ค^Gไฯ—ฯซ‰|�D„!ฝa>8ฌ>๛๊หฏี‡iW้ษวงBJะ๑ม >œ1ษš?ิฟSQ็ด)“ผฦ ำGตTกz Zsเฺี+(‹š3aXŸ๏ฺฝG)๋฿A๘( ‡ฦ�๑>crVอต?จ�ภผtฉR๚ไตS‘เ๎31๗ภk„˜Rฉ˜ ‚€ D7BDŒ๎็#ญA@Aเ?€ฃ๏s"ขS๋ฐพaอ๚๒หฯขuXฃฦอHํฒ+ฉwช ฺ›�!๚งฺ œ;k&]S�)-†�ุฏ ŒŠ„๑ฬำO๙4๋�๗? 5๋ึU๐ษ(‚€ 1ujืา$h'•า�๛ZŠfPยƒ�Zจ็@MŒทฌฺทีi fนฌล†ห>ๅฺสI๑pอชๅส•g.hฑYศN=คI*ˆˆ็M‚KโxบjลRํ๎‘มHซHำบU jู\ญ”ูŸย ๚“[น Q.๔ธEาL9œˆˆ๛„๒ีไ)ำLดฎปFตช4u๚ 6yาx2฿N›ž�ถlาธHฬUr@\i5ธœ๎ค�Žร�ก1”กƒš›“KXNAบ]ส=g๗๎o[�a๕๋ฝJ;w๎ฒT‘Ž™๗ไ†HQ?ศV:w๑"aƒ�ฺฏืc“™ ๆธTDDŒqzผ�[‘}ฝ๛Yฃ† 4้wไ่›๎ G ฌ6๘K๊f=vŒš4๓Œเeขํ�}ฌXƒ{oฅ�kc�ว|ƒ๗ว'�ฺ‰|(w๗ฮํ๚#• )๎ี/Lnฑ1oฺ๋zฝu+j�ฌ‰ถท฿žืpใ:iย85sึlฟฎฎM^NDิฎ:•,ๆY>Rภxƒ{�…‹๊s๛Oฯทบ[ไ>ญกVศ๘๓ uŒŽu…็A iะศƒญฟ๖ฺ VรGŒข๙ ้ไ่?๋ืฎฆิฉะืต๊ิณ.ฆๅฺร}๎ผ/�ƒ#พๆ}2ะ�Œ*fฮ˜ช๋ƒK๏"ล<๏)oˆPj d\),˜"bฬฆ ึG) ƒlŒ+cอQฉJuต_ศRฅJฅ‰c%ห”3ษ๛v๏ิs=>œ(Q:pZวCO"™รย}&‘Œ—แ<ภ๎{‚ผ น–A�‘ฺ๖ญ›ดK_”M๊r�ฒฏi฿์๔†^๗˜{ทA�~๖นgi๑โ%>sbีส•ิ‡P=uึิGต๋ึ3ลxC]๓‡๚w**[4.=งฺŠ™u?W๒‘ผพ๚0ษ(cb;j„E0ตA8ฌ[ป6ุ�ล—_xUฟ3–/]H)RคP�C9๓8+S‡ŠOl<ำPพใsš‰—ฃ ‚€ DBDŒพg"-A@Aเ–B@ˆˆั๗ธ jˆW•๊ฦ?j=ี]ฉ(ี�7�zมฝ๒ค cตB—� ฺัพใ›๖`‚‚ว�น3•สะŸ>qั€(Ž”*Yาฺ 3mปz๕*ล(WŽ‹-•DЁD€ซFŒำพcg/ฤฝz{ศ>pA–Zฉฒ~ฎ6† ‰dไ๐กTฒDq}n7แš(9ธ2†นู‰V""W่ฒ\Yๅโ ฎ!ร1C\ˆ+"ข!ศกmปt๕!จacmหฦ๕Z้ฤN:1+ไตซฤ๐Moจ”Œแdกnบ9•แ&Œ“\œzœH0{ฮ<‚Šฃ1๓ ์›ถˆวผๆไšูไ5GƒsจDฤํ1› ส|0(c๋Gm�ดฆfM๋๔nTศtB๕cฺ‡๋P๛)ƒ‘[Lz๎jDภvสลฌ1Nถฐ๗�g vีCปq7ถœdา๑็ํOีค๔h�“ุ "ข�ิฎ[฿"6นm[|นอลK–บV˜�ตc›ฅH๊คฌถ`๎l5๗dำทส]ฉ๒1‘u๊5ฐศrธ้dCXอ‘;/‚ตqwฎ ฑv่ts] ื“P‚ูใt`ˆ?œธ[๓f|น๚žนuN๖Gr1lˆVOD๛�`สแวHฦh^Ž��ํบยŒ๓กT9 “TpQ��6ŠMฅfS/'It‰{v2ฎJw๑ยE*YถผSฒ an‰ˆ|>…z~ม"ลผสฦ;ฟc๛VKกคCจึM2‘@ศ™y๓Kปฮ๔๋?Hป/h�ฺ•:�;;vะn*/๊ภ0BO"™รย}&แŽ—แ>@ษ‰ˆกผ'ศ›kิฉA�(Šป๙ˆ$า๚�ๆG�ว{q฿�๑ยก�{ตr5โํDD„2(พB…�iyy฿๔ƒ0งฟSQGƒ๚๕,uo\ป1|๕5�๘สฎฤrๆฮšA9rผ ‹ดƒีƒ๐Qฬ฿฿ลฑ‰๊q๓L†๑!l๚ŒY4~โ$}.?‚€ ‚€ ฝ1zŸดLA@[!"F฿cNŸ!ƒR,ผฆ�L�ไีธ ก*ีkจ Sยแ™ONำฦ๕kฝา˜‹FM[่ฏฑแ๊๐๖ไท[.กฆธX}�“ญl“/šŽpyWYmฝฌ�C–ปนฑซึDS›ฅ-‚ภ สีcƒ๚ฏjืiำฆฑ\.&OžBป�ร=sฅ)ใ.๚ชVฏฅ7ดฬฦ.H2EK”ึ›9[6ฎฃt้า�RŠR�@2ชขิ3าฅ{˜าจ:“฿~ปŽqคุธ “hฦฬY๚�฿Oดห”.Eร† าอๆnฉ��G pCŽˆ+""'A๑บRƒ—า8>๘ะƒVอ&? ม ็†€scf ฎ@ซTซi‚ฝŽฑฝ้ๆU8ปเ$ฎะi’pล0๛33ฯ 1น �Gธฦ�ปwฟrลz, ษ?’~`0ไDDท๏fำส_P.4๎ ๙๓;n‚vอl๊"MัขEฬ%}๗ํw๚�๔Y\7๏8w"AqโH\oธš๗$6ˆˆ'”ซm(๗„j๑AD\ญิ;แzŠหS๓~๙s“ฬ‰dPำœ8iŠฎƒk�ฉ›q‚-o๒๎|'F“ย์}o๑ย๙๔์3O๋:^o�๖์�งฯ#๙‰y“ืŸDฤพ�าสUซy๕Z]c&” *็DๆDฤ�}๚\k2�ฮ‡:Fฃ�Hืฆ†JD„`ทoy�๏ณˆ ฆ่•9Ž/๐A‘ฐ`๗Š5ู.๕ž;๓้Yฺฎ>;ขๆŒEnอ-‘ง‹ูถ]‘โป๙Tมษ๔'ิ๙$’9,�g๎x๎3ฆœˆ๊{’k™H๛๒sฝ�๕Plิฌ 3�๖�๏๔R�‚>ษ'ŽK ไืแNDD๔#จEgห๖œV|ผ๏�{ฌ2าฆMซฯฑŽƒ;j' gอ๊฿ฉN๕บ ใคfง#ธšฌ?""HะE•z"๐H�ภt[’�t๕\ุ?œ0ํ ŸHŸ‰ฉ[ˆˆ 9 ‚€ ‰!"&žg%-A@Aเ?‰€ืc}๚™gฉLน บัฟ^�•fL �%r๒ษฉช"x<๔p:O>ฅŒ8cj๐|ั€L‰โลฉ^�ฺ”3gซ9BDด A ฮภfyๅสี��UศีสŒป_ใZ ฎŽฑqb ŠUป๖์ต6ฏํ๊s\5หไq:Ž3–ฐษศข•ˆุช…ฺWใ0Nœ t/�โ 9".ˆˆ|cฺ_�<ฤถต๊X„6CฐB'Uฌ�c่๎ืDฑาๅ+๒ขฌ๓p6�ฌฬ!œp’ Wจ2E<�ิSeO˜์ežABน๒˜�อ์ตซWP–ฬ™๕ฝ๐Ÿ~๘Qน]HP|ไi?0eq""'ฌšxง#wข#0CŒ„๋ๅโฅสzx=NeฺรœิU9qคGฯ^ดaร&{ถXป6๏IlAๆฉ+T‹"โ‘ƒ๛4ฑ/๗ฯ\mหฎ|i๎ฑB…r4จฟ็žืoุHo๕์ญฃxฟ๕—w�ธัTธ ‡la†Heห”ึe 9šๆ/X่ฅp‰œiป9F:ošrฬ1>‰ˆNd”ั#‡Q๑bลtsœH่ˆเช€nศพ‘Œัฑฑฎ0ใ|0r๎ฌœศ(\Uำ‰ศ‰2ส๘�เฦญ7�=ผƒvƒ๛๕ตJ{๒ิ้^ใณ=ฎ9™-kfŽ�"ๅ�uศฐ>ลqล2Cpๅ*p‘1๎ี๏ป๗^ฎUAD๎ำ๛mชZนฒsRส๕ฉฬe@จ๓IคsX8ฯ$�๑2�g่"}Ox_ๅ"ฎื2ผฎpฯนšต?๕ปpห7๏๘€รi]ฮ฿/๛ุ็9dศ@๋ƒ5ํpR35iC]๓‡๓wชฉ+œใ๊•หิ:เQีinใ๋๛ุ๙Yำงา#<ดjใOจ๘ฤฦ31ๅ8ญ›M:9 ‚€ ‚@๔ Dฤ่yาA@A@nI„ˆ˜๘;�.ร�2H>ใวŒt}-”{”๊+uุผูณ่วฟw7>‚์QตJ%ํฒช�เสg๎ผ๙>$ žFฮA vภฦํิษดห]”ทi๛คK—พ'(D�ซ6p‹ืC‡P๓–ญuล\1nตผV๒็หg5*&fmฺCcFืaPฏฦUkp bื{ง�Wnผ.ำ๕ฎSž<นฉHaŠฦไ)ำิ๗4$๓kัJD„{ilžม&MžJุxื 9".ˆˆ\Ysฮ่ฑใ7Sฑษo,R‚ส uำอิ๊‘“\œTฮ8๑ƒ>คบ๕=๎ษPy ADœ5cๅฮ•S฿.\รฑƒ{ตzฏึU.ำ๐I~แป Jนฆฅ>i?0rE(Dดย… ั๘ฑฃtfœแไง~ฟaํ*ส˜1ฃฮEซ‹jฬ dp-" 7N1ชZ<>6ฯƒฝ'†t้PชT 1ิใ~:‰'P›ใƒˆx๒ุa=Ÿภ}�—}•–œฺว฿ป๗฿�€^mะะ'W˜ๅ๎ฦ9ฉย_^r็ฮฅหดฟ๗��๗้OฮPอฺu้อNohต'd€"/”ycร"™7๊O"ข“๛L7Dฤ6ญ[R‹fMu๓ฑ.่�ีฃย็t? wŒŽญu…็C%":๕N�โDD|ธqGŠ;�AเŽา,\์nK>={ŽชีจๅชจR%‹ซ๕`SGwง $6oีฦฏ{gTเ–ˆˆy ๏ ย]ช�zพ�ƒjTซชƒ Bห–{ๆฤcGj…}ฬำ#วŒQŠtsผฒVฌT†LO=๙]Už ^.Pุ+>’‹P็“ุ˜รB}&แŽ—‘<>—‡๒ž๐g‘k^ธ็๏8JFฅ๊€Fํ9�๒b#_๋�tๅŠVกถ—ห฿/NDD�ูณู"!‚lธcื.ยz.ไaํ•+๔�•ย=ฦ„๓ฐญฏCY๓‡๛w*ฦนฌYDภ3โ๏ฆำ5|=b'"rทอ��7ํ�ปฮž;O?+ฯ0��—Qnะจ‰ใ˜ >ฑ๕L ๘ k2Xท{า†›M”A@A J"b”>i– ‚€ ท BDL|Oบm‡Žฺ=3”sฦŽ๒y��E•ช5(๓/ธw๏ฺA'Žu“-^าเ?พ+ฟR‘ส•+KO<�˜Wธฯใ'Nะ๊5kๅ?<ฝ‘ A n่�๕MชS�ณ ฝn�Fzป—GeสิสI† „8พฑ‚aๅข๋Ž;๎ะฎห•Un™กx�บ „ w�ˆ~|“ร(ู่D7~Z+uฦ–อ=nG3ฑชr;�งwO}W+”Kห~สตeธfศN$ธ`e.คsR,Dธq y ๙`มVqฉˆWm/ไx�ำฟTํ8ษลษU/๏๏ปv๏กvj.6f”�N๚€เช[พผyโ�ะ"@IDAT ฎ�`NฎMZใ"žฯ็ฬc‚ƒ฿๊�•jีฌกำaฃสmก็J–(AeีปษUว(า้ฌ9sญข"้ฆCD ด mา๒#\b2lมยลจ็�oฦX�ƒi๙Š•<นฦธร์*w^ \pโˆฟ aู_xแyส!ฝ}๕๊5ฺตkทum?™9} ๅษ[;ฝ‡†Pํ†ˆ่f\ดืkCD4JถNi์aลŠUธ�$MฌŽwภŸm�ธ–าง๓เโ–xมษ1_}�5•ฏ่Q+ใupRˆงpฉ ๓ส๛ีWT�•*<›>็Dฤ๊5k[jฎ&แ๚ต+)SฦL๚ E ลย}"ึฆฅ•B๙ล‹—LาˆŽ‘ฬ›N'""ˆR#† ีอ�๐รด+Jง{1aแŽัฑตฎ0sm\Mๆžƒ๑QH๎ผ/Kๆ:~๑‚y๔์ณฯ่๔N๓`ฐ‚ ๘U ~ชXพaฤ‡s0ป๒ตฝNDt"ค™๔๗‡ ๒ฌ—ธ๚ฉ‰ว‘“`9นxั�น๔�sฯ\ฮ.PL4oึ„>�่cJuืšธR1ิช“%KJฑญพ๊|ย�ฟ†;‡L�>“pวหHž ๗œž;�9aื�?ฦ็Z†ืฮ9'ุ�๘ใe*ZขT8ลฤIžใG้wเŠ"ว*R�ง�~q"b•Jฏิag”‹๖ื6๖!W;| V‰ˆแ�jฦŸ› `�Vๅ�8ญxŸๅDDผ‡1›7j๒)ˆ™ 7๕Yo๐๕ˆฟug(Dฤุz&–}ปwา�wงา—ัขโiฺ&GA@A@pF@ˆˆฮธHจ ‚€ ‚@๓aะ‚‚$ุฒqฅK—Nงโ๏ษถM‘้|่A}ษ‰ˆ\แv์๘‰4sึl“E๙ว<>F eอฯืก�บ`๎อ๕ถW#\˜ฟ ่Oส—ี)๑wๆKnร† "จ"ย8‘฿�พ�ุqร๓�ชฐ5D?DฤP๐‰ญg‚v๒๑แ๒ๅหzญส�/็‚€ ‚€ 1:Ÿ‹ดJA@[!"F฿ฃNr[บ�๏uว†UซQ›2f๒(ณ|��%ตs๓?y๏พ๛๚ๅk{ๆ”w�IM›ตข$I=�y-ฎ™๙ฺ|�๚u:r์ญ\นŠbถล ศŽ\ ‚€3ัน`IะฎŽuฒuซWZ&œˆˆา–/]์ๅขo�มƒิJน‡ทo�ุ•…๖+cชTต;†ปhEqADฌฏ\ีพููC๖†๎;ฎŒ`�นSญTฑ‚"C๎๐!Z๑6m�ธžN๗ฐ2e<>ะน""฿คบำฏฟ�B็ฮfUDฤpŸI$Dฤ_~๙•J—-๏…;WF๋ำท?ญR*ฝฦฬฦ-6†+Uฉaฟfีrz4K4q์จTดh๏ �7†อมฝปwX_'^��”Jกิ‰เฯ vิH๚ฉ?\""'๎šฒp„Kๅ๖;๓ }ฮษ™ œTชZ�qณC<’!<|ุงŒP‰#ผ€P‰ˆ6ถ๛๕ํญฃQ~\ก2fT&Aภ'˜…JD„ฺ�ไย.]บD5•ย 6ดนA}0sๆLด{ฯ+ุจ…"nh‡iลpดq�ญฒ„@พyฯ7ฮgำซUฉฌ��"๏Cน •p๊e(c๗ฎwดKWn ร7yปฬyจDDNx=u๊}ฅ์ฺศๅxŒ "" ^ถd‘v…‹s'" ยq"b(ctlญ+Œ‹t(๊/Yฺk~0m4G�๗M(Jof|6ๅ;�ฆ�œ�฿ก`y�ลsRฯ๐ฃhพR tcPPดจ‚|PL3าฃ��•ERS>�ca>ชภ๛ธc๛Vญฒดํ�่ไฅ6[กB9ิฟข่ื_ฅ�…Š๊s�๐yมbอtwชปiา„q&HC™ƒฝ2๚นu>แm g ็™„;^F๒Lย}OณyWb-ใ็1ปFE_… 6‚-^4/ึ+›6�\w"ƒQ0hAA๐ต(�šรฝน1๎บaœˆศ]t๏�ป—ฺถ{รdำG�๗_ "b(k�p�NEŸฝ๏พ๛ผฺ์ย๔3�พOŸึn˜ผ่“๘{ EŠ:ˆน &<เ#novzƒ๊+ฦ๘Zฦ„แศ๋ทฏix:œวึ3AY\ษ้แc=1A@A@ˆ~„ˆ�ฯHZ(‚€ ‚ภ!"Fืใ}�…œ๊?&‹ซ ฺ‹t๊�“๔•Rธz๕Wๅโ/#,RDนƒ๓|ŽVฏYนœ>๛์ผพ�‡gซื�ำตkW้๔Gาyฅฺ๒ํท฿จš”๔lถl”็ล—ฌMฺ?�PJŠฦFล› ธถ[ฟa-U�แ[n๎ขโฅ‚@"F€ซ.�๐รด|ๅJ:v๔ธra๗ตi�ŠRง~ภบ;;‘šศljs" ย็ฮ›O#G฿๘FT‡V*ทล็ฮžฃ�yrQ“ฦผศ NDDนม& ค—�onฆ�ฅ”ศGfLBจ5ย%�้ำŸะJ๖E”މูŽจX1(๓@กวXฬถํดiหVM*x4sfชVต eห๖\Pืฒ\}›{(ใ� 2เึ˜ฏ1ชkp“mฌk—N„อMX็.]ี=�mข,"6์6oZฏ,y�ณฯh๖์น๔ูŸSช;Sั“O>ก�๚–ัฤSป’`lร}&‘อ}Nš๚จ"ษ!จp}กึY•ชxิMน8†JแyC%"6iิฺท{]๒ฬธ ้ย…KTผxQ‹„ˆศธ$"ึฌQ]฿3๊{๐�j๗ค��๛t๊�๗ คqป…JDD~Nœฦf“H�“„\ห„๚�yzเ R3Tดั‹•Lj6yใ‹ˆh�๐ไ�ฝ{๗QึวฅถmZ{� ม‰ˆ๒ฟlz๑แ๏ท�{๖าํ๊>กb�์3O›[ั*๙/ๆ+`]๓�'‚�ษ฿ฉผฮPฯ๙‡d๘hh๑ขฅ”"e ๊ะฎญื:•QŸcAึ�จๆŸฏ�L•”[k๓!ˆi‹?"b(๘ฤึ3A›๘G�ๅฝiฏA@A :"bt>i• ‚€ ท BDŒฎG "bฑ�_H;ต๐ŒฺD�ธ~ญeˆˆV€Ÿจ5ญTn6ฟ�๚+?)โ?ฤธธ่Bส\๕ะ�บฟ��‡’%KชƒํDDฎJƒPš‚šศp๑jฬฎfSคHa7๚ฆฺ•I็tด๙†‹Sz{Xพ�… Yสžืฑญ>ด;r'Œ|P[ถdืๆ )ฯฎ�g\Kš๘@GN๒ยYŸ^=-•๙โ‚ˆˆบยy&‘๎sh�ƒhๅ๊5^ั|cะ+ยvˆˆEจ๕kV9b bb๑’elฅ�ผฬŸ/MžไQ๏<ซ>DจZฝึอH�W6ดEY—Ÿ}�น#9/�~` 6ฯ1ŽIk?‚จยžฑ`d0(ผM™4ัrัi๒ู�๎5โˆ);T""ˆ \ๅห”ƒ#6๔“&๕ŒณqIDD]\ฝืฦ6(‚Qžฝฬฅu ‡ˆˆ๑nุะมt—R๊๖gN.žน๛jง| tดRฎOœ8iE�‰5V„ํ$ชสUkุBo^ฺ฿๏Š`ัฏ�ภ› b้,�yีsีศ`อYบl9 <ิ'™ษp—ื-""๏๛XS”,ใ๋z�ดรND4แ�่4FGฒฎเeร�&ˆ�Nถm๛;ิ้อ› Qผฯุ qศ_๏ี:ิฅs']T_ี—@ฺIH9|(•,Q\7มŸBณS๛ ้อ)ฮ„แ�lุธผศ  ุ��๏>ษะ/ฬ‡jX›.[ผภ" ๛$V ๑WฏQวgทv๕ สข>๔€mVmtํ�–>ง>Z1ฤ]ฃkื๕| #cแ'œ๙$�9,�gษx๎3‰ไ=IศตL$]dY|”๓7ท:••หล ๆyE™ฟญผcแ‚ปถT'""'k�๓ม๋E’nฅƒญอZั^ฎ๙฿a‘�๊Tถ�0่;+CงฑŠ—a'"Bqy�˜?""๒บลicใ™ไฬ™ƒๆฬœŽโ่ซฏฟฆ๒+๋s๙A@่G@ˆˆั�Œค…‚€ ‚€ �ง"bt=�L™ณPลW*Sฒ -๖ึ��๗฿ดgื:๕�ป^QI“&ฃ๚ +7ฉwำmท�ๆg. �ฐyร:ญถhยไ(‚@ ฐ๙ะป็[ึฦญI๛ล—_P๏พฎ�nO–Œvํ�Cํ:x\# 6‡vฝฃ“�‰>pฟา๙ ๑ู(ฎQฝต{ฝ �sฯ�ฆ:Mฦ9q๒$ญR0ธ…5† ๔dŒo”˜0วฟ�๚‹r็u&ขํฏทiEyr็คดiาZ?lข•)_ัฺ ๗WvจแตjVW*>-่~››02vํ�ญ #ม\/bรบ‹RW|๒๑ว5๖ฆ ปv๓RqCˆd� Fิไอ˜=gž—ผ]ัš๘&Jyธl™า๔`ฺด^}ฑwŸ~ดzํ:“L+ฯ2 ��ž:๕‡ใzc dอaoฉwดVMtๆ์94V๕y'‹dŒw]ao�๋บukSŽžง;™ึQึoุHo๕์m%็๋'W็�อeทoiต\+s<Ÿ@im�š•๚]ฤ{PB‘�ƒฝฆ‰๘ธค{ืฎJฝ๙YŸ1i๐�?มQQี”มP?mฆ๚`–,Yฌฑลฉแ�>lฝœ๏%ฏy ๋ด�j=Šgแt๚๕ฅW*–ืU‚\ " ๋0�`P\4d˜>ญŸp็“pๆฐpŸIคใe8ฯ$’๗$!ื2‘๔‹ํ1›ี฿i}ตVW]ฏ-ธ›]ิ�ู้sTญ†�N"i#๒โ}จฆTM๙šฯ;~‚jTซช‹oุค™๙s{Ÿ�=ฝึ?Hˆ๑ใzu•J๏มึ€กฌ๙ร�;U฿@?U”Š!�๎Bฟ7†d-YbM'OF๘hŽิCว#a๙SฉษB=ุบ3|bใ™Œ9\ฉˆีทH=š฿งœ ‚€ ‚@t Dฤ่xา A@A@nY„ˆ�^EHษ”) �s฿ฝ”T}=�ฃrQ๕๙g็”;ธŸƒ6๘aE๊€ gไUปฎtแป๏่KEQDLpั-ซ".�๕ื฿t๔ศQว �pส ”'{๖็(ใ#(๒๔ท„j*6–žy๚)บ๗�{”zไท๔ฉ"ื8mคย,พโ ฬ’%s&บzํ7๚V)]r—”๑ี†ุฎ‡“\ ัH฿g–ฬtๆ“3ฎ๎’/<�<�s๏�t\0Œ‚Slทีฉ<ธž:eขŽฺปo?ตi��)™†ถ>�ฤใjฝFฏ3 Xz๎์๙๚\b๊ 2>๙ไcค˜Cสํ๑…๏ี.ŽOเ1C†๔ฎ๛\7'ฮ‹‡Kุ,Y2ัoฟ�AŸ�\นส�"h ฺ<ฆๆฃŸฏ�B๏พ๗ž฿>‹>n\3ร}"บหงศd๘ฐ็ุฑc~๓๒F`๑0Œuีkึๆัr!x&[7oTSฅ"ธ๋.RฬY>6ฦ่[m]แๆั๔้�6Uญ์QธŠ„„‡๙ "X�uืt้โ๗๚]Ž9Dคt้Vj�฿ธ&<บม%ฺา„3‡…๒Lbkผn๑๙Lะ๎ฤฒ– dXุบ๕้ํ^7ษห:0ภฯฤ๑cฉ`�V ฎZnฦม 7e๛K“งข-Xรภm5ึฯมT_M�ัgŸ}๖YJ๛`š๒™�แร}& 2โCf'ํ†ำษ#‚€ ๑‹€ใoฉMA@Aภ†€m€ศฅ ‚€ �r8‘\ใวฆ‚๙๓ำีซืจ@azIbปiฏ [8kย){ฉr ฒl๘ศั4มBŸb@Ž|^‘รฑ={๗ฦ+i9œ6ฦuจ}ตk�FW๓jƒ†๔แ‡๙T๙_ฃ}n* ุซ•Ÿ�Rไ�๒+�๒}‘?ธ‹พ=yrไ๊�GฅทcวNWiฃ%Ql—ัr?ัุ(ฟRกผ"��N^ฉP)ึ���{vRชTฉt0oต๊ฤฎ๛p{}r-Œ}๛๔า`t่๔&ํฺต[€A@D„€ัร’ฆ ‚€ ‚€ ๐_D@ˆˆ�ลง*๗$‚€ ก $—Pะ’ด‚@๔# ฑฆB๙ฒ”9Sf*Yฒ8eษœY฿,�ณ—*S�QE‘ป™มC‡ำโ%KCอvหฅ—1:n9T๓RฆธC)_sญ่7-‰ฎR๙๘jหพ�แ*ฎ\\'&ใ๗kdS๛�หm…’๋‚นsฌ[|ฝmฺณoŸu-'‚€ ‚€ ‚€BDtBEยA@A@โ !"ฦิR‘ ‚€ D)Br‰า#อยD bอ;�ถPšิฉญš��๗_๊�oญ^ปฮ ใ'BDไhฤอนŒัqƒซ”๊Œ?œS๘ฝ๔�๗TขTY� ข0†฿ฏฃ๋ฝ๐ย๓4nฬ(Jr�mš,�ดyซ่j ดFA@A *"bT>i” ‚€ ทBDผužต�ฉ ‚€ 8#๐f็Ž๔jฺ๔�๗Tฝfm:w�3็„*‰kv๏�NI“&ฅw”›ิNovu�๎ kWQ† ่ฯ?�ค?>M+Vฏฆ 6๙อ��๗Sๆฬ™�ฦŠ8qโd h‰ป€ŒัาโจE&ร5๓ฯWฎ$บ5D$ใe|?ฉOA@A@‚# DฤเI A@A@8D@ˆˆqฎ-‚€ ‚€ ‚€ ‚€ ‚€ ‚€ ‚@< DฤxYชA@A@๐€�c#1‚€ ‚€ ‚€ ‚€ ‚€ ‚€ ‚€ $„ˆ˜ž’ดQA@�0BD�?\น5A@A@A@A@A@A@A@ธ%"โ-๑˜ๅ&A@A@ˆ^„ˆฝฯFZ&‚€ ‚€ ‚€ ‚€ ‚€ ‚€ ‚€„ˆ่%I#‚€ ‚€ g1ฮ •‚A@A@A@A@A@A@A@ˆ„ˆ/0K%‚€ ‚€ �"ข?d$\A@A@A@A@A@A@ฤ€วs’V ‚€ ‚€ ๐ŸE@ˆˆ�ูG+7&‚€ ‚€ ‚€ ‚€ ‚€ ‚€ ทBDผEด�ฆ ‚€ ัŠ€ฃ๕ษHปA@A@A@A@A@A@A@p‡€�แ$ฉA@A@โ!"ฦฐRฌ ‚€ ‚€ ‚€ ‚€ ‚€ ‚€ ๑„€ใ hฉFA@Aภ!":ใ"ก‚€ ‚€ ‚€ ‚€ ‚€ ‚€ ‚€ $„ˆ˜Xž”ดSA@�(BD�>Xน-A@A@A@A@A@A@A@ธe"โ-๓จๅFA@A@ˆN„ˆฯEZ%‚€ ‚€ ‚€ ‚€ ‚€ ‚€ ‚€[„ˆ่)I'‚€ ‚€ '1N`•BCDเฮ”))yŠAs�๙วtํท฿‚ฆ“‚€ {���ฎ ป|๙ฒซtก&ชPกฝZงŽฮึปO_:๓้Yว"ž~๊)šแq๐ฤใัศCu5 .ฆฅหVฤu•หท?วPž—=ฏฟŠ์eฺ๓ูใ�• แ/ผ๐<กO�x๙G:v์9ต�ํ�eฟงฒ์i]๛ซ7œr๙3 –Ÿง ิพ@ๅdส˜‰ฒ>๖(ฅ๘aบvํ}๗�:๕�๛~็๖ุจ3P[ฃ!.ฺฦฎhภ$P๚๔๎Iy_ฬญ“ฬ™;?เุบ|้bJ‘โv:v�$๕ํ7 Pฑ' ˆ€�ต^61^ช6sž�ฟyM๚@๓nธ ว|=dฐg�\ฑb%ญ\ฝ&�ขb5Ÿน็P „๔ฝPtŸ๓๏]wฅิฺw่ไ๗๏7๗%JJA@A@P"b(hIZA@A@XG@ˆˆฑiฤ–,]–žx๒ฉ€ๅ\Vฤˆล ๆLc"๋ผZŸ๎ ตพผxแ;Zฑl‰‰Ššใฑ#้๖dษ‚ถ็ฏฟ�ฆ�/ๆ šN‚@์ ๐V๗ฎTซf W…u๎ฺbbถปJJขื[ทขๆอš่,m�wค�{๖8f1Oš1mฒO�฿�Cน^|ษ'<ฎ๒ๅอKSงLิี€,3jฬุธฎาo๙ :-]ผภ+�๚๕๋t๑โE๚๒ซฏ้�๗�ฃI“งzล› งผ&ฮ~,Yฆœ*๓’nิฐฝัพW’ฟ�๚‹พ�ๆU็Wดsว.ZฝvW|$ุ๐|๒‰วญ"^o�๖์�g]›๔๔ุ�ฝzำบ๕M”>พูนฃ๎๓๖9้�๙๓ิถ�บ�&รฌำ(wฎœๆา๕ฑVz๔๑้ำฎำ�nฺฐ–2คOo&๔๕‹—.าัcวี๓œb= Ÿ„7š6iLํ^omE:œ/Yj]๓“p๛)ฤฮฎ;ัณฯ>c‚ฌ#๚โG}Lƒ†ฃ?�ศ oีฒ9ตjั�บt2y๊4šw์ฺฝ‡ฺu่(yศqผ�๙ า๐‘ฃƒ–๎xดเ ฺดnI-š…>–;žfอ™๋X๔=GX๔z-’9์ฤัC”4iR]x‹–m่เแรฮIจ ‚€ ‚@œ Dฤ8U A@A@p‹€�"้ชืฌM(‚@vํ๊5š6eB $:.g๎p“ิ1อถอ้ม‡tŒ3�๙'ตSฤ�@ฟ ๆฮฆ์ูณ™,:-6‹,�~€ฒ@ส8aฌต!ํT>ย†ๅE`I�ศอ˜9‹ฦM˜ไ&iิฅ‰ถฑ+๊ฒ5(พ‰ˆ†ฬˆฑฑA#)�ึ$วหŽฺSรื๊๋8!a8B$�!ฬฃๆ“็่��๏�่๙œฒ(ท็vญJ™‰-mึGณะ๊•หuณ?9๓)ีจๅQ๗wU*ฝB}๛๔าั๋7lคทz๖๖—4ฌ๐pˆˆแŽ—nุพ�๋ิคQCทษญt&MฆiำgZื�D๚Gใๆyคs˜ob)g‚€ ‚€ $BDLิฅNA@A@ !"ZPDอ '"~๛ํ7Žํบคงvพใgoฟ�vjัฆ%M’ฤQb "B�ฦŸ�ฎ\3๛�D๐—GยA |8$Œใ'N๘-lๅช5 อoข0" SฆTIsๆ์9ฎIkK- gž~Jˆˆ 9N"๛ๅ—_iษาe๔ศ#(ใ#ะ3ฯ�GฉฺMœ4EŸใ‡ก�wไศQ]_ึฌRฦŒญt_~๙eฌธฮถQAร&อ่ฤ‰“V]8แไANDไ๎HทyหVฺถ}ฅM›†ZถhF๗�s‚i๏พ�ิฆm{}^ก|Yส๚่ฃ๚��dอš•Š.ค//�๔ญถน2Icๆฌ9ฉฃq"โขลK๕�*=ฎ!_z๑E๋Y]บtI=ฯ๊Žuแน๎�ณ“’ฐ5ศ‹y^สonล๋n?@!�c6Sฺ4ityhำ…แกC‡่/ี฿žzโ ชTฉฅO—> ๑ฃOำAE\๕g;w๏Žˆ�้ฏ�„O่ฑ+!๎9”:…ˆ Z’Vˆ"%"†ปึ‹Ÿป‹ฟZ y๋สฯ?Sก"ลVฬUƒฑ�š:}Fภ๔กFยrหๆ๕ม;w�ฐม”ืDD]‹.lช๓ี–“�/!f�;~•จฅ๏yรiฎ„ˆhฃ ‚€ ‰!"&ฮ็&ญA@Aเ?ƒ€ฃ๏Qr"โ่Cรn`ญ:ฏRบ๔ฎ0AJ„E;1ก\จ† ฒd�ใp"ข]ญ,ฺo=กษ<ัไš™A „k`c๒ฟL}zฝญwiuะ–ญ1ิฅ[ํs„๋bธ�ƒฺ๘ๆDDๅ† a•ทอpน›"E 6`ะZถ|…ฮ‰Š‹ญZท๕*ฮq่เTถLiึ๎โ$ลiสอ6”{�๙็*Qบ]พ|ูซ\s‘?_>š๖ุTฑฒว๊ถญ›ฉd้ฒ๚F…ˆ}ฯ[Z$D3แ|0-U(WŽ๒+’[ฆLต‹dธ.|wฮ๑9mW›ฅ+mJq‡.;)๕žX>bฤ‚ a7™งm›ึ”'w.‚j_*ฅ0๕ถOฯฃฉำf๘ธ,6mศ”1u์ะVซ‚ฬ‡<๏พwŠ๖๏?`นฬ›3w>3ึd๑:พัพV%4หWฌˆ๕อไ@DDิ[จ@š0~Œnยฟ��Kีjิขs็?3M๒:บ% ""ขภฮ;Pƒ๚BไEฅ๒ B]$ๆDD„๚`ํบ๕ฝTp�ุKw�q‡nBำๆญ่ศัฃ^อYบx=�ิS:l์ธ uN'Kh""ฺ4{ฦtส•+‡n�ไฉำh๒”i>M7vQ๊–0E๋ึฉญฯกูต๛[๚<ะ�~า*ายเบ.��Zดแ>ณvญZTดH!j�z;หU7ฟฏzฏึกB าฃY2Sฅ๙ฯ?ื้ยล tเภ!Zฐpqภq,”ฑซXฑขTธPAส™ใyJ“:-ฅLy�๖�๏๔๙_จv}JcฦŽ๗KšE{kึจNีชVฆ ้ำ๋1๏บR6ฝrๅg๚๔์Yฺข๚ยช5k๙mY็๗ZทjN9žžRงIญ�nฃ�‹—.าัฃวhบr•๗:.,\""ตkีฌNูŸฯฎ็$ดo�มส=�ฏfVจPŽชVชคร�๗ฟ�ฌw —๗�{ฯ+ํ��๛i๖œyVุฤ๑c้Ž๋ฌJ9๖พ{๏ีqP~ฝt้{+�u5ฮvxฃ“)๗ญ๎�”ยjญpบfํ:=>fห๖ฅHžœ>��s5&ฃมC‡[e๘;yณำ๔|๖์j๎อD๗�s7��๛๏๔ีื฿จye-T}๏ฺoฟ๙dEž\นrQ–ฬ™ดŠ๐ีซฟ๊นo๚Œ™•FAh._ฎ,�Ÿ๚ืใํ^z�,Zคๅษ“[ซศ�tๅŠš าˆQฃ}๚!Teส–ึชฒPL�๕ื_้�น๓ดv�ZนjตO2„๊†jพzL=ำ๔๊]ม{r�ณฯ•ฒ๋aŸน๊ฑcวŒค�T฿๙๓๏ฟจณ"ƒ�1วi@ฟพ”Dญ‹�พ�มuท“แCšชฯ>š93ฅK—N“แ๘แz�ƒh๑’ๅ>๓ส€Š]‡๖m๕|…็™4iR๚๚๋ฏ้ร>ฆกรG๚<ไ™ชˆ๖ษ’$ฅฃŠ<ถ–-]Šž|๒ Mผ?sๆ,mฺฒEฯHk c@๏ž7?ZFจ >ท Š„๎4๖Gฒึซ]ซฆVห† ๑mท��V œW�.ŠWซ๗วnผฝK–/Wcภ�TฒD1z๎ูg๕{_~๕•๊wkh��๖ฌึuธใฅU€‹< |ศซขˆ๛X‹กฟ<ซฺ ๛๕็_่่qพNiu"๕๎ป‰|EŠฺUyภ5&fป)�:F2^Z…จ“pึ฿<จDฤP๛ž�/}�ƒ๊3Oke๏ฏฟ๙†ฆซy%ี�wS�บu่ม‡ค๏พ�ŽFŽ๋ˆU8๏ฆนวPวhฌŸž}๎Y๚ํฺ5zฃSSŒu์ืทท๎W_ซนก�€AVธนO„:‡Y…�81๊žธฤw๐๐a{j�๐5ฅŠ]‘ึญ� ีฺํcฅO A@A@p€]C% A@A@โ!"ฦช‘•Dฤึสmd๒ไ)่‡พงฅส=i›vo่F 1ฒg#น[ p‰ˆุเ'mุธYz:&ูธnตr�ˆO\�๖i๗ž=>แNกyฐA=R)ะ>๑๘cNE้อx A โwncGิdn?DD\ผ`ž&1š< หL˜4ู\ฦส1•lXปสr™Hกะ--๋›7ฌณˆ ๅ*T๒Rร ๕ฦ9$Bจย U@cNDD<�๕kW๊$ Sฝ”ฟ In9qrอบ๕ิซw_+ŽŸDq๔ศaTผX1�,ธแ4doข>?ดฏ&ญ]U›ิ%K•ฅ=ปvPฒdI ฤกยEK๘คทธํ ‹๔่ๆูี wดซUญBU+W"รŒู�ฃ_2˜@ส๑gวŸคFM›๙‹ฆPฦ.Cพ๐W”;ปt{ห‘ฐ4nŒ"ฃ�p#๎”„€|๙=dUqr��ูq—ว™๓q&ั EFŒ ‡ˆทใ &V�.ปrjง7ฺำk ๊๓$~ฯทm‡:ฝys| ๖ํs˜Uศ7DDพถ†�{๖า*Eฦผ,&‚€ ‚€ BDŒ ?ษ-‚€ ‚€ !BDŒภ8ศฮ‰ˆฟ�vMฉ4$'�'2พh�๖�oh๋ๆk-_ฑ=๑ไS:ฯ์ำ่?~O4DD�X ตธ}๗]o5š€`Hค D„'"BษสFN๖๎{๏zฉ&"โ�A‡)์ซ/ฟฆซืฎา“?N… ค$I’่bฐฉ‰อMปaใชCฐžฯfไโŠˆธ|้bz๒‰วu}Pฺบm;]๙้Šช;ปE(ยFoZuผ”9๙ ํp้{GŠ;จTฉt{ฒdบ<�$""w๑ต?จ�9™[Z0""ส๙›ะ0ธPŽdใ‘? (/ฝูฉฃ&c@นชrีšแว‰ˆฯŒi๒็Yฅ€Yตz-�&�ร]๛#Ž }4ทl\งีณะžฃฦ๘(ฃ?�ˆพ�๎;Jฉ”=K*’—!ค9‘€๘sA;+bึX @๕ํๅ—๒)๖฿”๗ๅ‚^๗Œ‹YำงRnฅ ƒ,๒~ก�xเz)๏‹ฺญh ทํ:c?p}Ž๗ ตOจ~๚3;ฉคฑSงN)า๙ใึุŽผpW๛‡AฌXฑ"๊Œด!ืAฑoำๆ-:��@™Œซ„ม•ๅwx\ฮฟ๘bส’9ณNŠ๙๓ห/พ4ู๔�พ�ๅDD$„bใ๕~ข฿•,Q�"ยAq๔ุqVY8™l“z๏  ๓่iำคฅผy๓(ลฬิš`ล‰๎#† Q๎�=ฤcx@�†J฿ใj>4mฉ[ =vใd'ขิ้ำŸะŸ�ฉ฿จbL6DDž}cะ๙๓Ÿ้~S\)|B=6p๐8{ฏM[ƒ1—Pฎ๎AU๐ธzๆxŸห–)ญqG\Lฬ6๊�ตปIฆU W.[ข‰>ฤ‡ XภฺทmCM7า็��ีทjูœฐ2†พ๙žRZฦ฿ƒ่ปx�์ไ3–ึญ^i„๑ผv๎ฺฅ๓`�ีSุ7๊oษฒๅ+™ข๕=ุ‰ˆๆ๏-จCcฌ0ุ}Jํ†๚š�ธ\—/_Ž๎Rธภ–.[ฎๆcน/œต'ทฃ|ผ[XฏAy6wฎœฆJฏ>‡@ND4‰0—_ธp^z)ฏๅ๙ว/SัฅL}Œdผ๔*ศลWฦG๘˜€+ข๓แฦฝป๔๘€๙a�๘{fยƒฝ›H‡>_จ€g�ฯ>แƒ˜?"b$ใ%ส w�ผ�ฬX๏–ˆj฿3ๅฃNผiRงกิฉฐš๐ษ™Oี๘{Aึฅ[ฺฒ5FŸ‡๛n"sธctธDฤHๆ0}ณ์ว|๐‚ š8�N“F ฉํ„๋ฏ”Š๋๚๕i™"ธใƒ 1A@A@ะ"b่˜IA@A@XD@ˆˆฑf,ล‰ˆNEbcoรš5๔ๅ—Ÿ๛DงM๛ ีญ�š�ฯ�?�€ถ(าโํท฿žจˆˆ>7ลb9จs—n,DNA .เDฤ@๕ุโฐ1 —`‹•หWฎ‚2 (ฅุGŸVฎs=๎yu€รฯ๋ญ[Q๓fMtL\๙ฆ๖ฅ๏ฟง&M[Zค5Tส zœ€VชdqตA8Tท ื๕_kd‘ซ@๔;j„ตฑ–ˆˆœHส-อ ั‰จ ใ‡;tzSK ‘.฿ู๊[—๊Tg9ๅtศ :dwl˜ฺ?oพ๊ิk`Oขฏ’ˆทฎ:ดฃย=$lศƒTiwg—|•_๑(เ 1R+}+_`‹—, ๘QาธํHหŸ ฎa ฮฝw๊}M–ฺฑcง'ะ๖ห‰ˆถ(Ÿห`ส<>‚`\จR๙ห7O��๛ะ๚›ิ&๙ฏ๑“–@R์๑voM์โy5l �=–{‡ขˆาˆAvWโ(�ฺ)7ภปvํถ๊i�ชตl�L_๓qอ$€ ษ�สฝwฬถwLu�ท{'�}w*}5๋™OฯZq8ม๘๗๑ว;ืผฦร'ุี 9ก.ฌgอ™ุ๋"S†ฟฑม1“ ฤณi๘Z}ํฯ-%ฯหŸื…๏.Pm5ฦฃ ๆVฐH1ž•zพี�R#)ฉmป^คy฿|ณฃr%|ฤ"ว`ผXกศr๘0„ํ๖:i๕5S๐‚นs”jŸG�ฎn{๗้gขฌฃ์ดK)w๏�ถื{Qฟ�ซดs็.=?ขN’&Mช๋์คึ๔��‡ู`nีYญฦฤมษๆk)}:ฯNฤฑoๅ๒%š๘B%��ย�` sม„๑c4พ sพฆๆ•;S�IS'Oะa 6nึย‡œc'-9}R]šี4‰�ิ7b่`E"+ฉ/A�Fเ๋/N๘โ��ฎˆhWํ�๋mํๆcœiฺผ•ฉา๋h๚ ฐx>็M๒ขWขnืz1›6X$kผณธc\M๐ณฯ?งJU<ส‚ˆท‡E๓.าYม๚ตซ-b'&#A$ใฅฎ „ธใž4มC46คใ=ป�ัฎฮM1={๕Qsห2R1ํ๎ฝC}7Mู�ศ ˜๖�ฯำ๑๓Pฦหpื฿ผ>sn๊uKD4๙ptำ๗L๙ !ขเ๏DaXฯTฎZCซ›Cๅ‚<ˆ๒ฐp฿อHฦ่p‰ˆบม7~Bรx�Pฮ1–VซV…ส—)cฝ�&?ž็�ด�tทŠ๘&ฏA@A@ธี"โญ�ไ�A@A@H`„ˆ˜ภภกzCD„โUฅพ๒ฺLuW*Ju๗MR+ลšIฦj• ^Dณ–ญ•2B*ญh3qœว}าŠˆhSแ๗.็‚€ ๛ธ%"๚#)๘kั}ปตr�)ๆู8๗—ึอกS^ทdณyŽ2:w้๊Cผ)`หฦ๕š8๐ห/ฟRยEuuœ ่Dเ sˆˆ�E# ๆ›—บขX๘qใš™ซ๐RlsK@sCDYณhั"๚ํ.CCฝmNv๑๐กรดm๋&ญฤฝœˆˆ��ํ$ ำŽbJฉkฬศแ๚ฤ+ฬีN฿DD�T์R(7ฎ ๗ƒrึธ๑ษU�c6+•ด4:ฉQVโ}ฤ eท�• ์1#†ำƒ=hš็u„Z�Œbš‰Œo""ฺYทv-ํึ:eส;L3๔ส ่ฎXนฦ‡ุirืnศœ&Ÿ�่v์ฒ็ณ_Cu c'�เบm›ึฺ�,ฮกฺ๕&ทฦ�-š�ใ6o|ง3ไพสVxล‹ษ‰ฃ‹i~ศฐŽอ3eฤ'Šด˜Wธญ\พิrกฬ•้†•0�qr/ƒŸ๓qฯ‰ศฤว2ปŠž)‡“œ”7M:sไฤจ˜B๕ะn�eชfO—ืœต3("�m`�พTฑByฬษ}&ร@ฌLr[‹ฤ;Vฯ3gอ6Iญcƒ๚๕๎Ja†๔dE89y์ฐ^งภญw้r-ซษRฅา+๚ร \s๒ฑˆ’='T‚”ผ]อฅ†<š#w^Sคืัฌฅโ’ˆbึ๊•ตE'B.๎eว๖ญ–*dษ2ๅฌwžๆ8Nๆตท#/ฝ@rq5็ถ-7ๆ˜sฦ+7๗›6ฌ๕ส 7่+Vฎฆฅ‹่๐eหWะ€A�๏Rจ๏ฆW7.โšˆh๚ ช e�ํิV3Nว5ั|จƒ๗bื;1บ)P’ํุนซ>7ํษ๓.,�w3’1:15H7~0๏TชT‘ +ื;”บ37๔ืnุ >–Yๆ3พ๑tr.‚€ ‚€ เA@ˆˆาA@A@!"&(�Ž•งฯฎ)7ฬWA‡[† P•๊5ิFP2|ๆ“ำดq�อ‰B…‹Pฎ<žอก-J-โใ>ิ้ฑ�k ๙m{�๕ท๒ฯ^ˆศ… ทp""\ํญZ}sฬแ5cS—+๏ ยPBส–ํ9ํช .หŒืeศ“/!์xŒk"โฎ�ดB*‡"โuฅพ3nยpไช"ลK้qˆปสรธu๊ิ:Ÿ๙ปฑ๖ํ^ื—ˆˆภ้พ๛๎3ู,UE+ N8ษฬฑ“ ฆิธฉGฯ^ฝ[š""'nM>ƒเฮ5\ณAฤ™๗3ค—p‰ˆ�๑น๓็ฉJตšŽMๅไcวŽkล+ว„nSjวผO:e'R˜4P8รๆ?ฬNฦุน=ฦr%Laะm?ะฉ๔๓ฺŠไWพ\ส๚่ฃึ๛eโqด“ๅ8‰›� /ๆษญ๓๋ื�๕"ฮX!ž,š?—žSJฎฦ@ู่ณwญ]ป�K)ฮฤ�ซW,ีฎ— A/T"bž\น”zc%ๅŽ๛aJ“6 %WJุ0% 9uœ"ณฬ˜9K‡ใ‡+ฯ8า{๗๎งcวŽ๙(Z™nœlXปŠ2fฬจฏ@>�ขžอ‘ฃวu^๛<`ฯ฿ื†๒�ท฿Q้๒Pำ>.ฎXตš๚๕hขผŽฆŒ๘$":ฝœฤืเ` †wห(ฃจQช\ฏ๖๛ป่านี{ีCฎ3.`ํi๋Wžsฟ˜ฯMœ์4}ฦ,?q’Oภษ็วs™๙็ฦฅ8ฮก�ถV)&„q๊wj+ฦaำvป2ดi๓์ำ)—RๅSIฌ็�=จFตช:Š?gงด&Œ๔fฺŠsำพ$ษ’j๗�ใc?๏? \—(]IผŒฦ�m&M\๙<์O%j‚ ‘ยš4mApŸใDฤM›ทRทo้p๓ำ„ท‡4ฦ"/MกุซIX'OพK+WฏถTBOœ8ฉ]%รE๘t5ž›#์s'๊ ๕�tj_\ร];ตีŒำqMD\นz ๕ํ7@7มิษUทM˜๙@+’w3’1:ฑอณลธTกB9ชXพผRๆอf‚๕1.>ุ๒ช@.A@A@๘ Dฤ�ศƒ”�A@A ฑ" Dฤฤ๕ไž~ Xp@IDATๆY*scƒ๑ืซฟาŒ)ž ?จ 6i�’nปํ6๚Qm ฯ›3ำบฑฤDD g๓ภบQ9XG€6:�Uˆ ฿!CjีCi๎คhcO—DDพoฏื้์PE‚"�๊•ห4ก ้ธ๊Žษ‡ ดA�=ฎ,M๚ธฤบ fWHE๏ฟn�Mไฑ[\yฟณื๋tอื฿N๑fœg�u๓w†)ษาeโ6ฬ„q"๛ฑ#๕šฦ#y7#ฃ;๘ขTฌXZ4kj}$ƒp!"1A@A@‚# DฤเI A@A@8D@ˆˆqn�พใ›šp7sใวŒิตผRน*e}์q}�นRj๚ใฯ?ฌฺAN|โษง๔56.ฮŸ;K+e“ํ1[ฌ4 }๒๎๑#๚žยูฯ—7/AกๆไbYG8�prู๋m;8ช~S๙ไd'7ค9>oโ.^๚�กe7ƒ@๎๛๚›onฤใYฟพฝฉ๒+u‡ี๊จช�ไ“3Ž=นฆฉ็ƒฟว`XkิoุุฏŠ+Wํmะจ ฬธbk‹/ ˜ๅ็Ÿฏะบ๕uN{��่ี }๒ฮR๓J๎�นtธฟพDDŒW†|็4ฟก|ฮ‡ปbธ-†q"ขำ'e„;^"o(f”CกDzF๕+(๕ฦฤlฃูjN_ผภC้8wฎœบXพ0๕„๚nš|�—DฤHึ฿ผๆ�Œ๕แ�_‚›ฟ3L๙œkย N‹[`วะ฿"b$๏f$ct0"ขQฃtR 6˜r�Hื่ฆL7GผซpฯŒc๐!7|d‚:TeลA@A@# Dฤภ๘Hฌ ‚€ ‚@# Dฤ88Šo�กฃvฯ�๏ฟ�าุQรu pูœ9๓ฃฎkร&๑ฅ„-&DฤhyาAภpˆˆU*ฝBPคA9๐5ตแnW�1u๑ADฤฆฮ๘`Zฺด~%Sn)กธ๗ญ"W=๙„‡ธoั(ม�๕ษn]:k’า—{8ท[Bั– ๅหา �uณp/eสฟข]‰# C๚๔ดiรZ์็๚๕๋T PQŸwืไs�L๚@GNผแ.bใ›ˆhฺXI)๐TUช ฌทฆ&ŠaP ]ฅิฒ์ใฺๆk)}บ๔:)\ฮ�ใMมކˆl์Zบxศ ใส_ฆ|N\๓GD4iAส+Yข•-[šฒdฮl‚iŒ"g"‚ฤ”๗ฅผTพl*คT.“'Oฎ๓โ]หฏ๚OB›!Š$6"ขน?OAไƒaŒ�ถe“>ไ6^'`?|~w๊?Hj�ตใoŽrฝศr{N9ูษ i„I'a�”๕<%�…โ0ทwOพ๋„Eจpตi�RW3m๚Lš0i2ฏาี9ศVห–,คดiาxฅ�๖�oฉZฺŽc””อ�ู]{ย.ฒgŽ@„?~’5๕Vu@ND�๊ซฏจ�+U|rp"ขำzโƒˆศี‹ ัห�Xฎ"วI“ฑAD4u…3^šgjสิg9ฬค7๊ fอjย�฿C}7My�—DDิc๎%ิ๕7oฃ97c}8eล%1’w3’1zๆ๔)”'ทGYืIa๗ฤัC๊�“’j7๎ฅห{ืKsไ�0ฎ‰ˆxงฐ๎*ญ>โฒ—Xห๎�ต›VฌXeนZ7m”ฃ ‚€ ‚€„ˆ่‰A@A@ˆ„ˆ วbI“&#a*ีรIใ=JGฅห–ทT}ช๛฿�(i’$:D ฐก8QนูŠ"bด< i‡ เ฿3› �)|ฏฐq |ุุ๑iๆฌู^‰ธ๚œ?าฯเfƒง7็œ�TซN=ฟฎBW,[BP’ƒมu'”เ�ศ^ }ม8yสไ…"TaˆˆCคฒg7ูhฦ์9u•ุด`Šˆ�uศOฏTฎๆ—ิแ–€Œˆุ๓ญ๎Tฃz5}›_~๙%UจT5ข[๖GDDก�Y๑J a๗๏ัnเp๎ไๆะธJD<'แš[BัCdร9W๊แฎ]Aจ�ถ}’xYEE๐1D4ŽW"uแถุ๓9]๓็รว™„""š6‚ Zงv *Sฆ4�฿}&XกTuเภA๊ำo€E๔œ6eฝ”ืCึฺˆˆ�� ๕�ŒdŒๆc}.ๆsu EฤP็0๋a„pR �หŠ๐�Šž}ๆiŸ\่�kึฎง•+W9’ถ}2H€ ‚€ ‚€BD๔‚C.A@A@โ!"ฦ7โม๋Kr[บ�๏uว„Pฯศ˜)“Ž๛�๛Kzำว1! „๛ำ67\H^นr…f฿p?ษ’$๘ฉ�HGย!"rืyN.l๙fu\‡ HPฯAษD'ใฤ'ฒŠษuด_๙ล"xิW๎LAฦ‚ิ…MbcPAฺฒqๅR,n๖@4„Š@Dฤช•+Qว7:ะ�wงาMp"ค˜ถแ่–€ˆˆ๘fง7ดบ`’$๙={ั† E/^W(็ˆˆv๕ES.'ฺ ์฿—*V(ฏฃเ†ณY‹›คธก…ซDจใ€VธHqฟ›ขั@D,Qผ8แ!ะ�๙็ŸTบ\EM,แ*žœ๐g๐ภ‘ซฎ9ฝฟ&ญ�~B\œ._พส‘ˆ•ฦล ็[$ฎ’–ะDDsฏ8b,{๎\9sZ*žoุค8qงฺMฒ!]บt‰jช1แ๒ๅห:ฮ� /fฮœ‰v+’?s;vํ฿ณ“Rฅ๒ผท†คbส,\จ;ส\’ˆˆ1*ฅ"ฎ9นฝๅฎMแพ๕ํ^ฝญrp‚๑ไร?๒ ร๛T›ฬ{‰*คOแarŠำุฮษ›6o%จฯ9™qa๙�oฟ+2^iฟ๏พ=/Ÿ# * uษ@ฦ‰ˆpว …AcxOึญYฉฌ๐AQฅ`u๑โ%MำงNฆผ/zo��3clบp๑‚5‡2iย8]ิ;หWฌ์ี_๛๔๎I˜`‡กๆ-[๋s�*ู‰“๛@สฉTตบWฆl�๏#2hWำ&ฬC%u™|กํ๓8Wืใeก฿็ฯŸbถyM๙X๚ใ—ฉš"ˆB™wๅฒฅึ|;z์8š=วใjื”™3gš3sบพฤ‡cอ[ถ๑q๙Œ:๑กรสีkL6โค.๎บ�Jpใ๓ูQ5วลVN”B{_ๅค8Œๅ*x๚„ฝ\ใNแญZทฅ�ฺ“ผvCDD[wl฿ชIท(ฌ�h—RJ3ีA(Jย์ชฌ‘#/ั–P๛,ึ› คใdsธฆฦ:��—ท๏ุู\ZวP฿M+#; ‡ˆสx๎๚›5ั:5c}ดัภp฿อHฦh�‡�c)๎v>1ิ9ฬz!œt๎ุิฟ๙๗ๆูwv์ ๅŠ|่ฦ-}UIRA@A@n9„ˆxห=rนaA@A@ข !"Fื๓x�…œTคXqบt้"z๗$}ฅTขฎ^�•2dศจิ-ŠPฺดZ ^ณr9}๖ูyฺ๋฿Ib""โ พศฐ‘k฿ุ”^โA |ย!"๒3จ๋ฌT.Lw๏ูKท+—อš4๖Rฝp""B๐แ‡ำYฎVญ2Qค6ื;aล�ไดรŠP'5kT'lฤย ป_ฉ—Aี่฿�Nฝ�พตม…ํอ›ึำฝ๗�ฃำž�์3š={.}๖ล็”๊ฮT๔ไ“O(wฅeด;฿UkึPŸพt:�p• lบ/^ด”RคLAฺตีnpMยh""b“oKLŒj_:ส˜แห3ฺ eษ€ฑภงkื7อญhwิ ‰ภ€ีฉ๗= ’�*=ว†กH๔�๛QฦG2(2}F k”แF5้‚Y ""๒r’„)‹9๙๑{๗ํงjƒ?mฺ4z“8ภ�m๚๋H๕ DDด…“š–.[กHPใh๏๎šศ„xIœHhœดส]>†�ธ‚ž๕�ฝ{้�็Ÿ๚แS๊�ชUณ�w๏ฝhูี‚8๑3•็ฝS๏๋tN?|๐!-[พย)*Vระ๗1ถ”/_–าคNํEDDE[7ฎง‡ำ=ฌ๋ผ�ำO4cๆ,๚่ใำtWส;)งRฑช[ป–"๑}ะuช�ฑ‹“บ-ฦฺsgฯQ๎<นจIใFt{ฒdึฝ�‰ˆ €ิฌQŽ?N[ถnฃOฯžฅ;๏Hฉ๓ึฉUKปซGๆƒ†xแŠ~๕PŒ7mVnOะ๗฿Oฯ<�4•+SฦR๊‚๋YธOh3ไ”Hˆˆ‹ๆฯฅ็ž{V฿Šqอ�ำO—ตบ๘Y…๗™Oฯ:�&'>ผzอZ:}๚๚C)š�ฃศ„11�ฝ๒๑wปv๏ัฎ(๏Ju'ฝัฎ=๘็o€;vR‡N7วdคลผ %Tธฺ„�ไ อ[ฐ€ 6๛ะCQ๑ขEฉฌR๖ด�—-Yค฿Cไมx0aโ$๚๙ส/TฒTqEBฌŒ`m��r†CvโŠnx็g+’ๆปงN้zฒ>๚(+VDทพPmฏTฅบ็?ก’บx�Pฯ99๋(ฬbn๘ๅื_(cฦŒZํฐtษšว‰ทhใค‰ใ4)๋ถ๊ƒฐ=๛๖้๊A „b2 คฉ&อ[X๋จ~@$ก†z็-Xจศƒว่ouŽ5ษk๕_%ใrๆyIงม'แํ\ฝf}wแ;ฅ๘ eWJŒส—ำnOนโฆyง‘†๖ฮž;:BO>๕„Vอฤ฿’0vฤqB4W(7ช฿|๛n�O—ฏ๘Jร]๋๕่ึ…jืช‰*๕šeยฤษz‘Mฝฃ ‚›ถb์7a’N‡�>ฺใ_๏ี:ิฅs'œR฿�๕xช/ิOธใฅษjŸต?“ฃวŽQ“f7แv’นฟ๕e8๏&๚Tถ็<Šh;๚Lณฆ๕m€เผHญql๑ะnกŒ—ธฯpื฿๖zอX๏†ˆN฿3ๅ/Zผ„† กซ7a\y๚ุแบrืแแพ›จ$�1บIฃ†ิพ�๋บ ๅŽ›0‘.\ธDล‹ฅสฏTิแ๘ DDไ๏Œ›9ฬ*4„3n /A�p๚ C’กI*‚€ ‚€ เ€€@‘ A@A@๘C@ˆˆ๑‡ต›š@D,Vขdะคg๙fใ๚ตAำ!6d‹"ข›‚BŒ|!๏)I#DŽ@8DDิส7"ํญ€š“Qฬr"".˜;Gน๗ปนjฯฯฏ—.[N{”฿xธ9ท;L8ิ๗ ยg jg}z๕ด Mธ�h'"B-คณR๗ƒR^ ๓ทQŒ<๑ญˆ่ฏ๏+Baท{[n M:NL3a�Žœ�ฦ‰ˆ�าใ9 <$V6ƒ๎ƒัฦทบwีฤ8ํฉขY๓ึŽ>“'ZˆˆP2ƒข ๏ู่qใฉ{y้ซฏฟึ๊gฆอ๖ใฎwb4ษแ <๘ไ„Ÿ=Ÿนๆ�€Mผำไ—7:wัu™xND4a�ŽvK้b3ไ›นˆ=l่`บ๋ฮ;yฐื๙๑ใ'‘ุอุeณqฃGz•ํ๏ย‰ˆXซฆ/ษ‹็๙ำNณdxz~*งผผpฯ Q$""'Žู�ฬu.w้nฯห�ฦ"ฮ฿3็๙ฎ^ฝJ 7u$?ยฅo‹ๆMฝ;y^œ�‰ˆฏฦŒก]�ำšk"�u๐u!Œ๘pศNPขœ2iขๅ>ืิc?:๕?ค •ิe/7ิkN๘ ”ืAๆZฑt1ฅN�€Nพ`แb6ย๛=ํ�งUฉไ!๊^๘๎Uฉ^ำk„’,\ซ?๒ศ#~ซA‘‘ฐ[—ฮZmุoฆˆˆ�๒โรƒสUk๘‹ึฯs�šUŽ๋('ื�แฎ๕€๏ฒล ิGi�ถsu๕uผ0ๅคชpˆˆแŒ—ฆแ๔ู�;ท[$�™ณfำุ๑uqƒ๗๏�eฝ็}๛ ๐Rฦ4u†๓nv์ะžพV฿๐่๏#’Pวหpื฿๖ฦ™ฑ� 1œพgส‡ˆˆถ†๓n"_ธc4๚ WEYฦ0vาz ""า‡2‡™๒C9โ}~PฝหNคึPส‘ด‚€ ‚€ พั A@A@ˆG„ˆ`ปจ*Sๆ,T๑•ส”์†๒„=ห฿ส%ไž];่ิ{๏ฺฃ�^'SŠ8ฏท๗l ^Q๊<ณgN๓›6ก"ํ฿kฉ๏kƒ��`ฐ๔/แ#ภ�ฏฺb•ŠMt ฐฦ *ZcวM ๊ีชR6ฅดrๅ็ŸฉrsหmฦดษZู‡‡๙;‡KCธ6๔gุˆ๋�ญซR๑หกTถƒ\ฝฤไ…หิ~}z*d6‹(iโ@ไ:ฌG‹.๑Q๕™ ‹ฺ��๖๎�ฆฒํใ๘eศR**D%Qข„ส›9C*BๆB†R=อE™็™J™g’yž‰๔๔คe2O™฿u�งตฌ={๏3ํ}�ึ๛yฯ^รฝฆ๏ฝ๖�ง็�]ทžหžดสำทcวšกZu�ภมCฬะจ๖v๗ซ{ธ\]ฏlึ?:ว็คมษว;๗ฏวV๛;vZมรVฅนEซๆ๙›�ํ๋ฏ�aณL๙ŠN5Ewu!mฏA3ญœถCฯนsง,XฐP–ฏX้๏Paญgศ›ื์hXศมƒ๚›‹}wร^งažฺตj:C๋zฝ7ญธงก๚พhฺคฑ”(๑”�{ฯ=~OฉC๗ฑ*ฑูC�š6idชqูหฑฝ.ถ†:n๕๏๏:ฑตKŒm๖pิE r�ุoŸWC ร‡”ษVuผุฆ`?ปjTฏ&ญ^oแ๓ผ�ฐqฃLถ๚Y‡yึฉ[^ฆขฌ}Nย๔•บu%๗}นœ@‹ฝMŸ+ญ’ุญGOฟฯ{Ÿ^=คเ#xœำ�W๏o๐กขC:GยดvีrŒาŠต๚นเžดบๅฬ้Sฬ�_ํ=ก฿eตkืด๎๛aษ`…Lํ๐นป๊•๛ุ๖ผ†,^oัLŠ~ิชD—ลRึ฿๐สvQซ…N›>�๚žฌf†๒ตฅี [[Cัn�ถ�^ๅ๓ชฯ\็ฮญ๗๋ฝ>�๔๑๔ฐพ/ฝ�1~n~๖้G>๏Oญ€5๊ซฏอg€ฯม�]ั๎ึ๒Jฝบๆ๓ฝฦKต�$�ํซฯwg+๘]พ\Yง‚�N‡#ึฯ�™Vลอฑใฦ�ซWแๆ„๘�tNhอ่Pธ ญ c3�่^mๆตโ๏’%หฬ{LWธร\ฎั�n๑7ู�ญ�ผƒยv{ วWตช—ฅK—ฮ^e^๕wŒY฿}็Tfsoิภ]วŽํอะึ๎๕:ฏ฿_หWฌ’Aึ๏$vE\ํ ญrช“~ซกB:ฯธ~wฏ\ฝZฺท๏่์3;x�ะ฿ฃ4จ+%K”›2ft~—๒~ห๏zzอ_|�ล๚N{ยใ๓K฿WKฌเ์�๏พ็sญ๎ชว� 4ก\๗ๅปร๛:LปืnOq๙ผิc„๓ฬ~๓ี(๓{ฒ๎๏=,๘”Iใ๗x  ฮ{S+J๊๏@มL›7�$u^iเทiจŸ—แ��ํ>๙š•หฬ็ซ๗�๎6๖|8ฯ�บี+L`�bตฯ้ �ฎ”ฎšตขฐ{ ๕ฝi๏๎gด�รˆฯ>๙ุใป๚ศัฃาว๚๏ฐฦHถฌูLe๓ุฦก|‡ูืห+ € €@dDŒŒ~เ*@@kV€ bdv�อ™2Iฮœ๗ศM™n–ิฉRษกฟษŸ�ทZร‹ฬ ๆช@?๔ศ•+—๕วมt&X`�แ�OำˆZฅี฿๎น;งœ�\ธ็žœr๚ฬ?ฒ}�Ÿ>Gใ๋ฉะ Kซzฺ‡๔ผj '๗�นMŸ่๏›๚ญŸaม๔‰†S5เ}ณ๕ป๊qk8_ 5k(‹)<;˜ฆ๖Z]O' ๔dฐ†f�๑วอฒ� ฌ�š'oษj ~ไะ๙c�ึซ๎ฏ๏ฯ‡|Pt(ุ่†œ๚"‚lจŸตy๒�'V๒อ:t_ะฯ_‡ืf2ฮ›'ฏ�hํท†9�ฑk็U]ใใิ(ท5�vสT)ฌ@ฐ+จ฿1๔ศ—/Ÿdน=ณ=rTv๎�ํ๗�ฉํ์ ขุีuEญgO��zkXเ`>โใ>ร9† ๕9฿ตkทOศ6œใลถบ„๛y�qูvE œ฿ฟฏ์sมพ7ฝ๏&�ฯh�2ูณg“฿~�-จ�ž๑>/ห € €ั)@1:๛ซF@’Aฤdำ•� € €Dก€ฟ b�Fฤ\๒�Vp๏แ‡๋z–.[–(รฐ..žw๒DŒ็Sp8@@@D ˆ˜ศเœ@@ภS€ ขงK € € €@b DŒ_mึ๘ฅk„uะฯบ~!cฦŽ k฿h�‰ bด๕ื‹ € €\]€ โีh € €—C#€ € €W ˆx 7D Œ bpNดB@@ขI€ b4๕ืŠ €$C‚ˆษฐSน%@@ˆ1ฃฟ’ศ+‡–าe+DอuG๊…�rห-r๗�9รบผ~ุึ~ัธ“—,š/ฉSง– Iป7;Fใmpอ € € €.‚ˆ. f@@_€ bโ›sF@@@@@@@ >"ฦง&วB@Y€ bศd์€ € € € € € €D”Aฤˆ๊.@ธ๖"^{}ฮ#€ € € € € € €@๒ ˆ˜ผ๚“ปA@ขN€ bิuŒ € € € € € €xD๔เ`@@ ฑ"&ถ8็C@@@@@@โW€ b�zr4@@"†Fs@@@@@@@ ย"FX‡p9 € €ภต&@๑Z๋q๎@@@@@@’›Aฤไึฃ� € eฃฌรธ\@@@@@@@ภK€ ข‹ € €‰+@1qฝ9 € € € € € € ฿ใ[”ใ!€ €„$@1$.#€ € € € € € €'@1โบ„ B@ฎ-‚ˆืVsท € € € € € € �"&ฟ>ๅŽ@@จ ˆU�ลล"€ € € € € € €>}HX € ˜S›s!€ € € € € € €๑/@1�M9" € €@CภJคฆeห?#๗็ษู๋>$cFๅัๆพ๛๎—๒+yฌ๓^ธp๑‚ ๎฿ื{5ห € € € € € € ลฃธ๓ธt@@ 9DŒผ^ฌ�bMน+GฮX/์ิษS2dP?6?๒จ”*Sึc๗ยๅห—ฅW๗ฯฝWณŒ € € € € € €Q,@1Š;KG@’ƒAฤศ๋Ewqฯž�~/๐ภ�ฒhม\m๎ โฑcGๅิฉS�uแ�นs2eโxŸ๕ฌ@@@@@@@่ ˆฝ}ว•#€ €ษB€ bไuฃ;ˆุณ[ื /ะD\ผpl�a}ะ๛า@@@@@@ขW€ b๔๖WŽ €$ ‚ˆ‘ื#ฏOธ"@@@@@@"Y€ b$๗ื† €\#ฏ“ "F^ŸpE € € € € € €DฒAฤH๎ฎ @ธ"F^'ปƒˆงOŸ’4iาสฅK—ไ๔ฉSฒgฯn™3{–฿‹vอ|๎�9I™2…iwๆฬ?rไะ!™๓�wr๒ไ ฟ๛ฒ@@@@@@ขW€ b๔๖WŽ €$ ‚ˆ‘ื๎ ขฟซ;{๎ฌฬœ:Uv์๘ำcณ;ˆ่ฑแ฿ 3ฎYตRVฏZแo3๋@@@@@@@ J"Fiวqู € €@r ˆy=iตโษ'ไยล‹rใ 7ส3:{�ชx8 _oS)ั^i5จx๒๘q๙็Ÿ$ร๕$ใอ7[ีSšf—/_–q฿~-{๗๎ตwใ@@@@@@ข\€ b”w — €DปAฤศ๋มlูณห)kๆฃGŽx\\๖์wษ๓ีkH๊ิื™๕ฟ�บEfอ˜ๆดษแน-sf๙๋ฯํฮ:น>Cฉ�r='ศxย 7<ภฃ  € € € € € € ฝฃท๏ธr@@ YDŒฎn|เม|Rกbesั'NZยAม 5คุ๘ีfฆ2ขั�ปวัuใ\- € € € € € € ˆ†  € €‰!@11”ใ๗ญ�พi….\พฝบ}๐ฦM›9UG "Gผ*.} "€ € € € € € €@D DŒจ๎เb@@kO€ b๔๕yห6mอ๐ฬกV6ฌWฟก�z[fsรำงN–ญ�}7ฯ#€ € € € € € €€ADV € €$ฆAฤฤิŽ๛นRงพN4ˆจำูณ�ศ€พฝƒ>hณญ%]๚tฆ}ฟ�=ไ�๙๓A๏KC@@@@@@ˆ\‚ˆ‘�7\ € pMDŒผnN•2•\ผtั๏…UซQSrไฬiถƒฯz]q้า%๙฿ฯ�•ysf๛�ฮJ@@@@@@ˆ^‚ˆั�w\9 € ,"Ff7�œ)“ไฬy�”้fI*•๚๛�น}ซณ*ฦ6ฅM—Vrๅส-™2�"้ฏOo†j�๙ืŸฒw๏�ุvc € € € € € €DฑAฤ(๎<.@H“C/r € € € € € € p- Dผ–{Ÿ{G@"@€ bt—€ € € € € € €ฤA€ b๐ุ@@ ๎ใnศ@@@@@@@ค ˆ˜”๚œ@@@"๒ € € € € € € €ั-@1บ๛ซG@ข^€ bิw!7€ € € € € € €ืธAฤk�เ๖@@ค ˆ˜ิ=ภ๙@@@@@@@ธ DŒ›{#€ €ฤQ€ bู@@@@@@Hb‚ˆI�œ@ธึ"^๋O๗ € € € € € €ั.@1ฺ{๋G@ข\€ b”w — € € € € € €ืผAฤk�@HZ‚ˆI๋ฯู@@@@@@@ธ DŒซ ๛#€ €ฤI€ bœ๘ุ@@@@@@Hr‚ˆI�\ € pm Dผถ๛ŸปG@@@@@@่ ˆ�}ศ € €Q-@1ชป‹G@@@@@@„ " € €@’ DLR~NŽ € € € € € €ฤY€ bœ 9 € €@\"ฦE}@@@@@@@ค ˆ˜๔}ภ € €ืดAฤkบ๛นy@@@@@@H“A'r  € €@4 DŒๆ� ๎ฺoบ้&9sๆŒœ;w.ธhuฎฟ^าฆKgฎ๛๐แรQw�ษๅ‚‡ (2� ?��ณ|�i—ไr[�G„ ไห๗ dห–UnฯœEŽ="[ทn—_ถlน๊ี�rห-๒@ž<’ีฺ7UชTฒsวN๙ๅื_%า>;�ŸkWปฉ„บ๖7�ท•G ”ณ��#๕5 xตkี”ฆ๚l_นjt~็]Ÿ๕ ฝขF๕jRฏnmsš฿๊นH่kโ๘ € € € € ๐�˜3 € €ฤ"@1œ$ฺTถ�3ržผฑž�๐แC2f๔W�”xบดไษ›Wางฟ^RฆLiฺ]บtINœ8!ณgN“ฝ{๗�7)7h๐คฮห1แ‰ฅห–G|xขฎuญื[ื�๛ึญฒpแข$ฃ›?wถdษœY._พ,�Wฌ„œ:}ฺ็Zส•--๗�}œถถ}�อท>�#iER<๊*๖�gF[>� ฏf๔รบี’:uj+ˆ๘?ฉUง�ีš_3�#ๅ}’ภณgห&52ฅJษM7e๔นฅ�๛Hฟ�dฺŒ™>�ช=�œ<�\UษŸ�!I‘"…วv�์˜3wžt๏ูK๔‘0M7F๒�Ÿ๛ช—�็�UwพJƒ‘ร†JกBMซ l�ฒEsiโ'ˆธ~�iุไี€๛%ิ†ึ-[Hฃ† ฬแ›ฟ�J–ฏX™Pงโธ € € € € A#จ3ธ@@เZ ˆyฝ^�ลšrWŽœฑ^ุฉ“งdศ ~~�ิฌ]G๎ฬšอ๏6]นb๙RYปzUภํIนกุ“�'๚๕1—0|ฤH้�ทR^ฮUฯฝyใzำfำฆฅ^ƒFWmŸ ^zฑบผ�V's่๕~†›๚=อ่/GI™ฐโร๑�&RV&ลsะถMkฉ�J]C๐๊k-dีš5!sD๔O ๏�W}k_ฌQ]�้๓~ํ๊{๗้'รGŽ๒h2๏๛๏ไ๖�ณxฌ๓^ุฟoฟ‚ˆญ^o.7�pƒ��วV™0qR์'ผ†ถFย๛$นp�AD�|_ถb…l�a“�นc‡dพํVคอ๖o��๙ ๒B๕—ไฏ9ทn8`ช�๖�๏rๆŸ3RฌX1yถr%งz๎์๏็Hวท�v๖KชwqๆฌูVฅฦ}~/ๅ�๙๓2pะฟ�โบ๒ซ‚d�ผyไฬ™คg๏˜|0วดŸy‚ˆมhั@@@@โK€ b|Ir@@ฐ"†ล– ;นƒˆ=ปu ๚\้าฅ“W›ท4a’‹.สdซšิฎ;<๖ืaš5ภฉSRTย‹‹…6IชŠˆส—“ฯป|jnaหฏฟษ‹5kผ‚ˆiฬ†๘"ฦ~†kwkRฟO’“ผV5ญ๖ย 2bฤ—!CฝGา|ึŒฉrห-ท˜[�ฌ๋2f์8็๖;w๊0$�ผูซ๒Zำ&ฆํมฟ�–าe+8๛%ีŒ;ˆ๘ผUฅq๋ถํIu)!Ÿื~ๆ "†Lว € € € € ‚ˆqภcW@@ธ DŒปa|!� bฅ*Uๅ�}F๖ุ/๋ึญ—กรGXUธ8ืPนrEyกjUณœ"EJ)Tจ ™ื๊c?�๘ฃำNgดZูศQ_yฌำ…Pฯ้sืŠqcF›{ึU฿yWดj˜=้y�{ทณฝ(<๒ฐน?]กแ๗ดฯŽต๓ป�qฏrๆŸฏ๚ฌTxฆผ"5Kๆฬrโฤ ูj๕หด3eาไ)N;๏ •๊Pวน๎อeฃ2™อวŸฐ*t๎–ๅ–M�ƒp๐oyโ๑"rณuฮ_๛M>�๘Sฉ๕าK๒tษโrฝ(๛ร2n�f'Ÿฐ™'�>yฌHำ'นsๅ’๋3\/ฉRฅ–ํ�ทหjk๊@ร ๗ู้]าฆOg=฿›eภภมzzgาเ�Ÿw‘TฉSษขEKd์ธ๑f[คฝOœ 0ฃ�ุฮ๚าi์„ ๒Xแย๒ธี79๎ส!๚ฬ�oห/2jไW>Ÿ=}๛๔” ้ฏ—SgNKหV1C๑zŸย�็?n�์ื๙ึญไมpv0qขฬทภYeๆ�๗�‘ž{ฮ์2aาd๙ศzฎ‚™ด/Wญธ๒Q๔ษโ>ฯปG๛ถj•*ฮ!7YŸ{�๏egcgย "๊๐ำ•+V”'ญฯ œ9sศ-™2™€�พฝ๛d�_ส|หvา”ฉฏฎwn’าzฆ�ำูฮJ๛W��'ิ bธ฿a%Š—zukKž๛๓ศ7� ���SึฌY+็ฮ“W๊ล 5[ฅ\๛zyE@@@@ไ!@1y๔#w €DญAฤศ๋บpƒˆZ QL/^”>=ปE�ธขoพ%๙๓?`ซ็j๏ _บตdษ๒ม{๏:!2ฯ=D4ะุถ}๙แ‡›๎ฯ}Ÿ|�ๅHIŸ>ฝวz๗BŸ~d˜Fดงvoดvย๖บ@ฏ๓ๆ/vov๔ุฮ9=เZxฒhQ8 ฏYณำ ]Vช>ฒ›ท†[ํืท—ฝ๋ซฟ hL๚่ร๗คL้า๗ 4„ซ5X�T็•๚ฒy๓&q}œ…0c‡…‚ูฅJีj>กภชU*[F๏๛์�๓ฯ�“Zu๊๙ฌืะP฿�=|ึZกAฺZ/ว„‰ดM\๚คQƒ๚าข๙kNี๛œzฎ-[๛„vmฃ7ษ+ {์ฆ!ป)“&˜u฿อž#:ว ็I๏ ฐPั ฺv๙๔“[cVkุ๘ร>6\ปแŒi“LฐX—_oูF–._nor^;uh/ตkี4หญเ๎‡๙žgฬ่ฏDร๖4d่p้7` ฝาkืฯ>‘g*”7๛h:ุแ„5ผงC7๋ค๗Z่ฑ'ฬผ๗7�ฝ!u๋ผ์ฌ�ฐaฃ4h์ฦuฤa&� b‡๖ํคฮหตb=ณ†ถ5ผํ=i p๑‚น�ซอr‚…�ฎ๗ทา~฿S1�๏ฐบ/ื–ถึwRชTžกI๏๋!ˆ่-ย2 € € € €ษW€ b๒ํ[๎ @ˆ ‚ˆ‘ืM๎ โ้ำง$Mšดf8ๅำงNษž=ปeฮ์Y~/บe›ถVศ่:9z๔จฬ�~–<๖ฤ�ษw�iB งOŸ–ฝ{wห์™3�๎›”+_ฌQ]r[ี่tบ๛๎ปๅ๑วŠ˜๙ญ�ถ๙T๎›ฑ๏#ถWAD}�๗๎ู+EŠ6ี@u�Sึ็hkศb}ีฉqฃ†า๊๕ๆf~�‚Vเู3xฌฬ๛^2฿v›i๓Rญ:Ÿ_fฅ๕#>ƒˆsฟ›)w�y‡9tหึmeษา+Uํ๓๙{ญU๓%yซใ›f“wึ�>ฉ‚ˆZmsื๎=๎Kqๆgฮ๚ฮ#@k�๙็Yณn์�ฑKNž:)yr็�^ฐƒ{_t๏)_�ฦ9Ž=ฃU%Sงบฮ,–*Uา๙�Lˆ bธ฿aบ฿w3ฆหuืลผw�ํwูธqฃ�•ใ.ับ{"ˆ่ึ`@@@@ไ-@1y๗/w‡ €DผAฤศ๋"wั฿ี=wVfN*;v�้ฑนu�7M8Lƒˆ3ft‚b๎Fgญ`ฦุoG[กC๎ี3ฏร๙่ืว\ฯ๐#�c๊พุn]?“rๅสšU๋7�` ฺฦ ้ส ใฦXCVๆ6�{๕๎+#F}iๆ๕ว๒%‹,งอฒš�๖๛ฮ6ั*Uฟ�๒‹วะฬ ฌ;คตiำRฏA#๏อ>ห๑qN=จVOำ๐’N�}HJ•ฉ€fV๘1๚หQR ภC&T๘๐ฃ1ฦMอยjง5ญฐูฮ’tแยENs �}�แf๙ˆ๕ผ•xบŒณญHกB2|XฬพZฒdฉ˜�qX3�า zฆPŸƒ@ว eฝ†ต’ฃNฏพึยg�`Ž๕รบีฦ,˜ โ˜ฑใLธQƒlhำI‡‹�เรฅ‘ m�ฒ…YWฟQSอSร„แ๖‰๛}ฒn�ziิไ5sl�Qฎ\้ึต‹YึJxซ<๋๑ฬ�ฯx(AD็เ�ฮุวH์๗‰๗uZ๖"ฏฝฌUงMžhยบN๏]๏ำ฿”TADืbฏ{๗?๏{Tชิ lพ‡๒ษ˜1c}๎�…็ชส๛V]�๗หฉYปŽ}ฟฏ#‡ •B… šm Dtฟ7C๙{๛ญN๒า‹1Aq๏๗ฆwD๔�ตฌD@@@@ Y DL–�สM!€ €ั#@1๒๚ส"j5ฤ“Vฅฝ V์ฦn”ญpก=?wฮ ์๕6•ฺt]ฺtiฅ๙๋m์อๆUซAํ�ตKRคษ‘#งฉ–จ4„๘ๅˆ+U�๙L&Lœ$•+W”O?๚ะ\[—ฯปษทVxJซ๖๊Sัฎj็พพP๛d๑ยyrKฆLๆ�•(uๅhkˆ๒๒›ํ๏๐‘Lž:อฬ๋๛๗;้ถ@C3๋6๗d#ุ b|ฝO�ื�ผ;ˆx๔ุ1)^าs8rwXs๓ๆŸฌjž œร๕๎ัMž~บคY�ข[๙๚›om๎๗ฉ๗6ง‘5ใ๖ื๕๎ฐฃป]l๓>ZP†ไT๛k฿ฑ“OEึ@๛๋๏v=ญฌWใฅภรฟับ•4จeุ๑ตVลมฦM›:tœึป‡fŽํ@฿�ฬœ3ฌtlํ์m+—/1Uป€s@IDATฅํv๚šะAฤpฟร�ร‚7k�RVฌZๅพlYฝb™\}zณŽ ข  € € € €$k‚ˆษบ{น9@@ ๒"F^eณ†พ=e ร|ิช&็žฒgฟKžฏ^ร �๖๋™5#&0”1ใMาจ้•*g'Žwย`z *6ตชผ้ะอ:ieต];w˜๙H๚Jอ‚า{ะaTํ)EŠf6•5lฅ=,๊kุๅสU_ฐ›ศฬi“ญ€fณฌC��Yปnƒ5๔zŸ*ZฮN^3กฌโใœ9ญP้ิษใMเ่ไษ“Rถ|ล ฎ7” ข;\ฅทl�ฺฎบฮ�U็�ษดบฺโsuต™ดาไ�๙ dญๅ๚ƒ5�u0S(ฯA0ว ฆ;่—AฤN฿6U!ห”.-=บu5—จร"๋๐ศ ำp˜Nvศ*.}b?ง”2ๅž1วu�pW`ิกศ๛ไlถ๗Mฬ b|ผOœbฦDœ;wžด๏๘–ฯ^›6ฌ5Ufฝรตล‹“~}{™๖:lผ†ruาj‰ีaท5�t้r฿งฺ6ำฟAQ�7ิPดA�ีจr�mท๊๎๒�œนากSg3ตํ�ถฑ†นๆsVภฝvz>ีaฝayฏ๋X฿S๎*�mใฒ์"๊๛`๋��N�ฝ'5ญ[็eษŸ�!ษ’%‹dบ๙&ง‰.๋คื]๔ษโฮz3 DŒหwุš•หฬ๐ํงOŸ‘'ž|ส็า๛๗ํ-O{าฌ'ˆ่รร @@@@’ญAฤd�ต� € ฃฃŸ์ซ|เม|Rกbeณxโไ 6h€ฝI�h฿ั™Ÿ0๖[ูตkงณฌ3ๅ*Tด†ซŒฉzถaร:Yบhกว๖HX%€ๆฎRฬต{Wฟช๖�s๒��๑ู๕๒ๅหฒt๙r0`ฐ๘ ธธwฐCZมVz‹s~๘ม{๒�ณUฬeh๕5ญดฬJqา„q’๛พ\มึด๑ฎ๖ฆ�ดาŸ๗คฌiำgX฿†๚Tฏtท ๅ9p๏—๙ฤ"ถi๗ฆ๎ฺdณร‰Z�nิ๐กๆv์pbธ}โ;นƒrn+wUฦ3gษ�๏พ็lถŸ๑ฤ "ฦว๛ฤน f�ADญHฉ•)ฝงe‹šก‹/\ธ yยc๓œY3ไฮฌwšu๖0๏ตkี”Nฺ›uก=ฤ‚ฟ5�ฉNhXp‡jX�iำบฅูt้า%้�ฮปฑ™๎๏ นฮD|พZ ูบm{Pงำ๗T—.Ÿ˜ช‡ฑํp์ุqyชdLeู@ํ2ˆ๎w˜†,WญXj.YCโๅ+ล|ธ๏A+kE`"บe˜G@@@@ y DL��ห�!€ €/@1โปศ็[ท}ำTๆา@L฿^�ํ๖z ”๔๎3ฌซณัšq‡��sปL™8�ฝ9"ๆC  =[ฅ’|�แๆบw๏ูm i๛�;vTฆฯ˜ๅqŸ%K–†ฏิ“‡สgU‹LํฑM‰ฝ๛๔“ฃพ๔X๏^ฐCZมu฿ธœSCGsgฯ”4iาˆV/+๗LๅX}๎k %ˆ่ฎH๗ีืฃe�ƒ๎C๙ฬ/ZดุงŠ[นฒฅฅIใฦ’็��>ํ5ุดY Q7S(ฯฟ�รY—ุAฤVoด“ล‹—ˆ๛^ํแt�รํ“๒ๆ•qcF’Ÿ~๚ฏผ\ฏพO…๒ๅไ๓.Ÿš๕�ก9๛Oฬ ข^H\�'>7x•๎ โ—_}-�{๖๖ูcรฺีrUaUง {loั�5yตIcณn์ธ๑๒i—ฯeฬ่ฏ$_พอบp+lzœฤฯ‚าF๎ผว�ฺ๑—ิฌU7จ …/:u^ฎ%ฺท3๋5xฺญGฬPรบbํชๅ’.]:ูผ๙ฟR็•๚ฆ�CŸฝ.พ›=Gดขฃฟ)ฑ฿':t๐#๖ธ”™3ฟ๓Xv/ธƒˆV~็?W*Bฺํ์ โัcวคxษา๖j๓ชฯ๘์™ำM˜๙๐แรา๔ตๆ2q�Xณ-นวย\�ๅH)P ฟู[‡ŒฎSฟ์฿เชGำJ|]>๙ุ _:\๚ xี�ปA8ADญจีuาaแ_ฉ฿ะ'˜น~อสD "๚ ๐ฺŽq๙‹ํyิใ๗์�น”.Sํ‘ ข-ฮ+ € € € €ษ_€ b๒๏c๎@ˆh‚ˆ�=>—:๕uขCฮž�G๔ฝRนซ๑ซอๅฦo4�ด"ข�Sแ"หS%JšU[~๙Ÿฬถ†ดษ@ณ+‹บFwภ*˜!6ว{ฝ{([�Vฒtน€Uํ€ีฏฟ�.5^ชๅ}จ —ƒ9ง�๏ผ9฿ษ 7� /^”็^xQดZฐ“;ดไ]ัอ๛oฟีI^zฑบY�ภ q9gณW›JณืššC้Pศญ�ถทิko+|๔๔ำ%M�fอ[สŠUซ๎งร*w๛ผซูฎAšช/T๗ ฏ้Fญณgฮœ‘๚ › P้ก>>' cลค ใ$๗}1C๊z๏๎=�ฉ;๐ไ�ึ฿ฒVึ,\ธpุC3๋1รํ�Wปz 4iŸ4{ฝ•�๐รF&๎€ฆวฏ…ุ‚ˆ‰๕>ฑ/)ฎAD๛8�ฏWซ ุ๎ึ๒Jฝบฮn:ฟmšฮŠ3ก�โ‡sVkˆป้kอe{(ygE,3�•1ํฆ‘Dิ๋t_ํ๋ถ_uX{ปฺญฟ b(FLœ;ฯ�๎9sไ”๑cG{ํkx�ƒdฒtถงpพรt฿ž�?—าฅJู‡ ๘J1 @@@@Hv“]—rC € €@t DŒฌ�สy๗=Rๅู็ไบ4i�^ุ๙๓็eฉ5ฌ๒ๆ7๙�ฎ+ ~Lž|ชธถฐjUท% ็วบฏ�6ฉ_ต๊ื3สหํVฅถ›nส่\ฮ{๏(SฆMw–ํ Ku์ุ�ฉถgฏืWญ๊ต|ล*4xˆ์ฺฝ�ูิงW)๘ศ#วท7๎�ตK*ำgฬฒW|}ฒhQฉ]ปฆuฌ‡%C† N่ำ_h)�sฮš1ีนทธ„J4ำ A])Yข„�”1ฃ๓Œ่�Vช๒œฯ=jxฒ๓[ฅ|นฒฮะฝv# นjลต™VEIญฐgO:T๖[;J��๙|๖ั6t๋ีทŸว๐ฟ๖พ�ฏก>�๛‡บ|ห-ทศ๋-šI‘ยZU4ณ8!" /UจTลฉbฆวีanG ิ)ฮ;'…�?)Rจ 6ุ์๓๊k-L•Dweณื[ถ‘ฅห—หy๓สธ1ฃMป๖;yTc งO์‹ิ[M+ิšๆบ๋์UๆUซ๊uzซณl�ทb›วFkกฑUIฎน5,x๊ิฉM:ดvฯ��ฌ!ผ?3UX'M™*|๘ฑณ�{&1�'๖9›6i$ฏ7of/šืุชˆV|ฆผt๙๔ำN฿๓…ญŠจYณfu๖?�‚|;fŒt๏ู�Y็oฦฺ Oฟ��ปขฯœ{า๏‚�}๚Iuซยe~ซZฎฟ> ึH{ตฯb wฐ‚๒yr็�lฑ'๏๗ดฎ็;L๗{๛ญNRอช4๋~oj8|ฝUๅืฎไYฟQŸ€ฑ๎ห„ € € € €ษO€ b๒๋S๎@ˆ*‚ˆ‘ู]7gส$9s�#7eบYRงJ%‡�>$n฿*วฌpKฐำ-ท�*yxะj~Y��ถU๖๎�์ฎQ�NCZ๙๒ๅ“,ทg–ฃGŽสฮปๅฏลz?น๓ฮ;ๅfห๚๘ัใV๛W�'ึฑ1”sVฎ๔Œ|๚๑Gๆจ[~�M^ฌY;ˆ3ฤ 1ๆษsŸXIKูทoŸl�c›œ:}:ึๅห๗ dถ†ลพแ† r`�Aใบ�X๗ac๐แ๔‰]รข๗Y•Yฯ๛ฆผj?๊>๚�zไแ‡ๅฆ›3ส+Lš�ส๛Dฏ1�ษD์ำo€ >Bิ6�eฯ�}A‡ธ:w๊ 5_zั\ฦธ๑ๅ“ฯฎ ฯ๎ตฑ_๘ูณe“\นrYโt&4l1�3ฦ}ฯpพร๔ฌZํ๔ถ�n‘อ›�t`3๎Wห@@@@@ า"FZp= € €ภ5&@๑๋pn7๊�ีา�รKG�$ภWญRYาคM๒‘Y•ั.\๒~์<�CฝSญย7u๒Dุิ}ซฟXS~๛�PC{@@@@@ย ˆ6;"€ €ฤ‡Aฤ๘Pไ$œ€Vfห’๙6s‚u6$�‰ข์ศZ9lีŠฅa]๕มฟ�–าe+„ต/;%?ธ๋ผ\หTO,[ฆ”3�ฎ‹�ฐqำไล!€ € € € €DดAฤˆ๎.@H�“s‡$Gธ<(eส=“Yธง0ย "jHxฦดIgv๔จl�ถ=ย๏ŽหK,ล‹K๏ž�ฬ้>๏ึCพ36จS๋pฬณgN—”)Sสฑใวe๓O?ษ€ƒๅ—-[‚ฺŸF € € € € €ฤงAฤ๘ิไX € €! D ™Œ@@@@@@@ˆ ˆQ�มล € €ืžAฤkฏฯนc@@@@@@H^“Wr7 € €@ิ DŒบ.ใ‚@@@@@@@‚ˆ, € €$ถAฤฤ็| € € € € € € €@� DŒ_Oކ € ขAฤมhŽ € € € € € €D˜Aฤ๋.@ธึ"^k=ฮ�"€ € € € € € €@r ˆ˜�z”๛A@ขL€ b”u—‹ € € € € € €x D๔a@@ q"&ฎ7gC@@@@@@โ[€ b|‹r<@@"†ฤEc@@@@@@@ โ"F\—pA € €ภต%@๑ฺ๊o๎@@@@@@’ŸAฤไืง� € UฃชปธX@@@@@@@ภG€ ข +@@S€ bbjs.@@@@@@@ �"ฦฟ)GD@A€ bX4E@‚(Rจไพ?ท�sๆŒ์ฺฝGึฎ[ฤ^4I ๛s฿'�ปu5ง�อ7~bbœ6ัฯQฃz5ฉWทถ9o‡Žoห/[ถ$๚5\‹'์๚ู'๒๘cE|n}ะa2v�xŸ๕๖Š๒ๆ•�๛ุ‹ฮ๋ษ“'ฅrีœef@@@@ุ"ฦฆร6@@ ˆ˜เฤ!Ÿ l๙gไ�žƒ† •๛ฌทWฑ ๏น'ๆ๗๘๙๓K•ส1๏๙ซ5 YนrE็jšฝ๖ช�’)“DtH˜A@@@ "D@@„ ˆ˜pถแูD�ณgท฿รุ@-˜๋ฑํลšต%…H 4eอšอlบt้’๔๋ีC.^บจ)๋@@ H[nนEๆ|7CาฆMk๖8p๐ 5ู๋b …{ร 7ศcึ0ญUซT‘ร‡D า4!›DLH�ซ;น�%K–>=ป›UW "บ๗ำ๙ฑ฿Ž–ศKั†e@@@ˆU€ bฌ>ซ๏%้„xr‚ˆ!‚ลss‚ˆมD ฮ‰V € € € เ)@ัำƒ%@@D ˆ˜ศเAœ.!‚ˆ/ื}Eฒ�~‡9๛๔ฉ“e๋ฟq%4A@ุt8ี…๓็H๚๔้Mณ:ห๗s<+ฺ_๗ญPพœ”(�”ไน�~น5๓m’ๆบ๋ไศัฃฒ}�vู๘ใาปO?Ÿ�๓ๅ{Pฺตimึ0A+\Xผˆไธ+‡?~B�ทๅ5๒+Yตfวพ:์๋ Uซšu)Rค”B… šy๚๕G๋\๎iูŠ2rิWฮ* Rv๎�ม,Oš4Yๆฮ[เlำŽถQฃ๚ึœศภACD‡{๖ž4ฐy_ฎ\r์๘1yฃ]iX�+œ๙„<๒pนฮบoญ๖ฑขร‚ืซ[�z†๒ศ7� ���SึฌY+็ฮ“W๊ี5อšฟ�J–[๗ํ=i€ถBนฒ’ห๊—”)Sศ๙ d�ึm2cๆ,™2mบws ๗9hk=ฏY� S–,™%GŽf�๐‘#ๆ|fแ฿C‡๐yv��รฏ๓r-)�ิSr๏=wKๆฬ™ๅย…‹ฒฯ๚ว9+Wฎ–ั฿Œ‘ฟv�ๅ๚๖�ณHๅŠๅIk้œ9s˜!’SZUว๗ํ�'��๚Sๆ[ฯ�ค)S๖fจˆH†๕ € € € PJ–ใ"€ €%@1(ฆDm฿Aฤิฉฏ“ญฺX`Ni�(�ฟOฯDฝN† €@rp4@Xโ้2A฿ช{฿@;�b ๏�ชM[ูo…๔์ฉโ3ๅฅหงŸุ‹~_5\๘แGหด3ํํ�hํำœ•fๆอ_ ํ�์่l-^ฌ˜๔๋�ห,>B๚๔เlำ yuh฿ฮฌ๛เฃOdาไ)�uaา„q’๛พ\๒ฯ?�ˆฟJๅJ>mtEษาๅœpก}๐�ป’้ๆ›�ถี [�๖ไ‡6zl๔ั‚าปGwน้ฆŒ๋ฝโ;ˆ8cฺ$ึ๓>ฝผbี*iึผฅฝ(q้=H�—kK[ซ_SฅJๅำ฿Œฟ bฯ๎ŸK้Rฅ�57๋fฮ�N:ฟุด…๛|๓ี(ษŸ�!๛0ฑพ~ึ๕ 3v\ฌmBูจกย/บ|&<๒pภ�6lุ( 7qถ๋ณฌฯtlำฬYณฅ๓;๏ฦึD�๏q†fŽ•Š € € € Oใ ’ร € €„'@1<ท„�หD<}๚”คI“V.]บ$งO’={vหœูณB:}ษRฅฅเฃ…อ>ฟY†Y3ง…ด?@@ภฟ€ม�l฿ึl\ดhฑดn��C?kําๅห—Mม?ถm“ฟ��[48Uพ\9ั๊z:-^ผDZฝ๒ำeAฤ%ห–ษ�={ฅH‘ย’๋�{ต™œ:}Zส”ญ`^uY‡$.Uชค5'ๆ'ิจ^อฬŸ8qBพ›�ฝ™ทhีพนs็�‹nอ9€5c�๋๖์ู#ฟo�*iญ฿u ไฯ/ื_Ÿ� "ชร๔)“œj“ฦ\ดxฑ๙จธUE2{ถlๆPปญ฿žฉTี}X™6eขU=๑nณ๎ eบxษRIŸ.ฝ”+WฦTดวgฑyณWๅตฆ1a6ต_o���๏’ฮ:o+„W @~S้๏ีืZุงSŸจฯw3ฆ[ี$S›ใ�jkใฦrWŽปไษขEs่ŒwQ+!j…J{า๊™G5• zิ^m‚ˆHดงpŸƒkT7!T=ฮ�Vฟ<�Xsศญึ3ฟ~�• ‘บr๒”iข�๘š†$Eฌชก:้{mๅ๊ีVe๐ญr}† Rะชฦฉี 54ปf�:ูนc—œ๓แะ�r5ฆม,ฦูžtๆี^มC‡™U�บ~fหš๙๕~–Vug ๘ูำ„qcฌแˆs›ล^ฝ๛สˆQ_š๙reKKทฯปš๙Cึศu_i ปv๏6ห ๋�ฃ›คH‘ย,วgฑ฿�๒Tฑ'อquHํแ#G™y๛‡-� ZzWoดท๋k(}๒๖[ไฅซ›�7n�$ฏ4l์๊อvoH�:/;ห�Aฤน฿อ”;๎ผรlW7๕ณ'๗qu˜็ชฯวœCทววsPฬ๎x@ฟ>ๆtรGŒ๔Š�พŽ๘xีเiทฎ]ฬก4Tุ๙๗d�ฯaลิฏg†^๎�๓ส�ฺอ๗P>3fฌว3งzแนช๒พUฅSง��ฒEjึฎcๆ�� ˆ่O…u € € € R—c#€ €\U€ โU‰ฝDิjˆ'ญ*E.^”oธQnฬxexม๓็ฮYฤํmชลvูณ฿%5jึ6MŽ;&Z&า&ญ๘”ึ Z;ต�l4ดสt๘๐aำ<��’โZ9ง�ถŸ|b๗ัญ‰�ผำ'‘ื'qy๛๙‰หตฦๅู๓฿kW_��‹ฎRถLiำPt�ฤ฿๗ฌ†ต4ดฅำ๓ีjศึm�อผ;ˆxิ๚n/^2ๆ�fฃ๕รพฺผ๙'ฉc๑�Mก„�โ#€ๆ"jว–ญ�๐wYฮบ๋ื˜สsgฯž•๒ซ8ร5� žฏ๚ฌ|๐~ฬะมห–ฏ-[›MบNท้คa@ บง/G “‚1ซโ3ˆ8j๘Pั!กu๚๘ำ.2~ยD3สP๚ฤ= ด๗ฌร>ปงี+–™ “บฮDฬu๏=2eาำ๔ุฑใ๒TIฯแ™๕}ดp�็ฑ”ญPั<>žƒฤ "๖้ีCJ–(n๎U‡{ึaŸใcZน|‰�`UTิกมK–Š ห๚;n$ใ๒yM฿ ัtญ๔‰ฟw‘8Ÿ�ืŠO4�g4]ซ>]ืย็Aด๕‰�w=k@@โ*@1ฎ‚์ € '‚ˆqโKณeฯ.งฌa˜Z�tO*|พz I๚:ณ๚ท_ญa–gฤ>ฬ๒KV•–ฌYc†.\ฑ|ฉฌ]ํ๙Gj๗๑“b^�ฐศ๚cท]™(˜kะ!K[CMj5ญJสค€>q๒„|๚ั‡ก์&๓ๆ/vov๔๊1ุTฉZM๒ศ—่็lะ ^X>sๆฮK๔>‰ห9�รoFzŸ„๛|๒YW๚$@็&ี{3ฺ๚„ฯหตZ?ฃฝซnํปฅ�็]ค\ู2fรกรฅ฿€พฎฒฆj•ส๒ดUฉ/K–,r�ญทJสT)อบlOต๊ิ“Ÿ�ŸYt็ZŸูํ;พe7s^7mXk†_�ฟoฟ”}ฆ’ณ�=J่->h๎ bใฆอdญ5ไm ษ–ำ6:์ด=ูฟ3คฒ†$ฮ|�mf๕Ž;คrีฬ�เA�อวบP็•๚ฒy๓อz๛Gฃ๕ฅuซือb|?�เ=y๎ู*ๆธZ}o��…ฒzํYณvไณฏ!ะk(}ฒfๅ2<}๚Œ<๑ไS>‡tWht�แธน๓ๆK๛|๖u‡`5~Utจnโใ9Hฬ โ”‰ใฬะหzํ+Wu*c๊๒ี& shUษ�ึฐฺ๚^ฬt๓Mฮ.๖{S�aLั'c‚ŽฮFืŒ�:’†fNŠ฿ฟใ๒ป฿aฎ‡สkVฟรข้w~�;ฬซ]‹๚฿ฉI๑>‰ห9๙๏0Wบfใ๚ฟW\+}—฿ฟ]�ฬ"€ €๘ ˆ่…U € €‰'@1๑ฌใใL<˜O*Tฌlฅศ6h@ภรฆL™RZถig‚ญชŠ}zv ุ6ฉ6่ฐ”๓พ�.คำ�ีŸ4LXนrล๖ํึฃ—ฉ2iฉ์ฮ‹—,•Vmฺสw3งI๖l1มฮ`๗ี —ๅห็ ใ์~q=g�z๕ย๒™3wnข๗I\ฮM}๎s๐ษg]่“oœธพOฎ•>แ๓2ภdญึฯ่฿~�#pƒซlq;q๒๙๐ฃOฎฒว•อ๚8b่`น๋ฎปฎฌ 0๗Rญ:๒ห–-fซ;ˆ๘ญ5tl—ฯ}ฟ฿—-^(7�”ัgXg๗แC ฝลGอD,YบœSๅส}M๖ผปชฃฝ.ถWweบ)“ฦKฎ{๏5อ�ี�์�๕w๛$ฤgQร“cพ๙ฺ งmŸห~�๕ท฿e่ฐa2wž็ฐภ๖v๛5ุ>ั�ชKอnา,_)&iG_�•!�Aฤ:/ืR\ง@ฯ{฿๗��PฆL›nฺววs˜Aฤตซ–›�8�‚z์ sม�ะ๛์าๅS๕0ถ๖�*Jบ�Gj1)~�Žห๏z|‡นŸ*ฯy�‹ฆ฿๙ตฺ?�ๆู‡๖’�wjRผOโrN�;ฬ๎=ฯืธ�๏ืJŸฤๅ๗oOq–@@ผ"z‹ฐŒ € จ•;^Nึบํ›&\xแย้�ซ{ภc>Yฌธ<๖DQณ}ฯž�2๎�ั�&ๅ†อ_“ิฉR} ‡‘ฏฟ๙ึ WY่฿!ƒ�y๖๗sD+U{แน`w1ํ~ฒชP-\ธH^zฑบ�q๛ํA๏{้าea ™)SฆD?ง;Ž�A ฑ๛$.็Œฆ>‰หs@Ÿ๘�%ๅ{3š๚Dƒ?แ|\+Ÿ—Zี,�ษ๊ฒƒฑมห=D๐น๓็e๙ฒๅ๒วึmrฬnYงžฏ๊Tsซื ‘lฺ๔ฃY๏"~๙ีืาฝgoณ��cรฺีrU1Pง ป79๓ม†�t‡ซะ๊พ\[�l฿ึ๛+Œ9ษ ezOv1˜PุณU*ษว~`ฑ�๚ๆ�1ใฝ็ฑ|์ุQ™>c–Y7sฺdษ‘#‡™๗xฌPพœ|�ๅSณ=>ƒˆz@ #ถnีR+Rฤูœ่฿‹—Z�ฐกuŒ“{ฝ=lŸhEปล ๆš�Ž=*%žŽฉสiG_฿}งณิจS%าDlX�iำบฅi่๙q๏๋f:>žƒฤ "ฺร{Ÿ9sF�?฿ช‘n/{^Cž๓ๆฮvBˆ6\ธxฑ์�ปONž•ตZbแย…ฬ๑5|๗ฮ�๓9งDดซ๒๘4ฐVzำ}ต‚�ฃ†5‡๑�k๕zsi�จกู~ต โีย[z’ั_Ž2ว�ฐaฃ4h�ฤฬ๓cฤฐ!RธะฃฆฉฟŠ—๎๐จฟ{ ๆมดQณgฌะcYk่๎[ฌ`O๎๊–๖:๛5”>นZ๗์�น”.UสฺDtYgฬœ%oฟ๋๛�ธ๗}ฝeYบ|น9N|<‰Dœ=kšdหSษZ‡P&๔๐|ีgM5Iฝa ่ผRฟกฯ~๋ืฌ 9ˆ8l๘้ำ/p%s์๚1ึ๚D>7ึชฆฎๆฬ"€ € € €F€ " € €@’ DLR�OฎD "๊t๖์?2 ฏo$�–%หํ๒rฝ๚:+gญj-๚๙og๐@ยะ๊i๓็}/๚ชำป�y_ฆอ˜yีc)TH†lฺ-_ฑR4(ๆž๔xsฌ bฦŒ7šี‚ˆ���Sช>_�ฝซไห๗ Œ�•YงCืxฉ–วv{มฝลึฦn๋ ๙ ฏนƒk๑Dิ๛ท‡พฺ๐ท๖5ฺฏŸ~�‘Tฎ๔ŒY�ดห็2vœg5Eญ†จUuJศ ข9มฟ?ๆY}y๛1•c{FB้“๏gM—ฌYณš3TฉZM�ฺ๑—๛”โ>ง;ˆ่y๊>บฏ๗4๏๛๏Dรฒ:นฯ;ˆจ}ฃ}”PำAไ‰ว3‡�ฌ๋2f์ธซžJ+_ฝฺคฑiืปo>bคว>๎๗๎ีBตE\๊o๖_ถ|…ดhฺูใXฑ-|5rธ<๒ศรฆIlแีุŽม6@@@ธ๖"^{}ฮ#€ €%@1ขบร\Lช”ฉไโฅ‹~/ฌZš’#gNณํเมVต ฯ?Žฺ;น���฿Ÿdฎ๕e&@ˆ’X‡&ึ้ภมƒาผEKŸ๊†�๚ฟ'Šส !1Uศ›Wฦm๖9|ไˆ”,Uึฬ�?�l๗†ิญ๓ฒฝ(‚ˆฺ Y๓–ฒbี*งญ;ˆ7sๆwา๙��8��3‹ฮ3•๚tจฬาeห๛T}sทีPš†ำtฺฟoฟ”}ฆ’ณ9{ถl2mส$g(่๘"๊ม'Ž+๗็พฯœ็ซฏGKทฝœsบgด*ๅบต๋œ๋w�ห–-ข!.{า!5ภ—.]:ณ*>ƒˆ:,๓>หฦ_ีฝษวษ}นr™sถ๏ุIๆฮo_’วk(}าปG7y๚้’f�๑&ŠกlOๅส•‘n]ฏ,ปƒˆ๒\8ŽคOŸ�4o๕F;Yผx‰ฝซTฎ\Q>�่Cณ|โฤ yฒ๘•*Ÿ๑๑จำ”Iฬ๑7o�I๊ผาภ9w|ฯ4{ตฉ4{ญฉ9์ไE๋Y8|๘ฐวirๆศ)w฿S–Xรf๋ไบzษฒeาฒีํ๕w๏๒›uW "บฝB ิv๙๔ั๊•:๕0P† nๆ๙ € € €ฤ&@16ถ!€ €$ธAฤ'้?๒จF(-์—อ›6šแ”Ožํฑ@ˆ ทอž9อ viเh๊ดi๒๋oฟษ 7�(…ญ!zห”)-๔๐�ฐnตคNฺ\„žfอš-วŽ“ชึะฐvษพยุ‚ˆ'O’^ฝ๛Zฟ3์”2eKKj/˜�๔wญ†จรห๚›พ�๚Ky่ก|f“๖fZ็?rไฐ\บtI�๘cซฯ~ห/”›nสhฺ/ถB['L–�nปUš7{ี๚�$‹sŠ๘ ">Vคˆ 2ะ9ฎV”›2uบ์�ทืชึwปศ�U๙ฐขdษœY:ฟ๓ฎน~ปฑ๛Z5ค9ๆ�q’๎๚tาฆUKัเค=ลgQƒ“9๎ส.‹ฌPŸ†ฺ�ฒ๚#[ถฌRโฉงคJๅ+มอฒ*ส��์K๐x ฅOดZžVอณงั฿Œ‘eห–Kฎ๛๎•–-š;ฯฃnwuนsงR๓ฅuVฮœ9#�๚ดžื฿%ฟ๕๏๒‰h(1ะไ]Iะ]I1ะ>๖๚ุ‚ˆv๏WC(ป�่๐ฤ:Lฑฟi��า๎อŽ›ฺฝัZ^ฉWืcฟ…๘ "๊ฑ;uh/ตkี๔wu�ADญŠุ�ช*™"E v� ๑Dด+8zŸว^žz๐w฿้์fฝฯ์ส�๛Zึ`แ็]?“2dิD6lุ่ต‘;๊ฝำล‹%UชTfu0AฤชU*ห‡ผ็๗YŒ-”ช'˜:y‚�{ฯ=�— ฑU:๕iฬ @@@ธฆ"^S�ออ"€ €‘'@1ฒ๚$็�๗H•gŸ“๋�ญDใ}u็ฯŸ—ฅVEขอ?n๒�ไ,7h�ช�|๓อfyั‚yฒiใฮ6f@@ atึ>x_ถ†mต‡ฝตฯt่ะa™8yฒ๔0ศ^e^ต2]uซ‚ก]QW๊Pษ"<{๖ฉWทŽฉn์ฎlจีuุVฆฯ˜%…ญชnYณf5ห๚ใ�๙ ๒ํ˜1าฝgog] ™'‹•ฺตkJAซบ^+จe๗…ปัUสZีํICY›6m–…‹‹'ญSงฮoหwณ็ุMœืoพ%๙ญ*†G“โ%ฏรi`ฆxฑbาฑc{น+{vŸ:ฬ๎๒ซdะเ!ฒk๗nํฯ[•%;XAFŠุžดZๅทcวŠูซำ@kฟƒ†ุ›ใ๔๚F๋VRก\Yง๚ž๛`วŸqใ'H฿��ซ�ฮ‡ฺ'oฟีIชฝ๐œว3ด�ฯ?e��ณw'๐Rวฺฌ)i!”d‰HซญEฺต-vZตPYB"IvI›J;Eฅ}ง}‘hัBŠฟŠ6ekตไ��ž๋œž™;3w๎�[อ�>วหณŸ็ผฯฬ™้5฿๙=+พ๐ร~š6—/พXpวŒ']_zลmใ € € € €€ ˆศ@@เธ D<ฎ�až๓ฌณค`มB’ใฌœ’ลT]ูmบr๛~ำ๙อ|yฯ€ €๑-P๘ขBrูe—ส�eป ศ…๋YฯBรFE‹•ผ๙๒ศ†๏6Šv“ipƒˆฝ๚๔ต]อ,Pะ„�ฎํ?๎H8‹ดฏX–iHK�ซ]8/[บ,lX-–}Gฺฦu๚ีtmปeห6ำ�๑‘6ฑห./RฤvWmŠ;‹b๕ั๋‘7on9x๐Oูlฺ้๚GฑหจVัชœนs็’5kพJสLi%M๗แ๙M๗ล[ทn‹บห฿ใ๕๏ต๏ฎใอ ^7าดพ>ฝใEZ/x™{�p�งวk฿;ง๔ุW๐9ซ้ดผŸคต๚]่ข ๅ�sฮ‘?’ ›6ษ�พ�Ÿภฐงห@IDAT�’า�ำ๒ฌ?๋พจ/^\�5ŸiW|ฑ*ชฯ฿‘žW๎๓:าz)ฒ@@HT‚ˆ‰zๅh7 € A"ฦ฿…ฌZ�fน๔ฒ"ถgฯn9โฝ๋”ฏp“3_ๆdอšUN:้$ปฮ?��#ป�YฆM$ฟ�๒KศํŽ็ฬE๓็JŽgฆุ„ฮฯฟ &M–Žž”;๏h่ฏ�๎{รๅอทz๚ำ�Hซ–Jซฺษ‰“งศsปx‹dฬ่‘rูฅ—๘ำแF��๗_นก�_�้\�ปฟ!ื–)#™2e๒7U็E‹K�v๙๓9ถM= w฿u‡ไอ›ืXV-Z>ฒื˜๋w๏=wษ ื_'ูฒeKถฮW_ญ•ื฿์.ซVญXฆ�<ู�๑€y‘&๎ธ๋^Yท~}คUข^ฆฯฝoฝiฐ%$K–,�v?™ื๗kฏฟ!3gอ๑็ฅืศ๑8ฆถฝXฑ+ฅYำ&Rก\9�uvใฆษฎGZฯณJๅส๒ฤcศน๙ฯ นซo�๗๔ู่K>Y�iภ๒|๙๒špUo)tแ…6DฐะL์�ฝG*#�ผH๊�vซ�vk]น๊ช+�๛ดท’�s>ž9ห�ำzศฮปผู[4o&ตn้ฏำชuYผd‰?ํŽ�V๗iืฎไ2Auo๘๋ฏฟๅำฯ–H›ถzณ๖qฺไ rมุ๖ฟ๘๒ซ๒แ˜ฑv�ฅฎ]คNํZv|ฦGหSO?pŽ๎๛Eภ3ก๓อ›7หิฉำe๘๛,~ถciุ พ๗า+ฏส่“Ž็ฎดxแ<ษž=ป๙Qภ฿RฒฬuRฆT)<่w•จฦ,Ztิฏั์™3$ož<๊ฝ/ชF†XI๏ตƒ๔KถDŸwฅฎน.ู|f จ�็Y� Dณ฿�Cส�x“]u๙า%’อ�{!xะ{ีOป~’/ฟ๚Jzฟ�?b0,x[๎e>งTฌxฃ]ิกใ32}ฦวษVำ๗ะfMšศ-ujษฉงžj—๗ํ๗Ž๔00ูบ้5#ตŸ+b}?IK{n�JnฎQอs๗uเภ๛™ข๗�}�ูใฑพวฯz5oฎ.ฯ<�มพ?บ'๑๋oฟIง็บศ‚… �ูาธั�๒hปถv^ธ๛้gF�7š๗ผึ๗์7บuุ € € €@F ˆ˜ัฏ0็‡ €ฤนAฤ๘ป@๕�)˜*‘†}{๗ษ€�}’ญr_ฃ&ฆšWžd๓ฝZ=MŒปLฅฏx–,^hซบคิฆฎ/ฝ"cฦŽ“็;?+ท฿zซฟบVUชZฝf@XPถk๛ฐ4m�ศฎ<™0๎C)|ัEvYJ*VฎๆW†า/๊†$E.ป4์fkึ|)-Z=”ฌ=a7`Aš๔š46ฤ† ๋Kฮ9๖๕ล+ฅQำๆ๓ผ‰ื_}YjTฏๆM†|ิ/ใ›4o~k๔ภ}๒ุ#ํBฎjๆm๕คXU/ิvม๓๔<‡ 6@ซm}๎๙.2uฺŒเMcž>วผ�ฺkฅYณฦRฆt้dํn๖`+ฟย]ฒ…1ฮธ�พ{ฅฝ "F4T๒p›Gย}—^rฑŒ�pTคอ์ฒAƒ‡Hฏ>กYM aD4คrซy๎คTe๕|Sษs�ุัrŠSUV�บ๐“O’ํ^sไvิ๎Jแ�kpคํรญm๐ี๕5ฎกb {ƒ๛~๔zท7CO?�t‘ด)Vขดhตฉ~}{{ปˆ๚Qรฅ2=Zรๆชก–ฏ๘Bš4{0]ฅ๗‘ฺตk๚๛jีฒ… ยD๔Iษ ๎็Y}ญZ%p�œ™vถ�€ rีŸUƒื4�งo?ัะZj‡�๛ศueห�อVญX๖�ภ�ฏ�lัๅฤ๖ๆEzิJ|“&Œฑ๛ีะcuถt฿วt๙ƒอ›Hu๓๙ห ‹y๛8hˆ >พ_zหา๒๋็ŠX฿ObmซพŸO7?KiX๔ษbyจM๒ฯกฑพวฯz ๊ืณŸGดtจ!ิ๓Nœข๏ี:|0r”ผ๚zท€M5๔�ปgw��6=฿วฤ € € ็ใ�ั<@@ ฃ DŒฟ+์ทo฿ฒปL•ฌy�}‘้ญPๆฺ๋ฅ\๙ vR‡;~�.ซWญ4]~žg*,^๎)ณ�>yงo๒ฃทŸใ๑จ.ฮ4ีขtธ๔าKฅ|นฒv�็Ÿwหคษ“ํธ�™8iชญสโ?ผ…�� �๚๐&ํcดAD nํ�น#`[oโฯฟ� ุo›‡ZK๓fM์b�’lะก๒๕บ๕R�๊bา่�๛�/t{๖๊cชก ๓vรใQx๙ลฎRปึอ!MQ+ฬ|[*›ทlถ2oธ๖:)[๎9+gN�}nTฉvไyฆaЉใ?”๏L๗อŸ˜Jจzญ8$%K— ๅหJ�บึ๛qฝw„Qฝ โฎ]ปl๕รoMw‹rฆ’ฯ-ฆjŸ P‡r<ฐฒะfจ ข>Ÿฬ›ํW��|้2™3wžไ0�‘?hชqeอšTa3ิฝ4ิqใu^ฌม7ˆจL rfฮ”Y๒“Oส^w}๔ฮYซ\j่P๗�(ฺ ข†‘๎๛๏ต์ํS๋ืซ็Wž3wฎ|��๎b[Y๕hT=๕2uาx�y�๚แถษช€z๋ฅ๕qิ#์=’ bZ%ู>�b "j•พ›nLช่Ÿฉh๎�F็ 6Ÿ5ƒฝT(_ฮ„ะOXค๏#^ลo�|บ$จ:๎๏�!C‡ฝgทqƒˆlิแ๔ำN—Kฬ็œฒ7\๏W์�รlS็ึz�r์Ša�ผ๘B[ๅP{wธt๏ั3`อฆM–�๙๓ฬ๓&ŽF1-Ÿ+b}?๑ฮ'ตnQC๏ .’7™ช—™M%ๅ�ฅTฉ�.ฝgy3า๒ฌ?๋i›�ืส—_~%#?�P2Ÿ”I๎น็n�ว^ZฑBลส�)ฺ „ "๊๋จ฿ทๅŒำOท๋๋>๏นฟ‘ฟ-# € € €ภ‰$@๑Dบฺœ+ € ‡ใ๏ขธAฤทบฝu�jˆ฿oฺ(ฦ๑ท=ีPZดzุ�Bฑง้ฒJร1๑8�Xก‚ญfกm ืญฎ�๐ฮa้rบbฅช�ค}Œ6ˆ˜šŠuO›โwแช_ฎ๊—ฌ�ะบU i๙`R๕ฝ๔  y๛็1ด€DิpีgŸ/•vm’บcŽDิj,็šัเ!รช๕่Qดชส€�o๛ฐ:u๋E�5a๏^oษๅ“ช ๕์�vศA่3‰ชใZVซฤ๊ฐ�›oฅแwตใDc๊kHปŸ�่ฃ�Šขn,ฺ ข†AO9๙�ิปผ๐bิBฃ�FF!—Iชpูฆ�cฆBัยเUBNwxฒฝ�}ืvู๐๗?7บuน^๐L5ะ0‹7\_ถBศ/ำuฝำงุ๎ศฟ�฿w๒ำฯ?ู.uปPAฤ‘๏—ขW\nw๛๒ซฏหจัฺ๑เฐฅฮ<ึ!8�t๚kp$ฅ ขVภœ2iœ฿J๏บd” ข๛<๏๘lงฐ]ผซC๋VJ‰ซฏ–�yr�{v๕บsืNYถlน <ฤT�ๅ;…ImQ฿{=pŸ\b‚ฝง~š Fe‘M›6™ะ๙็ขaooะ็๒ ฯ?g'g˜๛๕˜ฑGฎ—ทN๐ฃ{tะ๛;/ŽiZป�>9k6$?aข�u็r�uืš*u—ส฿ฆ›wญt๙พน'L˜tคโณH+�62ีx/พธฐœgฮEป„฿ธ้{๙์ณฯ“U•sห5ั.ธ _TH๔GM;ด ๐UW]i๎›'›๖}/Kอต|ๅต7�รŒkh�ฑGฺI‘"—Iสœ)“l฿พ]ึญ๛Fบฝี#ไ๛��ฝ{สฉฆ ๙ีkึศ๒ๅ_ˆv^ฬT“ฮuึY๖9ณxษง๒|—ŽใNh0NŸ…/*l�kฯฒ‹ด๋_ ‡kUฺHŸฃ4่Vใๆ๊f�‹lภI+�m0ีl'™ภืธ๑�รคi<#ข�kฏHตjI?๒3nผt}1)ฌษ}฿?qbศู๋ทO/๛\๑๎๚�งรั"ฆๅsEฌ๏'แ|า:_ซ๋otุฐaƒ�V�—ฑพวฯzร”’%“ช;†บๆO?๕„ฝo๊ษน�P‡ "๊�oุr๖ูนฌล&s�บ๛ž๛C~n๒ฑA@@2ธAฤ ~9=@@ �"ฦ฿Š5ˆxใfๆK˜ณํ -œ?OV,_prท}Tฒfหf็๕๋ำS4Hƒ๛…X4—-_.ฅK•ฒี5�Pตฦ‘€Vz5L _Ž้ฐtู2[-ุ๐ƒแ๏ส•Wตณ;=๗ผ�’;x'L7ฐ๗�{?{ลŠ•าธYR%E h˜#=‚ˆ3งO•sฮ=วถ#ฺnJ[ตxPZต|ะnใ~y๓ษ�ทa ำu๎Cญ[ฺ)ํJ\ƒB:่น๊บ^Wพ:o๗๎=rS•j:šฆแx3Tƒc "z•คผ�E`๔ึ๗5ภ0m๊$”ัyแยล�๚๎ใ€�}ๅบkฏฑณRSำญ ชJ•wŒื^yษv�๏ฟ�Jณๆ-ฅ‘้โ�๋ึ>T๑๓O๙•๕>้…ล44Uึt'๎แ*๛น๋ฤ๋xฌม‘”‚ˆzพ๎๓J฿ซ5š‚ˆz�๕y CคŠ˜Zujธฉฺx๊ฉงฺuC�้ีงฏ 2aฤHCj‚ˆฺ=ญ�๛ผ€๐~ื~ฝNjำฮ฿4X็Uƒ^lบฃmีบM๐๊ำ๎yO:]:vJ 1ฌ”ส ฝgxAโUซVK๖์g๘•Q�]�ฐ๙ัJป� ๏อ›5 {žZฅฒe๋‡“�bฝ&ว‘‹ ฒ‡?t่œlˆมƒ๛[ดj,ะฃnฏš๛OŽgobงตbh๛ง:ุธ+xฏ=ž�ทN1กฤเ!�uำข# ๗>ะศ�ม]GฏGื:K•สGบwu—๋๘ |๊้g‚gว4ั‚ˆjฎ๖:ฬ_ฐPฺ>’TU7ŽZฯš9รvซ?ฤธๅึzQ�เhCต5ฺฯฑพŸ„:fzฬs+ ฎY๓ฅ�๛@cทฑพวฯznฦFM›'ปWT0�‹๗้�รž�ๆอ›ฅv��ํxpq่ป๏ษˆw‡‰~nาACษ๗�฿8ู}า.ไ € € p D<.6งŠ €ฤฃAฤ๘ป*nq��}’-�ษถๅ�๛๖™ "�ไใำB6๚๚สษu7”ตห~๛ํWN๒บ_พ�ŠขRฃfmป์ภา�ํ^!๗3SDิช^ธภาt}้ฟ RดAD�วึm�Cž�ิiำ�/ดn�Jl�ิฎง•–๔Xมƒ�MpžฝeศฐwƒW‚ˆษHาuFz�๊g๚…zษ2ืEีฦiS&ส็Ÿoืm�ไS2sึœจถKi%ํส๗ฮ;ฺี�สŸใM๗ฟ›*aXหš5ฉgjฺ้ธวใ˜กฺm`ภ�ึ ผx๓RDิส–UซTฒ•Kฝ`qp%Jo฿๎ฃ1ส–ปAชUฉ"ีชVฑ‹๔>ฌ��jh-šม ญJ—Reมhƒˆ,๛แ(ฟkุ๏LฐฆŠฺ•ธNิส‚ฺ%ฝ ็ฯฑUB๙๕Wน๑ฆคื ]โw?;„X5๊Ynั�Hป �nB2๚ƒฝงlูบล"VซVลTž{ี_]_๗+Lท�Zๅ๚ๆีE๗ฉรฬ™ณLภ/ฉ;SoๅXฏ‰Dิ}i0yแขEฆr๖ๆ�Wูท:์=yซgเgF7คฏมw�a†ษส 7\gํuZ•ฌ๎m๕uิผ{7Cร•kLuฤK/นฤ†๊ฝ๙w�uฏฌ[ฟ�›ดnศJŸซVฏ1ก๛�r�น๙ฅ|๙r6*ˆ๘lวาฐAR;4�ธภœใฦ›์sตฒyy!�—^yUF86เ˜ฑLธADu;x๐Pภnrๆฬ!๚ผำแงŸ–สUk,w'<ฏHtw}o<ฝบfึ�น๏+๚YYซ้†๔G�นwnฯAฤX฿O"oZ–ฝ๙ฦk๖๕ฉ๛ฎด์=_R๛<>๋}ฑ์3�ใUv]�dh๕าฒnฒ‹� ขV)ื๗e๏3ท�ร๔เ�ศย�ใ € € €ภ‰&@๑Dปโœ/ € gใ์‚˜ๆธAฤPญ;๔็!™jบ;�ผ๙๛d‹�m5�๒๛๏ฟหiๆ ์l�UBิy“'Œ3]&}‘Ÿlq0#– โGๆหyญ งƒ[9#ฺ bคำvƒ,nธƒ‡“žฝ๚$�Tป;ิ๎u>โ}yใอท’ญC1IบฮH โS๕ซXฑซlป>๛|ฉ}๛Fpัไค๑c�Jc�๚~๏ ๐ใ?ฮ˜6Iฮหž์�ปืV า็› ฎˆ่kตbPอฺumธiสค ’;๗ู๒๋oฟษ˜1ใlE6=ˆ>ฟ๔yv" ‘‚ˆz]๚™ฟืE๗ฮ;ฅ๊อต,Oข�€ฅVฒซTตzุห�ษ‚y�kรซ้ฎ\ฑโฆk�u)Aข "บ๗ ญ~�ิT�๔7ผงAญšunฑวu_๚<ื็{ธAปpฟฑ|yปXซj•ยดมAD ัt6� ฯžs$”ฎฯฃbลฎ๔๏ �๋Y�นมํ:]ƒtw฿๗€ฌ]๛ต฿ฬXฏ‰D�๑ใน๓�๛�]ิ4]ฟ๚๒K๖nจIgh ^ƒK:hตQ“ๆพฑ�g�6ศา “Ziาผ ”Nี�สฌม?โ(cช^”ิ…ถv%]ฑRUo—�ฃถy๚Œ�iั ๋˜ั#ํ=Yปน~�ษ2w๎<[๊ิ’_H $G\๕7Œ0โ#ฌfล{ัฝึฺเ_~U>>ฌ9ฮLำev.{nกยคvAˆ?๑D ั�ใ6Kซ๊=๋ค“NฒE7{ะ�L’–๗x๗>{,>_บ๗Hฝง]]2)๏ยบ๋่�b%J�ลnั]_วฝถฯg@@8"žˆWsF@โH€ b]Œ�šโ… ตโ^๓๖฿ๆหำ์gd—์g้๏ฏ?�4ีฐzฺJ‰มgp“ ?/Q"xถ��๗_ๆ ูQฒใวะ•�’mpœfฤDิ -ฺฏะtะnkต๛ฺ๔"บ_ค๗์�Mnบฉข=Fธ๎'Ÿy๚)Dl`ืั๊:Ze'xxด][ilบQ๕†p�<{หyL@Zƒˆnภo฿��า แ]~ะ"RKบฝ�ช_/ฅสA‘๖jูเ�ฅL้ค/by� ๙ึT’7f”ํ"ีซ<ๅv!*$jฟ‘ๆc†jO,Aฤ•ห?๗ซจ้>Cu�๊X‹ๆฯ๕C€๎rฝว่5 7๔ู๊]*Vจl๑ุ๑ไ`Œvpร8ZAญมw%�๔‰๖ษ}๗�m็ป7€D,Yฒ„ึึ*dZก๑๙ฮไ๖[ฺ๋�่๘ิ้๚ย๓vz�Bำgปว์xฌ4HprˆฎWรํ๏ะมƒษบ€ ท๎ั˜๏7nฺd*ฎญ6ีา2ห9๙๒Iฑซฎ2ก�#�ป#=ˆ๘ึ›ฏKๅJI2ร_=oทŠUJ!?o›Pั็ฯๅ‡ฺBUปsใ^ลฝ{?$ะ0฿ปร�ฆLž2ี�ื=hzugฏะhU<ญ*npซ›†{อฟิต‹ิฉ|u_๓บฯXฏ‰DิU่+�ACู—\\ุฮj�p[๙d๑งv��ช๚ฅ[/ธปk/ˆจU{oฎ๕Ž้K?9J^}ฝ›ทศV๋ิช:ธ!`…0#nทยแ>น๏›ฉ ฯ…9คํ–[Ÿั ๑Dิ๖Ž7?rาแŒำN—ยๆฺพ่";ญv�๔“ิ5]-๋gขPรฝ๗�%Oถ�.Š๖ว�~"zแ๕95iยXษk~(กCpU๖ดผว๋ฯzž0nŒ=}>iEฤPƒ{ฟ(c%๛�‹DtˆjฬC@@N$‚ˆ'าีๆ\@@8 ˆๅ<ำตแ>ำ ๓ฏฆ๊‹;œ�r[�ฆฒKV;๛�oึหด)“�U2›ภฤ=๗7’ณs็ถ๓ดสฤ฿�%'eฮ,Yฬ�:hEDํฺy�บฏํt<�‰5ˆจ•B๚๔๎aOIป@ี VดAD n๘.t•Hท{ภoพaปƒิƒ๔้�O L 6ธŽžl/w฿uง)„คมo๘ล\๋p_๎z๋๐ฝ@Z‚ˆZัซป้๚ฮซj—R ฏU๚%๑‚yณ�๊ฃ้๔๖ญ๎ลฺๅsฝzท‹V`ิืt“ๆ-lUœฉ“ฦK์f้q�ใqL๗œฝ๑X‚ˆZ•้ดS“‚c™vด]๕iศ/ท้:๕,SY๒"๓ey�บ�vา๛นV�๓ฝ/ฮž=G–š็�ฆ{๐pƒšิuBูžs๎9�ๆ^pีŸรˆ[ฑูƒญไเก{ษ•๋l้๕ึ›v^ผ๊LhUฯงž~ฦฃ:‹�Qทชg‹–ษ’ฯ?๗—ฅ4B1%!‘w‡ ’%Š�C๎�๛^j฿ใ๕g=7ˆธ�นฎl๙��B?็–-_1dQซแfอšล฿^+v๊็v@@@เD ˆxข?8@@เ8 D<ฮ •‡ฟ�ŠขRฃfmปี{�A�๛๚{ธอ|ฑ~แีK~๙eŒzธ่—เ:\s�๕rƒ๙ขGฟุึ/t๚šภ�_&คCฌAD=—ั#G๘]gถ}๔qนฺtญ�ดq#{š3L`BฟH๕† ใ>๔ซฝ�Vฏlุธษ[๖๑นNฯH}ำ�ญC†ฝ+Z™(xpปf~o๘้ึ=)ผำGO ึ ข~‘�ฏO/[eP[—š/4ตยฅVบิAรซZY)=ท๋<�‚_Cˆ:hฃ็MทŸ:ธ�"ฆwืฬว๊˜๖D‚�ฤD ฺEฬ“nะIwmeE Fฟ๒rWษž=ฉ‹gํ^Yซอ…š4z@ด’˜zึชฎม�Œ๊2๗ง!ญฆ๊ ‘‚ˆ|ž>5)ธฎ�ฉjฐคpแยrเภฉืเN[๑ำ DฅGืฬz<7pํต3าczh#ํ?าฒเ ข†Au8x๐์ุนSถ›jยcวŒ—…Ÿ|ฐ›ฮฯ=+๕nปีฮ{ฝ�›2โ�‘หuโ๓O๙๗ฏ‹ษd+™n…ฟฆอZศฒ+Bญ–n๓^่าYnฝฅŽ�฿๐๗?7บuธo=O=฿เA๘ .}๛พc๏มหƒงฝ0›†HJ]s]๐b;ํ†Uย�Skืฎ)/w}มฎ?e๊4yฆSg;พ์ณลr๒ษ'‹ฎXZตFMSaถ”ผ�bR๗ใมUC6(ส™nQปzึฐ^คแูŽคaƒ๚‘V X6o�|i๗X{^ฌืฤ "†zNบ๏i ‘�o'}�œ7{ฆœ}vR๗ปกถsCƒ[ถn•Zu’^ฺ`/XดfอWข.�มฝ�z๏๋ะ๑ศ็5]Oฏณ^๏เA?็Nš<ลta?ะ๏Zฺ[วญ๊่อ‹๔จฯ}คepƒˆ)๙ฤ[ัป็้๋๙—=ฟศ;vศš/ฟ”�ฦ6Rะุํโฺ{อฅฦ bdญ^=Lลๅ“ชjโ๗?ะ4Y7๒iy?ึŸ/�{d4]3ป๋ธ5ฤุ๒ก‡ฅ”้@xฆƒ~~jีบMช‚ฐ‘๕YŠ € €$ฆAฤฤผnด@ศ0๏Rถ{์ [ลJปถ๋�ใM�ผ๙ฺฝf?ำmspะPซ)^xaR7kซW~!s็ฬ๒ทง‘ดkTฏ&ฏฟšTฑlอš/mˆ#=ƒˆตn)ฺํฃแชฃฝ๚๒KR๓ๆ๊v๔ 7ุ๒'*X‚ˆ—^rฑ 4Pฮ<3ป=ฦ์9sไฑ๖OEu<]ษ ถฆG˜!๘ภ;<)w�qค๚.ื@Y��๊๛ๅK—HถฌYM7์Kษ2กร=ม๛4}<Žช=ว3ˆจํq_ำฉ้rปž -w6แeผ๎ํDะํYร]^ดpฯท‚›๎b๑’%{*quqฟ๛`ญ๚ฆ!’นs็�.uE/ไnไvษฺชๅƒาชER๕2ท๋aw�ิŒ฿ัฐพํึ8ฺm�W†˜๎a#^ข�W,๋นAฤ�J฿~๏DตํŽTป%ี!�ต‹ว ขฦfฮ˜jซธjฉฺอต“นBhีุ&�/W^Yิฏ๋ญง}NiP?าMQซj๐V‡/ฟ�สV|�ง๛ž�ัว3ๅษํ*^ Sฯซ๔ต7ศโ…๓�Pฐฎ ]ญ_T่B�žช�gปฃ�ธ!›ๅหWุŠต‘vใ†Aต:้ยEAืเmฟ1]ซปd]ห5I)ˆุบU ั€˜๎*>Y0ฯŸ ดsฯ_+ัj่ำผ{ะส•ซไ&IŸฅผe)uฝjU+K๓fอไฒK/๑6๓5๘`ซ‡dีชี�<ทZคžรฮ]?๙หBhศs๋ถmกE=/Qƒˆ‘Bม)�ุG‰~†าก�Sdๆฬู)mฐœ bGภฤ‹/t z๊ ?h�ฒ•h7ิเฝพ�eัผวฯz+–~ๆW2ิฎ™ƒ฿๗�ฯ;ฟ��‡”ป๑&{Znั�<6า�๘ฎ่—�uBU\uMG@@N‚ˆ'ยUๆ@@8 ˆว'Lำฺ˜๎ต{fญ๚ะณ๛vญSMทฐ-Mดาี wŽTJด3อŸ+ฏ*fบ]Lฺ๊p�ึ-๒แจดU}๑๖›�i "j[�๎@WฌX)ฅJ•ฐMLŠˆำ/์tะ๎ต:Z๐เV,ำ.ŸงNผ ำGY ตADํžtุ~•'ฏซฺh›้๏ะกCRฑRีd_ช†ฺWฅJ7๙ม1]ฎ�ํ…๛‚Yฐ„uํขyๆฌ9v–†4  รฯ?๏–JU“ยฐv†๓'ธขิช•ซร/าใ˜Zฅงx‰ซHช_ว;ˆจ�.wzๆi{๓š.\�้F5เฤ‚&� Eฟ�๖ป”ฏX)h ฌฉVE^}้E?ะฅ�ฝkท๏ก๗‹๙PหCอsซฤนa8]7ธสœ[u้ีืปษ#“žOก๖›็ลD์๐d{น๛ฎ;-Iธ๐๙ห>ณื๘OS‰ธ๔5ื‡ๅ๓tบยัฎˆ๘ฤใส}๗�c���oุ: 4pvํuืJญ›kH…๒ๅlB]ฌŸAสVH 8ซŒzAฤHกi7ะ\Yฯ�™@5ชƒ–sป9ืkขีF5h5o�|fซ"ฺs.ำ�z1S5Yร=ื�บkP๏8ฉyt��ู็Kๅม–ญ#n๎�g#ฝ�#๎ไฟ…ฉน&n1T]7ˆจ•ีW7tj;7P๘ีWkๅ๎๛๘ฏuGยะฑฝ้ฝฐ\ูฒRงVMั๗_ํb^‡เnำว{ว‰Dt?ณGSิป†๎c,Aฤิ|–qๅ็†w์hŸ~๊ ัnๅuะ๗Žวฬั‚+๒บ๛Š๕=�ฝy๛‹ๅ๓ฅทm4ณgฮผy๒ุUƒซ;๋L W{]˜ปฯ+7ˆจŸQ๔ณŠ๚๘Fิใ่ห{š�? € € €@ ˆ˜A.$ง €$ชAฤฤบr@ิ ข‡4],๗ดใ9อ๊›&Uฒ ๎ฒูฎ`�\]ผธTช’Nฺตkงผ��0oQ\=บ_jjwฐ-Z>”ฌ}ฯw~Vnฟ5ฉป?ท"†ฎฎ›ย๔"jืฝรดํ (ัภ'ฆ๒Rๆฬ™ํ:แบี.P๏ฝ;ฉ‚–ฎ๘๙๒ๅ๒\็.v�ค]ภ † ŒzGั@ร๐กCไœsฯฑณBu้ญ๎ัํ225•WญX๊(t฿œm�,yธU—นฏ ๎žำํBx™y>5mZิmด;g�๒�"_าใ˜nธห;nจ/ฝeกc h ๙”l'๛ปk�ฆmT�ฏ๛8#nฅภ™3g™ŠOIกDg•ฃ๎�BซWVฉ~ค2˜nPฎ์ าฃ{7[‘Nงƒ๏e:ฯ๔�2�ฝก��ล]ฆใ ๐ŸO|�๓ห™>�#ygเ ป๊ศ๏IัขWุq €�s_ฃ€nt�JgัvAmw–A�ธฯีิTD|ธu+yฐySซฎ’คWฉ*\ ี#ฝ6E๓่†ฯt�P5w?๏ ld:OปฑืPlจม u้๓U_?{๖์ XอํR๔•ื�‘ฃF�ๅnˆEอsไ8ำ�x`ฤฃค{ทืDป๔ฬ’5‹ ญDบ๏,ส ตีv๋MQซ�u{�5ปพV:ิ๛cz )]7ˆจ]มO6#เฐ�๚๖–ฒื'…fต:ฐพท้เฮ๕c ๗ณfฯ‘วŸ8RYุ{ค5ˆ่6ิ=ž†๙kืฝ�_�ฬำD+ณ๊๐v฿��ฝะ_แ(ŒxฯY�uจŠ‘nืี๑ิ5sฌ฿2HJ”(n%_|๙U๙pฬุTซฆ6ˆ˜ฺฯ2กห็ŠP๛9Z๓� ฐ��:>๛œhีืHCฌ๏๑้๑Y/RปB-<ฐฟ”)]ฺ.:์=yซgฏ€ี�.๋58�๖ฟ๛† "๊ฦ๎{ฑV็mำ๖ัˆมอ€2 € €d0‚ˆ์‚r: € €@ข DŒฟ+–9Sf๙็๐?!VฏมR `Aป์งŸv‰†ผม๋šY+%zงŸ์�ทื[d�yทœw�v|�ฺฏไฃำ–วห„๛…X,AD=™ำง๚ม2๏ผา#ˆจ๛š6eข\p�๙vทมaทยTคฎX�๕tG้„ฐ;�DDิ@ภ{CIเาแ›o�'7ชšกวซก“9ณ>๖+>�ๆ‘จฟ๘LMQ็V๖๎p้�#)ˆฌm;fคœ—�<�ฌNฯ=/“ฆL๕š่?ฦ๒ๅ}Z้†ปผ†‹ ขx‰ๆ˜u๋ิ–ฏึฎ Tิ ุ๊ัฃlI๗ีซO_ัฐ™๊ฉ•ธ‚ปHถ อŸ๏3ืฎด“บNซ�ชึ๊ )๖๋ำKN=๕Tป�ญ\hgฤ๐็mL/_ฎฌ�2ิ๓ะญงUเ4˜๎u‡ุ่๛ไฑGฺูmทlู"ตnน-†$๖&๎s5๘�้ฬด�Lํ>S‡ 7สฝ&เ้น๊ผ๛๏ปWดBŸ_ฏ[/w�}ฏ๕็Xต n ุ๊jี.ožYืฎ�ฺ›๔๕ไ†๐Cuต้ฏlF�๎ฮตจขC ๎khฤ๛#ๅ๕no๚ซ้ksฺไ‰~๗~s๏๖บๅี๖,^4฿ๆ๊F�q–�ฉฟฮlบื๎Kำkะcง&ˆจ๏CM›,งœrŠmBจืฎ.ะ�–-{ฝ_ืkoฌืฤ "ช›๚yƒVsZK‚ˆR๎๛ฑ๊บผ๐ขŒŸ8)pฅSiyO๋gฝอ‰8๋ถบทH—็Ÿณ๋่sงก ค{Asฝท๙พญZซ+<๒๘2w๎<ปnค ขฎ0a์h)\8้�ฃ๛ญ{[�€๗cป� € € €'€Aฤเ"sŠ € €@< DŒฏซsu๑’ฆ[ืสข ืฌZ)[Lu—ฝ{�๓ฯ/`บ๕ฌ(y๓ๆ๓ษ^~นํ–[ยะ/ฝ๒ชนWฉๅVิ6j๑sฬPƒv-๋}Ajน7/ฅ ข™ๆฯๅwกปfอ—2g�<†lฺธฑd5โtะเˆNดม}ฎฆ&ˆจฎ3ฆO‘œ�ฝ�j}‚ huโซฏ*& ๊฿๎โยu�์Yซ โ\žฮ๛l{ุป๎ฝ?dธะk“๗่์๔น8m๚ s?�B~๚้'นโ๒หฅfRชT ป๊๖ํ�Mpํoณ ิญxฅƒพ.�t‰h5ภร‡�•5_~้ �™ฎซUC็อ[ g็9[i๓ฐ๙L”WgKจ`›Hัunซืภ†šj\{Me‡pม?oyj='�.šŠˆบž[ษKซŸ;ฮv3�๛ฟ� �5eสHuำฅด—�งwฌXฎ‰Dิ6่๛฿ุฑใๅŒ์งหฃm�Jพs’�O5คA oะเไŒฉ“�ต†๗>๘`ดœ”้$i|�}~u<ํขปZZ! ๏พ๊zนงฯ๘X:t|ฦ;ค้N;ฉjไฦM›ฬฝrบ|mยฐLU๐R%Jศํท฿๊�8D+ฦ=ูกฃฟŽ 4ะn๊gสกร�•Ukึุu _t‘TชTั†ส0Ÿท5ด”ึม{?ั�d๔Šˆฝ{ฝ%7–/oษ�~J†๚ผ}�t ๏uฉ}ต๙�ฌืB‡M฿/+M0V มv}๑e;๎�‰ๅณLz|ฎp�pดฦ๕ว ร‡ •“N:ษ?„v3jะื˜�[ริ5ึ๗๘ด~ึ๓ฺšวOMX\ซ๒๊๐�† 2a‚ [š๓nุเvSแ9้Gw?�ผ[*™รzCJAD๕6x Q๋6ม�๖๓๖ร# € € ั"f๔+ฬ๙!€ €q.@1พ.+Uฉšbฃพ�fฝฉฬgพฐq†\นฮ–๛5๑ฟุำE๚%ž~ั็~กตaรw2yย8gหใ?๊~qฉ5]_zล~AŸRQ๗1o๖L9๛์\�๎‚ฟŒš0๎C�‹O/ เฏaDฟ่๋๗voฟ[ษPซ†ซไ่ญ๋~แง๓จˆ่ษฤ�8�t3๊…R"ํล{้: Wฎผฒhคี�eม•ผฃ>a‚8E์dจ๎ๅผ๕B=ฆ6ˆจฯฝ!ƒˆ~กjะฎ;u๎,โ5ฤ๒ๅ}Z้†ปผ6E ๊:nธำ�&ิใŽwHตšตC-Š)ˆrGฮฬn�{ศ{รG๘sผ ข?#ฬˆ�ญ ทŠศ๑ฆ#=บ•�"ญ—RQทญw๛m6ๆuผฟเสhมห3๒ด๛\MMQM�`]8# @ืoxgธลv�ฑ"�u็๒๔SIม2 ๖6i�"b›ผ…z/ะ๗๊”†P�๕†ฺ&8็ญ3ีอt�0h@?ั ^ธAซ{ถzธญํzู]็๙ฮไ๖[ฺ๋Y๎ฝยญ6ฆกฟ’eฎs7K๓ธ๋mQ๊^๛HDŒดพ. uMย๙ป๛า`{ฃ&อ�๐ตทฬ�A†7ฯ}ิpฉvตช•{�มป๏ลDt๗<ฎฯƒFMš'๋ๆ[Ž�๛พm~จZ �ฮ›ึAฤ่_ ๊ชี/๕฿ฟ��‡”ป๑&2ลG ™M™�ฟCjึฎk~ฐ-`Ÿฑ|–Iฯ8Jส•“>ฝ{Dต๗ƒส5ื— X7ึ๗๘ด~ึ hD”ตk�,]ฬgV๏Gม›้๙=๑TGYฐ๐ศ๛NJAD�G‡'�ห�wyฏuป–>ำ € € €@F ˆ˜Qฏ,็… €$ˆAฤ๘บP/,$unนUฒfหฒa™Š\ ็ฯ•5ซW…\~ฎ้š๕ๆZตM๕ฐค๊‚๎J���ฌZ�…,œ7ืใมกมp๊๘l'™:mFภ—LแบUtปzำ�Ÿ8Qž๏๒ขฟkญ Y๔ŠหMฆรR�tC�Eงฟb˜‘7฿xM*”/็Wำี๔‹๐ูsๆส3:‡ู*i๖Cญ[J‹ๆอ�u>Y�ฉด6A †ุฆN๏wฑi/�sHื2๐)]บTคี�eม!4oม๒ฅK$[ึฌถชWญ:ทฆ๊y๔ูโE~ต=�_4ฯ�ฒธ{๗7คtษR_�jt/ฟ๖†฿}ื>๗Q+ลhWง๎ะณ๗�2xศPwVฒ๑ด๓มๆMmต/wง)U`ำฎ’ปพ๐ผปIศ๑Hม‘eŸ-xmF:fงg;ฺ š^—๋มำ.ป{ง…Ÿ|ฐH]ทึญ#—^r‰„ ๖i%Ÿ!ร†‰v)<,]๒‰฿k๐2wZ= ๎ธ+Yศ]วื{RUSS‡ฆอZ„ฌเฉหด+แvm�Hž�นuาZํ๑Ssj๛่ใ�ฌ๎ั}ฎฆTน0NตjUไฑvm%��‹5์ฆญ�|๓ญ€๊p+�71 _ฟškค็lจmฃ7mสDฟ‚œพ๏่}'ฺกW๎RขxqฟBฉป�Sฉ๔e๒”i๎์ฐใz_yบรSRฺTR<ืTฑ๕~0กี50๎ฺต๕ๆ๕ฆ๗Zwะืf‡ง;†์V�ฝhทฆฯw้j7ีnxง›Š~:่๖๚๚J๏ม{_BŽtฌ&&ษ™gfOถฺ› ‰พนCฌืฤ "๎฿@&Mž,๕๋ี xOูl*ถ3๗ƒ 7น‡๓วkืฎ)OตoŸ์น ี_|๙5๓Y่H%bo#๏พ�Uฝ.ื๋2u๒l7aขํŽึ�๎าK.6แูงไชซŠtซํ-�โ‹•าฃwฟ’ฆ7฿{ิ็ZวงŸ’๊ีช&�^?~๕ีZ™jช|jลอด�็ูC‡I™๋ส&�ถeั‚นถb›พf๔sCธแ๓Oูส“Z๙ฎl…่ƒ~nื๋)�หผฯ!ฉ=ฦห/v ’้ ำ๎=z†;d๓5๚ัด)!฿7�•๕�Yฅzอdc๙,ใ��cG๚\ผ๎ั˜.Sช” ๔NTปึ �*&ฝ็ปฤ๚Ÿ–ฯz๎๑S3ฎมKญŽ{ฮน็lฆ�ฌ๋ฟู‚+‘ป�Oะ(ิjฬC@@2ฌAฤ {i91@@ 1"ฦ็uสyึYRฐ`!ษqVNษ’9ณ์6–๏7m0]�Uƒณ›/ฑ ธP๒˜n ๗ํ�/�ทm‘mๆ O†๔(Z๔ )T่Bู๐�ฦd•xา�h์#Z(GฮฆรUข�B‹แx๓Xœ—Cป-Pเษ}vnฬ&�Mลล๏ฟ�!Y"ธ=๚ๅ}lEฮ์gž!ฟ์�Eพ�ธแ˜]“เ๖D;ญม t�ด๋็d_๖GปึK. ฎ… –ำO?ีvืฝึt#/ƒ‡4@คƒv!�๐ฮปcjšVCำ๐`N๓ๅ๗_ท็ฉAนฃ=h ํโ‹ หoๆ˜ซVฏN1ุyด�sด๖ฏAญ"—‘์ฆ›ไ;v™๎่ทคx?Iํ5๑‚ˆ๛๖๏ท�=๋น”ฝ�z9�s๕๊5)ฯ;w}พ_qE๙๛Ÿรฆ‹๏ตQo็mŸฺG�ฬ•'Oำฅ๋้ฒk็Oๆน๗CชŽฉี๘.ป์b�์Ž;์g75`ˆ^@ŸŸำงLถมUญZง]ฑk•!พา๒ฌ?๋้็ฏโลฏถ?[ถtY†ฝทวื3„ึ € € €@F ˆ˜‘ฏ.็† €$€AฤธH4@HฃภALย’v/nuุ4๎6Cl^ฎ์ 6\™ฺ“9�ฯ?ข�mDLดs ฝวGภญ๊\m�๘ดˆฃ"€ € € €€+@ัี`@@เ˜ D<ๆไ@8ๆZ .ožค.นƒปผ<ๆ‰ณŽ=R.ป๔’˜ZUงn=[™/ฆำF|8ฌVฏ+\จ=“ฏืญฃz]ธฆœ € € €@ฦ ˆ˜ฑฎ'gƒ €$œAฤ„ปd4@@ "ฆ#&ปB@@@8n=F@P‚ˆ<@@Ndญyv๎\ฉ&8|๘ฐฌZต:ี�๏ FŽxO.ฟผˆ์�ณG*Wญqผ›ร๑@@@@าI€ b:Aฒ@@ุ"ฦๆฦV € € € € € € €@ผDŒ—+A;@@T€ โ zแ9m@@@@@@ศ03ฬฅไD@@ฤ ˆ˜˜ืV#€ € € € € € €žADO‚G@@ใ"@๑ธฐsP@@@@@@@ �"ฆ%;B@ˆE€ b,jlƒ € € € € € €ฤAฤ๘นด@8!"ž—“F@@@@@@ $@1]LN@HD‚ˆ‰xีh3 € € € € € € pD€ โ ฦ@@ŽƒAฤใ€ฮ!@@@@@@@t ˆ˜Ž˜์ @@ ๕Soฦ € € € € € € €@< DŒงซA[@@P€ โ xั9e@@@@@@ศP3ิๅไd@@ฤ ˆ˜xืŒ#€ € € € € € €ฎADWƒq@@c.@๑˜“s@@@@@@@@ ]"ฆ+';C@HญAฤิŠ%ึ๚9ฯ:K~�ๅ—ฤj4ญE@@@@@@T DL+#€ €คทAฤ๔M๛�ชVฟY.ฝฌHฤํูณ[FŽx/ไ:5jึ–‹/นTฒdษ"'t’>|X< kฟ๚R>Yธ ไ6ฬD@@@@@@ฤ ˆ˜ธืŽ–#€ €B€ b�]ฦ๚ ๏” Œุฐ}{๗ษ€�}’ญำฌEkษž={ฒ๙�Œoืฏ—iS'y“<"€ € € € € € €@ ˆ˜."ง€ €$ฒAฤ๘ปznq๛๖m!ธk็.™7gfภฒ›*U‘โ%Kูy�๓,_๚™lูผY.*\XJ”,-™2eฒ๐ฬ�๓@IDATหf~4�VG ุ˜ @@@@@@HX‚ˆ {้h8 € 1"ฦ฿utƒˆou{-๊>�๎1ษš5ซ]_ปm�ฑใG�.”z ๏ฐำป�Y�6ุ_ฦ € € € € € €$ถAฤฤพ~ด@Hx‚ˆ๑w c ">ฺ�){2๛๖ํ•��Nvbอ[ถ–3ฮศ.��๛ฏ๔ํ�C��๓ฯd๋0@@@@@@O€ bโ]3ZŒ €d(‚ˆ๑w9c "ž{๎นr็=๗�“ูตs‡ผ?��d'vว�๗I��๙ํ�)'ศw฿}›lf € € € € € € €@โ DLผkF‹@@ %@1�.งD�ฟŸdหvฒ>|X๖๏�'�ทo“gLKึ่ิ?Yธ@–-�,ู~˜ € € € € € €‰'@1๑ฎ-F@2”Aฤ๘ปœn1T๋�yHฆNœ(›7ฐุ๋šy๏�?d`�พหtข™้š9ป้šY‡ีซพนณgูq� € € € € € € €@b DL์๋G๋@@„ ˆ—ะ "j5ฤฝ�!�๓ f?๓Lฟฑ�๙ง๔ํำำVJ๔fถyไ1ษ’%ซ|�ฝaฒkืNo‘(pกิkx‡?ฝแป๏d๒ฤq�4# € € € € € € ธ๗ฺัr@@ CDŒฟหx�๙็ห>ำ ๓ฏฟ�ะธ๓ฯฟ@nซ฿ภ~๛อz™6e’ฟNๅชีฅุีลํ๔฿�-ห—~.[ทn–B–%KKฆL™�uฟ฿ธQ&ŒใO3‚ € € € € € €‰+@1qฏ-G@2„AฤฤบŒ—_QTjิฌm�‡้‚yPPฬ-Z?,งvzศ“ฺทwŸœ~FาฒU+Wสผ93CฎวL@@@@@@H,‚ˆ‰uฝh- € แ"&�%m๗ุถบกV=์�ใอd'pหญ๕คเ…�ส‰��—้ฆy—�๏�oไฦŠ•์๚๓ๆฬ’U+ฟHถ-3@@@@@@@ ๑"&�5ฃล € €@† ˆ˜x—ณอ#ูแแร‡ฅg๗7ยž@ๆL™Mฤ3ไ๗฿ณ๋ิพๅVนไาห์๘จFศ�ท…�– € € € € € € 8็ZัR@@ C DLฌหš%KVั ข‡”พฝ{F}n€Q+)j‘@@@@@@_€ bโ_Cฮ@Hh‚ˆ๑w๙ด’แ?‡� ูฐz ๎” ฺe?�ดKFผ;4ไzม3ซีจ)Eฏผสฮ�~ใF™0~L๐*L#€ € € € € € €@‚ DLะ Gณ@@Œ"@1พฎไีลKJลJ•eืฎฒfีJูฒyณ์�๛‡œ~)_ฑขไอ›ฯo๐ฤqcdำฆ�ดŽ4i�Rถm�"+W,—Ÿ�I _|ฑ”,}ไฯž]๏฿�•A๏๔ณ๛ ุ @@@@@@HX‚ˆ {้h8 € 1"ฦืuิ bฅ*USlิท฿ฌ—iS&%[ฏ�cOHฆL™’อืB\�ษ"Y๖๙’ห™‰ € € € € € €‰)@11ฏญF@2ŒAฤ๘บ”/,$unนUฒfหฒa�๕—,œ?Wึฌ^r๙ƒญ’ำO?#ูฒC’i“'ห฿VPLถ"3@@@@@@@ แ"&�%ฃม € €@ฦ ˆŸื3็YgIม‚…$วY9%Kๆฬฒ๛็�๒�ฆ ๒�oฟฅุเ\นฮ–B–9rุ.žฟYฟN4ภศ€ € € € € € €S€ bฦผฎœ € 0ๆRัP@@@@@@@ คAฤ,ฬD@8V•4วA@@@@@@ŽŽAฤฃใส^@@ข ˆ%ซ!€ € € € € € €q*@1N/ อB@N‚ˆ'ส•ๆ<@@@@@@@ ฃ DฬจW–๓B@D€ b‚\(š‰ € € € € € €„ ˆ†ู € €วF€ โฑqๆ( € € € € € € €ภั ˆxดdู/ € €@Tฃbb%@@@@@@@ n"ฦํฅกa € €ภ‰!@๑ฤธฮœ% € € € € € €d\‚ˆ๗ฺrf € €@BDLˆหD#@@@@@@@ฐราฐ@@เXD<ส@@@@@@8zž-{F@ˆB€ bHฌ‚ € € € € € €ฤฑAฤ8พ84 @8"žW™sD@@@@@@Œ,@1#_]ฮ @H‚ˆ p‘h" € € € € € € A€ b!€ €}‚ˆG฿˜# € € € € € € €GS€ โัิe฿ € €) DL‘ˆ@@@@@@@ธ ˆื—‡ฦ!€ €_€ bฦฟฦœ! € € € € € €dl‚ˆ๛๚rv € €@� DŒ๛Kไ70Wฎณๅื_‘ร‡๛๓AHLiS&ส้งะ๘�iัชต|๛ฟ๏ๆว�„ถปuซRคศe’;wnษ”้$�ฤแ#Fส‡cฦฦ[sz{๎พ๋NyฐY“dว๙tษ็า๑ูNษๆGš๑D๛วคd‰r่เAiิดyคUY–A^่าYJ/&๛๗;๎บ7ƒœU่ำะ{GัขE%oพๅd9้คค ว?�#ปw�,๏r?9ฬ—ซu๊�.9sๆ”ฌูฒูเโพ}๛dํWkdษโOBnรL@c+ฐr๙็’9sๆdmฺฌ…,[ฑ"ู�๔œQญje)ta!|ฺ/ร฿� Uปึ ัค c%o�ผษถ:์=yซgฏd๓3๚Œ6ต–ๆ!‚ˆห—ฏ&อ[ค๊๔‡(ฅJ•ฐ�+Q:U�ฒr|่kไ�{๎ถYธ่Yท~}ฤ†ฝ��0น๊ช+ํ็ตโฅฎ‰ธnข.ฬ—/ฏ๔{ปทน๏\๒พท{๗ฏๅgd—{๎o$ง™/ณร ou{-ู"ญšxฯ�H–,Y“-ำkVฏ’9ณ>นŒ™ €วN vํš~Eฤ:ตjIฑbWูƒ‹ โˆw‡™ใ])ˆธบd™TtซJซ–ฺm��๋/๓พฒF6}�ฝž={ฎ,๙�๓Tํ/#ฌฌ!“๋ฎKrฬ–ํdyโ๑GํiDฬW7๕็Pฎ์ าทOR w๐กาณ๗�wr"/ฝไb๛แจˆบpะเ!าซO฿ืKอ žl/Zต4� oผฉJธลฉž�ตืJณfฅL้ไAโfถ’ฅห–…�็ห]_}o7hลู_~5�โ4อ/^�jyo่`ป}oะสผ_ญ]+‡�๙Gพ๙๖)Vป็ โ5eสHกBIaภbW]%ujืฒ็y4ƒˆE‹^!�฿๎2�ช�๙็�าผEKJ�d�ย@@@าK€ bzIฒ@@˜"ฦฤvิ7j๕p;9ๅ”S์q�2Am[ถศ๖ํ�ไ๔ำO—๓.ธ@ฮ>;ท๔x๓๕dํpท๛อtw๗อบuฆ2โYr‰v๖_EลฆO•u_ฏMถ-3@Žภ“ํ7ิ๎ฒ๗ bw‚ฏRนฒmk‡Žฯศ๔„�ƒŸ5kV.ทณb "�~k]�ๅ๕Oศ๊’ม–‰8M1๙Uำฐ๎ฤ๑สw6ส'‹�Šp2�— ๅหJ์F‡–z ๎Hทp–Vํ๖๚‘๎heฟ™ณ็ศf๓น๚œ|๙คZี*ฆ โ|rsญบษรญ�8๋ฃ้aทŒDฌX๑F้๕ึ›�ถcฦ—๕๋ฟ‘ซ‹3“‚sบPปl�โ‹•�z้5ขaM m๊0nยD้๒ย‹ฉฺuข�ป\็ฃD๕มนโ๒"ึp‹yพ=F�1ฯ๏&๎๗+ /[พ\š6o™*gVF@@@ %‚ˆ) ฑ@@เจ D<ชผ1ํผ่•WKต5์ถ๛M—ส๏$ ุ—v๑ฆ_ึบCAำอๆํ๕&mทŸผำทฟธJต๊rUฑโvz๗ฯ?ห{ร’*ž๘+0‚ p�)ˆ8โ�ก~๕ฦ๋หVํ2”!P -Aฤภ=1•ˆSี&Œ-… ถพ๔สซฆโฑฉ฿Iˆ-ดยŸV๚ำa๊ดา๑ูN!ึJฟYn๑ื฿~“‘ฃFKนnฐ]o๋Q"{ผ๙†Tชt“mฬิฉำฅcง็�†อ›=ำ�)—ž2uš<ำฉณฟ,ฝFiืฦ„ไฐป{ฒCG๙่ใ™้ต๋ธฺฯฑ"พจL7ฦž๗ไ๎{๏๗รตฺMxงgžถห๔฿rีkึ–;wล•A@@Hl‚ˆ‰}�h= € ๐ใ๏6kัZฒgฯn6t๐๙๕—_ขjไw฿'๙๓็ท๋ฮŸ7[VฎXแoื๒กถr๊ฉงฺiํnญo๏๒็Ÿ๚หAฑ�ฉjๅก‚ ฺฎ๔๔หใ-[ทษฬYณไ�๗G† \�yGCฉQญช Pdสt’�๕๗฿ฒัT|า ภ„I“X//Rฤ๏ฒu‘ฉ5tุ{หฝ ํ๚ถL้RvฒKื—ๅ‡อ?x‹์ใmuo‘7W—ย]$y๓ไ‘?�๘C6˜cNš2UฦŸฐฎ;Q๏ถ[ฅVอ›ๅ_๓_วgŸณวธฉbE)Sฆดไฬ‘Cด{สล‹—Hท๎oษž={์ฆฺต`๕ชUๅฺkหH�s๓[—ฟอ9j5ฉM›6ษpใฉ2ำsž1ว)).(`ฺนWพ\๛• ๚ž4ฌปœ|๊)๒๕ื๋ค_�n3�๑6ตถm,\๘"{O�ตk—�oรygภ Yตjตฟ^จ‘�ฝ�’SNNช*ซหตฒำึm�Bญšฆy๏๔[ฒfฮ"ห–ฏฐฯ›ซW“ห.ปTิ่�oฟ“้}$Œ•โ1RDŒๅšh5ฒฮ:๚ํะ`N–,Y์ดVํs‡;v`Rณํุ๑ใCVHLอ๋ฤm‹๛ša๕yY๗–:rํ5eไ�๓ฮณๆ_�ต๔~ปŸ}Nด์S๊rูc�7ฯษwŽ-zน�ฑwฏฬ˜๑‘ฬŸฟPฺทL.6ฯง฿�Cฦ›Š_o๕L๊>ื=fzŒง6ˆุณ{7ษ”%sภก<$ํŸ์0ฯ›pฏษจ1c$ืYนคj•Jreัข’-[6๛๚7~ขผ7|„ท‰�ุ๖แึR๔สขข?tx๔๑'�๙�ศ ]:‹†ฉถš{_ื_ถณO?ํ4ู้ใMษtR&9๔ืŸฦ๑ฉd๗C�ๆลบHf๓C‰ฟ�๙[Zด|ศ�ๅqyŒๅตฉ]โ�^ทฎmoธ็ฒ.|�ัvR๔Š+์z�=๚ฑGฺ�คyy๓ๆ๑+�้sQ฿�aเ !]˜ป]3ืพๅ6�๕y๑ซ‹ษฆ๖oฟ�._™*ึฯw้6ฌค๖z�"E.“<ๆ=Aฏม๖ํ�e�บoค�[=�๛น�ฏฝ๛์—ื^๋–๊cบ๛Jqท๛ไแ๏ ot๋žๆ�๊ฝrไˆค๗ู๔๎~9\ใ๔ต2ฬ„?๚่cะศŽ{4d๕ฆ้�๗าK.๖fสฑพ65ˆ๘rืl๋พ2มซป๏Kช็6W๗ํฦ๔^ค๗q ศzฎ๎บแฦ_yํ [)ฯ[๎nซ]ธj1xุฝ{�TฅZ๐l){�๕๒๊+/…}��๓n‚๊,0ž–c&kD:ฬะฟฏ\wmา๓ฑg๏ทe๐กi�ซ�ี๐๐๏หoพe๗ฉ๏ลธ>Vี\ฃ "+vฅy ณํำiZทุq}พMž4^๒ไฮmงฝ?ทีkเWุ๓ๆล๒่�ซRฺVปดพ๗ฦซลr๏าxว��T/�ีVฃ๒ย:j้†๚tzฬ่‘~8ฏiณฒฬฉ\ชห�/ศต๊฿�›๊l;ธAB ).XดH6š*@œพ D�d_็บbธn-�ํ“๖(ข]Gฎ_�ฝoh๕9ญฐ่ถู ฝif…i๋ญ*hŽ]ฆtำ=๏•�nค~ร;ๅ��}็Ow~๎Yั Œ:hXgึ์9ถrใๅหKพs๒๙๋… "บFz=>ž5�ฺj…0ฏ‹M�gƒ;๎ ฤ๐‚�ŽUQCz�ดŠฃ\ฝก๕รmๅ“ลŸz“ษc "ฆๆšhลดfMŽ„Hjีช้‡AG˜ิ}คื( "บแติl;k๖\Yบl™ท+‰๕uโํภ "z๓4ผฒn�zึฟ ภถ2hจ โถํ�ไ ฉ*จ•Cฝaง �n*$zีจฦŒ๏W�๓ึIG๏๙MQ๗|็g%Kๆฌ๖ะ•*U๔ฏM4ADป‘๙ฃแฟ;vศuื]k๏ :?Txอ  i— ฉ "๊็qŽ๒ป‡ี0๐ฐw‡�รทk๓4�๏๙ฅฦทšิฑ yู�ั๛zpH8ฺืๆย๙sl…X�eจฐ—V9ำjg:ธK y{ฯซ /ผะVํิu6l�hชพV?a’h{ผมป&�ดี?๙t‰d?ใ <ฏdœขห4ไ\Iwๆ๔ฉ~ˆ^ฏทพ�ฬ-Zn๘?{w.Eู†q�!”6PAR0€OA@Eบปป”‹ด@‘‘”n้–ดฐP $%มožw™qถงฯ๎แ?\ืู้y็7รต๗>๏“O8็๑๓/ฟHอฺžบ}Œ˜ำ�GL๕:-๖คT(WN*”/gvงฯหšx}žD๗8ฯu๋*ญ[ต0›k…ลวฌสพ ด–ซG��ำTK}gุ3W�กด`ŸEฺ%ณvอฌรz+�ี I๋ ๏ ujy>KอŒkดโจ�wฤtะส˜ฉฌ๊ฤ:ใuYรฦอผ^'๖�‘��่็์^๋ตuฬ๚ผาฯจŠ*ˆ>ŸtXฟ~ƒt}ฎ‡๔ว�.‹ซ โœYJž�นฬแํ๛#ญโ;๎,งBฝ�ถ/พ๘RZถigO๒ˆ € € €@Œ"ฦ˜ € €ฤD€ bL๔b�\น๓Hี๊žnท*ขdบึีฒ๏‘Ž๛SฆO์5�ฎคx��9?vดYึชm{น�๊ฒ๑Ÿ.หฎ;ไ‰"Eอ�=?� ห–.๖ฺž nD>/ฟ่Tิฎ{ปX•E๗Yแ>{ะ/ถ{๕๊.�ถํOV�Wตฬ�˜^*)Rค0ำ=Ÿ๏muoฝฦY6๛ร&8 3|ƒˆ๎เš†Dฺถ{ส้žRืะฟฏhืิ:ธC@f†๋oะ!X๘รตI”G}รNพœ�aL i‚ Q "F็š๘W+oiT<๚_`าwฝ@ำQู6บฏ๛ธพAฤ�Vwเ=z>๏๕ีuฮ9'๊ฏ�ฐjED}+Qฺ<ทwm�ิ้๎Tป3ี€�ง›ึ›0าฮ]ปคํต๐ฟ}ฬุxดŸ‘ "บ9eโ)Xฐ€™ู ข†ฌด;[๔yนt๑Bน๓ฮ;ฬดo˜ว E5ˆจ;ำ๊{ZYS๔p้๒eiiฅำคNcU?mๆi@ธM๛Žืํ:�4,�ฤไต๙๒‹ฝญ๗๏๚ฆuบถรูบยณ=zyฝ�งTฌ่“2vดง�oญ์ง�"์kข๋่gF“ฆ-œ๗ๅŽํ�ษำ=?Pั๐y—ฎฯ9ป๒zฟดย‹ญฺดw�ปตฒ์ดฉMwทบ;`ฎำั=ฆnำAรkeK—‘4iR;]ฤ๋>ตบ็่ฑce๖œy1=„ู^ป3ึnฏ7h(T_'q5D&ˆ่พ–v5e �O4ม�ศ@รjงญhˆN฿๋mืPbซ–ออฎขtŒฬ{—๎�~ิq�‘B^ฝuิ ใฦŽ2๏3:ก๗Uze8lาจ‘h๗ืฟฺณอฃ>฿็ฮ�@ดบขพ=Z๘ ฏๅ๎‰๘"ฎ^๑ฑdศมถ|ฅ*ฆBฃ�<ะฯ�!VuN;ะ์{Ÿ่n+ใ € € €DG€ btิุ@@ ึ"ฦeฌ์่ษb%ไ๑'Šxํ๋ิษ“r๔ศImuešูชฆกี u๘๊หฯeํ๊Uf\ฟx๋๔Œง›ฤฟฌ/*'MxW ,(ฅJ{*ฬฌYตB.[กJUช™๕[•ตZG( H [ถ`m๛๛โE็ z bใัฺฤG๑ภRญfฏfปึZL+„ูƒ@‹NQ๗กAj T๋ ก็dI“ษ-ทค3ำฑีฅฎูY �ฤไต้~�๚พOFดฬ��˜๛๔ํ/๎เท๛\|s#†‘าฅK™C๛ฎŒŸ0ั� yถ[iำชฅ™g‡�์์็NGๅ˜๖๖1y9bจ”*Qยo‘้ฦ�oฃfL|oœWeZ จ-\ดXฮXUQณZ?๔ฑC�บ w…ฯvญEvM7ŠืฯD�lิaึ์9๒ฦ ทdมผูr�}๗‰Vญื ‰ดoืF๔G:ธ��{Zณ#ื๗}F|๕zTฎVรซe๗{�‡3gษ ท†ธZ๑จ†๕ตงC jฆ๖ึ‘ "๊k/บ�?ูตcซ�|“งสญส�๗E๚Z2lธฌ_ใ๙qK ๛HปญQyŒ๎๓ &็�cFwป„h+ว �,Œญ�‡�;s@@@ ฆc*ศ๖ € €1 ˆ#พX฿ธ„U!ฆ`ม�ชSํู๓ฃ,[ฒศ9Nถ์ูญ/#›้+�\‘‘ร=_ะ�rหญาถƒงbฮ)+0cฺdy๊้ฎ&cWOฬ•+ทTญแ้�Mซ-ฮ๚ะำฅขณ๓ั/ขึYญ$I’D๚่v0 ฟ>Vwuž๊‘‘�X+ฬ9{F�xu`d71ู๋[/œ'vทu‘�A๕šuๅแ|yใ�˜ญ[ทˆ–ฯŠ•ซโ�šฤไ˜‘ฝึำ/ํ ™;ธh]๗<๗—ุ+ญnƒ{Zี }๗โพ]0k…ฃG๕T<{ฆหณฒq๓fณนVnา N:๘V๛sNt๙๏ฟ�ฎ^ฏป3�mๆ้฿`‰ฮs'Lœ,ฃฦŒีูืด;มอ›Šv7š!ร]Nทฑ)Rค”[oฝลl๏ฎ่ วไzเ~™gu๑ชƒoq�ฺUN/ญˆxล d๊`ฟG่ฃปk็Re+ˆ06+^๛ฃ๏-ฉฏA/[a9๊^+ใ๎็vฅZฎbฟ�ฺ?]PฅZMงZ™๏ŠQ "F๕š๘ฯnW\c๚:ั6ปC)$ี@iDƒDิส‰ต๊xชฺู]}O4�ž"E sฟœฟเc๎ลฑ6™ ข๛พเห/ฟ’฿ณ�;ํ{ }ฝ6oีฦซk๒˜ฦd๛ุxmฺU/]พ,%ญje…ฌเ๊(๋ว!:|๑ล—าฒMป MŒn1ชแะอึ9�b "บด*ฌVfณ;ˆีcฺ�ว๖c�:ตฅ_OeOw8&วy๙ล�ึ}�ตสจ๓ศซฏฝแท;๗gk ช’~DcFd‚ˆ0ิ ก{ะ$ตlำึTึ๙v€Zวํฎ“๕ว1ัฝงี�ธ‡๘"zนzพAฤi“'Š��๊ ฏหอ›6ห�}๛dีฉ]S๎ปฯ๓ƒญ�Š: ‘ "F๗ž��๙๓2gึ‡’'w.ฏรป+]kUlญŽญC ฏ #1ก๏9แrฯฯ�ร‚_P�jL�O”ฯƒเgร@@HH‚ˆ ฉฯฑ@@จˆbฯดiำI๛kažS'Oส”I�aชTซ.น๓3�Aฤˆพคท7{ฑw/i�ศS‰iษาe๒J_๏๓,\ฐ Lš8�ฌ๎"บปf1jŒLš<ล�ฅyŒจkๆm[6I๊ิฉไฒี%sมkมiฏChย๒9x๐ TญQ�ฏu๎ ขVGี/˜ ๎ ข0 ด^tฏ‰๏พโ#ˆฏwั๎žิ๗\�ำกDŒNภฤ�ํq p™žฏV=jธ9๕จ�aฆ@๛�|็6S5XQรsf}`*บํตk�บ๕…DUฤุxmบซฺj7ธ?๔”/็้>ต�€Weมขล๎ำ๗ฏ โย๙sฌสjžฆ๊ฆ�๊๚ๆ›oฅI๓–N;C-ˆจ:ญ@งร้ำI๑RžฯOงมืF|+a๙ลW~ก{{๗g‘vw�๚›ƒํEฮฃป๛�@๏ัฺฎ�qึื‘>ŠZ%๏ศ|~็ห๗่๛ฒ{๐mณ�€แ๖kัใ"4สADฝ_[น|™$I’Dฮž=+ญฌ ฐ๏็ฉ๛๓6ข{w1ะ๛ง๛Dw�}อuNฌUงžh X‡อ›Iฯ๎ฯš๑ีkึH๗kUํอ � € € € C‚ˆ1ds@@˜ P1f~qฑต]ู๐โ…‹2nฬฟC4l�T2gษjๆฯ›3SZUสtpwูฌnfผ?EŽ;f–้ŸŽŸฑ>iฬ๔๛S'y-sVbL`๛ง›$UชTข•‡4„ฐo�ฯืp~=๐ซh ภwะ.ว๕‹s*Uฌ o ๒TgZณvญคI“Vžx�1ณ~ เโห/พ`*r๊ cฦพ+ใ'L4๋FๅOTƒˆ๏ฝ;ึi“viฉ][บ‡ฮV—อOuhofนƒˆ5ซW“W๖7๓uy�ถu+้ึ๕ณ�]Qgฬ›3K4จจCณ–ญœJPfF�hธ$ๅอ)œ-:w้ฉk๋l‰wุI+ย•ซXENœ8แตๅฆ๕kๅึ[o1๓…พ์•ปuyZดหe†[• 'Of/๒zŒ๎5๑ฺ‰5aW ิ๙ตหw;Žlˆ16^'แDดร|ชู๊ผธ"ฺี ๕Xพแ5wp-Xัฝ�ฎ]Ÿ™nm~๘!�ธปh73�ั๎สณgหๆ,:lคlฐบvอ!6^›y๓>(lีแ๐o‡ๅฮ;๎4็jWฑจฝ๎ โฌูsไAoEดบD78n์()Zคˆูท�Uฏ๛@6—^x�ฬZตz๔่ี�Y�c:;ˆๅw…ธฃGš๗S฿Cธซ�ห�›0IF�๏G7๖|}tฟl฿ฑSฺw์ไ^lฦทnูh*�kUุ}ไัย~หป>ำYฺตmใ5ฟ]‡Nฒc็NฏyMธCiมถี็ฌ])Y๗๕ว๏H…*ีœ�บŸช&;+ฦ`$”ƒˆ๎>l�๒ฉt~ฆซื™ช฿ +จxห-ž๎ฝ# "บŸG๎*…^;ŒแDฏฯI๓fMฝผ=dจW็ฑฃGšส๎บBluE๎Œ@@@^€ โ �@HX‚ˆ ๋่่M›ท’ ืบ�;{ฆ:xภkต.ฯvทชy*Ž๚ถี�๏UณผPแวฅxษRf�ทbฆL™คa“ๆฆ’ศ๙๓็d�ุั^๛dU`ย๘q๒๘cž๐Aฐ๎™5่๑ว‘?œ ›~แฝv๕ `Tทฎฯ๕๕๋78„Zฑ้Wš้ˆB+[6ฎณ*!zพ4ท7>v์ธ”)_ัžt+”/+C�๒TsาpSMซฒŽo่MWึ๊Mูฒf5]M;_‰jqฬจRผXQณตo8Nซข-Y8฿๙า฿Dิๆฒฅ‹ๅfซBซ†;:?�Uถl๕TnUปนV€Z�ฉƒoัธŒจš\��˜ชฏม‚ฃvืธๆ ึŸ`แ{yt๕\4ฤbT'{จ[ป–๔๋๛Š™ิnฒซTซi/๒{twKชV:{บ�๖]1บืฤw?#†‘าฅK™ูz,๛๚๘ฎh:ฒAฤุxธƒDแTqลฒฅ’)s&รี@m\฿xํUฉVตฒi›ไ4(g๔“Z5ช›ษ@ADw๘๘๘๑Rื o฿tSr™?gถ๓^0lฤH™2๕}{—~+?�H๎ฮtท3฿ท ฮ‚ŒฤึkS๏มr็zภซ% -’�^๓š็;แt๎��ตช๖„Œ}ืณงฃ tวu?๎lyเ~OWตพฏŸ่ำnsT5�ฅ]y{ฏฑ฿Wtฟม��2๛๘u; ฎŸEZาจw5�๙ง”ซเy]ุ๛ึว๘ "๊ฑ�•”}?G*ฅJ–ะี$P…bณ †�ฯงˆ*๓;Ld�ปt[๛๓9ะgผ๛ตใ๎š๙y๒ศ์™3ฬกOXใK•)๏ี ฿เ_DADw5์่„ลฝdย}บŠ๛s@C๚“'N0๗H๚ธŠVเิฎ”dwฬF@@@ Jฃฤลส € €ฑ-@1ถEcพฟ\นr[]|ึ2;บ|้’,\0W:dย‡š4“ป2xชฌ8q\ฆM๖ฎŠึ๕นž’,Y2ณํ7_๏–ตซVZกฦ Rว๊.๑ๆ›o6๓?๛lงl\ท6ๆ e$ญพ7๋รฆ+R=~�#๏ฯ˜!ฌJฃw฿}ท”-]Z*Wช(พaญ2ฅ!.\ธ ฃวŒ“๗�du฿™W:=ีมyฝEิํŸ†}ป™œ=gžี}ไ ณ_฿?๎/๙๕ห๓)V๐ํห�ปอjฺ=g™2ฅDƒฟZmฏYปž๏ๆี โs�บJ๋V-ฬ~4 9w�|ซK๗ฯ${๖l๒t็Nr็w8วpuๆ๋ฏ๊ีชšๅ��ท,ดบ1=y๊”h%ศœ9r˜๙๚ว7lกขๅ/•�nฝีฌณ�็Ÿeส”i๒๓ฏฟHบ4้$w๎\Rนr%Š(d์ลGQƒ.Sฆฝ/�ทํ�yrษ3–‘�พ๋[ ษn—�xO๖{dั‚9ฮ๛๗O{๗‰vั}ษ๚ ะ์ส•ซอช1น&๖ฑ๔Qป„ิฎ!u๘ำชœ;o�S๕M+;žž๑มLykศ;๎Me@�พR� ้ �สึฎื เ{Ÿo%ุ`ก3ฏGqยท"bฐอฏ๗ฺิ�ฌ[ณาy์�ฟ_jื๕ะƒํำž฿็•—ค~�:๖คืใ›ƒ฿–™ณf;๓b ิเป~†4„ฉU*งN›๎ตJLŽ้ตฃHNุAฤ๋ญพ~รF้jU�4D'ˆจ๏uฺฅ} ฯ"๛ฟ�๖›Tช๊y๎ฺ๓์ว่�•ํ�z๔ํ~YืymเฉQ�โดMdบ๚ด]dๆE5ˆ๗.m‡ฝ]Tƒˆ ึppd†๋kVฏ&๚™›$Iฟ�•ฏTล+,๎ทB$ghq�˜Qฮ+|7ำฯฺVwแม*;๛ฎฯ4 € € €‘ ˆY)ึC@ˆ‚ˆqย+;ญQปฎไฬyฏ_8JปV^ผ`พUม่๗€ว)๐h!)^ข”$K๎ฉŒจ+้ัว“้S'�†™�่… ”—^๊m…�๎๕ฃะส^Cญ ‡o…/ ฉผ�ึ yฒศ^ฏำ+Vล› V˜โๅ>�q�Xฝโc'ฬจUซี \ฑทัcพ๔boฉXกผSmฯ^ฆๅoพ๙V>๚xนWwซ๖๒ฯu“–V•,}?จ฿ฐฑ์๙iฏฝ(่ใฃVีจ~}^๖ q�zเW้guOชํ‚9PxD�ฺืฺV+Oi`S+G~๛�๗2g๎<ัŠq:l฿ฑSฺ[_ฤ๛ไุฟไห๗ฐS%ะ^G+ฬmทช}๘มฌ •๛vn�")Rคฐ7‘ศV1s6ˆฤˆžŸ�5ณVงR�‚u‚ ๊�้ถmาณg๏๋>์รi Hปแฮnฟ๒�ปoŸิฉืะ^EbrMœX#j�บusซปฯ’r๋-ท8ฮญj]Uซ{*ˆนืทว'พ7Nด–^ฯวŸ,nฯ๚“ื‰;p7d่py๚Œ วั“'พ'…ฌkเธุ�ฏ๋kCปfีaิศaRฒxqัส“u๋�gkฦา ?�|Oษ�ภขA>{ู่๛งยฅฮ�ฑuณtณื ๖ุ๙™ฎฒyหงๆ90uาณฺ่ฑใLลV๗6ujี”��๚˜Y/ผ๔ฒhง๎กXั'ๅอื_sชด้2ญX:rไhiืฎตdษœล+@๋(}�ราฐฑงšฆ{Ÿ:พศชเ|oฮœfถoWภ:ำ�ฝชNkติŠUช{Uิ๙1b๓ตi๖ดMZ1O+็Evh�ฆตฉจ›ัz�ณ+โ้ถ�๚”…‹—8ป™4แ])\จœ?Až(๊�šZพlฑ฿5q6ถFดฒn๏ž=ฝŽกหOœ8!ฏฝ1XVฏYใ^�Œว๔˜~;ผฮ ญWซfuษeฝ์ส�๎Mด*�ไฉSECฎมําVƒะ๎!2ืDŸC‡พ-…-่ผฏ๊>๔=zี๊5ๆzœ;�ฝ[gผC๛ถฆบญ3รน�็‰†�^ุ฿ฝIภ๑`?xมz฿ะ*ฺn{ะช–ณfฯ•Qcฦฺณb�ัj่G๖ฃ๓�ฅ�ฺ�๊‚;k–,๒ั’…ๆžj�ยE2`เk๖แฬฃVูญg|ํภดฮิือา–Y๏'Mฅ฿ศ�ใ”)SZฺ[ฏัœึ{V๊ิžชขฦ.WฑJฌฝ'iีํมึ�Žพ/ฺกGฝWะฯžžฝ^ฐ*ƒ�๊u~L € € € cC‘} € €D[€ bด้โmรlูณKฮ๛๎—ณึ—๛~ฺ#Zี02C† %ฯƒสqซโฦ฿}'Wฎ^‰ฬfฌƒภ - _�็ฮ“[2gฮ$'Ÿ”ฝ๛๗Eช2ކรt›C‡๛ใ Tƒdนs฿/ึท�V0๙ูทwคoQm“†ช๎ป�>ซซเหฒำ  m�ฏบฺ�ธร$ZN+ฤE4hUกœ9๎‘ณ็ฮหoVทž‘ PFดฟุZฆ็dํ@…ฮ+bUบผ|๙ฒ์อิ@IDATฺตห9็ุ:ฆ{?1ฝ&๎}ลืxBผNโ๋�ย๑8๙๓?"Yณf‘=V—๔๑๑บrw ญ^ณ็ฬตบข๋tฑ๕ฺิ�lXทฺ„พตl‰Reโ๔5S q=๘`๙็สU๙๖�o#๕ูำcFu{5อn�ืj8=�-iฃ๔9ีcZ฿~ฮ๋g๕O{~ ้๋i>๛rๆˆทืg ฏPœงฯกผy๓J†Œw™๛ G‡๚ m~�‰วอขs๊็G๛@@@BK€ bh]Zƒ €�poธKฮ #€๑" ]b9rิ๏Xoผ๖ชTซZูฬ>b”Ukš฿:แ0CƒพAฤph7mD ก��๓jEอสีjฦZๅ1๗9ลึkSซฏi7ป:ฌ_ฟAบ>ืร}ฦ@@@@9‚ˆ!wIh € pc Dผฑฎ7g‹ฤ‡€Vk\บxพ้�uลสU๒ฃUy*yฒคRก\9ฉ`u+ญร_‘Š•ซ†tEชˆฌb+์ั1X†@b๘tำzI›6ญ9%ํf[ป�Ž‹!&ฏMญฺY ~)๖ไ“Vุ๙๎T�ถ๋(;?๛,.šห>@@@@ˆ5‚ˆฑFษŽ@@ข#@1:jlƒ ‘€D ถฮีซWeะ[Cdึ์9มV ๙๙1 ;…�ษั@bY@_/ณgฮ�oฟ]ดbอฺ๕โ,„“ืๆ;o–๒ๅสz�ข%Kฅoฟ^๓˜@@@@@ "†โUกM € €ภ $@๑บุœ* Oz๓อืไ‘|๙ไ๖�nsŽชค}๛๖หaรๅ๓ฯฟpๆ‡ใˆžใ†uซ%y๒ไฒfํ:้ัซw8žmF ั ฤไต9p@?ฉQญชhXz฿�ŸeใฦM2jฬุDgฤ !€ € € €$N‚ˆ‰๓บrV € €@ุD ›KEC@ฐะPะw�%�พ GŽ หs ั € € € € €„บAฤPฟBด@Hไ๙ๆ๔@@@@@@@ ั DL๔—˜D@B[€ bh_Z‡ € € € € € €\O€ โ๕„XŽ € งใ”—#€ € € € € € €q.@1ฮ‰9 € €@D#าa € € € € € € ๚C�ัB@@ Q DLิ——“C@@@@@@@€ โ p‘9E@@ ”"†๒ีกm € € € € € € €ภ๕"^฿ˆ5@@โP€ bโฒk@@@@@@@ "ฦ2‡@@.@1ธ K@@@@@@@p ˆW‰6"€ €‰X€ b"พธœ € € € € € €�oˆหฬI"€ €ก+@1tฏ -C@@@@@@"#@12Jฌƒ € gใŒ–#€ € € € € € €๑"@1^˜9 € €@0‚ˆมdBo~๚๔wศฉS'ๅ๊ีซกื8Z„ €ฤ‘@๚๔้ๅนsKถ์ูฬ}ะ‘#Ge฿พ}r่๐แ8:"ป e^=ปหฃ ศ฿/JซถํCนฉ า6}ฝไห๗ฐdห’ENZ�w8p๐ ์��M‚ด…ƒ&œ@8ฝNชUซ"M76X�๚=?ํM88ŽŒ € €„นAฤ0ฟ€4@w‚ˆก{“&M*ต๊ึ—Œ๎–)SH’$ILcฏ�sEŽ?&LŸด๑7฿|ณ”ฏXู๚ย�Ib�;แผL›฿P|๔ "~๙ๅWาขตง๒™ถทวs�คe‹ๆ^Mฟ^Qซยๅษ“[.\ธ(รFx‚ฆ^;ธม&*”/+C�๚๏J฿~๛,^๚‘�๚หฏ’ูชŽXถlั็%Aฤะ}b๘/Z�Ž?Vค˜ำเลŠษ่Qรiน^1œ^'>ZภzO/oฮoา”ฉVD๕B`@@@ภO€ ข 3@@โS€ b|jG๎XyzฤชjXษฌ|�๚โ}ฺ”‰ข_Fนญvจ]ืน‡‡๓ๅ—r*šY_๚[พ��syด`!น้ฆ›$\‚ˆฺxญˆจ•�ADทใ €$~ญ[6Švsฌ๗0mฺw ฐ๙.,ษฌ{ขญ�ท๛.2ำ  Lˆc<๙™้Dิ๛ื2ๅ+9�3/_ถXฒdฮโีฺ๋ฝVfBๆฬ๚P๒ไฮe$ถl�*:w๑Sั ›7o๖[ฦŒ„๐ "j‹๚๔ํoฅ:�ฦซฅZต*:๊ ื ":+2‚ € € pC Dผก.7'‹ €„žAฤะป&ํ:v–t้า™†M™๔žœ:y2Rฬ็Rฆlูนcซ์ฺนรl๓Lท๎aD�๓ุ1)k}Aํ‚5  �˜•,Q\r็ส%w�uง�l/Ož:%?๏�Yพ๘๊+1rด{Wr฿ฝ9ๅๅ_0๓Ž�yLžxผฐ�v�m๒ใž=2๐ต7คqร†RบT ำ-๖�}๛ฅgฏไืฟzํC'๒็DZ5o&๗฿Ÿdษ’Eฎ\น"๛�Eถm�.C‡๐[Ÿ € 9�ฌ^8ฎY๙ฐUบrีš‘�ะZซ๛ณ�ไกผš๕3dธKฒgฯnฦOX๗S๛ญฯu๗0aโd'ฤจ!Ÿ:5kส+(w๖์yฒHSez—๕รŽAƒ†Hฟพ/› ŒWญฯ๛ํ;wJ—ฎฯ9ปŠ๎1X# ๊ื“บujIV๋žB๏๕พโิฉำ๒ำ�ฝ๒‰ีฅ๎‚E‹�ซ‡อธDผdU๘Nš$‰$Ož\†%“งNณ<’ำฆšsนpแ‚คJ•สŒ "Ž:D’&๗๎v๘๏‹Kฯ็=๗tม@๔^ฑ}๛ถRฎLiษ!ƒฉ8ฎm9y�„|ต{ทฺ้v็gŸ�<ฎIฉR%eไฐwL๛5ด[ฎb'ไ๐คฬ์ีใ9)Xฐ ไฬq\พ�y��ดoŸL˜8Iv๏�ฦk‹บตkIี*•อ<๗๋วk%kโทหํึ�๕น ็ฝ^+๖zตkึJ•+Z๗ๅ๗J†ป๎’3gฮศ>๋๕ฉ•็/Xhฏๆ๗h�_๙W^zฅฏ.Tะบo/%… ’�nฝี�`ห–ญ2d่ฐ(;๘,gธƒˆ๖kaำๆ-๒t—nฆ›7ฌ“[nIgU�๏u(ˆ˜ฏ _ทjู�บ–๗I๚๔ท›๖�๕ื9t๘ฐl�ฒEฦŒ}7 ไ๓={Hถ์Y�– 2<เ�ฝtE๛ฝVŸWƒ‘NOu�ไ“lVZY�›๏พ•�^ ZQQ_/-š6‘<�ห#ฉญ๗›Ÿ�Yถ๏ุ)Ÿ๙ฅTฏVีด%ขใ๛5– € € €@ D ม‹B“@@I€ b่]ํg{TJ•,aO๚=ž;^Š พ�oƒša[ม? U>๑๘cข]7nึB^zแyiิฐ ก}๙ีn)^ฌจiนo1}๚๔ฒ~อส€g•ฏ@ก€๓ํ™๚<า็Sฐ!Xมpน&/<฿Sš4ndNฯ\ vพ๎๙3fฑฃGษึj ุ๒ฮ0™5{Žณธนโ๊ีณป™^นr•๔์�ขณฬษkgฮx฿LjMฏง=h0๔ี�ค\ูฒ๖,ฟวˆบ~ๅฅLhW7š;oพิฏWืo{๑RŸพ๒ัG\Š3�ADmทฃ/]บ$%K—“"V(z่มฆู-[.ีชz‚ พAฤ„xhQร อZถ๒ ด๊๚ห–,4B฿mปX?ค�ฐqฃ๏l3ํ~ฏ=x๐`ภํ๕ฝฆtน ~�7nิPžทžปษ’yš}W์�LW+@๙ฉ๏lฆ@@@ฐ ˆ6—І"€ €‰S€ bh]ื[ญJmฺ?e๕�ท฿ศกC%฿#ฌ๊้ๅ๊ฟWๅœีU๓๗Vฅ‡�ถFชแแD์๘ิำ2��1ๆผ~๛ํ7ฉTต†sŽื "�๛๏ฟฆหฦฝ๛๗ห1ซขข~ฑZฑBำฅฃ๎d�๚ า๕นf๎ ขVŽ๙๊ซฏๅก‡”)R˜ๅx๘ส๚2�ยดICHZu๙ษ'ŠX�S_–วŸ,nึ ท?๎ โ่ฑใค_Ÿ—Eฯณj๕Z2u๒Sฅ๐ใๅ+$UสRบt)szพADูฟ฿+’<™็๙PฆL)Ik�w้QฑsงŽ๒T‡๖f=ฝ~ปฌ๛5ฝ†)Sฆ’|VX5_พ‡MELฝuแtM†ฟ๓ถ”ฑช=๊ มX ศFv๒ึ ฉPพœY]+!ฎ^ณฦtu�@ฎฌ๊ˆ9ฬ| #Vญ^ำ๙A 7mXk~Œs��yขจ�๓าŽœ4eชWurwPŸ6m’�๛–lYณJY๋<’Z]ญ๋เฒ33ญ?๎ํํyงNŸ–~๘Q�พ๔ท�/OSa1œƒˆฤ9�๓>3`เkRไ‰วญ�”��ั3g›๗*=๗@F๑๙:ั6l�t“Sษtฏ๕žจโใวK–L™ฅx๑br๋ญทHฐ ข�ฐKซส๋�‘‡๊ต‘ "๊vG•อŸn•tiำZแึ2ฦL็ณ>/ฆL๕„auZ�oธl้b็3eฟU q‡U ๑๎LwK)๋Gj๎ ข[ƒq@@G‚ˆแxีh3 € ˆ"†ึลฬ•;๙ฒO[๕ป๕eSฆฬ™6๐ุฑ?e๚ิษ—นg†SQฟHž4แ]ซ‹5Oe›~�สยลKฬ้ "๊—JM5 ๘vŸฌีoๆฮ�ภtมงรG ?a๖ๅ"j$ญ†ิ๕™ฮาฎmณ|�ยEข_๚ตmำZบu๑|1�ชm{๙� ่ฐ|ูbษ’ู๓ฅู๔ศ�Vฅ{ะ๎็ฯeพำ/W›4oiช�ุหyD@ศ ผ๑๊@Sฬฝ๖ั?�4?ุถ}‡|�๑r็G๎u�ใฺeุ่ั#อฌI“งศˆQž<ธืฑว�Aฤg{๔’ตkืษดษฅ@�f•^zY40ง๛ำ�j@ซะcE์อวจS7r‡ๅUดำฃ*X@VฎZใ#œF�Aฤj5jษ†๕kLHฯีฎ€จมฃ:ตjDDtŸ๓”‰ฌฎ„ ˜YวŒแcฤศัขก8๗ กตTฉS9๗x๖ฒpบ&ณ>œ!Z�ฬ๊๐� /ษ'+WŽดฯอ~ิ๎ฯ็อ™eชรi7เ�žํ!7oถ›.ณต๋l๔~\๏หํa�ุQRิชางรKฏ๔ญา็์kฎ๓ชืฌ๋�ฃ๋1็ฮžiBŒzฬVทฺ๚:ณ‡ีซสk˜ษ“Vexญ่;๘ื[•๓^|๑ฏ๗ญlบn�zำ5ฐ๏๖ก:ํฎˆXปn}yอz�ห๛เ�ฬs3๕๊ ,พ๖ฦ ™3w^คhร้šฌY๕‰�u็ๆผฺถ๋(;ญช‘�],o�พ]|ซBjะP‡:�ํฐTฎZำูmอ๊ีฌ๎•๛›i vต‚ค๖เงiตั†›ู‹Lพฺ•ฏ๚ฺี ๏เ๎ฎWทต+–ฺ๋นƒˆZUะห–ฏd/ ๋G฿ bฉ’%ฅ[ืgผฮIป34�X"F๗uโฎzไ#Rพฒ็�?^ŽไDt‚ˆ}๚๖—ลK?rŽ Ÿ[ทl4ำพฯ=wํ:wํ’�=lูธNาฅKgfDtห0Ž € €แ(@1ฏmF@‘Aฤะบ˜%J—ฑ*ผxบิ–ํู๓ฃ,[ฒศidถ์ูฅ^O๘ํส?Wฌnป†8ห„[Qฯแร้ำฌฎ’๓šำ้๙|oS(XED๛œ๕ ัาฅJš๎�๎ผใIš,ฉY”!C{ั/๏พ�๖;ฏ ข]�จ\ูฒ2tศ`ณฎ]‰ั�ฌ�ฝ›๛K[]๙๗฿~7�ุ�6๊Dฦป3:�‚-ZฒT๚๖๓Tv1+๒@ข$ Uาjีจau‰�ˆ�tSrฟmืฌ]+ฯ๕x�oพฮˆJ(ะ]ฑHัฆส–;tXชl9qโ„<�ญ‹ดiีาฯž็>xTŽฉ�นซภi5ๅOทm“M›ถX�H๏’=?ํu๏:,ว}ƒˆ๎›žะ’ฅหไ•พ�โ$ˆ8p@?๋นS�ธ]ผxQVฏ^+�vl—ํV—ฌGŽ ๊Nืd๕สๅฆ+b=™v:ษŽ;ƒž—{ม๓={Hณฆž�Sผ1่-™5{Ž{ฑ�tำzIkuyจ๚็ถ-›L•>ํB\+jืื:๔๋๛Šิญ]หŒ๛Vกt‡Mu…@๗ัฺUฎ=๘อtพ;ˆ8aโd5fฌฝzX?๚ฯž;'+>�ศ๙ฺมƒฅjฺโ�ฟHlUDŒ๎๋Dซตฎ_๓_N}ฟZฝz์ฐ�ป์J๒‘ฝ(ั "–ฏTล๏u�้ๆ ฆ�๖}๛๗[?Bkเ�๎B:Xwโ#G uบh&ˆ่ฐ1‚ € €a*@1L/อF@‹Aฤะบ’ฌ.ฎJ]๋†Lป,m})r๕๊UฏFถถช�v�mf�dซ+ใำงO{-wO„cั]‰๐ป๏FMšIฐ ขvอ“6ํ;z�ฃล $ปU�]m็‘ฃz-๗ะ๔:|ุkถ;ˆ•ฎจฝv‚‚ˆujี” <�/์�ฏฟฉ•#&ฏ“ ๅหZ�หท“�น๐“ี@b‡NO›�ƒ๙-tอˆjQจ—ฟเcฎ=xF�•ํส’พบ� "๚๊0 € €แ&@1�ฎํE@™Aฤะบ iำฆ“๖ึy:œ:yRฆLzฯฏUชU—�y<•Oถl�(;ถm๕[วžฎADw—xŸ}๖…ี]u๛”ฤ�"Tซ!ฎ\พฬtƒ|๖์Yiีฆ_†Z-ฑPก‚f�ุ"vl฿Nž๎�”ู฿{&ษ่ฑใœv1‚ €๑'ะญ๋3าถu+sภ•ซVKฯ็_๐;ธ๛‡“&O‘ฃฦ๘ญcฯT1>ƒˆv;4Tพ\9ฉ\นขW•D Zjเ2�†@Aฤ@็WAD๗ฑดฺuๅŠคผVิดช๖ูƒ]5�ž๖} ๅkโ๎bู๚ถ?ะt฿>/Kฝ:ตอ"ป๒ท๏zvจ+X่Kปๅีื?��#ลK–‘>ฏผ,Uฌ็ญฏพ�ฆฬ7฿k—ใ฿#E�ฬ‹J7า๎ธƒˆ๖ฝฝ{yธŽปƒpต๋ึญˆhˆซ ข๛Xั}่�อŠ-*ีซV‘�๙qบ•�ดy‹<�ฅ›๛~ใqDิƒํ�ถERคH!ฺๅ๕“ลJ๚ไฐwคT)ฯ|‚ˆ~<ฬ@@@0 ˆfŒๆ"€ €‰M€ b่]ัn�{™/n.^ธ(ใฦŒ๐k`รฦM%sO ysfสม�ึฑg„kQ�ฟl้"งา‘}>๚h [�XOš8�,ฺผๅSั/�ƒVKZaoน%™mY้ฎเีŠˆZ๑cศ[ƒอ�v์�)๚%* €ฤฟ@�ฺตค_฿Wฬืฎ]'ฯ๖่ๅืwqึ์9๒ฦ ท�ึฑgฤE๑zวด์ั]ํn‘ีอi฿~‚ญฒ๓C)ˆ่FZe�#fผ;ฃ™ีงoYผ๔#๗โ ใกvM�ฯqํน’ีํ‘#Gƒถ฿^ะก}[ั๐— / #บ‡{ฒ฿#Kอ3?๘๙๓ุ1)[พ’{ฑ๏๓สKRฟn3ฎ�ทo�FาฆM+��ท”*S�ฏ‚็ห/พ ิ3๋๛ฎŒŸ0ัoŸื›Aฑ‰๔ู๊�0ฝ�ๆ ™=g^Pฒศvatึ‚่พN5l Z๙T‡ึ�Uซี๔‚ˆกwM›6o%2zพ;{ฆ:่4์๒lwIž�&ำ๐C฿ญRl็ ข๛ ,๗๙ูAฤ�ๅษ#ณgzบŸ;aUิ/<�ƒ;P ๓c#ˆจU_>YถDRฆLiฌ+; A-ZDVฎZใnใ € Iํ:v็ฮฯ‚v5;sฦ๛’7ฏงBtฐ*ลZษnแ�นๆˆปw-อZถzt๗}CLบfŽส1ต1zo‘:U*ฟ.hu™;่ตd้2yฅo?VCB๕Z�๑วฟ@œ.ฐบพ�พ๛Œeฯ�/ศส•ซืpป&3?˜.y�Ÿi�—_~%ž๎โwฮZm�าฅห๒ษŠ•f=w€๑�๙๓Rตz-9qโ„cะฟ_ัฎuViQซ�ฝ?e’ณ=ข]*w๋�ำžt�?่9}๚/ฉYงžื1ํณfษb~Œดu๛v{–๓H1๖ƒˆั}่Eั๗เoฟ�ฮน>๖H™2ฅe๘;o›ษ`�!�๋๊c\๛๗{ลz>ื2‡�นk—ดm๏ฉpฏ3Zตl.�Ÿ�ฏb#ADรฤ@@c‚ˆa|๑h: € "†�Uฬ•+ทTญแ๙ขไ๒ฅKฒpม\9|่ 6jาL๎สม4๚ฤ‰ใ2mฒw%‘ฌYณIึlู“z์‰"’,Y2V�พ๕Sg�มƒฟš}:3hd๗ปœ#�_๚;3ฌ‘ี+>– ืฮืžou๚๓�,—ไfั†M›dูฒๅr๚ิiฉYณ†ำ5œฝ]lu_๎/สด+:ํvNป๛๋ฬ_’={vyฌpaฉhu๙—ส )Zย๏‹`ป=<"€ €@pm[6I๊ิฉไุฑใฒj๕jู๓ำ^3ž%KfiPฟฎ�›3งู๘฿�•&อ[ ร่ ๎{…5kืšPี™3gฬถ�ถ๏t‚PฑDŒส1u]ญง็ณ๋ณฯฌุ*๙i๏^I“*ต*\P7lh tฝื�$sๆฏ~ฆ๋„โADฝทา๛*{่�|ัฐš=Ÿ๏mUเปl/’ 7:ใ๓ๆฬ’์ูฒสบ๕ฬ�_}�”,^\ชWซ๊ฌWพRฏ*‚แvM�ก/=ฉ�?�,+ฌ็าพŸ๗KึฬYคL้R’/฿รฒ�“า๛ล—๓ž3๋Cษ“;—™>t๘ฐŒ3ึบ�KสW(๋„ถtaวงž–@ก@]๖๑G‹kกำ:่5 ๖cw•> #Nฑบ�r๗nณ�}๗�+eส”2�7�jUัซY�S=ั,ผ๖‡ b๐ b|ฟN์`ฉ>฿–~๔ฑ|g/�}Q ( u๊ิr*�k๘๕๙^r_Fษ๕ภ�’)Sfg^�บตคT‰f๚�้3d็ฎฯe?�๘ƒ๓๚�เ�ฉ๒๐ร™��ๆ/๘˜ณŽ=bw'�๛oฟKEซ:จ=่๛ล’E๓�7~�๕7ข๕๏ฮtทิฌ^อ้FZื'ˆhซ๑ˆ € €แ*@1\ฏํF@‰AฤะผMšตดบ‹ป�iœV=Lš4ฉื๔ŒiSๅ๘๑?y:Rฟa+ˆ˜อk^ ‰ฟ�*๓็ฮ ด(^็]/ˆุฆUKyถ[ฏ6นƒˆฺ5Y๓ฆMผ–›ˆญ ข๎ฦด)ๆ �`วฒ็Dด%xD@ jv๑z[อ๘`ฆผ5ไ ซนซ ๚ฎ๔ๆเทeๆฌูfvl#{L=ฐปปZ฿๖ูำ?�๒KภP–ฝ<”c#ˆ่พ_ผ�นบCpDิภSDร‚E‹ค�€ืผV วkาผYSyฮบgถ ใuBื&|ƒˆE‹‘แร†HŠ)ญnๆญ฿ฐQบZีุƒ �บ>#m[ทrkธฐxฉ2ฮด๏ˆV฿{w์ษ˜ั๓ร*฿ๅ๖tฐ็AฤˆtX† € €แ @1ฎmD@ฑAฤะฝธ5jื•œ9๏๕ jkฯŸ?'‹ฬทบš๛�ฏ๑๕4’lู๏๑›๏;ใื_‘s=_ผ๛.‹ฯ้ฯvl“›nJnuwI =�dภCo\ฟFnป๕VณL+–ซXลฉ^ค3_zแyฉWทŽืฏ็ฯ_ฐ*s,ณ*ไ\”อ›‰VKช฿ฐฑฉฆTธ`A™4qผูŸ]แล�ตœ��ฒป๋g฿.๛tc Iถฑพะบๅ–tf_๎?ฟ๘U6lุ$C†wฯf@") มช๒eห˜๊WZ�ูwะ n&L’…‹—๘.๒›n�ฆตTฎTQ2ZU–oฝ๕gyฟ�ํŸ๎�”tl฿ฮบw๘[ ?Qิฌำฉc้๔Tนt๙ฒzฌˆ™ืบU +๐ีU๔žคxษ2A+Gๆ˜บรjีชHหๆอๅ๛๏๓ป็ำch•ฤ!C‡y�๛˜†„ษŸฅ‹็ห=ึฝ้แ฿Kๅชžฎ~5}ะฏ›jึWฎ\‘ฒ*{๏Žญ›%eส”6๓›็้uชTกผdสœษoฝฟ�:#peU๔ย๕šhEผ็{๕ฐช…ๆ๐บ/ึ๓�ทฟŒoขำ5ณ}ฮzฟ๛ๆฏ:Fํ๙๚:˜๚�t3๖]{VภGฝถzํaั’ฅาท฿{2เcšิฉๅฅ{KEฺ๋�|๓อ^๋่ฏพ๙ๆ[๙่ใๅ2k๖ฏe:ัในnาฒEsฏ{{ฟ•ยpฦ€�}ฅถUั]ฯฟZฺปjืำช[งถ๔๋ใฉjฉ]ตk—ํ๖฿ฏ ๙พุปท๕ื๏:j›>�� >jดhwแพรฤ๗ฦ™*๒พ๓MO™๚พ 1า,š4แ])\จ๕�แ ๒Dัโ~ซ/_ถXฒXU@ตJcญ:๕�–Wฉ\Qš7k&Xmฟ๙ฆ›Œ๓ึญV…}k\�uฐผๆท13@@@0 ˆ&Šf"€ €‰U€ b่_ูlVwฟ9๏ป_ฮZ�๎๛iœ>}:๔ฯ-ิ/4๓ๆอ+2�%๛๖๎๗ซบ—อัŠ.yr็‘t้าศ‘?ŽสC๎รโ๒ธ์@A@?ใณ[๗B๏ฮ(iำZŸตฟI”Ÿตzžไz@2dธK’[มK Z๊=อน๓็o„หง็จ๗j˜หแNนx๑’ฐ~0ข]}_o็kข?ฒษš5‹œ<~Rด›c}>E4คOŸ^z๐AIk�ฯ๎�ป/R>ํ/ฒห๔บไฮmUญL’ฤ๚‘ี<็# ๋E๗uขMษ›๗Aน๋ฎปฬ{๔ั#Zฯน_C��C๚๚ถ฿_วฟ;ฦt ฎ็Rชlฏ ดฮc@@@ยI€ b8]-ฺŠ €$B‚ˆ‰๐ขrJ € € € `4xจƒ>4ึŸฌYฒศ’E๓Mั3ึ�Š–(m/โ@@K‚ˆayูh4 € x"&žkษ™ € € € €€ทภทI‰โลdใฦM๒ฉี๓ฑcวๅž{ฒK›ึญไŽ;า›•'M™*#FŽ๖�)@@@ ฬ"†ูฃน € €@b ˆ˜ุฎ(็ƒ € € €ถภ;o–๒ๅสฺ“~ฺt๕šu�ๆ3@@7‚ˆแvลh/ € ศ"&ฒ ส้ € € € €€#ะฐA=ฉWทฎ�฿ฝ’,Y23�฿�•ฃG�”5kืส ท†8๋2‚ € €„ณAฤpพzด@HมEไ@@@@เบ้ำง—�oปU๖ํ�๙บ๋ฒ € € nรํŠั^@@ ‘ DLd”ำA@@@@@@N€ โ wษ9a@@ ด"†ึ๕ 5 € € € € € € €@T"FUŒ๕@@bU€ bฌrฒ3@@@@@@@ �"ฦ;9D@p Dtk0Ž € € € € € €„ŸAฤ๐ปfด@HTีๅไd@@@@@@@เ ˆx^tN@%‚ˆกt5h  € € € € € € u‚ˆQ7c @@X ˆ‹˜์ @@@@@@H‚ˆ €ฮ!@@� ˆ๘Ÿc € € € € € € €@8 D วซF›@@D$@1]LN@@@@@@nH‚ˆ7ไe็ค@@ะ ˆ:ื‚– € € € € € € €ั ˆ5ถA@ˆ5‚ˆฑFษŽ@@@@@@@ ˆ˜ ์@@ภ ˆhK„�c๚๔wศฉS'ๅ๊ีซ‘jlชิฉ%Yาdr๖์™HญฯJ € € € € € € žร๓บัj@@ ัD �K™4iRฉUทพdฬpทคH™B’$Ib{ๅŸ+r�๘1๙`๚Tฏฦงป%+QJrไธWnพ๙fัํuะเโฅฟ/ษถญ[ไ‹ฯwymร € € € € € €„ฟAฤ๐ฟ†œ € ึC๓๒ฅM›Nšถh%ฉญช†ม†aC{-z๊้ฎ’*U*ฏyพฟ�๖›ฬ�pบ๏lฆ@@@@@@@ Œ"†๑ลฃ้ € €@b ˆšWฑำ3�$eส”ฆq—/_–รสoฟ–4iาH–lูไŽ;๎”แ๏ผๅี๘NO[�คJ)��๓๙ใw9z๔ˆ�}๑oษ‘3ง�)ณณ๎Žm[eหๆฮ4# € € € € € € �ร๛๚ัz@@ ์"†�%ฬ๛ะ#RกR%ำฐ๓็ฮษด)ๅโล‹^ ีn—ตหe๗PฏA#9zไูธaฝ{ถ/Uฆฌxด?w๎ฌผ7nŒ฿:ฬ@@@@@@@๐ ˆžืV#€ €‰F€ b่]สv;Kบt้LรฆLzON<+์ึฝ—h€๑ส•+2rุXู';A@@@@@@„ ˆ˜๐ื€ € €7ดAฤะป�ฯ๖x^’$I"งN’)ววZ โ?Vq8AฤXƒeG € € € € € €$ฐAฤพ@ธั"†ึ3เึ[o•6ํŸ2๚��oไะกƒ’๏‘’>}zน๚๏U9guี��w฿สŽm[ฃิ๐,YณJƒFMอ6ฑpŒRCX@@@@@@b]€ bฌ“ฒC@@จDŒŠV�ฏ›+wฉZฝฆ9ะ๏ฟ�&™2gxะcว�”้S'\hfป$�-ท˜EŸํฺ!ืฏ ด๓@@@@@@@ "†แEฃษ € €@b ˆZW๓ษb%ไ๑'Šx5๊ิษ“r๔ศI&dฮ’E’&Mj–๕ๅ็ฒv๕*ฏuM”.SN๒?Zะ,:sๆŒL?6ะj 6/M๊ิ’"eสH�๏‹ๅ�๙๓f}ญ•แฤ‰1ฺ.!ฺส1_a๛y€Oฤ>บ4บฏ“ฺ่Fwป„h+วTภ๏—]์นถOB<฿ใ๛5ญ็ฬ1ํ+๏�ำ็AB<8ฆ๗5ดงธฏฐ%?ฺ>บ4œ�ยฉญ7สk3œฎIเWs@@@ะ ˆฺื‡ึ!€ €‰^€ bh]โฅหHม‚…Fํู๓ฃ,[ฒศ™ฮ–=ปิkะุL_๙็ŠŒ>ฤYhไพ๛๊5kK’$Iไ๊ีซ๒�”‰rา 6†ส _Dญ[ฝยด/ฒm๚๓ุ1)[พ’๔๏ืG๊ิ๒TŒ์ถo~[ฮœ=#oผ:0ฒ›˜๕Vญ^#=z๕–ล ็Iฮ9ขดm๕šuๅแ|yใ�˜ญ[ทˆ–ฯŠ•ซโ�šฤไ˜แtMข๛ร"๖แž?ธOL_›แ๖\‚% € € €@่ D �kCห@@B€ bh]ๆ JฉาๅLฃฎ\น"ฃG 5Bw+[ท๋(ท�v›™5yยปr๚๔i๗bgŽRSNY็[ขTY์ซVญJ”ถ2tธœตชBjุ *ร๚ ฅ๋ณ�ๅใKVซ*eT†z ษCy๓ฦ๛1[ตh!ั๑Yฑreผ_“˜3œฎItŸฏฟ9ˆkไE—Pฏอpป&พŽฮ๛๏—Ažxึl�<‰ษ{ื$ธญ~n๒ฑOt?Oโ^&��/นฏ��‹้�7๏—]unL๏eย้�2�๎+‚_5– € € €ก+@1tฏ -C@n‚ˆกu™๏ษqฏิฉW฿4*X7สต๋ิ—๗�kึYตbyภpแํท฿.อZถ‘ไษ“›๕ถm�"[ทlญ“ฝึšง;?%ษ“%‹t�Nœ8)ำ?๘PŠ}R >Z า�้Šห?Y!็ฯ_บujEiปฏฟ�Nึฎ]' ิ“ป3fŒ๔ถWฏ�+“งLฝ๑}ฬ๒GหgฯO{%พฏILŽNื$&ฯฎIเ—]Bพ6ร้š๐~๘๙cฟG‡ำ๛%Ÿaฏฅฮีฯ๘˜|žD๗u“c๒๘zฦ๔^kุU็ฺŸ›|†6ฒ}ย้ตษgXเkiฦวไ�;๐ž™‹ € €„ถAฤะพ>ด@H๔C๋งM›Nฺ?ีู4๊”ี…๒”I๏๙5ฐJต๊’;ฯƒf�–อeวถญ^๋คI“VZทm/7�|ณ™ฟ๛ซ/eอช^๋0 € € € € € €‰G€ bโน–œ  € –C๏ฒu๋�หtง|๑ยE7f„_6n*™ณd5๓็อ™)pึI‘2…ดm๗”คH™าฬ�๓รฒฬ๊N˜@@@@@@ฏAฤฤ{m93@@ ,"†�ejฺผ•dธึ�๏�ู3ๅะม�‚†ฺฺ.ฯvทบ\พษ4|ฤะทๅ๊ีซf\็ตํะQRงNcฆ๙yฟ,œ?ืŒ๓@@@@@@ฏAฤฤ{m93@@ ,"†�eส•+ทTญQห4์๒ฅKฒpม\9|่ 6jาL๎สม,;qโธL›<ั9ึํ:สmท�fฆ/Y�}�ู.g™๗ศฟฒuหf๏YL!€ € € € € € €@ุ D �KGร@@ฤ!@14ฏc“f-%ใ�w;ำช‡I“&๕šž1mช?�ง3ฏ๋s=%YฒdฮtD#�+gฯž‰h–!€ € € € € € €@˜D “ E3@@ฤ*@1tฏlฺu%gฮ{ฝˆฺฺ๓็ฯษโ๓ๅ?~๗j|ืgญ b๒ศ฿7Fฮ;๋ต= € € € € € € žร๓บัj@@ ัD �K™-{vษy฿�r๖ฬู๗ำ9}๚t่7š"€ € € € € € €@ผ DŒ7j„ € H€ b ๆ!€ € € € € € €แ#@1|ฎ-E@ฅAฤDyY9)@@@@@@ธ"�@›SE@BQ€ b(^ฺ„ € € € € € €D^€ bไญX@@ "ฦ*ปD@@@@@@โQ€ b € €@ฌ DŒUNv†ภ��ตc$‡A Š‚พ�ฉธTRj 4|ฆฃ�3๔(| @€ @€ @€ผ. D|�… @€O!โSร� @€ @€ @€ศ"ๆํฬฤ @€ฃ„ˆGญำc @€ @€ @€h( DlธtO&@€์$ D�if!@€ @€ @€ @€ภ�Bฤ�อœ @€X( D\ˆ้ง @€ @€ @€ P D,›™อiรIDAT@w% @€ภ- Dผ-�G€ @€ @€ @€D!bโึฬL€8H@ˆxะ2=… @€ @€ @€–Bฤ–k๗h @€ภ>Bฤ}va @€ @€ @€ŒGิœ!@€X& D\F้‡ @€ @€ @€ P" D,aw) @€ภ% Dผ$�%@€ @€ @€ @€@ฆ€1soฆ&@€# Dแ ก“pcšxก์›|X`<่„ย49ง3nY=๐`�๒Cnœ‰›| ๔ฤฦกoจๅh"Wf�-๗?r๘ช๊;Š+ฅ ฃQพฉํคํ1ฤขฌ้ืRวš>TWฮะศท�9_UZŸ‘฿Zb‹ฑ�ุi์8v;„5vkยZฑรJ<ดŠชVั ท8U<ูG�?žฦงฒ’rื:ืnื๊ฑ|aก๒�8ำฅ3eโLQ>‹ ฿�BWย9‚ๅๆ๊ๆ €๒;ข~Mฝbชพ๓�]�1|Jก2๓‹Žg ภมG0�|ัYฟ„�c‡�๙ YZ‡+; ธฃŒ9ฐ07เ �@ใ@ H)`*ฌฒฎg˜fƒ ”`-จ›ภฐ์๛@#8Žƒ?ภyะฎ€[p๕tg ผ�‚:ย@Œ ฤqF�o$ Eข8$IC2 ข@f#‹2dR‰lFj‘_‘ƒศqไ,า�@๎!�ศKไŠก4ิ5CํะQจ7สF#ัt š‰ๆกEh1บ ญ@kะ]hz=^A;ัgh0-Œ‰Yb.˜7ฦมbฐT,“asฑRฌซม๊ฑf๘?_ย:ฑ์=Nฤ8 w+8Oฤ๙x>_ŠWโ;๐�$~ ฟ‡๗โŸ t‚)ม™เKเ&2 3%„rย6ยย)ธ›บoˆD"“hO๔‚ป1…˜EœE\J�@�C ๖‘H$c’3ษŸCโ‘๒I%ค๕ค]คฃค‹ค.า;ฒู‚์F#ง’%ไ…ไr๒N๒๒E๒cr?E—bK๑ฅฤP”™”ๅ”ญ”fสJฅŸชGตง๚SจYิิ j=๕๕6๕•–––•–ึ-ฑึ|ญ ญฝZgด๎iฝง้ำœhฺdš‚ถŒถvŒvƒ๖ŠNง�ัƒ่ฉ๔|๚2z-��.�6C{ค6W[ =OปJปA๛ข๖sŠŽญ[gชN‘Nนฮ~ :=บ];]Ž.Owฎn•๎A�kบ}z ฝัz1zนzK๕v๊ี{ขOาทำี่๋oั?ก�€1ฌŸฑˆฑ•qŠัe@4ฐ7เd”์6h3่5ิ7c˜dXhXexุฐ“‰1ํ˜\fs9s๓*๓ร0ณa์aยaK†ีป8์ญัpฃ #กQฉัฃ+FŒYฦกฦูฦ+๏˜เ&N&Lf˜l49eา3�`ธ฿p�๐าแ๛†฿4EMLใLg™n1m5ํ337 7“šญ7;aึcฮ42ฯ2_c~ฤผ�‚a`!ถXcqิโ)หลfๅฐ*X'Yฝ–ฆ–– หอ–m–�V๖V‰V ญ๖X�ฑฆZ{[gXฏฑnฑ๎ตฑฐo3�ฆฮๆฆ-ลึ�Vdปฮ๖ดํ[;{ปdปํํžุูsํ‹์๋์o;ะ๒j.;ฝณ78ถ;กNN"ง*ง ฮจณงณุyƒsวยŸ’5#ฎนะ\ุ..u.๗F2GF\8ฒqไ๓Q6ฃRGญuzิgWืืญฎทF๋7zแ่ๆั/�œ�๘nUn—�้๎a๎๓�›�_Œq#ณqฬu†วx=Z<>yzyส<๋=ปฝlผาผชฝฎyxวz/๕>ใC๐ ๖™็sศ็ฝฏงoพ๏>฿ฟ�\�ฒ�v๚=k?V8vุ๋�V�<�อ�ฌ€ด€Ÿ:-y5๗ƒฌƒA�‚ณูY์]์็มฎมฒเมo9พœ9œc!XHxHiH[จ~hbhe่�0ซฐฬฐบฐ�p๐Yแว"‘+#ฎqอธ|n-ทwœืธ9ใNFา"ใ#+#๏G9Eษขšวฃใว_=�vดmด$บ1ฤpcVว�‰ตอ‹�}qB์„ช โFวอŽ;ฯˆŸฟ3�MBpย๒„[‰‰Šฤ–$คษIตIo“C’W%wN5qฮฤ๓)&)โ”ฆTRjR๊ถิพIก“ึN๊š์1นd๒ี)๖S งœj25g๊แi:ำxำ๖งา’ำvฆ}ไล๐jx}้�๔๊๔^>‡ฟŽ�L$X#่๚ W g๘gฌสx’้Ÿน:ณ[(*๕ˆ9โJ๑‹ฌˆฌMYoณcฒทgไ$็์ษ%็ฆๅ”่Kฒ%'ง›O/œ�!u––H;๓|๓ึๆ๕ส"e�ไˆ|Šผ)฿ุ[Š๗  ช �อHšฑฟPฏPRุ:ำiๆ’™‹ยŠ~™…ฯโฯj™m9{ม์{sุs6ฯEๆฆฯm™g=ฏx^ื�๐๙;Pd/๘sก๋ยU _/J^ิ\lV<ฟ๘มแ?ิ•h—ศJฎ�่๗ใฆล๘b๑โถ%๎Kึ/๙\*(=WๆZV^๖q)้นŸF�T๑ำภฒŒemห=—o\A\!Yqueเสซ๔Vญzฐz�๊†5ฌ5ฅk^ฏถ๖l๙˜๒M๋จ๋๋:+ข*šึ�ฌ_ฑ�cฅจ๒JUpีžjำ๊%ีo76\�ดฑ~“ูฆฒM~�|}s๘ๆ†ปš๒-ฤ-[mMฺz๚๏_jท™l+�๖iปd{็Žธ'kฝjkwš๎\^‡ึ)๊บwM�ีพ;dwSฝK�ๆ=ฬ=e{ม^ล�งฟฆ�zu_ไพ–��๛๋ณ�ญ๚ใ@iา0ณกทQิุู”าิqp�ม–fฟๆฟ�}๛!หCU‡ /?B=R|dเhััพcาc=ว3?h™ึr๋ฤฤ—ON8ูv*๒ิ™?ย�8qš}๚่�3‡ฮ๚ž=xฮ๛\ใyฯ๓ ญญ�๔๘๓@›g[รฏ Mํ>ํอc;Ž\ ผx�Rศฅ?.s/Ÿฟ}ฅใjโี๋ื&_๋ผ.ธ�ไFฮ7 n๖฿š›pป๔Ž๎๒ปฆwk�ๅ๘ฏ=ž‡๏…�kฝ�ึ�ƒgๅ?v?ข?*l๑ธ๖‰�“C�a�ํO'=ํz&}ึ฿S๒—�_ีฯž�๖wะ฿ญฝ{ป^ศ^ ผ\๚ส๘ี๖ืc^ท๔ล๖�}“๛ฆ�m้;ใw;�{ฟ?�!๙รใ�I+>9~j�๙๙๖@๎ภ€”'ใฉŽlhF/ท@Og‡vจ“ิ๗<• ๊ปฉ �„ีwA•xฐ=€ฤ๙Dม3สFุl!ฆมง๒จžPw๗กฆy†ป›š‹o<„wฏฬ 5๐I60ะฟa`เำV์ Žๅฉ๏—J!ยปมฯŽJิึJ฿สฟ(ำ~a,™ใง pHYs%%IR$๐žiTXtXML:com.adobe.xmp 1376 424 ผ๒QiDOTิ(ิิห๑oดข@IDATx์xE†z๏ฝw์Š?VlุEQŠ R•* ฑŠฝ+vฑ ‚๔�{๏5เŸo’�ฬ๎�{soฒ฿yฒปณ3ณณ๏–oฯœ“แฌ2I…-YฑVทฎVน|*zaS         H?Vฎู SปzฅT *ุT๑cc          ุ ๐ข๒”H€H€H€H€H€H€H€H€H€า ฐ้ใ:p$@$@$@$@$@$@$@$@$@  ฐเEๅ)‘         ค`ำวuเ(H€H€H€H€H€H€H€H€H€.@`/ภ‹สS"        H(ภฆ๋ภQ         \€(ภ^€•งD$@$@$@$@$@$@$@$@$>P€Mืฃ         ธ P€ฝ/*O‰H€H€H€H€H€H€H€H€H } ›>ฎGA$@$@$@$@$@$@$@$@$pHwl�<น/@ฬ<%         ‹‘ภกรG๔iืฎ^)UงŸแฌฒิ๔ฐdลZ�œlj(ฒ-         @z"๎ุิ*ม้ .วB$@$@$@$@$@$@$@$@$pqฐOSซ{๚ๆ›ฺ\�—“gO$@$@$@$@$@$@$@$@$žP€MOWƒc!        ธ P€ฝ .'O†H€H€H€H€H€H€H€H€H = ›žฎวB$@$@$@$@$@$@$@$@$pA {A]Nž         @z"@6=] Ž…H€H€H€H€H€H€H€H€Hเ‚"@๖‚บœ<         ๔D€lzบ         ภE€์u9y2$@$@$@$@$@$@$@$@$@้‰ุ๔t58          Šุ ๊r๒dH€H€H€H€H€H€H€H€H€า ฐ้้jp,$@$@$@$@$@$@$@$@$@ ฐิๅไษ         ค'`ำำีเXH€H€H€H€H€H€H€H€H€.(`/จหษ“!        HO(ภฆงซมฑ         \P(ภ^P—“'C$@$@$@$@$@$@$@$@$žP€MOWƒc!        ธ P€ฝ .'O†H€H€H€H€H€H€H€H€H = ›žฎวB$@$@$@$@$@$@$@$@$pA {A]Nž         @z"@6=] Ž…H€H€H€H€H€H€H€H€Hเ‚"@๖‚บœ<         ๔D€lzบ         ภE€์u9y2$@$@$@$@$@$@$@$@$@้‰ุ๔t58          Šุ ๊r๒dH€H€H€H€H€H€H€H€H€า ฐ้้jp,$@$@$@$@$@$@$@$@$@ ฐิๅไษ         ค'`ำ๘jœ>|DŽฏX๐o๙*9ต}งฤ9ข�“๘�GฯVฆ”DWซ,ัีซHŽjU$บV5ษœ7ฃ7H€H€H€H€H€H€H€H€H€�;(ภฆมตŠ�ป_๖๓ƒ˜๙“[ผ,UGศQฅ’ไฝ๎*ษscษก„Y         ภ‡Xฏีแ?�–ฏO•ฃs๘ุkRWัตkH‘‡๎“‚MoM*ไ         @บ%@ึ‡Ksx๖ู�ส๋rlแRzKพ‹์ๅหJ้๎OI�ฦื$_™5H€H€H€H€H€H€H€H€H€ฮ ฐฉ@่ฐl์๛’�qV*zIyำ<ื\.†พ(™ ไOy'lI$@$@$@$@$@$@$@$@$f(ภฆ-ย l่9@โ๖9iฅฐป7ห”'ทTึOว‰Mq'lH$@$@$@$@$@$@$@$@$&(ภฆ๋–aceื[๏ฅ eฺ5)ฺฆ…”zฆฃdศ’9ํยžI€H€H€H€H€H€H€H€H€""@6\gbOศฺฮ=ๅ๐๏Eะ๊�UอYฟถT2N2ๆˆ:wๅ‘H€H€H€H€H€H€H€H€H€‚ sG��ฒ๊ฑNณjญsG:�สQฝŠT{{‚dส+Œร!      ธ l;'ฝ?�)QY3สK๗“�ั™"ย๐ำ๒ฃ๒ืฺษ™=ฃ฿}P€ ใ œ‰‰•ๅอ“ุ5๋รจ}�ซไฌ[SชM}U2dอz�ร       �็ฬ^{\^๚rท๗ŠKํRู“=‡ฆc6J�้ณrKํ�๒๔ํ๚Lุ$?/?ฆทน:ŸŒnQย�ฮJ‹W7ห๗KJ%^๎›P3œ&็ญN'—้c?pi^yตuI{]��.ำfิ�8œKZฺน>ž็Œ}Ÿ๏>(ภ&wNŸ–Um;ห‘ฟ�MฎfบฺŸฟษ Rq๔เt5&ๆฟA �ะ9{๊”=ุฬ๙๓I†ฬ‘}ดงณ•ณqq๐ฐ=ชŒูณั[�ฆม �:ผใNl�,งvํ‘ŒูฒIถฒฅ$k‘ยพŸ฿ฅพ#e‡$@$@$. ผ๑�y๎ƒzloถ-%M๋็Ivœ–€vMๅh๙ผK9ป>X‘s-ˆž๋ใู;+ึ�ใฏSัeบiJ6™Kฑฉ�0ู3ใำdjฅฯ�ฅบu”b?r�‡๐ 1k7HฬšurbำVษ’/ฏไจRQ�หVZ} J๋ฯ>็ภksk\)ข>„้hธไ{›+$@$๐_#ฐ๏‹oeร๓�=‡V,฿ฅžธYH$@$@?ุิยก9A ฐ‘3Kห`ƒะล4์%ท=(๐�LEืฎ!ล{X๒฿�8ขn Zn5A�8+ขv๎ส™•ทi๏>’Lyrปwฅ�ถ๒ž\๙่ำrtฮ�ฐ‘ฅ`~ฉ๕ๅ{‚?i็—ุ๓หŸGฟxœ>zL'wœ{Hz|ธCว'จ๊Sb่ธGJJใj9-�ว{zฺ6๙jแ9v2ฉ}แ�™eZปาา \G[k,Ÿyoป|คŽ}R ฟ–A�ฝ๛’<2^7s ใl๙ฺfuM;ฎ ขP>xY^ชปน๒`์p�฿W—{ฦmิ๗๚๘ณO%ฉชฤpุ–�qาU%9›ต๊˜�ถ~เj~y>Aน*�ล๙4 ฐ๔-\*+šท๕ุ^ฆิร๋ี/;/�_y]vผ>UไLาƒI�5>~[ขkV‹คIŠ๊๙kฎฌR�ฏnƒธZ่๎�%{้wเ๚mถgbณท�$Ft7็๖9$@๖ยๆก.j`/๊ห๏หษ๏๛๔kูะห๙;ณส”ฑ’็jJ& lยeื$@$@$Ž๘)ภN�๋ tžพ]Ÿ�ฬ๎ๅๅา๒I‚ิฮUš�&bฌึ�่-ษVบd๒•SQใศ฿�สช6Oฅจ‡ฺ฿~ ูห—MQ�pอoะXN;nW‡(]�Ÿํm๗สฮ)ำd๋ˆWลu�\เ1๋e'6l’ƒ*9ฺ๑ฅ+ไ๘ชต‚Šˆ—ญB>ไฌ[K �rฝHฆL^MmwM๛ภ�‡„hลDwวซoสก?�–ธฝ๛%“ฃ*W”R]ฺ้ฅีเฬ๑ู๙ๆปr๐็฿ไ”ส4IMํŒชXNโก`ำ[ญjA—gใโd�ท?สฑEKี๘Wสษํ;u2ถ่jU$gRเฮ&‚คd~2a๘๎g9ฆ8ลฌ^ซฯ ‰฿ฒ—--9U\โขญšฉP�qW‚ ฐ'7o•ํ“�’ใหWK�กCj์%บje)xฯm’๋’บษ�ฯ๓‡๕ัชฑฌ’ุ๕›$Cฦ ’ญdq‰ชT^{Z#๖ฒ—…+€ฮUฮ&}อœ;ท”์ฺมั-ผำwO�PŽฬ/'ทlW��๕�“ตxQษQฅขผ•d)œ๔าั8ฤฦถัฏJ�‘คฏ›๙oพ�3™ฤ—˜ต๋ํž๒\qฉไป้๖ถต‚{p,‹ฎQM �wงตi/�๙�๘„๛ๆฤ๚j๚r}ธg๒ซ~ณ•I๚ฅj7R+AŸญ#Ge๛ฤ7ไ่ผE lขขคโ่AŽ็ �่๛๕ว_ณ€0N%%„ท<ฦ™๋’:๚ ๛'ๆภิ๚™'e๋๐๑๊R&�‚ฯ1““![69๐�/ฒ[ฝ๕ฒ—))9ชVRำท ๚2ป?tXฬ�IŽ-Yฎว}j๗^ษZคไจVY?g๙›�จฆฦ฿> �'w๎ึ็ฝ๋คคp่๏’จส๔aฒชg๏…”ž๛�S?ุ›ๅไถ ฤiษRP%Tฯ �Y˜mเeป฿�Hbืmฐwม“๐ผ์เฟสแฟ็ฺปขkV—B๗�aoปWR๚�ฆE?~ฝRสู<'p�ฏ๎ฃ*$ล)u_dฬšEฒ-,ูJ•ิ๏j๗์�ซ{f|ข๎้3‚Y'‡gฯ1ปำ‰-ญ�nดq๚ymร}—Zใเ’H€H€HเฟIภ` จ)๗๙ฃ“ˆ8ฉฐk*Gห็]สู'nŠˆฆ์ผฑr๓๐„ฟi๒Eg’…ซ8<"!บ�>jƒM€ฮ�์ธ๖I�ฯw้ใดQโDBำ05ฝ� ซตx‡�ื ฏf๎บ>D ฟŸฬ;,J๏“wž(เzๅภตฒZลช…อ๋_Yสสชื๑รKDDน)ˆ†+ภ"�k๙n+lORS`EŸฐA*Lย่๏๗๊ušaๆ๑J*u‘bkŠพˆ—ZA๕nฎˆ๕z๒*…•W็6ท_eG[„&จ�cฅ๖’EลƒชŽรX0&ุๅrศืฯ”wด…งsต็Wฺ็„k‚ksณ๛kํqนsL’๘๚y็rrตบทL+�iนูหฬ" T1wษVๅฝ ๏hxว�ื0ฏ๔mZฤฑ�\nP€uั^�Xง€?f\U63fฯ&ี฿{]rTw^่€Š>�้7Y๛ิs๗มฅ� �ท‹คมฟตฏq$`S็๛ƒvqZ 4[GNp์/ัฑm hฅ�บ[†ŽทXแhจ6 vUUำ/! บmืิ๗eหKฃํbˆu๛J5บร!�ิŠ5•ัโ[๎“31 _ๅฬ:X‡เRmฺค *b๘ฎR๗Vผ–‚๎ฃJฏผœ๊ฉฃ๘#{3ฮำH์ใ>&โ–้๕Œง็%ภ"†เฺN=��ุ�๎ธEสฟิ7h�^ฟฮืa๕]$F‰๏ก,๗ ฅยฐ~๗Q8ขม้ใวe๑๗JผSM+๖D+)๕ฬ“vฤ-$สƒส๒6พV*๔ร€W�—฿จD๎$ฑคซพใ|Nะ๎฿ZW D`ห ฎี๙้3kำ^.พแn%ยํฐทs]v‰T{gขฝc๋q%$5๕นd็vvทy=[5ฟ˜.Knน฿1>ดซlU}sผํ†aฎœRโ๊ขฦMต๋��l4B |yš:ื2=ปJ‘G๔�ย�฿� z๔8?ณโYใ>ฬ๋fฑ,ธโๆ๏ซ2žำ fY›a-Oํ�#๋บ๔าbvจ™r็’Jc^’�W^๊จถ่บ;ไิฎ=vY��]-•_io›+ซ๏"‡ี‡+หp๊�๐‰ตi/S๛�Z๙ี๏ฃิrฦ9ป@ึฉx๓q{�ณlง{™ฝ\�ผZs๐มcษญม๏Mณ}ฮ๚ต๕�OPๆ็ต ็]jŽƒ๋$@$@$@�Mฆ้„+ภvU๑Eง�™๐ทื๘–%คล‰น!ขีํณZม-^�ญNŽ…ฉๅ�ฦึ๐ŒGฺ๖ญ๒ู�รบ�สกUqOSk๏�y@ลFM๘kšŠกzk$ว ทˆhหDร`1๕" ๑fงท/cug/!R๗�hงŠ {Zjซฤcะ๛ฬใMUcผอฃีธำดํ๒ฎ๒H…-R"*<]a๐žU๕ใonีEร›—GฏM๐.ตฎ v˜ยฌู็OXX/ๅ]lืdืJ ๊฿-ฯW/๑ํKwUz‰"๒’มUฅx�ิ__๔๋ทQ€5ˆฦํ; ฏŽ��ยSม{n7zJ๛ีอƒG*ฯญ#>ะ%s~x๋ฆ•-ผ๖๖€?&-3ฅว„Gํา�›9Dไ๚*ำทปy่~G5/‘ุย›6˜eศšUj}๙žฌh๑x€ ็nฯรJใ”ะๆ2\'\ฏp-Xศ†pฺcœว, งชฎSบWW)๚H3G}ท[ธ๙=ฒ็�ฯ”7จzซ‡0ˆUu�ๆื๙ร;su;ีaู<6ฆzฟ}-ฃ’~Q$'@ฬ\zgs9ฑq‹ู•๖๊+7ธ]ถใีทิ/๗I๖vr+น †kะเตj>\2๏kS/แyทฌ้รŽ2l4\�ปภปำ6u�ๆVฟยq�ส๔๎&EZ> ซ[ผLVถ์เ๘pbท๕XAˆ•ส�฿4๗ณแโxงบอ`ื>�ผ�q–ปŠ๗ถ๚ŸV•ืวD�ยK€ลป*’3|Xƒ€ๅ6|ร‡ฐpอ�nH+ +ัถย2ลืา๔ฐ๔Sคร�xn�์ว๗‘œแมฟ๒‘Ž็2ิ5หœ/ฏท3ๅสฉ=ฮ)ภ†ขล}$@$@$@~0Xฤ๚,ฌ�%g‹ทœะUย`๏ฝQf+/GX(Q^ฌ›๗ลxjZโ<(‘ิษห>ŸHf.I๘?๒'สสu*”@$๏ษ�ี,ค#qr@…:8p,^w๖ซฤ˜ฌo+ู;๊&้,ฆˆ๘j๋’๖กLA4ินฺ ิสซ?๏“>Ÿ์าE๏ซถ7ช แšyผUรชJก\ืo์{eภ็ �ชณzU”Z%�~Fฒซ฿V%\—ืŒ๐ๆฑ๗—>๏ิEmีด�a&๐ทฎ‰—Gชู�k�b‡ฐ๋๖œิษป บกผฉฏชไ๔|ตฺ฿;n“#๙#yถ,ค๋ป๕ต๛ฐVpŽZผ� เูฦพK��>"ob/ึ:VrK/โ�_}/๋Ÿ}มณiจ็ฌข๒6อ)สย`#Œ‰ฝ�น~ฒ�ห™ฮฑฉ็aZN"vอบฆ๎Y ~ ฐ~=ท~๕ใื๛ศฮ^+๑๛ ณ7ฮฤฤศ‰Mส“ภ๕Žม‡|\ฤข%M๎w^็ [Sํ�„w Ÿื6นwiแฐ˜H€H€Hเ?Fภ`รŸj hแ ฐu”g+’Xล—mŸ่!๊Yม(„h‹ข๐ภ ei)ภ>5u›ฬHL†๐ ฅ x‡๔Ÿ)ภ|_๛uฟ๔R�ณ0S€ตฎ‹Wฟ^eชFุ๋ฌๆ5q฿^ํ�eึ�c–รปyษเ*A=—‘,์Nๅ)kฦ ถฺ#๎-’“�งโิžoฃk\/๑ลุํนZ๋ซ:๎ค็ฮ4.<๒Jสฅ†Eb_!ยฆ•!�ชGŸฺฝ�ณbyษญฆ@็SSณs5ฌ—ฤ%H O/?๕ฦ-๛ยณj๚|S=ๅ ฆ๗ŸPฑMsO�&ม;ญlŸ๎’9O.ูซ2JoคผUƒˆy๐vฮฆโำฟXMษ�1MวFˆ3ถ&โ๕"nฏiฅบ?%ลฺถด‹๖|๐™l๊7ฬ๑วvฮบ5ฅ๚๛oุu’[ˆ;_Mkv‹ฌษJ=๛ด€ฉ๒๐ฤ�๛ัŽ๎๒\sนNgz ฐJ+ฅโŸPSฉแy@M��ิX€˜SบG)ฺบนี•ŽW์ว๙#&๊Žื�ถ๛ล ฦQe๒�Cย้ๅ!๋i๋ฮ๚ส…C‰๋ž้#ˆอišพ3”ศ‰฿๒‰ๆทธ๒kjZ}ฃคi๕ฑ*~๊า�C@A˜† ร๛[�„\โZอซ{ญฃŽ)เaว๒๛Z๋DvŽJjฃเ]ทJ๙ก/ฺลˆoผml‚ƒBxาี‡ˆฉ !=ถ ฃืญx*ผ�_๐‘Y<ำๆ‡์ƒ7ฝๅi์ูทย�ฅ…gพ• ใฺอฟ์†€>+Oa‹ิ�6ฝ8D๖~๒•54ฝิa:8eGืF0b.ฎG๕-�่qู9๙�‘ฦี\,๚�f_๓/ป1 Iมปo“2}บฉ๘ฟั๚��ฌ>ไ!ด‚i่/Q๑ฐ๑D์X๐<ฑu{ภ;ผ�$wโ‡*xogฮŸฯ์&ไ:๎3$bษึ�ไGผ็5ํŸ‘Cณf;๚w5ฎ ฬO‘ฮฏ็ึฏ~�zง–3žƒ%*คi๐H‡gบegOž”…๊ใ๙$KแBR๏๗ฏu�ืxฟ์��มวำG�2ฬxI‹k๊]j›K   �>s)ภ"ัี–ัีƒBKN€ลŸl๙ใˆํDํ@‚ฏ.อชŠ�๗๊/๛m๏Nซ2„ภู2จต™ไฤฉ3v�ำด`;O฿.ˆŸ sวšตฦl้—‹๘ฟษB0Œyจ„๖X-œ(Šรc๕หฎๅ’kุ๊๏%ภขผi็๖ซโbย๊เ•tซ�gปdนŠ_k�)ฎwU��ฅเG๘ ๋x‘.)ภ&ร”อ๙—�ฟPฑ๑"๊(•W4{L%u �‹OrIฑR1ป้š'ปห!•(+,Sยg•x๊qษ^ฎt@/QqR๓�ะศYW ฆ‹ฎฟ+ LAํ๏>ึ�_จ์%นEZิ๓ุ�^bจ‡dAห๎NRQVไa๕Gดb`^^J^!ภบ „2ำงา๔เ5๗นืฝผ!�ะ[m–�ึL%ฎฺhm ผ๖.Iบ^^,ฤ`ˆ‘ฆ!๖#b@š! ฬฯ๓wว:…ˆU๖wPำ๋ฃDฉnuฒ5์& ๑ฮืงขŠmO๐8–i๎>๔ญแโ?$Cf็/%$k;๒๗<ปiฮ:5#๒>_|ำฝ*ฑื6ป}ก๛›JนI^ฑsk\้๙กภiะxeซ'ๅ่œ๙v?ˆGZqิ ฝ($ฉ)'_พkืตV๐Žมปฦดฒ/>'…›฿ซ‹ผž-pซฃž?ฏ„zป�zOถ kvงc(๋2ŽR‘e๗ถ’•lอ2ˆI๎p ึ>ฏฅงซฎอ๛ฬบ.ฑk7>ะY–9_AŒtำˆoำ€แf‘\บjŽc�ฺ๐๓ฺบ฿ƒ๎฿#ึ1น$  ๘o8,b|�ฝ.aVh0/MPl๐โูธ๗”๖ฑ<`Q^ฒ๓rฬฉR‘l๒ฯ‹•Pไ‹ADDข)ุใื–Wๅ“%’ย�}ณ๘ˆ<๒ฺฝ?-XำC๕]�๕–ฺIณ"๕มC�H�T%พ๚sอqอ{๏+5MŸคGLุUFลdEb/ฤuE\ูHฬ`!๚��ป’Nะiุํ*ฬข%g_��#ˆำ๛ั�C๖uD่ „ 8_F6‘<ผ๔เ‰U}๋AฒŸ๓i๐d‚GS$V๓ณi:iT$m"ญปuฤ+ZศŒค—XเNFAยค—ม{Šiๅ‡ฝจณŠฃฬK$‚wX•%ฺ4=MU%ๆ2อ=ๅฺฺ็N:Vเvๅa<"มรxŸ๒ฆ�ะk UU{Q^บLyž)๑วm๐๖๛ทฆิ s{UปVผฺิ1จ)๋๐บs�จ7ว•Q ฐ},กั-.xล�ด๚œ฿ ฑรใ4gฝZRฃส�:ฤ[\pๅ-ึ!๕าบ;ิผ|อศส^ธู=บš—hPฆG็"&ยI˜๑cญใx ๔๒!ผGU*oUK๕r๓Kฃt{ซ#ยตg&ฤ}>พlฅ๖€ต๖! >Xึ`�ฏ๖ตw_#ฤ)†—๋i�b~ร๋ญ&zYm๊ซAร„„„ฝž-xฉnแ๔๒ณๆŽ�Uกœิ๚ๆ}kทc้%๔_บ�/ฯ็ศั0qรK€…g8žiทA่…เkš๙ ˆ�ช>ณืŸ=ำำK5^…PXp๕ญ/่�77–Šc‡ุ�C`๗S€u ๊xฆ‘Lฌะ�wูฯท}๐ +~‰t~=ท~๕ใื๛ุRห๙ไๆญฒ๘f็ณwN๙Aฝ$ฯตฮ฿A.“]LึFม   4 p.XS$DผT/๏ิ‡โฅVฏง xบšlC%ฬnPยlฆŒ"FV—œส“6ต†Xณˆ9 C,าฟ^v7๑Sai)ภ">.โไยnจ‘K>่XFฏปŒœนWŽœ8-ข�fฒ &n›ฏ‚เ๙vศ”฿่~qUรต+ฌตร,PE{ฏบ�ฮ฿+_.<ฌ‹oT@J&&�ฒX�ธvŽ—๚}Wหษxฅช*toQ้p}Aฝฮ=GโฅZ„{'W๖ŒฒiTp/๋p๚KM ฐ‰๔0�tซ๒ ืt,B57ขฯแvaฝy๕ฏ ˜ช ๗๘PuSณ๏ไ๖ฒ๋ํj*๎ฬฐ“ยoืZJชฉ๎–นลภPยฺฬญz™ีT/1ำโa^"Qรex.z‰กี฿›ฌฆบืั�˜? B ฐฬ`ทผ4:`J3ผฆƒูก_�t์๐ว๐ว<�จท,”hjี ถt3‡ˆ1อห��ดณ!jร�:ฤงmgวแS๚ม-ภ::M�ภณ]็‡OUŒ�ค ๊f=dP_vฯ#f‘ฝŽน๊ี–าฬQfnธลhaU�งซx‰D^S5=ุิ|๕Gฑ�B ฐ^๑�ํCm›bnจzุ็๖ศส฿ไฉ8zprอ<๗ปุPBฐ[ˆ0Xฟฮ็ำe๋๐๑Žฑšq9;’ูG€…7)�Pๆ๖เ V7kัยRดU๓„ธธ๘ŸB„ๆ3€๐Hาณ์ฎ‡%fีZ�[Žช•๔x็ึผสI`]w2/3”†ื๓ษ๐Lotฏพผž-ซ๗sj•‡ปtวร ีฮK€ญ2eฌไน๚rฯf๎8ฆ๋7f@@�f๎g้๐NถฬoV{V�rฟร๋ึ:–cฉูผ*๖3โCร๛ุ4ฟXฟž[ฟ๚q_ ๓œรY7฿ว~pFlใฝ%{hฒ›6Qก$žฒcนš(ภš4ธN$@$@$เ7s!ภbฬ‡ฎ“ล[N่แ็ษ‘Q†�_\๊–‰’ {Nษะฏwหฒm ๛Pม-ภ"้S…n S�ฑำฬŸฟฝฐ๒จฬ*)๏ัษฟ๎x[ย*ษ*s”Ž™! ,ถพ&ฟ๎๓๛ฅGดธh‰‡่+-X๔$\Hฦร๙woRXsuวม8๙bมa๙่฿Cvฬำo”ุyy…บnjXt` ฿ลT ีQ*ฦk�าQฒt๋ }�w�NpFƒฯ๚ีUl�…ขw•็Wส~%TรเE�ปi•@,ซ�ด�จผ๓ว;ฑYอ’ูๅท^u=�๐`Q>�ว}าOลw…eหœA ๕ˆ๋z"๎ฌ”์ฒ�>�*มฺรWๅW^ท วš๐ำ>๙W‰�ฐ�ณฉํJ๋๕๓๑ร/�3รYeฉ9ฟ’า1 –ง9…7น~‚yP%ื.-๖๏~๗#Aา—p žœ๐่<Ÿ†x|›‡Œ–รฟซฉฤ.ณ๕บC๒ช]ำ>H^์Rฝเƒ<ญฤVม;v๎qวx†`V์ั‡ฤ[K<๙˜”่๔„#V*7ี�๋;ูุgฐ์�๘KปSˆมฅ{vั�/ZปF๘+z€ s ๗ูฒzw฿ฏVyธKSMฎŸฌ{�ๅ€มฬ-ิ#$@รฅณํ๊~ ฐ่‰ W?�Uโ๖$L‡ฒๆตข�๗†ธยfโ@ฟXฟž[ฟ๚๑๋}daL-g๔ณ�›dCฯษญc˜Kผ;ชซ9ชT2‹…ฌ7H€H€H€|&pฎุuปOษ๕J„…gค—!Aฆภฟ๔h€‹๚ณV“f6 ผEƒYT– 2ซW%-ยซc–{%แ2๗฿\+—สาZ€ล1ฒU‹žXf]o.$}”ะiYjXL��฿u‚i�ก์อถฅคi�<Ž*๐LฝkฬŸืฑรุภu? ฒส•ไ‘L€Eณฏnถ™#d’’!1š)ฮ�;V!ฯํWู๖ดu์ฏค6๙UR.xธ!K๘ผK�็ ’u•xชญฃฬ�pO๋4ฝ–ย‰�`ืv๊!H๒vระ…LˆEjŽ9ุz๎+ช)จสซ1 s{โๆVำWซพ้๔ ฃ]ล/ึฏ๓฿�ีwฒ�ูรฏ;๋+wiคฎ‹~ฝ’โธw๚ุq$gฟŠ?ปfœ �‹ษบฏ�}„ฺvว›อฃผKtxT…&xยnV๋ซ:๖์๖ Sูะ/Qโ่๒ีษะฌสp,O๎}Ÿ}ฃฤŸึ.ฝ„@ฎe+QLŠ<๒ ฎ๎ณe๕ํ�P‚wRพ๋Yป“]"ฆฏWา>ฏ†~ ฐ๎็ฬ�ภใu์ๅ๗ท‘ใKWุปLฏaฆ…k !,vM�PŽฮ/q๛b7Y๛K%ยึUฟฌdina)ชLํhbmธฝJณ•.ฉยw|ขw๛๕�๚ี_๏#๋�ญeJ9[ํE%ฤ์›=}!วT๘�� fY ๆ—zฮt์N›าk‹ธ฿ฅLยๅธ,�    †ภ�สSฑ�Œ๚|เ9ยไฬะฎฏ‘S>์Xึฎ�แ�Cาแํ/Nฏi๔‡cฮศ6)oี�›�žีŠg—๗:”‘Wีดvฤ+…ทๅ•สm 1}‰๒ฮ4�ัว*yำŠ <&#ฑษณ๖หๅuซผ,-ƒืY wิอ#—๕Oศร1MฑGชexฮพ๒HRH3ฎjฐ˜ฌV^K$”z�รVฆ!tร๐fลDะpއ8ฏจ›�ท’T-–อ์Z‹ฺ•๗ํ— Ž�๐†๖`1!มใึัPm`œ-_�,�ฌ?n'ยB\“;๋ๅ‘—ี˜ ชฑ›Œ๊@`G26+)ืƒ—ๅ•‰ญ๘~:๏ฐผจฎผ‚Mร�า�๒|า๏๎ข’/ฺy,ณ�นXง›Hู์)9๘๐.ƒ—Yzฐ๘ƒ‡‚Fธfzฎ…�&œzว/“=3�๘F� ™3K9$บQำ]ƒšz3jมฯจ€๘„ีฆฟฆK�Iฎ๒6พV*OnิNZีIoฎj’T ึ,oZ†+๙%ภn�บ@ณ ,ฆฮง…น=%‘ะฅ�๏_ง่P~ ฐ~?’†-ฝร) F2�„เ ฐฏธ4On�.๛ฟ��ฌชง๛ึ๛ํk;™•cg xv๘๎'uฏ} x.MK‰@แรธด๏บMวVF฿fŸ'6จ�l�š ˆb_๙—๚ส†พ/ูa ��—๐๘‡็ฟiฯ ขEjแ>[Vฟna2ืฅ๕ ภาย�`W4o+ว.ต‡‰๋Q�Ÿํm๗ส�Kop„[1฿mจ›–ฌ9ฤ๎=๒ื\ู=ใcfN€ืvฉnIanึ +b๖‰u๗‡KS€๕๋น๕ซฟ�Gnๆv$œอvๆ:~T๑ภwฝ�žฤฎ�h๎า๋ˆ9l~|H›าk‹ธ฿ฅๆป(`ะ,    @<]ถ=ADญฅฆงCฌ‹ิึ์:ฉฝ6ปดŒš๖$อEุ�nู'[๖Ÿ’*Jœ4ฝ5ร๎ภ็Š„W(Fงฯœีต5๕฿็รt‘{�๎“’_ ™ๅ g“์สซ8\C\�ญNI uMสช๐)นฎแ๋H์ม๕?ฉbSเฺ[ษฝยi›ึu(ภ&vว�K|จ๘†ษตM‹�้a�^uV2 `็ทgŸ,ผึRภ๔\t�]rj๛ฮคๆ๊)ฝไ฿Ÿ=cแนง[ฃQ•ืวH•tฎHไ— ๏Wx]™,™๊œ>~\y?ลฺี!”‡;eฑSะด`ํ!’o๊�ฒYUฌฤL(๔K€๕๋�ฝฎโVึ๚&)™‘u2จปเส›ขWมฆท 2ูร‚‰hทจqำ€i�ฉ�bŽorฦv86ฟAcงญe:>๒ถ„/”นTโชj๏Lดv‰ฃŒbื' 89๋ี’๊3’>ภ[ใฆk�Rด0หฌ๕ณ'OJ�แฃึฆdŒส.™rๅิ�แ>[Vใ ฯ๗Wษ๙พต6โ๐%JศDŒT/‹?tXMำN๚’™ฅ€๚๘๊รŽั‰Ÿฌ็;Fy‡zeฎ?4kถฌi�Œ1Q๐wKY|”J4/6’๐ V?‘,แฉฝ๔ฮ‡Mฐ ๏jุา;[(o๎„`๛ุF Rทึ๕?$�ม๋๊[bฎ)ภ๚๕�๚ี_๏#0 ว’ใN;&ฝ%�ฦLrTญ0r ธํ&ป,ึฏk‹ƒ{—ฺใ     €ƒุD�ึบZMN๚฿Aษc#%BŠG7พม๋I˜"ฑดO=&๓^๏„LๅvวญC%:K”€„&ฆUzๅeษwC#]ดeุXู๕ึ{ๆnมป๊[ดhcํะ™ฒWฑ-นZิ™๛ณŠP/\‘ศ๋~s๊ถuL,�S’อH46žษjŠฉe˜‚\Gy0น…&wฒ$ิ/�๏yมT๋p์ศ?๓dU๋ŽŽช๐ะฎ๕๙tม1-ร˜\u‹cชผ{Zด_ฌŸ็ฟ๔ถf1็czํY็ท๙ฅQฒ[yŸšfzห† ดฆฒ�›ื �”๎ั%!‰Vbงnฏฦ์ๅสHํoี1]•Wึ๕”ฤฎ]๓ไณr่oฯ้2ฝžฑร`xซ๋$‡g+Gำ๑c{ุฑวํมˆsจญ„ํ์ๅห:๊ ฤผk,3ง/‡๛lYm�๑ทŠSš‹ึ* ๆ�พQy๑๎UำณMซ๗๛7Ž๛ฺ�็^๗S€=๚๏BYูฒฝใ™๓ๅ•šŸO“ฌE �ๅH:ธ์ฎ‡$�ะป +๎0งv๏‘E๎pิq‹๊Ž!6๖ผ�ฉl๊7ฬQฃ๒ฤ’ท๑5Ž2�ž๛ทฎzฟ๏%3ฉไบ.ฝ”๗ฯŽ6๎ะ/ธภม ฏ€ฆ‹mฟž[?๚๑๋}ไg๓่-ƒ๗(ย@˜๏j์;:wฌ|คƒUM/ย�#`�ผถก�ฅŽsƒH€H€H€H€H@ ›x#,PSืแัฎี๛ใ[ษRจ@ธีำดž—ภ๊€™ ไ—๚ณqไBีd฿โ๎–“‰�yf;Lฝ- ผฌฒ, gใใๅ่ย%*vๆ็ษG๔4iLำO๔nƒ—��หo ˆ‹‡?T 4นQ{เ_ฑJ T˜‡ำ๋nq*\‘ศ/ƒpO{E<สJvj'ัตชษ‰M[โฉž�nŠว๊๒๓Q"s4 หVดx\ะ4�a_ ษ ’ฝl)=๕๘่"5}ฺ^PทศรH™>�์f~ ฐ่ะฏ๓๗š.�ฃkVำฮq๛๖หก฿� ๐`… ุpษ6วไD//n๔Q๓ำฉ’ฃZeRV?ั5 y๎opฬ}yC‰Q๗ใUแ8>ี๕ญ)ฝ์ำ๊ำ-D๎๙เ3ู๔ขwRจบฟ|!Y‹ตš๊ๅqsr๙:สpพE[5“฿ืIฅ๑ฮ้้V_eึซ˜ฌ๎i็ึ~๗RO‘sผํฅŽ�แ>[๎พjึร๛เอYMวฤ�`ql|tX�๎™€Dk^ใBˆฤข†ทถ—้๗e‹'ผv%ฤ_@€={B–�๖`ภฝโูน*ฬR0ฟิ๚๚A21ำ|๛ฃฌ{ฆYฐOไ\๕๋hZkง—๋วs‹��๊ว๗‘œ‘\lู=-ร�X‰Xๆ?1฿ดHXด๓ฺ๋†๓.5วษu    ธุ P€Mผึw! zจ›ฑ9ฃ3=˜WฆPใ*x—JJ44!)QจzฉูŸmc_“�๏~œฌhš�ๆฦRฆw7O๏0s ๐<[�น‡[ฒยณOx)–R�š…›฿k6ณื„j๕‡ฌŽษiืH\Q"๏�W:Jตื]ชŽ2l ฦeY(ถ˜�บSeถ>s<ฦช๎Xๆน๊2ษš๊๎ุมโ3n่9@O7๖๔ฐRBV1%t—์�ฮžšovฏฯ�บฝb‡Z๕�a ~ื๘๐Mkทc้ื๙Cด[฿c€ฤํU�=ผ}1Uบ�พ‚ฑธm๋ศ ฒ๓๕ฉv1” ช]J๖A „ทฒฑว*Q๋ิฮ�Jh-$QJฬ‰ชT^ขีTbˆ ‘�p=ฆ๚=ฃ!ษWr"GควHซ๚šษ๒•rrหvํแฅ!ๆe$๑^รฃ[ผL‹ฤˆY N^ำ รํฯzพฟ_qOลฎ^งใ GU,/QสJ†lู�fุ}@ˆ9กฎ%b"้Rๆ<นี8สIถR%$CๆLa๗ฒข:ืณงฯ8ช๘ึทฃWตกฤ๗˜u$v�ฦฎ๊YER.„1HkC�ฏ๑๛j๏L7›š"Ÿ�ณกฮœณ๏ทฌลŠ่๘ฮ™ขSศK]kx_czฆ\9C6ู}xOžPก—๗ Xf/_.ภใ5TGหฑฅ+ไ๔แ#’ณNอTLภG_ž[Ÿ๚๑ใ}”jฮ๊™;ฉ๎›ถHœŠEŸ!cF�ม�a3ญฬ๗k›Veฟ$@$@$@$@$p ›xSืฑฺดI’ซaฝ๓z3_Vถz2ข1T�เ �‡tDX™H€H€H€H€H€H€H€H€H b`‘>ฆ�4LtŠ(ฆโ"ฑฮ๙ดu]{ห™ฮD<กฦฏช*ฆ`šyฯ…:8๗‘        ภEF€ฌqมWถl/G�]h”$ฟZ{ๆG’ฝ\้ไ+ฆAุ5๋e้]‹œqNMuจ�—5ช๏LU…๛H€H€H€H€H€H€H€H€H€|"@ึ้•MุุํXEผฮ่บ5%ณŠ7YyJBftG…sฐฑขูcrlัฒˆŽTR%ฉ*�ฎuDmX™H€H€H€H€H€H€H€H€H e(ภ�โ๖๎—…ื�j”xฏFืฎ.qป๗ส)๕V๖…gฅp‹๛ผ+งQ้ฮ7ฆหึแใ#๎ฝ�Ÿ3ur›ˆฒ         @ฤ(ภบญ~ฌ“ž=วUšฐ‰ฌๆ™ขฃ$fี:ว� Y2K๕w'KtํŽ๒ดฺ8๔๋ŸฒฆCทˆป/p�MRaไภˆ�ฑ         @สP€uqร”~Lํ7-sž\’ฃR92o‘Y์Xฯ”3Zชฯ˜"Q•ส;ส��8:‘ฌzด“œ=y2โฎซฟ�†ไTah$@$@$@$@$@$@$@$@$@็†XฮซZu”#sๆ‰dสคหุ•kๅtLŒGMgQฦจ์Ri�0ษs๕ๅฮ>m๙gžฌ~ขซœ=u*โแ[ใร7#nว$@$@$@$@$@$@$@$@$@)'@ึƒผ`7๕*งวศษญ�=j„.*�\')๚่Cก+Eธ ย6—"ฯWชๆำ%G•J•ีI€H€H€H€H€H€H€H€H€RC€lz๋Ÿ๋'๛ฟœdo๒ล๙nh$ๅ๕–ฬy๓$_9Dุตdc฿มQ8ฅVคๅRฆwไ1cSz<ถ#        H @6ศp๚่1Yr๋ทwษgศšUŠ4ปGŠถj&YKKพQ#v�Fู6๎59๘รฏFiไซY ๆ—ฺ฿ฌ’‡EG�˜-H€H€H€H€H€H€H€H€H€RE€l|G�šซ^=ขF๘ป�*ฯ5WHถโล$kฑ"’ฅPษZคฐdศ˜Qโ”๘ƒ‡uธƒ#sศัy žฏ~XๅืFI�FW๙ั๛         ˆุd€m๑Š์œ2-™Z้swษฮํฅx‡6้sp         \(ภ&w‘ฯž•5บษกYณ“ซ™ฎ๖็ปพ‘Tš๐rบC$@$@$@$@$@$@$@$@ ฐa\๑3'NสЇž˜ๅซยจ}�ซDUฎ 5>xS2Fe?�ƒแH€H€H€H€H€H€H€H€Hเ"&@6ฬ‹๐ฌzฌ“ฤฌXf‹๓S-ื%uฅ๒ค‘’)Wฮ๓3•H€H€H€H€H€H€H€H€Hภ&@ึF‘�สู“'em็ž้6A�ฦืJฅ1ƒ%CึฌษŸ k         ค9 ฐ)@ผeุXู๕ึ{)h™vMŠถj.ฅ{vIปฐg         ˆ P€YBƒร�-๋Ÿ}AโIa�4หZคฐ”๙Eษ}Y:d/$@$@$@$@$@$@$@$@$@พ › ”๑๛ศ๚�ๅ๐�คข—”7-๒ะ�Rช[Gษ˜#*ๅœƒ–qqq’1cFษ”)“/G;|ไˆ|=๓'ูบ}‡ฤลลห•J|พ�บซS�w\|ผผ:ๅูนkดj๑€TUIฬ,๛โ›๏uyฑข…ฅ้m7[ลชlทL~kบdษ’U:ด}D๒ๅอc๏ใJd6m�*฿�4K7zเž;$พผ‘uภฺ็„ภโฅหๅ๏น $C† า๎ั‡วœ๒ฮ{Z๊ืญ%—ช8ิ็สฮ๕ฝณg๏>๙๔ห™๚๔๎ผ๕F)^ฌ่น:ี็๋™?สถปฤ�Kq‡lH$@$@$@$@$@$1 ฐ# lp่—฿e๋่W%vํ†ภiP’ทัUR�ษG%gšiะป?]ฎZณ^^{sš์S"uผ8aYณf‘๒eKK—ŽKž�นSt 9๓สุ‰Sไ์ูณv๛สหK���ํํHW>๙โ๙๘๓otณ<นsษคฑร์.ฺuzNŽ=&ัั9dส+#์๒>†ษ๚›๕vƒ๚uค�ำํ์}\‰Œภ็_'|๒ฅnิฃ�SRงf๕ศ:Hฌ A|ํ๚z๋พปn—หิKQ?lไM`ฤธI2แฝ๓ฝ7'h!ึชูผอ“zตvอjาณ�ำVqš/�บwย่อ•‰ฏฟญซทmี"U~ย=fj๋ต๏�ผ>r4เ–ฺ~ูžH€H€H€H€H€H |`รg•lอ฿�,;^Ÿ*1หW%[7%๒7นAŠทo-9ชTJI๓sึ„Š`:ˆฐ)๑”k�พซœTษะ`่งHแ‚rลฅ ž“)ตPl0๑‚lJiถKญˆฏฤ~/”ƒ‡�ร[นู}MํmฎคžXั๏5 ฐฉฟ—ุ      \l(ภฆม?ฑa“์๛๊{ู�๕๗rr๋๖T!Zy”ๅป�Z)p๛อ’ญT‰T๕u.�จผ฿œ๖พ}จ๊U+K๕ช•ดึ_sๆษ๑ใ1zยL58"OX„h฿น‡nŸ;WN™8zˆ/a ‚เต7ฆษ๎={ๅก๏u„ &ภ"ม”wfจYT‚–‡ ‡+š@jุ๏~�Uฆฮ๘ุแN)ภ๚sQ€ฅ๋�]ลI€H€H€H€H€Hเโ @6ฏ๓ฉํ;ๅธ๒ˆ=พbตZฎ”ธฝ๛%^Mi?}๘ˆœ>v�q๔ฌ*ฮhtj*ด@ ษQฝŠ1I �%kีฎณœ:ง‡�ซ{'ฉUฃช=|„ xฆg?ูต{ฏ.kt๕า�ฑ–๖�ไVƒr่จ บฺ�ฎฝRžhใŒC™\๛”์&ภฆค/ถ๑&ข๙เ—วส๊ต๋ํN‡ื๒‚ฅkc๑m…,X฿n&vD$@$@$@$@$@ ฐูOหำ�เ <ีญท>D5&แ…]‡ค9=๛ ัๅ%K“แƒ๚ิ V0oแb9๎5ฝ๛ก๏‘�oน!XU]Ž๘ณ›ถl•lYณI…๒e$GTไษส�`*ั}ล๊ตRฎL))\จ`ศq›;ืฌ� ีจVู,N๕๚Q%�ใZœT เNž:e๋k๒ุ#อU|้Kๅ๎$\‡ิL†oิป ๖ฤ ปž%๐ป๛Ž&v™นzิ๘ษฒh้2ว๓€๗BM5๓แน.OฆSr{‡aLx๖๐!ร:ผ“๎น3a�ฑฑ'ไ5•ุnฎJ|h�#hWZ…ร้๘xkฝฤ6H€H€H€H€H€H 4 ฐก๙pฏฯL‘ฌ|น22๘…็“=ย่W&ห�๙‹‚ึป๖ชห•ไ#z?B TA(k๓๐ƒrำ๕์*flYณ/T&^|๑อ๗๒�ว_่>z<ำัเM๘\฿Aบ~+Vญี๋^?nพแ:i�ะŽ]๋6lRโ๋(ํอุ้‘ธ=xัย�6ใญ‰‰{’_ธใ๓zต@ศสฆ=�๖i-f/VT Œผ ๛Gพ” >[๛แษูตG?-๔Xe๎%สe+ื๕่๖”๖ŽuืqoC4�rๆ๒ะw�ปฬ{+%ฐธo† ��P+๐Œ?rฐไสmC ~ฎฯ ‘สฎ VเY:y�หq๛๙พƒต7p๖์ูtฟศT๏eS฿˜82ภ+๓รOฟ’ฯพš้ีฤ.+Uฒธผ<ฐฝ•…K–)Orœง๗uDx์๓,VmKฉ‹็ฯK(ป๓ถ›ค๙}w9ชคีฝcค�‘;”�v๓๕๒pณ{ํ*ฆ[ฃZฐฬ๐สผ?Qยw+Oeงm๖{‚ผ�‹9ฅ๗gฐwft๏5ภ_o๘฿5ัAถS๗>ม7˜Ah: wŠผผƒ๕ษr     ธP P€ฝPฏl:=ฏ�†ษ†›๕่�Bhฐ!C E�XLอถDฯฦฎ–kฏบL7)^ดˆไR�”Hศ๔ฮ{้2•w(ค~�šสหpปš:<วŽ แ`๚”O]T%ภถSžฑ! ŠLye„๎?ย`Qžซq.kX_bbbu;Luถ๖ฝ1aคDEeื�๘๑ด= Œภ ฬ�ืํ*)XEJS๕๗๎Kุง+จแ ฐn‘�.mPW ฝณ�๘[ๆ/\b ˆ�zu“*•*X‡K€ต .ฉ[[ ุ9rdW^ง�ศOฟ�aํ’gžn' ๋ืฑท‘ ยฏe76พVํฏ+1ฑฑ๒รฯฟ้i฿ึ>,ร`อ6ึzjXx๘ต้๐Œœํมˆะฟฯžฃ>,ดฝ˜�Bs�Ž�ๅxLBr9ˆ๎ื]s•)\Pต๛G{*[�ฯnม�`ญ๑/VD{E-RX า~๚ฅ๖<ฦ�ซ.o(O)๏[ห,`kษ๎๐Q็๑๋๏ณต0h ฌท(กฟUขะ๏>Oญธว ศ's”งใ'_|c ณ๐เฦ๕ฒ,%ฌ{œ๐>ฟ)ฑฯ™๊y…งบeใ†tLรOห{็หo}nZฎฟ๎jํํŠ๐ฬž+7oฑ๗๕yฎ‹X!@L๐.นฃษMRฏNMu๏œRแ4fฺ]๐์O™0ย๚^ฮ+ณ<ภ+ฉkฐzํ๕๎๚ะ๖Lwq_ทH๎O/ึ-พโ:ใz[๖๖ปส๗?อา›8>h\uEC�ผ~�๙7ฺs;+–/+๛&ฬะ•๙ƒH€H€H€H€H€Hภ“XO,,L ฆ@š#G”@|Œฤ’‹๛๚�๏ษ�EKัHป>๕„Žกi๖๘ดˆS ƒW ผaกX/๑mย`๖}V‰ๅะฤ6k๊9 0�โ ์Ÿ่iฺXวิ์W”ง%DXำz๕๊‡ย`ฒ`ฺ๛Ÿ่ฎ ศ�u๛-fท2a๒�ถๆ๖�3X/Oล._~๓ƒ๎๏๊+.•ŽOดึ๋�>ีอ๔�ย.*A0ว}aู๙`อq v+๎3ฎ-<;t้a{วN;T๒ไฮ-๐ฤ}6ัใq.มRzขญ๛†w`7xพ&~lp‹ฏhƒ�ˆ๛ ›๚๚8GฬWpร9Q�๙๒ๅ•aส –F$@$@$@$@$@$šุะ|ธื'‹Uยฆก#“ผNแ5๏ฉH,96นพ0]ำถaํ}Xว{ลzZ ฐ^ำฟqผ_~๛S ร๎mzซ�ง<a/žจง‡c�ถ-ƒ็ผd- W€ต๊[š ิ๊ีฎ)ฯuM-SแงOะ…ืื +ั๗•ื�า๕ซVฎ bตv h‹‚ึํปฺbะ๙`Ÿ์ฺSว๋ลxLแ �–มCืมžฐแX๋v]๔”n„-˜<~ธ�ฤ`!b!ฎฆ�๊Y9v�ธŠญ›YฆNg๏n�&แ๚ธERป‚Z๙่ณฏ!-6B ฬ:Oฤ:yฌgฌัA*ฎ5ต~�ˆA:๑ฺฆD€ตฦ OโัC๛ฃ›{ฌc7ํž5ky็ตฑzZ�;g‚ฐ&0S๔ี‰?เq:๎ี7ดงvน2ฅฅู}M๕S€E�Z„q[0Ol๔๗๗�„Xึˆ[ ฯvทม๋�ง0ผ๐~€Yื ๋‘�Ÿฆ‹ �z๕ทฝนแ5™n3?…;Sม�ทI€H€H€H€H€H€’P€Mbมต4"ฐI%‚'Ÿ;๔ก๏‘�oน!โฃE"ภB\งโค"�ัฃGๅฐ๚ทv�FYน:!&๋ใญ[ฆแราJ€uOทNx�†าw`‚gNK7ฝฮB ซฆชžu<ฏ%ผ+w๏ูซฝุŽ(6ณ`…จSซบ–žฒ›Yฌ� ำฎ Vz์)}}อ้๙๏~๘™|ญโดยž|ผต\sๅฅz��cไ๘ืd�‚ลบ๘| ฐ-UbธxuฯไษK&ๆbุ�HยถYy?ย;1]ม๖็Y๊พsFGห๋ฏx ฐมฎ#ฤฒ;w๋ฉ๎Vุ ำK๕’zตฅ{ง๖aฯ:Oทอ๎ฝำณDBkš|็'�สๅ*|,R”ธงa๘ั๘ฺซ๔บ๛>ŒXฑF-iy๏˜�ก๎K๗8ฑm ฐfย*ณ๎ฆอ[ฅgฟ!บศŒซฺS%]รปๆ๖Xึ…๊’zY๑rถค‹โณฎ[J๎OK€…ภ แ=XH } ฤ๎๘ย๐ุE๘ˆซี3\ฒx1ณ*ืI€H€H€H€H€H€ย @6 Hฌ’rค ย@�‚yM—ท๗pXxŸฝง„?Kะ ึ๗น`อุ›ๆ8ฬD]ฆkลu{;šmฑnฦัต+wฏmˆฎใ'ฝฉ…Wx๘ณ`ฌ)ฎบ�Z"ญYว๔่>ธoPแฦLาt>XLฉฦ๘a^ก�็๊�F‚ฑสป1Šญiํ๎:ุ&ภบc›m-/YณฆฦcŠ<ฬ+$„ู�\7ฯำ,ตŽP& ต‘ ฐฆ'hจc˜๛,๏ฮดผwยํ�—ตn ฐm[ตะฑcญ}ึ๑ชป๖xQoš์O?2๙–ี�Z–Ua)†จฐๆuKษ�i ฐVฟึฒS‡วt�[k�ฝ8lL@ŒfิA|ํFW_ฎEไ,Yฒธ›q›H€H€H€H€H€HภƒX(,๒‡Dะฮฯ๕ต=ฎเIบ”Zrฌ)ไYว€วW%ภ๛+>�ด_1\65Iธ"`�ซฃ‡•œ)ถY็a.อ๘Ÿแ ฐซืฎ—~/ฦ�ˆ(ู•Gค๗\ ฐ|๒ฅJ^๔>ล๓!ภย3ผ0wœV]โฒลท{๚9;“ผU"ุfUlแี๓K€ErฏWงLี}บใ๕๊ย ?L!U�๑…ฝšมห๓ึ›๋]‘ ฐฆPŒ{:ฑก *่วJผOษฝ3b์$+'eฦ‚๖:w™_l8์kTซขฝ›Ssb�มXผ‡๊2”bูN~kบNh%uณ˜เšv|ขMHืชห%      \์(ภ^์w@?ฆนvzถํ๑…DS๎E‘:9ถลฃux๔ ฑ�ถU*Uฐ๓๋๏i1แ ฐ–xCฆผ’@ํรIยฉ�gภ0Yฟq3บืวย1ฝ์Q•@ศJิฎ�ๅ๙ต็+๚รt๐ป๏h"—5จงง$ฃฬy�`฿�เSA’%˜W&ฝC�@'’๙Xฎk o2d7&Œt„่kษฒ•2ddB‚-ฟXSฌ23ษ[cท–m:tตฝคฯ—๛Tท�ถp0หฅหWษŸฯีรพ๋๖›u†zST๋�นฝ\RทถuZ๖า๚0เ—‹ŽญไV๐ฒ}{าO1๏ป•J4ƒงโmึใ้ ผฌแ‘‹๛`ส„’#*สgr+‘ ฐ่ฯgค‚oZ�;ๆ{‰‘ะห�VษฐbcOH‰โEๅฮ[oาUฬqE‚`ฬฤ)2็฿บ$EkXฟŽืa=หRzข3K€ต>"แc ๚;x่ฐ>Vคa พคํS�uโ4t๐สศม‚w.H€H€H€H€H€H 8 ฐมูpO <ืw ฮ),X–๑”tm '๎D^ฆ๋•จๆภมCฺ#ืšF›XŒฑใ3ฝl4O>�J%ฎบฬ�FF๛รFหฉSqvYค,NVžนrๅด๛ภสำ�๛ุ‚น_,ฤ+5|`บ x™ๆqพุ}._~๛ƒโุŽP1k!RZ+ํ:=oว2?b,_LึหหwยไทmัึOึ<๎ฏ•G[6ณ†ช—‹_1Nฏ#แึ�“F๋๕7ฆฮฐ“ญีชQMzuOˆ}k5†ธ๖ย แvฒจ‘/ฝ C`Jุฎ=๚ษฎ�{t๗=า\ี4�๓ฝTยชใ1ฑ*DCyuฬPฝ;-๏$่{์ษgl/ฮž�ž–ฺ5ซ™รˆฏ฿�4K—™๏ฐิฐหWฎ–A/ี}โ^˜4vจว39Ž๛Ž:.ผLขฑwญd…)ฝ?ัน[€EฤืNฯ๖ต๏็๋ฏปZ (รp<ฎโีโCZพผy๕ณ€pฆ™ ลฦ (… 0wsH€H€H€H€H€HภE€ฌ 7SG`ภะัฒr๕Z� ฤ…&* €Rฒ<;อจส!2ธ�ธ๗ฌฌ C ฐhcybฝ^ํšr๓ืIฑ"…e๖?�สง_ฮดล์W€=—1`1.s:>ถ!๒A�€`b Yญ$Zแ ฐf‚"… Iำ�n–บตk่$;ำ��Dวžล๑`~ ฐ่๋๕ท฿“_” รธ‘t กŽวฤ(๋7{*ดฎ ~œ/<Uขœ•!}๗6ฝM{นฮ™ท@�R๗•ุ ืขฬ_,†ัํๅ1ต็Ÿ1<ว*„ร1ร๚�Sฎแฉ‰i�Hฦๅeˆ‘‰i�‡๕U€ลฑ>��k๙ไ‹oฝk—แบŽฺฯแอ ึใ'ฝi{&�•|<ค<–!ะZ–m฿š��๐๓oV7žK�#ฟเH –ึ๗ฮภac๔ฯ%^wอ•า๎ั„๐ (Jญ‹gฌง๒๘Qฟก อ๐l6-%๗'ฺ{‡a฿g_อฤฤ…Aไ~Y%ๅ*Yผ˜,^บ\†Žš หC�่า๑q�A%T๎#     PšรŠgลฺี+ฅ G%�จI“)7ฟ’๒ฐej ์ยDboN4X{3Niหๆ๗ูููอ๚}๖•J๕ƒCDCœฬฦ*1R#•lโ ข ฤุัฃวไ‰N q MoA์ณbfๆส-“•Gše฿�๐‹L›๑ฑ�4ง0›ž‰ศqบmวฮ]าญื]ฌ„ž?�šฃB9lืขh๙reTถ๑ฺCญฏš"พ.QHW€ลม�]ฐX&ฟ9]Ž?n �วฆ_่ัU'ขBˆx#YeV ’%Šฉฌ้}ญbวฒๅใดวฅWผFŽM{๗Yแะก-›฿ซฎ”ŒR๛aฝบw’Z5ช๊๕H˜๑q‘d์{๎ˆด ํๅ:XM฿บ}‡ํelu/ำŽOด–�๙๒ZEz‰๋9zย๋ฒm๛NG9ผ—มข.๖น๏ก^�†ชญ[tŒึ้S^qดต6,Iฤq๕ชฯIxMCเ5 ืตqฃซค๕CLsG=/o'f3�VฏZI=-ํะึ>3†ฉ;‰”๋ี}๏Xmแู‰p ๐|6 B/โทm�Bฒ(q�mi}๏ฬ�๑๙เใ/๔์ูณI‹๛๏A!^Uฑ\aๆ;ฤ7ุv~๎]tำ๕คอรšป!†ซ{b๙ส5"xั"…คตช_งfuGk^ุ‘�Ÿ–7ซ๛�ณ๚ฤ}`%ๅ2ฝด1“^ศ–GดUหา%Kศใm )bึแ:      @ฟtO ฐILน– &์ฮ]{ค|ูาถทb:–/Cฐ๒ภc BXค†p›ถl•<นsk>‘ถOM}ˆ•ป๗์ำำฎ!rฅgณ๎กขส‹ย2x‡2xรฎYฟAฒfษ"U*U;ดFจ>ร�a{อบ :iฆŒC� ื&`�ƒRคPA}žแ† ทณฤว5J4Fc$ท*ฌŽฎฅๅฝƒะ๐*?sๆดห…ํ•๎ุƒี�ปoฟŽท‹ธีH†•-kึ`Uส#ฝ?:ณ��›ทlำษ� *OeŒำป6ฬฎXH€H€H€H€H€.Z`/ฺKฯOo จ๔๘ฒฆ{egG".ซNž<นeRbาข๔v.        @ ฐผH ฐฆ๒cH €8๕๋ิ’˜ุX•ฬjถ|5๓G;ผยํMn”‡ธ;žC! ๘?{g'ต๑ล๑WœBก๐ว ดธK‘โ.ฅxqww?��9ไpท"ล��Šป)Eฺ-ฅ�๙อ2นูlvoฯoแ=>\’™I2๙F6๙อ›7L€ 0&ภ˜`L€ 0&`&ภฌ™/3P$€ธฏ“gฬ๓ณˆม8bP/?หq&ภ˜`L€ 0&ภ˜`L€ 0ะ%ภl่๒็ฝ3|๎ขe๔๋ฃ'yˆYก\IชPถคC'0&ภ˜`L€ 0&ภ˜`L€ „=,ภ†ฝsย5b’บs๏พ ฃ“งHž„>•้0&ภ˜`L€ 0&ภ˜`L€ x`=่dqU™`L€ 0&ภ˜`L€ 0&ภ˜๐,,ภzึ๙โฺ2&ภ˜`L€ 0&ภ˜`L€ 0&เAX€๕ “ลUeL€ 0&ภ˜`L€ 0&ภ˜`Lภณฐ๋Y็‹kห˜`L€ 0&ภ˜`L€ 0&ภ˜€`ึƒNW• 0&ภ˜`L€ 0&ภ˜`L€ 0ฯ"ภฌg/ฎ-`L€ 0&ภ˜`L€ 0&ภ˜`D€X:Y\U&ภ˜`L€ 0&ภ˜`L€ 0&ภ<‹ ฐžuพธถL€ 0&ภ˜`L€ 0&ภ˜`L€ x`=่dqU™`L€ 0&ภ˜`L€ 0&ภ˜๐,,ภzึ๙โฺ2&ภ˜`L€ 0&ภ˜`L€ 0&เAX€๕ “ลUeL€ 0&ภ˜`L€ 0&ภ˜`Lภณฐ๋Y็‹kห˜`L€ 0&ภ˜`L€ 0&ภ˜€`ึƒNW• 0&ภ˜`L€ 0&ภ˜`L€ 0ฯ"ภฌg/ฎ-`L€ 0&ภ˜`L€ 0&ภ˜`D€X:Y\U&ภ˜`L€ 0&ภ˜`L€ 0&ภ<‹ ฐžuพธถL€ 0&ภ˜`L€ 0&ภ˜`L€ x`=่dqU™`L€ 0&ภ˜`L€ 0&ภ˜๐,,ภzึ๙โฺ2&ภ˜`L€ 0&ภ˜`L€ 0&เAX€๕ “ลUeL€ 0&ภ˜`L€ 0&ภ˜`Lภณฐ๋Y็‹kห˜`L€ 0&ภ˜`L€ 0&ภ˜€`ึƒNW• 0&ภ˜`L€ 0&ภ˜`L€ 0ฯ"ภฌg/ฎ-`L€ 0&ภ˜`L€ 0&ภ˜`D€X:Y\U&ภ˜`L€ 0&ภ˜`L€ 0&ภ<‹ ฐžuพธถL€ 0&ภ˜`L€ 0&ภ˜`L€ x`=่dqU™`L€ 0&ภ˜`L€ 0&ภ˜๐,,ภzึ๙โฺ2&ภ˜`L€ 0&ภ˜`L€ 0&เAX€๕ “ลUeL€ 0&ภ˜`L€ 0&ภ˜`Lภณฐ๋Y็‹kห˜`L€ 0&ภ˜`L€ 0&ภ˜€`ึƒNW• 0&ภ˜`L€ 0&ภ˜`L€ 0ฯ"ภฌg/ฎ-`L€ 0&ภ˜`L€ 0&ภ˜`D€X:Y\U&ภ˜`L€ 0&ภ˜`L€ 0&ภ<‹ ฐžuพธถL€ 0&ภ˜`L€ 0&ภ˜`L€ x0'ภ~3†แใช2&ภ˜`L€ 0&ภ˜`L€ 0&ภœx�โฅฬฬœ>•๓Bnไ|๖Ÿ07ส9-ข”``"โ &ภ˜`L€ 0&ภ˜`L€ 0&ภ<Œ@˜`ำฅN๎aนบL€ 0&ภ˜`L€ 0&ภ˜`L€ 0kฏ�aฦ–X๋ลฉL€ 0&ภ˜`L€ 0&ภ˜`L€ x`=๏œq™`L€ 0&ภ˜`L€ 0&ภ˜๐,ภzศ‰โj2&ภ˜`L€ 0&ภ˜`L€ 0&เyX€๕ผsฦ5fL€ 0&ภ˜`L€ 0&ภ˜`LภCฐ๋!'Šซษ˜`L€ 0&ภ˜`L€ 0&ภ˜€็`ึ๓ฮื˜ 0&ภ˜`L€ 0&ภ˜`L€ 0!ภฌ‡œ(ฎ&`L€ 0&ภ˜`L€ 0&ภ˜`žG€Xฯ;g\c&ภ˜`L€ 0&ภ˜`L€ 0&ภ<„ ฐrขธšL€ 0&ภ˜`L€ 0&ภ˜`L€ x`=๏œq™`L€ 0&ภ˜`L€ 0&ภ˜๐,ภzศ‰โj2&ภ˜`L€ 0&ภ˜`L€ 0&เyX€๕ผsฦ5fL€ 0&ภ˜`L€ 0&ภ˜`LภCฐ๋!'Šซษ˜`L€ 0&ภ˜`L€ 0&ภ˜€็`ึ๓ฮื˜ 0&ภ˜`L€ 0&ภ˜`L€ 0!ภฌ‡œ(ฎ&`L€ 0&ภ˜`L€ 0&ภ˜`žG€Xฯ;g\c&ภ˜`L€ 0&ภ˜`L€ 0&ภ<„ ฐrขธšL€ 0&ภ˜`L€ 0&ภ˜`L€ x`=๏œq™`L€ 0&ภ˜`L€ 0&ภ˜๐,ภzศ‰โj2&ภ˜`L€ 0&ภ˜`L€ 0&เyX€๕ผsๆq5.}๖‰�โO(ุ��G๏�#z��}(์wษ˜`L€ 0&ภ˜`L€ 0&๐)`๖S>๛ม|์ะ[mโk่ฏๆรƒ๛ฏaล„ 0&ภ˜`L€ 0&ภ˜`L€ „`C๓งน“แรั›7ohึฌYไํํM7n�ษ“'งN:Qร† )J”(๔๎_๖„ •ม;eL€ 0&ภ˜`L€ 0x๕๊๚iลZบ}๗>�๙็_�^ŸW{ขE๛œ’~˜ชW*K1b|๖*ศ5 r,ภ9R� „a�ฟG%J” ห—/‡ (้าฅฃอ›7SยD‰D8vƒ '…+ม˜`L€ 0&ภ˜`N �๕๚57•^ผ|้ด gx.˜1bPื-(ฺ็Q=๗ ธๆn`ึ-L\ศฟเ�š;wn:v์˜W ึ๒๙๒ๅฃฝ{๗ฒlฐRๆ3&ภ˜`L€ 0&ภ˜@PXดl5;y&(6ล�ฃrd๛–jWซFkวี *,ภI�ށ9ณgQ‹-์ายสย์ูณฉvบaฅ:\&ภ˜`L€ 0&ภ˜`–๚ Mฏ�๘ำ2?_DFƒzw๙8†ย)`ขแŒภ(X ?9r$@›ศ!)R„ฒdษBI“&ฅ˜1cาgbDฏ/^ะ;w่ฬ™3ดgฯ:u๊T€ถŸ+W.ฺปo€ึๅ•˜`L€ 0&ภ˜`L€ „�„ิฎx?กHภ{xฟP�;๏:$ฐ”?ม}ฤ๓?z้5ัฃGงฆM›ส�iำฆu‹ุอ›7iๆฬ™4u๊T๚�๗฿�Z…bˆ+Ož�ๆvy.ศ˜`L€ 0&ภ˜`L 4ฐิC~Ÿ,ภ†<๓�# ฐ!M�ู_ไH�:Rxถ6n�˜L๑โลsksก็ฯŸำภiโฤ‰๔๏ฟ�šณ-—฿��e:'z?�๚‹ ภg�าlL€ 0&ภ˜`L€ 0• ฐ๋™ต?.`ํy|ŒK,ภ~Œg5 “;lœ8qhม‚๔ร?I8@5jิ ๛๗๏๛น=`�Dไฏ��๗ฝz๕‡๐.�ย_๋ค๐กรGฉYหึRl�ๆ›ฏiรš•>|๘€l*Dึ™8i =๙ํฉ�Wฅ ๅ)หท฿†ศ~ƒ{'gฮžฅซึศ�|FŸQ๗ฎ)jิ{ไN�#FคHโpถ%rไ ฟž็-XHWฏ]—Uฮ›;•.U28ช๏๏m๊ืV๎�กฝ9Cn็น93ึ{‚ฑอ*•*PๆL™Œež๑,kึฎงc'NศJงK›†jืฌแYภฺ>�๕อž�“|n4mX‡b}ำุาœKฤ€ �R–ฬ o(;q๚,ญ\ณ‘R&OJ ๋~œ0ช๗ฆ-;้�ƒ๔ฯ?๏(wŽ์TคP>…ไ“ยฉเ�๛๗๒๚๙d!„๑?๛ห:r�” •ึค~ญ0^�ภU๏๕๋7โ=/Jเ6bฑ๖?๏�Q8แ–฿ๅ-ชโI,ภ†8๒Pู! ฐก‚=Dwสlˆโ�tvๆ—›A~ฯ๘ตŽงไฟ๏<3็.ขs็/ฤW|sมขF‰"œ 2R“ต]^หฎŽ๓ยฅซขกiƒlt๙๋ฏืฒhq_ฤ‹‡š6จE)’%sต๚'™วฌใiฯŸ'•+YŒย…๛Œถ์ุK�wp,J) ฟŠO)’~#๗�ๆํ฿t์ค๕sฬ\=`mD๎=๛‡๚ญzDQ"…ฃA•โS์hพฮVฃ6>ฅฟ฿�GำFฃฉ?7# ๓ห,ภ†๙Sไ™t%ภ&Nœ˜๖๏฿/>ดmฅ >ย'OžPม‚้๒ๅหN7l๚ฬูœn฿Uฦ็ŸGฅใ‡C็b๎�tแโ%YฝT)SPำฦ\Uี2ขT—๎=iห–m–๙zb7แYฟNm=)ะ๓#G#‡2]ดAฺ�}h�ฦ2;\ธ๐4|ศ@U4ฤงซืฌฃž}lมิ๑uๆฤ๑’ฮe=šทjC๛๖tYFeVช๘#๕่ๆEั>ฺwšลณM€ฝs็.ีmะุh\Pฬอำ*•+าภ~}ฬษ~.ใ>๊7p0ญ�เE์l…ึญšS๋อeปL‡Gm‘โ%้?�ๅส–)E#‡ qนNHfšฏ!�^f6$ฯDเ๖uO4|ข1NYหๆอ,ฺu์L�w์’ละ8ทm๓zŠ)’Z-Dฆˆ��นGท๗UฎT ชZฉœ�ๅอY€5q\nฺฆ ฝ}๛Vf@P‹/˜\฿eงสส…วOžAiฒ ังไ๗E๔ฐ>ณj�&Zตึ๖>ข๊:mย(งBแ”™๓่ะ‘ใชจๅิ,ุ[๚ˆ๕{ศีaAผk*ม nฐ๐ฺ๋๛XุซืoะะQ\†v‹,ž฿ร๖ข8�๓_ใ๛ฮ=๛i๎ยฅฎN'•๗yอj]–๙ิ2�`“~“˜ฒบhคม{แฃวO้๚ญ;โ�๐OG8r@wŠอ๖ „ƒN=‡™cชYนA †ก'C�ฎ�ๅผ_�`�x๛ž๊Lฝ+EทQ่”iพŠB™ฟŽBY“DกT๑#‹†!วra=ฅึิ;ด๓‚ํญ“๗K]ใ+ฃส ฺ]”๓UrฤคIu้ž2รl0žฉ_}fัร)ณ(^๊”จ{{ํ้vฏA๔lอ&Š]ก4%��_๋†…ยฮุศข{-ฤื์ูณีฤZง08V@ โ^��๗ฟ�ซ_นr…rๆฬ้t ฐOU€ญ\ฝ]Tlช”ดfล2ƒ™ป3ฝ๚๖งUซืบ[œฦŽN%K–pปผ_1'๙Lกsข�WjU"คncวM ™sๆI็ฯœ5]p(T ?M๑™`ิหูŒXl#yฒคดvีฯ~ ปฮ๖g•๎Cณx๖1 ฐxA-๗c%๚๕ัc+<i�๛๔ขjU+;คปJจ]ฏ:}ฺU#/„^�๎œKeึฎฒฦT~HOอื ฐ!}‚fGŽฃ†M| fNŸBua6๔šจTญฆ‘�งWwชYฝšฑ3บ>|8?ฏชU*O๓็ pี‚BB—4mX›bj๏9ฮ<`Ož9'Eปษ’R๑�๘1Bดํ�KbŒ/ขำ๘Qƒ-ป!+ViSงขž^ํ< ฎต.=^ƒชาฮุอ�vาโeซT1J‘<eห’Q�ถŸ=w.^พjไU,WŠ*–/m,ฬ3บ‹5JG€๎๐๚๕kร[\1h฿บ)e=„‚ส�บ๖>F๖อ›ทโพ์Iด`ธ7sŠ^9ฑbลค�w๎‰p2ง๋ƒ.ึ_–s็ฯฦ-�iษฯkŒขX?uชไาร๖๒•๋„๗/eŸBuฌ๎L�`ห�PTˆื…��ย฿์=p„Vฌ�์gูฐ\`ิ ๔๙‡๐g่9าฑ็ 0S�เ`}๑Žฒ๔๑�Mpuะ bF อพฆLB ๋ฒไ!ฝx�žJdˆNUsฦ ฒ]ฐ๋7สฯDท �๏U‰ณlQบิษU’วOOeฬkƒ„T%พช•ณ�โž7œ*ฆฮุQฃFQ็ฮํชXขD ฺนs'(P€บt้Beส๘z=ุ4-์ฺต‹FŽI;v์ Œ3าษ“'ํJฬ›76lh—ฆ‚B€๕™2Mฦ*S�ฤ๔์นณv�ใ‹-,^ขS่EDŒร/จa�zvi!ตX๖แร_ฉุ๖/� ๊ีฅ"E R๚tุ้่๑ดqำfZฟa“qH๎z~+rฦ๑0ปpku<ณๆศct[ิฟUฎไทˆf`Uธ l๏้ำgtโไ)๑฿�Z๏ุพM€ผ™ˆ; อโูว$ภNŸ9‹ผ'๘x{ดiใ†”?_บ,w–‹๐ +Vฎ6๒zว๏ฎํ�ฝ—ฺด๋`‡W�ะม)WŽ๔๐แCZฝvอ_ธุศ‡—เ‰#,… ฃiืK"฿a ิฏ๑’ร’™ฏ!`ราูqฟ.๎ ฐุ"~?๐;๛๊ซดc‹ฝw ฬฦ?บ›1}Zฺ๊ัท๋0๎ึrำJุ๙ิ<uˆŸ9z�™Tจ@j\ฏ–žmฬ+Vž$ภv๋3˜ ภร๛๗๗็/ไผ3ถฝWoฃLฝZUฉธxฏา ก&M%“ะ๋eส๘z๖G;ฏ ฐsงwhl~)ฦ๐ž4ฎ�ธ)ภ+s๊„‘�๚ฝtฯฏk๏c`็-ZF;v๏“X2คKC�:ตฑC๔�ณ฿EใBแ๛^ฆ๊�•’$ฑ…ฒ+hฑ ‡XฉX^4$ˆ0/บแ\ข 7Nl!๎ะณ?้๙ `ศ3ฟ\ค้sR‹7-œ?ท!8๏�{P†!+Rlฤ๐"‹Y•ฝ|๓/ฝ๘หvoช4L›ŽMEW� ถฏฺ_”žธeฟ�‚f6Nd›G‚kSิH"tO…๘K Aภฐ6ฬ,ภZ\n๗†{ำ“…หŒwDXณ๘๛วR”dˆ�ปท; ฅ+V‰ค่&ค<_UYคcPฎ๔้ำำ 1`Fบ‡‡,ฤ„/ฟ�’’&MJ5ฎHq@IDATYE�8ˆ+Vฌ06ƒnk/…'EดhัŒ4ฌSธpaฺทฯ๖adˆ™ `๕ํฉyt'๎�ฯ๗eaฺไIT ฟฏฏส้Sด๖"\Bผ�ฅK›Zดง6ฃัหš็/ˆ๘ซ7n�"tลX‰%]๔พu ๋7์�ฟ๏จaใๆt๋๖mนฤZœ7{†œ9Š[๛›3o>ใmTฃgw/ชSหืฃIe 9ฺN@าใN�*>HTฌหHย#:ฅˆ๕f6ฤ”}๒๘‰L†๘”R„KPุG>jะ?ต๐ˆฝ|๙Š^ฟyM“งL™ฏะดs๋&๚Lฤ /ยฤ-ํfร€7n�ฑl{๖ฅJ•JฦXM?žนจฟ–9žชีฌkฌณw็6ห�>ฬ˜ุ gํลV�ผu;u๊าีX1I�+—แต๙์ท฿Œผ‚/<ฯอ๖่๑c๚Mx่(K“&5!>ขป อโ™`แ‘rโิiบvํšผ_3Š{ูŠปฺฏšขห๙ฅKW่๚๋/n”_ฤVvื๖0ฯfp=๛หyz(ฎ๋ โภqƒแ฿‚้5ใQYJqชk<ฐฯFตML๑๛w๗๎=บ ผNo‹g>ฎฏ4"v4b ๛ๅ๎ฝ๛t๑า%บs๗.E็3aย„โาQ"1ี =Opญ?~’ผDXe#† ขœนl�๎โˆž)๚51mฦ,?ัทq#คcม… ถ๗…ˆ|�มฏข๋m,J*~K๕cT�š*a'ฐ์Q—‡โนŸZ�N~�๗ศี�ฟ•ฑcวขฤ ฟrUิ฿yOล�v[\{‘#EฯŽo ๏$ซ aภฑ๑>ถ๗U+P้ลฌŠ‘bๅฎ พ —ฏP,O;ู‡|–v’x๏�บ{�๘ IA�Œ�k[v์ขEKl๏!จs”(‘่๔Y�oŠ3Vct๑;ู{ธๅ.>ื0lฮToงืโu^ฟy[ฌฤ!lรฟ๖@|่&H@~xb�ุฤืยB„5[X`1ธยX๏‰v๑L๕zb”hฏ.s=โศภมC 1Uฯร‡`ต*•dlP%=ป[v๏ืฝนq 6kฺ˜5m!ใ๊�{Ÿ ใ„ฐžROv9฿ัซ=}b๛ศอ—77ตhึฤกผ๙:?t๔หฬƒa�ํฺดrX � ัฅ,i’คn ผXgศฐ‘ด่ง%ju้�šโlSณ็ฮงัc}ไ๔ฒj~๑‚9bฐ–oีข ƒ{Wโรƒ?ค,0,ฤ้ณุuW๕Ž/Ÿlีด>™อ�ธu-Yn๓–๏ฺฑ eLŸFญbˆŠfv๘˜ B8ฟ*Ÿ—ิGb‰"ฆ(l†ฯ)\^B‹จ ้QขDฆbเฎl฿fยขƒaปงฮ”m*ฯูษ’Rทฮmจซ^pœ8žQC๚ช"~N๑พ5s�bั๘uฬแ๗๖ิฉQ™ ไหmlวgฦ:rิฑqQ@ุ‡Bยณiะ๐q*ษaŠ:๗ูู๋.}�ฆญดf�f‡n้ภ฿ซ"ยภ๊ืฎ&ฎH!B1-Yผˆxฉdทฟ^‰ธŠํบ๔”�`;y�pš2sฎŸl�fํไ{+฿q#Z๎ฆื€แ„๛f%Œ?u–ๆ-ZJ/>4NชDŒ~(V„ชU.ฏ’nŠ๔ีึฃ‹Fบz5*Qq+;xไ-Z๎Bฅ›1}่+๙›���ฟขก๏ �บsO�๚6"ซฒjŠํgฟs‰ลzxŽ�*ึ9{แฒŒ7‹xจQ"G’EนxEๆa!uสd๔Mโ„2ํGOœ‘๓๊OdฑN-–๊ฮฝ‡TeH—šโวต9ืเš='๖ฅ,ฏ๙q๏มNฝ Cjdอ”^��}C๏ลณaํฦํขูๆศ2ษEc๒&ˆ/ด‰H2V๎�‡ฯUW–6u )l'ฟ›ฯ~.@ฎ\ปIก)ภ๊๕ผV|“oท}ำD๘]ž†ขˆฉ3ƒc๛๙{o่`”๙๋จ!œณ’ถt� ฐ_พฃk฿Š:'ช‘)zd?v`ฑ{wุwโ8ฎ?zKฟŠ�%‹‰พŽQผWYl,’8l@wV-DX‡2,พฉY€M’$‰๔Lรหจูเ]๓๋ฏฟš“�ตUฤy.<#gอlูฒeฃำฆX‹ก-ภยKฐrตZ–ช^ˆG๋ืฌฐ๓ฬ2{ถ้ๅ๕๙bE ำD๏ฑ2ษ/]ฌ!๘e๓,คฃl�DYxu-]4฿ฎ~~m#ฐ"ƒY๘ จ�ง�@ปnไV๕†h๒๓’E†วœUgiๅ*U5„, D†ษ�1wXณฎ„œkB<+/๖ญ ุ๐ฤึ ื_๖\๙Œค์โY0wฆ0�ฑอโxาCO�03 ooช*t[ณv=๕่ํ๗Gพี1่โ!ผ4แๅงFาี๗๙/…ิ๎[-3ฬe�]†ˆv๖�9Y�YC‚ีถ0€Dreบ๐‡swQ|ธก+_ช”)ล@-ถGUึ?ำ+Wฃซ<-๑�ี1ิvt†hp๘๕‘๐ค๛ะ=\•ังๆO`ม"ถ๐˜6‹“๊<ๆูŒ ˆ‹ŠปฮNอฃaMฦี}‹�ภ>ฑ w๏ฉa"ไลๅหbih4+๛cEง๗*๑1งqอป#ภ.š?›pm)CcW–๏r"ปฟ=j�ภN*ภข�่"ŽCg††฿azRBZA ฐ.ํ[RๆŒ้U–Sข#ภอŸ1ั(ธ‰ˆŸCทเ๓}?4Bf'{บm�พ‹/]ฉ'ูอCœDฃ๘ แู๎฿ฎฟ#€pฎL๏V?qสL—#B็ฯ›K ฐCFŽwบI<'ั๕Y™ฮMฅ้SˆQฺ6ท;๐tํ9`˜,๏aˆงบ)!OO๓k^ฏB* ดยุ‰S�`•8…๋โทู{žํผzIaŽ 3&ถซŠ_็…ณ ฏะ๖ย;ิ“ฬ]๖ศฑ“ไ3}Ž<4 ึึฑMs9๓‹๓ ิง%žกfำEิ6-‹Xอั… ๋�ตงฏ‹๛�ี}ะง{Gแูš�n๗๐Gh ี฿.๓รฮwฟ๎(๑‘ ษ๚ต›.MJ—ขุ๗E Q�šUฌ6เดฎฝIg l !)’%ลฌKS ๘9ธ,‹ม‰N�…žŠž[าแN;F—๛3ƒB€ถ/…ณภ>] ‚7o฿ฅัm=ˆF ฦuซ ๏y๛žYjˆงณE฿ทo}=+‘‡ฦ‹†ตซ8๔zภ9žณ่g™งzเlฺพ‡ึo�!7ูผA-๑\N+็๑�cภH9ฏ�dฮ–š7๔mธ๕™)”‰ฐ.m›J๑๓๐‡เฌฬg๔@5+Dิsbpฒ๔vฝฦLšI7ฤ`dฐ๚5+Sฮ์พลฦŠb"๒�ล?� ู*ฟIฝ๊–ƒžAจ~$๘reทฝ�๕ \z X+XU?5-8๔]๙ีึ8ำค`l\ล1ม้;ฏฉษ์๛„ฎ�บ!ผมŒF‰(Gฒฯไ‹๗฿P‘พN"Fฦ‡™b้ฃำข_ษBหฅก๋žะฬ=ฟั๋ฤ‚fqข‡งั5RษL๖=–yAํูž�;'ฅlI|ฟ‰\ ฐw~๛‡ผD\ฺ=—ํฯE{Uฯ๕% ฎœ€>บJ, ฐฺœณซ&ย:ไyธ๘ Žfถkืฎ4|๘pฤ/๐ญ๐Žัปฑ:r#�gฯ 1bฎูฦŒC^^^vษก-ภŽ?‰fฬšmิ BkลŠๅewฯๅ?ฏฒ๓4‚^ฒ์„ฎรส0bG�{pŸ–,Yn', ๆ#ผ�o๒ลห?่๔™3ฦ‡/„ๅ™”-kทผ0hา โส—ฃโยปโ�ฬ™�๔hฌศเL€๕™: ๏›๋ืฏหnฑชŽ๘๘ว>Z]gL›,“อ1 !ดึฏ[G0ฐo�:$บฐ+sื;X•ว�'y 6’ๆอ™A9ด็Œ ‹wุฮ]{ะฆอ[Œ-่,•(Uฮธ†pžO;Dส+˜ฝ‡@~,G�ah`UE2fศ ฤ™ฯ้ไฉ3F�[ไ1๊KBI1J!l(K!บะๆœ๎�ฟG๛๖Tษr:rุ‚ศซLUผ๛า‰Fc'Nฺํ๙ฮยeจu�™ยฃe๏พ�ดd้2:p่ฐฑŠแ4dธ๐๎^&ืEห�ัƒ๛จ๏€ARผ�[tฝำ ƒื ย5๎1�˜ขัE๎afณbˆ๋%›(�™�xร๚๙฿=ยSe`ž(ภ๊ ภแ.ะxท~ํJ)ฬๆูผdูrั3ม&ๆจ�$ษ“%‘ƒšE_” Jแ .nwฮ๐๛Z„Uน*Bs่q‹q?๎฿ณCzอฃzฏ,ใyUฆtIบfญ๐†R ศC\jษˆey๚ฤ๎7 แmโฦ‰‹ข4x@_ั ๐œWt๏u\KVชlPO*ภŽ;ษ<๑q๚ร๗EDืโBT๛…๖:"ฝลPWˆฏรลจเส‚K€ล๖แํZตb9J+<ไˆnห‹—ญ4bˆšฝ(�nญ:t—#1c]ิณlษโ"tK|๑!{ลมkิ?์ึปiแ’ุฌ�)๓Cq๑n‘^\่€๘Mพrํบฬƒ7฿œฉ6Q ƒoก‹3<•@]ธ@>fล๖�๚*~|9ฒตŠ๋9x„อ;1‘๐ชj๘a`24ค(V3ฎฉJ?––1ก๋ํ๒U๋Dํษ์ฉ‹Xฒ’โOfแ๕! กA‚@ิUgS=คยืBผาทป,๊Žปw�!้EŒpn›5ชgtฃ‡ุเ3m–!›แยว}ใVลฝ�^๎ขoั‚๙ลoG4yเ= oPุ่ก�ฤ]™F�ธ+ภ�ผjฝ๐hณฝ•-๕=a=บษฃป<,Oฎ๏;™ญi๋ฮา;žยณ&“๗‰ปืž.ภbป่‰TฅbY)Hขaหี}‰๓ึผญ—1ุ<ฯห–�žพ๙:!]พvC�— 3{ฅ›ฏ]ผ[•๚พ(ๅ๘.‹hH{C๋Eใธ ySวบQไถ๓!|ฆฮฆำ็ฮหอ˜Ÿyฮถ ฯ�fmmข_–ฬจj…r4ฮgบ^Ÿูญ‚บโโ‰�ฺv A%ภBXํฺ�ึ@j� รฝงสร๓sp๏ฮ"ช๙pฬb'Ul็6Mค๗ซžgžวu฿w่8้ษซ๒ CvวB[€ฝ ำขำ”๑ล๛_ฏvีžถ๛๕[๙ศ.อผ0 bฤcˆศ0๓ต�ฏg'!๚&“y๊O๏A#DCศ=นุฉm ‚๐้_รu08�(A�วc�Mdc‰_�ฝ~๓& :Vห)ผs๗ฌ3Ccหฐ�=e’้A%ภึฎVะ=_™>Wํช?R�\ูU–๔๚๔‚ฆํ๚M๒N L%�B[฿ๅ‡odบvs%�œ†Uตyึฦ๙"ล‹Aๆฏ<�’Zอฟ/็ฃ‰p�หฦฅ‚ฉฃั•Gำชใ/hใูW2/r„ฯ่๖X฿zD€-;๎6ฟ๙—�^นฌ1จa/)Sโจด๛าŸิgลฏฯaุศ๊ จ^พXr>4�ฐยิอ"ฌพ๛E|ล1้,Zร^ฯ}€,”ืัW_}%ญc9ฐ†S ฆ„pบแกaƒt) Mย>@•้qUšูำ�ร!ิโH๗lC7ž้S&‰.๒)ีช.งA!ภbเ.�z8จW|lเuข,ดXˆ—…Š–Pีกพฝ{PjUeฬเ%3{ฮผ’7–[6kJm�๘ Hseˆ!บeห6Yq•็ญซuTžY€�ๅ๔q™…ˆงลWƒ‡42Cฆน‹>ผ.Š~๏+๒C‚ค,g�‚†Pd^e"ภzu๎@ ๋ืSปSณศช 3๙…งžŠม‰ขC๛๖1ม๖cญ6b^ๅฒŸ(mฺ42�,šมz*X,j๛ศฦ ้ำฅฃŸ—.R›๖ืT4K_‚ukืดŒงฉ—ำ็K—ซhz๕๛6sF9Xิž}Œk๋ช๚v\อ_ฟq“สU๐}กtgึฬpŠฯั]6ฟ�ฆอโ๎้ฑ#‡ห2ž*ภ๖๋ำ“ชWu์Ž˜g๓ํ�wจT9›0 8V^วธ‡‹•(e'hฅฌ~O+๊‚Fžฌ๔ะ๐VGL^˜��€e„-ษŸ/�วาญฬ|่๗นU๙#วะผ…พ๗โ๖อD๏•ฏฌŠyš.ภ๚ต๑„ …7๋ว† ซ๕ +ผ)ณtแ3ธX VมาlฃวO] mทบงc๋Ž� ๏ษ๑ฃ[๎‘ฃŸร�#ภš๋`^^ณa3ญXฝA&7ฉ_‹฿UYPฐวNž!„4€)˜ึต'‘Ž๎๛ญ;๕ภฌ๔LTฑcu+้7฿ะภ>พ€ฒฐ?�่ƒAเี=๘�`แญนRxซชมคฬป!s*Wฆ„Œ็ช็�{๐z๖*“เ9~ิ ;q^/๋i๓ฎXผ฿Ÿ=‘f‰๘ร*๎mL1 ํฤ16๊X๕๛ย†`�ไbเะณฒ(<–แนฌ›XrB_๓๚๙‡‡ผ๒ชFXฤ•eDร๒่– �่๗ˆ�xข_ป่ถฦ ณํ�{€f/X"“อ^ำๆฒฮ–ัaณแฝญ„mเn|ู=๛ัฌ๙‹ํ6มบN*าใ๏l›w์ฝ‹|ว|ภภ^ˆ/หf#v�ฎ�ฒ =ถ?^)*bช�‚%ซ่ฐh ƒ๗๋่A= /Vs8€xb ใ~��ซชะ๐ดัฟ›‘oืq>ณdผX$ขGฤJ}ศะ`WoุJเก[๗Ž-eœ[•6dŒhl๖๕ฺืK„$๙Bf๋"j�๊)wŽฌj5๑บDำๆ๘^฿•ส•คb…๒๙๚บFข“๏แ�œไ๘&๛7ึ,<�]z๐Vnไ๎ธด†h…๑b@ฺ๋6ัa>@7=ยฬm๊+Jฃœ_1`GnxBซNพ”ดณD(ƒt‰ข่›ง‚รDx„‡ถz๊#โ้ฦ$๓"ภ&้t‰�พ๛’ฤ‰HG๚ฺk#wEh…j>wคwlฅ์1ฉgนธv๕ษ`C’๖‡}Y‰ฐ“๘ŠริXข7Eหงn๘�บu+•*UJO๔�‚ จVญZ๒ฃ๛€( ๛๎ป๏่ไษ“ฦ๖CS€5wqีใ๐ฉ โ…G๗ŠุฏUฉ\Qf๋ฑUyts…‡&บๆฮ“KฦผTy๚T�ศจฌฺ�ฑใว…ที*ฺบm‡CwoUS�#หก-ภ=vœ4n†ชHณ„ขฅ�l๐b…เ ๛แ๛b4nฬ(sงห฿ๅฮgฤRดxฎ(2ฬฌซฒศƒ&Œ8โลHท*ีk^ิqใฤก="*์’ˆ1ZฉZMฃจ๗ุQž€`๕ม•ิฦwํูKญ�vP‹า[^�๐zศœอืง\น2„‘ำอfvFJฅKู„e]<�Jtง�ฑeฃyuาC1 ผมบ•หสธ“A�ไ‰S๔๚อCธึื๓@ou�ŽžปฅJ�`lƒฌTฏYว.”ฦ�Yำ)g›็‹QะษฬษSงจN�ฦFn๗ฎ]จ^Zฦฒšัโ:‚งถ•้ืณ.d{ชปw็6‡๛ว˜g3Bfเ�Uฆยzจe52}M�ูส‚J€57ฮ!ฌM๖์พjจงj๘€W๙ัƒ6๏+๓เ}(Oุ|B„อ)~?s ึฏ� j›ๆ๛ิ/v๚ฬYไ=มGญN+DรH:ัๆึ™~ŸฏŠ6ภ๑ฅ,๏ีK rสอBB€ํะฆ™ๅ@[บG—ฑa‹๖โ๗์ฝ^!ภ:3%6T€…ื„hxฝ๚ใ•๔&บv�–แ}ฺHˆฃ……HชL—๊ซ„พœล-\$โ฿โฝ\F‘UะE,„@0{–ชz๚5ลศ๕�๚ุธB$…คnบ7mย(;jUn๎ยฅดsฏ81.ฑh˜€ร1Nโ*ณ๒ิDๅ�Œw_ ๘–_ผ~—ํ[‰ฑ„Bn„„u๋ิฦ#ํO`ฦB7rAO3 ฌศCLe5 ›9  ?`u�ฐฎบ't๑้ส๔๐z†ุd6ฤ^FŒ^XฏฎฤภZ)ไ|ฃ–ๅ๛๐œ๘แš”ฆ?H ฎ xxร๔kื|Lju�๋4 q`ฑ฿c'Šzพฮ  ็™2NดฺŽw๘ �โปฯ&šจt๓Tฑฯอฅ+ึธค ๅƒC€ีลMฝNฮๆ}๖”q2[ฑเอW'€u๏;DxMู> {um/Gฎื๗ฏืัJ€ีC@<ํŒ�2ุ7J@DD(๕~eแOž9'~�็Z^Ÿ่-ี N ูe\ฏ—ี�e1xฃซจฌึ hš+๓ถtึœง/ว๚2&yตoeโBฯoูพ›|ฮแพž6ัึ ฎ‡@�ิšีlŽ๚z�`็MŸ`๙�px‚ร”‹๓ุฐ…ญ๚!| „93U๗H‘"าL[7~wฎ]ฝL@Xซ:มใ"ฝ๒:vgp7�ว6G๎+�ญ=ะบ๗๗ำ��4T lˆ†6แภา}€Ÿส�PTฤ.์g9€7(ผB•ๅ�.+ีญแxจ|ซi๋.})ŸYPK„.Pฆwฺ-ุ๚วฒ, �:ม�ทษ?,bณ^ผ�–ฟzGฟ�๙/=๛๓ป๑šึŸฑ…!€€ !ถบ๐pี฿ส—๊sช•๛K*žแ Š๙น}ž�I(�a6„ม[‰ฏช ฑ?"V`๓็ฯO{๗๎U‡iL—.]J5k๚zโ˜™8q"ตnํ๛€W›ชTฉญ^ฝZ-ŠิŒ๙ œALKt›V†nœ่โญ›.@""š_ึจQ}jาฐQ �่'O™N๋6l0<-ฬ3ื��ส‚K€U�ว๑'5ka78บ๛ข�/L?~�Kf~๘แ" วกาโlฎซ๚ู}�,กUคˆ‘ิ๊–ำ,฿fฆษ“�k…๗™2๐ๆฬ3ำr'�`Q฿”)RR^แูาผicงƒž�!<ณj@b="ๆฃ.ฆ้�ษU9Lƒ[€} ^�‹—,c์ืvงŽํŒe5c๎J฿พmkyฬศืลร`U�ฮœ=K5๋4P‹RXึใ1ฆ™Qcผiฮผ๙Fุ๊ั#ฉd‰โฦฒšAŒ,ูsฉE๚แ‡๏i�จฦฒซ™ห—ฏH>ช ยg@ไ6›ฮ๑h!ข[™6แ\๖‹๘ 0๓ฝดE)ล๓%^�8ฒ์(o:'บฐย๊ิจ์46๑qัU~‚่2K"b๊�Uฮซ?8ื+ืl$„“๘ใฯ?Uฒ1M"„>xˆบ2ˆkใ&ฺ�a\• Šผ๎� OH๛�;ๆํ๊lแอซzถก�gย#๖›ฤ‰„ฐœZ†–0ฏซ/๋ฦสKV?เ3nธ]iต. ฐŠ„�ก:tํc๛ฺพคm �๑…ว/ ฯN=Vถญ„๏฿9"lป`ฎ๎฿5>น€ฐท๏�—a.๐\4ฅผ9=t™Gืy�Xท�#(งธ/+—๗]O‰”๚vะ๓`HŸ.FRH ฐ�w U๋ท๛วŒYถหtฒ€ฐˆ;r@w#๖๑=ัX0l์d‡5[ฯ,XX`ณ๖นJE Tt$ธ๏mQแ ฯX�ุ๑�))q์ˆฦ*๎ฐุbฐB๐ue`Ÿ�๑/Ušp›0—ูฦŠHฝหลฃJ฿ล0g…๘2 ฐ!ˆ�,พ"์ฬnฎD„ีXt�?z๔จ้}๛๖YฬๅPะ +Wฎค *8ฌQบtiัฅ฿ึ๚Œฬะ`'LšLSง๛vƒPH•v3แš๐Š8~โํฺฝวaไx๓เ;`๑กnุฐD"~/„/+3{เAˆ€ ำEณธชถฅ{ข™หV€=~โ$ีkุDํŠฮ›Eูฒf5–;ฃ‹Z)#†๛วฬ์…ณ'�ณบ]ูฆอ[‰xZ‡eZf1�ไI�”ฟP1ฃฬ๔ฉ>bิ้<ฦฒš n‰พอฎv'C @ิ1›ณ(งsJ�Š๗Šฌส๒็หkู]๙้3๛zป๒ U�ยt™ท๚b$!๔B0˜ ‰9r็7’ขžไ๎ฯ**b*3pฆาu†ธฯฌ‹รKc6๙๏^฿fฮ,๊š+7aญ<อ็aY€ ฬณู,B๊p)�˜šร8`อฯ=ต gฯFœงŒYพSลH๗7�1๓๘ษ:~�aเฎ5kืโ"6๐[7ญ3ถf>vฟB๔0ˆ พ+;ฐwง่�ฅZ ึi@X �ฯC>bK/BE ็7ฤ3ค?Eฤ^ฝ€Y k,๊ิคu'q�#๕3B„|ืม@F0�ฐw๑L‡ๅT%Š"x+ำc?‡ปlลZZฟy›�PB๗|wM๗ จ;}ฮBฺ๐ˆปป4สแใ๘ภ�rƒ=~๒Tฮฯš<ึeศ%"ž"DCg†Q็‰ะ›ท๏–=7T9O‹ซฉ ฐ่Ž๎—ภฎŽำ<…`ˆ˜ซ0ีe_…pี0กxป‚ภ?ฐจ‡C ป?ยภ�นv๕2�๑€U^�hDqล[`o๚ฤั%ŠญKณฌ ลJฟoฎX],ฏWซ*/โ๋L`ฑูO&) ์๐qSไ@Z€ิผA-o7ญม๋์/"nฉึๅ>ซคญIฝ๊F�/ฏะq1—3C8ฑSgฯ‹p8ฉq�jFฑŸลเโปDฬ_�RฅHJZ62’œ ฐ่ฑักว ฃfฬแ |f.  —ฎส2]ฺ65สบ{�!แx•๙Œถ�+Xถ`๓v์�3ež��œึnฺYง†˜ำo฿�Mฝบดฆ„ โหrฤฒปขอ†ใลqรB[€}๓ฯ”ฌห%๑[-œƒbF SƒRษzm`5œyOฮcฌ่"ฤ€_ถญkrปฎ�~ ฐำv?ฃ~+ูm6b๘ฯ่๓ศŸ‰แ้อ฿๏ ย),ฐฌฺษ.1่ึเต้ย�7๒˜U:ฆ ฤ๑o๕Jf ฆ็…ิ< ฐ!DฺJ|M2ค�ปC�G ย๊lโฤ‰ล(œwHฟz๕JqDฬ*ืญ!+บHภ~ฐ?ณeX>}ฺHMฑEป๖่eิล™๖Ptgร่‘ฐXฑbษฌเa๓ๆญoซŽ>ธส™ปก๊b ๒uV๗dCž;ฆ�„ธขปwlฑ๓FP�0{c้1Tอ+!vง๎ฅ‹f…ฤเIฯลภm0ณแ_ฑOQWeๆโ1p2„ธฟ^ฟ–ษŸ‹Aฤb‹sเ—™ฝNyมนฺNP ฐ›ทnงN]|เž�ฝh่p›ะ‰˜Ÿ'E๘ซ—kณkfˆ๚ป๒^Tว็,๒1H ƒแ�ฺแญ›™ลบี+(E๒dฒˆ.ฅk๖บuๆ=Š๛ณุฅ๊Z ฐxแ2๓5฿ฃˆ�|@ ]Y”ศ‘ๅ=ฉ–_‹็`™๒๛้zรY€uึจ ถง7 !-ฐjป๎L"ภ.[)พM6O 7ๆ}u๎ั_’ˆ๔ฐ(ภv๎ัOิ๏™ฌv๛ึM){G‘rาิYยณว๖žไฎซ�ค‹C:}pชภ ฐ)’9ŽD ใ3mถ�e.1ฒw๋ฆ ๕�ปœืชะ`๕.ื๚เiๆสCS"E‹๖9M๑v�่7ฏƒๅญ;vำย%+d–CซuยJZP ฐ8ฏ^ล่Oaบthiฤ…ญ_ป+\ภ๒•๋Œ›ึฟฌ;ƒp!ด„๗ค้ฒnบ์ฮตซ—qW€}!,n�ู๖’.MJ๊ัฅฝ%$ถ๊ะ�๐ดถ ญa^q’/†Aร0x˜•น{?Xญ๛1งV€Eศ„P๏ฅh8+หB|T๒๛xต5^น~“ฦO™c,ซ็ฯฃ?„๘๘ตGƒY)ปs๏๐ถฏmXปชhหคА.ภ6ฉWƒฒfNoไMžตฮ ๑Wโา">ญฒ `ฑ= †P0|_w๎ๅ๋ !ลx๏โ;ฆHlูธeL—Zฆแเย@\สภจฟฐLฑmถืฯhึ^�;@ม4ŸำฒึIdUo?�‡r ผ&็›ŠMƒ*�Deu๎L�`uธ(๔ �–ŒMต๓ฤค๔ฺ@\…�่ƒTฌช7็ใท�ขŸำŠc/ŒzJ–ถ�F ๑) ฐ!€�A`žฏJ|Uปw(ใแ"ฌ.ภขป>๘bฤˆกื˜ย[uํฺตฦr`f๒ๆอK๛๗๏wุZ่ `�ฉuว M๖™`eี]โเ’E๓ํDH๓(ั*”มๆ-�จ“H™ูหษ,ม{o๚”Iชธ์2ฎำส/˜CYพตuPiฎฆ[๔มมJ/F]„x (eืฎ]ฃŽ]{ะ๕kืU6„ส–)%—ั��ฐ•A$๎ีรKึแ"De�`อ-b†ข๛ต�mอ<าผ93ไfjŸˆั แHY�:ตฉ[ืฮjั้TคP๏“Gษ.ชNWฐศ0‹ŽบะaQ�eบg�‹๊Zƒ่ช<1จwณ2wV€?ั‡ฆอ˜e์^า>ผEฬลจ2m๑’ฅ4x่#"�ถM๋—]่ฮใ˜Qรฉpก‚Fฌ\ˆ\M„w๑U+OYญีฉwO�ฝ‰ั|ป๖่I‡#\฿ฃF ฑปGz๔๎+ฝ ีบญ[5—‹๊=&<ฺ›6omœ+”ำลgตžซฉ.ฦ9klัb[8ึS']็1˜Wฃฆ-ํ๊P… ฺ>Tอกะฅvะ€~‚UนญŸ–.ฃAC์=ดยฒ˜g3๘้ƒพaนjๅJ„๘ปเ ณCว.†G:๒aบุgใˆQci�‚…ถ ‹ฟฺตฆfMหˆ_\ฑJ5#lŠ‹�๛๓็”ฏ`QฃฎY�6จ๋ฯ‘ยโ7K5Š™l3‡ใภฝบh�A4œ*„E%†โœuj�X ’ศืcŸŽิำˆ™Žผ�"4หO+l=eJ/DeDlZ๕N|]€ญT๎*ฆ=ณ ฏ�ด] žwK $˜ƒjT*kทnP ฐญšิฅ โ7Aูึ๛hอฦmjQo2๑ฌPฯ„\€่\๚๛ย๒˜TA H6s�Rjๆ6ลฯ๖ฆ jฒ(š,Dึ�ƒฎž ๚\จ[‚v1กT๑#ำพ^ษๅผ�(ถX๚่ดจ…ํ7Mญฏ ผฉDฆฝ=ท?dํšธ�ๆ<ิฌชฆD ƒ‰มฌ“!๔‡ุ`ํ ฌZˆฏช e=X„ีX฿ึญ[ฉx๑โ๊P้)๑Ÿ;w๎@{มโกพ}๛v*Rคˆฑm5ฯWxภ๊š,๊1cึlูUี /ˆ้‰ฃ3ขต[y1!_�@ELฏœylโ‡Z]หณeอB๗๎฿“]ง•ภ†�Qร‡R™า%UQ้Qฯ:� ฮ-Rศฉง—=}ๆ ีช๋่]แ%EŠt๙ส;๏.ฌ ฏFฤTยฺฅK—ฉRตš๚fๅ<สมƒิl`ใŸฐf‘�C�ิDB$^ณb™��/็ฯSตšuํv•5KJ˜0�Kn�พm—O฿xqใฺฅY-ภSP‰วzุซฒฮา‚R€ล>๔:้๛t%พปร0ฐ,ฎำยล~0Dิ ยN’$฿ศ8ยjคvUgณHฎ‹‡A-ภ๚Lq|'OSป–S\‡hฌภKBl˜M_j๎fฎว@ฦzธฟ!๊††˜ิ"ควSแy aS7s(=ฯูผนฑฤช›ทฮP฿Ž๒D6฿ษ“%ฅ๕klฏ(a.oย† งถ๓(๓ล96[X`Qื€>›ฑ๎ึํ;dˆฬ+รu๏y�™ฎ๒0ีุภ>!๒ข๗ภ_ฝ6vO�Œำำ-๑As๑า%ฃ1๔XฎeฌD7n�2ึCL` บqkŸษกื฿ ฌ.เ]ฃHม|T\xหกak๓Ž]BT?fW็ฐ(ภข‚mป๔2อมq|%ผŸัโบg๋ๆฎ‹u๔Y2e๑ฐ Q ๕ะัใดFฤ�C#ธฒ€ ฐM�t�>mฝ2‹๋นxั‚Rยจ๐ฐŸWญงตทศy|(W(WŠr‰pฟ={N'Nก{๖aZ7o$๓PXจ*ภส๚๑G๑jๅ)มชW�aFซตyรบ†‡ ฮั๔ู ƒF)๋�น1จ–.Zแ�โ๘๓ๅฮAD๒ฝb€ดM[vแฃชW๙QŽ๏ใjปam”,๎Yt๛W!3pฌไมา™๙uํF€ล๛D๓ถ^ฦภi,ญ|้ยฃ0!]แลVญ�dx˜"^0”นsํ๊e�#ภNๅว„g9 ืะe า%Šษะ่nธฯ{„เฏ8–ืS q]มะซฑI๋ฮFžyภภ๎}‹ฦˆGฒlฬ˜1จ™ธฮ3Oย็โwdีบFC xฺต**�… ต_ทv†G'ชซ{oส—‹ชU,cฮ๑แต๎ณp?^CˆD{ะสuถ็nน’ลDxžBฦz~อ่lvัฐูจNUฟV1๒ƒR€5{c'๐rล{bz#ฎธฒ[w๎ัจ ำๅ"ย ๎�™>�เ4ขสผฯ˜โ�วlก%ภฮ?๐;๕XŽตถU๑Oงิ๓ušBjฉัท่ิ�{ใ๔†‰จ|ึvีGx€2coาำW�R�่`Ÿv๙J€�_๔๐t~hjป<]€M'"้›า.�ฮ�๗*ฝ}๗ŸLŒ{โึkช7�ึZ1[L\%พ�พฐา๋2�๑๖= ฐŠฬู 6E:]jGe\•๑ด้=1"�“…6มuGฬWณ็ซ๙˜>ึ,ภv่ะฦŽk>\น-š5กvmlK*_ƒZ€ล>ZตiOป๗๎Sปs9โ3 ศo”้7`0-_แ+Tโ^4ะ…8ณœJo016 อคI“š–.^`x฿jY.gอ็๛G=tำBจC/…ณ็ฌใ}AT]<ฅOŸN฿„๔ไ…Gฏ3kาฐอœ3ืศ๋l`žอ8ศŽข‡ย–-�Œใีg๐,ซQญ*-๚i‰‘ฌ ฐH ฬณ๋๏ล๐�๗๋บ2วง†่_ฅFm?‡แ‰�ณxฆ›cถ6kู†๖8ˆ*ุูข๙ณ [สฬ!-� W ึ ชi@X์ปฯ t[||93tฅ…ุ ซ,บCฬR](อวาฐN Zผlฅƒ�#ภZ ยฅo;ฅ๐์ปvใฆL จซ‹\j�ๆAจz‹stวล9ยzˆ‹8ฑสt*4Xิg๏�C4s�bU5—ำrฅJPีJๅ์สธs��‡์e็Mfท‘0ธ”,oศHoบ|ีZศถ:|ฟฎ==฿ฟ!ฐ? ฌๆ3m–x๖~PH,*�๚๕^๋Z—}wฎ]ฝŒXˆn๐˜ฦ๓า/K“*๕๊๊๛�…F‚ม#ผี*”-I•~๔๔ะ˜0`่h‚๋สR$s 7โช�ง,8ีฎ๚#ๅอ•�@๖P„<สททdkแІ Wฏ�‰ำ็ษxจ(A๑XU\T๓บ/^พ"๔’Pฆ ฐH๋�ก…ฤ5กสถ›"œ.tฅ‹ม›ตt‰".Ÿ‹๐p?uŽล๔ฤจ[^๒ฆf•๒v฿ูFฆ˜ั98Xxฎึฬำุ๕ฃ—�านปฏ้ฒˆ๊ทฑU‘+Zx:ฺ/ฅยbVzรHj^ไTKl/B๘ฯhฯๅ?iฬฆ'ฦvB`ˆIุLืใ ��็ฟr�jนbR<_Rา8‘Œซz‚๊"ฟ^พ/)QฌHดํ—Wิ๕c๚Sขส#ภ๊qnฑฝๆ…cS-Q—oD]v\๘ƒฆ๎|Fวoฺยm•ฮ�อn’Xํ6ฤง์ŒศOeฬkl�๑U6‹ฐYq�จQeร๊ิ,ภ~%lบy๓ฆ๔pC/_พLq…G!ผ/a$///:tศ>hทฬt๑žญร‡ท๔ฎลjx‰ศ˜1#Axิ-คXฟb€BL=ึ�A,ฤ‡:ผๆš7klฟTร�ƒ‡hยฤษONณแนC�6า๓Uu™ะห`]๏๑“คทช๊šž]p\0wฆ^ฬๅ<๖;jดทเแ„ำr5ซWฃึ-›็X/˜‰>Sฅท™žฏ+t‹ฟ ฮืศัใd„ คlฦ์94ฮ{ขZคำ'Ž8ˆSˆณ‰r๋ึo4„ณ‹ @l๊�ณฏƒว+๒ะอบญ_.ฝเ„<+Cwt„6Pถ}๓แQ๛•Zt{ช Vuv{C โศ‘'ฟศYฟn๊ๆe฿ีอผ]ฟb`]x�ถy=%Jh�๒t๑โ%wXm{’1PดpAต(ง่ึ�_–;vํv 2@vใท[I,ภƒY 7ํ) ™IDAT]�้าฅ•BฟนLอ: H…�p&าšืQหxYBcƒี�ฉส@ะ์าฑแบีํš๘ฉQงždŽ๋w๎ฌi–ก>ท]‡ฮฦq่�ภนว9‚P†F&�D๔�๙ Lq=#|€nบ >Kฮฃž}๛ ว�vื ดฑฃ‡ o€x๚๊ฦ�ฦM›EฃLใ^CžํM7ƒไข UชeW�ผิhqu  โ+รsa3bhhAƒ‹ฒ๓gN๘ษ4 ฯf์c๖�๙r E�ƒ��{u๋J/_ฝด๓’5 ฐy6ชใƒทjฯ^}้๐ัcฦ๙Wy8ฯญ[6—฿ฉ45E›ISฆZ ศธŽ›5mDxv˜cc}๋ผ‹่งฅหI๗^7Ÿ�ื๘ัƒ{�ชม9…๘ˆc`Yลภ!�4wkw๐ž2c.ญ1 โช�ผu—~��z|Yณ‹:Aฮ”>๑~†k๐ๆ{โทe‡  �…ท]�a-ี–๋`�Naิ †pปq�nฺฐe'ŠYZ๊”ษจšธ๎ฬ^พrB D†๕ญ/ำฆNAUฑ^���}�ไ7ฺ/ม*—ทฝวbPฤฮฝm๗ขQะษŒ๗๐~Nr|“}๑Žฒ๔ฑ9/๚ฆ:Ÿƒ๐9ช๚WI ดeecท<ฅ‘|ลeซ2!ฐE ^5ข�6:/yH‹DŒU�๔ซVƒp้eKdŒN[ฑ๕€ Œ‹m๚์๘ญyฌo�aแ๔NaฤB ุ`„�lีบ�gลญSw๗mtg—J„๕p๋ฮvCชŒY€ล~็ฯŸOu๊ิ‘Uจ]ป6>|˜บvํJอ›๛~]]$w์ุ!…ุล‹[VทjีชT @*\ธฐW- }H�ผy3•.]ฺกHp ฐ๘ฑำ_T๐้ŽA,น~�บ์บ“@t�L?พ]๗g�@H‚‡ข๋b๘EM@CkatถžJG—>t—ฐ๚ Ve\Mั๔๖ํ;r๐ฏ฿_<]าื_'ฆคI“ส๚ธZyn�บ%D‰W”&Mšืรี~เ †ฎาh=ตคU=nŠ�็โbว�Ÿ๛ะi�Bg๛š:}&auบ“cเช€˜~ แeรY��6ฎ‘�…Šู‰ckW�L)S$wwr]ฟบฝ1!�ฝw—b ]\CDืทะ6\ฃธ6nŠฐw๎�ฅ˜_ฤ คษ’ศ(ี€dUG|`\นrUtฟN้g`��.\ ซBธ!ถPษฤ>pcๆAŽฺgw_šXข๛„็C qธs โบ}๐๐ก�Ÿไ›o� ู˜c ฉu๚lF�S๖มƒโ|ฆ2อa ฬฅ:ฎ x6โœ`pฐ‡โผD]†aq็๗ฯฬ_…0๕ไ้๙!”8qb๙LS?ชŽฮฆธ๖1pW”(Q์๎a4ถไ-PฤXญf๕ชิงWcูfplทฤ`Ÿฏ^�%…‘จQฃxBต�ฎฃ…ั๕rิ›Pํ๖สข บารC1๓ะี5จ ื4โสย๔Qฬ๛๙๓ฯฟ่๊›>\x9xห_D7 ำห`xMtAฟs๗พฌg"ั˜›"ERหXœVฯล๛~%฿ษIฤ;Yฌ/}ฝฃฌสJiG1wแRyศ๒ๅฑ{…Y๑p๗ฺณZื?i๊ย C*ฤ†ึ๊ฒŽ.‰†[ยใ๑้oฯ„‡c<๑�˜Œเู๎๊�ƒ1�ธ๏๐>Oฺž;lP<[8\ธฯฤ;ม3*ย} j๑ซยM`;c‡๔6V5 ฐ*ๅ G"˜Lๅ…ิ4ษื‰ฤ๕E4&?wฏี๕ฦเ~๘ฆFŒุภ˜;์“W๏(S/็l๔ศแ(I�H”>ad้qš#™}#ˆU�Ž�๘‹šฯนOwuƒเฺPxพ๖(—" ฏXณม๓tภ๊Gดไ๐sz-ๆaบ‹ๅ™bฐ!BU๙Hƒฺๆ๛�Q™ฬ1(�๋Hข9ย+ต”๐N…�,อjณเœ฿ะ))eOUฮใŠ[ ay|m{็Ÿี'^าภต้ม๏�ๅ1>œk’๋K๊S>ž๔ถห แ`C๘งฒ;+Bฤ9แqˆQผศ๔่ัƒ6lุ@&Lpˆ�ฺพ}{š8qข%.ˆท ,ฐฬำ๑รž'O:~�ึ ฅ็—ซ๏ƒ็?-UDhx๎ยฬ1?C‹ผา๚ d็ั†v~Z87ดชฤ๛ A7o�–ฃืซ]v๏ฺ…๊ีฉฅษ•k C3.\ค๊ต๋๙ซF๛vo—!7�ตR0vW€ ฦ*„ฺฆอ๑uทnZg78]จU์ุ๑ฦ-� ๏ูย๙๓Zzz"�"bNยrd๛–ฺถl๒ แC�”เ�ฃนฐ ข"lโ˜!ข[ด}ผรO‰ซg 6จน+ภี�z+Žใ=}[4$ฤŽ่๎ชม^Žุ`G�i๎ภJ€‰พ}๛R���%x๘ไฬ™“โ oฯ~�๚ษมธฯxฟ=ybํ ฏš็ยใ]"]™ตm�ึฒ ฐ–X81€เ%—#w~cํ้S}(^฿n–FFอ B�FMB[`๗๓fOง฿}B5แ�„6ฝ๛=ž™{vl% |๓4ึู €ฎ๏�ต�๗a WๅB*๏S`– PฑŒฎัํ�ถฆๆM‡๖O~?๐ชู๋oจมก`��๔]ถ,b๔็ิย�๙ฑg7ัฑ“gŒ|ซnาF&ฯ0#๐ห…หbD๕๋ด๏ภ้ล‰๊งc๔๔j็aGยี�” ฐ๛iœ�ะ`? สก{”,ภ†.�v๏ฮXt)�พ};,XP๛ขE‹จeห–ฒkd๒ไษ)“ ๊ผˆ/ ฯXWvGtDทHgvZŒRž/_>)ๆZ•aึŠ ง”bแ6jb‹แU„:ุฟg‡C\ฺ€n; ๋ืํzVm�ฆ%ตlึิ!>^h่ช\ฝ��qa-[4ฅVอ›ษyO`แั�กณ—ฌป;ะ=rม�Yva�Y/8ห|ช์8w|๖�ymšิฉ ƒฑน๊พœ็เS�๖ิY๓้เแc~~)ำฑfต€ล[๖sใ\€ „ฮ=๚� (…๐>�#ำ"๎$๐ํป๕7โฃzJU=ูV‘p=…—�๘�]โ\'T์���ŸใD�@IDAT์]ธิFฝPคHฑโR\ JqwงธCq)ฎล���Š;wืwทขm)T�ฮ,“7›อส{ปฯ่ฝ|ผ$c™œศ&g๎œๆยศ ;wแชฌ>M /Zแช!ˆย;ํJ์ุฑi๏�ฝ”>}zYfศ!4hะ ๚๓ฯ?ึ1g�บu‹พ๘โ sฒ�พs็ๅฯŸŸ๎�ฝk™ฤw๏�ršวŒ@hGเ๔™3Tง~#y"D 4ฉSSซ๏›Sม�๙B๛กq�}ˆภŒYณ้า�ooZq4oฺุ‡ญsSV\พ|…ฆฯžcdu้ะž$ˆol๓ #˜lฺถƒ6n๙‰~��‡�ฤŒึซEY2้ว Œ@hF G�กt��C ๎J’(ตh๒ล'4๗�?ˆ@๋ฮ}ไ5Z=uสdข�แd๗o�บC๏�ฝญ‡h��๛๏hาจึ>72ธxๅ†์Hๆ ฉฝ๊P&`ฝย๏ฃซ์Š€ลมฦŸ6o�LYฒd‘ว�โล :qโ„๘(๘@ะ(Pภ%&ฮุซWฏRฉRฅ่ๆอ›.๋3๋ฮ�x�ื_6Lใe็#8$>F€` ๐๚อot็๎�๏\ฑ(ูI่“O>๑Aห�#ภ0Œ@` ะนว๚๋Ÿ)Œxทg๛๘€/c๘Oยาจ!}>พƒใ#ฒC€ X;8xรWธ#`ฑŸจQฃาดiำจvํฺvป}๛๖-E‰ล.อผq๛๖mJ’$‰]๒ฦฉAƒ๔�๙sปtซ &`ญPแ4F€`F€`F€`„ภดู ้๔ูŸ)|„ˆbภ,,ฑ!้ไxัฏ�b�ฏ๗๏([ึฬิฌa/Zใชก&`CรY …}�,jz��ณฉ+VคQฃFQŠ6๙‰w๏�QคH‘\5d'N,ห�ฟŸz๔่A .tYGeF‹ž>๛Um๒’`F€`F€`F€‘ผx๙’˜Hฏ฿ผ ‘�ใNy‡@ดฯ>ฃ~=;RT7Nh�ํ…k‡˜€ gแ#์Cพผy่๘๑ใY๘๐แฉfอšิดiS‚feฎ\น\ึ�ดi“”*˜5k–$^�ฃ›3gNฺท�€ห๖9“`F€`F€`F€ ผx๑’,YI7๏�ฅ?�xบฤ}๐ศ‘#  ฤิ NuŠ!ดุู>~˜€�๘ฯqฐแ�๙๓ฉYำ&มฒow;5{6ีซW฿]1ฮgF€`F€`F€`F€`ผF€ Xฏ!ไœ!เ_/Xgํ๘2={๖์tเเ!_6ษm1Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0N`ึ)4œแ-๗๎�ฅreหาล‹ฝmส'๕ำฆMK›ทlฺฑ๖มป|า87ย0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภX ภฌ(œไ;�พ}K , ฑcวะ7|ืฐ?ZBpฏ:Rฝ๚๕�๗๒Gณ\”`F€`F€`F€`F€p‹ฐn!โŒ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ &`†ืbF€`F€`F€`F€`Fภ-Lภบ…ˆ 0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#0˜€ n\‹`F€`F€`F€`F€`ท0๋".ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ@ภ`6`ธq-F€`F€`F€`F€`F€`�"ภฌ[ˆธ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0C€ ุ€แฦตF€`F€`F€`F€`F€p‹ฐn!โŒ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ &`†ืbF€`F€`F€`F€`Fภ-Lภบ…ˆ 0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#0˜€ n\‹`F€`F€`F€`F€`ท0๋".ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ@ภ`6`ธq-F€`F€`F€`F€`F€`�"ภฌ[ˆธ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0C€ ุ€แฦตF€`F€`F€`F€`F€p‹ฐn!โŒ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ &`†ืbF€`F€`F€`F€`Fภ-Lภบ…ˆ 0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#0˜€ n\‹`F€`F€`F€`F€`ท„86F๔hn;อF€`F€`F€`F€`F€ ผ|๕Zv3s†ิ^u7ฬ�„yำยน Weu&`ฝA‘๋2Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ@HB ฤฐ้ำคI๘p_F€`F€`F€`F€`F€0!N‚€ ุŸKฎศ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0! &`Cุ แ๎0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œภวƒฐฯนไ#aF€`F€`F€`F€`†ฐ!์„pwF€`F€`F€`F€`FเใA€ ุ็\๒‘0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ@C€ ุvBธ;Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#๐๑ ภ์วs.๙HF€`F€`F€`F€`F „!ภl;!�F€`F€`F€`F€`F€๘x`๖ใ9—|$Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ย`6„๎#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ|<0๛๑œK>F€`F€`F€`F€`F€a0ยNw‡`F€`F€`F€`F€`>˜€�xฮ% #ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ„0˜€ a'„ปร0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Lภ~<็’„`F€`F€`F€`F€`BLภ†ฐย�aF€`F€`F€`F€`&`?žsษGย0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0! &`Cุ แ๎0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œภวƒฐฯนไ#aF€`F€`F€`F€`†ฐ!์„|Œ�๙$lX †ฤ๑'์�๛�๛?ข��7๖ฮปdF€`F€`F€`F€๘/#ภ์๙์๒ฑƒo}�๎อ™3‡ฦG7n�ไ=Z7Ÿ"E ุ๊ฑ#5hะ€"DŒH‚ecF€`F€`F€`Bo��FKWญง�w๏ำ๏ฟ�*๚ฬt@”(‘)Y’ฤTฃr9Šํ3ื…9๗ฃ@€ ุโ4†ฬƒx๘เ>•,Y’._พ":˜>}zฺฒe %H˜(D๔‡;ม0Œ#ภ0Œ#ภ0Œ#ภธBเทoi๘ุi๔๊๕kWล8/”"=Z4ฺ๊พE‰)”w�S˜€๕).็/ย ู<นsั๑ใว�U/ฐ ็อ›—๖์�+ไุ 6ฐฑๆ๖F€`F€`F€`ผC`๑Šตt�ิY๏แฺ!์_EuชW ั}ไฮyฐ�c่ฒ…_Ÿฟ Ÿ๖ค7ฟ�๎ฒœ9๓ณจQจxกผ๔yฌ˜ๆฌPฑ=wฮljัขEˆ์+$๊ิญ"๛ฦbF€`F€`F€`ฝ๒7Ÿ ๊๒2t �g`ฏฮกฃณ�ห#ภl€กs_ไ๋ฦํป้�๛ฟ�ถ(!Bx*Wขpจ$a ไฯGGต8*๗I_~๙%.\˜ฒdษBษ’%ฃ่ัฃห^ฏ^ฝข;w๎ะูณgiฏ๐b=}๚ด๛ฦ,Jไฬ™“๖ํ?`‘รIŒ#ภ0Œ#ภ0Œ#ภ0Œ@ศA }ท�!ง3�“@C`�ฐพึ672`6ฮƒทไซ๊Vh%aใฤ�œ^๛Cฃ&jิจิดiS๙?]บt๊๐].o�ผIณfอขiำฆั‹/\–ี3ฃ •งฯ~ี“x`F€`F€`F€q0โNI tˆ ุ@5D5สl œ3๙!ผ๐d-้น'ซฌฟMxฮ�e๓œ $lDแฝ๋‰… †7nLƒ ขธqใzRลกฬห—/iภ€4qโD๚็Ÿ๒ญ�ะ+ูช-N z~�ใŸQxKณ1Œ#ภ0Œ#ภ0Œ#๐ฑ"ภ์วzfํ‹ X{<>ฦ-&`}|Vฝ%_UwB; ๋ ;vlZธp!•,YRถWหƒRอš5้��๛n�aึ-D�*๐ฟ���ผ๙ขE๛ฬ_๕R๘๐‘cิฌe+Iถ๑Eฺดn5}๒ษ'i*H๊Lœ4•ž�๚L๎ซrล ”ๅซฏ‚dฟฝ“ณ็ฮัช5๋ไnยP๊ึตEŠ๔qG๎๑^ จaP-ดุ�…‹่๊ต๋ฒปyrๅค2ฅK…ˆฎ๋ื:ิฉ};!7M๖ํฅ›3n‚ัฯช•+RๆL™Œm^ ]ฌ[ฟ‘ŽŸ<);>]ZชSซfˆ<€ทo�ฯฐOCd฿‚ซS็~พ@GOœ–2PMพซmืน —ั฿bะ;KๆŒ„ภ!Aeทo฿ฅํป๗ษ�U๙ถ,ลŠ#จvM‡ž ณ“็ฯ_างŸF VอQฤ‚l�!qG�๙N`1$v๛$pulแZŒ1‚|^}lว†ใa๖c<ซŽวฤฌ#&[ ฐ><ฃพ"_U—B3 ๋Ž€M‘"m�บ•RฅJE ๏เ ซ–8~ตฎ–zšยว* ไk™2e่�๙๓z1‡u_ฐ?๔์M}๐Rvุ‹„ฯcฦขž�ปบ(:ฒ.]บL&Mก_.\’6‚Dh�ธq(ož�ิฆUKŠ#Hv_[ฃฆอ้ศัใFณS&งB๒�!iๅนฦศWฐจัฅล ๆPVกm์ส–ญ๘Q่'sZ$VฌX”.mZัNfy�8-ศ+Wญก>�{9ฐgกo“มฃ็cลสีt๛๖ก็�^$SาฆIC�ทv{>อxฺฑ็ cก`JI˜ ฅL๖…�๛Ÿ๏�ำ๑Sึฯ s๗˜€ต!r๏๙_ิwอc๚4BXX9ลŠโ็l5r๓3z�๗�จ@บ(”?Md3„!~› X"_“ฏช[ก•„uEภ&Nœ˜8 >ถm%uฌพZ>}๚” (@—/_vฺค/ุ ™ฟvฺพซ |�8ž`h&ะ>6๖ฮปTฏAccpมู ฉZฅ ่��YถC๚Eq�Uฉa๏IๆPศ”gผu +Eฟ�๖›lญ\ูา4b่`Sหมทiพ~๔๛˜ ุเ;/��๓=1่‰8e-›7ฃไษ’ชMcูถC'ฺฑsท�ฦภ�O[7R„`๔\ณa ญYo๛0:iZyRชXaชUฝ’)็ฟณ้Šผ๙/ฐ›ถํ ๅ+ื'ฯไXฑbRŸ:�ŸGŸข]{m^;ทk)gKBศ €‰Sgyิ›b… P�ฺี์สโ�ฏGฟก๔๐ัcปt}�ฐร๖ฆ˜1ข๋ษํzฟมฃ่ฦญ�n/\ธpิดAส๓ทe�S`�”™๔วo)๋WฉT๑"U]�ร…CQผ]ป๖@/_ฝvฺk<ร[4ฎ๏1ๆป๕% RxjˆX?y์0O‹{]ฮ6ู‰)kf็๒lx7|�ไ]ฟuGผ�๎uŸ‚ป�ปQ”(ถo wยIขcAม�%c�ตช”'ฤ0 Tตฺ้Oฎป๛ใ ๛�ปฉ๎ดปbเุฑต๐‚งL›เSสœไSสš๔SJ/ข��sฃ๚•+W(GŽN�W X? €`ฉSงขuซV˜yบาณO?ZณvฝงลiฬˆaTชT หป+๘Bh�Nš<•ฮ‹i€5ซW%บ;fอg$�r๖คืŽ‘+:้P0>š:y‚�ฝ๚‡€Ec)’'ฃ๕kVบ%v�๎X+เ †fํc"`๑‚Z��สoUOฌ_๏žTฝZOŠส๛/(X�8ส6ญ_cIŒฉ� ^šฏ&`ƒ๚ ๘fGง†Mšอš1• ua6ฬ˜จ\ฝ–‘ ๎Z5ช�Aน2j�T9-WํSศใ O•ฤ ใหฉๅืn�ณ[�VูTฉBiชTพŒฑ�_ZqE��—ุรฦาี๋7ไฉo\ฟ6ฬŸ�แ2˜:kพ”(@ฦิqร Rภก`0&l�๚ญXe{‹๎F2๊�rฅ$ฌn#วMฆ๓ฟุ�!แๅ Wx>|๔„Ž?)คก�•ลˆw๔ะ~zีv]'`!ฃฃx๐"o฿พ3gl๑<ํZ5ฅlb“ฏL�‡้าคฆ]ฺ:4๋๊v(Šz!f&�•=นใ›ฌ”H<รŸ={N‡ ดฐO> KใG๖h6รธI3�zภbf&<ฟa˜!1iฬPนM •*–%_฿ˆQงM�m� eK&ŒขนฒะFย:#`GŽI:uฒ;ิ%Jะฎ]ป(��ินsg*[ถฌ]พณ�ปwำˆ#h็ฮ”1cF:u๊”]ั๙๓็Sร† ําิ†/ุษSง�}คกํs็ฯูM/ZคฅL‘RํV.ฃG�Œ~W฿.-จ6ผ%`>|DEKฺˆ6จ_ ‹—๔ ้ำำ๑'i๓–ญดqำใ<๕�4*xนโ y่ๅ.<ชŽGbึ์นi๋๛๕ฆ*•�{R™ X%W๖๐by๒ิi๑฿�Z๏ะฎu€ผ™ˆ'š ด‰€1k6›0ู€๚ฃM7ค|ysำe1ธ๓ฃ_Xตzญ‘้ฟ'๖ZLu�ฐi“หข๘ˆ6b”Q&A‚๘ดs›ko=ฃฐXมต’ฟpqA&=—ษ)’'ฃB+9$™๙๚a6$ฯ๛โ)‹๑�฿˜ฏiYษ.]นJCF๚ Lไศ–ELSmlื2|87| }ฆIt€”jืฅ— ฒธ6>vำ X\f๙เb;0 ๘L›0ยgฑ ิ}๘_"`1‚AXิ(Qh�จA^ฐส๐ ๏ิฝแ�†™ ตkTVู^-!ูXัB๙้ป:A7่KVp๖็‹4c�Rต๊–…๒ๅ2็]๛I‚rAEภ†�DH’Uู๋?�กWุรT–อ ลขb*ฟฏ-Aป‹าท�WŸัฌฦ‰}ึ<$๚ฏ{B‘"„ก�ใQLM‚€=`m0�g ุฅซ6 �›{4ณ”+Yุ#ฝ™Sgก“g–่eำFพ�ส๙tu%›IXถ5+๛้ไฉr!aiEภ*’#•บม๓UM“E:‚reศNŠ ˆt�โล I(ฤˆƒ’%KFY…v�ร‡iีชUF3x)~�๚ต๐8๐#ฒAB*Tˆ๖๏฿o”S+พ `U[๚rตJิซฏํ้ำงLข�๙๒่EึแmนH�๛๏�(}บ4”&u# C-แ‚ะ_ฝq๓a(`%šGYE's0ฌ_ล”šฟ�๙›6nNทn฿–-@oq�œ™r�ำˆŸzดฟน๓ะศัใŒ๔่ึ…๊ึ๖๓jR ,Zข6Iืž|$ฆฎ)b(‚๐ˆN•าqะšฒOŸ<•๕1M5•KPุวฆฟแE7อ‡b[o�|KSฆฮ™ูดk๛ #ด>rฑ…W†ูเ้tใฦ ฉe๛๋๓_…gpjฉฑ?^\sQm��ห/TฝV=ฃฮพ]?Y๎฿(๐aลLภ^8gOถขุึํ;จc็ฎFUh’;ดOnรk๓๙ฏฟy)พ๐<7�ใ'O่ืg~ๅาฆMCฟ -O14hŠ€…ววษำgฺ่ตk๒~อ(๎e+�อ�มด๓K—ฎะ๕ื)nœธโคกข๏ฮ^แš�a๊Yฬ˜1%กƒ6ฑ฿CGމ้อแล}”Jo2?sฬ๛6oใผแ�)ณ:w-[ตฅฝ๛จ"tไภ^‡๛ฮศ๔็สBsถ๏€AFญ�๚๒พขฑํnๅภกริฌE+ฃXทฎฉ~�ฺฦ6V๐Lx�ุ6Tฟว s{B�….f๊ิ))]บt–็๗�ฝ{๗Œ6q�`ฐE7<�nkS3๕2ๆ๋'ฐX\7ล3R™๊žA๚๘�฿ฉˆ๘ˆ฿�ฅิ›็2~ฯฮ��‹ภ๐})ฎ์ฟQ๏…f๘ตซืTW(•ธ>ี๕ํํsัhTฌเท๏๎�{tAx�ฯ๛$‰‰>ค%H˜ษฝึ๑|�Yฬ.ธ}็ถ˜ึ๚%LP "&ฃ๔b€M7ฬ:Aฐด'NQ!Iฃl๘เ”#gvน[ฬJัฏ‰้3gำ๘‰“UQ -ุN�๛ Y�ภD‘‚๙จA�Fฬ+“gฬ^}ถ็o†tฉฉ[งถๆ"rZ๐wฤฝ๐์ื—า �ตหโบภภK๊”ษ=žบŽ๓ R๚ฉR$๗ศรK๕๋�ฝ๔Hj้ำคr้ฉ้ dศ•kื้๏ฟ�ฅ๔iSู]ช?ฮ– �๎� u^ๆ X�žณ?๔‘dฆืฯ˜่78ฆ๗; ์๓/ล9ผEษ“&š๙Ž๏'z๛V๋.]็�7๑ ‘ัฃ๋fิ๘)โูtQ” Gณงุ,ซvญาt�kVซHeJu(ถd๙jฺบรๆ\โŠ๔Bภป๋7o‹gโ{Jš$ฑG฿M; ! ๎XีMu aปํ๗M้›ฌ™U–Wห€ฐธท๎ˆ็@ฺT)์ˆtw�ฤ�๛โ�@<ซ"3€ฝฏˆ๗C1U>ฎะว ˆอYฐŒ๖น1X›–M,ƒยS�ฐ”โ๙ุท{Gน๎อHp4m�Y<ห�ฯฑฐ4cาh;โื›ถ=ฉ๖๒ี๔Lัaฤโว‹#Ÿ5xัm๖ยt๊'กง๓บw[ELรŸlš†�ื?�ฃsw฿R›…้ฦำ๗ฦLฌ›ะง^ชh8ฐXฃำ+Lภฺ@๙ฯฐ3,7.‹สๅJx�; ปzใvcŸM๋;�x0 รŠ๛ใ?R•*Udo๐แ€ผ[‘C้๒๑ฑ?~|๙๑‰ถฑฏ…ฤวตูB‹๐1ใ&ฺ้™๊�Dค่.;่z‚P 4ฤ S๕<|๐VฏZYjƒ*โ)Sึ์†W‚^Vญ•93-]4Om:]š‰ีIฦ ๒ย~Š*ƒœ4eชัNm1ี4C�|๛Ž]„`�N™ง‡Faฑ2p๐PZบ�G™„ใ9๚ธ‘=e๚ !A0อุ>sโˆิ4็2 h+f2sำๆญิMSรK•ู,k�˜$ข„,ฑ ฦทoู`�…ๅถ',*ึkะฤฮ๖ุแ�าภฌ‘;จ_™ซ๚‡๗๏กปุyp[uPah&ะ๖๏�AรFŽ"`jถvmZQณ&,ฝ†._พBmฺw’ƒๆz8๗ฝ{tณœ�ฏ{sใlึด15jฺBjก้ํ๛ษฦJษ =�ีz‡.?ะณง6r:ož\ิขY‡โๆ๋๘a๚กท†ผ‹ƒR๐ฎ�ปs›ฟH‹มCGะโฅหŒฎภ๛5E๒dฦ6VFOณ็ฮ—iะ3V่๑=•๛P8ฤ,ปˆเRฮศ‰หWฏำคiณeเ0UK๔ฑค๐๔ชQฅ‚ๅณd฿ˆฑ“ฅ~'ŽIศธrฅ‹[ส,xCภ^j“งฯ‘ฑฺ–ะ,oู๔;สœ1ƒžlท>Iิ;y๚ฌ$ฅUฆ๛ึฉQ…žŠฦ€แ๒๏9Sไ–๊ƒพฤ{&“u๋3˜|๐์ึ๓ี๚จ!}ํฮ%้ SfัY1Hฃฆ์ฃ,GพL/‚;ถiแ๐ผ‡^1t‹aใGข‘‚Hฝ/H0u๖๊JI‰๋ฮzฤ๎�—ณ๎�ซ] ruวž�rร๔ด;&ต฿=ยปvŽ๐ฒ…eSย�4oคฒไ๒ฤ้s4๑rzeาํฤ5Xฒhaช.ฎ�ะfžฐk7nฅี๋lฟ Šœฦ๙kะผ<ธ/ฆŽny๘ธ็ฐ=0Tฅb9ริชBสไษจoN2ห|8~ƒsบฬ �พมคœด{๑๒•ร5‡ฦABฆ‰ฺถpะ=ฆแ%๚๒ๅkแธ�@}\๓ส” ส฿–ลฆวv๘่ :แ’xฮAฤj`๗$๎M˜ฏุฅ+ึะ–Ÿvษ6ญ4’eF � ;l์TI˜ซnEฮ[๕kVฆ/ลuค์ะั“ด๘G?k•�Uฦ๔"˜YA�ฦB�ะรวO้–๘�บxูo Y•UKดŸ9CZ๑�“@ีDs.KฝY่ก~1‚,๚๓ล+โท๓ฉ\O“*9}‘8ก\‡ว๘ฑ“gUsrQิษฏiฉ๎ฺwุศว33^œฯๅ6Wฯ‹})ห“ใkยต ;}๎แ7=kฆ "ศๆ๔ฏธ๗ึo�aง!œBฬB^B1 }B+๗�รว„็–+K—&ฅ$ถใ‹฿n�ฮb€แสต›œฌ�฿A๋ล7๙�7Mค๐a่โฐด๔ฉX:3(ษ�r๏O๚[`”9I$ ึYI[บ ุ'ฏ�ฆkO�‰>'ช๘)jD7;ฐุฝ'ฌ๓ฅ๋฿ั#ฑฟไฑ#P’Xแๅ3รขน Ob X/!ื X�ก%`ั�€๎ำหC๕Wu3›T|ผม3 fK˜0!=zd›–hฮ๓t;’ะy)ฐ๗โ<8Nแี๏CHฆDUฒใeซ? ใqMภ๔บ๔ภ@”3๋�ญƒ๐lMa—}๒ฬ99เฃุpค้�ญ#แูฃ ว„cƒม๓�i็้๓Xตํษr�ขๅFPผE Q�šU<ฉๆดฬ_โ7rxFแ๙EฒมiLภz‰~@ษะ��ตkW6l˜ฺ๘Jxศ่SY y€)ศ็ฯŸ'นf=z4u้าล.9ธ ุฑใ'ัฬูsŒ>hญTฉ…?๊?ฎ\c็ ุ๊๛ๆิช…ŸWฉr฿ šปF]กส™=;�{pŸ–-๛ัฮ๓Iyพตn�^|่�FgฮยฃไY/ส;้๋ฌY<๒D:-ˆ์:๕๛ฦ ศงŠสS1แฝ๐UๆLn=šฝ%œฐ“งMง#GŽำ๕๋ืๅิXีI๘มวจ๋ฬ้SdฒYทD๋w๕๊Rฬ˜ัลดไƒtXLaWๆฉwฐ*%ผ;r็/d$อŸ;“ฒk็Œ ‹O ุN]ปำ–ญ�Œ๔ K%J—7ฎ!œ็ำวK/Uุ์™8d`ช๘my๒†fFีvฦ/ฟืDd:%ผ—0]0F?ิ<ฆ::ฅ๊zDน”Bj"‡ภ้��{rzธช‹ๅˆกƒ $ฏ2€Ui๐๐KŸ6 ?yสn฿ศw&—ก๊zฒ„วศพ�hู๒t๐๐ฃŠ‚p•,V€Wž… /^ฯ>AซV‹*Iภ.สp�ƒ3›Nภ๊y ณใฦŽ-e$ti”ัฝTC+ซŽ๗EขD ้ญ ํ{๗์.Ÿ_�<——ญ๘QฬJฐ}lช}ภk4E๒ค2` •Gช/ Xศไ/Tฬ๎~ยoC!ฉrU ~๊šลธ์�)=ๆัW๓๓๚ฌ5kTืAqถX)T ?M™4žvํูGs…์ำgOํ~ mGิƒ ๊฿Gxๅู:บ็:ฮีเ€ฌเ�๙ณ๐š‚yซฺ้ฒ�Bพโูศ…b#n�ฯ้ภกcv`ฬฤ‚"`eE๑'ก�UฉBY‚็ ผาVญ�hxฆ!Zzห&฿ฉขโ7�!๕่;ฤุN/<ช‹ �uภ๛„œ$H<ณgฮoพ<9ฉษwตํฮตนซm�๖ดh�Uz™!�ˆ+f YไCใ๏;ื‚˜)Oผ+Dกƒโz€‡ฏฬ0{ [ํ+$ฅyJภฺ๊ก๚เร�ƒGhๆผล๒ฬ๗ผ:ฮฆญ:I\q�A:x*MูAรวษb‰„วaร’*ฑฤ7Q์ฯcษt�F4SซV*'<�’I๏�%+VKRy �ฦ€UiุOs<;>ผหม;ฟ\ฉโ๔E’„t๙ฺ Z'ผz!]C�ศม}ไ:�่,ถqm•.^Dn๛ใ?iฃ Q๗ ๒ฆA‘"ู๎”๗ฦtoc�ฮX f๙ท}�ูค?_��Ž7ๅ}Eภ‚Xํฺฮ๏ป๒ฎ ห‡›&ปฯฯAฝ:9จๆ~›ษNxสขMg๏ซ๚…o\eAMภช�๊KEภvj�„เ�๊สp๔2Vz๒ชr …A{bมMภ^„i‘„iชxโฐgJปnO฿๓œ๚ฎ~l—f�่_).5/l๓6>๗O*>๒ฆนˆฑ]0mZ�สำถ‚H]!UW6ฝA"๚๖๋hF‘%‡_Rวฅๅ๖†Iํ`g,Hๆขโ8!มเฬp�ปปฅ h็—1๋%๒LภZh๖€Eภฌ‚ :nูฒ%MŸ>�!= 7€ฬู~ZŽ™„‡งnมIภB{ณpฑRFwเ}8wึ4ƒ ƒ'ผ‘.\ผ(หเๅแ๐��’่๔UถF]žฦŽ6ถAฬ6๛พต”v@b๗ฎ]$ฑ  ่ฟ๐[ทj…ส๒x้nชŠไษจHกBTฃFUก‡็Hˆซภ“Rz0LOู.ฆOƒ์R†ฉต๐๐R6{ฦ4สหw•๎l Oะฎ�{สlœ?x้b้‰yBภ‚ฬ)RผดAถ ํsงŽLfญลนณฆSฮ~ค�BvAŸ&}�ศ9-T๕ฯ อ,HKšผฯลเJฉฒ฿S้ั๖O[7ืด’แ1ฎ Zย I•?y’พk่็ ขค‘าฬ4ฐ%ŠฅQ#†ส๛ค“&MฅYs็ฉๆจl™R4r˜yadxฐMุ‹—.xซ*8ๆฮ�Y๊ ซ2�Yฮœ3—ฦ YeŠW�ž,กํšฟp1ฃh๕ชUจ_�ตh$Š+Vืฌ�ฎCg;�’%‹ำุ‘รe3ก™€mูฌ)ตlัิxๆโ€ผy.ƒxศฟฐ�ต�ปg7ช%คW` †E๐nึอ—l฿�ƒ์ดฏอƒ>‡Žฅ&อZปoิ พธv�หmฬjภ์ef9‰แ#F ฯQ›ง 4aแ-ฏฬ<˜5kฦTส“+งสvXบ{๖8T๐a<+!›>ad€?๖กaจ<ป � ฒM7xย��ม}ปู:๛…๐t$<�tป)ผq๚ถyภ›ษn}ลT๗dq+.}ฟ‘>�”ฆOดตฃO›อ�๕WR3Q฿งN˜ย“mฆ๐์Rฆ“7žฐบGdJบm�พ“–�ธV&„ื Qห[ถ๏jtฝ~hO:y‰2บ3ถ=%`ฝ9gุา๏๔FV4H ่„6>ะAฟ�๓O์Rxม๖ขดฉu๒ในฉภ’<๘๓]ณถั้ชธ๙ฺsUVๅ 3ษ๐Lฦเ@๗ฮmU–๔ฐํ;ุv]}%ตoีฬศร Hw5=ฟv๕ส’\ถ+‚7`)“๛ษศ๑ƒPง$%๔๛�Lภ๖ํัQด‘\U•K%ษ‚ ีฯSฎว&`ฝD Xkuฃaฏ„w€ ต  Aร+รบ%ฯS๑B`J;ะ =kาฅ,8 X_๘Uฆ{•ฉ4ณง)>xAิโEI๗nร4ฒS'‰)๒ฉTU—K_ฐพำ๙‡๎tเ ํสีK•*A m+eมMภ‚ผ,Xค„๊๕้ีjVฏflc^ถy$�ุaำฆตy4W ัm�~’E๒ๆฮex�บชฃ๒ฬ์ฯgNศ,ผคcZๆเjะฐF 3dšง่ƒd(Rผ”jRA „”ๅศSภ ‹ฬuQ& l—Nํฉแw๕ี.ไาLฒ๊ไL>แญง‚ฑแฃใ๐�ฝาปHoภ\๕Šฅ"(TZYฤLภšƒ`=X(R�h.ƒ"ดr๙bc�?+ๅพญ,ƒ�™๋€ิญWง–ฅฆฆนฌปmxำๅ-Pฤ๐�#ผPw๏ุ๊ิ›ภY{ืo�ค๒�^&ก_�ถ๕๗ลอฌ™Gxภ‚Xฤs)‡Cb0Z X๓ •<๑ว›็๒ํ�wจt๙Šช)9ํ�์uŒ๛ทh‰าˆยพ$`๕๛ฉh?๙ฃSbE—อ€ง:4yafฯ_\/ h1ภเฮ�Kภ‚ฬฟศ๏>�ฑu“˜น’ภ�n|’ฏ< ๑ฎ210Myฌ๐ะต6uvpŸn”ฤbŠ็๗ํปIAyปฉ~*ขลL’ช|,Ab]ฟyKzC*ขFM;วปุ์)c,‡ž(=hัฦ˜a�-ฝ็<%`U?๐ำ๏ญฌEปฎาำาณ&‘E ๋ˆ@Vฐด"`ฯฎถ™ �Q^œHา‰,ญH€V34ๆ V๊ึณk;ฉi๎่Oป๖ายฅ+e2ฆ๏c?L'`+–+ๅoอLด็xร~˜โ๚ส+KrๅศFQ„็แ^แ‰ฉศ6”๗O„wไว๕9iฬ;\ไ—Q๋Gด” ร~C›น"`๑�q๎—‹4{�ƒคŒ.ๆN=ฤ๎0Up4$šeฦO™)fคœ“ๅญž๊~๓„€…^*ผอฆKG@฿7ก˜Sฯฌ๋ฯl+ƒDม๘ษ3ๅฆ�€ต’EA]3ุ,Yกฺ๗dฉž'zY<๏๒ไสNตชU’šวzžืg/X"ฃหjVƒ_�m/ ๅBภ�ด๛€x๏x*w/nlI*bฉ�ยek่ศ‰ำR๗tิภฦ{งY ฎ ด๛vkgTUา๐d�ฯo0�ฎc'ฯ–zฑ(Œ•๘=T์ฺM� x่ึญCKฉsซาž,4ฝซMาง‹˜-๐™�ึIิz5*Qฎ์Yr็~นDำ็.1ถ+—/EE ๆ1ถ๕บFข“•qร๚:ษ๑K๖ฏjvƒ.=x'น;6แZq�m:r�FZB6๒บ้R ˜ืิ”F9wฐ#6=ฅ5ง^ห@pณ…”A๚DŸ๊อSกBแกญ_‡{ =�8ถwฯ€ฐI;^ขw�’ฦOG๛ุs#w…ดB๕ษwคwlๅlัฉGy�l-ปฮัฐ^อฌ5€: B๔ฆะQำ ฃ�ทoงาฅm/—zž7๋ .คฺตmSงฐ5ส๛อ7฿ะฉSถQ:ดœฌ๙cWัSถn�n$ ่�›ชVฉ$ทu}GUS]แก‰i๎นr็”D‰สำ—พ `U{วOœWkhปะิงšซ|ติ?๔‘�์ฑใ'จAใfช{ณ„b๊Œูเลชˆง’ล‹าุั6o"s9ซํorๅ5ฆ‘[ผVuTš™€U้ฮ– I@bฤ/FบUญQว๐ข™ทWLe‡]ำ\+Wฏe7f$ม{Tท€ฐz€%ีึ๎ฝ๛จUฟ>xkƒƒ—wๆฏ�<Šห—/Kˆžn63น3j๘*SฺF,๋,ฆL๏�ถู\t)ศlX�ฃCO@จŸ:yZz&™งๅฃพ zซ}"ฐไ5”™u:Uบปๅฉำงฉ๎wb�บvฆ๚uk�jลLภฎ_ณ’R o4ณ!ˆึฮ]{Œd เร&ดฐร‡ ข๒ๅสวฃVผy.๏ำฟq฿*sๆน๊ฆํถ๋BฅตhTวะพU-‚hตkัPก#โ๗dแ๒5ฦ6VŠฮGห–0า‚š€ลฑ@rภlc†๔2‹�ฟ�‹ฆฯ[bWคB้bvZธ�‡'xัv๘พ1ฅJ‘T–ลตั{๐ป€^ศฺทซกๅุ3๏าึ๓ฟษ>๏ํž‚า&ˆ(ื๚•ธตญK2™f�“นืUB๐ฌฯ> KWGุaTUฟ�WŸัฌฦ‰Uฒวห…_P—ๅd๙นMS้ฬ6ย; lส.—้๗w�Š฿"ข“�SSยแ<๎GPdึKด™€ตP'`ณgฯNGu(ธ`มjะ Cบ7 ฃFขŽ;:4Qฎ\9ฺผู  NึLh8tึ"กqร๏จS�จ#"Iืชืภ%้‰ฉฏญZ6ณ›Vf}Iภ๊�„ˆอปvักรG โR•-ฆ†—.URn7kฅีจ๚้l™6mB๔tOฬ้{ืO[eภ O๊ขŒXx$N7ฺˆLฎ๏c๙+ฉ�ภ!F’๒ด"†—ศ“วำ๚Uแ€ฐช}ี–.\คช5๋IŠ€5{ :#0!ฉอce฿7oFญ[ต›:๋LNC๗๘๓†€U๛วtvˆุ้Sงฯ2ผˆ‘n–y@šงf๖4 จ๗+๖g๖žw6`&`U0;sŸอำำAtƒ๐ญฌ3‚ะ›็2k ๊7mtม�Y–๗ไๆ-[ล์ฤพ"`อ๗‰ฑ7+ŠLGฑ.�zะฆอ[ึ€ถkืฮจHกve�Kภฮ[ฐFŒkดฑj๙Aภฆ3ถseภะ1†n"‚T้c�ป_ฌ๐hDtr5Pgี†3V'Wอ๕Iซ—ูwเ0อ^t0]?า\ืผm๖z4็[mW(SRjD"ฯฟฌฎgiีถUššj?f‚เ$‚…ม†๔๏A‰xF๋พ�Cภ๔œก?พ `[u่ๆ< m;3cYำ ุ�=;ˆL!u๙CpฦxqใRฬั-wญŠV—z%=ฐา;ถำศ3Yึœ:{^ผ{ฬ3๔D๕v0›ซA�š„ปไนV@IDAT >ž˜งR žดๅชLแyฉaฝšฎАޗซ‚ภปKป๏>w”‡พ.ขห@?ตV๕Jป๐k๖bW้ม�ซ?;ฌไRT],U฿uv€uฆ™ช—๑†€ี๛‚uhF#่  �eๅulฎใl{ฦ�EB��๖ ๋์8ซ๋๋t_ฐ๐…Wจฒ\bเญ^MวkLๅ[-[u๎Cy…dAm!] Lyิชm,กw�ณS+#)จ ุฝาŠ5›Œ�cล์นk—้dcฦผฅษ†=;ืOŸ=ง~รฦ9ิะ5bC๛ํธ�t๔†อำ๕โะ43ส'ฏะ์�l๒นRFv:-่ฦ'ฒ,๒ั๛As�ฐะfฝx�=y๓7ฝ๘�z�๛฿t�ฦ[ฺxึ&CD., l แแช฿ส›:2ีฮƒŠ}๙El?@&wL˜€๕๘€ฐˆ`บq›mTฉ\ษยvn๙๎บะ}บkื—๙:›/_>ฺทoŸC๓ห—/งZต�<๑  aโฤ‰ิช•฿^5QนreZปvญฺ VX€D‡@ขนณFพฃ& ล0~สิดaำ&รำาศ�ฐr ฺฆ K”ซฺว”šตฐ‹^ฃZU๊��F<่วฏ{a้m€8รq่ZœแR๕�‘‡fโำ฿#„ ช[.ณ|•Yžฑฬ4%Nž:๐ๆฬ3ำTลnำ‹�ฆJ™Jzง5oฺุiะ3zPฝGL+._น]ฟv]&C"bฬˆaชˆฑt‡! š5`�Cภ>มdŠ•*k์ืvวmmตbžN฿ฎM+ย1ร‚‹€U};{๎ีช�@mJฯ^]ูศ๐`ลฌ9์ฬKำƒฆ่๒ๅ+Uา ธอf&`อ:ภช<ˆEŒสเI ‚ุ|™uCQ~วฮ�ิถC'UUNyWž”ฎฎŸ๛P๑R~žzxvเ;r๔8AทZ™3V.กฌžหf,ๆฬœNนr:z๏™e�Kภ:{.�ป_z{ซcฤ3๓3ก™์สยŠ2{wnณ๓ไAPฟน๓ัฯB7�™ีมนดL™ Xxฟย V™B๋อsูLB๊ธ€ก2ณฬ3ึ�ฬS๕=๑bŸ1ห7ช้žโFข?V@Œœ>}–ŽŠ฿ํต๋7ฒช ]oู|์ฮnUทO�r๐Fm�ทKxโลP›บ�&‹ ฐ8ฑcั่ก��๎ฃ=z*งฑ‚Œ‚้z€ะ7//ฆUฮŸื.จ—าq๕ ฟฎฝศ�g�*#uhํ7จ ]�๎'ž/๐ภCเ'�˜ X}š{NไฅUำ†๏น€7Lๆcn`โิYt�ิY™์)๋อ9รŽ|Aภ๖0Œ๎ 2ๆฬQfZ�๑ วGหึ“%�ย˜Fl�่ฬ™f่อ[ทฉฟ๐(วณๆŠจ5ทฏถ1ต๛ธ๖ูบcœYขาฟ-[ŠชT๔ U้!uฉฐ�H›ผx๙Jjฎโ8ี”}%?MVhณZY`ฐุ—%๔เmบwซฏ=`เ ื^8A†บ"Dก) miX�ฺีจXa?ง™่ๆฎ�\ฆDQชYอ๑๛าM>อ;l์TH i� 6eฮ˜ฮ่ำนŸ…nฉ6ๅ>ซ‚ึค~ #�็‹W่„ภๅฬ ณs๚�/๔ต๘Mj\ฏบQlๅบ-ด๛ƒfฎJL2ตoูHm’3ฯฺwh”รŠYพ`๒ฌ…R.y�45e�ฝ�pผส&ฒ�fb�Š€1�K—า๋ทุ~ƒŒDำ 4฿ฝ{O=;ทข„‚$โฺูMัfร๑โธaมMภ�๙ื�(y็Kb0A8EGงฆ–�ฺ"`5œuOฎ#VT!1เฮ~๊šยnjฟ;v๚ž็ิwตํทGต�“09b!i๐ �๙�_q ๓–€Uํ๏AทญB๎�)Yฅc_�๖.ษ az^Pญ3๋%ามA†ว>� “Nภ&Nœ˜๎�นใะฤก•[ xุ๚สฐ์ฯl_‹Vgฮœ1’ƒ“€…ถhื๎~/RฮHฐ‡"š"ขGยbฦŒ)Yแ#๊ฯw~ฃ:zp+”3OE�*sfZบhฒค้,“ุณCeyดิƒ7น"ŠฬYบ†ช9ฐ’šาฌ:ฐ‚"xาKธ f&#�Kภ*=ีพ9J<G!€”ู@ฤa๔Y|dว็ภ™ฝNyยนjว—์ึํ;จcg?ธGท.4d˜่„v์)!?€Qqณ™ X3†(๏Š@Sํ9“ @>‚„ฉˆไ8ว‡Ep'xD๋fฦbรฺU”2ErY$ฐXณืญ3R�ŸEK๚i‰ZฐxแฒยW?ฦAC†ำ’eหคCSนฒฅm�ฎผฯ‡ฌู�H๕ขEฌ2™ ุ’%‹ำุ‘๖/f2๗ผา†Fuวฎ�Œ๎!ุ^•ส๖':aˆ‚!™€๕ๆนl๖ุตบ๐\ห[ฐˆl…Nภz๛\‰™0g๔๖B�ฐpŸ„ฃ๘>�Š็�ฟx+Exp*ร` ~ฏty‚% ็R–ฏl^fZฮะtvf๚ สx;้l?V้ถHึ]ŒมŽ.ํ[Qฆ/�>Fอu ฺนG™ ลGษuHk฿บ™๘๘ฬdฎJjŠดฏX์@-๐ฒ9iดๅ ๔8o QxŸ‚<ƒตํ�SzไbPg๊๘แัจe!'�KภขีO�พง้sศžคO›šบwvœLD#y๓”€๕ๆœa?�%`ญด6'NŸCวE ค!ขฝงๆ VŸf^ฝJ*Wชธๅ๎๛-น!sิพา;Y/ˆม€๎BƒU ย^ู�˜ฎ#›2y2๊+tdC‹๙Š€ล๑v้9@DhJ!่�พ% 6Vย๐]๊2(š&๊~s†›ซ{Xตง_J‚yบnถณ \–7i†lสY._ฐ*Ÿ�\Vวข/๕เfujVฆ’E ู๋.ืAชต๎ุ=ฤxฟขณ�ฐŒ๕^Š฿๗1"X๔Qaศ๏�ฅ\วŸ+ืoา๘ฉsmตขt„1ณเ7SGมฌ”A}๘ธijS.ึฉ&žy~ฟ•:�ค~Mสš9ƒQ~ส์E๔‹ •A—๚ดส|Eภข=ƒ ฿ืz–๋๚x๏*ข�ื็ถwจ–๋Rฦ๔iŒbภ…@\ส€Q?ฐLa�lฯ•i๖พ็ฒ{าFฆญ’ส๕�ฯ�ขœฎษ๕ฆcัภ*๑ิ!xผtGภ&jQ๐ถๆˆEurGง Z ฎอ‚n๔๖ซ:W�ท� …‡^าชใฏŒ~L…–ท๚B ๒%ฐ^BP2๔มฃ'ด๏อ+ด@žb%ฎว= ่>=� ๊,^๚๑ั-Z4‡–แญบ~�z‡๔€$ไษ“‡8เP#t 0ืฆ;'kๅ๑ถl๑;ฉsค่้S&ษH๗[ท�DE@ efO'3y๏ฝS'ฉโrส4ฆN+ำ?คUšซ%=8‚7uไ%‚พ(ปvํuฺ่�˜ๆŽtTš;=N'ฤ=ปw‘A^@ˆะ?๖�Kภš Zh†b ถ๎Qhd6๎LŒKu A‡@)๛ฎn๚กซ๛”BฟO;,=งT;ž,อคฃ๒8๔คฎนฬ{1ธ‘-GใC คซ ˜† n๎fež`่-;~โdš>sถฑ{xIOž0Nx‘E’i %AN*ƒœรO[6/3Eภbz5œวั#‡Qก‚ b DWแ]|๕ƒž๊ิฎYƒz๕ฐ�›ฯ„@ื๎=ำ฿q}>ุ๎Ayุ“งOฉPQ›62ถกƒทs๛ปk้�5Œs6ะb&`ฑศ@(ฉ๔ญAฃft๋๖mc๗บGทY๊S๖๖๏+pส/_T—._A3๊b%$ฐ�<—qlzภ7lWซR™ ฟ‹๋ฤg๛ otไรtึ�็ขYซท}�VิฌIc�Žฤ_hWชZ�ฌั5‘1€$Nถmฺ@Ÿ‹`*ส #9 e๋Wฏ TฉRษMณ๎ใฉ“&8•Fั๑๐ปฑ}หีl,uข็ๆ‡Žญคู Š`X๘‡สŸ—‰D˜NๆYyjN›ฝ€9.ห๚’€ี๗kก�็ —iฤX�๏=naบ,LŸฺœ1C:ฺ๊ก•LW๐}��wm^0๐ดƒ$ฬyฃˆุ ณ•uํ5ะ\ณ’z@€œพƒFˆ๛โญhˆL>๗y๛๖Ojู�รซ$H%�t�Wค„€๕๏9ร~ุ‘B๐๊'tnC‹๙’€E ,`Kš4 �พ}Wพ๓ฬ™:ึx๗1ใข๎Cgdคซ{Xตฅ?uv�โR.ๅ0๘�ทป฿{1าเ‰ฺฉ[_CrEž˜ฐ:ๆ …vฐ๙zB฿žโ=LฬPะpฟE�๐ O�-�wQ๎฿ศ`p(oถ Sf ๏O�๗+0h�ๆ-‹�›‰ะ๋7๏v–qhรลิz<—a ง bQ‘ก ;ถj,$šl฿๓บ๖้จ=์fjKWู~฿K+HeKฑ{ที ุสๅKRQํ™Bx�–"8�-จ/;ีฌ\ฮฎฎ/ ุ๏›ิฃ/5ํ้ํป๖ำบอ?xเx“‹{Qฉ\้\ฆx!yLชเk๑ฮ0kมr1xu›โŠ ศMิ4xธxbyYฝqปQดฉ6UภH +:‹๎l฿พŠs!?-"v็ส•หk/Xk;v์ ย…G7แ๙ X�‚“€E?fฮžC˜Žช ‚ˆ8ฆณb4Yy2!_�Hล5“#w~UM.1ต�๋ฌY่��{r๊ด"ุ9rุ*[ฆ”Qพwฟดj๕Zc+ hŠ.่”Œำ Ÿ9{–jืkจ'ษu/)SฆคหWฎุyx!^ะTฤฺฅK—ฉr๕Zm œU„y`ใ X3ITH$>๖ืญZ!๗ ร๊ตู๊๕!k–,”0a|๚EL/ัI'ย”๐ธqโุ•ทฺะู่ฒ Veฅ๙’€ล>๔>้๛tEพ{‚กท,ฎSสำ}AœTL„—ฒŠึฎ๚l&ษ“€1�^ฌางƒ"Oh๏�ฃด�ะฏˆโš#ข‡+�ล9 –ัA’ม๐›]ถT1๑‘˜Cิ}F+Vญ�D~ƒพ$` y‘z’๛ลx‰–(VH่น‰วNˆ้�gฮฐ�ysIMNฌรS^ฃ๐ย†ุฉVฑœ๐9s๎gAฐ ด 3{ญบ"o๑c&`oŠ๋ญ๏เ‘ฒ=�ษ“+ปะ- ฝฎO9G[~ฺeเŸC}i�ผ‘QVว๏uะอžํ+Iึ๎ุต~พpษ(‹O Xฝ]�ž3์วvำถด|ๅ:—ŒฅJ‘ไN๊”~œฝ…v้mแก ƒ~`�U(mšTt๕ฺ yฯˆ้ผ0๛ก๙ฉ4}Aภข]ๅ uDถ‡nkฆ/ำห)ต;๗๎'�๘ƒXมช 3‚:u๏'œ�IธVr‹g๖yฌ†~,ฆc:8 วVQดW\ะี�w๐mูถำทช!„พo�ึม#สฎ“bยKอ7ฆ]#๕šuาKิ\ึผ]ฌha7zค�ๅล‹ฉJ:ๆขd€'ถv�๊ั�๏%หU|ˆC2ษรSZ1ๅืสPงโทๅ ข��!`AD/YึŽุS๛ัฝIงฮ˜I'MUYN—cFงR%ญง๊™+้�]˜๎�M�šฏ X๓a๔„๙!1ๅ฿™y‚กท,๖ =�ญฺุ‘FV}jัฌ ตm�ฝ]V`ฐุั๗ญ�ัž}๛ํ๖้lc๊ไ T0>#ปo�A๔ใชีฦ6๎Es€.s 2_yฟbงๆsƒ}ฃบ™ Xh›3o^ฤn}`ฟ�Bb ’]ฺ:กฺฝWป4}ฃIร4k๎<#)คฐ�<—qฤ์„m�~2ŽW_มsฌf๕jvอteฝy.ข�~แaฯ}+๒๙สtOfคaเซjอ:RยF•ฑZโ/˜#/๔�f-[ำƒ‡๔$นŽฒุR†™ RๆNฎ@•๓๕˜‡‘Y๎ฺฦวท๎Š๒๐ิ‘ฅผอm„N~”!๘‹/ X์gอ๚อดfƒ๕oง๊>G ๊m็1tTL}Ÿ:sžAฎฉฒ๚็ท_๗N’ U้ฎศg,๊.X๒#ํุฝO5cน0ดOปภ` GเAซฆyZUi{์รT~O Xoฮ๚เ ‹๋ ๅt๒ uG ๊#ง๖b$}แ�ซ” �lๆ)็พ"`Ÿ‰มอ.=๛‹๗ํ_ใๆุFpša์฿›u^'ี์’อ™œuGฎ,Eม�†๗๚ะbพ$`qฬƒGŒฃหWฏ‡๒$ฌ3ำ๏QUƒ,{ูไง๔|gฺรฮXด/ะษำgปผf0HีW<;'Nจบ@Iภb'Jˆเ„๎ RmOˆ้SY๔สต๋4h๘8ฃZลrฅuำ–+-ผ_+Wะณƒm�,:_งฺท”'g6ใ8>~BƒF๚9ต^กฎฎ9Tผ)ผณ'ฮ˜/oฐ BzฌJiบแ๗0zดฯŒ$€Ebท๖-(‰v�ล "˜‡t_ฐh�ฌeใ๊นื๑ำๆŠูOQEZกs^ซjป๏l•‡ฅ~ฬIภยsตVฎ่ฦฎฟ�‡ฮ฿}K—E ช_?hซ"3f”O่X฿T’|4 ‹ฌ*0ไ†‘ิผ๐็T[ดN่ด๎ฝ�;�๒ิhƒMฤf๚๎W่ล๏�ศ๚ีsFงบนcPฒุ U]‚ †ศฏŸ7%Ё~๚๙ ๕[๛„~„จ2oX]็ํ5/‹j‹พ|!๚ฒ๓ยo4mืs:qำ6€X&๓g4งIbต� _ฒฌ—KRt› E?ฉž’ฐ ุ{๐˜�{มผ๎%ฬไ+4ฺส•๔Œ์๕๒T�Lภ&›n�ผ)ฝซะเๅห—)Ž๐(„๗%์ะกCิฅK:|๘ฐ�๖๔<[‡ f้]‹6๐"œ1cF๑จ[Pฐ๎4@Aฆ"บ๎ˆ~โC^sอ›5–ว๕พc�ภกร4aโหhี˜ช�พMk้๙ชฆL่๕Qwœ๐พ…ทชา๐ส&p\8o–^ฬๅ:7š}๒๔W: 0‚Uฉ`{—…nyง^ƒ2ฎV�+Aเช-•โsdAฺฒฒ1�žัˆM~ไฒUHlมซ"…ทoฃำฒ‡ดXhฌ๊ฆkฌZแาห–ศ•ถ��›L๒†€E“w�Jื=ั›wX‡�ภม^) ‚ุก@$0๋Jยzบ๋ะFพโธฬ,า,X@u๋ึล*ีฉS‡Ž9B]ปvฅๆอ›ห4�น$ฆI๎�นSฑK–,1า๕•jีชQ��๙ฉPกB’\ี๓ฬ๋[ทnฅ2e�ฆPฉ�ภ"`๑cงฟP[}ฉ>่K| \ฟ~]J1ฤS7ใว‹g7=D/ซฏC’เกะ2z๑๒ฅ๔ดIœ8ฑะฺ๕aิหZญใฅำ%ฬมผฌสZฅaJ้ํ�wค็ิ‹W/ลดง„”$IbJ–,™์U= „รญ[ท1๑†าฆMเ~่mšืA&`€ัฮ^ขะ›7o 2๐ฅ >ฒ ๅ‹™น-W� ]Iฆ+rUว*Oฟ†๐ฒแฌฯVuญาpไ+XิŽ [ฟf%ฅJ™ยชธeš'ZV๔g"ˆทป๗๎RLแก‹k�gมmฺ๊ธ)ดP๏�ฝKั?‹Fษ’'•(jษช�ธrๅชิสฤK|P›Y�เุแ�v๗คซ^nก‡๚เมJ*•G๗ฎูส�Iฟ๘ย#นŽ ฦ# ๛ ่s๛RฆIฺx4ห˜ JีG_<qN์ก8/QฃD•,ž�6เ๗๋‰๓เแI„ล�ำ฿2\๗๊๕ฉ ช๔๛-y๒V‡HตjTฃ�=ป�มนB๊๔น๓๔่ัS๑�!๔�’Šk?นxฑ'ฌ๚ฯสซ7ฤเฒธวำข��็ตี>œฅแ\]ำ€฿พ}'~ณ�ฆ;+ฏงC&เWAชฤ‹�นธ6jฟ๑‹)๖˜ ฯJฅ/ซ๗วู:|ฬฆำ๔ีฝณฒžฆล9ร>๐�ภ\ดฯข:ํH��w๏ ฯฐจ๔…xw๒ไšsฺ˜?3p�_บ|UศW=คpโ๚ฦต@ พภ6๗�„ฤว 96ปฤ๔y่6รt)[ฎ๓ฟxๆƒ(…้AƒœืX๔SA^"(’’9XKพฉ…ใพ"ž/7ลทศ}ั7ผ?ฆH‘Œาฅv�ฬ€Gฃซ{ำ7ฝ๓m+žฐพ�ฃอณ’aร†KฯลwาkvT๗พิ—UiX‚pm(<_ป—‹Cแ…WฌูเyฺํcZvไ%ฝ๋0€ล๖,lฐ FU>า@„ถ.�9•อ๒ พŽ$š+ผRK ๏TุJ4ซ๕ยr}Sวd”-Y$นŽ?Jทฤ๒๘:๖ฮ?kOพฆ๋Ÿะƒๅฑ"ฦฝฉFฮิปB\้ l—ฤLภ๚๐ภ"aC#๙ HญุTโc�ผ๐8ฤˆ#~0ปw๏N›6mข &8hทถkืŽ&N๔๓rิOศ�… ๊I–๋๘ฬ;78a…า ซ๏ƒื�[Tา๐�…9ำ� jDเ™ึป�@ปiั ตtัผ ๎ ๏/ˆธ)t(หV๐๓ํึต3ีฏ๋็์Š€ โฎzผ;G{๗๎ฝวๅวŽแ ฝเqๅ@(่)ป๖&อ๚บพฅo ๖rF€f๐mคkT๋ฃ‚นkผ๛€@pฐพ:lO X_ํ/4ทใ ˜ว๗ื?�ฃ_๎�)uY“~โG๗ฬ‰D<พู่oหฎลŒŽย ยำlw~�‹๎>�‹าฤ@q>๓ฌ]sžnฟ~+ฉฟว๑/}+%Ž๘ƒ‹ž๖ XO‘๒ œฏIุะJพ*+้}๚๔ก~�๚aU‹ศ‘#ล�ž}๛๖•มธ๏xฟ=}jํ ฯš—ยใS{A+›ฃ๔Œi“ลิง�ฦvPฏ@แปFMค-ะ๙sfP๖oพ ๊.๑�‚hC๋†็ๅ��eเl‡F6Cfk•:˜ส•-m•,i�U� -iLmืฆ5oฺ8Xฮ๏”`†ภฯ. o๖๋ด�เQ‚N/,ˆะฃK�ึU๎O0"ภl0‚„ปn6๕?ป+&`}|๊}Eย†f๒:#`1%qวŽT €Mr๑โลิฒeK9=2EŠ”Iƒ๚E่‹ย3ึ•�ฺU˜n๏ฬฮˆ(ๅy๓ๆ•dฎU&`ญPแด€"-�FMlx‘„ิมฝ;�ฯ�U€Iq4ัJ„เ!XpทA‚;wwwww9��!���เม�=@B๒��zู้�Yนฝป=ฅŠ›™ถ้y#;๓บ๚•.ญ_�๖KฝSโ๚ฏUทก]ีึญZP‹ฆM์า9!t"€ฉ์ะเฝ~�†<ภอ›PหfMๅzH$`ก้๛ื{[=IWgฎWฎ"‚zWE5๏K%`วอ๑ูs็IฌSฅLIฦ˜S๕๕$๓ฮF€๐%JcXUƒlัุแƒาlŒ€B mื~†ชJ )K๖€u๏Lม ~�ฐ~๎ๆR!&`เิ๙—„ ้ไ+ uFภ"/FŒดgฯ#ธั!Chะ A๔แรdปeะ M(ดศYhฤ�zฮŒ Xgศpzh@@'`แ๙Jฏ–อ(^ซ—nh8N>ฟ#ฐcงH 4ฒaaDPx‹ฒ,—/_A‰f;้,ธ!h"#ภ0Œภ—‹@�Ceะพ0aพก"๐e๓ฦ๕d@ถ/>rGด๊ิGhซใ(+DคฅHfํ}W฿HJ…ˆ๔@'?}๚—&Žเ–ธ‰เŒฐtvฬ$ฌ_wNˆแ—.V~ˆ�ฝ_›’zฎXtฆ6n�H3f”�{!‚พ@ซ๕‚Vyศ:๋ผ3๖๊ีซTผxqPษโ๑ๅฌ>ฐฮแ๔ะ‚}�ีW6pBหฑ๑q0Œ#ภ0Œ#ภ0_ z  ��/ฤzม~)็ษฏว ๏ืฐ"Rิศ!}�ฺื !0€'สฟ$lH%_ฉO,สDЉฆNJ5kZร ฐ#บžvsKD$O Šถ~�zช_ฟ>Aoฮ'cึ'„8Ÿ`F€`F€`F จ˜:k:๓… ๗-}#ˆบฏ„“[ศGฤ๋ฟ‚X�็๏”%Sjฺ Vศ?(>—0๋�g‚„�บ๋ฝžพฑH‚€,Z0wˆ๓|Uว�ขฟ�v/Zu๙๒ๅiไศ‘ Xุว :šฎLื€ฝw๏๕่ัƒ,XเชŠ‘%Jz๒๔™ฑอ+Œ#ภ0Œ#ภ0Œ#ภ0Œ@pDเ…@=x๘z�ๆMp์๗ษŸD‰™๚๕์@เ€ุB7Lภ†๎๓dG—'w.:v์˜�๛+คชWฏNMš4‘ับsไศแฒ.‚tAช`ๆฬ™’x๕~l๖์ูi๏พ�.�็LF€`F€`F€`F 8 ๐โลKšฟh9�ธ}‡�๚๋}p่๗มŸDˆ๐%NŸ๊ืชJัขE๕gk\=$ ภlH8K!ฐ๓ๆอฃฆMหžฯœ5‹๊ิฉ,๛ฦbF€`F€`F€`F€]0บฮgฐ:฿zมF็ณfอJ๛ Œ]๑>F€`F€`F€`F€`b–/‚Cเ๎�;TบT)บx๑b€ํร7 งJ•Š6nฺD๑ใ�๏๒M\–`F€`F€`F€`F€๐ Lภ๚-.๋k�ฟO ๆฯง1cFำ๕๋ื}]฿�ซ}๛Tงn]ƒ{yb�#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ# `V!มKF€`F€`F€`F€`F€`<Œฐ”›cF€`F€`F€`F€`F@!ภฌB‚—Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภx&`= (7ว0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ€B€ X…/F€`F€`F€`F€`F€๐0LภzPnŽ`F€`F€`F€`F€`…ฐ ^2Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#เa˜€๕0 �#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0 &`ผdF€`F€`F€`F€`Fภร0๋a@น9F€`F€`F€`F€`F€`Lภ*$xษ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ€‡`ึร€rsŒ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ(˜€UH๐’`F€`F€`F€`F€`#ภฌ‡ๅๆF€`F€`F€`F€`F€P0ซเ%#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0F€ Xสอ1Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ# `V!มKF€`F€`F€`F€`F€`<Œฐ”›cF€`F€`F€`F€`F@!ภฌB‚—Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภx&`= (7ว0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ€B ุฐัขFQ}ใ%#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0!—ฏ^ห�gH›ย_ว๑ี�„๙ง…ณฎส๊Lภ๚Eฎห0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0ม `GภฆI™48แร}aF€`F€`F€`F€`Fภฯ; &`�|.น"#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ3˜€ f'„ปร0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0ก&`Cฯนไ#aF€`F€`F€`F€``†ฐม์„pwF€`F€`F€`F€`F ๔ ภl่9—|$Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ฬ`6˜๎#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ„˜€ =็’„`F€`F€`F€`F€`‚Lภณย�aF€`F€`F€`F€`ะƒฐก็\๒‘0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ@0C€ ุ`vBธ;Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#z`6๔œK>F€`F€`F€`F€`F€f0ฬNw‡`F€`F€`F€`F€`BLภ†žsษGย0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0ม &`ƒู แ๎0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ@่A€ ุะs.๙HF€`F€`F€`F€`F ˜!ภl0;!�F€`F€`F€`F€`F€=0zฮ% #ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ3˜€ f'„ปร0Œ#ภ0Œ#ภ0Œ#ภ0Œ#ภ0ก&`Cฯนไ#aF€`F€`F€`F€``†ฐม์„„ฦ๎|๓๕ื๔ีW$�‹?A`�๛฿�่ฟ��๗฿Aฐw�%#ภ0Œ#ภ0Œ#ภ0Œ#ภ0Œภ—Œฐ_๒ูเc฿j!_ƒ†x5ˆุ +lŒ#ภ0Œ#ภ0Œ#ภ0Œ@ˆ@เอ›ท๔๛Šตt๋ฮ=z๗๎ฏัg๎คk"FŒ@‰ฤงjKS”(‘]ๆ�Pฐกโ4ฯƒ๓อื๔แรš5k;–ฎ_ฟ$Mš4)u่ะ4h@แร‡งO�ฒ'lœ�)#ภ0Œ#ภ0Œ#ภ0Œ€ฏ๘๋�{6f*ฝz�ฺW๕ธpศ@ j”(ิฅ]sŠแปัa๎ฅŸ`ึฯะqEW|-d๎฿ปKE‹ฅห—/ป*hyiาคกอ›7S�x๑„ปม๐ผ#F€`F€`F€`?!ฐp้j:v๒ŒŸ๊rฅ@ึฬ?SญชๅCFgน—~F€ X?Cว]!๏ื9rะฑcว\ ๔ผ�นsำ�ฝ{ู 6ะ‘็2Œ#ภ0Œ#ภ0Œ#ภ๘�ƒFา›ท๏|[ห‡ "GŠH{u A=ๆฎ๚&`�‚ื๑9ณgQ๓ๆอ},fฯžMตjื Š]๓>F€`F€`F€`ทhืญฟ�eน`ศE`ฌw฿�y๎น[0๋L\ศทไห›‡Ž9โ�jฒ�O?�D คŒ3Rโฤ‰)jิจ๔•ˆ่๕๊ี+บ}๛69s†๖์ูCงN๒S๛ูณgงฝ๛๖๛ฉ.WbF€`F€`F€` &` ้ �ฐA‹`์ ุภ@๙ �Gฬ?ะk_ˆ„GЉš4i"�งNฺ-ฤn�ธA3gฮคฉSงา‹/�ชƒBQ„ศ๕“งฯ�.ฯƒ๏�๚‹p�ำ ฒž`F€`F€`ะŠฐก๕ฬฺฐถx„ฦ-&`CใY ว๔mธฐn๕žญ5ขAƒQฌXฑ�ชc.๔๒ๅK0`M˜0��๗_sถรํ�ใ0�†ภ��๗?z๓ๆญ ท#๛ญ_ิ:t๘(5mแ%ฯuย„ hรš•๔อ7฿๘ข…ภ-:aโz๒์ฉ�iล๒e)ใฯ?nhogฮžฅซึศึฟขฏจ[—Ž๔�wก;r'ˆ�ฐaรR8๑? ์ํปw��o)L˜0m~๐๘฿ถ}‡l3Nฌุิส+xศรผณFokๅŠๅ)C๚๔ฦ๖คฉำ่ัฃวr;kๆฬTฆL)#WBgฯฃฅหWสNG๘.uํ�!X?ท=…๎?Ÿ>ั๔9 ่แฃ'TปZ%J•"™ั๔บM[ezœุ1ฉL‰ขF๚ƒ‡h๖�฿ๅณฆIƒฺ๔}ดจF^h]๙๏ฟ�hใึt�๚Mz๛๎=%ˆ—๊ิจZ—+!เ์>E‡hส๛๗ฤ{^xc�S+ีฎง๚\ฺa6ธœ‰€ํฐ‹oph ุเpBa�!`cฤˆA , bลŠyP๕๊ี้�ฝ{>ถ็ ถkฯ�๔ฯ?พ'r๘>:๕์�ลว>๗—.]ฆ๑'ำ๙ …Gฑ…`+VLส+'ต๖jA1ล9๖ด5lาŒฑw›@�บu›��๛oyx๐ุO•2%uhืสว๓้ ?า�฿J"๛�ฝ๛ฦR4!ป’:uJj�ฺ‹~ฮมU>ๆ={๖œ +i๔ฝ}�VิคQC๋F{๗๏S‘โฅ]๕ํ�ƒชUฑ’.ูrๅฃทo฿ส�_ ค๑cFey%d!๐๚๕สWจˆqb eณฆAr#วMฆg/^บต๏Ÿำ�Dี+—sซฌฃBซึmคUk7ษฌจb€rยจ!FฑVบำk1p1bš2v˜‘�o๐Hบ~๓–�ฮ’)ตmูฤศ +/^พข.ฝž‡สพ ŽfL ๗๛ส5ุ่)kไ๒ZU+Qบดฉิกฺ,‡ŒOo�Yžy6ฆดฉR~1๕่ Sล ๖s–M V&ˆ—าฆJAyrewX& �วฝ฿ภh�ฃx็™9w!;‘@’ยู๖]๘๐ย™ 5ฎ_‹ย๚aภS -งฃ'Nา_ฝ7%|๘o)Cบดิธ^-ย:›-Lภฺโญ<9ณR™โ…้๋ฏฟข-;๖า๖�์ QJ�cSฒฤ ๅ�?|�›Žด�ธ๊ฐฎะ yLภ†Ž๓์Žย'6iาคดy๓fI แžฐj‰ƒQ๋jฉง้ซ็#ไkษ’%้œ๐ถqež `ำfศ์jN๓"D๘ŽŽšˆน๓ะ…‹—d฿R$Oๆ'"คTงn=hห–mNQetํา‘๊ีฎฅ6=ฒ>r แ8”m^ฟ†เ ซl๏พด~ใFน๙๕ื฿๗เ*+ะ—ซืฌฃฝ-b๊ งฯœ8"^พvูf-[ัพ�]–Q™+”ฃ๎];SฤT’G–๎`ฺ ุ�ท๏P๚ŒมgภVฎT๔ํํ,�i:<ˆ5ma๓๑แจpฑ"…i๔ศแ๒้(฿งด&อZาC‡e1 ˆ์ุบัใถ>๕มY>ฐฮ y้ฝ๛ 0ดbEŠPแB์bษฒๅิ •€\ทz%Kšฤฎ\@'4๖๊ ˆ`๗O%ŒO{w๕s—\ฐญ;๖ W‚˜�า ุมรวาๅซื Œแ๑›(A|๊ะฦ๊ฉฟlๅ:๚๓๚ Š!ไญšา'คุ›ทฉ๏เ6�ญYญ"�ต Mšฺจ�คตZuนฤ‡ฝ๗€^.ห„–Lw๏ืhQฃP—v^_xO{ส?yJณๆ-’อU([‚RงLaืดณ๛ุฎ`Kธzํ:a@ภีฬB ” ะ“b�เ�เ;<�{ ๐,Ÿœ"๒อ7_SŸn)ษg๒สiม/,ร6ฑ๘อส”มน<fr=z�”ฎ‰gำ�ท๏B<‚ร๛w“ฟก8 t่1(ุSJe$AŒa–G๋.��๊ฐ˜๎>�‡๚ฎzDแร}M+ฦฆ่ฟ1๐ฑ๑)��้”/uDส›าณ฿ภฦNp… ุ๗Knฺ?~|ฺฟฟ อ,ฃBžฦ้ษ“'”/_>บ|๙ฒำฆฟTถRตštQฐ)’ำšKbไ,ฃgŸ~ดj๕Zgูv้ฃ‡{S๑โEํา�š๐BHNLœ4…ฮ�qชWญL !u=f<อœ3ืH:ๆ„Ÿษ+ฃ?ฎดi฿‘ถ๏ุ%k็้ฆL๏cKพ!`ัXา$‰iํชๅ>ป>๎X+เ†ก™€ล j™rล๔เว*ฮW๛๕๎IUซTr^ภ”๓P|€)Qฺ๎รƒ3บ7ˆชVทvM!๑ะImบฝผx๑"Uชf%+z๕่J5ซWsป~@d6 ผ๖๕ษ๕๊R็Žํ์v�Ix=�’#แ[จ@>š8~ฌ]น€Nะ (‘#น�]†๔?QS!เWƒง<ศ‹�๊Uส�H8#n@Pฬ�mษg ‚ZU่ึ‡fkาช“A�O5ุแ๑ถ๏ฺ‡ž=!ฝโฆObเP็X๏ฐ3�ะ๐ฆ„ม๛ไ–3K:y5iเ,;Tฅ๋๗+HVepภx๛๎/›฿QwใG ฆศ>�ืช Ÿ–'NŸฅq“fศbธK-lWEc๓@Š]ม”๐แรGยqะ‚แ9™ํ—ฬ๔�๗Q้ึํปt์ฤiร1?F ํ'หน๓งY๋ฮ๔�รY4œซห›+ล‹Gสฑ์;pุศ๛Vศ1M9˜=a5P�!`K+D%Šะj9^�$œi๖8B+ึnv\ „คŽุ"|–?รภj๛ƒMฯ’€}๛๑?ช=๕Žธํ7์7Dฉ~ O„งL‰ยSŠุ฿Š๏`๛rม=ฅๆิ�ด๓‚e vฎh4ฒ๚F—ใดน(ื+gJ๋xnะอุAฏ0€?œ4‹L™EฑjWฃx�ฺ๚jOทzค็k6Q๔๒%)ั 7สํŒ€ล*ศื,Yฒx €ผห/†)ช˜บ๖ร?ีฏ\นBูฒes3+@@IDATฬ์ค)ำ์Fpฯž;k3=พpกยร'™ั/ฌD™๐ๆ_๖มƒ‡r:ณ�๗๚u๋Pม‚๙(mš4t์๘ ฺธi3ญ฿ฐษ(โฎ็งQมŸ+๎‡��…[ี๑q)kNƒlุฏ7UชXมวบfVษU ฝงOŸำ‰“งฤ�“6ํxzZน;†fv๚ฬY4v�$c่’6iิ€๒ไฮI—ลณe™_Xฑrต‘้H0ธk#Fฅ9๓ๆลั~๗ฎฅ�žg7mก~๙X9-ผง}ซ=�ฑKwฺดy‹ัฮแ�{Eงูุก+Lภ๚Pสv‡€ลแ@ถฯe๛vmฟ�๎{Oฉz�Y*B'จ “ะH�๘ๅผ(ฏฯุBพhฤเ>›‰์ผ…Kiว๎}๒x~ˆ�ฝ$ฑแŒ€ฝ|๕O<|œ,๏฿Œ‚�g#๒้~ฝ&ฒŽ8Cz“ฏdIS฿=�—Jภ๊ื๎OiRQืญl๐ฤ`Hง�๙�ŸLุซ %Jd‰fSX�8*ˆ�‰Sgษ”ศ‘"าxAฐโA�sั๎๑ฎ ซWซ*.We๑KOฐ ฬ3\ค้sW›!nY Oƒp�น๗ ”!.์รWŸ(c๏ซnjœจahAำ”^ฒa? W๏�ฃข?Eข*ูขzlLภ๚ ๅWโก้€ƒ๗นข*q๖‚ๅ"J“2ฉJ ๑หS้rวเ"U‘ฏชrฆ?ชีณtFภŽ1‚:vด}1*Zด(ํ�น“๒ๆอK:uขRฅJนuœปvํขแร‡ำŽ;(]บttาDJอ›74p์!เ ึQ'WŠ Dฝ๚๖7ฒฆMžHy๓Xฏ#C[ทผu! ๐฿�ฃ4B๛1eŠ”‚จ๕™พ ๔Wฏ฿ธIw…๔`ล‹2‰ Oๆ`Xะ�๔๏'jะจ�ผuK๎ำ๖็อถŒ์‡�6ผ[๛i๒HYnฉvอjำXz)ด--ำถธ๔๗”๎'หวผ�ž?ทผ\…„|๒d๖๗<4eŸ<~"� 'ผ@’ นe๐€}$ฺ€a:สฯSย 1๘�ร{š๘ฅK—่ช˜Z?~–A4่eึ�“ณ,–•œฐป๗0สŒาืW็า�่๊^ปqK\—แฅœBชนsฟพz�šฺv๎-ง๙โ8็ฯ˜เ‘ร๕‹๛๋ร‡ฟ…lA2้อ๎N‡๐)}�ๆMิ๖/Q/นŸผ?qํ=๏)ล{3HNฟX็žฤ4uห;๘œฉcํ~‡ะๆ แูUXฅ๒ฅจ\)๋o€Lt๐gสฬyt่ศq™ำฐNuฟ!ท]ฉs็/ัˆฑ–๐_„v›–M์ส|ฉ ~!`/_ฝNOa�• “ขฒบอZฐ”Nž๙COโu Xlุoพ"ฌส^๘—^�eQiX6-ˆฉ�žถ�Z�๑K�™f6Š๏ฑๆ!Aะอc๚.�Wิฟ|l๚^“ `X ฬLภ:ธ�๎zฅ'ฟYงxปCยšษื่ๅJPขมฝดผ“ฐŠ$5“!๐|UVpTส•V6'Nœ bdฒx)‰-š$t2 โมƒดbล �˜ผ/`#Z_6Pง@ดoŸลม(,V‚‹๐ัc'ุ่™๊}ฌUฃ:u๎ิ�!๑ T 1ศTฝ>ุซVฎ(ตAึ้3eต™ฆฅ—ว:����\sฒ�ถ™Xล๔QL#5Hภ‰“งษ5ซU็ิ๒ำฎCgฺ๚9"ปN…ลสภมC้๗%หdŽ็�ฉcF๖ไiำ…มTc๛๔๑รโ#)™ƒsด3™นaใf๊&‚ฉ9าธBฐฌฑฃ‡๛9ุธ “hฺ หH|A๘l�ดN๋‰๓UwXิฎSฟฑ'์ัC๛(’ธ�อนƒ๚๗ต“ipT�ะพ�ิพSgnGฝTš XxฒyIภิl&ีดqCป—>”ืบ]G9ˆ`ฎ‡s฿ปG7‡ำ๛uื`ำ&ฤ5ะ�n ?ฐŸ4~Œ “››wบ�พsWz๚ฤBN็ำใš7mlWึ|?wMะN๐:ำ„6ๆฬœ>…rๅศnืg ป๖์%ฏึํŒlxRใ™ข›N๒ขG์uช๏�ฟO/ช"ž+บ/ZขŒ‘ไHŠ„aV1ํ\Yป6ธษอภ$`uอ�=ป‰฿–[๔�"ซืG้R%h๘P a‚ฮ๙็ู๐๛’ฅโๆญูX‚˜ุฏeศœอxๆดiีาธพ–‰`o} 2สoูธNDƒglceวฮ�โ~้`ค้ƒ[*๑น๘อ์ิฅ›ร{๗ฮSฅŠๅUq›ๅย฿ำ˜q์๎#ย๓บc๛6F ดK—.Sลช๖pzƒ^-›‘W๓fF~—๕ใO“&5ญXbฌ3 เŠ;„Žฃ�ฃ๏3็-<วŒ๓งสdซ]ฝๅอC%ษ%ศQฏฯำส๓ๅษ)‚หิ4๒ฐท๎ ลหVหr]ฺท26AฒS�2ža/_พ�>ปษ๓ัhƒ’eKฅŠๅJi๚ ˆ*่:Bๆ@�Ÿ0ธ]ซฆดnใVI m�๔๑ชˆ[K๔e๕บอr Oฏ€iแ…๓็•žŸJมH&L™ฉณYW�ฐ šทX�Hข0ศั™“F�ิ{.‚ซ 3Iฮ—2 ~”.Q„*”)ฉ’Œeฏร่ถ ŒARvh�L๔kฝ�<ธ‡พฯ™j๑J5*ธฑาฑ;ผ๘,ฟ!�:ถ–ƒ! ฌ`ฮุฅ+ึา๚อ�d`o&Id† 9ผ~ำ6ปูY๘mชYฅๅฬ�‹-ฟlw๏ื�CF า๙ฆ<ๅ‘y๚์yB/XZแ�€sแศ ๙ฑsฯ~™UซzE10๙”ถ๏ฒ j;*_กlIq-•Y๚}<|`o %C‚๏(ŒๅงัYq_ฐ_ข?}ณXใ|K‘พ๕a๖์๛IวตG้กุ_’แ(A๔ฐมF —5`œTO'ูซHXป2!˜|~f6QขDrJฒฃ—วธqใาร‡�๛wB€๛ฅ˜šŽ—ณeไา้ำ–—2•ิ์˜qiฦฌูช;bค0UจP–ยˆฤeหWูxš=ˆŠ—.'ผ5๎uแU•=kVบ+ฆั.^ผฬ˜Š๋ืฌ”AšZตi'Fึ฿า้3gŒœ‹ŒBฎ†ฉฅะ๕ษN kีmhS ไS๙ฒe่W1J�s†๔>๊EภNš:>Fืฎ]#šฏŒ>ย“?๘u1mฒL?r๔5hl%@ดึซS[ุท�Sุ•น๋ฌสc‰๐œy I๓ๆฬ ฌš๎ฑ‘แ`ลLผ)SsQณพ็†ตซ(IโDฒผAŽมpžO;d3uุ์E7d`*_ฎ ๙C3+w&�@j"Rคt๒ิฃสซR๙ 1ฎGิ1–Mเt๗�]ฺท� jR.แ’L™Nภช4hฑฆƒวNœดู7๒ษeจบ๎,1%}๏พ�ดxษR1u�ฐQล‘็ง‘้`ๅฉ๐Œ๚ตx)ฃภฆBนฒTดศฏtOœทBสDTจาž“พ1�หืภก!ซ^|U;:ซาฐก+F )%กฯN@�ๆ๕kDลX•ืXH๔€•��า')T0ฟ tๆŸgร5A\•)odT๛๙Ÿ๑็ tOฬฺ9j6Oฐบg8๖•#{Vส—7๔–œ;qอ!oแ�ู„็# ^ณy๒–๋๘ƒkฒvอ๊B�;ต xoaE+ฏmh‚w้�Kึัuฉqฬษ’%“้ตjTฃโลl? อำ+–,ื\Y>0�ธK่่}ูบc7�ถx…LQYชุฏโผฆฟล๗้€๘�น๒yฐอLุน"`p ›f-ZภsFภข#x––(Rˆฒ�’Q >}ž[)k๙(Eศž๏ฤteบ๕%z0xฦU,[Rƒ\๖ฉtUyw ุปBชคgฟกQZ on๚E|ศ‚่๑x๒๔9#ฏWืvrj4฿o�ฒ|๘f!ลโ ฉ"f ืไ ƒ๑๑Ÿฟฅฦ็�w๏ฤ;^C2B๘๏Œˆ๗po*‚๛@Vขว๗C๔ht์ไiแ™ปI\ฟโkL˜YWRฐ2S�ม๙((ށ`นsf“Kw�@~กMงr_่๋dAฌ#˜–;์@๏1„i๋pJจPถ„ qื}V๛†ฮf—v^vSหQ๕aุ/H+x\ใ]žœYf9๒Vmืฅป๗koแษŒk6D•๑ใ�(ืแ OXX[ฏ&”%cนฎ�ภSห0เ ๏Yœวโป$ฯส5dฎ๋<น,^x๑ใล5H&uหBhCHฆล Ÿฅb0E zภน…๐HUv็ฮ=๊9ภ[mJR2ฟุ‚^ ท์0d๒็อI๊ZI(€EธงซT(CฉลlŸ๛ยร}ัา•) ต1รศu��A`ฎISg<`qลoจ๗€žn7�บSOƒคฮš๙gj$ศrQย3a�ขeดwฟลปื*๎™฿[��Q(,่)ฤj—ถึo ;ยุ๋{ฌลSžŸƒzu4ฎog0šษNxสขMg็ Aฟ๐ซ,ฐ Xต_}ฉุŽญK๏W=ฯผŽ๋พฯ1า“Wๅ9์Ž%‹�ๅrฎ<ด�>6ฮUŽmืํำท฿Sใู๗S�uƒผมŒ†๑(k’F๒ล{จเฐฦถyฅpฺHดฐนๅ[yโ'š†ฌ{B3๗<ฃ๗�ˆ อbD๚†FึˆKลำGาR‰–yEm�—i;&ฆฬ‰,�ฬHpEภ�~๖uบด{.ฟณicฌีฒGฃA•โP!k”ฦl กoGฐj$ฌ]^'_ฉ™€ําฅ y{[_2์๘Y€บ๎ส๓อ็„7ศ\ณ5Š:w๎l“”,ด7uฝ•rๆฐโnd8Y'h—๎–Rœ?฿xxนCภBwฑP‘!‚}œ=yิ8NH@Aูœ™ำ({ถฌj“บ ู…u๋6�ว๏งˆฌ?ฌ๎`h&`Aุ,]ดภะไกSผT9y‘m›ืืด’1อ^ด„A’*;vโีkะDmส๋�ž†ซ™€-๚ka9|จผ a9qโš9gฎQฟTษโ4ย{ˆฑํ›™…žง" T]sงm๊ ซ2ฮ–ภgภภ!†‡ณr5ชUธtฑตwVVOฯ_จจ1ใLรซ๋VC ถm๛N6Zทล™6f„ล[/คzภง�9sะ0๏ม†�ชยฮ?ฯ tํ�ฝW5EลŠฆร,ื$อฺอH๓$ i<_•™๕UอฤชT)iีฒลฒธyfE฿�= ฉุผem๕6\ด`.ลŽKํŠt‰™์�ฑ‘g^Yท~#uํa!n‘‡™… ภj ˜"t@Tีำฒž‰jส๖์๙‹ลฦsRGฏu‹F”"YR›jJฃ‰C๚v7ˆAWฌ๒œ๓+�ทGแu–ฤฆj:=๕)พG„gๅ$แa รqŒaฃ[Ÿ#ฤ๔า�F’ป,ผฺ-[%๋)”OH 3ฺภสิY๓ฅlึK๛•ชW.‡Uร<ก๛๛าUดi�Nู&Hึ-lec@๗่ky�ƒเœ1qคฑ€๛clA&YฏMฃ›+ “฿ฌaƒผu‡€ีu7]ํฟ๗ร๖ฒัˆ�ํ๗ๅดu็YญYรบbฟึ฿{$Nš1‡.|žš๋-ฆษ๛UิUฟ*O�ฏๆ๛D฿ŸNdb๐A—ฯธ!4ณ๛ถœox่uุ๋FฏJบ�ศQuฯฃo4`Q>Cบดาk๋ส๔�-*a•™้ึg�Sœaบฌช ฯ;”yƒใ?rE�ฐX'`๑,3{ืโ}ฅi๋N†…ป๗ณฺทZb฿>A{xทBฌeภณu๓ฦrะBฅ๙ดั ™Eเ:*อŽmZH2�Q�—šๆ)ถVี๒„้๙ส๔@\ตช”ฃ\ูณจ,้๕yBx�O�+(pn”-\บš=)7[6ฎc#k๐๘–=s๎"�+ค า‹ู ูu *๖ฑpy๔๘ฉ�–˜ฟxฅ๘-OB๕kZฮ1(Š`^0H0@Z@คๆ�nˆ‰�นMSใป e๎‰๏สgฯ^Š๛แ;๑�œHU“ห &`/ยดะgย4y์pดฟงe\urฺ๎็ิwฅๅYคาฬห�bQณ‚?ศไsw>P‘ฮ ุ�ฉ"าฏ„Fm‘บTชฎlZ�xT.ณ๕๚Zt่%u๘�ฌฒฎ}"ุ ’นฐ8NH083�ฎnI ฺนAeLภ"๒vDซ a1$๐|อ&ฃ!U๓ี8€ฯ+fณ๒็ฯo.F-Zด iำฆูฅ๛%๒90�yL'ฝ˜šญ[Pฐ พ@€)ำ=สTšูำำรAิโrส0ย>}สD1E>นJrน๔‹@1บvง�,?PฎvXผxQ้นง“{AMภ‚ผ9ฅLMงU�Xโ%3Kถ\แึขij�ช…^ฤๅ:4DทยขGy�บฌ๔9ำLภ�q๚ธฬ‡<5N‹Wƒผ‡ฬižข �BEŠn‘จ†ะเ…๎ฅ2gRžๆบ(ใ„ ˆ�ฬ$ซฎcšงภฏฦ1€?ดo๔�qU_ŸFo&`อฌ@6ๅ+d๕ผK+<์– O;ฟX้reฐ;s]บujีฐ �d.็h1sษฟ๐๗%ฦuf.Oำ& 8ี๋4—ืท3�’ร๐v„W2dฬf&`อ$8สใ:ษ™ท ัGxฆBฐJภโv๏ุb'โ฿gร/9r2 ็๎�e่IภฤHn@zC™' X ๚(ฬL8ผท7สค)ำ�•ฉชฃวŽS�FMU2ๅ^ณƒ๔ฃฤTpwฬ7,ผ�๑œS6ฐ_oq;'BU9O-กใS{foVWๅืlุL+VoE ๓ ๏CX@ฐ๑…^ˆ^ณ้œ Q R6zผ๐�์ฑฆ๗Oฏ๏Xxษ*๓+aฃ๊ซ%"ฆƒ †ฉ)๙*KOฐm;๗’�~๐พš5yดร+๏Q„Gในkศ@ๆฆฐร๕‘jd†/�่zฃ ฤว๙เ>ึ฿\wุํบฺ[@”=kAB%็๎้‹AxุBฃ$ฌฒฅย[ฺฏ0GQ๋UนธT๗ซ#^iฟXพjฝแeš9czj็e}–แ˜[ถ๋F๐ ym–!P!๐lŸ=ล:ศ„zพ%`งaใuŽ6`^ํปIฏZ๓>ิตw จŽL\U]s+Yดฐ,ฆฐHCžูFŽ›,dS,ฮ~ ์Œ›xu47-�Š ฉgzำv>'�%$ฐฆ ‚3็.ž๑ๆฒ้าฆฆ†uk๗จ9�K�๖ ปmื~Ck5vฌ’TฤRท‹Wัa1H๏ื‘{๏ f9€XB+ผoทถFU%]�ืa�บ้๐v3i–ิ‹E"<ฐAV๊?AAภฎ�ฐ•€‡n�ฺท:ท*m๐จIฦ า†๔้,="หlDญSญๅศšIUฃณ็/ัด9‹ŒํŠeŠ ํ๓\ฦถ^ืHtฒ2ึ�๚;์ค๙F‚@ต‘ขหez๓แ?‚ มQฉU2�z๚e๐ง�ใ<ิชp ชœอB„.:๔ŠฆํzfไB�ย„’ห>ศtE์fO†V‰-ำbDCฑข„‘๋+ฟฆ–๓๏ษ๕ˆBn [้˜”/eDบ๒่oZu�m<๛Fๆ}ๆ+บ5ฺฺ/ฟฐฅว�ขใ7,ƒDe2EกyฃQ๚๘฿ั๎K๏จ๗Ї7์lxต8T7๗๗rฟA๑‡ ุ@F�Lย๊ป-ไ+ŽI'`๑B�JLƒาdก $~�๑Gcสา�cF4{ศ่†‡ผคKYPฐf๙reKซnKผ๐l�ผีุะท7Uฎd๙@-Wฉช�Tึฤโ˜แก‰i๎9rf—ำ๗ŒสฺŠ'Xี�ฑใวiูŠUดu�ƒ่Qy๚าL�5k&€Y\1uฦl 2”ว#<ูฦŒa.โt['bผN+Š 3๋ช,๒@๔l฿ผbˆ#�*WซexQวำษ๗ T˜Yทq์่๏Q��Bภ:า15‚‚ท6ผถแๅ@<สส”)EรT›ฦา<|ไฐ!Tฒ„…Xึ XL#฿ฑeฃQOญ่R 7Xทา~€F•uตก~๒ฤ)z�แƒA\๋ๅ}Kะ_ธp‘jึm`s฿เร0ž˜ึ๘ZศWุ่H๒ษฦ9$๔~่๋:!ๆˆdGY3ปvีrJn๒์C9}ฺฑs7VฅaPฯ๕Jภ:ป��๓l€ท0Hoeฮ<ฎกŒสž -iศ AŠš4nhœ‡+‚ศiำก“ึ3‚_!–ปฆb… Y๒้๕อ,ค2@�™ ๗€Oศn�!•€uF๚็ูp�ฦM‚งดฒๆMKyตญ–fญUOฐ๚ภฺŸOหู3ฆIX”3หŠ˜๋ยKซตW ชQฝšqญช2๚๕ๆ _Uืw๙สีิ&uh฿†7จol๔Š"t@ึ uก]'rd๋‡Hด%+ึHBัUƒ€…็YmS-๔Iิฅฐ-ฺ ๏สฟ�’ณ ๔ภUๆใภTmL™†๙†€้ OฝGŸ8๕jC›Aภb –|cIจ�™จUฌ3ย�vu‚ฯันq‡€‰๚�ใ๑มY๊j:ฺ/ขำฏZปIf™ฝ๘k�ๆmv๘ใ=A�ีซ%ขฺ�ิ:ฺวœ‹] rTว/i๎�๊~๕i8ฦv^อz ‚(‚V+,Mชิฝ“…่ืๅ๚๗์LI'ดูoXGบช1ใ8ฟธTฌ~M”.Q„ชV,ซŠ�,1eฟQห2-ฉะ๙๏ืำญ@ชDyp#ะ.™อLภšต€U๙มC‡ ฉ„ลjSzSรซ:ดฐ�y6˜ฑะอ เฤŠYๆภท์๖ปจM{๋tP�๓\—ม>�๙m™4aŒˆ uเ:uฺ ก๛{ภธ~ฎf\ฌ[ฝ�ฦ#�7,fOิkุิhฒWฎTSบeŠะqE˜˜๛r ชt™’žoŸ>�+=ไ‘๏.ซ‚๗˜๛แN.G$๖ํŒ€Uo|"ป๕žฒ๗-B๎ฐะ †๙†€…6๋ล{้๑›O๔โ�ฟ๔��':v�=ญ?c‘! "ๆถš๐pีƒoๅNjๆˆFฟ�™ขFฐ�]6 V˜€ dะ‘ฏช ัC ซฐy๒ไกฝ{๗ชร4–K–,ก5j�žX™0ayyYGุT›+VคีซWซM๑"๐ฑ๎ษ‚๎ฅ2= J?q2Mnกฆ๓ช|฿.�ผvŽŸ8Aปv๏ฑ‹_ตr%๊ืว:ลหฟ,ฆ„c6,ž€็ก#3kุ"7<ญ`:k&WU[บ—ฐนŒ ุใ'NR�ีฎ่ทyณ(s&หTD#ั+:1XซFuู๊ฝ‹ฏZ3ฐฮZ=ท}ี(�คYK�๘ฐฌ†ฉฤ“'Žต‰t>}๊$ี7ง]ณMภย;�งŸณ๛…คฬๆLยๅtœ=้๛�๙sฺ+ศ'eyr็ฒ“wPy:้RjใบU*ห้า|�Ž9œŠ�ีa๙’e*ะอ[ทŒผ3'Žฺ้ไ™ฆ•\BทUI$M’˜ึฏYi*a/A “yzasเ=uMšIGGžŒf/ๆvmผจiใFฒ๙{๗๏S‘โึ้ยๆภO:ก่.มญ๗[_ืฯ•3M�<@v๋๚�… ไฃ‰ใํ="ฬ2ฎุKQš4ฉ๕ร ณ—ฎ~ฮ0ญ* ๗๛โ…๓l๊๚fำ@/\ผ@xๆoฺฒ.‹h�บ™ฅK�มWี7#ำgHจ2นT„Ž™๘tตฯzM�ž…ู„—Pัย๙ \ส๖์;Dณ๑s—€UไนAภ๖žญื?{ถN;ฬ๘pT�Wหfญ;ฟ๑๎ฐz๐(hำ–�ฅYณd”�hž๕›ต•ป ร๗ 9ศ‘�ฉ�Kภž�ใ7ล‡ฝุg๋�ภฺ่›ฒ‚�Eั<ฏ๕š๐4๎;ุ๒[้(เ“^๖๙‹—ด_ฬHฺถsฏแฉˆ|hำBฃ6ค˜_๎WGวถuวn๚m๑ ™‚„๑ใQว๎�ไถ๎-ฎืu‡€uv๋ํ8"`�"AKHJ4oTW6ญ{ทzฺV‘๗`ยu๊ฬtขา ฎ? ฟ fค3 กแฬฆฯ๙๖ด8๎8ำฌvV74ง๛…€๕3Eา.อ๊ืƒ`ึwŠณ�Rmส}ฆ ?Qใบึมะ?.^กใ"—3รŒฎSgฯ ๙‹tิจNUฃุr�f—๘Mิ-EฒฤิฎEC#ษ ๏v�ๅฐb–/˜4sะ๓พ*หtj�ฤ”uGศ|เx•M9@ญ’#šทฃ๗2สเ™นvำc�ัสู๓…tโ฿ิณ“ลZ�ฐ7o฿Q7AD› ว‹ใ†6S๏ซ๔เี'‚’หฝฑฑ๐Œ๕๏—œโGทzฎปCภb?ะ`แ๋ส�Kภ>}๛/U‹ŒหlqฟKฝสฤขŠฟD1g๚6ฐน™|…์ฬ&W(!auำ�=j‡๔พ}๛ๆฒ+่‹„•+WR๙๒ๅํj”,YRhชn6าƒ’€…ถ(‚ฅ(sF‚=zmˆ ๛�๛๏eไb|`|๘h}จ่มญPฮLv�œ!���\dIำ X฿zิกู8ม63บ†ช90“šฮl้!ษˆญ๙E๐$E๙—€…๖)๚ช บy Z /gd ˆ8 €Eฃ๕ัล9๐ษฬ^ง๚๔^Ÿ๊ช|OฐfขฃGทฮ4ฤ�๒๑†ฉๆ'…�€ฃ—k3kฦ}๕,๊#HผQ`8ว‡D`'xD๋fฦb�๊”,iY$ Xณื-‚ฏA"มlธ? +i$;"`๑ยeฦw๎�4|ไฃž#า™จ›-W^w฿ฐ:y ฏ้ใ‡ญคฒฺนูถXฑ"4f„ํKไร‡จPQหo๊แ^RzยธGA๔*sT฿Lgึฟฯ�๙L๖๏ูa๗�0_ำ: �๏]บ)8eรJmฯ๔ม)ิ ุn=๛ะฺu๋e}�S๛„วดู L=2๖'vl‚ืโร๖ต˜ป๕)b๑๊5๋จG๏พF=ฏ–อศซy3c['`K—*Aร‡6๒ฬ+ณ€ฌ…2wๅ;Ty�.}K่่D ๔ว ณ~ิฉพฬ˜ป0ฅ ุs�;"๛็L?๖ศฑ“4i๚Y�%`๙‰w๚๎ป๐FX9'‚“Œ;Iฆ๙—€uฆณูฆSOฉฟ‡>L7ฬ.โถM‡Lม€Eด๛.ฝ,ืUŠdIฉwท๖ฆ^Z6Wฏ฿L+ืXฆั๊Aึึ‡ŽO/[ x�–/]\ห �ซพฝ_ ~Sกณ‹%dโB;~๗>Y|โ่กIo€u†›_ X์X้ใ7ฺYฎฉณๆำมรวd?แ๒$ซ๋VCึก{'หเ‰์€้ n†dgศTH›@โน๔ู™้มรเฑ ฯm6แภาญฟ0”.VˆJ)`”ำ ุ8ฑcJ๕^ gˆั"X๔Qaศ๏�ู๊Uๅฺ 7ล๚› U๚ึ ๊฿ ๒1ˆฃ`Vสn฿ฝOรฦNU›rู V๚%Sz#M'`ืญN™2ค5๒&ฯ๚ฮ ๒WtiกOซฬS,ฺC๐0Hภ๐}�ฑง�ป ผw๑NSณ9Z4ชM้าค”i๘ƒ\ฤฅ ๕หึx๎ด๎าOeป\Dฎ��’tบ$’…fkิ0tj` ู‡M"Vƒ™wๅ:‚`E>ูถ.Imฆ๖๛DภN��œ๚ฎดพwข�ฐ฿|Eพ�JH|C��@œย�KภสFฤŸ]"่ึ ต้ยฝ๒˜U:–qฤ๑oํœฤฆ็ึ:ฐ„ด#๒5ัเ�r๏vyก€„ี ุ๘๑ใ bะ๒pืแ~#4ฤ๓๊ฃOฯ๓๋:๖ƒ�™-sๆฬt๚๔i#9( Xhๆ/Tิ˜� Bc๑ย๙6Rร†ขyฟ-4๚ซrŒp}6ุธGฬˆะ�๊K b๕๑R ข\Ÿ๖๏[9 ŒC›ปถo&xV้f&`‘งยŸ<ก๚bชธ๎…k๖๊ึฅPฟwฯnY มฃ8ฉk๙ม™€E��๓l่�Lh๕4†๗๊ฬi“…W^44Mบ<‰Lt^ฆธฎ•<ุฟฏธ๖๒ส—�฿—,ฅƒฝUถ\๊์�ƒ‡จisซWž�„F4มpjึi`็CฺัC๛ำo{๗@+VฎF’ดนณฆ‹ >ฟจM) ฃkJใyˆ็ข2€™๙ ๒92H(@JAูแ�{(ส็(ร*- —พ%ttั'Œbำ=xอt์�W๔>้๛tEพปƒก X\ง 3<ั7ฤ‰DD\x"ยY73I์คฉำhาไi๚๎ๅ‡-+๐‰ ณ้ธธทq+ำ5แล^N่๐"h“nฬH*ผ{xหถm[�๖๋CfoH=฿ผn–Cึ/4usDภ"็๗ฃ๙เ^„๗ซ๎ ฎห\่m;ปŸƒ;๋Ÿgk\ำfร3๖•๐ฦน7›Nภbภ$W�6^ฯ(๓ำŸํ2A�ั Xคีkะ„Ž Iex6gฯ‘^‹�Ÿ9{ฮฆํ*•*R�พฝdั=๛๖S ฏ6ชšผ�๑›”2E :{๖›6Qศ\�เๆkƒ$4_ทy �j\[ ?ะV`š"ฬS�]๕A'2ฆ�‰~qbลคCGำก+‡๗ e๎ฐฮด#B‚}›0eฆิ"U�D€›?� Ÿมj6�ื@Vย�%`u ‚ุ“าล‹ˆ๗’ดtIx\.Zถสf๚ป_ XhฬBk†kฆŒZ”D�V(’๗Vำึไ ”I$>˜ซ”/-หžื๏Ž�๛ ขห,Sเ_๛๓ษvํ9@s~[,‹ีฌVัะŸี๋M˜6›Ž?%“เ•^ตb*\0Ÿ˜.๚ติt:kžq�š=วOž!/หเ:�wชU,Gูณeฆ'Ÿาแ™ OOu^G้kฯ๚�ƒ๋บ_๎Wgว๒ว…ห4|Œ๕�ๅjWฏ$$E 8ฌ๒F*^Ÿƒwแ�ศ—'ๅ2‰$0ศ&g๗ฑ� # ไ฿บ}—zด4gSภ ไห- ฐsbz8žx็€ๅห““0_Y@ฐๆkฑ\้b„ oะtฦtkhb๏ูะธฆJ๛•ชW.'ปฆKrเa๖”1y†ภ]็/^–ๅWถT1*[ฒจ�ฝมqn�ต‡–ฎXk�ว๐Rฦ` ›Oฐ Q๛vm#1Wธ๊�›๙sgงชJฉ,yŽ๏‹A่ZวŽร "Q`‡xฎญ\ทE–-Sผฐxฎๅ7๊๙ดขฐY2ฆง†ตซ๘Tลศ๗$k๖ ฦNเๅ๚ื_๏ล๑ฦ”๏jว7ล�:b�tน ๙‚Aฝ:ฺอถ๘$~‹ยˆk�lAIภ‚dอ1๐Oq.-ฝาp!%N›‹2#E์oi_ฯค–Bพ๘ซุยi#ัยๆ lj๊oส8฿า�๖ํ^๛„&l*๋yš€ี;ƒ b&sLL/ะ๋Lภ0ยvฤช๒Uuมฎl&auวทu๋V๚๕W๋ดouฬงNข9r๘� /F�ทoง‚ ชฆ%<_แซ[Pฐะืkูชกฯฉ๗M_‰๑๛o๓lผใฬฤŠ^^_‡fโุQ#l~,/^ผH•ชีา‹ษu฿่šงขฺ5ฆ%เ :†)SZG‘ H182ิ)_ฎŒแ…m฿ฐˆ๔\คX)bOํG๗&2}M˜8Ee9]ŽSฒ‹‹ฉู๎˜>ำ�kืด'š}jวำ,44nfณ[2ล”gๆ†�%`ฑoxH6๗jm|T:๋ฃˆ๒Iภข-[ตฅ�{-ำ๕KฅO™4ž๒็อฃ6ษ์ iึ/ฑYบ\%‡ืจัˆถb๖:ีฒœฎše@tXU2ฐา6{๎|•mทุฏท ำ*ุค›eOl2ลtจWฌZmม€E��๓lpไฅชc��้3gI:‹ฤ5kืS๗^}Œ|๓ ึอœ3ืH6ฐะีญSฏก!๏a4ญคM“†0จกหุธz.๋ีอยŒ ฬ�0›W !U �+3ห<๘$W ๊yr้BวQ.ฝOษลเษŸืoศ$w XgžsEภ‚€3a>w^๏บฑžM่ถ>๑ส8w ุหb&ภเแใŒvฬ+๘ˆ…W๖๏W๖ภกฃ4m๖›ฆร† Cณ&1าŽ๒rสŒนaedh+xŸ่ืฝฃ$hUrp!`ผ…ีWี?๓ว=fุ@›)๓˜6"xฎฬ \ฎ๊Ež_๎WW�Qฏpย๔`„jšฐฃz๊>ี๓เฉ U˜สw5 ใŒ€E�฿—ฎขM�vbีฉ$ฺฟง i,ฎลN=๚ ggN๛ค2ฬžมบ7:ส ุห๐ศ O�—ย๓X7}เGฅCOvิะ�Yx*ณY๐˜—ิyIDAT‹–jU)Gนฒg1`} ไภฐLx ฏะดšWจQP[นq๋M˜>O๊ก"„$๔X•.ชVTฎพz�FxoG6’u‰�ฺ5ง&ฏUrp4Y$OฐุผYK-h จ�๊KxธŽ›:Gผ[=1’s‰Aฎ•ห:}~่วT์�/จ๛2HZบ]A่ŸNฉฯ8ฌ”y“N�~/ำฆ7ˆGe3Y<œU!ศ”}ƒžพ๙—bG C{'SYrฉุ"}C็‡Xeฉฐ‰b„ฅ#}’�ิE�Y๚\ฅŸ,์ฐุ7฿S�้wd๛2GฅA•c�์ ษ;_ฆท�cV!s๖‚…‘N“าžWeBฺ๒ฎ๗Xz๒›ลใ}‡ๆซู๓ี|Lก…„5ฐํฺตฃัฃG›Wnฯ›77nl| ;,ไ"?�ฃF"์ร‘ 2„z๕ฒx๙จ�ภ"`}า™:r๔X;" Lš5mdฃ_ช๚ฉฆใ'L6ฎจt,แuิฎu+้๙๊่ฅuว =xซ*ฌ,‚ ^0wฆ�Œหux‰9ึฮ+JฏTฃZU๑แ�ิแ4Tx M˜4ีฦKu&L =q/ขX้dย๛๋๔๑รFำ3fฯก1c'�งO1ฆ†ซDB(ทn�FรkฬLไข์ูs็จ[>vฏศ+//ต๒iQแŽa::ฆ/+�พyƒ๐จ�Qmบฝิ‰?G}vปกฯ๑"5g’ณ^ฺิตs—M๙„ก™(ฺถy=ล‹ืฆอ‹/ ย฿๊ฑ DNคtD๛๕D;vํ6ฎG•]ีกƒ๛หi�*M-๕€C˜๊ ข฿l5jื^ฏ gบฬuิ6^–0ุเ่�Te@ฌvj฿N^ท* ห?…งV๕ฺu%ๆธ~็ฮšf'๕oo๘๏ศณํเธ:whO๐ฆ๖‹้šฯ๐Š:zpŸอ‹ข™€=ๆA~b้าv^๘8xN82œ็ถ: /�{F6Žปh‘ย4tะส’=ทqŒบฤผ๎ ฌ ’ฦPฆ{J๊:า*฿7K}ŠชU*'‚nfื“Cฤบบ_!•2yฌ๕>๑k็งฬœgเ ๎hร๖๊b3จ ส่Gฮสจฒๆ%ฎลy‹–ษ`X๘m0๎ฟ*สP๑"…lฒpv๎ู_zฑ"ุไ4tƒ”ฦB m๗พƒK๐M—#[jPปบห ^z›_สบ;ฌฐ ฟห†งว&"๒ƒzvอ ;]+i๓ๆ”มฏtา้ธF>N๋6๏ภฆีฏY‰า  บช7n�กๅk7ู่หš X๔ ฤp๚ดฉ "ืเ�wล๏๎)}€k�ZL๕‡5oXKึมบYNaฤภ๎qปq�nฺฐล๙@GสไIจชT1{๙โz=!‘กพฃมฑิ)“‰ูข^ฬะiŸ<ฃ�#Xฅฒ–w\ ๚t์e๙m–.�๘Vžซ5rD5Z|๔๚_:w็=]จž ‚Sู๗ฟกฃ}“K๒Qฅa‰€U๙†\7’š�jŠ๖ย|๓ํน�ŽFmzbด ม&b3M๗+๔โe?UณGฅฺ9ฃQโแ U]‚ šศฏ›;ล๛>m๛ใ ๕[�˜� BT™X]็ํ5+jŠพ$}ูqแ-M�๙œŽ฿ฐผ?”ฬ™f7Žฏv่K๖€ @ศOฅหeด๎๙ช ›IุLTY!fi&`�๑Gบqใ†๑มw๙๒eŠ)ฆt+ธƒR็ฮ้ะกCพ:Fxถz{{;๔ฎEC๘๑I—.ม๓Sท€"`ฑ?�Eš;†ŠkืฎIOเ8qโˆisฑmFบตโๅ๐ลห—Rว๚ทพัาƒๆ*ฆK่^Pฮ๖ๅ(�ัใวt๋ึm�๋ลซ—B'*ฎˆฎŸ'N,๛ใจŽž"๖ๆอ›๔๚อJ•*•Ÿ๛กทi^BฃงŽi”G?nˆ)แ/ล1D�ƒะ๋Œk่&š�sถ=u๚L?ัขฆ*rV�Yบ~ แeรYŸี7งใษ“ฟฐ ณvีrJžฬ�ม.w04๏ื/� ไ๎�ฝC฿ ’ื>>‚ฺิตqใึ-บ}็E…'I$ต๗ิ๓หQ1ธqๅสUJž<นK`�ƒืฏ_—S1…^ $คDb0ย/พ�—M›ทPGกวฌฬ๐ฯซ^pกU}_xSฆ�WขชgKx๖�DFd‘oฎ/gํ‡tu��๒lภถ๋7ฎK]rŸ0ณŒŒ#ๅ๐ธ/4๑?Qย„nI  žูpN ฉ‚็H�x๑…๎บ๕#ม\V฿F=์วษ <ื�ฝะw�ฆ…ำUอ$o๑าๅไ๏๖…7Hw„4!/่ยฉ`$!ํœ๕WE5วs`�๔๑ฮŠ9M๑๒•ิY92ุ ƒ'ž› ไฬฟ๔��ธy›ž 2(ถธๆใ‰ 1��-ี�่ušu] �ไWbqญ�$H ๘dxฝ�!=d4�{pบยษง๖B[>$ E๋ิฎ%e๘ษฝAv1Pพ๏C�Wฏ�ืw๒dI ๒( ๖ๅn› Ž. ƒ›ยใZฮqใฤฟ๏IไเŠซ{ ๗ฉซ๋ไฺๅซื ๏Vฯžฝ hัขRR๑ฬ@:พ^ŸwXว5�žŠwRh�๕Wb`๖น๗ฒณ–กƒF๔๗X4Žัฮ่มVg(3ซฺAนxย‘ฆ‚ƒฉผภZ&ธŸ?iG^;๋๚ ]o|SC#ึ?ๆ[ึ}๘QํG 'm9ฒั[žา๐ ๖—zYHlมซพ k�FวลhกะXีMืXu„K/[4]$ฺ๚‡E‚ะ?,ฺœดใ \๓Xo�n๒z%3bปภl‚�|ีบี{0ลฌ]•โws์้l๗Š„๕ q๋ฌญ H7ฐ่ร�๙๓ฉvํฺฒ;ตjีขร‡S—.]จYณfF/]บD;v์D์ขE๖m(XฅJส›7/(P@’ซFe+›7oฆ’%Kฺๅkท#N๘bจ,คเน s4�;(€€—e๏�iห–mฦ๎๊๗฿ๆ�ผz œฟp1Co3ož\„€~ส\ฐชLp[Bขใเก#nwซzี*"ศ_ทหtAw ุ€๎GPดแยEช\�๊:lศ *Sฺ�๗9(๚ฺ๗ าxภP‹DD<1 �ทGGปCF .s‚EAV&Œtฯ[วฎ!N`‚)z@=OyิำCๅn…B‚‚€๕Œ๎ฐžฺ_Hnว๖ษ›O”พงe๖ธฃc๔ํื”(f8J๗[้qš5IGลlาŽ\�‹šอนG_}ฒIแฺ@xพv/“ย ฏXณม๓ด�๊Gด๘๐Kz/ึa:‹ํ™"ุ`AŒช|คmUไ*•! ๅ| I4Gxฅ–�ฉฐๅ"hVซ๗ๅ๚†‰)Kโ๏ไ:�(�Zหใjูฮพ\}โ5 X๛˜๎ฟ๘ว(1ษ…ชeFฝหฦ"xฅ1”่‡โ};"`แ vNL๙† =?^zฦบฺ๏mก3ฝSgvZPนs็–dฎฃ2Lภ:B…ำB :‹Š”)RWหf”?ฏีK7ด+‡฿ุฑS%2-ฐ0Bฏz๘Pžr์w4�ซ =๊๎=๛ะ�ฤ?Xล๒Œ“ำฝส\Š๐'g�ธ@ฟ-^nษY5๙�๖๎(ด๊*Ž๘ฑX’ฮ้ƒ>จิB„1bLช็’VแSˆข,p>กยaƒb$Q{˜:่ฉGฯ–๕โC‘ลฆO3%็ฆV��ฅณ5qื�๎™ž๛๗๓๐�ป��Ÿ�๏|ฮภ๑ๅฯY^�_๑Vฯkแํ7^?าจ„@๙๔w๙ญธ๒๏กญ[^๛Šอ๐ส฿wVx�๐ภ์UญTwฌuำss{;”๋ปNOฯฤSฺสo๖๑Š `+>มjx ฐe=kืฎ gฯž�]~pp0=z4�บukัๅ–7m,6&น฿Q†ณๅฑล†9 ุ…d�ผ*eะ๓Dฑ‘JYUลิ8 Prc‰ซWk›Œฌ,6ณ๊|vc�Tมึ ฐ๏:R�M�hืฎ\Šq้sNเฮปแ‹ก|–อšซฬซ”ุ”š๚šจภ–Zทn] [‹ฏร–วdฑใvนV๋ŸลŽํe@Ÿญผฯ? ฐใใใa๛๖ํลŽ๖—๎sี�ฐs^ @€ @€@ž‡๚? ท๏�ีาOมๆ)›GUๅำฏmลNQCƒG๒(HK& €]2ฺวปใฐฅN{{{ปvํš‡Uฎ[>‘Q๏ธ|๙rุฐaรผœ:u*๔๖๖ฮ๎๘=๏ไ=oฐ๗€xK€ @€ู  ฿�๐Sh{jyxฒ๊–฿rsดพ@ผ�-‚๕�3ำแฅท„�๏๎n�AA]l]'�ฏภช๖•affqkป์ุฑ# ีึ€-๏7==สM:๊�]๖j๑5บ���0::Z๏’ูsแื฿~Ÿ}๏ @€ศQ`ฒุ€๚ฃO>ืo�ศฑ<55)ะฑjU๘เ`hภChM�ฦๅ`3˜„*–๐๊+/‡๓็ฯ/zhmmma็ฮกฏฏฏถH�ถm�๊^{๚๔ฺ้R###ตเต‘๕cปปปรื฿œซ�ฟ“ @€ @ ษษkแไ—_…KฟL„›7งr(I M ฌX๑txfใ๚ะป๛ฐfอ๊&{sy+`[a–Zฐฦ'N„�}๛ฒฌ|ไ๘๑ฐgฯ�,kS @€ @€@ตฐีšฯฌFำ่Sฐฃ๘ฎฎฎp๎�๏ฦญ�ƒ @€ @€@ภ๚%X2+W&ย›==แย… KvF:�ผys;s&ฌ_?๓ฎF๚๐Y @€ @€`ั๒ู†ฆฆฆย่ษ“แุฑOรล‹พ>ลแภƒaฯ�ฝ��+ล�๔A€ @€ @ `ฃ„– @€ @€‰ฐ‰AuG€ @€ @€( €Z @€ @€$ภ&ี @€ @€ข€6Jh  @€ @€ X@›Tw @€ @€ˆุ(ก%@€ @€ @€@blbP� @€ @€ @ `ฃ„– @€ @€‰ฐ‰AuG€ @€ @€( €Z @€ @€$ภ&ี @€ @€ข€6Jh  @€ @€ X@›Tw @€ @€ˆุ(ก%@€ @€ @€@blbP� @€ @€ @ `ฃ„– @€ @€‰ฐ‰AuG€ @€ @€( €Z @€ @€$ภ&ี @€ @€ข@v์šีฑ6- @€ @€ZZเฺืk๕oy~SSใX๖wq4ำร?ื.ภ6ฃ่Z @€ @€rศ.€m6 ฮ W- @€ @€<�๑มำfsฯdOภ6[ศใ=FO€ @€ @€@NุœfC- @€ @€TJ@[ฉ้4 @€ @€rภๆ4j!@€ @€ @ RุJMงม @€ @€ “€6งูP  @€ @€•ภVj: † @€ @€œฐ9อ†Z @€ @€จ”€ถRำi0 @€ @€ไ$ €อi6ิB€ @€ @€@ฅฐ•šNƒ!@€ @€ @ 'lNณก @€ @€*% €ญิt  @€ @€9 ค `�‚_(“^j:’IENDฎB`‚pydantic-httpx2-6dd59b9/docs/img/logo.jpg000066400000000000000000000363501526547463400204010ustar00rootroot00000000000000�ุ�เJFIFdd�์Ducky�๎Adobedภ��„   #%'%#//33//@@@@@@@@@@@@@@@&&0##0+.'''.+550055@@?@@@@@@@@@@@@�ภะ^"�ฤ‰!1A"Qaq2‘กR#ฑBbr‚’มข3CัฒScs“$๐แาƒ4D๑ร%5ยฃU&�ฺ ?๔ (ข€ขฑEhขŠŠ( (ขŠŠ( (ขŠฐHHึk๚ว4ด™ข#—Š# {ฏหฐ๋ �ํ๐ ๋่ฏ:เ�ซไ๘๗Hsๆธ๐B™พ&P@ี[ิ< zRล�h=Š๓�_ฯ“ธd-ฟแก๛HŸ[scRb{kชZ�a‡Epg๋~] :‘f้๊๓SXŸ_m™‰ง‹Bn•ฟำAูQUX�Rqs(ggว .;่ศ๕5ถ�๕c๐ฬ7E"ศ ฃ๗PIEPQEXฌัAW๔ื žฯ๙‘Ž�๛nถ๛้,ง๓xWfโ๒šlr?๔yสM๚‡[�5ะัA>Bฮ›‚ดmญใmqฉ]ดฉฉfฤ$“" ‘! ไฝาŠUUฺอฅo‹•T]ุภ,ญิY•aๆ๕QEQ@V•Tณ ’t อU๒นฆB$sคX'^ฯŽฏใ๛44 ฮหWtž.฿k{d:๔v่vฉพ–ืญYล‰‹v†Œศw9U นฝ&ีผqวkJ4UQ`๐ท (ขŠŠ( (ขŠŠ( (ฅ๒ณฐ๐ื~T้ ฺ�v `5[/ึOG�ป=(ฌรํ AuEs��ใ้฿ ุ�ๅท๖Šฯ�6๚xhg`qฟัAESA๕oำ๓ุ.bฉ> �ทซXฆ†e� ฌŠ|T†u”QE_ิ- โe1>รt n”ฐV๐>ผ๗๊<–“œŸฉ@UูT"�ี้|†;ไ`dC l–HุFใจkyO�^aอล1fpHฑ#[^โ๋fิะ$. k-{zฝ:z้ฅX๔(ฑ]ล‰ \›S|\QๆศษFc ^4Pท^ฦแ”฿j๋n•ึqP "L†ฤ•_8ยฤศ๏O1‡EK=๏poAฤ๖ฒ5/ชตŠตŽึ จืฆต`˜ุ a”Zก-ต#RIto‹วัาบžC๙ฅ8arb™oโ�$…ีtPŽ—๕Uฆ?6š็*G:ศwฦฆรvลaาโ๔�oำ๘xใๆ!dP็r†บ1]หก#x๔๕ตX/าผฑaŠ ํav๒ุ[Kœ๐˜Jwc™1[�ฬŒƒ๙nW๎ญ๛<”๒ฆ\•aตฟๆGง๗h"vV2,x’ขร wR�€๚8๛M/6}๙�eว�๋๖�xvH=โžศฯ|m�iœ2��๎ชAท›์Zา>oŠv ๓+‹-โ?dกh fˆKฦr’์?ฎLgีv๓�zถ๏}AŽŸ›iC ˜[h๋u”โฉd‹`dยษ\yI$ษ BญoฬSp฿ฆด9œ–%พkๆโ�oˆ5๖กf��คะg›ยšo——~&G„9 �-๛งแoqซ ฏ‘8�P’)(๒0ุ๊ษ�ข๔ณcMƒwŽI1ะณผุ�ล]“๘Mจ.จชจนyฃˆK— ผWทฬc0•ปnSโ};‡–?้ๆY๊ ๙‡ตNขŠ(ข€คฆ‰qrŽj=ํฉชป‹mัๅ€Pท74ํk"$ˆัธ�Ž ฒŸt"€GWP่C# ซpA๑ถช�G๙L–ใ฿Hฌส?„B �ฬ6“์ซ Š+ rg(ฅๆ™ึ(T~7๑๖ญcภ€๏–F2O-ถ™$mYˆŒhžLษsdัJˆ 6ํ1fR‰oัNPQEEC‘•‹s&U‰?ท>~ดข๒“d้‰$ชF“M๙k่�7ŸrะXิ99˜ธ‰�ส™!Aโ์๔ีVAอ’aนL๓_vยLณ6โู๊.‡SgdD’tO‰ีt�๗oKPk7ิ+ๅy9ล๔VHสF๓$ฐจ{฿We‘�ƒฤสฦg๛JดŸ’ร‚QŽาnœ๔†0]�•/o}Dgๅf?๔๐GŽ—๘๒s๊Ž/ํj ๏่œ�ื9\ไˆ/ชใฤฑ‹~๕'?มฌสฒggrhAล+สเOhY}ไUแโDเP๒ล๎b6Ž๙iื๘‰ญฮw†ข��.๖ก@Ÿบƒ˜ฬ๚^NC/l\?”‚฿žrd�#�š�gcqงQj›+่ผฌ’%9ร*๔#cD ฝ‰;WO]t+Ÿ� Nา’d0S�-77�j๐9Iอๆไ )mS5M~Nแ แ2x8ฐค0อb่โเ‘q๓02›ด4žF&12\�Z(�ไasqๆ7R+ั๓8^3-‘ฒโ3IดF$7� ๊ฬ–๔uช๏คไฤ†vรฎัรท1ฑP.ฒ_ฉถšPpฅ-qbH๋`~ฺc#7D—V‚EํrขวำVƒ†�ฏœ™’5VR่วT2รต/B๔ฅ๒ธี…LัฑeV 0Sผ�ฎ๏…nถผ}”'๕ฯyื”UC๐œฅ6[“aน|/ุ้�Z๗ำญ๋ศ dผ.บภ‚&–๖:ญิท๔ืคY?๘฿oต.ฮ฿oณธ๗v๎ูทv���(-ลy็ี8Œ9 ธะิN7,H๊-าฝ U'ี8ห&y _dy;๒๙ฏเ(8^3Žฮ–`SiY,KคW1ธ่F๒ฃC]^?Qc™g\๓fiU็m˜ฤ�๛-VLfG‘ลคJGw๒ๆำเ฿ฤ5ซŠ ุryพฺ๗๐ข2~ฑIฌพเPš�็y@Hn8›xคศo์�ถŸ$s 4ค�ฟ�&L{�ํ�ฉsAฯr�›'�ศฟ๑ึ฿;Ÿo�_'�ศฟ๑า}eย#mW’Fฝฌฑžฟลถ™ƒ™“.�'ˆำ๑์@ฏ๏ ไŠ �nMสˆq’0V์ำI๐ŸFุร_ํญdใ็ฬˆวศN6๘ก…{hร๐ฑbฮ}ฤTm?;>฿—ƒ๓4ฮd`Aถ‹Ÿ}gไน)m๓<A๘qฃXฟฝ'pะb^้์xo6,q ถ็D_๏U๑แ`r)ฺโqApsX†วQwอ�[Om[AฤแC ˜กšqาi˜สเ๚‹“ท�Zเ^f Pโtฉ…ฺ฿ฦญA๚o‰ข๖‰‘o|ฑ๎ผอใ[EฤฯŒo–๛!c\_๕u]ฝ=•gE?$99“+ณ_'๛บ�ไ%‰๗กจ&—)7า~ูƒ%Ml=อถบIี "๏aัn�ๆ—›+อ…Eน4ˆษไณXˆํ`p%ศน๓(บGืฦ๔Œ9x8“<3$ฒไ1�นะผนภmฌพgบƒ่Uญ'สอ$Y2H2dRW ฯสM๕?แฤ Žฆไ~*ธ�yŽหๅๆŸ‚KๅฺG•ต=/ึ�E๒ภ8ƒ.NฬฤธX฿›’�ฟฒ๛=฿อPโp�Œ๊W)วˆNธ˜ŒL� ๙‰๖Uฎ.ฦD฿/x่ไ}>ถvิ๛่„๒EaโE…๛๓บC‘ikRฒKศใษๆI\lฬXTCด‹v�Sฐ฿ลชๆ ˜rTผ$ฒmึ eภธญ�D)"‡FeapGฌฮOuๅวส,–6!: |]Oพฃ“šRZAะ’ภค}ฑฒิ91ไ๑ฏ€๋$"ฦธS๑9�hd๊พรq์ฉ�ฌว?;>)KFdOsรผP!&*<„“ึ็ตb[ภ+y4�9๑โฦ#^3'<8‘‡ู=3หq™gn>TR?เ 7)ึ›” �Vล�c�6๑ิv%๔_ฎหVจ‚HLl†ท๛ฒฟ๋ํง( ช�ฑ”า˜ขโ๒[i ฑํข�zู้^@r9�œKฒวslˆภ z1O2’พ้W๔Pqาม๕m$*ดŒส{qๅ<–�๑(kxOyถBM•ศ2e IQํ’ทถหงฬI๑ซi2sฐXfqฅ"ษ‰Iš(ิ ไ฿tF๖๋^ต]—•cž?=ฤ�l“ไ6�ฤฺ�‹๕ Fhp‰BtPH7�ิญตฎใ่ฌLœ๊Ž' 1N๋�๛ไ๓๛๔งj2๑ขาIQIะEฯบ‚Zอ-&t(ชผ›๕]‹�ญaUฏ๕%ๆ’ N?')ใฐslจ'ภฐr“F2น8•ต {ฤxw^่Ÿb๎4�Rbfs%�ฅ2ผฮYฺIฃP๒จ๒†:(๔SBnt›œ\pพ ฬื๛DTfEƒ!ถN'|u�ฺ๎a4Œ˜ŸNEศ’• ูถหŽูฒš็Ž๚FC�อlูy›Jไq๎สE›ด๑ส:tr„�”}ศ�A˜ูาMหศ‡ FZW{ฆ๏;7Zšจ9X2qฦO'+ในM Mผทขอใๅƒ!Cแผ \ูๆ]‘พฟญ =ฝz๔ฺ“‰เ๒y\่ฬcd0KyฆFRฑฺอฑNปš�ฺ์qู–ำ’ศ‹ฌ'�ทZŒY~M๏รซถงh3ะฮBฝ…ญ2\ŸkFS๔TG3’„‘>uป๑œ9�I6ฒ๔�ฺFl2zž>๔Vง#ž‰ฌุd.žhฆ(}~Y๛jUๆp7l•�๚mZ/ฝภ}O.n,Xาe4ชa‰K;‚ ะPใอ7!ฬอ‘,rc<(˜หปoพMbธฑธิ้]-V๐๐c”l่K”Kบฑkฑ%ญb@๗U•+5Šอ’.๘ู?#ํฬpg’ว“+ŽIbI๗nU”ดฃUถแะ๕ฎชจนํุ“ม›ิ™›nโ™€ธM๘…ลั๑ฒพนูRdŸ_ษ‹๙cิ๛ษฆกƒ6รDHP}ิฌ3f็Eัํล…ล๕ษm่�+๗ิ‡Žฦf฿>้อ๏iXฒb|?uฯŸŠ„ชฟuว๊D ๖%๊Hdy.Z6t�บื>แ{Rญษ๑๐ฑƒ๓ฅ_๒1—y๗ํ๒yญK๓Z"&gซนห๎E๒y4NaX™ง`‘‰™ถ‹zอล$��.แr็5‡�w ๖ศลS๏ฉˆฤ'~N์ษ:๎ศ;ภ?ฒŸ๗ t  ๛นนฮ‰zX™ไ�Uุฃํ5ท๔ก%�o*|‹‹2—ํ!ฟ์Cณ๏ง่ [ยย]ธฐ$Cฤจ>ำิำ4TSdใภ7M*D=.มM”ฌ�_o$ ป๑ฏ‘ฟ™,ii~ฃโcัf3vณ�๚ˆ>๊Œ๓yR โqำJฆ๖f:zCํ ฤŸMb]ค‚I#”ƒmล\tา�ลc๗ิRq?“9†๒J €�w.฿๎ิŸ�ำeฑยB:�R �8ธคคใ ŠI+ส0%ธ”: ึบX5ต๐ ฬฒ๒XŽXๆคฃมƒศAv๖๔M™’Cฅœ,hถRŽฌฬพืŽ(7\z ฐ?ะ๑แ’5‹#9V6Eธ�!ู›้ๅOUG“—(๛แวŒVH€bฮˆf๒๙TƒmชบƒืE ขห—"Ž6๙‡yU๒#ŠXะ“ๆ)ฏq}—สC ไ$ฑf(Y�4f1’ูpำแqN๎ฦ’a’’!ว@ล€นe�ใGmu#O]G…†ˆ™RใJ๊a[ l…•ํ๗6�ฉถ— N@๒fฌ`ฺ8หแ@�>G๙AeบT์)"้พNๅภ&�Uฑ๛i„อ‰d“ๆsC�9:�Zฆๆk~;}UผาKฺ งROgdะ-ู�€‘๋พพ.4xเ ไ0$BเษŒฌ6‚�๎`lJ (rนK.67ัฦ‚ลŠคq฿าž>พอ*Fว๚‰ภvž,HำV๓’BฦšALค|ฎRAqpฉ4ฑฑ 6�้oี�5;แgvŠว™#!ณ–Y€<{ั0#๘…รŒฮœณอศnนีbŒmฅ๎<–ฉ‚ลาK<ƒฤw;`๛D!B™์>WTžฤ�้ด�ภ^“�Z”s[๙ฌwŒ๘์!ลฝ6m�ฺ ›้๎ฮ็ลW>–,฿๋X^ˆณa‰0‹j฿,ํ'ึฟ�Sรหq๓ซ0W�2�๘ุ ‹ƒpzAZ0yhเไ{Š:&DJ฿�aญ†_-�>”ดฦ•H๗ฌ�ณ๗šzGuีPธ๑ฑ๛ํQ์e`ฒฟeŽ€H _ุ[CAˆ๙)%0 Bฮ ปOไ} ดVฑ>๊ทiดจฝอด๑๐5ุ๘ูQ์ž4š3จ hฝ&�CFw`ๅฯŠ|wz/๙r๎๛ˆ iฒBณ$ั: ๎น๖ญํ๏ฑใธ\฿:ร ฐ�x์ฌ?Š;YIyx4ษ†<ค�kŽv7พ) พฦฌ�๘ผษไ |ฆ�ๅoฒ‚6แๅ\,�Œsเฎยt�Yทพต_๋˜›ฯf ะฬX˜ุม!า฿ ๏_HฆN>t:ใdw๛<ป์‘,฿m๋Sศษ�ญฦ’!ใ$ถ้ๆ๕ ]y�uO�!>ƒwฃ&;�๚nZW-8�ฬธ“ o$˜๋�zobอ๖Zง‹&�J๑‘w>ึ:ะ(�ซพ˜Xsไ“ัŠ๖c�iถ�ยฑทŸโ||5> yฝถ/�i�Œœ|d๎dJฑ'ฅศ_ำUs}E‹qฐ>kŸ„"ฏ™K ฐ๐น •›•; \w;Iq๛0„ญ%ม๚s=ูโ‚7ฝ๗KgrO๏๎cPถ/ิ9jฆ|Œฉ1มๅ ๘ƒ6ฌ}ฤ}๚O๔๖ุ‚ำ0 $็YA�mๆไ\๕4 ษ๕.>�ฮ$นNป€ ข5]‡i๘ตำูZว๕mฤรตŠณฯ ๑ŠO‡_}\ฌXะ( ฉฏNƒง�J['™ใ๑Žฮ่–vั Šฯ#@Q�ดณp|พAS“ศ<พึKGฅษTฑbzZฑ/มqฅ{๒”gmอฟอcใ๋ }ึไs�œฅ1ใ\<.9kปB��ใ�ิ๏ยaเžํปู�ฬ๚›Ÿย:ำ๋ ค06`hqขั�กR ศn‚oo€ŸF–ชŽ<|8v “2ษผฦใyธVู+ท๐“ฏ@/ฆ•}ศๅฎ2แ wœ*†ีฎv์_5ุ๚ซฎข—-ž6hpˆฑไบข–๓–nƒภYFงOี N|”; 2k•w1ฑ ศ/ๅ๊ฬwiq๗๔็L}ศๅ—#ปe3บ/]T๙wรแฏขฎrเ‚&˜ศ†hฑ‚ึFน๎K!, ตธ:๘Tธ๘ไq=ษ2d๖ปจ ่ Xฅ๕? คXฯสDRm,h๛ษ{�…ูl|�?eZโ็G๒ัHใๅRปmถ�ƒ�K ›ํMค\xŠญ—;Y�;€^ฬไฑม�ฎฃโ่=๔$ฏ>"FX3e ูRไถุ๕{ฅ[mยอ$๒วŽฅW%TDd]ืŠq`ธ ฒซกใBGCOq๙=‰ใ ๒�ส%Sๆu�–YE� ›๖j€๖š4†PฒGฺ6Vqถยไ2ุุฉฑิ/O†ฎ8้aส\–™ใˆLŠ%ŽE…•ผrh๑V]?Lญ…4Mฺ๘ญๆ}ชวอีฏoWZW„ŽาaH`ฟ”yJ\ ๎ธ]บ฿กท�kC7‘Œ ผl๛^5Va) 7ฐฐ`รM๎๖Šg–ํ[Sเipn�“bZ�ีfส%›๊ )N‘ไใ\Y˜๖ถง๒ํ�ฏ๖PŸRรc๓ุฒE w—๓b๓jฝmvฎัาDFิ2›ƒ๏ฌE$f'@P�ญKร๒)พŽฝ ˆ•#ฺ฿}า;w8ณผMาฤ�Xxiถฃฯเq๒U[ฮ4๑€ฉ*pทฝบŠV7๚ƒŒธ˜P€�‰C(ิ๚›ํ gนฯcX4Qๆง‰V๖๗€>๊ัพคภˆ๖น(ฅย&ภ๗ใ=ฒO†๑u4ฯอ`g€ฑฑŽb/ุ”l“Cด่zุ้ฅ<่’)GPสzซ ƒ๖ะ' |vJ๏รใพ฿ตP�ํ6ฬจฃดn'`อ๒พศฟูIไ�9ลOr‘ถ4„๎cณDภŽ„m6๛ช1‰ฯแ/�6Zg ?แๅ.วท K_x qน‡�W˜ใลศ฿๓ฅภ๗ฺฅdฤอ†ฬ"้ัื�U฿�†,v)ษโอƒcn๋!’๋F฿j™1xฌ๋ๅaHGฯŠ๛O๑l6?ฤ(6|ุ๎?+ja82วงกฎ}งูZ70ุงo'Ž๘หใฟ™๏uีˆ �[ล3ขศฆ�ภ฿�ช๎S’ฑ#ŠCเ™ k9q�MฝFลKiใAฌrหศ‚4‰r,ฎฆโC ๑<บnk๔>ฝt*ชŠUQ`€Kqุๆ u/�+๙ŸKZ�๊n€ขŠ( (ข€ขŠ(0สJฐบ‘bˆ5Y.4˜s6V9ฉ คค–่d๔้๐šณข‚–<ˆrœ/$ฬ๚Ÿ*๙q๏์พๆ�*my\a ณ่ˆ„/oP™“YRW@^3u=>ฺ8ฬD�u/ปโ�o ๐๖P-//9m˜ุฅ›มคuU๑ืหธ๘�ZB~C9…็ส$žHแฦPฒผŠ<่ญ5�›O์งeหQ,pใ&ยฺEkน่[@ �Š�+ฑเIไ•;ˆรykFŒ‹!I�ธ๔SAรE&o#”‘ฌJ’d !ie{�๎1-b4ฐ๑ฝzx™U„ยฺชม"A`‹ฎํถนi0ฦ?ิˆ1`[ท(„฿haผ1ด[‰ฝฏv"ีฺฉ%A=mญƒ3�yณ๔่ฝด�U+ ลลฑ’Iฒ%V ๓=๔ฟBคzjGฮ„9Žg”uH†ฺ๋o…}ๆ€นณ/ๆ2ใ‚zG็k~๓ }ิ dโ๐˜;^hQๆ?แ+žไ์๎ ๑ญ๑ธิ˜Œœดต@ฃlh‡รm†งฦ๔ดธQMฬม+๙xสำๅศNๆv“หlอsฎฆีyA€Kdศ๎ยŸeศ๎?ˆvY`ึง‘Š.เฅตัโ}ิณศฐ ฅ๘z:ณ�๚ ›๚h+๙‚ฒBL˜ŸjฒลYพรXn#ืฏฌี~?’ณ1–ฯ:yม'อฝ†ม�7ิฎถ-ฉซ.7ทŸŒจUษBn7Ÿีaิุ\๋โuฉ�G�๖B"๒;~ >!mวจ ข“ฑ&9T}�ค`ฮหw Šฌฺ ฅใ~Ÿ‚LuyYฏ,r“ขชฒ›X๘iWLณˆ%–hคํะ››ณzƒ๚Tpา๒b9วศ#‚‹H ซ>ฏ/ คŸt€Qถฑcซ�Sp,ญทรำV˜1E‚UนYšuŠCไtาหf๘Z�๊ฌ›;%๒'(๛รถฆภ*๙ฎ ญ๐ƒqW\ภ�Rฦ่f๓ห�7ิ!!|—๔{}” J%d1ภ›ฤ"^อษ๎™P๎[~5ืNพ"ฅโณๅ&๖Ž็f�yˆ$ฏรไ๎�๐ๅr�•ศ;W๓k)^ู>UD`lื๑๕P;ˆ‘&Hฅษk*c†ใŒ�๗7”žญ๖xTง '-Xgษh��m *ถ�ฉ4v๗XVล๐ธะ#PLา๋ฑAyฅ#Mวฤ๛N”,9y^lฃุˆ๔วต#�ไƒ_r�ฆ32fส๘q™๓P*+กbจ�Geฺฃ�Xำ%6O›>Mภ�ํข%bฆ:3๛๔๕SqลH#‰B"่ชขภV๔วq Hิ"Šขภ{…C•–ธ๊S,ฯคPฏฤ็๛ค๘TrๅI+ด6iฺI›Xโ๖�โoP๗ฺฅวลH.ลŒ“?ว+๊อ�€z…ผ\ร&Aษ`๙r•’fUฒ€wm@�HP-V5K|�๎|s9วm,Icตฏฐ-ษ4ิ™|Œัธฦลํ?*Lƒก>;’2Xi@ิไํ)ฑูYZๅXxƒEQส_“—ดŽใyd†ฺ>f ิz|=m[G�_#<แfdฃใˆทไฆ2์ ธ๙Q™๎�a]ฉžE„8)Ž;/–�˜ฃผ๊�/pดq"Fมศถ|ฯ U?ฐต๔ฌ็†‹ ‰ ชภ.�kธ‘ใง†”สBฃ�1(Nฃ ะxR�ซFLฝส)3ศ\์„io^๒ด™๓OQ ท$ˆOUaP5้แ\๖;วลƒ.1˜�ฤK๛ฬGทฦฏ9ศYxผผVi Fา)+ๆ$7ณ x“งชจpxซ๑ค…2‰7Iๅ…I๚mAฯe634hศๅพ6ํ2‹WU๔“โ74}ถuyP;=ˆ‹|uิtฎLA+ป] ,�Wกฐบ๋~’ฦ ฤO�r’O0ํ^๛M �^coถๆHฐ๒ ฮDฬ‰ัค[าวปa`?`�ŠิแๅQ‰%ศ"ฦ%”HGbX๏ฑŠ‘ีถต๕๑ฆฯ™๒,Š6J-,H[ธ‘tP|C ค_ึ*ษหม… ๑ๅ‚้ๅ.X)O7๋t ฃใ#ไธ์y†1’Hข๎FWศJฯจ�้e๘\_ำW<\ฟ7'ฯG2I ‘jฒ๙ ˆh�c}m}il}ธผด7M3`อถxF�Šฎ�1o่sXาq๑>gˆณสึ2ใํ=ฒŠ|อh๖�๙บฒ‚วูฆœ"นว-�Y�ร‰K๋๙diฑF”ไฑG4oŠ9VSะƒกK‹ฯ˜qa“/ กล(†|oฯ„ฎ�*๋�ตilY,ง`t�น cึ�o{๎๗P/ล1‰dโๆ;คฤฐŒถฆH๘m๎๘OฌT™\FS๗dlฝ{ˆJท�Pr)–�†!ม(“ขศา4€๑ƒถHิ]ˆ7๐ต7˜’น†E0ไจปB๖ฝฝ*FŒ=b'ลๆฑC<…ศQ๐ว?_f๏๛ลQ๓j™๒A๓ัž/ 2 r๛6ƒrัส‚ฤ�๑ตvTถvF<ƒ”…เrศM๊ ๘ธืห๋ Uxุ•cศโฅX\F#WKฦ ki7บ‘Y—%•-ศฤ }TL‡|$๖ ฝc฿Pž$#'…ษ8,�mฑ&4—๑hŽž๕"ทNO'๒๙˜*|ฟ7฿Œ฿ฝ4ฤ-๋ ƒธ๖ษhZ !v bd๓'ฦ ‹xkV๑ใcฤลข@Pสกไx�lIRlMฐใe๙HŠ*Jt’2ฆหธ\hพŠผร”M‹ข�eท_}๔QEEPQEXฌึ(3Xฌั@QEๅษ�š๊ท๒๎c`7iU€:“๊˜L�H”ถ7,๒ฏ๛ร๚€๚พบ฿Žc8ฮฮa6_๙c�ธ�Xิ๘๚[ฉง่4Š(แb‰B"‹*จณณ#ยวi�? qฏล#Ÿ…ึMK4ัมอ+Ž0Yุ๔uคpฃ›.Eไrืhท�$kืo�a๖ =4q˜2ย>a™�ูHีQญตQ=JบV�–Zโโฑ๓d!E๘šFัT M9T’ถO%ศJqญุม ro๚†CนืBอีs@็…<.ฤ๒NKeHlwษ๐ถ–๘|*$€ฯษกv$`ฉ}Œ>๋-ืO"ŠxBFฦ fTฺืฑ�ำV=}?m)ย~n<นคXๆM$ฃ๗ํว�ลว}ฮJุ_BM�>๊ฏiม–|ญ๖T%#]หฦ5�R5ฝิๆtํฅปา ๘ศ๚/ูิ๚ชตฬH8‹�’8�เ�–ฺง๘ฆ7ฟจๆIฐฒผรๅ'$ฝ�š DŒ฿ฒz ๆa9ƒณŽ๒Dซ๚มส฿iิt z้s>fYณ–7BธุRวฐXŸอใv�๎�๋œรŸ ธydŠBามป BTƒฺg#K�๛Zื คYณะZI6ว+บHขฤ��m@๔ืi๔คO‘ม`ฤQ$Xไ–@[ชผr]vŸ5ฏ๊5ว๒Ÿ}P‰1qฃฯe8r‰๛งF อตะชฎฃถmถญ#�ฺAŽ7 x -˜n฿ิTอ Fั2�Y;MrnSฅฏึ๚xฒq�&ได˜2>3ึัŸ!๗กแช๑<ซแ[n ฦ\c๘g๓c�!ๆ๚b~9๑ไ“;%rX—–.}>ฝ =๗ฃ–ภ—# Œ{ เq‘ื�Xฮ๕[U>ฺk-3pแหAe™ํ๊Tžช}‡J �.k;•ŠG#ๅไ2ร �$L?+_‡ฆญ2q!ส@ฒƒuีNืC้VƒH๒||<\ฆ ฏฯใ\:wโ#อ>Ÿย| 9‰—v0žT5ร+ ชคลxฏ& ฃ~ฆคN|nย}c฿zฮ6d9@ฤสbœฬวYภ้ำฃ/ฌi[โfใfล�วpภ2๔daี]NชG ึ30 ฬ@$บศ†๑L‡l‘ทโF�ฐ>4฿RdcLqฑแeศ›C �yุงเc๛:zฉ๎†Eษ]็`f฿dาฺ๕ทถ’ไr2+ไ€gšL|คc˜•6Vจ�ฎ‡รัL}9o‘;@ พเ[Uะ]Oฐะ[QEQ@QEQ@QEQAซขศŒŽ.ฌ ฐ๔ƒกช^"ธฬ้ฐูY~a‹ใ3๔m w=Ÿ�•yU๚dขšพษ{(ลณ]X1๐รฦ๔ๆeŒd]จešCถWโv�ภฃฤ}รยฌไ’8ฃie`‘ ,ฬz(6$s ฌRว4bX›tm๐ฐ่GคzชดC•สบห90๑W‹I?กฅ=UOเ�oEg“อK€m›5p.1แ4งร๗GฆƒY๒น฿.บเa89 แ,๋ชล๋ กo^•mPaโC…4ัฦ,=$๘ฑ>$MM@ฏ'–q0ค•5”ู!_ล+ˆ?˜ึุiƒ‡2์f๑g:ณi7ค๒?๋yจ1บร€ฟ3/�WบB=รs}•k@Ÿ-3มวNั›Jส#ˆ��คFŸ{SBA ๐Dช‹์QjW6๓eแโ‡yžO�†�G๓ฒำsJฤ๓Hl‘ฉv>ฅ4ฒฬ2yFM๛ B#jAสศ��‰�ตD็ย&วขฒlVิ†UYQŸฤ�ฝ+Hปkว‘&™ฒ๔Ž?ห—(5��.3๖ W—x%LL8#*ถŒศบ๏ฏไก ิ๙E��@ื Š™ไd2l“ Iฆ็ฅ์ˆส|cO/�\ฟ ‰ฑ ˜‹ค ค›~1fu๖hยป์LXฑ ฤ, ’Iน,ฬnฬo~ฆนlIฤ๒lLาคk`ล��ฦฟ์ท้ ๅ2๑๑ฃ.!ฑ•ยJZ๚*€ฃื^หD˜8ผj $ayถ*๎.‹e“รโZน.‹›;?\Z0๋3 Xฑ๕ฺฝ‘ฦ98rฦฃ๓v“�ีo๊ธ,‘อ‹F)S‰?m˜ึฦย5๔?E%™‹˜่ปL=ฌจ}Ht`?ๅ[ุi.1หวd€ฆR�‚zคf’/@ืUซธ™=ถI7,lw%๕�ๆ mdŠ€ย์ป”x•๔�๕]Œฟ/ฮeฤฃห‰2Gฃธ‡ต'�ถถวW ]<ฌ1�ท^ฆ"/๛๊+<์็`e^ภปcทฌLท_๏  ฐธฝผi=<๙x€ฟz๛3]˜8jjGŽ9c,<าžุoq`ูKๅ�ฬ\›ูX˜$๖Iช}Œถ๗ะ;U9pหวf7+็ว—hฮวุ(ฐ�e�oH๖S๙ญ:bษ&>ฒฦ7ช�-พbฟฤ4ญเš<ˆ#ž3xๅP๊}L.(4ž |์~� I€2‰YXt> ิ8sOŸ%˜wJ ˜f�m๑?ถ?X{ลk|,Ÿ’c�O-฿Ÿี=ZwU๕{)ŒผTส‹cŽค4RฏลŽŒด ๒CM7ฯq๒�ง"ข�ฮฑส๊LŸฌ=}Eoว๒1#beG๒�„@ &แ—�คM๚ศ~๏— &I7cไ€นp�ธŠเ�2'์ท�tญyแHภ>k’—(ุลŠ;x๙ฮณ0๛—�k�ห๒_/ �&[ฎ:Ÿ@๙ํ�7 ำ63๒2�žๆ^–ดcษ๛SQผฏศสทด0ฦ‹ทา๎K๎Sฦ‘ฦฑ ฒ ฃะฐจ0ู$ศโWfฟฉ,}หA?ๆ๒yR�๋ว๚Œ�ฒัส,qaq“ Y?แ/žK๛B�฿Yโผุ‚sื%šc์su�ํฉ<พ_ณŸ‘_™&4H7ฐ-!�Yก@บ srqŒศ šd-'สdgY�๖R5ืิl5ญx~*s*๒9Ž��ณ๖ศัลŒž'ฆ€xT^3ๆๆœวฺฺi_Mล#oแ]i>CยไG•๓bวฤ—Aง( ฌแธ>9…žYd^I'j๔ภึฌˆธฑ้Yขƒšๅ๘ตลwสวRจLv?Yฎรฤ7 ีถAศD�wNท�v•i*GŽพšuั]J8บžขซ&ยสA๙,_บส�ไฎฦฝวรญ่4–'<# �pส๒ล}u๒ไ/�j~HŒž$ไEฎีL˜ฯ�2%ขขร”ร:e:nศุ๗ ฒH—‚ฏฐ[OJ›ˆPx๏•}{ &;R1P?–ิ็๘Fuืตถuท์�xœ่ŽN ‹ฎW|G๖ืฮ‡ํดใ—‰_b˜\๗dฦEoฦ“๒‰|P�&�ห;G�(%ลrqขzJญ่ธฝฉLIา ้8ญกง� lึa�-Yโฯoๆ0ํo–™‚~ไŸšฟ๋Z ๆเt์r)i๐Xณmบทt5๒๋jsฑ>oฦdชCร'ŠHบซงีXใ๒�o;.ษ˜็๐Hš0�Gช™V ก”�X\H5Y›$|fbๆ‹˜๒ํ๑.ฌฮฃษ"ฏแoU…�ฮุaLีqN;ั"�อฺ46๑฿�…TM_;”Ÿ0ช1‡\ฐะK+&„ฉรP฿ˆ฿ๅณ„ล1cูR:วกf~ส้1ฑโฦ…a‰Bจ๐ฺ๘šฐ0"ม‡ถžgme๕v�FšขŠŠ( (ขŠŠ( (ขŠŠลf€ขŠ( (ข€ญ]ั‘ลี = ๕ญจ ค›้โ“bc*UR]H�uฮปmเA๖ีf"๒ผNAŠ#šษ.ใ ศ:ซjWำก๗W]Qห Sฒ pฌC ู‡CAO‰ฬแaq๐œ…t[”’EE฿๑ณบู‰ฟJุr‡+ˆaž9"‚)%p{๙O ^šษแpง;”4/โั›\tฑ*ถoคั�˜L&่ฐตต>4YQG Œฎฅี•w ›}Tหสใb๑๋†NVZล��˜#mฑg„X๛้x�Žˆ้ทq,v]บ ๐บดƒใแ`ๅLŒฝ7(๖*ุPPฟ)ษOaยฏ$jq์ฮภ บศรNŸช=๕iฤ๐]” •ิ6ๅŒทY/ฉnฝj�lx?มSุ*Z ฐะVhข€ขŠ( (ข€ฌVh ชไxƒ9gฦ*…‘รก;1 s๏jฏ73‰2ล4eำs<ยF;มฺพh�Pโ�ŸถบšŽXb™JJิ่A ฏโณฑ�Iโฟiคหr„€3[Rš�*x Eษd@~ ‘gฺ?.Oะต†โฑ ซ#5สH7จฟแ๔EUdpYkš๙”X"wVU?ญ๗Z๔ๅฃ‹’Uฑ“ืภ˜H๛์๔gๅ`ค2cๅdG™vปH ƒกชEเ9, ๏’�$c๙o$ฎ๒ฦ—ฑEd"ื}4๒p นwฌ)hซ’อ�ฝร๎76ภะ(œฮd81แcฦ’fใฦi˜ฺฟ3h:Zดฦโฒsf"gyƒ-ๅšo+ซ_แ|ณJบฤโ0ฑ/ฑ73 ?›ANPGcฤ"‰B ๐kโjZ( (ขŠŠ( (ขŠŠ( �ูpydantic-httpx2-6dd59b9/docs/img/rich-progress.gif000066400000000000000000002207641526547463400222210ustar00rootroot00000000000000GIF89aุx๔***888IIIVVVhhhwwwŠŠŠ—‰–––ฌฌฌทททยผบษษษุุุ็็็๕๕๕!๙!� NETSCAPE2.0!� ImageMagickgamma=0.454545,ุx� ใDdižhชฎl๋พp,ฯtm฿xฎ๏|๏�ภ pH,นrษl:ŸะจtJญZฏX์#หํzฟเฐxL.›ฯ่ดzอnป฿๐๕c>‡ภ่Ž๙�ฐว�€:|[†‡ˆ‰6ƒ„u-u…,}Š–—Œ|Œ›z'~Yž4 —ฆงiš™’)‘tƒ“„™จดpซysธt' ก% %#N ฌ2พตสหWƒซฟ&™ฯฃ'ฏ}ฬฺeบy�ธ�ี ั ยมNy6ษ�๏๐Eุ‘*๓๕๖ใ๑๛Tรรบ�ฤ์๕€ม‚`็,ศฃpAG@`ฐeโ1šจG$TวฏคI”�์แณG …ซkOส<๒/ื7›รข�๒œŸ‚v,�ด0Bมบ|8H&ิŽ.ข[z–‹ฐsbห™Xฑ๖กฦซU'M]]ฺƒ•ต,>แj๚;F‘ฤQช้Hœ‹Kฮ`4Jฯ8I{Eฎe[น๛�r่–คูร๑๒้s;6ฆQฎaKึงfฺศTชs7ั-:นŸฯƒะ€้ฅคYย้ถ์H$-x0Gย™ O�อ ฆฌ•œแƒท๑=7ืโdซ9‚O�F?G—mWฉ฿ธ�z�โ๎ํ๑๏–ฐ1Šๅ�1ใเWมซŽV๙ธ๎๊�6u^ิชั`”๔XJ)aกQUDXw้ญg /™�' 6.$xเƒึ(ฦG/?้ท1 8$ิR๕ต%Z"pX‡�Dw1๐Aจข•ผฐJq์มธ"x�€N ถะูŒ<๖่ใLlb‡D:‡รŽ@&ฉไ’LVฑI“PF)ๅ”TViๅ•Xfฉๅdv้ๅ—`†)ฆxc–)!dfz‰fšeฎษๆ›pฦ)็œsบIgyw†igž{ๆIฆŸ๙๔ gj่กˆ&ช่ขŒ6๊่ฃF*้ค”Vj้ฅ˜fช้ฆœv๊้ง †*๊จค–j๊ฉจnJhชฌถ๊*งฤ*ซฌฏึj๋ญธๆช๋ฎผ๖๊+ฅซ�*์ฐ— จฑฤ&ซ์ฒฬ6๋์ณษ ํดพ�"‹จติfซํถ�v๋ญฎา*แšJ€ฌ€ฎงฤz๎ง๏zŠญก๓~k๏ฝ๘ๆซ/พแ`~ ˆ:ภผDpซ ๐iF*์i ,|์พWl๑ล฿.FQๅ€จ#Z๐มฉF0จ;�ฉษ'Zoฦ0ว,๓ฬ4๎ DPnฃ์ฌ(ˆl0=+๊sั”B,rฅๅF ๒า•ฒ )าพ�rอXgญ๕ึฮ†�GA?:ฎ „Tจไj@@0ฤMh496ซฒtp7 ‰ร่์ฃM่๔อ19า:-ฒแ‡ฐษX^ยำ‰Ž]6U�gCฐnๆข[อ๕้จงฎบญแ2L‚ฯ‡ๆผษม<€ิไภ([๐์่P่0ยDรr@ูย7jR<๏pลŸ๛lQ@มm?†๓‡}(๕ฦG€�๎ะ๓N๒๓D/9ฃทฯŒ๐(]จ.˜พ๚��๗๏?ำ‰"ภp>Fษyร‚Aจ�5/ ˆัVUฐ Kr๕#YมWAํ}Œฤช$ว0 โMจ nื3x0eแ{Z ตมไ=€†โ›รOถ(ูก+…*G‡ฆฟ�๑ˆH�฿ฮnG‚ั)*g˜›Hก๊ฑฒ+d‡*Xฤ %9�PwZ4�u;ฬฑฬ‹†า๏,‡6ห}p‹แศ…ฦ๛�aZลศ9D•ัPR@�ๆ B1‰ˆLค"3ถณœ1 Ždด yŠœ๑Xด™๘โจ0�Œ›ฃห$™ผˆy27ฌ฿Rfšš๑icฌc๎n๘<Š๙#% <*0wขƒภนศb๓˜ฺ๊ื-#`ษFๅฌyณรถเDŽIkŽ\Œุ “วมบ๑ฑQ{\ า๐HC)ๆฌ—T69รC‘“›นl^ํ)>t@’hฑ#%๏คูฑu™ จ@{uณpl ถ์กษ Pถj @ิ๓V+W~˜��,สล>fq�ฒร๔๖๖ถุฒ‰โ�:วH•Š�(้ b€RจคSyB u;€c5TT่5ฑ๕จHeี5Q(›„*ด ื>๕9oฎิa๐H›วN็9‡q๏หช\ธช;๔!0”*ซ QฤฅUC๑)8Gกžg”Aสึ:gHคJส�5ฉ€ ฌ`3ีH >ส>+kข ุ‰ฬ‰—b์ข$K*สfฒ4ฤ, ธL$๖†Duู`GKฺาN๖ดb�[ €ง&ี‘‰€L�๙Wำฺ๖ถIulj๋Uฎถˆ’o�*Z�๗ธีmd5k[หบsVณBฎt�ง‹HๅR๗บุอ.nญซ�๎z๗ปๅ.xวK�๒๒OผๆMฏzื 3๔ฒ๗ฝ๐๏ถ�+฿๚ฺ๗พพข/~๗ห฿�šJฟ� ฐ€ @๘ภŽl‚ฬเCอมŽฐ€,แ [8ปพฐ†7|� s๘ร ฮmˆGLโใzธฤ(Nฑ™ซโปX‘'~ฑŒg,ณำ๘ฦ8ึ—sฬใ'ำว@2#…Lไ"๓หศHNrถvฌไ&;YTL~ฒ”งŒฉ(S๙สXv”•ณฬๅ.ใำห`s•ลLๆ2OอฬhNsีฬf3oนอp–๑›ใL็ฯนฮx๑๓ฬg ๏นฯ€Ž๐ŸM่บะˆ&๐กฯอ่�.บัถ/‹#M้ ?บา˜N๏ฅ3อi๐nบำ ฦpจG แO“๚ิ�Eตช l๊Uป:ฐญ~ตฌ๋Y�™ตพตฎaผ๋^kฺืภoฎƒMlี ปุศ�ฺฑ“อlšMบูะqดง=ฺeS๛ฺ๙ฒ6ถทํ-ms๛�Kทธ้ํq›[Yๅ>ทบ•๎uป\๏ŽทฑๅMoฎตป�๘�oพ๗]c~๛c๗�ทภ ;๐‚ูเ๏VภฮpF-ผแ_sฤ'พฌgS�โทr-ฦ7žซ<œใ!๙!� ImageMagickgamma=0.454545,ฒ; …###$$$)))***+++,,,333===JJJNNNWWWYYYZZZ[[[\\\jjjnnnrrrvvvzzz|||€€€‡‡‡ŽŽŽ“““žžžจจจถถถทททฦฦฦศศศสสสฬฬฬอออฺฺฺ���เเเแแแใใใไไไๅๅๅ็็็่่่้้้๊๊๊๓๓๓๘๘๘mภ€pHfล$่ๆHAชYำ*Rช5€ท�์4์މๆ!่Sฌฤผ`ด8เXWูํ& ฉB€U 8%1_..7(O- "l&DB 13 T&#*9T1TIA!๙!� ImageMagickgamma=0.454545,ฒ &/†###$$$)))***+++,,,---...333===JJJLLLNNNQQQTTTUUUWWWYYYZZZ[[[\\\jjjlllnnnrrrtttvvvzzz|||€€€‡‡‡ŒŒŒŽŽŽ“““žžžŸŸŸจจจฏฏฏถถถทททผผผฦฦฦศศศสสสฬฬฬอออฮฮฮฯฯฯฺฺฺ������เเเแแแใใใไไไๅๅๅ็็็่่่้้้๊๊๊๋๋๋๎๎๎๓๓๓๘๘๘๚€K,/IŠ‹ˆŒŽ6IJ.А˜!›‹K>K—™Ÿ)“ŸŠ;K5‹šŽ‰›)7DžŸ%Kณฑ**ท›7<ŒฟฐŸมฤ2Kษงด)ŠฯธŒI"Žสฆื‹ฺŽ่้้จุใะซ๒)๏๐�๓๙๕A๘๙ซRจ`TBEŠDœgP‰ „vฌ˜่mแ*ƒ)–ฤ@!ˆE€)|๘x>ฮKัcุ:ฬP)oCE ‚0„M€3\�Xาแg> AN˜4šฯำงPฃJJตชีซXณj�สตซืฏ`รŠKถฌูณhำv !๙!� ImageMagickgamma=0.454545,ุx†***:::@@?GFFOOPOPPVVV_`___`_``gggpopwwwํNJ่\Z�WS๊a^+ตC=ตQCทV€-ฦHํฉ>�ถ?€€่ซN�บ@้ฌS}บ‡kน�_ฤ๓ห๏gศ๖sฬ๕xะ๖ˆˆ‡———ฟ‹ซซซธธธืŒ‹�‘ุท‰ภฟฟาฝฝƒมบสผาศฝ‘นอ’พำฆปรภฟภ•รูฆห�ปฮืƒห์‹ุ�ฬฬฬำฬหรำฦะะฯฯฯะุุุเ฿฿฿฿เแแแ๓๓๓�€).C„CA††BB‰Š„AŠ‹BA’“Ž…“…œC@œ‡„‹˜ฃ’C‹‡•™จขจฐ–ญ œฒˆ•คฃญก –›บฎ—Žฉฟ@ฐฦงนจอฆภชบคอีฎุฝฬทนรสธถฯผเฃ‡Šซ”กแ•ช…‘งฌ๒ณฑพฯญ“ไผพช๖ั†ำ๐ v/›6_�X๗๋-hนค…fm AQแ.๕S่ŠแฑY๏2ลปb-‹jLฤฃฒ†(๗”Hอb u่ภฝT)#NJ@?นƒEH(ฎBษ„|Z”์•ฑOKs๊ดะ(ีํšV‚๊L๊ฮœL2ฬhส“ฃO]%IS‹Niงซ�ห6ๅšถ.cฮ๎ ญคiXChั�ไ้1gQ€m=BB๛h/< ๕ฺŠซ–ฟtƒ ƒต›ตhCปงt>†|ณ^DW�š|ุiๅฉ•/ใ oฑฃพจูฮ6no๊sซqฏ,:cUฤคู๋่[wiMงฯUVอ8ฐ9vขฏสพKxท๐ฦน?ฯ�ปะŽล<“มาํใฤภ{Š $__�‘ืR*^oNจธ�ยdYร฿kฝy•ฬR๕–SŒแƒJั–˜ƒ€yี˜] ขUTTบ5HIƒvเ†ึM8œ‰'�ดเžW\[ั‡฿c,๕ลฅzmฉ3แ‚žhึiŠ0�๖ฦ€–ไf=~6ขZ$�gb•Dšฅข~f=‰d…Xฦข†l ž€S&(d(ฎ™"]คะ'^’G )fZ�•)ุ™Tฅ™f‰]b)TpฒHข‹u‚Gค€‘ญฒงŒ!R๙฿  ๊u฿VJฉWi}œฅž˜™ฮ'แ!Kอ' งฏˆ‰ห–Pศง๗ฝSn๚$‘ฌูaฌ•สJ�ญฑZ˜[”YซฏGๆุT งถว+**ซl…ิ๒:aVญ&�Nk‚ๅฺ้ญขW_—บา๙bฅำจXิ†์b๚ใซุ๚ื�ดํๅ%ฌ#�G่|E^ k_;bงIอ[ใผูโหfkกn้*ม<๒G๎ทถ�œlซ็Rkpฆ๗ซ0ทฃx๛0ผโฮZ.˜ฺ‚ูฐส๘n<$ถW 2ด๛~‹lษืชฏฦ๋š,ฯ๙rผ-ณ๔มร <๐+lบุฆ,t€ฐภซ[๖๕ยLPม รสoจ1‚J0ผ`๒ห ฒg3™ ซ™Žl๑ƒCž�jมา๊+Tุwk๊hอwŸ๊.ส*^,๗†ฉe�สnฅ-ช๓อ้ตฏช mเ๗R‚Cœ‡ม›โ=y8/?๙ณ฿$^‹nฆ๋�cฏn]œีเ/Oห๘ฉแZฌ8ฦ“๓ +ไC๚*tๅ[^�{ๆคGiธˆ�๊>.๏Œ;�ป[‘ _:ชล๛สผ้อBึ๛๖�~'�ผฎ฿Kฯ๒‡’=Wฺใ๎v’ส{๘–็�„<@ม��Cภร‚N3ฺ8@@f`�#ภ&ิƒ pํ @ุผฺฑŠ^\เ๚lบ  ]ัš�˜ม้UcS]๋>ุ7แ*Gท! ?จทำฅ๐\$Œœ�F?UีญoฌK!ึ<ุ7N่:HขBpƒ&:ั‰dภ็4(B�๐` คa)วถพXภ<ผกฆ&'Ejฏvฌซ›ทุ!ๅˆ\ฌ c(ร๊^W‰Xล6๚0„(ŒฃฒๆˆAŽ๐Ž’ำb/ธC6Lo๒ ‡ศถ"zpFดค์�EAี I� %d๘มะ€ุ)“แ @‚๐-hศ* ‘„ฌๅภดHส[VŠb์#qนฦณซๆ0syIZ๚r–ซ$แ3๕ุฬ:‚้ƒ7มD อnj“›ฺผม €‚๎  ฐFbส˜ตacP‚j2sB(ง=™นภg2š�l'5๏ผk๒rซใ;›๙Od๒า–kิเ1gจLOโPก๒d่%'*M.’ ]( ฯ’FsกLiTฐJœ20- VนตWB๐ัฬฉNwสำd๖๔ง@ตhPuสัŒ๕จHMชNm‚ฆ:๕ฉOตม}�O ด`H) @ di‚์`B?ยพ:!Y*5š จgฬชิ€ฌe…Y@N |๎ฌxอซ^๗สืพ๚๕ฏ€ ,O% าPJ`•ฆไL3pสฌา6}`สJสนฎาฒ@ภฌ`๗ชูŸvvณ2�์QE›Sฬ’๖จLSU ึ:5�P€ Y%@P‚  &่ชj‹€dŒ5๎^ะ€€๕Tง0pติu>iKค€ฒz=ํeG(�พ–ทง็%ฏzA;UฮŽvฝ์ฏ^๐€”ึ—๋1`ภล2–ฑซ~'4N ภœ@{ๅห`�ำV6šB„อ*เI–^ฐ…-;W gvภVฏf'ผเ๖F๘๐…?,โ‡ฤV๑Š5�YวvHa๕A†s „ˆเว@Vm,ี )จุ™U์เ]}2 ช[ @่j ภฮฉR8รถ๑…@์ Ue€v€‚2ำuอV�*P%wyฦ.^ฏ€kŒใำ8ฦ vฑŽY,a??ุyึ0ƒW,cส�๙ลŒVqŽม\h:ัŒ�3 =fHร—ะ•.๔ Cli?cZ†6๋} xB�Uฌห šว>ˆฌม›แAั`ซฐอชcJ�ณรธ๎๔ข}�็a›๘ฦ8žkg9YM_˜ูฒ๖ต/ฬiXิvจณ V o�ั(fฑถำ๎+;ณ6ฒผlƒ“ล%@j0€๏fน™๒W}`‚�เ0@jPVภ ธxฤ)๑ญ&€ˆ6@t  žH€“%,[0� ฿ฦึoฒ{ญ๒Wุ� วณธ�๎H˜วฺž๑ป›�๎™ปผ�*ฦvfำmnšณ�ๆไ&๗†k~ใ•+;็7๚ธฅ=tŸณ๛่ 7ิ{ŽjpcxิŽFด„}@XVGเฐDฯฌ:ะ฿ลฐ{�3dน†`ษj;้…žเื‡�^ฑ‡�{วj?ธฺxณฎ๕๋;ถฆฟžฮl�ูรŽ<๔�ๅ\์bgwิ•๘ฑsž๒ๅ๖uฑ+ํwฐ๓ฝฌ(๖๖เ๕fฟฃ�ั„5ขs,pLYปฌ๗8ฆ€P฿๚Kฦ<ฆ0ฆตุj�tk€hภ[�ํš}๐{›เขt�cN์ ง^็ƒf�ื—^๚ึo~๖|7zษ6yฤฆvฤ&จG ˆzฎืkฒค‡gฐv“&x˜‡€`ถVaw€ไvzฆื€๗7๘w�ทxฑWดg€^ว@8z*8'x‚ฤ�ฆfทRD‡y,๐_ฒV@ภ8x k\ใ๘e—‡b#˜y8l`ฆtx'€c€a&yตwwส†yQ(xถnฉงcดท^่yˆws,WœWlHH{V่…{v€8{้&lฮl3ง„h่yว…O(zQ8฿”{เˆ#0๗ฟทg่ืoืU:ฆ|[ur๐;pZ•yˆ๘„•–vู–m7tP)0%€b ถg์gr&0|k๘ƒ๑๗†งtsˆ„๊6vw†ธX€i‡k๒wuq๘‚‚ŒZ8‹ล‡ถจ‡ฝจrvศ‹จ‡^Œf({Ž‹ว่†ษX‹�ทv‹ฆG…Kˆ‡พXxฤXตGrุุ†”ล‰h๘x;J*wyลึ‰๕RŒ๔ุฎY‰q่†LX™G‡ํศ†aจŠ‡rXUx„ lฝื…๔X‹ปh—xˆg y‘™†G({)ืˆ„wธต7{l๘ฉWŒ ฉxบ˜Œ,Y“(x„2 $ะM;IจM2@‘†ˆ:V@‰ฐ~สgfSฆ(€ปๅhึ €(๙d๗w‘ู…ษ˜ค˜ะoฃh)Pๆทเ)ะUฌ๘{Ei…ศI“+้‘YŒ “˜•y—1‰Žิ˜†{9—่ˆ�’1ษ†ด(’. ‡žg‘G—"๙—ต่xtx-’“™’ํ˜˜-Y˜Œ™†๙˜*๙‘ƒ7™$W™ƒ)—™9‘ ้…1�ใ๔H“>๗Sฌ‰ˆ0ะฐ$W(๙’,้’G8—&้c%€/Yœ_ˆ†^h“Š7›™™‰ดูซ)˜[i‘ดนœ—7V‡‡y‰lŠ)ห้œปฉา)‘ฯIžฉcษู’๏๙x3yp3@๘‰Ÿ#Ÿ�9A™z;pˆRฉˆ>ะีE‰@Šส็pdฦ5f–UฅH—ํ9œ๔Ÿ:†  ะup :Uฉgึ ะOึ~Ry”ม9š๐‰žม�ฉžฃ)œัiœ“‰กyษœษข(hžญ™‰…๙ข\ฃะ้žs‰œิyฃห™ฃนฃฯyž' ค}ฉ2สฬ‰„6ZฅŒฉŒKZˆภ<ะQ35ภiZ‹O–‰=เp`เึ™ณ Ÿˆ‡GฅtŠก}JžwจDJ›ูiœษ‰จyœŒ:จˆ:—c•*จE:ฉ*YฉศI‰> จ™บ• i˜ฮ้ฉ—ชc”ฉทVIซฒซ 0ซ@๎Yงษ8V”ุซG‰u ฌ๗djœ์™ชูผjฅŠb—j’้‰ช *ชž ญ น�ลjคv๚ฃไ)ชŸšฌ )ญˆHญjญAบูšชกสญเjฉ�ฎชซไJคฦzฎงฏ๑นชฌ๊ญsฺช๐šซ ชชyฉ[ฐ{ฐ›ฐ ปฐuบฐภสฐ{ฐส๚ฐ[ฑ{ฑหฐ›ฑ๋ฺฺฑ ฌฺŠ[Gฒ&Kฒ‹hฒ,kฐรฺฒปV0�ฑ :ณ+ณ6‹ฑ5›ณ‹ณ<[ฑ;๛ณB;ดDKณ[ด{ดHปดIหด ๋ณNป–N ดS{ฐJ;ตสZตVซต›ต\KฐW๋ด^๛ตd{ฑc[ถh›ถe{ถj‹ฑo…ฑ�ถhหถr‹ตuKถt{ทxปฐoKถqKฐ}ห�ฒy{ฉ+ดƒ‹ฐ…�ฒ‡ป‰›ถซทH๛ธD+นdKนBkน\‹น<ซนUหน6๋น ๛”ข;บค[บฆ{บคkจปบฌ�บฎ๛บฐปฒ;ปด[ปฒซบถ›ปบปปผ�ปพ›ปธ๛ปย;ผฅผฤ{ผยkผศปผปซผซฝา;ฝิ[ฝึ{ฝุ›ฝฺปฝ��ฝ�๛ฝเพโ;พไ[พๆ{พ่›พ๊ปพ์�พ๎๛พ๐ฟ๒;ฟ๔{พะ[ฟ๘›ฟ๚‹พิืฟำทฟภ<ภ\ภ|ภœภเ{ฟ �ภ<พ�ืฟึ๗ภ\ม|มœม\ม ผมœภ�[}�๛ม$\ย&|ย(œย��มา+Cภย๒{€ฟ0ร๊ี'ร๋[ร๋มุ7ย*ฤB<ฤD\ฤF รkFk้พGFฝ@€ฟDP;LVLล๊K&ฐพ?์รF�ล`ฦb<ฦฬย%@@@Nๆพg์ฤP,ล[ฬพOŒล้;ล=ย@Lฦzผว|�ว~\ฝ,์ @0œฝPศึ�ฦำ๛ฤ ‡lฝˆ�ศเซลNผภ0lว,พ˜ผฝ’œฝxœวสข<สค์ม,์Dp„ผฝ.œ&`ล(ฝ&06 @ห`(@ตUะ๛ฤpฦj|ฟV<ฝ0๔4jฬฝ ฦWฝ�ลlลAฬQ<หะ๋ฐฬผหิปษิlฬDpอำ‹eว�ศั›จlลq|ฝ.ผฏ<ฬภอา{ห ม�[ส��ฯะฬย `ลซฌฝƒLขH<”ฝˆ`ะŽL„เฏฬ= `;@pัA0ลฏผฺหDฐ\๖ะ;เั MliŒO<O|%ฐัำ๛ฦำ๛าา3 ฐา 0ัQ ฐา-Mวึ›ะCฐะ\Mำ>Ÿ|�ี^�ี`-พ0|iผต,ฯV<าOห`ฬะ๋ะํศฏ�หสlลpัTŒ@ฝึอ�หxญฝžpฟvl{�ฬf6ศZlี}}ืs,ฝ-ฝzฝิ|�ฤ;PืXุั{ีQึวn �ศ!Œ}a]ฺฆ}ฺ_]ศˆMg]ฝƒผิ0)ฝVMลs-ฝŠ์ุWmว=าั›Aะูาซูี๋ะ0�T��า �MทŒCฐ@ �™ ี@ฝส��มญสq ฬ`ีฐM�ิ๋ะแ=�฿mว๘,ย!Œฺ์��๎อวชMMฯึ๋ะ(}ัlMำฌญูฏ์ฦแ�ฌ-ฝ็qั์ ไ\ฝzอOผล]หฎืชแณอศศญ�P�เ�*]ิ�ฦ nูู;ศ๗ฝเพ฿q�์ฟ?œฝ ะฺ๏�โ.�โฬยะ;ศƒL฿ฎM��9„ํฬg�u]เvฌื์ผฬฑ์�ีฝเฝปผล‘]ืฑŒุ ๐ฤvŒไn�P�ไ๘ญีฮ��vผไะไ‹�ม"ฝ ฿}ฮฎีŸœฝgฮโ0็r>็๔�มF�สi์�hm๐ส•ิJLฝ๓= `ัV^ๅŸ ็ื‡ี€Œั ฮŒลŸฐ`ฬnเnฬMแ™ฯk]}า›่—๎ืƒ  ๐าUŽั ้ไ�~�แ|~ฦ.ฝจl�l๎รŒฝ็Gหt�๋ภ์้หย`ไฬ-pื!Nั(ภยอำ[ฯ�o์้WNอ!mล�อะฎโV ลPํแุ-าžํ™mอ- ๎q��+=Cภึ*}ฮต=ฝฮฬีnะหNฝอู๊�ฯผฎเ๋ย>๐_๐ื฿ˆ<ฝƒฬˆั, ๏ฤpพภ?์,n๑๐z ฿๐Yอ๏�สิซ ๐ฟ๒,�๋‘ฬฝƒฌลMND€์๓ี[[ปl๓น~}ขŽฝp�(ฏ๒-_๔F฿�๓Dเ์า๋ฬ]n๐ƒผใM้ิ�ล�~ฝ@ว)Ÿ๔G฿๕^OสOพภ๕+ฏ๑�ๆุ[ฐญีD�๕n�๖๖pภมLฝ ะ๖sŸ�๗zOฤrฟ๗ฌ๖ีปx๏๗„_๘�๗†ŸฟY?ฝม\/M๖‰๙’?ะ“oภp๒zฯRY%Pเ•�๙ ฏฟˆ๚๎{๙ห๎N๚ชฟ๚๓;๚ฌŸพ%@. ฝ;ภ๓ฏ๛ธ/ึนOฟ ะkQŒdป?�ฤฏฝฎ_�เ‹ำิ<ั;๘ศ��ท�ะพR‹ๆำ�ั�๏[S-�ฺ��p๙เ?�ไ?��_�่Ÿ�ค�๊฿�๎_๘์��๒?�_�๔�๘_๐๖Ÿ��฿�qพ�€ 8HXhxˆ˜จธศุ่๘)9IYiy‰™ฉนษู้๙ *:JZPŠšชบสฺ๊๚ +;�K[k๛xzซปห�๋๛ ,N^~)`žฎพฮ�๎.์�.?O_oฟฯ฿๏�ฯLภ <J ย… :\จ๐กฤ‰+ฆ‹h1ฃฦ“a์2คศ‘ซ>’<‰2ฅJ\+[บ| Sษ˜4kฺ48๓ฆฮ<฿ก๋ 4จPv9‡=ŠYัคL›:ต๔ฉิฉTAEญŠ5ซV–[ปz� ้*ุฑd™Š-‹6-ฯณj�บuษ๖ญ�น!ใาฝ‹wข�ผ|๛�้7ฐ`‹{>Lฑโล 3~ นšใศ”+{ดŒ9๓ทษš;~{–ล๙ณ่ัจB“>š“้ิฌ[KZํ:ถ์|ณk��๘ถ๎�“`๓��ู7๐แ˜…?ู8๒ๅˆ•3ุ9๔้xฅSฟ�ึ:๖ํhตs��ี;๘๑Yล“?/57๚๕อูปo�>~t๙๔๙šฏ?ๆ���Wช๏เWH X์W`‚!๙!� ImageMagickgamma=0.454545,ึ&ƒ***888IIIVVVjjjwww‡‡‡–––งงงทททศศศุุุ่่่๓๓๓�ศIซฝ8๋อป�`(Ždižhชฎl๋พp,ฯtm฿xฎ๏|๏�ภ pH,– ฃrษl:ŸะจtJล “ม#€+n„+P(พ+ouอnป฿๐ธI10‹ฤkPจ7,‡„+ƒrŒŽ‘/t  /–~€‚zcŠก’งจฉชซkX [ \ฃถฝฟ ‹มลร~ท\ฆวฌาำิีึค ด� ‡  ห ๑\ฃ–xฤ๏—}ผ๕ 0 _7 !@ ��UH&กเก๚$ศoBภC�-„+0.“9†ˆนฦฒฅห—U(๐vhY- x—ฤ)  2ษLฦaiภฏภ1G)�`เ$ฮ$�1@เ้ถr˜ �๐'gาฏvQ`jภ้ƒ•UฏV%k" 8u๒`่nƒM0 LX‡+ ฌผ๙@%/“�q™๕j�ผЇ<&dˆิŸเ=ึ†กAƒ[‹ผa๙ @“gณle�Lb็Š@_ยL*๊g"C…,ๅยศ“+_.Bฆ„ืŽ3ฬา–[B_็–๓djัะล@w^แ62B฿'„ชNฟ ๎Rค˜^kPCซ?™ฒย๔ ี๑�ตˆ฿0gเ–MZxC^haVŽV*e5A.ฤ|‚Œ๕mŸ†��u7๚�มแ[๊ๅ  ฌจ›6ษจ%A‡แUฅZB"f"—฿„�< ลƒs ‘เ‘H&I…L“ฝe!ณ่cIF�`ฒ๒6Aj>๖โ–=–ง!„จ†ู?ณ !2ฦH‘™๛�็;œ๙dEDYษT^"d ฉไ „๚รa๛(`‰• Y€%€M€ษ?uภVฦh`"ิ;ขตฆ.9€O(L™๑ฮ‡|ฑW›ฯdrฉฆฆŠฆEv8ฐHYข"ฒ–hฯ9๓จU�A) p#จกศ&ซl ู�`‘€@ �ศH ุ@UM@เ!�๑ส0�ัX~0~Z‡ญ+nG๖i„ขท™nyัแ5มPV เภ„๊\r€|าKTต •ญ Pภ:ห6์๐ร,ศ`าฉ‰Axภ`m;Bว€ƒศบxฬ‹ษผ\Iูฦํšp@™ C,๓ฬ4๛าAƒฤCเม ใ์;Ÿ€) ฃ\๓ัHำ์๓ฎ]สผ4ภM—๐ฒG1'm๕ีV“Œ๕ษ*LMตั[‡-๖4e”m๖ุ@$\Aัhทํถ*f˜]๖�< m�t็ญ๗rŸฝ๗ ^ฯ˜ฐฑnธ}ฯ}๘ j F $Œภ+‹Wn9˜‰ภ๓ๅ* =T9๚r.๚่7dพ9้€ฦ�6าข๎๚๋'$�*์.Ÿ†ฅŽราฎ๛๎ศ~:๏ˆ๕œ �๑ฎ—ญน฿ศ“วฟ7/=็พO?B@ฐl�๖•›ฮ�๗เ[_}๘ไ—Oปูหฯn�๚์w/{๛๐วฟw฿หหo��b���ฯ\F๚Š๋Ÿˆ,�๐€Dศภย$!๙2!� ImageMagickgamma=0.454545, ม†<<�ถ?€€่ซN�บ@้ฌS}บ‡ˆˆˆ™™™ฟ‹งงงฏฐฏฏฏฐทททืŒ‹�‘ุท‰ภฟฟัฝฝƒมบสผภภฟาศฝภฟภฤึดลฬดหีฝะูฯๆŸะๆกฯๅคัๅฒุ๊อออาอหวาษัะฯะฯะฤำฺึึึ�€(@‡ˆ‰‰))Š’ˆ-,“›œžŸ กขฃคฅฆงจ9ช8=จฎฏฐฑฒณจถถ;;ฝพŸรฤ<ดษสหฬอฑชะ?า9ำ@?’ :ฮข::!#&ข #ษ%ฒ#ไง งททฟ๓ลล�๚๛��ฏ98โศa# มUื—H‡D%@์sPม89„q„DZ Bศj๐ฑT็JนปehR ๓~Ešฤโ�=M�r๊�ูOUŸ@mุจ!ด`E R"2Aภวก9๕ก-Y‡t ภ:ษฤ†$G้pฺIAINd%uC–”6�ชํ๔@€€ท(l๒เKƒ_˜ฝ‚Mฒ7ฌBab๙x*^ฬ๘฿P #ใPD€"F^ Y ๓ท ะa".DžrภˆŒ ุa€mv ( ๚้� ดX€ภ๖ูC :7@ ั‡œc๎ว:Fl†ฮภ้‚  ๗Rข๏Zy;  ๔4 „ซบ‡p+ยฆ }�ๅK›ุtOฃดฒ˜‚Š1ศ“ƒ9ู„Dอˆ(€�yE‚>„€ฺ1C `=0ฐภ$iฅ5Iฒแbˆ"b&P‚S ฤๅCr� Š์ˆ�‚PีSŒ รsม'%|&€#`L๙Pžู@ฮw@„pภ<ภวQdB%R`–$4T€&่ฐภ>ไvˆ์ไท_�uำ_€u@เ$ลv *ญศJBฐTZ ฆฏhJ งฎx: จhาส 6�๐“ช7ด๚SQ"าชญ0คฆŽ๐เT€จภE๕เT !$kBฒฬ6›ฬฐ€™>๐@€6 8Pmฎ@rUยต#8 bแภ‹>0%W h bต‹ศ P@4@@›QuูJิก‰ภ‡๘@ฏS<š@ฏˆ$&y&’Z+=�šn7ฝีuW^{่—/‚U—ab`ม(N!sสฟ"ก')S๊rห/w๓ส3“Usฉ*›ยฒฮ›@ˆ๊ชCตzCQBYˆ0†#ปซบญˆb— r)nธฺถ<‚ะ€t�ต^W:d 0เภd‘ฤpž0p „Y 2น"_์Y๙จณ LEฝ3oืึ#˜ล@เRปฬœ l`]ม@`.Wว๐9ipN= ejฺธ’-'ศZฐ/} ุข)kปฉ”<ฬ.“NVZ ‚ฃฆSMฅ๑ฦW�ปฑป^๒ี�|หฎ/ฒ๒ค3O}๐ะ๛ }ี�–"ฝฮพ7o๊๋ร_?}๘ใทฏs๑,‹j@5mฟซ3;•้ใเƒ �ยัฏYDnษ+X๖Œ๗ฏV0 เซ”ˆ^ใ2ศอ,ฦ๊Qv๏ ){Q�J@บ๊Ž*๐๒มV*•ย: ษaฐ(/‚ะ:=ฑฐ†…D%เŸ๐zไฐ ~hoWQ�J$P฿ ohT_8ะD๏๕<ฐ@ษ,เ+—�@xไ#ˆ|U<1 ๏B`D฿{๐ล3๖ฮŒd|žก'Gๅ™ั‹i|ฃใ8G7ช๑wbฤฃF>๖QFฌ#ˆ๔ฦ์� 2ธA@๎g?ิ@ฯ๋รุ�ๆ .™Bิฐ jHD„ภ6–4žq*Œt™SพEยesค`Uธ‡๕ฉาCH‰ฌแ  ฐนN6ฬ๋1)_ฤk‘(X :ุภ:Iซฌง9ฬ$๗ง”~ ApV€œ๓:่A…ธฤ”Œ:xA็มฯwŒl๏a�s๗<คฝงศมqŽูำŸ" ะ†สrE่D๛XQ1:ฃfŒh-บศ�y๔ข…„จ๐ฦขฟ์ER 8$L')FnDž$3  ภzเ"๒จ™$]จiY-1>Gš�cๆๆ�ฎ tkะY€ฏฮๅฝ›ฎ”�aŽ&…:ฑฃ๖ฒ�I6 ธศyฌ?tNVทฉ0่„‡mDb˜ ŸQลXค!ด๒T้#2๐ˆ๘ช•�ะไJy๐K`โืฃ๘Lm7ฬY�๕tภเํA�ุๆ�ป1ฆฐซ๕psๅแ�J๘ย๘ญ1HWen o!"y$GEYVa^khpmws!{JJJSSShhhyyyˆ$™(ข+ช-!ฒ/"น1$ƒ"&†'+—,- //ฆ11ซ33ณ5Š$†’&Ž™(•ก*œซ,ฆณ.ฎถ/ฑผ1ทร3ฝห5ฦ‚‚‚šššจจจธธธสสส���ๅๅๅ๖๖๖�€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“‰@(…&F”œžŸ กขฃคฅฆงจฉชซฌญฎฏฐญ(@†'šฑธนบปผฝพฟภมยรฤค@ดƒณ@Dทลฮฯะัาำิย‹ ีฺช–(%ADว��ๆ็่ย๋Š๎Œ๐…๒๔ญล๙ฃ7??; 1ธ‘รƒ ?ฆ[ศษŠ#B@0ยฐขล‹ง`ะจ# 2jิ ‘‘๎t่HHฅH–ƒ:ˆ”แ‘‘FŽ5mˆA(CŒu0bฤ€ัมžก +\(ภ(…ŠงO (ช ‚า|PUTุgˆ ฎŸ๚}h ใวต7B˜ฐƒฦท�‹Pัd„"&เ๊�หืฬ b \ิ!‚0jไ$€AfˆT@H&‚�%พœ™p ภmr6œn:ก€. ,Rฑข‚ํ ฒมŽ0ˆ…‹|-TLจ�PD ๘1B!–_๐รƒ}ณ)bท›‰!ูร‹_( ฦA25ฺ้โq‚ซฌŽซฌ˜ถS+จš~š’จœ–๚+ฃฉฎz๋ฃ‰&�jฅฬ.๊์ฎ)…�ฉชฟ๖j*ฐฐjk-ค�bjฉฒด’‹ญด„Rซ๎ตจถฃ*ฃญย{+คฑโzอธฟ–‹๋นป๎{ชฌยขสํซ๔�ฮKiทยเ:2ภƒ Žd๐™!2(HD ฒ1ร0ร‚ƒต�r"'q์๑ฬˆีงiษ3 `@า#ธภิlJ ึ!)$ล[pฒpaัข&!gN`@GG๒'v2๐๕#ุpC € "˜`B nว w�rำm๗�v็ํ6�z๗ํ๗฿€๋อwเ„ำ=xแ‡aDo~ธ฿.๙ไuS.yไ€?Ž9ๆysn๙็}{๚�Ÿk๙ๅ•็5ศ ช&๋ฬวŸฦAžœ2ฐื {๎(qะ N ๊�{ฮtฬžศฆmTƒ F 4ยuพUฅH ฌย๓Eง” �*,MA `™%v6๐<7€๚p6ฐ†”`��๗7�8�p๗ฯ��๘ำ฿� ๐6pฐ฿�๘ง@’ށ�3`�A๚‚Œ ˜ฟ–  7่มNpƒT`K˜ฟb๐…"d W่ยาP‚,ดแwˆภp€*„เ[8DЇ2๔a3จฤนQฐˆK�แWh?)fh@b„์ Qž’eHZbFึ—1e%ษ"อฦ˜F h ๒ุ|Lƒd€ฬcฤ๓ข‰3%G7๐ ถ๗ก9`,XW `ดB z’ฤˆz A่ ’‚@ ฺ�เƒไ่“  ฅ(U1ŸTI(‹0ŸC€qฅ<%ODfJAศ Jˆู-Jัheํ™#ธ$ˆ!น'h#qœe2 7J‰ภ๓๒q50ˆุ7สvบ๓๐Lสhเ‘�," 3ฤยXค�ณž๗๙งคฤ�)ษžข9ฯวœไ3(eวD„ X@‰ U hZ"@>ด€CА›Qด?F" JลูI ! ‰งLgJำ%&HฬbtJˆภ@ฝŒ-Mv2ˆ, จ‰FpสS,5งJ„F#๕@u1†€ม์บ%(ฅY๘ค)อ๓@ฑ!„€๘ฦฌ rๆ4ำค‚ญ%e+เP!T lB“ภ�ก"D :๐Ajสุฦ:๖"ˆHvFˆP†P“ฌzjvษfถJ‘U�1#;ูˆฒฌ—%”g)›PBSyงแงqพ๗ฝ‹ ย7omYp€E`ขๆ๗T-M)hม๗œ๙อpๅ๔{ฌtงK]j ซ„ย๎! ]F ต'ำฎด‹ู๒"p@^P ฝpยวqซK฿๚ฺ๗พ๘อฏ~๗ห฿�๚๗ฟฐ€L฿@!๙!� ImageMagickgamma=0.454545,, †' 5 = ' ) 25<& %43><&&&:::E PWhr}!@>HVen o!"y#FDXVa^khxt{ xJJJRRRnnnzzzˆ$—(ก*จ,!ฒ/"น1$‚"~ฐVmัXv&‡(+—-- //ฆ11ซ33ณ5‰#…’&Žš(–ก)œญ,จณ.ฎถ/ฑผ1ถร2ฝ�jฬ5ฦƒƒƒ™™™จจจทททษษษ���ไไไ๕๕๕�€‚‡ˆ‚…‰ŒŽ‘’“”•–—˜‚)D(EHDฃ)™ฆงจฉชซฌญฎฏฐฏ—ณด“ธ‰ถ•ผฑ‘—ม‡:Cฦ=‚;< ‚CษฟำิีฎD))KFJึเแโใไๅๆ58๋“ 4787 7ธ4๔ˆ๑5�๙ปQcมค๛"q h Z3hะ˜๑A$ /2RT€EฦรJ€p"ศA=tŒ2 €็bส|•B‰’K@rbฆฯŸ@ƒ m๕aƒ‚3ptดว  6X$G;โแ0x่ƒU๐py56าุw๗ %ีpศZ�7hl่`ƒaค /*P๑bุฃ, Lฬˆฤ`C2bฤฟC#G&’D็('ŽH�ฬนณgs p4ˆ4ฃiปh|ะฐ๕PUqภ~๛ช#ฺ<ศV‹ใƒ ะoุ๐ ภ�TF^:๐ขค อA?€h@‚ฒR๑็๏ๆN่!‰ ›เำซ_ฯพ‘ืใˆชฺnš+Z Z bMฏ)†ฌฤภ:จ5ย�ว[pบwqเ y ‚ ‘\ะย!ผp $ไ๐ƒยLC‘ƒ$ ด่โ‹/ถ'#$G„ฒDO3ๆจใŽๆl`U$M5ฐ l%Rqˆไ�gมี0ร 6—–“PBย$-U๙HD8ฐUWpร ภฺ|๐ีย ิ=ื— ฉ ˆ<ม „จC"ˆ€ภ#แ็Ÿ€š:š ใช่ขŒขยZ’ฐFC xUค ฦ1ขไ!J)@งบyฺ้#^๊–8šดธตN ๐1‚ั ,@ึH.ฌ0Fน"Šฮ(’";ฐไH2$ซ์ฒษฦpยณะF+ํดิVkํตุfซํถฺšภ-ถ&„๎ทไ–k๎น่žเmบ์ถ๋๎ป้ฎ ๏ผŸ<ค‘โ`.น๖ฃฆ๚ทีDษdSํlฅRG‰*“Oฒื �lWฌ‡@w^-ุสˆฒpภ nV7L‚๐ "Dง0๏ฬ4ื<๓ธ6็ฌ๓ฮ<๗์๓ฯ4›๐H~P’’๖าo#›๎งฏ]a๕ด Q?ยZ]Tศศ Tีฅฤ<๘[—‘ผP2…Xโa"ฬ @A „3=ภ|สเMx็�๗�xธ€็=‹�ƒ๛M8Š๋อทแ}PธแH๙เ…'๘ๅ‹'๎๘แ‘g~ธ่˜3.ธแ๎8็7�zไ„{�๙้ซC>๚ใ”[บแคฯฒ๙๎ข๓ฮธโy/๙ใช/๎z๊ถO~๚๋ฅ{;๊ง๏ํz๏ลใŽwๅฺGo;๓�Šฏ<๑ว{�๛์š๓ผ๓#๏}๒WM ึ‚,]S็งิ}ปๅ7�ฐฺ:่Gp ฅ‘Zซˆำ”K�ชB‚x*ิษp†P"นมŒ9€@4Eยš๐„(œ„S4ภB ,Ka’เฃซ‰iณ T๊ท$…IY€๗ง4"๒Pˆ?T พœ6ฑh i„ ZเŒคํ+ˆฮ!& ผธiฦ0ฦผ'e๔ #Hกืศฦ6ฒวk๋XGก๛๐pE๓T#hGQ…๋ธ”I6Dธ…๑!คqภC€อUqฑฃ#เ‚Œ˜-g2"ฒ8˜‘’=%: แฦRš๒”จ์Œ–โ่bฌ4Z,p”Fฌ’iณด† เฑ8'เๅ!!๙!� ImageMagickgamma=0.454545,, †* 4 ' ) 25;* )76>=&&&:::HXjsz B%@>HVen o!"y#FDYVa^hevr{ xJJJRRRnnnzzz‡$˜(ข+ซ-!ฐ."บ1$ƒ"ฐVmัXv&‡(+˜--ก//ฆ11ซ33ณ5†"‚’&Žš(–ก)œญ-จณ.ฎถ/ฑผ1ถร3ฝ๎d†�jฬ5ฦƒƒƒ™™™จจจทททษษษ���ไไไ๕๕๕�€‚ƒ„…†Š‹ŒŽ‘’“”•Š'C&DGC '–ฃคฅฆงจฉชซฌญฎ“Žฒด…ฑฐถฏŒง ; ‚ 8:‚ B ปฬอฮจC''JEIฯฺู����฿„216็3ไŠ5ดใ…56้„๓5๖๘๚Œ2แdศŠ!CFŒบPมขลŠTP‘!B„ุC„vˆGฒdชI’ˆ ง!ภ`๋ญทกซฎธ�๚B ภ+์ฐฤk์ฑศKBฒฬ6๋์ณฦ’ ญดะVkญณห^ซํถ�v๋mณู~+๎ธ�rขHdPa—ม‰DถภfC)rจlŽล�Ž2’xZ‹ไk/ฟ“q ฃ˜ฝC|ล)ปฑภ *@b*:�`dq]‚่€C!๐รญ-น$—lrฒแ"›๒ษ,ท์๒ฐ+ฟ,๓ฬใฦํ"ๆhzN ์.b”ษ›ู ˜%wE“ล#I-Ÿ!1l ‘4› �ษH€( 2A  8ศ\6ภึ? ๐ร1;€rฤM@ดdw�ท�rภ7}ฯํ7฿q0€฿ฝิ๘�rำ7เr๋ญ7ไ‘รM9y๏ wแƒ๏}๘แ7บ/}๏Mx�zg^9�—;8ๅชŸพ๘ๅ‚วฒ๙�ฃ;>{เบ_.9้}‡.w์ท›๎9ๆป>z๋oน๓ฌ—^๗๋ร๓-ป๐7ฏ<โบc_ธโ�พำ |ๅŒcn}๑อ ๐y๒ธ#ฮผํฮ—ฏw๔Oฯ๘่น7"‹‰ฐ €wใ1ิะ“์„ฆ€ไ๘™ะ ่?œmh3€w^๘h,Hม Vพbb„เ’Fิ2•MO(Lก WศยI๐LัษขhZดH^MิaŽภGVen o!"y#FEQNYWa^jgvs!{JJJRRRnnnzzz‡#—(ก*จ,!ฒ/#น1$ƒ"ฐVmัXv&‡(+—--ก//ฆ11ซ33ณ5Š$†’&š(•ก)œฌ,ฆณ.ญถ/ฑผ1ถร2ฝ๎d†�jฬ5ฦƒƒƒ™™™จจจทททษษษ���ไไไ๕๕๕�€‚ƒ‡ƒˆ‹ŒŽ‘’“”•–—ƒ*F)GJFข*˜ฅฆงจฉชซฌญฎฏฏญณ’ตˆฒ•นฐช>Eย<< ‚EผฮฯะฎF**MHLั����฿เแ 5898 ‘5้8ต๋ํˆๆ6๎‚๖8๘’๛�8ิ8$p5h|ธๅจ 0X๘šTกEAหz@p0B‘%ŠRBœษ“ฎT0aก JP œIณฆอ›ฌไ ม`ม†Œ4˜หฑ ‘€ อA๔ะค สีzบ!๊  ‹จ’‹๗ˆF ƒnไ˜…ฃฦx!ฝha`ยฺI� ^ิใวข"QศDœ€Y๒RI+^ฬธq76*ี๘ ก)ฃƒƒ&W.*่(}9>{�ูัh๖J7๒๚Aฆd[€‡๕soิโnAŠŒธ›ฌ ผŽ“‹C๑@„%‚X*ŸNฝบ๕ฮH/)ฐŒจ๗Y�9ุ#ฮ7x�Qๅt์ำฎ>7หl8d{ภ้ย‹AภpA$ผPมo@€W >๔‚ <๔ CA่If˜!rจa‡jจแuŽ%J2‘จโŠ,†๓ั–$:‰wˆ ฒ� Œ€ 4ะpรl\)d@>&�tค#}…_ >ๆ'yช5Rม Yร XA€B?�@ยEˆภ%ฤภC#tไศDิi็xๆฉ็†ดˆำ LัœŸ„j(*•ี`TIฒ#"ด-๒่l9)@tP)mš>าiุื•@zGYLกW�!ผภยบ ‰ ,เ\ Pุ'>$Ba<ˆิH3kฌฑC$›์ฑส.{lฑ2  ํดิVkํตุfซํถ�v๋ํทืž ฎธเ–k๎น่ฆซ๎บ์ถ๋๎ป๐ย๋ #�]%f‘LŠ]R’rืฃNIูC)ภจ๑็ศฟู ฬค=Yู,7ะเำ ‘�uษยZฐภฅ#ภ@~ ภ2; r� =์'Bจษ ๑ฦ,๓ฬแv{อ8็ฌsต7๏์๓ฯ๐๖ฬํ ่D•ๆห�ฝ๒!2)y6ค…ะx9� uำ‹l€ƒี‚LอdG}๕0~ฒ1€รŒ“ผ`ม#Aไ๖oB๔0v ‚‘Œ.sภK>€xเ†๛r8…�wเ…€ˆ�=๙เSN€แ•ฮyๅŒpxไŸ7nyเข'�8ใ›+>๚ๆŸท>๙๊Žว>9๋ข nx์‰็9์’ฟ^;่—k~{๋‡{>๛โฝ ฟ�๏ฒœธ๊ฮ๛ฮz๔ฬ�m}ํซ3Nน๖�‡y๖ก/n๚๊‘Ÿธ˜{z็ฯ๏;้่ฯ๚๔–ืOธ๕ฆ“ฟฝไถ๛เtw:ว9Gcšฃ–ๆขFƒุNy0šํ ƒ‚กy„ำqšีtภุ๒#‚Qa:ฤ_1�Lฤi€„ณฆ– e jฦกvศร๚๐‡—่QRศรฏฎ]0‚>Aส�#F( ‰`€;ผฒxeŠDฑโqลCPQ‹๙ธฬ1Bžhภ\yฤ$็–ZโbsAฤ!a!‚ุ�Šแ!ˆ€ ค ้'ฏ0ลˆฐมา ”ช๖DjŒLUZIดQ2Uh„XQpˆK2%“b<ฤุฤrŽ8-p�ฦแ2โVˆ๚ะ’ธฬฅ.wy0+ฃ#–ˆ SOdD0xฬhภ+Dโ๘ˆ@!๙!� ImageMagickgamma=0.454545, ‘†) 3 < #' ) 25<% $75><***777C PWjrz B%@>HVen o!"y$GEYWa^khqmws~ zJJJSSSgggwww†#˜(ก*ซ-!ฒ/#บ1$ƒ"าXw&‡(+—,-ก//ฆ11ฌ33ณ5‹$†’&Žš(–ข*ฌ,งฒ.ญถ/ฑผ1ถร2ฝ๎d†�jห4ล‹‹‹–––จจจธธธศศศููู้้้๓๓๓�€M+…LI…(MFHL…FM‘…MG‘‹+M‘JK—™…›•จƒšŒŸ…กœM*LHK*ขคฌ‘ซ‘ฎ ข)ณ–ซ(L„ฆŒจ•‚ษ‡‰›Žฬึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎�‚*ลฅJLL๔’”•—ฯ›"ๅ ภฉkรRXส'K ,aM” ฆ‘ฟ]…l8PE…œH8/[ผ’ฐ๎1|วฒฅห—0cสœIณฆอ›…Tษ�ทsd“%MšTญุ?Fรvˆถ๔h6E„$ู”t!"Aณ.mบจŒWAŸJฃU0•ิBH6 PI็Pb�…†Šณฎ�ปx๓๊�ห—ฏ #)&)AQ%G$จPศี ฃK˜จ@‘„ ศฦ™-•\ydษ”-ะุ„ํTy˜—ะd"ศั‘'O‰๏–ฝญL83ู๔5€ฟ#nbธฏ๑ใศ“+_ฮ�%ึ&ญูV๊ค•#่„R‡T]ฒQŒุ<�<ถ,๗&�ฆ=#๔Ÿ‘ฬw๏ู้ง„%H ัฯDต ี�๖^tจฌภD€อ%จเ‚ 6่เL๑HวL,ึ„ฺXxކาี‡�xh‰ˆ–ผRVืP๘เŠ,ถ่โ‹บ… ”}ฃq2VBใl7๖่ใ@น>YzBฺ�E$3G๖”ไ“PF)e8ฅ]uๅ–\v้ๅ—`†)ๆ˜d–iๆ™hฆฉๆšlถ้ๆ›pฦน�ZZCงœxๆฉ็;|ำง6n(*ƒrS่‚ิ้€Eัร…8ฐC!๒@์ฉ้ฆœvำA9เฐม6 ิj ‡าม  B  Bจ6ฤ 8ไP+7ธ๊j+6ิP จ@C ศ~*3`ะBจ4๛,7ด -T@?hท…๔ฐC Eะ „ ฆซnบไภณ. 50ะภ 6X#€ป…lk T2๋ ิ€รŸ ธ[๊มฺฬ๚ฎม๒›C‘��CŸ๔rะฝ�L๐B 1P‰ว ‹ฌM/ด`ภ0ธPˆE8PศE„@Ps @ิน๎ฯ@ท๙…4รฏึppt!JS,ซฐ…ิBปฒo…$Œ๕ีY็€56\ u6ณาPศ ๖yช2œM ,Lr%pหmr6ภ-ฤp' Eœ ณ7“PA7๎ธšํr`์ ฺl ฺ b๔ฏ}*p$ํฦŠvย*-๚ฉู„ภ่P_3+รค l๐A�@Rภ�‘่ฮ{6ภ‰1\อ`B;ภC2„� ภ๕ุ_Ÿม๖�gฯ}๗�ุŸA๖ไWษŸE ษ๛0ค๎ ฟ๛๏�฿~ขิ�w‚ฤฐ–�Uใ~๒;฿j๎GภŒธ๏~๙๋_๛ุr> ึฏ L �๔'ฟ๒"QํƒT๛งม>Ap๖K๓7ภฦ๏|๛หื2šBp4 !�๔็B†p}ฺz GS@ึƒ%ไ`P่พJ!ฌแ CR‡๊ ;˜B%ส0†L! ตุB#ฐ}I�aqhม2PŠmฤa๏dB>‘๒ณšถ6(ซXฬiุPฺŸ>eถJุ v•๐\ี๐ฉ>ู€4 œ PH ‹฿!i�pIืู ฃขืลfว6ฅIŽZฟ‹ฤ๎๎† ภ ˆ เG…€\B่มjL a#ู5@„b๓˜ศLฆ2—‰LD"ะŒf P อjZ๓šาคf5ตyMnb๓›เฬๆ7ฝiMrŽ3œ่Œฆ9ี™ฮmbsเ„็4�)ฯvฒณ›๖ฬง>๑้ฮw๎3Ÿ๒ฌg=ลOhjณNŸาUฤ z5`c‹D&™กศH ‘ปb‡QpXธหคFฑ‚<าh“�้ชสTb•�(ถห”YŠE๘A|@ฝHI/<B๒˜5ƒขีจCHjRชิฅ"ตฉFMf๒€� ะ่ช4š&VทชUฎRำซ]ล๊<ทJVฑ~ตชY-kZรzUถถ๕ฌkฅฆUฝjึyฮ5ฎh=+[ต๊Vต~uฏp5kY :Xฒ๖ฏ~ญ+ๆสWร๖ฏrฌV›ึป&ถฏcUฌc[ุษฆUญ™ฅ๋f›ห~๖ญ�**”๖vู`ก๐ย  5^๐‹ขŸSีั๘…+ŒzNrฝลไn�IkะเŸชdป0Fƒp€^,LQ1]m€1pมเฦŒ]แฺF 3ุ$ษ|œzื{“2r�พfฌึกขข� ิฅ�`ฟ๖eFป�[XVุ(—Kส��Ž*ฆ.•n„O 0f™ฬP3๘ภผ็M€๕เL๖š๘ฤ,๙m$r€ศmPญhนลํ"=ท4ฎั8VaใE"A…cฏ‘-sวƒiWฯ=Xีm)+{‡ ๐.t ฃ แ]๓๖@„ห0Šทฬๅ๙ชฟทฺา"ั€๘ญ8ค5เ\w-ภVณR€โ\Nส™ฮ‘ภsqpg>�ธCฆ6`ทaฃ่[ฐท@ัุ[!Z ท‘%Šeณ,ฃตƒj์€‘๒HะๅR›ฺAF•{Q๑ITยT ม �jUฃฮ~ฐ/>ช#ยbฎๆEฎ}m\๚Lภhฝv k d-˜๔ณก]‰ฑาูฒ,สกสงทธดJฬf่๕fq( � …7บืผศไ@า)@ด!๙!� ImageMagickgamma=0.454545,,˜ …) 4 > #' ) 25<) (0 .86=;IPYgs|!B%@>GVen o!"x#IGZXa^hfvsJJJSSS‰$˜(ข+จ,!ฒ/"น1$ƒ"าXw&†'+—,- //ฆ11ซ33ด5†"‚’&Žš(–ข*ช,ฅณ.ฎถ/ฑผ1ถร2ฝ๎d†�jอ5ว�@€pH,‡ƒมqษl:ŸะจtJญZฏุฌvหํzฟเฐx,8อPดQeงUŽคๅล ‡6j6B?}o‡ˆ‰Š‹ŒŽ‘R/ E–P0332K2h™›DŸ0—C.23ฌP.ซญL/D0f.//.nK'D(++*Pฬ*Œะ๑ฎจัฃH“*]zๅ…‡ ‰8…jP ƒ Œ๘Œ๊ฟฮุ Yชฮ.ํุ‹3<Q๐‰ฃ\ค"9a"ๆษ#VDpRA…ภไ8๐6D1cA!๘ฉๅห˜3k�ฬลL‚จ�|ฎE•›ซU=ƒ8ใา‚Oน ^ข;#ูh�^B‹a‡บb�ํ ใ‰&—XPA‡‰™Lค ณ'‘๊9oฐ๘ฑƒฦเร‡ฟ@žผ๘๒ๆวฃ?ฟ^ผxLe‰(# I|Iฬ—cฆ�€๚๗ๅ๗฿}๓�gFs๕8_Y๙ภ| *!„�๘฿~๑๙ �๖7a‚ แƒ�5๘ ‰#~X†}^จ_†Z˜  ž(โJ,จกƒโุ}, ‘†%๚ุโŒhX† *Xไ’r๔ ŠI$ƒF ‰ฃ‡$ศไˆ:šๅŠSขXฅ–๚ฝ๘คGๅ‰f„œRh0�Exอ` .ธCŸ:(ฬP ‚^๔Bม=j†pd ƒZN ๗W@๗DK$mŠ]ฃโ7 5์B 01€ฐฦ*๋ฌดึj๋ญณ0a %ภkฏฟ ฌฐผ๚๊ซฐวซ์ฒฟ&‹์ฒฮmณรJห์ตสN[,ด�f[-ตุ†ปญทไซ-ฐ�ำž+๎ณๅฒk.ท้ฎ๎น๔v๛nผไ๋๋|ัฏPตEฤ1 ร'Hx•๒ ็ลขท(šืยLธะ Wูษั'ต้e„ฆFฤTAัฌ€Bsฅ‘2 � ร6๐ กด`๓อ7๗ ณฮ8๏ฬsฮ>๗ดอด6GยัH#nาG/ดำJ3�tิRW�ซฑV?5ำPO}ตึR�uี` ถืY›mฌฺjo�vึ[sญu�]ฏ6�q“=u�Tฃ}7�|ำ�ท�{ฟ=v�vห 8แ$๐ปšฟ7q•ภ_ TŸ‰า%Šลe Z‡ŽRะœ_ิAข]๙ € .(  ผ@2�จ02VำษBฌ ภส6ิ C๐B;ฬฺgฬ7๏�๓™�+ZไK|ฆ'[9^T1ุ๖ k� ๑�m3„ภ๘ผqBPMzT=1ปศY ล &๑ฝ?ฆฒ� Ydpp<ไ็เžศภ:Bzา;ย BGิTo5ŸiMYภ2= ฒฅ ผฤ+_เ*v™ คไ—œ!œMh๓ !จภ€@~๔!‡ เก๑c<…p —ศฤ&>ovา€Zล€LQ*ย \.RDyโ—๋ฌุŠ…(@�ย+ฮ˜FฎdQ2`ใถเสตou.`@,า„•tj@F๐BFเ%B8  “!#ภA7ฐ!Hr’•ฌม �€ˆภ‰  ฅ(GฉŽGqฌ6โ;%*‡เ‰ิจ๒-y‘ *m#Sฎฐ,ฆ”A�X๙ธZ~B—Nจc=T'Pผ€4K83–y‚-s™�ย26ค`™๙ฃยfFสnz๓›เD‡�ม„+V!ไ:0N~ฅณ(`ไ„`:!๙!� ImageMagickgamma=0.454545,, †) 4 ? #( ) 25;% $0 /75>€คCฒ%ŠA6๙ฅ’คˆi%™[ๆ(ๅœU‚ˆ%‘\ฦ9&˜Kเe’+By&ŸjZษf–†ษcฐภฆRd มuŠฬ$ "Ci„X7ˆ5คฤtฆฅ'รช30rฏย #๖ิ MT้‘€rฮ=฿VtUภฎE๐คeะ#”ภZ’Pย >„"Š ฤทเ†+๎ธไ–k๎น่~{ภ 'œ`Bป&ผ�๎ผ๓สKoผ๔ๆซ/ผ๎๎ปฏผ๖๚[oภ๙์ฎม๓‹๐ฟ�&<ฐภใ๋pม��N\๑ย๚Jฬpม๛๛nว๗6<ฑฦg rษ'7œ๒ม—|๑ป๚˜:ศ 0ฐi5ใฐยMฬ˜nเชํเณi� }ุฯEปทช.ฆTืคcT"รฒZ *H€}  ,L`H A„0H๖€รE๛ผเ๖�o� ท�pฯMw�vื7�s๋�ท�ใึ๏เ„๗๛๑เ†Œ๏แ„#�๘โ�8ใ…G�ฑโ—S.๙ไ˜;ny็ž7zโ•ož๙ไ”‡^:๊ งž9ๆค;�:ไขs๎:ํ•ืnz์‹ฯ~{๋ฆ็^ป๎š�‹บ ‰ศ @{(,ง…(ทมK2y“!ส[ณ’s็ดบ=��/ข�Mแwบ5ซพ ฮำซฐ๒ฐฺl‚x -PศAธ0H7เู|โโ๚ศภ:Pส›IิขฝAิ fhฮ “รไš พfMเ`&|ฐ]@7ภ  ˆ€’เ ง8วนŒNN…™ขŽ jpœA0เ$\$šQฬตช€ž5ผgิj8JvBŸุเg"`ะฦAฤ๐$Qฉ`kฒยP=!Yก@!ฐBฌ $++ !1LŠœ ฉHGš @O @E&+aษไAฯค.I เว4“+ลD !๙!� ImageMagickgamma=0.454545,,‘ …( 5 #( ) 25;' &65=;IXhs}!B%@>HVdn o!"x#FDYWa^jgvrJJJSSS‰$—'ข+ฅ+ ฑ."น1$ƒ"าXw&‡(+—-- //ฆ11ซ33ด5ˆ#„’&Žš(–ข*ฌ-งฑ.ฌถ/ฑผ1ถร3ฝ๎d†�jห4ล�@€pH,ฦคrษl:ŸะจtJญZฏุฌvหํzฟเฐX)€–“็hzœ บ๏amNงe3Žฐมkฐ�€‚ƒ„…†‡ˆ‰E,D,‘’,PŽJ/gŒ—D+00-C/กฃM ขM”C–e+’kJ&(('F%O$บ'ม1ษษ8842<6 Šืฺุู����_ฆ0 Dๆๆ--O จD0B. ไค0 ,šBช๘ู2๒ษBภ~K ฉWๆ‹ ™^1@(Ž ! Kใ’'H !‘<@ ฌ€7L~›Iณฆอ›8s*aฑมย�8200<แร�YCx๚ผžPช„:๕”ษTจUยุ $จ†\`€1๐#ŠDˆetBขD“6�ธ ภ#šx๓๊�หทฏv ”ฌP็d์…ขF R†SŸ€ข€d“,ต<™ษง~ชศp6ร )P˜ŒpยZ&!0‰†ภ 1xเˆแฤภ฿ภS>�ทoโล#ง`�ภ๒เฯ•#o=8p" 0@ภ๖w�ฝฟyณฝ<๘๒ู‡t�ฎพ|™๔Mรo๊ž}ใ์ๅํูพ~||๓๛uG_๋้'„€� �W฿}� ^ �ื�yถว�๎�)8฿zŒ จŸ๘I …ไ!ˆ!‰FxR‡ ส"‹#–ธa|(ZธF~,jh พ๗aƒ่ฑวb~ุ•5„cIdbT^] ู“-„E“BŒU +ฌpš–ดะฅ L€)ๆ`žฑ‰๖ย„๓ิฎษ&D(@€งGIเY@%€ิฅ)ฬƒิ–ฤ;D*้ค”Vj้ฅ˜fชฉฆ !‚!|๚iจขŽZ๊ฉจžJชจซชš๊ซฃถ๊๊ฌฐย*ซฌฌึšjธๆJซฎจ�๚jฏต๒jkฐภ๛kฉฤฺฺ,ฎอ๊*์ฎษ2๛lฐกสš–DD๙„˜œ•ษ@�fƒX�dipฎนbiย๎์Ž๛ฎ`ˆ)ูa ‚™’F<€‚D˜@{6แ/ &@€ั B�`G ่†ƒข?bงยลcฌรฦgฬqว์ฑศ!s<ฒษ%ƒฌBฅ๒๊๒หฦf๛rฌ0ว\ณฬ.ƒช3ฬ โœmฯ3๛\3ะฦอ๓อB๏ltฯD๏|ดัGฯ uฮH/�sิM }5าIOm๓ะO'�๕ึA{=6ฉ\{mตำT๛ฬ6ีfำ\๓ถ?ัBfKจk‡]ภ<๒มํX์ศS บ…Cuฺ„วฃธgŒีฅO ญ€ภ๑;„ฟ!มYิY�ž  ัAF”ณ–b4มQ็Cจฅห๙|มัCฐ6\FtJzิ0;๏Cg@ง๘๗๏���๓Ž'ล B1L)ทถ๗ˆฉ0ฐ)YQ;^ะ@drdAœ�–ฤ1aคCม่š’!Œภ-Bภ Š0ู9#…๒gHรฺ0'เ[<€ p o1E๐Jญt%๚อxEภ'ŒGA%�p‡—เฤเeN่� V  ด!K@ม@ฦ๐ฉ`iy>'›: !ผ!w„ภ€ไเ7ฬฃ๗ศวA O_!ZƒภAˆY#$ˆ‡ฦ�1|Œ!$( 9B2’ x%้Eลไ ฑโpพ๓๕‚hB.Fhย๓‘O จXgIหZฺ๒eทtน„n+xน�%N>ภ$A!๙!� ImageMagickgamma=0.454545,ุx†* 3 > #( ) 25;' &0 .86><***888HPYfs|!B%@>HWen!p! o!"y$HFZWa^ifqmws~ zJJJTTTjjjwwwˆ$™(ก*ซ-!ฒ/"น1$ƒ"าXw&‡(+—,-ก//ฆ11ซ33ณ5‰#…’&Žš(–ข*ซ,ฆฒ.ญถ/ฑผ1ถร2ฝ๎d†�jฬ5ฦŠŠŠ—‰–––ญญญถถถยผบวววุุุ็็็๕๕๕�€LNQ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ กขฃคฅฆง™MจซฌญฎฏฐฑฒณดตถทธธOนผฝพฟภมยรฤลฦวศษสหฬอฮฯะหPOิOPีNิำีืัเฟPืใ฿แ็่้๊หฺ��ิ�๒Œำใี๏๋๙ญๅQใ���91'ซ\ภG๘8%ฤคํา@}#ฒฒv๏ฃŠ๎.bฌ&ฑฃจrึ Š$Hh ษ(L Adส “—KR*ZYจษ.O 75aYษควŸ@5u�hMQ<ŠOr‡Qiะง� ต7ฯฯCWŸศ,ๅ„ง EWป~brSSฮžNกช]�ฏฺ�-–XL„4้ยBDฒ��Hd<ชฑ:Ysแ%ฺS“Kxน�ศ:ไฉ5สฮBd™ฤิU๓U(žYv&\ถะ`ฤ9O3น&ๅอีZ]"&ds)แึ ›�|•ะcญ…ฃ@๎ื›ฏ๑gGY(g1Q^Žt๋b=๖MmBึ c‘ตฅฃbญถš6bน$ƒQส�mdZˆ–ฝ๙T ‘l–สK�ิ3ำsN1ๅNZฆF$Hื‘”•€ทŠ7$Žšeba~™}๚K†ึูฃ†X(ขQvฦ^„–J๙฿.ŽJ6œต7yช"—ฯ�๋ทตฌนศ=๒�•Q~‚๋ั›ob๕Lร)ˆ˜a�ษPบ˜9:�Y๘}Ežœq.%›ฺƒx๔ษๅฒ�wง‹œจ9,�'_žฐชซ1*จฦซŽtŒ็ฦฒฒ;’ป�&š\ไ้VeI#Gโํnษ~…(Œ‘นŒlฒฅๆYถืฒemฉ�vำi]ญฬุ~๐‚w[‘,u+i:2M;1ซ้๑ิ๖R�XR'+3ฅๅฅ\งญ๖ฺณำoogrิงฌtถู$ๅฦ๖�|๗-+)ฎuˆ~n๘แˆ'ฎ๘โŒ7๎๘ใ฿>'๙ไ”WN”ˆ–g~นๆœgŽy็๚่ค—n๚้จงฎ๚๊ฌ7ี:่ขฟNฎ์œวN;šดภ๎ผ๗๎๛๏ภ/�๐ฤo�๑ศ'ฏ�๒ฬ7๏�๓ะG/�๔ิWo�๕ุgฏ�๖�w๏}๔�บ/�๘ไ—o�๙่งฏ�๚์ท๏�๛๎‡��๔ืo��๘็ฏ���๗ฝ๎-`�Hภ๐€L H=ธ่N€ฝ“0>H@|+ธ ๕ฐ‚jpzd GHยš๐„ัc{ื"){X๏…ˆ/ Hจž �–C๊Eแ…( ข‡Hฤ"๎O…ฐแ๎ภแ8{Lœa oุC๊ €†U”ศล.z๑‹`ค^ ศปiH D�ล� `Šk๔]7Gไm‘wu4^0E:ส/yw,�รHศB๒Dข` xdJฒ;%@A~,€ย� ‚๐จเ“บฃa ˜ˆ�เE2 ภR.มx+( Oน”T>ม†–ิ�VฐสVR�-ู“ส�1ว7‹\O€< ๆฐฑ้„,F™#ๆตЁ|ใ"ื้Xu~ำงS๋bฃส;“–‘ ป,Lฮปฺ๖ถธ5!LAชPล๏œฉ,*3!Af6 R์eฃ๐Auขuตร๛f*i๘BŒ6ฒ;ฬ7๚\ห๒ช,ผgf๐Oƒเฏ2U(YYปป3N7งป#.Œ›�๚ฺ๗พไๆ"yฦ3า—ทฤh1wxพ2๑�EjW๙J�ั๒nฒฝSmxrxZa‚ๆผ„P!!r˜เ*:ุ›s]%l+ €”ุPยพ@�{Q๕๎๎›ป่+~gLใทoท*~ wแXฟ�p“t‚a) ���sซ<ชrU<L %_]ฒ๐VษJ™๔ะ+P”ห�“ดร฿N’™ฬJ-;๕จฯ|‡๛มŸdqๆ-้ƒ์ปAูฦxฮณžฝงH*ก(Nˆ๓oญN�n’„ฐ!˜ฯหิ๖ยF^Šlํ›~ช“ดJ~p๑ย; ซŸฅ้cŒ)้`^ฃ˜gOก]ผ็Vป๚ีอ `m1&��d๘)oD€9พ;„ Œ๒Aุ�z`‚#B5๎HA๔จŽยิŽ็HT*6๚จbD๕9Fแ(T๎Ž๑ˆlช๔๏8Ž้ 9�๔YŽ็HŽษŽ๙ ู๔h`Žษ๚h ษ‘"้+‘๋่’‘ ‘$‰๛h8iAeŽบcŽช„“™‘)“Dู’Y’่Gโ8*9“๒Hq—†จƒปใ; ƒht7๐‚พƒrุ;4(XIAh9@|8`h90'Œ@@T(@=@%P<`ฐ›ฒ9›ดY›ถy›ธ™›บi›€l๔›ภœ*œภ9œฤyœศ™œลฉœฬูœฮ๙œฬiœะ‰œาIœี9ุ™ำyฺ๙›�ูุ๙เ9žึ œภC•ผฃ:` €•yI<เ €Y7dq๙;่น;lqฉˆ๐ุŸ(<ศŸRW 08Ÿ6ฐ‡Vน{^๗vป#˜ฝ#กฤ“w3R่;.€1เ0~ŒฉwŠ~‹ืx@‰ม#‹ู…?pB�0@ ŒปใD0CšWw5ฐฃ<สฃE๐ฃ?ฺฃ@ค>:คBjคE คGชคIJค;:คEภฃดyq�๖IŸnฦ9œV๚IYถฅ^ชฅUjฅ]zฅ`๚ฅf๊ฅcŠฅi*ฆgZฆhสฅa งVncฺฆgฺฅX*งaฺAnฺง_Šง[ZงtฺฆuŠฆ€สฆs๊งvจdŠจdše…Zฆi ฉ‰ งkชจ‹ ฆy๊ฆƒzง„zจzงV:l๙น; pu8ะx<z—ศf|็y‡�&(mˆ•4ˆ{ถ —ดชซmƒ!`ำg ฐ–8กก(Z<0เ}1กผณกy„�Œ้`2€กฌh๚}.ะw›‰<+ žสค\สึ3สฆœสชฬ<จผสฎ�สŽหฒ<หืำสด|หฉlหธผห ฌหผ�ห—์หภ<ฬ,ฬฤ|ฬ‡lฬศผฬ~�ลฬ�ฬฒฌฬะ<อ�o,อิ|อhlอุผอ`ฌอ��อ๕๋อเ<ฮ?+ฮไ|ฮ hฮ่ผฮ<งฮ์�ฮ็ฮ๐<ฯ'ฯ๔|ฯgฯ๘ผฯ๔ฆฯ��ฯิๆฯ=ะ็Fะฝร}ะ Mc ฝะ]_ �ะ}W=ั�R}ัMฝั}H�ั"q#]า�า&าBคl*�าฎ†า.ำ ำ2]ำDำ6ำ�ƒำ:�ำ๙รำ>ิ๔ิB]ิํCิFิ่ƒิJ�ิใริNี�ีR]ีตlีXF,ี\B‚ึี`BI@ีa]ึล!๙!� ImageMagickgamma=0.454545,,š †* 4 ( ) 25<* )76>=???HYht|!B%@>HWem o!"x#GEQOWUa^gdpmws{ xAAARRRˆ$—(ข+ฉ,!ฑ."บ1$ƒ"ฐVmาXw&‡(+˜-- //ฆ11ซ33ณ5‡"ƒ’&›(–ก)œซ,ฆณ.ฎถ/ฐผ1ถร3ฝ๎d†�jฬ5ฦ�€‚‚†‡ˆ‰…‰Ž‘’“”•–—˜™š›œžŸ กขฃคฃง—ชจ“ฎˆฌ•ฐฅ˜—ท‡! บึˆ?จl30‡š$ธ@]#ฐภ]"ฐ ั#ใ#Hโกˆ9D6HrภŒ4าXม7ึˆcŽ6๎จฃ=โ๘ฃA๒8ใŽ �iไH*™d5ฦ'ๅ”TV๙Tข2๐ษR d P[ˆศภ�!�ํ—\ศ 34วฆ›pBฒ&* ีI\ ฆษลๆrศ†_$๒•H"FR˜ €v‡x †ฐC ุ Œะ=€# ฤฉจฆช๊ชฌถ๊๊ซฐฦ*๋ฌญ’jๅญธๆ๊™lผี3 ฟ)๘ œuˆs‰คiˆ„อฝsแ44+ภ…\X—ฬท›ศaื85ศ๐\"…&2�’Lง]'ฐ)Qjˆ‹40^ฝ‹ืC7|ืH/,ฐภ?\๐ภLpย3ผฐม C�ฐย�'�Cฤฟ`1ฦฐ &„,๒ศ$—l๒ษ(งฌ๒ส,ท์๒ห0ว,๓ฬ4ืl๓อ8ื\$ศ๕šˆฑยช@Bดe™ศRjf•%qฎน8L�iเาqjปๆ›ฒ)Cุ5๎!ๅ2“Lทยb' PL1’ƒ/pK@Kก^๖ฎุ๓�|๗ํ๗฿€.๘เ„—ผณ#�™สn$nศšแ8ˆๆส%H}ฒษpW}Ao.9"0h0WYฐ�qฆIถ R@Iaฎ " ‚ไภรฟ‚4ถ)๘0€ํ�ุ ศ#?ู๑R%o�Ÿ�)H๏|๔@<๔ั@ภ๑� @€๗X��๑ฺ�๘ษ_๛โปŸ�) /=๙ำC�๖ุงฏ?๓ํ;_๚พW>๋%oyใ_๙ๆg@๊p๛ �ผ>๑‘ฯ|๓“ ๒่วพ�yฯ{๑›๗๊ทภๆฏD!�๎@*๐xทP ๒๎งภ๓50{4^GHมํu๐~ˆk€3จFะ‘C�~ก,A๘ว@บฑออQ›ฦƒŠŒ#ŽmVS ธ0g)d"ิ†กKฌ@m‚8A &„xเ๐J ก)A�๎n-Q๑๖ศว>๚ัJLน€ ป" ˜0 >าิ\@XชŠ™”H*@+‰L€„ว"qh’“†เำ"i๐I(j๑ฅ;โ. ƒwสˆŠbม‚GAเ–ƒ sˆ ธ+ฑไT�|!D่1$˜tเƒb�๑™ะŒฆ4m2:pGX ืสDนN‚k‚@V"๘dอป€ใฃศIƒ0 ‚ 8ฤ:มๅฮ๙ฌto้@$ฑห‹\Dm!๒็Eศf‹สํบบ2ั[M๓กจDฃ‘งคดQ,€QJ  ฃ�Y"m@๚ัั —•2ภf!๙!� ImageMagickgamma=0.454545,,‘ †) 3 > ( ) 25<& %76=;???IQXhr|!B%@>GVen o!"x#FEQNYWa^jgvs!{AAARRR‡#™(ข+ฉ,!ฒ/"น1$ƒ"ฐVmาXw&‡(+—-- //ฆ11ซ33ณ5Š$†’&š(•ก)œฌ,ฆณ.ญถ/ฑผ1ถร2ฝ๎d†�jฬ5ฦ�€‚ƒ‡ƒ†ˆŒŽ‘’“”•–—˜™š›œžŸ กขฃคžŽงข “ชจ–ฐฅš—ตˆฃ–‡๚๒‚XCe6€ 7ฌ"R‘‚๎ZA\TtAx$ -pกม|… !ั—ฑ๕ุ๋ณk฿ฎLชฯD)กR`™Qƒ๒žศ๎ฬYฝต}•Yษ. ฉ��ฬfnตึถ‡’ิR€ ฟ0sะ ‘PP)ฤ}•ภร!ขร8 ๑’$ โˆ#b`ข‰$žˆb‰*ฆุ"‹'บ#Œ+Šจ"2ึ˜ภ9โHฃ$Žศ�Di$nDู�ด€>2h@ yBƒm‡@9@ƒ 2ิ–จlู%$l%& \อpƒ“๎ไ@mท Eษ€VเB-,ค ’0ฤB ฟ…0D=ร"0@ 8่๐ร=2€”Vj้ฅ˜fช้ฆœv๊้ง †J้"F–j๊ฉ,Uš •ดAW’X‰H™Vษ YทV๕ปาŠ๋#ธ๚šๅelin`YS–nะ9ˆ. QะFิะ ท€เแ":๐ˆ‡?่’#ฤ`๎น็กฎบ่ฎหnบ๎ถ/ผ๋ส[/ฝ๏š๋n๖ๆรพ�๒‹ฏภ่ฦ 'ฌ๐ย 7์๐รG,๑ฤ�Wl๑ลgฌ๑ฦw์๑วGษyซฒฺ ,˜Mbซ เ5b+–ฒa๓—0ห93™@ู์ๅ#2t€%—•ั†ำ6๘3‰ณ‚ุฉ \$Z A ,ิBLƒ€4ศ9< ‰ขส —m๖ูhงญ๖ฺlทฝถศސGฅ ไษpๅฐว")ปŒ^ea 2|�˜5x}… Ž฿Uทfะoฺvž“’ m  ,0€ š?โB ‚ะ5�ื; ’ร^ˆฤ@รCุbฏ€ิ^;!ด{f๛์0ปํง ๐๛๎พ ะ{ํฝ๛ด0ห0<๏ดฯ�๏ัืn�๒ห?ฯ|๏�ษP;๖ถk฿;๕ศo�๙น—Oฝ๕ฬ?ผํธC฿ผ๔ฦผ�๗ใพ๓งจ๓ฝ๑5}ึำ_๖พว=็™/พ3`ห—ฟ�ฑo} t_�เผ๙�{๗ฃ��:ุฟูY0€�cdะฤˆุ 2‹‹� ๖6ˆ๓DฉJ่q+>–ฆd~ณมM๓ˆ„3€\ l#สEBA‚‚3บAf@LD .  *"xŽข†!ฎQ่ฑKฃืศฦุ�Dp”Š ฐไ$$BM๐Pด€oLษe เใ7fฒฬd6(ไ!๏(ฤCศ ‘†ค W€xก1ภ([D ฎเ "*`NB Aภฅ”hมCค๕ ํb @J็ mฬฅ.wษห–|FYึ@M$ญแDTƒ†‚&}hี5ำ,pฆ œ(€jXร‰‚8ๆ!ขฉ,lๆˆ๛‰ dpรF„ฒ! ฮ9[ Dคฅ@˜:Awˆ@€T U/๗ษฯ~๚3`€UG๔1ztYAYถP( ก%ูd#€Jเภr !๙!� ImageMagickgamma=0.454545,,™ …* 4 " ( ( 25<' &0 .75>HVen o!"y$HFYWa^jgxt{ xJJJSSSŠ$š(ก*ฉ,!ด/#น1$‚"~าXw&‡(+—--ก//ฆ11ฌ33ณ5‰#„’&Žš(–ก)œซ,ฆณ.ฎถ/ฑผ1ถร2ฝ๎d†�jฬ5ฦ�@€ะ0ศ$ฃ˜l:ŸะจtJญZฏุฌvหํzฟเฐxL NดU�dG�ฦ๓^ฎ #อวว5Ž37B 45B>vŽ‘’“”•–—˜V-122/G-. Q.ฃtB1jคHŸG11ฑRทนฅO.G.h-..-ชI&G&า&''&Q(**)B" :9F;|F74 >E8"™๓๔๕๖๗๘๙๚’  0^™u! ห„xแBมม’AศN2| xช•YN!ŒฒcBข.! D rI ME#(”˜@�Š(%"(PBด#!� aื‘๘่วพซXณj�สตซ -Lฬ๐Qู'2 ม cAcF\pH› Ž eษNฤปั,”ฑyกˆโ dA'41`u€‰l:  ย•*  pใ†‘< œ ™ ภ‡;u^Sซ^อบตk1ว,ชU0 JL#ด๙1์ ueƒJP;-(ร2":a Švrม2���๙—€ ุ}�U@เ$ธ ‚Bˆ`€h_}G ‘วx�pฦ  Fˆˆ(ภxšข"’x‡X"ถุ!1สqb‡%สHใ‡%~Vโ‰"�Qใ8ชศa‹Aฮ๘ฃŒy )ึ†9ฉbw�่b‡Cข๘c‰G9"ŒVฮ่ไ)๊8%Ez)ไ–ZษขšJึธแŽ&>Yค™<ข™"œ$ๆ(ึŒ&ก•’AXศดlฉqh Hศ•ฤoม-†h Š.ๆQข‹>ั(œ ๖‚ *A สคUั��”„FU Aƒ :˜–žh4†0 :|๐O ะรฑศ&ซ์ฒฬ6๋์ณะF+ํดิV›,ฑB@ยฺjหmท�~ ๎ธไz[nน�โžK๎้Ž�๎ถ๏ช nผ่ส‹.ฝ�ฎ‹ฏผ๛ฮkฏพ๊พห๎ฟ๕�/ภ็ ๏ท้Žฆ,…]LLน,p( q(”a1ลุ� vฟศXซ�D plุง,ฅBEซIBญTD6A3f„zHŸ{ ‰D,4ํดำ„pDhจaฐ”ๆมk่q€ฒ<ค๏�๛๐_ฒlA$DlUฤ \M่@Z๖U0�9€๗SN`6R]1Š1ŒJค@=#ฬ๊(ฬ� ซก๑ ุมvˆœ/~ญนะPศยบฐ ฉศobŠ๙Q9…Ž~ฃ#�F-๓๛a ๏rฑN Q7 ฤK ขg—(†8ŒB…เ*H ม `0@ xภ|๐�{็฿>๘ย6บ๑pLํ2 ˆข›@€๎xะ๐@รE:€(&w ` �!Q$`jA p ฉTT’†” —W,เฃjฬPf`%p‚ bu@&€ธวไ |7จ%€ม'!๙!� ImageMagickgamma=0.454545,,‘ …( 4 < #( ( 25;* )76>=E PWjsz B%@>HVem o!"y#FDYVa^hevr{ xJJJSSS‡#—(ข*ช-!ฑ."น1$ƒ"าXw&‡(+˜--ก//ฆ11ฌ33ด5†"‚’&Žš(–ก)œญ-จณ.ฎถ/ฑผ1ถร3ฝ๎d†�jฬ5ฦ�@€pH,ฃrษl:ŸะจtJญZฏุฌvหํzฟเpX +หPดQe›งIj ^แย†ํๆ:~o‚ƒ„…†‡ˆ‰Š‹ŒS.3/ F/ R•—J2h–E.230šBคฆPซM/D•e./ทnK'D'++'tM'*+*ฟC ??x86!?9#���฿เแโใ† 20E งNํ3๏C2B1ค“Cญ /:กš‘AA@]ขf`(ษ#Cbฬ(ใE 3d9bX"*N€ ล“! `,4i?.๘แAฤcไr๊�ษณง�ฯŸV8ฬ(P^”ข๓„ุ๒ย†�˜กa`ีฉUดสบซี&\Y‰b!Ÿœ0aลG!V4‹kภษ “JD�Mอ?ฌ=Jธฐแรˆƒก-AฃO0f€L„TzฺE}zIA$œXฮุไ้$ฒคฮ(t"g}’„€�!T )ฐ‚B“+$(๙โO {h�ุAใษะฃCท@:๔็ีญGฯnแ:๎ามoฯ๎]ปฌณา: mตำZ[-ถฬ6›-ต฿bk์ทูปmน��’[,ท้";ฎบฺZ;mด๐ฎ.ด�Ž‹SษภU bญ๙L'บภ)ฤCษ9รxv’#<๑.l@งe“QI))ั่จภึค!5ัึ]˜ฐBŒ๐ร๐Es,ทƒ ;phD--ดะ=]๔ะFMtาH3ฝดัMC�ดาA'�CิTท`5ึWO�uีNƒ-ตุYoดฌ>ซ๖ฺอฎํ๖ฐn๛ถนpซ w�vว�v�|ำ�ทน|ใํทเw๋mธเ๛�7โrณญx�€;>7ใ‹Gnxเ“[8โœk>w฿L‘P(0Y้Mn:AQMต(;—9ึฮ�=bโ)AZษะ็์นƒตFu>U† ., w2z�nษ ม จผL&œภ ะd�’7ิฐ๐๐bไc@ฌ=”ฏ�๚์sแี#œS๑หฏTcฐo6CEB�’่�๑žย?=แฯ‹G„๗šุX†POูT0&ุ&zB˜€n†0bเมxะŒฏ}(d‚~ผ“ยบ๐…Rก f,•'Xๆ4\‚ย2ใŽV%—˜สšะqCtศืฤ 6ผ;ษ๒Œ )†จ)‚ ๐2QI#gใ๋žq`Hฦ2š๑Œ„ัภ%๐ˆyŒ~๓๓ฬ)ะ`vušhฃฺจ#๎Myว(๐ว๙ ม\iโ๐Ї4„ 0@% !@`$ฑ’ัŒ ็QŸ$‚…Pไ<WษสVบา๕๘ `„7 3 ฅไˆ–Gแ๕ำˆ€ J…˜ ).u™!bสภ˜Kข,3{ฅ:ืษฮvVA็˜‚ Yะ“ˆฬ$BjH๙ํ3(NBิI"ภt!๙!� ImageMagickgamma=0.454545,,‘ †( 8 > #( ( 25;& %64>HWfm o!"y$FDQOXVa^ifqmvs} yJJJSSSŠ$–'ข+ง, ณ/#น1$ƒ"าXw&‡(+˜-- //ฆ11ซ33ณ5Š#†’&Žš(–ข*ฌ,งณ.ฎถ/ฑผ1ถร3ฝ๎d†�jห5ล�€‚ƒ†† ‡Š‹ŒŽ‘’“”•–—˜™š›œžŸ กขžŒฆ“ฅจฌ‡ฎ‘ฐฃ‹Œถ“ตŠ#Aฝ ‚ 88‚Aณษสหฬอฮฯะัาำ 05ื2 †ื4ึฺุ‹4จ1 ‡แ2๋ƒ45๎‘โ1†1ฆ021`pฅHยŠ-XH04ย &T8่Cม‚าqC„F;JPIฒคษ“(Sช,นA4d ยP#Ckทน„)S‘aWcœ {ฤ0wดฆRฆŽฌ%]šS5ƒfิ0E#F† 5๔=B@-‚ะBด�ธ‘5‹V-€A=8 ศ~I๐ˆปฒฐแรˆ+^ ŠCAhbPtุE0ฤˆัฆQ544 Z4วฆO…nด‘5‚\35ฃƒ n” ด€ ˆ AZ˜ค›7€�่a+ˆ‡พผ0žNฝบ๕ุ๋™”ก&3(m?Dูจ •…ึX';,š์ฏi^ิ]›๙Qk0uผ �ง=6I-เA[ ๐�€‚C=๘%9ุก €ภ†nhม‡nจ!ˆ!rHข""pb‡+šH"Œ๘"Œ*ฮ่แŒ2‚ศ"Ž5๊่ข7๊c%ๆXbE�‰b‡0ฦhˆ.ƒœ3€S %•ุbห”SšbŠ•Tv)–V@–ฅp‰J™d~‰e•Qชiๅ˜rฐ%–^ฺ™ฆ˜gVIๅ˜`ช)›~๊Y'm" ็bบฆ*}ขi&šoฎY้œ„fgข‘.Jžg๊๙่•ešๆŸƒ†ช๊6ฬ@ฯ ึศ@Vlภซ๏"€† gT9ฆ�˜" ร6‚ว�U 5|ำU� @Sk‘H€เ hdภ$ฺ.4/A์`ๆ$ธฐ\52๐ฦ+๏ผ๔ึk๏ฝ๘ๆซ๏พ�๖๋๏ฟฯ{ภ '|‚ #l๐ม /ฌpร;�0ฤ�lBลG์pรgฌฑฦŒqศ์qย ›1ษ+S�qวว\ฒสรฬ0ว+L้ะ@CjฤbS•!้h…ํmPr฿ฏ๋—{Y#Qo55#0lp,e�ัvอyๅ˜[ฮ7ฝq_l๚้ฆŒ:รจŸฎบ๋ญ+๛์ฌำn๛๊ฯž;๎ญ[ฌ;๎ฏ๗~;์ม๓{๏ล�^{์ษ‡,|๓ฮ๏:๔ัว�ˆcดvงM3„mˆc�฿Œ้"พยอ}Aล4zAq ™ฒ๋y็~T”ƒ,Mดม @4„ษฺ†ะุฒ‚ด)B7dD_p ‹ˆ`9ธB�";„่•มz๐ƒซX j›๗Œ/"�ฮ|z•ฮ@,1ะGw^(ˆ:‚{0\!;6€žšเฯ?ขL๘A$ะ-@มZถEฤษD0‹ ฤุมAศEPคศI] ฃญSฐo5เU+ฦWF”๏<ืXG{(ว.=4จใ่๗™�ฤ}†ศˆจ@`b *๐ˆฌ`>่Aเ ^‘8ธม^�1ฦNz๒“ ๔ ึq“๕"&๋เฦั •+Œ๒LKyวฎ๎ธ?งผร €5nIƒ\๎าฑ4 zฉKSบh”แ €๔ว-H"ุ…+P‹ู 2ˆคE, ห4ญ)๔ข7ฤ r ๘เกŒง<็Iฯ’�ไk2 `๒552ซ ˆQๆA+`-Z_s,ป1D 4Z‡pf@ฃ„Po<"k†๘ใื๔๗ˆ ไฃ-˜€ เ„(ัฮ J๚Q‘สˆ›๐Vฯšฺ๔ฆ8�„\ฒˆสBนDTuCฅๅ"€ชT”ภ,i{j$!๙!� ImageMagickgamma=0.454545,,™ …) 4 " ( ) 25;) (65>=HXgs|!B%@>HVen o!"y$FDYVa^ifwt{ xJJJSSS‰$˜(ข+จ,!ด/#น1$‚"~าXw&‡(+˜--ก//ฆ11ฌ33ณ5‰#…’&Žš(–ก)œญ-จณ.ฎถ/ฑผ1ถร2ฝ๎d†�jฬ5ฦ�@€pHƒขาT:ŸะจtJญZฏุฌvหํzฟเฐxL.›VeO�E8U~Vu€วฦฮz€7 B 35B =ƒyŽ‘’“”•–—J-C,1Ÿ- T œN0l›Eค1.ข01ญS,ดถP-Dšj,--,tJ&))(ว%TฯE €}B! :8B53 =I8*˜่้๊๋์ํ๎๏fŸฆ 0ฝRค -/่ˆqAˆZ1d ูรยฟT � ศOb ˆP�๙๕้รื/}�๗�ู‡฿~๙H xเกฦp€วค1H8xฤN(@F�8ธaxx˜!ƒGl8œฆˆวƒi\่ JHแ„wp˜ก„zˆ„ F8"†B(ŠAพศขƒIผcŠBTXcŽฺจ#ˆ=๊Hb'6XไŠ0ถ˜ไƒ2 # qใ†9f˜$!*‘€D™ ‘ม/่๒fj รย Eธเฆ Wž,์๙Dz๒ ล $Z[ 1lคฯm0คีšYS@B3Bภฬ\yIก�_ไ@ &„!9,ึ$*ฬ ƒล<ไช๋ฎผ๖๊๋ฏภ+์ฐฤk์ฑศ&ซ์ฎถ1‚#D mดิJ;mติ^›-ถ�r[ญถ�v nธฯŽ�ํท�แš‹.น๋ชหญ๎Žซฎปาฒ�ฎฝูฦ๛nบ๕>๛l/๐ถSฌภฆN8•A*ค๘‚ ฃ ฑ๐กLฌA\จTื.q-,ภลตiเ ขแฉ�'ตใD_ุU V1j6=tะ€`6s(„ < a€v9�ก3ฌ`๔ัG๏ ดาH/อtาN75ิKK]5ีOํ๔Vgฝยึ]sตุZO]๖ีg{ ๖ุaทอถัฝ2๏�tCk7���ทตs—[ท�~ใ�w�ƒ�ท�๐ๆxโ|'�ทใ‹;^ทแ{#๘ไ—O�ธๅ‡Gฮ9ๅ}ƒ.zๆ{/พ๙฿ Šไf)AสF‹&Dะ�Wฟ  น๑[ฒฤ๏o๚^๛p}&|ศpฺฺG,$€š TฐL„t )คF135โ�5E ะCะ0CPse์รsฏ;ด/��๐ุ†๒ก&xๆ’=ํ-งฉยฦBะะ }_่`พT1"‡xฬฃ๗H™ษ‰ภS.ยO$@‚‚Ÿจฬ\`ฆ0$"ใ$IO 2NLศ$™B•�„R,P€\๐0' %x€* ย˜!%ก:ษ๕ ช46้{8@fp*0ภ9X!‡Iฬbo2…Qๆ‚๔iw ‚ิ'`—1อฤ!ฐ€4#EšmzฑQ1P€‚ผ)xห@Gฎ ไ|๐ƒ(‚+‡ “์y๐ƒ/‹Bp`hว จ@Jะ2$@œRBศ„j E@Iั…พ#"tB!๙!� ImageMagickgamma=0.454545,, †* 4 < ( ) 25<& %76=;???GRYcr| B%@>HVen o!"y$FEQNYWa^jgvs!{AAARRRƒ#›)ฉ-!ฒ/#บ1$ƒ"ฐVmาXw&‡(+˜--ก//ฆ11ซ33ณ5Š$†’&š(•ก)œฌ,ฆณ.ญถ/ฑผ1ถร2ฝ๎d†�jฬ5ฦ�€‚ƒ‡ƒˆŒŽ‘’“”•–—˜™š›œžŸ กขฃคฅ‡–ฉซ’ญˆฏ“ฑฆด;Bน99 ‚Bตลฦวศษสหฬอฮฯ2 ‡ 3564ิ‘ุ3�Œ5ซำˆ166฿‡�๋เ๊์2‡าฉ1321ณ\PQ‘@‚“RจXธะa: 8ภ$„ ภรด CŠIฒคษR ิ[`#ถณฑAŒqŒิุ H6 fjXps•ผšE#ฅำ`็ฃt ัฐ‘ช†Œ l�‹$aE‹u�6’ŠาZ(จƒ‡A!�Qยํษปx๓๊�หท๏ค›6ภํซ$ภA๒ฃ� @ฦ @Vœภdฤ†YeP๙iKA ิฅข๑AะชfSH{H…jึ’T\@„@ศFsษมฏ๏฿ภƒ ž‰อภ‚ ๓ค™Zhญˆ O eะžศYBoเ9ใF�ฝCJ‡ำƒh5J0/iQุ‚�ร‡ไ!J์ะBP7แร ’$`เb  ‚.ศ`‚6!„ JX!…่ f˜ภ†rˆกˆNXโ…'zโˆ!ถศโ‹)’ˆ ฤีhฃ3,mฺ6ก1ภA?Db\*�ฤP"3จ�wˆuƒ ูX F`œe3@I$โ Rๅ`Oษ`CVก–ž-'ษ{e ‚ๆ$*ดภ‚ ,‚<๐@Bˆภ%�ƒ#Œฐ‹#a่กˆ&ช่ขŒ6๊่ฃF*้ค”Vj้ฅ˜jศœvjŠUv7d2ฬภย�S6้ิ’‘ ’•”Tฑ7k–ญ:r๋8น6CUJwZU๊h%#k"’,WXเ• € เฆ9์ˆ€>ไ ‘#ภเํท฿!ฎธเŽKnธๆ–›.บใช�.ป็zk.๎ฦ รผ๕า ฏพ๒ฎ�๏ป�ฺ‹๏พ๙L๐ม๓ ๎ (4์๐รG,๑ฤ�Wl๑ลgฌ๑ฦw์๑ว s#ๆiภภiC ซฤ๐]8ัฤู‘ษษฬ“‚—O�ะบ๓ฬXฦฬ3อŽ�*”ULV{ศฒjฮ7‰-L ‚” ฤ :เ(?ุ่้้ฟ๒ูhงญ๖ฺlทํvฦ']์� คคdฏŒœf• 20ๆฒ#8ซœอV} 7แ/#ฒ2โใuา—IฃงžtฉFต —ทืยlB่0v‰ ัภ์ 6ูจ๓%@@ซผ�z๋ด�{๋‹่พป์ตฟ>@์ฟห;๑ถ[6๛์ถฯพ:๒ฮ#�{๐ฏฏ�:๕ฒปพ'๑รO<๏�ฏ๏yป๋ล฿พ;๎ฟฯŽ=๎ุ?฿ป๎ฑฟOภ๐ฬ<๓ษวฏป๓เ› �ำƒ๋RฑปM5bาG b0.N%–ูŒtฎsณXU‚—y5.๓ˆ”ิ`ƒ6่@ใเ22‰I=?;“ินH € ๒ั�f>ะSื๎CŒิ๙๐‡@ "qv4ˆฌ๐ไ4fjฬta$ �HR#p2š,`P|โtšจEx�\„โx#้(ธ†ำXh ด€(�G9 B,ฐ#.p€ภ+rิV.ฐ†ฯ๑b? ษศF:๒#Dl`ฑDxˆุ€งฐค:Rg•ฅFxin[ภ'ฟ$M’ฒ’—ฬค:jPนขQ;ฤฒUเแˆ6}ๅ+ะ€-o™KAx%M,ธๅ pˆ@ภ€ 0เ#—ษฬf:“`ภ,@KAิญีœง˜Mjr“/ะ#ๆ`ว@!๙!� ImageMagickgamma=0.454545,,™ †( 4 = ( ) 25;' &0 .86>ถถƒ:>ƒ ;=!‚Eพฏศษสหฬอฮฯะัา’ 5ึึ ƒีจ6998‹7ช�5�ƒ 896๋4๎๐๓๏๑‡5„5ฆืjtpล(ภ U€ใล„GX0d1หว(b h H„"E ๒ฑรDE@NL[ษฒฅห—0cสdVรF‡›บip—#฿"( ัำ€q‚v†‹"Gะ8T}ีQSช e0ศ)56tศมฯ‘„ ’ƒB�0f- เ‚…ณ-๙ะqˆคˆƒŠไ*โน3+^ฬธฑใว“j€8$YCŽl“เะ`ˆFY•/kหมAPำาH›vฺ(uiWฅ!HA8S7&ุPต‹lีฒCะยM€‘์=ห`A„)!ฒ๗๏เร‹ฯI๒* DOjGAQAฆาc�•mฒ,ฃrŸ‘~๗}vQUyp8่fเ#ฑ€!หQภ /8bA…‚ƒาไC ˆ`H‚๐ฐWA๐ๅ,ถุ"0ย่bŒ2พHใŒ7ฺ#Ž;๊X#‹4bภใ9ค>"� dŽK๖ุ$‘F&yไ”RV๙ค’E2™ฅ“[้"ไ…)ๆ%5ˆA๒Mฒk…ุ !i ยAฆุ@ 7ภAUvโูศœu�™'#4€รXt"‚–‘‰ƒษ — 6ฒ�, ญ€&ฤD>2ข.'ฤฐC$ภั"แ๊ซฐฦ*๋ฌดึj๋ญธๆช๋ฎผ๖๊๋ฏภKซ"ckฌxŽ€่ฉ‰eฒgVq0–žQ]ปเดื2r-  ๊ม 4ธทๆWแผ“ี"*ฤ !โ p ฝภB!(A!ฃาŠA์ ฑ†0รม#<ฤย 'ฬpร ?์ฐฤ�3<ฑลC|๐รC\ฌ๑ {�qฦ#oLฑษฃ�qศ$‹์rห0ซ\2ศ'ำœฒอ#,ƒ <๗์๓ฯ@-๔ะDm๔ัH'ญ๔าL7ํtั@2งฃ‚T๋ˆ{ั’ีp:;งHตฃgOฌ‰อศืaใ [kึ@ƒeธั o6Dา๎ UภผŽ  �VศE ภ๏uƒ๔p๊พEŒp์ใWBภำ”Wn๙ๅ˜gฎ๙ๅQ?’š]ฯืH8€�ณƒTปๆ eY“_ฌ โ:#ผล๊„ะะ้9hทขI๕�hฅ‚ภp/lU0ษ†…cยแ$ 2ยภB ใƒใ‘gฏ=#0€�0@เ @๘�` ๚แ›@๛็ฃo>๏ฃ�๚์ื_ฟ๚็“ฟฟ๚฿ภ๘ะ7พ๒ล/|๕ปŸ�ิ๗พ๒ฏ{เฃ_๛พ7๛o๓s๛$˜พ๐แป฿�๘Wฟ๙ษ๏|�แ๕wB�OTD!a›ืTอY„ ศ์ แั….uK@jข•žขธftA<"กขUจื}E7้แ#๎Iจx(Dผฑต่มงVๅ@_๐ล„เ8ลใ�‹ฃ็Hวว€€`ภ ๊Sตน9E๑€J<ศโ;฿uรM‡สš6ภ€nฬC J7 IAขL๑ $%ปน6B�Ž\ ะ€ z3ล<‡hฮ Z…\QiŽ $ ถhJ; )†ก—\zมD| „็ี๑˜ศLฆ2™ม“wpEv้ ‡€ภ1ŸิDS5ำขฬ5ห"p„ƒ3๐)“8ภ9p, ‡โ^'๑;ž€ล'†C&bด0$‹„ TคZ0ฯศฅŒplDถฬ‚๔ ญD9 ภำ€ดDเ9ัUP๔กา0€โYขD !๙!� ImageMagickgamma=0.454545,,‘ †( 5 < #( ) 25:% $0 /75>Zัข‚ื จ@ภ€Ša˜–C�C0ยฤ‘x๓๊�หทฏ฿j ฝัาQอ †๊ š!#ร žnp่yqไษ|"fyณๆFเPฎช่ Tญฐเศภ‹Xธ@ป๐m!บ†Tฌ๕ทท๏฿ภƒ ง4Cด!74ž$ƒ†!™Zษำ1ดแเ9ฆถ@น$–OId–[Z ็•H โๅ›aF%™P๙ šIjy“rถๅ›Tjyฅœ‰�๙J˜Y2CyWญBSหE‚Za47i<ก&cอ€š)4ศ รLŒdƒชชฌ.RฯOุ0ฉ)้  ›5ฒA+P ฿ ผ`#ผ ki…P >์Wฆ '่๐ร#4ภศBt๋ํทเ†+๎ธไ–k๎น่ฆซ๎บ์ถ๋๎ป๐ฒ{ภ )ิ› ๖โk๏พ���๏ฟ๛๊ ฐภ๙œ/ภ#ฐย�ฬฏร(8์ฏย�7ฬpฟื ฑฦง0lt0ีwิ ุถศฅ†ธjuƒ ฺxpรฬ7ป*ณ;9kำมอOuภtง–Ž8I)ดB!ผP$-<อฌ"' 1ย ๘ƒ-@ d—]vhฃmvฺjŸอ๖ฺoป6�sห�6ูlA๗�1ไฝท�vŽw�ƒื]8฿~�๗โŠ7~ธเ}นแ“#NxธS๑ๆœ๛ห๙ๆžŽ๏่“�๙ฝŸ‡^บ้ ณ>:๊ฉปฑ๊ณหฎq์ฐทnป๋ดทžป๏ธ‹~{้ร‹Žฯ7� ”r@ABษา%งฬ‚ ฦr:ฆ>&�ฑbฃ�M��ƒฦjช:†ซ ์:$;HิS?า~+ม?… 0 ƒ์รต‚†Cภเ ‚ศภ่uเ8ฺัTFๅF1ำ‹Nn 4Ž้เมรม๏Œะ%XษO20”\:Q‰Dค&ธภ=[ˆูR^”@"ย€ ‹ ฐHLข%t„%:๑7ค้• ระ@OT\๕Tย*I†‹หนL#Vbjˆ๑)“ฉ‡ฬW2ั&†Hฑ4bXv€k๐@  ๘มด5ฤ๎ภCˆศษศF:า/X€@ƒ2"e…˜TKRูeˆNMoสaŠ7ภก€c”6(ๅ)%eษAา”™’fฐˆ, SIZ!,P€ .Pศ WbF -XA0‘ฌดA?’ rฐA8€@ ม#ทษอnzs๊G `าl๒ (D HWen p! o!"y$FDQOXVa^ifqmvs} yJJJSSSˆ$š( *ฉ,!ณ/#น1$ƒ"าXw&‡(+—--ก//ฅ11ฌ33ณ5Š#†’&Žš(–ข*ฌ,งณ.ฎถ/ฑผ1ถร3ฝ๎d†�jห5ล�€‚ƒ†† ‡Š‹ŒŽ‘’“”•–—˜™š›œžŸ กขฃ‡ก ’ฆ‹ช“ฌค•œ#Aต ‚ 79‚Aฏมยรฤลฦวศษสห”1ฯฯ ƒ455“1จ‹3ชฮ�ƒ0ึ2ใี็‘ๆ่‹1†ฺฆ0210ฎ) กhAPEH)ชH˜Bะ‡ !เR(ว ์(มฌฃว CŠIฒX Rnเvก†ๅ๘1J` ž .]˜aMฺ wฤ กส�หก2•ปฉฃฅƒxššร๓AXA๐เ  lU‰‚Yณ+V*Dะƒ_�‚XฤรฒJ๊�หทฏ฿ฟ€-ล่ฐ่ช 5l.šxŒฌท๔ gA๎.[ฦ\ใrฃอ้:?ญA€kฆh”ฆ–ิP ZxU4กE�HZH"€=dี „ึƒภศ“+_ฮผyงม�rย˜)ƒหฦ‡3E“rKT ฌอ๛ | ศ‹ศ›Gฏจัะ5ฆ–�P’,ฒ-ค„BลํA๔ — 8ไ`C€6@‚ภ‚ 2Xมƒ6a„N(ก…Bxก†Rธเ„l่! Šb‡'~ˆกŠฒ8b‰(š(cŒ4บ˜"‰+โุขŽ/ๆฃ yHฆ ‹,�d‘G*™ไM„ฉไMD.Yˆ)Xy%U*ideQ.หMI&yd˜0ษฅ“เDY%•^N‰ฅ–`vi&˜eฆ9feyž™งšU>‰ง”…Tึๅ”‚ศ’ๆb5`…+ๅฬ@œ†Ax6ษPš!�M_d0L€u•ษ*uฐ&€ฉข6๒ุ5ะ รงช€AN‘เ7› PV@’Hภฐ‚ะฤ…@‚ ภ…Q#!ํดิVkํตุfซํถ�v๋ํทเ†+๎ธไ–knท rยบ๋šภ๎ป๐ย๋nผ์ฮ๛ฎ ๖�Kฏพ�ฦ›๏พ๒|ยฟ<ฐภ๗0ย ๏K๐ฟ๓�ภ�l0+zึี Ck†˜ZvำผwHง‚hPŸuะ€สฌ™์ˆหฌ‘๊ชล0 vkjึœว๑!บ‚B \ํI-D`HA๐P…ะ@€=Lิ๔/Tmตี?d๕ีZouื\ƒ�ตึa“=ถืUw�Cูhฟ 6�kŸwฺbำmถ�mฟ-7�|๏ํ7�sป]ทเwž๗เznตตทแ๋๘ใŒ๏มO.9ไ”;žyๅ๎b>yๅ›ƒy็ _>๚ๅก{>:้งs�นๆฌGn:์ณ;�ˆษrk-}ใ}A�z้ 8ๅฎษฃ&–“:ษำ”{จ2b๓้ะ๐”ิ„ฺาT0(€V�;า๓"ตษ 2€88„ƒXฤC๘p‹s๘็ฯึ๊๏`8ู€ jเŠๅศYฮธ๑˜™ิภ;5 Š žaซf…‚่�ูฃ”•Xใ�‹Uiƒ HŒOน™$"ะb9อ7‚B‚ฤ…;ธ฿�vศรd4่้๊กEB“หPo€›b„*ด3ฤPfdMณ™)ข4คมk ง๐1แ JsฤGœpHEƒD4`ก฿๚na ทcˆxฬฃ๗จฟ,@ เ 7d… แ" 3ฤiฦกฉE$ภ{.Q#€r0 จd"‡ธ‚`R“Š!‡gC+,เ2Y#PFภ ภb™‚aนฦ–†X แZิโ‚ะ.tเ๘๑๑˜ศLฆ2?R sP๊0อ$เ!fต€E,Rฌa”ณ"D~xณ๚fวjPMโyV^4ฤ�ำLฌ„า5‰gCภ‚xฎภ|นฬO.)ฐˆ8เM๓ภิ–Iะ‚๔ ŸHภl"0@&xง"%ฺ…:R1ฝจH ห~บฐ!๙!� ImageMagickgamma=0.454545,,š …) 4 " ( ) 25;* )86>=HXgs|!B%@>HVen o!"y$FEQNYWa^hfvs}!zJJJSSS‰$˜(ข+จ,!ด/#น1$ƒ"าXw&‡(+˜--ก//ฆ11ฌ33ด5Š$†’&š(•ก)œฌ-งณ.ญถ/ฑผ1ถร2ฝ๎d†�jฬ5ฦ�@€ ศ$ภP:ŸะจtJญZฏุฌvหํzฟเฐxL.'32=eŸฏnต5ะ์6n>฿ށ��๘ 46B > rŠ‹ŒŽ‘’“”H .120H.œTž I1lŸH™/ฃ-22ฎSฑณฏJ.Gบi-..-qO&G(*อUศC‡6 FC y€64 >F9"•ๅๆ็่้๊๋์c 2- qฒธO๖2๘2B,d’‘เศ† 0ฑ9h!! bI&4%ึ‚!0dค‰แโBปข<`ฆขภ‘(ก"™อ\ฐใ nB|p 3D�Žv@ƒ JดจQ)-^๙  kExB�icƒ 2ค˜(๑ ค“*L9‘ขฅ>>8 ุ |vpดฑใว#K†๓ฯIฉ XฅภลŒoAๆ~์ย€‚LปฎTาษUNฌฯR�ธถญ 1ค4iRษu DHม/>„ธAhšศจac…+คุฮ;…๏฿ปƒ๏}ผx๓ๅมŸWŸž�๖๑ึป?_~�๖๗฿ฃืฯž��๚๘ู'`€๚—}๛!ุŸ‚�% BX`w�)ัE0€�pุO‡p!!ึ‘††zุฤ†f“†ˆht(ฤาa†ย(D†5z˜b‰ ักก‰�๔ุฤŠ1บŒ)ฮXc ‘ฃŒRูไ‘Jผฃ€.-X0ฤ;$Ub†9ๆ/ธ…„hCภ•ฦ ยไVส›-ดnŒฝ ƒ—ี6ฬUbฝdWล=^เๅR>เ€4ซlณฮ[mณา"{mถสn+,ตะ~kญWน๐ย�ฑx œฆนT ˆ‰หœIฐ๙V\sj—พฬ๙�บษ๏-dC žaถ‘,ณ@ไoIิ%ม^&เจ\—M 7 ยs |˜uฆƒ•f“D,ด์ฒห<ฤ๓ห2ฯ sอ4ใ|ณฬ9๓ผณอ-ืฬCฯ@ณ 4ัC�œtะ:3ํณำEญ4าTOm5ิK�ดึOs๕ึRc]ตุWซ�ฐhง�mทj›vดlฃ=ญ�oฯ�ถฐrป๗ดqำ�ท�o๘��7�ั~x฿kž๖W=$ฤT๚6„YCPTžf(UeIˆ9ZฟUฦ ้e–•�pฅ~:มภU็�Uiผy JM๑O!A^$jา!3 ฮLy$ำL4่OL&�๔ิ?q€ชีg†=j’ รเ;ฅ'๘ ณ1•๖€ !@ไํทฆf/ฤ_Q��)ะFjzฆnปL&@4ใ€1แIฆ„PƒšAั‚v0€์ไ‚ัž7ุ ๙Šƒ ฌB เ5น�ๆฃ‹‚P8ฯค๐้ำ'พbฬ0,Pa?p;X<ฤ3ตS“˜�…ภ'€BpP—�x์9๐€žw„.ษR5 ม!ย.z๑‹`,สGย9KธKO6T‚ผ†&๔)€s๒˜\ ภ €X€"tดใ\เ.<ึ๑ŒH(ไึr0X€);‚J„—Œจ€.xภdrDใ แbCจA๒ศ„- 5๐@ล0š๒”จLe#l!ƒ $แธ๐ำ … บทP$ |_Hเ'Y�Oน��ไนฌ“ˆRqๅhวYpd–I0 +ๆHช G`†€ษ! ภ*{ยฉสrš๓œ่ฤย ฉˆ๏ xg>๘hบ}๒DG(๙„ !๙!� ImageMagickgamma=0.454545,,‘ †( 5 ( ) 25<% $75>HVen o!"y#GEYWa^khqmws~ zAAARRR‰$—'ข+ฅ+ ฑ."น1$ƒ"ฐVmาXw&‡(+˜-- //ฅ11ซ33ณ5‹$†’&Žš(–ข*ฌ,งฒ.ญถ/ฑผ1ถร2ฝ๎d†�jห4ล�€‚‚…†…‡‹ŒŽ‘’“”•–—˜™š›œžŸ กขฃŸŒงกฉ‘ซ‡ญ’ฏคŒŠžด† 9@@9„ 68‚@ ฒศษสหฬอฮฯะัาข 0343…4ุ‘0แโ0Œ3ฉ0ฺ†/�๋†ื1์๒4๔ไ�0ง/โ4ฤZ!ลŠƒข( ษ +T0 ภC‡…ๅธก"ฆ‰Iฒคษ“(S’L@ใER] ป๑8่ไCฦ"30บpF‚x4.T;'ศ]Mk8 9]€ป…bะ85s�™ˆPภ€‰ 8˜๖‘�' ˆ ศ‚>้ˆ{E์จฅฒฐแรˆ+^์ F FfZ`”ะ ‹‚มaๆQAhhฤๆะ˜”N�5iำ�ฝฤr+qซzศภ †ขtลข< x@0žNฝบ๕ุ๋I…บMี’)ฝx|ˆ๒gงTZน6น™ฺ�?๒ @พ#wLK�ž‘@ไJฌ@˜+D0�#kEฐˆ^พˆ„ �€C @๐PC$dจก†tุแ†~ศaˆ ’8ข‡%ขxขˆ†XAŠ,เ"Œ/ฎXc‹&โจขŽ1ฮh#@�($7ส˜ฃ‘;"�ูใ‘>ค“C*Yd“RnhevXBยRภ๐ย7RแCV“pSOV�ฒๅ64โๅx์@ /ผเ“#ๆœ/„ื@Iะ•mธ€ม ฌEb ‚‚๘om5โ› `pฟ!LGš0@,ุะรเีศ?คช๊ชฌถ๊๊ซฐฦ*๋ฌดึj๋ญธๆช๋ฎผ๖๊๋ฏป๚’ๅฐ†ฬไ๎€g71๐VK�’็"๊งA›ปmะๆตqžรญ#�ๆ๙ํŸ๛ผ@™œEัเฯ$ฌ0!)œคด‹ œ…i7กC9\(๖ะฏฐ‡เยย 3์รร7 qฤ�O,ฑลC|ฑฦSผ๐ฤ>l์ฑ ‹rว'Œฑสณ0€)๓��๎`��๘  ฟ�๔ƒ_H€๙b�3…��ื?๖�ฯ}  ็็?๚‚�๋_�วพ๘ต๏}„_ํม๘ี/‚๑๓1ƒี ๊‰"ง๒ฌ‡Z7Dž6\ฃC๔ภฦ๊ษ†GsŸัD|TXโ๗ศ˜xRQ$L !๙!� ImageMagickgamma=0.454545,,š †( 4 = ( ) 25;' &0 /75>h :จ2€ฆ=ƒn$วcF๋fZภฎ๋A�ฌZก"ํูA^:๐b ฃ ฝ?`hGW=๘ ์—ฤ_ฦะฃKŸNฝzฆ3y�€cฒ#์†pdชfั �,0W{Qึํqฯฆ€ุC๐Lyh เฦk๛=ขH/�&œZจเย[†Tเย ผ`A!90HDั !ฐ0„r `โ‰'b ขŠ(ฎศbŠ.ถ#Œ+สX#/š่"6ๆˆภŽ=๒ˆฃ:ฮXไG๚�ไA6ษไ“I๙ฃ‘S"Yฅ’T.ฅ“[Byฅ”Z~ษฅ˜^ขˆ€u-y#kHฅ nB๖Mใง)5ฬ0O�แฉ'OŒ๔ @ž{6‚S�ัภU�p$@mตเqPเ– ฉ@ˆ0#B '� aH˜ƒ@Œ0ยF‹ 0ฤฌดึj๋ญธๆช๋ฎผ๖๊๋ฏภ+์ฐฤk์ฑศ&ซ์ฑข‰R} bƒj๕yทด†ฤfˆyƒt€ƒ฿x €ธฑศน\™ปศ ไษๆขCต#�!‘d R€ +HPฟ„�`ห"'!ย ˆ„A4�— Gฑ�S,qลOŒ๑ลk\1ว{œ1ฤ ๒ศ2”|ฒษ"ณLrว/‡3ส*ทผ๒อ6็<ณห)ร�ณฬ?ำ์sอ;ใ\ดฮA๓LtาF3tฤ1ค ๕ิTWm๕ีXgญ๕ึ\wํ5ึ(8Rร}๛=ๅ่ybซVˆ7DKH}hร‰m9vv๗ำg74"๗�tฃึœ4ฬฐ™)ำ*ฐ ๘@Z !šVV ๙ฒฟะ6ˆDX+0 ยซกŒณค—n:b|ญ๚๊ฌท๎:ุ๒ล <์ิn-!๓YvhsgC=าเ;๐ป[ƒร๏‚๏wMN ฮจ โi ธค\“ผ€ฝ ;ฦˆ0�%"ฦQจงงฏ�๚ฮ @@@เ>๒็�๛๙ำ�พ�๙s�๐ง?๙๑O~�ƒ_�ไะ€๔S ใ@Bฐ๓3ล €?�๙๏;ล€)Xƒ6Co3%ไ� jrƒlT†y.4M#`(B๚mvีpžQ้)dq‚ แ‚ ๔ๅ7@ภvะ—@ 6‚—ƒ}™cŸทศล.V'OŒ`อd50ขsขษต€tฌCX‡‰Gู‘ั(t”ฃก:@็MkˆฬผQ€hŠ๐ Z0 q+po!EคลSƒ‘!‚А!เ<Dzx๑”จLฅ*Ÿaƒ4BŒgฌ“ด\ฉ-C(ชv๑a j็C�Qมม!€_๖r]|„ูแ•‚!iศnสrL‚I6 ข‚ศŠšถสrš๓œ่\†nWฐs†ึJ€3Eฯw.#0@พ๐ฉ/}"!๙,,‘ †) 4 < ( ( 25:& %64>HWdn!p! o!"x#FDQOXVa^ifqmvs} yAAARRR†#š(ข+ฉ-!ฑ."บ1$ƒ"ฐVmาXw&†'+—-- //ฅ11ฌ33ณ5Š#†’&Žš(–ข*ฌ,งณ.ฎถ/ฑผ1ถร3ฝ๎d†�jห5ล�€‚ƒ†† ‡Š‹ŒŽ‘’“”•–—˜™š›œžŸ กขฃ‡กฆ‘จŠช’ฌคฏ‚‡%Dถ"‚ ;< ‚Dฐยรฤลฦวศษสหฬ†4ฯะ4ƒ887ั4 ‹7จฺ ‡3ี5ไƒ78่‘๋ํ้าƒ4ฆ3543ฎŒ,ฌ(`H‹Y€d`…‹.Ad„."…z่ 1€อBŠIฒคษ“(C}Xนา† AphH`๎฿!58t่ภA� 2aฒรกภะ™ h€dnฆR›†š&]ฺศ6A์L� กรVHZผxฑpะ าVุศ€‹� L˜เA€ า‹o‰) Lธฐแร”€nไUขh|x4ฃษ1‹ R,่่bฮ<;-บ*ŽษTำŠšTณ*"5ดยฅณ‹FT ศ,พˆp|€ธธ๑ใศ“+ืคฯ^ะ/#ฃf๔Xžฉaโ ง‡ด˜�ซY^ภ๑Žฬแ0ut=จ=เ€4ซภlณถ%x1ั"@ ปไ`  เ‚ ^เ ƒ >aƒFX!…Z˜!†*(แvˆภ‡!‚ศก‰^˜โ†+ŠHโ‰%ฦใŒ-ข8ขŠ7ฒ˜ฃ‹8พXฃŒ?าธฃ> ค‘B�Y$ƒ,GŒ�Eี @Bƒx�Sรtƒ`งฎ]6Csaฺ0ftŒ|#€5ฬ๐š‹Tv �นwรฤค$๖•%ศ ญ@]๐ย !ตแC!„˜ร@Œ`Q# ก้ฆœv๊้ง †*๊จค–j๊ฉจฆช๊ชฌถ๊๊ซฐฦ*ซฉ:IŠj{BM;ฏ ’ุเ�!j*โๅ ฬ็•๒,˜เ<;ฯ|j6[=3<ฅVีxืซ!}ˆตย#ฒฑภย*ผ  บ@ต6 �ีzH2๔๋ฏฟB๐ฟ pม#|ฐภ 3ผฐม�,Dร�ห 1ล?œqฤ s์ฐว_ฌ1ฦ$l2ศ[�ฑสณ๒ส"ฃ\ฒฬ'ปœrฬ6ฯœsอ8ใ์o )-๔ะDm๔ัH'ญ๔าL ม#๛ๅ1ู๐ญ!ษๆ PZrฌ ิ`ท็:`nู„}๖ ้q@อ˜1i5Clu5แ.RปŽศๆ]*œ�‚ˆ � <๔6Aเb๋ใG.94m๙ๅ˜gn9 Ž@้3hื๕#@q0HeŒ| @ี๕<”6ด>ž"ฌ ๕ตุแA��ฉ�Uไญศ~๙1b_๑ผ€ฝ$ B‚>@ฝ๘เ๘ไุgฏฝ`@y๗�ะ�ๆ—�=๘้›2๘�“o~๗kขO>�[ห?๗ๅวฯพ�๗๋�๗๚G๛‰r฿Kฯ์ฤ6ˆำLB5‹ภcพtีๅŽฅภท†ำ5bƒ aD?P™<ู 5ุž#„wผ€๛:ฤ[8Aแ G7=\$./มุž‡Hฤ""ฆMŠธ:ฅฎ]ษ'X€`ƒคcK‹H€šจ€t˜#๘"Sถฦ( B)>™ห๘นrxP;r[@j@•Fภเฯสbเb!ย์ญ?y์@` [่@:เA.z„ๆ๑’˜ฬค&~E0`(8!„EAPฺ Jะฒษ•บ5ฌญญRw?ฉAทTYvใ'ซœS� ๑nYƒmT ฦ2–sเ!ciมม‚Cข]c)!เ€Z@_›ฬฆ6ทษMO@‹�๘ฆฑบhrZB‹Y ฆ8วY’ ƒ ( ) 25<' &53><***888GQYgs|!B%@>HVen o!"y$FDQOXVa^jgqmwt| yIIISSSjjjwwwˆ$˜(ข+ช-!ฒ/#น1$‚"~ฐVmาXw&‡(+˜-- //ฆ11ซ33ณ5Š$†’&Žš(–ก)œญ,จณ.ฎถ/ฑผ1ถร3ฝ๎d†�jฬ5ฦŠŠŠ—‰–––ญญญถถถยผบวววุุุ็็็๕๕๕�€LNQ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ กขฃคฅฆง™MจซฌญฎฏฐฑฒณดตถทธธOนผฝพฟภมยรฤลฦวศษสหฬอฮฯะหPOิOPีีำีืั฿ฟPืโ�เๆ็่้หNู�Žูู๏ึ๐๊๕ฏไQโ๙๘๚ˆNๅฒศ๕{Dํำ?N์.ดวฐแชy๐ .๊‘ั?j�ด9�Šœ5 Z"2 “BP™rยคๅ’“‹˜xsขฒS“]›Z"ษฑงOM#ZS„1ขปDA�\z dQqE๒<4๕ ฬR4 ZดคะอOLpj {i*ำณh‘V[ฒ‚ล’x�‰ {H(ลดx9�8 $U'K^Š ผ„aj‚‚๒6YKY ฑŒาคๆ�ภ[i2y‰สๆย’4แ์๏%Mœ,I?�jrš –*&ํXqกูOฬŽด*8Jใ|บ๓ wVt…๑pูญVณ๎r‰รฃ๏๋๋ฑzษ—„XWํ |๑VซQ"CฎY9 x๓]{k"3jฺ์|“5ู�dU+Yฟ}๕�ฒปแyM“ส*n-ฯ1OPๆชŠQฐใn'œธ"�-z฿‚ฦุ /Nฌ"-‰๕ค�ม็_ก…่fU‚๘9(`n�มT๊|" œ~™�ลhใจิ›พ|ฦฺ๎วญคŠQ#v9ย› ฯ๚nH๑žวฐdo�k›o8MIIธท™˜กๅ๙™JRŠ4�iพ>ฆงIส ฅ‹˜กฆุW& พ—๕–�U)g2=ๅ1"^kญ2‰ถข๙๕;Xฏ‚ณO]n*๖�pวP>tำ=N&วขr฿ู็ูฏr.๘เศ๐Љ!‚�!แŒ7๎๘ใG.๙ไ”Wn๙—fฎ๙ๆšทส๙็.zๆžพy้ฆงฎ๚๊ฌท๎๚๋ฐวฎ:๊ฒรZ๛†ด฿.T๎ฒ๓�:/�๐ฤo�๑ศ'ฏ�๒ฬ7๏�๓ะG/�๔ิWo�๕ุgฏ�๖�w๏�๗�เ‡/�๘ไ_|๙่งฏ�๚์ท๏�๛๐ว/��๔ืO�๙๖็ฏ���๗๏��  h=เฑ`L ศภ:๐Œ ๖ฺ</P@๚R๔qp{P;จฝJ๐„(Lก WศB๋ญ ƒ  ค๏I@ฤ#@X€พ( a{) �ต…$ด๐ˆHLข—(ภPxH0oœเฝ(ๆp‡=ฌแ๖ ร!f/ ZdขวHฦ2š{,จ ๐ฆ(hะy\lž‡G(๐0Žฤรc๑๔่ผ"ฬ$ฐธG�=Œอ€!ฯศศF:๒‘ t"xฬก,‡‡*QR”5๑ข๑4™„N@˜ยฅ ษอnz๓›ไKใ$…ง‚B,rš๛@ยI(D“Du(ทDม‚ƒX ฑMZƒœŒแ๑Vใ$๙�gถ ์ข˜ ๕'Pแ `ขฤK(?eXPฒœO0จ4‹ืFqจ๓žข+IEpบ๔ฅ0้๒$)P]†g›ษ+i?}ผ“ฏ$' ขา’)@’YNJ๊—:ŒBRp�PไMใ|L%ค™pM'ดŒํไ"R@U/.UšAt๊+uุRVเขOxฃ;Wา>ตงQ๘)Jeสืพ๚•›’|f๐ฺ™œาตชž ^ศI�อ–~ ^2=jXx๊pฅƒ)๑ฺ๙L?RVx๐๔่(I‚œฃzฑช $G+๛”3จXLซ๐ชj<ฮฎฑ ŠM&6�ส��๚‰4%^ห‰ฺูFa–w}'(i๛ุเนUฒ?๔h(-ซZฺฏœศEคtA�ฺ :A ๅl่s3+ผณ๏ณ๏l-AqฺFbืนึ๎^“‹ะๅ๗ท๘อฏ~(ฮgjฐm #:-่ัYบ–nก@ 9��ฌ:•1Gํฌf‡'[tๅ‡Munbฟบ‚ิ&ณมาTํƒšุืพU<ฌpWŠหวแrิภ B‚๗Kใ�x~ม%+cขธ รขผีtย฿๙Jf‚U„žํ` คเ$Iq๒๊…ดgˆ�X ,Y`I†ฎ๐จส$ฟ5หO–*ฺHฬ&\ใ‡Tถ๒›‡ท‹คŒ*ˆbK…ท ��๘ฯ€t๙KI% ฅ >aGฒศ“„เก”ื\ุฦ0พฤ#จyฺ9ฤTšปซ 3yƒ็a๓ฯำ…ˆกGo aQบˆำรป†ฟสhโ9Zะธฮตฎฉwภsฎ9ฏ™ฌฒฏบ็�F`ศส#ภŒฅง์ใ5|ฯฆใฒษzlใภวm”ค๑เน๋n{๛�ฮ>&3นW K +‰�sถ‹'4��๐Žwฎ‡�< ฆใ, ํ]ผqT�๘~้]ฝL��ัธย�[‚3�แ8 .๑Š[�โ|ฅ8ฦ7ฮ๑Ž›QใรC@๑€€q#ฏไOนส�h< ;/ฯc๓bNj่ั||€๑r�<ž“O็ห9Np„ข@x=(๚‚๐€เ! ?A๐ p„ฆฏ�๊๏ภถพแq [ื˜ท€l= 0^t๐F€เiž tฐธ[tวA�•gƒญ��=yธม๐8p ฺเ7ฐn>< ผ 2A„ื‚ศหเXžใ#ƒษ'๏/^^ ๓ผภ.ธะ‹gฌy มHเa�(B0!=(มํ `�๘฿ภ8 €พฟัฬ_@฿๗~ผ่ภ Pb.€ๅot฿†‚ๅ—ํม+?ฮฯ๘๔๏`์O^฿ <ฐkP7เภฺฏผP Py™pp0z�๗(x<•7ย2 s1๐p1เฦS2@ฬr(pมฃUW๐3p�Dภห“เŽแ˜ไHŽโXŽๆ8Ž่xŽ๋จŽๅศŽ๏่Ž้Ž่˜๐8 P๗h๒ศ๔ุŽ�‰๚ุ๛x™้๙ )IY ‰ฉษ™‘ษ‘น‘ 9‘)Ž ฐD}—:€„ƒ็}ษฃ… ะ‰ืuฤƒฑ8ฺฃ=š?คB ค"TคGšคF๊ฃHสฃBฺคNสฃ>F<Œุส—Cึƒภ<=ˆ~px%vฦ3›ยฃuึ7vx—“:่}i:”kŠฆ:  u<ฉ|t… ภ:€ฅหSวŒะง2เœึyt่-†ุ@ธz–รS็ลrG๐ม3Gภ—ฤณ‚ฦ+ง_Zxvฺ”ฑจ…ูz<.สฉำY^ฤในXจp‡ๅ:Œn(ฉbhษ3•้*—ฬS—ยGd…M‡zy+xtฃJuVฐt+h{švZ7‰uท|ปิgvิ—�ท•มใ”cสŒศู<}ท0}Œซƒ[ŠรธrงŽ นั๚ณšศ”ืท€^z<‘๊@yp™W•๗zะฉ•2เจ๛kฎตŒJ/`‹ji<.๐0•d(ถหJw๕บ‚J'ˆศ‡><Dเฉu{ฝ~ศ‰…=‹œ[งš`ง’‘ปuปช“ลcv�ห€พ>Hj่ซK�”โ๗G์ฟล#œรsดแ‡3{<–gyhy0จรC^<‘๚ฟgyปร“ตœ็ุz'๋‹‘‡ปด๔<…<ื(œม&\ฤF|ฤฮˆฤJผฤt{pL�ฤP์qBลT\ล7ลVœลZฌkXผล^�ล4ึล`<ฦd์Wb\ฦhœฦ�tฦj�ฦn\Fl�ฦr<ว-วt|วx�@vœว|�วดว~ศ‚\?€<ศ†|ศ๋SศˆผศŒ�=Š�ศษ'ษ”\ษ้๓ศ–œษš ฏ›�ษžL=˜�ษขผศก<สฆ,ศฅ|สชœวฉผสฎ,วญ�สฒœฦฑ<หถ ฦต|หบœลนผหพ ลฝ�หยŒฤN<ฬฦ�ฦม|ฬสLทษผฬฮฌˆอ�ฬา||ถั<อึœrี|อฺŒqูผอ�q��อโฌpแ<ฮๆoๅ|ฮ๊�m้ผฮ๎,hํ�ฮ๒lcล<ฯ๖,ล๗œฯิฌฯ�ฌr๑�ฯ S�ะฝฦ}ะ7ะฝะวะ-o �ะD=ัญB}ัAฝัอ@๕�ั"-S=า&�?%}า*ญ?)ฝา.ญช/ำเิา2]ำ๊Cำ6ำใƒำ:�ำ�า>ิ'๔nB]ิ,”HVen o!"y$FDQOXVa^ifqmvs} yAAARRR‡$–'ข+ฆ, ฐ."บ1$ƒ"ฐVmาXw&‡'+˜-- //ฅ11ฌ33ณ5Š#†’&Žš(–ข*ฌ,งณ.ฎถ/ฑผ1ถร3ฝ๎d†�jห5ล�€‚ƒ†† ‡Š‹ŒŽ‘’“”•–—˜™š›œžŸ กขŸŒฅ งฉ‡ซ‘ญฃŒ‹ฒ”ต†!@บ‚ 78‚ @ ฐฦวศษสหฬอฮฯะก443†ำิื’0Œ3ง�‡/ิ1฿ƒ้๋ํ4๊0ุ0ฅ/0๛ฏ‹'TฌXQ`U|0แย@>๘R(‡ ่ญฃว CŠI๒ฃ ;u2ๅสHจฝ3$€ฦ6 3จ%0ิฮBโกณ€จ?CCm4tP ฅdภธa†=†+N(a+LlํสP…Vฎ^Gไ€ �ภ ฑฃPษปx๓๊�หทฏงช‚ะุ 0ม„ฅ1sะ‹ƒ`l8™ธfAํ0ฐŒ™†ๆFœdv„nƒ ิJอ0 `ฺัA'P,:qยkคุ‹>D`ƒG!ธo1:๐Kผธ๑ใศ“ร:yํลŒA-ผiฺ…มŠ*31e จู;๙ 5ซŒพ'ศ‰~QผR๏ศ`mธQ€�ฯ/ฉ~F7มร๐K ึษ 6ุ B่`„>Hแ„Z!†jX!ƒRภแ‡„8ขˆขb†+vุ"‰&ฆxโŒ2ึ๘ขŠ%ฒ˜ฃ‹;ยจcŒ7าค=โd‘B"�Iไ‘L�่$M๒่เ}กร %– vAxk†t7ศ4‚ภ๐ยcญA%ๆšิ5N)1ภIฺSืXๅๆj\0รg€e€ดA ˆ „ž`จ#ˆjˆบ่`ื"ฐpHิศ?t๊้ง †*๊จค–j๊ฉจฆช๊ชฌถ๊๊ซฐฦ*๋ฌดึj๋ญŸฺฅW61ฌย๋kƒศ๐xŒ2ง"จ%– …‰ฃณหถ&NดD;'ตŒผA‚]ง5็ + €B&�G๎ ) ปยขŒฌ�nบ‹๊&Du ย€€<�ะƒฎ‡เยภ์รมŒpย/ฌฐร #�ฐฤ�3<๐ย>Llฑ kœqล_ ฑศ“ผqว {ฌrส,›2ว#ร\ฒฬ'วŒฒห+ใ�2อ/฿ฬsฮ?๏์๓ะ6=3ั3�B L7ํ๔ำPG-๕ิO? ' œิซ ืeMƒ ภ>๋ำu>m‡า"f 2—ข=ท๖ู0€mฮqs!็ !๙!� ImageMagickgamma=0.454545,,š †( 5 ( ) 25<& %64>HVen o!"y$GEYWa^khqmxt} yAAARRR‰$™(ก*จ, ฒ."น1$‚"~ฐVmาXw&‡(+—-- //ฆ11ซ33ณ5‹$‡’&Žš(–ข*ฌ,งณ.ฎถ/ฑผ1ถร2ฝ๎d†�jห5ล�€‚‚……„†Šˆ‹Ž‘’“”•–—˜™š›œžŸ กขฃคฅฅจ—ชญ’ฏ†ฑ“ณฆ‹ธ :AA:‰8ฟA;‚ 79‚Aศถาำิีึืฺุู��ข 1551ญ2แ5” 1454 Ž4ช1๐†แ2๘‚0แ๗(�ง@า††2Œ#F j)’‚ลŠ @ฑยbI(BฆH@€;.x@Yˆ„‡|๐คใ†ˆ „v่ฦณงฯŸ@ƒ ๊sFŒ fศ(ิ!ƒ‚�๚=RPฦf @'Cป �ร๐mž }ึ™„VญD�5j‡ŠFŒ ์N:!กภF`qย@ น"UXผx… ‚4"H3E$p๒`ณ‡3‰ŠMบด้ำจCeจoต\E โJ‚ฑ4RรB1:`[h๋†ณ54๐ \xชเลmWด \�‚ไฝ]48‚ ‰1X1‰…ูฉH‡A–7‡เœบฝ๛๗๐ให7•ทU‹๔M฿šR์ฐรo]ฑUโฐ<อ%ษ‚คœY8 ะภ —TภB.ฐ‘&'ค@™fŒฤ -ูะ“ “ƒ A๔`ร$ไจฃŽ๔ุใŽ>�ศc@9คE"�yค9iA’L"เ$”O.Ye“Fbฉค–QNi%•`~)&—WJ™ฅ™[ขูๅ™^’ฆ›cชYf›rพYgœtๆษๆžiู๊'ŸQ๎ˆ@6ฌฅมr q U h๐‹ศก!x(*2ภร \ @ฆ›Fโ)จœBB[ ฺUรs์f%ˆ(ศ`P’u•LX2AเเมzAไPศ2>ย #ุpC €p$!ํดิVkํตุfซํถ�v๋ํทเ†+๎ธไ–k๎น่ฆซ๎บ์š+L5[ละ( 4ภ`ศn๘Iฒ[ 2d OัญE)lPCง๓\๐มาU‰ยy เฐฉ�d�ju#รt†Dภ…xŒB x8ข$ƒ €9ใ7*BใeŒิุ>ผkH/๔์ณฯ?๔ฯB tัD#}ดะI3ฝดั=�CำPฟ 5ีS?uิJsํดืU_ญ5ึdm6ุ[[�ตฺ_ณ๖ฺbฃ]ถ�gปv�vฯw�x๗ ๗฿m๛8เU๛์‚ ˆ'ฎ๘โŒ7ฎ8( 20๐P!ป�6ษnk�&ŽPe)X\uภแกฆcบจคซฮ!ล‡jบ*3ภ€ๅ”x rศ%v ”m",2ภx…เpว๑ม|ะG/�๔ิOB€ใุgฟx ”@ƒq� `X U๖,BŽTZศjF โ์ฃ�>$๑ป�#0l@;ฬ~a†ฑT$ ฐ‚ (b0„ฎ&ซภ8"2ั0ฤŒ%ˆไ,=:x^๕6ศมzp4F8B แR(€„X!1BŽ(,๓ซDฝฤR›�HVen o!"y$FDQOXVa^ifqmvs} yAAARRR‡#›)จ,!ฒ/"น1$ƒ"ฐVmาXw&‡(+—--ก//ฆ11ฌ33ณ5Š#†’&Žš(–ข*ฌ,งณ.ฎถ/ฑผ1ถร3ฝ๎d†�jห5ล�€‚ƒ†† ‡‹ŒŽ‘’“”•–—˜™š›œžŸ กขฃžŽฆกจ‘ช‡ฌ’ฎคฑƒŠ†$Bท!‚ 9:‚Bฒรฤลฦวศษสหฬอ• 2662ฌา6”3 5จ2�†1า�†56้‘๋ํๅŽ2†�ฆ12๚ฐŒ* Jกข`A‘(ดX(A!"v )ดวˆ‰x˜pฦฑฃว CŠiLภ  2ิจ'(ƒ ฮ๕[”@š\#’ข-ุภl•Hp)ฌ@KB๘ ‚๐rCƒ7D‚ภ…bxม†fศa‡~่กˆ!r8ข‰%‚xแ‡œจ",บุbŠ3ฎHข(โ๘bŒ4ส่c@๊X#Œ7™ฃ‘;�ษฃ?2$’C. e“S>)ๅ•Jfy$–[j™d—`พ˜!’hภ”5จีNa‘(๐’jŒ0ร~†”7lศC 3€็ {๖็ศŸ{๖ูT4ูP%ญ  Ri‘(  -ฐ x9€Z[ูf‹<BH . 'BDŽ ฤชฌถ๊๊ซฐฦ*๋ฌดึj๋ญธๆช๋ฎผ๖๊๋ฏภ+์ฐฤklฏข>’@ 1d` ณwข› 4 ็!฿ภbง ุเงT๗ๆmถึ<าญŸเœ�€ช†'OำL;ˆค†D@A[ฉ ‰B-((p&<ไCฒ 4่C?${H04์ฐร@D๑ร�O qลc|ฑฤsผฑล W Dว ร 2ษ#œrศณ์ฑห%Ÿฌ2ส4ฯl3ฬ+›�ฒฮ/๓๓ฮ2ใ\ณะ7๛œsะFtัH7 ๔ำ=;5ิ?Omuษฟ€ยึ[Cเˆ็ฬภ€žืqๆ ฑ�—ุ—Sv4๕mMูญ๓-�ฃ ๊อb:yภ�บ฿่้k1$`&5’ะหH-4๔ศ-P`–‚วๅ HBŒ0ˆฆ๐C.ั….๚่ค— \w=I ฅึhฆ]sM9‘1ฒํz6P%ˆ>ฆ{ž๓-r6Kผฏ[6ŠฑถŸKูD`#ดP$-ค ˆฌน BTๆ��เ  ›n�๙่งo>0€๒๖.7�‚ด *โ ขx‡�~|7ž๙rbGิคดAแ๋ไรQ‹ฒjา๚๑อˆ†4<  ภ‹NิฒมแรืlQ‡ฒSฯ‰A˜ไฤ a‰Aึ “)`j"(•๐๐”ZศB๔จr8Dง๊ๅส…XOp€’๕…๒—ภ ฆ05!€DqPภ ‘yสC( ™สZ$MxXL�)$]\ใ,ด €ภด!๙,ขK† & 6 = ) 25< *( &0 .65=;***777B QThr}!@>HVe1@%n o!"y$IGYWa^khpmws!{IIIVVVhhhwww†#™(ก*จ,!ฒ/#น1$ƒ"&†'+—,-ก//ฆ11ฌ33ณ5wšY†ฎeนkŠ$†’&Ž™'”ก*œซ,ฆณ.ฎถ/ฑฝ1ทร3ฝฬ5ฦŠŠŠ–––ฌฌฌทททษษษุุุ็็็๕๕๕�€N‚ƒL……Mƒ‰Š‚M†…‹NŽ‘•–—˜™š›œžŸ กขฃŠ“†›ˆคชซฌญฎฏฐฑฒณฐ“ฆ‡–ถŽL—ทL“ดมยรฤลฌพฟMหสŠKฉฦ˜Ÿฯัึืฺุู‰Žพ–ฟ�ง•†บำ�็่้้ปK์Lํะ‚J๑๒ƒMKึํ I๔๊��ำ-�ฅฬœข]๛ :„P\ภ‡#z*ดคลŠ฿้Kฤฏิผ…J)tฅ_$z๑:Ž”ศฒฅKM wEŠij&อF/s๊จQใEŠ๏่•T’d^“$H�MRH “คสœสใตชQฉ’”h5ษD+Vฆ^W๎Kึร˜6‘ณำ`ูท�pe5ส่ณ็;ชƒ’e„ัže‚Rmuถจ$wj่กˆพคฬข‹ ืh(|%*้ค”Vj)คƒ^ช้ฆœv๊้ง †*๊จค–j๊"-ฆช๊ชปฑ๊ชชžฝ*k‰ณึJซญณฦŠ๋ฎผ๖๊๋ฏภ๊ ,Mรบ*lฑ"›๊ฑตเ์ณะF+ํดิVkํตุfซํถ�v๋ํทเ†+๎ธไ–k๎น่ฆซ๎บ์ถ๋๎ป๐N+@ผ๔ึk๏ฝ๘ๆซ๏พ�๖๋๏ฟ,๐ภl๐ม'ฌ๐ย 7์๐รG,๑ฤ�Wlqร41€ฝ*4Po  [@ *จ๒น&_ฌ๒ส,ท์rล,เฃ๋N Bด8มBฝNn ƒ์|nฯ/m๔ัH'ํ๎8้ต.Mเฌ3ฯ4ฃ+DŸ�DีJwํ๕ื`w�ˆNlผํh{„R๏ŒถดoO7ทY;+@ฺ��-m>รwทu_;wุ„n๘แ๚�ขBูุfผ1: ตวฮฎะ„ ค„)tžvฮ,ฌฝฺผ4๐7P@+ˆฎDถ*VuเฅฮฤฮLงอD ซ‡Žศ๋ฯ 05ดด#‚:ด,Pี„ะจ€ืำ:๙j’7๑ทๅ ฎ�๖�woํโ�‚˜m-ูสา Lเืํภย"7็�หฃภ/,ฤ๎D๖๒๓]�ต+ฐ ่3<#๘ศž–๎็ไl�ฃŸ์ฌ1\ž�ฒ็>�ฌเ}B เV@ภ๑ ว|ะุท๏น๐…0$œ๓๎มมj‘/d9K‚ณB’6๕ก/€`ถœqNuDšะrˆฤ#€oืj„ูถึผแญ๎uz!ิ‡6Aค ‚ �โ–Hฝีตž8i‘ิำ—ยฺ๑Žx\™๚$Qร่ qะ|ตฟANj}คฯ�w2ด/g\kcดิว<ขฝฏ†ํ{฿ �ณI4ฎ๏Yu ภ;ุศ๖-ฮ~i�%A™H?2/‚$ไฤ—วZฺ๒–#�โ ็ฦ: ’ฯzFฦ วดถฑฒƒ˜d+ูJi-.uX[ไ�‚ฉฬล- ‹ำส2้ฌ4ถ๒’ิ@ฟฒํ์™ฟ”$ดศf?`:๋ ".็Iฯzโkcd#/ฃลNgญ-uUไE™Fบt2ณŠK„e๏ธI-%bps4;ๅ/a™ฑ ัg cจ"ก5ฦ‰พNฌร`H|ๆPlฎ•z{–.๕>€.N ๖ŒฉLgjฎ'&am0ตแ๚Tฐถ3>‹8ั เWฟ?fMq)ษ3สฦfโL+๘H฿ช�T6:!d็�fSŸeS๓~M๐jU3ฦ„TฃP�๔x๑U}ชr>}g iJืบฺ๕ZH ŠพJ-๒ล่o,๕eด6'ทตo0IH=yPkฐ5)€b9Kม๖!SซตlTJูgฝฏ5่JๅŒูV" dห `;ะปบ๖ตu%-ฉๅรZก–$ฐฺj ‘แp‰7�t€rฤ•[qูGv๖๖ส„ญtงำู๖Uฐะš€ๆŽ8�•Nrป|ฅฎxว;ำŒตึYˆXžxฝ ญ๔Rผ๐/]ฐ�๘าWพ๘อฏ~๗ห฿�๚๗ฟฐ€Lเ๘ภ^"ตp-�มŽ๐ทn - cหยัยฐผt›7 ๋๋ม�2ˆŸE€แั๒Œpโg@ล,F1๐ ˆภY0$ฬc 5H@ดhƒุ@ศฯ ŒŒไk™ษิ๊H๗ใ W8E>r๐ฐ el)นหีA  ลฬ‹5จ Bเแgeเ.xœเ,ธ@2pมˆซี<หเt€Šฐโ?Kล#€@Œภ` ZัŒ@|PF`(่ฑฆผYะย2Pƒ);Kิค6ตตP]j pVง?๊l@ญ>ตญS�f`๙ึนฎ‘7๐,O�ฯ 5เภญ8cเู0 ็P /ภ(``�YA๘tLb#œภY=0B *hntซ;FะŒ  aำ๘.p Bฐ€ฺn9่€ฎ�๊ �Zฏธฏa--4?k฿��7s`๐…วบเบŽuต0พp…S‹ศ!p–Š|์ 9่๕ 2 ญ ศ@ฺฐ€ ฐ- ศเม~น5# 8+zพใA่๔žท Œ|;=ภ๓J€ฟŸีo!<cฎ:Pไ1WK๋W๗:ีsะไจO]ึd฿zื๖ต=ํaทึ“็’&ฏ{ณ[ - ฤ�เYถ%gh้�ะจ4ƒ‡๐ƒ!๑‘‚~po F Bฐี€ฮ{�๓}่?/๚ัƒพ๔คG�้EŸzึฏ�๔/ฝZ๛ศž๖ณ}๎cฏz�ป�๗ตฟฝ๎qO�แ๘ปท}๏•�{ๆ๙ยG~๑ฅ|็'?๚ึŸ~๖ซ�๎C�๛อ๗~๘ม��๑›ฟ๖ŸG.ดค.q”ฯห4 ม Nžrภ_�ึrฟ�ใ?hูภไ๋wv๔๗~�Gt�e๕‡€rWถ7เ€๓r4 �ฆqึrg1เ๐,2b |w-10‡c;˜KG3`,�(ƒ/ุ‚p=๐E@$เี2<„B8„DX„Fx„H˜„Jธ„Lุ„N๘„P…R8…TX…Vx…X˜…Zธ…\8…ึล~ฯ๒9ห&z'†d8ehX-h(eฐ†ฮโ†า†ฮา†j8†hX†zfc่†{๘q k๕ทd]ืkP€0gfHˆ-เ0๘,‡๗,Kงs$=P.จcFŠฃXnD@*ึhpฃฐ‹ฑธดH‹ฒX‹ถ8‹ธx‹ปจ‹ตศ‹ฟ่‹น‹ธธภ8Œ:PŒวhŒยศŒฤุ‹ฯŒัˆŒสุŒหxึ˜ำ่Œ�ษ�(฿H�X�ˆๅจแศไ˜ŽๆศŽ่ธŽ๐8Ž๒Ž๑H๓(Ž๖˜ศ(‹:๐…ˆrRkJF้k 8-ษp้, €€ํGv ‰9‘๙'‘I‘ย๖(งf�vl4€6€ˆฯbsเ,ะg/€.0‚ุ6Gsฮา‰<—yBB t=G9น“ฯ>0กX#๐tHู_t่,iฦ”N้uQ๙vO U 7-Kู”W•^I•b7-Mib)w๐jถ๖‘wgrƒHlฺ10xา"x�2ฐ‰`“3ถb(Fํๆ~ษn็6�tE@EpcBŠIู˜๘ต”R‡B†qR—v<h™‡v-Rทฯ™“น™•9šG-ฅ‰A8pšำB‡fhjx'rจ-ง—ฯโrๆbี‚—๘@๊2:Fฦ้ƒ`œ€œFเƒˆy”B t2ๆ˜ึI] ฐMษ €dD–๐ฮB8 แ™vฯ"ž้)™็‰d�ว•ฺ k�9ždืž๔ ž๊ •่yŸ๖)l -l‰4ฐ`ชV-€€s ื“ฮโ1‚2)bpgาถh+tฮBBะก7๖กštŽฮโB@&p.�:]Xdn'1Z›(ฃp๙,6 <1Šp)‡าRฃ3๚ฃ9JฃEคัโi‰คE–ฃ๗Ÿฯ2ˆว–คVv-1เg1@“๐~ึ{ึฅ2ฐ›r้g0ฐ›ึโฆ3†x‚ๆŠ/ง๚•\ู™มำd๋ื™๓้- žshงvƒงก)จ๑b‚ฯbจl:mˆช’‡*งฉ’:ฉ”Zฉ–zฉ˜šฉ*S2œฺฉš๚ฉ ŠG็ๅ,ฃชฆzช…SชฅŠชฌฺช“1ึๅLำฒชฎZซถj01s๛-ชzซพ๚ซƒSGWณZฌภzฌศช/cร8ืาซษ๚ฌะ๚.ฟ4ฑสซฦญ~ุšญๅ>ƒ-ฮชญเฎ�’๎ัGืสQโšฎ๊z-{ิๆjญฒบฎ๒:ฏๅิ@ŸT-฿Jฏ๚šญi“O๗J-๙บฏ‹ฌซsSญ1M๘zฎปฐพ*y๕;แฏ๐สฐ๛ซฒๅญ [ฑ�ชฯ%ฑ่บฑ ‹ญฒ$๛ซzฒ%›ฒ—;pydantic-httpx2-6dd59b9/docs/img/tqdm-progress.gif000066400000000000000000002471621526547463400222420ustar00rootroot00000000000000GIF89aึw๔***888IIIVVVhhhwwwŠŠŠ–––ฌฌฌทททมบบษษษุุุเ��็็็๕๕๕!๙!� NETSCAPE2.0!� ImageMagickgamma=0.454545,ึw�เย ฬKฬ๙อ๊& �,แภ”�Pุ+1ฐลย!ŸD 2ฑIล‘dL‘ฮ™)%�9NR$p(�ซฐ๋ทPพ„4X `8แT€!MkVƒ™#Mž%‚ๆLz4›ฬŸSJลี€วlญŠ$Zขช3IXงบˆ*–cหf�žม”้j“›ƒ &e”IAl ~4เi`พ„บ<-fญมeฃ ๆ๑ฯŠ@Zำญ`ŒฮฑโหAิฆE …‚Dวbš ธ!้จณฎWชœ//ˆ#ฝ&˜ม,คHc�Š๒ืษ‘‡‘�*™ท๑€Z&Wป6ฎมn �ผฝฎB P3ศŽuุ™จ9�ํjทฆ๗ิTgฺเ๑๗}ฮฝ4ูทชr'>ตณ ฟฟ"ฯผฤ™gฮกืP`%<�]nะuG `…ะM๊ฬFะg1่฿†wคsWฃQ6R}!๑วแ‰(ธD€Fว: ฃmึษ%ย๊‘ฃ+Hลศ„PA‘ะŠDยัห}ผธฐZqฤ<ษ&EF™Xห‰ิbnํ• M=—W่YธC>๊อcM�ดT†ๅ%ๅ›˜XIˆ31x'‘๛๔ฃ'KUแ€เ€*่ >xแ zƒธขh๊่ฃFช~’Vj้ฅ˜fช้ฆœv๊้ง'๊จค–j๊ฉข—*ชฌ’ชjซฐฦ*๋ฌดึj๋ญธๆช๋ฎผ๖๊๋ฏภ+์ฐร`์ฑศ&ซ์ฒฬ6๋์ณะF+ํดิ�Vkํตุfซํถ�v๋ํทเ†+๎ธไ–k๎น่ฆซ๎บ์ถ๋๎ฒฤ+ฏผ๏ึk๏ฝ๘ๆซ๏พ�๖๋๏ฟฬm๐ l๐ม'ฌ๐ย 7์๐ร็ฌฌฤWl๑ลgฌqปDปฐ."@ .€K1ฒ/o,๓ฬ4ืlณล�˜ภธฤ@ฌ+›@๔ทCป\๐อL7ํ๔ำPฃ‹@n†;uฒ?ญnาแ�|ดท\{ณฑcGm๖ูhงu$Wภวั^lึผญฌ�หโM-_ื 7ต t�O๖ณz7[vูj7๎๘ใ',HC+ภ$ภฑ <๐ท� �คLภวYO�๔€ฤ`ž€ D[ภ?; €๋;t็;p:™W3๗เs๓Žฌ๊< 5ท›;ณ—็žk=/๙๗เ‡/~ป”—P๘ฒป‚€5@@ำภ)�ณ“tำ>L@-ป฿4ทฟf 78เั๚๗ฟ€ตใD~&:ภ@ ( วฟ 6๐๓‹@ @?ญQฮ ไ`ฒาwA๖น~วส๔ผ7พฺ๐†8คVHะ€–9ซcเ๕` ƒฦ €ๆ๊vฌŸ9ฐnI{Ÿึ~V;'‚P…ษ*�`(ล$^O&@L�ภ๛�V‚าอ‹}๋"ซˆ 4K‹ฦยโฑา'ฤฺฑrGl฿โrศว>๚‡@ไ�‘€ ๋}D›�฿ไึฤฐ%~>ไŸ 8=9๋ˆฯใ[#)?๚1ฏsฬƒโืGศMฦp’๏��0)ธพ)ซc™\ภ!aํ๑ธฬฅ.ฯึ1สนr…Hคd #ะฑ้€‘^|�#‰yฌ<Šส�%ฬ"ปe–Œฯค�^(‡hถฒ‘ฯ3ฅฑช€‚–ะฃฆ›ี1U‘rwห]ฺ๓ž๘ดุว:VฬAJฬ“วz'ฎyฬส๓›”›ข!V@KพPk�ุYB“x�•`‚% ฺ�7ุทรQN•†�จฑฌ45Ft…ศ๊ฅฑ่G12s†หงLgJS€เ&SใD$ัฟhฎษ๚Qฒ˜€žตoฃ\›ฌaFB:๔~0ศั”สิ72ำ…H�Qv,ช>ฑc(,ŒF ีŒ"‹ ดh|*ยdqB–dฃaM็Jืบข+๊h@ZฉwŽฅสา\ ‚ฦะo๊+๎Œๆณถ—›h๒ฐI) "VDoฦฑฃ™c6ˆw,๚5VAฦ:`n๐Xc‘ ญ@dHแHฑzฺ๕ตฐํถไyพWfฐถ’dV€�ป[ปีํoป6�เ๚Vท;m'nๅw,ืส๖นะnถ�Tšฌ๎‰ฐ=โุฌ[:˜ษUบเ ฏxSชฮ,ขGƒvฅ.ฒHภY๏ฦtผ๐ฏ|๋ฦ�๘ `ธะ›ืผๆห฿�๚๗ฟฐ€Lเ๘ภNฐ‚ฬเ;๘มŽฐ„'Lแ [๘ยฮฐ†7ฬแ{๘ร ฑˆGLโ›๘ฤ(NฑŠWฬโป๘ล0ŽฑŒgLใ�๘ฦ8ฮฑŽwฬใ๛๘ว@ฒ‡Lไ"๙ศHNฒ’—ฬไ&;๙ษPŽฒ”งLๅ*[๙สXฮฒ–ทฬๅ.{๙ห`ณ˜วLๆ2›๙ฬhNณšืฬๆ6ป๙อpŽณœ็L็:�๙ฮxฮณž๗ฬ็>๛๙ฯ€ด M่B๚ะˆNดขnอ่F;๚ัŽดค'M้J[๚า˜ฮดฆ7อ้N{๚ำ ตจGM๊R›๚ิจNตชWอ๊Vป๚ีฐŽตฌgM๋Z�๚ึธฮตฎwอ๋^๛๚ืภถฐ‡M์b๛ุศNถฒ—อ์f;๛ูะŽถดงMํj[๛ฺุVp!๙!� ImageMagickgamma=0.454545,ก …๖๖๖๔๔๔๔๔๔๗๗๗๕๕๕ๅๅๅ���๘๘๘���ฯฯฯแแแ๓๓๓๘๘๘๕๕๕๕๕๕๕๕๕๕๕๕๔๔๔์์์���ฮฮฮฯฯฯ���๊๊๊๒๒๒๕๕๕๕๕๕๕๕๕๕๕๕๕๕๕๕๕๕๒๒๒๋๋๋ๆๆๆ่่่๎๎๎๒๒๒๕๕๕๕๕๕๕๕๕๕๕๕๕๕๕๕๕๕๕๕๕๕๕๕๔๔๔๓๓๓๔๔๔๕๕๕๕๕๕๕๕๕๕๕๕0@@@0  DBฑ`4HD2กT,LFณแt<PH4"•L'TJตbต\/XL6 !๙!� ImageMagickgamma=0.454545,ก" †###$$$))),,,333===JJJNNNWWWYYYZZZ[[[\\\nnnrrrvvvzzz|||€€€‡‡‡ŽŽŽ“““žžžจจจถถถทททฦฦฦศศศสสสฬฬฬอออีีีืืืฺฺฺุุุููู������เเเแแแใใใไไไ็็็่่่้้้๊๊๊๋๋๋ํํํ๎๎๎๏๏๏๒๒๒๓๓๓๔๔๔๕๕๕๗๗๗๘๘๘๙๙๙����€C‚ƒ„…†‚D‡ƒ??CŒŽŽ”•”’Œ‚™›“š’˜–ฃคŸฅ› ง‘ค“ฃฆก‘˜ขžตฐจชนงฏธบฆฉทจฑดญฝพชขภดหภวผซมผถฎวศ=Ž=ึ—•ฦ;=D;ยญำย็8;'Cฺ�า๏ญ58Cเฮั�ซ88๕๗๒ๅjลฯ฿?vํฬ5ณT€C ์๊ัะแม€?\ธXฑQฃGŽ=j\‘โ…A‹๕6rดศฒฅK‹NZด0ƒมห›7cฒฬะCŠ6q uจร!RxXza่ะ˜~ˆเ`†ำซ:ฬxัว%"`}๊"€�‘+TยW f(PC�ซ#@ฌ›pื)„ ๔ฝJภe !๙!� ImageMagickgamma=0.454545,ึ)†***:::FFFOOPVVV__``_`gggopowwwํMJ่\Z�WS๊a^+ตC=ตQCทV-ฦHํฉ>�ถ?€€่ซN�บ@้ฌR}บ‡kน�_ฤ๓ห๏gศ๖sฬ๕xะ๖ˆˆˆ———ฟ‹ซซซธธธืŒ‹�‘ุท‰ัฝฝƒมบสผภภฟาศผนฬ‘นอ’พำฅปรภฟภ•รูฆห�ปฮืƒห์‹ุ�ฬฬฬิหษวาษัะฯฯะะุุุเ฿฿็็็๓๓๓�€%%=?@…‡@†ŠŠˆ†ˆ…Œ‹‡“‘‹—•—‰›?›Œœ–’˜’މ‘จŸง”ฏฌŽ– ขฆคญซ ผฎดจฉนฎณฤกชทพšœพฑฝรฒฏภปษบดคม˜าถูฉฬ“ฮฤŸภวโธงย™�ศ�ญ฿ฐ�šไฯวแ้�ื์ร๎็้ํลอ๐�Cnีฒzดjค๘แฃกร‡#J|ศp"ฤŠ1J�ัƒbฦ†=๚จจ๑ำฤQžดx‘ฅH—#Wf์ุRๅK—6Sยน3ฆDB>izฬ้“%ั›=‹Zl๙ึมv�GImw^�ๆŸkา‡ }ฺ%v oฯู็ nใต7][ใญๆ�น1ฤenํW_}ึ๖กuฮ}(ƒโฝw� ๘tbxโn๘!nWษ๘ใ€6โ…ฃ‹5า�H’4�๘xญๅˆ t:๖8c|'Fษไ“แ }Yฅ‰ๆษX^‰g ฉ$‘ฎ‰™b๚X%˜iข็e’tบ $œTZy�Ÿิy7cัญvB 0ะ€ dbˆBPp …สๅr*H0จ`ฉฅb่โ|ƒ†�•ฅ†*Ÿผั˜rฆๆ$‡ขJแŠญ*(ชŽถž ๊ญนฝ*ชฌq‚J์•ท6$lช^ฦ๚คฏฅ๚@ƒ tะA ศ>่์ ฎ2„,ณR"ษl‘•r๛+ดด6๛�ฑถqซ๋ท9.หฎ•ๆถznฎห๑บ๎ปํึzjฒฎโkj–๕Bkโ ยๆx๎ฌฦพ�bผgซpม้�๐ถ฿Jœ+ท94เภว 7Cน•๚ฐCคœrŒ์งฤ,๓่ะ"ผโ�้˜ฯฺปsนปญฒ\–�+ภ๋��/ฎŸ.ํณัซ ฝoภซํ๔รฑ*m*ยภ๊ผ/ 7„}C4”mถูจ๖ภ ]�์!ภฦฆm.ทŠY ย”xgœภ 3&\2ญบ—๕ึH๎๋ึo�pลOภ€าZัŸƒ,คสZึEm ก2�ิG[OยZัf]ํขY๊ีภ.tคei[€{\หขถฐ_,n%m;R‘N6ธiwีว5oŠ]��!�Vลต้{ฝหe-g7…(/F‰๋ใท‹ฑ[ญษQ,๒@UYnjdEๆ–fPพฑmฅผี<๖ผnŽฏ™ป�6g—ฅdr ‡ซื/Ÿะำ๕๒h…๋E#Gyสวตtฅมส่็ฒุซ™ฝโŸฬeืfบา’ๆ.่K>žถ๚ี€มต9€%Rต<ARงH€.:uกNeชSณ้Pk�เุศNถQฝš€c@<8€*€ฃ�R–ฐPหดบ’Vฎ อ้T+นธ n๔จํg,ปีฤดx5ํลr'ฺษ้๎๎บ๙ฌowSzึ™V๒ผณผiDc๚ำ่Uท ู}c‚Oบาw3G�ŒเจŽฏฝง�๎—Pอ&n›{ ย๊ŽRี&cx็ hเ฿๏8ร!>๒ึี8wqกตฉr›ใœข#ฃดอg๊่ŽŸš่whาa^๏๒๚\ๆRๆyฝฅ~่ค4่w๑ศญNiคg<ๆfฆนำU�๎€k์๔ErชพWฟ€่วฌuธqญ๋(ตื;AR \E� Qคnฮป�๔”ƒฝยA A aฟO[›eี/jญอ่J:ฯอ๛sxว\้_‡yอษN๘จgw๊งฏ๚ตŒuิ}๋Ÿ๕็™~Rฑฯš๔ฑGo๊m�s�_=๓ถ��ŠU-๛ฅƒฝ๖›{ฮัญ{•_:‹=ฐภ€@{ก฿ั|†xวV�ฆสž็Xก![ึ้ำใเwนญปSNvฒใ\๐U็๔๐ญ^๘ยร}�รG๚ำvCฯิ๐7๗o=ภU+ๆs†Fg�ืf๎•^`Wvฝื€๘Wt"๗t๐ทU9ว{(s๏'€.ˆ>mg>ๆ๓F6yเV`ธ6yภTz'8 wฐa� eE8pเ}xs่ewŒWฟDKŠ—K+่K+เT"๐mZdyหง๎๗y�ืu์ทiFG€วsศt…&\ ˆnRX|๛†ถw{x…จ…0ว…๔๖…งF:7†p˜|๐€ง'€X่…jH†Rจ]Q}ำ‡Pธƒ\ธ)ภGฒำ)ะ~*ง:ะแ—;,ำ^ไ}:ศ+€~มณ^ค1็~^ทƒจ๗‡คXo:xFฉwŠ�w}ฌxsV่y�ืŠฆxŠLEvชX‹งจyฏ‹พจsกH‹ฝqทs:˜ŒสธŒ$Hv๚eENศ LYไLผ๔Jภt2ฐx�ฦดxu4WpฆศL€ทKู๕KำdำVUภ”V&่Eัผุ‹๎'Šฆ๘‡v8ŒลyT7Œฎง‹ณ‹ลŒก(‡ฌธYิ�8ฏXIwย่YดŠ1‡pˆ‚ˆqXXภX‘Y„‰f„&€(Šb\ลTfTi(ษ9๐(‘2)!™’—จŠfค “™’นธQ!™]˜8‘—ุ“BY”2้“*™’;pF<น’K้”Eน”๗‘3ฉ’3‰’Zุ”L9”ฉุ“U9‘I •Fู”\‰•™’M9•3Y•cI”=ฉ•‡ฦ•ท่•hู•H ’p”*๐—€˜| �–b้“!ฉw1”(“G)–wY—จธ˜”“@ITlฉŠ`9”Ty˜W™ŠŒน•Aน–™—’้™V š�”_™–fDšฎ้–zฉšr™rฃi—ฆ๙˜๙™Q9uO —›ษ–)›ผ™•ตษšงI–™œV™šฝ‰œ(ู ิig›Kู–ž‰˜•ู‹—�ž�I—�Ižฏูฦ้”Œ)žฏižหžเ๙์Y™๎้žcฉ–Ž9Ÿgไž๑Y™�นž๚‰Ÿ‹iŸ ) �)žQ) บ  ๊Ÿ๚ฉ˜ใ๙žšž  ๊ ๒้�)ž๕‰žเIž: zก –I™๚ก๙9Ÿ๖ข�J™.ก"๊Ÿ*๚ขแ fิ!@ิ9}#šก&คB:คDZคFzคHšคJบคLฺคN’๖คR:ฅTZฅVzฅXšฅS:ำษฃฉฅ`ฆb:ฆdZฆfzฆhšฆjบฆlฺฆโ G;๊ฅ_๊ฆtZงvzงxšงzบง|ฺงm:I `!pqBJˆšจŠบจŒฺจŽ๚จฉ’:ฉ”Zฉ•บa–šฉšบฉœฺฉž๚ฉ ชข:ชคZชฆzชจšชชบชฌJฉ8ˆฟ"๐‚0L™*งธšซบบซผฺซพ๚ซภฌย:ฌฤZฌฦzฌศšฌสบฌฬฺฌฮ๚ฌะญา:ญิZญึzญ�^บ!ฐ@@0>€ญโ:ฎไZฎrŠl –lๆบฎ์ฺฎ๎๚ฎ๐ฏ๒:ฏฯ !?€@ฏ�๚ฏๅชl๊ ฐ[ฐ{ฐ›ฐ �ฌ๖ชฏ!ฐฃP ;ฑปซ๛wPฑปฑ�ฑ๛ฑภZ๚ ๘J@ ฬ*@0ฒุZ(�ฒ/หฌP4ณห๊ฒฮŠฑฮ†l �ณ>๛ณ@ด๑Z.ซฌPDญpด<@ะฅื qสฌ  UปฌT›ณ bB๛ต`ถb;ถภJ>ฐ,‹ฌ!@}�Šั*@ งP+ตึบตฯ ตYซฌ@ \{ฑd๛ท€�ธ‚;ธนส๘šถพˆปซk+ทQ Š‹ซ‘›ซ“+ฌvK•ฌˆ;ท”ปธฟzนฝšนบชl้๊ด„{บจ›บช;ฑ<๐ึ้นrŠฏท�Jwรฒ ๐ JฒD๚:ทkซด#%>pดเธ”๋ซYฅ |Kฒว ษKา)ซ> ฏถผอซดr๚ธ^jผศkบ เ  ้Zบวถบ๚ปฟ��ฟๆ:}‰ป^ชฒŸ x@@{หฃf�ช ‰pkฝ?pซพ๛๚ PGŒพvsภฝŠง `ทญปม�7๛๊ญ=`ดP;P‹พ,ย˜ บฌ6่ปิฉ@€ี&พ'ฬ pยyปŽ`ภฌภำปฏ<]›ฟ�;ลT\ลVLฌ€พ8`ณน:†ภยP+ฟวซฏ Œภ ท• ต<Œทpต]ด:ม@ะฏlฬซ 1ฒ ์ฦ7์ญ"ฆฒ{ซภŠ›\วœตz<ม� ตn[ศิษx�ฤนJภ`\ป0ฦ฿ ๊‹ฎสvลœ�ษžlล~|ฒ๏+พว ผตณสฒ;พ lฒ;สญ,LZ4มMŒรr๊ลRปต�ณณฬญ๖s7๖Cห< บค์ภ@ห๛ฺm pรำ‰หร|ฤLส�ฆฬฤฒšฏPLบR�ษ��อ� ธ*;}Œซแผว |ฒญLซ�ดคฌหขL%ฎP‹ม`ห^:}ส๋ฮศ<หWซVึฉVLฯ—หน<บห ฎ'์ม$๛ธึ™ฯาฬฃ^�ฬˆฬภบ�ส๘;ฐ฿œัฝัซฏ*ซฒใŒฤ #ฝฬ่kณk›ถ]ฯ;j ว�า๖ฬฃ �ฅ$ฐภ0นq์ว ฦ;JำY บ; นqlf|ผำyำิ™ำใlณ*+ั�๊ดW›าี™l ๆตฝี\�ี� ว$ฐถ/Œฬ‘ผทท‹|ฮฯหฃ'ฌw มBฝ?€pผƒ�ฮ}ร>ฐ6‰0�ฝญ;Vvmฒข|ผื{�w ฟ'lฝ œต่›ฺ ฝฺญmด<ŠีMฺเ�โฌ*+ภ}ภฐหTบ`�ใหลลส�๋ ฿ฮ*฿rK฿๖-นdญฒ �iอ:›ฎใ=เ^เหZฮท�ปุMฺ๎ฅต”ำ ~ั�ถ?€€่ซN�บ@้ญR€€}ป‡ˆˆˆ˜˜˜ฟ‹Ÿ ŸซซซฐฐฏทททืŒ‹�‘ุท‰ัฝฝƒมบสผัศผฤึดลฬดหีพัฺฯๆŸะๆกฯๅคัๅฒุ๊ฬฬฬิหษวำษัะฯฯฯะฬัาุุุเ฿฿็็็๓๓๓�€**ACD…D†‰‰…ŒŠ‡Žˆ‡“’•‘‹•‘”œ˜”ž ŸขŠ—ˆ†šฃ›ญ–ฏฑฐณฉณ˜งCตกถฌซด™คฒฅผภมฤ ทนญฤบชรหžŒตฏราจภำหฒฃ�ฯฆ�คืฟพเพยฮ็ฬธ๊ธอศฝุ๑ไ�๓ฟวไจ=.CB����๘Hฐ มƒัŸ@„# โล%Ftจฑฃว‹B,ฬ่ฑคA’�Pšยpฅส•!+ย๘๒%ฦ”uุTsฆฯ~ E��Iณ'Q˜A…€LxTๆฮฆP‘F๊ฏ%U˜V .�™๕jษฎทv[r+X—^ำฆีฉถ฿ูถ�฿๚#‹ฎGน@กโm๛t)ล‹ ้� ฐานa�".ผกเฐ–�ทq^ษ@3nU<ูฐVb=็%˜1fฅšM_FL:re‚ขWรฦผy๔gูkี}๙5ล…งOฟฦํZ๖ใ�ณ'‚.�ู6nั„&KNYนฤะิ[Sžzzp฿ึ#b�^ฝ๔เฎฅ+›?|ป๙„5ฟ?„7{็ฺWงmyฟ๛ๆ�ฉv}ฝ  g๓๙Gž&—`m๙ํืž„ฺๅแp๋V฿tํ5`zH qป f_€าUจ฿ˆๆfg๒}ุŠ1Žxแซ=h�‹2—`‹!*ถ^Ž�ล๖ื๕�ม‚L`ม I–8Z-€ฐม ด�‘�ิ`B\ Vฆzป™™f”คqนกR\Jyค†fฒ™&kSย‰'CIFฉ'œ}–็ฆšo�9gou–y'~zZŸAกƒ7่฿\Ž&šonฉจขRโจ&}g˜!mฺhc›—๑)฿ €โง)ชฌ–gŸ ยฺiœ†ฦJูฌuโI๊ŸBจกธ ฺ(ก›NI็šพ9ชฌด๋็ฎฒZ๊ฒ˜:‹(ดฟข๋™Cฐs–z+มศžฉจ 'ิœyฺม +๑a(ปณห ZY !๐ฬข›รกฒภ ฐฦ;ฬrตg�rำะฒK(žฃf]ตวWณ$๖ต?3-qว_�6ฦcท=๕ลTฃอถฉš๖iบ|W@ิIบ ๏เD ไ›/-ื_ถ�^๗E(C�sฺฏU.ณภj๘็ojžpใ”K.๕ิฅ u็ห‚ฮy9่{์ฐห>ปตค€kฬP ฌฐ่ฎC  4€ผ๏ซ๗^฿#PD<เ>‹3 P<้~Bฯน๐�๗`ภ �ป�ูฉ~-๊]Bพ:ท��พ้ยฯฏ>ถj‹~�แ๐วoนำ๓ฺฑธ5ฬIF�� ๚ึ7(Aญ€"/-AMŠ พศไ:&๐ƒ กGHย†6Hก WธBเ 7c^T€!%Pภ๊ณร์ Iีใแ!๚์€ย‚„๊ฉ@*จž๗fpร>ํเ‡<ฌ�ื~9 z<„A™๘ƒ6๑†7์ƒ๐ล$๙‰J�ขฏ˜;\�.p#ืhย>๚๑€ ค )ศ๓qo็’@ tNp˜ $฿ๅภ)ƒ๘ส@๛�ฤD8ึว“›a'AWEB‚r{งŒ฿(?WสAฆฒ>”บ gi1P€ ๘$๐eHp‚Dภ—ุมต7”เ“3cŸZ๙€$ึg `cƒฐƒ„@—Hขฐ8ณ>)Xภ๐€†ภ @ภภ)%>ภx@ด็ƒ\&เœm�Bะฤ” ˜วภšะ„ž3)ะฅB๙5ๅ) —บKา0 `(ุม9k€ศ“#\ฅแZ)ศW‚ฮฅฎS)เXH˜ฮฆŸ“)+AศR–N]  €ฎ lސเ$)Jh^ _O…๊4 ว�/”6ˆะฌg}€๐ส1*ˆ=อชCYล๊กฌ`ฅVqUJPzUซ‘๊*4ฅ้ƒฐ^ีŒAD๋YลZWUฏฏ›คม dษBฐะ–7�ม 4`ก*H@ ส˜ร�เ์�A ่(pN�Š+$QŠ‚gw่Ye`ฒ@p€Rะƒใ๙@คํTƒ‚œ`#;Š‚DเัAB‚Ž ต(H@fˆ€œภ˜ม ภณ6ธPย"ฐ >€ง ๐Z+"€*˜9…กพVukVKษี›ฮ5ญSฝ๋~กนืฆึฏk ๐Uณšื�$๕Wญ›คซ]แˆืญญŸค)_ึV“ีมrฅY‡`แzRxภ>c‰}๐ำsuจEฝ*zิwI’‚ุ€Hฤจb2Lคๅ!Zแไ ๖ะฤME#4yœb;Xซ‰m"^™ฬVฑ61ศ;ผaƒฯZE- 1หG}๒ร�เ Oตห_๕ม”ร\ๅซ๎˜อp์` KKฺ๒ฏเYFะ<& ŠA8๊s‚ˆQต hb๐ูฏฮ%€ดคKiJŸเอโmภF๐€<฿V�-โ@>l3ย-๔ชG‚๔3ตทm๏&ฐM( zดๆแF�„ € ฆ{�*�2€ฑrฝใ๐๓*Hฆw`ž๙ีบใjฌญMCšU †๓—‘ฬD%“™อmmฅนฃฌๆOR9ภDฦ2’๋ษe ๙ซ^.ทV™ไtŸูย;l๗•ู oNส�ห๔.0ยœo1/๙�๎Nr!žœๆ5™�(ฌนนศFžหo�q= ิ F๒ ะใ_/๙ใ �ตzeL๓~อชD˜ฟuสfEx\๋p!พผ็Yญpอ;ู_~ถฎ1_ข”ํํd+]้กฤyคt�_v๛�ส@zะ฿œแ๊ฝฌ@Hz‘๗ํƒเภฐ8ธมูืฮvh™ซ@ซณฉRW/‡JฤlฬQ \๐�=6 ภย'๏๐ษcภ�~ผT�๏จQ0CR+ั!8k�]Pิี๏ยภดุ�ฟ�๚อš‚ณan๊,—(p@ `ถๆšNo�ษ\Gภœ๊ A�ฃ„Qง€๋ฦ7bžzP�pŒOฟนปsždšฝ็;ฮ๚ฝฃฮ๕3zฝ้a๏แ_อ˜๏1ซ9๐Zฟ2๕หm}ญ��ภc5r๗?„ฏgX์K'ท๙ฃ๔้Oฝ๚<ง~*ฦU?ดDฐcU$tKDt}๕WZ๖r>ฐ@ „.ดW"Aƒ38ะHทI\e?v/&๐y0—E?v"๗}�sj†Fet‚›ิU�Gู‡u/ศ‚wV=Pƒeคf=‡‚ืnู็ƒf•‚Ÿ—€ƒแƒ^7ƒ�Uƒูwƒุ—s;ุn=ˆƒ@8pBˆWw~'f—vƒฅvkW†70_่€eD ๐0`y>P‰f{–๗สตDภ๖fOืCJ'XM4จf˜5 ฐC�ฆf˜ทcจV^ยฅDญ๖ขืDuw|qejM$R#น๖< ฺSM \ nXhf”z_”^PF"EuGj6m็)|w|;ฤ30$PFจE๏dZoˆK่‚eไe2x„QH„>xƒGe…<ธDZu!ง~C๘…�ึจtฺ&r\ฅ„RฆŒNXP๘~S(/7uW(ˆ>่ุศc"็…Xg„q•‚แศCษ)/ศŒ็ˆui๕C|FqๅŽื8F}๕Œg๕fๅ2~cYˆ„$ง”D„=จf=8˜ด/๗vJ4ˆˆF"’"y‚ X’)hƒ0—t7ุ€%ฉmหจ๎ศUKŽ ่’้ธ†€ฅm�๕‚?‡‚+9”๖๘‚&ูƒˆiS˜”Xx“็‡“Zฆ“ั˜e6 4g‡•k;ƒuv4p~;ึ†jF‹่jXhฟUhั๕z่|๐ด€ห(“็'eNนDีไ„€˜ 0ฒ8!`Yฏ�Qค&Rm‰P�—>๔Z`\% 0Oภ•‘yLQDเ?€jภ—u จi?ะzญv™Vw มี้Rา&–ณ็‹›‹&Œพ$wเจ')”*๙›=h’Gy“ฺx3™‚5๙”Iˆ—!น“ฺุei’A™’!œ(ˆ@ษ”ฦษ—ี๘yN™๏˜‘๊ธ›ู’ฝIBศ’ย้ŽjถE#p€แว”ษy‚I‰ža็ว7เ๙‘@€c‘ไ1@…t้0ภ‘๙’00c๊๗’Sจ;†jถ. ๚�)žYˆ่I‚ห8 –เX„jžŠ„ศyƒ2‰กE�จก6ษก�x”**“) ”Yˆ„vyข4Z„30;@คg7)8j<ฃ‡qH_๙ฤ;ะ๓T ฐ™ฎŒ‘ฅl๏ˆ„'š’{‰eค&‹“ษ™˜w‚จ?€๊คP–œI›ว—};0™ Eš;ฆเLeT‹eคฃwYะƒคYฆw:yz;„ง๐ิะๆค\rw<;เlต9YeฤฮงขTุขC็”% ”ัžขŠK)ข�Hข †TˆขชขSiกข๘ฉ$8‘ขŠฃZฃงšŽFˆŸ&ฺชG๙ชœสขู็ขสช2:•>ธE๐y€–๕ธชชHhYW$‹�>ดะ$ฐืŠ >TF<ะp%ะืjYotƒW$pb"=€ญเ๚‚๊ชฎt)‹หJฏ)iญ๗jญ๕ ฎ๊:iฏ๚*กแ๊C฿Šฏหฏ้ธj๔Šฏศ๙ฏ๗ฺฐ์š‘ํู ฑทJฑ�Šฑ์:20ฒ$[ฒ%;;š๖z[›ฎืสŠWTฑฒศฐแ๗ชฌ�ŠญW4—:Kณ ปD1[ณ›‘1‹ฏEหฐLZฏ+งึXดoไดG‹’ ‹Gmณ*๋‰๋สฎฝjฐ›ฑ +ณ›ฐซฑ7‹ฐ๛ณ+ฑ6ปฏ?;ฑ3 ถi ฒฑส๊ตA‹ถ ซถ+ฑฅšณ;ดK�ฮ @jดa ฐ_{ดVหธ‹หธAปฐ๋ธŒหคw;น�šฎน-๛ถ1๋I ตขตKบP๋นWฤ,๋ฒปธแ:น�ฒE บ™[ปถซนถป;ป“ .เ0_.ฐ00.0ฦ;บฏ๋ด KYฺบ˜{บนซธ1ซN๚[ะฝฆ›ฝ‘ ป›ซป�๋บท๛ตuRE[ ๐g�ปj�Kนงปนด+พฃ+ฝเหน›ซบ9‹นโปนฌซน๐บ๋�ฟœ;ฝ๏[นซ{ปผผ”+ป� ภWด2!0ธฯฺผ๓ซฝ|มœมผม�ม�ม ย"<ย น–๛ม4Cย�ฬšnศฟ*�ย0|ด'G‹# 1œร:ผร<�ร>ŒนyมŸ'�รF|ฤHœฤJผฤL�ฤN�ฤPลR<ลT์;B<ฤD@ลZฌฟG์ย[�ล`ฦb<ฦd\ฦfœร{&ม0๐Yผม(วr<วt\วv|วxœวs|z|วnูวq�ว€<ศy,ศxlศ(ภว„<วˆ\ศŒLวŠผศ’\วˆษ“lว–์วuœษ—�ษž�ษœœศŸ<สขฌวก์ษ•Lส’œสชLศฌ�ส€�สฐ�ษผวw ` '08ผ’,มภฬย<ฬฤ\ฬฦ|ฬศœฬสผฬฬ�ฬฮ�ฬะอา<อ�ิ\อึ|อุœอฺผอ��อ��อเ!D€ Bฮ๊ผฮ์�ฮ๎�ฮ๐ฯ๒<ฯ๔\ฯ๖|ฯ๘ฬ#ะ@G”ฯ=ะ]ะ}ะะ ฝะ ญฬ๛�ฯ$๐ฉะlZ }ััฝั�ัํั ๐ฯ็<ฮ:ะฬ)-ม�,า๊ฬ'ญฮ ำี ภ3}อ9�ั<�ำ>�ำ@ิมฌ%เฦ ๐ฬ+ํฌํDDญอpิD ั๊L$ ำง๐žึlีB�ี^�ี`ึ๑ผC.าƒ;Yฮ; อ$@ภ,ีT ฮ\อRญีี\ืbฝื|��ื~�ื�œิ$&Cpึว†MฬoืS ˆฬ=ฬ‰}ฬzํุ“mฬ†-ืยูฬ\ูลฬู€ฺข=ฺคํำIํCPธ—อาC {ˆฮZB@ำ`าฐ)@   ๐ฯrญึD"*€Bี ภ๔ฺศœZงpีŽ]�Dp�ฮMB๐ฯ>ะ�Cฐ�ม ฬีาM�ƒ›D’0ืข๕�ลLุฎ]ฮฑ=�ƒ๋&]ฺ๔]฿๖}฿๏œิ๑‰ซ=ธ�œ 7L  ืซ†หงp เุำ=#pDฐา?ะ� `€ภเ!๑เnฬ๑้ŽWืN^^�DะR=Rแ>เฮzืภโ#ฎฮJฮ;PMแ�แ�ร�฿Cะล=เ๎ใ–…฿HžไJพไฮœิภBล4�ใ†pแRmฮP��<ใ%ื‘-ีDฐ �ž �R �bNๆ2^ฬ� า\อh��ฟีฯDฅ�ผๆe>ธm๎ฌgNีi๎ุCเ1�$็>.ฬ�mๅ๎ๅ� \๎ไL>้”^้๗-้v>Nฬ\>ืผ์็\ฝห.ญึŒํใD๐žไผ้ n๊x-ฬ�ภีฉ>ธ?„เ uBฐPญ>ธง.มฒŽเช~๋gใš]เsํูภ�้ƒ๛้pๆ�W-๊–>ํิ^ํ}้DŸ‰ฬ�ผเ ~ถnาw.ม‹ีฒ�๋ไLำ*ฮšํฌส.ม…‹�ดN4}๋…k]๗ฎๆ็Žืํ~ใ๔n๋้�บํฌ�,ั๑^่�ฬ�^่เ๎ฌ;`าCPึ>๑_๑<ิ��ฯ�,๑ฤผ๐ ึ��ไำ�๏i�่|~๎W]ธ+C ๏ษ�๊ม�็ฮŠ\ญ๒1�้v�b�ž�^ูฟ>ธ6/่]ธ�^�๏‰์3�๓1~ึOฮ!/็Q>ๅ?๕T_๕ฝ๒Cpoโ6�๑wพOY<ใL ฬฺพX �๓ZMฒU�lพ๏Ÿ=� �ะฺk?๐ณ�๏Cฮ�เ/๒าFๆี�ฺP4๐�์4�๋-๗…่>`๗�๕o�ึ์ฦm๕”_๙–Ÿ฿+�Lˆ]๏๕ง€† )ฬŽ-ีI�๓`€ˆ`์]๎๎0ฬ๛\�ซ 0?ฮ*Mโ ž๚ฏ~ ฌN๐ฌ?นOฮ8B� ๐ำ]ไๅ เ฿ ๚ภLฮP}๙ฺฟ��?อ’N๐&ฟ�~ูGพูะ฿Q-๕ฮ๊ใํoอ์ูํ�ๆฯาใ?ฬๅ฿�๚ฟ��ฟอ/ม€0 Bดpˆ˜จธศุ่๘)9I๙(@ไฐ(ˆRX้๙ *:JZjzŠšชบสฺ๊๚ ;z๕ูฐ8DD!ปห๋Iป(D4ค�[l|Œœฌผฬ�์�ฬ M-+0]ญฝอ�ํ� พฺะฐ0n^žฎพฮ�๎�_|N/oŸฏฟฯ฿_JฮŸภ <ˆะU ฬ5d0ขฤ‰+Z\7ฎแB;z�2คHOอ<‰2ฅส•๚žใศ2ฆฬ™4kฮ+‰ฮฆฮ<{๚LดัฅหŸD‹=z'DคL›:} OhฦqPซZฝŠuฮœYปz� ิCก รš=‹ึ์ึดl�บE๊p*ืทtฺ๋Mฉเ�ฝ|๛V\๋7ฐเม-5žK8ฑโล�โ:d 9ฒไc!๙!� ImageMagickgamma=0.454545,*ะƒ)))777EEEVVVfffwwwŠŠŠ™™™จจจทททษษษืืื๊๊๊๓๓๓�ศIซฝ8๋อป�`(Ždižhชฎl๋พp,ฯtxž�|๏�ภ pH,ศ$MวT:ŸะจtJญZฏุ SW 6ƒภฤ›-›ฯ่ด,0‘?๏Jๆฬว฿Sม็S๎€‚‚^u'ˆn‹ ;"  šjงจฉชฉฅ•—™v–ฑ–˜ฃ b mcทตฏธ ฝปฬ bวลึนุรฐูฅ˜%—˜ใ  yบผส์8#– _ ส เ  V)\ศฐก‘ ;่ใ็เ†‰๊๒L์gq“ƒ�ค๊‰ขฐัŸ`๛8ฐ๔IBฝŽ0ˆiŸษ•5T�PRใG›0+$@0`€%a"(zิ%ƒป"V๐QƒŽ เ !เAœ <( ถ@‚e :\หถญ[ญ8t�j †น'ฝ๚า ึฉ Œ€wฅƒq๘Z2ุoจKA)(ซPx๑^บ|วPจ|@bฬ_;yขิ( $๔+5ลซYท‚ญ)ิeล๎*P!๎�฿ภƒ�Vห6�ญ-G`t›P๋*ฮ%†้ๆ#™/ว”๐–ฌ73ศ์�Rยํท)๔CŠ�|๙ุ่• €�ณึ๕Bฬ”๔๋๔�ƒษLวแ@VZ๑B9ด0+ตsIh'�…fจ†…`ี > ƒBH"ˆŽัމๅB"@–๐โƒฆ“A „wQr'า(ใ†HA= �dŒ3ฦ๘ว.๑ขR$ R, @9๓ร฿ ิด(9์ฒO‘`ีLE]6ˆ@�๐%�i(็œt>แ[‡"๎"€™˜ฉง‡~VไแzZ`].€๚“hzv g1สj(@ กy d {IX6Ž�™็ฆš๖ย(-< ”$ฌ:$, tงE]z[‚"” HัL&ภผรaฤkl wf ซ=†�แนkณห๒gbYJ`]‘หŽใhด๔บ@X5เ‰Ž,ภใXฬn‹ฎด#ขซญ)X= แฉ‡�gH'�[4”าคgฬR@@= ค &ส๖มhDฤฮ 3NUค$w์ลgLยฐ฿˜—Žลiq๗1v ,ม_t\ว0฿ร฿�j€`‘qy))ะrฮgฐ๒ศ.ใฆsBจรซวํคG0๛ฆ–4พ‚,_Žh]๕‘ย�ฺฦg!ๅ๗Iมฦฉ๑ุd—ญœุh 0…ฦP 6ืo๓5‡๚zษึzลmะท@๓“น}๗ฺ?€7�ฯ่]๘แใH฿98ญ/�s๛ฬ์ญX{ Sœ0H‡’ วfงฎzฑจ_ะ่SRc6ฏ‡.ฬ็ถk้t์!Nฃผ ่Ž•;฿�ญมxเพ�ษฦว>ม์๊EO|ํา7�ธ๖�h9XŽ{#M�~Aะ๎C"@ภบˆpld~P,-uฒ‰:๓ตพ๚��งฟ9ยDK&@ค?ะ ภ[R( ะQ �T4ม•P(5K†ลๆ'@ v๐Ud’เ%Š$B�@hg‚ฺ๊ม6eŒ€ฐ`ภ(X[\ยiฐS @f๔P<์Ÿ‡œ ส๏‡rˆ๏ใ $`}๘qโง˜ๆY`‰W”bT "W&bฑl0ฤ 7ฦ@1Hใย?"บ๑pฬ0ฆย+œ*ƒ6˜‡:์ัน8๚๑€dหp?d�ย#"ก€I๒‘Œค$ฑฐ…D!๙!� ImageMagickgamma=0.454545,,šƒ(((777FFFWWWeeewww‰‰‰šššฆฆฆธธธษษษุุุ้้้๓๓๓�ศIซต%‹หป�`(Ždižhชฎl๋พp,ฯtm฿ธ5SฐI‚‡P‘+ศคry๓น?J`GBิำฒU`ฐ4:&uหฃsฌฐ%ำ– k,Wษ€ม8H yAB LŠ‹ŒŽ+ " •–“ B B~ <vxR B‚ ฎy จƒ ož||<ญฏ=มรZลฐศ ภณฤอฒฎ ›) šBื—–†w‚ตทนŸœ „ ‰’†›๒๘๙๚๛�2่" tP@  8๐ใภƒZ�๕aภC …ฐภม�ฒ&z๙`C+p4้ข@ฑBซ!E=�S๒CG˜59>$นrยMžขFส๐AA1›๓ฤˆZmผ p`At}^”๐iƒิpP ภƒูnSz่‘~pใส�^‰ �ุฒPํบ–๘L๘VPyฏYD�เšฌ~๕ศฦืหไึƒ‚f™/o๖ฐxtiะิVจ†ชฏAu^ฮŽภ+0์V_ืไa1ูฒneSฐ›ส�ใศ“+ท๑ฏ„^�[+8D๋”(R4` ถpgย—^๔`’CขไIใก@HO ฐฯใD�<}!J ?ฟx�๒I�qอy�— 80Yj•ฬ็ุ^+H4ยspะ›Vฐ็�เ ยG0oQPN=C,gโ‰(ฆุq"T3ูAิาKยๅ)€˜ำ;:ภ†@†๐,ะส @6 d!w<4–J6HdAv๔d”q�P)%–TV !ถpid‚SjY%ŸLC5ฐ`,ย„—ยก„เb๚คษKๆ”]x @‚`,ธ‰ขฉจ่ขŒฦีœ€ิ้P%ผิ ~ Žrwซ๙ษ!lํเ‰กฒV ฉ่'# ?พว‘“}ฺ^ฅ–4ซ!…*kชบฺš!„8@ฆ:€ชจผ{+S�‰ฺQขTSžก'8t‘Zžšญฺ˜ŸyV๑‰EAขื6ช๎บ์"๑่2Q–uaBH๓ŠTžjีYล•g]๊ู†บ@„๐–ซ๑U@ฐภฉ>์Gจ<|อภOœ๊— +ฤฒ'"P JDโ[žซ„•ฎc9)Aธ๚!�€mQ\ุรWก))[ฦต+๔ะDรภโ~š‘˜…]X��! ทตๅGอqฺ`ึ%๒ ๐Ec\๑ธถ B�ใˆd๎�๛™ํน|5๖ๅEK @5กP๔ธ‚Ms@ๅf6>”ฏ6gกษdฆฆภฏษหST‘ดภRAฐัuงม4ะDn&ศAJฐP€�h<�ฏNc‘œv€~„š˜Šื๐Tภ์^ู„�๔“›=Do@+�–ศฤuษฏผ@0ฆgtธ-ยALfฌ Dcุ“0Pึ4M|e?œ๘šฤmˆmGฎ ใ:ไ$€h@ngq’#98ยQTC[x�‡ndK+#ดฐ'ฤmP Mˆbพ8ฤ4Jภvฺz ด&z๒“&ฺค š)่ 9œ'สษŒYzPฝTRอ๒ภ&YyหิPห”ี3ๅฬโ/ฤac!ศห@ษฬf:s.ํ้ลœืDZu๑™ุฬฆ6ทYƒ/ เ` &๗หGD!๙!� ImageMagickgamma=0.454545,,ƒ(((777FFFVVVdddxxxŠŠŠ———ฆฆฆทททษษษุุุ้้้๓๓๓�ศIซฝ7Rz็ล€dižhชฎl๋พp,ฯtm฿xฎ๏|I@”™ศคแk:Ÿะจtส๖ะศZบ2qSภ_/ ]aŸ�B5U‡ฅ,x|0`0 FJJ ‰‰ s‘’“’†+ D% Iš˜DwA  r คw„B Hฎ H ฎ ค˜ง ~~Aตทณฦฒ\ฐสศถธฬฑฯท{&ฌาyy.wy ื# แโั^x ๎ "  Ž… ˆŒ‹�H˜PHฐ มƒ&์KAษ' ‚€@Nรข’เ ^…�H8d[ภ๒b๋'ฐ6่๘ซยภBพdฒG(U�lนณDะ•ˆยzhม@วA$P@U™‹v๏˜Vภš�:t "ฏอƒ=์ข Pภ"œKทฎ�&mืจ3‰กฏ3๊2.p๑Tนm @•p$Ÿ-&“>`bk0A?G�ฉ๙ไdทก๚siน@  า๑็3[/ถpต –Qเถ@’ษ=ปฯœ ๐ มู yAฟˆ$฿�็ะฃKOธ๐„qzZ)€y!=Wะ‚@“ฃŸใ#1^พ€$!ฬ๛ย๘W3*NถPแทฯฯ~›๚๔"่�็�zั\  จž~,[C|5ธV ๒�UBp7 Žจƒ)~@ฃ€˜๐ร\�87�Š,ถˆP‰'โา#4T€. pท�ŒขttqจqฯˆอFO๗,L/ )ฯ’w„df�Tม‘Iฺยค=O>@AGใ`๙ไ!๔pฉไ!gะใe™Y’ูd›_ขG�ัศ‚‡XxA3ฆ็…qƒ‰กV4ล Œ๑IrG๔ƒ"#ถน(้ค”>‘ ๗เ$H„(†-ัา€ฆ‹-€ฃ eNjN`\ฦ ๐๊ฌ๕,Rหฉ“Qy•6+ญ�๊ฅ&ั*ซฏ^ฦบˆ๔�4gฐษึ๊ฅญฉฐ,ฑดZŒ0pภ Ž h'kั€ฦ=pŸซ!MR4มจšส9ส\q•ๆซ๏พ6ฬ{ย"@่9bช$ตภะ๐I]E๓วO�ฅ&'=�.‰qปZ.ฑŠี7๋‚rวkž,’–#lผrส�.ภผ‰๒โฒgLข:฿ฐ›ฬ&Aฆ5งฃ Bf‹8e‘ๆOƒม0ั๎Hีg/s‘๒k๕ีX๓V อ$’�yนูต˜๚ฎ‚xqXถณ‘T ฃ๎งฎxœคภู!ตต�๗ีํ๖Buเv฿๛ N๗>/1ฐ(„๓}๘ ๑5 GyBๅ�_ผถแk๓‚H:2บีY—n:ึ—–„!y†0 กม โ92J�ๅa ํy๊ตฦปพ{|า.yต๗ป_แ‹�yจน๎ฎC็9ฒผ๏หD,_�๏ัfม๎ฌM�ื#่ DšB{b8ฅ�€เถฉ>&&๒h#ง็ฏ�คฉ›ะะC(ึd๔ด hหTY`น9 l2฿Y|BX„ภA<˜ฎ€Q2 ^๐?ค H:&ดฌ๗หคฐ‚ƒกLยE#นyFธภ>๗}‚„่ก@ @ŠนฯSขq ? ฃ‰bKuuข{UmXฬ"ษB๚WAPN’AB ๓แi€5��D•™�ฃIQQ๑F@ฒ/จc‡?ปฃL่ฦ7*ร๊pภ)P€… €Œล ม4ยDฌ‹่„Š0ฐภ$8`‘“•1Žฎ-€˜/ 2ะpŠ3Vิข*WiœrV Mม^0‘ธROฎ”มf ฤฉPf@+ทด@( †`rf–m _ ˆ34ธR+ฑิN-ฯ0L'€eˆุTฦฏศสnz๓›Yฤ0@LU@(e"!๙!� ImageMagickgamma=0.454545,,ƒ(((777FFFVVVeeewwwŠŠŠ˜˜˜ฅฅฅธธธษษษุุุ้้้๓๓๓�ศIซฝ8—]๏C&Ždižhชฎl๋พp,ฯtm฿xฎ๏๎LAๅ'!ŒG‰เมl:ผจtJญZฏ™`.0ฮธHŒึ2vˆšRf{Mmเป/ฮ[`X]T็ฮ€  @NN ‘M ”OX™š›œšŽ&‚# M ! Fชa DฎŒ@ LนGปฝฎฐ w  ห ?ภยEะจ#ฯผพึมพYะุำ%ท �ŽผP-–Lๆ|฿ฅL ิ ๒๒ Ž ƒJ.=@G‰เฅ~ž*\ศฐa†&ๆั{$"Aœ@€ ซ]�&8xpgภD4ู–์R^vน„ู๊AH #U0„์ไK’รN`เ@'…–?c๚ค))Sง@Eน่่?ทกPyu—ั PฝXฤXฯ‚ œ `3ม+—\2่˜@u๓๊�หฤK๐Ž˜dd“\ป$brgู T ˆ0”%•@)ฅ€ขจxRภ๔๒ƒฬ‚‘nๅภ4jซwน.=คd•Z'(ขฆ‚ึโ�ฃOำฎ` I€eุ`;‰ท„ฟGาญ$ ยพุณk฿Ž:ไpQฐค๒#“่ๆHฦ #o�ž฿ฅฌ๚™Aอ่P`฿Ÿฐฯƒภ� ฅฐ2# ศDC@กเาท ˜„Iภี๔ี*!๐L-RI๘ƒEˆG-ฌ,Œฉฤ%�‹ี ฦ�Œ4ึ่‰*)Lba $ณŠn>M–ฬIl5ฺ>,V€a#๘ํณภ. ะไ=ษภ€‘จeไ†ญๅ”O>"erTR„ำผ้d•j–ู Fด๙ไ_’&#9'{H)# ฅิฃg*`V)AYจˆ:q&@B'WA0 t˜fช)�‘ J$„)� ุงb ”บ(h“ำ‘/– @QฑึJRฌ คสภช\Š6AqดP\ญE6�+,~“�ศz+~EHูZ~ฒาJgฌญw,pฏZ าฅ+ Sิ`tf ญฌDJช—„ผ“ฬ’Vษt’lj๏ฝ๘พ สค€%!‘wฦIหๅ*ๅ2’yaจt+”Ÿฒ๖eฤU.ภม $<‚ฏฃy’ฤl(!#ยฆว&ำg02Iฑ˜(;[‚ร|ซ๏iS˜Aษ2ณ๐s“h?ผ[sษKษŸ๙6ํ๔ำ†˜!ยนI! ˜d“ฦVnTอ*๘Cฉ๓(xนj}€"ฝz]vโ…� &vฬ�dห�ฮ ษ@คาก2cปม’9$t&ำ@.8ฃ^™J-�6ั ๊Tว^ขธา‘€๛๔่คou–_\&™Cฤฉร๔CŒฦ๋aภงZ‡@Z๎ํส.๛+lo์%๏ป{ภjE มปI�,ฏnœๅBผpฮƒ+K{AO.ฦއk6Aใl(o<๓ด~vgว:€dต?็bา๐฿U๚�๔�x:๗`P 6 ภE๚𐀄ฉ…€:ะ4 ๅ)r`ZA@ฎe€?(Eม N๐1ูำ ่AVภœ!แญ„&|๐lู๓€Ÿศ–Cเ†Bฺ ('L‚aFฺ†]hย๙๏%€ะืŽ� ฅ5pD�ๆU๏ี๏ŠXไหย�. 8ี‰7H{ว :๒‘K%,ฐZเŽร‹›Šิฐ,ˆŽ•Ž@0R0�C็† `ิฃ๘H่9Cn�ใ)*' ่ฑ ๖ ce$ั] #M`"�ะฤARC-M€‡�›ฉ‘`Rษข*Wฉdล \ ๗P ห Kท|ท…Ka–นฌ@0มAJaำ ฏ, by .\`˜GภE6ก–zX๓šcฅ6ทษM†์‚s๋&fล%D!๙!� ImageMagickgamma=0.454545,,˜ƒ(((777FFFWWWdddvvv‰‰‰šššฅฅฅทททสสสุุุ้้้๓๓๓�ศIซฝ8๋MC!Epdižhชฎl๋พp,ฯtm฿xฎ๏�0JAๅN~D@2 <žOoJญZฏุ[๐S]ๆek!ท ˆtบ๓ถIๆV�๘ๆฬฑ์~,~€ RGP’ “P –O•™›P‰Y กขฃค6&ƒ~ช Pญ D u ?ฉ Oฒ@ภยดDธ ‡‡#ฤยJาฎัมฎพvีGฐลึc�˜O-�รู ํ ๏Oฎ๒Œ y  Veข4ฐำ$ƒ’(ลฐกร‡ –จGฯม< (เ`�Ÿ,ึ๐เŠ€ ๋‹J–๛>>Sร^ถ” ำAฎ :kขไิeIC53utุOCy–„9`ƒ‚ซ v5[`ภ�=ฎ^<( ถภฑ%8แTฐ-[IŸ สKท๎ ‰$๐uuฅืซ L#€-ฐ(ฉ„C_๗ ๔'ำŸฦภ�รฉ่ษำ 7=€ผIฮŒ,–สธo8 ฅ†N-3t ŸUKภ$Aฑ ำฃ[ฃฺ<‚€_%|7*+“5›ธต„JsM“โฺNฝ:uไ%z�ึ~:C€vRcnzcธ๐ ์˜>PaœฤFŒ_–ฝ๚'8�W~PฌชLน�๗DZ�yš~๏t�g_U๋1ผฌP`€๛Q–?œWo †&$#ะ[ฬ-7 1žX็โ‹0–bข $…Sc 0ใ€ฬ”ภ;I}ง€ O?.Œ‘ ู€’|ิ€�vAf๙’่“ว“ฬP`QˆL"้”ฐ5†>Qjyๆ’nrIม”dj ฆGุCๆ Eฦน$F�o P˜† 'ี'Šฉ˜ะ${ฦh้ฅ˜ึ€W ฉ& 9Zู- ,โ%9>yชJ%บ์C`˜ุป”๚ภฉ( แ,Qฦส*ซพFนŠ+ภบ*lก„Z ๒�๕๊ำฏฝ๎ร๊ฐภ*ํฑๅคฺB‘ฏ>{ฌฆRPไใzfั“Iข–คฮฑ \™ฦ+๏ผ)ฬXยบA•Hฑ€๚าี$น–ฏ*˜,rฮ’ —๔$ดŒˆ•9๕วคยฐชฦbฐฑรำJ€ฏ˜8ภ์Ÿฃ๑X‡™Aส2I O])รท,/œœwอT@RฅƒVŠษ?šิ่‰)B:ฉาาั๋๔ำ๔nJBนž้ปogด’4ำภ<ํ*ฎ_้=@Y๙แ'x ( ต\�ไuุ^z=หmqpŸ�_‘01ภh�v+(๖ู^ใ]ฬุ‰5]ฌB‘€ƒทAzŒฮธ�เ€ ญฎrJท๚ป-Bm๚้˜JอีT‡AมIV ืๅ๙์—ึUล†ปr’ษ@�่j{ ผWmOltคI<๒ศVZภ” 4ขu บ_ฤIL_ต?ฐ+๑ภโjUพA‘ฺ3ฏ– ์ฦญบ>ํk~>‹บ้ฃI็)ำจ๗๏uŸ฿๛ฺงˆบbJช€ะ�‹Kา@03ยB#๒ฯXRZAb@)�9x˜ fฐ„|1!๑‚cภ ‹aeธB6H…U๙ € ฃ�่Sิ�qAœPn„:ำ %A™o@'๘™ข�‘œตXขWศ๗ �๏‹`…๊2เDณi‰b๒ �๘"N``ป๘Iง„)้้vœ OCฆคp฿ ฦ'๙„JYฤ„ิc ัhBร‰ƒtข!Xว.N€#PŸD•—IP&ฌภ!E9$€—iBwl`ล(„๑•ฐ…V Tฎ ฿uษYŠม–z8–Pร@bŠก ˜% pfS—พ3s!ฃฑ€™cเฅผ~ิ‘;ฦ๒›เ ็\˜แŒธ‰sqE!๙!� ImageMagickgamma=0.454545,,ƒ(((777FFFWWWdddwwwŠŠŠšššคคคทททสสสุุุ๊๊๊๓๓๓�ศIซฝ8๋]C๙pdižhชฎl๋พp,ฯtm฿xฎ“ร(‹ฏ๓#N|รa๑<จaGญZฏุl ๘ ‚&่qธย1ซ€@ฺtG}ฆฏไqปฏต  SNQQ ‘‘“”Q —’𖐆}กขฃคฅ-Œa Š ซ P ` CvŒ>ชฌ?ฎOภ Qฌทนต „„#ลวฤฦรgยศพฐุิGูภำื ณ็็,�โMฟQ   ŽP.yข4ฐง‚ ‚2ลฐกร‡W�•8P\‚ 8hดวAƒ�%3 H8I�Hฎภ;€‘LnXภภยL˜ๆฝŒน๓š`(Fi‡aจอ›Fฮหเtž‚ซWCชPšจ_ห –(Y ภƒ p๕๛'แ‘ภƒp5!�i!ฤปx๓๊ศ–ƒบ^ศคgหy,ง[ ัำV=%� L€~P@‰ู˜fW‘žภณg‘4;้�3€ฌ5˜,XJูž›ดF-๛u��™-8้‚ถ8ใ2� dถlงณ$�–๗-๕๋Ÿ๖j฿ฮฏ๔3›kวQง!ำD  ฺดค†2“x wu�๏๐ก(=ญaฟณ๏ส8�ึKŠH+Sx฿l€SŽhฆ ๖ุJP๒…’ฉฅย๐ล@<โ r"ฌbMz�แHuมhvQฤื�8ๆx…‹&X x4,‘ cAURXc”ฤ".๒@๚,$ผTy%aฐไcME&e> X๙–๘hษ‘Pุˆ&•e^9B0าศ=p๒tgšqฎ @›cช™€. MtŽี@O๑ฬ 0เ@C~็VŒ4ฮh�ฆR่่้ง ย๐ !R$ฎa0ภ3$ฐQ~ท0€ศ=c0bGข“เŒ™ะ+aน.๋ฌ`^ €˜˜์”ส�โ3ษˆ“๋ฎฝฮ ]๗L:ยฏ๘p €ซ<๋ˆEg.;„‰/$j-0“œx"…Aึบฆe™&$ฃพ™ฺ๊ฟL*&D)D&�"๊สGe�”ภ=‹"J*Y€’›๗ ›kฦ)้zๆ?@H`ฃIpl‹guผqส*9ฃว-Ÿ9มMd‹@.,฿ดงฦ~๚‘ฒf.�ฐ( ๊Jจ0”ฬ๓—*1mX_—jŠ)งRWฐภXg}ใจ�bช˜ฅ™ฐ(Er‡$ส’ศ#จณ6m็—@ูœญ*ั=7=๕แg‡y?ำถ‰•๚อ7o�ญAใ‹�a 4ฏ+Š�‹8`ู Tฬ8ิ๛าE5ฟT_ญ๕้จCฤ๕ฅZœZJไญศ7แrถ{$Іซ…G่i คงJvS…ฌ๏œVถ"งกDูษgดx‡ธฒภ<ะ๋ฦO๖อ�๐ผ<แนฦ%^œเ๕ลน ๆฤศญu@Sว_5้๒›ž๚�๘‡ฒzฺlคยX ม 5ฐˆร_0ภ3D๒$ฬIน๋�7›ณ PiDร(Pผ0Yภ†*BI ษวษ  A ž',Œ!แ%ฃยŠ„ะ ›bุ@uญ…ฌ`แป\8ฝEF„ฤฑ'2ก &Ž2rS�ฆHล,์๏H๓[ญI^!Ez\‹†QX€„E‰ู ‹”ˆŒ>ŽŠ5Bมด;Oฑ|rJ“ิ*�ป�Dม€�!�2^ (ว< ภQ Jx@„rl0ฤWฮSพ%(โˆ2t๘B‡อxเ˜คœtg"‰4ึจU!๙!� ImageMagickgamma=0.454545, ,šƒ(((777FFFWWWdddvvv‰‰‰šššคคคทททสสสุุุ้้้๓๓๓�ศIซฝ8๋อป�`(Ždižhชฎl๋พp,ฯ๔$ ไLpํ 0H,๒ŽFภะ(D:kะจtJญZz �2่ฃt์ตk* ฮgŠธฒ๎ดKo.(.นมพdw€p<�  †6”” ••—˜ ›œžžš›ข›Vฉชซฌญ’}~จJ  ฝ ภ C {|@ƒ…jทนปทธ สฦศ ‰‰;าบ<ฯใแะ‚„ป โัๅ์๎ธๆŒ ”8$ฬ์๏๐aฆ�[p`w"�ูี`‚4H@แ@ LaาX‰#%�Ÿ< ๊€ซ“(Sช4aัAƒ%p;@ ฿พ (ุ™ ภญEJ�์๐ภ$…Ž(�ข™ฏหฯƒ}> @่†a–tเิอw71hm๚ja‡ง๏œญUฺถp@[‡”ุ%(  @ฯ oร2š*กI•<(`jbaฑฒHหฅ0oUkฅ็ฯ SFัheT:o8-u๖0ธ(มฤŒ%ฅ(5ะn™ดZn‹“๖$�ทQF\ …฿ฝk฿NฌA€ๆส`g๓ผy๒ฺO4Dˆ’yGต ^8๘ๅหQt๘วEำ์`!` Tภ <ข!-Bศ€7qศb.ดํ›}ศŠ1พศโˆฬธaRAeิ :RงF0I$-๙ฺb$๒Œ3ษe`(ๆfa’‰‰จๆšl†เ%ก๒PD �โA4สไ‡ไBœD\V6๕น7|<€D‡JยMQ๒‘ฅVT*j(ข-Z็๘a_ฆ—Jภ =สจ4š่ขฉ":ง„ฒชj#<ฦ€•#j7yj€ชช๗igฎง&๐ฮa!HY™๛�1�Ÿณ�™‰IšmVkํต�%ฌ—p‰tะH- รภธฤแ‰Œฎ�ชn'X#ภyๅ6p.-ฤ‰•"แบซhท€หฉ z�หผ‡89™,˜ศฉบ็๕หUทS๐มœ"ๆ K™ ซLผ๒†ำรO€˜ศ| Qน(xŸqึAK’ฬ#ี์_sืๆฌs›ูnprฅ˜ไj;๖*ฅภCใตฅไ;ด0’<๔ด $€ด"๎M aขO‡+uQย Œมื&Y“2u>ๆา0กˆ•๕b`}ูa 1ณyฌp—P57�e [ hXm^Uตไh๙ั|ณอŽธ๓ไ”๘&�ƒซ๘วพPF้dีDM…Xy_`8$›K๐!^�Fขก0:Ššป@0ฌำึ๙x=ฐ๏‡่ส–\แข๛EฝsพตๆภC”k<คwy๙กlA๏วปŽ�•์๔a�" ,.ูฒc6[�ณ็Gk�ด•ท๏�IŒsฐปnเ ž ”>Aี>3;†LฃN่p๐›ฎLX�#Df็–}%,Dคˆก„%Lp[๔›G๒ฑ€}ฐŒ€ยบ ๕,XฟลrณรTv4ฅง;�MŸnuะไ5f E A™Eุ€G1Ž|"—พ™r›ภี๛–ศฤ๔Œพ;€o€wœ@�>ๆ‘ชmฮn…rภƒ—C์ฐ6‹มโ>ฌจFŸ Œลษ_gดฦ9fฑ0Nb#Xpง3R`ƒ€žณ8ศฐlฑHv�žเ#ฐaO @ `ˆxเ ฝ0ไ=ช8ว< ฑจศG%R”�๔ข3๑#Ÿด2 RฌาใLgIห<๑ง‚(เทช`ฉScไŸษ ขฎ ˆ’9ฺ%U$" SpิืŽนLeV 6ฐ&+ฑ<1ฺTB/�ะKX๑ œRม…๕�`= �ƒ)๊%6้K1ฝ\แ๖*Vห~๚๓Ÿซกžpษ+&sAัณะPชG`HOA3ูpะษLิ ญภ"ช†ŠfT@†|”8ƒhใ ฆใ(@Wสา–บ๔$ึ๐ฦ7_๚ƒbฎ"!๙!� ImageMagickgamma=0.454545,,‘ƒ(((777FFFWWWdddwwwŠŠŠšššคคคธธธสสสุุุ้้้๓๓๓�ศIซฝ8๋อป—A|dižhชฎl๋พp,ฯtm฿l0�Lๅg!‚†H€XY*งq9• œvหํzปA’NบำŽ9แขPU@ ๎แZ.ž}ŸtำพัWN.:|g Š  #@Š›› œœžŸŠกขคŸฆ ขฃชจX_ฑฒณดต˜˜›ˆ›น  F |˜D – ‰ะ ‹–ลวษ  เ ?ึุ@ืำะาิบŠผ}็ํัŠ๔†๓้ ›ร(อฯ(Hร’รป๑$(  €ƒL,@๐ Pƒdฑยสี*U�[u ’d)XถRช\ษ…F  p-C‡9Pd้š$ Š์ xp@ยM้|H$ไฺ}๘มฏHœBm๚ภภาจ”2•sfอ b๘Kku�Ip@‡xRX8ภ!ฤฐ2iVฒเ)@€ะ–1็•’OF>e’๒ไT9[j�ฬYๅห”~R(Œ†฿`ฉภ‹(gNธ‚5/ฺdขV €k X) ญ}ํ๖โบ“pDžpBh รs๓ฏx ธmK``Œƒฑ N ํแ๙YN€ธยg%•S]~5�ฃไ๛”3w�ฯฟ๗\�cG่uภ�Qk)๒C(s„วฤNะ ุ�"5‚oYœณ`P�่'!†โ�Dจึ„(]๕ผXˆb.Žธ�„x!…C•FQ`€ฌ)ฐ€ยlว@( X€ฬแ'Ÿ“๔AiŸeRŠคŸXfฉ% KrIิhCน%O(U^EaมIVะใ%&ั5P$็CJลO]jถEุI ž™:็ไLqš็-_6Aข†ส่J จ;:แb 0 c ;-JL˜5r@ัจ™Wm  ธ‘๊{MRฉ๋“ปFู๋”ผฆ๒ื–ฤkฌQWjpT›ใ�qw\กNุS1‘ ฤšผู*ข์ เ‰Bˆzโmœ PK E~J่^แVTุท�~หdช๐ฦI^ˆฬ‚@‘u ๎ธ�ถ๊ภธFฮทโ~‘8ฅ‚ถงพzW+Qx"ฺPX่ฮ_น๋ซวภ~,rศ$[y์ษ(๛‡‹ฑีV„ลxr@D%V.EกR"DŽhK™��ฅ7R)@8:ฃต.ง@ำ)tQ๒„ุ—tJะ๒“๖ gำ”NอKิ<0%ม C‰งฬฤ–oษ๐]ญ๐;ฎ๑,R}{Wา฿)ฆ,๘เ)จมNoรํ๒q๒ˆ›เุฅํQ�q�P ๆโD”a‘O�ก{Šฌป9…ž+[บ?"๎&?reดz๊œณž์�จธo—’*�อ๕Lqิ]RvWŠ7฿€3Ÿwษ€฿N๘๔ิ฿`x?7HPาFฮ บƒยCƒ๑0ั@t €oŒ่a้ง~๑๓?ซ�๚Š o๖ศ�P฿ฆ“?�-๎  n๐ ทdF$€˜pถ‡@]) €1Œ+Hโ;�ป[Nใผ๚ํy}หO๕VศB\/ q9€ Ÿฒ6 €ƒ(Q๙ศ’ฏษ10q<ข `‰Dเ†f2"‡Q. ภ/ณฒ€q(7ฤ,1‡ฟ›โ�‰#ชค�เ�‘ˆนP‘uYด")‚ฌJํั‰‰Xร š ีˆก ฝ2N0ยHŽh�Dวš๐W)Y"_!ฝ:๒‘$xaDม .ยT‰ฃ›ฬิ> ่ [R�ฤบด‰Eญรภ่คsVD˜ šF“คT„h4ฅI%˜ๆ  ไ�7Ž[Š&–ธLT-9หs *๖�ภ+WgI,`rSน�DBD* jภ`ผB#!ษอnZ›+ fRe‚นœ`xจ:ํB‚เ|3ยQฟiอL๗,9ญPฯ!€‡aี98Noึเ0�4จBสPx"k(080[D!๙!� ImageMagickgamma=0.454545,,ƒ(((777FFFWWWdddwwwŠŠŠšššคคคธธธสสสุุุ้้้๓๓๓�ศIซฝ8๋อป฿AA|dižhชฎl๋พp,ฯtm฿ค hC0;‹ฏ2�(E!q 0"•ง๓ูœ œvหํzgภ�ฃ๛„O=ฮ™Tˆูฆ“ึมุ\�๕A8ƒ} ‹# #V‹šš ›› žš กฃกฆžจŸคฅฌชขX_ฒณดต_— Š‹ ‰š{ ‹• Fบ C มMฤ?ี ุศส …  ๅ >ร‹�ูล•้ึ�บœjีื์ึ๎ย๗๎ั ืก€ึ`M5Tวmา์`ฐม๔šp ‹„+�ค^-ู*คซ“&Sž:้ั–ห—0c~่่aม๎™ฤขฤ ฤไผ€˜ ˆR๐ €šไm:4HะชSJHNย# WZm:@,Pชf‹�:ํ‚QฌS…ฆอดฌR€ ๒&h;3)% (เ e†ภcภ ’kะๅ„f”+UฆยผY๓*ฯฐ หMบ๔,ห$&im<%ร•ฤz[ iQŸr(๘+)์ผ๖๚@๖ต•าEžง8๑^รงn<2มทPำ'จๆแ\บ๐๎ฑ™|฿ฝ‚บy[ี:{ฆNHŽ�I๊ำ– 3๋๏ผ�sX �ฤ’ih จ}@ฬL็TcLr�T๘0Jปนใ๊A€„ศA5ˆZh� 0วั_$Š๘แ"*2๖@0’Xม‚œ‹-ฮ๘โ„น9@#‹0J@Q{%๘ภ”}Qd†““€ $F20สy €g�๑็e—`๘Ÿ€&-vเ™hฆ้–%XไT”Sฦ‡Edดภ˜เูT…)—–KฉGงx0hw>P”"DฆHWEลhh…„*zhข?("ฯฅ…RเฆอXJ)ข…vR'ฉfิฆฃb ภ.!๙‡๛tƒง4(p๋ป„@PMไuำ –฿—b"Kๆ˜%�1Kาณฑจ)ํดำ&ศTำ๕ฺภภบง่8ฐทภ”“XิF'p((๓\ฤ๎ป๎*je ”ซ_Qภ.บ์ํo๛๘n…+fฌ5ถ�๎ภ�|๋ภภF๐ท�`ภ๔8–‚บ่š”มx์�$ฮxีSXเh‰™ว†นฌฒอย m€1ฏ"ต8็<.์–ษCเ–E“DBLQ XTฮ$Aภwญ�Tร“M๕ธJื{๏)f)ูิ…J ปCmดข๘ŒD' `„ุSU 6ฺs~ู€MSตF “†€b‡ดIะInx็@|จEF๓ฬฮr™ฌห5‡ฆ๓ๅ�˜ฟdmฺ�…O*+T@า[”(ฐ[aฐไŠฅgA:sN.ฐื"ฌ”hณK`z๏ฏ�L๐ฆะyC1Pl‘ฏ†ศ|๑/้wž›ภqŽ�u@Ÿช*ถn่รต-G[>.๙ห”C.๓€™ท๏>›cเ$@.Š„(a�ธ‹ {†€ฺ็�b�`ฒI†๎4ฏ๊,b W8ส‘ฝ(สGLมา�,P€ƒ,`ŽญC…๊ฏ‚ตqะG๘ขZ A๗ห ;|J‹cฬ(cฏr่›œƒHD ย{Ÿ—ศ‚๘ แ8ˆขP ๊อw๊‘‘�`tr: ฌŽOี“�I2vูรAถ่#�M`๎™�ำxF6NCA## )ึ๊…›#ตHว เ‘kภ pE>’้@ศˆ3@ฤ ฯ่Žp@“Bข†(ชิ8@…๗ษ„๙V9Vฎ/‰LŒฅ,K$„B…ี(…4•‡…เiพธบ.ฐM0'#ล‡"“้•Ÿm ,ำภ.~ู„]<@+H‰dฆ˜ู„[^ ƒ่˜&6— ฌ โl’&จYMb ˜Eย!B์รหหฬ`F @W$6ห \ก–� จ@๙ษ‰ตfภ‰ฌชรB๔…Ÿ\A9+๐ะ เ$G,ฌจ 4Zˆ!ฃํ( ##'4@ฃ/Œ@m€ร้ญ๔ฅ0ฉ @QŽG,TฆM—-"!๙!� ImageMagickgamma=0.454545, ,™ƒ)))666FFFVVVdddvvvŠŠŠ™™™คคคธธธสสสุุุ้้้๓๓๓�ศIซฝ8๋อป�_!ฤ( `ชฎl๋พp,ฯtm฿xฎ๏[0 –03L„#@)a*h๓ค.)ฬkrŠํjŸมcL.#x่ดzอ๎ =‚_rศ๑ั?พ,ๆฝฏ X~K…|qz‰G‡{9v > d G c   bed ฏฐฒc ด ดฑปทถดฟฒมฏผยทc mสหฬอ0ซ˜žฉKŸาš L ~J ิีc้œำ�฿แ’ ฃ FึํM�๊๖”งkฬ™ึฐ�c0IBj H”ธ‰ล9ด)� เม�pเ`Bงข hฐส ’M8Pฒ‰ฏ›ภpหษsงฯWรส}uะ™ัฃHา๔RคV: €‰^ำ‘5ฅNะugภƒช ช;I สจฆV€ฉ”ฎผY �ภฒk5ะ=[%N +Hฅสw/ฝม˜H˜ ‚ŠW ฃ๎*I“QvบcหˆW™xP € โอ„F'PืBa“ZKvํžฏMสปท๏ะRฤB!๔ƒ�q้ดภิ˜;'ไ3@zยgดgŠcฏ๗ 9€S|3,`Pม๋มะญ#ฯr;๒๏i5ดG?�x ๆทณUฃ๊� #ฤโœ:0A5™b#mcšฃลRัL5ต†[lฮf.าฦa†ท�๒�o$–h"fz *จภทŠกฅฟะ ^Qณ ‹ฌL xฌXcDŒW<€$u/J็@dJ>ภ ;s…งศ72ษŠุy‰”3ต่%,ล`ีใ“‰f ุำ@dไำ๖ิใ_-„ำJ‡€‚๘แOชก ศœจ่ขŒJเงq>•ŠKvฒิ ‘ฮ™‘Y˜fึ0๑WšิPzgžฆZ๚@=บt๚”•ศEAง–”*žซn•&ทๆ9๋W@N9ฝฺ๚’ฅ)๊2aฑ�ฑ#ฺ คV)”ˆtBา„‘> ำ€รๅb' 0เ@ ิgกก!ๆ†๎ ๊ถ[จป‡ฎkPฃ๔ึห›น˜ฺฃญๆ"€-๙๊š7 œโา๙-ฟสu�๐ช ผมร:ypซRg�ฺp+•=�oฎ,สิสฐาธชฟ์0qdผ๒ฦ3ฎYชฑฐฐI๚šฌม/vEK).–ฏxต=C˜+@A๐ฆ๛๎ิ๑Fอ.ีRW5#ฺ๋๕ื<,Uษะผ’,า=ฝ€cKS„W`Yฐsัgk4ซ๕ฐ�)A�ฬšฃfƒ•Kูwž�‚WHฯ ๛,เ…�]ทˆซlA,�q๋�bdS~u}�™ฬd`ผf๙8–๊๒ฐๆสบฦ(์ณ[(ุธ็žพp์Kบ้o �ฤJเ๖ฆไๆS‹๕x T1?†๑ †q˜MฦH:๔ม9Fฌ‰ฆจ”uOนT’้<๓๊kฐ}๓มโโยฮh‡ศ=P‡\~J+ึMO+E2็ดฺmMv‚B ํต/�9๐0x๘7ลุฯ ศ’Ž๏FุY�’ถฏ^gbz๒`๕(`$�T„ษ0a[แB0ตG"*€Yฦ๐…ํกกu€8ร Lิโ�๐3ฎ๛Xง‰KภE@€8ˆ+2˜(€�(žึMgsผbอhh@ญ™1khผฺีhบ๑ เ�E$ฆYZผใฬB)Vq‹ŠY�f๒Q .AภT๐˜,’ฆ‘yไ ' ซ/ๅ‘‹l!๔ธ0f2` )@ส€่ฐ;Œิc!นGOfq“ก\€ภ%L.Anู"? ?ฺLญ์ฃค„๕ำdbB0๑„[FŠบ์ฆ€ฝˆฆ,Ša5Qskืœ…4mg8z๓›ใžvฬ#˜ๅน|หฎŒษŽŠrnKุฮIŒ%ๆTfT|v<ฝ\/Ÿำ่i*ภGE˜…$nc-P๐-แœmB]JณL่ก๚ฤจ'.šLŸe@฿ปe9+บซ๏@M๛@!€:–@ g ^ท ™ฺิ›-�€J“(–2ยXPฉ`zHžvภงมrฉ *Yฟ"$๕งFE๊ คŠงF!ชJตŽ“ฌ๘`ฅAเiPล›๒ๆi$IซZปfึถบ๕ญศ> ืด…n!๙!� ImageMagickgamma=0.454545,,ƒ(((666FFFVVVdddvvvŠŠŠšššคคคทททสสสุุุ้้้๓๓๓�ศIซฝ8๋อป�_!Žค€hชฎl๋พp,ฯtm฿xฎƒฐ 'IภG VŒคRhA&ฬ‹ำธ”F'ี U๐่zŽn˜ +›ฯ่4f๘แ‹=;ลsJ฿E�ช€@๚ywrzB@m„Iˆsin H ^  dX__ ฃ^ฅฆจฆซฃญคฉชฑฏงณถฉดฆžjผฝพฟ  ’]”ฤ`• bž F ั A EอษX�ฦะาิ  ๊ 'ฬลสI�ป‹๒ปำ^๎฿B๖๛�$hk@PœŠl ่!3˜a@ƒbDPภA(  x @ƒ�4˜ภื-V']ฅ„eฒ%J—*cyกฌฆอ›hDzHัโ+Ž�ฐภม’|430!Œž48เ€ขG“ ŒŠ๔าL%8%สภBณฌ^ท UึฎDฌ-ะŒฆYฐpอ๋6*�ด?&ฬMล0(H t™JB”๊๘ @€สไBP๒ฅ็˜ŸY†ฎS4่ำฆcูลษบตk:QLถ0;W€lถ`S=๊Ž-0Xยํญ๚Ž็�� ,N€3`ช ผศ๊บกฬพ�'ซ โถฮ™;๙"ฐใn ƒแลisิ@ต0UซG^ถฌปr…ุIฌ�Dฺh]ไ"Kiข–`j 6จหkF(แz_Q˜t#ys*xฯ ฤGะ•uโs]”ๅแ8]–ฮMฐbŠSmุ"’ศxใŽ4ƒH๚�ุ\Ž(รฃ>๊x$๏ูAP'D†$๐ภœด7NQ�ฤ*^R€ภf)X €k"ุ&ยiเœ2อ4แxFxๆ €)ใ—�yมFeTิUaภcัyTๆPํBจG 4ภค†nฉMT‹>คศำ™ษฅ–bZ้–W๚๗ษจ†^4มFRaอ–ฆชeก•บ @๐ิŠ๊C|$%%าิg F๔@o€�r@4:ะวŸฆษเ›jฦ™-nj{ญทŽฒZžไ–›F…Dห4>„�Œ[j)@)WAร'ฝqซ%ยCฏผ�nYสผ[ŽูภฝไKV๔Nๆpผ^ัK=P[Ž๏ กฅQ'h ภCLpz‹,ฑเcฮ �2\ิบ@ล€Z>)D)๐@ฌฏบjmธ�สษ&ธุ~tถ_Œk๎าLื Œ8QJXlฤ‰&–. ภF๊pBTฑRP์ซ•EใฅekBฏึ\#�)ป5ฎzunhฯ-qีiำ-q?,FXmvฉy[šเXฃJA)aงฉZZYAW”dtฤบ�๏Iปkฌี}ดัž‡�ํ็ฉ(�๔้จฏ€n—e,ฬP๕ไม๕๊|qD0ฐYUฺุโ ส๎\† $ ณธต{Žณซ$–/ํ”๘h๕’0@ํ๓ฮ7O๗MจาBหRภฎมe๚PU๚ \ฦTœฃ)บะฃฯฟญ�ชฅฎ��ช/฿ม๚แIX 3nˆ็*ป‰F๒D„ฑY"FTสN#ธ› yn‰[`@ v Dค /Aฏฤ 3มใL0„XP อ‡/8+>ผ †…$‹Yๆ/�€Q Ÿ]่2๕K"�–x?%สฤt�‹ขงโ?)(€<่Q�ฎ˜ERเ! ฉ ๋E�-๊z VOHขc„’ตจต2F4ฒภใธG-NŒ<šฃ/“‰’&xณ๚่E9ยัำร!#นม 8`,ฏSีDฐˆ`‹?„ค้a ง,H|‡‚C%hฮF›Ie™:'ึ’–ฅ›ข.w)ี•oส%C0ขษ$KUลฃ€ื๖ฅวQ8'ศ1 Œdr้ŽUŽI5xjb)ฆ7มYv!}(d‡1ละM`Qณผฺฆ‚yฬwbม]@ฦŽ„ ž‡X 0c�„E Šผdมฯ”ะ†๊๏ (ฟR จB\เ <„TE�WP�u”ฺคฮjฐ\๔ฃ EฉqTš„bิฃฝLใGQ)Š,u่Me‘ž๚ิ"ีฉP‡:ิRฌCDต:�f†!๙!� ImageMagickgamma=0.454545,,ƒ)))777FFFVVVcccwwwŠŠŠšššฃฃฃทททษษษููู้้้๓๓๓�ศIซฝ8๋อป�`XŒcžhชฎl๋พp,ฯtm฿8:˜R0Xผ…‰“ข1ษVŽฮๅ๐9•F‘อk6(xxฝ†œxL.ื|Ÿภlูqk`|e@ ๖แ\‚{o=ƒ~fj+ ‹Œ  aŽ=_œ _  ^ ฃŸงฆ จซชฌฏฃขฉงฒฅถœ“lผฝพฟ™ _— š ฦ Aำ <อฯCรลI ^เัึี…ฅ‘‘&โ฿ะ๏ใะ�ไรฆ๙๖ �๒๐ีร0/ž…j?Tlซ็อเd‹ข)˜Xสพะ …�%tษต๊–I’ฑPr‚ต๒dI•_Xฦ์ด๋—อ›8e€๔ €€BJคtH/ะฤM `*ะ€$๘RO)aqฤธชQ฿ƒ]M7,``A+ืฌ_ฯŠM‹UBฯ@…fฐฺ] ็ฒํ:RG-Q่๙ณ่Š Oเ ำพ&0'uY—)_jฮฬน%LR˜=o�นfฮำจSsB”]l`ฐภ€` โศR๒(าฺถก1๖h๗์งฤลษถ@B%พsuO@Ž�8์YีeWูทํƒผฆ@ฝธ์แูฉLวn>IฒyOฟ}M�๔Iฺ]6pYไหŒ�4ฺLŸy‚V L &h Jฆฉ&แ„จฑ–FD0@A๘•”& ฒGpL๘๕S]๒œ#$>Gyœ�พ)gๆ์ทฯA๘ <�๖@Œท.nb:@้$^`๒่?่‚G่2„ฮ.ำ ]tๅ…Pgt—(OŠ@@ ฎ<`Ž1žย$บฬIดยxฝTb h๘@เศc$ผ†~๐T•๙@รB—)๚*G>ศ้P}้หึฮ�GDฬ €�‘YaภP๕ @2‚\โ€`�Sต)งฦF ๑'1’๑ H™1ะ5ฤ}ํŒฆ{#)๐†ศัIBS"$บ”EๆฤqŒรHˆI(าQŽ|tฮ•r8ฤพxฑŠ—ศใ9ŒศฐaBœn๖YFดE(;1JN”}งโดR9 Pb‹•,idg๙ญ#^€)_hภ‰ษ ˜ยŽœx‘5ยถB4yั � `ธiY2ƒฒLeb๒kXฒฆ\กK €๎`ฆˆ†ำิส=ฺค€_โ“ฬ”e`_ K_ถหไa“V\<ฺ฿DB%ZฺไYƒ๓ง@}&€~�r˜A (†f  ฏ)h =6uˆถม O–E“€P‡ฮP‰miF+*Rฮ=-pV สาลๅฅฒlฉLgสาOฐœ4 AฐM1D!๙!� ImageMagickgamma=0.454545, ,™ƒ(((888FFFVVVdddwwwŠŠŠšššฃฃฃธธธษษษุุุ้้้๓๓๓�ศIซฝ8๋อป�`(dAbชฎl๋พp,ฯtm฿x�ย6 � NˆวJqiaE(%:}&ฏฮซิช}fQ‚‡Xlะ™ฯ่๔ฎ็ ุ็ฆ็G|ส€่๗งzPBJo …Jƒ‰hn‹C ’A b e› acช ชซญc ฏbฑฒดฏฌตฒถญผฎนภฏพฐบพ jศษสjฆ c b  ฺ�ง E”z@ •S˜šG๊์�เื˜ž (๊ คP๛�„�๕{f #ํ2๒ฯ%K*ฬ๑ฃ@๐Aip=8@€ˆ�˜tzะใ’$ pภม‘b0ƒ๕Š)ŒๆL™ช†อฒ™“'1Uว– JิEK (เเ‹ hณSAUซภt,+žKม(!$glBŽ”ฤu‚ื X0‹ถ์ฦณ$้�ญ AL]าspoฺฝy5ะM,มใˆ"Œ่wฉม$‹ฤฤ&ๅG aVn}€ ภƒฆ $๘ฦา)€T5q�ŒM๛fํžฒwๆ�ๅS๗ํ Eƒ ~กYV($[’L–Cฃๅ†ƒวำ $๗+t๎vกcZ Ac คฃzะ๔k๖แ•P?zไBวง๏]�๚๖๖A�Qอ(+�cเง+H +'‘ข�t0šiฌ4ภQ ๕ฦ�n:}x�lถ•ˆ�ˆพ™Hโ‰d็โ‹ยq๘AJN1X�.mx‚‚:(ะ2‡ƒI€ีrสEคyrิ#u๔ธ&ึ&ๆ2!’=6ม‘bจ„6Œ@‡ฅEZIๅuV>Yไฌฉ Bั€–HVฺ9(ˆRX™'า˜l…�,๗ˆ†hhกˆช่o06๊(2‚r ภM-—+ไuภŠ%็l@SŒฅค€๕“็ž}žฺŸ.uส‘E็]Wช๒ฉUญ `@5d$ชZI0iฅp9ตฆŠาช}�บuฺธ fgฉ-PKมฐ@vะXส% )ฑ๔ER,z"ภ3}@&ฃi‹ช˜"‹๐ฎ(๏ป๓Š่ฎฝ๑พ �ฃ�๖+ƒŒ’R ฿{Ÿเ'vNฐ€7 ˆโ+š่aญธฐ"ƒไZL๎ยo๘ฐbp†ซฑVแฦr๑E@™V+8์ภAœิ@i๐ œ@ฤ ๆ<.สจ@†1Iศฅไm™+L,lฎ0/h$ฑPภINpRยอึ:”ย!(l๗ฺnพ๘ึ๋5Šaำk6พ๛๚ซ๖ฺ‘9ูAล€B&ญสะ,ภIžˆยX‘Š S‡nแ๕ฉทฬŸฤjมฌ ^3แq,�’‡;+eHฝอd~๋i–kpา•ผัำคP๔เ›วฝมIIญ#@Eช ™าq)ม=„V่ฎq ๖ุ]'J6๒ว+obฺlG/}œnw Ÿ๎m0กย \}ภl0P}cƒKV! o†Ya6ง่}ตเ7Y๙ฝ™%๛™e‰�ม๚P ๊ฒF6์ทพ]๏J๗3 p7mภhธ#)แ[œ๘ฬ๕Z†24 p*ž๓š๗5ฑะ„%ิื๔VศB‡P` ข' ˆฏz�ส7โค ด)ƒVฯี$žา)~ ซภี6!ฤฯะ๓qbา2 8z„Šf๔Y%อฤพ<ฯศ0 TANฺฆภ‚*qp]cp š…ิณQฦ;ๆO‡•}€pเtj$5*ณCT[0ั เลb๊ฬ8ี๙<๕] V›šUž6ax+X๊Xงเภ D๋ึ‘ูษ๕ฎxอซฐ*dณ๊uJ!๙!� ImageMagickgamma=0.454545,,ƒ(((888FFFVVVdddwwwŠŠŠšššฃฃฃทททษษษุุุ้้้๓๓๓�ศIซฝ8๋อป�`(Ždižhชฎl๋พp,ฯญ0lC0wฅ๛”ŸD๘ป$08T-ฤงิ)E:…ัisŠ`GF.›ฯ^ส–ล๐#^�‡ึMโ �� Cƒ‚ˆi†d6&’  ’ฃฃ คคฆง’ฉชฌงฎจชซฒฐฅดถณฒนตธพปคchรฤล2Ÿ!=ฃ” ฃ B†? หEัb; ’ไีื Œ  ๒ :ๆใยE๗่โ�โ๐qฐw.Ÿฟ‚๗ๅ[๗อDทิ$4›ฤกƒ1Xp`h�,@๐@@ (ฐ�๑ซUหW/c›้’&L›2k๊ผ)iกฑŸ@ƒ~X๙€คe=š‹ˆ!AภH0—IBคAp`ิBชKNี: ชฎnธdม\Gณc „u7,\NกJ]๛@๎]ปb5�c”S‰‘ ื50 ภา "G�;a““๔M ฮ( ขp�ญkgNžจOซmšujืง} M{62HbZน๏‡t˜[ Iา yDP kสj(‰znŽา๐โ3ฐฅ0}ฌ๔ิฃ/ฉ�ปเsศ‡ง”๕Y๕๑^สo?D๗p!”3ฏ`๙ƒจgu•�คYfเ=เbกฤ�‚ฅฝึเj2ุ iถแ…X�†�„  8ะ~cัๅCฤพZข๗�` ‹z@8]=WD dฉตJ†faŸw๊‰็ทใ:๎นๅฦ6่บ์ฒp�! ์cีz0ช| Xรภ&$�‘ฯ๊ +p˜]5 kพ๑๐หโ�M^%™€ม SWฌb‘X[$"๊0qˆ lJสฟ3ฐวE 8ฏ 3)_�RฐœศไูXฆg ๆ)4นโ=ดน้บhปL7อมป˜‚@$M�รฮ!\์[พ$ษณ\YญYAภทz0Ifรณ‘]c๒ฐ ฌZถV๓š6ฌ M7ญ.gI €{K๘Vc ๗VŸš‚จ𙕐iXใ/�F]ZH "C,อgาแŠ๎งัD�ดดำฌท.‘’Dส ™วQ^พY๕๕๕’ฐS09W’ฉQWะ€F $ปป ึ;๑ย๏ฝ—g0�๑rQ^ั0@m๐ิK฿e๕\y@‰5Kูิ>”๚ิwฆRยdา€ุ๏z‹4๊๛›^z๊์_O\Gภj‡(RD02Ne =I‰7ฐ;a fน๋Dwrw็Dp#ืhžvฒวมๆ”'ƒ&™'PยฌhŽ…๔กQ4ะƒn๐()„ ๅ๓ƒM๐ฦEูO”‘ภN3˜8€ มฯ้GFฦ’SGว?*๚]U<�W ศEง}(ˆ=@โ•ศ�,ใbเ“ึฆ39เ… ีขSjDฃeQ฿ฐฦ|ตHKށ๒ุƒ;K๐ใั ืˆF5&ฒE3\า"๕8Ip่†)†\#|„HTลPsœZ'x€Rส‘ผqUTA ไ4G[C๊V�'ภZZqŠZ เ๊บศKฺ F #+) ƒษ๛cฟ. ปโ ! Ÿฬอ9ช’ฬ ˆฌฯ(ขi฿ำVฺGU4#ฅqฏ๖ฉ฿า๙Iซ€ณ์ด@ข‚ ža ™;"')ไนw Hฃภ›^Pป4จB‹APจS ัa":d ้๑@�0ภ x$ล(ฆ๐‘VภคAฉ@qC7‘žJ dๅL ่ๅ�� ฿ ˜˜*์้J๚�t็๖ฉ;wํŸ†|ํฬ%คใO]ดg-ฦ5phMีg$%ุ˜ Hƒ�เ iJzฉฌล’WKb+]ส„๙2ืL›4oSฦณงO (? Cmh'ภฮ;cื P*แภตฃž8ˆ�ญ"<�uรผ‚ํ๚ภภZณm฿‚+0 €ดžsฃ7ฌ†พ†ŒRa•ŒรK ะ|A๐ ˆ8จิ๖ซขbๆ�Œณ๓/อžƒี�%แ#๏J””ภ€1&ล>0้8y"U€ฮ�s๎าฃ_Qž๘ ซ–T˜Z�๛๓ๅา{‘ž๘ท{`ฐ€ทC œด�vG~|F[L๗rŸ๗hจqahท@hš„RL…ฅq˜š‡๛�ˆ$สภŒซ$MŠ่w™w๙8 ‚>*ธbˆฉ0•:Iy\(=nฒO(4`ใ  ๕ขdy”]8ภ^Ÿฌa$๐พฟPЇ?4 }จ#,‘f๋qpฮฑ7 ‘;K„ฯ�x€ลธp; ,�‚( ฅ จG_\‡€#ˆŒแ �I#˜„ตไ…ะŽbaExว|]…€ŒT�8 4!Qƒ6๊"ฑ˜ +Uc เ-Hเt1“0y LีpEฬภศสด Nnฒ”š$ฅC8I%บฉค€จxITž‰•˜*ิฮA€Kœษะ ‰ II๏X๒zHฆ[ศ5ช#k @&’ำ€›]†Žยศฆ.ด๙กaย›_'ฤฉ mš3ไ$็ูาศv&c(คธ*p ‡@I5ฬ9Oเฌ!* ?่0@๕%}Fฎ�m๎"ะ��QZP่Cฃุ๋$M๘phCJฯ1f‰ฃb ๆ]jw‚”- :ลท0ญˆAmpศ"5 €8น๓ฆ�9;qสำิ4@L้4„๑5UฯO]0สํผาF=#c–J˜•eJ}jชีCPๅAํฉXำ@’ป0tฌhM+NูaไMญ‡เ'\็Jืบฺ๕ฎi ๖๐Vผฎว~ ฌ`Kุยถ_!๙!� ImageMagickgamma=0.454545,,‘ƒ(((999FFFVVVeeewwwŠŠŠ›››ฃฃฃธธธษษษุุุ้้้๓๓๓�ศIซฝ8๋อป�`(†Qœง‰ม่พp,ฯtm฿xฎ๏< ›AK๒ณ +ร#‘’œ(วจนฌB™—&ึiฝrญOฏR�}Ž—‚‡zอVz๐ธ|W”�ย9!' ศ๖c‚LH‡|3‹F‰{r@w k šo imj ฉชฌ˜ฌซฑฎฒฉตmฐถดฎนmทlฟkฝlรkมjลญฎkฃsฮฯะฅ!”ฐŸ ” G�‘ C อP jอํ๏้G ‘  � -โนƒ'�๓ึIจv-Bƒ์๎)จ@ท†"ะฉฃPN|�kL8๐เง},@€2@ƒบ9ู5ซฆ.›พh��™'0=y�๔ilณhH“*ตh๊5ืHšlงฯยSQ๕˜เe…%Iะ๎(•=๋ต�V ]ซ’e`a-ฺ?e��`ื๋„ซ/๐3ป@_นYM–๘ลฎXษš$ะ.๐พษํFajŠ@,(งไ๑) C…%ชLu๋ ฐSว^ํ๚ม1�จi/ซธดท๏ฆ=ธt3a3จศ†Gnท@B(ฟ�E_`@๔ฐ0 ?™&{;˜ฬซAl˜.…๎Yนฟสš�หฆ๕ฺEi@\v๖ะko฿E�w'๔ฅ�๕‚J$๑v\„๒IฤcNขAˆ‰BำH€Jmทe˜�kฒuจ›‡~(bˆ$โฦš‰F๘�Š,ŠPa˜ีv0`ฮG% จ�-ศ’Hu๐๐T32๗]I—<=Žทๆ„ีsHNฉF”5๊@‘T—ฃePˆ”d—\ชั”hอ๘F—ุl‡œ- ‰Uะ™UWฃ๘#‹ศdแ†(ฮVข†'Š! † (ˆ‹ฒขb‹FЁŸ„b––YโYiIOฉี•&ฤๅ„|~…Kธด?๑จ*ซ้”๔}ไuRชŸญ๚@ซฉ6 ๋จึ-ไชฏฌwi`tฤ๋ซ�,๋ภชอr์ฒฤ๎jlง1€ลK๒q–—xCD  %HC/^จhขŒฒ;bฃƒ"*oก๓ฆ(้ฝ๘b๐br�ทŽ,็]ีีฑtH9‘ศ)ม*`"ภf˜DŒา*๑Šย|aiqฤc ฑฤŸาะศ๏๚มo&;ฯ-T,1ฦ2ฃTฒ…�๎Jฒส�:�‚ฯR๒ทI�ฑ”@u_g&?‡ค[๏บOท๕ป๎ฦK๏‰l<š๏ึฟํ›ม*ภ- ญ=bซHI,,K�„๒X�Pเ3K–ึ,&yทcุ�G2 wวทŠ–฿xnํค†kโ7ุboว‚หฺˆำธv�ญ๖ฝ๘‰‹๔8ง,ฉ‡ฺVPะœฮฤ‘buซRๅ฿25ำี‡าตํRใN๕ิฉhอ๕๏IQชZฉกy ฯ ' €URu0pf>“ฤ: Tyฝtn;๔|Mฟๅ•d?�๕ๆg`ฝyๆ฿ฦl1€.๙ุkฯพวฌ_พ)๎ณf@{JฉhSmฃ€ ˜ถา€m'?ผƒ—ซ6มR๐‚4J}€วมฎEKBŠ �&๐€ๆ8! œYŸ์> aภgฮ{zœ„๛0<แœlEเ>1�!|ˆ �g ›@ะฒJ๘p†PขะŠล#^!‰&�ะ >&ZR‰6Kฺ&�`ๅLหžoyงxj…?ๅ,๐๎{ ;™ i�ๅ”J๔O น—า‚่Bqื Qฦ`๊3CT่ก60๓–ณcCทJ0ฦฟŒgไL) :j/•บดฐใAเ‰:ธ`�ำ@LรS๐ะ“เ)olzฯศ`ง€ -ƒTแฤD}ฉTcฦPY๕ชbœชVทŠวv�Cก\รz!๙!� ImageMagickgamma=0.454545, ,™ƒ(((888FFFVVVeeewwwŠŠŠšššฃฃฃทททสสสุุุ๊๊๊๓๓๓�ศIซฝ8๋อป�`(Ž`PEšขj@พp,ฯtm฿xฎ๏|.I@p …cฒr(™Kg9…J)อ็uzlRฃ�j๛�jฏ‚‡zอV|๐ธœ4œOƒQศฉ[�0ƒƒXD‡€0‹I‰v —w–o žwmk ฌjฎฏ ฏณฒดฑฌถบดปmนmพlยkฤjฦภรธฬทดkง’าำqฉ–——งj–G ฿A� ั ง๐แž ๆ่ ก ธฐ'ฏ^ผ‚}โอ‹ฆฎAž �Kข^ยp›*|{H‚›Ž�ฺ1ฤ0 ~.%”เกpฆ&4X€เ€ P8ะ IฏŸฮx TจQขC—%-V้QฅO_คFต* žT&ุ๚0•›  ๑MผQภฅ๐เ€ฏ1'ฤ;@ภไกณdmˆ€ฺ~ ,ฬ%๋เ๎yA^l—ฏ�็5Lทฑผ ;Vฃ�ŒoaNe’‰ภหž)\˜i n€›'ะทSUศฆP๊ฮอ›้าcธ}G�ปVpโร?ƒlตน๓ึ:\ฝ ๕่ ฅFลS  ”^ P๏ญ[โ;O๎มธํคิค˜B๔๊�o?Žฬ๖้น�—„Iๅ‘ไ~๎`U(˜Ÿ^วkd<ะีaใภcžผfภkฎ€๖–xi‡ฬŠว)—‹*ถใ‹2าrะr>งใŽ;‰ทมL^Hb๑qถ“#ค:�„'!ภ่ ิไVzเŒ˜ษwN4้fงฌ€ ๘@Mเิซ*�8pภฎ–eฐ@}�ป๋ฐฟb๙l<€ฺ77๑๊k•”2’›๓เฌถชŒ ํึ6+ํL�–า-ซ! Yผคrˆ+ช€ภl`6Aฏธ d6HX�–io"�ฉยก2\)ฆƒบsฅVฬcมpฟด /ข—^> ”RS" h6oyฎฒณ0‹ห6ตผ€�˜L+หV๓ห-๚rฬwD#ta3ใุc kl–4–G ะ๒ : ฬQ๏บtŸ0ะ๛l ‰ฎ�SมšธV`๖<�$rช0I|๐ฆ฿0�|๏ํ๗ย}�72lŒj๑แv`��@k"\…‡ฐ๕๊ส�นยึฌัšฬ๙+Yสส2ซŽๆn๙Z“ปœgฐ๚ๆพฮาmM์7Oซหบ๊‡ม>้ฏงฎŠ์‚ธg๛ X„yฤำ@3Uฦญๆ ฑ~๕…qŠ็�}เ ƒ�ฐ�฿>๑วˆงŸ๘๏LO ฬืR่lึฺ!แ‘T^†ิw‰œjKIOะ5เ~[ฺ �—ก4ฅฤtเŸ�๘Šฑ˜„ัh j( ึKค +:๓ฑIภ„}<ืธฺะm ธ��ฦ็=๒ูฐ†8Ÿ�วCยAC}@คฦฉ>ภยยห —๐ยอาฃ.ษ๔ช_ุ#E๓(=: O�xV‘Šœฉ^ไ๔๓พ0(�ZกI๐/^๑‹ษฐย'ฬxE$คั>$ฬ แ๗‡ t ภK>rยโ!เ๚มž…๖'žื์0|ๆ{$ uXพN’Ž ข&k ธ R๓x h‡H™”็5ข8€ฦฬน๛ ๋ฃtb$ ‘€lตผe@G.–ฮนฬฬC‚ 6 ˜$ฤTL):ฝp'™ด„ (iJdJS"Š�ฎะ ฤ๒ž๘ๆ,ซูห 5๕ฉ›ี†ึง$โจอ*ŠฃŒV4ƒ๕„E‹๒™Œ}�๓�T?ฺขยm๒ p่$vต†uึฉ ฆK—ณX๑žVึŒt ะ๊ƒ“5๔ฅฃ๒@ /'เKžAฐVP8บ™จh@ฃ,T ภ€ˆ›‚ K% ก•Bฑ˜i‰#$ย�AดZd3ฅ๒ไq^AฒO&JUpฏกm˜jUทฺdาซO-BX9เิxตMวƒ%0€‡ y5H{@๋ �j๐ $คซ"6งƒธ"ญ\ ฌ๚ถ9ยVy‚Mฌb‡3€ิtฑ2pFฅ!๙!� ImageMagickgamma=0.454545,,‘ƒ(((888FFFVVVdddwww‰‰‰šššฃฃฃทททษษษุุุ้้้๓๓๓�ศIซฝ8๋อป�`(Ždižhชฎl๋พp,ฯ๔5S \8ีK? 0{ลก/WI:™Pห/xฤ ›X้r›�Fkเฐ˜ สป *wtyNฟŸ๙F€D|h2f) ˆ š›š œœžŸขฃคกขงŸฉ คซ›ฏฅจญฑฎดทฆธณนคcฟภa— วว › ”  i ?Š|–= ฮ> šฯFโไืูี ŽŽ8็้@ฬ่ๅD๕๚Šˆเณgn\?�&เหgยธJำ4๙๒๐ฏMˆ,@๐@@€� (h€)ข*]'yํZ™’%+•-cพt ๅL™5ar:ฌงO#=K@ขp@ŒผK‰‰ƒ$ašžxฆI฿Tฬาˆ;ถ#€ฉฌnXภภยุฒb€ปV.� ฬ๐5ฌ„พf5,p0ื/คข–เ:‰ย‚ˆ;x!๏�]mk4๊ีช_หn]š๖ง‰?s๋šƒฦ t™p@ฏ„โสฤ-ˆคI#… lž€5ไูพ2Y็K9๓ภ|�Rจ�;ฌนg‘@�:nฬ5 /R;�๕็l7_!๘p D�Ÿ’(ำG™MGˆศภมHIกู�…ณีขก…rh[lbb‡ฎศ฿n(ฆจAoะ1ภ5u‘ื @(rHW•S%’PณUcA’t8ฎEแา™d[?P$าๅ”$เƒเห•š@Iค&Kภ€VŽ)ค0’ภใ€ˆ# ว�’<ใH(4V HI%nจ‡‚ึV(k‡‚˜จˆ‹JคโฃVRฆ๘€„ƒ-ฒAqiท�`Y=ˆ ๕9�€๐ัโ๊ชƒ…เ80๊ZโUาฌธบซFฑฆ5?ย๑z็E{aษ%�y์%�มฺำHุฌด@`jkฒ"๔xGธe ž๑}ิฒ@$ ภ™u์ี›h†*๏ ๔ฦ[/ข๓ฺ+Jธ‘๖›‹€@b3ถn€ี#ม=ะึื0 Iณ ‚‡ื€žึQฦมๆ€žะ๓ŽฤุY|มบpผqฏrฏ˜่ฃ๒หF4ะVž>hน%-ฏฌฑฦ4วL'หgฌจึ•เํg xฎžเ .= 0rNจพ๘�ซhพ]s�ตืŒ’ฒฅฟh�;iมi54U”ี@ฟ-G6K’VnSฐดฏใ�ุ+Gวj7GŽH7ง:น[8ณ›e%ธ„›—qิ�tdฅŒ—่ะชkแƒGฮำ;”‹~]žภ=ย฿H—ด˜s„ง@ค  <ษE\S๐†ํ๛ุb—M6‰ม�๛&�ฆญผ0ำz‰ฉ˜4�†yc%—โหฌ-ม฿ล9,Œ�‹c๕š ท’L{๘a~ฏ=q่ˆOาBœD† ๚„๏�๊ท‰�๋[�ƒ^'ฌ่cFBฉ�pๆf}n๛S…†gขFUlภ;ž๑2ศA%oy ”A01 ฬว ˆ’�d์้ณ%ศc=3g…฿hกษ�าธ๓`ฤ‡!‘!๑Sร!9๚(3๐ ฌ iˆElฯข(=๊œ‡�๋�w@€~‹O&  gI0I7(ผโ]‚Œ#EิทฺใKR 0 3@83๖‚ }`เฃx Fลี zxษ  งอ4โ‰fฒไ ฯ๒:์ ฆ‡™Lส&CyIBย‰ขดำลขฤ,‡”ฃDe#TนพSjา8คX0i„ju€’คคf`€`.`eXท=;=็<์ [ั0QTSƒ&บๆ฿Xmnย›lœ 8!4GG�๑œ/ศ#"ยีช๚�ฐ–‘๔€‘ะ›%A?๕ัpƒ๎8ูศฦ ”˜™F@ะ (ž๐q@<›I)‰G (ข:jมI Ty'™&: b ฃํ{ะmจ4ฯ0V/‹ภKัIำšฺิฆ2�€RธEpหษ*ี~๙SD& 9=สบH™ศ๐เง2�šJ7X ฉใ๑)$ซ�๔ซ` ซXวช๘ฮ]�๚+lฌ�_ „ฆA~์๕ว�ธฝท'ไQ�^aคš„แใภ#[ltา Mาดโ\sฦฃbn(*ื"s+"๗โr4ฮhcŒ'J%�ŽะQทul๐hเUฆ<ว=@ิขz เุˆTHŸ’U>€d๗™ิd}(pMZ^yŸ•IJลdh>'A'/AfฤwGš™ๅ–Xnไ›้ฅYฺ”D[.จ1Iƒ_็tฐ“‹8ฆH้ฅ2V๊ขฆ0bz"งn๒(*U’v`’LJpฤ่/ำไ๔ใื'J2ค๘ฅ'Aซฏฦสkฐฎ– 8ฏ–]cN๐’ฝ�ฎ๖kฐ๘Eๅณ‰GV™พไl„ฏ ตซM ญฒ�ซ ิ€œ#LYA๊ฒ‹AบJสYหบQ G†ศI‰–f๊iภŸผฉม ฌpTฃ6\ o๊LP‹วขawาO:  ทฌj“8Vvเ1ส+yผศฆŒl฿ปซฅ KฐฒวA4ฤฒสๅ�ง]๏(ฤฯ,ภ1ะะPฮ6‡�ฯ#€ฏฒ™‰โิ2Ÿwภii@8�%=็™ฐ„(ค�๔่ฦ<Y{0tฤ: ธ Jเ๓นย๙zŸส๕C๘ƒ๛tีžะไg‡Eœ‰�ฟ™Q‰G4bีTฤ2!h ญAB�8ฒ€‰ ฑ?Pœข“D ดๅ?h“—*๘ฤ .ABg\Bg :ท|๐-โ[J”Bฦํหd๔TxBพ0†ˆม 1pžภ/C =€ถธ5„#8L™^F๔ฝWHA฿ ะจูhr"ัฬšืIฦฬKsร3ๅ*‡$KlˆดTฅ-ณKึh>ฉ์ˆJk๚Lกbม€‚pอv ะฆ65mqชT=เดP^< ใิh@ 5†ฅ>P*~ฤZ‚ภ\@?ฐ@UทzVฒ–ภi_€+[ี๊ึ๖d’ฦ+มfิศ#\uช€ ฌ :CุฮไIฐˆMlUศQ—*8ร˜t"!๙!� ImageMagickgamma=0.454545, ,™ƒ(((888FFFVVVeeewwwŠŠŠ™™™ฃฃฃทททสสสุุุ้้้๓๓๓�ศIซฝ8๋อป�`(ŽdนEZj*˜p,ฯtm฿xฎ๏<(ผขA`V†$ัข”(‘M็’}R1ะใ5น•zนฺญ๕K“›ู08jฎช‘‚‡|�pศฝผ^V �๖LB}LF%‰‰T†D'#„G‘“‚€! s   ฅ กtt ณsตถธถปณฝดนบมฟทรฦนฤrษยศวผฮพะภอิมx›ุูฐsกฃเขค J pฃฎI r D๔u๗่J์8@ล`ม๙์แ“ใ`Ÿ„๕N๘7๎!†ฎ >Px"กร�v๎˜(W‘EฃจTศj€้ช ‚4H@a&iลชE:ํั F“UZtฉำฆP‘>•UY09<ตi�๊ณ+/cJ8๐ฉรL9ฎ่ฉ’`งั€$(;�จล๛œฺ m2ฐ`—ฏ� „ซxด(7.œw๑]๔ภท$ฒ+p,ตๆ)[žvมb[ฌตภส‘€ไn›ํนศf ฎž8ิnฑ็š ภ†wœ0นำsฉ„€]ˆH `–HI)ฦVjŽฃš๚๐ŽsZ๑ง#‡•ชฏZ๏7pม’บมค <สสMF€๔ˆมิยN2ืR.อMฆ�+?›Aดศ์ฆ5[[ ัM†"OัH'1ะŸ%p“ธขk4ฮ3[ด,}uำi๖Xยค: 6.ฐN™(ิฤ(Lj Cin็ ๑ลก๒ ๊฿Sฌท-Yulธ ฌf0ื;๚�ซษด˜๒Mจฬฤ�ฟx+qป๙ฝสN^f*>c €ด�r๎Ÿต7อี๙ป|�๚ฬโ�$.SW}จ๋ซ_ซบฑด~ฏฬr‰=6ทด#Wl`เๆพ๓Y]0๒D5๗๋8�{nฑ๗๛๘๗�—/x.จฎพ‰c๐V๔nN$‚’+๐b–W๏x‡‚f&y�ƒW,Rv?ไZจป“ž(ฅภ�ํ๏Rb‚ื`˜4‹เ"`ำwึ@ j €เ`ˆt1˜m)‰ย@|๕4�ลz3‰ƒ*D–ฆํ/|เ๋['พ๎ะE"YŸE๐ฤFZp+ูฌ†u|-€'ฃ@�ๆ2ฟ:ไ~เHP�กะคล'.KŠฅปะ^H-bฑP…ร ณุฃ!œm�ฮ8ฮhF9ฐ1L, ค’ๆ๑'…๔ำ!็ว?แมMS๖Xpค @ชศNEŠ่„๊ะ|ไ;Ÿ&3ษIbา“ฦูุG้๖9>Š�P น‚=Š‘๐ieส(`9b5QyŽ,ลE p 8ํฒ—~๑ี๘ณž—|ชžl€IOศใ—ษ”Ÿ p‘๙์Rั„&ฟN๘ฬe&๓ˆi;@bˆ` ั —ใ”ะ6Ch(๎ ภv‡FHจL:LะLงp€ƒ๎fI�ะ‡Ÿผไ&AูIฮ"}คLhL‰|่ Œเถณ$Q=yq˜8q™ขfa&0„BญรZ.ZผA้ว˜!E  ไsฒS"  Kก† „ฅ 5J›Iฝถด’]ฉ๑0Pัš^ศK)GpC€B:ฦฉ]SจTง๚๎ŽชXๅOUุิxษบฦฒย`ŒศDYปz„rFfล&จยธ1{8๘ช8ณีฌ๚๕ฏ3€Kุย"ฐˆM์ jA8Uฑ (Wfค!๙!� ImageMagickgamma=0.454545,,‘ƒ(((999FFFVVVdddwwwŠŠŠ›››ฃฃฃทททษษษุุุ้้้๓๓๓�ศIซฝ8๋อป�`(ŽdนEAคkช)ฯtm฿xฎ๏|๏‹ƒ˜$0ฐ+ยใ’œ(ว'ิI.ซWcv�ฤZฟุงx f’•�rT›Mฃ%‚‡|N—~๘ผ‡f"|†2‹L‚Hˆ2” –Ez& œ w šus ฎrฐฑ ฑณฎธuบtผฏถพฒภรฑมทฤนศปถตลสฝฯฟถsฉึืซ ิŸœ rฉ GŸ’B ีPใ N ไๆ่๊ 0ศ F}สๅ�WจžB ๑HผwแC(็a8ศƒ9�Lภ“wแ�“ศแฤ`‚4H@แ€'ั„9�™Œgf=ƒ.ฃ•๓˜OhGฅ EบT้PW@ŸNำxญช›N- 0เ€$•จ8่3@`�Ÿฑไฌ๐เ€ชnฦ–}ภI฿นg”’๐q…Q�โ…จwฐนf%HLApร$|7๑แย–0—ช›v,€๕|,d™+ก   ๗œ’lpŠ›-ปvRMqKeบ�)๏฿พƒ๋>\xาV“฿€อA?#�ยjˆ€พ๚˜R[aเ„–เ“ภ–ฆ๕!ห9Žม๖ษ‡�SP>�๓ื‘ฬฟฟ^ฑ‚๔ๅ�~่1กฤ€„™Gม)ใ‰žtNDYจัE,/�มšฌีขsq�fTn#๖V�‰%—ขqด‰ุ"‰/šธ"Š1ฺ‚œr8สภœlนu,XจAwœbฯyฤ0‹$แUƒJีY„‘๎…7ฅ๎!ค$w‡ฑB•P €”aสแฅใ€Cฆ˜ด$!ญ‰ๅ˜yf›BาYไœ่ใืจิ @Bจ†žr—อ๒_ ฺฃค2ึศ"ฅ*ZJ#ฆ—บ8 \9†ZรŽ0x>–น่ผ€L ่c�Gฐฦ $2=บ_5ฎยบภM/ลิ@ฌ79ืV�บ`�๋๋ญ&๙,5ุ๋ฐฒ�LR๐ดืŽฌดุB;7ึ’ซน�h” –gฉ๒r"“{๐Bม,Vฑy*๐คWส้ฆgz๐Œ kzœจฯ๐แI„P4เ�)ZP ฐ๐๑งž์ต๘•/ศะฆ\Kฐrฬ$kl2|( ฿1ฯ�r’>S ภ<=ร37ฯA๑’ตส 4L/๒วš�ณGฟฅ` l9ฉq †2vพ@*า ไ™้็‘&�)มt,7ยu+|wร ำมjฤ€g@*F แหจ๘›์ˆืึyึ5fงาci�พค(หัnNณไUะฮo.ซๆw]’ใneKA-ny+Gิฅ?~:๋g€z๋์†๗u +ง�าโ9ฏ�ˆ Kฟ†ค�7 ฑฐริOo��ีc�ง๎}Mัoภ–vใ้Jวp๓96ษl้ž ‡cฅ๚ฌ๙@Aฺf๙˜ผฟ์tบŸb�c?๙xGp๊#]lhR€๖ฬฃ€  |ฦ†@jหK*ั• VV: Mหsย)ๆ'”ขฉ๚D+ดวยผออn.ฤ gจท>์{8�€ !ธœ)#D‚ฺW๕ฬ:่๐_“0ฐฒ๖�AD€z@“xภ๑ฉ@�ีใD)๒ว ุโใU0cกH SC/DAmjZ6‚•‰ฐlฏาB+ฏบๅAQ:Sˆl˜=Bn†/ฌ!"eจH๙-‡ฤภเ0P เxเXธ1q@iŠ�—`‚, N`วS 0€Pโ้“ก\ภืฐ˜3พฒ•Œ.!รI xr—aฅ>2กm<€|ฟtฅ'A9ฏ^~G—กd ช’vp K<@%zT™’ฒร3v”@พZB~•qL‚d†:‰ยNจฌำ"Š ไ9zสมž๗y็OŠ‚ฯ~๊sž�ฌgQษ‚ย €—นงhๆฅ-ljขƒใ‘eผจ.‰3_ึA>ส“Cƒ*ไ€ˆฮฒข`ขใP0“จึH็0ž %dP ยG๗bR‡ภ๔#๓˜ฉ๔๊PFิ�ไำ)Š.๙m€สšA—สิ r*Mไะ@04ฦ}œฑ๊)?(พไY ช2้ƒ๐UฯbŽ^WจšVตv }`�รใvpึจฺ๕ฎ+ก๖สืพ^ฏ€ ์ `A� ๖0s@R;!๙!� ImageMagickgamma=0.454545, ฑ4…(((999?@?@@???@@?@FFFOPOOPPWWW`_`gggopowww+ตB=ดQBถV-ฦHํฉ>�ถ?€€็ชM�บ@่ฌR€€}ป‡‰‰‰™™™Ÿ Ÿฉฉฉฐฐฏธธธึต†บสผัศผฤึดลฬณสิžฯๆŸะๆกฯๅขะไฬฬฬัฮษฯะฯะะฯฯฯะฯะะิิิ้้้๓๓๓�ภูŒ&ฬ`Ž•dๅˆษ‰BกdBญZ%ัgšๅณZ0ุ+“ฟๅฎzœ^Ÿฯb๏ปฝ ฏ้๒8� Fฉ�)‚ƒ)(u ""” ‰ %Ž3%žvxQQ 3 ง3.”ซ B!  -3 b  ขฒบ ศ1ฐB ” B ศ0ฯบ3"ฝš03- ‰!Y-Š !๓ๅ มคul{ ฬ x็Ÿฟ�F),#PAƒำ4˜MA‰ แะก€Dษ’#BฐBr‹m4FD‰Pฅห‹๏ผฤธ’ขม™ aฺด3ำ�Š? 2F"Z(่&พด€๑แ ^ดขžhะ-'J1hyc0ร‚3ขฦpB Z8@ฐN[  hล๚ะ‚ร€`P๊ล}†Lp_"8qิ�฿ชZ|(๐aUaง-4 žั 2ž(hฤเ@ผ!1Z -‚YŒฐBt…จ2cอ…ดสLษ๛๖J.8c~ฮณทW�0~†#K–„,3ฒd•“{ฒk฿ฮฝ6๗๏ฤม‹?>พ� Ÿ@ญค‚Q!0Tžมaมบ"„dำo „!?Yˆะˆ  ฮ�tะ€|๋PYg๋ ฿*ญ�„๐ 1I eŽiY,ะ 5ศฐ2C 0$`ษY8P@ ุ7™ B4รแ *F‘23ผ B p ฺ|ž&ฤ<๓‰ aU-ดpyX’—ey�m™]—^V&x`ฮ`ฤs1แDSPQ�cฦ †:Yะ)'vยw็yฮะ็žsžH ๋ญฐ^ ,ด๗�‹€ ข*RnhQP9ˆญDย ,เฉz๊้l3ฬลีŽขี™j๑D๊ง4BHyยค๚๑๓@Wฌf!cฦฐซ:*พ—0 ก3|@— „†Œž๒€1ทp ‚ๆ…ถPRใAU€jื็Ÿแ๊Ygน�eŒ‹ฎ๊ฎ{๎ปxฮ0hFWมๆFฑuUl`.y’ ฐŸEpพœp ํฌ ร›pฤ ๋๙pฤ �›๎ย|๑ฦOฌN >สยษ,j่†ะCฃBคโX~1˜ร `+b€1 H3ยLg Upฮ$๐ไง1 ม.‚X%Tt�๊gคY!2ZSำ D฿ศApQu€ัIZไŠวˆP<&ฉš.00ๆจฉ @wค$้รŠ ๏ภ!ฮpเ๛‰1ย†ŒธลŠƒฬ8ะฟ›8ฤ’MนวsŽ9ป7^ฐบcร™๔&qฅ—^d›%E0� F+^:Œ"›�pํดร(4|ญ�nด๎ดZปO{Qh!นํฤฑ๑ฝ{ ฃ๏ผ7๏ฑะฎ฿ผ๐ฦ;O�๒๐i�1๔ำKo๛ 2ฤp‚ส+ œฒสํะ๚ห @�AykPฅ๒i‚}-% F๓\‡=ไu`D;ž๏ิaฅc EJ‘ม4p<)•ภJ (เ,ยั ไ y(€Dเ€pศ…ฆ%จ  *€ b๐ผhI‚+`ะฝอ?Rา@b๐!*HbTฐ–$›โ_aถ<B,{ภs]ำ๗ฝ�…ฯzสฃ๘ธฝ2~๑Œษร๓�~xพึ‘1rfผž๘ฎ๗ล9ฎqŒwŒ�ฤG๒’Žฯณฃ๐�HฝใกQŽ{$_P‚ ะ๋( 6)ƒ�I’ึ‰ :๙‚›Mฒ“0h_ํƒNJPฐ< Yส พ’ฏผŒJฉK ฺQ—สซe/eK`๒๒‹น�e๏‚)Kd๚ฒ˜ศ„ม1{็Ke3’อคๆ+Opฒ๘ษฏ›�<ํT“?jฑ…TTŠ =`€เb'ธVึrฺr—ท4#ฤธโHb’HCฒœv<‘ ผภ ซTขใฑส—-˜ะ {ี‚iรtแ๑@EžอOI๊™d๐‹ฃ1ะ€B‰�มAใ"‘TT๓ +†@‚ J2›™ห|Z“–ูฬ'4—9MŸ�๒šา jOตiฬ{V๓จ@u๊5“ITฉN•Q&.Ÿ*หขRซฬดj๘”šิ™r’.A(@ Œ “”ไ+%9x@€@6ะNV)ฎœl฿-{<นถฐต<์ิๆzณร๖-p์`ต้ะศ26ฑ’ฝ™e3๋ฯW.V‚ฅฤฌd!หูg�๒ณ…mฌCMภฺึบึต'p5]ฐCXBvณUสY•ฆๆ‚`Hpณท4lg+WIcณทUญgS๓Wศ๖ฏภฝ-\#ป�้wธู„ซ\ญ �ลnต…”โR�ฅ�ฆฦ‚1จ-h๋XสตญcI[ฺXV6ธสอ,}K๋^๘†ถพ๛ๅlฏ๛฿า8ณฦฏ|‰;‡2wท’ฌฎ„ญแ�–ยฦฐvน�� CWปาpˆ%œ� Cxฤ$�ซf=Œb ง&ย'๖๐‡C+ใ๘ล!†1‹Ulcง˜ปI!A๏’”ค�ฅบ=ึ๐��rใิ5x@ํkะ๒ืเ�P=�ูฯ��๛��(}P๏๓Wซ๒—z๛�€๘€ุyœ7€(Xyhy่y y่y#y๐—”W‚ ˆ€šง‚๘‚0ƒ2X|@ เ๗็4๐ @ pQ` ศ4P!y ๗G ‚4๐X"ฐydq PXRy3 ะƒD@฿pM(y(y^…Syด… [x,Xy5xƒ9ธƒfy?83Xˆ†xˆˆHz†4`-5ะp!X%๐\ศ… ๐Gˆƒ/๐ˆ ะ5@ˆ๐7๑๗5‰˜ว5Q ะ€/@0Šฅ�Š:ˆŠ ฐ‰UจŠŸจ‰oyคX‹คHˆ•๘Š๑†ฎ6ฑˆ‚–ทˆœ่ˆ(‰,H‰‰˜ฺธู(ฆX:Ph๐ˆ"8€H(‚๗‡ย˜ ๐†iุ„๐G„ํ˜yDะ๛๗Ž :ศ‹X=D€๓˜๕y5๐H๒H/ Ž x‚|†฿ŽใๅŒ�ุ‘๙‘ธˆwHYฐˆภ‡!xษ๘} ยศ‚Iyๅx‡๛g‰ศ8“4Œ?˜’�P“ ๐ง’g‰2I“๏ศŠ h’รx““'’‘G’w’๕—’’\ู•^Y}�ๅ่”IŒ5ฐˆ{ˆ.ฉ“๕ว“ฤ8ยจ“Iy Psx‚ษุ“๙s)sูoY”nˆl y4้๔T9—u)•’–๊๘di–_9™”Y™ษทˆฌh‰ฌจ—5€Š=น’5ฐ•O9‘๙7—๛h•ฃ 0yy'น€ 5เT˜…�ศ๓˜ฉนšyฆฉŽM8—Ÿ…๒ืš๗š{ˆ˜’‡™ง™ผู™ทh™ะา‰{‹่อ๒Š“GŠ%yฎXD ‰น‰€C๐PศŽแ‰yiH‹"ฐ„8‹ไy˜๗ว}P‰็i›ข‘7žˆA‹X*-ภžšศ‰ ๐… ‡‰˜5`�ุู‰…ำ๙ กช๗9ธ•ษ8‡’งŠ๗งQ‰‚@Š`๘‰น—”‹‰•๗กQŒhฑœท8ขnxn™ข ช†‘g‰Yƒm๘ƒ'J‘KˆŸ)z‰ `ก–ˆกzคHšค—ท‘JŒษะค(“ฃT ‡Wš€YjฅP๊Ÿษค–7J:ฆdชคส9yฦ๐š์xคgฺ˜NQYฆr:งันˆF yKH‹Ijง”—งIง€จ–)Y*ง\*จˆšจŠบจŒฺจŽ๚จฉ’:ฉ”Zฉ–zฉิŸYyฝh‚[š‚pชš่(‚&hช๏7ชขšŽขšชชzชฏ๚ช.�(ฅXซจzชถzซฒ ซป๊ชฐฺขษซยšซญJฌฃZƒœHqส•š๚y„š‚สyš*ฅ™7ญ-Xจ‡Jzา๐ภwจ‰ุZจ——ญคGฎžJ‚…*›ชzš*ฎดืฌ•งกoศdฒษ™kZ‰?ฉŽ—ศ…๒บฏ�*ค๛สฏ{�*ฐ[ฐ;ฐเจฐฏyฐ ‹ฐ๙ฐ๋ฐฐ�ฐ;ฑ‹ฑ�สฐ�ฑ\xงy —Kx=)ฏ฿jyeศ…(จ•‘็ YZ†๘„3pฏšXฃ๗‡`งŽ๒2›yฏY]H๘…สj‚F‹ณ˜ดmIDคใjดหสณ4 ดXฃหฺฒzจˆ�๙ณ ฺณšว‰?ณ3ภ}_! ฎ4Ky–HCey†!ภ’QZI™ฏ:ฐ ฐz๋ฑ ฒ�ท‚ธ„ปฏ{ห…‡›ƒ{‰{ฑ~[ธŒปธˆ+น ๛ท"�‘$ปy๏xL๔}† ท๎ y3dEๅ)Žๆˆงq�˜o๘'‹ณP8ก๘}ฏ+q;Ÿ™บ—2@yยIปฒ›ป™ืปย ๊ภ ฒฎ“Gผฉ�ปคบฆ;�๙}!ะBดkตœวบ๋˜ก ภ‰š‡ โ พถ‹บ�WแP†3Šฆร˜ก-9—GXปH—<ธ•™›ทKน ;ธ†ซฟ๛ธ�๛ท‘หฟ �น“+ภkภŠKภฌภ๛๋ภ{น�ศบœ๗3ะค8y๐�ys™‰PX’s‰ป„ษ g$ฑธฌ’ !ฐๅˆ€+\ y๏(ย•Oy- y/ฌ‘ …วน•9lบจถ—ย;ฤ>์ซ๊ยRูมขW7'lyชHญ ร 3|พmHท”'ฆX †ษ^ุƒ๐g› *ฟ“Gม๚šฟผภ ภ|๛ฦmฑ \นl|ว€›วqภ�ฟs์ธ�+ม�จฦ™—“•g˜0ฌ’š…๒yุฐT๊Š;หร๗j‰์ย0Œ—|1`บก  ฝ6�’ว�ผŠRํเพˆiํไ�ช<|‹๓Ž์|˜ื•งๆ–'๊ษูลXjโxม .้X์้Žฝ&ศ‰@ฺ8zzฮŽฏ&H๋lอ๊/วOึฯ�QŽ�๏๑ฑnึ๔�•๊y8ศIm€ู้๐.yบณc.y๛mะฯ!นkJŠฝpŒ„)ฟq‹ฯฟ๔U๏๔คุฝQ†SOŠa�ข5@"` =™†ซธyภ๓๕ažู ฉก๘™จจดV)yGy�A2฿:฿ง‰@ˆ �C*Ž$<0ะˆX=ไh=๙ญž๑–/๒ธž๙DŽ๙›๏ไšฒ^ ื›๗…cฉมย]์จ ต๓x‰๙'็8_–ล]yกx‰Oณ๗"h ๗วŠฎ๔ขŒั"x๛›i๛˜8yบ‡ย_•\†•ท-€„&๛šจ๛าŸ๚pH�bนฏ,๗วiyิฯษˆ)�@d�� าb�๛€ฟ้Qh%9=฿”ทย๗'‚ฦ “ปˆyBˆฉ้ท๚%ฯ•๗_™ฤG๘~@0@Ec``T.™JDฒ5 &ี*ีCฑ(๖Ze"›`ฅบŠ—f%9œUตว\;Pค•>~๎I*@€๐1Qq‘ฑั๑2rN ฆฒfA2Ss“ณำ“1คฆeดE๎๓T3เƒฦี๕6Vv–ถ‘าณVw—ทwAƒ#˜ฃ—xi กXy™นู9๒ถ2๗™บฺ๚;;*!๙, ,™ƒ(((777FFFVVVeeewww‰‰‰™™™ฃฃฃทททษษษุุุ้้้๓๓๓�ศIซฝ8๋อป�`(ŽdižSกฎ+1 p,ฯtm฿xฎ๏ฺLมๅ'!‹#ภศ<+Dๅ…RชNคvบตrฟาฆS๚�*ล`ช7ฌ.—ฑLมc�pะ็ž�_}"€}IB'ŠŠW‡PŽ…'’ ”@ƒ~‚F žž   งขEww ตtทธบธ vพปผยฝตลถปวนฤภฦฤะธสัมปหsฟึิฯฺ�ตำ�ปyšไ ฒก้ฃฅฐ tใ F๏d DคฆW sํ๘ซkž ]๐งJีs๘(QD‚คkP€ƒ�ไpฑ"พx&๖ตฃ€๐‡lHP@“ฆฑ€ตcฐม$ pง9แ%eถ�6ฅีขr“ uชีชX™Rีz•kVงM‡…3ดœYE=ิคY'•@ภ฿)ฌ$ุQ8ภLE็ฌ๔w€ภวC„S=xwย� X l๘งส‡7`ถ ภS‚ฯ \ฦ}` 2โ˜ฆ5ฃฮ @.�ขCxkภœุfฯ๕งPNYž^ั๊๘ €Aขณ � –นX็ืžwm>]๚W๋^ณSฟฝ๛Sํุทƒ๗.์มธณ่/œ แ[มแrฮ๊ใ‚Vท+จสธ xวฃ”�ๅฯPํตfž๗เ gqIFA0@€—QxลƒFุ™เ€€Nโy]@๘กฎไ%ย{๑Ap=€\!a,–ใ-�M-a‘�wโ�‘BV—$wD"ูไ’ใ=Yž…้U้ฃQ ht„m=zเฯ�  $-"1a;ณฒ dณฝฐ (a0ฆfษนฅๆ’ต�บ็€hi*ˆง{ Z”G {Šาโ›ภๆฃp‰Nฦ`?pYA1-6ŸyๅC>ธY๊OุXฐžrR™๊ชถส๊ซJฎซซณ:‡‡•ธVgท„ ฃ>SJL€ย`PVpใ>�ิ เิ์ณ�ดfวลยฃ‘U0mะJ๛€ณเFK=~ฎ ุ!๘„ฆไฎซฎนŽว์ธิb)O•ฐl จ�บ‰?7u้ ‰ ผ 0เ€"ฑ�ˆ*ญLbฅฦFBูฑฌรrญ$ใRVฎ้Y�+Oเ0ZT.0 3ˆ฿"็O:฿ภ/่,s4›7้B}ฮ$ใ-A�ณM3ฑRฯ<ห@"๓<@๘L�ฆrBM5˜F=JlO7M•�”dฎศw.PA๔/Kh‡ั:r๊r%o,ฒเฬฑ“‡{Œ๘เ†�ส6สfฉLศ�ตฌAp�'ทฆ€Oชwศ„-ปฌ๏ฟล๘ >ฑlญๆœฏRท�ฒTบLง๛ํ�Zบ้น“ำ˜z=ฆท‡๚์j`๛๏:K€9 Œค๔Kฒ'�๋Zpฆ~ัสไ€Š็˜8ศ„ฌ~๚์7^๘โ๏+ฎ๘ญฃw*ฬrฯmษN ๓„ค๑�จฐ็ฐู๐‰]ข˜ไ อะิ@)*`@&ฐิ@h9pจ2 จุ :sมv&iฆย ภฟ8์#� nฎฐ@็Zย›มŠ"V4 `CŸ๛ึ7ฤ๖มˆG4ข�„˜ฤ"�a๕ำB>รสษวY๐„�0”R@€e๒�ฏ๘I(?fไbk่มU€ง0#ฯ˜9,ขิษ `—ฬQŽxฌฃ�h!-Ra†=ท$P`Bใุป ๅฒ๊™งง๐L€๓+‹‰K<Ÿ(ืฤR†’”ง|Yขx–๛m\ตฑ$Jำ(ท๑ษภๅ]๚wตŸ‹—• &�Sลธไ#0ฆๆ(ะF ฤฎ–ษ”ุ1‹้จŒ ™ฉ๘ำ๚3�D!ฐ1ฃฉ)RS›ึ\ 6•#ไ2—น‰Š4@Y“ถม <โiŠเใ/สฐ ้ ™8(›$:•๙PษฤT‚ฒกe�ํ"๊8(ฒRS๔@@๕S‹คมฃG E‰'เน›]` # ส?Tคา:ไeค6�V š„ฯn+อข"—yแEZ๋๘๘�ดggvฺาฃ†”~KฐCๆ2€RŠ.ช3(้FborปจXวJึ |ฒS-kึย.2ึฏ~€ฆ]rฝ$ R}}$ฺšืภ ^5,I~wƒทB.2Uซd'Kู๋&˜อฌE+หูฮ:“O ฑซgQดัš๖ดจMญjWK\"เŒ`- RAXฺู๖ถธอญnwห�\E!๙!� ImageMagickgamma=0.454545,ึw†(((999CZ ?@?@@???@@?@FFFOPOOPPWWW`_`gggopowwwศ<;ํNJ่\Z�XS๊a^+ตB=ตQCทV-ฦHํฉ>�ถ?€€่ซN�บ@้ญR€€}ป‡‰‰‰™™™ฟ‹Ÿ ŸจจจฐฐฏทททืŒ‹�‘ุท‰ัฝฝƒมบสผัศผฤึดลฬดหีพัฺฯๆŸะๆกฯๅคัๅฒุ๊ฬฬฬิหษวำษัะฯฯฯะฬัาุุุเ฿฿็็็๓๓๓�€**ACD…C…††‡DŠŠ‰Œ’‘’ˆ“–ŽŒ•›–œ™ —žข”ฅฃ˜ฆฃŽญชฉฐฌซ™ฎœจนฑตฏ‘ค‡šผ‹คžงŸลšสฆฬฎฑวŸบรพะภ มฅฉกชฐญาุณ›ทวแตดโิไปณเถึ฿รๆ้‰�ซ๎่็ื๐๗ผC=.†Hฐ มƒƒˆฐaC†.Lฑขล /„จ‘ฃฦŠ-z ™ฑใว'†tศP`ษ/St)ำbL‰7OๆDYณงฤ“#๎�๙qฅO!FYฮ 4eาžOU.58T๊ัซXณj�สตซืฏ`ฉVฌ–"ำฒhำช]หถญ�ท�2ษžอSฎ :ฦ��หwo^‚ 3ฦ�๋phUปgmRŒฑ&โ˜ ๛|ผธ๑�บf%๓E ุฒย–้๖�{S.cฯจ;o$Pณ๊y9ึจ"็ืz F๎WใKองSRึ�๘ถุ‹ฟ7ง๖อœ๘ๅษวCoŽบด๒๋ธ“๓ฮ�๙tIฦษƒ)ปrqีฟK�Ž[(๘พม๏ชnนz๓๔ฑหวธพ=าฤโ™ีžk์�๗�5„™ Vท฿qz็`x๐%ิ_f€iGี{Zศ_~ู']ƒ V7‚หy๘\‡~ˆขˆ๚!ศโ‡๛กธ�†็อ๘เx% c|2ถXฃz‚ฑ@มX�ภ ŽD lฐ-0IF/d ม˜เƒ‹9สgฅ“�‘gวไำEึ™+Ž9ใ˜‘๖ฆrgษ •b†๖&Ÿy–น็|B‘ƒ7� โiฎ(fFฌ]ฆ็ƒผ ็zkบhๆฅ:้]ž'zชๆ{’~j‚ฑ�ฉf˜}>z'‡r:ชŸqย:)vt6fงฃถ :โŽญžXjŽฑ�šซ_`v:lซธ‚วgห*K$™รด็๑นนž ' pB ๏&ฌf'€บช™๕~๓Ž�:Lc#”01{�ึเq �า(ฆ4ฒษ4+pŸ›"\ฐมG�/ษ-ญpฮNKLดฤZS�งีH/ฌtยb;ฺ๐ี_oํvึb+7 { ฎธโ’�๔x5hษ๎บ๘๒พฅ’Œตแw+oม๙b]^ศo+5โ{?nxใ”งJ๙gต Lนผ5ไph‰Š>บ่7่ ฐ)t�ƒ3Œ‡ย&—น7ๆ<. 4ะภ ฤ.0 ฐ๗ภ‰.ธจบแ u;ู<ๅ ๙ๅ=(ะzไ”wฉๅ�‡{๏ฉๆˆs^v๔†๋Ž;ืxŽพ๘ํ{oพ๛ษŸซพ๘’‚๏9�ใ‘yy๋ ไFภ ฌภp-ภ›9P%’‰เo�&Hม Z๐‚ฬ 7ุ=ุเ6กGBx  @A>6 @@B ฐม� ;ุ“b่ค/]ฯD๖๐*P€ พTฝ ะ �สa'E’๕ŠMvpร t1@เแ|Fัyึ ย—7 ธเŒBไม0Oํ?8#yศม>๚๑€ ค 9ศ๕๙ภุ’@ lํะnxใ€$ลๅร๙m]`WN�ศ?>๒ฯGl๔ž'=ฉฦ๑|ฑ‡๔�)+ธJ †’•็b#) ืJ’ั Q$ฬฅ L่ฉD@X€ @L€˜ ม ๐ห8`I„� ’K๘ัI#X€๓‚ˆร„ภ0@๐€@%O 0€<@‡#p@p€4j@ภ`ฝ เ่Dใx‚–`™ภpร&๎€wMgR b>Š3˜g"€ํyq ฐ€€4@@„็ฉZR๐•lฅ,ล็R๘ี”0 LSูฝ›ชrƒ9ๅ฿N�(=’๑qุ*PlMเ\1�ภ$ษ�ฉV5\0ฅทšIb๒„l๔ฉงByรฒzq–‚๓ ซi8(Žต[A#\ู*ธ�`–n-%*Q๙ลYž๋‹}•ซ฿JXฃฮ๕ฐzฯ-A(BฦŽ๐ผิb๏Tƒ< *่(gXร(เ๋ ขHa๐,/งim้๒ภอ ”6$P€เb อค@pะ^x„!B`)`@Y‚t Fผแ€‚๘z"Eq•ฯ   ภ์v€t '@ฬš[้Ž`ƒx@ธ›€aŸ”อํ๖bาโ ๘.ป;�uฐ{l`{๊คภ๒1”ฏŒ+)azZ�น�๕\yE๐[L9ภ>๒ภ…ฐa3 เบžยNl))Œ8 ร!๑wˆaค^KฉLujj{(UซR๕ชY pWฝบ%ตขาฎฅ„b cลบ�ะว<ฬi ษZ`ญฆีรž\๋VO™ึ.บ5ต]ผ!fฌb! 6หS.ฅ'ฏ\J˜uหaๆฒ‰ฌี0ฃาฬใ!ณ”ตผึ#ห‹}์Aศg.๏โUใเF:Žg†ใ / f+[8` ๘XUP า%จ๔ฅ/-ั๑@€Ÿ๑<@ ๒จ€๑F‡p๊‰n7ผ.Olจqถ]�ช[Bไ5 ี?ฉJiO� A8�ส่U๏ฟ๖โ@‚!ซ �์Npรุ6หธ–จ ะ�;–อึชY=์$9ซ๑ฬu.๓XูผU7ฮAp7˜ัb/‹Q�[ewœ๏�๎ญขy�"&cพ�lึ7[™เ๛ๆ๒+�อ๐4 vเ๒†3-Ž`zƒ™ส฿ก‡ื D^K‘Œฬึ‘0ฦ๑x ’“”$|l็\าซXฒ5N๐%{๘‹๘�น ผfงv่,u~dฆ๋ต‹Iq˜หŠdชKโD}ฒmจpy›๕๋๏๚ัฑ\๔ตฆ[้R�๚ึีž๏[โ`ฯ7ศๆ~บว๎ม>€ }@‚�บ�เ…7œแ ={C `ป?8�ฉวxC๘ฎ xผไ- F2–“œPกˆk&Q ํวMiœ๕๐;ˆCqˆ^;SS�œ๖๊ส๊$ 8J๐€‚Œ�DใดIภ๒ D›ฃ `@:Yะ๗V๏Wวu XŽknฃำณ:๔ฑ”uNsฎG=�`ง๚๗w.u…›ฝอใW;ีผ๕ซ{=๋ไo๙ำ?๕ตo}�ฺธำฯN๕Wฝ�ล๗~rฅu๒'vi7ua‡dg~‡~Z‡fxdf+P@rร๘ฆVd”@ 4.Ubf๒๗&ภc๊"AwZHguฅV+W|(fหำจe+�Xe[ff-xZ,—eŒ—ƒ+—oxดs3€#Vsddd,‡t๒๖ƒ>ธ‚าV€^g58€9hJ;8…pึ?จ‚๏V€งๅ74t—(u7wdXw3๐ƒxคw�าw@@z,'x>^ƒ๐"ลrภ่E…^ธv9่ƒลZ่vd3”MjDzfๆpWใถๅ†Gฑๅชgfใึ:i๕kfRณวj[GM๊e;@B?P P| 0ะะvjf–L.„Šะึแ&8‡7}gๅP‚3‰A z@คVCๆ…H˜ZJˆ…Lุ‡ํ‡ePˆd[จƒ^ศ‚7dŒ@ธ…\ื€,xF๘vฦ~�Kธ…MXสˆ‚R€Gศƒ=(Z่ีXsDศh…bfeYX|๏xt๖…K6…า๖Œ=๘dุrีB@rt„•งV/ง@แR.5H?ะภc๎าŒgƒEศ่ึ}*h…Yƒ@)+I”7ธ‘่q37.pœE= ™7ู‡,๙7๐10ศ-W„')ž-‡G!Y“fถe5ธ‘)YŽๆ˜ X„}ธ‘\”G5dfXˆ๚™ ฑyœ๐ษก šGชก กZ…๛ˆ *Œ�J}๚' ก"๊ขxิJi:ฆ3w:Š3ะ‡G•ูฅ_น —แเLตEต5{ฯxก1šƒ1๊ฌฅ‚"ส˜ šP๐ฌff�–C๋คP๏‰๏”C฿fƒฅPŸv˜ฉงPฅ6FใF| ลPq8ศOFz˜งฃ๖! P๒š*pค๕4•ฟดธ 0%•ƒ ฐš๊ขxกบก๊Yข(บข๊ "*ฅ1Šฉย8ข๊YชJฉิงฉขŠข5šœฺขšJขช‚ซJฃฅJชงŠชฒzฉ3ชซ.๙ชซ ŠฅŠ ปšC;ฐG2ฐ<ภEศสƒ[๔<ะ %�ะ9T…J}= p€" ฅ0›– ญชฆTบƒ–šช๐zฌcTC� ค<ธญำก๕ฺฎ๑ ช54ฏ0๚ฎz„ะ*ฐ๗สฏฒŠฌkดฏKฅ\”ฏๆศฐ๒ ฏ หญ;02ฑปฑ;;ภหx� ฃ>P€กศšฎบE๘jฐ�zฐ๋h]šCjEณฑ4๛ฏ็Šณ:‹ฒ๕Jณ—ศฐ!�ฒ)KขE๋ณ๊šฒz‡ฌ‰‰๋ฉ,๋ฒ�สฏ Kฏ๏:ด๋ฒ›ฎTkณ๙ญๆ่ฉกหต(ปฐW๛ฎ-Kถ[[ถ1�ฐ`+ญย8ถd;ฑ ›ณ,+ญj›ตl+ฐQต)�ธ ธ> ธ‚›ณ‡kธQ;ซ„+ธ,kธVปญ) น“ซฐ[ธƒญˆ[นŽซน›ณHKนh[ต›หนŸดž[บ‘;ซ�บŸ›น9ไ3เ0 ปxIปณ{ฑฐ+นป;Š€ด‚ ฐค[ฐขธHtค�6ผ‘ซผ‡kบฮ›บฅ‹น“๋ณภkธF‹ฌใ&]ั:C/๔ผ ปปลหป�jผฯปธชปผร�ญ•บ‰‹พ�พโ‹บโ๋พž นแ;ถ๋ปป•ซธฬปนg‹ดา›พชKนอ[ภ|Gœภ ผภ �ภ�ภม<ม\ม MZyม ฌ# ฝLภย‡[\‹#€—"œย*�ผย,�ย.�ย0ร2<ร4\ร6|ร8œร:<ฟ;�ร>�ร@ฤB<ฤD\ฤF|ฤHœฤJผฤL<รฃ‰O ลP์•^)ลQลUlลY|ลWผล\,ล^ฬลaLลV<ลeœd�ลZ|ฦf ฦk์ฦUœลq�ฦmผลc�ฦ_,ฦO<วn�ลrŒวz�วXLวƒฬฦ‚ฌฦ*sศศ^ผศwฌศ}ฬวu\ฦLวLศ‡Œษ‹Lศvlศ— ษ†lษ”�ษ“ษกLสœŒว|Lสจ สyŒส’\ศ‚�สดlสŒ ศฉŒษ•หฑŒศน�หŒ0ฬฤ\ฬฦ|ฬศœฬสผฬฬ�ฬฮ�ฬะอา<อ�ิ\อึ|อุœอฺผอ��อ��อเฮโ<ฮไ\ฮๆ|ฮ่œฮ๊ผฮ์�ฮ๎�ฮ๐ฯ๒<ฯ๔\ฯ๖|ฯ๘œฯ๚ผฯ��ฯ��ฯะ=ฮ@4ะ}ะะ ฝะ �ะ-อ]ฬ@ฮ ่ผออภ‘ฺั�ฬ"�ะ&}า(า*ฝาะ<ัร�ND@iเ< `ฬ@€ฮD@�ผŸ0�ผำ,=ิD]ิF}ิ๛์า#@A@าฮ$@6ำ:อำ�|ำ@ออBิ\�ี^�ี`mอ.อ(-อpัฮผิSำg}ฬmฬhอ[=ฬoอqMฬTํึw อsอ�ฬuึ€ุ‚=ุําMํำ{ฬ0ปื)0ฬ>#า0 ฺC   pั7KM)€ึ  5  ฦไุฮlkŸ`ีฃ]ฺง�‹@BpัAภ0๐ูกMฬmำคMฆ]ฬA 9=ฬ]๚ฺหผุํิ-"ํ”Mุึ}�ุ�โ์า ๐ ‰}ฬ'L=sอE Pำ7#pไ=ฬ;ภ� ฐD0จM�C๐�D๐ฬ์D _@Y�๔m฿๘อ]ะิ pำะ�๛]�]ฬnฬ๓อ;๖ญรDฐฌ•ื�jูืเฝ�@ฺญ็ฝฺ�โ.�โ0ฎฬ. ^าŠ�๘}ำ'0ฬค}ัๆ=ัีu}ำDฐ๙ ิ>�7�ุFŽไPแห<h-ิ ืMZYัDภ•mไ�t-ๅรผไc๎ไ>ๆYอ(Užีษl�Cฐใะ ?Aใxž็z.ุ3\~฿หl�ษๅ*0ฬ*ฮำ%0qญึล|ำVๅ@อแ๘-฿A฿Nๆศ,่xอำ.า:N;>sY–Žืnๅƒ๊Dเ้•๎ำ�฿9myๅžใƒ>…‡ฎๅŠพ็พ�๋ภพา}^ั^๋%๎c^ฤl฿ญ์ฤี�km๊ช.า* ฐพ้ห เงีช>้๐้�อˆแŽๆƒ�ืณ�ํหnํฎแ~Nี�ฝํ$nฬฤ>ๆ=.฿ซ๏มž๏๚พ๏�์า]ัอ��D€์ชN๐เำ6^าK}ืbN๋ะ�B>ไ.ํสฌโษB ๑t๋ํ�฿Fิ Oๆ�Nฬฺ฿�Oฺ9m๑รŒ๑ฦ^า๓^๐ฤ|ๅ ฯ๏6๓8OฯQ�€ฎฬๆ] ี,^ฬ๖๋ฤ<เŽ้ศ๒YMนEฺa>๋๘�ฤ�รmีPฏD˜=ฬ ัคํ฿No๕ชIฬ[/๕ํ๎Z๓]แป=X_ต�ิ์�๎BO๔ำ9Ÿ�๗zฟ๗ๅ\ะNRฬ�็Nฝื~ฺล,แั7ําR.๖�ฏ�๘ฏฬฮิๆmี� ฏ�ํึŽ๎”๏๕ง� •>ฬ›oฯแ>B๐ุ0เฤญโงnใ @ฬๆ� (`๘D€๘|฿๛พ�๛-ใ฿-๏Ÿฬ9ื�ฬ€ใิผ�ศ?ฮฮoำฬฺำ๏็0_�ศ|�ภฟ��฿�ฺ๓ลœู)pไ|�ฤ,�ไ๏�๊ฟ�์ฏฬ‹อ๛รlใ๑]�C�p}��๚ฟ�๛_ูํ�€ 8HXhxˆ˜จธศุ่๘)9IYiy‰™ฉนษู้๙ *:JZjzŠšชบสฺ๊๚ [ฺ�@[[+‹›ซปห�๋๛ ,ŒKหP\<œฌผฬ�์� [klห)  80}ศM@�-ž^HฮmŽ.~พ~๎ฮ^�พnฎŽ฿.�N๏žฟ๖ู๊#8_ยx๛twฐ 8}� ‚qศiผ)๓ัG‘฿,5ฅธ’+;ฒ$„ํัศu/อ�sS€m‰Hค@…Z„ ฤ่ Bˆ8`ภŽ5 ข`P!z๕zโ๋ืbม–uJ๖lุณ(ฮY[ฎXน_้še๋ึฎSฝo�ฆ-๛wฎ�ถj๓๚5\๘lเบˆหŽ๛ตวGธ62ŠYHA*2�‘ฌ(3f(‚#!คf‰!แtN N…ำ!Yัษ&ขQ !งS/JAd๊ิvทs�ž][Q€โ—6}j“y7้ัg7ไZHrJฎƒl„๊"Aœ๙VบwถFคจ)huHA)| BไัG'N ่‘ ƒDฐ^ #!@B”@He]แEกcƒ5&ึc‚U˜แ…2–˜…!v๘กW‚("d%:uข‰ฆHขŠ0‚6#6า_Ž๐C%๐ฃx‰”ใ ส๖ภ ๘ฝ4~X" ์ภ gN^™%’JfฉH ;R%—฿”‰%|Taešก‚�.‚&˜uช9ศ‚@ ๅw‘@เ•Ÿ @ง�A,ะภผเฅ K@ฤ@ฤf†เค"ี4@–~ pG ‚์`š8C0œ.:ศ`:"Š1n(ใฌ_ตศ"†ท๊zWญฒ�ฺ+ญถปkฌ.›+ฒDเบ์‹ณาXฃ"#X ฆข๒˜จขสๆย›`2ี ๎šฆ2๊ซDœ �ถpZๅž๔�Pˆน๔ฅk/ํค.ป้€ิ|—ฎ{ฏจ๙๎ OW�^๋�SVฒC @y'โe์บ*x›อูฐ`MแŠcŽ-๎' ฉ�`๚ค8ชฆJึงR ซฏว๊ผ—ณ�ภ๖ฌ,ณ| ํ๓ฮร& ใฯอ*หืะE#-ฌาMGญ–Bฒรแ1rหฅ�ฦ a,M|ฮ ื‘ ภU‘qV8E/ุคล๛ฝNฉ๖fh็M–Bถ ภ�kรฬH#ธฺ๔.8}k<ศ�ๆฝ3จŸ`v!de,$"d 2 ่6�ห๊F„!dc‡ฅScฆ]MงฦLB–xW5p‚?ฤ<aขาตฉฎุWะผอ๓าษOM<๓หฏ|ิฤNติะ;mผWะV}ˆซŽิ.ฎy%l๘Œ6AŠ~๋เ๏„T้ช ”Ž#�CœŸŸ๚Mษซฏื bA๘ำษไ—�ฟ๚}‰F๗›_� ช�ํN$”ฺ_ธ?:p Œ_UภAAภ๏#„W hนป}ƒ,s~าWฉ,มI! ยึ!๗‘fPภIฌR ูmฏW‰eจ็I–Pา9WๅLzศ;Z๑’fดb=xDใโำฎHE0*Y]ฤb๕จฝ1:kˆ�ป$tรA8`%(OฉQฤ<ๅnW)ู ศ‘&]', ‹>GHC†e9'ย�ๆว0ูํฉS$้>gI˜l“ "คร %Zค‚‡+d%;yษS’tูค*9ˆแ:•hRr4&v๎˜ฺมศ2„�1ฉ`}ฬ’”ˆเB�ภฑูR‚˜–9—„xk83ษ&!S6%ูส„ฬ(ฦ,ขฑŒa$ใอู<่ก3yไิขgลvข8ฺk#ฦฎV8!ฐ|™ฒ‰>ฉt‚Mๅm฿h’฿w1Jๅ8๖SUฆ:LJ9’ ฟูgC฿๖คXะก แ!๚ะิY3Y+G#pŽ๊+u อh๊zBŒ๊หฃ%ฌDๆ–0`A:%Ÿdธ‡Q%Xะ๘(ร €OฌRืA1g”ั+cฃ"7ˆAum™ุŸฤฆVแLdeฺแiฝ์ฑ๓zgeซYำ๙Vpjศช๖๔�"ฐสหำ��•จ6@ัฎNฒ‚l�ก™#บNAˆ[ �๊0ฆ`ฐŠ c79€แำ &b้5จ โ~\R๊�‚รฦVึnชM ึฆY„า’ถืYv™š1ฺ๊„@d0„฿ฝญ*ฃฺ,:"PžEฉŒMาlฉp(ภ็ฒAC่XŒˆ�n”œhEcwซจFธrทญโ}็vร๘�4z—j๖์ต!]D ่Z่€H|1ƒ0ส4ฟ]!JจMจุ+ภ�"๊~ุDˆ‰ฐะi„œ/‹‚ภ.‡g9C-กยI<&X‡ฯU฿ C'ยQ™ๅฅpซˆ›Šใ*~ยเ†y`ŠŠ�LLๆฬC,จ*ห๕T$๒วฯ€ง๊ชŠW฿–)’wญ^lฒ\�บล๑–ืแ•2“ญO๖ถทv hป‘ เ ฿w€ ะj2ศA]{฿Ilุ€ฺ`‰R\W‰@gฟํVอ’ฅ์๓lg,5 ฮ+ฯv-=›RศDฎๆ�u็$:ะช"4! �8@‹ว‡ AœปŸŽ1‚ำpž- ้A<€z @ธค6 2Yb๓!„ะCPชcวจj$fL&ฏœKฏภ†G( z‹Yo\ลาl๐:;ส่=ฬณำJmlW๛ฺยฦ]�8ญGw_ย๖š’cเ๊ะ�ภrd †Ÿึyๅu๓Šจหaฑ˜rึ Fฤ‚ื๑hง�[ื7!ะ-Ž|฿;๔| "ฐƒv(ผ?ธชฤQ๐{ห{ฑ่ภฌฑqห"t—ทญSTŽW๓ธณูAmVŸ†๋ตว Hท% €o`ไร๙–๔GL๑��๓๙%pŽโXย@“ภ9Dœ~‰_JOงบHP ๕zๅ\่Vื:D”>u๒‘๛ฉœ{7ภ๓ฅฃุ" z&-|๔ธห=CŸป�7œฉ[์wฬ^ $%šDฟปแฟ‰บ#~๑p@R’lฦรฤๅA๗ ~"”ๆJ~๓œบ–;๚ะož�ถ(ผ่O๚ิซ~๕ฌoฝ๋_๛ุห~๖ดฏฝํo๛�๋~๗ผ๏ฝ๏�เ ๘ฤ/พ๑�ไ+๙ฬoพ๓Ÿ�่K๚ิฏพ๕ฏ�์k๛�๏พ๗ฟ�๐‹�ไ/ฟ๙ฯ�๔ซ�์oฟ๛฿�๘ห�๔ฏฟ�๏��๋��๏ฟ��€(€H€h€ˆ€ จ€ ศ€ ่€(Hhˆจศ่‚!(‚#H‚%h‚'ˆ‚)จ‚+ศ‚-่‚/ƒ1(ƒ3Hƒ5hƒ7ˆƒ9จƒ;ศƒ=่ƒ?„A(„CH„Eh„Gˆ„Iจ„Kศ„M่„O…Q(…SH…0Uh…Wˆ…Yจ…[ศ…]่…_†a(†cH†eh†gˆ†iจ†kศ†m่†o‡q(‡V!๙!� ImageMagickgamma=0.454545,,‘ƒ(((777FFFVVVfffxxx‰‰‰›››ฃฃฃธธธสสสุุุ้้้๓๓๓�ศIซฝ8๋อป�`(ŽdiždPฌฤสขp,ฯtm฿xฎ ย6“@ฯฌ‹Aส1ฉd6%ศ%๔9ฝDฉiu‹tvณฦญ๘๙ํjหN/๓š�ช�bsš+xุ๏GCวWO!<"nD~(Šˆ B„”’˜}'– v C {uxw ฒณตv ทดทผตพฒภxยถฝบฤvศปวฬฦฮฟบนฯมอะำรีิืลึตฏœ:ฎ z ๆ฿พกv‚ Hฎ‰E ‚A vฌ ๘หS@j2#�!ศ\ƒฉCŸ@๐’ศ{I์ฆQ\ฌจBVpโๆe•‰_eไฑ9š(pถษ็}yคง›{„Iาzƒ๒™่›€ฦ9p{2 „š&L๚น่ฉก=Š–‹}๒๑ข€็Aฑค“M"yชชOJ้*•ฏ&ษjชSสZ+tV^)Cฉ์๔R_ีf*ส5ภ€˜ pคŽ[ �7jƒiดS>-เ;๕ไ€ต ฆ,rก V<L[ํตๆๆtํd<ึำ�น�›€9bžดSท้Z๛Vพ๋ึ.ถ๏ช�ํˆ*†ฐ�aช JŒร&7obึqŠ4—€@}5๒R–Dก๊๑ฌ฿ฺ*ฌ$�๋ช"ำz๒ศ&็ก๋ Yฎcโผฐถz เb๐œRแ‚๖ v0อ�ๆ"@Hณ– Dห1 Jถ 58า<-M F_=,]mt87€-๕Z์ึ@P-ภีlW=0,]อ“ึบ�[ฅP �„=6a{๛ำ;๖}"Jฒˆ๓ฃส%ฃผ2ใ-G๎xใ,O.yๅ�ทไ๚2 Šwเ“ิ๎"€ณธ6ๆQ„><๏dฌ*ค^฿;% ภีฑv๕ ์ฤ๋Q—›a่�ฎ�ิฎฮตnžพ‡ลy ๐‘,;๑?๛�{_jBดD+ผ“ย0™n •ศY‹จใz–ศaนๅ๐ป๒ใ๓S�พ�Fjพน 1o ฉฉ ๊าฆ|ำŠ๖เn0~๑ฯ๔ำกอๆๆ€ำม(P ž:5A D๐ิŸ)X(บ+6fŽ0„แ‰ส2a‰`hบร&ฐ›ยŒT— šPฑG9GB๑ปŸ๋wน%‚์‰)cbม#ย�€W`เ�ˆ๊ต %˜มRำ บ่|C  &5ถ‘Dธ#c4จrQภltใ`ฬ—….่‘Dฦ ใ7ุแ~เ1DP�ศGพmm‡pd้€† tPCฏ0ภเŸี,Zุฃ†2E(าฯ”๖“"�ขˆส&ชา‰wจขCะ? lหd)ภั\w"GMM.๘bษ%ž8 ŒจPาำ*‡ฮtT'@Gล'9š๑e3ณ๙+_B“›ศ‚ษหั๔ฅp�|ๆ๙ฐฉNjoัไG v‚€e!X๋Hf=kณ›…‚%๔$ง˜ฺแ›"0ไไเ#ว–r ฎเมก`i(C�kัWUtGอ(E'บ่\๔ฃ}hH#:jดฃ'อ฿,w%หษ<‹1™E๐Ih˜0ๅ ิฎ‰‡๙ไษB;L‚ำา‘Žfไ#hPj‡ ๚๋0L%j‰’vภbจKjmhšท‘ไฐง๗t13ะฐๆ4F\๊M?AI˜rn+ซ\็JW๔่โˆuEOม&1]a‡\;*!นฎนมฐ'0E%Tฤ5+ถญ@ฌ${ศ*แฑo%B9gˆ 6ฏ  ญhG;Yท˜ึด-%ญjCK †(vตเภr �ฺฺ๖ถธอญnwkฃF๘6ณผ%f๖�โ๗ธศMฎr—ห�D!๙!� ImageMagickgamma=0.454545, ,šƒ(((777FFFVVVfffwww‰‰‰šššฃฃฃธธธสสสุุุ้้้๓๓๓�ศIซฝ8๋อป�`(ŽdižจDแฒฏฮtm฿xฎ๏| pU‚$ัขLŸN(Eูl.ฏQ€ซๅfซL๎ถ+อšษ^jX ^›ี—6+งKผ~Ÿ่ีŠ ?c~ZC€LF&SА‘”ˆG—˜›„† z•  จx{zขทyนบผทพ{ภธบปฤยลฤศวฦหฮอะสัฝำฟีมืรา�ิ�ึ�บ}ž(ณผคต ฑ ๏๏ J —Hฆ์Z ๒ฌ#๐มภy๕& ภท!เชUA<Pเ? -R(ะ@ฯ€C�ูe4x1NศRงN๔ฃHA฿G็&xp`@@#ไaว`‚4'ซ‘lษบ)�ถ8mMก2๊4jRชRซbฝชตkึฏ\ม2{ถฌใศํ0ณๆMY:aup— n‚[IะIiM 3wRx€ ๒~€๗^|7(``ฐaF๎4ม๒fWp€sbว‹3ำL�ฆ*ฤห-1Kpy^jhkถ(ะฑzฮŒเ<ใ๔š”ปƒtฌU็[ก{5๛ŒฌtฑีŸgพ}๚u๊อปcož‡hZหa>๒*๘‚แsT~ ภ+ุVMh๐~6<โ�ิ€งกP}๗™ภ”U๒@€�แ‚rA …โธ3ˆ~A8เ„ก5…ƒŠศ|%็_ญˆ(์อvภHดธ็XqขศCมkIhxเ �‘F&ฉ’K*ษ“O:ฉ‹ˆ็กไ3กลภ]๘Uา=อท�๎ZK บX๛์’ปํฟH{‚ม 6์J ่&ยิตe#yิญEฒŠ๋ช ำส1ฌตv๒ว"{lVyผZiŽ@” ผ๗@ฤ๓พ๒“" `ญฟ‰"@ะ๋]:๔ฟ87ภ€ฮ๘a`'ฟ})™dญ„}tl5paต�[#ีB @ฯVื’๕ฟe<๑ย!Pฌtž_ZpฉAŠ�”ภL>์ข_ฉฃˆฦฬ,ซแ%“Œ๘โ*+�๘แ“Gcห#ฮ��|G"sข‚๓Oซฬdฤ  �ำ+ž�{๚_ื~+M3<ฎซ{NหฅจSAํๆษฅ)�]๊ภทำๆ~ฎqฌป}๎�ๆw� L*A็ŒะTภ†ุ>˜นก6y*.๖4<มUKโŸlrส๊;�~๚์ว๒�๋‹ล2ๅ!๘šAq fI๔ภดp—<@tp�"ชu๚q`ƒ�ฑ ฮฏจำ•ต(PP‚ `@Aส๘ฅ>g๛ืbD๓#ˆ…pOœ�;(B ฐ+ึ-$v๚x-ค“ภ1( ณYง^sTP๕>๔9‘qM„ข�๊GE๗MัŠ๖ซ��< ฟ–|(ภๆดฐ!UpA๕@เ™„ลภ}คCpc#D@4x๘ไG9ยฑ�หอ๛ภฟฮษ‡YภK�!FšG[lิ฿V’Dฯ8OhๆHฅ!.kธ:Z๐ฐ@Bค่‰&อWธศI‘~Xฌ"�`9KY>ั•ำีA`9L@Šก,)itส�๘G"@t‚hษ(ี*]๕Lใผๆ%‡IๆŸฮ๘LMฦูผfญนอ�ฌ(œๅผ๐“zู'‘ใ,€ส™อyfjœ�@gฆ†Iอ‰J�,ๆ^มรŽˆ„Yภฅ+โโรq๎2๚‰ใลแ~คโผา–ฅFkนั[F—%†yvฉฉ f`™z@ก;ธLฎK๐Q ด้ Š@DฅSƒศิ<Zไ"ด(ฆ0่Š…ิฮเb ˆd‘@ำำขฬฅR5ศcV๚ภ–Ž”X86P††๑ภไฐ'่‘๔ญpซ\}` ]ฮm�Z4ฦq4ฌฺบยž@ศซ {ฟ�ตฐk `d "8–ฑtu็�บืปz๖ณ  - เ€าคดจ�•hWWQ<„ุcํlŠฟ!๙!� ImageMagickgamma=0.454545,ึ<„(((777GGGWWWhhhwww‰‰‰šššฆฆฆทททมบบศศศุุุเ��็็็๕๕๕�เยlDMขal&C;|€6‚jำ…l‡ZhฮาำXesฤภiฺระฟ˜4@�1–๗BฝDv๏\๔J�Hk|0้ฆฬPก็mฝัˆํซ๕ชมล%ณ%šฦฝP๓/ั(ะžSŸ�ตS7HM�”T"š#`f™`! ŽตฮeFิBWตใ^6฿…Xล(Dกไ‰รh7ˆํ‘่‰v"šB|‰ูTT็}ึ฿zFxิ9ฑ…ฮ7อUจ™ลมยD\cY๔ €่ๅBฏุuQ†%@ิ/\โcW๒"Q/Iๅ‘h‘0Iฅ„$œX`ŒpFก"!$r”ษ=:ฤ>,ฦฉว4ฌTSะ5›จV“ู่FูXเ่ฐู€†ชˆFGงžsึ‡ …›jๆภƒฅ&!…ญm*ฺ'W๖7ูNถฤๅU/๙)+xฎฤ‚=๒s๋|x7+ B�4ื\z่'Š~jูj5ŠรฃฺUVD�Žต,f�จ Zkณ ๗) สถฅแจ&ปPท}cœซฟ,wค†�*/ญษ ”'K๒ผ Jพ๓๎‘ ตฒ“ฑGถ๋fXห~bW ะ6‰lL<ตPnฝM™”,Uมš%]‘๕_ต2๕)[ŸŠpen<‘๖ZG�๏หC๐ำง sฮœ‚ฬ0�Y }ƒ„wใ Q:ั0%_kฮH'ญt €4m‚"ลi4gณ$ฺ๕ๆา\wํuWq๏),†๒๕ูhงญ๖ฺlทํ๖�pว}Eaต๎S๗žw฿M7ฏy๏ซ7ž…นXซเ€ x�„๋ฝwLv฿“x1‹?~๘฿}Wฮธๅƒ#n8ๆœำ‰x็�Š๚่žS>ใ‘ง๎8เš[�x้งCz�’ณ>{฿ฏ7;ชำพ9!/�๐ฤo�๑ศ'ฏ�๒ฬ7๏�๓ะG/�๔ิWo�๕ุgฏ�๖�w๏�๗เ‡/�๘ไ—o�๙่งฏ�๚์ท๏�๛๐ว/��๔ืo��๘็ฏ���๗๏�� JHภ๐€L ศ@่ ž"€พภ|ภ๖@€เ‚ฺณ`GHยš๐„(Œ�…g&, �@ˆ€Dฐ|@ภ๖ `j/0Lก‡Hฤ"7|•xo‰4ดก๙rุฝ๚0{T<ขทศล.z‘z+�@(&ฝ yP^ A3ฯฦƒใ๓ pEศัyg$ž฿˜G่eqyw�ข IศB0Œ‰เa‘'€ ‡ ^ ะG@` €Cภษ3ึ๐KK๐™ฬะŽed˜W€^๘”%0e๐A<เŒ @สจqยƒฅoN<๋ฤ2‰ญ์a๒GF ธ% /iศjZ๓šุ2MฐศใMPpH๐Gs@P3ฌ! ษ2ม`์่:ถSy€ uจ€wฦ3๓” Q€@6P๐วเฝณLะ 5ใ—=๒ะ๛ฌc�๑&ธŠ8ไข๐ฬ™อ’š๔ค(=^Pำ€yไคf <‡œ‘œ+ $ํฬฬำŠ้ ื่ห4x 5ž ๒Hว ๎ฑ†พL@&Drš?&P…'ิเAีŽฑ๑ไG‘วคJœi๐›F`ก)ซ\็๊EธR5๕&0%ผ๊0!}LcOฏHลเuค gชQโ‘3‰"5l^yqN<`’ึQฌ๐ ฬ‰N6ฑ!อฉปŠิฦo‚IไซS�JIบบ๖ตฐEแJ@NšVx-M ึQฐ^fa๋ะฤ~rณท O Tรพด`ฉf�ภรๆะฒW<ฎ๐$;า่ๆsž@ญt™+RFพ5ธป@,|�๖บ๗ฝ ใ'8มลo‚ง4,1yH‚ผ*ฑญฟฤฎt‡สื†ัฌร#ญCtHZข†ท0ชตหุแ5”‡9ๅ+†k:ฺ= Hฃ/}p~#ฐ_&†พ(NฑŠ�—a,ฑ��( ฐD'ฯ…ฤหgd˜Nแ๚0ภ&ฏ‹�ไฉ3%€˜05yT†๘ฃD.mOฉ �BภƒCž Fำ1aA นก…จr}iฌโQhลhNณšว7@h‚ฅสz•P7๕[o—!PM1c้ืแ‘ สไDH7๓Iฬ5{๚ำ v\ƒGฦๅแด›#ต๑€๊ใเฤา{ตซaฝAXหzีฎ๖on[ญ�C‡๚ืภถ‘™‡฿โ €ษp^qn‹วษ! ๛ูะŽ6#ฏ\ผMŒZลล& š)ํn{๛�งฅ๕ฏ np›๛�่Nทบือ๎�เ�๐†wป็M๏zฑำยรทฝ๗=ฦ›ื�x๘๔อา่ฝบีไN�Aƒi๋8ช๑๗* ™ื๊E<โฆ๒.�อŽkในร?Nržขฺใ%็้ฤW๒‘ท\ไgyษ-๎ผป–€เ๋ปu๓c๊  ็€\๘ฦiญ�s๊ัHฏcั�ผฅใถ�ธŽ๚ฮก.?งW็O:าpFœ#d+mฉ 48sฌ‡U>@tƒซ;งภํ(€๛ ไŽHผ}t?�ํฮw�] ‹๛FL๗Hธ�y๗{�ก6๗พื�๑@�{�WP-วH>"„ง<�_กˆยg$o� ฎฝ>[:ฯํI<‘=ผžo[h0*}ฌฃ™G`ฮย„@•…)K(@šมณ%ีcO~F๗ม<~ฒใจ�แ‰ฝ@Wc๓ฝ:}#W?ผY>๔lŸKใู2๚าx=๛ šdโž$ภลa\๕ลห็„�[ๅŽ%ƒ0�–ศ๊�หOํธฅy—5%`gฒxก๗x—•'่x จw“7 ŠwโxŸท€xO#z่๘€X ˜‚(จ๐w>ศ<†5B}6ˆเg €eม'๖XมsŠg๕O $NP=˜gbTษ#ลฃ„L„6„„สs„Uh ภƒYx…[โ„…Q๘VdH„>U=hุd }หC…๕็ƒOxAšJ0aˆุ<ˆvณ”^ฬร �ิ,๖…ฉ&< ๑]D ๖`ฮHEฦ(]ศx‰O9ิOญ5P pqุ๊Y`ีb๏ศSไ”vGลCwศ]L้D�ŸqFEฉ9i}ฎ@Lฟเฉ<หMดTS๋ฤPLL๛Hด‡… =ี"{“6แ$E€hAG8๘k๗`ฑ้™ตX“x‘/Iyซ)’,*›ฉ€‚‹ดษšY™ฃธˆ—h›ศˆ.๊’ฐ“9ฃฟ ค8ฺŸ๐๓ฮำก/ๅŒ —O๒๙aภ ัถ…Œ“k*IฆคSmIฐSฒฑ_:|] Meฺ[;% ะkบŸแg;ฅฆgšOก@ขภ$ก”œ}Šงvjง~ชง™4<‡*v ฺ=cŠJNฤC๕ุงtฺVkม o๊dฑtb๕�bฮ–oึ‡ฮณD จ๏ yDYม“i†๒RiTšI’˜Šฌ˜ฃgคOำ‰xš"™wพน™49ค|2 ฃŒˆyฉy)’‘‡›4jฯJฌ (ฌ2)ญrญถœ่3œศฃชฌZgdY =IY /ึ๙B ู†ึIbRคKฤCคkQc^ฺลS•‡Hฏ”�…ฏ š<๗Zฏ@yไแตDlX{ฐ ;ฐzZ<{ฐยSฉิSย# |ฑDšuซฏ์ ๎Z๗G„ภ7–ณEเยuƒ9i๏‡Gc1i vณ�8Rํ CNุ‹คฦญBKนบญŽWฌฎุ‘-šy� yณ๘4€๐ด‹Gด.ส™5บฃ “อ:ค—ุด™HดฟชyM;xŽธž๒#ฎqคณ๙ิX$Œฦฆณ�%† @UภC tวSฉ†u‡ฅ•Y2K‰๕B™ถOpj•�ทUfˆ‹<๙คธ}เT}ท�ิpถท6๖ธ{hK`—n๙ธ’z=•๊+เgน€+ทƒkทbิ—[Sq๊Uถไจ |Hฬ#h›UTฑXCุ[�ึœC˜ข54ถผบฌBš™(ตI๛ขT‹ฌ�บ‚่’อฺผ!จฌธ*z_ ฐศžฝL:’า[“N๓x�หดุ;z๒czห๓ ๅถซฅFงธ�)†4E~๏*�ป๊T˜ๆ†ไ˜id'R/$†๕+žŽๅ†๋ศฟci_w„ภ๋ธFช]๙F!ลภ"Eม๖ฅrฑชฟๅีW๚sฯใฑลŒ2gมr ภฌปตa๖หz1Hปi˜`๕$ฒ�ˆ„*Eห๖ " A)ชˆนŠฺ‚8ผ7š™ฤ{ซ'ฉผ ่�:’ฬkฤฮšฝCŒœ')ี‘?๊ญผษ™�ปตV�ŠM๚ฤ6jwXk0ฬfญG‚๐AtiG Ph�%OŽšC7A๋Z �น FfเAผวศewXk1<�uใ้•‚L\Lะศ�fkiAƒ�_6�ยฮwfŒ\ศ๕ศœ�<<’,<ษ}ๅว€ฬv7‰ก9๔nิ —กLศƒ�ฟ„I‡^ชvxŠJ|,<ฉ4ร‰ฉกฑหJ“|„็ฑšuฅlฦNผฬป*‚Gสซะ\ฤอŒฌิฬฬฅฉฬำlอ?Zอู�อือ��อา,ฮศ ฎ.˜ฦฦSiโU‘ะ{บ์คC 5e_๏สฦs6ฝ@L๚l+$ห๖7|‹�ฯ7‡[OW$ะiะ U ์ซ\ เIL๛ฌm๐Lะ�ฦ[' jkดมษsqR1–ะjTั%œo๚”หด๖&)L˜ฟLqวk™4JบดL“*pkฆˆๆl>บs3ํXG@Wำห3ิcัcิ$tิใฐ๗ลิธฅ}<๗ิ๗๕A5wำ„ีjTิZ H็š=SฝQP =HํMฌfช“ำ:ฝึ57#ิฦึเhลWM:uห)„ๆg ื|�ืฮ‡ „tึDh9�@Z'ุ!๙!� ImageMagickgamma=0.454545,,‘ƒ(((777EEEWWWdddwwwŠŠŠ›››ฃฃฃธธธษษษุุุ้้้๓๓๓�ศIซฝ8๋อป�`(ŽdižhŠlAj,ฯtm฿xร6ภžX!ฦห9Y2Ÿ”eฒฉŒZƒ˜ใ๔*Rฟ^,ุ —ลฮฎ๙ผึ‚‹W6PwWล‚‡^oะ {BC„"8(AAพ ๛BMXเ`ี* "TศpCฦ…�ˆฉ.รวzM84ฉ2ฅFQBtฐ'�’#%xp`@AB  x @ƒ8hฒmœำd� Š“ZŽ๊SgMญjล•๋TฏUม^…๖•lXณcŸฉอ*๖:J=์์๙S'OŸD7$(  €ƒฅ๗ฬM ‰iOปzVR<@`�ก‚Œ>Gxร 7ฮธงd ‹7R@š๔_ห๐`p0๗`€ เภ8H`„ฺ๔ฦ€๘! ,ฐo๘ๅึlh �€ แฦ%U’-ุ…คxBjW$wD&9ไ’F*ู$“H๔ขณศE!้มU`Š !๑เK%tฤ„a=jห+ะฒำšzะข cn ‚ฒ<ะ›nฎ็W›ฬCส› –4~dก|jนgœ4เภ ~Bส(ค#ภ@ิีAˆNดะ{ซไ€์รœ“Q>้jซฐ~วชฌPา๚ชญฑFงซuอ)ดว”:จ๊ฉลบPฑ$@Q€�เวำ ฬfช ๒7TF-PืfKั=ัญ‚™แ)?ุ๕mท๊&Miฒซํ˜BJ�,%๏บ๑y๋.ัฦ�oป�ฌํฟ"ฦbม๎œง'พ0 ฬษฝUJไญปŽว๋ฌ‰๋ศ!ƒ�qญ%ฃ|2วh›Cฦ/T‰/HtEฎๆฏ ลz›l:P.bึLtp@็’ะฮ=“[ƒ˜€)HMด5K]หJWMo‹‡E^€0‡ตJK ดึsM๏ูjำK5ั%mมNr๐Jร'ฐ_อhธEŒ‹„ศ)ณ์๑โˆฏœซใ$Cž๘ใŒ›ผห�8ภผมP~ห|ฎ„�E.},ภP๚qf฿ุ�๙�ผ*฿š๎O๊ขC ‡๑ ๛ท ๕ปปF™[๕_โ๎>|มหฯ;ํ๚>{��Iฐ_�Tล๎$bŠ พ,๎nLyใ•ซœพโ่ทoน๛๊รฯGy:!œล๔ฐ_<:ๆฟ�1Bส`s์็๘ม€๋ด(€๕I{ผ๙p@ห˜KKPว—vาภ/e`'”€ีDอ0`%DะขAC�M*|` Mฐ@lŠZสฝV7`œซf8Xร`fพศญ๏|๏Kb�”ศ>&"q‰Pย� ง ‰ศ‡†น"�ืะ ™\จเŠศŸ๖`@f€‡พˆ0:ํ6.L#๕ะลAtฤ#‡hฬc€cฮาจ!์ƒฬฃ5v/(,R.ฌP \xฃƒTํ01BEŠฦจ“ัŠMๅCIสQšาˆ๒;%y่ง9“d—Dด`i พE ! xม$ีƒRเ€7ฺb๋Q �‡Gฐi2uผUPwฒภ< ฬcRK๗บฅฑฎ๙0ๆ๏๘ฃ5ซ €i’S„ี3'6วนฮ ภซ &  1เ๘์Iคชฐoถ่“๘[ ‚T!๓๎์เEBฯฒะ[4tีCDๆซ3ั‰>ฃขสภ(u4ZŽ๊ยฃc้sD*ัŒ6วขบข Z™?้แ›.uภŽฐZด=๚โ่Nฬใ2Š”šญ๙5๓—oœศ‘Pิ กฉ/ช)Q‡:a๖‘๊TUNmีฉLฅ๊Ss&]`FGบภผZU% –-๊RFฟบฺ๕ฎxอ+�ฬงา€ฎn…k�บ A4ฐ๐lค�๊„ฟข@w`l†~๐‡ H๖—ฅ@fkูX`ณA[ ซืาš๖ดจM-^+๙dฉ๖ตฆ=Eไ [เlฅ!๙!� ImageMagickgamma=0.454545, ,‡ƒ(((777FFFWWWeeevvvŠŠŠ›››ฃฃฃทททสสสุุุ๊๊๊๓๓๓�ศIซฝ8๋อป�`(Ždižhชฎl๋พp,ฯค C0wฅK? ะŠฦเy46‰;J‘๙LBี!ru./\lU)�v}็,ušถJัู8ู+ Ž|AฦูR#9}D=&ŒŒR‰ ‡'“‘•;-„    งw ถ  ทท บถผฝฟฝยบฤทนภฦพภมฬส ฯอษฮิภศรีุำ�ฝืลู฿�แฺไใๆวเปท{1ฒž ขค‚ถ A๒*เ๛Aส”” ฐ;‚ป~�fXเ@ƒ:4t‹aย…�4~œเ ษ’ 6ˆtธc#H +ถLุq={ุโxคd%ศ๗jBƒะ …)ค[&N]UชๅฌfลzŽซึฎะฆ†ฝ:vkYฐาฬฆEญญุต_ใzๅ๚ฒิB€,P5'@@็)„ฌ$ไำ4เม lีD8Xgฤ…BLR้† ,P.์เฒใTฅ?Ÿถ,!‚ื ๒จ6ูteฯ(ฃ6M›๕ˆฟE'$( ่ฌšc=`w42ฌผ{Hเ๏้, ติบ% w๎Yน฿ฝwO~ผ๙ํฺ฿ขgซพ=๗๕เฯƒซหยไ๖'nพ<„+V:-�ะ (š0ะ�แํฃ  2๘€€ธ‚�Dกอ๓ภ‚>(แ>o ฒ!„€จก‰xุแˆย‹+rX" �ั@.ไ2+ ๊ะ;yW./�๕โ{๎ฅ‡ไ’J6ษ“O:|โQYž•๒1)S;}iภu#Dcq€ะ ้๐ $ฮEAๆศbaJq†Š„žญ๙Y†p5ง_~ฦCN8แgg—9Ug๛ิ๙งฃ‚N@hŸr ้ƒ๐&&ฺC.J@@p ^๖]”ฌN™dซUพ๊*”ณJ+ญทฺzฅฌถ4Š*คชrŸNHมจภ^ิc �~r@^Ÿ$ย” ;ARเภ€-S�>ภ`>B†r!  ๔@ถG!ไํบฺr &๙,”ิR�vKA.8ั‚|�ฎธ‡KAฝืย�๎,ป[‚ต๛Rิ€ wฌ‚ Ÿ@|D 0เ#�yฏปโZฒฎYขŒๅส$ง ๋ษ/ป\+ซษข ฒY ฦ›v€�‚ ๖ร€+๗ —Zฃvคใ—เธดRผ�ภะ%ž{AบDKำโj]/AฒฏธL๋ธฃc0šวณDอ ื7’ญ”ูุีคใ�`k ตธ%๔ !E,’ึ@GKชไณํั~น๊ฬ็3ห&ห,yไ�0cnyๆ—wฮ9ฬ5Ÿpณ™ ^๘I{ะA'ล_1‹4ฉIน๒Xl๏ฺ.!ƒ ธพŠี๔ฃฎ๎๎ึŽถร;˜ฺbฌถlK |�Kw�ผL฿ญ๖ุ‡๐#ผ$ถรŒ"ึภEะ œ}=๎๙ๆ๐Sฎrห๒ON��•ืฏ๙zก› ฌyA‘฿20*jQ` hŒt"ำaเ{สy@†:… J ST ธง T0*Œิิ†ตณ ๖ลPจ๛B&B:•สภM(LลฉK๙(eธšศB`Ed—*๗}.~๘›_�’hฟ%:Q‰Plโฏd๐?Ÿ.‡.2!�ุฌpฐMภขังŒQS#โb)ผผ `MDษiฬ>ฮXฦดQ€Ž,€-@ธ ูf๓่<ฮQช"คุ>0@ํร@d๘ด—ค  งธ€Fฟ๔%/O”ข(๗วDR†า”QDๅ(%ืฟŒ.”คEตˆa’Ÿ่H^Vqเ0ฌc ธยXหKยB'HEr๔ธen&˜m< ฦrาฬI13™ึผเแ้L’„ŠŸ 7ญ‰Ld†�ฌๆ2วนฬžฌ•ดๅ ยc‚๘(0")]„FˆkภวฌC fx#>ตEBqaะท,tCmจ5�$ช–‡>4ฅจ..ชQtp'ฃ iE;สJ*"*๚œPtr Œ!L*บุ'ภ@ฆ] ฅ/dJBฤงS<$fฆ‰ๆ�H‹”๒TŸAฌภ'@าำค’ฤ€(2‚ิฃฺB|Š้ฯชบีV (สKmPŽq๖์@จ@‹2ัเญpซ\็JืธšUซ0€[˜ึK๔K๘ซ๔สยž€จ๓pซa} XU๕ี(Dฺ$k‰ด=ถญLศ‹์pฬบz๖ณ  ญhG๛‚Uต’ดจB,2อิ~6GŒsญlgK�ฺฺถฎฆฝญn_ฐˆ0"zป…k*๖�โ๗ธศMmn“ห�ๆ:!๙!� ImageMagickgamma=0.454545,,ƒ(((666FFFWWWdddwwwŠŠŠ›››ฃฃฃทททษษษุุุ้้้๓๓๓�ศIซฝ8๋อป�`(ŽdižhชbAแบม*ฯtm฿x� ‚6ฤ’ภภ NŠE0yฌ ‰Mฃ::ญี์ีสฬ2ฟXฐTปผˆตใ'บš์z)jjZ~žc฿cถyK<B <)‡#?=DŽ&“p— )›š˜G :C C ƒ ~ชบ บบ ฝชผภยภลฝวปรฟรษมหฯาฤัึฮืภอฦูศ�สร��ุไ�ๅใๆ้่ฝโเ๊๎ถฉ  ��๒> ๅ“  A+$pDภ>SAr@+b  I0ร� B2ˆ@โŒGLRdคฒ"€~๘๘m(9๑Ÿ’–,'บค๙วๆ‡('์๋ืภ็ŽH(ฒภ€=,@๐@@€Jk98๒ ฺ9x`ฝพป.์ดฎgฟ’5[Mmฺฑoหฎ—-ตปh�ยี+ท.]พ`u8ฐ•>๘€๐Kภ8D3‡™ Q0 Pp@•ฯ0จ*Ab่T=LOธผม•ำP—ึ<`ดจ  E“  wo…=ํภQn�ญi#ง์ 4ƒโ$r๙kใว {ƒษG๐ ว$๔$ไฺ‹ื-เฟํู็฿๗ฝ฿๛๖๓ำท;ฟฟ๛�๐๙�'฿W‚q�™าู? ,0ฯ*œ•Gูฦ(฿M •ณเยฬlเGV…(Q…ฒ์ๆั-dFโ!Ž8[VXศ8aˆเธขˆ�ศ/*ec‰$4ุu (@‚,dถๅ‘ว‹QฎW€๘qฉŸ€[‚ษ฿bHๆ™ฆ&škพS ‚,nฐะฒ8๙R…�B'1>ƒ0˜ฐ’™นดค…'phŠท˜๔็…(ภ@ "zหขQ0D‹^dมwnbง‰F ‡‰j่ง2UjซžŽCกš.เ ภT10eH&ูIBฒ9ฆšวถฉlฒฬ�š‰ฌณหB�l—eRkฌ*&y๖ฑ๎๖K…ฉœ”ภญตxK!฿i>*^%์ดJ@UW-๐๓ึ{๏>๊ฒ{ฎ [•พ[ๅ+ีฝซI(ฏŸ๚> ะช€p๘2|pม��K WL๏ลls,.นPต‡�  šจ <7ษcYV๛ๅตึ>›sด;O{ณฮ?๓ดฯ^-ๆ›่รI�’PะI(RำภMบ@ฏฒPษBขl/ผ๗Kz๒"/%q ฃŠ<žฟฌํ'ูu/T„ิ‘ญ@qd๏‰ใ;€@ tWลvฺf๛‰K฿�-€�‰�=r‡�Dxษ!Cฅลi๕A21.€m4ฮCK๋zฯฏท๛์ฒืพบ๊6๏‡tงw@€DEIeม/Sf@\๐.U๎&ๅ$ปD•,›�;ฝfฬQถ<> p๘๏’Vp}๕SŸ=๏ๅaฐOใฒแฅO~ลๆฏม๘ูใoฟ๑�ขษ๐ค' 4จ9@ gโค%ขๅ๎ฌปะ$่ภBwฬ *v‡ฅy`]ธ#t9ๆ๐žใTฬุค3ฉ’Igฺ'“ญeF3*ิภ>(ˆIUGQฑ’Ifศ"!‘:บaอz(�กˆ,ด กD|41Š!��๐.่0ํC‹&ฆฃA4 x5ำเ/ธF5Vƒplc฿(วฒ%iX์u–#8๋P[ฃŒATศก=N z๐ +JxCV|Hy‚l�ฒลFภG–๔ZคศKIŒ(ภh` Kส(“Ÿฬ*•ฒส>`gˆ e7I#ฮอp3œˆุ Bึ‚ฉซ#‡; “ฤค1•‰ฬc๊‚ƒ๐`ข$€ฮTจ$Qฤ4„9จ  š็าผทฎ.J€’€Q*2งlส€ๅฉ „ ™นIพฦ‡šŠ็sLัฮฺlณ‰�D—>!ิDW๖Œช!๋งLฏ™ศI9ฐ˜YMs&QkEเ ˜H�œpภA4ะ0k*๐เU,ฐ) @ƒฤ‘๋๘/ไ@ส—-Sฤศd็สŸ3‡�์น4hำขQ“>อ:u๋ีฎcรžPsํัทU?)Ar‡พ)&,a8b'๘�5เม�~ฟ w~ธ0uณข q“ฐ<- ฦญ &ฎ!ผ่ั;p๖๚qไ๎‹N0�Q#€KŸ €€๋q�0U& ŠY�9v�Wคsอ=๗�{p-`ภ~”|#5ว4๐@"€P$ฑ'A9ถไ"fดฝุ"ŒนฝVฃl7ฦHฃŒธ๑จ›6‰ฃ:ฮhd;ผ…๓  Xˆก†ลํ–แ‚฿�Dณ W)v!8อU)%”^™%…,๐dZูฆ”ฌHๅysVPN’ผ9’žxศ)ๆžuZ9B“_bŽ]4 �Xเอ‚2f—ฅ`pแ&`x€tŽณฉ3–(b:OEv•ˆG�ธใชฉษjฏชฺ๊ฑบ:k‘ฐ�šใฎI@Ihั8Ÿ:ฺT8œk๖�ิRhร๒•์Wศ‚ชl4ฬjนALl*JงีKํzแ.ธpYL# ฎปว&zŸดึR ๏kž@ด8ถไŠ-บWณ8 <›กYาไ+ญ™‚cSŽ-อฏ7เ€ล ื€=w{‹น–,ซษถขLซฎD๒Z๋ส*ใz๒ฬ)ำ ณnI๚ๆAฤ$eฌุลWผ{ฬ8Wฐ^ญ82<฿ๅ3วS�3{\:'"า�U๔ฦ@?=4z•ตะSŽน[ุTWะ?wฬถล*J5bฯRC�๖ื%4=C7€6z}•@a~ 1ึŒฒ ็E�+lชฟ0�”Ž�๏Žๆˆสnfม‚ถฮจฦ์2ห/ห\๓๊7ณฎz๋ฐฟ.๛้ฆทl;9ว�Asbgž€˜w�N—ฟ@L�์Fกค่ํ;๐™G฿yวว7ภ€7ฬg f›oน๐ˆeNŽNพ‡_v–พฎH—†Wฎ9๔เo~่tจ๗๎_พy ผW ~ู ะ ฝฅzืS^ข๓•]\ฮq:ฉภ…v‘)ฑูฤฯษ�&พ}5ehญ–œPGยฺฅŽv6›�ํJ˜Bบฮ…ฑƒก iไ+u@oฬ {r่พใูD”@„.ะ?งa>;โล›Xฯ๒9ฯ’xจ€Žˆƒ็ปภ�GาAว8Lj QฯŽXล$bQTt�Ÿsฑผaศ ๏ุNามฦ&~%yUภ๚‚"ฆ™b$$ืงI� ึฉ๊I4 �,kZ jVฒฒ5ก|YจขjPต‘#โ*^ฏŠไุt‚ป]งZีผ๖Uซ†ืD'ะห4�ฑ|อ๊V+7L6ซkิ^สจฝ๊ฒŸญlY‹ŸหšKcsใภ`ํ๊Œ(€จ ,\�ธ€ซภ/ูYšฑx=qo ณ๛0›ศQ—"—:ึ�ค hˆญน๗lไšะ€GR ””\‡[ใ๑‘NdW฿mYxปป~wผถA/Gtฅ^HdปT"/mr&ื ฮฬ œž{฿R-6K`้lฯa’ๆฆธ+๑ฏMลYžวBWŽ›�$ ] l`ภ๔ห_sHxถ๎/ใVr�‚m“I๊‡=ฯ๒aฟ<—๛-ฮ_0€ฟ†5โ9็ ถจ_€œ๚IแศHNฒ’W`d9ศDึqG๐d;E™�๛1$ช์žf่ส$เ๒๘  -C™ฬF3ฆ�/ž€อ$€sžsไ.๙ฮxฮณž๗ฌgh eˆโ๓ˆ๗�[AkME‹ขกอ่F;๚ั"(2b้d#›†~E,ฺW้N{๚ำ ตจG}‚˜๚ิง&ตชWอ๊Vป๚ี0๘p7`M๋Z�๚ึธตฌ•๋^๛๚ืภ๖ ส่YปTุศNถฒ—อ์�˜ๅฟุ๕ฎ›Mํj[๛ฺvb@[ic๛�เทธกPbsภ�ใNทบือnTืลๆ๕ฑ�M๏z�๛�xิ^0ผY|๛๛฿g7gcส๏y�เOธฒYไ/ฃ฿ ธฤ'k�-โ�ฆธฦ7ฮ๑Gkก(6ฦ;N๒’›< ัถร๑“ป�ๅ0BLŒ‰i  ;ๆ8ฯนฮiPŽ'||็@บะGoyท|่HOบาGp๓ฅ;�้P๏ชQ๕ช[}ใ!๙2, ม†ฎฎฎฏฏฏฐฐฐฑฑฑฒฒฒณณณดดดตตตถถถทททธธธนนนบบบปปปผผผฝฝฝฟฟฟภภภมมมยยยรรรฤฤฤลลลฦฦฦวววสสสหหหฬฬฬอออฮฮฮฯฯฯะะะัััาาาำำำิิิีีีึึึืืืฺฺฺุุุููู������������฿฿฿เเเแแแโโโใใใไไไๅๅๅๆๆๆ็็็่่่้้้๊๊๊๋๋๋์์์ํํํ๎๎๎๏๏๏๐๐๐๑๑๑๒๒๒๓๓๓๔๔๔๕๕๕�€&!!'0C‡‡DŠ‹ˆ0'&,BBC‹–Їނ…ˆ‰—Ÿ กขฃคฅฆงจฉชซฌญฎฏ–0!!†ทžDˆŸนฐญปฟพพ,ฤ,”ฝ˜>&'ฦล&”ขB&ลอวภยฺู����฿ซ0ฮ,ิ03ๆ็00ศ‹>˜–ษเก„ญ>๒๓ ฤอฤะ•ŸฆGNHจi�๚๙จฏกร‡#ย’5kPE‹‚Bฐ๐4€ญN๗2iเ/Ÿฐ&zฉฌt‹ภŒN-˜9ำŒPโฌัดฦงณฦ ลJดจัn,BtXสด)ำ›บx‰lˆ๏†ฐ0ภืท!†d$–aฅชฉštธณŸ‰P�ิj5–lต s฿�หทฏ_F,œ.U:xiOF:ะภวŒล0˜@นPƒDโƒภ ซ6‚VทW x>คฃe ™ จ๎ +ฑ์:Šถ%‚ฟ�'ย2ฤD/Mcฝ�*_ฮ|�”Š}z๔;:ะัถŽฉ“N˜#ฒc#M๐!BWฒูอF‹et 9ํฦ๊nCฐ ` �\ษ}ข‘qว้]:๕Hsfจa+IY4˜E bทุ™เ€U๙ฒU&Xr‡Dเ๏,โO๑ร‚-ŠˆC >(จหeˆ๘ ƒa�มKˆุW‰‰ G\ฟอu/v้ธ›„v้ๅ—Dโ˜ี’‹K.6€">ZฉฉŒ™@ษ 4ุcx6เภžไ้lE€งŸกีiำdfa้Afยก๙œQสี'?w้%™ืฬฆ`†*ช_b^„FWฮ7•"'œ(D~“ฌ8Dylพx ะX•/:ฤeWฅ4’ˆ๑โg.ฑzโpๅHณ‹4[ะ*"ญŽฦ@3๊ถ�‰ เ^”5d%&ฅฏ�รšๅ�ำZฯัุLฐิ'‰ .klB4อc™�jQA๙อhื>s0/า*คmทG์9฿ซŠ๛-$ฉŽ8ƒฒ‡tภHBิWHb”mึู•'kAฎjชE๋ฮ&ีฦ็E‹ ๋Œrˆ3Œ�ณ(?ฯ3ก�Œ7�7&ธD๎U฿,aดโ�Žนr;pydantic-httpx2-6dd59b9/docs/index.md000066400000000000000000000116441526547463400176130ustar00rootroot00000000000000--- title: HTTPX2 --- [![Test Suite](https://github.com/pydantic/httpx2/workflows/Test%20Suite/badge.svg)](https://github.com/pydantic/httpx2/actions) [![Package version](https://badge.fury.io/py/httpx2.svg)](https://pypi.org/project/httpx2/) [![Join Slack](https://img.shields.io/badge/Slack-Join%20Slack-4A154B?logo=slack)](https://pydantic.dev/docs/logfire/join-slack/) *A next-generation HTTP client for Python.* HTTPX2 is a fully featured HTTP client for Python, which provides sync and async APIs, and support for both HTTP/1.1 and HTTP/2. !!! note HTTPX2 is a continuation of the wonderful work started by [@lovelydinosaur](https://github.com/lovelydinosaur) and the broader HTTPX community. We're enormously grateful for everything that has gone into HTTPX over the years - it has been a foundational piece of the modern Python ecosystem, and this project would not exist without it. With HTTPX itself seeing limited activity recently, Pydantic is picking up stewardship under the HTTPX2 name so that users have a reliably maintained path forward - including timely security updates for a library that sits in the critical path of so many production systems. Our aim is to honour the original project's design, keep it stable for everyone relying on it, and continue evolving it carefully. Thank you to [@lovelydinosaur](https://github.com/lovelydinosaur) and every past contributor for laying such a strong foundation. ๐Ÿ’™ --- Install HTTPX2 using pip: ```shell pip install httpx2 ``` Now, let's get started: ```pycon >>> import httpx2 >>> r = httpx2.get('https://www.example.org/') >>> r >>> r.status_code 200 >>> r.headers['content-type'] 'text/html; charset=UTF-8' >>> r.text '\n\n\nExample Domain...' ``` Or, using the command-line client. ```shell # The command line client is an optional dependency. pip install 'httpx2[cli]' ``` Which now allows us to use HTTPX2 directly from the command-line: ```shell httpx2 --help ``` ## Features HTTPX2 builds on the well-established usability of `requests`, and gives you: * A broadly [requests-compatible API](compatibility.md). * Standard synchronous interface, but with [async support if you need it](async.md). * HTTP/1.1 [and HTTP/2 support](http2.md). * Ability to make requests directly to [WSGI applications](advanced/transports.md#wsgi-transport) or [ASGI applications](advanced/transports.md#asgi-transport). * Strict timeouts everywhere. * Fully type annotated. * 100% test coverage. Plus all the standard features of `requests`... * International Domains and URLs * Keep-Alive & Connection Pooling * Sessions with Cookie Persistence * Browser-style SSL Verification * Basic/Digest Authentication * Elegant Key/Value Cookies * Automatic Decompression * Automatic Content Decoding * Unicode Response Bodies * Multipart File Uploads * HTTP(S) Proxy Support * Connection Timeouts * Streaming Downloads * .netrc Support * Chunked Requests ## Documentation For a run-through of all the basics, head over to the [QuickStart](quickstart.md). For more advanced topics, see the **Advanced** section, the [async support](async.md) section, or the [HTTP/2](http2.md) section. The [Developer Interface](api.md) provides a comprehensive API reference. To find out about tools that integrate with HTTPX2, see [Third Party Packages](third_party_packages.md). ## Dependencies The HTTPX2 project relies on these excellent libraries: * `httpcore2` - The underlying transport implementation for `httpx2`. * `h11` - HTTP/1.1 support. * `anyio` - Structured concurrency primitives, used to support both `asyncio` and `trio`. * `truststore` - SSL verification using the operating system's trust store. * `idna` - Internationalized domain name support. As well as these optional installs: * `h2` - HTTP/2 support. *(Optional, with `httpx2[http2]`)* * `socksio` - SOCKS proxy support. *(Optional, with `httpx2[socks]`)* * `wsproto` - WebSocket support. *(Optional, with `httpx2[ws]`)* * `rich` - Rich terminal support. *(Optional, with `httpx2[cli]`)* * `click` - Command line client support. *(Optional, with `httpx2[cli]`)* * `brotli` or `brotlicffi` - Decoding for "brotli" compressed responses. *(Optional, with `httpx2[brotli]`)* * `backports.zstd` - Decoding for "zstd" compressed responses on Python 3.13 and below. *(Optional, with `httpx2[zstd]`. On Python 3.14+, `zstd` is supported via the stdlib [`compression.zstd`][] module when it is available, and the `httpx2[zstd]` extra installs nothing.)* A huge amount of credit is due to `requests` for the API layout that much of this work follows, as well as to `urllib3` for plenty of design inspiration around the lower-level networking details. ## Installation Install with pip: ```shell pip install httpx2 ``` Or, to include the optional HTTP/2 support, use: ```shell pip install 'httpx2[http2]' ``` To include the optional brotli and zstandard decoders support, use: ```shell pip install 'httpx2[brotli,zstd]' ``` pydantic-httpx2-6dd59b9/docs/logging.md000066400000000000000000000102231526547463400201220ustar00rootroot00000000000000# Logging If you need to inspect the internal behaviour of `httpx2`, you can use Python's standard logging to output information about the underlying network behaviour. For example, the following configuration... ```python import logging import httpx2 logging.basicConfig( format="%(levelname)s [%(asctime)s] %(name)s - %(message)s", datefmt="%Y-%m-%d %H:%M:%S", level=logging.DEBUG ) httpx2.get("https://www.example.com") ``` Will send debug level output to the console, or wherever `stdout` is directed too... ``` DEBUG [2024-09-28 17:27:40] httpcore2.connection - connect_tcp.started host='www.example.com' port=443 local_address=None timeout=5.0 socket_options=None DEBUG [2024-09-28 17:27:41] httpcore2.connection - connect_tcp.complete return_value= DEBUG [2024-09-28 17:27:41] httpcore2.connection - start_tls.started ssl_context= server_hostname='www.example.com' timeout=5.0 DEBUG [2024-09-28 17:27:41] httpcore2.connection - start_tls.complete return_value= DEBUG [2024-09-28 17:27:41] httpcore2.http11 - send_request_headers.started request= DEBUG [2024-09-28 17:27:41] httpcore2.http11 - send_request_headers.complete DEBUG [2024-09-28 17:27:41] httpcore2.http11 - send_request_body.started request= DEBUG [2024-09-28 17:27:41] httpcore2.http11 - send_request_body.complete DEBUG [2024-09-28 17:27:41] httpcore2.http11 - receive_response_headers.started request= DEBUG [2024-09-28 17:27:41] httpcore2.http11 - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Content-Encoding', b'gzip'), (b'Accept-Ranges', b'bytes'), (b'Age', b'407727'), (b'Cache-Control', b'max-age=604800'), (b'Content-Type', b'text/html; charset=UTF-8'), (b'Date', b'Sat, 28 Sep 2024 13:27:42 GMT'), (b'Etag', b'"3147526947+gzip"'), (b'Expires', b'Sat, 05 Oct 2024 13:27:42 GMT'), (b'Last-Modified', b'Thu, 17 Oct 2019 07:18:26 GMT'), (b'Server', b'ECAcc (dcd/7D43)'), (b'Vary', b'Accept-Encoding'), (b'X-Cache', b'HIT'), (b'Content-Length', b'648')]) INFO [2024-09-28 17:27:41] httpx2 - HTTP Request: GET https://www.example.com "HTTP/1.1 200 OK" DEBUG [2024-09-28 17:27:41] httpcore2.http11 - receive_response_body.started request= DEBUG [2024-09-28 17:27:41] httpcore2.http11 - receive_response_body.complete DEBUG [2024-09-28 17:27:41] httpcore2.http11 - response_closed.started DEBUG [2024-09-28 17:27:41] httpcore2.http11 - response_closed.complete DEBUG [2024-09-28 17:27:41] httpcore2.connection - close.started DEBUG [2024-09-28 17:27:41] httpcore2.connection - close.complete ``` Logging output includes information from both the high-level `httpx2` logger, and the network-level `httpcore2` loggers, which can be configured separately. The network-level loggers are named under the `httpcore2` namespace, such as `httpcore2.connection`, `httpcore2.http11`, and `httpcore2.http2`. Configuring the parent `httpcore2` logger captures the output of all of them. For handling more complex logging configurations you might want to use the dictionary configuration style... ```python import logging.config import httpx2 LOGGING_CONFIG = { "version": 1, "handlers": { "default": { "class": "logging.StreamHandler", "formatter": "http", "stream": "ext://sys.stderr" } }, "formatters": { "http": { "format": "%(levelname)s [%(asctime)s] %(name)s - %(message)s", "datefmt": "%Y-%m-%d %H:%M:%S", } }, 'loggers': { 'httpx2': { 'handlers': ['default'], 'level': 'DEBUG', }, 'httpcore2': { 'handlers': ['default'], 'level': 'DEBUG', }, } } logging.config.dictConfig(LOGGING_CONFIG) httpx2.get('https://www.example.com') ``` The exact formatting of the debug logging may be subject to change across different versions of `httpx2` and `httpcore2`. If you need to rely on a particular format it is recommended that you pin installation of these packages to fixed versions. pydantic-httpx2-6dd59b9/docs/migration.md000066400000000000000000000306461526547463400205000ustar00rootroot00000000000000# Migrating from HTTPX So, you have an application (or a library) using `httpx`, and you want to move to `httpx2`. Good news: this is probably the easiest migration you will do this year. `httpx2` is a fork of `httpx 0.28.1`. It has the same public API. The same `Client`, the same `AsyncClient`, the same `Response`, the same everything. The main thing that changed is the name. Let's see how to do it, step by step. ## In a Hurry? If your application depends on `httpx` directly, the whole migration is: * Replace `httpx` with `httpx2` in your dependencies. * Replace `import httpx` with `import httpx2` in your code. ```python import httpx2 r = httpx2.get("https://www.example.org/") ``` That's it. Everything else works the same. If you want an even smaller diff, you can alias the import and keep the rest of your code untouched: ```python import httpx2 as httpx r = httpx.get("https://www.example.org/") ``` Both styles are fine. The alias style is great for a first migration pass in a big codebase, and you can rename properly later (or never, we won't judge). ## You Can Have Both Installed This is the part that matters if you have a **huge codebase**, or dependencies you don't control. `httpx` and `httpx2` are different packages, with different import names. They don't conflict. They can be installed in the same environment, at the same time, and each one works normally. This means: * Your transitive dependencies that still require `httpx` keep working, unchanged. * You don't have to wait for every library in your dependency tree to migrate before you do. * You can migrate your own code **incrementally**, one module at a time, one pull request at a time. There is no flag day. !!! tip Don't try to migrate a large application in one giant pull request. Add `httpx2` next to `httpx`, migrate your own modules gradually, and remove the `httpx` pin once nothing of yours (and none of your dependencies) imports it anymore. To find what still uses `httpx` in your environment: ```shell grep -rn "import httpx\b" src/ ``` And to see which installed packages still depend on it: ```shell pip install pipdeptree pipdeptree --reverse --packages httpx ``` ### But objects don't cross the boundary There is one rule to keep in mind: the two packages can live side by side, but their objects can't stand in for each other. `httpx2.Client` and `httpx.Client` are **distinct classes**. Same for `Response`, `Request`, `Timeout`, all of it. If a library that is still on `httpx` accepts a client and checks `isinstance(client, httpx.Client)` internally - or is simply written against `httpx` types - passing it an `httpx2.Client` will fail. The same goes for exceptions: an `httpx.HTTPError` raised inside a still-on-`httpx` dependency will not be caught by `except httpx2.HTTPError`. So, the rule of thumb: **the package that receives the object decides which module you create it from.** ```python import httpx import httpx2 import some_library_still_on_httpx # Your own code: httpx2. client = httpx2.AsyncClient() # A dependency that expects httpx: give it httpx. some_library_still_on_httpx.configure(http_client=httpx.AsyncClient()) ``` This is exactly why incremental migration works: your code moves to `httpx2`, while each dependency keeps receiving the types it expects, until it migrates too. And to be clear: this boundary is not a permanent feature of your life. It only exists while both packages are in your environment. Every dependency that moves to `httpx2` removes a piece of it - the [For Package Maintainers](#for-package-maintainers) section below gives maintainers two proven, low-effort paths to do it, so point them there. The day your last dependency migrates, you uninstall `httpx`, and this whole section stops applying to you. If you don't want to wait for that day - your application is on `httpx2`, but some dependencies still `import httpx`, and you want everyone to share the same classes now - there is an escape hatch, `alias_httpx()`: ```python import httpx2 httpx2.alias_httpx() ``` After this call, `import httpx` resolves to `httpx2` and `import httpcore` resolves to `httpcore2`, process-wide. Submodule imports included. Dependencies importing `httpx` get the `httpx2` classes, so `isinstance()` checks pass and `except` clauses catch across the boundary - and the same holds for dependencies importing `httpcore` directly, such as custom transports catching low-level exceptions. You can pass your `httpx2.Client` anywhere and drop the `httpx` and `httpcore` installs entirely. There are exactly two rules: * **Call it first.** It must run at the very top of your entrypoint, before anything imports `httpx` or `httpcore`. Modules that already imported them hold references the alias can't rewrite, so `alias_httpx()` raises a `RuntimeError` instead of half-working. * **Applications only, never libraries.** It changes the meaning of `import httpx` for the whole process. That is an application's decision to make, not something a library should impose on its users. !!! warning Don't do `sys.modules["httpx"] = httpx2` by hand instead. It looks equivalent, but any `from httpx.something import ...` in a dependency loads the module a second time under the `httpx` name, quietly recreating the two-class-hierarchies problem. `alias_httpx()` handles submodules correctly. And a few things no aliasing can fix, so you know where the edges are: * `importlib.metadata.version("httpx")` reads installed package metadata, not imports - it will raise or report the old `httpx` version. * A library configuring `logging.getLogger("httpx")` won't see `httpx2`'s logs (the loggers are `httpx2` and `httpcore2.*`). * Subprocesses and spawn-based workers re-import from scratch: each new process needs to call `alias_httpx()` too, before importing `httpx`. Think of it as a bridge, not a destination: it gives you the end state today - one set of classes, no `httpx` install - while your dependencies catch up. Once the last one migrates, you delete the call and the bridge was never there. ## What Changed The public API did not change. But a rename touches a few visible things, and there are a couple of behavior differences worth knowing about. ### Renames * **Package and import**: `httpx` is now `httpx2`. * **The CLI**: the command line client is now `httpx2` (installed with `httpx2[cli]`). * **The User-Agent header**: the default is now `python-httpx2/`. If you have server-side logic or tests matching on `python-httpx/...`, update them. * **The loggers**: `httpx` is now `httpx2`, and `httpcore.*` is now `httpcore2.*`. If you configure logging by logger name, update those names. * **The transport package**: `httpcore` is now `httpcore2`. If you import `httpcore` directly (for example, to catch low-level exceptions in a transport), switch those imports to `httpcore2`. ### Behavior differences * **SSL verification uses the operating system's trust store**, via [`truststore`](https://truststore.readthedocs.io/), instead of `certifi`'s bundled certificates. For most users this just means fewer corporate-proxy headaches. The `SSL_CERT_FILE` and `SSL_CERT_DIR` environment variables are still honored first, and you can still pass `verify=` explicitly. See [SSL](advanced/ssl.md) for details. * **Python 3.11 or newer is required**. Support for Python 3.9 and 3.10 was dropped. * **Deprecation warnings are visible by default**. `httpx2` uses `HTTPXDeprecationWarning`, a `UserWarning` subclass, so you will actually see deprecations without configuring warning filters. ### New things you get Not required for the migration, but nice to have: * **Server-Sent Events** support is built in, via `client.sse()`. If you use `httpx-sse`, you can drop it. See [Server-Sent Events](sse.md). * **WebSockets** support is built in, with the `httpx2[ws]` extra. If you use `httpx-ws`, you can drop it too. See [WebSockets](websockets.md). ## For Package Maintainers If you maintain a library that depends on `httpx`, you have two good options, depending on whether you can release a new major version or not. Both have been battle-tested by real projects. !!! warning Whatever you choose, don't mix the two packages in one code path. `httpx.Response` and `httpx2.Response` are distinct classes: an `isinstance()` check against one will not match objects from the other, and a `httpx2.Client` cannot be passed where your code truly requires a `httpx.Client`. Pick one module per code path, as the patterns below do. ### If you can release a major version: replace it The simple option. Swap the dependency, rename the imports, document it as a breaking change. This is what the [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk) did in [#2972](https://github.com/modelcontextprotocol/python-sdk/pull/2972) for its v2 release: * `httpx` (and `httpx-sse`) replaced with `httpx2` in `pyproject.toml`. * Imports renamed across the codebase. * The change documented in the migration guide, including the visible differences (trust store verification, logger names, User-Agent). For your users, the impact is small: if your API lets them pass their own client (an `http_client=...` parameter, for example), they only need to change which module they build it from. Everything else is internal to your library. ### If you can't release a major version: support both, prefer `httpx2` Maybe your library is stable, widely deployed, and a major version is not on the table. You can still migrate, without breaking anyone. The pattern: **try `httpx2` first, fall back to `httpx` with a deprecation warning, and point your install extra at `httpx2`** so that new installs get the new package. This is what [Starlette](https://github.com/encode/starlette) did for its `TestClient` in [#3291](https://github.com/encode/starlette/pull/3291): ```python import warnings from typing import TYPE_CHECKING if TYPE_CHECKING: import httpx2 as httpx else: try: import httpx2 as httpx except ModuleNotFoundError: try: import httpx except ModuleNotFoundError: raise RuntimeError( "This module requires the httpx2 package to be installed.\n" "You can install it with:\n" " $ pip install httpx2\n" ) from None else: warnings.warn( "Using `httpx` with this package is deprecated; install `httpx2` instead.", DeprecationWarning, stacklevel=2, ) ``` Then the rest of the module just uses `httpx.Client`, `httpx.Response`, etc., and it works with whichever package is installed. How this behaves: * Users with `httpx2` installed get `httpx2`. Silently, no changes needed. * Users with only `httpx` installed keep working, with a deprecation warning telling them where things are going. * Users with neither get a clear error pointing at `httpx2`. And in your `pyproject.toml`, update the extra (or dependency) that installs the HTTP client so that new installs bring in `httpx2`: ```toml [project.optional-dependencies] full = [ "httpx2>=2.0.0", ] ``` !!! tip Keep the `TYPE_CHECKING` branch importing a single module (`httpx2`, aliased as `httpx`). That way your type checker always sees one consistent set of types, while the runtime fallback stays flexible. !!! note Use a warning class that is visible by default (a `UserWarning` subclass) if you have one. Starlette added `StarletteDeprecationWarning` for exactly this reason: a deprecation nobody sees is a deprecation that doesn't work. Later, when you do get to release a major version, you delete the fallback branch and the pattern collapses into a plain `import httpx2`. ## Checklist A quick summary to review before you ship: * Dependencies: `httpx` replaced by (or accompanied by) `httpx2`. * Imports: `import httpx` replaced by `import httpx2` (or aliased). * Direct `httpcore` imports switched to `httpcore2`. * Logging configuration updated for the `httpx2` and `httpcore2.*` logger names. * Anything matching on the `python-httpx/...` User-Agent updated. * Custom CA setups verified against the trust store behavior (or `verify=` passed explicitly). * `httpx-sse` and `httpx-ws` dependencies dropped if you migrate to the built-in [SSE](sse.md) and [WebSockets](websockets.md) support. * Dependencies still importing `httpx`: either keep `httpx` installed for them, or call `alias_httpx()` at the top of your entrypoint. If you get stuck on something not covered here, open a [discussion](https://github.com/pydantic/httpx2/discussions) and we will help you out - and probably update this page too. pydantic-httpx2-6dd59b9/docs/overrides/000077500000000000000000000000001526547463400201565ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/docs/overrides/pyodide.html000066400000000000000000000100511526547463400224760ustar00rootroot00000000000000{% extends "main.html" %} {% block styles %} {{ super() }} {% endblock %} {% block scripts %} {{ super() }} {% endblock %} pydantic-httpx2-6dd59b9/docs/quickstart.md000066400000000000000000000350541526547463400206770ustar00rootroot00000000000000# QuickStart First, start by importing HTTPX: ```pycon >>> import httpx2 ``` Now, letโ€™s try to get a webpage. ```pycon >>> r = httpx2.get('https://httpbin.org/get') >>> r ``` Similarly, to make an HTTP POST request: ```pycon >>> r = httpx2.post('https://httpbin.org/post', data={'key': 'value'}) ``` The PUT, DELETE, HEAD, and OPTIONS requests all follow the same style: ```pycon >>> r = httpx2.put('https://httpbin.org/put', data={'key': 'value'}) >>> r = httpx2.delete('https://httpbin.org/delete') >>> r = httpx2.head('https://httpbin.org/get') >>> r = httpx2.options('https://httpbin.org/get') ``` ## Passing Parameters in URLs To include URL query parameters in the request, use the `params` keyword: ```pycon >>> params = {'key1': 'value1', 'key2': 'value2'} >>> r = httpx2.get('https://httpbin.org/get', params=params) ``` To see how the values get encoding into the URL string, we can inspect the resulting URL that was used to make the request: ```pycon >>> r.url URL('https://httpbin.org/get?key2=value2&key1=value1') ``` You can also pass a list of items as a value: ```pycon >>> params = {'key1': 'value1', 'key2': ['value2', 'value3']} >>> r = httpx2.get('https://httpbin.org/get', params=params) >>> r.url URL('https://httpbin.org/get?key1=value1&key2=value2&key2=value3') ``` ## Response Content HTTPX will automatically handle decoding the response content into Unicode text. ```pycon >>> r = httpx2.get('https://www.example.org/') >>> r.text '\n\n\nExample Domain...' ``` You can inspect what encoding will be used to decode the response. ```pycon >>> r.encoding 'UTF-8' ``` In some cases the response may not contain an explicit encoding, in which case HTTPX will attempt to automatically determine an encoding to use. ```pycon >>> r.encoding None >>> r.text '\n\n\nExample Domain...' ``` If you need to override the standard behaviour and explicitly set the encoding to use, then you can do that too. ```pycon >>> r.encoding = 'ISO-8859-1' ``` ## Binary Response Content The response content can also be accessed as bytes, for non-text responses: ```pycon >>> r.content b'\n\n\nExample Domain...' ``` Any `gzip` and `deflate` HTTP response encodings will automatically be decoded for you. If `brotlipy` is installed, then the `brotli` response encoding will be supported. The `zstd` response encoding is supported on Python 3.14+ via the stdlib [`compression.zstd`][] module when it is available; on Python 3.13 and below it requires the `backports.zstd` package. For example, to create an image from binary data returned by a request, you can use the following code: ```pycon >>> from PIL import Image >>> from io import BytesIO >>> i = Image.open(BytesIO(r.content)) ``` ## JSON Response Content Often Web API responses will be encoded as JSON. ```pycon >>> r = httpx2.get('https://api.github.com/events') >>> r.json() [{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...' ... }}] ``` ## Custom Headers To include additional headers in the outgoing request, use the `headers` keyword argument: ```pycon >>> url = 'https://httpbin.org/headers' >>> headers = {'user-agent': 'my-app/0.0.1'} >>> r = httpx2.get(url, headers=headers) ``` ## Sending Form Encoded Data Some types of HTTP requests, such as `POST` and `PUT` requests, can include data in the request body. One common way of including that is as form-encoded data, which is used for HTML forms. ```pycon >>> data = {'key1': 'value1', 'key2': 'value2'} >>> r = httpx2.post("https://httpbin.org/post", data=data) >>> print(r.text) { ... "form": { "key2": "value2", "key1": "value1" }, ... } ``` Form encoded data can also include multiple values from a given key. ```pycon >>> data = {'key1': ['value1', 'value2']} >>> r = httpx2.post("https://httpbin.org/post", data=data) >>> print(r.text) { ... "form": { "key1": [ "value1", "value2" ] }, ... } ``` ## Sending Multipart File Uploads You can also upload files, using HTTP multipart encoding: ```pycon >>> with open('report.xls', 'rb') as report_file: ... files = {'upload-file': report_file} ... r = httpx2.post("https://httpbin.org/post", files=files) >>> print(r.text) { ... "files": { "upload-file": "<... binary content ...>" }, ... } ``` You can also explicitly set the filename and content type, by using a tuple of items for the file value: ```pycon >>> with open('report.xls', 'rb') as report_file: ... files = {'upload-file': ('report.xls', report_file, 'application/vnd.ms-excel')} ... r = httpx2.post("https://httpbin.org/post", files=files) >>> print(r.text) { ... "files": { "upload-file": "<... binary content ...>" }, ... } ``` If you need to include non-file data fields in the multipart form, use the `data=...` parameter: ```pycon >>> data = {'message': 'Hello, world!'} >>> with open('report.xls', 'rb') as report_file: ... files = {'file': report_file} ... r = httpx2.post("https://httpbin.org/post", data=data, files=files) >>> print(r.text) { ... "files": { "file": "<... binary content ...>" }, "form": { "message": "Hello, world!", }, ... } ``` ## Sending JSON Encoded Data Form encoded data is okay if all you need is a simple key-value data structure. For more complicated data structures you'll often want to use JSON encoding instead. ```pycon >>> data = {'integer': 123, 'boolean': True, 'list': ['a', 'b', 'c']} >>> r = httpx2.post("https://httpbin.org/post", json=data) >>> print(r.text) { ... "json": { "boolean": true, "integer": 123, "list": [ "a", "b", "c" ] }, ... } ``` ## Sending Binary Request Data For other encodings, you should use the `content=...` parameter, passing either a `bytes` type or a generator that yields `bytes`. ```pycon >>> content = b'Hello, world' >>> r = httpx2.post("https://httpbin.org/post", content=content) ``` You may also want to set a custom `Content-Type` header when uploading binary data. ## Response Status Codes We can inspect the HTTP status code of the response: ```pycon >>> r = httpx2.get('https://httpbin.org/get') >>> r.status_code 200 ``` HTTPX also includes an easy shortcut for accessing status codes by their text phrase. ```pycon >>> r.status_code == httpx2.codes.OK True ``` We can raise an exception for any responses which are not a 2xx success code: ```pycon >>> not_found = httpx2.get('https://httpbin.org/status/404') >>> not_found.status_code 404 >>> not_found.raise_for_status() Traceback (most recent call last): File "", line 1, in File "/path/to/site-packages/httpx2/_models.py", line 815, in raise_for_status raise HTTPStatusError(message, request=request, response=self) httpx2.HTTPStatusError: Client error '404 Not Found' for url 'https://httpbin.org/status/404' For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404 ``` Any successful response codes will return the `Response` instance rather than raising an exception. ```pycon >>> r.raise_for_status() ``` The method returns the response instance, allowing you to use it inline. For example: ```pycon >>> r = httpx2.get('...').raise_for_status() >>> data = httpx2.get('...').raise_for_status().json() ``` ## Response Headers The response headers are available as a dictionary-like interface. ```pycon >>> r.headers Headers({ 'content-encoding': 'gzip', 'transfer-encoding': 'chunked', 'connection': 'close', 'server': 'nginx/1.0.4', 'x-runtime': '148ms', 'etag': '"e1ca502697e5c9317743dc078f67693f"', 'content-type': 'application/json' }) ``` The `Headers` data type is case-insensitive, so you can use any capitalization. ```pycon >>> r.headers['Content-Type'] 'application/json' >>> r.headers.get('content-type') 'application/json' ``` Multiple values for a single response header are represented as a single comma-separated value, as per [RFC 7230](https://tools.ietf.org/html/rfc7230#section-3.2): > A recipient MAY combine multiple header fields with the same field name into one โ€œfield-name: field-valueโ€ pair, without changing the semantics of the message, by appending each subsequent field-value to the combined field value in order, separated by a comma. ## Streaming Responses For large downloads you may want to use streaming responses that do not load the entire response body into memory at once. You can stream the binary content of the response... ```pycon >>> with httpx2.stream("GET", "https://www.example.com") as r: ... for data in r.iter_bytes(): ... print(data) ``` Or the text of the response... ```pycon >>> with httpx2.stream("GET", "https://www.example.com") as r: ... for text in r.iter_text(): ... print(text) ``` Or stream the text, on a line-by-line basis... ```pycon >>> with httpx2.stream("GET", "https://www.example.com") as r: ... for line in r.iter_lines(): ... print(line) ``` HTTPX will use universal line endings, normalising all cases to `\n`. In some cases you might want to access the raw bytes on the response without applying any HTTP content decoding. In this case any content encoding that the web server has applied such as `gzip`, `deflate`, `brotli`, or `zstd` will not be automatically decoded. ```pycon >>> with httpx2.stream("GET", "https://www.example.com") as r: ... for chunk in r.iter_raw(): ... print(chunk) ``` If you're using streaming responses in any of these ways then the `response.content` and `response.text` attributes will not be available, and will raise errors if accessed. However you can also use the response streaming functionality to conditionally load the response body: ```pycon >>> with httpx2.stream("GET", "https://www.example.com") as r: ... if int(r.headers['Content-Length']) < TOO_LONG: ... r.read() ... print(r.text) ``` ## Cookies Any cookies that are set on the response can be easily accessed: ```pycon >>> r = httpx2.get('https://httpbin.org/cookies/set?chocolate=chip') >>> r.cookies['chocolate'] 'chip' ``` To include cookies in an outgoing request, use the `cookies` parameter: ```pycon >>> cookies = {"peanut": "butter"} >>> r = httpx2.get('https://httpbin.org/cookies', cookies=cookies) >>> r.json() {'cookies': {'peanut': 'butter'}} ``` Cookies are returned in a `Cookies` instance, which is a dict-like data structure with additional API for accessing cookies by their domain or path. ```pycon >>> cookies = httpx2.Cookies() >>> cookies.set('cookie_on_domain', 'hello, there!', domain='httpbin.org') >>> cookies.set('cookie_off_domain', 'nope.', domain='example.org') >>> r = httpx2.get('http://httpbin.org/cookies', cookies=cookies) >>> r.json() {'cookies': {'cookie_on_domain': 'hello, there!'}} ``` ## Redirection and History By default, HTTPX will **not** follow redirects for all HTTP methods, although this can be explicitly enabled. For example, GitHub redirects all HTTP requests to HTTPS. ```pycon >>> r = httpx2.get('http://github.com/') >>> r.status_code 301 >>> r.history [] >>> r.next_request ``` You can modify the default redirection handling with the `follow_redirects` parameter: ```pycon >>> r = httpx2.get('http://github.com/', follow_redirects=True) >>> r.url URL('https://github.com/') >>> r.status_code 200 >>> r.history [] ``` The `history` property of the response can be used to inspect any followed redirects. It contains a list of any redirect responses that were followed, in the order in which they were made. ## Timeouts HTTPX defaults to including reasonable timeouts for all network operations, meaning that if a connection is not properly established then it should always raise an error rather than hanging indefinitely. The default timeout for network inactivity is five seconds. You can modify the value to be more or less strict: ```pycon >>> httpx2.get('https://github.com/', timeout=0.001) ``` You can also disable the timeout behavior completely... ```pycon >>> httpx2.get('https://github.com/', timeout=None) ``` For advanced timeout management, see [Timeout fine-tuning](advanced/timeouts.md#fine-tuning-the-configuration). ## Authentication HTTPX supports Basic and Digest HTTP authentication. To provide Basic authentication credentials, pass a 2-tuple of plaintext `str` or `bytes` objects as the `auth` argument to the request functions: ```pycon >>> httpx2.get("https://example.com", auth=("my_user", "password123")) ``` To provide credentials for Digest authentication you'll need to instantiate a `DigestAuth` object with the plaintext username and password as arguments. This object can be then passed as the `auth` argument to the request methods as above: ```pycon >>> auth = httpx2.DigestAuth("my_user", "password123") >>> httpx2.get("https://example.com", auth=auth) ``` ## Exceptions HTTPX will raise exceptions if an error occurs. The most important exception classes in HTTPX are `RequestError` and `HTTPStatusError`. The `RequestError` class is a superclass that encompasses any exception that occurs while issuing an HTTP request. These exceptions include a `.request` attribute. ```python try: response = httpx2.get("https://www.example.com/") except httpx2.RequestError as exc: print(f"An error occurred while requesting {exc.request.url!r}.") ``` The `HTTPStatusError` class is raised by `response.raise_for_status()` on responses which are not a 2xx success code. These exceptions include both a `.request` and a `.response` attribute. ```python response = httpx2.get("https://www.example.com/") try: response.raise_for_status() except httpx2.HTTPStatusError as exc: print(f"Error response {exc.response.status_code} while requesting {exc.request.url!r}.") ``` There is also a base class `HTTPError` that includes both of these categories, and can be used to catch either failed requests, or 4xx and 5xx responses. You can either use this base class to catch both categories... ```python try: response = httpx2.get("https://www.example.com/") response.raise_for_status() except httpx2.HTTPError as exc: print(f"Error while requesting {exc.request.url!r}.") ``` Or handle each case explicitly... ```python try: response = httpx2.get("https://www.example.com/") response.raise_for_status() except httpx2.RequestError as exc: print(f"An error occurred while requesting {exc.request.url!r}.") except httpx2.HTTPStatusError as exc: print(f"Error response {exc.response.status_code} while requesting {exc.request.url!r}.") ``` For a full list of available exceptions, see [Exceptions (API Reference)](exceptions.md). pydantic-httpx2-6dd59b9/docs/sse.md000066400000000000000000000070171526547463400172750ustar00rootroot00000000000000# Server-Sent Events [Server-sent events][mdn] (SSE) let a server push a stream of events to the client over a single long-lived HTTP response with the `text/event-stream` content type. HTTPX has native support for consuming them through `client.sse()`. ## Consuming events `client.sse()` is a context manager that yields an `EventSource`. Iterating the `EventSource` decodes the stream and yields a `ServerSentEvent` for each event: ```pycon >>> with httpx2.Client() as client: ... with client.sse("https://example.com/sse") as source: ... for event in source: ... print(event.event, event.data) ``` It works the same way with the async client, using `async with` and `async for`: ```pycon >>> async with httpx2.AsyncClient() as client: ... async with client.sse("https://example.com/sse") as source: ... async for event in source: ... print(event.event, event.data) ``` `sse()` issues a `GET` request by default. Some APIs stream events in response to a `POST` - pass `method="POST"` along with the usual request arguments: ```pycon >>> with client.sse("https://example.com/sse", method="POST", json={"query": "..."}) as source: ... for event in source: ... print(event.data) ``` The `Accept: text/event-stream` and `Cache-Control: no-store` headers are set for you; any headers you pass take precedence. ## The `ServerSentEvent` Each event exposes the fields defined by the SSE specification: | Attribute | Description | | --------- | ----------- | | `event` | The event type. Defaults to `"message"`. | | `data` | The event payload. Multiple `data:` lines are joined with `\n`. | | `id` | The last event ID, which persists across events until changed. | | `retry` | The reconnection time in milliseconds, or `None`. | When the payload is JSON, `event.json()` decodes `event.data` for you: ```pycon >>> with client.sse("https://example.com/sse") as source: ... for event in source: ... print(event.json()) ``` ## Accessing the response The underlying [`Response`](api.md#response) is available as `source.response`, which is useful for inspecting the status code or headers before iterating: ```pycon >>> with client.sse("https://example.com/sse") as source: ... source.response.raise_for_status() ... for event in source: ... print(event.data) ``` ## Error handling If the response does not have a `text/event-stream` content type, iterating the `EventSource` raises `SSEError`: ```pycon >>> with client.sse("https://example.com/not-an-event-stream") as source: ... for event in source: # raises httpx2.SSEError ... ... ``` `SSEError` is a subclass of [`TransportError`](exceptions.md), so it is also caught by `except httpx2.TransportError`. ## Limiting event size An event is buffered until its terminating blank line arrives. To stop a stream that keeps sending data without ever completing an event from growing the buffer indefinitely, `client.sse()` caps the bytes buffered for a single event at 1 MiB by default and raises `SSEError` once an event exceeds the limit. Pass `max_event_size` to change the cap: ```pycon >>> with client.sse("https://example.com/sse", max_event_size=8 * 1024 * 1024) as source: ... for event in source: # raise the 1 MiB default to 8 MiB ... print(event.data) ``` The counter resets after each event, so the limit applies per event rather than to the stream as a whole. Set `max_event_size=None` to buffer events without any limit. [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events pydantic-httpx2-6dd59b9/docs/third_party_packages.md000066400000000000000000000044021526547463400226650ustar00rootroot00000000000000# Third Party Packages These maintained packages integrate with HTTPX2. ## Plugins ### httpx-pki [GitHub](https://github.com/ccbest/httpx-pki) PKCS#12 / PEM client-certificate (mTLS) sessions, with OS cert-store loading, identity selection, and certificate rotation. ### httpx2-pytest [GitHub](https://github.com/angryfoxx/httpx2-pytest) - [Documentation](https://github.com/angryfoxx/httpx2-pytest#about-httpx2) Provides a [pytest](https://docs.pytest.org/en/latest/) fixture to mock HTTPX2 within test cases. This package is a fork of [pytest-httpx](https://github.com/Colin-b/pytest_httpx) for HTTPX2. ### interlock-cb [GitHub](https://github.com/bagowix/interlock) - [Documentation](https://bagowix.github.io/interlock/integrations/httpx2/) A circuit breaker transport: keeps one breaker per host, so calls to a failing host fail fast instead of waiting out every timeout. Trips on failure rate over a sliding window and on slow responses. ### pytest-HTTPX2 [GitHub](https://github.com/lundberg/pytest-httpx2) A pytest plugin for mocking out HTTPX2 using RESPX. ## Libraries with HTTPX2 support ### Authlib [GitHub](https://github.com/authlib/authlib) - [Documentation](https://docs.authlib.org/en/latest/) A Python library for building OAuth and OpenID Connect clients and servers. Includes an [OAuth HTTPX2 client](https://docs.authlib.org/en/latest/oauth2/client/http/httpx.html). ### httpdbg [GitHub](https://github.com/cle-b/httpdbg) - [Documentation](https://httpdbg.readthedocs.io/) A tool for python developers to easily debug the HTTP(S) client requests in a python program. ### httpx2-negotiate-sspi [Github](https://github.com/achapkowski/httpx2_negotiate_sspi) [Documentation](https://achapkowski.github.io/httpx2_negotiate_sspi) HTTP Negotiate authentication for httpx2 using Windows SSPI. ### httpx2_kerberos httpx2_kerberos is a Python library that adds Kerberos/GSSAPI authentication support to the HTTPX2 client for making secure, authenticated HTTP requests. [github](https://github.com/achapkowski/httpx2_kerberos) [Documentation](https://achapkowski.github.io/httpx2_kerberos) ### VCR.py [GitHub](https://github.com/kevin1024/vcrpy) - [Documentation](https://vcrpy.readthedocs.io/) Record and repeat requests. pydantic-httpx2-6dd59b9/docs/troubleshooting.md000066400000000000000000000041551526547463400217320ustar00rootroot00000000000000# Troubleshooting This page lists some common problems or issues you could encounter while developing with HTTPX, as well as possible solutions. ## Proxies --- ### "`The handshake operation timed out`" on HTTPS requests when using a proxy **Description**: When using a proxy and making an HTTPS request, you see an exception looking like this: ```console httpx2.ProxyError: _ssl.c:1091: The handshake operation timed out ``` **Similar issues**: [encode/httpx#1412](https://github.com/encode/httpx/issues/1412), [encode/httpx#1433](https://github.com/encode/httpx/issues/1433) **Resolution**: it is likely that you've set up your proxies like this... ```python mounts = { "http://": httpx2.HTTPTransport(proxy="http://myproxy.org"), "https://": httpx2.HTTPTransport(proxy="https://myproxy.org"), } ``` Using this setup, you're telling HTTPX to connect to the proxy using HTTP for HTTP requests, and using HTTPS for HTTPS requests. But if you get the error above, it is likely that your proxy doesn't support connecting via HTTPS. Don't worry: that's a [common gotcha](advanced/proxies.md#http-proxies). Change the scheme of your HTTPS proxy to `http://...` instead of `https://...`: ```python mounts = { "http://": httpx2.HTTPTransport(proxy="http://myproxy.org"), "https://": httpx2.HTTPTransport(proxy="http://myproxy.org"), } ``` This can be simplified to: ```python proxy = "http://myproxy.org" with httpx2.Client(proxy=proxy) as client: ... ``` For more information, see [Proxies: FORWARD vs TUNNEL](advanced/proxies.md#forward-vs-tunnel). --- ### Error when making requests to an HTTPS proxy **Description**: your proxy _does_ support connecting via HTTPS, but you are seeing errors along the lines of... ```console httpx2.ProxyError: [SSL: PRE_MAC_LENGTH_TOO_LONG] invalid alert (_ssl.c:1091) ``` **Similar issues**: [encode/httpx#1424](https://github.com/encode/httpx/issues/1424). **Resolution**: HTTPX does not properly support HTTPS proxies at this time. If that's something you're interested in having, please see [encode/httpx#1434](https://github.com/encode/httpx/issues/1434) and consider lending a hand there. pydantic-httpx2-6dd59b9/docs/websockets.md000066400000000000000000000141351526547463400206530ustar00rootroot00000000000000# WebSockets [WebSockets][mdn] provide a full-duplex communication channel between the client and the server over a single long-lived connection, allowing both sides to send messages at any time. HTTPX has native support for them through `client.websocket()`. WebSocket support requires the optional `wsproto` dependency: ```shell pip install 'httpx2[ws]' ``` ## Opening a session `client.websocket()` is a context manager that performs the WebSocket handshake and yields a `WebSocketSession`: ```pycon >>> with httpx2.Client() as client: ... with client.websocket("wss://example.com/ws") as ws: ... ws.send_text("Hello!") ... message = ws.receive_text() ``` It works the same way with the async client, using `async with` and `await`: ```pycon >>> async with httpx2.AsyncClient() as client: ... async with client.websocket("wss://example.com/ws") as ws: ... await ws.send_text("Hello!") ... message = await ws.receive_text() ``` Both `ws://` and `wss://` URLs are supported, as well as their `http://` and `https://` equivalents. The handshake is a regular HTTP request, so the client's configuration - headers, cookies, authentication, proxies, and timeouts - applies as usual. The session is closed automatically when exiting the context manager. For quick one-off sessions, there is also a top-level `httpx2.websocket()` function, mirroring `httpx2.request()`: ```pycon >>> with httpx2.websocket("wss://example.com/ws") as ws: ... ws.send_text("Hello!") ``` ## Sending and receiving messages The session provides `send` and `receive` methods for text, bytes, and JSON messages: ```pycon >>> ws.send_text("Hello!") >>> ws.send_bytes(b"Hello!") >>> ws.send_json({"message": "Hello!"}) ``` ```pycon >>> ws.receive_text() 'Hello!' >>> ws.receive_bytes() b'Hello!' >>> ws.receive_json() {'message': 'Hello!'} ``` JSON messages are sent as text frames by default. Pass `mode="binary"` to `send_json()` or `receive_json()` to use binary frames instead. The `receive` methods block until a message is available. Pass a `timeout` in seconds to bound the wait: ```pycon >>> ws.receive_text(timeout=2.0) ``` If no message arrives in time, `TimeoutError` is raised. If the received message doesn't match the expected type, `WebSocketInvalidTypeReceived` is raised. ## Subprotocols To negotiate a subprotocol with the server, pass the `subprotocols` argument. The subprotocol accepted by the server is available as `ws.subprotocol`: ```pycon >>> with client.websocket("wss://example.com/ws", subprotocols=["graphql-ws"]) as ws: ... ws.subprotocol 'graphql-ws' ``` ## Keepalive pings The session automatically sends a Ping event at a regular interval to keep the connection alive. If the server doesn't answer in time, the connection is considered lost and `WebSocketNetworkError` is raised. You can also send a Ping manually. `ping()` returns an event that is set when the corresponding Pong is received: ```pycon >>> pong = ws.ping() >>> pong.wait() # Blocks until the server answers. ``` ## Configuration `client.websocket()` and `httpx2.websocket()` accept the following keyword arguments to tune the session behaviour: | Argument | Default | Description | | -------- | ------- | ----------- | | `max_message_size_bytes` | 65536 | The maximum incoming message size in bytes. Messages larger than this limit, including fragmented messages whose cumulative size exceeds the limit, close the connection with `MESSAGE_TOO_BIG`. | | `queue_size` | 512 | The size of the queue holding received messages until they are consumed. When full, the session stops reading from the server until room is available. | | `keepalive_ping_interval_seconds` | 20.0 | The interval between automatic keepalive pings. Use `None` to disable them. | | `keepalive_ping_timeout_seconds` | 20.0 | How long to wait for the server to answer a keepalive ping before considering the connection lost. | ## Accessing the handshake response The [`Response`](api.md#response) that upgraded the connection is available as `ws.response`, which is useful for inspecting the handshake headers: ```pycon >>> with client.websocket("wss://example.com/ws") as ws: ... ws.response.headers ``` ## Error handling WebSocket exceptions live in the `httpx2.websockets` namespace: ```pycon >>> from httpx2.websockets import WebSocketDisconnect ``` * `WebSocketUpgradeError` - the server didn't accept the upgrade, and responded with something other than a `101 Switching Protocols` status code. The response is available as `.response`. * `WebSocketDisconnect` - the server closed the session. The close code and reason are available as `.code` and `.reason`. * `WebSocketInvalidTypeReceived` - the received message didn't match the expected type. * `WebSocketNetworkError` - a network error occurred, typically because the underlying stream closed or timed out. All of these are subclasses of `httpx2.websockets.HTTPXWSException`: ```pycon >>> from httpx2.websockets import WebSocketDisconnect >>> with client.websocket("wss://example.com/ws") as ws: ... try: ... message = ws.receive_text() ... except WebSocketDisconnect as exc: ... print(f"Connection closed: {exc.code} {exc.reason}") ``` ## Testing ASGI applications Just as [`ASGITransport`](advanced/transports.md#asgi-transport) lets you make HTTP requests directly against an ASGI application, `ASGIWebSocketTransport` extends it with WebSocket support - useful for testing Starlette or FastAPI applications without running a server: ```python from httpx2 import AsyncClient from httpx2.websockets import ASGIWebSocketTransport async with AsyncClient(transport=ASGIWebSocketTransport(app)) as client: async with client.websocket("ws://testserver/ws") as ws: await ws.send_text("Hello!") message = await ws.receive_text() ``` Regular HTTP requests through the same transport work too, so a single client can exercise the whole application. ## Acknowledgements WebSocket support is derived from the excellent [httpx-ws](https://github.com/frankie567/httpx-ws) package by [Franรงois Voron](https://github.com/frankie567). [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API pydantic-httpx2-6dd59b9/mkdocs.yml000066400000000000000000000046041526547463400172330ustar00rootroot00000000000000site_name: HTTPX2 site_description: A next-generation HTTP client for Python. theme: name: 'material' custom_dir: 'docs/overrides' palette: - scheme: 'default' media: '(prefers-color-scheme: light)' toggle: icon: 'material/lightbulb' name: "Switch to dark mode" - scheme: 'slate' media: '(prefers-color-scheme: dark)' primary: 'blue' toggle: icon: 'material/lightbulb-outline' name: 'Switch to light mode' repo_name: pydantic/httpx2 repo_url: https://github.com/pydantic/httpx2/ edit_uri: "" nav: - Introduction: 'index.md' - QuickStart: 'quickstart.md' - Migrating from HTTPX: 'migration.md' - Advanced: - Clients: 'advanced/clients.md' - Authentication: 'advanced/authentication.md' - SSL: 'advanced/ssl.md' - Proxies: 'advanced/proxies.md' - Timeouts: 'advanced/timeouts.md' - Resource Limits: 'advanced/resource-limits.md' - Event Hooks: 'advanced/event-hooks.md' - Transports: 'advanced/transports.md' - Text Encodings: 'advanced/text-encodings.md' - Extensions: 'advanced/extensions.md' - Emscripten: 'advanced/emscripten.md' - Guides: - Async Support: 'async.md' - HTTP/2 Support: 'http2.md' - Logging: 'logging.md' - Server-Sent Events: 'sse.md' - WebSockets: 'websockets.md' - Requests Compatibility: 'compatibility.md' - Troubleshooting: 'troubleshooting.md' - API Reference: - Developer Interface: 'api.md' - Exceptions: 'exceptions.md' - Environment Variables: 'environment_variables.md' - Community: - Third Party Packages: 'third_party_packages.md' - Contributing: 'contributing.md' - Code of Conduct: 'code_of_conduct.md' plugins: - mkdocstrings: handlers: python: inventories: - https://docs.python.org/3/objects.inv options: show_root_heading: true show_source: false show_signature_annotations: true separate_signature: true line_length: 60 heading_level: 3 inherited_members: true markdown_extensions: - admonition - pymdownx.highlight: use_pygments: true pygments_lang_class: true - pymdownx.superfences extra_css: - css/custom.css pydantic-httpx2-6dd59b9/pyproject.toml000066400000000000000000000052741526547463400201500ustar00rootroot00000000000000[tool.uv] package = false default-groups = ["dev", "docs", "bench"] required-version = ">=0.8.6" exclude-newer = "7 days" exclude-newer-package = { idna = "2026-06-03T00:00:00Z", httpx2-jsfetch = "2026-08-08T00:00:00Z" } [tool.uv.workspace] members = ["src/httpx2", "src/httpcore2"] [tool.uv.sources] httpcore2 = { workspace = true } httpx2 = { workspace = true } [dependency-groups] dev = [ "httpx2[brotli,cli,http2,socks,ws,zstd]", "httpcore2[asyncio,trio,http2,socks]", # Tests "chardet>=7.6.0", "coverage[toml]>=7.15.4", "cryptography>=50.0.1", "flaky>=3.8", "pytest>=9.1.0", "pytest-codspeed>=5.0.3", "pytest-httpbin>=2.1.0", "pytest-trio>=0.8.0", "starlette>=1.6.0", "trio>=0.34.0", "trio-typing>=0.10.0", "trustme>=1.2.1", "uvicorn>=0.52.4", "websockets>=16.1.1", "werkzeug>=3.1.9", # Linting "mypy>=2.3.1", "ruff>=0.16.4", # Packaging "twine>=7.0.0", ] docs = ["zensical>=0.0.57", "mkdocstrings[python]>=1.0.6"] bench = [ "aiohttp>=3.14.3", "pyinstrument>=5.1.3", "zuvloop>=0.0.8; python_version >= '3.14' and implementation_name == 'cpython'", ] [tool.ruff] line-length = 120 target-version = "py311" exclude = ["src/httpcore2/httpcore2/_sync", "tests/httpcore2/_sync"] extend-exclude = ["*.md"] [tool.ruff.lint] select = ["B", "C4", "E", "F", "I", "PERF", "PIE", "UP", "W"] ignore = ["B904", "B028", "C401", "PERF203"] [tool.ruff.lint.isort] combine-as-imports = true known-first-party = ["httpx2", "httpcore2"] [tool.ruff.lint.per-file-ignores] "__init__.py" = ["F403", "F405"] [tool.mypy] ignore_missing_imports = true strict = true [tool.pytest.ini_options] addopts = "-rxXs --import-mode=importlib" testpaths = ["tests"] filterwarnings = [ "error", "ignore: You seem to already have a custom sys.excepthook handler installed. I'll skip installing Trio's custom handler, but this means MultiErrors will not show full tracebacks.:RuntimeWarning", # See: https://github.com/agronholm/anyio/issues/508 "ignore: trio.MultiError is deprecated since Trio 0.22.0:trio.TrioDeprecationWarning", ] markers = [ "copied_from(source, changes=None): mark test as copied from somewhere else, along with a description of changes made to accommodate e.g. our test setup", "network: marks tests which require network connection. Used in 3rd-party build environments that have network disabled.", "benchmark: marks CodSpeed benchmark tests under tests/test_benchmark*.py.", ] [tool.coverage.run] source_pkgs = ["httpx2", "httpcore2", "tests"] omit = ["src/httpcore2/httpcore2/_sync/*", "tests/test_benchmark*.py"] [tool.coverage.report] exclude_also = [ "if TYPE_CHECKING:", "if (typing|_typing).TYPE_CHECKING:", "raise NotImplementedError", "@(typing\\.)?overload", ] pydantic-httpx2-6dd59b9/redirects/000077500000000000000000000000001526547463400172105ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/redirects/.README.md000066400000000000000000000023351526547463400205500ustar00rootroot00000000000000# Redirects site The HTTPX2 docs used to be served from `httpx2.pydantic.dev` and now live at . This directory is deployed to `httpx2.pydantic.dev` in their place: a Cloudflare Worker (`httpx2-docs`, configured in `wrangler.toml`) that serves no pages of its own, only the rules in `_redirects`. Deploy it by hand after changing `_redirects`, there's no workflow for it: ```bash wrangler deploy ``` Check rules locally first with `wrangler dev`, which prints how many it parsed and serves them on localhost. Two behaviours differ between `wrangler dev` and production, both found by testing the deployed site: - Splat rules such as `/advanced/*` lose to the `/*` catch-all in production, though they win locally. Every path we care about is therefore listed in full rather than matched by prefix. - Redirect rules take precedence over static assets, so the catch-all shadows any file placed here. That includes `robots.txt`, which is why there isn't one. A `200` rewrite to serve it anyway works locally and is ignored in production. This README is uploaded with the rest of the directory, and like any file here it is unreachable: a request for `/.README.md` matches the catch-all and redirects. pydantic-httpx2-6dd59b9/redirects/_redirects000066400000000000000000000121121526547463400212530ustar00rootroot00000000000000# Redirects from the old docs site to https://pydantic.dev/docs/httpx2/. # Deployed by hand: `wrangler deploy` (see wrangler.toml). / https://pydantic.dev/docs/httpx2/get-started/ 301 /index.html https://pydantic.dev/docs/httpx2/get-started/ 301 /quickstart https://pydantic.dev/docs/httpx2/get-started/quickstart/ 301 /quickstart/ https://pydantic.dev/docs/httpx2/get-started/quickstart/ 301 /migration https://pydantic.dev/docs/httpx2/get-started/migration/ 301 /migration/ https://pydantic.dev/docs/httpx2/get-started/migration/ 301 /advanced https://pydantic.dev/docs/httpx2/advanced/clients/ 301 /advanced/ https://pydantic.dev/docs/httpx2/advanced/clients/ 301 /advanced/authentication https://pydantic.dev/docs/httpx2/advanced/authentication/ 301 /advanced/authentication/ https://pydantic.dev/docs/httpx2/advanced/authentication/ 301 /advanced/clients https://pydantic.dev/docs/httpx2/advanced/clients/ 301 /advanced/clients/ https://pydantic.dev/docs/httpx2/advanced/clients/ 301 /advanced/event-hooks https://pydantic.dev/docs/httpx2/advanced/event-hooks/ 301 /advanced/event-hooks/ https://pydantic.dev/docs/httpx2/advanced/event-hooks/ 301 /advanced/extensions https://pydantic.dev/docs/httpx2/advanced/extensions/ 301 /advanced/extensions/ https://pydantic.dev/docs/httpx2/advanced/extensions/ 301 /advanced/proxies https://pydantic.dev/docs/httpx2/advanced/proxies/ 301 /advanced/proxies/ https://pydantic.dev/docs/httpx2/advanced/proxies/ 301 /advanced/resource-limits https://pydantic.dev/docs/httpx2/advanced/resource-limits/ 301 /advanced/resource-limits/ https://pydantic.dev/docs/httpx2/advanced/resource-limits/ 301 /advanced/ssl https://pydantic.dev/docs/httpx2/advanced/ssl/ 301 /advanced/ssl/ https://pydantic.dev/docs/httpx2/advanced/ssl/ 301 /advanced/text-encodings https://pydantic.dev/docs/httpx2/advanced/text-encodings/ 301 /advanced/text-encodings/ https://pydantic.dev/docs/httpx2/advanced/text-encodings/ 301 /advanced/timeouts https://pydantic.dev/docs/httpx2/advanced/timeouts/ 301 /advanced/timeouts/ https://pydantic.dev/docs/httpx2/advanced/timeouts/ 301 /advanced/transports https://pydantic.dev/docs/httpx2/advanced/transports/ 301 /advanced/transports/ https://pydantic.dev/docs/httpx2/advanced/transports/ 301 /advanced/emscripten https://pydantic.dev/docs/httpx2/advanced/emscripten/ 301 /advanced/emscripten/ https://pydantic.dev/docs/httpx2/advanced/emscripten/ 301 /async https://pydantic.dev/docs/httpx2/guides/async/ 301 /async/ https://pydantic.dev/docs/httpx2/guides/async/ 301 /compatibility https://pydantic.dev/docs/httpx2/guides/compatibility/ 301 /compatibility/ https://pydantic.dev/docs/httpx2/guides/compatibility/ 301 /http2 https://pydantic.dev/docs/httpx2/guides/http2/ 301 /http2/ https://pydantic.dev/docs/httpx2/guides/http2/ 301 /logging https://pydantic.dev/docs/httpx2/guides/logging/ 301 /logging/ https://pydantic.dev/docs/httpx2/guides/logging/ 301 /sse https://pydantic.dev/docs/httpx2/guides/sse/ 301 /sse/ https://pydantic.dev/docs/httpx2/guides/sse/ 301 /troubleshooting https://pydantic.dev/docs/httpx2/guides/troubleshooting/ 301 /troubleshooting/ https://pydantic.dev/docs/httpx2/guides/troubleshooting/ 301 /websockets https://pydantic.dev/docs/httpx2/guides/websockets/ 301 /websockets/ https://pydantic.dev/docs/httpx2/guides/websockets/ 301 /api https://pydantic.dev/docs/httpx2/api/api/ 301 /api/ https://pydantic.dev/docs/httpx2/api/api/ 301 /environment_variables https://pydantic.dev/docs/httpx2/api/environment_variables/ 301 /environment_variables/ https://pydantic.dev/docs/httpx2/api/environment_variables/ 301 /exceptions https://pydantic.dev/docs/httpx2/api/exceptions/ 301 /exceptions/ https://pydantic.dev/docs/httpx2/api/exceptions/ 301 /code_of_conduct https://pydantic.dev/docs/httpx2/community/code_of_conduct/ 301 /code_of_conduct/ https://pydantic.dev/docs/httpx2/community/code_of_conduct/ 301 /contributing https://pydantic.dev/docs/httpx2/community/contributing/ 301 /contributing/ https://pydantic.dev/docs/httpx2/community/contributing/ 301 /third_party_packages https://pydantic.dev/docs/httpx2/community/third_party_packages/ 301 /third_party_packages/ https://pydantic.dev/docs/httpx2/community/third_party_packages/ 301 /objects.inv https://pydantic.dev/docs/httpx2/objects.inv 301 /sitemap.xml https://pydantic.dev/sitemap.xml 301 /favicon.ico https://pydantic.dev/favicon.ico 301 /img/butterfly.png https://pydantic.dev/docs/httpx2/img/butterfly.png 301 /img/gh-actions-fail-check.png https://pydantic.dev/docs/httpx2/img/gh-actions-fail-check.png 301 /img/gh-actions-fail-test.png https://pydantic.dev/docs/httpx2/img/gh-actions-fail-test.png 301 /img/gh-actions-fail.png https://pydantic.dev/docs/httpx2/img/gh-actions-fail.png 301 /img/logo.jpg https://pydantic.dev/docs/httpx2/img/logo.jpg 301 /img/rich-progress.gif https://pydantic.dev/docs/httpx2/img/rich-progress.gif 301 /img/tqdm-progress.gif https://pydantic.dev/docs/httpx2/img/tqdm-progress.gif 301 # Everything else, including pages that no longer exist. Splat rules lose to this # one in production, so every path we care about is listed explicitly above. /* https://pydantic.dev/docs/httpx2/get-started/ 301 pydantic-httpx2-6dd59b9/scripts/000077500000000000000000000000001526547463400167135ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/scripts/benchmark000077500000000000000000000004041526547463400205710ustar00rootroot00000000000000#!/bin/sh -e # Usage: scripts/benchmark [run.py options] # # scripts/benchmark --quick # scripts/benchmark --python main=../httpx2-main/.venv/bin/python --python work=.venv/bin/python # # See benchmark/README.md. exec uv run python benchmark/run.py "$@" pydantic-httpx2-6dd59b9/scripts/build000077500000000000000000000001571526547463400177430ustar00rootroot00000000000000#!/bin/sh -e set -x uv build --all-packages uv run twine check dist/* uv run zensical build -c -f mkdocs.yml pydantic-httpx2-6dd59b9/scripts/check000077500000000000000000000003641526547463400177210ustar00rootroot00000000000000#!/bin/sh -e export SOURCE_FILES="src/httpx2 tests/httpx2 src/httpcore2 tests/httpcore2 benchmark" set -x uv lock --check uv run ruff format --check --diff uv run mypy $SOURCE_FILES uv run ruff check uv run python scripts/unasync.py --check pydantic-httpx2-6dd59b9/scripts/coverage000077500000000000000000000001341526547463400204320ustar00rootroot00000000000000#!/bin/sh -e set -x uv run coverage report --show-missing --skip-covered --fail-under=100 pydantic-httpx2-6dd59b9/scripts/docs000077500000000000000000000000721526547463400175700ustar00rootroot00000000000000#!/bin/sh -e set -x uv run zensical serve -f mkdocs.yml pydantic-httpx2-6dd59b9/scripts/install000077500000000000000000000000471526547463400203100ustar00rootroot00000000000000#!/bin/sh -e set -x uv sync --frozen pydantic-httpx2-6dd59b9/scripts/lint000077500000000000000000000005501526547463400176070ustar00rootroot00000000000000#!/bin/sh -e export SOURCE_FILES="src/httpx2 tests/httpx2 src/httpcore2 tests/httpcore2 benchmark" set -x uv run ruff format $SOURCE_FILES uv run ruff check --fix $SOURCE_FILES # Run unasync last because its `--check` mode is not aware of code formatters. # (This means sync code isn't prettified, and that's mostly okay.) uv run python scripts/unasync.py pydantic-httpx2-6dd59b9/scripts/test000077500000000000000000000002461526547463400176220ustar00rootroot00000000000000#!/bin/sh set -ex if [ -z $GITHUB_ACTIONS ]; then scripts/check fi uv run coverage run -m pytest "$@" if [ -z $GITHUB_ACTIONS ]; then scripts/coverage fi pydantic-httpx2-6dd59b9/scripts/unasync.py000066400000000000000000000063051526547463400207510ustar00rootroot00000000000000#!venv/bin/python import os import re import sys from pprint import pprint SUBS = [ ( "from .._backends.auto import AutoBackend", "from .._backends.sync import SyncBackend", ), ("import trio as concurrency", "from tests.httpcore2 import concurrency"), ("AsyncIterator", "Iterator"), ("Async([A-Z][A-Za-z0-9_]*)", r"\2"), ("async def", "def"), ("async with", "with"), ("async for", "for"), ("await ", ""), ("handle_async_request", "handle_request"), ("aclose", "close"), ("aiter_stream", "iter_stream"), ("aread", "read"), ("asynccontextmanager", "contextmanager"), ("safe_async_iterate", "safe_iterate"), ("__aenter__", "__enter__"), ("__aexit__", "__exit__"), ("__aiter__", "__iter__"), ("@pytest.mark.anyio", ""), ("@pytest.mark.trio", ""), ("AutoBackend", "SyncBackend"), ] COMPILED_SUBS = [(re.compile(r"(^|\b)" + regex + r"($|\b)"), repl) for regex, repl in SUBS] USED_SUBS = set() def unasync_line(line): for index, (regex, repl) in enumerate(COMPILED_SUBS): old_line = line line = re.sub(regex, repl, line) if old_line != line: USED_SUBS.add(index) return line def unasync_file(in_path, out_path): with open(in_path) as in_file: with open(out_path, "w", newline="") as out_file: for line in in_file.readlines(): line = unasync_line(line) out_file.write(line) def unasync_file_check(in_path, out_path): with open(in_path) as in_file: with open(out_path) as out_file: for in_line, out_line in zip(in_file.readlines(), out_file.readlines(), strict=True): expected = unasync_line(in_line) if out_line != expected: print(f"unasync mismatch between {in_path!r} and {out_path!r}") print(f"Async code: {in_line!r}") print(f"Expected sync code: {expected!r}") print(f"Actual sync code: {out_line!r}") sys.exit(1) def unasync_dir(in_dir, out_dir, check_only=False): for dirpath, _dirnames, filenames in os.walk(in_dir): for filename in filenames: if not filename.endswith(".py"): continue rel_dir = os.path.relpath(dirpath, in_dir) in_path = os.path.normpath(os.path.join(in_dir, rel_dir, filename)) out_path = os.path.normpath(os.path.join(out_dir, rel_dir, filename)) print(in_path, "->", out_path) if check_only: unasync_file_check(in_path, out_path) else: unasync_file(in_path, out_path) def main(): check_only = "--check" in sys.argv unasync_dir( "src/httpcore2/httpcore2/_async", "src/httpcore2/httpcore2/_sync", check_only=check_only, ) unasync_dir( "tests/httpcore2/_async", "tests/httpcore2/_sync", check_only=check_only, ) if len(USED_SUBS) != len(SUBS): unused_subs = [SUBS[i] for i in range(len(SUBS)) if i not in USED_SUBS] print("These patterns were not used:") pprint(unused_subs) exit(1) if __name__ == "__main__": main() pydantic-httpx2-6dd59b9/src/000077500000000000000000000000001526547463400160135ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/src/httpcore2/000077500000000000000000000000001526547463400177255ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/src/httpcore2/.gitignore000066400000000000000000000001701526547463400217130ustar00rootroot00000000000000*.pyc .coverage .pytest_cache/ .mypy_cache/ __pycache__/ htmlcov/ site/ *.egg-info/ venv*/ .python-version build/ dist/ pydantic-httpx2-6dd59b9/src/httpcore2/CHANGELOG.md000066400000000000000000000535771526547463400215570ustar00rootroot00000000000000# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## 2.15.1 (October 19th, 2026) ### Fixed * Configure the default SSL context once on Linux, instead of on every handshake. With OpenSSL older than 3.4, CPU usage grew over the lifetime of a reused client. ([#1253](https://github.com/pydantic/httpx2/pull/1253)) ## 2.15.0 (October 19th, 2026) ### Removed * Drop support for Python 3.10. ([#1274](https://github.com/pydantic/httpx2/pull/1274)) ## 2.14.0 (October 18th, 2026) ### Fixed * Keep `CONNECT` and absolute-form proxy targets when the request sets the `target` extension. ([#1262](https://github.com/pydantic/httpx2/pull/1262)) * Stop blocking reads when an HTTP/2 server lowers `SETTINGS_MAX_CONCURRENT_STREAMS` while requests are in flight. ([#1217](https://github.com/pydantic/httpx2/pull/1217)) * Raise `WriteError` instead of `anyio.EndOfStream` when writing after the peer closes a TLS connection without `close_notify`. ([#1263](https://github.com/pydantic/httpx2/pull/1263)) ## 2.13.1 (September 23rd, 2026) ### Fixed * Honor the `sni_hostname` extension for TLS inside HTTP proxy tunnels without applying it to the proxy's TLS connection. ([#1223](https://github.com/pydantic/httpx2/pull/1223)) * Prefer HTTP/2 during TLS protocol negotiation when enabled, and stop advertising HTTP/1.1 when it is disabled. ([#1155](https://github.com/pydantic/httpx2/pull/1155)) ## 2.13.0 (September 14th, 2026) ### Changed * Require Trio 0.34.0 or later for the `trio` extra. ([#1179](https://github.com/pydantic/httpx2/pull/1179)) ### Fixed * Avoid nested async generator finalization errors when streamed responses are abandoned early. ([#1204](https://github.com/pydantic/httpx2/pull/1204)) ## 2.12.0 (August 18th, 2026) No changes since `2.11.0`. Version bumped to stay in lockstep with `httpx2`. ## 2.11.0 (August 18th, 2026) ### Changed * Cache sniffio availability instead of importing it on every synchronization call. ([#1132](https://github.com/pydantic/httpx2/pull/1132)) ## 2.10.0 (August 9th, 2026) ### Added * Add support for Python 3.15. ([#1090](https://github.com/pydantic/httpx2/pull/1090)) ### Changed * Avoid quadratic copying when sending large HTTP/2 request bodies. ([#1127](https://github.com/pydantic/httpx2/pull/1127)) ### Fixed * Propagate the original exception instead of raising `KeyError` when an HTTP/2 stream fails. ([#1093](https://github.com/pydantic/httpx2/pull/1093)) * Start TLS for the `wss` scheme in SOCKS5 proxy connections. ([#1104](https://github.com/pydantic/httpx2/pull/1104)) ## 2.9.1 (July 24th, 2026) No changes since `2.9.0`. Version bumped to stay in lockstep with `httpx2`. ## 2.9.0 (July 23rd, 2026) No changes since `2.8.0`. Version bumped to stay in lockstep with `httpx2`. ## 2.8.0 (July 23rd, 2026) ### Changed * Assign each released connection to a single queued request, eliminating multi-assignment churn in the connection pool. ([#1075](https://github.com/pydantic/httpx2/pull/1075)) ## 2.7.0 (July 14th, 2026) No changes since `2.6.0`. Version bumped to stay in lockstep with `httpx2`. ## 2.6.0 (July 14th, 2026) ### Fixed * Clean up garbage connections on cancellation in `AsyncConnectionPool`. ([#983](https://github.com/pydantic/httpx2/pull/983)) * Read `_expire_at` only once in `has_expired()`. ([#1045](https://github.com/pydantic/httpx2/pull/1045)) ## 2.5.0 (June 25th, 2026) ### Fixed * Propagate the timeout through the SOCKS5 handshake. ([#1009](https://github.com/pydantic/httpx2/pull/1009)) ## 2.4.0 (June 11th, 2026) ### Fixed * Move HTTP/2 stream events cleanup inside `_state_lock`. ([#1013](https://github.com/pydantic/httpx2/pull/1013)) * Release the HTTP/2 semaphore permit on `NoAvailableStreamIDError`. ([#1012](https://github.com/pydantic/httpx2/pull/1012)) * Use `RLock` instead of `Lock` to prevent a thread deadlock. ([#1008](https://github.com/pydantic/httpx2/pull/1008)) ## 2.3.0 (June 1st, 2026) ### Changed * Use `truststore` instead of `certifi` for default SSL verification, loading the operating system's trust store. ([#1002](https://github.com/pydantic/httpx2/pull/1002)) * Rewrite `_assign_requests_to_connections` as a single-pass loop. ([#974](https://github.com/pydantic/httpx2/pull/974)) * Use `anyio`'s `fast_acquire` for `Lock` and `Semaphore`. ([#970](https://github.com/pydantic/httpx2/pull/970)) * Use `memoryview` in `write()` to avoid copies. ([#954](https://github.com/pydantic/httpx2/pull/954)) ## 2.2.0 (May 16th, 2026) No changes since `2.1.0`. Version bumped to stay in lockstep with `httpx2`. ## 2.1.0 (May 15th, 2026) ### Removed * Drop support for Python 3.8 and 3.9. ([#208](https://github.com/pydantic/httpx2/pull/208)) ### Added * Add support for Python 3.14. ([#208](https://github.com/pydantic/httpx2/pull/208)) * Bundle `LICENSE.md` in the sdist. ([#938](https://github.com/pydantic/httpx2/pull/938)) ### Fixed * Wait for positive flow-control credit when a peer's `SETTINGS` frame drives a stream's send window negative, instead of letting h2 raise `LocalProtocolError`. ([#935](https://github.com/pydantic/httpx2/pull/935)) ## 2.0.0 Official first release of `httpcore2`. No changes since `2.0.0b1`. ## 2.0.0b1 First release of `httpcore2`, a fork of [`httpcore`](https://github.com/encode/httpcore) maintained by Pydantic. Forked from `httpcore 1.0.9`. ### Breaking changes * **Renamed package**: `httpcore` -> `httpcore2`. `import httpcore` becomes `import httpcore2`. No other public API changed. ### Fixed * Fix `max_keepalive_connections` not being properly handled. (Inherited from upstream PR [encode/httpcore#1000](https://github.com/encode/httpcore/pull/1000).) --- Historical entries below are from upstream `encode/httpcore`. ## Version 1.0.9 (April 24th, 2025) - Resolve https://github.com/advisories/GHSA-vqfr-h8mv-ghfj with h11 dependency update. (#1008) ## Version 1.0.8 (April 11th, 2025) - Fix `AttributeError` when importing on Python 3.14. (#1005) ## Version 1.0.7 (November 15th, 2024) - Support `proxy=โ€ฆ` configuration on `ConnectionPool()`. (#974) ## Version 1.0.6 (October 1st, 2024) - Relax `trio` dependency pinning. (#956) - Handle `trio` raising `NotImplementedError` on unsupported platforms. (#955) - Handle mapping `ssl.SSLError` to `httpcore.ConnectError`. (#918) ## 1.0.5 (March 27th, 2024) - Handle `EndOfStream` exception for anyio backend. (#899) - Allow trio `0.25.*` series in package dependencies. (#903) ## 1.0.4 (February 21st, 2024) - Add `target` request extension. (#888) - Fix support for connection `Upgrade` and `CONNECT` when some data in the stream has been read. (#882) ## 1.0.3 (February 13th, 2024) - Fix support for async cancellations. (#880) - Fix trace extension when used with socks proxy. (#849) - Fix SSL context for connections using the "wss" scheme (#869) ## 1.0.2 (November 10th, 2023) - Fix `float("inf")` timeouts in `Event.wait` function. (#846) ## 1.0.1 (November 3rd, 2023) - Fix pool timeout to account for the total time spent retrying. (#823) - Raise a neater RuntimeError when the correct async deps are not installed. (#826) - Add support for synchronous TLS-in-TLS streams. (#840) ## 1.0.0 (October 6th, 2023) From version 1.0 our async support is now optional, as the package has minimal dependencies by default. For async support use either `pip install 'httpcore[asyncio]'` or `pip install 'httpcore[trio]'`. The project versioning policy is now explicitly governed by SEMVER. See https://semver.org/. - Async support becomes fully optional. (#809) - Add support for Python 3.12. (#807) ## 0.18.0 (September 8th, 2023) - Add support for HTTPS proxies. (#745, #786) - Drop Python 3.7 support. (#727) - Handle `sni_hostname` extension with SOCKS proxy. (#774) - Handle HTTP/1.1 half-closed connections gracefully. (#641) - Change the type of `Extensions` from `Mapping[Str, Any]` to `MutableMapping[Str, Any]`. (#762) ## 0.17.3 (July 5th, 2023) - Support async cancellations, ensuring that the connection pool is left in a clean state when cancellations occur. (#726) - The networking backend interface has [been added to the public API](https://www.encode.io/httpcore/network-backends). Some classes which were previously private implementation detail are now part of the top-level public API. (#699) - Graceful handling of HTTP/2 GoAway frames, with requests being transparently retried on a new connection. (#730) - Add exceptions when a synchronous `trace callback` is passed to an asynchronous request or an asynchronous `trace callback` is passed to a synchronous request. (#717) - Drop Python 3.7 support. (#727) ## 0.17.2 (May 23th, 2023) - Add `socket_options` argument to `ConnectionPool` and `HTTProxy` classes. (#668) - Improve logging with per-module logger names. (#690) - Add `sni_hostname` request extension. (#696) - Resolve race condition during import of `anyio` package. (#692) - Enable TCP_NODELAY for all synchronous sockets. (#651) ## 0.17.1 (May 17th, 2023) - If 'retries' is set, then allow retries if an SSL handshake error occurs. (#669) - Improve correctness of tracebacks on network exceptions, by raising properly chained exceptions. (#678) - Prevent connection-hanging behaviour when HTTP/2 connections are closed by a server-sent 'GoAway' frame. (#679) - Fix edge-case exception when removing requests from the connection pool. (#680) - Fix pool timeout edge-case. (#688) ## 0.17.0 (March 16th, 2023) - Add DEBUG level logging. (#648) - Respect HTTP/2 max concurrent streams when settings updates are sent by server. (#652) - Increase the allowable HTTP header size to 100kB. (#647) - Add `retries` option to SOCKS proxy classes. (#643) ## 0.16.3 (December 20th, 2022) - Allow `ws` and `wss` schemes. Allows us to properly support websocket upgrade connections. (#625) - Forwarding HTTP proxies use a connection-per-remote-host. Required by some proxy implementations. (#637) - Don't raise `RuntimeError` when closing a connection pool with active connections. Removes some error cases when cancellations are used. (#631) - Lazy import `anyio`, so that it's no longer a hard dependency, and isn't imported if unused. (#639) ## 0.16.2 (November 25th, 2022) - Revert 'Fix async cancellation behaviour', which introduced race conditions. (#627) - Raise `RuntimeError` if attempting to us UNIX domain sockets on Windows. (#619) ## 0.16.1 (November 17th, 2022) - Fix HTTP/1.1 interim informational responses, such as "100 Continue". (#605) ## 0.16.0 (October 11th, 2022) - Support HTTP/1.1 informational responses. (#581) - Fix async cancellation behaviour. (#580) - Support `h11` 0.14. (#579) ## 0.15.0 (May 17th, 2022) - Drop Python 3.6 support (#535) - Ensure HTTP proxy CONNECT requests include `timeout` configuration. (#506) - Switch to explicit `typing.Optional` for type hints. (#513) - For `trio` map OSError exceptions to `ConnectError`. (#543) ## 0.14.7 (February 4th, 2022) - Requests which raise a PoolTimeout need to be removed from the pool queue. (#502) - Fix AttributeError that happened when Socks5Connection were terminated. (#501) ## 0.14.6 (February 1st, 2022) - Fix SOCKS support for `http://` URLs. (#492) - Resolve race condition around exceptions during streaming a response. (#491) ## 0.14.5 (January 18th, 2022) - SOCKS proxy support. (#478) - Add proxy_auth argument to HTTPProxy. (#481) - Improve error message on 'RemoteProtocolError' exception when server disconnects without sending a response. (#479) ## 0.14.4 (January 5th, 2022) - Support HTTP/2 on HTTPS tunnelling proxies. (#468) - Fix proxy headers missing on HTTP forwarding. (#456) - Only instantiate SSL context if required. (#457) - More robust HTTP/2 handling. (#253, #439, #440, #441) ## 0.14.3 (November 17th, 2021) - Fix race condition when removing closed connections from the pool. (#437) ## 0.14.2 (November 16th, 2021) - Failed connections no longer remain in the pool. (Pull #433) ## 0.14.1 (November 12th, 2021) - `max_connections` becomes optional. (Pull #429) - `certifi` is now included in the install dependencies. (Pull #428) - `h2` is now strictly optional. (Pull #428) ## 0.14.0 (November 11th, 2021) The 0.14 release is a complete reworking of `httpcore`, comprehensively addressing some underlying issues in the connection pooling, as well as substantially redesigning the API to be more user friendly. Some of the lower-level API design also makes the components more easily testable in isolation, and the package now has 100% test coverage. See [discussion #419](https://github.com/encode/httpcore/discussions/419) for a little more background. There's some other neat bits in there too, such as the "trace" extension, which gives a hook into inspecting the internal events that occur during the request/response cycle. This extension is needed for the HTTPX cli, in order to... * Log the point at which the connection is established, and the IP/port on which it is made. * Determine if the outgoing request should log as HTTP/1.1 or HTTP/2, rather than having to assume it's HTTP/2 if the --http2 flag was passed. (Which may not actually be true.) * Log SSL version info / certificate info. Note that `curio` support is not currently available in 0.14.0. If you're using `httpcore` with `curio` please get in touch, so we can assess if we ought to prioritize it as a feature or not. ## 0.13.7 (September 13th, 2021) - Fix broken error messaging when URL scheme is missing, or a non HTTP(S) scheme is used. (Pull #403) ## 0.13.6 (June 15th, 2021) ### Fixed - Close sockets when read or write timeouts occur. (Pull #365) ## 0.13.5 (June 14th, 2021) ### Fixed - Resolved niggles with AnyIO EOF behaviours. (Pull #358, #362) ## 0.13.4 (June 9th, 2021) ### Added - Improved error messaging when URL scheme is missing, or a non HTTP(S) scheme is used. (Pull #354) ### Fixed - Switched to `anyio` as the default backend implementation when running with `asyncio`. Resolves some awkward [TLS timeout issues](https://github.com/encode/httpx/discussions/1511). ## 0.13.3 (May 6th, 2021) ### Added - Support HTTP/2 prior knowledge, using `httpcore.SyncConnectionPool(http1=False)`. (Pull #333) ### Fixed - Handle cases where environment does not provide `select.poll` support. (Pull #331) ## 0.13.2 (April 29th, 2021) ### Added - Improve error message for specific case of `RemoteProtocolError` where server disconnects without sending a response. (Pull #313) ## 0.13.1 (April 28th, 2021) ### Fixed - More resilient testing for closed connections. (Pull #311) - Don't raise exceptions on ungraceful connection closes. (Pull #310) ## 0.13.0 (April 21st, 2021) The 0.13 release updates the core API in order to match the HTTPX Transport API, introduced in HTTPX 0.18 onwards. An example of making requests with the new interface is: ```python with httpcore.SyncConnectionPool() as http: status_code, headers, stream, extensions = http.handle_request( method=b'GET', url=(b'https', b'example.org', 443, b'/'), headers=[(b'host', b'example.org'), (b'user-agent', b'httpcore')] stream=httpcore.ByteStream(b''), extensions={} ) body = stream.read() print(status_code, body) ``` ### Changed - The `.request()` method is now `handle_request()`. (Pull #296) - The `.arequest()` method is now `.handle_async_request()`. (Pull #296) - The `headers` argument is no longer optional. (Pull #296) - The `stream` argument is no longer optional. (Pull #296) - The `ext` argument is now named `extensions`, and is no longer optional. (Pull #296) - The `"reason"` extension keyword is now named `"reason_phrase"`. (Pull #296) - The `"reason_phrase"` and `"http_version"` extensions now use byte strings for their values. (Pull #296) - The `httpcore.PlainByteStream()` class becomes `httpcore.ByteStream()`. (Pull #296) ### Added - Streams now support a `.read()` interface. (Pull #296) ### Fixed - Task cancellation no longer leaks connections from the connection pool. (Pull #305) ## 0.12.3 (December 7th, 2020) ### Fixed - Abort SSL connections on close rather than waiting for remote EOF when using `asyncio`. (Pull #167) - Fix exception raised in case of connect timeouts when using the `anyio` backend. (Pull #236) - Fix `Host` header precedence for `:authority` in HTTP/2. (Pull #241, #243) - Handle extra edge case when detecting for socket readability when using `asyncio`. (Pull #242, #244) - Fix `asyncio` SSL warning when using proxy tunneling. (Pull #249) ## 0.12.2 (November 20th, 2020) ### Fixed - Properly wrap connect errors on the asyncio backend. (Pull #235) - Fix `ImportError` occurring on Python 3.9 when using the HTTP/1.1 sync client in a multithreaded context. (Pull #237) ## 0.12.1 (November 7th, 2020) ### Added - Add connect retries. (Pull #221) ### Fixed - Tweak detection of dropped connections, resolving an issue with open files limits on Linux. (Pull #185) - Avoid leaking connections when establishing an HTTP tunnel to a proxy has failed. (Pull #223) - Properly wrap OS errors when using `trio`. (Pull #225) ## 0.12.0 (October 6th, 2020) ### Changed - HTTP header casing is now preserved, rather than always sent in lowercase. (#216 and python-hyper/h11#104) ### Added - Add Python 3.9 to officially supported versions. ### Fixed - Gracefully handle a stdlib asyncio bug when a connection is closed while it is in a paused-for-reading state. (#201) ## 0.11.1 (September 28nd, 2020) ### Fixed - Add await to async semaphore release() coroutine (#197) - Drop incorrect curio classifier (#192) ## 0.11.0 (September 22nd, 2020) The Transport API with 0.11.0 has a couple of significant changes. Firstly we've moved changed the request interface in order to allow extensions, which will later enable us to support features such as trailing headers, HTTP/2 server push, and CONNECT/Upgrade connections. The interface changes from: ```python def request(method, url, headers, stream, timeout): return (http_version, status_code, reason, headers, stream) ``` To instead including an optional dictionary of extensions on the request and response: ```python def request(method, url, headers, stream, ext): return (status_code, headers, stream, ext) ``` Having an open-ended extensions point will allow us to add later support for various optional features, that wouldn't otherwise be supported without these API changes. In particular: * Trailing headers support. * HTTP/2 Server Push * sendfile. * Exposing raw connection on CONNECT, Upgrade, HTTP/2 bi-di streaming. * Exposing debug information out of the API, including template name, template context. Currently extensions are limited to: * request: `timeout` - Optional. Timeout dictionary. * response: `http_version` - Optional. Include the HTTP version used on the response. * response: `reason` - Optional. Include the reason phrase used on the response. Only valid with HTTP/1.*. See https://github.com/encode/httpx/issues/1274#issuecomment-694884553 for the history behind this. Secondly, the async version of `request` is now namespaced as `arequest`. This allows concrete transports to support both sync and async implementations on the same class. ### Added - Add curio support. (Pull #168) - Add anyio support, with `backend="anyio"`. (Pull #169) ### Changed - Update the Transport API to use 'ext' for optional extensions. (Pull #190) - Update the Transport API to use `.request` and `.arequest` so implementations can support both sync and async. (Pull #189) ## 0.10.2 (August 20th, 2020) ### Added - Added Unix Domain Socket support. (Pull #139) ### Fixed - Always include the port on proxy CONNECT requests. (Pull #154) - Fix `max_keepalive_connections` configuration. (Pull #153) - Fixes behaviour in HTTP/1.1 where server disconnects can be used to signal the end of the response body. (Pull #164) ## 0.10.1 (August 7th, 2020) - Include `max_keepalive_connections` on `AsyncHTTPProxy`/`SyncHTTPProxy` classes. ## 0.10.0 (August 7th, 2020) The most notable change in the 0.10.0 release is that HTTP/2 support is now fully optional. Use either `pip install httpcore` for HTTP/1.1 support only, or `pip install httpcore[http2]` for HTTP/1.1 and HTTP/2 support. ### Added - HTTP/2 support becomes optional. (Pull #121, #130) - Add `local_address=...` support. (Pull #100, #134) - Add `PlainByteStream`, `IteratorByteStream`, `AsyncIteratorByteStream`. The `AsyncByteSteam` and `SyncByteStream` classes are now pure interface classes. (#133) - Add `LocalProtocolError`, `RemoteProtocolError` exceptions. (Pull #129) - Add `UnsupportedProtocol` exception. (Pull #128) - Add `.get_connection_info()` method. (Pull #102, #137) - Add better TRACE logs. (Pull #101) ### Changed - `max_keepalive` is deprecated in favour of `max_keepalive_connections`. (Pull #140) ### Fixed - Improve handling of server disconnects. (Pull #112) ## 0.9.1 (May 27th, 2020) ### Fixed - Proper host resolution for sync case, including IPv6 support. (Pull #97) - Close outstanding connections when connection pool is closed. (Pull #98) ## 0.9.0 (May 21th, 2020) ### Changed - URL port becomes an `Optional[int]` instead of `int`. (Pull #92) ### Fixed - Honor HTTP/2 max concurrent streams settings. (Pull #89, #90) - Remove incorrect debug log. (Pull #83) ## 0.8.4 (May 11th, 2020) ### Added - Logging via HTTPCORE_LOG_LEVEL and HTTPX_LOG_LEVEL environment variables and TRACE level logging. (Pull #79) ### Fixed - Reuse of connections on HTTP/2 in close concurrency situations. (Pull #81) ## 0.8.3 (May 6rd, 2020) ### Fixed - Include `Host` and `Accept` headers on proxy "CONNECT" requests. - De-duplicate any headers also contained in proxy_headers. - HTTP/2 flag not being passed down to proxy connections. ## 0.8.2 (May 3rd, 2020) ### Fixed - Fix connections using proxy forwarding requests not being added to the connection pool properly. (Pull #70) ## 0.8.1 (April 30th, 2020) ### Changed - Allow inherintance of both `httpcore.AsyncByteStream`, `httpcore.SyncByteStream` without type conflicts. ## 0.8.0 (April 30th, 2020) ### Fixed - Fixed tunnel proxy support. ###ย Added - New `TimeoutException` base class. ## 0.7.0 (March 5th, 2020) - First integration with HTTPX. pydantic-httpx2-6dd59b9/src/httpcore2/LICENSE.md000066400000000000000000000030771526547463400213400ustar00rootroot00000000000000Copyright ยฉ 2026 to present Pydantic Services Inc. and individual contributors. Copyright ยฉ 2020, [Encode OSS Ltd](https://www.encode.io/). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * 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 HOLDER 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. pydantic-httpx2-6dd59b9/src/httpcore2/README.md000066400000000000000000000065061526547463400212130ustar00rootroot00000000000000# HTTPCore 2 [![Test Suite](https://github.com/pydantic/httpx2/workflows/Test%20Suite/badge.svg)](https://github.com/pydantic/httpx2/actions) [![Package version](https://badge.fury.io/py/httpcore2.svg)](https://pypi.org/project/httpcore2/) > *Do one thing, and do it well.* The HTTPCore 2 package provides a minimal low-level HTTP client, which does one thing only. Sending HTTP requests. It does not provide any high level model abstractions over the API, does not handle redirects, multipart uploads, building authentication headers, transparent HTTP caching, URL parsing, session cookie handling, content or charset decoding, handling JSON, environment based configuration defaults, or any of that Jazz. Some things HTTPCore 2 does do: * Sending HTTP requests. * Thread-safe / task-safe connection pooling. * HTTP(S) proxy & SOCKS proxy support. * Supports HTTP/1.1 and HTTP/2. * Provides both sync and async interfaces. * Async backend support for `asyncio` and `trio`. ## Installation For HTTP/1.1 only support, install with: ```shell pip install httpcore2 ``` There are also a number of optional extras available... ```shell pip install 'httpcore2[asyncio,trio,http2,socks]' ``` ## Sending requests Send an HTTP request: ```python import httpcore2 response = httpcore2.request("GET", "https://www.example.com/") print(response) # print(response.status) # 200 print(response.headers) # [(b'Accept-Ranges', b'bytes'), (b'Age', b'557328'), (b'Cache-Control', b'max-age=604800'), ...] print(response.content) # b'\n\n\nExample Domain\n\n\n ...' ``` The top-level `httpcore2.request()` function is provided for convenience. In practice whenever you're working with `httpcore2` you'll want to use the connection pooling functionality that it provides. ```python import httpcore2 http = httpcore2.ConnectionPool() response = http.request("GET", "https://www.example.com/") ``` Once you're ready to get going, [head over to the documentation](https://github.com/pydantic/httpx2/tree/main/src/httpcore2/docs). ## Motivation You *probably* don't want to be using HTTPCore 2 directly. It might make sense if you're writing something like a proxy service in Python, and you just want something at the lowest possible level, but more typically you'll want to use a higher level client library, such as `httpx2`. The motivation for `httpcore2` is: * To provide a reusable low-level client library, that other packages can then build on top of. * To provide a *really clear interface split* between the networking code and client logic, so that each is easier to understand and reason about in isolation. ## Dependencies The `httpcore2` package has the following dependencies... * `h11` * `truststore` And the following optional extras... * `anyio` - Required by `pip install 'httpcore2[asyncio]'`. * `trio` - Required by `pip install 'httpcore2[trio]'`. * `h2` - Required by `pip install 'httpcore2[http2]'`. * `socksio` - Required by `pip install 'httpcore2[socks]'`. ## Versioning We use [SEMVER for our versioning policy](https://semver.org/). For changes between package versions please see our [project changelog](CHANGELOG.md). We recommend pinning your requirements either the most current major version, or a more specific version range: ```shell pip install 'httpcore2==2.*' ``` pydantic-httpx2-6dd59b9/src/httpcore2/docs/000077500000000000000000000000001526547463400206555ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/src/httpcore2/docs/async.md000066400000000000000000000161361526547463400223230ustar00rootroot00000000000000# Async Support HTTPX offers a standard synchronous API by default, but also gives you the option of an async client if you need it. Async is a concurrency model that is far more efficient than multi-threading, and can provide significant performance benefits and enable the use of long-lived network connections such as WebSockets. If you're working with an async web framework then you'll also want to use an async client for sending outgoing HTTP requests. Launching concurrent async tasks is far more resource efficient than spawning multiple threads. The Python interpreter should be able to comfortably handle switching between over 1000 concurrent tasks, while a sensible number of threads in a thread pool might be to enable around 10 or 20 concurrent threads. ## Enabling Async support If you're using async with [Python's stdlib `asyncio` support](https://docs.python.org/3/library/asyncio.html), install the optional dependencies using: ```shell pip install 'httpcore2[asyncio]' ``` Alternatively, if you're working with [the Python `trio` package](https://trio.readthedocs.io/en/stable/): ```shell pip install 'httpcore2[trio]' ``` We highly recommend `trio` for async support. The `trio` project [pioneered the principles of structured concurrency](https://en.wikipedia.org/wiki/Structured_concurrency), and has a more carefully constrained API against which to work from. ## API differences When using async support, you need make sure to use an async connection pool class: ```python # The async variation of `httpcore2.ConnectionPool` async with httpcore2.AsyncConnectionPool() as http: ... ``` ### Sending requests Sending requests with the async version of `httpcore2` requires the `await` keyword: ```python import asyncio import httpcore2 async def main(): async with httpcore2.AsyncConnectionPool() as http: response = await http.request("GET", "https://www.example.com/") asyncio.run(main()) ``` When including content in the request, the content must either be bytes or an *async iterable* yielding bytes. ### Streaming responses Streaming responses also require a slightly different interface to the sync version: * `with .stream(...) as response` โ†’ `async with .stream() as response`. * `for chunk in response.iter_stream()` โ†’ `async for chunk in response.aiter_stream()`. * `response.read()` โ†’ `await response.aread()`. * `response.close()` โ†’ `await response.aclose()` For example: ```python import asyncio import httpcore2 async def main(): async with httpcore2.AsyncConnectionPool() as http: async with http.stream("GET", "https://www.example.com/") as response: async for chunk in response.aiter_stream(): print(f"Downloaded: {chunk}") asyncio.run(main()) ``` ### Pool lifespans When using `httpcore2` in an async environment it is strongly recommended that you instantiate and use connection pools using the context managed style: ```python async with httpcore2.AsyncConnectionPool() as http: ... ``` To benefit from connection pooling it is recommended that you instantiate a single connection pool in this style, and pass it around throughout your application. If you do want to use a connection pool without this style then you'll need to ensure that you explicitly close the pool once it is no longer required: ```python try: http = httpcore2.AsyncConnectionPool() ... finally: await http.aclose() ``` This is a little different to the threaded context, where it's okay to simply instantiate a globally available connection pool, and then allow Python's garbage collection to deal with closing any connections in the pool, once the `__del__` method is called. The reason for this difference is that asynchronous code is not able to run within the context of the synchronous `__del__` method, so there is no way for connections to be automatically closed at the point of garbage collection. This can lead to unterminated TCP connections still remaining after the Python interpreter quits. ## Supported environments HTTPX supports either `asyncio` or `trio` as an async environment. It will auto-detect which of those two to use as the backend for socket operations and concurrency primitives. ### AsyncIO AsyncIO is Python's [built-in library](https://docs.python.org/3/library/asyncio.html) for writing concurrent code with the async/await syntax. Let's take a look at sending several outgoing HTTP requests concurrently, using `asyncio`: ```python import asyncio import httpcore2 import time async def download(http, year): await http.request("GET", f"https://en.wikipedia.org/wiki/{year}") async def main(): async with httpcore2.AsyncConnectionPool() as http: started = time.time() # Here we use `asyncio.gather()` in order to run several tasks concurrently... tasks = [download(http, year) for year in range(2000, 2020)] await asyncio.gather(*tasks) complete = time.time() for connection in http.connections: print(connection) print("Complete in %.3f seconds" % (complete - started)) asyncio.run(main()) ``` ### Trio Trio is [an alternative async library](https://trio.readthedocs.io/en/stable/), designed around the [the principles of structured concurrency](https://en.wikipedia.org/wiki/Structured_concurrency). ```python import httpcore2 import trio import time async def download(http, year): await http.request("GET", f"https://en.wikipedia.org/wiki/{year}") async def main(): async with httpcore2.AsyncConnectionPool() as http: started = time.time() async with trio.open_nursery() as nursery: for year in range(2000, 2020): nursery.start_soon(download, http, year) complete = time.time() for connection in http.connections: print(connection) print("Complete in %.3f seconds" % (complete - started)) trio.run(main) ``` ### AnyIO AnyIO is an [asynchronous networking and concurrency library](https://anyio.readthedocs.io/) that works on top of either asyncio or trio. It blends in with native libraries of your chosen backend (defaults to asyncio). The `anyio` library is designed around the [the principles of structured concurrency](https://en.wikipedia.org/wiki/Structured_concurrency), and brings many of the same correctness and usability benefits that Trio provides, while interoperating with existing `asyncio` libraries. ```python import httpcore2 import anyio import time async def download(http, year): await http.request("GET", f"https://en.wikipedia.org/wiki/{year}") async def main(): async with httpcore2.AsyncConnectionPool() as http: started = time.time() async with anyio.create_task_group() as task_group: for year in range(2000, 2020): task_group.start_soon(download, http, year) complete = time.time() for connection in http.connections: print(connection) print("Complete in %.3f seconds" % (complete - started)) anyio.run(main) ``` --- # Reference ## `httpcore2.AsyncConnectionPool` ::: httpcore2.AsyncConnectionPool handler: python rendering: show_source: False pydantic-httpx2-6dd59b9/src/httpcore2/docs/connection-pools.md000066400000000000000000000106511526547463400244730ustar00rootroot00000000000000# Connection Pools While the top-level API provides convenience functions for working with `httpcore2`, in practice you'll almost always want to take advantage of the connection pooling functionality that it provides. To do so, instantiate a pool instance, and use it to send requests: ```python import httpcore2 http = httpcore2.ConnectionPool() r = http.request("GET", "https://www.example.com/") print(r) # ``` Connection pools support the same `.request()` and `.stream()` APIs [as described in the Quickstart](../quickstart). We can observe the benefits of connection pooling with a simple script like so: ```python import httpcore2 import time http = httpcore2.ConnectionPool() for counter in range(5): started = time.time() response = http.request("GET", "https://www.example.com/") complete = time.time() print(response, "in %.3f seconds" % (complete - started)) ``` The output *should* demonstrate the initial request as being substantially slower than the subsequent requests: ``` in {0.529} seconds in {0.096} seconds in {0.097} seconds in {0.095} seconds in {0.098} seconds ``` This is to be expected. Once we've established a connection to `"www.example.com"` we're able to reuse it for following requests. ## Configuration The connection pool instance is also the main point of configuration. Let's take a look at the various options that it provides: ### SSL configuration * `ssl_context`: An SSL context to use for verifying connections. If not specified, the default `httpcore2.default_ssl_context()` will be used. ### Pooling configuration * `max_connections`: The maximum number of concurrent HTTP connections that the pool should allow. Any attempt to send a request on a pool that would exceed this amount will block until a connection is available. * `max_keepalive_connections`: The maximum number of idle HTTP connections that will be maintained in the pool. * `keepalive_expiry`: The duration in seconds that an idle HTTP connection may be maintained for before being expired from the pool. ### HTTP version support * `http1`: A boolean indicating if HTTP/1.1 requests should be supported by the connection pool. Defaults to `True`. * `http2`: A boolean indicating if HTTP/2 requests should be supported by the connection pool. Defaults to `False`. ### Other options * `retries`: The maximum number of retries when trying to establish a connection. * `local_address`: Local address to connect from. Can also be used to connect using a particular address family. Using `local_address="0.0.0.0"` will connect using an `AF_INET` address (IPv4), while using `local_address="::"` will connect using an `AF_INET6` address (IPv6). * `uds`: Path to a Unix Domain Socket to use instead of TCP sockets. * `network_backend`: A backend instance to use for handling network I/O. * `socket_options`: Socket options that have to be included in the TCP socket when the connection was established. ## Pool lifespans Because connection pools hold onto network resources, careful developers may want to ensure that instances are properly closed once they are no longer required. Working with a single global instance isn't a bad idea for many use case, since the connection pool will automatically be closed when the `__del__` method is called on it: ```python # This is perfectly fine for most purposes. # The connection pool will automatically be closed when it is garbage collected, # or when the Python interpreter exits. http = httpcore2.ConnectionPool() ``` However, to be more explicit around the resource usage, we can use the connection pool within a context manager: ```python with httpcore2.ConnectionPool() as http: ... ``` Or else close the pool explicitly: ```python http = httpcore2.ConnectionPool() try: ... finally: http.close() ``` ## Thread and task safety Connection pools are designed to be thread-safe. Similarly, when using `httpcore2` in an async context connection pools are task-safe. This means that you can have a single connection pool instance shared by multiple threads. --- # Reference ## `httpcore2.ConnectionPool` ::: httpcore2.ConnectionPool handler: python rendering: show_source: False pydantic-httpx2-6dd59b9/src/httpcore2/docs/connections.md000066400000000000000000000006351526547463400235250ustar00rootroot00000000000000# Connections TODO --- # Reference ## `httpcore2.HTTPConnection` ::: httpcore2.HTTPConnection handler: python rendering: show_source: False ## `httpcore2.HTTP11Connection` ::: httpcore2.HTTP11Connection handler: python rendering: show_source: False ## `httpcore2.HTTP2Connection` ::: httpcore2.HTTP2Connection handler: python rendering: show_source: False pydantic-httpx2-6dd59b9/src/httpcore2/docs/exceptions.md000066400000000000000000000007761526547463400233720ustar00rootroot00000000000000# Exceptions The following exceptions may be raised when sending a request: * `httpcore2.TimeoutException` * `httpcore2.PoolTimeout` * `httpcore2.ConnectTimeout` * `httpcore2.ReadTimeout` * `httpcore2.WriteTimeout` * `httpcore2.NetworkError` * `httpcore2.ConnectError` * `httpcore2.ReadError` * `httpcore2.WriteError` * `httpcore2.ProtocolError` * `httpcore2.RemoteProtocolError` * `httpcore2.LocalProtocolError` * `httpcore2.ProxyError` * `httpcore2.UnsupportedProtocol` pydantic-httpx2-6dd59b9/src/httpcore2/docs/extensions.md000066400000000000000000000260171526547463400234040ustar00rootroot00000000000000# Extensions The request/response API used by `httpcore2` is kept deliberately simple and explicit. The `Request` and `Response` models are pretty slim wrappers around this core API: ``` # Pseudo-code expressing the essentials of the request/response model. ( status_code: int, headers: List[Tuple(bytes, bytes)], stream: Iterable[bytes] ) = handle_request( method: bytes, url: URL, headers: List[Tuple(bytes, bytes)], stream: Iterable[bytes] ) ``` This is everything that's needed in order to represent an HTTP exchange. Well... almost. There is a maxim in Computer Science that *"All non-trivial abstractions, to some degree, are leaky"*. When an expression is leaky, it's important that it ought to at least leak only in well-defined places. In order to handle cases that don't otherwise fit inside this core abstraction, `httpcore2` requests and responses have 'extensions'. These are a dictionary of optional additional information. Let's expand on our request/response abstraction... ``` # Pseudo-code expressing the essentials of the request/response model, # plus extensions allowing for additional API that does not fit into # this abstraction. ( status_code: int, headers: List[Tuple(bytes, bytes)], stream: Iterable[bytes], extensions: dict ) = handle_request( method: bytes, url: URL, headers: List[Tuple(bytes, bytes)], stream: Iterable[bytes], extensions: dict ) ``` Several extensions are supported both on the request: ```python r = httpcore2.request( "GET", "https://www.example.com", extensions={"timeout": {"connect": 5.0}} ) ``` And on the response: ```python r = httpcore2.request("GET", "https://www.example.com") print(r.extensions["http_version"]) # When using HTTP/1.1 on the client side, the server HTTP response # could feasibly be one of b"HTTP/0.9", b"HTTP/1.0", or b"HTTP/1.1". ``` ## Request Extensions ### `"timeout"` A dictionary of `str: Optional[float]` timeout values. May include values for `'connect'`, `'read'`, `'write'`, or `'pool'`. For example: ```python # Timeout if a connection takes more than 5 seconds to established, or if # we are blocked waiting on the connection pool for more than 10 seconds. r = httpcore2.request( "GET", "https://www.example.com", extensions={"timeout": {"connect": 5.0, "pool": 10.0}} ) ``` ### `"trace"` The trace extension allows a callback handler to be installed to monitor the internal flow of events within `httpcore2`. The simplest way to explain this is with an example: ```python import httpcore2 def log(event_name, info): print(event_name, info) r = httpcore2.request("GET", "https://www.example.com/", extensions={"trace": log}) # connection.connect_tcp.started {'host': 'www.example.com', 'port': 443, 'local_address': None, 'timeout': None} # connection.connect_tcp.complete {'return_value': } # connection.start_tls.started {'ssl_context': , 'server_hostname': b'www.example.com', 'timeout': None} # connection.start_tls.complete {'return_value': } # http11.send_request_headers.started {'request': } # http11.send_request_headers.complete {'return_value': None} # http11.send_request_body.started {'request': } # http11.send_request_body.complete {'return_value': None} # http11.receive_response_headers.started {'request': } # http11.receive_response_headers.complete {'return_value': (b'HTTP/1.1', 200, b'OK', [(b'Age', b'553715'), (b'Cache-Control', b'max-age=604800'), (b'Content-Type', b'text/html; charset=UTF-8'), (b'Date', b'Thu, 21 Oct 2021 17:08:42 GMT'), (b'Etag', b'"3147526947+ident"'), (b'Expires', b'Thu, 28 Oct 2021 17:08:42 GMT'), (b'Last-Modified', b'Thu, 17 Oct 2019 07:18:26 GMT'), (b'Server', b'ECS (nyb/1DCD)'), (b'Vary', b'Accept-Encoding'), (b'X-Cache', b'HIT'), (b'Content-Length', b'1256')])} # http11.receive_response_body.started {'request': } # http11.receive_response_body.complete {'return_value': None} # http11.response_closed.started {} # http11.response_closed.complete {'return_value': None} ``` The `event_name` and `info` arguments here will be one of the following: * `{event_type}.{event_name}.started`, `` * `{event_type}.{event_name}.complete`, `{"return_value": <...>}` * `{event_type}.{event_name}.failed`, `{"exception": <...>}` Note that when using the async variant of `httpcore2` the handler function passed to `"trace"` must be an `async def ...` function. The following event types are currently exposed... **Establishing the connection** * `"connection.connect_tcp"` * `"connection.connect_unix_socket"` * `"connection.start_tls"` **HTTP/1.1 events** * `"http11.send_request_headers"` * `"http11.send_request_body"` * `"http11.receive_response"` * `"http11.receive_response_body"` * `"http11.response_closed"` **HTTP/2 events** * `"http2.send_connection_init"` * `"http2.send_request_headers"` * `"http2.send_request_body"` * `"http2.receive_response_headers"` * `"http2.receive_response_body"` * `"http2.response_closed"` The exact set of trace events may be subject to change across different versions of `httpcore2`. If you need to rely on a particular set of events it is recommended that you pin installation of the package to a fixed version. ### `"sni_hostname"` The server's hostname, which is used to confirm the hostname supplied by the SSL certificate. For example: ``` python headers = {"Host": "www.encode.io"} extensions = {"sni_hostname": "www.encode.io"} response = httpcore2.request( "GET", "https://185.199.108.153", headers=headers, extensions=extensions ) ``` ### `"target"` The target that is used as [the HTTP target instead of the URL path](https://datatracker.ietf.org/doc/html/rfc2616#section-5.1.2). This enables support constructing requests that would otherwise be unsupported. In particular... * Forward proxy requests using an absolute URI. * Tunneling proxy requests using `CONNECT` with hostname as the target. * Server-wide `OPTIONS *` requests. For example: ```python extensions = {"target": b"www.encode.io:443"} response = httpcore2.request( "CONNECT", "http://your-tunnel-proxy.com", headers=headers, extensions=extensions ) ``` ## Response Extensions ### `"http_version"` The HTTP version, as bytes. Eg. `b"HTTP/1.1"`. When using HTTP/1.1 the response line includes an explicit version, and the value of this key could feasibly be one of `b"HTTP/0.9"`, `b"HTTP/1.0"`, or `b"HTTP/1.1"`. When using HTTP/2 there is no further response versioning included in the protocol, and the value of this key will always be `b"HTTP/2"`. ### `"reason_phrase"` The reason-phrase of the HTTP response, as bytes. For example `b"OK"`. Some servers may include a custom reason phrase, although this is not recommended. HTTP/2 onwards does not include a reason phrase on the wire. When no key is included, a default based on the status code may be used. ### `"stream_id"` When HTTP/2 is being used the `"stream_id"` response extension can be accessed to determine the ID of the data stream that the response was sent on. ### `"network_stream"` The `"network_stream"` extension allows developers to handle HTTP `CONNECT` and `Upgrade` requests, by providing an API that steps outside the standard request/response model, and can directly read or write to the network. The interface provided by the network stream: * `read(max_bytes, timeout = None) -> bytes` * `write(buffer, timeout = None)` * `close()` * `start_tls(ssl_context, server_hostname = None, timeout = None) -> NetworkStream` * `get_extra_info(info) -> Any` This API can be used as the foundation for working with HTTP proxies, WebSocket upgrades, and other advanced use-cases. See the [network backends documentation](network-backends.md) for more information on working directly with network streams. ##### `CONNECT` requests A proxy CONNECT request using the network stream: ```python # Formulate a CONNECT request... # # This will establish a connection to 127.0.0.1:8080, and then send the following... # # CONNECT http://www.example.com HTTP/1.1 url = "http://127.0.0.1:8080" extensions = {"target": "http://www.example.com"} with httpcore2.stream("CONNECT", url, extensions=extensions) as response: network_stream = response.extensions["network_stream"] # Upgrade to an SSL stream... network_stream = network_stream.start_tls( ssl_context=httpcore2.default_ssl_context(), hostname=b"www.example.com", ) # Manually send an HTTP request over the network stream, and read the response... # # For a more complete example see the httpcore2 `TunnelHTTPConnection` implementation. network_stream.write(b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n") data = network_stream.read() print(data) ``` ##### `Upgrade` requests Using the `wsproto` package to handle a websockets session: ```python import httpcore2 import wsproto import os import base64 url = "http://127.0.0.1:8000/" headers = { b"Connection": b"Upgrade", b"Upgrade": b"WebSocket", b"Sec-WebSocket-Key": base64.b64encode(os.urandom(16)), b"Sec-WebSocket-Version": b"13" } with httpcore2.stream("GET", url, headers=headers) as response: if response.status != 101: raise Exception("Failed to upgrade to websockets", response) # Get the raw network stream. network_steam = response.extensions["network_stream"] # Write a WebSocket text frame to the stream. ws_connection = wsproto.Connection(wsproto.ConnectionType.CLIENT) message = wsproto.events.TextMessage("hello, world!") outgoing_data = ws_connection.send(message) network_steam.write(outgoing_data) # Wait for a response. incoming_data = network_steam.read(max_bytes=4096) ws_connection.receive_data(incoming_data) for event in ws_connection.events(): if isinstance(event, wsproto.events.TextMessage): print("Got data:", event.data) # Write a WebSocket close to the stream. message = wsproto.events.CloseConnection(code=1000) outgoing_data = ws_connection.send(message) network_steam.write(outgoing_data) ``` ##### Extra network information The network stream abstraction also allows access to various low-level information that may be exposed by the underlying socket: ```python response = httpcore2.request("GET", "https://www.example.com") network_stream = response.extensions["network_stream"] client_addr = network_stream.get_extra_info("client_addr") server_addr = network_stream.get_extra_info("server_addr") print("Client address", client_addr) print("Server address", server_addr) ``` The socket SSL information is also available through this interface, although you need to ensure that the underlying connection is still open, in order to access it... ```python with httpcore2.stream("GET", "https://www.example.com") as response: network_stream = response.extensions["network_stream"] ssl_object = network_stream.get_extra_info("ssl_object") print("TLS version", ssl_object.version()) ``` pydantic-httpx2-6dd59b9/src/httpcore2/docs/http2.md000066400000000000000000000177721526547463400222560ustar00rootroot00000000000000# HTTP/2 HTTP/2 is a major new iteration of the HTTP protocol, that provides a more efficient transport, with potential performance benefits. HTTP/2 does not change the core semantics of the request or response, but alters the way that data is sent to and from the server. Rather than the text format that HTTP/1.1 uses, HTTP/2 is a binary format. The binary format provides full request and response multiplexing, and efficient compression of HTTP headers. The stream multiplexing means that where HTTP/1.1 requires one TCP stream for each concurrent request, HTTP/2 allows a single TCP stream to handle multiple concurrent requests. HTTP/2 also provides support for functionality such as response prioritization, and server push. For a comprehensive guide to HTTP/2 you may want to check out "[HTTP2 Explained](https://http2-explained.haxx.se)". ## Enabling HTTP/2 When using the `httpcore2` client, HTTP/2 support is not enabled by default, because HTTP/1.1 is a mature, battle-hardened transport layer, and our HTTP/1.1 implementation may be considered the more robust option at this point in time. It is possible that a future version of `httpcore2` may enable HTTP/2 support by default. If you're issuing highly concurrent requests you might want to consider trying out our HTTP/2 support. You can do so by first making sure to install the optional HTTP/2 dependencies... ```shell pip install 'httpcore2[http2]' ``` And then instantiating a connection pool with HTTP/2 support enabled: ```python import httpcore2 pool = httpcore2.ConnectionPool(http2=True) ``` We can take a look at the difference in behaviour by issuing several outgoing requests in parallel. Start out by using a standard HTTP/1.1 connection pool: ```python import httpcore2 import concurrent.futures import time def download(http, year): http.request("GET", f"https://en.wikipedia.org/wiki/{year}") def main(): with httpcore2.ConnectionPool() as http: started = time.time() with concurrent.futures.ThreadPoolExecutor(max_workers=10) as threads: for year in range(2000, 2020): threads.submit(download, http, year) complete = time.time() for connection in http.connections: print(connection) print("Complete in %.3f seconds" % (complete - started)) main() ``` If you run this with an HTTP/1.1 connection pool, you ought to see output similar to the following: ```python , , , , , , , Complete in 0.586 seconds ``` We can see that the connection pool required a number of connections in order to handle the parallel requests. If we now upgrade our connection pool to support HTTP/2: ```python with httpcore2.ConnectionPool(http2=True) as http: ... ``` And run the same script again, we should end up with something like this: ```python Complete in 0.573 seconds ``` All of our requests have been handled over a single connection. Switching to HTTP/2 should not *necessarily* be considered an "upgrade". It is more complex, and requires more computational power, and so particularly in an interpreted language like Python it *could* be slower in some instances. Moreover, utilising multiple connections may end up connecting to multiple hosts, and could sometimes appear faster to the client, at the cost of requiring more server resources. Enabling HTTP/2 is most likely to be beneficial if you are sending requests in high concurrency, and may often be more well suited to an async context, rather than multi-threading. ## Inspecting the HTTP version Enabling HTTP/2 support on the client does not *necessarily* mean that your requests and responses will be transported over HTTP/2, since both the client *and* the server need to support HTTP/2. If you connect to a server that only supports HTTP/1.1 the client will use a standard HTTP/1.1 connection instead. You can determine which version of the HTTP protocol was used by examining the `"http_version"` response extension. ```python import httpcore2 pool = httpcore2.ConnectionPool(http2=True) response = pool.request("GET", "https://www.example.com/") # Should be one of b"HTTP/2", b"HTTP/1.1", b"HTTP/1.0", or b"HTTP/0.9". print(response.extensions["http_version"]) ``` See [the extensions documentation](extensions.md) for more details. ## HTTP/2 negotiation Robust servers need to support both HTTP/2 and HTTP/1.1 capable clients, and so need some way to "negotiate" with the client which protocol version will be used. ### HTTP/2 over HTTPS Generally the method used is for the server to advertise if it has HTTP/2 support during the part of the SSL connection handshake. This is known as ALPN - "Application Layer Protocol Negotiation". Most browsers only provide HTTP/2 support over HTTPS connections, and this is also the default behaviour that `httpcore2` provides. If you enable HTTP/2 support you should still expect to see HTTP/1.1 connections for any `http://` URLs. ### HTTP/2 over HTTP Servers can optionally also support HTTP/2 over HTTP by supporting the `Upgrade: h2c` header. This mechanism is not supported by `httpcore2`. It requires an additional round-trip between the client and server, and also requires any request body to be sent twice. ### Prior Knowledge If you know in advance that the server you are communicating with will support HTTP/2, then you can enforce that the client uses HTTP/2, without requiring either ALPN support or an HTTP `Upgrade: h2c` header. This is managed by disabling HTTP/1.1 support on the connection pool: ```python pool = httpcore2.ConnectionPool(http1=False, http2=True) ``` ## Request & response headers Because HTTP/2 frames the requests and responses somewhat differently to HTTP/1.1, there is a difference in some of the headers that are used. In order for the `httpcore2` library to support both HTTP/1.1 and HTTP/2 transparently, the HTTP/1.1 style is always used throughout the API. Any differences in header styles are only mapped onto HTTP/2 at the internal network layer. ## Request headers The following pseudo-headers are used by HTTP/2 in the request: * `:method` - The request method. * `:path` - Taken from the URL of the request. * `:authority` - Equivalent to the `Host` header in HTTP/1.1. In `httpcore2` this is represented using the request `Host` header, which is automatically populated from the request URL if no `Host` header is explicitly included. * `:scheme` - Taken from the URL of the request. These pseudo-headers are included in `httpcore2` as part of the `request.method` and `request.url` attributes, and through the `request.headers["Host"]` header. *They are not exposed directly by their psuedo-header names.* The one other difference to be aware of is the `Transfer-Encoding: chunked` header. In HTTP/2 this header is never used, since streaming data is framed using a different mechanism. In `httpcore2` the `Transfer-Encoding: chunked` header is always used to represent the presence of a streaming body on the request, and is automatically populated if required. However the header is only sent if the underlying connection ends up being HTTP/1.1, and is omitted if the underlying connection ends up being HTTP/2. ## Response headers The following pseudo-header is used by HTTP/2 in the response: * `:status` - The response status code. In `httpcore2` this *is represented by the `response.status` attribute, rather than being exposed as a psuedo-header*. pydantic-httpx2-6dd59b9/src/httpcore2/docs/index.md000066400000000000000000000034131526547463400223070ustar00rootroot00000000000000# HTTPCore 2 [![Test Suite](https://github.com/pydantic/httpx2/workflows/Test%20Suite/badge.svg)](https://github.com/pydantic/httpx2/actions) [![Package version](https://badge.fury.io/py/httpcore2.svg)](https://pypi.org/project/httpcore2/) > *Do one thing, and do it well.* The HTTPCore 2 package provides a minimal low-level HTTP client, which does one thing only. Sending HTTP requests. It does not provide any high level model abstractions over the API, does not handle redirects, multipart uploads, building authentication headers, transparent HTTP caching, URL parsing, session cookie handling, content or charset decoding, handling JSON, environment based configuration defaults, or any of that Jazz. Some things HTTPCore 2 does do: * Sending HTTP requests. * Thread-safe / task-safe connection pooling. * HTTP(S) proxy & SOCKS proxy support. * Supports HTTP/1.1 and HTTP/2. * Provides both sync and async interfaces. * Async backend support for `asyncio` and `trio`. ## Installation For HTTP/1.1 only support, install with: ```shell pip install httpcore2 ``` For HTTP/1.1 and HTTP/2 support, install with: ```shell pip install 'httpcore2[http2]' ``` For SOCKS proxy support, install with: ```shell pip install 'httpcore2[socks]' ``` ## Example Let's check we're able to send HTTP requests: ```python import httpcore2 response = httpcore2.request("GET", "https://www.example.com/") print(response) # print(response.status) # 200 print(response.headers) # [(b'Accept-Ranges', b'bytes'), (b'Age', b'557328'), (b'Cache-Control', b'max-age=604800'), ...] print(response.content) # b'\n\n\nExample Domain\n\n\n ...' ``` Ready to get going? Head over to [the quickstart documentation](quickstart.md). pydantic-httpx2-6dd59b9/src/httpcore2/docs/logging.md000066400000000000000000000053541526547463400226340ustar00rootroot00000000000000# Logging If you need to inspect the internal behaviour of `httpcore2`, you can use Python's standard logging to output debug level information. For example, the following configuration... ```python import logging import httpcore2 logging.basicConfig( format="%(levelname)s [%(asctime)s] %(name)s - %(message)s", datefmt="%Y-%m-%d %H:%M:%S", level=logging.DEBUG ) httpcore2.request('GET', 'https://www.example.com') ``` Will send debug level output to the console, or wherever `stdout` is directed too... ``` DEBUG [2023-01-09 14:44:00] httpcore2.connection - connect_tcp.started host='www.example.com' port=443 local_address=None timeout=None DEBUG [2023-01-09 14:44:00] httpcore2.connection - connect_tcp.complete return_value= DEBUG [2023-01-09 14:44:00] httpcore2.connection - start_tls.started ssl_context= server_hostname='www.example.com' timeout=None DEBUG [2023-01-09 14:44:00] httpcore2.connection - start_tls.complete return_value= DEBUG [2023-01-09 14:44:00] httpcore2.http11 - send_request_headers.started request= DEBUG [2023-01-09 14:44:00] httpcore2.http11 - send_request_headers.complete DEBUG [2023-01-09 14:44:00] httpcore2.http11 - send_request_body.started request= DEBUG [2023-01-09 14:44:00] httpcore2.http11 - send_request_body.complete DEBUG [2023-01-09 14:44:00] httpcore2.http11 - receive_response_headers.started request= DEBUG [2023-01-09 14:44:00] httpcore2.http11 - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Age', b'572646'), (b'Cache-Control', b'max-age=604800'), (b'Content-Type', b'text/html; charset=UTF-8'), (b'Date', b'Mon, 09 Jan 2023 14:44:00 GMT'), (b'Etag', b'"3147526947+ident"'), (b'Expires', b'Mon, 16 Jan 2023 14:44:00 GMT'), (b'Last-Modified', b'Thu, 17 Oct 2019 07:18:26 GMT'), (b'Server', b'ECS (nyb/1D18)'), (b'Vary', b'Accept-Encoding'), (b'X-Cache', b'HIT'), (b'Content-Length', b'1256')]) DEBUG [2023-01-09 14:44:00] httpcore2.http11 - receive_response_body.started request= DEBUG [2023-01-09 14:44:00] httpcore2.http11 - receive_response_body.complete DEBUG [2023-01-09 14:44:00] httpcore2.http11 - response_closed.started DEBUG [2023-01-09 14:44:00] httpcore2.http11 - response_closed.complete DEBUG [2023-01-09 14:44:00] httpcore2.connection - close.started DEBUG [2023-01-09 14:44:00] httpcore2.connection - close.complete ``` The exact formatting of the debug logging may be subject to change across different versions of `httpcore2`. If you need to rely on a particular format it is recommended that you pin installation of the package to a fixed version.pydantic-httpx2-6dd59b9/src/httpcore2/docs/network-backends.md000066400000000000000000000213361526547463400244450ustar00rootroot00000000000000# Network Backends The API layer at which `httpcore2` interacts with the network is described as the network backend. Various backend implementations are provided, allowing `httpcore2` to handle networking in different runtime contexts. ## Working with network backends ### The default network backend Typically you won't need to specify a network backend, as a default will automatically be selected. However, understanding how the network backends fit in may be useful if you want to better understand the underlying architecture. Let's start by seeing how we can explicitly select the network backend. First we're making a standard HTTP request, using a connection pool: ```python import httpcore2 with httpcore2.ConnectionPool() as http: response = http.request('GET', 'https://www.example.com') print(response) ``` We can also have the same behavior, but be explicit with our selection of the network backend: ```python import httpcore2 network_backend = httpcore2.SyncBackend() with httpcore2.ConnectionPool(network_backend=network_backend) as http: response = http.request('GET', 'https://www.example.com') print(response) ``` The `httpcore2.SyncBackend()` implementation handles the opening of TCP connections, and operations on the socket stream, such as reading, writing, and closing the connection. We can get a better understanding of this by using a network backend to send a basic HTTP/1.1 request directly: ```python import httpcore2 # Create an SSL context using 'certifi' for the certificates. ssl_context = httpcore2.default_ssl_context() # A basic HTTP/1.1 request as a plain bytestring. request = b'\r\n'.join([ b'GET / HTTP/1.1', b'Host: www.example.com', b'Accept: */*', b'Connection: close', b'' ]) # Open a TCP stream and upgrade it to SSL. network_backend = httpcore2.SyncBackend() network_stream = network_backend.connect_tcp("www.example.com", 443) network_stream = network_stream.start_tls(ssl_context, server_hostname="www.example.com") # Send the HTTP request. network_stream.write(request) # Read the HTTP response. while True: response = network_stream.read(max_bytes=4096) if response == b'': break print(response) # The output should look something like this: # # b'HTTP/1.1 200 OK\r\nAge: 600005\r\n [...] Content-Length: 1256\r\nConnection: close\r\n\r\n' # b'\n\n\n Example Domain [...] \n' ``` ### Async network backends If we're working with an `async` codebase, then we need to select a different backend. The `httpcore2.AnyIOBackend` is suitable for usage if you're running under `asyncio`. This is a networking backend implemented using [the `anyio` package](https://anyio.readthedocs.io/en/3.x/). ```python import httpcore2 import asyncio async def main(): network_backend = httpcore2.AnyIOBackend() async with httpcore2.AsyncConnectionPool(network_backend=network_backend) as http: response = await http.request('GET', 'https://www.example.com') print(response) asyncio.run(main()) ``` The `AnyIOBackend` will work when running under either `asyncio` or `trio`. However, if you're working with async using the [`trio` framework](https://trio.readthedocs.io/en/stable/), then we recommend using the `httpcore2.TrioBackend`. This will give you the same kind of networking behavior you'd have using `AnyIOBackend`, but there will be a little less indirection so it will be marginally more efficient and will present cleaner tracebacks in error cases. ```python import httpcore2 import trio async def main(): network_backend = httpcore2.TrioBackend() async with httpcore2.AsyncConnectionPool(network_backend=network_backend) as http: response = await http.request('GET', 'https://www.example.com') print(response) trio.run(main) ``` ### Mock network backends There are also mock network backends available that can be useful for testing purposes. These backends accept a list of bytes, and return network stream interfaces that return those byte streams. Here's an example of mocking a simple HTTP/1.1 response... ```python import httpcore2 network_backend = httpcore2.MockBackend([ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ]) with httpcore2.ConnectionPool(network_backend=network_backend) as http: response = http.request("GET", "https://example.com/") print(response.extensions['http_version']) print(response.status) print(response.content) ``` Mocking a HTTP/2 response is more complex, since it uses a binary format... ```python import hpack import hyperframe.frame import httpcore2 content = [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame( stream_id=1, data=b"Hello, world!", flags=["END_STREAM"] ).serialize(), ] # Note that we instantiate the mock backend with an `http2=True` argument. # This ensures that the mock network stream acts as if the `h2` ALPN flag has been set, # and causes the connection pool to interact with the connection using HTTP/2. network_backend = httpcore2.MockBackend(content, http2=True) with httpcore2.ConnectionPool(network_backend=network_backend) as http: response = http.request("GET", "https://example.com/") print(response.extensions['http_version']) print(response.status) print(response.content) ``` ### Custom network backends The base interface for network backends is provided as public API, allowing you to implement custom networking behavior. You can use this to provide advanced networking functionality such as: * Network recording / replay. * In-depth debug tooling. * Handling non-standard SSL or DNS requirements. Here's an example that records the network response to a file on disk: ```python import httpcore2 class RecordingNetworkStream(httpcore2.NetworkStream): def __init__(self, record_file, stream): self.record_file = record_file self.stream = stream def read(self, max_bytes, timeout=None): data = self.stream.read(max_bytes, timeout=timeout) self.record_file.write(data) return data def write(self, buffer, timeout=None): self.stream.write(buffer, timeout=timeout) def close(self) -> None: self.stream.close() def start_tls( self, ssl_context, server_hostname=None, timeout=None, ): self.stream = self.stream.start_tls( ssl_context, server_hostname=server_hostname, timeout=timeout ) return self def get_extra_info(self, info): return self.stream.get_extra_info(info) class RecordingNetworkBackend(httpcore2.NetworkBackend): """ A custom network backend that records network responses. """ def __init__(self, record_file): self.record_file = record_file self.backend = httpcore2.SyncBackend() def connect_tcp( self, host, port, timeout=None, local_address=None, socket_options=None, ): # Note that we're only using a single record file here, # so even if multiple connections are opened the network # traffic will all write to the same file. # An alternative implementation might automatically use # a new file for each opened connection. stream = self.backend.connect_tcp( host, port, timeout=timeout, local_address=local_address, socket_options=socket_options ) return RecordingNetworkStream(self.record_file, stream) # Once you make the request, the raw HTTP/1.1 response will be available #ย in the 'network-recording' file. # # Try switching to `http2=True` to see the difference when recording HTTP/2 binary network traffic, # or add `headers={'Accept-Encoding': 'gzip'}` to see HTTP content compression. with open("network-recording", "wb") as record_file: network_backend = RecordingNetworkBackend(record_file) with httpcore2.ConnectionPool(network_backend=network_backend) as http: response = http.request("GET", "https://www.example.com/") print(response) ``` --- ## Reference ### Networking Backends * `httpcore2.SyncBackend` * `httpcore2.AnyIOBackend` * `httpcore2.TrioBackend` ### Mock Backends * `httpcore2.MockBackend` * `httpcore2.MockStream` * `httpcore2.AsyncMockBackend` * `httpcore2.AsyncMockStream` ### Base Interface * `httpcore2.NetworkBackend` * `httpcore2.NetworkStream` * `httpcore2.AsyncNetworkBackend` * `httpcore2.AsyncNetworkStream` pydantic-httpx2-6dd59b9/src/httpcore2/docs/proxies.md000066400000000000000000000063131526547463400226730ustar00rootroot00000000000000# Proxies The `httpcore2` package provides support for HTTP proxies, using either "HTTP Forwarding" or "HTTP Tunnelling". Forwarding is a proxy mechanism for sending requests to `http` URLs via an intermediate proxy. Tunnelling is a proxy mechanism for sending requests to `https` URLs via an intermediate proxy. Sending requests via a proxy is very similar to sending requests using a standard connection pool: ```python import httpcore2 proxy = httpcore2.Proxy("http://127.0.0.1:8080/") pool = httpcore2.ConnectionPool(proxy=proxy) r = proxy.request("GET", "https://www.example.com/") print(r) # ``` You can test the `httpcore2` proxy support, using the Python [`proxy.py`](https://pypi.org/project/proxy.py/) tool: ```shell pip install proxy.py proxy --hostname 127.0.0.1 --port 8080 ``` Requests will automatically use either forwarding or tunnelling, depending on if the scheme is `http` or `https`. ## Authentication Proxy authentication can be included in the initial configuration: ```python import httpcore2 # A `Proxy-Authorization` header will be included on the initial proxy connection. proxy = httpcore2.Proxy( url="http://127.0.0.1:8080/", auth=("", "") ) pool = httpcore2.ConnectionPool(proxy=proxy) ``` Custom headers can also be included: ```python import httpcore2 import base64 # Construct and include a `Proxy-Authorization` header. auth = base64.b64encode(b":") proxy = httpcore2.Proxy( url="http://127.0.0.1:8080/", headers={"Proxy-Authorization": b"Basic " + auth} ) pool = httpcore2.ConnectionPool(proxy=proxy) ``` ## Proxy SSL The `httpcore2` package also supports HTTPS proxies for http and https destinations. HTTPS proxies can be used in the same way that HTTP proxies are. ```python proxy = httpcore2.Proxy(url="https://127.0.0.1:8080/") ``` Also, when using HTTPS proxies, you may need to configure the SSL context, which you can do with the `ssl_context` argument. ```python import ssl import httpcore2 proxy_ssl_context = ssl.create_default_context() proxy_ssl_context.check_hostname = False proxy = httpcore2.Proxy( url='https://127.0.0.1:8080/', ssl_context=proxy_ssl_context ) pool = httpcore2.ConnectionPool(proxy=proxy) ``` ## HTTP Versions If you use proxies, keep in mind that the `httpcore2` package only supports proxies to HTTP/1.1 servers. ## SOCKS proxy support The `httpcore2` package also supports proxies using the SOCKS5 protocol. Make sure to install the optional dependency using `pip install 'httpcore2[socks]'`. The `SOCKSProxy` class should be using instead of a standard connection pool: ```python import httpcore2 # Note that the SOCKS port is 1080. proxy = httpcore2.Proxy(url="socks5://127.0.0.1:1080/") pool = httpcore2.ConnectionPool(proxy=proxy) r = pool.request("GET", "https://www.example.com/") ``` Authentication via SOCKS is also supported: ```python import httpcore2 proxy = httpcore2.Proxy( url="socks5://127.0.0.1:1080/", auth=("", ""), ) pool = httpcore2.ConnectionPool(proxy=proxy) r = pool.request("GET", "https://www.example.com/") ``` --- # Reference ## `httpcore2.Proxy` ::: httpcore2.Proxy handler: python rendering: show_source: False pydantic-httpx2-6dd59b9/src/httpcore2/docs/quickstart.md000066400000000000000000000120711526547463400233720ustar00rootroot00000000000000# Quickstart For convenience, the `httpcore2` package provides a couple of top-level functions that you can use for sending HTTP requests. You probably don't want to integrate against functions if you're writing a library that uses `httpcore2`, but you might find them useful for testing `httpcore2` from the command-line, or if you're writing a simple script that doesn't require any of the connection pooling or advanced configuration that `httpcore2` offers. ## Sending a request We'll start off by sending a request... ```python import httpcore2 response = httpcore2.request("GET", "https://www.example.com/") print(response) # print(response.status) # 200 print(response.headers) # [(b'Accept-Ranges', b'bytes'), (b'Age', b'557328'), (b'Cache-Control', b'max-age=604800'), ...] print(response.content) # b'\n\n\nExample Domain\n\n\n ...' ``` ## Request headers Request headers may be included either in a dictionary style, or as a list of two-tuples. ```python import httpcore2 import json headers = {'User-Agent': 'httpcore2'} r = httpcore2.request('GET', 'https://httpbin.org/headers', headers=headers) print(json.loads(r.content)) # { # 'headers': { # 'Host': 'httpbin.org', # 'User-Agent': 'httpcore2', # 'X-Amzn-Trace-Id': 'Root=1-616ff5de-5ea1b7e12766f1cf3b8e3a33' # } # } ``` The keys and values may either be provided as strings or as bytes. Where strings are provided they may only contain characters within the ASCII range `chr(0)` - `chr(127)`. To include characters outside this range you must deal with any character encoding explicitly, and pass bytes as the header keys/values. The `Host` header will always be automatically included in any outgoing request, as it is strictly required to be present by the HTTP protocol. *Note that the `X-Amzn-Trace-Id` header shown in the example above is not an outgoing request header, but has been added by a gateway server.* ## Request body A request body can be included either as bytes... ```python import httpcore2 import json r = httpcore2.request('POST', 'https://httpbin.org/post', content=b'Hello, world') print(json.loads(r.content)) # { # 'args': {}, # 'data': 'Hello, world', # 'files': {}, # 'form': {}, # 'headers': { # 'Host': 'httpbin.org', # 'Content-Length': '12', # 'X-Amzn-Trace-Id': 'Root=1-61700258-00e338a124ca55854bf8435f' # }, # 'json': None, # 'origin': '68.41.35.196', # 'url': 'https://httpbin.org/post' # } ``` Or as an iterable that returns bytes... ```python import httpcore2 import json with open("hello-world.txt", "rb") as input_file: r = httpcore2.request('POST', 'https://httpbin.org/post', content=input_file) print(json.loads(r.content)) # { # 'args': {}, # 'data': 'Hello, world', # 'files': {}, # 'form': {}, # 'headers': { # 'Host': 'httpbin.org', # 'Transfer-Encoding': 'chunked', # 'X-Amzn-Trace-Id': 'Root=1-61700258-00e338a124ca55854bf8435f' # }, # 'json': None, # 'origin': '68.41.35.196', # 'url': 'https://httpbin.org/post' # } ``` When a request body is included, either a `Content-Length` header or a `Transfer-Encoding: chunked` header will be automatically included. The `Content-Length` header is used when passing bytes, and indicates an HTTP request with a body of a pre-determined length. The `Transfer-Encoding: chunked` header is the mechanism that HTTP/1.1 uses for sending HTTP request bodies without a pre-determined length. ## Streaming responses When using the `httpcore2.request()` function, the response body will automatically be read to completion, and made available in the `response.content` attribute. Sometimes you may be dealing with large responses and not want to read the entire response into memory. The `httpcore2.stream()` function provides a mechanism for sending a request and dealing with a streaming response: ```python import httpcore2 with httpcore2.stream('GET', 'https://example.com') as response: for chunk in response.iter_stream(): print(f"Downloaded: {chunk}") ``` Here's a more complete example that demonstrates downloading a response: ```python import httpcore2 with httpcore2.stream('GET', 'https://speed.hetzner.de/100MB.bin') as response: with open("download.bin", "wb") as output_file: for chunk in response.iter_stream(): output_file.write(chunk) ``` The `httpcore2.stream()` API also allows you to *conditionally* read the response... ```python import httpcore2 with httpcore2.stream('GET', 'https://example.com') as response: content_length = [int(v) for k, v in response.headers if k.lower() == b'content-length'][0] if content_length > 100_000_000: raise Exception("Response too large.") response.read() # `response.content` is now available. ``` --- # Reference ## `httpcore2.request()` ::: httpcore2.request handler: python rendering: show_source: False ## `httpcore2.stream()` ::: httpcore2.stream handler: python rendering: show_source: False pydantic-httpx2-6dd59b9/src/httpcore2/docs/requests-responses-urls.md000066400000000000000000000025601526547463400260570ustar00rootroot00000000000000# Requests, Responses, and URLs TODO ## Requests Request instances in `httpcore2` are deliberately simple, and only include the essential information required to represent an HTTP request. Properties on the request are plain byte-wise representations. ```python >>> request = httpcore2.Request("GET", "https://www.example.com/") >>> request.method b"GET" >>> request.url httpcore2.URL(scheme=b"https", host=b"www.example.com", port=None, target=b"/") >>> request.headers [(b'Host', b'www.example.com')] >>> request.stream ``` The interface is liberal in the types that it accepts, but specific in the properties that it uses to represent them. For example, headers may be specified as a dictionary of strings, but internally are represented as a list of `(byte, byte)` tuples. ```python >>> headers = {"User-Agent": "custom"} >>> request = httpcore2.Request("GET", "https://www.example.com/", headers=headers) >>> request.headers [(b'Host', b'www.example.com'), (b"User-Agent", b"custom")] ## Responses ... ## URLs ... --- # Reference ## `httpcore2.Request` ::: httpcore2.Request handler: python rendering: show_source: False ## `httpcore2.Response` ::: httpcore2.Response handler: python rendering: show_source: False ## `httpcore2.URL` ::: httpcore2.URL handler: python rendering: show_source: False pydantic-httpx2-6dd59b9/src/httpcore2/docs/table-of-contents.md000066400000000000000000000030041526547463400245200ustar00rootroot00000000000000# API Reference * Quickstart * `httpcore2.request()` * `httpcore2.stream()` * Requests, Responses, and URLs * `httpcore2.Request` * `httpcore2.Response` * `httpcore2.URL` * Connection Pools * `httpcore2.ConnectionPool` * Proxies * `httpcore2.Proxy` * Connections * `httpcore2.HTTPConnection` * `httpcore2.HTTP11Connection` * `httpcore2.HTTP2Connection` * Async Support * `httpcore2.AsyncConnectionPool` * `httpcore2.AsyncHTTPConnection` * `httpcore2.AsyncHTTP11Connection` * `httpcore2.AsyncHTTP2Connection` * Network Backends * Sync * `httpcore2._backends.sync.SyncBackend` * `httpcore2._backends.mock.MockBackend` * Async * `httpcore2._backends.auto.AutoBackend` * `httpcore2._backends.anyio.AnyIOBackend` * `httpcore2._backends.trio.TrioBackend` * `httpcore2._backends.mock.AsyncMockBackend` * Base interfaces * `httpcore2._backends.base.NetworkBackend` * `httpcore2._backends.base.AsyncNetworkBackend` * Exceptions * `httpcore2.TimeoutException` * `httpcore2.PoolTimeout` * `httpcore2.ConnectTimeout` * `httpcore2.ReadTimeout` * `httpcore2.WriteTimeout` * `httpcore2.NetworkError` * `httpcore2.ConnectError` * `httpcore2.ReadError` * `httpcore2.WriteError` * `httpcore2.ProtocolError` * `httpcore2.RemoteProtocolError` * `httpcore2.LocalProtocolError` * `httpcore2.ProxyError` * `httpcore2.UnsupportedProtocol` pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/000077500000000000000000000000001526547463400216375ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/__init__.py000066400000000000000000000066211526547463400237550ustar00rootroot00000000000000from importlib.metadata import version from ._api import request, stream from ._async import ( AsyncConnectionInterface, AsyncConnectionPool, AsyncHTTP2Connection, AsyncHTTP11Connection, AsyncHTTPConnection, AsyncHTTPProxy, AsyncSOCKSProxy, ) from ._backends.base import ( SOCKET_OPTION, AsyncNetworkBackend, AsyncNetworkStream, NetworkBackend, NetworkStream, ) from ._backends.mock import AsyncMockBackend, AsyncMockStream, MockBackend, MockStream from ._backends.sync import SyncBackend from ._exceptions import ( ConnectError, ConnectionNotAvailable, ConnectTimeout, LocalProtocolError, NetworkError, PoolTimeout, ProtocolError, ProxyError, ReadError, ReadTimeout, RemoteProtocolError, TimeoutException, UnsupportedProtocol, WriteError, WriteTimeout, ) from ._models import URL, Origin, Proxy, Request, Response from ._ssl import default_ssl_context from ._sync import ( ConnectionInterface, ConnectionPool, HTTP2Connection, HTTP11Connection, HTTPConnection, HTTPProxy, SOCKSProxy, ) # The 'httpcore2.AnyIOBackend' class is conditional on 'anyio' being installed. try: from ._backends.anyio import AnyIOBackend except ImportError: # pragma: no cover class AnyIOBackend: # type: ignore def __init__(self, *args, **kwargs): # type: ignore msg = "Attempted to use 'httpcore2.AnyIOBackend' but 'anyio' is not installed." raise RuntimeError(msg) # The 'httpcore2.TrioBackend' class is conditional on 'trio' being installed. try: from ._backends.trio import TrioBackend except ImportError: # pragma: no cover class TrioBackend: # type: ignore def __init__(self, *args, **kwargs): # type: ignore msg = "Attempted to use 'httpcore2.TrioBackend' but 'trio' is not installed." raise RuntimeError(msg) __all__ = [ # top-level requests "request", "stream", # models "Origin", "URL", "Request", "Response", "Proxy", # async "AsyncHTTPConnection", "AsyncConnectionPool", "AsyncHTTPProxy", "AsyncHTTP11Connection", "AsyncHTTP2Connection", "AsyncConnectionInterface", "AsyncSOCKSProxy", # sync "HTTPConnection", "ConnectionPool", "HTTPProxy", "HTTP11Connection", "HTTP2Connection", "ConnectionInterface", "SOCKSProxy", # network backends, implementations "SyncBackend", "AnyIOBackend", "TrioBackend", # network backends, mock implementations "AsyncMockBackend", "AsyncMockStream", "MockBackend", "MockStream", # network backends, interface "AsyncNetworkStream", "AsyncNetworkBackend", "NetworkStream", "NetworkBackend", # util "default_ssl_context", "SOCKET_OPTION", # exceptions "ConnectionNotAvailable", "ProxyError", "ProtocolError", "LocalProtocolError", "RemoteProtocolError", "UnsupportedProtocol", "TimeoutException", "PoolTimeout", "ConnectTimeout", "ReadTimeout", "WriteTimeout", "NetworkError", "ConnectError", "ReadError", "WriteError", ] __version__ = version("httpcore2") __locals = locals() for __name in __all__: # Exclude SOCKET_OPTION, it causes AttributeError on Python 3.14 if not __name.startswith(("__", "SOCKET_OPTION")): setattr(__locals[__name], "__module__", "httpcore2") # noqa pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_api.py000066400000000000000000000061601526547463400231240ustar00rootroot00000000000000from __future__ import annotations import contextlib import typing from collections.abc import Generator from ._models import URL, Extensions, HeaderTypes, Response from ._sync.connection_pool import ConnectionPool def request( method: bytes | str, url: URL | bytes | str, *, headers: HeaderTypes = None, content: bytes | typing.Iterator[bytes] | None = None, extensions: Extensions | None = None, ) -> Response: """ Sends an HTTP request, returning the response. ``` response = httpcore2.request("GET", "https://www.example.com/") ``` Arguments: method: The HTTP method for the request. Typically one of `"GET"`, `"OPTIONS"`, `"HEAD"`, `"POST"`, `"PUT"`, `"PATCH"`, or `"DELETE"`. url: The URL of the HTTP request. Either as an instance of `httpcore2.URL`, or as str/bytes. headers: The HTTP request headers. Either as a dictionary of str/bytes, or as a list of two-tuples of str/bytes. content: The content of the request body. Either as bytes, or as a bytes iterator. extensions: A dictionary of optional extra information included on the request. Possible keys include `"timeout"`. Returns: An instance of `httpcore2.Response`. """ with ConnectionPool() as pool: return pool.request( method=method, url=url, headers=headers, content=content, extensions=extensions, ) @contextlib.contextmanager def stream( method: bytes | str, url: URL | bytes | str, *, headers: HeaderTypes = None, content: bytes | typing.Iterator[bytes] | None = None, extensions: Extensions | None = None, ) -> Generator[Response]: """ Sends an HTTP request, returning the response within a content manager. ``` with httpcore2.stream("GET", "https://www.example.com/") as response: ... ``` When using the `stream()` function, the body of the response will not be automatically read. If you want to access the response body you should either use `content = response.read()`, or `for chunk in response.iter_content()`. Arguments: method: The HTTP method for the request. Typically one of `"GET"`, `"OPTIONS"`, `"HEAD"`, `"POST"`, `"PUT"`, `"PATCH"`, or `"DELETE"`. url: The URL of the HTTP request. Either as an instance of `httpcore2.URL`, or as str/bytes. headers: The HTTP request headers. Either as a dictionary of str/bytes, or as a list of two-tuples of str/bytes. content: The content of the request body. Either as bytes, or as a bytes iterator. extensions: A dictionary of optional extra information included on the request. Possible keys include `"timeout"`. Returns: An instance of `httpcore2.Response`. """ with ConnectionPool() as pool: with pool.stream( method=method, url=url, headers=headers, content=content, extensions=extensions, ) as response: yield response pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_async/000077500000000000000000000000001526547463400231135ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_async/__init__.py000066400000000000000000000023071526547463400252260ustar00rootroot00000000000000from .connection import AsyncHTTPConnection from .connection_pool import AsyncConnectionPool from .http11 import AsyncHTTP11Connection from .http_proxy import AsyncHTTPProxy from .interfaces import AsyncConnectionInterface try: from .http2 import AsyncHTTP2Connection except ImportError: # pragma: no cover class AsyncHTTP2Connection: # type: ignore def __init__(self, *args, **kwargs) -> None: # type: ignore raise RuntimeError( "Attempted to use http2 support, but the `h2` package is not " "installed. Use 'pip install httpcore[http2]'." ) try: from .socks_proxy import AsyncSOCKSProxy except ImportError: # pragma: no cover class AsyncSOCKSProxy: # type: ignore def __init__(self, *args, **kwargs) -> None: # type: ignore raise RuntimeError( "Attempted to use SOCKS support, but the `socksio` package is not " "installed. Use 'pip install httpcore[socks]'." ) __all__ = [ "AsyncHTTPConnection", "AsyncConnectionPool", "AsyncHTTPProxy", "AsyncHTTP11Connection", "AsyncHTTP2Connection", "AsyncConnectionInterface", "AsyncSOCKSProxy", ] pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_async/connection.py000066400000000000000000000201611526547463400256240ustar00rootroot00000000000000from __future__ import annotations import itertools import logging import ssl import types import typing from .._backends.auto import AutoBackend from .._backends.base import SOCKET_OPTION, AsyncNetworkBackend, AsyncNetworkStream from .._exceptions import ConnectError, ConnectTimeout from .._models import Origin, Request, Response from .._ssl import default_ssl_context from .._synchronization import AsyncLock from .._trace import Trace from .http11 import AsyncHTTP11Connection from .interfaces import AsyncConnectionInterface RETRIES_BACKOFF_FACTOR = 0.5 # 0s, 0.5s, 1s, 2s, 4s, etc. logger = logging.getLogger("httpcore2.connection") def exponential_backoff(factor: float) -> typing.Iterator[float]: """ Generate a geometric sequence that has a ratio of 2 and starts with 0. For example: - `factor = 2`: `0, 2, 4, 8, 16, 32, 64, ...` - `factor = 3`: `0, 3, 6, 12, 24, 48, 96, ...` """ yield 0 for n in itertools.count(): yield factor * 2**n class AsyncHTTPConnection(AsyncConnectionInterface): def __init__( self, origin: Origin, ssl_context: ssl.SSLContext | None = None, keepalive_expiry: float | None = None, http1: bool = True, http2: bool = False, retries: int = 0, local_address: str | None = None, uds: str | None = None, network_backend: AsyncNetworkBackend | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> None: self._origin = origin self._ssl_context = ssl_context self._keepalive_expiry = keepalive_expiry self._http1 = http1 self._http2 = http2 self._retries = retries self._local_address = local_address self._uds = uds self._network_backend: AsyncNetworkBackend = AutoBackend() if network_backend is None else network_backend self._connection: AsyncConnectionInterface | None = None self._connect_failed: bool = False self._request_lock = AsyncLock() self._socket_options = socket_options async def handle_async_request(self, request: Request) -> Response: if not self.can_handle_request(request.url.origin): raise RuntimeError(f"Attempted to send request to {request.url.origin} on connection to {self._origin}") try: async with self._request_lock: if self._connection is None: stream = await self._connect(request) ssl_object = stream.get_extra_info("ssl_object") http2_negotiated = ssl_object is not None and ssl_object.selected_alpn_protocol() == "h2" if http2_negotiated or (self._http2 and not self._http1): from .http2 import AsyncHTTP2Connection self._connection = AsyncHTTP2Connection( origin=self._origin, stream=stream, keepalive_expiry=self._keepalive_expiry, ) else: self._connection = AsyncHTTP11Connection( origin=self._origin, stream=stream, keepalive_expiry=self._keepalive_expiry, ) except BaseException as exc: self._connect_failed = True raise exc return await self._connection.handle_async_request(request) async def _connect(self, request: Request) -> AsyncNetworkStream: timeouts = request.extensions.get("timeout", {}) sni_hostname = request.extensions.get("sni_hostname", None) timeout = timeouts.get("connect", None) retries_left = self._retries delays = exponential_backoff(factor=RETRIES_BACKOFF_FACTOR) while True: try: if self._uds is None: kwargs = { "host": self._origin.host.decode("ascii"), "port": self._origin.port, "local_address": self._local_address, "timeout": timeout, "socket_options": self._socket_options, } async with Trace("connect_tcp", logger, request, kwargs) as trace: stream = await self._network_backend.connect_tcp(**kwargs) trace.return_value = stream else: kwargs = { "path": self._uds, "timeout": timeout, "socket_options": self._socket_options, } async with Trace("connect_unix_socket", logger, request, kwargs) as trace: stream = await self._network_backend.connect_unix_socket(**kwargs) trace.return_value = stream if self._origin.scheme in (b"https", b"wss"): ssl_context = default_ssl_context() if self._ssl_context is None else self._ssl_context alpn_protocols = (["h2", "http/1.1"] if self._http1 else ["h2"]) if self._http2 else ["http/1.1"] ssl_context.set_alpn_protocols(alpn_protocols) kwargs = { "ssl_context": ssl_context, "server_hostname": sni_hostname or self._origin.host.decode("ascii"), "timeout": timeout, } async with Trace("start_tls", logger, request, kwargs) as trace: stream = await stream.start_tls(**kwargs) trace.return_value = stream return stream except (ConnectError, ConnectTimeout): if retries_left <= 0: raise retries_left -= 1 delay = next(delays) async with Trace("retry", logger, request, kwargs) as trace: await self._network_backend.sleep(delay) def can_handle_request(self, origin: Origin) -> bool: return origin == self._origin async def aclose(self) -> None: if self._connection is not None: async with Trace("close", logger, None, {}): await self._connection.aclose() def is_connected(self) -> bool: return self._connection is not None and self._connection.is_connected() def is_available(self) -> bool: if self._connection is None: # If HTTP/2 support is enabled, and the resulting connection could # end up as HTTP/2 then we should indicate the connection as being # available to service multiple requests. return self._http2 and (self._origin.scheme == b"https" or not self._http1) and not self._connect_failed return self._connection.is_available() def has_expired(self) -> bool: if self._connection is None: return self._connect_failed return self._connection.has_expired() def is_idle(self) -> bool: if self._connection is None: return self._connect_failed return self._connection.is_idle() def can_multiplex(self) -> bool: return self._connection is not None and self._connection.can_multiplex() def is_closed(self) -> bool: if self._connection is None: return self._connect_failed return self._connection.is_closed() def info(self) -> str: if self._connection is None: return "CONNECTION FAILED" if self._connect_failed else "CONNECTING" return self._connection.info() def __repr__(self) -> str: return f"<{self.__class__.__name__} [{self.info()}]>" # These context managers are not used in the standard flow, but are # useful for testing or working with connection instances directly. async def __aenter__(self) -> AsyncHTTPConnection: return self async def __aexit__( self, exc_type: type[BaseException] | None = None, exc_value: BaseException | None = None, traceback: types.TracebackType | None = None, ) -> None: await self.aclose() pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_async/connection_pool.py000066400000000000000000000462551526547463400266710ustar00rootroot00000000000000from __future__ import annotations import ssl import sys import types import typing from collections.abc import AsyncGenerator from .._backends.auto import AutoBackend from .._backends.base import SOCKET_OPTION, AsyncNetworkBackend from .._exceptions import ConnectionNotAvailable, UnsupportedProtocol from .._models import Origin, Proxy, Request, Response from .._synchronization import AsyncEvent, AsyncShieldCancellation, AsyncThreadLock from .._utils import safe_async_iterate from .connection import AsyncHTTPConnection from .interfaces import AsyncConnectionInterface, AsyncRequestInterface class AsyncPoolRequest: def __init__(self, request: Request) -> None: self.request = request self.connection: AsyncConnectionInterface | None = None self._connection_acquired = AsyncEvent() def assign_to_connection(self, connection: AsyncConnectionInterface | None) -> None: self.connection = connection self._connection_acquired.set() def clear_connection(self) -> None: self.connection = None self._connection_acquired = AsyncEvent() async def wait_for_connection(self, timeout: float | None = None) -> AsyncConnectionInterface: if self.connection is None: await self._connection_acquired.wait(timeout=timeout) assert self.connection is not None return self.connection def is_queued(self) -> bool: return self.connection is None class AsyncConnectionPool(AsyncRequestInterface): """ A connection pool for making HTTP requests. """ def __init__( self, ssl_context: ssl.SSLContext | None = None, proxy: Proxy | None = None, max_connections: int | None = 10, max_keepalive_connections: int | None = None, keepalive_expiry: float | None = None, http1: bool = True, http2: bool = False, retries: int = 0, local_address: str | None = None, uds: str | None = None, network_backend: AsyncNetworkBackend | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> None: """ A connection pool for making HTTP requests. Parameters: ssl_context: An SSL context to use for verifying connections. If not specified, the default `httpcore2.default_ssl_context()` will be used. max_connections: The maximum number of concurrent HTTP connections that the pool should allow. Any attempt to send a request on a pool that would exceed this amount will block until a connection is available. max_keepalive_connections: The maximum number of idle HTTP connections that will be maintained in the pool. keepalive_expiry: The duration in seconds that an idle HTTP connection may be maintained for before being expired from the pool. http1: A boolean indicating if HTTP/1.1 requests should be supported by the connection pool. Defaults to True. http2: A boolean indicating if HTTP/2 requests should be supported by the connection pool. Defaults to False. retries: The maximum number of retries when trying to establish a connection. local_address: Local address to connect from. Can also be used to connect using a particular address family. Using `local_address="0.0.0.0"` will connect using an `AF_INET` address (IPv4), while using `local_address="::"` will connect using an `AF_INET6` address (IPv6). uds: Path to a Unix Domain Socket to use instead of TCP sockets. network_backend: A backend instance to use for handling network I/O. socket_options: Socket options that have to be included in the TCP socket when the connection was established. """ self._ssl_context = ssl_context self._proxy = proxy self._max_connections = sys.maxsize if max_connections is None else max_connections self._max_keepalive_connections = ( sys.maxsize if max_keepalive_connections is None else max_keepalive_connections ) self._max_keepalive_connections = min(self._max_connections, self._max_keepalive_connections) self._keepalive_expiry = keepalive_expiry self._http1 = http1 self._http2 = http2 self._retries = retries self._local_address = local_address self._uds = uds self._network_backend = AutoBackend() if network_backend is None else network_backend self._socket_options = socket_options # The mutable state on a connection pool is the queue of incoming requests, # and the set of connections that are servicing those requests. self._connections: list[AsyncConnectionInterface] = [] self._requests: list[AsyncPoolRequest] = [] # We only mutate the state of the connection pool within an 'optional_thread_lock' # context. This holds a threading lock unless we're running in async mode, # in which case it is a no-op. self._optional_thread_lock = AsyncThreadLock() def create_connection(self, origin: Origin) -> AsyncConnectionInterface: if self._proxy is not None: if self._proxy.url.scheme in (b"socks5", b"socks5h"): from .socks_proxy import AsyncSocks5Connection return AsyncSocks5Connection( proxy_origin=self._proxy.url.origin, proxy_auth=self._proxy.auth, remote_origin=origin, ssl_context=self._ssl_context, keepalive_expiry=self._keepalive_expiry, http1=self._http1, http2=self._http2, network_backend=self._network_backend, ) elif origin.scheme == b"http": from .http_proxy import AsyncForwardHTTPConnection return AsyncForwardHTTPConnection( proxy_origin=self._proxy.url.origin, proxy_headers=self._proxy.headers, proxy_ssl_context=self._proxy.ssl_context, remote_origin=origin, keepalive_expiry=self._keepalive_expiry, network_backend=self._network_backend, ) from .http_proxy import AsyncTunnelHTTPConnection return AsyncTunnelHTTPConnection( proxy_origin=self._proxy.url.origin, proxy_headers=self._proxy.headers, proxy_ssl_context=self._proxy.ssl_context, remote_origin=origin, ssl_context=self._ssl_context, keepalive_expiry=self._keepalive_expiry, http1=self._http1, http2=self._http2, network_backend=self._network_backend, ) return AsyncHTTPConnection( origin=origin, ssl_context=self._ssl_context, keepalive_expiry=self._keepalive_expiry, http1=self._http1, http2=self._http2, retries=self._retries, local_address=self._local_address, uds=self._uds, network_backend=self._network_backend, socket_options=self._socket_options, ) @property def connections(self) -> list[AsyncConnectionInterface]: """ Return a list of the connections currently in the pool. For example: ```python >>> pool.connections [ , , , ] ``` """ return list(self._connections) async def handle_async_request(self, request: Request) -> Response: """ Send an HTTP request, and return an HTTP response. This is the core implementation that is called into by `.request()` or `.stream()`. """ scheme = request.url.scheme.decode() if scheme == "": raise UnsupportedProtocol("Request URL is missing an 'http://' or 'https://' protocol.") if scheme not in ("http", "https", "ws", "wss"): raise UnsupportedProtocol(f"Request URL has an unsupported protocol '{scheme}://'.") timeouts = request.extensions.get("timeout", {}) timeout = timeouts.get("pool", None) with self._optional_thread_lock: # Add the incoming request to our request queue. pool_request = AsyncPoolRequest(request) self._requests.append(pool_request) try: while True: with self._optional_thread_lock: # Assign incoming requests to available connections, # closing or creating new connections as required. closing = self._assign_requests_to_connections() await self._close_connections(closing) # Wait until this request has an assigned connection. connection = await pool_request.wait_for_connection(timeout=timeout) try: # Send the request on the assigned connection. response = await connection.handle_async_request(pool_request.request) except ConnectionNotAvailable: # In some cases a connection may initially be available to # handle a request, but then become unavailable. # # In this case we clear the connection and try again. pool_request.clear_connection() else: break # pragma: no cover except BaseException as exc: with self._optional_thread_lock: # For any exception or cancellation we remove the request from # the queue, and then re-assign requests to connections. self._requests.remove(pool_request) closing = self._assign_requests_to_connections() await self._close_connections(closing) raise exc from None # Return the response. Note that in this case we still have to manage # the point at which the response is closed. assert isinstance(response.stream, typing.AsyncIterable) return Response( status=response.status, headers=response.headers, content=PoolByteStream(stream=response.stream, pool_request=pool_request, pool=self), extensions=response.extensions, ) def _assign_requests_to_connections(self) -> list[AsyncConnectionInterface]: """ Manage the state of the connection pool, assigning incoming requests to connections as available. Called whenever a new request is added or removed from the pool. Any closing connections are returned, allowing the I/O for closing those connections to be handled separately. """ closing_connections: list[AsyncConnectionInterface] = [] retained_connections: list[AsyncConnectionInterface] = [] # Connections currently referenced by an in-flight request, including # connections that are in the process of being established and idle # connections reserved by an assigned-but-not-yet-sent request. request_connections = {r.connection for r in self._requests} # First we handle cleaning up any connections that are closed # or have expired their keep-alive, in a single pass. Reserved # connections skip the expiry check: they were checked when assigned, # and `has_expired()` on an idle connection probes the socket. for connection in self._connections: reserved = connection in request_connections if connection.is_closed(): continue elif not (connection.is_connected() or reserved): # Garbage: a NEW-state connection whose request was cancelled # before the TCP handshake completed. Drop it without closing # (there is no socket to close yet). continue elif not reserved and connection.has_expired(): closing_connections.append(connection) else: retained_connections.append(connection) # Then we close any surplus idle connections, to enforce the # max_keepalive_connections setting. Reserved connections are not # surplus: a request is about to be sent on them. idle_surplus = ( sum(connection.is_idle() and connection not in request_connections for connection in retained_connections) - self._max_keepalive_connections ) if idle_surplus > 0: kept: list[AsyncConnectionInterface] = [] for connection in retained_connections: if idle_surplus > 0 and connection.is_idle() and connection not in request_connections: closing_connections.append(connection) idle_surplus -= 1 else: kept.append(connection) retained_connections = kept self._connections = retained_connections # Snapshot the set of reusable connections once, rather than rebuilding # it per queued request โ€” this is what brings the loop from O(N*M) to # O(N+M) in the common case. # # An idle connection already assigned to an in-flight request is # reserved: it stays IDLE until the winning task sends on it, so # without this exclusion the next pass would assign it again and the # loser would churn through `ConnectionNotAvailable`. Multiplexing # connections are exempt: they can take further requests while idle. available_connections = [ connection for connection in self._connections if connection.is_available() and not (connection.is_idle() and connection in request_connections and not connection.can_multiplex()) ] new_connection_budget = self._max_connections - len(self._connections) # Assign queued requests to connections. Once no connection is # available and no new connection may be created, no queued request # can be assigned, so the scan stops early: this keeps a pass on a # saturated pool O(connections) rather than O(in-flight requests). for pool_request in self._requests: if not available_connections and new_connection_budget <= 0: break if not pool_request.is_queued(): continue origin = pool_request.request.url.origin # There are three cases for how we may be able to handle the request: # # 1. There is an existing connection that can handle the request. # 2. We can create a new connection to handle the request. # 3. We can close an idle connection and then create a new connection # to handle the request. for idx, connection in enumerate(available_connections): if connection.can_handle_request(origin): pool_request.assign_to_connection(connection) if connection.is_idle() and not connection.can_multiplex(): # An idle HTTP/1.1 connection can only take this # single request until it is released. del available_connections[idx] break else: if new_connection_budget > 0: connection = self.create_connection(origin) self._connections.append(connection) pool_request.assign_to_connection(connection) new_connection_budget -= 1 continue for idx, connection in enumerate(available_connections): if connection.is_idle(): del available_connections[idx] self._connections.remove(connection) closing_connections.append(connection) connection = self.create_connection(origin) self._connections.append(connection) pool_request.assign_to_connection(connection) break return closing_connections async def _close_connections(self, closing: list[AsyncConnectionInterface]) -> None: # Close connections which have been removed from the pool. with AsyncShieldCancellation(): for connection in closing: await connection.aclose() async def aclose(self) -> None: # Explicitly close the connection pool. # Clears all existing requests and connections. with self._optional_thread_lock: closing_connections = list(self._connections) self._connections = [] await self._close_connections(closing_connections) async def __aenter__(self) -> AsyncConnectionPool: return self async def __aexit__( self, exc_type: type[BaseException] | None = None, exc_value: BaseException | None = None, traceback: types.TracebackType | None = None, ) -> None: await self.aclose() def __repr__(self) -> str: class_name = self.__class__.__name__ with self._optional_thread_lock: request_is_queued = [request.is_queued() for request in self._requests] connection_is_idle = [connection.is_idle() for connection in self._connections] num_active_requests = request_is_queued.count(False) num_queued_requests = request_is_queued.count(True) num_active_connections = connection_is_idle.count(False) num_idle_connections = connection_is_idle.count(True) requests_info = f"Requests: {num_active_requests} active, {num_queued_requests} queued" connection_info = f"Connections: {num_active_connections} active, {num_idle_connections} idle" return f"<{class_name} [{requests_info} | {connection_info}]>" class PoolByteStream: def __init__( self, stream: typing.AsyncIterable[bytes], pool_request: AsyncPoolRequest, pool: AsyncConnectionPool, ) -> None: self._stream = stream self._pool_request = pool_request self._pool = pool self._closed = False async def __aiter__(self) -> AsyncGenerator[bytes]: async with safe_async_iterate(self._stream) as iterator: async for chunk in iterator: yield chunk async def aclose(self) -> None: if not self._closed: self._closed = True with AsyncShieldCancellation(): if hasattr(self._stream, "aclose"): await self._stream.aclose() with self._pool._optional_thread_lock: self._pool._requests.remove(self._pool_request) closing = self._pool._assign_requests_to_connections() await self._pool._close_connections(closing) pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_async/http11.py000066400000000000000000000331461526547463400246150ustar00rootroot00000000000000from __future__ import annotations import enum import logging import ssl import time import types import typing from collections.abc import AsyncGenerator import h11 from .._backends.base import AsyncNetworkStream from .._exceptions import ( ConnectionNotAvailable, LocalProtocolError, RemoteProtocolError, WriteError, map_exceptions, ) from .._models import Origin, Request, Response from .._synchronization import AsyncLock, AsyncShieldCancellation from .._trace import Trace from .._utils import safe_async_iterate from .interfaces import AsyncConnectionInterface logger = logging.getLogger("httpcore2.http11") # A subset of `h11.Event` types supported by `_send_event` H11SendEvent = h11.Request | h11.Data | h11.EndOfMessage class HTTPConnectionState(enum.IntEnum): NEW = 0 ACTIVE = 1 IDLE = 2 CLOSED = 3 class AsyncHTTP11Connection(AsyncConnectionInterface): READ_NUM_BYTES = 64 * 1024 MAX_INCOMPLETE_EVENT_SIZE = 100 * 1024 def __init__( self, origin: Origin, stream: AsyncNetworkStream, keepalive_expiry: float | None = None, ) -> None: self._origin = origin self._network_stream = stream self._keepalive_expiry: float | None = keepalive_expiry self._expire_at: float | None = None self._state = HTTPConnectionState.NEW self._state_lock = AsyncLock() self._request_count = 0 self._h11_state = h11.Connection( our_role=h11.CLIENT, max_incomplete_event_size=self.MAX_INCOMPLETE_EVENT_SIZE, ) async def handle_async_request(self, request: Request) -> Response: if not self.can_handle_request(request.url.origin): raise RuntimeError(f"Attempted to send request to {request.url.origin} on connection to {self._origin}") async with self._state_lock: if self._state in (HTTPConnectionState.NEW, HTTPConnectionState.IDLE): self._request_count += 1 self._state = HTTPConnectionState.ACTIVE self._expire_at = None else: raise ConnectionNotAvailable() try: kwargs = {"request": request} try: async with Trace("send_request_headers", logger, request, kwargs) as trace: await self._send_request_headers(**kwargs) async with Trace("send_request_body", logger, request, kwargs) as trace: await self._send_request_body(**kwargs) except WriteError: # If we get a write error while we're writing the request, # then we suppress this error and move on to attempting to # read the response. Servers can sometimes close the request # preemptively and then respond with a well formed HTTP # error response. pass async with Trace("receive_response_headers", logger, request, kwargs) as trace: ( http_version, status, reason_phrase, headers, trailing_data, ) = await self._receive_response_headers(**kwargs) trace.return_value = ( http_version, status, reason_phrase, headers, ) network_stream = self._network_stream # CONNECT or Upgrade request if (status == 101) or ((request.method == b"CONNECT") and (200 <= status < 300)): network_stream = AsyncHTTP11UpgradeStream(network_stream, trailing_data) return Response( status=status, headers=headers, content=HTTP11ConnectionByteStream(self, request), extensions={ "http_version": http_version, "reason_phrase": reason_phrase, "network_stream": network_stream, }, ) except BaseException as exc: with AsyncShieldCancellation(): async with Trace("response_closed", logger, request) as trace: await self._response_closed() raise exc # Sending the request... async def _send_request_headers(self, request: Request) -> None: timeouts = request.extensions.get("timeout", {}) timeout = timeouts.get("write", None) with map_exceptions({h11.LocalProtocolError: LocalProtocolError}): event = h11.Request( method=request.method, target=request.url.target, headers=request.headers, ) await self._send_event(event, timeout=timeout) async def _send_request_body(self, request: Request) -> None: timeouts = request.extensions.get("timeout", {}) timeout = timeouts.get("write", None) assert isinstance(request.stream, typing.AsyncIterable) async with safe_async_iterate(request.stream) as iterator: async for chunk in iterator: event = h11.Data(data=chunk) await self._send_event(event, timeout=timeout) await self._send_event(h11.EndOfMessage(), timeout=timeout) async def _send_event(self, event: h11.Event, timeout: float | None = None) -> None: bytes_to_send = self._h11_state.send(event) if bytes_to_send is not None: await self._network_stream.write(bytes_to_send, timeout=timeout) # Receiving the response... async def _receive_response_headers( self, request: Request ) -> tuple[bytes, int, bytes, list[tuple[bytes, bytes]], bytes]: timeouts = request.extensions.get("timeout", {}) timeout = timeouts.get("read", None) while True: event = await self._receive_event(timeout=timeout) if isinstance(event, h11.Response): break if isinstance(event, h11.InformationalResponse) and event.status_code == 101: break http_version = b"HTTP/" + event.http_version # h11 version 0.11+ supports a `raw_items` interface to get the # raw header casing, rather than the enforced lowercase headers. headers = event.headers.raw_items() trailing_data, _ = self._h11_state.trailing_data return http_version, event.status_code, event.reason, headers, trailing_data async def _receive_response_body(self, request: Request) -> AsyncGenerator[bytes]: timeouts = request.extensions.get("timeout", {}) timeout = timeouts.get("read", None) while True: event = await self._receive_event(timeout=timeout) if isinstance(event, h11.Data): yield bytes(event.data) elif isinstance(event, (h11.EndOfMessage, h11.PAUSED)): break async def _receive_event(self, timeout: float | None = None) -> h11.Event | type[h11.PAUSED]: while True: with map_exceptions({h11.RemoteProtocolError: RemoteProtocolError}): event = self._h11_state.next_event() if event is h11.NEED_DATA: data = await self._network_stream.read(self.READ_NUM_BYTES, timeout=timeout) # If we feed this case through h11 we'll raise an exception like: # # httpcore2.RemoteProtocolError: can't handle event type # ConnectionClosed when role=SERVER and state=SEND_RESPONSE # # Which is accurate, but not very informative from an end-user # perspective. Instead we handle this case distinctly and treat # it as a ConnectError. if data == b"" and self._h11_state.their_state == h11.SEND_RESPONSE: msg = "Server disconnected without sending a response." raise RemoteProtocolError(msg) self._h11_state.receive_data(data) else: # mypy fails to narrow the type in the above if statement above return event # type: ignore[return-value] async def _response_closed(self) -> None: async with self._state_lock: if self._h11_state.our_state is h11.DONE and self._h11_state.their_state is h11.DONE: self._state = HTTPConnectionState.IDLE self._h11_state.start_next_cycle() if self._keepalive_expiry is not None: now = time.monotonic() self._expire_at = now + self._keepalive_expiry else: await self.aclose() # Once the connection is no longer required... async def aclose(self) -> None: # Note that this method unilaterally closes the connection, and does # not have any kind of locking in place around it. self._state = HTTPConnectionState.CLOSED await self._network_stream.aclose() # The AsyncConnectionInterface methods provide information about the state of # the connection, allowing for a connection pooling implementation to # determine when to reuse and when to close the connection... def can_handle_request(self, origin: Origin) -> bool: return origin == self._origin def is_connected(self) -> bool: return not self.is_closed() def is_available(self) -> bool: # Note that HTTP/1.1 connections in the "NEW" state are not treated as # being "available". The control flow which created the connection will # be able to send an outgoing request, but the connection will not be # acquired from the connection pool for any other request. return self._state == HTTPConnectionState.IDLE def has_expired(self) -> bool: now = time.monotonic() # Read `_expire_at` once into a local: on free-threaded builds another # thread may reset it to `None` between the check and the comparison. expire_at = self._expire_at keepalive_expired = expire_at is not None and now > expire_at # If the HTTP connection is idle but the socket is readable, then the # only valid state is that the socket is about to return b"", indicating # a server-initiated disconnect. server_disconnected = self._state == HTTPConnectionState.IDLE and self._network_stream.get_extra_info( "is_readable" ) return keepalive_expired or server_disconnected def is_idle(self) -> bool: return self._state == HTTPConnectionState.IDLE def is_closed(self) -> bool: return self._state == HTTPConnectionState.CLOSED def info(self) -> str: origin = str(self._origin) return f"{origin!r}, HTTP/1.1, {self._state.name}, Request Count: {self._request_count}" def __repr__(self) -> str: class_name = self.__class__.__name__ origin = str(self._origin) return f"<{class_name} [{origin!r}, {self._state.name}, Request Count: {self._request_count}]>" # These context managers are not used in the standard flow, but are # useful for testing or working with connection instances directly. async def __aenter__(self) -> AsyncHTTP11Connection: return self async def __aexit__( self, exc_type: type[BaseException] | None = None, exc_value: BaseException | None = None, traceback: types.TracebackType | None = None, ) -> None: await self.aclose() class HTTP11ConnectionByteStream: def __init__(self, connection: AsyncHTTP11Connection, request: Request) -> None: self._connection = connection self._request = request self._closed = False async def __aiter__(self) -> AsyncGenerator[bytes]: kwargs = {"request": self._request} try: async with Trace("receive_response_body", logger, self._request, kwargs): async with safe_async_iterate(self._connection._receive_response_body(**kwargs)) as iterator: async for chunk in iterator: yield chunk except BaseException as exc: # If we get an exception while streaming the response, # we want to close the response (and possibly the connection) # before raising that exception. with AsyncShieldCancellation(): await self.aclose() raise exc async def aclose(self) -> None: if not self._closed: self._closed = True async with Trace("response_closed", logger, self._request): await self._connection._response_closed() class AsyncHTTP11UpgradeStream(AsyncNetworkStream): def __init__(self, stream: AsyncNetworkStream, leading_data: bytes) -> None: self._stream = stream self._leading_data = leading_data async def read(self, max_bytes: int, timeout: float | None = None) -> bytes: if self._leading_data: buffer = self._leading_data[:max_bytes] self._leading_data = self._leading_data[max_bytes:] return buffer else: return await self._stream.read(max_bytes, timeout) async def write(self, buffer: bytes, timeout: float | None = None) -> None: await self._stream.write(buffer, timeout) async def aclose(self) -> None: await self._stream.aclose() async def start_tls( self, ssl_context: ssl.SSLContext, server_hostname: str | None = None, timeout: float | None = None, ) -> AsyncNetworkStream: return await self._stream.start_tls(ssl_context, server_hostname, timeout) def get_extra_info(self, info: str) -> typing.Any: return self._stream.get_extra_info(info) pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_async/http2.py000066400000000000000000000610401526547463400245270ustar00rootroot00000000000000from __future__ import annotations import enum import logging import time import types import typing from collections.abc import AsyncGenerator import h2.config import h2.connection import h2.events import h2.exceptions import h2.settings from .._backends.base import AsyncNetworkStream from .._exceptions import ConnectionNotAvailable, LocalProtocolError, RemoteProtocolError from .._models import Origin, Request, Response from .._synchronization import AsyncLock, AsyncSemaphore, AsyncShieldCancellation from .._trace import Trace from .._utils import safe_async_iterate from .interfaces import AsyncConnectionInterface logger = logging.getLogger("httpcore2.http2") def has_body_headers(request: Request) -> bool: return any(k.lower() == b"content-length" or k.lower() == b"transfer-encoding" for k, _v in request.headers) class HTTPConnectionState(enum.IntEnum): ACTIVE = 1 IDLE = 2 CLOSED = 3 class AsyncHTTP2Connection(AsyncConnectionInterface): READ_NUM_BYTES = 64 * 1024 CONFIG = h2.config.H2Configuration(validate_inbound_headers=False) def __init__( self, origin: Origin, stream: AsyncNetworkStream, keepalive_expiry: float | None = None, ): self._origin = origin self._network_stream = stream self._keepalive_expiry: float | None = keepalive_expiry self._h2_state = h2.connection.H2Connection(config=self.CONFIG) self._state = HTTPConnectionState.IDLE self._expire_at: float | None = None self._request_count = 0 self._init_lock = AsyncLock() self._state_lock = AsyncLock() self._read_lock = AsyncLock() self._write_lock = AsyncLock() self._sent_connection_init = False self._used_all_stream_ids = False self._connection_error = False # Mapping from stream ID to response stream events. self._events: dict[ int, list[h2.events.ResponseReceived | h2.events.DataReceived | h2.events.StreamEnded | h2.events.StreamReset,], ] = {} # Connection terminated events are stored as state since # we need to handle them for all streams. self._connection_terminated: h2.events.ConnectionTerminated | None = None self._read_exception: Exception | None = None self._write_exception: Exception | None = None async def handle_async_request(self, request: Request) -> Response: if not self.can_handle_request(request.url.origin): # This cannot occur in normal operation, since the connection pool # will only send requests on connections that handle them. # It's in place simply for resilience as a guard against incorrect # usage, for anyone working directly with httpcore connections. raise RuntimeError(f"Attempted to send request to {request.url.origin} on connection to {self._origin}") async with self._state_lock: if self._state in (HTTPConnectionState.ACTIVE, HTTPConnectionState.IDLE): self._request_count += 1 self._expire_at = None self._state = HTTPConnectionState.ACTIVE else: raise ConnectionNotAvailable() async with self._init_lock: if not self._sent_connection_init: try: sci_kwargs = {"request": request} async with Trace("send_connection_init", logger, request, sci_kwargs): await self._send_connection_init(**sci_kwargs) except BaseException as exc: with AsyncShieldCancellation(): await self.aclose() raise exc self._sent_connection_init = True # Initially start with just 1 until the remote server provides # its max_concurrent_streams value self._max_streams = 1 # Revoked permits still held by active or queued requests. self._max_streams_deficit = 0 local_settings_max_streams = self._h2_state.local_settings.max_concurrent_streams self._max_streams_semaphore = AsyncSemaphore(local_settings_max_streams) for _ in range(local_settings_max_streams - self._max_streams): await self._max_streams_semaphore.acquire() # A queued request may receive a permit just before the limit drops. while True: await self._max_streams_semaphore.acquire() with AsyncShieldCancellation(): async with self._state_lock: if not self._max_streams_deficit: break self._max_streams_deficit -= 1 try: stream_id = self._h2_state.get_next_available_stream_id() self._events[stream_id] = [] except h2.exceptions.NoAvailableStreamIDError: # pragma: no cover self._used_all_stream_ids = True self._request_count -= 1 await self._max_streams_semaphore.release() raise ConnectionNotAvailable() try: kwargs = {"request": request, "stream_id": stream_id} async with Trace("send_request_headers", logger, request, kwargs): await self._send_request_headers(request=request, stream_id=stream_id) async with Trace("send_request_body", logger, request, kwargs): await self._send_request_body(request=request, stream_id=stream_id) async with Trace("receive_response_headers", logger, request, kwargs) as trace: status, headers = await self._receive_response(request=request, stream_id=stream_id) trace.return_value = (status, headers) return Response( status=status, headers=headers, content=HTTP2ConnectionByteStream(self, request, stream_id=stream_id), extensions={ "http_version": b"HTTP/2", "network_stream": self._network_stream, "stream_id": stream_id, }, ) except BaseException as exc: # noqa: PIE786 with AsyncShieldCancellation(): kwargs = {"stream_id": stream_id} async with Trace("response_closed", logger, request, kwargs): await self._response_closed(stream_id=stream_id) if isinstance(exc, h2.exceptions.ProtocolError): # One case where h2 can raise a protocol error is when a # closed frame has been seen by the state machine. # # This happens when one stream is reading, and encounters # a GOAWAY event. Other flows of control may then raise # a protocol error at any point they interact with the 'h2_state'. # # In this case we'll have stored the event, and should raise # it as a RemoteProtocolError. if self._connection_terminated: # pragma: no cover raise RemoteProtocolError(self._connection_terminated) # If h2 raises a protocol error in some other state then we # must somehow have made a protocol violation. raise LocalProtocolError(exc) # pragma: no cover raise exc async def _send_connection_init(self, request: Request) -> None: """ The HTTP/2 connection requires some initial setup before we can start using individual request/response streams on it. """ # Need to set these manually here instead of manipulating via # __setitem__() otherwise the H2Connection will emit SettingsUpdate # frames in addition to sending the undesired defaults. self._h2_state.local_settings = h2.settings.Settings( client=True, initial_values={ # Disable PUSH_PROMISE frames from the server since we don't do anything # with them for now. Maybe when we support caching? h2.settings.SettingCodes.ENABLE_PUSH: 0, # These two are taken from h2 for safe defaults h2.settings.SettingCodes.MAX_CONCURRENT_STREAMS: 100, h2.settings.SettingCodes.MAX_HEADER_LIST_SIZE: 65536, }, ) # Some websites (*cough* Yahoo *cough*) balk at this setting being # present in the initial handshake since it's not defined in the original # RFC despite the RFC mandating ignoring settings you don't know about. del self._h2_state.local_settings[h2.settings.SettingCodes.ENABLE_CONNECT_PROTOCOL] self._h2_state.initiate_connection() self._h2_state.increment_flow_control_window(2**24) await self._write_outgoing_data(request) # Sending the request... async def _send_request_headers(self, request: Request, stream_id: int) -> None: """ Send the request headers to a given stream ID. """ end_stream = not has_body_headers(request) # In HTTP/2 the ':authority' pseudo-header is used instead of 'Host'. # In order to gracefully handle HTTP/1.1 and HTTP/2 we always require # HTTP/1.1 style headers, and map them appropriately if we end up on # an HTTP/2 connection. authority = [v for k, v in request.headers if k.lower() == b"host"][0] headers = [ (b":method", request.method), (b":authority", authority), (b":scheme", request.url.scheme), (b":path", request.url.target), ] + [ (k.lower(), v) for k, v in request.headers if k.lower() not in ( b"host", b"transfer-encoding", ) ] self._h2_state.send_headers(stream_id, headers, end_stream=end_stream) self._h2_state.increment_flow_control_window(2**24, stream_id=stream_id) await self._write_outgoing_data(request) async def _send_request_body(self, request: Request, stream_id: int) -> None: """ Iterate over the request body sending it to a given stream ID. """ if not has_body_headers(request): return assert isinstance(request.stream, typing.AsyncIterable) async with safe_async_iterate(request.stream) as iterator: async for chunk in iterator: await self._send_stream_data(request, stream_id, chunk) await self._send_end_stream(request, stream_id) async def _send_stream_data(self, request: Request, stream_id: int, data: bytes) -> None: """ Send a single chunk of data in one or more data frames. """ position = 0 while position < len(data): max_flow = await self._wait_for_outgoing_flow(request, stream_id) chunk = data[position : position + max_flow] position += len(chunk) self._h2_state.send_data(stream_id, chunk) await self._write_outgoing_data(request) async def _send_end_stream(self, request: Request, stream_id: int) -> None: """ Send an empty data frame on on a given stream ID with the END_STREAM flag set. """ self._h2_state.end_stream(stream_id) await self._write_outgoing_data(request) # Receiving the response... async def _receive_response(self, request: Request, stream_id: int) -> tuple[int, list[tuple[bytes, bytes]]]: """ Return the response status code and headers for a given stream ID. """ while True: event = await self._receive_stream_event(request, stream_id) if isinstance(event, h2.events.ResponseReceived): break status_code = 200 headers: list[tuple[bytes, bytes]] = [] assert event.headers is not None for k, v in event.headers: if k == b":status": status_code = int(v.decode("ascii", errors="ignore")) elif not k.startswith(b":"): headers.append((k, v)) return (status_code, headers) async def _receive_response_body(self, request: Request, stream_id: int) -> AsyncGenerator[bytes]: """ Iterator that returns the bytes of the response body for a given stream ID. """ while True: event = await self._receive_stream_event(request, stream_id) if isinstance(event, h2.events.DataReceived): assert event.flow_controlled_length is not None assert event.data is not None amount = event.flow_controlled_length self._h2_state.acknowledge_received_data(amount, stream_id) await self._write_outgoing_data(request) yield event.data elif isinstance(event, h2.events.StreamEnded): break async def _receive_stream_event( self, request: Request, stream_id: int ) -> h2.events.ResponseReceived | h2.events.DataReceived | h2.events.StreamEnded: """ Return the next available event for a given stream ID. Will read more data from the network if required. """ while not self._events.get(stream_id): await self._receive_events(request, stream_id) event = self._events[stream_id].pop(0) if isinstance(event, h2.events.StreamReset): raise RemoteProtocolError(event) return event async def _receive_events(self, request: Request, stream_id: int | None = None) -> None: """ Read some data from the network until we see one or more events for a given stream ID. """ async with self._read_lock: if self._connection_terminated is not None: last_stream_id = self._connection_terminated.last_stream_id if stream_id and last_stream_id and stream_id > last_stream_id: self._request_count -= 1 raise ConnectionNotAvailable() raise RemoteProtocolError(self._connection_terminated) # This conditional is a bit icky. We don't want to block reading if we've # actually got an event to return for a given stream. We need to do that # check *within* the atomic read lock. Though it also need to be optional, # because when we call it from `_wait_for_outgoing_flow` we *do* want to # block until we've available flow control, event when we have events # pending for the stream ID we're attempting to send on. if stream_id is None or not self._events.get(stream_id): events = await self._read_incoming_data(request) for event in events: if isinstance(event, h2.events.RemoteSettingsChanged): async with Trace("receive_remote_settings", logger, request) as trace: trace.return_value = event elif isinstance( event, ( h2.events.ResponseReceived, h2.events.DataReceived, h2.events.StreamEnded, h2.events.StreamReset, ), ): if event.stream_id in self._events: self._events[event.stream_id].append(event) elif isinstance(event, h2.events.ConnectionTerminated): self._connection_terminated = event await self._write_outgoing_data(request) async def _receive_remote_settings_change(self, event: h2.events.RemoteSettingsChanged) -> None: max_concurrent_streams = event.changed_settings.get(h2.settings.SettingCodes.MAX_CONCURRENT_STREAMS) if max_concurrent_streams: new_max_streams = min( max_concurrent_streams.new_value, self._h2_state.local_settings.max_concurrent_streams, ) if new_max_streams and new_max_streams != self._max_streams: # Never wait for permits while holding the read lock. while new_max_streams > self._max_streams: if self._max_streams_deficit > 0: self._max_streams_deficit -= 1 else: await self._max_streams_semaphore.release() self._max_streams += 1 while new_max_streams < self._max_streams: if not self._max_streams_semaphore.acquire_if_available(): self._max_streams_deficit += 1 self._max_streams -= 1 async def _response_closed(self, stream_id: int) -> None: async with self._state_lock: if stream_id in self._events: if self._max_streams_deficit > 0: self._max_streams_deficit -= 1 else: await self._max_streams_semaphore.release() del self._events[stream_id] if self._connection_terminated and not self._events: await self.aclose() elif self._state == HTTPConnectionState.ACTIVE and not self._events: self._state = HTTPConnectionState.IDLE if self._keepalive_expiry is not None: now = time.monotonic() self._expire_at = now + self._keepalive_expiry if self._used_all_stream_ids: # pragma: no cover await self.aclose() async def aclose(self) -> None: # Note that this method unilaterally closes the connection, and does # not have any kind of locking in place around it. self._h2_state.close_connection() self._state = HTTPConnectionState.CLOSED await self._network_stream.aclose() # Wrappers around network read/write operations... async def _read_incoming_data(self, request: Request) -> list[h2.events.Event]: timeouts = request.extensions.get("timeout", {}) timeout = timeouts.get("read", None) if self._read_exception is not None: raise self._read_exception # pragma: no cover try: data = await self._network_stream.read(self.READ_NUM_BYTES, timeout) if data == b"": raise RemoteProtocolError("Server disconnected") except Exception as exc: # If we get a network error we should: # # 1. Save the exception and just raise it immediately on any future reads. # (For example, this means that a single read timeout or disconnect will # immediately close all pending streams. Without requiring multiple # sequential timeouts.) # 2. Mark the connection as errored, so that we don't accept any other # incoming requests. self._read_exception = exc self._connection_error = True raise exc # Apply settings and stream admission limits atomically. with AsyncShieldCancellation(): async with self._state_lock: events: list[h2.events.Event] = self._h2_state.receive_data(data) for event in events: if isinstance(event, h2.events.RemoteSettingsChanged): await self._receive_remote_settings_change(event) return events async def _write_outgoing_data(self, request: Request) -> None: timeouts = request.extensions.get("timeout", {}) timeout = timeouts.get("write", None) async with self._write_lock: data_to_send = self._h2_state.data_to_send() if self._write_exception is not None: raise self._write_exception # pragma: no cover try: await self._network_stream.write(data_to_send, timeout) except Exception as exc: # pragma: no cover # If we get a network error we should: # # 1. Save the exception and just raise it immediately on any future write. # (For example, this means that a single write timeout or disconnect will # immediately close all pending streams. Without requiring multiple # sequential timeouts.) # 2. Mark the connection as errored, so that we don't accept any other # incoming requests. self._write_exception = exc self._connection_error = True raise exc # Flow control... async def _wait_for_outgoing_flow(self, request: Request, stream_id: int) -> int: """ Returns the maximum allowable outgoing flow for a given stream. If the allowable flow is zero, then waits on the network until WindowUpdated frames have increased the flow rate. https://tools.ietf.org/html/rfc7540#section-6.9 """ local_flow: int = self._h2_state.local_flow_control_window(stream_id) max_frame_size: int = self._h2_state.max_outbound_frame_size flow = min(local_flow, max_frame_size) while flow <= 0: await self._receive_events(request) local_flow = self._h2_state.local_flow_control_window(stream_id) max_frame_size = self._h2_state.max_outbound_frame_size flow = min(local_flow, max_frame_size) return flow # Interface for connection pooling... def can_handle_request(self, origin: Origin) -> bool: return origin == self._origin def is_connected(self) -> bool: return not self.is_closed() def is_available(self) -> bool: return ( self._state != HTTPConnectionState.CLOSED and not self._connection_error and not self._used_all_stream_ids and not (self._h2_state.state_machine.state == h2.connection.ConnectionState.CLOSED) ) def has_expired(self) -> bool: now = time.monotonic() # Read `_expire_at` once into a local: on free-threaded builds another # thread may reset it to `None` between the check and the comparison. expire_at = self._expire_at return expire_at is not None and now > expire_at def is_idle(self) -> bool: return self._state == HTTPConnectionState.IDLE def can_multiplex(self) -> bool: return True def is_closed(self) -> bool: return self._state == HTTPConnectionState.CLOSED def info(self) -> str: origin = str(self._origin) return f"{origin!r}, HTTP/2, {self._state.name}, Request Count: {self._request_count}" def __repr__(self) -> str: class_name = self.__class__.__name__ origin = str(self._origin) return f"<{class_name} [{origin!r}, {self._state.name}, Request Count: {self._request_count}]>" # These context managers are not used in the standard flow, but are # useful for testing or working with connection instances directly. async def __aenter__(self) -> AsyncHTTP2Connection: return self async def __aexit__( self, exc_type: type[BaseException] | None = None, exc_value: BaseException | None = None, traceback: types.TracebackType | None = None, ) -> None: await self.aclose() class HTTP2ConnectionByteStream: def __init__(self, connection: AsyncHTTP2Connection, request: Request, stream_id: int) -> None: self._connection = connection self._request = request self._stream_id = stream_id self._closed = False async def __aiter__(self) -> AsyncGenerator[bytes]: kwargs = {"request": self._request, "stream_id": self._stream_id} try: async with Trace("receive_response_body", logger, self._request, kwargs): async with safe_async_iterate( self._connection._receive_response_body(request=self._request, stream_id=self._stream_id) ) as iterator: async for chunk in iterator: yield chunk except BaseException as exc: # If we get an exception while streaming the response, # we want to close the response (and possibly the connection) # before raising that exception. with AsyncShieldCancellation(): await self.aclose() raise exc async def aclose(self) -> None: if not self._closed: self._closed = True kwargs = {"stream_id": self._stream_id} async with Trace("response_closed", logger, self._request, kwargs): await self._connection._response_closed(stream_id=self._stream_id) pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_async/http_proxy.py000066400000000000000000000351311526547463400257100ustar00rootroot00000000000000from __future__ import annotations import base64 import logging import ssl import typing from .._backends.base import SOCKET_OPTION, AsyncNetworkBackend from .._exceptions import ProxyError from .._models import ( URL, Origin, Request, Response, enforce_bytes, enforce_headers, enforce_url, ) from .._ssl import default_ssl_context from .._synchronization import AsyncLock from .._trace import Trace from .connection import AsyncHTTPConnection from .connection_pool import AsyncConnectionPool from .http11 import AsyncHTTP11Connection from .interfaces import AsyncConnectionInterface ByteOrStr = bytes | str HeadersAsSequence = typing.Sequence[tuple[ByteOrStr, ByteOrStr]] HeadersAsMapping = typing.Mapping[ByteOrStr, ByteOrStr] logger = logging.getLogger("httpcore2.proxy") def merge_headers( default_headers: typing.Sequence[tuple[bytes, bytes]] | None = None, override_headers: typing.Sequence[tuple[bytes, bytes]] | None = None, ) -> list[tuple[bytes, bytes]]: """ Append default_headers and override_headers, de-duplicating if a key exists in both cases. """ default_headers = [] if default_headers is None else list(default_headers) override_headers = [] if override_headers is None else list(override_headers) has_override = set(key.lower() for key, _value in override_headers) default_headers = [(key, value) for key, value in default_headers if key.lower() not in has_override] return default_headers + override_headers class AsyncHTTPProxy(AsyncConnectionPool): # pragma: no cover """ A connection pool that sends requests via an HTTP proxy. """ def __init__( self, proxy_url: URL | bytes | str, proxy_auth: tuple[bytes | str, bytes | str] | None = None, proxy_headers: HeadersAsMapping | HeadersAsSequence | None = None, ssl_context: ssl.SSLContext | None = None, proxy_ssl_context: ssl.SSLContext | None = None, max_connections: int | None = 10, max_keepalive_connections: int | None = None, keepalive_expiry: float | None = None, http1: bool = True, http2: bool = False, retries: int = 0, local_address: str | None = None, uds: str | None = None, network_backend: AsyncNetworkBackend | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> None: """ A connection pool for making HTTP requests. Parameters: proxy_url: The URL to use when connecting to the proxy server. For example `"http://127.0.0.1:8080/"`. proxy_auth: Any proxy authentication as a two-tuple of (username, password). May be either bytes or ascii-only str. proxy_headers: Any HTTP headers to use for the proxy requests. For example `{"Proxy-Authorization": "Basic :"}`. ssl_context: An SSL context to use for verifying connections. If not specified, the default `httpcore2.default_ssl_context()` will be used. proxy_ssl_context: The same as `ssl_context`, but for a proxy server rather than a remote origin. max_connections: The maximum number of concurrent HTTP connections that the pool should allow. Any attempt to send a request on a pool that would exceed this amount will block until a connection is available. max_keepalive_connections: The maximum number of idle HTTP connections that will be maintained in the pool. keepalive_expiry: The duration in seconds that an idle HTTP connection may be maintained for before being expired from the pool. http1: A boolean indicating if HTTP/1.1 requests should be supported by the connection pool. Defaults to True. http2: A boolean indicating if HTTP/2 requests should be supported by the connection pool. Defaults to False. retries: The maximum number of retries when trying to establish a connection. local_address: Local address to connect from. Can also be used to connect using a particular address family. Using `local_address="0.0.0.0"` will connect using an `AF_INET` address (IPv4), while using `local_address="::"` will connect using an `AF_INET6` address (IPv6). uds: Path to a Unix Domain Socket to use instead of TCP sockets. network_backend: A backend instance to use for handling network I/O. """ super().__init__( ssl_context=ssl_context, max_connections=max_connections, max_keepalive_connections=max_keepalive_connections, keepalive_expiry=keepalive_expiry, http1=http1, http2=http2, network_backend=network_backend, retries=retries, local_address=local_address, uds=uds, socket_options=socket_options, ) self._proxy_url = enforce_url(proxy_url, name="proxy_url") if self._proxy_url.scheme == b"http" and proxy_ssl_context is not None: # pragma: no cover raise RuntimeError("The `proxy_ssl_context` argument is not allowed for the http scheme") self._ssl_context = ssl_context self._proxy_ssl_context = proxy_ssl_context self._proxy_headers = enforce_headers(proxy_headers, name="proxy_headers") if proxy_auth is not None: username = enforce_bytes(proxy_auth[0], name="proxy_auth") password = enforce_bytes(proxy_auth[1], name="proxy_auth") userpass = username + b":" + password authorization = b"Basic " + base64.b64encode(userpass) self._proxy_headers = [(b"Proxy-Authorization", authorization)] + self._proxy_headers def create_connection(self, origin: Origin) -> AsyncConnectionInterface: if origin.scheme == b"http": return AsyncForwardHTTPConnection( proxy_origin=self._proxy_url.origin, proxy_headers=self._proxy_headers, remote_origin=origin, keepalive_expiry=self._keepalive_expiry, network_backend=self._network_backend, proxy_ssl_context=self._proxy_ssl_context, ) return AsyncTunnelHTTPConnection( proxy_origin=self._proxy_url.origin, proxy_headers=self._proxy_headers, remote_origin=origin, ssl_context=self._ssl_context, proxy_ssl_context=self._proxy_ssl_context, keepalive_expiry=self._keepalive_expiry, http1=self._http1, http2=self._http2, network_backend=self._network_backend, ) class AsyncForwardHTTPConnection(AsyncConnectionInterface): def __init__( self, proxy_origin: Origin, remote_origin: Origin, proxy_headers: HeadersAsMapping | HeadersAsSequence | None = None, keepalive_expiry: float | None = None, network_backend: AsyncNetworkBackend | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, proxy_ssl_context: ssl.SSLContext | None = None, ) -> None: self._connection = AsyncHTTPConnection( origin=proxy_origin, keepalive_expiry=keepalive_expiry, network_backend=network_backend, socket_options=socket_options, ssl_context=proxy_ssl_context, ) self._proxy_origin = proxy_origin self._proxy_headers = enforce_headers(proxy_headers, name="proxy_headers") self._remote_origin = remote_origin async def handle_async_request(self, request: Request) -> Response: headers = merge_headers(self._proxy_headers, request.headers) url = URL( scheme=self._proxy_origin.scheme, host=self._proxy_origin.host, port=self._proxy_origin.port, target=bytes(request.url) if request.url.target.startswith(b"/") else request.url.target, ) proxy_request = Request( method=request.method, url=url, headers=headers, content=request.stream, extensions={ key: value for key, value in request.extensions.items() if key not in ("sni_hostname", "target") }, ) return await self._connection.handle_async_request(proxy_request) def can_handle_request(self, origin: Origin) -> bool: return origin == self._remote_origin async def aclose(self) -> None: await self._connection.aclose() def info(self) -> str: return self._connection.info() def is_connected(self) -> bool: return self._connection.is_connected() def is_available(self) -> bool: return self._connection.is_available() def has_expired(self) -> bool: return self._connection.has_expired() def is_idle(self) -> bool: return self._connection.is_idle() def is_closed(self) -> bool: return self._connection.is_closed() def __repr__(self) -> str: return f"<{self.__class__.__name__} [{self.info()}]>" class AsyncTunnelHTTPConnection(AsyncConnectionInterface): def __init__( self, proxy_origin: Origin, remote_origin: Origin, ssl_context: ssl.SSLContext | None = None, proxy_ssl_context: ssl.SSLContext | None = None, proxy_headers: typing.Sequence[tuple[bytes, bytes]] | None = None, keepalive_expiry: float | None = None, http1: bool = True, http2: bool = False, network_backend: AsyncNetworkBackend | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> None: self._connection: AsyncConnectionInterface = AsyncHTTPConnection( origin=proxy_origin, keepalive_expiry=keepalive_expiry, network_backend=network_backend, socket_options=socket_options, ssl_context=proxy_ssl_context, ) self._proxy_origin = proxy_origin self._remote_origin = remote_origin self._ssl_context = ssl_context self._proxy_ssl_context = proxy_ssl_context self._proxy_headers = enforce_headers(proxy_headers, name="proxy_headers") self._keepalive_expiry = keepalive_expiry self._http1 = http1 self._http2 = http2 self._connect_lock = AsyncLock() self._connected = False async def handle_async_request(self, request: Request) -> Response: timeouts = request.extensions.get("timeout", {}) timeout = timeouts.get("connect", None) async with self._connect_lock: if not self._connected: target = b"%b:%d" % (self._remote_origin.host, self._remote_origin.port) connect_url = URL( scheme=self._proxy_origin.scheme, host=self._proxy_origin.host, port=self._proxy_origin.port, target=target, ) connect_headers = merge_headers([(b"Host", target), (b"Accept", b"*/*")], self._proxy_headers) connect_request = Request( method=b"CONNECT", url=connect_url, headers=connect_headers, extensions={ key: value for key, value in request.extensions.items() if key not in ("sni_hostname", "target") }, ) connect_response = await self._connection.handle_async_request(connect_request) if connect_response.status < 200 or connect_response.status > 299: reason_bytes = connect_response.extensions.get("reason_phrase", b"") reason_str = reason_bytes.decode("ascii", errors="ignore") msg = f"{connect_response.status} {reason_str}" await self._connection.aclose() raise ProxyError(msg) stream = connect_response.extensions["network_stream"] # Upgrade the stream to SSL ssl_context = default_ssl_context() if self._ssl_context is None else self._ssl_context alpn_protocols = (["h2", "http/1.1"] if self._http1 else ["h2"]) if self._http2 else ["http/1.1"] ssl_context.set_alpn_protocols(alpn_protocols) server_hostname = request.extensions.get("sni_hostname") or self._remote_origin.host.decode("ascii") kwargs = { "ssl_context": ssl_context, "server_hostname": server_hostname, "timeout": timeout, } async with Trace("start_tls", logger, request, kwargs) as trace: stream = await stream.start_tls(**kwargs) trace.return_value = stream # Determine if we should be using HTTP/1.1 or HTTP/2 ssl_object = stream.get_extra_info("ssl_object") http2_negotiated = ssl_object is not None and ssl_object.selected_alpn_protocol() == "h2" # Create the HTTP/1.1 or HTTP/2 connection if http2_negotiated or (self._http2 and not self._http1): from .http2 import AsyncHTTP2Connection self._connection = AsyncHTTP2Connection( origin=self._remote_origin, stream=stream, keepalive_expiry=self._keepalive_expiry, ) else: self._connection = AsyncHTTP11Connection( origin=self._remote_origin, stream=stream, keepalive_expiry=self._keepalive_expiry, ) self._connected = True return await self._connection.handle_async_request(request) def can_handle_request(self, origin: Origin) -> bool: return origin == self._remote_origin async def aclose(self) -> None: await self._connection.aclose() def info(self) -> str: return self._connection.info() def is_connected(self) -> bool: return self._connection.is_connected() def is_available(self) -> bool: return self._connection.is_available() def has_expired(self) -> bool: return self._connection.has_expired() def is_idle(self) -> bool: return self._connection.is_idle() def is_closed(self) -> bool: return self._connection.is_closed() def __repr__(self) -> str: return f"<{self.__class__.__name__} [{self.info()}]>" pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_async/interfaces.py000066400000000000000000000123631526547463400256150ustar00rootroot00000000000000from __future__ import annotations import contextlib import typing from collections.abc import AsyncGenerator from .._models import ( URL, Extensions, HeaderTypes, Origin, Request, Response, enforce_bytes, enforce_headers, enforce_url, include_request_headers, ) class AsyncRequestInterface: async def request( self, method: bytes | str, url: URL | bytes | str, *, headers: HeaderTypes = None, content: bytes | typing.AsyncIterator[bytes] | None = None, extensions: Extensions | None = None, ) -> Response: # Strict type checking on our parameters. method = enforce_bytes(method, name="method") url = enforce_url(url, name="url") headers = enforce_headers(headers, name="headers") # Include Host header, and optionally Content-Length or Transfer-Encoding. headers = include_request_headers(headers, url=url, content=content) request = Request( method=method, url=url, headers=headers, content=content, extensions=extensions, ) response = await self.handle_async_request(request) try: await response.aread() finally: await response.aclose() return response @contextlib.asynccontextmanager async def stream( self, method: bytes | str, url: URL | bytes | str, *, headers: HeaderTypes = None, content: bytes | typing.AsyncIterator[bytes] | None = None, extensions: Extensions | None = None, ) -> AsyncGenerator[Response]: # Strict type checking on our parameters. method = enforce_bytes(method, name="method") url = enforce_url(url, name="url") headers = enforce_headers(headers, name="headers") # Include Host header, and optionally Content-Length or Transfer-Encoding. headers = include_request_headers(headers, url=url, content=content) request = Request( method=method, url=url, headers=headers, content=content, extensions=extensions, ) response = await self.handle_async_request(request) try: yield response finally: await response.aclose() async def handle_async_request(self, request: Request) -> Response: raise NotImplementedError() # pragma: no cover class AsyncConnectionInterface(AsyncRequestInterface): async def aclose(self) -> None: raise NotImplementedError() # pragma: no cover def info(self) -> str: raise NotImplementedError() # pragma: no cover def can_handle_request(self, origin: Origin) -> bool: raise NotImplementedError() # pragma: no cover def is_connected(self) -> bool: """ Return `True` if the connection is open (the underlying socket has been established). A connection in the NEW state (just created but not yet connected) returns `False`. Note: for some implementations `is_connected() != not is_closed()`. The default implementation returns `not self.is_closed()`, which is correct for connections that are never in the NEW (pre-TCP) state. """ return not self.is_closed() # pragma: no cover def is_available(self) -> bool: """ Return `True` if the connection is currently able to accept an outgoing request. An HTTP/1.1 connection will only be available if it is currently idle. An HTTP/2 connection will be available so long as the stream ID space is not yet exhausted, and the connection is not in an error state. While the connection is being established we may not yet know if it is going to result in an HTTP/1.1 or HTTP/2 connection. The connection should be treated as being available, but might ultimately raise `NewConnectionRequired` required exceptions if multiple requests are attempted over a connection that ends up being established as HTTP/1.1. """ raise NotImplementedError() # pragma: no cover def has_expired(self) -> bool: """ Return `True` if the connection is in a state where it should be closed. This either means that the connection is idle and it has passed the expiry time on its keep-alive, or that server has sent an EOF. """ raise NotImplementedError() # pragma: no cover def is_idle(self) -> bool: """ Return `True` if the connection is currently idle. """ raise NotImplementedError() # pragma: no cover def can_multiplex(self) -> bool: """ Return `True` if the connection can serve multiple requests concurrently, such as an established HTTP/2 connection. The default covers HTTP/1.1-style implementations, which serve a single request at a time. """ return False def is_closed(self) -> bool: """ Return `True` if the connection has been closed. Used when a response is closed to determine if the connection may be returned to the connection pool or not. """ raise NotImplementedError() # pragma: no cover pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_async/socks_proxy.py000066400000000000000000000331731526547463400260570ustar00rootroot00000000000000from __future__ import annotations import logging import ssl import socksio from .._backends.auto import AutoBackend from .._backends.base import AsyncNetworkBackend, AsyncNetworkStream from .._exceptions import ConnectionNotAvailable, ProxyError from .._models import URL, Origin, Request, Response, enforce_bytes, enforce_url from .._ssl import default_ssl_context from .._synchronization import AsyncLock from .._trace import Trace from .connection_pool import AsyncConnectionPool from .http11 import AsyncHTTP11Connection from .interfaces import AsyncConnectionInterface logger = logging.getLogger("httpcore2.socks") AUTH_METHODS = { b"\x00": "NO AUTHENTICATION REQUIRED", b"\x01": "GSSAPI", b"\x02": "USERNAME/PASSWORD", b"\xff": "NO ACCEPTABLE METHODS", } REPLY_CODES = { b"\x00": "Succeeded", b"\x01": "General SOCKS server failure", b"\x02": "Connection not allowed by ruleset", b"\x03": "Network unreachable", b"\x04": "Host unreachable", b"\x05": "Connection refused", b"\x06": "TTL expired", b"\x07": "Command not supported", b"\x08": "Address type not supported", } async def _init_socks5_connection( stream: AsyncNetworkStream, *, host: bytes, port: int, auth: tuple[bytes, bytes] | None = None, timeouts: dict[str, float | None] | None = None, ) -> None: timeouts = timeouts or {} write_timeout = timeouts.get("write", None) read_timeout = timeouts.get("read", None) conn = socksio.socks5.SOCKS5Connection() # Auth method request auth_method = ( socksio.socks5.SOCKS5AuthMethod.NO_AUTH_REQUIRED if auth is None else socksio.socks5.SOCKS5AuthMethod.USERNAME_PASSWORD ) conn.send(socksio.socks5.SOCKS5AuthMethodsRequest([auth_method])) outgoing_bytes = conn.data_to_send() await stream.write(outgoing_bytes, timeout=write_timeout) # Auth method response incoming_bytes = await stream.read(max_bytes=4096, timeout=read_timeout) response = conn.receive_data(incoming_bytes) assert isinstance(response, socksio.socks5.SOCKS5AuthReply) if response.method != auth_method: requested = AUTH_METHODS.get(auth_method, "UNKNOWN") responded = AUTH_METHODS.get(response.method, "UNKNOWN") raise ProxyError(f"Requested {requested} from proxy server, but got {responded}.") if response.method == socksio.socks5.SOCKS5AuthMethod.USERNAME_PASSWORD: # Username/password request assert auth is not None username, password = auth conn.send(socksio.socks5.SOCKS5UsernamePasswordRequest(username, password)) outgoing_bytes = conn.data_to_send() await stream.write(outgoing_bytes, timeout=write_timeout) # Username/password response incoming_bytes = await stream.read(max_bytes=4096, timeout=read_timeout) response = conn.receive_data(incoming_bytes) assert isinstance(response, socksio.socks5.SOCKS5UsernamePasswordReply) if not response.success: raise ProxyError("Invalid username/password") # Connect request conn.send(socksio.socks5.SOCKS5CommandRequest.from_address(socksio.socks5.SOCKS5Command.CONNECT, (host, port))) outgoing_bytes = conn.data_to_send() await stream.write(outgoing_bytes, timeout=write_timeout) # Connect response incoming_bytes = await stream.read(max_bytes=4096, timeout=read_timeout) response = conn.receive_data(incoming_bytes) assert isinstance(response, socksio.socks5.SOCKS5Reply) if response.reply_code != socksio.socks5.SOCKS5ReplyCode.SUCCEEDED: reply_code = REPLY_CODES.get(response.reply_code, "UNKOWN") raise ProxyError(f"Proxy Server could not connect: {reply_code}.") class AsyncSOCKSProxy(AsyncConnectionPool): # pragma: no cover """ A connection pool that sends requests via an HTTP proxy. """ def __init__( self, proxy_url: URL | bytes | str, proxy_auth: tuple[bytes | str, bytes | str] | None = None, ssl_context: ssl.SSLContext | None = None, max_connections: int | None = 10, max_keepalive_connections: int | None = None, keepalive_expiry: float | None = None, http1: bool = True, http2: bool = False, retries: int = 0, network_backend: AsyncNetworkBackend | None = None, ) -> None: """ A connection pool for making HTTP requests. Parameters: proxy_url: The URL to use when connecting to the proxy server. For example `"http://127.0.0.1:8080/"`. ssl_context: An SSL context to use for verifying connections. If not specified, the default `httpcore2.default_ssl_context()` will be used. max_connections: The maximum number of concurrent HTTP connections that the pool should allow. Any attempt to send a request on a pool that would exceed this amount will block until a connection is available. max_keepalive_connections: The maximum number of idle HTTP connections that will be maintained in the pool. keepalive_expiry: The duration in seconds that an idle HTTP connection may be maintained for before being expired from the pool. http1: A boolean indicating if HTTP/1.1 requests should be supported by the connection pool. Defaults to True. http2: A boolean indicating if HTTP/2 requests should be supported by the connection pool. Defaults to False. retries: The maximum number of retries when trying to establish a connection. local_address: Local address to connect from. Can also be used to connect using a particular address family. Using `local_address="0.0.0.0"` will connect using an `AF_INET` address (IPv4), while using `local_address="::"` will connect using an `AF_INET6` address (IPv6). uds: Path to a Unix Domain Socket to use instead of TCP sockets. network_backend: A backend instance to use for handling network I/O. """ super().__init__( ssl_context=ssl_context, max_connections=max_connections, max_keepalive_connections=max_keepalive_connections, keepalive_expiry=keepalive_expiry, http1=http1, http2=http2, network_backend=network_backend, retries=retries, ) self._ssl_context = ssl_context self._proxy_url = enforce_url(proxy_url, name="proxy_url") if proxy_auth is not None: username, password = proxy_auth username_bytes = enforce_bytes(username, name="proxy_auth") password_bytes = enforce_bytes(password, name="proxy_auth") self._proxy_auth: tuple[bytes, bytes] | None = ( username_bytes, password_bytes, ) else: self._proxy_auth = None def create_connection(self, origin: Origin) -> AsyncConnectionInterface: return AsyncSocks5Connection( proxy_origin=self._proxy_url.origin, remote_origin=origin, proxy_auth=self._proxy_auth, ssl_context=self._ssl_context, keepalive_expiry=self._keepalive_expiry, http1=self._http1, http2=self._http2, network_backend=self._network_backend, ) class AsyncSocks5Connection(AsyncConnectionInterface): def __init__( self, proxy_origin: Origin, remote_origin: Origin, proxy_auth: tuple[bytes, bytes] | None = None, ssl_context: ssl.SSLContext | None = None, keepalive_expiry: float | None = None, http1: bool = True, http2: bool = False, network_backend: AsyncNetworkBackend | None = None, ) -> None: self._proxy_origin = proxy_origin self._remote_origin = remote_origin self._proxy_auth = proxy_auth self._ssl_context = ssl_context self._keepalive_expiry = keepalive_expiry self._http1 = http1 self._http2 = http2 self._network_backend: AsyncNetworkBackend = AutoBackend() if network_backend is None else network_backend self._connect_lock = AsyncLock() self._connection: AsyncConnectionInterface | None = None self._connect_failed = False async def handle_async_request(self, request: Request) -> Response: timeouts = request.extensions.get("timeout", {}) sni_hostname = request.extensions.get("sni_hostname", None) timeout = timeouts.get("connect", None) async with self._connect_lock: if self._connection is None: try: # Connect to the proxy kwargs = { "host": self._proxy_origin.host.decode("ascii"), "port": self._proxy_origin.port, "timeout": timeout, } async with Trace("connect_tcp", logger, request, kwargs) as trace: stream = await self._network_backend.connect_tcp(**kwargs) trace.return_value = stream # Connect to the remote host using socks5 kwargs = { "stream": stream, "host": self._remote_origin.host.decode("ascii"), "port": self._remote_origin.port, "auth": self._proxy_auth, "timeouts": timeouts, } async with Trace("setup_socks5_connection", logger, request, kwargs) as trace: await _init_socks5_connection(**kwargs) trace.return_value = stream # Upgrade the stream to SSL if self._remote_origin.scheme in (b"https", b"wss"): ssl_context = default_ssl_context() if self._ssl_context is None else self._ssl_context alpn_protocols = ( (["h2", "http/1.1"] if self._http1 else ["h2"]) if self._http2 else ["http/1.1"] ) ssl_context.set_alpn_protocols(alpn_protocols) kwargs = { "ssl_context": ssl_context, "server_hostname": sni_hostname or self._remote_origin.host.decode("ascii"), "timeout": timeout, } async with Trace("start_tls", logger, request, kwargs) as trace: stream = await stream.start_tls(**kwargs) trace.return_value = stream # Determine if we should be using HTTP/1.1 or HTTP/2 ssl_object = stream.get_extra_info("ssl_object") http2_negotiated = ssl_object is not None and ssl_object.selected_alpn_protocol() == "h2" # Create the HTTP/1.1 or HTTP/2 connection if http2_negotiated or (self._http2 and not self._http1): # pragma: no cover from .http2 import AsyncHTTP2Connection self._connection = AsyncHTTP2Connection( origin=self._remote_origin, stream=stream, keepalive_expiry=self._keepalive_expiry, ) else: self._connection = AsyncHTTP11Connection( origin=self._remote_origin, stream=stream, keepalive_expiry=self._keepalive_expiry, ) except Exception as exc: self._connect_failed = True raise exc elif not self._connection.is_available(): # pragma: no cover raise ConnectionNotAvailable() return await self._connection.handle_async_request(request) def can_handle_request(self, origin: Origin) -> bool: return origin == self._remote_origin async def aclose(self) -> None: if self._connection is not None: await self._connection.aclose() def is_connected(self) -> bool: return self._connection is not None and self._connection.is_connected() def is_available(self) -> bool: if self._connection is None: # pragma: no cover # If HTTP/2 support is enabled, and the resulting connection could # end up as HTTP/2 then we should indicate the connection as being # available to service multiple requests. return ( self._http2 and (self._remote_origin.scheme == b"https" or not self._http1) and not self._connect_failed ) return self._connection.is_available() def has_expired(self) -> bool: if self._connection is None: # pragma: no cover return self._connect_failed return self._connection.has_expired() def is_idle(self) -> bool: if self._connection is None: # pragma: no cover return self._connect_failed return self._connection.is_idle() def is_closed(self) -> bool: if self._connection is None: # pragma: no cover return self._connect_failed return self._connection.is_closed() def info(self) -> str: if self._connection is None: # pragma: no cover return "CONNECTION FAILED" if self._connect_failed else "CONNECTING" return self._connection.info() def __repr__(self) -> str: return f"<{self.__class__.__name__} [{self.info()}]>" pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_backends/000077500000000000000000000000001526547463400235505ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_backends/__init__.py000066400000000000000000000000001526547463400256470ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_backends/anyio.py000066400000000000000000000126461526547463400252520ustar00rootroot00000000000000from __future__ import annotations import ssl import typing import anyio import anyio.abc import anyio.streams.tls from .._exceptions import ( ConnectError, ConnectTimeout, ReadError, ReadTimeout, WriteError, WriteTimeout, map_exceptions, ) from .._utils import is_socket_readable from .base import SOCKET_OPTION, AsyncNetworkBackend, AsyncNetworkStream class AnyIOStream(AsyncNetworkStream): def __init__(self, stream: anyio.abc.ByteStream) -> None: self._stream = stream async def read(self, max_bytes: int, timeout: float | None = None) -> bytes: exc_map: dict[type[Exception], type[Exception]] = { TimeoutError: ReadTimeout, anyio.BrokenResourceError: ReadError, anyio.ClosedResourceError: ReadError, anyio.EndOfStream: ReadError, } with map_exceptions(exc_map): with anyio.fail_after(timeout): try: return await self._stream.receive(max_bytes=max_bytes) except anyio.EndOfStream: # pragma: no cover return b"" async def write(self, buffer: bytes, timeout: float | None = None) -> None: if not buffer: return exc_map: dict[type[Exception], type[Exception]] = { TimeoutError: WriteTimeout, anyio.BrokenResourceError: WriteError, anyio.ClosedResourceError: WriteError, anyio.EndOfStream: WriteError, } with map_exceptions(exc_map): with anyio.fail_after(timeout): await self._stream.send(item=buffer) async def aclose(self) -> None: await self._stream.aclose() async def start_tls( self, ssl_context: ssl.SSLContext, server_hostname: str | None = None, timeout: float | None = None, ) -> AsyncNetworkStream: exc_map: dict[type[Exception], type[Exception]] = { TimeoutError: ConnectTimeout, anyio.BrokenResourceError: ConnectError, anyio.EndOfStream: ConnectError, ssl.SSLError: ConnectError, } with map_exceptions(exc_map): try: with anyio.fail_after(timeout): ssl_stream = await anyio.streams.tls.TLSStream.wrap( self._stream, ssl_context=ssl_context, hostname=server_hostname, standard_compatible=False, server_side=False, ) except Exception as exc: # pragma: no cover await self.aclose() raise exc return AnyIOStream(ssl_stream) def get_extra_info(self, info: str) -> typing.Any: if info == "ssl_object": return self._stream.extra(anyio.streams.tls.TLSAttribute.ssl_object, None) if info == "client_addr": return self._stream.extra(anyio.abc.SocketAttribute.local_address, None) if info == "server_addr": return self._stream.extra(anyio.abc.SocketAttribute.remote_address, None) if info == "socket": return self._stream.extra(anyio.abc.SocketAttribute.raw_socket, None) if info == "is_readable": sock = self._stream.extra(anyio.abc.SocketAttribute.raw_socket, None) return is_socket_readable(sock) return None class AnyIOBackend(AsyncNetworkBackend): async def connect_tcp( self, host: str, port: int, timeout: float | None = None, local_address: str | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> AsyncNetworkStream: # pragma: no cover if socket_options is None: socket_options = [] exc_map: dict[type[Exception], type[Exception]] = { TimeoutError: ConnectTimeout, OSError: ConnectError, anyio.BrokenResourceError: ConnectError, } with map_exceptions(exc_map): with anyio.fail_after(timeout): stream: anyio.abc.ByteStream = await anyio.connect_tcp( remote_host=host, remote_port=port, local_host=local_address, ) # By default TCP sockets opened in `asyncio` include TCP_NODELAY. for option in socket_options: stream._raw_socket.setsockopt(*option) # type: ignore[attr-defined] # pragma: no cover return AnyIOStream(stream) async def connect_unix_socket( self, path: str, timeout: float | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> AsyncNetworkStream: # pragma: no cover if socket_options is None: socket_options = [] exc_map: dict[type[Exception], type[Exception]] = { TimeoutError: ConnectTimeout, OSError: ConnectError, anyio.BrokenResourceError: ConnectError, } with map_exceptions(exc_map): with anyio.fail_after(timeout): stream: anyio.abc.ByteStream = await anyio.connect_unix(path) for option in socket_options: stream._raw_socket.setsockopt(*option) # type: ignore[attr-defined] # pragma: no cover return AnyIOStream(stream) async def sleep(self, seconds: float) -> None: await anyio.sleep(seconds) # pragma: no cover pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_backends/auto.py000066400000000000000000000031521526547463400250730ustar00rootroot00000000000000from __future__ import annotations import typing from .._synchronization import current_async_library from .base import SOCKET_OPTION, AsyncNetworkBackend, AsyncNetworkStream class AutoBackend(AsyncNetworkBackend): async def _init_backend(self) -> None: if not (hasattr(self, "_backend")): backend = current_async_library() if backend == "trio": from .trio import TrioBackend self._backend: AsyncNetworkBackend = TrioBackend() else: from .anyio import AnyIOBackend self._backend = AnyIOBackend() async def connect_tcp( self, host: str, port: int, timeout: float | None = None, local_address: str | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> AsyncNetworkStream: await self._init_backend() return await self._backend.connect_tcp( host, port, timeout=timeout, local_address=local_address, socket_options=socket_options, ) async def connect_unix_socket( self, path: str, timeout: float | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> AsyncNetworkStream: # pragma: no cover await self._init_backend() return await self._backend.connect_unix_socket(path, timeout=timeout, socket_options=socket_options) async def sleep(self, seconds: float) -> None: # pragma: no cover await self._init_backend() return await self._backend.sleep(seconds) pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_backends/base.py000066400000000000000000000056651526547463400250500ustar00rootroot00000000000000from __future__ import annotations import ssl import time import typing SOCKET_OPTION = tuple[int, int, int] | tuple[int, int, bytes | bytearray] | tuple[int, int, None, int] class NetworkStream: def read(self, max_bytes: int, timeout: float | None = None) -> bytes: raise NotImplementedError() # pragma: no cover def write(self, buffer: bytes, timeout: float | None = None) -> None: raise NotImplementedError() # pragma: no cover def close(self) -> None: raise NotImplementedError() # pragma: no cover def start_tls( self, ssl_context: ssl.SSLContext, server_hostname: str | None = None, timeout: float | None = None, ) -> NetworkStream: raise NotImplementedError() # pragma: no cover def get_extra_info(self, info: str) -> typing.Any: return None # pragma: no cover class NetworkBackend: def connect_tcp( self, host: str, port: int, timeout: float | None = None, local_address: str | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> NetworkStream: raise NotImplementedError() # pragma: no cover def connect_unix_socket( self, path: str, timeout: float | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> NetworkStream: raise NotImplementedError() # pragma: no cover def sleep(self, seconds: float) -> None: time.sleep(seconds) # pragma: no cover class AsyncNetworkStream: async def read(self, max_bytes: int, timeout: float | None = None) -> bytes: raise NotImplementedError() # pragma: no cover async def write(self, buffer: bytes, timeout: float | None = None) -> None: raise NotImplementedError() # pragma: no cover async def aclose(self) -> None: raise NotImplementedError() # pragma: no cover async def start_tls( self, ssl_context: ssl.SSLContext, server_hostname: str | None = None, timeout: float | None = None, ) -> AsyncNetworkStream: raise NotImplementedError() # pragma: no cover def get_extra_info(self, info: str) -> typing.Any: return None # pragma: no cover class AsyncNetworkBackend: async def connect_tcp( self, host: str, port: int, timeout: float | None = None, local_address: str | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> AsyncNetworkStream: raise NotImplementedError() # pragma: no cover async def connect_unix_socket( self, path: str, timeout: float | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> AsyncNetworkStream: raise NotImplementedError() # pragma: no cover async def sleep(self, seconds: float) -> None: raise NotImplementedError() # pragma: no cover pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_backends/mock.py000066400000000000000000000077571526547463400250730ustar00rootroot00000000000000from __future__ import annotations import ssl import typing from .._exceptions import ReadError from .base import ( SOCKET_OPTION, AsyncNetworkBackend, AsyncNetworkStream, NetworkBackend, NetworkStream, ) class MockSSLObject: def __init__(self, http2: bool): self._http2 = http2 def selected_alpn_protocol(self) -> str: return "h2" if self._http2 else "http/1.1" class MockStream(NetworkStream): def __init__(self, buffer: list[bytes], http2: bool = False) -> None: self._buffer = buffer self._http2 = http2 self._closed = False def read(self, max_bytes: int, timeout: float | None = None) -> bytes: if self._closed: raise ReadError("Connection closed") if not self._buffer: return b"" return self._buffer.pop(0) def write(self, buffer: bytes, timeout: float | None = None) -> None: pass def close(self) -> None: self._closed = True def start_tls( self, ssl_context: ssl.SSLContext, server_hostname: str | None = None, timeout: float | None = None, ) -> NetworkStream: return self def get_extra_info(self, info: str) -> typing.Any: return MockSSLObject(http2=self._http2) if info == "ssl_object" else None def __repr__(self) -> str: return "" class MockBackend(NetworkBackend): def __init__(self, buffer: list[bytes], http2: bool = False) -> None: self._buffer = buffer self._http2 = http2 def connect_tcp( self, host: str, port: int, timeout: float | None = None, local_address: str | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> NetworkStream: return MockStream(list(self._buffer), http2=self._http2) def connect_unix_socket( self, path: str, timeout: float | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> NetworkStream: return MockStream(list(self._buffer), http2=self._http2) def sleep(self, seconds: float) -> None: pass class AsyncMockStream(AsyncNetworkStream): def __init__(self, buffer: list[bytes], http2: bool = False) -> None: self._buffer = buffer self._http2 = http2 self._closed = False async def read(self, max_bytes: int, timeout: float | None = None) -> bytes: if self._closed: raise ReadError("Connection closed") if not self._buffer: return b"" return self._buffer.pop(0) async def write(self, buffer: bytes, timeout: float | None = None) -> None: pass async def aclose(self) -> None: self._closed = True async def start_tls( self, ssl_context: ssl.SSLContext, server_hostname: str | None = None, timeout: float | None = None, ) -> AsyncNetworkStream: return self def get_extra_info(self, info: str) -> typing.Any: return MockSSLObject(http2=self._http2) if info == "ssl_object" else None def __repr__(self) -> str: return "" class AsyncMockBackend(AsyncNetworkBackend): def __init__(self, buffer: list[bytes], http2: bool = False) -> None: self._buffer = buffer self._http2 = http2 async def connect_tcp( self, host: str, port: int, timeout: float | None = None, local_address: str | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> AsyncNetworkStream: return AsyncMockStream(list(self._buffer), http2=self._http2) async def connect_unix_socket( self, path: str, timeout: float | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> AsyncNetworkStream: return AsyncMockStream(list(self._buffer), http2=self._http2) async def sleep(self, seconds: float) -> None: pass pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_backends/sync.py000066400000000000000000000174271526547463400251110ustar00rootroot00000000000000from __future__ import annotations import functools import socket import ssl import sys import typing from .._exceptions import ( ConnectError, ConnectTimeout, ExceptionMapping, ReadError, ReadTimeout, WriteError, WriteTimeout, map_exceptions, ) from .._utils import is_socket_readable from .base import SOCKET_OPTION, NetworkBackend, NetworkStream class TLSinTLSStream(NetworkStream): # pragma: no cover """ Because the standard `SSLContext.wrap_socket` method does not work for `SSLSocket` objects, we need this class to implement TLS stream using an underlying `SSLObject` instance in order to support TLS on top of TLS. """ # Defined in RFC 8449 TLS_RECORD_SIZE = 16384 def __init__( self, sock: socket.socket, ssl_context: ssl.SSLContext, server_hostname: str | None = None, timeout: float | None = None, ): self._sock = sock self._incoming = ssl.MemoryBIO() self._outgoing = ssl.MemoryBIO() self.ssl_obj = ssl_context.wrap_bio( incoming=self._incoming, outgoing=self._outgoing, server_hostname=server_hostname, ) self._sock.settimeout(timeout) self._perform_io(self.ssl_obj.do_handshake) def _perform_io( self, func: typing.Callable[..., typing.Any], ) -> typing.Any: ret = None while True: errno = None try: ret = func() except (ssl.SSLWantReadError, ssl.SSLWantWriteError) as e: errno = e.errno self._sock.sendall(self._outgoing.read()) if errno == ssl.SSL_ERROR_WANT_READ: buf = self._sock.recv(self.TLS_RECORD_SIZE) if buf: self._incoming.write(buf) else: self._incoming.write_eof() if errno is None: return ret def read(self, max_bytes: int, timeout: float | None = None) -> bytes: exc_map: ExceptionMapping = {socket.timeout: ReadTimeout, OSError: ReadError} with map_exceptions(exc_map): self._sock.settimeout(timeout) return typing.cast(bytes, self._perform_io(functools.partial(self.ssl_obj.read, max_bytes))) def write(self, buffer: bytes, timeout: float | None = None) -> None: exc_map: ExceptionMapping = {socket.timeout: WriteTimeout, OSError: WriteError} with map_exceptions(exc_map): self._sock.settimeout(timeout) view = memoryview(buffer) # zero-copy slicing; avoids copies while view: nsent = self._perform_io(functools.partial(self.ssl_obj.write, view)) view = view[nsent:] def close(self) -> None: self._sock.close() def start_tls( self, ssl_context: ssl.SSLContext, server_hostname: str | None = None, timeout: float | None = None, ) -> NetworkStream: raise NotImplementedError() def get_extra_info(self, info: str) -> typing.Any: if info == "ssl_object": return self.ssl_obj if info == "client_addr": return self._sock.getsockname() if info == "server_addr": return self._sock.getpeername() if info == "socket": return self._sock if info == "is_readable": return is_socket_readable(self._sock) return None class SyncStream(NetworkStream): def __init__(self, sock: socket.socket) -> None: self._sock = sock def read(self, max_bytes: int, timeout: float | None = None) -> bytes: exc_map: ExceptionMapping = {socket.timeout: ReadTimeout, OSError: ReadError} with map_exceptions(exc_map): self._sock.settimeout(timeout) return self._sock.recv(max_bytes) def write(self, buffer: bytes, timeout: float | None = None) -> None: if not buffer: return exc_map: ExceptionMapping = {socket.timeout: WriteTimeout, OSError: WriteError} with map_exceptions(exc_map): view = memoryview(buffer) # zero-copy slicing; avoids copies while view: self._sock.settimeout(timeout) n = self._sock.send(view) view = view[n:] def close(self) -> None: self._sock.close() def start_tls( self, ssl_context: ssl.SSLContext, server_hostname: str | None = None, timeout: float | None = None, ) -> NetworkStream: exc_map: ExceptionMapping = { socket.timeout: ConnectTimeout, OSError: ConnectError, } with map_exceptions(exc_map): try: if isinstance(self._sock, ssl.SSLSocket): # pragma: no cover # If the underlying socket has already been upgraded # to the TLS layer (i.e. is an instance of SSLSocket), # we need some additional smarts to support TLS-in-TLS. return TLSinTLSStream(self._sock, ssl_context, server_hostname, timeout) else: self._sock.settimeout(timeout) sock = ssl_context.wrap_socket(self._sock, server_hostname=server_hostname) except Exception as exc: # pragma: no cover self.close() raise exc return SyncStream(sock) def get_extra_info(self, info: str) -> typing.Any: if info == "ssl_object" and isinstance(self._sock, ssl.SSLSocket): return self._sock._sslobj # type: ignore if info == "client_addr": return self._sock.getsockname() if info == "server_addr": return self._sock.getpeername() if info == "socket": return self._sock if info == "is_readable": return is_socket_readable(self._sock) return None class SyncBackend(NetworkBackend): def connect_tcp( self, host: str, port: int, timeout: float | None = None, local_address: str | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> NetworkStream: # Note that we automatically include `TCP_NODELAY` # in addition to any other custom socket options. if socket_options is None: socket_options = [] # pragma: no cover address = (host, port) source_address = None if local_address is None else (local_address, 0) exc_map: ExceptionMapping = { socket.timeout: ConnectTimeout, OSError: ConnectError, } with map_exceptions(exc_map): sock = socket.create_connection( address, timeout, source_address=source_address, ) for option in socket_options: sock.setsockopt(*option) # pragma: no cover sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) return SyncStream(sock) def connect_unix_socket( self, path: str, timeout: float | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> NetworkStream: # pragma: no cover if sys.platform == "win32": raise RuntimeError("Attempted to connect to a UNIX socket on a Windows system.") if socket_options is None: socket_options = [] exc_map: ExceptionMapping = { socket.timeout: ConnectTimeout, OSError: ConnectError, } with map_exceptions(exc_map): sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) for option in socket_options: sock.setsockopt(*option) sock.settimeout(timeout) sock.connect(path) return SyncStream(sock) pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_backends/trio.py000066400000000000000000000135111526547463400251000ustar00rootroot00000000000000from __future__ import annotations import ssl import typing import trio from .._exceptions import ( ConnectError, ConnectTimeout, ExceptionMapping, ReadError, ReadTimeout, WriteError, WriteTimeout, map_exceptions, ) from .base import SOCKET_OPTION, AsyncNetworkBackend, AsyncNetworkStream class TrioStream(AsyncNetworkStream): def __init__(self, stream: trio.abc.Stream) -> None: self._stream = stream async def read(self, max_bytes: int, timeout: float | None = None) -> bytes: timeout_or_inf = float("inf") if timeout is None else timeout exc_map: ExceptionMapping = { trio.TooSlowError: ReadTimeout, trio.BrokenResourceError: ReadError, trio.ClosedResourceError: ReadError, } with map_exceptions(exc_map): with trio.fail_after(timeout_or_inf): data: bytes = await self._stream.receive_some(max_bytes=max_bytes) return data async def write(self, buffer: bytes, timeout: float | None = None) -> None: if not buffer: return timeout_or_inf = float("inf") if timeout is None else timeout exc_map: ExceptionMapping = { trio.TooSlowError: WriteTimeout, trio.BrokenResourceError: WriteError, trio.ClosedResourceError: WriteError, } with map_exceptions(exc_map): with trio.fail_after(timeout_or_inf): await self._stream.send_all(data=buffer) async def aclose(self) -> None: await self._stream.aclose() async def start_tls( self, ssl_context: ssl.SSLContext, server_hostname: str | None = None, timeout: float | None = None, ) -> AsyncNetworkStream: timeout_or_inf = float("inf") if timeout is None else timeout exc_map: ExceptionMapping = { trio.TooSlowError: ConnectTimeout, trio.BrokenResourceError: ConnectError, } ssl_stream = trio.SSLStream( self._stream, ssl_context=ssl_context, server_hostname=server_hostname, https_compatible=True, server_side=False, ) with map_exceptions(exc_map): try: with trio.fail_after(timeout_or_inf): await ssl_stream.do_handshake() except Exception as exc: # pragma: no cover await self.aclose() raise exc return TrioStream(ssl_stream) def get_extra_info(self, info: str) -> typing.Any: if info == "ssl_object" and isinstance(self._stream, trio.SSLStream): # Type checkers cannot see `_ssl_object` attribute because trio._ssl.SSLStream uses __getattr__/__setattr__. # Tracked at https://github.com/python-trio/trio/issues/542 return self._stream._ssl_object # type: ignore[attr-defined] if info == "client_addr": return self._get_socket_stream().socket.getsockname() if info == "server_addr": return self._get_socket_stream().socket.getpeername() if info == "socket": stream = self._stream while isinstance(stream, trio.SSLStream): stream = stream.transport_stream assert isinstance(stream, trio.SocketStream) return stream.socket if info == "is_readable": socket = self.get_extra_info("socket") return socket.is_readable() return None def _get_socket_stream(self) -> trio.SocketStream: stream = self._stream while isinstance(stream, trio.SSLStream): stream = stream.transport_stream assert isinstance(stream, trio.SocketStream) return stream class TrioBackend(AsyncNetworkBackend): async def connect_tcp( self, host: str, port: int, timeout: float | None = None, local_address: str | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> AsyncNetworkStream: # By default for TCP sockets, trio enables TCP_NODELAY. # https://trio.readthedocs.io/en/stable/reference-io.html#trio.SocketStream if socket_options is None: socket_options = [] # pragma: no cover timeout_or_inf = float("inf") if timeout is None else timeout exc_map: ExceptionMapping = { trio.TooSlowError: ConnectTimeout, trio.BrokenResourceError: ConnectError, OSError: ConnectError, } with map_exceptions(exc_map): with trio.fail_after(timeout_or_inf): stream: trio.abc.Stream = await trio.open_tcp_stream(host=host, port=port, local_address=local_address) for option in socket_options: stream.setsockopt(*option) # type: ignore[attr-defined] # pragma: no cover return TrioStream(stream) async def connect_unix_socket( self, path: str, timeout: float | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> AsyncNetworkStream: # pragma: no cover if socket_options is None: socket_options = [] timeout_or_inf = float("inf") if timeout is None else timeout exc_map: ExceptionMapping = { trio.TooSlowError: ConnectTimeout, trio.BrokenResourceError: ConnectError, OSError: ConnectError, } with map_exceptions(exc_map): with trio.fail_after(timeout_or_inf): stream: trio.abc.Stream = await trio.open_unix_socket(path) for option in socket_options: stream.setsockopt(*option) # type: ignore[attr-defined] # pragma: no cover return TrioStream(stream) async def sleep(self, seconds: float) -> None: await trio.sleep(seconds) # pragma: no cover pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_exceptions.py000066400000000000000000000023271526547463400245350ustar00rootroot00000000000000from __future__ import annotations import contextlib import typing from collections.abc import Generator ExceptionMapping = typing.Mapping[type[Exception], type[Exception]] @contextlib.contextmanager def map_exceptions(map: ExceptionMapping) -> Generator[None]: try: yield except Exception as exc: # noqa: PIE786 for from_exc, to_exc in map.items(): if isinstance(exc, from_exc): raise to_exc(exc) from exc raise # pragma: no cover class ConnectionNotAvailable(Exception): pass class ProxyError(Exception): pass class UnsupportedProtocol(Exception): pass class ProtocolError(Exception): pass class RemoteProtocolError(ProtocolError): pass class LocalProtocolError(ProtocolError): pass # Timeout errors class TimeoutException(Exception): pass class PoolTimeout(TimeoutException): pass class ConnectTimeout(TimeoutException): pass class ReadTimeout(TimeoutException): pass class WriteTimeout(TimeoutException): pass # Network errors class NetworkError(Exception): pass class ConnectError(NetworkError): pass class ReadError(NetworkError): pass class WriteError(NetworkError): pass pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_models.py000066400000000000000000000420161526547463400236360ustar00rootroot00000000000000from __future__ import annotations import base64 import ssl import typing import urllib.parse from collections.abc import AsyncGenerator from ._utils import safe_async_iterate # Functions for typechecking... ByteOrStr = bytes | str HeadersAsSequence = typing.Sequence[tuple[ByteOrStr, ByteOrStr]] HeadersAsMapping = typing.Mapping[ByteOrStr, ByteOrStr] HeaderTypes = HeadersAsSequence | HeadersAsMapping | None Extensions = typing.MutableMapping[str, typing.Any] def enforce_bytes(value: bytes | str, *, name: str) -> bytes: """ Any arguments that are ultimately represented as bytes can be specified either as bytes or as strings. However we enforce that any string arguments must only contain characters in the plain ASCII range. chr(0)...chr(127). If you need to use characters outside that range then be precise, and use a byte-wise argument. """ if isinstance(value, str): try: return value.encode("ascii") except UnicodeEncodeError: raise TypeError(f"{name} strings may not include unicode characters.") elif isinstance(value, bytes): return value seen_type = type(value).__name__ raise TypeError(f"{name} must be bytes or str, but got {seen_type}.") def enforce_url(value: URL | bytes | str, *, name: str) -> URL: """ Type check for URL parameters. """ if isinstance(value, (bytes, str)): return URL(value) elif isinstance(value, URL): return value seen_type = type(value).__name__ raise TypeError(f"{name} must be a URL, bytes, or str, but got {seen_type}.") def enforce_headers( value: HeadersAsMapping | HeadersAsSequence | None = None, *, name: str ) -> list[tuple[bytes, bytes]]: """ Convenience function that ensure all items in request or response headers are either bytes or strings in the plain ASCII range. """ if value is None: return [] elif isinstance(value, typing.Mapping): return [ ( enforce_bytes(k, name="header name"), enforce_bytes(v, name="header value"), ) for k, v in value.items() ] elif isinstance(value, typing.Sequence): return [ ( enforce_bytes(k, name="header name"), enforce_bytes(v, name="header value"), ) for k, v in value ] seen_type = type(value).__name__ raise TypeError(f"{name} must be a mapping or sequence of two-tuples, but got {seen_type}.") def enforce_stream( value: bytes | typing.Iterable[bytes] | typing.AsyncIterable[bytes] | None, *, name: str, ) -> typing.Iterable[bytes] | typing.AsyncIterable[bytes]: if value is None: return ByteStream(b"") elif isinstance(value, bytes): return ByteStream(value) return value # * https://tools.ietf.org/html/rfc3986#section-3.2.3 # * https://url.spec.whatwg.org/#url-miscellaneous # * https://url.spec.whatwg.org/#scheme-state DEFAULT_PORTS = { b"ftp": 21, b"http": 80, b"https": 443, b"ws": 80, b"wss": 443, } def include_request_headers( headers: list[tuple[bytes, bytes]], *, url: URL, content: None | bytes | typing.Iterable[bytes] | typing.AsyncIterable[bytes], ) -> list[tuple[bytes, bytes]]: headers_set = {k.lower() for k, _v in headers} if b"host" not in headers_set: default_port = DEFAULT_PORTS.get(url.scheme) if url.port is None or url.port == default_port: header_value = url.host else: header_value = b"%b:%d" % (url.host, url.port) headers = [(b"Host", header_value)] + headers if content is not None and b"content-length" not in headers_set and b"transfer-encoding" not in headers_set: if isinstance(content, bytes): content_length = str(len(content)).encode("ascii") headers += [(b"Content-Length", content_length)] else: headers += [(b"Transfer-Encoding", b"chunked")] # pragma: no cover return headers # Interfaces for byte streams... class ByteStream: """ A container for non-streaming content, and that supports both sync and async stream iteration. """ def __init__(self, content: bytes) -> None: self._content = content def __iter__(self) -> typing.Iterator[bytes]: yield self._content async def __aiter__(self) -> AsyncGenerator[bytes]: yield self._content def __repr__(self) -> str: return f"<{self.__class__.__name__} [{len(self._content)} bytes]>" class Origin: def __init__(self, scheme: bytes, host: bytes, port: int) -> None: self.scheme = scheme self.host = host self.port = port def __eq__(self, other: typing.Any) -> bool: return ( isinstance(other, Origin) and self.scheme == other.scheme and self.host == other.host and self.port == other.port ) def __str__(self) -> str: scheme = self.scheme.decode("ascii") host = self.host.decode("ascii") port = str(self.port) return f"{scheme}://{host}:{port}" class URL: """ Represents the URL against which an HTTP request may be made. The URL may either be specified as a plain string, for convenience: ```python url = httpcore2.URL("https://www.example.com/") ``` Or be constructed with explicitly pre-parsed components: ```python url = httpcore2.URL(scheme=b'https', host=b'www.example.com', port=None, target=b'/') ``` Using this second more explicit style allows integrations that are using `httpcore` to pass through URLs that have already been parsed in order to use libraries such as `rfc-3986` rather than relying on the stdlib. It also ensures that URL parsing is treated identically at both the networking level and at any higher layers of abstraction. The four components are important here, as they allow the URL to be precisely specified in a pre-parsed format. They also allow certain types of request to be created that could not otherwise be expressed. For example, an HTTP request to `http://www.example.com/` forwarded via a proxy at `http://localhost:8080`... ```python # Constructs an HTTP request with a complete URL as the target: # GET https://www.example.com/ HTTP/1.1 url = httpcore2.URL( scheme=b'http', host=b'localhost', port=8080, target=b'https://www.example.com/' ) request = httpcore2.Request( method="GET", url=url ) ``` Another example is constructing an `OPTIONS *` request... ```python # Constructs an 'OPTIONS *' HTTP request: # OPTIONS * HTTP/1.1 url = httpcore2.URL(scheme=b'https', host=b'www.example.com', target=b'*') request = httpcore2.Request(method="OPTIONS", url=url) ``` This kind of request is not possible to formulate with a URL string, because the `/` delimiter is always used to demark the target from the host/port portion of the URL. For convenience, string-like arguments may be specified either as strings or as bytes. However, once a request is being issue over-the-wire, the URL components are always ultimately required to be a bytewise representation. In order to avoid any ambiguity over character encodings, when strings are used as arguments, they must be strictly limited to the ASCII range `chr(0)`-`chr(127)`. If you require a bytewise representation that is outside this range you must handle the character encoding directly, and pass a bytes instance. """ def __init__( self, url: bytes | str = "", *, scheme: bytes | str = b"", host: bytes | str = b"", port: int | None = None, target: bytes | str = b"", ) -> None: """ Parameters: url: The complete URL as a string or bytes. scheme: The URL scheme as a string or bytes. Typically either `"http"` or `"https"`. host: The URL host as a string or bytes. Such as `"www.example.com"`. port: The port to connect to. Either an integer or `None`. target: The target of the HTTP request. Such as `"/items?search=red"`. """ if url: parsed = urllib.parse.urlparse(enforce_bytes(url, name="url")) self.scheme = parsed.scheme self.host = parsed.hostname or b"" self.port = parsed.port self.target = (parsed.path or b"/") + (b"?" + parsed.query if parsed.query else b"") else: self.scheme = enforce_bytes(scheme, name="scheme") self.host = enforce_bytes(host, name="host") self.port = port self.target = enforce_bytes(target, name="target") @property def origin(self) -> Origin: default_port = { b"http": 80, b"https": 443, b"ws": 80, b"wss": 443, b"socks5": 1080, b"socks5h": 1080, }[self.scheme] return Origin(scheme=self.scheme, host=self.host, port=self.port or default_port) def __eq__(self, other: typing.Any) -> bool: return ( isinstance(other, URL) and other.scheme == self.scheme and other.host == self.host and other.port == self.port and other.target == self.target ) def __bytes__(self) -> bytes: if self.port is None: return b"%b://%b%b" % (self.scheme, self.host, self.target) return b"%b://%b:%d%b" % (self.scheme, self.host, self.port, self.target) def __repr__(self) -> str: return ( f"{self.__class__.__name__}(scheme={self.scheme!r}, " f"host={self.host!r}, port={self.port!r}, target={self.target!r})" ) class Request: """ An HTTP request. """ def __init__( self, method: bytes | str, url: URL | bytes | str, *, headers: HeaderTypes = None, content: bytes | typing.Iterable[bytes] | typing.AsyncIterable[bytes] | None = None, extensions: Extensions | None = None, ) -> None: """ Parameters: method: The HTTP request method, either as a string or bytes. For example: `GET`. url: The request URL, either as a `URL` instance, or as a string or bytes. For example: `"https://www.example.com".` headers: The HTTP request headers. content: The content of the request body. extensions: A dictionary of optional extra information included on the request. Possible keys include `"timeout"`, and `"trace"`. """ self.method: bytes = enforce_bytes(method, name="method") self.url: URL = enforce_url(url, name="url") self.headers: list[tuple[bytes, bytes]] = enforce_headers(headers, name="headers") self.stream: typing.Iterable[bytes] | typing.AsyncIterable[bytes] = enforce_stream(content, name="content") self.extensions = {} if extensions is None else extensions if "target" in self.extensions: self.url = URL( scheme=self.url.scheme, host=self.url.host, port=self.url.port, target=self.extensions["target"], ) def __repr__(self) -> str: return f"<{self.__class__.__name__} [{self.method!r}]>" class Response: """ An HTTP response. """ def __init__( self, status: int, *, headers: HeaderTypes = None, content: bytes | typing.Iterable[bytes] | typing.AsyncIterable[bytes] | None = None, extensions: Extensions | None = None, ) -> None: """ Parameters: status: The HTTP status code of the response. For example `200`. headers: The HTTP response headers. content: The content of the response body. extensions: A dictionary of optional extra information included on the responseself.Possible keys include `"http_version"`, `"reason_phrase"`, and `"network_stream"`. """ self.status: int = status self.headers: list[tuple[bytes, bytes]] = enforce_headers(headers, name="headers") self.stream: typing.Iterable[bytes] | typing.AsyncIterable[bytes] = enforce_stream(content, name="content") self.extensions = {} if extensions is None else extensions self._stream_consumed = False @property def content(self) -> bytes: if not hasattr(self, "_content"): if isinstance(self.stream, typing.Iterable): raise RuntimeError( "Attempted to access 'response.content' on a streaming response. Call 'response.read()' first." ) else: raise RuntimeError( "Attempted to access 'response.content' on a streaming response. " "Call 'await response.aread()' first." ) return self._content def __repr__(self) -> str: return f"<{self.__class__.__name__} [{self.status}]>" # Sync interface... def read(self) -> bytes: if not isinstance(self.stream, typing.Iterable): # pragma: no cover raise RuntimeError( "Attempted to read an asynchronous response using 'response.read()'. " "You should use 'await response.aread()' instead." ) if not hasattr(self, "_content"): self._content = b"".join(list(self.iter_stream())) return self._content def iter_stream(self) -> typing.Iterator[bytes]: if not isinstance(self.stream, typing.Iterable): # pragma: no cover raise RuntimeError( "Attempted to stream an asynchronous response using 'for ... in " "response.iter_stream()'. " "You should use 'async for ... in response.aiter_stream()' instead." ) if self._stream_consumed: raise RuntimeError("Attempted to call 'for ... in response.iter_stream()' more than once.") self._stream_consumed = True yield from self.stream def close(self) -> None: if not isinstance(self.stream, typing.Iterable): # pragma: no cover raise RuntimeError( "Attempted to close an asynchronous response using 'response.close()'. " "You should use 'await response.aclose()' instead." ) if hasattr(self.stream, "close"): self.stream.close() # Async interface... async def aread(self) -> bytes: if not isinstance(self.stream, typing.AsyncIterable): # pragma: no cover raise RuntimeError( "Attempted to read an synchronous response using " "'await response.aread()'. " "You should use 'response.read()' instead." ) if not hasattr(self, "_content"): async with safe_async_iterate(self.aiter_stream()) as parts: self._content = b"".join([part async for part in parts]) return self._content async def aiter_stream(self) -> AsyncGenerator[bytes]: if not isinstance(self.stream, typing.AsyncIterable): # pragma: no cover raise RuntimeError( "Attempted to stream an synchronous response using 'async for ... in " "response.aiter_stream()'. " "You should use 'for ... in response.iter_stream()' instead." ) if self._stream_consumed: raise RuntimeError("Attempted to call 'async for ... in response.aiter_stream()' more than once.") self._stream_consumed = True async with safe_async_iterate(self.stream) as iterator: async for chunk in iterator: yield chunk async def aclose(self) -> None: if not isinstance(self.stream, typing.AsyncIterable): # pragma: no cover raise RuntimeError( "Attempted to close a synchronous response using " "'await response.aclose()'. " "You should use 'response.close()' instead." ) if hasattr(self.stream, "aclose"): await self.stream.aclose() class Proxy: def __init__( self, url: URL | bytes | str, auth: tuple[bytes | str, bytes | str] | None = None, headers: HeadersAsMapping | HeadersAsSequence | None = None, ssl_context: ssl.SSLContext | None = None, ): self.url = enforce_url(url, name="url") self.headers = enforce_headers(headers, name="headers") self.ssl_context = ssl_context if auth is not None: username = enforce_bytes(auth[0], name="auth") password = enforce_bytes(auth[1], name="auth") userpass = username + b":" + password authorization = b"Basic " + base64.b64encode(userpass) self.auth: tuple[bytes, bytes] | None = (username, password) self.headers = [(b"Proxy-Authorization", authorization)] + self.headers else: self.auth = None pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_ssl.py000066400000000000000000000036251526547463400231570ustar00rootroot00000000000000import os import platform import re import ssl import truststore # Mirrors `truststore`'s Linux fallbacks for when OpenSSL's compiled-in paths are unusable: # https://github.com/sethmlarson/truststore/blob/0714f72a739d182cdb8502f4e1bb4cf7ebfe4eb5/src/truststore/_openssl.py#L8-L19 CA_FILE_CANDIDATES = [ "/etc/ssl/cert.pem", "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", "/etc/pki/tls/cert.pem", "/etc/ssl/certs/ca-certificates.crt", "/etc/ssl/ca-bundle.pem", ] # `_trust_env` is internal to `httpx2`; drop it with the Linux branch below once sethmlarson/truststore#213 ships. def default_ssl_context(*, _trust_env: bool = True) -> ssl.SSLContext: if _trust_env and (cafile := os.environ.get("SSL_CERT_FILE")): # pragma: no cover return ssl.create_default_context(cafile=cafile) if _trust_env and (capath := os.environ.get("SSL_CERT_DIR")): # pragma: no cover return ssl.create_default_context(capath=capath) if platform.system() in ("Windows", "Darwin"): # pragma: no cover return truststore.SSLContext(ssl.PROTOCOL_TLS_CLIENT) # `truststore` re-adds verify paths per handshake, which OpenSSL < 3.4 accumulates (sethmlarson/truststore#212). ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) # Compiled-in paths, since `set_default_verify_paths()` would read `SSL_CERT_*`. paths = ssl.get_default_verify_paths() cafile = paths.openssl_cafile if os.path.isfile(paths.openssl_cafile) else None capath = paths.openssl_capath if os.path.isdir(paths.openssl_capath) else None if capath and not cafile: # pragma: no cover if not any(re.fullmatch(r"[0-9a-fA-F]{8}\.\d", f) for f in os.listdir(capath)): capath = None if not cafile and not capath: # pragma: no cover cafile = next(filter(os.path.isfile, CA_FILE_CANDIDATES), None) if cafile or capath: ctx.load_verify_locations(cafile, capath) return ctx pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_sync/000077500000000000000000000000001526547463400227525ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_sync/__init__.py000066400000000000000000000021671526547463400250710ustar00rootroot00000000000000from .connection import HTTPConnection from .connection_pool import ConnectionPool from .http11 import HTTP11Connection from .http_proxy import HTTPProxy from .interfaces import ConnectionInterface try: from .http2 import HTTP2Connection except ImportError: # pragma: no cover class HTTP2Connection: # type: ignore def __init__(self, *args, **kwargs) -> None: # type: ignore raise RuntimeError( "Attempted to use http2 support, but the `h2` package is not " "installed. Use 'pip install httpcore[http2]'." ) try: from .socks_proxy import SOCKSProxy except ImportError: # pragma: no cover class SOCKSProxy: # type: ignore def __init__(self, *args, **kwargs) -> None: # type: ignore raise RuntimeError( "Attempted to use SOCKS support, but the `socksio` package is not " "installed. Use 'pip install httpcore[socks]'." ) __all__ = [ "HTTPConnection", "ConnectionPool", "HTTPProxy", "HTTP11Connection", "HTTP2Connection", "ConnectionInterface", "SOCKSProxy", ] pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_sync/connection.py000066400000000000000000000176361526547463400255000ustar00rootroot00000000000000from __future__ import annotations import itertools import logging import ssl import types import typing from .._backends.sync import SyncBackend from .._backends.base import SOCKET_OPTION, NetworkBackend, NetworkStream from .._exceptions import ConnectError, ConnectTimeout from .._models import Origin, Request, Response from .._ssl import default_ssl_context from .._synchronization import Lock from .._trace import Trace from .http11 import HTTP11Connection from .interfaces import ConnectionInterface RETRIES_BACKOFF_FACTOR = 0.5 # 0s, 0.5s, 1s, 2s, 4s, etc. logger = logging.getLogger("httpcore2.connection") def exponential_backoff(factor: float) -> typing.Iterator[float]: """ Generate a geometric sequence that has a ratio of 2 and starts with 0. For example: - `factor = 2`: `0, 2, 4, 8, 16, 32, 64, ...` - `factor = 3`: `0, 3, 6, 12, 24, 48, 96, ...` """ yield 0 for n in itertools.count(): yield factor * 2**n class HTTPConnection(ConnectionInterface): def __init__( self, origin: Origin, ssl_context: ssl.SSLContext | None = None, keepalive_expiry: float | None = None, http1: bool = True, http2: bool = False, retries: int = 0, local_address: str | None = None, uds: str | None = None, network_backend: NetworkBackend | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> None: self._origin = origin self._ssl_context = ssl_context self._keepalive_expiry = keepalive_expiry self._http1 = http1 self._http2 = http2 self._retries = retries self._local_address = local_address self._uds = uds self._network_backend: NetworkBackend = SyncBackend() if network_backend is None else network_backend self._connection: ConnectionInterface | None = None self._connect_failed: bool = False self._request_lock = Lock() self._socket_options = socket_options def handle_request(self, request: Request) -> Response: if not self.can_handle_request(request.url.origin): raise RuntimeError(f"Attempted to send request to {request.url.origin} on connection to {self._origin}") try: with self._request_lock: if self._connection is None: stream = self._connect(request) ssl_object = stream.get_extra_info("ssl_object") http2_negotiated = ssl_object is not None and ssl_object.selected_alpn_protocol() == "h2" if http2_negotiated or (self._http2 and not self._http1): from .http2 import HTTP2Connection self._connection = HTTP2Connection( origin=self._origin, stream=stream, keepalive_expiry=self._keepalive_expiry, ) else: self._connection = HTTP11Connection( origin=self._origin, stream=stream, keepalive_expiry=self._keepalive_expiry, ) except BaseException as exc: self._connect_failed = True raise exc return self._connection.handle_request(request) def _connect(self, request: Request) -> NetworkStream: timeouts = request.extensions.get("timeout", {}) sni_hostname = request.extensions.get("sni_hostname", None) timeout = timeouts.get("connect", None) retries_left = self._retries delays = exponential_backoff(factor=RETRIES_BACKOFF_FACTOR) while True: try: if self._uds is None: kwargs = { "host": self._origin.host.decode("ascii"), "port": self._origin.port, "local_address": self._local_address, "timeout": timeout, "socket_options": self._socket_options, } with Trace("connect_tcp", logger, request, kwargs) as trace: stream = self._network_backend.connect_tcp(**kwargs) trace.return_value = stream else: kwargs = { "path": self._uds, "timeout": timeout, "socket_options": self._socket_options, } with Trace("connect_unix_socket", logger, request, kwargs) as trace: stream = self._network_backend.connect_unix_socket(**kwargs) trace.return_value = stream if self._origin.scheme in (b"https", b"wss"): ssl_context = default_ssl_context() if self._ssl_context is None else self._ssl_context alpn_protocols = (["h2", "http/1.1"] if self._http1 else ["h2"]) if self._http2 else ["http/1.1"] ssl_context.set_alpn_protocols(alpn_protocols) kwargs = { "ssl_context": ssl_context, "server_hostname": sni_hostname or self._origin.host.decode("ascii"), "timeout": timeout, } with Trace("start_tls", logger, request, kwargs) as trace: stream = stream.start_tls(**kwargs) trace.return_value = stream return stream except (ConnectError, ConnectTimeout): if retries_left <= 0: raise retries_left -= 1 delay = next(delays) with Trace("retry", logger, request, kwargs) as trace: self._network_backend.sleep(delay) def can_handle_request(self, origin: Origin) -> bool: return origin == self._origin def close(self) -> None: if self._connection is not None: with Trace("close", logger, None, {}): self._connection.close() def is_connected(self) -> bool: return self._connection is not None and self._connection.is_connected() def is_available(self) -> bool: if self._connection is None: # If HTTP/2 support is enabled, and the resulting connection could # end up as HTTP/2 then we should indicate the connection as being # available to service multiple requests. return self._http2 and (self._origin.scheme == b"https" or not self._http1) and not self._connect_failed return self._connection.is_available() def has_expired(self) -> bool: if self._connection is None: return self._connect_failed return self._connection.has_expired() def is_idle(self) -> bool: if self._connection is None: return self._connect_failed return self._connection.is_idle() def can_multiplex(self) -> bool: return self._connection is not None and self._connection.can_multiplex() def is_closed(self) -> bool: if self._connection is None: return self._connect_failed return self._connection.is_closed() def info(self) -> str: if self._connection is None: return "CONNECTION FAILED" if self._connect_failed else "CONNECTING" return self._connection.info() def __repr__(self) -> str: return f"<{self.__class__.__name__} [{self.info()}]>" # These context managers are not used in the standard flow, but are # useful for testing or working with connection instances directly. def __enter__(self) -> HTTPConnection: return self def __exit__( self, exc_type: type[BaseException] | None = None, exc_value: BaseException | None = None, traceback: types.TracebackType | None = None, ) -> None: self.close() pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_sync/connection_pool.py000066400000000000000000000454561526547463400265320ustar00rootroot00000000000000from __future__ import annotations import ssl import sys import types import typing from collections.abc import Generator from .._backends.sync import SyncBackend from .._backends.base import SOCKET_OPTION, NetworkBackend from .._exceptions import ConnectionNotAvailable, UnsupportedProtocol from .._models import Origin, Proxy, Request, Response from .._synchronization import Event, ShieldCancellation, ThreadLock from .._utils import safe_iterate from .connection import HTTPConnection from .interfaces import ConnectionInterface, RequestInterface class PoolRequest: def __init__(self, request: Request) -> None: self.request = request self.connection: ConnectionInterface | None = None self._connection_acquired = Event() def assign_to_connection(self, connection: ConnectionInterface | None) -> None: self.connection = connection self._connection_acquired.set() def clear_connection(self) -> None: self.connection = None self._connection_acquired = Event() def wait_for_connection(self, timeout: float | None = None) -> ConnectionInterface: if self.connection is None: self._connection_acquired.wait(timeout=timeout) assert self.connection is not None return self.connection def is_queued(self) -> bool: return self.connection is None class ConnectionPool(RequestInterface): """ A connection pool for making HTTP requests. """ def __init__( self, ssl_context: ssl.SSLContext | None = None, proxy: Proxy | None = None, max_connections: int | None = 10, max_keepalive_connections: int | None = None, keepalive_expiry: float | None = None, http1: bool = True, http2: bool = False, retries: int = 0, local_address: str | None = None, uds: str | None = None, network_backend: NetworkBackend | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> None: """ A connection pool for making HTTP requests. Parameters: ssl_context: An SSL context to use for verifying connections. If not specified, the default `httpcore2.default_ssl_context()` will be used. max_connections: The maximum number of concurrent HTTP connections that the pool should allow. Any attempt to send a request on a pool that would exceed this amount will block until a connection is available. max_keepalive_connections: The maximum number of idle HTTP connections that will be maintained in the pool. keepalive_expiry: The duration in seconds that an idle HTTP connection may be maintained for before being expired from the pool. http1: A boolean indicating if HTTP/1.1 requests should be supported by the connection pool. Defaults to True. http2: A boolean indicating if HTTP/2 requests should be supported by the connection pool. Defaults to False. retries: The maximum number of retries when trying to establish a connection. local_address: Local address to connect from. Can also be used to connect using a particular address family. Using `local_address="0.0.0.0"` will connect using an `AF_INET` address (IPv4), while using `local_address="::"` will connect using an `AF_INET6` address (IPv6). uds: Path to a Unix Domain Socket to use instead of TCP sockets. network_backend: A backend instance to use for handling network I/O. socket_options: Socket options that have to be included in the TCP socket when the connection was established. """ self._ssl_context = ssl_context self._proxy = proxy self._max_connections = sys.maxsize if max_connections is None else max_connections self._max_keepalive_connections = ( sys.maxsize if max_keepalive_connections is None else max_keepalive_connections ) self._max_keepalive_connections = min(self._max_connections, self._max_keepalive_connections) self._keepalive_expiry = keepalive_expiry self._http1 = http1 self._http2 = http2 self._retries = retries self._local_address = local_address self._uds = uds self._network_backend = SyncBackend() if network_backend is None else network_backend self._socket_options = socket_options # The mutable state on a connection pool is the queue of incoming requests, # and the set of connections that are servicing those requests. self._connections: list[ConnectionInterface] = [] self._requests: list[PoolRequest] = [] # We only mutate the state of the connection pool within an 'optional_thread_lock' # context. This holds a threading lock unless we're running in async mode, # in which case it is a no-op. self._optional_thread_lock = ThreadLock() def create_connection(self, origin: Origin) -> ConnectionInterface: if self._proxy is not None: if self._proxy.url.scheme in (b"socks5", b"socks5h"): from .socks_proxy import Socks5Connection return Socks5Connection( proxy_origin=self._proxy.url.origin, proxy_auth=self._proxy.auth, remote_origin=origin, ssl_context=self._ssl_context, keepalive_expiry=self._keepalive_expiry, http1=self._http1, http2=self._http2, network_backend=self._network_backend, ) elif origin.scheme == b"http": from .http_proxy import ForwardHTTPConnection return ForwardHTTPConnection( proxy_origin=self._proxy.url.origin, proxy_headers=self._proxy.headers, proxy_ssl_context=self._proxy.ssl_context, remote_origin=origin, keepalive_expiry=self._keepalive_expiry, network_backend=self._network_backend, ) from .http_proxy import TunnelHTTPConnection return TunnelHTTPConnection( proxy_origin=self._proxy.url.origin, proxy_headers=self._proxy.headers, proxy_ssl_context=self._proxy.ssl_context, remote_origin=origin, ssl_context=self._ssl_context, keepalive_expiry=self._keepalive_expiry, http1=self._http1, http2=self._http2, network_backend=self._network_backend, ) return HTTPConnection( origin=origin, ssl_context=self._ssl_context, keepalive_expiry=self._keepalive_expiry, http1=self._http1, http2=self._http2, retries=self._retries, local_address=self._local_address, uds=self._uds, network_backend=self._network_backend, socket_options=self._socket_options, ) @property def connections(self) -> list[ConnectionInterface]: """ Return a list of the connections currently in the pool. For example: ```python >>> pool.connections [ , , , ] ``` """ return list(self._connections) def handle_request(self, request: Request) -> Response: """ Send an HTTP request, and return an HTTP response. This is the core implementation that is called into by `.request()` or `.stream()`. """ scheme = request.url.scheme.decode() if scheme == "": raise UnsupportedProtocol("Request URL is missing an 'http://' or 'https://' protocol.") if scheme not in ("http", "https", "ws", "wss"): raise UnsupportedProtocol(f"Request URL has an unsupported protocol '{scheme}://'.") timeouts = request.extensions.get("timeout", {}) timeout = timeouts.get("pool", None) with self._optional_thread_lock: # Add the incoming request to our request queue. pool_request = PoolRequest(request) self._requests.append(pool_request) try: while True: with self._optional_thread_lock: # Assign incoming requests to available connections, # closing or creating new connections as required. closing = self._assign_requests_to_connections() self._close_connections(closing) # Wait until this request has an assigned connection. connection = pool_request.wait_for_connection(timeout=timeout) try: # Send the request on the assigned connection. response = connection.handle_request(pool_request.request) except ConnectionNotAvailable: # In some cases a connection may initially be available to # handle a request, but then become unavailable. # # In this case we clear the connection and try again. pool_request.clear_connection() else: break # pragma: no cover except BaseException as exc: with self._optional_thread_lock: # For any exception or cancellation we remove the request from # the queue, and then re-assign requests to connections. self._requests.remove(pool_request) closing = self._assign_requests_to_connections() self._close_connections(closing) raise exc from None # Return the response. Note that in this case we still have to manage # the point at which the response is closed. assert isinstance(response.stream, typing.Iterable) return Response( status=response.status, headers=response.headers, content=PoolByteStream(stream=response.stream, pool_request=pool_request, pool=self), extensions=response.extensions, ) def _assign_requests_to_connections(self) -> list[ConnectionInterface]: """ Manage the state of the connection pool, assigning incoming requests to connections as available. Called whenever a new request is added or removed from the pool. Any closing connections are returned, allowing the I/O for closing those connections to be handled separately. """ closing_connections: list[ConnectionInterface] = [] retained_connections: list[ConnectionInterface] = [] # Connections currently referenced by an in-flight request, including # connections that are in the process of being established and idle # connections reserved by an assigned-but-not-yet-sent request. request_connections = {r.connection for r in self._requests} # First we handle cleaning up any connections that are closed # or have expired their keep-alive, in a single pass. Reserved # connections skip the expiry check: they were checked when assigned, # and `has_expired()` on an idle connection probes the socket. for connection in self._connections: reserved = connection in request_connections if connection.is_closed(): continue elif not (connection.is_connected() or reserved): # Garbage: a NEW-state connection whose request was cancelled # before the TCP handshake completed. Drop it without closing # (there is no socket to close yet). continue elif not reserved and connection.has_expired(): closing_connections.append(connection) else: retained_connections.append(connection) # Then we close any surplus idle connections, to enforce the # max_keepalive_connections setting. Reserved connections are not # surplus: a request is about to be sent on them. idle_surplus = ( sum(connection.is_idle() and connection not in request_connections for connection in retained_connections) - self._max_keepalive_connections ) if idle_surplus > 0: kept: list[ConnectionInterface] = [] for connection in retained_connections: if idle_surplus > 0 and connection.is_idle() and connection not in request_connections: closing_connections.append(connection) idle_surplus -= 1 else: kept.append(connection) retained_connections = kept self._connections = retained_connections # Snapshot the set of reusable connections once, rather than rebuilding # it per queued request โ€” this is what brings the loop from O(N*M) to # O(N+M) in the common case. # # An idle connection already assigned to an in-flight request is # reserved: it stays IDLE until the winning task sends on it, so # without this exclusion the next pass would assign it again and the # loser would churn through `ConnectionNotAvailable`. Multiplexing # connections are exempt: they can take further requests while idle. available_connections = [ connection for connection in self._connections if connection.is_available() and not (connection.is_idle() and connection in request_connections and not connection.can_multiplex()) ] new_connection_budget = self._max_connections - len(self._connections) # Assign queued requests to connections. Once no connection is # available and no new connection may be created, no queued request # can be assigned, so the scan stops early: this keeps a pass on a # saturated pool O(connections) rather than O(in-flight requests). for pool_request in self._requests: if not available_connections and new_connection_budget <= 0: break if not pool_request.is_queued(): continue origin = pool_request.request.url.origin # There are three cases for how we may be able to handle the request: # # 1. There is an existing connection that can handle the request. # 2. We can create a new connection to handle the request. # 3. We can close an idle connection and then create a new connection # to handle the request. for idx, connection in enumerate(available_connections): if connection.can_handle_request(origin): pool_request.assign_to_connection(connection) if connection.is_idle() and not connection.can_multiplex(): # An idle HTTP/1.1 connection can only take this # single request until it is released. del available_connections[idx] break else: if new_connection_budget > 0: connection = self.create_connection(origin) self._connections.append(connection) pool_request.assign_to_connection(connection) new_connection_budget -= 1 continue for idx, connection in enumerate(available_connections): if connection.is_idle(): del available_connections[idx] self._connections.remove(connection) closing_connections.append(connection) connection = self.create_connection(origin) self._connections.append(connection) pool_request.assign_to_connection(connection) break return closing_connections def _close_connections(self, closing: list[ConnectionInterface]) -> None: # Close connections which have been removed from the pool. with ShieldCancellation(): for connection in closing: connection.close() def close(self) -> None: # Explicitly close the connection pool. # Clears all existing requests and connections. with self._optional_thread_lock: closing_connections = list(self._connections) self._connections = [] self._close_connections(closing_connections) def __enter__(self) -> ConnectionPool: return self def __exit__( self, exc_type: type[BaseException] | None = None, exc_value: BaseException | None = None, traceback: types.TracebackType | None = None, ) -> None: self.close() def __repr__(self) -> str: class_name = self.__class__.__name__ with self._optional_thread_lock: request_is_queued = [request.is_queued() for request in self._requests] connection_is_idle = [connection.is_idle() for connection in self._connections] num_active_requests = request_is_queued.count(False) num_queued_requests = request_is_queued.count(True) num_active_connections = connection_is_idle.count(False) num_idle_connections = connection_is_idle.count(True) requests_info = f"Requests: {num_active_requests} active, {num_queued_requests} queued" connection_info = f"Connections: {num_active_connections} active, {num_idle_connections} idle" return f"<{class_name} [{requests_info} | {connection_info}]>" class PoolByteStream: def __init__( self, stream: typing.Iterable[bytes], pool_request: PoolRequest, pool: ConnectionPool, ) -> None: self._stream = stream self._pool_request = pool_request self._pool = pool self._closed = False def __iter__(self) -> Generator[bytes]: with safe_iterate(self._stream) as iterator: for chunk in iterator: yield chunk def close(self) -> None: if not self._closed: self._closed = True with ShieldCancellation(): if hasattr(self._stream, "close"): self._stream.close() with self._pool._optional_thread_lock: self._pool._requests.remove(self._pool_request) closing = self._pool._assign_requests_to_connections() self._pool._close_connections(closing) pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_sync/http11.py000066400000000000000000000322571526547463400244560ustar00rootroot00000000000000from __future__ import annotations import enum import logging import ssl import time import types import typing from collections.abc import Generator import h11 from .._backends.base import NetworkStream from .._exceptions import ( ConnectionNotAvailable, LocalProtocolError, RemoteProtocolError, WriteError, map_exceptions, ) from .._models import Origin, Request, Response from .._synchronization import Lock, ShieldCancellation from .._trace import Trace from .._utils import safe_iterate from .interfaces import ConnectionInterface logger = logging.getLogger("httpcore2.http11") # A subset of `h11.Event` types supported by `_send_event` H11SendEvent = h11.Request | h11.Data | h11.EndOfMessage class HTTPConnectionState(enum.IntEnum): NEW = 0 ACTIVE = 1 IDLE = 2 CLOSED = 3 class HTTP11Connection(ConnectionInterface): READ_NUM_BYTES = 64 * 1024 MAX_INCOMPLETE_EVENT_SIZE = 100 * 1024 def __init__( self, origin: Origin, stream: NetworkStream, keepalive_expiry: float | None = None, ) -> None: self._origin = origin self._network_stream = stream self._keepalive_expiry: float | None = keepalive_expiry self._expire_at: float | None = None self._state = HTTPConnectionState.NEW self._state_lock = Lock() self._request_count = 0 self._h11_state = h11.Connection( our_role=h11.CLIENT, max_incomplete_event_size=self.MAX_INCOMPLETE_EVENT_SIZE, ) def handle_request(self, request: Request) -> Response: if not self.can_handle_request(request.url.origin): raise RuntimeError(f"Attempted to send request to {request.url.origin} on connection to {self._origin}") with self._state_lock: if self._state in (HTTPConnectionState.NEW, HTTPConnectionState.IDLE): self._request_count += 1 self._state = HTTPConnectionState.ACTIVE self._expire_at = None else: raise ConnectionNotAvailable() try: kwargs = {"request": request} try: with Trace("send_request_headers", logger, request, kwargs) as trace: self._send_request_headers(**kwargs) with Trace("send_request_body", logger, request, kwargs) as trace: self._send_request_body(**kwargs) except WriteError: # If we get a write error while we're writing the request, # then we suppress this error and move on to attempting to # read the response. Servers can sometimes close the request # preemptively and then respond with a well formed HTTP # error response. pass with Trace("receive_response_headers", logger, request, kwargs) as trace: ( http_version, status, reason_phrase, headers, trailing_data, ) = self._receive_response_headers(**kwargs) trace.return_value = ( http_version, status, reason_phrase, headers, ) network_stream = self._network_stream # CONNECT or Upgrade request if (status == 101) or ((request.method == b"CONNECT") and (200 <= status < 300)): network_stream = HTTP11UpgradeStream(network_stream, trailing_data) return Response( status=status, headers=headers, content=HTTP11ConnectionByteStream(self, request), extensions={ "http_version": http_version, "reason_phrase": reason_phrase, "network_stream": network_stream, }, ) except BaseException as exc: with ShieldCancellation(): with Trace("response_closed", logger, request) as trace: self._response_closed() raise exc # Sending the request... def _send_request_headers(self, request: Request) -> None: timeouts = request.extensions.get("timeout", {}) timeout = timeouts.get("write", None) with map_exceptions({h11.LocalProtocolError: LocalProtocolError}): event = h11.Request( method=request.method, target=request.url.target, headers=request.headers, ) self._send_event(event, timeout=timeout) def _send_request_body(self, request: Request) -> None: timeouts = request.extensions.get("timeout", {}) timeout = timeouts.get("write", None) assert isinstance(request.stream, typing.Iterable) with safe_iterate(request.stream) as iterator: for chunk in iterator: event = h11.Data(data=chunk) self._send_event(event, timeout=timeout) self._send_event(h11.EndOfMessage(), timeout=timeout) def _send_event(self, event: h11.Event, timeout: float | None = None) -> None: bytes_to_send = self._h11_state.send(event) if bytes_to_send is not None: self._network_stream.write(bytes_to_send, timeout=timeout) # Receiving the response... def _receive_response_headers( self, request: Request ) -> tuple[bytes, int, bytes, list[tuple[bytes, bytes]], bytes]: timeouts = request.extensions.get("timeout", {}) timeout = timeouts.get("read", None) while True: event = self._receive_event(timeout=timeout) if isinstance(event, h11.Response): break if isinstance(event, h11.InformationalResponse) and event.status_code == 101: break http_version = b"HTTP/" + event.http_version # h11 version 0.11+ supports a `raw_items` interface to get the # raw header casing, rather than the enforced lowercase headers. headers = event.headers.raw_items() trailing_data, _ = self._h11_state.trailing_data return http_version, event.status_code, event.reason, headers, trailing_data def _receive_response_body(self, request: Request) -> Generator[bytes]: timeouts = request.extensions.get("timeout", {}) timeout = timeouts.get("read", None) while True: event = self._receive_event(timeout=timeout) if isinstance(event, h11.Data): yield bytes(event.data) elif isinstance(event, (h11.EndOfMessage, h11.PAUSED)): break def _receive_event(self, timeout: float | None = None) -> h11.Event | type[h11.PAUSED]: while True: with map_exceptions({h11.RemoteProtocolError: RemoteProtocolError}): event = self._h11_state.next_event() if event is h11.NEED_DATA: data = self._network_stream.read(self.READ_NUM_BYTES, timeout=timeout) # If we feed this case through h11 we'll raise an exception like: # # httpcore2.RemoteProtocolError: can't handle event type # ConnectionClosed when role=SERVER and state=SEND_RESPONSE # # Which is accurate, but not very informative from an end-user # perspective. Instead we handle this case distinctly and treat # it as a ConnectError. if data == b"" and self._h11_state.their_state == h11.SEND_RESPONSE: msg = "Server disconnected without sending a response." raise RemoteProtocolError(msg) self._h11_state.receive_data(data) else: # mypy fails to narrow the type in the above if statement above return event # type: ignore[return-value] def _response_closed(self) -> None: with self._state_lock: if self._h11_state.our_state is h11.DONE and self._h11_state.their_state is h11.DONE: self._state = HTTPConnectionState.IDLE self._h11_state.start_next_cycle() if self._keepalive_expiry is not None: now = time.monotonic() self._expire_at = now + self._keepalive_expiry else: self.close() # Once the connection is no longer required... def close(self) -> None: # Note that this method unilaterally closes the connection, and does # not have any kind of locking in place around it. self._state = HTTPConnectionState.CLOSED self._network_stream.close() # The ConnectionInterface methods provide information about the state of # the connection, allowing for a connection pooling implementation to # determine when to reuse and when to close the connection... def can_handle_request(self, origin: Origin) -> bool: return origin == self._origin def is_connected(self) -> bool: return not self.is_closed() def is_available(self) -> bool: # Note that HTTP/1.1 connections in the "NEW" state are not treated as # being "available". The control flow which created the connection will # be able to send an outgoing request, but the connection will not be # acquired from the connection pool for any other request. return self._state == HTTPConnectionState.IDLE def has_expired(self) -> bool: now = time.monotonic() # Read `_expire_at` once into a local: on free-threaded builds another # thread may reset it to `None` between the check and the comparison. expire_at = self._expire_at keepalive_expired = expire_at is not None and now > expire_at # If the HTTP connection is idle but the socket is readable, then the # only valid state is that the socket is about to return b"", indicating # a server-initiated disconnect. server_disconnected = self._state == HTTPConnectionState.IDLE and self._network_stream.get_extra_info( "is_readable" ) return keepalive_expired or server_disconnected def is_idle(self) -> bool: return self._state == HTTPConnectionState.IDLE def is_closed(self) -> bool: return self._state == HTTPConnectionState.CLOSED def info(self) -> str: origin = str(self._origin) return f"{origin!r}, HTTP/1.1, {self._state.name}, Request Count: {self._request_count}" def __repr__(self) -> str: class_name = self.__class__.__name__ origin = str(self._origin) return f"<{class_name} [{origin!r}, {self._state.name}, Request Count: {self._request_count}]>" # These context managers are not used in the standard flow, but are # useful for testing or working with connection instances directly. def __enter__(self) -> HTTP11Connection: return self def __exit__( self, exc_type: type[BaseException] | None = None, exc_value: BaseException | None = None, traceback: types.TracebackType | None = None, ) -> None: self.close() class HTTP11ConnectionByteStream: def __init__(self, connection: HTTP11Connection, request: Request) -> None: self._connection = connection self._request = request self._closed = False def __iter__(self) -> Generator[bytes]: kwargs = {"request": self._request} try: with Trace("receive_response_body", logger, self._request, kwargs): with safe_iterate(self._connection._receive_response_body(**kwargs)) as iterator: for chunk in iterator: yield chunk except BaseException as exc: # If we get an exception while streaming the response, # we want to close the response (and possibly the connection) # before raising that exception. with ShieldCancellation(): self.close() raise exc def close(self) -> None: if not self._closed: self._closed = True with Trace("response_closed", logger, self._request): self._connection._response_closed() class HTTP11UpgradeStream(NetworkStream): def __init__(self, stream: NetworkStream, leading_data: bytes) -> None: self._stream = stream self._leading_data = leading_data def read(self, max_bytes: int, timeout: float | None = None) -> bytes: if self._leading_data: buffer = self._leading_data[:max_bytes] self._leading_data = self._leading_data[max_bytes:] return buffer else: return self._stream.read(max_bytes, timeout) def write(self, buffer: bytes, timeout: float | None = None) -> None: self._stream.write(buffer, timeout) def close(self) -> None: self._stream.close() def start_tls( self, ssl_context: ssl.SSLContext, server_hostname: str | None = None, timeout: float | None = None, ) -> NetworkStream: return self._stream.start_tls(ssl_context, server_hostname, timeout) def get_extra_info(self, info: str) -> typing.Any: return self._stream.get_extra_info(info) pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_sync/http2.py000066400000000000000000000577171526547463400244060ustar00rootroot00000000000000from __future__ import annotations import enum import logging import time import types import typing from collections.abc import Generator import h2.config import h2.connection import h2.events import h2.exceptions import h2.settings from .._backends.base import NetworkStream from .._exceptions import ConnectionNotAvailable, LocalProtocolError, RemoteProtocolError from .._models import Origin, Request, Response from .._synchronization import Lock, Semaphore, ShieldCancellation from .._trace import Trace from .._utils import safe_iterate from .interfaces import ConnectionInterface logger = logging.getLogger("httpcore2.http2") def has_body_headers(request: Request) -> bool: return any(k.lower() == b"content-length" or k.lower() == b"transfer-encoding" for k, _v in request.headers) class HTTPConnectionState(enum.IntEnum): ACTIVE = 1 IDLE = 2 CLOSED = 3 class HTTP2Connection(ConnectionInterface): READ_NUM_BYTES = 64 * 1024 CONFIG = h2.config.H2Configuration(validate_inbound_headers=False) def __init__( self, origin: Origin, stream: NetworkStream, keepalive_expiry: float | None = None, ): self._origin = origin self._network_stream = stream self._keepalive_expiry: float | None = keepalive_expiry self._h2_state = h2.connection.H2Connection(config=self.CONFIG) self._state = HTTPConnectionState.IDLE self._expire_at: float | None = None self._request_count = 0 self._init_lock = Lock() self._state_lock = Lock() self._read_lock = Lock() self._write_lock = Lock() self._sent_connection_init = False self._used_all_stream_ids = False self._connection_error = False # Mapping from stream ID to response stream events. self._events: dict[ int, list[h2.events.ResponseReceived | h2.events.DataReceived | h2.events.StreamEnded | h2.events.StreamReset,], ] = {} # Connection terminated events are stored as state since # we need to handle them for all streams. self._connection_terminated: h2.events.ConnectionTerminated | None = None self._read_exception: Exception | None = None self._write_exception: Exception | None = None def handle_request(self, request: Request) -> Response: if not self.can_handle_request(request.url.origin): # This cannot occur in normal operation, since the connection pool # will only send requests on connections that handle them. # It's in place simply for resilience as a guard against incorrect # usage, for anyone working directly with httpcore connections. raise RuntimeError(f"Attempted to send request to {request.url.origin} on connection to {self._origin}") with self._state_lock: if self._state in (HTTPConnectionState.ACTIVE, HTTPConnectionState.IDLE): self._request_count += 1 self._expire_at = None self._state = HTTPConnectionState.ACTIVE else: raise ConnectionNotAvailable() with self._init_lock: if not self._sent_connection_init: try: sci_kwargs = {"request": request} with Trace("send_connection_init", logger, request, sci_kwargs): self._send_connection_init(**sci_kwargs) except BaseException as exc: with ShieldCancellation(): self.close() raise exc self._sent_connection_init = True # Initially start with just 1 until the remote server provides # its max_concurrent_streams value self._max_streams = 1 # Revoked permits still held by active or queued requests. self._max_streams_deficit = 0 local_settings_max_streams = self._h2_state.local_settings.max_concurrent_streams self._max_streams_semaphore = Semaphore(local_settings_max_streams) for _ in range(local_settings_max_streams - self._max_streams): self._max_streams_semaphore.acquire() # A queued request may receive a permit just before the limit drops. while True: self._max_streams_semaphore.acquire() with ShieldCancellation(): with self._state_lock: if not self._max_streams_deficit: break self._max_streams_deficit -= 1 try: stream_id = self._h2_state.get_next_available_stream_id() self._events[stream_id] = [] except h2.exceptions.NoAvailableStreamIDError: # pragma: no cover self._used_all_stream_ids = True self._request_count -= 1 self._max_streams_semaphore.release() raise ConnectionNotAvailable() try: kwargs = {"request": request, "stream_id": stream_id} with Trace("send_request_headers", logger, request, kwargs): self._send_request_headers(request=request, stream_id=stream_id) with Trace("send_request_body", logger, request, kwargs): self._send_request_body(request=request, stream_id=stream_id) with Trace("receive_response_headers", logger, request, kwargs) as trace: status, headers = self._receive_response(request=request, stream_id=stream_id) trace.return_value = (status, headers) return Response( status=status, headers=headers, content=HTTP2ConnectionByteStream(self, request, stream_id=stream_id), extensions={ "http_version": b"HTTP/2", "network_stream": self._network_stream, "stream_id": stream_id, }, ) except BaseException as exc: # noqa: PIE786 with ShieldCancellation(): kwargs = {"stream_id": stream_id} with Trace("response_closed", logger, request, kwargs): self._response_closed(stream_id=stream_id) if isinstance(exc, h2.exceptions.ProtocolError): # One case where h2 can raise a protocol error is when a # closed frame has been seen by the state machine. # # This happens when one stream is reading, and encounters # a GOAWAY event. Other flows of control may then raise # a protocol error at any point they interact with the 'h2_state'. # # In this case we'll have stored the event, and should raise # it as a RemoteProtocolError. if self._connection_terminated: # pragma: no cover raise RemoteProtocolError(self._connection_terminated) # If h2 raises a protocol error in some other state then we # must somehow have made a protocol violation. raise LocalProtocolError(exc) # pragma: no cover raise exc def _send_connection_init(self, request: Request) -> None: """ The HTTP/2 connection requires some initial setup before we can start using individual request/response streams on it. """ # Need to set these manually here instead of manipulating via # __setitem__() otherwise the H2Connection will emit SettingsUpdate # frames in addition to sending the undesired defaults. self._h2_state.local_settings = h2.settings.Settings( client=True, initial_values={ # Disable PUSH_PROMISE frames from the server since we don't do anything # with them for now. Maybe when we support caching? h2.settings.SettingCodes.ENABLE_PUSH: 0, # These two are taken from h2 for safe defaults h2.settings.SettingCodes.MAX_CONCURRENT_STREAMS: 100, h2.settings.SettingCodes.MAX_HEADER_LIST_SIZE: 65536, }, ) # Some websites (*cough* Yahoo *cough*) balk at this setting being # present in the initial handshake since it's not defined in the original # RFC despite the RFC mandating ignoring settings you don't know about. del self._h2_state.local_settings[h2.settings.SettingCodes.ENABLE_CONNECT_PROTOCOL] self._h2_state.initiate_connection() self._h2_state.increment_flow_control_window(2**24) self._write_outgoing_data(request) # Sending the request... def _send_request_headers(self, request: Request, stream_id: int) -> None: """ Send the request headers to a given stream ID. """ end_stream = not has_body_headers(request) # In HTTP/2 the ':authority' pseudo-header is used instead of 'Host'. # In order to gracefully handle HTTP/1.1 and HTTP/2 we always require # HTTP/1.1 style headers, and map them appropriately if we end up on # an HTTP/2 connection. authority = [v for k, v in request.headers if k.lower() == b"host"][0] headers = [ (b":method", request.method), (b":authority", authority), (b":scheme", request.url.scheme), (b":path", request.url.target), ] + [ (k.lower(), v) for k, v in request.headers if k.lower() not in ( b"host", b"transfer-encoding", ) ] self._h2_state.send_headers(stream_id, headers, end_stream=end_stream) self._h2_state.increment_flow_control_window(2**24, stream_id=stream_id) self._write_outgoing_data(request) def _send_request_body(self, request: Request, stream_id: int) -> None: """ Iterate over the request body sending it to a given stream ID. """ if not has_body_headers(request): return assert isinstance(request.stream, typing.Iterable) with safe_iterate(request.stream) as iterator: for chunk in iterator: self._send_stream_data(request, stream_id, chunk) self._send_end_stream(request, stream_id) def _send_stream_data(self, request: Request, stream_id: int, data: bytes) -> None: """ Send a single chunk of data in one or more data frames. """ position = 0 while position < len(data): max_flow = self._wait_for_outgoing_flow(request, stream_id) chunk = data[position : position + max_flow] position += len(chunk) self._h2_state.send_data(stream_id, chunk) self._write_outgoing_data(request) def _send_end_stream(self, request: Request, stream_id: int) -> None: """ Send an empty data frame on on a given stream ID with the END_STREAM flag set. """ self._h2_state.end_stream(stream_id) self._write_outgoing_data(request) # Receiving the response... def _receive_response(self, request: Request, stream_id: int) -> tuple[int, list[tuple[bytes, bytes]]]: """ Return the response status code and headers for a given stream ID. """ while True: event = self._receive_stream_event(request, stream_id) if isinstance(event, h2.events.ResponseReceived): break status_code = 200 headers: list[tuple[bytes, bytes]] = [] assert event.headers is not None for k, v in event.headers: if k == b":status": status_code = int(v.decode("ascii", errors="ignore")) elif not k.startswith(b":"): headers.append((k, v)) return (status_code, headers) def _receive_response_body(self, request: Request, stream_id: int) -> Generator[bytes]: """ Iterator that returns the bytes of the response body for a given stream ID. """ while True: event = self._receive_stream_event(request, stream_id) if isinstance(event, h2.events.DataReceived): assert event.flow_controlled_length is not None assert event.data is not None amount = event.flow_controlled_length self._h2_state.acknowledge_received_data(amount, stream_id) self._write_outgoing_data(request) yield event.data elif isinstance(event, h2.events.StreamEnded): break def _receive_stream_event( self, request: Request, stream_id: int ) -> h2.events.ResponseReceived | h2.events.DataReceived | h2.events.StreamEnded: """ Return the next available event for a given stream ID. Will read more data from the network if required. """ while not self._events.get(stream_id): self._receive_events(request, stream_id) event = self._events[stream_id].pop(0) if isinstance(event, h2.events.StreamReset): raise RemoteProtocolError(event) return event def _receive_events(self, request: Request, stream_id: int | None = None) -> None: """ Read some data from the network until we see one or more events for a given stream ID. """ with self._read_lock: if self._connection_terminated is not None: last_stream_id = self._connection_terminated.last_stream_id if stream_id and last_stream_id and stream_id > last_stream_id: self._request_count -= 1 raise ConnectionNotAvailable() raise RemoteProtocolError(self._connection_terminated) # This conditional is a bit icky. We don't want to block reading if we've # actually got an event to return for a given stream. We need to do that # check *within* the atomic read lock. Though it also need to be optional, # because when we call it from `_wait_for_outgoing_flow` we *do* want to # block until we've available flow control, event when we have events # pending for the stream ID we're attempting to send on. if stream_id is None or not self._events.get(stream_id): events = self._read_incoming_data(request) for event in events: if isinstance(event, h2.events.RemoteSettingsChanged): with Trace("receive_remote_settings", logger, request) as trace: trace.return_value = event elif isinstance( event, ( h2.events.ResponseReceived, h2.events.DataReceived, h2.events.StreamEnded, h2.events.StreamReset, ), ): if event.stream_id in self._events: self._events[event.stream_id].append(event) elif isinstance(event, h2.events.ConnectionTerminated): self._connection_terminated = event self._write_outgoing_data(request) def _receive_remote_settings_change(self, event: h2.events.RemoteSettingsChanged) -> None: max_concurrent_streams = event.changed_settings.get(h2.settings.SettingCodes.MAX_CONCURRENT_STREAMS) if max_concurrent_streams: new_max_streams = min( max_concurrent_streams.new_value, self._h2_state.local_settings.max_concurrent_streams, ) if new_max_streams and new_max_streams != self._max_streams: # Never wait for permits while holding the read lock. while new_max_streams > self._max_streams: if self._max_streams_deficit > 0: self._max_streams_deficit -= 1 else: self._max_streams_semaphore.release() self._max_streams += 1 while new_max_streams < self._max_streams: if not self._max_streams_semaphore.acquire_if_available(): self._max_streams_deficit += 1 self._max_streams -= 1 def _response_closed(self, stream_id: int) -> None: with self._state_lock: if stream_id in self._events: if self._max_streams_deficit > 0: self._max_streams_deficit -= 1 else: self._max_streams_semaphore.release() del self._events[stream_id] if self._connection_terminated and not self._events: self.close() elif self._state == HTTPConnectionState.ACTIVE and not self._events: self._state = HTTPConnectionState.IDLE if self._keepalive_expiry is not None: now = time.monotonic() self._expire_at = now + self._keepalive_expiry if self._used_all_stream_ids: # pragma: no cover self.close() def close(self) -> None: # Note that this method unilaterally closes the connection, and does # not have any kind of locking in place around it. self._h2_state.close_connection() self._state = HTTPConnectionState.CLOSED self._network_stream.close() # Wrappers around network read/write operations... def _read_incoming_data(self, request: Request) -> list[h2.events.Event]: timeouts = request.extensions.get("timeout", {}) timeout = timeouts.get("read", None) if self._read_exception is not None: raise self._read_exception # pragma: no cover try: data = self._network_stream.read(self.READ_NUM_BYTES, timeout) if data == b"": raise RemoteProtocolError("Server disconnected") except Exception as exc: # If we get a network error we should: # # 1. Save the exception and just raise it immediately on any future reads. # (For example, this means that a single read timeout or disconnect will # immediately close all pending streams. Without requiring multiple # sequential timeouts.) # 2. Mark the connection as errored, so that we don't accept any other # incoming requests. self._read_exception = exc self._connection_error = True raise exc # Apply settings and stream admission limits atomically. with ShieldCancellation(): with self._state_lock: events: list[h2.events.Event] = self._h2_state.receive_data(data) for event in events: if isinstance(event, h2.events.RemoteSettingsChanged): self._receive_remote_settings_change(event) return events def _write_outgoing_data(self, request: Request) -> None: timeouts = request.extensions.get("timeout", {}) timeout = timeouts.get("write", None) with self._write_lock: data_to_send = self._h2_state.data_to_send() if self._write_exception is not None: raise self._write_exception # pragma: no cover try: self._network_stream.write(data_to_send, timeout) except Exception as exc: # pragma: no cover # If we get a network error we should: # # 1. Save the exception and just raise it immediately on any future write. # (For example, this means that a single write timeout or disconnect will # immediately close all pending streams. Without requiring multiple # sequential timeouts.) # 2. Mark the connection as errored, so that we don't accept any other # incoming requests. self._write_exception = exc self._connection_error = True raise exc # Flow control... def _wait_for_outgoing_flow(self, request: Request, stream_id: int) -> int: """ Returns the maximum allowable outgoing flow for a given stream. If the allowable flow is zero, then waits on the network until WindowUpdated frames have increased the flow rate. https://tools.ietf.org/html/rfc7540#section-6.9 """ local_flow: int = self._h2_state.local_flow_control_window(stream_id) max_frame_size: int = self._h2_state.max_outbound_frame_size flow = min(local_flow, max_frame_size) while flow <= 0: self._receive_events(request) local_flow = self._h2_state.local_flow_control_window(stream_id) max_frame_size = self._h2_state.max_outbound_frame_size flow = min(local_flow, max_frame_size) return flow # Interface for connection pooling... def can_handle_request(self, origin: Origin) -> bool: return origin == self._origin def is_connected(self) -> bool: return not self.is_closed() def is_available(self) -> bool: return ( self._state != HTTPConnectionState.CLOSED and not self._connection_error and not self._used_all_stream_ids and not (self._h2_state.state_machine.state == h2.connection.ConnectionState.CLOSED) ) def has_expired(self) -> bool: now = time.monotonic() # Read `_expire_at` once into a local: on free-threaded builds another # thread may reset it to `None` between the check and the comparison. expire_at = self._expire_at return expire_at is not None and now > expire_at def is_idle(self) -> bool: return self._state == HTTPConnectionState.IDLE def can_multiplex(self) -> bool: return True def is_closed(self) -> bool: return self._state == HTTPConnectionState.CLOSED def info(self) -> str: origin = str(self._origin) return f"{origin!r}, HTTP/2, {self._state.name}, Request Count: {self._request_count}" def __repr__(self) -> str: class_name = self.__class__.__name__ origin = str(self._origin) return f"<{class_name} [{origin!r}, {self._state.name}, Request Count: {self._request_count}]>" # These context managers are not used in the standard flow, but are # useful for testing or working with connection instances directly. def __enter__(self) -> HTTP2Connection: return self def __exit__( self, exc_type: type[BaseException] | None = None, exc_value: BaseException | None = None, traceback: types.TracebackType | None = None, ) -> None: self.close() class HTTP2ConnectionByteStream: def __init__(self, connection: HTTP2Connection, request: Request, stream_id: int) -> None: self._connection = connection self._request = request self._stream_id = stream_id self._closed = False def __iter__(self) -> Generator[bytes]: kwargs = {"request": self._request, "stream_id": self._stream_id} try: with Trace("receive_response_body", logger, self._request, kwargs): with safe_iterate( self._connection._receive_response_body(request=self._request, stream_id=self._stream_id) ) as iterator: for chunk in iterator: yield chunk except BaseException as exc: # If we get an exception while streaming the response, # we want to close the response (and possibly the connection) # before raising that exception. with ShieldCancellation(): self.close() raise exc def close(self) -> None: if not self._closed: self._closed = True kwargs = {"stream_id": self._stream_id} with Trace("response_closed", logger, self._request, kwargs): self._connection._response_closed(stream_id=self._stream_id) pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_sync/http_proxy.py000066400000000000000000000345531526547463400255560ustar00rootroot00000000000000from __future__ import annotations import base64 import logging import ssl import typing from .._backends.base import SOCKET_OPTION, NetworkBackend from .._exceptions import ProxyError from .._models import ( URL, Origin, Request, Response, enforce_bytes, enforce_headers, enforce_url, ) from .._ssl import default_ssl_context from .._synchronization import Lock from .._trace import Trace from .connection import HTTPConnection from .connection_pool import ConnectionPool from .http11 import HTTP11Connection from .interfaces import ConnectionInterface ByteOrStr = bytes | str HeadersAsSequence = typing.Sequence[tuple[ByteOrStr, ByteOrStr]] HeadersAsMapping = typing.Mapping[ByteOrStr, ByteOrStr] logger = logging.getLogger("httpcore2.proxy") def merge_headers( default_headers: typing.Sequence[tuple[bytes, bytes]] | None = None, override_headers: typing.Sequence[tuple[bytes, bytes]] | None = None, ) -> list[tuple[bytes, bytes]]: """ Append default_headers and override_headers, de-duplicating if a key exists in both cases. """ default_headers = [] if default_headers is None else list(default_headers) override_headers = [] if override_headers is None else list(override_headers) has_override = set(key.lower() for key, _value in override_headers) default_headers = [(key, value) for key, value in default_headers if key.lower() not in has_override] return default_headers + override_headers class HTTPProxy(ConnectionPool): # pragma: no cover """ A connection pool that sends requests via an HTTP proxy. """ def __init__( self, proxy_url: URL | bytes | str, proxy_auth: tuple[bytes | str, bytes | str] | None = None, proxy_headers: HeadersAsMapping | HeadersAsSequence | None = None, ssl_context: ssl.SSLContext | None = None, proxy_ssl_context: ssl.SSLContext | None = None, max_connections: int | None = 10, max_keepalive_connections: int | None = None, keepalive_expiry: float | None = None, http1: bool = True, http2: bool = False, retries: int = 0, local_address: str | None = None, uds: str | None = None, network_backend: NetworkBackend | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> None: """ A connection pool for making HTTP requests. Parameters: proxy_url: The URL to use when connecting to the proxy server. For example `"http://127.0.0.1:8080/"`. proxy_auth: Any proxy authentication as a two-tuple of (username, password). May be either bytes or ascii-only str. proxy_headers: Any HTTP headers to use for the proxy requests. For example `{"Proxy-Authorization": "Basic :"}`. ssl_context: An SSL context to use for verifying connections. If not specified, the default `httpcore2.default_ssl_context()` will be used. proxy_ssl_context: The same as `ssl_context`, but for a proxy server rather than a remote origin. max_connections: The maximum number of concurrent HTTP connections that the pool should allow. Any attempt to send a request on a pool that would exceed this amount will block until a connection is available. max_keepalive_connections: The maximum number of idle HTTP connections that will be maintained in the pool. keepalive_expiry: The duration in seconds that an idle HTTP connection may be maintained for before being expired from the pool. http1: A boolean indicating if HTTP/1.1 requests should be supported by the connection pool. Defaults to True. http2: A boolean indicating if HTTP/2 requests should be supported by the connection pool. Defaults to False. retries: The maximum number of retries when trying to establish a connection. local_address: Local address to connect from. Can also be used to connect using a particular address family. Using `local_address="0.0.0.0"` will connect using an `AF_INET` address (IPv4), while using `local_address="::"` will connect using an `AF_INET6` address (IPv6). uds: Path to a Unix Domain Socket to use instead of TCP sockets. network_backend: A backend instance to use for handling network I/O. """ super().__init__( ssl_context=ssl_context, max_connections=max_connections, max_keepalive_connections=max_keepalive_connections, keepalive_expiry=keepalive_expiry, http1=http1, http2=http2, network_backend=network_backend, retries=retries, local_address=local_address, uds=uds, socket_options=socket_options, ) self._proxy_url = enforce_url(proxy_url, name="proxy_url") if self._proxy_url.scheme == b"http" and proxy_ssl_context is not None: # pragma: no cover raise RuntimeError("The `proxy_ssl_context` argument is not allowed for the http scheme") self._ssl_context = ssl_context self._proxy_ssl_context = proxy_ssl_context self._proxy_headers = enforce_headers(proxy_headers, name="proxy_headers") if proxy_auth is not None: username = enforce_bytes(proxy_auth[0], name="proxy_auth") password = enforce_bytes(proxy_auth[1], name="proxy_auth") userpass = username + b":" + password authorization = b"Basic " + base64.b64encode(userpass) self._proxy_headers = [(b"Proxy-Authorization", authorization)] + self._proxy_headers def create_connection(self, origin: Origin) -> ConnectionInterface: if origin.scheme == b"http": return ForwardHTTPConnection( proxy_origin=self._proxy_url.origin, proxy_headers=self._proxy_headers, remote_origin=origin, keepalive_expiry=self._keepalive_expiry, network_backend=self._network_backend, proxy_ssl_context=self._proxy_ssl_context, ) return TunnelHTTPConnection( proxy_origin=self._proxy_url.origin, proxy_headers=self._proxy_headers, remote_origin=origin, ssl_context=self._ssl_context, proxy_ssl_context=self._proxy_ssl_context, keepalive_expiry=self._keepalive_expiry, http1=self._http1, http2=self._http2, network_backend=self._network_backend, ) class ForwardHTTPConnection(ConnectionInterface): def __init__( self, proxy_origin: Origin, remote_origin: Origin, proxy_headers: HeadersAsMapping | HeadersAsSequence | None = None, keepalive_expiry: float | None = None, network_backend: NetworkBackend | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, proxy_ssl_context: ssl.SSLContext | None = None, ) -> None: self._connection = HTTPConnection( origin=proxy_origin, keepalive_expiry=keepalive_expiry, network_backend=network_backend, socket_options=socket_options, ssl_context=proxy_ssl_context, ) self._proxy_origin = proxy_origin self._proxy_headers = enforce_headers(proxy_headers, name="proxy_headers") self._remote_origin = remote_origin def handle_request(self, request: Request) -> Response: headers = merge_headers(self._proxy_headers, request.headers) url = URL( scheme=self._proxy_origin.scheme, host=self._proxy_origin.host, port=self._proxy_origin.port, target=bytes(request.url) if request.url.target.startswith(b"/") else request.url.target, ) proxy_request = Request( method=request.method, url=url, headers=headers, content=request.stream, extensions={ key: value for key, value in request.extensions.items() if key not in ("sni_hostname", "target") }, ) return self._connection.handle_request(proxy_request) def can_handle_request(self, origin: Origin) -> bool: return origin == self._remote_origin def close(self) -> None: self._connection.close() def info(self) -> str: return self._connection.info() def is_connected(self) -> bool: return self._connection.is_connected() def is_available(self) -> bool: return self._connection.is_available() def has_expired(self) -> bool: return self._connection.has_expired() def is_idle(self) -> bool: return self._connection.is_idle() def is_closed(self) -> bool: return self._connection.is_closed() def __repr__(self) -> str: return f"<{self.__class__.__name__} [{self.info()}]>" class TunnelHTTPConnection(ConnectionInterface): def __init__( self, proxy_origin: Origin, remote_origin: Origin, ssl_context: ssl.SSLContext | None = None, proxy_ssl_context: ssl.SSLContext | None = None, proxy_headers: typing.Sequence[tuple[bytes, bytes]] | None = None, keepalive_expiry: float | None = None, http1: bool = True, http2: bool = False, network_backend: NetworkBackend | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> None: self._connection: ConnectionInterface = HTTPConnection( origin=proxy_origin, keepalive_expiry=keepalive_expiry, network_backend=network_backend, socket_options=socket_options, ssl_context=proxy_ssl_context, ) self._proxy_origin = proxy_origin self._remote_origin = remote_origin self._ssl_context = ssl_context self._proxy_ssl_context = proxy_ssl_context self._proxy_headers = enforce_headers(proxy_headers, name="proxy_headers") self._keepalive_expiry = keepalive_expiry self._http1 = http1 self._http2 = http2 self._connect_lock = Lock() self._connected = False def handle_request(self, request: Request) -> Response: timeouts = request.extensions.get("timeout", {}) timeout = timeouts.get("connect", None) with self._connect_lock: if not self._connected: target = b"%b:%d" % (self._remote_origin.host, self._remote_origin.port) connect_url = URL( scheme=self._proxy_origin.scheme, host=self._proxy_origin.host, port=self._proxy_origin.port, target=target, ) connect_headers = merge_headers([(b"Host", target), (b"Accept", b"*/*")], self._proxy_headers) connect_request = Request( method=b"CONNECT", url=connect_url, headers=connect_headers, extensions={ key: value for key, value in request.extensions.items() if key not in ("sni_hostname", "target") }, ) connect_response = self._connection.handle_request(connect_request) if connect_response.status < 200 or connect_response.status > 299: reason_bytes = connect_response.extensions.get("reason_phrase", b"") reason_str = reason_bytes.decode("ascii", errors="ignore") msg = f"{connect_response.status} {reason_str}" self._connection.close() raise ProxyError(msg) stream = connect_response.extensions["network_stream"] # Upgrade the stream to SSL ssl_context = default_ssl_context() if self._ssl_context is None else self._ssl_context alpn_protocols = (["h2", "http/1.1"] if self._http1 else ["h2"]) if self._http2 else ["http/1.1"] ssl_context.set_alpn_protocols(alpn_protocols) server_hostname = request.extensions.get("sni_hostname") or self._remote_origin.host.decode("ascii") kwargs = { "ssl_context": ssl_context, "server_hostname": server_hostname, "timeout": timeout, } with Trace("start_tls", logger, request, kwargs) as trace: stream = stream.start_tls(**kwargs) trace.return_value = stream # Determine if we should be using HTTP/1.1 or HTTP/2 ssl_object = stream.get_extra_info("ssl_object") http2_negotiated = ssl_object is not None and ssl_object.selected_alpn_protocol() == "h2" # Create the HTTP/1.1 or HTTP/2 connection if http2_negotiated or (self._http2 and not self._http1): from .http2 import HTTP2Connection self._connection = HTTP2Connection( origin=self._remote_origin, stream=stream, keepalive_expiry=self._keepalive_expiry, ) else: self._connection = HTTP11Connection( origin=self._remote_origin, stream=stream, keepalive_expiry=self._keepalive_expiry, ) self._connected = True return self._connection.handle_request(request) def can_handle_request(self, origin: Origin) -> bool: return origin == self._remote_origin def close(self) -> None: self._connection.close() def info(self) -> str: return self._connection.info() def is_connected(self) -> bool: return self._connection.is_connected() def is_available(self) -> bool: return self._connection.is_available() def has_expired(self) -> bool: return self._connection.has_expired() def is_idle(self) -> bool: return self._connection.is_idle() def is_closed(self) -> bool: return self._connection.is_closed() def __repr__(self) -> str: return f"<{self.__class__.__name__} [{self.info()}]>" pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_sync/interfaces.py000066400000000000000000000121771526547463400254570ustar00rootroot00000000000000from __future__ import annotations import contextlib import typing from collections.abc import Generator from .._models import ( URL, Extensions, HeaderTypes, Origin, Request, Response, enforce_bytes, enforce_headers, enforce_url, include_request_headers, ) class RequestInterface: def request( self, method: bytes | str, url: URL | bytes | str, *, headers: HeaderTypes = None, content: bytes | typing.Iterator[bytes] | None = None, extensions: Extensions | None = None, ) -> Response: # Strict type checking on our parameters. method = enforce_bytes(method, name="method") url = enforce_url(url, name="url") headers = enforce_headers(headers, name="headers") # Include Host header, and optionally Content-Length or Transfer-Encoding. headers = include_request_headers(headers, url=url, content=content) request = Request( method=method, url=url, headers=headers, content=content, extensions=extensions, ) response = self.handle_request(request) try: response.read() finally: response.close() return response @contextlib.contextmanager def stream( self, method: bytes | str, url: URL | bytes | str, *, headers: HeaderTypes = None, content: bytes | typing.Iterator[bytes] | None = None, extensions: Extensions | None = None, ) -> Generator[Response]: # Strict type checking on our parameters. method = enforce_bytes(method, name="method") url = enforce_url(url, name="url") headers = enforce_headers(headers, name="headers") # Include Host header, and optionally Content-Length or Transfer-Encoding. headers = include_request_headers(headers, url=url, content=content) request = Request( method=method, url=url, headers=headers, content=content, extensions=extensions, ) response = self.handle_request(request) try: yield response finally: response.close() def handle_request(self, request: Request) -> Response: raise NotImplementedError() # pragma: no cover class ConnectionInterface(RequestInterface): def close(self) -> None: raise NotImplementedError() # pragma: no cover def info(self) -> str: raise NotImplementedError() # pragma: no cover def can_handle_request(self, origin: Origin) -> bool: raise NotImplementedError() # pragma: no cover def is_connected(self) -> bool: """ Return `True` if the connection is open (the underlying socket has been established). A connection in the NEW state (just created but not yet connected) returns `False`. Note: for some implementations `is_connected() != not is_closed()`. The default implementation returns `not self.is_closed()`, which is correct for connections that are never in the NEW (pre-TCP) state. """ return not self.is_closed() # pragma: no cover def is_available(self) -> bool: """ Return `True` if the connection is currently able to accept an outgoing request. An HTTP/1.1 connection will only be available if it is currently idle. An HTTP/2 connection will be available so long as the stream ID space is not yet exhausted, and the connection is not in an error state. While the connection is being established we may not yet know if it is going to result in an HTTP/1.1 or HTTP/2 connection. The connection should be treated as being available, but might ultimately raise `NewConnectionRequired` required exceptions if multiple requests are attempted over a connection that ends up being established as HTTP/1.1. """ raise NotImplementedError() # pragma: no cover def has_expired(self) -> bool: """ Return `True` if the connection is in a state where it should be closed. This either means that the connection is idle and it has passed the expiry time on its keep-alive, or that server has sent an EOF. """ raise NotImplementedError() # pragma: no cover def is_idle(self) -> bool: """ Return `True` if the connection is currently idle. """ raise NotImplementedError() # pragma: no cover def can_multiplex(self) -> bool: """ Return `True` if the connection can serve multiple requests concurrently, such as an established HTTP/2 connection. The default covers HTTP/1.1-style implementations, which serve a single request at a time. """ return False def is_closed(self) -> bool: """ Return `True` if the connection has been closed. Used when a response is closed to determine if the connection may be returned to the connection pool or not. """ raise NotImplementedError() # pragma: no cover pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_sync/socks_proxy.py000066400000000000000000000326301526547463400257130ustar00rootroot00000000000000from __future__ import annotations import logging import ssl import socksio from .._backends.sync import SyncBackend from .._backends.base import NetworkBackend, NetworkStream from .._exceptions import ConnectionNotAvailable, ProxyError from .._models import URL, Origin, Request, Response, enforce_bytes, enforce_url from .._ssl import default_ssl_context from .._synchronization import Lock from .._trace import Trace from .connection_pool import ConnectionPool from .http11 import HTTP11Connection from .interfaces import ConnectionInterface logger = logging.getLogger("httpcore2.socks") AUTH_METHODS = { b"\x00": "NO AUTHENTICATION REQUIRED", b"\x01": "GSSAPI", b"\x02": "USERNAME/PASSWORD", b"\xff": "NO ACCEPTABLE METHODS", } REPLY_CODES = { b"\x00": "Succeeded", b"\x01": "General SOCKS server failure", b"\x02": "Connection not allowed by ruleset", b"\x03": "Network unreachable", b"\x04": "Host unreachable", b"\x05": "Connection refused", b"\x06": "TTL expired", b"\x07": "Command not supported", b"\x08": "Address type not supported", } def _init_socks5_connection( stream: NetworkStream, *, host: bytes, port: int, auth: tuple[bytes, bytes] | None = None, timeouts: dict[str, float | None] | None = None, ) -> None: timeouts = timeouts or {} write_timeout = timeouts.get("write", None) read_timeout = timeouts.get("read", None) conn = socksio.socks5.SOCKS5Connection() # Auth method request auth_method = ( socksio.socks5.SOCKS5AuthMethod.NO_AUTH_REQUIRED if auth is None else socksio.socks5.SOCKS5AuthMethod.USERNAME_PASSWORD ) conn.send(socksio.socks5.SOCKS5AuthMethodsRequest([auth_method])) outgoing_bytes = conn.data_to_send() stream.write(outgoing_bytes, timeout=write_timeout) # Auth method response incoming_bytes = stream.read(max_bytes=4096, timeout=read_timeout) response = conn.receive_data(incoming_bytes) assert isinstance(response, socksio.socks5.SOCKS5AuthReply) if response.method != auth_method: requested = AUTH_METHODS.get(auth_method, "UNKNOWN") responded = AUTH_METHODS.get(response.method, "UNKNOWN") raise ProxyError(f"Requested {requested} from proxy server, but got {responded}.") if response.method == socksio.socks5.SOCKS5AuthMethod.USERNAME_PASSWORD: # Username/password request assert auth is not None username, password = auth conn.send(socksio.socks5.SOCKS5UsernamePasswordRequest(username, password)) outgoing_bytes = conn.data_to_send() stream.write(outgoing_bytes, timeout=write_timeout) # Username/password response incoming_bytes = stream.read(max_bytes=4096, timeout=read_timeout) response = conn.receive_data(incoming_bytes) assert isinstance(response, socksio.socks5.SOCKS5UsernamePasswordReply) if not response.success: raise ProxyError("Invalid username/password") # Connect request conn.send(socksio.socks5.SOCKS5CommandRequest.from_address(socksio.socks5.SOCKS5Command.CONNECT, (host, port))) outgoing_bytes = conn.data_to_send() stream.write(outgoing_bytes, timeout=write_timeout) # Connect response incoming_bytes = stream.read(max_bytes=4096, timeout=read_timeout) response = conn.receive_data(incoming_bytes) assert isinstance(response, socksio.socks5.SOCKS5Reply) if response.reply_code != socksio.socks5.SOCKS5ReplyCode.SUCCEEDED: reply_code = REPLY_CODES.get(response.reply_code, "UNKOWN") raise ProxyError(f"Proxy Server could not connect: {reply_code}.") class SOCKSProxy(ConnectionPool): # pragma: no cover """ A connection pool that sends requests via an HTTP proxy. """ def __init__( self, proxy_url: URL | bytes | str, proxy_auth: tuple[bytes | str, bytes | str] | None = None, ssl_context: ssl.SSLContext | None = None, max_connections: int | None = 10, max_keepalive_connections: int | None = None, keepalive_expiry: float | None = None, http1: bool = True, http2: bool = False, retries: int = 0, network_backend: NetworkBackend | None = None, ) -> None: """ A connection pool for making HTTP requests. Parameters: proxy_url: The URL to use when connecting to the proxy server. For example `"http://127.0.0.1:8080/"`. ssl_context: An SSL context to use for verifying connections. If not specified, the default `httpcore2.default_ssl_context()` will be used. max_connections: The maximum number of concurrent HTTP connections that the pool should allow. Any attempt to send a request on a pool that would exceed this amount will block until a connection is available. max_keepalive_connections: The maximum number of idle HTTP connections that will be maintained in the pool. keepalive_expiry: The duration in seconds that an idle HTTP connection may be maintained for before being expired from the pool. http1: A boolean indicating if HTTP/1.1 requests should be supported by the connection pool. Defaults to True. http2: A boolean indicating if HTTP/2 requests should be supported by the connection pool. Defaults to False. retries: The maximum number of retries when trying to establish a connection. local_address: Local address to connect from. Can also be used to connect using a particular address family. Using `local_address="0.0.0.0"` will connect using an `AF_INET` address (IPv4), while using `local_address="::"` will connect using an `AF_INET6` address (IPv6). uds: Path to a Unix Domain Socket to use instead of TCP sockets. network_backend: A backend instance to use for handling network I/O. """ super().__init__( ssl_context=ssl_context, max_connections=max_connections, max_keepalive_connections=max_keepalive_connections, keepalive_expiry=keepalive_expiry, http1=http1, http2=http2, network_backend=network_backend, retries=retries, ) self._ssl_context = ssl_context self._proxy_url = enforce_url(proxy_url, name="proxy_url") if proxy_auth is not None: username, password = proxy_auth username_bytes = enforce_bytes(username, name="proxy_auth") password_bytes = enforce_bytes(password, name="proxy_auth") self._proxy_auth: tuple[bytes, bytes] | None = ( username_bytes, password_bytes, ) else: self._proxy_auth = None def create_connection(self, origin: Origin) -> ConnectionInterface: return Socks5Connection( proxy_origin=self._proxy_url.origin, remote_origin=origin, proxy_auth=self._proxy_auth, ssl_context=self._ssl_context, keepalive_expiry=self._keepalive_expiry, http1=self._http1, http2=self._http2, network_backend=self._network_backend, ) class Socks5Connection(ConnectionInterface): def __init__( self, proxy_origin: Origin, remote_origin: Origin, proxy_auth: tuple[bytes, bytes] | None = None, ssl_context: ssl.SSLContext | None = None, keepalive_expiry: float | None = None, http1: bool = True, http2: bool = False, network_backend: NetworkBackend | None = None, ) -> None: self._proxy_origin = proxy_origin self._remote_origin = remote_origin self._proxy_auth = proxy_auth self._ssl_context = ssl_context self._keepalive_expiry = keepalive_expiry self._http1 = http1 self._http2 = http2 self._network_backend: NetworkBackend = SyncBackend() if network_backend is None else network_backend self._connect_lock = Lock() self._connection: ConnectionInterface | None = None self._connect_failed = False def handle_request(self, request: Request) -> Response: timeouts = request.extensions.get("timeout", {}) sni_hostname = request.extensions.get("sni_hostname", None) timeout = timeouts.get("connect", None) with self._connect_lock: if self._connection is None: try: # Connect to the proxy kwargs = { "host": self._proxy_origin.host.decode("ascii"), "port": self._proxy_origin.port, "timeout": timeout, } with Trace("connect_tcp", logger, request, kwargs) as trace: stream = self._network_backend.connect_tcp(**kwargs) trace.return_value = stream # Connect to the remote host using socks5 kwargs = { "stream": stream, "host": self._remote_origin.host.decode("ascii"), "port": self._remote_origin.port, "auth": self._proxy_auth, "timeouts": timeouts, } with Trace("setup_socks5_connection", logger, request, kwargs) as trace: _init_socks5_connection(**kwargs) trace.return_value = stream # Upgrade the stream to SSL if self._remote_origin.scheme in (b"https", b"wss"): ssl_context = default_ssl_context() if self._ssl_context is None else self._ssl_context alpn_protocols = ( (["h2", "http/1.1"] if self._http1 else ["h2"]) if self._http2 else ["http/1.1"] ) ssl_context.set_alpn_protocols(alpn_protocols) kwargs = { "ssl_context": ssl_context, "server_hostname": sni_hostname or self._remote_origin.host.decode("ascii"), "timeout": timeout, } with Trace("start_tls", logger, request, kwargs) as trace: stream = stream.start_tls(**kwargs) trace.return_value = stream # Determine if we should be using HTTP/1.1 or HTTP/2 ssl_object = stream.get_extra_info("ssl_object") http2_negotiated = ssl_object is not None and ssl_object.selected_alpn_protocol() == "h2" # Create the HTTP/1.1 or HTTP/2 connection if http2_negotiated or (self._http2 and not self._http1): # pragma: no cover from .http2 import HTTP2Connection self._connection = HTTP2Connection( origin=self._remote_origin, stream=stream, keepalive_expiry=self._keepalive_expiry, ) else: self._connection = HTTP11Connection( origin=self._remote_origin, stream=stream, keepalive_expiry=self._keepalive_expiry, ) except Exception as exc: self._connect_failed = True raise exc elif not self._connection.is_available(): # pragma: no cover raise ConnectionNotAvailable() return self._connection.handle_request(request) def can_handle_request(self, origin: Origin) -> bool: return origin == self._remote_origin def close(self) -> None: if self._connection is not None: self._connection.close() def is_connected(self) -> bool: return self._connection is not None and self._connection.is_connected() def is_available(self) -> bool: if self._connection is None: # pragma: no cover # If HTTP/2 support is enabled, and the resulting connection could # end up as HTTP/2 then we should indicate the connection as being # available to service multiple requests. return ( self._http2 and (self._remote_origin.scheme == b"https" or not self._http1) and not self._connect_failed ) return self._connection.is_available() def has_expired(self) -> bool: if self._connection is None: # pragma: no cover return self._connect_failed return self._connection.has_expired() def is_idle(self) -> bool: if self._connection is None: # pragma: no cover return self._connect_failed return self._connection.is_idle() def is_closed(self) -> bool: if self._connection is None: # pragma: no cover return self._connect_failed return self._connection.is_closed() def info(self) -> str: if self._connection is None: # pragma: no cover return "CONNECTION FAILED" if self._connect_failed else "CONNECTING" return self._connection.info() def __repr__(self) -> str: return f"<{self.__class__.__name__} [{self.info()}]>" pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_synchronization.py000066400000000000000000000240601526547463400256130ustar00rootroot00000000000000from __future__ import annotations import threading import types from ._exceptions import ExceptionMapping, PoolTimeout, map_exceptions # Our async synchronization primitives use either 'anyio' or 'trio' depending # on if they're running under asyncio or trio. try: import trio except (ImportError, NotImplementedError): # pragma: no cover trio = None # type: ignore try: import anyio except ImportError: # pragma: no cover anyio = None # type: ignore try: import sniffio except ImportError: # pragma: no cover sniffio = None # type: ignore def current_async_library() -> str: # Determine if we're running under trio or asyncio. # See https://sniffio.readthedocs.io/en/latest/ if sniffio is None: # pragma: no cover environment = "asyncio" else: environment = sniffio.current_async_library() if environment not in ("asyncio", "trio"): # pragma: no cover raise RuntimeError("Running under an unsupported async environment.") if environment == "asyncio" and anyio is None: # pragma: no cover raise RuntimeError("Running with asyncio requires installation of 'httpcore[asyncio]'.") if environment == "trio" and trio is None: # pragma: no cover raise RuntimeError("Running with trio requires installation of 'httpcore[trio]'.") return environment class AsyncLock: """ This is a standard lock. In the sync case `Lock` provides thread locking. In the async case `AsyncLock` provides async locking. """ def __init__(self) -> None: self._backend = "" def setup(self) -> None: """ Detect if we're running under 'asyncio' or 'trio' and create a lock with the correct implementation. """ self._backend = current_async_library() if self._backend == "trio": self._trio_lock = trio.Lock() elif self._backend == "asyncio": self._anyio_lock = anyio.Lock(fast_acquire=True) async def __aenter__(self) -> AsyncLock: if not self._backend: self.setup() if self._backend == "trio": await self._trio_lock.acquire() elif self._backend == "asyncio": await self._anyio_lock.acquire() return self async def __aexit__( self, exc_type: type[BaseException] | None = None, exc_value: BaseException | None = None, traceback: types.TracebackType | None = None, ) -> None: if self._backend == "trio": self._trio_lock.release() elif self._backend == "asyncio": self._anyio_lock.release() class AsyncThreadLock: """ This is a threading-only lock for no-I/O contexts. In the sync case `ThreadLock` provides thread locking. In the async case `AsyncThreadLock` is a no-op. """ def __enter__(self) -> AsyncThreadLock: return self def __exit__( self, exc_type: type[BaseException] | None = None, exc_value: BaseException | None = None, traceback: types.TracebackType | None = None, ) -> None: pass class AsyncEvent: def __init__(self) -> None: self._backend = "" def setup(self) -> None: """ Detect if we're running under 'asyncio' or 'trio' and create a lock with the correct implementation. """ self._backend = current_async_library() if self._backend == "trio": self._trio_event = trio.Event() elif self._backend == "asyncio": self._anyio_event = anyio.Event() def set(self) -> None: if not self._backend: self.setup() if self._backend == "trio": self._trio_event.set() elif self._backend == "asyncio": self._anyio_event.set() async def wait(self, timeout: float | None = None) -> None: if not self._backend: self.setup() if self._backend == "trio": trio_exc_map: ExceptionMapping = {trio.TooSlowError: PoolTimeout} timeout_or_inf = float("inf") if timeout is None else timeout with map_exceptions(trio_exc_map): with trio.fail_after(timeout_or_inf): await self._trio_event.wait() elif self._backend == "asyncio": anyio_exc_map: ExceptionMapping = {TimeoutError: PoolTimeout} with map_exceptions(anyio_exc_map): with anyio.fail_after(timeout): await self._anyio_event.wait() class AsyncSemaphore: def __init__(self, bound: int) -> None: self._bound = bound self._backend = "" def setup(self) -> None: """ Detect if we're running under 'asyncio' or 'trio' and create a semaphore with the correct implementation. """ self._backend = current_async_library() if self._backend == "trio": self._trio_semaphore = trio.Semaphore(initial_value=self._bound, max_value=self._bound) elif self._backend == "asyncio": self._anyio_semaphore = anyio.Semaphore(initial_value=self._bound, max_value=self._bound, fast_acquire=True) async def acquire(self) -> None: if not self._backend: self.setup() if self._backend == "trio": await self._trio_semaphore.acquire() elif self._backend == "asyncio": await self._anyio_semaphore.acquire() def acquire_if_available(self) -> bool: """ Acquire a permit if one is immediately available, without blocking. Returns True if a permit was acquired. Like `release()`, this requires `setup()` to have run, which any prior `acquire()` call ensures. """ if self._backend == "trio": try: self._trio_semaphore.acquire_nowait() except trio.WouldBlock: return False return True elif self._backend == "asyncio": try: self._anyio_semaphore.acquire_nowait() except anyio.WouldBlock: return False return True return False # pragma: no cover async def release(self) -> None: if self._backend == "trio": self._trio_semaphore.release() elif self._backend == "asyncio": self._anyio_semaphore.release() class AsyncShieldCancellation: # For certain portions of our codebase where we're dealing with # closing connections during exception handling we want to shield # the operation from being cancelled. # # with AsyncShieldCancellation(): # ... # clean-up operations, shielded from cancellation. def __init__(self) -> None: """ Detect if we're running under 'asyncio' or 'trio' and create a shielded scope with the correct implementation. """ self._backend = current_async_library() if self._backend == "trio": self._trio_shield = trio.CancelScope(shield=True) elif self._backend == "asyncio": self._anyio_shield = anyio.CancelScope(shield=True) def __enter__(self) -> AsyncShieldCancellation: if self._backend == "trio": self._trio_shield.__enter__() elif self._backend == "asyncio": self._anyio_shield.__enter__() return self def __exit__( self, exc_type: type[BaseException] | None = None, exc_value: BaseException | None = None, traceback: types.TracebackType | None = None, ) -> None: if self._backend == "trio": self._trio_shield.__exit__(exc_type, exc_value, traceback) elif self._backend == "asyncio": self._anyio_shield.__exit__(exc_type, exc_value, traceback) # Our thread-based synchronization primitives... class Lock: """ This is a standard lock. In the sync case `Lock` provides thread locking. In the async case `AsyncLock` provides async locking. """ def __init__(self) -> None: self._lock = threading.Lock() def __enter__(self) -> Lock: self._lock.acquire() return self def __exit__( self, exc_type: type[BaseException] | None = None, exc_value: BaseException | None = None, traceback: types.TracebackType | None = None, ) -> None: self._lock.release() class ThreadLock: """ This is a threading-only lock for no-I/O contexts. In the sync case `ThreadLock` provides thread locking. In the async case `AsyncThreadLock` is a no-op. """ def __init__(self) -> None: self._lock = threading.RLock() def __enter__(self) -> ThreadLock: self._lock.acquire() return self def __exit__( self, exc_type: type[BaseException] | None = None, exc_value: BaseException | None = None, traceback: types.TracebackType | None = None, ) -> None: self._lock.release() class Event: def __init__(self) -> None: self._event = threading.Event() def set(self) -> None: self._event.set() def wait(self, timeout: float | None = None) -> None: if timeout == float("inf"): # pragma: no cover timeout = None if not self._event.wait(timeout=timeout): raise PoolTimeout() # pragma: no cover class Semaphore: def __init__(self, bound: int) -> None: self._semaphore = threading.Semaphore(value=bound) def acquire(self) -> None: self._semaphore.acquire() def acquire_if_available(self) -> bool: return self._semaphore.acquire(blocking=False) def release(self) -> None: self._semaphore.release() class ShieldCancellation: # Thread-synchronous codebases don't support cancellation semantics. # We have this class because we need to mirror the async and sync # cases within our package, but it's just a no-op. def __enter__(self) -> ShieldCancellation: return self def __exit__( self, exc_type: type[BaseException] | None = None, exc_value: BaseException | None = None, traceback: types.TracebackType | None = None, ) -> None: pass pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_trace.py000066400000000000000000000075301526547463400234530ustar00rootroot00000000000000from __future__ import annotations import inspect import logging import types import typing from ._models import Request class Trace: def __init__( self, name: str, logger: logging.Logger, request: Request | None = None, kwargs: dict[str, typing.Any] | None = None, ) -> None: self.name = name self.logger = logger self.trace_extension = None if request is None else request.extensions.get("trace") self.debug = self.logger.isEnabledFor(logging.DEBUG) self.kwargs = kwargs or {} self.return_value: typing.Any = None self.should_trace = self.debug or self.trace_extension is not None self.prefix = self.logger.name.split(".")[-1] def trace(self, name: str, info: dict[str, typing.Any]) -> None: if self.trace_extension is not None: prefix_and_name = f"{self.prefix}.{name}" ret = self.trace_extension(prefix_and_name, info) if inspect.iscoroutine(ret): # pragma: no cover raise TypeError( "If you are using a synchronous interface, " "the callback of the `trace` extension should " "be a normal function instead of an asynchronous function." ) if self.debug: if not info or "return_value" in info and info["return_value"] is None: message = name else: args = " ".join([f"{key}={value!r}" for key, value in info.items()]) message = f"{name} {args}" self.logger.debug(message) def __enter__(self) -> Trace: if self.should_trace: info = self.kwargs self.trace(f"{self.name}.started", info) return self def __exit__( self, exc_type: type[BaseException] | None = None, exc_value: BaseException | None = None, traceback: types.TracebackType | None = None, ) -> None: if self.should_trace: if exc_value is None: info = {"return_value": self.return_value} self.trace(f"{self.name}.complete", info) else: info = {"exception": exc_value} self.trace(f"{self.name}.failed", info) async def atrace(self, name: str, info: dict[str, typing.Any]) -> None: if self.trace_extension is not None: prefix_and_name = f"{self.prefix}.{name}" coro = self.trace_extension(prefix_and_name, info) if not inspect.iscoroutine(coro): # pragma: no cover raise TypeError( "If you're using an asynchronous interface, " "the callback of the `trace` extension should " "be an asynchronous function rather than a normal function." ) await coro if self.debug: if not info or "return_value" in info and info["return_value"] is None: message = name else: args = " ".join([f"{key}={value!r}" for key, value in info.items()]) message = f"{name} {args}" self.logger.debug(message) async def __aenter__(self) -> Trace: if self.should_trace: info = self.kwargs await self.atrace(f"{self.name}.started", info) return self async def __aexit__( self, exc_type: type[BaseException] | None = None, exc_value: BaseException | None = None, traceback: types.TracebackType | None = None, ) -> None: if self.should_trace: if exc_value is None: info = {"return_value": self.return_value} await self.atrace(f"{self.name}.complete", info) else: info = {"exception": exc_value} await self.atrace(f"{self.name}.failed", info) pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/_utils.py000066400000000000000000000047451526547463400235220ustar00rootroot00000000000000from __future__ import annotations import select import socket import sys import typing from collections.abc import ( AsyncIterable, AsyncIterator, Generator, Iterable, Iterator, ) from contextlib import AbstractAsyncContextManager, aclosing, contextmanager, nullcontext from types import AsyncGeneratorType T = typing.TypeVar("T") def is_socket_readable(sock: socket.socket | None) -> bool: """ Return whether a socket, as identified by its file descriptor, is readable. "A socket is readable" means that the read buffer isn't empty, i.e. that calling .recv() on it would immediately return some data. """ # NOTE: we want check for readability without actually attempting to read, because # we don't want to block forever if it's not readable. # In the case that the socket no longer exists, or cannot return a file # descriptor, we treat it as being readable, as if it the next read operation # on it is ready to return the terminating `b""`. sock_fd = None if sock is None else sock.fileno() if sock_fd is None or sock_fd < 0: # pragma: no cover return True # The implementation below was stolen from: # https://github.com/python-trio/trio/blob/20ee2b1b7376db637435d80e266212a35837ddcc/trio/_socket.py#L471-L478 # See also: https://github.com/encode/httpcore/pull/193#issuecomment-703129316 # Use select.select on Windows, and when poll is unavailable and select.poll # everywhere else. (E.g. When eventlet is in use. See #327) if sys.platform == "win32" or getattr(select, "poll", None) is None: # pragma: no cover rready, _, _ = select.select([sock_fd], [], [], 0) return bool(rready) p = select.poll() p.register(sock_fd, select.POLLIN) return bool(p.poll(0)) def safe_async_iterate( iterable_or_iterator: AsyncIterable[T] | AsyncIterator[T], / ) -> AbstractAsyncContextManager[AsyncIterator[T]]: iterator = ( iterable_or_iterator if isinstance(iterable_or_iterator, AsyncIterator) else iterable_or_iterator.__aiter__() ) if isinstance(iterator, AsyncGeneratorType): return aclosing(iterator) return nullcontext(iterator) @contextmanager def safe_iterate(iterable_or_iterator: Iterable[T] | Iterator[T], /) -> Generator[Iterator[T], None, None]: # This is boilerplate code, only needed to make unasync happy iterator = iterable_or_iterator if isinstance(iterable_or_iterator, Iterator) else iterable_or_iterator.__iter__() yield iterator pydantic-httpx2-6dd59b9/src/httpcore2/httpcore2/py.typed000066400000000000000000000000001526547463400233240ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/src/httpcore2/mkdocs.yml000066400000000000000000000014361526547463400217340ustar00rootroot00000000000000site_name: HTTPCore 2 site_description: A minimal HTTP client for Python. repo_name: pydantic/httpx2 repo_url: https://github.com/pydantic/httpx2/ nav: - Introduction: 'index.md' - Quickstart: 'quickstart.md' - Connection Pools: 'connection-pools.md' - Proxies: 'proxies.md' - HTTP/2: 'http2.md' - Async Support: 'async.md' - Network Backends: 'network-backends.md' - Extensions: 'extensions.md' - Logging: 'logging.md' - Exceptions: 'exceptions.md' theme: name: "material" plugins: - search - mkdocstrings: default_handler: python watch: - httpcore2 handlers: python: members_order: - "source" markdown_extensions: - codehilite: css_class: highlight pydantic-httpx2-6dd59b9/src/httpcore2/pyproject.toml000066400000000000000000000040201526547463400226350ustar00rootroot00000000000000[build-system] requires = [ "hatchling", "hatch-fancy-pypi-readme", "uv-dynamic-versioning>=0.14.1", ] build-backend = "hatchling.build" [tool.hatch.version] source = "uv-dynamic-versioning" [tool.uv-dynamic-versioning] vcs = "git" style = "pep440" bump = true fallback-version = "0.0.0" [project] name = "httpcore2" dynamic = ["readme", "version"] description = "A minimal low-level HTTP client." license = "BSD-3-Clause" requires-python = ">=3.11" authors = [{ name = "Tom Christie", email = "tom@tomchristie.com" }] maintainers = [ { name = "Pydantic Services Inc.", email = "engineering@pydantic.dev" }, ] classifiers = [ "Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Framework :: AnyIO", "Framework :: AsyncIO", "Framework :: Trio", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", "Programming Language :: Python :: 3.15", "Topic :: Internet :: WWW/HTTP", ] dependencies = ["truststore>=0.10", "h11>=0.16"] [project.optional-dependencies] http2 = ["h2>=3,<5"] socks = ["socksio==1.*"] trio = ["trio>=0.34.0,<1.0"] asyncio = ["anyio>=4.5.0,<5.0"] [project.urls] Changelog = "https://github.com/pydantic/httpx2/blob/main/src/httpcore2/CHANGELOG.md" Homepage = "https://github.com/pydantic/httpx2" Source = "https://github.com/pydantic/httpx2/blob/main/src/httpcore2" [tool.hatch.build.targets.sdist] include = ["/httpcore2", "/CHANGELOG.md", "/LICENSE.md", "/README.md", "/tests"] [tool.hatch.metadata.hooks.fancy-pypi-readme] content-type = "text/markdown" [[tool.hatch.metadata.hooks.fancy-pypi-readme.fragments]] path = "README.md" [[tool.hatch.metadata.hooks.fancy-pypi-readme.fragments]] path = "CHANGELOG.md" pydantic-httpx2-6dd59b9/src/httpx2/000077500000000000000000000000001526547463400172445ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/src/httpx2/CHANGELOG.md000066400000000000000000001732511526547463400210660ustar00rootroot00000000000000# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## 2.15.1 (October 19th, 2026) ### Fixed * Configure the default SSL context once on Linux, instead of on every handshake. With OpenSSL older than 3.4, CPU usage grew over the lifetime of a reused client. ([#1253](https://github.com/pydantic/httpx2/pull/1253)) ## 2.15.0 (October 19th, 2026) ### Removed * Drop support for Python 3.10. ([#1274](https://github.com/pydantic/httpx2/pull/1274)) ## 2.14.0 (October 18th, 2026) ### Added * Match IP CIDR ranges, like `192.168.0.0/16` and `[fe80::]/10`, in `NO_PROXY` and `mounts`. Requests to any address in the range now bypass the proxy; previously only the network address itself did. ([#1165](https://github.com/pydantic/httpx2/pull/1165)) * Accept bracketed IPv6 addresses, like `[::1]` and `[::1]:8080`, in `NO_PROXY`. ([#1267](https://github.com/pydantic/httpx2/pull/1267)) ### Changed * Raise `InvalidURL` for a `mounts` key with an IP host followed by anything other than a valid CIDR prefix, like `all://10.0.0.0/33`. ([#1165](https://github.com/pydantic/httpx2/pull/1165)) ### Fixed * Ignore `NO_PROXY` entries that cannot be parsed, instead of raising `InvalidURL` when the client is created. ([#1267](https://github.com/pydantic/httpx2/pull/1267)) * Import `httpx2` on FIPS-enforced Python builds without `hashlib.md5`. `DigestAuth` raises `ProtocolError` when the server asks for an unavailable algorithm. ([#1130](https://github.com/pydantic/httpx2/pull/1130)) * Handle reads after an ASGI WebSocket app shuts down, instead of leaking `anyio` exceptions. ([#1233](https://github.com/pydantic/httpx2/pull/1233)) * Stop the sync WebSocket session from hanging on exit when its event queue is full. ([#1123](https://github.com/pydantic/httpx2/pull/1123)) ## 2.13.1 (September 23rd, 2026) ### Fixed * Calculate `Content-Length` from the remaining bytes when a file is passed as `content=`, respecting its current position. ([#1214](https://github.com/pydantic/httpx2/pull/1214)) * Stop the sync WebSocket keepalive thread cleanly when a ping races with connection shutdown. ([#1228](https://github.com/pydantic/httpx2/pull/1228)) ## 2.13.0 (September 14th, 2026) ### Changed * Require `brotlicffi` 1.2.0.2 or later for the `brotli` extra on non-CPython implementations. ([#1179](https://github.com/pydantic/httpx2/pull/1179)) ### Fixed * Make the `--no-verify` CLI flag disable TLS certificate verification and add an explicit `--verify` counterpart. ([#1140](https://github.com/pydantic/httpx2/pull/1140), [#1186](https://github.com/pydantic/httpx2/pull/1186)) * Avoid nested async generator finalization errors when streamed responses are abandoned early. ([#1204](https://github.com/pydantic/httpx2/pull/1204)) ## 2.12.0 (August 18th, 2026) ### Changed * Use `backports.zstd` for Zstandard decoding on Python 3.13 and earlier. ([#1146](https://github.com/pydantic/httpx2/pull/1146)) ### Fixed * Bound peak memory while streaming compressed responses and close response streams when decoding fails. ([#1126](https://github.com/pydantic/httpx2/pull/1126)) ## 2.11.0 (August 18th, 2026) ### Added * Add the public `Origin` value object and `URL.origin` property for normalized, hashable origin comparisons. ([#1134](https://github.com/pydantic/httpx2/pull/1134)) ### Changed * Require Brotli 1.2.0 or later for the `brotli` extra. ([#1141](https://github.com/pydantic/httpx2/pull/1141)) ### Fixed * Restore deprecated status code aliases. ([#1135](https://github.com/pydantic/httpx2/pull/1135)) * Extract HTTP/2 release notes from changelog headings correctly. ([#1136](https://github.com/pydantic/httpx2/pull/1136)) * Respect explicit `Transfer-Encoding` headers and expose buffered request body lengths to WSGI applications. ([#1137](https://github.com/pydantic/httpx2/pull/1137)) * Validate multipart part header names and values before serialization. ([#1142](https://github.com/pydantic/httpx2/pull/1142)) ## 2.10.0 (August 9th, 2026) ### Added * Add support for running on WebAssembly / Emscripten via Pyodide, using a JavaScript `fetch`-based transport defined in `httpx2-jsfetch`. ([#1119](https://github.com/pydantic/httpx2/pull/1119)) * Add `max_event_size` to cap SSE event buffering. ([#1071](https://github.com/pydantic/httpx2/pull/1071)) * Add RFC 9110 status code constants. ([#1069](https://github.com/pydantic/httpx2/pull/1069)) * Add support for Python 3.15. ([#1090](https://github.com/pydantic/httpx2/pull/1090)) ### Changed * Improve SSE chunk buffering performance. ([#1117](https://github.com/pydantic/httpx2/pull/1117)) * Skip cookie extraction for responses without `Set-Cookie` headers. ([#1107](https://github.com/pydantic/httpx2/pull/1107)) * Return `str | None` instead of `Any` from `Headers.get`. ([#1121](https://github.com/pydantic/httpx2/pull/1121)) ### Fixed * Enforce the WebSocket max message size across fragmented messages. ([#1085](https://github.com/pydantic/httpx2/pull/1085)) * Ignore unsolicited and duplicate WebSocket Pong frames. ([#1122](https://github.com/pydantic/httpx2/pull/1122)) ## 2.9.1 (July 24th, 2026) ### Fixed * Alias `httpcore` imports to `httpcore2` in `alias_httpx()`. ([#1082](https://github.com/pydantic/httpx2/pull/1082)) ## 2.9.0 (July 23rd, 2026) ### Added * Add `alias_httpx()`, letting applications make `import httpx` resolve to `httpx2` process-wide. ([#1077](https://github.com/pydantic/httpx2/pull/1077)) ## 2.8.0 (July 23rd, 2026) No changes since `2.7.0`. Version bumped to stay in lockstep with `httpcore2`. ## 2.7.0 (July 14th, 2026) ### Changed * Update the vendored `httpx-ws` to upstream v0.9.0. ([#1067](https://github.com/pydantic/httpx2/pull/1067)) ## 2.6.0 (July 14th, 2026) ### Added * Add native WebSocket support by vendoring `httpx-ws`, installable with `httpx2[ws]`. ([#1042](https://github.com/pydantic/httpx2/pull/1042)) * Add support for the `QUERY` HTTP method via `httpx2.query()` and `client.query()`. ([#1055](https://github.com/pydantic/httpx2/pull/1055)) ### Changed * Allow `click` 8.4+ in the `cli` extra, dropping the upper bound. ([#1040](https://github.com/pydantic/httpx2/pull/1040)) ## 2.5.0 (June 25th, 2026) ### Added * Add native server-sent events support via `client.sse()`. ([#1046](https://github.com/pydantic/httpx2/pull/1046)) * Support `|` and `|=` operators for `Headers`. ([#1047](https://github.com/pydantic/httpx2/pull/1047)) ### Fixed * Allow IPv6 CIDR notation in `no_proxy`. ([#967](https://github.com/pydantic/httpx2/pull/967)) ## 2.4.0 (June 11th, 2026) ### Added * Add `HTTPXDeprecationWarning`, a `UserWarning` subclass shown by default so deprecations are visible without enabling warnings. ([#1029](https://github.com/pydantic/httpx2/pull/1029)) ### Changed * Limit the number of chained `Content-Encoding` decoders to 5. ([#1027](https://github.com/pydantic/httpx2/pull/1027)) * Allow version 15 of `rich` in the `cli` extra. ([#1015](https://github.com/pydantic/httpx2/pull/1015)) ### Fixed * Parse an empty `Digest` auth realm without crashing. ([#1023](https://github.com/pydantic/httpx2/pull/1023)) * Decode IDNA labels in non-leading host positions. ([#1018](https://github.com/pydantic/httpx2/pull/1018)) ## 2.3.0 (June 1st, 2026) ### Changed * Use `truststore` instead of `certifi` for default SSL verification, loading the operating system's trust store. ([#209](https://github.com/pydantic/httpx2/pull/209)) ### Fixed * Raise when `verify` is a string path and a client-side `cert` is also provided to `create_ssl_context`. ([#990](https://github.com/pydantic/httpx2/pull/990)) * Allow a `default_encoding` callable to return `None`. ([#951](https://github.com/pydantic/httpx2/pull/951)) * Make the `zstd` import optional on Python 3.14. ([#1000](https://github.com/pydantic/httpx2/pull/1000)) * Store elapsed time on the stream wrapper to avoid reference cycles. ([#948](https://github.com/pydantic/httpx2/pull/948)) ## 2.2.0 (May 16th, 2026) ### Fixed * Handle multi-frame zstd streams split across chunks. ([#946](https://github.com/pydantic/httpx2/pull/946)) ### Changed * Lazily import the `_main` CLI module to speed up `import httpx2`. ([#947](https://github.com/pydantic/httpx2/pull/947)) ## 2.1.0 (May 15th, 2026) ### Removed * Drop support for Python 3.9. ([#208](https://github.com/pydantic/httpx2/pull/208)) ### Added * Add support for Python 3.14. ([#208](https://github.com/pydantic/httpx2/pull/208)) * Use stdlib `compression.zstd` for Zstd decompression on Python 3.14+; fall back to the `zstandard` package on older versions. ([#932](https://github.com/pydantic/httpx2/pull/932)) * Bundle `LICENSE.md` in the sdist. ([#938](https://github.com/pydantic/httpx2/pull/938)) ## 2.0.0 Official first release of `httpx2`. No changes since `2.0.0b1`. ## 2.0.0b1 First release of `httpx2`, a fork of [`httpx`](https://github.com/encode/httpx) maintained by Pydantic. Forked from `httpx 0.28.1` (commit [`b5addb6`](https://github.com/encode/httpx/commit/b5addb6)). ### Breaking changes * **Renamed package**: `httpx` -> `httpx2`. `import httpx` becomes `import httpx2`. The CLI is now `httpx2`, the User-Agent header is `python-httpx2/`, and the logger is `httpx2`. No other public API changed. * **Renamed transitive dependency**: `httpcore` -> `httpcore2`, vendored into the same repository as a uv workspace member. Code that imports `httpcore` directly should switch to `httpcore2`. `httpx2` always depends on a specific `httpcore2` version, pinned exactly. ### Added * Expose `FunctionAuth` from the public API. (Inherited from upstream PR [encode/httpx#3699](https://github.com/encode/httpx/pull/3699).) ### Fixed * Eliminate `PytestUnraisableExceptionWarning` from async generator finalization during stream teardown under trio. ([#137](https://github.com/pydantic/httpx2/pull/137), backporting [encode/httpcore#1019](https://github.com/encode/httpcore/pull/1019) by @agronholm.) --- Historical entries below are from upstream `encode/httpx`. ## 0.28.1 (6th December, 2024) * Fix SSL case where `verify=False` together with client side certificates. ## 0.28.0 (28th November, 2024) Be aware that the default *JSON request bodies now use a more compact representation*. This is generally considered a preferred style, tho may require updates to test suites. The 0.28 release includes a limited set of deprecations... **Deprecations**: We are working towards a simplified SSL configuration API. *For users of the standard `verify=True` or `verify=False` cases, or `verify=` case this should require no changes. The following cases have been deprecated...* * The `verify` argument as a string argument is now deprecated and will raise warnings. * The `cert` argument is now deprecated and will raise warnings. Our revised [SSL documentation](docs/advanced/ssl.md) covers how to implement the same behaviour with a more constrained API. **The following changes are also included**: * The deprecated `proxies` argument has now been removed. * The deprecated `app` argument has now been removed. * JSON request bodies use a compact representation. (#3363) * Review URL percent escape sets, based on WHATWG spec. (#3371, #3373) * Ensure `certifi` and `httpcore` are only imported if required. (#3377) * Treat `socks5h` as a valid proxy scheme. (#3178) * Cleanup `Request()` method signature in line with `client.request()` and `httpx.request()`. (#3378) * Bugfix: When passing `params={}`, always strictly update rather than merge with an existing querystring. (#3364) ## 0.27.2 (27th August, 2024) ### Fixed * Reintroduced supposedly-private `URLTypes` shortcut. (#2673) ## 0.27.1 (27th August, 2024) ### Added * Support for `zstd` content decoding using the python `zstandard` package is added. Installable using `httpx[zstd]`. (#3139) ### Fixed * Improved error messaging for `InvalidURL` exceptions. (#3250) * Fix `app` type signature in `ASGITransport`. (#3109) ## 0.27.0 (21st February, 2024) ### Deprecated * The `app=...` shortcut has been deprecated. Use the explicit style of `transport=httpx.WSGITransport()` or `transport=httpx.ASGITransport()` instead. ### Fixed * Respect the `http1` argument while configuring proxy transports. (#3023) * Fix RFC 2069 mode digest authentication. (#3045) ## 0.26.0 (20th December, 2023) ### Added * The `proxy` argument was added. You should use the `proxy` argument instead of the deprecated `proxies`, or use `mounts=` for more complex configurations. (#2879) ### Deprecated * The `proxies` argument is now deprecated. It will still continue to work, but it will be removed in the future. (#2879) ### Fixed * Fix cases of double escaping of URL path components. Allow / as a safe character in the query portion. (#2990) * Handle `NO_PROXY` envvar cases when a fully qualified URL is supplied as the value. (#2741) * Allow URLs where username or password contains unescaped '@'. (#2986) * Ensure ASGI `raw_path` does not include URL query component. (#2999) * Ensure `Response.iter_text()` cannot yield empty strings. (#2998) ## 0.25.2 (24th November, 2023) ### Added * Add missing type hints to few `__init__()` methods. (#2938) ## 0.25.1 (3rd November, 2023) ### Added * Add support for Python 3.12. (#2854) * Add support for httpcore 1.0 (#2885) ### Fixed * Raise `ValueError` on `Response.encoding` being set after `Response.text` has been accessed. (#2852) ## 0.25.0 (11th September, 2023) ### Removed * Drop support for Python 3.7. (#2813) ### Added * Support HTTPS proxies. (#2845) * Change the type of `Extensions` from `Mapping[Str, Any]` to `MutableMapping[Str, Any]`. (#2803) * Add `socket_options` argument to `httpx.HTTPTransport` and `httpx.AsyncHTTPTransport` classes. (#2716) * The `Response.raise_for_status()` method now returns the response instance. For example: `data = httpx.get('...').raise_for_status().json()`. (#2776) ### Fixed * Return `500` error response instead of exceptions when `raise_app_exceptions=False` is set on `ASGITransport`. (#2669) * Ensure all `WSGITransport` environs have a `SERVER_PROTOCOL`. (#2708) * Always encode forward slashes as `%2F` in query parameters (#2723) * Use Mozilla documentation instead of `httpstatuses.com` for HTTP error reference (#2768) ## 0.24.1 (17th May, 2023) ### Added * Provide additional context in some `InvalidURL` exceptions. (#2675) ### Fixed * Fix optional percent-encoding behaviour. (#2671) * More robust checking for opening upload files in binary mode. (#2630) * Properly support IP addresses in `NO_PROXY` environment variable. (#2659) * Set default file for `NetRCAuth()` to `None` to use the stdlib default. (#2667) * Set logging request lines to INFO level for async requests, in line with sync requests. (#2656) * Fix which gen-delims need to be escaped for path/query/fragment components in URL. (#2701) ## 0.24.0 (6th April, 2023) ### Changed * The logging behaviour has been changed to be more in-line with other standard Python logging usages. We no longer have a custom `TRACE` log level, and we no longer use the `HTTPX_LOG_LEVEL` environment variable to auto-configure logging. We now have a significant amount of `DEBUG` logging available at the network level. Full documentation is available at https://www.python-httpx.org/logging/ (#2547, encode/httpcore#648) * The `Response.iter_lines()` method now matches the stdlib behaviour and does not include the newline characters. It also resolves a performance issue. (#2423) * Query parameter encoding switches from using + for spaces and %2F for forward slash, to instead using %20 for spaces and treating forward slash as a safe, unescaped character. This differs from `requests`, but is in line with browser behavior in Chrome, Safari, and Firefox. Both options are RFC valid. (#2543) * NetRC authentication is no longer automatically handled, but is instead supported by an explicit `httpx.NetRCAuth()` authentication class. See the documentation at https://www.python-httpx.org/advanced/authentication/#netrc-authentication (#2525) ### Removed * The `rfc3986` dependency has been removed. (#2252) ## 0.23.3 (4th January, 2023) ### Fixed * Version 0.23.2 accidentally included stricter type checking on query parameters. This shouldn've have been included in a minor version bump, and is now reverted. (#2523, #2539) ## 0.23.2 (2nd January, 2023) ### Added * Support digest auth nonce counting to avoid multiple auth requests. (#2463) ### Fixed * Multipart file uploads where the file length cannot be determine now use chunked transfer encoding, rather than loading the entire file into memory in order to determine the `Content-Length`. (#2382) * Raise `TypeError` if content is passed a dict-instance. (#2495) * Partially revert the API breaking change in 0.23.1, which removed `RawURL`. We continue to expose a `url.raw` property which is now a plain named-tuple. This API is still expected to be deprecated, but we will do so with a major version bump. (#2481) ## 0.23.1 (18th November, 2022) **Note**: The 0.23.1 release should have used a proper version bump, rather than a minor point release. There are API surface area changes that may affect some users. See the "Removed" section of these release notes for details. ### Added * Support for Python 3.11. (#2420) * Allow setting an explicit multipart boundary in `Content-Type` header. (#2278) * Allow `tuple` or `list` for multipart values, not just `list`. (#2355) * Allow `str` content for multipart upload files. (#2400) * Support connection upgrades. See https://www.encode.io/httpcore/extensions/#upgrade-requests ### Fixed * Don't drop empty query parameters. (#2354) ### Removed * Upload files *must* always be opened in binary mode. (#2400) * Drop `.read`/`.aread` from `SyncByteStream`/`AsyncByteStream`. (#2407) * Drop `RawURL`. (#2241) ## 0.23.0 (23rd May, 2022) ### Changed * Drop support for Python 3.6. (#2097) * Use `utf-8` as the default character set, instead of falling back to `charset-normalizer` for auto-detection. To enable automatic character set detection, see [the documentation](https://www.python-httpx.org/advanced/text-encodings/#using-auto-detection). (#2165) ### Fixed * Fix `URL.copy_with` for some oddly formed URL cases. (#2185) * Digest authentication should use case-insensitive comparison for determining which algorithm is being used. (#2204) * Fix console markup escaping in command line client. (#1866) * When files are used in multipart upload, ensure we always seek to the start of the file. (#2065) * Ensure that `iter_bytes` never yields zero-length chunks. (#2068) * Preserve `Authorization` header for redirects that are to the same origin, but are an `http`-to-`https` upgrade. (#2074) * When responses have binary output, don't print the output to the console in the command line client. Use output like `<16086 bytes of binary data>` instead. (#2076) * Fix display of `--proxies` argument in the command line client help. (#2125) * Close responses when task cancellations occur during stream reading. (#2156) * Fix type error on accessing `.request` on `HTTPError` exceptions. (#2158) ## 0.22.0 (26th January, 2022) ### Added * Support for [the SOCKS5 proxy protocol](https://www.python-httpx.org/advanced/proxies/#socks) via [the `socksio` package](https://github.com/sethmlarson/socksio). (#2034) * Support for custom headers in multipart/form-data requests (#1936) ### Fixed * Don't perform unreliable close/warning on `__del__` with unclosed clients. (#2026) * Fix `Headers.update(...)` to correctly handle repeated headers (#2038) ## 0.21.3 (6th January, 2022) ### Fixed * Fix streaming uploads using `SyncByteStream` or `AsyncByteStream`. Regression in 0.21.2. (#2016) ## 0.21.2 (5th January, 2022) ### Fixed * HTTP/2 support for tunnelled proxy cases. (#2009) * Improved the speed of large file uploads. (#1948) ## 0.21.1 (16th November, 2021) ### Fixed * The `response.url` property is now correctly annotated as `URL`, instead of `Optional[URL]`. (#1940) ## 0.21.0 (15th November, 2021) The 0.21.0 release integrates against a newly redesigned `httpcore` backend. Both packages ought to automatically update to the required versions, but if you are seeing any issues, you should ensure that you have `httpx==0.21.*` and `httpcore==0.14.*` installed. ### Added * The command-line client will now display connection information when `-v/--verbose` is used. * The command-line client will now display server certificate information when `-v/--verbose` is used. * The command-line client is now able to properly detect if the outgoing request should be formatted as HTTP/1.1 or HTTP/2, based on the result of the HTTP/2 negotiation. ### Removed * Curio support is no longer currently included. Please get in touch if you require this, so that we can assess priorities. ## 0.20.0 (13th October, 2021) The 0.20.0 release adds an integrated command-line client, and also includes some design changes. The most notable of these is that redirect responses are no longer automatically followed, unless specifically requested. This design decision prioritises a more explicit approach to redirects, in order to avoid code that unintentionally issues multiple requests as a result of misconfigured URLs. For example, previously a client configured to send requests to `http://api.github.com/` would end up sending every API request twice, as each request would be redirected to `https://api.github.com/`. If you do want auto-redirect behaviour, you can enable this either by configuring the client instance with `Client(follow_redirects=True)`, or on a per-request basis, with `.get(..., follow_redirects=True)`. This change is a classic trade-off between convenience and precision, with no "right" answer. See [discussion #1785](https://github.com/encode/httpx/discussions/1785) for more context. The other major design change is an update to the Transport API, which is the low-level interface against which requests are sent. Previously this interface used only primitive datastructures, like so... ```python (status_code, headers, stream, extensions) = transport.handle_request(method, url, headers, stream, extensions) try ... finally: stream.close() ``` Now the interface is much simpler... ```python response = transport.handle_request(request) try ... finally: response.close() ``` ### Changed * The `allow_redirects` flag is now `follow_redirects` and defaults to `False`. * The `raise_for_status()` method will now raise an exception for any responses except those with 2xx status codes. Previously only 4xx and 5xx status codes would result in an exception. * The low-level transport API changes to the much simpler `response = transport.handle_request(request)`. * The `client.send()` method no longer accepts a `timeout=...` argument, but the `client.build_request()` does. This required by the signature change of the Transport API. The request timeout configuration is now stored on the request instance, as `request.extensions['timeout']`. ### Added * Added the `httpx` command-line client. * Response instances now include `.is_informational`, `.is_success`, `.is_redirect`, `.is_client_error`, and `.is_server_error` properties for checking 1xx, 2xx, 3xx, 4xx, and 5xx response types. Note that the behaviour of `.is_redirect` is slightly different in that it now returns True for all 3xx responses, in order to allow for a consistent set of properties onto the different HTTP status code types. The `response.has_redirect_location` location may be used to determine responses with properly formed URL redirects. ### Fixed * `response.iter_bytes()` no longer raises a ValueError when called on a response with no content. (Pull #1827) * The `'wsgi.error'` configuration now defaults to `sys.stderr`, and is corrected to be a `TextIO` interface, not a `BytesIO` interface. Additionally, the WSGITransport now accepts a `wsgi_error` configuration. (Pull #1828) * Follow the WSGI spec by properly closing the iterable returned by the application. (Pull #1830) ## 0.19.0 (19th August, 2021) ### Added * Add support for `Client(allow_redirects=)`. (Pull #1790) * Add automatic character set detection, when no `charset` is included in the response `Content-Type` header. (Pull #1791) ### Changed * Event hooks are now also called for any additional redirect or auth requests/responses. (Pull #1806) * Strictly enforce that upload files must be opened in binary mode. (Pull #1736) * Strictly enforce that client instances can only be opened and closed once, and cannot be re-opened. (Pull #1800) * Drop `mode` argument from `httpx.Proxy(..., mode=...)`. (Pull #1795) ## 0.18.2 (17th June, 2021) ### Added * Support for Python 3.10. (Pull #1687) * Expose `httpx.USE_CLIENT_DEFAULT`, used as the default to `auth` and `timeout` parameters in request methods. (Pull #1634) * Support [HTTP/2 "prior knowledge"](https://python-hyper.org/projects/hyper-h2/en/v2.3.1/negotiating-http2.html#prior-knowledge), using `httpx.Client(http1=False, http2=True)`. (Pull #1624) ### Fixed * Clean up some cases where warnings were being issued. (Pull #1687) * Prefer Content-Length over Transfer-Encoding: chunked for content= cases. (Pull #1619) ## 0.18.1 (29th April, 2021) ### Changed * Update brotli support to use the `brotlicffi` package (Pull #1605) * Ensure that `Request(..., stream=...)` does not auto-generate any headers on the request instance. (Pull #1607) ### Fixed * Pass through `timeout=...` in top-level httpx.stream() function. (Pull #1613) * Map httpcore transport close exceptions to httpx exceptions. (Pull #1606) ## 0.18.0 (27th April, 2021) The 0.18.x release series formalises our low-level Transport API, introducing the base classes `httpx.BaseTransport` and `httpx.AsyncBaseTransport`. See the "[Custom transports](https://www.python-httpx.org/advanced/transports/#custom-transports)" documentation and the [`httpx.BaseTransport.handle_request()`](https://github.com/encode/httpx/blob/397aad98fdc8b7580a5fc3e88f1578b4302c6382/httpx/_transports/base.py#L77-L147) docstring for more complete details on implementing custom transports. Pull request #1522 includes a checklist of differences from the previous `httpcore` transport API, for developers implementing custom transports. The following API changes have been issuing deprecation warnings since 0.17.0 onwards, and are now fully deprecated... * You should now use httpx.codes consistently instead of httpx.StatusCodes. * Use limits=... instead of pool_limits=.... * Use proxies={"http://": ...} instead of proxies={"http": ...} for scheme-specific mounting. ### Changed * Transport instances now inherit from `httpx.BaseTransport` or `httpx.AsyncBaseTransport`, and should implement either the `handle_request` method or `handle_async_request` method. (Pull #1522, #1550) * The `response.ext` property and `Response(ext=...)` argument are now named `extensions`. (Pull #1522) * The recommendation to not use `data=` in favour of `content=` has now been escalated to a deprecation warning. (Pull #1573) * Drop `Response(on_close=...)` from API, since it was a bit of leaking implementation detail. (Pull #1572) * When using a client instance, cookies should always be set on the client, rather than on a per-request basis. We prefer enforcing a stricter API here because it provides clearer expectations around cookie persistence, particularly when redirects occur. (Pull #1574) * The runtime exception `httpx.ResponseClosed` is now named `httpx.StreamClosed`. (#1584) * The `httpx.QueryParams` model now presents an immutable interface. There is a discussion on [the design and motivation here](https://github.com/encode/httpx/discussions/1599). Use `client.params = client.params.merge(...)` instead of `client.params.update(...)`. The basic query manipulation methods are `query.set(...)`, `query.add(...)`, and `query.remove()`. (#1600) ### Added * The `Request` and `Response` classes can now be serialized using pickle. (#1579) * Handle `data={"key": [None|int|float|bool]}` cases. (Pull #1539) * Support `httpx.URL(**kwargs)`, for example `httpx.URL(scheme="https", host="www.example.com", path="/')`, or `httpx.URL("https://www.example.com/", username="tom@gmail.com", password="123 456")`. (Pull #1601) * Support `url.copy_with(params=...)`. (Pull #1601) * Add `url.params` parameter, returning an immutable `QueryParams` instance. (Pull #1601) * Support query manipulation methods on the URL class. These are `url.copy_set_param()`, `url.copy_add_param()`, `url.copy_remove_param()`, `url.copy_merge_params()`. (Pull #1601) * The `httpx.URL` class now performs port normalization, so `:80` ports are stripped from `http` URLs and `:443` ports are stripped from `https` URLs. (Pull #1603) * The `URL.host` property returns unicode strings for internationalized domain names. The `URL.raw_host` property returns byte strings with IDNA escaping applied. (Pull #1590) ### Fixed * Fix Content-Length for cases of `files=...` where unicode string is used as the file content. (Pull #1537) * Fix some cases of merging relative URLs against `Client(base_url=...)`. (Pull #1532) * The `request.content` attribute is now always available except for streaming content, which requires an explicit `.read()`. (Pull #1583) ## 0.17.1 (March 15th, 2021) ### Fixed * Type annotation on `CertTypes` allows `keyfile` and `password` to be optional. (Pull #1503) * Fix httpcore pinned version. (Pull #1495) ## 0.17.0 (February 28th, 2021) ### Added * Add `httpx.MockTransport()`, allowing to mock out a transport using pre-determined responses. (Pull #1401, Pull #1449) * Add `httpx.HTTPTransport()` and `httpx.AsyncHTTPTransport()` default transports. (Pull #1399) * Add mount API support, using `httpx.Client(mounts=...)`. (Pull #1362) * Add `chunk_size` parameter to `iter_raw()`, `iter_bytes()`, `iter_text()`. (Pull #1277) * Add `keepalive_expiry` parameter to `httpx.Limits()` configuration. (Pull #1398) * Add repr to `httpx.Cookies` to display available cookies. (Pull #1411) * Add support for `params=` (previously only `params=` was supported). (Pull #1426) ### Fixed * Add missing `raw_path` to ASGI scope. (Pull #1357) * Tweak `create_ssl_context` defaults to use `trust_env=True`. (Pull #1447) * Properly URL-escape WSGI `PATH_INFO`. (Pull #1391) * Properly set default ports in WSGI transport. (Pull #1469) * Properly encode slashes when using `base_url`. (Pull #1407) * Properly map exceptions in `request.aclose()`. (Pull #1465) ## 0.16.1 (October 8th, 2020) ### Fixed * Support literal IPv6 addresses in URLs. (Pull #1349) * Force lowercase headers in ASGI scope dictionaries. (Pull #1351) ## 0.16.0 (October 6th, 2020) ### Changed * Preserve HTTP header casing. (Pull #1338, encode/httpcore#216, python-hyper/h11#104) * Drop `response.next()` and `response.anext()` methods in favour of `response.next_request` attribute. (Pull #1339) * Closed clients now raise a runtime error if attempting to send a request. (Pull #1346) ### Added * Add Python 3.9 to officially supported versions. * Type annotate `__enter__`/`__exit__`/`__aenter__`/`__aexit__` in a way that supports subclasses of `Client` and `AsyncClient`. (Pull #1336) ## 0.15.5 (October 1st, 2020) ### Added * Add `response.next_request` (Pull #1334) ## 0.15.4 (September 25th, 2020) ### Added * Support direct comparisons between `Headers` and dicts or lists of two-tuples. Eg. `assert response.headers == {"Content-Length": 24}` (Pull #1326) ### Fixed * Fix automatic `.read()` when `Response` instances are created with `content=` (Pull #1324) ## 0.15.3 (September 24th, 2020) ### Fixed * Fixed connection leak in async client due to improper closing of response streams. (Pull #1316) ## 0.15.2 (September 23nd, 2020) ### Fixed * Fixed `response.elapsed` property. (Pull #1313) * Fixed client authentication interaction with `.stream()`. (Pull #1312) ## 0.15.1 (September 23nd, 2020) ### Fixed * ASGITransport now properly applies URL decoding to the `path` component, as-per the ASGI spec. (Pull #1307) ## 0.15.0 (September 22nd, 2020) ### Added * Added support for curio. (Pull https://github.com/encode/httpcore/pull/168) * Added support for event hooks. (Pull #1246) * Added support for authentication flows which require either sync or async I/O. (Pull #1217) * Added support for monitoring download progress with `response.num_bytes_downloaded`. (Pull #1268) * Added `Request(content=...)` for byte content, instead of overloading `Request(data=...)` (Pull #1266) * Added support for all URL components as parameter names when using `url.copy_with(...)`. (Pull #1285) * Neater split between automatically populated headers on `Request` instances, vs default `client.headers`. (Pull #1248) * Unclosed `AsyncClient` instances will now raise warnings if garbage collected. (Pull #1197) * Support `Response(content=..., text=..., html=..., json=...)` for creating usable response instances in code. (Pull #1265, #1297) * Support instantiating requests from the low-level transport API. (Pull #1293) * Raise errors on invalid URL types. (Pull #1259) ### Changed * Cleaned up expected behaviour for URL escaping. `url.path` is now URL escaped. (Pull #1285) * Cleaned up expected behaviour for bytes vs str in URL components. `url.userinfo` and `url.query` are not URL escaped, and so return bytes. (Pull #1285) * Drop `url.authority` property in favour of `url.netloc`, since "authority" was semantically incorrect. (Pull #1285) * Drop `url.full_path` property in favour of `url.raw_path`, for better consistency with other parts of the API. (Pull #1285) * No longer use the `chardet` library for auto-detecting charsets, instead defaulting to a simpler approach when no charset is specified. (#1269) ### Fixed * Swapped ordering of redirects and authentication flow. (Pull #1267) * `.netrc` lookups should use host, not host+port. (Pull #1298) ### Removed * The `URLLib3Transport` class no longer exists. We've published it instead as an example of [a custom transport class](https://gist.github.com/florimondmanca/d56764d78d748eb9f73165da388e546e). (Pull #1182) * Drop `request.timer` attribute, which was being used internally to set `response.elapsed`. (Pull #1249) * Drop `response.decoder` attribute, which was being used internally. (Pull #1276) * `Request.prepare()` is now a private method. (Pull #1284) * The `Headers.getlist()` method had previously been deprecated in favour of `Headers.get_list()`. It is now fully removed. * The `QueryParams.getlist()` method had previously been deprecated in favour of `QueryParams.get_list()`. It is now fully removed. * The `URL.is_ssl` property had previously been deprecated in favour of `URL.scheme == "https"`. It is now fully removed. * The `httpx.PoolLimits` class had previously been deprecated in favour of `httpx.Limits`. It is now fully removed. * The `max_keepalive` setting had previously been deprecated in favour of the more explicit `max_keepalive_connections`. It is now fully removed. * The verbose `httpx.Timeout(5.0, connect_timeout=60.0)` style had previously been deprecated in favour of `httpx.Timeout(5.0, connect=60.0)`. It is now fully removed. * Support for instantiating a timeout config missing some defaults, such as `httpx.Timeout(connect=60.0)`, had previously been deprecated in favour of enforcing a more explicit style, such as `httpx.Timeout(5.0, connect=60.0)`. This is now strictly enforced. ## 0.14.3 (September 2nd, 2020) ### Added * `http.Response()` may now be instantiated without a `request=...` parameter. Useful for some unit testing cases. (Pull #1238) * Add `103 Early Hints` and `425 Too Early` status codes. (Pull #1244) ### Fixed * `DigestAuth` now handles responses that include multiple 'WWW-Authenticate' headers. (Pull #1240) * Call into transport `__enter__`/`__exit__` or `__aenter__`/`__aexit__` when client is used in a context manager style. (Pull #1218) ## 0.14.2 (August 24th, 2020) ### Added * Support `client.get(..., auth=None)` to bypass the default authentication on a clients. (Pull #1115) * Support `client.auth = ...` property setter. (Pull #1185) * Support `httpx.get(..., proxies=...)` on top-level request functions. (Pull #1198) * Display instances with nicer import styles. (Eg. ) (Pull #1155) * Support `cookies=[(key, value)]` list-of-two-tuples style usage. (Pull #1211) ### Fixed * Ensure that automatically included headers on a request may be modified. (Pull #1205) * Allow explicit `Content-Length` header on streaming requests. (Pull #1170) * Handle URL quoted usernames and passwords properly. (Pull #1159) * Use more consistent default for `HEAD` requests, setting `allow_redirects=True`. (Pull #1183) * If a transport error occurs while streaming the response, raise an `httpx` exception, not the underlying `httpcore` exception. (Pull #1190) * Include the underlying `httpcore` traceback, when transport exceptions occur. (Pull #1199) ## 0.14.1 (August 11th, 2020) ### Added * The `httpx.URL(...)` class now raises `httpx.InvalidURL` on invalid URLs, rather than exposing the underlying `rfc3986` exception. If a redirect response includes an invalid 'Location' header, then a `RemoteProtocolError` exception is raised, which will be associated with the request that caused it. (Pull #1163) ### Fixed * Handling multiple `Set-Cookie` headers became broken in the 0.14.0 release, and is now resolved. (Pull #1156) ## 0.14.0 (August 7th, 2020) The 0.14 release includes a range of improvements to the public API, intended on preparing for our upcoming 1.0 release. * Our HTTP/2 support is now fully optional. **You now need to use `pip install httpx[http2]` if you want to include the HTTP/2 dependencies.** * Our HSTS support has now been removed. Rewriting URLs from `http` to `https` if the host is on the HSTS list can be beneficial in avoiding roundtrips to incorrectly formed URLs, but on balance we've decided to remove this feature, on the principle of least surprise. Most programmatic clients do not include HSTS support, and for now we're opting to remove our support for it. * Our exception hierarchy has been overhauled. Most users will want to stick with their existing `httpx.HTTPError` usage, but we've got a clearer overall structure now. See https://www.python-httpx.org/exceptions/ for more details. When upgrading you should be aware of the following public API changes. Note that deprecated usages will currently continue to function, but will issue warnings. * You should now use `httpx.codes` consistently instead of `httpx.StatusCodes`. * Usage of `httpx.Timeout()` should now always include an explicit default. Eg. `httpx.Timeout(None, pool=5.0)`. * When using `httpx.Timeout()`, we now have more concisely named keyword arguments. Eg. `read=5.0`, instead of `read_timeout=5.0`. * Use `httpx.Limits()` instead of `httpx.PoolLimits()`, and `limits=...` instead of `pool_limits=...`. * The `httpx.Limits(max_keepalive=...)` argument is now deprecated in favour of a more explicit `httpx.Limits(max_keepalive_connections=...)`. * Keys used with `Client(proxies={...})` should now be in the style of `{"http://": ...}`, rather than `{"http": ...}`. * The multidict methods `Headers.getlist()` and `QueryParams.getlist()` are deprecated in favour of more consistent `.get_list()` variants. * The `URL.is_ssl` property is deprecated in favour of `URL.scheme == "https"`. * The `URL.join(relative_url=...)` method is now `URL.join(url=...)`. This change does not support warnings for the deprecated usage style. One notable aspect of the 0.14.0 release is that it tightens up the public API for `httpx`, by ensuring that several internal attributes and methods have now become strictly private. The following previously had nominally public names on the client, but were all undocumented and intended solely for internal usage. They are all now replaced with underscored names, and should not be relied on or accessed. These changes should not affect users who have been working from the `httpx` documentation. * `.merge_url()`, `.merge_headers()`, `.merge_cookies()`, `.merge_queryparams()` * `.build_auth()`, `.build_redirect_request()` * `.redirect_method()`, `.redirect_url()`, `.redirect_headers()`, `.redirect_stream()` * `.send_handling_redirects()`, `.send_handling_auth()`, `.send_single_request()` * `.init_transport()`, `.init_proxy_transport()` * `.proxies`, `.transport`, `.netrc`, `.get_proxy_map()` See pull requests #997, #1065, #1071. Some areas of API which were already on the deprecation path, and were raising warnings or errors in 0.13.x have now been escalated to being fully removed. * Drop `ASGIDispatch`, `WSGIDispatch`, which have been replaced by `ASGITransport`, `WSGITransport`. * Drop `dispatch=...`` on client, which has been replaced by `transport=...`` * Drop `soft_limit`, `hard_limit`, which have been replaced by `max_keepalive` and `max_connections`. * Drop `Response.stream` and` `Response.raw`, which have been replaced by ``.aiter_bytes` and `.aiter_raw`. * Drop `proxies=` in favor of `proxies=httpx.Proxy(...)`. See pull requests #1057, #1058. ### Added * Added dedicated exception class `httpx.HTTPStatusError` for `.raise_for_status()` exceptions. (Pull #1072) * Added `httpx.create_ssl_context()` helper function. (Pull #996) * Support for proxy exclusions like `proxies={"https://www.example.com": None}`. (Pull #1099) * Support `QueryParams(None)` and `client.params = None`. (Pull #1060) ### Changed * Use `httpx.codes` consistently in favour of `httpx.StatusCodes` which is placed into deprecation. (Pull #1088) * Usage of `httpx.Timeout()` should now always include an explicit default. Eg. `httpx.Timeout(None, pool=5.0)`. (Pull #1085) * Switch to more concise `httpx.Timeout()` keyword arguments. Eg. `read=5.0`, instead of `read_timeout=5.0`. (Pull #1111) * Use `httpx.Limits()` instead of `httpx.PoolLimits()`, and `limits=...` instead of `pool_limits=...`. (Pull #1113) * Keys used with `Client(proxies={...})` should now be in the style of `{"http://": ...}`, rather than `{"http": ...}`. (Pull #1127) * The multidict methods `Headers.getlist` and `QueryParams.getlist` are deprecated in favour of more consistent `.get_list()` variants. (Pull #1089) * `URL.port` becomes `Optional[int]`. Now only returns a port if one is explicitly included in the URL string. (Pull #1080) * The `URL(..., allow_relative=[bool])` parameter no longer exists. All URL instances may be relative. (Pull #1073) * Drop unnecessary `url.full_path = ...` property setter. (Pull #1069) * The `URL.join(relative_url=...)` method is now `URL.join(url=...)`. (Pull #1129) * The `URL.is_ssl` property is deprecated in favour of `URL.scheme == "https"`. (Pull #1128) ### Fixed * Add missing `Response.next()` method. (Pull #1055) * Ensure all exception classes are exposed as public API. (Pull #1045) * Support multiple items with an identical field name in multipart encodings. (Pull #777) * Skip HSTS preloading on single-label domains. (Pull #1074) * Fixes for `Response.iter_lines()`. (Pull #1033, #1075) * Ignore permission errors when accessing `.netrc` files. (Pull #1104) * Allow bare hostnames in `HTTP_PROXY` etc... environment variables. (Pull #1120) * Settings `app=...` or `transport=...` bypasses any environment based proxy defaults. (Pull #1122) * Fix handling of `.base_url` when a path component is included in the base URL. (Pull #1130) --- ## 0.13.3 (May 29th, 2020) ### Fixed * Include missing keepalive expiry configuration. (Pull #1005) * Improved error message when URL redirect has a custom scheme. (Pull #1002) ## 0.13.2 (May 27th, 2020) ### Fixed * Include explicit "Content-Length: 0" on POST, PUT, PATCH if no request body is used. (Pull #995) * Add `http2` option to `httpx.Client`. (Pull #982) * Tighten up API typing in places. (Pull #992, #999) ## 0.13.1 (May 22nd, 2020) ### Fixed * Fix pool options deprecation warning. (Pull #980) * Include `httpx.URLLib3ProxyTransport` in top-level API. (Pull #979) ## 0.13.0 (May 22nd, 2020) This release switches to `httpcore` for all the internal networking, which means: * We're using the same codebase for both our sync and async clients. * HTTP/2 support is now available with the sync client. * We no longer have a `urllib3` dependency for our sync client, although there is still an *optional* `URLLib3Transport` class. It also means we've had to remove our UDS support, since maintaining that would have meant having to push back our work towards a 1.0 release, which isn't a trade-off we wanted to make. We also now have [a public "Transport API"](https://www.python-httpx.org/advanced/transports/#custom-transports), which you can use to implement custom transport implementations against. This formalises and replaces our previously private "Dispatch API". ### Changed * Use `httpcore` for underlying HTTP transport. Drop `urllib3` requirement. (Pull #804, #967) * Rename pool limit options from `soft_limit`/`hard_limit` to `max_keepalive`/`max_connections`. (Pull #968) * The previous private "Dispatch API" has now been promoted to a public "Transport API". When customizing the transport use `transport=...`. The `ASGIDispatch` and `WSGIDispatch` class naming is deprecated in favour of `ASGITransport` and `WSGITransport`. (Pull #963) ### Added * Added `URLLib3Transport` class for optional `urllib3` transport support. (Pull #804, #963) * Streaming multipart uploads. (Pull #857) * Logging via HTTPCORE_LOG_LEVEL and HTTPX_LOG_LEVEL environment variables and TRACE level logging. (Pull encode/httpcore#79) ### Fixed * Performance improvement in brotli decoder. (Pull #906) * Proper warning level of deprecation notice in `Response.stream` and `Response.raw`. (Pull #908) * Fix support for generator based WSGI apps. (Pull #887) * Reuse of connections on HTTP/2 in close concurrency situations. (Pull encode/httpcore#81) * Honor HTTP/2 max concurrent streams settings (Pull encode/httpcore#89, encode/httpcore#90) * Fix bytes support in multipart uploads. (Pull #974) * Improve typing support for `files=...`. (Pull #976) ### Removed * Dropped support for `Client(uds=...)` (Pull #804) ## 0.13.0.dev2 (May 12th, 2020) The 0.13.0.dev2 is a *pre-release* version. To install it, use `pip install httpx --pre`. ### Added * Logging via HTTPCORE_LOG_LEVEL and HTTPX_LOG_LEVEL environment variables and TRACE level logging. (HTTPCore Pull #79) ### Fixed * Reuse of connections on HTTP/2 in close concurrency situations. (HTTPCore Pull #81) * When using an `app=` observe neater disconnect behaviour instead of sending empty body messages. (Pull #919) ## 0.13.0.dev1 (May 6th, 2020) The 0.13.0.dev1 is a *pre-release* version. To install it, use `pip install httpx --pre`. ### Fixed * Passing `http2` flag to proxy dispatchers. (Pull #934) * Use [`httpcore` v0.8.3](https://github.com/encode/httpcore/releases/tag/0.8.3) which addresses problems in handling of headers when using proxies. ## 0.13.0.dev0 (April 30th, 2020) The 0.13.0.dev0 is a *pre-release* version. To install it, use `pip install httpx --pre`. This release switches to `httpcore` for all the internal networking, which means: * We're using the same codebase for both our sync and async clients. * HTTP/2 support is now available with the sync client. * We no longer have a `urllib3` dependency for our sync client, although there is still an *optional* `URLLib3Dispatcher` class. It also means we've had to remove our UDS support, since maintaining that would have meant having to push back our work towards a 1.0 release, which isn't a trade-off we wanted to make. ### Changed * Use `httpcore` for underlying HTTP transport. Drop `urllib3` requirement. (Pull #804) ### Added * Added `URLLib3Dispatcher` class for optional `urllib3` transport support. (Pull #804) * Streaming multipart uploads. (Pull #857) ### Fixed * Performance improvement in brotli decoder. (Pull #906) * Proper warning level of deprecation notice in `Response.stream` and `Response.raw`. (Pull #908) * Fix support for generator based WSGI apps. (Pull #887) ### Removed * Dropped support for `Client(uds=...)` (Pull #804) --- ## 0.12.1 (March 19th, 2020) ### Fixed * Resolved packaging issue, where additional files were being included. ## 0.12.0 (March 9th, 2020) The 0.12 release tightens up the API expectations for `httpx` by switching to private module names to enforce better clarity around public API. All imports of `httpx` should import from the top-level package only, such as `from httpx import Request`, rather than importing from privately namespaced modules such as `from httpx._models import Request`. ### Added * Support making response body available to auth classes with `.requires_response_body`. (Pull #803) * Export `NetworkError` exception. (Pull #814) * Add support for `NO_PROXY` environment variable. (Pull #835) ### Changed * Switched to private module names. (Pull #785) * Drop redirect looping detection and the `RedirectLoop` exception, instead using `TooManyRedirects`. (Pull #819) * Drop `backend=...` parameter on `AsyncClient`, in favour of always autodetecting `trio`/`asyncio`. (Pull #791) ### Fixed * Support basic auth credentials in proxy URLs. (Pull #780) * Fix `httpx.Proxy(url, mode="FORWARD_ONLY")` configuration. (Pull #788) * Fallback to setting headers as UTF-8 if no encoding is specified. (Pull #820) * Close proxy dispatches classes on client close. (Pull #826) * Support custom `cert` parameters even if `verify=False`. (Pull #796) * Don't support invalid dict-of-dicts form data in `data=...`. (Pull #811) --- ## 0.11.1 (January 17th, 2020) ### Fixed * Fixed usage of `proxies=...` on `Client()`. (Pull #763) * Support both `zlib` and `deflate` style encodings on `Content-Encoding: deflate`. (Pull #758) * Fix for streaming a redirect response body with `allow_redirects=False`. (Pull #766) * Handle redirect with malformed Location headers missing host. (Pull #774) ## 0.11.0 (January 9th, 2020) The 0.11 release reintroduces our sync support, so that `httpx` now supports both a standard thread-concurrency API, and an async API. Existing async `httpx` users that are upgrading to 0.11 should ensure that: * Async codebases should always use a client instance to make requests, instead of the top-level API. * The async client is named as `httpx.AsyncClient()`, instead of `httpx.Client()`. * When instantiating proxy configurations use the `httpx.Proxy()` class, instead of the previous `httpx.HTTPProxy()`. This new configuration class works for configuring both sync and async clients. We believe the API is now pretty much stable, and are aiming for a 1.0 release sometime on or before April 2020. ### Changed - Top level API such as `httpx.get(url, ...)`, `httpx.post(url, ...)`, `httpx.request(method, url, ...)` becomes synchronous. - Added `httpx.Client()` for synchronous clients, with `httpx.AsyncClient` being used for async clients. - Switched to `proxies=httpx.Proxy(...)` for proxy configuration. - Network connection errors are wrapped in `httpx.NetworkError`, rather than exposing lower-level exception types directly. ### Removed - The `request.url.origin` property and `httpx.Origin` class are no longer available. - The per-request `cert`, `verify`, and `trust_env` arguments are escalated from raising errors if used, to no longer being available. These arguments should be used on a per-client instance instead, or in the top-level API. - The `stream` argument has escalated from raising an error when used, to no longer being available. Use the `client.stream(...)` or `httpx.stream()` streaming API instead. ### Fixed - Redirect loop detection matches against `(method, url)` rather than `url`. (Pull #734) --- ## 0.10.1 (December 31st, 2019) ### Fixed - Fix issue with concurrent connection acquisition. (Pull #700) - Fix write error on closing HTTP/2 connections. (Pull #699) ## 0.10.0 (December 29th, 2019) The 0.10.0 release makes some changes that will allow us to support both sync and async interfaces. In particular with streaming responses the `response.read()` method becomes `response.aread()`, and the `response.close()` method becomes `response.aclose()`. If following redirects explicitly the `response.next()` method becomes `response.anext()`. ### Fixed - End HTTP/2 streams immediately on no-body requests, rather than sending an empty body message. (Pull #682) - Improve typing for `Response.request`: switch from `Optional[Request]` to `Request`. (Pull #666) - `Response.elapsed` now reflects the entire download time. (Pull #687, #692) ### Changed - Added `AsyncClient` as a synonym for `Client`. (Pull #680) - Switch to `response.aread()` for conditionally reading streaming responses. (Pull #674) - Switch to `response.aclose()` and `client.aclose()` for explicit closing. (Pull #674, #675) - Switch to `response.anext()` for resolving the next redirect response. (Pull #676) ### Removed - When using a client instance, the per-request usage of `verify`, `cert`, and `trust_env` have now escalated from raising a warning to raising an error. You should set these arguments on the client instead. (Pull #617) - Removed the undocumented `request.read()`, since end users should not require it. --- ## 0.9.5 (December 20th, 2019) ### Fixed - Fix Host header and HSTS rewrites when an explicit `:80` port is included in URL. (Pull #649) - Query Params on the URL string are merged with any `params=...` argument. (Pull #653) - More robust behavior when closing connections. (Pull #640) - More robust behavior when handling HTTP/2 headers with trailing whitespace. (Pull #637) - Allow any explicit `Content-Type` header to take precedence over the encoding default. (Pull #633) ## 0.9.4 (December 12th, 2019) ### Fixed - Added expiry to Keep-Alive connections, resolving issues with acquiring connections. (Pull #627) - Increased flow control windows on HTTP/2, resolving download speed issues. (Pull #629) ## 0.9.3 (December 7th, 2019) ### Fixed - Fixed HTTP/2 with autodetection backend. (Pull #614) ## 0.9.2 (December 7th, 2019) * Released due to packaging build artifact. ## 0.9.1 (December 6th, 2019) * Released due to packaging build artifact. ## 0.9.0 (December 6th, 2019) The 0.9 releases brings some major new features, including: * A new streaming API. * Autodetection of either asyncio or trio. * Nicer timeout configuration. * HTTP/2 support off by default, but can be enabled. We've also removed all private types from the top-level package export. In order to ensure you are only ever working with public API you should make sure to only import the top-level package eg. `import httpx`, rather than importing modules within the package. ### Added - Added concurrency backend autodetection. (Pull #585) - Added `Client(backend='trio')` and `Client(backend='asyncio')` API. (Pull #585) - Added `response.stream_lines()` API. (Pull #575) - Added `response.is_error` API. (Pull #574) - Added support for `timeout=Timeout(5.0, connect_timeout=60.0)` styles. (Pull #593) ### Fixed - Requests or Clients with `timeout=None` now correctly always disable timeouts. (Pull #592) - Request 'Authorization' headers now have priority over `.netrc` authentication info. (Commit 095b691) - Files without a filename no longer set a Content-Type in multipart data. (Commit ed94950) ### Changed - Added `httpx.stream()` API. Using `stream=True` now results in a warning. (Pull #600, #610) - HTTP/2 support is switched to "off by default", but can be enabled explicitly. (Pull #584) - Switched to `Client(http2=True)` API from `Client(http_versions=["HTTP/1.1", "HTTP/2"])`. (Pull #586) - Removed all private types from the top-level package export. (Pull #608) - The SSL configuration settings of `verify`, `cert`, and `trust_env` now raise warnings if used per-request when using a Client instance. They should always be set on the Client instance itself. (Pull #597) - Use plain strings "TUNNEL_ONLY" or "FORWARD_ONLY" on the HTTPProxy `proxy_mode` argument. The `HTTPProxyMode` enum still exists, but its usage will raise warnings. (#610) - Pool timeouts are now on the timeout configuration, not the pool limits configuration. (Pull #563) - The timeout configuration is now named `httpx.Timeout(...)`, not `httpx.TimeoutConfig(...)`. The old version currently remains as a synonym for backwards compatibility. (Pull #591) --- ## 0.8.0 (November 27, 2019) ### Removed - The synchronous API has been removed, in order to allow us to fundamentally change how we approach supporting both sync and async variants. (See #588 for more details.) --- ## 0.7.8 (November 17, 2019) ### Added - Add support for proxy tunnels for Python 3.6 + asyncio. (Pull #521) ## 0.7.7 (November 15, 2019) ### Fixed - Resolve an issue with cookies behavior on redirect requests. (Pull #529) ### Added - Add request/response DEBUG logs. (Pull #502) - Use TRACE log level for low level info. (Pull #500) ## 0.7.6 (November 2, 2019) ### Removed - Drop `proxies` parameter from the high-level API. (Pull #485) ### Fixed - Tweak multipart files: omit null filenames, add support for `str` file contents. (Pull #482) - Cache NETRC authentication per-client. (Pull #400) - Rely on `getproxies` for all proxy environment variables. (Pull #470) - Wait for the `asyncio` stream to close when closing a connection. (Pull #494) ## 0.7.5 (October 10, 2019) ### Added - Allow lists of values to be passed to `params`. (Pull #386) - `ASGIDispatch`, `WSGIDispatch` are now available in the `httpx.dispatch` namespace. (Pull #407) - `HTTPError` is now available in the `httpx` namespace. (Pull #421) - Add support for `start_tls()` to the Trio concurrency backend. (Pull #467) ### Fixed - Username and password are no longer included in the `Host` header when basic authentication credentials are supplied via the URL. (Pull #417) ### Removed - The `.delete()` function no longer has `json`, `data`, or `files` parameters to match the expected semantics of the `DELETE` method. (Pull #408) - Removed the `trio` extra. Trio support is detected automatically. (Pull #390) ## 0.7.4 (September 25, 2019) ### Added - Add Trio concurrency backend. (Pull #276) - Add `params` parameter to `Client` for setting default query parameters. (Pull #372) - Add support for `SSL_CERT_FILE` and `SSL_CERT_DIR` environment variables. (Pull #307) - Add debug logging to calls into ASGI apps. (Pull #371) - Add debug logging to SSL configuration. (Pull #378) ### Fixed - Fix a bug when using `Client` without timeouts in Python 3.6. (Pull #383) - Propagate `Client` configuration to HTTP proxies. (Pull #377) ## 0.7.3 (September 20, 2019) ### Added - HTTP Proxy support. (Pulls #259, #353) - Add Digest authentication. (Pull #332) - Add `.build_request()` method to `Client` and `AsyncClient`. (Pull #319) - Add `.elapsed` property on responses. (Pull #351) - Add support for `SSLKEYLOGFILE` in Python 3.8b4+. (Pull #301) ### Removed - Drop NPN support for HTTP version negotiation. (Pull #314) ### Fixed - Fix distribution of type annotations for mypy (Pull #361). - Set `Host` header when redirecting cross-origin. (Pull #321) - Drop `Content-Length` headers on `GET` redirects. (Pull #310) - Raise `KeyError` if header isn't found in `Headers`. (Pull #324) - Raise `NotRedirectResponse` in `response.next()` if there is no redirection to perform. (Pull #297) - Fix bug in calculating the HTTP/2 maximum frame size. (Pull #153) ## 0.7.2 (August 28, 2019) - Enforce using `httpx.AsyncioBackend` for the synchronous client. (Pull #232) - `httpx.ConnectionPool` will properly release a dropped connection. (Pull #230) - Remove the `raise_app_exceptions` argument from `Client`. (Pull #238) - `DecodeError` will no longer be raised for an empty body encoded with Brotli. (Pull #237) - Added `http_versions` parameter to `Client`. (Pull #250) - Only use HTTP/1.1 on short-lived connections like `httpx.get()`. (Pull #284) - Convert `Client.cookies` and `Client.headers` when set as a property. (Pull #274) - Setting `HTTPX_DEBUG=1` enables debug logging on all requests. (Pull #277) ## 0.7.1 (August 18, 2019) - Include files with source distribution to be installable. (Pull #233) ## 0.7.0 (August 17, 2019) - Add the `trust_env` property to `BaseClient`. (Pull #187) - Add the `links` property to `BaseResponse`. (Pull #211) - Accept `ssl.SSLContext` instances into `SSLConfig(verify=...)`. (Pull #215) - Add `Response.stream_text()` with incremental encoding detection. (Pull #183) - Properly updated the `Host` header when a redirect changes the origin. (Pull #199) - Ignore invalid `Content-Encoding` headers. (Pull #196) - Use `~/.netrc` and `~/_netrc` files by default when `trust_env=True`. (Pull #189) - Create exception base class `HTTPError` with `request` and `response` properties. (Pull #162) - Add HSTS preload list checking within `BaseClient` to upgrade HTTP URLs to HTTPS. (Pull #184) - Switch IDNA encoding from IDNA 2003 to IDNA 2008. (Pull #161) - Expose base classes for alternate concurrency backends. (Pull #178) - Improve Multipart parameter encoding. (Pull #167) - Add the `headers` property to `BaseClient`. (Pull #159) - Add support for Google's `brotli` library. (Pull #156) - Remove deprecated TLS versions (TLSv1 and TLSv1.1) from default `SSLConfig`. (Pull #155) - Fix `URL.join(...)` to work similarly to RFC 3986 URL joining. (Pull #144) --- ## 0.6.8 (July 25, 2019) - Check for disconnections when searching for an available connection in `ConnectionPool.keepalive_connections` (Pull #145) - Allow string comparison for `URL` objects (Pull #139) - Add HTTP status codes 418 and 451 (Pull #135) - Add support for client certificate passwords (Pull #118) - Enable post-handshake client cert authentication for TLSv1.3 (Pull #118) - Disable using `commonName` for hostname checking for OpenSSL 1.1.0+ (Pull #118) - Detect encoding for `Response.json()` (Pull #116) ## 0.6.7 (July 8, 2019) - Check for connection aliveness on re-acquisition (Pull #111) ## 0.6.6 (July 3, 2019) - Improve `USER_AGENT` (Pull #110) - Add `Connection: keep-alive` by default to HTTP/1.1 connections. (Pull #110) ## 0.6.5 (June 27, 2019) - Include `Host` header by default. (Pull #109) - Improve HTTP protocol detection. (Pull #107) ## 0.6.4 (June 25, 2019) - Implement read and write timeouts (Pull #104) ## 0.6.3 (June 24, 2019) - Handle early connection closes (Pull #103) ## 0.6.2 (June 23, 2019) - Use urllib3's `DEFAULT_CIPHERS` for the `SSLConfig` object. (Pull #100) ## 0.6.1 (June 21, 2019) - Add support for setting a `base_url` on the `Client`. ## 0.6.0 (June 21, 2019) - Honor `local_flow_control_window` for HTTP/2 connections (Pull #98) pydantic-httpx2-6dd59b9/src/httpx2/httpx2/000077500000000000000000000000001526547463400204755ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/src/httpx2/httpx2/__init__.py000066400000000000000000000051451526547463400226130ustar00rootroot00000000000000from .__version__ import __description__, __title__, __version__ from ._alias import * from ._api import * from ._auth import * from ._client import * from ._config import * from ._content import * from ._exceptions import * from ._models import * from ._sse import * from ._status_codes import * from ._transports import * from ._types import * from ._urls import * __all__ = [ # __version__.py "__description__", "__title__", "__version__", # _alias.py "alias_httpx", # _api.py "delete", "get", "head", "options", "patch", "post", "put", "query", "request", "stream", "websocket", # _auth.py "Auth", "BasicAuth", "DigestAuth", "FunctionAuth", "NetRCAuth", # _client.py "AsyncClient", "Client", "USE_CLIENT_DEFAULT", # _config.py "create_ssl_context", "Limits", "Proxy", "Timeout", # _content.py "ByteStream", # _exceptions.py "CloseError", "ConnectError", "ConnectTimeout", "CookieConflict", "DecodingError", "HTTPError", "HTTPStatusError", "InvalidURL", "LocalProtocolError", "NetworkError", "PoolTimeout", "ProtocolError", "ProxyError", "ReadError", "ReadTimeout", "RemoteProtocolError", "RequestError", "RequestNotRead", "ResponseNotRead", "StreamClosed", "StreamConsumed", "StreamError", "TimeoutException", "TooManyRedirects", "TransportError", "UnsupportedProtocol", "WriteError", "WriteTimeout", # _models.py "Cookies", "Headers", "Request", "Response", # _sse.py "EventSource", "ServerSentEvent", "SSEError", # _status_codes.py "codes", # _transports "ASGITransport", "AsyncBaseTransport", "AsyncHTTPTransport", "BaseTransport", "HTTPTransport", "MockTransport", "WSGITransport", # _types.py "AsyncByteStream", "SyncByteStream", # _urls.py "Origin", "QueryParams", "URL", ] __locals = locals() for __name in __all__: if not __name.startswith("__"): setattr(__locals[__name], "__module__", "httpx2") # noqa def __getattr__(name: str) -> object: # pragma: no cover if name == "main": import warnings warnings.warn( "`httpx2.main` is deprecated and will be removed in a future release. " "Use the `httpx2` CLI entry point instead.", DeprecationWarning, stacklevel=2, ) from ._main import main return main raise AttributeError(f"module {__name__!r} has no attribute {name!r}") pydantic-httpx2-6dd59b9/src/httpx2/httpx2/__version__.py000066400000000000000000000002361526547463400233310ustar00rootroot00000000000000from importlib.metadata import version __title__ = "httpx2" __description__ = "A next generation HTTP client, for Python 3." __version__ = version("httpx2") pydantic-httpx2-6dd59b9/src/httpx2/httpx2/_alias.py000066400000000000000000000045771526547463400223140ustar00rootroot00000000000000from __future__ import annotations import importlib import importlib.abc import importlib.machinery import importlib.util import sys from collections.abc import Sequence from types import ModuleType __all__ = ["alias_httpx"] class _AliasLoader(importlib.abc.Loader): _original_spec: importlib.machinery.ModuleSpec | None def __init__(self, real_name: str) -> None: self._real_name = real_name def create_module(self, spec: importlib.machinery.ModuleSpec) -> ModuleType: module = importlib.import_module(self._real_name) self._original_spec = module.__spec__ return module def exec_module(self, module: ModuleType) -> None: module.__spec__ = self._original_spec class _AliasFinder(importlib.abc.MetaPathFinder): def __init__(self, alias: str, real: str) -> None: self._alias = alias self._real = real def find_spec( self, fullname: str, path: Sequence[str] | None = None, target: ModuleType | None = None, ) -> importlib.machinery.ModuleSpec | None: if fullname != self._alias and not fullname.startswith(self._alias + "."): return None real_name = self._real + fullname.removeprefix(self._alias) if real_name not in sys.modules and importlib.util.find_spec(real_name) is None: return None return importlib.machinery.ModuleSpec(fullname, _AliasLoader(real_name)) def _alias(alias: str, module: ModuleType) -> None: existing = sys.modules.get(alias) if existing is not None and existing is not module: raise RuntimeError(f"{alias} was already imported; call `alias_httpx()` before any `import {alias}`.") if not any(isinstance(finder, _AliasFinder) and finder._alias == alias for finder in sys.meta_path): sys.meta_path.insert(0, _AliasFinder(alias, module.__name__)) sys.modules[alias] = module def alias_httpx() -> None: """ Make `import httpx` resolve to `httpx2`, and `import httpcore` to `httpcore2`, process-wide. Intended for applications migrating from `httpx`, so that dependencies still importing `httpx` or `httpcore` share the `httpx2` classes. Libraries should never call this. Must be called before anything imports `httpx` or `httpcore`. Calling it again is a no-op. """ import httpcore2 import httpx2 _alias("httpx", httpx2) _alias("httpcore", httpcore2) pydantic-httpx2-6dd59b9/src/httpx2/httpx2/_api.py000066400000000000000000000347121526547463400217660ustar00rootroot00000000000000from __future__ import annotations import typing from collections.abc import Generator from contextlib import contextmanager from ._client import Client from ._config import ( DEFAULT_KEEPALIVE_PING_INTERVAL_SECONDS, DEFAULT_KEEPALIVE_PING_TIMEOUT_SECONDS, DEFAULT_MAX_MESSAGE_SIZE_BYTES, DEFAULT_QUEUE_SIZE, DEFAULT_TIMEOUT_CONFIG, ) from ._models import Response from ._types import ( AuthTypes, CookieTypes, HeaderTypes, ProxyTypes, QueryParamTypes, RequestContent, RequestData, RequestFiles, TimeoutTypes, ) from ._urls import URL if typing.TYPE_CHECKING: import ssl # pragma: no cover from .websockets._api import WebSocketSession __all__ = [ "delete", "get", "head", "options", "patch", "post", "put", "query", "request", "stream", "websocket", ] def request( method: str, url: URL | str, *, params: QueryParamTypes | None = None, content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: typing.Any | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | None = None, proxy: ProxyTypes | None = None, timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, follow_redirects: bool = False, verify: ssl.SSLContext | str | bool = True, trust_env: bool = True, ) -> Response: """Sends an HTTP request. Parameters: method: HTTP method for the new `Request` object: `GET`, `OPTIONS`, `HEAD`, `POST`, `PUT`, `PATCH`, `DELETE`, or `QUERY`. url: URL for the new `Request` object. params: *(optional)* Query parameters to include in the URL, as a string, dictionary, or sequence of two-tuples. content: *(optional)* Binary content to include in the body of the request, as bytes or a byte iterator. data: *(optional)* Form data to include in the body of the request, as a dictionary. files: *(optional)* A dictionary of upload files to include in the body of the request. json: *(optional)* A JSON serializable object to include in the body of the request. headers: *(optional)* Dictionary of HTTP headers to include in the request. cookies: *(optional)* Dictionary of Cookie items to include in the request. auth: *(optional)* An authentication class to use when sending the request. proxy: *(optional)* A proxy URL where all the traffic should be routed. timeout: *(optional)* The timeout configuration to use when sending the request. follow_redirects: *(optional)* Enables or disables HTTP redirects. verify: *(optional)* Either `True` to use an SSL context with the default CA bundle, `False` to disable verification, or an instance of `ssl.SSLContext` to use a custom context. trust_env: *(optional)* Enables or disables usage of environment variables for configuration. Returns: The `Response` object. Usage: ``` >>> import httpx2 >>> response = httpx2.request('GET', 'https://httpbin.org/get') >>> response ``` """ with Client( cookies=cookies, proxy=proxy, verify=verify, timeout=timeout, trust_env=trust_env, ) as client: return client.request( method=method, url=url, content=content, data=data, files=files, json=json, params=params, headers=headers, auth=auth, follow_redirects=follow_redirects, ) @contextmanager def stream( method: str, url: URL | str, *, params: QueryParamTypes | None = None, content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: typing.Any | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | None = None, proxy: ProxyTypes | None = None, timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, follow_redirects: bool = False, verify: ssl.SSLContext | str | bool = True, trust_env: bool = True, ) -> Generator[Response]: """ Alternative to `httpx2.request()` that streams the response body instead of loading it into memory at once. **Parameters**: See `httpx2.request`. See also: [Streaming Responses][0] [0]: quickstart.md#streaming-responses """ with Client( cookies=cookies, proxy=proxy, verify=verify, timeout=timeout, trust_env=trust_env, ) as client: with client.stream( method=method, url=url, content=content, data=data, files=files, json=json, params=params, headers=headers, auth=auth, follow_redirects=follow_redirects, ) as response: yield response def get( url: URL | str, *, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | None = None, proxy: ProxyTypes | None = None, follow_redirects: bool = False, verify: ssl.SSLContext | str | bool = True, timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, trust_env: bool = True, ) -> Response: """ Sends a `GET` request. **Parameters**: See `httpx2.request`. Note that the `data`, `files`, `json` and `content` parameters are not available on this function, as `GET` requests should not include a request body. """ return request( "GET", url, params=params, headers=headers, cookies=cookies, auth=auth, proxy=proxy, follow_redirects=follow_redirects, verify=verify, timeout=timeout, trust_env=trust_env, ) def options( url: URL | str, *, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | None = None, proxy: ProxyTypes | None = None, follow_redirects: bool = False, verify: ssl.SSLContext | str | bool = True, timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, trust_env: bool = True, ) -> Response: """ Sends an `OPTIONS` request. **Parameters**: See `httpx2.request`. Note that the `data`, `files`, `json` and `content` parameters are not available on this function, as `OPTIONS` requests should not include a request body. """ return request( "OPTIONS", url, params=params, headers=headers, cookies=cookies, auth=auth, proxy=proxy, follow_redirects=follow_redirects, verify=verify, timeout=timeout, trust_env=trust_env, ) def head( url: URL | str, *, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | None = None, proxy: ProxyTypes | None = None, follow_redirects: bool = False, verify: ssl.SSLContext | str | bool = True, timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, trust_env: bool = True, ) -> Response: """ Sends a `HEAD` request. **Parameters**: See `httpx2.request`. Note that the `data`, `files`, `json` and `content` parameters are not available on this function, as `HEAD` requests should not include a request body. """ return request( "HEAD", url, params=params, headers=headers, cookies=cookies, auth=auth, proxy=proxy, follow_redirects=follow_redirects, verify=verify, timeout=timeout, trust_env=trust_env, ) def post( url: URL | str, *, content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: typing.Any | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | None = None, proxy: ProxyTypes | None = None, follow_redirects: bool = False, verify: ssl.SSLContext | str | bool = True, timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, trust_env: bool = True, ) -> Response: """ Sends a `POST` request. **Parameters**: See `httpx2.request`. """ return request( "POST", url, content=content, data=data, files=files, json=json, params=params, headers=headers, cookies=cookies, auth=auth, proxy=proxy, follow_redirects=follow_redirects, verify=verify, timeout=timeout, trust_env=trust_env, ) def put( url: URL | str, *, content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: typing.Any | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | None = None, proxy: ProxyTypes | None = None, follow_redirects: bool = False, verify: ssl.SSLContext | str | bool = True, timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, trust_env: bool = True, ) -> Response: """ Sends a `PUT` request. **Parameters**: See `httpx2.request`. """ return request( "PUT", url, content=content, data=data, files=files, json=json, params=params, headers=headers, cookies=cookies, auth=auth, proxy=proxy, follow_redirects=follow_redirects, verify=verify, timeout=timeout, trust_env=trust_env, ) def patch( url: URL | str, *, content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: typing.Any | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | None = None, proxy: ProxyTypes | None = None, follow_redirects: bool = False, verify: ssl.SSLContext | str | bool = True, timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, trust_env: bool = True, ) -> Response: """ Sends a `PATCH` request. **Parameters**: See `httpx2.request`. """ return request( "PATCH", url, content=content, data=data, files=files, json=json, params=params, headers=headers, cookies=cookies, auth=auth, proxy=proxy, follow_redirects=follow_redirects, verify=verify, timeout=timeout, trust_env=trust_env, ) def delete( url: URL | str, *, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | None = None, proxy: ProxyTypes | None = None, follow_redirects: bool = False, timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, verify: ssl.SSLContext | str | bool = True, trust_env: bool = True, ) -> Response: """ Sends a `DELETE` request. **Parameters**: See `httpx2.request`. Note that the `data`, `files`, `json` and `content` parameters are not available on this function, as `DELETE` requests should not include a request body. """ return request( "DELETE", url, params=params, headers=headers, cookies=cookies, auth=auth, proxy=proxy, follow_redirects=follow_redirects, verify=verify, timeout=timeout, trust_env=trust_env, ) def query( url: URL | str, *, content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: typing.Any | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | None = None, proxy: ProxyTypes | None = None, follow_redirects: bool = False, verify: ssl.SSLContext | str | bool = True, timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, trust_env: bool = True, ) -> Response: """ Sends a `QUERY` request. **Parameters**: See `httpx2.request`. """ return request( "QUERY", url, content=content, data=data, files=files, json=json, params=params, headers=headers, cookies=cookies, auth=auth, proxy=proxy, follow_redirects=follow_redirects, verify=verify, timeout=timeout, trust_env=trust_env, ) @contextmanager def websocket( url: URL | str, *, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | None = None, proxy: ProxyTypes | None = None, follow_redirects: bool = False, timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, verify: ssl.SSLContext | str | bool = True, trust_env: bool = True, subprotocols: list[str] | None = None, max_message_size_bytes: int = DEFAULT_MAX_MESSAGE_SIZE_BYTES, queue_size: int = DEFAULT_QUEUE_SIZE, keepalive_ping_interval_seconds: float | None = DEFAULT_KEEPALIVE_PING_INTERVAL_SECONDS, keepalive_ping_timeout_seconds: float | None = DEFAULT_KEEPALIVE_PING_TIMEOUT_SECONDS, ) -> Generator[WebSocketSession]: """ Open a WebSocket session. The session is closed automatically when exiting the context manager. ```python with httpx2.websocket("ws://localhost:8000/ws") as ws: ws.send_text("Hello!") message = ws.receive_text() ``` **Parameters**: See `httpx2.request` and `httpx2.Client.websocket`. """ with Client( cookies=cookies, proxy=proxy, verify=verify, timeout=timeout, trust_env=trust_env, ) as client: with client.websocket( url, params=params, headers=headers, auth=auth, follow_redirects=follow_redirects, subprotocols=subprotocols, max_message_size_bytes=max_message_size_bytes, queue_size=queue_size, keepalive_ping_interval_seconds=keepalive_ping_interval_seconds, keepalive_ping_timeout_seconds=keepalive_ping_timeout_seconds, ) as session: yield session pydantic-httpx2-6dd59b9/src/httpx2/httpx2/_auth.py000066400000000000000000000273011526547463400221520ustar00rootroot00000000000000from __future__ import annotations import hashlib import os import re import time import typing from base64 import b64encode from urllib.request import parse_http_list from ._exceptions import ProtocolError from ._models import Cookies, Request, Response from ._utils import to_bytes, to_str if typing.TYPE_CHECKING: from collections.abc import Callable from hashlib import _Hash __all__ = ["Auth", "BasicAuth", "DigestAuth", "FunctionAuth", "NetRCAuth"] class Auth: """ Base class for all authentication schemes. To implement a custom authentication scheme, subclass `Auth` and override the `.auth_flow()` method. If the authentication scheme does I/O such as disk access or network calls, or uses synchronization primitives such as locks, you should override `.sync_auth_flow()` and/or `.async_auth_flow()` instead of `.auth_flow()` to provide specialized implementations that will be used by `Client` and `AsyncClient` respectively. """ requires_request_body = False requires_response_body = False def auth_flow(self, request: Request) -> typing.Generator[Request, Response, None]: """ Execute the authentication flow. To dispatch a request, `yield` it: ``` yield request ``` The client will `.send()` the response back into the flow generator. You can access it like so: ``` response = yield request ``` A `return` (or reaching the end of the generator) will result in the client returning the last response obtained from the server. You can dispatch as many requests as is necessary. """ yield request def sync_auth_flow(self, request: Request) -> typing.Generator[Request, Response, None]: """ Execute the authentication flow synchronously. By default, this defers to `.auth_flow()`. You should override this method when the authentication scheme does I/O and/or uses concurrency primitives. """ if self.requires_request_body: request.read() flow = self.auth_flow(request) request = next(flow) while True: response = yield request if self.requires_response_body: response.read() try: request = flow.send(response) except StopIteration: break async def async_auth_flow(self, request: Request) -> typing.AsyncGenerator[Request, Response]: """ Execute the authentication flow asynchronously. By default, this defers to `.auth_flow()`. You should override this method when the authentication scheme does I/O and/or uses concurrency primitives. """ if self.requires_request_body: await request.aread() flow = self.auth_flow(request) request = next(flow) while True: response = yield request if self.requires_response_body: await response.aread() try: request = flow.send(response) except StopIteration: break class FunctionAuth(Auth): """ Allows the 'auth' argument to be passed as a simple callable function, that takes the request, and returns a new, modified request. """ def __init__(self, func: typing.Callable[[Request], Request]) -> None: self._func = func def auth_flow(self, request: Request) -> typing.Generator[Request, Response, None]: yield self._func(request) class BasicAuth(Auth): """ Allows the 'auth' argument to be passed as a (username, password) pair, and uses HTTP Basic authentication. """ def __init__(self, username: str | bytes, password: str | bytes) -> None: self._auth_header = self._build_auth_header(username, password) def auth_flow(self, request: Request) -> typing.Generator[Request, Response, None]: request.headers["Authorization"] = self._auth_header yield request def _build_auth_header(self, username: str | bytes, password: str | bytes) -> str: userpass = b":".join((to_bytes(username), to_bytes(password))) token = b64encode(userpass).decode() return f"Basic {token}" class NetRCAuth(Auth): """ Use a 'netrc' file to lookup basic auth credentials based on the url host. """ def __init__(self, file: str | None = None) -> None: # Lazily import 'netrc'. # There's no need for us to load this module unless 'NetRCAuth' is being used. import netrc self._netrc_info = netrc.netrc(file) def auth_flow(self, request: Request) -> typing.Generator[Request, Response, None]: auth_info = self._netrc_info.authenticators(request.url.host) if auth_info is None or not auth_info[2]: # The netrc file did not have authentication credentials for this host. yield request else: # Build a basic auth header with credentials from the netrc file. request.headers["Authorization"] = self._build_auth_header(username=auth_info[0], password=auth_info[2]) yield request def _build_auth_header(self, username: str | bytes, password: str | bytes) -> str: userpass = b":".join((to_bytes(username), to_bytes(password))) token = b64encode(userpass).decode() return f"Basic {token}" class DigestAuth(Auth): # Hashes are resolved by name at use time, since FIPS builds may remove or block MD5. _ALGORITHM_TO_HASH_NAME = { "MD5": "md5", "MD5-SESS": "md5", "SHA": "sha1", "SHA-SESS": "sha1", "SHA-256": "sha256", "SHA-256-SESS": "sha256", "SHA-512": "sha512", "SHA-512-SESS": "sha512", } def __init__(self, username: str | bytes, password: str | bytes) -> None: self._username = to_bytes(username) self._password = to_bytes(password) self._last_challenge: _DigestAuthChallenge | None = None self._nonce_count = 1 def auth_flow(self, request: Request) -> typing.Generator[Request, Response, None]: if self._last_challenge: request.headers["Authorization"] = self._build_auth_header(request, self._last_challenge) response = yield request if response.status_code != 401 or "www-authenticate" not in response.headers: # If the response is not a 401 then we don't # need to build an authenticated request. return for auth_header in response.headers.get_list("www-authenticate"): if auth_header.lower().startswith("digest "): break else: # If the response does not include a 'WWW-Authenticate: Digest ...' # header, then we don't need to build an authenticated request. return self._last_challenge = self._parse_challenge(request, response, auth_header) self._nonce_count = 1 request.headers["Authorization"] = self._build_auth_header(request, self._last_challenge) if response.cookies: Cookies(response.cookies).set_cookie_header(request=request) yield request def _parse_challenge(self, request: Request, response: Response, auth_header: str) -> _DigestAuthChallenge: """ Returns a challenge from a Digest WWW-Authenticate header. These take the form of: `Digest realm="realm@host.com",qop="auth,auth-int",nonce="abc",opaque="xyz"` """ scheme, _, fields = auth_header.partition(" ") # This method should only ever have been called with a Digest auth header. assert scheme.lower() == "digest" header_dict: dict[str, str] = {} for field in parse_http_list(fields): key, value = field.strip().split("=", 1) header_dict[key] = value.strip('"') try: realm = header_dict["realm"].encode() nonce = header_dict["nonce"].encode() algorithm = header_dict.get("algorithm", "MD5") opaque = header_dict["opaque"].encode() if "opaque" in header_dict else None qop = header_dict["qop"].encode() if "qop" in header_dict else None return _DigestAuthChallenge(realm=realm, nonce=nonce, algorithm=algorithm, opaque=opaque, qop=qop) except KeyError as exc: message = "Malformed Digest WWW-Authenticate header" raise ProtocolError(message, request=request) from exc def _build_auth_header(self, request: Request, challenge: _DigestAuthChallenge) -> str: try: hash_func: Callable[[bytes], _Hash] = getattr( hashlib, self._ALGORITHM_TO_HASH_NAME[challenge.algorithm.upper()] ) except (KeyError, AttributeError) as exc: message = f"Unsupported digest auth algorithm {challenge.algorithm!r}" raise ProtocolError(message, request=request) from exc def digest(data: bytes) -> bytes: return hash_func(data).hexdigest().encode() A1 = b":".join((self._username, challenge.realm, self._password)) path = request.url.raw_path A2 = b":".join((request.method.encode(), path)) # TODO: implement auth-int HA2 = digest(A2) nc_value = b"%08x" % self._nonce_count cnonce = self._get_client_nonce(self._nonce_count, challenge.nonce) self._nonce_count += 1 HA1 = digest(A1) if challenge.algorithm.lower().endswith("-sess"): HA1 = digest(b":".join((HA1, challenge.nonce, cnonce))) qop = self._resolve_qop(challenge.qop, request=request) if qop is None: # Following RFC 2069 digest_data = [HA1, challenge.nonce, HA2] else: # Following RFC 2617/7616 digest_data = [HA1, challenge.nonce, nc_value, cnonce, qop, HA2] format_args = { "username": self._username, "realm": challenge.realm, "nonce": challenge.nonce, "uri": path, "response": digest(b":".join(digest_data)), "algorithm": challenge.algorithm.encode(), } if challenge.opaque: format_args["opaque"] = challenge.opaque if qop: format_args["qop"] = b"auth" format_args["nc"] = nc_value format_args["cnonce"] = cnonce return "Digest " + self._get_header_value(format_args) def _get_client_nonce(self, nonce_count: int, nonce: bytes) -> bytes: s = str(nonce_count).encode() s += nonce s += time.ctime().encode() s += os.urandom(8) return hashlib.sha1(s).hexdigest()[:16].encode() def _get_header_value(self, header_fields: dict[str, bytes]) -> str: NON_QUOTED_FIELDS = ("algorithm", "qop", "nc") QUOTED_TEMPLATE = '{}="{}"' NON_QUOTED_TEMPLATE = "{}={}" header_value = "" for i, (field, value) in enumerate(header_fields.items()): if i > 0: header_value += ", " template = QUOTED_TEMPLATE if field not in NON_QUOTED_FIELDS else NON_QUOTED_TEMPLATE header_value += template.format(field, to_str(value)) return header_value def _resolve_qop(self, qop: bytes | None, request: Request) -> bytes | None: if qop is None: return None qops = re.split(b", ?", qop) if b"auth" in qops: return b"auth" if qops == [b"auth-int"]: raise NotImplementedError("Digest auth-int support is not yet implemented") message = f'Unexpected qop value "{qop!r}" in digest auth' raise ProtocolError(message, request=request) class _DigestAuthChallenge(typing.NamedTuple): realm: bytes nonce: bytes algorithm: str opaque: bytes | None qop: bytes | None pydantic-httpx2-6dd59b9/src/httpx2/httpx2/_client.py000066400000000000000000002232221526547463400224670ustar00rootroot00000000000000from __future__ import annotations import datetime import enum import logging import time import typing import warnings from collections.abc import AsyncGenerator, Generator from contextlib import asynccontextmanager, contextmanager from types import TracebackType from .__version__ import __version__ from ._auth import Auth, BasicAuth, FunctionAuth from ._config import ( DEFAULT_KEEPALIVE_PING_INTERVAL_SECONDS, DEFAULT_KEEPALIVE_PING_TIMEOUT_SECONDS, DEFAULT_LIMITS, DEFAULT_MAX_EVENT_SIZE_BYTES, DEFAULT_MAX_MESSAGE_SIZE_BYTES, DEFAULT_MAX_REDIRECTS, DEFAULT_QUEUE_SIZE, DEFAULT_TIMEOUT_CONFIG, Limits, Proxy, Timeout, ) from ._decoders import SUPPORTED_DECODERS from ._exceptions import ( InvalidURL, RemoteProtocolError, TooManyRedirects, request_context, ) from ._models import Cookies, Headers, Request, Response from ._sse import EventSource from ._status_codes import codes from ._transports import AsyncHTTPTransport, HTTPTransport from ._transports.base import AsyncBaseTransport, BaseTransport from ._types import ( AsyncByteStream, AuthTypes, CertTypes, CookieTypes, HeaderTypes, ProxyTypes, QueryParamTypes, RequestContent, RequestData, RequestExtensions, RequestFiles, SyncByteStream, TimeoutTypes, ) from ._urls import URL, QueryParams from ._utils import URLPattern, get_environment_proxies if typing.TYPE_CHECKING: import ssl # pragma: no cover from .websockets._api import AsyncWebSocketSession, WebSocketSession __all__ = ["USE_CLIENT_DEFAULT", "AsyncClient", "Client"] # The type annotation for @classmethod and context managers here follows PEP 484 # https://www.python.org/dev/peps/pep-0484/#annotating-instance-and-class-methods T = typing.TypeVar("T", bound="Client") U = typing.TypeVar("U", bound="AsyncClient") def _is_https_redirect(url: URL, location: URL) -> bool: """ Return 'True' if 'location' is a HTTPS upgrade of 'url' """ origin = url.origin location_origin = location.origin return ( origin.host == location_origin.host and origin.scheme == "http" and origin.port == 80 and location_origin.scheme == "https" and location_origin.port == 443 ) class UseClientDefault: """ For some parameters such as `auth=...` and `timeout=...` we need to be able to indicate the default "unset" state, in a way that is distinctly different to using `None`. The default "unset" state indicates that whatever default is set on the client should be used. This is different to setting `None`, which explicitly disables the parameter, possibly overriding a client default. For example we use `timeout=USE_CLIENT_DEFAULT` in the `request()` signature. Omitting the `timeout` parameter will send a request using whatever default timeout has been configured on the client. Including `timeout=None` will ensure no timeout is used. Note that user code shouldn't need to use the `USE_CLIENT_DEFAULT` constant, but it is used internally when a parameter is not included. """ USE_CLIENT_DEFAULT = UseClientDefault() logger = logging.getLogger("httpx2") USER_AGENT = f"python-httpx2/{__version__}" ACCEPT_ENCODING = ", ".join([key for key in SUPPORTED_DECODERS.keys() if key != "identity"]) class ClientState(enum.Enum): # UNOPENED: # The client has been instantiated, but has not been used to send a request, # or been opened by entering the context of a `with` block. UNOPENED = 1 # OPENED: # The client has either sent a request, or is within a `with` block. OPENED = 2 # CLOSED: # The client has either exited the `with` block, or `close()` has # been called explicitly. CLOSED = 3 class BoundSyncStream(SyncByteStream): """ A byte stream that tracks elapsed time for a response. Once closed, the elapsed time is available via the `elapsed` attribute, and the response can read it back from `response.stream.elapsed`. """ def __init__(self, stream: SyncByteStream, start: float) -> None: self._stream = stream self._start = start self.elapsed: datetime.timedelta | None = None def __iter__(self) -> typing.Iterator[bytes]: yield from self._stream def close(self) -> None: self.elapsed = datetime.timedelta(seconds=time.perf_counter() - self._start) self._stream.close() class BoundAsyncStream(AsyncByteStream): """ An async byte stream that tracks elapsed time for a response. Once closed, the elapsed time is available via the `elapsed` attribute, and the response can read it back from `response.stream.elapsed`. """ def __init__(self, stream: AsyncByteStream, start: float) -> None: self._stream = stream self._start = start self.elapsed: datetime.timedelta | None = None async def __aiter__(self) -> typing.AsyncIterator[bytes]: stream = self._stream.__aiter__() try: async for chunk in stream: yield chunk finally: if isinstance(stream, AsyncGenerator): await stream.aclose() async def aclose(self) -> None: self.elapsed = datetime.timedelta(seconds=time.perf_counter() - self._start) await self._stream.aclose() EventHook = typing.Callable[..., typing.Any] class BaseClient: def __init__( self, *, auth: AuthTypes | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, follow_redirects: bool = False, max_redirects: int = DEFAULT_MAX_REDIRECTS, event_hooks: None | (typing.Mapping[str, list[EventHook]]) = None, base_url: URL | str = "", trust_env: bool = True, default_encoding: str | typing.Callable[[bytes], str | None] = "utf-8", ) -> None: event_hooks = {} if event_hooks is None else event_hooks self._base_url = self._enforce_trailing_slash(URL(base_url)) self._auth = self._build_auth(auth) self._params = QueryParams(params) self.headers = Headers(headers) self._cookies = Cookies(cookies) self._timeout = Timeout(timeout) self.follow_redirects = follow_redirects self.max_redirects = max_redirects self._event_hooks = { "request": list(event_hooks.get("request", [])), "response": list(event_hooks.get("response", [])), } self._trust_env = trust_env self._default_encoding = default_encoding self._state = ClientState.UNOPENED @property def is_closed(self) -> bool: """ Check if the client being closed """ return self._state == ClientState.CLOSED @property def trust_env(self) -> bool: return self._trust_env def _enforce_trailing_slash(self, url: URL) -> URL: if url.raw_path.endswith(b"/"): return url return url.copy_with(raw_path=url.raw_path + b"/") def _get_proxy_map(self, proxy: ProxyTypes | None, allow_env_proxies: bool) -> dict[str, Proxy | None]: if proxy is None: if allow_env_proxies: return {key: None if url is None else Proxy(url=url) for key, url in get_environment_proxies().items()} return {} else: proxy = Proxy(url=proxy) if isinstance(proxy, (str, URL)) else proxy return {"all://": proxy} @property def timeout(self) -> Timeout: return self._timeout @timeout.setter def timeout(self, timeout: TimeoutTypes) -> None: self._timeout = Timeout(timeout) @property def event_hooks(self) -> dict[str, list[EventHook]]: return self._event_hooks @event_hooks.setter def event_hooks(self, event_hooks: dict[str, list[EventHook]]) -> None: self._event_hooks = { "request": list(event_hooks.get("request", [])), "response": list(event_hooks.get("response", [])), } @property def auth(self) -> Auth | None: """ Authentication class used when none is passed at the request-level. See also [Authentication][0]. [0]: quickstart.md#authentication """ return self._auth @auth.setter def auth(self, auth: AuthTypes) -> None: self._auth = self._build_auth(auth) @property def base_url(self) -> URL: """ Base URL to use when sending requests with relative URLs. """ return self._base_url @base_url.setter def base_url(self, url: URL | str) -> None: self._base_url = self._enforce_trailing_slash(URL(url)) @property def headers(self) -> Headers: """ HTTP headers to include when sending requests. """ return self._headers @headers.setter def headers(self, headers: HeaderTypes) -> None: client_headers = Headers( { b"Accept": b"*/*", b"Accept-Encoding": ACCEPT_ENCODING.encode("ascii"), b"Connection": b"keep-alive", b"User-Agent": USER_AGENT.encode("ascii"), } ) client_headers.update(headers) self._headers = client_headers @property def cookies(self) -> Cookies: """ Cookie values to include when sending requests. """ return self._cookies @cookies.setter def cookies(self, cookies: CookieTypes) -> None: self._cookies = Cookies(cookies) @property def params(self) -> QueryParams: """ Query parameters to include in the URL when sending requests. """ return self._params @params.setter def params(self, params: QueryParamTypes) -> None: self._params = QueryParams(params) def build_request( self, method: str, url: URL | str, *, content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: typing.Any | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Request: """ Build and return a request instance. * The `params`, `headers` and `cookies` arguments are merged with any values set on the client. * The `url` argument is merged with any `base_url` set on the client. See also: [Request instances][0] [0]: advanced/clients.md#request-instances """ url = self._merge_url(url) headers = self._merge_headers(headers) cookies = self._merge_cookies(cookies) params = self._merge_queryparams(params) extensions = {} if extensions is None else extensions if "timeout" not in extensions: timeout = self.timeout if isinstance(timeout, UseClientDefault) else Timeout(timeout) extensions = dict(**extensions, timeout=timeout.as_dict()) return Request( method, url, content=content, data=data, files=files, json=json, params=params, headers=headers, cookies=cookies, extensions=extensions, ) def _merge_url(self, url: URL | str) -> URL: """ Merge a URL argument together with any 'base_url' on the client, to create the URL used for the outgoing request. """ merge_url = URL(url) if merge_url.is_relative_url: # To merge URLs we always append to the base URL. To get this # behaviour correct we always ensure the base URL ends in a '/' # separator, and strip any leading '/' from the merge URL. # # So, eg... # # >>> client = Client(base_url="https://www.example.com/subpath") # >>> client.base_url # URL('https://www.example.com/subpath/') # >>> client.build_request("GET", "/path").url # URL('https://www.example.com/subpath/path') merge_raw_path = self.base_url.raw_path + merge_url.raw_path.lstrip(b"/") return self.base_url.copy_with(raw_path=merge_raw_path) return merge_url def _merge_cookies(self, cookies: CookieTypes | None = None) -> CookieTypes | None: """ Merge a cookies argument together with any cookies on the client, to create the cookies used for the outgoing request. """ if cookies or self.cookies: merged_cookies = Cookies(self.cookies) merged_cookies.update(cookies) return merged_cookies return cookies def _merge_headers(self, headers: HeaderTypes | None = None) -> HeaderTypes | None: """ Merge a headers argument together with any headers on the client, to create the headers used for the outgoing request. """ merged_headers = Headers(self.headers) merged_headers.update(headers) return merged_headers def _merge_queryparams(self, params: QueryParamTypes | None = None) -> QueryParamTypes | None: """ Merge a queryparams argument together with any queryparams on the client, to create the queryparams used for the outgoing request. """ if params or self.params: merged_queryparams = QueryParams(self.params) return merged_queryparams.merge(params) return params def _build_auth(self, auth: AuthTypes | None) -> Auth | None: if auth is None: return None elif isinstance(auth, tuple): return BasicAuth(username=auth[0], password=auth[1]) elif isinstance(auth, Auth): return auth elif callable(auth): return FunctionAuth(func=auth) else: raise TypeError(f'Invalid "auth" argument: {auth!r}') def _build_request_auth( self, request: Request, auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, ) -> Auth: auth = self._auth if isinstance(auth, UseClientDefault) else self._build_auth(auth) if auth is not None: return auth username, password = request.url.username, request.url.password if username or password: return BasicAuth(username=username, password=password) return Auth() def _build_redirect_request(self, request: Request, response: Response) -> Request: """ Given a request and a redirect response, return a new request that should be used to effect the redirect. """ method = self._redirect_method(request, response) url = self._redirect_url(request, response) headers = self._redirect_headers(request, url, method) stream = self._redirect_stream(request, method) cookies = Cookies(self.cookies) return Request( method=method, url=url, headers=headers, cookies=cookies, stream=stream, extensions=request.extensions, ) def _redirect_method(self, request: Request, response: Response) -> str: """ When being redirected we may want to change the method of the request based on certain specs or browser behavior. """ method = request.method # https://tools.ietf.org/html/rfc7231#section-6.4.4 if response.status_code == codes.SEE_OTHER and method != "HEAD": method = "GET" # Do what the browsers do, despite standards... # Turn 302s into GETs. # QUERY is excluded, per RFC 10008 Section 2.5. # https://datatracker.ietf.org/doc/html/rfc10008#section-2.5 if response.status_code == codes.FOUND and method not in ("HEAD", "QUERY"): method = "GET" # If a POST is responded to with a 301, turn it into a GET. # This bizarre behaviour is explained in 'requests' issue 1704. if response.status_code == codes.MOVED_PERMANENTLY and method == "POST": method = "GET" return method def _redirect_url(self, request: Request, response: Response) -> URL: """ Return the URL for the redirect to follow. """ location = response.headers["Location"] try: url = URL(location) except InvalidURL as exc: raise RemoteProtocolError(f"Invalid URL in location header: {exc}.", request=request) from None # Handle malformed 'Location' headers that are "absolute" form, have no host. # See: https://github.com/encode/httpx/issues/771 if url.scheme and not url.host: url = url.copy_with(host=request.url.host) # Facilitate relative 'Location' headers, as allowed by RFC 7231. # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource') if url.is_relative_url: url = request.url.join(url) # Attach previous fragment if needed (RFC 7231 7.1.2) if request.url.fragment and not url.fragment: url = url.copy_with(fragment=request.url.fragment) return url def _redirect_headers(self, request: Request, url: URL, method: str) -> Headers: """ Return the headers that should be used for the redirect request. """ headers = Headers(request.headers) if url.origin != request.url.origin: if not _is_https_redirect(request.url, url): # Strip Authorization headers when responses are redirected # away from the origin. (Except for direct HTTP to HTTPS redirects.) headers.pop("Authorization", None) # Update the Host header. headers["Host"] = url.netloc.decode("ascii") if method != request.method and method == "GET": # If we've switch to a 'GET' request, then strip any headers which # are only relevant to the request body. headers.pop("Content-Length", None) headers.pop("Transfer-Encoding", None) # We should use the client cookie store to determine any cookie header, # rather than whatever was on the original outgoing request. headers.pop("Cookie", None) return headers def _redirect_stream(self, request: Request, method: str) -> SyncByteStream | AsyncByteStream | None: """ Return the body that should be used for the redirect request. """ if method != request.method and method == "GET": return None return request.stream def _set_timeout(self, request: Request) -> None: if "timeout" not in request.extensions: timeout = self.timeout if isinstance(self.timeout, UseClientDefault) else Timeout(self.timeout) request.extensions = dict(**request.extensions, timeout=timeout.as_dict()) class Client(BaseClient): """ An HTTP client, with connection pooling, HTTP/2, redirects, cookie persistence, etc. It can be shared between threads. Usage: ```python >>> client = httpx2.Client() >>> response = client.get('https://example.org') ``` **Parameters:** * **auth** - *(optional)* An authentication class to use when sending requests. * **params** - *(optional)* Query parameters to include in request URLs, as a string, dictionary, or sequence of two-tuples. * **headers** - *(optional)* Dictionary of HTTP headers to include when sending requests. * **cookies** - *(optional)* Dictionary of Cookie items to include when sending requests. * **verify** - *(optional)* Either `True` to use an SSL context with the default CA bundle, `False` to disable verification, or an instance of `ssl.SSLContext` to use a custom context. * **http2** - *(optional)* A boolean indicating if HTTP/2 support should be enabled. Defaults to `False`. * **proxy** - *(optional)* A proxy URL where all the traffic should be routed. * **mounts** - *(optional)* A dictionary mapping URL patterns to transports, used to route requests through specific transports based on the URL. * **timeout** - *(optional)* The timeout configuration to use when sending requests. * **limits** - *(optional)* The limits configuration to use. * **max_redirects** - *(optional)* The maximum number of redirect responses that should be followed. * **base_url** - *(optional)* A URL to use as the base when building request URLs. * **transport** - *(optional)* A transport class to use for sending requests over the network. * **trust_env** - *(optional)* Enables or disables usage of environment variables for configuration. * **default_encoding** - *(optional)* The default encoding to use for decoding response text, if no charset information is included in a response Content-Type header. Set to a callable for automatic character set detection. Default: "utf-8". """ def __init__( self, *, auth: AuthTypes | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, verify: ssl.SSLContext | str | bool = True, cert: CertTypes | None = None, trust_env: bool = True, http1: bool = True, http2: bool = False, proxy: ProxyTypes | None = None, mounts: None | (typing.Mapping[str, BaseTransport | None]) = None, timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, follow_redirects: bool = False, limits: Limits = DEFAULT_LIMITS, max_redirects: int = DEFAULT_MAX_REDIRECTS, event_hooks: None | (typing.Mapping[str, list[EventHook]]) = None, base_url: URL | str = "", transport: BaseTransport | None = None, default_encoding: str | typing.Callable[[bytes], str | None] = "utf-8", ) -> None: super().__init__( auth=auth, params=params, headers=headers, cookies=cookies, timeout=timeout, follow_redirects=follow_redirects, max_redirects=max_redirects, event_hooks=event_hooks, base_url=base_url, trust_env=trust_env, default_encoding=default_encoding, ) if http2: try: import h2 # noqa except ImportError: # pragma: no cover raise ImportError( "Using http2=True, but the 'h2' package is not installed. " "Make sure to install httpx using `pip install httpx[http2]`." ) from None allow_env_proxies = trust_env and transport is None proxy_map = self._get_proxy_map(proxy, allow_env_proxies) self._transport = self._init_transport( verify=verify, cert=cert, trust_env=trust_env, http1=http1, http2=http2, limits=limits, transport=transport, ) self._mounts: dict[URLPattern, BaseTransport | None] = { URLPattern(key): None if proxy is None else self._init_proxy_transport( proxy, verify=verify, cert=cert, trust_env=trust_env, http1=http1, http2=http2, limits=limits, ) for key, proxy in proxy_map.items() } if mounts is not None: self._mounts.update({URLPattern(key): transport for key, transport in mounts.items()}) self._mounts = dict(sorted(self._mounts.items())) def _init_transport( self, verify: ssl.SSLContext | str | bool = True, cert: CertTypes | None = None, trust_env: bool = True, http1: bool = True, http2: bool = False, limits: Limits = DEFAULT_LIMITS, transport: BaseTransport | None = None, ) -> BaseTransport: if transport is not None: return transport return HTTPTransport( verify=verify, cert=cert, trust_env=trust_env, http1=http1, http2=http2, limits=limits, ) def _init_proxy_transport( self, proxy: Proxy, verify: ssl.SSLContext | str | bool = True, cert: CertTypes | None = None, trust_env: bool = True, http1: bool = True, http2: bool = False, limits: Limits = DEFAULT_LIMITS, ) -> BaseTransport: return HTTPTransport( verify=verify, cert=cert, trust_env=trust_env, http1=http1, http2=http2, limits=limits, proxy=proxy, ) def _transport_for_url(self, url: URL) -> BaseTransport: """ Returns the transport instance that should be used for a given URL. This will either be the standard connection pool, or a proxy. """ for pattern, transport in self._mounts.items(): if pattern.matches(url): return self._transport if transport is None else transport return self._transport def request( self, method: str, url: URL | str, *, content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: typing.Any | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Response: """ Build and send a request. Equivalent to: ```python request = client.build_request(...) response = client.send(request, ...) ``` See `Client.build_request()`, `Client.send()` and [Merging of configuration][0] for how the various parameters are merged with client-level configuration. [0]: advanced/clients.md#merging-of-configuration """ if cookies is not None: message = ( "Setting per-request cookies=<...> is being deprecated, because " "the expected behaviour on cookie persistence is ambiguous. Set " "cookies directly on the client instance instead." ) warnings.warn(message, DeprecationWarning, stacklevel=2) request = self.build_request( method=method, url=url, content=content, data=data, files=files, json=json, params=params, headers=headers, cookies=cookies, timeout=timeout, extensions=extensions, ) return self.send(request, auth=auth, follow_redirects=follow_redirects) @contextmanager def stream( self, method: str, url: URL | str, *, content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: typing.Any | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Generator[Response]: """ Alternative to `httpx2.request()` that streams the response body instead of loading it into memory at once. **Parameters**: See `httpx2.request`. See also: [Streaming Responses][0] [0]: quickstart.md#streaming-responses """ request = self.build_request( method=method, url=url, content=content, data=data, files=files, json=json, params=params, headers=headers, cookies=cookies, timeout=timeout, extensions=extensions, ) response = self.send( request=request, auth=auth, follow_redirects=follow_redirects, stream=True, ) try: yield response finally: response.close() @contextmanager def sse( self, url: URL | str, *, method: str = "GET", content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: typing.Any | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, max_event_size: int | None = DEFAULT_MAX_EVENT_SIZE_BYTES, ) -> Generator[EventSource]: """ Connect to a server-sent events endpoint and yield an `EventSource`. Iterating the `EventSource` yields `ServerSentEvent` instances. **Parameters**: See `httpx2.request`. """ with self.stream( method, url, content=content, data=data, files=files, json=json, params=params, headers={"Accept": "text/event-stream", "Cache-Control": "no-store"} | Headers(headers), cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) as response: yield EventSource(response, max_event_size=max_event_size) @contextmanager def websocket( self, url: URL | str, *, max_message_size_bytes: int = DEFAULT_MAX_MESSAGE_SIZE_BYTES, queue_size: int = DEFAULT_QUEUE_SIZE, keepalive_ping_interval_seconds: float | None = DEFAULT_KEEPALIVE_PING_INTERVAL_SECONDS, keepalive_ping_timeout_seconds: float | None = DEFAULT_KEEPALIVE_PING_TIMEOUT_SECONDS, subprotocols: list[str] | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Generator[WebSocketSession]: """ Open a WebSocket session, using this client's configuration. The session is closed automatically when exiting the context manager. ```python with httpx2.Client() as client: with client.websocket("ws://localhost:8000/ws") as ws: ws.send_text("Hello!") message = ws.receive_text() ``` """ try: from .websockets._api import connect_ws except ImportError: # pragma: no cover raise ImportError( "WebSocket support requires the `wsproto` package. Install it with `pip install httpx2[ws]`." ) with connect_ws( str(url), self, max_message_size_bytes=max_message_size_bytes, queue_size=queue_size, keepalive_ping_interval_seconds=keepalive_ping_interval_seconds, keepalive_ping_timeout_seconds=keepalive_ping_timeout_seconds, subprotocols=subprotocols, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) as session: yield session def send( self, request: Request, *, stream: bool = False, auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, ) -> Response: """ Send a request. The request is sent as-is, unmodified. Typically you'll want to build one with `Client.build_request()` so that any client-level configuration is merged into the request, but passing an explicit `httpx2.Request()` is supported as well. See also: [Request instances][0] [0]: advanced/clients.md#request-instances """ if self._state == ClientState.CLOSED: raise RuntimeError("Cannot send a request, as the client has been closed.") self._state = ClientState.OPENED follow_redirects = self.follow_redirects if isinstance(follow_redirects, UseClientDefault) else follow_redirects self._set_timeout(request) auth = self._build_request_auth(request, auth) response = self._send_handling_auth( request, auth=auth, follow_redirects=follow_redirects, history=[], ) try: if not stream: response.read() return response except BaseException as exc: response.close() raise exc def _send_handling_auth( self, request: Request, auth: Auth, follow_redirects: bool, history: list[Response], ) -> Response: auth_flow = auth.sync_auth_flow(request) try: request = next(auth_flow) while True: response = self._send_handling_redirects( request, follow_redirects=follow_redirects, history=history, ) try: try: next_request = auth_flow.send(response) except StopIteration: return response response.history = list(history) response.read() request = next_request history.append(response) except BaseException as exc: response.close() raise exc finally: auth_flow.close() def _send_handling_redirects( self, request: Request, follow_redirects: bool, history: list[Response], ) -> Response: while True: if len(history) > self.max_redirects: raise TooManyRedirects("Exceeded maximum allowed redirects.", request=request) for hook in self._event_hooks["request"]: hook(request) response = self._send_single_request(request) try: for hook in self._event_hooks["response"]: hook(response) response.history = list(history) if not response.has_redirect_location: return response request = self._build_redirect_request(request, response) history = history + [response] if follow_redirects: response.read() else: response.next_request = request return response except BaseException as exc: response.close() raise exc def _send_single_request(self, request: Request) -> Response: """ Sends a single request, without handling any redirections. """ transport = self._transport_for_url(request.url) start = time.perf_counter() if not isinstance(request.stream, SyncByteStream): raise RuntimeError("Attempted to send an async request with a sync Client instance.") with request_context(request=request): response = transport.handle_request(request) assert isinstance(response.stream, SyncByteStream) response.request = request response.stream = BoundSyncStream(response.stream, start=start) self.cookies.extract_cookies(response) response.default_encoding = self._default_encoding logger.info( 'HTTP Request: %s %s "%s %d %s"', request.method, request.url, response.http_version, response.status_code, response.reason_phrase, ) return response def get( self, url: URL | str, *, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Response: """ Send a `GET` request. **Parameters**: See `httpx2.request`. """ return self.request( "GET", url, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) def options( self, url: URL | str, *, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Response: """ Send an `OPTIONS` request. **Parameters**: See `httpx2.request`. """ return self.request( "OPTIONS", url, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) def head( self, url: URL | str, *, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Response: """ Send a `HEAD` request. **Parameters**: See `httpx2.request`. """ return self.request( "HEAD", url, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) def post( self, url: URL | str, *, content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: typing.Any | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Response: """ Send a `POST` request. **Parameters**: See `httpx2.request`. """ return self.request( "POST", url, content=content, data=data, files=files, json=json, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) def put( self, url: URL | str, *, content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: typing.Any | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Response: """ Send a `PUT` request. **Parameters**: See `httpx2.request`. """ return self.request( "PUT", url, content=content, data=data, files=files, json=json, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) def patch( self, url: URL | str, *, content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: typing.Any | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Response: """ Send a `PATCH` request. **Parameters**: See `httpx2.request`. """ return self.request( "PATCH", url, content=content, data=data, files=files, json=json, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) def delete( self, url: URL | str, *, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Response: """ Send a `DELETE` request. **Parameters**: See `httpx2.request`. """ return self.request( "DELETE", url, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) def query( self, url: URL | str, *, content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: typing.Any | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Response: """ Send a `QUERY` request. **Parameters**: See `httpx2.request`. """ return self.request( "QUERY", url, content=content, data=data, files=files, json=json, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) def close(self) -> None: """ Close transport and proxies. """ if self._state != ClientState.CLOSED: self._state = ClientState.CLOSED self._transport.close() for transport in self._mounts.values(): if transport is not None: transport.close() def __enter__(self: T) -> T: if self._state != ClientState.UNOPENED: msg = { ClientState.OPENED: "Cannot open a client instance more than once.", ClientState.CLOSED: ("Cannot reopen a client instance, once it has been closed."), }[self._state] raise RuntimeError(msg) self._state = ClientState.OPENED self._transport.__enter__() for transport in self._mounts.values(): if transport is not None: transport.__enter__() return self def __exit__( self, exc_type: type[BaseException] | None = None, exc_value: BaseException | None = None, traceback: TracebackType | None = None, ) -> None: self._state = ClientState.CLOSED self._transport.__exit__(exc_type, exc_value, traceback) for transport in self._mounts.values(): if transport is not None: transport.__exit__(exc_type, exc_value, traceback) class AsyncClient(BaseClient): """ An asynchronous HTTP client, with connection pooling, HTTP/2, redirects, cookie persistence, etc. It can be shared between tasks. Usage: ```python >>> async with httpx2.AsyncClient() as client: >>> response = await client.get('https://example.org') ``` **Parameters:** * **auth** - *(optional)* An authentication class to use when sending requests. * **params** - *(optional)* Query parameters to include in request URLs, as a string, dictionary, or sequence of two-tuples. * **headers** - *(optional)* Dictionary of HTTP headers to include when sending requests. * **cookies** - *(optional)* Dictionary of Cookie items to include when sending requests. * **verify** - *(optional)* Either `True` to use an SSL context with the default CA bundle, `False` to disable verification, or an instance of `ssl.SSLContext` to use a custom context. * **http2** - *(optional)* A boolean indicating if HTTP/2 support should be enabled. Defaults to `False`. * **proxy** - *(optional)* A proxy URL where all the traffic should be routed. * **mounts** - *(optional)* A dictionary mapping URL patterns to transports, used to route requests through specific transports based on the URL. * **timeout** - *(optional)* The timeout configuration to use when sending requests. * **limits** - *(optional)* The limits configuration to use. * **max_redirects** - *(optional)* The maximum number of redirect responses that should be followed. * **base_url** - *(optional)* A URL to use as the base when building request URLs. * **transport** - *(optional)* A transport class to use for sending requests over the network. * **trust_env** - *(optional)* Enables or disables usage of environment variables for configuration. * **default_encoding** - *(optional)* The default encoding to use for decoding response text, if no charset information is included in a response Content-Type header. Set to a callable for automatic character set detection. Default: "utf-8". """ def __init__( self, *, auth: AuthTypes | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, verify: ssl.SSLContext | str | bool = True, cert: CertTypes | None = None, http1: bool = True, http2: bool = False, proxy: ProxyTypes | None = None, mounts: None | (typing.Mapping[str, AsyncBaseTransport | None]) = None, timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG, follow_redirects: bool = False, limits: Limits = DEFAULT_LIMITS, max_redirects: int = DEFAULT_MAX_REDIRECTS, event_hooks: None | (typing.Mapping[str, list[EventHook]]) = None, base_url: URL | str = "", transport: AsyncBaseTransport | None = None, trust_env: bool = True, default_encoding: str | typing.Callable[[bytes], str | None] = "utf-8", ) -> None: super().__init__( auth=auth, params=params, headers=headers, cookies=cookies, timeout=timeout, follow_redirects=follow_redirects, max_redirects=max_redirects, event_hooks=event_hooks, base_url=base_url, trust_env=trust_env, default_encoding=default_encoding, ) if http2: try: import h2 # noqa except ImportError: # pragma: no cover raise ImportError( "Using http2=True, but the 'h2' package is not installed. " "Make sure to install httpx using `pip install httpx[http2]`." ) from None allow_env_proxies = trust_env and transport is None proxy_map = self._get_proxy_map(proxy, allow_env_proxies) self._transport = self._init_transport( verify=verify, cert=cert, trust_env=trust_env, http1=http1, http2=http2, limits=limits, transport=transport, ) self._mounts: dict[URLPattern, AsyncBaseTransport | None] = { URLPattern(key): None if proxy is None else self._init_proxy_transport( proxy, verify=verify, cert=cert, trust_env=trust_env, http1=http1, http2=http2, limits=limits, ) for key, proxy in proxy_map.items() } if mounts is not None: self._mounts.update({URLPattern(key): transport for key, transport in mounts.items()}) self._mounts = dict(sorted(self._mounts.items())) def _init_transport( self, verify: ssl.SSLContext | str | bool = True, cert: CertTypes | None = None, trust_env: bool = True, http1: bool = True, http2: bool = False, limits: Limits = DEFAULT_LIMITS, transport: AsyncBaseTransport | None = None, ) -> AsyncBaseTransport: if transport is not None: return transport return AsyncHTTPTransport( verify=verify, cert=cert, trust_env=trust_env, http1=http1, http2=http2, limits=limits, ) def _init_proxy_transport( self, proxy: Proxy, verify: ssl.SSLContext | str | bool = True, cert: CertTypes | None = None, trust_env: bool = True, http1: bool = True, http2: bool = False, limits: Limits = DEFAULT_LIMITS, ) -> AsyncBaseTransport: return AsyncHTTPTransport( verify=verify, cert=cert, trust_env=trust_env, http1=http1, http2=http2, limits=limits, proxy=proxy, ) def _transport_for_url(self, url: URL) -> AsyncBaseTransport: """ Returns the transport instance that should be used for a given URL. This will either be the standard connection pool, or a proxy. """ for pattern, transport in self._mounts.items(): if pattern.matches(url): return self._transport if transport is None else transport return self._transport async def request( self, method: str, url: URL | str, *, content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: typing.Any | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Response: """ Build and send a request. Equivalent to: ```python request = client.build_request(...) response = await client.send(request, ...) ``` See `AsyncClient.build_request()`, `AsyncClient.send()` and [Merging of configuration][0] for how the various parameters are merged with client-level configuration. [0]: advanced/clients.md#merging-of-configuration """ if cookies is not None: # pragma: no cover message = ( "Setting per-request cookies=<...> is being deprecated, because " "the expected behaviour on cookie persistence is ambiguous. Set " "cookies directly on the client instance instead." ) warnings.warn(message, DeprecationWarning, stacklevel=2) request = self.build_request( method=method, url=url, content=content, data=data, files=files, json=json, params=params, headers=headers, cookies=cookies, timeout=timeout, extensions=extensions, ) return await self.send(request, auth=auth, follow_redirects=follow_redirects) @asynccontextmanager async def stream( self, method: str, url: URL | str, *, content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: typing.Any | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> AsyncGenerator[Response]: """ Alternative to `httpx2.request()` that streams the response body instead of loading it into memory at once. **Parameters**: See `httpx2.request`. See also: [Streaming Responses][0] [0]: quickstart.md#streaming-responses """ request = self.build_request( method=method, url=url, content=content, data=data, files=files, json=json, params=params, headers=headers, cookies=cookies, timeout=timeout, extensions=extensions, ) response = await self.send( request=request, auth=auth, follow_redirects=follow_redirects, stream=True, ) try: yield response finally: await response.aclose() @asynccontextmanager async def sse( self, url: URL | str, *, method: str = "GET", content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: typing.Any | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, max_event_size: int | None = DEFAULT_MAX_EVENT_SIZE_BYTES, ) -> AsyncGenerator[EventSource]: """ Connect to a server-sent events endpoint and yield an `EventSource`. Iterating the `EventSource` yields `ServerSentEvent` instances. **Parameters**: See `httpx2.request`. """ async with self.stream( method, url, content=content, data=data, files=files, json=json, params=params, headers={"Accept": "text/event-stream", "Cache-Control": "no-store"} | Headers(headers), cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) as response: yield EventSource(response, max_event_size=max_event_size) @asynccontextmanager async def websocket( self, url: URL | str, *, max_message_size_bytes: int = DEFAULT_MAX_MESSAGE_SIZE_BYTES, queue_size: int = DEFAULT_QUEUE_SIZE, keepalive_ping_interval_seconds: float | None = DEFAULT_KEEPALIVE_PING_INTERVAL_SECONDS, keepalive_ping_timeout_seconds: float | None = DEFAULT_KEEPALIVE_PING_TIMEOUT_SECONDS, subprotocols: list[str] | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> AsyncGenerator[AsyncWebSocketSession]: """ Open a WebSocket session, using this client's configuration. The session is closed automatically when exiting the context manager. ```python async with httpx2.AsyncClient() as client: async with client.websocket("ws://localhost:8000/ws") as ws: await ws.send_text("Hello!") message = await ws.receive_text() ``` """ try: from .websockets._api import aconnect_ws except ImportError: # pragma: no cover raise ImportError( "WebSocket support requires the `wsproto` package. Install it with `pip install httpx2[ws]`." ) async with aconnect_ws( str(url), self, max_message_size_bytes=max_message_size_bytes, queue_size=queue_size, keepalive_ping_interval_seconds=keepalive_ping_interval_seconds, keepalive_ping_timeout_seconds=keepalive_ping_timeout_seconds, subprotocols=subprotocols, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) as session: yield session async def send( self, request: Request, *, stream: bool = False, auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, ) -> Response: """ Send a request. The request is sent as-is, unmodified. Typically you'll want to build one with `AsyncClient.build_request()` so that any client-level configuration is merged into the request, but passing an explicit `httpx2.Request()` is supported as well. See also: [Request instances][0] [0]: advanced/clients.md#request-instances """ if self._state == ClientState.CLOSED: raise RuntimeError("Cannot send a request, as the client has been closed.") self._state = ClientState.OPENED follow_redirects = self.follow_redirects if isinstance(follow_redirects, UseClientDefault) else follow_redirects self._set_timeout(request) auth = self._build_request_auth(request, auth) response = await self._send_handling_auth( request, auth=auth, follow_redirects=follow_redirects, history=[], ) try: if not stream: await response.aread() return response except BaseException as exc: await response.aclose() raise exc async def _send_handling_auth( self, request: Request, auth: Auth, follow_redirects: bool, history: list[Response], ) -> Response: auth_flow = auth.async_auth_flow(request) try: request = await auth_flow.__anext__() while True: response = await self._send_handling_redirects( request, follow_redirects=follow_redirects, history=history, ) try: try: next_request = await auth_flow.asend(response) except StopAsyncIteration: return response response.history = list(history) await response.aread() request = next_request history.append(response) except BaseException as exc: await response.aclose() raise exc finally: await auth_flow.aclose() async def _send_handling_redirects( self, request: Request, follow_redirects: bool, history: list[Response], ) -> Response: while True: if len(history) > self.max_redirects: raise TooManyRedirects("Exceeded maximum allowed redirects.", request=request) for hook in self._event_hooks["request"]: await hook(request) response = await self._send_single_request(request) try: for hook in self._event_hooks["response"]: await hook(response) response.history = list(history) if not response.has_redirect_location: return response request = self._build_redirect_request(request, response) history = history + [response] if follow_redirects: await response.aread() else: response.next_request = request return response except BaseException as exc: await response.aclose() raise exc async def _send_single_request(self, request: Request) -> Response: """ Sends a single request, without handling any redirections. """ transport = self._transport_for_url(request.url) start = time.perf_counter() if not isinstance(request.stream, AsyncByteStream): raise RuntimeError("Attempted to send a sync request with an AsyncClient instance.") with request_context(request=request): response = await transport.handle_async_request(request) assert isinstance(response.stream, AsyncByteStream) response.request = request response.stream = BoundAsyncStream(response.stream, start=start) self.cookies.extract_cookies(response) response.default_encoding = self._default_encoding logger.info( 'HTTP Request: %s %s "%s %d %s"', request.method, request.url, response.http_version, response.status_code, response.reason_phrase, ) return response async def get( self, url: URL | str, *, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Response: """ Send a `GET` request. **Parameters**: See `httpx2.request`. """ return await self.request( "GET", url, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) async def options( self, url: URL | str, *, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Response: """ Send an `OPTIONS` request. **Parameters**: See `httpx2.request`. """ return await self.request( "OPTIONS", url, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) async def head( self, url: URL | str, *, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Response: """ Send a `HEAD` request. **Parameters**: See `httpx2.request`. """ return await self.request( "HEAD", url, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) async def post( self, url: URL | str, *, content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: typing.Any | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Response: """ Send a `POST` request. **Parameters**: See `httpx2.request`. """ return await self.request( "POST", url, content=content, data=data, files=files, json=json, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) async def put( self, url: URL | str, *, content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: typing.Any | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Response: """ Send a `PUT` request. **Parameters**: See `httpx2.request`. """ return await self.request( "PUT", url, content=content, data=data, files=files, json=json, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) async def patch( self, url: URL | str, *, content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: typing.Any | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Response: """ Send a `PATCH` request. **Parameters**: See `httpx2.request`. """ return await self.request( "PATCH", url, content=content, data=data, files=files, json=json, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) async def delete( self, url: URL | str, *, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Response: """ Send a `DELETE` request. **Parameters**: See `httpx2.request`. """ return await self.request( "DELETE", url, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) async def query( self, url: URL | str, *, content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: typing.Any | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Response: """ Send a `QUERY` request. **Parameters**: See `httpx2.request`. """ return await self.request( "QUERY", url, content=content, data=data, files=files, json=json, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) async def aclose(self) -> None: """ Close transport and proxies. """ if self._state != ClientState.CLOSED: self._state = ClientState.CLOSED await self._transport.aclose() for proxy in self._mounts.values(): if proxy is not None: await proxy.aclose() async def __aenter__(self: U) -> U: if self._state != ClientState.UNOPENED: msg = { ClientState.OPENED: "Cannot open a client instance more than once.", ClientState.CLOSED: ("Cannot reopen a client instance, once it has been closed."), }[self._state] raise RuntimeError(msg) self._state = ClientState.OPENED await self._transport.__aenter__() for proxy in self._mounts.values(): if proxy is not None: await proxy.__aenter__() return self async def __aexit__( self, exc_type: type[BaseException] | None = None, exc_value: BaseException | None = None, traceback: TracebackType | None = None, ) -> None: self._state = ClientState.CLOSED await self._transport.__aexit__(exc_type, exc_value, traceback) for proxy in self._mounts.values(): if proxy is not None: await proxy.__aexit__(exc_type, exc_value, traceback) pydantic-httpx2-6dd59b9/src/httpx2/httpx2/_config.py000066400000000000000000000164161526547463400224630ustar00rootroot00000000000000from __future__ import annotations import dataclasses import os import typing from ._models import Headers from ._types import CertTypes, HeaderTypes, TimeoutTypes from ._urls import URL if typing.TYPE_CHECKING: import ssl # pragma: no cover __all__ = ["Limits", "Proxy", "Timeout", "create_ssl_context"] class UnsetType: pass # pragma: no cover UNSET = UnsetType() def create_ssl_context( verify: ssl.SSLContext | str | bool = True, cert: CertTypes | None = None, trust_env: bool = True, ) -> ssl.SSLContext: import ssl import warnings import httpcore2 if verify is True: ctx = httpcore2.default_ssl_context(_trust_env=trust_env) elif verify is False: ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE elif isinstance(verify, str): if cert: raise TypeError( "`verify=` cannot be combined with `cert=...`. " "Build an `ssl.SSLContext` and pass it as `verify=`, " "using `.load_cert_chain()` to configure the certificate chain." ) message = ( "`verify=` is deprecated. " "Use `verify=ssl.create_default_context(cafile=...)` " "or `verify=ssl.create_default_context(capath=...)` instead." ) warnings.warn(message, DeprecationWarning) if os.path.isdir(verify): # pragma: no cover return ssl.create_default_context(capath=verify) return ssl.create_default_context(cafile=verify) else: ctx = verify if cert: # pragma: no cover message = ( "`cert=...` is deprecated. Use `verify=` instead," "with `.load_cert_chain()` to configure the certificate chain." ) warnings.warn(message, DeprecationWarning) if isinstance(cert, str): ctx.load_cert_chain(cert) else: ctx.load_cert_chain(*cert) return ctx @dataclasses.dataclass(init=False, repr=False) class Timeout: """ Timeout configuration. **Usage**: Timeout(None) # No timeouts. Timeout(5.0) # 5s timeout on all operations. Timeout(None, connect=5.0) # 5s timeout on connect, no other timeouts. Timeout(5.0, connect=10.0) # 10s timeout on connect. 5s timeout elsewhere. Timeout(5.0, pool=None) # No timeout on acquiring connection from pool. # 5s timeout elsewhere. """ connect: float | None read: float | None write: float | None pool: float | None def __init__( self, timeout: TimeoutTypes | UnsetType = UNSET, *, connect: None | float | UnsetType = UNSET, read: None | float | UnsetType = UNSET, write: None | float | UnsetType = UNSET, pool: None | float | UnsetType = UNSET, ) -> None: if isinstance(timeout, Timeout): # Passed as a single explicit Timeout. assert connect is UNSET assert read is UNSET assert write is UNSET assert pool is UNSET self.connect = timeout.connect self.read = timeout.read self.write = timeout.write self.pool = timeout.pool elif isinstance(timeout, tuple): # Passed as a tuple. self.connect = timeout[0] self.read = timeout[1] self.write = None if len(timeout) < 3 else timeout[2] self.pool = None if len(timeout) < 4 else timeout[3] elif not ( isinstance(connect, UnsetType) or isinstance(read, UnsetType) or isinstance(write, UnsetType) or isinstance(pool, UnsetType) ): self.connect = connect self.read = read self.write = write self.pool = pool else: if isinstance(timeout, UnsetType): raise ValueError("httpx2.Timeout must either include a default, or set all four parameters explicitly.") self.connect = timeout if isinstance(connect, UnsetType) else connect self.read = timeout if isinstance(read, UnsetType) else read self.write = timeout if isinstance(write, UnsetType) else write self.pool = timeout if isinstance(pool, UnsetType) else pool def as_dict(self) -> dict[str, float | None]: return { "connect": self.connect, "read": self.read, "write": self.write, "pool": self.pool, } def __repr__(self) -> str: class_name = self.__class__.__name__ if len({self.connect, self.read, self.write, self.pool}) == 1: return f"{class_name}(timeout={self.connect})" return f"{class_name}(connect={self.connect}, read={self.read}, write={self.write}, pool={self.pool})" @dataclasses.dataclass(kw_only=True) class Limits: """ Configuration for limits to various client behaviors. **Parameters:** * **max_connections** - The maximum number of concurrent connections that may be established. * **max_keepalive_connections** - Allow the connection pool to maintain keep-alive connections below this point. Should be less than or equal to `max_connections`. * **keepalive_expiry** - Time limit on idle keep-alive connections in seconds. """ max_connections: int | None = None max_keepalive_connections: int | None = None keepalive_expiry: float | None = 5.0 class Proxy: def __init__( self, url: URL | str, *, ssl_context: ssl.SSLContext | None = None, auth: tuple[str, str] | None = None, headers: HeaderTypes | None = None, ) -> None: url = URL(url) headers = Headers(headers) if url.scheme not in ("http", "https", "socks5", "socks5h"): raise ValueError(f"Unknown scheme for proxy URL {url!r}") if url.username or url.password: # Remove any auth credentials from the URL. auth = (url.username, url.password) url = url.copy_with(username=None, password=None) self.url = url self.auth = auth self.headers = headers self.ssl_context = ssl_context @property def raw_auth(self) -> tuple[bytes, bytes] | None: # The proxy authentication as raw bytes. return None if self.auth is None else (self.auth[0].encode("utf-8"), self.auth[1].encode("utf-8")) def __repr__(self) -> str: # The authentication is represented with the password component masked. auth = (self.auth[0], "********") if self.auth else None # Build a nice concise representation. url_str = f"{str(self.url)!r}" auth_str = f", auth={auth!r}" if auth else "" headers_str = f", headers={dict(self.headers)!r}" if self.headers else "" return f"Proxy({url_str}{auth_str}{headers_str})" DEFAULT_TIMEOUT_CONFIG = Timeout(timeout=5.0) DEFAULT_LIMITS = Limits(max_connections=100, max_keepalive_connections=20) DEFAULT_MAX_REDIRECTS = 20 DEFAULT_MAX_EVENT_SIZE_BYTES = 1024 * 1024 DEFAULT_MAX_MESSAGE_SIZE_BYTES = 65_536 DEFAULT_QUEUE_SIZE = 512 DEFAULT_KEEPALIVE_PING_INTERVAL_SECONDS = 20.0 DEFAULT_KEEPALIVE_PING_TIMEOUT_SECONDS = 20.0 pydantic-httpx2-6dd59b9/src/httpx2/httpx2/_content.py000066400000000000000000000204521526547463400226630ustar00rootroot00000000000000from __future__ import annotations import inspect import warnings from collections.abc import AsyncGenerator, AsyncIterable, AsyncIterator, Iterable, Iterator, Mapping from json import dumps as json_dumps from typing import ( Any, ) from urllib.parse import urlencode from ._exceptions import StreamClosed, StreamConsumed from ._multipart import MultipartStream from ._types import ( AsyncByteStream, RequestContent, RequestData, RequestFiles, ResponseContent, SyncByteStream, ) from ._utils import peek_filelike_remaining_length, primitive_value_to_str __all__ = ["ByteStream"] class ByteStream(AsyncByteStream, SyncByteStream): def __init__(self, stream: bytes) -> None: self._stream = stream def __iter__(self) -> Iterator[bytes]: yield self._stream async def __aiter__(self) -> AsyncIterator[bytes]: yield self._stream class IteratorByteStream(SyncByteStream): CHUNK_SIZE = 65_536 def __init__(self, stream: Iterable[bytes]) -> None: self._stream = stream self._is_stream_consumed = False self._is_generator = inspect.isgenerator(stream) def __iter__(self) -> Iterator[bytes]: if self._is_stream_consumed and self._is_generator: raise StreamConsumed() self._is_stream_consumed = True if hasattr(self._stream, "read"): # File-like interfaces should use 'read' directly. chunk = self._stream.read(self.CHUNK_SIZE) while chunk: yield chunk chunk = self._stream.read(self.CHUNK_SIZE) else: # Otherwise iterate. yield from self._stream class AsyncIteratorByteStream(AsyncByteStream): CHUNK_SIZE = 65_536 def __init__(self, stream: AsyncIterable[bytes]) -> None: self._stream = stream self._is_stream_consumed = False self._is_generator = inspect.isasyncgen(stream) async def __aiter__(self) -> AsyncIterator[bytes]: if self._is_stream_consumed and self._is_generator: raise StreamConsumed() self._is_stream_consumed = True if hasattr(self._stream, "aread"): # File-like interfaces should use 'aread' directly. chunk = await self._stream.aread(self.CHUNK_SIZE) while chunk: yield chunk chunk = await self._stream.aread(self.CHUNK_SIZE) else: # Otherwise iterate, making sure the wrapped stream is closed even if the # consumer stops early (e.g. an exception is raised part-way through decoding). stream = self._stream.__aiter__() try: async for part in stream: yield part finally: if isinstance(stream, AsyncGenerator): await stream.aclose() class UnattachedStream(AsyncByteStream, SyncByteStream): """ If a request or response is serialized using pickle, then it is no longer attached to a stream for I/O purposes. Any stream operations should result in `httpx2.StreamClosed`. """ def __iter__(self) -> Iterator[bytes]: raise StreamClosed() async def __aiter__(self) -> AsyncIterator[bytes]: raise StreamClosed() yield b"" # pragma: no cover def encode_content( content: str | bytes | Iterable[bytes] | AsyncIterable[bytes], ) -> tuple[dict[str, str], SyncByteStream | AsyncByteStream]: if isinstance(content, (bytes, str)): body = content.encode("utf-8") if isinstance(content, str) else content content_length = len(body) headers = {"Content-Length": str(content_length)} if body else {} return headers, ByteStream(body) elif isinstance(content, Iterable) and not isinstance(content, dict): # `not isinstance(content, dict)` is a bit oddly specific, but it # catches a case that's easy for users to make in error, and would # otherwise pass through here, like any other bytes-iterable, # because `dict` happens to be iterable. See issue #2491. content_length_or_none = peek_filelike_remaining_length(content) if content_length_or_none is None: headers = {"Transfer-Encoding": "chunked"} else: headers = {"Content-Length": str(content_length_or_none)} return headers, IteratorByteStream(content) elif isinstance(content, AsyncIterable): headers = {"Transfer-Encoding": "chunked"} return headers, AsyncIteratorByteStream(content) raise TypeError(f"Unexpected type for 'content', {type(content)!r}") def encode_urlencoded_data(data: RequestData) -> tuple[dict[str, str], ByteStream]: plain_data: list[tuple[str, str]] = [] for key, value in data.items(): if isinstance(value, (list, tuple)): plain_data.extend([(key, primitive_value_to_str(item)) for item in value]) else: plain_data.append((key, primitive_value_to_str(value))) body = urlencode(plain_data, doseq=True).encode("utf-8") content_length = str(len(body)) content_type = "application/x-www-form-urlencoded" headers = {"Content-Length": content_length, "Content-Type": content_type} return headers, ByteStream(body) def encode_multipart_data( data: RequestData, files: RequestFiles, boundary: bytes | None ) -> tuple[dict[str, str], MultipartStream]: multipart = MultipartStream(data=data, files=files, boundary=boundary) headers = multipart.get_headers() return headers, multipart def encode_text(text: str) -> tuple[dict[str, str], ByteStream]: body = text.encode("utf-8") content_length = str(len(body)) content_type = "text/plain; charset=utf-8" headers = {"Content-Length": content_length, "Content-Type": content_type} return headers, ByteStream(body) def encode_html(html: str) -> tuple[dict[str, str], ByteStream]: body = html.encode("utf-8") content_length = str(len(body)) content_type = "text/html; charset=utf-8" headers = {"Content-Length": content_length, "Content-Type": content_type} return headers, ByteStream(body) def encode_json(json: Any) -> tuple[dict[str, str], ByteStream]: body = json_dumps(json, ensure_ascii=False, separators=(",", ":"), allow_nan=False).encode("utf-8") content_length = str(len(body)) content_type = "application/json" headers = {"Content-Length": content_length, "Content-Type": content_type} return headers, ByteStream(body) def encode_request( content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: Any | None = None, boundary: bytes | None = None, ) -> tuple[dict[str, str], SyncByteStream | AsyncByteStream]: """ Handles encoding the given `content`, `data`, `files`, and `json`, returning a two-tuple of (, ). """ if data is not None and not isinstance(data, Mapping): # We prefer to separate `content=` # for raw request content, and `data=
` for url encoded or # multipart form content. # # However for compat with requests, we *do* still support # `data=` usages. We deal with that case here, treating it # as if `content=<...>` had been supplied instead. message = "Use 'content=<...>' to upload raw bytes/text content." warnings.warn(message, DeprecationWarning, stacklevel=2) return encode_content(data) if content is not None: return encode_content(content) elif files: return encode_multipart_data(data or {}, files, boundary) elif data: return encode_urlencoded_data(data) elif json is not None: return encode_json(json) return {}, ByteStream(b"") def encode_response( content: ResponseContent | None = None, text: str | None = None, html: str | None = None, json: Any | None = None, ) -> tuple[dict[str, str], SyncByteStream | AsyncByteStream]: """ Handles encoding the given `content`, returning a two-tuple of (, ). """ if content is not None: return encode_content(content) elif text is not None: return encode_text(text) elif html is not None: return encode_html(html) elif json is not None: return encode_json(json) return {}, ByteStream(b"") pydantic-httpx2-6dd59b9/src/httpx2/httpx2/_decoders.py000066400000000000000000000353061526547463400230050ustar00rootroot00000000000000""" Handlers for Content-Encoding. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding """ from __future__ import annotations import codecs import io import itertools import sys import typing import zlib from ._exceptions import DecodingError # Brotli support is optional try: # The C bindings in `brotli` are recommended for CPython. import brotli except ImportError: # pragma: no cover try: # The CFFI bindings in `brotlicffi` are recommended for PyPy # and other environments. import brotlicffi as brotli except ImportError: brotli = None # Zstandard support is optional on Python <= 3.13. # On Python 3.14+, the stdlib includes an optional built-in zstd implementation. if typing.TYPE_CHECKING: if sys.version_info >= (3, 14): from compression.zstd import ZstdDecompressor, ZstdError else: from backports.zstd import ZstdDecompressor, ZstdError _zstandard_installed: bool else: # pragma: no cover try: if sys.version_info >= (3, 14): from compression.zstd import ZstdDecompressor, ZstdError else: from backports.zstd import ZstdDecompressor, ZstdError _zstandard_installed = True except ImportError: _zstandard_installed = False MAX_DECODE_CHUNK_SIZE = 2**20 # 1 MiB class Decompressor(typing.Protocol): @property def unconsumed_tail(self) -> bytes: ... def decompress(self, data: bytes, max_length: int) -> bytes: ... def flush(self) -> bytes: ... class ZlibDecompressor: """ Drain a `zlib`/`gzip` decompressor in bounded pieces so a small compressed input cannot inflate to an unbounded buffer in a single call. """ def __init__(self, decompressor: Decompressor) -> None: self.decompressor = decompressor def decompress(self, data: bytes) -> typing.Iterator[bytes]: decompressed = self.decompressor.decompress(data, MAX_DECODE_CHUNK_SIZE) while decompressed: yield decompressed decompressed = self.decompressor.decompress(self.decompressor.unconsumed_tail, MAX_DECODE_CHUNK_SIZE) def flush(self) -> bytes: return self.decompressor.flush() class ContentDecoder: def decode(self, data: bytes) -> typing.Iterator[bytes]: raise NotImplementedError() # pragma: no cover def flush(self) -> typing.Iterator[bytes]: raise NotImplementedError() # pragma: no cover class IdentityDecoder(ContentDecoder): """ Handle unencoded data. """ def decode(self, data: bytes) -> typing.Iterator[bytes]: yield data def flush(self) -> typing.Iterator[bytes]: yield from () class DeflateDecoder(ContentDecoder): """ Handle 'deflate' decoding. See: https://stackoverflow.com/questions/1838699 """ def __init__(self) -> None: self.first_attempt = True self.decompressor = ZlibDecompressor(zlib.decompressobj()) def decode(self, data: bytes) -> typing.Iterator[bytes]: was_first_attempt = self.first_attempt self.first_attempt = False try: yield from self.decompressor.decompress(data) except zlib.error as exc: if was_first_attempt: self.decompressor = ZlibDecompressor(zlib.decompressobj(-zlib.MAX_WBITS)) yield from self.decode(data) else: raise DecodingError(str(exc)) from exc def flush(self) -> typing.Iterator[bytes]: try: yield self.decompressor.flush() except zlib.error as exc: # pragma: no cover raise DecodingError(str(exc)) from exc class GZipDecoder(ContentDecoder): """ Handle 'gzip' decoding. See: https://stackoverflow.com/questions/1838699 """ def __init__(self) -> None: self.decompressor = ZlibDecompressor(zlib.decompressobj(zlib.MAX_WBITS | 16)) def decode(self, data: bytes) -> typing.Iterator[bytes]: try: yield from self.decompressor.decompress(data) except zlib.error as exc: raise DecodingError(str(exc)) from exc def flush(self) -> typing.Iterator[bytes]: try: yield self.decompressor.flush() except zlib.error as exc: # pragma: no cover raise DecodingError(str(exc)) from exc class BrotliDecoder(ContentDecoder): """ Handle 'brotli' decoding. Requires `pip install brotlipy`. See: https://brotlipy.readthedocs.io/ or `pip install brotli`. See https://github.com/google/brotli Supports both 'brotlipy' and 'Brotli' packages since they share an import name. The top branches are for 'brotlipy' and bottom branches for 'Brotli' """ def __init__(self) -> None: if brotli is None: # pragma: no cover raise ImportError( "Using 'BrotliDecoder', but neither of the 'brotlicffi' or 'brotli' " "packages have been installed. " "Make sure to install httpx using `pip install httpx[brotli]`." ) from None self.decompressor = brotli.Decompressor() self.seen_data = False self._decompress: typing.Callable[..., bytes] if hasattr(self.decompressor, "decompress"): # The 'brotlicffi' package. self._decompress = self.decompressor.decompress # pragma: no cover else: # The 'brotli' package. self._decompress = self.decompressor.process def decode(self, data: bytes) -> typing.Iterator[bytes]: if not data: return self.seen_data = True try: # The C backend may allocate nearly twice the requested threshold. output_buffer_limit = MAX_DECODE_CHUNK_SIZE // 2 decompressed = self._decompress(data, output_buffer_limit=output_buffer_limit) while decompressed: yield decompressed decompressed = self._decompress(b"", output_buffer_limit=output_buffer_limit) except brotli.error as exc: raise DecodingError(str(exc)) from exc def flush(self) -> typing.Iterator[bytes]: if not self.seen_data: return try: if hasattr(self.decompressor, "finish"): # Only available in the 'brotlicffi' package. # As the decompressor decompresses eagerly, this # will never actually emit any data. However, it will potentially throw # errors if a truncated or damaged data stream has been used. self.decompressor.finish() # pragma: no cover except brotli.error as exc: # pragma: no cover raise DecodingError(str(exc)) from exc yield from () class ZStandardDecoder(ContentDecoder): """Handle 'zstd' RFC 8878 decoding. On Python 3.13 and below, this requires `pip install httpx2[zstd]`. """ # inspired by the ZstdDecoder implementation in urllib3 def __init__(self) -> None: if not _zstandard_installed: # pragma: no cover raise ImportError( "Using 'ZStandardDecoder', ...Make sure to install httpx using `pip install httpx[zstd]`." ) from None self.decompressor = ZstdDecompressor() self.seen_data = False def decode(self, data: bytes) -> typing.Iterator[bytes]: if not data: return self.seen_data = True try: if self.decompressor.eof: data = self.decompressor.unused_data + data self.decompressor = ZstdDecompressor() while True: decompressed = self.decompressor.decompress(data, MAX_DECODE_CHUNK_SIZE) while decompressed: yield decompressed if self.decompressor.needs_input or self.decompressor.eof: break decompressed = self.decompressor.decompress(b"", MAX_DECODE_CHUNK_SIZE) if not (self.decompressor.eof and self.decompressor.unused_data): break data = self.decompressor.unused_data self.decompressor = ZstdDecompressor() except ZstdError as exc: raise DecodingError(str(exc)) from exc def flush(self) -> typing.Iterator[bytes]: if not self.seen_data: return if not self.decompressor.eof: raise DecodingError("Zstandard data is incomplete") # pragma: no cover yield from () class MultiDecoder(ContentDecoder): """ Handle the case where multiple encodings have been applied. """ max_decode_links: typing.ClassVar[int] = 5 def __init__(self, encodings: typing.Sequence[str]) -> None: """ 'encodings' should be the content codings in the order in which each was applied. """ codings = [encoding for encoding in encodings if encoding in SUPPORTED_DECODERS] if len(codings) > self.max_decode_links: raise DecodingError(f"Cannot apply more than {self.max_decode_links} content encodings.") # Note that we reverse the order for decoding. self.children: list[ContentDecoder] = [SUPPORTED_DECODERS[coding]() for coding in reversed(codings)] def decode(self, data: bytes) -> typing.Iterator[bytes]: streams: typing.Iterator[bytes] = iter((data,)) for child in self.children: streams = self._pipe(child.decode, streams) yield from streams def flush(self) -> typing.Iterator[bytes]: streams: typing.Iterator[bytes] = iter(()) for child in self.children: streams = itertools.chain(self._pipe(child.decode, streams), child.flush()) yield from streams @staticmethod def _pipe( decode: typing.Callable[[bytes], typing.Iterator[bytes]], upstream: typing.Iterator[bytes], ) -> typing.Iterator[bytes]: for chunk in upstream: yield from decode(chunk) class ByteChunker: """ Handles returning byte content in fixed-size chunks. """ def __init__(self, chunk_size: int | None = None) -> None: self._buffer = io.BytesIO() self._chunk_size = chunk_size def decode(self, content: bytes) -> list[bytes]: if self._chunk_size is None: return [content] if content else [] self._buffer.write(content) if self._buffer.tell() >= self._chunk_size: value = self._buffer.getvalue() chunks = [value[i : i + self._chunk_size] for i in range(0, len(value), self._chunk_size)] if len(chunks[-1]) == self._chunk_size: self._buffer.seek(0) self._buffer.truncate() return chunks else: self._buffer.seek(0) self._buffer.write(chunks[-1]) self._buffer.truncate() return chunks[:-1] else: return [] def flush(self) -> list[bytes]: value = self._buffer.getvalue() self._buffer.seek(0) self._buffer.truncate() return [value] if value else [] class TextChunker: """ Handles returning text content in fixed-size chunks. """ def __init__(self, chunk_size: int | None = None) -> None: self._buffer = io.StringIO() self._chunk_size = chunk_size def decode(self, content: str) -> list[str]: if self._chunk_size is None: return [content] if content else [] self._buffer.write(content) if self._buffer.tell() >= self._chunk_size: value = self._buffer.getvalue() chunks = [value[i : i + self._chunk_size] for i in range(0, len(value), self._chunk_size)] if len(chunks[-1]) == self._chunk_size: self._buffer.seek(0) self._buffer.truncate() return chunks else: self._buffer.seek(0) self._buffer.write(chunks[-1]) self._buffer.truncate() return chunks[:-1] else: return [] def flush(self) -> list[str]: value = self._buffer.getvalue() self._buffer.seek(0) self._buffer.truncate() return [value] if value else [] class TextDecoder: """ Handles incrementally decoding bytes into text """ def __init__(self, encoding: str = "utf-8") -> None: self.decoder = codecs.getincrementaldecoder(encoding)(errors="replace") def decode(self, data: bytes) -> str: return self.decoder.decode(data) def flush(self) -> str: return self.decoder.decode(b"", True) class LineDecoder: """ Handles incrementally reading lines from text. Has the same behaviour as the stdllib splitlines, but handling the input iteratively. """ def __init__(self) -> None: self.buffer: list[str] = [] self.trailing_cr: bool = False def decode(self, text: str) -> list[str]: # See https://docs.python.org/3/library/stdtypes.html#str.splitlines NEWLINE_CHARS = "\n\r\x0b\x0c\x1c\x1d\x1e\x85\u2028\u2029" # We always push a trailing `\r` into the next decode iteration. if self.trailing_cr: text = "\r" + text self.trailing_cr = False if text.endswith("\r"): self.trailing_cr = True text = text[:-1] if not text: # NOTE: the edge case input of empty text doesn't occur in practice, # because other httpx internals filter out this value return [] # pragma: no cover trailing_newline = text[-1] in NEWLINE_CHARS lines = text.splitlines() if len(lines) == 1 and not trailing_newline: # No new lines, buffer the input and continue. self.buffer.append(lines[0]) return [] if self.buffer: # Include any existing buffer in the first portion of the # splitlines result. lines = ["".join(self.buffer) + lines[0]] + lines[1:] self.buffer = [] if not trailing_newline: # If the last segment of splitlines is not newline terminated, # then drop it from our output and start a new buffer. self.buffer = [lines.pop()] return lines def flush(self) -> list[str]: if not self.buffer and not self.trailing_cr: return [] lines = ["".join(self.buffer)] self.buffer = [] self.trailing_cr = False return lines SUPPORTED_DECODERS: dict[str, type[ContentDecoder]] = { "identity": IdentityDecoder, "gzip": GZipDecoder, "deflate": DeflateDecoder, "br": BrotliDecoder, "zstd": ZStandardDecoder, } if brotli is None: SUPPORTED_DECODERS.pop("br") # pragma: no cover if not _zstandard_installed: SUPPORTED_DECODERS.pop("zstd") # pragma: no cover pydantic-httpx2-6dd59b9/src/httpx2/httpx2/_exceptions.py000066400000000000000000000212311526547463400233660ustar00rootroot00000000000000""" Our exception hierarchy: * HTTPError x RequestError + TransportError - TimeoutException ยท ConnectTimeout ยท ReadTimeout ยท WriteTimeout ยท PoolTimeout - NetworkError ยท ConnectError ยท ReadError ยท WriteError ยท CloseError - ProtocolError ยท LocalProtocolError ยท RemoteProtocolError - ProxyError - UnsupportedProtocol + DecodingError + TooManyRedirects x HTTPStatusError * InvalidURL * CookieConflict * StreamError x StreamConsumed x StreamClosed x ResponseNotRead x RequestNotRead """ from __future__ import annotations import contextlib import typing from collections.abc import Generator if typing.TYPE_CHECKING: from ._models import Request, Response # pragma: no cover __all__ = [ "CloseError", "ConnectError", "ConnectTimeout", "CookieConflict", "DecodingError", "HTTPError", "HTTPStatusError", "InvalidURL", "LocalProtocolError", "NetworkError", "PoolTimeout", "ProtocolError", "ProxyError", "ReadError", "ReadTimeout", "RemoteProtocolError", "RequestError", "RequestNotRead", "ResponseNotRead", "StreamClosed", "StreamConsumed", "StreamError", "TimeoutException", "TooManyRedirects", "TransportError", "UnsupportedProtocol", "WriteError", "WriteTimeout", ] class HTTPXDeprecationWarning(UserWarning): """A custom deprecation warning for HTTPX. Unlike the built-in `DeprecationWarning`, this inherits from `UserWarning` to ensure it is visible by default, helping users discover deprecated features without needing to enable warnings explicitly. Reference: https://sethmlarson.dev/deprecations-via-warnings-dont-work-for-python-libraries """ class HTTPError(Exception): """ Base class for `RequestError` and `HTTPStatusError`. Useful for `try...except` blocks when issuing a request, and then calling `.raise_for_status()`. For example: ``` try: response = httpx2.get("https://www.example.com") response.raise_for_status() except httpx2.HTTPError as exc: print(f"HTTP Exception for {exc.request.url} - {exc}") ``` """ def __init__(self, message: str) -> None: super().__init__(message) self._request: Request | None = None @property def request(self) -> Request: if self._request is None: raise RuntimeError("The .request property has not been set.") return self._request @request.setter def request(self, request: Request) -> None: self._request = request class RequestError(HTTPError): """ Base class for all exceptions that may occur when issuing a `.request()`. """ def __init__(self, message: str, *, request: Request | None = None) -> None: super().__init__(message) # At the point an exception is raised we won't typically have a request # instance to associate it with. # # The 'request_context' context manager is used within the Client and # Response methods in order to ensure that any raised exceptions # have a `.request` property set on them. self._request = request class TransportError(RequestError): """ Base class for all exceptions that occur at the level of the Transport API. """ # Timeout exceptions... class TimeoutException(TransportError): """ The base class for timeout errors. An operation has timed out. """ class ConnectTimeout(TimeoutException): """ Timed out while connecting to the host. """ class ReadTimeout(TimeoutException): """ Timed out while receiving data from the host. """ class WriteTimeout(TimeoutException): """ Timed out while sending data to the host. """ class PoolTimeout(TimeoutException): """ Timed out waiting to acquire a connection from the pool. """ # Core networking exceptions... class NetworkError(TransportError): """ The base class for network-related errors. An error occurred while interacting with the network. """ class ReadError(NetworkError): """ Failed to receive data from the network. """ class WriteError(NetworkError): """ Failed to send data through the network. """ class ConnectError(NetworkError): """ Failed to establish a connection. """ class CloseError(NetworkError): """ Failed to close a connection. """ # Other transport exceptions... class ProxyError(TransportError): """ An error occurred while establishing a proxy connection. """ class UnsupportedProtocol(TransportError): """ Attempted to make a request to an unsupported protocol. For example issuing a request to `ftp://www.example.com`. """ class ProtocolError(TransportError): """ The protocol was violated. """ class LocalProtocolError(ProtocolError): """ A protocol was violated by the client. For example if the user instantiated a `Request` instance explicitly, failed to include the mandatory `Host:` header, and then issued it directly using `client.send()`. """ class RemoteProtocolError(ProtocolError): """ The protocol was violated by the server. For example, returning malformed HTTP. """ # Other request exceptions... class DecodingError(RequestError): """ Decoding of the response failed, due to a malformed encoding. """ class TooManyRedirects(RequestError): """ Too many redirects. """ # Client errors class HTTPStatusError(HTTPError): """ The response had an error HTTP status of 4xx or 5xx. May be raised when calling `response.raise_for_status()` """ def __init__(self, message: str, *, request: Request, response: Response) -> None: super().__init__(message) self.request = request self.response = response class InvalidURL(Exception): """ URL is improperly formed or cannot be parsed. """ def __init__(self, message: str) -> None: super().__init__(message) class CookieConflict(Exception): """ Attempted to lookup a cookie by name, but multiple cookies existed. Can occur when calling `response.cookies.get(...)`. """ def __init__(self, message: str) -> None: super().__init__(message) # Stream exceptions... # These may occur as the result of a programming error, by accessing # the request/response stream in an invalid manner. class StreamError(RuntimeError): """ The base class for stream exceptions. The developer made an error in accessing the request stream in an invalid way. """ def __init__(self, message: str) -> None: super().__init__(message) class StreamConsumed(StreamError): """ Attempted to read or stream content, but the content has already been streamed. """ def __init__(self) -> None: message = ( "Attempted to read or stream some content, but the content has " "already been streamed. For requests, this could be due to passing " "a generator as request content, and then receiving a redirect " "response or a secondary request as part of an authentication flow." "For responses, this could be due to attempting to stream the response " "content more than once." ) super().__init__(message) class StreamClosed(StreamError): """ Attempted to read or stream response content, but the request has been closed. """ def __init__(self) -> None: message = "Attempted to read or stream content, but the stream has been closed." super().__init__(message) class ResponseNotRead(StreamError): """ Attempted to access streaming response content, without having called `read()`. """ def __init__(self) -> None: message = "Attempted to access streaming response content, without having called `read()`." super().__init__(message) class RequestNotRead(StreamError): """ Attempted to access streaming request content, without having called `read()`. """ def __init__(self) -> None: message = "Attempted to access streaming request content, without having called `read()`." super().__init__(message) @contextlib.contextmanager def request_context(request: Request | None = None) -> Generator[None]: """ A context manager that can be used to attach the given request context to any `RequestError` exceptions that are raised within the block. """ try: yield except RequestError as exc: if request is not None: exc.request = request raise exc pydantic-httpx2-6dd59b9/src/httpx2/httpx2/_main.py000066400000000000000000000361121526547463400221350ustar00rootroot00000000000000from __future__ import annotations import functools import json import sys import typing import click import pygments.lexers import pygments.util import rich.console import rich.markup import rich.progress import rich.syntax import rich.table from ._client import Client from ._exceptions import RequestError from ._models import Response from ._status_codes import codes if typing.TYPE_CHECKING: import httpcore2 # pragma: no cover def print_help() -> None: console = rich.console.Console() console.print("[bold]HTTPX :butterfly:", justify="center") console.print() console.print("A next generation HTTP client.", justify="center") console.print() console.print("Usage: [bold]httpx2[/bold] [cyan] [OPTIONS][/cyan] ", justify="left") console.print() table = rich.table.Table.grid(padding=1, pad_edge=True) table.add_column("Parameter", no_wrap=True, justify="left", style="bold") table.add_column("Description") table.add_row( "-m, --method [cyan]METHOD", "Request method, such as GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD, QUERY.\n" "[Default: GET, or POST if a request body is included]", ) table.add_row( "-p, --params [cyan] ...", "Query parameters to include in the request URL.", ) table.add_row("-c, --content [cyan]TEXT", "Byte content to include in the request body.") table.add_row("-d, --data [cyan] ...", "Form data to include in the request body.") table.add_row( "-f, --files [cyan] ...", "Form files to include in the request body.", ) table.add_row("-j, --json [cyan]TEXT", "JSON data to include in the request body.") table.add_row( "-h, --headers [cyan] ...", "Include additional HTTP headers in the request.", ) table.add_row("--cookies [cyan] ...", "Cookies to include in the request.") table.add_row( "--auth [cyan]", "Username and password to include in the request. Specify '-' for the password" " to use a password prompt. Note that using --verbose/-v will expose" " the Authorization header, including the password encoding" " in a trivially reversible format.", ) table.add_row( "--proxy [cyan]URL", "Send the request via a proxy. Should be the URL giving the proxy address.", ) table.add_row( "--timeout [cyan]FLOAT", "Timeout value to use for network operations, such as establishing the" " connection, reading some data, etc... [Default: 5.0]", ) table.add_row("--follow-redirects", "Automatically follow redirects.") table.add_row("--verify / --no-verify", "Enable SSL verification.") table.add_row("--http2", "Send the request using HTTP/2, if the remote server supports it.") table.add_row( "--download [cyan]FILE", "Save the response content as a file, rather than displaying it.", ) table.add_row("-v, --verbose", "Verbose output. Show request as well as response.") table.add_row("--help", "Show this message and exit.") console.print(table) def get_lexer_for_response(response: Response) -> str: content_type = response.headers.get("Content-Type") if content_type is not None: mime_type, _, _ = content_type.partition(";") try: return typing.cast(str, pygments.lexers.get_lexer_for_mimetype(mime_type.strip()).name) except pygments.util.ClassNotFound: # pragma: no cover pass return "" # pragma: no cover def format_request_headers(request: httpcore2.Request, http2: bool = False) -> str: version = "HTTP/2" if http2 else "HTTP/1.1" headers = [(name.lower() if http2 else name, value) for name, value in request.headers] method = request.method.decode("ascii") target = request.url.target.decode("ascii") lines = [f"{method} {target} {version}"] + [ f"{name.decode('ascii')}: {value.decode('ascii')}" for name, value in headers ] return "\n".join(lines) def format_response_headers( http_version: bytes, status: int, reason_phrase: bytes | None, headers: list[tuple[bytes, bytes]], ) -> str: version = http_version.decode("ascii") reason = codes.get_reason_phrase(status) if reason_phrase is None else reason_phrase.decode("ascii") lines = [f"{version} {status} {reason}"] + [ f"{name.decode('ascii')}: {value.decode('ascii')}" for name, value in headers ] return "\n".join(lines) def print_request_headers(request: httpcore2.Request, http2: bool = False) -> None: console = rich.console.Console() http_text = format_request_headers(request, http2=http2) syntax = rich.syntax.Syntax(http_text, "http", theme="ansi_dark", word_wrap=True) console.print(syntax) syntax = rich.syntax.Syntax("", "http", theme="ansi_dark", word_wrap=True) console.print(syntax) def print_response_headers( http_version: bytes, status: int, reason_phrase: bytes | None, headers: list[tuple[bytes, bytes]], ) -> None: console = rich.console.Console() http_text = format_response_headers(http_version, status, reason_phrase, headers) syntax = rich.syntax.Syntax(http_text, "http", theme="ansi_dark", word_wrap=True) console.print(syntax) syntax = rich.syntax.Syntax("", "http", theme="ansi_dark", word_wrap=True) console.print(syntax) def print_response(response: Response) -> None: console = rich.console.Console() lexer_name = get_lexer_for_response(response) if lexer_name: if lexer_name.lower() == "json": try: data = response.json() text = json.dumps(data, indent=4) except ValueError: # pragma: no cover text = response.text else: text = response.text syntax = rich.syntax.Syntax(text, lexer_name, theme="ansi_dark", word_wrap=True) console.print(syntax) else: console.print(f"<{len(response.content)} bytes of binary data>") _PCTRTT = tuple[tuple[str, str], ...] _PCTRTTT = tuple[_PCTRTT, ...] _PeerCertRetDictType = dict[str, str | _PCTRTTT | _PCTRTT] def format_certificate(cert: _PeerCertRetDictType) -> str: # pragma: no cover lines: list[str] = [] for key, value in cert.items(): if isinstance(value, (list, tuple)): lines.append(f"* {key}:") for item in value: if key in ("subject", "issuer"): lines.extend(f"* {sub_item[0]}: {sub_item[1]!r}" for sub_item in item) elif isinstance(item, tuple) and len(item) == 2: lines.append(f"* {item[0]}: {item[1]!r}") else: lines.append(f"* {item!r}") else: lines.append(f"* {key}: {value!r}") return "\n".join(lines) def trace(name: str, info: typing.Mapping[str, typing.Any], verbose: bool = False) -> None: console = rich.console.Console() if name == "connection.connect_tcp.started" and verbose: host = info["host"] console.print(f"* Connecting to {host!r}") elif name == "connection.connect_tcp.complete" and verbose: stream = info["return_value"] server_addr = stream.get_extra_info("server_addr") console.print(f"* Connected to {server_addr[0]!r} on port {server_addr[1]}") elif name == "connection.start_tls.complete" and verbose: # pragma: no cover stream = info["return_value"] ssl_object = stream.get_extra_info("ssl_object") version = ssl_object.version() cipher = ssl_object.cipher() server_cert = ssl_object.getpeercert() alpn = ssl_object.selected_alpn_protocol() console.print(f"* SSL established using {version!r} / {cipher[0]!r}") console.print(f"* Selected ALPN protocol: {alpn!r}") if server_cert: console.print("* Server certificate:") console.print(format_certificate(server_cert)) elif name == "http11.send_request_headers.started" and verbose: request = info["request"] print_request_headers(request, http2=False) elif name == "http2.send_request_headers.started" and verbose: # pragma: no cover request = info["request"] print_request_headers(request, http2=True) elif name == "http11.receive_response_headers.complete": http_version, status, reason_phrase, headers = info["return_value"] print_response_headers(http_version, status, reason_phrase, headers) elif name == "http2.receive_response_headers.complete": # pragma: no cover status, headers = info["return_value"] http_version = b"HTTP/2" reason_phrase = None print_response_headers(http_version, status, reason_phrase, headers) def download_response(response: Response, download: typing.BinaryIO) -> None: console = rich.console.Console() console.print() content_length = response.headers.get("Content-Length") with rich.progress.Progress( "[progress.description]{task.description}", "[progress.percentage]{task.percentage:>3.0f}%", rich.progress.BarColumn(bar_width=None), rich.progress.DownloadColumn(), rich.progress.TransferSpeedColumn(), ) as progress: description = f"Downloading [bold]{rich.markup.escape(download.name)}" download_task = progress.add_task( description, total=int(content_length or 0), start=content_length is not None, ) for chunk in response.iter_bytes(): download.write(chunk) progress.update(download_task, completed=response.num_bytes_downloaded) def validate_json( ctx: click.Context, param: click.Option | click.Parameter, value: typing.Any, ) -> typing.Any: if value is None: return None try: return json.loads(value) except json.JSONDecodeError: # pragma: no cover raise click.BadParameter("Not valid JSON") def validate_auth( ctx: click.Context, param: click.Option | click.Parameter, value: typing.Any, ) -> typing.Any: if value == (None, None): return None username, password = value if password == "-": # pragma: no cover password = click.prompt("Password", hide_input=True) return (username, password) def handle_help( ctx: click.Context, param: click.Option | click.Parameter, value: typing.Any, ) -> None: if not value or ctx.resilient_parsing: return print_help() ctx.exit() @click.command(add_help_option=False) @click.argument("url", type=str) @click.option( "--method", "-m", "method", type=str, help=( "Request method, such as GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD, QUERY. " "[Default: GET, or POST if a request body is included]" ), ) @click.option( "--params", "-p", "params", type=(str, str), multiple=True, help="Query parameters to include in the request URL.", ) @click.option( "--content", "-c", "content", type=str, help="Byte content to include in the request body.", ) @click.option( "--data", "-d", "data", type=(str, str), multiple=True, help="Form data to include in the request body.", ) @click.option( "--files", "-f", "files", type=(str, click.File(mode="rb")), multiple=True, help="Form files to include in the request body.", ) @click.option( "--json", "-j", "json", type=str, callback=validate_json, help="JSON data to include in the request body.", ) @click.option( "--headers", "-h", "headers", type=(str, str), multiple=True, help="Include additional HTTP headers in the request.", ) @click.option( "--cookies", "cookies", type=(str, str), multiple=True, help="Cookies to include in the request.", ) @click.option( "--auth", "auth", type=(str, str), default=(None, None), callback=validate_auth, help=( "Username and password to include in the request. " "Specify '-' for the password to use a password prompt. " "Note that using --verbose/-v will expose the Authorization header, " "including the password encoding in a trivially reversible format." ), ) @click.option( "--proxy", "proxy", type=str, default=None, help="Send the request via a proxy. Should be the URL giving the proxy address.", ) @click.option( "--timeout", "timeout", type=float, default=5.0, help=( "Timeout value to use for network operations, such as establishing the " "connection, reading some data, etc... [Default: 5.0]" ), ) @click.option( "--follow-redirects", "follow_redirects", is_flag=True, default=False, help="Automatically follow redirects.", ) @click.option( "--verify/--no-verify", default=True, help="Enable SSL verification.", ) @click.option( "--http2", "http2", type=bool, is_flag=True, default=False, help="Send the request using HTTP/2, if the remote server supports it.", ) @click.option( "--download", type=click.File("wb"), help="Save the response content as a file, rather than displaying it.", ) @click.option( "--verbose", "-v", type=bool, is_flag=True, default=False, help="Verbose. Show request as well as response.", ) @click.option( "--help", is_flag=True, is_eager=True, expose_value=False, callback=handle_help, help="Show this message and exit.", ) def main( url: str, method: str, params: list[tuple[str, str]], content: str, data: list[tuple[str, str]], files: list[tuple[str, click.File]], json: str, headers: list[tuple[str, str]], cookies: list[tuple[str, str]], auth: tuple[str, str] | None, proxy: str, timeout: float, follow_redirects: bool, verify: bool, http2: bool, download: typing.BinaryIO | None, verbose: bool, ) -> None: """ An HTTP command line client. Sends a request and displays the response. """ if not method: method = "POST" if content or data or files or json else "GET" try: with Client(proxy=proxy, timeout=timeout, http2=http2, verify=verify) as client: with client.stream( method, url, params=list(params), content=content, data=dict(data), files=files, # type: ignore[arg-type] json=json, headers=headers, cookies=dict(cookies), auth=auth, follow_redirects=follow_redirects, extensions={"trace": functools.partial(trace, verbose=verbose)}, ) as response: if download is not None: download_response(response, download) else: response.read() if response.content: print_response(response) except RequestError as exc: console = rich.console.Console() console.print(f"[red]{type(exc).__name__}[/red]: {exc}") sys.exit(1) sys.exit(0 if response.is_success else 1) pydantic-httpx2-6dd59b9/src/httpx2/httpx2/_models.py000066400000000000000000001312521526547463400224750ustar00rootroot00000000000000from __future__ import annotations import codecs import contextlib import datetime import email.message import json as jsonlib import re import typing import urllib.request from collections.abc import AsyncGenerator, Mapping from http.cookiejar import Cookie, CookieJar from ._content import ByteStream, UnattachedStream, encode_request, encode_response from ._decoders import ( ByteChunker, ContentDecoder, IdentityDecoder, LineDecoder, MultiDecoder, TextChunker, TextDecoder, ) from ._exceptions import ( CookieConflict, HTTPStatusError, RequestNotRead, ResponseNotRead, StreamClosed, StreamConsumed, request_context, ) from ._multipart import get_multipart_boundary_from_content_type from ._status_codes import codes from ._types import ( AsyncByteStream, CookieTypes, HeaderTypes, QueryParamTypes, RequestContent, RequestData, RequestExtensions, RequestFiles, ResponseContent, ResponseExtensions, SyncByteStream, ) from ._urls import URL from ._utils import to_bytes_or_str, to_str __all__ = ["Cookies", "Headers", "Request", "Response"] SENSITIVE_HEADERS = {"authorization", "proxy-authorization"} _T = typing.TypeVar("_T") def _is_known_encoding(encoding: str) -> bool: """ Return `True` if `encoding` is a known codec. """ try: codecs.lookup(encoding) except LookupError: return False return True def _normalize_header_key(key: str | bytes, encoding: str | None = None) -> bytes: """ Coerce str/bytes into a strictly byte-wise HTTP header key. """ return key if isinstance(key, bytes) else key.encode(encoding or "ascii") def _normalize_header_value(value: str | bytes, encoding: str | None = None) -> bytes: """ Coerce str/bytes into a strictly byte-wise HTTP header value. """ if isinstance(value, bytes): return value if not isinstance(value, str): raise TypeError(f"Header value must be str or bytes, not {type(value)}") return value.encode(encoding or "ascii") def _parse_content_type_charset(content_type: str) -> str | None: # We used to use `cgi.parse_header()` here, but `cgi` became a dead battery. # See: https://peps.python.org/pep-0594/#cgi msg = email.message.Message() msg["content-type"] = content_type return msg.get_content_charset(failobj=None) def _parse_header_links(value: str) -> list[dict[str, str]]: """ Returns a list of parsed link headers, for more info see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Link The generic syntax of those is: Link: < uri-reference >; param1=value1; param2="value2" So for instance: Link; '; type="image/jpeg",;' would return [ {"url": "http:/.../front.jpeg", "type": "image/jpeg"}, {"url": "http://.../back.jpeg"}, ] :param value: HTTP Link entity-header field :return: list of parsed link headers """ links: list[dict[str, str]] = [] replace_chars = " '\"" value = value.strip(replace_chars) if not value: return links for val in re.split(", *<", value): try: url, params = val.split(";", 1) except ValueError: url, params = val, "" link = {"url": url.strip("<> '\"")} for param in params.split(";"): try: key, value = param.split("=") except ValueError: break link[key.strip(replace_chars)] = value.strip(replace_chars) links.append(link) return links def _obfuscate_sensitive_headers( items: typing.Iterable[tuple[typing.AnyStr, typing.AnyStr]], ) -> typing.Iterator[tuple[typing.AnyStr, typing.AnyStr]]: for k, v in items: if to_str(k.lower()) in SENSITIVE_HEADERS: v = to_bytes_or_str("[secure]", match_type_of=v) yield k, v class Headers(typing.MutableMapping[str, str]): """ HTTP headers, as a case-insensitive multi-dict. """ def __init__( self, headers: HeaderTypes | None = None, encoding: str | None = None, ) -> None: self._list: list[tuple[bytes, bytes, bytes]] = [] if isinstance(headers, Headers): self._list = list(headers._list) elif isinstance(headers, Mapping): for k, v in headers.items(): bytes_key = _normalize_header_key(k, encoding) bytes_value = _normalize_header_value(v, encoding) self._list.append((bytes_key, bytes_key.lower(), bytes_value)) elif headers is not None: for k, v in headers: bytes_key = _normalize_header_key(k, encoding) bytes_value = _normalize_header_value(v, encoding) self._list.append((bytes_key, bytes_key.lower(), bytes_value)) self._encoding = encoding @property def encoding(self) -> str: """ Header encoding is mandated as ascii, but we allow fallbacks to utf-8 or iso-8859-1. """ if self._encoding is None: for encoding in ["ascii", "utf-8"]: for key, value in self.raw: try: key.decode(encoding) value.decode(encoding) except UnicodeDecodeError: break else: # The else block runs if 'break' did not occur, meaning # all values fitted the encoding. self._encoding = encoding break else: # The ISO-8859-1 encoding covers all 256 code points in a byte, # so will never raise decode errors. self._encoding = "iso-8859-1" return self._encoding @encoding.setter def encoding(self, value: str) -> None: self._encoding = value @property def raw(self) -> list[tuple[bytes, bytes]]: """ Returns a list of the raw header items, as byte pairs. """ return [(raw_key, value) for raw_key, _, value in self._list] def keys(self) -> typing.KeysView[str]: return {key.decode(self.encoding): None for _, key, _value in self._list}.keys() def values(self) -> typing.ValuesView[str]: values_dict: dict[str, str] = {} for _, key, value in self._list: str_key = key.decode(self.encoding) str_value = value.decode(self.encoding) if str_key in values_dict: values_dict[str_key] += f", {str_value}" else: values_dict[str_key] = str_value return values_dict.values() def items(self) -> typing.ItemsView[str, str]: """ Return `(key, value)` items of headers. Concatenate headers into a single comma separated value when a key occurs multiple times. """ values_dict: dict[str, str] = {} for _, key, value in self._list: str_key = key.decode(self.encoding) str_value = value.decode(self.encoding) if str_key in values_dict: values_dict[str_key] += f", {str_value}" else: values_dict[str_key] = str_value return values_dict.items() def multi_items(self) -> list[tuple[str, str]]: """ Return a list of `(key, value)` pairs of headers. Allow multiple occurrences of the same key without concatenating into a single comma separated value. """ return [(key.decode(self.encoding), value.decode(self.encoding)) for _, key, value in self._list] @typing.overload def get(self, key: str, /) -> str | None: ... @typing.overload def get(self, key: str, default: _T) -> str | _T: ... def get(self, key: str, default: _T | None = None) -> str | _T | None: """ Return a header value. If multiple occurrences of the header occur then concatenate them together with commas. """ try: return self[key] except KeyError: return default def get_list(self, key: str, split_commas: bool = False) -> list[str]: """ Return a list of all header values for a given key. If `split_commas=True` is passed, then any comma separated header values are split into multiple return strings. """ get_header_key = key.lower().encode(self.encoding) values = [ item_value.decode(self.encoding) for _, item_key, item_value in self._list if item_key.lower() == get_header_key ] if not split_commas: return values split_values: list[str] = [] for value in values: split_values.extend([item.strip() for item in value.split(",")]) return split_values def update(self, headers: HeaderTypes | None = None) -> None: # type: ignore headers = Headers(headers) for key in headers.keys(): if key in self: self.pop(key) self._list.extend(headers._list) def copy(self) -> Headers: return Headers(self, encoding=self.encoding) def __or__(self, other: Mapping[str, str]) -> Headers: if not isinstance(other, Mapping): return NotImplemented merged = self.copy() merged.update(other) return merged def __ror__(self, other: Mapping[str, str]) -> Headers: if not isinstance(other, Mapping): return NotImplemented merged = Headers(other) merged.update(self) return merged def __ior__(self, other: HeaderTypes) -> Headers: self.update(other) return self def __getitem__(self, key: str) -> str: """ Return a single header value. If there are multiple headers with the same key, then we concatenate them with commas. See: https://tools.ietf.org/html/rfc7230#section-3.2.2 """ normalized_key = key.lower().encode(self.encoding) items = [ header_value.decode(self.encoding) for _, header_key, header_value in self._list if header_key == normalized_key ] if items: return ", ".join(items) raise KeyError(key) def __setitem__(self, key: str, value: str) -> None: """ Set the header `key` to `value`, removing any duplicate entries. Retains insertion order. """ set_key = key.encode(self._encoding or "utf-8") set_value = value.encode(self._encoding or "utf-8") lookup_key = set_key.lower() found_indexes = [idx for idx, (_, item_key, _) in enumerate(self._list) if item_key == lookup_key] for idx in reversed(found_indexes[1:]): del self._list[idx] if found_indexes: idx = found_indexes[0] self._list[idx] = (set_key, lookup_key, set_value) else: self._list.append((set_key, lookup_key, set_value)) def __delitem__(self, key: str) -> None: """ Remove the header `key`. """ del_key = key.lower().encode(self.encoding) pop_indexes = [idx for idx, (_, item_key, _) in enumerate(self._list) if item_key.lower() == del_key] if not pop_indexes: raise KeyError(key) for idx in reversed(pop_indexes): del self._list[idx] def __contains__(self, key: typing.Any) -> bool: header_key = key.lower().encode(self.encoding) return header_key in [key for _, key, _ in self._list] def __iter__(self) -> typing.Iterator[typing.Any]: return iter(self.keys()) def __len__(self) -> int: return len(self._list) def __eq__(self, other: typing.Any) -> bool: try: other_headers = Headers(other) except ValueError: return False self_list = [(key, value) for _, key, value in self._list] other_list = [(key, value) for _, key, value in other_headers._list] return sorted(self_list) == sorted(other_list) def __repr__(self) -> str: class_name = self.__class__.__name__ encoding_str = "" if self.encoding != "ascii": encoding_str = f", encoding={self.encoding!r}" as_list = list(_obfuscate_sensitive_headers(self.multi_items())) as_dict = dict(as_list) no_duplicate_keys = len(as_dict) == len(as_list) if no_duplicate_keys: return f"{class_name}({as_dict!r}{encoding_str})" return f"{class_name}({as_list!r}{encoding_str})" class Request: def __init__( self, method: str, url: URL | str, *, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: typing.Any | None = None, stream: SyncByteStream | AsyncByteStream | None = None, extensions: RequestExtensions | None = None, ) -> None: self.method = method.upper() self.url = URL(url) if params is None else URL(url, params=params) self.headers = Headers(headers) self.extensions = {} if extensions is None else dict(extensions) if cookies: Cookies(cookies).set_cookie_header(self) if stream is None: content_type: str | None = self.headers.get("content-type") headers, stream = encode_request( content=content, data=data, files=files, json=json, boundary=get_multipart_boundary_from_content_type( content_type=content_type.encode(self.headers.encoding) if content_type else None ), ) self._prepare(headers) self.stream = stream # Load the request body, except for streaming content. if isinstance(stream, ByteStream): self.read() else: # There's an important distinction between `Request(content=...)`, # and `Request(stream=...)`. # # Using `content=...` implies automatically populated `Host` and content # headers, of either `Content-Length: ...` or `Transfer-Encoding: chunked`. # # Using `stream=...` will not automatically include *any* # auto-populated headers. # # As an end-user you don't really need `stream=...`. It's only # useful when: # # * Preserving the request stream when copying requests, eg for redirects. # * Creating request instances on the *server-side* of the transport API. self.stream = stream def _prepare(self, default_headers: dict[str, str]) -> None: for key, value in default_headers.items(): # Ignore Content-Length if Transfer-Encoding has been set explicitly. if key.lower() == "content-length" and "Transfer-Encoding" in self.headers: continue # Ignore Transfer-Encoding if Content-Length has been set explicitly. if key.lower() == "transfer-encoding" and "Content-Length" in self.headers: continue self.headers.setdefault(key, value) auto_headers: list[tuple[bytes, bytes]] = [] has_host = "Host" in self.headers has_content_length = "Content-Length" in self.headers or "Transfer-Encoding" in self.headers if not has_host and self.url.host: auto_headers.append((b"Host", self.url.netloc)) if not has_content_length and self.method in ("POST", "PUT", "PATCH", "QUERY"): auto_headers.append((b"Content-Length", b"0")) self.headers = Headers(auto_headers + self.headers.raw) @property def content(self) -> bytes: if not hasattr(self, "_content"): raise RequestNotRead() return self._content def read(self) -> bytes: """ Read and return the request content. """ if not hasattr(self, "_content"): assert isinstance(self.stream, typing.Iterable) self._content = b"".join(self.stream) if not isinstance(self.stream, ByteStream): # If a streaming request has been read entirely into memory, then # we can replace the stream with a raw bytes implementation, # to ensure that any non-replayable streams can still be used. self.stream = ByteStream(self._content) return self._content async def aread(self) -> bytes: """ Read and return the request content. """ if not hasattr(self, "_content"): assert isinstance(self.stream, typing.AsyncIterable) self._content = b"".join([part async for part in self.stream]) if not isinstance(self.stream, ByteStream): # If a streaming request has been read entirely into memory, then # we can replace the stream with a raw bytes implementation, # to ensure that any non-replayable streams can still be used. self.stream = ByteStream(self._content) return self._content def __repr__(self) -> str: class_name = self.__class__.__name__ url = str(self.url) return f"<{class_name}({self.method!r}, {url!r})>" def __getstate__(self) -> dict[str, typing.Any]: return {name: value for name, value in self.__dict__.items() if name not in ["extensions", "stream"]} def __setstate__(self, state: dict[str, typing.Any]) -> None: for name, value in state.items(): setattr(self, name, value) self.extensions = {} self.stream = UnattachedStream() class Response: def __init__( self, status_code: int, *, headers: HeaderTypes | None = None, content: ResponseContent | None = None, text: str | None = None, html: str | None = None, json: typing.Any = None, stream: SyncByteStream | AsyncByteStream | None = None, request: Request | None = None, extensions: ResponseExtensions | None = None, history: list[Response] | None = None, default_encoding: str | typing.Callable[[bytes], str | None] = "utf-8", ) -> None: self.status_code = status_code self.headers = Headers(headers) self._request: Request | None = request # When follow_redirects=False and a redirect is received, # the client will set `response.next_request`. self.next_request: Request | None = None self.extensions = {} if extensions is None else dict(extensions) self.history = [] if history is None else list(history) self.is_closed = False self.is_stream_consumed = False self.default_encoding = default_encoding if stream is None: headers, stream = encode_response(content, text, html, json) self._prepare(headers) self.stream = stream if isinstance(stream, ByteStream): # Load the response body, except for streaming content. self.read() else: # There's an important distinction between `Response(content=...)`, # and `Response(stream=...)`. # # Using `content=...` implies automatically populated content headers, # of either `Content-Length: ...` or `Transfer-Encoding: chunked`. # # Using `stream=...` will not automatically include any content headers. # # As an end-user you don't really need `stream=...`. It's only # useful when creating response instances having received a stream # from the transport API. self.stream = stream self._num_bytes_downloaded = 0 def _prepare(self, default_headers: dict[str, str]) -> None: for key, value in default_headers.items(): # Ignore Transfer-Encoding if the Content-Length has been set explicitly. if key.lower() == "transfer-encoding" and "content-length" in self.headers: continue self.headers.setdefault(key, value) @property def elapsed(self) -> datetime.timedelta: """ Returns the time taken for the complete request/response cycle to complete. """ if not hasattr(self, "_elapsed"): stream_elapsed: datetime.timedelta | None = getattr(self.stream, "elapsed", None) if stream_elapsed is not None: return stream_elapsed raise RuntimeError("'.elapsed' may only be accessed after the response has been read or closed.") return self._elapsed @elapsed.setter def elapsed(self, elapsed: datetime.timedelta) -> None: self._elapsed = elapsed @property def request(self) -> Request: """ Returns the request instance associated to the current response. """ if self._request is None: raise RuntimeError("The request instance has not been set on this response.") return self._request @request.setter def request(self, value: Request) -> None: self._request = value @property def http_version(self) -> str: try: http_version: bytes = self.extensions["http_version"] except KeyError: return "HTTP/1.1" else: return http_version.decode("ascii", errors="ignore") @property def reason_phrase(self) -> str: try: reason_phrase: bytes = self.extensions["reason_phrase"] except KeyError: return codes.get_reason_phrase(self.status_code) else: return reason_phrase.decode("ascii", errors="ignore") @property def url(self) -> URL: """ Returns the URL for which the request was made. """ return self.request.url @property def content(self) -> bytes: if not hasattr(self, "_content"): raise ResponseNotRead() return self._content @property def text(self) -> str: if not hasattr(self, "_text"): content = self.content if not content: self._text = "" else: decoder = TextDecoder(encoding=self.encoding or "utf-8") self._text = "".join([decoder.decode(self.content), decoder.flush()]) return self._text @property def encoding(self) -> str | None: """ Return an encoding to use for decoding the byte content into text. The priority for determining this is given by... * `.encoding = <>` has been set explicitly. * The encoding as specified by the charset parameter in the Content-Type header. * The encoding as determined by `default_encoding`, which may either be a string like "utf-8" indicating the encoding to use, or may be a callable which enables charset autodetection. """ if not hasattr(self, "_encoding"): encoding = self.charset_encoding if encoding is None or not _is_known_encoding(encoding): if isinstance(self.default_encoding, str): encoding = self.default_encoding elif hasattr(self, "_content"): encoding = self.default_encoding(self._content) self._encoding = encoding or "utf-8" return self._encoding @encoding.setter def encoding(self, value: str) -> None: """ Set the encoding to use for decoding the byte content into text. If the `text` attribute has been accessed, attempting to set the encoding will throw a ValueError. """ if hasattr(self, "_text"): raise ValueError("Setting encoding after `text` has been accessed is not allowed.") self._encoding = value @property def charset_encoding(self) -> str | None: """ Return the encoding, as specified by the Content-Type header. """ content_type = self.headers.get("Content-Type") if content_type is None: return None return _parse_content_type_charset(content_type) def _get_content_decoder(self) -> ContentDecoder: """ Returns a decoder instance which can be used to decode the raw byte content, depending on the Content-Encoding used in the response. """ if not hasattr(self, "_decoder"): values = self.headers.get_list("content-encoding", split_commas=True) encodings = [value.strip().lower() for value in values] decoder = MultiDecoder([encoding for encoding in encodings if encoding != "identity"]) if len(decoder.children) == 1: self._decoder = decoder.children[0] elif decoder.children: self._decoder = decoder else: self._decoder = IdentityDecoder() return self._decoder @property def is_informational(self) -> bool: """ A property which is `True` for 1xx status codes, `False` otherwise. """ return codes.is_informational(self.status_code) @property def is_success(self) -> bool: """ A property which is `True` for 2xx status codes, `False` otherwise. """ return codes.is_success(self.status_code) @property def is_redirect(self) -> bool: """ A property which is `True` for 3xx status codes, `False` otherwise. Note that not all responses with a 3xx status code indicate a URL redirect. Use `response.has_redirect_location` to determine responses with a properly formed URL redirection. """ return codes.is_redirect(self.status_code) @property def is_client_error(self) -> bool: """ A property which is `True` for 4xx status codes, `False` otherwise. """ return codes.is_client_error(self.status_code) @property def is_server_error(self) -> bool: """ A property which is `True` for 5xx status codes, `False` otherwise. """ return codes.is_server_error(self.status_code) @property def is_error(self) -> bool: """ A property which is `True` for 4xx and 5xx status codes, `False` otherwise. """ return codes.is_error(self.status_code) @property def has_redirect_location(self) -> bool: """ Returns True for 3xx responses with a properly formed URL redirection, `False` otherwise. """ return ( self.status_code in ( # 301 (Cacheable redirect. Method may change to GET.) codes.MOVED_PERMANENTLY, # 302 (Uncacheable redirect. Method may change to GET.) codes.FOUND, # 303 (Client should make a GET or HEAD request.) codes.SEE_OTHER, # 307 (Equiv. 302, but retain method) codes.TEMPORARY_REDIRECT, # 308 (Equiv. 301, but retain method) codes.PERMANENT_REDIRECT, ) and "Location" in self.headers ) def raise_for_status(self) -> Response: """ Raise the `HTTPStatusError` if one occurred. """ request = self._request if request is None: raise RuntimeError( "Cannot call `raise_for_status` as the request instance has not been set on this response." ) if self.is_success: return self if self.has_redirect_location: message = ( "{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n" "Redirect location: '{0.headers[location]}'\n" "For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}" ) else: message = ( "{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n" "For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}" ) status_class = self.status_code // 100 error_types = { 1: "Informational response", 3: "Redirect response", 4: "Client error", 5: "Server error", } error_type = error_types.get(status_class, "Invalid status code") message = message.format(self, error_type=error_type) raise HTTPStatusError(message, request=request, response=self) def json(self, **kwargs: typing.Any) -> typing.Any: return jsonlib.loads(self.content, **kwargs) @property def cookies(self) -> Cookies: if not hasattr(self, "_cookies"): self._cookies = Cookies() self._cookies.extract_cookies(self) return self._cookies @property def links(self) -> dict[str | None, dict[str, str]]: """ Returns the parsed header links of the response, if any """ header = self.headers.get("link") if header is None: return {} return {(link.get("rel") or link.get("url")): link for link in _parse_header_links(header)} @property def num_bytes_downloaded(self) -> int: return self._num_bytes_downloaded def __repr__(self) -> str: return f"" def __getstate__(self) -> dict[str, typing.Any]: return { name: value for name, value in self.__dict__.items() if name not in ["extensions", "stream", "is_closed", "_decoder"] } def __setstate__(self, state: dict[str, typing.Any]) -> None: for name, value in state.items(): setattr(self, name, value) self.is_closed = True self.extensions = {} self.stream = UnattachedStream() def read(self) -> bytes: """ Read and return the response content. """ if not hasattr(self, "_content"): self._content = b"".join(self.iter_bytes()) return self._content def iter_bytes(self, chunk_size: int | None = None) -> typing.Iterator[bytes]: """ A byte-iterator over the decoded response content. This allows us to handle gzip, deflate, brotli, and zstd encoded responses. """ if hasattr(self, "_content"): chunk_size = len(self._content) if chunk_size is None else chunk_size for i in range(0, len(self._content), max(chunk_size, 1)): yield self._content[i : i + chunk_size] else: decoder = self._get_content_decoder() chunker = ByteChunker(chunk_size=chunk_size) with request_context(request=self._request): for raw_bytes in self.iter_raw(): for decoded in decoder.decode(raw_bytes): for chunk in chunker.decode(decoded): yield chunk for decoded in decoder.flush(): for chunk in chunker.decode(decoded): yield chunk # pragma: no cover for chunk in chunker.flush(): yield chunk def iter_text(self, chunk_size: int | None = None) -> typing.Iterator[str]: """ A str-iterator over the decoded response content that handles both gzip, deflate, etc but also detects the content's string encoding. """ decoder = TextDecoder(encoding=self.encoding or "utf-8") chunker = TextChunker(chunk_size=chunk_size) with request_context(request=self._request): for byte_content in self.iter_bytes(): text_content = decoder.decode(byte_content) for chunk in chunker.decode(text_content): yield chunk text_content = decoder.flush() for chunk in chunker.decode(text_content): yield chunk # pragma: no cover for chunk in chunker.flush(): yield chunk def iter_lines(self) -> typing.Iterator[str]: decoder = LineDecoder() with request_context(request=self._request): for text in self.iter_text(): for line in decoder.decode(text): yield line for line in decoder.flush(): yield line def iter_raw(self, chunk_size: int | None = None) -> typing.Iterator[bytes]: """ A byte-iterator over the raw response content. """ if self.is_stream_consumed: raise StreamConsumed() if self.is_closed: raise StreamClosed() if not isinstance(self.stream, SyncByteStream): raise RuntimeError("Attempted to call a sync iterator on an async stream.") self.is_stream_consumed = True self._num_bytes_downloaded = 0 chunker = ByteChunker(chunk_size=chunk_size) try: with request_context(request=self._request): for raw_stream_bytes in self.stream: self._num_bytes_downloaded += len(raw_stream_bytes) for chunk in chunker.decode(raw_stream_bytes): yield chunk for chunk in chunker.flush(): yield chunk finally: self.close() def close(self) -> None: """ Close the response and release the connection. Automatically called if the response body is read to completion. """ if not isinstance(self.stream, SyncByteStream): raise RuntimeError("Attempted to call a sync close on an async stream.") if not self.is_closed: self.is_closed = True with request_context(request=self._request): self.stream.close() async def aread(self) -> bytes: """ Read and return the response content. """ if not hasattr(self, "_content"): async with contextlib.aclosing(self.aiter_bytes()) as parts: self._content = b"".join([part async for part in parts]) return self._content async def aiter_bytes(self, chunk_size: int | None = None) -> typing.AsyncGenerator[bytes, None]: """ A byte-iterator over the decoded response content. This allows us to handle gzip, deflate, brotli, and zstd encoded responses. """ if hasattr(self, "_content"): chunk_size = len(self._content) if chunk_size is None else chunk_size for i in range(0, len(self._content), max(chunk_size, 1)): yield self._content[i : i + chunk_size] else: decoder = self._get_content_decoder() chunker = ByteChunker(chunk_size=chunk_size) with request_context(request=self._request): async with contextlib.aclosing(self.aiter_raw()) as raw_stream: async for raw_bytes in raw_stream: for decoded in decoder.decode(raw_bytes): for chunk in chunker.decode(decoded): yield chunk for decoded in decoder.flush(): for chunk in chunker.decode(decoded): yield chunk # pragma: no cover for chunk in chunker.flush(): yield chunk async def aiter_text(self, chunk_size: int | None = None) -> typing.AsyncIterator[str]: """ A str-iterator over the decoded response content that handles both gzip, deflate, etc but also detects the content's string encoding. """ decoder = TextDecoder(encoding=self.encoding or "utf-8") chunker = TextChunker(chunk_size=chunk_size) with request_context(request=self._request): async for byte_content in self.aiter_bytes(): text_content = decoder.decode(byte_content) for chunk in chunker.decode(text_content): yield chunk text_content = decoder.flush() for chunk in chunker.decode(text_content): yield chunk # pragma: no cover for chunk in chunker.flush(): yield chunk async def aiter_lines(self) -> typing.AsyncIterator[str]: decoder = LineDecoder() with request_context(request=self._request): async for text in self.aiter_text(): for line in decoder.decode(text): yield line for line in decoder.flush(): yield line async def aiter_raw(self, chunk_size: int | None = None) -> typing.AsyncGenerator[bytes, None]: """ A byte-iterator over the raw response content. """ if self.is_stream_consumed: raise StreamConsumed() if self.is_closed: raise StreamClosed() if not isinstance(self.stream, AsyncByteStream): raise RuntimeError("Attempted to call an async iterator on a sync stream.") self.is_stream_consumed = True self._num_bytes_downloaded = 0 chunker = ByteChunker(chunk_size=chunk_size) stream = self.stream.__aiter__() try: with request_context(request=self._request): async for raw_stream_bytes in stream: self._num_bytes_downloaded += len(raw_stream_bytes) for chunk in chunker.decode(raw_stream_bytes): yield chunk for chunk in chunker.flush(): yield chunk finally: if isinstance(stream, AsyncGenerator): await stream.aclose() await self.aclose() async def aclose(self) -> None: """ Close the response and release the connection. Automatically called if the response body is read to completion. """ if not isinstance(self.stream, AsyncByteStream): raise RuntimeError("Attempted to call an async close on a sync stream.") if not self.is_closed: self.is_closed = True with request_context(request=self._request): await self.stream.aclose() class Cookies(typing.MutableMapping[str, str]): """ HTTP Cookies, as a mutable mapping. """ def __init__(self, cookies: CookieTypes | None = None) -> None: if cookies is None or isinstance(cookies, dict): self.jar = CookieJar() if isinstance(cookies, dict): for key, value in cookies.items(): self.set(key, value) elif isinstance(cookies, list): self.jar = CookieJar() for key, value in cookies: self.set(key, value) elif isinstance(cookies, Cookies): self.jar = CookieJar() for cookie in cookies.jar: self.jar.set_cookie(cookie) else: self.jar = cookies def extract_cookies(self, response: Response) -> None: """ Loads any cookies based on the response `Set-Cookie` headers. """ if "set-cookie" not in response.headers and "set-cookie2" not in response.headers: return urllib_response = self._CookieCompatResponse(response) urllib_request = self._CookieCompatRequest(response.request) self.jar.extract_cookies(urllib_response, urllib_request) # type: ignore def set_cookie_header(self, request: Request) -> None: """ Sets an appropriate 'Cookie:' HTTP header on the `Request`. """ urllib_request = self._CookieCompatRequest(request) self.jar.add_cookie_header(urllib_request) def set(self, name: str, value: str, domain: str = "", path: str = "/") -> None: """ Set a cookie value by name. May optionally include domain and path. """ kwargs = { "version": 0, "name": name, "value": value, "port": None, "port_specified": False, "domain": domain, "domain_specified": bool(domain), "domain_initial_dot": domain.startswith("."), "path": path, "path_specified": bool(path), "secure": False, "expires": None, "discard": True, "comment": None, "comment_url": None, "rest": {"HttpOnly": None}, "rfc2109": False, } cookie = Cookie(**kwargs) # type: ignore self.jar.set_cookie(cookie) def get( # type: ignore self, name: str, default: str | None = None, domain: str | None = None, path: str | None = None, ) -> str | None: """ Get a cookie by name. May optionally include domain and path in order to specify exactly which cookie to retrieve. """ value = None for cookie in self.jar: if cookie.name == name: if domain is None or cookie.domain == domain: if path is None or cookie.path == path: if value is not None: message = f"Multiple cookies exist with name={name}" raise CookieConflict(message) value = cookie.value if value is None: return default return value def delete( self, name: str, domain: str | None = None, path: str | None = None, ) -> None: """ Delete a cookie by name. May optionally include domain and path in order to specify exactly which cookie to delete. """ if domain is not None and path is not None: return self.jar.clear(domain, path, name) remove = [ cookie for cookie in self.jar if cookie.name == name and (domain is None or cookie.domain == domain) and (path is None or cookie.path == path) ] for cookie in remove: self.jar.clear(cookie.domain, cookie.path, cookie.name) def clear(self, domain: str | None = None, path: str | None = None) -> None: """ Delete all cookies. Optionally include a domain and path in order to only delete a subset of all the cookies. """ args: list[str] = [] if domain is not None: args.append(domain) if path is not None: assert domain is not None args.append(path) self.jar.clear(*args) def update(self, cookies: CookieTypes | None = None) -> None: # type: ignore cookies = Cookies(cookies) for cookie in cookies.jar: self.jar.set_cookie(cookie) def __setitem__(self, name: str, value: str) -> None: return self.set(name, value) def __getitem__(self, name: str) -> str: value = self.get(name) if value is None: raise KeyError(name) return value def __delitem__(self, name: str) -> None: return self.delete(name) def __len__(self) -> int: return len(self.jar) def __iter__(self) -> typing.Iterator[str]: return (cookie.name for cookie in self.jar) def __bool__(self) -> bool: for _ in self.jar: return True return False def __repr__(self) -> str: cookies_repr = ", ".join( [f"" for cookie in self.jar] ) return f"" class _CookieCompatRequest(urllib.request.Request): """ Wraps a `Request` instance up in a compatibility interface suitable for use with `CookieJar` operations. """ def __init__(self, request: Request) -> None: super().__init__( url=str(request.url), headers=dict(request.headers), method=request.method, ) self.request = request def add_unredirected_header(self, key: str, val: str) -> None: super().add_unredirected_header(key, val) self.request.headers[key] = val class _CookieCompatResponse: """ Wraps a `Request` instance up in a compatibility interface suitable for use with `CookieJar` operations. """ def __init__(self, response: Response) -> None: self.response = response def info(self) -> email.message.Message: info = email.message.Message() for key, value in self.response.headers.multi_items(): # Note that setting `info[key]` here is an "append" operation, # not a "replace" operation. # https://docs.python.org/3/library/email.compat32-message.html#email.message.Message.__setitem__ info[key] = value return info pydantic-httpx2-6dd59b9/src/httpx2/httpx2/_multipart.py000066400000000000000000000234421526547463400232340ustar00rootroot00000000000000from __future__ import annotations import io import mimetypes import os import re import typing from pathlib import Path from ._types import ( AsyncByteStream, FileContent, FileTypes, RequestData, RequestFiles, SyncByteStream, ) from ._utils import ( peek_filelike_length, primitive_value_to_str, to_bytes, ) _HTML5_FORM_ENCODING_REPLACEMENTS = {'"': "%22", "\\": "\\\\"} _HTML5_FORM_ENCODING_REPLACEMENTS.update({chr(c): f"%{c:02X}" for c in range(0x1F + 1) if c != 0x1B}) _HTML5_FORM_ENCODING_RE = re.compile(r"|".join([re.escape(c) for c in _HTML5_FORM_ENCODING_REPLACEMENTS.keys()])) _HEADER_NAME_RE = re.compile(r"[!#$%&'*+\-.^_`|~0-9A-Za-z]+") _FORBIDDEN_HEADER_VALUE_CHARS_RE = re.compile(r"[\x00-\x08\x0a-\x1f\x7f]") def _format_form_param(name: str, value: str) -> bytes: """ Encode a name/value pair within a multipart form. """ def replacer(match: typing.Match[str]) -> str: return _HTML5_FORM_ENCODING_REPLACEMENTS[match.group(0)] value = _HTML5_FORM_ENCODING_RE.sub(replacer, value) return f'{name}="{value}"'.encode() def _guess_content_type(filename: str | None) -> str | None: """ Guesses the mimetype based on a filename. Defaults to `application/octet-stream`. Returns `None` if `filename` is `None` or empty. """ if filename: return mimetypes.guess_type(filename)[0] or "application/octet-stream" return None def get_multipart_boundary_from_content_type( content_type: bytes | None, ) -> bytes | None: if not content_type or not content_type.startswith(b"multipart/form-data"): return None # parse boundary according to # https://www.rfc-editor.org/rfc/rfc2046#section-5.1.1 if b";" in content_type: for section in content_type.split(b";"): if section.strip().lower().startswith(b"boundary="): return section.strip()[len(b"boundary=") :].strip(b'"') return None class DataField: """ A single form field item, within a multipart form field. """ def __init__(self, name: str, value: str | bytes | int | float | None) -> None: if not isinstance(name, str): raise TypeError(f"Invalid type for name. Expected str, got {type(name)}: {name!r}") if value is not None and not isinstance(value, (str, bytes, int, float)): raise TypeError(f"Invalid type for value. Expected primitive type, got {type(value)}: {value!r}") self.name = name self.value: str | bytes = value if isinstance(value, bytes) else primitive_value_to_str(value) def render_headers(self) -> bytes: if not hasattr(self, "_headers"): name = _format_form_param("name", self.name) self._headers = b"".join([b"Content-Disposition: form-data; ", name, b"\r\n\r\n"]) return self._headers def render_data(self) -> bytes: if not hasattr(self, "_data"): self._data = to_bytes(self.value) return self._data def get_length(self) -> int: headers = self.render_headers() data = self.render_data() return len(headers) + len(data) def render(self) -> typing.Iterator[bytes]: yield self.render_headers() yield self.render_data() class FileField: """ A single file field item, within a multipart form field. """ CHUNK_SIZE = 64 * 1024 def __init__(self, name: str, value: FileTypes) -> None: self.name = name fileobj: FileContent headers: dict[str, str] = {} content_type: str | None = None # This large tuple based API largely mirror's requests' API # It would be good to think of better APIs for this that we could # include in httpx 2.0 since variable length tuples(especially of 4 elements) # are quite unwieldy if isinstance(value, tuple): if len(value) == 2: # neither the 3rd parameter (content_type) nor the 4th (headers) # was included filename, fileobj = value elif len(value) == 3: filename, fileobj, content_type = value else: # all 4 parameters included filename, fileobj, content_type, headers = value # type: ignore else: filename = Path(str(getattr(value, "name", "upload"))).name fileobj = value if content_type is None: content_type = _guess_content_type(filename) has_content_type_header = any("content-type" in key.lower() for key in headers) if content_type is not None and not has_content_type_header: # note that unlike requests, we ignore the content_type provided in the 3rd # tuple element if it is also included in the headers requests does # the opposite (it overwrites the headerwith the 3rd tuple element) headers["Content-Type"] = content_type if isinstance(fileobj, io.StringIO): raise TypeError("Multipart file uploads require 'io.BytesIO', not 'io.StringIO'.") if isinstance(fileobj, io.TextIOBase): raise TypeError("Multipart file uploads must be opened in binary mode, not text mode.") self.filename = filename self.file = fileobj self.headers = headers def get_length(self) -> int | None: headers = self.render_headers() if isinstance(self.file, (str, bytes)): return len(headers) + len(to_bytes(self.file)) file_length = peek_filelike_length(self.file) # If we can't determine the filesize without reading it into memory, # then return `None` here, to indicate an unknown file length. if file_length is None: return None return len(headers) + file_length def render_headers(self) -> bytes: if not hasattr(self, "_headers"): parts = [ b"Content-Disposition: form-data; ", _format_form_param("name", self.name), ] if self.filename: filename = _format_form_param("filename", self.filename) parts.extend([b"; ", filename]) for header_name, header_value in self.headers.items(): if _HEADER_NAME_RE.fullmatch(header_name) is None: raise ValueError("Invalid multipart header name.") if _FORBIDDEN_HEADER_VALUE_CHARS_RE.search(header_value) is not None: raise ValueError("Invalid control character in multipart header value.") key, val = f"\r\n{header_name}: ".encode(), header_value.encode() parts.extend([key, val]) parts.append(b"\r\n\r\n") self._headers = b"".join(parts) return self._headers def render_data(self) -> typing.Iterator[bytes]: if isinstance(self.file, (str, bytes)): yield to_bytes(self.file) return if hasattr(self.file, "seek"): try: self.file.seek(0) except io.UnsupportedOperation: pass chunk = self.file.read(self.CHUNK_SIZE) while chunk: yield to_bytes(chunk) chunk = self.file.read(self.CHUNK_SIZE) def render(self) -> typing.Iterator[bytes]: yield self.render_headers() yield from self.render_data() class MultipartStream(SyncByteStream, AsyncByteStream): """ Request content as streaming multipart encoded form data. """ def __init__( self, data: RequestData, files: RequestFiles, boundary: bytes | None = None, ) -> None: if boundary is None: boundary = os.urandom(16).hex().encode("ascii") self.boundary = boundary self.content_type = f"multipart/form-data; boundary={boundary.decode('ascii')}" self.fields = list(self._iter_fields(data, files)) def _iter_fields(self, data: RequestData, files: RequestFiles) -> typing.Iterator[FileField | DataField]: for name, value in data.items(): if isinstance(value, (tuple, list)): for item in value: yield DataField(name=name, value=item) else: yield DataField(name=name, value=value) file_items = files.items() if isinstance(files, typing.Mapping) else files for name, value in file_items: yield FileField(name=name, value=value) def iter_chunks(self) -> typing.Iterator[bytes]: for field in self.fields: yield b"--%s\r\n" % self.boundary yield from field.render() yield b"\r\n" yield b"--%s--\r\n" % self.boundary def get_content_length(self) -> int | None: """ Return the length of the multipart encoded content, or `None` if any of the files have a length that cannot be determined upfront. """ boundary_length = len(self.boundary) length = 0 for field in self.fields: field_length = field.get_length() if field_length is None: return None length += 2 + boundary_length + 2 # b"--{boundary}\r\n" length += field_length length += 2 # b"\r\n" length += 2 + boundary_length + 4 # b"--{boundary}--\r\n" return length # Content stream interface. def get_headers(self) -> dict[str, str]: content_length = self.get_content_length() content_type = self.content_type if content_length is None: return {"Transfer-Encoding": "chunked", "Content-Type": content_type} return {"Content-Length": str(content_length), "Content-Type": content_type} def __iter__(self) -> typing.Iterator[bytes]: yield from self.iter_chunks() async def __aiter__(self) -> typing.AsyncIterator[bytes]: for chunk in self.iter_chunks(): yield chunk pydantic-httpx2-6dd59b9/src/httpx2/httpx2/_sse.py000066400000000000000000000166001526547463400220030ustar00rootroot00000000000000""" Server-sent events support, derived from httpx-sse (https://github.com/florimondmanca/httpx-sse). ``` MIT License Copyright (c) 2022 Florimond Manca 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. ``` """ from __future__ import annotations import json as jsonlib from collections.abc import AsyncIterator, Iterator from dataclasses import dataclass from ._config import DEFAULT_MAX_EVENT_SIZE_BYTES from ._exceptions import TransportError, request_context from ._models import Response __all__ = ["EventSource", "SSEError", "ServerSentEvent"] class SSEError(TransportError): """ An error that occurred while connecting to a server-sent events endpoint. """ @dataclass(frozen=True) class ServerSentEvent: event: str = "message" data: str = "" id: str = "" retry: int | None = None def json(self) -> object: return jsonlib.loads(self.data) class _SSEEventDecoder: def __init__(self, max_event_size: int | None = None) -> None: self._max_event_size = max_event_size self._event = "" self._data: list[str] = [] self._event_size = 0 self._last_event_id = "" self._retry: int | None = None self._pending = False def decode(self, line: str) -> ServerSentEvent | None: if not line: self._event_size = 0 if not self._pending: return None sse = ServerSentEvent( event=self._event or "message", data="\n".join(self._data), id=self._last_event_id, retry=self._retry, ) self._event = "" self._data = [] self._retry = None self._pending = False return sse if line.startswith(":"): return None self._event_size += len(line.encode("utf-8")) self._check_size() fieldname, _, value = line.partition(":") value = value[1:] if value.startswith(" ") else value if fieldname == "event": self._event = value self._pending = True elif fieldname == "data": self._data.append(value) self._pending = True elif fieldname == "id": if "\0" not in value: self._last_event_id = value self._pending = True elif fieldname == "retry": try: self._retry = int(value) self._pending = True except ValueError: pass return None def check_pending(self, pending_size: int) -> None: """ Bound the total bytes buffered for the in-progress event, including a trailing line that has not been terminated by a newline yet. """ self._check_size(pending_size) def _check_size(self, pending_size: int = 0) -> None: if self._max_event_size is not None and self._event_size + pending_size > self._max_event_size: raise SSEError(f"Server-sent event exceeded the {self._max_event_size} byte limit.") class _SSELineDecoder: def __init__(self) -> None: self._parts: list[str] = [] self._pending_size = 0 self._trailing_cr = False @property def pending_size(self) -> int: return self._pending_size def decode(self, text: str) -> list[str]: if self._trailing_cr: text = "\r" + text self._trailing_cr = False if text.endswith("\r"): self._trailing_cr = True text = text[:-1] text = text.replace("\r\n", "\n").replace("\r", "\n") if "\n" not in text: self._append(text) return [] lines = text.split("\n") self._append(lines[0]) lines[0] = self._consume_pending() self._append(lines.pop()) return lines def flush(self) -> list[str]: if self._trailing_cr: self._append("\n") self._trailing_cr = False buffer = self._consume_pending() if not buffer: return [] return buffer.split("\n") def _append(self, text: str) -> None: if text: self._parts.append(text) self._pending_size += len(text.encode("utf-8")) def _consume_pending(self) -> str: pending = "".join(self._parts) self._parts = [] self._pending_size = 0 return pending class _SSEParser: def __init__(self, max_event_size: int | None = None) -> None: self._event_decoder = _SSEEventDecoder(max_event_size) self._line_decoder = _SSELineDecoder() def decode(self, text: str) -> Iterator[ServerSentEvent]: yield from self._decode_lines(self._line_decoder.decode(text)) self._event_decoder.check_pending(self._line_decoder.pending_size) def flush(self) -> Iterator[ServerSentEvent]: yield from self._decode_lines(self._line_decoder.flush()) def _decode_lines(self, lines: list[str]) -> Iterator[ServerSentEvent]: for line in lines: sse = self._event_decoder.decode(line) if sse is not None: yield sse class EventSource: def __init__(self, response: Response, max_event_size: int | None = DEFAULT_MAX_EVENT_SIZE_BYTES) -> None: self._response = response self._max_event_size = max_event_size @property def response(self) -> Response: return self._response def _check_content_type(self) -> None: content_type, _, _ = self._response.headers.get("content-type", "").partition(";") if content_type.strip().lower() != "text/event-stream": raise SSEError(f"Expected response with content type 'text/event-stream', got {content_type.strip()!r}.") def __iter__(self) -> Iterator[ServerSentEvent]: with request_context(request=self._response.request): self._check_content_type() parser = _SSEParser(self._max_event_size) for chunk in self._response.iter_text(): yield from parser.decode(chunk) yield from parser.flush() async def __aiter__(self) -> AsyncIterator[ServerSentEvent]: with request_context(request=self._response.request): self._check_content_type() parser = _SSEParser(self._max_event_size) async for chunk in self._response.aiter_text(): for sse in parser.decode(chunk): yield sse for sse in parser.flush(): yield sse pydantic-httpx2-6dd59b9/src/httpx2/httpx2/_status_codes.py000066400000000000000000000147411526547463400237150ustar00rootroot00000000000000from __future__ import annotations import warnings from enum import EnumMeta, IntEnum __all__ = ["codes"] # Constant names that were renamed by RFC 9110, kept as deprecated aliases # mapping each old name to its canonical replacement. _DEPRECATED_CODES = { "REQUEST_ENTITY_TOO_LARGE": "CONTENT_TOO_LARGE", "REQUEST_URI_TOO_LONG": "URI_TOO_LONG", "REQUESTED_RANGE_NOT_SATISFIABLE": "RANGE_NOT_SATISFIABLE", "UNPROCESSABLE_ENTITY": "UNPROCESSABLE_CONTENT", } class _CodesMeta(EnumMeta): def __getattribute__(cls, name: str) -> object: if name in _DEPRECATED_CODES: new_name = _DEPRECATED_CODES[name] warnings.warn( f"'{name}' is deprecated. Use '{new_name}' instead.", category=DeprecationWarning, stacklevel=2, ) return super().__getattribute__(name) class codes(IntEnum, metaclass=_CodesMeta): """HTTP status codes and reason phrases Status codes from the following RFCs are all observed: * RFC 9110: HTTP Semantics, obsoletes 7231 & 7238 * RFC 6585: Additional HTTP Status Codes * RFC 3229: Delta encoding in HTTP * RFC 4918: HTTP Extensions for WebDAV, obsoletes 2518 * RFC 5842: Binding Extensions to WebDAV * RFC 2295: Transparent Content Negotiation in HTTP * RFC 2774: An HTTP Extension Framework * RFC 7540: Hypertext Transfer Protocol Version 2 (HTTP/2) * RFC 2324: Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0) * RFC 7725: An HTTP Status Code to Report Legal Obstacles * RFC 8297: An HTTP Status Code for Indicating Hints * RFC 8470: Using Early Data in HTTP """ def __new__(cls, value: int, phrase: str = "") -> codes: obj = int.__new__(cls, value) obj._value_ = value obj.phrase = phrase # type: ignore[attr-defined] return obj def __str__(self) -> str: return str(self.value) @classmethod def get_reason_phrase(cls, value: int) -> str: try: return codes(value).phrase # type: ignore except ValueError: return "" @classmethod def is_informational(cls, value: int) -> bool: """ Returns `True` for 1xx status codes, `False` otherwise. """ return 100 <= value <= 199 @classmethod def is_success(cls, value: int) -> bool: """ Returns `True` for 2xx status codes, `False` otherwise. """ return 200 <= value <= 299 @classmethod def is_redirect(cls, value: int) -> bool: """ Returns `True` for 3xx status codes, `False` otherwise. """ return 300 <= value <= 399 @classmethod def is_client_error(cls, value: int) -> bool: """ Returns `True` for 4xx status codes, `False` otherwise. """ return 400 <= value <= 499 @classmethod def is_server_error(cls, value: int) -> bool: """ Returns `True` for 5xx status codes, `False` otherwise. """ return 500 <= value <= 599 @classmethod def is_error(cls, value: int) -> bool: """ Returns `True` for 4xx or 5xx status codes, `False` otherwise. """ return 400 <= value <= 599 # informational CONTINUE = 100, "Continue" SWITCHING_PROTOCOLS = 101, "Switching Protocols" PROCESSING = 102, "Processing" EARLY_HINTS = 103, "Early Hints" # success OK = 200, "OK" CREATED = 201, "Created" ACCEPTED = 202, "Accepted" NON_AUTHORITATIVE_INFORMATION = 203, "Non-Authoritative Information" NO_CONTENT = 204, "No Content" RESET_CONTENT = 205, "Reset Content" PARTIAL_CONTENT = 206, "Partial Content" MULTI_STATUS = 207, "Multi-Status" ALREADY_REPORTED = 208, "Already Reported" IM_USED = 226, "IM Used" # redirection MULTIPLE_CHOICES = 300, "Multiple Choices" MOVED_PERMANENTLY = 301, "Moved Permanently" FOUND = 302, "Found" SEE_OTHER = 303, "See Other" NOT_MODIFIED = 304, "Not Modified" USE_PROXY = 305, "Use Proxy" TEMPORARY_REDIRECT = 307, "Temporary Redirect" PERMANENT_REDIRECT = 308, "Permanent Redirect" # client error BAD_REQUEST = 400, "Bad Request" UNAUTHORIZED = 401, "Unauthorized" PAYMENT_REQUIRED = 402, "Payment Required" FORBIDDEN = 403, "Forbidden" NOT_FOUND = 404, "Not Found" METHOD_NOT_ALLOWED = 405, "Method Not Allowed" NOT_ACCEPTABLE = 406, "Not Acceptable" PROXY_AUTHENTICATION_REQUIRED = 407, "Proxy Authentication Required" REQUEST_TIMEOUT = 408, "Request Timeout" CONFLICT = 409, "Conflict" GONE = 410, "Gone" LENGTH_REQUIRED = 411, "Length Required" PRECONDITION_FAILED = 412, "Precondition Failed" CONTENT_TOO_LARGE = 413, "Content Too Large" URI_TOO_LONG = 414, "URI Too Long" UNSUPPORTED_MEDIA_TYPE = 415, "Unsupported Media Type" RANGE_NOT_SATISFIABLE = 416, "Range Not Satisfiable" EXPECTATION_FAILED = 417, "Expectation Failed" IM_A_TEAPOT = 418, "I'm a teapot" MISDIRECTED_REQUEST = 421, "Misdirected Request" UNPROCESSABLE_CONTENT = 422, "Unprocessable Content" LOCKED = 423, "Locked" FAILED_DEPENDENCY = 424, "Failed Dependency" TOO_EARLY = 425, "Too Early" UPGRADE_REQUIRED = 426, "Upgrade Required" PRECONDITION_REQUIRED = 428, "Precondition Required" TOO_MANY_REQUESTS = 429, "Too Many Requests" REQUEST_HEADER_FIELDS_TOO_LARGE = 431, "Request Header Fields Too Large" UNAVAILABLE_FOR_LEGAL_REASONS = 451, "Unavailable For Legal Reasons" # server errors INTERNAL_SERVER_ERROR = 500, "Internal Server Error" NOT_IMPLEMENTED = 501, "Not Implemented" BAD_GATEWAY = 502, "Bad Gateway" SERVICE_UNAVAILABLE = 503, "Service Unavailable" GATEWAY_TIMEOUT = 504, "Gateway Timeout" HTTP_VERSION_NOT_SUPPORTED = 505, "HTTP Version Not Supported" VARIANT_ALSO_NEGOTIATES = 506, "Variant Also Negotiates" INSUFFICIENT_STORAGE = 507, "Insufficient Storage" LOOP_DETECTED = 508, "Loop Detected" NOT_EXTENDED = 510, "Not Extended" NETWORK_AUTHENTICATION_REQUIRED = 511, "Network Authentication Required" # Deprecated aliases for names replaced by RFC 9110. REQUEST_ENTITY_TOO_LARGE = CONTENT_TOO_LARGE REQUEST_URI_TOO_LONG = URI_TOO_LONG REQUESTED_RANGE_NOT_SATISFIABLE = RANGE_NOT_SATISFIABLE UNPROCESSABLE_ENTITY = UNPROCESSABLE_CONTENT # Include lower-case styles for `requests` compatibility. for name, code in codes.__members__.items(): setattr(codes, name.lower(), int(code)) pydantic-httpx2-6dd59b9/src/httpx2/httpx2/_transports/000077500000000000000000000000001526547463400230535ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/src/httpx2/httpx2/_transports/__init__.py000066400000000000000000000013071526547463400251650ustar00rootroot00000000000000import sys from .asgi import ASGITransport from .base import AsyncBaseTransport, BaseTransport from .mock import MockTransport from .wsgi import WSGITransport if sys.platform == "emscripten": # pragma: nocover if sys.version_info < (3, 12): raise RuntimeError("httpx2 requires Python 3.12+ on Emscripten.") from httpx2_jsfetch import ( AsyncJavascriptFetchTransport as AsyncHTTPTransport, JavascriptFetchTransport as HTTPTransport, ) else: from .default import AsyncHTTPTransport, HTTPTransport __all__ = [ "ASGITransport", "AsyncBaseTransport", "BaseTransport", "AsyncHTTPTransport", "HTTPTransport", "MockTransport", "WSGITransport", ] pydantic-httpx2-6dd59b9/src/httpx2/httpx2/_transports/asgi.py000066400000000000000000000124651526547463400243600ustar00rootroot00000000000000from __future__ import annotations import typing from .._models import Request, Response from .._types import AsyncByteStream from .base import AsyncBaseTransport if typing.TYPE_CHECKING: import asyncio import trio Event = asyncio.Event | trio.Event _Message = typing.MutableMapping[str, typing.Any] _Receive = typing.Callable[[], typing.Awaitable[_Message]] _Send = typing.Callable[[typing.MutableMapping[str, typing.Any]], typing.Awaitable[None]] _ASGIApp = typing.Callable[[typing.MutableMapping[str, typing.Any], _Receive, _Send], typing.Awaitable[None]] __all__ = ["ASGITransport"] def is_running_trio() -> bool: try: # sniffio is a dependency of trio. # See https://github.com/python-trio/trio/issues/2802 import sniffio if sniffio.current_async_library() == "trio": return True except ImportError: # pragma: no cover pass return False def create_event() -> Event: if is_running_trio(): import trio return trio.Event() import asyncio return asyncio.Event() class ASGIResponseStream(AsyncByteStream): def __init__(self, body: list[bytes]) -> None: self._body = body async def __aiter__(self) -> typing.AsyncIterator[bytes]: yield b"".join(self._body) class ASGITransport(AsyncBaseTransport): """ A custom AsyncTransport that handles sending requests directly to an ASGI app. ```python transport = httpx2.ASGITransport( app=app, root_path="/submount", client=("1.2.3.4", 123) ) client = httpx2.AsyncClient(transport=transport) ``` Arguments: app: The ASGI application. raise_app_exceptions: Boolean indicating if exceptions in the application should be raised. Default to `True`. Can be set to `False` for use cases such as testing the content of a client 500 response. root_path: The root path on which the ASGI application should be mounted. client: A two-tuple indicating the client IP and port of incoming requests. """ def __init__( self, app: _ASGIApp, raise_app_exceptions: bool = True, root_path: str = "", client: tuple[str, int] = ("127.0.0.1", 123), ) -> None: self.app = app self.raise_app_exceptions = raise_app_exceptions self.root_path = root_path self.client = client async def handle_async_request(self, request: Request) -> Response: assert isinstance(request.stream, AsyncByteStream) # ASGI scope. scope = { "type": "http", "asgi": {"version": "3.0"}, "http_version": "1.1", "method": request.method, "headers": [(k.lower(), v) for (k, v) in request.headers.raw], "scheme": request.url.scheme, "path": request.url.path, "raw_path": request.url.raw_path.split(b"?")[0], "query_string": request.url.query, "server": (request.url.host, request.url.port), "client": self.client, "root_path": self.root_path, } # Request. request_body_chunks = request.stream.__aiter__() request_complete = False # Response. status_code = None response_headers = None body_parts: list[bytes] = [] response_started = False response_complete = create_event() # ASGI callables. async def receive() -> dict[str, typing.Any]: nonlocal request_complete if request_complete: await response_complete.wait() return {"type": "http.disconnect"} try: body = await request_body_chunks.__anext__() except StopAsyncIteration: request_complete = True return {"type": "http.request", "body": b"", "more_body": False} return {"type": "http.request", "body": body, "more_body": True} async def send(message: typing.MutableMapping[str, typing.Any]) -> None: nonlocal status_code, response_headers, response_started if message["type"] == "http.response.start": assert not response_started status_code = message["status"] response_headers = message.get("headers", []) response_started = True elif message["type"] == "http.response.body": assert not response_complete.is_set() body = message.get("body", b"") more_body = message.get("more_body", False) if body and request.method != "HEAD": body_parts.append(body) if not more_body: response_complete.set() try: await self.app(scope, receive, send) except Exception: if self.raise_app_exceptions: raise response_complete.set() if status_code is None: status_code = 500 if response_headers is None: response_headers = {} assert response_complete.is_set() assert status_code is not None assert response_headers is not None stream = ASGIResponseStream(body_parts) return Response(status_code, headers=response_headers, stream=stream) pydantic-httpx2-6dd59b9/src/httpx2/httpx2/_transports/base.py000066400000000000000000000050301526547463400243350ustar00rootroot00000000000000from __future__ import annotations import typing from types import TracebackType from .._models import Request, Response # TODO(Marcelo): When Python 3.10 reaches EOF, we can use `typing.Self` instead of defining those two. T = typing.TypeVar("T", bound="BaseTransport") A = typing.TypeVar("A", bound="AsyncBaseTransport") __all__ = ["AsyncBaseTransport", "BaseTransport"] class BaseTransport: def __enter__(self: T) -> T: return self def __exit__( self, exc_type: type[BaseException] | None = None, exc_value: BaseException | None = None, traceback: TracebackType | None = None, ) -> None: self.close() def handle_request(self, request: Request) -> Response: """ Send a single HTTP request and return a response. Developers shouldn't typically ever need to call into this API directly, since the Client class provides all the higher level user-facing API niceties. In order to properly release any network resources, the response stream should *either* be consumed immediately, with a call to `response.stream.read()`, or else the `handle_request` call should be followed with a try/finally block to ensuring the stream is always closed. Example usage: with httpx2.HTTPTransport() as transport: req = httpx2.Request( method=b"GET", url=(b"https", b"www.example.com", 443, b"/"), headers=[(b"Host", b"www.example.com")], ) resp = transport.handle_request(req) body = resp.stream.read() print(resp.status_code, resp.headers, body) Takes a `Request` instance as the only argument. Returns a `Response` instance. """ raise NotImplementedError("The 'handle_request' method must be implemented.") # pragma: no cover def close(self) -> None: pass class AsyncBaseTransport: async def __aenter__(self: A) -> A: return self async def __aexit__( self, exc_type: type[BaseException] | None = None, exc_value: BaseException | None = None, traceback: TracebackType | None = None, ) -> None: await self.aclose() async def handle_async_request( self, request: Request, ) -> Response: raise NotImplementedError("The 'handle_async_request' method must be implemented.") # pragma: no cover async def aclose(self) -> None: pass pydantic-httpx2-6dd59b9/src/httpx2/httpx2/_transports/default.py000066400000000000000000000331311526547463400250520ustar00rootroot00000000000000""" Custom transports, with nicely configured defaults. The following additional keyword arguments are currently supported by httpcore... * uds: str * local_address: str * retries: int Example usages... # Disable HTTP/2 on a single specific domain. mounts = { "all://": httpx2.HTTPTransport(http2=True), "all://*example.org": httpx2.HTTPTransport() } # Using advanced httpcore configuration, with connection retries. transport = httpx2.HTTPTransport(retries=1) client = httpx2.Client(transport=transport) # Using advanced httpcore configuration, with unix domain sockets. transport = httpx2.HTTPTransport(uds="socket.uds") client = httpx2.Client(transport=transport) """ from __future__ import annotations import contextlib import typing from collections.abc import Generator from types import TracebackType if typing.TYPE_CHECKING: # pragma: no cover import ssl import httpx2 from .._config import DEFAULT_LIMITS, Limits, Proxy, create_ssl_context from .._exceptions import ( ConnectError, ConnectTimeout, LocalProtocolError, NetworkError, PoolTimeout, ProtocolError, ProxyError, ReadError, ReadTimeout, RemoteProtocolError, TimeoutException, UnsupportedProtocol, WriteError, WriteTimeout, ) from .._models import Request, Response from .._types import AsyncByteStream, CertTypes, ProxyTypes, SyncByteStream from .._urls import URL from .base import AsyncBaseTransport, BaseTransport T = typing.TypeVar("T", bound="HTTPTransport") A = typing.TypeVar("A", bound="AsyncHTTPTransport") SOCKET_OPTION = tuple[int, int, int] | tuple[int, int, bytes | bytearray] | tuple[int, int, None, int] __all__ = ["AsyncHTTPTransport", "HTTPTransport"] HTTPCORE_EXC_MAP: dict[type[Exception], type[httpx2.HTTPError]] = {} def _load_httpcore_exceptions() -> dict[type[Exception], type[httpx2.HTTPError]]: import httpcore2 return { httpcore2.TimeoutException: TimeoutException, httpcore2.ConnectTimeout: ConnectTimeout, httpcore2.ReadTimeout: ReadTimeout, httpcore2.WriteTimeout: WriteTimeout, httpcore2.PoolTimeout: PoolTimeout, httpcore2.NetworkError: NetworkError, httpcore2.ConnectError: ConnectError, httpcore2.ReadError: ReadError, httpcore2.WriteError: WriteError, httpcore2.ProxyError: ProxyError, httpcore2.UnsupportedProtocol: UnsupportedProtocol, httpcore2.ProtocolError: ProtocolError, httpcore2.LocalProtocolError: LocalProtocolError, httpcore2.RemoteProtocolError: RemoteProtocolError, } @contextlib.contextmanager def map_httpcore_exceptions() -> Generator[None]: global HTTPCORE_EXC_MAP if len(HTTPCORE_EXC_MAP) == 0: HTTPCORE_EXC_MAP = _load_httpcore_exceptions() try: yield except Exception as exc: mapped_exc = None for from_exc, to_exc in HTTPCORE_EXC_MAP.items(): if not isinstance(exc, from_exc): continue # We want to map to the most specific exception we can find. # Eg if `exc` is an `httpcore2.ReadTimeout`, we want to map to # `httpx2.ReadTimeout`, not just `httpx2.TimeoutException`. if mapped_exc is None or issubclass(to_exc, mapped_exc): mapped_exc = to_exc if mapped_exc is None: # pragma: no cover raise message = str(exc) raise mapped_exc(message) from exc class ResponseStream(SyncByteStream): def __init__(self, httpcore_stream: typing.Iterable[bytes]) -> None: self._httpcore_stream = httpcore_stream def __iter__(self) -> typing.Iterator[bytes]: with map_httpcore_exceptions(): yield from self._httpcore_stream def close(self) -> None: if hasattr(self._httpcore_stream, "close"): self._httpcore_stream.close() class HTTPTransport(BaseTransport): def __init__( self, verify: ssl.SSLContext | str | bool = True, cert: CertTypes | None = None, trust_env: bool = True, http1: bool = True, http2: bool = False, limits: Limits = DEFAULT_LIMITS, proxy: ProxyTypes | None = None, uds: str | None = None, local_address: str | None = None, retries: int = 0, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> None: import httpcore2 proxy = Proxy(url=proxy) if isinstance(proxy, (str, URL)) else proxy ssl_context = create_ssl_context(verify=verify, cert=cert, trust_env=trust_env) if proxy is None: self._pool = httpcore2.ConnectionPool( ssl_context=ssl_context, max_connections=limits.max_connections, max_keepalive_connections=limits.max_keepalive_connections, keepalive_expiry=limits.keepalive_expiry, http1=http1, http2=http2, uds=uds, local_address=local_address, retries=retries, socket_options=socket_options, ) elif proxy.url.scheme in ("http", "https"): self._pool = httpcore2.HTTPProxy( proxy_url=httpcore2.URL( scheme=proxy.url.raw_scheme, host=proxy.url.raw_host, port=proxy.url.port, target=proxy.url.raw_path, ), proxy_auth=proxy.raw_auth, proxy_headers=proxy.headers.raw, ssl_context=ssl_context, proxy_ssl_context=proxy.ssl_context, max_connections=limits.max_connections, max_keepalive_connections=limits.max_keepalive_connections, keepalive_expiry=limits.keepalive_expiry, http1=http1, http2=http2, socket_options=socket_options, ) elif proxy.url.scheme in ("socks5", "socks5h"): try: import socksio # noqa except ImportError: # pragma: no cover raise ImportError( "Using SOCKS proxy, but the 'socksio' package is not installed. " "Make sure to install httpx using `pip install httpx[socks]`." ) from None self._pool = httpcore2.SOCKSProxy( proxy_url=httpcore2.URL( scheme=proxy.url.raw_scheme, host=proxy.url.raw_host, port=proxy.url.port, target=proxy.url.raw_path, ), proxy_auth=proxy.raw_auth, ssl_context=ssl_context, max_connections=limits.max_connections, max_keepalive_connections=limits.max_keepalive_connections, keepalive_expiry=limits.keepalive_expiry, http1=http1, http2=http2, ) else: # pragma: no cover raise ValueError( f"Proxy protocol must be either 'http', 'https', 'socks5', or 'socks5h', but got {proxy.url.scheme!r}." ) def __enter__(self: T) -> T: # Use generics for subclass support. self._pool.__enter__() return self def __exit__( self, exc_type: type[BaseException] | None = None, exc_value: BaseException | None = None, traceback: TracebackType | None = None, ) -> None: with map_httpcore_exceptions(): self._pool.__exit__(exc_type, exc_value, traceback) def handle_request( self, request: Request, ) -> Response: assert isinstance(request.stream, SyncByteStream) import httpcore2 req = httpcore2.Request( method=request.method, url=httpcore2.URL( scheme=request.url.raw_scheme, host=request.url.raw_host, port=request.url.port, target=request.url.raw_path, ), headers=request.headers.raw, content=request.stream, extensions=request.extensions, ) with map_httpcore_exceptions(): resp = self._pool.handle_request(req) assert isinstance(resp.stream, typing.Iterable) return Response( status_code=resp.status, headers=resp.headers, stream=ResponseStream(resp.stream), extensions=resp.extensions, ) def close(self) -> None: self._pool.close() class AsyncResponseStream(AsyncByteStream): def __init__(self, httpcore_stream: typing.AsyncIterable[bytes]) -> None: self._httpcore_stream = httpcore_stream async def __aiter__(self) -> typing.AsyncIterator[bytes]: with map_httpcore_exceptions(): async for part in self._httpcore_stream: yield part async def aclose(self) -> None: if hasattr(self._httpcore_stream, "aclose"): await self._httpcore_stream.aclose() class AsyncHTTPTransport(AsyncBaseTransport): def __init__( self, verify: ssl.SSLContext | str | bool = True, cert: CertTypes | None = None, trust_env: bool = True, http1: bool = True, http2: bool = False, limits: Limits = DEFAULT_LIMITS, proxy: ProxyTypes | None = None, uds: str | None = None, local_address: str | None = None, retries: int = 0, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> None: import httpcore2 proxy = Proxy(url=proxy) if isinstance(proxy, (str, URL)) else proxy ssl_context = create_ssl_context(verify=verify, cert=cert, trust_env=trust_env) if proxy is None: self._pool = httpcore2.AsyncConnectionPool( ssl_context=ssl_context, max_connections=limits.max_connections, max_keepalive_connections=limits.max_keepalive_connections, keepalive_expiry=limits.keepalive_expiry, http1=http1, http2=http2, uds=uds, local_address=local_address, retries=retries, socket_options=socket_options, ) elif proxy.url.scheme in ("http", "https"): self._pool = httpcore2.AsyncHTTPProxy( proxy_url=httpcore2.URL( scheme=proxy.url.raw_scheme, host=proxy.url.raw_host, port=proxy.url.port, target=proxy.url.raw_path, ), proxy_auth=proxy.raw_auth, proxy_headers=proxy.headers.raw, proxy_ssl_context=proxy.ssl_context, ssl_context=ssl_context, max_connections=limits.max_connections, max_keepalive_connections=limits.max_keepalive_connections, keepalive_expiry=limits.keepalive_expiry, http1=http1, http2=http2, socket_options=socket_options, ) elif proxy.url.scheme in ("socks5", "socks5h"): try: import socksio # noqa except ImportError: # pragma: no cover raise ImportError( "Using SOCKS proxy, but the 'socksio' package is not installed. " "Make sure to install httpx using `pip install httpx[socks]`." ) from None self._pool = httpcore2.AsyncSOCKSProxy( proxy_url=httpcore2.URL( scheme=proxy.url.raw_scheme, host=proxy.url.raw_host, port=proxy.url.port, target=proxy.url.raw_path, ), proxy_auth=proxy.raw_auth, ssl_context=ssl_context, max_connections=limits.max_connections, max_keepalive_connections=limits.max_keepalive_connections, keepalive_expiry=limits.keepalive_expiry, http1=http1, http2=http2, ) else: # pragma: no cover raise ValueError( f"Proxy protocol must be either 'http', 'https', 'socks5', or 'socks5h', but got {proxy.url.scheme!r}." ) async def __aenter__(self: A) -> A: # Use generics for subclass support. await self._pool.__aenter__() return self async def __aexit__( self, exc_type: type[BaseException] | None = None, exc_value: BaseException | None = None, traceback: TracebackType | None = None, ) -> None: with map_httpcore_exceptions(): await self._pool.__aexit__(exc_type, exc_value, traceback) async def handle_async_request( self, request: Request, ) -> Response: assert isinstance(request.stream, AsyncByteStream) import httpcore2 req = httpcore2.Request( method=request.method, url=httpcore2.URL( scheme=request.url.raw_scheme, host=request.url.raw_host, port=request.url.port, target=request.url.raw_path, ), headers=request.headers.raw, content=request.stream, extensions=request.extensions, ) with map_httpcore_exceptions(): resp = await self._pool.handle_async_request(req) assert isinstance(resp.stream, typing.AsyncIterable) return Response( status_code=resp.status, headers=resp.headers, stream=AsyncResponseStream(resp.stream), extensions=resp.extensions, ) async def aclose(self) -> None: await self._pool.aclose() pydantic-httpx2-6dd59b9/src/httpx2/httpx2/_transports/mock.py000066400000000000000000000022711526547463400243600ustar00rootroot00000000000000from __future__ import annotations import typing from .._models import Request, Response from .base import AsyncBaseTransport, BaseTransport SyncHandler = typing.Callable[[Request], Response] AsyncHandler = typing.Callable[[Request], typing.Coroutine[None, None, Response]] __all__ = ["MockTransport"] class MockTransport(AsyncBaseTransport, BaseTransport): def __init__(self, handler: SyncHandler | AsyncHandler) -> None: self.handler = handler def handle_request( self, request: Request, ) -> Response: request.read() response = self.handler(request) if not isinstance(response, Response): # pragma: no cover raise TypeError("Cannot use an async handler in a sync Client") return response async def handle_async_request(self, request: Request) -> Response: await request.aread() response = self.handler(request) # Allow handler to *optionally* be an `async` function. # If it is, then the `response` variable need to be awaited to actually # return the result. if not isinstance(response, Response): response = await response return response pydantic-httpx2-6dd59b9/src/httpx2/httpx2/_transports/wsgi.py000066400000000000000000000114501526547463400243770ustar00rootroot00000000000000from __future__ import annotations import io import itertools import sys import typing from .._models import Request, Response from .._types import SyncByteStream from .base import BaseTransport if typing.TYPE_CHECKING: from _typeshed import OptExcInfo # pragma: no cover from _typeshed.wsgi import WSGIApplication # pragma: no cover _T = typing.TypeVar("_T") __all__ = ["WSGITransport"] def _skip_leading_empty_chunks(body: typing.Iterable[_T]) -> typing.Iterable[_T]: body = iter(body) for chunk in body: if chunk: return itertools.chain([chunk], body) return [] class WSGIByteStream(SyncByteStream): def __init__(self, result: typing.Iterable[bytes]) -> None: self._close = getattr(result, "close", None) self._result = _skip_leading_empty_chunks(result) def __iter__(self) -> typing.Iterator[bytes]: yield from self._result def close(self) -> None: if self._close is not None: self._close() class WSGITransport(BaseTransport): """ A custom transport that handles sending requests directly to an WSGI app. The simplest way to use this functionality is to use the `app` argument. ``` client = httpx2.Client(app=app) ``` Alternatively, you can setup the transport instance explicitly. This allows you to include any additional configuration arguments specific to the WSGITransport class: ``` transport = httpx2.WSGITransport( app=app, script_name="/submount", remote_addr="1.2.3.4" ) client = httpx2.Client(transport=transport) ``` Arguments: app: The WSGI application. raise_app_exceptions: Boolean indicating if exceptions in the application should be raised. Default to `True`. Can be set to `False` for use cases such as testing the content of a client 500 response. script_name: The root path on which the WSGI application should be mounted. remote_addr: A string indicating the client IP of incoming requests. """ def __init__( self, app: WSGIApplication, raise_app_exceptions: bool = True, script_name: str = "", remote_addr: str = "127.0.0.1", wsgi_errors: typing.TextIO | None = None, ) -> None: self.app = app self.raise_app_exceptions = raise_app_exceptions self.script_name = script_name self.remote_addr = remote_addr self.wsgi_errors = wsgi_errors def handle_request(self, request: Request) -> Response: request.read() wsgi_input = io.BytesIO(request.content) port = request.url.port or {"http": 80, "https": 443}[request.url.scheme] environ = { "wsgi.version": (1, 0), "wsgi.url_scheme": request.url.scheme, "wsgi.input": wsgi_input, "wsgi.errors": self.wsgi_errors or sys.stderr, "wsgi.multithread": True, "wsgi.multiprocess": False, "wsgi.run_once": False, "REQUEST_METHOD": request.method, "SCRIPT_NAME": self.script_name, "PATH_INFO": request.url.path, "QUERY_STRING": request.url.query.decode("ascii"), "SERVER_NAME": request.url.host, "SERVER_PORT": str(port), "SERVER_PROTOCOL": "HTTP/1.1", "REMOTE_ADDR": self.remote_addr, } if request.content and "Content-Length" not in request.headers: environ["CONTENT_LENGTH"] = str(len(request.content)) for header_key, header_value in request.headers.raw: key = header_key.decode("ascii").upper().replace("-", "_") if key not in ("CONTENT_TYPE", "CONTENT_LENGTH"): key = "HTTP_" + key environ[key] = header_value.decode("ascii") seen_status = None seen_response_headers = None seen_exc_info = None def start_response( status: str, response_headers: list[tuple[str, str]], exc_info: OptExcInfo | None = None, ) -> typing.Callable[[bytes], typing.Any]: nonlocal seen_status, seen_response_headers, seen_exc_info seen_status = status seen_response_headers = response_headers seen_exc_info = exc_info return lambda _: None result = self.app(environ, start_response) stream = WSGIByteStream(result) assert seen_status is not None assert seen_response_headers is not None if seen_exc_info and seen_exc_info[0] and self.raise_app_exceptions: raise seen_exc_info[1] status_code = int(seen_status.split()[0]) headers = [(key.encode("ascii"), value.encode("ascii")) for key, value in seen_response_headers] return Response(status_code, headers=headers, stream=stream) pydantic-httpx2-6dd59b9/src/httpx2/httpx2/_types.py000066400000000000000000000051571526547463400223620ustar00rootroot00000000000000""" Type definitions for type checking purposes. """ from collections.abc import AsyncIterable, AsyncIterator, Callable, Iterable, Iterator, Mapping, Sequence from http.cookiejar import CookieJar from typing import IO, TYPE_CHECKING, Any, Union if TYPE_CHECKING: from ._auth import Auth # noqa: F401 from ._config import Proxy, Timeout # noqa: F401 from ._models import Cookies, Headers, Request # noqa: F401 from ._urls import URL, QueryParams # noqa: F401 PrimitiveData = str | int | float | bool | None URLTypes = Union["URL", str] QueryParamTypes = Union[ "QueryParams", Mapping[str, PrimitiveData | Sequence[PrimitiveData]], list[tuple[str, PrimitiveData]], tuple[tuple[str, PrimitiveData], ...], str, bytes, ] HeaderTypes = Union[ "Headers", Mapping[str, str], Mapping[bytes, bytes], Sequence[tuple[str, str]], Sequence[tuple[bytes, bytes]], ] CookieTypes = Union["Cookies", CookieJar, dict[str, str], list[tuple[str, str]]] TimeoutTypes = Union[float | None, tuple[float | None, float | None, float | None, float | None], "Timeout"] ProxyTypes = Union["URL", str, "Proxy"] CertTypes = str | tuple[str, str] | tuple[str, str, str] AuthTypes = Union[tuple[str | bytes, str | bytes], Callable[["Request"], "Request"], "Auth"] RequestContent = str | bytes | Iterable[bytes] | AsyncIterable[bytes] ResponseContent = str | bytes | Iterable[bytes] | AsyncIterable[bytes] ResponseExtensions = Mapping[str, Any] RequestData = Mapping[str, Any] FileContent = IO[bytes] | bytes | str FileTypes = ( # # file (or bytes) FileContent # # (filename, file (or bytes)) | tuple[str | None, FileContent] # # (filename, file (or bytes), content_type) | tuple[str | None, FileContent, str | None] | tuple[str | None, FileContent, str | None, Mapping[str, str]] ) RequestFiles = Mapping[str, FileTypes] | Sequence[tuple[str, FileTypes]] RequestExtensions = Mapping[str, Any] __all__ = ["AsyncByteStream", "SyncByteStream"] class SyncByteStream: def __iter__(self) -> Iterator[bytes]: raise NotImplementedError("The '__iter__' method must be implemented.") # pragma: no cover yield b"" # pragma: no cover def close(self) -> None: """ Subclasses can override this method to release any network resources after a request/response cycle is complete. """ class AsyncByteStream: async def __aiter__(self) -> AsyncIterator[bytes]: raise NotImplementedError("The '__aiter__' method must be implemented.") # pragma: no cover yield b"" # pragma: no cover async def aclose(self) -> None: pass pydantic-httpx2-6dd59b9/src/httpx2/httpx2/_urlparse.py000066400000000000000000000436231526547463400230530ustar00rootroot00000000000000""" An implementation of `urlparse` that provides URL validation and normalization as described by RFC3986. We rely on this implementation rather than the one in Python's stdlib, because: * It provides more complete URL validation. * It properly differentiates between an empty querystring and an absent querystring, to distinguish URLs with a trailing '?'. * It handles scheme, hostname, port, and path normalization. * It supports IDNA hostnames, normalizing them to their encoded form. * The API supports passing individual components, as well as the complete URL string. Previously we relied on the excellent `rfc3986` package to handle URL parsing and validation, but this module provides a simpler alternative, with less indirection required. """ from __future__ import annotations import ipaddress import re import typing import idna from ._exceptions import InvalidURL MAX_URL_LENGTH = 65536 # https://datatracker.ietf.org/doc/html/rfc3986.html#section-2.3 UNRESERVED_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~" SUB_DELIMS = "!$&'()*+,;=" PERCENT_ENCODED_REGEX = re.compile("%[A-Fa-f0-9]{2}") # https://url.spec.whatwg.org/#percent-encoded-bytes # The fragment percent-encode set is the C0 control percent-encode set # and U+0020 SPACE, U+0022 ("), U+003C (<), U+003E (>), and U+0060 (`). FRAG_SAFE = "".join([chr(i) for i in range(0x20, 0x7F) if i not in (0x20, 0x22, 0x3C, 0x3E, 0x60)]) # The query percent-encode set is the C0 control percent-encode set # and U+0020 SPACE, U+0022 ("), U+0023 (#), U+003C (<), and U+003E (>). QUERY_SAFE = "".join([chr(i) for i in range(0x20, 0x7F) if i not in (0x20, 0x22, 0x23, 0x3C, 0x3E)]) # The path percent-encode set is the query percent-encode set # and U+003F (?), U+0060 (`), U+007B ({), and U+007D (}). PATH_SAFE = "".join( [chr(i) for i in range(0x20, 0x7F) if i not in (0x20, 0x22, 0x23, 0x3C, 0x3E) + (0x3F, 0x60, 0x7B, 0x7D)] ) # The userinfo percent-encode set is the path percent-encode set # and U+002F (/), U+003A (:), U+003B (;), U+003D (=), U+0040 (@), # U+005B ([) to U+005E (^), inclusive, and U+007C (|). USERNAME_SAFE = "".join( [ chr(i) for i in range(0x20, 0x7F) if i not in (0x20, 0x22, 0x23, 0x3C, 0x3E) + (0x3F, 0x60, 0x7B, 0x7D) + (0x2F, 0x3A, 0x3B, 0x3D, 0x40, 0x5B, 0x5C, 0x5D, 0x5E, 0x7C) ] ) PASSWORD_SAFE = "".join( [ chr(i) for i in range(0x20, 0x7F) if i not in (0x20, 0x22, 0x23, 0x3C, 0x3E) + (0x3F, 0x60, 0x7B, 0x7D) + (0x2F, 0x3A, 0x3B, 0x3D, 0x40, 0x5B, 0x5C, 0x5D, 0x5E, 0x7C) ] ) # Note... The terminology 'userinfo' percent-encode set in the WHATWG document # is used for the username and password quoting. For the joint userinfo component # we remove U+003A (:) from the safe set. USERINFO_SAFE = "".join( [ chr(i) for i in range(0x20, 0x7F) if i not in (0x20, 0x22, 0x23, 0x3C, 0x3E) + (0x3F, 0x60, 0x7B, 0x7D) + (0x2F, 0x3B, 0x3D, 0x40, 0x5B, 0x5C, 0x5D, 0x5E, 0x7C) ] ) # {scheme}: (optional) # //{authority} (optional) # {path} # ?{query} (optional) # #{fragment} (optional) URL_REGEX = re.compile( ( r"(?:(?P{scheme}):)?" r"(?://(?P{authority}))?" r"(?P{path})" r"(?:\?(?P{query}))?" r"(?:#(?P{fragment}))?" ).format( scheme="([a-zA-Z][a-zA-Z0-9+.-]*)?", authority="[^/?#]*", path="[^?#]*", query="[^#]*", fragment=".*", ) ) # {userinfo}@ (optional) # {host} # :{port} (optional) AUTHORITY_REGEX = re.compile( (r"(?:(?P{userinfo})@)?" r"(?P{host})" r":?(?P{port})?").format( userinfo=".*", # Any character sequence. host="(\\[.*\\]|[^:@]*)", # Either any character sequence excluding ':' or '@', # or an IPv6 address enclosed within square brackets. port=".*", # Any character sequence. ) ) # If we call urlparse with an individual component, then we need to regex # validate that component individually. # Note that we're duplicating the same strings as above. Shock! Horror!! COMPONENT_REGEX = { "scheme": re.compile("([a-zA-Z][a-zA-Z0-9+.-]*)?"), "authority": re.compile("[^/?#]*"), "path": re.compile("[^?#]*"), "query": re.compile("[^#]*"), "fragment": re.compile(".*"), "userinfo": re.compile("[^@]*"), "host": re.compile("(\\[.*\\]|[^:]*)"), "port": re.compile(".*"), } # We use these simple regexs as a first pass before handing off to # the stdlib 'ipaddress' module for IP address validation. IPv4_STYLE_HOSTNAME = re.compile(r"^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$") IPv6_STYLE_HOSTNAME = re.compile(r"^\[.*\]$") class ParseResult(typing.NamedTuple): scheme: str userinfo: str host: str port: int | None path: str query: str | None fragment: str | None @property def authority(self) -> str: return "".join( [ f"{self.userinfo}@" if self.userinfo else "", f"[{self.host}]" if ":" in self.host else self.host, f":{self.port}" if self.port is not None else "", ] ) @property def netloc(self) -> str: return "".join( [ f"[{self.host}]" if ":" in self.host else self.host, f":{self.port}" if self.port is not None else "", ] ) def copy_with(self, **kwargs: str | None) -> ParseResult: if not kwargs: return self defaults = { "scheme": self.scheme, "authority": self.authority, "path": self.path, "query": self.query, "fragment": self.fragment, } defaults.update(kwargs) return urlparse("", **defaults) def __str__(self) -> str: authority = self.authority return "".join( [ f"{self.scheme}:" if self.scheme else "", f"//{authority}" if authority else "", self.path, f"?{self.query}" if self.query is not None else "", f"#{self.fragment}" if self.fragment is not None else "", ] ) def urlparse(url: str = "", **kwargs: str | None) -> ParseResult: # Initial basic checks on allowable URLs. # --------------------------------------- # Hard limit the maximum allowable URL length. if len(url) > MAX_URL_LENGTH: raise InvalidURL("URL too long") # If a URL includes any ASCII control characters including \t, \r, \n, # then treat it as invalid. if any(char.isascii() and not char.isprintable() for char in url): char = next(char for char in url if char.isascii() and not char.isprintable()) idx = url.find(char) error = f"Invalid non-printable ASCII character in URL, {char!r} at position {idx}." raise InvalidURL(error) # Some keyword arguments require special handling. # ------------------------------------------------ # Coerce "port" to a string, if it is provided as an integer. if "port" in kwargs: port = kwargs["port"] kwargs["port"] = str(port) if isinstance(port, int) else port # Replace "netloc" with "host and "port". if "netloc" in kwargs: netloc = kwargs.pop("netloc") or "" kwargs["host"], _, kwargs["port"] = netloc.partition(":") # Replace "username" and/or "password" with "userinfo". if "username" in kwargs or "password" in kwargs: username = quote(kwargs.pop("username", "") or "", safe=USERNAME_SAFE) password = quote(kwargs.pop("password", "") or "", safe=PASSWORD_SAFE) kwargs["userinfo"] = f"{username}:{password}" if password else username # Replace "raw_path" with "path" and "query". if "raw_path" in kwargs: raw_path = kwargs.pop("raw_path") or "" kwargs["path"], separator, kwargs["query"] = raw_path.partition("?") if not separator: kwargs["query"] = None # Ensure that IPv6 "host" addresses are always escaped with "[...]". if "host" in kwargs: host = kwargs.get("host") or "" if ":" in host and not (host.startswith("[") and host.endswith("]")): kwargs["host"] = f"[{host}]" # If any keyword arguments are provided, ensure they are valid. # ------------------------------------------------------------- for key, value in kwargs.items(): if value is not None: if len(value) > MAX_URL_LENGTH: raise InvalidURL(f"URL component '{key}' too long") # If a component includes any ASCII control characters including \t, \r, \n, # then treat it as invalid. if any(char.isascii() and not char.isprintable() for char in value): char = next(char for char in value if char.isascii() and not char.isprintable()) idx = value.find(char) error = f"Invalid non-printable ASCII character in URL {key} component, {char!r} at position {idx}." raise InvalidURL(error) # Ensure that keyword arguments match as a valid regex. if not COMPONENT_REGEX[key].fullmatch(value): raise InvalidURL(f"Invalid URL component '{key}'") # The URL_REGEX will always match, but may have empty components. url_match = URL_REGEX.match(url) assert url_match is not None url_dict = url_match.groupdict() # * 'scheme', 'authority', and 'path' may be empty strings. # * 'query' may be 'None', indicating no trailing "?" portion. # Any string including the empty string, indicates a trailing "?". # * 'fragment' may be 'None', indicating no trailing "#" portion. # Any string including the empty string, indicates a trailing "#". scheme = kwargs.get("scheme", url_dict["scheme"]) or "" authority = kwargs.get("authority", url_dict["authority"]) or "" path = kwargs.get("path", url_dict["path"]) or "" query = kwargs.get("query", url_dict["query"]) frag = kwargs.get("fragment", url_dict["fragment"]) # The AUTHORITY_REGEX will always match, but may have empty components. authority_match = AUTHORITY_REGEX.match(authority) assert authority_match is not None authority_dict = authority_match.groupdict() # * 'userinfo' and 'host' may be empty strings. # * 'port' may be 'None'. userinfo = kwargs.get("userinfo", authority_dict["userinfo"]) or "" host = kwargs.get("host", authority_dict["host"]) or "" port = kwargs.get("port", authority_dict["port"]) # Normalize and validate each component. # We end up with a parsed representation of the URL, # with components that are plain ASCII bytestrings. parsed_scheme: str = scheme.lower() parsed_userinfo: str = quote(userinfo, safe=USERINFO_SAFE) parsed_host: str = encode_host(host) parsed_port: int | None = normalize_port(port, scheme) has_scheme = parsed_scheme != "" has_authority = parsed_userinfo != "" or parsed_host != "" or parsed_port is not None validate_path(path, has_scheme=has_scheme, has_authority=has_authority) if has_scheme or has_authority: path = normalize_path(path) parsed_path: str = quote(path, safe=PATH_SAFE) parsed_query: str | None = None if query is None else quote(query, safe=QUERY_SAFE) parsed_frag: str | None = None if frag is None else quote(frag, safe=FRAG_SAFE) # The parsed ASCII bytestrings are our canonical form. # All properties of the URL are derived from these. return ParseResult( parsed_scheme, parsed_userinfo, parsed_host, parsed_port, parsed_path, parsed_query, parsed_frag, ) def encode_host(host: str) -> str: if not host: return "" elif IPv4_STYLE_HOSTNAME.match(host): # Validate IPv4 hostnames like #.#.#.# # # From https://datatracker.ietf.org/doc/html/rfc3986/#section-3.2.2 # # IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet try: ipaddress.IPv4Address(host) except ipaddress.AddressValueError: raise InvalidURL(f"Invalid IPv4 address: {host!r}") return host elif IPv6_STYLE_HOSTNAME.match(host): # Validate IPv6 hostnames like [...] # # From https://datatracker.ietf.org/doc/html/rfc3986/#section-3.2.2 # # "A host identified by an Internet Protocol literal address, version 6 # [RFC3513] or later, is distinguished by enclosing the IP literal # within square brackets ("[" and "]"). This is the only place where # square bracket characters are allowed in the URI syntax." try: ipaddress.IPv6Address(host[1:-1]) except ipaddress.AddressValueError: raise InvalidURL(f"Invalid IPv6 address: {host!r}") return host[1:-1] elif host.isascii(): # Regular ASCII hostnames # # From https://datatracker.ietf.org/doc/html/rfc3986/#section-3.2.2 # # reg-name = *( unreserved / pct-encoded / sub-delims ) WHATWG_SAFE = '"`{}%|\\' return quote(host.lower(), safe=SUB_DELIMS + WHATWG_SAFE) # IDNA hostnames try: return idna.encode(host.lower()).decode("ascii") except idna.IDNAError: raise InvalidURL(f"Invalid IDNA hostname: {host!r}") def normalize_port(port: str | int | None, scheme: str) -> int | None: # From https://tools.ietf.org/html/rfc3986#section-3.2.3 # # "A scheme may define a default port. For example, the "http" scheme # defines a default port of "80", corresponding to its reserved TCP # port number. The type of port designated by the port number (e.g., # TCP, UDP, SCTP) is defined by the URI scheme. URI producers and # normalizers should omit the port component and its ":" delimiter if # port is empty or if its value would be the same as that of the # scheme's default." if port is None or port == "": return None try: port_as_int = int(port) except ValueError: raise InvalidURL(f"Invalid port: {port!r}") # See https://url.spec.whatwg.org/#url-miscellaneous default_port = {"ftp": 21, "http": 80, "https": 443, "ws": 80, "wss": 443}.get(scheme) if port_as_int == default_port: return None return port_as_int def validate_path(path: str, has_scheme: bool, has_authority: bool) -> None: """ Path validation rules that depend on if the URL contains a scheme or authority component. See https://datatracker.ietf.org/doc/html/rfc3986.html#section-3.3 """ if has_authority: # If a URI contains an authority component, then the path component # must either be empty or begin with a slash ("/") character." if path and not path.startswith("/"): raise InvalidURL("For absolute URLs, path must be empty or begin with '/'") if not has_scheme and not has_authority: # If a URI does not contain an authority component, then the path cannot begin # with two slash characters ("//"). if path.startswith("//"): raise InvalidURL("Relative URLs cannot have a path starting with '//'") # In addition, a URI reference (Section 4.1) may be a relative-path reference, # in which case the first path segment cannot contain a colon (":") character. if path.startswith(":"): raise InvalidURL("Relative URLs cannot have a path starting with ':'") def normalize_path(path: str) -> str: """ Drop "." and ".." segments from a URL path. For example: normalize_path("/path/./to/somewhere/..") == "/path/to" """ # Fast return when no '.' characters in the path. if "." not in path: return path components = path.split("/") # Fast return when no '.' or '..' components in the path. if "." not in components and ".." not in components: return path # https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.4 output: list[str] = [] for component in components: if component == ".": pass elif component == "..": if output and output != [""]: output.pop() else: output.append(component) return "/".join(output) def PERCENT(string: str) -> str: return "".join([f"%{byte:02X}" for byte in string.encode("utf-8")]) def percent_encoded(string: str, safe: str) -> str: """ Use percent-encoding to quote a string. """ NON_ESCAPED_CHARS = UNRESERVED_CHARACTERS + safe # Fast path for strings that don't need escaping. if not string.rstrip(NON_ESCAPED_CHARS): return string return "".join([char if char in NON_ESCAPED_CHARS else PERCENT(char) for char in string]) def quote(string: str, safe: str) -> str: """ Use percent-encoding to quote a string, omitting existing '%xx' escape sequences. See: https://www.rfc-editor.org/rfc/rfc3986#section-2.1 * `string`: The string to be percent-escaped. * `safe`: A string containing characters that may be treated as safe, and do not need to be escaped. Unreserved characters are always treated as safe. See: https://www.rfc-editor.org/rfc/rfc3986#section-2.3 """ parts: list[str] = [] current_position = 0 for match in re.finditer(PERCENT_ENCODED_REGEX, string): start_position, end_position = match.start(), match.end() matched_text = match.group(0) # Add any text up to the '%xx' escape sequence. if start_position != current_position: leading_text = string[current_position:start_position] parts.append(percent_encoded(leading_text, safe=safe)) # Add the '%xx' escape sequence. parts.append(matched_text) current_position = end_position # Add any text after the final '%xx' escape sequence. if current_position != len(string): trailing_text = string[current_position:] parts.append(percent_encoded(trailing_text, safe=safe)) return "".join(parts) pydantic-httpx2-6dd59b9/src/httpx2/httpx2/_urls.py000066400000000000000000000552201526547463400221770ustar00rootroot00000000000000from __future__ import annotations import ipaddress import sys import typing from dataclasses import dataclass from urllib.parse import parse_qs, unquote, urlencode import idna if sys.version_info >= (3, 13): from warnings import deprecated # pragma: no cover else: from typing_extensions import deprecated # pragma: no cover from ._exceptions import HTTPXDeprecationWarning from ._types import QueryParamTypes from ._urlparse import urlparse from ._utils import primitive_value_to_str __all__ = ["URL", "Origin", "QueryParams"] class URL: """ url = httpx2.URL("HTTPS://jo%40email.com:a%20secret@mรผller.de:1234/pa%20th?search=ab#anchorlink") assert url.scheme == "https" assert url.username == "jo@email.com" assert url.password == "a secret" assert url.userinfo == b"jo%40email.com:a%20secret" assert url.host == "mรผller.de" assert url.raw_host == b"xn--mller-kva.de" assert url.port == 1234 assert url.netloc == b"xn--mller-kva.de:1234" assert url.path == "/pa th" assert url.query == b"search=ab" assert url.raw_path == b"/pa%20th?search=ab" assert url.fragment == "anchorlink" The components of a URL are broken down like this: https://jo%40email.com:a%20secret@mรผller.de:1234/pa%20th?search=ab#anchorlink [scheme] [ username ] [password] [ host ][port][ path ] [ query ] [fragment] [ userinfo ] [ netloc ][ raw_path ] Note that: * `url.scheme` is normalized to always be lowercased. * `url.host` is normalized to always be lowercased. Internationalized domain names are represented in unicode, without IDNA encoding applied. For instance: url = httpx2.URL("http://ไธญๅ›ฝ.icom.museum") assert url.host == "ไธญๅ›ฝ.icom.museum" url = httpx2.URL("http://xn--fiqs8s.icom.museum") assert url.host == "ไธญๅ›ฝ.icom.museum" * `url.raw_host` is normalized to always be lowercased, and is IDNA encoded. url = httpx2.URL("http://ไธญๅ›ฝ.icom.museum") assert url.raw_host == b"xn--fiqs8s.icom.museum" url = httpx2.URL("http://xn--fiqs8s.icom.museum") assert url.raw_host == b"xn--fiqs8s.icom.museum" * `url.port` is either None or an integer. URLs that include the default port for "http", "https", "ws", "wss", and "ftp" schemes have their port normalized to `None`. assert httpx2.URL("http://example.com") == httpx2.URL("http://example.com:80") assert httpx2.URL("http://example.com").port is None assert httpx2.URL("http://example.com:80").port is None * `url.userinfo` is raw bytes, without URL escaping. Usually you'll want to work with `url.username` and `url.password` instead, which handle the URL escaping. * `url.raw_path` is raw bytes of both the path and query, without URL escaping. This portion is used as the target when constructing HTTP requests. Usually you'll want to work with `url.path` instead. * `url.query` is raw bytes, without URL escaping. A URL query string portion can only be properly URL escaped when decoding the parameter names and values themselves. """ def __init__(self, url: URL | str = "", **kwargs: typing.Any) -> None: if kwargs: allowed = { "scheme": str, "username": str, "password": str, "userinfo": bytes, "host": str, "port": int, "netloc": bytes, "path": str, "query": bytes, "raw_path": bytes, "fragment": str, "params": object, } # Perform type checking for all supported keyword arguments. for key, value in kwargs.items(): if key not in allowed: message = f"{key!r} is an invalid keyword argument for URL()" raise TypeError(message) if value is not None and not isinstance(value, allowed[key]): expected = allowed[key].__name__ seen = type(value).__name__ message = f"Argument {key!r} must be {expected} but got {seen}" raise TypeError(message) if isinstance(value, bytes): kwargs[key] = value.decode("ascii") if "params" in kwargs: # Replace any "params" keyword with the raw "query" instead. # # Ensure that empty params use `kwargs["query"] = None` rather # than `kwargs["query"] = ""`, so that generated URLs do not # include an empty trailing "?". params = kwargs.pop("params") kwargs["query"] = None if not params else str(QueryParams(params)) if isinstance(url, str): self._uri_reference = urlparse(url, **kwargs) elif isinstance(url, URL): self._uri_reference = url._uri_reference.copy_with(**kwargs) else: raise TypeError(f"Invalid type for url. Expected str or httpx2.URL, got {type(url)}: {url!r}") @property def scheme(self) -> str: """ The URL scheme, such as "http", "https". Always normalised to lowercase. """ return self._uri_reference.scheme @property def raw_scheme(self) -> bytes: """ The raw bytes representation of the URL scheme, such as b"http", b"https". Always normalised to lowercase. """ return self._uri_reference.scheme.encode("ascii") @property def userinfo(self) -> bytes: """ The URL userinfo as a raw bytestring. For example: b"jo%40email.com:a%20secret". """ return self._uri_reference.userinfo.encode("ascii") @property def username(self) -> str: """ The URL username as a string, with URL decoding applied. For example: "jo@email.com" """ userinfo = self._uri_reference.userinfo return unquote(userinfo.partition(":")[0]) @property def password(self) -> str: """ The URL password as a string, with URL decoding applied. For example: "a secret" """ userinfo = self._uri_reference.userinfo return unquote(userinfo.partition(":")[2]) @property def host(self) -> str: """ The URL host as a string. Always normalized to lowercase, with IDNA hosts decoded into unicode. Examples: url = httpx2.URL("http://www.EXAMPLE.org") assert url.host == "www.example.org" url = httpx2.URL("http://ไธญๅ›ฝ.icom.museum") assert url.host == "ไธญๅ›ฝ.icom.museum" url = httpx2.URL("http://xn--fiqs8s.icom.museum") assert url.host == "ไธญๅ›ฝ.icom.museum" url = httpx2.URL("https://[::ffff:192.168.0.1]") assert url.host == "::ffff:192.168.0.1" """ host: str = self._uri_reference.host if "xn--" in host: host = idna.decode(host, display=True) return host @property def raw_host(self) -> bytes: """ The raw bytes representation of the URL host. Always normalized to lowercase, and IDNA encoded. Examples: url = httpx2.URL("http://www.EXAMPLE.org") assert url.raw_host == b"www.example.org" url = httpx2.URL("http://ไธญๅ›ฝ.icom.museum") assert url.raw_host == b"xn--fiqs8s.icom.museum" url = httpx2.URL("http://xn--fiqs8s.icom.museum") assert url.raw_host == b"xn--fiqs8s.icom.museum" url = httpx2.URL("https://[::ffff:192.168.0.1]") assert url.raw_host == b"::ffff:192.168.0.1" """ return self._uri_reference.host.encode("ascii") @property def port(self) -> int | None: """ The URL port as an integer. Note that the URL class performs port normalization as per the WHATWG spec. Default ports for "http", "https", "ws", "wss", and "ftp" schemes are always treated as `None`. For example: assert httpx2.URL("http://www.example.com") == httpx2.URL("http://www.example.com:80") assert httpx2.URL("http://www.example.com:80").port is None """ return self._uri_reference.port @property def netloc(self) -> bytes: """ Either `` or `:` as bytes. Always normalized to lowercase, and IDNA encoded. This property may be used for generating the value of a request "Host" header. """ return self._uri_reference.netloc.encode("ascii") @property def path(self) -> str: """ The URL path as a string. Excluding the query string, and URL decoded. For example: url = httpx2.URL("https://example.com/pa%20th") assert url.path == "/pa th" """ path = self._uri_reference.path or "/" return unquote(path) @property def query(self) -> bytes: """ The URL query string, as raw bytes, excluding the leading b"?". This is necessarily a bytewise interface, because we cannot perform URL decoding of this representation until we've parsed the keys and values into a QueryParams instance. For example: url = httpx2.URL("https://example.com/?filter=some%20search%20terms") assert url.query == b"filter=some%20search%20terms" """ query = self._uri_reference.query or "" return query.encode("ascii") @property def params(self) -> QueryParams: """ The URL query parameters, neatly parsed and packaged into an immutable multidict representation. """ return QueryParams(self._uri_reference.query) @property def raw_path(self) -> bytes: """ The complete URL path and query string as raw bytes. Used as the target when constructing HTTP requests. For example: GET /users?search=some%20text HTTP/1.1 Host: www.example.org Connection: close """ path = self._uri_reference.path or "/" if self._uri_reference.query is not None: path += "?" + self._uri_reference.query return path.encode("ascii") @property def fragment(self) -> str: """ The URL fragments, as used in HTML anchors. As a string, without the leading '#'. """ return unquote(self._uri_reference.fragment or "") @property def is_absolute_url(self) -> bool: """ Return `True` for absolute URLs such as 'http://example.com/path', and `False` for relative URLs such as '/path'. """ # We don't use `.is_absolute` from `rfc3986` because it treats # URLs with a fragment portion as not absolute. # What we actually care about is if the URL provides # a scheme and hostname to which connections should be made. return bool(self._uri_reference.scheme and self._uri_reference.host) @property def is_relative_url(self) -> bool: """ Return `False` for absolute URLs such as 'http://example.com/path', and `True` for relative URLs such as '/path'. """ return not self.is_absolute_url @property def origin(self) -> Origin: """ The URL origin as an immutable, hashable `Origin` value. The origin consists of the URL scheme, host, and effective port. User information, path, query, and fragment components are excluded. """ return Origin(self) def copy_with(self, **kwargs: typing.Any) -> URL: """ Copy this URL, returning a new URL with some components altered. Accepts the same set of parameters as the components that are made available via properties on the `URL` class. For example: url = httpx2.URL("https://www.example.com").copy_with( username="jo@gmail.com", password="a secret" ) assert url == "https://jo%40email.com:a%20secret@www.example.com" """ return URL(self, **kwargs) def copy_set_param(self, key: str, value: typing.Any = None) -> URL: return self.copy_with(params=self.params.set(key, value)) def copy_add_param(self, key: str, value: typing.Any = None) -> URL: return self.copy_with(params=self.params.add(key, value)) def copy_remove_param(self, key: str) -> URL: return self.copy_with(params=self.params.remove(key)) def copy_merge_params(self, params: QueryParamTypes) -> URL: return self.copy_with(params=self.params.merge(params)) def join(self, url: URL | str) -> URL: """ Return an absolute URL, using this URL as the base. Eg. url = httpx2.URL("https://www.example.com/test") url = url.join("/new/path") assert url == "https://www.example.com/new/path" """ from urllib.parse import urljoin return URL(urljoin(str(self), str(URL(url)))) def __hash__(self) -> int: return hash(str(self)) def __eq__(self, other: typing.Any) -> bool: return isinstance(other, (URL, str)) and str(self) == str(URL(other)) def __str__(self) -> str: return str(self._uri_reference) def __repr__(self) -> str: scheme, userinfo, host, port, path, query, fragment = self._uri_reference if ":" in userinfo: # Mask any password component. userinfo = f"{userinfo.split(':')[0]}:[secure]" authority = "".join( [ f"{userinfo}@" if userinfo else "", f"[{host}]" if ":" in host else host, f":{port}" if port is not None else "", ] ) url = "".join( [ f"{self.scheme}:" if scheme else "", f"//{authority}" if authority else "", path, f"?{query}" if query is not None else "", f"#{fragment}" if fragment is not None else "", ] ) return f"{self.__class__.__name__}({url!r})" @property @deprecated("URL.raw is deprecated.", category=HTTPXDeprecationWarning) def raw(self) -> tuple[bytes, bytes, int, bytes]: # pragma: no cover import collections RawURL = collections.namedtuple("RawURL", ["raw_scheme", "raw_host", "port", "raw_path"]) return RawURL( raw_scheme=self.raw_scheme, raw_host=self.raw_host, port=self.port, raw_path=self.raw_path, ) _ORIGIN_DEFAULT_PORTS = { "ftp": 21, "http": 80, "https": 443, "ws": 80, "wss": 443, } @dataclass(frozen=True, slots=True, init=False) class Origin: """ The scheme, host, and effective port of a URL. Origins are normalized, immutable, comparable, and hashable. See RFC 9110, Section 4.3.1: https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin """ scheme: str host: str port: int | None def __init__(self, url: URL | str) -> None: if not isinstance(url, URL): url = URL(url) if url.is_relative_url: raise ValueError("URL must be absolute to have an origin") host = url.host if b":" in url.raw_host: # IPv6 addresses may have multiple equivalent string forms. Store # their canonical compressed form so origin equality is numeric. host = str(ipaddress.IPv6Address(url.raw_host.decode("ascii"))) port = url.port if port is None: port = _ORIGIN_DEFAULT_PORTS.get(url.scheme) object.__setattr__(self, "scheme", url.scheme) object.__setattr__(self, "host", host) object.__setattr__(self, "port", port) class QueryParams(typing.Mapping[str, str]): """ URL query parameters, as a multi-dict. """ def __init__(self, *args: QueryParamTypes | None, **kwargs: typing.Any) -> None: assert len(args) < 2, "Too many arguments." assert not (args and kwargs), "Cannot mix named and unnamed arguments." value = args[0] if args else kwargs if value is None or isinstance(value, (str, bytes)): value = value.decode("ascii") if isinstance(value, bytes) else value self._dict = parse_qs(value, keep_blank_values=True) elif isinstance(value, QueryParams): self._dict = {k: list(v) for k, v in value._dict.items()} else: dict_value: dict[typing.Any, list[typing.Any]] = {} if isinstance(value, (list, tuple)): # Convert list inputs like: # [("a", "123"), ("a", "456"), ("b", "789")] # To a dict representation, like: # {"a": ["123", "456"], "b": ["789"]} for item in value: dict_value.setdefault(item[0], []).append(item[1]) else: # Convert dict inputs like: # {"a": "123", "b": ["456", "789"]} # To dict inputs where values are always lists, like: # {"a": ["123"], "b": ["456", "789"]} dict_value = {k: list(v) if isinstance(v, (list, tuple)) else [v] for k, v in value.items()} # Ensure that keys and values are neatly coerced to strings. # We coerce values `True` and `False` to JSON-like "true" and "false" # representations, and coerce `None` values to the empty string. self._dict = {str(k): [primitive_value_to_str(item) for item in v] for k, v in dict_value.items()} def keys(self) -> typing.KeysView[str]: """ Return all the keys in the query params. Usage: q = httpx2.QueryParams("a=123&a=456&b=789") assert list(q.keys()) == ["a", "b"] """ return self._dict.keys() def values(self) -> typing.ValuesView[str]: """ Return all the values in the query params. If a key occurs more than once only the first item for that key is returned. Usage: q = httpx2.QueryParams("a=123&a=456&b=789") assert list(q.values()) == ["123", "789"] """ return {k: v[0] for k, v in self._dict.items()}.values() def items(self) -> typing.ItemsView[str, str]: """ Return all items in the query params. If a key occurs more than once only the first item for that key is returned. Usage: q = httpx2.QueryParams("a=123&a=456&b=789") assert list(q.items()) == [("a", "123"), ("b", "789")] """ return {k: v[0] for k, v in self._dict.items()}.items() def multi_items(self) -> list[tuple[str, str]]: """ Return all items in the query params. Allow duplicate keys to occur. Usage: q = httpx2.QueryParams("a=123&a=456&b=789") assert list(q.multi_items()) == [("a", "123"), ("a", "456"), ("b", "789")] """ multi_items: list[tuple[str, str]] = [] for k, v in self._dict.items(): multi_items.extend([(k, i) for i in v]) return multi_items def get(self, key: typing.Any, default: typing.Any = None) -> typing.Any: """ Get a value from the query param for a given key. If the key occurs more than once, then only the first value is returned. Usage: q = httpx2.QueryParams("a=123&a=456&b=789") assert q.get("a") == "123" """ if key in self._dict: return self._dict[str(key)][0] return default def get_list(self, key: str) -> list[str]: """ Get all values from the query param for a given key. Usage: q = httpx2.QueryParams("a=123&a=456&b=789") assert q.get_list("a") == ["123", "456"] """ return list(self._dict.get(str(key), [])) def set(self, key: str, value: typing.Any = None) -> QueryParams: """ Return a new QueryParams instance, setting the value of a key. Usage: q = httpx2.QueryParams("a=123") q = q.set("a", "456") assert q == httpx2.QueryParams("a=456") """ q = QueryParams() q._dict = dict(self._dict) q._dict[str(key)] = [primitive_value_to_str(value)] return q def add(self, key: str, value: typing.Any = None) -> QueryParams: """ Return a new QueryParams instance, setting or appending the value of a key. Usage: q = httpx2.QueryParams("a=123") q = q.add("a", "456") assert q == httpx2.QueryParams("a=123&a=456") """ q = QueryParams() q._dict = dict(self._dict) q._dict[str(key)] = q.get_list(key) + [primitive_value_to_str(value)] return q def remove(self, key: str) -> QueryParams: """ Return a new QueryParams instance, removing the value of a key. Usage: q = httpx2.QueryParams("a=123") q = q.remove("a") assert q == httpx2.QueryParams("") """ q = QueryParams() q._dict = dict(self._dict) q._dict.pop(str(key), None) return q def merge(self, params: QueryParamTypes | None = None) -> QueryParams: """ Return a new QueryParams instance, updated with. Usage: q = httpx2.QueryParams("a=123") q = q.merge({"b": "456"}) assert q == httpx2.QueryParams("a=123&b=456") q = httpx2.QueryParams("a=123") q = q.merge({"a": "456", "b": "789"}) assert q == httpx2.QueryParams("a=456&b=789") """ q = QueryParams(params) q._dict = {**self._dict, **q._dict} return q def __getitem__(self, key: typing.Any) -> str: return self._dict[key][0] def __contains__(self, key: typing.Any) -> bool: return key in self._dict def __iter__(self) -> typing.Iterator[typing.Any]: return iter(self.keys()) def __len__(self) -> int: return len(self._dict) def __bool__(self) -> bool: return bool(self._dict) def __hash__(self) -> int: return hash(str(self)) def __eq__(self, other: typing.Any) -> bool: if not isinstance(other, self.__class__): return False return sorted(self.multi_items()) == sorted(other.multi_items()) def __str__(self) -> str: return urlencode(self.multi_items()) def __repr__(self) -> str: class_name = self.__class__.__name__ query_string = str(self) return f"{class_name}({query_string!r})" def update(self, params: QueryParamTypes | None = None) -> None: raise RuntimeError("QueryParams are immutable since 0.18.0. Use `q = q.merge(...)` to create an updated copy.") def __setitem__(self, key: str, value: str) -> None: raise RuntimeError( "QueryParams are immutable since 0.18.0. Use `q = q.set(key, value)` to create an updated copy." ) pydantic-httpx2-6dd59b9/src/httpx2/httpx2/_utils.py000066400000000000000000000244341526547463400223550ustar00rootroot00000000000000from __future__ import annotations import ipaddress import os import re import typing from urllib.request import getproxies from ._exceptions import InvalidURL from ._types import PrimitiveData if typing.TYPE_CHECKING: from ._urls import URL def primitive_value_to_str(value: PrimitiveData) -> str: """ Coerce a primitive data type into a string value. Note that we prefer JSON-style 'true'/'false' for boolean values here. """ if value is True: return "true" elif value is False: return "false" elif value is None: return "" return str(value) def get_environment_proxies() -> dict[str, str | None]: """Gets proxy information from the environment""" # urllib.request.getproxies() falls back on System # Registry and Config for proxies on Windows and macOS. # We don't want to propagate non-HTTP proxies into # our configuration such as 'TRAVIS_APT_PROXY'. proxy_info = getproxies() mounts: dict[str, str | None] = {} for scheme in ("http", "https", "all"): if proxy_info.get(scheme): hostname = proxy_info[scheme] mounts[f"{scheme}://"] = hostname if "://" in hostname else f"http://{hostname}" no_proxy_hosts = [host.strip() for host in proxy_info.get("no", "").split(",")] for hostname in no_proxy_hosts: # See https://curl.haxx.se/libcurl/c/CURLOPT_NOPROXY.html for details # on how names in `NO_PROXY` are handled. if hostname == "*": # If NO_PROXY=* is used or if "*" occurs as any one of the comma # separated hostnames, then we should just bypass any information # from HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, and always ignore # proxies. return {} elif hostname: # NO_PROXY=.google.com is marked as "all://*.google.com, # which disables "www.google.com" but not "google.com" # NO_PROXY=google.com is marked as "all://*google.com, # which disables "www.google.com" and "google.com". # (But not "wwwgoogle.com") # NO_PROXY can include domains, IPv6, IPv4 addresses and "localhost" # NO_PROXY=example.com,::1,localhost,192.168.0.0/16 if "://" in hostname: mounts[hostname] = None elif is_ipv4_hostname(hostname): mounts[f"all://{hostname}"] = None elif is_ipv6_hostname(hostname): if "/" in hostname: addr, _, subnet = hostname.partition("/") mounts[f"all://[{addr}]/{subnet}"] = None else: mounts[f"all://[{hostname}]"] = None elif hostname.lower() == "localhost": mounts[f"all://{hostname}"] = None elif hostname.startswith("["): mounts[f"all://{hostname}"] = None elif "/" not in hostname: mounts[f"all://*{hostname}"] = None for pattern in list(mounts): try: URLPattern(pattern) except InvalidURL: del mounts[pattern] # Like curl and Go, ignore entries that cannot be parsed. return mounts def to_bytes(value: str | bytes, encoding: str = "utf-8") -> bytes: return value.encode(encoding) if isinstance(value, str) else value def to_str(value: str | bytes, encoding: str = "utf-8") -> str: return value if isinstance(value, str) else value.decode(encoding) def to_bytes_or_str(value: str, match_type_of: typing.AnyStr) -> typing.AnyStr: return value if isinstance(match_type_of, str) else value.encode() def peek_filelike_length(stream: typing.Any) -> int | None: """ Given a file-like stream object, return its length in number of bytes without reading it into memory. """ try: # Is it an actual file? fd = stream.fileno() # Yup, seems to be an actual file. length = os.fstat(fd).st_size except (AttributeError, OSError): # No... Maybe it's something that supports random access, like `io.BytesIO`? try: # Assuming so, go to end of stream to figure out its length, # then put it back in place. offset = stream.tell() length = stream.seek(0, os.SEEK_END) stream.seek(offset) except (AttributeError, OSError): # Not even that? Sorry, we're doomed... return None return length def peek_filelike_remaining_length(stream: typing.Any) -> int | None: """Return the remaining byte length without changing the stream position.""" try: offset: int = stream.tell() length: int = stream.seek(0, os.SEEK_END) stream.seek(offset) except (AttributeError, OSError): return None return max(0, length - offset) class URLPattern: """ A utility class currently used for making lookups against proxy keys... # Wildcard matching... >>> pattern = URLPattern("all://") >>> pattern.matches(httpx2.URL("http://example.com")) True # Witch scheme matching... >>> pattern = URLPattern("https://") >>> pattern.matches(httpx2.URL("https://example.com")) True >>> pattern.matches(httpx2.URL("http://example.com")) False # With domain matching... >>> pattern = URLPattern("https://example.com") >>> pattern.matches(httpx2.URL("https://example.com")) True >>> pattern.matches(httpx2.URL("http://example.com")) False >>> pattern.matches(httpx2.URL("https://other.com")) False # Wildcard scheme, with domain matching... >>> pattern = URLPattern("all://example.com") >>> pattern.matches(httpx2.URL("https://example.com")) True >>> pattern.matches(httpx2.URL("http://example.com")) True >>> pattern.matches(httpx2.URL("https://other.com")) False # With port matching... >>> pattern = URLPattern("https://example.com:1234") >>> pattern.matches(httpx2.URL("https://example.com:1234")) True >>> pattern.matches(httpx2.URL("https://example.com")) False """ def __init__(self, pattern: str) -> None: from ._urls import URL if pattern and ":" not in pattern: raise ValueError( f"Proxy keys should use proper URL forms rather " f"than plain scheme strings. " f'Instead of "{pattern}", use "{pattern}://"' ) url = URL(pattern) self.network = None prefix = url.path.removeprefix("/") if prefix and (is_ipv4_hostname(url.host) or is_ipv6_hostname(url.host)): # A CIDR-style host, e.g. "all://192.168.0.0/16" or "all://[::1]/64". host = f"[{url.host}]" if ":" in url.host else url.host if "@" in pattern or "%" in pattern or not prefix.isdigit() or not pattern.endswith(f"{host}/{prefix}"): raise InvalidURL(f"Invalid network in {pattern!r}") try: self.network = ipaddress.ip_network(f"{url.host}/{prefix}", strict=False) except ValueError as exc: raise InvalidURL(f"Invalid network in {pattern!r}") from exc self.pattern = pattern self.scheme = "" if url.scheme == "all" else url.scheme self.host = "" if url.host == "*" else url.host self.port = url.port if self.network is not None: self.host_regex: typing.Pattern[str] | None = None elif not url.host or url.host == "*": self.host_regex = None elif url.host.startswith("*."): # *.example.com should match "www.example.com", but not "example.com" domain = re.escape(url.host[2:]) self.host_regex = re.compile(f"^.+\\.{domain}$") elif url.host.startswith("*"): # *example.com should match "www.example.com" and "example.com" domain = re.escape(url.host[1:]) self.host_regex = re.compile(f"^(.+\\.)?{domain}$") else: # example.com should match "example.com" but not "www.example.com" domain = re.escape(url.host) self.host_regex = re.compile(f"^{domain}$") def matches(self, other: URL) -> bool: if self.scheme and self.scheme != other.scheme: return False if self.network is not None: try: other_address = ipaddress.ip_address(other.host) except ValueError: return False if other_address not in self.network: return False elif self.host and self.host_regex is not None and not self.host_regex.match(other.host): return False if self.port is not None and self.port != other.port: return False return True @property def priority(self) -> tuple[int, int, int, int, int]: """ The priority allows URLPattern instances to be sortable, so that we can match from most specific to least specific. """ # URLs with a port should take priority over URLs without a port. port_priority = 0 if self.port is not None else 1 # Exact hosts match first, then networks, then patterns without a host. host_kind_priority = 1 if self.network is not None else 0 if self.host else 2 # Smaller networks match first. Address count, not prefix length, so IPv4 and IPv6 compare fairly. network_priority = self.network.num_addresses if self.network is not None else 0 # Longer hostnames should match first. Networks are already ordered by size. host_priority = -len(self.host) if self.network is None else 0 # Longer schemes should match first. scheme_priority = -len(self.scheme) return (port_priority, host_kind_priority, network_priority, host_priority, scheme_priority) def __hash__(self) -> int: return hash(self.pattern) def __lt__(self, other: URLPattern) -> bool: return self.priority < other.priority def __eq__(self, other: typing.Any) -> bool: return isinstance(other, URLPattern) and self.pattern == other.pattern def is_ipv4_hostname(hostname: str) -> bool: try: ipaddress.IPv4Address(hostname.split("/")[0]) except Exception: return False return True def is_ipv6_hostname(hostname: str) -> bool: try: ipaddress.IPv6Address(hostname.split("/")[0]) except Exception: return False return True pydantic-httpx2-6dd59b9/src/httpx2/httpx2/py.typed000066400000000000000000000000001526547463400221620ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/src/httpx2/httpx2/websockets/000077500000000000000000000000001526547463400226465ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/src/httpx2/httpx2/websockets/__init__.py000066400000000000000000000034421526547463400247620ustar00rootroot00000000000000""" WebSocket support, derived from httpx-ws (https://github.com/frankie567/httpx-ws). ``` MIT License Copyright (c) 2021 Franรงois Voron 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. ``` """ from ._api import ( AsyncWebSocketClient, AsyncWebSocketSession, JSONMode, WebSocketClient, WebSocketSession, ) from ._exceptions import ( HTTPXWSException, WebSocketDisconnect, WebSocketInvalidTypeReceived, WebSocketNetworkError, WebSocketUpgradeError, ) from ._transport import ASGIWebSocketTransport __all__ = [ "ASGIWebSocketTransport", "AsyncWebSocketClient", "AsyncWebSocketSession", "HTTPXWSException", "JSONMode", "WebSocketClient", "WebSocketDisconnect", "WebSocketInvalidTypeReceived", "WebSocketNetworkError", "WebSocketSession", "WebSocketUpgradeError", ] pydantic-httpx2-6dd59b9/src/httpx2/httpx2/websockets/_api.py000066400000000000000000001734631526547463400241460ustar00rootroot00000000000000from __future__ import annotations import base64 import concurrent.futures import contextlib import json import queue import secrets import sys import threading import typing from types import TracebackType if sys.version_info >= (3, 13): from queue import ShutDown as QueueShutDown # pragma: no cover from typing import TypeVar # pragma: no cover else: from typing_extensions import TypeVar # pragma: no cover class QueueShutDown(Exception): # pragma: no cover """Stand-in for `queue.ShutDown`, which is never raised before Python 3.13.""" import anyio import wsproto import wsproto.utilities from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream from wsproto.frame_protocol import CloseReason from .._client import USE_CLIENT_DEFAULT from .._config import ( DEFAULT_KEEPALIVE_PING_INTERVAL_SECONDS, DEFAULT_KEEPALIVE_PING_TIMEOUT_SECONDS, DEFAULT_MAX_MESSAGE_SIZE_BYTES, DEFAULT_QUEUE_SIZE, ) from .._models import Headers from ._exceptions import ( HTTPXWSException, WebSocketDisconnect, WebSocketInvalidTypeReceived, WebSocketNetworkError, WebSocketUpgradeError, ) from ._ping import AsyncPingManager, PingManager from ._transport import ASGIWebSocketAsyncNetworkStream if typing.TYPE_CHECKING: from httpcore2 import AsyncNetworkStream, NetworkStream from .._client import AsyncClient, Client, UseClientDefault from .._models import Response from .._types import ( AuthTypes, CookieTypes, HeaderTypes, QueryParamTypes, RequestExtensions, TimeoutTypes, ) JSONMode = typing.Literal["text", "binary"] TaskFunction = typing.TypeVar("TaskFunction") TaskResult = typing.TypeVar("TaskResult") SyncSession = TypeVar("SyncSession", bound="WebSocketSession", default="WebSocketSession") AsyncSession = TypeVar("AsyncSession", bound="AsyncWebSocketSession", default="AsyncWebSocketSession") class ShouldClose(Exception): pass class EndOfStream(Exception): pass class WebSocketSession: """ Sync context manager representing an opened WebSocket session. Attributes: subprotocol (typing.Optional[str]): Optional protocol that has been accepted by the server. response (Response | None): The webSocket handshake response. """ subprotocol: str | None response: Response | None def __init__( self, stream: NetworkStream, *, max_message_size_bytes: int = DEFAULT_MAX_MESSAGE_SIZE_BYTES, queue_size: int = DEFAULT_QUEUE_SIZE, keepalive_ping_interval_seconds: float | None = DEFAULT_KEEPALIVE_PING_INTERVAL_SECONDS, keepalive_ping_timeout_seconds: float | None = DEFAULT_KEEPALIVE_PING_TIMEOUT_SECONDS, response: Response | None = None, ) -> None: self.stream = stream self.connection = wsproto.connection.Connection(wsproto.ConnectionType.CLIENT) self.response = response if self.response is not None: self.subprotocol = self.response.headers.get("sec-websocket-protocol") else: self.subprotocol = None self._events: queue.Queue[wsproto.events.Event | HTTPXWSException] = queue.Queue(queue_size) self._ping_manager = PingManager() self._should_close = threading.Event() self._write_lock = threading.Lock() self._should_close_task: concurrent.futures.Future[bool] | None = None self._executor: concurrent.futures.ThreadPoolExecutor | None = None self._max_message_size_bytes = max_message_size_bytes self._queue_size = queue_size self._keepalive_ping_interval_seconds = keepalive_ping_interval_seconds self._keepalive_ping_timeout_seconds = keepalive_ping_timeout_seconds def _get_executor_should_close_task( self, ) -> tuple[concurrent.futures.ThreadPoolExecutor, concurrent.futures.Future[bool]]: if self._should_close_task is None: self._executor = concurrent.futures.ThreadPoolExecutor() self._should_close_task = self._executor.submit(self._should_close.wait) assert self._executor is not None return self._executor, self._should_close_task def __enter__(self) -> WebSocketSession: self._background_receive_task = threading.Thread( target=self._background_receive, args=(self._max_message_size_bytes,) ) self._background_receive_task.start() self._background_keepalive_ping_task: threading.Thread | None = None if self._keepalive_ping_interval_seconds is not None: self._background_keepalive_ping_task = threading.Thread( target=self._background_keepalive_ping, args=( self._keepalive_ping_interval_seconds, self._keepalive_ping_timeout_seconds, ), ) self._background_keepalive_ping_task.start() return self def __exit__( self, exc_type: type[BaseException] | None, exc: BaseException | None, tb: TracebackType | None, ) -> None: self.close() # A task blocked on a full events queue only exits once there's room, or the queue shuts down. if sys.version_info >= (3, 13): # pragma: no cover - Python 3.13+ only self._events.shutdown(immediate=True) self._background_receive_task.join() if self._background_keepalive_ping_task is not None: self._background_keepalive_ping_task.join() else: # pragma: no cover - Python < 3.13 only for task in (self._background_receive_task, self._background_keepalive_ping_task): while task is not None and task.is_alive(): with contextlib.suppress(queue.Empty): self._events.get(timeout=0.01) def ping(self, payload: bytes = b"") -> threading.Event: """ Send a Ping message. Args: payload: Payload to attach to the Ping event. Internally, it's used to track this specific event. If left empty, a random one will be generated. Returns: An event that can be used to wait for the corresponding Pong response. Examples: Send a Ping and wait for the Pong pong_callback = ws.ping() # Will block until the corresponding Pong is received. pong_callback.wait() """ ping_id, callback = self._ping_manager.create(payload) event = wsproto.events.Ping(ping_id) self.send(event) return callback def send(self, event: wsproto.events.Event) -> None: """ Send an Event message. Mainly useful to send events that are not supported by the library. Most of the time, [ping()][httpx_ws.WebSocketSession.ping], [send_text()][httpx_ws.WebSocketSession.send_text], [send_bytes()][httpx_ws.WebSocketSession.send_bytes] and [send_json()][httpx_ws.WebSocketSession.send_json] are preferred. Args: event: The event to send. Raises: WebSocketNetworkError: A network error occured. Examples: Send an event. event = wsproto.events.Message(b"Hello!") ws.send(event) """ import httpcore2 try: data = self.connection.send(event) with self._write_lock: self.stream.write(data) except httpcore2.WriteError as e: self.close(CloseReason.INTERNAL_ERROR, "Stream write error") raise WebSocketNetworkError() from e def send_text(self, data: str) -> None: """ Send a text message. Args: data: The text to send. Raises: WebSocketNetworkError: A network error occured. Examples: Send a text message. ws.send_text("Hello!") """ event = wsproto.events.TextMessage(data=data) self.send(event) def send_bytes(self, data: bytes) -> None: """ Send a bytes message. Args: data: The data to send. Raises: WebSocketNetworkError: A network error occured. Examples: Send a bytes message. ws.send_bytes(b"Hello!") """ event = wsproto.events.BytesMessage(data=data) self.send(event) def send_json(self, data: typing.Any, mode: JSONMode = "text") -> None: """ Send JSON data. Args: data: The data to send. Must be serializable by [json.dumps][json.dumps]. mode: The sending mode. Should either be `'text'` or `'bytes'`. Raises: WebSocketNetworkError: A network error occured. Examples: Send JSON data. data = {"message": "Hello!"} ws.send_json(data) """ assert mode in ["text", "binary"] serialized_data = json.dumps(data) if mode == "text": self.send_text(serialized_data) else: self.send_bytes(serialized_data.encode("utf-8")) def receive(self, timeout: float | None = None) -> wsproto.events.Event: """ Receive an event from the server. Mainly useful to receive raw [wsproto.events.Event][wsproto.events.Event]. Most of the time, [receive_text()][httpx_ws.WebSocketSession.receive_text], [receive_bytes()][httpx_ws.WebSocketSession.receive_bytes], and [receive_json()][httpx_ws.WebSocketSession.receive_json] are preferred. Args: timeout: Number of seconds to wait for an event. If `None`, will block until an event is available. Returns: A raw [wsproto.events.Event][wsproto.events.Event]. Raises: TimeoutError: No event was received before the timeout delay. WebSocketDisconnect: The server closed the websocket. WebSocketNetworkError: A network error occured. Examples: Wait for an event until one is available. try: event = ws.receive() except WebSocketDisconnect: print("Connection closed") Wait for an event for 2 seconds. try: event = ws.receive(timeout=2.) except TimeoutError: print("No event received.") except WebSocketDisconnect: print("Connection closed") """ try: event = self._events.get(block=True, timeout=timeout) except queue.Empty as e: raise TimeoutError from e except QueueShutDown as e: # pragma: no cover - Python 3.13+ only raise WebSocketDisconnect() from e if isinstance(event, HTTPXWSException): raise event if isinstance(event, wsproto.events.CloseConnection): raise WebSocketDisconnect(event.code, event.reason) return event def receive_text(self, timeout: float | None = None) -> str: """ Receive text from the server. Args: timeout: Number of seconds to wait for an event. If `None`, will block until an event is available. Returns: Text data. Raises: TimeoutError: No event was received before the timeout delay. WebSocketDisconnect: The server closed the websocket. WebSocketNetworkError: A network error occured. WebSocketInvalidTypeReceived: The received event was not a text message. Examples: Wait for text until available. try: text = ws.receive_text() except WebSocketDisconnect: print("Connection closed") Wait for text for 2 seconds. try: event = ws.receive_text(timeout=2.) except TimeoutError: print("No text received.") except WebSocketDisconnect: print("Connection closed") """ event = self.receive(timeout) if isinstance(event, wsproto.events.TextMessage): return event.data raise WebSocketInvalidTypeReceived(event) def receive_bytes(self, timeout: float | None = None) -> bytes: """ Receive bytes from the server. Args: timeout: Number of seconds to wait for an event. If `None`, will block until an event is available. Returns: Bytes data. Raises: TimeoutError: No event was received before the timeout delay. WebSocketDisconnect: The server closed the websocket. WebSocketNetworkError: A network error occured. WebSocketInvalidTypeReceived: The received event was not a bytes message. Examples: Wait for bytes until available. try: data = ws.receive_bytes() except WebSocketDisconnect: print("Connection closed") Wait for bytes for 2 seconds. try: data = ws.receive_bytes(timeout=2.) except TimeoutError: print("No data received.") except WebSocketDisconnect: print("Connection closed") """ event = self.receive(timeout) if isinstance(event, wsproto.events.BytesMessage): return bytes(event.data) raise WebSocketInvalidTypeReceived(event) def receive_json(self, timeout: float | None = None, mode: JSONMode = "text") -> typing.Any: """ Receive JSON data from the server. The received data should be parseable by [json.loads][json.loads]. Args: timeout: Number of seconds to wait for an event. If `None`, will block until an event is available. mode: Receive mode. Should either be `'text'` or `'bytes'`. Returns: Parsed JSON data. Raises: TimeoutError: No event was received before the timeout delay. WebSocketDisconnect: The server closed the websocket. WebSocketNetworkError: A network error occured. WebSocketInvalidTypeReceived: The received event didn't correspond to the specified mode. Examples: Wait for data until available. try: data = ws.receive_json() except WebSocketDisconnect: print("Connection closed") Wait for data for 2 seconds. try: data = ws.receive_json(timeout=2.) except TimeoutError: print("No data received.") except WebSocketDisconnect: print("Connection closed") """ assert mode in ["text", "binary"] data: str | bytes if mode == "text": data = self.receive_text(timeout) elif mode == "binary": data = self.receive_bytes(timeout) return json.loads(data) def close(self, code: int = 1000, reason: str | None = None) -> None: """ Close the WebSocket session. Internally, it'll send the [CloseConnection][wsproto.events.CloseConnection] event. *This method is automatically called when exiting the context manager.* Args: code: The integer close code to indicate why the connection has closed. reason: Additional reasoning for why the connection has closed. Examples: Close the WebSocket session. ws.close() """ import httpcore2 self._should_close.set() if self._executor is not None: self._executor.shutdown(False) if self.connection.state not in { wsproto.connection.ConnectionState.LOCAL_CLOSING, wsproto.connection.ConnectionState.CLOSED, }: event = wsproto.events.CloseConnection(code, reason) data = self.connection.send(event) try: with self._write_lock: self.stream.write(data) except httpcore2.WriteError: pass self.stream.close() def _background_receive(self, max_bytes: int) -> None: """ Background thread listening for data from the server. Internally, it'll: * Answer to Ping events. * Acknowledge Pong events. * Put other events in the [_events][_events] queue that'll eventually be consumed by the user. Args: max_bytes: The maximum chunk size to read at each iteration. """ import httpcore2 partial_message_buffer: str | bytes | None = None partial_message_size = 0 try: while not self._should_close.is_set(): data = self._wait_until_closed(self._read_stream, max_bytes) self.connection.receive_data(data) for event in self.connection.events(): if isinstance(event, wsproto.events.Ping): data = self.connection.send(event.response()) with self._write_lock: self.stream.write(data) continue if isinstance(event, wsproto.events.Pong): self._ping_manager.ack(event.payload) continue if isinstance(event, wsproto.events.CloseConnection): self._should_close.set() if isinstance(event, wsproto.events.Message): partial_message_size += len(event.data.encode() if isinstance(event.data, str) else event.data) if partial_message_size > max_bytes: self.close(CloseReason.MESSAGE_TOO_BIG, "Message too big") self._events.put(WebSocketDisconnect(CloseReason.MESSAGE_TOO_BIG, "Message too big")) break # Unfinished message: bufferize if not event.message_finished: if partial_message_buffer is None: partial_message_buffer = event.data else: partial_message_buffer += event.data # Finished message but no buffer: just emit the event elif partial_message_buffer is None: partial_message_size = 0 self._events.put(event) # Finished message with buffer: emit the full event else: event_type = type(event) full_message_event = event_type(partial_message_buffer + event.data) partial_message_buffer = None partial_message_size = 0 self._events.put(full_message_event) continue self._events.put(event) except (httpcore2.ReadError, httpcore2.WriteError, EndOfStream): self.close(CloseReason.INTERNAL_ERROR, "Stream error") with contextlib.suppress(QueueShutDown): self._events.put(WebSocketNetworkError()) except (ShouldClose, QueueShutDown): pass def _background_keepalive_ping(self, interval_seconds: float, timeout_seconds: float | None = None) -> None: try: while not self._should_close.is_set(): should_close = self._wait_until_closed(self._should_close.wait, interval_seconds) if should_close: # pragma: no cover raise ShouldClose() try: pong_callback = self.ping() except wsproto.utilities.LocalProtocolError: return if timeout_seconds is not None: acknowledged = self._wait_until_closed(pong_callback.wait, timeout_seconds) if not acknowledged: self.close(CloseReason.INTERNAL_ERROR, "Keepalive ping timeout") self._events.put(WebSocketNetworkError()) except (ShouldClose, QueueShutDown): pass def _wait_until_closed( self, callable: typing.Callable[..., TaskResult], *args: typing.Any, **kwargs: typing.Any ) -> TaskResult: try: executor, should_close_task = self._get_executor_should_close_task() todo_task = executor.submit(callable, *args, **kwargs) except RuntimeError as e: raise ShouldClose() from e else: done, _ = concurrent.futures.wait( (todo_task, should_close_task), # type: ignore[misc] return_when=concurrent.futures.FIRST_COMPLETED, ) if should_close_task in done: raise ShouldClose() assert todo_task in done result = todo_task.result() return result def _read_stream(self, max_bytes: int) -> bytes: data = self.stream.read(max_bytes) if data == b"": raise EndOfStream() return data class AsyncWebSocketSession(anyio.AsyncContextManagerMixin): """ Async context manager representing an opened WebSocket session. Internally, this session uses an anyio task group to manage background tasks. As a result, exceptions that are not caught inside the context manager and propagate out of the `async with` block will be wrapped in an [ExceptionGroup][ExceptionGroup]. To handle them, use the `except*` syntax: async with AsyncWebSocketSession(stream) as ws: try: data = await ws.receive_text() except WebSocketDisconnect: # Caught inside the context manager: plain exception. print("Connection closed") # If not caught inside: try: async with AsyncWebSocketSession(stream) as ws: data = await ws.receive_text() except* WebSocketDisconnect: # Propagated out of the context manager: wrapped in ExceptionGroup. print("Connection closed") Attributes: subprotocol (typing.Optional[str]): Optional protocol that has been accepted by the server. response (Response | None): The webSocket handshake response. """ subprotocol: str | None response: Response | None _send_event: MemoryObjectSendStream[wsproto.events.Event | HTTPXWSException] _receive_event: MemoryObjectReceiveStream[wsproto.events.Event | HTTPXWSException] def __init__( self, stream: AsyncNetworkStream, *, max_message_size_bytes: int = DEFAULT_MAX_MESSAGE_SIZE_BYTES, queue_size: int = DEFAULT_QUEUE_SIZE, keepalive_ping_interval_seconds: float | None = DEFAULT_KEEPALIVE_PING_INTERVAL_SECONDS, keepalive_ping_timeout_seconds: float | None = DEFAULT_KEEPALIVE_PING_TIMEOUT_SECONDS, response: Response | None = None, ) -> None: self.stream = stream self.connection = wsproto.connection.Connection(wsproto.ConnectionType.CLIENT) self.response = response if self.response is not None: self.subprotocol = self.response.headers.get("sec-websocket-protocol") else: self.subprotocol = None self._ping_manager = AsyncPingManager() self._should_close = anyio.Event() self._write_lock = anyio.Lock() self._max_message_size_bytes = max_message_size_bytes self._queue_size = queue_size # Always disable keepalive ping when emulating ASGI if isinstance(stream, ASGIWebSocketAsyncNetworkStream): self._keepalive_ping_interval_seconds = None self._keepalive_ping_timeout_seconds = None else: self._keepalive_ping_interval_seconds = keepalive_ping_interval_seconds self._keepalive_ping_timeout_seconds = keepalive_ping_timeout_seconds @contextlib.asynccontextmanager async def __asynccontextmanager__(self) -> typing.AsyncGenerator[AsyncWebSocketSession, None]: self._send_event, self._receive_event = anyio.create_memory_object_stream[ wsproto.events.Event | HTTPXWSException ]() self._background_task_group = anyio.create_task_group() async with self._send_event, self._receive_event, self._background_task_group: self._background_task_group.start_soon(self._background_receive, self._max_message_size_bytes) if self._keepalive_ping_interval_seconds is not None: self._background_task_group.start_soon( self._background_keepalive_ping, self._keepalive_ping_interval_seconds, self._keepalive_ping_timeout_seconds, ) try: yield self finally: self._background_task_group.cancel_scope.cancel() with anyio.CancelScope(shield=True): await self.close() async def ping(self, payload: bytes = b"") -> anyio.Event: """ Send a Ping message. Args: payload: Payload to attach to the Ping event. Internally, it's used to track this specific event. If left empty, a random one will be generated. Returns: An event that can be used to wait for the corresponding Pong response. Examples: Send a Ping and wait for the Pong pong_callback = await ws.ping() # Will block until the corresponding Pong is received. await pong_callback.wait() """ ping_id, callback = self._ping_manager.create(payload) event = wsproto.events.Ping(ping_id) await self.send(event) return callback async def send(self, event: wsproto.events.Event) -> None: """ Send an Event message. Mainly useful to send events that are not supported by the library. Most of the time, [ping()][httpx_ws.AsyncWebSocketSession.ping], [send_text()][httpx_ws.AsyncWebSocketSession.send_text], [send_bytes()][httpx_ws.AsyncWebSocketSession.send_bytes] and [send_json()][httpx_ws.AsyncWebSocketSession.send_json] are preferred. Args: event: The event to send. Raises: WebSocketNetworkError: A network error occured. Note: Exceptions not caught inside the context manager will be wrapped in an [ExceptionGroup][ExceptionGroup]. Use `except*` to catch them outside the `async with` block. Examples: Send an event. event = await wsproto.events.Message(b"Hello!") ws.send(event) """ import httpcore2 try: data = self.connection.send(event) async with self._write_lock: await self.stream.write(data) except httpcore2.WriteError as e: await self.close(CloseReason.INTERNAL_ERROR, "Stream write error") raise WebSocketNetworkError() from e async def send_text(self, data: str) -> None: """ Send a text message. Args: data: The text to send. Raises: WebSocketNetworkError: A network error occured. Note: Exceptions not caught inside the context manager will be wrapped in an [ExceptionGroup][ExceptionGroup]. Use `except*` to catch them outside the `async with` block. Examples: Send a text message. await ws.send_text("Hello!") """ event = wsproto.events.TextMessage(data=data) await self.send(event) async def send_bytes(self, data: bytes) -> None: """ Send a bytes message. Args: data: The data to send. Raises: WebSocketNetworkError: A network error occured. Note: Exceptions not caught inside the context manager will be wrapped in an [ExceptionGroup][ExceptionGroup]. Use `except*` to catch them outside the `async with` block. Examples: Send a bytes message. await ws.send_bytes(b"Hello!") """ event = wsproto.events.BytesMessage(data=data) await self.send(event) async def send_json(self, data: typing.Any, mode: JSONMode = "text") -> None: """ Send JSON data. Args: data: The data to send. Must be serializable by [json.dumps][json.dumps]. mode: The sending mode. Should either be `'text'` or `'bytes'`. Raises: WebSocketNetworkError: A network error occured. Note: Exceptions not caught inside the context manager will be wrapped in an [ExceptionGroup][ExceptionGroup]. Use `except*` to catch them outside the `async with` block. Examples: Send JSON data. data = {"message": "Hello!"} await ws.send_json(data) """ assert mode in ["text", "binary"] serialized_data = json.dumps(data) if mode == "text": await self.send_text(serialized_data) else: await self.send_bytes(serialized_data.encode("utf-8")) async def receive(self, timeout: float | None = None) -> wsproto.events.Event: """ Receive an event from the server. Mainly useful to receive raw [wsproto.events.Event][wsproto.events.Event]. Most of the time, [receive_text()][httpx_ws.AsyncWebSocketSession.receive_text], [receive_bytes()][httpx_ws.AsyncWebSocketSession.receive_bytes], and [receive_json()][httpx_ws.AsyncWebSocketSession.receive_json] are preferred. Args: timeout: Number of seconds to wait for an event. If `None`, will block until an event is available. Returns: A raw [wsproto.events.Event][wsproto.events.Event]. Raises: TimeoutError: No event was received before the timeout delay. WebSocketDisconnect: The server closed the websocket. WebSocketNetworkError: A network error occured. Note: Exceptions not caught inside the context manager will be wrapped in an [ExceptionGroup][ExceptionGroup]. Use `except*` to catch them outside the `async with` block. Examples: Wait for an event until one is available. try: event = await ws.receive() except WebSocketDisconnect: print("Connection closed") Wait for an event for 2 seconds. try: event = await ws.receive(timeout=2.) except TimeoutError: print("No event received.") except WebSocketDisconnect: print("Connection closed") """ with anyio.fail_after(timeout): event = await self._receive_event.receive() if isinstance(event, HTTPXWSException): raise event if isinstance(event, wsproto.events.CloseConnection): raise WebSocketDisconnect(event.code, event.reason) return event async def receive_text(self, timeout: float | None = None) -> str: """ Receive text from the server. Args: timeout: Number of seconds to wait for an event. If `None`, will block until an event is available. Returns: Text data. Raises: TimeoutError: No event was received before the timeout delay. WebSocketDisconnect: The server closed the websocket. WebSocketNetworkError: A network error occured. WebSocketInvalidTypeReceived: The received event was not a text message. Note: Exceptions not caught inside the context manager will be wrapped in an [ExceptionGroup][ExceptionGroup]. Use `except*` to catch them outside the `async with` block. Examples: Wait for text until available. try: text = await ws.receive_text() except WebSocketDisconnect: print("Connection closed") Wait for text for 2 seconds. try: event = await ws.receive_text(timeout=2.) except TimeoutError: print("No text received.") except WebSocketDisconnect: print("Connection closed") """ event = await self.receive(timeout) if isinstance(event, wsproto.events.TextMessage): return event.data raise WebSocketInvalidTypeReceived(event) async def receive_bytes(self, timeout: float | None = None) -> bytes: """ Receive bytes from the server. Args: timeout: Number of seconds to wait for an event. If `None`, will block until an event is available. Returns: Bytes data. Raises: TimeoutError: No event was received before the timeout delay. WebSocketDisconnect: The server closed the websocket. WebSocketNetworkError: A network error occured. WebSocketInvalidTypeReceived: The received event was not a bytes message. Note: Exceptions not caught inside the context manager will be wrapped in an [ExceptionGroup][ExceptionGroup]. Use `except*` to catch them outside the `async with` block. Examples: Wait for bytes until available. try: data = await ws.receive_bytes() except WebSocketDisconnect: print("Connection closed") Wait for bytes for 2 seconds. try: data = await ws.receive_bytes(timeout=2.) except TimeoutError: print("No data received.") except WebSocketDisconnect: print("Connection closed") """ event = await self.receive(timeout) if isinstance(event, wsproto.events.BytesMessage): return bytes(event.data) raise WebSocketInvalidTypeReceived(event) async def receive_json(self, timeout: float | None = None, mode: JSONMode = "text") -> typing.Any: """ Receive JSON data from the server. The received data should be parseable by [json.loads][json.loads]. Args: timeout: Number of seconds to wait for an event. If `None`, will block until an event is available. mode: Receive mode. Should either be `'text'` or `'bytes'`. Returns: Parsed JSON data. Raises: TimeoutError: No event was received before the timeout delay. WebSocketDisconnect: The server closed the websocket. WebSocketNetworkError: A network error occured. WebSocketInvalidTypeReceived: The received event didn't correspond to the specified mode. Note: Exceptions not caught inside the context manager will be wrapped in an [ExceptionGroup][ExceptionGroup]. Use `except*` to catch them outside the `async with` block. Examples: Wait for data until available. try: data = await ws.receive_json() except WebSocketDisconnect: print("Connection closed") Wait for data for 2 seconds. try: data = await ws.receive_json(timeout=2.) except TimeoutError: print("No data received.") except WebSocketDisconnect: print("Connection closed") """ assert mode in ["text", "binary"] data: str | bytes if mode == "text": data = await self.receive_text(timeout) elif mode == "binary": data = await self.receive_bytes(timeout) return json.loads(data) async def close(self, code: int = 1000, reason: str | None = None) -> None: """ Close the WebSocket session. Internally, it'll send the [CloseConnection][wsproto.events.CloseConnection] event. *This method is automatically called when exiting the context manager.* Args: code: The integer close code to indicate why the connection has closed. reason: Additional reasoning for why the connection has closed. Examples: Close the WebSocket session. await ws.close() """ import httpcore2 self._should_close.set() if self.connection.state not in { wsproto.connection.ConnectionState.LOCAL_CLOSING, wsproto.connection.ConnectionState.CLOSED, }: event = wsproto.events.CloseConnection(code, reason) data = self.connection.send(event) try: async with self._write_lock: await self.stream.write(data) except httpcore2.WriteError: pass await self.stream.aclose() async def _background_receive(self, max_bytes: int) -> None: """ Background task listening for data from the server. Internally, it'll: * Answer to Ping events. * Acknowledge Pong events. * Put other events in the [_events][_events] queue that'll eventually be consumed by the user. Args: max_bytes: The maximum chunk size to read at each iteration. """ import httpcore2 partial_message_buffer: str | bytes | None = None partial_message_size = 0 try: while not self._should_close.is_set(): data = await self._read_stream(max_bytes) self.connection.receive_data(data) for event in self.connection.events(): if isinstance(event, wsproto.events.Ping): data = self.connection.send(event.response()) async with self._write_lock: await self.stream.write(data) continue if isinstance(event, wsproto.events.Pong): self._ping_manager.ack(event.payload) continue if isinstance(event, wsproto.events.CloseConnection): self._should_close.set() if isinstance(event, wsproto.events.Message): partial_message_size += len(event.data.encode() if isinstance(event.data, str) else event.data) if partial_message_size > max_bytes: await self.close(CloseReason.MESSAGE_TOO_BIG, "Message too big") await self._send_event.send( WebSocketDisconnect(CloseReason.MESSAGE_TOO_BIG, "Message too big") ) break # Unfinished message: bufferize if not event.message_finished: if partial_message_buffer is None: partial_message_buffer = event.data else: partial_message_buffer += event.data # Finished message but no buffer: just emit the event elif partial_message_buffer is None: partial_message_size = 0 await self._send_event.send(event) # Finished message with buffer: emit the full event else: event_type = type(event) full_message_event = event_type(partial_message_buffer + event.data) partial_message_buffer = None partial_message_size = 0 await self._send_event.send(full_message_event) continue await self._send_event.send(event) except (httpcore2.ReadError, httpcore2.WriteError, EndOfStream): await self.close(CloseReason.INTERNAL_ERROR, "Stream error") await self._send_event.send(WebSocketNetworkError()) async def _background_keepalive_ping(self, interval_seconds: float, timeout_seconds: float | None = None) -> None: while not self._should_close.is_set(): await anyio.sleep(interval_seconds) try: pong_callback = await self.ping() # Connection is closing, exit the task except wsproto.utilities.LocalProtocolError: return if timeout_seconds is not None: try: with anyio.fail_after(timeout_seconds): await pong_callback.wait() except TimeoutError: await self.close(CloseReason.INTERNAL_ERROR, "Keepalive ping timeout") await self._send_event.send(WebSocketNetworkError()) async def _read_stream(self, max_bytes: int) -> bytes: data = await self.stream.read(max_bytes) if data == b"": raise EndOfStream() return data def _get_headers( subprotocols: list[str] | None, ) -> dict[str, typing.Any]: headers = { "connection": "upgrade", "upgrade": "websocket", "sec-websocket-key": base64.b64encode(secrets.token_bytes(16)).decode("utf-8"), "sec-websocket-version": "13", } if subprotocols is not None: headers["sec-websocket-protocol"] = ", ".join(subprotocols) return headers class WebSocketClient(typing.Generic[SyncSession]): """ A sync WebSocket client. This class provides an API for connecting to WebSocket. Attributes: client: HTTPX client to use. max_message_size_bytes: Maximum incoming message size in bytes. Larger messages, including fragmented messages whose cumulative size exceeds the limit, close the connection with `MESSAGE_TOO_BIG`. Defaults to 65 KiB. queue_size: Size of the queue where the received messages will be held until they are consumed. If the queue is full, the client will stop receive messages from the server until the queue has room available. Defaults to 512. keepalive_ping_interval_seconds: Interval at which the client will automatically send a Ping event to keep the connection alive. Set it to `None` to disable this mechanism. Defaults to 20 seconds. keepalive_ping_timeout_seconds: Maximum delay the client will wait for an answer to its Ping event. If the delay is exceeded, [WebSocketNetworkError][httpx_ws.WebSocketNetworkError] will be raised and the connection closed. Defaults to 20 seconds. session_class: The session class to use. Defaults to [WebSocketSession][httpx_ws.WebSocketSession]. """ def __init__( self, client: Client, *, max_message_size_bytes: int = DEFAULT_MAX_MESSAGE_SIZE_BYTES, queue_size: int = DEFAULT_QUEUE_SIZE, keepalive_ping_interval_seconds: float | None = DEFAULT_KEEPALIVE_PING_INTERVAL_SECONDS, keepalive_ping_timeout_seconds: float | None = DEFAULT_KEEPALIVE_PING_TIMEOUT_SECONDS, session_class: type[SyncSession] = WebSocketSession, # type: ignore[assignment] ) -> None: self.client = client self.max_message_size_bytes = max_message_size_bytes self.queue_size = queue_size self.keepalive_ping_interval_seconds = keepalive_ping_interval_seconds self.keepalive_ping_timeout_seconds = keepalive_ping_timeout_seconds self.session_class = session_class @contextlib.contextmanager def connect( self, url: str, *, subprotocols: list[str] | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> typing.Generator[SyncSession, None, None]: """ Start a sync WebSocket session. It returns a context manager that'll automatically call [close()][httpx_ws.WebSocketSession.close] when exiting. Args: url: The WebSocket URL. subprotocols: Optional list of subprotocols to negotiate with the server. params: Query parameters to include in the handshake request. headers: Headers to include in the handshake request. cookies: Cookies to include in the handshake request. auth: Authentication to use for the handshake request. follow_redirects: Whether to follow redirects on the handshake request. timeout: Timeout configuration for the handshake request. extensions: Request extensions for the handshake request. Returns: A [context manager][contextlib.AbstractContextManager] for [WebSocketSession][httpx_ws.WebSocketSession]. Examples: Initialize the client and connect to a WebSocket. with httpx2.Client() as client: ws_client = WebSocketClient(client) with ws_client.connect("http://localhost:8000/ws") as ws: message = ws.receive_text() print(message) ws.send_text("Hello!") """ with self.client.stream( "GET", url, params=params, headers=Headers(headers) | _get_headers(subprotocols), cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) as response: if response.status_code != 101: raise WebSocketUpgradeError(response) session = self.session_class( response.extensions["network_stream"], max_message_size_bytes=self.max_message_size_bytes, queue_size=self.queue_size, keepalive_ping_interval_seconds=self.keepalive_ping_interval_seconds, keepalive_ping_timeout_seconds=self.keepalive_ping_timeout_seconds, response=response, ) with session: yield session @contextlib.contextmanager def connect_ws( url: str, client: Client | None = None, *, max_message_size_bytes: int = DEFAULT_MAX_MESSAGE_SIZE_BYTES, queue_size: int = DEFAULT_QUEUE_SIZE, keepalive_ping_interval_seconds: float | None = DEFAULT_KEEPALIVE_PING_INTERVAL_SECONDS, keepalive_ping_timeout_seconds: float | None = DEFAULT_KEEPALIVE_PING_TIMEOUT_SECONDS, subprotocols: list[str] | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> typing.Generator[WebSocketSession, None, None]: """ Start a sync WebSocket session. It returns a context manager that'll automatically call [close()][httpx_ws.WebSocketSession.close] when exiting. Args: url: The WebSocket URL. client: HTTPX client to use. If not provided, a default one will be initialized. max_message_size_bytes: Maximum incoming message size in bytes. Larger messages, including fragmented messages whose cumulative size exceeds the limit, close the connection with `MESSAGE_TOO_BIG`. Defaults to 65 KiB. queue_size: Size of the queue where the received messages will be held until they are consumed. If the queue is full, the client will stop receive messages from the server until the queue has room available. Defaults to 512. keepalive_ping_interval_seconds: Interval at which the client will automatically send a Ping event to keep the connection alive. Set it to `None` to disable this mechanism. Defaults to 20 seconds. keepalive_ping_timeout_seconds: Maximum delay the client will wait for an answer to its Ping event. If the delay is exceeded, [WebSocketNetworkError][httpx_ws.WebSocketNetworkError] will be raised and the connection closed. Defaults to 20 seconds. subprotocols: Optional list of subprotocols to negotiate with the server. params: Query parameters to include in the handshake request. headers: Headers to include in the handshake request. cookies: Cookies to include in the handshake request. auth: Authentication to use for the handshake request. follow_redirects: Whether to follow redirects on the handshake request. timeout: Timeout configuration for the handshake request. extensions: Request extensions for the handshake request. Returns: A [context manager][contextlib.AbstractContextManager] for [WebSocketSession][httpx_ws.WebSocketSession]. Examples: Without explicit HTTPX client. with connect_ws("http://localhost:8000/ws") as ws: message = ws.receive_text() print(message) ws.send_text("Hello!") With explicit HTTPX client. with httpx2.Client() as client: with connect_ws("http://localhost:8000/ws", client) as ws: message = ws.receive_text() print(message) ws.send_text("Hello!") """ if client is None: from .._client import Client owned_client: contextlib.AbstractContextManager[Client] = Client() else: owned_client = contextlib.nullcontext(client) with owned_client as client: ws_client = WebSocketClient( client=client, max_message_size_bytes=max_message_size_bytes, queue_size=queue_size, keepalive_ping_interval_seconds=keepalive_ping_interval_seconds, keepalive_ping_timeout_seconds=keepalive_ping_timeout_seconds, ) with ws_client.connect( url, subprotocols=subprotocols, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) as websocket: yield websocket class AsyncWebSocketClient(typing.Generic[AsyncSession]): """ An async WebSocket client. This class provides an API for connecting to WebSocket. Attributes: client: HTTPX client to use. max_message_size_bytes: Maximum incoming message size in bytes. Larger messages, including fragmented messages whose cumulative size exceeds the limit, close the connection with `MESSAGE_TOO_BIG`. Defaults to 65 KiB. queue_size: Size of the queue where the received messages will be held until they are consumed. If the queue is full, the client will stop receive messages from the server until the queue has room available. Defaults to 512. keepalive_ping_interval_seconds: Interval at which the client will automatically send a Ping event to keep the connection alive. Set it to `None` to disable this mechanism. Defaults to 20 seconds. keepalive_ping_timeout_seconds: Maximum delay the client will wait for an answer to its Ping event. If the delay is exceeded, [WebSocketNetworkError][httpx_ws.WebSocketNetworkError] will be raised in an [ExceptionGroup][ExceptionGroup] and the connection closed. Defaults to 20 seconds. session_class: The session class to use. Defaults to [AsyncWebSocketSession][httpx_ws.AsyncWebSocketSession]. """ def __init__( self, client: AsyncClient, *, max_message_size_bytes: int = DEFAULT_MAX_MESSAGE_SIZE_BYTES, queue_size: int = DEFAULT_QUEUE_SIZE, keepalive_ping_interval_seconds: float | None = DEFAULT_KEEPALIVE_PING_INTERVAL_SECONDS, keepalive_ping_timeout_seconds: float | None = DEFAULT_KEEPALIVE_PING_TIMEOUT_SECONDS, session_class: type[AsyncSession] = AsyncWebSocketSession, # type: ignore[assignment] ) -> None: self.client = client self.max_message_size_bytes = max_message_size_bytes self.queue_size = queue_size self.keepalive_ping_interval_seconds = keepalive_ping_interval_seconds self.keepalive_ping_timeout_seconds = keepalive_ping_timeout_seconds self.session_class = session_class @contextlib.asynccontextmanager async def connect( self, url: str, *, subprotocols: list[str] | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> typing.AsyncGenerator[AsyncSession, None]: """ Start an async WebSocket session. It returns an async context manager that'll automatically call [close()][httpx_ws.AsyncWebSocketSession.close] when exiting. Args: url: The WebSocket URL. subprotocols: Optional list of subprotocols to negotiate with the server. params: Query parameters to include in the handshake request. headers: Headers to include in the handshake request. cookies: Cookies to include in the handshake request. auth: Authentication to use for the handshake request. follow_redirects: Whether to follow redirects on the handshake request. timeout: Timeout configuration for the handshake request. extensions: Request extensions for the handshake request. Returns: An [async context manager][contextlib.AbstractAsyncContextManager] for [AsyncWebSocketSession][httpx_ws.AsyncWebSocketSession]. Examples: Initialize the client and connect to a WebSocket. async with httpx2.AsyncClient() as client: ws_client = AsyncWebSocketClient(client) async with ws_client.connect("http://localhost:8000/ws") as ws: message = await ws.receive_text() print(message) await ws.send_text("Hello!") """ async with self.client.stream( "GET", url, params=params, headers=Headers(headers) | _get_headers(subprotocols), cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) as response: if response.status_code != 101: raise WebSocketUpgradeError(response) session = self.session_class( response.extensions["network_stream"], max_message_size_bytes=self.max_message_size_bytes, queue_size=self.queue_size, keepalive_ping_interval_seconds=self.keepalive_ping_interval_seconds, keepalive_ping_timeout_seconds=self.keepalive_ping_timeout_seconds, response=response, ) async with session: yield session @contextlib.asynccontextmanager async def aconnect_ws( url: str, client: AsyncClient | None = None, *, max_message_size_bytes: int = DEFAULT_MAX_MESSAGE_SIZE_BYTES, queue_size: int = DEFAULT_QUEUE_SIZE, keepalive_ping_interval_seconds: float | None = DEFAULT_KEEPALIVE_PING_INTERVAL_SECONDS, keepalive_ping_timeout_seconds: float | None = DEFAULT_KEEPALIVE_PING_TIMEOUT_SECONDS, subprotocols: list[str] | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> typing.AsyncGenerator[AsyncWebSocketSession, None]: """ Start an async WebSocket session. It returns an async context manager that'll automatically call [close()][httpx_ws.AsyncWebSocketSession.close] when exiting. Args: url: The WebSocket URL. client: HTTPX client to use. If not provided, a default one will be initialized. max_message_size_bytes: Maximum incoming message size in bytes. Larger messages, including fragmented messages whose cumulative size exceeds the limit, close the connection with `MESSAGE_TOO_BIG`. Defaults to 65 KiB. queue_size: Size of the queue where the received messages will be held until they are consumed. If the queue is full, the client will stop receive messages from the server until the queue has room available. Defaults to 512. keepalive_ping_interval_seconds: Interval at which the client will automatically send a Ping event to keep the connection alive. Set it to `None` to disable this mechanism. Defaults to 20 seconds. keepalive_ping_timeout_seconds: Maximum delay the client will wait for an answer to its Ping event. If the delay is exceeded, [WebSocketNetworkError][httpx_ws.WebSocketNetworkError] will be raised in an [ExceptionGroup][ExceptionGroup] and the connection closed. Defaults to 20 seconds. subprotocols: Optional list of subprotocols to negotiate with the server. params: Query parameters to include in the handshake request. headers: Headers to include in the handshake request. cookies: Cookies to include in the handshake request. auth: Authentication to use for the handshake request. follow_redirects: Whether to follow redirects on the handshake request. timeout: Timeout configuration for the handshake request. extensions: Request extensions for the handshake request. Returns: An [async context manager][contextlib.AbstractAsyncContextManager] for [AsyncWebSocketSession][httpx_ws.AsyncWebSocketSession]. Examples: Without explicit HTTPX client. async with aconnect_ws("http://localhost:8000/ws") as ws: message = await ws.receive_text() print(message) await ws.send_text("Hello!") With explicit HTTPX client. async with httpx2.AsyncClient() as client: async with aconnect_ws("http://localhost:8000/ws", client) as ws: message = await ws.receive_text() print(message) await ws.send_text("Hello!") """ if client is None: from .._client import AsyncClient owned_client: contextlib.AbstractAsyncContextManager[AsyncClient] = AsyncClient() else: owned_client = contextlib.nullcontext(client) async with owned_client as client: ws_client = AsyncWebSocketClient( client=client, max_message_size_bytes=max_message_size_bytes, queue_size=queue_size, keepalive_ping_interval_seconds=keepalive_ping_interval_seconds, keepalive_ping_timeout_seconds=keepalive_ping_timeout_seconds, ) async with ws_client.connect( url, subprotocols=subprotocols, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) as websocket: yield websocket pydantic-httpx2-6dd59b9/src/httpx2/httpx2/websockets/_exceptions.py000066400000000000000000000024121526547463400255370ustar00rootroot00000000000000from __future__ import annotations import typing if typing.TYPE_CHECKING: import wsproto from .._models import Response class HTTPXWSException(Exception): """ Base exception class for HTTPX WS. """ class WebSocketUpgradeError(HTTPXWSException): """ Raised when the initial connection didn't correctly upgrade to a WebSocket session. """ def __init__(self, response: Response) -> None: self.response = response class WebSocketDisconnect(HTTPXWSException): """ Raised when the server closed the WebSocket session. Args: code: The integer close code to indicate why the connection has closed. reason: Additional reasoning for why the connection has closed. """ def __init__(self, code: int = 1000, reason: str | None = None) -> None: self.code = code self.reason = reason or "" class WebSocketInvalidTypeReceived(HTTPXWSException): """ Raised when an event is not of the expected type. """ def __init__(self, event: wsproto.events.Event) -> None: self.event = event class WebSocketNetworkError(HTTPXWSException): """ Raised when a network error occured, typically if the underlying stream has closed or timeout. """ pydantic-httpx2-6dd59b9/src/httpx2/httpx2/websockets/_ping.py000066400000000000000000000023521526547463400243160ustar00rootroot00000000000000from __future__ import annotations import secrets import threading import anyio class PingManagerBase: def _generate_id(self) -> bytes: return secrets.token_bytes() class PingManager(PingManagerBase): def __init__(self) -> None: self._pings: dict[bytes, threading.Event] = {} def create(self, ping_id: bytes | None = None) -> tuple[bytes, threading.Event]: ping_id = self._generate_id() if not ping_id else ping_id event = threading.Event() self._pings[ping_id] = event return ping_id, event def ack(self, ping_id: bytes | bytearray) -> None: event = self._pings.pop(bytes(ping_id), None) if event is not None: event.set() class AsyncPingManager(PingManagerBase): def __init__(self) -> None: self._pings: dict[bytes, anyio.Event] = {} def create(self, ping_id: bytes | None = None) -> tuple[bytes, anyio.Event]: ping_id = self._generate_id() if not ping_id else ping_id event = anyio.Event() self._pings[ping_id] = event return ping_id, event def ack(self, ping_id: bytes | bytearray) -> None: event = self._pings.pop(bytes(ping_id), None) if event is not None: event.set() pydantic-httpx2-6dd59b9/src/httpx2/httpx2/websockets/_transport.py000066400000000000000000000254251526547463400254230ustar00rootroot00000000000000from __future__ import annotations import contextlib import math import typing from types import TracebackType import anyio import wsproto from anyio.streams.stapled import StapledObjectStream from wsproto.frame_protocol import CloseReason from .._models import Request, Response from .._transports.asgi import ASGITransport, _ASGIApp from .._types import AsyncByteStream from ._exceptions import WebSocketDisconnect, WebSocketUpgradeError Scope = dict[str, typing.Any] Message = dict[str, typing.Any] Receive = typing.Callable[[], typing.Awaitable[Message]] Send = typing.Callable[[Scope], typing.Coroutine[None, None, None]] ASGIApp = typing.Callable[[Scope, Receive, Send], typing.Coroutine[None, None, None]] class ASGIWebSocketTransportError(Exception): pass class UnhandledASGIMessageType(ASGIWebSocketTransportError): def __init__(self, message: Message) -> None: self.message = message class UnhandledWebSocketEvent(ASGIWebSocketTransportError): def __init__(self, event: wsproto.events.Event) -> None: self.event = event class ASGIWebSocketAsyncNetworkStream: def __init__( self, app: ASGIApp, scope: Scope, task_group: anyio.abc.TaskGroup, initial_receive_timeout: float = 1.0, ) -> None: self.app = app self.scope = scope self._receive_queue = StapledObjectStream(*anyio.create_memory_object_stream[Message](max_buffer_size=math.inf)) self._send_queue = StapledObjectStream(*anyio.create_memory_object_stream[Message](max_buffer_size=math.inf)) self._task_group = task_group self._initial_receive_timeout = initial_receive_timeout self.connection = wsproto.WSConnection(wsproto.ConnectionType.SERVER) self.connection.initiate_upgrade_connection(scope["headers"], scope["path"]) self._aentered = False async def __aenter__( self, ) -> tuple[ASGIWebSocketAsyncNetworkStream, bytes]: if self._aentered: raise RuntimeError("Cannot use ASGIWebSocketAsyncNetworkStream in a context manager twice") self._aentered = True self._task_group.start_soon(self._run) async with contextlib.AsyncExitStack() as stack: stack.push_async_callback(self.aclose) await self.send({"type": "websocket.connect"}) try: message = await self.receive(self._initial_receive_timeout) except TimeoutError as e: raise RuntimeError( "WebSocket didn't accept the connection in time. Did you forget to call accept()?" ) from e if message["type"] == "websocket.close": await stack.aclose() raise WebSocketDisconnect(message["code"], message.get("reason")) # Websocket Denial Response extension # Ref: https://asgi.readthedocs.io/en/latest/extensions.html#websocket-denial-response if message["type"] == "websocket.http.response.start": status_code: int = message["status"] headers: list[tuple[bytes, bytes]] = message["headers"] body: list[bytes] = [] while True: message = await self.receive() assert message["type"] == "websocket.http.response.body" body.append(message["body"]) if not message.get("more_body", False): break await stack.aclose() raise WebSocketUpgradeError(Response(status_code, headers=headers, content=b"".join(body))) assert message["type"] == "websocket.accept" retval = self, self._build_accept_response(message) self._exit_stack = stack.pop_all() return retval async def __aexit__( self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None, ) -> bool | None: return await self._exit_stack.__aexit__(exc_type, exc_val, exc_tb) async def read(self, max_bytes: int, timeout: float | None = None) -> bytes: import httpcore2 try: message: Message = await self.receive(timeout=timeout) except anyio.EndOfStream: return b"" except anyio.ClosedResourceError as exc: raise httpcore2.ReadError() from exc type = message["type"] if type not in {"websocket.send", "websocket.close"}: raise UnhandledASGIMessageType(message) event: wsproto.events.Event if type == "websocket.send": data_str: str | None = message.get("text") if data_str is not None: event = wsproto.events.TextMessage(data_str) data_bytes: bytes | None = message.get("bytes") if data_bytes is not None: event = wsproto.events.BytesMessage(data_bytes) elif type == "websocket.close": event = wsproto.events.CloseConnection(message["code"], message["reason"]) return self.connection.send(event) async def write(self, buffer: bytes, timeout: float | None = None) -> None: self.connection.receive_data(buffer) for event in self.connection.events(): if isinstance(event, wsproto.events.Request): pass elif isinstance(event, wsproto.events.CloseConnection): await self.send( { "type": "websocket.disconnect", "code": event.code, "reason": event.reason, } ) elif isinstance(event, wsproto.events.TextMessage): await self.send({"type": "websocket.receive", "text": event.data}) elif isinstance(event, wsproto.events.BytesMessage): await self.send({"type": "websocket.receive", "bytes": event.data}) else: raise UnhandledWebSocketEvent(event) async def aclose(self) -> None: with contextlib.suppress(anyio.ClosedResourceError): await self.send({"type": "websocket.disconnect"}) await self._receive_queue.aclose() await self._send_queue.aclose() async def send(self, message: Message) -> None: await self._receive_queue.send(message) async def receive(self, timeout: float | None = None) -> Message: if timeout is None: timeout = math.inf with anyio.fail_after(timeout): return await self._send_queue.receive() async def _run(self) -> None: """ The sub-thread in which the websocket session runs. """ scope = self.scope receive = self._receive_queue.receive send = self._send_queue.send try: await self.app(scope, receive, send) except Exception as e: message = { "type": "websocket.close", "code": CloseReason.INTERNAL_ERROR, "reason": str(e), } with contextlib.suppress(anyio.ClosedResourceError): await send(message) def _build_accept_response(self, message: Message) -> bytes: subprotocol = message.get("subprotocol", None) headers = message.get("headers", []) return self.connection.send( wsproto.events.AcceptConnection( subprotocol=subprotocol, extra_headers=headers, ) ) class ASGIWebSocketTransport(ASGITransport): def __init__( self, app: _ASGIApp, raise_app_exceptions: bool = True, root_path: str = "", client: tuple[str, int] = ("127.0.0.1", 123), initial_receive_timeout: float = 1.0, ) -> None: super().__init__(app, raise_app_exceptions, root_path, client) self._exit_stack: contextlib.AsyncExitStack | None = None self._initial_receive_timeout = initial_receive_timeout async def __aenter__(self) -> ASGIWebSocketTransport: async with contextlib.AsyncExitStack() as stack: self._task_group = await stack.enter_async_context(anyio.create_task_group()) self._exit_stack = stack.pop_all() return self async def __aexit__( self, exc_type: type[BaseException] | None = None, exc_val: BaseException | None = None, exc_tb: TracebackType | None = None, ) -> None: await super().__aexit__(exc_type, exc_val, exc_tb) assert self._exit_stack is not None await self._exit_stack.__aexit__(exc_type, exc_val, exc_tb) async def handle_async_request(self, request: Request) -> Response: scheme = request.url.scheme headers = request.headers if scheme in {"ws", "wss"} or headers.get("upgrade") == "websocket": subprotocols: list[str] = [] if (subprotocols_header := headers.get("sec-websocket-protocol")) is not None: subprotocols = subprotocols_header.split(",") scope = { "type": "websocket", "path": request.url.path, "raw_path": request.url.raw_path, "root_path": self.root_path, "scheme": scheme, "query_string": request.url.query, "headers": [(k.lower(), v) for (k, v) in request.headers.raw], "client": self.client, "server": (request.url.host, request.url.port), "subprotocols": subprotocols, } return await self._handle_ws_request(request, scope) return await super().handle_async_request(request) async def _create_asgi_websocket_async_network_stream( self, *, task_status: anyio.abc.TaskStatus[tuple[ASGIWebSocketAsyncNetworkStream, bytes]], ) -> None: stream = ASGIWebSocketAsyncNetworkStream( self.app, # type: ignore[arg-type] self.scope, self._task_group, self._initial_receive_timeout, ) assert self._exit_stack is not None result = await self._exit_stack.enter_async_context(stream) task_status.started(result) async def _handle_ws_request( self, request: Request, scope: Scope, ) -> Response: assert isinstance(request.stream, AsyncByteStream) self.scope = scope stream, accept_response = await self._task_group.start(self._create_asgi_websocket_async_network_stream) accept_response_lines = accept_response.decode("utf-8").splitlines() headers = [ typing.cast(tuple[str, str], line.split(": ", 1)) for line in accept_response_lines[1:] if line.strip() != "" ] return Response( status_code=101, headers=headers, extensions={"network_stream": stream}, ) pydantic-httpx2-6dd59b9/src/httpx2/pyproject.toml000066400000000000000000000064471526547463400221730ustar00rootroot00000000000000[build-system] requires = ["hatchling", "hatch-fancy-pypi-readme", "uv-dynamic-versioning>=0.14.1"] build-backend = "hatchling.build" [tool.hatch.version] source = "uv-dynamic-versioning" [tool.uv-dynamic-versioning] vcs = "git" style = "pep440" bump = true fallback-version = "0.0.0" [project] name = "httpx2" description = "The next generation HTTP client." license = "BSD-3-Clause" requires-python = ">=3.11" authors = [ { name = "Tom Christie", email = "tom@tomchristie.com" }, ] maintainers = [ { name = "Pydantic Services Inc.", email = "engineering@pydantic.dev" } ] classifiers = [ "Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Framework :: AnyIO", "Framework :: AsyncIO", "Framework :: Trio", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", "Programming Language :: Python :: 3.15", "Topic :: Internet :: WWW/HTTP", ] dynamic = ["readme", "version", "dependencies"] [tool.hatch.metadata.hooks.uv-dynamic-versioning] dependencies = [ "truststore>=0.10; sys_platform != 'emscripten'", "httpcore2=={{ version }}; sys_platform != 'emscripten'", "anyio>=4.10; sys_platform != 'emscripten'", "httpx2-jsfetch; sys_platform == 'emscripten' and python_version >= '3.12'", "idna>=3.18", "typing_extensions>=4.5.0; python_version < '3.13'", ] [project.optional-dependencies] brotli = [ "brotli>=1.2.0; platform_python_implementation == 'CPython'", "brotlicffi>=1.2.0.2; platform_python_implementation != 'CPython'", ] cli = [ "click>=8.4.2", "pygments==2.*", "rich>=10,<16", ] http2 = [ "h2>=3,<5", ] socks = [ "socksio==1.*", ] ws = [ "wsproto>=1.2", ] # TODO(Marcelo): Remove when Python 3.13 reaches EOL. zstd = [ "backports.zstd>=1.0.0; python_version <= '3.13'", ] [project.scripts] httpx2 = "httpx2._main:main" [project.urls] Changelog = "https://github.com/pydantic/httpx2/blob/main/src/httpx2/CHANGELOG.md" Homepage = "https://github.com/pydantic/httpx2" Source = "https://github.com/pydantic/httpx2" [tool.hatch.build.targets.sdist] include = ["/httpx2", "/CHANGELOG.md"] [tool.hatch.build.targets.sdist.force-include] "../../README.md" = "README.md" "../../LICENSE.md" = "LICENSE.md" [tool.hatch.build.targets.wheel] packages = ["httpx2"] [tool.hatch.metadata.hooks.fancy-pypi-readme] content-type = "text/markdown" [[tool.hatch.metadata.hooks.fancy-pypi-readme.fragments]] path = "../../README.md" [[tool.hatch.metadata.hooks.fancy-pypi-readme.fragments]] text = "\n## Release Information\n\n" [[tool.hatch.metadata.hooks.fancy-pypi-readme.fragments]] path = "CHANGELOG.md" pattern = "\n(## [0-9].+?)(?=\n## |$)" [[tool.hatch.metadata.hooks.fancy-pypi-readme.fragments]] text = "\n---\n\n[Full changelog](https://github.com/pydantic/httpx2/blob/main/src/httpx2/CHANGELOG.md)\n" [[tool.hatch.metadata.hooks.fancy-pypi-readme.substitutions]] pattern = 'src="(docs/img/.*?)"' replacement = 'src="https://raw.githubusercontent.com/pydantic/httpx2/main/\1"' pydantic-httpx2-6dd59b9/tests/000077500000000000000000000000001526547463400163665ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/tests/__init__.py000066400000000000000000000000001526547463400204650ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/tests/httpcore2/000077500000000000000000000000001526547463400203005ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/tests/httpcore2/__init__.py000066400000000000000000000000001526547463400223770ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/tests/httpcore2/_async/000077500000000000000000000000001526547463400215545ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/tests/httpcore2/_async/__init__.py000066400000000000000000000000001526547463400236530ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/tests/httpcore2/_async/test_connection.py000066400000000000000000000301351526547463400253260ustar00rootroot00000000000000import ssl import typing import hpack import hyperframe.frame import pytest from httpcore2 import ( SOCKET_OPTION, AsyncHTTPConnection, AsyncMockBackend, AsyncMockStream, AsyncNetworkStream, ConnectError, ConnectionNotAvailable, Origin, RemoteProtocolError, WriteError, ) @pytest.mark.anyio async def test_http_connection() -> None: origin = Origin(b"https", b"example.com", 443) network_backend = AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) async with AsyncHTTPConnection(origin=origin, network_backend=network_backend, keepalive_expiry=5.0) as conn: assert not conn.is_idle() assert not conn.is_closed() assert not conn.is_available() assert not conn.has_expired() assert not conn.is_connected() assert repr(conn) == "" async with conn.stream("GET", "https://example.com/") as response: assert repr(conn) == "" await response.aread() assert response.status == 200 assert response.content == b"Hello, world!" assert conn.is_idle() assert not conn.is_closed() assert conn.is_available() assert not conn.has_expired() assert conn.is_connected() assert repr(conn) == "" @pytest.mark.anyio async def test_concurrent_requests_not_available_on_http11_connections() -> None: """ Attempting to issue a request against an already active HTTP/1.1 connection will raise a `ConnectionNotAvailable` exception. """ origin = Origin(b"https", b"example.com", 443) network_backend = AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) async with AsyncHTTPConnection(origin=origin, network_backend=network_backend, keepalive_expiry=5.0) as conn: async with conn.stream("GET", "https://example.com/"): with pytest.raises(ConnectionNotAvailable): await conn.request("GET", "https://example.com/") @pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning") @pytest.mark.anyio async def test_write_error_with_response_sent() -> None: """ If a server half-closes the connection while the client is sending the request, it may still send a response. In this case the client should successfully read and return the response. See also the `test_write_error_without_response_sent` test above. """ class ErrorOnRequestTooLargeStream(AsyncMockStream): def __init__(self, buffer: list[bytes], http2: bool = False) -> None: super().__init__(buffer, http2) self.count = 0 async def write(self, buffer: bytes, timeout: float | None = None) -> None: self.count += len(buffer) if self.count > 1_000_000: raise WriteError() class ErrorOnRequestTooLarge(AsyncMockBackend): async def connect_tcp( self, host: str, port: int, timeout: float | None = None, local_address: str | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> AsyncMockStream: return ErrorOnRequestTooLargeStream(list(self._buffer), http2=self._http2) origin = Origin(b"https", b"example.com", 443) network_backend = ErrorOnRequestTooLarge( [ b"HTTP/1.1 413 Payload Too Large\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 37\r\n", b"\r\n", b"Request body exceeded 1,000,000 bytes", ] ) async with AsyncHTTPConnection(origin=origin, network_backend=network_backend, keepalive_expiry=5.0) as conn: content = b"x" * 10_000_000 response = await conn.request("POST", "https://example.com/", content=content) assert response.status == 413 assert response.content == b"Request body exceeded 1,000,000 bytes" @pytest.mark.anyio @pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning") async def test_write_error_without_response_sent() -> None: """ If a server fully closes the connection while the client is sending the request, then client should raise an error. See also the `test_write_error_with_response_sent` test above. """ class ErrorOnRequestTooLargeStream(AsyncMockStream): def __init__(self, buffer: list[bytes], http2: bool = False) -> None: super().__init__(buffer, http2) self.count = 0 async def write(self, buffer: bytes, timeout: float | None = None) -> None: self.count += len(buffer) if self.count > 1_000_000: raise WriteError() class ErrorOnRequestTooLarge(AsyncMockBackend): async def connect_tcp( self, host: str, port: int, timeout: float | None = None, local_address: str | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> AsyncMockStream: return ErrorOnRequestTooLargeStream(list(self._buffer), http2=self._http2) origin = Origin(b"https", b"example.com", 443) network_backend = ErrorOnRequestTooLarge([]) async with AsyncHTTPConnection(origin=origin, network_backend=network_backend, keepalive_expiry=5.0) as conn: content = b"x" * 10_000_000 with pytest.raises(RemoteProtocolError) as exc_info: await conn.request("POST", "https://example.com/", content=content) assert str(exc_info.value) == "Server disconnected without sending a response." @pytest.mark.anyio @pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning") async def test_http2_connection() -> None: origin = Origin(b"https", b"example.com", 443) network_backend = AsyncMockBackend( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), ], http2=True, ) async with AsyncHTTPConnection(origin=origin, network_backend=network_backend, http2=True) as conn: response = await conn.request("GET", "https://example.com/") assert response.status == 200 assert response.content == b"Hello, world!" assert response.extensions["http_version"] == b"HTTP/2" @pytest.mark.anyio async def test_request_to_incorrect_origin() -> None: """ A connection can only send requests whichever origin it is connected to. """ origin = Origin(b"https", b"example.com", 443) network_backend = AsyncMockBackend([]) async with AsyncHTTPConnection(origin=origin, network_backend=network_backend) as conn: with pytest.raises(RuntimeError): await conn.request("GET", "https://other.com/") class NeedsRetryBackend(AsyncMockBackend): def __init__( self, buffer: list[bytes], http2: bool = False, connect_tcp_failures: int = 2, start_tls_failures: int = 0, ) -> None: self._connect_tcp_failures = connect_tcp_failures self._start_tls_failures = start_tls_failures super().__init__(buffer, http2) async def connect_tcp( self, host: str, port: int, timeout: float | None = None, local_address: str | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> AsyncNetworkStream: if self._connect_tcp_failures > 0: self._connect_tcp_failures -= 1 raise ConnectError() stream = await super().connect_tcp(host, port, timeout=timeout, local_address=local_address) return self._NeedsRetryAsyncNetworkStream(self, stream) class _NeedsRetryAsyncNetworkStream(AsyncNetworkStream): def __init__(self, backend: "NeedsRetryBackend", stream: AsyncNetworkStream) -> None: self._backend = backend self._stream = stream async def read(self, max_bytes: int, timeout: float | None = None) -> bytes: return await self._stream.read(max_bytes, timeout) async def write(self, buffer: bytes, timeout: float | None = None) -> None: await self._stream.write(buffer, timeout) async def aclose(self) -> None: await self._stream.aclose() async def start_tls( self, ssl_context: ssl.SSLContext, server_hostname: str | None = None, timeout: float | None = None, ) -> "AsyncNetworkStream": if self._backend._start_tls_failures > 0: self._backend._start_tls_failures -= 1 raise ConnectError() stream = await self._stream.start_tls(ssl_context, server_hostname, timeout) return self._backend._NeedsRetryAsyncNetworkStream(self._backend, stream) def get_extra_info(self, info: str) -> typing.Any: return self._stream.get_extra_info(info) @pytest.mark.anyio async def test_connection_retries() -> None: origin = Origin(b"https", b"example.com", 443) content = [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] network_backend = NeedsRetryBackend(content) async with AsyncHTTPConnection(origin=origin, network_backend=network_backend, retries=3) as conn: response = await conn.request("GET", "https://example.com/") assert response.status == 200 network_backend = NeedsRetryBackend(content) async with AsyncHTTPConnection( origin=origin, network_backend=network_backend, ) as conn: with pytest.raises(ConnectError): await conn.request("GET", "https://example.com/") @pytest.mark.anyio async def test_connection_retries_tls() -> None: origin = Origin(b"https", b"example.com", 443) content = [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] network_backend = NeedsRetryBackend(content, connect_tcp_failures=0, start_tls_failures=2) async with AsyncHTTPConnection(origin=origin, network_backend=network_backend, retries=3) as conn: response = await conn.request("GET", "https://example.com/") assert response.status == 200 network_backend = NeedsRetryBackend(content, connect_tcp_failures=0, start_tls_failures=2) async with AsyncHTTPConnection( origin=origin, network_backend=network_backend, ) as conn: with pytest.raises(ConnectError): await conn.request("GET", "https://example.com/") @pytest.mark.anyio async def test_uds_connections() -> None: # We're not actually testing Unix Domain Sockets here, because we're just # using a mock backend, but at least we're covering the UDS codepath # in `connection.py` which we may as well do. origin = Origin(b"https", b"example.com", 443) network_backend = AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) async with AsyncHTTPConnection(origin=origin, network_backend=network_backend, uds="/mock/example") as conn: response = await conn.request("GET", "https://example.com/") assert response.status == 200 pydantic-httpx2-6dd59b9/tests/httpcore2/_async/test_connection_pool.py000066400000000000000000001043251526547463400263620ustar00rootroot00000000000000import logging import typing import hpack import hyperframe.frame import pytest import trio as concurrency import httpcore2 @pytest.mark.anyio async def test_connection_pool_with_keepalive() -> None: """ By default HTTP/1.1 requests should be returned to the connection pool. """ network_backend = httpcore2.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) async with httpcore2.AsyncConnectionPool(network_backend=network_backend, max_keepalive_connections=1) as pool: # Sending an initial request, which once complete will return to the pool, IDLE. async with pool.stream("GET", "https://example.com/") as response: info = [repr(c) for c in pool.connections] assert info == [""] assert repr(pool) == "" await response.aread() assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in pool.connections] assert info == [""] assert repr(pool) == "" # Sending a second request to the same origin will reuse the existing IDLE connection. async with pool.stream("GET", "https://example.com/") as response: info = [repr(c) for c in pool.connections] assert info == [""] assert repr(pool) == "" await response.aread() assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in pool.connections] assert info == [""] assert repr(pool) == "" # Sending a request to a different origin will not reuse the existing IDLE connection. async with ( pool.stream("GET", "http://example.com/") as response_1, pool.stream("GET", "http://example.com/") as response_2, ): info = [repr(c) for c in pool.connections] assert info == [ "", "", "", ] assert repr(pool) == "" await response_1.aread() await response_2.aread() assert response_1.status == 200 assert response_1.content == b"Hello, world!" assert response_2.status == 200 assert response_2.content == b"Hello, world!" info = [repr(c) for c in pool.connections] assert info == [ "", ] assert repr(pool) == "" @pytest.mark.anyio async def test_connection_pool_with_close() -> None: """ HTTP/1.1 requests that include a 'Connection: Close' header should not be returned to the connection pool. """ network_backend = httpcore2.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) async with httpcore2.AsyncConnectionPool(network_backend=network_backend) as pool: # Sending an initial request, which once complete will not return to the pool. async with pool.stream("GET", "https://example.com/", headers={"Connection": "close"}) as response: info = [repr(c) for c in pool.connections] assert info == [""] await response.aread() assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in pool.connections] assert info == [] @pytest.mark.anyio async def test_connection_pool_with_http2() -> None: """ Test a connection pool with HTTP/2 requests. """ network_backend = httpcore2.AsyncMockBackend( buffer=[ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), hyperframe.frame.HeadersFrame( stream_id=3, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=3, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), ], http2=True, ) async with httpcore2.AsyncConnectionPool( network_backend=network_backend, ) as pool: # Sending an initial request, which once complete will return to the pool, IDLE. response = await pool.request("GET", "https://example.com/") assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in pool.connections] assert info == [""] # Sending a second request to the same origin will reuse the existing IDLE connection. response = await pool.request("GET", "https://example.com/") assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in pool.connections] assert info == [""] @pytest.mark.anyio async def test_connection_pool_with_http2_goaway() -> None: """ Test a connection pool with HTTP/2 requests, that cleanly disconnects with a GoAway frame after the first request. """ network_backend = httpcore2.AsyncMockBackend( buffer=[ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), hyperframe.frame.GoAwayFrame(stream_id=0, error_code=0, last_stream_id=1).serialize(), b"", ], http2=True, ) async with httpcore2.AsyncConnectionPool( network_backend=network_backend, ) as pool: # Sending an initial request, which once complete will return to the pool, IDLE. response = await pool.request("GET", "https://example.com/") assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in pool.connections] assert info == [""] # Sending a second request to the same origin will require a new connection. # The original connection has now been closed. response = await pool.request("GET", "https://example.com/") assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in pool.connections] assert info == [ "", ] @pytest.mark.anyio async def test_trace_request() -> None: """ The 'trace' request extension allows for a callback function to inspect the internal events that occur while sending a request. """ network_backend = httpcore2.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) called: list[str] = [] async def trace(name: str, kwargs: dict[str, typing.Any]) -> None: called.append(name) async with httpcore2.AsyncConnectionPool(network_backend=network_backend) as pool: await pool.request("GET", "https://example.com/", extensions={"trace": trace}) assert called == [ "connection.connect_tcp.started", "connection.connect_tcp.complete", "connection.start_tls.started", "connection.start_tls.complete", "http11.send_request_headers.started", "http11.send_request_headers.complete", "http11.send_request_body.started", "http11.send_request_body.complete", "http11.receive_response_headers.started", "http11.receive_response_headers.complete", "http11.receive_response_body.started", "http11.receive_response_body.complete", "http11.response_closed.started", "http11.response_closed.complete", ] @pytest.mark.anyio async def test_debug_request(caplog: pytest.LogCaptureFixture) -> None: """ The 'trace' request extension allows for a callback function to inspect the internal events that occur while sending a request. """ caplog.set_level(logging.DEBUG) network_backend = httpcore2.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) async with httpcore2.AsyncConnectionPool(network_backend=network_backend) as pool: await pool.request("GET", "http://example.com/") assert caplog.record_tuples == [ ( "httpcore2.connection", logging.DEBUG, "connect_tcp.started host='example.com' port=80 local_address=None timeout=None socket_options=None", ), ( "httpcore2.connection", logging.DEBUG, "connect_tcp.complete return_value=", ), ( "httpcore2.http11", logging.DEBUG, "send_request_headers.started request=", ), ("httpcore2.http11", logging.DEBUG, "send_request_headers.complete"), ( "httpcore2.http11", logging.DEBUG, "send_request_body.started request=", ), ("httpcore2.http11", logging.DEBUG, "send_request_body.complete"), ( "httpcore2.http11", logging.DEBUG, "receive_response_headers.started request=", ), ( "httpcore2.http11", logging.DEBUG, "receive_response_headers.complete return_value=" "(b'HTTP/1.1', 200, b'OK', [(b'Content-Type', b'plain/text'), (b'Content-Length', b'13')])", ), ( "httpcore2.http11", logging.DEBUG, "receive_response_body.started request=", ), ("httpcore2.http11", logging.DEBUG, "receive_response_body.complete"), ("httpcore2.http11", logging.DEBUG, "response_closed.started"), ("httpcore2.http11", logging.DEBUG, "response_closed.complete"), ("httpcore2.connection", logging.DEBUG, "close.started"), ("httpcore2.connection", logging.DEBUG, "close.complete"), ] @pytest.mark.anyio async def test_connection_pool_with_http_exception() -> None: """ HTTP/1.1 requests that result in an exception during the connection should not be returned to the connection pool. """ network_backend = httpcore2.AsyncMockBackend([b"Wait, this isn't valid HTTP!"]) called: list[str] = [] async def trace(name: str, kwargs: dict[str, typing.Any]) -> None: called.append(name) async with httpcore2.AsyncConnectionPool(network_backend=network_backend) as pool: # Sending an initial request, which once complete will not return to the pool. with pytest.raises(httpcore2.RemoteProtocolError): await pool.request("GET", "https://example.com/", extensions={"trace": trace}) info = [repr(c) for c in pool.connections] assert info == [] assert called == [ "connection.connect_tcp.started", "connection.connect_tcp.complete", "connection.start_tls.started", "connection.start_tls.complete", "http11.send_request_headers.started", "http11.send_request_headers.complete", "http11.send_request_body.started", "http11.send_request_body.complete", "http11.receive_response_headers.started", "http11.receive_response_headers.failed", "http11.response_closed.started", "http11.response_closed.complete", ] @pytest.mark.anyio async def test_connection_pool_with_connect_exception() -> None: """ HTTP/1.1 requests that result in an exception during connection should not be returned to the connection pool. """ class FailedConnectBackend(httpcore2.AsyncMockBackend): async def connect_tcp( self, host: str, port: int, timeout: float | None = None, local_address: str | None = None, socket_options: typing.Iterable[httpcore2.SOCKET_OPTION] | None = None, ) -> httpcore2.AsyncNetworkStream: raise httpcore2.ConnectError("Could not connect") network_backend = FailedConnectBackend([]) called: list[str] = [] async def trace(name: str, kwargs: dict[str, typing.Any]) -> None: called.append(name) async with httpcore2.AsyncConnectionPool(network_backend=network_backend) as pool: # Sending an initial request, which once complete will not return to the pool. with pytest.raises(httpcore2.ConnectError): await pool.request("GET", "https://example.com/", extensions={"trace": trace}) info = [repr(c) for c in pool.connections] assert info == [] assert called == [ "connection.connect_tcp.started", "connection.connect_tcp.failed", ] @pytest.mark.anyio async def test_connection_pool_with_immediate_expiry() -> None: """ Connection pools with keepalive_expiry=0.0 should immediately expire keep alive connections. """ network_backend = httpcore2.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) async with httpcore2.AsyncConnectionPool( keepalive_expiry=0.0, network_backend=network_backend, ) as pool: # Sending an initial request, which once complete will not return to the pool. async with pool.stream("GET", "https://example.com/") as response: info = [repr(c) for c in pool.connections] assert info == [""] await response.aread() assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in pool.connections] assert info == [] @pytest.mark.anyio async def test_connection_pool_with_no_keepalive_connections_allowed() -> None: """ When 'max_keepalive_connections=0' is used, IDLE connections should not be returned to the pool. """ network_backend = httpcore2.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) async with httpcore2.AsyncConnectionPool(max_keepalive_connections=0, network_backend=network_backend) as pool: # Sending an initial request, which once complete will not return to the pool. async with pool.stream("GET", "https://example.com/") as response: info = [repr(c) for c in pool.connections] assert info == [""] await response.aread() assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in pool.connections] assert info == [] @pytest.mark.anyio async def test_connection_pool_closes_idle_connection_for_different_origin() -> None: """ When the pool is at 'max_connections' and an incoming request is for an origin with no reusable connection, an IDLE connection to a different origin is closed to make room for the new connection. """ network_backend = httpcore2.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) async with httpcore2.AsyncConnectionPool(network_backend=network_backend, max_connections=1) as pool: # An initial request to a.com leaves a single IDLE connection in the pool. response = await pool.request("GET", "https://a.com/") assert response.status == 200 info = [repr(c) for c in pool.connections] assert info == [""] # A request to b.com cannot reuse the a.com connection and the pool is full, # so the IDLE a.com connection is closed and replaced with a b.com connection. response = await pool.request("GET", "https://b.com/") assert response.status == 200 info = [repr(c) for c in pool.connections] assert info == [""] @pytest.mark.trio async def test_connection_pool_concurrency() -> None: """ HTTP/1.1 requests made in concurrency must not ever exceed the maximum number of allowable connection in the pool. """ network_backend = httpcore2.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) async def fetch(pool: httpcore2.AsyncConnectionPool, domain: str, info_list: list[list[str]]) -> None: async with pool.stream("GET", f"http://{domain}/") as response: info = [repr(c) for c in pool.connections] info_list.append(info) await response.aread() async with httpcore2.AsyncConnectionPool(max_connections=1, network_backend=network_backend) as pool: info_list: list[list[str]] = [] async with concurrency.open_nursery() as nursery: for domain in ["a.com", "b.com", "c.com", "d.com", "e.com"]: nursery.start_soon(fetch, pool, domain, info_list) for item in info_list: # Check that each time we inspected the connection pool, only a # single connection was established at any one time. assert len(item) == 1 # Each connection was to a different host, and only sent a single # request on that connection. assert item[0] in [ "", "", "", "", "", ] @pytest.mark.trio async def test_connection_pool_concurrency_same_domain_closing() -> None: """ HTTP/1.1 requests made in concurrency must not ever exceed the maximum number of allowable connection in the pool. """ network_backend = httpcore2.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"Connection: close\r\n", b"\r\n", b"Hello, world!", ] ) async def fetch(pool: httpcore2.AsyncConnectionPool, domain: str, info_list: list[list[str]]) -> None: async with pool.stream("GET", f"https://{domain}/") as response: info = [repr(c) for c in pool.connections] info_list.append(info) await response.aread() async with httpcore2.AsyncConnectionPool(max_connections=1, network_backend=network_backend, http2=True) as pool: info_list: list[list[str]] = [] async with concurrency.open_nursery() as nursery: for domain in ["a.com", "a.com", "a.com", "a.com", "a.com"]: nursery.start_soon(fetch, pool, domain, info_list) for item in info_list: # Check that each time we inspected the connection pool, only a # single connection was established at any one time. assert len(item) == 1 # Only a single request was sent on each connection. assert item[0] == "" @pytest.mark.trio async def test_connection_pool_concurrency_same_domain_keepalive() -> None: """ HTTP/1.1 requests made in concurrency must not ever exceed the maximum number of allowable connection in the pool. """ network_backend = httpcore2.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] * 5 ) async def fetch(pool: httpcore2.AsyncConnectionPool, domain: str, info_list: list[list[str]]) -> None: async with pool.stream("GET", f"https://{domain}/") as response: info = [repr(c) for c in pool.connections] info_list.append(info) await response.aread() async with httpcore2.AsyncConnectionPool(max_connections=1, network_backend=network_backend, http2=True) as pool: info_list: list[list[str]] = [] async with concurrency.open_nursery() as nursery: for domain in ["a.com", "a.com", "a.com", "a.com", "a.com"]: nursery.start_soon(fetch, pool, domain, info_list) for item in info_list: # Check that each time we inspected the connection pool, only a # single connection was established at any one time. assert len(item) == 1 # The connection sent multiple requests. assert item[0] in [ "", "", "", "", "", ] assert repr(pool) == "" @pytest.mark.anyio async def test_unsupported_protocol() -> None: async with httpcore2.AsyncConnectionPool() as pool: with pytest.raises(httpcore2.UnsupportedProtocol): await pool.request("GET", "ftp://www.example.com/") with pytest.raises(httpcore2.UnsupportedProtocol): await pool.request("GET", "://www.example.com/") @pytest.mark.anyio async def test_connection_pool_closed_while_request_in_flight() -> None: """ Closing a connection pool while a request/response is still in-flight should raise an error. """ network_backend = httpcore2.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) async with httpcore2.AsyncConnectionPool( network_backend=network_backend, ) as pool: # Send a request, and then close the connection pool while the # response has not yet been streamed. async with pool.stream("GET", "https://example.com/") as response: await pool.aclose() with pytest.raises(httpcore2.ReadError): await response.aread() @pytest.mark.anyio async def test_connection_pool_timeout() -> None: """ Ensure that exceeding max_connections can cause a request to timeout. """ network_backend = httpcore2.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) async with httpcore2.AsyncConnectionPool(network_backend=network_backend, max_connections=1) as pool: # Send a request to a pool that is configured to only support a single # connection, and then ensure that a second concurrent request # fails with a timeout. async with pool.stream("GET", "https://example.com/"): with pytest.raises(httpcore2.PoolTimeout): extensions = {"timeout": {"pool": 0.0001}} await pool.request("GET", "https://example.com/", extensions=extensions) @pytest.mark.anyio async def test_connection_pool_timeout_zero() -> None: """ A pool timeout of 0 shouldn't raise a PoolTimeout if there's no need to wait on a new connection. """ network_backend = httpcore2.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) # Use a pool timeout of zero. extensions = {"timeout": {"pool": 0}} # A connection pool configured to allow only one connection at a time. async with httpcore2.AsyncConnectionPool(network_backend=network_backend, max_connections=1) as pool: # Two consecutive requests with a pool timeout of zero. # Both succeed without raising a timeout. response = await pool.request("GET", "https://example.com/", extensions=extensions) assert response.status == 200 assert response.content == b"Hello, world!" response = await pool.request("GET", "https://example.com/", extensions=extensions) assert response.status == 200 assert response.content == b"Hello, world!" # A connection pool configured to allow only one connection at a time. async with httpcore2.AsyncConnectionPool(network_backend=network_backend, max_connections=1) as pool: # Two concurrent requests with a pool timeout of zero. # Only the first will succeed without raising a timeout. async with pool.stream("GET", "https://example.com/", extensions=extensions) as response: # The first response hasn't yet completed. with pytest.raises(httpcore2.PoolTimeout): # So a pool timeout occurs. await pool.request("GET", "https://example.com/", extensions=extensions) # The first response now completes. await response.aread() assert response.status == 200 assert response.content == b"Hello, world!" @pytest.mark.anyio async def test_http11_upgrade_connection() -> None: """ HTTP "101 Switching Protocols" indicates an upgraded connection. We should return the response, so that the network stream may be used for the upgraded connection. https://httpwg.org/specs/rfc9110.html#status.101 https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/101 """ network_backend = httpcore2.AsyncMockBackend( [ b"HTTP/1.1 101 Switching Protocols\r\n", b"Connection: upgrade\r\n", b"Upgrade: custom\r\n", b"\r\n", b"...", ] ) called: list[str] = [] async def trace(name: str, kwargs: dict[str, typing.Any]) -> None: called.append(name) async with httpcore2.AsyncConnectionPool(network_backend=network_backend, max_connections=1) as pool: async with pool.stream( "GET", "wss://example.com/", headers={"Connection": "upgrade", "Upgrade": "custom"}, extensions={"trace": trace}, ) as response: assert response.status == 101 network_stream = response.extensions["network_stream"] content = await network_stream.read(max_bytes=1024) assert content == b"..." assert called == [ "connection.connect_tcp.started", "connection.connect_tcp.complete", "connection.start_tls.started", "connection.start_tls.complete", "http11.send_request_headers.started", "http11.send_request_headers.complete", "http11.send_request_body.started", "http11.send_request_body.complete", "http11.receive_response_headers.started", "http11.receive_response_headers.complete", "http11.response_closed.started", "http11.response_closed.complete", ] @pytest.mark.trio async def test_connection_pool_assigns_released_connection_to_one_queued_request() -> None: """ A released connection must be handed to exactly one queued request. Assigning it to every queued request wakes them all, only for all but one to fail with `ConnectionNotAvailable` and re-enter the queue, degrading quadratically with queue depth. """ class CountingPool(httpcore2.AsyncConnectionPool): assign_passes = 0 def _assign_requests_to_connections(self) -> list[httpcore2.AsyncConnectionInterface]: CountingPool.assign_passes += 1 return super()._assign_requests_to_connections() network_backend = httpcore2.AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] * 10 ) async def fetch(pool: httpcore2.AsyncConnectionPool) -> None: async with pool.stream("GET", "https://example.com/") as response: await response.aread() assert response.status == 200 async with CountingPool(max_connections=1, network_backend=network_backend) as pool: async with concurrency.open_nursery() as nursery: for _ in range(10): nursery.start_soon(fetch, pool) # Exactly two passes per request: one when it is queued, one when it # releases its connection. assert CountingPool.assign_passes == 2 * 10 @pytest.mark.trio async def test_connection_pool_multiplexes_idle_http2_connection_within_a_pass() -> None: """ A burst of requests arriving while a warmed HTTP/2 connection is idle must be assigned to it immediately, not serialized behind the first request's reservation. """ class QueueObservingPool(httpcore2.AsyncConnectionPool): max_queued_after_pass = 0 def _assign_requests_to_connections(self) -> list[httpcore2.AsyncConnectionInterface]: closing = super()._assign_requests_to_connections() queued = sum(request.is_queued() for request in self._requests) QueueObservingPool.max_queued_after_pass = max(QueueObservingPool.max_queued_after_pass, queued) return closing def response_frames(stream_id: int) -> list[bytes]: return [ hyperframe.frame.HeadersFrame( stream_id=stream_id, data=hpack.Encoder().encode([(b":status", b"200")]), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=stream_id, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), ] network_backend = httpcore2.AsyncMockBackend( buffer=[ hyperframe.frame.SettingsFrame().serialize(), *response_frames(1), *response_frames(3), *response_frames(5), *response_frames(7), ], http2=True, ) async def fetch(pool: httpcore2.AsyncConnectionPool) -> None: response = await pool.request("GET", "https://example.com/") assert response.status == 200 async with QueueObservingPool(network_backend=network_backend, max_connections=1, http2=True) as pool: # Warm the connection; it returns to the pool IDLE. await fetch(pool) async with concurrency.open_nursery() as nursery: for _ in range(3): nursery.start_soon(fetch, pool) assert QueueObservingPool.max_queued_after_pass == 0 pydantic-httpx2-6dd59b9/tests/httpcore2/_async/test_http11.py000066400000000000000000000307321526547463400243130ustar00rootroot00000000000000import pytest import httpcore2 @pytest.mark.anyio async def test_http11_connection() -> None: origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.AsyncMockStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) async with httpcore2.AsyncHTTP11Connection(origin=origin, stream=stream, keepalive_expiry=5.0) as conn: response = await conn.request("GET", "https://example.com/") assert response.status == 200 assert response.content == b"Hello, world!" assert conn.is_idle() assert not conn.is_closed() assert conn.is_available() assert not conn.has_expired() assert conn.is_connected() assert repr(conn) == "" @pytest.mark.anyio async def test_http11_connection_unread_response() -> None: """ If the client releases the response without reading it to termination, then the connection will not be reusable. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.AsyncMockStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) async with httpcore2.AsyncHTTP11Connection(origin=origin, stream=stream) as conn: async with conn.stream("GET", "https://example.com/") as response: assert response.status == 200 assert not conn.is_idle() assert conn.is_closed() assert not conn.is_available() assert not conn.has_expired() assert repr(conn) == "" @pytest.mark.anyio async def test_http11_connection_with_remote_protocol_error() -> None: """ If a remote protocol error occurs, then no response will be returned, and the connection will not be reusable. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.AsyncMockStream([b"Wait, this isn't valid HTTP!", b""]) async with httpcore2.AsyncHTTP11Connection(origin=origin, stream=stream) as conn: with pytest.raises(httpcore2.RemoteProtocolError): await conn.request("GET", "https://example.com/") assert not conn.is_idle() assert conn.is_closed() assert not conn.is_available() assert not conn.has_expired() assert repr(conn) == "" @pytest.mark.anyio async def test_http11_connection_with_incomplete_response() -> None: """ We should be gracefully handling the case where the connection ends prematurely. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.AsyncMockStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, wor", ] ) async with httpcore2.AsyncHTTP11Connection(origin=origin, stream=stream) as conn: with pytest.raises(httpcore2.RemoteProtocolError): await conn.request("GET", "https://example.com/") assert not conn.is_idle() assert conn.is_closed() assert not conn.is_available() assert not conn.has_expired() assert repr(conn) == "" @pytest.mark.anyio async def test_http11_connection_with_local_protocol_error() -> None: """ If a local protocol error occurs, then no response will be returned, and the connection will not be reusable. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.AsyncMockStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) async with httpcore2.AsyncHTTP11Connection(origin=origin, stream=stream) as conn: with pytest.raises(httpcore2.LocalProtocolError) as exc_info: await conn.request("GET", "https://example.com/", headers={"Host": "\0"}) assert str(exc_info.value) == "Illegal header value b'\\x00'" assert not conn.is_idle() assert conn.is_closed() assert not conn.is_available() assert not conn.has_expired() assert repr(conn) == "" @pytest.mark.anyio async def test_http11_connection_handles_one_active_request() -> None: """ Attempting to send a request while one is already in-flight will raise a ConnectionNotAvailable exception. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.AsyncMockStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) async with httpcore2.AsyncHTTP11Connection(origin=origin, stream=stream) as conn: async with conn.stream("GET", "https://example.com/"): with pytest.raises(httpcore2.ConnectionNotAvailable): await conn.request("GET", "https://example.com/") @pytest.mark.anyio async def test_http11_connection_attempt_close() -> None: """ A connection can only be closed when it is idle. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.AsyncMockStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) async with httpcore2.AsyncHTTP11Connection(origin=origin, stream=stream) as conn: async with conn.stream("GET", "https://example.com/") as response: await response.aread() assert response.status == 200 assert response.content == b"Hello, world!" @pytest.mark.anyio async def test_http11_request_to_incorrect_origin() -> None: """ A connection can only send requests to whichever origin it is connected to. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.AsyncMockStream([]) async with httpcore2.AsyncHTTP11Connection(origin=origin, stream=stream) as conn: with pytest.raises(RuntimeError): await conn.request("GET", "https://other.com/") @pytest.mark.anyio async def test_http11_expect_continue() -> None: """ HTTP "100 Continue" is an interim response. We simply ignore it and return the final response. https://httpwg.org/specs/rfc9110.html#status.100 https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/100 """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.AsyncMockStream( [ b"HTTP/1.1 100 Continue\r\n", b"\r\n", b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) async with httpcore2.AsyncHTTP11Connection(origin=origin, stream=stream, keepalive_expiry=5.0) as conn: response = await conn.request( "GET", "https://example.com/", headers={"Expect": "continue"}, ) assert response.status == 200 assert response.content == b"Hello, world!" @pytest.mark.anyio async def test_http11_upgrade_connection() -> None: """ HTTP "101 Switching Protocols" indicates an upgraded connection. We should return the response, so that the network stream may be used for the upgraded connection. https://httpwg.org/specs/rfc9110.html#status.101 https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/101 """ origin = httpcore2.Origin(b"wss", b"example.com", 443) stream = httpcore2.AsyncMockStream( [ b"HTTP/1.1 101 Switching Protocols\r\n", b"Connection: upgrade\r\n", b"Upgrade: custom\r\n", b"\r\n", b"...", ] ) async with httpcore2.AsyncHTTP11Connection(origin=origin, stream=stream, keepalive_expiry=5.0) as conn: async with conn.stream( "GET", "wss://example.com/", headers={"Connection": "upgrade", "Upgrade": "custom"}, ) as response: assert response.status == 101 network_stream = response.extensions["network_stream"] content = await network_stream.read(max_bytes=1024) assert content == b"..." @pytest.mark.anyio async def test_http11_upgrade_with_trailing_data() -> None: """ HTTP "101 Switching Protocols" indicates an upgraded connection. In `CONNECT` and `Upgrade:` requests, we need to handover the trailing data in the h11.Connection object. https://h11.readthedocs.io/en/latest/api.html#switching-protocols """ origin = httpcore2.Origin(b"wss", b"example.com", 443) stream = httpcore2.AsyncMockStream( # The first element of this mock network stream buffer simulates networking # in which response headers and data are received at once. # This means that "foobar" becomes trailing data. [ (b"HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nUpgrade: custom\r\n\r\nfoobar"), b"baz", ] ) async with httpcore2.AsyncHTTP11Connection(origin=origin, stream=stream, keepalive_expiry=5.0) as conn: async with conn.stream( "GET", "wss://example.com/", headers={"Connection": "upgrade", "Upgrade": "custom"}, ) as response: assert response.status == 101 network_stream = response.extensions["network_stream"] content = await network_stream.read(max_bytes=3) assert content == b"foo" content = await network_stream.read(max_bytes=3) assert content == b"bar" content = await network_stream.read(max_bytes=3) assert content == b"baz" # Lazy tests for AsyncHTTP11UpgradeStream await network_stream.write(b"spam") invalid = network_stream.get_extra_info("invalid") assert invalid is None await network_stream.aclose() @pytest.mark.anyio async def test_http11_early_hints() -> None: """ HTTP "103 Early Hints" is an interim response. We simply ignore it and return the final response. https://datatracker.ietf.org/doc/rfc8297/ """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.AsyncMockStream( [ b"HTTP/1.1 103 Early Hints\r\n", b"Link: ; rel=preload; as=style\r\n", b"Link: ; rel=preload; as=style\r\n", b"\r\n", b"HTTP/1.1 200 OK\r\n", b"Content-Type: text/html; charset=utf-8\r\n", b"Content-Length: 30\r\n", b"Link: ; rel=preload; as=style\r\n", b"Link: ; rel=preload; as=script\r\n", b"\r\n", b"Hello, world! ...", ] ) async with httpcore2.AsyncHTTP11Connection(origin=origin, stream=stream, keepalive_expiry=5.0) as conn: response = await conn.request( "GET", "https://example.com/", headers={"Expect": "continue"}, ) assert response.status == 200 assert response.content == b"Hello, world! ..." @pytest.mark.anyio async def test_http11_header_sub_100kb() -> None: """ A connection should be able to handle a http header size up to 100kB. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.AsyncMockStream( [ b"HTTP/1.1 200 OK\r\n", # 17 b"Content-Type: plain/text\r\n", # 43 b"Cookie: " + b"x" * (100 * 1024 - 72) + b"\r\n", # 102381 b"Content-Length: 0\r\n", # 102400 b"\r\n", b"", ] ) async with httpcore2.AsyncHTTP11Connection(origin=origin, stream=stream, keepalive_expiry=5.0) as conn: response = await conn.request("GET", "https://example.com/") assert response.status == 200 assert response.content == b"" pydantic-httpx2-6dd59b9/tests/httpcore2/_async/test_http2.py000066400000000000000000000461141526547463400242340ustar00rootroot00000000000000import hpack import hyperframe.frame import pytest import httpcore2 @pytest.mark.anyio async def test_http2_connection() -> None: origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.AsyncMockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), ] ) async with httpcore2.AsyncHTTP2Connection(origin=origin, stream=stream, keepalive_expiry=5.0) as conn: response = await conn.request("GET", "https://example.com/") assert response.status == 200 assert response.content == b"Hello, world!" assert conn.is_idle() assert conn.is_available() assert not conn.is_closed() assert not conn.has_expired() assert conn.is_connected() assert conn.info() == "'https://example.com:443', HTTP/2, IDLE, Request Count: 1" assert repr(conn) == "" @pytest.mark.anyio async def test_http2_connection_closed() -> None: origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.AsyncMockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), # Connection is closed after the first response hyperframe.frame.GoAwayFrame(stream_id=0, error_code=0, last_stream_id=1).serialize(), ] ) async with httpcore2.AsyncHTTP2Connection(origin=origin, stream=stream, keepalive_expiry=5.0) as conn: await conn.request("GET", "https://example.com/") with pytest.raises(httpcore2.ConnectionNotAvailable): await conn.request("GET", "https://example.com/") assert not conn.is_available() @pytest.mark.anyio async def test_http2_response_closed_twice() -> None: """ Closing a response for a stream that has already been removed should be a no-op, rather than raising a `KeyError` that masks the exception which triggered the cleanup. See https://github.com/encode/httpx/issues/3072 """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.AsyncMockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), ] ) async with httpcore2.AsyncHTTP2Connection(origin=origin, stream=stream, keepalive_expiry=5.0) as conn: await conn.request("GET", "https://example.com/") # The stream was closed when the response completed. await conn._response_closed(stream_id=1) @pytest.mark.anyio async def test_http2_connection_post_request() -> None: origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.AsyncMockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), ] ) async with httpcore2.AsyncHTTP2Connection(origin=origin, stream=stream) as conn: response = await conn.request( "POST", "https://example.com/", headers={b"content-length": b"17"}, content=b'{"data": "upload"}', ) assert response.status == 200 assert response.content == b"Hello, world!" @pytest.mark.anyio async def test_http2_connection_with_remote_protocol_error() -> None: """ If a remote protocol error occurs, then no response will be returned, and the connection will not be reusable. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.AsyncMockStream([b"Wait, this isn't valid HTTP!", b""]) async with httpcore2.AsyncHTTP2Connection(origin=origin, stream=stream) as conn: with pytest.raises(httpcore2.RemoteProtocolError): await conn.request("GET", "https://example.com/") @pytest.mark.anyio async def test_http2_connection_with_rst_stream() -> None: """ If a stream reset occurs, then no response will be returned, but the connection will remain reusable for other requests. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.AsyncMockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), # Stream is closed midway through the first response... hyperframe.frame.RstStreamFrame(stream_id=1, error_code=8).serialize(), # ...Which doesn't prevent the second response. hyperframe.frame.HeadersFrame( stream_id=3, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=3, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), b"", ] ) async with httpcore2.AsyncHTTP2Connection(origin=origin, stream=stream) as conn: with pytest.raises(httpcore2.RemoteProtocolError): await conn.request("GET", "https://example.com/") response = await conn.request("GET", "https://example.com/") assert response.status == 200 @pytest.mark.anyio async def test_http2_connection_with_goaway() -> None: """ If a GoAway frame occurs, then no response will be returned, and the connection will not be reusable for other requests. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.AsyncMockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), # Connection is closed midway through the first response... hyperframe.frame.GoAwayFrame(stream_id=0, error_code=0).serialize(), # ...We'll never get to this second response. hyperframe.frame.HeadersFrame( stream_id=3, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=3, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), b"", ] ) async with httpcore2.AsyncHTTP2Connection(origin=origin, stream=stream) as conn: # The initial request has been closed midway, with an unrecoverable error. with pytest.raises(httpcore2.RemoteProtocolError): await conn.request("GET", "https://example.com/") # The second request can receive a graceful `ConnectionNotAvailable`, # and may be retried on a new connection. with pytest.raises(httpcore2.ConnectionNotAvailable): await conn.request("GET", "https://example.com/") @pytest.mark.anyio async def test_http2_connection_with_negative_flow_control_window() -> None: """A negative stream flow-control window must be awaited, not sent into. After the 65535-byte window is exhausted, the server reduces INITIAL_WINDOW_SIZE by 32767, which adjusts the just-exhausted stream window from 0 to -32767. `_wait_for_outgoing_flow` must park the stream until WINDOW_UPDATE restores positive credit; otherwise `h2` raises `LocalProtocolError` on the next send_data. """ origin = httpcore2.Origin(b"https", b"example.com", 443) reduce_settings = hyperframe.frame.SettingsFrame(stream_id=0) reduce_settings.settings = {hyperframe.frame.SettingsFrame.INITIAL_WINDOW_SIZE: 32768} stream = httpcore2.AsyncMockStream( [ hyperframe.frame.SettingsFrame(stream_id=0).serialize(), # This frame reduces INITIAL_WINDOW_SIZE to 32768, which adjusts the just-exhausted stream window to -32767. reduce_settings.serialize(), hyperframe.frame.WindowUpdateFrame(stream_id=0, window_increment=100_000).serialize(), hyperframe.frame.WindowUpdateFrame(stream_id=1, window_increment=100_000).serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"response", flags=["END_STREAM"]).serialize(), ] ) async with httpcore2.AsyncHTTP2Connection(origin=origin, stream=stream) as conn: response = await conn.request("POST", "https://example.com/", content=b"x" * 100_000) assert response.status == 200 assert response.content == b"response" @pytest.mark.anyio async def test_http2_connection_with_flow_control() -> None: origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.AsyncMockStream( [ hyperframe.frame.SettingsFrame().serialize(), # Available flow: 65,535 hyperframe.frame.WindowUpdateFrame(stream_id=0, window_increment=10_000).serialize(), hyperframe.frame.WindowUpdateFrame(stream_id=1, window_increment=10_000).serialize(), # Available flow: 75,535 hyperframe.frame.WindowUpdateFrame(stream_id=0, window_increment=10_000).serialize(), hyperframe.frame.WindowUpdateFrame(stream_id=1, window_increment=10_000).serialize(), # Available flow: 85,535 hyperframe.frame.WindowUpdateFrame(stream_id=0, window_increment=10_000).serialize(), hyperframe.frame.WindowUpdateFrame(stream_id=1, window_increment=10_000).serialize(), # Available flow: 95,535 hyperframe.frame.WindowUpdateFrame(stream_id=0, window_increment=10_000).serialize(), hyperframe.frame.WindowUpdateFrame(stream_id=1, window_increment=10_000).serialize(), # Available flow: 105,535 hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"100,000 bytes received", flags=["END_STREAM"]).serialize(), ] ) async with httpcore2.AsyncHTTP2Connection(origin=origin, stream=stream) as conn: response = await conn.request( "POST", "https://example.com/", content=b"x" * 100_000, ) assert response.status == 200 assert response.content == b"100,000 bytes received" @pytest.mark.anyio async def test_http2_connection_attempt_close() -> None: """ A connection can only be closed when it is idle. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.AsyncMockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), ] ) async with httpcore2.AsyncHTTP2Connection(origin=origin, stream=stream) as conn: async with conn.stream("GET", "https://example.com/") as response: await response.aread() assert response.status == 200 assert response.content == b"Hello, world!" await conn.aclose() with pytest.raises(httpcore2.ConnectionNotAvailable): await conn.request("GET", "https://example.com/") @pytest.mark.anyio async def test_http2_request_to_incorrect_origin() -> None: """ A connection can only send requests to whichever origin it is connected to. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.AsyncMockStream([]) async with httpcore2.AsyncHTTP2Connection(origin=origin, stream=stream) as conn: with pytest.raises(RuntimeError): await conn.request("GET", "https://other.com/") @pytest.mark.anyio async def test_http2_remote_max_streams_update() -> None: """ If the remote server updates the maximum concurrent streams value, we should be adjusting how many streams we will allow. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.AsyncMockStream( [ hyperframe.frame.SettingsFrame( settings={hyperframe.frame.SettingsFrame.MAX_CONCURRENT_STREAMS: 1000} ).serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"Hello, world!").serialize(), hyperframe.frame.SettingsFrame( settings={hyperframe.frame.SettingsFrame.MAX_CONCURRENT_STREAMS: 50} ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"Hello, world...again!", flags=["END_STREAM"]).serialize(), ] ) async with httpcore2.AsyncHTTP2Connection(origin=origin, stream=stream) as conn: async with conn.stream("GET", "https://example.com/") as response: i = 0 async for chunk in response.aiter_stream(): if i == 0: assert chunk == b"Hello, world!" assert conn._h2_state.remote_settings.max_concurrent_streams == 1000 assert conn._max_streams == min( conn._h2_state.remote_settings.max_concurrent_streams, conn._h2_state.local_settings.max_concurrent_streams, ) elif i == 1: assert chunk == b"Hello, world...again!" assert conn._h2_state.remote_settings.max_concurrent_streams == 50 assert conn._max_streams == min( conn._h2_state.remote_settings.max_concurrent_streams, conn._h2_state.local_settings.max_concurrent_streams, ) i += 1 @pytest.mark.anyio @pytest.mark.parametrize("limits", [[1], [1, 2], [1, 100], [1, 2, 1]]) async def test_http2_remote_max_streams_decrease_below_in_flight(limits: list[int]) -> None: origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.AsyncMockStream( [ hyperframe.frame.SettingsFrame( settings={hyperframe.frame.SettingsFrame.MAX_CONCURRENT_STREAMS: 100} ).serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode([(b":status", b"200")]), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.HeadersFrame( stream_id=3, data=hpack.Encoder().encode([(b":status", b"200")]), flags=["END_HEADERS"], ).serialize(), *[ hyperframe.frame.SettingsFrame( settings={hyperframe.frame.SettingsFrame.MAX_CONCURRENT_STREAMS: limit} ).serialize() for limit in limits ], hyperframe.frame.DataFrame(stream_id=1, data=b"response a", flags=["END_STREAM"]).serialize(), hyperframe.frame.DataFrame(stream_id=3, data=b"response b", flags=["END_STREAM"]).serialize(), hyperframe.frame.HeadersFrame( stream_id=5, data=hpack.Encoder().encode([(b":status", b"200")]), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=5, data=b"response c", flags=["END_STREAM"]).serialize(), ] ) async with httpcore2.AsyncHTTP2Connection(origin=origin, stream=stream) as conn: async with conn.stream("GET", "https://example.com/a") as response_a: async with conn.stream("GET", "https://example.com/b") as response_b: assert response_a.status == response_b.status == 200 assert await response_a.aread() == b"response a" assert await response_b.aread() == b"response b" response_c = await conn.request("GET", "https://example.com/c") assert response_c.status == 200 assert response_c.content == b"response c" assert conn.is_idle() pydantic-httpx2-6dd59b9/tests/httpcore2/_async/test_http_proxy.py000066400000000000000000000313751526547463400254160ustar00rootroot00000000000000import ssl import typing import hpack import hyperframe.frame import pytest from httpcore2 import ( SOCKET_OPTION, AsyncConnectionPool, AsyncMockBackend, AsyncMockStream, AsyncNetworkStream, Origin, Proxy, ProxyError, ) @pytest.mark.anyio async def test_proxy_forwarding() -> None: """ Send an HTTP request via a proxy. """ network_backend = AsyncMockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) async with AsyncConnectionPool( proxy=Proxy("http://localhost:8080/"), max_connections=10, network_backend=network_backend, ) as proxy: # Sending an initial request, which once complete will return to the pool, IDLE. async with proxy.stream("GET", "http://example.com/") as response: info = [repr(c) for c in proxy.connections] assert info == [ "" ] await response.aread() assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in proxy.connections] assert info == [""] assert proxy.connections[0].is_idle() assert proxy.connections[0].is_available() assert not proxy.connections[0].is_closed() # A connection on a forwarding proxy can only handle HTTP requests to the same origin. assert proxy.connections[0].can_handle_request(Origin(b"http", b"example.com", 80)) assert not proxy.connections[0].can_handle_request(Origin(b"http", b"other.com", 80)) assert not proxy.connections[0].can_handle_request(Origin(b"https", b"example.com", 443)) assert not proxy.connections[0].can_handle_request(Origin(b"https", b"other.com", 443)) @pytest.mark.anyio async def test_proxy_tunneling() -> None: """ Send an HTTPS request via a proxy. """ network_backend = AsyncMockBackend( [ # The initial response to the proxy CONNECT b"HTTP/1.1 200 OK\r\n\r\n", # The actual response from the remote server b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) async with AsyncConnectionPool( proxy=Proxy("http://localhost:8080/"), network_backend=network_backend, ) as proxy: # Sending an initial request, which once complete will return to the pool, IDLE. async with proxy.stream("GET", "https://example.com/") as response: info = [repr(c) for c in proxy.connections] assert info == [ "" ] await response.aread() assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in proxy.connections] assert info == [""] assert proxy.connections[0].is_idle() assert proxy.connections[0].is_available() assert not proxy.connections[0].is_closed() # A connection on a tunneled proxy can only handle HTTPS requests to the same origin. assert not proxy.connections[0].can_handle_request(Origin(b"http", b"example.com", 80)) assert not proxy.connections[0].can_handle_request(Origin(b"http", b"other.com", 80)) assert proxy.connections[0].can_handle_request(Origin(b"https", b"example.com", 443)) assert not proxy.connections[0].can_handle_request(Origin(b"https", b"other.com", 443)) # We need to adapt the mock backend here slightly in order to deal # with the proxy case. We do not want the initial connection to the proxy # to indicate an HTTP/2 connection, but we do want it to indicate HTTP/2 # once the SSL upgrade has taken place. class HTTP1ThenHTTP2Stream(AsyncMockStream): async def start_tls( self, ssl_context: ssl.SSLContext, server_hostname: str | None = None, timeout: float | None = None, ) -> AsyncNetworkStream: self._http2 = True return self class HTTP1ThenHTTP2Backend(AsyncMockBackend): async def connect_tcp( self, host: str, port: int, timeout: float | None = None, local_address: str | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> AsyncNetworkStream: return HTTP1ThenHTTP2Stream(list(self._buffer)) @pytest.mark.anyio async def test_proxy_tunneling_http2() -> None: """ Send an HTTP/2 request via a proxy. """ network_backend = HTTP1ThenHTTP2Backend( [ # The initial response to the proxy CONNECT b"HTTP/1.1 200 OK\r\n\r\n", # The actual response from the remote server hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), ], ) async with AsyncConnectionPool( proxy=Proxy("http://localhost:8080/"), network_backend=network_backend, http2=True, ) as proxy: # Sending an initial request, which once complete will return to the pool, IDLE. async with proxy.stream("GET", "https://example.com/") as response: info = [repr(c) for c in proxy.connections] assert info == [""] await response.aread() assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in proxy.connections] assert info == [""] assert proxy.connections[0].is_idle() assert proxy.connections[0].is_available() assert not proxy.connections[0].is_closed() # A connection on a tunneled proxy can only handle HTTPS requests to the same origin. assert not proxy.connections[0].can_handle_request(Origin(b"http", b"example.com", 80)) assert not proxy.connections[0].can_handle_request(Origin(b"http", b"other.com", 80)) assert proxy.connections[0].can_handle_request(Origin(b"https", b"example.com", 443)) assert not proxy.connections[0].can_handle_request(Origin(b"https", b"other.com", 443)) @pytest.mark.anyio async def test_proxy_tunneling_with_403() -> None: """ Send an HTTPS request via a proxy. """ network_backend = AsyncMockBackend( [ b"HTTP/1.1 403 Permission Denied\r\n\r\n", ] ) async with AsyncConnectionPool( proxy=Proxy("http://localhost:8080/"), network_backend=network_backend, ) as proxy: with pytest.raises(ProxyError) as exc_info: await proxy.request("GET", "https://example.com/") assert str(exc_info.value) == "403 Permission Denied" assert not proxy.connections @pytest.mark.anyio async def test_proxy_tunneling_with_auth() -> None: """ Send an authenticated HTTPS request via a proxy. """ network_backend = AsyncMockBackend( [ # The initial response to the proxy CONNECT b"HTTP/1.1 200 OK\r\n\r\n", # The actual response from the remote server b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) async with AsyncConnectionPool( proxy=Proxy( url="http://localhost:8080/", auth=("username", "password"), ), network_backend=network_backend, ) as proxy: response = await proxy.request("GET", "https://example.com/") assert response.status == 200 assert response.content == b"Hello, world!" def test_proxy_headers() -> None: proxy = Proxy( url="http://localhost:8080/", auth=("username", "password"), ) assert proxy.headers == [(b"Proxy-Authorization", b"Basic dXNlcm5hbWU6cGFzc3dvcmQ=")] @pytest.mark.anyio @pytest.mark.parametrize( "method, target, forwarding_target", [ ("GET", b"/custom^path", b"http://example.com/custom^path"), ("OPTIONS", b"*", b"*"), ("CONNECT", b"example.com:443", b"example.com:443"), ("GET", b"http://example.com/custom^path", b"http://example.com/custom^path"), ], ) async def test_proxy_forwarding_preserves_target_extension( method: str, target: bytes, forwarding_target: bytes ) -> None: events: dict[str, dict[str, typing.Any]] = {} async def trace(name: str, info: dict[str, typing.Any]) -> None: events[name] = info network_backend = AsyncMockBackend([b"HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n"]) extensions = {"target": target, "trace": trace} expected_extensions = extensions.copy() async with AsyncConnectionPool(proxy=Proxy("http://localhost:8080"), network_backend=network_backend) as pool: await pool.request(method, "http://example.com/", extensions=extensions) request = events["http11.send_request_headers.started"]["request"] assert request.url.target == forwarding_target assert extensions == expected_extensions @pytest.mark.anyio async def test_proxy_tunneling_preserves_target_extension() -> None: events: dict[str, list[dict[str, typing.Any]]] = {} async def trace(name: str, info: dict[str, typing.Any]) -> None: events.setdefault(name, []).append(info) network_backend = AsyncMockBackend( [ b"HTTP/1.1 200 Connection established\r\n\r\n", b"HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n", ] ) extensions = {"target": b"/custom^path", "trace": trace} expected_extensions = extensions.copy() async with AsyncConnectionPool(proxy=Proxy("http://localhost:8080"), network_backend=network_backend) as pool: await pool.request("GET", "https://example.com/", extensions=extensions) requests = [info["request"] for info in events["http11.send_request_headers.started"]] assert [(request.method, request.url.target) for request in requests] == [ (b"CONNECT", b"example.com:443"), (b"GET", b"/custom^path"), ] assert extensions == expected_extensions @pytest.mark.anyio async def test_proxy_forwarding_uses_proxy_tls_hostname() -> None: events: dict[str, dict[str, typing.Any]] = {} async def trace(name: str, info: dict[str, typing.Any]) -> None: events[name] = info network_backend = AsyncMockBackend([b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nOK"]) extensions = {"sni_hostname": "example.com", "trace": trace} expected_extensions = extensions.copy() async with AsyncConnectionPool(proxy=Proxy("https://localhost:8080"), network_backend=network_backend) as pool: await pool.request("GET", "http://192.0.2.1/", extensions=extensions) assert events["connection.start_tls.started"]["server_hostname"] == "localhost" assert extensions == expected_extensions @pytest.mark.anyio @pytest.mark.parametrize( "sni_extensions, expected_hostname", [({}, "192.0.2.1"), ({"sni_hostname": "example.com"}, "example.com")], ) async def test_proxy_tunneling_respects_sni_hostname(sni_extensions: dict[str, str], expected_hostname: str) -> None: events: dict[str, dict[str, typing.Any]] = {} async def trace(name: str, info: dict[str, typing.Any]) -> None: events[name] = info network_backend = AsyncMockBackend( [ b"HTTP/1.1 200 Connection established\r\n\r\n", b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nOK", ] ) extensions = {"trace": trace, **sni_extensions} expected_extensions = extensions.copy() async with AsyncConnectionPool(proxy=Proxy("https://localhost:8080"), network_backend=network_backend) as pool: await pool.request("GET", "https://192.0.2.1/", extensions=extensions) assert events["connection.start_tls.started"]["server_hostname"] == "localhost" assert events["proxy.start_tls.started"]["server_hostname"] == expected_hostname assert extensions == expected_extensions pydantic-httpx2-6dd59b9/tests/httpcore2/_async/test_integration.py000066400000000000000000000034251526547463400255140ustar00rootroot00000000000000import ssl import pytest from pytest_httpbin.serve import Server import httpcore2 @pytest.mark.anyio async def test_request(httpbin: Server) -> None: async with httpcore2.AsyncConnectionPool() as pool: response = await pool.request("GET", httpbin.url) assert response.status == 200 @pytest.mark.anyio async def test_ssl_request(httpbin_secure: Server) -> None: ssl_context = ssl.create_default_context() ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE async with httpcore2.AsyncConnectionPool(ssl_context=ssl_context) as pool: response = await pool.request("GET", httpbin_secure.url) assert response.status == 200 @pytest.mark.anyio async def test_extra_info(httpbin_secure: Server) -> None: ssl_context = ssl.create_default_context() ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE async with httpcore2.AsyncConnectionPool(ssl_context=ssl_context) as pool: async with pool.stream("GET", httpbin_secure.url) as response: assert response.status == 200 stream = response.extensions["network_stream"] ssl_object = stream.get_extra_info("ssl_object") assert ssl_object.version() == "TLSv1.3" local_addr = stream.get_extra_info("client_addr") assert local_addr[0] == "127.0.0.1" remote_addr = stream.get_extra_info("server_addr") assert f"https://{remote_addr[0]}:{remote_addr[1]}" == httpbin_secure.url sock = stream.get_extra_info("socket") assert hasattr(sock, "family") assert hasattr(sock, "type") invalid = stream.get_extra_info("invalid") assert invalid is None stream.get_extra_info("is_readable") pydantic-httpx2-6dd59b9/tests/httpcore2/_async/test_socks_proxy.py000066400000000000000000000147141526547463400255570ustar00rootroot00000000000000import pytest import httpcore2 @pytest.mark.anyio async def test_socks5_request() -> None: """ Send an HTTP request via a SOCKS proxy. """ network_backend = httpcore2.AsyncMockBackend( [ # The initial socks CONNECT # v5 NOAUTH b"\x05\x00", # v5 SUC RSV IP4 127 .0 .0 .1 :80 b"\x05\x00\x00\x01\xff\x00\x00\x01\x00\x50", # The actual response from the remote server b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) async with httpcore2.AsyncConnectionPool( proxy=httpcore2.Proxy("socks5://localhost:8080/"), network_backend=network_backend, ) as proxy: # Sending an initial request, which once complete will return to the pool, IDLE. async with proxy.stream("GET", "https://example.com/") as response: info = [repr(c) for c in proxy.connections] assert info == [""] await response.aread() assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in proxy.connections] assert info == [""] assert proxy.connections[0].is_idle() assert proxy.connections[0].is_available() assert not proxy.connections[0].is_closed() # A connection on a tunneled proxy can only handle HTTPS requests to the same origin. assert not proxy.connections[0].can_handle_request(httpcore2.Origin(b"http", b"example.com", 80)) assert not proxy.connections[0].can_handle_request(httpcore2.Origin(b"http", b"other.com", 80)) assert proxy.connections[0].can_handle_request(httpcore2.Origin(b"https", b"example.com", 443)) assert not proxy.connections[0].can_handle_request(httpcore2.Origin(b"https", b"other.com", 443)) @pytest.mark.anyio async def test_authenticated_socks5_request() -> None: """ Send an HTTP request via a SOCKS proxy. """ network_backend = httpcore2.AsyncMockBackend( [ # The initial socks CONNECT # v5 USERNAME/PASSWORD b"\x05\x02", # v1 VALID USERNAME/PASSWORD b"\x01\x00", # v5 SUC RSV IP4 127 .0 .0 .1 :80 b"\x05\x00\x00\x01\xff\x00\x00\x01\x00\x50", # The actual response from the remote server b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) async with httpcore2.AsyncConnectionPool( proxy=httpcore2.Proxy( url="socks5://localhost:8080/", auth=(b"username", b"password"), ), network_backend=network_backend, ) as proxy: # Sending an initial request, which once complete will return to the pool, IDLE. async with proxy.stream("GET", "https://example.com/") as response: info = [repr(c) for c in proxy.connections] assert info == [""] await response.aread() assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in proxy.connections] assert info == [""] assert proxy.connections[0].is_idle() assert proxy.connections[0].is_available() assert not proxy.connections[0].is_closed() @pytest.mark.anyio async def test_socks5_request_connect_failed() -> None: """ Attempt to send an HTTP request via a SOCKS proxy, resulting in a connect failure. """ network_backend = httpcore2.AsyncMockBackend( [ # The initial socks CONNECT # v5 NOAUTH b"\x05\x00", # v5 NO RSV IP4 0 .0 .0 .0 :00 b"\x05\x05\x00\x01\x00\x00\x00\x00\x00\x00", ] ) async with httpcore2.AsyncConnectionPool( proxy=httpcore2.Proxy("socks5://localhost:8080/"), network_backend=network_backend, ) as proxy: # Sending a request, which the proxy rejects with pytest.raises(httpcore2.ProxyError) as exc_info: await proxy.request("GET", "https://example.com/") assert str(exc_info.value) == "Proxy Server could not connect: Connection refused." assert not proxy.connections @pytest.mark.anyio async def test_socks5_request_failed_to_provide_auth() -> None: """ Attempt to send an HTTP request via an authenticated SOCKS proxy, without providing authentication credentials. """ network_backend = httpcore2.AsyncMockBackend( [ # v5 USERNAME/PASSWORD b"\x05\x02", ] ) async with httpcore2.AsyncConnectionPool( proxy=httpcore2.Proxy("socks5://localhost:8080/"), network_backend=network_backend, ) as proxy: # Sending a request, which the proxy rejects with pytest.raises(httpcore2.ProxyError) as exc_info: await proxy.request("GET", "https://example.com/") assert ( str(exc_info.value) == "Requested NO AUTHENTICATION REQUIRED from proxy server, but got USERNAME/PASSWORD." ) assert not proxy.connections @pytest.mark.anyio async def test_socks5_request_incorrect_auth() -> None: """ Attempt to send an HTTP request via an authenticated SOCKS proxy, with incorrect authentication credentials. """ network_backend = httpcore2.AsyncMockBackend( [ # v5 USERNAME/PASSWORD b"\x05\x02", # v1 INVALID USERNAME/PASSWORD b"\x01\x01", ] ) async with httpcore2.AsyncConnectionPool( proxy=httpcore2.Proxy( url="socks5://localhost:8080/", auth=(b"invalid", b"invalid"), ), network_backend=network_backend, ) as proxy: # Sending a request, which the proxy rejects with pytest.raises(httpcore2.ProxyError) as exc_info: await proxy.request("GET", "https://example.com/") assert str(exc_info.value) == "Invalid username/password" assert not proxy.connections pydantic-httpx2-6dd59b9/tests/httpcore2/_sync/000077500000000000000000000000001526547463400214135ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/tests/httpcore2/_sync/__init__.py000066400000000000000000000000001526547463400235120ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/tests/httpcore2/_sync/test_connection.py000066400000000000000000000267641526547463400252020ustar00rootroot00000000000000import ssl import typing import hpack import hyperframe.frame import pytest from httpcore2 import ( SOCKET_OPTION, HTTPConnection, MockBackend, MockStream, NetworkStream, ConnectError, ConnectionNotAvailable, Origin, RemoteProtocolError, WriteError, ) def test_http_connection() -> None: origin = Origin(b"https", b"example.com", 443) network_backend = MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) with HTTPConnection(origin=origin, network_backend=network_backend, keepalive_expiry=5.0) as conn: assert not conn.is_idle() assert not conn.is_closed() assert not conn.is_available() assert not conn.has_expired() assert not conn.is_connected() assert repr(conn) == "" with conn.stream("GET", "https://example.com/") as response: assert repr(conn) == "" response.read() assert response.status == 200 assert response.content == b"Hello, world!" assert conn.is_idle() assert not conn.is_closed() assert conn.is_available() assert not conn.has_expired() assert conn.is_connected() assert repr(conn) == "" def test_concurrent_requests_not_available_on_http11_connections() -> None: """ Attempting to issue a request against an already active HTTP/1.1 connection will raise a `ConnectionNotAvailable` exception. """ origin = Origin(b"https", b"example.com", 443) network_backend = MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) with HTTPConnection(origin=origin, network_backend=network_backend, keepalive_expiry=5.0) as conn: with conn.stream("GET", "https://example.com/"): with pytest.raises(ConnectionNotAvailable): conn.request("GET", "https://example.com/") @pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning") def test_write_error_with_response_sent() -> None: """ If a server half-closes the connection while the client is sending the request, it may still send a response. In this case the client should successfully read and return the response. See also the `test_write_error_without_response_sent` test above. """ class ErrorOnRequestTooLargeStream(MockStream): def __init__(self, buffer: list[bytes], http2: bool = False) -> None: super().__init__(buffer, http2) self.count = 0 def write(self, buffer: bytes, timeout: float | None = None) -> None: self.count += len(buffer) if self.count > 1_000_000: raise WriteError() class ErrorOnRequestTooLarge(MockBackend): def connect_tcp( self, host: str, port: int, timeout: float | None = None, local_address: str | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> MockStream: return ErrorOnRequestTooLargeStream(list(self._buffer), http2=self._http2) origin = Origin(b"https", b"example.com", 443) network_backend = ErrorOnRequestTooLarge( [ b"HTTP/1.1 413 Payload Too Large\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 37\r\n", b"\r\n", b"Request body exceeded 1,000,000 bytes", ] ) with HTTPConnection(origin=origin, network_backend=network_backend, keepalive_expiry=5.0) as conn: content = b"x" * 10_000_000 response = conn.request("POST", "https://example.com/", content=content) assert response.status == 413 assert response.content == b"Request body exceeded 1,000,000 bytes" @pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning") def test_write_error_without_response_sent() -> None: """ If a server fully closes the connection while the client is sending the request, then client should raise an error. See also the `test_write_error_with_response_sent` test above. """ class ErrorOnRequestTooLargeStream(MockStream): def __init__(self, buffer: list[bytes], http2: bool = False) -> None: super().__init__(buffer, http2) self.count = 0 def write(self, buffer: bytes, timeout: float | None = None) -> None: self.count += len(buffer) if self.count > 1_000_000: raise WriteError() class ErrorOnRequestTooLarge(MockBackend): def connect_tcp( self, host: str, port: int, timeout: float | None = None, local_address: str | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> MockStream: return ErrorOnRequestTooLargeStream(list(self._buffer), http2=self._http2) origin = Origin(b"https", b"example.com", 443) network_backend = ErrorOnRequestTooLarge([]) with HTTPConnection(origin=origin, network_backend=network_backend, keepalive_expiry=5.0) as conn: content = b"x" * 10_000_000 with pytest.raises(RemoteProtocolError) as exc_info: conn.request("POST", "https://example.com/", content=content) assert str(exc_info.value) == "Server disconnected without sending a response." @pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning") def test_http2_connection() -> None: origin = Origin(b"https", b"example.com", 443) network_backend = MockBackend( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), ], http2=True, ) with HTTPConnection(origin=origin, network_backend=network_backend, http2=True) as conn: response = conn.request("GET", "https://example.com/") assert response.status == 200 assert response.content == b"Hello, world!" assert response.extensions["http_version"] == b"HTTP/2" def test_request_to_incorrect_origin() -> None: """ A connection can only send requests whichever origin it is connected to. """ origin = Origin(b"https", b"example.com", 443) network_backend = MockBackend([]) with HTTPConnection(origin=origin, network_backend=network_backend) as conn: with pytest.raises(RuntimeError): conn.request("GET", "https://other.com/") class NeedsRetryBackend(MockBackend): def __init__( self, buffer: list[bytes], http2: bool = False, connect_tcp_failures: int = 2, start_tls_failures: int = 0, ) -> None: self._connect_tcp_failures = connect_tcp_failures self._start_tls_failures = start_tls_failures super().__init__(buffer, http2) def connect_tcp( self, host: str, port: int, timeout: float | None = None, local_address: str | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> NetworkStream: if self._connect_tcp_failures > 0: self._connect_tcp_failures -= 1 raise ConnectError() stream = super().connect_tcp(host, port, timeout=timeout, local_address=local_address) return self._NeedsRetryAsyncNetworkStream(self, stream) class _NeedsRetryAsyncNetworkStream(NetworkStream): def __init__(self, backend: "NeedsRetryBackend", stream: NetworkStream) -> None: self._backend = backend self._stream = stream def read(self, max_bytes: int, timeout: float | None = None) -> bytes: return self._stream.read(max_bytes, timeout) def write(self, buffer: bytes, timeout: float | None = None) -> None: self._stream.write(buffer, timeout) def close(self) -> None: self._stream.close() def start_tls( self, ssl_context: ssl.SSLContext, server_hostname: str | None = None, timeout: float | None = None, ) -> "NetworkStream": if self._backend._start_tls_failures > 0: self._backend._start_tls_failures -= 1 raise ConnectError() stream = self._stream.start_tls(ssl_context, server_hostname, timeout) return self._backend._NeedsRetryAsyncNetworkStream(self._backend, stream) def get_extra_info(self, info: str) -> typing.Any: return self._stream.get_extra_info(info) def test_connection_retries() -> None: origin = Origin(b"https", b"example.com", 443) content = [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] network_backend = NeedsRetryBackend(content) with HTTPConnection(origin=origin, network_backend=network_backend, retries=3) as conn: response = conn.request("GET", "https://example.com/") assert response.status == 200 network_backend = NeedsRetryBackend(content) with HTTPConnection( origin=origin, network_backend=network_backend, ) as conn: with pytest.raises(ConnectError): conn.request("GET", "https://example.com/") def test_connection_retries_tls() -> None: origin = Origin(b"https", b"example.com", 443) content = [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] network_backend = NeedsRetryBackend(content, connect_tcp_failures=0, start_tls_failures=2) with HTTPConnection(origin=origin, network_backend=network_backend, retries=3) as conn: response = conn.request("GET", "https://example.com/") assert response.status == 200 network_backend = NeedsRetryBackend(content, connect_tcp_failures=0, start_tls_failures=2) with HTTPConnection( origin=origin, network_backend=network_backend, ) as conn: with pytest.raises(ConnectError): conn.request("GET", "https://example.com/") def test_uds_connections() -> None: # We're not actually testing Unix Domain Sockets here, because we're just # using a mock backend, but at least we're covering the UDS codepath # in `connection.py` which we may as well do. origin = Origin(b"https", b"example.com", 443) network_backend = MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) with HTTPConnection(origin=origin, network_backend=network_backend, uds="/mock/example") as conn: response = conn.request("GET", "https://example.com/") assert response.status == 200 pydantic-httpx2-6dd59b9/tests/httpcore2/_sync/test_connection_pool.py000066400000000000000000001014731526547463400262220ustar00rootroot00000000000000import logging import typing import hpack import hyperframe.frame import pytest from tests.httpcore2 import concurrency import httpcore2 def test_connection_pool_with_keepalive() -> None: """ By default HTTP/1.1 requests should be returned to the connection pool. """ network_backend = httpcore2.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) with httpcore2.ConnectionPool(network_backend=network_backend, max_keepalive_connections=1) as pool: # Sending an initial request, which once complete will return to the pool, IDLE. with pool.stream("GET", "https://example.com/") as response: info = [repr(c) for c in pool.connections] assert info == [""] assert repr(pool) == "" response.read() assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in pool.connections] assert info == [""] assert repr(pool) == "" # Sending a second request to the same origin will reuse the existing IDLE connection. with pool.stream("GET", "https://example.com/") as response: info = [repr(c) for c in pool.connections] assert info == [""] assert repr(pool) == "" response.read() assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in pool.connections] assert info == [""] assert repr(pool) == "" # Sending a request to a different origin will not reuse the existing IDLE connection. with ( pool.stream("GET", "http://example.com/") as response_1, pool.stream("GET", "http://example.com/") as response_2, ): info = [repr(c) for c in pool.connections] assert info == [ "", "", "", ] assert repr(pool) == "" response_1.read() response_2.read() assert response_1.status == 200 assert response_1.content == b"Hello, world!" assert response_2.status == 200 assert response_2.content == b"Hello, world!" info = [repr(c) for c in pool.connections] assert info == [ "", ] assert repr(pool) == "" def test_connection_pool_with_close() -> None: """ HTTP/1.1 requests that include a 'Connection: Close' header should not be returned to the connection pool. """ network_backend = httpcore2.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) with httpcore2.ConnectionPool(network_backend=network_backend) as pool: # Sending an initial request, which once complete will not return to the pool. with pool.stream("GET", "https://example.com/", headers={"Connection": "close"}) as response: info = [repr(c) for c in pool.connections] assert info == [""] response.read() assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in pool.connections] assert info == [] def test_connection_pool_with_http2() -> None: """ Test a connection pool with HTTP/2 requests. """ network_backend = httpcore2.MockBackend( buffer=[ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), hyperframe.frame.HeadersFrame( stream_id=3, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=3, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), ], http2=True, ) with httpcore2.ConnectionPool( network_backend=network_backend, ) as pool: # Sending an initial request, which once complete will return to the pool, IDLE. response = pool.request("GET", "https://example.com/") assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in pool.connections] assert info == [""] # Sending a second request to the same origin will reuse the existing IDLE connection. response = pool.request("GET", "https://example.com/") assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in pool.connections] assert info == [""] def test_connection_pool_with_http2_goaway() -> None: """ Test a connection pool with HTTP/2 requests, that cleanly disconnects with a GoAway frame after the first request. """ network_backend = httpcore2.MockBackend( buffer=[ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), hyperframe.frame.GoAwayFrame(stream_id=0, error_code=0, last_stream_id=1).serialize(), b"", ], http2=True, ) with httpcore2.ConnectionPool( network_backend=network_backend, ) as pool: # Sending an initial request, which once complete will return to the pool, IDLE. response = pool.request("GET", "https://example.com/") assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in pool.connections] assert info == [""] # Sending a second request to the same origin will require a new connection. # The original connection has now been closed. response = pool.request("GET", "https://example.com/") assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in pool.connections] assert info == [ "", ] def test_trace_request() -> None: """ The 'trace' request extension allows for a callback function to inspect the internal events that occur while sending a request. """ network_backend = httpcore2.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) called: list[str] = [] def trace(name: str, kwargs: dict[str, typing.Any]) -> None: called.append(name) with httpcore2.ConnectionPool(network_backend=network_backend) as pool: pool.request("GET", "https://example.com/", extensions={"trace": trace}) assert called == [ "connection.connect_tcp.started", "connection.connect_tcp.complete", "connection.start_tls.started", "connection.start_tls.complete", "http11.send_request_headers.started", "http11.send_request_headers.complete", "http11.send_request_body.started", "http11.send_request_body.complete", "http11.receive_response_headers.started", "http11.receive_response_headers.complete", "http11.receive_response_body.started", "http11.receive_response_body.complete", "http11.response_closed.started", "http11.response_closed.complete", ] def test_debug_request(caplog: pytest.LogCaptureFixture) -> None: """ The 'trace' request extension allows for a callback function to inspect the internal events that occur while sending a request. """ caplog.set_level(logging.DEBUG) network_backend = httpcore2.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) with httpcore2.ConnectionPool(network_backend=network_backend) as pool: pool.request("GET", "http://example.com/") assert caplog.record_tuples == [ ( "httpcore2.connection", logging.DEBUG, "connect_tcp.started host='example.com' port=80 local_address=None timeout=None socket_options=None", ), ( "httpcore2.connection", logging.DEBUG, "connect_tcp.complete return_value=", ), ( "httpcore2.http11", logging.DEBUG, "send_request_headers.started request=", ), ("httpcore2.http11", logging.DEBUG, "send_request_headers.complete"), ( "httpcore2.http11", logging.DEBUG, "send_request_body.started request=", ), ("httpcore2.http11", logging.DEBUG, "send_request_body.complete"), ( "httpcore2.http11", logging.DEBUG, "receive_response_headers.started request=", ), ( "httpcore2.http11", logging.DEBUG, "receive_response_headers.complete return_value=" "(b'HTTP/1.1', 200, b'OK', [(b'Content-Type', b'plain/text'), (b'Content-Length', b'13')])", ), ( "httpcore2.http11", logging.DEBUG, "receive_response_body.started request=", ), ("httpcore2.http11", logging.DEBUG, "receive_response_body.complete"), ("httpcore2.http11", logging.DEBUG, "response_closed.started"), ("httpcore2.http11", logging.DEBUG, "response_closed.complete"), ("httpcore2.connection", logging.DEBUG, "close.started"), ("httpcore2.connection", logging.DEBUG, "close.complete"), ] def test_connection_pool_with_http_exception() -> None: """ HTTP/1.1 requests that result in an exception during the connection should not be returned to the connection pool. """ network_backend = httpcore2.MockBackend([b"Wait, this isn't valid HTTP!"]) called: list[str] = [] def trace(name: str, kwargs: dict[str, typing.Any]) -> None: called.append(name) with httpcore2.ConnectionPool(network_backend=network_backend) as pool: # Sending an initial request, which once complete will not return to the pool. with pytest.raises(httpcore2.RemoteProtocolError): pool.request("GET", "https://example.com/", extensions={"trace": trace}) info = [repr(c) for c in pool.connections] assert info == [] assert called == [ "connection.connect_tcp.started", "connection.connect_tcp.complete", "connection.start_tls.started", "connection.start_tls.complete", "http11.send_request_headers.started", "http11.send_request_headers.complete", "http11.send_request_body.started", "http11.send_request_body.complete", "http11.receive_response_headers.started", "http11.receive_response_headers.failed", "http11.response_closed.started", "http11.response_closed.complete", ] def test_connection_pool_with_connect_exception() -> None: """ HTTP/1.1 requests that result in an exception during connection should not be returned to the connection pool. """ class FailedConnectBackend(httpcore2.MockBackend): def connect_tcp( self, host: str, port: int, timeout: float | None = None, local_address: str | None = None, socket_options: typing.Iterable[httpcore2.SOCKET_OPTION] | None = None, ) -> httpcore2.NetworkStream: raise httpcore2.ConnectError("Could not connect") network_backend = FailedConnectBackend([]) called: list[str] = [] def trace(name: str, kwargs: dict[str, typing.Any]) -> None: called.append(name) with httpcore2.ConnectionPool(network_backend=network_backend) as pool: # Sending an initial request, which once complete will not return to the pool. with pytest.raises(httpcore2.ConnectError): pool.request("GET", "https://example.com/", extensions={"trace": trace}) info = [repr(c) for c in pool.connections] assert info == [] assert called == [ "connection.connect_tcp.started", "connection.connect_tcp.failed", ] def test_connection_pool_with_immediate_expiry() -> None: """ Connection pools with keepalive_expiry=0.0 should immediately expire keep alive connections. """ network_backend = httpcore2.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) with httpcore2.ConnectionPool( keepalive_expiry=0.0, network_backend=network_backend, ) as pool: # Sending an initial request, which once complete will not return to the pool. with pool.stream("GET", "https://example.com/") as response: info = [repr(c) for c in pool.connections] assert info == [""] response.read() assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in pool.connections] assert info == [] def test_connection_pool_with_no_keepalive_connections_allowed() -> None: """ When 'max_keepalive_connections=0' is used, IDLE connections should not be returned to the pool. """ network_backend = httpcore2.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) with httpcore2.ConnectionPool(max_keepalive_connections=0, network_backend=network_backend) as pool: # Sending an initial request, which once complete will not return to the pool. with pool.stream("GET", "https://example.com/") as response: info = [repr(c) for c in pool.connections] assert info == [""] response.read() assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in pool.connections] assert info == [] def test_connection_pool_closes_idle_connection_for_different_origin() -> None: """ When the pool is at 'max_connections' and an incoming request is for an origin with no reusable connection, an IDLE connection to a different origin is closed to make room for the new connection. """ network_backend = httpcore2.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) with httpcore2.ConnectionPool(network_backend=network_backend, max_connections=1) as pool: # An initial request to a.com leaves a single IDLE connection in the pool. response = pool.request("GET", "https://a.com/") assert response.status == 200 info = [repr(c) for c in pool.connections] assert info == [""] # A request to b.com cannot reuse the a.com connection and the pool is full, # so the IDLE a.com connection is closed and replaced with a b.com connection. response = pool.request("GET", "https://b.com/") assert response.status == 200 info = [repr(c) for c in pool.connections] assert info == [""] def test_connection_pool_concurrency() -> None: """ HTTP/1.1 requests made in concurrency must not ever exceed the maximum number of allowable connection in the pool. """ network_backend = httpcore2.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) def fetch(pool: httpcore2.ConnectionPool, domain: str, info_list: list[list[str]]) -> None: with pool.stream("GET", f"http://{domain}/") as response: info = [repr(c) for c in pool.connections] info_list.append(info) response.read() with httpcore2.ConnectionPool(max_connections=1, network_backend=network_backend) as pool: info_list: list[list[str]] = [] with concurrency.open_nursery() as nursery: for domain in ["a.com", "b.com", "c.com", "d.com", "e.com"]: nursery.start_soon(fetch, pool, domain, info_list) for item in info_list: # Check that each time we inspected the connection pool, only a # single connection was established at any one time. assert len(item) == 1 # Each connection was to a different host, and only sent a single # request on that connection. assert item[0] in [ "", "", "", "", "", ] def test_connection_pool_concurrency_same_domain_closing() -> None: """ HTTP/1.1 requests made in concurrency must not ever exceed the maximum number of allowable connection in the pool. """ network_backend = httpcore2.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"Connection: close\r\n", b"\r\n", b"Hello, world!", ] ) def fetch(pool: httpcore2.ConnectionPool, domain: str, info_list: list[list[str]]) -> None: with pool.stream("GET", f"https://{domain}/") as response: info = [repr(c) for c in pool.connections] info_list.append(info) response.read() with httpcore2.ConnectionPool(max_connections=1, network_backend=network_backend, http2=True) as pool: info_list: list[list[str]] = [] with concurrency.open_nursery() as nursery: for domain in ["a.com", "a.com", "a.com", "a.com", "a.com"]: nursery.start_soon(fetch, pool, domain, info_list) for item in info_list: # Check that each time we inspected the connection pool, only a # single connection was established at any one time. assert len(item) == 1 # Only a single request was sent on each connection. assert item[0] == "" def test_connection_pool_concurrency_same_domain_keepalive() -> None: """ HTTP/1.1 requests made in concurrency must not ever exceed the maximum number of allowable connection in the pool. """ network_backend = httpcore2.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] * 5 ) def fetch(pool: httpcore2.ConnectionPool, domain: str, info_list: list[list[str]]) -> None: with pool.stream("GET", f"https://{domain}/") as response: info = [repr(c) for c in pool.connections] info_list.append(info) response.read() with httpcore2.ConnectionPool(max_connections=1, network_backend=network_backend, http2=True) as pool: info_list: list[list[str]] = [] with concurrency.open_nursery() as nursery: for domain in ["a.com", "a.com", "a.com", "a.com", "a.com"]: nursery.start_soon(fetch, pool, domain, info_list) for item in info_list: # Check that each time we inspected the connection pool, only a # single connection was established at any one time. assert len(item) == 1 # The connection sent multiple requests. assert item[0] in [ "", "", "", "", "", ] assert repr(pool) == "" def test_unsupported_protocol() -> None: with httpcore2.ConnectionPool() as pool: with pytest.raises(httpcore2.UnsupportedProtocol): pool.request("GET", "ftp://www.example.com/") with pytest.raises(httpcore2.UnsupportedProtocol): pool.request("GET", "://www.example.com/") def test_connection_pool_closed_while_request_in_flight() -> None: """ Closing a connection pool while a request/response is still in-flight should raise an error. """ network_backend = httpcore2.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) with httpcore2.ConnectionPool( network_backend=network_backend, ) as pool: # Send a request, and then close the connection pool while the # response has not yet been streamed. with pool.stream("GET", "https://example.com/") as response: pool.close() with pytest.raises(httpcore2.ReadError): response.read() def test_connection_pool_timeout() -> None: """ Ensure that exceeding max_connections can cause a request to timeout. """ network_backend = httpcore2.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) with httpcore2.ConnectionPool(network_backend=network_backend, max_connections=1) as pool: # Send a request to a pool that is configured to only support a single # connection, and then ensure that a second concurrent request # fails with a timeout. with pool.stream("GET", "https://example.com/"): with pytest.raises(httpcore2.PoolTimeout): extensions = {"timeout": {"pool": 0.0001}} pool.request("GET", "https://example.com/", extensions=extensions) def test_connection_pool_timeout_zero() -> None: """ A pool timeout of 0 shouldn't raise a PoolTimeout if there's no need to wait on a new connection. """ network_backend = httpcore2.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) # Use a pool timeout of zero. extensions = {"timeout": {"pool": 0}} # A connection pool configured to allow only one connection at a time. with httpcore2.ConnectionPool(network_backend=network_backend, max_connections=1) as pool: # Two consecutive requests with a pool timeout of zero. # Both succeed without raising a timeout. response = pool.request("GET", "https://example.com/", extensions=extensions) assert response.status == 200 assert response.content == b"Hello, world!" response = pool.request("GET", "https://example.com/", extensions=extensions) assert response.status == 200 assert response.content == b"Hello, world!" # A connection pool configured to allow only one connection at a time. with httpcore2.ConnectionPool(network_backend=network_backend, max_connections=1) as pool: # Two concurrent requests with a pool timeout of zero. # Only the first will succeed without raising a timeout. with pool.stream("GET", "https://example.com/", extensions=extensions) as response: # The first response hasn't yet completed. with pytest.raises(httpcore2.PoolTimeout): # So a pool timeout occurs. pool.request("GET", "https://example.com/", extensions=extensions) # The first response now completes. response.read() assert response.status == 200 assert response.content == b"Hello, world!" def test_http11_upgrade_connection() -> None: """ HTTP "101 Switching Protocols" indicates an upgraded connection. We should return the response, so that the network stream may be used for the upgraded connection. https://httpwg.org/specs/rfc9110.html#status.101 https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/101 """ network_backend = httpcore2.MockBackend( [ b"HTTP/1.1 101 Switching Protocols\r\n", b"Connection: upgrade\r\n", b"Upgrade: custom\r\n", b"\r\n", b"...", ] ) called: list[str] = [] def trace(name: str, kwargs: dict[str, typing.Any]) -> None: called.append(name) with httpcore2.ConnectionPool(network_backend=network_backend, max_connections=1) as pool: with pool.stream( "GET", "wss://example.com/", headers={"Connection": "upgrade", "Upgrade": "custom"}, extensions={"trace": trace}, ) as response: assert response.status == 101 network_stream = response.extensions["network_stream"] content = network_stream.read(max_bytes=1024) assert content == b"..." assert called == [ "connection.connect_tcp.started", "connection.connect_tcp.complete", "connection.start_tls.started", "connection.start_tls.complete", "http11.send_request_headers.started", "http11.send_request_headers.complete", "http11.send_request_body.started", "http11.send_request_body.complete", "http11.receive_response_headers.started", "http11.receive_response_headers.complete", "http11.response_closed.started", "http11.response_closed.complete", ] def test_connection_pool_assigns_released_connection_to_one_queued_request() -> None: """ A released connection must be handed to exactly one queued request. Assigning it to every queued request wakes them all, only for all but one to fail with `ConnectionNotAvailable` and re-enter the queue, degrading quadratically with queue depth. """ class CountingPool(httpcore2.ConnectionPool): assign_passes = 0 def _assign_requests_to_connections(self) -> list[httpcore2.ConnectionInterface]: CountingPool.assign_passes += 1 return super()._assign_requests_to_connections() network_backend = httpcore2.MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] * 10 ) def fetch(pool: httpcore2.ConnectionPool) -> None: with pool.stream("GET", "https://example.com/") as response: response.read() assert response.status == 200 with CountingPool(max_connections=1, network_backend=network_backend) as pool: with concurrency.open_nursery() as nursery: for _ in range(10): nursery.start_soon(fetch, pool) # Exactly two passes per request: one when it is queued, one when it # releases its connection. assert CountingPool.assign_passes == 2 * 10 def test_connection_pool_multiplexes_idle_http2_connection_within_a_pass() -> None: """ A burst of requests arriving while a warmed HTTP/2 connection is idle must be assigned to it immediately, not serialized behind the first request's reservation. """ class QueueObservingPool(httpcore2.ConnectionPool): max_queued_after_pass = 0 def _assign_requests_to_connections(self) -> list[httpcore2.ConnectionInterface]: closing = super()._assign_requests_to_connections() queued = sum(request.is_queued() for request in self._requests) QueueObservingPool.max_queued_after_pass = max(QueueObservingPool.max_queued_after_pass, queued) return closing def response_frames(stream_id: int) -> list[bytes]: return [ hyperframe.frame.HeadersFrame( stream_id=stream_id, data=hpack.Encoder().encode([(b":status", b"200")]), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=stream_id, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), ] network_backend = httpcore2.MockBackend( buffer=[ hyperframe.frame.SettingsFrame().serialize(), *response_frames(1), *response_frames(3), *response_frames(5), *response_frames(7), ], http2=True, ) def fetch(pool: httpcore2.ConnectionPool) -> None: response = pool.request("GET", "https://example.com/") assert response.status == 200 with QueueObservingPool(network_backend=network_backend, max_connections=1, http2=True) as pool: # Warm the connection; it returns to the pool IDLE. fetch(pool) with concurrency.open_nursery() as nursery: for _ in range(3): nursery.start_soon(fetch, pool) assert QueueObservingPool.max_queued_after_pass == 0 pydantic-httpx2-6dd59b9/tests/httpcore2/_sync/test_http11.py000066400000000000000000000274641526547463400241620ustar00rootroot00000000000000import pytest import httpcore2 def test_http11_connection() -> None: origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.MockStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) with httpcore2.HTTP11Connection(origin=origin, stream=stream, keepalive_expiry=5.0) as conn: response = conn.request("GET", "https://example.com/") assert response.status == 200 assert response.content == b"Hello, world!" assert conn.is_idle() assert not conn.is_closed() assert conn.is_available() assert not conn.has_expired() assert conn.is_connected() assert repr(conn) == "" def test_http11_connection_unread_response() -> None: """ If the client releases the response without reading it to termination, then the connection will not be reusable. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.MockStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) with httpcore2.HTTP11Connection(origin=origin, stream=stream) as conn: with conn.stream("GET", "https://example.com/") as response: assert response.status == 200 assert not conn.is_idle() assert conn.is_closed() assert not conn.is_available() assert not conn.has_expired() assert repr(conn) == "" def test_http11_connection_with_remote_protocol_error() -> None: """ If a remote protocol error occurs, then no response will be returned, and the connection will not be reusable. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.MockStream([b"Wait, this isn't valid HTTP!", b""]) with httpcore2.HTTP11Connection(origin=origin, stream=stream) as conn: with pytest.raises(httpcore2.RemoteProtocolError): conn.request("GET", "https://example.com/") assert not conn.is_idle() assert conn.is_closed() assert not conn.is_available() assert not conn.has_expired() assert repr(conn) == "" def test_http11_connection_with_incomplete_response() -> None: """ We should be gracefully handling the case where the connection ends prematurely. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.MockStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, wor", ] ) with httpcore2.HTTP11Connection(origin=origin, stream=stream) as conn: with pytest.raises(httpcore2.RemoteProtocolError): conn.request("GET", "https://example.com/") assert not conn.is_idle() assert conn.is_closed() assert not conn.is_available() assert not conn.has_expired() assert repr(conn) == "" def test_http11_connection_with_local_protocol_error() -> None: """ If a local protocol error occurs, then no response will be returned, and the connection will not be reusable. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.MockStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) with httpcore2.HTTP11Connection(origin=origin, stream=stream) as conn: with pytest.raises(httpcore2.LocalProtocolError) as exc_info: conn.request("GET", "https://example.com/", headers={"Host": "\0"}) assert str(exc_info.value) == "Illegal header value b'\\x00'" assert not conn.is_idle() assert conn.is_closed() assert not conn.is_available() assert not conn.has_expired() assert repr(conn) == "" def test_http11_connection_handles_one_active_request() -> None: """ Attempting to send a request while one is already in-flight will raise a ConnectionNotAvailable exception. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.MockStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) with httpcore2.HTTP11Connection(origin=origin, stream=stream) as conn: with conn.stream("GET", "https://example.com/"): with pytest.raises(httpcore2.ConnectionNotAvailable): conn.request("GET", "https://example.com/") def test_http11_connection_attempt_close() -> None: """ A connection can only be closed when it is idle. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.MockStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) with httpcore2.HTTP11Connection(origin=origin, stream=stream) as conn: with conn.stream("GET", "https://example.com/") as response: response.read() assert response.status == 200 assert response.content == b"Hello, world!" def test_http11_request_to_incorrect_origin() -> None: """ A connection can only send requests to whichever origin it is connected to. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.MockStream([]) with httpcore2.HTTP11Connection(origin=origin, stream=stream) as conn: with pytest.raises(RuntimeError): conn.request("GET", "https://other.com/") def test_http11_expect_continue() -> None: """ HTTP "100 Continue" is an interim response. We simply ignore it and return the final response. https://httpwg.org/specs/rfc9110.html#status.100 https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/100 """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.MockStream( [ b"HTTP/1.1 100 Continue\r\n", b"\r\n", b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) with httpcore2.HTTP11Connection(origin=origin, stream=stream, keepalive_expiry=5.0) as conn: response = conn.request( "GET", "https://example.com/", headers={"Expect": "continue"}, ) assert response.status == 200 assert response.content == b"Hello, world!" def test_http11_upgrade_connection() -> None: """ HTTP "101 Switching Protocols" indicates an upgraded connection. We should return the response, so that the network stream may be used for the upgraded connection. https://httpwg.org/specs/rfc9110.html#status.101 https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/101 """ origin = httpcore2.Origin(b"wss", b"example.com", 443) stream = httpcore2.MockStream( [ b"HTTP/1.1 101 Switching Protocols\r\n", b"Connection: upgrade\r\n", b"Upgrade: custom\r\n", b"\r\n", b"...", ] ) with httpcore2.HTTP11Connection(origin=origin, stream=stream, keepalive_expiry=5.0) as conn: with conn.stream( "GET", "wss://example.com/", headers={"Connection": "upgrade", "Upgrade": "custom"}, ) as response: assert response.status == 101 network_stream = response.extensions["network_stream"] content = network_stream.read(max_bytes=1024) assert content == b"..." def test_http11_upgrade_with_trailing_data() -> None: """ HTTP "101 Switching Protocols" indicates an upgraded connection. In `CONNECT` and `Upgrade:` requests, we need to handover the trailing data in the h11.Connection object. https://h11.readthedocs.io/en/latest/api.html#switching-protocols """ origin = httpcore2.Origin(b"wss", b"example.com", 443) stream = httpcore2.MockStream( # The first element of this mock network stream buffer simulates networking # in which response headers and data are received at once. # This means that "foobar" becomes trailing data. [ (b"HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nUpgrade: custom\r\n\r\nfoobar"), b"baz", ] ) with httpcore2.HTTP11Connection(origin=origin, stream=stream, keepalive_expiry=5.0) as conn: with conn.stream( "GET", "wss://example.com/", headers={"Connection": "upgrade", "Upgrade": "custom"}, ) as response: assert response.status == 101 network_stream = response.extensions["network_stream"] content = network_stream.read(max_bytes=3) assert content == b"foo" content = network_stream.read(max_bytes=3) assert content == b"bar" content = network_stream.read(max_bytes=3) assert content == b"baz" # Lazy tests for HTTP11UpgradeStream network_stream.write(b"spam") invalid = network_stream.get_extra_info("invalid") assert invalid is None network_stream.close() def test_http11_early_hints() -> None: """ HTTP "103 Early Hints" is an interim response. We simply ignore it and return the final response. https://datatracker.ietf.org/doc/rfc8297/ """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.MockStream( [ b"HTTP/1.1 103 Early Hints\r\n", b"Link: ; rel=preload; as=style\r\n", b"Link: ; rel=preload; as=style\r\n", b"\r\n", b"HTTP/1.1 200 OK\r\n", b"Content-Type: text/html; charset=utf-8\r\n", b"Content-Length: 30\r\n", b"Link: ; rel=preload; as=style\r\n", b"Link: ; rel=preload; as=script\r\n", b"\r\n", b"Hello, world! ...", ] ) with httpcore2.HTTP11Connection(origin=origin, stream=stream, keepalive_expiry=5.0) as conn: response = conn.request( "GET", "https://example.com/", headers={"Expect": "continue"}, ) assert response.status == 200 assert response.content == b"Hello, world! ..." def test_http11_header_sub_100kb() -> None: """ A connection should be able to handle a http header size up to 100kB. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.MockStream( [ b"HTTP/1.1 200 OK\r\n", # 17 b"Content-Type: plain/text\r\n", # 43 b"Cookie: " + b"x" * (100 * 1024 - 72) + b"\r\n", # 102381 b"Content-Length: 0\r\n", # 102400 b"\r\n", b"", ] ) with httpcore2.HTTP11Connection(origin=origin, stream=stream, keepalive_expiry=5.0) as conn: response = conn.request("GET", "https://example.com/") assert response.status == 200 assert response.content == b"" pydantic-httpx2-6dd59b9/tests/httpcore2/_sync/test_http2.py000066400000000000000000000446441526547463400241010ustar00rootroot00000000000000import hpack import hyperframe.frame import pytest import httpcore2 def test_http2_connection() -> None: origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.MockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), ] ) with httpcore2.HTTP2Connection(origin=origin, stream=stream, keepalive_expiry=5.0) as conn: response = conn.request("GET", "https://example.com/") assert response.status == 200 assert response.content == b"Hello, world!" assert conn.is_idle() assert conn.is_available() assert not conn.is_closed() assert not conn.has_expired() assert conn.is_connected() assert conn.info() == "'https://example.com:443', HTTP/2, IDLE, Request Count: 1" assert repr(conn) == "" def test_http2_connection_closed() -> None: origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.MockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), # Connection is closed after the first response hyperframe.frame.GoAwayFrame(stream_id=0, error_code=0, last_stream_id=1).serialize(), ] ) with httpcore2.HTTP2Connection(origin=origin, stream=stream, keepalive_expiry=5.0) as conn: conn.request("GET", "https://example.com/") with pytest.raises(httpcore2.ConnectionNotAvailable): conn.request("GET", "https://example.com/") assert not conn.is_available() def test_http2_response_closed_twice() -> None: """ Closing a response for a stream that has already been removed should be a no-op, rather than raising a `KeyError` that masks the exception which triggered the cleanup. See https://github.com/encode/httpx/issues/3072 """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.MockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), ] ) with httpcore2.HTTP2Connection(origin=origin, stream=stream, keepalive_expiry=5.0) as conn: conn.request("GET", "https://example.com/") # The stream was closed when the response completed. conn._response_closed(stream_id=1) def test_http2_connection_post_request() -> None: origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.MockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), ] ) with httpcore2.HTTP2Connection(origin=origin, stream=stream) as conn: response = conn.request( "POST", "https://example.com/", headers={b"content-length": b"17"}, content=b'{"data": "upload"}', ) assert response.status == 200 assert response.content == b"Hello, world!" def test_http2_connection_with_remote_protocol_error() -> None: """ If a remote protocol error occurs, then no response will be returned, and the connection will not be reusable. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.MockStream([b"Wait, this isn't valid HTTP!", b""]) with httpcore2.HTTP2Connection(origin=origin, stream=stream) as conn: with pytest.raises(httpcore2.RemoteProtocolError): conn.request("GET", "https://example.com/") def test_http2_connection_with_rst_stream() -> None: """ If a stream reset occurs, then no response will be returned, but the connection will remain reusable for other requests. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.MockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), # Stream is closed midway through the first response... hyperframe.frame.RstStreamFrame(stream_id=1, error_code=8).serialize(), # ...Which doesn't prevent the second response. hyperframe.frame.HeadersFrame( stream_id=3, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=3, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), b"", ] ) with httpcore2.HTTP2Connection(origin=origin, stream=stream) as conn: with pytest.raises(httpcore2.RemoteProtocolError): conn.request("GET", "https://example.com/") response = conn.request("GET", "https://example.com/") assert response.status == 200 def test_http2_connection_with_goaway() -> None: """ If a GoAway frame occurs, then no response will be returned, and the connection will not be reusable for other requests. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.MockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), # Connection is closed midway through the first response... hyperframe.frame.GoAwayFrame(stream_id=0, error_code=0).serialize(), # ...We'll never get to this second response. hyperframe.frame.HeadersFrame( stream_id=3, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=3, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), b"", ] ) with httpcore2.HTTP2Connection(origin=origin, stream=stream) as conn: # The initial request has been closed midway, with an unrecoverable error. with pytest.raises(httpcore2.RemoteProtocolError): conn.request("GET", "https://example.com/") # The second request can receive a graceful `ConnectionNotAvailable`, # and may be retried on a new connection. with pytest.raises(httpcore2.ConnectionNotAvailable): conn.request("GET", "https://example.com/") def test_http2_connection_with_negative_flow_control_window() -> None: """A negative stream flow-control window must be awaited, not sent into. After the 65535-byte window is exhausted, the server reduces INITIAL_WINDOW_SIZE by 32767, which adjusts the just-exhausted stream window from 0 to -32767. `_wait_for_outgoing_flow` must park the stream until WINDOW_UPDATE restores positive credit; otherwise `h2` raises `LocalProtocolError` on the next send_data. """ origin = httpcore2.Origin(b"https", b"example.com", 443) reduce_settings = hyperframe.frame.SettingsFrame(stream_id=0) reduce_settings.settings = {hyperframe.frame.SettingsFrame.INITIAL_WINDOW_SIZE: 32768} stream = httpcore2.MockStream( [ hyperframe.frame.SettingsFrame(stream_id=0).serialize(), # This frame reduces INITIAL_WINDOW_SIZE to 32768, which adjusts the just-exhausted stream window to -32767. reduce_settings.serialize(), hyperframe.frame.WindowUpdateFrame(stream_id=0, window_increment=100_000).serialize(), hyperframe.frame.WindowUpdateFrame(stream_id=1, window_increment=100_000).serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"response", flags=["END_STREAM"]).serialize(), ] ) with httpcore2.HTTP2Connection(origin=origin, stream=stream) as conn: response = conn.request("POST", "https://example.com/", content=b"x" * 100_000) assert response.status == 200 assert response.content == b"response" def test_http2_connection_with_flow_control() -> None: origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.MockStream( [ hyperframe.frame.SettingsFrame().serialize(), # Available flow: 65,535 hyperframe.frame.WindowUpdateFrame(stream_id=0, window_increment=10_000).serialize(), hyperframe.frame.WindowUpdateFrame(stream_id=1, window_increment=10_000).serialize(), # Available flow: 75,535 hyperframe.frame.WindowUpdateFrame(stream_id=0, window_increment=10_000).serialize(), hyperframe.frame.WindowUpdateFrame(stream_id=1, window_increment=10_000).serialize(), # Available flow: 85,535 hyperframe.frame.WindowUpdateFrame(stream_id=0, window_increment=10_000).serialize(), hyperframe.frame.WindowUpdateFrame(stream_id=1, window_increment=10_000).serialize(), # Available flow: 95,535 hyperframe.frame.WindowUpdateFrame(stream_id=0, window_increment=10_000).serialize(), hyperframe.frame.WindowUpdateFrame(stream_id=1, window_increment=10_000).serialize(), # Available flow: 105,535 hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"100,000 bytes received", flags=["END_STREAM"]).serialize(), ] ) with httpcore2.HTTP2Connection(origin=origin, stream=stream) as conn: response = conn.request( "POST", "https://example.com/", content=b"x" * 100_000, ) assert response.status == 200 assert response.content == b"100,000 bytes received" def test_http2_connection_attempt_close() -> None: """ A connection can only be closed when it is idle. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.MockStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), ] ) with httpcore2.HTTP2Connection(origin=origin, stream=stream) as conn: with conn.stream("GET", "https://example.com/") as response: response.read() assert response.status == 200 assert response.content == b"Hello, world!" conn.close() with pytest.raises(httpcore2.ConnectionNotAvailable): conn.request("GET", "https://example.com/") def test_http2_request_to_incorrect_origin() -> None: """ A connection can only send requests to whichever origin it is connected to. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.MockStream([]) with httpcore2.HTTP2Connection(origin=origin, stream=stream) as conn: with pytest.raises(RuntimeError): conn.request("GET", "https://other.com/") def test_http2_remote_max_streams_update() -> None: """ If the remote server updates the maximum concurrent streams value, we should be adjusting how many streams we will allow. """ origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.MockStream( [ hyperframe.frame.SettingsFrame( settings={hyperframe.frame.SettingsFrame.MAX_CONCURRENT_STREAMS: 1000} ).serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"Hello, world!").serialize(), hyperframe.frame.SettingsFrame( settings={hyperframe.frame.SettingsFrame.MAX_CONCURRENT_STREAMS: 50} ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"Hello, world...again!", flags=["END_STREAM"]).serialize(), ] ) with httpcore2.HTTP2Connection(origin=origin, stream=stream) as conn: with conn.stream("GET", "https://example.com/") as response: i = 0 for chunk in response.iter_stream(): if i == 0: assert chunk == b"Hello, world!" assert conn._h2_state.remote_settings.max_concurrent_streams == 1000 assert conn._max_streams == min( conn._h2_state.remote_settings.max_concurrent_streams, conn._h2_state.local_settings.max_concurrent_streams, ) elif i == 1: assert chunk == b"Hello, world...again!" assert conn._h2_state.remote_settings.max_concurrent_streams == 50 assert conn._max_streams == min( conn._h2_state.remote_settings.max_concurrent_streams, conn._h2_state.local_settings.max_concurrent_streams, ) i += 1 @pytest.mark.parametrize("limits", [[1], [1, 2], [1, 100], [1, 2, 1]]) def test_http2_remote_max_streams_decrease_below_in_flight(limits: list[int]) -> None: origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.MockStream( [ hyperframe.frame.SettingsFrame( settings={hyperframe.frame.SettingsFrame.MAX_CONCURRENT_STREAMS: 100} ).serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode([(b":status", b"200")]), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.HeadersFrame( stream_id=3, data=hpack.Encoder().encode([(b":status", b"200")]), flags=["END_HEADERS"], ).serialize(), *[ hyperframe.frame.SettingsFrame( settings={hyperframe.frame.SettingsFrame.MAX_CONCURRENT_STREAMS: limit} ).serialize() for limit in limits ], hyperframe.frame.DataFrame(stream_id=1, data=b"response a", flags=["END_STREAM"]).serialize(), hyperframe.frame.DataFrame(stream_id=3, data=b"response b", flags=["END_STREAM"]).serialize(), hyperframe.frame.HeadersFrame( stream_id=5, data=hpack.Encoder().encode([(b":status", b"200")]), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=5, data=b"response c", flags=["END_STREAM"]).serialize(), ] ) with httpcore2.HTTP2Connection(origin=origin, stream=stream) as conn: with conn.stream("GET", "https://example.com/a") as response_a: with conn.stream("GET", "https://example.com/b") as response_b: assert response_a.status == response_b.status == 200 assert response_a.read() == b"response a" assert response_b.read() == b"response b" response_c = conn.request("GET", "https://example.com/c") assert response_c.status == 200 assert response_c.content == b"response c" assert conn.is_idle() pydantic-httpx2-6dd59b9/tests/httpcore2/_sync/test_http_proxy.py000066400000000000000000000303451526547463400252510ustar00rootroot00000000000000import ssl import typing import hpack import hyperframe.frame import pytest from httpcore2 import ( SOCKET_OPTION, ConnectionPool, MockBackend, MockStream, NetworkStream, Origin, Proxy, ProxyError, ) def test_proxy_forwarding() -> None: """ Send an HTTP request via a proxy. """ network_backend = MockBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) with ConnectionPool( proxy=Proxy("http://localhost:8080/"), max_connections=10, network_backend=network_backend, ) as proxy: # Sending an initial request, which once complete will return to the pool, IDLE. with proxy.stream("GET", "http://example.com/") as response: info = [repr(c) for c in proxy.connections] assert info == [ "" ] response.read() assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in proxy.connections] assert info == [""] assert proxy.connections[0].is_idle() assert proxy.connections[0].is_available() assert not proxy.connections[0].is_closed() # A connection on a forwarding proxy can only handle HTTP requests to the same origin. assert proxy.connections[0].can_handle_request(Origin(b"http", b"example.com", 80)) assert not proxy.connections[0].can_handle_request(Origin(b"http", b"other.com", 80)) assert not proxy.connections[0].can_handle_request(Origin(b"https", b"example.com", 443)) assert not proxy.connections[0].can_handle_request(Origin(b"https", b"other.com", 443)) def test_proxy_tunneling() -> None: """ Send an HTTPS request via a proxy. """ network_backend = MockBackend( [ # The initial response to the proxy CONNECT b"HTTP/1.1 200 OK\r\n\r\n", # The actual response from the remote server b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) with ConnectionPool( proxy=Proxy("http://localhost:8080/"), network_backend=network_backend, ) as proxy: # Sending an initial request, which once complete will return to the pool, IDLE. with proxy.stream("GET", "https://example.com/") as response: info = [repr(c) for c in proxy.connections] assert info == [ "" ] response.read() assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in proxy.connections] assert info == [""] assert proxy.connections[0].is_idle() assert proxy.connections[0].is_available() assert not proxy.connections[0].is_closed() # A connection on a tunneled proxy can only handle HTTPS requests to the same origin. assert not proxy.connections[0].can_handle_request(Origin(b"http", b"example.com", 80)) assert not proxy.connections[0].can_handle_request(Origin(b"http", b"other.com", 80)) assert proxy.connections[0].can_handle_request(Origin(b"https", b"example.com", 443)) assert not proxy.connections[0].can_handle_request(Origin(b"https", b"other.com", 443)) # We need to adapt the mock backend here slightly in order to deal # with the proxy case. We do not want the initial connection to the proxy # to indicate an HTTP/2 connection, but we do want it to indicate HTTP/2 # once the SSL upgrade has taken place. class HTTP1ThenHTTP2Stream(MockStream): def start_tls( self, ssl_context: ssl.SSLContext, server_hostname: str | None = None, timeout: float | None = None, ) -> NetworkStream: self._http2 = True return self class HTTP1ThenHTTP2Backend(MockBackend): def connect_tcp( self, host: str, port: int, timeout: float | None = None, local_address: str | None = None, socket_options: typing.Iterable[SOCKET_OPTION] | None = None, ) -> NetworkStream: return HTTP1ThenHTTP2Stream(list(self._buffer)) def test_proxy_tunneling_http2() -> None: """ Send an HTTP/2 request via a proxy. """ network_backend = HTTP1ThenHTTP2Backend( [ # The initial response to the proxy CONNECT b"HTTP/1.1 200 OK\r\n\r\n", # The actual response from the remote server hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"Hello, world!", flags=["END_STREAM"]).serialize(), ], ) with ConnectionPool( proxy=Proxy("http://localhost:8080/"), network_backend=network_backend, http2=True, ) as proxy: # Sending an initial request, which once complete will return to the pool, IDLE. with proxy.stream("GET", "https://example.com/") as response: info = [repr(c) for c in proxy.connections] assert info == [""] response.read() assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in proxy.connections] assert info == [""] assert proxy.connections[0].is_idle() assert proxy.connections[0].is_available() assert not proxy.connections[0].is_closed() # A connection on a tunneled proxy can only handle HTTPS requests to the same origin. assert not proxy.connections[0].can_handle_request(Origin(b"http", b"example.com", 80)) assert not proxy.connections[0].can_handle_request(Origin(b"http", b"other.com", 80)) assert proxy.connections[0].can_handle_request(Origin(b"https", b"example.com", 443)) assert not proxy.connections[0].can_handle_request(Origin(b"https", b"other.com", 443)) def test_proxy_tunneling_with_403() -> None: """ Send an HTTPS request via a proxy. """ network_backend = MockBackend( [ b"HTTP/1.1 403 Permission Denied\r\n\r\n", ] ) with ConnectionPool( proxy=Proxy("http://localhost:8080/"), network_backend=network_backend, ) as proxy: with pytest.raises(ProxyError) as exc_info: proxy.request("GET", "https://example.com/") assert str(exc_info.value) == "403 Permission Denied" assert not proxy.connections def test_proxy_tunneling_with_auth() -> None: """ Send an authenticated HTTPS request via a proxy. """ network_backend = MockBackend( [ # The initial response to the proxy CONNECT b"HTTP/1.1 200 OK\r\n\r\n", # The actual response from the remote server b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) with ConnectionPool( proxy=Proxy( url="http://localhost:8080/", auth=("username", "password"), ), network_backend=network_backend, ) as proxy: response = proxy.request("GET", "https://example.com/") assert response.status == 200 assert response.content == b"Hello, world!" def test_proxy_headers() -> None: proxy = Proxy( url="http://localhost:8080/", auth=("username", "password"), ) assert proxy.headers == [(b"Proxy-Authorization", b"Basic dXNlcm5hbWU6cGFzc3dvcmQ=")] @pytest.mark.parametrize( "method, target, forwarding_target", [ ("GET", b"/custom^path", b"http://example.com/custom^path"), ("OPTIONS", b"*", b"*"), ("CONNECT", b"example.com:443", b"example.com:443"), ("GET", b"http://example.com/custom^path", b"http://example.com/custom^path"), ], ) def test_proxy_forwarding_preserves_target_extension( method: str, target: bytes, forwarding_target: bytes ) -> None: events: dict[str, dict[str, typing.Any]] = {} def trace(name: str, info: dict[str, typing.Any]) -> None: events[name] = info network_backend = MockBackend([b"HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n"]) extensions = {"target": target, "trace": trace} expected_extensions = extensions.copy() with ConnectionPool(proxy=Proxy("http://localhost:8080"), network_backend=network_backend) as pool: pool.request(method, "http://example.com/", extensions=extensions) request = events["http11.send_request_headers.started"]["request"] assert request.url.target == forwarding_target assert extensions == expected_extensions def test_proxy_tunneling_preserves_target_extension() -> None: events: dict[str, list[dict[str, typing.Any]]] = {} def trace(name: str, info: dict[str, typing.Any]) -> None: events.setdefault(name, []).append(info) network_backend = MockBackend( [ b"HTTP/1.1 200 Connection established\r\n\r\n", b"HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n", ] ) extensions = {"target": b"/custom^path", "trace": trace} expected_extensions = extensions.copy() with ConnectionPool(proxy=Proxy("http://localhost:8080"), network_backend=network_backend) as pool: pool.request("GET", "https://example.com/", extensions=extensions) requests = [info["request"] for info in events["http11.send_request_headers.started"]] assert [(request.method, request.url.target) for request in requests] == [ (b"CONNECT", b"example.com:443"), (b"GET", b"/custom^path"), ] assert extensions == expected_extensions def test_proxy_forwarding_uses_proxy_tls_hostname() -> None: events: dict[str, dict[str, typing.Any]] = {} def trace(name: str, info: dict[str, typing.Any]) -> None: events[name] = info network_backend = MockBackend([b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nOK"]) extensions = {"sni_hostname": "example.com", "trace": trace} expected_extensions = extensions.copy() with ConnectionPool(proxy=Proxy("https://localhost:8080"), network_backend=network_backend) as pool: pool.request("GET", "http://192.0.2.1/", extensions=extensions) assert events["connection.start_tls.started"]["server_hostname"] == "localhost" assert extensions == expected_extensions @pytest.mark.parametrize( "sni_extensions, expected_hostname", [({}, "192.0.2.1"), ({"sni_hostname": "example.com"}, "example.com")], ) def test_proxy_tunneling_respects_sni_hostname(sni_extensions: dict[str, str], expected_hostname: str) -> None: events: dict[str, dict[str, typing.Any]] = {} def trace(name: str, info: dict[str, typing.Any]) -> None: events[name] = info network_backend = MockBackend( [ b"HTTP/1.1 200 Connection established\r\n\r\n", b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nOK", ] ) extensions = {"trace": trace, **sni_extensions} expected_extensions = extensions.copy() with ConnectionPool(proxy=Proxy("https://localhost:8080"), network_backend=network_backend) as pool: pool.request("GET", "https://192.0.2.1/", extensions=extensions) assert events["connection.start_tls.started"]["server_hostname"] == "localhost" assert events["proxy.start_tls.started"]["server_hostname"] == expected_hostname assert extensions == expected_extensions pydantic-httpx2-6dd59b9/tests/httpcore2/_sync/test_integration.py000066400000000000000000000032321526547463400253470ustar00rootroot00000000000000import ssl import pytest from pytest_httpbin.serve import Server import httpcore2 def test_request(httpbin: Server) -> None: with httpcore2.ConnectionPool() as pool: response = pool.request("GET", httpbin.url) assert response.status == 200 def test_ssl_request(httpbin_secure: Server) -> None: ssl_context = ssl.create_default_context() ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE with httpcore2.ConnectionPool(ssl_context=ssl_context) as pool: response = pool.request("GET", httpbin_secure.url) assert response.status == 200 def test_extra_info(httpbin_secure: Server) -> None: ssl_context = ssl.create_default_context() ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE with httpcore2.ConnectionPool(ssl_context=ssl_context) as pool: with pool.stream("GET", httpbin_secure.url) as response: assert response.status == 200 stream = response.extensions["network_stream"] ssl_object = stream.get_extra_info("ssl_object") assert ssl_object.version() == "TLSv1.3" local_addr = stream.get_extra_info("client_addr") assert local_addr[0] == "127.0.0.1" remote_addr = stream.get_extra_info("server_addr") assert f"https://{remote_addr[0]}:{remote_addr[1]}" == httpbin_secure.url sock = stream.get_extra_info("socket") assert hasattr(sock, "family") assert hasattr(sock, "type") invalid = stream.get_extra_info("invalid") assert invalid is None stream.get_extra_info("is_readable") pydantic-httpx2-6dd59b9/tests/httpcore2/_sync/test_socks_proxy.py000066400000000000000000000143041526547463400254110ustar00rootroot00000000000000import pytest import httpcore2 def test_socks5_request() -> None: """ Send an HTTP request via a SOCKS proxy. """ network_backend = httpcore2.MockBackend( [ # The initial socks CONNECT # v5 NOAUTH b"\x05\x00", # v5 SUC RSV IP4 127 .0 .0 .1 :80 b"\x05\x00\x00\x01\xff\x00\x00\x01\x00\x50", # The actual response from the remote server b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) with httpcore2.ConnectionPool( proxy=httpcore2.Proxy("socks5://localhost:8080/"), network_backend=network_backend, ) as proxy: # Sending an initial request, which once complete will return to the pool, IDLE. with proxy.stream("GET", "https://example.com/") as response: info = [repr(c) for c in proxy.connections] assert info == [""] response.read() assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in proxy.connections] assert info == [""] assert proxy.connections[0].is_idle() assert proxy.connections[0].is_available() assert not proxy.connections[0].is_closed() # A connection on a tunneled proxy can only handle HTTPS requests to the same origin. assert not proxy.connections[0].can_handle_request(httpcore2.Origin(b"http", b"example.com", 80)) assert not proxy.connections[0].can_handle_request(httpcore2.Origin(b"http", b"other.com", 80)) assert proxy.connections[0].can_handle_request(httpcore2.Origin(b"https", b"example.com", 443)) assert not proxy.connections[0].can_handle_request(httpcore2.Origin(b"https", b"other.com", 443)) def test_authenticated_socks5_request() -> None: """ Send an HTTP request via a SOCKS proxy. """ network_backend = httpcore2.MockBackend( [ # The initial socks CONNECT # v5 USERNAME/PASSWORD b"\x05\x02", # v1 VALID USERNAME/PASSWORD b"\x01\x00", # v5 SUC RSV IP4 127 .0 .0 .1 :80 b"\x05\x00\x00\x01\xff\x00\x00\x01\x00\x50", # The actual response from the remote server b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ] ) with httpcore2.ConnectionPool( proxy=httpcore2.Proxy( url="socks5://localhost:8080/", auth=(b"username", b"password"), ), network_backend=network_backend, ) as proxy: # Sending an initial request, which once complete will return to the pool, IDLE. with proxy.stream("GET", "https://example.com/") as response: info = [repr(c) for c in proxy.connections] assert info == [""] response.read() assert response.status == 200 assert response.content == b"Hello, world!" info = [repr(c) for c in proxy.connections] assert info == [""] assert proxy.connections[0].is_idle() assert proxy.connections[0].is_available() assert not proxy.connections[0].is_closed() def test_socks5_request_connect_failed() -> None: """ Attempt to send an HTTP request via a SOCKS proxy, resulting in a connect failure. """ network_backend = httpcore2.MockBackend( [ # The initial socks CONNECT # v5 NOAUTH b"\x05\x00", # v5 NO RSV IP4 0 .0 .0 .0 :00 b"\x05\x05\x00\x01\x00\x00\x00\x00\x00\x00", ] ) with httpcore2.ConnectionPool( proxy=httpcore2.Proxy("socks5://localhost:8080/"), network_backend=network_backend, ) as proxy: # Sending a request, which the proxy rejects with pytest.raises(httpcore2.ProxyError) as exc_info: proxy.request("GET", "https://example.com/") assert str(exc_info.value) == "Proxy Server could not connect: Connection refused." assert not proxy.connections def test_socks5_request_failed_to_provide_auth() -> None: """ Attempt to send an HTTP request via an authenticated SOCKS proxy, without providing authentication credentials. """ network_backend = httpcore2.MockBackend( [ # v5 USERNAME/PASSWORD b"\x05\x02", ] ) with httpcore2.ConnectionPool( proxy=httpcore2.Proxy("socks5://localhost:8080/"), network_backend=network_backend, ) as proxy: # Sending a request, which the proxy rejects with pytest.raises(httpcore2.ProxyError) as exc_info: proxy.request("GET", "https://example.com/") assert ( str(exc_info.value) == "Requested NO AUTHENTICATION REQUIRED from proxy server, but got USERNAME/PASSWORD." ) assert not proxy.connections def test_socks5_request_incorrect_auth() -> None: """ Attempt to send an HTTP request via an authenticated SOCKS proxy, with incorrect authentication credentials. """ network_backend = httpcore2.MockBackend( [ # v5 USERNAME/PASSWORD b"\x05\x02", # v1 INVALID USERNAME/PASSWORD b"\x01\x01", ] ) with httpcore2.ConnectionPool( proxy=httpcore2.Proxy( url="socks5://localhost:8080/", auth=(b"invalid", b"invalid"), ), network_backend=network_backend, ) as proxy: # Sending a request, which the proxy rejects with pytest.raises(httpcore2.ProxyError) as exc_info: proxy.request("GET", "https://example.com/") assert str(exc_info.value) == "Invalid username/password" assert not proxy.connections pydantic-httpx2-6dd59b9/tests/httpcore2/concurrency.py000066400000000000000000000022701526547463400232050ustar00rootroot00000000000000""" Some of our tests require branching of flow control. We'd like to have the same kind of test for both async and sync environments, and so we have functionality here that replicate's Trio's `open_nursery` API, but in a plain old multi-threaded context. We don't do any smarts around cancellations, or managing exceptions from children, because we don't need that for our use-case. """ import threading from collections.abc import Callable from types import TracebackType from typing import Any class Nursery: def __init__(self) -> None: self._threads: list[threading.Thread] = [] def __enter__(self) -> "Nursery": return self def __exit__( self, exc_type: type[BaseException] | None = None, exc_value: BaseException | None = None, traceback: TracebackType | None = None, ) -> None: for thread in self._threads: thread.start() for thread in self._threads: thread.join() def start_soon(self, func: Callable[..., object], *args: Any) -> None: thread = threading.Thread(target=func, args=args) self._threads.append(thread) def open_nursery() -> Nursery: return Nursery() pydantic-httpx2-6dd59b9/tests/httpcore2/test_api.py000066400000000000000000000011461526547463400224640ustar00rootroot00000000000000import json from pytest_httpbin.serve import Server import httpcore2 def test_request(httpbin: Server) -> None: response = httpcore2.request("GET", httpbin.url) assert response.status == 200 def test_stream(httpbin: Server) -> None: with httpcore2.stream("GET", httpbin.url) as response: assert response.status == 200 def test_request_with_content(httpbin: Server) -> None: url = f"{httpbin.url}/post" response = httpcore2.request("POST", url, content=b'{"hello":"world"}') assert response.status == 200 assert json.loads(response.content)["json"] == {"hello": "world"} pydantic-httpx2-6dd59b9/tests/httpcore2/test_cancellations.py000066400000000000000000000352701526547463400245370ustar00rootroot00000000000000import typing from unittest.mock import patch import anyio import hpack import hyperframe.frame import pytest from trio.testing import MockClock import httpcore2 @pytest.fixture(params=["asyncio", "trio"]) def anyio_backend(request: pytest.FixtureRequest) -> str | tuple[str, dict[str, MockClock]]: if request.param == "trio": return "trio", {"clock": MockClock(autojump_threshold=0)} return "asyncio" class SlowWriteStream(httpcore2.AsyncNetworkStream): """ A stream that we can use to test cancellations during the request writing. """ async def write(self, buffer: bytes, timeout: float | None = None) -> None: await anyio.sleep(999) async def aclose(self) -> None: await anyio.sleep(0) class HandshakeThenSlowWriteStream(httpcore2.AsyncNetworkStream): """ A stream that we can use to test cancellations during the HTTP/2 request writing, after allowing the initial handshake to complete. """ def __init__(self) -> None: self._handshake_complete = False async def write(self, buffer: bytes, timeout: float | None = None) -> None: if not self._handshake_complete: self._handshake_complete = True else: await anyio.sleep(999) async def aclose(self) -> None: await anyio.sleep(0) class SlowReadStream(httpcore2.AsyncNetworkStream): """ A stream that we can use to test cancellations during the response reading. """ def __init__(self, buffer: list[bytes]): self._buffer = buffer async def write(self, buffer: bytes, timeout: float | None = None) -> None: pass async def read(self, max_bytes: int, timeout: float | None = None) -> bytes: if not self._buffer: await anyio.sleep(999) return self._buffer.pop(0) async def aclose(self) -> None: await anyio.sleep(0) class SlowWriteBackend(httpcore2.AsyncNetworkBackend): async def connect_tcp( self, host: str, port: int, timeout: float | None = None, local_address: str | None = None, socket_options: typing.Iterable[httpcore2.SOCKET_OPTION] | None = None, ) -> httpcore2.AsyncNetworkStream: return SlowWriteStream() class SlowReadBackend(httpcore2.AsyncNetworkBackend): def __init__(self, buffer: list[bytes]): self._buffer = buffer async def connect_tcp( self, host: str, port: int, timeout: float | None = None, local_address: str | None = None, socket_options: typing.Iterable[httpcore2.SOCKET_OPTION] | None = None, ) -> httpcore2.AsyncNetworkStream: return SlowReadStream(self._buffer) @pytest.mark.anyio async def test_connection_pool_timeout_during_request() -> None: """ An async timeout when writing an HTTP/1.1 response on the connection pool should leave the pool in a consistent state. In this case, that means the connection will become closed, and no longer remain in the pool. """ network_backend = SlowWriteBackend() async with httpcore2.AsyncConnectionPool(network_backend=network_backend) as pool: with anyio.move_on_after(0.01): await pool.request("GET", "http://example.com") assert not pool.connections @pytest.mark.anyio async def test_connection_pool_timeout_during_response() -> None: """ An async timeout when reading an HTTP/1.1 response on the connection pool should leave the pool in a consistent state. In this case, that means the connection will become closed, and no longer remain in the pool. """ network_backend = SlowReadBackend( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 1000\r\n", b"\r\n", b"Hello, world!...", ] ) async with httpcore2.AsyncConnectionPool(network_backend=network_backend) as pool: with anyio.move_on_after(0.01): await pool.request("GET", "http://example.com") assert not pool.connections @pytest.mark.anyio async def test_connection_pool_cancellation_during_waiting_for_connection() -> None: """ A cancellation while a request is waiting for a connection should leave the pool in a consistent state. In this case, that means the new (not-yet-connected) connection is discarded and no longer remains in the pool. """ async def wait_for_connection(self: typing.Any, *args: typing.Any, **kwargs: typing.Any) -> None: await anyio.sleep(999) with patch( "httpcore2._async.connection_pool.AsyncPoolRequest.wait_for_connection", new=wait_for_connection, ): async with httpcore2.AsyncConnectionPool() as pool: with anyio.move_on_after(0.01): await pool.request("GET", "http://example.com") assert not pool.connections @pytest.mark.anyio async def test_h11_timeout_during_request() -> None: """ An async timeout on an HTTP/1.1 during the request writing should leave the connection in a neatly closed state. """ origin = httpcore2.Origin(b"http", b"example.com", 80) stream = SlowWriteStream() async with httpcore2.AsyncHTTP11Connection(origin, stream) as conn: with anyio.move_on_after(0.01): await conn.request("GET", "http://example.com") assert conn.is_closed() @pytest.mark.anyio async def test_h11_timeout_during_response() -> None: """ An async timeout on an HTTP/1.1 during the response reading should leave the connection in a neatly closed state. """ origin = httpcore2.Origin(b"http", b"example.com", 80) stream = SlowReadStream( [ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 1000\r\n", b"\r\n", b"Hello, world!...", ] ) async with httpcore2.AsyncHTTP11Connection(origin, stream) as conn: with anyio.move_on_after(0.01): await conn.request("GET", "http://example.com") assert conn.is_closed() @pytest.mark.anyio @pytest.mark.parametrize("cancel_waiter", [False, True]) @pytest.mark.parametrize("close_before_settings", [False, True]) async def test_h2_queued_request_after_stream_limit_decrease(cancel_waiter: bool, close_before_settings: bool) -> None: origin = httpcore2.Origin(b"https", b"example.com", 443) stream = httpcore2.AsyncMockStream( [ hyperframe.frame.SettingsFrame( settings={hyperframe.frame.SettingsFrame.MAX_CONCURRENT_STREAMS: 2} ).serialize(), *[ hyperframe.frame.HeadersFrame( stream_id=stream_id, data=hpack.Encoder().encode([(b":status", b"200")]), flags=["END_HEADERS"], ).serialize() for stream_id in (1, 3) ], hyperframe.frame.DataFrame(stream_id=1, data=b"response a", flags=["END_STREAM"]).serialize(), hyperframe.frame.SettingsFrame( settings={hyperframe.frame.SettingsFrame.MAX_CONCURRENT_STREAMS: 1} ).serialize(), hyperframe.frame.DataFrame(stream_id=3, data=b"response b").serialize(), hyperframe.frame.DataFrame(stream_id=3, flags=["END_STREAM"]).serialize(), *[ hyperframe.frame.HeadersFrame( stream_id=stream_id, data=hpack.Encoder().encode([(b":status", b"200")]), flags=["END_HEADERS", "END_STREAM"], ).serialize() for stream_id in (5, 7) ], ] ) statuses: list[int] = [] waiter_scope = anyio.CancelScope() async def fetch(conn: httpcore2.AsyncHTTP2Connection) -> None: with waiter_scope: response = await conn.request("GET", "https://example.com/queued") statuses.append(response.status) async with httpcore2.AsyncHTTP2Connection(origin=origin, stream=stream) as conn: with anyio.fail_after(2): async with conn.stream("GET", "https://example.com/a") as response_a: async def trace(name: str, info: dict[str, typing.Any]) -> None: if name == "http2.receive_remote_settings.started" and not close_before_settings: await response_a.aclose() await anyio.wait_all_tasks_blocked() async with conn.stream("GET", "https://example.com/b", extensions={"trace": trace}) as response_b: async with anyio.create_task_group() as task_group: task_group.start_soon(fetch, conn) await anyio.wait_all_tasks_blocked() assert await response_a.aread() == b"response a" if close_before_settings: await response_a.aclose() iterator = response_b.aiter_stream() assert await anext(iterator) == b"response b" await anyio.wait_all_tasks_blocked() if not close_before_settings: assert statuses == [] expected_statuses = statuses.copy() if cancel_waiter else [200] if cancel_waiter: waiter_scope.cancel() await anyio.wait_all_tasks_blocked() async for chunk in iterator: assert chunk == b"" await response_b.aclose() assert statuses == expected_statuses response = await conn.request("GET", "https://example.com/reused") assert response.status == 200 assert conn.is_idle() @pytest.mark.anyio async def test_h2_stream_limit_capacity() -> None: origin = httpcore2.Origin(b"https", b"example.com", 443) buffer = [ hyperframe.frame.SettingsFrame(settings={hyperframe.frame.SettingsFrame.MAX_CONCURRENT_STREAMS: 2}).serialize(), *[ hyperframe.frame.HeadersFrame( stream_id=stream_id, data=hpack.Encoder().encode([(b":status", b"200")]), flags=["END_HEADERS"], ).serialize() for stream_id in (1, 3) ], hyperframe.frame.SettingsFrame(settings={hyperframe.frame.SettingsFrame.MAX_CONCURRENT_STREAMS: 1}).serialize(), hyperframe.frame.DataFrame(stream_id=3, data=b"response b").serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"response a", flags=["END_STREAM"]).serialize(), hyperframe.frame.SettingsFrame(settings={hyperframe.frame.SettingsFrame.MAX_CONCURRENT_STREAMS: 2}).serialize(), hyperframe.frame.DataFrame(stream_id=3, data=b"more").serialize(), hyperframe.frame.HeadersFrame( stream_id=5, data=hpack.Encoder().encode([(b":status", b"200")]), flags=["END_HEADERS", "END_STREAM"], ).serialize(), ] stream = httpcore2.AsyncMockStream(buffer) statuses: list[int] = [] async def fetch(conn: httpcore2.AsyncHTTP2Connection) -> None: response = await conn.request("GET", "https://example.com/queued") statuses.append(response.status) async with httpcore2.AsyncHTTP2Connection(origin=origin, stream=stream) as conn: with anyio.fail_after(2): async with conn.stream("GET", "https://example.com/a") as response_a: async with conn.stream("GET", "https://example.com/b") as response_b: iterator = response_b.aiter_stream() assert await anext(iterator) == b"response b" assert await response_a.aread() == b"response a" await response_a.aclose() async with anyio.create_task_group() as task_group: task_group.start_soon(fetch, conn) await anyio.wait_all_tasks_blocked() assert statuses == [] assert await anext(iterator) == b"more" await anyio.wait_all_tasks_blocked() assert statuses == [200] buffer.append(hyperframe.frame.DataFrame(stream_id=3, flags=["END_STREAM"]).serialize()) async for chunk in iterator: assert chunk == b"" assert conn.is_idle() @pytest.mark.anyio async def test_h2_timeout_during_handshake() -> None: """ An async timeout on an HTTP/2 during the initial handshake should leave the connection in a neatly closed state. """ origin = httpcore2.Origin(b"http", b"example.com", 80) stream = SlowWriteStream() async with httpcore2.AsyncHTTP2Connection(origin, stream) as conn: with anyio.move_on_after(0.01): await conn.request("GET", "http://example.com") assert conn.is_closed() @pytest.mark.anyio async def test_h2_timeout_during_request() -> None: """ An async timeout on an HTTP/2 during a request should leave the connection in a neatly idle state. The connection is not closed because it is multiplexed, and a timeout on one request does not require the entire connection be closed. """ origin = httpcore2.Origin(b"http", b"example.com", 80) stream = HandshakeThenSlowWriteStream() async with httpcore2.AsyncHTTP2Connection(origin, stream) as conn: with anyio.move_on_after(0.01): await conn.request("GET", "http://example.com") assert not conn.is_closed() assert conn.is_idle() @pytest.mark.anyio async def test_h2_timeout_during_response() -> None: """ An async timeout on an HTTP/2 during the response reading should leave the connection in a neatly idle state. The connection is not closed because it is multiplexed, and a timeout on one request does not require the entire connection be closed. """ origin = httpcore2.Origin(b"http", b"example.com", 80) stream = SlowReadStream( [ hyperframe.frame.SettingsFrame().serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode( [ (b":status", b"200"), (b"content-type", b"plain/text"), ] ), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"Hello, world!...", flags=[]).serialize(), ] ) async with httpcore2.AsyncHTTP2Connection(origin, stream) as conn: with anyio.move_on_after(0.01): await conn.request("GET", "http://example.com") assert not conn.is_closed() assert conn.is_idle() pydantic-httpx2-6dd59b9/tests/httpcore2/test_models.py000066400000000000000000000137741526547463400232100ustar00rootroot00000000000000import typing import pytest import httpcore2 # URL def test_url() -> None: url = httpcore2.URL("https://www.example.com/") assert url == httpcore2.URL(scheme="https", host="www.example.com", port=None, target="/") assert bytes(url) == b"https://www.example.com/" def test_url_with_port() -> None: url = httpcore2.URL("https://www.example.com:443/") assert url == httpcore2.URL(scheme="https", host="www.example.com", port=443, target="/") assert bytes(url) == b"https://www.example.com:443/" def test_url_with_invalid_argument() -> None: with pytest.raises(TypeError) as exc_info: httpcore2.URL(123) # type: ignore assert str(exc_info.value) == "url must be bytes or str, but got int." def test_url_cannot_include_unicode_strings() -> None: """ URLs instantiated with strings outside of the plain ASCII range are disallowed, but the explicit style allows for these ambiguous cases to be precisely expressed. """ with pytest.raises(TypeError) as exc_info: httpcore2.URL("https://www.example.com/โ˜บ") assert str(exc_info.value) == "url strings may not include unicode characters." httpcore2.URL(scheme=b"https", host=b"www.example.com", target="/โ˜บ".encode()) def test_url_origin_socks5() -> None: url = httpcore2.URL("socks5://127.0.0.1") origin = url.origin assert origin == httpcore2.Origin(scheme=b"socks5", host=b"127.0.0.1", port=1080) assert str(origin) == "socks5://127.0.0.1:1080" url = httpcore2.URL("socks5h://127.0.0.1") origin = url.origin assert origin == httpcore2.Origin(scheme=b"socks5h", host=b"127.0.0.1", port=1080) assert str(origin) == "socks5h://127.0.0.1:1080" # Request def test_request() -> None: request = httpcore2.Request("GET", "https://www.example.com/") assert request.method == b"GET" assert request.url == httpcore2.URL("https://www.example.com/") assert request.headers == [] assert request.extensions == {} assert repr(request) == "" assert repr(request.url) == "URL(scheme=b'https', host=b'www.example.com', port=None, target=b'/')" assert repr(request.stream) == "" def test_request_with_target_extension() -> None: extensions = {"target": b"/another_path"} request = httpcore2.Request("GET", "https://www.example.com/path", extensions=extensions) assert request.url.target == b"/another_path" extensions = {"target": b"/unescaped|path"} request = httpcore2.Request("GET", "https://www.example.com/path", extensions=extensions) assert request.url.target == b"/unescaped|path" def test_request_with_invalid_method() -> None: with pytest.raises(TypeError) as exc_info: httpcore2.Request(123, "https://www.example.com/") # type: ignore assert str(exc_info.value) == "method must be bytes or str, but got int." def test_request_with_invalid_url() -> None: with pytest.raises(TypeError) as exc_info: httpcore2.Request("GET", 123) # type: ignore assert str(exc_info.value) == "url must be a URL, bytes, or str, but got int." def test_request_with_invalid_headers() -> None: with pytest.raises(TypeError) as exc_info: httpcore2.Request("GET", "https://www.example.com/", headers=123) # type: ignore assert str(exc_info.value) == "headers must be a mapping or sequence of two-tuples, but got int." # Response def test_response() -> None: response = httpcore2.Response(200) assert response.status == 200 assert response.headers == [] assert response.extensions == {} assert repr(response) == "" assert repr(response.stream) == "" # Tests for reading and streaming sync byte streams... class ByteIterator: def __init__(self, chunks: list[bytes]) -> None: self._chunks = chunks def __iter__(self) -> typing.Iterator[bytes]: yield from self._chunks def test_response_sync_read() -> None: stream = ByteIterator([b"Hello, ", b"world!"]) response = httpcore2.Response(200, content=stream) assert response.read() == b"Hello, world!" assert response.content == b"Hello, world!" def test_response_sync_streaming() -> None: stream = ByteIterator([b"Hello, ", b"world!"]) response = httpcore2.Response(200, content=stream) content = b"".join(list(response.iter_stream())) assert content == b"Hello, world!" # We streamed the response rather than reading it, so .content is not available. with pytest.raises(RuntimeError): _ = response.content # Once we've streamed the response, we can't access the stream again. with pytest.raises(RuntimeError): for _chunk in response.iter_stream(): pass # pragma: no cover # Tests for reading and streaming async byte streams... class AsyncByteIterator: def __init__(self, chunks: list[bytes]) -> None: self._chunks = iter(chunks) def __aiter__(self) -> typing.AsyncIterator[bytes]: return self async def __anext__(self) -> bytes: try: return next(self._chunks) except StopIteration: raise StopAsyncIteration from None @pytest.mark.trio async def test_response_async_read() -> None: stream = AsyncByteIterator([b"Hello, ", b"world!"]) response = httpcore2.Response(200, content=stream) assert await response.aread() == b"Hello, world!" assert response.content == b"Hello, world!" @pytest.mark.trio async def test_response_async_streaming() -> None: stream = AsyncByteIterator([b"Hello, ", b"world!"]) response = httpcore2.Response(200, content=stream) content = b"".join([chunk async for chunk in response.aiter_stream()]) assert content == b"Hello, world!" # We streamed the response rather than reading it, so .content is not available. with pytest.raises(RuntimeError): _ = response.content # Once we've streamed the response, we can't access the stream again. with pytest.raises(RuntimeError): async for _chunk in response.aiter_stream(): pass # pragma: no cover pydantic-httpx2-6dd59b9/tests/httpx2/000077500000000000000000000000001526547463400176175ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/tests/httpx2/__init__.py000066400000000000000000000000001526547463400217160ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/tests/httpx2/client/000077500000000000000000000000001526547463400210755ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/tests/httpx2/client/__init__.py000066400000000000000000000000001526547463400231740ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/tests/httpx2/client/test_async_client.py000066400000000000000000000325011526547463400251620ustar00rootroot00000000000000from __future__ import annotations import asyncio import sys import typing from datetime import timedelta import pytest import httpx2 if typing.TYPE_CHECKING: from conftest import TestServer @pytest.mark.anyio async def test_get(server: TestServer) -> None: url = server.url async with httpx2.AsyncClient(http2=True) as client: response = await client.get(url) assert response.status_code == 200 assert response.text == "Hello, world!" assert response.http_version == "HTTP/1.1" assert response.headers assert repr(response) == "" assert response.elapsed > timedelta(seconds=0) @pytest.mark.parametrize( "url", [ pytest.param("invalid://example.org", id="scheme-not-http(s)"), pytest.param("://example.org", id="no-scheme"), pytest.param("http://", id="no-host"), ], ) @pytest.mark.anyio async def test_get_invalid_url(server: TestServer, url: str) -> None: async with httpx2.AsyncClient() as client: with pytest.raises((httpx2.UnsupportedProtocol, httpx2.LocalProtocolError)): await client.get(url) @pytest.mark.anyio async def test_build_request(server: TestServer) -> None: url = server.url.copy_with(path="/echo_headers") headers = {"Custom-header": "value"} async with httpx2.AsyncClient() as client: request = client.build_request("GET", url) request.headers.update(headers) response = await client.send(request) assert response.status_code == 200 assert response.url == url assert response.json()["Custom-header"] == "value" @pytest.mark.anyio async def test_post(server: TestServer) -> None: url = server.url async with httpx2.AsyncClient() as client: response = await client.post(url, content=b"Hello, world!") assert response.status_code == 200 @pytest.mark.anyio async def test_post_json(server: TestServer) -> None: url = server.url async with httpx2.AsyncClient() as client: response = await client.post(url, json={"text": "Hello, world!"}) assert response.status_code == 200 @pytest.mark.anyio async def test_stream_response(server: TestServer) -> None: async with httpx2.AsyncClient() as client: async with client.stream("GET", server.url) as response: body = await response.aread() assert response.status_code == 200 assert body == b"Hello, world!" assert response.content == b"Hello, world!" def test_abandon_streamed_response(server: TestServer) -> None: async def request() -> None: client = httpx2.AsyncClient() request = client.build_request("GET", server.url.copy_with(path="/stream_response")) response = await client.send(request, stream=True) generators: list[typing.AsyncGenerator[object, None]] = [] hooks = sys.get_asyncgen_hooks() def firstiter(generator: typing.AsyncGenerator[object, None]) -> None: generators.append(generator) if hooks.firstiter is not None: hooks.firstiter(generator) sys.set_asyncgen_hooks(firstiter=firstiter) try: async for _line in response.aiter_lines(): break finally: sys.set_asyncgen_hooks(*hooks) try: for generator in reversed(generators): await generator.aclose() finally: await response.aclose() await client.aclose() asyncio.run(request()) @pytest.mark.anyio async def test_access_content_stream_response(server: TestServer) -> None: async with httpx2.AsyncClient() as client: async with client.stream("GET", server.url) as response: pass assert response.status_code == 200 with pytest.raises(httpx2.ResponseNotRead): response.content # noqa: B018 @pytest.mark.anyio async def test_stream_request(server: TestServer) -> None: async def hello_world() -> typing.AsyncIterator[bytes]: yield b"Hello, " yield b"world!" async with httpx2.AsyncClient() as client: response = await client.post(server.url, content=hello_world()) assert response.status_code == 200 @pytest.mark.anyio async def test_cannot_stream_sync_request(server: TestServer) -> None: def hello_world() -> typing.Iterator[bytes]: # pragma: no cover yield b"Hello, " yield b"world!" async with httpx2.AsyncClient() as client: with pytest.raises(RuntimeError): await client.post(server.url, content=hello_world()) @pytest.mark.anyio async def test_raise_for_status(server: TestServer) -> None: async with httpx2.AsyncClient() as client: for status_code in (200, 400, 404, 500, 505): response = await client.request("GET", server.url.copy_with(path=f"/status/{status_code}")) if 400 <= status_code < 600: with pytest.raises(httpx2.HTTPStatusError) as exc_info: response.raise_for_status() assert exc_info.value.response == response else: assert response.raise_for_status() is response @pytest.mark.anyio async def test_options(server: TestServer) -> None: async with httpx2.AsyncClient() as client: response = await client.options(server.url) assert response.status_code == 200 assert response.text == "Hello, world!" @pytest.mark.anyio async def test_head(server: TestServer) -> None: async with httpx2.AsyncClient() as client: response = await client.head(server.url) assert response.status_code == 200 assert response.text == "" @pytest.mark.anyio async def test_put(server: TestServer) -> None: async with httpx2.AsyncClient() as client: response = await client.put(server.url, content=b"Hello, world!") assert response.status_code == 200 @pytest.mark.anyio async def test_patch(server: TestServer) -> None: async with httpx2.AsyncClient() as client: response = await client.patch(server.url, content=b"Hello, world!") assert response.status_code == 200 @pytest.mark.anyio async def test_delete(server: TestServer) -> None: async with httpx2.AsyncClient() as client: response = await client.delete(server.url) assert response.status_code == 200 assert response.text == "Hello, world!" @pytest.mark.anyio async def test_query(server: TestServer) -> None: async with httpx2.AsyncClient() as client: response = await client.query(server.url, content=b"Hello, world!") assert response.status_code == 200 @pytest.mark.anyio async def test_100_continue(server: TestServer) -> None: headers = {"Expect": "100-continue"} content = b"Echo request body" async with httpx2.AsyncClient() as client: response = await client.post(server.url.copy_with(path="/echo_body"), headers=headers, content=content) assert response.status_code == 200 assert response.content == content @pytest.mark.anyio async def test_context_managed_transport() -> None: class Transport(httpx2.AsyncBaseTransport): def __init__(self) -> None: self.events: list[str] = [] async def aclose(self) -> None: # The base implementation of httpx2.AsyncBaseTransport just # calls into `.aclose`, so simple transport cases can just override # this method for any cleanup, where more complex cases # might want to additionally override `__aenter__`/`__aexit__`. self.events.append("transport.aclose") async def __aenter__(self) -> Transport: await super().__aenter__() self.events.append("transport.__aenter__") return self async def __aexit__(self, *args: typing.Any) -> None: await super().__aexit__(*args) self.events.append("transport.__aexit__") transport = Transport() async with httpx2.AsyncClient(transport=transport): pass assert transport.events == [ "transport.__aenter__", "transport.aclose", "transport.__aexit__", ] @pytest.mark.anyio async def test_context_managed_transport_and_mount() -> None: class Transport(httpx2.AsyncBaseTransport): def __init__(self, name: str) -> None: self.name: str = name self.events: list[str] = [] async def aclose(self) -> None: # The base implementation of httpx2.AsyncBaseTransport just # calls into `.aclose`, so simple transport cases can just override # this method for any cleanup, where more complex cases # might want to additionally override `__aenter__`/`__aexit__`. self.events.append(f"{self.name}.aclose") async def __aenter__(self) -> Transport: await super().__aenter__() self.events.append(f"{self.name}.__aenter__") return self async def __aexit__(self, *args: typing.Any) -> None: await super().__aexit__(*args) self.events.append(f"{self.name}.__aexit__") transport = Transport(name="transport") mounted = Transport(name="mounted") async with httpx2.AsyncClient(transport=transport, mounts={"http://www.example.org": mounted}): pass assert transport.events == [ "transport.__aenter__", "transport.aclose", "transport.__aexit__", ] assert mounted.events == [ "mounted.__aenter__", "mounted.aclose", "mounted.__aexit__", ] def hello_world(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, text="Hello, world!") @pytest.mark.anyio async def test_client_closed_state_using_implicit_open() -> None: client = httpx2.AsyncClient(transport=httpx2.MockTransport(hello_world)) assert not client.is_closed await client.get("http://example.com") assert not client.is_closed await client.aclose() assert client.is_closed # Once we're close we cannot make any more requests. with pytest.raises(RuntimeError): await client.get("http://example.com") # Once we're closed we cannot reopen the client. with pytest.raises(RuntimeError): async with client: pass # pragma: no cover @pytest.mark.anyio async def test_client_closed_state_using_with_block() -> None: transport = httpx2.MockTransport(hello_world) async with httpx2.AsyncClient(transport=transport) as client: assert not client.is_closed await client.get("http://example.com") assert client.is_closed with pytest.raises(RuntimeError): await client.get("http://example.com") def unmounted(request: httpx2.Request) -> httpx2.Response: data = {"app": "unmounted"} return httpx2.Response(200, json=data) def mounted(request: httpx2.Request) -> httpx2.Response: data = {"app": "mounted"} return httpx2.Response(200, json=data) @pytest.mark.anyio async def test_mounted_transport() -> None: transport = httpx2.MockTransport(unmounted) mounts = {"custom://": httpx2.MockTransport(mounted)} async with httpx2.AsyncClient(transport=transport, mounts=mounts) as client: response = await client.get("https://www.example.com") assert response.status_code == 200 assert response.json() == {"app": "unmounted"} response = await client.get("custom://www.example.com") assert response.status_code == 200 assert response.json() == {"app": "mounted"} @pytest.mark.anyio async def test_async_mock_transport() -> None: async def hello_world(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, text="Hello, world!") transport = httpx2.MockTransport(hello_world) async with httpx2.AsyncClient(transport=transport) as client: response = await client.get("https://www.example.com") assert response.status_code == 200 assert response.text == "Hello, world!" @pytest.mark.anyio async def test_cancellation_during_stream() -> None: """ If any BaseException is raised during streaming the response, then the stream should be closed. This includes: * `asyncio.CancelledError` (A subclass of BaseException from Python 3.8 onwards.) * `trio.Cancelled` * `KeyboardInterrupt` * `SystemExit` See https://github.com/encode/httpx/issues/2139 """ stream_was_closed = False def response_with_cancel_during_stream(request: httpx2.Request) -> httpx2.Response: class CancelledStream(httpx2.AsyncByteStream): async def __aiter__(self) -> typing.AsyncIterator[bytes]: yield b"Hello" raise KeyboardInterrupt() yield b", world" # pragma: no cover async def aclose(self) -> None: nonlocal stream_was_closed stream_was_closed = True return httpx2.Response(200, headers={"Content-Length": "12"}, stream=CancelledStream()) transport = httpx2.MockTransport(response_with_cancel_during_stream) async with httpx2.AsyncClient(transport=transport) as client: with pytest.raises(KeyboardInterrupt): await client.get("https://www.example.com") assert stream_was_closed @pytest.mark.anyio async def test_server_extensions(server: TestServer) -> None: url = server.url async with httpx2.AsyncClient(http2=True) as client: response = await client.get(url) assert response.status_code == 200 assert response.extensions["http_version"] == b"HTTP/1.1" pydantic-httpx2-6dd59b9/tests/httpx2/client/test_auth.py000066400000000000000000000576351526547463400234670ustar00rootroot00000000000000""" Integration tests for authentication. Unit tests for auth classes also exist in tests/test_auth.py """ import hashlib import os import threading import typing from urllib.request import parse_keqv_list import anyio import pytest import httpx2 from ..common import FIXTURES_DIR class App: """ A mock app to test auth credentials. """ def __init__(self, auth_header: str = "", status_code: int = 200) -> None: self.auth_header = auth_header self.status_code = status_code def __call__(self, request: httpx2.Request) -> httpx2.Response: headers = {"www-authenticate": self.auth_header} if self.auth_header else {} data = {"auth": request.headers.get("Authorization")} return httpx2.Response(self.status_code, headers=headers, json=data) class DigestApp: def __init__( self, algorithm: str = "SHA-256", send_response_after_attempt: int = 1, qop: str = "auth", regenerate_nonce: bool = True, ) -> None: self.algorithm = algorithm self.send_response_after_attempt = send_response_after_attempt self.qop = qop self._regenerate_nonce = regenerate_nonce self._response_count = 0 def __call__(self, request: httpx2.Request) -> httpx2.Response: if self._response_count < self.send_response_after_attempt: return self.challenge_send(request) data = {"auth": request.headers.get("Authorization")} return httpx2.Response(200, json=data) def challenge_send(self, request: httpx2.Request) -> httpx2.Response: self._response_count += 1 nonce = ( hashlib.sha256(os.urandom(8)).hexdigest() if self._regenerate_nonce else "ee96edced2a0b43e4869e96ebe27563f369c1205a049d06419bb51d8aeddf3d3" ) challenge_data = { "nonce": nonce, "qop": self.qop, "opaque": ("ee6378f3ee14ebfd2fff54b70a91a7c9390518047f242ab2271380db0e14bda1"), "algorithm": self.algorithm, "stale": "FALSE", } challenge_str = ", ".join(f'{key}="{value}"' for key, value in challenge_data.items() if value) headers = { "www-authenticate": f'Digest realm="httpx@example.org", {challenge_str}', } return httpx2.Response(401, headers=headers) class RepeatAuth(httpx2.Auth): """ A mock authentication scheme that requires clients to send the request a fixed number of times, and then send a last request containing an aggregation of nonces that the server sent in 'WWW-Authenticate' headers of intermediate responses. """ requires_request_body = True def __init__(self, repeat: int) -> None: self.repeat = repeat def auth_flow(self, request: httpx2.Request) -> typing.Generator[httpx2.Request, httpx2.Response, None]: nonces: list[str] = [] for index in range(self.repeat): request.headers["Authorization"] = f"Repeat {index}" response = yield request nonces.append(response.headers["www-authenticate"]) key = ".".join(nonces) request.headers["Authorization"] = f"Repeat {key}" yield request class ResponseBodyAuth(httpx2.Auth): """ A mock authentication scheme that requires clients to send an 'Authorization' header, then send back the contents of the response in the 'Authorization' header. """ requires_response_body = True def __init__(self, token: str) -> None: self.token = token def auth_flow(self, request: httpx2.Request) -> typing.Generator[httpx2.Request, httpx2.Response, None]: request.headers["Authorization"] = self.token response = yield request data = response.text request.headers["Authorization"] = data yield request class SyncOrAsyncAuth(httpx2.Auth): """ A mock authentication scheme that uses a different implementation for the sync and async cases. """ def __init__(self) -> None: self._lock = threading.Lock() self._async_lock = anyio.Lock() def sync_auth_flow(self, request: httpx2.Request) -> typing.Generator[httpx2.Request, httpx2.Response, None]: with self._lock: request.headers["Authorization"] = "sync-auth" yield request async def async_auth_flow(self, request: httpx2.Request) -> typing.AsyncGenerator[httpx2.Request, httpx2.Response]: async with self._async_lock: request.headers["Authorization"] = "async-auth" yield request @pytest.mark.anyio async def test_basic_auth() -> None: url = "https://example.org/" auth = ("user", "password123") app = App() async with httpx2.AsyncClient(transport=httpx2.MockTransport(app)) as client: response = await client.get(url, auth=auth) assert response.status_code == 200 assert response.json() == {"auth": "Basic dXNlcjpwYXNzd29yZDEyMw=="} @pytest.mark.anyio async def test_basic_auth_with_stream() -> None: """ See: https://github.com/encode/httpx/pull/1312 """ url = "https://example.org/" auth = ("user", "password123") app = App() async with httpx2.AsyncClient(transport=httpx2.MockTransport(app), auth=auth) as client: async with client.stream("GET", url) as response: await response.aread() assert response.status_code == 200 assert response.json() == {"auth": "Basic dXNlcjpwYXNzd29yZDEyMw=="} @pytest.mark.anyio async def test_basic_auth_in_url() -> None: url = "https://user:password123@example.org/" app = App() async with httpx2.AsyncClient(transport=httpx2.MockTransport(app)) as client: response = await client.get(url) assert response.status_code == 200 assert response.json() == {"auth": "Basic dXNlcjpwYXNzd29yZDEyMw=="} @pytest.mark.anyio async def test_basic_auth_on_session() -> None: url = "https://example.org/" auth = ("user", "password123") app = App() async with httpx2.AsyncClient(transport=httpx2.MockTransport(app), auth=auth) as client: response = await client.get(url) assert response.status_code == 200 assert response.json() == {"auth": "Basic dXNlcjpwYXNzd29yZDEyMw=="} @pytest.mark.anyio async def test_custom_auth() -> None: url = "https://example.org/" app = App() def auth(request: httpx2.Request) -> httpx2.Request: request.headers["Authorization"] = "Token 123" return request async with httpx2.AsyncClient(transport=httpx2.MockTransport(app)) as client: response = await client.get(url, auth=auth) assert response.status_code == 200 assert response.json() == {"auth": "Token 123"} def test_netrc_auth_credentials_exist() -> None: """ When netrc auth is being used and a request is made to a host that is in the netrc file, then the relevant credentials should be applied. """ netrc_file = str(FIXTURES_DIR / ".netrc") url = "http://netrcexample.org" app = App() auth = httpx2.NetRCAuth(netrc_file) with httpx2.Client(transport=httpx2.MockTransport(app), auth=auth) as client: response = client.get(url) assert response.status_code == 200 assert response.json() == {"auth": "Basic ZXhhbXBsZS11c2VybmFtZTpleGFtcGxlLXBhc3N3b3Jk"} def test_netrc_auth_credentials_do_not_exist() -> None: """ When netrc auth is being used and a request is made to a host that is not in the netrc file, then no credentials should be applied. """ netrc_file = str(FIXTURES_DIR / ".netrc") url = "http://example.org" app = App() auth = httpx2.NetRCAuth(netrc_file) with httpx2.Client(transport=httpx2.MockTransport(app), auth=auth) as client: response = client.get(url) assert response.status_code == 200 assert response.json() == {"auth": None} @pytest.mark.anyio async def test_auth_disable_per_request() -> None: url = "https://example.org/" auth = ("user", "password123") app = App() async with httpx2.AsyncClient(transport=httpx2.MockTransport(app), auth=auth) as client: response = await client.get(url, auth=None) assert response.status_code == 200 assert response.json() == {"auth": None} def test_auth_hidden_url() -> None: url = "http://example-username:example-password@example.org/" expected = "URL('http://example-username:[secure]@example.org/')" assert url == httpx2.URL(url) assert expected == repr(httpx2.URL(url)) @pytest.mark.anyio async def test_auth_hidden_header() -> None: url = "https://example.org/" auth = ("example-username", "example-password") app = App() async with httpx2.AsyncClient(transport=httpx2.MockTransport(app)) as client: response = await client.get(url, auth=auth) assert "'authorization': '[secure]'" in str(response.request.headers) @pytest.mark.anyio async def test_auth_property() -> None: app = App() async with httpx2.AsyncClient(transport=httpx2.MockTransport(app)) as client: assert client.auth is None client.auth = ("user", "password123") assert isinstance(client.auth, httpx2.BasicAuth) url = "https://example.org/" response = await client.get(url) assert response.status_code == 200 assert response.json() == {"auth": "Basic dXNlcjpwYXNzd29yZDEyMw=="} @pytest.mark.anyio async def test_auth_invalid_type() -> None: app = App() with pytest.raises(TypeError): client = httpx2.AsyncClient( transport=httpx2.MockTransport(app), auth="not a tuple, not a callable", # type: ignore ) async with httpx2.AsyncClient(transport=httpx2.MockTransport(app)) as client: with pytest.raises(TypeError): await client.get(auth="not a tuple, not a callable") # type: ignore with pytest.raises(TypeError): client.auth = "not a tuple, not a callable" # type: ignore @pytest.mark.anyio async def test_digest_auth_returns_no_auth_if_no_digest_header_in_response() -> None: url = "https://example.org/" auth = httpx2.DigestAuth(username="user", password="password123") app = App() async with httpx2.AsyncClient(transport=httpx2.MockTransport(app)) as client: response = await client.get(url, auth=auth) assert response.status_code == 200 assert response.json() == {"auth": None} assert len(response.history) == 0 def test_digest_auth_returns_no_auth_if_alternate_auth_scheme() -> None: url = "https://example.org/" auth = httpx2.DigestAuth(username="user", password="password123") auth_header = "Token ..." app = App(auth_header=auth_header, status_code=401) client = httpx2.Client(transport=httpx2.MockTransport(app)) response = client.get(url, auth=auth) assert response.status_code == 401 assert response.json() == {"auth": None} assert len(response.history) == 0 @pytest.mark.anyio async def test_digest_auth_200_response_including_digest_auth_header() -> None: url = "https://example.org/" auth = httpx2.DigestAuth(username="user", password="password123") auth_header = 'Digest realm="realm@host.com",qop="auth",nonce="abc",opaque="xyz"' app = App(auth_header=auth_header, status_code=200) async with httpx2.AsyncClient(transport=httpx2.MockTransport(app)) as client: response = await client.get(url, auth=auth) assert response.status_code == 200 assert response.json() == {"auth": None} assert len(response.history) == 0 @pytest.mark.anyio async def test_digest_auth_401_response_without_digest_auth_header() -> None: url = "https://example.org/" auth = httpx2.DigestAuth(username="user", password="password123") app = App(auth_header="", status_code=401) async with httpx2.AsyncClient(transport=httpx2.MockTransport(app)) as client: response = await client.get(url, auth=auth) assert response.status_code == 401 assert response.json() == {"auth": None} assert len(response.history) == 0 @pytest.mark.parametrize( "algorithm,expected_hash_length,expected_response_length", [ ("MD5", 64, 32), ("MD5-SESS", 64, 32), ("SHA", 64, 40), ("SHA-SESS", 64, 40), ("SHA-256", 64, 64), ("SHA-256-SESS", 64, 64), ("SHA-512", 64, 128), ("SHA-512-SESS", 64, 128), ], ) @pytest.mark.anyio async def test_digest_auth(algorithm: str, expected_hash_length: int, expected_response_length: int) -> None: url = "https://example.org/" auth = httpx2.DigestAuth(username="user", password="password123") app = DigestApp(algorithm=algorithm) async with httpx2.AsyncClient(transport=httpx2.MockTransport(app)) as client: response = await client.get(url, auth=auth) assert response.status_code == 200 assert len(response.history) == 1 authorization = typing.cast(dict[str, typing.Any], response.json())["auth"] scheme, _, fields = authorization.partition(" ") assert scheme == "Digest" response_fields = [field.strip() for field in fields.split(",")] digest_data = dict(field.split("=") for field in response_fields) assert digest_data["username"] == '"user"' assert digest_data["realm"] == '"httpx@example.org"' assert "nonce" in digest_data assert digest_data["uri"] == '"/"' assert len(digest_data["response"]) == expected_response_length + 2 # extra quotes assert len(digest_data["opaque"]) == expected_hash_length + 2 assert digest_data["algorithm"] == algorithm assert digest_data["qop"] == "auth" assert digest_data["nc"] == "00000001" assert len(digest_data["cnonce"]) == 16 + 2 @pytest.mark.anyio async def test_digest_auth_no_specified_qop() -> None: url = "https://example.org/" auth = httpx2.DigestAuth(username="user", password="password123") app = DigestApp(qop="") async with httpx2.AsyncClient(transport=httpx2.MockTransport(app)) as client: response = await client.get(url, auth=auth) assert response.status_code == 200 assert len(response.history) == 1 authorization = typing.cast(dict[str, typing.Any], response.json())["auth"] scheme, _, fields = authorization.partition(" ") assert scheme == "Digest" response_fields = [field.strip() for field in fields.split(",")] digest_data = dict(field.split("=") for field in response_fields) assert "qop" not in digest_data assert "nc" not in digest_data assert "cnonce" not in digest_data assert digest_data["username"] == '"user"' assert digest_data["realm"] == '"httpx@example.org"' assert len(digest_data["nonce"]) == 64 + 2 # extra quotes assert digest_data["uri"] == '"/"' assert len(digest_data["response"]) == 64 + 2 assert len(digest_data["opaque"]) == 64 + 2 assert digest_data["algorithm"] == "SHA-256" @pytest.mark.parametrize("qop", ("auth, auth-int", "auth,auth-int", "unknown,auth")) @pytest.mark.anyio async def test_digest_auth_qop_including_spaces_and_auth_returns_auth(qop: str) -> None: url = "https://example.org/" auth = httpx2.DigestAuth(username="user", password="password123") app = DigestApp(qop=qop) async with httpx2.AsyncClient(transport=httpx2.MockTransport(app)) as client: response = await client.get(url, auth=auth) assert response.status_code == 200 assert len(response.history) == 1 @pytest.mark.anyio async def test_digest_auth_qop_auth_int_not_implemented() -> None: url = "https://example.org/" auth = httpx2.DigestAuth(username="user", password="password123") app = DigestApp(qop="auth-int") async with httpx2.AsyncClient(transport=httpx2.MockTransport(app)) as client: with pytest.raises(NotImplementedError): await client.get(url, auth=auth) @pytest.mark.anyio async def test_digest_auth_qop_must_be_auth_or_auth_int() -> None: url = "https://example.org/" auth = httpx2.DigestAuth(username="user", password="password123") app = DigestApp(qop="not-auth") async with httpx2.AsyncClient(transport=httpx2.MockTransport(app)) as client: with pytest.raises(httpx2.ProtocolError): await client.get(url, auth=auth) @pytest.mark.anyio async def test_digest_auth_incorrect_credentials() -> None: url = "https://example.org/" auth = httpx2.DigestAuth(username="user", password="password123") app = DigestApp(send_response_after_attempt=2) async with httpx2.AsyncClient(transport=httpx2.MockTransport(app)) as client: response = await client.get(url, auth=auth) assert response.status_code == 401 assert len(response.history) == 1 @pytest.mark.anyio async def test_digest_auth_reuses_challenge() -> None: url = "https://example.org/" auth = httpx2.DigestAuth(username="user", password="password123") app = DigestApp() async with httpx2.AsyncClient(transport=httpx2.MockTransport(app)) as client: response_1 = await client.get(url, auth=auth) response_2 = await client.get(url, auth=auth) assert response_1.status_code == 200 assert response_2.status_code == 200 assert len(response_1.history) == 1 assert len(response_2.history) == 0 @pytest.mark.anyio async def test_digest_auth_resets_nonce_count_after_401() -> None: url = "https://example.org/" auth = httpx2.DigestAuth(username="user", password="password123") app = DigestApp() async with httpx2.AsyncClient(transport=httpx2.MockTransport(app)) as client: response_1 = await client.get(url, auth=auth) assert response_1.status_code == 200 assert len(response_1.history) == 1 first_nonce = parse_keqv_list(response_1.request.headers["Authorization"].split(", "))["nonce"] first_nc = parse_keqv_list(response_1.request.headers["Authorization"].split(", "))["nc"] # with this we now force a 401 on a subsequent (but initial) request app.send_response_after_attempt = 2 # we expect the client again to try to authenticate, # i.e. the history length must be 1 response_2 = await client.get(url, auth=auth) assert response_2.status_code == 200 assert len(response_2.history) == 1 second_nonce = parse_keqv_list(response_2.request.headers["Authorization"].split(", "))["nonce"] second_nc = parse_keqv_list(response_2.request.headers["Authorization"].split(", "))["nc"] assert first_nonce != second_nonce # ensures that the auth challenge was reset assert first_nc == second_nc # ensures the nonce count is reset when the authentication failed @pytest.mark.parametrize( "auth_header", [ 'Digest realm="httpx@example.org", qop="auth"', # missing fields 'Digest realm="httpx@example.org", qop="auth,au', # malformed fields list ], ) @pytest.mark.anyio async def test_async_digest_auth_raises_protocol_error_on_malformed_header( auth_header: str, ) -> None: url = "https://example.org/" auth = httpx2.DigestAuth(username="user", password="password123") app = App(auth_header=auth_header, status_code=401) async with httpx2.AsyncClient(transport=httpx2.MockTransport(app)) as client: with pytest.raises(httpx2.ProtocolError): await client.get(url, auth=auth) @pytest.mark.parametrize( "auth_header", [ 'Digest realm="httpx@example.org", qop="auth"', # missing fields 'Digest realm="httpx@example.org", qop="auth,au', # malformed fields list ], ) def test_sync_digest_auth_raises_protocol_error_on_malformed_header( auth_header: str, ) -> None: url = "https://example.org/" auth = httpx2.DigestAuth(username="user", password="password123") app = App(auth_header=auth_header, status_code=401) with httpx2.Client(transport=httpx2.MockTransport(app)) as client: with pytest.raises(httpx2.ProtocolError): client.get(url, auth=auth) @pytest.mark.anyio async def test_async_auth_history() -> None: """ Test that intermediate requests sent as part of an authentication flow are recorded in the response history. """ url = "https://example.org/" auth = RepeatAuth(repeat=2) app = App(auth_header="abc") async with httpx2.AsyncClient(transport=httpx2.MockTransport(app)) as client: response = await client.get(url, auth=auth) assert response.status_code == 200 assert response.json() == {"auth": "Repeat abc.abc"} assert len(response.history) == 2 resp1, resp2 = response.history assert resp1.json() == {"auth": "Repeat 0"} assert resp2.json() == {"auth": "Repeat 1"} assert len(resp2.history) == 1 assert resp2.history == [resp1] assert len(resp1.history) == 0 def test_sync_auth_history() -> None: """ Test that intermediate requests sent as part of an authentication flow are recorded in the response history. """ url = "https://example.org/" auth = RepeatAuth(repeat=2) app = App(auth_header="abc") with httpx2.Client(transport=httpx2.MockTransport(app)) as client: response = client.get(url, auth=auth) assert response.status_code == 200 assert response.json() == {"auth": "Repeat abc.abc"} assert len(response.history) == 2 resp1, resp2 = response.history assert resp1.json() == {"auth": "Repeat 0"} assert resp2.json() == {"auth": "Repeat 1"} assert len(resp2.history) == 1 assert resp2.history == [resp1] assert len(resp1.history) == 0 class ConsumeBodyTransport(httpx2.MockTransport): async def handle_async_request(self, request: httpx2.Request) -> httpx2.Response: assert isinstance(request.stream, httpx2.AsyncByteStream) [_ async for _ in request.stream] return self.handler(request) # type: ignore[return-value] @pytest.mark.anyio async def test_digest_auth_unavailable_streaming_body() -> None: url = "https://example.org/" auth = httpx2.DigestAuth(username="user", password="password123") app = DigestApp() async def streaming_body() -> typing.AsyncIterator[bytes]: yield b"Example request body" # pragma: no cover async with httpx2.AsyncClient(transport=ConsumeBodyTransport(app)) as client: with pytest.raises(httpx2.StreamConsumed): await client.post(url, content=streaming_body(), auth=auth) @pytest.mark.anyio async def test_async_auth_reads_response_body() -> None: """ Test that we can read the response body in an auth flow if `requires_response_body` is set. """ url = "https://example.org/" auth = ResponseBodyAuth("xyz") app = App() async with httpx2.AsyncClient(transport=httpx2.MockTransport(app)) as client: response = await client.get(url, auth=auth) assert response.status_code == 200 assert response.json() == {"auth": '{"auth":"xyz"}'} def test_sync_auth_reads_response_body() -> None: """ Test that we can read the response body in an auth flow if `requires_response_body` is set. """ url = "https://example.org/" auth = ResponseBodyAuth("xyz") app = App() with httpx2.Client(transport=httpx2.MockTransport(app)) as client: response = client.get(url, auth=auth) assert response.status_code == 200 assert response.json() == {"auth": '{"auth":"xyz"}'} @pytest.mark.anyio async def test_async_auth() -> None: """ Test that we can use an auth implementation specific to the async case, to support cases that require performing I/O or using concurrency primitives (such as checking a disk-based cache or fetching a token from a remote auth server). """ url = "https://example.org/" auth = SyncOrAsyncAuth() app = App() async with httpx2.AsyncClient(transport=httpx2.MockTransport(app)) as client: response = await client.get(url, auth=auth) assert response.status_code == 200 assert response.json() == {"auth": "async-auth"} def test_sync_auth() -> None: """ Test that we can use an auth implementation specific to the sync case. """ url = "https://example.org/" auth = SyncOrAsyncAuth() app = App() with httpx2.Client(transport=httpx2.MockTransport(app)) as client: response = client.get(url, auth=auth) assert response.status_code == 200 assert response.json() == {"auth": "sync-auth"} pydantic-httpx2-6dd59b9/tests/httpx2/client/test_client.py000066400000000000000000000400021526547463400237600ustar00rootroot00000000000000from __future__ import annotations import typing from datetime import timedelta import chardet import pytest import httpx2 if typing.TYPE_CHECKING: from conftest import TestServer def autodetect(content: bytes) -> str | None: return chardet.detect(content).get("encoding") def test_get(server: TestServer) -> None: url = server.url with httpx2.Client(http2=True) as http: response = http.get(url) assert response.status_code == 200 assert response.url == url assert response.content == b"Hello, world!" assert response.text == "Hello, world!" assert response.http_version == "HTTP/1.1" assert response.encoding == "utf-8" assert response.request.url == url assert response.headers assert response.is_redirect is False assert repr(response) == "" assert response.elapsed > timedelta(0) @pytest.mark.parametrize( "url", [ pytest.param("invalid://example.org", id="scheme-not-http(s)"), pytest.param("://example.org", id="no-scheme"), pytest.param("http://", id="no-host"), ], ) def test_get_invalid_url(server: TestServer, url: str) -> None: with httpx2.Client() as client: with pytest.raises((httpx2.UnsupportedProtocol, httpx2.LocalProtocolError)): client.get(url) def test_build_request(server: TestServer) -> None: url = server.url.copy_with(path="/echo_headers") headers = {"Custom-header": "value"} with httpx2.Client() as client: request = client.build_request("GET", url) request.headers.update(headers) response = client.send(request) assert response.status_code == 200 assert response.url == url assert response.json()["Custom-header"] == "value" def test_build_post_request(server: TestServer) -> None: url = server.url.copy_with(path="/echo_headers") headers = {"Custom-header": "value"} with httpx2.Client() as client: request = client.build_request("POST", url) request.headers.update(headers) response = client.send(request) assert response.status_code == 200 assert response.url == url assert response.json()["Content-length"] == "0" assert response.json()["Custom-header"] == "value" def test_post(server: TestServer) -> None: with httpx2.Client() as client: response = client.post(server.url, content=b"Hello, world!") assert response.status_code == 200 assert response.reason_phrase == "OK" def test_post_json(server: TestServer) -> None: with httpx2.Client() as client: response = client.post(server.url, json={"text": "Hello, world!"}) assert response.status_code == 200 assert response.reason_phrase == "OK" def test_stream_response(server: TestServer) -> None: with httpx2.Client() as client: with client.stream("GET", server.url) as response: content = response.read() assert response.status_code == 200 assert content == b"Hello, world!" def test_stream_iterator(server: TestServer) -> None: body = b"" with httpx2.Client() as client: with client.stream("GET", server.url) as response: for chunk in response.iter_bytes(): body += chunk assert response.status_code == 200 assert body == b"Hello, world!" def test_raw_iterator(server: TestServer) -> None: body = b"" with httpx2.Client() as client: with client.stream("GET", server.url) as response: for chunk in response.iter_raw(): body += chunk assert response.status_code == 200 assert body == b"Hello, world!" def test_cannot_stream_async_request(server: TestServer) -> None: async def hello_world() -> typing.AsyncIterator[bytes]: # pragma: no cover yield b"Hello, " yield b"world!" with httpx2.Client() as client: with pytest.raises(RuntimeError): client.post(server.url, content=hello_world()) def test_raise_for_status(server: TestServer) -> None: with httpx2.Client() as client: for status_code in (200, 400, 404, 500, 505): response = client.request("GET", server.url.copy_with(path=f"/status/{status_code}")) if 400 <= status_code < 600: with pytest.raises(httpx2.HTTPStatusError) as exc_info: response.raise_for_status() assert exc_info.value.response == response assert exc_info.value.request.url.path == f"/status/{status_code}" else: assert response.raise_for_status() is response def test_options(server: TestServer) -> None: with httpx2.Client() as client: response = client.options(server.url) assert response.status_code == 200 assert response.reason_phrase == "OK" def test_head(server: TestServer) -> None: with httpx2.Client() as client: response = client.head(server.url) assert response.status_code == 200 assert response.reason_phrase == "OK" def test_put(server: TestServer) -> None: with httpx2.Client() as client: response = client.put(server.url, content=b"Hello, world!") assert response.status_code == 200 assert response.reason_phrase == "OK" def test_patch(server: TestServer) -> None: with httpx2.Client() as client: response = client.patch(server.url, content=b"Hello, world!") assert response.status_code == 200 assert response.reason_phrase == "OK" def test_delete(server: TestServer) -> None: with httpx2.Client() as client: response = client.delete(server.url) assert response.status_code == 200 assert response.reason_phrase == "OK" def test_query(server: TestServer) -> None: with httpx2.Client() as client: response = client.query(server.url, content=b"Hello, world!") assert response.status_code == 200 assert response.reason_phrase == "OK" def test_base_url(server: TestServer) -> None: base_url = server.url with httpx2.Client(base_url=base_url) as client: response = client.get("/") assert response.status_code == 200 assert response.url == base_url def test_merge_absolute_url() -> None: client = httpx2.Client(base_url="https://www.example.com/") request = client.build_request("GET", "http://www.example.com/") assert request.url == "http://www.example.com/" def test_merge_relative_url() -> None: client = httpx2.Client(base_url="https://www.example.com/") request = client.build_request("GET", "/testing/123") assert request.url == "https://www.example.com/testing/123" def test_merge_relative_url_with_path() -> None: client = httpx2.Client(base_url="https://www.example.com/some/path") request = client.build_request("GET", "/testing/123") assert request.url == "https://www.example.com/some/path/testing/123" def test_merge_relative_url_with_dotted_path() -> None: client = httpx2.Client(base_url="https://www.example.com/some/path") request = client.build_request("GET", "../testing/123") assert request.url == "https://www.example.com/some/testing/123" def test_merge_relative_url_with_path_including_colon() -> None: client = httpx2.Client(base_url="https://www.example.com/some/path") request = client.build_request("GET", "/testing:123") assert request.url == "https://www.example.com/some/path/testing:123" def test_merge_relative_url_with_encoded_slashes() -> None: client = httpx2.Client(base_url="https://www.example.com/") request = client.build_request("GET", "/testing%2F123") assert request.url == "https://www.example.com/testing%2F123" client = httpx2.Client(base_url="https://www.example.com/base%2Fpath") request = client.build_request("GET", "/testing") assert request.url == "https://www.example.com/base%2Fpath/testing" def test_context_managed_transport() -> None: class Transport(httpx2.BaseTransport): def __init__(self) -> None: self.events: list[str] = [] def close(self) -> None: # The base implementation of httpx2.BaseTransport just # calls into `.close`, so simple transport cases can just override # this method for any cleanup, where more complex cases # might want to additionally override `__enter__`/`__exit__`. self.events.append("transport.close") def __enter__(self) -> Transport: super().__enter__() self.events.append("transport.__enter__") return self def __exit__(self, *args: typing.Any) -> None: super().__exit__(*args) self.events.append("transport.__exit__") transport = Transport() with httpx2.Client(transport=transport): pass assert transport.events == [ "transport.__enter__", "transport.close", "transport.__exit__", ] def test_context_managed_transport_and_mount() -> None: class Transport(httpx2.BaseTransport): def __init__(self, name: str) -> None: self.name: str = name self.events: list[str] = [] def close(self) -> None: # The base implementation of httpx2.BaseTransport just # calls into `.close`, so simple transport cases can just override # this method for any cleanup, where more complex cases # might want to additionally override `__enter__`/`__exit__`. self.events.append(f"{self.name}.close") def __enter__(self) -> Transport: super().__enter__() self.events.append(f"{self.name}.__enter__") return self def __exit__(self, *args: typing.Any) -> None: super().__exit__(*args) self.events.append(f"{self.name}.__exit__") transport = Transport(name="transport") mounted = Transport(name="mounted") with httpx2.Client(transport=transport, mounts={"http://www.example.org": mounted}): pass assert transport.events == [ "transport.__enter__", "transport.close", "transport.__exit__", ] assert mounted.events == [ "mounted.__enter__", "mounted.close", "mounted.__exit__", ] def hello_world(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, text="Hello, world!") def test_client_closed_state_using_implicit_open() -> None: client = httpx2.Client(transport=httpx2.MockTransport(hello_world)) assert not client.is_closed client.get("http://example.com") assert not client.is_closed client.close() assert client.is_closed # Once we're close we cannot make any more requests. with pytest.raises(RuntimeError): client.get("http://example.com") # Once we're closed we cannot reopen the client. with pytest.raises(RuntimeError): with client: pass # pragma: no cover def test_client_closed_state_using_with_block() -> None: with httpx2.Client(transport=httpx2.MockTransport(hello_world)) as client: assert not client.is_closed client.get("http://example.com") assert client.is_closed with pytest.raises(RuntimeError): client.get("http://example.com") def echo_raw_headers(request: httpx2.Request) -> httpx2.Response: data = [(name.decode("ascii"), value.decode("ascii")) for name, value in request.headers.raw] return httpx2.Response(200, json=data) def test_raw_client_header() -> None: """ Set a header in the Client. """ url = "http://example.org/echo_headers" headers = {"Example-Header": "example-value"} client = httpx2.Client(transport=httpx2.MockTransport(echo_raw_headers), headers=headers) response = client.get(url) assert response.status_code == 200 assert response.json() == [ ["Host", "example.org"], ["Accept", "*/*"], ["Accept-Encoding", "gzip, deflate, br, zstd"], ["Connection", "keep-alive"], ["User-Agent", f"python-httpx2/{httpx2.__version__}"], ["Example-Header", "example-value"], ] def unmounted(request: httpx2.Request) -> httpx2.Response: data = {"app": "unmounted"} return httpx2.Response(200, json=data) def mounted(request: httpx2.Request) -> httpx2.Response: data = {"app": "mounted"} return httpx2.Response(200, json=data) def test_mounted_transport() -> None: transport = httpx2.MockTransport(unmounted) mounts = {"custom://": httpx2.MockTransport(mounted)} client = httpx2.Client(transport=transport, mounts=mounts) response = client.get("https://www.example.com") assert response.status_code == 200 assert response.json() == {"app": "unmounted"} response = client.get("custom://www.example.com") assert response.status_code == 200 assert response.json() == {"app": "mounted"} def test_all_mounted_transport() -> None: mounts = {"all://": httpx2.MockTransport(mounted)} client = httpx2.Client(mounts=mounts) response = client.get("https://www.example.com") assert response.status_code == 200 assert response.json() == {"app": "mounted"} def test_server_extensions(server: TestServer) -> None: url = server.url.copy_with(path="/http_version_2") with httpx2.Client(http2=True) as client: response = client.get(url) assert response.status_code == 200 assert response.extensions["http_version"] == b"HTTP/1.1" def test_client_decode_text_using_autodetect() -> None: # Ensure that a 'default_encoding=autodetect' on the response allows for # encoding autodetection to be used when no "Content-Type: text/plain; charset=..." # info is present. # # Here we have some french text encoded with WINDOWS-1252, rather than UTF-8. # The curly quotes and em dash occupy bytes 0x80-0x9F, which are control # characters in ISO-8859-1, so the encoding is unambiguously WINDOWS-1252. text = ( "Non-seulement Desprรฉaux ne se trompait pas โ€” mais de tous les รฉcrivains " "que la France a produits, sans excepter Voltaire lui-mรชme, imprรฉgnรฉ de " "lโ€™esprit anglais par son sรฉjour ร  Londres, cโ€™est incontestablement " "โ€œMoliรจreโ€ ou Poquelin qui reproduit avec lโ€™exactitude la plus vive et la " "plus complรจte le fond du gรฉnie franรงais." ) def cp1252_but_no_content_type(request: httpx2.Request) -> httpx2.Response: content = text.encode("WINDOWS-1252") return httpx2.Response(200, content=content) transport = httpx2.MockTransport(cp1252_but_no_content_type) with httpx2.Client(transport=transport, default_encoding=autodetect) as client: response = client.get("http://www.example.com") assert response.status_code == 200 assert response.reason_phrase == "OK" assert response.encoding == "Windows-1252" assert response.text == text def test_client_decode_text_using_explicit_encoding() -> None: # Ensure that a 'default_encoding="..."' on the response is used for text decoding # when no "Content-Type: text/plain; charset=..."" info is present. # # Here we have some french text encoded with WINDOWS-1252, rather than UTF-8. # The curly quotes and em dash occupy bytes 0x80-0x9F, which are control # characters in ISO-8859-1, so the encoding is unambiguously WINDOWS-1252. text = ( "Non-seulement Desprรฉaux ne se trompait pas โ€” mais de tous les รฉcrivains " "que la France a produits, sans excepter Voltaire lui-mรชme, imprรฉgnรฉ de " "lโ€™esprit anglais par son sรฉjour ร  Londres, cโ€™est incontestablement " "โ€œMoliรจreโ€ ou Poquelin qui reproduit avec lโ€™exactitude la plus vive et la " "plus complรจte le fond du gรฉnie franรงais." ) def cp1252_but_no_content_type(request: httpx2.Request) -> httpx2.Response: content = text.encode("WINDOWS-1252") return httpx2.Response(200, content=content) transport = httpx2.MockTransport(cp1252_but_no_content_type) with httpx2.Client(transport=transport, default_encoding=autodetect) as client: response = client.get("http://www.example.com") assert response.status_code == 200 assert response.reason_phrase == "OK" assert response.encoding == "Windows-1252" assert response.text == text pydantic-httpx2-6dd59b9/tests/httpx2/client/test_cookies.py000066400000000000000000000115231526547463400241440ustar00rootroot00000000000000from http.cookiejar import Cookie, CookieJar import pytest import httpx2 def get_and_set_cookies(request: httpx2.Request) -> httpx2.Response: if request.url.path == "/echo_cookies": data = {"cookies": request.headers.get("cookie")} return httpx2.Response(200, json=data) elif request.url.path == "/set_cookie": headers = {"set-cookie": "example-name=example-value"} return httpx2.Response(200, headers=headers) else: raise NotImplementedError() # pragma: no cover def test_set_cookie() -> None: """ Send a request including a cookie. """ url = "http://example.org/echo_cookies" cookies = {"example-name": "example-value"} client = httpx2.Client(cookies=cookies, transport=httpx2.MockTransport(get_and_set_cookies)) response = client.get(url) assert response.status_code == 200 assert response.json() == {"cookies": "example-name=example-value"} def test_set_per_request_cookie_is_deprecated() -> None: """ Sending a request including a per-request cookie is deprecated. """ url = "http://example.org/echo_cookies" cookies = {"example-name": "example-value"} client = httpx2.Client(transport=httpx2.MockTransport(get_and_set_cookies)) with pytest.warns(DeprecationWarning): response = client.get(url, cookies=cookies) assert response.status_code == 200 assert response.json() == {"cookies": "example-name=example-value"} def test_set_cookie_with_cookiejar() -> None: """ Send a request including a cookie, using a `CookieJar` instance. """ url = "http://example.org/echo_cookies" cookies = CookieJar() cookie = Cookie( version=0, name="example-name", value="example-value", port=None, port_specified=False, domain="", domain_specified=False, domain_initial_dot=False, path="/", path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={"HttpOnly": ""}, rfc2109=False, ) cookies.set_cookie(cookie) client = httpx2.Client(cookies=cookies, transport=httpx2.MockTransport(get_and_set_cookies)) response = client.get(url) assert response.status_code == 200 assert response.json() == {"cookies": "example-name=example-value"} def test_setting_client_cookies_to_cookiejar() -> None: """ Send a request including a cookie, using a `CookieJar` instance. """ url = "http://example.org/echo_cookies" cookies = CookieJar() cookie = Cookie( version=0, name="example-name", value="example-value", port=None, port_specified=False, domain="", domain_specified=False, domain_initial_dot=False, path="/", path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={"HttpOnly": ""}, rfc2109=False, ) cookies.set_cookie(cookie) client = httpx2.Client(cookies=cookies, transport=httpx2.MockTransport(get_and_set_cookies)) response = client.get(url) assert response.status_code == 200 assert response.json() == {"cookies": "example-name=example-value"} def test_set_cookie_with_cookies_model() -> None: """ Send a request including a cookie, using a `Cookies` instance. """ url = "http://example.org/echo_cookies" cookies = httpx2.Cookies() cookies["example-name"] = "example-value" client = httpx2.Client(transport=httpx2.MockTransport(get_and_set_cookies)) client.cookies = cookies response = client.get(url) assert response.status_code == 200 assert response.json() == {"cookies": "example-name=example-value"} def test_get_cookie() -> None: url = "http://example.org/set_cookie" client = httpx2.Client(transport=httpx2.MockTransport(get_and_set_cookies)) response = client.get(url) assert response.status_code == 200 assert response.cookies["example-name"] == "example-value" assert client.cookies["example-name"] == "example-value" def test_cookie_persistence() -> None: """ Ensure that Client instances persist cookies between requests. """ client = httpx2.Client(transport=httpx2.MockTransport(get_and_set_cookies)) response = client.get("http://example.org/echo_cookies") assert response.status_code == 200 assert response.json() == {"cookies": None} response = client.get("http://example.org/set_cookie") assert response.status_code == 200 assert response.cookies["example-name"] == "example-value" assert client.cookies["example-name"] == "example-value" response = client.get("http://example.org/echo_cookies") assert response.status_code == 200 assert response.json() == {"cookies": "example-name=example-value"} pydantic-httpx2-6dd59b9/tests/httpx2/client/test_event_hooks.py000066400000000000000000000171641526547463400250430ustar00rootroot00000000000000from __future__ import annotations import typing import pytest import httpx2 if typing.TYPE_CHECKING: from conftest import TestServer def app(request: httpx2.Request) -> httpx2.Response: if request.url.path == "/redirect": return httpx2.Response(303, headers={"server": "testserver", "location": "/"}) elif request.url.path.startswith("/status/"): status_code = int(request.url.path[-3:]) return httpx2.Response(status_code, headers={"server": "testserver"}) return httpx2.Response(200, headers={"server": "testserver"}) def test_event_hooks() -> None: events = [] def on_request(request: httpx2.Request) -> None: events.append({"event": "request", "headers": dict(request.headers)}) def on_response(response: httpx2.Response) -> None: events.append({"event": "response", "headers": dict(response.headers)}) event_hooks: dict[str, list[typing.Callable[..., typing.Any]]] = { "request": [on_request], "response": [on_response], } with httpx2.Client(event_hooks=event_hooks, transport=httpx2.MockTransport(app)) as http: http.get("http://127.0.0.1:8000/", auth=("username", "password")) assert events == [ { "event": "request", "headers": { "host": "127.0.0.1:8000", "user-agent": f"python-httpx2/{httpx2.__version__}", "accept": "*/*", "accept-encoding": "gzip, deflate, br, zstd", "connection": "keep-alive", "authorization": "Basic dXNlcm5hbWU6cGFzc3dvcmQ=", }, }, { "event": "response", "headers": {"server": "testserver"}, }, ] def test_event_hooks_raising_exception(server: TestServer) -> None: def raise_on_4xx_5xx(response: httpx2.Response) -> None: response.raise_for_status() event_hooks = {"response": [raise_on_4xx_5xx]} with httpx2.Client(event_hooks=event_hooks, transport=httpx2.MockTransport(app)) as http: try: http.get("http://127.0.0.1:8000/status/400") except httpx2.HTTPStatusError as exc: assert exc.response.is_closed @pytest.mark.anyio async def test_async_event_hooks() -> None: events = [] async def on_request(request: httpx2.Request) -> None: events.append({"event": "request", "headers": dict(request.headers)}) async def on_response(response: httpx2.Response) -> None: events.append({"event": "response", "headers": dict(response.headers)}) event_hooks: dict[str, list[typing.Callable[..., typing.Any]]] = { "request": [on_request], "response": [on_response], } async with httpx2.AsyncClient(event_hooks=event_hooks, transport=httpx2.MockTransport(app)) as http: await http.get("http://127.0.0.1:8000/", auth=("username", "password")) assert events == [ { "event": "request", "headers": { "host": "127.0.0.1:8000", "user-agent": f"python-httpx2/{httpx2.__version__}", "accept": "*/*", "accept-encoding": "gzip, deflate, br, zstd", "connection": "keep-alive", "authorization": "Basic dXNlcm5hbWU6cGFzc3dvcmQ=", }, }, { "event": "response", "headers": {"server": "testserver"}, }, ] @pytest.mark.anyio async def test_async_event_hooks_raising_exception() -> None: async def raise_on_4xx_5xx(response: httpx2.Response) -> None: response.raise_for_status() event_hooks = {"response": [raise_on_4xx_5xx]} async with httpx2.AsyncClient(event_hooks=event_hooks, transport=httpx2.MockTransport(app)) as http: try: await http.get("http://127.0.0.1:8000/status/400") except httpx2.HTTPStatusError as exc: assert exc.response.is_closed def test_event_hooks_with_redirect() -> None: """ A redirect request should trigger additional 'request' and 'response' event hooks. """ events = [] def on_request(request: httpx2.Request) -> None: events.append({"event": "request", "headers": dict(request.headers)}) def on_response(response: httpx2.Response) -> None: events.append({"event": "response", "headers": dict(response.headers)}) event_hooks: dict[str, list[typing.Callable[..., typing.Any]]] = { "request": [on_request], "response": [on_response], } with httpx2.Client( event_hooks=event_hooks, transport=httpx2.MockTransport(app), follow_redirects=True, ) as http: http.get("http://127.0.0.1:8000/redirect", auth=("username", "password")) assert events == [ { "event": "request", "headers": { "host": "127.0.0.1:8000", "user-agent": f"python-httpx2/{httpx2.__version__}", "accept": "*/*", "accept-encoding": "gzip, deflate, br, zstd", "connection": "keep-alive", "authorization": "Basic dXNlcm5hbWU6cGFzc3dvcmQ=", }, }, { "event": "response", "headers": {"location": "/", "server": "testserver"}, }, { "event": "request", "headers": { "host": "127.0.0.1:8000", "user-agent": f"python-httpx2/{httpx2.__version__}", "accept": "*/*", "accept-encoding": "gzip, deflate, br, zstd", "connection": "keep-alive", "authorization": "Basic dXNlcm5hbWU6cGFzc3dvcmQ=", }, }, { "event": "response", "headers": {"server": "testserver"}, }, ] @pytest.mark.anyio async def test_async_event_hooks_with_redirect() -> None: """ A redirect request should trigger additional 'request' and 'response' event hooks. """ events = [] async def on_request(request: httpx2.Request) -> None: events.append({"event": "request", "headers": dict(request.headers)}) async def on_response(response: httpx2.Response) -> None: events.append({"event": "response", "headers": dict(response.headers)}) event_hooks: dict[str, list[typing.Callable[..., typing.Any]]] = { "request": [on_request], "response": [on_response], } async with httpx2.AsyncClient( event_hooks=event_hooks, transport=httpx2.MockTransport(app), follow_redirects=True, ) as http: await http.get("http://127.0.0.1:8000/redirect", auth=("username", "password")) assert events == [ { "event": "request", "headers": { "host": "127.0.0.1:8000", "user-agent": f"python-httpx2/{httpx2.__version__}", "accept": "*/*", "accept-encoding": "gzip, deflate, br, zstd", "connection": "keep-alive", "authorization": "Basic dXNlcm5hbWU6cGFzc3dvcmQ=", }, }, { "event": "response", "headers": {"location": "/", "server": "testserver"}, }, { "event": "request", "headers": { "host": "127.0.0.1:8000", "user-agent": f"python-httpx2/{httpx2.__version__}", "accept": "*/*", "accept-encoding": "gzip, deflate, br, zstd", "connection": "keep-alive", "authorization": "Basic dXNlcm5hbWU6cGFzc3dvcmQ=", }, }, { "event": "response", "headers": {"server": "testserver"}, }, ] pydantic-httpx2-6dd59b9/tests/httpx2/client/test_headers.py000077500000000000000000000235541526547463400241350ustar00rootroot00000000000000#!/usr/bin/env python3 import pytest import httpx2 def echo_headers(request: httpx2.Request) -> httpx2.Response: data = {"headers": dict(request.headers)} return httpx2.Response(200, json=data) def echo_repeated_headers_multi_items(request: httpx2.Request) -> httpx2.Response: data = {"headers": list(request.headers.multi_items())} return httpx2.Response(200, json=data) def echo_repeated_headers_items(request: httpx2.Request) -> httpx2.Response: data = {"headers": list(request.headers.items())} return httpx2.Response(200, json=data) def test_client_header() -> None: """ Set a header in the Client. """ url = "http://example.org/echo_headers" headers = {"Example-Header": "example-value"} transport = httpx2.MockTransport(echo_headers) client = httpx2.Client(transport=transport, headers=headers) response = client.get(url) assert response.status_code == 200 assert response.json() == { "headers": { "accept": "*/*", "accept-encoding": "gzip, deflate, br, zstd", "connection": "keep-alive", "example-header": "example-value", "host": "example.org", "user-agent": f"python-httpx2/{httpx2.__version__}", } } def test_header_merge() -> None: url = "http://example.org/echo_headers" client_headers = {"User-Agent": "python-myclient/0.2.1"} request_headers = {"X-Auth-Token": "FooBarBazToken"} client = httpx2.Client(transport=httpx2.MockTransport(echo_headers), headers=client_headers) response = client.get(url, headers=request_headers) assert response.status_code == 200 assert response.json() == { "headers": { "accept": "*/*", "accept-encoding": "gzip, deflate, br, zstd", "connection": "keep-alive", "host": "example.org", "user-agent": "python-myclient/0.2.1", "x-auth-token": "FooBarBazToken", } } def test_header_merge_conflicting_headers() -> None: url = "http://example.org/echo_headers" client_headers = {"X-Auth-Token": "FooBar"} request_headers = {"X-Auth-Token": "BazToken"} client = httpx2.Client(transport=httpx2.MockTransport(echo_headers), headers=client_headers) response = client.get(url, headers=request_headers) assert response.status_code == 200 assert response.json() == { "headers": { "accept": "*/*", "accept-encoding": "gzip, deflate, br, zstd", "connection": "keep-alive", "host": "example.org", "user-agent": f"python-httpx2/{httpx2.__version__}", "x-auth-token": "BazToken", } } def test_header_update() -> None: url = "http://example.org/echo_headers" client = httpx2.Client(transport=httpx2.MockTransport(echo_headers)) first_response = client.get(url) client.headers.update({"User-Agent": "python-myclient/0.2.1", "Another-Header": "AThing"}) second_response = client.get(url) assert first_response.status_code == 200 assert first_response.json() == { "headers": { "accept": "*/*", "accept-encoding": "gzip, deflate, br, zstd", "connection": "keep-alive", "host": "example.org", "user-agent": f"python-httpx2/{httpx2.__version__}", } } assert second_response.status_code == 200 assert second_response.json() == { "headers": { "accept": "*/*", "accept-encoding": "gzip, deflate, br, zstd", "another-header": "AThing", "connection": "keep-alive", "host": "example.org", "user-agent": "python-myclient/0.2.1", } } def test_header_repeated_items() -> None: url = "http://example.org/echo_headers" client = httpx2.Client(transport=httpx2.MockTransport(echo_repeated_headers_items)) response = client.get(url, headers=[("x-header", "1"), ("x-header", "2,3")]) assert response.status_code == 200 echoed_headers = response.json()["headers"] # as per RFC 7230, the whitespace after a comma is insignificant # so we split and strip here so that we can do a safe comparison assert ["x-header", ["1", "2", "3"]] in [[k, [subv.lstrip() for subv in v.split(",")]] for k, v in echoed_headers] def test_header_repeated_multi_items() -> None: url = "http://example.org/echo_headers" client = httpx2.Client(transport=httpx2.MockTransport(echo_repeated_headers_multi_items)) response = client.get(url, headers=[("x-header", "1"), ("x-header", "2,3")]) assert response.status_code == 200 echoed_headers = response.json()["headers"] assert ["x-header", "1"] in echoed_headers assert ["x-header", "2,3"] in echoed_headers def test_remove_default_header() -> None: """ Remove a default header from the Client. """ url = "http://example.org/echo_headers" client = httpx2.Client(transport=httpx2.MockTransport(echo_headers)) del client.headers["User-Agent"] response = client.get(url) assert response.status_code == 200 assert response.json() == { "headers": { "accept": "*/*", "accept-encoding": "gzip, deflate, br, zstd", "connection": "keep-alive", "host": "example.org", } } def test_header_does_not_exist() -> None: headers = httpx2.Headers({"foo": "bar"}) with pytest.raises(KeyError): del headers["baz"] def test_header_with_incorrect_value() -> None: with pytest.raises( TypeError, match=f"Header value must be str or bytes, not {type(None)}", ): httpx2.Headers({"foo": None}) # type: ignore def test_host_with_auth_and_port_in_url() -> None: """ The Host header should only include the hostname, or hostname:port (for non-default ports only). Any userinfo or default port should not be present. """ url = "http://username:password@example.org:80/echo_headers" client = httpx2.Client(transport=httpx2.MockTransport(echo_headers)) response = client.get(url) assert response.status_code == 200 assert response.json() == { "headers": { "accept": "*/*", "accept-encoding": "gzip, deflate, br, zstd", "connection": "keep-alive", "host": "example.org", "user-agent": f"python-httpx2/{httpx2.__version__}", "authorization": "Basic dXNlcm5hbWU6cGFzc3dvcmQ=", } } def test_host_with_non_default_port_in_url() -> None: """ If the URL includes a non-default port, then it should be included in the Host header. """ url = "http://username:password@example.org:123/echo_headers" client = httpx2.Client(transport=httpx2.MockTransport(echo_headers)) response = client.get(url) assert response.status_code == 200 assert response.json() == { "headers": { "accept": "*/*", "accept-encoding": "gzip, deflate, br, zstd", "connection": "keep-alive", "host": "example.org:123", "user-agent": f"python-httpx2/{httpx2.__version__}", "authorization": "Basic dXNlcm5hbWU6cGFzc3dvcmQ=", } } def test_request_auto_headers() -> None: request = httpx2.Request("GET", "https://www.example.org/") assert "host" in request.headers def test_same_origin() -> None: origin = httpx2.URL("https://example.com") request = httpx2.Request("GET", "HTTPS://EXAMPLE.COM:443") client = httpx2.Client() headers = client._redirect_headers(request, origin, "GET") assert headers["Host"] == request.url.netloc.decode("ascii") def test_same_origin_with_equivalent_ipv6_addresses() -> None: origin = httpx2.URL("https://[0:0:0:0:0:0:0:1]/redirected") request = httpx2.Request("GET", "https://[::1]/", headers={"Authorization": "secret"}) client = httpx2.Client() headers = client._redirect_headers(request, origin, "GET") assert headers["Authorization"] == "secret" def test_not_same_origin() -> None: origin = httpx2.URL("https://example.com") request = httpx2.Request("GET", "HTTP://EXAMPLE.COM:80") client = httpx2.Client() headers = client._redirect_headers(request, origin, "GET") assert headers["Host"] == origin.netloc.decode("ascii") def test_not_same_origin_with_percent_encoded_ipv6_scope() -> None: origin = httpx2.URL("https://[2001:db8::10]") request = httpx2.Request("GET", "https://[2001:db8::1%30]", headers={"Authorization": "secret"}) client = httpx2.Client() headers = client._redirect_headers(request, origin, "GET") assert "Authorization" not in headers def test_is_https_redirect() -> None: url = httpx2.URL("https://example.com") request = httpx2.Request("GET", "http://example.com", headers={"Authorization": "empty"}) client = httpx2.Client() headers = client._redirect_headers(request, url, "GET") assert "Authorization" in headers def test_is_https_redirect_with_equivalent_ipv6_addresses() -> None: url = httpx2.URL("https://[0:0:0:0:0:0:0:1]") request = httpx2.Request("GET", "http://[::1]", headers={"Authorization": "secret"}) client = httpx2.Client() headers = client._redirect_headers(request, url, "GET") assert headers["Authorization"] == "secret" def test_is_not_https_redirect() -> None: url = httpx2.URL("https://www.example.com") request = httpx2.Request("GET", "http://example.com", headers={"Authorization": "empty"}) client = httpx2.Client() headers = client._redirect_headers(request, url, "GET") assert "Authorization" not in headers def test_is_not_https_redirect_if_not_default_ports() -> None: url = httpx2.URL("https://example.com:1337") request = httpx2.Request("GET", "http://example.com:9999", headers={"Authorization": "empty"}) client = httpx2.Client() headers = client._redirect_headers(request, url, "GET") assert "Authorization" not in headers pydantic-httpx2-6dd59b9/tests/httpx2/client/test_properties.py000066400000000000000000000041041526547463400247010ustar00rootroot00000000000000from __future__ import annotations import httpx2 def test_client_base_url() -> None: client = httpx2.Client() client.base_url = "https://www.example.org/" assert isinstance(client.base_url, httpx2.URL) assert client.base_url == "https://www.example.org/" def test_client_base_url_without_trailing_slash() -> None: client = httpx2.Client() client.base_url = "https://www.example.org/path" assert isinstance(client.base_url, httpx2.URL) assert client.base_url == "https://www.example.org/path/" def test_client_base_url_with_trailing_slash() -> None: client = httpx2.Client() client.base_url = "https://www.example.org/path/" assert isinstance(client.base_url, httpx2.URL) assert client.base_url == "https://www.example.org/path/" def test_client_headers() -> None: client = httpx2.Client() client.headers = {"a": "b"} assert isinstance(client.headers, httpx2.Headers) assert client.headers["A"] == "b" def test_client_cookies() -> None: client = httpx2.Client() client.cookies = {"a": "b"} assert isinstance(client.cookies, httpx2.Cookies) mycookies = list(client.cookies.jar) assert len(mycookies) == 1 assert mycookies[0].name == "a" and mycookies[0].value == "b" def test_client_timeout() -> None: expected_timeout = 12.0 client = httpx2.Client() client.timeout = expected_timeout assert isinstance(client.timeout, httpx2.Timeout) assert client.timeout.connect == expected_timeout assert client.timeout.read == expected_timeout assert client.timeout.write == expected_timeout assert client.timeout.pool == expected_timeout def test_client_event_hooks() -> None: def on_request(request: httpx2.Request) -> None: pass # pragma: no cover client = httpx2.Client() client.event_hooks = {"request": [on_request]} assert client.event_hooks == {"request": [on_request], "response": []} def test_client_trust_env() -> None: client = httpx2.Client() assert client.trust_env client = httpx2.Client(trust_env=False) assert not client.trust_env pydantic-httpx2-6dd59b9/tests/httpx2/client/test_proxies.py000066400000000000000000000270161526547463400242050ustar00rootroot00000000000000from __future__ import annotations import typing import pytest import httpcore2 import httpx2 def url_to_origin(url: str) -> httpcore2.URL: """ Given a URL string, return the origin in the raw tuple format that `httpcore` uses for it's representation. """ u = httpx2.URL(url) return httpcore2.URL(scheme=u.raw_scheme, host=u.raw_host, port=u.port, target="/") def test_socks_proxy() -> None: url = httpx2.URL("http://www.example.com") for proxy in ("socks5://localhost/", "socks5h://localhost/"): client = httpx2.Client(proxy=proxy) transport = client._transport_for_url(url) assert isinstance(transport, httpx2.HTTPTransport) assert isinstance(transport._pool, httpcore2.SOCKSProxy) async_client = httpx2.AsyncClient(proxy=proxy) async_transport = async_client._transport_for_url(url) assert isinstance(async_transport, httpx2.AsyncHTTPTransport) assert isinstance(async_transport._pool, httpcore2.AsyncSOCKSProxy) PROXY_URL = "http://[::1]" @pytest.mark.parametrize( ["url", "proxies", "expected"], [ ("http://example.com", {}, None), ("http://example.com", {"https://": PROXY_URL}, None), ("http://example.com", {"http://example.net": PROXY_URL}, None), # Using "*" should match any domain name. ("http://example.com", {"http://*": PROXY_URL}, PROXY_URL), ("https://example.com", {"http://*": PROXY_URL}, None), # Using "example.com" should match example.com, but not www.example.com ("http://example.com", {"http://example.com": PROXY_URL}, PROXY_URL), ("http://www.example.com", {"http://example.com": PROXY_URL}, None), # Using "*.example.com" should match www.example.com, but not example.com ("http://example.com", {"http://*.example.com": PROXY_URL}, None), ("http://www.example.com", {"http://*.example.com": PROXY_URL}, PROXY_URL), # Using "*example.com" should match example.com and www.example.com ("http://example.com", {"http://*example.com": PROXY_URL}, PROXY_URL), ("http://www.example.com", {"http://*example.com": PROXY_URL}, PROXY_URL), ("http://wwwexample.com", {"http://*example.com": PROXY_URL}, None), # ... ("http://example.com:443", {"http://example.com": PROXY_URL}, PROXY_URL), ("http://example.com", {"all://": PROXY_URL}, PROXY_URL), ("http://example.com", {"http://": PROXY_URL}, PROXY_URL), ("http://example.com", {"all://example.com": PROXY_URL}, PROXY_URL), ("http://example.com", {"http://example.com": PROXY_URL}, PROXY_URL), ("http://example.com", {"http://example.com:80": PROXY_URL}, PROXY_URL), ("http://example.com:8080", {"http://example.com:8080": PROXY_URL}, PROXY_URL), ("http://example.com:8080", {"http://example.com": PROXY_URL}, PROXY_URL), ( "http://example.com", { "all://": PROXY_URL + ":1", "http://": PROXY_URL + ":2", "all://example.com": PROXY_URL + ":3", "http://example.com": PROXY_URL + ":4", }, PROXY_URL + ":4", ), ( "http://example.com", { "all://": PROXY_URL + ":1", "http://": PROXY_URL + ":2", "all://example.com": PROXY_URL + ":3", }, PROXY_URL + ":3", ), ( "http://example.com", {"all://": PROXY_URL + ":1", "http://": PROXY_URL + ":2"}, PROXY_URL + ":2", ), ], ) def test_transport_for_request(url: str, proxies: dict[str, str], expected: str | None) -> None: mounts = {key: httpx2.HTTPTransport(proxy=value) for key, value in proxies.items()} client = httpx2.Client(mounts=mounts) transport = client._transport_for_url(httpx2.URL(url)) if expected is None: assert transport is client._transport else: assert isinstance(transport, httpx2.HTTPTransport) assert isinstance(transport._pool, httpcore2.HTTPProxy) assert transport._pool._proxy_url == url_to_origin(expected) @pytest.mark.anyio @pytest.mark.network async def test_async_proxy_close() -> None: transport = httpx2.AsyncHTTPTransport(proxy=PROXY_URL) client = httpx2.AsyncClient(mounts={"https://": transport}) try: await client.get("http://example.com") finally: await client.aclose() @pytest.mark.network def test_sync_proxy_close() -> None: transport = httpx2.HTTPTransport(proxy=PROXY_URL) client = httpx2.Client(mounts={"https://": transport}) try: client.get("http://example.com") finally: client.close() def test_unsupported_proxy_scheme() -> None: with pytest.raises(ValueError): httpx2.Client(proxy="ftp://127.0.0.1") @pytest.mark.parametrize( ["url", "env", "expected"], [ ("http://google.com", {}, None), ( "http://google.com", {"HTTP_PROXY": "http://example.com"}, "http://example.com", ), # Auto prepend http scheme ("http://google.com", {"HTTP_PROXY": "example.com"}, "http://example.com"), ( "http://google.com", {"HTTP_PROXY": "http://example.com", "NO_PROXY": "google.com"}, None, ), # Everything proxied when NO_PROXY is empty/unset ( "http://127.0.0.1", {"ALL_PROXY": "http://localhost:123", "NO_PROXY": ""}, "http://localhost:123", ), # Not proxied if NO_PROXY matches URL. ( "http://127.0.0.1", {"ALL_PROXY": "http://localhost:123", "NO_PROXY": "127.0.0.1"}, None, ), # Proxied if NO_PROXY scheme does not match URL. ( "http://127.0.0.1", {"ALL_PROXY": "http://localhost:123", "NO_PROXY": "https://127.0.0.1"}, "http://localhost:123", ), # Proxied if NO_PROXY scheme does not match host. ( "http://127.0.0.1", {"ALL_PROXY": "http://localhost:123", "NO_PROXY": "1.1.1.1"}, "http://localhost:123", ), # Not proxied if NO_PROXY matches host domain suffix. ( "http://courses.mit.edu", {"ALL_PROXY": "http://localhost:123", "NO_PROXY": "mit.edu"}, None, ), # Proxied even though NO_PROXY matches host domain *prefix*. ( "https://mit.edu.info", {"ALL_PROXY": "http://localhost:123", "NO_PROXY": "mit.edu"}, "http://localhost:123", ), # Not proxied if one item in NO_PROXY case matches host domain suffix. ( "https://mit.edu.info", {"ALL_PROXY": "http://localhost:123", "NO_PROXY": "mit.edu,edu.info"}, None, ), # Not proxied if one item in NO_PROXY case matches host domain suffix. # May include whitespace. ( "https://mit.edu.info", {"ALL_PROXY": "http://localhost:123", "NO_PROXY": "mit.edu, edu.info"}, None, ), # Proxied if no items in NO_PROXY match. ( "https://mit.edu.info", {"ALL_PROXY": "http://localhost:123", "NO_PROXY": "mit.edu,mit.info"}, "http://localhost:123", ), # Proxied if NO_PROXY domain doesn't match. ( "https://foo.example.com", {"ALL_PROXY": "http://localhost:123", "NO_PROXY": "www.example.com"}, "http://localhost:123", ), # Not proxied for subdomains matching NO_PROXY, with a leading ".". ( "https://www.example1.com", {"ALL_PROXY": "http://localhost:123", "NO_PROXY": ".example1.com"}, None, ), # Proxied, because NO_PROXY subdomains only match if "." separated. ( "https://www.example2.com", {"ALL_PROXY": "http://localhost:123", "NO_PROXY": "ample2.com"}, "http://localhost:123", ), # Not proxied for addresses within a NO_PROXY network. ( "http://192.168.5.10", {"ALL_PROXY": "http://localhost:123", "NO_PROXY": "192.168.0.0/16"}, None, ), ( "http://[fe80::1]", {"ALL_PROXY": "http://localhost:123", "NO_PROXY": "[fe80::]/64"}, None, ), # Proxied for addresses outside a NO_PROXY network. ( "http://10.0.0.1", {"ALL_PROXY": "http://localhost:123", "NO_PROXY": "192.168.0.0/16"}, "http://localhost:123", ), # Proxied, because an invalid NO_PROXY network is ignored. ( "http://192.168.0.0", {"ALL_PROXY": "http://localhost:123", "NO_PROXY": "192.168.0.0/33"}, "http://localhost:123", ), # No requests are proxied if NO_PROXY="*" is set. ( "https://www.example3.com", {"ALL_PROXY": "http://localhost:123", "NO_PROXY": "*"}, None, ), ], ) @pytest.mark.parametrize("client_class", [httpx2.Client, httpx2.AsyncClient]) def test_proxies_environ( monkeypatch: pytest.MonkeyPatch, client_class: type[typing.Any], url: str, env: dict[str, str], expected: str | None, ) -> None: for name, value in env.items(): monkeypatch.setenv(name, value) client = client_class() transport = client._transport_for_url(httpx2.URL(url)) if expected is None: assert transport == client._transport else: assert transport._pool._proxy_url == url_to_origin(expected) @pytest.mark.parametrize( ["proxies", "is_valid"], [ ({"http": "http://127.0.0.1"}, False), ({"https": "http://127.0.0.1"}, False), ({"all": "http://127.0.0.1"}, False), ({"http://": "http://127.0.0.1"}, True), ({"https://": "http://127.0.0.1"}, True), ({"all://": "http://127.0.0.1"}, True), ], ) def test_for_deprecated_proxy_params(proxies: dict[str, str], is_valid: bool) -> None: mounts = {key: httpx2.HTTPTransport(proxy=value) for key, value in proxies.items()} if not is_valid: with pytest.raises(ValueError): httpx2.Client(mounts=mounts) else: httpx2.Client(mounts=mounts) def test_proxy_with_mounts() -> None: proxy_transport = httpx2.HTTPTransport(proxy="http://127.0.0.1") client = httpx2.Client(mounts={"http://": proxy_transport}) transport = client._transport_for_url(httpx2.URL("http://example.com")) assert transport == proxy_transport def test_host_mount_takes_priority_over_network_mount() -> None: network = httpx2.MockTransport(lambda request: httpx2.Response(200, text="network")) host = httpx2.MockTransport(lambda request: httpx2.Response(200, text="host")) client = httpx2.Client(mounts={"all://10.0.0.0/8": network, "all://10.1.2.3": host}) assert client.get("http://10.1.2.3").text == "host" assert client.get("http://10.4.5.6").text == "network" def test_scheme_mount_takes_priority_over_equal_network_mount() -> None: all_schemes = httpx2.MockTransport(lambda request: httpx2.Response(200, text="all")) http = httpx2.MockTransport(lambda request: httpx2.Response(200, text="http")) client = httpx2.Client(mounts={"all://[0:0:0:0:0:0:0:0]/0": all_schemes, "http://[::]/0": http}) assert client.get("http://[2001:db8::1]").text == "http" def test_mount_with_invalid_network() -> None: with pytest.raises(httpx2.InvalidURL): httpx2.Client(mounts={"all://127.0.0.1:8080/8": httpx2.HTTPTransport()}) pydantic-httpx2-6dd59b9/tests/httpx2/client/test_queryparams.py000066400000000000000000000021211526547463400250530ustar00rootroot00000000000000import httpx2 def hello_world(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, text="Hello, world") def test_client_queryparams() -> None: client = httpx2.Client(params={"a": "b"}) assert isinstance(client.params, httpx2.QueryParams) assert client.params["a"] == "b" def test_client_queryparams_string() -> None: client = httpx2.Client(params="a=b") assert isinstance(client.params, httpx2.QueryParams) assert client.params["a"] == "b" client = httpx2.Client() client.params = "a=b" assert isinstance(client.params, httpx2.QueryParams) assert client.params["a"] == "b" def test_client_queryparams_echo() -> None: url = "http://example.org/echo_queryparams" client_queryparams = "first=str" request_queryparams = {"second": "dict"} client = httpx2.Client(transport=httpx2.MockTransport(hello_world), params=client_queryparams) response = client.get(url, params=request_queryparams) assert response.status_code == 200 assert response.url == "http://example.org/echo_queryparams?first=str&second=dict" pydantic-httpx2-6dd59b9/tests/httpx2/client/test_redirects.py000066400000000000000000000451411526547463400244770ustar00rootroot00000000000000import typing import pytest import httpx2 def redirects(request: httpx2.Request) -> httpx2.Response: if request.url.scheme not in ("http", "https"): msg = f"Scheme {request.url.scheme!r} not supported." raise httpx2.UnsupportedProtocol(msg) if request.url.path == "/redirect_301": status_code = httpx2.codes.MOVED_PERMANENTLY content = b"here" headers = {"location": "https://example.org/"} return httpx2.Response(status_code, headers=headers, content=content) elif request.url.path == "/redirect_302": status_code = httpx2.codes.FOUND headers = {"location": "https://example.org/"} return httpx2.Response(status_code, headers=headers) elif request.url.path == "/redirect_303": status_code = httpx2.codes.SEE_OTHER headers = {"location": "https://example.org/"} return httpx2.Response(status_code, headers=headers) elif request.url.path == "/relative_redirect": status_code = httpx2.codes.SEE_OTHER headers = {"location": "/"} return httpx2.Response(status_code, headers=headers) elif request.url.path == "/malformed_redirect": status_code = httpx2.codes.SEE_OTHER headers = {"location": "https://:443/"} return httpx2.Response(status_code, headers=headers) elif request.url.path == "/invalid_redirect": status_code = httpx2.codes.SEE_OTHER raw_headers = [(b"location", "https://๐Ÿ˜‡/".encode())] return httpx2.Response(status_code, headers=raw_headers) elif request.url.path == "/no_scheme_redirect": status_code = httpx2.codes.SEE_OTHER headers = {"location": "//example.org/"} return httpx2.Response(status_code, headers=headers) elif request.url.path == "/multiple_redirects": params = httpx2.QueryParams(request.url.query) count = int(params.get("count", "0")) redirect_count = count - 1 status_code = httpx2.codes.SEE_OTHER if count else httpx2.codes.OK if count: location = "/multiple_redirects" if redirect_count: location += f"?count={redirect_count}" headers = {"location": location} else: headers = {} return httpx2.Response(status_code, headers=headers) if request.url.path == "/redirect_loop": status_code = httpx2.codes.SEE_OTHER headers = {"location": "/redirect_loop"} return httpx2.Response(status_code, headers=headers) elif request.url.path == "/cross_domain": status_code = httpx2.codes.SEE_OTHER headers = {"location": "https://example.org/cross_domain_target"} return httpx2.Response(status_code, headers=headers) elif request.url.path == "/cross_domain_target": status_code = httpx2.codes.OK data = { "body": request.content.decode("ascii"), "headers": dict(request.headers), } return httpx2.Response(status_code, json=data) elif request.url.path == "/redirect_body": status_code = httpx2.codes.PERMANENT_REDIRECT headers = {"location": "/redirect_body_target"} return httpx2.Response(status_code, headers=headers) elif request.url.path == "/redirect_no_body": status_code = httpx2.codes.SEE_OTHER headers = {"location": "/redirect_body_target"} return httpx2.Response(status_code, headers=headers) elif request.url.path == "/redirect_found_body": status_code = httpx2.codes.FOUND headers = {"location": "/redirect_body_target"} return httpx2.Response(status_code, headers=headers) elif request.url.path == "/redirect_body_target": data = { "body": request.content.decode("ascii"), "headers": dict(request.headers), } return httpx2.Response(200, json=data) elif request.url.path == "/cross_subdomain": if request.headers["Host"] != "www.example.org": status_code = httpx2.codes.PERMANENT_REDIRECT headers = {"location": "https://www.example.org/cross_subdomain"} return httpx2.Response(status_code, headers=headers) else: return httpx2.Response(200, text="Hello, world!") elif request.url.path == "/redirect_custom_scheme": status_code = httpx2.codes.MOVED_PERMANENTLY headers = {"location": "market://details?id=42"} return httpx2.Response(status_code, headers=headers) if request.method == "HEAD": return httpx2.Response(200) return httpx2.Response(200, html="Hello, world!") def test_redirect_301() -> None: client = httpx2.Client(transport=httpx2.MockTransport(redirects)) response = client.post("https://example.org/redirect_301", follow_redirects=True) assert response.status_code == httpx2.codes.OK assert response.url == "https://example.org/" assert len(response.history) == 1 def test_redirect_302() -> None: client = httpx2.Client(transport=httpx2.MockTransport(redirects)) response = client.post("https://example.org/redirect_302", follow_redirects=True) assert response.status_code == httpx2.codes.OK assert response.url == "https://example.org/" assert len(response.history) == 1 def test_redirect_303() -> None: client = httpx2.Client(transport=httpx2.MockTransport(redirects)) response = client.get("https://example.org/redirect_303", follow_redirects=True) assert response.status_code == httpx2.codes.OK assert response.url == "https://example.org/" assert len(response.history) == 1 def test_next_request() -> None: client = httpx2.Client(transport=httpx2.MockTransport(redirects)) request = client.build_request("POST", "https://example.org/redirect_303") response = client.send(request, follow_redirects=False) assert response.status_code == httpx2.codes.SEE_OTHER assert response.url == "https://example.org/redirect_303" assert response.next_request is not None response = client.send(response.next_request, follow_redirects=False) assert response.status_code == httpx2.codes.OK assert response.url == "https://example.org/" assert response.next_request is None @pytest.mark.anyio async def test_async_next_request() -> None: async with httpx2.AsyncClient(transport=httpx2.MockTransport(redirects)) as client: request = client.build_request("POST", "https://example.org/redirect_303") response = await client.send(request, follow_redirects=False) assert response.status_code == httpx2.codes.SEE_OTHER assert response.url == "https://example.org/redirect_303" assert response.next_request is not None response = await client.send(response.next_request, follow_redirects=False) assert response.status_code == httpx2.codes.OK assert response.url == "https://example.org/" assert response.next_request is None def test_head_redirect() -> None: """ Contrary to Requests, redirects remain enabled by default for HEAD requests. """ client = httpx2.Client(transport=httpx2.MockTransport(redirects)) response = client.head("https://example.org/redirect_302", follow_redirects=True) assert response.status_code == httpx2.codes.OK assert response.url == "https://example.org/" assert response.request.method == "HEAD" assert len(response.history) == 1 assert response.text == "" def test_relative_redirect() -> None: client = httpx2.Client(transport=httpx2.MockTransport(redirects)) response = client.get("https://example.org/relative_redirect", follow_redirects=True) assert response.status_code == httpx2.codes.OK assert response.url == "https://example.org/" assert len(response.history) == 1 def test_malformed_redirect() -> None: # https://github.com/encode/httpx/issues/771 client = httpx2.Client(transport=httpx2.MockTransport(redirects)) response = client.get("http://example.org/malformed_redirect", follow_redirects=True) assert response.status_code == httpx2.codes.OK assert response.url == "https://example.org:443/" assert len(response.history) == 1 def test_invalid_redirect() -> None: client = httpx2.Client(transport=httpx2.MockTransport(redirects)) with pytest.raises(httpx2.RemoteProtocolError): client.get("http://example.org/invalid_redirect", follow_redirects=True) def test_no_scheme_redirect() -> None: client = httpx2.Client(transport=httpx2.MockTransport(redirects)) response = client.get("https://example.org/no_scheme_redirect", follow_redirects=True) assert response.status_code == httpx2.codes.OK assert response.url == "https://example.org/" assert len(response.history) == 1 def test_fragment_redirect() -> None: client = httpx2.Client(transport=httpx2.MockTransport(redirects)) response = client.get("https://example.org/relative_redirect#fragment", follow_redirects=True) assert response.status_code == httpx2.codes.OK assert response.url == "https://example.org/#fragment" assert len(response.history) == 1 def test_multiple_redirects() -> None: client = httpx2.Client(transport=httpx2.MockTransport(redirects)) response = client.get("https://example.org/multiple_redirects?count=20", follow_redirects=True) assert response.status_code == httpx2.codes.OK assert response.url == "https://example.org/multiple_redirects" assert len(response.history) == 20 assert response.history[0].url == "https://example.org/multiple_redirects?count=20" assert response.history[1].url == "https://example.org/multiple_redirects?count=19" assert len(response.history[0].history) == 0 assert len(response.history[1].history) == 1 @pytest.mark.anyio async def test_async_too_many_redirects() -> None: async with httpx2.AsyncClient(transport=httpx2.MockTransport(redirects)) as client: with pytest.raises(httpx2.TooManyRedirects): await client.get("https://example.org/multiple_redirects?count=21", follow_redirects=True) def test_sync_too_many_redirects() -> None: client = httpx2.Client(transport=httpx2.MockTransport(redirects)) with pytest.raises(httpx2.TooManyRedirects): client.get("https://example.org/multiple_redirects?count=21", follow_redirects=True) def test_redirect_loop() -> None: client = httpx2.Client(transport=httpx2.MockTransport(redirects)) with pytest.raises(httpx2.TooManyRedirects): client.get("https://example.org/redirect_loop", follow_redirects=True) def test_cross_domain_redirect_with_auth_header() -> None: client = httpx2.Client(transport=httpx2.MockTransport(redirects)) url = "https://example.com/cross_domain" headers = {"Authorization": "abc"} response = client.get(url, headers=headers, follow_redirects=True) assert response.url == "https://example.org/cross_domain_target" assert "authorization" not in response.json()["headers"] def test_cross_domain_https_redirect_with_auth_header() -> None: client = httpx2.Client(transport=httpx2.MockTransport(redirects)) url = "http://example.com/cross_domain" headers = {"Authorization": "abc"} response = client.get(url, headers=headers, follow_redirects=True) assert response.url == "https://example.org/cross_domain_target" assert "authorization" not in response.json()["headers"] def test_cross_domain_redirect_with_auth() -> None: client = httpx2.Client(transport=httpx2.MockTransport(redirects)) url = "https://example.com/cross_domain" response = client.get(url, auth=("user", "pass"), follow_redirects=True) assert response.url == "https://example.org/cross_domain_target" assert "authorization" not in response.json()["headers"] def test_same_domain_redirect() -> None: client = httpx2.Client(transport=httpx2.MockTransport(redirects)) url = "https://example.org/cross_domain" headers = {"Authorization": "abc"} response = client.get(url, headers=headers, follow_redirects=True) assert response.url == "https://example.org/cross_domain_target" assert response.json()["headers"]["authorization"] == "abc" def test_same_domain_https_redirect_with_auth_header() -> None: client = httpx2.Client(transport=httpx2.MockTransport(redirects)) url = "http://example.org/cross_domain" headers = {"Authorization": "abc"} response = client.get(url, headers=headers, follow_redirects=True) assert response.url == "https://example.org/cross_domain_target" assert response.json()["headers"]["authorization"] == "abc" def test_body_redirect() -> None: """ A 308 redirect should preserve the request body. """ client = httpx2.Client(transport=httpx2.MockTransport(redirects)) url = "https://example.org/redirect_body" content = b"Example request body" response = client.post(url, content=content, follow_redirects=True) assert response.url == "https://example.org/redirect_body_target" assert response.json()["body"] == "Example request body" assert "content-length" in response.json()["headers"] def test_no_body_redirect() -> None: """ A 303 redirect should remove the request body. """ client = httpx2.Client(transport=httpx2.MockTransport(redirects)) url = "https://example.org/redirect_no_body" content = b"Example request body" response = client.post(url, content=content, follow_redirects=True) assert response.url == "https://example.org/redirect_body_target" assert response.json()["body"] == "" assert "content-length" not in response.json()["headers"] def test_query_body_redirect() -> None: """ A 302 redirect should preserve the method and body of a `QUERY` request. https://datatracker.ietf.org/doc/html/rfc10008#section-2.5 """ client = httpx2.Client(transport=httpx2.MockTransport(redirects)) url = "https://example.org/redirect_found_body" content = b"Example request body" response = client.query(url, content=content, follow_redirects=True) assert response.url == "https://example.org/redirect_body_target" assert response.request.method == "QUERY" assert response.json()["body"] == "Example request body" assert "content-length" in response.json()["headers"] def test_query_no_body_redirect() -> None: """ A 303 redirect should convert a `QUERY` request to a `GET` request. https://datatracker.ietf.org/doc/html/rfc10008#section-2.5 """ client = httpx2.Client(transport=httpx2.MockTransport(redirects)) url = "https://example.org/redirect_no_body" content = b"Example request body" response = client.query(url, content=content, follow_redirects=True) assert response.url == "https://example.org/redirect_body_target" assert response.request.method == "GET" assert response.json()["body"] == "" def test_can_stream_if_no_redirect() -> None: client = httpx2.Client(transport=httpx2.MockTransport(redirects)) url = "https://example.org/redirect_301" with client.stream("GET", url, follow_redirects=False) as response: pass assert response.status_code == httpx2.codes.MOVED_PERMANENTLY assert response.headers["location"] == "https://example.org/" class ConsumeBodyTransport(httpx2.MockTransport): def handle_request(self, request: httpx2.Request) -> httpx2.Response: assert isinstance(request.stream, httpx2.SyncByteStream) list(request.stream) return self.handler(request) # type: ignore[return-value] def test_cannot_redirect_streaming_body() -> None: client = httpx2.Client(transport=ConsumeBodyTransport(redirects)) url = "https://example.org/redirect_body" def streaming_body() -> typing.Iterator[bytes]: yield b"Example request body" # pragma: no cover with pytest.raises(httpx2.StreamConsumed): client.post(url, content=streaming_body(), follow_redirects=True) def test_cross_subdomain_redirect() -> None: client = httpx2.Client(transport=httpx2.MockTransport(redirects)) url = "https://example.com/cross_subdomain" response = client.get(url, follow_redirects=True) assert response.url == "https://www.example.org/cross_subdomain" def cookie_sessions(request: httpx2.Request) -> httpx2.Response: if request.url.path == "/": cookie = request.headers.get("Cookie") if cookie is not None: content = b"Logged in" else: content = b"Not logged in" return httpx2.Response(200, content=content) elif request.url.path == "/login": status_code = httpx2.codes.SEE_OTHER headers = { "location": "/", "set-cookie": ("session=eyJ1c2VybmFtZSI6ICJ0b21; path=/; Max-Age=1209600; httponly; samesite=lax"), } return httpx2.Response(status_code, headers=headers) else: assert request.url.path == "/logout" status_code = httpx2.codes.SEE_OTHER headers = { "location": "/", "set-cookie": ("session=null; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; httponly; samesite=lax"), } return httpx2.Response(status_code, headers=headers) def test_redirect_cookie_behavior() -> None: client = httpx2.Client(transport=httpx2.MockTransport(cookie_sessions), follow_redirects=True) # The client is not logged in. response = client.get("https://example.com/") assert response.url == "https://example.com/" assert response.text == "Not logged in" # Login redirects to the homepage, setting a session cookie. response = client.post("https://example.com/login") assert response.url == "https://example.com/" assert response.text == "Logged in" # The client is logged in. response = client.get("https://example.com/") assert response.url == "https://example.com/" assert response.text == "Logged in" # Logout redirects to the homepage, expiring the session cookie. response = client.post("https://example.com/logout") assert response.url == "https://example.com/" assert response.text == "Not logged in" # The client is not logged in. response = client.get("https://example.com/") assert response.url == "https://example.com/" assert response.text == "Not logged in" def test_redirect_custom_scheme() -> None: client = httpx2.Client(transport=httpx2.MockTransport(redirects)) with pytest.raises(httpx2.UnsupportedProtocol) as e: client.post("https://example.org/redirect_custom_scheme", follow_redirects=True) assert str(e.value) == "Scheme 'market' not supported." @pytest.mark.anyio async def test_async_invalid_redirect() -> None: async with httpx2.AsyncClient(transport=httpx2.MockTransport(redirects)) as client: with pytest.raises(httpx2.RemoteProtocolError): await client.get("http://example.org/invalid_redirect", follow_redirects=True) pydantic-httpx2-6dd59b9/tests/httpx2/common.py000066400000000000000000000001401526547463400214540ustar00rootroot00000000000000import pathlib TESTS_DIR = pathlib.Path(__file__).parent FIXTURES_DIR = TESTS_DIR / "fixtures" pydantic-httpx2-6dd59b9/tests/httpx2/concurrency.py000066400000000000000000000005041526547463400225220ustar00rootroot00000000000000""" Async environment-agnostic concurrency utilities that are only used in tests. """ import asyncio import sniffio import trio async def sleep(seconds: float) -> None: if sniffio.current_async_library() == "trio": await trio.sleep(seconds) # pragma: no cover else: await asyncio.sleep(seconds) pydantic-httpx2-6dd59b9/tests/httpx2/conftest.py000066400000000000000000000223231526547463400220200ustar00rootroot00000000000000import asyncio import json import os import socket import threading import time import typing import pytest import trustme from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives.serialization import ( BestAvailableEncryption, Encoding, PrivateFormat, load_pem_private_key, ) from uvicorn.config import Config from uvicorn.server import Server import httpx2 from tests.httpx2.concurrency import sleep ENVIRONMENT_VARIABLES = { "SSL_CERT_FILE", "SSL_CERT_DIR", "HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY", "NO_PROXY", "SSLKEYLOGFILE", } @pytest.fixture(scope="function", autouse=True) def clean_environ() -> typing.Iterator[None]: """Keeps os.environ clean for every test without having to mock os.environ""" original_environ = os.environ.copy() os.environ.clear() os.environ.update( { k: v for k, v in original_environ.items() if k not in ENVIRONMENT_VARIABLES and k.lower() not in ENVIRONMENT_VARIABLES } ) yield os.environ.clear() os.environ.update(original_environ) Message = dict[str, typing.Any] Receive = typing.Callable[[], typing.Awaitable[Message]] Send = typing.Callable[[dict[str, typing.Any]], typing.Coroutine[None, None, None]] Scope = dict[str, typing.Any] async def app(scope: Scope, receive: Receive, send: Send) -> None: assert scope["type"] == "http" if scope["path"].startswith("/slow_response"): await slow_response(scope, receive, send) elif scope["path"].startswith("/stream_response"): await stream_response(scope, receive, send) elif scope["path"].startswith("/status"): await status_code(scope, receive, send) elif scope["path"].startswith("/echo_body"): await echo_body(scope, receive, send) elif scope["path"].startswith("/echo_binary"): await echo_binary(scope, receive, send) elif scope["path"].startswith("/echo_headers"): await echo_headers(scope, receive, send) elif scope["path"].startswith("/redirect_301"): await redirect_301(scope, receive, send) elif scope["path"].startswith("/json"): await hello_world_json(scope, receive, send) else: await hello_world(scope, receive, send) async def hello_world(scope: Scope, receive: Receive, send: Send) -> None: await send( { "type": "http.response.start", "status": 200, "headers": [[b"content-type", b"text/plain"]], } ) await send({"type": "http.response.body", "body": b"Hello, world!"}) async def hello_world_json(scope: Scope, receive: Receive, send: Send) -> None: await send( { "type": "http.response.start", "status": 200, "headers": [[b"content-type", b"application/json"]], } ) await send({"type": "http.response.body", "body": b'{"Hello": "world!"}'}) async def slow_response(scope: Scope, receive: Receive, send: Send) -> None: await send( { "type": "http.response.start", "status": 200, "headers": [[b"content-type", b"text/plain"]], } ) await sleep(1.0) # Allow triggering a read timeout. await send({"type": "http.response.body", "body": b"Hello, world!"}) async def stream_response(scope: Scope, receive: Receive, send: Send) -> None: await send( { "type": "http.response.start", "status": 200, "headers": [[b"content-type", b"text/plain"]], } ) await send({"type": "http.response.body", "body": b"Hello\n", "more_body": True}) await sleep(0.1) await send({"type": "http.response.body", "body": b"world!"}) async def status_code(scope: Scope, receive: Receive, send: Send) -> None: status_code = int(scope["path"].replace("/status/", "")) await send( { "type": "http.response.start", "status": status_code, "headers": [[b"content-type", b"text/plain"]], } ) await send({"type": "http.response.body", "body": b"Hello, world!"}) async def echo_body(scope: Scope, receive: Receive, send: Send) -> None: body = b"" more_body = True while more_body: message = await receive() body += message.get("body", b"") more_body = message.get("more_body", False) await send( { "type": "http.response.start", "status": 200, "headers": [[b"content-type", b"text/plain"]], } ) await send({"type": "http.response.body", "body": body}) async def echo_binary(scope: Scope, receive: Receive, send: Send) -> None: body = b"" more_body = True while more_body: message = await receive() body += message.get("body", b"") more_body = message.get("more_body", False) await send( { "type": "http.response.start", "status": 200, "headers": [[b"content-type", b"application/octet-stream"]], } ) await send({"type": "http.response.body", "body": body}) async def echo_headers(scope: Scope, receive: Receive, send: Send) -> None: body = {name.capitalize().decode(): value.decode() for name, value in scope.get("headers", [])} await send( { "type": "http.response.start", "status": 200, "headers": [[b"content-type", b"application/json"]], } ) await send({"type": "http.response.body", "body": json.dumps(body).encode()}) async def redirect_301(scope: Scope, receive: Receive, send: Send) -> None: await send({"type": "http.response.start", "status": 301, "headers": [[b"location", b"/"]]}) await send({"type": "http.response.body"}) @pytest.fixture(scope="session") def cert_authority() -> trustme.CA: return trustme.CA() @pytest.fixture(scope="session") def localhost_cert(cert_authority: trustme.CA) -> trustme.LeafCert: return cert_authority.issue_cert("localhost") @pytest.fixture(scope="session") def cert_pem_file(localhost_cert: trustme.LeafCert) -> typing.Iterator[str]: with localhost_cert.cert_chain_pems[0].tempfile() as tmp: yield tmp @pytest.fixture(scope="session") def cert_private_key_file(localhost_cert: trustme.LeafCert) -> typing.Iterator[str]: with localhost_cert.private_key_pem.tempfile() as tmp: yield tmp @pytest.fixture(scope="session") def cert_encrypted_private_key_file(localhost_cert: trustme.LeafCert) -> typing.Iterator[str]: # Deserialize the private key and then reserialize with a password private_key = load_pem_private_key(localhost_cert.private_key_pem.bytes(), password=None, backend=default_backend()) encrypted_private_key_pem = trustme.Blob( private_key.private_bytes( Encoding.PEM, PrivateFormat.TraditionalOpenSSL, BestAvailableEncryption(password=b"password"), ) ) with encrypted_private_key_pem.tempfile() as tmp: yield tmp class TestServer(Server): @property def url(self) -> httpx2.URL: protocol = "https" if self.config.is_ssl else "http" return httpx2.URL(f"{protocol}://{self.config.host}:{self.config.port}/") def install_signal_handlers(self) -> None: # Disable the default installation of handlers for signals such as SIGTERM, # because it can only be done in the main thread. pass # pragma: no cover async def serve(self, sockets: list[socket.socket] | None = None) -> None: self.restart_requested = asyncio.Event() loop = asyncio.get_running_loop() tasks = { loop.create_task(super().serve(sockets=sockets)), loop.create_task(self.watch_restarts()), } await asyncio.wait(tasks) async def restart(self) -> None: # pragma: no cover # This coroutine may be called from a different thread than the one the # server is running on, and from an async environment that's not asyncio. # For this reason, we use an event to coordinate with the server # instead of calling shutdown()/startup() directly, and should not make # any asyncio-specific operations. self.started = False self.restart_requested.set() while not self.started: await sleep(0.2) async def watch_restarts(self) -> None: # pragma: no cover while True: if self.should_exit: return try: await asyncio.wait_for(self.restart_requested.wait(), timeout=0.1) except TimeoutError: continue self.restart_requested.clear() await self.shutdown() await self.startup() def serve_in_thread(server: TestServer) -> typing.Iterator[TestServer]: thread = threading.Thread(target=server.run) thread.start() try: while not server.started: time.sleep(1e-3) yield server finally: server.should_exit = True thread.join() @pytest.fixture(scope="session") def server(free_tcp_port_factory: typing.Callable[[], int]) -> typing.Iterator[TestServer]: config = Config(app=app, lifespan="off", loop="asyncio", ws="none", port=free_tcp_port_factory()) server = TestServer(config=config) yield from serve_in_thread(server) pydantic-httpx2-6dd59b9/tests/httpx2/fixtures/000077500000000000000000000000001526547463400214705ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/tests/httpx2/fixtures/.netrc000066400000000000000000000001111526547463400225750ustar00rootroot00000000000000machine netrcexample.org login example-username password example-passwordpydantic-httpx2-6dd59b9/tests/httpx2/models/000077500000000000000000000000001526547463400211025ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/tests/httpx2/models/__init__.py000066400000000000000000000000001526547463400232010ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/tests/httpx2/models/test_cookies.py000066400000000000000000000102621526547463400241500ustar00rootroot00000000000000import http.cookiejar from http.client import HTTPResponse from urllib.request import Request as UrllibRequest import pytest import httpx2 def test_cookies() -> None: cookies = httpx2.Cookies({"name": "value"}) assert cookies["name"] == "value" assert "name" in cookies assert len(cookies) == 1 assert dict(cookies) == {"name": "value"} assert bool(cookies) is True del cookies["name"] assert "name" not in cookies assert len(cookies) == 0 assert dict(cookies) == {} assert bool(cookies) is False def test_cookies_update() -> None: cookies = httpx2.Cookies() more_cookies = httpx2.Cookies() more_cookies.set("name", "value", domain="example.com") cookies.update(more_cookies) assert dict(cookies) == {"name": "value"} assert cookies.get("name", domain="example.com") == "value" def test_cookies_with_domain() -> None: cookies = httpx2.Cookies() cookies.set("name", "value", domain="example.com") cookies.set("name", "value", domain="example.org") with pytest.raises(httpx2.CookieConflict): cookies["name"] cookies.clear(domain="example.com") assert len(cookies) == 1 def test_cookies_with_domain_and_path() -> None: cookies = httpx2.Cookies() cookies.set("name", "value", domain="example.com", path="/subpath/1") cookies.set("name", "value", domain="example.com", path="/subpath/2") cookies.clear(domain="example.com", path="/subpath/1") assert len(cookies) == 1 cookies.delete("name", domain="example.com", path="/subpath/2") assert len(cookies) == 0 def test_extract_cookies_skips_cookie_jar_without_set_cookie() -> None: class TrackingCookieJar(http.cookiejar.CookieJar): def __init__(self) -> None: super().__init__() self.extract_count = 0 def extract_cookies(self, response: HTTPResponse, request: UrllibRequest) -> None: self.extract_count += 1 jar = TrackingCookieJar() request = httpx2.Request("GET", "https://www.example.org") cookies = httpx2.Cookies(jar) cookies.extract_cookies(httpx2.Response(200, request=request)) assert jar.extract_count == 0 cookies.extract_cookies(httpx2.Response(200, request=request, headers={"Set-Cookie": "name=value"})) assert jar.extract_count == 1 def test_set_cookie2() -> None: policy = http.cookiejar.DefaultCookiePolicy(rfc2965=True) jar = http.cookiejar.CookieJar(policy=policy) headers = [(b"Set-Cookie2", b'customer="WILE_E_COYOTE"; Version="1"; Path="/"')] request = httpx2.Request("GET", "https://www.example.org") response = httpx2.Response(200, request=request, headers=headers) cookies = httpx2.Cookies(jar) cookies.extract_cookies(response) assert cookies["customer"] == "WILE_E_COYOTE" def test_multiple_set_cookie() -> None: jar = http.cookiejar.CookieJar() headers = [ ( b"Set-Cookie", b"1P_JAR=2020-08-09-18; expires=Tue, 08-Sep-2099 18:33:35 GMT; path=/; domain=.example.org; Secure", ), ( b"Set-Cookie", b"NID=204=KWdXOuypc86YvRfBSiWoW1dEXfSl_5qI7sxZY4umlk4J35yNTeNEkw15" b"MRaujK6uYCwkrtjihTTXZPp285z_xDOUzrdHt4dj0Z5C0VOpbvdLwRdHatHAzQs7" b"7TsaiWY78a3qU9r7KP_RbSLvLl2hlhnWFR2Hp5nWKPsAcOhQgSg; expires=Mon, " b"08-Feb-2099 18:33:35 GMT; path=/; domain=.example.org; HttpOnly", ), ] request = httpx2.Request("GET", "https://www.example.org") response = httpx2.Response(200, request=request, headers=headers) cookies = httpx2.Cookies(jar) cookies.extract_cookies(response) assert len(cookies) == 2 def test_cookies_can_be_a_list_of_tuples() -> None: cookies_val = [("name1", "val1"), ("name2", "val2")] cookies = httpx2.Cookies(cookies_val) assert len(cookies.items()) == 2 for k, v in cookies_val: assert cookies[k] == v def test_cookies_repr() -> None: cookies = httpx2.Cookies() cookies.set(name="foo", value="bar", domain="http://blah.com") cookies.set(name="fizz", value="buzz", domain="http://hello.com") assert repr(cookies) == ( ", ]>" ) pydantic-httpx2-6dd59b9/tests/httpx2/models/test_headers.py000066400000000000000000000205061526547463400241310ustar00rootroot00000000000000from __future__ import annotations import pytest import httpx2 def test_headers() -> None: h = httpx2.Headers([("a", "123"), ("a", "456"), ("b", "789")]) assert "a" in h assert "A" in h assert "b" in h assert "B" in h assert "c" not in h assert h["a"] == "123, 456" assert h.get("a") == "123, 456" assert h.get("nope", default=None) is None assert h.get_list("a") == ["123", "456"] assert list(h.keys()) == ["a", "b"] assert list(h.values()) == ["123, 456", "789"] assert list(h.items()) == [("a", "123, 456"), ("b", "789")] assert h.multi_items() == [("a", "123"), ("a", "456"), ("b", "789")] assert list(h) == ["a", "b"] assert dict(h) == {"a": "123, 456", "b": "789"} assert repr(h) == "Headers([('a', '123'), ('a', '456'), ('b', '789')])" assert h == [("a", "123"), ("b", "789"), ("a", "456")] assert h == [("a", "123"), ("A", "456"), ("b", "789")] assert h == {"a": "123", "A": "456", "b": "789"} assert h != "a: 123\nA: 456\nb: 789" h = httpx2.Headers({"a": "123", "b": "789"}) assert h["A"] == "123" assert h["B"] == "789" assert h.raw == [(b"a", b"123"), (b"b", b"789")] assert repr(h) == "Headers({'a': '123', 'b': '789'})" def test_header_mutations() -> None: h = httpx2.Headers() assert dict(h) == {} h["a"] = "1" assert dict(h) == {"a": "1"} h["a"] = "2" assert dict(h) == {"a": "2"} h.setdefault("a", "3") assert dict(h) == {"a": "2"} h.setdefault("b", "4") assert dict(h) == {"a": "2", "b": "4"} del h["a"] assert dict(h) == {"b": "4"} assert h.raw == [(b"b", b"4")] def test_copy_headers_method() -> None: headers = httpx2.Headers({"custom": "example"}) headers_copy = headers.copy() assert headers == headers_copy assert headers is not headers_copy def test_copy_headers_init() -> None: headers = httpx2.Headers({"custom": "example"}) headers_copy = httpx2.Headers(headers) assert headers == headers_copy def test_headers_or() -> None: left = httpx2.Headers({"a": "1", "b": "2"}) merged = left | {"b": "3", "c": "4"} assert isinstance(merged, httpx2.Headers) assert dict(merged) == {"a": "1", "b": "3", "c": "4"} assert dict(left) == {"a": "1", "b": "2"} def test_headers_or_with_headers() -> None: merged = httpx2.Headers({"a": "1"}) | httpx2.Headers({"a": "2"}) assert dict(merged) == {"a": "2"} def test_headers_ror() -> None: merged = {"a": "1", "b": "2"} | httpx2.Headers({"b": "3"}) assert isinstance(merged, httpx2.Headers) assert dict(merged) == {"a": "1", "b": "3"} def test_headers_ior() -> None: headers = httpx2.Headers({"a": "1"}) original = headers headers |= {"a": "2", "b": "3"} assert headers is original assert dict(headers) == {"a": "2", "b": "3"} def test_headers_ior_accepts_update_inputs() -> None: headers = httpx2.Headers({"a": "1"}) headers |= [("a", "2"), ("b", "3")] assert dict(headers) == {"a": "2", "b": "3"} def test_headers_or_unsupported_type() -> None: with pytest.raises(TypeError): httpx2.Headers({"a": "1"}) | [("b", "2")] # type: ignore[operator] with pytest.raises(TypeError): [("b", "2")] | httpx2.Headers({"a": "1"}) # type: ignore[operator] def test_headers_insert_retains_ordering() -> None: headers = httpx2.Headers({"a": "a", "b": "b", "c": "c"}) headers["b"] = "123" assert list(headers.values()) == ["a", "123", "c"] def test_headers_insert_appends_if_new() -> None: headers = httpx2.Headers({"a": "a", "b": "b", "c": "c"}) headers["d"] = "123" assert list(headers.values()) == ["a", "b", "c", "123"] def test_headers_insert_removes_all_existing() -> None: headers = httpx2.Headers([("a", "123"), ("a", "456")]) headers["a"] = "789" assert dict(headers) == {"a": "789"} def test_headers_delete_removes_all_existing() -> None: headers = httpx2.Headers([("a", "123"), ("a", "456")]) del headers["a"] assert dict(headers) == {} def test_headers_dict_repr() -> None: """ Headers should display with a dict repr by default. """ headers = httpx2.Headers({"custom": "example"}) assert repr(headers) == "Headers({'custom': 'example'})" def test_headers_encoding_in_repr() -> None: """ Headers should display an encoding in the repr if required. """ headers = httpx2.Headers({b"custom": "example โ˜ƒ".encode()}) assert repr(headers) == "Headers({'custom': 'example โ˜ƒ'}, encoding='utf-8')" def test_headers_list_repr() -> None: """ Headers should display with a list repr if they include multiple identical keys. """ headers = httpx2.Headers([("custom", "example 1"), ("custom", "example 2")]) assert repr(headers) == "Headers([('custom', 'example 1'), ('custom', 'example 2')])" def test_headers_decode_ascii() -> None: """ Headers should decode as ascii by default. """ raw_headers = [(b"Custom", b"Example")] headers = httpx2.Headers(raw_headers) assert dict(headers) == {"custom": "Example"} assert headers.encoding == "ascii" def test_headers_decode_utf_8() -> None: """ Headers containing non-ascii codepoints should default to decoding as utf-8. """ raw_headers = [(b"Custom", "Code point: โ˜ƒ".encode())] headers = httpx2.Headers(raw_headers) assert dict(headers) == {"custom": "Code point: โ˜ƒ"} assert headers.encoding == "utf-8" def test_headers_decode_iso_8859_1() -> None: """ Headers containing non-UTF-8 codepoints should default to decoding as iso-8859-1. """ raw_headers = [(b"Custom", "Code point: รฟ".encode("iso-8859-1"))] headers = httpx2.Headers(raw_headers) assert dict(headers) == {"custom": "Code point: รฟ"} assert headers.encoding == "iso-8859-1" def test_headers_decode_explicit_encoding() -> None: """ An explicit encoding may be set on headers in order to force a particular decoding. """ raw_headers = [(b"Custom", "Code point: โ˜ƒ".encode())] headers = httpx2.Headers(raw_headers) headers.encoding = "iso-8859-1" assert dict(headers) == {"custom": "Code point: รข\x98\x83"} assert headers.encoding == "iso-8859-1" def test_multiple_headers() -> None: """ `Headers.get_list` should support both split_commas=False and split_commas=True. """ h = httpx2.Headers([("set-cookie", "a, b"), ("set-cookie", "c")]) assert h.get_list("Set-Cookie") == ["a, b", "c"] h = httpx2.Headers([("vary", "a, b"), ("vary", "c")]) assert h.get_list("Vary", split_commas=True) == ["a", "b", "c"] @pytest.mark.parametrize("header", ["authorization", "proxy-authorization"]) def test_sensitive_headers(header: str) -> None: """ Some headers should be obfuscated because they contain sensitive data. """ value = "s3kr3t" h = httpx2.Headers({header: value}) assert repr(h) == f"Headers({{'{header}': '[secure]'}})" @pytest.mark.parametrize( "headers, output", [ ([("content-type", "text/html")], [("content-type", "text/html")]), ([("authorization", "s3kr3t")], [("authorization", "[secure]")]), ([("proxy-authorization", "s3kr3t")], [("proxy-authorization", "[secure]")]), ], ) def test_obfuscate_sensitive_headers(headers: list[tuple[str, str]], output: list[tuple[str, str]]) -> None: as_dict = dict(output) headers_class = httpx2.Headers(dict(headers)) assert repr(headers_class) == f"Headers({as_dict!r})" @pytest.mark.parametrize( "value, expected", ( ( '; rel=front; type="image/jpeg"', [{"url": "http:/.../front.jpeg", "rel": "front", "type": "image/jpeg"}], ), ("", [{"url": "http:/.../front.jpeg"}]), (";", [{"url": "http:/.../front.jpeg"}]), ( '; type="image/jpeg",;', [ {"url": "http:/.../front.jpeg", "type": "image/jpeg"}, {"url": "http://.../back.jpeg"}, ], ), ("", []), ), ) def test_parse_header_links(value: str, expected: list[dict[str, str]]) -> None: all_links = httpx2.Response(200, headers={"link": value}).links.values() assert all(link in all_links for link in expected) def test_parse_header_links_no_link() -> None: all_links = httpx2.Response(200).links assert all_links == {} pydantic-httpx2-6dd59b9/tests/httpx2/models/test_queryparams.py000066400000000000000000000071571526547463400250760ustar00rootroot00000000000000from __future__ import annotations import typing import pytest import httpx2 @pytest.mark.parametrize( "source", [ "a=123&a=456&b=789", {"a": ["123", "456"], "b": 789}, {"a": ("123", "456"), "b": 789}, [("a", "123"), ("a", "456"), ("b", "789")], (("a", "123"), ("a", "456"), ("b", "789")), ], ) def test_queryparams(source: typing.Any) -> None: q = httpx2.QueryParams(source) assert "a" in q assert "A" not in q assert "c" not in q assert q["a"] == "123" assert q.get("a") == "123" assert q.get("nope", default=None) is None assert q.get_list("a") == ["123", "456"] assert list(q.keys()) == ["a", "b"] assert list(q.values()) == ["123", "789"] assert list(q.items()) == [("a", "123"), ("b", "789")] assert len(q) == 2 assert list(q) == ["a", "b"] assert dict(q) == {"a": "123", "b": "789"} assert str(q) == "a=123&a=456&b=789" assert repr(q) == "QueryParams('a=123&a=456&b=789')" assert httpx2.QueryParams({"a": "123", "b": "456"}) == httpx2.QueryParams([("a", "123"), ("b", "456")]) assert httpx2.QueryParams({"a": "123", "b": "456"}) == httpx2.QueryParams("a=123&b=456") assert httpx2.QueryParams({"a": "123", "b": "456"}) == httpx2.QueryParams({"b": "456", "a": "123"}) assert httpx2.QueryParams() == httpx2.QueryParams({}) assert httpx2.QueryParams([("a", "123"), ("a", "456")]) == httpx2.QueryParams("a=123&a=456") assert httpx2.QueryParams({"a": "123", "b": "456"}) != "invalid" q = httpx2.QueryParams([("a", "123"), ("a", "456")]) assert httpx2.QueryParams(q) == q def test_queryparam_types() -> None: q = httpx2.QueryParams(None) assert str(q) == "" q = httpx2.QueryParams({"a": True}) assert str(q) == "a=true" q = httpx2.QueryParams({"a": False}) assert str(q) == "a=false" q = httpx2.QueryParams({"a": ""}) assert str(q) == "a=" q = httpx2.QueryParams({"a": None}) assert str(q) == "a=" q = httpx2.QueryParams({"a": 1.23}) assert str(q) == "a=1.23" q = httpx2.QueryParams({"a": 123}) assert str(q) == "a=123" q = httpx2.QueryParams({"a": [1, 2]}) assert str(q) == "a=1&a=2" def test_empty_query_params() -> None: q = httpx2.QueryParams({"a": ""}) assert str(q) == "a=" q = httpx2.QueryParams("a=") assert str(q) == "a=" q = httpx2.QueryParams("a") assert str(q) == "a=" def test_queryparam_update_is_hard_deprecated() -> None: q = httpx2.QueryParams("a=123") with pytest.raises(RuntimeError): q.update({"a": "456"}) def test_queryparam_setter_is_hard_deprecated() -> None: q = httpx2.QueryParams("a=123") with pytest.raises(RuntimeError): q["a"] = "456" def test_queryparam_set() -> None: q = httpx2.QueryParams("a=123") q = q.set("a", "456") assert q == httpx2.QueryParams("a=456") def test_queryparam_add() -> None: q = httpx2.QueryParams("a=123") q = q.add("a", "456") assert q == httpx2.QueryParams("a=123&a=456") def test_queryparam_remove() -> None: q = httpx2.QueryParams("a=123") q = q.remove("a") assert q == httpx2.QueryParams("") def test_queryparam_merge() -> None: q = httpx2.QueryParams("a=123") q = q.merge({"b": "456"}) assert q == httpx2.QueryParams("a=123&b=456") q = q.merge({"a": "000", "c": "789"}) assert q == httpx2.QueryParams("a=000&b=456&c=789") def test_queryparams_are_hashable() -> None: params = ( httpx2.QueryParams("a=123"), httpx2.QueryParams({"a": 123}), httpx2.QueryParams("b=456"), httpx2.QueryParams({"b": 456}), ) assert len(set(params)) == 2 pydantic-httpx2-6dd59b9/tests/httpx2/models/test_requests.py000066400000000000000000000210711526547463400243670ustar00rootroot00000000000000from __future__ import annotations import pickle import typing import pytest import httpx2 def test_request_repr() -> None: request = httpx2.Request("GET", "http://example.org") assert repr(request) == "" def test_no_content() -> None: request = httpx2.Request("GET", "http://example.org") assert "Content-Length" not in request.headers def test_content_length_header() -> None: request = httpx2.Request("POST", "http://example.org", content=b"test 123") assert request.headers["Content-Length"] == "8" def test_ignore_content_length_header_if_transfer_encoding_exists() -> None: headers = {"Transfer-Encoding": "chunked"} request = httpx2.Request("POST", "http://example.org", content=b"test 123", headers=headers) assert request.headers["Transfer-Encoding"] == "chunked" assert "Content-Length" not in request.headers def test_iterable_content() -> None: class Content: def __iter__(self) -> typing.Iterator[bytes]: yield b"test 123" # pragma: no cover request = httpx2.Request("POST", "http://example.org", content=Content()) assert request.headers == {"Host": "example.org", "Transfer-Encoding": "chunked"} def test_generator_with_transfer_encoding_header() -> None: def content() -> typing.Iterator[bytes]: yield b"test 123" # pragma: no cover request = httpx2.Request("POST", "http://example.org", content=content()) assert request.headers == {"Host": "example.org", "Transfer-Encoding": "chunked"} def test_generator_with_content_length_header() -> None: def content() -> typing.Iterator[bytes]: yield b"test 123" # pragma: no cover headers = {"Content-Length": "8"} request = httpx2.Request("POST", "http://example.org", content=content(), headers=headers) assert request.headers == {"Host": "example.org", "Content-Length": "8"} def test_url_encoded_data() -> None: request = httpx2.Request("POST", "http://example.org", data={"test": "123"}) request.read() assert request.headers["Content-Type"] == "application/x-www-form-urlencoded" assert request.content == b"test=123" def test_json_encoded_data() -> None: request = httpx2.Request("POST", "http://example.org", json={"test": 123}) request.read() assert request.headers["Content-Type"] == "application/json" assert request.content == b'{"test":123}' def test_headers() -> None: request = httpx2.Request("POST", "http://example.org", json={"test": 123}) assert request.headers == { "Host": "example.org", "Content-Type": "application/json", "Content-Length": "12", } def test_read_and_stream_data() -> None: # Ensure a request may still be streamed if it has been read. # Needed for cases such as authentication classes that read the request body. request = httpx2.Request("POST", "http://example.org", json={"test": 123}) request.read() assert request.stream is not None assert isinstance(request.stream, typing.Iterable) content = b"".join(list(request.stream)) assert content == request.content @pytest.mark.anyio async def test_aread_and_stream_data() -> None: # Ensure a request may still be streamed if it has been read. # Needed for cases such as authentication classes that read the request body. request = httpx2.Request("POST", "http://example.org", json={"test": 123}) await request.aread() assert request.stream is not None assert isinstance(request.stream, typing.AsyncIterable) content = b"".join([part async for part in request.stream]) assert content == request.content def test_cannot_access_streaming_content_without_read() -> None: # Ensure that streaming requests def streaming_body() -> typing.Iterator[bytes]: # pragma: no cover yield b"" request = httpx2.Request("POST", "http://example.org", content=streaming_body()) with pytest.raises(httpx2.RequestNotRead): request.content # noqa: B018 def test_transfer_encoding_header() -> None: async def streaming_body(data: bytes) -> typing.AsyncIterator[bytes]: yield data # pragma: no cover data = streaming_body(b"test 123") request = httpx2.Request("POST", "http://example.org", content=data) assert "Content-Length" not in request.headers assert request.headers["Transfer-Encoding"] == "chunked" def test_ignore_transfer_encoding_header_if_content_length_exists() -> None: """ `Transfer-Encoding` should be ignored if `Content-Length` has been set explicitly. See https://github.com/encode/httpx/issues/1168 """ def streaming_body(data: bytes) -> typing.Iterator[bytes]: yield data # pragma: no cover data = streaming_body(b"abcd") headers = {"Content-Length": "4"} request = httpx2.Request("POST", "http://example.org", content=data, headers=headers) assert "Transfer-Encoding" not in request.headers assert request.headers["Content-Length"] == "4" def test_override_host_header() -> None: headers = {"host": "1.2.3.4:80"} request = httpx2.Request("GET", "http://example.org", headers=headers) assert request.headers["Host"] == "1.2.3.4:80" def test_override_accept_encoding_header() -> None: headers = {"Accept-Encoding": "identity"} request = httpx2.Request("GET", "http://example.org", headers=headers) assert request.headers["Accept-Encoding"] == "identity" def test_override_content_length_header() -> None: async def streaming_body(data: bytes) -> typing.AsyncIterator[bytes]: yield data # pragma: no cover data = streaming_body(b"test 123") headers = {"Content-Length": "8"} request = httpx2.Request("POST", "http://example.org", content=data, headers=headers) assert request.headers["Content-Length"] == "8" def test_url() -> None: url = "http://example.org" request = httpx2.Request("GET", url) assert request.url.scheme == "http" assert request.url.port is None assert request.url.path == "/" assert request.url.raw_path == b"/" url = "https://example.org/abc?foo=bar" request = httpx2.Request("GET", url) assert request.url.scheme == "https" assert request.url.port is None assert request.url.path == "/abc" assert request.url.raw_path == b"/abc?foo=bar" def test_request_picklable() -> None: request = httpx2.Request("POST", "http://example.org", json={"test": 123}) pickle_request = pickle.loads(pickle.dumps(request)) assert pickle_request.method == "POST" assert pickle_request.url.path == "/" assert pickle_request.headers["Content-Type"] == "application/json" assert pickle_request.content == b'{"test":123}' assert pickle_request.stream is not None assert request.headers == { "Host": "example.org", "Content-Type": "application/json", "content-length": "12", } @pytest.mark.anyio async def test_request_async_streaming_content_picklable() -> None: async def streaming_body(data: bytes) -> typing.AsyncIterator[bytes]: yield data data = streaming_body(b"test 123") request = httpx2.Request("POST", "http://example.org", content=data) pickle_request = pickle.loads(pickle.dumps(request)) with pytest.raises(httpx2.RequestNotRead): pickle_request.content # noqa: B018 with pytest.raises(httpx2.StreamClosed): await pickle_request.aread() request = httpx2.Request("POST", "http://example.org", content=data) await request.aread() pickle_request = pickle.loads(pickle.dumps(request)) assert pickle_request.content == b"test 123" def test_request_generator_content_picklable() -> None: def content() -> typing.Iterator[bytes]: yield b"test 123" # pragma: no cover request = httpx2.Request("POST", "http://example.org", content=content()) pickle_request = pickle.loads(pickle.dumps(request)) with pytest.raises(httpx2.RequestNotRead): pickle_request.content # noqa: B018 with pytest.raises(httpx2.StreamClosed): pickle_request.read() request = httpx2.Request("POST", "http://example.org", content=content()) request.read() pickle_request = pickle.loads(pickle.dumps(request)) assert pickle_request.content == b"test 123" def test_request_params() -> None: request = httpx2.Request("GET", "http://example.com", params={}) assert str(request.url) == "http://example.com" request = httpx2.Request("GET", "http://example.com?c=3", params={"a": "1", "b": "2"}) assert str(request.url) == "http://example.com?a=1&b=2" request = httpx2.Request("GET", "http://example.com?a=1", params={}) assert str(request.url) == "http://example.com" pydantic-httpx2-6dd59b9/tests/httpx2/models/test_responses.py000066400000000000000000000750561526547463400245510ustar00rootroot00000000000000from __future__ import annotations import datetime import json import pickle import typing import chardet import pytest import httpx2 class StreamingBody: def __iter__(self) -> typing.Iterator[bytes]: yield b"Hello, " yield b"world!" def streaming_body() -> typing.Iterator[bytes]: yield b"Hello, " yield b"world!" async def async_streaming_body() -> typing.AsyncIterator[bytes]: yield b"Hello, " yield b"world!" def autodetect(content: bytes) -> str | None: return chardet.detect(content).get("encoding") def test_response() -> None: response = httpx2.Response( 200, content=b"Hello, world!", request=httpx2.Request("GET", "https://example.org"), ) assert response.status_code == 200 assert response.reason_phrase == "OK" assert response.text == "Hello, world!" assert response.request.method == "GET" assert response.request.url == "https://example.org" assert not response.is_error def test_response_content() -> None: response = httpx2.Response(200, content="Hello, world!") assert response.status_code == 200 assert response.reason_phrase == "OK" assert response.text == "Hello, world!" assert response.headers == {"Content-Length": "13"} def test_response_text() -> None: response = httpx2.Response(200, text="Hello, world!") assert response.status_code == 200 assert response.reason_phrase == "OK" assert response.text == "Hello, world!" assert response.headers == { "Content-Length": "13", "Content-Type": "text/plain; charset=utf-8", } def test_response_html() -> None: response = httpx2.Response(200, html="Hello, world!") assert response.status_code == 200 assert response.reason_phrase == "OK" assert response.text == "Hello, world!" assert response.headers == { "Content-Length": "39", "Content-Type": "text/html; charset=utf-8", } def test_response_json() -> None: response = httpx2.Response(200, json={"hello": "world"}) assert response.status_code == 200 assert response.reason_phrase == "OK" assert str(response.json()) == "{'hello': 'world'}" assert response.headers == { "Content-Length": "17", "Content-Type": "application/json", } def test_raise_for_status() -> None: request = httpx2.Request("GET", "https://example.org") # 2xx status codes are not an error. response = httpx2.Response(200, request=request) response.raise_for_status() # 1xx status codes are informational responses. response = httpx2.Response(101, request=request) assert response.is_informational with pytest.raises(httpx2.HTTPStatusError) as exc_info: response.raise_for_status() assert str(exc_info.value) == ( "Informational response '101 Switching Protocols' for url 'https://example.org'\n" "For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/101" ) # 3xx status codes are redirections. headers = {"location": "https://other.org"} response = httpx2.Response(303, headers=headers, request=request) assert response.is_redirect with pytest.raises(httpx2.HTTPStatusError) as exc_info: response.raise_for_status() assert str(exc_info.value) == ( "Redirect response '303 See Other' for url 'https://example.org'\n" "Redirect location: 'https://other.org'\n" "For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/303" ) # 4xx status codes are a client error. response = httpx2.Response(403, request=request) assert response.is_client_error assert response.is_error with pytest.raises(httpx2.HTTPStatusError) as exc_info: response.raise_for_status() assert str(exc_info.value) == ( "Client error '403 Forbidden' for url 'https://example.org'\n" "For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403" ) # 5xx status codes are a server error. response = httpx2.Response(500, request=request) assert response.is_server_error assert response.is_error with pytest.raises(httpx2.HTTPStatusError) as exc_info: response.raise_for_status() assert str(exc_info.value) == ( "Server error '500 Internal Server Error' for url 'https://example.org'\n" "For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500" ) # Calling .raise_for_status without setting a request instance is # not valid. Should raise a runtime error. response = httpx2.Response(200) with pytest.raises(RuntimeError): response.raise_for_status() def test_response_repr() -> None: response = httpx2.Response( 200, content=b"Hello, world!", ) assert repr(response) == "" def test_response_content_type_encoding() -> None: """ Use the charset encoding in the Content-Type header if possible. """ headers = {"Content-Type": "text-plain; charset=latin-1"} content = "Latin 1: รฟ".encode("latin-1") response = httpx2.Response( 200, content=content, headers=headers, ) assert response.text == "Latin 1: รฟ" assert response.encoding == "latin-1" def test_response_default_to_utf8_encoding() -> None: """ Default to utf-8 encoding if there is no Content-Type header. """ content = "ใŠใฏใ‚ˆใ†ใ”ใ–ใ„ใพใ™ใ€‚".encode() response = httpx2.Response( 200, content=content, ) assert response.text == "ใŠใฏใ‚ˆใ†ใ”ใ–ใ„ใพใ™ใ€‚" assert response.encoding == "utf-8" def test_response_fallback_to_utf8_encoding() -> None: """ Fallback to utf-8 if we get an invalid charset in the Content-Type header. """ headers = {"Content-Type": "text-plain; charset=invalid-codec-name"} content = "ใŠใฏใ‚ˆใ†ใ”ใ–ใ„ใพใ™ใ€‚".encode() response = httpx2.Response( 200, content=content, headers=headers, ) assert response.text == "ใŠใฏใ‚ˆใ†ใ”ใ–ใ„ใพใ™ใ€‚" assert response.encoding == "utf-8" def test_response_no_charset_with_ascii_content() -> None: """ A response with ascii encoded content should decode correctly, even with no charset specified. """ content = b"Hello, world!" headers = {"Content-Type": "text/plain"} response = httpx2.Response( 200, content=content, headers=headers, ) assert response.status_code == 200 assert response.encoding == "utf-8" assert response.text == "Hello, world!" def test_response_no_charset_with_utf8_content() -> None: """ A response with UTF-8 encoded content should decode correctly, even with no charset specified. """ content = "Unicode Snowman: โ˜ƒ".encode() headers = {"Content-Type": "text/plain"} response = httpx2.Response( 200, content=content, headers=headers, ) assert response.text == "Unicode Snowman: โ˜ƒ" assert response.encoding == "utf-8" def test_response_no_charset_with_iso_8859_1_content() -> None: """ A response with ISO 8859-1 encoded content should decode correctly, even with no charset specified, if autodetect is enabled. """ content = "Accented: ร–sterreich abcdefghijklmnopqrstuzwxyz".encode("iso-8859-1") headers = {"Content-Type": "text/plain"} response = httpx2.Response(200, content=content, headers=headers, default_encoding=autodetect) assert response.text == "Accented: ร–sterreich abcdefghijklmnopqrstuzwxyz" assert response.charset_encoding is None def test_response_no_charset_with_cp_1252_content() -> None: """ A response with Windows 1252 encoded content should decode correctly, even with no charset specified, if autodetect is enabled. """ text = "Non-seulement Desprรฉaux ne se trompait pas โ€” mais de tous les รฉcrivains que la France a produits." content = text.encode("cp1252") headers = {"Content-Type": "text/plain"} response = httpx2.Response(200, content=content, headers=headers, default_encoding=autodetect) assert response.text == text assert response.charset_encoding is None def test_response_non_text_encoding() -> None: """ Default to attempting utf-8 encoding for non-text content-type headers. """ headers = {"Content-Type": "image/png"} response = httpx2.Response( 200, content=b"xyz", headers=headers, ) assert response.text == "xyz" assert response.encoding == "utf-8" def test_response_set_explicit_encoding() -> None: headers = {"Content-Type": "text-plain; charset=utf-8"} # Deliberately incorrect charset response = httpx2.Response( 200, content="Latin 1: รฟ".encode("latin-1"), headers=headers, ) response.encoding = "latin-1" assert response.text == "Latin 1: รฟ" assert response.encoding == "latin-1" def test_response_force_encoding() -> None: response = httpx2.Response( 200, content="Snowman: โ˜ƒ".encode(), ) response.encoding = "iso-8859-1" assert response.status_code == 200 assert response.reason_phrase == "OK" assert response.text == "Snowman: รข\x98\x83" assert response.encoding == "iso-8859-1" def test_response_force_encoding_after_text_accessed() -> None: response = httpx2.Response( 200, content=b"Hello, world!", ) assert response.status_code == 200 assert response.reason_phrase == "OK" assert response.text == "Hello, world!" assert response.encoding == "utf-8" with pytest.raises(ValueError): response.encoding = "UTF8" with pytest.raises(ValueError): response.encoding = "iso-8859-1" def test_read() -> None: response = httpx2.Response( 200, content=b"Hello, world!", ) assert response.status_code == 200 assert response.text == "Hello, world!" assert response.encoding == "utf-8" assert response.is_closed content = response.read() assert content == b"Hello, world!" assert response.content == b"Hello, world!" assert response.is_closed def test_empty_read() -> None: response = httpx2.Response(200) assert response.status_code == 200 assert response.text == "" assert response.encoding == "utf-8" assert response.is_closed content = response.read() assert content == b"" assert response.content == b"" assert response.is_closed @pytest.mark.anyio async def test_aread() -> None: response = httpx2.Response( 200, content=b"Hello, world!", ) assert response.status_code == 200 assert response.text == "Hello, world!" assert response.encoding == "utf-8" assert response.is_closed content = await response.aread() assert content == b"Hello, world!" assert response.content == b"Hello, world!" assert response.is_closed @pytest.mark.anyio async def test_empty_aread() -> None: response = httpx2.Response(200) assert response.status_code == 200 assert response.text == "" assert response.encoding == "utf-8" assert response.is_closed content = await response.aread() assert content == b"" assert response.content == b"" assert response.is_closed def test_iter_raw() -> None: response = httpx2.Response( 200, content=streaming_body(), ) raw = b"" for part in response.iter_raw(): raw += part assert raw == b"Hello, world!" def test_iter_raw_with_chunksize() -> None: response = httpx2.Response(200, content=streaming_body()) parts = list(response.iter_raw(chunk_size=5)) assert parts == [b"Hello", b", wor", b"ld!"] response = httpx2.Response(200, content=streaming_body()) parts = list(response.iter_raw(chunk_size=7)) assert parts == [b"Hello, ", b"world!"] response = httpx2.Response(200, content=streaming_body()) parts = list(response.iter_raw(chunk_size=13)) assert parts == [b"Hello, world!"] response = httpx2.Response(200, content=streaming_body()) parts = list(response.iter_raw(chunk_size=20)) assert parts == [b"Hello, world!"] def test_iter_raw_doesnt_return_empty_chunks() -> None: def streaming_body_with_empty_chunks() -> typing.Iterator[bytes]: yield b"Hello, " yield b"" yield b"world!" yield b"" response = httpx2.Response(200, content=streaming_body_with_empty_chunks()) parts = list(response.iter_raw()) assert parts == [b"Hello, ", b"world!"] def test_iter_raw_on_iterable() -> None: response = httpx2.Response( 200, content=StreamingBody(), ) raw = b"" for part in response.iter_raw(): raw += part assert raw == b"Hello, world!" def test_iter_raw_on_async() -> None: response = httpx2.Response( 200, content=async_streaming_body(), ) with pytest.raises(RuntimeError): list(response.iter_raw()) def test_close_on_async() -> None: response = httpx2.Response( 200, content=async_streaming_body(), ) with pytest.raises(RuntimeError): response.close() def test_iter_raw_increments_updates_counter() -> None: response = httpx2.Response(200, content=streaming_body()) num_downloaded = response.num_bytes_downloaded for part in response.iter_raw(): assert len(part) == (response.num_bytes_downloaded - num_downloaded) num_downloaded = response.num_bytes_downloaded @pytest.mark.anyio async def test_aiter_raw() -> None: response = httpx2.Response(200, content=async_streaming_body()) raw = b"" async for part in response.aiter_raw(): raw += part assert raw == b"Hello, world!" @pytest.mark.anyio async def test_aiter_raw_with_chunksize() -> None: response = httpx2.Response(200, content=async_streaming_body()) parts = [part async for part in response.aiter_raw(chunk_size=5)] assert parts == [b"Hello", b", wor", b"ld!"] response = httpx2.Response(200, content=async_streaming_body()) parts = [part async for part in response.aiter_raw(chunk_size=13)] assert parts == [b"Hello, world!"] response = httpx2.Response(200, content=async_streaming_body()) parts = [part async for part in response.aiter_raw(chunk_size=20)] assert parts == [b"Hello, world!"] @pytest.mark.anyio async def test_aiter_raw_on_sync() -> None: response = httpx2.Response( 200, content=streaming_body(), ) with pytest.raises(RuntimeError): [part async for part in response.aiter_raw()] @pytest.mark.anyio async def test_aclose_on_sync() -> None: response = httpx2.Response( 200, content=streaming_body(), ) with pytest.raises(RuntimeError): await response.aclose() @pytest.mark.anyio async def test_aiter_raw_increments_updates_counter() -> None: response = httpx2.Response(200, content=async_streaming_body()) num_downloaded = response.num_bytes_downloaded async for part in response.aiter_raw(): assert len(part) == (response.num_bytes_downloaded - num_downloaded) num_downloaded = response.num_bytes_downloaded def test_iter_bytes() -> None: response = httpx2.Response(200, content=b"Hello, world!") content = b"" for part in response.iter_bytes(): content += part assert content == b"Hello, world!" def test_iter_bytes_with_chunk_size() -> None: response = httpx2.Response(200, content=streaming_body()) parts = list(response.iter_bytes(chunk_size=5)) assert parts == [b"Hello", b", wor", b"ld!"] response = httpx2.Response(200, content=streaming_body()) parts = list(response.iter_bytes(chunk_size=13)) assert parts == [b"Hello, world!"] response = httpx2.Response(200, content=streaming_body()) parts = list(response.iter_bytes(chunk_size=20)) assert parts == [b"Hello, world!"] def test_iter_bytes_with_empty_response() -> None: response = httpx2.Response(200, content=b"") parts = list(response.iter_bytes()) assert parts == [] def test_iter_bytes_doesnt_return_empty_chunks() -> None: def streaming_body_with_empty_chunks() -> typing.Iterator[bytes]: yield b"Hello, " yield b"" yield b"world!" yield b"" response = httpx2.Response(200, content=streaming_body_with_empty_chunks()) parts = list(response.iter_bytes()) assert parts == [b"Hello, ", b"world!"] @pytest.mark.anyio async def test_aiter_bytes() -> None: response = httpx2.Response( 200, content=b"Hello, world!", ) content = b"" async for part in response.aiter_bytes(): content += part assert content == b"Hello, world!" @pytest.mark.anyio async def test_aiter_bytes_with_chunk_size() -> None: response = httpx2.Response(200, content=async_streaming_body()) parts = [part async for part in response.aiter_bytes(chunk_size=5)] assert parts == [b"Hello", b", wor", b"ld!"] response = httpx2.Response(200, content=async_streaming_body()) parts = [part async for part in response.aiter_bytes(chunk_size=13)] assert parts == [b"Hello, world!"] response = httpx2.Response(200, content=async_streaming_body()) parts = [part async for part in response.aiter_bytes(chunk_size=20)] assert parts == [b"Hello, world!"] def test_iter_text() -> None: response = httpx2.Response( 200, content=b"Hello, world!", ) content = "" for part in response.iter_text(): content += part assert content == "Hello, world!" def test_iter_text_with_chunk_size() -> None: response = httpx2.Response(200, content=b"Hello, world!") parts = list(response.iter_text(chunk_size=5)) assert parts == ["Hello", ", wor", "ld!"] response = httpx2.Response(200, content=b"Hello, world!!") parts = list(response.iter_text(chunk_size=7)) assert parts == ["Hello, ", "world!!"] response = httpx2.Response(200, content=b"Hello, world!") parts = list(response.iter_text(chunk_size=7)) assert parts == ["Hello, ", "world!"] response = httpx2.Response(200, content=b"Hello, world!") parts = list(response.iter_text(chunk_size=13)) assert parts == ["Hello, world!"] response = httpx2.Response(200, content=b"Hello, world!") parts = list(response.iter_text(chunk_size=20)) assert parts == ["Hello, world!"] @pytest.mark.anyio async def test_aiter_text() -> None: response = httpx2.Response( 200, content=b"Hello, world!", ) content = "" async for part in response.aiter_text(): content += part assert content == "Hello, world!" @pytest.mark.anyio async def test_aiter_text_with_chunk_size() -> None: response = httpx2.Response(200, content=b"Hello, world!") parts = [part async for part in response.aiter_text(chunk_size=5)] assert parts == ["Hello", ", wor", "ld!"] response = httpx2.Response(200, content=b"Hello, world!") parts = [part async for part in response.aiter_text(chunk_size=13)] assert parts == ["Hello, world!"] response = httpx2.Response(200, content=b"Hello, world!") parts = [part async for part in response.aiter_text(chunk_size=20)] assert parts == ["Hello, world!"] def test_iter_lines() -> None: response = httpx2.Response( 200, content=b"Hello,\nworld!", ) content = list(response.iter_lines()) assert content == ["Hello,", "world!"] @pytest.mark.anyio async def test_aiter_lines() -> None: response = httpx2.Response( 200, content=b"Hello,\nworld!", ) content = [line async for line in response.aiter_lines()] assert content == ["Hello,", "world!"] def test_sync_streaming_response() -> None: response = httpx2.Response( 200, content=streaming_body(), ) assert response.status_code == 200 assert not response.is_closed content = response.read() assert content == b"Hello, world!" assert response.content == b"Hello, world!" assert response.is_closed @pytest.mark.anyio async def test_async_streaming_response() -> None: response = httpx2.Response( 200, content=async_streaming_body(), ) assert response.status_code == 200 assert not response.is_closed content = await response.aread() assert content == b"Hello, world!" assert response.content == b"Hello, world!" assert response.is_closed def test_cannot_read_after_stream_consumed() -> None: response = httpx2.Response( 200, content=streaming_body(), ) content = b"" for part in response.iter_bytes(): content += part with pytest.raises(httpx2.StreamConsumed): response.read() @pytest.mark.anyio async def test_cannot_aread_after_stream_consumed() -> None: response = httpx2.Response( 200, content=async_streaming_body(), ) content = b"" async for part in response.aiter_bytes(): content += part with pytest.raises(httpx2.StreamConsumed): await response.aread() def test_cannot_read_after_response_closed() -> None: response = httpx2.Response( 200, content=streaming_body(), ) response.close() with pytest.raises(httpx2.StreamClosed): response.read() @pytest.mark.anyio async def test_cannot_aread_after_response_closed() -> None: response = httpx2.Response( 200, content=async_streaming_body(), ) await response.aclose() with pytest.raises(httpx2.StreamClosed): await response.aread() @pytest.mark.anyio async def test_elapsed_not_available_until_closed() -> None: response = httpx2.Response( 200, content=async_streaming_body(), ) with pytest.raises(RuntimeError): response.elapsed # noqa: B018 def test_elapsed_set_directly() -> None: response = httpx2.Response(200) response.elapsed = datetime.timedelta(seconds=1) assert response.elapsed == datetime.timedelta(seconds=1) def test_unknown_status_code() -> None: response = httpx2.Response( 600, ) assert response.status_code == 600 assert response.reason_phrase == "" assert response.text == "" def test_json_with_specified_encoding() -> None: data = {"greeting": "hello", "recipient": "world"} content = json.dumps(data).encode("utf-16") headers = {"Content-Type": "application/json, charset=utf-16"} response = httpx2.Response( 200, content=content, headers=headers, ) assert response.json() == data def test_json_with_options() -> None: data = {"greeting": "hello", "recipient": "world", "amount": 1} content = json.dumps(data).encode("utf-16") headers = {"Content-Type": "application/json, charset=utf-16"} response = httpx2.Response( 200, content=content, headers=headers, ) assert response.json(parse_int=str)["amount"] == "1" @pytest.mark.parametrize( "encoding", [ "utf-8", "utf-8-sig", "utf-16", "utf-16-be", "utf-16-le", "utf-32", "utf-32-be", "utf-32-le", ], ) def test_json_without_specified_charset(encoding: str) -> None: data = {"greeting": "hello", "recipient": "world"} content = json.dumps(data).encode(encoding) headers = {"Content-Type": "application/json"} response = httpx2.Response( 200, content=content, headers=headers, ) assert response.json() == data @pytest.mark.parametrize( "encoding", [ "utf-8", "utf-8-sig", "utf-16", "utf-16-be", "utf-16-le", "utf-32", "utf-32-be", "utf-32-le", ], ) def test_json_with_specified_charset(encoding: str) -> None: data = {"greeting": "hello", "recipient": "world"} content = json.dumps(data).encode(encoding) headers = {"Content-Type": f"application/json; charset={encoding}"} response = httpx2.Response( 200, content=content, headers=headers, ) assert response.json() == data @pytest.mark.parametrize( "headers, expected", [ ( {"Link": "; rel='preload'"}, {"preload": {"rel": "preload", "url": "https://example.com"}}, ), ( {"Link": '; rel="hub", ; rel="self"'}, { "hub": {"url": "/hub", "rel": "hub"}, "self": {"url": "/resource", "rel": "self"}, }, ), ], ) def test_link_headers(headers: dict[str, str], expected: dict[str, dict[str, str]]) -> None: response = httpx2.Response( 200, content=None, headers=headers, ) assert response.links == expected @pytest.mark.parametrize("header_value", (b"deflate", b"gzip", b"br")) def test_decode_error_with_request(header_value: bytes) -> None: headers = [(b"Content-Encoding", header_value)] broken_compressed_body = b"xxxxxxxxxxxxxx" with pytest.raises(httpx2.DecodingError): httpx2.Response( 200, headers=headers, content=broken_compressed_body, ) with pytest.raises(httpx2.DecodingError): httpx2.Response( 200, headers=headers, content=broken_compressed_body, request=httpx2.Request("GET", "https://www.example.org/"), ) @pytest.mark.parametrize("header_value", (b"deflate", b"gzip", b"br")) def test_value_error_without_request(header_value: bytes) -> None: headers = [(b"Content-Encoding", header_value)] broken_compressed_body = b"xxxxxxxxxxxxxx" with pytest.raises(httpx2.DecodingError): httpx2.Response(200, headers=headers, content=broken_compressed_body) def test_response_with_unset_request() -> None: response = httpx2.Response(200, content=b"Hello, world!") assert response.status_code == 200 assert response.reason_phrase == "OK" assert response.text == "Hello, world!" assert not response.is_error def test_set_request_after_init() -> None: response = httpx2.Response(200, content=b"Hello, world!") response.request = httpx2.Request("GET", "https://www.example.org") assert response.request.method == "GET" assert response.request.url == "https://www.example.org" def test_cannot_access_unset_request() -> None: response = httpx2.Response(200, content=b"Hello, world!") with pytest.raises(RuntimeError): response.request # noqa: B018 def test_generator_with_transfer_encoding_header() -> None: def content() -> typing.Iterator[bytes]: yield b"test 123" # pragma: no cover response = httpx2.Response(200, content=content()) assert response.headers == {"Transfer-Encoding": "chunked"} def test_generator_with_content_length_header() -> None: def content() -> typing.Iterator[bytes]: yield b"test 123" # pragma: no cover headers = {"Content-Length": "8"} response = httpx2.Response(200, content=content(), headers=headers) assert response.headers == {"Content-Length": "8"} def test_response_picklable() -> None: response = httpx2.Response( 200, content=b"Hello, world!", request=httpx2.Request("GET", "https://example.org"), ) pickle_response = pickle.loads(pickle.dumps(response)) assert pickle_response.is_closed is True assert pickle_response.is_stream_consumed is True assert pickle_response.next_request is None assert pickle_response.stream is not None assert pickle_response.content == b"Hello, world!" assert pickle_response.status_code == 200 assert pickle_response.request.url == response.request.url assert pickle_response.extensions == {} assert pickle_response.history == [] @pytest.mark.anyio async def test_response_async_streaming_picklable() -> None: response = httpx2.Response(200, content=async_streaming_body()) pickle_response = pickle.loads(pickle.dumps(response)) with pytest.raises(httpx2.ResponseNotRead): pickle_response.content # noqa: B018 with pytest.raises(httpx2.StreamClosed): await pickle_response.aread() assert pickle_response.is_stream_consumed is False assert pickle_response.num_bytes_downloaded == 0 assert pickle_response.headers == {"Transfer-Encoding": "chunked"} response = httpx2.Response(200, content=async_streaming_body()) await response.aread() pickle_response = pickle.loads(pickle.dumps(response)) assert pickle_response.is_stream_consumed is True assert pickle_response.content == b"Hello, world!" assert pickle_response.num_bytes_downloaded == 13 def test_response_decode_text_using_autodetect() -> None: # Ensure that a 'default_encoding="autodetect"' on the response allows for # encoding autodetection to be used when no "Content-Type: text/plain; charset=..." # info is present. # # Here we have some french text encoded with WINDOWS-1252, rather than UTF-8. # The curly quotes and em dash occupy bytes 0x80-0x9F, which are control # characters in ISO-8859-1, so the encoding is unambiguously WINDOWS-1252. text = ( "Non-seulement Desprรฉaux ne se trompait pas โ€” mais de tous les รฉcrivains " "que la France a produits, sans excepter Voltaire lui-mรชme, imprรฉgnรฉ de " "lโ€™esprit anglais par son sรฉjour ร  Londres, cโ€™est incontestablement " "โ€œMoliรจreโ€ ou Poquelin qui reproduit avec lโ€™exactitude la plus vive et la " "plus complรจte le fond du gรฉnie franรงais." ) content = text.encode("WINDOWS-1252") response = httpx2.Response(200, content=content, default_encoding=autodetect) assert response.status_code == 200 assert response.reason_phrase == "OK" assert response.encoding == "Windows-1252" assert response.text == text def test_response_decode_text_using_explicit_encoding() -> None: # Ensure that a 'default_encoding="..."' on the response is used for text decoding # when no "Content-Type: text/plain; charset=..."" info is present. # # Here we have some french text encoded with Windows-1252, rather than UTF-8. # https://en.wikipedia.org/wiki/Windows-1252 text = ( "Non-seulement Desprรฉaux ne se trompait pas, mais de tous les รฉcrivains " "que la France a produits, sans excepter Voltaire lui-mรชme, imprรฉgnรฉ de " "l'esprit anglais par son sรฉjour ร  Londres, c'est incontestablement " "Moliรจre ou Poquelin qui reproduit avec l'exactitude la plus vive et la " "plus complรจte le fond du gรฉnie franรงais." ) content = text.encode("cp1252") response = httpx2.Response(200, content=content, default_encoding="cp1252") assert response.status_code == 200 assert response.reason_phrase == "OK" assert response.encoding == "cp1252" assert response.text == text pydantic-httpx2-6dd59b9/tests/httpx2/models/test_url.py000066400000000000000000000744121526547463400233250ustar00rootroot00000000000000from __future__ import annotations import pytest import httpx2 # Tests for `httpx2.URL` instantiation and property accessors. def test_basic_url() -> None: url = httpx2.URL("https://www.example.com/") assert url.scheme == "https" assert url.userinfo == b"" assert url.netloc == b"www.example.com" assert url.host == "www.example.com" assert url.port is None assert url.path == "/" assert url.query == b"" assert url.fragment == "" assert str(url) == "https://www.example.com/" assert repr(url) == "URL('https://www.example.com/')" def test_complete_url() -> None: url = httpx2.URL("https://example.org:123/path/to/somewhere?abc=123#anchor") assert url.scheme == "https" assert url.host == "example.org" assert url.port == 123 assert url.path == "/path/to/somewhere" assert url.query == b"abc=123" assert url.raw_path == b"/path/to/somewhere?abc=123" assert url.fragment == "anchor" assert str(url) == "https://example.org:123/path/to/somewhere?abc=123#anchor" assert repr(url) == "URL('https://example.org:123/path/to/somewhere?abc=123#anchor')" def test_url_with_empty_query() -> None: """ URLs with and without a trailing `?` but an empty query component should preserve the information on the raw path. """ url = httpx2.URL("https://www.example.com/path") assert url.path == "/path" assert url.query == b"" assert url.raw_path == b"/path" url = httpx2.URL("https://www.example.com/path?") assert url.path == "/path" assert url.query == b"" assert url.raw_path == b"/path?" def test_url_no_scheme() -> None: url = httpx2.URL("://example.com") assert url.scheme == "" assert url.host == "example.com" assert url.path == "/" def test_url_no_authority() -> None: url = httpx2.URL("http://") assert url.scheme == "http" assert url.host == "" assert url.path == "/" def test_origin() -> None: url = httpx2.URL("https://user:password@example.com/path?query#fragment") assert url.origin == httpx2.Origin("https://example.com") assert url.origin.scheme == "https" assert url.origin.host == "example.com" assert url.origin.port == 443 assert repr(url.origin) == "Origin(scheme='https', host='example.com', port=443)" def test_origin_is_immutable_and_hashable() -> None: origin = httpx2.Origin("https://example.com") with pytest.raises(AttributeError): origin.host = "other.example.com" # type: ignore[misc] assert {origin, httpx2.Origin("HTTPS://EXAMPLE.COM:443")} == {origin} @pytest.mark.parametrize( "url,scheme,port", [ ("ftp://example.com", "ftp", 21), ("http://example.com", "http", 80), ("https://example.com", "https", 443), ("ws://example.com/socket", "ws", 80), ("wss://example.com/socket", "wss", 443), ("custom://example.com", "custom", None), ("custom://example.com:1234", "custom", 1234), ], ) def test_origin_effective_port(url: str, scheme: str, port: int | None) -> None: origin = httpx2.Origin(url) assert origin.scheme == scheme assert origin.port == port @pytest.mark.parametrize( "left,right", [ ("https://example.com", "HTTPS://EXAMPLE.COM:443"), ("https://ไธญๅ›ฝ.icom.museum", "https://xn--fiqs8s.icom.museum:443"), ("ws://example.com/socket", "ws://example.com:80/other"), ("wss://example.com/socket", "wss://example.com:443/other"), ("https://[::1]", "https://[0:0:0:0:0:0:0:1]"), ("https://[2001:db8::1]", "https://[2001:0db8:0:0:0:0:0:1]"), ("https://[::ffff:192.168.0.1]", "https://[::ffff:c0a8:1]"), ("https://[fe80::1%25eth0]", "https://[fe80:0:0:0:0:0:0:1%25eth0]"), ], ) def test_equivalent_origins(left: str, right: str) -> None: assert httpx2.URL(left).origin == httpx2.URL(right).origin @pytest.mark.parametrize( "left,right", [ ("http://example.com", "https://example.com"), ("http://example.com", "ws://example.com"), ("https://example.com", "wss://example.com"), ("https://example.com", "https://example.com:444"), ("https://[::1]", "https://[::2]"), ("https://[fe80::1%25eth0]", "https://[fe80::1%25eth1]"), ("https://[fe80::1%eth0]", "https://[fe80::1%25eth0]"), ("https://[2001:db8::1%30]", "https://[2001:db8::10]"), ], ) def test_distinct_origins(left: str, right: str) -> None: assert httpx2.URL(left).origin != httpx2.URL(right).origin @pytest.mark.parametrize("url", ["", "/path", "mailto:user@example.com", "file:///tmp/example"]) def test_relative_url_does_not_have_origin(url: str) -> None: with pytest.raises(ValueError, match="URL must be absolute to have an origin"): _ = httpx2.URL(url).origin def test_origin_preserves_percent_escaped_ipv6_scope() -> None: assert httpx2.Origin("https://[2001:db8::1%2e]").host == "2001:db8::1%2e" # Tests for percent encoding across path, query, and fragment... @pytest.mark.parametrize( "url,raw_path,path,query,fragment", [ # URL with unescaped chars in path. ( "https://example.com/!$&'()*+,;= abc ABC 123 :/[]@", b"/!$&'()*+,;=%20abc%20ABC%20123%20:/[]@", "/!$&'()*+,;= abc ABC 123 :/[]@", b"", "", ), # URL with escaped chars in path. ( "https://example.com/!$&'()*+,;=%20abc%20ABC%20123%20:/[]@", b"/!$&'()*+,;=%20abc%20ABC%20123%20:/[]@", "/!$&'()*+,;= abc ABC 123 :/[]@", b"", "", ), # URL with mix of unescaped and escaped chars in path. # WARNING: This has the incorrect behaviour, adding the test as an interim step. ( "https://example.com/ %61%62%63", b"/%20%61%62%63", "/ abc", b"", "", ), # URL with unescaped chars in query. ( "https://example.com/?!$&'()*+,;= abc ABC 123 :/[]@?", b"/?!$&'()*+,;=%20abc%20ABC%20123%20:/[]@?", "/", b"!$&'()*+,;=%20abc%20ABC%20123%20:/[]@?", "", ), # URL with escaped chars in query. ( "https://example.com/?!$&%27()*+,;=%20abc%20ABC%20123%20:%2F[]@?", b"/?!$&%27()*+,;=%20abc%20ABC%20123%20:%2F[]@?", "/", b"!$&%27()*+,;=%20abc%20ABC%20123%20:%2F[]@?", "", ), # URL with mix of unescaped and escaped chars in query. ( "https://example.com/?%20%97%98%99", b"/?%20%97%98%99", "/", b"%20%97%98%99", "", ), # URL encoding characters in fragment. ( "https://example.com/#!$&'()*+,;= abc ABC 123 :/[]@?#", b"/", "/", b"", "!$&'()*+,;= abc ABC 123 :/[]@?#", ), ], ) def test_path_query_fragment(url: str, raw_path: bytes, path: str, query: bytes, fragment: str) -> None: parsed = httpx2.URL(url) assert parsed.raw_path == raw_path assert parsed.path == path assert parsed.query == query assert parsed.fragment == fragment def test_url_query_encoding() -> None: url = httpx2.URL("https://www.example.com/?a=b c&d=e/f") assert url.raw_path == b"/?a=b%20c&d=e/f" url = httpx2.URL("https://www.example.com/?a=b+c&d=e/f") assert url.raw_path == b"/?a=b+c&d=e/f" url = httpx2.URL("https://www.example.com/", params={"a": "b c", "d": "e/f"}) assert url.raw_path == b"/?a=b+c&d=e%2Ff" def test_url_params() -> None: url = httpx2.URL("https://example.org:123/path/to/somewhere", params={"a": "123"}) assert str(url) == "https://example.org:123/path/to/somewhere?a=123" assert url.params == httpx2.QueryParams({"a": "123"}) url = httpx2.URL("https://example.org:123/path/to/somewhere?b=456", params={"a": "123"}) assert str(url) == "https://example.org:123/path/to/somewhere?a=123" assert url.params == httpx2.QueryParams({"a": "123"}) # Tests for username and password @pytest.mark.parametrize( "url,userinfo,username,password", [ # username and password in URL. ( "https://username:password@example.com", b"username:password", "username", "password", ), # username and password in URL with percent escape sequences. ( "https://username%40gmail.com:pa%20ssword@example.com", b"username%40gmail.com:pa%20ssword", "username@gmail.com", "pa ssword", ), ( "https://user%20name:p%40ssword@example.com", b"user%20name:p%40ssword", "user name", "p@ssword", ), # username and password in URL without percent escape sequences. ( "https://username@gmail.com:pa ssword@example.com", b"username%40gmail.com:pa%20ssword", "username@gmail.com", "pa ssword", ), ( "https://user name:p@ssword@example.com", b"user%20name:p%40ssword", "user name", "p@ssword", ), ], ) def test_url_username_and_password(url: str, userinfo: bytes, username: str, password: str) -> None: parsed = httpx2.URL(url) assert parsed.userinfo == userinfo assert parsed.username == username assert parsed.password == password # Tests for different host types def test_url_valid_host() -> None: url = httpx2.URL("https://example.com/") assert url.host == "example.com" def test_url_normalized_host() -> None: url = httpx2.URL("https://EXAMPLE.com/") assert url.host == "example.com" def test_url_percent_escape_host() -> None: url = httpx2.URL("https://exam le.com/") assert url.host == "exam%20le.com" def test_url_ipv4_like_host() -> None: """rare host names used to quality as IPv4""" url = httpx2.URL("https://023b76x43144/") assert url.host == "023b76x43144" # Tests for different port types def test_url_valid_port() -> None: url = httpx2.URL("https://example.com:123/") assert url.port == 123 def test_url_normalized_port() -> None: # If the port matches the scheme default it is normalized to None. url = httpx2.URL("https://example.com:443/") assert url.port is None def test_url_invalid_port() -> None: with pytest.raises(httpx2.InvalidURL) as exc: httpx2.URL("https://example.com:abc/") assert str(exc.value) == "Invalid port: 'abc'" # Tests for path handling def test_url_normalized_path() -> None: url = httpx2.URL("https://example.com/abc/def/../ghi/./jkl") assert url.path == "/abc/ghi/jkl" def test_url_escaped_path() -> None: url = httpx2.URL("https://example.com/ /๐ŸŒŸ/") assert url.raw_path == b"/%20/%F0%9F%8C%9F/" def test_url_leading_dot_prefix_on_absolute_url() -> None: url = httpx2.URL("https://example.com/../abc") assert url.path == "/abc" def test_url_leading_dot_prefix_on_relative_url() -> None: url = httpx2.URL("../abc") assert url.path == "../abc" # Tests for query parameter percent encoding. # # Percent-encoding in `params={}` should match browser form behavior. def test_param_with_space() -> None: # Params passed as form key-value pairs should be form escaped, # Including the special case of "+" for space separators. url = httpx2.URL("http://webservice", params={"u": "with spaces"}) assert str(url) == "http://webservice?u=with+spaces" def test_param_requires_encoding() -> None: # Params passed as form key-value pairs should be escaped. url = httpx2.URL("http://webservice", params={"u": "%"}) assert str(url) == "http://webservice?u=%25" def test_param_with_percent_encoded() -> None: # Params passed as form key-value pairs should always be escaped, # even if they include a valid escape sequence. # We want to match browser form behaviour here. url = httpx2.URL("http://webservice", params={"u": "with%20spaces"}) assert str(url) == "http://webservice?u=with%2520spaces" def test_param_with_existing_escape_requires_encoding() -> None: # Params passed as form key-value pairs should always be escaped, # even if they include a valid escape sequence. # We want to match browser form behaviour here. url = httpx2.URL("http://webservice", params={"u": "http://example.com?q=foo%2Fa"}) assert str(url) == "http://webservice?u=http%3A%2F%2Fexample.com%3Fq%3Dfoo%252Fa" # Tests for query parameter percent encoding. # # Percent-encoding in `url={}` should match browser URL bar behavior. def test_query_with_existing_percent_encoding() -> None: # Valid percent encoded sequences should not be double encoded. url = httpx2.URL("http://webservice?u=phrase%20with%20spaces") assert str(url) == "http://webservice?u=phrase%20with%20spaces" def test_query_requiring_percent_encoding() -> None: # Characters that require percent encoding should be encoded. url = httpx2.URL("http://webservice?u=phrase with spaces") assert str(url) == "http://webservice?u=phrase%20with%20spaces" def test_query_with_mixed_percent_encoding() -> None: # When a mix of encoded and unencoded characters are present, # characters that require percent encoding should be encoded, # while existing sequences should not be double encoded. url = httpx2.URL("http://webservice?u=phrase%20with spaces") assert str(url) == "http://webservice?u=phrase%20with%20spaces" # Tests for invalid URLs def test_url_invalid_hostname() -> None: """ Ensure that invalid URLs raise an `httpx2.InvalidURL` exception. """ with pytest.raises(httpx2.InvalidURL): httpx2.URL("https://๐Ÿ˜‡/") def test_url_excessively_long_url() -> None: with pytest.raises(httpx2.InvalidURL) as exc: httpx2.URL("https://www.example.com/" + "x" * 100_000) assert str(exc.value) == "URL too long" def test_url_excessively_long_component() -> None: with pytest.raises(httpx2.InvalidURL) as exc: httpx2.URL("https://www.example.com", path="/" + "x" * 100_000) assert str(exc.value) == "URL component 'path' too long" def test_url_non_printing_character_in_url() -> None: with pytest.raises(httpx2.InvalidURL) as exc: httpx2.URL("https://www.example.com/\n") assert str(exc.value) == ("Invalid non-printable ASCII character in URL, '\\n' at position 24.") def test_url_non_printing_character_in_component() -> None: with pytest.raises(httpx2.InvalidURL) as exc: httpx2.URL("https://www.example.com", path="/\n") assert str(exc.value) == ("Invalid non-printable ASCII character in URL path component, '\\n' at position 1.") # Test for url components def test_url_with_components() -> None: url = httpx2.URL(scheme="https", host="www.example.com", path="/") assert url.scheme == "https" assert url.userinfo == b"" assert url.host == "www.example.com" assert url.port is None assert url.path == "/" assert url.query == b"" assert url.fragment == "" assert str(url) == "https://www.example.com/" def test_urlparse_with_invalid_component() -> None: with pytest.raises(TypeError) as exc: httpx2.URL(scheme="https", host="www.example.com", incorrect="/") assert str(exc.value) == "'incorrect' is an invalid keyword argument for URL()" def test_urlparse_with_invalid_scheme() -> None: with pytest.raises(httpx2.InvalidURL) as exc: httpx2.URL(scheme="~", host="www.example.com", path="/") assert str(exc.value) == "Invalid URL component 'scheme'" def test_urlparse_with_invalid_path() -> None: with pytest.raises(httpx2.InvalidURL) as exc: httpx2.URL(scheme="https", host="www.example.com", path="abc") assert str(exc.value) == "For absolute URLs, path must be empty or begin with '/'" with pytest.raises(httpx2.InvalidURL) as exc: httpx2.URL(path="//abc") assert str(exc.value) == "Relative URLs cannot have a path starting with '//'" with pytest.raises(httpx2.InvalidURL) as exc: httpx2.URL(path=":abc") assert str(exc.value) == "Relative URLs cannot have a path starting with ':'" def test_url_with_relative_path() -> None: # This path would be invalid for an absolute URL, but is valid as a relative URL. url = httpx2.URL(path="abc") assert url.path == "abc" # Tests for `httpx2.URL` python built-in operators. def test_url_eq_str() -> None: """ Ensure that `httpx2.URL` supports the equality operator. """ url = httpx2.URL("https://example.org:123/path/to/somewhere?abc=123#anchor") assert url == "https://example.org:123/path/to/somewhere?abc=123#anchor" assert str(url) == url def test_url_set() -> None: """ Ensure that `httpx2.URL` instances can be used in sets. """ urls = ( httpx2.URL("http://example.org:123/path/to/somewhere"), httpx2.URL("http://example.org:123/path/to/somewhere/else"), ) url_set = set(urls) assert all(url in urls for url in url_set) # Tests for TypeErrors when instantiating `httpx2.URL`. def test_url_invalid_type() -> None: """ Ensure that invalid types on `httpx2.URL()` raise a `TypeError`. """ class ExternalURLClass: # representing external URL class pass with pytest.raises(TypeError): httpx2.URL(ExternalURLClass()) # type: ignore def test_url_with_invalid_component() -> None: with pytest.raises(TypeError) as exc: httpx2.URL(scheme="https", host="www.example.com", incorrect="/") assert str(exc.value) == "'incorrect' is an invalid keyword argument for URL()" # Tests for `URL.join()`. def test_url_join() -> None: """ Some basic URL joining tests. """ url = httpx2.URL("https://example.org:123/path/to/somewhere") assert url.join("/somewhere-else") == "https://example.org:123/somewhere-else" assert url.join("somewhere-else") == "https://example.org:123/path/to/somewhere-else" assert url.join("../somewhere-else") == "https://example.org:123/path/somewhere-else" assert url.join("../../somewhere-else") == "https://example.org:123/somewhere-else" def test_relative_url_join() -> None: url = httpx2.URL("/path/to/somewhere") assert url.join("/somewhere-else") == "/somewhere-else" assert url.join("somewhere-else") == "/path/to/somewhere-else" assert url.join("../somewhere-else") == "/path/somewhere-else" assert url.join("../../somewhere-else") == "/somewhere-else" def test_url_join_rfc3986() -> None: """ URL joining tests, as-per reference examples in RFC 3986. https://tools.ietf.org/html/rfc3986#section-5.4 """ url = httpx2.URL("http://example.com/b/c/d;p?q") assert url.join("g") == "http://example.com/b/c/g" assert url.join("./g") == "http://example.com/b/c/g" assert url.join("g/") == "http://example.com/b/c/g/" assert url.join("/g") == "http://example.com/g" assert url.join("//g") == "http://g" assert url.join("?y") == "http://example.com/b/c/d;p?y" assert url.join("g?y") == "http://example.com/b/c/g?y" assert url.join("#s") == "http://example.com/b/c/d;p?q#s" assert url.join("g#s") == "http://example.com/b/c/g#s" assert url.join("g?y#s") == "http://example.com/b/c/g?y#s" assert url.join(";x") == "http://example.com/b/c/;x" assert url.join("g;x") == "http://example.com/b/c/g;x" assert url.join("g;x?y#s") == "http://example.com/b/c/g;x?y#s" assert url.join("") == "http://example.com/b/c/d;p?q" assert url.join(".") == "http://example.com/b/c/" assert url.join("./") == "http://example.com/b/c/" assert url.join("..") == "http://example.com/b/" assert url.join("../") == "http://example.com/b/" assert url.join("../g") == "http://example.com/b/g" assert url.join("../..") == "http://example.com/" assert url.join("../../") == "http://example.com/" assert url.join("../../g") == "http://example.com/g" assert url.join("../../../g") == "http://example.com/g" assert url.join("../../../../g") == "http://example.com/g" assert url.join("/./g") == "http://example.com/g" assert url.join("/../g") == "http://example.com/g" assert url.join("g.") == "http://example.com/b/c/g." assert url.join(".g") == "http://example.com/b/c/.g" assert url.join("g..") == "http://example.com/b/c/g.." assert url.join("..g") == "http://example.com/b/c/..g" assert url.join("./../g") == "http://example.com/b/g" assert url.join("./g/.") == "http://example.com/b/c/g/" assert url.join("g/./h") == "http://example.com/b/c/g/h" assert url.join("g/../h") == "http://example.com/b/c/h" assert url.join("g;x=1/./y") == "http://example.com/b/c/g;x=1/y" assert url.join("g;x=1/../y") == "http://example.com/b/c/y" assert url.join("g?y/./x") == "http://example.com/b/c/g?y/./x" assert url.join("g?y/../x") == "http://example.com/b/c/g?y/../x" assert url.join("g#s/./x") == "http://example.com/b/c/g#s/./x" assert url.join("g#s/../x") == "http://example.com/b/c/g#s/../x" def test_resolution_error_1833() -> None: """ See https://github.com/encode/httpx/issues/1833 """ url = httpx2.URL("https://example.com/?[]") assert url.join("/") == "https://example.com/" # Tests for `URL.copy_with()`. def test_copy_with() -> None: url = httpx2.URL("https://www.example.com/") assert str(url) == "https://www.example.com/" url = url.copy_with() assert str(url) == "https://www.example.com/" url = url.copy_with(scheme="http") assert str(url) == "http://www.example.com/" url = url.copy_with(netloc=b"example.com") assert str(url) == "http://example.com/" url = url.copy_with(path="/abc") assert str(url) == "http://example.com/abc" def test_url_copywith_authority_subcomponents() -> None: copy_with_kwargs = { "username": "username", "password": "password", "port": 444, "host": "example.net", } url = httpx2.URL("https://example.org") new = url.copy_with(**copy_with_kwargs) assert str(new) == "https://username:password@example.net:444" def test_url_copywith_netloc() -> None: copy_with_kwargs = { "netloc": b"example.net:444", } url = httpx2.URL("https://example.org") new = url.copy_with(**copy_with_kwargs) assert str(new) == "https://example.net:444" def test_url_copywith_userinfo_subcomponents() -> None: copy_with_kwargs = { "username": "tom@example.org", "password": "abc123@ %", } url = httpx2.URL("https://example.org") new = url.copy_with(**copy_with_kwargs) assert str(new) == "https://tom%40example.org:abc123%40%20%@example.org" assert new.username == "tom@example.org" assert new.password == "abc123@ %" assert new.userinfo == b"tom%40example.org:abc123%40%20%" def test_url_copywith_invalid_component() -> None: url = httpx2.URL("https://example.org") with pytest.raises(TypeError): url.copy_with(pathh="/incorrect-spelling") with pytest.raises(TypeError): url.copy_with(userinfo="should be bytes") def test_url_copywith_urlencoded_path() -> None: url = httpx2.URL("https://example.org") url = url.copy_with(path="/path to somewhere") assert url.path == "/path to somewhere" assert url.query == b"" assert url.raw_path == b"/path%20to%20somewhere" def test_url_copywith_query() -> None: url = httpx2.URL("https://example.org") url = url.copy_with(query=b"a=123") assert url.path == "/" assert url.query == b"a=123" assert url.raw_path == b"/?a=123" def test_url_copywith_raw_path() -> None: url = httpx2.URL("https://example.org") url = url.copy_with(raw_path=b"/some/path") assert url.path == "/some/path" assert url.query == b"" assert url.raw_path == b"/some/path" url = httpx2.URL("https://example.org") url = url.copy_with(raw_path=b"/some/path?") assert url.path == "/some/path" assert url.query == b"" assert url.raw_path == b"/some/path?" url = httpx2.URL("https://example.org") url = url.copy_with(raw_path=b"/some/path?a=123") assert url.path == "/some/path" assert url.query == b"a=123" assert url.raw_path == b"/some/path?a=123" def test_url_copywith_security() -> None: """ Prevent unexpected changes on URL after calling copy_with (CVE-2021-41945) """ with pytest.raises(httpx2.InvalidURL): httpx2.URL("https://u:p@[invalid!]//evilHost/path?t=w#tw") url = httpx2.URL("https://example.com/path?t=w#tw") bad = "https://xxxx:xxxx@xxxxxxx/xxxxx/xxx?x=x#xxxxx" with pytest.raises(httpx2.InvalidURL): url.copy_with(scheme=bad) # Tests for copy-modifying-parameters methods. # # `URL.copy_set_param()` # `URL.copy_add_param()` # `URL.copy_remove_param()` # `URL.copy_merge_params()` def test_url_set_param_manipulation() -> None: """ Some basic URL query parameter manipulation. """ url = httpx2.URL("https://example.org:123/?a=123") assert url.copy_set_param("a", "456") == "https://example.org:123/?a=456" def test_url_add_param_manipulation() -> None: """ Some basic URL query parameter manipulation. """ url = httpx2.URL("https://example.org:123/?a=123") assert url.copy_add_param("a", "456") == "https://example.org:123/?a=123&a=456" def test_url_remove_param_manipulation() -> None: """ Some basic URL query parameter manipulation. """ url = httpx2.URL("https://example.org:123/?a=123") assert url.copy_remove_param("a") == "https://example.org:123/" def test_url_merge_params_manipulation() -> None: """ Some basic URL query parameter manipulation. """ url = httpx2.URL("https://example.org:123/?a=123") assert url.copy_merge_params({"b": "456"}) == "https://example.org:123/?a=123&b=456" # Tests for IDNA hostname support. @pytest.mark.parametrize( "given,idna,host,raw_host,scheme,port", [ ( "http://ไธญๅ›ฝ.icom.museum:80/", "http://xn--fiqs8s.icom.museum:80/", "ไธญๅ›ฝ.icom.museum", b"xn--fiqs8s.icom.museum", "http", None, ), ( "http://KรถnigsgรครŸchen.de", "http://xn--knigsgchen-b4a3dun.de", "kรถnigsgรครŸchen.de", b"xn--knigsgchen-b4a3dun.de", "http", None, ), ( "https://faรŸ.de", "https://xn--fa-hia.de", "faรŸ.de", b"xn--fa-hia.de", "https", None, ), ( "https://ฮฒฯŒฮปฮฟฯ‚.com:443", "https://xn--nxasmm1c.com:443", "ฮฒฯŒฮปฮฟฯ‚.com", b"xn--nxasmm1c.com", "https", None, ), ( "http://เทเทŠโ€เถปเท“.com:444", "http://xn--10cl1a0b660p.com:444", "เทเทŠโ€เถปเท“.com", b"xn--10cl1a0b660p.com", "http", 444, ), ( "https://ู†ุงู…ู‡โ€Œุง�Œ.com:4433", "https://xn--mgba3gch31f060k.com:4433", "ู†ุงู…ู‡โ€Œุง�Œ.com", b"xn--mgba3gch31f060k.com", "https", 4433, ), ( "https://www.รฉgalitรฉ-femmes-hommes.gouv.fr", "https://www.xn--galit-femmes-hommes-9ybf.gouv.fr", "www.รฉgalitรฉ-femmes-hommes.gouv.fr", b"www.xn--galit-femmes-hommes-9ybf.gouv.fr", "https", None, ), ], ids=[ "http_with_port", "unicode_tr46_compat", "https_without_port", "https_with_port", "http_with_custom_port", "https_with_custom_port", "idna_label_after_ascii_label", ], ) def test_idna_url(given: str, idna: str, host: str, raw_host: bytes, scheme: str, port: int | None) -> None: url = httpx2.URL(given) assert url == httpx2.URL(idna) assert url.host == host assert url.raw_host == raw_host assert url.scheme == scheme assert url.port == port def test_url_unescaped_idna_host() -> None: url = httpx2.URL("https://ไธญๅ›ฝ.icom.museum/") assert url.raw_host == b"xn--fiqs8s.icom.museum" def test_url_escaped_idna_host() -> None: url = httpx2.URL("https://xn--fiqs8s.icom.museum/") assert url.raw_host == b"xn--fiqs8s.icom.museum" def test_url_malformed_idna_label_after_ascii_label() -> None: url = httpx2.URL("https://a.b.c.xn--pokxncvks/") assert url.host == "a.b.c.xn--pokxncvks" def test_url_mixed_valid_and_malformed_idna_labels() -> None: url = httpx2.URL("https://xn--fiqs8s.xn--pokxncvks/") assert url.host == "ไธญๅ›ฝ.xn--pokxncvks" def test_url_invalid_idna_host() -> None: with pytest.raises(httpx2.InvalidURL) as exc: httpx2.URL("https://โ˜ƒ.com/") assert str(exc.value) == "Invalid IDNA hostname: 'โ˜ƒ.com'" # Tests for IPv4 hostname support. def test_url_valid_ipv4() -> None: url = httpx2.URL("https://1.2.3.4/") assert url.host == "1.2.3.4" def test_url_invalid_ipv4() -> None: with pytest.raises(httpx2.InvalidURL) as exc: httpx2.URL("https://999.999.999.999/") assert str(exc.value) == "Invalid IPv4 address: '999.999.999.999'" # Tests for IPv6 hostname support. def test_ipv6_url() -> None: url = httpx2.URL("http://[::ffff:192.168.0.1]:5678/") assert url.host == "::ffff:192.168.0.1" assert url.netloc == b"[::ffff:192.168.0.1]:5678" def test_url_valid_ipv6() -> None: url = httpx2.URL("https://[2001:db8::ff00:42:8329]/") assert url.host == "2001:db8::ff00:42:8329" def test_url_invalid_ipv6() -> None: with pytest.raises(httpx2.InvalidURL) as exc: httpx2.URL("https://[2001]/") assert str(exc.value) == "Invalid IPv6 address: '[2001]'" @pytest.mark.parametrize("host", ["[::ffff:192.168.0.1]", "::ffff:192.168.0.1"]) def test_ipv6_url_from_raw_url(host: str) -> None: url = httpx2.URL(scheme="https", host=host, port=443, path="/") assert url.host == "::ffff:192.168.0.1" assert url.netloc == b"[::ffff:192.168.0.1]" assert str(url) == "https://[::ffff:192.168.0.1]/" @pytest.mark.parametrize( "url_str", [ "http://127.0.0.1:1234", "http://example.com:1234", "http://[::ffff:127.0.0.1]:1234", ], ) @pytest.mark.parametrize("new_host", ["[::ffff:192.168.0.1]", "::ffff:192.168.0.1"]) def test_ipv6_url_copy_with_host(url_str: str, new_host: str) -> None: url = httpx2.URL(url_str).copy_with(host=new_host) assert url.host == "::ffff:192.168.0.1" assert url.netloc == b"[::ffff:192.168.0.1]:1234" assert str(url) == "http://[::ffff:192.168.0.1]:1234" pydantic-httpx2-6dd59b9/tests/httpx2/models/test_whatwg.py000066400000000000000000000037111526547463400240160ustar00rootroot00000000000000# The WHATWG have various tests that can be used to validate the URL parsing. # # https://url.spec.whatwg.org/ from __future__ import annotations import json import typing import pytest from httpx2._urlparse import urlparse # URL test cases from... # https://github.com/web-platform-tests/wpt/blob/master/url/resources/urltestdata.json with open("tests/httpx2/models/whatwg.json", encoding="utf-8") as input: test_cases = json.load(input) test_cases = [item for item in test_cases if not isinstance(item, str) and not item.get("failure")] @pytest.mark.parametrize("test_case", test_cases) def test_urlparse(test_case: dict[str, typing.Any]) -> None: if test_case["href"] in ("a: foo.com", "lolscheme:x x#x%20x"): # Skip these two test cases. # WHATWG cases where are not using percent-encoding for the space character. # Anyone know what's going on here? return p = urlparse(test_case["href"]) # Test cases include the protocol with the trailing ":" protocol = p.scheme + ":" # Include the square brackets for IPv6 addresses. hostname = f"[{p.host}]" if ":" in p.host else p.host # The test cases use a string representation of the port. port = "" if p.port is None else str(p.port) # I have nothing to say about this one. path = p.path # The 'search' and 'hash' components in the whatwg tests are semantic, not literal. # Our parsing differentiates between no query/hash and empty-string query/hash. search = "" if p.query in (None, "") else "?" + str(p.query) hash = "" if p.fragment in (None, "") else "#" + str(p.fragment) # URL hostnames are case-insensitive. # We normalize these, unlike the WHATWG test cases. assert protocol == test_case["protocol"] assert hostname.lower() == test_case["hostname"].lower() assert port == test_case["port"] assert path == test_case["pathname"] assert search == test_case["search"] assert hash == test_case["hash"] pydantic-httpx2-6dd59b9/tests/httpx2/models/whatwg.json000066400000000000000000006277141526547463400233170ustar00rootroot00000000000000[ "See ../README.md for a description of the format.", { "input": "http://example\t.\norg", "base": "http://example.org/foo/bar", "href": "http://example.org/", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://user:pass@foo:21/bar;par?b#c", "base": "http://example.org/foo/bar", "href": "http://user:pass@foo:21/bar;par?b#c", "origin": "http://foo:21", "protocol": "http:", "username": "user", "password": "pass", "host": "foo:21", "hostname": "foo", "port": "21", "pathname": "/bar;par", "search": "?b", "hash": "#c" }, { "input": "https://test:@test", "base": null, "href": "https://test@test/", "origin": "https://test", "protocol": "https:", "username": "test", "password": "", "host": "test", "hostname": "test", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "https://:@test", "base": null, "href": "https://test/", "origin": "https://test", "protocol": "https:", "username": "", "password": "", "host": "test", "hostname": "test", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "non-special://test:@test/x", "base": null, "href": "non-special://test@test/x", "origin": "null", "protocol": "non-special:", "username": "test", "password": "", "host": "test", "hostname": "test", "port": "", "pathname": "/x", "search": "", "hash": "" }, { "input": "non-special://:@test/x", "base": null, "href": "non-special://test/x", "origin": "null", "protocol": "non-special:", "username": "", "password": "", "host": "test", "hostname": "test", "port": "", "pathname": "/x", "search": "", "hash": "" }, { "input": "http:foo.com", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/foo.com", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/foo.com", "search": "", "hash": "" }, { "input": "\t :foo.com \n", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/:foo.com", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/:foo.com", "search": "", "hash": "" }, { "input": " foo.com ", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/foo.com", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/foo.com", "search": "", "hash": "" }, { "input": "a:\t foo.com", "base": "http://example.org/foo/bar", "href": "a: foo.com", "origin": "null", "protocol": "a:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": " foo.com", "search": "", "hash": "" }, { "input": "http://f:21/ b ? d # e ", "base": "http://example.org/foo/bar", "href": "http://f:21/%20b%20?%20d%20#%20e", "origin": "http://f:21", "protocol": "http:", "username": "", "password": "", "host": "f:21", "hostname": "f", "port": "21", "pathname": "/%20b%20", "search": "?%20d%20", "hash": "#%20e" }, { "input": "lolscheme:x x#x x", "base": null, "href": "lolscheme:x x#x%20x", "protocol": "lolscheme:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "x x", "search": "", "hash": "#x%20x" }, { "input": "http://f:/c", "base": "http://example.org/foo/bar", "href": "http://f/c", "origin": "http://f", "protocol": "http:", "username": "", "password": "", "host": "f", "hostname": "f", "port": "", "pathname": "/c", "search": "", "hash": "" }, { "input": "http://f:0/c", "base": "http://example.org/foo/bar", "href": "http://f:0/c", "origin": "http://f:0", "protocol": "http:", "username": "", "password": "", "host": "f:0", "hostname": "f", "port": "0", "pathname": "/c", "search": "", "hash": "" }, { "input": "http://f:00000000000000/c", "base": "http://example.org/foo/bar", "href": "http://f:0/c", "origin": "http://f:0", "protocol": "http:", "username": "", "password": "", "host": "f:0", "hostname": "f", "port": "0", "pathname": "/c", "search": "", "hash": "" }, { "input": "http://f:00000000000000000000080/c", "base": "http://example.org/foo/bar", "href": "http://f/c", "origin": "http://f", "protocol": "http:", "username": "", "password": "", "host": "f", "hostname": "f", "port": "", "pathname": "/c", "search": "", "hash": "" }, { "input": "http://f:b/c", "base": "http://example.org/foo/bar", "failure": true }, { "input": "http://f: /c", "base": "http://example.org/foo/bar", "failure": true }, { "input": "http://f:\n/c", "base": "http://example.org/foo/bar", "href": "http://f/c", "origin": "http://f", "protocol": "http:", "username": "", "password": "", "host": "f", "hostname": "f", "port": "", "pathname": "/c", "search": "", "hash": "" }, { "input": "http://f:fifty-two/c", "base": "http://example.org/foo/bar", "failure": true }, { "input": "http://f:999999/c", "base": "http://example.org/foo/bar", "failure": true }, { "input": "non-special://f:999999/c", "base": "http://example.org/foo/bar", "failure": true }, { "input": "http://f: 21 / b ? d # e ", "base": "http://example.org/foo/bar", "failure": true }, { "input": "", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/bar", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/bar", "search": "", "hash": "" }, { "input": " \t", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/bar", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/bar", "search": "", "hash": "" }, { "input": ":foo.com/", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/:foo.com/", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/:foo.com/", "search": "", "hash": "" }, { "input": ":foo.com\\", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/:foo.com/", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/:foo.com/", "search": "", "hash": "" }, { "input": ":", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/:", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/:", "search": "", "hash": "" }, { "input": ":a", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/:a", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/:a", "search": "", "hash": "" }, { "input": ":/", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/:/", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/:/", "search": "", "hash": "" }, { "input": ":\\", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/:/", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/:/", "search": "", "hash": "" }, { "input": ":#", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/:#", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/:", "search": "", "hash": "" }, { "input": "#", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/bar#", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/bar", "search": "", "hash": "" }, { "input": "#/", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/bar#/", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/bar", "search": "", "hash": "#/" }, { "input": "#\\", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/bar#\\", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/bar", "search": "", "hash": "#\\" }, { "input": "#;?", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/bar#;?", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/bar", "search": "", "hash": "#;?" }, { "input": "?", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/bar?", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/bar", "search": "", "hash": "" }, { "input": "/", "base": "http://example.org/foo/bar", "href": "http://example.org/", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": ":23", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/:23", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/:23", "search": "", "hash": "" }, { "input": "/:23", "base": "http://example.org/foo/bar", "href": "http://example.org/:23", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/:23", "search": "", "hash": "" }, { "input": "\\x", "base": "http://example.org/foo/bar", "href": "http://example.org/x", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/x", "search": "", "hash": "" }, { "input": "\\\\x\\hello", "base": "http://example.org/foo/bar", "href": "http://x/hello", "origin": "http://x", "protocol": "http:", "username": "", "password": "", "host": "x", "hostname": "x", "port": "", "pathname": "/hello", "search": "", "hash": "" }, { "input": "::", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/::", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/::", "search": "", "hash": "" }, { "input": "::23", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/::23", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/::23", "search": "", "hash": "" }, { "input": "foo://", "base": "http://example.org/foo/bar", "href": "foo://", "origin": "null", "protocol": "foo:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "", "search": "", "hash": "" }, { "input": "http://a:b@c:29/d", "base": "http://example.org/foo/bar", "href": "http://a:b@c:29/d", "origin": "http://c:29", "protocol": "http:", "username": "a", "password": "b", "host": "c:29", "hostname": "c", "port": "29", "pathname": "/d", "search": "", "hash": "" }, { "input": "http::@c:29", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/:@c:29", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/:@c:29", "search": "", "hash": "" }, { "input": "http://&a:foo(b]c@d:2/", "base": "http://example.org/foo/bar", "href": "http://&a:foo(b%5Dc@d:2/", "origin": "http://d:2", "protocol": "http:", "username": "&a", "password": "foo(b%5Dc", "host": "d:2", "hostname": "d", "port": "2", "pathname": "/", "search": "", "hash": "" }, { "input": "http://::@c@d:2", "base": "http://example.org/foo/bar", "href": "http://:%3A%40c@d:2/", "origin": "http://d:2", "protocol": "http:", "username": "", "password": "%3A%40c", "host": "d:2", "hostname": "d", "port": "2", "pathname": "/", "search": "", "hash": "" }, { "input": "http://foo.com:b@d/", "base": "http://example.org/foo/bar", "href": "http://foo.com:b@d/", "origin": "http://d", "protocol": "http:", "username": "foo.com", "password": "b", "host": "d", "hostname": "d", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://foo.com/\\@", "base": "http://example.org/foo/bar", "href": "http://foo.com//@", "origin": "http://foo.com", "protocol": "http:", "username": "", "password": "", "host": "foo.com", "hostname": "foo.com", "port": "", "pathname": "//@", "search": "", "hash": "" }, { "input": "http:\\\\foo.com\\", "base": "http://example.org/foo/bar", "href": "http://foo.com/", "origin": "http://foo.com", "protocol": "http:", "username": "", "password": "", "host": "foo.com", "hostname": "foo.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http:\\\\a\\b:c\\d@foo.com\\", "base": "http://example.org/foo/bar", "href": "http://a/b:c/d@foo.com/", "origin": "http://a", "protocol": "http:", "username": "", "password": "", "host": "a", "hostname": "a", "port": "", "pathname": "/b:c/d@foo.com/", "search": "", "hash": "" }, { "input": "http://a:b@c\\", "base": null, "href": "http://a:b@c/", "origin": "http://c", "protocol": "http:", "username": "a", "password": "b", "host": "c", "hostname": "c", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "ws://a@b\\c", "base": null, "href": "ws://a@b/c", "origin": "ws://b", "protocol": "ws:", "username": "a", "password": "", "host": "b", "hostname": "b", "port": "", "pathname": "/c", "search": "", "hash": "" }, { "input": "foo:/", "base": "http://example.org/foo/bar", "href": "foo:/", "origin": "null", "protocol": "foo:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "foo:/bar.com/", "base": "http://example.org/foo/bar", "href": "foo:/bar.com/", "origin": "null", "protocol": "foo:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/bar.com/", "search": "", "hash": "" }, { "input": "foo://///////", "base": "http://example.org/foo/bar", "href": "foo://///////", "origin": "null", "protocol": "foo:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "///////", "search": "", "hash": "" }, { "input": "foo://///////bar.com/", "base": "http://example.org/foo/bar", "href": "foo://///////bar.com/", "origin": "null", "protocol": "foo:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "///////bar.com/", "search": "", "hash": "" }, { "input": "foo:////://///", "base": "http://example.org/foo/bar", "href": "foo:////://///", "origin": "null", "protocol": "foo:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//://///", "search": "", "hash": "" }, { "input": "c:/foo", "base": "http://example.org/foo/bar", "href": "c:/foo", "origin": "null", "protocol": "c:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/foo", "search": "", "hash": "" }, { "input": "//foo/bar", "base": "http://example.org/foo/bar", "href": "http://foo/bar", "origin": "http://foo", "protocol": "http:", "username": "", "password": "", "host": "foo", "hostname": "foo", "port": "", "pathname": "/bar", "search": "", "hash": "" }, { "input": "http://foo/path;a??e#f#g", "base": "http://example.org/foo/bar", "href": "http://foo/path;a??e#f#g", "origin": "http://foo", "protocol": "http:", "username": "", "password": "", "host": "foo", "hostname": "foo", "port": "", "pathname": "/path;a", "search": "??e", "hash": "#f#g" }, { "input": "http://foo/abcd?efgh?ijkl", "base": "http://example.org/foo/bar", "href": "http://foo/abcd?efgh?ijkl", "origin": "http://foo", "protocol": "http:", "username": "", "password": "", "host": "foo", "hostname": "foo", "port": "", "pathname": "/abcd", "search": "?efgh?ijkl", "hash": "" }, { "input": "http://foo/abcd#foo?bar", "base": "http://example.org/foo/bar", "href": "http://foo/abcd#foo?bar", "origin": "http://foo", "protocol": "http:", "username": "", "password": "", "host": "foo", "hostname": "foo", "port": "", "pathname": "/abcd", "search": "", "hash": "#foo?bar" }, { "input": "[61:24:74]:98", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/[61:24:74]:98", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/[61:24:74]:98", "search": "", "hash": "" }, { "input": "http:[61:27]/:foo", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/[61:27]/:foo", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/[61:27]/:foo", "search": "", "hash": "" }, { "input": "http://[1::2]:3:4", "base": "http://example.org/foo/bar", "failure": true }, { "input": "http://2001::1", "base": "http://example.org/foo/bar", "failure": true }, { "input": "http://2001::1]", "base": "http://example.org/foo/bar", "failure": true }, { "input": "http://2001::1]:80", "base": "http://example.org/foo/bar", "failure": true }, { "input": "http://[2001::1]", "base": "http://example.org/foo/bar", "href": "http://[2001::1]/", "origin": "http://[2001::1]", "protocol": "http:", "username": "", "password": "", "host": "[2001::1]", "hostname": "[2001::1]", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://[::127.0.0.1]", "base": "http://example.org/foo/bar", "href": "http://[::7f00:1]/", "origin": "http://[::7f00:1]", "protocol": "http:", "username": "", "password": "", "host": "[::7f00:1]", "hostname": "[::7f00:1]", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://[::127.0.0.1.]", "base": "http://example.org/foo/bar", "failure": true }, { "input": "http://[0:0:0:0:0:0:13.1.68.3]", "base": "http://example.org/foo/bar", "href": "http://[::d01:4403]/", "origin": "http://[::d01:4403]", "protocol": "http:", "username": "", "password": "", "host": "[::d01:4403]", "hostname": "[::d01:4403]", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://[2001::1]:80", "base": "http://example.org/foo/bar", "href": "http://[2001::1]/", "origin": "http://[2001::1]", "protocol": "http:", "username": "", "password": "", "host": "[2001::1]", "hostname": "[2001::1]", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http:/example.com/", "base": "http://example.org/foo/bar", "href": "http://example.org/example.com/", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/example.com/", "search": "", "hash": "" }, { "input": "ftp:/example.com/", "base": "http://example.org/foo/bar", "href": "ftp://example.com/", "origin": "ftp://example.com", "protocol": "ftp:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "https:/example.com/", "base": "http://example.org/foo/bar", "href": "https://example.com/", "origin": "https://example.com", "protocol": "https:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "madeupscheme:/example.com/", "base": "http://example.org/foo/bar", "href": "madeupscheme:/example.com/", "origin": "null", "protocol": "madeupscheme:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/example.com/", "search": "", "hash": "" }, { "input": "file:/example.com/", "base": "http://example.org/foo/bar", "href": "file:///example.com/", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/example.com/", "search": "", "hash": "" }, { "input": "file://example:1/", "base": null, "failure": true }, { "input": "file://example:test/", "base": null, "failure": true }, { "input": "file://example%/", "base": null, "failure": true }, { "input": "file://[example]/", "base": null, "failure": true }, { "input": "ftps:/example.com/", "base": "http://example.org/foo/bar", "href": "ftps:/example.com/", "origin": "null", "protocol": "ftps:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/example.com/", "search": "", "hash": "" }, { "input": "gopher:/example.com/", "base": "http://example.org/foo/bar", "href": "gopher:/example.com/", "origin": "null", "protocol": "gopher:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/example.com/", "search": "", "hash": "" }, { "input": "ws:/example.com/", "base": "http://example.org/foo/bar", "href": "ws://example.com/", "origin": "ws://example.com", "protocol": "ws:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "wss:/example.com/", "base": "http://example.org/foo/bar", "href": "wss://example.com/", "origin": "wss://example.com", "protocol": "wss:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "data:/example.com/", "base": "http://example.org/foo/bar", "href": "data:/example.com/", "origin": "null", "protocol": "data:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/example.com/", "search": "", "hash": "" }, { "input": "javascript:/example.com/", "base": "http://example.org/foo/bar", "href": "javascript:/example.com/", "origin": "null", "protocol": "javascript:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/example.com/", "search": "", "hash": "" }, { "input": "mailto:/example.com/", "base": "http://example.org/foo/bar", "href": "mailto:/example.com/", "origin": "null", "protocol": "mailto:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/example.com/", "search": "", "hash": "" }, { "input": "http:example.com/", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/example.com/", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/example.com/", "search": "", "hash": "" }, { "input": "ftp:example.com/", "base": "http://example.org/foo/bar", "href": "ftp://example.com/", "origin": "ftp://example.com", "protocol": "ftp:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "https:example.com/", "base": "http://example.org/foo/bar", "href": "https://example.com/", "origin": "https://example.com", "protocol": "https:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "madeupscheme:example.com/", "base": "http://example.org/foo/bar", "href": "madeupscheme:example.com/", "origin": "null", "protocol": "madeupscheme:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "example.com/", "search": "", "hash": "" }, { "input": "ftps:example.com/", "base": "http://example.org/foo/bar", "href": "ftps:example.com/", "origin": "null", "protocol": "ftps:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "example.com/", "search": "", "hash": "" }, { "input": "gopher:example.com/", "base": "http://example.org/foo/bar", "href": "gopher:example.com/", "origin": "null", "protocol": "gopher:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "example.com/", "search": "", "hash": "" }, { "input": "ws:example.com/", "base": "http://example.org/foo/bar", "href": "ws://example.com/", "origin": "ws://example.com", "protocol": "ws:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "wss:example.com/", "base": "http://example.org/foo/bar", "href": "wss://example.com/", "origin": "wss://example.com", "protocol": "wss:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "data:example.com/", "base": "http://example.org/foo/bar", "href": "data:example.com/", "origin": "null", "protocol": "data:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "example.com/", "search": "", "hash": "" }, { "input": "javascript:example.com/", "base": "http://example.org/foo/bar", "href": "javascript:example.com/", "origin": "null", "protocol": "javascript:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "example.com/", "search": "", "hash": "" }, { "input": "mailto:example.com/", "base": "http://example.org/foo/bar", "href": "mailto:example.com/", "origin": "null", "protocol": "mailto:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "example.com/", "search": "", "hash": "" }, { "input": "/a/b/c", "base": "http://example.org/foo/bar", "href": "http://example.org/a/b/c", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/a/b/c", "search": "", "hash": "" }, { "input": "/a/ /c", "base": "http://example.org/foo/bar", "href": "http://example.org/a/%20/c", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/a/%20/c", "search": "", "hash": "" }, { "input": "/a%2fc", "base": "http://example.org/foo/bar", "href": "http://example.org/a%2fc", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/a%2fc", "search": "", "hash": "" }, { "input": "/a/%2f/c", "base": "http://example.org/foo/bar", "href": "http://example.org/a/%2f/c", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/a/%2f/c", "search": "", "hash": "" }, { "input": "#ฮฒ", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/bar#%CE%B2", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/bar", "search": "", "hash": "#%CE%B2" }, { "input": "data:text/html,test#test", "base": "http://example.org/foo/bar", "href": "data:text/html,test#test", "origin": "null", "protocol": "data:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "text/html,test", "search": "", "hash": "#test" }, { "input": "tel:1234567890", "base": "http://example.org/foo/bar", "href": "tel:1234567890", "origin": "null", "protocol": "tel:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "1234567890", "search": "", "hash": "" }, "# Based on https://felixfbecker.github.io/whatwg-url-custom-host-repro/", { "input": "ssh://example.com/foo/bar.git", "base": "http://example.org/", "href": "ssh://example.com/foo/bar.git", "origin": "null", "protocol": "ssh:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/foo/bar.git", "search": "", "hash": "" }, "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/file.html", { "input": "file:c:\\foo\\bar.html", "base": "file:///tmp/mock/path", "href": "file:///c:/foo/bar.html", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/c:/foo/bar.html", "search": "", "hash": "" }, { "input": " File:c|////foo\\bar.html", "base": "file:///tmp/mock/path", "href": "file:///c:////foo/bar.html", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/c:////foo/bar.html", "search": "", "hash": "" }, { "input": "C|/foo/bar", "base": "file:///tmp/mock/path", "href": "file:///C:/foo/bar", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/C:/foo/bar", "search": "", "hash": "" }, { "input": "/C|\\foo\\bar", "base": "file:///tmp/mock/path", "href": "file:///C:/foo/bar", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/C:/foo/bar", "search": "", "hash": "" }, { "input": "//C|/foo/bar", "base": "file:///tmp/mock/path", "href": "file:///C:/foo/bar", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/C:/foo/bar", "search": "", "hash": "" }, { "input": "//server/file", "base": "file:///tmp/mock/path", "href": "file://server/file", "protocol": "file:", "username": "", "password": "", "host": "server", "hostname": "server", "port": "", "pathname": "/file", "search": "", "hash": "" }, { "input": "\\\\server\\file", "base": "file:///tmp/mock/path", "href": "file://server/file", "protocol": "file:", "username": "", "password": "", "host": "server", "hostname": "server", "port": "", "pathname": "/file", "search": "", "hash": "" }, { "input": "/\\server/file", "base": "file:///tmp/mock/path", "href": "file://server/file", "protocol": "file:", "username": "", "password": "", "host": "server", "hostname": "server", "port": "", "pathname": "/file", "search": "", "hash": "" }, { "input": "file:///foo/bar.txt", "base": "file:///tmp/mock/path", "href": "file:///foo/bar.txt", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/foo/bar.txt", "search": "", "hash": "" }, { "input": "file:///home/me", "base": "file:///tmp/mock/path", "href": "file:///home/me", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/home/me", "search": "", "hash": "" }, { "input": "//", "base": "file:///tmp/mock/path", "href": "file:///", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "///", "base": "file:///tmp/mock/path", "href": "file:///", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "///test", "base": "file:///tmp/mock/path", "href": "file:///test", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/test", "search": "", "hash": "" }, { "input": "file://test", "base": "file:///tmp/mock/path", "href": "file://test/", "protocol": "file:", "username": "", "password": "", "host": "test", "hostname": "test", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "file://localhost", "base": "file:///tmp/mock/path", "href": "file:///", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "file://localhost/", "base": "file:///tmp/mock/path", "href": "file:///", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "file://localhost/test", "base": "file:///tmp/mock/path", "href": "file:///test", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/test", "search": "", "hash": "" }, { "input": "test", "base": "file:///tmp/mock/path", "href": "file:///tmp/mock/test", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/tmp/mock/test", "search": "", "hash": "" }, { "input": "file:test", "base": "file:///tmp/mock/path", "href": "file:///tmp/mock/test", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/tmp/mock/test", "search": "", "hash": "" }, "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/script-tests/path.js", { "input": "http://example.com/././foo", "base": null, "href": "http://example.com/foo", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/foo", "search": "", "hash": "" }, { "input": "http://example.com/./.foo", "base": null, "href": "http://example.com/.foo", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/.foo", "search": "", "hash": "" }, { "input": "http://example.com/foo/.", "base": null, "href": "http://example.com/foo/", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/foo/", "search": "", "hash": "" }, { "input": "http://example.com/foo/./", "base": null, "href": "http://example.com/foo/", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/foo/", "search": "", "hash": "" }, { "input": "http://example.com/foo/bar/..", "base": null, "href": "http://example.com/foo/", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/foo/", "search": "", "hash": "" }, { "input": "http://example.com/foo/bar/../", "base": null, "href": "http://example.com/foo/", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/foo/", "search": "", "hash": "" }, { "input": "http://example.com/foo/..bar", "base": null, "href": "http://example.com/foo/..bar", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/foo/..bar", "search": "", "hash": "" }, { "input": "http://example.com/foo/bar/../ton", "base": null, "href": "http://example.com/foo/ton", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/foo/ton", "search": "", "hash": "" }, { "input": "http://example.com/foo/bar/../ton/../../a", "base": null, "href": "http://example.com/a", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/a", "search": "", "hash": "" }, { "input": "http://example.com/foo/../../..", "base": null, "href": "http://example.com/", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://example.com/foo/../../../ton", "base": null, "href": "http://example.com/ton", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/ton", "search": "", "hash": "" }, { "input": "http://example.com/foo/%2e", "base": null, "href": "http://example.com/foo/", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/foo/", "search": "", "hash": "" }, { "input": "http://example.com/foo/%2e%2", "base": null, "href": "http://example.com/foo/%2e%2", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/foo/%2e%2", "search": "", "hash": "" }, { "input": "http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar", "base": null, "href": "http://example.com/%2e.bar", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/%2e.bar", "search": "", "hash": "" }, { "input": "http://example.com////../..", "base": null, "href": "http://example.com//", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "//", "search": "", "hash": "" }, { "input": "http://example.com/foo/bar//../..", "base": null, "href": "http://example.com/foo/", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/foo/", "search": "", "hash": "" }, { "input": "http://example.com/foo/bar//..", "base": null, "href": "http://example.com/foo/bar/", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/foo/bar/", "search": "", "hash": "" }, { "input": "http://example.com/foo", "base": null, "href": "http://example.com/foo", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/foo", "search": "", "hash": "" }, { "input": "http://example.com/%20foo", "base": null, "href": "http://example.com/%20foo", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/%20foo", "search": "", "hash": "" }, { "input": "http://example.com/foo%", "base": null, "href": "http://example.com/foo%", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/foo%", "search": "", "hash": "" }, { "input": "http://example.com/foo%2", "base": null, "href": "http://example.com/foo%2", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/foo%2", "search": "", "hash": "" }, { "input": "http://example.com/foo%2zbar", "base": null, "href": "http://example.com/foo%2zbar", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/foo%2zbar", "search": "", "hash": "" }, { "input": "http://example.com/foo%2ร‚ยฉzbar", "base": null, "href": "http://example.com/foo%2%C3%82%C2%A9zbar", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/foo%2%C3%82%C2%A9zbar", "search": "", "hash": "" }, { "input": "http://example.com/foo%41%7a", "base": null, "href": "http://example.com/foo%41%7a", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/foo%41%7a", "search": "", "hash": "" }, { "input": "http://example.com/foo\t\u0091%91", "base": null, "href": "http://example.com/foo%C2%91%91", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/foo%C2%91%91", "search": "", "hash": "" }, { "input": "http://example.com/foo%00%51", "base": null, "href": "http://example.com/foo%00%51", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/foo%00%51", "search": "", "hash": "" }, { "input": "http://example.com/(%28:%3A%29)", "base": null, "href": "http://example.com/(%28:%3A%29)", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/(%28:%3A%29)", "search": "", "hash": "" }, { "input": "http://example.com/%3A%3a%3C%3c", "base": null, "href": "http://example.com/%3A%3a%3C%3c", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/%3A%3a%3C%3c", "search": "", "hash": "" }, { "input": "http://example.com/foo\tbar", "base": null, "href": "http://example.com/foobar", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/foobar", "search": "", "hash": "" }, { "input": "http://example.com\\\\foo\\\\bar", "base": null, "href": "http://example.com//foo//bar", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "//foo//bar", "search": "", "hash": "" }, { "input": "http://example.com/%7Ffp3%3Eju%3Dduvgw%3Dd", "base": null, "href": "http://example.com/%7Ffp3%3Eju%3Dduvgw%3Dd", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/%7Ffp3%3Eju%3Dduvgw%3Dd", "search": "", "hash": "" }, { "input": "http://example.com/@asdf%40", "base": null, "href": "http://example.com/@asdf%40", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/@asdf%40", "search": "", "hash": "" }, { "input": "http://example.com/ไฝ ๅฅฝไฝ ๅฅฝ", "base": null, "href": "http://example.com/%E4%BD%A0%E5%A5%BD%E4%BD%A0%E5%A5%BD", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/%E4%BD%A0%E5%A5%BD%E4%BD%A0%E5%A5%BD", "search": "", "hash": "" }, { "input": "http://example.com/โ€ฅ/foo", "base": null, "href": "http://example.com/%E2%80%A5/foo", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/%E2%80%A5/foo", "search": "", "hash": "" }, { "input": "http://example.com/๏ปฟ/foo", "base": null, "href": "http://example.com/%EF%BB%BF/foo", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/%EF%BB%BF/foo", "search": "", "hash": "" }, { "input": "http://example.com/โ€ฎ/foo/โ€ญ/bar", "base": null, "href": "http://example.com/%E2%80%AE/foo/%E2%80%AD/bar", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/%E2%80%AE/foo/%E2%80%AD/bar", "search": "", "hash": "" }, "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/script-tests/relative.js", { "input": "http://www.google.com/foo?bar=baz#", "base": null, "href": "http://www.google.com/foo?bar=baz#", "origin": "http://www.google.com", "protocol": "http:", "username": "", "password": "", "host": "www.google.com", "hostname": "www.google.com", "port": "", "pathname": "/foo", "search": "?bar=baz", "hash": "" }, { "input": "http://www.google.com/foo?bar=baz# ยป", "base": null, "href": "http://www.google.com/foo?bar=baz#%20%C2%BB", "origin": "http://www.google.com", "protocol": "http:", "username": "", "password": "", "host": "www.google.com", "hostname": "www.google.com", "port": "", "pathname": "/foo", "search": "?bar=baz", "hash": "#%20%C2%BB" }, { "input": "data:test# ยป", "base": null, "href": "data:test#%20%C2%BB", "origin": "null", "protocol": "data:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "test", "search": "", "hash": "#%20%C2%BB" }, { "input": "http://www.google.com", "base": null, "href": "http://www.google.com/", "origin": "http://www.google.com", "protocol": "http:", "username": "", "password": "", "host": "www.google.com", "hostname": "www.google.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://192.0x00A80001", "base": null, "href": "http://192.168.0.1/", "origin": "http://192.168.0.1", "protocol": "http:", "username": "", "password": "", "host": "192.168.0.1", "hostname": "192.168.0.1", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://www/foo%2Ehtml", "base": null, "href": "http://www/foo%2Ehtml", "origin": "http://www", "protocol": "http:", "username": "", "password": "", "host": "www", "hostname": "www", "port": "", "pathname": "/foo%2Ehtml", "search": "", "hash": "" }, { "input": "http://www/foo/%2E/html", "base": null, "href": "http://www/foo/html", "origin": "http://www", "protocol": "http:", "username": "", "password": "", "host": "www", "hostname": "www", "port": "", "pathname": "/foo/html", "search": "", "hash": "" }, { "input": "http://user:pass@/", "base": null, "failure": true }, { "input": "http://%25DOMAIN:foobar@foodomain.com/", "base": null, "href": "http://%25DOMAIN:foobar@foodomain.com/", "origin": "http://foodomain.com", "protocol": "http:", "username": "%25DOMAIN", "password": "foobar", "host": "foodomain.com", "hostname": "foodomain.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http:\\\\www.google.com\\foo", "base": null, "href": "http://www.google.com/foo", "origin": "http://www.google.com", "protocol": "http:", "username": "", "password": "", "host": "www.google.com", "hostname": "www.google.com", "port": "", "pathname": "/foo", "search": "", "hash": "" }, { "input": "http://foo:80/", "base": null, "href": "http://foo/", "origin": "http://foo", "protocol": "http:", "username": "", "password": "", "host": "foo", "hostname": "foo", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://foo:81/", "base": null, "href": "http://foo:81/", "origin": "http://foo:81", "protocol": "http:", "username": "", "password": "", "host": "foo:81", "hostname": "foo", "port": "81", "pathname": "/", "search": "", "hash": "" }, { "input": "httpa://foo:80/", "base": null, "href": "httpa://foo:80/", "origin": "null", "protocol": "httpa:", "username": "", "password": "", "host": "foo:80", "hostname": "foo", "port": "80", "pathname": "/", "search": "", "hash": "" }, { "input": "http://foo:-80/", "base": null, "failure": true }, { "input": "https://foo:443/", "base": null, "href": "https://foo/", "origin": "https://foo", "protocol": "https:", "username": "", "password": "", "host": "foo", "hostname": "foo", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "https://foo:80/", "base": null, "href": "https://foo:80/", "origin": "https://foo:80", "protocol": "https:", "username": "", "password": "", "host": "foo:80", "hostname": "foo", "port": "80", "pathname": "/", "search": "", "hash": "" }, { "input": "ftp://foo:21/", "base": null, "href": "ftp://foo/", "origin": "ftp://foo", "protocol": "ftp:", "username": "", "password": "", "host": "foo", "hostname": "foo", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "ftp://foo:80/", "base": null, "href": "ftp://foo:80/", "origin": "ftp://foo:80", "protocol": "ftp:", "username": "", "password": "", "host": "foo:80", "hostname": "foo", "port": "80", "pathname": "/", "search": "", "hash": "" }, { "input": "gopher://foo:70/", "base": null, "href": "gopher://foo:70/", "origin": "null", "protocol": "gopher:", "username": "", "password": "", "host": "foo:70", "hostname": "foo", "port": "70", "pathname": "/", "search": "", "hash": "" }, { "input": "gopher://foo:443/", "base": null, "href": "gopher://foo:443/", "origin": "null", "protocol": "gopher:", "username": "", "password": "", "host": "foo:443", "hostname": "foo", "port": "443", "pathname": "/", "search": "", "hash": "" }, { "input": "ws://foo:80/", "base": null, "href": "ws://foo/", "origin": "ws://foo", "protocol": "ws:", "username": "", "password": "", "host": "foo", "hostname": "foo", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "ws://foo:81/", "base": null, "href": "ws://foo:81/", "origin": "ws://foo:81", "protocol": "ws:", "username": "", "password": "", "host": "foo:81", "hostname": "foo", "port": "81", "pathname": "/", "search": "", "hash": "" }, { "input": "ws://foo:443/", "base": null, "href": "ws://foo:443/", "origin": "ws://foo:443", "protocol": "ws:", "username": "", "password": "", "host": "foo:443", "hostname": "foo", "port": "443", "pathname": "/", "search": "", "hash": "" }, { "input": "ws://foo:815/", "base": null, "href": "ws://foo:815/", "origin": "ws://foo:815", "protocol": "ws:", "username": "", "password": "", "host": "foo:815", "hostname": "foo", "port": "815", "pathname": "/", "search": "", "hash": "" }, { "input": "wss://foo:80/", "base": null, "href": "wss://foo:80/", "origin": "wss://foo:80", "protocol": "wss:", "username": "", "password": "", "host": "foo:80", "hostname": "foo", "port": "80", "pathname": "/", "search": "", "hash": "" }, { "input": "wss://foo:81/", "base": null, "href": "wss://foo:81/", "origin": "wss://foo:81", "protocol": "wss:", "username": "", "password": "", "host": "foo:81", "hostname": "foo", "port": "81", "pathname": "/", "search": "", "hash": "" }, { "input": "wss://foo:443/", "base": null, "href": "wss://foo/", "origin": "wss://foo", "protocol": "wss:", "username": "", "password": "", "host": "foo", "hostname": "foo", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "wss://foo:815/", "base": null, "href": "wss://foo:815/", "origin": "wss://foo:815", "protocol": "wss:", "username": "", "password": "", "host": "foo:815", "hostname": "foo", "port": "815", "pathname": "/", "search": "", "hash": "" }, { "input": "http:/example.com/", "base": null, "href": "http://example.com/", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "ftp:/example.com/", "base": null, "href": "ftp://example.com/", "origin": "ftp://example.com", "protocol": "ftp:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "https:/example.com/", "base": null, "href": "https://example.com/", "origin": "https://example.com", "protocol": "https:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "madeupscheme:/example.com/", "base": null, "href": "madeupscheme:/example.com/", "origin": "null", "protocol": "madeupscheme:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/example.com/", "search": "", "hash": "" }, { "input": "file:/example.com/", "base": null, "href": "file:///example.com/", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/example.com/", "search": "", "hash": "" }, { "input": "ftps:/example.com/", "base": null, "href": "ftps:/example.com/", "origin": "null", "protocol": "ftps:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/example.com/", "search": "", "hash": "" }, { "input": "gopher:/example.com/", "base": null, "href": "gopher:/example.com/", "origin": "null", "protocol": "gopher:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/example.com/", "search": "", "hash": "" }, { "input": "ws:/example.com/", "base": null, "href": "ws://example.com/", "origin": "ws://example.com", "protocol": "ws:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "wss:/example.com/", "base": null, "href": "wss://example.com/", "origin": "wss://example.com", "protocol": "wss:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "data:/example.com/", "base": null, "href": "data:/example.com/", "origin": "null", "protocol": "data:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/example.com/", "search": "", "hash": "" }, { "input": "javascript:/example.com/", "base": null, "href": "javascript:/example.com/", "origin": "null", "protocol": "javascript:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/example.com/", "search": "", "hash": "" }, { "input": "mailto:/example.com/", "base": null, "href": "mailto:/example.com/", "origin": "null", "protocol": "mailto:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/example.com/", "search": "", "hash": "" }, { "input": "http:example.com/", "base": null, "href": "http://example.com/", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "ftp:example.com/", "base": null, "href": "ftp://example.com/", "origin": "ftp://example.com", "protocol": "ftp:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "https:example.com/", "base": null, "href": "https://example.com/", "origin": "https://example.com", "protocol": "https:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "madeupscheme:example.com/", "base": null, "href": "madeupscheme:example.com/", "origin": "null", "protocol": "madeupscheme:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "example.com/", "search": "", "hash": "" }, { "input": "ftps:example.com/", "base": null, "href": "ftps:example.com/", "origin": "null", "protocol": "ftps:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "example.com/", "search": "", "hash": "" }, { "input": "gopher:example.com/", "base": null, "href": "gopher:example.com/", "origin": "null", "protocol": "gopher:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "example.com/", "search": "", "hash": "" }, { "input": "ws:example.com/", "base": null, "href": "ws://example.com/", "origin": "ws://example.com", "protocol": "ws:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "wss:example.com/", "base": null, "href": "wss://example.com/", "origin": "wss://example.com", "protocol": "wss:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "data:example.com/", "base": null, "href": "data:example.com/", "origin": "null", "protocol": "data:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "example.com/", "search": "", "hash": "" }, { "input": "javascript:example.com/", "base": null, "href": "javascript:example.com/", "origin": "null", "protocol": "javascript:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "example.com/", "search": "", "hash": "" }, { "input": "mailto:example.com/", "base": null, "href": "mailto:example.com/", "origin": "null", "protocol": "mailto:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "example.com/", "search": "", "hash": "" }, "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/segments-userinfo-vs-host.html", { "input": "http:@www.example.com", "base": null, "href": "http://www.example.com/", "origin": "http://www.example.com", "protocol": "http:", "username": "", "password": "", "host": "www.example.com", "hostname": "www.example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http:/@www.example.com", "base": null, "href": "http://www.example.com/", "origin": "http://www.example.com", "protocol": "http:", "username": "", "password": "", "host": "www.example.com", "hostname": "www.example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://@www.example.com", "base": null, "href": "http://www.example.com/", "origin": "http://www.example.com", "protocol": "http:", "username": "", "password": "", "host": "www.example.com", "hostname": "www.example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http:a:b@www.example.com", "base": null, "href": "http://a:b@www.example.com/", "origin": "http://www.example.com", "protocol": "http:", "username": "a", "password": "b", "host": "www.example.com", "hostname": "www.example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http:/a:b@www.example.com", "base": null, "href": "http://a:b@www.example.com/", "origin": "http://www.example.com", "protocol": "http:", "username": "a", "password": "b", "host": "www.example.com", "hostname": "www.example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://a:b@www.example.com", "base": null, "href": "http://a:b@www.example.com/", "origin": "http://www.example.com", "protocol": "http:", "username": "a", "password": "b", "host": "www.example.com", "hostname": "www.example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://@pple.com", "base": null, "href": "http://pple.com/", "origin": "http://pple.com", "protocol": "http:", "username": "", "password": "", "host": "pple.com", "hostname": "pple.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http::b@www.example.com", "base": null, "href": "http://:b@www.example.com/", "origin": "http://www.example.com", "protocol": "http:", "username": "", "password": "b", "host": "www.example.com", "hostname": "www.example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http:/:b@www.example.com", "base": null, "href": "http://:b@www.example.com/", "origin": "http://www.example.com", "protocol": "http:", "username": "", "password": "b", "host": "www.example.com", "hostname": "www.example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://:b@www.example.com", "base": null, "href": "http://:b@www.example.com/", "origin": "http://www.example.com", "protocol": "http:", "username": "", "password": "b", "host": "www.example.com", "hostname": "www.example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http:/:@/www.example.com", "base": null, "failure": true, "relativeTo": "non-opaque-path-base" }, { "input": "http://user@/www.example.com", "base": null, "failure": true }, { "input": "http:@/www.example.com", "base": null, "failure": true, "relativeTo": "non-opaque-path-base" }, { "input": "http:/@/www.example.com", "base": null, "failure": true, "relativeTo": "non-opaque-path-base" }, { "input": "http://@/www.example.com", "base": null, "failure": true }, { "input": "https:@/www.example.com", "base": null, "failure": true, "relativeTo": "non-opaque-path-base" }, { "input": "http:a:b@/www.example.com", "base": null, "failure": true, "relativeTo": "non-opaque-path-base" }, { "input": "http:/a:b@/www.example.com", "base": null, "failure": true, "relativeTo": "non-opaque-path-base" }, { "input": "http://a:b@/www.example.com", "base": null, "failure": true }, { "input": "http::@/www.example.com", "base": null, "failure": true, "relativeTo": "non-opaque-path-base" }, { "input": "http:a:@www.example.com", "base": null, "href": "http://a@www.example.com/", "origin": "http://www.example.com", "protocol": "http:", "username": "a", "password": "", "host": "www.example.com", "hostname": "www.example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http:/a:@www.example.com", "base": null, "href": "http://a@www.example.com/", "origin": "http://www.example.com", "protocol": "http:", "username": "a", "password": "", "host": "www.example.com", "hostname": "www.example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://a:@www.example.com", "base": null, "href": "http://a@www.example.com/", "origin": "http://www.example.com", "protocol": "http:", "username": "a", "password": "", "host": "www.example.com", "hostname": "www.example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://www.@pple.com", "base": null, "href": "http://www.@pple.com/", "origin": "http://pple.com", "protocol": "http:", "username": "www.", "password": "", "host": "pple.com", "hostname": "pple.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http:@:www.example.com", "base": null, "failure": true, "relativeTo": "non-opaque-path-base" }, { "input": "http:/@:www.example.com", "base": null, "failure": true, "relativeTo": "non-opaque-path-base" }, { "input": "http://@:www.example.com", "base": null, "failure": true }, { "input": "http://:@www.example.com", "base": null, "href": "http://www.example.com/", "origin": "http://www.example.com", "protocol": "http:", "username": "", "password": "", "host": "www.example.com", "hostname": "www.example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, "# Others", { "input": "/", "base": "http://www.example.com/test", "href": "http://www.example.com/", "origin": "http://www.example.com", "protocol": "http:", "username": "", "password": "", "host": "www.example.com", "hostname": "www.example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "/test.txt", "base": "http://www.example.com/test", "href": "http://www.example.com/test.txt", "origin": "http://www.example.com", "protocol": "http:", "username": "", "password": "", "host": "www.example.com", "hostname": "www.example.com", "port": "", "pathname": "/test.txt", "search": "", "hash": "" }, { "input": ".", "base": "http://www.example.com/test", "href": "http://www.example.com/", "origin": "http://www.example.com", "protocol": "http:", "username": "", "password": "", "host": "www.example.com", "hostname": "www.example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "..", "base": "http://www.example.com/test", "href": "http://www.example.com/", "origin": "http://www.example.com", "protocol": "http:", "username": "", "password": "", "host": "www.example.com", "hostname": "www.example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "test.txt", "base": "http://www.example.com/test", "href": "http://www.example.com/test.txt", "origin": "http://www.example.com", "protocol": "http:", "username": "", "password": "", "host": "www.example.com", "hostname": "www.example.com", "port": "", "pathname": "/test.txt", "search": "", "hash": "" }, { "input": "./test.txt", "base": "http://www.example.com/test", "href": "http://www.example.com/test.txt", "origin": "http://www.example.com", "protocol": "http:", "username": "", "password": "", "host": "www.example.com", "hostname": "www.example.com", "port": "", "pathname": "/test.txt", "search": "", "hash": "" }, { "input": "../test.txt", "base": "http://www.example.com/test", "href": "http://www.example.com/test.txt", "origin": "http://www.example.com", "protocol": "http:", "username": "", "password": "", "host": "www.example.com", "hostname": "www.example.com", "port": "", "pathname": "/test.txt", "search": "", "hash": "" }, { "input": "../aaa/test.txt", "base": "http://www.example.com/test", "href": "http://www.example.com/aaa/test.txt", "origin": "http://www.example.com", "protocol": "http:", "username": "", "password": "", "host": "www.example.com", "hostname": "www.example.com", "port": "", "pathname": "/aaa/test.txt", "search": "", "hash": "" }, { "input": "../../test.txt", "base": "http://www.example.com/test", "href": "http://www.example.com/test.txt", "origin": "http://www.example.com", "protocol": "http:", "username": "", "password": "", "host": "www.example.com", "hostname": "www.example.com", "port": "", "pathname": "/test.txt", "search": "", "hash": "" }, { "input": "ไธญ/test.txt", "base": "http://www.example.com/test", "href": "http://www.example.com/%E4%B8%AD/test.txt", "origin": "http://www.example.com", "protocol": "http:", "username": "", "password": "", "host": "www.example.com", "hostname": "www.example.com", "port": "", "pathname": "/%E4%B8%AD/test.txt", "search": "", "hash": "" }, { "input": "http://www.example2.com", "base": "http://www.example.com/test", "href": "http://www.example2.com/", "origin": "http://www.example2.com", "protocol": "http:", "username": "", "password": "", "host": "www.example2.com", "hostname": "www.example2.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "//www.example2.com", "base": "http://www.example.com/test", "href": "http://www.example2.com/", "origin": "http://www.example2.com", "protocol": "http:", "username": "", "password": "", "host": "www.example2.com", "hostname": "www.example2.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "file:...", "base": "http://www.example.com/test", "href": "file:///...", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/...", "search": "", "hash": "" }, { "input": "file:..", "base": "http://www.example.com/test", "href": "file:///", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "file:a", "base": "http://www.example.com/test", "href": "file:///a", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/a", "search": "", "hash": "" }, { "input": "file:.", "base": null, "href": "file:///", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "file:.", "base": "http://www.example.com/test", "href": "file:///", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/", "search": "", "hash": "" }, "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/host.html", "Basic canonicalization, uppercase should be converted to lowercase", { "input": "http://ExAmPlE.CoM", "base": "http://other.com/", "href": "http://example.com/", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://example example.com", "base": "http://other.com/", "failure": true }, { "input": "http://Goo%20 goo%7C|.com", "base": "http://other.com/", "failure": true }, { "input": "http://[]", "base": "http://other.com/", "failure": true }, { "input": "http://[:]", "base": "http://other.com/", "failure": true }, "U+3000 is mapped to U+0020 (space) which is disallowed", { "input": "http://GOO\u00a0\u3000goo.com", "base": "http://other.com/", "failure": true }, "Other types of space (no-break, zero-width, zero-width-no-break) are name-prepped away to nothing. U+200B, U+2060, and U+FEFF, are ignored", { "input": "http://GOO\u200b\u2060\ufeffgoo.com", "base": "http://other.com/", "href": "http://googoo.com/", "origin": "http://googoo.com", "protocol": "http:", "username": "", "password": "", "host": "googoo.com", "hostname": "googoo.com", "port": "", "pathname": "/", "search": "", "hash": "" }, "Leading and trailing C0 control or space", { "input": "\u0000\u001b\u0004\u0012 http://example.com/\u001f \u000d ", "base": null, "href": "http://example.com/", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/", "search": "", "hash": "" }, "Ideographic full stop (full-width period for Chinese, etc.) should be treated as a dot. U+3002 is mapped to U+002E (dot)", { "input": "http://www.fooใ€‚bar.com", "base": "http://other.com/", "href": "http://www.foo.bar.com/", "origin": "http://www.foo.bar.com", "protocol": "http:", "username": "", "password": "", "host": "www.foo.bar.com", "hostname": "www.foo.bar.com", "port": "", "pathname": "/", "search": "", "hash": "" }, "Invalid unicode characters should fail... U+FDD0 is disallowed; %ef%b7%90 is U+FDD0", { "input": "http://\ufdd0zyx.com", "base": "http://other.com/", "failure": true }, "This is the same as previous but escaped", { "input": "http://%ef%b7%90zyx.com", "base": "http://other.com/", "failure": true }, "U+FFFD", { "input": "https://\ufffd", "base": null, "failure": true }, { "input": "https://%EF%BF%BD", "base": null, "failure": true }, { "input": "https://x/\ufffd?\ufffd#\ufffd", "base": null, "href": "https://x/%EF%BF%BD?%EF%BF%BD#%EF%BF%BD", "origin": "https://x", "protocol": "https:", "username": "", "password": "", "host": "x", "hostname": "x", "port": "", "pathname": "/%EF%BF%BD", "search": "?%EF%BF%BD", "hash": "#%EF%BF%BD" }, "Domain is ASCII, but a label is invalid IDNA", { "input": "http://a.b.c.xn--pokxncvks", "base": null, "failure": true }, { "input": "http://10.0.0.xn--pokxncvks", "base": null, "failure": true }, "IDNA labels should be matched case-insensitively", { "input": "http://a.b.c.XN--pokxncvks", "base": null, "failure": true }, { "input": "http://a.b.c.Xn--pokxncvks", "base": null, "failure": true }, { "input": "http://10.0.0.XN--pokxncvks", "base": null, "failure": true }, { "input": "http://10.0.0.xN--pokxncvks", "base": null, "failure": true }, "Test name prepping, fullwidth input should be converted to ASCII and NOT IDN-ized. This is 'Go' in fullwidth UTF-8/UTF-16.", { "input": "http://๏ผง๏ฝ.com", "base": "http://other.com/", "href": "http://go.com/", "origin": "http://go.com", "protocol": "http:", "username": "", "password": "", "host": "go.com", "hostname": "go.com", "port": "", "pathname": "/", "search": "", "hash": "" }, "URL spec forbids the following. https://www.w3.org/Bugs/Public/show_bug.cgi?id=24257", { "input": "http://๏ผ…๏ผ”๏ผ‘.com", "base": "http://other.com/", "failure": true }, { "input": "http://%ef%bc%85%ef%bc%94%ef%bc%91.com", "base": "http://other.com/", "failure": true }, "...%00 in fullwidth should fail (also as escaped UTF-8 input)", { "input": "http://๏ผ…๏ผ๏ผ.com", "base": "http://other.com/", "failure": true }, { "input": "http://%ef%bc%85%ef%bc%90%ef%bc%90.com", "base": "http://other.com/", "failure": true }, "Basic IDN support, UTF-8 and UTF-16 input should be converted to IDN", { "input": "http://ไฝ ๅฅฝไฝ ๅฅฝ", "base": "http://other.com/", "href": "http://xn--6qqa088eba/", "origin": "http://xn--6qqa088eba", "protocol": "http:", "username": "", "password": "", "host": "xn--6qqa088eba", "hostname": "xn--6qqa088eba", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "https://faรŸ.ExAmPlE/", "base": null, "href": "https://xn--fa-hia.example/", "origin": "https://xn--fa-hia.example", "protocol": "https:", "username": "", "password": "", "host": "xn--fa-hia.example", "hostname": "xn--fa-hia.example", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "sc://faรŸ.ExAmPlE/", "base": null, "href": "sc://fa%C3%9F.ExAmPlE/", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "fa%C3%9F.ExAmPlE", "hostname": "fa%C3%9F.ExAmPlE", "port": "", "pathname": "/", "search": "", "hash": "" }, "Invalid escaped characters should fail and the percents should be escaped. https://www.w3.org/Bugs/Public/show_bug.cgi?id=24191", { "input": "http://%zz%66%a.com", "base": "http://other.com/", "failure": true }, "If we get an invalid character that has been escaped.", { "input": "http://%25", "base": "http://other.com/", "failure": true }, { "input": "http://hello%00", "base": "http://other.com/", "failure": true }, "Escaped numbers should be treated like IP addresses if they are.", { "input": "http://%30%78%63%30%2e%30%32%35%30.01", "base": "http://other.com/", "href": "http://192.168.0.1/", "origin": "http://192.168.0.1", "protocol": "http:", "username": "", "password": "", "host": "192.168.0.1", "hostname": "192.168.0.1", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://%30%78%63%30%2e%30%32%35%30.01%2e", "base": "http://other.com/", "href": "http://192.168.0.1/", "origin": "http://192.168.0.1", "protocol": "http:", "username": "", "password": "", "host": "192.168.0.1", "hostname": "192.168.0.1", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://192.168.0.257", "base": "http://other.com/", "failure": true }, "Invalid escaping in hosts causes failure", { "input": "http://%3g%78%63%30%2e%30%32%35%30%2E.01", "base": "http://other.com/", "failure": true }, "A space in a host causes failure", { "input": "http://192.168.0.1 hello", "base": "http://other.com/", "failure": true }, { "input": "https://x x:12", "base": null, "failure": true }, "Fullwidth and escaped UTF-8 fullwidth should still be treated as IP", { "input": "http://๏ผ๏ผธ๏ฝƒ๏ผ๏ผŽ๏ผ๏ผ’๏ผ•๏ผ๏ผŽ๏ผ๏ผ‘", "base": "http://other.com/", "href": "http://192.168.0.1/", "origin": "http://192.168.0.1", "protocol": "http:", "username": "", "password": "", "host": "192.168.0.1", "hostname": "192.168.0.1", "port": "", "pathname": "/", "search": "", "hash": "" }, "Domains with empty labels", { "input": "http://./", "base": null, "href": "http://./", "origin": "http://.", "protocol": "http:", "username": "", "password": "", "host": ".", "hostname": ".", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://../", "base": null, "href": "http://../", "origin": "http://..", "protocol": "http:", "username": "", "password": "", "host": "..", "hostname": "..", "port": "", "pathname": "/", "search": "", "hash": "" }, "Non-special domains with empty labels", { "input": "h://.", "base": null, "href": "h://.", "origin": "null", "protocol": "h:", "username": "", "password": "", "host": ".", "hostname": ".", "port": "", "pathname": "", "search": "", "hash": "" }, "Broken IPv6", { "input": "http://[www.google.com]/", "base": null, "failure": true }, { "input": "http://[google.com]", "base": "http://other.com/", "failure": true }, { "input": "http://[::1.2.3.4x]", "base": "http://other.com/", "failure": true }, { "input": "http://[::1.2.3.]", "base": "http://other.com/", "failure": true }, { "input": "http://[::1.2.]", "base": "http://other.com/", "failure": true }, { "input": "http://[::.1.2]", "base": "http://other.com/", "failure": true }, { "input": "http://[::1.]", "base": "http://other.com/", "failure": true }, { "input": "http://[::.1]", "base": "http://other.com/", "failure": true }, { "input": "http://[::%31]", "base": "http://other.com/", "failure": true }, { "input": "http://%5B::1]", "base": "http://other.com/", "failure": true }, "Misc Unicode", { "input": "http://foo:๐Ÿ’ฉ@example.com/bar", "base": "http://other.com/", "href": "http://foo:%F0%9F%92%A9@example.com/bar", "origin": "http://example.com", "protocol": "http:", "username": "foo", "password": "%F0%9F%92%A9", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/bar", "search": "", "hash": "" }, "# resolving a fragment against any scheme succeeds", { "input": "#", "base": "test:test", "href": "test:test#", "origin": "null", "protocol": "test:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "test", "search": "", "hash": "" }, { "input": "#x", "base": "mailto:x@x.com", "href": "mailto:x@x.com#x", "origin": "null", "protocol": "mailto:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "x@x.com", "search": "", "hash": "#x" }, { "input": "#x", "base": "data:,", "href": "data:,#x", "origin": "null", "protocol": "data:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": ",", "search": "", "hash": "#x" }, { "input": "#x", "base": "about:blank", "href": "about:blank#x", "origin": "null", "protocol": "about:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "blank", "search": "", "hash": "#x" }, { "input": "#x:y", "base": "about:blank", "href": "about:blank#x:y", "origin": "null", "protocol": "about:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "blank", "search": "", "hash": "#x:y" }, { "input": "#", "base": "test:test?test", "href": "test:test?test#", "origin": "null", "protocol": "test:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "test", "search": "?test", "hash": "" }, "# multiple @ in authority state", { "input": "https://@test@test@example:800/", "base": "http://doesnotmatter/", "href": "https://%40test%40test@example:800/", "origin": "https://example:800", "protocol": "https:", "username": "%40test%40test", "password": "", "host": "example:800", "hostname": "example", "port": "800", "pathname": "/", "search": "", "hash": "" }, { "input": "https://@@@example", "base": "http://doesnotmatter/", "href": "https://%40%40@example/", "origin": "https://example", "protocol": "https:", "username": "%40%40", "password": "", "host": "example", "hostname": "example", "port": "", "pathname": "/", "search": "", "hash": "" }, "non-az-09 characters", { "input": "http://`{}:`{}@h/`{}?`{}", "base": "http://doesnotmatter/", "href": "http://%60%7B%7D:%60%7B%7D@h/%60%7B%7D?`{}", "origin": "http://h", "protocol": "http:", "username": "%60%7B%7D", "password": "%60%7B%7D", "host": "h", "hostname": "h", "port": "", "pathname": "/%60%7B%7D", "search": "?`{}", "hash": "" }, "byte is ' and url is special", { "input": "http://host/?'", "base": null, "href": "http://host/?%27", "origin": "http://host", "protocol": "http:", "username": "", "password": "", "host": "host", "hostname": "host", "port": "", "pathname": "/", "search": "?%27", "hash": "" }, { "input": "notspecial://host/?'", "base": null, "href": "notspecial://host/?'", "origin": "null", "protocol": "notspecial:", "username": "", "password": "", "host": "host", "hostname": "host", "port": "", "pathname": "/", "search": "?'", "hash": "" }, "# Credentials in base", { "input": "/some/path", "base": "http://user@example.org/smth", "href": "http://user@example.org/some/path", "origin": "http://example.org", "protocol": "http:", "username": "user", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/some/path", "search": "", "hash": "" }, { "input": "", "base": "http://user:pass@example.org:21/smth", "href": "http://user:pass@example.org:21/smth", "origin": "http://example.org:21", "protocol": "http:", "username": "user", "password": "pass", "host": "example.org:21", "hostname": "example.org", "port": "21", "pathname": "/smth", "search": "", "hash": "" }, { "input": "/some/path", "base": "http://user:pass@example.org:21/smth", "href": "http://user:pass@example.org:21/some/path", "origin": "http://example.org:21", "protocol": "http:", "username": "user", "password": "pass", "host": "example.org:21", "hostname": "example.org", "port": "21", "pathname": "/some/path", "search": "", "hash": "" }, "# a set of tests designed by zcorpan for relative URLs with unknown schemes", { "input": "i", "base": "sc:sd", "failure": true }, { "input": "i", "base": "sc:sd/sd", "failure": true }, { "input": "i", "base": "sc:/pa/pa", "href": "sc:/pa/i", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/pa/i", "search": "", "hash": "" }, { "input": "i", "base": "sc://ho/pa", "href": "sc://ho/i", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "ho", "hostname": "ho", "port": "", "pathname": "/i", "search": "", "hash": "" }, { "input": "i", "base": "sc:///pa/pa", "href": "sc:///pa/i", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/pa/i", "search": "", "hash": "" }, { "input": "../i", "base": "sc:sd", "failure": true }, { "input": "../i", "base": "sc:sd/sd", "failure": true }, { "input": "../i", "base": "sc:/pa/pa", "href": "sc:/i", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/i", "search": "", "hash": "" }, { "input": "../i", "base": "sc://ho/pa", "href": "sc://ho/i", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "ho", "hostname": "ho", "port": "", "pathname": "/i", "search": "", "hash": "" }, { "input": "../i", "base": "sc:///pa/pa", "href": "sc:///i", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/i", "search": "", "hash": "" }, { "input": "/i", "base": "sc:sd", "failure": true }, { "input": "/i", "base": "sc:sd/sd", "failure": true }, { "input": "/i", "base": "sc:/pa/pa", "href": "sc:/i", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/i", "search": "", "hash": "" }, { "input": "/i", "base": "sc://ho/pa", "href": "sc://ho/i", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "ho", "hostname": "ho", "port": "", "pathname": "/i", "search": "", "hash": "" }, { "input": "/i", "base": "sc:///pa/pa", "href": "sc:///i", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/i", "search": "", "hash": "" }, { "input": "?i", "base": "sc:sd", "failure": true }, { "input": "?i", "base": "sc:sd/sd", "failure": true }, { "input": "?i", "base": "sc:/pa/pa", "href": "sc:/pa/pa?i", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/pa/pa", "search": "?i", "hash": "" }, { "input": "?i", "base": "sc://ho/pa", "href": "sc://ho/pa?i", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "ho", "hostname": "ho", "port": "", "pathname": "/pa", "search": "?i", "hash": "" }, { "input": "?i", "base": "sc:///pa/pa", "href": "sc:///pa/pa?i", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/pa/pa", "search": "?i", "hash": "" }, { "input": "#i", "base": "sc:sd", "href": "sc:sd#i", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "sd", "search": "", "hash": "#i" }, { "input": "#i", "base": "sc:sd/sd", "href": "sc:sd/sd#i", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "sd/sd", "search": "", "hash": "#i" }, { "input": "#i", "base": "sc:/pa/pa", "href": "sc:/pa/pa#i", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/pa/pa", "search": "", "hash": "#i" }, { "input": "#i", "base": "sc://ho/pa", "href": "sc://ho/pa#i", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "ho", "hostname": "ho", "port": "", "pathname": "/pa", "search": "", "hash": "#i" }, { "input": "#i", "base": "sc:///pa/pa", "href": "sc:///pa/pa#i", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/pa/pa", "search": "", "hash": "#i" }, "# make sure that relative URL logic works on known typically non-relative schemes too", { "input": "about:/../", "base": null, "href": "about:/", "origin": "null", "protocol": "about:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "data:/../", "base": null, "href": "data:/", "origin": "null", "protocol": "data:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "javascript:/../", "base": null, "href": "javascript:/", "origin": "null", "protocol": "javascript:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "mailto:/../", "base": null, "href": "mailto:/", "origin": "null", "protocol": "mailto:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/", "search": "", "hash": "" }, "# unknown schemes and their hosts", { "input": "sc://รฑ.test/", "base": null, "href": "sc://%C3%B1.test/", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "%C3%B1.test", "hostname": "%C3%B1.test", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "sc://%/", "base": null, "href": "sc://%/", "protocol": "sc:", "username": "", "password": "", "host": "%", "hostname": "%", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "sc://@/", "base": null, "failure": true }, { "input": "sc://te@s:t@/", "base": null, "failure": true }, { "input": "sc://:/", "base": null, "failure": true }, { "input": "sc://:12/", "base": null, "failure": true }, { "input": "x", "base": "sc://รฑ", "href": "sc://%C3%B1/x", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "%C3%B1", "hostname": "%C3%B1", "port": "", "pathname": "/x", "search": "", "hash": "" }, "# unknown schemes and backslashes", { "input": "sc:\\../", "base": null, "href": "sc:\\../", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "\\../", "search": "", "hash": "" }, "# unknown scheme with path looking like a password", { "input": "sc::a@example.net", "base": null, "href": "sc::a@example.net", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": ":a@example.net", "search": "", "hash": "" }, "# unknown scheme with bogus percent-encoding", { "input": "wow:%NBD", "base": null, "href": "wow:%NBD", "origin": "null", "protocol": "wow:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "%NBD", "search": "", "hash": "" }, { "input": "wow:%1G", "base": null, "href": "wow:%1G", "origin": "null", "protocol": "wow:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "%1G", "search": "", "hash": "" }, "# unknown scheme with non-URL characters", { "input": "wow:\uFFFF", "base": null, "href": "wow:%EF%BF%BF", "origin": "null", "protocol": "wow:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "%EF%BF%BF", "search": "", "hash": "" }, { "input": "http://example.com/\uD800\uD801\uDFFE\uDFFF\uFDD0\uFDCF\uFDEF\uFDF0\uFFFE\uFFFF?\uD800\uD801\uDFFE\uDFFF\uFDD0\uFDCF\uFDEF\uFDF0\uFFFE\uFFFF", "base": null, "href": "http://example.com/%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF?%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF", "origin": "http://example.com", "protocol": "http:", "username": "", "password": "", "host": "example.com", "hostname": "example.com", "port": "", "pathname": "/%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF", "search": "?%EF%BF%BD%F0%90%9F%BE%EF%BF%BD%EF%B7%90%EF%B7%8F%EF%B7%AF%EF%B7%B0%EF%BF%BE%EF%BF%BF", "hash": "" }, "Forbidden host code points", { "input": "sc://a\u0000b/", "base": null, "failure": true }, { "input": "sc://a b/", "base": null, "failure": true }, { "input": "sc://ab", "base": null, "failure": true }, { "input": "sc://a[b/", "base": null, "failure": true }, { "input": "sc://a\\b/", "base": null, "failure": true }, { "input": "sc://a]b/", "base": null, "failure": true }, { "input": "sc://a^b", "base": null, "failure": true }, { "input": "sc://a|b/", "base": null, "failure": true }, "Forbidden host codepoints: tabs and newlines are removed during preprocessing", { "input": "foo://ho\u0009st/", "base": null, "hash": "", "host": "host", "hostname": "host", "href":"foo://host/", "password": "", "pathname": "/", "port":"", "protocol": "foo:", "search": "", "username": "" }, { "input": "foo://ho\u000Ast/", "base": null, "hash": "", "host": "host", "hostname": "host", "href":"foo://host/", "password": "", "pathname": "/", "port":"", "protocol": "foo:", "search": "", "username": "" }, { "input": "foo://ho\u000Dst/", "base": null, "hash": "", "host": "host", "hostname": "host", "href":"foo://host/", "password": "", "pathname": "/", "port":"", "protocol": "foo:", "search": "", "username": "" }, "Forbidden domain code-points", { "input": "http://a\u0000b/", "base": null, "failure": true }, { "input": "http://a\u0001b/", "base": null, "failure": true }, { "input": "http://a\u0002b/", "base": null, "failure": true }, { "input": "http://a\u0003b/", "base": null, "failure": true }, { "input": "http://a\u0004b/", "base": null, "failure": true }, { "input": "http://a\u0005b/", "base": null, "failure": true }, { "input": "http://a\u0006b/", "base": null, "failure": true }, { "input": "http://a\u0007b/", "base": null, "failure": true }, { "input": "http://a\u0008b/", "base": null, "failure": true }, { "input": "http://a\u000Bb/", "base": null, "failure": true }, { "input": "http://a\u000Cb/", "base": null, "failure": true }, { "input": "http://a\u000Eb/", "base": null, "failure": true }, { "input": "http://a\u000Fb/", "base": null, "failure": true }, { "input": "http://a\u0010b/", "base": null, "failure": true }, { "input": "http://a\u0011b/", "base": null, "failure": true }, { "input": "http://a\u0012b/", "base": null, "failure": true }, { "input": "http://a\u0013b/", "base": null, "failure": true }, { "input": "http://a\u0014b/", "base": null, "failure": true }, { "input": "http://a\u0015b/", "base": null, "failure": true }, { "input": "http://a\u0016b/", "base": null, "failure": true }, { "input": "http://a\u0017b/", "base": null, "failure": true }, { "input": "http://a\u0018b/", "base": null, "failure": true }, { "input": "http://a\u0019b/", "base": null, "failure": true }, { "input": "http://a\u001Ab/", "base": null, "failure": true }, { "input": "http://a\u001Bb/", "base": null, "failure": true }, { "input": "http://a\u001Cb/", "base": null, "failure": true }, { "input": "http://a\u001Db/", "base": null, "failure": true }, { "input": "http://a\u001Eb/", "base": null, "failure": true }, { "input": "http://a\u001Fb/", "base": null, "failure": true }, { "input": "http://a b/", "base": null, "failure": true }, { "input": "http://a%b/", "base": null, "failure": true }, { "input": "http://ab", "base": null, "failure": true }, { "input": "http://a[b/", "base": null, "failure": true }, { "input": "http://a]b/", "base": null, "failure": true }, { "input": "http://a^b", "base": null, "failure": true }, { "input": "http://a|b/", "base": null, "failure": true }, { "input": "http://a\u007Fb/", "base": null, "failure": true }, "Forbidden domain codepoints: tabs and newlines are removed during preprocessing", { "input": "http://ho\u0009st/", "base": null, "hash": "", "host": "host", "hostname": "host", "href":"http://host/", "password": "", "pathname": "/", "port":"", "protocol": "http:", "search": "", "username": "" }, { "input": "http://ho\u000Ast/", "base": null, "hash": "", "host": "host", "hostname": "host", "href":"http://host/", "password": "", "pathname": "/", "port":"", "protocol": "http:", "search": "", "username": "" }, { "input": "http://ho\u000Dst/", "base": null, "hash": "", "host": "host", "hostname": "host", "href":"http://host/", "password": "", "pathname": "/", "port":"", "protocol": "http:", "search": "", "username": "" }, "Encoded forbidden domain codepoints in special URLs", { "input": "http://ho%00st/", "base": null, "failure": true }, { "input": "http://ho%01st/", "base": null, "failure": true }, { "input": "http://ho%02st/", "base": null, "failure": true }, { "input": "http://ho%03st/", "base": null, "failure": true }, { "input": "http://ho%04st/", "base": null, "failure": true }, { "input": "http://ho%05st/", "base": null, "failure": true }, { "input": "http://ho%06st/", "base": null, "failure": true }, { "input": "http://ho%07st/", "base": null, "failure": true }, { "input": "http://ho%08st/", "base": null, "failure": true }, { "input": "http://ho%09st/", "base": null, "failure": true }, { "input": "http://ho%0Ast/", "base": null, "failure": true }, { "input": "http://ho%0Bst/", "base": null, "failure": true }, { "input": "http://ho%0Cst/", "base": null, "failure": true }, { "input": "http://ho%0Dst/", "base": null, "failure": true }, { "input": "http://ho%0Est/", "base": null, "failure": true }, { "input": "http://ho%0Fst/", "base": null, "failure": true }, { "input": "http://ho%10st/", "base": null, "failure": true }, { "input": "http://ho%11st/", "base": null, "failure": true }, { "input": "http://ho%12st/", "base": null, "failure": true }, { "input": "http://ho%13st/", "base": null, "failure": true }, { "input": "http://ho%14st/", "base": null, "failure": true }, { "input": "http://ho%15st/", "base": null, "failure": true }, { "input": "http://ho%16st/", "base": null, "failure": true }, { "input": "http://ho%17st/", "base": null, "failure": true }, { "input": "http://ho%18st/", "base": null, "failure": true }, { "input": "http://ho%19st/", "base": null, "failure": true }, { "input": "http://ho%1Ast/", "base": null, "failure": true }, { "input": "http://ho%1Bst/", "base": null, "failure": true }, { "input": "http://ho%1Cst/", "base": null, "failure": true }, { "input": "http://ho%1Dst/", "base": null, "failure": true }, { "input": "http://ho%1Est/", "base": null, "failure": true }, { "input": "http://ho%1Fst/", "base": null, "failure": true }, { "input": "http://ho%20st/", "base": null, "failure": true }, { "input": "http://ho%23st/", "base": null, "failure": true }, { "input": "http://ho%25st/", "base": null, "failure": true }, { "input": "http://ho%2Fst/", "base": null, "failure": true }, { "input": "http://ho%3Ast/", "base": null, "failure": true }, { "input": "http://ho%3Cst/", "base": null, "failure": true }, { "input": "http://ho%3Est/", "base": null, "failure": true }, { "input": "http://ho%3Fst/", "base": null, "failure": true }, { "input": "http://ho%40st/", "base": null, "failure": true }, { "input": "http://ho%5Bst/", "base": null, "failure": true }, { "input": "http://ho%5Cst/", "base": null, "failure": true }, { "input": "http://ho%5Dst/", "base": null, "failure": true }, { "input": "http://ho%7Cst/", "base": null, "failure": true }, { "input": "http://ho%7Fst/", "base": null, "failure": true }, "Allowed host/domain code points", { "input": "http://!\"$&'()*+,-.;=_`{}~/", "base": null, "href": "http://!\"$&'()*+,-.;=_`{}~/", "origin": "http://!\"$&'()*+,-.;=_`{}~", "protocol": "http:", "username": "", "password": "", "host": "!\"$&'()*+,-.;=_`{}~", "hostname": "!\"$&'()*+,-.;=_`{}~", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "sc://\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u000B\u000C\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F\u007F!\"$%&'()*+,-.;=_`{}~/", "base": null, "href": "sc://%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F!\"$%&'()*+,-.;=_`{}~/", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F!\"$%&'()*+,-.;=_`{}~", "hostname": "%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F!\"$%&'()*+,-.;=_`{}~", "port": "", "pathname": "/", "search": "", "hash": "" }, "# Hosts and percent-encoding", { "input": "ftp://example.com%80/", "base": null, "failure": true }, { "input": "ftp://example.com%A0/", "base": null, "failure": true }, { "input": "https://example.com%80/", "base": null, "failure": true }, { "input": "https://example.com%A0/", "base": null, "failure": true }, { "input": "ftp://%e2%98%83", "base": null, "href": "ftp://xn--n3h/", "origin": "ftp://xn--n3h", "protocol": "ftp:", "username": "", "password": "", "host": "xn--n3h", "hostname": "xn--n3h", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "https://%e2%98%83", "base": null, "href": "https://xn--n3h/", "origin": "https://xn--n3h", "protocol": "https:", "username": "", "password": "", "host": "xn--n3h", "hostname": "xn--n3h", "port": "", "pathname": "/", "search": "", "hash": "" }, "# tests from jsdom/whatwg-url designed for code coverage", { "input": "http://127.0.0.1:10100/relative_import.html", "base": null, "href": "http://127.0.0.1:10100/relative_import.html", "origin": "http://127.0.0.1:10100", "protocol": "http:", "username": "", "password": "", "host": "127.0.0.1:10100", "hostname": "127.0.0.1", "port": "10100", "pathname": "/relative_import.html", "search": "", "hash": "" }, { "input": "http://facebook.com/?foo=%7B%22abc%22", "base": null, "href": "http://facebook.com/?foo=%7B%22abc%22", "origin": "http://facebook.com", "protocol": "http:", "username": "", "password": "", "host": "facebook.com", "hostname": "facebook.com", "port": "", "pathname": "/", "search": "?foo=%7B%22abc%22", "hash": "" }, { "input": "https://localhost:3000/jqueryui@1.2.3", "base": null, "href": "https://localhost:3000/jqueryui@1.2.3", "origin": "https://localhost:3000", "protocol": "https:", "username": "", "password": "", "host": "localhost:3000", "hostname": "localhost", "port": "3000", "pathname": "/jqueryui@1.2.3", "search": "", "hash": "" }, "# tab/LF/CR", { "input": "h\tt\nt\rp://h\to\ns\rt:9\t0\n0\r0/p\ta\nt\rh?q\tu\ne\rry#f\tr\na\rg", "base": null, "href": "http://host:9000/path?query#frag", "origin": "http://host:9000", "protocol": "http:", "username": "", "password": "", "host": "host:9000", "hostname": "host", "port": "9000", "pathname": "/path", "search": "?query", "hash": "#frag" }, "# Stringification of URL.searchParams", { "input": "?a=b&c=d", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/bar?a=b&c=d", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/bar", "search": "?a=b&c=d", "searchParams": "a=b&c=d", "hash": "" }, { "input": "??a=b&c=d", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/bar??a=b&c=d", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/bar", "search": "??a=b&c=d", "searchParams": "%3Fa=b&c=d", "hash": "" }, "# Scheme only", { "input": "http:", "base": "http://example.org/foo/bar", "href": "http://example.org/foo/bar", "origin": "http://example.org", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/foo/bar", "search": "", "searchParams": "", "hash": "" }, { "input": "http:", "base": "https://example.org/foo/bar", "failure": true }, { "input": "sc:", "base": "https://example.org/foo/bar", "href": "sc:", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "", "search": "", "searchParams": "", "hash": "" }, "# Percent encoding of fragments", { "input": "http://foo.bar/baz?qux#foo\bbar", "base": null, "href": "http://foo.bar/baz?qux#foo%08bar", "origin": "http://foo.bar", "protocol": "http:", "username": "", "password": "", "host": "foo.bar", "hostname": "foo.bar", "port": "", "pathname": "/baz", "search": "?qux", "searchParams": "qux=", "hash": "#foo%08bar" }, { "input": "http://foo.bar/baz?qux#foo\"bar", "base": null, "href": "http://foo.bar/baz?qux#foo%22bar", "origin": "http://foo.bar", "protocol": "http:", "username": "", "password": "", "host": "foo.bar", "hostname": "foo.bar", "port": "", "pathname": "/baz", "search": "?qux", "searchParams": "qux=", "hash": "#foo%22bar" }, { "input": "http://foo.bar/baz?qux#foobar", "base": null, "href": "http://foo.bar/baz?qux#foo%3Ebar", "origin": "http://foo.bar", "protocol": "http:", "username": "", "password": "", "host": "foo.bar", "hostname": "foo.bar", "port": "", "pathname": "/baz", "search": "?qux", "searchParams": "qux=", "hash": "#foo%3Ebar" }, { "input": "http://foo.bar/baz?qux#foo`bar", "base": null, "href": "http://foo.bar/baz?qux#foo%60bar", "origin": "http://foo.bar", "protocol": "http:", "username": "", "password": "", "host": "foo.bar", "hostname": "foo.bar", "port": "", "pathname": "/baz", "search": "?qux", "searchParams": "qux=", "hash": "#foo%60bar" }, "# IPv4 parsing (via https://github.com/nodejs/node/pull/10317)", { "input": "http://1.2.3.4/", "base": "http://other.com/", "href": "http://1.2.3.4/", "origin": "http://1.2.3.4", "protocol": "http:", "username": "", "password": "", "host": "1.2.3.4", "hostname": "1.2.3.4", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://1.2.3.4./", "base": "http://other.com/", "href": "http://1.2.3.4/", "origin": "http://1.2.3.4", "protocol": "http:", "username": "", "password": "", "host": "1.2.3.4", "hostname": "1.2.3.4", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://192.168.257", "base": "http://other.com/", "href": "http://192.168.1.1/", "origin": "http://192.168.1.1", "protocol": "http:", "username": "", "password": "", "host": "192.168.1.1", "hostname": "192.168.1.1", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://192.168.257.", "base": "http://other.com/", "href": "http://192.168.1.1/", "origin": "http://192.168.1.1", "protocol": "http:", "username": "", "password": "", "host": "192.168.1.1", "hostname": "192.168.1.1", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://192.168.257.com", "base": "http://other.com/", "href": "http://192.168.257.com/", "origin": "http://192.168.257.com", "protocol": "http:", "username": "", "password": "", "host": "192.168.257.com", "hostname": "192.168.257.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://256", "base": "http://other.com/", "href": "http://0.0.1.0/", "origin": "http://0.0.1.0", "protocol": "http:", "username": "", "password": "", "host": "0.0.1.0", "hostname": "0.0.1.0", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://256.com", "base": "http://other.com/", "href": "http://256.com/", "origin": "http://256.com", "protocol": "http:", "username": "", "password": "", "host": "256.com", "hostname": "256.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://999999999", "base": "http://other.com/", "href": "http://59.154.201.255/", "origin": "http://59.154.201.255", "protocol": "http:", "username": "", "password": "", "host": "59.154.201.255", "hostname": "59.154.201.255", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://999999999.", "base": "http://other.com/", "href": "http://59.154.201.255/", "origin": "http://59.154.201.255", "protocol": "http:", "username": "", "password": "", "host": "59.154.201.255", "hostname": "59.154.201.255", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://999999999.com", "base": "http://other.com/", "href": "http://999999999.com/", "origin": "http://999999999.com", "protocol": "http:", "username": "", "password": "", "host": "999999999.com", "hostname": "999999999.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://10000000000", "base": "http://other.com/", "failure": true }, { "input": "http://10000000000.com", "base": "http://other.com/", "href": "http://10000000000.com/", "origin": "http://10000000000.com", "protocol": "http:", "username": "", "password": "", "host": "10000000000.com", "hostname": "10000000000.com", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://4294967295", "base": "http://other.com/", "href": "http://255.255.255.255/", "origin": "http://255.255.255.255", "protocol": "http:", "username": "", "password": "", "host": "255.255.255.255", "hostname": "255.255.255.255", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://4294967296", "base": "http://other.com/", "failure": true }, { "input": "http://0xffffffff", "base": "http://other.com/", "href": "http://255.255.255.255/", "origin": "http://255.255.255.255", "protocol": "http:", "username": "", "password": "", "host": "255.255.255.255", "hostname": "255.255.255.255", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://0xffffffff1", "base": "http://other.com/", "failure": true }, { "input": "http://256.256.256.256", "base": "http://other.com/", "failure": true }, { "input": "https://0x.0x.0", "base": null, "href": "https://0.0.0.0/", "origin": "https://0.0.0.0", "protocol": "https:", "username": "", "password": "", "host": "0.0.0.0", "hostname": "0.0.0.0", "port": "", "pathname": "/", "search": "", "hash": "" }, "More IPv4 parsing (via https://github.com/jsdom/whatwg-url/issues/92)", { "input": "https://0x100000000/test", "base": null, "failure": true }, { "input": "https://256.0.0.1/test", "base": null, "failure": true }, "# file URLs containing percent-encoded Windows drive letters (shouldn't work)", { "input": "file:///C%3A/", "base": null, "href": "file:///C%3A/", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/C%3A/", "search": "", "hash": "" }, { "input": "file:///C%7C/", "base": null, "href": "file:///C%7C/", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/C%7C/", "search": "", "hash": "" }, { "input": "file://%43%3A", "base": null, "failure": true }, { "input": "file://%43%7C", "base": null, "failure": true }, { "input": "file://%43|", "base": null, "failure": true }, { "input": "file://C%7C", "base": null, "failure": true }, { "input": "file://%43%7C/", "base": null, "failure": true }, { "input": "https://%43%7C/", "base": null, "failure": true }, { "input": "asdf://%43|/", "base": null, "failure": true }, { "input": "asdf://%43%7C/", "base": null, "href": "asdf://%43%7C/", "origin": "null", "protocol": "asdf:", "username": "", "password": "", "host": "%43%7C", "hostname": "%43%7C", "port": "", "pathname": "/", "search": "", "hash": "" }, "# file URLs relative to other file URLs (via https://github.com/jsdom/whatwg-url/pull/60)", { "input": "pix/submit.gif", "base": "file:///C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/anchor.html", "href": "file:///C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/pix/submit.gif", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/pix/submit.gif", "search": "", "hash": "" }, { "input": "..", "base": "file:///C:/", "href": "file:///C:/", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/C:/", "search": "", "hash": "" }, { "input": "..", "base": "file:///", "href": "file:///", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/", "search": "", "hash": "" }, "# More file URL tests by zcorpan and annevk", { "input": "/", "base": "file:///C:/a/b", "href": "file:///C:/", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/C:/", "search": "", "hash": "" }, { "input": "/", "base": "file://h/C:/a/b", "href": "file://h/C:/", "protocol": "file:", "username": "", "password": "", "host": "h", "hostname": "h", "port": "", "pathname": "/C:/", "search": "", "hash": "" }, { "input": "/", "base": "file://h/a/b", "href": "file://h/", "protocol": "file:", "username": "", "password": "", "host": "h", "hostname": "h", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "//d:", "base": "file:///C:/a/b", "href": "file:///d:", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/d:", "search": "", "hash": "" }, { "input": "//d:/..", "base": "file:///C:/a/b", "href": "file:///d:/", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/d:/", "search": "", "hash": "" }, { "input": "..", "base": "file:///ab:/", "href": "file:///", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "..", "base": "file:///1:/", "href": "file:///", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "", "base": "file:///test?test#test", "href": "file:///test?test", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/test", "search": "?test", "hash": "" }, { "input": "file:", "base": "file:///test?test#test", "href": "file:///test?test", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/test", "search": "?test", "hash": "" }, { "input": "?x", "base": "file:///test?test#test", "href": "file:///test?x", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/test", "search": "?x", "hash": "" }, { "input": "file:?x", "base": "file:///test?test#test", "href": "file:///test?x", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/test", "search": "?x", "hash": "" }, { "input": "#x", "base": "file:///test?test#test", "href": "file:///test?test#x", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/test", "search": "?test", "hash": "#x" }, { "input": "file:#x", "base": "file:///test?test#test", "href": "file:///test?test#x", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/test", "search": "?test", "hash": "#x" }, "# File URLs and many (back)slashes", { "input": "file:\\\\//", "base": null, "href": "file:////", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//", "search": "", "hash": "" }, { "input": "file:\\\\\\\\", "base": null, "href": "file:////", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//", "search": "", "hash": "" }, { "input": "file:\\\\\\\\?fox", "base": null, "href": "file:////?fox", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//", "search": "?fox", "hash": "" }, { "input": "file:\\\\\\\\#guppy", "base": null, "href": "file:////#guppy", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//", "search": "", "hash": "#guppy" }, { "input": "file://spider///", "base": null, "href": "file://spider///", "protocol": "file:", "username": "", "password": "", "host": "spider", "hostname": "spider", "port": "", "pathname": "///", "search": "", "hash": "" }, { "input": "file:\\\\localhost//", "base": null, "href": "file:////", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//", "search": "", "hash": "" }, { "input": "file:///localhost//cat", "base": null, "href": "file:///localhost//cat", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/localhost//cat", "search": "", "hash": "" }, { "input": "file://\\/localhost//cat", "base": null, "href": "file:////localhost//cat", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//localhost//cat", "search": "", "hash": "" }, { "input": "file://localhost//a//../..//", "base": null, "href": "file://///", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "///", "search": "", "hash": "" }, { "input": "/////mouse", "base": "file:///elephant", "href": "file://///mouse", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "///mouse", "search": "", "hash": "" }, { "input": "\\//pig", "base": "file://lion/", "href": "file:///pig", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/pig", "search": "", "hash": "" }, { "input": "\\/localhost//pig", "base": "file://lion/", "href": "file:////pig", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//pig", "search": "", "hash": "" }, { "input": "//localhost//pig", "base": "file://lion/", "href": "file:////pig", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//pig", "search": "", "hash": "" }, { "input": "/..//localhost//pig", "base": "file://lion/", "href": "file://lion//localhost//pig", "protocol": "file:", "username": "", "password": "", "host": "lion", "hostname": "lion", "port": "", "pathname": "//localhost//pig", "search": "", "hash": "" }, { "input": "file://", "base": "file://ape/", "href": "file:///", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/", "search": "", "hash": "" }, "# File URLs with non-empty hosts", { "input": "/rooibos", "base": "file://tea/", "href": "file://tea/rooibos", "protocol": "file:", "username": "", "password": "", "host": "tea", "hostname": "tea", "port": "", "pathname": "/rooibos", "search": "", "hash": "" }, { "input": "/?chai", "base": "file://tea/", "href": "file://tea/?chai", "protocol": "file:", "username": "", "password": "", "host": "tea", "hostname": "tea", "port": "", "pathname": "/", "search": "?chai", "hash": "" }, "# Windows drive letter handling with the 'file:' base URL", { "input": "C|", "base": "file://host/dir/file", "href": "file://host/C:", "protocol": "file:", "username": "", "password": "", "host": "host", "hostname": "host", "port": "", "pathname": "/C:", "search": "", "hash": "" }, { "input": "C|", "base": "file://host/D:/dir1/dir2/file", "href": "file://host/C:", "protocol": "file:", "username": "", "password": "", "host": "host", "hostname": "host", "port": "", "pathname": "/C:", "search": "", "hash": "" }, { "input": "C|#", "base": "file://host/dir/file", "href": "file://host/C:#", "protocol": "file:", "username": "", "password": "", "host": "host", "hostname": "host", "port": "", "pathname": "/C:", "search": "", "hash": "" }, { "input": "C|?", "base": "file://host/dir/file", "href": "file://host/C:?", "protocol": "file:", "username": "", "password": "", "host": "host", "hostname": "host", "port": "", "pathname": "/C:", "search": "", "hash": "" }, { "input": "C|/", "base": "file://host/dir/file", "href": "file://host/C:/", "protocol": "file:", "username": "", "password": "", "host": "host", "hostname": "host", "port": "", "pathname": "/C:/", "search": "", "hash": "" }, { "input": "C|\n/", "base": "file://host/dir/file", "href": "file://host/C:/", "protocol": "file:", "username": "", "password": "", "host": "host", "hostname": "host", "port": "", "pathname": "/C:/", "search": "", "hash": "" }, { "input": "C|\\", "base": "file://host/dir/file", "href": "file://host/C:/", "protocol": "file:", "username": "", "password": "", "host": "host", "hostname": "host", "port": "", "pathname": "/C:/", "search": "", "hash": "" }, { "input": "C", "base": "file://host/dir/file", "href": "file://host/dir/C", "protocol": "file:", "username": "", "password": "", "host": "host", "hostname": "host", "port": "", "pathname": "/dir/C", "search": "", "hash": "" }, { "input": "C|a", "base": "file://host/dir/file", "href": "file://host/dir/C|a", "protocol": "file:", "username": "", "password": "", "host": "host", "hostname": "host", "port": "", "pathname": "/dir/C|a", "search": "", "hash": "" }, "# Windows drive letter quirk in the file slash state", { "input": "/c:/foo/bar", "base": "file:///c:/baz/qux", "href": "file:///c:/foo/bar", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/c:/foo/bar", "search": "", "hash": "" }, { "input": "/c|/foo/bar", "base": "file:///c:/baz/qux", "href": "file:///c:/foo/bar", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/c:/foo/bar", "search": "", "hash": "" }, { "input": "file:\\c:\\foo\\bar", "base": "file:///c:/baz/qux", "href": "file:///c:/foo/bar", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/c:/foo/bar", "search": "", "hash": "" }, { "input": "/c:/foo/bar", "base": "file://host/path", "href": "file://host/c:/foo/bar", "protocol": "file:", "username": "", "password": "", "host": "host", "hostname": "host", "port": "", "pathname": "/c:/foo/bar", "search": "", "hash": "" }, "# Do not drop the host in the presence of a drive letter", { "input": "file://example.net/C:/", "base": null, "href": "file://example.net/C:/", "protocol": "file:", "username": "", "password": "", "host": "example.net", "hostname": "example.net", "port": "", "pathname": "/C:/", "search": "", "hash": "" }, { "input": "file://1.2.3.4/C:/", "base": null, "href": "file://1.2.3.4/C:/", "protocol": "file:", "username": "", "password": "", "host": "1.2.3.4", "hostname": "1.2.3.4", "port": "", "pathname": "/C:/", "search": "", "hash": "" }, { "input": "file://[1::8]/C:/", "base": null, "href": "file://[1::8]/C:/", "protocol": "file:", "username": "", "password": "", "host": "[1::8]", "hostname": "[1::8]", "port": "", "pathname": "/C:/", "search": "", "hash": "" }, "# Copy the host from the base URL in the following cases", { "input": "C|/", "base": "file://host/", "href": "file://host/C:/", "protocol": "file:", "username": "", "password": "", "host": "host", "hostname": "host", "port": "", "pathname": "/C:/", "search": "", "hash": "" }, { "input": "/C:/", "base": "file://host/", "href": "file://host/C:/", "protocol": "file:", "username": "", "password": "", "host": "host", "hostname": "host", "port": "", "pathname": "/C:/", "search": "", "hash": "" }, { "input": "file:C:/", "base": "file://host/", "href": "file://host/C:/", "protocol": "file:", "username": "", "password": "", "host": "host", "hostname": "host", "port": "", "pathname": "/C:/", "search": "", "hash": "" }, { "input": "file:/C:/", "base": "file://host/", "href": "file://host/C:/", "protocol": "file:", "username": "", "password": "", "host": "host", "hostname": "host", "port": "", "pathname": "/C:/", "search": "", "hash": "" }, "# Copy the empty host from the input in the following cases", { "input": "//C:/", "base": "file://host/", "href": "file:///C:/", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/C:/", "search": "", "hash": "" }, { "input": "file://C:/", "base": "file://host/", "href": "file:///C:/", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/C:/", "search": "", "hash": "" }, { "input": "///C:/", "base": "file://host/", "href": "file:///C:/", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/C:/", "search": "", "hash": "" }, { "input": "file:///C:/", "base": "file://host/", "href": "file:///C:/", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/C:/", "search": "", "hash": "" }, "# Windows drive letter quirk (no host)", { "input": "file:/C|/", "base": null, "href": "file:///C:/", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/C:/", "search": "", "hash": "" }, { "input": "file://C|/", "base": null, "href": "file:///C:/", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/C:/", "search": "", "hash": "" }, "# file URLs without base URL by Rimas Miseviฤius", { "input": "file:", "base": null, "href": "file:///", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "file:?q=v", "base": null, "href": "file:///?q=v", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/", "search": "?q=v", "hash": "" }, { "input": "file:#frag", "base": null, "href": "file:///#frag", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/", "search": "", "hash": "#frag" }, "# file: drive letter cases from https://crbug.com/1078698", { "input": "file:///Y:", "base": null, "href": "file:///Y:", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/Y:", "search": "", "hash": "" }, { "input": "file:///Y:/", "base": null, "href": "file:///Y:/", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/Y:/", "search": "", "hash": "" }, { "input": "file:///./Y", "base": null, "href": "file:///Y", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/Y", "search": "", "hash": "" }, { "input": "file:///./Y:", "base": null, "href": "file:///Y:", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/Y:", "search": "", "hash": "" }, { "input": "\\\\\\.\\Y:", "base": null, "failure": true, "relativeTo": "non-opaque-path-base" }, "# file: drive letter cases from https://crbug.com/1078698 but lowercased", { "input": "file:///y:", "base": null, "href": "file:///y:", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/y:", "search": "", "hash": "" }, { "input": "file:///y:/", "base": null, "href": "file:///y:/", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/y:/", "search": "", "hash": "" }, { "input": "file:///./y", "base": null, "href": "file:///y", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/y", "search": "", "hash": "" }, { "input": "file:///./y:", "base": null, "href": "file:///y:", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/y:", "search": "", "hash": "" }, { "input": "\\\\\\.\\y:", "base": null, "failure": true, "relativeTo": "non-opaque-path-base" }, "# Additional file URL tests for (https://github.com/whatwg/url/issues/405)", { "input": "file://localhost//a//../..//foo", "base": null, "href": "file://///foo", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "///foo", "search": "", "hash": "" }, { "input": "file://localhost////foo", "base": null, "href": "file://////foo", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "////foo", "search": "", "hash": "" }, { "input": "file:////foo", "base": null, "href": "file:////foo", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//foo", "search": "", "hash": "" }, { "input": "file:///one/two", "base": "file:///", "href": "file:///one/two", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/one/two", "search": "", "hash": "" }, { "input": "file:////one/two", "base": "file:///", "href": "file:////one/two", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//one/two", "search": "", "hash": "" }, { "input": "//one/two", "base": "file:///", "href": "file://one/two", "protocol": "file:", "username": "", "password": "", "host": "one", "hostname": "one", "port": "", "pathname": "/two", "search": "", "hash": "" }, { "input": "///one/two", "base": "file:///", "href": "file:///one/two", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/one/two", "search": "", "hash": "" }, { "input": "////one/two", "base": "file:///", "href": "file:////one/two", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//one/two", "search": "", "hash": "" }, { "input": "file:///.//", "base": "file:////", "href": "file:////", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//", "search": "", "hash": "" }, "File URL tests for https://github.com/whatwg/url/issues/549", { "input": "file:.//p", "base": null, "href": "file:////p", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//p", "search": "", "hash": "" }, { "input": "file:/.//p", "base": null, "href": "file:////p", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//p", "search": "", "hash": "" }, "# IPv6 tests", { "input": "http://[1:0::]", "base": "http://example.net/", "href": "http://[1::]/", "origin": "http://[1::]", "protocol": "http:", "username": "", "password": "", "host": "[1::]", "hostname": "[1::]", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://[0:1:2:3:4:5:6:7:8]", "base": "http://example.net/", "failure": true }, { "input": "https://[0::0::0]", "base": null, "failure": true }, { "input": "https://[0:.0]", "base": null, "failure": true }, { "input": "https://[0:0:]", "base": null, "failure": true }, { "input": "https://[0:1:2:3:4:5:6:7.0.0.0.1]", "base": null, "failure": true }, { "input": "https://[0:1.00.0.0.0]", "base": null, "failure": true }, { "input": "https://[0:1.290.0.0.0]", "base": null, "failure": true }, { "input": "https://[0:1.23.23]", "base": null, "failure": true }, "# Empty host", { "input": "http://?", "base": null, "failure": true }, { "input": "http://#", "base": null, "failure": true }, "Port overflow (2^32 + 81)", { "input": "http://f:4294967377/c", "base": "http://example.org/", "failure": true }, "Port overflow (2^64 + 81)", { "input": "http://f:18446744073709551697/c", "base": "http://example.org/", "failure": true }, "Port overflow (2^128 + 81)", { "input": "http://f:340282366920938463463374607431768211537/c", "base": "http://example.org/", "failure": true }, "# Non-special-URL path tests", { "input": "sc://รฑ", "base": null, "href": "sc://%C3%B1", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "%C3%B1", "hostname": "%C3%B1", "port": "", "pathname": "", "search": "", "hash": "" }, { "input": "sc://รฑ?x", "base": null, "href": "sc://%C3%B1?x", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "%C3%B1", "hostname": "%C3%B1", "port": "", "pathname": "", "search": "?x", "hash": "" }, { "input": "sc://รฑ#x", "base": null, "href": "sc://%C3%B1#x", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "%C3%B1", "hostname": "%C3%B1", "port": "", "pathname": "", "search": "", "hash": "#x" }, { "input": "#x", "base": "sc://รฑ", "href": "sc://%C3%B1#x", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "%C3%B1", "hostname": "%C3%B1", "port": "", "pathname": "", "search": "", "hash": "#x" }, { "input": "?x", "base": "sc://รฑ", "href": "sc://%C3%B1?x", "origin": "null", "protocol": "sc:", "username": "", "password": "", "host": "%C3%B1", "hostname": "%C3%B1", "port": "", "pathname": "", "search": "?x", "hash": "" }, { "input": "sc://?", "base": null, "href": "sc://?", "protocol": "sc:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "", "search": "", "hash": "" }, { "input": "sc://#", "base": null, "href": "sc://#", "protocol": "sc:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "", "search": "", "hash": "" }, { "input": "///", "base": "sc://x/", "href": "sc:///", "protocol": "sc:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "////", "base": "sc://x/", "href": "sc:////", "protocol": "sc:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//", "search": "", "hash": "" }, { "input": "////x/", "base": "sc://x/", "href": "sc:////x/", "protocol": "sc:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//x/", "search": "", "hash": "" }, { "input": "tftp://foobar.com/someconfig;mode=netascii", "base": null, "href": "tftp://foobar.com/someconfig;mode=netascii", "origin": "null", "protocol": "tftp:", "username": "", "password": "", "host": "foobar.com", "hostname": "foobar.com", "port": "", "pathname": "/someconfig;mode=netascii", "search": "", "hash": "" }, { "input": "telnet://user:pass@foobar.com:23/", "base": null, "href": "telnet://user:pass@foobar.com:23/", "origin": "null", "protocol": "telnet:", "username": "user", "password": "pass", "host": "foobar.com:23", "hostname": "foobar.com", "port": "23", "pathname": "/", "search": "", "hash": "" }, { "input": "ut2004://10.10.10.10:7777/Index.ut2", "base": null, "href": "ut2004://10.10.10.10:7777/Index.ut2", "origin": "null", "protocol": "ut2004:", "username": "", "password": "", "host": "10.10.10.10:7777", "hostname": "10.10.10.10", "port": "7777", "pathname": "/Index.ut2", "search": "", "hash": "" }, { "input": "redis://foo:bar@somehost:6379/0?baz=bam&qux=baz", "base": null, "href": "redis://foo:bar@somehost:6379/0?baz=bam&qux=baz", "origin": "null", "protocol": "redis:", "username": "foo", "password": "bar", "host": "somehost:6379", "hostname": "somehost", "port": "6379", "pathname": "/0", "search": "?baz=bam&qux=baz", "hash": "" }, { "input": "rsync://foo@host:911/sup", "base": null, "href": "rsync://foo@host:911/sup", "origin": "null", "protocol": "rsync:", "username": "foo", "password": "", "host": "host:911", "hostname": "host", "port": "911", "pathname": "/sup", "search": "", "hash": "" }, { "input": "git://github.com/foo/bar.git", "base": null, "href": "git://github.com/foo/bar.git", "origin": "null", "protocol": "git:", "username": "", "password": "", "host": "github.com", "hostname": "github.com", "port": "", "pathname": "/foo/bar.git", "search": "", "hash": "" }, { "input": "irc://myserver.com:6999/channel?passwd", "base": null, "href": "irc://myserver.com:6999/channel?passwd", "origin": "null", "protocol": "irc:", "username": "", "password": "", "host": "myserver.com:6999", "hostname": "myserver.com", "port": "6999", "pathname": "/channel", "search": "?passwd", "hash": "" }, { "input": "dns://fw.example.org:9999/foo.bar.org?type=TXT", "base": null, "href": "dns://fw.example.org:9999/foo.bar.org?type=TXT", "origin": "null", "protocol": "dns:", "username": "", "password": "", "host": "fw.example.org:9999", "hostname": "fw.example.org", "port": "9999", "pathname": "/foo.bar.org", "search": "?type=TXT", "hash": "" }, { "input": "ldap://localhost:389/ou=People,o=JNDITutorial", "base": null, "href": "ldap://localhost:389/ou=People,o=JNDITutorial", "origin": "null", "protocol": "ldap:", "username": "", "password": "", "host": "localhost:389", "hostname": "localhost", "port": "389", "pathname": "/ou=People,o=JNDITutorial", "search": "", "hash": "" }, { "input": "git+https://github.com/foo/bar", "base": null, "href": "git+https://github.com/foo/bar", "origin": "null", "protocol": "git+https:", "username": "", "password": "", "host": "github.com", "hostname": "github.com", "port": "", "pathname": "/foo/bar", "search": "", "hash": "" }, { "input": "urn:ietf:rfc:2648", "base": null, "href": "urn:ietf:rfc:2648", "origin": "null", "protocol": "urn:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "ietf:rfc:2648", "search": "", "hash": "" }, { "input": "tag:joe@example.org,2001:foo/bar", "base": null, "href": "tag:joe@example.org,2001:foo/bar", "origin": "null", "protocol": "tag:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "joe@example.org,2001:foo/bar", "search": "", "hash": "" }, "Serialize /. in path", { "input": "non-spec:/.//", "base": null, "href": "non-spec:/.//", "protocol": "non-spec:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//", "search": "", "hash": "" }, { "input": "non-spec:/..//", "base": null, "href": "non-spec:/.//", "protocol": "non-spec:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//", "search": "", "hash": "" }, { "input": "non-spec:/a/..//", "base": null, "href": "non-spec:/.//", "protocol": "non-spec:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//", "search": "", "hash": "" }, { "input": "non-spec:/.//path", "base": null, "href": "non-spec:/.//path", "protocol": "non-spec:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//path", "search": "", "hash": "" }, { "input": "non-spec:/..//path", "base": null, "href": "non-spec:/.//path", "protocol": "non-spec:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//path", "search": "", "hash": "" }, { "input": "non-spec:/a/..//path", "base": null, "href": "non-spec:/.//path", "protocol": "non-spec:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//path", "search": "", "hash": "" }, { "input": "/.//path", "base": "non-spec:/p", "href": "non-spec:/.//path", "protocol": "non-spec:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//path", "search": "", "hash": "" }, { "input": "/..//path", "base": "non-spec:/p", "href": "non-spec:/.//path", "protocol": "non-spec:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//path", "search": "", "hash": "" }, { "input": "..//path", "base": "non-spec:/p", "href": "non-spec:/.//path", "protocol": "non-spec:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//path", "search": "", "hash": "" }, { "input": "a/..//path", "base": "non-spec:/p", "href": "non-spec:/.//path", "protocol": "non-spec:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//path", "search": "", "hash": "" }, { "input": "", "base": "non-spec:/..//p", "href": "non-spec:/.//p", "protocol": "non-spec:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//p", "search": "", "hash": "" }, { "input": "path", "base": "non-spec:/..//p", "href": "non-spec:/.//path", "protocol": "non-spec:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "//path", "search": "", "hash": "" }, "Do not serialize /. in path", { "input": "../path", "base": "non-spec:/.//p", "href": "non-spec:/path", "protocol": "non-spec:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/path", "search": "", "hash": "" }, "# percent encoded hosts in non-special-URLs", { "input": "non-special://%E2%80%A0/", "base": null, "href": "non-special://%E2%80%A0/", "protocol": "non-special:", "username": "", "password": "", "host": "%E2%80%A0", "hostname": "%E2%80%A0", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "non-special://H%4fSt/path", "base": null, "href": "non-special://H%4fSt/path", "protocol": "non-special:", "username": "", "password": "", "host": "H%4fSt", "hostname": "H%4fSt", "port": "", "pathname": "/path", "search": "", "hash": "" }, "# IPv6 in non-special-URLs", { "input": "non-special://[1:2:0:0:5:0:0:0]/", "base": null, "href": "non-special://[1:2:0:0:5::]/", "protocol": "non-special:", "username": "", "password": "", "host": "[1:2:0:0:5::]", "hostname": "[1:2:0:0:5::]", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "non-special://[1:2:0:0:0:0:0:3]/", "base": null, "href": "non-special://[1:2::3]/", "protocol": "non-special:", "username": "", "password": "", "host": "[1:2::3]", "hostname": "[1:2::3]", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "non-special://[1:2::3]:80/", "base": null, "href": "non-special://[1:2::3]:80/", "protocol": "non-special:", "username": "", "password": "", "host": "[1:2::3]:80", "hostname": "[1:2::3]", "port": "80", "pathname": "/", "search": "", "hash": "" }, { "input": "non-special://[:80/", "base": null, "failure": true }, { "input": "blob:https://example.com:443/", "base": null, "href": "blob:https://example.com:443/", "origin": "https://example.com", "protocol": "blob:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "https://example.com:443/", "search": "", "hash": "" }, { "input": "blob:http://example.org:88/", "base": null, "href": "blob:http://example.org:88/", "origin": "http://example.org:88", "protocol": "blob:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "http://example.org:88/", "search": "", "hash": "" }, { "input": "blob:d3958f5c-0777-0845-9dcf-2cb28783acaf", "base": null, "href": "blob:d3958f5c-0777-0845-9dcf-2cb28783acaf", "origin": "null", "protocol": "blob:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "d3958f5c-0777-0845-9dcf-2cb28783acaf", "search": "", "hash": "" }, { "input": "blob:", "base": null, "href": "blob:", "origin": "null", "protocol": "blob:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "", "search": "", "hash": "" }, "blob: in blob:", { "input": "blob:blob:", "base": null, "href": "blob:blob:", "origin": "null", "protocol": "blob:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "blob:", "search": "", "hash": "" }, { "input": "blob:blob:https://example.org/", "base": null, "href": "blob:blob:https://example.org/", "origin": "null", "protocol": "blob:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "blob:https://example.org/", "search": "", "hash": "" }, "Non-http(s): in blob:", { "input": "blob:about:blank", "base": null, "href": "blob:about:blank", "origin": "null", "protocol": "blob:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "about:blank", "search": "", "hash": "" }, { "input": "blob:file://host/path", "base": null, "href": "blob:file://host/path", "protocol": "blob:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "file://host/path", "search": "", "hash": "" }, { "input": "blob:ftp://host/path", "base": null, "href": "blob:ftp://host/path", "origin": "null", "protocol": "blob:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "ftp://host/path", "search": "", "hash": "" }, { "input": "blob:ws://example.org/", "base": null, "href": "blob:ws://example.org/", "origin": "null", "protocol": "blob:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "ws://example.org/", "search": "", "hash": "" }, { "input": "blob:wss://example.org/", "base": null, "href": "blob:wss://example.org/", "origin": "null", "protocol": "blob:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "wss://example.org/", "search": "", "hash": "" }, "Percent-encoded http: in blob:", { "input": "blob:http%3a//example.org/", "base": null, "href": "blob:http%3a//example.org/", "origin": "null", "protocol": "blob:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "http%3a//example.org/", "search": "", "hash": "" }, "Invalid IPv4 radix digits", { "input": "http://0x7f.0.0.0x7g", "base": null, "href": "http://0x7f.0.0.0x7g/", "protocol": "http:", "username": "", "password": "", "host": "0x7f.0.0.0x7g", "hostname": "0x7f.0.0.0x7g", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://0X7F.0.0.0X7G", "base": null, "href": "http://0x7f.0.0.0x7g/", "protocol": "http:", "username": "", "password": "", "host": "0x7f.0.0.0x7g", "hostname": "0x7f.0.0.0x7g", "port": "", "pathname": "/", "search": "", "hash": "" }, "Invalid IPv4 portion of IPv6 address", { "input": "http://[::127.0.0.0.1]", "base": null, "failure": true }, "Uncompressed IPv6 addresses with 0", { "input": "http://[0:1:0:1:0:1:0:1]", "base": null, "href": "http://[0:1:0:1:0:1:0:1]/", "protocol": "http:", "username": "", "password": "", "host": "[0:1:0:1:0:1:0:1]", "hostname": "[0:1:0:1:0:1:0:1]", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "http://[1:0:1:0:1:0:1:0]", "base": null, "href": "http://[1:0:1:0:1:0:1:0]/", "protocol": "http:", "username": "", "password": "", "host": "[1:0:1:0:1:0:1:0]", "hostname": "[1:0:1:0:1:0:1:0]", "port": "", "pathname": "/", "search": "", "hash": "" }, "Percent-encoded query and fragment", { "input": "http://example.org/test?\u0022", "base": null, "href": "http://example.org/test?%22", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/test", "search": "?%22", "hash": "" }, { "input": "http://example.org/test?\u0023", "base": null, "href": "http://example.org/test?#", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/test", "search": "", "hash": "" }, { "input": "http://example.org/test?\u003C", "base": null, "href": "http://example.org/test?%3C", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/test", "search": "?%3C", "hash": "" }, { "input": "http://example.org/test?\u003E", "base": null, "href": "http://example.org/test?%3E", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/test", "search": "?%3E", "hash": "" }, { "input": "http://example.org/test?\u2323", "base": null, "href": "http://example.org/test?%E2%8C%A3", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/test", "search": "?%E2%8C%A3", "hash": "" }, { "input": "http://example.org/test?%23%23", "base": null, "href": "http://example.org/test?%23%23", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/test", "search": "?%23%23", "hash": "" }, { "input": "http://example.org/test?%GH", "base": null, "href": "http://example.org/test?%GH", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/test", "search": "?%GH", "hash": "" }, { "input": "http://example.org/test?a#%EF", "base": null, "href": "http://example.org/test?a#%EF", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/test", "search": "?a", "hash": "#%EF" }, { "input": "http://example.org/test?a#%GH", "base": null, "href": "http://example.org/test?a#%GH", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/test", "search": "?a", "hash": "#%GH" }, "URLs that require a non-about:blank base. (Also serve as invalid base tests.)", { "input": "a", "base": null, "failure": true, "relativeTo": "non-opaque-path-base" }, { "input": "a/", "base": null, "failure": true, "relativeTo": "non-opaque-path-base" }, { "input": "a//", "base": null, "failure": true, "relativeTo": "non-opaque-path-base" }, "Bases that don't fail to parse but fail to be bases", { "input": "test-a-colon.html", "base": "a:", "failure": true }, { "input": "test-a-colon-b.html", "base": "a:b", "failure": true }, "Other base URL tests, that must succeed", { "input": "test-a-colon-slash.html", "base": "a:/", "href": "a:/test-a-colon-slash.html", "protocol": "a:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/test-a-colon-slash.html", "search": "", "hash": "" }, { "input": "test-a-colon-slash-slash.html", "base": "a://", "href": "a:///test-a-colon-slash-slash.html", "protocol": "a:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/test-a-colon-slash-slash.html", "search": "", "hash": "" }, { "input": "test-a-colon-slash-b.html", "base": "a:/b", "href": "a:/test-a-colon-slash-b.html", "protocol": "a:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/test-a-colon-slash-b.html", "search": "", "hash": "" }, { "input": "test-a-colon-slash-slash-b.html", "base": "a://b", "href": "a://b/test-a-colon-slash-slash-b.html", "protocol": "a:", "username": "", "password": "", "host": "b", "hostname": "b", "port": "", "pathname": "/test-a-colon-slash-slash-b.html", "search": "", "hash": "" }, "Null code point in fragment", { "input": "http://example.org/test?a#b\u0000c", "base": null, "href": "http://example.org/test?a#b%00c", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/test", "search": "?a", "hash": "#b%00c" }, { "input": "non-spec://example.org/test?a#b\u0000c", "base": null, "href": "non-spec://example.org/test?a#b%00c", "protocol": "non-spec:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/test", "search": "?a", "hash": "#b%00c" }, { "input": "non-spec:/test?a#b\u0000c", "base": null, "href": "non-spec:/test?a#b%00c", "protocol": "non-spec:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/test", "search": "?a", "hash": "#b%00c" }, "First scheme char - not allowed: https://github.com/whatwg/url/issues/464", { "input": "10.0.0.7:8080/foo.html", "base": "file:///some/dir/bar.html", "href": "file:///some/dir/10.0.0.7:8080/foo.html", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/some/dir/10.0.0.7:8080/foo.html", "search": "", "hash": "" }, "Subsequent scheme chars - not allowed", { "input": "a!@$*=/foo.html", "base": "file:///some/dir/bar.html", "href": "file:///some/dir/a!@$*=/foo.html", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/some/dir/a!@$*=/foo.html", "search": "", "hash": "" }, "First and subsequent scheme chars - allowed", { "input": "a1234567890-+.:foo/bar", "base": "http://example.com/dir/file", "href": "a1234567890-+.:foo/bar", "protocol": "a1234567890-+.:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "foo/bar", "search": "", "hash": "" }, "IDNA ignored code points in file URLs hosts", { "input": "file://a\u00ADb/p", "base": null, "href": "file://ab/p", "protocol": "file:", "username": "", "password": "", "host": "ab", "hostname": "ab", "port": "", "pathname": "/p", "search": "", "hash": "" }, { "input": "file://a%C2%ADb/p", "base": null, "href": "file://ab/p", "protocol": "file:", "username": "", "password": "", "host": "ab", "hostname": "ab", "port": "", "pathname": "/p", "search": "", "hash": "" }, "IDNA hostnames which get mapped to 'localhost'", { "input": "file://loC๐€๐‹๐‡๐จ๐ฌ๐ญ/usr/bin", "base": null, "href": "file:///usr/bin", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/usr/bin", "search": "", "hash": "" }, "Empty host after the domain to ASCII", { "input": "file://\u00ad/p", "base": null, "failure": true }, { "input": "file://%C2%AD/p", "base": null, "failure": true }, { "input": "file://xn--/p", "base": null, "failure": true }, "https://bugzilla.mozilla.org/show_bug.cgi?id=1647058", { "input": "#link", "base": "https://example.org/##link", "href": "https://example.org/#link", "protocol": "https:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/", "search": "", "hash": "#link" }, "UTF-8 percent-encode of C0 control percent-encode set and supersets", { "input": "non-special:cannot-be-a-base-url-\u0000\u0001\u001F\u001E\u007E\u007F\u0080", "base": null, "hash": "", "host": "", "hostname": "", "href": "non-special:cannot-be-a-base-url-%00%01%1F%1E~%7F%C2%80", "origin": "null", "password": "", "pathname": "cannot-be-a-base-url-%00%01%1F%1E~%7F%C2%80", "port": "", "protocol": "non-special:", "search": "", "username": "" }, { "input": "https://www.example.com/path{\u007Fpath.html?query'\u007F=query#fragment<\u007Ffragment", "base": null, "hash": "#fragment%3C%7Ffragment", "host": "www.example.com", "hostname": "www.example.com", "href": "https://www.example.com/path%7B%7Fpath.html?query%27%7F=query#fragment%3C%7Ffragment", "origin": "https://www.example.com", "password": "", "pathname": "/path%7B%7Fpath.html", "port": "", "protocol": "https:", "search": "?query%27%7F=query", "username": "" }, { "input": "https://user:pass[\u007F@foo/bar", "base": "http://example.org", "hash": "", "host": "foo", "hostname": "foo", "href": "https://user:pass%5B%7F@foo/bar", "origin": "https://foo", "password": "pass%5B%7F", "pathname": "/bar", "port": "", "protocol": "https:", "search": "", "username": "user" }, "Tests for the distinct percent-encode sets", { "input": "foo:// !\"$%&'()*+,-.;<=>@[\\]^_`{|}~@host/", "base": null, "hash": "", "host": "host", "hostname": "host", "href": "foo://%20!%22$%&'()*+,-.%3B%3C%3D%3E%40%5B%5C%5D%5E_%60%7B%7C%7D~@host/", "origin": "null", "password": "", "pathname": "/", "port":"", "protocol": "foo:", "search": "", "username": "%20!%22$%&'()*+,-.%3B%3C%3D%3E%40%5B%5C%5D%5E_%60%7B%7C%7D~" }, { "input": "wss:// !\"$%&'()*+,-.;<=>@[]^_`{|}~@host/", "base": null, "hash": "", "host": "host", "hostname": "host", "href": "wss://%20!%22$%&'()*+,-.%3B%3C%3D%3E%40%5B%5D%5E_%60%7B%7C%7D~@host/", "origin": "wss://host", "password": "", "pathname": "/", "port":"", "protocol": "wss:", "search": "", "username": "%20!%22$%&'()*+,-.%3B%3C%3D%3E%40%5B%5D%5E_%60%7B%7C%7D~" }, { "input": "foo://joe: !\"$%&'()*+,-.:;<=>@[\\]^_`{|}~@host/", "base": null, "hash": "", "host": "host", "hostname": "host", "href": "foo://joe:%20!%22$%&'()*+,-.%3A%3B%3C%3D%3E%40%5B%5C%5D%5E_%60%7B%7C%7D~@host/", "origin": "null", "password": "%20!%22$%&'()*+,-.%3A%3B%3C%3D%3E%40%5B%5C%5D%5E_%60%7B%7C%7D~", "pathname": "/", "port":"", "protocol": "foo:", "search": "", "username": "joe" }, { "input": "wss://joe: !\"$%&'()*+,-.:;<=>@[]^_`{|}~@host/", "base": null, "hash": "", "host": "host", "hostname": "host", "href": "wss://joe:%20!%22$%&'()*+,-.%3A%3B%3C%3D%3E%40%5B%5D%5E_%60%7B%7C%7D~@host/", "origin": "wss://host", "password": "%20!%22$%&'()*+,-.%3A%3B%3C%3D%3E%40%5B%5D%5E_%60%7B%7C%7D~", "pathname": "/", "port":"", "protocol": "wss:", "search": "", "username": "joe" }, { "input": "foo://!\"$%&'()*+,-.;=_`{}~/", "base": null, "hash": "", "host": "!\"$%&'()*+,-.;=_`{}~", "hostname": "!\"$%&'()*+,-.;=_`{}~", "href":"foo://!\"$%&'()*+,-.;=_`{}~/", "origin": "null", "password": "", "pathname": "/", "port":"", "protocol": "foo:", "search": "", "username": "" }, { "input": "wss://!\"$&'()*+,-.;=_`{}~/", "base": null, "hash": "", "host": "!\"$&'()*+,-.;=_`{}~", "hostname": "!\"$&'()*+,-.;=_`{}~", "href":"wss://!\"$&'()*+,-.;=_`{}~/", "origin": "wss://!\"$&'()*+,-.;=_`{}~", "password": "", "pathname": "/", "port":"", "protocol": "wss:", "search": "", "username": "" }, { "input": "foo://host/ !\"$%&'()*+,-./:;<=>@[\\]^_`{|}~", "base": null, "hash": "", "host": "host", "hostname": "host", "href": "foo://host/%20!%22$%&'()*+,-./:;%3C=%3E@[\\]^_%60%7B|%7D~", "origin": "null", "password": "", "pathname": "/%20!%22$%&'()*+,-./:;%3C=%3E@[\\]^_%60%7B|%7D~", "port":"", "protocol": "foo:", "search": "", "username": "" }, { "input": "wss://host/ !\"$%&'()*+,-./:;<=>@[\\]^_`{|}~", "base": null, "hash": "", "host": "host", "hostname": "host", "href": "wss://host/%20!%22$%&'()*+,-./:;%3C=%3E@[/]^_%60%7B|%7D~", "origin": "wss://host", "password": "", "pathname": "/%20!%22$%&'()*+,-./:;%3C=%3E@[/]^_%60%7B|%7D~", "port":"", "protocol": "wss:", "search": "", "username": "" }, { "input": "foo://host/dir/? !\"$%&'()*+,-./:;<=>?@[\\]^_`{|}~", "base": null, "hash": "", "host": "host", "hostname": "host", "href": "foo://host/dir/?%20!%22$%&'()*+,-./:;%3C=%3E?@[\\]^_`{|}~", "origin": "null", "password": "", "pathname": "/dir/", "port":"", "protocol": "foo:", "search": "?%20!%22$%&'()*+,-./:;%3C=%3E?@[\\]^_`{|}~", "username": "" }, { "input": "wss://host/dir/? !\"$%&'()*+,-./:;<=>?@[\\]^_`{|}~", "base": null, "hash": "", "host": "host", "hostname": "host", "href": "wss://host/dir/?%20!%22$%&%27()*+,-./:;%3C=%3E?@[\\]^_`{|}~", "origin": "wss://host", "password": "", "pathname": "/dir/", "port":"", "protocol": "wss:", "search": "?%20!%22$%&%27()*+,-./:;%3C=%3E?@[\\]^_`{|}~", "username": "" }, { "input": "foo://host/dir/# !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", "base": null, "hash": "#%20!%22#$%&'()*+,-./:;%3C=%3E?@[\\]^_%60{|}~", "host": "host", "hostname": "host", "href": "foo://host/dir/#%20!%22#$%&'()*+,-./:;%3C=%3E?@[\\]^_%60{|}~", "origin": "null", "password": "", "pathname": "/dir/", "port":"", "protocol": "foo:", "search": "", "username": "" }, { "input": "wss://host/dir/# !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", "base": null, "hash": "#%20!%22#$%&'()*+,-./:;%3C=%3E?@[\\]^_%60{|}~", "host": "host", "hostname": "host", "href": "wss://host/dir/#%20!%22#$%&'()*+,-./:;%3C=%3E?@[\\]^_%60{|}~", "origin": "wss://host", "password": "", "pathname": "/dir/", "port":"", "protocol": "wss:", "search": "", "username": "" }, "Ensure that input schemes are not ignored when resolving non-special URLs", { "input": "abc:rootless", "base": "abc://host/path", "hash": "", "host": "", "hostname": "", "href":"abc:rootless", "password": "", "pathname": "rootless", "port":"", "protocol": "abc:", "search": "", "username": "" }, { "input": "abc:rootless", "base": "abc:/path", "hash": "", "host": "", "hostname": "", "href":"abc:rootless", "password": "", "pathname": "rootless", "port":"", "protocol": "abc:", "search": "", "username": "" }, { "input": "abc:rootless", "base": "abc:path", "hash": "", "host": "", "hostname": "", "href":"abc:rootless", "password": "", "pathname": "rootless", "port":"", "protocol": "abc:", "search": "", "username": "" }, { "input": "abc:/rooted", "base": "abc://host/path", "hash": "", "host": "", "hostname": "", "href":"abc:/rooted", "password": "", "pathname": "/rooted", "port":"", "protocol": "abc:", "search": "", "username": "" }, "Empty query and fragment with blank should throw an error", { "input": "#", "base": null, "failure": true, "relativeTo": "any-base" }, { "input": "?", "base": null, "failure": true, "relativeTo": "non-opaque-path-base" }, "Last component looks like a number, but not valid IPv4", { "input": "http://1.2.3.4.5", "base": "http://other.com/", "failure": true }, { "input": "http://1.2.3.4.5.", "base": "http://other.com/", "failure": true }, { "input": "http://0..0x300/", "base": null, "failure": true }, { "input": "http://0..0x300./", "base": null, "failure": true }, { "input": "http://256.256.256.256.256", "base": "http://other.com/", "failure": true }, { "input": "http://256.256.256.256.256.", "base": "http://other.com/", "failure": true }, { "input": "http://1.2.3.08", "base": null, "failure": true }, { "input": "http://1.2.3.08.", "base": null, "failure": true }, { "input": "http://1.2.3.09", "base": null, "failure": true }, { "input": "http://09.2.3.4", "base": null, "failure": true }, { "input": "http://09.2.3.4.", "base": null, "failure": true }, { "input": "http://01.2.3.4.5", "base": null, "failure": true }, { "input": "http://01.2.3.4.5.", "base": null, "failure": true }, { "input": "http://0x100.2.3.4", "base": null, "failure": true }, { "input": "http://0x100.2.3.4.", "base": null, "failure": true }, { "input": "http://0x1.2.3.4.5", "base": null, "failure": true }, { "input": "http://0x1.2.3.4.5.", "base": null, "failure": true }, { "input": "http://foo.1.2.3.4", "base": null, "failure": true }, { "input": "http://foo.1.2.3.4.", "base": null, "failure": true }, { "input": "http://foo.2.3.4", "base": null, "failure": true }, { "input": "http://foo.2.3.4.", "base": null, "failure": true }, { "input": "http://foo.09", "base": null, "failure": true }, { "input": "http://foo.09.", "base": null, "failure": true }, { "input": "http://foo.0x4", "base": null, "failure": true }, { "input": "http://foo.0x4.", "base": null, "failure": true }, { "input": "http://foo.09..", "base": null, "hash": "", "host": "foo.09..", "hostname": "foo.09..", "href":"http://foo.09../", "password": "", "pathname": "/", "port":"", "protocol": "http:", "search": "", "username": "" }, { "input": "http://0999999999999999999/", "base": null, "failure": true }, { "input": "http://foo.0x", "base": null, "failure": true }, { "input": "http://foo.0XFfFfFfFfFfFfFfFfFfAcE123", "base": null, "failure": true }, { "input": "http://๐Ÿ’ฉ.123/", "base": null, "failure": true }, "U+0000 and U+FFFF in various places", { "input": "https://\u0000y", "base": null, "failure": true }, { "input": "https://x/\u0000y", "base": null, "hash": "", "host": "x", "hostname": "x", "href": "https://x/%00y", "password": "", "pathname": "/%00y", "port": "", "protocol": "https:", "search": "", "username": "" }, { "input": "https://x/?\u0000y", "base": null, "hash": "", "host": "x", "hostname": "x", "href": "https://x/?%00y", "password": "", "pathname": "/", "port": "", "protocol": "https:", "search": "?%00y", "username": "" }, { "input": "https://x/?#\u0000y", "base": null, "hash": "#%00y", "host": "x", "hostname": "x", "href": "https://x/?#%00y", "password": "", "pathname": "/", "port": "", "protocol": "https:", "search": "", "username": "" }, { "input": "https://\uFFFFy", "base": null, "failure": true }, { "input": "https://x/\uFFFFy", "base": null, "hash": "", "host": "x", "hostname": "x", "href": "https://x/%EF%BF%BFy", "password": "", "pathname": "/%EF%BF%BFy", "port": "", "protocol": "https:", "search": "", "username": "" }, { "input": "https://x/?\uFFFFy", "base": null, "hash": "", "host": "x", "hostname": "x", "href": "https://x/?%EF%BF%BFy", "password": "", "pathname": "/", "port": "", "protocol": "https:", "search": "?%EF%BF%BFy", "username": "" }, { "input": "https://x/?#\uFFFFy", "base": null, "hash": "#%EF%BF%BFy", "host": "x", "hostname": "x", "href": "https://x/?#%EF%BF%BFy", "password": "", "pathname": "/", "port": "", "protocol": "https:", "search": "", "username": "" }, { "input": "non-special:\u0000y", "base": null, "hash": "", "host": "", "hostname": "", "href": "non-special:%00y", "password": "", "pathname": "%00y", "port": "", "protocol": "non-special:", "search": "", "username": "" }, { "input": "non-special:x/\u0000y", "base": null, "hash": "", "host": "", "hostname": "", "href": "non-special:x/%00y", "password": "", "pathname": "x/%00y", "port": "", "protocol": "non-special:", "search": "", "username": "" }, { "input": "non-special:x/?\u0000y", "base": null, "hash": "", "host": "", "hostname": "", "href": "non-special:x/?%00y", "password": "", "pathname": "x/", "port": "", "protocol": "non-special:", "search": "?%00y", "username": "" }, { "input": "non-special:x/?#\u0000y", "base": null, "hash": "#%00y", "host": "", "hostname": "", "href": "non-special:x/?#%00y", "password": "", "pathname": "x/", "port": "", "protocol": "non-special:", "search": "", "username": "" }, { "input": "non-special:\uFFFFy", "base": null, "hash": "", "host": "", "hostname": "", "href": "non-special:%EF%BF%BFy", "password": "", "pathname": "%EF%BF%BFy", "port": "", "protocol": "non-special:", "search": "", "username": "" }, { "input": "non-special:x/\uFFFFy", "base": null, "hash": "", "host": "", "hostname": "", "href": "non-special:x/%EF%BF%BFy", "password": "", "pathname": "x/%EF%BF%BFy", "port": "", "protocol": "non-special:", "search": "", "username": "" }, { "input": "non-special:x/?\uFFFFy", "base": null, "hash": "", "host": "", "hostname": "", "href": "non-special:x/?%EF%BF%BFy", "password": "", "pathname": "x/", "port": "", "protocol": "non-special:", "search": "?%EF%BF%BFy", "username": "" }, { "input": "non-special:x/?#\uFFFFy", "base": null, "hash": "#%EF%BF%BFy", "host": "", "hostname": "", "href": "non-special:x/?#%EF%BF%BFy", "password": "", "pathname": "x/", "port": "", "protocol": "non-special:", "search": "", "username": "" }, { "input": "", "base": null, "failure": true, "relativeTo": "non-opaque-path-base" }, { "input": "https://example.com/\"quoted\"", "base": null, "hash": "", "host": "example.com", "hostname": "example.com", "href": "https://example.com/%22quoted%22", "origin": "https://example.com", "password": "", "pathname": "/%22quoted%22", "port": "", "protocol": "https:", "search": "", "username": "" }, { "input": "https://a%C2%ADb/", "base": null, "hash": "", "host": "ab", "hostname": "ab", "href": "https://ab/", "origin": "https://ab", "password": "", "pathname": "/", "port": "", "protocol": "https:", "search": "", "username": "" }, { "comment": "Empty host after domain to ASCII", "input": "https://\u00AD/", "base": null, "failure": true }, { "input": "https://%C2%AD/", "base": null, "failure": true }, { "input": "https://xn--/", "base": null, "failure": true }, "Non-special schemes that some implementations might incorrectly treat as special", { "input": "data://example.com:8080/pathname?search#hash", "base": null, "href": "data://example.com:8080/pathname?search#hash", "origin": "null", "protocol": "data:", "username": "", "password": "", "host": "example.com:8080", "hostname": "example.com", "port": "8080", "pathname": "/pathname", "search": "?search", "hash": "#hash" }, { "input": "data:///test", "base": null, "href": "data:///test", "origin": "null", "protocol": "data:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/test", "search": "", "hash": "" }, { "input": "data://test/a/../b", "base": null, "href": "data://test/b", "origin": "null", "protocol": "data:", "username": "", "password": "", "host": "test", "hostname": "test", "port": "", "pathname": "/b", "search": "", "hash": "" }, { "input": "data://:443", "base": null, "failure": true }, { "input": "data://test:test", "base": null, "failure": true }, { "input": "data://[:1]", "base": null, "failure": true }, { "input": "javascript://example.com:8080/pathname?search#hash", "base": null, "href": "javascript://example.com:8080/pathname?search#hash", "origin": "null", "protocol": "javascript:", "username": "", "password": "", "host": "example.com:8080", "hostname": "example.com", "port": "8080", "pathname": "/pathname", "search": "?search", "hash": "#hash" }, { "input": "javascript:///test", "base": null, "href": "javascript:///test", "origin": "null", "protocol": "javascript:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/test", "search": "", "hash": "" }, { "input": "javascript://test/a/../b", "base": null, "href": "javascript://test/b", "origin": "null", "protocol": "javascript:", "username": "", "password": "", "host": "test", "hostname": "test", "port": "", "pathname": "/b", "search": "", "hash": "" }, { "input": "javascript://:443", "base": null, "failure": true }, { "input": "javascript://test:test", "base": null, "failure": true }, { "input": "javascript://[:1]", "base": null, "failure": true }, { "input": "mailto://example.com:8080/pathname?search#hash", "base": null, "href": "mailto://example.com:8080/pathname?search#hash", "origin": "null", "protocol": "mailto:", "username": "", "password": "", "host": "example.com:8080", "hostname": "example.com", "port": "8080", "pathname": "/pathname", "search": "?search", "hash": "#hash" }, { "input": "mailto:///test", "base": null, "href": "mailto:///test", "origin": "null", "protocol": "mailto:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/test", "search": "", "hash": "" }, { "input": "mailto://test/a/../b", "base": null, "href": "mailto://test/b", "origin": "null", "protocol": "mailto:", "username": "", "password": "", "host": "test", "hostname": "test", "port": "", "pathname": "/b", "search": "", "hash": "" }, { "input": "mailto://:443", "base": null, "failure": true }, { "input": "mailto://test:test", "base": null, "failure": true }, { "input": "mailto://[:1]", "base": null, "failure": true }, { "input": "intent://example.com:8080/pathname?search#hash", "base": null, "href": "intent://example.com:8080/pathname?search#hash", "origin": "null", "protocol": "intent:", "username": "", "password": "", "host": "example.com:8080", "hostname": "example.com", "port": "8080", "pathname": "/pathname", "search": "?search", "hash": "#hash" }, { "input": "intent:///test", "base": null, "href": "intent:///test", "origin": "null", "protocol": "intent:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/test", "search": "", "hash": "" }, { "input": "intent://test/a/../b", "base": null, "href": "intent://test/b", "origin": "null", "protocol": "intent:", "username": "", "password": "", "host": "test", "hostname": "test", "port": "", "pathname": "/b", "search": "", "hash": "" }, { "input": "intent://:443", "base": null, "failure": true }, { "input": "intent://test:test", "base": null, "failure": true }, { "input": "intent://[:1]", "base": null, "failure": true }, { "input": "urn://example.com:8080/pathname?search#hash", "base": null, "href": "urn://example.com:8080/pathname?search#hash", "origin": "null", "protocol": "urn:", "username": "", "password": "", "host": "example.com:8080", "hostname": "example.com", "port": "8080", "pathname": "/pathname", "search": "?search", "hash": "#hash" }, { "input": "urn:///test", "base": null, "href": "urn:///test", "origin": "null", "protocol": "urn:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/test", "search": "", "hash": "" }, { "input": "urn://test/a/../b", "base": null, "href": "urn://test/b", "origin": "null", "protocol": "urn:", "username": "", "password": "", "host": "test", "hostname": "test", "port": "", "pathname": "/b", "search": "", "hash": "" }, { "input": "urn://:443", "base": null, "failure": true }, { "input": "urn://test:test", "base": null, "failure": true }, { "input": "urn://[:1]", "base": null, "failure": true }, { "input": "turn://example.com:8080/pathname?search#hash", "base": null, "href": "turn://example.com:8080/pathname?search#hash", "origin": "null", "protocol": "turn:", "username": "", "password": "", "host": "example.com:8080", "hostname": "example.com", "port": "8080", "pathname": "/pathname", "search": "?search", "hash": "#hash" }, { "input": "turn:///test", "base": null, "href": "turn:///test", "origin": "null", "protocol": "turn:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/test", "search": "", "hash": "" }, { "input": "turn://test/a/../b", "base": null, "href": "turn://test/b", "origin": "null", "protocol": "turn:", "username": "", "password": "", "host": "test", "hostname": "test", "port": "", "pathname": "/b", "search": "", "hash": "" }, { "input": "turn://:443", "base": null, "failure": true }, { "input": "turn://test:test", "base": null, "failure": true }, { "input": "turn://[:1]", "base": null, "failure": true }, { "input": "stun://example.com:8080/pathname?search#hash", "base": null, "href": "stun://example.com:8080/pathname?search#hash", "origin": "null", "protocol": "stun:", "username": "", "password": "", "host": "example.com:8080", "hostname": "example.com", "port": "8080", "pathname": "/pathname", "search": "?search", "hash": "#hash" }, { "input": "stun:///test", "base": null, "href": "stun:///test", "origin": "null", "protocol": "stun:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/test", "search": "", "hash": "" }, { "input": "stun://test/a/../b", "base": null, "href": "stun://test/b", "origin": "null", "protocol": "stun:", "username": "", "password": "", "host": "test", "hostname": "test", "port": "", "pathname": "/b", "search": "", "hash": "" }, { "input": "stun://:443", "base": null, "failure": true }, { "input": "stun://test:test", "base": null, "failure": true }, { "input": "stun://[:1]", "base": null, "failure": true }, { "input": "w://x:0", "base": null, "href": "w://x:0", "origin": "null", "protocol": "w:", "username": "", "password": "", "host": "x:0", "hostname": "x", "port": "0", "pathname": "", "search": "", "hash": "" }, { "input": "west://x:0", "base": null, "href": "west://x:0", "origin": "null", "protocol": "west:", "username": "", "password": "", "host": "x:0", "hostname": "x", "port": "0", "pathname": "", "search": "", "hash": "" }, "Scheme relative path starting with multiple slashes", { "input": "///test", "base": "http://example.org/", "href": "http://test/", "protocol": "http:", "username": "", "password": "", "host": "test", "hostname": "test", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "///\\//\\//test", "base": "http://example.org/", "href": "http://test/", "protocol": "http:", "username": "", "password": "", "host": "test", "hostname": "test", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "///example.org/path", "base": "http://example.org/", "href": "http://example.org/path", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/path", "search": "", "hash": "" }, { "input": "///example.org/../path", "base": "http://example.org/", "href": "http://example.org/path", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/path", "search": "", "hash": "" }, { "input": "///example.org/../../", "base": "http://example.org/", "href": "http://example.org/", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "///example.org/../path/../../", "base": "http://example.org/", "href": "http://example.org/", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "///example.org/../path/../../path", "base": "http://example.org/", "href": "http://example.org/path", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/path", "search": "", "hash": "" }, { "input": "/\\/\\//example.org/../path", "base": "http://example.org/", "href": "http://example.org/path", "protocol": "http:", "username": "", "password": "", "host": "example.org", "hostname": "example.org", "port": "", "pathname": "/path", "search": "", "hash": "" }, { "input": "///abcdef/../", "base": "file:///", "href": "file:///", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "/", "search": "", "hash": "" }, { "input": "/\\//\\/a/../", "base": "file:///", "href": "file://////", "protocol": "file:", "username": "", "password": "", "host": "", "hostname": "", "port": "", "pathname": "////", "search": "", "hash": "" }, { "input": "//a/../", "base": "file:///", "href": "file://a/", "protocol": "file:", "username": "", "password": "", "host": "a", "hostname": "a", "port": "", "pathname": "/", "search": "", "hash": "" } ] pydantic-httpx2-6dd59b9/tests/httpx2/test_alias.py000066400000000000000000000065401526547463400223260ustar00rootroot00000000000000from __future__ import annotations import importlib import importlib.util import sys import types from collections.abc import Iterator import pytest import httpcore2 import httpx2 from httpx2._alias import _AliasFinder def _is_aliased(name: str) -> bool: return name.partition(".")[0] in ("httpx", "httpcore") @pytest.fixture(autouse=True) def restore_import_state() -> Iterator[None]: saved_meta_path = list(sys.meta_path) saved_modules = {name: module for name, module in sys.modules.items() if _is_aliased(name)} yield sys.meta_path[:] = saved_meta_path for name in [name for name in sys.modules if _is_aliased(name)]: del sys.modules[name] sys.modules.update(saved_modules) def test_alias_top_level_import() -> None: httpx2.alias_httpx() import httpx assert httpx is httpx2 assert httpx.Client is httpx2.Client def test_alias_submodules_share_modules() -> None: httpx2.alias_httpx() from httpx._exceptions import HTTPError assert HTTPError is httpx2.HTTPError assert sys.modules["httpx._exceptions"] is sys.modules["httpx2._exceptions"] with pytest.raises(HTTPError): raise httpx2.ConnectError("boom") def test_alias_httpcore_top_level_import() -> None: httpx2.alias_httpx() import httpcore assert httpcore is httpcore2 assert httpcore.ConnectionPool is httpcore2.ConnectionPool def test_alias_httpcore_submodules_share_modules() -> None: httpx2.alias_httpx() from httpcore._exceptions import ConnectError assert ConnectError is httpcore2.ConnectError assert sys.modules["httpcore._exceptions"] is sys.modules["httpcore2._exceptions"] def test_alias_finder_handles_top_level_import() -> None: httpx2.alias_httpx() del sys.modules["httpx"] import httpx assert httpx is httpx2 def test_alias_preserves_canonical_spec() -> None: httpx2.alias_httpx() importlib.import_module("httpx._exceptions") spec = sys.modules["httpx2._exceptions"].__spec__ assert spec is not None assert spec.name == "httpx2._exceptions" def test_alias_is_idempotent() -> None: httpx2.alias_httpx() assert sum(isinstance(finder, _AliasFinder) for finder in sys.meta_path) == 2 httpx2.alias_httpx() assert sum(isinstance(finder, _AliasFinder) for finder in sys.meta_path) == 2 def test_alias_raises_if_httpx_already_imported() -> None: sys.modules["httpx"] = types.ModuleType("httpx") with pytest.raises(RuntimeError, match="httpx was already imported"): httpx2.alias_httpx() def test_alias_raises_if_httpcore_already_imported() -> None: sys.modules["httpcore"] = types.ModuleType("httpcore") with pytest.raises(RuntimeError, match="httpcore was already imported"): httpx2.alias_httpx() def test_finder_ignores_other_modules() -> None: assert _AliasFinder("httpx", "httpx2").find_spec("json") is None def test_finder_returns_none_for_missing_submodules() -> None: httpx2.alias_httpx() assert importlib.util.find_spec("httpx._does_not_exist") is None with pytest.raises(ModuleNotFoundError): importlib.import_module("httpx._does_not_exist") def test_finder_locates_unloaded_submodules(monkeypatch: pytest.MonkeyPatch) -> None: httpx2.alias_httpx() monkeypatch.delitem(sys.modules, "httpx2._main", raising=False) assert importlib.util.find_spec("httpx._main") is not None pydantic-httpx2-6dd59b9/tests/httpx2/test_api.py000066400000000000000000000061751526547463400220120ustar00rootroot00000000000000from __future__ import annotations import typing import pytest import httpx2 if typing.TYPE_CHECKING: from conftest import TestServer def test_get(server: TestServer) -> None: response = httpx2.get(server.url) assert response.status_code == 200 assert response.reason_phrase == "OK" assert response.text == "Hello, world!" assert response.http_version == "HTTP/1.1" def test_post(server: TestServer) -> None: response = httpx2.post(server.url, content=b"Hello, world!") assert response.status_code == 200 assert response.reason_phrase == "OK" def test_post_byte_iterator(server: TestServer) -> None: def data() -> typing.Iterator[bytes]: yield b"Hello" yield b", " yield b"world!" response = httpx2.post(server.url, content=data()) assert response.status_code == 200 assert response.reason_phrase == "OK" def test_post_byte_stream(server: TestServer) -> None: class Data(httpx2.SyncByteStream): def __iter__(self) -> typing.Iterator[bytes]: yield b"Hello" yield b", " yield b"world!" response = httpx2.post(server.url, content=Data()) assert response.status_code == 200 assert response.reason_phrase == "OK" def test_options(server: TestServer) -> None: response = httpx2.options(server.url) assert response.status_code == 200 assert response.reason_phrase == "OK" def test_head(server: TestServer) -> None: response = httpx2.head(server.url) assert response.status_code == 200 assert response.reason_phrase == "OK" def test_put(server: TestServer) -> None: response = httpx2.put(server.url, content=b"Hello, world!") assert response.status_code == 200 assert response.reason_phrase == "OK" def test_patch(server: TestServer) -> None: response = httpx2.patch(server.url, content=b"Hello, world!") assert response.status_code == 200 assert response.reason_phrase == "OK" def test_delete(server: TestServer) -> None: response = httpx2.delete(server.url) assert response.status_code == 200 assert response.reason_phrase == "OK" def test_query(server: TestServer) -> None: response = httpx2.query(server.url, content=b"Hello, world!") assert response.status_code == 200 assert response.reason_phrase == "OK" def test_stream(server: TestServer) -> None: with httpx2.stream("GET", server.url) as response: response.read() assert response.status_code == 200 assert response.reason_phrase == "OK" assert response.text == "Hello, world!" assert response.http_version == "HTTP/1.1" def test_get_invalid_url() -> None: with pytest.raises(httpx2.UnsupportedProtocol): httpx2.get("invalid://example.org") # check that httpcore isn't imported until we do a request def test_httpcore_lazy_loading(server: TestServer) -> None: import sys # unload our module if it is already loaded if "httpx2" in sys.modules: del sys.modules["httpx2"] del sys.modules["httpcore2"] import httpx2 assert "httpcore2" not in sys.modules _response = httpx2.get(server.url) assert "httpcore2" in sys.modules pydantic-httpx2-6dd59b9/tests/httpx2/test_asgi.py000066400000000000000000000202701526547463400221540ustar00rootroot00000000000000import json import typing import pytest import httpx2 Message = typing.MutableMapping[str, typing.Any] Receive = typing.Callable[[], typing.Awaitable[Message]] Send = typing.Callable[[typing.MutableMapping[str, typing.Any]], typing.Awaitable[None]] Scope = typing.MutableMapping[str, typing.Any] async def hello_world(scope: Scope, receive: Receive, send: Send) -> None: status = 200 output = b"Hello, World!" headers = [(b"content-type", "text/plain"), (b"content-length", str(len(output)))] await send({"type": "http.response.start", "status": status, "headers": headers}) await send({"type": "http.response.body", "body": output}) async def echo_path(scope: Scope, receive: Receive, send: Send) -> None: status = 200 output = json.dumps({"path": scope["path"]}).encode("utf-8") headers = [(b"content-type", "text/plain"), (b"content-length", str(len(output)))] await send({"type": "http.response.start", "status": status, "headers": headers}) await send({"type": "http.response.body", "body": output}) async def echo_raw_path(scope: Scope, receive: Receive, send: Send) -> None: status = 200 output = json.dumps({"raw_path": scope["raw_path"].decode("ascii")}).encode("utf-8") headers = [(b"content-type", "text/plain"), (b"content-length", str(len(output)))] await send({"type": "http.response.start", "status": status, "headers": headers}) await send({"type": "http.response.body", "body": output}) async def echo_body(scope: Scope, receive: Receive, send: Send) -> None: status = 200 headers = [(b"content-type", "text/plain")] await send({"type": "http.response.start", "status": status, "headers": headers}) more_body = True while more_body: message = await receive() body = message.get("body", b"") more_body = message.get("more_body", False) await send({"type": "http.response.body", "body": body, "more_body": more_body}) async def echo_headers(scope: Scope, receive: Receive, send: Send) -> None: status = 200 output = json.dumps({"headers": [[k.decode(), v.decode()] for k, v in scope["headers"]]}).encode("utf-8") headers = [(b"content-type", "text/plain"), (b"content-length", str(len(output)))] await send({"type": "http.response.start", "status": status, "headers": headers}) await send({"type": "http.response.body", "body": output}) async def raise_exc(scope: Scope, receive: Receive, send: Send) -> None: raise RuntimeError() async def raise_exc_after_response(scope: Scope, receive: Receive, send: Send) -> None: status = 200 output = b"Hello, World!" headers = [(b"content-type", "text/plain"), (b"content-length", str(len(output)))] await send({"type": "http.response.start", "status": status, "headers": headers}) await send({"type": "http.response.body", "body": output}) raise RuntimeError() @pytest.mark.anyio async def test_asgi_transport() -> None: async with httpx2.ASGITransport(app=hello_world) as transport: request = httpx2.Request("GET", "http://www.example.com/") response = await transport.handle_async_request(request) await response.aread() assert response.status_code == 200 assert response.content == b"Hello, World!" @pytest.mark.anyio async def test_asgi_transport_no_body() -> None: async with httpx2.ASGITransport(app=echo_body) as transport: request = httpx2.Request("GET", "http://www.example.com/") response = await transport.handle_async_request(request) await response.aread() assert response.status_code == 200 assert response.content == b"" @pytest.mark.anyio async def test_asgi() -> None: transport = httpx2.ASGITransport(app=hello_world) async with httpx2.AsyncClient(transport=transport) as client: response = await client.get("http://www.example.org/") assert response.status_code == 200 assert response.text == "Hello, World!" @pytest.mark.anyio async def test_asgi_urlencoded_path() -> None: transport = httpx2.ASGITransport(app=echo_path) async with httpx2.AsyncClient(transport=transport) as client: url = httpx2.URL("http://www.example.org/").copy_with(path="/user@example.org") response = await client.get(url) assert response.status_code == 200 assert response.json() == {"path": "/user@example.org"} @pytest.mark.anyio async def test_asgi_raw_path() -> None: transport = httpx2.ASGITransport(app=echo_raw_path) async with httpx2.AsyncClient(transport=transport) as client: url = httpx2.URL("http://www.example.org/").copy_with(path="/user@example.org") response = await client.get(url) assert response.status_code == 200 assert response.json() == {"raw_path": "/user@example.org"} @pytest.mark.anyio async def test_asgi_raw_path_should_not_include_querystring_portion() -> None: """ See https://github.com/encode/httpx/issues/2810 """ transport = httpx2.ASGITransport(app=echo_raw_path) async with httpx2.AsyncClient(transport=transport) as client: url = httpx2.URL("http://www.example.org/path?query") response = await client.get(url) assert response.status_code == 200 assert response.json() == {"raw_path": "/path"} @pytest.mark.anyio async def test_asgi_upload() -> None: transport = httpx2.ASGITransport(app=echo_body) async with httpx2.AsyncClient(transport=transport) as client: response = await client.post("http://www.example.org/", content=b"example") assert response.status_code == 200 assert response.text == "example" @pytest.mark.anyio async def test_asgi_headers() -> None: transport = httpx2.ASGITransport(app=echo_headers) async with httpx2.AsyncClient(transport=transport) as client: response = await client.get("http://www.example.org/") assert response.status_code == 200 assert response.json() == { "headers": [ ["host", "www.example.org"], ["accept", "*/*"], ["accept-encoding", "gzip, deflate, br, zstd"], ["connection", "keep-alive"], ["user-agent", f"python-httpx2/{httpx2.__version__}"], ] } @pytest.mark.anyio async def test_asgi_exc() -> None: transport = httpx2.ASGITransport(app=raise_exc) async with httpx2.AsyncClient(transport=transport) as client: with pytest.raises(RuntimeError): await client.get("http://www.example.org/") @pytest.mark.anyio async def test_asgi_exc_after_response() -> None: transport = httpx2.ASGITransport(app=raise_exc_after_response) async with httpx2.AsyncClient(transport=transport) as client: with pytest.raises(RuntimeError): await client.get("http://www.example.org/") @pytest.mark.anyio async def test_asgi_disconnect_after_response_complete() -> None: disconnect = False async def read_body(scope: Scope, receive: Receive, send: Send) -> None: nonlocal disconnect status = 200 headers = [(b"content-type", "text/plain")] await send({"type": "http.response.start", "status": status, "headers": headers}) more_body = True while more_body: message = await receive() more_body = message.get("more_body", False) await send({"type": "http.response.body", "body": b"", "more_body": False}) # The ASGI spec says of the Disconnect message: # "Sent to the application when a HTTP connection is closed or if receive is # called after a response has been sent." # So if receive() is called again, the disconnect message should be received message = await receive() disconnect = message.get("type") == "http.disconnect" transport = httpx2.ASGITransport(app=read_body) async with httpx2.AsyncClient(transport=transport) as client: response = await client.post("http://www.example.org/", content=b"example") assert response.status_code == 200 assert disconnect @pytest.mark.anyio async def test_asgi_exc_no_raise() -> None: transport = httpx2.ASGITransport(app=raise_exc, raise_app_exceptions=False) async with httpx2.AsyncClient(transport=transport) as client: response = await client.get("http://www.example.org/") assert response.status_code == 500 pydantic-httpx2-6dd59b9/tests/httpx2/test_auth.py000066400000000000000000000323311526547463400221730ustar00rootroot00000000000000""" Unit tests for auth classes. Integration tests also exist in tests/client/test_auth.py """ import hashlib import typing from urllib.request import parse_keqv_list import pytest import httpx2 def test_basic_auth() -> None: auth = httpx2.BasicAuth(username="user", password="pass") request = httpx2.Request("GET", "https://www.example.com") # The initial request should include a basic auth header. flow = auth.sync_auth_flow(request) request = next(flow) assert request.headers["Authorization"].startswith("Basic") # No other requests are made. response = httpx2.Response(content=b"Hello, world!", status_code=200) with pytest.raises(StopIteration): flow.send(response) def test_digest_auth_with_200() -> None: auth = httpx2.DigestAuth(username="user", password="pass") request = httpx2.Request("GET", "https://www.example.com") # The initial request should not include an auth header. flow = auth.sync_auth_flow(request) request = next(flow) assert "Authorization" not in request.headers # If a 200 response is returned, then no other requests are made. response = httpx2.Response(content=b"Hello, world!", status_code=200) with pytest.raises(StopIteration): flow.send(response) def test_digest_auth_with_401() -> None: auth = httpx2.DigestAuth(username="user", password="pass") request = httpx2.Request("GET", "https://www.example.com") # The initial request should not include an auth header. flow = auth.sync_auth_flow(request) request = next(flow) assert "Authorization" not in request.headers # If a 401 response is returned, then a digest auth request is made. headers = {"WWW-Authenticate": 'Digest realm="...", qop="auth", nonce="...", opaque="..."'} response = httpx2.Response(content=b"Auth required", status_code=401, headers=headers, request=request) request = flow.send(response) assert request.headers["Authorization"].startswith("Digest") # No other requests are made. response = httpx2.Response(content=b"Hello, world!", status_code=200) with pytest.raises(StopIteration): flow.send(response) def test_digest_auth_with_401_nonce_counting() -> None: auth = httpx2.DigestAuth(username="user", password="pass") request = httpx2.Request("GET", "https://www.example.com") # The initial request should not include an auth header. flow = auth.sync_auth_flow(request) request = next(flow) assert "Authorization" not in request.headers # If a 401 response is returned, then a digest auth request is made. headers = {"WWW-Authenticate": 'Digest realm="...", qop="auth", nonce="...", opaque="..."'} response = httpx2.Response(content=b"Auth required", status_code=401, headers=headers, request=request) first_request = flow.send(response) assert first_request.headers["Authorization"].startswith("Digest") # Each subsequent request contains the digest header by default... request = httpx2.Request("GET", "https://www.example.com") flow = auth.sync_auth_flow(request) second_request = next(flow) assert second_request.headers["Authorization"].startswith("Digest") # ... and the client nonce count (nc) is increased first_nc = parse_keqv_list(first_request.headers["Authorization"].split(", "))["nc"] second_nc = parse_keqv_list(second_request.headers["Authorization"].split(", "))["nc"] assert int(first_nc, 16) + 1 == int(second_nc, 16) # No other requests are made. response = httpx2.Response(content=b"Hello, world!", status_code=200) with pytest.raises(StopIteration): flow.send(response) def set_cookies(request: httpx2.Request) -> httpx2.Response: headers = { "Set-Cookie": "session=.session_value...", "WWW-Authenticate": 'Digest realm="...", qop="auth", nonce="...", opaque="..."', } if request.url.path == "/auth": return httpx2.Response(content=b"Auth required", status_code=401, headers=headers) else: raise NotImplementedError() # pragma: no cover def test_digest_auth_setting_cookie_in_request() -> None: url = "https://www.example.com/auth" client = httpx2.Client(transport=httpx2.MockTransport(set_cookies)) request = client.build_request("GET", url) auth = httpx2.DigestAuth(username="user", password="pass") flow = auth.sync_auth_flow(request) request = next(flow) assert "Authorization" not in request.headers response = client.get(url) assert len(response.cookies) > 0 assert response.cookies["session"] == ".session_value..." request = flow.send(response) assert request.headers["Authorization"].startswith("Digest") assert request.headers["Cookie"] == "session=.session_value..." # No other requests are made. response = httpx2.Response(content=b"Hello, world!", status_code=200, request=request) with pytest.raises(StopIteration): flow.send(response) def test_digest_auth_rfc_2069() -> None: # Example from https://datatracker.ietf.org/doc/html/rfc2069#section-2.4 # with corrected response from https://www.rfc-editor.org/errata/eid749 auth = httpx2.DigestAuth(username="Mufasa", password="CircleOfLife") request = httpx2.Request("GET", "https://www.example.com/dir/index.html") # The initial request should not include an auth header. flow = auth.sync_auth_flow(request) request = next(flow) assert "Authorization" not in request.headers # If a 401 response is returned, then a digest auth request is made. headers = { "WWW-Authenticate": ( 'Digest realm="testrealm@host.com", ' 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", ' 'opaque="5ccc069c403ebaf9f0171e9517f40e41"' ) } response = httpx2.Response(content=b"Auth required", status_code=401, headers=headers, request=request) request = flow.send(response) assert request.headers["Authorization"].startswith("Digest") assert 'username="Mufasa"' in request.headers["Authorization"] assert 'realm="testrealm@host.com"' in request.headers["Authorization"] assert 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093"' in request.headers["Authorization"] assert 'uri="/dir/index.html"' in request.headers["Authorization"] assert 'opaque="5ccc069c403ebaf9f0171e9517f40e41"' in request.headers["Authorization"] assert 'response="1949323746fe6a43ef61f9606e7febea"' in request.headers["Authorization"] # No other requests are made. response = httpx2.Response(content=b"Hello, world!", status_code=200) with pytest.raises(StopIteration): flow.send(response) def test_digest_auth_rfc_7616_md5(monkeypatch: pytest.MonkeyPatch) -> None: # Example from https://datatracker.ietf.org/doc/html/rfc7616#section-3.9.1 def mock_get_client_nonce(nonce_count: int, nonce: bytes) -> bytes: return b"f2/wE4q74E6zIJEtWaHKaf5wv/H5QzzpXusqGemxURZJ" auth = httpx2.DigestAuth(username="Mufasa", password="Circle of Life") monkeypatch.setattr(auth, "_get_client_nonce", mock_get_client_nonce) request = httpx2.Request("GET", "https://www.example.com/dir/index.html") # The initial request should not include an auth header. flow = auth.sync_auth_flow(request) request = next(flow) assert "Authorization" not in request.headers # If a 401 response is returned, then a digest auth request is made. headers = { "WWW-Authenticate": ( 'Digest realm="http-auth@example.org", ' 'qop="auth, auth-int", ' "algorithm=MD5, " 'nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v", ' 'opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS"' ) } response = httpx2.Response(content=b"Auth required", status_code=401, headers=headers, request=request) request = flow.send(response) assert request.headers["Authorization"].startswith("Digest") assert 'username="Mufasa"' in request.headers["Authorization"] assert 'realm="http-auth@example.org"' in request.headers["Authorization"] assert 'uri="/dir/index.html"' in request.headers["Authorization"] assert "algorithm=MD5" in request.headers["Authorization"] assert 'nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v"' in request.headers["Authorization"] assert "nc=00000001" in request.headers["Authorization"] assert 'cnonce="f2/wE4q74E6zIJEtWaHKaf5wv/H5QzzpXusqGemxURZJ"' in request.headers["Authorization"] assert "qop=auth" in request.headers["Authorization"] assert 'opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS"' in request.headers["Authorization"] assert 'response="8ca523f5e9506fed4657c9700eebdbec"' in request.headers["Authorization"] # No other requests are made. response = httpx2.Response(content=b"Hello, world!", status_code=200) with pytest.raises(StopIteration): flow.send(response) def test_digest_auth_rfc_7616_sha_256(monkeypatch: pytest.MonkeyPatch) -> None: # Example from https://datatracker.ietf.org/doc/html/rfc7616#section-3.9.1 def mock_get_client_nonce(nonce_count: int, nonce: bytes) -> bytes: return b"f2/wE4q74E6zIJEtWaHKaf5wv/H5QzzpXusqGemxURZJ" auth = httpx2.DigestAuth(username="Mufasa", password="Circle of Life") monkeypatch.setattr(auth, "_get_client_nonce", mock_get_client_nonce) request = httpx2.Request("GET", "https://www.example.com/dir/index.html") # The initial request should not include an auth header. flow = auth.sync_auth_flow(request) request = next(flow) assert "Authorization" not in request.headers # If a 401 response is returned, then a digest auth request is made. headers = { "WWW-Authenticate": ( 'Digest realm="http-auth@example.org", ' 'qop="auth, auth-int", ' "algorithm=SHA-256, " 'nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v", ' 'opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS"' ) } response = httpx2.Response(content=b"Auth required", status_code=401, headers=headers, request=request) request = flow.send(response) assert request.headers["Authorization"].startswith("Digest") assert 'username="Mufasa"' in request.headers["Authorization"] assert 'realm="http-auth@example.org"' in request.headers["Authorization"] assert 'uri="/dir/index.html"' in request.headers["Authorization"] assert "algorithm=SHA-256" in request.headers["Authorization"] assert 'nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v"' in request.headers["Authorization"] assert "nc=00000001" in request.headers["Authorization"] assert 'cnonce="f2/wE4q74E6zIJEtWaHKaf5wv/H5QzzpXusqGemxURZJ"' in request.headers["Authorization"] assert "qop=auth" in request.headers["Authorization"] assert 'opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS"' in request.headers["Authorization"] assert ( 'response="753927fa0e85d155564e2e272a28d1802ca10daf4496794697cf8db5856cb6c1"' in request.headers["Authorization"] ) # No other requests are made. response = httpx2.Response(content=b"Hello, world!", status_code=200) with pytest.raises(StopIteration): flow.send(response) def test_digest_auth_empty_realm() -> None: auth = httpx2.DigestAuth(username="user", password="pass") request = httpx2.Request("GET", "https://www.example.com") flow = auth.sync_auth_flow(request) request = next(flow) # Digest realm has been left empty. headers = {"WWW-Authenticate": 'Digest realm=, qop="auth", nonce="...", opaque="..."'} response = httpx2.Response(content=b"Auth required", status_code=401, headers=headers, request=request) request = flow.send(response) assert request.headers["Authorization"].startswith('Digest username="user", realm="", nonce="..."') def test_digest_auth_unsupported_algorithm() -> None: auth = httpx2.DigestAuth(username="user", password="pass") flow = auth.sync_auth_flow(httpx2.Request("GET", "https://www.example.com")) request = next(flow) headers = {"WWW-Authenticate": 'Digest realm="test", algorithm=UNKNOWN, nonce="abc"'} response = httpx2.Response(status_code=401, headers=headers, request=request) with pytest.raises(httpx2.ProtocolError, match="Unsupported digest auth algorithm 'UNKNOWN'"): flow.send(response) def fips_blocked_md5(data: bytes = b"") -> typing.Any: raise ValueError("[digital envelope routines] unsupported") @pytest.mark.parametrize( ["md5", "error", "match"], [ pytest.param(fips_blocked_md5, ValueError, "digital envelope routines", id="blocked"), pytest.param(None, httpx2.ProtocolError, "Unsupported digest auth algorithm 'MD5'", id="removed"), ], ) def test_digest_auth_md5_unavailable( monkeypatch: pytest.MonkeyPatch, md5: typing.Any, error: type[Exception], match: str ) -> None: if md5 is None: monkeypatch.delattr(hashlib, "md5", raising=False) else: monkeypatch.setattr(hashlib, "md5", md5) auth = httpx2.DigestAuth(username="user", password="pass") flow = auth.sync_auth_flow(httpx2.Request("GET", "https://www.example.com")) request = next(flow) headers = {"WWW-Authenticate": 'Digest realm="test", algorithm=MD5, nonce="abc"'} response = httpx2.Response(status_code=401, headers=headers, request=request) with pytest.raises(error, match=match): flow.send(response) pydantic-httpx2-6dd59b9/tests/httpx2/test_config.py000066400000000000000000000145241526547463400225030ustar00rootroot00000000000000from __future__ import annotations import platform import ssl import typing from pathlib import Path import pytest import trustme import httpx2 if typing.TYPE_CHECKING: from conftest import TestServer def test_load_ssl_config() -> None: context = httpx2.create_ssl_context() assert context.verify_mode == ssl.VerifyMode.CERT_REQUIRED assert context.check_hostname is True def test_load_ssl_config_verify_non_existing_file() -> None: with pytest.raises(IOError): context = httpx2.create_ssl_context() context.load_verify_locations(cafile="/path/to/nowhere") def test_load_ssl_config_cert_and_key(cert_pem_file: str, cert_private_key_file: str) -> None: context = httpx2.create_ssl_context() context.load_cert_chain(cert_pem_file, cert_private_key_file) assert context.verify_mode == ssl.VerifyMode.CERT_REQUIRED assert context.check_hostname is True @pytest.mark.parametrize("password", [b"password", "password"]) def test_load_ssl_config_cert_and_encrypted_key( cert_pem_file: str, cert_encrypted_private_key_file: str, password: bytes | str ) -> None: context = httpx2.create_ssl_context() context.load_cert_chain(cert_pem_file, cert_encrypted_private_key_file, password) assert context.verify_mode == ssl.VerifyMode.CERT_REQUIRED assert context.check_hostname is True def test_load_ssl_config_cert_and_key_invalid_password( cert_pem_file: str, cert_encrypted_private_key_file: str ) -> None: with pytest.raises(ssl.SSLError): context = httpx2.create_ssl_context() context.load_cert_chain(cert_pem_file, cert_encrypted_private_key_file, "password1") def test_load_ssl_config_cert_without_key_raises(cert_pem_file: str) -> None: with pytest.raises(ssl.SSLError): context = httpx2.create_ssl_context() context.load_cert_chain(cert_pem_file) def test_load_ssl_config_no_verify() -> None: context = httpx2.create_ssl_context(verify=False) assert context.verify_mode == ssl.VerifyMode.CERT_NONE assert context.check_hostname is False @pytest.mark.parametrize("trust_env", [True, False]) def test_create_ssl_context_trust_env( trust_env: bool, cert_authority: trustme.CA, tmp_path: Path, monkeypatch: pytest.MonkeyPatch ) -> None: ca_file = tmp_path / "ca.pem" cert_authority.cert_pem.write_to_path(str(ca_file)) monkeypatch.setenv("SSL_CERT_FILE", str(ca_file)) # `truststore`'s Windows and macOS contexts do not implement `get_ca_certs()`. monkeypatch.setattr(platform, "system", lambda: "Linux") context = httpx2.create_ssl_context(trust_env=trust_env) ca_der = ssl.PEM_cert_to_DER_cert(cert_authority.cert_pem.bytes().decode()) assert (ca_der in context.get_ca_certs(binary_form=True)) is trust_env def test_create_ssl_context_verify_str(cert_pem_file: str) -> None: with pytest.warns(DeprecationWarning, match="`verify=` is deprecated"): context = httpx2.create_ssl_context(verify=cert_pem_file) assert context.verify_mode == ssl.VerifyMode.CERT_REQUIRED def test_create_ssl_context_verify_str_with_cert_raises(cert_pem_file: str, cert_private_key_file: str) -> None: with pytest.raises(TypeError, match="cannot be combined with `cert=...`"): httpx2.create_ssl_context(verify=cert_pem_file, cert=(cert_pem_file, cert_private_key_file)) def test_SSLContext_with_get_request(server: TestServer, cert_pem_file: str) -> None: context = httpx2.create_ssl_context() context.load_verify_locations(cert_pem_file) response = httpx2.get(server.url, verify=context) assert response.status_code == 200 def test_limits_repr() -> None: limits = httpx2.Limits(max_connections=100) expected = "Limits(max_connections=100, max_keepalive_connections=None, keepalive_expiry=5.0)" assert repr(limits) == expected def test_limits_eq() -> None: limits = httpx2.Limits(max_connections=100) assert limits == httpx2.Limits(max_connections=100) def test_timeout_eq() -> None: timeout = httpx2.Timeout(timeout=5.0) assert timeout == httpx2.Timeout(timeout=5.0) def test_timeout_all_parameters_set() -> None: timeout = httpx2.Timeout(connect=5.0, read=5.0, write=5.0, pool=5.0) assert timeout == httpx2.Timeout(timeout=5.0) def test_timeout_from_nothing() -> None: timeout = httpx2.Timeout(None) assert timeout.connect is None assert timeout.read is None assert timeout.write is None assert timeout.pool is None def test_timeout_from_none() -> None: timeout = httpx2.Timeout(timeout=None) assert timeout == httpx2.Timeout(None) def test_timeout_from_one_none_value() -> None: timeout = httpx2.Timeout(None, read=None) assert timeout == httpx2.Timeout(None) def test_timeout_from_one_value() -> None: timeout = httpx2.Timeout(None, read=5.0) assert timeout == httpx2.Timeout(timeout=(None, 5.0, None, None)) def test_timeout_from_one_value_and_default() -> None: timeout = httpx2.Timeout(5.0, pool=60.0) assert timeout == httpx2.Timeout(timeout=(5.0, 5.0, 5.0, 60.0)) def test_timeout_missing_default() -> None: with pytest.raises(ValueError): httpx2.Timeout(pool=60.0) def test_timeout_from_tuple() -> None: timeout = httpx2.Timeout(timeout=(5.0, 5.0, 5.0, 5.0)) assert timeout == httpx2.Timeout(timeout=5.0) def test_timeout_from_config_instance() -> None: timeout = httpx2.Timeout(timeout=5.0) assert httpx2.Timeout(timeout) == httpx2.Timeout(timeout=5.0) def test_timeout_repr() -> None: timeout = httpx2.Timeout(timeout=5.0) assert repr(timeout) == "Timeout(timeout=5.0)" timeout = httpx2.Timeout(None, read=5.0) assert repr(timeout) == "Timeout(connect=None, read=5.0, write=None, pool=None)" def test_proxy_from_url() -> None: proxy = httpx2.Proxy("https://example.com") assert str(proxy.url) == "https://example.com" assert proxy.auth is None assert proxy.headers == {} assert repr(proxy) == "Proxy('https://example.com')" def test_proxy_with_auth_from_url() -> None: proxy = httpx2.Proxy("https://username:password@example.com") assert str(proxy.url) == "https://example.com" assert proxy.auth == ("username", "password") assert proxy.headers == {} assert repr(proxy) == "Proxy('https://example.com', auth=('username', '********'))" def test_invalid_proxy_scheme() -> None: with pytest.raises(ValueError): httpx2.Proxy("invalid://example.com") pydantic-httpx2-6dd59b9/tests/httpx2/test_content.py000066400000000000000000000456731526547463400227210ustar00rootroot00000000000000import gzip import io import os import tempfile import typing import pytest import httpx2 method = "POST" url = "https://www.example.com" @pytest.mark.anyio async def test_empty_content() -> None: request = httpx2.Request(method, url) assert isinstance(request.stream, httpx2.SyncByteStream) assert isinstance(request.stream, httpx2.AsyncByteStream) sync_content = b"".join(list(request.stream)) async_content = b"".join([part async for part in request.stream]) assert request.headers == {"Host": "www.example.com", "Content-Length": "0"} assert sync_content == b"" assert async_content == b"" def test_empty_query_content() -> None: request = httpx2.Request("QUERY", url) assert request.headers == {"Host": "www.example.com", "Content-Length": "0"} @pytest.mark.anyio async def test_bytes_content() -> None: request = httpx2.Request(method, url, content=b"Hello, world!") assert isinstance(request.stream, typing.Iterable) assert isinstance(request.stream, typing.AsyncIterable) sync_content = b"".join(list(request.stream)) async_content = b"".join([part async for part in request.stream]) assert request.headers == {"Host": "www.example.com", "Content-Length": "13"} assert sync_content == b"Hello, world!" assert async_content == b"Hello, world!" # Support 'data' for compat with requests. with pytest.warns(DeprecationWarning): request = httpx2.Request(method, url, data=b"Hello, world!") # type: ignore assert isinstance(request.stream, typing.Iterable) assert isinstance(request.stream, typing.AsyncIterable) sync_content = b"".join(list(request.stream)) async_content = b"".join([part async for part in request.stream]) assert request.headers == {"Host": "www.example.com", "Content-Length": "13"} assert sync_content == b"Hello, world!" assert async_content == b"Hello, world!" @pytest.mark.anyio async def test_bytesio_content() -> None: request = httpx2.Request(method, url, content=io.BytesIO(b"Hello, world!")) assert isinstance(request.stream, typing.Iterable) assert not isinstance(request.stream, typing.AsyncIterable) content = b"".join(list(request.stream)) assert request.headers == {"Host": "www.example.com", "Content-Length": "13"} assert content == b"Hello, world!" def test_file_content() -> None: with tempfile.TemporaryFile() as file: file.write(b"0123456789") file.seek(4) request = httpx2.Request(method, url, content=file) assert file.tell() == 4 assert request.headers["Content-Length"] == "6" assert request.read() == b"456789" request = httpx2.Request(method, url, content=file) assert file.tell() == 10 assert request.headers["Content-Length"] == "0" assert request.read() == b"" file.seek(15) request = httpx2.Request(method, url, content=file) assert file.tell() == 15 assert request.headers["Content-Length"] == "0" assert request.read() == b"" def test_gzip_file_content() -> None: content = b"0123456789" * 100 with tempfile.TemporaryFile() as raw: raw.write(gzip.compress(content)) raw.seek(0) with gzip.GzipFile(fileobj=raw, mode="rb") as file: file.read(4) request = httpx2.Request(method, url, content=file) assert file.tell() == 4 assert request.headers["Content-Length"] == str(len(content) - 4) assert request.read() == content[4:] def test_non_seekable_file_content() -> None: read_fd, write_fd = os.pipe() with os.fdopen(read_fd, "rb") as file: with os.fdopen(write_fd, "wb") as writer: writer.write(b"0123456789") request = httpx2.Request(method, url, content=file) assert request.headers["Transfer-Encoding"] == "chunked" assert "Content-Length" not in request.headers assert request.read() == b"0123456789" @pytest.mark.anyio async def test_async_bytesio_content() -> None: class AsyncBytesIO: def __init__(self, content: bytes) -> None: self._idx = 0 self._content = content async def aread(self, chunk_size: int) -> bytes: chunk = self._content[self._idx : self._idx + chunk_size] self._idx = self._idx + chunk_size return chunk async def __aiter__(self) -> typing.AsyncIterator[bytes]: yield self._content # pragma: no cover request = httpx2.Request(method, url, content=AsyncBytesIO(b"Hello, world!")) assert not isinstance(request.stream, typing.Iterable) assert isinstance(request.stream, typing.AsyncIterable) content = b"".join([part async for part in request.stream]) assert request.headers == { "Host": "www.example.com", "Transfer-Encoding": "chunked", } assert content == b"Hello, world!" @pytest.mark.anyio async def test_iterator_content() -> None: def hello_world() -> typing.Iterator[bytes]: yield b"Hello, " yield b"world!" request = httpx2.Request(method, url, content=hello_world()) assert isinstance(request.stream, typing.Iterable) assert not isinstance(request.stream, typing.AsyncIterable) content = b"".join(list(request.stream)) assert request.headers == { "Host": "www.example.com", "Transfer-Encoding": "chunked", } assert content == b"Hello, world!" with pytest.raises(httpx2.StreamConsumed): list(request.stream) # Support 'data' for compat with requests. with pytest.warns(DeprecationWarning): request = httpx2.Request(method, url, data=hello_world()) # type: ignore assert isinstance(request.stream, typing.Iterable) assert not isinstance(request.stream, typing.AsyncIterable) content = b"".join(list(request.stream)) assert request.headers == { "Host": "www.example.com", "Transfer-Encoding": "chunked", } assert content == b"Hello, world!" @pytest.mark.anyio async def test_aiterator_content() -> None: async def hello_world() -> typing.AsyncIterator[bytes]: yield b"Hello, " yield b"world!" request = httpx2.Request(method, url, content=hello_world()) assert not isinstance(request.stream, typing.Iterable) assert isinstance(request.stream, typing.AsyncIterable) content = b"".join([part async for part in request.stream]) assert request.headers == { "Host": "www.example.com", "Transfer-Encoding": "chunked", } assert content == b"Hello, world!" with pytest.raises(httpx2.StreamConsumed): [part async for part in request.stream] # Support 'data' for compat with requests. with pytest.warns(DeprecationWarning): request = httpx2.Request(method, url, data=hello_world()) # type: ignore assert not isinstance(request.stream, typing.Iterable) assert isinstance(request.stream, typing.AsyncIterable) content = b"".join([part async for part in request.stream]) assert request.headers == { "Host": "www.example.com", "Transfer-Encoding": "chunked", } assert content == b"Hello, world!" @pytest.mark.anyio async def test_json_content() -> None: request = httpx2.Request(method, url, json={"Hello": "world!"}) assert isinstance(request.stream, typing.Iterable) assert isinstance(request.stream, typing.AsyncIterable) sync_content = b"".join(list(request.stream)) async_content = b"".join([part async for part in request.stream]) assert request.headers == { "Host": "www.example.com", "Content-Length": "18", "Content-Type": "application/json", } assert sync_content == b'{"Hello":"world!"}' assert async_content == b'{"Hello":"world!"}' @pytest.mark.anyio async def test_urlencoded_content() -> None: request = httpx2.Request(method, url, data={"Hello": "world!"}) assert isinstance(request.stream, typing.Iterable) assert isinstance(request.stream, typing.AsyncIterable) sync_content = b"".join(list(request.stream)) async_content = b"".join([part async for part in request.stream]) assert request.headers == { "Host": "www.example.com", "Content-Length": "14", "Content-Type": "application/x-www-form-urlencoded", } assert sync_content == b"Hello=world%21" assert async_content == b"Hello=world%21" @pytest.mark.anyio async def test_urlencoded_boolean() -> None: request = httpx2.Request(method, url, data={"example": True}) assert isinstance(request.stream, typing.Iterable) assert isinstance(request.stream, typing.AsyncIterable) sync_content = b"".join(list(request.stream)) async_content = b"".join([part async for part in request.stream]) assert request.headers == { "Host": "www.example.com", "Content-Length": "12", "Content-Type": "application/x-www-form-urlencoded", } assert sync_content == b"example=true" assert async_content == b"example=true" @pytest.mark.anyio async def test_urlencoded_none() -> None: request = httpx2.Request(method, url, data={"example": None}) assert isinstance(request.stream, typing.Iterable) assert isinstance(request.stream, typing.AsyncIterable) sync_content = b"".join(list(request.stream)) async_content = b"".join([part async for part in request.stream]) assert request.headers == { "Host": "www.example.com", "Content-Length": "8", "Content-Type": "application/x-www-form-urlencoded", } assert sync_content == b"example=" assert async_content == b"example=" @pytest.mark.anyio async def test_urlencoded_list() -> None: request = httpx2.Request(method, url, data={"example": ["a", 1, True]}) assert isinstance(request.stream, typing.Iterable) assert isinstance(request.stream, typing.AsyncIterable) sync_content = b"".join(list(request.stream)) async_content = b"".join([part async for part in request.stream]) assert request.headers == { "Host": "www.example.com", "Content-Length": "32", "Content-Type": "application/x-www-form-urlencoded", } assert sync_content == b"example=a&example=1&example=true" assert async_content == b"example=a&example=1&example=true" @pytest.mark.anyio async def test_multipart_files_content() -> None: files = {"file": io.BytesIO(b"")} headers = {"Content-Type": "multipart/form-data; boundary=+++"} request = httpx2.Request( method, url, files=files, headers=headers, ) assert isinstance(request.stream, typing.Iterable) assert isinstance(request.stream, typing.AsyncIterable) sync_content = b"".join(list(request.stream)) async_content = b"".join([part async for part in request.stream]) assert request.headers == { "Host": "www.example.com", "Content-Length": "138", "Content-Type": "multipart/form-data; boundary=+++", } assert sync_content == b"".join( [ b"--+++\r\n", b'Content-Disposition: form-data; name="file"; filename="upload"\r\n', b"Content-Type: application/octet-stream\r\n", b"\r\n", b"\r\n", b"--+++--\r\n", ] ) assert async_content == b"".join( [ b"--+++\r\n", b'Content-Disposition: form-data; name="file"; filename="upload"\r\n', b"Content-Type: application/octet-stream\r\n", b"\r\n", b"\r\n", b"--+++--\r\n", ] ) @pytest.mark.anyio async def test_multipart_data_and_files_content() -> None: data = {"message": "Hello, world!"} files = {"file": io.BytesIO(b"")} headers = {"Content-Type": "multipart/form-data; boundary=+++"} request = httpx2.Request(method, url, data=data, files=files, headers=headers) assert isinstance(request.stream, typing.Iterable) assert isinstance(request.stream, typing.AsyncIterable) sync_content = b"".join(list(request.stream)) async_content = b"".join([part async for part in request.stream]) assert request.headers == { "Host": "www.example.com", "Content-Length": "210", "Content-Type": "multipart/form-data; boundary=+++", } assert sync_content == b"".join( [ b"--+++\r\n", b'Content-Disposition: form-data; name="message"\r\n', b"\r\n", b"Hello, world!\r\n", b"--+++\r\n", b'Content-Disposition: form-data; name="file"; filename="upload"\r\n', b"Content-Type: application/octet-stream\r\n", b"\r\n", b"\r\n", b"--+++--\r\n", ] ) assert async_content == b"".join( [ b"--+++\r\n", b'Content-Disposition: form-data; name="message"\r\n', b"\r\n", b"Hello, world!\r\n", b"--+++\r\n", b'Content-Disposition: form-data; name="file"; filename="upload"\r\n', b"Content-Type: application/octet-stream\r\n", b"\r\n", b"\r\n", b"--+++--\r\n", ] ) @pytest.mark.anyio async def test_empty_request() -> None: request = httpx2.Request(method, url, data={}, files={}) assert isinstance(request.stream, typing.Iterable) assert isinstance(request.stream, typing.AsyncIterable) sync_content = b"".join(list(request.stream)) async_content = b"".join([part async for part in request.stream]) assert request.headers == {"Host": "www.example.com", "Content-Length": "0"} assert sync_content == b"" assert async_content == b"" def test_invalid_argument() -> None: with pytest.raises(TypeError): httpx2.Request(method, url, content=123) # type: ignore with pytest.raises(TypeError): httpx2.Request(method, url, content={"a": "b"}) # type: ignore @pytest.mark.anyio async def test_multipart_multiple_files_single_input_content() -> None: files = [ ("file", io.BytesIO(b"")), ("file", io.BytesIO(b"")), ] headers = {"Content-Type": "multipart/form-data; boundary=+++"} request = httpx2.Request(method, url, files=files, headers=headers) assert isinstance(request.stream, typing.Iterable) assert isinstance(request.stream, typing.AsyncIterable) sync_content = b"".join(list(request.stream)) async_content = b"".join([part async for part in request.stream]) assert request.headers == { "Host": "www.example.com", "Content-Length": "271", "Content-Type": "multipart/form-data; boundary=+++", } assert sync_content == b"".join( [ b"--+++\r\n", b'Content-Disposition: form-data; name="file"; filename="upload"\r\n', b"Content-Type: application/octet-stream\r\n", b"\r\n", b"\r\n", b"--+++\r\n", b'Content-Disposition: form-data; name="file"; filename="upload"\r\n', b"Content-Type: application/octet-stream\r\n", b"\r\n", b"\r\n", b"--+++--\r\n", ] ) assert async_content == b"".join( [ b"--+++\r\n", b'Content-Disposition: form-data; name="file"; filename="upload"\r\n', b"Content-Type: application/octet-stream\r\n", b"\r\n", b"\r\n", b"--+++\r\n", b'Content-Disposition: form-data; name="file"; filename="upload"\r\n', b"Content-Type: application/octet-stream\r\n", b"\r\n", b"\r\n", b"--+++--\r\n", ] ) @pytest.mark.anyio async def test_response_empty_content() -> None: response = httpx2.Response(200) assert isinstance(response.stream, typing.Iterable) assert isinstance(response.stream, typing.AsyncIterable) sync_content = b"".join(list(response.stream)) async_content = b"".join([part async for part in response.stream]) assert response.headers == {} assert sync_content == b"" assert async_content == b"" @pytest.mark.anyio async def test_response_bytes_content() -> None: response = httpx2.Response(200, content=b"Hello, world!") assert isinstance(response.stream, typing.Iterable) assert isinstance(response.stream, typing.AsyncIterable) sync_content = b"".join(list(response.stream)) async_content = b"".join([part async for part in response.stream]) assert response.headers == {"Content-Length": "13"} assert sync_content == b"Hello, world!" assert async_content == b"Hello, world!" @pytest.mark.anyio async def test_response_iterator_content() -> None: def hello_world() -> typing.Iterator[bytes]: yield b"Hello, " yield b"world!" response = httpx2.Response(200, content=hello_world()) assert isinstance(response.stream, typing.Iterable) assert not isinstance(response.stream, typing.AsyncIterable) content = b"".join(list(response.stream)) assert response.headers == {"Transfer-Encoding": "chunked"} assert content == b"Hello, world!" with pytest.raises(httpx2.StreamConsumed): list(response.stream) @pytest.mark.anyio async def test_response_aiterator_content() -> None: async def hello_world() -> typing.AsyncIterator[bytes]: yield b"Hello, " yield b"world!" response = httpx2.Response(200, content=hello_world()) assert not isinstance(response.stream, typing.Iterable) assert isinstance(response.stream, typing.AsyncIterable) content = b"".join([part async for part in response.stream]) assert response.headers == {"Transfer-Encoding": "chunked"} assert content == b"Hello, world!" with pytest.raises(httpx2.StreamConsumed): [part async for part in response.stream] def test_response_invalid_argument() -> None: with pytest.raises(TypeError): httpx2.Response(200, content=123) # type: ignore def test_ensure_ascii_false_with_french_characters() -> None: data = {"greeting": "Bonjour, รงa va ?"} response = httpx2.Response(200, json=data) assert "รงa va" in response.text, "ensure_ascii=False should preserve French accented characters" assert response.headers["Content-Type"] == "application/json" def test_separators_for_compact_json() -> None: data = {"clรฉ": "valeur", "liste": [1, 2, 3]} response = httpx2.Response(200, json=data) assert response.text == '{"clรฉ":"valeur","liste":[1,2,3]}', ( "separators=(',', ':') should produce a compact representation" ) assert response.headers["Content-Type"] == "application/json" def test_allow_nan_false() -> None: data_with_nan = {"nombre": float("nan")} data_with_inf = {"nombre": float("inf")} with pytest.raises(ValueError, match="Out of range float values are not JSON compliant"): httpx2.Response(200, json=data_with_nan) with pytest.raises(ValueError, match="Out of range float values are not JSON compliant"): httpx2.Response(200, json=data_with_inf) pydantic-httpx2-6dd59b9/tests/httpx2/test_decoders.py000066400000000000000000000404051526547463400230230ustar00rootroot00000000000000from __future__ import annotations import io import sys import tracemalloc import typing import zlib import brotli import chardet import pytest import httpx2 if sys.version_info >= (3, 14): # pragma: no cover from compression import zstd else: # pragma: no cover from backports import zstd def test_deflate() -> None: """ Deflate encoding may use either 'zlib' or 'deflate' in the wild. https://stackoverflow.com/questions/1838699/how-can-i-decompress-a-gzip-stream-with-zlib#answer-22311297 """ body = b"test 123" compressor = zlib.compressobj(9, zlib.DEFLATED, -zlib.MAX_WBITS) compressed_body = compressor.compress(body) + compressor.flush() headers = [(b"Content-Encoding", b"deflate")] response = httpx2.Response( 200, headers=headers, content=compressed_body, ) assert response.content == body def test_zlib() -> None: """ Deflate encoding may use either 'zlib' or 'deflate' in the wild. https://stackoverflow.com/questions/1838699/how-can-i-decompress-a-gzip-stream-with-zlib#answer-22311297 """ body = b"test 123" compressed_body = zlib.compress(body) headers = [(b"Content-Encoding", b"deflate")] response = httpx2.Response( 200, headers=headers, content=compressed_body, ) assert response.content == body def test_gzip() -> None: body = b"test 123" compressor = zlib.compressobj(9, zlib.DEFLATED, zlib.MAX_WBITS | 16) compressed_body = compressor.compress(body) + compressor.flush() headers = [(b"Content-Encoding", b"gzip")] response = httpx2.Response( 200, headers=headers, content=compressed_body, ) assert response.content == body @pytest.mark.parametrize("wbits", (zlib.MAX_WBITS | 16, zlib.MAX_WBITS)) def test_decoding_bounds_peak_memory(wbits: int) -> None: # A small compressed body that inflates to a large output must not be # materialised in a single decode step. Even when the entire compressed # body arrives as one raw chunk, peak memory stays far below the decoded # size because decoding happens in bounded pieces. decoded_size = 64 * 1024 * 1024 compressor = zlib.compressobj(9, zlib.DEFLATED, wbits) compressed = compressor.compress(b"\x00" * decoded_size) + compressor.flush() encoding = b"gzip" if wbits & 16 else b"deflate" def raw() -> typing.Iterator[bytes]: yield compressed # deliver the whole bomb as a single raw chunk response = httpx2.Response(200, headers=[(b"Content-Encoding", encoding)], content=raw()) total = 0 tracemalloc.start() for chunk in response.iter_bytes(): total += len(chunk) _, peak = tracemalloc.get_traced_memory() tracemalloc.stop() assert total == decoded_size assert peak < decoded_size // 8 def test_brotli() -> None: body = b"test 123" compressed_body = b"\x8b\x03\x80test 123\x03" headers = [(b"Content-Encoding", b"br")] response = httpx2.Response( 200, headers=headers, content=compressed_body, ) assert response.content == body @pytest.mark.parametrize(("encoding", "compress"), [(b"br", brotli.compress), (b"zstd", zstd.compress)]) def test_decoding_bounds_output_chunks(encoding: bytes, compress: typing.Callable[[bytes], bytes]) -> None: body = b"\x00" * (2**20 + 1) compressed_body = compress(body) def raw() -> typing.Iterator[bytes]: yield compressed_body response = httpx2.Response(200, headers=[(b"Content-Encoding", encoding)], content=raw()) chunks = list(response.iter_bytes()) assert b"".join(chunks) == body assert max(map(len, chunks)) <= 2**20 def test_zstd() -> None: body = b"test 123" compressed_body = zstd.compress(body) headers = [(b"Content-Encoding", b"zstd")] response = httpx2.Response( 200, headers=headers, content=compressed_body, ) assert response.content == body def test_zstd_decoding_error() -> None: compressed_body = "this_is_not_zstd_compressed_data" headers = [(b"Content-Encoding", b"zstd")] with pytest.raises(httpx2.DecodingError): httpx2.Response( 200, headers=headers, content=compressed_body, ) def test_zstd_empty() -> None: headers = [(b"Content-Encoding", b"zstd")] response = httpx2.Response(200, headers=headers, content=b"") assert response.content == b"" def test_zstd_truncated() -> None: body = b"test 123" compressed_body = zstd.compress(body) headers = [(b"Content-Encoding", b"zstd")] with pytest.raises(httpx2.DecodingError): httpx2.Response( 200, headers=headers, content=compressed_body[1:3], ) def test_zstd_multiframe() -> None: # test inspired by urllib3 test suite data = ( # Zstandard frame zstd.compress(b"foo") # skippable frame (must be ignored) + bytes.fromhex( "50 2A 4D 18" # Magic_Number (little-endian) "07 00 00 00" # Frame_Size (little-endian) "00 00 00 00 00 00 00" # User_Data ) # Zstandard frame + zstd.compress(b"bar") ) compressed_body = io.BytesIO(data) headers = [(b"Content-Encoding", b"zstd")] response = httpx2.Response(200, headers=headers, content=compressed_body) response.read() assert response.content == b"foobar" def test_zstd_streaming_multiple_frames() -> None: body1 = b"test 123 " body2 = b"another frame" # Create two separate complete frames frame1 = zstd.compress(body1) frame2 = zstd.compress(body2) # Create an iterator that yields frames separately def content_iterator() -> typing.Iterator[bytes]: yield frame1 yield frame2 headers = [(b"Content-Encoding", b"zstd")] response = httpx2.Response(200, headers=headers, content=content_iterator()) response.read() assert response.content == body1 + body2 def test_zstd_empty_decode_after_eof() -> None: # An empty `decode(b"")` after a complete frame must not raise EOFError on # stdlib `compression.zstd`. This path is reached via `MultiDecoder.flush()`, # which feeds b"" through each child to drain residue across stacked encodings. body = b"test 123" compressed_body = zstd.compress(body) headers = [(b"Content-Encoding", b"zstd, identity")] response = httpx2.Response(200, headers=headers, content=compressed_body) assert response.content == body def test_multi() -> None: body = b"test 123" deflate_compressor = zlib.compressobj(9, zlib.DEFLATED, -zlib.MAX_WBITS) compressed_body = deflate_compressor.compress(body) + deflate_compressor.flush() gzip_compressor = zlib.compressobj(9, zlib.DEFLATED, zlib.MAX_WBITS | 16) compressed_body = gzip_compressor.compress(compressed_body) + gzip_compressor.flush() headers = [(b"Content-Encoding", b"deflate, gzip")] response = httpx2.Response( 200, headers=headers, content=compressed_body, ) assert response.content == body def test_multi_with_identity() -> None: body = b"test 123" compressed_body = b"\x8b\x03\x80test 123\x03" headers = [(b"Content-Encoding", b"br, identity")] response = httpx2.Response( 200, headers=headers, content=compressed_body, ) assert response.content == body headers = [(b"Content-Encoding", b"identity, br")] response = httpx2.Response( 200, headers=headers, content=compressed_body, ) assert response.content == body def test_multi_brotli_zstd() -> None: body = b"test 123" compressed_body = zstd.compress(b"\x8b\x03\x80test 123\x03") headers = [(b"Content-Encoding", b"br, zstd")] response = httpx2.Response(200, headers=headers, content=compressed_body) assert response.content == body def test_multi_zstd_gzip() -> None: # A gzip layer ahead of zstd means gzip's end-of-stream flush feeds b"" into # the zstd decoder after its frame is complete; it must not raise. body = b"test 123" inner = zstd.compress(body) compressor = zlib.compressobj(9, zlib.DEFLATED, zlib.MAX_WBITS | 16) compressed_body = compressor.compress(inner) + compressor.flush() headers = [(b"Content-Encoding", b"zstd, gzip")] response = httpx2.Response(200, headers=headers, content=compressed_body) assert response.content == body def test_multi_brotli_gzip() -> None: body = b"test 123" inner = b"\x8b\x03\x80test 123\x03" compressor = zlib.compressobj(9, zlib.DEFLATED, zlib.MAX_WBITS | 16) compressed_body = compressor.compress(inner) + compressor.flush() headers = [(b"Content-Encoding", b"br, gzip")] response = httpx2.Response(200, headers=headers, content=compressed_body) assert response.content == body def test_multi_decode_links_limit() -> None: headers = [(b"Content-Encoding", b", ".join([b"gzip"] * 6))] with pytest.raises(httpx2.DecodingError, match="Cannot apply more than 5 content encodings"): httpx2.Response(200, headers=headers, content=b"") def test_multi_decode_links_limit_ignores_identity_and_unsupported() -> None: body = b"test 123" compressed = zlib.compress(body) headers = [(b"Content-Encoding", b"identity, identity, identity, identity, identity, deflate")] response = httpx2.Response(200, headers=headers, content=compressed) assert response.content == body @pytest.mark.anyio async def test_streaming() -> None: body = b"test 123" compressor = zlib.compressobj(9, zlib.DEFLATED, zlib.MAX_WBITS | 16) async def compress(body: bytes) -> typing.AsyncIterator[bytes]: yield compressor.compress(body) yield compressor.flush() headers = [(b"Content-Encoding", b"gzip")] response = httpx2.Response( 200, headers=headers, content=compress(body), ) assert not hasattr(response, "body") assert await response.aread() == body @pytest.mark.parametrize("header_value", (b"deflate", b"gzip", b"br", b"identity")) def test_empty_content(header_value: bytes) -> None: headers = [(b"Content-Encoding", header_value)] response = httpx2.Response( 200, headers=headers, content=b"", ) assert response.content == b"" @pytest.mark.parametrize("header_value", (b"deflate", b"gzip", b"br", b"identity")) def test_decoders_empty_cases(header_value: bytes) -> None: headers = [(b"Content-Encoding", header_value)] response = httpx2.Response(content=b"", status_code=200, headers=headers) assert response.read() == b"" @pytest.mark.parametrize("header_value", (b"deflate", b"gzip", b"br")) def test_decoding_errors(header_value: bytes) -> None: headers = [(b"Content-Encoding", header_value)] compressed_body = b"invalid" with pytest.raises(httpx2.DecodingError): request = httpx2.Request("GET", "https://example.org") httpx2.Response(200, headers=headers, content=compressed_body, request=request) with pytest.raises(httpx2.DecodingError): httpx2.Response(200, headers=headers, content=compressed_body) @pytest.mark.parametrize( ["data", "encoding"], [ ((b"Hello,", b" world!"), "ascii"), ((b"\xe3\x83", b"\x88\xe3\x83\xa9", b"\xe3", b"\x83\x99\xe3\x83\xab"), "utf-8"), (("Lโ€™รฉtรฉ ร  Paris coรปte 20 โ‚ฌ โ€” cโ€™est dรฉjร  cher pour une journรฉe entiรจre.".encode("cp1252"), b""), "cp1252"), ((b"Accented: \xd6sterreich abcdefghijklmnopqrstuvwxyz", b""), "iso-8859-1"), ], ) @pytest.mark.anyio async def test_text_decoder_with_autodetect(data: tuple[bytes, ...], encoding: str) -> None: async def iterator() -> typing.AsyncIterator[bytes]: nonlocal data for chunk in data: yield chunk def autodetect(content: bytes) -> str | None: return chardet.detect(content).get("encoding") # Accessing `.text` on a read response. response = httpx2.Response(200, content=iterator(), default_encoding=autodetect) await response.aread() assert response.text == (b"".join(data)).decode(encoding) # Streaming `.aiter_text` iteratively. # Note that if we streamed the text *without* having read it first, then # we won't get a `charset_normalizer` guess, and will instead always rely # on utf-8 if no charset is specified. text = "".join([part async for part in response.aiter_text()]) assert text == (b"".join(data)).decode(encoding) @pytest.mark.anyio async def test_text_decoder_known_encoding() -> None: async def iterator() -> typing.AsyncIterator[bytes]: yield b"\x83g" yield b"\x83" yield b"\x89\x83x\x83\x8b" response = httpx2.Response( 200, headers=[(b"Content-Type", b"text/html; charset=shift-jis")], content=iterator(), ) await response.aread() assert "".join(response.text) == "ใƒˆใƒฉใƒ™ใƒซ" def test_text_decoder_empty_cases() -> None: response = httpx2.Response(200, content=b"") assert response.text == "" response = httpx2.Response(200, content=[b""]) response.read() assert response.text == "" @pytest.mark.parametrize( ["data", "expected"], [((b"Hello,", b" world!"), ["Hello,", " world!"])], ) def test_streaming_text_decoder(data: typing.Iterable[bytes], expected: list[str]) -> None: response = httpx2.Response(200, content=iter(data)) assert list(response.iter_text()) == expected def test_line_decoder_nl() -> None: response = httpx2.Response(200, content=[b""]) assert list(response.iter_lines()) == [] response = httpx2.Response(200, content=[b"", b"a\n\nb\nc"]) assert list(response.iter_lines()) == ["a", "", "b", "c"] # Issue #1033 response = httpx2.Response(200, content=[b"", b"12345\n", b"foo ", b"bar ", b"baz\n"]) assert list(response.iter_lines()) == ["12345", "foo bar baz"] def test_line_decoder_cr() -> None: response = httpx2.Response(200, content=[b"", b"a\r\rb\rc"]) assert list(response.iter_lines()) == ["a", "", "b", "c"] response = httpx2.Response(200, content=[b"", b"a\r\rb\rc\r"]) assert list(response.iter_lines()) == ["a", "", "b", "c"] # Issue #1033 response = httpx2.Response(200, content=[b"", b"12345\r", b"foo ", b"bar ", b"baz\r"]) assert list(response.iter_lines()) == ["12345", "foo bar baz"] def test_line_decoder_crnl() -> None: response = httpx2.Response(200, content=[b"", b"a\r\n\r\nb\r\nc"]) assert list(response.iter_lines()) == ["a", "", "b", "c"] response = httpx2.Response(200, content=[b"", b"a\r\n\r\nb\r\nc\r\n"]) assert list(response.iter_lines()) == ["a", "", "b", "c"] response = httpx2.Response(200, content=[b"", b"a\r", b"\n\r\nb\r\nc"]) assert list(response.iter_lines()) == ["a", "", "b", "c"] # Issue #1033 response = httpx2.Response(200, content=[b"", b"12345\r\n", b"foo bar baz\r\n"]) assert list(response.iter_lines()) == ["12345", "foo bar baz"] def test_invalid_content_encoding_header() -> None: headers = [(b"Content-Encoding", b"invalid-header")] body = b"test 123" response = httpx2.Response( 200, headers=headers, content=body, ) assert response.content == body def test_streaming_decode_error_closes_response() -> None: response: httpx2.Response | None = None def handler(request: httpx2.Request) -> httpx2.Response: nonlocal response response = httpx2.Response(200, headers={"Content-Encoding": "gzip"}, content=iter([b"invalid"])) return response with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with pytest.raises(httpx2.DecodingError): client.get("https://example.org") assert response is not None assert response.is_closed @pytest.mark.anyio async def test_async_streaming_decode_error_closes_response() -> None: response: httpx2.Response | None = None async def content() -> typing.AsyncIterator[bytes]: yield b"invalid" async def handler(request: httpx2.Request) -> httpx2.Response: nonlocal response response = httpx2.Response(200, headers={"Content-Encoding": "gzip"}, content=content()) return response async with httpx2.AsyncClient(transport=httpx2.MockTransport(handler)) as client: with pytest.raises(httpx2.DecodingError): await client.get("https://example.org") assert response is not None assert response.is_closed pydantic-httpx2-6dd59b9/tests/httpx2/test_exceptions.py000066400000000000000000000062541526547463400234200ustar00rootroot00000000000000from __future__ import annotations import socket import ssl import threading import typing import pytest import trustme import httpcore2 import httpx2 if typing.TYPE_CHECKING: from conftest import TestServer def test_httpcore_all_exceptions_mapped() -> None: """ All exception classes exposed by HTTPCore are properly mapped to an HTTPX-specific exception class. """ expected_mapped_httpcore_exceptions = { value.__name__ for _, value in vars(httpcore2).items() if isinstance(value, type) and issubclass(value, Exception) and value is not httpcore2.ConnectionNotAvailable } httpx_exceptions = { value.__name__ for _, value in vars(httpx2).items() if isinstance(value, type) and issubclass(value, Exception) } unmapped_exceptions = expected_mapped_httpcore_exceptions - httpx_exceptions if unmapped_exceptions: # pragma: no cover pytest.fail(f"Unmapped httpcore exceptions: {unmapped_exceptions}") def test_httpcore_exception_mapping(server: TestServer) -> None: """ HTTPCore exception mapping works as expected. """ impossible_port = 123456 with pytest.raises(httpx2.ConnectError): httpx2.get(server.url.copy_with(port=impossible_port)) with pytest.raises(httpx2.ReadTimeout): httpx2.get( server.url.copy_with(path="/slow_response"), timeout=httpx2.Timeout(5, read=0.01), ) def test_request_attribute() -> None: # Exception without request attribute exc = httpx2.ReadTimeout("Read operation timed out") with pytest.raises(RuntimeError): exc.request # noqa: B018 # Exception with request attribute request = httpx2.Request("GET", "https://www.example.com") exc = httpx2.ReadTimeout("Read operation timed out", request=request) assert exc.request == request @pytest.fixture def ragged_eof_tls_server(cert_authority: trustme.CA) -> typing.Iterator[int]: server_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) cert_authority.issue_cert("localhost").configure_cert(server_context) def serve() -> None: raw, _ = listener.accept() with server_context.wrap_socket(raw, server_side=True) as conn: # Ends the TCP stream without sending a TLS `close_notify`. conn.shutdown(socket.SHUT_WR) while conn.recv(65536): pass # pragma: no cover with socket.create_server(("127.0.0.1", 0)) as listener: thread = threading.Thread(target=serve) thread.start() yield listener.getsockname()[1] thread.join() @pytest.mark.anyio async def test_anyio_write_after_ragged_tls_eof(cert_authority: trustme.CA, ragged_eof_tls_server: int) -> None: client_context = ssl.create_default_context() cert_authority.configure_trust(client_context) stream = await httpcore2.AnyIOBackend().connect_tcp("127.0.0.1", ragged_eof_tls_server) stream = await stream.start_tls(client_context, server_hostname="localhost") try: assert await stream.read(65536) == b"" with pytest.raises(httpcore2.WriteError): await stream.write(b"GET / HTTP/1.1\r\n\r\n") finally: await stream.aclose() pydantic-httpx2-6dd59b9/tests/httpx2/test_exported_members.py000066400000000000000000000011001526547463400245640ustar00rootroot00000000000000import httpx2 def test_all_imports_are_exported() -> None: included_private_members = {"__description__", "__title__", "__version__"} # `httpx2.websockets` is a subpackage, bound on `httpx2` by importing it, rather than a re-export. excluded_members = {"websockets"} public_members = { member for member in vars(httpx2) if (not member.startswith("_") or member in included_private_members) and member not in excluded_members } assert set(httpx2.__all__) == public_members assert len(httpx2.__all__) == len(public_members) pydantic-httpx2-6dd59b9/tests/httpx2/test_main.py000066400000000000000000000140051526547463400221540ustar00rootroot00000000000000from __future__ import annotations import typing import pytest from click.testing import CliRunner import httpx2 from httpx2._main import main if typing.TYPE_CHECKING: from pathlib import Path from conftest import TestServer def splitlines(output: str) -> typing.Iterable[str]: return [line.strip() for line in output.splitlines()] def remove_date_header(lines: typing.Iterable[str]) -> typing.Iterable[str]: return [line for line in lines if not line.startswith("date:")] def test_help() -> None: runner = CliRunner() result = runner.invoke(main, ["--help"]) assert result.exit_code == 0 assert "A next generation HTTP client." in result.output @pytest.mark.parametrize( ("option", "expected"), [ ([], True), (["--verify"], True), (["--no-verify"], False), ], ) def test_verify_option(option: list[str], expected: bool) -> None: with main.make_context("httpx2", ["https://example.com", *option]) as context: assert context.params["verify"] is expected def test_get(server: TestServer) -> None: url = str(server.url) runner = CliRunner() result = runner.invoke(main, [url]) assert result.exit_code == 0 assert remove_date_header(splitlines(result.output)) == [ "HTTP/1.1 200 OK", "server: uvicorn", "content-type: text/plain", "Transfer-Encoding: chunked", "", "Hello, world!", ] def test_json(server: TestServer) -> None: url = str(server.url.copy_with(path="/json")) runner = CliRunner() result = runner.invoke(main, [url]) assert result.exit_code == 0 assert remove_date_header(splitlines(result.output)) == [ "HTTP/1.1 200 OK", "server: uvicorn", "content-type: application/json", "Transfer-Encoding: chunked", "", "{", '"Hello": "world!"', "}", ] def test_binary(server: TestServer) -> None: url = str(server.url.copy_with(path="/echo_binary")) runner = CliRunner() content = "Hello, world!" result = runner.invoke(main, [url, "-c", content]) assert result.exit_code == 0 assert remove_date_header(splitlines(result.output)) == [ "HTTP/1.1 200 OK", "server: uvicorn", "content-type: application/octet-stream", "Transfer-Encoding: chunked", "", f"<{len(content)} bytes of binary data>", ] def test_redirects(server: TestServer) -> None: url = str(server.url.copy_with(path="/redirect_301")) runner = CliRunner() result = runner.invoke(main, [url]) assert result.exit_code == 1 assert remove_date_header(splitlines(result.output)) == [ "HTTP/1.1 301 Moved Permanently", "server: uvicorn", "location: /", "Transfer-Encoding: chunked", "", ] def test_follow_redirects(server: TestServer) -> None: url = str(server.url.copy_with(path="/redirect_301")) runner = CliRunner() result = runner.invoke(main, [url, "--follow-redirects"]) assert result.exit_code == 0 assert remove_date_header(splitlines(result.output)) == [ "HTTP/1.1 301 Moved Permanently", "server: uvicorn", "location: /", "Transfer-Encoding: chunked", "", "HTTP/1.1 200 OK", "server: uvicorn", "content-type: text/plain", "Transfer-Encoding: chunked", "", "Hello, world!", ] def test_post(server: TestServer) -> None: url = str(server.url.copy_with(path="/echo_body")) runner = CliRunner() result = runner.invoke(main, [url, "-m", "POST", "-j", '{"hello": "world"}']) assert result.exit_code == 0 assert remove_date_header(splitlines(result.output)) == [ "HTTP/1.1 200 OK", "server: uvicorn", "content-type: text/plain", "Transfer-Encoding: chunked", "", '{"hello":"world"}', ] def test_verbose(server: TestServer) -> None: url = str(server.url) runner = CliRunner() result = runner.invoke(main, [url, "-v"]) assert result.exit_code == 0 assert remove_date_header(splitlines(result.output)) == [ "* Connecting to '127.0.0.1'", f"* Connected to '127.0.0.1' on port {server.url.port}", "GET / HTTP/1.1", f"Host: {server.url.netloc.decode('ascii')}", "Accept: */*", "Accept-Encoding: gzip, deflate, br, zstd", "Connection: keep-alive", f"User-Agent: python-httpx2/{httpx2.__version__}", "", "HTTP/1.1 200 OK", "server: uvicorn", "content-type: text/plain", "Transfer-Encoding: chunked", "", "Hello, world!", ] def test_auth(server: TestServer) -> None: url = str(server.url) runner = CliRunner() result = runner.invoke(main, [url, "-v", "--auth", "username", "password"]) print(result.output) assert result.exit_code == 0 assert remove_date_header(splitlines(result.output)) == [ "* Connecting to '127.0.0.1'", f"* Connected to '127.0.0.1' on port {server.url.port}", "GET / HTTP/1.1", f"Host: {server.url.netloc.decode('ascii')}", "Accept: */*", "Accept-Encoding: gzip, deflate, br, zstd", "Connection: keep-alive", f"User-Agent: python-httpx2/{httpx2.__version__}", "Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=", "", "HTTP/1.1 200 OK", "server: uvicorn", "content-type: text/plain", "Transfer-Encoding: chunked", "", "Hello, world!", ] def test_download(server: TestServer, tmp_path: Path) -> None: url = str(server.url) output_path = tmp_path / "index.txt" runner = CliRunner() runner.invoke(main, [url, "--download", str(output_path)]) assert output_path.read_text() == "Hello, world!" def test_errors() -> None: runner = CliRunner() result = runner.invoke(main, ["invalid://example.org"]) assert result.exit_code == 1 assert splitlines(result.output) == [ "UnsupportedProtocol: Request URL has an unsupported protocol 'invalid://'.", ] pydantic-httpx2-6dd59b9/tests/httpx2/test_multipart.py000066400000000000000000000436161526547463400232630ustar00rootroot00000000000000from __future__ import annotations import io import tempfile import typing import pytest import httpx2 def echo_request_content(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, content=request.content) @pytest.mark.parametrize(("value,output"), (("abc", b"abc"), (b"abc", b"abc"))) def test_multipart(value: str | bytes, output: bytes) -> None: client = httpx2.Client(transport=httpx2.MockTransport(echo_request_content)) # Test with a single-value 'data' argument, and a plain file 'files' argument. data = {"text": value} files = {"file": io.BytesIO(b"")} response = client.post("http://127.0.0.1:8000/", data=data, files=files) boundary = response.request.headers["Content-Type"].split("boundary=")[-1] boundary_bytes = boundary.encode("ascii") assert response.status_code == 200 assert response.content == b"".join( [ b"--" + boundary_bytes + b"\r\n", b'Content-Disposition: form-data; name="text"\r\n', b"\r\n", b"abc\r\n", b"--" + boundary_bytes + b"\r\n", b'Content-Disposition: form-data; name="file"; filename="upload"\r\n', b"Content-Type: application/octet-stream\r\n", b"\r\n", b"\r\n", b"--" + boundary_bytes + b"--\r\n", ] ) @pytest.mark.parametrize( "header", [ "multipart/form-data; boundary=+++; charset=utf-8", "multipart/form-data; charset=utf-8; boundary=+++", "multipart/form-data; boundary=+++", "multipart/form-data; boundary=+++ ;", 'multipart/form-data; boundary="+++"; charset=utf-8', 'multipart/form-data; charset=utf-8; boundary="+++"', 'multipart/form-data; boundary="+++"', 'multipart/form-data; boundary="+++" ;', ], ) def test_multipart_explicit_boundary(header: str) -> None: client = httpx2.Client(transport=httpx2.MockTransport(echo_request_content)) files = {"file": io.BytesIO(b"")} headers = {"content-type": header} response = client.post("http://127.0.0.1:8000/", files=files, headers=headers) boundary_bytes = b"+++" assert response.status_code == 200 assert response.request.headers["Content-Type"] == header assert response.content == b"".join( [ b"--" + boundary_bytes + b"\r\n", b'Content-Disposition: form-data; name="file"; filename="upload"\r\n', b"Content-Type: application/octet-stream\r\n", b"\r\n", b"\r\n", b"--" + boundary_bytes + b"--\r\n", ] ) @pytest.mark.parametrize( "header", [ "multipart/form-data; charset=utf-8", "multipart/form-data; charset=utf-8; ", ], ) def test_multipart_header_without_boundary(header: str) -> None: client = httpx2.Client(transport=httpx2.MockTransport(echo_request_content)) files = {"file": io.BytesIO(b"")} headers = {"content-type": header} response = client.post("http://127.0.0.1:8000/", files=files, headers=headers) assert response.status_code == 200 assert response.request.headers["Content-Type"] == header @pytest.mark.parametrize(("key"), (b"abc", 1, 2.3, None)) def test_multipart_invalid_key(key: typing.Any) -> None: client = httpx2.Client(transport=httpx2.MockTransport(echo_request_content)) data = {key: "abc"} files = {"file": io.BytesIO(b"")} with pytest.raises(TypeError) as e: client.post( "http://127.0.0.1:8000/", data=data, files=files, ) assert "Invalid type for name" in str(e.value) assert repr(key) in str(e.value) @pytest.mark.parametrize(("value"), (object(), {"key": "value"})) def test_multipart_invalid_value(value: typing.Any) -> None: client = httpx2.Client(transport=httpx2.MockTransport(echo_request_content)) data = {"text": value} files = {"file": io.BytesIO(b"")} with pytest.raises(TypeError) as e: client.post("http://127.0.0.1:8000/", data=data, files=files) assert "Invalid type for value" in str(e.value) def test_multipart_file_tuple() -> None: client = httpx2.Client(transport=httpx2.MockTransport(echo_request_content)) # Test with a list of values 'data' argument, # and a tuple style 'files' argument. data = {"text": ["abc"]} files = {"file": ("name.txt", io.BytesIO(b""))} response = client.post("http://127.0.0.1:8000/", data=data, files=files) boundary = response.request.headers["Content-Type"].split("boundary=")[-1] boundary_bytes = boundary.encode("ascii") assert response.status_code == 200 assert response.content == b"".join( [ b"--" + boundary_bytes + b"\r\n", b'Content-Disposition: form-data; name="text"\r\n', b"\r\n", b"abc\r\n", b"--" + boundary_bytes + b"\r\n", b'Content-Disposition: form-data; name="file"; filename="name.txt"\r\n', b"Content-Type: text/plain\r\n", b"\r\n", b"\r\n", b"--" + boundary_bytes + b"--\r\n", ] ) @pytest.mark.parametrize("file_content_type", [None, "text/plain"]) def test_multipart_file_tuple_headers(file_content_type: str | None) -> None: file_name = "test.txt" file_content = io.BytesIO(b"") file_headers = {"Expires": "0"} url = "https://www.example.com/" headers = {"Content-Type": "multipart/form-data; boundary=BOUNDARY"} files = {"file": (file_name, file_content, file_content_type, file_headers)} request = httpx2.Request("POST", url, headers=headers, files=files) request.read() assert request.headers == { "Host": "www.example.com", "Content-Type": "multipart/form-data; boundary=BOUNDARY", "Content-Length": str(len(request.content)), } assert request.content == ( f'--BOUNDARY\r\nContent-Disposition: form-data; name="file"; ' f'filename="{file_name}"\r\nExpires: 0\r\nContent-Type: ' f"text/plain\r\n\r\n\r\n--BOUNDARY--\r\n" "".encode("ascii") ) def test_multipart_headers_include_content_type() -> None: """ Content-Type from 4th tuple parameter (headers) should override the 3rd parameter (content_type) """ file_name = "test.txt" file_content = io.BytesIO(b"") file_content_type = "text/plain" file_headers = {"Content-Type": "image/png"} url = "https://www.example.com/" headers = {"Content-Type": "multipart/form-data; boundary=BOUNDARY"} files = {"file": (file_name, file_content, file_content_type, file_headers)} request = httpx2.Request("POST", url, headers=headers, files=files) request.read() assert request.headers == { "Host": "www.example.com", "Content-Type": "multipart/form-data; boundary=BOUNDARY", "Content-Length": str(len(request.content)), } assert request.content == ( f'--BOUNDARY\r\nContent-Disposition: form-data; name="file"; ' f'filename="{file_name}"\r\nContent-Type: ' f"image/png\r\n\r\n\r\n--BOUNDARY--\r\n" "".encode("ascii") ) @pytest.mark.parametrize( ("content_type", "file_headers"), [ ("text/plain\r", {}), (None, {"X-Test\t": "value"}), (None, {"X-Test": "value\n"}), ], ) def test_multipart_rejects_invalid_file_headers(content_type: str | None, file_headers: dict[str, str]) -> None: files = {"file": ("test.txt", b"", content_type, file_headers)} with pytest.raises(ValueError, match="Invalid .*multipart header"): httpx2.Request("POST", "https://www.example.com/", files=files) @pytest.mark.parametrize("control_character", ["\x00", "\x01", "\x08", "\x1f", "\x7f"]) def test_multipart_rejects_control_characters_in_file_header_values(control_character: str) -> None: files = {"file": ("test.txt", b"", None, {"X-Test": f"value{control_character}"})} with pytest.raises(ValueError, match="Invalid control character in multipart header value"): httpx2.Request("POST", "https://www.example.com/", files=files) def test_multipart_encode(tmp_path: typing.Any) -> None: path = str(tmp_path / "name.txt") with open(path, "wb") as f: f.write(b"") url = "https://www.example.com/" headers = {"Content-Type": "multipart/form-data; boundary=BOUNDARY"} data = { "a": "1", "b": b"C", "c": ["11", "22", "33"], "d": "", "e": True, "f": "", } with open(path, "rb") as input_file: files = {"file": ("name.txt", input_file)} request = httpx2.Request("POST", url, headers=headers, data=data, files=files) request.read() assert request.headers == { "Host": "www.example.com", "Content-Type": "multipart/form-data; boundary=BOUNDARY", "Content-Length": str(len(request.content)), } assert request.content == ( '--BOUNDARY\r\nContent-Disposition: form-data; name="a"\r\n\r\n1\r\n' '--BOUNDARY\r\nContent-Disposition: form-data; name="b"\r\n\r\nC\r\n' '--BOUNDARY\r\nContent-Disposition: form-data; name="c"\r\n\r\n11\r\n' '--BOUNDARY\r\nContent-Disposition: form-data; name="c"\r\n\r\n22\r\n' '--BOUNDARY\r\nContent-Disposition: form-data; name="c"\r\n\r\n33\r\n' '--BOUNDARY\r\nContent-Disposition: form-data; name="d"\r\n\r\n\r\n' '--BOUNDARY\r\nContent-Disposition: form-data; name="e"\r\n\r\ntrue\r\n' '--BOUNDARY\r\nContent-Disposition: form-data; name="f"\r\n\r\n\r\n' '--BOUNDARY\r\nContent-Disposition: form-data; name="file";' ' filename="name.txt"\r\n' "Content-Type: text/plain\r\n\r\n\r\n" "--BOUNDARY--\r\n" "".encode("ascii") ) def test_multipart_encode_unicode_file_contents() -> None: url = "https://www.example.com/" headers = {"Content-Type": "multipart/form-data; boundary=BOUNDARY"} files = {"file": ("name.txt", b"")} request = httpx2.Request("POST", url, headers=headers, files=files) request.read() assert request.headers == { "Host": "www.example.com", "Content-Type": "multipart/form-data; boundary=BOUNDARY", "Content-Length": str(len(request.content)), } assert request.content == ( b'--BOUNDARY\r\nContent-Disposition: form-data; name="file";' b' filename="name.txt"\r\n' b"Content-Type: text/plain\r\n\r\n\r\n" b"--BOUNDARY--\r\n" ) def test_multipart_encode_files_allows_filenames_as_none() -> None: url = "https://www.example.com/" headers = {"Content-Type": "multipart/form-data; boundary=BOUNDARY"} files = {"file": (None, io.BytesIO(b""))} request = httpx2.Request("POST", url, headers=headers, data={}, files=files) request.read() assert request.headers == { "Host": "www.example.com", "Content-Type": "multipart/form-data; boundary=BOUNDARY", "Content-Length": str(len(request.content)), } assert request.content == ( '--BOUNDARY\r\nContent-Disposition: form-data; name="file"\r\n\r\n\r\n--BOUNDARY--\r\n'.encode( "ascii" ) ) @pytest.mark.parametrize( "file_name,expected_content_type", [ ("example.json", "application/json"), ("example.txt", "text/plain"), ("no-extension", "application/octet-stream"), ], ) def test_multipart_encode_files_guesses_correct_content_type(file_name: str, expected_content_type: str) -> None: url = "https://www.example.com/" headers = {"Content-Type": "multipart/form-data; boundary=BOUNDARY"} files = {"file": (file_name, io.BytesIO(b""))} request = httpx2.Request("POST", url, headers=headers, data={}, files=files) request.read() assert request.headers == { "Host": "www.example.com", "Content-Type": "multipart/form-data; boundary=BOUNDARY", "Content-Length": str(len(request.content)), } assert request.content == ( f'--BOUNDARY\r\nContent-Disposition: form-data; name="file"; ' f'filename="{file_name}"\r\nContent-Type: ' f"{expected_content_type}\r\n\r\n\r\n--BOUNDARY--\r\n" "".encode("ascii") ) def test_multipart_encode_files_allows_bytes_content() -> None: url = "https://www.example.com/" headers = {"Content-Type": "multipart/form-data; boundary=BOUNDARY"} files = {"file": ("test.txt", b"", "text/plain")} request = httpx2.Request("POST", url, headers=headers, data={}, files=files) request.read() assert request.headers == { "Host": "www.example.com", "Content-Type": "multipart/form-data; boundary=BOUNDARY", "Content-Length": str(len(request.content)), } assert request.content == ( '--BOUNDARY\r\nContent-Disposition: form-data; name="file"; ' 'filename="test.txt"\r\n' "Content-Type: text/plain\r\n\r\n\r\n" "--BOUNDARY--\r\n" "".encode("ascii") ) def test_multipart_encode_files_allows_str_content() -> None: url = "https://www.example.com/" headers = {"Content-Type": "multipart/form-data; boundary=BOUNDARY"} files = {"file": ("test.txt", "", "text/plain")} request = httpx2.Request("POST", url, headers=headers, data={}, files=files) request.read() assert request.headers == { "Host": "www.example.com", "Content-Type": "multipart/form-data; boundary=BOUNDARY", "Content-Length": str(len(request.content)), } assert request.content == ( '--BOUNDARY\r\nContent-Disposition: form-data; name="file"; ' 'filename="test.txt"\r\n' "Content-Type: text/plain\r\n\r\n\r\n" "--BOUNDARY--\r\n" "".encode("ascii") ) def test_multipart_encode_files_raises_exception_with_StringIO_content() -> None: url = "https://www.example.com" files = {"file": ("test.txt", io.StringIO("content"), "text/plain")} with pytest.raises(TypeError): httpx2.Request("POST", url, data={}, files=files) # type: ignore[arg-type] def test_multipart_encode_files_raises_exception_with_text_mode_file() -> None: url = "https://www.example.com" with tempfile.TemporaryFile(mode="w") as upload: files = {"file": ("test.txt", upload, "text/plain")} with pytest.raises(TypeError): httpx2.Request("POST", url, data={}, files=files) # type: ignore[arg-type] def test_multipart_encode_non_seekable_filelike() -> None: """ Test that special readable but non-seekable filelike objects are supported. In this case uploads with use 'Transfer-Encoding: chunked', instead of a 'Content-Length' header. """ class IteratorIO(io.IOBase): def __init__(self, iterator: typing.Iterator[bytes]) -> None: self._iterator = iterator def read(self, *args: typing.Any) -> bytes: return b"".join(self._iterator) def data() -> typing.Iterator[bytes]: yield b"Hello" yield b"World" url = "https://www.example.com/" headers = {"Content-Type": "multipart/form-data; boundary=BOUNDARY"} fileobj: typing.Any = IteratorIO(data()) files = {"file": fileobj} request = httpx2.Request("POST", url, headers=headers, files=files) request.read() assert request.headers == { "Host": "www.example.com", "Content-Type": "multipart/form-data; boundary=BOUNDARY", "Transfer-Encoding": "chunked", } assert request.content == ( b"--BOUNDARY\r\n" b'Content-Disposition: form-data; name="file"; filename="upload"\r\n' b"Content-Type: application/octet-stream\r\n" b"\r\n" b"HelloWorld\r\n" b"--BOUNDARY--\r\n" ) def test_multipart_rewinds_files() -> None: with tempfile.TemporaryFile() as upload: upload.write(b"Hello, world!") transport = httpx2.MockTransport(echo_request_content) client = httpx2.Client(transport=transport) files = {"file": upload} response = client.post("http://127.0.0.1:8000/", files=files) assert response.status_code == 200 assert b"\r\nHello, world!\r\n" in response.content # POSTing the same file instance a second time should have the same content. files = {"file": upload} response = client.post("http://127.0.0.1:8000/", files=files) assert response.status_code == 200 assert int(response.request.headers["Content-Length"]) == len(response.content) assert b"\r\nHello, world!\r\n" in response.content class TestHeaderParamHTML5Formatting: def test_unicode(self) -> None: filename = "n\u00e4me" expected = b'filename="n\xc3\xa4me"' files = {"upload": (filename, b"")} request = httpx2.Request("GET", "https://www.example.com", files=files) assert expected in request.read() def test_ascii(self) -> None: filename = "name" expected = b'filename="name"' files = {"upload": (filename, b"")} request = httpx2.Request("GET", "https://www.example.com", files=files) assert expected in request.read() def test_unicode_escape(self) -> None: filename = "hello\\world\u0022" expected = b'filename="hello\\\\world%22"' files = {"upload": (filename, b"")} request = httpx2.Request("GET", "https://www.example.com", files=files) assert expected in request.read() def test_unicode_with_control_character(self) -> None: filename = "hello\x1a\x1b\x1c" expected = b'filename="hello%1A\x1b%1C"' files = {"upload": (filename, b"")} request = httpx2.Request("GET", "https://www.example.com", files=files) assert expected in request.read() pydantic-httpx2-6dd59b9/tests/httpx2/test_sse.py000066400000000000000000000505631526547463400220330ustar00rootroot00000000000000from __future__ import annotations from collections.abc import AsyncIterator, Iterator import pytest import httpx2 SSE_BODY = b": this is a comment\nevent: ping\ndata: hello\nid: 1\nretry: 500\n\ndata: first\ndata: second\n\n" def sse_handler(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, content=SSE_BODY, headers={"Content-Type": "text/event-stream"}) def test_sse_sync() -> None: with httpx2.Client(transport=httpx2.MockTransport(sse_handler)) as client: with client.sse("http://testserver/sse") as source: events = list(source) assert events == [ httpx2.ServerSentEvent(event="ping", data="hello", id="1", retry=500), httpx2.ServerSentEvent(event="message", data="first\nsecond", id="1"), ] @pytest.mark.anyio async def test_sse_async() -> None: async with httpx2.AsyncClient(transport=httpx2.MockTransport(sse_handler)) as client: async with client.sse("http://testserver/sse") as source: events = [event async for event in source] assert events == [ httpx2.ServerSentEvent(event="ping", data="hello", id="1", retry=500), httpx2.ServerSentEvent(event="message", data="first\nsecond", id="1"), ] def test_default_event_is_message() -> None: def handler(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, content=b"data: hi\n\n", headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse") as source: (event,) = list(source) assert event.event == "message" assert event.data == "hi" assert event.id == "" assert event.retry is None def test_json() -> None: def handler(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, content=b'data: {"x": 1}\n\n', headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse") as source: (event,) = list(source) assert event.json() == {"x": 1} def test_invalid_retry_is_ignored() -> None: def handler(request: httpx2.Request) -> httpx2.Response: body = b"retry: not-a-number\ndata: hi\n\n" return httpx2.Response(200, content=body, headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse") as source: (event,) = list(source) assert event.retry is None def test_id_with_null_is_ignored() -> None: def handler(request: httpx2.Request) -> httpx2.Response: body = b"id: a\0b\ndata: hi\n\n" return httpx2.Response(200, content=body, headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse") as source: (event,) = list(source) assert event.id == "" def test_field_without_value() -> None: def handler(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, content=b"data\n\n", headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse") as source: (event,) = list(source) assert event.data == "" def test_last_event_id_persists() -> None: def handler(request: httpx2.Request) -> httpx2.Response: body = b"id: 1\ndata: a\n\ndata: b\n\n" return httpx2.Response(200, content=body, headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse") as source: events = list(source) assert [event.id for event in events] == ["1", "1"] def test_blank_lines_after_id_do_not_dispatch() -> None: def handler(request: httpx2.Request) -> httpx2.Response: body = b"id: 1\ndata: a\n\n\n\ndata: b\n\n" return httpx2.Response(200, content=body, headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse") as source: events = list(source) assert [event.data for event in events] == ["a", "b"] def test_id_only_block_is_dispatched() -> None: def handler(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, content=b"id: 1\n\n", headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse") as source: (event,) = list(source) assert event.id == "1" assert event.data == "" @pytest.mark.parametrize( "content_type", ["text/event-stream", "text/event-stream; charset=utf-8", "Text/Event-Stream", "TEXT/EVENT-STREAM"], ) def test_content_type_accepted(content_type: str) -> None: def handler(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, content=b"data: hi\n\n", headers={"Content-Type": content_type}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse") as source: (event,) = list(source) assert event.data == "hi" def test_content_type_mismatch_raises() -> None: def handler(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, content=b"data: hi\n\n", headers={"Content-Type": "application/json"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse") as source: with pytest.raises(httpx2.SSEError, match="text/event-stream"): list(source) @pytest.mark.anyio async def test_content_type_mismatch_raises_async() -> None: def handler(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, content=b"data: hi\n\n", headers={"Content-Type": "application/json"}) async with httpx2.AsyncClient(transport=httpx2.MockTransport(handler)) as client: async with client.sse("http://testserver/sse") as source: with pytest.raises(httpx2.SSEError, match="text/event-stream"): [event async for event in source] def test_sets_sse_headers() -> None: captured: dict[str, str] = {} def handler(request: httpx2.Request) -> httpx2.Response: captured.update(request.headers) return httpx2.Response(200, content=b"data: hi\n\n", headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse") as source: list(source) assert captured["accept"] == "text/event-stream" assert captured["cache-control"] == "no-store" def test_user_headers_take_precedence() -> None: captured: dict[str, str] = {} def handler(request: httpx2.Request) -> httpx2.Response: captured.update(request.headers) return httpx2.Response(200, content=b"data: hi\n\n", headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse", headers={"Accept": "text/event-stream, application/json"}) as source: list(source) assert captured["accept"] == "text/event-stream, application/json" def test_response_is_accessible() -> None: with httpx2.Client(transport=httpx2.MockTransport(sse_handler)) as client: with client.sse("http://testserver/sse") as source: assert isinstance(source.response, httpx2.Response) assert source.response.status_code == 200 def test_post_method() -> None: captured: list[str] = [] def handler(request: httpx2.Request) -> httpx2.Response: captured.append(request.method) return httpx2.Response(200, content=b"data: hi\n\n", headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse", method="POST", json={"q": 1}) as source: list(source) assert captured == ["POST"] def test_chunk_boundaries_and_crlf_sync() -> None: def chunks() -> Iterator[bytes]: yield b"data: he" yield b"llo\r\n\r" yield b"\ndata: wor" yield b"ld\r\n\r\n" def handler(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, content=chunks(), headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse") as source: events = list(source) assert [event.data for event in events] == ["hello", "world"] @pytest.mark.anyio async def test_chunk_boundaries_and_crlf_async() -> None: async def chunks() -> AsyncIterator[bytes]: yield b"data: he" yield b"llo\r\n\r" yield b"\ndata: wor" yield b"ld\r\n\r\n" def handler(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, content=chunks(), headers={"Content-Type": "text/event-stream"}) async with httpx2.AsyncClient(transport=httpx2.MockTransport(handler)) as client: async with client.sse("http://testserver/sse") as source: events = [event async for event in source] assert [event.data for event in events] == ["hello", "world"] def test_event_without_trailing_blank_line() -> None: def handler(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, content=b"data: hi", headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse") as source: events = list(source) assert events == [] def test_leading_blank_line_is_ignored() -> None: def handler(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, content=b"\ndata: hi\n\n", headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse") as source: (event,) = list(source) assert event.data == "hi" def test_max_event_size_rejects_unterminated_line() -> None: def handler(request: httpx2.Request) -> httpx2.Response: body = b"data: " + b"A" * 8192 return httpx2.Response(200, content=body, headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse", max_event_size=4096) as source: with pytest.raises(httpx2.SSEError, match="4096 byte limit"): list(source) def test_max_event_size_rejects_many_data_lines() -> None: def handler(request: httpx2.Request) -> httpx2.Response: body = b"data: chunk\n" * 1000 return httpx2.Response(200, content=body, headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse", max_event_size=100) as source: with pytest.raises(httpx2.SSEError, match="100 byte limit"): list(source) def test_max_event_size_counts_empty_data_lines() -> None: def handler(request: httpx2.Request) -> httpx2.Response: body = b"data\n" * 1000 return httpx2.Response(200, content=body, headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse", max_event_size=100) as source: with pytest.raises(httpx2.SSEError, match="100 byte limit"): list(source) def test_max_event_size_counts_non_data_fields() -> None: def handler(request: httpx2.Request) -> httpx2.Response: body = b"id: " + b"A" * 8192 + b"\n\n" return httpx2.Response(200, content=body, headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse", max_event_size=4096) as source: with pytest.raises(httpx2.SSEError, match="4096 byte limit"): list(source) def test_max_event_size_measures_utf8_bytes() -> None: def handler(request: httpx2.Request) -> httpx2.Response: body = b"data: " + "๐Ÿ˜€".encode() * 50 + b"\n\n" return httpx2.Response(200, content=body, headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse", max_event_size=100) as source: with pytest.raises(httpx2.SSEError, match="100 byte limit"): list(source) def test_max_event_size_rejects_single_large_data_line() -> None: def handler(request: httpx2.Request) -> httpx2.Response: body = b"data: " + b"A" * 8192 + b"\n\n" return httpx2.Response(200, content=body, headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse", max_event_size=4096) as source: with pytest.raises(httpx2.SSEError, match="4096 byte limit"): list(source) def test_max_event_size_ignores_keepalive_comments() -> None: def handler(request: httpx2.Request) -> httpx2.Response: body = b": keepalive\n\n" * 1000 + b"data: hi\n\n" return httpx2.Response(200, content=body, headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse", max_event_size=100) as source: (event,) = list(source) assert event.data == "hi" def test_max_event_size_allows_event_under_limit() -> None: def handler(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, content=b"data: hi\n\n", headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse", max_event_size=4096) as source: (event,) = list(source) assert event.data == "hi" def test_max_event_size_resets_between_events() -> None: def handler(request: httpx2.Request) -> httpx2.Response: body = b"data: " + b"A" * 80 + b"\n\ndata: " + b"B" * 80 + b"\n\n" return httpx2.Response(200, content=body, headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse", max_event_size=100) as source: events = list(source) assert [len(event.data) for event in events] == [80, 80] def test_max_event_size_applies_by_default() -> None: def handler(request: httpx2.Request) -> httpx2.Response: body = b"data: " + b"A" * (2 * 1024 * 1024) + b"\n\n" return httpx2.Response(200, content=body, headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse") as source: with pytest.raises(httpx2.SSEError, match="byte limit"): list(source) def test_max_event_size_none_disables_limit() -> None: def handler(request: httpx2.Request) -> httpx2.Response: body = b"data: " + b"A" * (2 * 1024 * 1024) + b"\n\n" return httpx2.Response(200, content=body, headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse", max_event_size=None) as source: (event,) = list(source) assert len(event.data) == 2 * 1024 * 1024 def test_max_event_size_spans_completed_and_pending_lines() -> None: def chunks() -> Iterator[bytes]: yield b"data: " + b"A" * 60 + b"\n" yield b"data: " + b"B" * 60 def handler(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, content=chunks(), headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse", max_event_size=100) as source: with pytest.raises(httpx2.SSEError, match="100 byte limit"): list(source) def test_max_event_size_does_not_conflate_adjacent_events() -> None: def chunks() -> Iterator[bytes]: yield b"data: " + b"A" * 60 + b"\n\ndata: " + b"B" * 60 yield b"\n\n" def handler(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, content=chunks(), headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse", max_event_size=100) as source: events = list(source) assert [len(event.data) for event in events] == [60, 60] def test_max_event_size_error_has_request() -> None: def handler(request: httpx2.Request) -> httpx2.Response: body = b"data: " + b"A" * 8192 + b"\n\n" return httpx2.Response(200, content=body, headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse", max_event_size=4096) as source: with pytest.raises(httpx2.SSEError) as exc_info: list(source) assert exc_info.value.request.url == "http://testserver/sse" @pytest.mark.anyio async def test_max_event_size_applies_by_default_async() -> None: captured: list[int | None] = [] def handler(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, content=b"data: hi\n\n", headers={"Content-Type": "text/event-stream"}) async with httpx2.AsyncClient(transport=httpx2.MockTransport(handler)) as client: async with client.sse("http://testserver/sse") as source: captured.append(source._max_event_size) [event async for event in source] assert captured == [1024 * 1024] @pytest.mark.anyio async def test_max_event_size_allows_event_under_limit_async() -> None: def handler(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, content=b"data: hi\n\n", headers={"Content-Type": "text/event-stream"}) async with httpx2.AsyncClient(transport=httpx2.MockTransport(handler)) as client: async with client.sse("http://testserver/sse", max_event_size=4096) as source: events = [event async for event in source] assert [event.data for event in events] == ["hi"] def test_event_dispatched_at_eof_on_trailing_cr_sync() -> None: def chunks() -> Iterator[bytes]: yield b"data: hi\n" yield b"\r" def handler(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, content=chunks(), headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse") as source: (event,) = list(source) assert event.data == "hi" @pytest.mark.anyio async def test_event_dispatched_at_eof_on_trailing_cr_async() -> None: async def chunks() -> AsyncIterator[bytes]: yield b"data: hi\n" yield b"\r" def handler(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, content=chunks(), headers={"Content-Type": "text/event-stream"}) async with httpx2.AsyncClient(transport=httpx2.MockTransport(handler)) as client: async with client.sse("http://testserver/sse") as source: events = [event async for event in source] assert [event.data for event in events] == ["hi"] def test_many_chunks_without_line_separator() -> None: parts = [f"{index:04d}".encode() for index in range(1_000)] def chunks() -> Iterator[bytes]: yield b"data: " yield from parts yield b"\n\n" def handler(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, content=chunks(), headers={"Content-Type": "text/event-stream"}) with httpx2.Client(transport=httpx2.MockTransport(handler)) as client: with client.sse("http://testserver/sse") as source: (event,) = list(source) assert event.data == b"".join(parts).decode() pydantic-httpx2-6dd59b9/tests/httpx2/test_status_codes.py000066400000000000000000000040631526547463400237330ustar00rootroot00000000000000import pytest import httpx2 def test_status_code_as_int() -> None: # mypy doesn't (yet) recognize that IntEnum members are ints, so ignore it here assert httpx2.codes.NOT_FOUND == 404 # type: ignore[comparison-overlap] assert str(httpx2.codes.NOT_FOUND) == "404" def test_status_code_value_lookup() -> None: assert httpx2.codes(404) == 404 def test_status_code_phrase_lookup() -> None: assert httpx2.codes["NOT_FOUND"] == 404 def test_lowercase_status_code() -> None: assert httpx2.codes.not_found == 404 def test_reason_phrase_for_status_code() -> None: assert httpx2.codes.get_reason_phrase(404) == "Not Found" def test_reason_phrase_for_unknown_status_code() -> None: assert httpx2.codes.get_reason_phrase(499) == "" def test_rfc9110_status_texts() -> None: assert httpx2.codes.get_reason_phrase(413) == "Content Too Large" assert httpx2.codes.get_reason_phrase(414) == "URI Too Long" assert httpx2.codes.get_reason_phrase(416) == "Range Not Satisfiable" assert httpx2.codes.get_reason_phrase(422) == "Unprocessable Content" @pytest.mark.parametrize( ("old_name", "new_name"), [ ("REQUEST_ENTITY_TOO_LARGE", "CONTENT_TOO_LARGE"), ("REQUEST_URI_TOO_LONG", "URI_TOO_LONG"), ("REQUESTED_RANGE_NOT_SATISFIABLE", "RANGE_NOT_SATISFIABLE"), ("UNPROCESSABLE_ENTITY", "UNPROCESSABLE_CONTENT"), ], ) def test_pre_rfc9110_aliases_are_deprecated(old_name: str, new_name: str) -> None: # the pre-RFC 9110 constant names are kept as deprecated aliases msg = f"'{old_name}' is deprecated. Use '{new_name}' instead." with pytest.warns(DeprecationWarning, match=msg): assert getattr(httpx2.codes, old_name) == httpx2.codes[new_name] assert old_name in httpx2.codes.__members__ assert httpx2.codes[old_name] == httpx2.codes[new_name] assert getattr(httpx2.codes, old_name.lower()) == httpx2.codes[new_name] def test_unknown_status_code_attribute_raises() -> None: name = "NOT_A_REAL_CODE" with pytest.raises(AttributeError): getattr(httpx2.codes, name) pydantic-httpx2-6dd59b9/tests/httpx2/test_timeouts.py000066400000000000000000000036371526547463400231120ustar00rootroot00000000000000from __future__ import annotations import typing import pytest import httpx2 if typing.TYPE_CHECKING: from conftest import TestServer @pytest.mark.anyio async def test_read_timeout(server: TestServer) -> None: timeout = httpx2.Timeout(None, read=1e-6) async with httpx2.AsyncClient(timeout=timeout) as client: with pytest.raises(httpx2.ReadTimeout): await client.get(server.url.copy_with(path="/slow_response")) @pytest.mark.anyio async def test_write_timeout(server: TestServer) -> None: timeout = httpx2.Timeout(None, write=1e-6) async with httpx2.AsyncClient(timeout=timeout) as client: with pytest.raises(httpx2.WriteTimeout): data = b"*" * 1024 * 1024 * 100 await client.put(server.url.copy_with(path="/slow_response"), content=data) @pytest.mark.anyio @pytest.mark.network async def test_connect_timeout(server: TestServer) -> None: timeout = httpx2.Timeout(None, connect=1e-6) async with httpx2.AsyncClient(timeout=timeout) as client: with pytest.raises(httpx2.ConnectTimeout): # See https://stackoverflow.com/questions/100841/ await client.get("http://10.255.255.1/") @pytest.mark.anyio async def test_pool_timeout(server: TestServer) -> None: limits = httpx2.Limits(max_connections=1) timeout = httpx2.Timeout(None, pool=1e-4) async with httpx2.AsyncClient(limits=limits, timeout=timeout) as client: with pytest.raises(httpx2.PoolTimeout): async with client.stream("GET", server.url): await client.get(server.url) @pytest.mark.anyio async def test_async_client_new_request_send_timeout(server: TestServer) -> None: timeout = httpx2.Timeout(1e-6) async with httpx2.AsyncClient(timeout=timeout) as client: with pytest.raises(httpx2.TimeoutException): await client.send(httpx2.Request("GET", server.url.copy_with(path="/slow_response"))) pydantic-httpx2-6dd59b9/tests/httpx2/test_utils.py000066400000000000000000000157701526547463400224020ustar00rootroot00000000000000from __future__ import annotations import json import logging import os import random import typing import pytest import httpx2 from httpx2._utils import URLPattern, get_environment_proxies if typing.TYPE_CHECKING: from conftest import TestServer @pytest.mark.parametrize( "encoding", ( "utf-32", "utf-8-sig", "utf-16", "utf-8", "utf-16-be", "utf-16-le", "utf-32-be", "utf-32-le", ), ) def test_encoded(encoding: str) -> None: content = '{"abc": 123}'.encode(encoding) response = httpx2.Response(200, content=content) assert response.json() == {"abc": 123} def test_bad_utf_like_encoding() -> None: content = b"\x00\x00\x00\x00" response = httpx2.Response(200, content=content) with pytest.raises(json.decoder.JSONDecodeError): response.json() @pytest.mark.parametrize( ("encoding", "expected"), ( ("utf-16-be", "utf-16"), ("utf-16-le", "utf-16"), ("utf-32-be", "utf-32"), ("utf-32-le", "utf-32"), ), ) def test_guess_by_bom(encoding: str, expected: str) -> None: content = '\ufeff{"abc": 123}'.encode(encoding) response = httpx2.Response(200, content=content) assert response.json() == {"abc": 123} def test_logging_request(server: TestServer, caplog: pytest.LogCaptureFixture) -> None: caplog.set_level(logging.INFO) with httpx2.Client() as client: response = client.get(server.url) assert response.status_code == 200 httpx2_records = [r for r in caplog.record_tuples if r[0] == "httpx2"] assert httpx2_records == [ ( "httpx2", logging.INFO, f'HTTP Request: GET {server.url} "HTTP/1.1 200 OK"', ) ] def test_logging_redirect_chain(server: TestServer, caplog: pytest.LogCaptureFixture) -> None: caplog.set_level(logging.INFO) redirect_url = server.url.copy_with(path="/redirect_301") with httpx2.Client(follow_redirects=True) as client: response = client.get(redirect_url) assert response.status_code == 200 httpx2_records = [r for r in caplog.record_tuples if r[0] == "httpx2"] assert httpx2_records == [ ( "httpx2", logging.INFO, f'HTTP Request: GET {redirect_url} "HTTP/1.1 301 Moved Permanently"', ), ( "httpx2", logging.INFO, f'HTTP Request: GET {server.url} "HTTP/1.1 200 OK"', ), ] @pytest.mark.parametrize( ["environment", "proxies"], [ ({}, {}), ({"HTTP_PROXY": "http://127.0.0.1"}, {"http://": "http://127.0.0.1"}), ( {"https_proxy": "http://127.0.0.1", "HTTP_PROXY": "https://127.0.0.1"}, {"https://": "http://127.0.0.1", "http://": "https://127.0.0.1"}, ), ({"all_proxy": "http://127.0.0.1"}, {"all://": "http://127.0.0.1"}), ({"TRAVIS_APT_PROXY": "http://127.0.0.1"}, {}), ({"no_proxy": "127.0.0.1"}, {"all://127.0.0.1": None}), ({"no_proxy": "192.168.0.0/16"}, {"all://192.168.0.0/16": None}), ({"no_proxy": "::1"}, {"all://[::1]": None}), ({"no_proxy": "[::1]"}, {"all://[::1]": None}), ({"no_proxy": "[::1]:8080"}, {"all://[::1]:8080": None}), ({"no_proxy": "[::1]/128"}, {"all://[::1]/128": None}), ({"no_proxy": "[::1,foo:bar,github.com"}, {"all://*github.com": None}), ( { "no_proxy": ",".join( [ "192.168.0.0/33", "[::1]/129", "127.0.0.1//0", "127.0.0.1:8080/8", "127.0.0.1/8/../0", "127.0.0.1/255.0.0.0", "10.0.0.0/8?x", "10.0.0.0/8?", "10.0.0.0/8#", "user@10.0.0.0/8", "[fe80::1%eth0]/128", "github.com", ] ) }, {"all://*github.com": None}, ), ({"no_proxy": "fe11::/16"}, {"all://[fe11::]/16": None}), ({"no_proxy": "localhost"}, {"all://localhost": None}), ({"no_proxy": "github.com"}, {"all://*github.com": None}), ({"no_proxy": ".github.com"}, {"all://*.github.com": None}), ({"no_proxy": "http://github.com"}, {"http://github.com": None}), ], ) def test_get_environment_proxies(environment: dict[str, str], proxies: dict[str, str | None]) -> None: os.environ.update(environment) assert get_environment_proxies() == proxies @pytest.mark.parametrize( ["pattern", "url", "expected"], [ ("http://example.com", "http://example.com", True), ("http://example.com", "https://example.com", False), ("http://example.com", "http://other.com", False), ("http://example.com:123", "http://example.com:123", True), ("http://example.com:123", "http://example.com:456", False), ("http://example.com:123", "http://example.com", False), ("all://example.com", "http://example.com", True), ("all://example.com", "https://example.com", True), ("http://", "http://example.com", True), ("http://", "https://example.com", False), ("all://", "https://example.com:123", True), ("", "https://example.com:123", True), ("all://192.168.0.0/16", "http://192.168.5.10", True), ("all://192.168.0.0/16", "http://192.168.5.10:8080", True), ("all://192.168.0.0/16", "http://10.0.0.1", False), ("all://192.168.0.0/16", "http://example.com", False), ("all://[::1]/128", "http://[::1]", True), ("all://[::1]/128", "http://[::1]:8080", True), ("all://[::1]/128", "http://[::2]", False), ("all://192.168.0.0.0/16", "http://192.168.4.5", False), # Invalid CIDR ("all://[fe11::]/16", "http://[fe11:1234::5]", True), ("all://192.168.0.10/16", "http://192.168.5.10", True), # host bits set ], ) def test_url_matches(pattern: str, url: str, expected: bool) -> None: url_pattern = URLPattern(pattern) assert url_pattern.matches(httpx2.URL(url)) == expected def test_pattern_priority() -> None: matchers = [ URLPattern("all://"), URLPattern("http://"), URLPattern("http://example.com"), URLPattern("http://example.com:123"), URLPattern("all://192.168.1.10"), URLPattern("all://[::]/8"), # 2**120 addresses URLPattern("all://192.168.1.0/24"), # 256 addresses URLPattern("all://192.168.1.0/23"), # 512 addresses URLPattern("all://[::]/126"), # 4 addresses ] random.shuffle(matchers) assert sorted(matchers) == [ URLPattern("http://example.com:123"), URLPattern("all://192.168.1.10"), URLPattern("http://example.com"), URLPattern("all://[::]/126"), URLPattern("all://192.168.1.0/24"), URLPattern("all://192.168.1.0/23"), URLPattern("all://[::]/8"), URLPattern("http://"), URLPattern("all://"), ] pydantic-httpx2-6dd59b9/tests/httpx2/test_wsgi.py000066400000000000000000000154651526547463400222140ustar00rootroot00000000000000from __future__ import annotations import sys import typing import wsgiref.validate from functools import partial from io import StringIO import pytest import httpx2 if typing.TYPE_CHECKING: from _typeshed.wsgi import StartResponse, WSGIApplication, WSGIEnvironment def application_factory(output: typing.Iterable[bytes]) -> WSGIApplication: def application(environ: WSGIEnvironment, start_response: StartResponse) -> typing.Iterator[bytes]: status = "200 OK" response_headers = [ ("Content-type", "text/plain"), ] start_response(status, response_headers) yield from output return wsgiref.validate.validator(application) def echo_body(environ: WSGIEnvironment, start_response: StartResponse) -> typing.Iterable[bytes]: status = "200 OK" output = environ["wsgi.input"].read() response_headers = [ ("Content-type", "text/plain"), ] start_response(status, response_headers) return [output] def echo_body_with_response_stream(environ: WSGIEnvironment, start_response: StartResponse) -> typing.Iterable[bytes]: status = "200 OK" response_headers = [("Content-Type", "text/plain")] start_response(status, response_headers) def output_generator(f: typing.IO[bytes]) -> typing.Iterator[bytes]: while True: output = f.read(2) if not output: break yield output return output_generator(f=environ["wsgi.input"]) def raise_exc( environ: WSGIEnvironment, start_response: StartResponse, exc: type[Exception] = ValueError, ) -> typing.Iterable[bytes]: status = "500 Server Error" output = b"Nope!" response_headers = [ ("Content-type", "text/plain"), ] try: raise exc() except exc: exc_info = sys.exc_info() start_response(status, response_headers, exc_info) return [output] def log_to_wsgi_log_buffer(environ: WSGIEnvironment, start_response: StartResponse) -> typing.Iterable[bytes]: print("test1", file=environ["wsgi.errors"]) environ["wsgi.errors"].write("test2") return echo_body(environ, start_response) def test_wsgi() -> None: transport = httpx2.WSGITransport(app=application_factory([b"Hello, World!"])) client = httpx2.Client(transport=transport) response = client.get("http://www.example.org/") assert response.status_code == 200 assert response.text == "Hello, World!" def test_wsgi_upload() -> None: transport = httpx2.WSGITransport(app=echo_body) client = httpx2.Client(transport=transport) response = client.post("http://www.example.org/", content=b"example") assert response.status_code == 200 assert response.text == "example" def test_wsgi_upload_with_transfer_encoding() -> None: def app(environ: WSGIEnvironment, start_response: StartResponse) -> typing.Iterable[bytes]: content_length = int(environ.get("CONTENT_LENGTH", "0")) output = environ["wsgi.input"].read(content_length) start_response("200 OK", [("Content-Type", "text/plain")]) return [output] transport = httpx2.WSGITransport(app=app) client = httpx2.Client(transport=transport) response = client.post( "http://www.example.org/", headers={"Transfer-Encoding": "chunked"}, content=b"example", ) assert response.status_code == 200 assert response.text == "example" def test_wsgi_upload_with_response_stream() -> None: transport = httpx2.WSGITransport(app=echo_body_with_response_stream) client = httpx2.Client(transport=transport) response = client.post("http://www.example.org/", content=b"example") assert response.status_code == 200 assert response.text == "example" def test_wsgi_exc() -> None: transport = httpx2.WSGITransport(app=raise_exc) client = httpx2.Client(transport=transport) with pytest.raises(ValueError): client.get("http://www.example.org/") def test_wsgi_http_error() -> None: transport = httpx2.WSGITransport(app=partial(raise_exc, exc=RuntimeError)) client = httpx2.Client(transport=transport) with pytest.raises(RuntimeError): client.get("http://www.example.org/") def test_wsgi_generator() -> None: output = [b"", b"", b"Some content", b" and more content"] transport = httpx2.WSGITransport(app=application_factory(output)) client = httpx2.Client(transport=transport) response = client.get("http://www.example.org/") assert response.status_code == 200 assert response.text == "Some content and more content" def test_wsgi_generator_empty() -> None: output = [b"", b"", b"", b""] transport = httpx2.WSGITransport(app=application_factory(output)) client = httpx2.Client(transport=transport) response = client.get("http://www.example.org/") assert response.status_code == 200 assert response.text == "" def test_logging() -> None: buffer = StringIO() transport = httpx2.WSGITransport(app=log_to_wsgi_log_buffer, wsgi_errors=buffer) client = httpx2.Client(transport=transport) response = client.post("http://www.example.org/", content=b"example") assert response.status_code == 200 # no errors buffer.seek(0) assert buffer.read() == "test1\ntest2" @pytest.mark.parametrize( "url, expected_server_port", [ pytest.param("http://www.example.org", "80", id="auto-http"), pytest.param("https://www.example.org", "443", id="auto-https"), pytest.param("http://www.example.org:8000", "8000", id="explicit-port"), ], ) def test_wsgi_server_port(url: str, expected_server_port: str) -> None: """ SERVER_PORT is populated correctly from the requested URL. """ hello_world_app = application_factory([b"Hello, World!"]) server_port: str | None = None def app(environ: WSGIEnvironment, start_response: StartResponse) -> typing.Iterable[bytes]: nonlocal server_port server_port = environ["SERVER_PORT"] return hello_world_app(environ, start_response) transport = httpx2.WSGITransport(app=app) client = httpx2.Client(transport=transport) response = client.get(url) assert response.status_code == 200 assert response.text == "Hello, World!" assert server_port == expected_server_port def test_wsgi_server_protocol() -> None: server_protocol = None def app(environ: WSGIEnvironment, start_response: StartResponse) -> typing.Iterable[bytes]: nonlocal server_protocol server_protocol = environ["SERVER_PROTOCOL"] start_response("200 OK", [("Content-Type", "text/plain")]) return [b"success"] transport = httpx2.WSGITransport(app=app) with httpx2.Client(transport=transport, base_url="http://testserver") as client: response = client.get("/") assert response.status_code == 200 assert response.text == "success" assert server_protocol == "HTTP/1.1" pydantic-httpx2-6dd59b9/tests/httpx2/websockets/000077500000000000000000000000001526547463400217705ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/tests/httpx2/websockets/__init__.py000066400000000000000000000000001526547463400240670ustar00rootroot00000000000000pydantic-httpx2-6dd59b9/tests/httpx2/websockets/conftest.py000066400000000000000000000046471526547463400242020ustar00rootroot00000000000000from __future__ import annotations import contextlib import pathlib import queue import tempfile import time import typing from unittest.mock import MagicMock import pytest import uvicorn from anyio.from_thread import start_blocking_portal from starlette.applications import Starlette from starlette.routing import WebSocketRoute from starlette.websockets import WebSocket WebSocketEndpoint = typing.Callable[[WebSocket], typing.Awaitable[None]] @pytest.fixture def on_receive_message() -> MagicMock: return MagicMock() @pytest.fixture(params=("wsproto", "websockets-sansio")) def websocket_implementation(request: pytest.FixtureRequest) -> typing.Literal["wsproto", "websockets-sansio"]: return request.param # type: ignore[no-any-return] class ServerFactoryFixture(typing.Protocol): def __call__(self, endpoint: WebSocketEndpoint) -> contextlib.AbstractContextManager[str]: ... @pytest.fixture def server_factory(websocket_implementation: typing.Literal["wsproto", "websockets-sansio"]) -> ServerFactoryFixture: @contextlib.contextmanager def _server_factory(endpoint: WebSocketEndpoint) -> typing.Iterator[str]: shutdown_queue: queue.Queue[bool] = queue.Queue() def create_app() -> Starlette: routes = [WebSocketRoute("/ws", endpoint=endpoint)] return Starlette(routes=routes) def create_server(app: Starlette, socket: str) -> uvicorn.Server: config = uvicorn.Config(app, uds=socket, ws=websocket_implementation, lifespan="off") return uvicorn.Server(config) def on_server_stopped(_task: object) -> None: shutdown_queue.put(True) with start_blocking_portal(backend="asyncio") as portal: with tempfile.TemporaryDirectory() as socket_directory: socket = str(pathlib.Path(socket_directory) / "socket.sock") app = create_app() server = create_server(app, socket) task = portal.start_task_soon(server.serve) task.add_done_callback(on_server_stopped) while not server.started and not task.done(): time.sleep(0.01) if task.done() and task.exception() is not None: # pragma: no cover raise typing.cast(BaseException, task.exception()) yield socket server.should_exit = True shutdown_queue.get(True) return _server_factory pydantic-httpx2-6dd59b9/tests/httpx2/websockets/test_api.py000066400000000000000000001303401526547463400241530ustar00rootroot00000000000000from __future__ import annotations import concurrent.futures import queue import sys import threading import time import typing from unittest.mock import MagicMock, call, patch import anyio import pytest import wsproto from starlette.websockets import WebSocket, WebSocketDisconnect as StarletteWebSocketDisconnect import httpcore2 as httpcore import httpx2 as httpx from httpcore2 import AsyncNetworkStream, NetworkStream from httpx2.websockets import WebSocketSession, _api from httpx2.websockets._api import ( AsyncWebSocketClient, AsyncWebSocketSession, JSONMode, WebSocketClient, aconnect_ws, connect_ws, ) from httpx2.websockets._exceptions import ( WebSocketDisconnect, WebSocketInvalidTypeReceived, WebSocketNetworkError, WebSocketUpgradeError, ) from tests.httpx2.websockets.conftest import ServerFactoryFixture @pytest.mark.anyio async def test_upgrade_error() -> None: def handler(request: httpx.Request) -> httpx.Response: return httpx.Response(400) with httpx.Client(base_url="http://localhost:8000", transport=httpx.MockTransport(handler)) as client: with pytest.raises(WebSocketUpgradeError): with connect_ws("http://socket/ws", client): pass # pragma: no cover async with httpx.AsyncClient(base_url="http://localhost:8000", transport=httpx.MockTransport(handler)) as aclient: with pytest.raises(WebSocketUpgradeError): async with aconnect_ws("http://socket/ws", aclient): pass # pragma: no cover @pytest.mark.anyio class TestSend: async def test_send_error(self) -> None: class MockNetworkStream(NetworkStream): def __init__(self) -> None: self.connection = wsproto.connection.Connection(wsproto.connection.ConnectionType.SERVER) self._should_close = False def read(self, max_bytes: int, timeout: float | None = None) -> bytes: while not self._should_close: # pragma: no cover time.sleep(0.1) raise httpcore.ReadError() # pragma: no cover def write(self, buffer: bytes, timeout: float | None = None) -> None: raise httpcore.WriteError() def close(self) -> None: self._should_close = True stream = MockNetworkStream() with pytest.raises(WebSocketNetworkError): with WebSocketSession(stream) as websocket_session: websocket_session.send(wsproto.events.Ping()) async def test_async_send_error(self) -> None: class AsyncMockNetworkStream(AsyncNetworkStream): def __init__(self) -> None: self.connection = wsproto.connection.Connection(wsproto.connection.ConnectionType.SERVER) self._should_close = False async def read(self, max_bytes: int, timeout: float | None = None) -> bytes: while not self._should_close: # pragma: no cover await anyio.sleep(0.1) raise httpcore.ReadError() # pragma: no cover async def write(self, buffer: bytes, timeout: float | None = None) -> None: raise httpcore.WriteError() async def aclose(self) -> None: self._should_close = True stream = AsyncMockNetworkStream() with pytest.RaisesGroup(WebSocketNetworkError): async with AsyncWebSocketSession(stream) as websocket_session: await websocket_session.send(wsproto.events.Ping()) async def test_send( self, server_factory: ServerFactoryFixture, on_receive_message: MagicMock, ) -> None: async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() message = await websocket.receive_text() on_receive_message(message) await websocket.close() with server_factory(websocket_endpoint) as socket: with httpx.Client(transport=httpx.HTTPTransport(uds=socket)) as client: with connect_ws("http://socket/ws", client) as ws: ws.send(wsproto.events.TextMessage(data="CLIENT_MESSAGE")) async with httpx.AsyncClient(transport=httpx.AsyncHTTPTransport(uds=socket)) as aclient: async with aconnect_ws("http://socket/ws", aclient) as aws: await aws.send(wsproto.events.TextMessage(data="CLIENT_MESSAGE")) on_receive_message.assert_has_calls([call("CLIENT_MESSAGE"), call("CLIENT_MESSAGE")]) async def test_send_text( self, server_factory: ServerFactoryFixture, on_receive_message: MagicMock, ) -> None: async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() message = await websocket.receive_text() on_receive_message(message) await websocket.close() with server_factory(websocket_endpoint) as socket: with httpx.Client(transport=httpx.HTTPTransport(uds=socket)) as client: with connect_ws("http://socket/ws", client) as ws: ws.send_text("CLIENT_MESSAGE") async with httpx.AsyncClient(transport=httpx.AsyncHTTPTransport(uds=socket)) as aclient: async with aconnect_ws("http://socket/ws", aclient) as aws: await aws.send_text("CLIENT_MESSAGE") on_receive_message.assert_has_calls([call("CLIENT_MESSAGE"), call("CLIENT_MESSAGE")]) async def test_send_bytes( self, server_factory: ServerFactoryFixture, on_receive_message: MagicMock, ) -> None: async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() message = await websocket.receive_bytes() on_receive_message(message) await websocket.close() with server_factory(websocket_endpoint) as socket: with httpx.Client(transport=httpx.HTTPTransport(uds=socket)) as client: with connect_ws("http://socket/ws", client) as ws: ws.send_bytes(b"CLIENT_MESSAGE") async with httpx.AsyncClient(transport=httpx.AsyncHTTPTransport(uds=socket)) as aclient: async with aconnect_ws("http://socket/ws", aclient) as aws: await aws.send_bytes(b"CLIENT_MESSAGE") on_receive_message.assert_has_calls([call(b"CLIENT_MESSAGE"), call(b"CLIENT_MESSAGE")]) @pytest.mark.parametrize("mode", ["text", "binary"]) async def test_send_json( self, mode: JSONMode, server_factory: ServerFactoryFixture, on_receive_message: MagicMock, ) -> None: async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() message = await websocket.receive_json(mode=mode) on_receive_message(message) await websocket.close() with server_factory(websocket_endpoint) as socket: with httpx.Client(transport=httpx.HTTPTransport(uds=socket)) as client: with connect_ws("http://socket/ws", client) as ws: ws.send_json({"message": "CLIENT_MESSAGE"}, mode=mode) async with httpx.AsyncClient(transport=httpx.AsyncHTTPTransport(uds=socket)) as aclient: async with aconnect_ws("http://socket/ws", aclient) as aws: await aws.send_json({"message": "CLIENT_MESSAGE"}, mode=mode) on_receive_message.assert_has_calls([call({"message": "CLIENT_MESSAGE"}), call({"message": "CLIENT_MESSAGE"})]) @pytest.mark.anyio class TestReceive: async def test_receive_error(self) -> None: class MockNetworkStream(NetworkStream): def __init__(self) -> None: self.connection = wsproto.connection.Connection(wsproto.connection.ConnectionType.SERVER) def read(self, max_bytes: int, timeout: float | None = None) -> bytes: raise httpcore.ReadError() def write(self, buffer: bytes, timeout: float | None = None) -> None: pass def close(self) -> None: pass stream = MockNetworkStream() with pytest.raises(WebSocketNetworkError): with WebSocketSession(stream) as websocket_session: websocket_session.receive() def test_receive_closed_socket(self) -> None: class MockNetworkStream(NetworkStream): def __init__(self) -> None: self.connection = wsproto.connection.Connection(wsproto.connection.ConnectionType.SERVER) def read(self, max_bytes: int, timeout: float | None = None) -> bytes: return b"" def write(self, buffer: bytes, timeout: float | None = None) -> None: pass def close(self) -> None: pass stream = MockNetworkStream() with pytest.raises(WebSocketNetworkError): with WebSocketSession(stream) as websocket_session: websocket_session.receive() def test_receive_timeout(self) -> None: class MockNetworkStream(NetworkStream): def __init__(self) -> None: self.connection = wsproto.connection.Connection(wsproto.connection.ConnectionType.SERVER) def read(self, max_bytes: int, timeout: float | None = None) -> bytes: time.sleep(0.2) return b"" def write(self, buffer: bytes, timeout: float | None = None) -> None: pass def close(self) -> None: pass stream = MockNetworkStream() with pytest.raises(TimeoutError): with WebSocketSession(stream) as websocket_session: websocket_session.receive(timeout=0.1) async def test_async_receive_error(self) -> None: class AsyncMockNetworkStream(AsyncNetworkStream): def __init__(self) -> None: self.connection = wsproto.connection.Connection(wsproto.connection.ConnectionType.SERVER) async def read(self, max_bytes: int, timeout: float | None = None) -> bytes: raise httpcore.ReadError() async def write(self, buffer: bytes, timeout: float | None = None) -> None: pass async def aclose(self) -> None: pass stream = AsyncMockNetworkStream() with pytest.RaisesGroup(WebSocketNetworkError): async with AsyncWebSocketSession(stream) as websocket_session: await websocket_session.receive() async def test_async_receive_closed_socket(self) -> None: class AsyncMockNetworkStream(AsyncNetworkStream): def __init__(self) -> None: self.connection = wsproto.connection.Connection(wsproto.connection.ConnectionType.SERVER) async def read(self, max_bytes: int, timeout: float | None = None) -> bytes: return b"" async def write(self, buffer: bytes, timeout: float | None = None) -> None: pass async def aclose(self) -> None: pass stream = AsyncMockNetworkStream() with pytest.RaisesGroup(WebSocketNetworkError): async with AsyncWebSocketSession(stream) as websocket_session: await websocket_session.receive() async def test_receive(self, server_factory: ServerFactoryFixture) -> None: async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() await websocket.send_text("SERVER_MESSAGE") await websocket.close() with server_factory(websocket_endpoint) as socket: with httpx.Client(transport=httpx.HTTPTransport(uds=socket)) as client: with connect_ws("http://socket/ws", client) as ws: event = ws.receive() assert isinstance(event, wsproto.events.TextMessage) assert event.data == "SERVER_MESSAGE" async with httpx.AsyncClient(transport=httpx.AsyncHTTPTransport(uds=socket)) as aclient: async with aconnect_ws("http://socket/ws", aclient) as aws: event = await aws.receive() assert isinstance(event, wsproto.events.TextMessage) assert event.data == "SERVER_MESSAGE" @pytest.mark.parametrize( "full_message,send_method", [ pytest.param(b"A" * 1024 * 4, "send_bytes", id="bytes"), pytest.param("A" * 1024 * 4, "send_text", id="text"), ], ) async def test_receive_oversized_message( self, full_message: str | bytes, send_method: str, server_factory: ServerFactoryFixture, ) -> None: async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() method = getattr(websocket, send_method) await method(full_message) await websocket.close() with server_factory(websocket_endpoint) as socket: with httpx.Client(transport=httpx.HTTPTransport(uds=socket)) as client: with connect_ws("http://socket/ws", client, max_message_size_bytes=1024) as ws: with pytest.raises(WebSocketDisconnect) as excinfo: ws.receive() assert excinfo.value.code == wsproto.frame_protocol.CloseReason.MESSAGE_TOO_BIG async with httpx.AsyncClient(transport=httpx.AsyncHTTPTransport(uds=socket)) as aclient: async with aconnect_ws("http://socket/ws", aclient, max_message_size_bytes=1024) as aws: with pytest.raises(WebSocketDisconnect) as aexcinfo: await aws.receive() assert aexcinfo.value.code == wsproto.frame_protocol.CloseReason.MESSAGE_TOO_BIG @pytest.mark.parametrize( "fragment_event", [ pytest.param(wsproto.events.BytesMessage(data=b"A" * 8, message_finished=False), id="binary"), pytest.param(wsproto.events.TextMessage(data="รฉ" * 4, message_finished=False), id="multibyte-text"), ], ) async def test_receive_oversized_fragmented_message( self, fragment_event: wsproto.events.Message[typing.Any], ) -> None: server_connection = wsproto.connection.Connection(wsproto.connection.ConnectionType.SERVER) fragments = [server_connection.send(fragment_event) for _ in range(3)] class MockNetworkStream(NetworkStream): def __init__(self) -> None: self._fragments = list(fragments) def read(self, max_bytes: int, timeout: float | None = None) -> bytes: if self._fragments: return self._fragments.pop(0) time.sleep(0.1) # pragma: no cover return b"" # pragma: no cover def write(self, buffer: bytes, timeout: float | None = None) -> None: pass def close(self) -> None: pass with WebSocketSession(MockNetworkStream(), max_message_size_bytes=16) as websocket_session: with pytest.raises(WebSocketDisconnect) as excinfo: websocket_session.receive() assert excinfo.value.code == wsproto.frame_protocol.CloseReason.MESSAGE_TOO_BIG @pytest.mark.parametrize( "fragment_event", [ pytest.param(wsproto.events.BytesMessage(data=b"A" * 8, message_finished=False), id="binary"), pytest.param(wsproto.events.TextMessage(data="รฉ" * 4, message_finished=False), id="multibyte-text"), ], ) async def test_async_receive_oversized_fragmented_message( self, fragment_event: wsproto.events.Message[typing.Any], ) -> None: server_connection = wsproto.connection.Connection(wsproto.connection.ConnectionType.SERVER) fragments = [server_connection.send(fragment_event) for _ in range(3)] class AsyncMockNetworkStream(AsyncNetworkStream): def __init__(self) -> None: self._fragments = list(fragments) async def read(self, max_bytes: int, timeout: float | None = None) -> bytes: if self._fragments: return self._fragments.pop(0) await anyio.sleep(0.1) # pragma: no cover return b"" # pragma: no cover async def write(self, buffer: bytes, timeout: float | None = None) -> None: pass async def aclose(self) -> None: pass async with AsyncWebSocketSession(AsyncMockNetworkStream(), max_message_size_bytes=16) as websocket_session: with pytest.raises(WebSocketDisconnect) as excinfo: await websocket_session.receive() assert excinfo.value.code == wsproto.frame_protocol.CloseReason.MESSAGE_TOO_BIG async def test_receive_text(self, server_factory: ServerFactoryFixture) -> None: async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() await websocket.send_text("SERVER_MESSAGE") await websocket.close() with server_factory(websocket_endpoint) as socket: with httpx.Client(transport=httpx.HTTPTransport(uds=socket)) as client: with connect_ws("http://socket/ws", client) as ws: data = ws.receive_text() assert data == "SERVER_MESSAGE" async with httpx.AsyncClient(transport=httpx.AsyncHTTPTransport(uds=socket)) as aclient: async with aconnect_ws("http://socket/ws", aclient) as aws: data = await aws.receive_text() assert data == "SERVER_MESSAGE" async def test_receive_text_invalid_type(self, server_factory: ServerFactoryFixture) -> None: async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() await websocket.send_bytes(b"SERVER_MESSAGE") await websocket.close() with server_factory(websocket_endpoint) as socket: with httpx.Client(transport=httpx.HTTPTransport(uds=socket)) as client: with connect_ws("http://socket/ws", client) as ws: with pytest.raises(WebSocketInvalidTypeReceived): ws.receive_text() async with httpx.AsyncClient(transport=httpx.AsyncHTTPTransport(uds=socket)) as aclient: async with aconnect_ws("http://socket/ws", aclient) as aws: with pytest.raises(WebSocketInvalidTypeReceived): await aws.receive_text() async def test_receive_bytes(self, server_factory: ServerFactoryFixture) -> None: async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() await websocket.send_bytes(b"SERVER_MESSAGE") await websocket.close() with server_factory(websocket_endpoint) as socket: with httpx.Client(transport=httpx.HTTPTransport(uds=socket)) as client: with connect_ws("http://socket/ws", client) as ws: data = ws.receive_bytes() assert data == b"SERVER_MESSAGE" async with httpx.AsyncClient(transport=httpx.AsyncHTTPTransport(uds=socket)) as aclient: async with aconnect_ws("http://socket/ws", aclient) as aws: data = await aws.receive_bytes() assert data == b"SERVER_MESSAGE" async def test_receive_bytes_invalid_type(self, server_factory: ServerFactoryFixture) -> None: async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() await websocket.send_text("SERVER_MESSAGE") await websocket.close() with server_factory(websocket_endpoint) as socket: with httpx.Client(transport=httpx.HTTPTransport(uds=socket)) as client: with connect_ws("http://socket/ws", client) as ws: with pytest.raises(WebSocketInvalidTypeReceived): ws.receive_bytes() async with httpx.AsyncClient(transport=httpx.AsyncHTTPTransport(uds=socket)) as aclient: async with aconnect_ws("http://socket/ws", aclient) as aws: with pytest.raises(WebSocketInvalidTypeReceived): await aws.receive_bytes() @pytest.mark.parametrize("mode", ["text", "binary"]) async def test_receive_json(self, mode: JSONMode, server_factory: ServerFactoryFixture) -> None: async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() await websocket.send_json({"message": "SERVER_MESSAGE"}, mode=mode) await websocket.close() with server_factory(websocket_endpoint) as socket: with httpx.Client(transport=httpx.HTTPTransport(uds=socket)) as client: with connect_ws("http://socket/ws", client) as ws: data = ws.receive_json(mode=mode) assert data == {"message": "SERVER_MESSAGE"} async with httpx.AsyncClient(transport=httpx.AsyncHTTPTransport(uds=socket)) as aclient: async with aconnect_ws("http://socket/ws", aclient) as aws: data = await aws.receive_json(mode=mode) assert data == {"message": "SERVER_MESSAGE"} @pytest.mark.anyio class TestReceivePing: async def test_receive_ping(self) -> None: class MockNetworkStream(NetworkStream): def __init__(self) -> None: self.connection = wsproto.connection.Connection(wsproto.connection.ConnectionType.SERVER) self.events_to_send = [ wsproto.events.Ping(b"SERVER_PING"), wsproto.events.CloseConnection(1000), ] def read(self, max_bytes: int, timeout: float | None = None) -> bytes: try: event = self.events_to_send.pop(0) return self.connection.send(event) except IndexError: # pragma: no cover raise httpcore.ReadError() def write(self, buffer: bytes, timeout: float | None = None) -> None: self.connection.receive_data(buffer) def close(self) -> None: pass stream = MockNetworkStream() with WebSocketSession(stream): await anyio.sleep(0.1) received_events = list(stream.connection.events()) assert received_events == [ wsproto.events.Pong(b"SERVER_PING"), wsproto.events.CloseConnection(1000, ""), ] async def test_async_receive_ping(self) -> None: class MockAsyncNetworkStream(AsyncNetworkStream): def __init__(self) -> None: self.connection = wsproto.connection.Connection(wsproto.connection.ConnectionType.SERVER) self.events_to_send = [ wsproto.events.Ping(b"SERVER_PING"), wsproto.events.CloseConnection(1000), ] async def read(self, max_bytes: int, timeout: float | None = None) -> bytes: try: event = self.events_to_send.pop(0) return self.connection.send(event) except IndexError: # pragma: no cover raise httpcore.ReadError() async def write(self, buffer: bytes, timeout: float | None = None) -> None: self.connection.receive_data(buffer) async def aclose(self) -> None: pass stream = MockAsyncNetworkStream() async with AsyncWebSocketSession(stream): await anyio.sleep(0.1) received_events = list(stream.connection.events()) assert received_events == [ wsproto.events.Pong(b"SERVER_PING"), wsproto.events.CloseConnection(1000, ""), ] async def test_receive_unsolicited_pong(self) -> None: class MockNetworkStream(NetworkStream): def __init__(self) -> None: self.connection = wsproto.connection.Connection(wsproto.connection.ConnectionType.SERVER) self.events_to_send = [ wsproto.events.Pong(b"UNSOLICITED"), wsproto.events.TextMessage("SERVER_MESSAGE"), wsproto.events.CloseConnection(1000), ] def read(self, max_bytes: int, timeout: float | None = None) -> bytes: try: event = self.events_to_send.pop(0) return self.connection.send(event) except IndexError: # pragma: no cover raise httpcore.ReadError() def write(self, buffer: bytes, timeout: float | None = None) -> None: self.connection.receive_data(buffer) def close(self) -> None: pass stream = MockNetworkStream() with WebSocketSession(stream) as session: assert session.receive_text(timeout=1) == "SERVER_MESSAGE" async def test_async_receive_unsolicited_pong(self) -> None: class MockAsyncNetworkStream(AsyncNetworkStream): def __init__(self) -> None: self.connection = wsproto.connection.Connection(wsproto.connection.ConnectionType.SERVER) self.events_to_send = [ wsproto.events.Pong(b"UNSOLICITED"), wsproto.events.TextMessage("SERVER_MESSAGE"), wsproto.events.CloseConnection(1000), ] async def read(self, max_bytes: int, timeout: float | None = None) -> bytes: try: event = self.events_to_send.pop(0) return self.connection.send(event) except IndexError: # pragma: no cover raise httpcore.ReadError() async def write(self, buffer: bytes, timeout: float | None = None) -> None: self.connection.receive_data(buffer) async def aclose(self) -> None: pass stream = MockAsyncNetworkStream() async with AsyncWebSocketSession(stream) as session: assert await session.receive_text(timeout=1) == "SERVER_MESSAGE" @pytest.mark.anyio class TestKeepalivePing: async def test_keepalive_ping(self) -> None: class MockNetworkStream(NetworkStream): def __init__(self) -> None: self.connection = wsproto.connection.Connection(wsproto.connection.ConnectionType.SERVER) self._should_close = False self.ping_received = 0 self.ping_answered = 0 self.events_to_send: queue.Queue[wsproto.events.Event] = queue.Queue() def read(self, max_bytes: int, timeout: float | None = None) -> bytes: while not self._should_close: try: event = self.events_to_send.get_nowait() self.ping_answered += 1 return self.connection.send(event) except queue.Empty: pass raise httpcore.ReadError() def write(self, buffer: bytes, timeout: float | None = None) -> None: self.connection.receive_data(buffer) for event in self.connection.events(): if isinstance(event, wsproto.events.Ping): self.ping_received += 1 self.events_to_send.put(event.response()) def close(self) -> None: self._should_close = True stream = MockNetworkStream() with WebSocketSession( stream, keepalive_ping_interval_seconds=0.1, keepalive_ping_timeout_seconds=0.1, ): await anyio.sleep(0.2) assert stream.ping_received >= 1 assert stream.ping_answered >= 1 def test_keepalive_ping_exits_when_closing(self, monkeypatch: pytest.MonkeyPatch) -> None: read_started = threading.Event() closed = threading.Event() writes: list[bytes] = [] class MockNetworkStream(NetworkStream): def read(self, max_bytes: int, timeout: float | None = None) -> bytes: read_started.set() assert closed.wait(5) return b"" def write(self, buffer: bytes, timeout: float | None = None) -> None: writes.append(buffer) def close(self) -> None: closed.set() session = WebSocketSession(MockNetworkStream(), keepalive_ping_interval_seconds=0) ping = session.ping def ping_while_closing(payload: bytes = b"") -> threading.Event: assert read_started.wait(5) session.close() return ping(payload) monkeypatch.setattr(session, "ping", ping_while_closing) with session: assert closed.wait(5) assert len(writes) == 1 async def test_keepalive_ping_timeout(self) -> None: class MockNetworkStream(NetworkStream): def __init__(self) -> None: self.connection = wsproto.connection.Connection(wsproto.connection.ConnectionType.SERVER) self._should_close = False def read(self, max_bytes: int, timeout: float | None = None) -> bytes: while not self._should_close: # pragma: no cover time.sleep(0.1) raise httpcore.ReadError() # pragma: no cover def write(self, buffer: bytes, timeout: float | None = None) -> None: pass def close(self) -> None: self._should_close = True stream = MockNetworkStream() with pytest.raises(WebSocketNetworkError): with WebSocketSession( stream, keepalive_ping_interval_seconds=0.1, keepalive_ping_timeout_seconds=0.1, ) as websocket_session: websocket_session.receive() async def test_async_keepalive_ping(self) -> None: class MockAsyncNetworkStream(AsyncNetworkStream): def __init__(self) -> None: self.connection = wsproto.connection.Connection(wsproto.connection.ConnectionType.SERVER) self._should_close = False self.ping_received = 0 self.ping_answered = 0 ( self.send_events, self.receive_events, ) = anyio.create_memory_object_stream[wsproto.events.Event]() async def read(self, max_bytes: int, timeout: float | None = None) -> bytes: while not self._should_close: try: event = self.receive_events.receive_nowait() self.ping_answered += 1 return self.connection.send(event) except anyio.WouldBlock: await anyio.sleep(0.1) raise httpcore.ReadError() # pragma: no cover async def write(self, buffer: bytes, timeout: float | None = None) -> None: self.connection.receive_data(buffer) for event in self.connection.events(): if isinstance(event, wsproto.events.Ping): self.ping_received += 1 await self.send_events.send(event.response()) async def aclose(self) -> None: self._should_close = True await self.send_events.aclose() await self.receive_events.aclose() stream = MockAsyncNetworkStream() async with AsyncWebSocketSession( stream, keepalive_ping_interval_seconds=0.1, keepalive_ping_timeout_seconds=0.1, ): await anyio.sleep(0.3) assert stream.ping_received >= 1 assert stream.ping_answered >= 1 async def test_async_keepalive_ping_exits_when_closing(self) -> None: writes = 0 class MockAsyncNetworkStream(AsyncNetworkStream): async def read(self, max_bytes: int, timeout: float | None = None) -> bytes: return b"" # pragma: no cover async def write(self, buffer: bytes, timeout: float | None = None) -> None: nonlocal writes writes += 1 # pragma: no cover async def aclose(self) -> None: ... # pragma: no cover session = AsyncWebSocketSession(MockAsyncNetworkStream(), keepalive_ping_interval_seconds=0.1) session.connection.send(wsproto.events.CloseConnection(1000)) with anyio.fail_after(1): await session._background_keepalive_ping(0.01) assert writes == 0 async def test_async_keepalive_ping_timeout(self) -> None: class MockAsyncNetworkStream(AsyncNetworkStream): def __init__(self) -> None: self.connection = wsproto.connection.Connection(wsproto.connection.ConnectionType.SERVER) self._should_close = False async def read(self, max_bytes: int, timeout: float | None = None) -> bytes: while not self._should_close: # pragma: no cover await anyio.sleep(0.1) raise httpcore.ReadError() # pragma: no cover async def write(self, buffer: bytes, timeout: float | None = None) -> None: pass async def aclose(self) -> None: self._should_close = True stream = MockAsyncNetworkStream() with pytest.RaisesGroup(WebSocketNetworkError): async with AsyncWebSocketSession( stream, keepalive_ping_interval_seconds=0.1, keepalive_ping_timeout_seconds=0.1, ) as websocket_session: await websocket_session.receive() @pytest.mark.anyio async def test_ping_pong(server_factory: ServerFactoryFixture) -> None: async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() try: await websocket.receive_text() except StarletteWebSocketDisconnect: pass with server_factory(websocket_endpoint) as socket: with httpx.Client(transport=httpx.HTTPTransport(uds=socket)) as client: with connect_ws("http://socket/ws", client) as ws: ping_callback = ws.ping() result = ping_callback.wait() assert result is True async with httpx.AsyncClient(transport=httpx.AsyncHTTPTransport(uds=socket)) as aclient: async with aconnect_ws("http://socket/ws", aclient) as aws: aping_callback = await aws.ping() await aping_callback.wait() assert aping_callback.is_set() @pytest.mark.anyio async def test_send_close(server_factory: ServerFactoryFixture, on_receive_message: MagicMock) -> None: async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() try: await websocket.receive_text() except StarletteWebSocketDisconnect as e: print(e) on_receive_message(e.code, e.reason) with server_factory(websocket_endpoint) as socket: with httpx.Client(transport=httpx.HTTPTransport(uds=socket)) as client: with connect_ws("http://socket/ws", client) as ws: ws.close(code=1001, reason="CLOSE_REASON") async with httpx.AsyncClient(transport=httpx.AsyncHTTPTransport(uds=socket)) as aclient: async with aconnect_ws("http://socket/ws", aclient) as aws: await aws.close(code=1001, reason="CLOSE_REASON") on_receive_message.assert_has_calls([call(1001, "CLOSE_REASON"), call(1001, "CLOSE_REASON")]) @pytest.mark.anyio async def test_receive_close(server_factory: ServerFactoryFixture) -> None: async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() await websocket.close() with server_factory(websocket_endpoint) as socket: with httpx.Client(transport=httpx.HTTPTransport(uds=socket)) as client: with connect_ws("http://socket/ws", client) as ws: with pytest.raises(WebSocketDisconnect): ws.receive() async with httpx.AsyncClient(transport=httpx.AsyncHTTPTransport(uds=socket)) as aclient: async with aconnect_ws("http://socket/ws", aclient) as aws: with pytest.raises(WebSocketDisconnect): await aws.receive() @pytest.mark.anyio async def test_default_httpx_client() -> None: with patch.object(_api, "WebSocketClient") as mock_client: with connect_ws("http://socket/ws"): pass mock_client.return_value.connect.assert_called_once() httpx_client = mock_client.call_args[1]["client"] assert isinstance(httpx_client, httpx.Client) assert httpx_client.is_closed with patch.object(_api, "AsyncWebSocketClient") as mock_async_client: async with aconnect_ws("http://socket/ws"): pass mock_async_client.return_value.connect.assert_called_once() httpx_client = mock_async_client.call_args[1]["client"] assert isinstance(httpx_client, httpx.AsyncClient) assert httpx_client.is_closed @pytest.mark.anyio async def test_subprotocol_and_response() -> None: def handler(request: httpx.Request) -> httpx.Response: assert request.headers["sec-websocket-protocol"] == "custom_protocol, unsupported_protocol" return httpx.Response( 101, headers={"sec-websocket-protocol": "custom_protocol"}, extensions={"network_stream": MagicMock(spec=NetworkStream)}, ) def async_handler(request: httpx.Request) -> httpx.Response: assert request.headers["sec-websocket-protocol"] == "custom_protocol, unsupported_protocol" return httpx.Response( 101, headers={"sec-websocket-protocol": "custom_protocol"}, extensions={"network_stream": MagicMock(spec=AsyncNetworkStream)}, ) with httpx.Client(base_url="http://localhost:8000", transport=httpx.MockTransport(handler)) as client: with connect_ws( "http://socket/ws", client, subprotocols=["custom_protocol", "unsupported_protocol"], ) as ws: assert isinstance(ws.response, httpx.Response) assert ws.subprotocol == "custom_protocol" assert ws.response.headers["sec-websocket-protocol"] == ws.subprotocol async with httpx.AsyncClient( base_url="http://localhost:8000", transport=httpx.MockTransport(async_handler) ) as aclient: async with aconnect_ws( "http://socket/ws", aclient, subprotocols=["custom_protocol", "unsupported_protocol"], ) as aws: assert isinstance(aws.response, httpx.Response) assert aws.subprotocol == "custom_protocol" assert aws.response.headers["sec-websocket-protocol"] == aws.subprotocol @pytest.mark.anyio async def test_threads_wont_hang(server_factory: ServerFactoryFixture) -> None: """ Check that all threads spawned in WebSocketSession are properly terminated during a series of messages exchange. This used to be the cause of a memory leak in the connect_ws client, see https://github.com/frankie567/httpx-ws/issues/76. """ async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() for _ in range(50): await websocket.send_text("SERVER_MESSAGE") await websocket.receive_text() await websocket.close() def session_threads() -> set[threading.Thread]: return set(threading.enumerate()) - threads_before def wait_for_session_threads(expected: int) -> None: for _ in range(100): if len(session_threads()) == expected: return time.sleep(0.05) # pragma: no cover - only runs if the threads are still exiting assert len(session_threads()) == expected # pragma: no cover with server_factory(websocket_endpoint) as socket: with httpx.Client(transport=httpx.HTTPTransport(uds=socket)) as client: threads_before = set(threading.enumerate()) with connect_ws("http://socket/ws", client, keepalive_ping_interval_seconds=None) as ws: for _ in range(50): ws.receive() ws.send_text("CLIENT_MESSAGE") wait_for_session_threads(2) wait_for_session_threads(0) @pytest.mark.anyio async def test_exit_with_full_queue(server_factory: ServerFactoryFixture) -> None: """ Check that exiting the session doesn't deadlock when the background receive thread is blocked on a full events queue. """ async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() for _ in range(10): await websocket.send_text("SERVER_MESSAGE") try: await websocket.receive_text() except StarletteWebSocketDisconnect: pass with server_factory(websocket_endpoint) as socket: with httpx.Client(transport=httpx.HTTPTransport(uds=socket)) as client: with connect_ws("http://socket/ws", client, queue_size=1, keepalive_ping_interval_seconds=None) as ws: assert ws.receive_text() == "SERVER_MESSAGE" @pytest.mark.skipif(sys.version_info < (3, 13), reason="`Queue.shutdown()` is new in Python 3.13") @pytest.mark.anyio async def test_receive_after_exit(server_factory: ServerFactoryFixture) -> None: # pragma: no cover async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() try: await websocket.receive_text() except StarletteWebSocketDisconnect: pass with server_factory(websocket_endpoint) as socket: with httpx.Client(transport=httpx.HTTPTransport(uds=socket)) as client: with connect_ws("http://socket/ws", client, keepalive_ping_interval_seconds=None) as ws: pass with pytest.raises(WebSocketDisconnect): ws.receive(timeout=1) @pytest.mark.anyio async def test_concurrency_write(server_factory: ServerFactoryFixture) -> None: """ Check that there is no error because of two tasks trying to write the stream at the same time. Typically, this is when a background ping tries to send a ping while the main task is sending a message. See: https://github.com/frankie567/httpx-ws/issues/29 """ async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() while True: message = await websocket.receive_text() await websocket.send_text(message) with server_factory(websocket_endpoint) as socket: # Added for completeness, but were not able to reproduce the issue with the sync client with httpx.Client(transport=httpx.HTTPTransport(uds=socket)) as client: with connect_ws("http://socket/ws", client) as ws: with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor: for _ in range(10): executor.submit(ws.send_text, "CLIENT_MESSAGE") async with httpx.AsyncClient(transport=httpx.AsyncHTTPTransport(uds=socket)) as aclient: async with aconnect_ws("http://socket/ws", aclient) as aws: async with anyio.create_task_group() as tg: for _ in range(10): tg.start_soon(aws.send_text, "CLIENT_MESSAGE") @pytest.mark.anyio async def test_client() -> None: def handler(request: httpx.Request) -> httpx.Response: return httpx.Response(101, extensions={"network_stream": MagicMock(spec=NetworkStream)}) def async_handler(request: httpx.Request) -> httpx.Response: return httpx.Response(101, extensions={"network_stream": MagicMock(spec=AsyncNetworkStream)}) with httpx.Client(base_url="http://localhost:8000", transport=httpx.MockTransport(handler)) as client: ws_client = WebSocketClient(client) with ws_client.connect("http://socket/ws") as ws: assert isinstance(ws.response, httpx.Response) async with httpx.AsyncClient( base_url="http://localhost:8000", transport=httpx.MockTransport(async_handler) ) as aclient: async_ws_client = AsyncWebSocketClient(aclient) async with async_ws_client.connect("http://socket/ws") as aws: assert isinstance(aws.response, httpx.Response) pydantic-httpx2-6dd59b9/tests/httpx2/websockets/test_high_level.py000066400000000000000000000112171526547463400255110ustar00rootroot00000000000000from __future__ import annotations import subprocess import sys import threading from unittest.mock import patch import anyio import pytest import wsproto from starlette.websockets import WebSocket import httpx2 as httpx from httpcore2 import AsyncNetworkStream, NetworkStream from httpx2.websockets import AsyncWebSocketSession, WebSocketSession, _api from tests.httpx2.websockets.conftest import ServerFactoryFixture def test_importing_httpx2_does_not_import_wsproto() -> None: code = "import sys; import httpx2; assert 'wsproto' not in sys.modules" assert subprocess.run([sys.executable, "-c", code], capture_output=True).returncode == 0 def test_top_level_websocket_uses_a_dedicated_client() -> None: with patch.object(_api, "WebSocketClient") as mock_client: with httpx.websocket("http://socket/ws"): pass mock_client.return_value.connect.assert_called_once() client = mock_client.call_args[1]["client"] assert isinstance(client, httpx.Client) assert client.is_closed @pytest.mark.anyio async def test_client_websocket(server_factory: ServerFactoryFixture) -> None: async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() await websocket.send_text("SERVER_MESSAGE") await websocket.close() with server_factory(websocket_endpoint) as socket: with httpx.Client(transport=httpx.HTTPTransport(uds=socket)) as client: with client.websocket("http://socket/ws") as ws: assert ws.receive_text() == "SERVER_MESSAGE" async with httpx.AsyncClient(transport=httpx.AsyncHTTPTransport(uds=socket)) as aclient: async with aclient.websocket("http://socket/ws") as aws: assert await aws.receive_text() == "SERVER_MESSAGE" @pytest.mark.anyio async def test_client_websocket_forwards_request_params(server_factory: ServerFactoryFixture) -> None: async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() await websocket.send_text(websocket.headers.get("x-token", "")) await websocket.close() with server_factory(websocket_endpoint) as socket: with httpx.Client(transport=httpx.HTTPTransport(uds=socket)) as client: with client.websocket("http://socket/ws", headers={"x-token": "secret"}) as ws: assert ws.receive_text() == "secret" async with httpx.AsyncClient(transport=httpx.AsyncHTTPTransport(uds=socket)) as aclient: async with aclient.websocket("http://socket/ws", headers={"x-token": "secret"}) as aws: assert await aws.receive_text() == "secret" def test_receive_reassembles_fragmented_message() -> None: server = wsproto.connection.Connection(wsproto.connection.ConnectionType.SERVER) fragments = server.send(wsproto.events.TextMessage("FRAG", message_finished=False)) fragments += server.send(wsproto.events.TextMessage("MEN", message_finished=False)) fragments += server.send(wsproto.events.TextMessage("TED", message_finished=True)) class MockNetworkStream(NetworkStream): def __init__(self) -> None: self._sent = False self._closed = threading.Event() def read(self, max_bytes: int, timeout: float | None = None) -> bytes: if self._sent: self._closed.wait() return b"" self._sent = True return fragments def write(self, buffer: bytes, timeout: float | None = None) -> None: ... def close(self) -> None: self._closed.set() with WebSocketSession(MockNetworkStream()) as ws: assert ws.receive_text() == "FRAGMENTED" @pytest.mark.anyio async def test_async_receive_reassembles_fragmented_message() -> None: server = wsproto.connection.Connection(wsproto.connection.ConnectionType.SERVER) fragments = server.send(wsproto.events.TextMessage("FRAG", message_finished=False)) fragments += server.send(wsproto.events.TextMessage("MEN", message_finished=False)) fragments += server.send(wsproto.events.TextMessage("TED", message_finished=True)) class AsyncMockNetworkStream(AsyncNetworkStream): def __init__(self) -> None: self._sent = False async def read(self, max_bytes: int, timeout: float | None = None) -> bytes: if self._sent: await anyio.sleep_forever() self._sent = True return fragments async def write(self, buffer: bytes, timeout: float | None = None) -> None: ... async def aclose(self) -> None: ... async with AsyncWebSocketSession(AsyncMockNetworkStream()) as ws: assert await ws.receive_text() == "FRAGMENTED" pydantic-httpx2-6dd59b9/tests/httpx2/websockets/test_transport.py000066400000000000000000000401371526547463400254420ustar00rootroot00000000000000from __future__ import annotations import base64 import secrets from typing import Any import anyio import pytest import wsproto from anyio import CancelScope, ClosedResourceError, create_task_group from starlette.applications import Starlette from starlette.requests import Request from starlette.responses import PlainTextResponse from starlette.routing import Route, WebSocketRoute from starlette.websockets import WebSocket import httpcore2 as httpcore import httpx2 as httpx from httpx2.websockets import AsyncWebSocketSession from httpx2.websockets._api import aconnect_ws from httpx2.websockets._exceptions import WebSocketDisconnect, WebSocketUpgradeError from httpx2.websockets._transport import ( ASGIWebSocketAsyncNetworkStream, ASGIWebSocketTransport, Receive, Scope, Send, UnhandledASGIMessageType, UnhandledWebSocketEvent, ) @pytest.fixture def websocket_request_headers() -> dict[str, str]: return { "connection": "upgrade", "upgrade": "websocket", "sec-websocket-key": base64.b64encode(secrets.token_bytes(16)).decode("utf-8"), "sec-websocket-version": "13", } @pytest.fixture def scope(websocket_request_headers: dict[str, str]) -> Scope: return { "type": "websocket", "path": "/ws", "raw_path": "/ws", "root_path": "/", "scheme": "ws", "headers": [ ("host", "localhost"), *websocket_request_headers.items(), ], "subprotocols": [], "server": ("localhost", 8000), } @pytest.mark.anyio class TestASGIWebSocketAsyncNetworkStream: async def test_write(self, scope: Scope) -> None: received_messages = [] async def app(scope: Scope, receive: Receive, send: Send) -> None: await send({"type": "websocket.accept"}) message = await receive() received_messages.append(message) while message["type"] != "websocket.disconnect": message = await receive() received_messages.append(message) connection = wsproto.connection.Connection(wsproto.connection.CLIENT) async with ( create_task_group() as tg, ASGIWebSocketAsyncNetworkStream(app, scope, tg) as (stream, _), ): text_event = wsproto.events.TextMessage("CLIENT_MESSAGE") await stream.write(connection.send(text_event)) bytes_event = wsproto.events.BytesMessage(b"CLIENT_MESSAGE") await stream.write(connection.send(bytes_event)) close_event = wsproto.events.CloseConnection(1000) await stream.write(connection.send(close_event)) # Add a small delay to ensure the app has processed all messages await anyio.sleep(0.1) assert received_messages == [ {"type": "websocket.connect"}, {"type": "websocket.receive", "text": "CLIENT_MESSAGE"}, {"type": "websocket.receive", "bytes": b"CLIENT_MESSAGE"}, {"type": "websocket.disconnect", "code": 1000, "reason": ""}, ] async def test_write_unhandled_event(self, scope: Scope) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: await send({"type": "websocket.accept"}) await receive() connection = wsproto.connection.Connection(wsproto.connection.CLIENT) async with ( create_task_group() as tg, ASGIWebSocketAsyncNetworkStream(app, scope, tg) as (stream, _), ): with pytest.raises(UnhandledWebSocketEvent): ping_event = wsproto.events.Ping(b"PING") await stream.write(connection.send(ping_event)) async def test_read(self, scope: Scope) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: await send({"type": "websocket.accept"}) await send({"type": "websocket.send", "text": "SERVER_MESSAGE"}) await send({"type": "websocket.send", "bytes": b"SERVER_MESSAGE"}) await send({"type": "websocket.close", "code": 1000, "reason": ""}) connection = wsproto.connection.Connection(wsproto.connection.CLIENT) events = [] async with ( create_task_group() as tg, ASGIWebSocketAsyncNetworkStream(app, scope, tg) as (stream, _), ): for _ in range(3): data = await stream.read(4096) connection.receive_data(data) events = list(connection.events()) assert events == [ wsproto.events.TextMessage("SERVER_MESSAGE"), wsproto.events.BytesMessage(bytearray(b"SERVER_MESSAGE")), wsproto.events.CloseConnection(1000, ""), ] async def test_read_during_and_after_close(self, scope: Scope) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: await receive() await send({"type": "websocket.accept"}) await receive() received: list[bytes] = [] with anyio.fail_after(5): async with ( create_task_group() as tg, ASGIWebSocketAsyncNetworkStream(app, scope, tg) as (stream, _), ): async def read() -> None: received.append(await stream.read(4096)) tg.start_soon(read) await anyio.wait_all_tasks_blocked() await stream.aclose() with pytest.raises(httpcore.ReadError): await stream.read(4096) assert received == [b""] async def test_read_unhandled_asgi_message(self, scope: Scope) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: await send({"type": "websocket.accept"}) await send({"type": "websocket.foo"}) async with ( create_task_group() as tg, ASGIWebSocketAsyncNetworkStream(app, scope, tg) as (stream, _), ): with pytest.raises(UnhandledASGIMessageType): await stream.read(4096) async def test_enter_twice(self, scope: Scope) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: await send({"type": "websocket.accept"}) await receive() async with ( create_task_group() as tg, ASGIWebSocketAsyncNetworkStream(app, scope, tg) as (stream, _), ): with pytest.raises(RuntimeError, match="context manager twice"): async with stream: pass # pragma: no cover async def test_close_immediately(self, scope: Scope) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: await send({"type": "websocket.close", "code": 1000, "reason": ""}) with pytest.raises(ExceptionGroup) as excinfo: async with ( create_task_group() as tg, ASGIWebSocketAsyncNetworkStream(app, scope, tg), ): pass # pragma: no cover assert excinfo.group_contains(WebSocketDisconnect) async def test_denial_response(self, scope: Scope) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: await send({"type": "websocket.http.response.start", "status": 401, "headers": []}) await send({"type": "websocket.http.response.body", "body": b"Unauthorized"}) with pytest.raises(ExceptionGroup) as excinfo: async with ( create_task_group() as tg, ASGIWebSocketAsyncNetworkStream(app, scope, tg), ): pass # pragma: no cover assert excinfo.group_contains(WebSocketUpgradeError) error = excinfo.value.exceptions[0] assert isinstance(error, WebSocketUpgradeError) assert error.response.status_code == 401 assert error.response.content == b"Unauthorized" async def test_exception(self, scope: Scope) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: raise Exception("Error") with pytest.raises(ExceptionGroup) as excinfo: async with ( create_task_group() as tg, ASGIWebSocketAsyncNetworkStream(app, scope, tg), ): pass # pragma: no cover assert excinfo.group_contains(WebSocketDisconnect) error = excinfo.value.exceptions[0] assert isinstance(error, WebSocketDisconnect) assert error.code == 1011 assert error.reason == "Error" async def test_never_accepts(self, scope: Scope) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: return with pytest.raises(ExceptionGroup) as excinfo: async with ( create_task_group() as tg, ASGIWebSocketAsyncNetworkStream(app, scope, tg), ): pass # pragma: no cover assert excinfo.group_contains(RuntimeError) async def test_app_exception_with_closed_send_queue(self, scope: Scope) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: await send({"type": "websocket.accept"}) await receive() raise Exception("App error") async with ( create_task_group() as tg, ASGIWebSocketAsyncNetworkStream(app, scope, tg) as (stream, _), ): await stream._send_queue.aclose() await stream.send({"type": "websocket.receive", "text": "trigger"}) @pytest.fixture def test_app() -> Starlette: async def http_endpoint(request: Request) -> PlainTextResponse: return PlainTextResponse("Hello, world!") async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() await websocket.receive_text() await websocket.close() # pragma: no cover routes = [ Route("/http", endpoint=http_endpoint), WebSocketRoute("/ws", endpoint=websocket_endpoint), ] return Starlette(routes=routes) @pytest.mark.anyio class TestASGIWebSocketTransport: async def test_http(self, test_app: Starlette) -> None: async with ASGIWebSocketTransport(app=test_app) as transport: request = httpx.Request("GET", "http://localhost:8000/http") response = await transport.handle_async_request(request) assert response.status_code == 200 @pytest.mark.parametrize( "url,headers", [ ("ws://localhost:8000/ws", {}), ("wss://localhost:8000/ws", {}), ("http://localhost:8000/ws", {"upgrade": "websocket"}), ], ) async def test_websocket( self, url: str, headers: dict[str, Any], test_app: Starlette, websocket_request_headers: dict[str, str], ) -> None: async with ASGIWebSocketTransport(app=test_app) as transport: request = httpx.Request("GET", url, headers={**websocket_request_headers, **headers}) response = await transport.handle_async_request(request) assert response.status_code == 101 assert isinstance(response.extensions["network_stream"], ASGIWebSocketAsyncNetworkStream) @pytest.mark.parametrize("stream_count", [1, 3]) async def test_transport_exit_closes_stream_queues( self, stream_count: int, test_app: Starlette, websocket_request_headers: dict[str, str], ) -> None: async with ASGIWebSocketTransport(app=test_app) as transport: streams = [] for _ in range(stream_count): request = httpx.Request( "GET", "ws://localhost:8000/ws", headers=websocket_request_headers, ) response = await transport.handle_async_request(request) streams.append(response.extensions["network_stream"]) for stream in streams: with pytest.raises(ClosedResourceError): await stream._receive_queue.send({}) with pytest.raises(ClosedResourceError): await stream._send_queue.send({}) async def test_aclose_after_transport_exit_does_not_raise( self, test_app: Starlette, websocket_request_headers: dict[str, str], ) -> None: async with ASGIWebSocketTransport(app=test_app) as transport: request = httpx.Request("GET", "ws://localhost:8000/ws", headers=websocket_request_headers) response = await transport.handle_async_request(request) stream = response.extensions["network_stream"] await stream.aclose() @pytest.mark.anyio async def test_subprotocol_support() -> None: async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept("custom_protocol") assert websocket.scope.get("subprotocols") == ["custom_protocol"] await websocket.send_text("SERVER_MESSAGE") await websocket.close() app = Starlette( routes=[ WebSocketRoute("/ws", endpoint=websocket_endpoint), ] ) async with httpx.AsyncClient(transport=ASGIWebSocketTransport(app)) as client: async with aconnect_ws("ws://localhost:8000/ws", client, subprotocols=["custom_protocol"]) as ws: await ws.receive_text() assert ws.subprotocol == "custom_protocol" @pytest.mark.anyio async def test_keepalive_ping_disabled() -> None: async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() await websocket.receive_text() await websocket.close() # pragma: no cover app = Starlette( routes=[ WebSocketRoute("/ws", endpoint=websocket_endpoint), ] ) async with httpx.AsyncClient(transport=ASGIWebSocketTransport(app)) as client: async with aconnect_ws("ws://localhost:8000/ws", client) as ws: assert ws._keepalive_ping_interval_seconds is None @pytest.mark.anyio async def test_cancel_scope_integrity() -> None: async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() await websocket.receive_text() await websocket.close() # pragma: no cover app = Starlette( routes=[ WebSocketRoute("/ws", endpoint=websocket_endpoint), ] ) async with httpx.AsyncClient(transport=ASGIWebSocketTransport(app)) as client: with CancelScope(): async with aconnect_ws("ws://localhost:8000/ws", client): pass @pytest.mark.anyio async def test_close_session_from_another_task() -> None: async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() await websocket.receive() app = Starlette(routes=[WebSocketRoute("/ws", endpoint=websocket_endpoint)]) exit_requested = anyio.Event() with anyio.fail_after(5): async with httpx.AsyncClient(transport=ASGIWebSocketTransport(app), base_url="http://test") as client: async def connection(*, task_status: anyio.abc.TaskStatus[AsyncWebSocketSession]) -> None: async with client.websocket("/ws") as websocket: task_status.started(websocket) await exit_requested.wait() async with create_task_group() as task_group: websocket = await task_group.start(connection) await anyio.wait_all_tasks_blocked() await websocket.close() await anyio.wait_all_tasks_blocked() exit_requested.set() @pytest.mark.anyio async def test_receive() -> None: messages: list[str] = [] async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() messages.append(await websocket.receive_text()) await websocket.close() app = Starlette( routes=[ WebSocketRoute("/ws", endpoint=websocket_endpoint), ] ) async with httpx.AsyncClient(transport=ASGIWebSocketTransport(app)) as client: async with aconnect_ws("ws://localhost:8000/ws", client) as ws: await ws.send_text("RESULT") assert len(messages) == 1 assert messages[0] == "RESULT" pydantic-httpx2-6dd59b9/tests/test_benchmark.py000066400000000000000000000132741526547463400217400ustar00rootroot00000000000000from __future__ import annotations import gzip import json from typing import TYPE_CHECKING, Any import pytest import httpx2 from httpx2._decoders import GZipDecoder, LineDecoder if TYPE_CHECKING: from pytest_codspeed import BenchmarkFixture pytestmark = pytest.mark.benchmark TYPICAL_URL = "https://www.example.org:8443/path/to/resource?key=value&other=1#frag" HEADERS: list[tuple[str, str]] = [ ("host", "example.org"), ("user-agent", "httpx2-bench/1.0"), ("accept", "*/*"), ("accept-encoding", "gzip, deflate, br"), *[(f"x-custom-{i}", f"value-{i}") for i in range(16)], ] SMALL_JSON: dict[str, Any] = { "id": 12345, "items": [{"sku": f"SKU-{i}", "qty": i, "price": i * 1.5} for i in range(50)], } MEDIUM_JSON: dict[str, Any] = { "records": [ {"id": i, "name": f"record-{i}", "tags": [f"t{j}" for j in range(8)], "active": bool(i % 2)} for i in range(256) ], } MEDIUM_JSON_BODY = json.dumps(MEDIUM_JSON).encode() QUERY_STRING = "key=value&other=1&" + "&".join(f"f{i}={i}" for i in range(16)) GZIP_BODY = gzip.compress(MEDIUM_JSON_BODY) SET_COOKIE_HEADERS: list[tuple[str, str]] = [ ("set-cookie", f"session{i}=value{i}; Path=/; Domain=example.org; HttpOnly") for i in range(8) ] DIGEST_CHALLENGE = 'Digest realm="httpx@example.org", qop="auth", nonce="abc123nonce", opaque="xyz789opaque"' # --- Micro: pure httpx2 hot paths ------------------------------------------------- def test_bench_url_parse(benchmark: BenchmarkFixture) -> None: benchmark(httpx2.URL, TYPICAL_URL) def test_bench_url_join(benchmark: BenchmarkFixture) -> None: base = httpx2.URL(TYPICAL_URL) benchmark(base.join, "/path/to/resource?key=value") def test_bench_headers_construct(benchmark: BenchmarkFixture) -> None: benchmark(httpx2.Headers, HEADERS) def test_bench_headers_raw(benchmark: BenchmarkFixture) -> None: headers = httpx2.Headers(HEADERS) benchmark(lambda: headers.raw) def test_bench_headers_lookup(benchmark: BenchmarkFixture) -> None: headers = httpx2.Headers(HEADERS) benchmark(lambda: headers["accept-encoding"]) def test_bench_queryparams_parse(benchmark: BenchmarkFixture) -> None: benchmark(httpx2.QueryParams, QUERY_STRING) def test_bench_queryparams_merge(benchmark: BenchmarkFixture) -> None: params = httpx2.QueryParams(QUERY_STRING) benchmark(lambda: params.merge({"added": "1", "other": "2"})) def test_bench_gzip_decode(benchmark: BenchmarkFixture) -> None: def decode() -> bytes: decoder = GZipDecoder() return b"".join(decoder.decode(GZIP_BODY)) + b"".join(decoder.flush()) benchmark(decode) def test_bench_line_decoder(benchmark: BenchmarkFixture) -> None: text = "\n".join(f"line number {i} with some content" for i in range(256)) + "\n" def split() -> list[str]: decoder = LineDecoder() return decoder.decode(text) + decoder.flush() benchmark(split) def test_bench_sse_many_chunks_without_line_separator(benchmark: BenchmarkFixture) -> None: chunks = [b"data: ", *([b"A" * 16] * 10_000), b"\n\n"] request = httpx2.Request("GET", "https://example.org/sse") def decode() -> int: response = httpx2.Response( 200, content=iter(chunks), headers={"content-type": "text/event-stream"}, request=request, ) (event,) = list(httpx2.EventSource(response, max_event_size=None)) return len(event.data) assert benchmark(decode) == 10_000 * 16 def test_bench_extract_cookies(benchmark: BenchmarkFixture) -> None: request = httpx2.Request("GET", "https://example.org/") def extract() -> None: response = httpx2.Response(200, headers=SET_COOKIE_HEADERS, request=request) httpx2.Cookies().extract_cookies(response) benchmark(extract) def test_bench_digest_auth_flow(benchmark: BenchmarkFixture) -> None: challenge = httpx2.Response( 401, headers=[("www-authenticate", DIGEST_CHALLENGE)], request=httpx2.Request("GET", "https://example.org/path/to/resource"), ) def flow() -> None: auth = httpx2.DigestAuth(username="user", password="password123") generator = auth.sync_auth_flow(httpx2.Request("GET", "https://example.org/path/to/resource")) next(generator) try: generator.send(challenge) except StopIteration: pass benchmark(flow) def test_bench_request_json_post(benchmark: BenchmarkFixture) -> None: benchmark(lambda: httpx2.Request("POST", TYPICAL_URL, headers=HEADERS, json=SMALL_JSON)) def test_bench_request_multipart(benchmark: BenchmarkFixture) -> None: def build() -> None: request = httpx2.Request( "POST", "https://example.org/upload", data={"name": "value", "other": "field", "description": "a longer text field"}, files={"small": ("hello.txt", b"x" * 4096, "text/plain")}, ) request.read() benchmark(build) def test_bench_response_read_json(benchmark: BenchmarkFixture) -> None: def build() -> Any: response = httpx2.Response( 200, headers=[("content-type", "application/json")], content=MEDIUM_JSON_BODY, ) return response.json() benchmark(build) # --- Macro: end-to-end client cycle via MockTransport ----------------------------- def _json_handler(request: httpx2.Request) -> httpx2.Response: return httpx2.Response(200, content=MEDIUM_JSON_BODY, headers=[("content-type", "application/json")]) def test_bench_client_post_json(benchmark: BenchmarkFixture) -> None: with httpx2.Client(transport=httpx2.MockTransport(_json_handler)) as client: benchmark(lambda: client.post(TYPICAL_URL, json=MEDIUM_JSON).json()) pydantic-httpx2-6dd59b9/tests/test_benchmark_memory.py000066400000000000000000000025051526547463400233230ustar00rootroot00000000000000from __future__ import annotations from typing import TYPE_CHECKING import hpack import hyperframe.frame import pytest import httpcore2 if TYPE_CHECKING: from pytest_codspeed import BenchmarkFixture pytestmark = pytest.mark.benchmark H2_WINDOW = 2**31 - 1 H2_BODY = b"x" * (8 * 1024 * 1024) def _h2_server_frames() -> list[bytes]: return [ hyperframe.frame.SettingsFrame( settings={hyperframe.frame.SettingsFrame.INITIAL_WINDOW_SIZE: H2_WINDOW} ).serialize(), hyperframe.frame.WindowUpdateFrame(stream_id=0, window_increment=H2_WINDOW - 65535).serialize(), hyperframe.frame.HeadersFrame( stream_id=1, data=hpack.Encoder().encode([(b":status", b"200")]), flags=["END_HEADERS"], ).serialize(), hyperframe.frame.DataFrame(stream_id=1, data=b"", flags=["END_STREAM"]).serialize(), ] def test_bench_http2_send_large_body(benchmark: BenchmarkFixture) -> None: origin = httpcore2.Origin(b"https", b"example.com", 443) def send() -> int: stream = httpcore2.MockStream(_h2_server_frames()) with httpcore2.HTTP2Connection(origin=origin, stream=stream) as conn: response = conn.request("POST", "https://example.com/", content=H2_BODY) return response.status assert benchmark(send) == 200 pydantic-httpx2-6dd59b9/uv.lock000066400000000000000000025643411526547463400165470ustar00rootroot00000000000000version = 1 revision = 5 requires-python = ">=3.11" resolution-markers = [ "python_full_version >= '3.15' and implementation_name == 'cpython'", "python_full_version == '3.14.*' and implementation_name == 'cpython'", "python_full_version >= '3.15' and implementation_name != 'cpython' and sys_platform == 'emscripten'", "(python_full_version >= '3.13' and python_full_version < '3.15' and implementation_name != 'cpython' and sys_platform == 'emscripten') or (python_full_version == '3.13.*' and implementation_name == 'cpython' and sys_platform == 'emscripten')", "python_full_version == '3.12.*' and sys_platform == 'emscripten'", "python_full_version >= '3.15' and implementation_name != 'cpython' and sys_platform != 'emscripten'", "(python_full_version >= '3.13' and python_full_version < '3.15' and implementation_name != 'cpython' and sys_platform != 'emscripten') or (python_full_version == '3.13.*' and implementation_name == 'cpython' and sys_platform != 'emscripten')", "python_full_version == '3.12.*' and sys_platform != 'emscripten'", "python_full_version < '3.12'", ] [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" [options.exclude-newer-package] httpx2-jsfetch = "2026-08-08T00:00:00Z" idna = "2026-06-03T00:00:00Z" [manifest] members = [ "httpcore2", "httpx2", ] default-groups = ["bench", "dev", "docs"] [manifest.dependency-groups] bench = [ { name = "aiohttp", specifier = ">=3.14.3" }, { name = "pyinstrument", specifier = ">=5.1.3" }, { name = "zuvloop", marker = "python_full_version >= '3.14' and implementation_name == 'cpython'", specifier = ">=0.0.8" }, ] dev = [ { name = "chardet", specifier = ">=7.6.0" }, { name = "coverage", extras = ["toml"], specifier = ">=7.15.4" }, { name = "cryptography", specifier = ">=50.0.1" }, { name = "flaky", specifier = ">=3.8" }, { name = "httpcore2", extras = ["asyncio", "trio", "http2", "socks"], editable = "src/httpcore2" }, { name = "httpx2", extras = ["brotli", "cli", "http2", "socks", "ws", "zstd"], editable = "src/httpx2" }, { name = "mypy", specifier = ">=2.3.1" }, { name = "pytest", specifier = ">=9.1.0" }, { name = "pytest-codspeed", specifier = ">=5.0.3" }, { name = "pytest-httpbin", specifier = ">=2.1.0" }, { name = "pytest-trio", specifier = ">=0.8.0" }, { name = "ruff", specifier = ">=0.16.4" }, { name = "starlette", specifier = ">=1.6.0" }, { name = "trio", specifier = ">=0.34.0" }, { name = "trio-typing", specifier = ">=0.10.0" }, { name = "trustme", specifier = ">=1.2.1" }, { name = "twine", specifier = ">=7.0.0" }, { name = "uvicorn", specifier = ">=0.52.4" }, { name = "websockets", specifier = ">=16.1.1" }, { name = "werkzeug", specifier = ">=3.1.9" }, ] docs = [ { name = "mkdocstrings", extras = ["python"], specifier = ">=1.0.6" }, { name = "zensical", specifier = ">=0.0.57" }, ] [[package]] name = "aiohappyeyeballs" version = "2.6.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760, upload-time = "2025-03-12T01:42:48.764Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265, upload-time = "2025-03-12T01:42:47.083Z" }, ] [[package]] name = "aiohttp" version = "3.14.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohappyeyeballs" }, { name = "aiosignal" }, { name = "attrs" }, { name = "frozenlist" }, { name = "multidict" }, { name = "propcache" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, { name = "yarl" }, ] sdist = { url = "https://files.pythonhosted.org/packages/93/2f/6a91adaa2dc26877d6ed2f54c0370c8910f019db7d77c5c6a194611e93ea/aiohttp-3.14.4.tar.gz", hash = "sha256:831fc5bd39ec2517851e348f613ddb5447a47cf4b71cb09845af7ad7ed45d8f9", size = 8077839, upload-time = "2026-10-05T17:43:48.309Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/81/e3/998dc75634ecd2a24f33bab480b57313059d55bcadff8825a46b7c80a8af/aiohttp-3.14.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eb0093ca0817019d539f0d27bdf98e823944e05bb7efd9d2337a45b92e4d1b06", size = 832892, upload-time = "2026-10-05T17:38:16.373Z" }, { url = "https://files.pythonhosted.org/packages/58/c9/9bacc26397854440d169f70ae00ea51721f504611d3a64cf043643792c32/aiohttp-3.14.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f482dc9c8309801b4259dd218609d3dae0a7bcdedeac56d90500eabaa0c23465", size = 559893, upload-time = "2026-10-05T17:38:18.74Z" }, { url = "https://files.pythonhosted.org/packages/fa/f3/90c5856014328a8b1e9a753de794edea282182b776ff65f0602ad4ffa520/aiohttp-3.14.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aa800bb7c1d00e166493931f2ddacb982db913292503dc2f4884db1f2bc5f105", size = 552850, upload-time = "2026-10-05T17:38:20.385Z" }, { url = "https://files.pythonhosted.org/packages/9b/88/e71c29ce6daa78fcee0feb1992f0fdc408f09f42c3311b1f1c68c36f16ea/aiohttp-3.14.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d90e4dae71b26597f6d1fd12af7d092ae67551edf0e524b73e0687214b79ee33", size = 1928941, upload-time = "2026-10-05T17:38:22.218Z" }, { url = "https://files.pythonhosted.org/packages/3a/4f/f0f3bebfa521a2ce5fd4302c937701cbc50cd6d908beaa597388639b0b98/aiohttp-3.14.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5b681054b8c3b86aa6a0384b6ad7f5cb78dccbabab1f4a3a6793f98ad1378959", size = 1882092, upload-time = "2026-10-05T17:38:24.016Z" }, { url = "https://files.pythonhosted.org/packages/b5/0d/5df041fd25dceb4f4cafbbee49bb2c1e2d54a91aedecaf03b77cbb404c44/aiohttp-3.14.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6dfe80b41bcf8d80d2125fb99a171adeb86db2fcb35c1a68e0226acba0ba7f03", size = 1986051, upload-time = "2026-10-05T17:38:26.022Z" }, { url = "https://files.pythonhosted.org/packages/1a/07/e95eddafffef7c3a74446f67ac4e477a49cec2c78f2ab6c86d1acfd90d2d/aiohttp-3.14.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:71e4a59c6a8c5a6ae8b0b696c32635913e8f526cc01448762eaf5a3c59df8a4f", size = 2107840, upload-time = "2026-10-05T17:38:28.112Z" }, { url = "https://files.pythonhosted.org/packages/da/6c/1f83990fea249dcb10f48086726953546efc9199c96b6be7114532ac361f/aiohttp-3.14.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f887c3b7fb3058fc1ccd917f52078540c18d938d12018cb9edd64b6811d20c57", size = 1930721, upload-time = "2026-10-05T17:38:30.046Z" }, { url = "https://files.pythonhosted.org/packages/6f/d1/48184a186ea26df4f81dd466144dcab7f9cdd1e131bfee0f0e41278c6f0d/aiohttp-3.14.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0da4525e9ba145a11617d2cd7e44fe1acaf471f9c72a0cad28e72879c1020fbb", size = 1774508, upload-time = "2026-10-05T17:38:31.8Z" }, { url = "https://files.pythonhosted.org/packages/0f/ef/a9ec758c6d3850453838c31b56d1e4499eb47c80883753a12dcb203f9afa/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f7e8d3c5caa44fdbee3eba1aa1417aa58c74c95d4089fe3c451911117fcbb2f3", size = 1902311, upload-time = "2026-10-05T17:38:33.791Z" }, { url = "https://files.pythonhosted.org/packages/d6/49/9a2be54900f2dea6e63bbf9628fced604686a2e301130ccde0b1aa2e7e53/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:09092cf906c18c824b6b16881da5a89cc9cfa9b15344e496bcf880e9045bee33", size = 1912107, upload-time = "2026-10-05T17:38:35.614Z" }, { url = "https://files.pythonhosted.org/packages/a2/2b/151254abfc0fe5cbb8e6c41ad04d52122db0af176fb31dbf3bc44e081bda/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:dfd144837e92264878bba6d3a7ffa8206668b21e87748740afd45d193e48c87e", size = 1960207, upload-time = "2026-10-05T17:38:37.322Z" }, { url = "https://files.pythonhosted.org/packages/23/99/92c8dce336ac5784755a3144623528516f2e3b6b4871d02cad5a0642ae66/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:9413cffe4e0d654b9b524f9c99dde8cbdb37e0ed9a2c4edd2e63adbac6b374e8", size = 1760168, upload-time = "2026-10-05T17:38:39.214Z" }, { url = "https://files.pythonhosted.org/packages/66/3e/f05fd8d1a9595730db8d522882eea76429b9be2ed5337609f7c6e3d9d49c/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f50d719f97ba488dfb8e306cf8c8cc172ff0683ec0af53917b288229aa555ba5", size = 1979946, upload-time = "2026-10-05T17:38:40.927Z" }, { url = "https://files.pythonhosted.org/packages/b9/14/8941aa73ffceabc2a0eb26878b4f1b2958fb7b5358f97cc49b1c00ed9258/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:68ed4824d96b7afec1f3a8d7fba190fe282718041c5772e20298003e1e3e5d66", size = 1923375, upload-time = "2026-10-05T17:38:43.184Z" }, { url = "https://files.pythonhosted.org/packages/18/b5/ef275b63c8bfe0a21e7e8d3ef0e67c4745ed403f1894fe5205057cedd3b9/aiohttp-3.14.4-cp311-cp311-win32.whl", hash = "sha256:d7a41d1427136828e6b11d3f3fd194d4357d5205a5b610be7ae07b1ba52ab974", size = 488414, upload-time = "2026-10-05T17:38:44.978Z" }, { url = "https://files.pythonhosted.org/packages/e7/0b/21bdd70a1e072222d9dbd96bed4fbed26f7c46c5a20af11b78d32fd049d6/aiohttp-3.14.4-cp311-cp311-win_amd64.whl", hash = "sha256:2efbdb87e79d596325c4eefaef0f4495d701145e882351310ebc538e854dc7a3", size = 512755, upload-time = "2026-10-05T17:38:47.036Z" }, { url = "https://files.pythonhosted.org/packages/b7/4c/bb324a7d20a9598187bb028ca8d6bcf66c63589c8632420919dd576964ed/aiohttp-3.14.4-cp311-cp311-win_arm64.whl", hash = "sha256:ac6e6f90d9360e460c873f945f11dc8698db0a71fec6612823f1aaaab2c11faa", size = 492960, upload-time = "2026-10-05T17:38:49.006Z" }, { url = "https://files.pythonhosted.org/packages/22/02/db5935d45347fa8ede56b777930740fb0e72bbb4473ddb6ff8541f6f2afa/aiohttp-3.14.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:55b0b335982b0db7117dff7f6a8e3aad43c4105f9e392ca04f9fc8d958a95cce", size = 817689, upload-time = "2026-10-05T17:38:50.69Z" }, { url = "https://files.pythonhosted.org/packages/e6/56/f00aa46127e6342f019d567853eeeb932e04fb9b9424b5fb981ad68f4178/aiohttp-3.14.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2d0d8e435582b0d53009dac99e26a3d2be932ed7c9dbfcfc70f3fce1cf943bd5", size = 549599, upload-time = "2026-10-05T17:38:52.525Z" }, { url = "https://files.pythonhosted.org/packages/3f/bc/825c09b09962253a2103e4a88c04374ee939c0c8ea31c270daa0308efb07/aiohttp-3.14.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bf734016932d68e1324cfb638cac7a0866a83933a33badf15e836a7e24efb8c0", size = 548132, upload-time = "2026-10-05T17:38:54.629Z" }, { url = "https://files.pythonhosted.org/packages/40/80/8a1bc8036540fe7cb38219cc5c0aa67d32e9068165725e8199ea8200b08b/aiohttp-3.14.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:322e3d741b3133bcbb981a41d4f9b8ac3545c18de49c662c2b1f4e1c770b98ad", size = 1898485, upload-time = "2026-10-05T17:38:56.439Z" }, { url = "https://files.pythonhosted.org/packages/3c/fe/65b464d8520ace0d65b4ca69bc9abe175f842c8ce8d1522d363d9669903f/aiohttp-3.14.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:15a3bb5f90a4e515071f3617a45dfe26560beb834a6b6e108cdf4bc9e9719ec3", size = 1875334, upload-time = "2026-10-05T17:38:58.536Z" }, { url = "https://files.pythonhosted.org/packages/be/51/9c583be502720e927560a8414f4dfb7c7de41945e1a30ccf7003b93c6f85/aiohttp-3.14.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6c044e52df1a466af82cad3518c92ea80cc4ddcfea86966ff083bb34bab29bf4", size = 1937772, upload-time = "2026-10-05T17:39:00.376Z" }, { url = "https://files.pythonhosted.org/packages/a2/3d/b56512df7ea9cbb5f59099a6b375088dd578356a5a3fb27198ab82e19832/aiohttp-3.14.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d613d7d51bf06fe9a5e3aab86ce06d835bb0ceb1a31ea9e8766df4a403ae62a6", size = 2066220, upload-time = "2026-10-05T17:39:02.54Z" }, { url = "https://files.pythonhosted.org/packages/11/6c/a7a42701d9ea319140a3d44a24ec72a00b0b46d1b899b26d8a705e65bdd8/aiohttp-3.14.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5e93ab6e6330dce40f5b43996f1fc5f2543296d263a5e4b59ff09e73870b7d8", size = 1922895, upload-time = "2026-10-05T17:39:04.638Z" }, { url = "https://files.pythonhosted.org/packages/77/04/f8337bd824ca3fe3968d34dc5037ace1c4872551c4621f8266239311d301/aiohttp-3.14.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:20134dc8e68c67e7478124d516449428684c0545b2d3faa575691c8bcbd56678", size = 1712589, upload-time = "2026-10-05T17:39:06.671Z" }, { url = "https://files.pythonhosted.org/packages/fe/a6/d20e2c940b592d7c4a21690889dbff64fe0ca3facd9190696368694e1488/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f0daef5ef012369dddc391c61f604111424aa9a96313a69fb899018b09d1b01e", size = 1862251, upload-time = "2026-10-05T17:39:08.523Z" }, { url = "https://files.pythonhosted.org/packages/f5/e4/d50edd5ae5d024b380a8e892e333840bb22967a9eb9c8492108a403f678a/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:19290a108de0718b73bc69b86e788975c6a59855c671ebe2a98a07a6f968328f", size = 1895155, upload-time = "2026-10-05T17:39:10.305Z" }, { url = "https://files.pythonhosted.org/packages/c3/d3/f36f2931f807ccf8437ec15e8f8bfaa4748d4792639401cc767a866abaa0/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1494877625baeffab669f4a25a09ec4eea721b49e35363081a2a8e4231fe141f", size = 1906623, upload-time = "2026-10-05T17:39:12.411Z" }, { url = "https://files.pythonhosted.org/packages/5d/0a/94821b711493142bf5e11c27b0d7502776778f7792c77ecc6647357d20c1/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:a779ce4bf099ce4ad2cdfed62f1ca536d435f53237c54ff40172fddada24d1b5", size = 1698932, upload-time = "2026-10-05T17:39:14.446Z" }, { url = "https://files.pythonhosted.org/packages/d9/76/3d5a0d28362f0053c1c457024749911932481e8fd105fddf8305b1f93c81/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:0b4cec9fca876e2d4f4c6cb32b177390132d04618867689f43fefabf3f5c3980", size = 1934528, upload-time = "2026-10-05T17:39:16.354Z" }, { url = "https://files.pythonhosted.org/packages/a7/51/9784a21dc05d2e0f6acaf864f16db53dab0fbd7b0753cef168601eacb012/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:217707313e23aedde9bea67cf8365c7b138b549ae179121ef3f476cf67e3173a", size = 1901984, upload-time = "2026-10-05T17:39:18.299Z" }, { url = "https://files.pythonhosted.org/packages/44/4f/f98c88703e6d620243aa08473a946ca4e3756b6288690e38f0d9f9c1d007/aiohttp-3.14.4-cp312-cp312-win32.whl", hash = "sha256:18a9fb9a3f6e6e63f4d27f9adeef313a2d3c69a84d31170a844623824e722534", size = 480278, upload-time = "2026-10-05T17:39:20.206Z" }, { url = "https://files.pythonhosted.org/packages/b7/bc/8555013f84b53e4fdde423131b641af50e822c6d7d9118b24c52b31f6900/aiohttp-3.14.4-cp312-cp312-win_amd64.whl", hash = "sha256:69dcb02d33dfe415d5ee342cc63b7d320efcaf4b761701c7bd7bfb91c715481a", size = 506317, upload-time = "2026-10-05T17:39:22.706Z" }, { url = "https://files.pythonhosted.org/packages/21/3f/ca5bad7bfdaa7ddca053a044a1c7c0d4f3ad9d1f12f96dcab10bfb9c50e7/aiohttp-3.14.4-cp312-cp312-win_arm64.whl", hash = "sha256:d36b0263e7c2fbf1750b9f35d4e7e48b0442d8c45e4a89e3e74168821fb014bb", size = 487683, upload-time = "2026-10-05T17:39:24.482Z" }, { url = "https://files.pythonhosted.org/packages/23/ec/7fee140da700ec3f5aa5e0fd2319f67be5e86de197e2384d27e5e6209e0e/aiohttp-3.14.4-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:264b5a7568306590c44ae4a0237ad1715e35d447ea44ebf324e4c8fd9f78f67a", size = 539114, upload-time = "2026-10-05T17:39:26.322Z" }, { url = "https://files.pythonhosted.org/packages/4e/04/930c01ce9e186e787046433d7dc5b45b188885f8406c14b58435b4431974/aiohttp-3.14.4-cp313-cp313-android_24_x86_64.whl", hash = "sha256:17e5d7c7775d8dd8e894c7ef6ebfa26509de36868a9a6c7c4fcfaf6a1bf43d60", size = 553514, upload-time = "2026-10-05T17:39:28.104Z" }, { url = "https://files.pythonhosted.org/packages/2c/d7/983e3cea81c07e95f35d34da4d1e182b5c05489c49b7560b198a83f0da79/aiohttp-3.14.4-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:e91dc8fe9cbd052d16f7f1267e285cf8bbac4d2194bd5741f05ef201c77ed09e", size = 521381, upload-time = "2026-10-05T17:39:30.419Z" }, { url = "https://files.pythonhosted.org/packages/0e/2d/80baed11659093883f51245755105557d3253e45bd0b693d70df0059d68b/aiohttp-3.14.4-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:8df6157d31703972aec9e3b93963f039ff06318301e30b007c3e941ff8a7ac42", size = 528347, upload-time = "2026-10-05T17:39:32.344Z" }, { url = "https://files.pythonhosted.org/packages/c8/18/bfda255c311096c08dab26dc65f3d219f090df37dc5f5f6345f8c3aefc1f/aiohttp-3.14.4-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:220912b351549dc736c59d104dc443fa615753102bb778a4e98f86e4d94bff6a", size = 539914, upload-time = "2026-10-05T17:39:34.265Z" }, { url = "https://files.pythonhosted.org/packages/51/fc/3b6ca6117c0c42481d719411fff7b5d3970ebd906543d3dc1ba40fe2462f/aiohttp-3.14.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2efa42b39bb3f524d5eca3760639b584afdd1143a6b047fda29910ffb75e4993", size = 813997, upload-time = "2026-10-05T17:39:36.061Z" }, { url = "https://files.pythonhosted.org/packages/b5/f6/86e3e02a9712aadc1ae0a1076bb2d1adf3d9addfe5542a28190c8f9b6d9b/aiohttp-3.14.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7e7356059c8262d2c1fd95242e2b7b70fbc6eee3135bf470049cbec3e968b5b0", size = 548058, upload-time = "2026-10-05T17:39:38.109Z" }, { url = "https://files.pythonhosted.org/packages/85/7e/6b9c2e271419d40ca76589613b3c7ab185fd3050a407bd2565b6aa46f695/aiohttp-3.14.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fac247d0cc956d732df1211ac2d8a9999ec8dc1a92a90401de9d52e4ead546f7", size = 545933, upload-time = "2026-10-05T17:39:40.193Z" }, { url = "https://files.pythonhosted.org/packages/14/fc/33d6e24a5f8ac32423230088c415e2a1c6efee23d902b62f20506631e40b/aiohttp-3.14.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e2eb0f8b03b4f2bd154ed8cf7c1a119a1ad04808c258bf58f90138c83b8c6d5", size = 1888265, upload-time = "2026-10-05T17:39:42.182Z" }, { url = "https://files.pythonhosted.org/packages/8d/e8/2eca1d468d83a514621d1280f9992d08649191db2028c9236b4edfa7c723/aiohttp-3.14.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7fbe827d27e0e369fd7bb88ceeaa5b46ea006e73e015b9dd77e3723a53162293", size = 1872300, upload-time = "2026-10-05T17:39:44.195Z" }, { url = "https://files.pythonhosted.org/packages/d6/f6/5872983de71b0214acdfb86822f5cca295b39be4832ec589fa224aee0f6c/aiohttp-3.14.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a70387146d03af9f047c629b71aa27d9594b3b31ec4c9c91e1a73d0d8bf38e0e", size = 1926213, upload-time = "2026-10-05T17:39:46.199Z" }, { url = "https://files.pythonhosted.org/packages/ee/65/ebfefa11a546c33c717af63c67868408ecf0b33b23a9d75669af95485407/aiohttp-3.14.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0d0934926fc65744e2fdd44ce68b2d79d5ee608a1e23f0596b35dd696519bb7c", size = 2056609, upload-time = "2026-10-05T17:39:48.221Z" }, { url = "https://files.pythonhosted.org/packages/69/c0/70667e82ec041f4122a17afce711bbcf94a71bec5888b69a49aed8817be2/aiohttp-3.14.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ff4b366510c733974adb7a4102c094e4a6308e6f369315a4cf14d2d0a619cf82", size = 1914740, upload-time = "2026-10-05T17:39:50.304Z" }, { url = "https://files.pythonhosted.org/packages/bf/86/559e9dfea676206b20737d7ccb5b3716bff5e58d2a8d53682e5301724cd1/aiohttp-3.14.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:85fac7c99e0ac3dcbd6ae1c33774e0603bfc732ddb967a6fce4a731103c1888e", size = 1703390, upload-time = "2026-10-05T17:39:52.385Z" }, { url = "https://files.pythonhosted.org/packages/fc/91/c98897d4cf23e120b2f3980042835cb34c86bbe3c653f3eaacf4bf986349/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ef1e9c3b4a2300023a5dc865889ce532cfaf6798ba4ef78fbbefe738a9d23efa", size = 1852642, upload-time = "2026-10-05T17:39:54.391Z" }, { url = "https://files.pythonhosted.org/packages/14/13/0258f352cb2c236f358a5b57d138e15fa2566e17accc0758d968dbf2ceb6/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:97e65916588be0f952b3307aaa8460c0771fa98dbea2dd27dabc9f5d84d53c3b", size = 1890616, upload-time = "2026-10-05T17:39:56.466Z" }, { url = "https://files.pythonhosted.org/packages/64/3c/f43e294ce1a06d1234a97bd862c1aa31acfa1a0eea3786c22fd0dc1ea731/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:840775cb39a9424f9edf142133a1192263ac5bd79117ad2a16602cef6a0c1e9d", size = 1896638, upload-time = "2026-10-05T17:39:58.585Z" }, { url = "https://files.pythonhosted.org/packages/9f/f7/ce1e3a85b73d05037d729d3d32da7d6959b9e433435e9abd46c2fb38410f/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:54f9256430ca040d58affbd551513de13a5cff7d065204fc52b9a1b0af09a049", size = 1693003, upload-time = "2026-10-05T17:40:00.698Z" }, { url = "https://files.pythonhosted.org/packages/1d/72/45eb900d6a9ee046728f5589f3d07f5d78f049b5fb84f48881fa4174d5df/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:6112d5931bf12c776188cab81b82bbb17d86e2e1381f2ade6edc43e6b240f0cb", size = 1927730, upload-time = "2026-10-05T17:40:02.943Z" }, { url = "https://files.pythonhosted.org/packages/b2/43/a83ff79dc8375953a1f00b808a21c82590f4e68304fecccdcc42a25fb7d8/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:facc6df39047c4732cbd885bb62e40df20885fcd709fc399e11f81b45ce0fff9", size = 1891177, upload-time = "2026-10-05T17:40:04.989Z" }, { url = "https://files.pythonhosted.org/packages/5c/ba/fbdc41608d4e2fb6084d960a41b392fa82beb5b126c2466de549b5c67fc8/aiohttp-3.14.4-cp313-cp313-win32.whl", hash = "sha256:7968634fa3a967a2bc0b9aeba1d5a1955501dcd7d0de44b96f7ebfb662797735", size = 479943, upload-time = "2026-10-05T17:40:07.402Z" }, { url = "https://files.pythonhosted.org/packages/35/51/d75629750e705832fd5cd52516a82943ed58b6e09c30e14830f5d87452fa/aiohttp-3.14.4-cp313-cp313-win_amd64.whl", hash = "sha256:c0a894b0265d139cd4c2c8bd4643822cc289a4a5331e21e810881bd000ffb2dc", size = 506209, upload-time = "2026-10-05T17:40:09.49Z" }, { url = "https://files.pythonhosted.org/packages/02/64/66452d2ffcc13e5e5ee4ba4a968656fa4a98c29ed5ff0205d4fde02b2943/aiohttp-3.14.4-cp313-cp313-win_arm64.whl", hash = "sha256:da16c3037178e72589d91de59536d271dffc92c2be2b47c38a45538cba54fd29", size = 487163, upload-time = "2026-10-05T17:40:11.526Z" }, { url = "https://files.pythonhosted.org/packages/d2/fd/b653b1f969e2e949fe4726af7a8043e8ef117f202bed7757ac8564e077a1/aiohttp-3.14.4-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:749bfc43bb1df71bbe6ed215044d5412d786698fc5771d2037436ca49622f3c9", size = 540738, upload-time = "2026-10-05T17:40:14.109Z" }, { url = "https://files.pythonhosted.org/packages/90/b5/eea49a0bb697deffac5165d707ec53a24748d6720b3af77a544107b49573/aiohttp-3.14.4-cp314-cp314-android_24_x86_64.whl", hash = "sha256:c113e4b489d711f606ca278cd8dc89179746244ea841aa0638b1b134600afad0", size = 554494, upload-time = "2026-10-05T17:40:16.231Z" }, { url = "https://files.pythonhosted.org/packages/11/ea/cf8f4efbbfa8572d9965cd43b3c6c84c581aa006772e5ce3ab4020027e9b/aiohttp-3.14.4-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:50969522bc7022026a2c7968e67da5c789f6b716b988edac55dc630390efd5df", size = 522653, upload-time = "2026-10-05T17:40:18.879Z" }, { url = "https://files.pythonhosted.org/packages/a3/24/9f6721f0b52323789cb1041ffc3afa729462d9925607e733a065b6fc5e17/aiohttp-3.14.4-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:cbf92cd7a1c800cee244558dd5630abb45c1c1093ef7b0d546a99f526ff7a9eb", size = 529697, upload-time = "2026-10-05T17:40:21.296Z" }, { url = "https://files.pythonhosted.org/packages/9c/a4/399debc3c2ca0ab88a08e3082b4c4f62d0f66978af60243c63f2345ef337/aiohttp-3.14.4-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:fc76be08ff407fba717a769aff04ca1b4bf9ecfdcb5caadef84a563fdbbd146d", size = 540526, upload-time = "2026-10-05T17:40:23.548Z" }, { url = "https://files.pythonhosted.org/packages/a2/97/90379813b18b795bccdeb3a5a85e9b93ac2c69f9c2a5d0faba59da3ad6d1/aiohttp-3.14.4-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:9b416f995b68a921069e6ec61fa07f2ac3ff033d92e97a69f673af89f5bb954d", size = 818866, upload-time = "2026-10-05T17:40:25.842Z" }, { url = "https://files.pythonhosted.org/packages/78/70/824fd0dac819652f1df895b3f621a75bf0a3050c30e38d8d2316e34ab821/aiohttp-3.14.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2c9585101cfca10e74a07cc0ef2bdc6d90616e6750926b20456f429d0608f740", size = 549666, upload-time = "2026-10-05T17:40:28.523Z" }, { url = "https://files.pythonhosted.org/packages/8c/45/eafb2dd200dd2b770ed25a2dc5731c4ba5d58ab3fa8e2e82494bb946808e/aiohttp-3.14.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3c4dcf611b095e7983421f49d01ffbed7ed574891533d606ea115fc23e7c4e90", size = 548961, upload-time = "2026-10-05T17:40:30.613Z" }, { url = "https://files.pythonhosted.org/packages/a7/bc/6c733a1c71300293471ac7ef1dffd12b5b4dc9a43c53461224b2b8a7f667/aiohttp-3.14.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f8f61a9b5fa56c58e3441f9dc64137f786232d40fb89127190d0e0f84e1e5865", size = 1883165, upload-time = "2026-10-05T17:40:33.062Z" }, { url = "https://files.pythonhosted.org/packages/37/34/885ddbd351679a31141b25e0d1a5e4f67738806e564c858b399709b61239/aiohttp-3.14.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d43e538dfc85b705fd832620d050970ef5613b3869a7169b44a554b9dab9eee9", size = 1844119, upload-time = "2026-10-05T17:40:35.266Z" }, { url = "https://files.pythonhosted.org/packages/cc/ef/0a64dac53c11d569851efb3e7eddb43551df72b2c172ebb34cccc93bcd3f/aiohttp-3.14.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4135c4bb4b7682a7633fadc7170ea969d843f83aa7224e70111a20675105c985", size = 1930222, upload-time = "2026-10-05T17:40:37.527Z" }, { url = "https://files.pythonhosted.org/packages/69/5f/774792ed8f973e0d234fcb06b0f0bc9f29e9a0a0dd847f6418c2904be7d9/aiohttp-3.14.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9055324f156a94fdf6dc9a825ae60f9a2947b88f591ea81ee80826633de62ae7", size = 2038842, upload-time = "2026-10-05T17:40:39.815Z" }, { url = "https://files.pythonhosted.org/packages/cb/05/e00f35581c97656d9e864edaa03292382c620dd1d9c836a4f73a2279acc4/aiohttp-3.14.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fb22c8e4b60385a9b414c70c6e8b2d0f4b23ff7fc4bb572ceb58297b228169f1", size = 1887845, upload-time = "2026-10-05T17:40:42.359Z" }, { url = "https://files.pythonhosted.org/packages/ca/2e/07e3eff5b4c1b082a2eaf0ffb508b409b21ea1ddc9fdc57f3eabb51469a1/aiohttp-3.14.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3b6945559a260112742ed58cde2165488d2fc51aeea34afbaa99d9371b43e1b5", size = 1702533, upload-time = "2026-10-05T17:40:44.569Z" }, { url = "https://files.pythonhosted.org/packages/75/44/816844b7f876e6f8fee4ecb088269fcd92241da712e4814a4d624eda13a9/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8f4078a90b174f15efb2c8725e8720c40dbd3b2cf6350dbc085c964a938d9de7", size = 1849058, upload-time = "2026-10-05T17:40:47.818Z" }, { url = "https://files.pythonhosted.org/packages/ae/bd/163242e12464a1f3e58a77e28beca949652ddce84abdd5500a91c70a1e0d/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:f433c5654e32f72de3ef074d715eb5c7604eb6d28a5c2f3c9e5056f20fe6b306", size = 1854600, upload-time = "2026-10-05T17:40:50.401Z" }, { url = "https://files.pythonhosted.org/packages/f2/59/5c1ae708a89524eddfd9c727b87cae26b5c50c3c76683b910ac06151ead0/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:871035fe79c636b6bc126ed78df37d72b830dfc751612cb4b1040360edf2719f", size = 1896565, upload-time = "2026-10-05T17:40:52.625Z" }, { url = "https://files.pythonhosted.org/packages/37/45/95300a7de69241fe47d3f838f3fb582c712782e172d447ff650a013ea673/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2617132524f66338f6c1d218cd16081576aefc40df4f2bcba338a99fbf67fec1", size = 1693092, upload-time = "2026-10-05T17:40:54.862Z" }, { url = "https://files.pythonhosted.org/packages/ff/33/01a8e61d48d0094121092c74125df14c0f8f10ee3149bfe68b6f869409a9/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d8bc326133272deee8ef337581550450e4bb735c0520be893b950a1f5baaf41a", size = 1917073, upload-time = "2026-10-05T17:40:57.656Z" }, { url = "https://files.pythonhosted.org/packages/9e/d6/1a4f24624cda6686d5b927e26d5d1ae3ebb692faf88e93017fab4b391fd0/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3ec57223e261b7fa9979c12dbce009ca53439be76cac3af27f860d3e4b1d6f7a", size = 1872656, upload-time = "2026-10-05T17:41:00.123Z" }, { url = "https://files.pythonhosted.org/packages/be/be/ed286fcfa2d22061ae021b568c790123505cd482df35e23023339ecaed96/aiohttp-3.14.4-cp314-cp314-win32.whl", hash = "sha256:7242043e71fc449a19a47d92f4e9fd1e0ae8d3f88488982381f422bf6d651218", size = 485461, upload-time = "2026-10-05T17:41:02.686Z" }, { url = "https://files.pythonhosted.org/packages/c0/74/e040e6f65f4da305777f1adb3023d47401693489e4a337c983b52d2a0a6b/aiohttp-3.14.4-cp314-cp314-win_amd64.whl", hash = "sha256:019587c7b3a44917dd61bcb312fd5c034f341dc9851b83e7b41b65e08b68ca0f", size = 512147, upload-time = "2026-10-05T17:41:04.98Z" }, { url = "https://files.pythonhosted.org/packages/2e/5e/bddb33ae15fdd5a68a10a986587aa9916c418a712fdd110d3b3ae9b51407/aiohttp-3.14.4-cp314-cp314-win_arm64.whl", hash = "sha256:60dc71d38db0988f37e78f6ad4a010a2f6355cfac3fff5f130cf5ef2231f3f0d", size = 494685, upload-time = "2026-10-05T17:41:07.366Z" }, { url = "https://files.pythonhosted.org/packages/22/2e/7b884014b40573f919fc3a528e5028bc37b249e31a93928ba61bdd25c960/aiohttp-3.14.4-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:674f53ab9d2794e2dd767619a3384bf1006f8d075e43c19d449a645f8ff641c2", size = 855696, upload-time = "2026-10-05T17:41:09.514Z" }, { url = "https://files.pythonhosted.org/packages/5f/e6/b6e2b4f580ab6ae39241bb9182aca60e6e1915cdad0148faaa04db3f366b/aiohttp-3.14.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:6d243221f73e5ac546c2ed9255100423e4bc092b08b944f23498e8cf3096c26c", size = 567931, upload-time = "2026-10-05T17:41:11.685Z" }, { url = "https://files.pythonhosted.org/packages/63/99/ae8e3a1a18adcbf636839d18b3cccc51007836ccdae5209381c5cf82d1ae/aiohttp-3.14.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0daa016eb74e7888ed5f9ceec6eea3158999c1c4a115ef5cbe88baa8d924f94c", size = 567421, upload-time = "2026-10-05T17:41:13.836Z" }, { url = "https://files.pythonhosted.org/packages/63/38/c5d4bb58be72b967a4090d2deeb38571f8c992852936c51dbbbeae49db1c/aiohttp-3.14.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70c031a622aa20add05ebd234b90adaf6bf51c1c88cc305ec760721af83308c3", size = 2054173, upload-time = "2026-10-05T17:41:16.098Z" }, { url = "https://files.pythonhosted.org/packages/eb/87/3c8a9c7670f56d478a75c5bb84b336fb61a67b908e36c30a4a96ed8c8e86/aiohttp-3.14.4-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7df363fa7c38945a896e12c69af4a1a56cbd4152791d9e41fd0bac396b72de38", size = 1918296, upload-time = "2026-10-05T17:41:18.478Z" }, { url = "https://files.pythonhosted.org/packages/49/97/bd00e499c0a1505b44f5e23b9739034ea9be792ad42537f2894211ba1c07/aiohttp-3.14.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:02a508ba5ad91c4d730523584c0adc65882274bba5e37c33bc2f475e37577256", size = 2027513, upload-time = "2026-10-05T17:41:20.874Z" }, { url = "https://files.pythonhosted.org/packages/23/1d/a3666a7c224f86a881f18d673a8ffdc92fa4c35274fb4361822f8f0dc566/aiohttp-3.14.4-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0cb3edece6fe6a944eaf97d803b88f606da6bc1600b1894c2969e78ffdc1fc29", size = 2152686, upload-time = "2026-10-05T17:41:23.181Z" }, { url = "https://files.pythonhosted.org/packages/46/7e/f4204b8c4959c46f6367c182afbbacef08a1b53874281912c52fbd80151c/aiohttp-3.14.4-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:21ce1223b461bcc5fb389a7204001578f1c0b85c2da60a84d915ebb021294245", size = 2006431, upload-time = "2026-10-05T17:41:25.776Z" }, { url = "https://files.pythonhosted.org/packages/33/43/091e69d42967cbea833ceb355c5457f8f70748fe08b88c9d91491b3fafb8/aiohttp-3.14.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:35d5432f0dc1c8b71307e9112461b52f336da225e344283eec4779222c0a1dff", size = 1789101, upload-time = "2026-10-05T17:41:28.095Z" }, { url = "https://files.pythonhosted.org/packages/47/7b/b57cbe533c01098c5d30471f057e7c3c19f281122f756acc9c716b636e2c/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d6ec364493057c118d08292f7cd60865965c209167d8657b45643a26aef77495", size = 1974472, upload-time = "2026-10-05T17:41:30.499Z" }, { url = "https://files.pythonhosted.org/packages/9f/44/79acce03611450e4ed8594f96f1cea40d70bc84fb4e918f94d7d9454a4af/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:70492983b7aed9e61bda82fe1ce80bcba9199610886443133783a288638923c0", size = 1956340, upload-time = "2026-10-05T17:41:33.009Z" }, { url = "https://files.pythonhosted.org/packages/da/bb/36e6cbd6720e3377a02f8709aec6fe80de729ef41e78ba01f13d50363c73/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:a77776673331577147e9d25cd7833a72e8891b47556336cff06ba1569e488b99", size = 1965771, upload-time = "2026-10-05T17:41:35.506Z" }, { url = "https://files.pythonhosted.org/packages/69/0f/879735ac70ce5e6852916eed51c706a517b205150a8d384f9fa60933a3fc/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:73799000dd6fd5247094fd8e6d3e1eb871e41aab5cc35dff9d9f654cd230bc24", size = 1780297, upload-time = "2026-10-05T17:41:38.284Z" }, { url = "https://files.pythonhosted.org/packages/01/5d/7c030ca5b6baf3b02eccd11afc3d58f0b35e407031d5cc78cae9c24921c0/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:27b370fb532e707e8c96d04fa0c96301fb7dba2d50aaca57f6c456cdfffec5bd", size = 2001374, upload-time = "2026-10-05T17:41:40.888Z" }, { url = "https://files.pythonhosted.org/packages/80/1e/ddacbb8141d727034c51dd192d17749521d5b30b03f84aa034325396089e/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:884e0d1c707b6217fee3080b9b4029eee7551af788ee761010df19be158414b7", size = 1968531, upload-time = "2026-10-05T17:41:43.62Z" }, { url = "https://files.pythonhosted.org/packages/3a/08/2214f823701eebc3e57db141faeae76df7bfd415f254cc7c1692258f228d/aiohttp-3.14.4-cp314-cp314t-win32.whl", hash = "sha256:f2e3d34edb151d3e27f93a8338e2da33e2c7261cd4c879ce5f5fe280cc190ea5", size = 504126, upload-time = "2026-10-05T17:41:46.321Z" }, { url = "https://files.pythonhosted.org/packages/91/a1/90e9b6fd23310b4e82d0c0a37b5ecc2944053350473c57533c1da9647235/aiohttp-3.14.4-cp314-cp314t-win_amd64.whl", hash = "sha256:88cf889e51092537fe44adfbff96c2a22d6479d6f92b97b3d413fbfd0a4decf4", size = 531494, upload-time = "2026-10-05T17:41:48.849Z" }, { url = "https://files.pythonhosted.org/packages/97/ab/5b501472c92b9b1dc53742591d6210dccb262962f4721299300d3a9f664b/aiohttp-3.14.4-cp314-cp314t-win_arm64.whl", hash = "sha256:ca450c6d42fda7c0bfaf0e200f32f77c5f2c960a33be1e14d197c84588b7f5f6", size = 510544, upload-time = "2026-10-05T17:41:51.358Z" }, { url = "https://files.pythonhosted.org/packages/0f/77/ef165a197850573ea07c8d77bf5f4854a1db12fdb20e1cf0b218abf025fc/aiohttp-3.14.4-cp315-cp315-android_24_arm64_v8a.whl", hash = "sha256:3b10799df72f66c30935bc661cb89e5ac2918debfc575e350e226fbaa846cbb7", size = 540737, upload-time = "2026-10-05T17:41:53.761Z" }, { url = "https://files.pythonhosted.org/packages/e6/aa/1663f64d1316b3be9d3f6fafa02b8d888070171a6544cba515e82f3af595/aiohttp-3.14.4-cp315-cp315-android_24_x86_64.whl", hash = "sha256:7ffd7f9dd39caccc6b2f68ec0339435ecad2b20f6ea2e2b3de91bbe464ac7137", size = 554600, upload-time = "2026-10-05T17:41:56.183Z" }, { url = "https://files.pythonhosted.org/packages/98/f7/d4d535855123c1a774a798643e75fdfbac62c047b0c0729d6505d09df444/aiohttp-3.14.4-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:a0a7a227353f7693f73878ad14cd2623cafadd656ababcd20e2adfb7225172ea", size = 523184, upload-time = "2026-10-05T17:41:58.624Z" }, { url = "https://files.pythonhosted.org/packages/0a/5f/18a8d1cd2958a0b6164b047c18ccb192f2123bb70f1c0a145f6f01f858ad/aiohttp-3.14.4-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:1c43b6af8e4708e8b3812a9ee4f79895207e12d555b7f6d70deb838e0011e12d", size = 530342, upload-time = "2026-10-05T17:42:00.96Z" }, { url = "https://files.pythonhosted.org/packages/7f/c4/d1dd2b1fcf8a3192a431375b287a8762ebfd22195ab5b201d3fac30e3a7a/aiohttp-3.14.4-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:97416b2b997e5e9b817e322b2f0a89b76c54cde22471f51ac17ac15e10901ba0", size = 540629, upload-time = "2026-10-05T17:42:03.324Z" }, { url = "https://files.pythonhosted.org/packages/37/51/d1868f3459f618f6b68a6ef549d8b3f76aa616fa083298911fd3ae65d6b9/aiohttp-3.14.4-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:ee2a5aa31e507c17841d592364f2148393b17f83bc2766e9211e1eb31ea72a70", size = 819347, upload-time = "2026-10-05T17:42:05.713Z" }, { url = "https://files.pythonhosted.org/packages/84/e6/53179b721b67e0bd20974d02eca97b5691559e8ce666ba23a65aecda6b7f/aiohttp-3.14.4-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:5d5d9843c34866e986dd24eef713452609e304550c471320ce7b54b3cfb1391e", size = 549825, upload-time = "2026-10-05T17:42:08.093Z" }, { url = "https://files.pythonhosted.org/packages/00/0f/d67ddf7a43d4899176954511b6c048328abec1a5df4901f811a3b408a4fc/aiohttp-3.14.4-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:efcbf93e31b52c21665b6ebc489eb6fdb0dfd86b592edc677b5cffdfa7b11677", size = 549315, upload-time = "2026-10-05T17:42:10.766Z" }, { url = "https://files.pythonhosted.org/packages/9d/db/42f372c7f8e259505f239cb49db75f23548deaec56d22c68b4866f1c3fe2/aiohttp-3.14.4-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2f1a79977794592dcf6485ed964ec2448db527a1bc0c72ec89663658dad3a739", size = 1892181, upload-time = "2026-10-05T17:42:13.194Z" }, { url = "https://files.pythonhosted.org/packages/23/0d/8b1900216302a94f69b41bf0786bb992a6e67d703f4698e335c2442db615/aiohttp-3.14.4-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:515e7ac6d27509dc3ba2c35fb88970b00b9e7b07ee7cc947c8733dcd54ef5def", size = 1883513, upload-time = "2026-10-05T17:42:15.704Z" }, { url = "https://files.pythonhosted.org/packages/7b/5e/15c014313e567fff931ec4a5f81683cc40251257791fbd607ec37c0dad80/aiohttp-3.14.4-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:185154ffa3b54765b5de96f464f41cfa476f8815a03854ae5e0fe4d48fb06e9c", size = 1933283, upload-time = "2026-10-05T17:42:18.241Z" }, { url = "https://files.pythonhosted.org/packages/f5/b3/bf7dc39a450218efb1d5c692bac7dc85ef56da282e889bee594f3267211e/aiohttp-3.14.4-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6aece59f77959628a22cd2ffe48b102cda9611d680e090f204385b3998a1190f", size = 2041054, upload-time = "2026-10-05T17:42:20.728Z" }, { url = "https://files.pythonhosted.org/packages/b6/03/ffba18d7aaedb5eafac3f41f0c26621ebb0a740bb0115ea2fae1911d902b/aiohttp-3.14.4-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7205aa6589f1ad1306c6994ff2e1ab5efabacf938f9ffd7682fb225c197b06a", size = 1895494, upload-time = "2026-10-05T17:42:23.518Z" }, { url = "https://files.pythonhosted.org/packages/45/f4/68123365b86826eee82bdceb7fb4c429204cb3a104d6b7ae44bc6a543fcb/aiohttp-3.14.4-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f38c7b3ce60d55ac0f2a9fd2edc194789d043fefea15cfb7dcb40b7d5f561146", size = 1714098, upload-time = "2026-10-05T17:42:26.471Z" }, { url = "https://files.pythonhosted.org/packages/b1/db/b13c0b214afc571782e8667f3b9e0bbed6843397be90fa35acf2f3ecfbb0/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:b0a1274ee4ee6203c15a341cce87f9f3df8151d5496047b3608bb62bd969cffc", size = 1857111, upload-time = "2026-10-05T17:42:29.169Z" }, { url = "https://files.pythonhosted.org/packages/6b/7f/4f5d3cee3c23b57119aebba5174962fed0bc493f37f38edab2f5730411b6/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:69ce2407951516f413adf3132b88451eababd710ce631f83c81a9603a3640253", size = 1892123, upload-time = "2026-10-05T17:42:31.786Z" }, { url = "https://files.pythonhosted.org/packages/5e/2e/5a6a1f014c4e17d58d4e935d0dd64e612f4eaa2f33cca2475b48ca5e3fb5/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:b84d3d057c60eb8e0c2b457a1203e868d82709d3f0c272a4975dfd88c2414939", size = 1898809, upload-time = "2026-10-05T17:42:34.34Z" }, { url = "https://files.pythonhosted.org/packages/de/f3/d1cca5311a70fcc1c7c2082e02044578a69bcb10686db33a322df9fb849e/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:4ecc84f69c9e217984f6877e832e4786a74567432c0bf2b7512919fbdfe18ade", size = 1704814, upload-time = "2026-10-05T17:42:37.047Z" }, { url = "https://files.pythonhosted.org/packages/0a/cb/cd58eae366148a5b9b1baa233542151154f2b72cd32daa39fd9db97d0c0d/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:878f2d7950238b2b0a8cbb88054444a125f0cfbc77f54c811aca0483132a9be3", size = 1918390, upload-time = "2026-10-05T17:42:39.674Z" }, { url = "https://files.pythonhosted.org/packages/e3/d8/f5e6c4939432734033048ba631503edf4a1e693ee5e261773e169803bbe4/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:6ff9d3a0e6935f1cb0a6685f9f4b3f0d3e406456d7a434a03cf309b8cd5d7a2e", size = 1878321, upload-time = "2026-10-05T17:42:42.528Z" }, { url = "https://files.pythonhosted.org/packages/2b/71/462957d6b5d4eb208f78e67745c41480bad2e738aa7caf1d9b07536920c1/aiohttp-3.14.4-cp315-cp315-win32.whl", hash = "sha256:e07dfd7cd360f20be26dc2487ad4c7f21b0b39fdd593e9ebf37d2424ad52defb", size = 485536, upload-time = "2026-10-05T17:42:45.223Z" }, { url = "https://files.pythonhosted.org/packages/ba/6e/48f59266a8b8c6420894ff59b8e74175252da67df85967b96997e96b7092/aiohttp-3.14.4-cp315-cp315-win_amd64.whl", hash = "sha256:921fc4f1ad549091bfc39cb5e93925b04f307f83517756a3111843851130efce", size = 512087, upload-time = "2026-10-05T17:42:47.717Z" }, { url = "https://files.pythonhosted.org/packages/25/f5/46263b23cee4f312e28aaabbdec2e074c807700a12c9dfa18beff461f035/aiohttp-3.14.4-cp315-cp315-win_arm64.whl", hash = "sha256:5be8af106f96fd625f6c264fa9faaaa9e0104089684d9015d2fa5b6eba6407c7", size = 494709, upload-time = "2026-10-05T17:42:50.615Z" }, { url = "https://files.pythonhosted.org/packages/77/8d/e3b1d406c95a8fe436ae2e5f01ee9591196c6c22c44c645b24f20d73eaea/aiohttp-3.14.4-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:e69727ec04a4608200ff32ec29478299df7657e2eb78c416ae338d0ca6662596", size = 856014, upload-time = "2026-10-05T17:42:53.425Z" }, { url = "https://files.pythonhosted.org/packages/5d/fc/e9e78d1097830040bc0a4b8af073379f964064bfa7f0a852d774f96f3168/aiohttp-3.14.4-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:f8b658dd3ef2ebd7708b311ed96ff7cb5edaca001a30018a091504ef492bcb1c", size = 567724, upload-time = "2026-10-05T17:42:56.416Z" }, { url = "https://files.pythonhosted.org/packages/e6/ad/c813a705a1da1c111c30723b52e1efb67763e9f0b3b54a418cb419616e7a/aiohttp-3.14.4-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:3749e018123df1205161a73ba96d336e17e9cf6b947295e53a43571de420e7b1", size = 567888, upload-time = "2026-10-05T17:42:59.048Z" }, { url = "https://files.pythonhosted.org/packages/c2/1f/7676f46aa24554a45686853c61552d02d67ade2b4c51adfe8b2ec4fdecd2/aiohttp-3.14.4-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8f28a3c4fca436b2e594090e7cd22558f5e93a30ca18516c436de982da6fc25a", size = 2054356, upload-time = "2026-10-05T17:43:01.781Z" }, { url = "https://files.pythonhosted.org/packages/44/79/b9ef7d7442061e0a3125990d6021230b30361a972f7b8ebfb011042877ce/aiohttp-3.14.4-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e099aae21246992a1d84303ff262262d054c474e46cace33b0d5a69810c71877", size = 1937678, upload-time = "2026-10-05T17:43:04.492Z" }, { url = "https://files.pythonhosted.org/packages/5c/98/5927a31540c8e6d0542effead5bd5c56e749a9d99d84e902fb80ae906ef8/aiohttp-3.14.4-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fafb521891e646d9cf5da89f01c75e7159d08be7254a024149630a698be28251", size = 2026705, upload-time = "2026-10-05T17:43:07.353Z" }, { url = "https://files.pythonhosted.org/packages/62/bd/1be001ed97dcfa57a292188c38979fb78be795b960b50f02660587bffa06/aiohttp-3.14.4-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1d385db2cd154bce0b3dd451cf2a52bec91ebb7be2c3a5d06b14b4391631d807", size = 2147075, upload-time = "2026-10-05T17:43:10.141Z" }, { url = "https://files.pythonhosted.org/packages/0b/f7/d59628ccedd7c86db4c1f904467d1c80fed6cc10a1831ed5d75ff12e5a71/aiohttp-3.14.4-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ae8a244889d8a53549851bf595b9f382f64acca57e8762da1ecb26ba786828f7", size = 2005016, upload-time = "2026-10-05T17:43:12.848Z" }, { url = "https://files.pythonhosted.org/packages/3c/dc/472db3ab1daafa12a61d7f83314f85f502b99c143c78d66554a5e24361fd/aiohttp-3.14.4-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:681dde68ff8d8d5e7d5abcad4feb45bfb457a218310c919825e21fc36cac3d0b", size = 1796363, upload-time = "2026-10-05T17:43:15.562Z" }, { url = "https://files.pythonhosted.org/packages/08/61/6f9834b131b9a42e30d68c469c196033d3cae2d8fe340d4668f362c4fd1f/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:b91a6441fcaed88ca7bca67726b189332df3ceb6ac0dfc98dcb9654bb723288c", size = 1974240, upload-time = "2026-10-05T17:43:18.884Z" }, { url = "https://files.pythonhosted.org/packages/b5/2f/b8eb2a276685ef1da7f7bc15348404b8b9ee12b8f32f2cd8895385cd1589/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:f15dbbac49bc15eaff95c0b8166525c4050996af578c7be141e145f40ee2cf24", size = 1973387, upload-time = "2026-10-05T17:43:21.661Z" }, { url = "https://files.pythonhosted.org/packages/5b/32/ad559b2d6817e85f7cb294d8641e975e64b526f4da98ffe941c9af67a047/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:7abae043e87692d1c2adda1fab501bb0612d28c4a23eb082005c1e684f792dac", size = 1968766, upload-time = "2026-10-05T17:43:24.544Z" }, { url = "https://files.pythonhosted.org/packages/60/67/4a16e398140bdabb363428b9f439af3f77706a6df8bea6e626bbde53c2ab/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:21f4624fb1051fc1aa10d57a636a80e829f7d0417462d6f1ce380b08fe1a904c", size = 1788193, upload-time = "2026-10-05T17:43:27.467Z" }, { url = "https://files.pythonhosted.org/packages/a9/38/17b326da7f52e530a675d789ade3e727a1b3db9959722f6049b9c392321a/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:2e8dc3a0fdaf9d12b954d3d06cc4c355d91b17fb6c671715b593624ca4c379f8", size = 1999645, upload-time = "2026-10-05T17:43:30.32Z" }, { url = "https://files.pythonhosted.org/packages/53/dc/91b87961250010e05eb3adabaf0d98e4229ee7543147c265e834922e1b0b/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:1410b6f6e3d52ea7c02c950496522ce6e85d5543bf154bc80a6141e505251cfa", size = 1970998, upload-time = "2026-10-05T17:43:33.364Z" }, { url = "https://files.pythonhosted.org/packages/72/66/9bcf2c2db7b75a3b51c11470ceb67941d028727d674276ff5d5120adc87e/aiohttp-3.14.4-cp315-cp315t-win32.whl", hash = "sha256:a65189a89f3e621f7c27a968b5131bbca29126e2b8517dc72b205747a39d4c96", size = 504036, upload-time = "2026-10-05T17:43:36.212Z" }, { url = "https://files.pythonhosted.org/packages/e2/20/349db4af12dbc16070d32028d30c2067123b4520f3dcb2d9013524efeb4f/aiohttp-3.14.4-cp315-cp315t-win_amd64.whl", hash = "sha256:2b2c95f5f769eec92b552969db1f79ea0282058ce5131ed0f2fa540b4af3f14e", size = 531284, upload-time = "2026-10-05T17:43:39.362Z" }, { url = "https://files.pythonhosted.org/packages/26/21/544c711bc5fad611278ebd153bdcab1bffce8b8581f8ec9096b275948a3c/aiohttp-3.14.4-cp315-cp315t-win_arm64.whl", hash = "sha256:54209fff79346ee1ef0d5cbf92fa80a5bb37396406bb4d932e5107f9c29b2d3f", size = 510623, upload-time = "2026-10-05T17:43:42.15Z" }, { url = "https://files.pythonhosted.org/packages/2b/27/5e1f8446545be98e9416af59c396b1ed1f9f3294afb0a40ee3a709889273/aiohttp-3.14.4-py3-none-any.whl", hash = "sha256:5c6758ba62aea282c537179cfc8474a90f2b5f7b089cc5ff66d8920d86a9bfdd", size = 279487, upload-time = "2026-10-05T17:43:44.905Z" }, ] [[package]] name = "aiosignal" version = "1.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "frozenlist" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload-time = "2025-07-03T22:54:43.528Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, ] [[package]] name = "anyio" version = "4.14.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/61/cc/a381afa6efea9f496eff839d4a6a1aed3bfafc7b3ab4b0d1b243a12573dd/anyio-4.14.2.tar.gz", hash = "sha256:cfa139f3ed1a23ee8f88a145ddb5ac7605b8bbfd8592baacd7ce3d8bb4313c7f", size = 260176, upload-time = "2026-07-12T20:29:07.082Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/da/35/f2287558c17e29fafc8ef3daf819bb9834061cfa43bff8014f7df7f63bdc/anyio-4.14.2-py3-none-any.whl", hash = "sha256:9f505dda5ac9f0c8309b5e8bd445a8c2bf7246f3ce950121e45ea15bc41d1494", size = 125813, upload-time = "2026-07-12T20:29:05.763Z" }, ] [[package]] name = "ast-serialize" version = "0.6.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/58/ad/0d70a3a2d6e01968d985415259e8ec7ad3f777903f9b1c1f3c8c44642c60/ast_serialize-0.6.0.tar.gz", hash = "sha256:aadd3ffcf4858c9726bf3515f7b199c7eadbe504f96028e4a87172c0da65a8fe", size = 61489, upload-time = "2026-06-30T20:02:55.555Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/3f/12/3e5f575f156555547c250a8b0d1347517a3a20fc7f4492e9703a69d4f45e/ast_serialize-0.6.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:a7520b672827885bafeae7501f684d14d47d17e5f45256f9df547686cca52264", size = 1177640, upload-time = "2026-06-30T20:02:06.708Z" }, { url = "https://files.pythonhosted.org/packages/a2/a4/921a9e27951627983b0f368859ea00f8330a551dc0bf4c2fdcb11855a98b/ast_serialize-0.6.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a14191beec7e0c078d2fc1f6edc0aee88bcd4db9f18e1bc9f8052b559c22dddc", size = 1168111, upload-time = "2026-06-30T20:02:08.366Z" }, { url = "https://files.pythonhosted.org/packages/00/69/950cf404de7b8782cf95e5c1237e25e2aa46177b287f39f9eeddf481fd6f/ast_serialize-0.6.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32ef62ec34cf6be20ad77d4799556638fbdf187f3ae10698dfb20ef9f2c89516", size = 1227656, upload-time = "2026-06-30T20:02:09.843Z" }, { url = "https://files.pythonhosted.org/packages/4c/a8/46f8f6a6479d9d2273980957bb091a506c55f5b95d3c029ee58518a78407/ast_serialize-0.6.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:13b7769970a39983b0adf2f38917b1cd3b8946f76df045756c3d741bc689f089", size = 1227706, upload-time = "2026-06-30T20:02:11.367Z" }, { url = "https://files.pythonhosted.org/packages/b7/b9/9ac415bda0a40e49eab8fea3b2741c19c98bb84d57d62c4cfc6230eb67be/ast_serialize-0.6.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6f7a408601bb3edaefb3bc67a4c01f5235e3253653b6a5729a2ee2382b35341c", size = 1431705, upload-time = "2026-06-30T20:02:12.737Z" }, { url = "https://files.pythonhosted.org/packages/e5/06/8807115d441444879f7561b5eede5ac18fc80392f11826d61ccf31f503b1/ast_serialize-0.6.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8670bfa51208a2c0c8d138928e40e998fab158f9200d53bb80c088b5b8eda7b8", size = 1249533, upload-time = "2026-06-30T20:02:14.571Z" }, { url = "https://files.pythonhosted.org/packages/3e/c0/c2ba82ef9618650357d9421a1fdb27ffec862a7f57e8e2de82a3ccd11e12/ast_serialize-0.6.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4826809eb8597a8cd59fd924b6d7c285b8969a1e0007e2cb652cab62376270f", size = 1252619, upload-time = "2026-06-30T20:02:16.219Z" }, { url = "https://files.pythonhosted.org/packages/0f/a7/fa31d52dd4102cede29fb9634e98d214129b2783b4f95528c6dc6a8f6587/ast_serialize-0.6.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:577a6c189068686869f5f1ddc38363f3ae1808a4753b577266f9202071a7bb66", size = 1242983, upload-time = "2026-06-30T20:02:17.813Z" }, { url = "https://files.pythonhosted.org/packages/b1/20/ddf742b5ad3c4bafd3466f2265037cfd99bc1b9a5ee46a5d58c90d523242/ast_serialize-0.6.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:085de7f62dc9cc247eb01e965a362707d1d90b1d89a82c5bf78301a60a3c417b", size = 1296148, upload-time = "2026-06-30T20:02:19.146Z" }, { url = "https://files.pythonhosted.org/packages/24/cb/9f6f217cce8b3b632c5568b478d195a35e79dce4dbe309438cb89ba6ea4f/ast_serialize-0.6.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:9f8a8b78b13173de6a9ec22111d9be674874cd5bdccda04f14ae5ebc2bef403a", size = 1403826, upload-time = "2026-06-30T20:02:20.696Z" }, { url = "https://files.pythonhosted.org/packages/2d/f8/9d16d4f0107a183924425cc0e7618d8bf76f96b45afa9ff19f924ed1ad57/ast_serialize-0.6.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:f2ff3baffc3a29c1f15bc9098aa0c09763410262d5e6cef42116f7356c184554", size = 1502943, upload-time = "2026-06-30T20:02:22.034Z" }, { url = "https://files.pythonhosted.org/packages/80/dd/bbc1c38756350dddf7e24acae1c9482ef42051c267417e019aecc1ed4075/ast_serialize-0.6.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:0067b25fce104eaae5b88383de9ab803faeb671831e14ca698b771b356e2600f", size = 1497632, upload-time = "2026-06-30T20:02:23.517Z" }, { url = "https://files.pythonhosted.org/packages/42/7e/9daffefcf5b97e6bb4c3e0b3c024c1aee9722f23d3cf7cd2ff80d6fb4a40/ast_serialize-0.6.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c617417f9cbb0cb144f6283c3cbe0d2e0f01beaf9f608f662b21191058a626ec", size = 1448858, upload-time = "2026-06-30T20:02:24.889Z" }, { url = "https://files.pythonhosted.org/packages/e5/1f/f9baaab81a677ea0af7d2458cac2f94ebcc85958f8a3c15ba9d9e5dab653/ast_serialize-0.6.0-cp314-cp314t-win32.whl", hash = "sha256:5337cb256dcea3df9288205213d1601581536526b8f4da44b6974f1180f3252a", size = 1052600, upload-time = "2026-06-30T20:02:26.263Z" }, { url = "https://files.pythonhosted.org/packages/9e/1f/41b535866519512d8cf6669cb2cff7823b7672bb6279c0333b4ff89d7d9f/ast_serialize-0.6.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2d947e45cafc4b09bd7528917fa84c517654a43de173c79785574b7b3068ac24", size = 1095570, upload-time = "2026-06-30T20:02:27.639Z" }, { url = "https://files.pythonhosted.org/packages/50/64/e472fe3e3a2d33d874b987e8518aedf24562919e3b6161a4fa1797e89c0f/ast_serialize-0.6.0-cp314-cp314t-win_arm64.whl", hash = "sha256:6e15ec740436e1a0d62de848641abe5f3a2f89a7f94907d534795ac91bbacf14", size = 1067267, upload-time = "2026-06-30T20:02:28.949Z" }, { url = "https://files.pythonhosted.org/packages/52/19/ac8348ae8711c9b5ae834634f635780cab62a0f5e6f988882e048b89c2ae/ast_serialize-0.6.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:093cb8bb91b720d8523580498d031791bb1bbaa048599c3d21085d380e11a596", size = 1185367, upload-time = "2026-06-30T20:02:30.427Z" }, { url = "https://files.pythonhosted.org/packages/c1/f6/ec7ec652c51db77c2f61d8573338e13e4704303265ccc658cb4031d9f354/ast_serialize-0.6.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:e61580a69faf47e3689795367ed211f2a10fd741478cc0f36a0f128793360aad", size = 1178657, upload-time = "2026-06-30T20:02:31.964Z" }, { url = "https://files.pythonhosted.org/packages/6f/02/613a7534a41d0122f37d1e0c64aa8ac78bfb831f8c92f6db057a311abb3c/ast_serialize-0.6.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:305802f2ce2a7c4e87835078ea85c58b586ddda8095b92fe2ead9364ae19c80a", size = 1238620, upload-time = "2026-06-30T20:02:33.664Z" }, { url = "https://files.pythonhosted.org/packages/4d/21/087957bba486242afc52f49b2d9e21c9dad00289356cf9efe67084015a9d/ast_serialize-0.6.0-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c7b8b8f0c42f752ea00b2b7d7c090b3f80d9c1c5c75cadf16423790a0cc74081", size = 1236075, upload-time = "2026-06-30T20:02:34.936Z" }, { url = "https://files.pythonhosted.org/packages/82/04/78128bbb170071c2c72a210a181f1c00e11cc1cec60a8beef747b07f9201/ast_serialize-0.6.0-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd5b91b9e6f2356ace3a556963b0cd783b395fbbb0bb17b4defc283415466e77", size = 1441348, upload-time = "2026-06-30T20:02:36.245Z" }, { url = "https://files.pythonhosted.org/packages/64/64/62fb99d6faf199b4c3e5b08a07136e9a0d7664bb249c6de3670e5b63e9b6/ast_serialize-0.6.0-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4d6ef91590258ada18909b9caea344dac4de2013906b035473cd674a43f4b790", size = 1258580, upload-time = "2026-06-30T20:02:37.53Z" }, { url = "https://files.pythonhosted.org/packages/ca/87/b4d6c38e0ccd5e85dc54cecdf933a152c60b28fe5d993a6d8a72fa6d5896/ast_serialize-0.6.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcbed41e9386059fc0261d602445ede0976c2ecec2939688bcbcb9ed0b6f28b7", size = 1261693, upload-time = "2026-06-30T20:02:39.123Z" }, { url = "https://files.pythonhosted.org/packages/0e/4b/3676ca2191f39bafb75f93f99b2f429ec464586158fece2165f3572805dc/ast_serialize-0.6.0-cp39-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:cdc4e6f930b9090c2f92c9036ad12ffb8e6e44d4a5ba06f1458a05d60f203f7b", size = 1252517, upload-time = "2026-06-30T20:02:40.511Z" }, { url = "https://files.pythonhosted.org/packages/f3/58/494ef8c4b4acb2f4a265ac934caf45f792a08fe27d6b853de35ad991941a/ast_serialize-0.6.0-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:897ac47b5637be41c0c07061c8a912fafa967ef1dc73fa115e4bfa70882a093b", size = 1304843, upload-time = "2026-06-30T20:02:41.961Z" }, { url = "https://files.pythonhosted.org/packages/b1/f2/13736d920ab3d49bbee80ef1a277dd7b7aaf3b3545efd9d2a8114fe05525/ast_serialize-0.6.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c4af9a1386166e40ed01464991806f89038a2d89782576c7774876fa77034e32", size = 1413698, upload-time = "2026-06-30T20:02:44.179Z" }, { url = "https://files.pythonhosted.org/packages/a8/5a/e046f3899e2acba4677d7427b76431443a1aa1a0e583dfb05b55b69d55cf/ast_serialize-0.6.0-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:c901adbd750029b9ac4ad3d6aa56853e0ad4875119fbf52b7b8298afc223828b", size = 1512209, upload-time = "2026-06-30T20:02:45.584Z" }, { url = "https://files.pythonhosted.org/packages/cc/c7/e42aaca7bb2d22a7c06d5a8c7930086c5a334e93d716e6fa5e6647a4515f/ast_serialize-0.6.0-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:3ae22a366b752ab4496191525b78b097b5b72d531752e3c1dd7e383a8f2c8a1a", size = 1508464, upload-time = "2026-06-30T20:02:46.942Z" }, { url = "https://files.pythonhosted.org/packages/95/93/5524a3dc6c3f593de3228ed9cbef73afa047625b7000ec21b7f58e6eb4d4/ast_serialize-0.6.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:4ed29121da8b3fdc291002801a1de0f76248fa07dce89157a5f277842cf6126e", size = 1457164, upload-time = "2026-06-30T20:02:48.294Z" }, { url = "https://files.pythonhosted.org/packages/4f/c0/36a6ffb4d653cf621427b4c4928671f53ad800c453474de2b82564a44ad9/ast_serialize-0.6.0-cp39-abi3-pyemscripten_2026_0_wasm32.whl", hash = "sha256:b1dac4e09d341c1300ba69cdcbe62867b32a8c75d90db9bf4d083bec3b039f0b", size = 863014, upload-time = "2026-06-30T20:02:49.742Z" }, { url = "https://files.pythonhosted.org/packages/09/c7/7d5ad8b49e1278e1c2a1e0274bd7850560b3f09313aa00c13bc8d5544792/ast_serialize-0.6.0-cp39-abi3-win32.whl", hash = "sha256:82c312a7844d2fdeb4d5c48bd3d215bf940dafd4704e1a9bcf252a99010a99b1", size = 1063165, upload-time = "2026-06-30T20:02:50.98Z" }, { url = "https://files.pythonhosted.org/packages/47/ae/6710c14ecb276031cf10249f6adf5a59e2d3fdb3b5183bd59f70524067ee/ast_serialize-0.6.0-cp39-abi3-win_amd64.whl", hash = "sha256:113b58346f9ceb664352032770caca817d4a3c86f611c6088e6ef65ddaa70f0e", size = 1101444, upload-time = "2026-06-30T20:02:52.554Z" }, { url = "https://files.pythonhosted.org/packages/66/40/c53deb2cd0c9b0fb636d24d9f40924cf2e65028e6b20b10cd5c1eeb2c730/ast_serialize-0.6.0-cp39-abi3-win_arm64.whl", hash = "sha256:ccd132fe8db56f61fe743b1f644d01b8d65b83248a8da506f3132bda86d6ed5e", size = 1072965, upload-time = "2026-06-30T20:02:54.097Z" }, ] [[package]] name = "async-generator" version = "1.10" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/ce/b6/6fa6b3b598a03cba5e80f829e0dadbb49d7645f523d209b2fb7ea0bbb02a/async_generator-1.10.tar.gz", hash = "sha256:6ebb3d106c12920aaae42ccb6f787ef5eefdcdd166ea3d628fa8476abe712144", size = 29870, upload-time = "2018-08-01T03:36:21.69Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/71/52/39d20e03abd0ac9159c162ec24b93fbcaa111e8400308f2465432495ca2b/async_generator-1.10-py3-none-any.whl", hash = "sha256:01c7bf666359b4967d2cda0000cc2e4af16a0ae098cbffcb8472fb9e8ad6585b", size = 18857, upload-time = "2018-08-01T03:36:20.029Z" }, ] [[package]] name = "attrs" version = "26.1.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/9a/8e/82a0fe20a541c03148528be8cac2408564a6c9a0cc7e9171802bc1d26985/attrs-26.1.0.tar.gz", hash = "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32", size = 952055, upload-time = "2026-03-19T14:22:25.026Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309", size = 67548, upload-time = "2026-03-19T14:22:23.645Z" }, ] [[package]] name = "backports-tarfile" version = "1.2.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/86/72/cd9b395f25e290e633655a100af28cb253e4393396264a98bd5f5951d50f/backports_tarfile-1.2.0.tar.gz", hash = "sha256:d75e02c268746e1b8144c278978b6e98e85de6ad16f8e4b0844a154557eca991", size = 86406, upload-time = "2024-05-28T17:01:54.731Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b9/fa/123043af240e49752f1c4bd24da5053b6bd00cad78c2be53c0d1e8b975bc/backports.tarfile-1.2.0-py3-none-any.whl", hash = "sha256:77e284d754527b01fb1e6fa8a1afe577858ebe4e9dad8919e34c862cb399bc34", size = 30181, upload-time = "2024-05-28T17:01:53.112Z" }, ] [[package]] name = "backports-zstd" version = "1.6.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/8e/b5/5a873da082bd08acd6a497f7aae224e94a7c27fa8f24488089cc50a16c84/backports_zstd-1.6.0.tar.gz", hash = "sha256:80a7859ffe70bf239d7a2ce15293bdeb5b4280ff7dc326ffab312b0e254dbb24", size = 1000009, upload-time = "2026-06-14T10:50:58.555Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/c5/90/428dd82228b1b6d62d5a1bf312c29e6c125af6a182fcfd82768ca179dcc7/backports_zstd-1.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c4fc41b2df5529cad5ceb230319e82728096d4b353ce8d4df68a2ec37e291bb8", size = 437067, upload-time = "2026-06-14T10:49:28.335Z" }, { url = "https://files.pythonhosted.org/packages/ef/48/768edf21fe33bae8d874470b1be136681d4d32eb820a32e1c98262ebe39b/backports_zstd-1.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:83391ef5935cc0f329b1abca414ae20ffe40d335fc21a4b5e664f08a74317d5f", size = 363454, upload-time = "2026-06-14T10:49:29.784Z" }, { url = "https://files.pythonhosted.org/packages/29/8a/d462c2e5071eb573378f0d26760f6590613086fdf59c2d3c66bdfffb9f41/backports_zstd-1.6.0-cp311-cp311-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:7d3f64c503af7b60115b97c16feaf75bd191ef2c978d5c0c7725a6682bef63c5", size = 507393, upload-time = "2026-06-14T10:49:31.077Z" }, { url = "https://files.pythonhosted.org/packages/b9/cb/af58363b0dd0b497282ecef1fa99789b03cc1885a01a41394cad42ceeff6/backports_zstd-1.6.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0308990ffc998df3c7ed35276bde049728b5c3956203cae40d80893576a41459", size = 476957, upload-time = "2026-06-14T10:49:32.53Z" }, { url = "https://files.pythonhosted.org/packages/e4/fd/5fbdf2275cefae95c4b3509f6db2dc372d0587ebafea342d28781d51d932/backports_zstd-1.6.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8c298785e2fadeab82342040f2d9ce764ce500e6da6a6d99a2de514e63580b5a", size = 582618, upload-time = "2026-06-14T10:49:33.723Z" }, { url = "https://files.pythonhosted.org/packages/99/6f/7dd45c53c907ea67f635c3900b58bb3347c01dc2ded441402028aae0ef9c/backports_zstd-1.6.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ae106fe16e36efc60ab098d02478d30aa0e31e1420eb4ecf0116459253bc6361", size = 642279, upload-time = "2026-06-14T10:49:34.938Z" }, { url = "https://files.pythonhosted.org/packages/4d/25/a9e37dd035027565fa0b7e367da50e88a6ab26e7fd413269aa118e25258b/backports_zstd-1.6.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7293fefe15f0e5852bdb4ad1e0e26f3cbd4d3e61c19f751ecc4ff34bc1eb237d", size = 492486, upload-time = "2026-06-14T10:49:36.06Z" }, { url = "https://files.pythonhosted.org/packages/a1/52/659686bf8f7c53ea279e1c44038504b82a6901cee2f5ae83c30bbf581301/backports_zstd-1.6.0-cp311-cp311-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ece8e7288db5b827ef8c64b2f78519f1a173a8991a625978fce02eccd7654fe9", size = 566440, upload-time = "2026-06-14T10:49:37.536Z" }, { url = "https://files.pythonhosted.org/packages/d9/1a/c7ea5a0ff607a1a6066bb7c7cb65ae20e2f85da6adc69ab77fd8943e180c/backports_zstd-1.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:28eef3881164f3c23ce58ed59e4684103bdd279583eb2d299858c9e9b72fde9a", size = 482899, upload-time = "2026-06-14T10:49:38.805Z" }, { url = "https://files.pythonhosted.org/packages/83/48/bd2b91100ee4fe6bb4d816e3659cbbb0cda5dd32760d2379c54d1752ec25/backports_zstd-1.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:481a1e9bd8f419fdc625307aa20234687f99368c75df511ef589693c5fea4c6f", size = 510826, upload-time = "2026-06-14T10:49:40.062Z" }, { url = "https://files.pythonhosted.org/packages/25/fe/fa28509d7ce2ad59404e7ce738a2fd858e12dfd9a896629f10330222a7fb/backports_zstd-1.6.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:3b6713371f8987a1178df93cb36f29eef191f224021e2d656b2f11ce60d26816", size = 586941, upload-time = "2026-06-14T10:49:41.305Z" }, { url = "https://files.pythonhosted.org/packages/45/28/757daf2399aa71bb37f9f7f48b42ab03fc51c340eccfad2fec92a23f6aa3/backports_zstd-1.6.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:b0ddbcd2866b8ff1a2836e4b0e4d44788f5b992d83fac75a38cda8f9a2bee079", size = 564261, upload-time = "2026-06-14T10:49:42.49Z" }, { url = "https://files.pythonhosted.org/packages/4e/53/9b9db30cb2c148a69c40ad7647aa787338041f3dc81c5b22113286e590e9/backports_zstd-1.6.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2914abea516704bdafb2090acd3f15b5f9debecfabd15b8dd8285b2ad3b92209", size = 632869, upload-time = "2026-06-14T10:49:43.981Z" }, { url = "https://files.pythonhosted.org/packages/81/a4/1692fbb88af8aaf900a53619fcc95c9e45d9ff162223a47fd672a9893c8d/backports_zstd-1.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:dd085eafa2aac6f883afd28210a3231f717f25409a1e44a39bb7b04c8c5b5646", size = 496496, upload-time = "2026-06-14T10:49:45.118Z" }, { url = "https://files.pythonhosted.org/packages/93/42/c5a66c47320bd12ce84a7341330ea582d67069bdb70214bca0b6bf394cfd/backports_zstd-1.6.0-cp311-cp311-win32.whl", hash = "sha256:b81b4cf3d6e0ad7ac92bef248f49fafc954262c5fb0f7e19d6aac497e5a856b2", size = 291613, upload-time = "2026-06-14T10:49:46.473Z" }, { url = "https://files.pythonhosted.org/packages/2a/f2/f22c19b4cdde429805ff5ac8dd77a95569a7c4cb8991741b2ff0d538f220/backports_zstd-1.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:10b61850c4112952e05aa6e6cce8c9a5936fbeadb321e154216705cc76a14afa", size = 329078, upload-time = "2026-06-14T10:49:47.71Z" }, { url = "https://files.pythonhosted.org/packages/ef/dc/e902a3f1eb92c4907b5f47f90cb3c2734ee315c4ff67179fc111343b45ba/backports_zstd-1.6.0-cp311-cp311-win_arm64.whl", hash = "sha256:068ef3d8c18815a2e3a752f766313e19910e7c50939b956923748d9c04ebcb1b", size = 291727, upload-time = "2026-06-14T10:49:48.929Z" }, { url = "https://files.pythonhosted.org/packages/1e/bb/009af3a9532d4cc66d5385391c512210fae32ab2442605f26aca1d8d2957/backports_zstd-1.6.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0466b14723f3b7697669c00ee66fe16e30e25636b286b0a923fa86fa3d8a753c", size = 437407, upload-time = "2026-06-14T10:49:50.155Z" }, { url = "https://files.pythonhosted.org/packages/0c/76/f7c02efde81ebb9993586f9e435d2fd1191a6f806f640e4eeb8d004493ed/backports_zstd-1.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1d146926e997d2d3de8212bdcbf4985344a2622ca3bec458d8908000a84fd883", size = 363519, upload-time = "2026-06-14T10:49:51.383Z" }, { url = "https://files.pythonhosted.org/packages/2e/5e/0cf66f12472fe3e082cc4134395a7e0b8746cfb30aabd74251ce8fafa9a7/backports_zstd-1.6.0-cp312-cp312-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:460fd6b3f338c659507ae36cfd6b58ac9942a2ff233c5cf574416dfec0451a84", size = 507756, upload-time = "2026-06-14T10:49:52.497Z" }, { url = "https://files.pythonhosted.org/packages/03/95/7ed25c90369360f96f8bfa961540845e063377c32a43b775201af66a588c/backports_zstd-1.6.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7c2b1f4a640c51130caa92cef5bf72bd3c3dbbcfbf814c37403aa0601b1811b0", size = 477578, upload-time = "2026-06-14T10:49:53.887Z" }, { url = "https://files.pythonhosted.org/packages/e3/75/f16b1d3e33ca396525847c81d96e3de7bc74d2c6f9ca2ddee76b0c450697/backports_zstd-1.6.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:beb43e9885202c8d4f3762319ed4d5e98e197622afbff8439fbbdd81d08938b9", size = 583029, upload-time = "2026-06-14T10:49:55.132Z" }, { url = "https://files.pythonhosted.org/packages/e1/2b/a17b111b631e1c79a0e570881c1a266c661b936585afa395435a458b1991/backports_zstd-1.6.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fbb746522ebfc11155f1cd688e2c48ef3d74125e38b63eabdaab068a055c3e88", size = 641741, upload-time = "2026-06-14T10:49:56.42Z" }, { url = "https://files.pythonhosted.org/packages/6b/b2/d17b2722c636d64b4e77ddc68d8d0625719d39f94021be8719a218af4c0a/backports_zstd-1.6.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a99710fbb225d459d66def4dc2bb2cd4a9a0bdc8b799fc0621cfdd863be9c93", size = 495554, upload-time = "2026-06-14T10:49:57.652Z" }, { url = "https://files.pythonhosted.org/packages/63/12/2853e8b6c03f03795b6548ea61f82cc104d4f7ff2523a04bc69f46984663/backports_zstd-1.6.0-cp312-cp312-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f69365ee2b836939137de024a302395a1cb8654fb6dc5ffef6381105259c8f87", size = 570027, upload-time = "2026-06-14T10:49:59.003Z" }, { url = "https://files.pythonhosted.org/packages/18/aa/83f37b81f3b8c6ea035bf260ec374648bd59372894c02323dc9de3cbdf77/backports_zstd-1.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:66cf8038893c7708ec345ffb3ac63c775d10f430f323ac2f0334fdb6a397c57c", size = 483594, upload-time = "2026-06-14T10:50:00.49Z" }, { url = "https://files.pythonhosted.org/packages/f5/6a/d77f8cd2ff642d3b3652c1ccab5b6583114dbf10f8cb0143531357c83998/backports_zstd-1.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e514c71ca72f3b56bd8fbda1a6a5b7d1100a2764b42a3c74a38841f25f9b00ab", size = 511206, upload-time = "2026-06-14T10:50:01.86Z" }, { url = "https://files.pythonhosted.org/packages/56/b2/99a60fe4d1aac8053769d2463271d5df37a7c11c387072fdbb0b16aed7f7/backports_zstd-1.6.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7741e44f7938ec94f9a52678c8d19b7bc548522ffdc39c9e4481af8db545fa9a", size = 587416, upload-time = "2026-06-14T10:50:03.236Z" }, { url = "https://files.pythonhosted.org/packages/ec/1e/a9c003fe4d14bd4bf671598d4c7dcc1cef51e3513d9d7111ba1d07b6f07b/backports_zstd-1.6.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:97e8a9674652496c7612b528085dd5a296c052a2edc466ca1bfb7b0b27820413", size = 567615, upload-time = "2026-06-14T10:50:04.524Z" }, { url = "https://files.pythonhosted.org/packages/ec/b9/955bd604f692c550c7cb66d00bd7691ead5c86df8ebd23d7254eeaa90789/backports_zstd-1.6.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:23a793f2fed4dbf0517319759a2cded0b0dd8e8d3797fe30badd5693e320c175", size = 632269, upload-time = "2026-06-14T10:50:05.86Z" }, { url = "https://files.pythonhosted.org/packages/18/d7/9f61f612f8a4193484c78a1f26db82a50141234189885113ef0085a8a961/backports_zstd-1.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b951113113ed4b8d173418a4f155c14b739dace626b3fa3f82be1831958d39e4", size = 500066, upload-time = "2026-06-14T10:50:07.446Z" }, { url = "https://files.pythonhosted.org/packages/81/a3/19fb8c48d94139481c5ccaf2fb54c31b543fa635fd7bd7399aadd15752ac/backports_zstd-1.6.0-cp312-cp312-win32.whl", hash = "sha256:6430b34a2ae6fcc604672f4f913102563473d9a015bdca1ce8c95041cc1f2677", size = 291825, upload-time = "2026-06-14T10:50:08.762Z" }, { url = "https://files.pythonhosted.org/packages/58/38/40ba081c6c71f0f22c64d3d54b912ad75a4e6812caa1397cbb15b5693b12/backports_zstd-1.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:08793876172551a930ce4d65c712cd516184d1a97070d4a1193e05bf0cf7040d", size = 329201, upload-time = "2026-06-14T10:50:09.979Z" }, { url = "https://files.pythonhosted.org/packages/2b/6c/f7116dd2edc6f960545f0d8616939eae3a20031b3b6669697d4f9fd83b2e/backports_zstd-1.6.0-cp312-cp312-win_arm64.whl", hash = "sha256:03b7c59c71f7a597e2bcb3f8368371e9a660a1bdf1c37afc1f1ad1496a013c19", size = 291901, upload-time = "2026-06-14T10:50:11.198Z" }, { url = "https://files.pythonhosted.org/packages/38/06/c430537d59c55d49bcd15ecf4b1aa965453219caad810a4f2b484816f4be/backports_zstd-1.6.0-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:2ace939e4d620e119423606f2d3d7115f8707733bf57f279ad9a9383f875986f", size = 400327, upload-time = "2026-06-14T10:50:12.446Z" }, { url = "https://files.pythonhosted.org/packages/36/48/2f8323bb0e3ebba88b54877a2979afeb83983fb2ca572f09ad61aae2d3a0/backports_zstd-1.6.0-cp313-cp313-android_24_x86_64.whl", hash = "sha256:4c68a9ed2df0cca51d774c521e68a34d2e3d9ebfc687ef8096adfd4f345b551d", size = 454276, upload-time = "2026-06-14T10:50:13.667Z" }, { url = "https://files.pythonhosted.org/packages/7c/39/87a665244a65f5b87a06b848c29a8cce07e91d59c5988ee2a32c0293a21c/backports_zstd-1.6.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:30576f49b82328ec8af16c11100efe52ca88526f71bbe100ef6b4e707dc13bf2", size = 357457, upload-time = "2026-06-14T10:50:14.906Z" }, { url = "https://files.pythonhosted.org/packages/7f/8b/854d4a47bb8b7a48bfb2ed381c7b03a70efb4fc49f0e4a1509b38a2e1727/backports_zstd-1.6.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:b4bddfcfb6679215d6f4dc5f79a1f9301af339480d70527a14b57a1f2e6b6cbf", size = 366139, upload-time = "2026-06-14T10:50:16.399Z" }, { url = "https://files.pythonhosted.org/packages/8f/de/c3af43eb8df6f2581e157e18a3e0121eadb826055b2fde3f91ec188689cb/backports_zstd-1.6.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:65048ed08c5124f05ff9f355ab9703014bb2dbe7f8d9948ce193685b1775f442", size = 446683, upload-time = "2026-06-14T10:50:17.633Z" }, { url = "https://files.pythonhosted.org/packages/5c/39/87cf3d883d386c10ac52f5322604fb9afdd204229f4c47d4a820a839b8ff/backports_zstd-1.6.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5918fc6b31437208721276964323933cd86077b8d5b469c59c1b3fd2c8220a05", size = 436869, upload-time = "2026-06-14T10:50:19.113Z" }, { url = "https://files.pythonhosted.org/packages/5e/b6/9479e6f0f18824ad38e8d7dd85161ab0842a198be669421232925bb30960/backports_zstd-1.6.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4b6c8b02ab0ccb2431bb7bc238be91d158b308915e7b07937388e540466fe7e7", size = 363090, upload-time = "2026-06-14T10:50:20.302Z" }, { url = "https://files.pythonhosted.org/packages/d9/74/a5e98fe108e17c91d9bc590a19e77f5d47d579e34d3f5bc098a949d6c27c/backports_zstd-1.6.0-cp313-cp313-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:711e6b98f8924e8b4a61ff97ab6321f33de024e1ed6a32f5123763aeda8459be", size = 507070, upload-time = "2026-06-14T10:50:21.536Z" }, { url = "https://files.pythonhosted.org/packages/69/f5/392bb7dce7363b77bc5403060f418fad438b9cfdd3edd10d65cee7d8fd11/backports_zstd-1.6.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2ba9ac10fc393e5123a08802e0e895a107cb4a66b9973d2844dbd8a343111e59", size = 477200, upload-time = "2026-06-14T10:50:22.91Z" }, { url = "https://files.pythonhosted.org/packages/e4/4d/dfb665806ba4f74bc48071d32006843b53568c4a17ff627a3061de5eaa09/backports_zstd-1.6.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2f723219335387d7546412d8141e0303590600949b4184a1391a0c6a3c756058", size = 582724, upload-time = "2026-06-14T10:50:24.28Z" }, { url = "https://files.pythonhosted.org/packages/57/b2/beeca7393a8310debd82ee2f0ce5c1801e8d7cb673f7f226f4a0866ca238/backports_zstd-1.6.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:64b94d7a836568926a3309ff510c7f8261b881b341fd4992cabf4f0998878f8a", size = 643493, upload-time = "2026-06-14T10:50:25.736Z" }, { url = "https://files.pythonhosted.org/packages/38/26/ce90e9eed6f25aaa4a4fa305a2aaf2d2ad81fd69de8eb248ddd91c80d1e0/backports_zstd-1.6.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e39258a09b1c7ca70b5e94a5c5ccfe4700b4250b8077cfeab31d0f79565d4c9b", size = 492190, upload-time = "2026-06-14T10:50:27.205Z" }, { url = "https://files.pythonhosted.org/packages/17/9b/37b9b146df1f5452419a96071a7017cbac212ec9b137d7a88ca46dc2aa9e/backports_zstd-1.6.0-cp313-cp313-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:15b1aae0f64cd742df4bba1d989d0a09a6ec619202543fdba684640454541fd3", size = 567432, upload-time = "2026-06-14T10:50:28.386Z" }, { url = "https://files.pythonhosted.org/packages/06/66/81b30991be83237529f36335ac3682bce26409064b906ac6122874575196/backports_zstd-1.6.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:25b5ddc789480072551af571a746e9500356b2aff0499861cf2ca07ea7431e68", size = 483021, upload-time = "2026-06-14T10:50:29.654Z" }, { url = "https://files.pythonhosted.org/packages/49/2a/792c65dcc1e45eb0c1bdc012ee94b84867186bfe27a860d0813bd216f03b/backports_zstd-1.6.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a13cfa3410a75e4cb87abdb669aaf79da861cb79299159054ff8f77b9671bc40", size = 510596, upload-time = "2026-06-14T10:50:31.657Z" }, { url = "https://files.pythonhosted.org/packages/1d/22/01b92a600505620e4cb5f20429e181f30458b7207ca8b52ca5ca6068c35f/backports_zstd-1.6.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:2ddab55a5f54dec8acfad68ef70f1c704fd21919990ddc238afbd6f496e61c6a", size = 587143, upload-time = "2026-06-14T10:50:32.868Z" }, { url = "https://files.pythonhosted.org/packages/d8/60/4672f5110b9eb01388cc6225a739e3a5fcd749a63a9c4c1450a04fa27113/backports_zstd-1.6.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:fa305a84087e10d7a85e8a8a3dcba8cdbda4868f2180173b264b7b488fd37c55", size = 565238, upload-time = "2026-06-14T10:50:34.173Z" }, { url = "https://files.pythonhosted.org/packages/5c/3b/19928d60ea7d25820bf12ef88de74534ca85b56ff7cf13c1b0e74e3a3d7c/backports_zstd-1.6.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:df27b57d214a3124fbe4e933ef5a903d4567f154260d9aece8c797a987f2a205", size = 633970, upload-time = "2026-06-14T10:50:35.506Z" }, { url = "https://files.pythonhosted.org/packages/df/97/c4cecb3e0ff53563ef9819f0395d919ceaae9c5147392ac23bac7afdb20f/backports_zstd-1.6.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:28fecd73459d74910ae1987ab84b7bef690d3dd860948430dd5555108b006daf", size = 496539, upload-time = "2026-06-14T10:50:37.015Z" }, { url = "https://files.pythonhosted.org/packages/eb/f4/46b2f29d2938a80e56e61a19f11ab093f531a9f8cd0ec8eeaac1246bcd99/backports_zstd-1.6.0-cp313-cp313-win32.whl", hash = "sha256:3e689af303df287142770abe3a48bbefd24dab4a09da5807d0e1fa8c75bab026", size = 291451, upload-time = "2026-06-14T10:50:38.518Z" }, { url = "https://files.pythonhosted.org/packages/d1/ad/b529f92166da61f496621345f95d2dc583c8ca5ac553c084a4ef6c12cd71/backports_zstd-1.6.0-cp313-cp313-win_amd64.whl", hash = "sha256:b067b1ef9c8e41fb0882c828aa37829938b5c0dab067eca72b23fc24c563b9da", size = 329023, upload-time = "2026-06-14T10:50:39.742Z" }, { url = "https://files.pythonhosted.org/packages/30/d8/6be904d20345fbebec583ca83676e01f30c76118b283eb666d8ec8291ca1/backports_zstd-1.6.0-cp313-cp313-win_arm64.whl", hash = "sha256:a838296f5b84c920172fb579cac894d255c1fc25457c7234613ddcfa385e49b7", size = 291636, upload-time = "2026-06-14T10:50:41.004Z" }, { url = "https://files.pythonhosted.org/packages/e8/09/898fe2f8196fa7ab825f5fed786c68581fdac7d23a8e20baa0cc01cb2f0b/backports_zstd-1.6.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:aeef8563b82ed4af328f98e5041c1b4800d86f68f857ffd1577d4d47dc9aa6cd", size = 411023, upload-time = "2026-06-14T10:50:50.286Z" }, { url = "https://files.pythonhosted.org/packages/6e/ad/6ad9af1596ab5f284bb53954be41396e13d23c81cdfe3d945402e8ee0215/backports_zstd-1.6.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9cb75e33131946fabd6319061df3b8b1d588fe0963183280e9b5f49f7772fc09", size = 340554, upload-time = "2026-06-14T10:50:51.523Z" }, { url = "https://files.pythonhosted.org/packages/f0/00/f083d7c8a4ee5d0bb21b4d3144e76de9f655ca4dd0bffcb95baa5bc47a62/backports_zstd-1.6.0-pp311-pypy311_pp73-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:ef132cfb638e9a86bd5dc07fb4e1cb895bc55bce6bb5e759366e8b160d0747e2", size = 421694, upload-time = "2026-06-14T10:50:52.917Z" }, { url = "https://files.pythonhosted.org/packages/41/d7/693b20f3ccae2e05d166f98fe55b1657451170b72c804ed9f6b98df520be/backports_zstd-1.6.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ab70eace272d6f122b121c057e436709b50a28abf30d97aab28433c08f4a4095", size = 395237, upload-time = "2026-06-14T10:50:54.448Z" }, { url = "https://files.pythonhosted.org/packages/53/a1/484e0f9ec994bd2285d6747e7c8028350f1a177e9210bc57637898042d3b/backports_zstd-1.6.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:17efb3d11137de5166dd51eedab9c36ad633402acba386eee8d715213ea47e49", size = 415201, upload-time = "2026-06-14T10:50:55.854Z" }, { url = "https://files.pythonhosted.org/packages/3c/56/70860ece85cd49b564305cbc22bf6c4183975427ff6dfe2097e855f5dd5e/backports_zstd-1.6.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:994167ff6551b9c1ce226e0aab16295b98c94507b5701aa60d2c32b7d50796b1", size = 315721, upload-time = "2026-06-14T10:50:57.074Z" }, ] [[package]] name = "blinker" version = "1.9.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/21/28/9b3f50ce0e048515135495f198351908d99540d69bfdc8c1d15b73dc55ce/blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf", size = 22460, upload-time = "2024-11-08T17:25:47.436Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc", size = 8458, upload-time = "2024-11-08T17:25:46.184Z" }, ] [[package]] name = "brotli" version = "1.2.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f7/16/c92ca344d646e71a43b8bb353f0a6490d7f6e06210f8554c8f874e454285/brotli-1.2.0.tar.gz", hash = "sha256:e310f77e41941c13340a95976fe66a8a95b01e783d430eeaf7a2f87e0a57dd0a", size = 7388632, upload-time = "2025-11-05T18:39:42.86Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/7a/ef/f285668811a9e1ddb47a18cb0b437d5fc2760d537a2fe8a57875ad6f8448/brotli-1.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:15b33fe93cedc4caaff8a0bd1eb7e3dab1c61bb22a0bf5bdfdfd97cd7da79744", size = 863110, upload-time = "2025-11-05T18:38:12.978Z" }, { url = "https://files.pythonhosted.org/packages/50/62/a3b77593587010c789a9d6eaa527c79e0848b7b860402cc64bc0bc28a86c/brotli-1.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:898be2be399c221d2671d29eed26b6b2713a02c2119168ed914e7d00ceadb56f", size = 445438, upload-time = "2025-11-05T18:38:14.208Z" }, { url = "https://files.pythonhosted.org/packages/cd/e1/7fadd47f40ce5549dc44493877db40292277db373da5053aff181656e16e/brotli-1.2.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:350c8348f0e76fff0a0fd6c26755d2653863279d086d3aa2c290a6a7251135dd", size = 1534420, upload-time = "2025-11-05T18:38:15.111Z" }, { url = "https://files.pythonhosted.org/packages/12/8b/1ed2f64054a5a008a4ccd2f271dbba7a5fb1a3067a99f5ceadedd4c1d5a7/brotli-1.2.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2e1ad3fda65ae0d93fec742a128d72e145c9c7a99ee2fcd667785d99eb25a7fe", size = 1632619, upload-time = "2025-11-05T18:38:16.094Z" }, { url = "https://files.pythonhosted.org/packages/89/5a/7071a621eb2d052d64efd5da2ef55ecdac7c3b0c6e4f9d519e9c66d987ef/brotli-1.2.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:40d918bce2b427a0c4ba189df7a006ac0c7277c180aee4617d99e9ccaaf59e6a", size = 1426014, upload-time = "2025-11-05T18:38:17.177Z" }, { url = "https://files.pythonhosted.org/packages/26/6d/0971a8ea435af5156acaaccec1a505f981c9c80227633851f2810abd252a/brotli-1.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2a7f1d03727130fc875448b65b127a9ec5d06d19d0148e7554384229706f9d1b", size = 1489661, upload-time = "2025-11-05T18:38:18.41Z" }, { url = "https://files.pythonhosted.org/packages/f3/75/c1baca8b4ec6c96a03ef8230fab2a785e35297632f402ebb1e78a1e39116/brotli-1.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:9c79f57faa25d97900bfb119480806d783fba83cd09ee0b33c17623935b05fa3", size = 1599150, upload-time = "2025-11-05T18:38:19.792Z" }, { url = "https://files.pythonhosted.org/packages/0d/1a/23fcfee1c324fd48a63d7ebf4bac3a4115bdb1b00e600f80f727d850b1ae/brotli-1.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:844a8ceb8483fefafc412f85c14f2aae2fb69567bf2a0de53cdb88b73e7c43ae", size = 1493505, upload-time = "2025-11-05T18:38:20.913Z" }, { url = "https://files.pythonhosted.org/packages/36/e5/12904bbd36afeef53d45a84881a4810ae8810ad7e328a971ebbfd760a0b3/brotli-1.2.0-cp311-cp311-win32.whl", hash = "sha256:aa47441fa3026543513139cb8926a92a8e305ee9c71a6209ef7a97d91640ea03", size = 334451, upload-time = "2025-11-05T18:38:21.94Z" }, { url = "https://files.pythonhosted.org/packages/02/8b/ecb5761b989629a4758c394b9301607a5880de61ee2ee5fe104b87149ebc/brotli-1.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:022426c9e99fd65d9475dce5c195526f04bb8be8907607e27e747893f6ee3e24", size = 369035, upload-time = "2025-11-05T18:38:22.941Z" }, { url = "https://files.pythonhosted.org/packages/11/ee/b0a11ab2315c69bb9b45a2aaed022499c9c24a205c3a49c3513b541a7967/brotli-1.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:35d382625778834a7f3061b15423919aa03e4f5da34ac8e02c074e4b75ab4f84", size = 861543, upload-time = "2025-11-05T18:38:24.183Z" }, { url = "https://files.pythonhosted.org/packages/e1/2f/29c1459513cd35828e25531ebfcbf3e92a5e49f560b1777a9af7203eb46e/brotli-1.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7a61c06b334bd99bc5ae84f1eeb36bfe01400264b3c352f968c6e30a10f9d08b", size = 444288, upload-time = "2025-11-05T18:38:25.139Z" }, { url = "https://files.pythonhosted.org/packages/3d/6f/feba03130d5fceadfa3a1bb102cb14650798c848b1df2a808356f939bb16/brotli-1.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:acec55bb7c90f1dfc476126f9711a8e81c9af7fb617409a9ee2953115343f08d", size = 1528071, upload-time = "2025-11-05T18:38:26.081Z" }, { url = "https://files.pythonhosted.org/packages/2b/38/f3abb554eee089bd15471057ba85f47e53a44a462cfce265d9bf7088eb09/brotli-1.2.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:260d3692396e1895c5034f204f0db022c056f9e2ac841593a4cf9426e2a3faca", size = 1626913, upload-time = "2025-11-05T18:38:27.284Z" }, { url = "https://files.pythonhosted.org/packages/03/a7/03aa61fbc3c5cbf99b44d158665f9b0dd3d8059be16c460208d9e385c837/brotli-1.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:072e7624b1fc4d601036ab3f4f27942ef772887e876beff0301d261210bca97f", size = 1419762, upload-time = "2025-11-05T18:38:28.295Z" }, { url = "https://files.pythonhosted.org/packages/21/1b/0374a89ee27d152a5069c356c96b93afd1b94eae83f1e004b57eb6ce2f10/brotli-1.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:adedc4a67e15327dfdd04884873c6d5a01d3e3b6f61406f99b1ed4865a2f6d28", size = 1484494, upload-time = "2025-11-05T18:38:29.29Z" }, { url = "https://files.pythonhosted.org/packages/cf/57/69d4fe84a67aef4f524dcd075c6eee868d7850e85bf01d778a857d8dbe0a/brotli-1.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7a47ce5c2288702e09dc22a44d0ee6152f2c7eda97b3c8482d826a1f3cfc7da7", size = 1593302, upload-time = "2025-11-05T18:38:30.639Z" }, { url = "https://files.pythonhosted.org/packages/d5/3b/39e13ce78a8e9a621c5df3aeb5fd181fcc8caba8c48a194cd629771f6828/brotli-1.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:af43b8711a8264bb4e7d6d9a6d004c3a2019c04c01127a868709ec29962b6036", size = 1487913, upload-time = "2025-11-05T18:38:31.618Z" }, { url = "https://files.pythonhosted.org/packages/62/28/4d00cb9bd76a6357a66fcd54b4b6d70288385584063f4b07884c1e7286ac/brotli-1.2.0-cp312-cp312-win32.whl", hash = "sha256:e99befa0b48f3cd293dafeacdd0d191804d105d279e0b387a32054c1180f3161", size = 334362, upload-time = "2025-11-05T18:38:32.939Z" }, { url = "https://files.pythonhosted.org/packages/1c/4e/bc1dcac9498859d5e353c9b153627a3752868a9d5f05ce8dedd81a2354ab/brotli-1.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:b35c13ce241abdd44cb8ca70683f20c0c079728a36a996297adb5334adfc1c44", size = 369115, upload-time = "2025-11-05T18:38:33.765Z" }, { url = "https://files.pythonhosted.org/packages/6c/d4/4ad5432ac98c73096159d9ce7ffeb82d151c2ac84adcc6168e476bb54674/brotli-1.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:9e5825ba2c9998375530504578fd4d5d1059d09621a02065d1b6bfc41a8e05ab", size = 861523, upload-time = "2025-11-05T18:38:34.67Z" }, { url = "https://files.pythonhosted.org/packages/91/9f/9cc5bd03ee68a85dc4bc89114f7067c056a3c14b3d95f171918c088bf88d/brotli-1.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0cf8c3b8ba93d496b2fae778039e2f5ecc7cff99df84df337ca31d8f2252896c", size = 444289, upload-time = "2025-11-05T18:38:35.6Z" }, { url = "https://files.pythonhosted.org/packages/2e/b6/fe84227c56a865d16a6614e2c4722864b380cb14b13f3e6bef441e73a85a/brotli-1.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c8565e3cdc1808b1a34714b553b262c5de5fbda202285782173ec137fd13709f", size = 1528076, upload-time = "2025-11-05T18:38:36.639Z" }, { url = "https://files.pythonhosted.org/packages/55/de/de4ae0aaca06c790371cf6e7ee93a024f6b4bb0568727da8c3de112e726c/brotli-1.2.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:26e8d3ecb0ee458a9804f47f21b74845cc823fd1bb19f02272be70774f56e2a6", size = 1626880, upload-time = "2025-11-05T18:38:37.623Z" }, { url = "https://files.pythonhosted.org/packages/5f/16/a1b22cbea436642e071adcaf8d4b350a2ad02f5e0ad0da879a1be16188a0/brotli-1.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67a91c5187e1eec76a61625c77a6c8c785650f5b576ca732bd33ef58b0dff49c", size = 1419737, upload-time = "2025-11-05T18:38:38.729Z" }, { url = "https://files.pythonhosted.org/packages/46/63/c968a97cbb3bdbf7f974ef5a6ab467a2879b82afbc5ffb65b8acbb744f95/brotli-1.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4ecdb3b6dc36e6d6e14d3a1bdc6c1057c8cbf80db04031d566eb6080ce283a48", size = 1484440, upload-time = "2025-11-05T18:38:39.916Z" }, { url = "https://files.pythonhosted.org/packages/06/9d/102c67ea5c9fc171f423e8399e585dabea29b5bc79b05572891e70013cdd/brotli-1.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3e1b35d56856f3ed326b140d3c6d9db91740f22e14b06e840fe4bb1923439a18", size = 1593313, upload-time = "2025-11-05T18:38:41.24Z" }, { url = "https://files.pythonhosted.org/packages/9e/4a/9526d14fa6b87bc827ba1755a8440e214ff90de03095cacd78a64abe2b7d/brotli-1.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:54a50a9dad16b32136b2241ddea9e4df159b41247b2ce6aac0b3276a66a8f1e5", size = 1487945, upload-time = "2025-11-05T18:38:42.277Z" }, { url = "https://files.pythonhosted.org/packages/5b/e8/3fe1ffed70cbef83c5236166acaed7bb9c766509b157854c80e2f766b38c/brotli-1.2.0-cp313-cp313-win32.whl", hash = "sha256:1b1d6a4efedd53671c793be6dd760fcf2107da3a52331ad9ea429edf0902f27a", size = 334368, upload-time = "2025-11-05T18:38:43.345Z" }, { url = "https://files.pythonhosted.org/packages/ff/91/e739587be970a113b37b821eae8097aac5a48e5f0eca438c22e4c7dd8648/brotli-1.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:b63daa43d82f0cdabf98dee215b375b4058cce72871fd07934f179885aad16e8", size = 369116, upload-time = "2025-11-05T18:38:44.609Z" }, { url = "https://files.pythonhosted.org/packages/17/e1/298c2ddf786bb7347a1cd71d63a347a79e5712a7c0cba9e3c3458ebd976f/brotli-1.2.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:6c12dad5cd04530323e723787ff762bac749a7b256a5bece32b2243dd5c27b21", size = 863080, upload-time = "2025-11-05T18:38:45.503Z" }, { url = "https://files.pythonhosted.org/packages/84/0c/aac98e286ba66868b2b3b50338ffbd85a35c7122e9531a73a37a29763d38/brotli-1.2.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3219bd9e69868e57183316ee19c84e03e8f8b5a1d1f2667e1aa8c2f91cb061ac", size = 445453, upload-time = "2025-11-05T18:38:46.433Z" }, { url = "https://files.pythonhosted.org/packages/ec/f1/0ca1f3f99ae300372635ab3fe2f7a79fa335fee3d874fa7f9e68575e0e62/brotli-1.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:963a08f3bebd8b75ac57661045402da15991468a621f014be54e50f53a58d19e", size = 1528168, upload-time = "2025-11-05T18:38:47.371Z" }, { url = "https://files.pythonhosted.org/packages/d6/a6/2ebfc8f766d46df8d3e65b880a2e220732395e6d7dc312c1e1244b0f074a/brotli-1.2.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9322b9f8656782414b37e6af884146869d46ab85158201d82bab9abbcb971dc7", size = 1627098, upload-time = "2025-11-05T18:38:48.385Z" }, { url = "https://files.pythonhosted.org/packages/f3/2f/0976d5b097ff8a22163b10617f76b2557f15f0f39d6a0fe1f02b1a53e92b/brotli-1.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cf9cba6f5b78a2071ec6fb1e7bd39acf35071d90a81231d67e92d637776a6a63", size = 1419861, upload-time = "2025-11-05T18:38:49.372Z" }, { url = "https://files.pythonhosted.org/packages/9c/97/d76df7176a2ce7616ff94c1fb72d307c9a30d2189fe877f3dd99af00ea5a/brotli-1.2.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7547369c4392b47d30a3467fe8c3330b4f2e0f7730e45e3103d7d636678a808b", size = 1484594, upload-time = "2025-11-05T18:38:50.655Z" }, { url = "https://files.pythonhosted.org/packages/d3/93/14cf0b1216f43df5609f5b272050b0abd219e0b54ea80b47cef9867b45e7/brotli-1.2.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:fc1530af5c3c275b8524f2e24841cbe2599d74462455e9bae5109e9ff42e9361", size = 1593455, upload-time = "2025-11-05T18:38:51.624Z" }, { url = "https://files.pythonhosted.org/packages/b3/73/3183c9e41ca755713bdf2cc1d0810df742c09484e2e1ddd693bee53877c1/brotli-1.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d2d085ded05278d1c7f65560aae97b3160aeb2ea2c0b3e26204856beccb60888", size = 1488164, upload-time = "2025-11-05T18:38:53.079Z" }, { url = "https://files.pythonhosted.org/packages/64/6a/0c78d8f3a582859236482fd9fa86a65a60328a00983006bcf6d83b7b2253/brotli-1.2.0-cp314-cp314-win32.whl", hash = "sha256:832c115a020e463c2f67664560449a7bea26b0c1fdd690352addad6d0a08714d", size = 339280, upload-time = "2025-11-05T18:38:54.02Z" }, { url = "https://files.pythonhosted.org/packages/f5/10/56978295c14794b2c12007b07f3e41ba26acda9257457d7085b0bb3bb90c/brotli-1.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:e7c0af964e0b4e3412a0ebf341ea26ec767fa0b4cf81abb5e897c9338b5ad6a3", size = 375639, upload-time = "2025-11-05T18:38:55.67Z" }, ] [[package]] name = "brotlicffi" version = "1.2.0.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi" }, ] sdist = { url = "https://files.pythonhosted.org/packages/71/97/7845739a36828ffe751a1c6b240692f552fd7ecf65026c51326c0a4aa369/brotlicffi-1.2.0.2.tar.gz", hash = "sha256:5e0fbd13644cf1f6015e75fa5e0ad8fdce1048d9c9ff90b0ce826174b249ee35", size = 478755, upload-time = "2026-08-21T17:29:18.415Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/77/a2/edda4f3fc7143434402eacad1e91433fe68ae648c22738eeddb6138638ba/brotlicffi-1.2.0.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ad05ca993234cf947f0ad71b1c8bc0af3d74e0410b1e2c32bb99de0cef6a994b", size = 438789, upload-time = "2026-08-21T17:28:55.708Z" }, { url = "https://files.pythonhosted.org/packages/0d/9c/506dc8edabb3cf9339c89f1ecc80a218aa166bb83b9f2e9cc1da67314072/brotlicffi-1.2.0.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0636cb5a85f31c36e08953d09a226cb788be900b976f81302895e3cf35d5e707", size = 1541246, upload-time = "2026-08-21T17:28:57.669Z" }, { url = "https://files.pythonhosted.org/packages/9f/d6/74cee9f9fbea8c42030a81056c64e092030a95bd2756ea83da1d1e8f5f29/brotlicffi-1.2.0.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:97bae40d45ebc2a6ac7b1c9b30825496a257192194b672ef5869e2df93467f69", size = 1542129, upload-time = "2026-08-21T17:28:59.502Z" }, { url = "https://files.pythonhosted.org/packages/24/cc/c32630b042ec2a13e8342e6ecb6b9d3531b1be4647b733d6fd365976041c/brotlicffi-1.2.0.2-cp314-cp314t-win32.whl", hash = "sha256:8f3f9bd61293dc48359763e693951393f39656086315067cf97e23e23e8911ab", size = 346840, upload-time = "2026-08-21T17:29:01.085Z" }, { url = "https://files.pythonhosted.org/packages/ee/0b/83cac3075721fe4c253ea1cc5310cb687c2f7d987e0fd60eb3ed769c24c0/brotlicffi-1.2.0.2-cp314-cp314t-win_amd64.whl", hash = "sha256:908add8a9c0eea00f5de799dc6de9f6d205d9ee11afabc7c03d6812c481200e2", size = 386079, upload-time = "2026-08-21T17:29:02.667Z" }, { url = "https://files.pythonhosted.org/packages/2e/71/c27f24b8334f65f2492601c7764338f156cb904d2ffe0061e6004a76d9cc/brotlicffi-1.2.0.2-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:d5a8ffa154f16660ab818d78045b55fa6f9970f1ca4c38998766e99c672071cb", size = 438885, upload-time = "2026-08-21T17:29:04.113Z" }, { url = "https://files.pythonhosted.org/packages/ef/22/d8fd1a4d09b7ab563b89380395e09151d2ef1344be31594df6a6987d4028/brotlicffi-1.2.0.2-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ec6b1af7b7a8ce788354f2c603651ada0fba166ec31ab879e2eec462a3e6dbf4", size = 1534365, upload-time = "2026-08-21T17:29:05.878Z" }, { url = "https://files.pythonhosted.org/packages/06/78/076419ed6c2c6aa3eaac6fd6b076502b4be89d50625fcdc513cd4aeca718/brotlicffi-1.2.0.2-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22916101de0e7ff535f2edf54b52a85591853b8ae9a98737643defdd3c063a3a", size = 1536851, upload-time = "2026-08-21T17:29:07.599Z" }, { url = "https://files.pythonhosted.org/packages/35/dd/31ae9945cbd605339fb51c9a609f7dbb182cd361adeabc1d470142357206/brotlicffi-1.2.0.2-cp39-abi3-win32.whl", hash = "sha256:df1d34c4ad9adbf7f63a6b42f7d0e4dfd259c88141b85145b57abecc1abc3b24", size = 342379, upload-time = "2026-08-21T17:29:09.05Z" }, { url = "https://files.pythonhosted.org/packages/95/ae/afd54e744df93b51cc29f6a19beccf9998b25743d7177697390de10479d1/brotlicffi-1.2.0.2-cp39-abi3-win_amd64.whl", hash = "sha256:489ca4da3ee65926d72bf01584b61088a9da6bdd1bb01b2040901e1beaffa8f0", size = 379761, upload-time = "2026-08-21T17:29:10.687Z" }, { url = "https://files.pythonhosted.org/packages/37/da/a5b65a86725d772504a348193cf1fab5ad6410794b422bf81faa17a96a66/brotlicffi-1.2.0.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:cf500bb9e02e1474ced1ecf22f74c568de2816b3627af6352ec51ac5e09e60ee", size = 407459, upload-time = "2026-08-21T17:29:12.385Z" }, { url = "https://files.pythonhosted.org/packages/e1/c7/a253288e66ee340f2f6320eda7022daa723f2918438d586a59e9c998aa27/brotlicffi-1.2.0.2-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dbb81489562dd5363bf86d9a8edb0ec8c97049b0819ba4936fc023e8847248bc", size = 406825, upload-time = "2026-08-21T17:29:13.992Z" }, { url = "https://files.pythonhosted.org/packages/6e/6c/ea8e3d34e1d64c5e5a920bb0c89bf9e92badf973937a60922820395e622d/brotlicffi-1.2.0.2-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fc7647657e4f3d73eab591910dbecb57d1ecaea7aa3dd04e6d704a2756fe0c59", size = 402903, upload-time = "2026-08-21T17:29:15.524Z" }, { url = "https://files.pythonhosted.org/packages/4e/17/17c22d48819001ca08cadab63b09b00e0c56a7579478aa7c2623f4280de6/brotlicffi-1.2.0.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:5eb5563173afb92c9111b180349ff17d7c83c79febabadca5de983b552565c3c", size = 378395, upload-time = "2026-08-21T17:29:16.857Z" }, ] [[package]] name = "certifi" version = "2026.4.22" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/25/ee/6caf7a40c36a1220410afe15a1cc64993a1f864871f698c0f93acb72842a/certifi-2026.4.22.tar.gz", hash = "sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580", size = 137077, upload-time = "2026-04-22T11:26:11.191Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/22/30/7cd8fdcdfbc5b869528b079bfb76dcdf6056b1a2097a662e5e8c04f42965/certifi-2026.4.22-py3-none-any.whl", hash = "sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a", size = 135707, upload-time = "2026-04-22T11:26:09.372Z" }, ] [[package]] name = "cffi" version = "2.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pycparser", marker = "implementation_name != 'PyPy'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/57/5f/ff100cae70ebe9d8df1c01a00e510e45d9adb5c1fdda84791b199141de97/cffi-2.1.0.tar.gz", hash = "sha256:efc1cdd798b1aaf39b4610bba7aad28c9bea9b910f25c784ccf9ec1fa719d1f9", size = 531036, upload-time = "2026-07-06T21:34:30.382Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/d3/67/85c89a59ba36a671e79638f44d466749f08179266a57e4f2ffdf92174072/cffi-2.1.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:02cb7ff33ded4f1532476731f89ede53e2e488a8e6205515a82144246ffa7dcc", size = 183845, upload-time = "2026-07-06T21:32:26.32Z" }, { url = "https://files.pythonhosted.org/packages/ea/dd/e3b0baa2d3d6a857ac72b7efbf18e32e487c9cdafcc13049ad765495b15e/cffi-2.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f5bce581e6b8c235e566a14768a943b172ada3ed73537bb0c0be1edee312d4e7", size = 184186, upload-time = "2026-07-06T21:32:28.025Z" }, { url = "https://files.pythonhosted.org/packages/65/68/9f3ef890cf3c6ab97bd531c5677f67613d302165d16f8142b2811782a614/cffi-2.1.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:30b65779d598c370374fefabf138d456fd6f3216bfa7bedfab1ba82025b0cd93", size = 211892, upload-time = "2026-07-06T21:32:29.565Z" }, { url = "https://files.pythonhosted.org/packages/22/d7/1a74539db16d8bfd839ff1515948948efbb162e574650fd3d846896eea95/cffi-2.1.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:88023dfe18799507b73f1dbb0d14326a17465de1bc9c9c7655c22845e9ddc3a2", size = 218793, upload-time = "2026-07-06T21:32:30.951Z" }, { url = "https://files.pythonhosted.org/packages/ec/d1/9a5b7169499e8e8d8e636de70b97ac7c9447104d2ff1a2cd94790cea5162/cffi-2.1.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:0a96b74cda968eebbad56d973efe5098974f0a9fb323865bf99ea1fd24e3e64c", size = 205737, upload-time = "2026-07-06T21:32:32.216Z" }, { url = "https://files.pythonhosted.org/packages/ba/b0/e131a9c41f10607926278453d9596163594fe1c4ebc46efe3b5e5b34eb84/cffi-2.1.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a5781494d4d400a3f47f8f1da94b324f6e6b440a53387774002890a2a2f4b50f", size = 204909, upload-time = "2026-07-06T21:32:33.655Z" }, { url = "https://files.pythonhosted.org/packages/fb/d2/4398416cd699b35167947c6e22aca52c47e69ad5695073c9f1f2c52e04aa/cffi-2.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aa7a1b53a2a4452ada2d1b5dade9960b2522f1e61293a811a077439e39029565", size = 217883, upload-time = "2026-07-06T21:32:35.173Z" }, { url = "https://files.pythonhosted.org/packages/a2/a5/d4fe77b589e5e82d43ebc809bf2e6474afe8e48e32ea050b9357645b6471/cffi-2.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9d8272c0e483b024e1b9ad029821470ed8ec65631dbd90217469da0e7cd89f1c", size = 221251, upload-time = "2026-07-06T21:32:36.527Z" }, { url = "https://files.pythonhosted.org/packages/22/f0/a2fc43084c0433caf7f461bccc013e28f848d04ee1c5ed7fce71423cf4d9/cffi-2.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7762faa47e8ff7eb80bd261d9a7d8eea2d8baa69de5e95b70c1f338bbe712f02", size = 214250, upload-time = "2026-07-06T21:32:37.852Z" }, { url = "https://files.pythonhosted.org/packages/04/8c/b925975448cf20634a9fbd5efceb807219db452653648d2897c0989cab2d/cffi-2.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:89095c1968b4ba8285840e131bf2891b09ae137fe2146905acae0354fbce1b5e", size = 219441, upload-time = "2026-07-06T21:32:39.146Z" }, { url = "https://files.pythonhosted.org/packages/eb/da/5c4918a2d61d86fa927d716cb3d8e4626ef8dc8f605a599d32f33897f59a/cffi-2.1.0-cp311-cp311-win32.whl", hash = "sha256:64c753a0f87a256020004f37a1c8c02c480e725f910f0b2a0f3f07debd1b2479", size = 174496, upload-time = "2026-07-06T21:32:40.467Z" }, { url = "https://files.pythonhosted.org/packages/f9/c8/6c2de1d55cf35ef8b92885d5ef280790f0fb9634d87ea1cc315176aecd61/cffi-2.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:4f26194e3d95e06501b942642855aed4f953d55e95d7d01b7c4483db3ecff458", size = 185113, upload-time = "2026-07-06T21:32:41.761Z" }, { url = "https://files.pythonhosted.org/packages/9e/4e/e8d7cb5783f1841a3c8fb3a7735838d7484d08ec08c9f984b14cac1ac0e9/cffi-2.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:35aaea0c7ee0e58a5cd8c2fd1a48fdf7ece0d2699b7ecdda08194e9ce5dd9b3d", size = 179927, upload-time = "2026-07-06T21:32:42.961Z" }, { url = "https://files.pythonhosted.org/packages/1e/85/990925db5df586ec90beb97529c853497e7f85ba0234830447faf41c3057/cffi-2.1.0-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:df2b82571a1b30f58a87bf4e5a9e78d2b1eff6c6ce8fd3aa3757221f93f0863f", size = 184829, upload-time = "2026-07-06T21:32:44.324Z" }, { url = "https://files.pythonhosted.org/packages/4b/92/e7bb136ad6b5352603732cf907ef862ca103f20f2031c1735a46300c20c9/cffi-2.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:78474632761faa0fb96f30b1c928c84ebcf68713cbb80d15bab09dfe61640fde", size = 184728, upload-time = "2026-07-06T21:32:45.683Z" }, { url = "https://files.pythonhosted.org/packages/c3/c0/d1ec30ffb370f748f2fb54425972bfef9871e0132e82fb589c46b6676049/cffi-2.1.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:5972433ad71a9e46516584ef60a0fda12d9dc459938d1539c3ddecf9bdc1368d", size = 214815, upload-time = "2026-07-06T21:32:48.557Z" }, { url = "https://files.pythonhosted.org/packages/1b/dc/5620cf930688be01f2d673804291de757a934c90b946dbdc3d84130c2ea4/cffi-2.1.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b6422532152adf4e59b110cb2808cee7a033800952f5c036b4af047ee43199e7", size = 222429, upload-time = "2026-07-06T21:32:49.848Z" }, { url = "https://files.pythonhosted.org/packages/4b/a4/77b53abbf7a1e0beb9637edbef2a94d15f9c822f591e85d439ffd91519a6/cffi-2.1.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:46b1c8db8f6122420f32d02fffb924c2fe9bc772d228c7c711748fff56aabb2b", size = 210315, upload-time = "2026-07-06T21:32:51.221Z" }, { url = "https://files.pythonhosted.org/packages/58/0c/f528df19cc94b675087324d4760d9e6d5bfae97d6217aa4fac43de4f5fcc/cffi-2.1.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9fafc5aa2e2a39aaf7f8cc0c1f044a9b07fca12e558dca53a3cc5c654ad67a7", size = 208859, upload-time = "2026-07-06T21:32:52.512Z" }, { url = "https://files.pythonhosted.org/packages/62/f2/c9522a81c32132799a1972c39f5c5f8b4c8b9f00488a23feaa6c06f07741/cffi-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1e9f50d192a3e525b15a75ab5114e442d83d657b7ec29182a991bc9a88fd3a66", size = 221844, upload-time = "2026-07-06T21:32:53.704Z" }, { url = "https://files.pythonhosted.org/packages/6e/28/bd53988b9833e8f8ad539d26f4c07a6b3f6bcb1e9e02e7ca038250b3428d/cffi-2.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98fff996e983a36d3aa2eca83af40c5821202e7e6f32d13ae94e3d2286f10cfe", size = 225287, upload-time = "2026-07-06T21:32:54.907Z" }, { url = "https://files.pythonhosted.org/packages/79/99/0d0fd37f055224085f42bbb2c022d002e17dde4a97972822327b07d84101/cffi-2.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:379de10ce1ba048b1448599d1b37b24caee16309d1ac98d3982fc997f768700b", size = 223681, upload-time = "2026-07-06T21:32:56.329Z" }, { url = "https://files.pythonhosted.org/packages/b0/80/c138990aa2a70b1a269f6e06348729836d733d6f970867943f61d367f8cc/cffi-2.1.0-cp312-cp312-win32.whl", hash = "sha256:9b8f0f26ca4e7513c534d351eca551947d053fac438f2a04ac96d882909b0d3a", size = 175269, upload-time = "2026-07-06T21:32:57.777Z" }, { url = "https://files.pythonhosted.org/packages/a8/eb/f636456ff21a83fc13c032b58cc5dde061691546ac79efa284b2989b7982/cffi-2.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:c97f080ea627e2863524c5af3836e2270b5f5dfff1f104392b959f8df0c5d384", size = 185881, upload-time = "2026-07-06T21:32:59.253Z" }, { url = "https://files.pythonhosted.org/packages/dd/2c/400ea43e721727dca8a65c4521390e9196757caba4a45643acb2b63271b8/cffi-2.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:6d194185eabd279f1c05ebe3504265ddfc5ad2b58d0714f7db9f01da592e9eb6", size = 180088, upload-time = "2026-07-06T21:33:02.278Z" }, { url = "https://files.pythonhosted.org/packages/96/88/a996879e2eeccb815f6e3a5967b12a308257412acec882039d386bd2aa7b/cffi-2.1.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:10537b1df4967ca26d21e5072d7d54188354483b91dc75058968d3f0cf13fbda", size = 194331, upload-time = "2026-07-06T21:33:03.697Z" }, { url = "https://files.pythonhosted.org/packages/58/85/7ae00d5c8dd6266f4e944c3db630f3c5c9a98b61d469c714d848b1d8138a/cffi-2.1.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:a95b05f9baf29b91171b3a8bd2020b028835243e7b0ff6bb23e2a3c228518b1b", size = 196966, upload-time = "2026-07-06T21:33:05.353Z" }, { url = "https://files.pythonhosted.org/packages/8c/e9/45c3a76ad8d43ad9261f4c95436da61128d3ca545d72b9612c0ab5be0b1c/cffi-2.1.0-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:15faec4adfff450819f3aee0e2e02c812de6edb88203aa58807955db2003472a", size = 184795, upload-time = "2026-07-06T21:33:06.699Z" }, { url = "https://files.pythonhosted.org/packages/84/4c/82f132cb4418ee6d953d982b19191e87e2a6372c8a4ce36e50b69d6ade4a/cffi-2.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:716ff8ec22f20b4d988b12884086bcef0fc99737043e503f7a3935a6be99b1ea", size = 184746, upload-time = "2026-07-06T21:33:08.071Z" }, { url = "https://files.pythonhosted.org/packages/a0/1c/4ed5a0e5bdca6cbc275556de3328dd1b76fd0c11cc13c88fe66d1d8715f2/cffi-2.1.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:63960549e4f8dc41e31accb97b975abaecfc44c03e396c093a6436763c2ea7db", size = 214747, upload-time = "2026-07-06T21:33:09.671Z" }, { url = "https://files.pythonhosted.org/packages/3a/a6/e879bb68cc23a2bc9ba8f4b7d8019f0c2694bad2ab6c4a3701d429439f58/cffi-2.1.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ff067a8d8d880e7809e4ac88eb009bb848870115317b306666502ccad30b147f", size = 222392, upload-time = "2026-07-06T21:33:10.896Z" }, { url = "https://files.pythonhosted.org/packages/88/f6/01890cfd63c08f8eb96a8319b0443690197d240a8bd6346048cf7bde9190/cffi-2.1.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:3b926723c13eba9f81d2ef3820d63aeceec3b2d4639906047bf675cb8a7a500d", size = 210285, upload-time = "2026-07-06T21:33:12.251Z" }, { url = "https://files.pythonhosted.org/packages/a6/cf/2b684132056f438567b61e19d690dd31cd0921ace051e0a458be6074369e/cffi-2.1.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:47ff3a8bfd8cb9da1af7524b965127095055654c177fcfc7578debcb015eecd0", size = 208801, upload-time = "2026-07-06T21:33:13.617Z" }, { url = "https://files.pythonhosted.org/packages/6f/08/f2e7d62c460faae0926f2d6e423694aa409ced3bc1fe2927a0a6e5f05416/cffi-2.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:799416bae98336e400981ff6e532d67d5c709cfb30afb79865a1315f94b0e224", size = 221808, upload-time = "2026-07-06T21:33:15.466Z" }, { url = "https://files.pythonhosted.org/packages/38/37/04f54b8e63a02f3d908332c9effbf8c366167c6f733ed8a3d4f79b7e2a1e/cffi-2.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:961be50688f7fba2fa65f63712d3b9b341a22311f5253460ce933f52f0de1c8c", size = 225241, upload-time = "2026-07-06T21:33:16.869Z" }, { url = "https://files.pythonhosted.org/packages/a9/d6/c72eecca433cd3e681c65ed313ab4835d9d4a379704d0f628a6a05f51c2e/cffi-2.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bf5c6cf48238b0eb4c086978c492ad1cbc22373fc5b2d7353b3a598ce6db887a", size = 223588, upload-time = "2026-07-06T21:33:18.239Z" }, { url = "https://files.pythonhosted.org/packages/c6/4b/e706f67279140f92939da3475ad610df18bfd52d50f14953a8e5fede71d5/cffi-2.1.0-cp313-cp313-win32.whl", hash = "sha256:db3eb7d46527159a878ec3460e9d40615bc25ba337d477db681aea6e4f05c5d2", size = 175248, upload-time = "2026-07-06T21:33:19.799Z" }, { url = "https://files.pythonhosted.org/packages/5a/47/59eb7975cb0e4ef0afa764ea945b29a5bb4537a9f771cb7d6c8a5dd74c95/cffi-2.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:8e74a6135550c4748af665b1b1118b6aab33b1fc6a16f9aff630af107c3b4512", size = 185717, upload-time = "2026-07-06T21:33:21.47Z" }, { url = "https://files.pythonhosted.org/packages/5a/af/34fee85c48f8d94efc8597bc09470c9dd274c145f1c12e0fbc6ab6d38d74/cffi-2.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:2282cd5e38aa8accd03e99d1256af8411c84cdbee6a89d841b563fdbd1f3e50f", size = 180114, upload-time = "2026-07-06T21:33:22.515Z" }, { url = "https://files.pythonhosted.org/packages/d8/f0/81478e482afa03f6d18dc8f2afb5edc45b3080853b634b5ed91961be0998/cffi-2.1.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:d2117334c3af3bdcb9a88522b844a2bdb5efdc4f71c6c822df55486ae1c3347a", size = 194142, upload-time = "2026-07-06T21:33:23.657Z" }, { url = "https://files.pythonhosted.org/packages/7d/95/8de304305cd9204974b0ca051b86d307cafca13aa575a0ef1b44d92c0d8c/cffi-2.1.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:702c436735fbe99d59ada02a1f65cfc0d31c0ee8b7290912f8fbc5cd1e4b16c3", size = 196819, upload-time = "2026-07-06T21:33:25.007Z" }, { url = "https://files.pythonhosted.org/packages/20/71/7c8372d30e42415602ed9f268f7cfd66f1b855fed881ecd168bcb45dbc0b/cffi-2.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:1ff3456eab0d889592d1936d6125bbfbc7ae4d3354a700f8bd80450a66445d4d", size = 184965, upload-time = "2026-07-06T21:33:26.605Z" }, { url = "https://files.pythonhosted.org/packages/d6/5c/584e626835f0375c928176c04137c96927165cb8733cdb3150ec04e5ee5e/cffi-2.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c4165821e131d6d4ca444347c2b694e2311bcfa3fe5a861cc72968f28867beac", size = 184952, upload-time = "2026-07-06T21:33:27.823Z" }, { url = "https://files.pythonhosted.org/packages/2e/d2/065fcae1c73979fac8e054462478d0ff8a29c40cdc2ed7ea5676a061df53/cffi-2.1.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:276f20fffd7b396e12516ba8edf9509210ac248cbbc5acbc39cd512f9f59ebe6", size = 222353, upload-time = "2026-07-06T21:33:29.178Z" }, { url = "https://files.pythonhosted.org/packages/ed/a5/e8bbb1ce5b3ac2f53ad6a10bde44318a5a8d99d4f4a000d44a6e39aeb3e4/cffi-2.1.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:7d5980a3433d4b71a5e120f9dd551403d7824e31e2e67124fe2769c404c06913", size = 210051, upload-time = "2026-07-06T21:33:30.534Z" }, { url = "https://files.pythonhosted.org/packages/28/ed/c127d3ac36e899c965e3361357c3befacd6578c03f40125183e41c3b219e/cffi-2.1.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:6ca4919c6e4f89aa99c42510b42cf54596892c00b3f9077f6bdd1505e24b9c8d", size = 208630, upload-time = "2026-07-06T21:33:31.753Z" }, { url = "https://files.pythonhosted.org/packages/cc/d7/97d3136f81db489ec8d1d67748c110d6c994268fd7528014aa9f2b085e4e/cffi-2.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d53d10f7da99ae46f7373b9150393e9c5eab9b224909982b43832668de4779f5", size = 221593, upload-time = "2026-07-06T21:33:33.044Z" }, { url = "https://files.pythonhosted.org/packages/d3/27/93195977168ee63aed233a1a0993a2178798654d1f4bddcdd321d6fd3b21/cffi-2.1.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c351efb95e832a853a29361675f33a7ce53de1a109cd73fd47af0712213aa4ce", size = 225146, upload-time = "2026-07-06T21:33:34.224Z" }, { url = "https://files.pythonhosted.org/packages/b3/c1/6dbd291ee2ae5a50a034aa057207081f545923bbf15dad4511e985aafff5/cffi-2.1.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:dbf7c7a88e2bac086f06d14577332760bdeecc42bdec8ac4077f6260557d9326", size = 223240, upload-time = "2026-07-06T21:33:35.57Z" }, { url = "https://files.pythonhosted.org/packages/0f/6f/ade5ce9863a57992a6ea3d0d10d7e29b8749fc127204b3d493d667b2815f/cffi-2.1.0-cp314-cp314-win32.whl", hash = "sha256:1854b724d00f6654c742097d5387569021be12d3a0f770eae1df8f8acfcc6acd", size = 177723, upload-time = "2026-07-06T21:33:51.626Z" }, { url = "https://files.pythonhosted.org/packages/41/de/92b9eeed4ae4a21d6fd9b2a2c8505cbed573299902ea73981cc13f7ff62c/cffi-2.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:1b96bfe2c4bd825681b7d311ad6d9b7280a091f43e8f63da5729638083cd3bfb", size = 187937, upload-time = "2026-07-06T21:33:53.403Z" }, { url = "https://files.pythonhosted.org/packages/2e/1a/cc6ae6c2913a03aab8898eee57963cf1035b8df5872ed8b9115fcc7e2be8/cffi-2.1.0-cp314-cp314-win_arm64.whl", hash = "sha256:7d28dff1db6764108bc30788d85d61c876beff416d9a49cb9dd7c5a9f34f5804", size = 183001, upload-time = "2026-07-06T21:33:54.74Z" }, { url = "https://files.pythonhosted.org/packages/14/f0/134c00ce0779ec86dea2aa1aac69339c2741a8045072676763512363a2ea/cffi-2.1.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7ea6b3e2c4250ff1de21c630fe72d0f63eb95c2c32ffbf64a358cf4a8836d714", size = 188538, upload-time = "2026-07-06T21:33:36.792Z" }, { url = "https://files.pythonhosted.org/packages/50/d8/3b86aba791cb610d24e8a3e1b2cd529e71fa15096b04e4d4e360049d4a4c/cffi-2.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6af371f3767faeffc6ac1ef57cdfd25844403e9d3f476c5537caee499de96376", size = 188230, upload-time = "2026-07-06T21:33:38.011Z" }, { url = "https://files.pythonhosted.org/packages/14/d0/117dcd9209255ad8571fbc8c92ef32593a1d294dcec91ddc4e4db50606f2/cffi-2.1.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb4e8997a49aa2c08a3e43c9045d224448b8941d88e7ac163c7d383e560cbf98", size = 223899, upload-time = "2026-07-06T21:33:39.514Z" }, { url = "https://files.pythonhosted.org/packages/b6/3d/f20f8b886b254e3ad10e15cd4186d3aed49f3e6a35ab37aab9f8f25f7c03/cffi-2.1.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:bf01d8c84cbea96b944c73b22182e6c7c432b3475632b8111dbfdc95ddad6e13", size = 211652, upload-time = "2026-07-06T21:33:40.851Z" }, { url = "https://files.pythonhosted.org/packages/28/3b/fad54de07260b93ddeef4b96d0131d57ea900675df1d410ae1deee52d7a6/cffi-2.1.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:33eb1ad83ebe8f313e0df035c406227d55a79456704a863fad9842136af5ad7d", size = 210755, upload-time = "2026-07-06T21:33:42.183Z" }, { url = "https://files.pythonhosted.org/packages/cc/82/3d5c705acb7abbba9bbd7d79b8e62e0f25b6120eb7ae6ac49f1b721722fe/cffi-2.1.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ac0f1a2d0cfa7eea3f2aaf006ab6e70e8feeb16b75d65b7e5939982ca2f11056", size = 223933, upload-time = "2026-07-06T21:33:43.603Z" }, { url = "https://files.pythonhosted.org/packages/6c/d0/47e338384ab6b1004241002fa616301020cea4fc95f283506565d252f276/cffi-2.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c16914df9fb7f500e440e6875fa23ff5e0b31db01fa9c06af98d59a91f0dc2e4", size = 226749, upload-time = "2026-07-06T21:33:45.046Z" }, { url = "https://files.pythonhosted.org/packages/70/25/65bd5b58ea4bfdfc15cde02cb5365f89ef8ab8b2adfb8fe5c4bd4233382f/cffi-2.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5ecbd0499275d57506d397eebe1981cee87b47fcd9ef5c22cab7ed7644a39a94", size = 225703, upload-time = "2026-07-06T21:33:46.374Z" }, { url = "https://files.pythonhosted.org/packages/dc/78/aa01ac599a8a4322533d45a1f9bc93b338276d2d59dabbe7c6d92a775c81/cffi-2.1.0-cp314-cp314t-win32.whl", hash = "sha256:7d034dcffa09e9a46c93fa3a3be402096cb5354ac6e41ab8e5cc9cd8b642ad76", size = 182857, upload-time = "2026-07-06T21:33:47.696Z" }, { url = "https://files.pythonhosted.org/packages/b9/26/d00496b22de4d4228f32dde94ad996f350c8aad676d63bcca0743c8dea4d/cffi-2.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0582a58f3051372229ca8e7f5f589f9e5632678208d8636fea3676711fdf7fe5", size = 194065, upload-time = "2026-07-06T21:33:48.953Z" }, { url = "https://files.pythonhosted.org/packages/d5/dd/0c7dbf815a579ff005008a2d815a55d6bb047c349eef536d9dc53d3f0a8d/cffi-2.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:510aeeeac94811b138077451da1fb18b308a5feab47dd2b603af55804155e1c8", size = 186404, upload-time = "2026-07-06T21:33:50.309Z" }, { url = "https://files.pythonhosted.org/packages/55/c7/8c8c50cb11c6750051daf12164098a9a6f027ac4356967fd4d800a07f242/cffi-2.1.0-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:2e9dabb9abcb7ad15938c7196ad5c1718a4e6d33cc79b4c0209bdb64c4a54a5c", size = 194121, upload-time = "2026-07-06T21:33:56.109Z" }, { url = "https://files.pythonhosted.org/packages/99/e2/67680bf19a6b60d2bb7ff83baefa2a4c3d2d7dc0f3277034b802e1fc504c/cffi-2.1.0-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:37f525a7e7e50c017fdebe58b787be310ad59357ae43a053943a6e1a6c526001", size = 196820, upload-time = "2026-07-06T21:33:57.288Z" }, { url = "https://files.pythonhosted.org/packages/ed/da/4bbe583a3b3a5c8c60892124fe17f3fa3656523faf0d3484eae90f091853/cffi-2.1.0-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:95f2954c2c9473d892eca6e0409f3568b37ab62a8eedb122461f73cc273476e3", size = 184936, upload-time = "2026-07-06T21:33:58.765Z" }, { url = "https://files.pythonhosted.org/packages/e5/4b/1f4c36ab273980d7aa75bb126ea4f8971f24a96108acad3a0a084028c57b/cffi-2.1.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:cdf2448aab5f661c9315308ec8b93f4e8a1a67a3c733f8631067a2b67d5913dc", size = 185045, upload-time = "2026-07-06T21:34:00.085Z" }, { url = "https://files.pythonhosted.org/packages/ef/c3/ad299dc38f3583f8d916b299f028af418a9ec98bc695fcbebeae7420691c/cffi-2.1.0-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:90bec57cf82089383bd06a605b3eb8daebf7e5a668520beaf6e327a83a947699", size = 222342, upload-time = "2026-07-06T21:34:01.814Z" }, { url = "https://files.pythonhosted.org/packages/eb/d8/df4543cc087245044ed02ef3ad8e0a26619d0075ac7a77a12dc81177851b/cffi-2.1.0-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6274dcb2d15cef48daa73ed1be5a40d501d74dccd0cd6db364776d12cb6ba022", size = 210073, upload-time = "2026-07-06T21:34:03.255Z" }, { url = "https://files.pythonhosted.org/packages/2c/0e/fac738d73728c6cea2a88a2883dca54892496cbba88a1dc1f2909cb8a6f5/cffi-2.1.0-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:2b71d409cccee78310ab5dec549aed052aaea483346e282c7b02362596e01bb0", size = 208551, upload-time = "2026-07-06T21:34:04.433Z" }, { url = "https://files.pythonhosted.org/packages/e6/3f/0b04a700dd64f465c93020253a793a82c9b4dff9961f48facd0df945d9b8/cffi-2.1.0-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7d3538f9c0e50670f4deb93dbb696576e60590369cae2faf7de681e597a8a1f1", size = 221649, upload-time = "2026-07-06T21:34:06.157Z" }, { url = "https://files.pythonhosted.org/packages/5d/7c/b7379a5704c79eda57ce075869ba70a0368d1c850f803b3c0d078d39dcaf/cffi-2.1.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:8f9ec95b8a043d3dfbc74d9abc6f7baf524dd27a8dc160b0a32ff9cdab650c28", size = 225203, upload-time = "2026-07-06T21:34:07.489Z" }, { url = "https://files.pythonhosted.org/packages/5a/02/d5e6c43ea85c41bda2a184a3418f195fe7cf602967a8d2b94e085b83deef/cffi-2.1.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:af5e2915d41fe6c961694d7bfdc8562942638200f3ce2765dfb8b745cf997629", size = 223263, upload-time = "2026-07-06T21:34:08.712Z" }, { url = "https://files.pythonhosted.org/packages/2c/d8/772b8259bf75749adffb1c546828978381fb516f60cf701f6c83daf60c85/cffi-2.1.0-cp315-cp315-win32.whl", hash = "sha256:0a42c688d19fca6e095a53c6a6e2295a5b050a8b289f109adab02a9e61a25de6", size = 177696, upload-time = "2026-07-06T21:34:26.355Z" }, { url = "https://files.pythonhosted.org/packages/2f/dd/afa2191fc6d57fedd26e5844a2fe2fcc0bbfa00961bbaa5a41e4921e7cca/cffi-2.1.0-cp315-cp315-win_amd64.whl", hash = "sha256:bccbbb5ee76a61f9d99b5bf3846a51d7fca4b6a732fe46f89295610edaf41853", size = 187914, upload-time = "2026-07-06T21:34:27.58Z" }, { url = "https://files.pythonhosted.org/packages/05/ef/6cd4f8c671517162379dc79cfae5aea9106bc38abb89628d5c16adf6a838/cffi-2.1.0-cp315-cp315-win_arm64.whl", hash = "sha256:8d35c139744adb3e727cd51b1a18324bbe44b8bd41bf8322bca4d41289f48eda", size = 183004, upload-time = "2026-07-06T21:34:28.905Z" }, { url = "https://files.pythonhosted.org/packages/11/b6/12fc55092817a5faa26fb8c40c7f9d662e11a46ee248c137aafc42517d92/cffi-2.1.0-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:f9912624a0c0b834b7520d7769b3644453aabc0a7e1c839da7359f050750e9bc", size = 188378, upload-time = "2026-07-06T21:34:09.926Z" }, { url = "https://files.pythonhosted.org/packages/8d/2e/cdac88979f295fde5daa69622c7d2111e56e7ceb94f211357fbe452339e4/cffi-2.1.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:df92f2aba50eb4d96718b68ef76f2e57a57b54f2fa62333496d16c6d585a85ca", size = 188319, upload-time = "2026-07-06T21:34:11.101Z" }, { url = "https://files.pythonhosted.org/packages/e0/27/1d0b408497e41a74795af122d7b603c418c5fed0171450f899afd04e594f/cffi-2.1.0-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0520e1f4c35f44e209cbbb421b67eec42e6a157f59444dfb6058874ff3610e5d", size = 223904, upload-time = "2026-07-06T21:34:12.606Z" }, { url = "https://files.pythonhosted.org/packages/8b/31/e115c985105dd7ffb32444505f18ceb874bb42d992af05d5dced7ecf1980/cffi-2.1.0-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:3681e031db29958a7502f5c0c9d6bbc4c36cb20f7b104086fa642d1799631ff8", size = 211554, upload-time = "2026-07-06T21:34:13.987Z" }, { url = "https://files.pythonhosted.org/packages/5a/67/9e6e09409336d9e515c58367e7cfcf4f89df06ad25252675595a58eb59d5/cffi-2.1.0-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:762f99479dcb369f60ab9017ad4ab97a36a1dd7c1ee5a3b15db0f4b8659120cd", size = 210795, upload-time = "2026-07-06T21:34:15.972Z" }, { url = "https://files.pythonhosted.org/packages/19/e5/d3cc82a4a0be7902af279c04181ad038449c096734464a5ae1de3e1401bd/cffi-2.1.0-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0611e7ebf90573a535ebdc33ae9da222d037853983e13359f580fab781ca017f", size = 223843, upload-time = "2026-07-06T21:34:17.509Z" }, { url = "https://files.pythonhosted.org/packages/b9/65/b434abc97ce7cecc2c640fde160507c0ecc7e21544b483ba3325d2e2ea17/cffi-2.1.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:86cf8755a791f72c85dc287128cc62d4f24d392e3f1e15837245623f4a33cccc", size = 226773, upload-time = "2026-07-06T21:34:19.05Z" }, { url = "https://files.pythonhosted.org/packages/b5/9f/d4dc66ca651eb1145a133314cda721abf13cfac3d28c4a0402263ae6ad75/cffi-2.1.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:ba00f661f8ba35d075c937174e27c2c421cec3942fd2e0ea3e66996757c0fdd9", size = 225719, upload-time = "2026-07-06T21:34:20.576Z" }, { url = "https://files.pythonhosted.org/packages/68/5a/e536c528bc8057496c360c0978559a2dc45653f89dd6151078aa7d8fca1a/cffi-2.1.0-cp315-cp315t-win32.whl", hash = "sha256:cb96698e3c7413d906ce83f8ffd245ec1bd94707541f299d0ce4d6b0193e982b", size = 182760, upload-time = "2026-07-06T21:34:22.059Z" }, { url = "https://files.pythonhosted.org/packages/d3/0b/0ffe8b82d3875bced5fa1e7986a7a46b748262a40ab7f60b475eb9fb1bb3/cffi-2.1.0-cp315-cp315t-win_amd64.whl", hash = "sha256:f146d154428a2523f9cc7936c02353c2459b8f6cf07d3cd1ee1c0a611109c5d5", size = 193769, upload-time = "2026-07-06T21:34:23.589Z" }, { url = "https://files.pythonhosted.org/packages/a0/17/1073b53b68c9b5ca6914adf5f8bf55aacc2d3be102418c90700160ea8605/cffi-2.1.0-cp315-cp315t-win_arm64.whl", hash = "sha256:cbb7640ce37159548d2147b5b8c241f962143d4c71231431820783f4dc78f210", size = 186405, upload-time = "2026-07-06T21:34:24.857Z" }, ] [[package]] name = "chardet" version = "7.6.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/b1/51/cd61c567092a6cec796144510a68aff158ebfc1df82950a45bae65f28413/chardet-7.6.0.tar.gz", hash = "sha256:93d9df6089ded42ed1fe9f57e272c0b74bd0464d45c0c7d50f09f26f31105c3c", size = 914462, upload-time = "2026-08-14T20:36:59.305Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/11/2e/d8634bee23a07bf512512ddf6218a68e47f045ae061c0cc80657ed79dcc0/chardet-7.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6424512f576fa7e88b7431d38a42d57552c8f717465a975fc42e497cd280d833", size = 1088243, upload-time = "2026-08-14T20:36:17.135Z" }, { url = "https://files.pythonhosted.org/packages/55/95/bd6d59026638cec47dace85858171fbecadd2f9e58cb2b973dc515aa790c/chardet-7.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:284136186ff90735f901ed0a1c6d41e7af67c666841cc0eceb58482a21b7056c", size = 1068688, upload-time = "2026-08-14T20:36:19.183Z" }, { url = "https://files.pythonhosted.org/packages/7f/4a/60ed03656b28c1f4d378bc3cfe8a6cdda62c7c289398f925610fbbabfd00/chardet-7.6.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5e9b31b9ae93872d66439b046a1e08c2ea99791f3c254dce1e2633e395c5587c", size = 1487945, upload-time = "2026-08-14T20:36:20.64Z" }, { url = "https://files.pythonhosted.org/packages/03/25/9c8db4f951e974a4db5558d9eea62e1fd5b5889c9d0ad0315eed67c5cdb3/chardet-7.6.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aa03322e07ac08d520ec50bb50c73143d0892d1adc067d4c5e58f4ef4b2363a8", size = 1510112, upload-time = "2026-08-14T20:36:22.248Z" }, { url = "https://files.pythonhosted.org/packages/76/1b/59eb88a78d8f5855c27c25788088df82834ad067f3dddaf4d86ef03cf2d3/chardet-7.6.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0ad9bc6dab4f338673353fa3f0dc96122f559aaf746087408106e2fcbf132fe8", size = 1462470, upload-time = "2026-08-14T20:36:23.557Z" }, { url = "https://files.pythonhosted.org/packages/02/af/46c80c317f9b4dd61f15c33b1e073fbdd64d13c70fe19e34943071dc9e50/chardet-7.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:360260d074d8712ac1e9048fcafb0fdde246f9d0b12555748ad0017c5ecee43d", size = 1157092, upload-time = "2026-08-14T20:36:25.082Z" }, { url = "https://files.pythonhosted.org/packages/6f/62/64da80dad0c804e743b4156f379183578f1e33918856ae928dc9248a6002/chardet-7.6.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:19fea52164e6e00f2a21ed418f42e4b0162a09199274c86d07ad3efd661317c4", size = 1094073, upload-time = "2026-08-14T20:36:26.53Z" }, { url = "https://files.pythonhosted.org/packages/44/99/934fb862d102c8756008597f4398323f32cef329f16e87fbb3bf76d4f4be/chardet-7.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a12023d48d0e207791c01161d03cb3c0d85c6a15f345eb9d3d56063a63d1e40f", size = 1071612, upload-time = "2026-08-14T20:36:28.067Z" }, { url = "https://files.pythonhosted.org/packages/71/e9/b04e0ec576a77e79fe37279a9a5d5b1ae752d365e43df2eca0d0eee4cea5/chardet-7.6.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:249993b88ac7a58cad2781acea8f379152a28a719c9b401d614898c63a8c83da", size = 1489219, upload-time = "2026-08-14T20:36:29.357Z" }, { url = "https://files.pythonhosted.org/packages/7d/a2/c4d99299e9ce7fad561f8bb56babbbbdd3bb6b4fbd7c0ec674c1dbdd2cc5/chardet-7.6.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2cf0adaca8b1c4bacfade9d0a1e4f8f70b1bb122833d6f07ab90e3adc84eb13a", size = 1518293, upload-time = "2026-08-14T20:36:30.879Z" }, { url = "https://files.pythonhosted.org/packages/56/1d/49f13052b74303bab2789d098063cbd19758217949ea54ffa216b6098cb3/chardet-7.6.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cf6d08c2373b7772a558d141f9e8cee53fe1d222341bac612e4d558b04995f73", size = 1459077, upload-time = "2026-08-14T20:36:32.149Z" }, { url = "https://files.pythonhosted.org/packages/0d/53/8da1f4758286efd8faf71356facddb382788ecf1bbd7c70d63e2e18a4898/chardet-7.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:406936df1328a3284fef366eaa2bfd1cccd0ef1b10cb99781dd5b022ea644b84", size = 1160778, upload-time = "2026-08-14T20:36:33.436Z" }, { url = "https://files.pythonhosted.org/packages/a3/29/16a7419edfbd60e901e6a797cbc3e038cb2a81903bc16c029db755f0156f/chardet-7.6.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:57e6846cc13ce1ff59979f4ec9da770c57e12aa99046073f632de5a51d9a6f20", size = 1088449, upload-time = "2026-08-14T20:36:34.723Z" }, { url = "https://files.pythonhosted.org/packages/1d/36/3a14b0f8ddeb302f157281ca656a3ce6874b78e2d6af03682f520b487245/chardet-7.6.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:089e3bb81a0a07e94f15461ded9f9ee66d349615b1a9fd557d4de1003e2fc12e", size = 1065126, upload-time = "2026-08-14T20:36:36.21Z" }, { url = "https://files.pythonhosted.org/packages/d2/4c/f59a39c2bfe4ac99baba8da842e8d2ea0b84dff7ba53a96e7ad8c71602d7/chardet-7.6.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:43ea433e43a23c55e8e17f3fad1e07f5cfe5450c73124b95b0d849c21ad379ee", size = 1482492, upload-time = "2026-08-14T20:36:37.649Z" }, { url = "https://files.pythonhosted.org/packages/bd/eb/93e8036681157f2217a18769927a035984526e6dbd5e91f28a375ca41c14/chardet-7.6.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2b5d31f9b7f793e15e81cca877e7ccd72bffffa2a3443a9d47be9dfee84fad69", size = 1514185, upload-time = "2026-08-14T20:36:39.119Z" }, { url = "https://files.pythonhosted.org/packages/10/04/0066d7ab2c135e404a6fa166bb7fa49d1c7bf7af07b86ed95b1c48a348c7/chardet-7.6.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c54b6a8d3b219560fa5cf4c28df932c37471afe047afdc152067104e741f38c1", size = 1454420, upload-time = "2026-08-14T20:36:40.549Z" }, { url = "https://files.pythonhosted.org/packages/6c/9f/e965f1d9eddfb86cf118f980d329cbee43c4ac4b562448b369a6b6ef36af/chardet-7.6.0-cp313-cp313-win_amd64.whl", hash = "sha256:b3b4c96c4df93899b3c8b9e8159e06b1f55c66d7ca384d91481108e251a06eb0", size = 1159067, upload-time = "2026-08-14T20:36:41.816Z" }, { url = "https://files.pythonhosted.org/packages/cf/78/e14991c9487277ed7d006fff58f3084ac792ed94cced081788abb95df70c/chardet-7.6.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:c6061adf247ab5dda173b67010e13904c6071717660c7c8077fb50aca362b264", size = 1087678, upload-time = "2026-08-14T20:36:43.2Z" }, { url = "https://files.pythonhosted.org/packages/7a/40/0f95e04cb1820e0a582cd6d86bbf26be8302a94ccf330f8ba5f69735389d/chardet-7.6.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:fc1e1571321baf8927582fe34363ad7f02279f11c8c2839c14b4c76894148db6", size = 1065310, upload-time = "2026-08-14T20:36:44.489Z" }, { url = "https://files.pythonhosted.org/packages/3b/a1/04404dcc9d6e1253b02583e562d2c7ddca50a7e91f460d62eff7e1d07c92/chardet-7.6.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8900f6c7cf6b015b17a51767cc6144689059ba1cdceaa383d29eb037ac28579e", size = 1485028, upload-time = "2026-08-14T20:36:45.797Z" }, { url = "https://files.pythonhosted.org/packages/f4/88/360064c4c7d9d0664561dae03b74c871d2f5332b329f5c99f1c997fb869a/chardet-7.6.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cedbc584789eb2edfde20fd03669972a833ce6019e60014ae613f9bfc440e8e3", size = 1510242, upload-time = "2026-08-14T20:36:47.206Z" }, { url = "https://files.pythonhosted.org/packages/43/4c/302869fa1c69a5a41e4e78782680b12552ffd4286c3ae3c839b7b8df53d4/chardet-7.6.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d5dc835e40e0e09c2c3eab43731a8b5127834f42786dda09ba2f4b699ccd527a", size = 1456456, upload-time = "2026-08-14T20:36:48.668Z" }, { url = "https://files.pythonhosted.org/packages/7c/a9/ff4fef15ed25fc3f945a3b981ae0f43c8559b3fbedb40267e59e583d105b/chardet-7.6.0-cp314-cp314-win_amd64.whl", hash = "sha256:0f304de7041afaec0195ad6464937cd112392002e9d72ed15d55f20a9abd3a13", size = 1159103, upload-time = "2026-08-14T20:36:50.107Z" }, { url = "https://files.pythonhosted.org/packages/31/44/94e6f89485ce6c630e8fec6d388e3fa747e58b7246b0cc8c5c532ba98650/chardet-7.6.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:a4f0a368ad04d5def08bdfaa17c7e15e71552f93923dc2aa9b2f7d9dee02fbb6", size = 1120302, upload-time = "2026-08-14T20:36:51.484Z" }, { url = "https://files.pythonhosted.org/packages/e0/cd/8e68ba12f13aaf4ee82d54ef8a1f83d62942e7a6bc1e579dd2d530a3e26e/chardet-7.6.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:75d6c3a4d2046d49e83d2d2206eb073a1f390743e856d90c1bbc19949b26acf4", size = 1093157, upload-time = "2026-08-14T20:36:52.987Z" }, { url = "https://files.pythonhosted.org/packages/f3/f6/6a35342b9efa69dcceab0ea8966571c6442a59c336bf460f0a2af95ed234/chardet-7.6.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:459e2b1c98f9a86a4698112aa42dffa802bbbff883c1ff144071f87224125862", size = 1521213, upload-time = "2026-08-14T20:36:54.812Z" }, { url = "https://files.pythonhosted.org/packages/df/8c/8f09bfabbaedae45caa72b996e96d5e3f6436dfddc55c1311ffa2f6bd7d2/chardet-7.6.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bdb6f03107b7ace3f44e0edd91aa24456ee558787df265cc19daf45785b31c7", size = 1528427, upload-time = "2026-08-14T20:36:56.224Z" }, { url = "https://files.pythonhosted.org/packages/0c/3d/2540627b193112e08b8045f3cad9295570866208555aa6625b63cc69c6cd/chardet-7.6.0-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:0c44a32da32cc8b23d6b20d98ace15ec7600950e4955d1bf5ab1f849b0187fdb", size = 1087374, upload-time = "2026-08-14T21:04:14.994Z" }, { url = "https://files.pythonhosted.org/packages/fe/de/dac4f550cde73c4732b4916e72ec489ae36933fbbd1697e4122d3ae2e9dd/chardet-7.6.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:7bbc8a9652c7f859c593847f220c1d264f25749369abb1a267b404ee8cceb209", size = 1064688, upload-time = "2026-08-14T21:04:16.806Z" }, { url = "https://files.pythonhosted.org/packages/06/45/f4f3f288496797d2cf1d1e9036f920ed2b4c79787b21c42a3314f4a6d532/chardet-7.6.0-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:83512a475a2f3886166aa0bca1bbb39343a4eb3186dd5532127d6f2591d09118", size = 1486320, upload-time = "2026-08-14T21:04:18.535Z" }, { url = "https://files.pythonhosted.org/packages/c0/81/3ca30c16e6c6015b737fca22d9342957cc617d8a65329d3e963ad754a31b/chardet-7.6.0-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:271ab71ec1be61dbbce0436de0848895c03eae051c379e937a39573d9ce403d9", size = 1515374, upload-time = "2026-08-14T21:04:20.724Z" }, { url = "https://files.pythonhosted.org/packages/6e/98/163a75b8b3372a6b6503f5f5a4154a222ac135c7a706b5d176f8e4b237a2/chardet-7.6.0-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:da86fc1b40ff5996fbb5e4c2d2dca770eac2c893cef157dacc050b8b4d929846", size = 1469504, upload-time = "2026-08-14T21:04:22.352Z" }, { url = "https://files.pythonhosted.org/packages/d7/4f/3ad1b1bd27ae7f0d3d13cf711366525cd781a9e067950d8a09aa280916cb/chardet-7.6.0-cp315-cp315-win_amd64.whl", hash = "sha256:b73f277c1ac09c4f8076c4214b816c7aa78a0a2f0cb7156742f4303f856bedc3", size = 1158551, upload-time = "2026-08-14T21:04:24.259Z" }, { url = "https://files.pythonhosted.org/packages/8d/92/22a609c68c5123ebdccd8fe1a80e423609012ce20166de19a2ed3955b2f7/chardet-7.6.0-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:61238d5945b36af9a2ad13494f8969b7deb3c3b4abe223e54670c064e73f5328", size = 1119186, upload-time = "2026-08-14T21:04:25.761Z" }, { url = "https://files.pythonhosted.org/packages/29/35/75a90143e4200e197f4f6cf5895d379e22bc785d0c7711120df18fa5347c/chardet-7.6.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:f2ec3c78cc6b54bf8e091ec4ee885473078b5d7ef18ab1b01c86ae1e98bf88f7", size = 1092596, upload-time = "2026-08-14T21:04:27.884Z" }, { url = "https://files.pythonhosted.org/packages/d1/2c/b6d5f47d878c46e04ae6fcb58e0969467925bc0819b333c682e0c41bbc5c/chardet-7.6.0-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:167d7ba3ee08b654e36d7b43ebd9a36606c9a12e2fabdb361757a095ca3b7e3d", size = 1516644, upload-time = "2026-08-14T21:04:29.624Z" }, { url = "https://files.pythonhosted.org/packages/25/d2/2bc3f1066c6f27bc3fa3a98dfd8a2a9c1e969a9d6bdc1edcd35278791fc4/chardet-7.6.0-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f14f46ef1977e41ce1f4814ca6984cea7f8b6baf8cbc6626ef7bf3d13cf7ea13", size = 1533221, upload-time = "2026-08-14T21:04:31.39Z" }, { url = "https://files.pythonhosted.org/packages/cf/6e/5a0b348fa4cd7847567a28c6e697ccf58391960bfd13a6e7473ee23ca2f2/chardet-7.6.0-py3-none-any.whl", hash = "sha256:4076d795897ce45239825956a1334e134322ecc4bfe84dbb12acd5390de0fbc1", size = 680279, upload-time = "2026-08-14T20:36:57.763Z" }, ] [[package]] name = "charset-normalizer" version = "3.4.7" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/e7/a1/67fe25fac3c7642725500a3f6cfe5821ad557c3abb11c9d20d12c7008d3e/charset_normalizer-3.4.7.tar.gz", hash = "sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5", size = 144271, upload-time = "2026-04-02T09:28:39.342Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/c2/d7/b5b7020a0565c2e9fa8c09f4b5fa6232feb326b8c20081ccded47ea368fd/charset_normalizer-3.4.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7", size = 309705, upload-time = "2026-04-02T09:26:02.191Z" }, { url = "https://files.pythonhosted.org/packages/5a/53/58c29116c340e5456724ecd2fff4196d236b98f3da97b404bc5e51ac3493/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7", size = 206419, upload-time = "2026-04-02T09:26:03.583Z" }, { url = "https://files.pythonhosted.org/packages/b2/02/e8146dc6591a37a00e5144c63f29fb7c97a734ea8a111190783c0e60ab63/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e", size = 227901, upload-time = "2026-04-02T09:26:04.738Z" }, { url = "https://files.pythonhosted.org/packages/fb/73/77486c4cd58f1267bf17db420e930c9afa1b3be3fe8c8b8ebbebc9624359/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c", size = 222742, upload-time = "2026-04-02T09:26:06.36Z" }, { url = "https://files.pythonhosted.org/packages/a1/fa/f74eb381a7d94ded44739e9d94de18dc5edc9c17fb8c11f0a6890696c0a9/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df", size = 214061, upload-time = "2026-04-02T09:26:08.347Z" }, { url = "https://files.pythonhosted.org/packages/dc/92/42bd3cefcf7687253fb86694b45f37b733c97f59af3724f356fa92b8c344/charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265", size = 199239, upload-time = "2026-04-02T09:26:09.823Z" }, { url = "https://files.pythonhosted.org/packages/4c/3d/069e7184e2aa3b3cddc700e3dd267413dc259854adc3380421c805c6a17d/charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4", size = 210173, upload-time = "2026-04-02T09:26:10.953Z" }, { url = "https://files.pythonhosted.org/packages/62/51/9d56feb5f2e7074c46f93e0ebdbe61f0848ee246e2f0d89f8e20b89ebb8f/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e", size = 209841, upload-time = "2026-04-02T09:26:12.142Z" }, { url = "https://files.pythonhosted.org/packages/d2/59/893d8f99cc4c837dda1fe2f1139079703deb9f321aabcb032355de13b6c7/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38", size = 200304, upload-time = "2026-04-02T09:26:13.711Z" }, { url = "https://files.pythonhosted.org/packages/7d/1d/ee6f3be3464247578d1ed5c46de545ccc3d3ff933695395c402c21fa6b77/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c", size = 229455, upload-time = "2026-04-02T09:26:14.941Z" }, { url = "https://files.pythonhosted.org/packages/54/bb/8fb0a946296ea96a488928bdce8ef99023998c48e4713af533e9bb98ef07/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b", size = 210036, upload-time = "2026-04-02T09:26:16.478Z" }, { url = "https://files.pythonhosted.org/packages/9a/bc/015b2387f913749f82afd4fcba07846d05b6d784dd16123cb66860e0237d/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c", size = 224739, upload-time = "2026-04-02T09:26:17.751Z" }, { url = "https://files.pythonhosted.org/packages/17/ab/63133691f56baae417493cba6b7c641571a2130eb7bceba6773367ab9ec5/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d", size = 216277, upload-time = "2026-04-02T09:26:18.981Z" }, { url = "https://files.pythonhosted.org/packages/06/6d/3be70e827977f20db77c12a97e6a9f973631a45b8d186c084527e53e77a4/charset_normalizer-3.4.7-cp311-cp311-win32.whl", hash = "sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad", size = 147819, upload-time = "2026-04-02T09:26:20.295Z" }, { url = "https://files.pythonhosted.org/packages/20/d9/5f67790f06b735d7c7637171bbfd89882ad67201891b7275e51116ed8207/charset_normalizer-3.4.7-cp311-cp311-win_amd64.whl", hash = "sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00", size = 159281, upload-time = "2026-04-02T09:26:21.74Z" }, { url = "https://files.pythonhosted.org/packages/ca/83/6413f36c5a34afead88ce6f66684d943d91f233d76dd083798f9602b75ae/charset_normalizer-3.4.7-cp311-cp311-win_arm64.whl", hash = "sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1", size = 147843, upload-time = "2026-04-02T09:26:22.901Z" }, { url = "https://files.pythonhosted.org/packages/0c/eb/4fc8d0a7110eb5fc9cc161723a34a8a6c200ce3b4fbf681bc86feee22308/charset_normalizer-3.4.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46", size = 311328, upload-time = "2026-04-02T09:26:24.331Z" }, { url = "https://files.pythonhosted.org/packages/f8/e3/0fadc706008ac9d7b9b5be6dc767c05f9d3e5df51744ce4cc9605de7b9f4/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2", size = 208061, upload-time = "2026-04-02T09:26:25.568Z" }, { url = "https://files.pythonhosted.org/packages/42/f0/3dd1045c47f4a4604df85ec18ad093912ae1344ac706993aff91d38773a2/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b", size = 229031, upload-time = "2026-04-02T09:26:26.865Z" }, { url = "https://files.pythonhosted.org/packages/dc/67/675a46eb016118a2fbde5a277a5d15f4f69d5f3f5f338e5ee2f8948fcf43/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a", size = 225239, upload-time = "2026-04-02T09:26:28.044Z" }, { url = "https://files.pythonhosted.org/packages/4b/f8/d0118a2f5f23b02cd166fa385c60f9b0d4f9194f574e2b31cef350ad7223/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116", size = 216589, upload-time = "2026-04-02T09:26:29.239Z" }, { url = "https://files.pythonhosted.org/packages/b1/f1/6d2b0b261b6c4ceef0fcb0d17a01cc5bc53586c2d4796fa04b5c540bc13d/charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb", size = 202733, upload-time = "2026-04-02T09:26:30.5Z" }, { url = "https://files.pythonhosted.org/packages/6f/c0/7b1f943f7e87cc3db9626ba17807d042c38645f0a1d4415c7a14afb5591f/charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1", size = 212652, upload-time = "2026-04-02T09:26:31.709Z" }, { url = "https://files.pythonhosted.org/packages/38/dd/5a9ab159fe45c6e72079398f277b7d2b523e7f716acc489726115a910097/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15", size = 211229, upload-time = "2026-04-02T09:26:33.282Z" }, { url = "https://files.pythonhosted.org/packages/d5/ff/531a1cad5ca855d1c1a8b69cb71abfd6d85c0291580146fda7c82857caa1/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5", size = 203552, upload-time = "2026-04-02T09:26:34.845Z" }, { url = "https://files.pythonhosted.org/packages/c1/4c/a5fb52d528a8ca41f7598cb619409ece30a169fbdf9cdce592e53b46c3a6/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d", size = 230806, upload-time = "2026-04-02T09:26:36.152Z" }, { url = "https://files.pythonhosted.org/packages/59/7a/071feed8124111a32b316b33ae4de83d36923039ef8cf48120266844285b/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7", size = 212316, upload-time = "2026-04-02T09:26:37.672Z" }, { url = "https://files.pythonhosted.org/packages/fd/35/f7dba3994312d7ba508e041eaac39a36b120f32d4c8662b8814dab876431/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464", size = 227274, upload-time = "2026-04-02T09:26:38.93Z" }, { url = "https://files.pythonhosted.org/packages/8a/2d/a572df5c9204ab7688ec1edc895a73ebded3b023bb07364710b05dd1c9be/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49", size = 218468, upload-time = "2026-04-02T09:26:40.17Z" }, { url = "https://files.pythonhosted.org/packages/86/eb/890922a8b03a568ca2f336c36585a4713c55d4d67bf0f0c78924be6315ca/charset_normalizer-3.4.7-cp312-cp312-win32.whl", hash = "sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c", size = 148460, upload-time = "2026-04-02T09:26:41.416Z" }, { url = "https://files.pythonhosted.org/packages/35/d9/0e7dffa06c5ab081f75b1b786f0aefc88365825dfcd0ac544bdb7b2b6853/charset_normalizer-3.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6", size = 159330, upload-time = "2026-04-02T09:26:42.554Z" }, { url = "https://files.pythonhosted.org/packages/9e/5d/481bcc2a7c88ea6b0878c299547843b2521ccbc40980cb406267088bc701/charset_normalizer-3.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d", size = 147828, upload-time = "2026-04-02T09:26:44.075Z" }, { url = "https://files.pythonhosted.org/packages/c1/3b/66777e39d3ae1ddc77ee606be4ec6d8cbd4c801f65e5a1b6f2b11b8346dd/charset_normalizer-3.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063", size = 309627, upload-time = "2026-04-02T09:26:45.198Z" }, { url = "https://files.pythonhosted.org/packages/2e/4e/b7f84e617b4854ade48a1b7915c8ccfadeba444d2a18c291f696e37f0d3b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c", size = 207008, upload-time = "2026-04-02T09:26:46.824Z" }, { url = "https://files.pythonhosted.org/packages/c4/bb/ec73c0257c9e11b268f018f068f5d00aa0ef8c8b09f7753ebd5f2880e248/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66", size = 228303, upload-time = "2026-04-02T09:26:48.397Z" }, { url = "https://files.pythonhosted.org/packages/85/fb/32d1f5033484494619f701e719429c69b766bfc4dbc61aa9e9c8c166528b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18", size = 224282, upload-time = "2026-04-02T09:26:49.684Z" }, { url = "https://files.pythonhosted.org/packages/fa/07/330e3a0dda4c404d6da83b327270906e9654a24f6c546dc886a0eb0ffb23/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd", size = 215595, upload-time = "2026-04-02T09:26:50.915Z" }, { url = "https://files.pythonhosted.org/packages/e3/7c/fc890655786e423f02556e0216d4b8c6bcb6bdfa890160dc66bf52dee468/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215", size = 201986, upload-time = "2026-04-02T09:26:52.197Z" }, { url = "https://files.pythonhosted.org/packages/d8/97/bfb18b3db2aed3b90cf54dc292ad79fdd5ad65c4eae454099475cbeadd0d/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859", size = 211711, upload-time = "2026-04-02T09:26:53.49Z" }, { url = "https://files.pythonhosted.org/packages/6f/a5/a581c13798546a7fd557c82614a5c65a13df2157e9ad6373166d2a3e645d/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8", size = 210036, upload-time = "2026-04-02T09:26:54.975Z" }, { url = "https://files.pythonhosted.org/packages/8c/bf/b3ab5bcb478e4193d517644b0fb2bf5497fbceeaa7a1bc0f4d5b50953861/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5", size = 202998, upload-time = "2026-04-02T09:26:56.303Z" }, { url = "https://files.pythonhosted.org/packages/e7/4e/23efd79b65d314fa320ec6017b4b5834d5c12a58ba4610aa353af2e2f577/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832", size = 230056, upload-time = "2026-04-02T09:26:57.554Z" }, { url = "https://files.pythonhosted.org/packages/b9/9f/1e1941bc3f0e01df116e68dc37a55c4d249df5e6fa77f008841aef68264f/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6", size = 211537, upload-time = "2026-04-02T09:26:58.843Z" }, { url = "https://files.pythonhosted.org/packages/80/0f/088cbb3020d44428964a6c97fe1edfb1b9550396bf6d278330281e8b709c/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48", size = 226176, upload-time = "2026-04-02T09:27:00.437Z" }, { url = "https://files.pythonhosted.org/packages/6a/9f/130394f9bbe06f4f63e22641d32fc9b202b7e251c9aef4db044324dac493/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a", size = 217723, upload-time = "2026-04-02T09:27:02.021Z" }, { url = "https://files.pythonhosted.org/packages/73/55/c469897448a06e49f8fa03f6caae97074fde823f432a98f979cc42b90e69/charset_normalizer-3.4.7-cp313-cp313-win32.whl", hash = "sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e", size = 148085, upload-time = "2026-04-02T09:27:03.192Z" }, { url = "https://files.pythonhosted.org/packages/5d/78/1b74c5bbb3f99b77a1715c91b3e0b5bdb6fe302d95ace4f5b1bec37b0167/charset_normalizer-3.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110", size = 158819, upload-time = "2026-04-02T09:27:04.454Z" }, { url = "https://files.pythonhosted.org/packages/68/86/46bd42279d323deb8687c4a5a811fd548cb7d1de10cf6535d099877a9a9f/charset_normalizer-3.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b", size = 147915, upload-time = "2026-04-02T09:27:05.971Z" }, { url = "https://files.pythonhosted.org/packages/97/c8/c67cb8c70e19ef1960b97b22ed2a1567711de46c4ddf19799923adc836c2/charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0", size = 309234, upload-time = "2026-04-02T09:27:07.194Z" }, { url = "https://files.pythonhosted.org/packages/99/85/c091fdee33f20de70d6c8b522743b6f831a2f1cd3ff86de4c6a827c48a76/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a", size = 208042, upload-time = "2026-04-02T09:27:08.749Z" }, { url = "https://files.pythonhosted.org/packages/87/1c/ab2ce611b984d2fd5d86a5a8a19c1ae26acac6bad967da4967562c75114d/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b", size = 228706, upload-time = "2026-04-02T09:27:09.951Z" }, { url = "https://files.pythonhosted.org/packages/a8/29/2b1d2cb00bf085f59d29eb773ce58ec2d325430f8c216804a0a5cd83cbca/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41", size = 224727, upload-time = "2026-04-02T09:27:11.175Z" }, { url = "https://files.pythonhosted.org/packages/47/5c/032c2d5a07fe4d4855fea851209cca2b6f03ebeb6d4e3afdb3358386a684/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e", size = 215882, upload-time = "2026-04-02T09:27:12.446Z" }, { url = "https://files.pythonhosted.org/packages/2c/c2/356065d5a8b78ed04499cae5f339f091946a6a74f91e03476c33f0ab7100/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae", size = 200860, upload-time = "2026-04-02T09:27:13.721Z" }, { url = "https://files.pythonhosted.org/packages/0c/cd/a32a84217ced5039f53b29f460962abb2d4420def55afabe45b1c3c7483d/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18", size = 211564, upload-time = "2026-04-02T09:27:15.272Z" }, { url = "https://files.pythonhosted.org/packages/44/86/58e6f13ce26cc3b8f4a36b94a0f22ae2f00a72534520f4ae6857c4b81f89/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b", size = 211276, upload-time = "2026-04-02T09:27:16.834Z" }, { url = "https://files.pythonhosted.org/packages/8f/fe/d17c32dc72e17e155e06883efa84514ca375f8a528ba2546bee73fc4df81/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356", size = 201238, upload-time = "2026-04-02T09:27:18.229Z" }, { url = "https://files.pythonhosted.org/packages/6a/29/f33daa50b06525a237451cdb6c69da366c381a3dadcd833fa5676bc468b3/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab", size = 230189, upload-time = "2026-04-02T09:27:19.445Z" }, { url = "https://files.pythonhosted.org/packages/b6/6e/52c84015394a6a0bdcd435210a7e944c5f94ea1055f5cc5d56c5fe368e7b/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46", size = 211352, upload-time = "2026-04-02T09:27:20.79Z" }, { url = "https://files.pythonhosted.org/packages/8c/d7/4353be581b373033fb9198bf1da3cf8f09c1082561e8e922aa7b39bf9fe8/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44", size = 227024, upload-time = "2026-04-02T09:27:22.063Z" }, { url = "https://files.pythonhosted.org/packages/30/45/99d18aa925bd1740098ccd3060e238e21115fffbfdcb8f3ece837d0ace6c/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72", size = 217869, upload-time = "2026-04-02T09:27:23.486Z" }, { url = "https://files.pythonhosted.org/packages/5c/05/5ee478aa53f4bb7996482153d4bfe1b89e0f087f0ab6b294fcf92d595873/charset_normalizer-3.4.7-cp314-cp314-win32.whl", hash = "sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10", size = 148541, upload-time = "2026-04-02T09:27:25.146Z" }, { url = "https://files.pythonhosted.org/packages/48/77/72dcb0921b2ce86420b2d79d454c7022bf5be40202a2a07906b9f2a35c97/charset_normalizer-3.4.7-cp314-cp314-win_amd64.whl", hash = "sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f", size = 159634, upload-time = "2026-04-02T09:27:26.642Z" }, { url = "https://files.pythonhosted.org/packages/c6/a3/c2369911cd72f02386e4e340770f6e158c7980267da16af8f668217abaa0/charset_normalizer-3.4.7-cp314-cp314-win_arm64.whl", hash = "sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246", size = 148384, upload-time = "2026-04-02T09:27:28.271Z" }, { url = "https://files.pythonhosted.org/packages/94/09/7e8a7f73d24dba1f0035fbbf014d2c36828fc1bf9c88f84093e57d315935/charset_normalizer-3.4.7-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24", size = 330133, upload-time = "2026-04-02T09:27:29.474Z" }, { url = "https://files.pythonhosted.org/packages/8d/da/96975ddb11f8e977f706f45cddd8540fd8242f71ecdb5d18a80723dcf62c/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79", size = 216257, upload-time = "2026-04-02T09:27:30.793Z" }, { url = "https://files.pythonhosted.org/packages/e5/e8/1d63bf8ef2d388e95c64b2098f45f84758f6d102a087552da1485912637b/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960", size = 234851, upload-time = "2026-04-02T09:27:32.44Z" }, { url = "https://files.pythonhosted.org/packages/9b/40/e5ff04233e70da2681fa43969ad6f66ca5611d7e669be0246c4c7aaf6dc8/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4", size = 233393, upload-time = "2026-04-02T09:27:34.03Z" }, { url = "https://files.pythonhosted.org/packages/be/c1/06c6c49d5a5450f76899992f1ee40b41d076aee9279b49cf9974d2f313d5/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e", size = 223251, upload-time = "2026-04-02T09:27:35.369Z" }, { url = "https://files.pythonhosted.org/packages/2b/9f/f2ff16fb050946169e3e1f82134d107e5d4ae72647ec8a1b1446c148480f/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1", size = 206609, upload-time = "2026-04-02T09:27:36.661Z" }, { url = "https://files.pythonhosted.org/packages/69/d5/a527c0cd8d64d2eab7459784fb4169a0ac76e5a6fc5237337982fd61347e/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44", size = 220014, upload-time = "2026-04-02T09:27:38.019Z" }, { url = "https://files.pythonhosted.org/packages/7e/80/8a7b8104a3e203074dc9aa2c613d4b726c0e136bad1cc734594b02867972/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e", size = 218979, upload-time = "2026-04-02T09:27:39.37Z" }, { url = "https://files.pythonhosted.org/packages/02/9a/b759b503d507f375b2b5c153e4d2ee0a75aa215b7f2489cf314f4541f2c0/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3", size = 209238, upload-time = "2026-04-02T09:27:40.722Z" }, { url = "https://files.pythonhosted.org/packages/c2/4e/0f3f5d47b86bdb79256e7290b26ac847a2832d9a4033f7eb2cd4bcf4bb5b/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0", size = 236110, upload-time = "2026-04-02T09:27:42.33Z" }, { url = "https://files.pythonhosted.org/packages/96/23/bce28734eb3ed2c91dcf93abeb8a5cf393a7b2749725030bb630e554fdd8/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e", size = 219824, upload-time = "2026-04-02T09:27:43.924Z" }, { url = "https://files.pythonhosted.org/packages/2c/6f/6e897c6984cc4d41af319b077f2f600fc8214eb2fe2d6bcb79141b882400/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb", size = 233103, upload-time = "2026-04-02T09:27:45.348Z" }, { url = "https://files.pythonhosted.org/packages/76/22/ef7bd0fe480a0ae9b656189ec00744b60933f68b4f42a7bb06589f6f576a/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe", size = 225194, upload-time = "2026-04-02T09:27:46.706Z" }, { url = "https://files.pythonhosted.org/packages/c5/a7/0e0ab3e0b5bc1219bd80a6a0d4d72ca74d9250cb2382b7c699c147e06017/charset_normalizer-3.4.7-cp314-cp314t-win32.whl", hash = "sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0", size = 159827, upload-time = "2026-04-02T09:27:48.053Z" }, { url = "https://files.pythonhosted.org/packages/7a/1d/29d32e0fb40864b1f878c7f5a0b343ae676c6e2b271a2d55cc3a152391da/charset_normalizer-3.4.7-cp314-cp314t-win_amd64.whl", hash = "sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c", size = 174168, upload-time = "2026-04-02T09:27:49.795Z" }, { url = "https://files.pythonhosted.org/packages/de/32/d92444ad05c7a6e41fb2036749777c163baf7a0301a040cb672d6b2b1ae9/charset_normalizer-3.4.7-cp314-cp314t-win_arm64.whl", hash = "sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d", size = 153018, upload-time = "2026-04-02T09:27:51.116Z" }, { url = "https://files.pythonhosted.org/packages/db/8f/61959034484a4a7c527811f4721e75d02d653a35afb0b6054474d8185d4c/charset_normalizer-3.4.7-py3-none-any.whl", hash = "sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d", size = 61958, upload-time = "2026-04-02T09:28:37.794Z" }, ] [[package]] name = "click" version = "8.5.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/c7/0e/7fa0ef50764b67090eca4114772a2abf8b6148198475e54c660b97caeee6/click-8.5.0.tar.gz", hash = "sha256:ba0d2089de75ea0310e2dde03160e6ca10009947fb95a182f9b54021bb272e34", size = 382235, upload-time = "2026-08-26T13:33:14.56Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/58/50/6c0d534c5f134586a8e1ba4e330569e32f057e33372ae556463212fb4cd3/click-8.5.0-py3-none-any.whl", hash = "sha256:255bc9599cf7748b4b1a446ccc735421bd08a2ae529a8b88597d3de5664ee360", size = 125251, upload-time = "2026-08-26T13:33:12.928Z" }, ] [[package]] name = "colorama" version = "0.4.6" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] [[package]] name = "coverage" version = "7.15.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/be/c3/4f2195f512fb172aa425a8803a874b2baa9ba7f80ff7b6080998761fc701/coverage-7.15.4.tar.gz", hash = "sha256:0548198fff07ccf4faf469520bce1c2eceb1ce3e62891921138dec10907f9d00", size = 936952, upload-time = "2026-08-06T13:50:24.442Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/2a/66/edcec7d7a0b524aa8923e22925fde6fe50ce005a113dca13ae1581455c4c/coverage-7.15.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bbac5abad70df71019988f83f26ac7092ff2642975def4429e98dc7585ef3490", size = 222367, upload-time = "2026-08-06T13:47:15.578Z" }, { url = "https://files.pythonhosted.org/packages/e6/c6/ab8de429e2e8548faf58ec7e1674a4ce00414b4113942d3fe87109cf0f68/coverage-7.15.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:357a173465c7ce028d07a95cc2b63b5bf59f50ecdd5ad75c5cbb78ada984048e", size = 222874, upload-time = "2026-08-06T13:47:16.961Z" }, { url = "https://files.pythonhosted.org/packages/be/c4/3b7b49587e8a6b9af79b3eb468d443d6042b6d65b47aa26586846a0d6566/coverage-7.15.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:21b803935e2efc3acebe9697197a294fccf5dc4e5382bd6369542ff7a7d2a1d7", size = 253287, upload-time = "2026-08-06T13:47:18.291Z" }, { url = "https://files.pythonhosted.org/packages/fb/65/ec03b743a2a229c72cc1eff3e57be9d3564e9c6b4d5aba2d70744a3fc0d8/coverage-7.15.4-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7a2b580774a4786c1053157c0165e04476e03ff293993d7c148eee784a94bae6", size = 255199, upload-time = "2026-08-06T13:47:19.765Z" }, { url = "https://files.pythonhosted.org/packages/41/4b/5163729e4b6582d61975cfd3ccab45b4ec53e21cf156d9941cb025188468/coverage-7.15.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a9464451c4efffe8d47ace5a540b10b0dc10e879066290f8600872b7f54a419d", size = 257308, upload-time = "2026-08-06T13:47:21.206Z" }, { url = "https://files.pythonhosted.org/packages/86/08/2167a0f08fb87d702fa423a48578a32865464b7c9e1db3911ad7812ab414/coverage-7.15.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:de602f34123c2f4af1c1869c6dbbbd60da6d5983bf01937367295d135cccbfce", size = 259268, upload-time = "2026-08-06T13:47:22.503Z" }, { url = "https://files.pythonhosted.org/packages/1e/e5/68eebae3053dbd48508edea559c21b23fbdf3460784f91370c83a86a6acd/coverage-7.15.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6879ded16a27f3eeca19b900c147e81616e7054db451471a611b2755ee5249f7", size = 253392, upload-time = "2026-08-06T13:47:23.88Z" }, { url = "https://files.pythonhosted.org/packages/1a/46/fd4ced40a2b691c774e515c9b69500bfa64c7960b67fcee4b2f6fad97fc3/coverage-7.15.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:986be58c3ab54aae8d3496a6225eea74f760fdbe739b38bd442c7e8d133aa53b", size = 255001, upload-time = "2026-08-06T13:47:25.469Z" }, { url = "https://files.pythonhosted.org/packages/53/25/ae2e5fa710bb6957a9aadeb9e3598d3b3e4af6587ce857ad42e8639a3f30/coverage-7.15.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c6103639613fe6c1e989082948419bc77a2d26b6c825c99d7fad25f7d3d87afc", size = 253061, upload-time = "2026-08-06T13:47:26.845Z" }, { url = "https://files.pythonhosted.org/packages/d7/31/67ddc0365db2c6e93ac8580bc4bbc50f65273262f973f63ebcdbc15c0495/coverage-7.15.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d3af93dddb5659276c63bc16ac6466ac2033a70ca816097bbc06345b8ccdf571", size = 256831, upload-time = "2026-08-06T13:47:28.217Z" }, { url = "https://files.pythonhosted.org/packages/f6/78/82b8fd18f57fb13f12d98fe874995bb2c4f9f17be8aff762c426323fdb96/coverage-7.15.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:b10075e5421d04265766a6d1dac809bbeb8a946fbb23c8f82c227409b2190719", size = 252781, upload-time = "2026-08-06T13:47:29.712Z" }, { url = "https://files.pythonhosted.org/packages/0a/eb/6c74ef4dd12b252e573c49bdef9e2ac265bf3dbb79b8d7feb3266e084e9e/coverage-7.15.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a67a9f78b2942d87ba8ce3059c642164d2aedd65337377fb52fe9803656bc5c7", size = 253692, upload-time = "2026-08-06T13:47:31.192Z" }, { url = "https://files.pythonhosted.org/packages/5a/66/eb9aed1c3fd2d36ee00eb173f434b14fa607fc056739c9a89ff4244010ea/coverage-7.15.4-cp311-cp311-win32.whl", hash = "sha256:69484d1aca26e322e1c3ce03f09341e84524ababad2d7202161738d83cc9f82e", size = 224461, upload-time = "2026-08-06T13:47:32.572Z" }, { url = "https://files.pythonhosted.org/packages/e2/6d/81fa4161dfb3ed9d74e40d58647eff83a56b7612e78352581280fce2f477/coverage-7.15.4-cp311-cp311-win_amd64.whl", hash = "sha256:63fd6fcd1dd6e158f7eb78606e72933b3f6d01e7b747f99c6c12d764307a0fdc", size = 224937, upload-time = "2026-08-06T13:47:34.205Z" }, { url = "https://files.pythonhosted.org/packages/5b/c1/d8dacf683c6cad3cf85ce68fd3774a6774ec402128822fdfaed920f11e6a/coverage-7.15.4-cp311-cp311-win_arm64.whl", hash = "sha256:ea82116c9893fa89e929b7f197ee5a1950a76e91cc5c85ba503fc02379d04890", size = 224479, upload-time = "2026-08-06T13:47:36.118Z" }, { url = "https://files.pythonhosted.org/packages/1d/48/bc8d4ba7b37551a767bd863f15b3f80182b271c2f55975356f5f7dbe94c2/coverage-7.15.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d4fedd1f7f428f9fe83b1ead5e7cc87a43427be31aadafbac3ac0636dc7abb22", size = 222543, upload-time = "2026-08-06T13:47:37.562Z" }, { url = "https://files.pythonhosted.org/packages/20/dd/88d6f83f1fffc974a3691a34a97951c5b12df7512a6782c5963883cbc058/coverage-7.15.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:37e2f0cdf58e2e1fed4e4d5a8f8786ae2f7eb80b478016876667dc4a01d60a97", size = 222905, upload-time = "2026-08-06T13:47:38.927Z" }, { url = "https://files.pythonhosted.org/packages/bd/5c/54ee0d4748585bb0acab9891cd8d92f2d3593165b4e59fc9de113bfb3140/coverage-7.15.4-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:fb55d0e70bb15f2e81477613627286581414693d74ac7963c93a790dd453ca9d", size = 254407, upload-time = "2026-08-06T13:47:40.488Z" }, { url = "https://files.pythonhosted.org/packages/8c/3f/f0642a372f494bd0d7dad3b497083b910194a5f1c88be2c94fef707c3b59/coverage-7.15.4-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:899b9da30f3c6c336566e3707495bb23e8302d39d862f01fa78c48b99b9437e2", size = 257145, upload-time = "2026-08-06T13:47:41.931Z" }, { url = "https://files.pythonhosted.org/packages/71/17/8b46d0ed68251016002ec972c8fc0119961a765d0984cafb8bf317c43758/coverage-7.15.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d15715e8c46552827e5e4f30a35575a2dbcad14454cf3284c54483946bd16931", size = 258257, upload-time = "2026-08-06T13:47:43.527Z" }, { url = "https://files.pythonhosted.org/packages/30/b8/8498a0e72d0adbe15477dd07463d2b3bb2c9f6a4815e8589e50939e2c3ae/coverage-7.15.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:002a438859f7b430bc99afeaf01a6d187dad1d0dc907b64cdeffc632a5db8fd8", size = 260517, upload-time = "2026-08-06T13:47:45.121Z" }, { url = "https://files.pythonhosted.org/packages/41/e1/7dce19c3bdb1e3dd63e769508216500edad81bd5f69a26d724e32aceaf78/coverage-7.15.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e4193a04b518f7968f3099755f5509ee7cccc6dc2b92a6b14841934d22e222c9", size = 254785, upload-time = "2026-08-06T13:47:46.541Z" }, { url = "https://files.pythonhosted.org/packages/dd/b1/e1494703c675a2561723cd9b89f45c9168782c31280c611b1f767851e57c/coverage-7.15.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e98dcc55d572b38e69d117da7e8e8efb8500f1f5eaf81ecd460a63220790b839", size = 256176, upload-time = "2026-08-06T13:47:48.155Z" }, { url = "https://files.pythonhosted.org/packages/73/76/a5629d270fb638a43a4b10466f51e2f49d532c1aa4da2913cbbb150bbe0a/coverage-7.15.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:af6c538498ce66c10d3fd541c2a8d5b03da5850355add34e6cba564210cb9e72", size = 254321, upload-time = "2026-08-06T13:47:49.757Z" }, { url = "https://files.pythonhosted.org/packages/ff/4f/9c44447218435d5766b911534f9d798144a5560f85e9a54ebe5f3f5d19f9/coverage-7.15.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1d10025d96ea89fc2f73714dbc4cbd433fe012c1ac9e23f895d7728b238b6e52", size = 258390, upload-time = "2026-08-06T13:47:51.248Z" }, { url = "https://files.pythonhosted.org/packages/de/36/c1e127616fb3fa18a9ff71e76c417f2fd7424332a4870015ac224ef4c039/coverage-7.15.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d802e1947603162ded419bff83ac7489820355d2b856dfb09206574e3a37ac0c", size = 253894, upload-time = "2026-08-06T13:47:52.816Z" }, { url = "https://files.pythonhosted.org/packages/e9/b9/fdb92c8ae7a8bb9b850cc253b7b3b9c8526f68130002048b5671cd510d09/coverage-7.15.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c2de40895718f91951b86712b4c5b694acaf9a0a49be13874896f599a1eed3f4", size = 255763, upload-time = "2026-08-06T13:47:54.296Z" }, { url = "https://files.pythonhosted.org/packages/6f/c0/a7d51b2587c7bdb76e71b0896d2565bf7d60436b5122fc83e511adb1f7cd/coverage-7.15.4-cp312-cp312-win32.whl", hash = "sha256:5c3431b2161279b7db5c2a1aa58ae02e5cb8c3c42d93a5094be3f5537bd5b11b", size = 224597, upload-time = "2026-08-06T13:47:56.074Z" }, { url = "https://files.pythonhosted.org/packages/49/b9/5c5f80cc55f5acaaca6dee677626bfcec8c87204a7809b438b08e84f4571/coverage-7.15.4-cp312-cp312-win_amd64.whl", hash = "sha256:6befeab5fb2b51c958ca4ac6c5d141a1e8240f4f76e46350f1911963deda49cd", size = 225135, upload-time = "2026-08-06T13:47:57.52Z" }, { url = "https://files.pythonhosted.org/packages/47/e4/2a4561f89ff6bf7c925c287d0f2cce8bdf139c3a33735c87e3203401cf94/coverage-7.15.4-cp312-cp312-win_arm64.whl", hash = "sha256:67bc345491ab55b837277d76f5775d057e8c7f1ac44d890d8c2c82adde258c6f", size = 224515, upload-time = "2026-08-06T13:47:58.977Z" }, { url = "https://files.pythonhosted.org/packages/f1/84/651a9310859673aaa3b3203f1aa1641ca60fcf2494683e1c9474c7172780/coverage-7.15.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c705b28feb2775dc82a25f1d473a370bc37ff93f5177f4e29ce2425f560f6921", size = 222565, upload-time = "2026-08-06T13:48:00.796Z" }, { url = "https://files.pythonhosted.org/packages/82/f9/4dcf700137e8af550670f4d74d1b63828ce93e1e2b05e5f10710eb2ea987/coverage-7.15.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3ff205ab5e3ecc670f6a4dd19d9cbf12ede53dd41cfc1e15716ec961ea6d314e", size = 222936, upload-time = "2026-08-06T13:48:02.391Z" }, { url = "https://files.pythonhosted.org/packages/07/4a/612ff1e780b3fbfd637486f542f84adc5503873d8b5d279dec1ffeef9414/coverage-7.15.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5172326e861a38b48b48befca15e0f477a26b283337a33a739c8fed229934e36", size = 253926, upload-time = "2026-08-06T13:48:04.382Z" }, { url = "https://files.pythonhosted.org/packages/b0/04/d1cff1c2ead4708a6a79c01d3736b6a25bd38a36678398f72a8dd33dfad9/coverage-7.15.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:12b59c90084e3234fb11184886bf4a40f4f16a8c8f867be2e087b81f8e8868d4", size = 256523, upload-time = "2026-08-06T13:48:05.996Z" }, { url = "https://files.pythonhosted.org/packages/b9/80/d34e13fb4b293cbdb9665838cf5522077b8ad14ef947550631a4bced36a5/coverage-7.15.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:349062d66f00b40fa2c1c222438bad25fabf755631b5d82937fe985c8008615c", size = 257759, upload-time = "2026-08-06T13:48:08.036Z" }, { url = "https://files.pythonhosted.org/packages/0f/e7/2c5fe7636fdb0732fe0f09f308a5b066864078b7fc61f6678e8478554f2e/coverage-7.15.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4256ced708e598e05209bc1a8ab4074e04a51dba4c62fb45926a229af675ace7", size = 259890, upload-time = "2026-08-06T13:48:09.834Z" }, { url = "https://files.pythonhosted.org/packages/92/28/9689f0858dfff59c2ea688938ab9fa2925631235df67126a42b6c5c70ae1/coverage-7.15.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d80f974b20782d9612c8b4c9beeca867074c7cf4079d1419843fa25a26428b25", size = 254121, upload-time = "2026-08-06T13:48:11.459Z" }, { url = "https://files.pythonhosted.org/packages/f9/e2/785077c230c157243eb5aa9a26c3be260ecd02001bead54a3cada3df8e03/coverage-7.15.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2e179f19bfe1d31f8eeeaa12990194d761c4f62f0759661000bca6cd8729f40b", size = 255891, upload-time = "2026-08-06T13:48:13.209Z" }, { url = "https://files.pythonhosted.org/packages/d4/90/e20371b17b40f912f21305c2db2f30efa3de306f7320fc916804872c85a4/coverage-7.15.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8bc16bb47b7679670eceff71d78bfb7d6e5b143f6c2cd117487ec7c75e0d4b78", size = 253859, upload-time = "2026-08-06T13:48:14.736Z" }, { url = "https://files.pythonhosted.org/packages/05/49/25371987ee459a5f67c0427fb75c74f9358e65f2c71fe75bf41c1b6c5fcb/coverage-7.15.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1cd685005cd2c4200adfc14cf39a603b9320efab3f18a8f7f156d20c9cc3345f", size = 258011, upload-time = "2026-08-06T13:48:16.464Z" }, { url = "https://files.pythonhosted.org/packages/30/6e/32e67467f6154bf4f1c4f63b05acc5097cba4237d45bbeeea446b52e8ac1/coverage-7.15.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:337399ad2c93b3acd2a937627dae8b3e86b66707cd3d3e856347999aadf1ef8d", size = 253676, upload-time = "2026-08-06T13:48:18.493Z" }, { url = "https://files.pythonhosted.org/packages/03/c1/8b24192e89286399765155251f99ee9f070a9d637109018ac23d99b99f6f/coverage-7.15.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:96e257121228ec5cd2bb919276e94ac11074471bc37d68dbae0e8308cce15fff", size = 255453, upload-time = "2026-08-06T13:48:20.057Z" }, { url = "https://files.pythonhosted.org/packages/16/6f/8b41ebdf67c87854e17c035336a90f1cfbad0c14c2a584301be6ff148718/coverage-7.15.4-cp313-cp313-win32.whl", hash = "sha256:c65a9e0dfc6143491879da4e13b5e30f8be192055de508d737fb14601edbd22c", size = 224605, upload-time = "2026-08-06T13:48:21.655Z" }, { url = "https://files.pythonhosted.org/packages/e0/e2/2946c7f0b42b152ecb21ff1bdad72e3d301e790c0c487e4a86e8c9f69347/coverage-7.15.4-cp313-cp313-win_amd64.whl", hash = "sha256:2ff8f5e9b8f7a94f0c11c45631eee103dbcb7d63274edd12c56efe1be690b3b4", size = 225148, upload-time = "2026-08-06T13:48:23.376Z" }, { url = "https://files.pythonhosted.org/packages/9e/83/3f4a69957f48ae7a0aba76c34743f88963d607b19e03f3f8e66f91cae0f9/coverage-7.15.4-cp313-cp313-win_arm64.whl", hash = "sha256:6e0a8a5083b096487d6cfced94cdd514d8f5db6f113610fb36c0620edb1028cf", size = 224536, upload-time = "2026-08-06T13:48:25.117Z" }, { url = "https://files.pythonhosted.org/packages/ea/ac/748cf29eeb2d6be34a3176ce26a4f49e38085ee08e8935f05f6f26ed7e0f/coverage-7.15.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:770e9325ab5ea6d56f77e59b29ecfe0ac20b57a82a601876f90494a4dda0386f", size = 222608, upload-time = "2026-08-06T13:48:26.806Z" }, { url = "https://files.pythonhosted.org/packages/0b/02/1abbf5c984677b0aa439cdacaccbf38d248939d8ef8fe1cc7a50d73edb77/coverage-7.15.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d12b33a3a50a1676b7784dc8d00a0c6d66a9f2add4b85a041c19b6a7e53ef23c", size = 222940, upload-time = "2026-08-06T13:48:28.432Z" }, { url = "https://files.pythonhosted.org/packages/eb/e1/ff8f9f53d9fcf586125b55d0b1f04ec1c14955fee41e83d5814bee141bb5/coverage-7.15.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5669c8378ebde86f5def7a25d29586631b58acc27ffde04399f678f3dfc6e082", size = 253985, upload-time = "2026-08-06T13:48:29.995Z" }, { url = "https://files.pythonhosted.org/packages/a1/26/595759762e514e81be1d7d01ed03444303bcd152226a6529998d253f9201/coverage-7.15.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:ff97a14362eef486483ed44042ca2027ea257df6ff768e62358ee0c9776925ac", size = 256492, upload-time = "2026-08-06T13:48:31.634Z" }, { url = "https://files.pythonhosted.org/packages/24/68/b79aabac54d482be23b5fcdd4f4662bff24a78edc4ee29201726929936d5/coverage-7.15.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5a325e815318638aed1655d9c06e6d7c2d3d46c09231ce988070428a8762d734", size = 257837, upload-time = "2026-08-06T13:48:33.186Z" }, { url = "https://files.pythonhosted.org/packages/09/0f/bf7f297885a5bf6fd71e5782404e0ff059ca09e8711ceb3a08544abde45a/coverage-7.15.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:474223409d88eb20d2d6a0d37ea60e8647a65a90cc008dc1f0410af5f64f1e0d", size = 260152, upload-time = "2026-08-06T13:48:34.75Z" }, { url = "https://files.pythonhosted.org/packages/fd/f1/296744e854ff8368542343457414380465e9ceefb9192342feb9d3bc461d/coverage-7.15.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7f2f62ae3cd189dd2e13aece758c57b3eecbd27be070dbd4cbd10936049e5dbf", size = 253978, upload-time = "2026-08-06T13:48:36.434Z" }, { url = "https://files.pythonhosted.org/packages/55/b0/bbdb2e9057493e66220a2e149ca2d301ba0e3a58a83bd6b90de9826d16f3/coverage-7.15.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:39ece820e29e0a2ba34b3ecb3be83c27e997eed8926f2ba6fe7ce7a0bda5843b", size = 255846, upload-time = "2026-08-06T13:48:38.317Z" }, { url = "https://files.pythonhosted.org/packages/96/e4/38015b2b6d21258713bd17e76b59d033b191efb5703589cffd037dfbca20/coverage-7.15.4-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:f21b56dcace11dfe013014201f577dcd592b2a9b72182d930361b47cf6f73f25", size = 253808, upload-time = "2026-08-06T13:48:39.993Z" }, { url = "https://files.pythonhosted.org/packages/0b/64/0d515c1e60ee6fbfd1a0e79c07cd87d388a233b7adc37758735677203808/coverage-7.15.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:93a3a0b662abcc10c73a47cbc72cd60f63618d6989fb2d1286e50eacd974f303", size = 258081, upload-time = "2026-08-06T13:48:41.971Z" }, { url = "https://files.pythonhosted.org/packages/91/71/04d9e7a3642146c6351338aef4ef85ab11dbbb54744c13245caba1aad1c0/coverage-7.15.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:141fae2cabf5569b782c10afc4c850ce10f618c13f8db54765cba99cc839da1f", size = 253624, upload-time = "2026-08-06T13:48:43.731Z" }, { url = "https://files.pythonhosted.org/packages/b4/a7/6c28b74c81ebff66987b0e2522ba5cffa3e90b0c33cb6a2eb264d4ee8cf1/coverage-7.15.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:81294c7e6ab30c5f74c0353b11b2fd6320e72d9bee6ac73b357caa8b916323a5", size = 255280, upload-time = "2026-08-06T13:48:45.58Z" }, { url = "https://files.pythonhosted.org/packages/52/af/bc19996a7014b98d7bbb0f0939453c67074af65784a3aa16a789a07381fa/coverage-7.15.4-cp314-cp314-win32.whl", hash = "sha256:7bbd7d6418e0dab31a206af5203bd43ae36edb8e7fba1940b055d3e9249290d7", size = 224768, upload-time = "2026-08-06T13:48:47.525Z" }, { url = "https://files.pythonhosted.org/packages/ee/90/219484e476d6e101ba0a444852579e05f5b75c37c611a42ed1190f73ef62/coverage-7.15.4-cp314-cp314-win_amd64.whl", hash = "sha256:f0204ed122758782970526057093f448051a39db9d810d4e344bb87a3546f425", size = 225259, upload-time = "2026-08-06T13:48:49.513Z" }, { url = "https://files.pythonhosted.org/packages/b7/66/fa77daf4e383e5f776dac62c2409b6af81910ae6fe326bd5170dba74cc63/coverage-7.15.4-cp314-cp314-win_arm64.whl", hash = "sha256:9e71e7bc71c686a123347ae47a0de33a175e797a85bb57b791492adf4eec8ed8", size = 224684, upload-time = "2026-08-06T13:48:51.235Z" }, { url = "https://files.pythonhosted.org/packages/58/5b/f03bf0ce362bbf3f785fa5219620d00778d4ac6fc9e407734828e9c672f6/coverage-7.15.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7c922735321eef3f87c280a3d39afff6b646723a2880b862cda4ac7a093b8aa8", size = 223338, upload-time = "2026-08-06T13:48:52.896Z" }, { url = "https://files.pythonhosted.org/packages/0f/76/e77d0ae22501831cc9f92193e8a957a5caa1dd177f90a6d1d9b106242d92/coverage-7.15.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f41c17c4668a655ce96d090d8d5ffdc24ef64b5a02f9753884d08483e8a4a41a", size = 223609, upload-time = "2026-08-06T13:48:54.688Z" }, { url = "https://files.pythonhosted.org/packages/82/1a/b1f089da8d38ac612fa2dd6dc7f4a1a7657d12f3e261d2996edd3a838d0b/coverage-7.15.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:46822e9b6ff1c6a72b518c162c44a8f45a61a1d609c51084bf5b16c023c5037b", size = 264970, upload-time = "2026-08-06T13:48:56.403Z" }, { url = "https://files.pythonhosted.org/packages/bf/31/e66d98d6e9c7fcc88470f1e234eaf6b1950dc0dfbf797f7282c1c861da24/coverage-7.15.4-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:3d6f4955b73b5445271379a59e3792b0d978f42d4a01e0cf7a67d9c33a3bb0a5", size = 267088, upload-time = "2026-08-06T13:48:58.41Z" }, { url = "https://files.pythonhosted.org/packages/59/a1/ae94eb2c541add426378408379f233591e069040b1e2cdb33df9498a0682/coverage-7.15.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3fc9e047706fb4a9abb54f719d3aa643e80e5bb3818182c40aee01ac0f0247ba", size = 269508, upload-time = "2026-08-06T13:49:00.42Z" }, { url = "https://files.pythonhosted.org/packages/9c/c7/88a10694a1c6a213569766aba9f25847b28155d4ac731b13226db216356d/coverage-7.15.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:05e491d4f3165d62d4f5c8fd48dfeabf2ae8f42cbbd484319af33ea851b78982", size = 270629, upload-time = "2026-08-06T13:49:02.234Z" }, { url = "https://files.pythonhosted.org/packages/b3/34/d8b8232e5e55169933b59aabcef2fedfa4b9d8897361bb80fcbda146505f/coverage-7.15.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:226c66e80ec0598d3b9b4874123df167ccca342aca8714f77cac6829688ee09c", size = 264043, upload-time = "2026-08-06T13:49:04.102Z" }, { url = "https://files.pythonhosted.org/packages/7e/35/58b009dbf8c471c7224716478b9fed4a7e1af15320e1ed41660978504663/coverage-7.15.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ac41cc14bebda0dbfb0628036b7f75706935c95bcc07fefe9a0f93614aa60a57", size = 266963, upload-time = "2026-08-06T13:49:05.821Z" }, { url = "https://files.pythonhosted.org/packages/62/aa/57fbda1b42c892968273c56b6ee9dc0f1310850859230a507bc7873b1f65/coverage-7.15.4-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:8af623e5cd92080acddd02b38f2f406a2c3a0893c38950b211890361448fbf26", size = 264569, upload-time = "2026-08-06T13:49:07.706Z" }, { url = "https://files.pythonhosted.org/packages/98/8a/360e6e7f24d477b7e889703af0afa878d15b6d4d8d2a822b2835c169a879/coverage-7.15.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:07545711d4f0f32852a18f18ad11f76f0109909d09e78b9008b4cfc67e829429", size = 268299, upload-time = "2026-08-06T13:49:09.587Z" }, { url = "https://files.pythonhosted.org/packages/4e/89/6f701261aee21b6b5fa8f7872229406dc917e125069448292223bf213606/coverage-7.15.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:a0865421cfdc53654b342d515e5a233187590882d20b95752150e53f65460017", size = 263413, upload-time = "2026-08-06T13:49:11.604Z" }, { url = "https://files.pythonhosted.org/packages/3f/0f/6f04036edc260ed425af83e834f627fad48941ce97b50bfe6edd8b6fa623/coverage-7.15.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:460115e32ee40566476db5048f9bec1e842c127ad8e6f8be745aad3ac9cbc839", size = 265725, upload-time = "2026-08-06T13:49:13.38Z" }, { url = "https://files.pythonhosted.org/packages/c4/ce/d19b5d4d5c49a7bfb925fd74310fee7d28bc99520ac3367ccbc54e662518/coverage-7.15.4-cp314-cp314t-win32.whl", hash = "sha256:cbde877ef9dd7baf272b9bfef2b8a25edd45d9170fc326951dd20eb480335e85", size = 225079, upload-time = "2026-08-06T13:49:15.265Z" }, { url = "https://files.pythonhosted.org/packages/26/bb/7aa1b3b173faee0679037ca950bbbe1247273656697994d8d13f80f8d4b4/coverage-7.15.4-cp314-cp314t-win_amd64.whl", hash = "sha256:3da9e92d1c551fd7563833e9ade686efb0c4b7363ab7681a94283958c950bf5e", size = 225911, upload-time = "2026-08-06T13:49:17.279Z" }, { url = "https://files.pythonhosted.org/packages/81/1c/4ea9e47426d80038d9222db3c4534cb6021a74b237d3ff97ffd33b6600dd/coverage-7.15.4-cp314-cp314t-win_arm64.whl", hash = "sha256:3a54f5a0d85050c73a38f6793090ee83974531e67fe5e57a1da9bee11398aa5e", size = 225219, upload-time = "2026-08-06T13:49:19.293Z" }, { url = "https://files.pythonhosted.org/packages/2b/c4/dc5d2ac8f9142e7ec7de66e7bf0591db29d78955a040bd915870d9c0e657/coverage-7.15.4-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:2c9872e4d9dc5d3cf616bf4b382f5a00359305a5be666a3dd0b5cdb4e49597f9", size = 222604, upload-time = "2026-08-06T13:49:21.279Z" }, { url = "https://files.pythonhosted.org/packages/70/39/33e63df81fe2ee100897451841c821467635923e58e37c6bd4b46dd8106c/coverage-7.15.4-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:e101dbb4b9b72f0cddd8cdc8c9c5b47f456766f5e0ac82dbfb75e5c55409b78a", size = 222944, upload-time = "2026-08-06T13:49:23.187Z" }, { url = "https://files.pythonhosted.org/packages/99/1f/ef3ffb5557febc75a0d97aa459d0266d7d741110265121cc6d8539343d44/coverage-7.15.4-cp315-cp315-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7d1abebdb047729e852b9c77a00497dfbeb11eb3a117e037d7dbc3ac8e5f5c54", size = 254050, upload-time = "2026-08-06T13:49:25.008Z" }, { url = "https://files.pythonhosted.org/packages/6f/f5/1f0f6f77698c3601ca0ae7431e34b24c62ca2f06fecb23b73ed1f651d2be/coverage-7.15.4-cp315-cp315-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d28a4a899354d0ea6214cc59b4fa19eefbce1b9ff1688ab579acf49e894bd3fb", size = 256967, upload-time = "2026-08-06T13:49:26.896Z" }, { url = "https://files.pythonhosted.org/packages/03/7a/2ed9bed79925f4367c83c77f66a89e5ca7229c288d2d19ad5f36d1ca0070/coverage-7.15.4-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ffb3c2aacea411cc7e1d27712490c11108e2de1d39019ae32915493a59a8b9ed", size = 258587, upload-time = "2026-08-06T13:49:28.692Z" }, { url = "https://files.pythonhosted.org/packages/45/8c/fa34044f71b7cc4ecb6da9c2408770959b0591fa9b5fb6fb6bca38f94298/coverage-7.15.4-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a9447978a92f405d301123cfd39ff49895490efb769a758fe2734c7f631bf8ce", size = 260785, upload-time = "2026-08-06T13:49:30.472Z" }, { url = "https://files.pythonhosted.org/packages/4f/54/d5727ce36b4524a7394ab9f5f1df378e1f23affcdab01037dc8655185cc7/coverage-7.15.4-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:050467a7983b8e2fe7dd41a78bb30c3e7f8c0b8cafda14b1c46f8b5e3cf2dd3c", size = 254545, upload-time = "2026-08-06T13:49:32.271Z" }, { url = "https://files.pythonhosted.org/packages/dc/e6/6e3783e576719590194bdffb6dd6d85490801785b7c331e35a245d8cb8b5/coverage-7.15.4-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:d003b7a5708ddad5c206c79607a6b92abb6fc13c57d99d8a4468cc03a2941ced", size = 256682, upload-time = "2026-08-06T13:49:34.089Z" }, { url = "https://files.pythonhosted.org/packages/dc/f2/bacdbde18b69ed2de424fcf64d9fb0a4913753d4f0eca8bae9daad69f4bd/coverage-7.15.4-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:c38efe30fd74e5c19e9433f11fb1f5dc9c6522770971b7c6145bbaa413dc8800", size = 254560, upload-time = "2026-08-06T13:49:36.052Z" }, { url = "https://files.pythonhosted.org/packages/6c/a3/1fb927196e3477c1b48831169ab58ba08f451ba87ae311ff1de68b26a616/coverage-7.15.4-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:1f4f826d70f772ab8b0c052329580d7fe8b8abd191e4ce0c8f81aec6614665d3", size = 258792, upload-time = "2026-08-06T13:49:38.01Z" }, { url = "https://files.pythonhosted.org/packages/41/58/30d4c149c69053de0edfe325614c1d28d508f62b1783e0e4a234d2e49136/coverage-7.15.4-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:4a4bf917c9953f57c957be31c1cd504e3bd2f34d4a352b9d391a3025336f6768", size = 253968, upload-time = "2026-08-06T13:49:39.934Z" }, { url = "https://files.pythonhosted.org/packages/89/e4/77f639371b918aad30dda4051f95404b43578f7f2e2f87ba73e02ed1ff37/coverage-7.15.4-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:1c9bf40ebef178a45192c75c4964760bb261b0e6ad725da5fc4c93f674f19753", size = 255893, upload-time = "2026-08-06T13:49:41.825Z" }, { url = "https://files.pythonhosted.org/packages/5c/62/13be29b3ddab35f14c87967a4820a05106d2a3eccb4fa4ff550bf30b75e0/coverage-7.15.4-cp315-cp315-win32.whl", hash = "sha256:43619d04c3671792d2c4706ae8bf45e265dc87bbd4078189ef8b847ea1e74be2", size = 224768, upload-time = "2026-08-06T13:49:44.08Z" }, { url = "https://files.pythonhosted.org/packages/a1/70/af0c6be0f964af6954f6b74bc109b0dbca02824696d2520fb17fe1ab06e3/coverage-7.15.4-cp315-cp315-win_amd64.whl", hash = "sha256:be619439dbcd31a2eab10b32de9fff62c26ed4bab69dc32b8363fdaaa0882809", size = 225242, upload-time = "2026-08-06T13:49:45.899Z" }, { url = "https://files.pythonhosted.org/packages/4f/2d/f3bd3aab899fc9efc18b53133ee68f5f98574ef480649b23e12962226387/coverage-7.15.4-cp315-cp315-win_arm64.whl", hash = "sha256:def597967dafc2e8d97c9097ea453c464e0bb8ed38f193a43070f10dc623bb6d", size = 224674, upload-time = "2026-08-06T13:49:48.322Z" }, { url = "https://files.pythonhosted.org/packages/f5/ca/f69251cd63eabc6438321aea22148754cce758a26bde07dd490e3fe7cfc5/coverage-7.15.4-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:c7dbc748ac8a1e3e59a2b28bea47675e6e778081dbbf081bde0d75def2fcbe1d", size = 223333, upload-time = "2026-08-06T13:49:50.293Z" }, { url = "https://files.pythonhosted.org/packages/a7/a7/037b53b2885b0d8447064432491a4d5a1014cd9f97a594d53acd0c04541a/coverage-7.15.4-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:2413074a5ecbb61a01a7888fc72db0ca324d13588c5b38bc0dd8564cdcdfea26", size = 223630, upload-time = "2026-08-06T13:49:52.637Z" }, { url = "https://files.pythonhosted.org/packages/80/4f/152b8a4779ae90da11bb24f7467df8a59f0be48a5c52acb856325ca48289/coverage-7.15.4-cp315-cp315t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:4e6f6f632b7b2f714bf7a1346e8f97b650ee71f3c298aaad42a2ab60f0f07645", size = 264489, upload-time = "2026-08-06T13:49:54.52Z" }, { url = "https://files.pythonhosted.org/packages/10/2d/84b4b9e0e1dd6528a51920ff7031f35b789382e467a28ec6a5a578cb8812/coverage-7.15.4-cp315-cp315t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8df457da2249d3c75ca2e5e835d59c725abfe92d27fdff6cd99eed85b51d5e9a", size = 267567, upload-time = "2026-08-06T13:49:56.721Z" }, { url = "https://files.pythonhosted.org/packages/53/fc/ba01cc25299f9f8a2c8b02d3b28c53f3543d9fbfbe4e74fa2760b48f163e/coverage-7.15.4-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:050f66a08805acb5b8a23c6d4a517b1ecf82c08e81ed0e4bd727df065e5c6624", size = 270123, upload-time = "2026-08-06T13:49:58.736Z" }, { url = "https://files.pythonhosted.org/packages/cf/d0/db2647cbf40b14f8c308f94ff7bf89c06d564e59f396906edf50086ec788/coverage-7.15.4-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1587fb771d1ccceef708fdde1e5af8c7ed24b486b61d13a321acb7d8145390aa", size = 271107, upload-time = "2026-08-06T13:50:00.811Z" }, { url = "https://files.pythonhosted.org/packages/70/ff/4d2d17924552c458bb4f77dd631f0e3bc92fbbdf2d2d916cd4b33bbfd5b1/coverage-7.15.4-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8b4f1c3a69ca580f3fbd6b2046915f536d7f586874f25c1bb23add2a3c88d50f", size = 264955, upload-time = "2026-08-06T13:50:03.023Z" }, { url = "https://files.pythonhosted.org/packages/ee/de/dc010c7a3691f396d93bbc26bfcafa1c2a3a351cd520470f15faf5795bd5/coverage-7.15.4-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:ffb58d7eff5b7f6ecc6fa21d6288ab7f968a212cb67d682c269c09b9eba3b66f", size = 267949, upload-time = "2026-08-06T13:50:05.557Z" }, { url = "https://files.pythonhosted.org/packages/78/ea/dc96a11375e83c045c2f7c61fb6918277cfe9401db7c0f7b1d111a84b2e5/coverage-7.15.4-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:d9df165544774574ee004b953023d1bebada1894a80b1052a43d798b0f676e67", size = 264421, upload-time = "2026-08-06T13:50:07.612Z" }, { url = "https://files.pythonhosted.org/packages/c8/86/b77131a0f9503ce461cd577076147d7a9040f0c5dda772686f729e2cc9cb/coverage-7.15.4-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:f9de0a24a4079b53e523b5c5e2c5945ec251ab486652659955187cf255a259bc", size = 269121, upload-time = "2026-08-06T13:50:09.58Z" }, { url = "https://files.pythonhosted.org/packages/24/24/944bc35007862955e7ebf05754e645419dcf5d7526c52735cfa2715e8ebf/coverage-7.15.4-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:150089274bdc9f940628552cb92844e0223c987f1902ab8efe9f45a2ec758d88", size = 264565, upload-time = "2026-08-06T13:50:11.722Z" }, { url = "https://files.pythonhosted.org/packages/c7/cc/a3bb9f93e7e740659163e2ea584f8196ddcd2c456a5dbe15f6c50105fec1/coverage-7.15.4-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:a58a94fed5da6997d258e8f7668c1e195fbd04a691d781b7558f1e468f9e68bc", size = 266522, upload-time = "2026-08-06T13:50:13.786Z" }, { url = "https://files.pythonhosted.org/packages/49/dd/e0e40f3560d878d888c580698ff5ad1179f5e1c3ac949684ef66b41a3817/coverage-7.15.4-cp315-cp315t-win32.whl", hash = "sha256:ebd5a6d8466ff30836572f3ba2cae8a5e8f85029b1c6d5e2ed338dc472a5166a", size = 225068, upload-time = "2026-08-06T13:50:15.825Z" }, { url = "https://files.pythonhosted.org/packages/c6/7e/37732ea80eebc30e976e4cdab15c190bc42d96959a42e38ddf6f8c60468f/coverage-7.15.4-cp315-cp315t-win_amd64.whl", hash = "sha256:288bde2a2d7ab6b6c2d7252fcde8b524387f2d970bdba9658fc6f8bbcaef0f9b", size = 225895, upload-time = "2026-08-06T13:50:17.928Z" }, { url = "https://files.pythonhosted.org/packages/c6/08/1e00f7923eaaba45fb3d51dd794125fc766304b1df264f3a9c6557bfb30e/coverage-7.15.4-cp315-cp315t-win_arm64.whl", hash = "sha256:68be5e1de60ff13c9095bbec0e5a7fa45b33b101752215b91345ea1f61c4a278", size = 225213, upload-time = "2026-08-06T13:50:19.981Z" }, { url = "https://files.pythonhosted.org/packages/b4/d9/e70c286c979378f061d8266e279b686ab0b0b688e1fe0af864684f23a77d/coverage-7.15.4-py3-none-any.whl", hash = "sha256:964730a1e9de9c0cf11be6a1a3c79ce419c34882842abd256086ba4698705e84", size = 214332, upload-time = "2026-08-06T13:50:22.192Z" }, ] [package.optional-dependencies] toml = [ { name = "tomli", marker = "python_full_version <= '3.11'" }, ] [[package]] name = "cryptography" version = "50.0.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/bb/ad/5d6702db60b1e40b41ef513b6967ff5848f307d50f8449baf1634f5908f1/cryptography-50.0.1.tar.gz", hash = "sha256:5dd9bda1c12b4162f6ff568eeb5e0ff956c28d14406e875cfe8a63a2d414ff20", size = 880381, upload-time = "2026-08-25T19:45:45.499Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ba/19/797e2aaac9df6a66f1550f49979dc1b1e39ecd2077501c30efa81e8d5d67/cryptography-50.0.1-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:b8f852c65863251b9e3a1b8c150ce21e59b522dbb6a7d4bc80e680d38388e986", size = 4010153, upload-time = "2026-08-25T19:44:03.155Z" }, { url = "https://files.pythonhosted.org/packages/90/34/9ce9a62ed9dc82ca9fd6a34445b6904af56e5f38b3eae2ed32e49c36053d/cryptography-50.0.1-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:53e279950892dc102c6b4e52af03ae5ea92fac572a1ddab78ca73a997f62b69f", size = 4723133, upload-time = "2026-08-25T19:44:05.461Z" }, { url = "https://files.pythonhosted.org/packages/57/26/e6d4fc8512a51a5f9ee7bfdbfb853bce1197087df40c9ad993ad370b846f/cryptography-50.0.1-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ff838d62ec1bfce4f9ba7fa16f4a7b554cd8d0c299e6be37502161a660c84eef", size = 4712478, upload-time = "2026-08-25T19:44:07.375Z" }, { url = "https://files.pythonhosted.org/packages/e6/de/d3cdc2815697aae84126cbd6a030ca7b6b452e28a88b501b836bd3aa7a86/cryptography-50.0.1-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:e74591e283fe6eb956416c929eb58262a719fe0311fd9054c62c3350ed8760d8", size = 4730726, upload-time = "2026-08-25T19:44:09.294Z" }, { url = "https://files.pythonhosted.org/packages/55/32/38c0d344b98c06d34b5df8946565a9c0d6dbf32c8e0730a7f05f0a3c6cab/cryptography-50.0.1-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:5fe002589592ed749ce77fe0695fcbd3500dd61d7d6db5858a7544c612fa8e45", size = 5353524, upload-time = "2026-08-25T19:44:11.96Z" }, { url = "https://files.pythonhosted.org/packages/e1/1b/82f0f0d8858d4432be1af790477edf62aef90324041aa07c57e57bef1af7/cryptography-50.0.1-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:51593d180cf6d179bde5c5d065bed81386b1f381656ae7d042b7ffc87a9895ad", size = 4746720, upload-time = "2026-08-25T19:44:14.051Z" }, { url = "https://files.pythonhosted.org/packages/29/ba/042ca458b8c64348c768284b5d23e69b92ed53d057ab779fee628564676d/cryptography-50.0.1-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:359e62deae718bce96170e223fdcb6357e4fbd3bb7a3a75f4430763532560e49", size = 4361866, upload-time = "2026-08-25T19:44:16.167Z" }, { url = "https://files.pythonhosted.org/packages/39/3b/e96c1ef71edef71057c7e3c3d982ce8fda554e0c52d0cc19c18845cde3eb/cryptography-50.0.1-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:e2ca8fd1b6b4b82a1c4cb02841d0837e3c12336c2e24b520ab8ab3b969733d8f", size = 4730028, upload-time = "2026-08-25T19:44:18.085Z" }, { url = "https://files.pythonhosted.org/packages/e3/38/45abd72ef63f2e7d0754a6cacf97bd8b69512ace7f6130d24c39ece65da2/cryptography-50.0.1-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:76de83fbd91ac49c0feaaa983d0748fd7a53176afac5fb3bf7478d244f0eb527", size = 5308405, upload-time = "2026-08-25T19:44:20.197Z" }, { url = "https://files.pythonhosted.org/packages/85/66/6ccca4722987ddedaa7fc9c3f4708af7431f5535666c174350830888c6b7/cryptography-50.0.1-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:51afcfceb15597cf2635068e4ac9a56b2abde622edde17f37d85fd7b5306497a", size = 4746230, upload-time = "2026-08-25T19:44:22.376Z" }, { url = "https://files.pythonhosted.org/packages/13/0e/b1f92e013228111413f2e6743948b80bc24dfd3c1b87ba98ceea16f5df89/cryptography-50.0.1-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:be224a65493ec5b74a158ff22a5522ce4a5ca1e543c647a3a4730d4a09e5f959", size = 4862596, upload-time = "2026-08-25T19:44:24.472Z" }, { url = "https://files.pythonhosted.org/packages/7e/22/c3654cccc856e9d682817b04ac3ee79731cb09ca6f95996a95c904de2883/cryptography-50.0.1-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:9ebcdd5519be9b652a46f507817a74591774fc3d6923ac364e4dfa64e36b291b", size = 5014082, upload-time = "2026-08-25T19:44:26.709Z" }, { url = "https://files.pythonhosted.org/packages/42/8b/cb12b1b60c91b074ca6bf0fdd59aa8f10d8bc5f73af8faece86ef0421b37/cryptography-50.0.1-cp311-abi3-win_amd64.whl", hash = "sha256:aed8db4f6d71c51efb89530e12d9464e7bf2923d46c3205dc794a2a93f8c0648", size = 3842826, upload-time = "2026-08-25T19:44:28.784Z" }, { url = "https://files.pythonhosted.org/packages/5b/f0/424cb557d99aa86ac55da5e2add02e2882e44047b6264f93ade1b975a993/cryptography-50.0.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:30a125032e5642a21ff816e021152bd4e7e94f03eff3f4b7fca41cd22bc3110f", size = 3973525, upload-time = "2026-08-25T19:44:30.7Z" }, { url = "https://files.pythonhosted.org/packages/4d/72/3a2711d967977ab5fc80b782837c7e8d1ac7445e764c20c381a265c57ef3/cryptography-50.0.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a0b1a59e3a089064a0ec309e9428c8e3ae4e161419d20ac33600767e83fc658a", size = 4708817, upload-time = "2026-08-25T19:44:32.773Z" }, { url = "https://files.pythonhosted.org/packages/b4/f2/bb1f56e10815b789df0b409a69fa4992ff3d3fef9c72747f4a6b26fed38e/cryptography-50.0.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8921d58f426793c5f1b47f0b59575780de9a095214958d0eb37d909593db8367", size = 4697300, upload-time = "2026-08-25T19:44:35.144Z" }, { url = "https://files.pythonhosted.org/packages/08/bd/ed5396be499ffcf8807a585bfe38b71a1fbdd1c342b4f9b6d0ef5162a946/cryptography-50.0.1-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:a8f40ea47330e71b594a7e246898f93177c259490c63183dbaf9e571d71ed9a5", size = 4716039, upload-time = "2026-08-25T19:44:37.192Z" }, { url = "https://files.pythonhosted.org/packages/f6/6e/1cf405c5c8e8df7545378048e954792f00b7f2367af8863ce8b8f3e10607/cryptography-50.0.1-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:a255449073358275b64b67d3f595f268bbef70e72b6edb65e0c70c735bf739c9", size = 5332388, upload-time = "2026-08-25T19:44:39.16Z" }, { url = "https://files.pythonhosted.org/packages/47/92/b4317e8c32c4f47b062f5398bd79106b220a124546f42be83bf32b761e2a/cryptography-50.0.1-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:8df2de9102026855887e4587084f6eabd80ed0f345b8ad8a7ac27ab9bf4723e0", size = 4730293, upload-time = "2026-08-25T19:44:41.298Z" }, { url = "https://files.pythonhosted.org/packages/39/0d/a1e7633e2c744d0f2983320a27e924ef2264c79c56e1a58d5fb0a1cfd413/cryptography-50.0.1-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:ac02b07824d4d1001bd4367599f839c19cb171924c796e52c23508ac14c2c0cc", size = 4346031, upload-time = "2026-08-25T19:44:43.245Z" }, { url = "https://files.pythonhosted.org/packages/88/dd/b215616f9bab3fc18510c78a4e5c9f362d77838503c363dc747c7d4f5c6f/cryptography-50.0.1-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:cbf74a81765ee67413503ca6e26dcc4f6f5a519822436cc0a1b97aab6c1b8a17", size = 4715344, upload-time = "2026-08-25T19:44:45.291Z" }, { url = "https://files.pythonhosted.org/packages/b1/1b/ec3ebd31741d0e963612c4fe43caa39341b9b1e031e469820e42e4c83918/cryptography-50.0.1-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:16c5ecd954b3330ebfb6605eca4fd952da8bef376551d5cc264534e3770a9ee6", size = 5287201, upload-time = "2026-08-25T19:44:47.297Z" }, { url = "https://files.pythonhosted.org/packages/1a/01/0127d11a762b31a9ee0221894f540318761783f3fdc4bc5d057698caebd5/cryptography-50.0.1-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:79bf008d1f9af6071c797ad133e39915dfee7614f18f18f4db9072eb715064a3", size = 4730023, upload-time = "2026-08-25T19:44:49.435Z" }, { url = "https://files.pythonhosted.org/packages/9e/b9/e7425ebfb599241a0c1d7000f1b466c3062da66c19d9525031315dff7213/cryptography-50.0.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:330fbb252391c596f1ae42c5754449dc924e6ad012dca8efe0d703f9f2d12ec6", size = 4847362, upload-time = "2026-08-25T19:44:51.94Z" }, { url = "https://files.pythonhosted.org/packages/2d/fd/60d0ddf4defa12e482c9d5e0f554384d6e8ab25341fd15f060028fd92e6a/cryptography-50.0.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:42be3bb70596b3abe4ac097b75be223e8b3ab614a0e5de068e3dcc54d71d6149", size = 4999247, upload-time = "2026-08-25T19:44:53.876Z" }, { url = "https://files.pythonhosted.org/packages/4d/56/bc4f2b209e766c93372cfcd59b781a0b2b59700f62a969580415b699c2b2/cryptography-50.0.1-cp314-cp314t-win_amd64.whl", hash = "sha256:f74455bb086a85d5e81246412602aaa97ed095e504cd40dd261ef50be42205bf", size = 3825806, upload-time = "2026-08-25T19:44:56.209Z" }, { url = "https://files.pythonhosted.org/packages/84/a9/ee16a903f13755e914d1eecc482fe64d1f10761c3960e5d8fa6837377aff/cryptography-50.0.1-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:ca83d00d9e69cd5eb63f2e69c3a5a59e0cecae5ae14c6ae0b35830fe3b37bad0", size = 4035307, upload-time = "2026-08-25T19:44:58.305Z" }, { url = "https://files.pythonhosted.org/packages/5e/a5/9ec7e81e8526c0d7a387d73386b2daed3f39e10d81a85930bd1b6bfba65c/cryptography-50.0.1-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:05ba322c4da95b262a212c345af888ef2c37c88c0509756ea00a0e6d68850f23", size = 4751900, upload-time = "2026-08-25T19:45:00.401Z" }, { url = "https://files.pythonhosted.org/packages/7e/3c/0e77bd5ffcf078e9dd27d3074aad6c030d9b10d0bf69329d573c927a188c/cryptography-50.0.1-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e22dfed744bd4002e909464cb23d2f0b05c6f3113a79ef2e9864a53db737c733", size = 4738357, upload-time = "2026-08-25T19:45:02.786Z" }, { url = "https://files.pythonhosted.org/packages/27/3a/3c5f80daa4dcd47323c7af8a2fcb90de27a33564d4fcac69846c0972691a/cryptography-50.0.1-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:4c4188f7c0cf655be5c06342b817ed0f9595b69ffa2b12026e5353eed29dea88", size = 4758474, upload-time = "2026-08-25T19:45:04.889Z" }, { url = "https://files.pythonhosted.org/packages/6e/2b/214cf0cf93db9628c3c20c896b229f327f6fb1b20e4b3743d8ad3f00af8b/cryptography-50.0.1-cp39-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:2ebbfb0f1fed745e91796e3e1080a1440423fdae8ece1b995a1d80883a409054", size = 5375862, upload-time = "2026-08-25T19:45:07.163Z" }, { url = "https://files.pythonhosted.org/packages/d6/51/3f9701867a46b6c1740c9b52fc4d3bed6cbdcfedcc9b6e64305c07f39cff/cryptography-50.0.1-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:407fe2b6db00939c05c0e945e9914238f2f0a430974839429dafc82b1ee6bee5", size = 4772942, upload-time = "2026-08-25T19:45:09.396Z" }, { url = "https://files.pythonhosted.org/packages/0d/5c/13ea642e08e2544d0f5396122055f4820cfacb3203562197b5967125ea97/cryptography-50.0.1-cp39-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:2b34d76a652ea2b6faf777c35df230c5637842cd904e04f16230c3f9f03e4361", size = 4383347, upload-time = "2026-08-25T19:45:11.659Z" }, { url = "https://files.pythonhosted.org/packages/84/d5/7d1fe1cb93f91c428093ff234e128c89ba8ea61a6f26aab406081f9b996e/cryptography-50.0.1-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:01f41478cf33fc605a6a089cd56d28b45c6c0b45a1928b61797f2621a04bac71", size = 4758050, upload-time = "2026-08-25T19:45:13.745Z" }, { url = "https://files.pythonhosted.org/packages/dd/04/557fc5ead96a829e0bc812a3b9dc4a52a2f27e4f7f5950da7ff27653a805/cryptography-50.0.1-cp39-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:fc3ed7ebd2a8c96f5b166de0ab9b624996bef3b07bbeb19364dfb78222c22c80", size = 5332955, upload-time = "2026-08-25T19:45:16.193Z" }, { url = "https://files.pythonhosted.org/packages/8c/eb/5d7124083e8d8cda8f5b348f544b71ad6f707ad63193758ef4d8e569da02/cryptography-50.0.1-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:9dde0a357190eb3b1da1bb9ab750e9c85cba82ca5977aa0836cbb94e92611239", size = 4772694, upload-time = "2026-08-25T19:45:18.315Z" }, { url = "https://files.pythonhosted.org/packages/63/8e/f1f955e0921dd2b6d22eae7e8d24a4c4b638d10735ffbf6a71f99eb0fcb8/cryptography-50.0.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fd3718b960d0b5dd213cdf03f3bcb7000e69dda0de8b956061947ff6bcff5558", size = 4888413, upload-time = "2026-08-25T19:45:20.4Z" }, { url = "https://files.pythonhosted.org/packages/1f/ab/89e2b798d2c3925f82e2bb72d5979f3d2f6da2dd22ef4a8cd8b70d920039/cryptography-50.0.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:2a93d05e34d5f67fba6f891fe85d929999baa7195e853923ea6d7576c9e68c5e", size = 5044355, upload-time = "2026-08-25T19:45:22.353Z" }, { url = "https://files.pythonhosted.org/packages/99/89/87ef49ffe383ef4e147d27b7bf2088fb0b54ea409dd87b5a89442e5828a5/cryptography-50.0.1-cp39-abi3-win_amd64.whl", hash = "sha256:55d16b1ef3ee0958d893a977b19777887e546c9954ea81b200c3301a864013f2", size = 3875429, upload-time = "2026-08-25T19:45:24.418Z" }, { url = "https://files.pythonhosted.org/packages/c7/27/8d207af749c453ee17ea087340b3f2b4adef75aadd1d277b1b129bdda84e/cryptography-50.0.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9cb3cb952cf5a8abd50c782a98a89d71699715e802fe349704b47f2425b42a94", size = 3974350, upload-time = "2026-08-25T19:45:26.551Z" }, { url = "https://files.pythonhosted.org/packages/14/9a/6d3a4d7852e22d657438b7bf51f66102c7d71c0e1fafeec652281d0403e5/cryptography-50.0.1-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5fe939deeb161024a6be98229c953b6591fef1f41214497a78fe793a244c017f", size = 4698675, upload-time = "2026-08-25T19:45:28.658Z" }, { url = "https://files.pythonhosted.org/packages/73/35/5c3717edf9e68a0550ce04e28eab493fe545eccd81742af03f6a75fe260b/cryptography-50.0.1-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fb4b9672d389c738b175c4166e78310f8a70358886aacd9173ee03a85ffdc671", size = 4707410, upload-time = "2026-08-25T19:45:30.816Z" }, { url = "https://files.pythonhosted.org/packages/1d/e0/e786934472e3ac4ecdecc7b129a0ca1a2a40dffdafcf2c3ea9d4397f8def/cryptography-50.0.1-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:d63ae8f6481fec907ac0f588eee8a90aefde112c633131fe540e5711ddbb5a4e", size = 4698378, upload-time = "2026-08-25T19:45:33.043Z" }, { url = "https://files.pythonhosted.org/packages/51/cf/5b3f53a0b74d122f023476ede40ba5d3e70d5cf475f73b899740d26a4fb2/cryptography-50.0.1-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:804728ce710890870f3aaa344b2e161172d258d768ac139d02cfd9092d0d94e6", size = 4706889, upload-time = "2026-08-25T19:45:35.086Z" }, { url = "https://files.pythonhosted.org/packages/71/44/711e61f7d014be825ef79b285b047292d1bf893732ac1bc030a351fb517f/cryptography-50.0.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:693c99b49bd37d0d096e4334c10232c77248c415b98d35236094cdf96d57258b", size = 3824006, upload-time = "2026-08-25T19:45:37.281Z" }, ] [[package]] name = "decorator" version = "5.2.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/43/fa/6d96a0978d19e17b68d634497769987b16c8f4cd0a7a05048bec693caa6b/decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360", size = 56711, upload-time = "2025-02-24T04:41:34.073Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a", size = 9190, upload-time = "2025-02-24T04:41:32.565Z" }, ] [[package]] name = "deepmerge" version = "2.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/a8/3a/b0ba594708f1ad0bc735884b3ad854d3ca3bdc1d741e56e40bbda6263499/deepmerge-2.0.tar.gz", hash = "sha256:5c3d86081fbebd04dd5de03626a0607b809a98fb6ccba5770b62466fe940ff20", size = 19890, upload-time = "2024-08-30T05:31:50.308Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/2d/82/e5d2c1c67d19841e9edc74954c827444ae826978499bde3dfc1d007c8c11/deepmerge-2.0-py3-none-any.whl", hash = "sha256:6de9ce507115cff0bed95ff0ce9ecc31088ef50cbdf09bc90a09349a318b3d00", size = 13475, upload-time = "2024-08-30T05:31:48.659Z" }, ] [[package]] name = "docutils" version = "0.22.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/ae/b6/03bb70946330e88ffec97aefd3ea75ba575cb2e762061e0e62a213befee8/docutils-0.22.4.tar.gz", hash = "sha256:4db53b1fde9abecbb74d91230d32ab626d94f6badfc575d6db9194a49df29968", size = 2291750, upload-time = "2025-12-18T19:00:26.443Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl", hash = "sha256:d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de", size = 633196, upload-time = "2025-12-18T19:00:18.077Z" }, ] [[package]] name = "flaky" version = "3.8.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/5b/c5/ef69119a01427204ff2db5fc8f98001087bcce719bbb94749dcd7b191365/flaky-3.8.1.tar.gz", hash = "sha256:47204a81ec905f3d5acfbd61daeabcada8f9d4031616d9bcb0618461729699f5", size = 25248, upload-time = "2024-03-12T22:17:59.265Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/7f/b8/b830fc43663246c3f3dd1ae7dca4847b96ed992537e85311e27fa41ac40e/flaky-3.8.1-py2.py3-none-any.whl", hash = "sha256:194ccf4f0d3a22b2de7130f4b62e45e977ac1b5ccad74d4d48f3005dcc38815e", size = 19139, upload-time = "2024-03-12T22:17:51.59Z" }, ] [[package]] name = "flasgger" version = "0.9.7.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "flask" }, { name = "jsonschema" }, { name = "mistune" }, { name = "packaging" }, { name = "pyyaml" }, { name = "six" }, ] sdist = { url = "https://files.pythonhosted.org/packages/8a/e4/05e80adeadc39f171b51bd29b24a6d9838127f3aaa1b07c1501e662a8cee/flasgger-0.9.7.1.tar.gz", hash = "sha256:ca098e10bfbb12f047acc6299cc70a33851943a746e550d86e65e60d4df245fb", size = 3979409, upload-time = "2023-05-18T17:15:21.328Z" } [[package]] name = "flask" version = "3.1.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "blinker" }, { name = "click" }, { name = "itsdangerous" }, { name = "jinja2" }, { name = "markupsafe" }, { name = "werkzeug" }, ] sdist = { url = "https://files.pythonhosted.org/packages/26/00/35d85dcce6c57fdc871f3867d465d780f302a175ea360f62533f12b27e2b/flask-3.1.3.tar.gz", hash = "sha256:0ef0e52b8a9cd932855379197dd8f94047b359ca0a78695144304cb45f87c9eb", size = 759004, upload-time = "2026-02-19T05:00:57.678Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/7f/9c/34f6962f9b9e9c71f6e5ed806e0d0ff03c9d1b0b2340088a0cf4bce09b18/flask-3.1.3-py3-none-any.whl", hash = "sha256:f4bcbefc124291925f1a26446da31a5178f9483862233b23c0c96a20701f670c", size = 103424, upload-time = "2026-02-19T05:00:56.027Z" }, ] [[package]] name = "frozenlist" version = "1.8.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/2d/f5/c831fac6cc817d26fd54c7eaccd04ef7e0288806943f7cc5bbf69f3ac1f0/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", size = 45875, upload-time = "2025-10-06T05:38:17.865Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/bc/03/077f869d540370db12165c0aa51640a873fb661d8b315d1d4d67b284d7ac/frozenlist-1.8.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:09474e9831bc2b2199fad6da3c14c7b0fbdd377cce9d3d77131be28906cb7d84", size = 86912, upload-time = "2025-10-06T05:35:45.98Z" }, { url = "https://files.pythonhosted.org/packages/df/b5/7610b6bd13e4ae77b96ba85abea1c8cb249683217ef09ac9e0ae93f25a91/frozenlist-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:17c883ab0ab67200b5f964d2b9ed6b00971917d5d8a92df149dc2c9779208ee9", size = 50046, upload-time = "2025-10-06T05:35:47.009Z" }, { url = "https://files.pythonhosted.org/packages/6e/ef/0e8f1fe32f8a53dd26bdd1f9347efe0778b0fddf62789ea683f4cc7d787d/frozenlist-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa47e444b8ba08fffd1c18e8cdb9a75db1b6a27f17507522834ad13ed5922b93", size = 50119, upload-time = "2025-10-06T05:35:48.38Z" }, { url = "https://files.pythonhosted.org/packages/11/b1/71a477adc7c36e5fb628245dfbdea2166feae310757dea848d02bd0689fd/frozenlist-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2552f44204b744fba866e573be4c1f9048d6a324dfe14475103fd51613eb1d1f", size = 231067, upload-time = "2025-10-06T05:35:49.97Z" }, { url = "https://files.pythonhosted.org/packages/45/7e/afe40eca3a2dc19b9904c0f5d7edfe82b5304cb831391edec0ac04af94c2/frozenlist-1.8.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:957e7c38f250991e48a9a73e6423db1bb9dd14e722a10f6b8bb8e16a0f55f695", size = 233160, upload-time = "2025-10-06T05:35:51.729Z" }, { url = "https://files.pythonhosted.org/packages/a6/aa/7416eac95603ce428679d273255ffc7c998d4132cfae200103f164b108aa/frozenlist-1.8.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8585e3bb2cdea02fc88ffa245069c36555557ad3609e83be0ec71f54fd4abb52", size = 228544, upload-time = "2025-10-06T05:35:53.246Z" }, { url = "https://files.pythonhosted.org/packages/8b/3d/2a2d1f683d55ac7e3875e4263d28410063e738384d3adc294f5ff3d7105e/frozenlist-1.8.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:edee74874ce20a373d62dc28b0b18b93f645633c2943fd90ee9d898550770581", size = 243797, upload-time = "2025-10-06T05:35:54.497Z" }, { url = "https://files.pythonhosted.org/packages/78/1e/2d5565b589e580c296d3bb54da08d206e797d941a83a6fdea42af23be79c/frozenlist-1.8.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c9a63152fe95756b85f31186bddf42e4c02c6321207fd6601a1c89ebac4fe567", size = 247923, upload-time = "2025-10-06T05:35:55.861Z" }, { url = "https://files.pythonhosted.org/packages/aa/c3/65872fcf1d326a7f101ad4d86285c403c87be7d832b7470b77f6d2ed5ddc/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b6db2185db9be0a04fecf2f241c70b63b1a242e2805be291855078f2b404dd6b", size = 230886, upload-time = "2025-10-06T05:35:57.399Z" }, { url = "https://files.pythonhosted.org/packages/a0/76/ac9ced601d62f6956f03cc794f9e04c81719509f85255abf96e2510f4265/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:f4be2e3d8bc8aabd566f8d5b8ba7ecc09249d74ba3c9ed52e54dc23a293f0b92", size = 245731, upload-time = "2025-10-06T05:35:58.563Z" }, { url = "https://files.pythonhosted.org/packages/b9/49/ecccb5f2598daf0b4a1415497eba4c33c1e8ce07495eb07d2860c731b8d5/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c8d1634419f39ea6f5c427ea2f90ca85126b54b50837f31497f3bf38266e853d", size = 241544, upload-time = "2025-10-06T05:35:59.719Z" }, { url = "https://files.pythonhosted.org/packages/53/4b/ddf24113323c0bbcc54cb38c8b8916f1da7165e07b8e24a717b4a12cbf10/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:1a7fa382a4a223773ed64242dbe1c9c326ec09457e6b8428efb4118c685c3dfd", size = 241806, upload-time = "2025-10-06T05:36:00.959Z" }, { url = "https://files.pythonhosted.org/packages/a7/fb/9b9a084d73c67175484ba2789a59f8eebebd0827d186a8102005ce41e1ba/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:11847b53d722050808926e785df837353bd4d75f1d494377e59b23594d834967", size = 229382, upload-time = "2025-10-06T05:36:02.22Z" }, { url = "https://files.pythonhosted.org/packages/95/a3/c8fb25aac55bf5e12dae5c5aa6a98f85d436c1dc658f21c3ac73f9fa95e5/frozenlist-1.8.0-cp311-cp311-win32.whl", hash = "sha256:27c6e8077956cf73eadd514be8fb04d77fc946a7fe9f7fe167648b0b9085cc25", size = 39647, upload-time = "2025-10-06T05:36:03.409Z" }, { url = "https://files.pythonhosted.org/packages/0a/f5/603d0d6a02cfd4c8f2a095a54672b3cf967ad688a60fb9faf04fc4887f65/frozenlist-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:ac913f8403b36a2c8610bbfd25b8013488533e71e62b4b4adce9c86c8cea905b", size = 44064, upload-time = "2025-10-06T05:36:04.368Z" }, { url = "https://files.pythonhosted.org/packages/5d/16/c2c9ab44e181f043a86f9a8f84d5124b62dbcb3a02c0977ec72b9ac1d3e0/frozenlist-1.8.0-cp311-cp311-win_arm64.whl", hash = "sha256:d4d3214a0f8394edfa3e303136d0575eece0745ff2b47bd2cb2e66dd92d4351a", size = 39937, upload-time = "2025-10-06T05:36:05.669Z" }, { url = "https://files.pythonhosted.org/packages/69/29/948b9aa87e75820a38650af445d2ef2b6b8a6fab1a23b6bb9e4ef0be2d59/frozenlist-1.8.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:78f7b9e5d6f2fdb88cdde9440dc147259b62b9d3b019924def9f6478be254ac1", size = 87782, upload-time = "2025-10-06T05:36:06.649Z" }, { url = "https://files.pythonhosted.org/packages/64/80/4f6e318ee2a7c0750ed724fa33a4bdf1eacdc5a39a7a24e818a773cd91af/frozenlist-1.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:229bf37d2e4acdaf808fd3f06e854a4a7a3661e871b10dc1f8f1896a3b05f18b", size = 50594, upload-time = "2025-10-06T05:36:07.69Z" }, { url = "https://files.pythonhosted.org/packages/2b/94/5c8a2b50a496b11dd519f4a24cb5496cf125681dd99e94c604ccdea9419a/frozenlist-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f833670942247a14eafbb675458b4e61c82e002a148f49e68257b79296e865c4", size = 50448, upload-time = "2025-10-06T05:36:08.78Z" }, { url = "https://files.pythonhosted.org/packages/6a/bd/d91c5e39f490a49df14320f4e8c80161cfcce09f1e2cde1edd16a551abb3/frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:494a5952b1c597ba44e0e78113a7266e656b9794eec897b19ead706bd7074383", size = 242411, upload-time = "2025-10-06T05:36:09.801Z" }, { url = "https://files.pythonhosted.org/packages/8f/83/f61505a05109ef3293dfb1ff594d13d64a2324ac3482be2cedc2be818256/frozenlist-1.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96f423a119f4777a4a056b66ce11527366a8bb92f54e541ade21f2374433f6d4", size = 243014, upload-time = "2025-10-06T05:36:11.394Z" }, { url = "https://files.pythonhosted.org/packages/d8/cb/cb6c7b0f7d4023ddda30cf56b8b17494eb3a79e3fda666bf735f63118b35/frozenlist-1.8.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3462dd9475af2025c31cc61be6652dfa25cbfb56cbbf52f4ccfe029f38decaf8", size = 234909, upload-time = "2025-10-06T05:36:12.598Z" }, { url = "https://files.pythonhosted.org/packages/31/c5/cd7a1f3b8b34af009fb17d4123c5a778b44ae2804e3ad6b86204255f9ec5/frozenlist-1.8.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4c800524c9cd9bac5166cd6f55285957fcfc907db323e193f2afcd4d9abd69b", size = 250049, upload-time = "2025-10-06T05:36:14.065Z" }, { url = "https://files.pythonhosted.org/packages/c0/01/2f95d3b416c584a1e7f0e1d6d31998c4a795f7544069ee2e0962a4b60740/frozenlist-1.8.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d6a5df73acd3399d893dafc71663ad22534b5aa4f94e8a2fabfe856c3c1b6a52", size = 256485, upload-time = "2025-10-06T05:36:15.39Z" }, { url = "https://files.pythonhosted.org/packages/ce/03/024bf7720b3abaebcff6d0793d73c154237b85bdf67b7ed55e5e9596dc9a/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:405e8fe955c2280ce66428b3ca55e12b3c4e9c336fb2103a4937e891c69a4a29", size = 237619, upload-time = "2025-10-06T05:36:16.558Z" }, { url = "https://files.pythonhosted.org/packages/69/fa/f8abdfe7d76b731f5d8bd217827cf6764d4f1d9763407e42717b4bed50a0/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:908bd3f6439f2fef9e85031b59fd4f1297af54415fb60e4254a95f75b3cab3f3", size = 250320, upload-time = "2025-10-06T05:36:17.821Z" }, { url = "https://files.pythonhosted.org/packages/f5/3c/b051329f718b463b22613e269ad72138cc256c540f78a6de89452803a47d/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:294e487f9ec720bd8ffcebc99d575f7eff3568a08a253d1ee1a0378754b74143", size = 246820, upload-time = "2025-10-06T05:36:19.046Z" }, { url = "https://files.pythonhosted.org/packages/0f/ae/58282e8f98e444b3f4dd42448ff36fa38bef29e40d40f330b22e7108f565/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:74c51543498289c0c43656701be6b077f4b265868fa7f8a8859c197006efb608", size = 250518, upload-time = "2025-10-06T05:36:20.763Z" }, { url = "https://files.pythonhosted.org/packages/8f/96/007e5944694d66123183845a106547a15944fbbb7154788cbf7272789536/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:776f352e8329135506a1d6bf16ac3f87bc25b28e765949282dcc627af36123aa", size = 239096, upload-time = "2025-10-06T05:36:22.129Z" }, { url = "https://files.pythonhosted.org/packages/66/bb/852b9d6db2fa40be96f29c0d1205c306288f0684df8fd26ca1951d461a56/frozenlist-1.8.0-cp312-cp312-win32.whl", hash = "sha256:433403ae80709741ce34038da08511d4a77062aa924baf411ef73d1146e74faf", size = 39985, upload-time = "2025-10-06T05:36:23.661Z" }, { url = "https://files.pythonhosted.org/packages/b8/af/38e51a553dd66eb064cdf193841f16f077585d4d28394c2fa6235cb41765/frozenlist-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746", size = 44591, upload-time = "2025-10-06T05:36:24.958Z" }, { url = "https://files.pythonhosted.org/packages/a7/06/1dc65480ab147339fecc70797e9c2f69d9cea9cf38934ce08df070fdb9cb/frozenlist-1.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd", size = 40102, upload-time = "2025-10-06T05:36:26.333Z" }, { url = "https://files.pythonhosted.org/packages/2d/40/0832c31a37d60f60ed79e9dfb5a92e1e2af4f40a16a29abcc7992af9edff/frozenlist-1.8.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8d92f1a84bb12d9e56f818b3a746f3efba93c1b63c8387a73dde655e1e42282a", size = 85717, upload-time = "2025-10-06T05:36:27.341Z" }, { url = "https://files.pythonhosted.org/packages/30/ba/b0b3de23f40bc55a7057bd38434e25c34fa48e17f20ee273bbde5e0650f3/frozenlist-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96153e77a591c8adc2ee805756c61f59fef4cf4073a9275ee86fe8cba41241f7", size = 49651, upload-time = "2025-10-06T05:36:28.855Z" }, { url = "https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40", size = 49417, upload-time = "2025-10-06T05:36:29.877Z" }, { url = "https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027", size = 234391, upload-time = "2025-10-06T05:36:31.301Z" }, { url = "https://files.pythonhosted.org/packages/40/76/c202df58e3acdf12969a7895fd6f3bc016c642e6726aa63bd3025e0fc71c/frozenlist-1.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaa352d7047a31d87dafcacbabe89df0aa506abb5b1b85a2fb91bc3faa02d822", size = 233048, upload-time = "2025-10-06T05:36:32.531Z" }, { url = "https://files.pythonhosted.org/packages/f9/c0/8746afb90f17b73ca5979c7a3958116e105ff796e718575175319b5bb4ce/frozenlist-1.8.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:03ae967b4e297f58f8c774c7eabcce57fe3c2434817d4385c50661845a058121", size = 226549, upload-time = "2025-10-06T05:36:33.706Z" }, { url = "https://files.pythonhosted.org/packages/7e/eb/4c7eefc718ff72f9b6c4893291abaae5fbc0c82226a32dcd8ef4f7a5dbef/frozenlist-1.8.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f6292f1de555ffcc675941d65fffffb0a5bcd992905015f85d0592201793e0e5", size = 239833, upload-time = "2025-10-06T05:36:34.947Z" }, { url = "https://files.pythonhosted.org/packages/c2/4e/e5c02187cf704224f8b21bee886f3d713ca379535f16893233b9d672ea71/frozenlist-1.8.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29548f9b5b5e3460ce7378144c3010363d8035cea44bc0bf02d57f5a685e084e", size = 245363, upload-time = "2025-10-06T05:36:36.534Z" }, { url = "https://files.pythonhosted.org/packages/1f/96/cb85ec608464472e82ad37a17f844889c36100eed57bea094518bf270692/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ec3cc8c5d4084591b4237c0a272cc4f50a5b03396a47d9caaf76f5d7b38a4f11", size = 229314, upload-time = "2025-10-06T05:36:38.582Z" }, { url = "https://files.pythonhosted.org/packages/5d/6f/4ae69c550e4cee66b57887daeebe006fe985917c01d0fff9caab9883f6d0/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:517279f58009d0b1f2e7c1b130b377a349405da3f7621ed6bfae50b10adf20c1", size = 243365, upload-time = "2025-10-06T05:36:40.152Z" }, { url = "https://files.pythonhosted.org/packages/7a/58/afd56de246cf11780a40a2c28dc7cbabbf06337cc8ddb1c780a2d97e88d8/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:db1e72ede2d0d7ccb213f218df6a078a9c09a7de257c2fe8fcef16d5925230b1", size = 237763, upload-time = "2025-10-06T05:36:41.355Z" }, { url = "https://files.pythonhosted.org/packages/cb/36/cdfaf6ed42e2644740d4a10452d8e97fa1c062e2a8006e4b09f1b5fd7d63/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b4dec9482a65c54a5044486847b8a66bf10c9cb4926d42927ec4e8fd5db7fed8", size = 240110, upload-time = "2025-10-06T05:36:42.716Z" }, { url = "https://files.pythonhosted.org/packages/03/a8/9ea226fbefad669f11b52e864c55f0bd57d3c8d7eb07e9f2e9a0b39502e1/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:21900c48ae04d13d416f0e1e0c4d81f7931f73a9dfa0b7a8746fb2fe7dd970ed", size = 233717, upload-time = "2025-10-06T05:36:44.251Z" }, { url = "https://files.pythonhosted.org/packages/1e/0b/1b5531611e83ba7d13ccc9988967ea1b51186af64c42b7a7af465dcc9568/frozenlist-1.8.0-cp313-cp313-win32.whl", hash = "sha256:8b7b94a067d1c504ee0b16def57ad5738701e4ba10cec90529f13fa03c833496", size = 39628, upload-time = "2025-10-06T05:36:45.423Z" }, { url = "https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231", size = 43882, upload-time = "2025-10-06T05:36:46.796Z" }, { url = "https://files.pythonhosted.org/packages/c1/17/502cd212cbfa96eb1388614fe39a3fc9ab87dbbe042b66f97acb57474834/frozenlist-1.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:44389d135b3ff43ba8cc89ff7f51f5a0bb6b63d829c8300f79a2fe4fe61bcc62", size = 39676, upload-time = "2025-10-06T05:36:47.8Z" }, { url = "https://files.pythonhosted.org/packages/d2/5c/3bbfaa920dfab09e76946a5d2833a7cbdf7b9b4a91c714666ac4855b88b4/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:e25ac20a2ef37e91c1b39938b591457666a0fa835c7783c3a8f33ea42870db94", size = 89235, upload-time = "2025-10-06T05:36:48.78Z" }, { url = "https://files.pythonhosted.org/packages/d2/d6/f03961ef72166cec1687e84e8925838442b615bd0b8854b54923ce5b7b8a/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07cdca25a91a4386d2e76ad992916a85038a9b97561bf7a3fd12d5d9ce31870c", size = 50742, upload-time = "2025-10-06T05:36:49.837Z" }, { url = "https://files.pythonhosted.org/packages/1e/bb/a6d12b7ba4c3337667d0e421f7181c82dda448ce4e7ad7ecd249a16fa806/frozenlist-1.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4e0c11f2cc6717e0a741f84a527c52616140741cd812a50422f83dc31749fb52", size = 51725, upload-time = "2025-10-06T05:36:50.851Z" }, { url = "https://files.pythonhosted.org/packages/bc/71/d1fed0ffe2c2ccd70b43714c6cab0f4188f09f8a67a7914a6b46ee30f274/frozenlist-1.8.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3210649ee28062ea6099cfda39e147fa1bc039583c8ee4481cb7811e2448c51", size = 284533, upload-time = "2025-10-06T05:36:51.898Z" }, { url = "https://files.pythonhosted.org/packages/c9/1f/fb1685a7b009d89f9bf78a42d94461bc06581f6e718c39344754a5d9bada/frozenlist-1.8.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:581ef5194c48035a7de2aefc72ac6539823bb71508189e5de01d60c9dcd5fa65", size = 292506, upload-time = "2025-10-06T05:36:53.101Z" }, { url = "https://files.pythonhosted.org/packages/e6/3b/b991fe1612703f7e0d05c0cf734c1b77aaf7c7d321df4572e8d36e7048c8/frozenlist-1.8.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3ef2d026f16a2b1866e1d86fc4e1291e1ed8a387b2c333809419a2f8b3a77b82", size = 274161, upload-time = "2025-10-06T05:36:54.309Z" }, { url = "https://files.pythonhosted.org/packages/ca/ec/c5c618767bcdf66e88945ec0157d7f6c4a1322f1473392319b7a2501ded7/frozenlist-1.8.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5500ef82073f599ac84d888e3a8c1f77ac831183244bfd7f11eaa0289fb30714", size = 294676, upload-time = "2025-10-06T05:36:55.566Z" }, { url = "https://files.pythonhosted.org/packages/7c/ce/3934758637d8f8a88d11f0585d6495ef54b2044ed6ec84492a91fa3b27aa/frozenlist-1.8.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50066c3997d0091c411a66e710f4e11752251e6d2d73d70d8d5d4c76442a199d", size = 300638, upload-time = "2025-10-06T05:36:56.758Z" }, { url = "https://files.pythonhosted.org/packages/fc/4f/a7e4d0d467298f42de4b41cbc7ddaf19d3cfeabaf9ff97c20c6c7ee409f9/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:5c1c8e78426e59b3f8005e9b19f6ff46e5845895adbde20ece9218319eca6506", size = 283067, upload-time = "2025-10-06T05:36:57.965Z" }, { url = "https://files.pythonhosted.org/packages/dc/48/c7b163063d55a83772b268e6d1affb960771b0e203b632cfe09522d67ea5/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:eefdba20de0d938cec6a89bd4d70f346a03108a19b9df4248d3cf0d88f1b0f51", size = 292101, upload-time = "2025-10-06T05:36:59.237Z" }, { url = "https://files.pythonhosted.org/packages/9f/d0/2366d3c4ecdc2fd391e0afa6e11500bfba0ea772764d631bbf82f0136c9d/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cf253e0e1c3ceb4aaff6df637ce033ff6535fb8c70a764a8f46aafd3d6ab798e", size = 289901, upload-time = "2025-10-06T05:37:00.811Z" }, { url = "https://files.pythonhosted.org/packages/b8/94/daff920e82c1b70e3618a2ac39fbc01ae3e2ff6124e80739ce5d71c9b920/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:032efa2674356903cd0261c4317a561a6850f3ac864a63fc1583147fb05a79b0", size = 289395, upload-time = "2025-10-06T05:37:02.115Z" }, { url = "https://files.pythonhosted.org/packages/e3/20/bba307ab4235a09fdcd3cc5508dbabd17c4634a1af4b96e0f69bfe551ebd/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6da155091429aeba16851ecb10a9104a108bcd32f6c1642867eadaee401c1c41", size = 283659, upload-time = "2025-10-06T05:37:03.711Z" }, { url = "https://files.pythonhosted.org/packages/fd/00/04ca1c3a7a124b6de4f8a9a17cc2fcad138b4608e7a3fc5877804b8715d7/frozenlist-1.8.0-cp313-cp313t-win32.whl", hash = "sha256:0f96534f8bfebc1a394209427d0f8a63d343c9779cda6fc25e8e121b5fd8555b", size = 43492, upload-time = "2025-10-06T05:37:04.915Z" }, { url = "https://files.pythonhosted.org/packages/59/5e/c69f733a86a94ab10f68e496dc6b7e8bc078ebb415281d5698313e3af3a1/frozenlist-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5d63a068f978fc69421fb0e6eb91a9603187527c86b7cd3f534a5b77a592b888", size = 48034, upload-time = "2025-10-06T05:37:06.343Z" }, { url = "https://files.pythonhosted.org/packages/16/6c/be9d79775d8abe79b05fa6d23da99ad6e7763a1d080fbae7290b286093fd/frozenlist-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf0a7e10b077bf5fb9380ad3ae8ce20ef919a6ad93b4552896419ac7e1d8e042", size = 41749, upload-time = "2025-10-06T05:37:07.431Z" }, { url = "https://files.pythonhosted.org/packages/f1/c8/85da824b7e7b9b6e7f7705b2ecaf9591ba6f79c1177f324c2735e41d36a2/frozenlist-1.8.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cee686f1f4cadeb2136007ddedd0aaf928ab95216e7691c63e50a8ec066336d0", size = 86127, upload-time = "2025-10-06T05:37:08.438Z" }, { url = "https://files.pythonhosted.org/packages/8e/e8/a1185e236ec66c20afd72399522f142c3724c785789255202d27ae992818/frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f", size = 49698, upload-time = "2025-10-06T05:37:09.48Z" }, { url = "https://files.pythonhosted.org/packages/a1/93/72b1736d68f03fda5fdf0f2180fb6caaae3894f1b854d006ac61ecc727ee/frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c", size = 49749, upload-time = "2025-10-06T05:37:10.569Z" }, { url = "https://files.pythonhosted.org/packages/a7/b2/fabede9fafd976b991e9f1b9c8c873ed86f202889b864756f240ce6dd855/frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2", size = 231298, upload-time = "2025-10-06T05:37:11.993Z" }, { url = "https://files.pythonhosted.org/packages/3a/3b/d9b1e0b0eed36e70477ffb8360c49c85c8ca8ef9700a4e6711f39a6e8b45/frozenlist-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:778a11b15673f6f1df23d9586f83c4846c471a8af693a22e066508b77d201ec8", size = 232015, upload-time = "2025-10-06T05:37:13.194Z" }, { url = "https://files.pythonhosted.org/packages/dc/94/be719d2766c1138148564a3960fc2c06eb688da592bdc25adcf856101be7/frozenlist-1.8.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686", size = 225038, upload-time = "2025-10-06T05:37:14.577Z" }, { url = "https://files.pythonhosted.org/packages/e4/09/6712b6c5465f083f52f50cf74167b92d4ea2f50e46a9eea0523d658454ae/frozenlist-1.8.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:97260ff46b207a82a7567b581ab4190bd4dfa09f4db8a8b49d1a958f6aa4940e", size = 240130, upload-time = "2025-10-06T05:37:15.781Z" }, { url = "https://files.pythonhosted.org/packages/f8/d4/cd065cdcf21550b54f3ce6a22e143ac9e4836ca42a0de1022da8498eac89/frozenlist-1.8.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:54b2077180eb7f83dd52c40b2750d0a9f175e06a42e3213ce047219de902717a", size = 242845, upload-time = "2025-10-06T05:37:17.037Z" }, { url = "https://files.pythonhosted.org/packages/62/c3/f57a5c8c70cd1ead3d5d5f776f89d33110b1addae0ab010ad774d9a44fb9/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2f05983daecab868a31e1da44462873306d3cbfd76d1f0b5b69c473d21dbb128", size = 229131, upload-time = "2025-10-06T05:37:18.221Z" }, { url = "https://files.pythonhosted.org/packages/6c/52/232476fe9cb64f0742f3fde2b7d26c1dac18b6d62071c74d4ded55e0ef94/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:33f48f51a446114bc5d251fb2954ab0164d5be02ad3382abcbfe07e2531d650f", size = 240542, upload-time = "2025-10-06T05:37:19.771Z" }, { url = "https://files.pythonhosted.org/packages/5f/85/07bf3f5d0fb5414aee5f47d33c6f5c77bfe49aac680bfece33d4fdf6a246/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:154e55ec0655291b5dd1b8731c637ecdb50975a2ae70c606d100750a540082f7", size = 237308, upload-time = "2025-10-06T05:37:20.969Z" }, { url = "https://files.pythonhosted.org/packages/11/99/ae3a33d5befd41ac0ca2cc7fd3aa707c9c324de2e89db0e0f45db9a64c26/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:4314debad13beb564b708b4a496020e5306c7333fa9a3ab90374169a20ffab30", size = 238210, upload-time = "2025-10-06T05:37:22.252Z" }, { url = "https://files.pythonhosted.org/packages/b2/60/b1d2da22f4970e7a155f0adde9b1435712ece01b3cd45ba63702aea33938/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:073f8bf8becba60aa931eb3bc420b217bb7d5b8f4750e6f8b3be7f3da85d38b7", size = 231972, upload-time = "2025-10-06T05:37:23.5Z" }, { url = "https://files.pythonhosted.org/packages/3f/ab/945b2f32de889993b9c9133216c068b7fcf257d8595a0ac420ac8677cab0/frozenlist-1.8.0-cp314-cp314-win32.whl", hash = "sha256:bac9c42ba2ac65ddc115d930c78d24ab8d4f465fd3fc473cdedfccadb9429806", size = 40536, upload-time = "2025-10-06T05:37:25.581Z" }, { url = "https://files.pythonhosted.org/packages/59/ad/9caa9b9c836d9ad6f067157a531ac48b7d36499f5036d4141ce78c230b1b/frozenlist-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:3e0761f4d1a44f1d1a47996511752cf3dcec5bbdd9cc2b4fe595caf97754b7a0", size = 44330, upload-time = "2025-10-06T05:37:26.928Z" }, { url = "https://files.pythonhosted.org/packages/82/13/e6950121764f2676f43534c555249f57030150260aee9dcf7d64efda11dd/frozenlist-1.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:d1eaff1d00c7751b7c6662e9c5ba6eb2c17a2306ba5e2a37f24ddf3cc953402b", size = 40627, upload-time = "2025-10-06T05:37:28.075Z" }, { url = "https://files.pythonhosted.org/packages/c0/c7/43200656ecc4e02d3f8bc248df68256cd9572b3f0017f0a0c4e93440ae23/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d3bb933317c52d7ea5004a1c442eef86f426886fba134ef8cf4226ea6ee1821d", size = 89238, upload-time = "2025-10-06T05:37:29.373Z" }, { url = "https://files.pythonhosted.org/packages/d1/29/55c5f0689b9c0fb765055629f472c0de484dcaf0acee2f7707266ae3583c/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8009897cdef112072f93a0efdce29cd819e717fd2f649ee3016efd3cd885a7ed", size = 50738, upload-time = "2025-10-06T05:37:30.792Z" }, { url = "https://files.pythonhosted.org/packages/ba/7d/b7282a445956506fa11da8c2db7d276adcbf2b17d8bb8407a47685263f90/frozenlist-1.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2c5dcbbc55383e5883246d11fd179782a9d07a986c40f49abe89ddf865913930", size = 51739, upload-time = "2025-10-06T05:37:32.127Z" }, { url = "https://files.pythonhosted.org/packages/62/1c/3d8622e60d0b767a5510d1d3cf21065b9db874696a51ea6d7a43180a259c/frozenlist-1.8.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:39ecbc32f1390387d2aa4f5a995e465e9e2f79ba3adcac92d68e3e0afae6657c", size = 284186, upload-time = "2025-10-06T05:37:33.21Z" }, { url = "https://files.pythonhosted.org/packages/2d/14/aa36d5f85a89679a85a1d44cd7a6657e0b1c75f61e7cad987b203d2daca8/frozenlist-1.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92db2bf818d5cc8d9c1f1fc56b897662e24ea5adb36ad1f1d82875bd64e03c24", size = 292196, upload-time = "2025-10-06T05:37:36.107Z" }, { url = "https://files.pythonhosted.org/packages/05/23/6bde59eb55abd407d34f77d39a5126fb7b4f109a3f611d3929f14b700c66/frozenlist-1.8.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dc43a022e555de94c3b68a4ef0b11c4f747d12c024a520c7101709a2144fb37", size = 273830, upload-time = "2025-10-06T05:37:37.663Z" }, { url = "https://files.pythonhosted.org/packages/d2/3f/22cff331bfad7a8afa616289000ba793347fcd7bc275f3b28ecea2a27909/frozenlist-1.8.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb89a7f2de3602cfed448095bab3f178399646ab7c61454315089787df07733a", size = 294289, upload-time = "2025-10-06T05:37:39.261Z" }, { url = "https://files.pythonhosted.org/packages/a4/89/5b057c799de4838b6c69aa82b79705f2027615e01be996d2486a69ca99c4/frozenlist-1.8.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:33139dc858c580ea50e7e60a1b0ea003efa1fd42e6ec7fdbad78fff65fad2fd2", size = 300318, upload-time = "2025-10-06T05:37:43.213Z" }, { url = "https://files.pythonhosted.org/packages/30/de/2c22ab3eb2a8af6d69dc799e48455813bab3690c760de58e1bf43b36da3e/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:168c0969a329b416119507ba30b9ea13688fafffac1b7822802537569a1cb0ef", size = 282814, upload-time = "2025-10-06T05:37:45.337Z" }, { url = "https://files.pythonhosted.org/packages/59/f7/970141a6a8dbd7f556d94977858cfb36fa9b66e0892c6dd780d2219d8cd8/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:28bd570e8e189d7f7b001966435f9dac6718324b5be2990ac496cf1ea9ddb7fe", size = 291762, upload-time = "2025-10-06T05:37:46.657Z" }, { url = "https://files.pythonhosted.org/packages/c1/15/ca1adae83a719f82df9116d66f5bb28bb95557b3951903d39135620ef157/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b2a095d45c5d46e5e79ba1e5b9cb787f541a8dee0433836cea4b96a2c439dcd8", size = 289470, upload-time = "2025-10-06T05:37:47.946Z" }, { url = "https://files.pythonhosted.org/packages/ac/83/dca6dc53bf657d371fbc88ddeb21b79891e747189c5de990b9dfff2ccba1/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:eab8145831a0d56ec9c4139b6c3e594c7a83c2c8be25d5bcf2d86136a532287a", size = 289042, upload-time = "2025-10-06T05:37:49.499Z" }, { url = "https://files.pythonhosted.org/packages/96/52/abddd34ca99be142f354398700536c5bd315880ed0a213812bc491cff5e4/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:974b28cf63cc99dfb2188d8d222bc6843656188164848c4f679e63dae4b0708e", size = 283148, upload-time = "2025-10-06T05:37:50.745Z" }, { url = "https://files.pythonhosted.org/packages/af/d3/76bd4ed4317e7119c2b7f57c3f6934aba26d277acc6309f873341640e21f/frozenlist-1.8.0-cp314-cp314t-win32.whl", hash = "sha256:342c97bf697ac5480c0a7ec73cd700ecfa5a8a40ac923bd035484616efecc2df", size = 44676, upload-time = "2025-10-06T05:37:52.222Z" }, { url = "https://files.pythonhosted.org/packages/89/76/c615883b7b521ead2944bb3480398cbb07e12b7b4e4d073d3752eb721558/frozenlist-1.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:06be8f67f39c8b1dc671f5d83aaefd3358ae5cdcf8314552c57e7ed3e6475bdd", size = 49451, upload-time = "2025-10-06T05:37:53.425Z" }, { url = "https://files.pythonhosted.org/packages/e0/a3/5982da14e113d07b325230f95060e2169f5311b1017ea8af2a29b374c289/frozenlist-1.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:102e6314ca4da683dca92e3b1355490fed5f313b768500084fbe6371fddfdb79", size = 42507, upload-time = "2025-10-06T05:37:54.513Z" }, { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" }, ] [[package]] name = "ghp-import" version = "2.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "python-dateutil" }, ] sdist = { url = "https://files.pythonhosted.org/packages/d9/29/d40217cbe2f6b1359e00c6c307bb3fc876ba74068cbab3dde77f03ca0dc4/ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343", size = 10943, upload-time = "2022-05-02T15:47:16.11Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619", size = 11034, upload-time = "2022-05-02T15:47:14.552Z" }, ] [[package]] name = "greenlet" version = "2.0.2" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.12'", ] sdist = { url = "https://files.pythonhosted.org/packages/1e/1e/632e55a04d732c8184201238d911207682b119c35cecbb9a573a6c566731/greenlet-2.0.2.tar.gz", hash = "sha256:e7c8dc13af7db097bed64a051d2dd49e9f0af495c26995c00a9ee842690d34c0", size = 164980, upload-time = "2023-01-28T14:19:28.808Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/a8/7a/5542d863a91b3309585219bae7d97aa82fe0482499a840c100297262ec8f/greenlet-2.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c4302695ad8027363e96311df24ee28978162cdcdd2006476c43970b384a244c", size = 243039, upload-time = "2023-01-28T14:24:38.834Z" }, { url = "https://files.pythonhosted.org/packages/03/1a/dae7e4abc978e3eff4b8e90e76fb6619ba38d3cabac5f10131880fc03091/greenlet-2.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d4606a527e30548153be1a9f155f4e283d109ffba663a15856089fb55f933e47", size = 197881, upload-time = "2023-08-30T19:46:54.788Z" }, { url = "https://files.pythonhosted.org/packages/e8/3a/ebc4fa1e813ae1fa718eb88417c31587e2efb743ed5f6ff0ae066502c349/greenlet-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c48f54ef8e05f04d6eff74b8233f6063cb1ed960243eacc474ee73a2ea8573ca", size = 612431, upload-time = "2023-01-28T14:49:47.917Z" }, { url = "https://files.pythonhosted.org/packages/6b/2f/1cb3f376df561c95cb61b199676f51251f991699e325a2aa5e12693d10b8/greenlet-2.0.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1846f1b999e78e13837c93c778dcfc3365902cfb8d1bdb7dd73ead37059f0d0", size = 627807, upload-time = "2023-01-28T14:44:41.138Z" }, { url = "https://files.pythonhosted.org/packages/86/8d/3a18311306830f6db5f5676a1cb8082c8943bfa6c928b40006e5358170fc/greenlet-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a06ad5312349fec0ab944664b01d26f8d1f05009566339ac6f63f56589bc1a2", size = 618820, upload-time = "2023-01-28T14:24:07.185Z" }, { url = "https://files.pythonhosted.org/packages/f0/2e/20eab0fa6353a08b0de055dd54e2575a6869ee693d86387076430475832d/greenlet-2.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:eff4eb9b7eb3e4d0cae3d28c283dc16d9bed6b193c2e1ace3ed86ce48ea8df19", size = 1138292, upload-time = "2023-01-28T14:50:01.666Z" }, { url = "https://files.pythonhosted.org/packages/71/c5/c26840ce91bcbbfc42c1a246289d9d4c758663652669f24e37f84bcdae2a/greenlet-2.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5454276c07d27a740c5892f4907c86327b632127dd9abec42ee62e12427ff7e3", size = 1161342, upload-time = "2023-01-28T14:26:41.487Z" }, { url = "https://files.pythonhosted.org/packages/7e/a6/0a34cde83fe520fa4e8192a1bc0fc7bf9f755215fefe3f42c9b97c45c620/greenlet-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:7cafd1208fdbe93b67c7086876f061f660cfddc44f404279c1585bbf3cdc64c5", size = 192458, upload-time = "2023-01-28T15:03:33.159Z" }, ] [[package]] name = "greenlet" version = "3.5.3" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.15' and implementation_name == 'cpython'", "python_full_version == '3.14.*' and implementation_name == 'cpython'", "python_full_version >= '3.15' and implementation_name != 'cpython' and sys_platform == 'emscripten'", "(python_full_version >= '3.13' and python_full_version < '3.15' and implementation_name != 'cpython' and sys_platform == 'emscripten') or (python_full_version == '3.13.*' and implementation_name == 'cpython' and sys_platform == 'emscripten')", "python_full_version == '3.12.*' and sys_platform == 'emscripten'", "python_full_version >= '3.15' and implementation_name != 'cpython' and sys_platform != 'emscripten'", "(python_full_version >= '3.13' and python_full_version < '3.15' and implementation_name != 'cpython' and sys_platform != 'emscripten') or (python_full_version == '3.13.*' and implementation_name == 'cpython' and sys_platform != 'emscripten')", "python_full_version == '3.12.*' and sys_platform != 'emscripten'", ] sdist = { url = "https://files.pythonhosted.org/packages/e2/f1/fbbfef6af0bad0548f09bc28948ea3c275b4edb19e17fc5ca9900a6a634d/greenlet-3.5.3.tar.gz", hash = "sha256:a61efc018fd3eb317eeca31aba90ee9e7f26f22884a79b6c6ec715bf71bb62f1", size = 200270, upload-time = "2026-06-26T19:28:24.832Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/51/58/5404031044f55afad7aad1aff8be3f22b1bed03e237cfeabbc7e5c8cfde0/greenlet-3.5.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:aca9b4ce85b152b5524ef7d88170efdff80dc0032aa8b75f9aaf7f3479ea95b4", size = 287424, upload-time = "2026-06-26T18:20:31.469Z" }, { url = "https://files.pythonhosted.org/packages/b4/bf/1c65e9b94a54d547068fa5b5a8a06f221f3316b48908e08668d29c77cb50/greenlet-3.5.3-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f71be4920368fe1fabeeaa53d1e3548337e2b223d9565f8ad5e392a75ba23fc", size = 606523, upload-time = "2026-06-26T19:07:08.859Z" }, { url = "https://files.pythonhosted.org/packages/b8/c7/b66baacc95775ad511287acb0137b95574a9ce5491902372b7564799d790/greenlet-3.5.3-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4d77e67f65f98449e3fb83f795b5d0a8437aead2f874ca89c96576caf4be3af6", size = 618315, upload-time = "2026-06-26T19:10:06.055Z" }, { url = "https://files.pythonhosted.org/packages/b0/a0/68afd1ebad40db87dac0a28ffa120726b98bf9c7c40c481b0f63c105d298/greenlet-3.5.3-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e18619ba655ac05d78d80fc83cac4ba892bd6927b99e3b8237aee861aaacc8bb", size = 626155, upload-time = "2026-06-26T19:24:14.44Z" }, { url = "https://files.pythonhosted.org/packages/78/2b/28ed29463522fdbe4c15b1f63922041626a7478316b34ab4adda3f0a4aba/greenlet-3.5.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8540f1e6205bd13ca0ce685581037219ca54a1b41a0a15d228c6c9b8ad5903d7", size = 617381, upload-time = "2026-06-26T18:32:16.077Z" }, { url = "https://files.pythonhosted.org/packages/07/7f/e327d912239ec4b3b49999e3967389bcf1ee8722b9ee9194d2752ecd558a/greenlet-3.5.3-cp311-cp311-manylinux_2_39_riscv64.whl", hash = "sha256:d27c0c653a60d9535f690226474a5cc1036a8b0d7b57504d1c4f89c44a07a80c", size = 421083, upload-time = "2026-06-26T19:25:35.804Z" }, { url = "https://files.pythonhosted.org/packages/2a/7b/ad04e9d1337fc04965dc9fc616b6a72cb65a24b800a014c011ec812f5489/greenlet-3.5.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7ef56fe650f50575bf843acde967b9c567687f3c22340941a899b7bc56e956a8", size = 1577771, upload-time = "2026-06-26T19:09:01.537Z" }, { url = "https://files.pythonhosted.org/packages/d8/33/6c87ab7ba663f70ca21f3022aad1ffe56d3f3e0521e836c2415e13abcc3c/greenlet-3.5.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5121af01cf911e70056c00d4b46d5e9b5d1415550038573d744138bacb59e6b8", size = 1644048, upload-time = "2026-06-26T18:31:42.996Z" }, { url = "https://files.pythonhosted.org/packages/1c/35/f0d8ee998b422cf8693b270f098e55d8d4ec8006b061b333f54f177d28d9/greenlet-3.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:0f41e4a05a3c0cb31b17023eff28dd111e1d16bf7d7d00406cd7df23f31398a7", size = 239137, upload-time = "2026-06-26T18:23:21.664Z" }, { url = "https://files.pythonhosted.org/packages/fb/96/b9820295576ef18c9edc404f10e260ae7215ceaf3781a54b720ed2627862/greenlet-3.5.3-cp311-cp311-win_arm64.whl", hash = "sha256:ec6f1af59f6b5f3fc9678e2ea062d8377d22ac644f7844cb7a292910cf12ff44", size = 237630, upload-time = "2026-06-26T18:24:00.281Z" }, { url = "https://files.pythonhosted.org/packages/5d/6e/4c37d51a2b7f82d2ff11bb6b5f7d766d9a011726624af255e843727627a3/greenlet-3.5.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:719757059f5a53fd0dde23f78cffeafcdd97b21c850ddb7ca684a3c1a1f122e2", size = 288685, upload-time = "2026-06-26T18:22:08.977Z" }, { url = "https://files.pythonhosted.org/packages/7a/73/815dd90131c1b71ebdf53dbc7c276cafec2a1173b97559f97aba72724a87/greenlet-3.5.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:efa9f765dd09f9d0cdac651ffdf631ee59ec5dc6ee7a73e0c012ba9c52fbdf5b", size = 604761, upload-time = "2026-06-26T19:07:10.114Z" }, { url = "https://files.pythonhosted.org/packages/9f/57/079cfe76bcef36b153b25607ee91c6fcb58f17f8b23c86bbbeabe0c88d72/greenlet-3.5.3-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7faba15ac005376e02a0384504e0243be3370ce010296a44a820feb342b505ab", size = 617044, upload-time = "2026-06-26T19:10:07.25Z" }, { url = "https://files.pythonhosted.org/packages/fb/fb/d97dc261209c80744b7c8132693a30d70ec6e7315e632cb0a10b3fec94dd/greenlet-3.5.3-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5795cd1101371140551c645f2d408b8d3c01a5a29cf8a9bce6e759c983682d23", size = 622351, upload-time = "2026-06-26T19:24:16.32Z" }, { url = "https://files.pythonhosted.org/packages/37/87/b4d095775a3fb1bcafbb483fc206b27ebb785724c83051447737085dc54e/greenlet-3.5.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:87142215824be6ac05e2e8e2786eec307ccbc27c36723c3881959df654af6861", size = 614244, upload-time = "2026-06-26T18:32:17.594Z" }, { url = "https://files.pythonhosted.org/packages/8e/ac/e5fee13cbbd0e8de312d9a146584b8a51891c68847330ef9dc8b5109d23f/greenlet-3.5.3-cp312-cp312-manylinux_2_39_riscv64.whl", hash = "sha256:af4923b3096e26a36d7e9cf24ab88083a20f97d191e3b97f253731ce9b41b28c", size = 425395, upload-time = "2026-06-26T19:25:37.144Z" }, { url = "https://files.pythonhosted.org/packages/8a/70/7559b609683650fa2b95b8ab84b4ab0b26556a635d19675e12aa832d826d/greenlet-3.5.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:215275b1b49320987352e6c1b054acca0064f965a2c66992bed9a6f7d913f149", size = 1574210, upload-time = "2026-06-26T19:09:03.077Z" }, { url = "https://files.pythonhosted.org/packages/ae/73/be55392074c60fc37655ca40fa6022457bfbf6718e9e342a7b0b41f96dd2/greenlet-3.5.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6b1b0eed82364b0e32c4ea0f221452d33e6bb17ae094d9f72aed9851812747ea", size = 1638627, upload-time = "2026-06-26T18:31:44.748Z" }, { url = "https://files.pythonhosted.org/packages/14/40/c57489acf8e37d74e2913d4eff63aa0dba17acccc4bdeef874dde2dbbec9/greenlet-3.5.3-cp312-cp312-win_amd64.whl", hash = "sha256:cde8adafa2365676f74a979744629589999093bc86e2484214f58e61df08902c", size = 239882, upload-time = "2026-06-26T18:23:27.518Z" }, { url = "https://files.pythonhosted.org/packages/71/fd/6fea0e3d6600f785069481ee637e09378dd4118acdfd38ad88ae2db31c98/greenlet-3.5.3-cp312-cp312-win_arm64.whl", hash = "sha256:c4e7b79d83805475f0102008843f6eb45fd3bb0b2e88c774adab5fbaab27117d", size = 238211, upload-time = "2026-06-26T18:22:37.671Z" }, { url = "https://files.pythonhosted.org/packages/9b/ff/a620267401db30a50cc8450ee90730e2d4a85658c055c0e760d4ed47fb13/greenlet-3.5.3-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:c8d87c2134d871df96ecdea9cec7cbaab286dadab0f56476e57aaf9e8ac11550", size = 287609, upload-time = "2026-06-26T18:21:14.724Z" }, { url = "https://files.pythonhosted.org/packages/d6/fa/5401ac78021c826a25b6dde0c705e0a8f29b617509f9185a31dac15fbe1b/greenlet-3.5.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a2d185dd1621757e70c3861cceffd5317ab4e7ed7eb09c82994828468527ade5", size = 607435, upload-time = "2026-06-26T19:07:11.412Z" }, { url = "https://files.pythonhosted.org/packages/e9/76/1dc144a2e56e65d36405078ed774224375ea520a1870a6e46e08bb4ac7bf/greenlet-3.5.3-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1c514a468149bf8fbbab874188a3535cd8a48a3e353eb53a3d424296f8dbacd3", size = 619787, upload-time = "2026-06-26T19:10:08.396Z" }, { url = "https://files.pythonhosted.org/packages/57/61/2f5b1adf256d039f5dab8005de8d3d7ad2b0070a3219c0e036b3fbfeb440/greenlet-3.5.3-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9ad04dd75458c6300b047c61b8639092433d205a25a14e310d6582a480efcca1", size = 625580, upload-time = "2026-06-26T19:24:18.344Z" }, { url = "https://files.pythonhosted.org/packages/bf/87/c298cee62df1de4ad7fec32abda73526cff347fd143a6ed4ac369246668a/greenlet-3.5.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:915f887cf2682b66419b879423a2e072634aa7b7dce6f3ada4957cfced3f1e9a", size = 616786, upload-time = "2026-06-26T18:32:19.128Z" }, { url = "https://files.pythonhosted.org/packages/3e/d9/ab7fc9e543e44d6879b0a6ef9a4b2188940fd180cc65d6f646883ddf7201/greenlet-3.5.3-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:afaabdd554cd7ae9bbb3ca070b0d7fdfd207dbf1d16865f7233837709d354bda", size = 427933, upload-time = "2026-06-26T19:25:38.219Z" }, { url = "https://files.pythonhosted.org/packages/9e/2e/e6f009885ed0705ccf33fe0583c117cfd03cde77e31a596dd5785a30762b/greenlet-3.5.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:766cfd421c13e450feb340cd472a3ed9957d438727b7b4593ad7c76c5d2b0deb", size = 1574316, upload-time = "2026-06-26T19:09:04.273Z" }, { url = "https://files.pythonhosted.org/packages/ef/fe/43fd110b01e40da0adb7c90ac7ea744bef2d43dca00de5095fd2351c2a68/greenlet-3.5.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2ecda9ec22edf38fa389369eaed8c3d37c05f3c54e69f69438dbb2cc1de1458b", size = 1638614, upload-time = "2026-06-26T18:31:46.297Z" }, { url = "https://files.pythonhosted.org/packages/0f/7c/062447147a61f8b4337b156fe70d32a165fcf2f89d7ca6255e572806705c/greenlet-3.5.3-cp313-cp313-win_amd64.whl", hash = "sha256:c82304750f057167ff60d188df1d0cc1764ce9567eadf03e6a7443bcedd0b30b", size = 239850, upload-time = "2026-06-26T18:21:54.613Z" }, { url = "https://files.pythonhosted.org/packages/c7/7e/220a7f5824a64a60443fc03b39dfac4ea63a7fb6d481efa27eafa928e7f4/greenlet-3.5.3-cp313-cp313-win_arm64.whl", hash = "sha256:dc133a1569ee667b2a6ef56ce551084aeefd87a5acbc4736d336d1e2edc6cfc4", size = 238141, upload-time = "2026-06-26T18:22:48.507Z" }, { url = "https://files.pythonhosted.org/packages/c3/93/43e116ee114b28737ba7e12952a0d4e2f55944d0f84e42bc91ba7192a3c9/greenlet-3.5.3-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:fd2e02fa07485778536a036222d616ab957b1d533f36b3ed98ce725d9c9d3117", size = 288202, upload-time = "2026-06-26T18:23:49.604Z" }, { url = "https://files.pythonhosted.org/packages/82/2f/146d218299046a43d1f029fd544b3d110d0f175a09c715c7e8da4a4a345d/greenlet-3.5.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df0a0628d1597eb0897b62f55d1343f772405fd25f3b2a796c76874b0c2e22e8", size = 654096, upload-time = "2026-06-26T19:07:12.71Z" }, { url = "https://files.pythonhosted.org/packages/a0/cc/04738cafb3f45fa991ea44f9de94c47dcec964f5a972300988a6751f49d9/greenlet-3.5.3-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ebd933a6adabc298bab47731a130fe6bfb888bd934eee37810f151159544540d", size = 666304, upload-time = "2026-06-26T19:10:09.503Z" }, { url = "https://files.pythonhosted.org/packages/86/a9/73fa62893d5b84b4205544e6b673c654cc43aa5b9899bac00f04d64af73d/greenlet-3.5.3-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8d19fe6c39ebff9259f07bcc685d3290f8fa4ea2278e51dd0008e4d6b0f2d814", size = 670657, upload-time = "2026-06-26T19:24:19.967Z" }, { url = "https://files.pythonhosted.org/packages/ce/aa/4e0dad5e605c270c784ab911c43da6adb136ccd4d81180f763ca429a723d/greenlet-3.5.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4b9d501b40e80b70e32323c799dd9b420a5577a9601469d362ae1ffb690f3a7c", size = 663635, upload-time = "2026-06-26T18:32:20.802Z" }, { url = "https://files.pythonhosted.org/packages/29/7e/2ffce64929fb3cab7b65d5a0b20aaf9764e227681d731b041077fc9a525a/greenlet-3.5.3-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:962c5df2db8cb446da51edf1ca5296c389d93b99c9d8aa2ee4c7d0d8f1218260", size = 473497, upload-time = "2026-06-26T19:25:39.421Z" }, { url = "https://files.pythonhosted.org/packages/d1/50/13efdbea246fe3d3b735e191fec08fb50809f53cd2383ebe123d0809e44b/greenlet-3.5.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a1fad1d11e7d6aab184107baa8e4ece11ccba3ec9599cd7efa5ff4d70d43256a", size = 1621252, upload-time = "2026-06-26T19:09:05.647Z" }, { url = "https://files.pythonhosted.org/packages/f7/22/c0a336ae4a1410fd5f5121098e5bfbf1865f64c5ef80b4b5412886c4a332/greenlet-3.5.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:fad5aec764399f1b5cc347ad250a59660f20c8f8888ea6bae1f93b769cce1154", size = 1684824, upload-time = "2026-06-26T18:31:47.738Z" }, { url = "https://files.pythonhosted.org/packages/7a/94/91aec0030bea75c4b3244251d0de60a1f3432d1ecb53ab6c437fb5c3ba61/greenlet-3.5.3-cp314-cp314-win_amd64.whl", hash = "sha256:7669aa24cf2a1041d6f7899575b494a3ab4cf68bfcc8609b1dc0be7272db835e", size = 240754, upload-time = "2026-06-26T18:22:15.669Z" }, { url = "https://files.pythonhosted.org/packages/e5/06/68d0983e79e02138f64b4d303c500c27ddb48e5e77f3debb80888a921eae/greenlet-3.5.3-cp314-cp314-win_arm64.whl", hash = "sha256:5b4807c4082c9d1b6d9eed56fcd041863e37f2228106eef24c30ca096e238605", size = 239549, upload-time = "2026-06-26T18:22:42.996Z" }, { url = "https://files.pythonhosted.org/packages/91/95/3e161213d7f1d378d15aa9e792093e9bfe01844680d04b7fd6e0107c9098/greenlet-3.5.3-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:271a8ea7c1024e8a0d7dd2be66dd66dda8a07193f41a17b9e924f7600f5b62be", size = 296389, upload-time = "2026-06-26T18:22:20.657Z" }, { url = "https://files.pythonhosted.org/packages/00/92/715c44721abe2b4d1ae9abde4179411868a5bff312479f54e105d372f131/greenlet-3.5.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:19131729ae0ddc3c2e1ef85e650169b5e37ee32e400f215f78b94d7b0d567310", size = 653382, upload-time = "2026-06-26T19:07:14.209Z" }, { url = "https://files.pythonhosted.org/packages/a0/83/37a10372a1090a6624cca8e74c12df1a36c2dc36429ed0255b7fb1aeee23/greenlet-3.5.3-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1540dd8e5fc2a5aec40fbb98ef8e149fa47c89a4b4a1cf2575a14d3d1869d7a8", size = 659401, upload-time = "2026-06-26T19:10:10.876Z" }, { url = "https://files.pythonhosted.org/packages/cb/73/8faec206b851c22b1733545fda900829a1f3f5b1c78ae7e0fb3dba57d9f4/greenlet-3.5.3-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b897d97759425953f69a9c0fac67f8fe333ec0ce7377ef186fb2b0c3ad5e354d", size = 659582, upload-time = "2026-06-26T19:24:21.357Z" }, { url = "https://files.pythonhosted.org/packages/db/e2/d1509cad4207da559cc42986ecdd8fc67ad0d1bba2bf03023c467fd5e0f3/greenlet-3.5.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e81fa194a1d20967877bdf9c7794db2bc99063e5be36aee710c08f04c5bb087f", size = 656969, upload-time = "2026-06-26T18:32:22.272Z" }, { url = "https://files.pythonhosted.org/packages/b4/55/50c19e49f8045834ada71ef12f8ad048eba8517c6aa41161bed676328fae/greenlet-3.5.3-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:3236754d423955ea08e9bb5f6c04a7895f9e22c290b66aa7653fcb922d839eb0", size = 491037, upload-time = "2026-06-26T19:25:40.672Z" }, { url = "https://files.pythonhosted.org/packages/86/7d/eaf70de20aadca3a5884aec58362861c64ce45e7b277f47ed026926a3b89/greenlet-3.5.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:55cf4d777485d43110e47133cbba6d74a8885a87ec1227ef0267f9ee80c5aa21", size = 1617822, upload-time = "2026-06-26T19:09:06.893Z" }, { url = "https://files.pythonhosted.org/packages/8a/f9/414d38fc400ae4350d4185eaad1827676f7cf5287b9136e0ed1cbbe20a7f/greenlet-3.5.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:12a248ba75f6a9a236375f52296c498c89ff1d8badf32deb9eca7abd5853f7da", size = 1677983, upload-time = "2026-06-26T18:31:49.396Z" }, { url = "https://files.pythonhosted.org/packages/e4/15/7edb977e08f9bff702fe42d6c902702786ff6b9694058b4e6a2a6ac90e57/greenlet-3.5.3-cp314-cp314t-win_amd64.whl", hash = "sha256:efc6bd60ea02e085862c74a3ef64b147ffc6f1a5ea7d9f26e7a939943f68c1e3", size = 243626, upload-time = "2026-06-26T18:24:41.485Z" }, { url = "https://files.pythonhosted.org/packages/2c/8a/93928dce91e6b3598b5e779e8d1fd6576a504640c58e78627077f6a7a91a/greenlet-3.5.3-cp315-cp315-macosx_11_0_universal2.whl", hash = "sha256:ea03f2f04367845d6b58eeed276e1e56e51f0b97d8ad5a88a7d20a91dc9056cc", size = 288860, upload-time = "2026-06-26T18:22:48.07Z" }, { url = "https://files.pythonhosted.org/packages/4f/ca/69db42d447a1378043e2c8f19c09cbbd1263371505053c496b49066d3d16/greenlet-3.5.3-cp315-cp315-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:78dbef602fda6d97d957eb7937f70c9ce9e9527330347f8f6b6f9e554a9e7a47", size = 659747, upload-time = "2026-06-26T19:07:15.565Z" }, { url = "https://files.pythonhosted.org/packages/a8/0b/af7ac2ef8dd41e3da1a40dda6305c23b9a03e13ba975ec916357b50f8575/greenlet-3.5.3-cp315-cp315-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6f73857adb8fee13fa56c172bd11262f888c0c648f9fea113e777bb2c7904a81", size = 670419, upload-time = "2026-06-26T19:10:12.293Z" }, { url = "https://files.pythonhosted.org/packages/25/aa/952cf28c2ff949a8c971134fb43854dd7eaa737218723aaef758f8c9aead/greenlet-3.5.3-cp315-cp315-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:cefa9cef4b371f9844c6053db71f1138bc6807bab1578b0dae5149c1f1141357", size = 674261, upload-time = "2026-06-26T19:24:22.79Z" }, { url = "https://files.pythonhosted.org/packages/51/1e/1d51640cacbfc455dbe9f9a9f594c49e4e244f63b9971a2f4764e46cc53d/greenlet-3.5.3-cp315-cp315-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:232fec92e823addaf02d9472cf7381e24a1d046a6ced1103c5caa4c21b9dfc1d", size = 668787, upload-time = "2026-06-26T18:32:24.298Z" }, { url = "https://files.pythonhosted.org/packages/dc/f2/b00d6f5e63e531a93562b2ec1a4c320fbee91f580fc42e6417af69d706e5/greenlet-3.5.3-cp315-cp315-manylinux_2_39_riscv64.whl", hash = "sha256:6219b6d04dbf6ba6084d77dc609e8473060dc55f759cbf626d512122781fa128", size = 480322, upload-time = "2026-06-26T19:25:41.852Z" }, { url = "https://files.pythonhosted.org/packages/21/66/4030d5b0b5894500023f003bb054d9bb354dfbd1e186c3a296759172f5f5/greenlet-3.5.3-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:2421c3564da9429d5586d46ca31ebb26516b5498a802cf65c041a8e8a8980d34", size = 1626305, upload-time = "2026-06-26T19:09:08.281Z" }, { url = "https://files.pythonhosted.org/packages/0e/50/5221371c7550108dfa3c378debc41d032aa9c78e89abb01d8011cfc93289/greenlet-3.5.3-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:e0f0d160f0b2e558e6c75f7930967183255dc9735e5f5b8cae58ee09c9576d8b", size = 1688631, upload-time = "2026-06-26T18:31:51.278Z" }, { url = "https://files.pythonhosted.org/packages/68/5d/00d469daae3c65d2bf620b10eee82eb022127d483c6bc8c69fae6f3fbf17/greenlet-3.5.3-cp315-cp315-win_amd64.whl", hash = "sha256:dd99329bbc15ca78dcc583dba05d0b1b0bae01ab6c2174989f5aaee3e41ac930", size = 241027, upload-time = "2026-06-26T18:22:38.203Z" }, { url = "https://files.pythonhosted.org/packages/e7/e8/883785b44c5780ed71e83d3e4437e710470be17a2e181e8b601e2da0dc4a/greenlet-3.5.3-cp315-cp315-win_arm64.whl", hash = "sha256:499fef2acede88c1864a57bb586b4bf533c81e1b82df7ab93451cdb47dfec227", size = 240085, upload-time = "2026-06-26T18:23:54.217Z" }, { url = "https://files.pythonhosted.org/packages/1c/da/4f4a8450962fad137c1c8981a3f1b8919d06c829993d4d476f9c525d5173/greenlet-3.5.3-cp315-cp315t-macosx_11_0_universal2.whl", hash = "sha256:176bc16a721fa5fc294d70b87b4dfa5fbdd251b3da5d5372735ecef9bd7d6d0c", size = 297221, upload-time = "2026-06-26T18:23:27.176Z" }, { url = "https://files.pythonhosted.org/packages/57/66/b3bfae3e220a9b63ea539a0eea681800c69ab1aada757eae8789f183e7ce/greenlet-3.5.3-cp315-cp315t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:629b614d2b786e89c50440e246f33eea78f58a962d0bdbbcc809e6d13605903f", size = 657221, upload-time = "2026-06-26T19:07:16.973Z" }, { url = "https://files.pythonhosted.org/packages/7b/81/b6d4d73a709684fc77e7fa034d7c2fe82cffa9fc920fadcaa659c2626213/greenlet-3.5.3-cp315-cp315t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2b2e857ae16f5f72142edf75f9f176fe7526ba19a2841df1420516f83831c9f2", size = 663226, upload-time = "2026-06-26T19:10:13.723Z" }, { url = "https://files.pythonhosted.org/packages/e9/39/0e0938a75115b939d42733a2a12e1d349653c9531fe6fe563e8a681f04e6/greenlet-3.5.3-cp315-cp315t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:16d192579ed281051396dddd7f7754dac6259e6b1fb26378c87b66622f8e3f91", size = 663706, upload-time = "2026-06-26T19:24:24.312Z" }, { url = "https://files.pythonhosted.org/packages/f5/07/e210b02b589f16e74ff48b730690e4a34ffe984219fce4f3c1a0e7ec8545/greenlet-3.5.3-cp315-cp315t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e515757e2e36bcbf1fad09a46e1557e8b1ae1797d4b44d09da7deed88ad28608", size = 660802, upload-time = "2026-06-26T18:32:26.081Z" }, { url = "https://files.pythonhosted.org/packages/5b/41/35d1c678cdb3c3b9e6bee691728e563cfb294202b23c7a4c3c2ccc343589/greenlet-3.5.3-cp315-cp315t-manylinux_2_39_riscv64.whl", hash = "sha256:4399eb8d041f20b68d943918bc55502a93d6fdc0a37c14da7881c04139acee9d", size = 498803, upload-time = "2026-06-26T19:25:43.063Z" }, { url = "https://files.pythonhosted.org/packages/eb/2e/5303eb3fa06bca089060f479707182a93e360683bc252acf846c3090d34e/greenlet-3.5.3-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:b363d46ed1ea431825fdb01471bb024fc08399bad1572a616e853c7684415adb", size = 1622157, upload-time = "2026-06-26T19:09:09.527Z" }, { url = "https://files.pythonhosted.org/packages/54/70/50de47a488f14df260b50ae34fb5d56016e308b098eab02c878b5223c26a/greenlet-3.5.3-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:e44da2f5bbdaabaf7d80b73dbb430c7035771e9f244e3c8b769715c9d8fa0a16", size = 1681159, upload-time = "2026-06-26T18:31:52.986Z" }, { url = "https://files.pythonhosted.org/packages/a7/13/1055e1dda7882073eda533e2b96c62e55bbd2db7fda6d5ece992febc7071/greenlet-3.5.3-cp315-cp315t-win_amd64.whl", hash = "sha256:8ff8bed3e3baa20a3ea261ce00526f1898ad4801d4886fd2220580ee0ad8fadf", size = 244007, upload-time = "2026-06-26T18:22:04.353Z" }, { url = "https://files.pythonhosted.org/packages/b4/0d/ca7d15afbdc397e3401134c9e1800d51d12b829661786187a4ad08fe484f/greenlet-3.5.3-cp315-cp315t-win_arm64.whl", hash = "sha256:b7068bd09f761f3f5b4d214c2bed063186b2a86148c740b3873e3f56d79bac31", size = 242586, upload-time = "2026-06-26T18:23:37.93Z" }, ] [[package]] name = "griffelib" version = "2.0.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/9d/82/74f4a3310cdabfbb10da554c3a672847f1ed33c6f61dd472681ce7f1fe67/griffelib-2.0.2.tar.gz", hash = "sha256:3cf20b3bc470e83763ffbf236e0076b1211bac1bc67de13daf494640f2de707e", size = 166461, upload-time = "2026-03-27T11:34:51.091Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/11/8c/c9138d881c79aa0ea9ed83cbd58d5ca75624378b38cee225dcf5c42cc91f/griffelib-2.0.2-py3-none-any.whl", hash = "sha256:925c857658fb1ba40c0772c37acbc2ab650bd794d9c1b9726922e36ea4117ea1", size = 142357, upload-time = "2026-03-27T11:34:46.275Z" }, ] [[package]] name = "h11" version = "0.16.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, ] [[package]] name = "h2" version = "4.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "hpack" }, { name = "hyperframe" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e7/85/7c366e69d84c17bb778fe41419e1fbcce3033d5b7ce29bbffff0a98b859f/h2-4.4.1.tar.gz", hash = "sha256:4e866ffb1a869ae14dd9b5e6beb5c24a13da0495ad72b65925ded182521c1516", size = 2157281, upload-time = "2026-08-03T11:45:09.509Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/7e/22/e85faf23bd72a92d1921e37d674ca56eb298a3c8be31fdecef0ff2b3aaac/h2-4.4.1-py3-none-any.whl", hash = "sha256:0e25f1462b23c9cb82d9eb02e28bc706dac2a68cb457c6a0d74d63c8a2a5d0e6", size = 62636, upload-time = "2026-08-03T11:44:59.164Z" }, ] [[package]] name = "hpack" version = "4.2.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/26/5b/fcabf6028144a8723726318b07a32c2f3314acdff6265743cf08a344b18e/hpack-4.2.0.tar.gz", hash = "sha256:0895cfa3b5531fc65fe439c05eb65144f123bf7a394fcaa56aa423548d8e45c0", size = 51300, upload-time = "2026-06-23T18:34:46.667Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/71/b4/4a9fcfb2aef6ba44d9073ecd301443aa00b3dac95de5619f2a7de7ec8a91/hpack-4.2.0-py3-none-any.whl", hash = "sha256:858ac0b02280fa582b5080d68db0899c62a80375e0e5413a74970c5e518b6986", size = 34246, upload-time = "2026-06-23T18:34:45.472Z" }, ] [[package]] name = "httpbin" version = "0.10.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "brotlicffi" }, { name = "decorator" }, { name = "flasgger" }, { name = "flask" }, { name = "greenlet", version = "2.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, { name = "greenlet", version = "3.5.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, { name = "six" }, { name = "werkzeug" }, ] sdist = { url = "https://files.pythonhosted.org/packages/61/90/e2eeeedc96fbfd9345dff0407574b8edb8ff97ad1682ef518bdfaf096dd5/httpbin-0.10.2.tar.gz", hash = "sha256:632148698261c8684ea2d2b624cdea845b402b1fe91736e89df886408c6317a9", size = 107327, upload-time = "2024-02-20T21:30:15.221Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/1f/2a/12e12f8f07070cd12b46c60fd8fd709ff01414830213bfc5153ab527331f/httpbin-0.10.2-py2.py3-none-any.whl", hash = "sha256:8e28e67f72ead4419977c9f2dba4ce86ce08768ada30ef9a87288527bb925d00", size = 100343, upload-time = "2024-02-20T21:30:12.383Z" }, ] [[package]] name = "httpcore2" source = { editable = "src/httpcore2" } dependencies = [ { name = "h11" }, { name = "truststore" }, ] [package.optional-dependencies] asyncio = [ { name = "anyio" }, ] http2 = [ { name = "h2" }, ] socks = [ { name = "socksio" }, ] trio = [ { name = "trio" }, ] [package.metadata] requires-dist = [ { name = "anyio", marker = "extra == 'asyncio'", specifier = ">=4.5.0,<5.0" }, { name = "h11", specifier = ">=0.16" }, { name = "h2", marker = "extra == 'http2'", specifier = ">=3,<5" }, { name = "socksio", marker = "extra == 'socks'", specifier = "==1.*" }, { name = "trio", marker = "extra == 'trio'", specifier = ">=0.34.0,<1.0" }, { name = "truststore", specifier = ">=0.10" }, ] provides-extras = ["asyncio", "http2", "socks", "trio"] [[package]] name = "httpx2" source = { editable = "src/httpx2" } dependencies = [ { name = "anyio", marker = "sys_platform != 'emscripten'" }, { name = "httpcore2", marker = "sys_platform != 'emscripten'" }, { name = "httpx2-jsfetch", marker = "python_full_version >= '3.12' and sys_platform == 'emscripten'" }, { name = "idna" }, { name = "truststore", marker = "sys_platform != 'emscripten'" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] [package.optional-dependencies] brotli = [ { name = "brotli", marker = "platform_python_implementation == 'CPython'" }, { name = "brotlicffi", marker = "platform_python_implementation != 'CPython'" }, ] cli = [ { name = "click" }, { name = "pygments" }, { name = "rich" }, ] http2 = [ { name = "h2" }, ] socks = [ { name = "socksio" }, ] ws = [ { name = "wsproto" }, ] zstd = [ { name = "backports-zstd", marker = "python_full_version < '3.14'" }, ] [package.metadata] requires-dist = [ { name = "anyio", marker = "sys_platform != 'emscripten'", specifier = ">=4.10" }, { name = "backports-zstd", marker = "python_full_version < '3.14' and extra == 'zstd'", specifier = ">=1.0.0" }, { name = "brotli", marker = "platform_python_implementation == 'CPython' and extra == 'brotli'", specifier = ">=1.2.0" }, { name = "brotlicffi", marker = "platform_python_implementation != 'CPython' and extra == 'brotli'", specifier = ">=1.2.0.2" }, { name = "click", marker = "extra == 'cli'", specifier = ">=8.4.2" }, { name = "h2", marker = "extra == 'http2'", specifier = ">=3,<5" }, { name = "httpcore2", marker = "sys_platform != 'emscripten'", editable = "src/httpcore2" }, { name = "httpx2-jsfetch", marker = "python_full_version >= '3.12' and sys_platform == 'emscripten'" }, { name = "idna", specifier = ">=3.18" }, { name = "pygments", marker = "extra == 'cli'", specifier = "==2.*" }, { name = "rich", marker = "extra == 'cli'", specifier = ">=10,<16" }, { name = "socksio", marker = "extra == 'socks'", specifier = "==1.*" }, { name = "truststore", marker = "sys_platform != 'emscripten'", specifier = ">=0.10" }, { name = "typing-extensions", marker = "python_full_version < '3.13'", specifier = ">=4.5.0" }, { name = "wsproto", marker = "extra == 'ws'", specifier = ">=1.2" }, ] provides-extras = ["brotli", "cli", "http2", "socks", "ws", "zstd"] [[package]] name = "httpx2-jsfetch" version = "1.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/cd/c4/0e5636363151a2a1795e0a77617168b9ca438e1748ec05fc9b5687f93d64/httpx2_jsfetch-1.0.tar.gz", hash = "sha256:70a0e3eabfef7cce5ad9c629f7d01ca05e418f586646f4ddf14782e4c1454c60", size = 6872, upload-time = "2026-08-07T00:13:07.492Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/9b/43/832f631d32e4f1211caa2ba368317739fe71f0b8530e4c9d15dc454bac2a/httpx2_jsfetch-1.0-py3-none-any.whl", hash = "sha256:cb916b707601e69a07721aabc8f3f6659be3a6893bc1ff5c6f9e02241df2da32", size = 6382, upload-time = "2026-08-07T00:13:06.567Z" }, ] [[package]] name = "hyperframe" version = "6.1.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/02/e7/94f8232d4a74cc99514c13a9f995811485a6903d48e5d952771ef6322e30/hyperframe-6.1.0.tar.gz", hash = "sha256:f630908a00854a7adeabd6382b43923a4c4cd4b821fcb527e6ab9e15382a3b08", size = 26566, upload-time = "2025-01-22T21:41:49.302Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/48/30/47d0bf6072f7252e6521f3447ccfa40b421b6824517f82854703d0f5a98b/hyperframe-6.1.0-py3-none-any.whl", hash = "sha256:b03380493a519fce58ea5af42e4a42317bf9bd425596f7a0835ffce80f1a42e5", size = 13007, upload-time = "2025-01-22T21:41:47.295Z" }, ] [[package]] name = "id" version = "1.6.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "urllib3" }, ] sdist = { url = "https://files.pythonhosted.org/packages/6d/04/c2156091427636080787aac190019dc64096e56a23b7364d3c1764ee3a06/id-1.6.1.tar.gz", hash = "sha256:d0732d624fb46fd4e7bc4e5152f00214450953b9e772c182c1c22964def1a069", size = 18088, upload-time = "2026-02-04T16:19:41.26Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/42/77/de194443bf38daed9452139e960c632b0ef9f9a5dd9ce605fdf18ca9f1b1/id-1.6.1-py3-none-any.whl", hash = "sha256:f5ec41ed2629a508f5d0988eda142e190c9c6da971100612c4de9ad9f9b237ca", size = 14689, upload-time = "2026-02-04T16:19:40.051Z" }, ] [[package]] name = "idna" version = "3.18" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/cd/63/9496c57188a2ee585e0f1db071d75089a11e98aa86eb99d9d7618fc1edce/idna-3.18.tar.gz", hash = "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848", size = 196711, upload-time = "2026-06-02T14:34:07.794Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2", size = 65455, upload-time = "2026-06-02T14:34:06.319Z" }, ] [[package]] name = "importlib-metadata" version = "9.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "zipp" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a9/01/15bb152d77b21318514a96f43af312635eb2500c96b55398d020c93d86ea/importlib_metadata-9.0.0.tar.gz", hash = "sha256:a4f57ab599e6a2e3016d7595cfd72eb4661a5106e787a95bcc90c7105b831efc", size = 56405, upload-time = "2026-03-20T06:42:56.999Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/38/3d/2d244233ac4f76e38533cfcb2991c9eb4c7bf688ae0a036d30725b8faafe/importlib_metadata-9.0.0-py3-none-any.whl", hash = "sha256:2d21d1cc5a017bd0559e36150c21c830ab1dc304dedd1b7ea85d20f45ef3edd7", size = 27789, upload-time = "2026-03-20T06:42:55.665Z" }, ] [[package]] name = "iniconfig" version = "2.3.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, ] [[package]] name = "itsdangerous" version = "2.2.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/9c/cb/8ac0172223afbccb63986cc25049b154ecfb5e85932587206f42317be31d/itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173", size = 54410, upload-time = "2024-04-16T21:28:15.614Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", size = 16234, upload-time = "2024-04-16T21:28:14.499Z" }, ] [[package]] name = "jaraco-classes" version = "3.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "more-itertools" }, ] sdist = { url = "https://files.pythonhosted.org/packages/06/c0/ed4a27bc5571b99e3cff68f8a9fa5b56ff7df1c2251cc715a652ddd26402/jaraco.classes-3.4.0.tar.gz", hash = "sha256:47a024b51d0239c0dd8c8540c6c7f484be3b8fcf0b2d85c13825780d3b3f3acd", size = 11780, upload-time = "2024-03-31T07:27:36.643Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/7f/66/b15ce62552d84bbfcec9a4873ab79d993a1dd4edb922cbfccae192bd5b5f/jaraco.classes-3.4.0-py3-none-any.whl", hash = "sha256:f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790", size = 6777, upload-time = "2024-03-31T07:27:34.792Z" }, ] [[package]] name = "jaraco-context" version = "6.1.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "backports-tarfile", marker = "python_full_version < '3.12'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/af/50/4763cd07e722bb6285316d390a164bc7e479db9d90daa769f22578f698b4/jaraco_context-6.1.2.tar.gz", hash = "sha256:f1a6c9d391e661cc5b8d39861ff077a7dc24dc23833ccee564b234b81c82dfe3", size = 16801, upload-time = "2026-03-20T22:13:33.922Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/f2/58/bc8954bda5fcda97bd7c19be11b85f91973d67a706ed4a3aec33e7de22db/jaraco_context-6.1.2-py3-none-any.whl", hash = "sha256:bf8150b79a2d5d91ae48629d8b427a8f7ba0e1097dd6202a9059f29a36379535", size = 7871, upload-time = "2026-03-20T22:13:32.808Z" }, ] [[package]] name = "jaraco-functools" version = "4.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "more-itertools" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0f/27/056e0638a86749374d6f57d0b0db39f29509cce9313cf91bdc0ac4d91084/jaraco_functools-4.4.0.tar.gz", hash = "sha256:da21933b0417b89515562656547a77b4931f98176eb173644c0d35032a33d6bb", size = 19943, upload-time = "2025-12-21T09:29:43.6Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/fd/c4/813bb09f0985cb21e959f21f2464169eca882656849adf727ac7bb7e1767/jaraco_functools-4.4.0-py3-none-any.whl", hash = "sha256:9eec1e36f45c818d9bf307c8948eb03b2b56cd44087b3cdc989abca1f20b9176", size = 10481, upload-time = "2025-12-21T09:29:42.27Z" }, ] [[package]] name = "jeepney" version = "0.9.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/7b/6f/357efd7602486741aa73ffc0617fb310a29b588ed0fd69c2399acbb85b0c/jeepney-0.9.0.tar.gz", hash = "sha256:cf0e9e845622b81e4a28df94c40345400256ec608d0e55bb8a3feaa9163f5732", size = 106758, upload-time = "2025-02-27T18:51:01.684Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b2/a3/e137168c9c44d18eff0376253da9f1e9234d0239e0ee230d2fee6cea8e55/jeepney-0.9.0-py3-none-any.whl", hash = "sha256:97e5714520c16fc0a45695e5365a2e11b81ea79bba796e26f9f1d178cb182683", size = 49010, upload-time = "2025-02-27T18:51:00.104Z" }, ] [[package]] name = "jinja2" version = "3.1.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, ] [[package]] name = "jsonschema" version = "4.26.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "attrs" }, { name = "jsonschema-specifications" }, { name = "referencing" }, { name = "rpds-py" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b3/fc/e067678238fa451312d4c62bf6e6cf5ec56375422aee02f9cb5f909b3047/jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326", size = 366583, upload-time = "2026-01-07T13:41:07.246Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce", size = 90630, upload-time = "2026-01-07T13:41:05.306Z" }, ] [[package]] name = "jsonschema-specifications" version = "2025.9.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "referencing" }, ] sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855, upload-time = "2025-09-08T01:34:59.186Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" }, ] [[package]] name = "keyring" version = "25.7.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "importlib-metadata", marker = "python_full_version < '3.12'" }, { name = "jaraco-classes" }, { name = "jaraco-context" }, { name = "jaraco-functools" }, { name = "jeepney", marker = "sys_platform == 'linux'" }, { name = "pywin32-ctypes", marker = "sys_platform == 'win32'" }, { name = "secretstorage", marker = "sys_platform == 'linux'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/43/4b/674af6ef2f97d56f0ab5153bf0bfa28ccb6c3ed4d1babf4305449668807b/keyring-25.7.0.tar.gz", hash = "sha256:fe01bd85eb3f8fb3dd0405defdeac9a5b4f6f0439edbb3149577f244a2e8245b", size = 63516, upload-time = "2025-11-16T16:26:09.482Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/81/db/e655086b7f3a705df045bf0933bdd9c2f79bb3c97bfef1384598bb79a217/keyring-25.7.0-py3-none-any.whl", hash = "sha256:be4a0b195f149690c166e850609a477c532ddbfbaed96a404d4e43f8d5e2689f", size = 39160, upload-time = "2025-11-16T16:26:08.402Z" }, ] [[package]] name = "librt" version = "0.16.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/04/f5/9dc696772d241814bacac7880bac32f2930b5a6ebc1f85317b83161a011c/librt-0.16.0.tar.gz", hash = "sha256:ac38d6d8d66bf3d744148dbbc0b8e193e195a51e364ed55e224631f5721891fc", size = 219839, upload-time = "2026-09-29T00:55:32.891Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ba/0e/b04fd2d76b6a78a02286938251b2c119fb36ddece92c76cb4886ef7d44b8/librt-0.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fe4372c52d4849096c6cc1cda2817d293ec51440c890474ed59ef38d46556f18", size = 148058, upload-time = "2026-09-29T00:44:40.903Z" }, { url = "https://files.pythonhosted.org/packages/a3/fc/e1ed24aadb32d38603c0c07f579d739eb4d90e64e90d525b024e4a999b4d/librt-0.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c72c5295a84bd249526da9bdca38f2e176d15c31c13bb0063c5053f4ca023421", size = 153073, upload-time = "2026-09-29T00:44:42.165Z" }, { url = "https://files.pythonhosted.org/packages/be/38/133ab655409420e0c34a9a9836a7f4e5ae75fba758d7fe177099130d58ba/librt-0.16.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:be56ba9c884143495b517f23fe794ae367d58cd89ea0fdd6d437e3c024a87f9f", size = 493052, upload-time = "2026-09-29T00:44:44.043Z" }, { url = "https://files.pythonhosted.org/packages/94/42/aaa663bc9421f5bf7bbbe9d3316d7219749698ec7688ac3b519770a89c04/librt-0.16.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:ef46c1a29ffb8c72e882e22618ec618778eacd0578fb22c6e7cf9c11d15f357b", size = 485506, upload-time = "2026-09-29T00:44:45.479Z" }, { url = "https://files.pythonhosted.org/packages/7b/59/83a6eb5087ba8b45b083859e2085256963e06d4c2531944cdd962670bfb5/librt-0.16.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d3c94211ee0c4f8d649ec06b7c115c0ec4eadb873a0e3154ca15cef3f814b071", size = 498708, upload-time = "2026-09-29T00:44:46.916Z" }, { url = "https://files.pythonhosted.org/packages/a0/e4/15a8d62b2bc12935080ec7277e2e0b9b233047781eb784a51d3e25af669a/librt-0.16.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:94aed6a8308818b91677957d1bd03188869cd7aeb23c5dba7912a6c0402f7602", size = 515981, upload-time = "2026-09-29T00:44:48.316Z" }, { url = "https://files.pythonhosted.org/packages/46/4f/287cc282ac5dd815204c0779e79401bb0a568c3a1335fb319bf0838fb566/librt-0.16.0-cp311-cp311-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:349c0bcb87ebd07481b6ff781e25cdc699723dbe2212e57dabb27f7a13b7b87d", size = 508670, upload-time = "2026-09-29T00:44:49.726Z" }, { url = "https://files.pythonhosted.org/packages/bf/5b/ab7292add898ade0d2b5b75d32a923aae315861671aa5c39f5491309f7ae/librt-0.16.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:001bfd59a7d45b17e3e75f2a8c6405280b35e7b84471792778e718c4f368950e", size = 530393, upload-time = "2026-09-29T00:44:51.356Z" }, { url = "https://files.pythonhosted.org/packages/7a/9e/8e6bcf027d4bcbc16a4e864b3d158a1d3e5f55ffa53af0238020cad89271/librt-0.16.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:28e038895b998d7a0c7798922ce8a1dc157675df5cf1c9ef0aca809ed804b7a1", size = 534302, upload-time = "2026-09-29T00:44:52.893Z" }, { url = "https://files.pythonhosted.org/packages/96/a4/8c5ab4f3b3a8e905ff8305d76976a2e666f52fe049edd398aed2402beb36/librt-0.16.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:0dbe4096a7ecc00fa835d24510ad8545a4efef738dac96e0e63516783ccde905", size = 536150, upload-time = "2026-09-29T00:44:54.421Z" }, { url = "https://files.pythonhosted.org/packages/ea/5e/7c4bc267e3cd4b8bd288de9f62d61fff203829c9cc649ea2aa12e9218cf0/librt-0.16.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:5cd5b092441053364af968ea12084692cb9d4a22f3ce9524e377880bf028761e", size = 514316, upload-time = "2026-09-29T00:44:55.998Z" }, { url = "https://files.pythonhosted.org/packages/e0/75/c8bc6b50f43c73819334233f5a3259c81216742cef56d2140c3dd377c3f0/librt-0.16.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3ddeb3c9dedb461bb457c6c7d9aa7fbf35329da313d1a7543d00c8d0f3473c96", size = 557731, upload-time = "2026-09-29T00:44:57.581Z" }, { url = "https://files.pythonhosted.org/packages/93/fb/e241f91bc8de6c7ac1c6a20ea6dd381bc52312b44d711ffcd97140db1e57/librt-0.16.0-cp311-cp311-win32.whl", hash = "sha256:e05108e0849966f53a8d2d3112a7af881d0efaa479bc735bba91108f9f2350a7", size = 104922, upload-time = "2026-09-29T00:44:59.078Z" }, { url = "https://files.pythonhosted.org/packages/d1/38/c892383d2bb1a6a80b2ec8ede84970a265a792c56614a06282bf3008517c/librt-0.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:5f49cff01bd608ef7d97104cb035c75455e79c2d70bf4a506cf773338ac1860d", size = 125093, upload-time = "2026-09-29T00:49:01.621Z" }, { url = "https://files.pythonhosted.org/packages/e4/56/8bbde1ed0b21480163617648f638fdaec9374cf5e9c846ebcee34ec02a42/librt-0.16.0-cp311-cp311-win_arm64.whl", hash = "sha256:1d28ae980ae2218f9c5b95d191e947296f918c9bf0b400d467a9430275bbe678", size = 115910, upload-time = "2026-09-29T00:52:40.131Z" }, { url = "https://files.pythonhosted.org/packages/ad/76/bbdaeb87b7c47b5c7343e90222b9bfa4e4a8a83f647e02933ad0129225b1/librt-0.16.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fe52bf4641069e7978a14253b036cb9002def1926317e710f2e249f8a8c47742", size = 151028, upload-time = "2026-09-29T00:52:41.508Z" }, { url = "https://files.pythonhosted.org/packages/fd/0c/ab8ed3dab0085931aec4a792c7eaac8dc6c5ff4691fda3a5360d9d8a9cd2/librt-0.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5bcc2c4726ced915b00de0c9856a4eeabfb3fddb93e10e0b8f735b7709358b6d", size = 155283, upload-time = "2026-09-29T00:52:42.873Z" }, { url = "https://files.pythonhosted.org/packages/eb/36/494e79d460c80c1f030661e8287c9eca5e1ad652dc2b2180b6cd42abce0a/librt-0.16.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff7baa55f8e7c69851419e50a666015d02a74198716fd45c0125a2112e0a389f", size = 503185, upload-time = "2026-09-29T00:52:44.638Z" }, { url = "https://files.pythonhosted.org/packages/9b/34/a8464038dd9db6e4381fa2b6eb73dc9a50888d77102c4c139304ac35cddc/librt-0.16.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:b95d5d92ab83d39e760a52091bb1baba664f3a2351e39b1e16801e5747c2f0e9", size = 496738, upload-time = "2026-09-29T00:52:46.441Z" }, { url = "https://files.pythonhosted.org/packages/6a/53/e0e5e334ef0c6ed27039d323819368b9ef6712be87d55ee2bf9799398afd/librt-0.16.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b6d085d70bce51d43c5c7c36d63490770180d8779e71c49305c87b4213918de7", size = 513818, upload-time = "2026-09-29T00:52:48.068Z" }, { url = "https://files.pythonhosted.org/packages/ad/f7/7ce72cbf19d0addd05090b339152fd0548a02562c2866a603e6e3b3da2df/librt-0.16.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:36e53948e99bbe3ffea257124cfcae1cfb01831555c9a9c903c9f9a72db7fd07", size = 531952, upload-time = "2026-09-29T00:52:49.816Z" }, { url = "https://files.pythonhosted.org/packages/83/22/0b1bcb6a8e723c8b4fd60dfc8ae8ec6461c54073fbc8685efeb8d900d407/librt-0.16.0-cp312-cp312-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:54d11f726aae9df5a6ffbbf0a03a52449bbac84a53ef03669cb41cdfd4ae41bf", size = 524465, upload-time = "2026-09-29T00:52:51.354Z" }, { url = "https://files.pythonhosted.org/packages/64/2e/e9c23b8b9df1813da1be205deca9606beb7ddd033972246cd426d05374a0/librt-0.16.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4323193ac0cd025f85af531df8ba91bf24d1973b401697347a6282e8fd3fcf5e", size = 543191, upload-time = "2026-09-29T00:52:53.284Z" }, { url = "https://files.pythonhosted.org/packages/bc/e5/6a8b21b342c03ed7e230fa3afbfd2edc58e6e87ef1f0d11fa2b9a748c252/librt-0.16.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e42f8e098b9c5396fefa05fb1cc7e33b0e08fc51da106b5de4a45fd22aac6743", size = 546979, upload-time = "2026-09-29T00:52:54.932Z" }, { url = "https://files.pythonhosted.org/packages/84/9e/b5129023eced1be01e01c22757f53be551d463b1bb7264f787927404c1d6/librt-0.16.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:39ec1d5a14e37baf1450a6cabf03fe552340808bf1ad9d71824ab90117716459", size = 555317, upload-time = "2026-09-29T00:52:56.869Z" }, { url = "https://files.pythonhosted.org/packages/71/89/28bba5938c725fe91f06bf93f7fa6c6b150229df53a87b454b0d5c2a796e/librt-0.16.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d1aabe3925cbb4a08d15b7b20ba4011b53019da0c4173a25155139b7b1baed65", size = 535846, upload-time = "2026-09-29T00:52:58.475Z" }, { url = "https://files.pythonhosted.org/packages/22/92/63773026614f888c5d4e370e395ce42ca604b89f70b3acdfedbf94851b80/librt-0.16.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:300c3ffdc459f4a779a8411ecb188e3ac0b1ff3a3a7b099642555dedae06c69b", size = 573700, upload-time = "2026-09-29T00:53:00.127Z" }, { url = "https://files.pythonhosted.org/packages/66/8f/347d4677eefb57cd9f8e01d95a1dcee9a91b4e44e664173c32ff6f3752e5/librt-0.16.0-cp312-cp312-win32.whl", hash = "sha256:c17194318e4c0c0348b36f36c2ec7534436fe0a4c15582403162a4f08c80797a", size = 106158, upload-time = "2026-09-29T00:53:02.031Z" }, { url = "https://files.pythonhosted.org/packages/f0/2c/5193dc81127cd5ddfad031391b046bf32dda219b38463ab872407ca30646/librt-0.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:25a58a19ea8d83b68209f04912df765e9260635ef77646542ed4b4abe6bc7940", size = 126176, upload-time = "2026-09-29T00:53:03.445Z" }, { url = "https://files.pythonhosted.org/packages/ff/3d/9668a400c8dd81d162eba38b33fa49fa6205f1a64493570a13fbb815c3ee/librt-0.16.0-cp312-cp312-win_arm64.whl", hash = "sha256:f7be7cf555bc30ec12622e9447299cc4a9b8ff307548b634794353db0c2065dc", size = 116572, upload-time = "2026-09-29T00:53:04.815Z" }, { url = "https://files.pythonhosted.org/packages/46/cd/ae5e0e9dba45d1399aa04a5395bcc0bead40d9fa06dc903634a7b4d7473d/librt-0.16.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c5e6144e68b577f157519f2ba88ca20e3ed61c29b00e5cdfa76cd2d45acf059a", size = 151036, upload-time = "2026-09-29T00:53:06.284Z" }, { url = "https://files.pythonhosted.org/packages/41/5a/48a16e323c5f9447a94cce7b59babf60fa04e62c3365ecf060c77ed8b320/librt-0.16.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:33f41443a1f4e1f099331b3d8120e409fbff84b9760bc1cc9ea496f37ddaa5cc", size = 155211, upload-time = "2026-09-29T00:53:07.72Z" }, { url = "https://files.pythonhosted.org/packages/3f/29/0f59299eb4251a409b2e690ad4b7d9f8a676db829d7817ec961f32b44f7e/librt-0.16.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7e510b7770bee609617a3374a96548eb114cae048023e3f049ee449e7ff2db32", size = 502587, upload-time = "2026-09-29T00:53:09.191Z" }, { url = "https://files.pythonhosted.org/packages/de/ba/d6fb4ef8d1537c396079d72289f16be7cd35a366e5065c51253fea2760b6/librt-0.16.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:efc49c462d4516b8a58b00b490078fa64689fd1fe66970cc190131d7afb8027e", size = 496146, upload-time = "2026-09-29T00:53:11.016Z" }, { url = "https://files.pythonhosted.org/packages/52/fc/8c50dd4d7cc97c0ee8f252c8a3104980f234391cf1519b554e8b9de08b60/librt-0.16.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:92caf82ebef5e12d21c72242b70d1e92536f1711cf2a727a4c276de4b4469087", size = 513336, upload-time = "2026-09-29T00:53:12.655Z" }, { url = "https://files.pythonhosted.org/packages/a9/59/16c409c56f708eda2db9a0553662845d45e3871c77d70a240dae3f3bdc56/librt-0.16.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:17bac7f7a16b328fff77e440287693eb017abde913595b5827ebccbc21ecd8a6", size = 531689, upload-time = "2026-09-29T00:53:14.39Z" }, { url = "https://files.pythonhosted.org/packages/88/82/d34772a6c29d1446dcca6e64d74062efd508523ab351aa16625a4689d5cc/librt-0.16.0-cp313-cp313-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5b976054553670829985ed767feb78fb6bcede0175327c4844dd5c281c1be659", size = 524537, upload-time = "2026-09-29T00:53:16.064Z" }, { url = "https://files.pythonhosted.org/packages/77/8f/24c5631313746131ccee53bc91fdc8374f9cf25e0082a1fee9c93bb98acc/librt-0.16.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0058f9d68721094105917254c72ac0569117bb7b13b9769cf45d26d89f9d21cd", size = 543231, upload-time = "2026-09-29T00:53:17.939Z" }, { url = "https://files.pythonhosted.org/packages/f2/cb/5f8e0d41dbd8b499c2265e939c31acc9ba59845565bf99539ad1c06aebcf/librt-0.16.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:30b7beaf3f4487b7d8adef1f158b49067cb4d5a19fa7a3bf31a4e7a820e435c5", size = 546499, upload-time = "2026-09-29T00:53:19.666Z" }, { url = "https://files.pythonhosted.org/packages/be/61/063052de441d1385f59cea4223f184bf9e5d125de1ae3239b490aa1e486e/librt-0.16.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:468df902df016a06eb0e40b0747dc8d14e47d7a38b18b63b1fb167d85cb94d63", size = 555261, upload-time = "2026-09-29T00:53:21.292Z" }, { url = "https://files.pythonhosted.org/packages/14/11/a2ada0529372268d6401afa9d457a095b68cd7753532b6f7f33049a19b43/librt-0.16.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:aea7b1f2b125dad5de85f049136651bff256c883c65e6b9209b2da0a1ac3cdef", size = 536029, upload-time = "2026-09-29T00:53:23.07Z" }, { url = "https://files.pythonhosted.org/packages/23/9d/5bb6d38853382986dca702fc7e06c8256d30f5fa0676d882773b744610dc/librt-0.16.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a8afb6557920860b7a3a596eb804cf37e09e7cf8a803db2478c202acc72d8c2e", size = 573748, upload-time = "2026-09-29T00:53:24.696Z" }, { url = "https://files.pythonhosted.org/packages/99/f6/0025cde35ff7f607684dc775a2b2d732cce2561cec050a6ee1fb2e1fc6fe/librt-0.16.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl", hash = "sha256:77c7a2b4fe2c1369e0d5aa1cade26740a7b14be32fbc9a5535d617d20065c39d", size = 79861, upload-time = "2026-09-29T00:53:26.089Z" }, { url = "https://files.pythonhosted.org/packages/93/93/303b8592909bd583f83f02818ffbea3f7647ca1e22b1cd5465d04b8145fe/librt-0.16.0-cp313-cp313-win32.whl", hash = "sha256:02d89c813d5ff74b17df72d3a34819d132cd168e56b81bf755b809bd9e46b8c4", size = 106236, upload-time = "2026-09-29T00:53:27.43Z" }, { url = "https://files.pythonhosted.org/packages/cf/24/80bbb463c60ed18e29cb26aba386ddb76609580e4e7160710e550587018c/librt-0.16.0-cp313-cp313-win_amd64.whl", hash = "sha256:14ed6ebe3e4f85f326d7920011ad30ff49ed9334e62cf88caef9ba973d9e3a92", size = 126180, upload-time = "2026-09-29T00:53:28.7Z" }, { url = "https://files.pythonhosted.org/packages/43/80/b1a6fbdd7da825cdd55c71aa81eb6cfa82c513c360774152eacb50b4a771/librt-0.16.0-cp313-cp313-win_arm64.whl", hash = "sha256:83d4041a3d9b2fd053a8a4e1f22878b3e5833e2712956382d5c048d791454e91", size = 116557, upload-time = "2026-09-29T00:53:30.012Z" }, { url = "https://files.pythonhosted.org/packages/1e/93/9e0cf7da129a93c3dc7f45bc3cd4a660f2aaa995aa8a6f95c2583ef41239/librt-0.16.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:931a0bb0fcac88f263e269e46eb30ba8e21402cd3c62ca40cb97034c0693fab1", size = 149844, upload-time = "2026-09-29T00:53:31.391Z" }, { url = "https://files.pythonhosted.org/packages/8f/26/8a90d2a8f2b2e471bb486b7aec117b8ae622715ed6c39853aec48ea20073/librt-0.16.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1bc17e54e5305f8d40b7ca203671ff5a9e59c1d0f8ea0f625dcca53a3984de11", size = 154111, upload-time = "2026-09-29T00:53:32.718Z" }, { url = "https://files.pythonhosted.org/packages/35/ce/67abb46258da4d3e42ff5b141db6f38c59357bef84c7979f183b22f924f1/librt-0.16.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:877698bf6bca5721d8be345f2fe09778e40ecadea8b58c73075f2b1a53666bf2", size = 494234, upload-time = "2026-09-29T00:53:34.466Z" }, { url = "https://files.pythonhosted.org/packages/12/f9/ea7162414a16f8f1bbd3b493ad6d22b926c5471916e078350bdbca8c4e5f/librt-0.16.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:5981c011b306781ce561e18e14230a14524a3d8109b97553666c942c18f31a96", size = 491173, upload-time = "2026-09-29T00:53:36.124Z" }, { url = "https://files.pythonhosted.org/packages/b1/09/9b3e869060dd33f9989b80ba4fea306f6db8cecefcdfe6d7346ef0603f65/librt-0.16.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:afced3dfc17cd805ecf7a3d77996a71cf5f2c75aa66eb0c21a9930f4fc992f86", size = 505547, upload-time = "2026-09-29T00:53:37.686Z" }, { url = "https://files.pythonhosted.org/packages/50/07/79007d2165f649ea93e08c0962d1d62c70af9cde77965255095bf9d96f9a/librt-0.16.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ca8052401c55d7511dda6760719fda7618067e83535d7d0010096d216c34b667", size = 523057, upload-time = "2026-09-29T00:53:39.301Z" }, { url = "https://files.pythonhosted.org/packages/61/0c/8fbaff66d0ba376d8864653f5acce1569bae27e89648671f26f7eca67ab8/librt-0.16.0-cp314-cp314-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1e511762a074005bb0aa569166779834e75e438370226930d0ce1866d4b6a33b", size = 515158, upload-time = "2026-09-29T00:53:41.012Z" }, { url = "https://files.pythonhosted.org/packages/df/2e/23ff0dece76f07a4124413a57682efa0bbeb5765ac0122bc0955513f82ca/librt-0.16.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f1e8591bd8a5a628cd7f07954c6a1592359a878bf032957a8e9057a41d644311", size = 534183, upload-time = "2026-09-29T00:53:42.451Z" }, { url = "https://files.pythonhosted.org/packages/26/c4/e11dea21d9a29486eba78887380374189d472734fa32cc50cb37ca44d3d0/librt-0.16.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:a4aaefb4ba6c07e1aeebb2795c8958148f1d6f9af3b555b53d23d766edb6d67a", size = 540663, upload-time = "2026-09-29T00:53:44.272Z" }, { url = "https://files.pythonhosted.org/packages/44/75/e873ae158a8b7f5359be33e7fd6c1fbe02d9a78a3e89a77de6b0e837f476/librt-0.16.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:d92db7a0f6aee44f1baee94750457e8d2d1c6ccea41842de6268d34e8dc7eddd", size = 545908, upload-time = "2026-09-29T00:53:45.812Z" }, { url = "https://files.pythonhosted.org/packages/ba/36/8939d3f6a93e11bd9592e6fe28d2b44f1c2dc4bed6e22e72359a91e18ffb/librt-0.16.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:378dfaffb38e59c24a87cde5713cd865d51ff7383fa12947f3907f306ea1ca55", size = 523302, upload-time = "2026-09-29T00:53:47.596Z" }, { url = "https://files.pythonhosted.org/packages/71/14/35309f44a077f0f42ade0e2e7cd88c0cea760c661af205c01ea90d3c0e1f/librt-0.16.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3e0c39bdc85370422e8b637be76eb1fd07d30967551b03e62267dd156f553152", size = 565911, upload-time = "2026-09-29T00:53:49.278Z" }, { url = "https://files.pythonhosted.org/packages/78/0c/df6255b94967f3159ebc46f08d8e783c12da6ee269ddb74b2efed63c640c/librt-0.16.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:1b384b90ab79a7bc30b566895809a636e0666f21f3cf12b54823d025b7e83839", size = 79119, upload-time = "2026-09-29T00:53:50.938Z" }, { url = "https://files.pythonhosted.org/packages/6b/44/d30d5a5461378c9d33f36736c6791c3b4c4ba4b1ffe0da7350aedcb2c9a0/librt-0.16.0-cp314-cp314-win32.whl", hash = "sha256:52327da75a94012e7f932f913d20d3876bed3c102be00e6c3e8600ff7bdd58a7", size = 100140, upload-time = "2026-09-29T00:53:52.205Z" }, { url = "https://files.pythonhosted.org/packages/c2/98/769712f356a1e897df3581bb0c3100375d054a000de26099360ea65b5111/librt-0.16.0-cp314-cp314-win_amd64.whl", hash = "sha256:3f0b8114c44b2ac06ff5dacd08e07e8e807ff4f46083f2a1602685122559be41", size = 120464, upload-time = "2026-09-29T00:53:53.495Z" }, { url = "https://files.pythonhosted.org/packages/bf/d3/ae2abccc8bdc8b063c1613a77686e17b74e9d3d60cfe6f12c63fa2821b9f/librt-0.16.0-cp314-cp314-win_arm64.whl", hash = "sha256:8caf96a4ef8fb27d0ac0d1ad8337d26a240acd4a02fe4345d0a8f264753e8f99", size = 110889, upload-time = "2026-09-29T00:53:54.817Z" }, { url = "https://files.pythonhosted.org/packages/e4/26/0737d4be058dd6376eade7dd8b380d4b869b6394cee929393a5a431c45bb/librt-0.16.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:953107e2f68d0f3512c48f898b0dbf0ce5cc52bba0f318d847c985dc555ee4cc", size = 159838, upload-time = "2026-09-29T00:53:56.22Z" }, { url = "https://files.pythonhosted.org/packages/01/96/9bc96531d7c620e9949af904470f02e3fa8f35129ab8e8f281c51eaa3788/librt-0.16.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ad37d5b9abd49c9a655dcda7ea52a8a752884062ef1ee71ae17c2f2a0f81fe6a", size = 162018, upload-time = "2026-09-29T00:53:57.532Z" }, { url = "https://files.pythonhosted.org/packages/0e/fa/b0289dcb186eb3f97221ba00da5f4bd3ba7fa5e99752d48aa8d336615334/librt-0.16.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2c4aa329c17bd1aaea4f6e89335d8ccd494b3a5830b6654462273e50e11023f0", size = 703983, upload-time = "2026-09-29T00:53:59.024Z" }, { url = "https://files.pythonhosted.org/packages/d9/ab/05ebbbde7530fc5eeb58fbd1581522a9f64f132fa703c4c595eed6e14760/librt-0.16.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:0ead24d2562a49473dddd9efef8581f020007eb0054389c3ee3ffad38b1ca4c9", size = 683847, upload-time = "2026-09-29T00:54:00.671Z" }, { url = "https://files.pythonhosted.org/packages/a3/75/f52aeecd4dbadbddf80725ba7de126d8bd5d0eb66247eae17a81ed90dd4d/librt-0.16.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:02118f56a9c36ddd07dfd9b919d9ecc117ba20a90987d56aa4c429fa34509188", size = 698045, upload-time = "2026-09-29T00:54:02.247Z" }, { url = "https://files.pythonhosted.org/packages/e6/55/fa277a835cd6eb42380591ceb85f48c5b4d2b2d7e2cb9869e1e17d24d237/librt-0.16.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4e29522c62e28595ff7e324c6834ade51127707f0e255b18d1c1cf03d39c1048", size = 724640, upload-time = "2026-09-29T00:54:04.078Z" }, { url = "https://files.pythonhosted.org/packages/25/e4/2cf64354f3fde8ebd591b3b48f96510bee24ac5f7d1e567adbbe210abdbd/librt-0.16.0-cp314-cp314t-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3ff4b2367926b69c6215635902cccb04048e73094e9862900d27cb2c6bbff143", size = 731748, upload-time = "2026-09-29T00:54:05.741Z" }, { url = "https://files.pythonhosted.org/packages/f8/c9/c180af3e94e01aa529fa93d7733fec2abc47f222345400cf21d5481d5f8a/librt-0.16.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c6f1b27bf1632a7e016af9f145f82be95e1edd7721a646505c21059257cb5a04", size = 754960, upload-time = "2026-09-29T00:54:07.38Z" }, { url = "https://files.pythonhosted.org/packages/95/d6/01073aa78c58f356b10d9c57b3fe9abb143df338142bcd316df417b89db0/librt-0.16.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:5696d7f52e7b37217cb3a8f92c744fe835942602fdd4c1a8bc4741d3bfdce15e", size = 747000, upload-time = "2026-09-29T00:54:09.06Z" }, { url = "https://files.pythonhosted.org/packages/f7/d8/1de3783908658d697a8cfc00582f61299ffba7796d7260c112e4700b1109/librt-0.16.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:6072e92dd876ff6ceeb6cf371e35e51f479349837391341f479b08df4564242b", size = 749569, upload-time = "2026-09-29T00:54:10.702Z" }, { url = "https://files.pythonhosted.org/packages/b7/32/e817f66c96d6caa8bb8435ff93c4c220624d59efc506be59ab98fcd01d0c/librt-0.16.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:39ca4f2f2fe05de8e63493da592d84311adabe5bef52b193851981da9816b302", size = 729483, upload-time = "2026-09-29T00:54:12.25Z" }, { url = "https://files.pythonhosted.org/packages/7c/c9/23992ccd2b9d22798fdd0f61353183a47414e651da782ad83eb680f50833/librt-0.16.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f9807485a908f00355820f18e91e045ffdcdc5adb68aaec40a1e2b88c5f7bba1", size = 776584, upload-time = "2026-09-29T00:54:13.837Z" }, { url = "https://files.pythonhosted.org/packages/67/3b/e8af957f08e6e2e8e566b099e43d2748418aa565df6ee1d9d3331209fdfe/librt-0.16.0-cp314-cp314t-win32.whl", hash = "sha256:94be5cb7bca4df6201f4183e9e4fa2086c655283d20b38cd84500a69057575a7", size = 104402, upload-time = "2026-09-29T00:54:15.568Z" }, { url = "https://files.pythonhosted.org/packages/ca/1c/946e6443d7cd32347a086043395e421e52fd603c9163d2ec970ceab8eed6/librt-0.16.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d46ca272b251d033dd4527b0dec5f261a28a52bd5fa0f99c117b0a1f8588cc2d", size = 126227, upload-time = "2026-09-29T00:54:17.165Z" }, { url = "https://files.pythonhosted.org/packages/c2/a3/bc4f9959d3c62bcbf9e5fd3470a8bbd8bf33224ed4c25d7fba173201b8ac/librt-0.16.0-cp314-cp314t-win_arm64.whl", hash = "sha256:b9d6d4b14e92d876f8026b54c20c445f36425214c1081dc76f74e40db386b82b", size = 116493, upload-time = "2026-09-29T00:54:18.567Z" }, { url = "https://files.pythonhosted.org/packages/b6/4b/10fdb42dfab4c1533e1570e686b18e86ff4328b406361b39fb3016667638/librt-0.16.0-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:6fe436af2eaf630474f491af5d032cbe45f93fcff5c3b9fe4ab194a7255b20ff", size = 149829, upload-time = "2026-09-29T00:54:19.933Z" }, { url = "https://files.pythonhosted.org/packages/8e/30/a90ca13f1d3d91af1680000a4038536907018fbd51764767287a05d28b8b/librt-0.16.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:8ff5d26c529336be9bd7ae04483235d77778ee7d6444a95353102b542601ce81", size = 154522, upload-time = "2026-09-29T00:54:21.306Z" }, { url = "https://files.pythonhosted.org/packages/5c/dd/bcf364eacfa070bb1fc88d503111ae7177914197ba1fa717c748926e7930/librt-0.16.0-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:909d8e3c1faee44cb762b1c519ff8613dcc5ceae5c99987a00917b5a31fd1d6a", size = 497593, upload-time = "2026-09-29T00:54:22.798Z" }, { url = "https://files.pythonhosted.org/packages/18/c1/2c4e81e347bdabfe8346bfc6dc37ae5e154d61c88e30848ec0606025a5e0/librt-0.16.0-cp315-cp315-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:6d4a64283ee61824b5790de882bc68e2d9d7a5143537cb7a966f7354f71646d4", size = 480459, upload-time = "2026-09-29T00:54:24.364Z" }, { url = "https://files.pythonhosted.org/packages/ab/d7/fef2a3cb8400701be496f6e459876f650b3451f407e30cb243de571ae615/librt-0.16.0-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5810ba811297fdf37a1531a57667cb8ace0842013ca8606bf9eb7c24cf4be154", size = 507814, upload-time = "2026-09-29T00:54:25.997Z" }, { url = "https://files.pythonhosted.org/packages/e1/6f/53762927a32e9dc9eb1d1c1f3528da281290c86d96929a8af652f671266e/librt-0.16.0-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e56aaf8c167548dc8e5d6f3bd0f48dcdd299a23c73be3f744aab79d99e9c7f5d", size = 525114, upload-time = "2026-09-29T00:54:27.747Z" }, { url = "https://files.pythonhosted.org/packages/6c/67/0b9d031f303c4e8c691a9a8ef9d272f13b530c11cc563b819df621b6a348/librt-0.16.0-cp315-cp315-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8f36c58e33b304b525c6c9c5076399c6ebf1109e17b9051a05a407b091b9215b", size = 520465, upload-time = "2026-09-29T00:54:29.331Z" }, { url = "https://files.pythonhosted.org/packages/ae/d5/2056a3a85864e882eb17a203a10ddb26fa748bc9718ec67e79059ab46cae/librt-0.16.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:242e00b3d4fa37c3d3c1ca5f5c9adb7d909ddb1eac9c41f2787320d00caa0af2", size = 537257, upload-time = "2026-09-29T00:54:30.915Z" }, { url = "https://files.pythonhosted.org/packages/54/57/e0d79790c163cbc0909e209a6f62e30bb713b647f905a176cdc64848fd4d/librt-0.16.0-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:0253721561787b8df8443eb347b7a6461015354e5bdd37ee38a41fef220d2bb0", size = 527442, upload-time = "2026-09-29T00:54:32.478Z" }, { url = "https://files.pythonhosted.org/packages/aa/50/1c0c95aba7af51f4752ea34fbf2eb79b36e7cae3a72536248e8c735de735/librt-0.16.0-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:3e483a8d69ede8067db70c0e83007423b6925de6fd53afed01d66160f2e9398c", size = 548139, upload-time = "2026-09-29T00:54:34.183Z" }, { url = "https://files.pythonhosted.org/packages/98/91/a8a43dd5138d4f55f88846b8f0c85454a4fad69952cebfcff9948f831290/librt-0.16.0-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:69ba927445cfaaffb4081003ef5224c55a5c2ab67ef956f416ef744916e44121", size = 529708, upload-time = "2026-09-29T00:54:35.761Z" }, { url = "https://files.pythonhosted.org/packages/2d/41/d5226881ab2b7c20d9d587b37bdd4a0ec8775a96d00ca87ac9f385587db4/librt-0.16.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:d6a365f2ab45a984d0e00eee0dd17f599ceab8cadab6ea07b6111c8132fc0e42", size = 567781, upload-time = "2026-09-29T00:54:37.409Z" }, { url = "https://files.pythonhosted.org/packages/bb/bf/2345ba57a626e8c78c4ddcc724636a8df5a593fe46c1ee76bbf477e32b0d/librt-0.16.0-cp315-cp315-pyemscripten_2026_5_wasm32.whl", hash = "sha256:f01f3805f2dae4781c0c34b440e31740d082950bdaf89a6f601ad589a28af57a", size = 79177, upload-time = "2026-09-29T00:54:38.792Z" }, { url = "https://files.pythonhosted.org/packages/1e/40/99e77936cc9207f629b077bf7cbc5e2f0827cddd7c29792f04ef881bd2c3/librt-0.16.0-cp315-cp315-win32.whl", hash = "sha256:b0e3e721c75d2e79a76d4422c79d7ba705fe1bbafec907037fe7a657a480a0e3", size = 100127, upload-time = "2026-09-29T00:54:40.251Z" }, { url = "https://files.pythonhosted.org/packages/56/1e/801fe26bc622061b9dfd010e166d94142cb774b733217e6d98d1c0cf2638/librt-0.16.0-cp315-cp315-win_amd64.whl", hash = "sha256:bc02954b1295de798bbdb0b4e2d8a28c2117de8b5c73dcbeb27dc32572dfb971", size = 120480, upload-time = "2026-09-29T00:54:41.722Z" }, { url = "https://files.pythonhosted.org/packages/bb/a9/d533983055bd36e112627384c2c038845d1df882540b8bcefb566475640b/librt-0.16.0-cp315-cp315-win_arm64.whl", hash = "sha256:c5db585d43449a5f54303d4b2774e45e1babd975cfe1630a3d708c0b80c3e560", size = 110915, upload-time = "2026-09-29T00:54:43.052Z" }, { url = "https://files.pythonhosted.org/packages/55/fe/d62238fa9c653b0e0613290349467cb65711b5800e8e474f45e942a0ad95/librt-0.16.0-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:f06c689cb14afd9b612727553a5ec5a40febf113ca41c4413a2b0b334285884b", size = 159714, upload-time = "2026-09-29T00:54:44.497Z" }, { url = "https://files.pythonhosted.org/packages/f3/ac/f31efe7818700be72ba4f9af8a80fa67c39808c8d26dacc55dc1f6f35172/librt-0.16.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:13b4e8aba90b0b1c82474e9844aa9ffe7ad3faa484350e1da64cb8188d903134", size = 162086, upload-time = "2026-09-29T00:54:45.968Z" }, { url = "https://files.pythonhosted.org/packages/d9/16/4d7487bf86a9d7e8e18f37ba5538789233ea693637379b75701bd35ec9de/librt-0.16.0-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5a269c46ae327d8e6f8c1f85f7516cb52c0fa48127565a1105a4f4a05ff2a0b4", size = 712727, upload-time = "2026-09-29T00:54:47.486Z" }, { url = "https://files.pythonhosted.org/packages/77/74/50cd550ccc1a517b9ed62347625c01ddf8c4afad66490312677c011458f6/librt-0.16.0-cp315-cp315t-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:a33e0dae1f8592146a4764d54ce842b278732d21a84e17c3bbe6b1bc158a2248", size = 681106, upload-time = "2026-09-29T00:54:49.126Z" }, { url = "https://files.pythonhosted.org/packages/df/5d/7293f712975ee6fdd2251411fd9ef1c62bc99c7b83ecbe62dbc999b1fab7/librt-0.16.0-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:47ada6ea32636492c61aa8ad27ae3b9404bfe7a97e3ba946d1984236cc741da0", size = 705921, upload-time = "2026-09-29T00:54:50.905Z" }, { url = "https://files.pythonhosted.org/packages/67/f7/8aab946f11d59d1bece9ffc65d994b200c789a8ca5a95c17e17e609f912a/librt-0.16.0-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c43bd6e642d8a248c114327f98dd25ac5a7cb5aa168ef02f0559b91874df16b8", size = 731786, upload-time = "2026-09-29T00:54:52.584Z" }, { url = "https://files.pythonhosted.org/packages/43/76/1c42ab31e7cb8384ebf6d3af607213c495222474f4940443ae7639ab7685/librt-0.16.0-cp315-cp315t-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c3d1bb7841a816ace6449bb26d3f9560dbfa20e71c568d23f0f62bf1e68f50b1", size = 744964, upload-time = "2026-09-29T00:54:54.217Z" }, { url = "https://files.pythonhosted.org/packages/6f/2e/4b19982d933d2dfced671e840b219e4c1cd3f507df6e6dabb51bbd4e3850/librt-0.16.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:3931f7a3db322e7f44e02a280e3949326ce9579ad388ee8d691dc7c76da9fb70", size = 765305, upload-time = "2026-09-29T00:54:55.815Z" }, { url = "https://files.pythonhosted.org/packages/b8/1b/e872583de2dcb3ac7746e7a2321aeeb168274f3952a87dc66e05ddb29faf/librt-0.16.0-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:f4462528b6000afe8f16907b5c7c2553abf1df005ba5140e6eb394541c3624c3", size = 744959, upload-time = "2026-09-29T00:54:57.532Z" }, { url = "https://files.pythonhosted.org/packages/10/de/a18c6bcfb297af2674233e90b3c3661c3a0af0f1434a0c966d2ef708a835/librt-0.16.0-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:80039ba9b6a7d5f1a0175a4cca6bbefead87bd854c80abad1cb30afe47a830db", size = 758138, upload-time = "2026-09-29T00:54:59.484Z" }, { url = "https://files.pythonhosted.org/packages/22/1c/0df1d732539c297bb1a093e1fe3204d2faf76a9022cf4e1d1c2fce059790/librt-0.16.0-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:7a1d272724b581bb6bc769dfdafed6da2ecc9886ba2450311de55a4ac2e1e9cd", size = 744268, upload-time = "2026-09-29T00:55:01.179Z" }, { url = "https://files.pythonhosted.org/packages/a2/f7/ccaf31331f20c91a5bd9bd48ffc3f743f9c81bb5720cc7b2a720ca204f0a/librt-0.16.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:fbe4fb8c5445f7496d7f7f6bb0807875d09d47e6771ffa175fb2df2895fb86ba", size = 785783, upload-time = "2026-09-29T00:55:02.938Z" }, { url = "https://files.pythonhosted.org/packages/c1/ea/7421d9e6db894cd6cd788b604b3394a163ded6b942052b6f96c23ccf08e1/librt-0.16.0-cp315-cp315t-win32.whl", hash = "sha256:375bfe6b572a8f6cfc398709356046173bf27e64c4c5edaf5f7062f051fb4bf9", size = 104355, upload-time = "2026-09-29T00:55:04.533Z" }, { url = "https://files.pythonhosted.org/packages/85/6d/7c31a506eb847bc58aeb2402d58e17605e821f68ab5df5e66fe274a6df41/librt-0.16.0-cp315-cp315t-win_amd64.whl", hash = "sha256:bd3150023d3dc2bc70f3784e59ffa1140d56ddba3d8125b3d6f9f85221279bfc", size = 126134, upload-time = "2026-09-29T00:55:06.017Z" }, { url = "https://files.pythonhosted.org/packages/36/69/7a5d10ac409c4da0355e054a14371871da9b5557fcc42772cd00181c6cce/librt-0.16.0-cp315-cp315t-win_arm64.whl", hash = "sha256:8ceafb70f2a4f0826f11031942e59c0728fd98da112dc346d4352bde1e486866", size = 116391, upload-time = "2026-09-29T00:55:07.484Z" }, ] [[package]] name = "markdown" version = "3.10.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/2b/f4/69fa6ed85ae003c2378ffa8f6d2e3234662abd02c10d216c0ba96081a238/markdown-3.10.2.tar.gz", hash = "sha256:994d51325d25ad8aa7ce4ebaec003febcce822c3f8c911e3b17c52f7f589f950", size = 368805, upload-time = "2026-02-09T14:57:26.942Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl", hash = "sha256:e91464b71ae3ee7afd3017d9f358ef0baf158fd9a298db92f1d4761133824c36", size = 108180, upload-time = "2026-02-09T14:57:25.787Z" }, ] [[package]] name = "markdown-it-py" version = "4.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mdurl" }, ] sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, ] [[package]] name = "markupsafe" version = "3.0.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/38/9b/e422a865e1d5d57d0e509b4e0bf1c1a70a7f6382c29a5aa428df994c8bc8/markupsafe-3.0.4.tar.gz", hash = "sha256:2e9ad7dd851bf45fab9f75cbff4cb493fee9979e8d8c7c9c3ee119022518edd6", size = 153777, upload-time = "2026-10-02T23:07:22.29Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/32/55/18dbb4778b30ada5ce071608503cc3edc9e14e13d868c17a6d178fc30f7a/markupsafe-3.0.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9e25feb9e330b63edb0278a0acdf85e50d0cb0fbf49c3084abbe4e24ae195346", size = 11520, upload-time = "2026-10-02T23:04:36.299Z" }, { url = "https://files.pythonhosted.org/packages/6c/14/0b05f79b4733e264a18d08fe08fa1df7347630ff32a6cb82180d9dccec55/markupsafe-3.0.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7d3391b2188d18737cb2fa147028b1096236eaa7e156446c650a489fa2cadc91", size = 12063, upload-time = "2026-10-02T23:04:37.291Z" }, { url = "https://files.pythonhosted.org/packages/ca/3a/63ba10b6c1463216b3e4df669a9f0e5a3b0c3071557d2e8229e3968c79fb/markupsafe-3.0.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:849dd2bb0e5e4ab2b71c7191726a4a8d5aa8a610daa584728cbee0b710ddc4ef", size = 24321, upload-time = "2026-10-02T23:04:38.262Z" }, { url = "https://files.pythonhosted.org/packages/1a/2e/5f015261b76ad633d187ef6f388b413aedd64a8773c4df59e530a0be5525/markupsafe-3.0.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:befb4158af32106b9a93db8d6d1d1cbbd418c0d5aca0cabb7b1780abf0c89169", size = 28845, upload-time = "2026-10-02T23:04:39.295Z" }, { url = "https://files.pythonhosted.org/packages/33/cf/26e594b26be40c2f1fec63ccf8a8b99d0335a5b2cbe84835c7d82a994375/markupsafe-3.0.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:71f88e749ea29f67f21f3b36433c1dc54c7729ed2a6d9e2da2e0d9e0d7b224eb", size = 24701, upload-time = "2026-10-02T23:04:40.348Z" }, { url = "https://files.pythonhosted.org/packages/81/a5/a513b76c139a3915b43404324e55c0b7979ae4f0d39eb6f075b0282e90a8/markupsafe-3.0.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6da83a088f8ef93b2d483a8232a4dbf4d69d3d8496b568a03c56becac43e1808", size = 22961, upload-time = "2026-10-02T23:04:41.372Z" }, { url = "https://files.pythonhosted.org/packages/46/cf/4c66192c100b4542bcbe392ae06696b670f66927be3ac38a213234778ff9/markupsafe-3.0.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8f0fac8b13d14bb06c68195f849371924ae53dd7b1c00fed24650f704383b692", size = 21920, upload-time = "2026-10-02T23:04:42.429Z" }, { url = "https://files.pythonhosted.org/packages/cb/17/ac3662678bfbad649893117ada2ba44dc30bf56884e84f13154a792b10f1/markupsafe-3.0.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4a7cdc2a420ca01058182da4253329764d4bfa055564d1eced90e6ba1e8b1d3d", size = 23726, upload-time = "2026-10-02T23:04:43.531Z" }, { url = "https://files.pythonhosted.org/packages/f7/af/fe47cee339180a69ebca3c57fb3483d0f5cbd1e8337d1871fb1d9c1aebee/markupsafe-3.0.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:83b3944fea42a8400edf92fd1770fb8d0d4f7de651353bd2d8525a92dba69a21", size = 22539, upload-time = "2026-10-02T23:04:44.618Z" }, { url = "https://files.pythonhosted.org/packages/12/32/d55440ba140442800e02d799c9cb5ab597bf6ebdb1177b5ea39a11f797bd/markupsafe-3.0.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:8138eb83940ec7299024d92d4dee45f601b9e6c5ffde9d25f4e35e326203c707", size = 23963, upload-time = "2026-10-02T23:04:45.656Z" }, { url = "https://files.pythonhosted.org/packages/50/9d/9c86042cb364c2ad4c971e6d1247929effd25f714cd7ee11b05e6316445b/markupsafe-3.0.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:811d02d5122171c1941357efd8f9bf4ffe907b7f0a1a4e729a880e4be3f46e3e", size = 21506, upload-time = "2026-10-02T23:04:46.671Z" }, { url = "https://files.pythonhosted.org/packages/75/ef/5b824f03ba40c3b3652b6272d083d2fc4fcdd440de519a3a39ba2c3e7262/markupsafe-3.0.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:50b5bedc9ed8a94fc8857a42ef4f84a81ea88f8d4f05dc8705fb23ee6d8dcca7", size = 22955, upload-time = "2026-10-02T23:04:47.698Z" }, { url = "https://files.pythonhosted.org/packages/1e/e8/44cfcb5ea40e5e43cec7793ef90704ed0c475280839076c4345757eb8e59/markupsafe-3.0.4-cp311-cp311-win32.whl", hash = "sha256:2e5a7cd7fdd14fcb1ae5d7d8bf23d24fbd1daefd1fbca2580132e1ea75f098b5", size = 14094, upload-time = "2026-10-02T23:04:48.788Z" }, { url = "https://files.pythonhosted.org/packages/91/89/f2b509f7bf79352e40117824c1070dbeafd4df67031d3fa98165a3134228/markupsafe-3.0.4-cp311-cp311-win_amd64.whl", hash = "sha256:fdb4ca07ab75ffadab4a8b135ad59cdbb3156b99310f3d565370da74a15d6bd3", size = 14328, upload-time = "2026-10-02T23:04:49.801Z" }, { url = "https://files.pythonhosted.org/packages/2b/5a/ccf22672a0f64dc682306e288f0dabcb06c7a201f3bb6e6cbf86d9e8ad03/markupsafe-3.0.4-cp311-cp311-win_arm64.whl", hash = "sha256:569d65055d367e3dcdf30c3f41119467b73d9ee9faf332bdf40402644f5ac08e", size = 14188, upload-time = "2026-10-02T23:04:50.847Z" }, { url = "https://files.pythonhosted.org/packages/81/09/4c59d56b8461ae8eb0d8ba34bb25b7e618547044679d58a82ef9b2479fc1/markupsafe-3.0.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:61631e08084be9e21a8967ec3139c7616ed7c5e9368e05c86d1b39562c8a57b6", size = 11658, upload-time = "2026-10-02T23:04:51.876Z" }, { url = "https://files.pythonhosted.org/packages/a2/f0/d6613774d86fbf6d145751d43c59875e47a6f9f17daee0aef173bd36d90e/markupsafe-3.0.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0930db9bdc62d22944e10b066448bb65dc9abe9112880c7cab8da54db4284d5f", size = 12050, upload-time = "2026-10-02T23:04:52.931Z" }, { url = "https://files.pythonhosted.org/packages/0d/f2/8f18e0b806eb13c1f8d07d917a720831ead54253a6dec011fbc78098a6f8/markupsafe-3.0.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6a45c3d514f2436064db00d7fc8778d888f0236ebfed649b53d13a59e69ad51b", size = 24363, upload-time = "2026-10-02T23:04:53.895Z" }, { url = "https://files.pythonhosted.org/packages/60/ce/fa07dbe8a5675558fa36dea033e19995bc783de2dec5f540ccb9030b06aa/markupsafe-3.0.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1e1451fab512d1bcc3dc26988ec1edb0b82c2db909132872cd9356070a6b63df", size = 28525, upload-time = "2026-10-02T23:04:54.905Z" }, { url = "https://files.pythonhosted.org/packages/85/40/be87c01f3868ec217f8a2015089d71c22c8c5a75324822e5ed1cdd87210d/markupsafe-3.0.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bd3ce56ae2cbae3ba82b683bc425cd7e48d2ed8b10f3e818186b6f5646d9271c", size = 24733, upload-time = "2026-10-02T23:04:56.229Z" }, { url = "https://files.pythonhosted.org/packages/4f/a7/aeedb5140afa41fc74c225e9184ab96723a6e873b6ee1c9fede7283456d8/markupsafe-3.0.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e124f974786f831d6043728e38296969d3579db8896fe004682f5758e613581", size = 22985, upload-time = "2026-10-02T23:04:57.521Z" }, { url = "https://files.pythonhosted.org/packages/c3/fc/e91352bb08c6a59da3ef0909d457bf95a5f5908fbf151b30a06d9dbcfbb4/markupsafe-3.0.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c02e8f18bdedba082cef725942ac823b9b60656db07f7e265cb31618dfd00d77", size = 22001, upload-time = "2026-10-02T23:04:58.597Z" }, { url = "https://files.pythonhosted.org/packages/5d/f8/bffee5e7d2a3deb59748a797650a48af7e672025cf641a79344a771ad106/markupsafe-3.0.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9f098115c247e11d138ab83a28fa0323c77015007ea2df73ba5fd714dfefd67c", size = 23793, upload-time = "2026-10-02T23:04:59.686Z" }, { url = "https://files.pythonhosted.org/packages/ed/59/b853d6628ecb4d658e1d637224846d5e9bb4adf4f8df97f3be9f29dce2ec/markupsafe-3.0.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d5f93ebbeb8032d47e349328ec8662d973d9b05a70b3c35df1f91fe419b84749", size = 22640, upload-time = "2026-10-02T23:05:00.768Z" }, { url = "https://files.pythonhosted.org/packages/09/b2/1506df394f0f075797c418d0301498f49e43be194e3ffcb49e6fe6ccf022/markupsafe-3.0.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:64511c54db4e4987aef4c41923235927428729e8174c5dba488429be70a998ed", size = 24074, upload-time = "2026-10-02T23:05:01.813Z" }, { url = "https://files.pythonhosted.org/packages/c7/81/5ed69cda630ac69ef60d06c09ba5a7f84ff66a2e28cf986fd5614ab3c6e6/markupsafe-3.0.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:e1a622f13970d81f95d0c72f9dc090dce9085fccfa4c9f2174377ee32bd15786", size = 21563, upload-time = "2026-10-02T23:05:03.239Z" }, { url = "https://files.pythonhosted.org/packages/0c/fe/fb1e79be0fea60aa32602ebefc9c35a82bb42b4df157285ab7dfec12341a/markupsafe-3.0.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c9a7f43c0b202b334cc9184af09bb8f21d3a209e038efaf106936fb69e6b026e", size = 23048, upload-time = "2026-10-02T23:05:04.479Z" }, { url = "https://files.pythonhosted.org/packages/c8/52/7632a53360671a9b750cdbabaf9cdd89f18b42248b8e4cb42c0b0296e459/markupsafe-3.0.4-cp312-cp312-win32.whl", hash = "sha256:f0ec3b750b59375eab5b0fb2b9254810c00a3375be6d789899f1055a1d556237", size = 14108, upload-time = "2026-10-02T23:05:05.513Z" }, { url = "https://files.pythonhosted.org/packages/3f/bf/62495e180b7000aaf30000fff849e933f74264638057176cf46852500adc/markupsafe-3.0.4-cp312-cp312-win_amd64.whl", hash = "sha256:11935df9bf455ed0c04eb87bcd720f02b1fe5e02128a9430f23aed6f93336fc7", size = 14303, upload-time = "2026-10-02T23:05:06.538Z" }, { url = "https://files.pythonhosted.org/packages/c5/8e/4c24208776a65878d656996945aacfbfe010d3720d1a98fc0eb8491fc03b/markupsafe-3.0.4-cp312-cp312-win_arm64.whl", hash = "sha256:a4bbd2d87dd233b9fc5812160c3d0ffbe42edc22a26ce0469f58479ede633fe9", size = 14174, upload-time = "2026-10-02T23:05:07.617Z" }, { url = "https://files.pythonhosted.org/packages/6d/18/4bc5ba32499e87bb2b0ef5b3a9bb9c00a131fa961ddf0be548cb550f548b/markupsafe-3.0.4-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:de8b364c423ef0a4bad9069657d617f9a5d2b2062457a89b1fa16ee199c399c1", size = 12786, upload-time = "2026-10-02T23:05:08.709Z" }, { url = "https://files.pythonhosted.org/packages/4e/6f/17f0c099bf25f3e31e63cc19244d9f6af861a9a4ab778c203997903cfdd0/markupsafe-3.0.4-cp313-cp313-android_24_x86_64.whl", hash = "sha256:34bdde374c5932765d7dc685c4a1d191a3207852d67e8e0a9eb6ea85156181f1", size = 12510, upload-time = "2026-10-02T23:05:09.93Z" }, { url = "https://files.pythonhosted.org/packages/11/af/1a141081b905036ee904ec4bd945e1f70b4e1b32d33c4e59e8cf1d58b247/markupsafe-3.0.4-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:6bd9e1788e15bfcf6a9082de42e30387e7b85d211ab21e57a939bb8cfaaf8d96", size = 11583, upload-time = "2026-10-02T23:05:10.884Z" }, { url = "https://files.pythonhosted.org/packages/e7/0a/a89385ae590232622a03e091805cff12f24fabe6c11e0e8bae096cece81c/markupsafe-3.0.4-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:5066b244f576f91afc8ee3ba029a89f99d39c79b1853fe9d39bea9f0afbec148", size = 11801, upload-time = "2026-10-02T23:05:11.913Z" }, { url = "https://files.pythonhosted.org/packages/ed/85/ea548dc013962eb73653124bc595635fbf9e0fa41d1f181a967ccb784dfb/markupsafe-3.0.4-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7a83aa6e4805df46fed18e989d3d16f86ef60cb50bbc8d9ce3a6be89165fbf6e", size = 11443, upload-time = "2026-10-02T23:05:12.887Z" }, { url = "https://files.pythonhosted.org/packages/cc/72/15f2e5ec9cf2eb00d5cdfe968d94e4156a7bd7303832c3f3b2c403a36839/markupsafe-3.0.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2d1b7d9308288661f56672b1b157d75fc536714d3638487bbea17b6318a78248", size = 11665, upload-time = "2026-10-02T23:05:13.829Z" }, { url = "https://files.pythonhosted.org/packages/ca/e0/4030bea613677e333c8a2c901fd405055f657f9d06acba5b7357984b6ef7/markupsafe-3.0.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:73e77980c7207854f00fc4e71fb1626868d5740ab4012623d55c7a99ad122a72", size = 12061, upload-time = "2026-10-02T23:05:14.807Z" }, { url = "https://files.pythonhosted.org/packages/f3/a5/28b76a7449eb702966b88bef599e2360b411fbb3afeee8fe560939be06ec/markupsafe-3.0.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7018d4af1cd272e847aa5917983ab5e83e4f6579f9dbfecd4a79c0ca80b144c2", size = 24395, upload-time = "2026-10-02T23:05:15.909Z" }, { url = "https://files.pythonhosted.org/packages/07/6c/21232811afc3a063b5e934b1ae2efda52f46154ec382f585149c020e61fe/markupsafe-3.0.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c90d5b3d4e944e065a301d741b3c1d784f6bd1f503aa68b4967e32b2ba313d85", size = 27183, upload-time = "2026-10-02T23:05:16.976Z" }, { url = "https://files.pythonhosted.org/packages/14/38/6ccdfa5b59049cb36fb80cbc80aee9cf1fc9bb77d1335ad435f2070b08cf/markupsafe-3.0.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:18a801868a884f216e784d7d14db2a4077143ce7610440aee2ce8f734e7cfcde", size = 24772, upload-time = "2026-10-02T23:05:18.209Z" }, { url = "https://files.pythonhosted.org/packages/63/e0/cec6865dfe88cb48fedd4b20aed6af5158e41092adcbf3e028bcc6ec2108/markupsafe-3.0.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:434139499bb20b502ed3baa1f169e618f924a97e7a777fea1a49446d80106cf6", size = 23017, upload-time = "2026-10-02T23:05:19.286Z" }, { url = "https://files.pythonhosted.org/packages/ee/76/6ed4940bb7648a9aac457c14f870cfdd5105f139a0fb1f29cd61fafa47d1/markupsafe-3.0.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9e227f3dbe6bde7491cf0a9965d00b88c6b1a4a95d11480ddf88bb96d397c19f", size = 22036, upload-time = "2026-10-02T23:05:20.352Z" }, { url = "https://files.pythonhosted.org/packages/a1/4f/ed476226d4fe46a09090a36025bf319296810028df55eb12f1253b540f3a/markupsafe-3.0.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b8cd1f918b26fd7b1832ece557cc18f2d8747309ff8b3f0ef9d4250c5ad67a39", size = 23786, upload-time = "2026-10-02T23:05:21.576Z" }, { url = "https://files.pythonhosted.org/packages/9a/35/66ff30450e35ef5fba9ebc930c9411747e537fd9447b65e44f5007e2b84d/markupsafe-3.0.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:a5fcffb37e602b0b3c1638a97746b9b96125caa9bcf6fa41d337a9261de231ee", size = 22672, upload-time = "2026-10-02T23:05:22.922Z" }, { url = "https://files.pythonhosted.org/packages/32/0b/72f45ce4b4efcbca4b80cf1b06703eff0be8d37e82abb78f66c85a7ead1e/markupsafe-3.0.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:5989cb26b2e1efc6a42216a9f6b5ee495ce5ace2e5b352a9af489976b32d1ee2", size = 24107, upload-time = "2026-10-02T23:05:24.175Z" }, { url = "https://files.pythonhosted.org/packages/d2/03/71776e5fdcba04614b384cc102e8a4198208579d896fd1394cb7cb9aa900/markupsafe-3.0.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:add96447a86d205ab616665d53b2950ee81083757f56e6ea833c8b2917646b46", size = 21615, upload-time = "2026-10-02T23:05:25.215Z" }, { url = "https://files.pythonhosted.org/packages/ab/5f/801ce02a02e7aee0f784b1ec7843026178f6adeb9c93ac67eb1992a9a84d/markupsafe-3.0.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2628d3a8cb648ecebb3c5d6b0a1052d400e4d8b7ac0fb786be8d285b50040d17", size = 23076, upload-time = "2026-10-02T23:05:26.423Z" }, { url = "https://files.pythonhosted.org/packages/4a/85/c43776625428f3bb4a61e8633940400e3efe6409e3c6f5bff26de5e45618/markupsafe-3.0.4-cp313-cp313-win32.whl", hash = "sha256:672d207103e6b16ca098611b0f9efad6bc00afd47c03d6ef62186495ca677dc0", size = 14118, upload-time = "2026-10-02T23:05:27.716Z" }, { url = "https://files.pythonhosted.org/packages/6f/36/163da64de88a13db79214ef75fa041be7fa13bdb42261cf5b7484de14bfb/markupsafe-3.0.4-cp313-cp313-win_amd64.whl", hash = "sha256:1f1f9477e174582b0a1b583d60b66e1f2cf5d3fe12cee985e4aedf44766600e5", size = 14313, upload-time = "2026-10-02T23:05:28.749Z" }, { url = "https://files.pythonhosted.org/packages/9f/a8/9b662783ffaa1149221432a923cee562f78b9cbbb8baa3df9b3753e63e1e/markupsafe-3.0.4-cp313-cp313-win_arm64.whl", hash = "sha256:06de8ef6331f6e822c28d577dc8bf43fe398800477c49498f38fc38b67ff33fc", size = 14189, upload-time = "2026-10-02T23:05:29.917Z" }, { url = "https://files.pythonhosted.org/packages/5c/c3/a944f3b0df22bd129e96915b9f4e98d2eeca6516687d7618304a966c3c74/markupsafe-3.0.4-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:4ed644d75aa94a2baf7ec3a96eaa160ea58c742eb9d27c6506053c5c40fc84ed", size = 12787, upload-time = "2026-10-02T23:05:30.971Z" }, { url = "https://files.pythonhosted.org/packages/d4/d6/a44863f69d88b6c7e27889108f70d47aed259edf89d5df3c5fca1eac87d6/markupsafe-3.0.4-cp314-cp314-android_24_x86_64.whl", hash = "sha256:6d2a9efe686f9de00d0d1ea32a4a5a86d558a2277501bd78d964214eab625e59", size = 12525, upload-time = "2026-10-02T23:05:32.263Z" }, { url = "https://files.pythonhosted.org/packages/17/8f/168ba80e532dd6a93f96f8f706f1ad41d7990b6e1aeedc1cc0d211a33497/markupsafe-3.0.4-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:8781a792a070cf2bd1b86d3aa943894115faaba6e88122a7bf32d62072742453", size = 11589, upload-time = "2026-10-02T23:05:33.251Z" }, { url = "https://files.pythonhosted.org/packages/32/b3/aa2c95a574d3af39403a469b295886eb9b6d448da568cbebb5a2cbfdc2e5/markupsafe-3.0.4-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:971a3bbb75d97ae4e2e8f7d4834236f86f85f0c85e04ab2e191db1123b04f80b", size = 11801, upload-time = "2026-10-02T23:05:34.315Z" }, { url = "https://files.pythonhosted.org/packages/60/d0/34b810107d83840e768bf485de795893ebbae35b26ab061b487adfa0a692/markupsafe-3.0.4-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:8909c2f1c6dd65e054ac4b573a91c8384d1492281e55d82d159d653f7a13adf6", size = 11447, upload-time = "2026-10-02T23:05:35.302Z" }, { url = "https://files.pythonhosted.org/packages/6c/ab/2f8488f0f817a39fca068d2b17daf446bf5cdb3eae28c3720af534d873b4/markupsafe-3.0.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:4cf3468d5ec187ffffcaca8e61929a37448f215dafc1386a12c750a72fe53634", size = 11722, upload-time = "2026-10-02T23:05:36.363Z" }, { url = "https://files.pythonhosted.org/packages/ad/40/e2d117b048d47282ade906fbfd92814cbee5647afc13fda88a3406039372/markupsafe-3.0.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:52704c5d36eb6dda8866493decd61111fff86244c9b1ad225ca01b9e91e5970f", size = 12061, upload-time = "2026-10-02T23:05:37.397Z" }, { url = "https://files.pythonhosted.org/packages/9a/a8/73a81135e85ba66217f5af7facb03bbb386807e1a729ab64532e4c802652/markupsafe-3.0.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1caa2fa5a6184fb233153b35f654e6687bd555476f6170f29d8ee9be1a8b0af9", size = 24434, upload-time = "2026-10-02T23:05:38.407Z" }, { url = "https://files.pythonhosted.org/packages/ac/ca/fa9216dd01efee2dfdacafe7df32b4d0170fbac694b0c258a193d6e53999/markupsafe-3.0.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:387d8cd30e69b3f0a72877b9ae717033396404e19095b17fe89753a981fda44f", size = 27183, upload-time = "2026-10-02T23:05:39.581Z" }, { url = "https://files.pythonhosted.org/packages/fa/4e/a469509e538d37af51103b17b073126973f2b1cbf197ff32c7ddf025cfe5/markupsafe-3.0.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:051417f74bcaaefa316276e0ff723f541616ca51043d070da00249d9bddd3e3c", size = 24813, upload-time = "2026-10-02T23:05:40.671Z" }, { url = "https://files.pythonhosted.org/packages/8f/db/d7282caf7ab03af44d5d6fdbaa019b35c7d7f1c90588b839c07cba640d6a/markupsafe-3.0.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8e9f292fcda89b324f2f5c91d13f1424a153e40fc2756f38ee23b15835ff300", size = 23049, upload-time = "2026-10-02T23:05:41.864Z" }, { url = "https://files.pythonhosted.org/packages/30/f3/b6a425206e6964efda6acee544d0eb01d1501784d0b8e2dcc74986f33b17/markupsafe-3.0.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:df1ae86ff54725a01fa1a0510b914ca53a161b7050be74f6204e24aded5971d0", size = 22088, upload-time = "2026-10-02T23:05:43.014Z" }, { url = "https://files.pythonhosted.org/packages/ea/8a/84d3582fc1f0d5bd466cdf2eebf175e172158a6e70701aacec1de1b35430/markupsafe-3.0.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8965520ac587c94a4ac48b729be3d8b8de00af39699b17585dfb599babe77977", size = 23846, upload-time = "2026-10-02T23:05:44.098Z" }, { url = "https://files.pythonhosted.org/packages/1c/65/db101cce51b7ba4864ac491a9859d297dd1adf0e55b103fee9db9c47c527/markupsafe-3.0.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:340cbb1957ba99929cbf19a75626d36ba1ae21d1730b287d1cf7f824a20c4fc7", size = 22674, upload-time = "2026-10-02T23:05:45.23Z" }, { url = "https://files.pythonhosted.org/packages/e0/49/ddee9813d71db0c7a5c9d97c832125e6758a0c844777f1cf076569bb0e22/markupsafe-3.0.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:3a93d9616ddecfb393727a0041a562cf0b15a244e20f2bd25efc7949be4c4f17", size = 24104, upload-time = "2026-10-02T23:05:46.398Z" }, { url = "https://files.pythonhosted.org/packages/aa/0e/7d8518d726726870a2399d69fd30d0fa36c5e57a2132c336b58d7c491073/markupsafe-3.0.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:d2e56fd3b00222722abfb3f5f0759ddbae4b90811b5ad4343c64030ad1bde70c", size = 21637, upload-time = "2026-10-02T23:05:47.48Z" }, { url = "https://files.pythonhosted.org/packages/b4/b0/b505e8a361ba557dbf3b3aa7331ea39b00d2022a26e925ff8463b9714bb3/markupsafe-3.0.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:0d9c47709875fdb321452056622e930c52afbc07a7d780762fbb8b4d91ce6fa4", size = 23081, upload-time = "2026-10-02T23:05:48.611Z" }, { url = "https://files.pythonhosted.org/packages/1c/ea/9cc3cea873f980c75cbdb6f4277ce30ee955de38be0b3d02f14c108e0698/markupsafe-3.0.4-cp314-cp314-win32.whl", hash = "sha256:38fc55594dab834470b6733dead2ee9e3f657fb0608c769dcafa0ba5ab52f45c", size = 14272, upload-time = "2026-10-02T23:05:49.707Z" }, { url = "https://files.pythonhosted.org/packages/80/f0/5792ff768a410f93ee3f84fc19345295ffc352d2c936b424cb37e514714c/markupsafe-3.0.4-cp314-cp314-win_amd64.whl", hash = "sha256:c1bc67752d5f21013cfe430df4062441714eab79f65a6a05e01505957e9c35fe", size = 14501, upload-time = "2026-10-02T23:05:50.788Z" }, { url = "https://files.pythonhosted.org/packages/5f/cf/3d074a8edffcc6899355232ff2543ae8d929733239596423b7db79698bc9/markupsafe-3.0.4-cp314-cp314-win_arm64.whl", hash = "sha256:7e1636da3d8dfc220b6dd10264db5f2b165e4888c4518594898fbe381049af8a", size = 14364, upload-time = "2026-10-02T23:05:51.857Z" }, { url = "https://files.pythonhosted.org/packages/d9/31/87ce42159aae2163cf3bbbd0c44bc87780510eecab1ea3859099aed95dcb/markupsafe-3.0.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:805c8b84534fa10891890f0e4be39f3a99e94615d93e8836bf9fa1fdca2feeb2", size = 11759, upload-time = "2026-10-02T23:05:52.951Z" }, { url = "https://files.pythonhosted.org/packages/5f/53/b047207eeb7752e960aca3eb1df5fb7eefa7dd4c62ac49bb156456c8a702/markupsafe-3.0.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:fa95848c929b6a75f6848d3c9793e59db365ee436776e57db835cdbfa79ba977", size = 12096, upload-time = "2026-10-02T23:05:54.066Z" }, { url = "https://files.pythonhosted.org/packages/ee/51/4326c88a13c7b755657d44b4bb986f8c3d9843ecba7e22d98661d87f9a57/markupsafe-3.0.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e916035e3e9930cbdfdd10abf48861340221857f45509565898e012263f7b289", size = 25699, upload-time = "2026-10-02T23:05:55.15Z" }, { url = "https://files.pythonhosted.org/packages/f2/bb/990581b7474bfcf2cf34bed6ba5ea23bd87adb9d671213d68e88620e7a6b/markupsafe-3.0.4-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b4d12837e0203bbace818ff4a7461afdcd78bcd782351cea148139180d7bcffe", size = 27804, upload-time = "2026-10-02T23:05:56.29Z" }, { url = "https://files.pythonhosted.org/packages/6b/89/89491878c28e8291f5aa2fffe2c2d57230d10ae366d55dd810b840513d78/markupsafe-3.0.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5086f9975abb1ab531ee6afca1761e4b59a19b446f3f6522ed776963228cfe5a", size = 25912, upload-time = "2026-10-02T23:05:57.416Z" }, { url = "https://files.pythonhosted.org/packages/30/77/680998b54efdea06fc114565cd739b6d059f826a0279219b218dfa750d29/markupsafe-3.0.4-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b4a635a0487774f841cb1fb62e907e7195cc95bc761e053184b8acc3ceb20733", size = 23623, upload-time = "2026-10-02T23:05:58.557Z" }, { url = "https://files.pythonhosted.org/packages/ae/75/2709f5ac5de9467b40b10e2bb8f89cc63dfb74582e09aa734b1124a217de/markupsafe-3.0.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb96e6e088d6cf71c1ea977510948320234824cf226e32f6f6e044f7a9c82b34", size = 23301, upload-time = "2026-10-02T23:05:59.94Z" }, { url = "https://files.pythonhosted.org/packages/a0/c8/39eadc6c5b14c9c7679bfb98f4d4c6a97863b5beb91839aca4d2d6e16e55/markupsafe-3.0.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8b5d563170ff8ba3181caa967c99a3c804d1dedb702c7cb93a6a7c32247da978", size = 24950, upload-time = "2026-10-02T23:06:01.289Z" }, { url = "https://files.pythonhosted.org/packages/1a/5e/01037f8a43e8ccb0bffb4fbdc5212db05bf080fdd7286cd392332d58128a/markupsafe-3.0.4-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:396ec4e65cc889f69786b3b89478b471cee5a3bcf468b9d9bb03e1a30fb291fc", size = 23330, upload-time = "2026-10-02T23:06:02.441Z" }, { url = "https://files.pythonhosted.org/packages/d4/f4/23e83ce0596bb0cbe670502d31df8f757bbd01a392aa486fa3b40d1ed399/markupsafe-3.0.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:15ba9e28640feef770374b116a6f019c21f52404aeabe516aa7f800587b98cfc", size = 25239, upload-time = "2026-10-02T23:06:03.579Z" }, { url = "https://files.pythonhosted.org/packages/88/5b/3708897368073cc683d524750474f41a77d2986152c380dcc55b20fdf340/markupsafe-3.0.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:d920abdfa61279ba1a2ef9484aab07bf03331f8c08a10120fa332353d06e6932", size = 22767, upload-time = "2026-10-02T23:06:04.699Z" }, { url = "https://files.pythonhosted.org/packages/c6/61/ebda1307864b409e6b3115757a3d4a09cca46cfb6cc65191b5de226b424b/markupsafe-3.0.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a9f54054101545a9a9cccefddf54316aa6e4491611fcbef9e91b3b6bebec04f6", size = 23668, upload-time = "2026-10-02T23:06:05.9Z" }, { url = "https://files.pythonhosted.org/packages/09/15/98075cceac3b5ba0dbb8e4762a847be967d2befc349a2cf2d0ac77f62c9d/markupsafe-3.0.4-cp314-cp314t-win32.whl", hash = "sha256:12a606a492de952afcb43b59a14aaaaad120e708d3663dd0fdf2d738d427a691", size = 14301, upload-time = "2026-10-02T23:06:07.109Z" }, { url = "https://files.pythonhosted.org/packages/0b/a3/768b560fcc4156685cb563d922b217810cfa7bc135773367f62f1f9d2078/markupsafe-3.0.4-cp314-cp314t-win_amd64.whl", hash = "sha256:a18f38cafc329bac5e3c2b96c765b4c96d3d103421ed22ab7988c1e3fce27464", size = 14526, upload-time = "2026-10-02T23:06:08.276Z" }, { url = "https://files.pythonhosted.org/packages/93/63/da554b4c97a6b0ea3229ca7fe8cbfb620be81613d517f482e85958550537/markupsafe-3.0.4-cp314-cp314t-win_arm64.whl", hash = "sha256:eba154571c16e032112afac0dc2dfe9e63c2ceb7aedd07bb7eecf2ce26d4dd4c", size = 14421, upload-time = "2026-10-02T23:06:09.402Z" }, { url = "https://files.pythonhosted.org/packages/a9/30/54d11c8ca027114898cab97421fb39e4ffd9ddf47cdbc44df2ec76722da9/markupsafe-3.0.4-cp315-cp315-android_24_arm64_v8a.whl", hash = "sha256:737c9c3981998eba27f11786f84fddcbabc74068b72a4a1f454ea02094b57b65", size = 12791, upload-time = "2026-10-02T23:06:10.485Z" }, { url = "https://files.pythonhosted.org/packages/10/6d/97c913e253a14bd3cd0e15a5c56d13203b823fa7ee32498342896a072dc4/markupsafe-3.0.4-cp315-cp315-android_24_x86_64.whl", hash = "sha256:489505b03f692c3f376394e49194fa7a7f9e8558d6e293a7056a0032b0c38163", size = 12527, upload-time = "2026-10-02T23:06:11.834Z" }, { url = "https://files.pythonhosted.org/packages/26/f9/b86d032042a4d597d9e1997f0e5f63a3eedaf11258e0a05760b0a0a826ea/markupsafe-3.0.4-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:077293e425f28ec737dbcad442a71752e28f8ae27cde3d68acd1fb212091cd92", size = 11602, upload-time = "2026-10-02T23:06:13.122Z" }, { url = "https://files.pythonhosted.org/packages/f2/dc/73c14c1eedf0ac5fa3292ba43435e6c49d2c2050f33cebde541f8f4807f1/markupsafe-3.0.4-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:9348cbb300d224fe3b89793262cb093504d4ae927004468463f745188a193e4a", size = 11817, upload-time = "2026-10-02T23:06:14.227Z" }, { url = "https://files.pythonhosted.org/packages/8f/69/2c2fcaa5fcee22d72c7819c0d536fd181c74a688e6143845419579cd2863/markupsafe-3.0.4-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:b807e598953730f82e4eae3bd30f6a122cf6b31c398c6b504c0e04c13c170429", size = 11446, upload-time = "2026-10-02T23:06:15.574Z" }, { url = "https://files.pythonhosted.org/packages/88/54/9e5ec76c62e6e2834d5a93623018c943e8b3bb41d663e3fd4c03303b9b85/markupsafe-3.0.4-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:799c39bdf5e2f1292fedd3009f7b3c9e760f10b2420cb9638d56920840ff6db8", size = 11719, upload-time = "2026-10-02T23:06:16.701Z" }, { url = "https://files.pythonhosted.org/packages/96/24/3ec292b44064c16229e064d770b2625bd8ea941aa61f44905a9fa44942c0/markupsafe-3.0.4-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:ae9dcb8fbe244cb82f8a6458b455b927a03685e383d9bacf1ea5ce180b96dc97", size = 12075, upload-time = "2026-10-02T23:06:17.855Z" }, { url = "https://files.pythonhosted.org/packages/aa/85/b64fdb1f304848518742136983c24e96d967bfb59a0ea160e92736901ab0/markupsafe-3.0.4-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4bced6e2a6dba6a28f7dd3c6ce14df1b2dd495923f16ea484cad03decd463b2b", size = 24656, upload-time = "2026-10-02T23:06:18.963Z" }, { url = "https://files.pythonhosted.org/packages/9c/18/23997d4c65b355da6390d61cd56e0ab3befd6ba8dda25cb40c602bd0fa6b/markupsafe-3.0.4-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3882fb412298575bae3b9c46868251f15cc69307359f87bb1b382e53d6e5a2c9", size = 27737, upload-time = "2026-10-02T23:06:20.117Z" }, { url = "https://files.pythonhosted.org/packages/d4/36/35998dead3c6af88c38265a56e58100211f036234ab88eb2283fd4cbce44/markupsafe-3.0.4-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:04e7902ba80ee4bac1d50a549606527a1dcf0476cd81403db41099d3b60ec653", size = 25003, upload-time = "2026-10-02T23:06:21.284Z" }, { url = "https://files.pythonhosted.org/packages/82/96/ef49135ce260db4ca4a12b119ed468449cd248db6b1468e2112b546d7a2e/markupsafe-3.0.4-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:925f929d6b59a8b3f8b8c6ac363cd0af7eecc81efb3071770b3c6717c450a369", size = 23111, upload-time = "2026-10-02T23:06:22.524Z" }, { url = "https://files.pythonhosted.org/packages/50/7d/83126e338bd88c17a220668235368ad719fd4638e426739858cbb8508f77/markupsafe-3.0.4-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f68edfc67aabac33708941f26f22a7b8e9f81429bc0cf249fcf7d66b23af8d19", size = 22403, upload-time = "2026-10-02T23:06:23.785Z" }, { url = "https://files.pythonhosted.org/packages/83/dd/daf7e420de23c8206c365204e7b85e1251d8e19d34196a56336f316e5ed2/markupsafe-3.0.4-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:e5c802729725bd07e2bc3ab7b76dc7e0bbfc53129d8f1eb1c002c24cf774717e", size = 24083, upload-time = "2026-10-02T23:06:25.037Z" }, { url = "https://files.pythonhosted.org/packages/19/3c/11eecdc06bc44ad5570350085b572ebf049e8f9a38d1ece6d76640b739cd/markupsafe-3.0.4-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:55ffd6ce583d97dc71dc92e930324c8c0d25aea7e3ade6ae54ef77cedb096811", size = 22931, upload-time = "2026-10-02T23:06:26.328Z" }, { url = "https://files.pythonhosted.org/packages/0d/9e/ac0fd77f2a726e56ecc3ca0235d095feace1358d1b822406c2a2ef26a4dc/markupsafe-3.0.4-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:2cb3dd71fc6be918ad4264346a8ed69485f9b7ed7bf35495d8e22807cd6b8bea", size = 24299, upload-time = "2026-10-02T23:06:27.742Z" }, { url = "https://files.pythonhosted.org/packages/d7/09/c6bd842ad58ff5b3bc76eeed7e9a42a6f11adc5d090ec697b72c9672731e/markupsafe-3.0.4-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:94f5407f7bc64fa6463906b896f9904beeeb7dd8dc116ee8e9056c8714ff9916", size = 21948, upload-time = "2026-10-02T23:06:29.274Z" }, { url = "https://files.pythonhosted.org/packages/a3/46/82f586711fed61e86faa1ee1bc317d68cd45a10c8bdbe3f7d1fdf9026ad8/markupsafe-3.0.4-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:2dad610540cb2e6272855c178f08ae9a1c7ac258a7fb71660553a5f104b42741", size = 23150, upload-time = "2026-10-02T23:06:30.583Z" }, { url = "https://files.pythonhosted.org/packages/19/2d/2dfdce99318abbfa26925195fbc17db188c46a1ec6457be121b6f9cfeb42/markupsafe-3.0.4-cp315-cp315-win32.whl", hash = "sha256:03470d1a8268e692ecf79ecd565593e59d44219377a7ead61f1f1b94c1f7ff6b", size = 14269, upload-time = "2026-10-02T23:06:31.949Z" }, { url = "https://files.pythonhosted.org/packages/5b/ec/6000fd82e8791e58fcd0456ec20f098957e2b03d5ed02eb73241a577c0ba/markupsafe-3.0.4-cp315-cp315-win_amd64.whl", hash = "sha256:d882a373d8093c2941e01291b7ced96e9cbe4781da9a7751ca7e6c70385e5214", size = 14496, upload-time = "2026-10-02T23:06:33.258Z" }, { url = "https://files.pythonhosted.org/packages/bc/66/e73bd5016421d5d6e2fb6de7dd609f9de020942ac8c626526bd8c6eeaf82/markupsafe-3.0.4-cp315-cp315-win_arm64.whl", hash = "sha256:353bd63081912ab8cfa6a0c7d185934cdf8426f04c618bba6bc4b394f2069b67", size = 14361, upload-time = "2026-10-02T23:06:34.539Z" }, { url = "https://files.pythonhosted.org/packages/90/df/cb8c3dc98d313a951df2f8968f44e4cb5643df6d3cab749a530ce2f7d972/markupsafe-3.0.4-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:c61750fadcd119d0825bcb7d7d675dd264dcc89cc05292aab5be68ebdbb374ad", size = 11760, upload-time = "2026-10-02T23:06:35.807Z" }, { url = "https://files.pythonhosted.org/packages/d6/bb/4af9b3ca0753d654ac75f9531d5bd741bb77ca6e696f36807c475ffc099a/markupsafe-3.0.4-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:1c0df495a977d10460a94941799c72d5b5ab03d3858d949b55b5a66c8f371c99", size = 12108, upload-time = "2026-10-02T23:06:37.089Z" }, { url = "https://files.pythonhosted.org/packages/3f/d4/b56429313aee5fd59b079c3df5615299959e25e7113eb6d8caadbdd7d38a/markupsafe-3.0.4-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:02fa4acbc6a3fc5c693c34d4dd8c1130b7fe99cc915181b0ddd6f72aeb296002", size = 25762, upload-time = "2026-10-02T23:06:38.419Z" }, { url = "https://files.pythonhosted.org/packages/65/f5/34c181e891aa4f7d59c918584672e0c5eb7fffe76c1387d1246008bf4081/markupsafe-3.0.4-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:05295589e619b9bed252a86b532b8e27350abc372d18ba89b59375325e91ec1e", size = 28400, upload-time = "2026-10-02T23:06:39.819Z" }, { url = "https://files.pythonhosted.org/packages/ce/b5/ad14694fd0ac9a5ce30bc6498f2999378f418583dd1679cca5a1b512957e/markupsafe-3.0.4-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:be6cb0c799abb0e2ba3e618e6d28ddddf7e485f6c2ce938dfa237daf3905072c", size = 25946, upload-time = "2026-10-02T23:06:41.381Z" }, { url = "https://files.pythonhosted.org/packages/d6/a8/26b606445387d0ceb1eb1f21840094b84e4e3c3c3983d80d10b89823b490/markupsafe-3.0.4-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:26e9867520db70d37f7fb421a7f0d8adb40171011fb84ce869afa1a83370dfa8", size = 23634, upload-time = "2026-10-02T23:06:42.748Z" }, { url = "https://files.pythonhosted.org/packages/39/a2/b8814de672f1f0094d498bf646f2fec9d6356b503d28ef500b71c5095377/markupsafe-3.0.4-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f03460ff076f70ab595bb45a0205ccea1971443575b6920c52e755dec2b3fbfe", size = 23488, upload-time = "2026-10-02T23:06:44.176Z" }, { url = "https://files.pythonhosted.org/packages/db/c7/287223376fb73335a3cc5d6eb22c6ab01358cf33945a9c39c06b9dac3f4b/markupsafe-3.0.4-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:436e3ffc6310d3c41878c601db29098102fe5d8a467c49da4a4125254e0980f2", size = 25037, upload-time = "2026-10-02T23:06:45.646Z" }, { url = "https://files.pythonhosted.org/packages/f9/29/4df8355e313426d19e62ba33e0253c009ca12a0894ee77d67fa67255361c/markupsafe-3.0.4-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:4e2c4809c14559aa7ef426f27fb35afbb38104c349a903bf8f3600456764bb38", size = 23543, upload-time = "2026-10-02T23:06:47.264Z" }, { url = "https://files.pythonhosted.org/packages/71/e5/8377731e8495668dcc768f645e717df18318c841edaf023a99395f6da9b4/markupsafe-3.0.4-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:da2af0d7aebfc2074080d72efa6ab8317c62481ef1f896f65d9999c1c01f4494", size = 25282, upload-time = "2026-10-02T23:06:48.795Z" }, { url = "https://files.pythonhosted.org/packages/ed/5f/373456e37ceb1478d657d6fe769cbe0a39f0a8dfc1548eeb19c471eefdd9/markupsafe-3.0.4-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:aa2c838cc024642cc04c6854232f32b43e5e22833dd11119c1766c7873b8370d", size = 22993, upload-time = "2026-10-02T23:06:50.31Z" }, { url = "https://files.pythonhosted.org/packages/d7/93/2cbd5628435afb6f541bbaced4bce0c2edac4b09a142e6e928b8b0da9858/markupsafe-3.0.4-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:b91cc9d336957239ff200f30097e6fea2dc6d6fb3c81e853eaa09eac904fd894", size = 23712, upload-time = "2026-10-02T23:06:51.759Z" }, { url = "https://files.pythonhosted.org/packages/81/99/157e10966b033b363aeda5263e82596ee232a0b1d082fdbf90aa417ff083/markupsafe-3.0.4-cp315-cp315t-win32.whl", hash = "sha256:e49fb0d1ce92cfa0cb198cc5b1b11cdf9d0638658e2a2db2687e39db7c87fc78", size = 14300, upload-time = "2026-10-02T23:06:53.241Z" }, { url = "https://files.pythonhosted.org/packages/33/05/55884815414c9706a23deca150b72c25a62109e65b0b6ce232077802c719/markupsafe-3.0.4-cp315-cp315t-win_amd64.whl", hash = "sha256:4f6e0852a0283b1b1fd776eeb7b766a5f440b3e2bd31ab51af3b400585f3965c", size = 14522, upload-time = "2026-10-02T23:06:54.729Z" }, { url = "https://files.pythonhosted.org/packages/92/f9/ecbde7149e95b8a0f18e16d5d747f7dc06049d5da2e4f77f6f5e4a1f46a8/markupsafe-3.0.4-cp315-cp315t-win_arm64.whl", hash = "sha256:39dbacefc411633db5b4378b066a9aca70a3d7e2922c9e578d825f844026eeba", size = 14417, upload-time = "2026-10-02T23:06:56.246Z" }, ] [[package]] name = "mdurl" version = "0.1.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, ] [[package]] name = "mergedeep" version = "1.3.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/3a/41/580bb4006e3ed0361b8151a01d324fb03f420815446c7def45d02f74c270/mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8", size = 4661, upload-time = "2021-02-05T18:55:30.623Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307", size = 6354, upload-time = "2021-02-05T18:55:29.583Z" }, ] [[package]] name = "mistune" version = "3.3.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/7b/92/328a294a6de83bacb95bed01f04e0eaff4e3616ee359fc821a5dfc539b02/mistune-3.3.4.tar.gz", hash = "sha256:58b5c96d6fcb61190dfe5fae498d2b2065f99cf61e9649418fd54cf1ada86dfe", size = 121426, upload-time = "2026-07-22T05:22:30.89Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/77/e4/288365afae98953bc01de09f686f40d8ee84578135aa7767d5d4e60b5278/mistune-3.3.4-py3-none-any.whl", hash = "sha256:ee015381e955e370962968befe1d729ab60fafb6a715ac6751763fbce38c8d4a", size = 66862, upload-time = "2026-07-22T05:22:29.419Z" }, ] [[package]] name = "mkdocs" version = "1.6.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "colorama", marker = "sys_platform == 'win32'" }, { name = "ghp-import" }, { name = "jinja2" }, { name = "markdown" }, { name = "markupsafe" }, { name = "mergedeep" }, { name = "mkdocs-get-deps" }, { name = "packaging" }, { name = "pathspec" }, { name = "pyyaml" }, { name = "pyyaml-env-tag" }, { name = "watchdog" }, ] sdist = { url = "https://files.pythonhosted.org/packages/bc/c6/bbd4f061bd16b378247f12953ffcb04786a618ce5e904b8c5a01a0309061/mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2", size = 3889159, upload-time = "2024-08-30T12:24:06.899Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e", size = 3864451, upload-time = "2024-08-30T12:24:05.054Z" }, ] [[package]] name = "mkdocs-autorefs" version = "1.4.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown" }, { name = "markupsafe" }, { name = "mkdocs" }, ] sdist = { url = "https://files.pythonhosted.org/packages/52/c0/f641843de3f612a6b48253f39244165acff36657a91cc903633d456ae1ac/mkdocs_autorefs-1.4.4.tar.gz", hash = "sha256:d54a284f27a7346b9c38f1f852177940c222da508e66edc816a0fa55fc6da197", size = 56588, upload-time = "2026-02-10T15:23:55.105Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl", hash = "sha256:834ef5408d827071ad1bc69e0f39704fa34c7fc05bc8e1c72b227dfdc5c76089", size = 25530, upload-time = "2026-02-10T15:23:53.817Z" }, ] [[package]] name = "mkdocs-get-deps" version = "0.2.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mergedeep" }, { name = "platformdirs" }, { name = "pyyaml" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ce/25/b3cccb187655b9393572bde9b09261d267c3bf2f2cdabe347673be5976a6/mkdocs_get_deps-0.2.2.tar.gz", hash = "sha256:8ee8d5f316cdbbb2834bc1df6e69c08fe769a83e040060de26d3c19fad3599a1", size = 11047, upload-time = "2026-03-10T02:46:33.632Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl", hash = "sha256:e7878cbeac04860b8b5e0ca31d3abad3df9411a75a32cde82f8e44b6c16ff650", size = 9555, upload-time = "2026-03-10T02:46:32.256Z" }, ] [[package]] name = "mkdocstrings" version = "1.0.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jinja2" }, { name = "markdown" }, { name = "markupsafe" }, { name = "mkdocs" }, { name = "mkdocs-autorefs" }, { name = "pymdown-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/53/71/f85bdf13355073ae15a7375f09879375a830553552e58c1c4b7e0bbc5c8b/mkdocstrings-1.0.6.tar.gz", hash = "sha256:a0b8c2bdd29a6416c80d717aa369bbf7831946bd9f23c2a66db1b1dbe7693dbd", size = 100649, upload-time = "2026-07-11T19:38:05.732Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/5d/5b/4c1902e8bdd5c4db63284e9d101dece4038d4025d6d88850ffe0a1578980/mkdocstrings-1.0.6-py3-none-any.whl", hash = "sha256:2703708697487d1b6d6d7b412e176fa436edf120c1bf81dc9e126b12d00893c7", size = 35787, upload-time = "2026-07-11T19:38:04.417Z" }, ] [package.optional-dependencies] python = [ { name = "mkdocstrings-python" }, ] [[package]] name = "mkdocstrings-python" version = "2.0.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "griffelib" }, { name = "mkdocs-autorefs" }, { name = "mkdocstrings" }, ] sdist = { url = "https://files.pythonhosted.org/packages/29/33/c225eaf898634bdda489a6766fc35d1683c640bffe0e0acd10646b13536d/mkdocstrings_python-2.0.3.tar.gz", hash = "sha256:c518632751cc869439b31c9d3177678ad2bfa5c21b79b863956ad68fc92c13b8", size = 199083, upload-time = "2026-02-20T10:38:36.368Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl", hash = "sha256:0b83513478bdfd803ff05aa43e9b1fca9dd22bcd9471f09ca6257f009bc5ee12", size = 104779, upload-time = "2026-02-20T10:38:34.517Z" }, ] [[package]] name = "more-itertools" version = "11.0.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/a2/f7/139d22fef48ac78127d18e01d80cf1be40236ae489769d17f35c3d425293/more_itertools-11.0.2.tar.gz", hash = "sha256:392a9e1e362cbc106a2457d37cabf9b36e5e12efd4ebff1654630e76597df804", size = 144659, upload-time = "2026-04-09T15:01:33.297Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/cb/98/6af411189d9413534c3eb691182bff1f5c6d44ed2f93f2edfe52a1bbceb8/more_itertools-11.0.2-py3-none-any.whl", hash = "sha256:6e35b35f818b01f691643c6c611bc0902f2e92b46c18fffa77ae1e7c46e912e4", size = 71939, upload-time = "2026-04-09T15:01:32.21Z" }, ] [[package]] name = "multidict" version = "6.9.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/d6/99/1d4d69c3512d0ddbfa3a1b69cfd9a151012ab2eb4eabbb096201b1f0b7d8/multidict-6.9.1.tar.gz", hash = "sha256:0f06e60fa190aa7abd0914c2a766736fdc8e9f34878c4346338534b73d1b20e2", size = 182404, upload-time = "2026-09-21T17:59:05.362Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/e3/24/3823efc330630a1f132bcd0a9b182ddec3c53f452f551c8e8d3aaf5a2d20/multidict-6.9.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:910d4260512660484c0dc1588a316fbb35a40c081c36fc51d1225351af17cfe4", size = 96739, upload-time = "2026-09-21T17:54:42.815Z" }, { url = "https://files.pythonhosted.org/packages/6a/69/36331fe1d3aeb0c525a9972d6cf82791075a395aa96f026f060009d691ae/multidict-6.9.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:33fa55b990f81c2927e01399ace0d18926c69d69baa8cdaa819424132fb97987", size = 58514, upload-time = "2026-09-21T17:54:44.064Z" }, { url = "https://files.pythonhosted.org/packages/8c/ca/5860651f782078ef13f2761c2593f4ba066d76f626b2f30f23a7f838b775/multidict-6.9.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:369b5aa01b241cd3fea6890bdbb11a1425d87bf1515831500d518f4223e9d72c", size = 57303, upload-time = "2026-09-21T17:54:45.304Z" }, { url = "https://files.pythonhosted.org/packages/c7/9f/c56e2fa223cb5d182660e1a09eec38880f96b7cd22769582f74447c60418/multidict-6.9.1-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:803f8b575a71b1b299d677c28db0653459c79b5308874efec813f17b7457c7f1", size = 320076, upload-time = "2026-09-21T17:54:46.826Z" }, { url = "https://files.pythonhosted.org/packages/59/97/eda4fe0cad51f96096363ed32d3e0f8df28dab00beff4d92adc9db517726/multidict-6.9.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b8a65621b98984a62e59403009591b8a5a7736273aefe1cab64cfb85b365cc07", size = 315489, upload-time = "2026-09-21T17:54:48.25Z" }, { url = "https://files.pythonhosted.org/packages/24/14/10b1ded0a4085a51c3054125f854da4f47ce4fec724a2d2503231b83f3db/multidict-6.9.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:13849a1d4f54c3809ae721e9e83ab28f5ea602f33660cb84eb6ef261eac706c1", size = 296716, upload-time = "2026-09-21T17:54:49.749Z" }, { url = "https://files.pythonhosted.org/packages/dc/14/04d155dd18528443cb9009f3a9f35f7417773797d072c95104ff17b8b9b7/multidict-6.9.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dd9a137a4a9becda3094f3831cd026380f75f6855e051eefe4c73ade524f1cc3", size = 330244, upload-time = "2026-09-21T17:54:51.26Z" }, { url = "https://files.pythonhosted.org/packages/8b/90/284d10b3a9e5b312a8ec5b7a175fc7d560eefdc99886320449891a197992/multidict-6.9.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9ae9614c317c50836689ce2dfde07c05fe0b16378562e2221746c3913ede3c80", size = 331288, upload-time = "2026-09-21T17:54:52.595Z" }, { url = "https://files.pythonhosted.org/packages/27/50/f420de3683f9b047fc5588064d84043ef57a7152ef451b8373dfc7068d22/multidict-6.9.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e8f1e362c9352b50ed120f001046fdbb80810c9d56580f4c3fc13bbe30823387", size = 320663, upload-time = "2026-09-21T17:54:53.91Z" }, { url = "https://files.pythonhosted.org/packages/01/ab/0120a650d7ce4fe167299c13a13cc4ee2dc72458a9c0e9e9330b824b73c9/multidict-6.9.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0dd655518f136febd96c05131a76a863e32fc2a1d7acd4e3c959e3ceb77d8345", size = 291139, upload-time = "2026-09-21T17:54:55.313Z" }, { url = "https://files.pythonhosted.org/packages/b3/3f/c66342f73ee5cd2c9b1dda6cfce89b5f348c48921b8c8b6e59aafbbfe31a/multidict-6.9.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2c5d675da8f1cb5650271c8ad5e95c0a3e5a183c105e72d953b12877b1c8d0fd", size = 310044, upload-time = "2026-09-21T17:54:56.745Z" }, { url = "https://files.pythonhosted.org/packages/05/0d/e44b90d9e77e44ec3473c4c7ac7ea95764d7e8fbf6d5a085ef9bff7ce0c2/multidict-6.9.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:658f90f49cf5af2441cad0a2b801c3ef520471989a1ec55bcb25b255b2ca8d2f", size = 303279, upload-time = "2026-09-21T17:54:58.178Z" }, { url = "https://files.pythonhosted.org/packages/97/8a/7741f7c23c211fae31ab546f0ba41569dae7671cf7ca30d5afb59e9d92aa/multidict-6.9.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:43124fe172ada86d03ac3c8dc8179091341f6724d5e5d5b160e1587e4cd3761b", size = 326177, upload-time = "2026-09-21T17:54:59.825Z" }, { url = "https://files.pythonhosted.org/packages/e8/63/0cdbfbbe36316b2ef4b8e011afaca2cf291a73fe4fabf34dd0b22e3ee48a/multidict-6.9.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b2f0adc22a4eb31e545221d93fc73a0f6a8cc2379d0f4309f71d1d17ba938b82", size = 323526, upload-time = "2026-09-21T17:55:01.43Z" }, { url = "https://files.pythonhosted.org/packages/98/05/0c86e9678e78f4596df0ed7f59d2aa755107da3f2a92f1b7fa150e94cbb8/multidict-6.9.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7fc59e9ba821b220944ccfe0f89c9dc4745f6d097569992356eb03869f21e953", size = 290278, upload-time = "2026-09-21T17:55:02.993Z" }, { url = "https://files.pythonhosted.org/packages/95/8e/71bd7f43c4883cba6c5f96db88bd2311d52e74ad7680be5915938490d56f/multidict-6.9.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:87cc632c88ee5dc80e12681047839304d98ee5c9a708d686505767001c9b8b9a", size = 321142, upload-time = "2026-09-21T17:55:04.48Z" }, { url = "https://files.pythonhosted.org/packages/2d/00/bf59d6bb22a4c152e4039574c29490caf3c65107715121807b4bd7cde244/multidict-6.9.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b828cf64d62dc09ac183f03c1aeedd164ade96a2ce4934109452edf29de1dd13", size = 319045, upload-time = "2026-09-21T17:55:06.119Z" }, { url = "https://files.pythonhosted.org/packages/3a/3c/f27f4f045198bf1c4bcd6eb3b6cf06be2dceaceb6e67222b903fce7a6749/multidict-6.9.1-cp311-cp311-win32.whl", hash = "sha256:2c1aeb92eea59d824f004341b26d5e4b47a8a441cf9726769b9a90abf9d0e08f", size = 51309, upload-time = "2026-09-21T17:55:07.531Z" }, { url = "https://files.pythonhosted.org/packages/91/17/c2064aef64efc007bc89a571f843e5772f27946eb9bc018731bf8016e319/multidict-6.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:5f89dad732280e7a10b74d40b91364f88e13c3f2c08c2ef83a8cd42f7a61af2e", size = 59148, upload-time = "2026-09-21T17:55:08.936Z" }, { url = "https://files.pythonhosted.org/packages/45/a1/3bab1827edd813dfb90712af5cbb7fc1473ed4d9c871d103df4f4bb950c2/multidict-6.9.1-cp311-cp311-win_arm64.whl", hash = "sha256:5800368526647146978389dfaa46da3356291e9f0fff9a4ef12e8c2bef964a0d", size = 54258, upload-time = "2026-09-21T17:55:10.191Z" }, { url = "https://files.pythonhosted.org/packages/d9/0d/4b5afb6d3e545c9af0cdfe2db8f6f4c6664568c23d863d888674e447e6a4/multidict-6.9.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:29138fef49828542e859828107e42e50d0e587c513b7eb4b2d92bade2b0860fe", size = 98360, upload-time = "2026-09-21T17:55:11.508Z" }, { url = "https://files.pythonhosted.org/packages/89/ab/1b9ca66251899981b21138b87da9d5a9c2c81af12b1ea7d19466972f7fe2/multidict-6.9.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:19e31815d41cefc365489e591d105d2baceb2f65aa75d29471fbdbda8651e006", size = 59979, upload-time = "2026-09-21T17:55:12.866Z" }, { url = "https://files.pythonhosted.org/packages/36/eb/6ae44062466c26c8469ef43f2481a6a48d8cea0587b2d54514ec92e2adfd/multidict-6.9.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6ed30be8918e18c8bed0a2e8b70639ecf02feb61ed00ca2e41cfcb2a50fa3f42", size = 57736, upload-time = "2026-09-21T17:55:14.223Z" }, { url = "https://files.pythonhosted.org/packages/b9/5c/a67817593019257a4ac8b0d1b4c426030e637c047b0692ef405439ecea7a/multidict-6.9.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:637f4ae36264bd7b8d9a60193acddc1d735ad52e8ed53a19931ea6d921fea8e5", size = 333097, upload-time = "2026-09-21T17:55:15.591Z" }, { url = "https://files.pythonhosted.org/packages/90/bf/599ae2e6222822d88a247a8a7ae82fe6fd25d5700757b79603d5edafe6a0/multidict-6.9.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:35fc236507fb1b3138f0af5ecd5f94ed752d4d6d826248eae425f86204013eea", size = 334196, upload-time = "2026-09-21T17:55:17.015Z" }, { url = "https://files.pythonhosted.org/packages/15/10/d8aac5acacbe7f5c117866c776ec26d5f15a868759b6f37ad8e7ed3b5b02/multidict-6.9.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e58952f04772f59f11c6e007471449809a30165188669bca8fdb19dde40a8f24", size = 317465, upload-time = "2026-09-21T17:55:18.412Z" }, { url = "https://files.pythonhosted.org/packages/19/0a/714f796f7293a8b1c5c3f465a26996231d5450c54e85d64ef1258c091134/multidict-6.9.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d35a4f1c63f07fbb8c8f9946dea98b21eddf6c57421585f71d91864be3ba2a24", size = 345914, upload-time = "2026-09-21T17:55:20.306Z" }, { url = "https://files.pythonhosted.org/packages/da/b1/e37fbf769c567be277bcf32df6234035a4384677fcc1bd852752be3d6b93/multidict-6.9.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b5f8771aaaed7f80e84a4e471d2f29ab6721e4595075e54d03ae1ed951b2000a", size = 351163, upload-time = "2026-09-21T17:55:22.21Z" }, { url = "https://files.pythonhosted.org/packages/ed/5b/db08419c1e1f7c9d60cfd2787b2b517d7ae4ebbda8281b48a33eb5141467/multidict-6.9.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:976fd7689d69ec78d67d31d38d396d8adb562f7e8368279f76aed4aa451fa06d", size = 336881, upload-time = "2026-09-21T17:55:23.699Z" }, { url = "https://files.pythonhosted.org/packages/9b/07/cc9bc8a62651d2d53ab93ee4993b3a71b7cb78eb8ebfc9c757a5b6698617/multidict-6.9.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:95052e8777a86bae87c0bd0b5ab22d809e3d1d02bf69e3e66ddda5ba75a05805", size = 303405, upload-time = "2026-09-21T17:55:25.305Z" }, { url = "https://files.pythonhosted.org/packages/b6/0c/8e912afafa70e944dbb8bec4b66ca6e008511395278c0d3dd0e89567536a/multidict-6.9.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1a8adfcaf96f587ab138476eaddef95f29b8a2a8a9afbfea8d2fd62180995d02", size = 324265, upload-time = "2026-09-21T17:55:26.989Z" }, { url = "https://files.pythonhosted.org/packages/66/6a/62c2af80fb085e6234805017af857b8e913dfac7a55e9c1349c27768c58a/multidict-6.9.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1a53de2772cfb74559df2eb4456ec4eeb908435ec55a84b69370d9d745d62aa8", size = 322085, upload-time = "2026-09-21T17:55:28.732Z" }, { url = "https://files.pythonhosted.org/packages/f8/6b/35bf801b336fd960811207203ffdcdc24acc3558b3e7ff2e1c914b141e70/multidict-6.9.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f2ce963299d42fa3f22a90adc0fdf174792ffef5ff4c7ffb68260548fb05580", size = 338107, upload-time = "2026-09-21T17:55:30.303Z" }, { url = "https://files.pythonhosted.org/packages/80/41/495ef65bf5bba29d142d81b3fe1b8154b919bed70e96491b1e93c3c26f0f/multidict-6.9.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5b30ddf7234e611ca877575b62840e6af5977f92f1f9d532eedbb05a44ff8004", size = 339631, upload-time = "2026-09-21T17:55:32.012Z" }, { url = "https://files.pythonhosted.org/packages/19/bd/057fdff5f4e04dcd40a960e38f77d19d3c4b67dd243ffa5f43718edb29fc/multidict-6.9.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:63ada7ee2e9345695f9e9bc4c65d72222253f07b1ac94fd0e37555cc6f3c7f60", size = 302080, upload-time = "2026-09-21T17:55:33.817Z" }, { url = "https://files.pythonhosted.org/packages/3f/de/9ace933ee8dad808632523726f42255b09600087219e3d4ead7369820910/multidict-6.9.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3c95601ed98fad3f6e2f8fe809c3b526b0fab31ef525e00a155e227f3d17f58a", size = 341107, upload-time = "2026-09-21T17:55:35.471Z" }, { url = "https://files.pythonhosted.org/packages/d8/ac/7c1204406097bfc5c283d4a3287d61166807d189917567df4c1318484fc4/multidict-6.9.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c148e8b596000dd3e4bfe206e70f3e666be18d72032e0012555f2373c52e35d6", size = 333482, upload-time = "2026-09-21T17:55:37.002Z" }, { url = "https://files.pythonhosted.org/packages/ff/c0/a70c32ea3299ebe00f44533740cb46905717c51faf29bbd3ce8bb5886d9d/multidict-6.9.1-cp312-cp312-win32.whl", hash = "sha256:f9dad513626a33670f17cddc6078e30e311f444c957e8dbfc5b2b4603c8b4edb", size = 52548, upload-time = "2026-09-21T17:55:38.529Z" }, { url = "https://files.pythonhosted.org/packages/d7/2e/8c9c2591df01e5692ad1bf92febb082a17b1c6c3a19aa8b7ff49988fd989/multidict-6.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:a16a1dc8529f9e734a41c3b856f3eae7ebacdc061dde3f8a844e0c7889c97203", size = 59622, upload-time = "2026-09-21T17:55:39.86Z" }, { url = "https://files.pythonhosted.org/packages/d0/95/59f4472ec512bc180fd207899594c7803ece96262ff9aaa3a4b6d7da6940/multidict-6.9.1-cp312-cp312-win_arm64.whl", hash = "sha256:361f7206cf341ba94fb015688f5c8b480f8e63bd58a4c14a48aeca7851a241cc", size = 54930, upload-time = "2026-09-21T17:55:41.155Z" }, { url = "https://files.pythonhosted.org/packages/eb/45/ddf7c76860f5f553a23ad3ca38463ccf5247081618977742c8dc4625355e/multidict-6.9.1-cp313-cp313-android_24_x86_64.whl", hash = "sha256:d7bf9e43282d69561618e8a0ea33368d532ebef42f15c096f427090521dd74f3", size = 63266, upload-time = "2026-09-21T17:55:42.676Z" }, { url = "https://files.pythonhosted.org/packages/6d/d3/f4ae5945ea2de597eaeb4eca3a74c59783ace54482c9b49435442b63efa8/multidict-6.9.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:03d47df72f084f757c1cb771188d5f4e3a805e4abc4d67e32509272343ae9382", size = 55771, upload-time = "2026-09-21T17:55:44.016Z" }, { url = "https://files.pythonhosted.org/packages/93/7d/15468239920040d01c686e5ae669e6382f7bf31fc3e5e0a6b8f1c3b32d3b/multidict-6.9.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:6bc94fe17c3c56e5418f79515b786b101845f70609b0d19d0c1ba13448e5633a", size = 57116, upload-time = "2026-09-21T17:55:45.315Z" }, { url = "https://files.pythonhosted.org/packages/17/1b/b958f06aac2d8b1e485eb1c105b1b159cbf3868249e5142142451577dad2/multidict-6.9.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8f2973bbd2bebd9d2e0cd6394c1292a1a19ccd56bdcbe1e174059f1a39be5b40", size = 97692, upload-time = "2026-09-21T17:55:46.674Z" }, { url = "https://files.pythonhosted.org/packages/93/6c/d6cfe18e61010166d7237d7527c775eb9843e7078feadea45b7628751b60/multidict-6.9.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:de7738b8c0bb74c4cc16bbd7fb49fc2bcf6430dba11b3432cd52768ae40933e8", size = 59556, upload-time = "2026-09-21T17:55:48.22Z" }, { url = "https://files.pythonhosted.org/packages/46/46/9b4c1127cece0289fb207d04aae5116382ddfcb2a4dc8e0cb49a33f3c7b3/multidict-6.9.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e5ccad4b7bac125722f48d6f862bed3b514d8526deea06316bb72f152cd30a7c", size = 57357, upload-time = "2026-09-21T17:55:49.998Z" }, { url = "https://files.pythonhosted.org/packages/bc/fc/c18b07100a6064573e49e538d13d47eb2b5221f48080512df78aef54ab04/multidict-6.9.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a49ff5cdb33654cb7d6a3c377aa2a83ddefaa1db31eb10bcf3c180aa84f9af8a", size = 330433, upload-time = "2026-09-21T17:55:51.435Z" }, { url = "https://files.pythonhosted.org/packages/62/ff/52a0082adeb69656b634609d4fb0ae65456deaae4cca3d5a12656626dc50/multidict-6.9.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b22ff30006a2f28f8bff878fb93413cbe3a4d1fd517c28081d848c90e9cfd2c8", size = 332487, upload-time = "2026-09-21T17:55:52.937Z" }, { url = "https://files.pythonhosted.org/packages/39/3e/80bd4729635a7af371ff4dcc312594cf96e73f98854491be8740792de430/multidict-6.9.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3adf06c66041aa21eeb8a71e82379b74773298c8e6d3d839b151aae441a99b94", size = 316911, upload-time = "2026-09-21T17:55:54.751Z" }, { url = "https://files.pythonhosted.org/packages/15/f4/7ea4a907e053e924e2e1694d90560f79f72056504bfd5e8483695f9527d2/multidict-6.9.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:963a8d8f97057082679523d0fd4c53a38f86bc58cabe4556faef682ae53fa2fa", size = 344950, upload-time = "2026-09-21T17:55:56.5Z" }, { url = "https://files.pythonhosted.org/packages/0d/16/9642ae41fbfbdc546aa481c2b07ae1bc087a94ab5f5020b4d9ab77da401f/multidict-6.9.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b66ccc5c2cdd26e74fa5d4c29ffae424cc6148bf93ce574821783fb3b6d452c5", size = 350264, upload-time = "2026-09-21T17:55:58.073Z" }, { url = "https://files.pythonhosted.org/packages/93/f2/e06c8e42074d0a4b8419bfe92afbd1d262190b69549ecbcd2dffa4f103c2/multidict-6.9.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7fd79c521f6290c69125fa2b85fa65d9e657e6a8ffaf722dc881b926bef4aa5c", size = 336213, upload-time = "2026-09-21T17:55:59.723Z" }, { url = "https://files.pythonhosted.org/packages/98/43/d7cf9ef4700e7c25244590d1b4f20cf12cbed86beba6c17be4d9e48c1099/multidict-6.9.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1d804e4caf5d5da37d6dac1325da5629ebef1e27a294c2b568b295814aa36c7b", size = 302555, upload-time = "2026-09-21T17:56:01.666Z" }, { url = "https://files.pythonhosted.org/packages/7d/3a/54209920324bc3928f5f2ba28b01a6dd957a9d48c3aaff77e38faaf5668d/multidict-6.9.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bb0d664505f4b112f384cffeee82e91e3f6448d8e574989479db4439b68cba05", size = 322247, upload-time = "2026-09-21T17:56:03.265Z" }, { url = "https://files.pythonhosted.org/packages/33/50/df96f961b178b621ab0adbf9221d4fd21534e1064fd9f5e85c1fa27fea55/multidict-6.9.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:9e14d17773b1b3c758ff153659a1824608a0cb562c45f484b5ed8a433428444a", size = 321787, upload-time = "2026-09-21T17:56:04.894Z" }, { url = "https://files.pythonhosted.org/packages/a7/9b/37f354562a8f82f9c1f63d3a94300fc82126d50320175f0702bbd544f87c/multidict-6.9.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:083735b7f395894e43adb278d5dae901448883a835ff8f1977e285fefdb10418", size = 335498, upload-time = "2026-09-21T17:56:06.783Z" }, { url = "https://files.pythonhosted.org/packages/1e/44/78e366efc6c004185295cc9eb9711c10f13eadf3b547603b9c5526329976/multidict-6.9.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b65121091567847a8cb520d364ab22ba90e00d3cc55fa9eb34bb439f0684bcd1", size = 338244, upload-time = "2026-09-21T17:56:09.162Z" }, { url = "https://files.pythonhosted.org/packages/ad/2b/ab5bd3964691abe4d14b43bdbdb8a621b77cea2ca352dc93159ec0a4575b/multidict-6.9.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:ea999ae6e80e66ad5eea287860951b033d0104ca34d6d87c7b5125ebe0e12721", size = 301641, upload-time = "2026-09-21T17:56:11.227Z" }, { url = "https://files.pythonhosted.org/packages/ea/a8/f6bc899f5aafaba755edc8e4bb934bc00b1e405f8d3fbc1dd10283738074/multidict-6.9.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:095d900c242e00fbe5f321ee072e7278b4153e78c5ce9c1efde167d62c1e4771", size = 340162, upload-time = "2026-09-21T17:56:13.076Z" }, { url = "https://files.pythonhosted.org/packages/eb/03/a8fc809ef364b8c231c065ea2ea2f97ae86d4f9a0e36b5721759fd606778/multidict-6.9.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6441cc837aea58be7d9baef1b2383eb8311ab9303f500f99ac90b584cd78bb14", size = 332826, upload-time = "2026-09-21T17:56:15.175Z" }, { url = "https://files.pythonhosted.org/packages/f2/27/32dde80245e2024e9bb7a6ca3c2fb7c695dc74014cba557cc35be6f91e24/multidict-6.9.1-cp313-cp313-win32.whl", hash = "sha256:9c4880d017555d70dea367dd49271830842d48e3891c2da97da7ce8c4abcee40", size = 52378, upload-time = "2026-09-21T17:56:16.959Z" }, { url = "https://files.pythonhosted.org/packages/be/78/1bac2987edac273a6b27fa50e9204bc3466c94a7b4f6a44828d730f8810f/multidict-6.9.1-cp313-cp313-win_amd64.whl", hash = "sha256:ac51cd64bae51c462ea58ad2492c9b8209667a4ef60c45c4a304518b67598d5d", size = 59449, upload-time = "2026-09-21T17:56:18.336Z" }, { url = "https://files.pythonhosted.org/packages/e1/32/2a77ce19eea48cb9b3521a202b513ba3349aafa702c8317be0b645ffb74b/multidict-6.9.1-cp313-cp313-win_arm64.whl", hash = "sha256:37a9ebe00c698279213d56e6c64e1962ab1e092918270649b397cac3dc196ca4", size = 54713, upload-time = "2026-09-21T17:56:19.774Z" }, { url = "https://files.pythonhosted.org/packages/ec/0f/c6041015aa2cdc11e1dff0cae58898ae5525d19e35efd65a4ecf3c6ea235/multidict-6.9.1-cp314-cp314-android_24_x86_64.whl", hash = "sha256:fc0dcb22fa9aeabfe3fa4e0430099acff985ec5d77a851382f76cc6146e780e5", size = 62336, upload-time = "2026-09-21T17:56:21.181Z" }, { url = "https://files.pythonhosted.org/packages/23/db/95bd0afb130a0149c955f1f066143528d60864e64f41ff5a1e1313609361/multidict-6.9.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:024123f0ab402ab33828e24eb80fa8f25167d0d3783ba5f287e39ed741e6abf9", size = 54892, upload-time = "2026-09-21T17:56:22.63Z" }, { url = "https://files.pythonhosted.org/packages/94/cc/8aa34ae8d09498e8da003f485c03371b55cf1bc6d56cff861b3a7de61251/multidict-6.9.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:af1b5a92315048c3e36bbebfa7d4760a9c3e910bc4166f11b20d77d20d6bcfca", size = 56251, upload-time = "2026-09-21T17:56:24.36Z" }, { url = "https://files.pythonhosted.org/packages/52/48/22baa3b95375096369b04c4348af14139570f302f951773d2c68bf0ccf2e/multidict-6.9.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:b2483da477932ad1983d1d33c18bc3771c6fb00cfbaaed70a875fd547ef8e840", size = 96345, upload-time = "2026-09-21T17:56:25.777Z" }, { url = "https://files.pythonhosted.org/packages/2f/3e/b96779dcac28ec6d491fd821112a0156b519b6701bba186cdf6f6df737f4/multidict-6.9.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:db4d697b18b6ef5528b1f36bfa25072cd2a421869f5963bc0e92c8a34b9e2800", size = 58901, upload-time = "2026-09-21T17:56:27.364Z" }, { url = "https://files.pythonhosted.org/packages/f9/b4/8e6d950f02ca6ecc00ecf671f2ddb5dab7017671a8d197326f75621f5786/multidict-6.9.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:854fd2f1bc6e8a56b89910b5cd7261a8b40f13ebb31572da985ce59c7da0886d", size = 56491, upload-time = "2026-09-21T17:56:28.901Z" }, { url = "https://files.pythonhosted.org/packages/ed/8f/212ed7e03282c7bc271e3796bf985b53d5727c2827361e3dd9c5ee6b093f/multidict-6.9.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:03731f6fc036180700c9dc2308205a48e5ca6f3ff03087739ab746f294022201", size = 332297, upload-time = "2026-09-21T17:56:30.495Z" }, { url = "https://files.pythonhosted.org/packages/a0/97/555aab000e03ecba85c0a1837fd5674d8bf10949490df7800da3a40660ce/multidict-6.9.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:989261c5f1735a165f2e4e87cf6d5f17ab734fa18f9ad0383d5adfcdaefce701", size = 329197, upload-time = "2026-09-21T17:56:32.652Z" }, { url = "https://files.pythonhosted.org/packages/3d/25/f3539b5bdc147beba66015795dfe589eedcc580348fb1a8c69b1df4196b5/multidict-6.9.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b4c9e5d05b126b267ac048a89a0e2d9b48b1b648add62d4872906304a8590610", size = 308456, upload-time = "2026-09-21T17:56:34.657Z" }, { url = "https://files.pythonhosted.org/packages/1e/7d/4665cad8fc326787d218879be879d86dfe32f006c1f88ae47b04d3b52fd5/multidict-6.9.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9d0a21cf76153de8f2d96a877991d6bc59b9ab5180b949e50db73cc193b4a694", size = 343382, upload-time = "2026-09-21T17:56:36.606Z" }, { url = "https://files.pythonhosted.org/packages/41/01/e1e9abe27f492b22dede492bc423015597412b14ce074f7475f4ecd80185/multidict-6.9.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e7386aa18d98d6b8af44b92173654ec469237fda35f8e8523e43b581a86f476a", size = 346848, upload-time = "2026-09-21T17:56:38.344Z" }, { url = "https://files.pythonhosted.org/packages/f8/e5/8d54118bc228e64e1087f1729647b93bbea225eda4a3f914663a6f410bca/multidict-6.9.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b69651732c64afb691e50cdc3387cae305e0eeff8804fe3e3ce203876494932a", size = 333612, upload-time = "2026-09-21T17:56:40.041Z" }, { url = "https://files.pythonhosted.org/packages/76/e1/9509dafc1fc68948e75842a74533ddfa64af57f2b17810e9cacfa68a829b/multidict-6.9.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1fee9a16d88a1c4865610de31ef5c666671020d7a81d1f510eaf3c97d00ebeba", size = 304246, upload-time = "2026-09-21T17:56:42.313Z" }, { url = "https://files.pythonhosted.org/packages/1d/b6/96b93808e1bec0b51d49d89859e49b82a94f7b2e58eca0fc44ffcafd3ae5/multidict-6.9.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7814bbee202acd3bd240204c17d8b87a4c48c81064fd8674dbe527d94d5a4290", size = 321983, upload-time = "2026-09-21T17:56:44.399Z" }, { url = "https://files.pythonhosted.org/packages/d9/1c/08e5184df026b9d8e05a6dce5da22628e46bc4a7c7f03b8bf3c6939a8c46/multidict-6.9.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:95f273bea318a194f656527ee2ed19494327bc500b8e87d9358e3222579aa28d", size = 315927, upload-time = "2026-09-21T17:56:46.208Z" }, { url = "https://files.pythonhosted.org/packages/d7/5d/9ff39e7387f6fcc9a81af5dbf055fde08149849a04f8df10ca5b086b0d39/multidict-6.9.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:73bcafa21a78d0776b3ee7cd2a63c66f968eb7db8e8d594e32d7329950f6e828", size = 336827, upload-time = "2026-09-21T17:56:48.021Z" }, { url = "https://files.pythonhosted.org/packages/5a/be/30fbb2cab22203128928066de94be247dc9a3230bf2bfc54437ac3b5f9f7/multidict-6.9.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:1a938761c77e0e6edb0c93d02f4e988d44a69e5195e5a3b893e5553311347132", size = 336317, upload-time = "2026-09-21T17:56:49.778Z" }, { url = "https://files.pythonhosted.org/packages/bf/f0/2480aef6b7d8e7ab89b064ae14f12ec069570dab3a5c13e0155912293247/multidict-6.9.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:37245ca4105386194dd1d292a6f2aae09bfe1bd7ac6f9ec25093e3cf8e9b143b", size = 303258, upload-time = "2026-09-21T17:56:51.829Z" }, { url = "https://files.pythonhosted.org/packages/4c/04/dbe59cf4ea3778600e8e70e30b31aa9118ad6da2844bc9f717804cbaa000/multidict-6.9.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f0700527dd5bfa8b7204b08330542f4f388899d3c14d885d8a368992e0eb562d", size = 337232, upload-time = "2026-09-21T17:56:53.537Z" }, { url = "https://files.pythonhosted.org/packages/f4/8c/abe55548f06f12878588f08eb803c5a391283f01243f784cb00adac79231/multidict-6.9.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6b7e54fd883671d1a8810704851c044b7173287c552b9f5c3d9e0eb9f00ae194", size = 330261, upload-time = "2026-09-21T17:56:55.335Z" }, { url = "https://files.pythonhosted.org/packages/d0/f1/ba67f668478f152bdfa18abe72e7588bd078bf8b42c172fcf542fcf45826/multidict-6.9.1-cp314-cp314-win32.whl", hash = "sha256:e81ae656b9935ac4528a71f96bb7a14d949778ed1897c573d3e7ebb9187f8841", size = 51715, upload-time = "2026-09-21T17:56:57.048Z" }, { url = "https://files.pythonhosted.org/packages/33/81/014bb2128aedc8157d2848f0ec8a0209c6b822fb88deea012834e1c4a4e8/multidict-6.9.1-cp314-cp314-win_amd64.whl", hash = "sha256:acddcac38adc8342ba48aba98896faa7928854bebb62542362138655b5367ee3", size = 58621, upload-time = "2026-09-21T17:56:58.531Z" }, { url = "https://files.pythonhosted.org/packages/66/34/8f43c03c2d8821a2320b8c560d8a49d0be2920627edfac3f546922f91969/multidict-6.9.1-cp314-cp314-win_arm64.whl", hash = "sha256:32217133dddc58c927805cf6c0731d8144584176b768042ee886d51e71860bc9", size = 53959, upload-time = "2026-09-21T17:57:00.15Z" }, { url = "https://files.pythonhosted.org/packages/08/64/4f2a5eeea10b6d42634ba168ec6efc732ef218772e57b8239cd485c202f6/multidict-6.9.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:0b2fb8c349d1103863750b5d8cb5ace766917f4b35f3d883c8f778853eaa9f76", size = 107694, upload-time = "2026-09-21T17:57:01.785Z" }, { url = "https://files.pythonhosted.org/packages/32/ce/c68d08ac2096c1528ff20d77fd10f7e401db3e534ac5a1c7726e36a77c2f/multidict-6.9.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:56d834b74c993a7d7cb2b8ab33a0d55c3e0d4a3d2f2da2808a4ad3d79189711b", size = 64766, upload-time = "2026-09-21T17:57:03.52Z" }, { url = "https://files.pythonhosted.org/packages/3a/9a/9f5c270c88fe289b4876fe28f9932a70e015a7916aff1e5b0325f7597b11/multidict-6.9.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:783ba7d845d79ce976afd9c1e91a4e5714671defa198ee789e8b23316083a485", size = 62723, upload-time = "2026-09-21T17:57:05.104Z" }, { url = "https://files.pythonhosted.org/packages/7c/63/c9a0b131354dd949426166cef712d708f436a8cf261114f8d5d2aec440ca/multidict-6.9.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:4d718fa1b5f0d0dd75e86fbbc5b0c93ea3a5d65216c85c61cd5d7cdddfe08455", size = 290445, upload-time = "2026-09-21T17:57:06.687Z" }, { url = "https://files.pythonhosted.org/packages/9d/41/ed27d1d20ba91f4e13e8f7dcfaa592614ae0e1d5f45e03171d23c3b098ac/multidict-6.9.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a313bad717dde740959d50850c315b75fd4eb0c5e6b4dc8535db0f1c369be125", size = 304375, upload-time = "2026-09-21T17:57:08.717Z" }, { url = "https://files.pythonhosted.org/packages/66/6f/a7b26167173c3b73d6e5ebb0856c5154ad005156c3a2fa4062329921819c/multidict-6.9.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ef01d29fca550ab871fd99154f82c6472aacf8e7def272dfb07b460123850390", size = 281746, upload-time = "2026-09-21T17:57:10.713Z" }, { url = "https://files.pythonhosted.org/packages/34/1d/da27bdd49b0cb84263288f5f48dbd915f2d17fd228fee2078ca607e80277/multidict-6.9.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0f3bd290711c6e9486173a6ee7cd4e7f00c3971c7908c1ec1b6e5437c5e4c6f9", size = 311499, upload-time = "2026-09-21T17:57:12.467Z" }, { url = "https://files.pythonhosted.org/packages/d0/36/ab0299a7abf53e38ff75d96c64480f1e2ff8edde985f93f7a1ad5e08bd94/multidict-6.9.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:81cdc537e0a42e3c0170752fcadbe450246d5c3b4b7231d6eb9672456605ac94", size = 313553, upload-time = "2026-09-21T17:57:14.548Z" }, { url = "https://files.pythonhosted.org/packages/5a/44/e21be702efc9c9ba097c8be874c68860b1cb6cf9c85611263039bf95b37e/multidict-6.9.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8b193bf7a443c97d81c47052f60c486071a4bdef4a573fa2514f920089414d45", size = 299898, upload-time = "2026-09-21T17:57:16.192Z" }, { url = "https://files.pythonhosted.org/packages/00/8d/e93bc0dc947c7f872e502cfaa7ad9d98f001e1c93cfa6f4940457a6e187a/multidict-6.9.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7a0c98f6a636adf0d7edd60c61589eaf52d149239af754d0bfeb0effedba53a8", size = 273054, upload-time = "2026-09-21T17:57:17.793Z" }, { url = "https://files.pythonhosted.org/packages/5e/c9/945b44493fbe7af26ffe1e43c506b376daeab070fc1a0923bef9bbf572eb/multidict-6.9.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:6e6b7e3a1520c39a2772f414cd9ddf5995f77e4e823dfa1522af383addd465a3", size = 294751, upload-time = "2026-09-21T17:57:19.631Z" }, { url = "https://files.pythonhosted.org/packages/24/79/0969a9b38b814e5fa3af1b0a57708c49b3d9b3d55c208bac6e98b87bb028/multidict-6.9.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:ca65cced0d67a9039e93bcd98a369920e499bf98296844ff56ead01c9085321f", size = 284523, upload-time = "2026-09-21T17:57:21.313Z" }, { url = "https://files.pythonhosted.org/packages/1d/1e/c32ddf53234c228b1a374ddabca19f542ac7f32752f5155982abe2304833/multidict-6.9.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:372c063f37480f62c1ae32dc3a1a0a5942b180c883f99789075a8a8ec3c4e709", size = 290275, upload-time = "2026-09-21T17:57:23.206Z" }, { url = "https://files.pythonhosted.org/packages/5d/09/7a99a3daafd987330abb865a2d36e432fd8bf18e790ddda55c5de15eb98f/multidict-6.9.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:827c92145b3b976b39430129c89d213b250dacbe5fce678e9a03940e6e848983", size = 303350, upload-time = "2026-09-21T17:57:25.086Z" }, { url = "https://files.pythonhosted.org/packages/2e/09/7e6ebaecc4e226d7fe27973c271d58b75c14c24e84c23736d21dc39997dd/multidict-6.9.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:9b0124b9c17e9890f0819b2e7a5f65ec9a2f5aabd6c8e7ad090c1675cf70dee6", size = 272232, upload-time = "2026-09-21T17:57:27.193Z" }, { url = "https://files.pythonhosted.org/packages/1f/6e/420e9e879b21cbdb5036214ee238efabcfab7bf262d3fc124132050f79ff/multidict-6.9.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:23136f5a564654eb61061ec6d5620a4c1ea32c8f552b65e9982a12b72bff601b", size = 300525, upload-time = "2026-09-21T17:57:29.004Z" }, { url = "https://files.pythonhosted.org/packages/b7/7f/c6b0896850b3ceb190ca302760d63148843371f027c5dde3d1d732343a08/multidict-6.9.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f2524ec55b3e65cbe235a8b3c36e2af3b635be02ed05e20c94e70c5c943c009e", size = 295933, upload-time = "2026-09-21T17:57:30.837Z" }, { url = "https://files.pythonhosted.org/packages/29/f2/f0ff3384a756227741c72f4ee94cadf1f9900df0ae961e48639f96115b1c/multidict-6.9.1-cp314-cp314t-win32.whl", hash = "sha256:35ba0263bae5dd3ad5aad767cc9afc01a8598c7dae30f1b3b2de98b1b32c28bd", size = 57776, upload-time = "2026-09-21T17:57:32.835Z" }, { url = "https://files.pythonhosted.org/packages/8d/87/013e1eed30ad46bec1eb68947bc9caf55ba2fd0d6aed04fe964e3b44c23b/multidict-6.9.1-cp314-cp314t-win_amd64.whl", hash = "sha256:7c8d5882ba25ac0282258be435d8a05aa0cbcacfce15799154a338f847f159b9", size = 64881, upload-time = "2026-09-21T17:57:34.489Z" }, { url = "https://files.pythonhosted.org/packages/7f/95/64dd049bb4c53426e2fee7afb874daaa8b4426c41878785883a94511ecf8/multidict-6.9.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ac348379cf4de5538a0a213be1532d289aa801ec5d267c5909446b9ea2f8e2c3", size = 58582, upload-time = "2026-09-21T17:57:36.19Z" }, { url = "https://files.pythonhosted.org/packages/a2/2c/26bc1723592cfe965b575652a7749026474b0625b04b04564e1fba265dc5/multidict-6.9.1-cp315-cp315-android_24_x86_64.whl", hash = "sha256:f04551dce5a7db8c9659f2e4245494c182d0663b83661803e08d46bfcae5eda1", size = 62339, upload-time = "2026-09-21T17:57:37.967Z" }, { url = "https://files.pythonhosted.org/packages/bd/c5/614d2eb9995232d066aae7f17d1d454060b6b5d882b22fbaf6150b05ef1d/multidict-6.9.1-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:c0c88085affd35c33e124e36930c5ad96aff9294ce195eaa0fd9cec962b64a82", size = 55009, upload-time = "2026-09-21T17:57:39.746Z" }, { url = "https://files.pythonhosted.org/packages/7f/24/f7179ecdf9cdd3581ace3292c3b883a1a500a374aa4e619bf6eb521c62e5/multidict-6.9.1-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:a8b75dd3d3638d9a19f23e84af4ffab3b8940422c0df2da2a77005ef5aa3d7ea", size = 56273, upload-time = "2026-09-21T17:57:41.544Z" }, { url = "https://files.pythonhosted.org/packages/ac/72/c9dffcecccd1f8b9a58f960ec4eaecab62c4edb08d5bb984d4de67fe3fdb/multidict-6.9.1-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:006c4478de0a1876f4834e14255776286f09b9846b505fe63f67f9d173a9487c", size = 96390, upload-time = "2026-09-21T17:57:43.385Z" }, { url = "https://files.pythonhosted.org/packages/e9/3f/76542360e655cecdb7c158c7af88c69c4db0d2aac3421659d41214927229/multidict-6.9.1-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:2784090c30a586d5b45197bd9c32f87fb927216cde302f6cfd76d76577e90f08", size = 58900, upload-time = "2026-09-21T17:57:45.105Z" }, { url = "https://files.pythonhosted.org/packages/04/15/f28c71af461dd4ff15653a165cfd8ddaf01f3387ff80d2dd0de057d527d0/multidict-6.9.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:7c708566da8014b120a64b1eb6d200c6c0c8cb36296383723cdb6fc82038270b", size = 56540, upload-time = "2026-09-21T17:57:46.913Z" }, { url = "https://files.pythonhosted.org/packages/19/de/5ee4050c3ddad88c605a89fc1cd18e89abd40a64f183e6fb5276b6eb7f52/multidict-6.9.1-cp315-cp315-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:042fb0196047e786936a730bd302de83143950da45f2c16078da8f35e1cf7919", size = 331818, upload-time = "2026-09-21T17:57:48.825Z" }, { url = "https://files.pythonhosted.org/packages/70/e2/2d4e3c3ee70f583334ff236fe6a3babf7a05ce56169a15df65453af647c0/multidict-6.9.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a2212a0c842c723d919ea4a22a9296cb6b244b386e4e6ea92adfc7fbf3095519", size = 329800, upload-time = "2026-09-21T17:57:50.91Z" }, { url = "https://files.pythonhosted.org/packages/d6/14/f64bd05667343a7250cdd99f81bda2270e3959f00832441f10c7f904e1c1/multidict-6.9.1-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:fd882aa29bf402b62bf1fd7c19fd5df4b6528cf468a908864b39368572b662a9", size = 312048, upload-time = "2026-09-21T17:57:53.053Z" }, { url = "https://files.pythonhosted.org/packages/64/bf/a91256ce00199e7544e3eda79c4e9544eb7388c38fa22f11638c2e357ccb/multidict-6.9.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c57541034d12b215ab0a2bfa371d1a8a198da18176d0426c27105b9161a6862d", size = 343676, upload-time = "2026-09-21T17:57:55.069Z" }, { url = "https://files.pythonhosted.org/packages/14/48/628b978413518159228c2b2ec38645362ceb6427e935d83d716e26490a49/multidict-6.9.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d73fed4e37158ff00cd271871170b79e40138db51e625fd352fa17c6acb34f67", size = 347028, upload-time = "2026-09-21T17:57:57.157Z" }, { url = "https://files.pythonhosted.org/packages/8c/73/5f9dc2b5ac7dd7a82458ae9cd283b99c185834f23442ace295362dcc5e45/multidict-6.9.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:79da2491348b30810728050b4a8ec0416f85884125c2fd44655b3d01150d9c3e", size = 335670, upload-time = "2026-09-21T17:57:59.126Z" }, { url = "https://files.pythonhosted.org/packages/f8/84/6f319ee000f5ab3fa0055b194ad706fddd552c60c76a21d581c87db1d46c/multidict-6.9.1-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b4da208a63434d21a3df64d29758e650fc4aa8cb05848554b76949c296539cca", size = 307804, upload-time = "2026-09-21T17:58:01.2Z" }, { url = "https://files.pythonhosted.org/packages/3f/24/61be5fe1616d033532e8d63dc789c0f35b9793917834713eefe050589ba9/multidict-6.9.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:877ca17fdcfdf5c397493a71e5ff97a87bb181417fe717fdadc77c08c09301ac", size = 323409, upload-time = "2026-09-21T17:58:03.383Z" }, { url = "https://files.pythonhosted.org/packages/22/a6/eab8aaf59892169a0f4e8e78a5516a6caa6abd8e96e6410111258f4ef0ef/multidict-6.9.1-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:40aec5299e1ed71fbb988389059da381c3c1a60e0c649acceb2a35d9b128848e", size = 315746, upload-time = "2026-09-21T17:58:05.372Z" }, { url = "https://files.pythonhosted.org/packages/42/b1/d1e14bab80a74babf6e2ac971a878b84fdcf3a972f3ec3400ca12260fac5/multidict-6.9.1-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:4a409ccc42aefec904038695d5d7fd6d8f3af2721b7b6401d55135ec7d6d298e", size = 334529, upload-time = "2026-09-21T17:58:07.35Z" }, { url = "https://files.pythonhosted.org/packages/f5/50/a05b1d36f6d3363a5a334cebbf11624c9c7a69d66fd23345eb53b1d43b7e/multidict-6.9.1-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:0a5769559e3312dd96731fbe15b4abb6033368ac1cad5a98dadd21946a4c7d6c", size = 336455, upload-time = "2026-09-21T17:58:09.112Z" }, { url = "https://files.pythonhosted.org/packages/cd/0d/bf33cb097380252b08e1177b5ae0cab822c47ce80d236f3f724953c76721/multidict-6.9.1-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:03fac50ddfd8302175b77863a015eccfae76767cda5506eef86df559ba861e1f", size = 305865, upload-time = "2026-09-21T17:58:10.921Z" }, { url = "https://files.pythonhosted.org/packages/ba/ee/a2bd133391204b1cec5a5caf327dc9a06710439b7403220860a8fb164560/multidict-6.9.1-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:5ecace251ccfa705bf3d7d35c5032cf750f5c629809740405697bce5c118c4a4", size = 337531, upload-time = "2026-09-21T17:58:12.846Z" }, { url = "https://files.pythonhosted.org/packages/a8/32/c0972486f81a06c3bbb23063c85afaac53c51608f7e35bcb101a1006408b/multidict-6.9.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:ecc89dbd4155b2f8a47f4bbd89242a35ed15e8e0ec581cab5ac65fa38407329d", size = 332464, upload-time = "2026-09-21T17:58:14.673Z" }, { url = "https://files.pythonhosted.org/packages/69/4f/5cbbe852b45d8a7f0ab3ed042386e4894e463010eb230603596cb15d0fee/multidict-6.9.1-cp315-cp315-win32.whl", hash = "sha256:a3ffe881246d28a862f1985824f484cb7361f44d6b99c4c620436ef56462f38d", size = 51714, upload-time = "2026-09-21T17:58:16.409Z" }, { url = "https://files.pythonhosted.org/packages/d4/77/1fa118386deeae4e7a48870fa5cb073e748b0ac5265a6990651cefc48068/multidict-6.9.1-cp315-cp315-win_amd64.whl", hash = "sha256:59c123d0e948d760a5f930f316cfefa07e8d632ab84327c0693ee6a88171154f", size = 58619, upload-time = "2026-09-21T17:58:18.369Z" }, { url = "https://files.pythonhosted.org/packages/dd/ee/51c45748acfce9cb69d89dcfcd09c874b385407fd6993e885d6905659865/multidict-6.9.1-cp315-cp315-win_arm64.whl", hash = "sha256:31199204b3ced121ff5407a2c342326a5d27e3870abbf94bd80dbd2451b7bc8f", size = 53969, upload-time = "2026-09-21T17:58:20.102Z" }, { url = "https://files.pythonhosted.org/packages/aa/57/89d2d3dedfae2558853c1770c7cbcdfd5211eb4c4090b1e8cb570544a490/multidict-6.9.1-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:8879510a76940670517ea1cb589978da44b86e286ec3e50d664ef330817afce7", size = 107679, upload-time = "2026-09-21T17:58:21.98Z" }, { url = "https://files.pythonhosted.org/packages/c8/df/0c2a28870181c1762f90952b897f6db46c934ce073efe0442604cbc276db/multidict-6.9.1-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:aec65b53a07f580606593f877eefbb29a45939bfc0d3fe6e6d9f42b41b749f68", size = 64753, upload-time = "2026-09-21T17:58:23.622Z" }, { url = "https://files.pythonhosted.org/packages/43/7e/9c6a3e7619459407d8958f7e56ab3dda7f0738f5aed9bb4ad48076e8de83/multidict-6.9.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:14c56f73e78faa1f68bbb826197cd5871994e70e841b8590829c35912ece5c64", size = 62732, upload-time = "2026-09-21T17:58:25.46Z" }, { url = "https://files.pythonhosted.org/packages/38/eb/fd56c9d83ba0cdc3cf66f9acb278b24ef1f043b620b96d145685a3b57338/multidict-6.9.1-cp315-cp315t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:38c9986f9ce50c459b10de216a05f4bd7ed5ac63887d56e500a52bb464b861ce", size = 288648, upload-time = "2026-09-21T17:58:27.115Z" }, { url = "https://files.pythonhosted.org/packages/df/ef/51e79c2442b0f56ac4ac580108d713078b31297e028d468fc220971a305d/multidict-6.9.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:15db6a102cbaf1949cf028ecf080aac76d20bcd29ad4e092574db6c6b7af78a5", size = 304919, upload-time = "2026-09-21T17:58:29.143Z" }, { url = "https://files.pythonhosted.org/packages/6f/e4/774700cc5739353fe88a7204ed30e78a9403d98d4bb2496cc91f096d2e71/multidict-6.9.1-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:bd82c4977196681a499bb6ca9e462afbc5c91c1c15b6a991dfbd72733fea4dd2", size = 289094, upload-time = "2026-09-21T17:58:30.938Z" }, { url = "https://files.pythonhosted.org/packages/ca/41/0bec327bc3a8271825376b6d8a469d1f80e3ba1e2e730e019836e29663c3/multidict-6.9.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bb58ba73a3f96f9a3e46b1fab69929d7edbbddb3133ee74b5c3c54074a53c4f1", size = 312007, upload-time = "2026-09-21T17:58:32.964Z" }, { url = "https://files.pythonhosted.org/packages/c3/7a/9906bf5f1fe20e8e755affccc1a69ecd8aebb079ac65386e5ffc8eefbe75/multidict-6.9.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7c6eecfab7ce4cd9487ff8ba936fe38cdfd68c04faf3d5c710363c6a8e695659", size = 314657, upload-time = "2026-09-21T17:58:35.285Z" }, { url = "https://files.pythonhosted.org/packages/33/92/cf6d665a45663bbe216420fe632da10e9f4f842b07ce02bc3ddf8eb882b8/multidict-6.9.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c62e71e6289d78c0108d8aeb495f8bd3cad4bc1632fedddc9297ddf287ecc20", size = 301563, upload-time = "2026-09-21T17:58:37.472Z" }, { url = "https://files.pythonhosted.org/packages/97/4c/9f1b7945526905d58b4b2d422e2ea81326dda71f9bdc9c32c8002639234a/multidict-6.9.1-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:539c2cd5fed0947c135cd7eabaaac55f48300dfa1de0f3ca4edb5efa6606f471", size = 278540, upload-time = "2026-09-21T17:58:39.551Z" }, { url = "https://files.pythonhosted.org/packages/5c/d9/133aa472fc1be181de29a0c2e1c4cd778280882f532b404395f646742e46/multidict-6.9.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:3100d169ceb7bc8f05f89a6db11d1b21f119975fc26f29dc45a472e3569f0879", size = 294858, upload-time = "2026-09-21T17:58:41.791Z" }, { url = "https://files.pythonhosted.org/packages/bd/38/21f2305dd20ac5038fa581b5d7e0d8dbbd70dc6b50231c22ec173dacddda/multidict-6.9.1-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:696477ad71385c4795e3b8e4cf10b0d2c28c2a1ca6a955e031cb1e62993e9ee3", size = 285461, upload-time = "2026-09-21T17:58:43.844Z" }, { url = "https://files.pythonhosted.org/packages/ad/21/465a43c214d1d7e2d0c974e727d4b5935f8a0868838b5df9d0984c83c1dc/multidict-6.9.1-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:f5844e7befc707367807586f550fa97e23dcfef0728f02b98c7bc498a961a5df", size = 288964, upload-time = "2026-09-21T17:58:46.16Z" }, { url = "https://files.pythonhosted.org/packages/2d/58/72a3e8d56c1e05146d2d1841dbaacf8986375eded1e5a58d30eef191a580/multidict-6.9.1-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:abc7c2e4b47bfe6a9aea434d3fdebb9597ee636e914e92ba352f2068b9142f4c", size = 303924, upload-time = "2026-09-21T17:58:48.395Z" }, { url = "https://files.pythonhosted.org/packages/6f/b9/911084c04530a682a54536b4f738d3992a593b5ff6fea1d6a1f02f3acc6b/multidict-6.9.1-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:7ab379f95caee071a37cbd8be86d4c65accc651d391f9f97748fef006f38769c", size = 278479, upload-time = "2026-09-21T17:58:50.494Z" }, { url = "https://files.pythonhosted.org/packages/45/eb/9a333346c02c928a9e82534638bce85697c10c46b4901fcd70af19357356/multidict-6.9.1-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:557a4e1708df428ebe6c3081c83a273d275dad2446ce0d81fc648ac71afdb18d", size = 301650, upload-time = "2026-09-21T17:58:52.554Z" }, { url = "https://files.pythonhosted.org/packages/67/2f/1d936c4e45c8199db6082b6836e9182e31aa393de0de652637790831ca4b/multidict-6.9.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:475d04d5192eba487a3e2f935976340baa24529046e9c1c9c7a3b7bf80445ae1", size = 298024, upload-time = "2026-09-21T17:58:55.03Z" }, { url = "https://files.pythonhosted.org/packages/a4/0c/ca62ae2882b89a4cfeb0bbca873a4afdb5fc32994c4f8a37a7cb52ede7a0/multidict-6.9.1-cp315-cp315t-win32.whl", hash = "sha256:10083a8a0f4e1b26b599889e90b9802504ce5d3f7722f925bbb7ca47dd22a7c1", size = 57810, upload-time = "2026-09-21T17:58:57.141Z" }, { url = "https://files.pythonhosted.org/packages/02/8b/b2c2805c3eb6fa4cdf5512fb95ac6174dde71e34dd601c5be52f4df5dc82/multidict-6.9.1-cp315-cp315t-win_amd64.whl", hash = "sha256:e96ca64383efa107262ee3949f047af5ee4f1845ba09463466c04d35a83bd3ec", size = 64984, upload-time = "2026-09-21T17:58:59.446Z" }, { url = "https://files.pythonhosted.org/packages/fd/34/03f1d204d698c408f4754c969882609b6b7a902c0e3d16a7033f219cdeda/multidict-6.9.1-cp315-cp315t-win_arm64.whl", hash = "sha256:501ed8b02a5990c67a91c732843609d43a6be1f7576fcdfc867331239f37fbd3", size = 58742, upload-time = "2026-09-21T17:59:01.726Z" }, { url = "https://files.pythonhosted.org/packages/be/59/e26cb779be4c591d1a910f59d29aca9fba4de70349840a833beba2652371/multidict-6.9.1-py3-none-any.whl", hash = "sha256:7bf6478188f4e47bf5686e8a33da4ae28bf43b1b2528d9ee144d28492bfac60b", size = 19176, upload-time = "2026-09-21T17:59:03.501Z" }, ] [[package]] name = "mypy" version = "2.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "ast-serialize" }, { name = "librt", marker = "platform_python_implementation != 'PyPy'" }, { name = "mypy-extensions" }, { name = "pathspec" }, { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/82/6a/878cc1097d4035f82bd516658d0c528d2a9955bc7b363afcbd0b07fea11b/mypy-2.3.1.tar.gz", hash = "sha256:47c1b1207258513a9d93495f69c8be9de73916186f0e52703e8c461b7a623419", size = 3992554, upload-time = "2026-08-15T03:03:38.549Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/a4/be/c624d4241484f37dc62839e177ab607a9b8b3e96f0866544ca99e8e41d51/mypy-2.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94f04929f1c44c35fb0061e912087edaf504acede963a4a7d00680bd089d8531", size = 13936739, upload-time = "2026-08-15T03:03:26.475Z" }, { url = "https://files.pythonhosted.org/packages/53/84/e3cf72f90dce5960871c82551c8fba6da05fc1018f79be41c047bd126bdd/mypy-2.3.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f5d716048611e85ca9eefb2e1baa5d73ede389b5820ded260ea27c757d667af8", size = 14166460, upload-time = "2026-08-15T03:01:50.565Z" }, { url = "https://files.pythonhosted.org/packages/4a/ff/6b97d58aa0f79a5ab9b472db1f6d6df1b11a51d74d0c08ab3760d3a613ba/mypy-2.3.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b091a455111214cb5c9d54a57b9618e9a49f9fe2a42e4e1ac86e9d104ed96ce8", size = 15100476, upload-time = "2026-08-15T03:03:12.079Z" }, { url = "https://files.pythonhosted.org/packages/da/f0/cbb4b7d2ae3ac635f6b4f2d9b04070b8a92edf50da599d3b39e5ed109001/mypy-2.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:df12e20c9efd614738c71b390007ecd0181125afc4ccafca04d78a1d2eed2c01", size = 15347826, upload-time = "2026-08-15T03:03:02.856Z" }, { url = "https://files.pythonhosted.org/packages/5f/10/91dcdc6f8d43fc08e6a06ab1f9732f3abaaf835ac1b2e67b9dff56910855/mypy-2.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:52eaf3a155f35cf80b40220288c861eb45f14a2340c1f6cbfbdb0feff32879d1", size = 11142615, upload-time = "2026-08-15T03:03:36.316Z" }, { url = "https://files.pythonhosted.org/packages/3d/8a/28d54535bf4b9aa43b2d8918c2ef660378b9f66b23d78dcee052744ae622/mypy-2.3.1-cp311-cp311-win_arm64.whl", hash = "sha256:9b4eacbee8a69836c06eff6d0dd4e134a07c2b047755b30c08625fe214f322c6", size = 10141145, upload-time = "2026-08-15T03:03:07.406Z" }, { url = "https://files.pythonhosted.org/packages/85/da/d6effc4f808a842d91edc22535dc9e799d2ff6e91449168b7f47a0771f54/mypy-2.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a32bbbb940af990d3be0b8af321c7b6815bb1b3b48142fe7459b9cc5f58959ff", size = 14047547, upload-time = "2026-08-15T03:02:57.707Z" }, { url = "https://files.pythonhosted.org/packages/e4/e6/478229701dab76f26485fc8ff5d6f241f393da22447400bbc56f6946aebe/mypy-2.3.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff715e45b2231a8e85de1d163d1b42791e4d7aab8f5145f85fee1b710b735aff", size = 14216515, upload-time = "2026-08-15T03:01:26.496Z" }, { url = "https://files.pythonhosted.org/packages/8d/fe/7c42327a3b21e84681f691982cbfe43f334a3685f3b683b72c376476c4fa/mypy-2.3.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:858fc57d3d91fa728e33e7ad71def60fc6272694607b306cd3292db53ae39080", size = 15307789, upload-time = "2026-08-15T03:03:31.62Z" }, { url = "https://files.pythonhosted.org/packages/59/f4/7e597edbe01b5a56fa958ce541302dcaabfed979966f1dffedbea0ea0fc2/mypy-2.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:851833db876e7b650f93719c74b7879a08e338979c96054fdfc3bfd90a486355", size = 15548831, upload-time = "2026-08-15T03:03:15.55Z" }, { url = "https://files.pythonhosted.org/packages/a3/52/cb31e084bc0314a1e384bdd677a4b80e55af04ccac077545e2238b9d320a/mypy-2.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:4c5095a327483591c94e0c8d3ef9e50d4ab1369b541eae007c1f23bc2a41f6bb", size = 11226359, upload-time = "2026-08-15T03:03:29.002Z" }, { url = "https://files.pythonhosted.org/packages/7a/47/88fcf6217b43fa2da81a8c2611370af18141536a4f0294bbf98b457d456d/mypy-2.3.1-cp312-cp312-win_arm64.whl", hash = "sha256:bbfe022634a2a195406bd469e888d2eaf193b02ba7e607391cd7640374aaae3b", size = 10214707, upload-time = "2026-08-15T03:02:48.807Z" }, { url = "https://files.pythonhosted.org/packages/de/cf/862010ee800ca9c2bd0c4c0dacf0f092e5411824a09b8f97ad4be8fe250e/mypy-2.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:114dff494000f18bd10d5d95d84b8567b26da60279ecbe838131841df20e635d", size = 13964542, upload-time = "2026-08-15T03:02:21.43Z" }, { url = "https://files.pythonhosted.org/packages/75/5a/3f3a2107b41e3e92e617e25daaee121413b91e9784bea733131ed4fecc5d/mypy-2.3.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c8637731bb5eee3671eb2c3200827aa3564ed8a9309ecee4d1afe77e6d031bdb", size = 14168922, upload-time = "2026-08-15T03:03:00.351Z" }, { url = "https://files.pythonhosted.org/packages/8b/41/04dc4fe7e63d7820fa4eff272e95157d30cbea921388f3ab3fe77794cd0b/mypy-2.3.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c80fbc405ed8020f5ff3802dc18cf060197bcdd3fbdd6a26ef2fd34dfdd5226", size = 15244791, upload-time = "2026-08-15T03:02:31.089Z" }, { url = "https://files.pythonhosted.org/packages/96/fc/c3053b26b9054949285aa868cb6af8c10e7591541cacd79c5dcc06a1fcf9/mypy-2.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:84081f538ce27375045c02e3d7f81bd11d853400621ae245d87ce7b6c420ec74", size = 15501627, upload-time = "2026-08-15T03:03:34.128Z" }, { url = "https://files.pythonhosted.org/packages/70/4e/d77daab008bbc4e5001374d7928f4a260d28f0e6747af444fc4763f7a310/mypy-2.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:e9144ac16fde007096f9563eb2041b4433c2d705c4218edeb79e7e9d01035ee6", size = 11243961, upload-time = "2026-08-15T03:02:11.952Z" }, { url = "https://files.pythonhosted.org/packages/f0/f8/7eb68c136e4abd30569fe31ef2bfcb7eceae9952cab80017c04cd09f5d0c/mypy-2.3.1-cp313-cp313-win_arm64.whl", hash = "sha256:77ad9529e67dca28e511f5cd5671436584ce91f6d3bac159a353158187b986ac", size = 10213219, upload-time = "2026-08-15T03:02:26.361Z" }, { url = "https://files.pythonhosted.org/packages/be/c4/42a49d44aeff804edf1b19acce0b49e8bd1a9c57dee9605dd8d980aa43d7/mypy-2.3.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:192abaedf75da1bc0b1cef104927e70ec49c1ef0031cc4825c7ee10a438ed24d", size = 13986778, upload-time = "2026-08-15T03:01:33.69Z" }, { url = "https://files.pythonhosted.org/packages/45/13/9331fd2dfed7194d66c5304072894a8be3e51e9deda6863c1eceaa35a43d/mypy-2.3.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf678dffd16efcda2c15cbd30e9ecc0081388e29ea23687a88e686ed92638dc3", size = 14188467, upload-time = "2026-08-15T03:02:40.554Z" }, { url = "https://files.pythonhosted.org/packages/78/f7/f4a34edab45667c5465855dc585a20e87978ffa8aee711445b7239d120c6/mypy-2.3.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e036f06b41630f4c8a1d48f9ac6aa26acc65f8be089973f5519da643318f03f", size = 15225538, upload-time = "2026-08-15T03:03:09.761Z" }, { url = "https://files.pythonhosted.org/packages/40/05/534b3590757bd05794f73e07f6666c2a77b8597ffed795c94ce570096aa0/mypy-2.3.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:71af9c8a894e862b58e92abb08e53b05a384a1e5e5d6dc7cda59126211a53d82", size = 15480805, upload-time = "2026-08-15T03:01:41.134Z" }, { url = "https://files.pythonhosted.org/packages/55/da/bdfba852e2562f599624af5bb7d29e36b0b4f526f2b8bac85efe0dd1803d/mypy-2.3.1-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:3c80cd23d85368bdd9f37d5231dfd97d35bcbf5bf41af96ef3a9b078ad1957f9", size = 7761712, upload-time = "2026-08-15T03:02:36.008Z" }, { url = "https://files.pythonhosted.org/packages/98/31/60fc64a74cdba4f2a5d642d32317993e479163e1ac7d91b695e5d15e2264/mypy-2.3.1-cp314-cp314-win_amd64.whl", hash = "sha256:4956f34d145e145562a0a0bf367f642bbc85c04ec2baf47ae015947c3169a85d", size = 11423968, upload-time = "2026-08-15T03:02:06.931Z" }, { url = "https://files.pythonhosted.org/packages/a9/23/eb5950b24cd26ba3b78f87707a275568d633c77dae8e61c9661be6055ca6/mypy-2.3.1-cp314-cp314-win_arm64.whl", hash = "sha256:cfb12e360242d23d91f5e978d94f58ea66acf5804c4fb6f2f794a20d4cb1b595", size = 10399323, upload-time = "2026-08-15T03:02:33.671Z" }, { url = "https://files.pythonhosted.org/packages/82/c7/f80f4e46c0b9a00eb5f78a79d49dda8bdf56a5230f7257fb33e76be04da7/mypy-2.3.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e5f1c50bb05b64e2026b52867e8d21106f01313c744a2c4ecc34c90d12e8d6e2", size = 15121308, upload-time = "2026-08-15T03:01:46.053Z" }, { url = "https://files.pythonhosted.org/packages/5d/74/9b04f17c7074cc5188f02fb63a2ca1d43fedf479e84fe3091c39061a1d7f/mypy-2.3.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:667196b352f4cf304ded4c10f90cfc179263a1acfb3cdcfa984bdfd340d498bc", size = 15536590, upload-time = "2026-08-15T03:01:35.941Z" }, { url = "https://files.pythonhosted.org/packages/26/04/c837ef6208e567774e2ed1f863f8ba6ec4817b1b6dd426315e5d559b6ec9/mypy-2.3.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b9c53e395c12cad2c6d4b67d5da7c6057638a132d85c08b73646b18f802a0045", size = 16791074, upload-time = "2026-08-15T03:01:31.073Z" }, { url = "https://files.pythonhosted.org/packages/37/68/48730230afa45192d5bd429a6a2ff24a6f8dedda90fdf2b221792b54518f/mypy-2.3.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:18162b128c3f9c703cd35f5537446900b0d21a2549aa7a95d21380d2ef643fb0", size = 17069183, upload-time = "2026-08-15T03:02:28.566Z" }, { url = "https://files.pythonhosted.org/packages/1c/ea/ca23fc9c20eeda09a15c9cbcf50015d0e73f409f6ead059e42aa69a608ff/mypy-2.3.1-cp314-cp314t-win_amd64.whl", hash = "sha256:30c0477d4aab7b7f39c8397dc877f2c96b9fe5588ec379f372c56eb63d599f63", size = 12154679, upload-time = "2026-08-15T03:02:04.809Z" }, { url = "https://files.pythonhosted.org/packages/3b/67/8d982126034990869466f73b8db80dcb2234a7ac39b4dad093e047a79835/mypy-2.3.1-cp314-cp314t-win_arm64.whl", hash = "sha256:6941ab3619377bc3f32ca02876b07d27f216f5201604b664d3937ea0fdd23bb4", size = 10969159, upload-time = "2026-08-15T03:02:38.152Z" }, { url = "https://files.pythonhosted.org/packages/ee/f7/41e7f2d8117fbc7a7587286162ffe2f688984b69c46ed63cf5f2e4fc3bae/mypy-2.3.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:6f041a6de52c9217ca125e78ba0a335cb7fd98a1c0580978e49ab2b126f70b57", size = 13990694, upload-time = "2026-08-15T03:03:21.919Z" }, { url = "https://files.pythonhosted.org/packages/06/85/8f665811a0c8f3bf6fa1d9acd665ec2d97a2bcc453ae68dcd92340941cd6/mypy-2.3.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5159ae60f5dbc3a498af5ba8365505808ac8031bc63f9e00304ad545d40bdd9b", size = 14203518, upload-time = "2026-08-15T03:01:48.455Z" }, { url = "https://files.pythonhosted.org/packages/2d/82/91b866c8546b120bff83b73a439d90d2d63ef3aff113599e6b8e4d566848/mypy-2.3.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:47a8a7a0a7f6f6e63995c0ac36fa0c07b127413fdc81f0439b7f3dccafd33561", size = 15220224, upload-time = "2026-08-15T03:01:23.577Z" }, { url = "https://files.pythonhosted.org/packages/c8/78/c226c99208ee40de7c768369fa533f933afa003dfdc606ff021450724e91/mypy-2.3.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:2329c0501293d4e1f33bc15d04d6304d65a1cdda967ee93a05c1e681a3923133", size = 15501512, upload-time = "2026-08-15T03:02:09.453Z" }, { url = "https://files.pythonhosted.org/packages/a9/e7/7cfb3f106c393979f4cc37ad6c0586044d50401e3c35b0c003e4f3ba6bc9/mypy-2.3.1-cp315-cp315-pyemscripten_2026_5_wasm32.whl", hash = "sha256:bb26deed807bdb0457cf3e3f1cd7c4a1cf9d66864eaf1b4a61e06805d4c6b1f9", size = 7761913, upload-time = "2026-08-15T03:01:55.65Z" }, { url = "https://files.pythonhosted.org/packages/99/3c/52affefa273b97939a1f474ae4a349c8718635c15b941112dfab4291b0c1/mypy-2.3.1-cp315-cp315-win_amd64.whl", hash = "sha256:375d7013876a8233b2d05be185bfa09f689696cd999ce8b1cfe6acac5c80e8a3", size = 11422533, upload-time = "2026-08-15T03:03:24.101Z" }, { url = "https://files.pythonhosted.org/packages/2a/b7/75643e70c72a5b346d8a9b1543c967ea8824df2ee3fb7ccba652c272b7bb/mypy-2.3.1-cp315-cp315-win_arm64.whl", hash = "sha256:586b3612214cceabb3c0f588c97e7d1e535393f06a60e912e994f6b3ace97523", size = 10397931, upload-time = "2026-08-15T03:02:55.265Z" }, { url = "https://files.pythonhosted.org/packages/10/ce/53be21f2d4adfcd26f63f1184a13ed797015ab463853f117e2e11e4d726f/mypy-2.3.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:ef0c6335cda9d807f8193d8ff6204a72bc909fa9882aacbca14f43cdb7188306", size = 15118669, upload-time = "2026-08-15T03:02:51.479Z" }, { url = "https://files.pythonhosted.org/packages/62/43/20de757cd42989d291a17fad607742c4c74e875ce5cea00e5a5225020ac1/mypy-2.3.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e598c8c66401d26b150872154a286e6d484cf2789c3bb28a7556806298423021", size = 15545627, upload-time = "2026-08-15T03:03:05.132Z" }, { url = "https://files.pythonhosted.org/packages/7e/fc/092bdf77ad280eaf501422f0f3b966012b528076cc13e41a774861c907d1/mypy-2.3.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eda22fd4efa9dcd39331d1dede9b5b8b8a7fd69af07592e778433da98610d29e", size = 16764157, upload-time = "2026-08-15T03:02:23.958Z" }, { url = "https://files.pythonhosted.org/packages/94/5c/c94c4d62d909b07f552d0d9356d7acc943825558e602a64822ffa2231536/mypy-2.3.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:2a0ba2e57847849fb0d1fcdabb32786d223095ed8bc121dfe322bcdb3d9c46bc", size = 17073258, upload-time = "2026-08-15T03:02:14.573Z" }, { url = "https://files.pythonhosted.org/packages/c0/f7/511a88b89e478053c02d22039bb8f3ce4183efe8fd7a4f0a5910a8bb0a32/mypy-2.3.1-cp315-cp315t-win_amd64.whl", hash = "sha256:3f7e865dd51f235f60a2dbcd8728a1c095f5ca28f095d48a725b84cd935735c4", size = 12135505, upload-time = "2026-08-15T03:02:16.714Z" }, { url = "https://files.pythonhosted.org/packages/71/bf/02573b56964ecb0f7c644f915f53c325ae15c3faec521c5adf11599a32df/mypy-2.3.1-cp315-cp315t-win_arm64.whl", hash = "sha256:8ad80807dc3ab8ea978b1b2b6e4a657194ace1d4ef03e0e731aff1abd517da29", size = 10962647, upload-time = "2026-08-15T03:01:43.712Z" }, { url = "https://files.pythonhosted.org/packages/8e/41/9675c7a1e78edecfba0b79e587a52594c56e189368261dc7b3a7fffb9527/mypy-2.3.1-py3-none-any.whl", hash = "sha256:6ed5c7e3419083268e5c9258bd1c1ef91af44a9e89374dbcaf37b775716e72eb", size = 2754338, upload-time = "2026-08-15T03:02:53.4Z" }, ] [[package]] name = "mypy-extensions" version = "1.1.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, ] [[package]] name = "nh3" version = "0.3.5" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/9c/5f/1d19bdc7d27238e37f3672cdc02cb77c56a4a86d140cd4f4f23c90df6e16/nh3-0.3.5.tar.gz", hash = "sha256:45855e14ff056064fec77133bfcf7cd691838168e5e17bbef075394954dc9dc8", size = 20743, upload-time = "2026-04-25T10:44:16.066Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/63/b0/8587ac42a9627ab88e7e221601f1dfccbf4db80b2a29222ea63266dc9abc/nh3-0.3.5-cp314-cp314t-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:23a312224875f72cd16bde417f49071451877e29ef646a60e50fcb69407cc18a", size = 1420126, upload-time = "2026-04-25T10:43:39.834Z" }, { url = "https://files.pythonhosted.org/packages/c0/1b/1dbc4d0c43f12e8c1784ede17eaee6f061d4fbe5505757c65c49b2ceab95/nh3-0.3.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:387abd011e81959d5a35151a11350a0795c6edeb53ebfa02d2e882dc01299263", size = 793943, upload-time = "2026-04-25T10:43:41.363Z" }, { url = "https://files.pythonhosted.org/packages/47/9f/d6758d7a14ee964bf439cc35ae4fa24a763a93399c8ef6f22bd11d532d29/nh3-0.3.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:48f45e3e914be93a596431aa143dedf1582557bf41a58153c296048d6e3798c9", size = 841150, upload-time = "2026-04-25T10:43:43.007Z" }, { url = "https://files.pythonhosted.org/packages/b6/36/d5d1ae8374612c98f390e1ea7c610fa6c9716259a03bbf4d15b269f40073/nh3-0.3.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0a09f51806fd51b4fedbf9ea2b61fef388f19aef0d62fe51199d41648be14588", size = 1008415, upload-time = "2026-04-25T10:43:44.324Z" }, { url = "https://files.pythonhosted.org/packages/ba/8f/d13a9c3fd2d9c131a2a281737380e9379eb0f8c33fea24c2b923aaafbb15/nh3-0.3.5-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:c357f1d042c67f135a5e6babb2b0e3b9d9224ff4a3543240f597767b01384ffd", size = 1092706, upload-time = "2026-04-25T10:43:45.653Z" }, { url = "https://files.pythonhosted.org/packages/bb/57/2f3add7f8680fcc896afa6a675cb2bab09982853ee8af40bad621f6b61c4/nh3-0.3.5-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:38748140bf76383ab7ce2dce0ad4cb663855d8fbc9098f7f3483673d09616a17", size = 1048346, upload-time = "2026-04-25T10:43:46.974Z" }, { url = "https://files.pythonhosted.org/packages/c1/c3/2f9e4ffa82863074d1361bfe949bc46393d91b3411579dfbbd090b24cac5/nh3-0.3.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:84bdeb082544fbcb77a12c034dd77d7da0556fdc0727b787eb6214b958c15e29", size = 1029038, upload-time = "2026-04-25T10:43:48.569Z" }, { url = "https://files.pythonhosted.org/packages/e8/10/2804deb3f3315184c9cae41702e293c87524b5a21f766b07d7fe3ffbcfbb/nh3-0.3.5-cp314-cp314t-win32.whl", hash = "sha256:c3aae321f67ae66cff2a627115f106a377d4475d10b0e13d97959a13486b9a88", size = 603263, upload-time = "2026-04-25T10:43:49.851Z" }, { url = "https://files.pythonhosted.org/packages/eb/a2/f6685248b49f7548fc9a8c335ab3a52f68610b72e8a61576447151e4e2e6/nh3-0.3.5-cp314-cp314t-win_amd64.whl", hash = "sha256:c88605d8d468f7fc1b31e06129bc91d6c96f6c621776c9b504a0da9beac9df5f", size = 616866, upload-time = "2026-04-25T10:43:51.005Z" }, { url = "https://files.pythonhosted.org/packages/ca/b6/d8c9018635d4acfefde6b68470daa510eed715a350cbaa2f928ba0609f81/nh3-0.3.5-cp314-cp314t-win_arm64.whl", hash = "sha256:72c5bdedec27fa33de6a5326346ea8aa3fe54f6ac294d54c4b204fb66a9f1e79", size = 602566, upload-time = "2026-04-25T10:43:52.283Z" }, { url = "https://files.pythonhosted.org/packages/85/30/d162e99746a2fb1d98bb0ef23af3e201b156cf09f7de867c7390c8fe1c06/nh3-0.3.5-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:3bb854485c9b33e5bb143ff3e49e577073bc6bc320f0ff8fc316dd89c0d3c101", size = 1442393, upload-time = "2026-04-25T10:43:53.556Z" }, { url = "https://files.pythonhosted.org/packages/25/8c/072120d506978ab053e1732d0efa7c86cb478fee0ee098fda0ac0d31cb34/nh3-0.3.5-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50d401ab2d8e86d59e2126e3ab2a2f45840c405842b626d9a51624b3a33b6878", size = 837722, upload-time = "2026-04-25T10:43:55.073Z" }, { url = "https://files.pythonhosted.org/packages/52/86/d4e06e28c5ad1c4b065f89737d02631bd49f1660b6ebcf17a87ffcd201da/nh3-0.3.5-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:acfd354e61accbe4c74f8017c6e397a776916dfe47c48643cf7fd84ade826f93", size = 822872, upload-time = "2026-04-25T10:43:56.581Z" }, { url = "https://files.pythonhosted.org/packages/0a/62/50659255213f241ec5797ae7427464c969397373e83b3659372b341ae869/nh3-0.3.5-cp38-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:52d877980d7ca01dc3baf3936bf844828bc6f332962227a684ed79c18cce14c3", size = 1100031, upload-time = "2026-04-25T10:43:58.098Z" }, { url = "https://files.pythonhosted.org/packages/00/7a/a12ae77593b2fcf3be25df7bc1c01967d0de448bdb4b6c7ec80fe4f5a74f/nh3-0.3.5-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:207c01801d3e9bb8ec08f08689346bdd30ce15b8bf60013a925d08b5388962a4", size = 1057669, upload-time = "2026-04-25T10:43:59.328Z" }, { url = "https://files.pythonhosted.org/packages/2d/71/5647dc04c0233192a3956fc91708822b21403a06508cacf78083c68e7bf0/nh3-0.3.5-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea232933394d1d58bf7c4bb348dc4660eae6604e1ae81cd2ba6d9ed80d390f3b", size = 914795, upload-time = "2026-04-25T10:44:00.52Z" }, { url = "https://files.pythonhosted.org/packages/1b/0e/bf298920729f216adcb002acf7ea01b90842603d2e4e2ce9b900d9ee8fab/nh3-0.3.5-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe3a787dc76b50de6bee54ef242f26c41dfe47654428e3e94f0fae5bb6dd2cc1", size = 806976, upload-time = "2026-04-25T10:44:01.743Z" }, { url = "https://files.pythonhosted.org/packages/85/01/26761e1dc2b848e65a62c19e5d39ad446283287cd4afddc89f364ab86bc9/nh3-0.3.5-cp38-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:488928988caad25ba14b1eb5bc74e25e21f3b5e40341d956f3ce4a8bc19460dc", size = 834904, upload-time = "2026-04-25T10:44:03.454Z" }, { url = "https://files.pythonhosted.org/packages/33/53/0766113e679540ac1edc1b82b1295aecd321eeb75d6fead70109a838b6ee/nh3-0.3.5-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2c069570b06aa848457713ad7af4a9905691291548c4466a9ad78ee95808382b", size = 857159, upload-time = "2026-04-25T10:44:05.003Z" }, { url = "https://files.pythonhosted.org/packages/58/36/734d353dfaf292fed574b8b3092f0ef79dc6404f3879f7faaa61a4701fad/nh3-0.3.5-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:eeedc90ed8c42c327e8e10e621ccfa314fc6cce35d5929f4297ff1cdb89667c4", size = 1018600, upload-time = "2026-04-25T10:44:06.18Z" }, { url = "https://files.pythonhosted.org/packages/6b/aa/d9c59c1b49669fcb7bababa55df82385f029ad5c2651f583c3a1141cfdd1/nh3-0.3.5-cp38-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:de8e8621853b6470fe928c684ee0d3f39ea8086cebafe4c416486488dea7b68d", size = 1103530, upload-time = "2026-04-25T10:44:07.68Z" }, { url = "https://files.pythonhosted.org/packages/90/b0/cdd210bfb8d9d43fb02fc3c868336b9955934d8e15e66eb1d15a147b8af0/nh3-0.3.5-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:6ea58cc44d274c643b83547ca9654a0b1a817609b160601356f76a2b744c49ad", size = 1061754, upload-time = "2026-04-25T10:44:09.362Z" }, { url = "https://files.pythonhosted.org/packages/ce/cb/7a39e72e668c8445bdd95e494b3e21cfdddc68329be8ea3522c8befb46c4/nh3-0.3.5-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e49c9b564e6bcb03ecd2f057213df9a0de15a95812ac9db9600b590db23d3ae9", size = 1040938, upload-time = "2026-04-25T10:44:10.775Z" }, { url = "https://files.pythonhosted.org/packages/af/4c/fc2f9ed208a3801a319f59b5fea03cdc20cf3bd8af14be930d3a8de01224/nh3-0.3.5-cp38-abi3-win32.whl", hash = "sha256:559e4c73b689e9a7aa97ac9760b1bc488038d7c1a575aa4ab5a0e19ee9630c0f", size = 611445, upload-time = "2026-04-25T10:44:12.317Z" }, { url = "https://files.pythonhosted.org/packages/db/1a/e4c9b5e2ae13e6092c9ec16d8ca30646cb01fcdea245f36c5b08fd21fbd5/nh3-0.3.5-cp38-abi3-win_amd64.whl", hash = "sha256:45e6a65dc88a300a2e3502cb9c8e6d1d6b831d6fba7470643333609c6aab1f30", size = 626502, upload-time = "2026-04-25T10:44:13.682Z" }, { url = "https://files.pythonhosted.org/packages/80/7c/19cd0671d1ba2762fb388fc149697d20d0568ccfeef833b11280a619e526/nh3-0.3.5-cp38-abi3-win_arm64.whl", hash = "sha256:8f85285700a18e9f3fc5bff41fe573fa84f81542ef13b48a89f9fecca0474d3b", size = 611069, upload-time = "2026-04-25T10:44:14.934Z" }, ] [[package]] name = "opentelemetry-api" version = "1.44.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ee/8b/aa9e2d8b8dfa7c946f7dec5d1f8f6ba8eca062f43509a06bdb5ce93d26c0/opentelemetry_api-1.44.0.tar.gz", hash = "sha256:67647e5e9566edcf421166fdf022b3537f818635daa852b289e34604dc6fb33a", size = 72406, upload-time = "2026-07-16T15:25:32.678Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ca/6f/a04e900f465ff3221ccc395522503e2d10e79fa21f2723c8e177aae1e0d1/opentelemetry_api-1.44.0-py3-none-any.whl", hash = "sha256:94b98c893a91b88657eaac1e3ba89618cdb85be6918196705354f34728b2cdef", size = 60018, upload-time = "2026-07-16T15:25:11.657Z" }, ] [[package]] name = "outcome" version = "1.3.0.post0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "attrs" }, ] sdist = { url = "https://files.pythonhosted.org/packages/98/df/77698abfac98571e65ffeb0c1fba8ffd692ab8458d617a0eed7d9a8d38f2/outcome-1.3.0.post0.tar.gz", hash = "sha256:9dcf02e65f2971b80047b377468e72a268e15c0af3cf1238e6ff14f7f91143b8", size = 21060, upload-time = "2023-10-26T04:26:04.361Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/55/8b/5ab7257531a5d830fc8000c476e63c935488d74609b50f9384a643ec0a62/outcome-1.3.0.post0-py2.py3-none-any.whl", hash = "sha256:e771c5ce06d1415e356078d3bdd68523f284b4ce5419828922b6871e65eda82b", size = 10692, upload-time = "2023-10-26T04:26:02.532Z" }, ] [[package]] name = "packaging" version = "26.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, ] [[package]] name = "pathspec" version = "1.1.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/5a/82/42f767fc1c1143d6fd36efb827202a2d997a375e160a71eb2888a925aac1/pathspec-1.1.1.tar.gz", hash = "sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a", size = 135180, upload-time = "2026-04-27T01:46:08.907Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl", hash = "sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189", size = 57328, upload-time = "2026-04-27T01:46:07.06Z" }, ] [[package]] name = "platformdirs" version = "4.9.6" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/9f/4a/0883b8e3802965322523f0b200ecf33d31f10991d0401162f4b23c698b42/platformdirs-4.9.6.tar.gz", hash = "sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a", size = 29400, upload-time = "2026-04-09T00:04:10.812Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/75/a6/a0a304dc33b49145b21f4808d763822111e67d1c3a32b524a1baf947b6e1/platformdirs-4.9.6-py3-none-any.whl", hash = "sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917", size = 21348, upload-time = "2026-04-09T00:04:09.463Z" }, ] [[package]] name = "pluggy" version = "1.6.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] [[package]] name = "propcache" version = "0.4.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/9e/da/e9fc233cf63743258bff22b3dfa7ea5baef7b5bc324af47a0ad89b8ffc6f/propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d", size = 46442, upload-time = "2025-10-08T19:49:02.291Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/8c/d4/4e2c9aaf7ac2242b9358f98dccd8f90f2605402f5afeff6c578682c2c491/propcache-0.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:60a8fda9644b7dfd5dece8c61d8a85e271cb958075bfc4e01083c148b61a7caf", size = 80208, upload-time = "2025-10-08T19:46:24.597Z" }, { url = "https://files.pythonhosted.org/packages/c2/21/d7b68e911f9c8e18e4ae43bdbc1e1e9bbd971f8866eb81608947b6f585ff/propcache-0.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5", size = 45777, upload-time = "2025-10-08T19:46:25.733Z" }, { url = "https://files.pythonhosted.org/packages/d3/1d/11605e99ac8ea9435651ee71ab4cb4bf03f0949586246476a25aadfec54a/propcache-0.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e", size = 47647, upload-time = "2025-10-08T19:46:27.304Z" }, { url = "https://files.pythonhosted.org/packages/58/1a/3c62c127a8466c9c843bccb503d40a273e5cc69838805f322e2826509e0d/propcache-0.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3d902a36df4e5989763425a8ab9e98cd8ad5c52c823b34ee7ef307fd50582566", size = 214929, upload-time = "2025-10-08T19:46:28.62Z" }, { url = "https://files.pythonhosted.org/packages/56/b9/8fa98f850960b367c4b8fe0592e7fc341daa7a9462e925228f10a60cf74f/propcache-0.4.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a9695397f85973bb40427dedddf70d8dc4a44b22f1650dd4af9eedf443d45165", size = 221778, upload-time = "2025-10-08T19:46:30.358Z" }, { url = "https://files.pythonhosted.org/packages/46/a6/0ab4f660eb59649d14b3d3d65c439421cf2f87fe5dd68591cbe3c1e78a89/propcache-0.4.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2bb07ffd7eaad486576430c89f9b215f9e4be68c4866a96e97db9e97fead85dc", size = 228144, upload-time = "2025-10-08T19:46:32.607Z" }, { url = "https://files.pythonhosted.org/packages/52/6a/57f43e054fb3d3a56ac9fc532bc684fc6169a26c75c353e65425b3e56eef/propcache-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48", size = 210030, upload-time = "2025-10-08T19:46:33.969Z" }, { url = "https://files.pythonhosted.org/packages/40/e2/27e6feebb5f6b8408fa29f5efbb765cd54c153ac77314d27e457a3e993b7/propcache-0.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fc38cba02d1acba4e2869eef1a57a43dfbd3d49a59bf90dda7444ec2be6a5570", size = 208252, upload-time = "2025-10-08T19:46:35.309Z" }, { url = "https://files.pythonhosted.org/packages/9e/f8/91c27b22ccda1dbc7967f921c42825564fa5336a01ecd72eb78a9f4f53c2/propcache-0.4.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:67fad6162281e80e882fb3ec355398cf72864a54069d060321f6cd0ade95fe85", size = 202064, upload-time = "2025-10-08T19:46:36.993Z" }, { url = "https://files.pythonhosted.org/packages/f2/26/7f00bd6bd1adba5aafe5f4a66390f243acab58eab24ff1a08bebb2ef9d40/propcache-0.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f10207adf04d08bec185bae14d9606a1444715bc99180f9331c9c02093e1959e", size = 212429, upload-time = "2025-10-08T19:46:38.398Z" }, { url = "https://files.pythonhosted.org/packages/84/89/fd108ba7815c1117ddca79c228f3f8a15fc82a73bca8b142eb5de13b2785/propcache-0.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e9b0d8d0845bbc4cfcdcbcdbf5086886bc8157aa963c31c777ceff7846c77757", size = 216727, upload-time = "2025-10-08T19:46:39.732Z" }, { url = "https://files.pythonhosted.org/packages/79/37/3ec3f7e3173e73f1d600495d8b545b53802cbf35506e5732dd8578db3724/propcache-0.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:981333cb2f4c1896a12f4ab92a9cc8f09ea664e9b7dbdc4eff74627af3a11c0f", size = 205097, upload-time = "2025-10-08T19:46:41.025Z" }, { url = "https://files.pythonhosted.org/packages/61/b0/b2631c19793f869d35f47d5a3a56fb19e9160d3c119f15ac7344fc3ccae7/propcache-0.4.1-cp311-cp311-win32.whl", hash = "sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1", size = 38084, upload-time = "2025-10-08T19:46:42.693Z" }, { url = "https://files.pythonhosted.org/packages/f4/78/6cce448e2098e9f3bfc91bb877f06aa24b6ccace872e39c53b2f707c4648/propcache-0.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6", size = 41637, upload-time = "2025-10-08T19:46:43.778Z" }, { url = "https://files.pythonhosted.org/packages/9c/e9/754f180cccd7f51a39913782c74717c581b9cc8177ad0e949f4d51812383/propcache-0.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239", size = 38064, upload-time = "2025-10-08T19:46:44.872Z" }, { url = "https://files.pythonhosted.org/packages/a2/0f/f17b1b2b221d5ca28b4b876e8bb046ac40466513960646bda8e1853cdfa2/propcache-0.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2", size = 80061, upload-time = "2025-10-08T19:46:46.075Z" }, { url = "https://files.pythonhosted.org/packages/76/47/8ccf75935f51448ba9a16a71b783eb7ef6b9ee60f5d14c7f8a8a79fbeed7/propcache-0.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403", size = 46037, upload-time = "2025-10-08T19:46:47.23Z" }, { url = "https://files.pythonhosted.org/packages/0a/b6/5c9a0e42df4d00bfb4a3cbbe5cf9f54260300c88a0e9af1f47ca5ce17ac0/propcache-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207", size = 47324, upload-time = "2025-10-08T19:46:48.384Z" }, { url = "https://files.pythonhosted.org/packages/9e/d3/6c7ee328b39a81ee877c962469f1e795f9db87f925251efeb0545e0020d0/propcache-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72", size = 225505, upload-time = "2025-10-08T19:46:50.055Z" }, { url = "https://files.pythonhosted.org/packages/01/5d/1c53f4563490b1d06a684742cc6076ef944bc6457df6051b7d1a877c057b/propcache-0.4.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367", size = 230242, upload-time = "2025-10-08T19:46:51.815Z" }, { url = "https://files.pythonhosted.org/packages/20/e1/ce4620633b0e2422207c3cb774a0ee61cac13abc6217763a7b9e2e3f4a12/propcache-0.4.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4", size = 238474, upload-time = "2025-10-08T19:46:53.208Z" }, { url = "https://files.pythonhosted.org/packages/46/4b/3aae6835b8e5f44ea6a68348ad90f78134047b503765087be2f9912140ea/propcache-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf", size = 221575, upload-time = "2025-10-08T19:46:54.511Z" }, { url = "https://files.pythonhosted.org/packages/6e/a5/8a5e8678bcc9d3a1a15b9a29165640d64762d424a16af543f00629c87338/propcache-0.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3", size = 216736, upload-time = "2025-10-08T19:46:56.212Z" }, { url = "https://files.pythonhosted.org/packages/f1/63/b7b215eddeac83ca1c6b934f89d09a625aa9ee4ba158338854c87210cc36/propcache-0.4.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778", size = 213019, upload-time = "2025-10-08T19:46:57.595Z" }, { url = "https://files.pythonhosted.org/packages/57/74/f580099a58c8af587cac7ba19ee7cb418506342fbbe2d4a4401661cca886/propcache-0.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6", size = 220376, upload-time = "2025-10-08T19:46:59.067Z" }, { url = "https://files.pythonhosted.org/packages/c4/ee/542f1313aff7eaf19c2bb758c5d0560d2683dac001a1c96d0774af799843/propcache-0.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9", size = 226988, upload-time = "2025-10-08T19:47:00.544Z" }, { url = "https://files.pythonhosted.org/packages/8f/18/9c6b015dd9c6930f6ce2229e1f02fb35298b847f2087ea2b436a5bfa7287/propcache-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75", size = 215615, upload-time = "2025-10-08T19:47:01.968Z" }, { url = "https://files.pythonhosted.org/packages/80/9e/e7b85720b98c45a45e1fca6a177024934dc9bc5f4d5dd04207f216fc33ed/propcache-0.4.1-cp312-cp312-win32.whl", hash = "sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8", size = 38066, upload-time = "2025-10-08T19:47:03.503Z" }, { url = "https://files.pythonhosted.org/packages/54/09/d19cff2a5aaac632ec8fc03737b223597b1e347416934c1b3a7df079784c/propcache-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db", size = 41655, upload-time = "2025-10-08T19:47:04.973Z" }, { url = "https://files.pythonhosted.org/packages/68/ab/6b5c191bb5de08036a8c697b265d4ca76148efb10fa162f14af14fb5f076/propcache-0.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1", size = 37789, upload-time = "2025-10-08T19:47:06.077Z" }, { url = "https://files.pythonhosted.org/packages/bf/df/6d9c1b6ac12b003837dde8a10231a7344512186e87b36e855bef32241942/propcache-0.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf", size = 77750, upload-time = "2025-10-08T19:47:07.648Z" }, { url = "https://files.pythonhosted.org/packages/8b/e8/677a0025e8a2acf07d3418a2e7ba529c9c33caf09d3c1f25513023c1db56/propcache-0.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311", size = 44780, upload-time = "2025-10-08T19:47:08.851Z" }, { url = "https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74", size = 46308, upload-time = "2025-10-08T19:47:09.982Z" }, { url = "https://files.pythonhosted.org/packages/2d/48/c5ac64dee5262044348d1d78a5f85dd1a57464a60d30daee946699963eb3/propcache-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe", size = 208182, upload-time = "2025-10-08T19:47:11.319Z" }, { url = "https://files.pythonhosted.org/packages/c6/0c/cd762dd011a9287389a6a3eb43aa30207bde253610cca06824aeabfe9653/propcache-0.4.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af", size = 211215, upload-time = "2025-10-08T19:47:13.146Z" }, { url = "https://files.pythonhosted.org/packages/30/3e/49861e90233ba36890ae0ca4c660e95df565b2cd15d4a68556ab5865974e/propcache-0.4.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c", size = 218112, upload-time = "2025-10-08T19:47:14.913Z" }, { url = "https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f", size = 204442, upload-time = "2025-10-08T19:47:16.277Z" }, { url = "https://files.pythonhosted.org/packages/50/a6/4282772fd016a76d3e5c0df58380a5ea64900afd836cec2c2f662d1b9bb3/propcache-0.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1", size = 199398, upload-time = "2025-10-08T19:47:17.962Z" }, { url = "https://files.pythonhosted.org/packages/3e/ec/d8a7cd406ee1ddb705db2139f8a10a8a427100347bd698e7014351c7af09/propcache-0.4.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24", size = 196920, upload-time = "2025-10-08T19:47:19.355Z" }, { url = "https://files.pythonhosted.org/packages/f6/6c/f38ab64af3764f431e359f8baf9e0a21013e24329e8b85d2da32e8ed07ca/propcache-0.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa", size = 203748, upload-time = "2025-10-08T19:47:21.338Z" }, { url = "https://files.pythonhosted.org/packages/d6/e3/fa846bd70f6534d647886621388f0a265254d30e3ce47e5c8e6e27dbf153/propcache-0.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61", size = 205877, upload-time = "2025-10-08T19:47:23.059Z" }, { url = "https://files.pythonhosted.org/packages/e2/39/8163fc6f3133fea7b5f2827e8eba2029a0277ab2c5beee6c1db7b10fc23d/propcache-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66", size = 199437, upload-time = "2025-10-08T19:47:24.445Z" }, { url = "https://files.pythonhosted.org/packages/93/89/caa9089970ca49c7c01662bd0eeedfe85494e863e8043565aeb6472ce8fe/propcache-0.4.1-cp313-cp313-win32.whl", hash = "sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81", size = 37586, upload-time = "2025-10-08T19:47:25.736Z" }, { url = "https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e", size = 40790, upload-time = "2025-10-08T19:47:26.847Z" }, { url = "https://files.pythonhosted.org/packages/59/1b/e71ae98235f8e2ba5004d8cb19765a74877abf189bc53fc0c80d799e56c3/propcache-0.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1", size = 37158, upload-time = "2025-10-08T19:47:27.961Z" }, { url = "https://files.pythonhosted.org/packages/83/ce/a31bbdfc24ee0dcbba458c8175ed26089cf109a55bbe7b7640ed2470cfe9/propcache-0.4.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b", size = 81451, upload-time = "2025-10-08T19:47:29.445Z" }, { url = "https://files.pythonhosted.org/packages/25/9c/442a45a470a68456e710d96cacd3573ef26a1d0a60067e6a7d5e655621ed/propcache-0.4.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566", size = 46374, upload-time = "2025-10-08T19:47:30.579Z" }, { url = "https://files.pythonhosted.org/packages/f4/bf/b1d5e21dbc3b2e889ea4327044fb16312a736d97640fb8b6aa3f9c7b3b65/propcache-0.4.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835", size = 48396, upload-time = "2025-10-08T19:47:31.79Z" }, { url = "https://files.pythonhosted.org/packages/f4/04/5b4c54a103d480e978d3c8a76073502b18db0c4bc17ab91b3cb5092ad949/propcache-0.4.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e", size = 275950, upload-time = "2025-10-08T19:47:33.481Z" }, { url = "https://files.pythonhosted.org/packages/b4/c1/86f846827fb969c4b78b0af79bba1d1ea2156492e1b83dea8b8a6ae27395/propcache-0.4.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859", size = 273856, upload-time = "2025-10-08T19:47:34.906Z" }, { url = "https://files.pythonhosted.org/packages/36/1d/fc272a63c8d3bbad6878c336c7a7dea15e8f2d23a544bda43205dfa83ada/propcache-0.4.1-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b", size = 280420, upload-time = "2025-10-08T19:47:36.338Z" }, { url = "https://files.pythonhosted.org/packages/07/0c/01f2219d39f7e53d52e5173bcb09c976609ba30209912a0680adfb8c593a/propcache-0.4.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0", size = 263254, upload-time = "2025-10-08T19:47:37.692Z" }, { url = "https://files.pythonhosted.org/packages/2d/18/cd28081658ce597898f0c4d174d4d0f3c5b6d4dc27ffafeef835c95eb359/propcache-0.4.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af", size = 261205, upload-time = "2025-10-08T19:47:39.659Z" }, { url = "https://files.pythonhosted.org/packages/7a/71/1f9e22eb8b8316701c2a19fa1f388c8a3185082607da8e406a803c9b954e/propcache-0.4.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393", size = 247873, upload-time = "2025-10-08T19:47:41.084Z" }, { url = "https://files.pythonhosted.org/packages/4a/65/3d4b61f36af2b4eddba9def857959f1016a51066b4f1ce348e0cf7881f58/propcache-0.4.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874", size = 262739, upload-time = "2025-10-08T19:47:42.51Z" }, { url = "https://files.pythonhosted.org/packages/2a/42/26746ab087faa77c1c68079b228810436ccd9a5ce9ac85e2b7307195fd06/propcache-0.4.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7", size = 263514, upload-time = "2025-10-08T19:47:43.927Z" }, { url = "https://files.pythonhosted.org/packages/94/13/630690fe201f5502d2403dd3cfd451ed8858fe3c738ee88d095ad2ff407b/propcache-0.4.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1", size = 257781, upload-time = "2025-10-08T19:47:45.448Z" }, { url = "https://files.pythonhosted.org/packages/92/f7/1d4ec5841505f423469efbfc381d64b7b467438cd5a4bbcbb063f3b73d27/propcache-0.4.1-cp313-cp313t-win32.whl", hash = "sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717", size = 41396, upload-time = "2025-10-08T19:47:47.202Z" }, { url = "https://files.pythonhosted.org/packages/48/f0/615c30622316496d2cbbc29f5985f7777d3ada70f23370608c1d3e081c1f/propcache-0.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37", size = 44897, upload-time = "2025-10-08T19:47:48.336Z" }, { url = "https://files.pythonhosted.org/packages/fd/ca/6002e46eccbe0e33dcd4069ef32f7f1c9e243736e07adca37ae8c4830ec3/propcache-0.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a", size = 39789, upload-time = "2025-10-08T19:47:49.876Z" }, { url = "https://files.pythonhosted.org/packages/8e/5c/bca52d654a896f831b8256683457ceddd490ec18d9ec50e97dfd8fc726a8/propcache-0.4.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12", size = 78152, upload-time = "2025-10-08T19:47:51.051Z" }, { url = "https://files.pythonhosted.org/packages/65/9b/03b04e7d82a5f54fb16113d839f5ea1ede58a61e90edf515f6577c66fa8f/propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c", size = 44869, upload-time = "2025-10-08T19:47:52.594Z" }, { url = "https://files.pythonhosted.org/packages/b2/fa/89a8ef0468d5833a23fff277b143d0573897cf75bd56670a6d28126c7d68/propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded", size = 46596, upload-time = "2025-10-08T19:47:54.073Z" }, { url = "https://files.pythonhosted.org/packages/86/bd/47816020d337f4a746edc42fe8d53669965138f39ee117414c7d7a340cfe/propcache-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641", size = 206981, upload-time = "2025-10-08T19:47:55.715Z" }, { url = "https://files.pythonhosted.org/packages/df/f6/c5fa1357cc9748510ee55f37173eb31bfde6d94e98ccd9e6f033f2fc06e1/propcache-0.4.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4", size = 211490, upload-time = "2025-10-08T19:47:57.499Z" }, { url = "https://files.pythonhosted.org/packages/80/1e/e5889652a7c4a3846683401a48f0f2e5083ce0ec1a8a5221d8058fbd1adf/propcache-0.4.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44", size = 215371, upload-time = "2025-10-08T19:47:59.317Z" }, { url = "https://files.pythonhosted.org/packages/b2/f2/889ad4b2408f72fe1a4f6a19491177b30ea7bf1a0fd5f17050ca08cfc882/propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d", size = 201424, upload-time = "2025-10-08T19:48:00.67Z" }, { url = "https://files.pythonhosted.org/packages/27/73/033d63069b57b0812c8bd19f311faebeceb6ba31b8f32b73432d12a0b826/propcache-0.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b", size = 197566, upload-time = "2025-10-08T19:48:02.604Z" }, { url = "https://files.pythonhosted.org/packages/dc/89/ce24f3dc182630b4e07aa6d15f0ff4b14ed4b9955fae95a0b54c58d66c05/propcache-0.4.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e", size = 193130, upload-time = "2025-10-08T19:48:04.499Z" }, { url = "https://files.pythonhosted.org/packages/a9/24/ef0d5fd1a811fb5c609278d0209c9f10c35f20581fcc16f818da959fc5b4/propcache-0.4.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f", size = 202625, upload-time = "2025-10-08T19:48:06.213Z" }, { url = "https://files.pythonhosted.org/packages/f5/02/98ec20ff5546f68d673df2f7a69e8c0d076b5abd05ca882dc7ee3a83653d/propcache-0.4.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49", size = 204209, upload-time = "2025-10-08T19:48:08.432Z" }, { url = "https://files.pythonhosted.org/packages/a0/87/492694f76759b15f0467a2a93ab68d32859672b646aa8a04ce4864e7932d/propcache-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144", size = 197797, upload-time = "2025-10-08T19:48:09.968Z" }, { url = "https://files.pythonhosted.org/packages/ee/36/66367de3575db1d2d3f3d177432bd14ee577a39d3f5d1b3d5df8afe3b6e2/propcache-0.4.1-cp314-cp314-win32.whl", hash = "sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f", size = 38140, upload-time = "2025-10-08T19:48:11.232Z" }, { url = "https://files.pythonhosted.org/packages/0c/2a/a758b47de253636e1b8aef181c0b4f4f204bf0dd964914fb2af90a95b49b/propcache-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153", size = 41257, upload-time = "2025-10-08T19:48:12.707Z" }, { url = "https://files.pythonhosted.org/packages/34/5e/63bd5896c3fec12edcbd6f12508d4890d23c265df28c74b175e1ef9f4f3b/propcache-0.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992", size = 38097, upload-time = "2025-10-08T19:48:13.923Z" }, { url = "https://files.pythonhosted.org/packages/99/85/9ff785d787ccf9bbb3f3106f79884a130951436f58392000231b4c737c80/propcache-0.4.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f", size = 81455, upload-time = "2025-10-08T19:48:15.16Z" }, { url = "https://files.pythonhosted.org/packages/90/85/2431c10c8e7ddb1445c1f7c4b54d886e8ad20e3c6307e7218f05922cad67/propcache-0.4.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393", size = 46372, upload-time = "2025-10-08T19:48:16.424Z" }, { url = "https://files.pythonhosted.org/packages/01/20/b0972d902472da9bcb683fa595099911f4d2e86e5683bcc45de60dd05dc3/propcache-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0", size = 48411, upload-time = "2025-10-08T19:48:17.577Z" }, { url = "https://files.pythonhosted.org/packages/e2/e3/7dc89f4f21e8f99bad3d5ddb3a3389afcf9da4ac69e3deb2dcdc96e74169/propcache-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a", size = 275712, upload-time = "2025-10-08T19:48:18.901Z" }, { url = "https://files.pythonhosted.org/packages/20/67/89800c8352489b21a8047c773067644e3897f02ecbbd610f4d46b7f08612/propcache-0.4.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be", size = 273557, upload-time = "2025-10-08T19:48:20.762Z" }, { url = "https://files.pythonhosted.org/packages/e2/a1/b52b055c766a54ce6d9c16d9aca0cad8059acd9637cdf8aa0222f4a026ef/propcache-0.4.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc", size = 280015, upload-time = "2025-10-08T19:48:22.592Z" }, { url = "https://files.pythonhosted.org/packages/48/c8/33cee30bd890672c63743049f3c9e4be087e6780906bfc3ec58528be59c1/propcache-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a", size = 262880, upload-time = "2025-10-08T19:48:23.947Z" }, { url = "https://files.pythonhosted.org/packages/0c/b1/8f08a143b204b418285c88b83d00edbd61afbc2c6415ffafc8905da7038b/propcache-0.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89", size = 260938, upload-time = "2025-10-08T19:48:25.656Z" }, { url = "https://files.pythonhosted.org/packages/cf/12/96e4664c82ca2f31e1c8dff86afb867348979eb78d3cb8546a680287a1e9/propcache-0.4.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726", size = 247641, upload-time = "2025-10-08T19:48:27.207Z" }, { url = "https://files.pythonhosted.org/packages/18/ed/e7a9cfca28133386ba52278136d42209d3125db08d0a6395f0cba0c0285c/propcache-0.4.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367", size = 262510, upload-time = "2025-10-08T19:48:28.65Z" }, { url = "https://files.pythonhosted.org/packages/f5/76/16d8bf65e8845dd62b4e2b57444ab81f07f40caa5652b8969b87ddcf2ef6/propcache-0.4.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36", size = 263161, upload-time = "2025-10-08T19:48:30.133Z" }, { url = "https://files.pythonhosted.org/packages/e7/70/c99e9edb5d91d5ad8a49fa3c1e8285ba64f1476782fed10ab251ff413ba1/propcache-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455", size = 257393, upload-time = "2025-10-08T19:48:31.567Z" }, { url = "https://files.pythonhosted.org/packages/08/02/87b25304249a35c0915d236575bc3574a323f60b47939a2262b77632a3ee/propcache-0.4.1-cp314-cp314t-win32.whl", hash = "sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85", size = 42546, upload-time = "2025-10-08T19:48:32.872Z" }, { url = "https://files.pythonhosted.org/packages/cb/ef/3c6ecf8b317aa982f309835e8f96987466123c6e596646d4e6a1dfcd080f/propcache-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1", size = 46259, upload-time = "2025-10-08T19:48:34.226Z" }, { url = "https://files.pythonhosted.org/packages/c4/2d/346e946d4951f37eca1e4f55be0f0174c52cd70720f84029b02f296f4a38/propcache-0.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9", size = 40428, upload-time = "2025-10-08T19:48:35.441Z" }, { url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" }, ] [[package]] name = "pycparser" version = "3.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size = 103492, upload-time = "2026-01-21T14:26:51.89Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" }, ] [[package]] name = "pygments" version = "2.21.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/49/2e/ced460408999b33da6b31b0021b0f37d329e202d4169aeb164493778f25b/pygments-2.21.0.tar.gz", hash = "sha256:610ca751c9bc2492b38eb9a38a7fbc93edbbb2d7182edaf34e66ae493dee5c8c", size = 5005329, upload-time = "2026-08-17T08:02:48.824Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/71/46/17f022dd3e953bf20a04a028a21ec746d942f8d2af30fa0f124fa0e6a684/pygments-2.21.0-py3-none-any.whl", hash = "sha256:2363c69b61c4a97c838da3b130dcd6468f4848992b21a82f2a63ec34377137d9", size = 1250147, upload-time = "2026-08-17T08:02:44.912Z" }, ] [[package]] name = "pyinstrument" version = "5.1.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/a0/05/5b79b16712f9b7c497f2137868908e5d38646a8ef7871d6008801e6e18a3/pyinstrument-5.1.3.tar.gz", hash = "sha256:93dc5576fa90bb267c46d864712329e8e057f51a6b15d0b4f917558d82066ba7", size = 262250, upload-time = "2026-07-29T17:18:39.748Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/f9/73/474b513a521b14b5fc58e7f191061bee78192deec4e22c8dc8d6ddeec628/pyinstrument-5.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:157aa322ceb07c2b990591c48b60a66482cad1026fdd53debd9f9ce7afb9b326", size = 126610, upload-time = "2026-07-29T17:17:28.755Z" }, { url = "https://files.pythonhosted.org/packages/3e/75/a2ba3a91600191492391f0ba997ae781c0c8791f01fc31ab381cba03318d/pyinstrument-5.1.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cd1a74b9dec4fafc4cf4dd1df9cda56a83b7cb3e3826236044edaae2a2d6edbe", size = 119854, upload-time = "2026-07-29T17:17:29.971Z" }, { url = "https://files.pythonhosted.org/packages/69/c7/dbb65c0e0c6dc189471607e580af8c44daf007949f99a9563489aaa7363b/pyinstrument-5.1.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:21b1486d8493b81fdef30e833ba4856785c34a79c9aea29c91bff5003a84e40a", size = 143448, upload-time = "2026-07-29T17:17:31.206Z" }, { url = "https://files.pythonhosted.org/packages/e0/50/e77726eac04a5070ebb69ad9456c0a5649c1b3fa9870504f3a49fd3a975d/pyinstrument-5.1.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c4bedf32ff7fd56fbd5d5e9ccd771bb27884faab312a990685a2d5e97c83f882", size = 141909, upload-time = "2026-07-29T17:17:32.619Z" }, { url = "https://files.pythonhosted.org/packages/d8/ba/7766a636c1afa7a844054a077f9dd05aa70c2bcaa2ca4573c079d1f7be56/pyinstrument-5.1.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:472a547412c78b7d783f28d7cdca7cdc870d172444a29078652a2e5bca406741", size = 142562, upload-time = "2026-07-29T17:17:34.118Z" }, { url = "https://files.pythonhosted.org/packages/6c/ea/edb64ef7b0d9de1fc2458b4f9c22fda82f33781f93510a3bc8cff591611c/pyinstrument-5.1.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7b31be199d1da29b19c522cafeef0e0778f2c8c4be349b56e17ff93b5ca8eff9", size = 141737, upload-time = "2026-07-29T17:17:35.742Z" }, { url = "https://files.pythonhosted.org/packages/2c/d3/d7f48a894f1a2a147263b892ee019b0c5bda38105ded85799a3ae53ca248/pyinstrument-5.1.3-cp311-cp311-win32.whl", hash = "sha256:6a4d948fd53df2891986a6c539ad463db729c4528dea4c16a7f995fe719758a2", size = 120618, upload-time = "2026-07-29T17:17:37.152Z" }, { url = "https://files.pythonhosted.org/packages/80/b9/cc9a9dc3e055840b477b1b147985f6ae251e5eebeaa257ff43ecd80c1c86/pyinstrument-5.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:fc46be132af558e9381383bacfe986da5abb9e1129151dc6ac760d8e4e420e0d", size = 121409, upload-time = "2026-07-29T17:17:38.443Z" }, { url = "https://files.pythonhosted.org/packages/83/7a/cf24adef45bdfa9dc59371713f960c449663ae90cbe0435ce353b38e3c8d/pyinstrument-5.1.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:eef82fd717e38c821b2276f50aa9812825036f03e7b345f2969dd264214cfc60", size = 126756, upload-time = "2026-07-29T17:17:39.758Z" }, { url = "https://files.pythonhosted.org/packages/89/bd/ef19f60fb92c800d5d9c12f09d86e541fdec794d98840fb2996d462d4d1d/pyinstrument-5.1.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:58009e21257ed0e139a666dfc628a6fa6a734fca3ec7bde77d51d43fc4947d7b", size = 119832, upload-time = "2026-07-29T17:17:40.972Z" }, { url = "https://files.pythonhosted.org/packages/48/5c/ed9d97b6c405580e18f304b613f482d1f5c7b52a18c3b4154ad0a1841e0c/pyinstrument-5.1.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6cbef7ea81fa11bbca1b0bbf9d1d56bf2da96b3f675b593142c8772f7d0dc35", size = 145074, upload-time = "2026-07-29T17:17:42.305Z" }, { url = "https://files.pythonhosted.org/packages/d7/6e/cd47fa4c2fef0d86a25684f0857df854155dfd2492bbbedd33b6c07f0578/pyinstrument-5.1.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4db9ebe8242038bf9f60c623bac0811611e54363a2fe33b79448b548b9108bef", size = 143859, upload-time = "2026-07-29T17:17:43.812Z" }, { url = "https://files.pythonhosted.org/packages/67/72/e471ce7be3332143f4fbf9886c3ed0726792d2d533d4c130682f611bbe90/pyinstrument-5.1.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f16e1501e9d3a423b837aacc0b6ce9fa7c2fbf5e0e73a7afe9847912d805594c", size = 143948, upload-time = "2026-07-29T17:17:45.056Z" }, { url = "https://files.pythonhosted.org/packages/fe/d6/1225f67d8da66c93ebdbf97081f9169b52d16c2e4453477f4f7e2de70879/pyinstrument-5.1.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c027d490a6caa2f18bf92ceecc46ab8580c8eee772af34b04c61c18fb4adf853", size = 143561, upload-time = "2026-07-29T17:17:46.329Z" }, { url = "https://files.pythonhosted.org/packages/16/85/e6da5dbcb4890f40e06500f55344b3361a54fb6773fc9fc63f3ba30ee47f/pyinstrument-5.1.3-cp312-cp312-win32.whl", hash = "sha256:5a5c2d30f255f0a84f9b5cd53e17877e3e73b921d34b395f17a206f85fda2cfc", size = 120745, upload-time = "2026-07-29T17:17:47.623Z" }, { url = "https://files.pythonhosted.org/packages/c3/fd/617fc91f97d617db558a0d863aaf9101f12203017ca2a07f11618a7094ef/pyinstrument-5.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1ad617768b3c35acc4db89b5130fc0b98ce763f3a42dde255447bed3bd40d306", size = 121486, upload-time = "2026-07-29T17:17:48.881Z" }, { url = "https://files.pythonhosted.org/packages/0c/37/5b9b4341a62fcb80206c8d179d8dfc6fe5574eed24c9035c44913430542e/pyinstrument-5.1.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:4d53b7f120d2643161c1508bcef2789009dca9565360d6e6b06bf598d29b246b", size = 126759, upload-time = "2026-07-29T17:17:50.119Z" }, { url = "https://files.pythonhosted.org/packages/54/bf/b0de56cf307f27d4ab459db8c0a05e1b660acf55b23b1ae810c830d9c235/pyinstrument-5.1.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7077446b490c73b6c1fbb4324c409f841914c032667ad395b8658c0bf742727b", size = 119829, upload-time = "2026-07-29T17:17:51.5Z" }, { url = "https://files.pythonhosted.org/packages/45/c5/bf2ff35d059a0ab2d61659ca7deb085daea41da39bde2c1b93f628ac8628/pyinstrument-5.1.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:06c26c65a4cd5699c7c3a7f41f372e9785d511ff0113ec39723c7bf0340e989c", size = 145216, upload-time = "2026-07-29T17:17:52.723Z" }, { url = "https://files.pythonhosted.org/packages/10/e3/1bc53c5fe87872fbd446191d115b2860366842f5699f6173ff6a1eddfbf6/pyinstrument-5.1.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4551c8fee6586f3ef01712d4dffcb9c38ae79d1dbc16fe9416e8ec60c88158c", size = 144041, upload-time = "2026-07-29T17:17:54.008Z" }, { url = "https://files.pythonhosted.org/packages/f4/c8/4b17e9e44bf192733e63ba679dcaff936cc5dfb8575ca8f961dcd19609d9/pyinstrument-5.1.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7021c95837d37dee2c05c4aa6ad7cf73ecc9b4c2bf040ce58897a9fcdaa36d8f", size = 144056, upload-time = "2026-07-29T17:17:55.4Z" }, { url = "https://files.pythonhosted.org/packages/01/f5/b05f1b1754aed92674a25083b8409a043755d49720bdc7e6319261b9fb6e/pyinstrument-5.1.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bdef704955e2dbbcf2b3f3dd574847996ff4cf1f2fb3a9c847e7c2e7182b6a19", size = 143702, upload-time = "2026-07-29T17:17:56.688Z" }, { url = "https://files.pythonhosted.org/packages/2e/1a/9e969ec59679f786aa9148642231c33324280e91d9ac2803687ea7c3b24b/pyinstrument-5.1.3-cp313-cp313-win32.whl", hash = "sha256:6e2b51ac576fdad9e2988636eee827c285de8c890867d305f9ebf7ce95f98bd0", size = 120749, upload-time = "2026-07-29T17:17:58.167Z" }, { url = "https://files.pythonhosted.org/packages/41/58/a2ad5dabb859634b60e17ddf3d3ab4c8ecd8d1ce1595392017c9480949aa/pyinstrument-5.1.3-cp313-cp313-win_amd64.whl", hash = "sha256:b4e48616d28606bf3c4b04d4369582c7802b23b38eacc62d7ea88f0145673387", size = 121493, upload-time = "2026-07-29T17:17:59.468Z" }, { url = "https://files.pythonhosted.org/packages/06/72/50f166caf3e4738e5df2dfcd32acf9d8c876c9b1ab2be94bd55d70787350/pyinstrument-5.1.3-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8c226b6680f20fc73430cbf71dff4be7d8daa926e9a21d563fbd632c8f49d993", size = 126746, upload-time = "2026-07-29T17:18:00.762Z" }, { url = "https://files.pythonhosted.org/packages/db/74/db134b2591a6e7354b60a6fd725b0dc896a7806978f64f158561e3344af2/pyinstrument-5.1.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:fb60379831d241155f2a271113bbdde1922a75bedbd1b8ad8a7647f84bde905c", size = 119838, upload-time = "2026-07-29T17:18:02.259Z" }, { url = "https://files.pythonhosted.org/packages/19/87/79966a8f00ac793562c196736b98eee60b8f3b017ee27b4576a21a2c441f/pyinstrument-5.1.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8bbda7c2ead7fc6eb686239c3c1141e6f99ed7427ba3b9223b3f53c4dd78de22", size = 144977, upload-time = "2026-07-29T17:18:03.675Z" }, { url = "https://files.pythonhosted.org/packages/17/d1/ce37a48a4148c76ee820dacc9c41c14530d618ab569edfe30138715f6116/pyinstrument-5.1.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:350c05b72ef6e5158c9414d11225742da767f15669f9f23f674e702b42b9fa76", size = 143732, upload-time = "2026-07-29T17:18:05.364Z" }, { url = "https://files.pythonhosted.org/packages/e1/bf/870ea051433b7f46c9e6a0e1bbae29564aa945e1c4a61a120066a53c29dd/pyinstrument-5.1.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:24b9e35f8586d68e53f16ff09fc5a932b21be3b3b973c6afd7bb073df6e14028", size = 143866, upload-time = "2026-07-29T17:18:06.65Z" }, { url = "https://files.pythonhosted.org/packages/55/0f/e19480d1e683c942463790a9f911f0890a014925db2652ab1c9619e136bb/pyinstrument-5.1.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:067811d732f731e88c715820f893896d7f1083af23a8813d81b46b8f6754be44", size = 143484, upload-time = "2026-07-29T17:18:07.986Z" }, { url = "https://files.pythonhosted.org/packages/56/8a/e260494a5dfd31e4628a02e7790b6f631313bbd98ca6bf7c15d9d6f4ae1c/pyinstrument-5.1.3-cp314-cp314-win32.whl", hash = "sha256:f5aca86d05f40f50720ba1edfd3acac23023292b902d50f6f2a3039d7b1f6413", size = 121366, upload-time = "2026-07-29T17:18:09.519Z" }, { url = "https://files.pythonhosted.org/packages/90/c2/39cd36da0d87b06e23666e5a375dc2918b55007f6bb8039d5bc7fd5cd9f3/pyinstrument-5.1.3-cp314-cp314-win_amd64.whl", hash = "sha256:cbfb924a0a9a4762388d16e9ed3dd0fb9db5d94bf433c3099d251707de4b94bd", size = 122160, upload-time = "2026-07-29T17:18:10.94Z" }, { url = "https://files.pythonhosted.org/packages/79/ee/11f6c8d11b954811f08ed66c814f28b7992d7bdcde6b259a921ef0efc5b7/pyinstrument-5.1.3-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:3cbe8e7b3b9306eb5e954a7722f87da9ad0cc396ffde65272aed3a3cf9389db1", size = 127640, upload-time = "2026-07-29T17:18:12.149Z" }, { url = "https://files.pythonhosted.org/packages/55/51/bea43b2667324e56a1f85abd2403663e34cd0fbc0fee7272aa11446eb7da/pyinstrument-5.1.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:26a2f33b682bca12fffcefccbfc373d516599c7a437df94a8f5f2d8f44e42415", size = 120278, upload-time = "2026-07-29T17:18:13.451Z" }, { url = "https://files.pythonhosted.org/packages/4d/55/49c32296eb6730e98736189dbfe369fc45deea1a166e3db4518c74d62f24/pyinstrument-5.1.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4ed0d243579d9f8690deed04d10a2001208fc5775ccf39c52137a4ae9627c750", size = 152785, upload-time = "2026-07-29T17:18:14.872Z" }, { url = "https://files.pythonhosted.org/packages/68/b1/8181fad7ea01b40c7f75b95802c406a06c0d0a11f8f496f625a471523bae/pyinstrument-5.1.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ec5df769cc2d4dc01c54fb05b28132f17691e914330fc4ba88e29a42b12e73c7", size = 150470, upload-time = "2026-07-29T17:18:16.275Z" }, { url = "https://files.pythonhosted.org/packages/a8/3b/3634f5438cc6cd7bce17b5bf369eb004b196cda89d46ba6168bacfbb385d/pyinstrument-5.1.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:23e3cedb558eacd2422c1258e016a89d057c15db0c21f892c3f6e5fd4a6d12b2", size = 150561, upload-time = "2026-07-29T17:18:17.529Z" }, { url = "https://files.pythonhosted.org/packages/6d/e4/a9c41f24bb9c3d3db66cdd645fe1178533954491f5c3cc9645c1f987635d/pyinstrument-5.1.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fcdc41a648a7c6c420c507998f00134639c2a0c6097904a33b859938a3340031", size = 149366, upload-time = "2026-07-29T17:18:19Z" }, { url = "https://files.pythonhosted.org/packages/87/b4/59d67f48adca36a6b2eb9c11cd90adef264c593b4b435c48f62b3241ef3e/pyinstrument-5.1.3-cp314-cp314t-win32.whl", hash = "sha256:dd4199f016827bda29d571b7c4e7c2ae968b881611da13b4e3c1991882f04445", size = 121735, upload-time = "2026-07-29T17:18:20.272Z" }, { url = "https://files.pythonhosted.org/packages/dd/ca/e5b233969e15f600f3f0a03ed8d8e7f02e28d6d66cc9cdd1ce21cdcbba22/pyinstrument-5.1.3-cp314-cp314t-win_amd64.whl", hash = "sha256:1d66dd832db458f81ca71fbe5fa97dbeb0bfb930d8bde4ea650523ce61dc7ec9", size = 122519, upload-time = "2026-07-29T17:18:21.523Z" }, { url = "https://files.pythonhosted.org/packages/4d/7e/94412787ed5320450664baf66bb2f46a0f0fec21742ef9701c8399cbc026/pyinstrument-5.1.3-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:a8bae0a0bf1ec2e54bd7a3a456395e1a1e695c53e06252b8e6f43b2c5f344139", size = 120787, upload-time = "2026-07-29T17:18:34.006Z" }, { url = "https://files.pythonhosted.org/packages/01/a5/43e397d6f1f2eecf8ac82e6c2ccb252493cfd413776bd094e4e770d4f762/pyinstrument-5.1.3-graalpy312-graalpy250_312_native-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c8b8a126894ea5553a7a565f86e26ae3c56a7b0a7c73422fbd382de3a34a1480", size = 123272, upload-time = "2026-07-29T17:18:35.447Z" }, { url = "https://files.pythonhosted.org/packages/2b/47/a51976758124654e18d1c11a2dcd6811a7a9c4e03f50d9ee8438e4fe6d20/pyinstrument-5.1.3-graalpy312-graalpy250_312_native-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e72d5db0bdc8488eba396a5447bdc7ecff067cbd4d7ca8f1d7b862dae0e9c2f6", size = 122216, upload-time = "2026-07-29T17:18:36.748Z" }, { url = "https://files.pythonhosted.org/packages/50/b2/f4708a7e1f7ad1777ed8b559b3ff08f1ed52059205c704d6e12bb941caa1/pyinstrument-5.1.3-graalpy312-graalpy250_312_native-win_amd64.whl", hash = "sha256:8f6d68350a2314222f85e32ccc519b69bcd41c82349e7b280ba5ebb473a5633a", size = 121850, upload-time = "2026-07-29T17:18:38.05Z" }, ] [[package]] name = "pymdown-extensions" version = "11.0.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown" }, { name = "pyyaml" }, ] sdist = { url = "https://files.pythonhosted.org/packages/21/a9/5f0c535ba3b08fe09270c16808e053a968868242ecbd5676d4e3a488bf28/pymdown_extensions-11.0.1.tar.gz", hash = "sha256:dd2905ae6fc5b75582fafb139a1266ffc754705efa902aa50067fa7ff4f94ec0", size = 857113, upload-time = "2026-07-02T17:59:22.955Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/d6/54/da572c98c0b77626a91b5d3b89f0231d8bff5125c225420908632f8b342d/pymdown_extensions-11.0.1-py3-none-any.whl", hash = "sha256:db3943a62bab7e03af1364f0c4083e64b91fb097675a4b6cceccfbe9a77e5eb2", size = 269455, upload-time = "2026-07-02T17:59:21.271Z" }, ] [[package]] name = "pytest" version = "9.1.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, { name = "pygments" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, ] [[package]] name = "pytest-codspeed" version = "5.0.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, { name = "rich" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e1/b4/cf932fcd1960a2fd6d9b09eb403253a8709aeee975961afa6299239a830e/pytest_codspeed-5.0.3.tar.gz", hash = "sha256:91afef90e6a96b013495e4702ef5d6358614a449e71008cdc194ef668778b92f", size = 324571, upload-time = "2026-05-22T16:20:49.231Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ac/ef/32ce60d42a4aa43e728d988e13eb6568fbc7b10a514517b459bafd3f2b94/pytest_codspeed-5.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f56d0339cd98d26f6e561987be25bdd2761a5d53d8f73493b1ebe02d0d451093", size = 366253, upload-time = "2026-05-22T16:21:10.013Z" }, { url = "https://files.pythonhosted.org/packages/2a/15/c66ef90a793c5d2c039e63a1726a5e55c678be2618b0f5f1660d0f79e25f/pytest_codspeed-5.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c682f6645d4eb472f3bd95dbda1805e3af4243610572cb7d6bf94a88e8a0b6c", size = 932465, upload-time = "2026-05-22T16:20:34.265Z" }, { url = "https://files.pythonhosted.org/packages/1a/7b/d231279301967f05b7909160489e85ee3a1b9da76094ea25343faba1abc2/pytest_codspeed-5.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f852bee785a7a124cb1720b1915670c6742af87747dc4d838f3ffdbd365ce9d9", size = 934925, upload-time = "2026-05-22T16:20:47.63Z" }, { url = "https://files.pythonhosted.org/packages/c2/22/456c48160b761d5028c8afa119f085a9fc42855a783a13d73918078969f0/pytest_codspeed-5.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2eeb25fb1ac3f73c4de50e739e78fea396b89782bdb740bf2a7cd2df21f8d4ee", size = 366255, upload-time = "2026-05-22T16:20:56.214Z" }, { url = "https://files.pythonhosted.org/packages/74/33/ac7441fa937c9d9f158083a8c46920a5a5c81ed3c5f96240fc8d650db5c2/pytest_codspeed-5.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:73c5c9d98a3372a42611989ccfa437cce3842431ac6d6b9ab42c4f0e59c070f7", size = 932325, upload-time = "2026-05-22T16:21:08.814Z" }, { url = "https://files.pythonhosted.org/packages/77/bc/8b994adcb9e9016e7d9a808056a3dd9cca21441e432ef456eae2b697d7fe/pytest_codspeed-5.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a2e0ab65df73e837666d12357280ca50ff6d6ac03ea5266703be518b68170edf", size = 934885, upload-time = "2026-05-22T16:21:01.444Z" }, { url = "https://files.pythonhosted.org/packages/dc/8e/e032451e9e0a06b0c4bff53105f62b693d9a54595dd8c024693741ce3380/pytest_codspeed-5.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6524c57fec279a22ffef6112af404036afc71b4704758ae9f0abda429b8478d4", size = 366253, upload-time = "2026-05-22T16:20:46.192Z" }, { url = "https://files.pythonhosted.org/packages/a9/7b/ae76fd8ac656b9695806a6aafd5f22ec32e6ce20e266a58f9112e01d3cd8/pytest_codspeed-5.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c383c9121deb58a69f174188e9e4488ffc0daced0ed276abf87747182511901", size = 932360, upload-time = "2026-05-22T16:20:30.589Z" }, { url = "https://files.pythonhosted.org/packages/a6/4a/dfd43d943fdb143be4fd62f34c2793ba349dc27aa188e521d19d629aa7ab/pytest_codspeed-5.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a4bcdb4b6522738152885ef067e0c8524d5699828d780fb6f464cdb3db44369c", size = 934928, upload-time = "2026-05-22T16:20:38.62Z" }, { url = "https://files.pythonhosted.org/packages/04/6a/fdcec19c7f267c195f147c51d3fd2245f6b8d09b80495ed0a90c008e0842/pytest_codspeed-5.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:25464363c7f9b9bd5022e969c0addba616fa40ac9b8f0fc9e030c4538863b32d", size = 366259, upload-time = "2026-05-22T16:21:06.039Z" }, { url = "https://files.pythonhosted.org/packages/6a/96/c6b03b81dcd21ae3d6b32cca0b3c10149fa378eb21b338d4b63c9eb8050b/pytest_codspeed-5.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:efd43f82ea03ced8488a767ded9473f050791ab7783ea8654107e1e0ac66af40", size = 932395, upload-time = "2026-05-22T16:21:04.804Z" }, { url = "https://files.pythonhosted.org/packages/96/08/56ad8f1cc7d6962f8a680141b361e93467a2abc53d976cd9d5e1edd740e3/pytest_codspeed-5.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:782f9985b6f6b45b8bc20152d206d3a52b56dd088ba81cb70a71f0b39841be9e", size = 934994, upload-time = "2026-05-22T16:20:28.809Z" }, { url = "https://files.pythonhosted.org/packages/0b/54/9096c4545f09da94b1b00f3be2fe4952949e86c9bcafca9a29b26aed1a75/pytest_codspeed-5.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9aa0815b90196f3c20d736ea8691381e97f12bbe8c7d87af10a351e434b452cb", size = 366311, upload-time = "2026-05-22T16:20:41.791Z" }, { url = "https://files.pythonhosted.org/packages/a7/3c/24c53f67a38ad48cb087105ac30a8aa0923223ee274ea9bf2dc705edaa59/pytest_codspeed-5.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:85505c96a3477c346ec2d2b7dced8478f4c651e2b1666ee102d53a832b511853", size = 933169, upload-time = "2026-05-22T16:20:43.178Z" }, { url = "https://files.pythonhosted.org/packages/d1/de/2213f868fa7694f743f96cccbc07e757f45c920c523cccc2da97bc8652df/pytest_codspeed-5.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20eba63765be9d1b6cacbbfad84b87d49eb04b357a7045a0899880da181f81e3", size = 935522, upload-time = "2026-05-22T16:21:03.398Z" }, { url = "https://files.pythonhosted.org/packages/df/85/5dfea1c031d6cccc11653464828edf205c30f798caf5b2a85375aacd914a/pytest_codspeed-5.0.3-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:ec9fa6f0af0a9feb0e0bd517fb59ef28f806fbd50c0c6900ac26cbb4d080eba5", size = 366275, upload-time = "2026-05-22T16:20:59.463Z" }, { url = "https://files.pythonhosted.org/packages/3c/2b/af4d1b612f03b98a6cf3c7d5f62678917a60110a8bf380d49ab408b31137/pytest_codspeed-5.0.3-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8df77b3409f54f4a268f77f3ff74992fe1d995cdbaf2cecf8ad74d32db217ce7", size = 932537, upload-time = "2026-05-22T16:20:54.945Z" }, { url = "https://files.pythonhosted.org/packages/f5/a2/c7ec45e36a61b418efb2a3cccaa67a0c2fcf1f21d5880f64c33114f0c249/pytest_codspeed-5.0.3-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a5d8695a227ea1c3a41d25db5b3fe720bf1b4808bd38862be811a4efd902c792", size = 934153, upload-time = "2026-05-22T16:21:07.494Z" }, { url = "https://files.pythonhosted.org/packages/cf/c7/d5bada9618a0af56a5c8065fc61280849cab8e7c1e24025807a51c3157ce/pytest_codspeed-5.0.3-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:bf4cc4178cbace8f4d2bd240408276bc4da3850ac5fcb5fb5f8a74ab417615bb", size = 366339, upload-time = "2026-05-22T16:20:51.968Z" }, { url = "https://files.pythonhosted.org/packages/a8/37/fb27aeb40a81320e7349553b877a21333c897b27c8dfe215630452908f36/pytest_codspeed-5.0.3-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:abe793da40f87295d33988673d34f06ea569848b44490b847552cd416816258a", size = 933055, upload-time = "2026-05-22T16:20:44.861Z" }, { url = "https://files.pythonhosted.org/packages/f3/d9/6f2d69e96deaf0475a695fc9195af59e7a3b5fab50782855e65c63a7bc28/pytest_codspeed-5.0.3-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c3a9ed38dfa776443b86f4b49a982e8443d0953db4974bd2673d63cc904ae1ad", size = 934481, upload-time = "2026-05-22T16:20:58.264Z" }, { url = "https://files.pythonhosted.org/packages/c5/b2/1d2a993c532146dce9eca5b5942d51898021c3579ce18b2454f932a915f8/pytest_codspeed-5.0.3-py3-none-any.whl", hash = "sha256:fe2ea83c924c2250675b75686c3ee456b8cf0208d83d552e182a195fdf467378", size = 74033, upload-time = "2026-05-22T16:20:26.814Z" }, ] [[package]] name = "pytest-httpbin" version = "2.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "httpbin" }, ] sdist = { url = "https://files.pythonhosted.org/packages/43/83/23b510bb5f20b1982f010dbf82d17e21f701470033e2f4d952ce6cf7a1c6/pytest_httpbin-2.1.0.tar.gz", hash = "sha256:d40579838443228327f9fe4f08d9338bee8885c29fe933e5f2d58c20a26c33c6", size = 13664, upload-time = "2024-09-18T15:35:58.222Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/0d/97/149289c7123f75e98edc94872545c2f597f349ee037b1e0a47aef0362fd4/pytest_httpbin-2.1.0-py3-none-any.whl", hash = "sha256:b3bf7346cc2ad231447189cd85b458e341056684a7a69d69533dd29692209cdd", size = 8309, upload-time = "2024-09-18T15:35:56.86Z" }, ] [[package]] name = "pytest-trio" version = "0.8.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "outcome" }, { name = "pytest" }, { name = "trio" }, ] sdist = { url = "https://files.pythonhosted.org/packages/13/08/056279526554c6c6e6ad6d4a479a338d14dc785ac30be8bdc6ca0153c1be/pytest-trio-0.8.0.tar.gz", hash = "sha256:8363db6336a79e6c53375a2123a41ddbeccc4aa93f93788651641789a56fb52e", size = 46525, upload-time = "2022-11-01T17:24:29.352Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/e9/22/71953f47e0da5852c899f58cd7a31e6100f37c632b7b9ee52d067613a844/pytest_trio-0.8.0-py3-none-any.whl", hash = "sha256:e6a7e7351ae3e8ec3f4564d30ee77d1ec66e1df611226e5618dbb32f9545c841", size = 27221, upload-time = "2022-11-01T17:24:27.501Z" }, ] [[package]] name = "python-dateutil" version = "2.9.0.post0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "six" }, ] sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, ] [[package]] name = "pywin32-ctypes" version = "0.2.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/85/9f/01a1a99704853cb63f253eea009390c88e7131c67e66a0a02099a8c917cb/pywin32-ctypes-0.2.3.tar.gz", hash = "sha256:d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755", size = 29471, upload-time = "2024-08-14T10:15:34.626Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/de/3d/8161f7711c017e01ac9f008dfddd9410dff3674334c233bde66e7ba65bbf/pywin32_ctypes-0.2.3-py3-none-any.whl", hash = "sha256:8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8", size = 30756, upload-time = "2024-08-14T10:15:33.187Z" }, ] [[package]] name = "pyyaml" version = "6.0.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, ] [[package]] name = "pyyaml-env-tag" version = "1.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyyaml" }, ] sdist = { url = "https://files.pythonhosted.org/packages/eb/2e/79c822141bfd05a853236b504869ebc6b70159afc570e1d5a20641782eaa/pyyaml_env_tag-1.1.tar.gz", hash = "sha256:2eb38b75a2d21ee0475d6d97ec19c63287a7e140231e4214969d0eac923cd7ff", size = 5737, upload-time = "2025-05-13T15:24:01.64Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl", hash = "sha256:17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04", size = 4722, upload-time = "2025-05-13T15:23:59.629Z" }, ] [[package]] name = "readme-renderer" version = "44.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "docutils" }, { name = "nh3" }, { name = "pygments" }, ] sdist = { url = "https://files.pythonhosted.org/packages/5a/a9/104ec9234c8448c4379768221ea6df01260cd6c2ce13182d4eac531c8342/readme_renderer-44.0.tar.gz", hash = "sha256:8712034eabbfa6805cacf1402b4eeb2a73028f72d1166d6f5cb7f9c047c5d1e1", size = 32056, upload-time = "2024-07-08T15:00:57.805Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/e1/67/921ec3024056483db83953ae8e48079ad62b92db7880013ca77632921dd0/readme_renderer-44.0-py3-none-any.whl", hash = "sha256:2fbca89b81a08526aadf1357a8c2ae889ec05fb03f5da67f9769c9a592166151", size = 13310, upload-time = "2024-07-08T15:00:56.577Z" }, ] [[package]] name = "referencing" version = "0.37.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "attrs" }, { name = "rpds-py" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/22/f5/df4e9027acead3ecc63e50fe1e36aca1523e1719559c499951bb4b53188f/referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8", size = 78036, upload-time = "2025-10-13T15:30:48.871Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231", size = 26766, upload-time = "2025-10-13T15:30:47.625Z" }, ] [[package]] name = "requests" version = "2.33.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "charset-normalizer" }, { name = "idna" }, { name = "urllib3" }, ] sdist = { url = "https://files.pythonhosted.org/packages/5f/a4/98b9c7c6428a668bf7e42ebb7c79d576a1c3c1e3ae2d47e674b468388871/requests-2.33.1.tar.gz", hash = "sha256:18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517", size = 134120, upload-time = "2026-03-30T16:09:15.531Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl", hash = "sha256:4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a", size = 64947, upload-time = "2026-03-30T16:09:13.83Z" }, ] [[package]] name = "requests-toolbelt" version = "1.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "requests" }, ] sdist = { url = "https://files.pythonhosted.org/packages/f3/61/d7545dafb7ac2230c70d38d31cbfe4cc64f7144dc41f6e4e4b78ecd9f5bb/requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", size = 206888, upload-time = "2023-05-01T04:11:33.229Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06", size = 54481, upload-time = "2023-05-01T04:11:28.427Z" }, ] [[package]] name = "rfc3986" version = "2.0.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/85/40/1520d68bfa07ab5a6f065a186815fb6610c86fe957bc065754e47f7b0840/rfc3986-2.0.0.tar.gz", hash = "sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c", size = 49026, upload-time = "2022-01-10T00:52:30.832Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ff/9a/9afaade874b2fa6c752c36f1548f718b5b83af81ed9b76628329dab81c1b/rfc3986-2.0.0-py2.py3-none-any.whl", hash = "sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd", size = 31326, upload-time = "2022-01-10T00:52:29.594Z" }, ] [[package]] name = "rich" version = "15.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown-it-py" }, { name = "pygments" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, ] [[package]] name = "rpds-py" version = "2026.6.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/aa/2a/9618a122aeb2a169a28b03889a2995fe297588964333d4a7d67bdf46e147/rpds_py-2026.6.3.tar.gz", hash = "sha256:1cebd1337c242e4ec2293e541f712b2da849b29f48f0c293684b71c0632625d4", size = 64051, upload-time = "2026-06-30T07:17:53.009Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/94/1f/a2dca5ffdbf1d475ffc4e80e4d5d720ff3a00f691795910116960ee12511/rpds_py-2026.6.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:7b689145a1485c335569bd056464f3243a29af7ed3871c7be31ad624ba239bc7", size = 342174, upload-time = "2026-06-30T07:14:54.821Z" }, { url = "https://files.pythonhosted.org/packages/4d/dc/323d08583c0832911768663d1944f0107fcd4088704858d84b5e06d105a0/rpds_py-2026.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:db08f45aecde626498fb3df07bcf6d2ec040af42e859a4f5040d79c200342911", size = 345513, upload-time = "2026-06-30T07:14:56.515Z" }, { url = "https://files.pythonhosted.org/packages/0b/2a/e31989834d18d2f26ec1d2774c5b1eb3331df4ea8ada525175294c94b48a/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:acc992ab27b15f852c76755eb2ab7dce86585ddadba6fa5946e58556088845b4", size = 373783, upload-time = "2026-06-30T07:14:57.736Z" }, { url = "https://files.pythonhosted.org/packages/87/fe/e80107ee3639585c9941c17d6a42cd65325022f656c023191fce78c324c8/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f88d653e7b3b779d71ae7454e20dcc9b6bae903f33c269db9f2be41bda3f261", size = 378316, upload-time = "2026-06-30T07:14:59.077Z" }, { url = "https://files.pythonhosted.org/packages/22/6f/81e3adf81acfb6fa694de2a6e4e7d8863121e3e0799e0a7725e6cf5679c4/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e52655eaf81e32593abedaa4bfe33170c8cfedf3365ed9be6e11e07f148f0278", size = 499423, upload-time = "2026-06-30T07:15:00.488Z" }, { url = "https://files.pythonhosted.org/packages/2d/9a/41263969df0ce3d9af2a96d5005a288200af1989aed3354bfceb5fc0b21f/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dfcc8b909769d19db55c7cc9541eb64b9b774b1057ffffb4f1048070475bb9f9", size = 386077, upload-time = "2026-06-30T07:15:01.911Z" }, { url = "https://files.pythonhosted.org/packages/5e/19/7e98f468bd50346faff5b10e5297374b443bfdddacc8e9fbc65984539597/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c1255b302953c86a486b81d330d5ee1d5bd937691ce271b6be0ef0e299eaab7", size = 371315, upload-time = "2026-06-30T07:15:03.317Z" }, { url = "https://files.pythonhosted.org/packages/99/3c/2b973b4d371906a134b03decfea7f5d9835a2c6d263454392e15b64b5b18/rpds_py-2026.6.3-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:8d2294a31386bfa251d8c8a39472beee17db67d4f1a6eabea665d35c9a4461c3", size = 383502, upload-time = "2026-06-30T07:15:04.627Z" }, { url = "https://files.pythonhosted.org/packages/98/2a/12e2799500af0a307bca76b63361c51f9fe479223561489c29eea1f2ee41/rpds_py-2026.6.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f8f23ead891a3b762f35ab3b04623da7056545b48aa60d59957e6789914545da", size = 402673, upload-time = "2026-06-30T07:15:05.856Z" }, { url = "https://files.pythonhosted.org/packages/2d/e3/21e5872d165fe08be4f229e3d5ee9d90019c0bf0e5538de60dbd54009450/rpds_py-2026.6.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:421aba32367055614287a4292b6a17f1939c9452299f7a0209c117e990b646d4", size = 549964, upload-time = "2026-06-30T07:15:07.159Z" }, { url = "https://files.pythonhosted.org/packages/1a/d0/5ee0fe36844297de8123bee27bc12078c1a7416ad9f1b8a8ca18d6b0c0ac/rpds_py-2026.6.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1e5822dfc2f0d4ab7e745eaa6d85945069329beeccef965af3f3bb26058fcab6", size = 615446, upload-time = "2026-06-30T07:15:08.531Z" }, { url = "https://files.pythonhosted.org/packages/b1/80/1ea5873cb683f2fbe5f21b23ea1f6d179ead19f3c5b249b7eb5dca568ef2/rpds_py-2026.6.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:83e35b57523816c8613fd0776b40cd8bb9f596b37ddd2692eb4a6bb5ab2f8c93", size = 576975, upload-time = "2026-06-30T07:15:09.97Z" }, { url = "https://files.pythonhosted.org/packages/c9/e1/90ef639217a5ddb15b7f4f61b1c33911fd044ad03c311bafdd2bcab85582/rpds_py-2026.6.3-cp311-cp311-win32.whl", hash = "sha256:de3eceba0b683bcbb1ab93da016d0270df1f9ae7be716b40214c5dafac6ea45a", size = 204453, upload-time = "2026-06-30T07:15:11.324Z" }, { url = "https://files.pythonhosted.org/packages/f2/b7/b7a1695d7af36f521fb11e80d6d3adbd744f73b921859bd3c2a2c0dc706f/rpds_py-2026.6.3-cp311-cp311-win_amd64.whl", hash = "sha256:2c54a076ca4d370980ab57bc0e31df57bbe8d41340436a90ef8b1219a3cbb127", size = 223219, upload-time = "2026-06-30T07:15:12.476Z" }, { url = "https://files.pythonhosted.org/packages/d7/a2/145afacf796e4506062825941176ad9445c2dcf2b3b6a1f13d3030a15e19/rpds_py-2026.6.3-cp311-cp311-win_arm64.whl", hash = "sha256:168c733a7112e071bb7a66460e667edfcff06c017a3c523f7a8a8e08d0140804", size = 219137, upload-time = "2026-06-30T07:15:13.631Z" }, { url = "https://files.pythonhosted.org/packages/5c/be/2e8974163072e7bab7df1a5acd54c4498e75e35d6d18b864d3a9d5dadc92/rpds_py-2026.6.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a0811d33247c3d6128a3001d763f2aa056bb3425204335400ac54f89eec3a0d0", size = 343691, upload-time = "2026-06-30T07:15:14.96Z" }, { url = "https://files.pythonhosted.org/packages/a4/73/319dfa745dd668efe89309141ded489126461fcecd2b8f3a3cda185129b6/rpds_py-2026.6.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:538949e262e46caa31ac01bdb3c1e8f642622922cacbabbae6a8445d9dc33eaf", size = 338542, upload-time = "2026-06-30T07:15:16.267Z" }, { url = "https://files.pythonhosted.org/packages/21/63/4239893be1c4d09b709b1a8f6be4188f0870084ff547f46606b8a75f1b03/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55927d532399c2c646100ff7feb48eaa940ad70f42cd68e1328f3ded9f81ca24", size = 368180, upload-time = "2026-06-30T07:15:17.62Z" }, { url = "https://files.pythonhosted.org/packages/1c/ca/9c5de382225234ceb37b1844ebdb140db12b2a278bb9efe2fcd19f6c82ce/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f56f1695bc5c0871cbc33dc0130fcf503aab0c57dcc5a6700a4f49eba4f2652e", size = 375067, upload-time = "2026-06-30T07:15:18.952Z" }, { url = "https://files.pythonhosted.org/packages/87/dc/863f69d1bf04ade34b7fe0d59b9fdf6f0135fe2d7cbca74f1d665589559d/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:270b293dae9058fc9fcedab50f13cebf46fb8ed1d1d54e0521a9da5d6b211975", size = 490509, upload-time = "2026-06-30T07:15:20.434Z" }, { url = "https://files.pythonhosted.org/packages/ce/ef/eac16a12048b45ec7c7fa94f2be3438a5f26bf9cc8580b18a1cfd609b7f6/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:127565fead0a10943b282957bd5447804ff3160ad79f2ad2635e6d249e380680", size = 382754, upload-time = "2026-06-30T07:15:21.831Z" }, { url = "https://files.pythonhosted.org/packages/04/8f/d2f3f532616be4d06c316ef119683e832bd3d41e112bf3a88f4151c95b17/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecabd69db66de867690f9797f2f8fa27ba501bbc24540cbdbdc649cd15888ba6", size = 366189, upload-time = "2026-06-30T07:15:23.371Z" }, { url = "https://files.pythonhosted.org/packages/e3/29/41a7b0e98a4b44cd676ab7598419623373eb43b20be68c084935c1a8cf88/rpds_py-2026.6.3-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:58eadac9cd119677b60e1cf8ac4052f35949d71b8a9e5556efccbe82533cf22a", size = 377750, upload-time = "2026-06-30T07:15:24.659Z" }, { url = "https://files.pythonhosted.org/packages/2e/05/ecda0bec46f9a1565090bcdc941d023f6a25aff85fda28f89f8d19878152/rpds_py-2026.6.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7491ee23305ac3eb59e492b6945881f5cd77a6f731061a3f25b77fd40f9e99a4", size = 395576, upload-time = "2026-06-30T07:15:25.987Z" }, { url = "https://files.pythonhosted.org/packages/68/a8/6ed52f03ee6cb854ce78785cc9a9a672eb880e83fd7224d471f667d151f1/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2c99f7e8ccb3dd6e3e4bfeac657a7b208c9bac8075f4b078c02d7404c34107fa", size = 543807, upload-time = "2026-06-30T07:15:27.356Z" }, { url = "https://files.pythonhosted.org/packages/8f/d6/156c0d3eea27ba09b92562ba2364ba124c0a061b199e17eac637cd25a5e2/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:62698275682bf121181861295c9181e789030a2d516071f5b8f3c23c170cd0fc", size = 611187, upload-time = "2026-06-30T07:15:28.931Z" }, { url = "https://files.pythonhosted.org/packages/f1/31/774212ed989c62f7f310220089f9b0a3fb8f40f5443d1727abd5d9f52bc9/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a214c993455f99a89aaeadc9b21241900037adc9d97203e374d75513c5911822", size = 573030, upload-time = "2026-06-30T07:15:30.553Z" }, { url = "https://files.pythonhosted.org/packages/c9/50/22f73127a41f1ce4f87fe39aadfb9a126345801c274aa93ae88456249327/rpds_py-2026.6.3-cp312-cp312-win32.whl", hash = "sha256:501f9f04a588d6a09179368c57071301445191767c64e4b52a6aa9871f1ef5ed", size = 202185, upload-time = "2026-06-30T07:15:32.027Z" }, { url = "https://files.pythonhosted.org/packages/04/3a/f0ee4d4dde9d3b69dedf1b5f74e7a40017046d55052d173e418c6a94f960/rpds_py-2026.6.3-cp312-cp312-win_amd64.whl", hash = "sha256:2c958bf94822e9290a40aaf2a822d4bc5c88099093e3948ad6c571eca9272e5f", size = 220394, upload-time = "2026-06-30T07:15:33.359Z" }, { url = "https://files.pythonhosted.org/packages/f3/83/3382fe37f809b59f02aac04dbc4e765b480b46ee0227ed516e3bdc4d3dfc/rpds_py-2026.6.3-cp312-cp312-win_arm64.whl", hash = "sha256:22bffe6042b9bcb0822bcd1955ec00e245daf17b4344e4ed8e9551b976b63e96", size = 215753, upload-time = "2026-06-30T07:15:34.778Z" }, { url = "https://files.pythonhosted.org/packages/a4/9e/b818ee580026ec578138e961027a68820c40afeb1ec8f6819b54fb99e196/rpds_py-2026.6.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:3cfe765c1da0072636ca06628261e0ea05688e160d5c8a03e0217c3854037223", size = 343012, upload-time = "2026-06-30T07:15:36.005Z" }, { url = "https://files.pythonhosted.org/packages/f3/6b/686d9dc4359a8f163cfbbf89ee0b4e586431de22fe8248edb63a8cf50d49/rpds_py-2026.6.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f4d78253f6996be4901669ad25319f842f740eccf4d58e3c7f3dd39e6dde1d8f", size = 338203, upload-time = "2026-06-30T07:15:37.462Z" }, { url = "https://files.pythonhosted.org/packages/9e/9b/069aa329940f8207615e091f5eedbbd40e1e15eac68a0790fd05ccdf796c/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54f45a148e28767bf343d33a684693c70e451c6f4c0e9904709a723fafbdfc1f", size = 367984, upload-time = "2026-06-30T07:15:39.008Z" }, { url = "https://files.pythonhosted.org/packages/14/db/34c203e4becff3703e4d3bc121842c00b8689197f398161203a880052f4e/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:842e7b070435622248c7a2c44ae53fa1440e073cc3023bc919fed570884097a7", size = 374815, upload-time = "2026-06-30T07:15:40.253Z" }, { url = "https://files.pythonhosted.org/packages/ee/7d/8071067d2cc453d916ad836e828c943f575e8a44612537759002a1e07381/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8020133a74bd81b4572dd8e4be028a6b1ebcd70e6726edc3918008c08bee6ee6", size = 490545, upload-time = "2026-06-30T07:15:41.729Z" }, { url = "https://files.pythonhosted.org/packages/a3/42/da06c5aa8f0484ff07f270787434204d9f4535e2f8c3b51ed402267e63c3/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cdc7e35386f3847df728fbcb5e887e2d79c19e2fa1eba9e51b6621d23e3243af", size = 382828, upload-time = "2026-06-30T07:15:43.327Z" }, { url = "https://files.pythonhosted.org/packages/57/d7/fe978efc2ae50abe48eb7464668ea99f53c010c60aeebb7b35ad27f23661/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acac386b453c2516111b50985d60ce46e7fadb5ea71ae7b25f4c946935bf27cf", size = 365678, upload-time = "2026-06-30T07:15:44.992Z" }, { url = "https://files.pythonhosted.org/packages/69/9d/1d8922e1990b2a6eb532b6ff53d3e73d2b3bbffc84116c75826bee73dfc6/rpds_py-2026.6.3-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:425560c6fa0415f27261727bb20bd097568485e5eb0c121f1949417d1c516885", size = 377811, upload-time = "2026-06-30T07:15:46.523Z" }, { url = "https://files.pythonhosted.org/packages/b1/3d/198dceafb4fb034a6a47347e1b0735d34e0bd4a50be4e898d408ee66cb14/rpds_py-2026.6.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a550fb4950a06dde3beb4721f5ad4b25bf4513784665b0a8522c792e2bd822a4", size = 395382, upload-time = "2026-06-30T07:15:47.955Z" }, { url = "https://files.pythonhosted.org/packages/1f/f1/13968e49655d40b6b19d8b9140296bbc6f1d86b3f0f6c346cf9f1adddf4b/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4f4bca01b63096f606e095734dd56e74e175f94cfbf24ff3d63281cec61f7bb7", size = 543832, upload-time = "2026-06-30T07:15:49.33Z" }, { url = "https://files.pythonhosted.org/packages/ac/ab/289bcb1b90bd3e40a2900c561fa0e2087345ecbb094f0b870f2345142b7c/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ccffae9a092a00deb7efd545fe5e2c33c33b88e7c054337e9a74c179347d0b7d", size = 611011, upload-time = "2026-06-30T07:15:50.847Z" }, { url = "https://files.pythonhosted.org/packages/1e/16/5043105e679436ccfbc8e5e0dd2d663ed18a8b8113515fd06a5e5d77c83e/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1cf01971c4f2c5553b772a542e4aaf191789cd331bc2cd4ff0e6e65ba49e1e97", size = 572431, upload-time = "2026-06-30T07:15:52.394Z" }, { url = "https://files.pythonhosted.org/packages/85/ed/adab103321c0a6565d5ae1c2998349bc3ee175b82ccc5ae8fc04cc413075/rpds_py-2026.6.3-cp313-cp313-win32.whl", hash = "sha256:8c3d1e9c15b9d51ca0391e13da1a25a0a4df3c58a37c9dc368e0736cf7f69df0", size = 201710, upload-time = "2026-06-30T07:15:53.894Z" }, { url = "https://files.pythonhosted.org/packages/7b/ed/a03b09668e74e5dabbf2e211f6468e1820c0552f7b0500082da31841bf7b/rpds_py-2026.6.3-cp313-cp313-win_amd64.whl", hash = "sha256:9250a9a0a6fd4648b3f868da8d91a4c52b5811a62df58e753d50ae4454a36f80", size = 219454, upload-time = "2026-06-30T07:15:55.25Z" }, { url = "https://files.pythonhosted.org/packages/27/17/b8642c12930b71bc2b25831f6708ccf0f75abcd11883932ec9ce54ba3a78/rpds_py-2026.6.3-cp313-cp313-win_arm64.whl", hash = "sha256:900a67df3fd1660b035a4761c4ce73c382ea6b35f90f9863c36c6fd8bf8b09bb", size = 215063, upload-time = "2026-06-30T07:15:56.573Z" }, { url = "https://files.pythonhosted.org/packages/b6/36/7fbe9dcdaf857fb3f63c2a2284b62492d95f5e8334e947e5fb6e7f68c9be/rpds_py-2026.6.3-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:931908d9fc855d8f74783377822be318edb6dcb19e47169dc038f9a1bf60b06e", size = 344510, upload-time = "2026-06-30T07:15:57.921Z" }, { url = "https://files.pythonhosted.org/packages/ba/54/f785cc3d3f60839ca57a5af4927a9f347b07b2799c373fc20f7949f87c7e/rpds_py-2026.6.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d7469697dce35be237db177d42e2a2ee26e6dcc5fc052078a6fefabd288c6edd", size = 339495, upload-time = "2026-06-30T07:15:59.238Z" }, { url = "https://files.pythonhosted.org/packages/63/ef/d4cdaf309e6b095b43597103cf8c0b951d6cca2acce68c474f75ec12e0c7/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcfbcf66006befb9fd2aeaa9e01feaf881b4dc330a02ba07d2322b1c11be7b5d", size = 369454, upload-time = "2026-06-30T07:16:01.021Z" }, { url = "https://files.pythonhosted.org/packages/96/4a/9559a68b7ee15db09d7981212e8c2e219d2a1d6d4faa0391d813c3496a36/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:847927daf4cffbd4e90e42bc890069897101edd015f956cb8721b3473372edda", size = 374583, upload-time = "2026-06-30T07:16:02.287Z" }, { url = "https://files.pythonhosted.org/packages/ef/75/8964aa7d2c6e8ac43eba8eb6e6b0fdda1f46d39f2fc3e6aa9f2cb17f485d/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aca6c1ef08a82bfe327cc156da694660f599923e2e6665b6d81c9c2d0ac9ffc8", size = 492919, upload-time = "2026-06-30T07:16:03.723Z" }, { url = "https://files.pythonhosted.org/packages/8f/97/6908094ac804115e65aedfd90f1b5fee4eebebd3f6c4cfc5419939267565/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ae50181a047c871561212bb97f7932a2d45fb53e947bd9b57ebad85b529cbc53", size = 383725, upload-time = "2026-06-30T07:16:05.305Z" }, { url = "https://files.pythonhosted.org/packages/d1/9c/0d1fdc2e7aba23e290d603bc494e97bd205bae262ce33c6b32a69768ed5e/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc319e5a1de4b6913aac94bf6a2f9e847371e0a140a43dd4991db1a09bc2d504", size = 367255, upload-time = "2026-06-30T07:16:07.086Z" }, { url = "https://files.pythonhosted.org/packages/c4/fe/f0209ca4a9ed074bc8acb44dfd0e81c3122e94c9689f5645b7973a866719/rpds_py-2026.6.3-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:e4316bf32babbed84e691e352faf967ce2f0f024174a8643c37c94a1080374fc", size = 379060, upload-time = "2026-06-30T07:16:08.525Z" }, { url = "https://files.pythonhosted.org/packages/c6/8d/f1cc54c616b9d8897de8738aac148d20afca93f68187475fe194d09a71b9/rpds_py-2026.6.3-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8c6e5a2f750cc71c3e3b11d71661f21d6f9bc6cebc6564b1466417a1ec03ec77", size = 395960, upload-time = "2026-06-30T07:16:09.989Z" }, { url = "https://files.pythonhosted.org/packages/fb/04/aafff00f73aeca2945f734f1d483c64ab8f472d0864ab02377fd8e89c3b2/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4470ce197d4090875cf6affbf1f853338387428df97c4fb7b7106317b8214698", size = 545356, upload-time = "2026-06-30T07:16:11.816Z" }, { url = "https://files.pythonhosted.org/packages/fd/cc/e229663b9e4ddac5a4acbe9085dd80a71af2a5d356b8b39d6bff233f24b0/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ea964164cc9afa72d4d9b23cc28dafae93693c0a53e0b42acbff15b22c3f9ddd", size = 612319, upload-time = "2026-06-30T07:16:13.586Z" }, { url = "https://files.pythonhosted.org/packages/e3/7a/8a0e6d3e6cd066af108b71b43122c3fe158dd9eb86acac626593a2582eb1/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:639c8929aa0afe81be836b04de888460d6bed38b9c54cfc18da8f6bfabf5af5d", size = 573508, upload-time = "2026-06-30T07:16:15.23Z" }, { url = "https://files.pythonhosted.org/packages/87/03/2a69ab618a789cf6cf85c86bb844c62d090e700ab1a2aa676b3741b6c516/rpds_py-2026.6.3-cp314-cp314-win32.whl", hash = "sha256:882076c00c0a608b131187055ddc5ae29f2e7eaf870d6168980420d58528a5c8", size = 202504, upload-time = "2026-06-30T07:16:16.893Z" }, { url = "https://files.pythonhosted.org/packages/85/62/a3892ba945f4e24c78f352e5de3c7620d8479f73f211406a97263d13c7d2/rpds_py-2026.6.3-cp314-cp314-win_amd64.whl", hash = "sha256:0be972be84cfcaf46c8c6edf690ca0f154ac17babf1f6a955a51579b34ad2dc5", size = 220380, upload-time = "2026-06-30T07:16:18.108Z" }, { url = "https://files.pythonhosted.org/packages/3d/e7/c2bd44dc831931815ad11ebb5f430b5a0a4d3caa9de837107876c30c3432/rpds_py-2026.6.3-cp314-cp314-win_arm64.whl", hash = "sha256:2a9c6f195058cb45335e8cc3802745c603d716eb96bc9625950c1aac71c0c703", size = 215976, upload-time = "2026-06-30T07:16:19.654Z" }, { url = "https://files.pythonhosted.org/packages/79/9c/fff7b74bce9a091ec9a012a03f9ff5f69364eaf9451060dfc4486da2ffdd/rpds_py-2026.6.3-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:f90938e92afda60266da758ee7d363447f7f0138c9559f9e1811629580582d90", size = 346840, upload-time = "2026-06-30T07:16:21.268Z" }, { url = "https://files.pythonhosted.org/packages/e9/44/77bcb1168b33704908295533d27f10eb811e9e3e193e8993dc99572211d3/rpds_py-2026.6.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ec829541c45bca16e61c7ae50c20501f213605beb75d1aba91a6ee37fbbb56a4", size = 340282, upload-time = "2026-06-30T07:16:22.875Z" }, { url = "https://files.pythonhosted.org/packages/87/3c/7a9081c7c9e645b39efe19e4ffbeccd80add246327cd9b888aecffd72317/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afd70d95892096cdb26f15a00c45907b17817577aa8d1c76b2dcc2788391f9e9", size = 370403, upload-time = "2026-06-30T07:16:24.415Z" }, { url = "https://files.pythonhosted.org/packages/f7/69/af47021eb7dad6ff3396cb001c08f0f3c4d06c20253f75be6421a59fe6b7/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:29dfa0533a5d4c94d4dfa1b694fcb56c9c63aad8330ffdd816fd225d0a7a162f", size = 376055, upload-time = "2026-06-30T07:16:26.111Z" }, { url = "https://files.pythonhosted.org/packages/81/fc/a3bcf517084396a6dd258c592567a3c011ba4557f2fde23dceaf26e74f2e/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:af05d726809bff6b141be124d4c7ce998f9c9c7f30edb1f46c07aa103d540b41", size = 494419, upload-time = "2026-06-30T07:16:27.596Z" }, { url = "https://files.pythonhosted.org/packages/c9/eb/13d529d1788135425c7bf207f8463458ca5d92e43f3f701365b83e9dffc1/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9826217f048f620d9a712672818bf231442c1b35d96b227a07eabd11b4bb6945", size = 384848, upload-time = "2026-06-30T07:16:29.183Z" }, { url = "https://files.pythonhosted.org/packages/8e/f4/b7ac49f30013aba8f7b9566b1dd07e81de95e708c1374b7bacc5b9bc5c9c/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:536bceea4fa4acf7e1c61da2b5786304367c816c8895be71b8f537c480b0ea1f", size = 371369, upload-time = "2026-06-30T07:16:30.912Z" }, { url = "https://files.pythonhosted.org/packages/31/86/6260bafa622f788b07ddec0e52d810305c8b9b0b8c27f58a2ab04bf62b4f/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:bc0011654b91cc4fb2ae701bec0a0ba1e552c0714247fa7af6c59e0ccfa3a4e1", size = 379673, upload-time = "2026-06-30T07:16:32.486Z" }, { url = "https://files.pythonhosted.org/packages/19/c3/03f1ee79a047b48daeca157c89a18509cde22b6b951d642b9b0af1be660a/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:539d75de9e0d536c84ff18dfeb805398e58227001ce09231a26a08b9aed1ee0e", size = 397500, upload-time = "2026-06-30T07:16:34.471Z" }, { url = "https://files.pythonhosted.org/packages/f0/95/8ed0cd8c377dca12aea498f119fe639fc474d1461545c39d2b5872eb1c0f/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:166cf54d9f44fc6ceb53c7860258dde44a81406646de79f8ed3234fca3b6e538", size = 545978, upload-time = "2026-06-30T07:16:36.45Z" }, { url = "https://files.pythonhosted.org/packages/d3/f2/0eb57f0eaa83f8fc152a7e03de968ab77e1f00732bebc892b190c6eebde7/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:d34c20167764fbcf927194d532dd7e0c56772f0a5f943fa5ef9e9afbba8fb9db", size = 613350, upload-time = "2026-06-30T07:16:38.213Z" }, { url = "https://files.pythonhosted.org/packages/5b/de/e0674bdbc3ef7634989b3f854c3f34bc1f587d36e5bfdc5c378d57034619/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ea7bb13b7c9a29791f87a0387ba7d3ad3a6d783d827e4d3f27b40a0ff44495e2", size = 576486, upload-time = "2026-06-30T07:16:39.797Z" }, { url = "https://files.pythonhosted.org/packages/f2/f6/21101359743cd136ada781e8210a85769578422ba460672eea0e29739200/rpds_py-2026.6.3-cp314-cp314t-win32.whl", hash = "sha256:6de4744d05bd1aa1be4ed7ea1189e3979196808008113bbbf899a460966b925e", size = 201068, upload-time = "2026-06-30T07:16:41.316Z" }, { url = "https://files.pythonhosted.org/packages/a6/b2/9574d4d44f7760c2aa32d92a0a4f41698e33f5b204a0bf5c9758f52c79d5/rpds_py-2026.6.3-cp314-cp314t-win_amd64.whl", hash = "sha256:c7b9a2f8f4d8e90af72571d3d495deebdd7e3c75451f5b41719aee166e940fc2", size = 220600, upload-time = "2026-06-30T07:16:43.091Z" }, { url = "https://files.pythonhosted.org/packages/08/ae/f23a2697e6ee6340a578b0f136be6483657bef0c6f9497b752bb5c0964bb/rpds_py-2026.6.3-cp315-cp315-macosx_10_12_x86_64.whl", hash = "sha256:e059c5dde6452b44424bd1834557556c226b57781dee1227af23518459722b13", size = 344726, upload-time = "2026-06-30T07:16:44.5Z" }, { url = "https://files.pythonhosted.org/packages/c3/63/e7b3a1a5358dd32c930a1062d8e15b67fd6e8922e81df9e91706d66ee5c8/rpds_py-2026.6.3-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:2f7c26fbc5acd2522b95d4177fe4710ffd8e9b20529e703ffbf8db4d93903f05", size = 339587, upload-time = "2026-06-30T07:16:46.255Z" }, { url = "https://files.pythonhosted.org/packages/ec/64/10a85681916ca55fffb91b0a211f84e34297c109243484dd6394660a8a7c/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3086b538543802f84c843911242db20447de00d8752dd0efc936dbcf02218ba", size = 369585, upload-time = "2026-06-30T07:16:48.101Z" }, { url = "https://files.pythonhosted.org/packages/76/c2/baf95c7c38823e12ba34407c5f5767a89e5cf2233895e56f608167ae9493/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8f2e5c5ee828d42cb11760761c0af6507927bec42d0ad5458f97c9203b054617", size = 375479, upload-time = "2026-06-30T07:16:49.93Z" }, { url = "https://files.pythonhosted.org/packages/6a/94/0aad06c72d65101e11d33528d438cda99a39ce0da99466e156158f2541d3/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ed0c1e5d10cdc7135537988c74a0188da68e2f3c30813ba3744ab1e42e0480f9", size = 492418, upload-time = "2026-06-30T07:16:51.641Z" }, { url = "https://files.pythonhosted.org/packages/b5/17/de3f5a479a1f056535d7489819639d8cd591ea6281d700390b43b1abd745/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c2642a7603ec0b16ed77da4555db3b4b472341904873788327c0b0d7b95f1bb", size = 384123, upload-time = "2026-06-30T07:16:53.622Z" }, { url = "https://files.pythonhosted.org/packages/46/7d/bf09bd1b145bb2671c03e1e6d1ab8651858d90d8c7dfeadd85a37a934fd8/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e4320744c1ffdd95a603def63344bfab2d33edeab301c5007e7de9f9f5b3885", size = 367351, upload-time = "2026-06-30T07:16:55.241Z" }, { url = "https://files.pythonhosted.org/packages/a3/ea/1bb734f314b8be319149ddee80b18bd41372bdcfbdf88d28131c0cd37719/rpds_py-2026.6.3-cp315-cp315-manylinux_2_31_riscv64.whl", hash = "sha256:a9f4645593036b81bbdb36b9c8e0ea0d1c3fee968c4d59db0344c14087ef143a", size = 378827, upload-time = "2026-06-30T07:16:56.841Z" }, { url = "https://files.pythonhosted.org/packages/4b/93/d9611e5b25e26df9a3649813ed66193ace9347a7c7fc4ab7cf70e94851c0/rpds_py-2026.6.3-cp315-cp315-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e55d236be29255554da47abe5c577637db7c24a02b8b46f0ca9524c855801868", size = 395966, upload-time = "2026-06-30T07:16:58.557Z" }, { url = "https://files.pythonhosted.org/packages/c3/cb/99d77e16e5534ae1d90629bbe419ba6ee170833a6a85e3aa1cc41726fbbc/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:24e9c5386e16669b674a69c156c8eeefcb578f3b3397b713b08e6d60f3c7b187", size = 545680, upload-time = "2026-06-30T07:17:00.164Z" }, { url = "https://files.pythonhosted.org/packages/59/15/11a29755f790cef7a2f755e8e14f4f0c33f39489e1893a632a2eee59672b/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:c60924535c75f1566b6eb75b5c31a48a43fef04fa2d0d201acbad8a9969c6107", size = 611853, upload-time = "2026-06-30T07:17:01.962Z" }, { url = "https://files.pythonhosted.org/packages/68/86/0c27547e21644da938fb530f7e1a8148dd24d02db07e7a5f2567a17ce710/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:38a2fea2787428f811719ceb9114cb78964a3138838320c29ac39526c79c16ba", size = 573715, upload-time = "2026-06-30T07:17:03.693Z" }, { url = "https://files.pythonhosted.org/packages/29/71/4d8fcf700931815594bce892255bbd973b94efaf0fc1932b0590df18d886/rpds_py-2026.6.3-cp315-cp315-win32.whl", hash = "sha256:d483fe17f01ad64b7bf7cc38fcefff1ca9fb83f8c2b2542b68f97ffe0611b369", size = 202864, upload-time = "2026-06-30T07:17:05.746Z" }, { url = "https://files.pythonhosted.org/packages/eb/62/b577562de0edbb55b2be85ce5fd09c33e386b9b13eee09833af4240fd5c4/rpds_py-2026.6.3-cp315-cp315-win_amd64.whl", hash = "sha256:67e3a721ffc5d8d2210d3671872298c4a84e4b8035cfe42ffd7cde35d772b146", size = 220430, upload-time = "2026-06-30T07:17:07.471Z" }, { url = "https://files.pythonhosted.org/packages/c8/95/d6d0b2509825141eef60669a5739eec88dbc6a48053d6c92993a5704defe/rpds_py-2026.6.3-cp315-cp315-win_arm64.whl", hash = "sha256:6e84adbcf4bf841aed8116a8264b9f50b4cb3e7bd89b516122e616ac56ca269e", size = 215877, upload-time = "2026-06-30T07:17:09.008Z" }, { url = "https://files.pythonhosted.org/packages/b7/bf/f3ea278f0afd615c1d0f19cb69043a41526e2bb600c2b536eb192218eb27/rpds_py-2026.6.3-cp315-cp315t-macosx_10_12_x86_64.whl", hash = "sha256:ae6dd8f10bd17aad820876d24caec9efdafd80a318d16c0a48edb5e136902c6b", size = 346933, upload-time = "2026-06-30T07:17:10.762Z" }, { url = "https://files.pythonhosted.org/packages/9d/29/9907bdf1c5346763cf10b7f6852aad86652168c259def904cbe0082c5864/rpds_py-2026.6.3-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:bdbd97738551fca3917c1bd7188bec1920bb520104f28e7e1007f9ceb17b7690", size = 340274, upload-time = "2026-06-30T07:17:12.266Z" }, { url = "https://files.pythonhosted.org/packages/6f/2c/8e03767b5778ef25cebf74a7a91a2c3806f8eced4c92cb7406bbe060756d/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b95977e7211527ab0ba576e286d023389fbeeb32a6b7b771665d333c60e5342", size = 370763, upload-time = "2026-06-30T07:17:14.107Z" }, { url = "https://files.pythonhosted.org/packages/2e/e1/df2a7e1ba2efd796af26194250b8d42c821b46592311595162af9ef0528d/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d15fde0e6fb0d88a60d221204873743e5d9f0b7d29165e62cd86d0413ad74ba6", size = 376467, upload-time = "2026-06-30T07:17:15.76Z" }, { url = "https://files.pythonhosted.org/packages/6b/de/8a0814d1946af29cb068fb259aa8622f856df1d0bab58429448726b537f5/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a136d453475ac0fcbda502ef1e6504bd28d6d904700915d278deeab0d00fe140", size = 496689, upload-time = "2026-06-30T07:17:17.308Z" }, { url = "https://files.pythonhosted.org/packages/df/f3/f19e0c852ba13694f5a79f3b719331051573cb5693feacf8a88ffffc3a71/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f826877d462181e5eb1c26a0026b8d0cab05d99844ecb6d8bf3627a2ca0c0442", size = 385340, upload-time = "2026-06-30T07:17:18.928Z" }, { url = "https://files.pythonhosted.org/packages/e2/ae/7ec3a9d2d4351f99e37bcb06b6b6f954512646bfdbf9742e1de727865daf/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79486287de1730dbaff3dbd124d0ca4d2ef7f9d29bf2544f1f93c09b5bcbbd12", size = 372179, upload-time = "2026-06-30T07:17:20.539Z" }, { url = "https://files.pythonhosted.org/packages/d3/ac/9cee911dff2aaa9a5a8354f6610bf2e6a616de9197c5fff4f54f82585f1e/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_31_riscv64.whl", hash = "sha256:808345f53cb952433ca2816f1604ff3515608a81784954f38d4452acfe8e61d5", size = 379993, upload-time = "2026-06-30T07:17:22.212Z" }, { url = "https://files.pythonhosted.org/packages/83/6b/7c2a07ba88d1e9a936612f7a5d067467ed03d971d5a06f7d309dff044a7e/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1967debc37f64f2c4dc90a7f563aec558b471966e12adcac4e1c4240496b6ebf", size = 398909, upload-time = "2026-06-30T07:17:23.66Z" }, { url = "https://files.pythonhosted.org/packages/97/0b/776ffcb66783637b0031f6d58d6fb55913c8b5abf00aeecd46bf933fb477/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:f0840b5b17057f7fd918b76183a4b5a0635f43e14eb2ce60dce1d4ee4707ea00", size = 546584, upload-time = "2026-06-30T07:17:25.264Z" }, { url = "https://files.pythonhosted.org/packages/55/33/ba3bc04d7092bd553c9b2b195624992d2cc4f3de1f380b7b93cbee67bd79/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:faa679d19a6696fd54259ad321251ad77a13e70e03dd834daa762a44fb6196ef", size = 614357, upload-time = "2026-06-30T07:17:26.888Z" }, { url = "https://files.pythonhosted.org/packages/8b/71/14edf065f04630b1a8472f7653cad03f6c478bcf95ea0e6aed55451e33ea/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:23a439f31ccbeff1574e24889128821d1f7917470e830cf6544dced1c662262a", size = 576533, upload-time = "2026-06-30T07:17:28.546Z" }, { url = "https://files.pythonhosted.org/packages/ba/76/65002b08596c389105720a8c0d22298b8dc25a4baf89b2ce431343c8b1de/rpds_py-2026.6.3-cp315-cp315t-win32.whl", hash = "sha256:913ca42ccad3f8cc6e292b587ae8ae49c8c823e5dce51a736252fc7c7cdfa577", size = 201204, upload-time = "2026-06-30T07:17:30.193Z" }, { url = "https://files.pythonhosted.org/packages/8c/97/d855d6b3c322d1f27e26f5241c42016b56cf01377ea8ed348285f54652f0/rpds_py-2026.6.3-cp315-cp315t-win_amd64.whl", hash = "sha256:ae3d4fe8c0b9213624fdce7279d70e3b148b682ca20719ebd193a23ebfa47324", size = 220719, upload-time = "2026-06-30T07:17:31.788Z" }, { url = "https://files.pythonhosted.org/packages/b4/9c/f0d19ac587fd0e4ab6b72cda355e9c5a6166b01ef7e064e437aef8eb9fef/rpds_py-2026.6.3-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:4cf2d36a2357e4d07bb5a4f98801265327b48256867816cfd2ceb001e9754a8f", size = 349791, upload-time = "2026-06-30T07:17:33.315Z" }, { url = "https://files.pythonhosted.org/packages/38/c7/1d49d204c9fd2ee6c537601dc4c1ba921e03363ca576bfab94a00254ac9a/rpds_py-2026.6.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:30c6dc199b24a5e3e81d50da0f00858c5bbdb2617a750395687f4339c5818171", size = 352842, upload-time = "2026-06-30T07:17:34.897Z" }, { url = "https://files.pythonhosted.org/packages/ac/e5/c0b5dc93cd0d4c06ce1f438907649514e2ea077bcd911e3154a51e96c38e/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9891e594296ab9dada6551c8e7b387b2721f27a67eecd528412e8906247a7b90", size = 382094, upload-time = "2026-06-30T07:17:36.514Z" }, { url = "https://files.pythonhosted.org/packages/0d/54/ec0e907b4ca8d541112db352409bd15f871c9b243e0c92c9b5a46ae96f01/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b5c2dc92304aa48a4a60443b548bb12f12e119d4b72f314015e67b9e1be97fca", size = 388662, upload-time = "2026-06-30T07:17:38.235Z" }, { url = "https://files.pythonhosted.org/packages/d3/f4/921c22a4fd0f1c1ac13a3996ffbf0aa67951e2c8ad0d1d9574938a2932e8/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:127e08c0642d880cf32ca47ec2a4a77b901f7e2dd1ad9762adb13955d72ffcc9", size = 504896, upload-time = "2026-06-30T07:17:39.689Z" }, { url = "https://files.pythonhosted.org/packages/0b/1b/a114b972cefa1ab1cdb3c7bb177cd3844a12826c507c722d3a73516dbbaf/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8bb68f03f395eb793220b45c097bd4d8c32944393da0fad8b999efac0868fc8c", size = 391545, upload-time = "2026-06-30T07:17:41.336Z" }, { url = "https://files.pythonhosted.org/packages/4e/98/af9b3db77d47fcbe6c8c1f36e2c2147ec70292819e99c325f871584a1c11/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3450b693fde92133e9f51060568a4c31fcca76d5e53bbd611e689ca446517e9", size = 380059, upload-time = "2026-06-30T07:17:42.857Z" }, { url = "https://files.pythonhosted.org/packages/c9/ba/0efd8668b97c1d26a61566386c636a7a7a09829e474fdf807caa15a2c844/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:5e8d07bddee435a2ff6f1920e18feff28d0bc4533e42f4bf6927fbd073312c41", size = 393235, upload-time = "2026-06-30T07:17:44.637Z" }, { url = "https://files.pythonhosted.org/packages/62/90/8c139ee9690f73b0829f32647de6f40d826f8f443af6fa72644f96351aac/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3a83ae6c67b7676b9878378547ca8e93ed77a580037bcbcd1d32f739e1e6089c", size = 413008, upload-time = "2026-06-30T07:17:46.225Z" }, { url = "https://files.pythonhosted.org/packages/9c/97/0043896fdd7828ce09a1d9a8b06433714d0960fc4ff3fc4aa72b666b764e/rpds_py-2026.6.3-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2bfd04c19ddbd6640de0b51894d764bd2758854d5b75bd102d2ef10cb9c293a9", size = 558118, upload-time = "2026-06-30T07:17:47.759Z" }, { url = "https://files.pythonhosted.org/packages/f6/40/02355f0e134f783a8f9814c4680a1bd311d37671577a5964ea838573ff37/rpds_py-2026.6.3-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:ca6546b66be9dc4738b1b043d5ebd5488c66c578c5ff0fd0e8065313fe3afb76", size = 623138, upload-time = "2026-06-30T07:17:49.355Z" }, { url = "https://files.pythonhosted.org/packages/10/85/48f0abdcef5cce4e034c7a5b0ceeceba0b01bf0d942824f4bb720afe2dec/rpds_py-2026.6.3-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:8e65860d238379ed982fd9ba690579b5e95af2f4840f99c772816dbe573cb826", size = 586486, upload-time = "2026-06-30T07:17:51.141Z" }, ] [[package]] name = "ruff" version = "0.16.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/00/8f/d8074b1f25e003164087a8bfe79a0f1a3945135764dbb6aaab04103dcaf9/ruff-0.16.4.tar.gz", hash = "sha256:13171aa9d9af2240ee3504e639de73122c67e74036de5ba2e1d01422cd17e3dc", size = 4899731, upload-time = "2026-08-20T17:43:59.196Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ff/80/779895ef584e089d22f2c6df0d0e99a65ec2df0805f1fffd439415b8c1f0/ruff-0.16.4-py3-none-linux_armv6l.whl", hash = "sha256:df4075f71ddac40b9934af60c3ec8a53047dd5a5fdc43224e6e4e8e9a27cb6f7", size = 10006909, upload-time = "2026-08-20T17:43:16.888Z" }, { url = "https://files.pythonhosted.org/packages/a9/e6/f553199b5e8927a05cb5c422d921fd0656b29ab976e91c44802107c6b0da/ruff-0.16.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:0c95538517af68004306b0fb3214ff2f2af67a65092aee77cd9eb86db6656604", size = 10240201, upload-time = "2026-08-20T17:43:19.337Z" }, { url = "https://files.pythonhosted.org/packages/1c/70/4a6dc4bb34da4dee35e30f09bbd1bfbdd26f33b62fb9b8df31f08a199cd2/ruff-0.16.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:963f83df8e69e575b64d67dd447ebbc917db41a14bf38d4593a4183e7aaa8255", size = 9835122, upload-time = "2026-08-20T17:43:21.708Z" }, { url = "https://files.pythonhosted.org/packages/24/12/c6e22d686372c15bcb7af99831f1a1be96df696491babf4f24e4f942c527/ruff-0.16.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32a5057c7ff3f6e6480a48fccfb3a412a690f48a3d03ac5cf08177d6c2da3ade", size = 9977162, upload-time = "2026-08-20T17:43:24.236Z" }, { url = "https://files.pythonhosted.org/packages/46/49/72b10ec912f5ab5854992eaf7aa7cd36729b6937d9dc4e0fb41b3bf428ec/ruff-0.16.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b3dce8d9b0c57c265b91885a66a567d8ea1372e8eb4e250fa8e5e3f579e99cff", size = 9829789, upload-time = "2026-08-20T17:43:26.966Z" }, { url = "https://files.pythonhosted.org/packages/fa/80/0f30e32e7f6ee26edc39075502db9d368d788a44a79b55f763eb4ab03796/ruff-0.16.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7dc651db49283c69f8e72c834eec4fe5573e4c646856aebece0ce385dceb2a80", size = 10527949, upload-time = "2026-08-20T17:43:29.384Z" }, { url = "https://files.pythonhosted.org/packages/52/3d/86e8ad3542169e56cac3859a343afdb9df2ad54d35a59ce1e67baee83421/ruff-0.16.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3817b87dbcabc92f13b05019257c5b89b5b4d51b5fb20f56fb5235ceb723cd07", size = 11333695, upload-time = "2026-08-20T17:43:31.872Z" }, { url = "https://files.pythonhosted.org/packages/d0/16/481c29b380c20a0054a8261066665e1b3488e23636c49d0a43e75975b9bb/ruff-0.16.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9fce1499134b2c8c68e5166f95705a5812062bb93aacc5f9873bb1a27084bc7", size = 10727741, upload-time = "2026-08-20T17:43:34.596Z" }, { url = "https://files.pythonhosted.org/packages/5e/b6/56bc0b8cf45b54b28b3a5e6381c8945d51b5b18adf659454c32295209a31/ruff-0.16.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2d812e482f5a7e02eee26cd73d2a37ebbdf47d795ea63ba1b89110ae93e9fb3", size = 10286522, upload-time = "2026-08-20T17:43:37.288Z" }, { url = "https://files.pythonhosted.org/packages/e8/8b/b345b4fb110f2fbe2bd31eabd271e5e8b3b7e4ee6c0e02f2dc6be78db000/ruff-0.16.4-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:6baaf984aa7976edf93d3b627fe2d1d22ee94bbca05fa6f90fc76d73924e3454", size = 10584182, upload-time = "2026-08-20T17:43:39.984Z" }, { url = "https://files.pythonhosted.org/packages/29/e5/827b34041c35f58774a9681a4213994c164fc987800f4dddabcf451da0bf/ruff-0.16.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:bdfcf0b28662eb890372d50f92c283bb94e67e7635ed93c7fd533970acff7b2b", size = 10134195, upload-time = "2026-08-20T17:43:42.351Z" }, { url = "https://files.pythonhosted.org/packages/0f/10/d0bffcdd6729b87afc82ba0ef377173356a7dc8e972f5179968cf2fdf98c/ruff-0.16.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:b66b02cb9b04f537643cadf5768e5f98dc461890d530cb67113d71c8c76e605d", size = 9825821, upload-time = "2026-08-20T17:43:44.532Z" }, { url = "https://files.pythonhosted.org/packages/f5/32/0db2a863b796ca62d83e92a07a3ccf00921b14db02059347576a2fda3d4b/ruff-0.16.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:8528bf9a4b291a60bf02ea453511e8ce6215bd2b982ee80405b66b008b6c30a0", size = 10267658, upload-time = "2026-08-20T17:43:46.989Z" }, { url = "https://files.pythonhosted.org/packages/b2/a0/fbdeb59e48c6261f523e56c8f12e9c08fbe693786595cc7e3959207a9232/ruff-0.16.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:fbd85d2875fdd67e833213a651f613bbf25303abf6aa822a5121f4531195678d", size = 10697071, upload-time = "2026-08-20T17:43:49.891Z" }, { url = "https://files.pythonhosted.org/packages/aa/28/0c6dd865859c6d17bc8ccc34cb72b0e02d6c7eb25e8a1e22b5bea681e2c0/ruff-0.16.4-py3-none-win32.whl", hash = "sha256:312769988007aaeb8e189b443ccdd03c0e6374489e053467be6d96518ebff76e", size = 10021687, upload-time = "2026-08-20T17:43:52.281Z" }, { url = "https://files.pythonhosted.org/packages/a3/03/e724450f621698117f9aa6dd241c94d0274ae96781378dc86745ae29f0e7/ruff-0.16.4-py3-none-win_amd64.whl", hash = "sha256:05d9d27a18c4bcbefada602480ec9e01e0bc949d432e0ced5df77edac195919c", size = 10567657, upload-time = "2026-08-20T17:43:54.78Z" }, { url = "https://files.pythonhosted.org/packages/0e/fe/da8b9e1347696bb22120b77280ec5ce25d500ca5cb39d5ad6e5c18de19c1/ruff-0.16.4-py3-none-win_arm64.whl", hash = "sha256:a3a61621c9b6f6a89573e938a080e648f1695baa3f58570a3a707bc51ff65a21", size = 10451579, upload-time = "2026-08-20T17:43:57.135Z" }, ] [[package]] name = "secretstorage" version = "3.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cryptography" }, { name = "jeepney" }, ] sdist = { url = "https://files.pythonhosted.org/packages/1c/03/e834bcd866f2f8a49a85eaff47340affa3bfa391ee9912a952a1faa68c7b/secretstorage-3.5.0.tar.gz", hash = "sha256:f04b8e4689cbce351744d5537bf6b1329c6fc68f91fa666f60a380edddcd11be", size = 19884, upload-time = "2025-11-23T19:02:53.191Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b7/46/f5af3402b579fd5e11573ce652019a67074317e18c1935cc0b4ba9b35552/secretstorage-3.5.0-py3-none-any.whl", hash = "sha256:0ce65888c0725fcb2c5bc0fdb8e5438eece02c523557ea40ce0703c266248137", size = 15554, upload-time = "2025-11-23T19:02:51.545Z" }, ] [[package]] name = "six" version = "1.17.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, ] [[package]] name = "sniffio" version = "1.3.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, ] [[package]] name = "socksio" version = "1.0.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f8/5c/48a7d9495be3d1c651198fd99dbb6ce190e2274d0f28b9051307bdec6b85/socksio-1.0.0.tar.gz", hash = "sha256:f88beb3da5b5c38b9890469de67d0cb0f9d494b78b106ca1845f96c10b91c4ac", size = 19055, upload-time = "2020-04-17T15:50:34.664Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/37/c3/6eeb6034408dac0fa653d126c9204ade96b819c936e136c5e8a6897eee9c/socksio-1.0.0-py3-none-any.whl", hash = "sha256:95dc1f15f9b34e8d7b16f06d74b8ccf48f609af32ab33c608d08761c5dcbb1f3", size = 12763, upload-time = "2020-04-17T15:50:31.878Z" }, ] [[package]] name = "sortedcontainers" version = "2.4.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/e8/c4/ba2f8066cceb6f23394729afe52f3bf7adec04bf9ed2c820b39e19299111/sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", size = 30594, upload-time = "2021-05-16T22:03:42.897Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575, upload-time = "2021-05-16T22:03:41.177Z" }, ] [[package]] name = "starlette" version = "1.6.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b5/b4/205b0d5241d934e8add0c38aa924c4f9fb7330834ff11e5444db964ec3f9/starlette-1.6.0.tar.gz", hash = "sha256:d4e3ac5e546444960c710297a3c9fc3f7ebae1b7e963f3d36173b49da535be9b", size = 2716969, upload-time = "2026-08-08T18:27:57.512Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/c8/cb/6a6a47d5b464bd08695d254f3da6e7986cc70c9fa5d778eda57538edfe56/starlette-1.6.0-py3-none-any.whl", hash = "sha256:a86dd39d14bb45f85a3d18525215a9ef0cfd1f192ac793220e72598c90335f0c", size = 75969, upload-time = "2026-08-08T18:27:56.196Z" }, ] [[package]] name = "tomli" version = "2.4.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/f4/11/db3d5885d8528263d8adc260bb2d28ebf1270b96e98f0e0268d32b8d9900/tomli-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30", size = 154704, upload-time = "2026-03-25T20:21:10.473Z" }, { url = "https://files.pythonhosted.org/packages/6d/f7/675db52c7e46064a9aa928885a9b20f4124ecb9bc2e1ce74c9106648d202/tomli-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a", size = 149454, upload-time = "2026-03-25T20:21:12.036Z" }, { url = "https://files.pythonhosted.org/packages/61/71/81c50943cf953efa35bce7646caab3cf457a7d8c030b27cfb40d7235f9ee/tomli-2.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076", size = 237561, upload-time = "2026-03-25T20:21:13.098Z" }, { url = "https://files.pythonhosted.org/packages/48/c1/f41d9cb618acccca7df82aaf682f9b49013c9397212cb9f53219e3abac37/tomli-2.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9", size = 243824, upload-time = "2026-03-25T20:21:14.569Z" }, { url = "https://files.pythonhosted.org/packages/22/e4/5a816ecdd1f8ca51fb756ef684b90f2780afc52fc67f987e3c61d800a46d/tomli-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c", size = 242227, upload-time = "2026-03-25T20:21:15.712Z" }, { url = "https://files.pythonhosted.org/packages/6b/49/2b2a0ef529aa6eec245d25f0c703e020a73955ad7edf73e7f54ddc608aa5/tomli-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc", size = 247859, upload-time = "2026-03-25T20:21:17.001Z" }, { url = "https://files.pythonhosted.org/packages/83/bd/6c1a630eaca337e1e78c5903104f831bda934c426f9231429396ce3c3467/tomli-2.4.1-cp311-cp311-win32.whl", hash = "sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049", size = 97204, upload-time = "2026-03-25T20:21:18.079Z" }, { url = "https://files.pythonhosted.org/packages/42/59/71461df1a885647e10b6bb7802d0b8e66480c61f3f43079e0dcd315b3954/tomli-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e", size = 108084, upload-time = "2026-03-25T20:21:18.978Z" }, { url = "https://files.pythonhosted.org/packages/b8/83/dceca96142499c069475b790e7913b1044c1a4337e700751f48ed723f883/tomli-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece", size = 95285, upload-time = "2026-03-25T20:21:20.309Z" }, { url = "https://files.pythonhosted.org/packages/c1/ba/42f134a3fe2b370f555f44b1d72feebb94debcab01676bf918d0cb70e9aa/tomli-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a", size = 155924, upload-time = "2026-03-25T20:21:21.626Z" }, { url = "https://files.pythonhosted.org/packages/dc/c7/62d7a17c26487ade21c5422b646110f2162f1fcc95980ef7f63e73c68f14/tomli-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085", size = 150018, upload-time = "2026-03-25T20:21:23.002Z" }, { url = "https://files.pythonhosted.org/packages/5c/05/79d13d7c15f13bdef410bdd49a6485b1c37d28968314eabee452c22a7fda/tomli-2.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9", size = 244948, upload-time = "2026-03-25T20:21:24.04Z" }, { url = "https://files.pythonhosted.org/packages/10/90/d62ce007a1c80d0b2c93e02cab211224756240884751b94ca72df8a875ca/tomli-2.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5", size = 253341, upload-time = "2026-03-25T20:21:25.177Z" }, { url = "https://files.pythonhosted.org/packages/1a/7e/caf6496d60152ad4ed09282c1885cca4eea150bfd007da84aea07bcc0a3e/tomli-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585", size = 248159, upload-time = "2026-03-25T20:21:26.364Z" }, { url = "https://files.pythonhosted.org/packages/99/e7/c6f69c3120de34bbd882c6fba7975f3d7a746e9218e56ab46a1bc4b42552/tomli-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1", size = 253290, upload-time = "2026-03-25T20:21:27.46Z" }, { url = "https://files.pythonhosted.org/packages/d6/2f/4a3c322f22c5c66c4b836ec58211641a4067364f5dcdd7b974b4c5da300c/tomli-2.4.1-cp312-cp312-win32.whl", hash = "sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917", size = 98141, upload-time = "2026-03-25T20:21:28.492Z" }, { url = "https://files.pythonhosted.org/packages/24/22/4daacd05391b92c55759d55eaee21e1dfaea86ce5c571f10083360adf534/tomli-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9", size = 108847, upload-time = "2026-03-25T20:21:29.386Z" }, { url = "https://files.pythonhosted.org/packages/68/fd/70e768887666ddd9e9f5d85129e84910f2db2796f9096aa02b721a53098d/tomli-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257", size = 95088, upload-time = "2026-03-25T20:21:30.677Z" }, { url = "https://files.pythonhosted.org/packages/07/06/b823a7e818c756d9a7123ba2cda7d07bc2dd32835648d1a7b7b7a05d848d/tomli-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54", size = 155866, upload-time = "2026-03-25T20:21:31.65Z" }, { url = "https://files.pythonhosted.org/packages/14/6f/12645cf7f08e1a20c7eb8c297c6f11d31c1b50f316a7e7e1e1de6e2e7b7e/tomli-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a", size = 149887, upload-time = "2026-03-25T20:21:33.028Z" }, { url = "https://files.pythonhosted.org/packages/5c/e0/90637574e5e7212c09099c67ad349b04ec4d6020324539297b634a0192b0/tomli-2.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897", size = 243704, upload-time = "2026-03-25T20:21:34.51Z" }, { url = "https://files.pythonhosted.org/packages/10/8f/d3ddb16c5a4befdf31a23307f72828686ab2096f068eaf56631e136c1fdd/tomli-2.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f", size = 251628, upload-time = "2026-03-25T20:21:36.012Z" }, { url = "https://files.pythonhosted.org/packages/e3/f1/dbeeb9116715abee2485bf0a12d07a8f31af94d71608c171c45f64c0469d/tomli-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d", size = 247180, upload-time = "2026-03-25T20:21:37.136Z" }, { url = "https://files.pythonhosted.org/packages/d3/74/16336ffd19ed4da28a70959f92f506233bd7cfc2332b20bdb01591e8b1d1/tomli-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5", size = 251674, upload-time = "2026-03-25T20:21:38.298Z" }, { url = "https://files.pythonhosted.org/packages/16/f9/229fa3434c590ddf6c0aa9af64d3af4b752540686cace29e6281e3458469/tomli-2.4.1-cp313-cp313-win32.whl", hash = "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd", size = 97976, upload-time = "2026-03-25T20:21:39.316Z" }, { url = "https://files.pythonhosted.org/packages/6a/1e/71dfd96bcc1c775420cb8befe7a9d35f2e5b1309798f009dca17b7708c1e/tomli-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36", size = 108755, upload-time = "2026-03-25T20:21:40.248Z" }, { url = "https://files.pythonhosted.org/packages/83/7a/d34f422a021d62420b78f5c538e5b102f62bea616d1d75a13f0a88acb04a/tomli-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd", size = 95265, upload-time = "2026-03-25T20:21:41.219Z" }, { url = "https://files.pythonhosted.org/packages/3c/fb/9a5c8d27dbab540869f7c1f8eb0abb3244189ce780ba9cd73f3770662072/tomli-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf", size = 155726, upload-time = "2026-03-25T20:21:42.23Z" }, { url = "https://files.pythonhosted.org/packages/62/05/d2f816630cc771ad836af54f5001f47a6f611d2d39535364f148b6a92d6b/tomli-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac", size = 149859, upload-time = "2026-03-25T20:21:43.386Z" }, { url = "https://files.pythonhosted.org/packages/ce/48/66341bdb858ad9bd0ceab5a86f90eddab127cf8b046418009f2125630ecb/tomli-2.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662", size = 244713, upload-time = "2026-03-25T20:21:44.474Z" }, { url = "https://files.pythonhosted.org/packages/df/6d/c5fad00d82b3c7a3ab6189bd4b10e60466f22cfe8a08a9394185c8a8111c/tomli-2.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853", size = 252084, upload-time = "2026-03-25T20:21:45.62Z" }, { url = "https://files.pythonhosted.org/packages/00/71/3a69e86f3eafe8c7a59d008d245888051005bd657760e96d5fbfb0b740c2/tomli-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15", size = 247973, upload-time = "2026-03-25T20:21:46.937Z" }, { url = "https://files.pythonhosted.org/packages/67/50/361e986652847fec4bd5e4a0208752fbe64689c603c7ae5ea7cb16b1c0ca/tomli-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba", size = 256223, upload-time = "2026-03-25T20:21:48.467Z" }, { url = "https://files.pythonhosted.org/packages/8c/9a/b4173689a9203472e5467217e0154b00e260621caa227b6fa01feab16998/tomli-2.4.1-cp314-cp314-win32.whl", hash = "sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6", size = 98973, upload-time = "2026-03-25T20:21:49.526Z" }, { url = "https://files.pythonhosted.org/packages/14/58/640ac93bf230cd27d002462c9af0d837779f8773bc03dee06b5835208214/tomli-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7", size = 109082, upload-time = "2026-03-25T20:21:50.506Z" }, { url = "https://files.pythonhosted.org/packages/d5/2f/702d5e05b227401c1068f0d386d79a589bb12bf64c3d2c72ce0631e3bc49/tomli-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232", size = 96490, upload-time = "2026-03-25T20:21:51.474Z" }, { url = "https://files.pythonhosted.org/packages/45/4b/b877b05c8ba62927d9865dd980e34a755de541eb65fffba52b4cc495d4d2/tomli-2.4.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4", size = 164263, upload-time = "2026-03-25T20:21:52.543Z" }, { url = "https://files.pythonhosted.org/packages/24/79/6ab420d37a270b89f7195dec5448f79400d9e9c1826df982f3f8e97b24fd/tomli-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c", size = 160736, upload-time = "2026-03-25T20:21:53.674Z" }, { url = "https://files.pythonhosted.org/packages/02/e0/3630057d8eb170310785723ed5adcdfb7d50cb7e6455f85ba8a3deed642b/tomli-2.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d", size = 270717, upload-time = "2026-03-25T20:21:55.129Z" }, { url = "https://files.pythonhosted.org/packages/7a/b4/1613716072e544d1a7891f548d8f9ec6ce2faf42ca65acae01d76ea06bb0/tomli-2.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41", size = 278461, upload-time = "2026-03-25T20:21:56.228Z" }, { url = "https://files.pythonhosted.org/packages/05/38/30f541baf6a3f6df77b3df16b01ba319221389e2da59427e221ef417ac0c/tomli-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c", size = 274855, upload-time = "2026-03-25T20:21:57.653Z" }, { url = "https://files.pythonhosted.org/packages/77/a3/ec9dd4fd2c38e98de34223b995a3b34813e6bdadf86c75314c928350ed14/tomli-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f", size = 283144, upload-time = "2026-03-25T20:21:59.089Z" }, { url = "https://files.pythonhosted.org/packages/ef/be/605a6261cac79fba2ec0c9827e986e00323a1945700969b8ee0b30d85453/tomli-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8", size = 108683, upload-time = "2026-03-25T20:22:00.214Z" }, { url = "https://files.pythonhosted.org/packages/12/64/da524626d3b9cc40c168a13da8335fe1c51be12c0a63685cc6db7308daae/tomli-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26", size = 121196, upload-time = "2026-03-25T20:22:01.169Z" }, { url = "https://files.pythonhosted.org/packages/5a/cd/e80b62269fc78fc36c9af5a6b89c835baa8af28ff5ad28c7028d60860320/tomli-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396", size = 100393, upload-time = "2026-03-25T20:22:02.137Z" }, { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, ] [[package]] name = "trio" version = "0.34.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "attrs" }, { name = "cffi", marker = "implementation_name != 'pypy' and os_name == 'nt'" }, { name = "idna" }, { name = "outcome" }, { name = "sniffio" }, { name = "sortedcontainers" }, ] sdist = { url = "https://files.pythonhosted.org/packages/92/dc/a2d25ed73ad49cfd79bf18d262577c3731c98e382284e28d522f49a0df35/trio-0.34.0.tar.gz", hash = "sha256:63b9485408bdfdde544fced107045a8c0086cdc4bd0ef2f797b9e0dd111b964b", size = 607457, upload-time = "2026-08-11T00:33:42.198Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/77/1f/555f1364bed52a92a864181962b77f1b15adadeacf23b86105324363e461/trio-0.34.0-py3-none-any.whl", hash = "sha256:6c7c9f49917694dcdcd5f67abd168df5599eca480d61f29854d17a61a75c2f05", size = 511840, upload-time = "2026-08-11T00:33:40.552Z" }, ] [[package]] name = "trio-typing" version = "0.10.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "async-generator" }, { name = "importlib-metadata" }, { name = "mypy-extensions" }, { name = "packaging" }, { name = "trio" }, { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b5/74/a87aafa40ec3a37089148b859892cbe2eef08d132c816d58a60459be5337/trio-typing-0.10.0.tar.gz", hash = "sha256:065ee684296d52a8ab0e2374666301aec36ee5747ac0e7a61f230250f8907ac3", size = 38747, upload-time = "2023-12-01T02:54:55.508Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/89/ff/9bd795273eb14fac7f6a59d16cc8c4d0948a619a1193d375437c7f50f3eb/trio_typing-0.10.0-py3-none-any.whl", hash = "sha256:6d0e7ec9d837a2fe03591031a172533fbf4a1a95baf369edebfc51d5a49f0264", size = 42224, upload-time = "2023-12-01T02:54:54.1Z" }, ] [[package]] name = "trustme" version = "1.2.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cryptography" }, { name = "idna" }, ] sdist = { url = "https://files.pythonhosted.org/packages/4b/c5/931476f4cf1cd9e736f32651005078061a50dc164a2569fb874e00eb2786/trustme-1.2.1.tar.gz", hash = "sha256:6528ba2bbc7f2db41f33825c8dd13e3e3eb9d334ba0f909713c8c3139f4ae47f", size = 26844, upload-time = "2025-01-02T01:55:32.632Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b5/f3/c34dbabf6da5eda56fe923226769d40e11806952cd7f46655dd06e10f018/trustme-1.2.1-py3-none-any.whl", hash = "sha256:d768e5fc57c86dfc5ec9365102e9b092541cd6954b35d8c1eea01a84f35a762a", size = 16530, upload-time = "2025-01-02T01:55:30.181Z" }, ] [[package]] name = "truststore" version = "0.10.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/53/a3/1585216310e344e8102c22482f6060c7a6ea0322b63e026372e6dcefcfd6/truststore-0.10.4.tar.gz", hash = "sha256:9d91bd436463ad5e4ee4aba766628dd6cd7010cf3e2461756b3303710eebc301", size = 26169, upload-time = "2025-08-12T18:49:02.73Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/19/97/56608b2249fe206a67cd573bc93cd9896e1efb9e98bce9c163bcdc704b88/truststore-0.10.4-py3-none-any.whl", hash = "sha256:adaeaecf1cbb5f4de3b1959b42d41f6fab57b2b1666adb59e89cb0b53361d981", size = 18660, upload-time = "2025-08-12T18:49:01.46Z" }, ] [[package]] name = "twine" version = "7.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "id" }, { name = "keyring", marker = "platform_machine != 'ppc64le' and platform_machine != 's390x'" }, { name = "packaging" }, { name = "readme-renderer" }, { name = "requests" }, { name = "requests-toolbelt" }, { name = "rfc3986" }, { name = "rich" }, { name = "urllib3" }, ] sdist = { url = "https://files.pythonhosted.org/packages/92/3c/58f808a359700f39a967dffede33efeac809262c03303fa3eec6afff8f49/twine-7.0.0.tar.gz", hash = "sha256:85cdb29c518efef867360ae4acd4b0dfd61c8654a22fca08e6f8539f05022177", size = 215032, upload-time = "2026-07-27T15:59:00.825Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/96/08/ddcdc06225eaad6de0e48e1002b06d919dbde20582d0662c7af51308e5d6/twine-7.0.0-py3-none-any.whl", hash = "sha256:b854164df26db268af05f49aa5c0344b10e27a494343ff05b1e0bad3b135f5a7", size = 43204, upload-time = "2026-07-27T15:58:59.26Z" }, ] [[package]] name = "typing-extensions" version = "4.15.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, ] [[package]] name = "urllib3" version = "2.8.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/e3/05/b17359e1cefb4f909b5e40b1b90a496d987258916dbbf88e842c729f510e/urllib3-2.8.0.tar.gz", hash = "sha256:63bf2ead4c879426ebf22ef2a781eeb4aa3b4ae798a0435506f8687fd5bb9b63", size = 458972, upload-time = "2026-09-15T19:29:36.253Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/92/9d/c4e665119135114480843e7ab388fa94d8480650450e6f8e26b70d323a4c/urllib3-2.8.0-py3-none-any.whl", hash = "sha256:0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3", size = 135717, upload-time = "2026-09-15T19:29:34.577Z" }, ] [[package]] name = "uvicorn" version = "0.52.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "h11" }, ] sdist = { url = "https://files.pythonhosted.org/packages/f2/0f/3f86e61397dd33bf2ccf28188c40db6a740658aeebbbf6e7dbc101a1f487/uvicorn-0.52.4.tar.gz", hash = "sha256:73acfee47a0b133c5de13d219492d62d8a31e935f4fe6e41a232451a15379f86", size = 100627, upload-time = "2026-08-19T06:27:41.821Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/f1/79/4a20b54ab0491485ccd8c077db2d39187c7f12b3e15485d38a7be37c81b4/uvicorn-0.52.4-py3-none-any.whl", hash = "sha256:f86e41a149d7d05a9969337e3946a9c171c06a5d42680896daaba624aeac8da1", size = 79871, upload-time = "2026-08-19T06:27:40.36Z" }, ] [[package]] name = "watchdog" version = "6.0.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220, upload-time = "2024-11-01T14:07:13.037Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/e0/24/d9be5cd6642a6aa68352ded4b4b10fb0d7889cb7f45814fb92cecd35f101/watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c", size = 96393, upload-time = "2024-11-01T14:06:31.756Z" }, { url = "https://files.pythonhosted.org/packages/63/7a/6013b0d8dbc56adca7fdd4f0beed381c59f6752341b12fa0886fa7afc78b/watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2", size = 88392, upload-time = "2024-11-01T14:06:32.99Z" }, { url = "https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c", size = 89019, upload-time = "2024-11-01T14:06:34.963Z" }, { url = "https://files.pythonhosted.org/packages/39/ea/3930d07dafc9e286ed356a679aa02d777c06e9bfd1164fa7c19c288a5483/watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", size = 96471, upload-time = "2024-11-01T14:06:37.745Z" }, { url = "https://files.pythonhosted.org/packages/12/87/48361531f70b1f87928b045df868a9fd4e253d9ae087fa4cf3f7113be363/watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", size = 88449, upload-time = "2024-11-01T14:06:39.748Z" }, { url = "https://files.pythonhosted.org/packages/5b/7e/8f322f5e600812e6f9a31b75d242631068ca8f4ef0582dd3ae6e72daecc8/watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", size = 89054, upload-time = "2024-11-01T14:06:41.009Z" }, { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480, upload-time = "2024-11-01T14:06:42.952Z" }, { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451, upload-time = "2024-11-01T14:06:45.084Z" }, { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057, upload-time = "2024-11-01T14:06:47.324Z" }, { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" }, { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" }, { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" }, { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077, upload-time = "2024-11-01T14:07:03.893Z" }, { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078, upload-time = "2024-11-01T14:07:05.189Z" }, { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077, upload-time = "2024-11-01T14:07:06.376Z" }, { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078, upload-time = "2024-11-01T14:07:07.547Z" }, { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065, upload-time = "2024-11-01T14:07:09.525Z" }, { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070, upload-time = "2024-11-01T14:07:10.686Z" }, { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067, upload-time = "2024-11-01T14:07:11.845Z" }, ] [[package]] name = "websockets" version = "16.1.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/21/f7/bc3a25c5ec26ce62ce487690becc2f3710bbc7b33338f005ad390db0b986/websockets-16.1.1.tar.gz", hash = "sha256:db234eda965dcce15df96bb9709f587cd87d4d52aaf0e80e2f34ec04c7670c57", size = 182204, upload-time = "2026-07-17T22:51:05.858Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/2b/03/47debfe28e9d6d354be5d777b67fd44c359b9eb299a5d103500bd7cc3e37/websockets-16.1.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d0fcf657e9f13ff4b177960ab2200237b12994232dfb6df16f1cfe1d4339f93c", size = 179566, upload-time = "2026-07-17T22:48:49.596Z" }, { url = "https://files.pythonhosted.org/packages/72/93/31efa1ed78c17e5cfc229fd449e3966e1b9cc15753204cd585cc8dd01f4a/websockets-16.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b852788aa51764e2d8e4cf5493d559326bcae5e38d16ba25ffa322b034df272a", size = 177250, upload-time = "2026-07-17T22:48:50.942Z" }, { url = "https://files.pythonhosted.org/packages/01/4a/542378ab3972b0c1cf1df3df3eff9591cea0d30c58c3aa3c4ddbc244e787/websockets-16.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1427fb4cf0d72f66333e2cacc3ff5f575bf2d7008166ce991a4a470b21d51a22", size = 177528, upload-time = "2026-07-17T22:48:52.59Z" }, { url = "https://files.pythonhosted.org/packages/33/d9/162321f63c7eed558e9e1798ed7a1e34a4f6dab51f35419e4ed7a4907979/websockets-16.1.1-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:da4ca1a9d72f9030b3146b8d7022719a9f3d478f61efe6f7dd51d243f61c51b2", size = 186859, upload-time = "2026-07-17T22:48:53.915Z" }, { url = "https://files.pythonhosted.org/packages/de/09/87df740f7430ce564bd52402e9c9458d4d0459cc7d2ee29e530c8204851b/websockets-16.1.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:86d7f0f8bdb25d2c632b72527325e4776430fd5bc61b9118de4e2b8ddb5f5b01", size = 188095, upload-time = "2026-07-17T22:48:55.384Z" }, { url = "https://files.pythonhosted.org/packages/d2/12/3d2703af7cc095f3c81904c92208cc1ae79affbc67376944b50ee9301f73/websockets-16.1.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7dfcad78ea1492ee3a9ec765cb7f51bbc17d477107aaf6b22abf7b2558d1c5a0", size = 191385, upload-time = "2026-07-17T22:48:56.742Z" }, { url = "https://files.pythonhosted.org/packages/1d/69/986aa0234a964a00f5149cfc46e136e96c8faad1c783474550f40d31aef4/websockets-16.1.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fb9a0a6dc3d1b3986cb88091b6899f0396651e0f74e2c9766ab8d6ffc3842e29", size = 188653, upload-time = "2026-07-17T22:48:58.134Z" }, { url = "https://files.pythonhosted.org/packages/35/6b/10f9d03e3970a69ba67bd3b46b87a929b586d0300fadbfe14f57c1f85490/websockets-16.1.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29dfa8114c4a620c69591c5973860f768eac29d3fd6904f37f34266cb219c512", size = 187426, upload-time = "2026-07-17T22:48:59.515Z" }, { url = "https://files.pythonhosted.org/packages/56/db/bb3aad62bf63d8bb3f0634b2eabffcfb3677a34bd19492110ff6869cf703/websockets-16.1.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6ff9417c0ada4d0f7d212f928303e5579bdf3ace4c802fa4afabb30995da58c3", size = 184882, upload-time = "2026-07-17T22:49:00.916Z" }, { url = "https://files.pythonhosted.org/packages/6c/4c/c09a2ea9bfbeccce52fdc383e5f28af4bc8843338aabac28c81489af6120/websockets-16.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8fe0b50da2d84535fb4f7b4bfa951280f97ce3d558a0443b541166d609e67b57", size = 187584, upload-time = "2026-07-17T22:49:02.283Z" }, { url = "https://files.pythonhosted.org/packages/c7/8b/31bb4eb4d9eaacf1fdd39d115772a8aeaedfc19b5dc262e57ffbc8a9d42c/websockets-16.1.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:34420aaa64440ebd51ac72ca8a45ef4626429438c9b02e633ae412ed43f925d3", size = 186174, upload-time = "2026-07-17T22:49:03.973Z" }, { url = "https://files.pythonhosted.org/packages/2f/e4/dc02d725610a1ad49e193ef91a548194d71bdc6cdf27da83067dd1f73995/websockets-16.1.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a6a61aff018180c9c50b7b0da33bfd29d378af3497429c95006c589a23a11648", size = 187986, upload-time = "2026-07-17T22:49:05.553Z" }, { url = "https://files.pythonhosted.org/packages/e0/73/30ed84c8bfd14c73d4af29d5ed9323c3073b48e0b7b23b67070f4e7fd59b/websockets-16.1.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:04fd29a0e2fe9414a95b00e92c67ae51bf900c50c0f8a4b2dafdad621f49ea1d", size = 185565, upload-time = "2026-07-17T22:49:06.959Z" }, { url = "https://files.pythonhosted.org/packages/7d/d3/4be8d4959f51e31b4f8fc0ece12b45bd3b6c0d15ea23b9990d9c11fc805f/websockets-16.1.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5c31aa7e39ee3e8a358573257f1c0bb5c52430d1b637030dd9c8cc2c282926be", size = 186598, upload-time = "2026-07-17T22:49:08.293Z" }, { url = "https://files.pythonhosted.org/packages/26/fa/abb38597a52d84ed9cfacadc7a0c6f2db282c0ab23cdf72b58a666a21227/websockets-16.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d14bfb217eb4701e850f1525c9d29d79c44794cdf1c299ead25f39f8c78dea81", size = 186834, upload-time = "2026-07-17T22:49:09.766Z" }, { url = "https://files.pythonhosted.org/packages/59/80/1119ad08a228b90c4eb77fbe48df7836731a605f5f881ba701ca826a4a65/websockets-16.1.1-cp311-cp311-win32.whl", hash = "sha256:2e28e602bb13da44fbe518c1781a88e3b9d4c3d48d02c9bad83e546164336f57", size = 179940, upload-time = "2026-07-17T22:49:11.196Z" }, { url = "https://files.pythonhosted.org/packages/71/b2/e511c1c6f64a95c2f3fc54bffda0e14eaa7e9442be605c29270f7589b918/websockets-16.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:7421fad442de870a8cbf2287d1cad7e706ece0dbfeba5e911df132cbdc1cb56a", size = 180239, upload-time = "2026-07-17T22:49:12.519Z" }, { url = "https://files.pythonhosted.org/packages/17/9d/681cda21c9eee743203a6cb79b9d3d05adad9aa60ec660c6c9bf4dd619ca/websockets-16.1.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:cc97814dfb786a83b6e2dc2e79351e1b83e6d715647d6887fcabd83026417a00", size = 179600, upload-time = "2026-07-17T22:49:13.92Z" }, { url = "https://files.pythonhosted.org/packages/fb/8d/6195a88b45e8d2a8f745fc2046e36f885a3c9763e6767d2c46229bf9510c/websockets-16.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e047dc87ef7ca50f4d309bf775ad4a71711c58556d75d7bd0604b2317f43e94b", size = 177272, upload-time = "2026-07-17T22:49:15.453Z" }, { url = "https://files.pythonhosted.org/packages/73/e3/fe2d498c64dea0095c9a9f9a351af4cd6eef31b618395582bc1f38ba45ff/websockets-16.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:01fbdcbac298efe19360b94bc0039c8f746f0220ba570f327577bfee81059175", size = 177542, upload-time = "2026-07-17T22:49:16.875Z" }, { url = "https://files.pythonhosted.org/packages/fe/ed/f1831681fce0e3242346e5458486003c5f124ed69e5e0b847fd029db4973/websockets-16.1.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0f62863e8a00a6d33c3d6566ec0b89f23787b747ffe0c3bc71ec0e76b82c94b1", size = 187137, upload-time = "2026-07-17T22:49:18.323Z" }, { url = "https://files.pythonhosted.org/packages/6f/79/4ff9dcc1bb46f6b4c536936dde1fd60f9b564f3304307274db97f4c9496d/websockets-16.1.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8087e82f842609734c9b5a1330464f8e94e346ba0e18c832c08bafa4b0d63c15", size = 188374, upload-time = "2026-07-17T22:49:19.65Z" }, { url = "https://files.pythonhosted.org/packages/62/c3/5c49b6efb36cab733d23773f6de575e1dba65736ead17d5d2b2a1daef779/websockets-16.1.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2bb5d041a8307d2e18782e7ce777f6fdb1e8c2f5d09291484b18c294b789d9aa", size = 191155, upload-time = "2026-07-17T22:49:21.331Z" }, { url = "https://files.pythonhosted.org/packages/6e/f6/56ccceda3a4838d18f1d40821480da4775397e8b1eecf4031e20c50e2e90/websockets-16.1.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1db4de4a0e95673f7545d393c49eeb0c2f18ac1ef93073218c79d5cdb2ee75ab", size = 189011, upload-time = "2026-07-17T22:49:22.889Z" }, { url = "https://files.pythonhosted.org/packages/86/d6/ad5286241a2bce1107e2798d3bfbd62cf79aee167bdb654f8cb1e9dbf949/websockets-16.1.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f17dbe07eb3ea7f99e4df9b7e0efefe80fbf30d37a8cc4d561a0aed310bc8847", size = 187766, upload-time = "2026-07-17T22:49:24.339Z" }, { url = "https://files.pythonhosted.org/packages/bc/67/d65c970b7e347fdca69479beb7811c2060529956730a7a4e3ae7c66b0e31/websockets-16.1.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4b57693728576d84ede0a77987ab16881b783d2cd9f1dc180a8fbbc3f79c4428", size = 185173, upload-time = "2026-07-17T22:49:25.743Z" }, { url = "https://files.pythonhosted.org/packages/1d/5b/14af3cd4ee69d8ea9baca58f3dc3cfb1ba78332a347fd478cb096549d60e/websockets-16.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2a636ff1e7a5c4edf71ef0e79adae7f25dba93b4fcbe3dc958733477ffeb0eaf", size = 187809, upload-time = "2026-07-17T22:49:27.147Z" }, { url = "https://files.pythonhosted.org/packages/7b/11/be301710d70de97e3e7b3586e6d492c9c06d6a61bf1c2202c36cf0c75607/websockets-16.1.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d6bec75c290fe484a8ba4cacdf838501e17c06ecfbbf31eede81a9e431bd7751", size = 186412, upload-time = "2026-07-17T22:49:28.611Z" }, { url = "https://files.pythonhosted.org/packages/db/07/fe1435bf6fe738a3d3b54dbe0c18dabf12cba4d909ac8b58b539ce27c1f4/websockets-16.1.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:54509b8e92fee4453e152b7558ddef37ce9705a044922f2095a6105e3f80c96f", size = 188290, upload-time = "2026-07-17T22:49:29.965Z" }, { url = "https://files.pythonhosted.org/packages/8a/0a/81f394aff8efcbb01208c1ced77df0a3c7fcce584a88c7273663697946c2/websockets-16.1.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:f0aa4aad3b1b69ad3fd85a0fd0952ec64331c762bd77ec51cc814170873890b2", size = 185844, upload-time = "2026-07-17T22:49:31.447Z" }, { url = "https://files.pythonhosted.org/packages/39/5c/dd485b995473f415510251fe9bd708f2d24458f439fce958daf8d66dc7c6/websockets-16.1.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:42290eb6db4ccaca7012656738214f8514082fb6fa40cdeb61bb9a471b52e383", size = 186823, upload-time = "2026-07-17T22:49:33.104Z" }, { url = "https://files.pythonhosted.org/packages/9d/0b/f78de76ff446f1e66af12b43c48a35f31744de93cfdec2f4ea67d5d7bbf1/websockets-16.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:53260c8930da5771cec89439bff99c20c8cb03ddb9588b980697355a83cd4bd3", size = 187102, upload-time = "2026-07-17T22:49:34.616Z" }, { url = "https://files.pythonhosted.org/packages/37/a1/4cf892007778eaf84ad162bfc98046e0ed89b63ac55949e3236626b2a23f/websockets-16.1.1-cp312-cp312-win32.whl", hash = "sha256:1d27fa8462ad6a1cb36206a3d0640b2333340def181fae11ed7f9adeaa5c0747", size = 179943, upload-time = "2026-07-17T22:49:36.213Z" }, { url = "https://files.pythonhosted.org/packages/d9/de/6abe251d28c3a3f217096575400b27750b18e0b1d2fff3a2a239960fea07/websockets-16.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:b436f6ec4fc3a6b4237c84d3f83170ed2b40bb584222f0ac47a0c8a5921980c7", size = 180243, upload-time = "2026-07-17T22:49:37.626Z" }, { url = "https://files.pythonhosted.org/packages/ce/fd/6ec6c6d2850aea25b1b2aa9901a016980bb87d01e89b3eb00470b1b5d471/websockets-16.1.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ab59169ace05dcb49a1d4118f0bde139557adf45091bd85747e36bf5de984dd1", size = 179587, upload-time = "2026-07-17T22:49:38.959Z" }, { url = "https://files.pythonhosted.org/packages/5f/d8/1d299d2dd34087db39831a34cc645ef8a6f89d78efada6983093513cd81c/websockets-16.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5e3b7d601f6f84156b08cc4a5e541c2b50ad7b36cfc302b657a12477c904a5df", size = 177272, upload-time = "2026-07-17T22:49:40.293Z" }, { url = "https://files.pythonhosted.org/packages/3d/86/0a70d3ae2f0f2256bb41302d9804dbca65d4360281e7feb3e1f94102ac46/websockets-16.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cd2ca96a082a36964aca83e992f72abeb61b7306c1a6cba4c7d06a7b93750cac", size = 177530, upload-time = "2026-07-17T22:49:41.786Z" }, { url = "https://files.pythonhosted.org/packages/b5/c2/c676c69444d9db448b3f0a55a98dcc534affce0bce961d9d2f0b8499b10a/websockets-16.1.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f5d497865f05bb222cab7016c6034542e84e5f29f49c6fd3f4939cda7197b5b8", size = 187197, upload-time = "2026-07-17T22:49:43.658Z" }, { url = "https://files.pythonhosted.org/packages/0b/13/88137fbaf726ebe29d62c1117fa11fa2bbb6209dc79d4ad738efbe36a2aa/websockets-16.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bae954c382e013d5ea5b190d2830526bfa45ad121c326da0049b8c769f185db6", size = 188433, upload-time = "2026-07-17T22:49:45.147Z" }, { url = "https://files.pythonhosted.org/packages/01/6d/46c2f2ce6751cb26f39293e1ecbf8544cb01321397cd476c2756b98c216d/websockets-16.1.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e09f753a169951eb4f28c2c774f71069304f66e7277e0f5a2892423599cfa854", size = 189868, upload-time = "2026-07-17T22:49:46.581Z" }, { url = "https://files.pythonhosted.org/packages/29/2b/170a9e8097636cfde4dc3c592b6e00b18a44a2f5407606d96ca542dd5838/websockets-16.1.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:024193f8551a2b0eafbdd160911012c4e6c228c28430c84433253299a9e42d6a", size = 189059, upload-time = "2026-07-17T22:49:47.972Z" }, { url = "https://files.pythonhosted.org/packages/a7/48/f0d4ebc9ab4b473b8861b9e20fdb663d515d42f7befdf62cdb60fee7a1ec/websockets-16.1.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:aabe464bfd13bd25f4821faf111da6fefdc389f870265a53105580e45b0a2e49", size = 187814, upload-time = "2026-07-17T22:49:49.344Z" }, { url = "https://files.pythonhosted.org/packages/d5/ba/39a41d3ae8e72696a9492581900611c5a91e2b07563b0bcd2523adea9854/websockets-16.1.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a28fcbc9b6baf54a2e23f8655f308e4ccc6afdd7266f8fe7954f320dcda0f785", size = 185229, upload-time = "2026-07-17T22:49:50.787Z" }, { url = "https://files.pythonhosted.org/packages/3c/36/ac15b604f850d1907f0a85ed721cefe47cd45034b3620069b829746cccbe/websockets-16.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:79eace538c6a97e96d0d03d4f9d314f9677f5ed85a8a984992ffd90b13cb8a56", size = 187874, upload-time = "2026-07-17T22:49:52.228Z" }, { url = "https://files.pythonhosted.org/packages/a8/f3/3fbd5d71d59299c3770faa5884d4f45070236ca5a35ab3a61830812c409a/websockets-16.1.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:496af849a472b531f758dbd4d61338f5000538cb1a7b3d20d9d32a264517f509", size = 186469, upload-time = "2026-07-17T22:49:53.776Z" }, { url = "https://files.pythonhosted.org/packages/b4/fc/dd90349bba58af2a53ef2ddd9c32716c81eb6d59a0687939fff561860878/websockets-16.1.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:5283810d2646741a0d8da2aa733d6aefa0545809afccb2a5d105a26bc45125f1", size = 188347, upload-time = "2026-07-17T22:49:55.202Z" }, { url = "https://files.pythonhosted.org/packages/4c/f3/f73ba86427682da59b78c11d77ba56d5b801c32e84afe79b274bbd6a9bb2/websockets-16.1.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:4e3b680b1e0a27457e727a0d572fd81dffa87b6dbf8b228ab57da64f7d85aead", size = 185903, upload-time = "2026-07-17T22:49:56.75Z" }, { url = "https://files.pythonhosted.org/packages/34/7c/f95eb20e80104173b3a0a092291f89ea4047ef6e608e0a57ca06eb14eecb/websockets-16.1.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:69159730a823dde3ea8d08783e8d47ef135a6d7e8d44eb127e32b321c9db8e3e", size = 186855, upload-time = "2026-07-17T22:49:58.467Z" }, { url = "https://files.pythonhosted.org/packages/b0/35/dd875b3e050ff232d60fa377707f890e369f74d134f1be32e8f68879747c/websockets-16.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ed5bb271084b46530ee2ddc0410537a9961152c5ccba2fc98c5276d992ccba87", size = 187140, upload-time = "2026-07-17T22:50:00.016Z" }, { url = "https://files.pythonhosted.org/packages/e8/dc/5cbfcb41824502f6af93b8f3943a4d06c67c23c7d2e31eb18748c4a5b2a7/websockets-16.1.1-cp313-cp313-win32.whl", hash = "sha256:cfb70b4eb56cac4da0a83588f3ad50d46beb0690391082f3d4e2d488c70b68ea", size = 179928, upload-time = "2026-07-17T22:50:01.685Z" }, { url = "https://files.pythonhosted.org/packages/b0/c1/71e5deb5b7f8f226997ab64908c184ac3105c0155ce2d486f318e5dd08a8/websockets-16.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:d9531d9cbeac99af6f038fb1bc351403531f7d634a2c2e10e2f7c854c6ed5b68", size = 180242, upload-time = "2026-07-17T22:50:03.117Z" }, { url = "https://files.pythonhosted.org/packages/73/a2/ba78a164eeea4620df4a4df4bd2ed6017438c4655cc0f36f2c0bc0432355/websockets-16.1.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:443aefe96b7fdb132e2a70806cca1f2af49bb3f28e47abcd7c2e9dcf4d8fa1b8", size = 179635, upload-time = "2026-07-17T22:50:05.001Z" }, { url = "https://files.pythonhosted.org/packages/b9/08/d26d7a7628cd4ac34cbbdb63ac80914ca842ed8e42938c40a53567806df3/websockets-16.1.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:6456ff333092d509127d75a638cb411afae8ff17f092635015d1902efec8a293", size = 177320, upload-time = "2026-07-17T22:50:06.427Z" }, { url = "https://files.pythonhosted.org/packages/0f/45/ebec83e6269536aa5932533c67b0af5c781f3e73fdbcd68672dcf43f4f44/websockets-16.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:fce6c48559c86d1ac3632ccb1bebc7d5442fbe79bd9bb0e40379ee54be2a4051", size = 177544, upload-time = "2026-07-17T22:50:07.834Z" }, { url = "https://files.pythonhosted.org/packages/c9/d5/abc614d2297f6c1c3e01e61260364457a47c25cc1cf6a879038902bc6aa8/websockets-16.1.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:92b820d345f7a3fc7b8163949ee92df910f290c3fc517b3d5301c78065adafe1", size = 187270, upload-time = "2026-07-17T22:50:09.275Z" }, { url = "https://files.pythonhosted.org/packages/52/71/4c99af3b87dff1b2927981f6876607d4acb45338c665242168d3982f7758/websockets-16.1.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2a606d9c24035242a3e256e9d5b77ed9cd6bccfcb7cf993e5ca3c0f6f68fb6a7", size = 188509, upload-time = "2026-07-17T22:50:10.722Z" }, { url = "https://files.pythonhosted.org/packages/9b/b4/5c8ca14b0df7eb84ed0524165c5359150210140817a3312aee57bf62a1cf/websockets-16.1.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:414e596c75f74e0994084694189d7dc9229fb278e33064d6784b73ffbba3ca31", size = 189882, upload-time = "2026-07-17T22:50:12.293Z" }, { url = "https://files.pythonhosted.org/packages/25/c1/bedfba9e70557129cb8083748d167bdcc01483dedf0f0df143676df05cbe/websockets-16.1.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:536676848fc5961aca9d20389951f59169508f765637a172403dc5434d722fa0", size = 189114, upload-time = "2026-07-17T22:50:13.789Z" }, { url = "https://files.pythonhosted.org/packages/df/09/aa835b2787835aebd839114be5de51b797cb480b63ba42b26d34dfe147cb/websockets-16.1.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:97fd3a0e8b53efa41970ac1dff3d8cf0d2884cadeb4caaf95db7ad1526926ee3", size = 187861, upload-time = "2026-07-17T22:50:15.179Z" }, { url = "https://files.pythonhosted.org/packages/20/26/f6408330694dbc9830857d9d23bc14ac4f6875127a480cfdda8d5ca21198/websockets-16.1.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7b1b19636af86a3c7995d4d028dbe376f39b4bf31541146f9c123582a6c94562", size = 185286, upload-time = "2026-07-17T22:50:16.741Z" }, { url = "https://files.pythonhosted.org/packages/17/9a/e0675e70dd8a80762cf35bb18799d3f290a4890ffe6439bc51d222796083/websockets-16.1.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:41c8e77f17294c0ac18008a7309b99b34ee72247ef10b6dff4c3f8b5ac29896b", size = 187935, upload-time = "2026-07-17T22:50:18.213Z" }, { url = "https://files.pythonhosted.org/packages/33/c1/3234cfb86afde01b81e9bddcc6e534c440975d60a13991259e833069ab3e/websockets-16.1.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:9f63bcef7f4b02b06b35fc01c93b96c43b5e88e1e8868676caacf493d5a31f3a", size = 186444, upload-time = "2026-07-17T22:50:19.67Z" }, { url = "https://files.pythonhosted.org/packages/89/87/9c15206e1d778923d8daa9657de07aa62ea815e13448319c98458c37b281/websockets-16.1.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:dab9eb87869da2d6ed3af3f3adf28414baae6ec9d4df355ffc18889132f3436c", size = 188409, upload-time = "2026-07-17T22:50:21.28Z" }, { url = "https://files.pythonhosted.org/packages/f2/00/cf5de5c67676de2d3eef8b2a518f168f6796595447a5b7161ba0d012915c/websockets-16.1.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:43e3a9fdd7cbf7ba6040c31fae0faf84ca1474fef777c4e37912f1540f854499", size = 185958, upload-time = "2026-07-17T22:50:22.719Z" }, { url = "https://files.pythonhosted.org/packages/62/c0/731b6ddede2e4136912ec4cff2cffbda35af73546be4762c3d7bd3bd79af/websockets-16.1.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:056ae37939ed7e9974f364f5864e76e49182622d8f9751ac1903c0d09b013985", size = 186911, upload-time = "2026-07-17T22:50:24.108Z" }, { url = "https://files.pythonhosted.org/packages/8c/7f/39c634472c4469a24a7c09cecddffb08fac6d0e74f73881a94ee8a40a196/websockets-16.1.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:a0eadbbf2c30f01efa58e1f110eb6fa293261f6b0b1aa38f7f48707107690af9", size = 187204, upload-time = "2026-07-17T22:50:25.548Z" }, { url = "https://files.pythonhosted.org/packages/26/89/9667c256c256dafcc62d21328ce7a40067da857969b68ee9af375b0aaf72/websockets-16.1.1-cp314-cp314-win32.whl", hash = "sha256:195c978b065fa40910582464f99d6b15c8b314c68e0546549a55ed83f4735328", size = 179603, upload-time = "2026-07-17T22:50:27.086Z" }, { url = "https://files.pythonhosted.org/packages/bd/dd/1c099d6c0fc5deb6b46ccdbb6981fdb4b12c917869cb3952408409dc18db/websockets-16.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:4e8d01cc3bcae7bbf8167f944aeafefed590fae5693552bba9794a9df68371cc", size = 179948, upload-time = "2026-07-17T22:50:28.521Z" }, { url = "https://files.pythonhosted.org/packages/35/25/9956b2d5e0529d5d23924f21bba1440d4c5c88a562e4f08550871ffa97a7/websockets-16.1.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:0ffd3031ea8bda8d61762e84220186105ba3b748b3c8da2ae4f7816fac03e573", size = 179963, upload-time = "2026-07-17T22:50:29.982Z" }, { url = "https://files.pythonhosted.org/packages/17/06/55ffc976c488b6aee9ea05761ff7c4e88e7c1fd82818c8ca7b556ad2f90c/websockets-16.1.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:84a2cef8deffbd9ab8ee0ea546a2a6a7030c28f44e6cdd4547dbfeb489eb8999", size = 177497, upload-time = "2026-07-17T22:50:31.396Z" }, { url = "https://files.pythonhosted.org/packages/0c/e8/f7dac2e980bacc92bdc26cebae4ae4d50cae5380732c50980598fc0bbae4/websockets-16.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3df13f73af9b3b38ab1195eb299ecb67a4330c911c97ae04043ff74085728abe", size = 177698, upload-time = "2026-07-17T22:50:32.829Z" }, { url = "https://files.pythonhosted.org/packages/b2/39/26762f734113e22da2b942c3aca85798e0c0405d64c256549540ff31e5a1/websockets-16.1.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:23253dd5bcae3f9aaee0a1d30967a8dbd52e5d3cff93a2e5b84df57b77d4750d", size = 187561, upload-time = "2026-07-17T22:50:34.24Z" }, { url = "https://files.pythonhosted.org/packages/11/94/c3f330851806b9b02138b774d593478323e73c99238681b4b93efe64e02d/websockets-16.1.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c1c5705e314449e3308872fe084b8571ce078ee4fc55a98a769bdefe5917392", size = 188732, upload-time = "2026-07-17T22:50:36.088Z" }, { url = "https://files.pythonhosted.org/packages/d1/f2/eb2c450f052de334ae33cf200ece6e87b0e14d186807074e4eb1cd2cdea2/websockets-16.1.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:69e52d175a0a7d1e13b4b67ad41c560b7d98e8c6f6126eb0bda496c784faf8c7", size = 190872, upload-time = "2026-07-17T22:50:38.008Z" }, { url = "https://files.pythonhosted.org/packages/70/31/2ac8cecf3a74f7fed9132129fc3d90b3998a1554570c11a69b2a8c20332d/websockets-16.1.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1f79c89b5eb034d1722938a891916582f8f7f503f58ca22518a63c3f2cd18499", size = 189305, upload-time = "2026-07-17T22:50:39.53Z" }, { url = "https://files.pythonhosted.org/packages/6a/cf/8ab19650d3c0d4562c92e70ab47c257c4aa5c6a713ed87fe63766b31fefc/websockets-16.1.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:39f2a024af5c345ffe8fcf1ee18c049c024c94df393bb09b044a6917c77bde43", size = 188033, upload-time = "2026-07-17T22:50:40.912Z" }, { url = "https://files.pythonhosted.org/packages/66/d7/a49a38a6127a4acb134fb1912b215d900cc657605cff32445bf519f3acc4/websockets-16.1.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:952303a7318d4cbe1011400839bb2051c9f84fa0a35923267f5daba34b15d458", size = 185748, upload-time = "2026-07-17T22:50:42.559Z" }, { url = "https://files.pythonhosted.org/packages/95/3e/ad1fa40388c7f2e0bb2c7930d0090b6c5498594bd1cdaec18864df3d9e97/websockets-16.1.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:249116b4a76063d930a46391ad56e135c286e4562a18309029fc2c73f4ed4c62", size = 188285, upload-time = "2026-07-17T22:50:43.974Z" }, { url = "https://files.pythonhosted.org/packages/35/b8/d5db28ca264b9104f82196f92dc8843e35fd391f763d42e4ad358f5bc97e/websockets-16.1.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:61922544a0587a13fd3f53e4c0e5e606510c7b0d9d22c8444e5fae22a06b38cb", size = 186777, upload-time = "2026-07-17T22:50:45.474Z" }, { url = "https://files.pythonhosted.org/packages/42/9c/726cb39d0cc43ae848dce4aa2acb04eecc6738b1264ec6d700bf6bcfb9f8/websockets-16.1.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:46dcaa042cd1de6c59e7d9269fa63ff7572b6df40510600b678f0826b3c7af51", size = 188682, upload-time = "2026-07-17T22:50:46.973Z" }, { url = "https://files.pythonhosted.org/packages/be/c7/1168704de8c2dd483edabe4a22cbe4465dd8be8dd95561d214f9fe092871/websockets-16.1.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:38565aca3e01ea8734e578fb2118dade0ecb0250533f29e22b8d1a7a196cf4d0", size = 186377, upload-time = "2026-07-17T22:50:48.413Z" }, { url = "https://files.pythonhosted.org/packages/ca/40/f9ff2d630ffce4e7dfea0b2288e1caf9ebbf9ff8a9ec9396136ce8b94935/websockets-16.1.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:42f599f4d48c7e1a3338fdaac3acd075be3b3cf02d4b274f3bf2767aedd3d217", size = 187148, upload-time = "2026-07-17T22:50:49.845Z" }, { url = "https://files.pythonhosted.org/packages/b5/71/e177c8299f78d7cbe2d14df228643c10c70c0e86e108e092056bbcc16e46/websockets-16.1.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:dcc04fedf83effaeb9cce98abc9469bb1b42ef85f03e01c8c1f4438ef7555737", size = 187578, upload-time = "2026-07-17T22:50:51.619Z" }, { url = "https://files.pythonhosted.org/packages/49/b2/b6987faf330f5af5c787a2610124c2e8403d51724f9001ec4fff6311fe7a/websockets-16.1.1-cp314-cp314t-win32.whl", hash = "sha256:8483c2096363120eea8b07c06ae7304d520f686665fffd4811fad423930a65d7", size = 179729, upload-time = "2026-07-17T22:50:53.269Z" }, { url = "https://files.pythonhosted.org/packages/a2/6e/fbac6ed878dd362fbad7d415fa4f84d38e3e33fed8cde45c64e783acf826/websockets-16.1.1-cp314-cp314t-win_amd64.whl", hash = "sha256:bcce07e23e5769375158f5efdcdafa8d5cd014b93c6683865b840ed65b96f231", size = 180072, upload-time = "2026-07-17T22:50:54.969Z" }, { url = "https://files.pythonhosted.org/packages/e1/ed/71fea6e141590cafc40b14dc5943b0845606bee87bdb52a21b6a73eb4311/websockets-16.1.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:820fb8450edddae3812fd58cbc08e2bf22812cb248ecb5f06dbb82119a56e869", size = 177185, upload-time = "2026-07-17T22:50:56.665Z" }, { url = "https://files.pythonhosted.org/packages/01/ec/00e7eeca200facf9266a83e4cbbf1bed0e67fba1d4d45031d3e5b3d81b5c/websockets-16.1.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:125f22dbefaf1554fea66fc83851490edb284ce4f501d37ffed2752f418332d9", size = 177459, upload-time = "2026-07-17T22:50:58.197Z" }, { url = "https://files.pythonhosted.org/packages/75/fd/5774c4b33f7c0d8f0c51809c8b3a93456c48e3543579262cfa64eb5f522e/websockets-16.1.1-pp311-pypy311_pp73-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:30bbe120437b5648a77d3519b7024ea09530e0b5b18d3698c5a0ae536fe0cc2e", size = 178294, upload-time = "2026-07-17T22:50:59.641Z" }, { url = "https://files.pythonhosted.org/packages/37/c3/48e2c03d2bd79bb45948841c592d24156312dd5f58cdf8f549febe652fb6/websockets-16.1.1-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b6b9dadbef0cccd9f4c4ee96b08898afa73e26803bbe0f6aeb5bb12b0074206d", size = 179190, upload-time = "2026-07-17T22:51:01.129Z" }, { url = "https://files.pythonhosted.org/packages/2d/3f/73e511ecf2496ceac57dd4ed8388efe2bcf0769338a2dbf242c8366ae87e/websockets-16.1.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:56cd5fc4f10a9ea8aa0804bddb7b42506cf9e136046f3b4c27de8fec9e2ecba5", size = 180330, upload-time = "2026-07-17T22:51:02.603Z" }, { url = "https://files.pythonhosted.org/packages/be/4d/2d0d67834092e354d2b0498f014a41249a89556bc406cf86f3e1557bb463/websockets-16.1.1-py3-none-any.whl", hash = "sha256:6abbd3e82c731c8e531714466acd5d87b5e88ac3243465337ba71d68e23ae7e3", size = 173814, upload-time = "2026-07-17T22:51:04.184Z" }, ] [[package]] name = "werkzeug" version = "3.1.9" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a4/34/4dd12fc8bb7d61c91467ec3efe415ffa7d5456f799954b40c5bbaeae470e/werkzeug-3.1.9.tar.gz", hash = "sha256:55ca7c70a75689be937aa27f8ff4b018f06ff4838fc73045560bf0f5a1291060", size = 940188, upload-time = "2026-09-27T18:33:41.637Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/a1/38/df03f564f43cec2684823f3cccae1a652ee7face1cbaa76fb223096e64d7/werkzeug-3.1.9-py3-none-any.whl", hash = "sha256:6392e50c78460ba618e5b21f08a71f59c99ce99cdc6cf6e3dd7e6ccca8754fab", size = 228700, upload-time = "2026-09-27T18:33:39.685Z" }, ] [[package]] name = "wsproto" version = "1.3.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "h11" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c7/79/12135bdf8b9c9367b8701c2c19a14c913c120b882d50b014ca0d38083c2c/wsproto-1.3.2.tar.gz", hash = "sha256:b86885dcf294e15204919950f666e06ffc6c7c114ca900b060d6e16293528294", size = 50116, upload-time = "2025-11-20T18:18:01.871Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl", hash = "sha256:61eea322cdf56e8cc904bd3ad7573359a242ba65688716b0710a5eb12beab584", size = 24405, upload-time = "2025-11-20T18:18:00.454Z" }, ] [[package]] name = "yarl" version = "1.25.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "multidict" }, { name = "propcache" }, ] sdist = { url = "https://files.pythonhosted.org/packages/75/16/e8be8e2fb175bbf41a0680381a319f1199fae256588241a2ac8677eafb49/yarl-1.25.1.tar.gz", hash = "sha256:03dd38de09bc213e9a8b29761eec33ee1d5318dac0e49d8af36e4d27830e23a7", size = 246245, upload-time = "2026-09-15T19:35:02.264Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/83/b3/2cea721d495ca57f8f414aa4867ee263f486b274e07463158cf52f02ba7f/yarl-1.25.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9d693bf4bf534e9ba3ae2780cfd577f5135629f7b5ac653490859d0b77864865", size = 143794, upload-time = "2026-09-15T19:30:26.946Z" }, { url = "https://files.pythonhosted.org/packages/55/e6/cd145cff8e5cf60b8b3c41fbecfa2a45028a8dec3fbc52bec03595ff3d3b/yarl-1.25.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ab2054c5531af2a9ba7b69b8ec91e4f884420e83a8c5e579b013084cb57e5e5d", size = 103993, upload-time = "2026-09-15T19:30:28.661Z" }, { url = "https://files.pythonhosted.org/packages/ce/7c/fbb40fe2d53747c40aa36a9e2bd2178a202f942bda0b670f3306d4aefbce/yarl-1.25.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:564fdc7085d2245ab84f88882fdb1d6ac0723124bff6ded35bfb1c00f812630d", size = 104010, upload-time = "2026-09-15T19:30:31.069Z" }, { url = "https://files.pythonhosted.org/packages/f0/0b/5a516f70641092283f57cf3670bdb75e7327bcc0dcb5038697e4dfbfd569/yarl-1.25.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:acae6b45d1ace09b6ba3876da43b88366ef368f73b988c7f57e14231753d4420", size = 116444, upload-time = "2026-09-15T19:30:32.894Z" }, { url = "https://files.pythonhosted.org/packages/b6/8a/d1a627f827b0a404ae0f5647cab0534959081cde13b0756a783469fb3b5e/yarl-1.25.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1fb2a01ba8cd9c5d2c5dc1ec35e0fc951d04b4f037541d4ac090c993ce58b3d7", size = 107565, upload-time = "2026-09-15T19:30:35.188Z" }, { url = "https://files.pythonhosted.org/packages/aa/cf/c8e0aaec886840a6c4480fe44eaec7cd4319f79a563b79321473be79c56f/yarl-1.25.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e92b6bcc741b86d67606c40d3cb9c7cc8e6c737f81e31f4a94efc204456c92e3", size = 125006, upload-time = "2026-09-15T19:30:37.1Z" }, { url = "https://files.pythonhosted.org/packages/50/26/0cce366d54a93cdc8342965dc7663385e4db161625cc1e8b18e786753d24/yarl-1.25.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:72c34ac7ad4314c19362d5ce27626dcc8429bd30bbf8c179f4234078851f9492", size = 128717, upload-time = "2026-09-15T19:30:38.904Z" }, { url = "https://files.pythonhosted.org/packages/95/0c/a71501bbc1a674ff72c4d6c2b75f4d9a5af819f5244c3a7558080a8802c5/yarl-1.25.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5add7b4ca7afeea91d52e4d4e4db3b1fe9885b71f07054560d8c4296b7441a2", size = 117728, upload-time = "2026-09-15T19:30:40.809Z" }, { url = "https://files.pythonhosted.org/packages/e7/6f/c3267ca01defeed9ed9c4ff9b17bd54915432c405945233265b707475d1c/yarl-1.25.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:def538065f9e4d4cf1ae164bd59aba00dfa84f03923e0de4c3788f252d6bcd17", size = 116224, upload-time = "2026-09-15T19:30:42.818Z" }, { url = "https://files.pythonhosted.org/packages/8f/69/fad57ee52d648431718ee0f1f68966a99c1352c3924688ffbdcc9d3fe51a/yarl-1.25.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a191bfdb30a79b98e5d175d75285f9fcb78bf0e46ba5efda042e1c72071a0de", size = 116299, upload-time = "2026-09-15T19:30:44.966Z" }, { url = "https://files.pythonhosted.org/packages/2a/d4/6a8c1e29f33338687ca278cba0a8fbf6525a322c2c02a9a500ccbe041152/yarl-1.25.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:71f42c5b9a948c113bbdebfa544598321431d064ff959d32e99b1feb61d68345", size = 108625, upload-time = "2026-09-15T19:30:46.874Z" }, { url = "https://files.pythonhosted.org/packages/e8/d2/3a35ae791c9cb6522c106923ff25c3230d999091e5e65511bca23bbd9914/yarl-1.25.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:72849d892954be4d09e569b8b831ac39ce58417fedc767d4308a0fe542018a40", size = 124515, upload-time = "2026-09-15T19:30:49.082Z" }, { url = "https://files.pythonhosted.org/packages/be/fd/2b022109a6b4af0f7dc371cf7500af380b0d4f034010243e1b0ce218dc93/yarl-1.25.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:efb01a106f971cb3752856bca2318bbdf7f01bd8823779c461586cbe5ffd5258", size = 115711, upload-time = "2026-09-15T19:30:51.208Z" }, { url = "https://files.pythonhosted.org/packages/18/59/f7586271136c3ddb0126bbfe661844699369b76b555fe38c4efe86870b2e/yarl-1.25.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a1daf47cd95a7c3a63456336bc5aaa8c86dd3a47d07ed3d0e76132ae4666a5a1", size = 122751, upload-time = "2026-09-15T19:30:53.535Z" }, { url = "https://files.pythonhosted.org/packages/a0/0b/07f7a2d881f7e16c385b47fc1753382600847cad305dcc7fa0c25828acf8/yarl-1.25.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9489e6abf47ba37f332075a91444c7cfedb03e6ce99fbb2f116bfe1ce810da3b", size = 117983, upload-time = "2026-09-15T19:30:55.277Z" }, { url = "https://files.pythonhosted.org/packages/aa/9d/8cdceec66a9b940700cb45931741403f045b162afd79bcb93c41cadd0972/yarl-1.25.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7306dee25b8a0e737363f347362b875094b4dc4e367311470656ae420fdbf8e", size = 102894, upload-time = "2026-09-15T19:30:57.606Z" }, { url = "https://files.pythonhosted.org/packages/17/f1/7ec357db1d3ad2863542d71e8fe64a126bbec17b134cd7d30951196809a5/yarl-1.25.1-cp311-cp311-win_arm64.whl", hash = "sha256:abb1384477f5901d436b5d2e5465954de46ea6098f59163d243660b5c4461d35", size = 98609, upload-time = "2026-09-15T19:30:59.705Z" }, { url = "https://files.pythonhosted.org/packages/75/b3/cd32ac66ae622b854c2df0ac52106dda220d361b65a64fde7d5b3684aa3f/yarl-1.25.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:94d7aa6debf92a1dd14cb5280b083a764169a13cfb23a452111160274ed989f4", size = 144798, upload-time = "2026-09-15T19:31:01.821Z" }, { url = "https://files.pythonhosted.org/packages/61/fb/a2c52a8007c2051ba74662afb112ecf3d00346af4c25e33df9d80fd14fb8/yarl-1.25.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:83d4a37e4b95da4d8bda930d6d35b75b4cdadbacbb4980cae290ea3100b5d51d", size = 104583, upload-time = "2026-09-15T19:31:04.05Z" }, { url = "https://files.pythonhosted.org/packages/be/dd/ee38aec8e09fdf957e50d4085453fbe202f56c6c3b4cf07b81cdb4f09ee9/yarl-1.25.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e029648f9c951db30e98a7d7ec90835db88ec4b32820efe2a9bdc2287e032eb6", size = 104325, upload-time = "2026-09-15T19:31:06.338Z" }, { url = "https://files.pythonhosted.org/packages/1e/b3/058dbfb1857b484c9cf9cc135659f50b85ce66e03c99e44dc2f7b6161f55/yarl-1.25.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4d781294bb815ecb5ea57ff6bbf8038e0a31a95fdf3e1788f66e0dc100d64b58", size = 115358, upload-time = "2026-09-15T19:31:08.593Z" }, { url = "https://files.pythonhosted.org/packages/db/39/29693446cf0cf6b15a0e2f75a5d40f93c56819b05b0622196f45e95b5cc0/yarl-1.25.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e12c538e00e7c1b286a07061046b90e8124e6a9793efae2c70db6a4aad07faad", size = 107658, upload-time = "2026-09-15T19:31:10.802Z" }, { url = "https://files.pythonhosted.org/packages/86/b3/3c4dd7e1af43b931fba95e0a722737f2ea94a6d199c802585282831d7abd/yarl-1.25.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7e4de3ac4adbad3d0bc7c6f4360a7dbff5de2f15e3b723be3198074e17fd9c40", size = 122660, upload-time = "2026-09-15T19:31:12.84Z" }, { url = "https://files.pythonhosted.org/packages/bd/b5/1b60dbc3cfc9c5712b15148c206748f2bc93953ffdbe25ea75b63dfc89c9/yarl-1.25.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:419f392a1da624877975709e3864dfe833af6cc7671b39318086d456e288380c", size = 126506, upload-time = "2026-09-15T19:31:15.088Z" }, { url = "https://files.pythonhosted.org/packages/bc/7b/ca212cbe170ac8b96e45317ecbcf9c3c3ecf0cdec98d5b088a9c4088929b/yarl-1.25.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c6f117789d22dce188e5754e8bc65b7e6ebf8cb73963b9fa761f672a5883769d", size = 117050, upload-time = "2026-09-15T19:31:17.241Z" }, { url = "https://files.pythonhosted.org/packages/cb/c3/72b4938cdbe619ad71ac156182faef4908846b84dc3ca4dbb4c4e6f84014/yarl-1.25.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:80e47012e730da131c9f059c80936783f9659aae22dc31c03c0595590d11ed54", size = 114174, upload-time = "2026-09-15T19:31:19.294Z" }, { url = "https://files.pythonhosted.org/packages/e8/43/268717870f9ba0cc9701a95181587f6dc8c5f387aab4aeecc83158f38a79/yarl-1.25.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e80f557716fd765439577131e526b8942ffc2c07bdbc5e39fa62f660ba1e963f", size = 114944, upload-time = "2026-09-15T19:31:21.414Z" }, { url = "https://files.pythonhosted.org/packages/da/84/baa5bf504d51fe062c4bcaf62936da97fffb43285978d0b39984824231fd/yarl-1.25.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:f61964f235a43738bfac50da46fc4254943a7eea3051aeb0b6fc7c992c29fadc", size = 108263, upload-time = "2026-09-15T19:31:23.388Z" }, { url = "https://files.pythonhosted.org/packages/a4/28/779a2ed9e0152a601a27039bed9aead3f0b79797a67e2c44bfa444622dd8/yarl-1.25.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e546fe1d4a93ebc2910f0d768baff19faa09843ab3f2036a67ed6e69fae4419d", size = 122184, upload-time = "2026-09-15T19:31:25.343Z" }, { url = "https://files.pythonhosted.org/packages/f8/1f/118e9e5b8f07694d63fd3222e801d7782270003f1a222aa798df3f8d5933/yarl-1.25.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:cce0727fd5ac04d372fa9bbfde9febc2bcf209aadfcf0468e45dec72719895d1", size = 114001, upload-time = "2026-09-15T19:31:27.465Z" }, { url = "https://files.pythonhosted.org/packages/0f/ae/a4cf1cf372313734b17996d4007f9f73596e7a178b9485802e5494ecf484/yarl-1.25.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af4ea5b37403ef4e30f3927eaed540db942bde01d8d3ff083527c0704d1c9c68", size = 120565, upload-time = "2026-09-15T19:31:29.47Z" }, { url = "https://files.pythonhosted.org/packages/05/79/ad94f93ca731bc9e44d321833ab96b82a4f9f5f63cf773f81a4aeea5ecc1/yarl-1.25.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:68782fdb4027b8d1eee25ec35e9a6db05e863b899eb0310b3a33b6c3fef55707", size = 117060, upload-time = "2026-09-15T19:31:31.367Z" }, { url = "https://files.pythonhosted.org/packages/bb/cc/51a7b4abf4ac593b8e7eb3794b28e5a35ae26eed8bc04787628d215af82f/yarl-1.25.1-cp312-cp312-win_amd64.whl", hash = "sha256:7d575b54cb3863ef9bc290ea4b009999d55dc237326131e4853cf33e888fee03", size = 102593, upload-time = "2026-09-15T19:31:33.329Z" }, { url = "https://files.pythonhosted.org/packages/9d/21/0941a6b93a58b59a1ec75e5333bf06929b671309c43c0cd201c172d9c39f/yarl-1.25.1-cp312-cp312-win_arm64.whl", hash = "sha256:bc3ac7bf569f6b64dad04dd7808c7872dae8a97df657856eac05e9b7e3614a85", size = 97697, upload-time = "2026-09-15T19:31:35.855Z" }, { url = "https://files.pythonhosted.org/packages/7b/ed/2f3129bbcc9a5c8ba12cc2b29d8060a3bab9c8043c456cfd4b5ca3188890/yarl-1.25.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:25868beca8b6765f8f7d0e11fe6dd7c66dd4b0793b9500286d20cc92352126a5", size = 143623, upload-time = "2026-09-15T19:31:37.966Z" }, { url = "https://files.pythonhosted.org/packages/17/e1/f1bc3390fdca352826676b531d0712736f156919090206700421d46b2c37/yarl-1.25.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:10b2fd95332f0d716d5eee3c9fb2ce8eada19082de7fee83d32e37992fd75c26", size = 104011, upload-time = "2026-09-15T19:31:40.25Z" }, { url = "https://files.pythonhosted.org/packages/a8/aa/50acc5c3e5da04172ae3c281c75405af4d2ca911e16120ab0563f4dffb66/yarl-1.25.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0f12afda4eea8c8994a76d4df1875c765194f5fbe8a9d197929ea303caee29ec", size = 103677, upload-time = "2026-09-15T19:31:42.46Z" }, { url = "https://files.pythonhosted.org/packages/30/d2/7d1e0ab9f8390e1fbcede5a6dbf70d23c96ad09b8c5567f3a514d1ddb0e2/yarl-1.25.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:14b79a30a93a3ce2e8832603fd0ab780ada281b0ba5110b519a634f2d7d7d1fc", size = 115392, upload-time = "2026-09-15T19:31:44.371Z" }, { url = "https://files.pythonhosted.org/packages/71/e1/5ba1e3a2a22139213655e760919038e8ed7e2d4a99826d0bbddb3beb96e5/yarl-1.25.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4bd6340d20ae2c7ca719b87b426e808e90743b676d05d4c26c4fb5ca71f41184", size = 107493, upload-time = "2026-09-15T19:31:46.273Z" }, { url = "https://files.pythonhosted.org/packages/f5/53/780653d5e0f73831f467cf13548912e5eec97f21dc49fc8daf21da027df4/yarl-1.25.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:126a2533570c554719ca40a1288fdee1700b6bc82e7131aa69fa85252d92e651", size = 122537, upload-time = "2026-09-15T19:31:48.654Z" }, { url = "https://files.pythonhosted.org/packages/03/92/d54fa70236c6036271c9c9c09fd978df5cbe3ef49ef6c46e9b833476d215/yarl-1.25.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a3faadac7d812ddac258feb57b9846b60c1b437c4f4b9ad42595c6f6fe4390df", size = 126170, upload-time = "2026-09-15T19:31:50.872Z" }, { url = "https://files.pythonhosted.org/packages/0e/b7/a82a49bf88340b837ef6972b508a1604ae377b9e6904b46b10cf5f1cf925/yarl-1.25.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be80550d9bfe83d9b62398a37081a90434e6df2d978ec345c3d2820de6beddab", size = 117012, upload-time = "2026-09-15T19:31:53.189Z" }, { url = "https://files.pythonhosted.org/packages/ef/78/5d684b411e3f3602464ee9b538db48205038f8605872985f61efb809ced0/yarl-1.25.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e07595c7d6f4db270ceede356a1bd1c07a34f1c26f958d1ed0cd7b48e0d2bba3", size = 114950, upload-time = "2026-09-15T19:31:55.694Z" }, { url = "https://files.pythonhosted.org/packages/2f/11/51d82b852c64f7fad0fc7a7ff3031517204887e874c722bbca839c0b23ac/yarl-1.25.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eb96ed1ae6c7d072d60840c0434aef07a2df611812810807fbc54263a6053e9a", size = 115428, upload-time = "2026-09-15T19:31:57.966Z" }, { url = "https://files.pythonhosted.org/packages/e4/49/9d1978049bf646b9ea918313926453c6901b71c92f097467777d47d36a88/yarl-1.25.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3feb99222553a8cbedfa52c2f59dd84c3f50d5b582c728d522caf8d72769a54b", size = 108428, upload-time = "2026-09-15T19:32:00.048Z" }, { url = "https://files.pythonhosted.org/packages/43/35/7b8f1ebb45d7ec3dda7d1909bf44f458de41ef91e2937f107733582a5166/yarl-1.25.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a2ed0ba415ccdf08f14bf544cb78346d0f76086707ffee24921a2c84dbf1305a", size = 121961, upload-time = "2026-09-15T19:32:02.436Z" }, { url = "https://files.pythonhosted.org/packages/63/d6/d8b689ab7ca26edeb85f6ff28812aac7a25376eefc1780e303a7bfbaceff/yarl-1.25.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:2b49375d22299b0a834c2bca72f39aaecc270d96fb24c30424899676f487b22a", size = 114961, upload-time = "2026-09-15T19:32:04.456Z" }, { url = "https://files.pythonhosted.org/packages/cf/d5/1a1798ea4dc6b7ee3260010a27907ebc697c95dae99817d817ed446d24aa/yarl-1.25.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ef74070ac553c59eb4f04258722066d6c6135b7baa03b2e9f2da65c096e96d98", size = 120036, upload-time = "2026-09-15T19:32:06.5Z" }, { url = "https://files.pythonhosted.org/packages/91/8d/b1b35ed7903da6669b1d367cb2c09436acd4ff508029b4f39a0c0c2058fc/yarl-1.25.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0a66db89ea473abeac4b70523cafd94db3772380e565f9d28af7a179b7af71fa", size = 117276, upload-time = "2026-09-15T19:32:09.401Z" }, { url = "https://files.pythonhosted.org/packages/3a/8f/4db01cef62caff0d7a4593ed694fb8a41a27a11158cab80d290221f13e57/yarl-1.25.1-cp313-cp313-win_amd64.whl", hash = "sha256:1f51020b2eb8a003c84925638ec63c21a750a4bddd3a22ec8eac6a742dadf1b9", size = 101945, upload-time = "2026-09-15T19:32:11.545Z" }, { url = "https://files.pythonhosted.org/packages/c0/5e/3ce00497c5c0babb74d4130c10c3828ccd215b4819d12020c42429f991ac/yarl-1.25.1-cp313-cp313-win_arm64.whl", hash = "sha256:b10dd0557ba422715b5206b3743192135a6022acca8baec51aa127d0a75db8fe", size = 97270, upload-time = "2026-09-15T19:32:14.127Z" }, { url = "https://files.pythonhosted.org/packages/80/cf/54023edfab7aa773b860503db0c56e962ccab0922803ee97988c176ea090/yarl-1.25.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:a9ca696eb02e5c02a8afd872ada510eba9b7fe6e68b9572c2e9a9b1941e31e2e", size = 143975, upload-time = "2026-09-15T19:32:16.416Z" }, { url = "https://files.pythonhosted.org/packages/d7/a8/e6c1be0e6761d0f2d10bbf33a3e1e02b99dc83874d92945d7b461a72481e/yarl-1.25.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:a5877f2255aab518ebe528289037699201d5dc5f045f2396cb30aa02db22f57f", size = 104018, upload-time = "2026-09-15T19:32:18.364Z" }, { url = "https://files.pythonhosted.org/packages/6e/bb/dda344765ffd3430afe1a1c66c866a57fae67786537d4f14607df6505ac1/yarl-1.25.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7a5c3115595995779ee21f2567035793911c3802a43c74f3fbb0314929ec67ac", size = 104156, upload-time = "2026-09-15T19:32:20.459Z" }, { url = "https://files.pythonhosted.org/packages/e5/5f/ed1538bcd06009fe990d6d283dd7667f639e62a81e35c6d8c6ef6c08fb3c/yarl-1.25.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77e5099b99b37f3cf79c246998ca9f7313a78054cd1809ec46bc1afad47e1c4c", size = 116025, upload-time = "2026-09-15T19:32:22.766Z" }, { url = "https://files.pythonhosted.org/packages/a2/af/2185daf56b99830d3356ecfada46faaa49945de6626e842b7728088d4980/yarl-1.25.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6efaf45df6a849cef613a03a94c845647456662f85438c886bb67a9c027c8c2c", size = 106985, upload-time = "2026-09-15T19:32:24.749Z" }, { url = "https://files.pythonhosted.org/packages/c1/65/bc1ae564fb4b04a30b6a8f250e787772581c57e4c3d5cf07ac3359de3103/yarl-1.25.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d5f90e44653c4e0f78501ed9bb7d3fce835a8d62b7c6ed0cb16557534087e743", size = 123030, upload-time = "2026-09-15T19:32:27.084Z" }, { url = "https://files.pythonhosted.org/packages/6a/3e/e2afcde10d74e53b3fa889960991efb3019beda2b1682a01de720a302056/yarl-1.25.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:632da579b2d879f6bad20f2cfa35ded1efe2f4f77f8abb26a6234a5b236acd2f", size = 126765, upload-time = "2026-09-15T19:32:29.332Z" }, { url = "https://files.pythonhosted.org/packages/a2/be/415b00c0fe5a0615b062a456b26623d7ec91c2bee20faea1a14045aa0469/yarl-1.25.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:30eec96e8a91bd588ce897c9543f6d5d8d34b28fbcba28a4dedf20ebeae9fe57", size = 117199, upload-time = "2026-09-15T19:32:31.49Z" }, { url = "https://files.pythonhosted.org/packages/97/27/3d8c63ddd3e8bcfd033748ab93876678ce59bacd66e4cb1ed851c9c5b37e/yarl-1.25.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:12b6bc4906e11f5e1a1cdcb12296e7afbd366c783cc8073403cd2fb74334e453", size = 115187, upload-time = "2026-09-15T19:32:34.137Z" }, { url = "https://files.pythonhosted.org/packages/39/b7/7a81d0be1a502a26a0d4326c6f2ecb736c824f570ea1c6529f2b0b227b50/yarl-1.25.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9d6ed3d17bccce4c05343e1ca8da13bc5c02c812a4e7282ddd05e8769322d3fc", size = 116085, upload-time = "2026-09-15T19:32:36.438Z" }, { url = "https://files.pythonhosted.org/packages/f0/69/39fff459916aa0fab42215dc47b759586fd80f94aa56dfc4a7c15ba6e0dc/yarl-1.25.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:f38a70074041d3b7e138e452799f5174198bae5bd5ab2000917badf403908c5f", size = 107996, upload-time = "2026-09-15T19:32:38.959Z" }, { url = "https://files.pythonhosted.org/packages/c0/39/80b9a55a3335590451d9ecf3eb593a8c635351f4c905ef056d7e8a8fd9e7/yarl-1.25.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:4ca89e4e21854ed27ec753297dde84b16c9f8e53b14a4866fb44457d643c19f8", size = 122549, upload-time = "2026-09-15T19:32:41.151Z" }, { url = "https://files.pythonhosted.org/packages/42/7d/a179c6757818bb59372a4adafd09f7f26a3b4a0f04c3ae404b544c0b0c82/yarl-1.25.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:1ab7618921a93767387a4b83776f751588f5b5ae9bb5bc96620e2e2e00bca868", size = 115107, upload-time = "2026-09-15T19:32:43.072Z" }, { url = "https://files.pythonhosted.org/packages/32/2b/a773ac867e4ab53a98ed98e5cefe3bae31e6f550252ca9d1de266f1a40c5/yarl-1.25.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:0ae12ff2b805fa02c4dab838005caef735e39986322698c48588d3beacb65c62", size = 120666, upload-time = "2026-09-15T19:32:45.061Z" }, { url = "https://files.pythonhosted.org/packages/bc/41/52be6505e85b0f76b4f85b01b5de7e06a0512201abc2c95e14e099549174/yarl-1.25.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:90c30ed53546da833c700115c0064c22120d1b1560f474699fd31f22dd668233", size = 117505, upload-time = "2026-09-15T19:32:47.177Z" }, { url = "https://files.pythonhosted.org/packages/f5/01/349c0386caedbbe488d519f252df54efac8a1459282d466c474bdd84a620/yarl-1.25.1-cp314-cp314-win_amd64.whl", hash = "sha256:acfa7e22aa6c6e7a5996a41d275bfa01efa7ea56ab890590280e9063e2cf5c1b", size = 103446, upload-time = "2026-09-15T19:32:49.615Z" }, { url = "https://files.pythonhosted.org/packages/5c/f0/8ec63180f77912f0dc4e5a42760cb8c08d20da1d5ace3578a01b84d1f3d8/yarl-1.25.1-cp314-cp314-win_arm64.whl", hash = "sha256:8e7d98cdbb6d71e726f7d525952867096053d1f290dd4e3c50d7d313a136f414", size = 99159, upload-time = "2026-09-15T19:32:51.686Z" }, { url = "https://files.pythonhosted.org/packages/47/7d/92d2220d6886b70ab1ed8579533ac2af2dfac716d5d929001daff7986df9/yarl-1.25.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:d21f0fa80a02d05299207eeaafef345d812ace96d5306e4ef265e1d419a615fa", size = 150071, upload-time = "2026-09-15T19:32:53.911Z" }, { url = "https://files.pythonhosted.org/packages/64/fc/b245e448124bcda9340df38e3553fa222b50260fca027a84095e9bd8642d/yarl-1.25.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:17c9877a89fb6e2bca6f9087eb24cd7fb434653946ef5075e470d23d49b52287", size = 106780, upload-time = "2026-09-15T19:32:56.443Z" }, { url = "https://files.pythonhosted.org/packages/51/e2/9a6ce2e334ebf218a30335ae76fb1696459430d42f733b8cb0d7d65b84d3/yarl-1.25.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:29273edf1530e397bd07cb784db1fbe0d2590b77569f2e24679a9c0a2d763b94", size = 107361, upload-time = "2026-09-15T19:32:58.827Z" }, { url = "https://files.pythonhosted.org/packages/ed/70/66e8c76b569b450d16e190f15071c916c3df70b0e33927e415ac497cf0c2/yarl-1.25.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b7abffdf37af1cec6a2ad69b827aa84320db5894791bc8ed932dc93fb274b7e9", size = 114396, upload-time = "2026-09-15T19:33:02.24Z" }, { url = "https://files.pythonhosted.org/packages/73/23/0d82838a05c57fdc05bc8b66e8c92dcc0df15e27463a5f163142d521c682/yarl-1.25.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2239a02249d9326655419e0168a28ca9008938eaab31dc29fc875c217927a6c0", size = 104882, upload-time = "2026-09-15T19:33:04.494Z" }, { url = "https://files.pythonhosted.org/packages/86/d4/ea08615c4edaa6049a13a2f1128944d068d1893abda7d708d4d7ea01599a/yarl-1.25.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:664ec6a520b74a1df2810666eb67695fcb77fa663e6ea0a25aaf2e529cb24dfa", size = 119485, upload-time = "2026-09-15T19:33:06.583Z" }, { url = "https://files.pythonhosted.org/packages/1a/82/0898bdce9b1ae403b308b9c733d0d24af4a3464270c2c081f457b16c3e0d/yarl-1.25.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4f1c91f5a5980a937ff8e238e98e6897e1ad74a4b1e2c0d68c73b5ffbb3f5c0b", size = 122490, upload-time = "2026-09-15T19:33:08.653Z" }, { url = "https://files.pythonhosted.org/packages/d1/38/97d79b81c342b78246cfedb74809e68841f3198d21653e10d3232bd9c622/yarl-1.25.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7c88edaec8c349ad4c5ad4c486a3defcc4b80ceb2f074436ffa0a87caf5e76a6", size = 115336, upload-time = "2026-09-15T19:33:11.056Z" }, { url = "https://files.pythonhosted.org/packages/8e/9d/2577896554cd310dc470adb6da0b7dd0b435cb63e2565204a7ac240e504c/yarl-1.25.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:35dcbea443fafb3eece757ad4e514560ddeb6c34cfae1582c620d7b293d7feee", size = 111825, upload-time = "2026-09-15T19:33:13.204Z" }, { url = "https://files.pythonhosted.org/packages/29/6b/7ac49d8ba84a5c4bd73415a4c949d22c749cb3762579b3d50e48019a78aa/yarl-1.25.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:882569ff613758cac762a457a5d72d6e211b28d4bcfea89d1d71ea942b02eac0", size = 114655, upload-time = "2026-09-15T19:33:15.553Z" }, { url = "https://files.pythonhosted.org/packages/e5/18/e5942a16723f5b72f9b1297fd5a85a54f6300cd15c0dcb5005b90cd89156/yarl-1.25.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:d0f1489233a254bb3643d2f05de7d59019254d81daeca6b9162fe9edef57e0c7", size = 106395, upload-time = "2026-09-15T19:33:17.599Z" }, { url = "https://files.pythonhosted.org/packages/7b/2d/549fa46240781513ebc47ae7eb418df428a163a2a3d644cc9cbb3ecb7846/yarl-1.25.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:f41753a76f4f63927d03a0d8ba8f5ce0f2083bec29a8cfaccc55371b1564b96b", size = 119277, upload-time = "2026-09-15T19:33:19.973Z" }, { url = "https://files.pythonhosted.org/packages/76/16/4763f78dcdc0b3b9fb3842b04afe72b9320857c6a69300c62a0eab03d119/yarl-1.25.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:8fb0eb4955adf0579001581f2f71a126e8781ba61bcd120f127b0401163c6c2d", size = 112504, upload-time = "2026-09-15T19:33:22.464Z" }, { url = "https://files.pythonhosted.org/packages/ae/b4/974e3edfe0d188393ce1cb9de400111c63fe61f4eb3b772a500d84c970d1/yarl-1.25.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:a1e32763e641a1566507d90a8d3b19bfc3cc04a9d4e5ae3e32189874ed4b58a3", size = 116243, upload-time = "2026-09-15T19:33:24.788Z" }, { url = "https://files.pythonhosted.org/packages/b0/aa/157b940428da80c104ca09666a740e51c94963df65d5b112e06b52e4d7a8/yarl-1.25.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:65b5b2066651b7432d389e9799d979c703bcc6ef44266bb8153ef54e91e4aab3", size = 115822, upload-time = "2026-09-15T19:33:26.886Z" }, { url = "https://files.pythonhosted.org/packages/7e/af/19fbdce41412e1b96825544cc52cd7029d3724655d0988237972f078bd29/yarl-1.25.1-cp314-cp314t-win_amd64.whl", hash = "sha256:734f6e5400352ac4254456003d462866c684703570929cff7a7bde015d0cb371", size = 107386, upload-time = "2026-09-15T19:33:29.009Z" }, { url = "https://files.pythonhosted.org/packages/2a/99/f6431c8968e89be608d74b28ae2d024521b2953f27dd44e0dece5e04f67a/yarl-1.25.1-cp314-cp314t-win_arm64.whl", hash = "sha256:287e99ff5aa4dc1c7630bfc683ded6f106d756c99dec432a2d7f197a784f51c6", size = 102094, upload-time = "2026-09-15T19:33:31.151Z" }, { url = "https://files.pythonhosted.org/packages/c7/3b/4f51eab40c2eabea6c3d5b121dff4b8988dc35087732ffede12d2be8b8dd/yarl-1.25.1-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:9b1bdaae98bc016825dd3c9d8ee1832f829b3341f9cc6ebd1a1b0a7fef7367cc", size = 143875, upload-time = "2026-09-15T19:33:33.52Z" }, { url = "https://files.pythonhosted.org/packages/41/05/bbd58fc063f5f299a883f810760b265ca26c8167c91cb9a494d0fe2387e1/yarl-1.25.1-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:e7011b8fb8c4054bf0c12e5edc6cd83778b0028e99ce59b18586ed036f92cfdc", size = 104028, upload-time = "2026-09-15T19:33:36.22Z" }, { url = "https://files.pythonhosted.org/packages/12/ee/2fba0aecb52e7020e189f684148783aa0b9cfa3b3bfb0b400646eef70ad4/yarl-1.25.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:f074e8d4aa0a5798920ddb6de3d08b228c614ff3724c3e8bd7577f4bafea867b", size = 104041, upload-time = "2026-09-15T19:33:38.86Z" }, { url = "https://files.pythonhosted.org/packages/38/35/884beab53ed88c7247d1671972b5ef116f7351fe0c7e6de8c3558372cb16/yarl-1.25.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d42e7e3ca399555578b4d617e3a6ecf13371b3743a115995fa010c7bf341459", size = 116018, upload-time = "2026-09-15T19:33:44.265Z" }, { url = "https://files.pythonhosted.org/packages/e2/cc/1a91b685afb55cc18608443ace95280e96e263a97565811732b6788d3269/yarl-1.25.1-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:aa4ed3dd308548f9e707d9caaf005d2d7f8c1e7868f858dfeb47fe76e16b391d", size = 107033, upload-time = "2026-09-15T19:33:46.45Z" }, { url = "https://files.pythonhosted.org/packages/c5/c1/58b379fcb1d68d907b7fcf75200c44321896509b2a6a74abbb4b19d864d2/yarl-1.25.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42a66563d8cc056ee32e6191e05097a7b2b3bc302e0bc3133daf8710eb18bd26", size = 123257, upload-time = "2026-09-15T19:33:48.631Z" }, { url = "https://files.pythonhosted.org/packages/d7/2d/1fe96cf5c2aeab10095e48f38585cf5a8451fb7253234822398e52aa5336/yarl-1.25.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:98d370568f393215d605304cdb77b3d5539bd192c75b623c7304c42c8d6d8273", size = 126745, upload-time = "2026-09-15T19:33:50.999Z" }, { url = "https://files.pythonhosted.org/packages/ad/60/8674394ce43f4dadae573a1d6f451716438e9eab7d7fe8d643c673a32d85/yarl-1.25.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23bf5b403c879a54964e0feac7285688e04bb220074878d737d331522da0a5bf", size = 117255, upload-time = "2026-09-15T19:33:53.456Z" }, { url = "https://files.pythonhosted.org/packages/2f/72/0faa30e02605d56127d42bb987dcc97da3863b7bf70b9bfbf5f739c05e30/yarl-1.25.1-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d45673badd08456d0340e9364eddafe1c53a9d2896424294de4d7dd71ad3ee57", size = 115166, upload-time = "2026-09-15T19:33:55.669Z" }, { url = "https://files.pythonhosted.org/packages/8c/90/9a46eac564c437e128285c5c1d7bb385d268394e9209d84f6bf4a14471ef/yarl-1.25.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:0136d640dfa9b0523853e411430a99f8a91eca85774c6420285a33b755bc6de3", size = 116082, upload-time = "2026-09-15T19:33:57.78Z" }, { url = "https://files.pythonhosted.org/packages/ad/38/4b1a686a3758878f93d2f1ea943f5a165f3555769cd16e761cfd0efdca17/yarl-1.25.1-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:59ba3a6e1aa8cfe5adf4bd270fd965db21955401b7ca6f1696010c55ed4daec2", size = 108048, upload-time = "2026-09-15T19:34:00.25Z" }, { url = "https://files.pythonhosted.org/packages/da/14/f348eb967f31a58348612a2b93bd8a2ab664548e2b5e879cac7f592f7201/yarl-1.25.1-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:87796fedc3ba97ec14fab55acb48584276e6c1e4c1e89c422bda62c838e754a9", size = 122775, upload-time = "2026-09-15T19:34:02.455Z" }, { url = "https://files.pythonhosted.org/packages/ab/e9/4f7b79700f88cb9e8bb66f8b54f9bce1844c013a2c39fdc47112e9334c95/yarl-1.25.1-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:bd0912757081f89b107d6c00b2ff8a194401b0b87eadcf4481de2b865a8fd44f", size = 115096, upload-time = "2026-09-15T19:34:05.283Z" }, { url = "https://files.pythonhosted.org/packages/cf/37/f9cb020331997d3eb887bd28d5410ecfd3d80bf163c23d7cec490d78dade/yarl-1.25.1-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:b51c159a9794633f5e0db7ecec7b2b6e3734eca1f5d17dc989ff3552a43ff78b", size = 120655, upload-time = "2026-09-15T19:34:07.382Z" }, { url = "https://files.pythonhosted.org/packages/12/83/52fceb22891a41f168db7ec22fd1d81e06b6a0b8d9f70921bd3e785defd0/yarl-1.25.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:319e070a01db9920fb63761843f96a104c8e2b9427266731810dc1e22595b17c", size = 117488, upload-time = "2026-09-15T19:34:09.988Z" }, { url = "https://files.pythonhosted.org/packages/f5/5c/ce6c4ff1247fcbe4b33d462c23a097106d909b173fde7042bc52290466e2/yarl-1.25.1-cp315-cp315-win_amd64.whl", hash = "sha256:a2059a2d891bd156bc5184e7ab7a56e78a84dfcfdeac8c501b552533ad1c36ee", size = 103434, upload-time = "2026-09-15T19:34:12.56Z" }, { url = "https://files.pythonhosted.org/packages/3c/a1/766a906b0704fb26d52b19dc22bed48a8ba0544203b70dcf44da350e8194/yarl-1.25.1-cp315-cp315-win_arm64.whl", hash = "sha256:a78b50b4f7918a3de71105d5c0b93bbc57bb8339a4d03a9dfd449f9068e76f3d", size = 99155, upload-time = "2026-09-15T19:34:15.132Z" }, { url = "https://files.pythonhosted.org/packages/bd/d3/a1d09b32cb6ab14f66b44939f5b4255b8b9e747aef3974af1d5d80ccc2fd/yarl-1.25.1-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:b5402a340723fa7da00b5cff987ddab61276be6d11251ea71ae02bcac54890d8", size = 149284, upload-time = "2026-09-15T19:34:17.452Z" }, { url = "https://files.pythonhosted.org/packages/7f/3b/fe554d879692650bca70bfbc0df124e82e4d2bb7456f698c7756f1279a96/yarl-1.25.1-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:eda19ea5ee88742f47a2340816e6f2d40b53bed3ab5b69794769f36af9f35bb4", size = 106399, upload-time = "2026-09-15T19:34:21.474Z" }, { url = "https://files.pythonhosted.org/packages/e1/4b/e7af56177ac8d40094c82d7728224c0b8472157d50d362e5fb3b014b2bc8/yarl-1.25.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:75baa6cf9b6d1c52f3e111a130e202fd8cf0a5b3a066c3f73d615e885092e4ec", size = 106968, upload-time = "2026-09-15T19:34:23.619Z" }, { url = "https://files.pythonhosted.org/packages/da/4f/2df41fd738d46f23ef829ae8b4468d94bb6070038fc6dfab6165ed44fea8/yarl-1.25.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dbcef5a9119ef653653132cccaf999b30a0af6f33bb0a4ba80bec30056868487", size = 114717, upload-time = "2026-09-15T19:34:25.879Z" }, { url = "https://files.pythonhosted.org/packages/69/ea/002b66df53bbd1aed1c23358ff99c9bdc744fe3f4d2740e1b2fdd7192885/yarl-1.25.1-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7efc9f082dfed77c316edffa9deb52888e1bc6789171887cc1f68e06d65465c8", size = 105198, upload-time = "2026-09-15T19:34:28.204Z" }, { url = "https://files.pythonhosted.org/packages/b1/7c/95c8bc0c8f97d71e59c94525ad60d76f5c57d3f2820f08137ca8b9f0542a/yarl-1.25.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fe01645169a2112aa1d4ebc3e4c5f029c5c8f97adfc32e5d37c993b39a994d75", size = 120271, upload-time = "2026-09-15T19:34:30.5Z" }, { url = "https://files.pythonhosted.org/packages/5d/7a/6fe9da56ec77927baa669fd86c39c567ce6205bab53d581082c6744c8ae7/yarl-1.25.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1c557dfd5e3db046053a0bdc72261ade790ebe8e2c7a41b36b0ca1f14cb95f3", size = 123572, upload-time = "2026-09-15T19:34:32.73Z" }, { url = "https://files.pythonhosted.org/packages/8b/83/35f222d17fa70a14c7c74fdf112ccf5515e0c2a87082b1f9b99f7693bf57/yarl-1.25.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ce4d6ccafb33d39bd78444612d14938ead674c25702ded2ee9c54a47735d225", size = 115228, upload-time = "2026-09-15T19:34:35.344Z" }, { url = "https://files.pythonhosted.org/packages/da/6f/fbaaf619423578a7d898d0f226ae47bc1906c293865c416d83c17b828b0e/yarl-1.25.1-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:80a063f8297fc796296f00f100be520f209b23dc98f93ce8eba6ee7122598209", size = 111618, upload-time = "2026-09-15T19:34:37.656Z" }, { url = "https://files.pythonhosted.org/packages/ba/78/7383278f1b3cf8e0496bd95b3281a7b09b89217b6b428db24c6b99b3deca/yarl-1.25.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:7cb414a73e21a7ab58254926073f2930cb22f5b4314ea4260a687e2b3fd4dce3", size = 114839, upload-time = "2026-09-15T19:34:40.099Z" }, { url = "https://files.pythonhosted.org/packages/62/49/5506e5b6d29aab91bd845cc9016d88c3d3f81b81bc242b8100bdd5737825/yarl-1.25.1-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:85a18376073f8a39aa07be34f9fc77e2869aa72c55c441efdd2cf79a0407504d", size = 106212, upload-time = "2026-09-15T19:34:42.768Z" }, { url = "https://files.pythonhosted.org/packages/46/8a/19877c193b7c5929f4b07118c18bbe390f3fadd0f59dd98c0cd12b31fa5c/yarl-1.25.1-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:77716e245c90f058466a05e6a465bb8600f767a8f4b18b4d40f3aff958e5f73c", size = 119985, upload-time = "2026-09-15T19:34:44.976Z" }, { url = "https://files.pythonhosted.org/packages/4e/6c/0a46fbbf9ecbcbd0cc20d2193394254b9e19817f22c814aab60f99847400/yarl-1.25.1-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:1e80dcf1446e1b080b1932b0d103c464a04112f5bc31f0f983ad418172063cde", size = 112081, upload-time = "2026-09-15T19:34:47.45Z" }, { url = "https://files.pythonhosted.org/packages/ef/30/93f5d471230c74ccd06255d0842739f86551f937f9e63a5e947853c6244a/yarl-1.25.1-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:bdc8d8b8c22e9e43ac68316b5e6cf083dec537f4ec213cb4aa967b583bc3fa64", size = 116995, upload-time = "2026-09-15T19:34:49.972Z" }, { url = "https://files.pythonhosted.org/packages/2b/80/c386593035ee3f9c6c6af0847b5578f2830c674794a9d7701b744a3ebd42/yarl-1.25.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:dfbf531053a0935f2e871bcd4753f90313688772ff8c017f5ea402e315a78c1f", size = 115570, upload-time = "2026-09-15T19:34:52.628Z" }, { url = "https://files.pythonhosted.org/packages/38/02/eef443559563ef8f2e10469387b8b1e97cb5efee95b288a56da60801f7ee/yarl-1.25.1-cp315-cp315t-win_amd64.whl", hash = "sha256:b13b88747769537f3d32e89e3a735da10c0a9e35d7322928c701b5f93d3afffd", size = 106811, upload-time = "2026-09-15T19:34:54.935Z" }, { url = "https://files.pythonhosted.org/packages/88/91/41e284ca2cf5211e05dae031d126a3668aea88fa759df56e7e35c6ad25ba/yarl-1.25.1-cp315-cp315t-win_arm64.whl", hash = "sha256:783dd1467083f4d3f7722ad6a313f24c173e7571372738fcb7a6e6d1ba48df25", size = 101804, upload-time = "2026-09-15T19:34:57.231Z" }, { url = "https://files.pythonhosted.org/packages/54/22/318c7980066769c6bcd9221ed2248294f5698811da099013098c670565ed/yarl-1.25.1-py3-none-any.whl", hash = "sha256:681c758b0490f9e96b78e5fa8e8dc6e648e9185bb6eaebe73183c33ea0c445f3", size = 63617, upload-time = "2026-09-15T19:34:59.616Z" }, ] [[package]] name = "zensical" version = "0.0.57" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "deepmerge" }, { name = "jinja2" }, { name = "markdown" }, { name = "pygments" }, { name = "pymdown-extensions" }, { name = "pyyaml" }, { name = "tomli" }, ] sdist = { url = "https://files.pythonhosted.org/packages/83/f4/fa40086c46a2e59e3d9239031f76623622e60e0d79f3df1282df2797a5c4/zensical-0.0.57.tar.gz", hash = "sha256:25fcbdf89a57153cc3ad1108a89d17c7226da5d3c551a8839c69cbd9c472a9d8", size = 4000458, upload-time = "2026-08-21T20:43:49.5Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/92/b9/49c37dc65105d1ca4a8b600a02c84ece00218d2293b2630611c620185ca3/zensical-0.0.57-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:98867d1a6ea2c57f1ebcf4902f61601f427350f2df0c04e30cfac8ba6163cd29", size = 12888507, upload-time = "2026-08-21T20:43:20.365Z" }, { url = "https://files.pythonhosted.org/packages/05/f7/54539984418de11387bbace39a744195555d32c98c95bf4d112b432548f5/zensical-0.0.57-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:0d7935d77d73a279545052e05d89d31960f30c1f33f53933f4c101fa271aee74", size = 12778169, upload-time = "2026-08-21T20:43:22.879Z" }, { url = "https://files.pythonhosted.org/packages/40/16/74aa60aa4cfecd5bd31ce60cb6a092cb56f1bc1aaadcc173463861ea4eb5/zensical-0.0.57-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7046d433511d97aa603915f0f6792d15b7f839793abc2b66ab7b7ff753ecff5", size = 13230823, upload-time = "2026-08-21T20:43:25.141Z" }, { url = "https://files.pythonhosted.org/packages/8a/d1/742d2487dd65dd18277daebcd37db56d5bd4a2408df02bde703ef8fb7b64/zensical-0.0.57-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ab85c5066b95e3a877cf8971e4ce30abb1ca1459fbfcc631f0a5a2bab56351a4", size = 13170523, upload-time = "2026-08-21T20:43:27.456Z" }, { url = "https://files.pythonhosted.org/packages/56/6f/12b570775d344f1a3d77e26d4ae0160bcac9e41ca38f7135352ccdf9b2c8/zensical-0.0.57-cp310-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f13d1b57ad3c8b8634933a93ea870ebac11245fe0c968d27fd2a059ee1c6311", size = 13549941, upload-time = "2026-08-21T20:43:29.964Z" }, { url = "https://files.pythonhosted.org/packages/7b/4e/436e6fc76674244c084ef7f6f17dc5ff85c76b15aef77c48b703fd0a2dda/zensical-0.0.57-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:021dd8fb70d1816cd012684fcf45d32b8f88a0cd28b7cbe71e5f8564f6d5764d", size = 13210086, upload-time = "2026-08-21T20:43:32.098Z" }, { url = "https://files.pythonhosted.org/packages/ef/52/20f3aeda9af1090f24241670a5cc20fff7494545fea9f5fa094c82f3dbdf/zensical-0.0.57-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:7e10f3c27fdc3eac3a9ae6ddcd87f3f00edc9f332050923313c95537961bfadd", size = 13408253, upload-time = "2026-08-21T20:43:34.258Z" }, { url = "https://files.pythonhosted.org/packages/e1/f2/2b18ba2f19674dbfcf745f3b66e005cc8efa66a1bcaba5e1b4f79467868a/zensical-0.0.57-cp310-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:78c85fee55c5aac3bdf8157e980c56397dca835167a5577c5429b5eb24ed990c", size = 13446689, upload-time = "2026-08-21T20:43:36.527Z" }, { url = "https://files.pythonhosted.org/packages/05/ba/68cdba447a9097e5f97742eef046020c6fa42d82972849b3a46a0718e890/zensical-0.0.57-cp310-abi3-musllinux_1_2_i686.whl", hash = "sha256:478d252e1924f3876e72cf7806967cb62e50d86eddb3da04bf43e882b532fa1b", size = 13598580, upload-time = "2026-08-21T20:43:38.646Z" }, { url = "https://files.pythonhosted.org/packages/ec/89/6358a4df272328bed5bea90b04d43e73758bc45ff058c5cb2665e1147314/zensical-0.0.57-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:66a9ca6b5f625b2a2b215eec2f3c72843a92d5d512042045ac6351d5dee9b339", size = 13557609, upload-time = "2026-08-21T20:43:40.866Z" }, { url = "https://files.pythonhosted.org/packages/77/e1/8831301a24f736743e3788f09ea048918b0bdcea4aaa90f7770a433d6eec/zensical-0.0.57-cp310-abi3-win32.whl", hash = "sha256:f0fe3dc27ca7dc4e168eddd0fe5b0f4d44e311fd4e0019241e289819e445203c", size = 12446805, upload-time = "2026-08-21T20:43:43.097Z" }, { url = "https://files.pythonhosted.org/packages/d7/3f/5d0ecd77d9ce962fdfde22dec036f4257a43ef6dbd55fb5c05fd294985ad/zensical-0.0.57-cp310-abi3-win_amd64.whl", hash = "sha256:a756834025c1c54e806e943be6d8df1048d0f8bcf6086e958568407a070a2572", size = 12716781, upload-time = "2026-08-21T20:43:45.273Z" }, ] [[package]] name = "zipp" version = "3.23.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/30/21/093488dfc7cc8964ded15ab726fad40f25fd3d788fd741cc1c5a17d78ee8/zipp-3.23.1.tar.gz", hash = "sha256:32120e378d32cd9714ad503c1d024619063ec28aad2248dc6672ad13edfa5110", size = 25965, upload-time = "2026-04-13T23:21:46.6Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/08/8a/0861bec20485572fbddf3dfba2910e38fe249796cb73ecdeb74e07eeb8d3/zipp-3.23.1-py3-none-any.whl", hash = "sha256:0b3596c50a5c700c9cb40ba8d86d9f2cc4807e9bedb06bcdf7fac85633e444dc", size = 10378, upload-time = "2026-04-13T23:21:45.386Z" }, ] [[package]] name = "zuvloop" version = "0.0.17" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "opentelemetry-api" }, { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/80/14/0c3bf1be773bffbd68876e38def6bf2cc4d1882060950a468653dcebb021/zuvloop-0.0.17.tar.gz", hash = "sha256:7f1a098de36ad257c939ba3ca1803a61ad4360cd07760dec7d2aedce5d979452", size = 1454154, upload-time = "2026-09-15T15:44:30.381Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/99/a6/353e0772a49360ff3a763933c6ee6f9582319694942c226a9e3f82c355dc/zuvloop-0.0.17-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:8ef6c5cbde35940bccee0ca566400e59a4e1c678f44dd78d66b99016b8b65a4a", size = 344488, upload-time = "2026-09-15T15:43:44.598Z" }, { url = "https://files.pythonhosted.org/packages/39/f5/e178fee6758d46e995342c5ebb5387046cf63ec23d0dad68662939338a20/zuvloop-0.0.17-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:28d5d39763e536950c04ad26ffb1d60957d20c5ef916203bb15293d8bdd7ab4b", size = 342929, upload-time = "2026-09-15T15:43:46.029Z" }, { url = "https://files.pythonhosted.org/packages/8a/21/187cb3f4b04b3a3f580ffee498a77cf2ff1bf7dbab6cbf978ad8924f9dfe/zuvloop-0.0.17-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:98a39087e145f8c68bacd417ddd6b1ce9bf2d763ef56867aa08ddbee5f673310", size = 1555167, upload-time = "2026-09-15T15:43:47.334Z" }, { url = "https://files.pythonhosted.org/packages/b5/e6/853ce4b9d5c935889a97bc33f98bf5dfc6b8e04b8c0f8dde1e4b57741e3f/zuvloop-0.0.17-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:c23e81fcbdb1d93a81da76e5747b75748edeafd5c95da9afaf165c73f1525231", size = 1588331, upload-time = "2026-09-15T15:43:48.813Z" }, { url = "https://files.pythonhosted.org/packages/60/c0/877fa6b3cd1ca775e0260d94d56af283edc2ff5c06ebfa6ebff63ea183a3/zuvloop-0.0.17-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:274fd02e3a915224e4489718f4d783df2b6080a45f43596b486e8aad71152a1e", size = 1531655, upload-time = "2026-09-15T15:43:50.412Z" }, { url = "https://files.pythonhosted.org/packages/f4/57/60f419e00b3a8b1a7fd65f5943a2900c3980332d58494c5c0650439e2ada/zuvloop-0.0.17-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d88fcf91a30ec443f5d5a0561d91f80ecf337c3ab63ba587655ce2df328f8462", size = 1563108, upload-time = "2026-09-15T15:43:51.937Z" }, { url = "https://files.pythonhosted.org/packages/72/da/729614358f0759ff576e11accf3cd8c4396672e44096d853ff4175de65f4/zuvloop-0.0.17-cp314-cp314-win_amd64.whl", hash = "sha256:5359f99edc564f911e0071b2197fc8efb4fbac3b6a8f700d5bbc65df60972627", size = 442722, upload-time = "2026-09-15T15:43:53.423Z" }, { url = "https://files.pythonhosted.org/packages/1f/17/f6649283cc006d631860191fb94c439a4e4caaae06712aec7f752f6bf95f/zuvloop-0.0.17-cp314-cp314-win_arm64.whl", hash = "sha256:bee2fbf1533c08a77eb1b34404b589fd59922bb9f956040d304827ec8f8774ed", size = 423827, upload-time = "2026-09-15T15:43:54.781Z" }, { url = "https://files.pythonhosted.org/packages/9f/b0/79a211a72e6f484dc5aa2f04d9ca52fd1a33f72a69c973132353dc381391/zuvloop-0.0.17-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:3dded18ccd7a8a1da9b6362dafd906db69b8a9e1b7fd067ddcbb25e2dd37878a", size = 339944, upload-time = "2026-09-15T15:43:56.067Z" }, { url = "https://files.pythonhosted.org/packages/e4/9c/106e2e96d7150d2b75439e2d29b765ca24a012f129c3b42cc831904ebdf0/zuvloop-0.0.17-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:149b7444fd3e32be12ff8389001c3872e444c7591c4225ca6feb4ef72d3c1c18", size = 337526, upload-time = "2026-09-15T15:43:57.543Z" }, { url = "https://files.pythonhosted.org/packages/8a/71/e640f4d2cf38a0be81bbdaf5444b59899375f623ba53ce9d359144e53eb3/zuvloop-0.0.17-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:6594d48bcd6881f4e91aa8914f8cc974e97cdbc9092f644d4d6cd57a8374aae5", size = 1525845, upload-time = "2026-09-15T15:43:58.969Z" }, { url = "https://files.pythonhosted.org/packages/6f/db/94579747d53017e23582b123f4168f0fa5874edf74b5a10c9648da20dd78/zuvloop-0.0.17-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:1ae2827209ad18c9892b346d5bbbceeb29ff3d6d0a10ffaa54d8d06fe37489a3", size = 1562489, upload-time = "2026-09-15T15:44:00.712Z" }, { url = "https://files.pythonhosted.org/packages/1b/dc/fc5dd6388d343ed612fa1171fac46128c40c63acedd475d575e0825e3ba5/zuvloop-0.0.17-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:78738ea00cb58e954e3803b156dfb5d9563bac28bb683d36bcb3017774de63c6", size = 1503251, upload-time = "2026-09-15T15:44:02.152Z" }, { url = "https://files.pythonhosted.org/packages/d1/4a/b8a38cd6b9da02759f66f717aed7b3bf06a0cc564482a9414087790dd29c/zuvloop-0.0.17-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ce44b18617dd2d877f8e78ecadc1766d2bdecbccb2760f0c35877d6256b633f0", size = 1537567, upload-time = "2026-09-15T15:44:03.491Z" }, { url = "https://files.pythonhosted.org/packages/df/38/65e7be13848b1404caad6a354780dacc158706abf6d36e94b38420ccca72/zuvloop-0.0.17-cp314-cp314t-win_amd64.whl", hash = "sha256:ba21d79efe4c1c5b2dd8b0a101de742e80feebf1df535174d0e990b1922afb8f", size = 440033, upload-time = "2026-09-15T15:44:05.051Z" }, { url = "https://files.pythonhosted.org/packages/6f/24/65916a589cb368beba10ef42cd650d2717ecd34df088929e0fb5c4cc4abf/zuvloop-0.0.17-cp314-cp314t-win_arm64.whl", hash = "sha256:23b48eaac2e295e3732e4870b478b0c6896b2548bb6a295d785825c0af0eca58", size = 420372, upload-time = "2026-09-15T15:44:06.292Z" }, { url = "https://files.pythonhosted.org/packages/c7/7f/e7ee3dce3bb346e988b0dd1d86f86f306b9258618a80d63a4e69e55926f3/zuvloop-0.0.17-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:506eacc31c98917acd17e48efb825a72c3d8b666724d78a6564a3cca5548a421", size = 344472, upload-time = "2026-09-15T15:44:07.495Z" }, { url = "https://files.pythonhosted.org/packages/f5/18/d7558d0649cac3544f53e83e6f980e58e283edcd87c9e2f828ab33eb4863/zuvloop-0.0.17-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:2bb6948a4baaf0d3ec917a934370e256be602fa9c007214014a9b7bc7d166697", size = 343023, upload-time = "2026-09-15T15:44:08.909Z" }, { url = "https://files.pythonhosted.org/packages/b8/89/1180eaa593596ef71633ee7a4fcb765c77ee5b0fe560d0d6ca3411fbf693/zuvloop-0.0.17-cp315-cp315-manylinux_2_28_aarch64.whl", hash = "sha256:d5b65a975af87bd9e1dec6ea5b12c8440716f35271c27c97bd544cb4272c4e9e", size = 1555471, upload-time = "2026-09-15T15:44:10.455Z" }, { url = "https://files.pythonhosted.org/packages/83/6c/b6bd615234254142a360dcbe1de9a118f6886ba347bdbaa4e6086930e116/zuvloop-0.0.17-cp315-cp315-manylinux_2_28_x86_64.whl", hash = "sha256:bbd9dea80218acd77e6b2d9e2014bd1fdcba3fe43e7df99471632c70c942e002", size = 1588504, upload-time = "2026-09-15T15:44:11.909Z" }, { url = "https://files.pythonhosted.org/packages/87/1d/e6d5b6e0a8f51486171c3362dde7592f3d274daf6ca63b70ef3ffbfa196c/zuvloop-0.0.17-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:9a86e74256a569df19eefd2fc34bff558757796c953cb0eda516557a02dab964", size = 1531890, upload-time = "2026-09-15T15:44:13.262Z" }, { url = "https://files.pythonhosted.org/packages/8c/7f/33cd0a98ae7a6c1ab7fd473b596364a4a1ecf727ab634997d0696292bb26/zuvloop-0.0.17-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:df59a9e3d4c8db838e366777c870b15f2f9f2e992578608aa01c7145a3cb8224", size = 1563255, upload-time = "2026-09-15T15:44:14.81Z" }, { url = "https://files.pythonhosted.org/packages/df/be/918c10d0a58ee975455a5e2dd41dfcbad811bd5774cc5166b6f8e6f45cce/zuvloop-0.0.17-cp315-cp315-win_amd64.whl", hash = "sha256:b3c176e7efb7e8329d6de2803b6161984be72904408deac9abf06acab62c8f2a", size = 442743, upload-time = "2026-09-15T15:44:16.227Z" }, { url = "https://files.pythonhosted.org/packages/73/b8/9c712a916b8dbe30552617e9a5af5e4b8d51c3610b9b84ea51cb5a7699de/zuvloop-0.0.17-cp315-cp315-win_arm64.whl", hash = "sha256:0c80ac05f80dd64eef614456802eb0dc97198c1066064a9177b0d70af35e69f0", size = 423892, upload-time = "2026-09-15T15:44:17.53Z" }, { url = "https://files.pythonhosted.org/packages/f0/74/270f8c69e5077a2aa330a575cbd11dda4f7ce2493d9c57fda432d6f1d0ce/zuvloop-0.0.17-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:137c99ddb6120bd19c265714d931f1d0ca2e019331623be38863d14362d268a1", size = 339952, upload-time = "2026-09-15T15:44:19.036Z" }, { url = "https://files.pythonhosted.org/packages/ae/2f/1273957fde2779ad8b6e5057ed4493f1364877eb9218c51118e5143f159c/zuvloop-0.0.17-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:32f74a05c73f09765139f8fa6e2fb588b538d270bef6cda7394bd05e8dfdd8ab", size = 337516, upload-time = "2026-09-15T15:44:20.423Z" }, { url = "https://files.pythonhosted.org/packages/e4/dc/8ce16954cd3872cd72e5c3e442df8d08c8ba2c09afecca3493442df9ce37/zuvloop-0.0.17-cp315-cp315t-manylinux_2_28_aarch64.whl", hash = "sha256:a1fdc6b98334e71eaecd2176b48f89b0bd1428bcf294d2b478a0c5eadba171ac", size = 1525955, upload-time = "2026-09-15T15:44:21.938Z" }, { url = "https://files.pythonhosted.org/packages/c2/1c/946ab2b0a4f8f2e23b275d3184fe212bf4530dbd459d939e2d6e9c984fee/zuvloop-0.0.17-cp315-cp315t-manylinux_2_28_x86_64.whl", hash = "sha256:c6fe1afcf83a1bba1d0962dc26afb4e18c905b7a2fda3159aa963c28295a2d3e", size = 1562511, upload-time = "2026-09-15T15:44:23.45Z" }, { url = "https://files.pythonhosted.org/packages/ef/e7/1b172171c706ec267b7e37cb55d4a531b377488d0678b66c95daa974a6f7/zuvloop-0.0.17-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:f53b315e2deba89ec23419b492c00109b8daabb413c86428292450e1805651d9", size = 1503449, upload-time = "2026-09-15T15:44:24.911Z" }, { url = "https://files.pythonhosted.org/packages/0f/37/59ade3f23c8a4394f0d56c0b426b769a7378e39c883a0c0a2b862c98f93e/zuvloop-0.0.17-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:d44fce96b84f9ff50b27bbee602dbddf589590c816dd8859a2b2bdbf82ac9e82", size = 1537480, upload-time = "2026-09-15T15:44:26.362Z" }, { url = "https://files.pythonhosted.org/packages/66/cf/17e9b354e33d0f05db02c956f006df24d69a5ec645701399272790a8d486/zuvloop-0.0.17-cp315-cp315t-win_amd64.whl", hash = "sha256:39e2f148814dbe67bd8b4f3095a305949d0ed3bd8ff1aa00ec897a8d05ad7187", size = 440032, upload-time = "2026-09-15T15:44:27.773Z" }, { url = "https://files.pythonhosted.org/packages/6c/f3/a979a18d2fc26f3ba9ec2354d345603882d7e993b1496c28652aa8d8e26f/zuvloop-0.0.17-cp315-cp315t-win_arm64.whl", hash = "sha256:a5abfbfd38add31380b0a6620300cd1f70a712f4ff885302d8a1110fa02f9c49", size = 420377, upload-time = "2026-09-15T15:44:29.045Z" }, ] pydantic-httpx2-6dd59b9/wrangler.toml000066400000000000000000000002611526547463400177410ustar00rootroot00000000000000name = "httpx2-docs" compatibility_date = "2026-05-22" preview_urls = false [[routes]] pattern = "httpx2.pydantic.dev" custom_domain = true [assets] directory = "./redirects"