pax_global_header00006660000000000000000000000064151014227240014510gustar00rootroot0000000000000052 comment=4941b4a04993d087dea66e9287fe9472babee879 starlette-0.50.0/000077500000000000000000000000001510142272400136015ustar00rootroot00000000000000starlette-0.50.0/.github/000077500000000000000000000000001510142272400151415ustar00rootroot00000000000000starlette-0.50.0/.github/FUNDING.yml000066400000000000000000000000171510142272400167540ustar00rootroot00000000000000github: Kludex starlette-0.50.0/.github/ISSUE_TEMPLATE/000077500000000000000000000000001510142272400173245ustar00rootroot00000000000000starlette-0.50.0/.github/ISSUE_TEMPLATE/1-issue.md000066400000000000000000000011201510142272400211260ustar00rootroot00000000000000--- 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/Kludex/starlette/discussions Possible bugs may be raised as a "Potential Issue" discussion, feature requests may be raised as an "Ideas" discussion. 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 #... starlette-0.50.0/.github/ISSUE_TEMPLATE/config.yml000066400000000000000000000006771510142272400213260ustar00rootroot00000000000000# 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/Kludex/starlette/discussions about: > The "Discussions" forum is where you want to start. 💖 - name: Chat url: https://discord.gg/SWU73HffbV about: > Our community chat forum. starlette-0.50.0/.github/dependabot.yml000066400000000000000000000005251510142272400177730ustar00rootroot00000000000000version: 2 updates: - package-ecosystem: "uv" directory: "/" schedule: interval: "monthly" groups: python-packages: patterns: - "*" - package-ecosystem: "github-actions" directory: "/" schedule: interval: monthly groups: github-actions: patterns: - "*" starlette-0.50.0/.github/pull_request_template.md000066400000000000000000000010431510142272400221000ustar00rootroot00000000000000 # 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. starlette-0.50.0/.github/workflows/000077500000000000000000000000001510142272400171765ustar00rootroot00000000000000starlette-0.50.0/.github/workflows/main.yml000066400000000000000000000024031510142272400206440ustar00rootroot00000000000000--- name: Test Suite on: push: branches: ["main"] pull_request: branches: ["main"] jobs: tests: name: "Python ${{ matrix.python-version }}" runs-on: ubuntu-latest strategy: matrix: python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Install uv uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2 with: python-version: ${{ matrix.python-version }} enable-cache: true - name: Install dependencies run: scripts/install - name: Run linting checks run: scripts/check if: ${{ matrix.python-version != '3.14' }} - name: "Build package & docs" run: scripts/build - name: "Run tests" run: scripts/test - name: "Enforce coverage" run: scripts/coverage # https://github.com/marketplace/actions/alls-green#why check: if: always() needs: [tests] runs-on: ubuntu-latest steps: - name: Decide whether the needed jobs succeeded or failed uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # v1.2.2 with: jobs: ${{ toJSON(needs) }} starlette-0.50.0/.github/workflows/publish.yml000066400000000000000000000061521510142272400213730ustar00rootroot00000000000000name: Publish on: push: tags: - '*' workflow_dispatch: jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Install uv uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2 with: python-version: "3.11" enable-cache: true - name: Install dependencies run: scripts/install - name: Build package & docs run: scripts/build - name: Upload package distributions uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: name: package-distributions path: dist/ - name: Upload documentation uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: name: documentation path: site/ pypi-publish: runs-on: ubuntu-latest needs: build if: success() && startsWith(github.ref, 'refs/tags/') permissions: id-token: write environment: name: pypi url: https://pypi.org/project/starlette steps: - name: Download artifacts uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 with: name: package-distributions path: dist/ - name: Publish distribution 📦 to PyPI uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 docs-publish: runs-on: ubuntu-latest needs: build permissions: contents: write steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Download artifacts uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 with: name: documentation path: site/ - name: Configure Git Credentials run: | git config user.name github-actions[bot] git config user.email 41898282+github-actions[bot]@users.noreply.github.com - name: Install uv uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2 with: python-version: "3.12" enable-cache: true - name: Install dependencies run: scripts/install - name: Publish documentation 📚 to GitHub Pages run: uv run mkdocs gh-deploy --force docs-cloudflare: runs-on: ubuntu-latest needs: build environment: name: cloudflare url: https://starlette.dev steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Download artifacts uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 with: name: documentation path: site/ - uses: cloudflare/wrangler-action@da0e0dfe58b7a431659754fdf3f186c529afbe65 # v3.14.1 with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} command: > pages deploy ./site --project-name starlette --commit-hash ${{ github.sha }} --branch main starlette-0.50.0/.gitignore000066400000000000000000000002001510142272400155610ustar00rootroot00000000000000*.pyc test.db .coverage .pytest_cache/ .mypy_cache/ __pycache__/ htmlcov/ site/ *.egg-info/ venv*/ .python-version build/ dist/ starlette-0.50.0/CITATION.cff000066400000000000000000000011631510142272400154740ustar00rootroot00000000000000# This CITATION.cff file was generated with cffinit. # Visit https://bit.ly/cffinit to generate yours today! cff-version: 1.2.0 title: Starlette message: >- If you use this software, please cite it using the metadata from this file. type: software authors: - given-names: Marcelo family-names: Trylesinski email: marcelotryle@gmail.com - given-names: Tom family-names: Christie email: tom@tomchristie.com repository-code: "https://github.com/Kludex/starlette" url: "https://starlette.dev/" abstract: Starlette is an ASGI web framework for Python. keywords: - asgi - starlette license: BSD-3-Clause starlette-0.50.0/LICENSE.md000066400000000000000000000027561510142272400152170ustar00rootroot00000000000000Copyright © 2018, [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. starlette-0.50.0/README.md000066400000000000000000000112701510142272400150610ustar00rootroot00000000000000

starlette-logo

✨ The little ASGI framework that shines. ✨

--- [![Build Status](https://github.com/Kludex/starlette/workflows/Test%20Suite/badge.svg)](https://github.com/Kludex/starlette/actions) [![Package version](https://badge.fury.io/py/starlette.svg)](https://pypi.python.org/pypi/starlette) [![Supported Python Version](https://img.shields.io/pypi/pyversions/starlette.svg?color=%2334D058)](https://pypi.org/project/starlette) [![Discord](https://img.shields.io/discord/1051468649518616576?logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/RxKUF5JuHs) --- **Documentation**: https://starlette.dev **Source Code**: https://github.com/Kludex/starlette --- # Starlette Starlette is a lightweight [ASGI][asgi] framework/toolkit, which is ideal for building async web services in Python. It is production-ready, and gives you the following: * A lightweight, low-complexity HTTP web framework. * WebSocket support. * In-process background tasks. * Startup and shutdown events. * Test client built on `httpx`. * CORS, GZip, Static Files, Streaming responses. * Session and Cookie support. * 100% test coverage. * 100% type annotated codebase. * Few hard dependencies. * Compatible with `asyncio` and `trio` backends. * Great overall performance [against independent benchmarks][techempower]. ## Installation ```shell $ pip install starlette ``` You'll also want to install an ASGI server, such as [uvicorn](https://www.uvicorn.org/), [daphne](https://github.com/django/daphne/), or [hypercorn](https://hypercorn.readthedocs.io/en/latest/). ```shell $ pip install uvicorn ``` ## Example ```python title="main.py" from starlette.applications import Starlette from starlette.responses import JSONResponse from starlette.routing import Route async def homepage(request): return JSONResponse({'hello': 'world'}) routes = [ Route("/", endpoint=homepage) ] app = Starlette(debug=True, routes=routes) ``` Then run the application using Uvicorn: ```shell $ uvicorn main:app ``` ## Dependencies Starlette only requires `anyio`, and the following are optional: * [`httpx`][httpx] - Required if you want to use the `TestClient`. * [`jinja2`][jinja2] - Required if you want to use `Jinja2Templates`. * [`python-multipart`][python-multipart] - Required if you want to support form parsing, with `request.form()`. * [`itsdangerous`][itsdangerous] - Required for `SessionMiddleware` support. * [`pyyaml`][pyyaml] - Required for `SchemaGenerator` support. You can install all of these with `pip install starlette[full]`. ## Framework or Toolkit Starlette is designed to be used either as a complete framework, or as an ASGI toolkit. You can use any of its components independently. ```python from starlette.responses import PlainTextResponse async def app(scope, receive, send): assert scope['type'] == 'http' response = PlainTextResponse('Hello, world!') await response(scope, receive, send) ``` Run the `app` application in `example.py`: ```shell $ uvicorn example:app INFO: Started server process [11509] INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) ``` Run uvicorn with `--reload` to enable auto-reloading on code changes. ## Modularity The modularity that Starlette is designed on promotes building re-usable components that can be shared between any ASGI framework. This should enable an ecosystem of shared middleware and mountable applications. The clean API separation also means it's easier to understand each component in isolation. ---

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

— ⭐️ —

[asgi]: https://asgi.readthedocs.io/en/latest/ [httpx]: https://www.python-httpx.org/ [jinja2]: https://jinja.palletsprojects.com/ [python-multipart]: https://multipart.fastapiexpert.com/ [itsdangerous]: https://itsdangerous.palletsprojects.com/ [sqlalchemy]: https://www.sqlalchemy.org [pyyaml]: https://pyyaml.org/wiki/PyYAMLDocumentation [techempower]: https://www.techempower.com/benchmarks/#hw=ph&test=fortune&l=zijzen-sf starlette-0.50.0/docs/000077500000000000000000000000001510142272400145315ustar00rootroot00000000000000starlette-0.50.0/docs/CNAME000066400000000000000000000000211510142272400152700ustar00rootroot00000000000000www.starlette.io starlette-0.50.0/docs/applications.md000066400000000000000000000033721510142272400175460ustar00rootroot00000000000000 ??? abstract "API Reference" ::: starlette.applications.Starlette options: parameter_headings: false show_root_heading: true heading_level: 3 filters: - "__init__" Starlette includes an application class `Starlette` that nicely ties together all of its other functionality. ```python from contextlib import asynccontextmanager from starlette.applications import Starlette from starlette.responses import PlainTextResponse from starlette.routing import Route, Mount, WebSocketRoute from starlette.staticfiles import StaticFiles def homepage(request): return PlainTextResponse('Hello, world!') def user_me(request): username = "John Doe" return PlainTextResponse('Hello, %s!' % username) def user(request): username = request.path_params['username'] return PlainTextResponse('Hello, %s!' % username) async def websocket_endpoint(websocket): await websocket.accept() await websocket.send_text('Hello, websocket!') await websocket.close() @asynccontextmanager async def lifespan(app): print('Startup') yield print('Shutdown') routes = [ Route('/', homepage), Route('/user/me', user_me), Route('/user/{username}', user), WebSocketRoute('/ws', websocket_endpoint), Mount('/static', StaticFiles(directory="static")), ] app = Starlette(debug=True, routes=routes, lifespan=lifespan) ``` ### Storing state on the app instance You can store arbitrary extra state on the application instance, using the generic `app.state` attribute. For example: ```python app.state.ADMIN_EMAIL = 'admin@example.org' ``` ### Accessing the app instance Where a `request` is available (i.e. endpoints and middleware), the app is available on `request.app`. starlette-0.50.0/docs/authentication.md000066400000000000000000000125461510142272400201020ustar00rootroot00000000000000Starlette offers a simple but powerful interface for handling authentication and permissions. Once you've installed `AuthenticationMiddleware` with an appropriate authentication backend the `request.user` and `request.auth` interfaces will be available in your endpoints. ```python from starlette.applications import Starlette from starlette.authentication import ( AuthCredentials, AuthenticationBackend, AuthenticationError, SimpleUser ) from starlette.middleware import Middleware from starlette.middleware.authentication import AuthenticationMiddleware from starlette.responses import PlainTextResponse from starlette.routing import Route import base64 import binascii class BasicAuthBackend(AuthenticationBackend): async def authenticate(self, conn): if "Authorization" not in conn.headers: return auth = conn.headers["Authorization"] try: scheme, credentials = auth.split() if scheme.lower() != 'basic': return decoded = base64.b64decode(credentials).decode("ascii") except (ValueError, UnicodeDecodeError, binascii.Error) as exc: raise AuthenticationError('Invalid basic auth credentials') username, _, password = decoded.partition(":") # TODO: You'd want to verify the username and password here. return AuthCredentials(["authenticated"]), SimpleUser(username) async def homepage(request): if request.user.is_authenticated: return PlainTextResponse('Hello, ' + request.user.display_name) return PlainTextResponse('Hello, you') routes = [ Route("/", endpoint=homepage) ] middleware = [ Middleware(AuthenticationMiddleware, backend=BasicAuthBackend()) ] app = Starlette(routes=routes, middleware=middleware) ``` ## Users Once `AuthenticationMiddleware` is installed the `request.user` interface will be available to endpoints or other middleware. This interface should subclass `BaseUser`, which provides two properties, as well as whatever other information your user model includes. * `.is_authenticated` * `.display_name` Starlette provides two built-in user implementations: `UnauthenticatedUser()`, and `SimpleUser(username)`. ## AuthCredentials It is important that authentication credentials are treated as separate concept from users. An authentication scheme should be able to restrict or grant particular privileges independently of the user identity. The `AuthCredentials` class provides the basic interface that `request.auth` exposes: * `.scopes` ## Permissions Permissions are implemented as an endpoint decorator, that enforces that the incoming request includes the required authentication scopes. ```python from starlette.authentication import requires @requires('authenticated') async def dashboard(request): ... ``` You can include either one or multiple required scopes: ```python from starlette.authentication import requires @requires(['authenticated', 'admin']) async def dashboard(request): ... ``` By default 403 responses will be returned when permissions are not granted. In some cases you might want to customize this, for example to hide information about the URL layout from unauthenticated users. ```python from starlette.authentication import requires @requires(['authenticated', 'admin'], status_code=404) async def dashboard(request): ... ``` !!! note The `status_code` parameter is not supported with WebSockets. The 403 (Forbidden) status code will always be used for those. Alternatively you might want to redirect unauthenticated users to a different page. ```python from starlette.authentication import requires async def homepage(request): ... @requires('authenticated', redirect='homepage') async def dashboard(request): ... ``` When redirecting users, the page you redirect them to will include URL they originally requested at the `next` query param: ```python from starlette.authentication import requires from starlette.responses import RedirectResponse @requires('authenticated', redirect='login') async def admin(request): ... async def login(request): if request.method == "POST": # Now that the user is authenticated, # we can send them to their original request destination if request.user.is_authenticated: next_url = request.query_params.get("next") if next_url: return RedirectResponse(next_url) return RedirectResponse("/") ``` For class-based endpoints, you should wrap the decorator around a method on the class. ```python from starlette.authentication import requires from starlette.endpoints import HTTPEndpoint class Dashboard(HTTPEndpoint): @requires("authenticated") async def get(self, request): ... ``` ## Custom authentication error responses You can customise the error response sent when a `AuthenticationError` is raised by an auth backend: ```python from starlette.applications import Starlette from starlette.middleware import Middleware from starlette.middleware.authentication import AuthenticationMiddleware from starlette.requests import Request from starlette.responses import JSONResponse def on_auth_error(request: Request, exc: Exception): return JSONResponse({"error": str(exc)}, status_code=401) app = Starlette( middleware=[ Middleware(AuthenticationMiddleware, backend=BasicAuthBackend(), on_error=on_auth_error), ], ) ``` starlette-0.50.0/docs/background.md000066400000000000000000000036511510142272400171770ustar00rootroot00000000000000 Starlette includes a `BackgroundTask` class for in-process background tasks. A background task should be attached to a response, and will run only once the response has been sent. ### Background Task Used to add a single background task to a response. Signature: `BackgroundTask(func, *args, **kwargs)` ```python from starlette.applications import Starlette from starlette.responses import JSONResponse from starlette.routing import Route from starlette.background import BackgroundTask ... async def signup(request): data = await request.json() username = data['username'] email = data['email'] task = BackgroundTask(send_welcome_email, to_address=email) message = {'status': 'Signup successful'} return JSONResponse(message, background=task) async def send_welcome_email(to_address): ... routes = [ ... Route('/user/signup', endpoint=signup, methods=['POST']) ] app = Starlette(routes=routes) ``` ### BackgroundTasks Used to add multiple background tasks to a response. Signature: `BackgroundTasks(tasks=[])` ```python from starlette.applications import Starlette from starlette.responses import JSONResponse from starlette.background import BackgroundTasks async def signup(request): data = await request.json() username = data['username'] email = data['email'] tasks = BackgroundTasks() tasks.add_task(send_welcome_email, to_address=email) tasks.add_task(send_admin_notification, username=username) message = {'status': 'Signup successful'} return JSONResponse(message, background=tasks) async def send_welcome_email(to_address): ... async def send_admin_notification(username): ... routes = [ Route('/user/signup', endpoint=signup, methods=['POST']) ] app = Starlette(routes=routes) ``` !!! important The tasks are executed in order. In case one of the tasks raises an exception, the following tasks will not get the opportunity to be executed. starlette-0.50.0/docs/config.md000066400000000000000000000154601510142272400163260ustar00rootroot00000000000000Starlette encourages a strict separation of configuration from code, following [the twelve-factor pattern][twelve-factor]. Configuration should be stored in environment variables, or in a `.env` file that is not committed to source control. ```python title="main.py" from sqlalchemy import create_engine from starlette.applications import Starlette from starlette.config import Config from starlette.datastructures import CommaSeparatedStrings, Secret # Config will be read from environment variables and/or ".env" files. config = Config(".env") DEBUG = config('DEBUG', cast=bool, default=False) DATABASE_URL = config('DATABASE_URL') SECRET_KEY = config('SECRET_KEY', cast=Secret) ALLOWED_HOSTS = config('ALLOWED_HOSTS', cast=CommaSeparatedStrings) app = Starlette(debug=DEBUG) engine = create_engine(DATABASE_URL) ... ``` ```shell title=".env" # Don't commit this to source control. # Eg. Include ".env" in your `.gitignore` file. DEBUG=True DATABASE_URL=postgresql://user:password@localhost:5432/database SECRET_KEY=43n080musdfjt54t-09sdgr ALLOWED_HOSTS=127.0.0.1, localhost ``` ## Configuration precedence The order in which configuration values are read is: * From an environment variable. * From the `.env` file. * The default value given in `config`. If none of those match, then `config(...)` will raise an error. ## Secrets For sensitive keys, the `Secret` class is useful, since it helps minimize occasions where the value it holds could leak out into tracebacks or other code introspection. To get the value of a `Secret` instance, you must explicitly cast it to a string. You should only do this at the point at which the value is used. ```python >>> from myproject import settings >>> settings.SECRET_KEY Secret('**********') >>> str(settings.SECRET_KEY) '98n349$%8b8-7yjn0n8y93T$23r' ``` !!! tip You can use `DatabaseURL` from `databases` package [here](https://github.com/encode/databases/blob/ab5eb718a78a27afe18775754e9c0fa2ad9cd211/databases/core.py#L420) to store database URLs and avoid leaking them in the logs. ## CommaSeparatedStrings For holding multiple inside a single config key, the `CommaSeparatedStrings` type is useful. ```python >>> from myproject import settings >>> print(settings.ALLOWED_HOSTS) CommaSeparatedStrings(['127.0.0.1', 'localhost']) >>> print(list(settings.ALLOWED_HOSTS)) ['127.0.0.1', 'localhost'] >>> print(len(settings.ALLOWED_HOSTS)) 2 >>> print(settings.ALLOWED_HOSTS[0]) '127.0.0.1' ``` ## Reading or modifying the environment In some cases you might want to read or modify the environment variables programmatically. This is particularly useful in testing, where you may want to override particular keys in the environment. Rather than reading or writing from `os.environ`, you should use Starlette's `environ` instance. This instance is a mapping onto the standard `os.environ` that additionally protects you by raising an error if any environment variable is set *after* the point that it has already been read by the configuration. If you're using `pytest`, then you can setup any initial environment in `tests/conftest.py`. ```python title="tests/conftest.py" from starlette.config import environ environ['DEBUG'] = 'TRUE' ``` ## Reading prefixed environment variables You can namespace the environment variables by setting `env_prefix` argument. ```python title="myproject/settings.py" import os from starlette.config import Config os.environ['APP_DEBUG'] = 'yes' os.environ['ENVIRONMENT'] = 'dev' config = Config(env_prefix='APP_') DEBUG = config('DEBUG') # lookups APP_DEBUG, returns "yes" ENVIRONMENT = config('ENVIRONMENT') # lookups APP_ENVIRONMENT, raises KeyError as variable is not defined ``` ## Custom encoding for environment files By default, Starlette reads environment files using UTF-8 encoding. You can specify a different encoding by setting `encoding` argument. ```python title="myproject/settings.py" from starlette.config import Config # Using custom encoding for .env file config = Config(".env", encoding="latin-1") ``` ## A full example Structuring large applications can be complex. You need proper separation of configuration and code, database isolation during tests, separate test and production databases, etc... Here we'll take a look at a complete example, that demonstrates how we can start to structure an application. First, let's keep our settings, our database table definitions, and our application logic separated: ```python title="myproject/settings.py" from starlette.config import Config from starlette.datastructures import Secret config = Config(".env") DEBUG = config('DEBUG', cast=bool, default=False) SECRET_KEY = config('SECRET_KEY', cast=Secret) DATABASE_URL = config('DATABASE_URL') ``` ```python title="myproject/tables.py" import sqlalchemy # Database table definitions. metadata = sqlalchemy.MetaData() organisations = sqlalchemy.Table( ... ) ``` ```python title="myproject/app.py" from starlette.applications import Starlette from starlette.middleware import Middleware from starlette.middleware.sessions import SessionMiddleware from starlette.routing import Route from myproject import settings async def homepage(request): ... routes = [ Route("/", endpoint=homepage) ] middleware = [ Middleware( SessionMiddleware, secret_key=settings.SECRET_KEY, ) ] app = Starlette(debug=settings.DEBUG, routes=routes, middleware=middleware) ``` Now let's deal with our test configuration. We'd like to create a new test database every time the test suite runs, and drop it once the tests complete. We'd also like to ensure ```python title="tests/conftest.py" from starlette.config import environ from starlette.testclient import TestClient from sqlalchemy import create_engine from sqlalchemy_utils import create_database, database_exists, drop_database # This line would raise an error if we use it after 'settings' has been imported. environ['DEBUG'] = 'TRUE' from myproject import settings from myproject.app import app from myproject.tables import metadata @pytest.fixture(autouse=True, scope="session") def setup_test_database(): """ Create a clean test database every time the tests are run. """ url = settings.DATABASE_URL engine = create_engine(url) assert not database_exists(url), 'Test database already exists. Aborting tests.' create_database(url) # Create the test database. metadata.create_all(engine) # Create the tables. yield # Run the tests. drop_database(url) # Drop the test database. @pytest.fixture() def client(): """ Make a 'client' fixture available to test cases. """ # Our fixture is created within a context manager. This ensures that # application lifespan runs for every test case. with TestClient(app) as test_client: yield test_client ``` [twelve-factor]: https://12factor.net/config starlette-0.50.0/docs/contributing.md000066400000000000000000000127311510142272400175660ustar00rootroot00000000000000# Contributing Thank you for being interested in contributing to Starlette. There are many ways you can contribute to the project: - Try Starlette and [report bugs/issues you find](https://github.com/Kludex/starlette/issues/new) - [Implement new features](https://github.com/Kludex/starlette/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) - [Review Pull Requests of others](https://github.com/Kludex/starlette/pulls) - Write documentation - Participate in discussions ## Reporting Bugs or Other Issues Found something that Starlette should support? Stumbled upon some unexpected behaviour? Contributions should generally start out with [a discussion](https://github.com/Kludex/starlette/discussions). Possible bugs may be raised as a "Potential Issue" discussion, feature requests may be raised as an "Ideas" discussion. 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. ## Development To start developing Starlette, create a **fork** of the [Starlette repository](https://github.com/Kludex/starlette) 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/starlette ``` You can now install the project and its dependencies using: ```shell $ cd starlette $ 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_application.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 Starlette 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/Kludex/starlette/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**: see `__version__.py`. For an example, see [#1600](https://github.com/Kludex/starlette/pull/1600). Once the release PR is merged, create a [new release](https://github.com/Kludex/starlette/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. starlette-0.50.0/docs/database.md000066400000000000000000000224521510142272400166240ustar00rootroot00000000000000Starlette is not strictly tied to any particular database implementation. You can use it with an asynchronous ORM, such as [GINO](https://python-gino.org/), or use regular non-async endpoints, and integrate with [SQLAlchemy](https://www.sqlalchemy.org/). In this documentation we'll demonstrate how to integrate against [the `databases` package](https://github.com/encode/databases), which provides SQLAlchemy core support against a range of different database drivers. Here's a complete example, that includes table definitions, configuring a `database.Database` instance, and a couple of endpoints that interact with the database. ```ini title=".env" DATABASE_URL=sqlite:///test.db ``` ```python title="app.py" import contextlib import databases import sqlalchemy from starlette.applications import Starlette from starlette.config import Config from starlette.responses import JSONResponse from starlette.routing import Route # Configuration from environment variables or '.env' file. config = Config('.env') DATABASE_URL = config('DATABASE_URL') # Database table definitions. metadata = sqlalchemy.MetaData() notes = sqlalchemy.Table( "notes", metadata, sqlalchemy.Column("id", sqlalchemy.Integer, primary_key=True), sqlalchemy.Column("text", sqlalchemy.String), sqlalchemy.Column("completed", sqlalchemy.Boolean), ) database = databases.Database(DATABASE_URL) @contextlib.asynccontextmanager async def lifespan(app): await database.connect() yield await database.disconnect() # Main application code. async def list_notes(request): query = notes.select() results = await database.fetch_all(query) content = [ { "text": result["text"], "completed": result["completed"] } for result in results ] return JSONResponse(content) async def add_note(request): data = await request.json() query = notes.insert().values( text=data["text"], completed=data["completed"] ) await database.execute(query) return JSONResponse({ "text": data["text"], "completed": data["completed"] }) routes = [ Route("/notes", endpoint=list_notes, methods=["GET"]), Route("/notes", endpoint=add_note, methods=["POST"]), ] app = Starlette( routes=routes, lifespan=lifespan, ) ``` Finally, you will need to create the database tables. It is recommended to use Alembic, which we briefly go over in [Migrations](#migrations) ## Queries Queries may be made with as [SQLAlchemy Core queries][sqlalchemy-core]. The following methods are supported: * `rows = await database.fetch_all(query)` * `row = await database.fetch_one(query)` * `async for row in database.iterate(query)` * `await database.execute(query)` * `await database.execute_many(query)` ## Transactions Database transactions are available either as a decorator, as a context manager, or as a low-level API. Using a decorator on an endpoint: ```python @database.transaction() async def populate_note(request): # This database insert occurs within a transaction. # It will be rolled back by the `RuntimeError`. query = notes.insert().values(text="you won't see me", completed=True) await database.execute(query) raise RuntimeError() ``` Using a context manager: ```python async def populate_note(request): async with database.transaction(): # This database insert occurs within a transaction. # It will be rolled back by the `RuntimeError`. query = notes.insert().values(text="you won't see me", completed=True) await request.database.execute(query) raise RuntimeError() ``` Using the low-level API: ```python async def populate_note(request): transaction = await database.transaction() try: # This database insert occurs within a transaction. # It will be rolled back by the `RuntimeError`. query = notes.insert().values(text="you won't see me", completed=True) await database.execute(query) raise RuntimeError() except: await transaction.rollback() raise else: await transaction.commit() ``` ## Test isolation There are a few things that we want to ensure when running tests against a service that uses a database. Our requirements should be: * Use a separate database for testing. * Create a new test database every time we run the tests. * Ensure that the database state is isolated between each test case. Here's how we need to structure our application and tests in order to meet those requirements: ```python from starlette.applications import Starlette from starlette.config import Config import databases config = Config(".env") TESTING = config('TESTING', cast=bool, default=False) DATABASE_URL = config('DATABASE_URL', cast=databases.DatabaseURL) TEST_DATABASE_URL = DATABASE_URL.replace(database='test_' + DATABASE_URL.database) # Use 'force_rollback' during testing, to ensure we do not persist database changes # between each test case. if TESTING: database = databases.Database(TEST_DATABASE_URL, force_rollback=True) else: database = databases.Database(DATABASE_URL) ``` We still need to set `TESTING` during a test run, and setup the test database. Assuming we're using `py.test`, here's how our `conftest.py` might look: ```python import pytest from starlette.config import environ from starlette.testclient import TestClient from sqlalchemy import create_engine from sqlalchemy_utils import database_exists, create_database, drop_database # This sets `os.environ`, but provides some additional protection. # If we placed it below the application import, it would raise an error # informing us that 'TESTING' had already been read from the environment. environ['TESTING'] = 'True' import app @pytest.fixture(scope="session", autouse=True) def create_test_database(): """ Create a clean database on every test case. For safety, we should abort if a database already exists. We use the `sqlalchemy_utils` package here for a few helpers in consistently creating and dropping the database. """ url = str(app.TEST_DATABASE_URL) engine = create_engine(url) assert not database_exists(url), 'Test database already exists. Aborting tests.' create_database(url) # Create the test database. metadata.create_all(engine) # Create the tables. yield # Run the tests. drop_database(url) # Drop the test database. @pytest.fixture() def client(): """ When using the 'client' fixture in test cases, we'll get full database rollbacks between test cases: def test_homepage(client): url = app.url_path_for('homepage') response = client.get(url) assert response.status_code == 200 """ with TestClient(app) as client: yield client ``` ## Migrations You'll almost certainly need to be using database migrations in order to manage incremental changes to the database. For this we'd strongly recommend [Alembic][alembic], which is written by the author of SQLAlchemy. ```shell $ pip install alembic $ alembic init migrations ``` Now, you'll want to set things up so that Alembic references the configured DATABASE_URL, and uses your table metadata. In `alembic.ini` remove the following line: ```shell sqlalchemy.url = driver://user:pass@localhost/dbname ``` In `migrations/env.py`, you need to set the ``'sqlalchemy.url'`` configuration key, and the `target_metadata` variable. You'll want something like this: ```python # The Alembic Config object. config = context.config # Configure Alembic to use our DATABASE_URL and our table definitions... import app config.set_main_option('sqlalchemy.url', str(app.DATABASE_URL)) target_metadata = app.metadata ... ``` Then, using our notes example above, create an initial revision: ```shell alembic revision -m "Create notes table" ``` And populate the new file (within `migrations/versions`) with the necessary directives: ```python def upgrade(): op.create_table( 'notes', sqlalchemy.Column("id", sqlalchemy.Integer, primary_key=True), sqlalchemy.Column("text", sqlalchemy.String), sqlalchemy.Column("completed", sqlalchemy.Boolean), ) def downgrade(): op.drop_table('notes') ``` And run your first migration. Our notes app can now run! ```shell alembic upgrade head ``` **Running migrations during testing** It is good practice to ensure that your test suite runs the database migrations every time it creates the test database. This will help catch any issues in your migration scripts, and will help ensure that the tests are running against a database that's in a consistent state with your live database. We can adjust the `create_test_database` fixture slightly: ```python from alembic import command from alembic.config import Config import app ... @pytest.fixture(scope="session", autouse=True) def create_test_database(): url = str(app.DATABASE_URL) engine = create_engine(url) assert not database_exists(url), 'Test database already exists. Aborting tests.' create_database(url) # Create the test database. config = Config("alembic.ini") # Run the migrations. command.upgrade(config, "head") yield # Run the tests. drop_database(url) # Drop the test database. ``` [sqlalchemy-core]: https://docs.sqlalchemy.org/en/latest/core/ [alembic]: https://alembic.sqlalchemy.org/en/latest/ starlette-0.50.0/docs/endpoints.md000066400000000000000000000100771510142272400170630ustar00rootroot00000000000000 Starlette includes the classes `HTTPEndpoint` and `WebSocketEndpoint` that provide a class-based view pattern for handling HTTP method dispatching and WebSocket sessions. ### HTTPEndpoint The `HTTPEndpoint` class can be used as an ASGI application: ```python from starlette.responses import PlainTextResponse from starlette.endpoints import HTTPEndpoint class App(HTTPEndpoint): async def get(self, request): return PlainTextResponse(f"Hello, world!") ``` If you're using a Starlette application instance to handle routing, you can dispatch to an `HTTPEndpoint` class. Make sure to dispatch to the class itself, rather than to an instance of the class: ```python from starlette.applications import Starlette from starlette.responses import PlainTextResponse from starlette.endpoints import HTTPEndpoint from starlette.routing import Route class Homepage(HTTPEndpoint): async def get(self, request): return PlainTextResponse(f"Hello, world!") class User(HTTPEndpoint): async def get(self, request): username = request.path_params['username'] return PlainTextResponse(f"Hello, {username}") routes = [ Route("/", Homepage), Route("/{username}", User) ] app = Starlette(routes=routes) ``` HTTP endpoint classes will respond with "405 Method not allowed" responses for any request methods which do not map to a corresponding handler. ### WebSocketEndpoint The `WebSocketEndpoint` class is an ASGI application that presents a wrapper around the functionality of a `WebSocket` instance. The ASGI connection scope is accessible on the endpoint instance via `.scope` and has an attribute `encoding` which may optionally be set, in order to validate the expected websocket data in the `on_receive` method. The encoding types are: * `'json'` * `'bytes'` * `'text'` There are three overridable methods for handling specific ASGI websocket message types: * `async def on_connect(websocket, **kwargs)` * `async def on_receive(websocket, data)` * `async def on_disconnect(websocket, close_code)` ```python from starlette.endpoints import WebSocketEndpoint class App(WebSocketEndpoint): encoding = 'bytes' async def on_connect(self, websocket): await websocket.accept() async def on_receive(self, websocket, data): await websocket.send_bytes(b"Message: " + data) async def on_disconnect(self, websocket, close_code): pass ``` The `WebSocketEndpoint` can also be used with the `Starlette` application class: ```python import uvicorn from starlette.applications import Starlette from starlette.endpoints import WebSocketEndpoint, HTTPEndpoint from starlette.responses import HTMLResponse from starlette.routing import Route, WebSocketRoute html = """ Chat

WebSocket Chat

""" class Homepage(HTTPEndpoint): async def get(self, request): return HTMLResponse(html) class Echo(WebSocketEndpoint): encoding = "text" async def on_receive(self, websocket, data): await websocket.send_text(f"Message text was: {data}") routes = [ Route("/", Homepage), WebSocketRoute("/ws", Echo) ] app = Starlette(routes=routes) ``` starlette-0.50.0/docs/exceptions.md000066400000000000000000000120501510142272400172320ustar00rootroot00000000000000 Starlette allows you to install custom exception handlers to deal with how you return responses when errors or handled exceptions occur. ```python from starlette.applications import Starlette from starlette.exceptions import HTTPException from starlette.requests import Request from starlette.responses import HTMLResponse HTML_404_PAGE = ... HTML_500_PAGE = ... async def not_found(request: Request, exc: HTTPException): return HTMLResponse(content=HTML_404_PAGE, status_code=exc.status_code) async def server_error(request: Request, exc: HTTPException): return HTMLResponse(content=HTML_500_PAGE, status_code=exc.status_code) exception_handlers = { 404: not_found, 500: server_error } app = Starlette(routes=routes, exception_handlers=exception_handlers) ``` If `debug` is enabled and an error occurs, then instead of using the installed 500 handler, Starlette will respond with a traceback response. ```python app = Starlette(debug=True, routes=routes, exception_handlers=exception_handlers) ``` As well as registering handlers for specific status codes, you can also register handlers for classes of exceptions. In particular you might want to override how the built-in `HTTPException` class is handled. For example, to use JSON style responses: ```python async def http_exception(request: Request, exc: HTTPException): return JSONResponse({"detail": exc.detail}, status_code=exc.status_code) exception_handlers = { HTTPException: http_exception } ``` The `HTTPException` is also equipped with the `headers` argument. Which allows the propagation of the headers to the response class: ```python async def http_exception(request: Request, exc: HTTPException): return JSONResponse( {"detail": exc.detail}, status_code=exc.status_code, headers=exc.headers ) ``` You might also want to override how `WebSocketException` is handled: ```python async def websocket_exception(websocket: WebSocket, exc: WebSocketException): await websocket.close(code=1008) exception_handlers = { WebSocketException: websocket_exception } ``` ## Errors and handled exceptions It is important to differentiate between handled exceptions and errors. Handled exceptions do not represent error cases. They are coerced into appropriate HTTP responses, which are then sent through the standard middleware stack. By default the `HTTPException` class is used to manage any handled exceptions. Errors are any other exception that occurs within the application. These cases should bubble through the entire middleware stack as exceptions. Any error logging middleware should ensure that it re-raises the exception all the way up to the server. In practical terms, the error handled used is `exception_handler[500]` or `exception_handler[Exception]`. Both keys `500` and `Exception` can be used. See below: ```python async def handle_error(request: Request, exc: HTTPException): # Perform some logic return JSONResponse({"detail": exc.detail}, status_code=exc.status_code) exception_handlers = { Exception: handle_error # or "500: handle_error" } ``` It's important to notice that in case a [`BackgroundTask`](background.md) raises an exception, it will be handled by the `handle_error` function, but at that point, the response was already sent. In other words, the response created by `handle_error` will be discarded. In case the error happens before the response was sent, then it will use the response object - in the above example, the returned `JSONResponse`. In order to deal with this behaviour correctly, the middleware stack of a `Starlette` application is configured like this: * `ServerErrorMiddleware` - Returns 500 responses when server errors occur. * Installed middleware * `ExceptionMiddleware` - Deals with handled exceptions, and returns responses. * Router * Endpoints ## HTTPException The `HTTPException` class provides a base class that you can use for any handled exceptions. The `ExceptionMiddleware` implementation defaults to returning plain-text HTTP responses for any `HTTPException`. * `HTTPException(status_code, detail=None, headers=None)` You should only raise `HTTPException` inside routing or endpoints. Middleware classes should instead just return appropriate responses directly. You can use an `HTTPException` on a WebSocket endpoint. In case it's raised before `websocket.accept()` the connection is not upgraded to a WebSocket connection, and the proper HTTP response is returned. ```python from starlette.applications import Starlette from starlette.exceptions import HTTPException from starlette.routing import WebSocketRoute from starlette.websockets import WebSocket async def websocket_endpoint(websocket: WebSocket): raise HTTPException(status_code=400, detail="Bad request") app = Starlette(routes=[WebSocketRoute("/ws", websocket_endpoint)]) ``` ## WebSocketException You can use the `WebSocketException` class to raise errors inside of WebSocket endpoints. * `WebSocketException(code=1008, reason=None)` You can set any code valid as defined [in the specification](https://tools.ietf.org/html/rfc6455#section-7.4.1). starlette-0.50.0/docs/graphql.md000066400000000000000000000011441510142272400165110ustar00rootroot00000000000000GraphQL support in Starlette was deprecated in version 0.15.0, and removed in version 0.17.0. Although GraphQL support is no longer built in to Starlette, you can still use GraphQL with Starlette via 3rd party libraries. These libraries all have Starlette-specific guides to help you do just that: - [Ariadne](https://ariadnegraphql.org/docs/starlette-integration.html) - [`starlette-graphene3`](https://github.com/ciscorn/starlette-graphene3#example) - [Strawberry](https://strawberry.rocks/docs/integrations/starlette) - [`tartiflette-asgi`](https://tartiflette.github.io/tartiflette-asgi/usage/#starlette) starlette-0.50.0/docs/img/000077500000000000000000000000001510142272400153055ustar00rootroot00000000000000starlette-0.50.0/docs/img/gh-actions-fail-check.png000066400000000000000000035506351510142272400220540ustar00rootroot00000000000000PNG  IHDR >Q miCCPICC ProfileHWXS[BzDj)!ҋ`#$cBP (;veQ}Pyu_ϙ3)w&4?p%H kq$/Ne[ zK=dxJܜJ~葡9hI %#aDhx g>y|'<%:'?D9t@0U-2n 9=`Cf\7θgOeVT2iȮdl@"RQsEQ료5s졙>ޣ~b Պ*vULE!c|4Rr3GѦQ)I\J%rrV]]RG=^]>GR}9:TG*:*.nަh Z:VK;I{@Aph5fkTk4h\xIִdiN,ҬܯyI[ejҪ:uSW=R;V;_{uH:::|:uNkt: D4a="}gG|utszwȑ#GqstU]svor!Xq˓9sg/o/WWwZL]fs1'ga^|s|(-[s7w026tZrkY=c9rX;Y]߳}3CҐPЪaaaua=ÏG""GrxZNOwSQԨĨGю+Gߋ4ƂXNqvq&Lp681qG⻤थIw-))RjSާH3b1ӌDiMcCǮ9s\ɸO~ G&jNNܟAHؑ˭fr2fؼռ ~9K/X!x埵"y.aB-bDs"r6ύݖ۟;_-?#XG+>5lI'IcU{Qҭ2D6^T ?[  ?LITiM{VVt|:oz sg<ɚi2+sVlgw }.enߊ]W5/u^|s?)i~ 6,-r_fR~2ײϋy/<ʟd-i[t22o_h㕣W63KZ5q );*+XYszup&k}L7mQ֦M 55 7?ݒ/_jo-ex[jkkwXZvyyWȮzMw{{^{c_Ծ@i0Qє~0`K_C.8\}Dң+:{\rD-[sکSmN;vYc>{Ƌ^Z=[ہ6Kޗ.\nn~JWCƹvz7nwy_)ww=½Z+<^GwJ{ZYs燻º.e_w}e?lZFoWKo\wޗ~0#OML\Kר%\)wS6hiaFQ' z nng l &Uh$}hD>-H+f,=Bg%3?Q("?JEQweXIfMM*>F(iNx >ASCIIScreenshotPg pHYs%%IR$iTXtXML:com.adobe.xmp 1478 3390 Screenshot 'iDOT(wp@IDATx oYUxc2(d5i WRFA#QH6iC qV( * ؁tft"(AAC oϹ=|T[~>89c9TyR8tzI-W5zUo @ BG18j6-Q_?\n+.a V?X X`Qiɘ``F1Y[0Bi#?XlZ2&X?XQgL; PD5 (?n)&Q`8bGͦ%c5udm` I?X X`Qiɘ``F1Y[0Bik8TW`0 ?h!&NE p(O)y'??T-K`"(8Oc'H+YK "(8Wc'__H+YK "(8Wc'__H+YK "(8Wc'__H+YK "(8Wc'__H+YK "(8Wc'__H+YK "(8Wc'__H+YK "(8Wc'__H+YK "(8Wc8C!#T}Ylb*?$1/9je`Lc*$5/bhnPU????0j^3΋mRL]hCU1000h¨yadۤDt;baaaфQgq^lbBGF #8&$E1T&Q1Sןd$E`>1iNU<﮻ҽ%g__H2/OJs+? c+3#?#$7*W<)ygQr`ʕW<PI\r)V9?X9aҼTq鎊;%\r/_}NpE+Qnko| Ƒyy|h&~AnE!UY/ȂN6-Tףm]&kB1!p10֬ײ=Lqm8B9q-N,_\kѹ2-=vbY#dž,%_urpfU"\-QXJjitx**<|98e\paZe,xUOqq ;#8e\pA|GȖ^mzbpr*aYǁ&,t:ןtρT s:P19дjzbN36<SMX/Xt_B[@b 9KWkhZL5a`1 uo M&,t:/]ncsi1ՄŜNg+m5x4-^錿tρT s:P19дjzbN36<SMX/Xt_B[@b 9KWkhZL5a`1 uo M&,t:/]ncsi1ՄŜNg+m5x4-^錿tρT s:P19дjzbN9yo/Bx(ժ O 'ɸ˩\? wW*?>0 Z_= +.Jka`Q':pOipO |z000ГGKL D848zCQIy=ZXTɣ%bN"SgS!ߨ??- ,*1SC'b3 b^oTR^zh1ԙG1Tx7*)O  =yDILWPv zV;7| pz:,@={Qa(#p]߂bJGȁz.UЃ~`Y0X@ 9Pv z0? (!׮WAƟg`1%#@=*s?0,,FZ{\^=ƟH p\k׫`ir pz` #-P=Bp]?ςbJGȁz.UЃ~`Y0X@ 9Pv z0? (!׮WAƟg`1%#@=*s?0,,FZ{\^=ƟH p\k׫`ir pz` #-P=Bp]?ςbJGȁz.UЃ~`Y0X@ 9Pv z0? (!׮WAyө<+D"U~=Tlq۽w(?ߵB8Ԍᨢ /_Xbk5`kv6#P2X֟?Yd'ϵB8Ԍ'O֟DYo߬YfZ!jFY7ob$ppVQV9yn1fņozwah8v/|wHK|{F ?̾'qc )__KY623cu/?)B Va=#?\ W/_ ."3b`n`!~`C`q1c7|X`C`?E`Knt8Xh>?XH``!a"X%d7:XzF ?4p |90>a@(cjB3hBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBnt2XBn7> q1p̚!'t659Y3h+cj5CN :ljr \-fɁV!2ku8Zf͐Ce 990방q1p̚!'4G[Wˬrr`@aScj5CN h29Y3æ!2kmer \-fɁ]MCe 99098Zf͐Wˬrr`@sq1p̚!'t659Y3h+cj5CN :ljr \-fɁV!2ku8Zf͐Ce 990방q1p̚!'4G[Wˬrr`@aScj5CN h29Y3æ!2kmer \-fɁ]MCe 99098Zf͐Wˬrr`@sq1p̚!'t659Y3h+cj5CN :ljr \-fɁV!2ku8Zf͐Ce 990방q1p̚!'4G[Wˬrr`@aScj5CN h29Y3æ!2kmer \-fɁ]MCe 99098Zf͐Wˬrr`@sq1p̚!'t659Y3h+cj5CN :ljr \-fɁV!2ku8Zf͐Ce 990방q1p̚!'4G[Wˬrr`@aScj5CN h29Y3æ!2kmer \-fɁ]MCe 99098Zf͐Wˬrr`@sq1p̚!'t659Y3h+cj5CN :ljr \-fɁV!2ku8Zf͐Ce 990방q1p̚!'4G[Wˬrr`@aScj5CN h29Y3æ!2kmer \-fɁ]MCe 99098Zf͐Wˬrr`@sq1p̚!'t659Y3h+cj5CN :ljr \-fɁV!2ku8Zf͐Ce 990방q1p̚!'4G[Wˬrr`@aScj5CN h29Y3æ!2kmer \-fɁ]MCe 99098Zf͐Wˬrr`@sq1p̚!'t659Y3h+cj5CN :ljr \-fɁV!2ku8Zf͐Ce 990방q1p̚!'4G[Wˬrr`@aScj5|өjPŸ >_ ܲi5&/g= :f>՘ :z00H,0T`̀Lѥu8՘ Wmz00H,0T`г$PRAT柜 ?)Եn_D502՘ :z00H,0T`̀Lѥu8՘"ryW :%csZIS_N?)ԵndVS?? ?9<3 19ƤT`)ՃGb,7> =hA8!_8u~z} ?f";$] 3G &;rG?raKJ"hAr OeXb+)bӖF?@!d';/?rao[X:ZqPa Zgс7o6?Xd o߬t`~>Zzܚ'lil)$;w_TN @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;4B?kCߖVtd-w-^)?mr {q]e;Nl*/.l>BP7g"2bGbi6 Mk3F7d"gɉ?9A֚4?\ڜ9G1ɉ?5i:?\O]5''?\N#qΗ#\rEjhA''\O-c(p?yvc.''?\NΗ#\rOژ7b3NN\rݝ,\-ֆ]rɍe86Ƨ. d0~UC 5˒?2= .d W%5bF(Ɵz)*d1\888>uχ>E/y?  5 D)EfHO`y:D KB8 6 4m=8>/kI*?ͧ2M\,;pu7yT"XQt?CX)a{߬uS*x]Gl__9sx+/G8^WLB*?z~ ;qCL`UU>ɸG qCL`UU>ɸs|q0nK}H;ĭUL;kѸ!UU$c̿- 1*dz~L ߈㆘RUO@2n=?&?qoDqC@' }޾Oخ-VAQRV!w"%OxQؕ ӽ nh%}&J751`x믮D?^`)` 8sNI_tNDppKA)/);RI4nM(Yb>SXb?/^PSX;Y[`e1q羅D'OouuW?vVw-e+o|\嚦\9|wLFp]-22Xc1nkTc1]kSh,uhC'c b9WݠkIy%5GtityQdwAb~uxW8N1Yk >A#{KQ\ltƟDNL_gO + mQXg˹ظ3?arxۄg:ah = iDp"a4'x L)7o??;_l`fac-_Y+Xb_}{i6o?oa7eY_;? H6'>'>*#>c8Ч ||3\InwKo9:a$Q3›q[hQ6g^^ZR_Ԍ? ?{%w[s*@uPڭ?s>!n. z,8dۗTmu$>"YW9'tϺgOH̿\$3zae)Xd_r/c-'cQg?kw͈A?D>OEDI ^88Q?,aH(w\/\r[/'bjw TQeĽ%@ZE2.; : Eazח r< Eazs'pzvK' Eazփw?0FuK' Eazփ~`8  jO>Xq-՞|2@.YƟڈ{^ziٻ̱9Coy զnZ{Ô64bȧq|>Q !g F{zpM8?,_ڼKb4Y&Ys%-r/?o ?2(`v?ڤ`WfDP_ɌSײ|_׿?쿲W=/ D7>A+g`]V.\0w>vsOes F6bKxnI11=cPP {3+5/eNeϿ5O Hoy%~SYɞL/R5ϫ}^yd(Q}B hoESS5M븲*Zmmpe1릤h4lqfYEAy0GJd*F 4b. y*3Sg 8(/7t}}edD}X/tP?΄%D #WoW\ N )OK`h/9XʨC'_?3Uo'EƩp'C7s7cW7?E/TL] PTe_aI O?ǿt|ӨZgQԊm Գհj<ÛUC|Y>Wϋ Ɵp;iy h= y.]/O8](l_{tU [^.]UűhKW~q,ZUE*l_{tU [^.]UűhKW~q,ZUE*l_{tU [^.]UűhKW~q,ZUE*l_{tU [^.]UűhKW~q,ZUE*l_{tU [^.]UűhKW~q,ZUE*l_{tU [^.]Uűh TOdҥFE~B~H/?E? ä"ׇ?O՜.20rZwdRWe`bM_q7 "F[C4 6o Bs7ߖ5Co[DFO?`w ?}lOW_FGD evTf1}1&3 |</dUߓ2ϧؘvL_&#ba3o@TvTf1}1& 8Ozw_n܉tc\kfe}å1FDsUqo߲v?gM4?_?*Ŗ6<5S@j>hMeX84֟?Y,[ pYAꅘYs "%$5_S up/tWq/*zAx_ S"/쿰+eN L ׉族v+sƧs'}tv-@U '"*$O3lB+s)8P̦VDca`?C0T}tQy =.f_2#$(2=)3> bB5_^?S3${}p|E /-0#I ?OϠKsr75Q= O?ykOoe#9*h>Ќ/|/'׏/W_l}'u^Ճ1)F Jf#jac>Nd>'T^- ǧ 13,CL$h^- O #9K$ddH$KѼZC={/*#.?cz%˘5xK&zfωo}BQ[D0"9;5Cq SCaW$?9.+]h \GCr8b/zciuO?}`?4)r{N#[=<r{ %}NĒ`5`AN_aHP0<Y@r˛|GD~;o"R+BQKFQҶU[! ?F387>Oo\=vj{wHO+[ѕ*t7raI ?̿ޜ3Z$ Xb{lHGy O쿱daW_I 쿲+쿳.k=>>7>7>{vu'T9 =9='[gXU6_') LդDnPUT׀qqbhWnPU??M5/DI&$u1TϧnopاIO?/wМa_!E%Q1y@׵ H6Yr* ,{#  XCFSA&;NC_ҕ²c)UR?J,Hn`_WSJ;t`쿰vVFg_$XO|o7>ae$ᢨ+TXЖq|rIfTnʕvTGg??̆BR3v\N3?(ir߳7>i>ݐ`r+%D)}UmM3L6®ѓ{q|'SdRp1hˑ̿\GKfґTcSLQnp_9%Kr'Q/p7sl*<=&ߺ1oTUϟ?W9Q/Ea|SշÇ LD?|TC!fO30bĨQ8c@ag78%\YT|2ʧO.}f{w7aYVث]?'ΈB!V}9Tiv3ABi$~O3 p:38uUk ?cOpՁxO`'+ٷq&Z@ 8FogfQn%5?16쿳;{(gf|im#䵏=քfp]3ívn@؏8?n5/P\a(#p]H p\k׫p;{˛+iqYP?IүRQ<պ뛝W_dg9T-fO3|rpYr'K<_,m߄/֟ZqaYs!#/?fbɋCj3OV0|+QF?qo쿱&^3“}[|-3oo/`l+ʦP\Wϫ|c{ rb*7xE负O)߹\2^y-UW8oG=ul|/1?ǟ<@'οO;E?/?Qa)qeƣg捐%ZzOz3ɮ}m\ooޅlW'Gr%/mI#5 q O ӹBbUXb a:%T6$X ֟^` SX`M-3o|ȋ5Mb]CsEYXD?0/,Q2'-Dzp߈S> V](N[{jw]rcqk׾ފd7@ǸǷկߟ|-r\?Cu[EeZ="aJ=ŴPp_Wاg@1c#SƟO ?__rIQ;%%_<);HBX FpEF?=8EZEeO _4D)#G,?tDQWy$NVX?XdI'O?bSQ֟(Xk`m3'q iXIO6%J!A pR7 :=UZ*fP5^ylqV_r\o|S9@ ZκfЄ5E lW%(I3dX lW%(I3dX lW%(I3dX lW%(I3dX lW%(I3dX lW%(I3dX lW%(I3dX lW%(I3dX lW%(I3dX lW%(I3dX lW%(I3dX lW%(I3dX lW%(I3dX lW%(I3dX lW%(I3dX lW%(I3dX lW%(I3dX lW%(I3dX lW%(I3dX lW%(I3dX :u~f|4B;xDgf-s&)Nx#b.gq1H6IYe;pe'o?&?m'7T}A`]d'ҼҨ%qb',ƞ"7q'?oߤPBt}꿶7>+}&I~vQ>'١Z_-fɁ]oWkzs7]u{ەoz5M%Ξݾ;c1~: e 990u1p̚!'tg\r \-fɁ`;!2kНqr1p̚!'PWˬrr`@wƅ!2kP Cr \-fɁ*Wˬrr`@1u1p̚!'tg\r \-fɁ`;!2kНqr1p̚!'PWˬrr`@wƅ!2kP Cr \-fɁ*Wˬrr`@1u1p̚!'tg\r \-fɁ`;!2kНqr1p̚!'4|h@uC,_?{rN |mޔ{R7;t7Jl 8G}{D38bg$ v ,/2tJhW)Op.~(ggCj4jX`+_AUf_d>`'tseGdG=əGdX J鬱o|ҷ= c rzgISG?W]=g䖏;N굯^%>P'v=Ϛw=?}F3$&ls%"D}wյ"w ?-%@y ¦՘vj۶Ƨ2hg4"`e|Uv~һj{j8T(+Ts|_şiF'ӌO,7Xx1KVL/PVN?Yd-@^u _74Qp?=oZ\A߬Yȉ?K|!yQ J?C 75g mH?ʄ+/N &yJ]ɩ|"K`₎tcj]8xz} Ck_/휾;UaS<7==ToW Δv#lQ(dBM1:?ڮ7l]s5ۧV=qv]?k oX$G3~ayFG}tcqI 柋^">2so=OklEFR[ֿTa`pzkTQ[v?o?̿RHlORo43͜B2#qA_ۛN r*U~Oor7PxxPzp&Tt_n~s7}*a_Sﻷ[y\qA@*:MB2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)$;43͜B2#qA @*:)8o|qGm{ONBmS\GSR "X _MFނaq10ZGpqԥdrȣY O"9Ws'O 7o߾tBZJJC1+r$[=(EXb!_%G_=Y?^.Ϭ/otӭΨEƿ=pٳ9' >Ȝ~uWhc8o4n0NNLuY@4;w>{fVk#S,eK'Q!$/9C)e~\QNy^_^?/?Xٺk^`+(j<~7s7FC>DN*-?I=r7xN\_O?NR>qiuoj=O %&InpCtXFd W[MO8.ߖom:_^ ?cELOu=n)ݷoS/{滰>Nw?ٮ7q?C7~v\ ¿_Wp&c*]doΥ хʰK3O'Zyl>9<[\p&c*}*~(Q|a:C{uvh>CH/_okGEv׿.E0?οO<aA2e#s믧/Fu!&ՋRgrJ`'o?/J=_ %?p7Prt`'̜yRm4W)!fgfg)f?k~ 1M)U_19 @s1zK꯻;*7~hZ+?߱V~F\K㊨׸qCLhUU>ɸzo2yWUWDbB Hƭ$'`h1n(UU$cW0F7 |q1 =.L~(h]K.i"J FhzNezng|8>/ apр)aa/?XIIpeWpo Ic+GG?H0% ? /쿰 /hͬ$~̈́o()*s{+sI4Ĉ?p]1;Xf7oM}OOՊ2Ƨ,`b?5뻿]{/UGz 6mO W|'7>g{ (;?`uV?7?~p>(so~ 'z*l&7$FO0m7M3g-~rlgJHX('_l{nvgJ]vY7o;wg>So;\x۶vK&7k9\mg6WfMn74{nv[l}ovp{~f7._qA6@d ^#}uL8X#YT?5y f@֥zCc3#N2uWl~i\37>l"]ZxV <ҟXc_oꕗF.ѡսfNePO38$%2r+P[iӟ}Ɨ_@q蛟_-wkN+/xȧۯ}g6m/޻}g?p{K^ -~g~vgt_mo}n?#? m7<O7)eaczD t9zv;ޡ?{Ӭ&y^mz0q}g]wvE!g?c?چ/g{vMk[[_'vW-ۗ="l۾e}=ַ=|;m_=b߿+ۧڧ_= lnU?~Foᑣ5#ǯ󯽯ԍd̝{'h!ursqk3o|ٿNʏ+w!8=+@N.ӝczs|_'/D X묮«}Qjej%Y X)-d/*Jp'Z0jC?:gbI 'o쿱&u7$oK_Oן7>fm]plhE9 Plz.՝ǨhqcoƖk{ W~Ց˥qۮN /19~;}{B^ޜs[mnw; 4/|XOo| |?/p8v?}SOr<~xp%ľI,Ay[j{a걏}?7EiO鿫s{W_M/{nOy orV~/y})]zCfyًhxS/{,mP(zЃznQq꫷kңe/_6Ƨn?/G wӞ}[$;~5 }v;V cG׌I%js^" PyVCvZy0@n:6_Y i=%1*~Ig5dƨh%iՐs^" PyVCvZy0@n:6_Y i=%1*~Ig5dƨh%iՐs^" PyVCvZy0@n:6_Y i=%1*~Ig5dƨh%iՐs^" PyVCvZy0@n:6_Y i=%1*~Ig5d0}TT`co_cRRı7}nWq|_Ɍ?>| ?X}?߽†_VˉO_EN7o?_r'<Ыf_t`_y`Gu.7?"Nw~7>[h|zpNs度he rm=!Ƿ7%(]{co7EZ.6t[":ns[m'o_/nv[ݹvv6('-G/xKD/i/bƧ?g7b6I~;{۳~&3>niӝ]s[gۿڽo7>?ȵ7v?u WhG\(`qWJ.qcL`amqQ$2dud53?vVF?Kc_##r|6'AV[R`skmp'?hF/쿲jB??|yϟe7>7 |f`׿W߯MYIR i94&ΓvAUX>cas6Q5Ȋ;HU?qmL?K_cc%Ʉs7}BR2Ƃ QmK{2_yUW??էR`e.~ nplr[O/|嫿&tv‡7>OzI'ov?u7C=Exv$07i{_!m}cO$;7tb{ϼTYy{g|vWQ=N/-^l7{3o;dO??˨SLx%쿰}|]dJǣzo1<'[++٩~ dEazc<8pgT{_ƞn_%oJ?7pʽ5^χK=V5ҳ JTTt~ިFe⎵lv3< 꼳φ-ςc>yCƧ^'Ƨ2eF(也ЀN|Z 5kUސzCނ1^tnZiF|q x'SNEXJA_%K&3Owߋԡ=tCΓ xn> gKxRS ]r1}&Q3MTB<j> ;ƌ8b;nnG^g7 .x٧u%r%(0PJaKJ FuhyO% JpZBcCTAIӕFPPR5C{Z(q`Pt#bJ 4])hk%_:%MW Z>AAI!ר-i=AIӕFPPR5C{Z(q`Pt#bJ 4])hk%_:%MW Z>AAI!ר-i=AIӕFPPR5C{Z(q`Pt#bJ 4])hk%_:%MW Z>AAI!ר-i=AIӕFPPR5C{Z(q`Pt#b9RuQ wDRJ_-O>⯕ V_J 4&?#a쯍?6 2o6LCؙ?Ϳlio[[7[W \f[DA#Ϝl;??򲣭?l OWtP.}?B[mm]8ldKB'M+9@!G ӊtqpЛণNIBf<([ þL]֮3|(Q2\=3OaҭFE^XW?n*{PY_e;Sy 7>QLkp%W9s(x?Bh\K/V+Mkj=Oz Or7nUk'xJ9O[iRBJY8_\msh^%֪V8cŪ o" ѡҦxd_ţR57c{N%{p9-xdGţbCSruN,(Ky `/i2_Tĉl=0&T <0X3c;'j#0f ߇|P"R-#__?'YmE5&QU0Xo;bi}0e_ӼmfWy]nx " i*]O?u?$=0 ͥLJS=&]4O? Խ ^V$?)XdPZ#x=h"0W_#b$Ә<KK9ݯOyt)%ħ ]\PZs87߼y3_f͞G'NMx7uVS=(ǎDBЉO+fM<_Il@<<pcMx eaڤϡ{mW¤Ix1rHT'XEZQ?/6MSވ?_~9N>~ӳV^˖`;oܙH-Λ7Z>itEQHpaqqL=O5ylݨ&@K+FCN)*Cѩ4"H4朔a7iw}FDyd39)]SLq͒GjC5?^XBqIX('?9Syo7\_?JZO8noMCg$) "74EAQILi6@`Al6?mihVeO . U *"4"}Q ɁaOdODӀR[[)xS"ϪSyƧ0 `t2iS3R18(=lYJVL!l1Q}Yh<)D6|| 75HO7JrK-O ;5km\{?z_ c@`St*,[jר YOt"NInL"Mo wJ/RH4h`XU½<+:s7V]. O*Q O|˯cvWO>b醒䟙 "aނxyȀtnY))c/}Hzn՜o.xn*V؅kPuI=%ىiߙR3R18ގ*\zKȇWj.r ^}  dlGiiA22p'!P1t柜${QY3c$ e/Fq0ov2mM 7I"l_lֿmM6~@l" [[֟l't}"߳?<>F,<@d'&֗ }S)H  =,Feۿj*8Q3Xv-̞1-ʷÏB> ?eЅ'u@ZaH72Od ?M<{ħ3ژ7ܘ!lNx"P8n|7>Ӌ?7>ըQ \%z`M OG,:w }>O/88#oRK~W_++͝ϟ:x;),<Ćg+ 嗞M7?֭gߛVC'|~?OZ`wPqpL?3™fOgw+Tb;pM_@|X.‚(hCt8pG31ML'l9bRɟ>L1l$ 6ИKC _?d/?&HƑL?leO$6#l_dp_t^!ڧ???@KND,[7l7[7&3([G[G$ѾWLR`,S)^_F[+7=ߣCoiow7 RHsi]5QA*r>͉@ټ))tpܤJ۸t|.ƍSnN<Ұ|0uٯP?2첶P(~ 9|$A w/LzG~8Ï<Z/eÆ p\ͺimpRfD&,00_B?: OdNd  L&NO%JL}oRsz_N҇O7Vi?+oqc49QjPV=n 1r8Ty]f?opn|ܩ=H8x?$ӐsC1 a8NjVq@G sj]QA*܁ZA-qT N~:Kx&~>23 1՘!T4iPL Ӄ"eaOJ tҠLP,@8?YH"q(v )]F0><cCYD 5ΩLz䏒̭' }}(M:#C`9ɂ QF=K|][8_OzhGhVR~, T POHsEO?4$76pV-663 >fͿl&;'6[q恆 {°[Q_H dPb/v -l_lFJ%k/岣ysgG؝!A) |'$WBcB*q@CV24y n\?)٦}WvT.m4'$~k) ZCSQ'".f̜?<^za擠t5Ŵ1IӉLgx&LƧ& Fk!ܘa>BO`@AD'>Q!I/Y?k_t)ޤ9; "R6p˭0zgLCYƧNkVϻ RuԄ֮] Wu =OK_ y k"QiơCX)M&UmNCa477X:!38K_htnz'",(P*dףHL0GAxe?6 f}+j3w4l5D?v&BF43[l?leO%lMl_l?mRg$[كH_l_lŏ1u'[G[U'[W[WYy?㮾8h=+!#mQxb@mMnxn֣<cm|MMKJH4Tv x6pS  a$'>eB?I+||4k.!ڷU v([}yo?K? 4l9PIn&g紆_/ buÐox[1m|zOCXTS&'2I]`/D0Ndr7VR$AȷF ƪ)NKfXՓԾcW8y2/' 79 .&NMA}!zϛ?Z}>wHY&0 ƽÇ :ӄϟ B> sB<y\p.4Ɵ/R$ov]}iL&OKmWK#`߮*T>cХ_@_t⍫NmعQB*ڼ=?-xRr0|q!'ѐ M50 hϙ {ʂq21Kjb 0OLÛI@R 9_'ʸ[4o +G8ħ{pcؿI>`$zƤY&LŸu&~_N`Q'Տҿ/Ԩ݋hcN98T4 (YǍO9>t,tZQH([6.nS1ag7n|:[puBNx NePcUwH.wQ:rO~a.#\S(OA?hOެ#Bj<*"kЯ0Pp?rHix-t9PT)H8'tO(ʫ0O^:gd‰'ԇ ʕ;,GC?sR>vv%tN=),_֩5!ow G5Gz0}oRa6t'Apcd搷{~AuF-uq)yd Bk%r)9}/Q2Տ W,2Tdf]J؜Ͽ`k`Sg% jh8n֢5ϫ'?=g~NnpR|~^|%uʼB%<)R} ~ P_@Oe\5IA >#oVl`Лo!Kɣ?6:2eɧ)qU`X1K_O5z6 ΣO ~KK缠[w@8"Bנpw{7.-oXxލ+o}}?p<-?'8|'d{ٕ˘lAG3fkkelof7naD0gםo?6_?8߳_t;( gW}&=-oa(V\o3:-wgy4'|l?Xˬ"H/i֭Mn.Jl'|& K@aˉkՁ W}<&w ޏs9j+݊Dxec~)Q pBxF[> muk-ICpДۨE]M'P`ʴge>9=0c{(ӿ?V`bG ?`ȃW*6WSjfP(\؟r5X:Oǂm p=[s#J[!o0Cn{ө+UnHxt~dl_ϝD$f-΁xӮ,-?7Ͽb >Dx"'(b܌Yࢋ/;AпkpaR*z 7m,~AU=58#FtFϿ/?ww?~)/7ߞ2gg6FvNUK̿7Olg㟍>Nza_g!1_<<-=_<Guo7g'_ן=Ϻ5aslZ7&?$ϝ!p 9饐):6*G)ٞ)a0y[a)ĞڕtӹAc+r,QMw$T:=3HOLwLĩ k}O3^NmNp5W'9'CLb$%O?f) -^b&'H-홚(Hl&TөX"@JzUTCM0)V) rGOz#S_[I]i_$Q?%?s د~x:+ޕwWaDYW\ }k˜>C}Ƨnd/ZLsߙg1_u\~z7~̚5|pYWT8hOEmO_'}mY:@mjԴ,Y$E( ~yPCD$2]-D@`<@0X:L)e?5kW2eEzU1_^_h`?#Q_O $E(E0?yS@Ny;5 ީݣcx.e/-BR_C0Ͻ86*H$?bćpdrlXj5;dQW6<@ZbJ!V#H[[j*7 +!>"֭Wl<I )Txğa 'DZE'->"cZkV(pwo965/[i&w_Q=FMZ⥸I䟙 3N"ŋan6\yuӱ^~a'# Vιn~?`__YG'<>Iοy@'LK͹W~̿wͿ,T ԋa?l?hoV`7zb2Ewff!(Yx$qjw_o7g _oe!N}"S%e=#%UΎ+u3"wcdA)q‚A S#| ]s@G[b)AtYF1Alr@G[b)Aa7:ajj(_)(Qg =[hj,kBIJ}[@OJ[]>c@T-RBDJ`MXKRE̊6 E? X/<ԓQi޺4af l< 9K\փqcH"S9+ri≠j3`԰rn|r%w\Mn< uԖ3 @ħ?k]])SE&x[{kN\'1Х5>iDb^x -Q'rrDr*C'?o>t7>(4WyZ/9hxIH&gR̦!?c$ ֬Ybƿ`__Yb{P?h¸'>9z?f]㘕3m0߀%8YTwiAUP;+ //.\:L?I/ΐhÐ㟰/Jgw'௿F@؂_v^,B6ms(RJ iH[FqȆ+WCڵW8Kx~`G6üAo773K(Rd7,ӛ4Sp~%bxtgYdI*_!iwnM JcTt)dPXx^w.pB':qRc1&6/ƨX Xl[CFCk1c>ؚ5_E8O.WvW?m@4G"k?? R??fm! <;pփ䳭6a΀Av?0/4W?43ԧعsA{yej""Wd:Q|3_-P'&) bgoglQzV䠣nف?{'2h$% iQ.Hz%C5d1D@\J+%C5NddJG"5VbKfkv 76r)Ej> 8An*mRX},q"%T8ʥX24[DKqK)Rc%dhƉl rPi(RJcl.Q.Hǒ']2 @\J+%C5NddJG"5VbKfkv 76r)Ej> 8An*mRX},q"%T8ʥX24[DKqK)Rc%dhƉl rPi(RJcl.Q.Hǒ']2 @\J+%C5NddJG"5VbKfkv 76r)Ej> 8An*mRX},q"%T8ʥX24[DKqK)Rc%dhƉl rPi;,:֏S P6.鹚h24J MXUix7nt\`ẅN|ʑʓ{ ^G{@ ( # |x-/3 G4Qfp.㤝G #\?COXO|:!M͛[aNyhڸq,Ćo-|5ZaAЦ 9WZ 2PHq 7|]iY|!5(Z(]Ьiɔ;5+8aҸiSOȝ9;O=< &Ō:~܌Sr.)?Aӛn|rU1ᅦ^= 'M;<PZUs@h{NH]JHSRtb}h{ŜIX?HȅH?Zs,\qϟl믥A7>17p0wW//Cˮ@(=ڴ;nǓÂpB=FjL?(g\IdKgC{?7{`~obW*û xP0hΘ{H/$gwX2o<~%e?*믑n9JZ%tY3=oh$?ofX/}GCuSO?Y<ʎ?Gch\90ǿ?`qlu"{='2xf0؃txm S4Y`ق fh>l mM'+hMit T ʣ`?e[Mi,4ɫe2QLԅTO!Q$G"7gl:pQ"r@ ڲĹ?ʝwr*{QY(ի}p^M7&7G[)rj_bEx79Q^xxg2&qy@_jeTrݮcpWWx畀pz8&K)gTӊpl_`{ zj`[‹/O?( Pdq8S(VXX=L$еsGGw?3LؼrP~!k_Pj-&[K`/YީӾ{ }'ץC{Ά3%K#Ga Xow}t׭^E!0_GjBn TkA?fnMЄH쿍61?B;>=W$9al_fC!4\Y銘m26foRy:&c/2kO?׬ZiwI=Sf'_(YiT<&2qfL?Б~8,?6?+TF% -k. Xk:=oeQYHv)\Fl9WJ tadH3#>#/'ű7B ¿xPJ%hvfc8$:)7Z>?@fIBCcbhڬ%bҥf}0hW=3d 4ӱ\p7_O}' }q3݈uл}\Z=:vWP8z~783ypYg<İ^^/<1LƧ.q՚w=.|~r&*w<ןqTǟ.m'>3m˯uO|^ѽ6DՏ;i"_'z6C?䐃aA+pڛo=yx>W?w%ԛ<ѷoO;7kwo㿍6cg?0?R=(x~'rO!X綽(owBf&i?5N䵐HQT43;5hǏc.q;A3eP'UqEæT")54Jq I)ؓ*GāXOx N&WcOb>8qR*_=xDeiRJ|5Jq I)ؓ*GāXOx N&WcOb>8qR*_=xDeiRJ|5Jq I)ؓ*GāXOx N&WcOb>8qR*_=xDeiRJ|5Jq I)ؓ*GāXOx N&WcOb>8qR*_=xDeiRJ|5Jq I)ؓ*GāXOx N&WcOb>8qR*_=xDeiRJ|5Jq I)ؓ*GāXOx N&WcOb>!m|iPHyK=Zw t4/e$&,MbOF #>#.׈f`upfs~Ӎ=_k_n6t \{M7_g͘_O@ RJex́Rc+'>eEO|HoFȟN{S "y+Ǎ" sfN Oa旓?:tmΝWKY O~[<#_ֶ ܁'4i kœ6w]y%*D\b/?Mm O|g4i u;pBnR+֕Bkք_^~ })zH!zv _;I?;O={8r#H܄Ioe?]s?#EX:Lh#l_VJ҈M|?c8xz|5,y̔G#f_RR[Q2w7&?2Wm3O}ժ:o!  2;p c=#4A)cZ.S:RoG@SWUI9nVH _RiE2Fm.1rҠq:Ù٫OdBnI?\ïI(+8VѯȘE//,WvA9_+Kw>:b׮[ Mj sJ*[}:ڗ%[0􃷡1G#V}5c&\WZuØO>c9[6jgaߧSݝq"މ^ǟ|(S,n׶Աtl|Ҹi q13 VS4Byǭ p_зr[TD7&?d+dQEfA쯍?L6g㟍g]lk_6[xԀߵx'Oʇ yňBn7~g?VЂQohuc܌Rձk֬]:!$_n͟;H20^GG.DD\"E%p4bkEE]u-쳔׭[T4E čOKc0t~>jծa^{'DQp[xS]M#4m I3[pݵOqSǟ-3Ƨ s]Kß_"Ea'wɧ:dT;"¿Kpu=bFZK@*BP~-Y ."y%{&1"At[c=-o٘McWg˸_vOrE0OlwO#? Z^۞g6?'඾UC~6;܁xvŝ#Cr6\ObǾCCv{}ʔdX!#gOv؆X^gBg.~1E[ {_LqtchA}pDnFiu0D'n;!f(JzžeOlQ4lv2%BT{Hi<Ea򏴅(%D'n(L"ma(JzE Q! < [Ħ( ӿH[^QBT{Hi<"7WR5.ɒYCtB8iğ`"?LF*d$KGU1C8aT WEujg 6a,]o>bG3WvƓr5lܸ 8|aPZ6>\[џ~¿^/o|е9O|J?fƧ0vx(UMӪ\Fn~OH8P͛;0;},圛'DϿUO|Ʌ1o_ viw2U[o?k'>]p6>21mn+a͚ߡvN/<4 sx:]y?Y6̟;T=8P=bЋa؈p 7O|'>=TTQZuA:p6bbp7@Jѿ^j/_udCƧóO>_}~IGϿKpݱ|ԆFi񒥈^9eCӚO&ObNUPIE? _n{4fy韌ͷg㿍glIrolg=oWtiΊƹ|ڱQƼщٳÜٳq??h377d7)x4j6ʗ/yO6|p!0^",'ſPcӨQ#`,OVsqý4ϧ~.Hn|B( e<4ѧkH?ehx-4x "M@q O,zƄ ???! ;6cDČ&rU"Vd ~5Lܚx8r9r뚮}Xm ÆGt)Xl[plc~PhrPx1w0Ҷ6>@u-nD硇' =]Ƨ˂i_wlD|JcXbyAh޼Y~n'hm'FӺUs^n~6>QOݷ>W@_ozÙMqoN%% %iS_+ZDF"$ྞw`Goj9OzzN+4 Cm3%BR7#L䏺Y^k7k?56c?쳳?5k_[7#I[8$ʖ=hL)Ky0M6*vg;̄9fbsgGcq_paqS-?1XP͚WM؄NstY`!^4m;yvUw,F߻n[/< BШi3h҄' *=yOq"?)Ah5䪌y|ië/R .A!5">;ִA@qxDkZ TFPHpN5-qxEP*E\#(f8^g'њ8"("R3/ⳓhMK^}Jp I%J%k Nj$ZW_\5BjE|vië/R .A!5">;ִA@qxDkZ TFPHpN5-qxEP*E\#(f8^g'њ8"("R3/ⳓhMK^}Jp I%J%k Nj$ZW_\5BjE|vië/R .A!5">;ִA@qxDkZ TFPHpN5-qxEP*E\#(f8^g'њ8"("R3/ⳓhMK^}Jp I%J%8'> n]IԬxM<2ȇ<{RCPϫ c+ǜi*bjw?,L) [nԬ]it`Gb.5N9_Km1kzxkxwzⓊF['MSO|;O|B^;l P-^'-0E"q O?!dyfZ6Eʀ'vULRxC`Nլ7ЉOBXh`סvz\࣡[ox?^h~֙H^P(4Og)Y)Y Onwv~<#0O*gO7^׃1G_}WS'@})6W̙ѯ+Z&O ŋpQPumKK356zI37"Zr' }.8:??@\jli!1o/6Kh|$MBtB6=/d/m'ee9$i5laiA9ZM8b?gD=ןe e*Wgt/fOg(0[~xoAò_~_ ڌuypbCnw'v;$8~>^2?t6>'#t?Wf#qN&.ZgIu]'@XQH{Wn09)65jr&JINϒ Q{O|{2g#x'nQI y\-\ OJLW%a"bIp d)`p L(  0kx'tG8??ԍlj`0y#9\ +埙 _ *5(^2of0`e˗_¢~{QPnmG6k'>}5i.jE\?{нەʎ,ܠ5p7ae9PXnpy]&vTINO>ɟ'?uٟM?i㯍6koa%`a/ÉU(kI҇]{k?y1OP^mO>9OjO*_tޝ\zmY`?G]KfAMQG1I O5r$,`q濻ۿFx&^Y#MxnNd,\?5b$,~!/4u4˟dNyg-CʅuBq'>3XBp(_\?_Ci_.ϟ"3瓦Pd MH! fWf}(y~RHBc+T(+>s) ("}}Dhа"1dp?TT>0IT \ ^߯=G*a%+P7 Q }2/a~|*OϿuħ^1~jՅ 7nޞpHR? i6ma֜oTŊފ@ /f̚'r1:v'>IYK,{I'ṔV"Yta3V???涂o?Y3nP?5k_d&6k㯍6k㯍$G (|Zn+|?.i{9*lOvdpw mWFMLك)TǘQ#_…2i#R%>n޼~:玼FlJ1:N"iyCc+W?篬96;dXtrKCys?S8Ƽ1`3i% 0jp'Bm̳qNLRb74n 775=;gXv$'C_cF 2 n:I3m G#G4-ʏ~Pr1, 7Y| Rc11)N6$T@!p (3TŹt{ : A- Fe)WˇtZBc-i=%+-o#9)H*JNa(}`Pt`9Ez*(0PJO`BXr|{@+?_' ib = JLDylT? ]v\&9ⶸM7?MBt@yL2&ZX!OM31!/'>l|:dd7O>Dx?/O-Xj5;!F=?HuuP\A}\n|ڄY˳aѢQ8çg#4O|B*~xr5йS;,AO!*a,_= `q^6tS(0k:7͉o'>=De׬k7nFopoϻ q{(%!qOr50OYb*lBPp!iLUq#MrԿΝ:pIiRʟH~%`̰Uf srO/X\l dK-#36GֈG? ??5kXEOidX h?ū26ǎ?J[IOUiO\z%5j HtOyjԈY3𤄃܆+~'Xmr(Q8lYʐ1j`_[AOuiL'}+; .n9Oj T4U"7\FM䶒kElFk"CKqOyP,n9xA5 7i?VH aP!y&dT 9bȑsC´"]&Z ? C%='#<س8U<^0cixx@$>mZ.G*_fi 'iӊtq< hH`PEbȿBe<=CC@1) ,7b_Fȥֱ>{VKNi6,[N8cƎÏ~E7믽/enlkC]pr7Wk/Rb'PSl1=1ϿUtyq.CT9ӊTh|7hP!}/k4H"q[)q*4e q}~3XR%G/S`d(.1*>#FAяg! .P*e LTIQ 0kyC| Ɵ?Ə`d Gb*? 4& NISS{dAoxj[Pf%/l\"tWnEy,W_g|*@?];ÅpXʋk;9ަMk, kIA~; pNCʥwիi twБ&OO}DvlNKqj}T'۵q׍wYH%p4kLԱMz=`֭;8xZxmZf6&}W(h;?j~fH| SGɿmst86koo?0Kd5ߍXS,t[cgf3l?Sb''>97-SR-Xd=I@sgIԽgMR}Z׿?]=f,ڒCqGEj[1~Z@^yyg"i[jIwvP9WB@;~?b;vLҮ;ѣRa05ܼfpe`4kSzQ붭i#\6߶M;:z/~Td^)+dRN|%-V[SϞPAڹsҪrcƌ{>}믽/xo\PОZ4o< QCY⃈QC{>rvޅ~9RxwCy-ZJ]PA[JTn.!JS%ǟ3/'1 Xs$d?ʱO|r%sO1~\ypY0:r c4=?@?$ݿ$Ŧk/<&iOdݺu?q3"&sO':"ss^f)DZ'>%KIn.1v| @ 0=#=%YBb@,5sZizFzVFog/d!Ug*h? %aI{@2?k '6QD ni޴`Hskpn.# !p,Ouׇ#呵kx:}fj]gZ[ƿ6V?L. Qx7o6/0'~fqv7}oԽ{wyNO|ޭN}$wX0޿G`ܹ:;@ީWT'QA/ȃFDW!n-8Dee8Qm8A۴iC|QNQ]>=vf*NAߟ~q*8NS\'>zU8>O&r]48'5w9Q];ߥ<{G?w4xf#t)-zmlQH @6mt,qc'R\y.J_̰/2g7g/-<M߿}wy(`vqN6 &Ob}ҿws4̩֯]acO(A'{pۀ R^ '?ol'@dia+z WNŅGOR2ܸ='GlW@ŁAѨ|$ (]%e}ɟLhH āAB42dcfAJpٿ/H.ǃKm^_S\dF-.LNP@4IaPxzI]r ~3"-яJ~ׯԳxȇ@MC?m쟳hkfk?ec_gg/W9>A^hΗCNNwzF5h Ƚ#DovUErjd\ }kN};vl#<?m݆f|k?N Ғcjn֬xM ')ek2/Ch9ݵ{Ϟ4v\1ިs;ş}BWSoڵ};uP?ӊR-5eti.$_6n ϥ+FGBl۷l8OOJN:|JI#b\7z+g2)J.?wtW}~FWꀠ3qUUsTYu!©F |$?}O_ @W]s J9+I~V>?Mm<Xoc7MO Mm}/hPqXeL>mXNSt(QD;Q~_8u7 'm[??|'6#bv_ޟƀly~HYp8JJ*5+FO|GSY i[δ:]9_[?1%3Lkhos]|okHaihAq4ƿ~, 6AАSE#']ɉOh믽$'>9P}i̵9^{M7RفRG~ϑSW_yoGMݻvrL^l9%g^(?n-ϭo-|6o߹Zj%. *8$|¡wLO:rZqm<Y2pk$=o79;JWי1>p (a'7=査P\Z0Nw^9%Jx"='KT?} ȃG'8 I+A=)٫sC2$}p@0ǃ0M9+掋'r3$II2=O+N1!/X IeUzs3NaaQr$ɑ Ӄ0`韤W"Ȑ!lMc'Kjd#RoŢ=.Q[p8kG%AC\NO\_"5+e_z/R}Bl?gcƿg?LM7o?t?^3zp{O % Y_It'SY:g3Uf{kqR3bY>/pHbQ5Uuo?0nDSo*Nk:ʡGҼĤi瓞:t脇ϡO) QPVZI"Oۿiŗx.T5t9ic$ ;.D\Kyħ~}gpjͥn˟J~oݪ5pLj9t03nڶm+eCs^-OoBDNeSc<6(+iV/$lтqE%f1-ύ ?T&Xu/Ͻc P&0 LxELeOD'N,ysi8A߿IN8Is` 8]KYٹib VC?s=&ż4tOFsW0dkypI21] hia1BX1 Fo'"I0aŴgNdxz yM#!#/ԉ$/NT:UGJ {!,:~@I6`->:Ԥf~0٠,-)-[_0͙7_s_{ǹ=h+ Ci6o?fJ.z{MOg}:k?fc?f} W?fc?gçWC8У{wsYxqݣaGl>g,?vhٶ[ZKĴ]? 4fVުΝ:©D[T7P frZA4rUj8]lvVj_ODK>VS߲eKym||X+8q N /nNQh= @$ Wy!zg<}vY-$@>w^ĉO%Bk4j53;qm?ޭ;M<:LO=:y1-uoӜnB4C_]*?z&3YWB_f*95^`LN/={<4_V/$/d?ϧ"HD3MNĜ] %׿;= *,/NO֭ou7o8M1ޙ0Yo3^,)NF#4V Ad䁌dJJ<`䁺He}y)1x@FRW/ ?:b!% 7Ӳ}i6lo X`M~,txJbaM\W#+?o8rAD >yh7c9< HƟA,AWӿne+͹D.c)"SK݉;> Bvq/-K9|bmw!iO菾aӪ+?;OdSUy%uڕ&Mܠݻw9yST0&ДEޡMlf l&Nq:aK|A[)hHgF~K'ho{_dZ߻T8. 'eY _Bj4^qܬ˷d!EH`Fq[Rb3?6}d#]|Aa`ƍ+QPBLY'N!S`?*Gf{2C j҈ͺʈ/r3iQៃR?rJsqYW_Fogt%7kͿb aٟf_ф`O߶`/%??l#_nMfiXfЃ\ROn53=ӓ*Ubεk_@zSʃMn.Ϻp|}Wip)hA?#>=!҈.fh1/\DW^1Zڵ|2Z@a_}8y9rՍOCc{]ȧ0Is]nϡ7W_J/Xj*|R(+G_E 8ir49 ϕv)} 6oDkZE*ɢjsA~>׮#ٿfP _oCǟ8=?fkqtǟl:輛vp|R^j~Kx*c/Dfe#6=_Jk4D6SsҒ5Y}Щ1Ư8 U(Sz<?MLl%JI/a+^Ѹ\jL? FKW4|(GnGB>2dQBG$QM ܃O'#cӒ7iW21?Tӿorm'Z feiF`m_x4"ll)j'm?,_^7XB'Nپv*fCapz⋷tf[[;wBcǍZʓUaY8.]vb*^?o6ڹSP r8&u%.H2Q 9ǧ8>uh/|ь_BC.Pgҥp\~ë/FBʼnWpH˴6y49e38Im0fu8?jzWd>So:Ig2'qԳg/io̧[H/R!W+I!kh14`wIÆӐ!Cy .<ǡm[$7(ϵ&k!GSs7Lq_Hk_Yi5_w4C(~{iyV 4;?(<'L_tjSԻE2_1.͛3ouVCz@ryJa(|Zl /u=dM'+ #ia 4N]ӣ|r!#L2,/^@(3$i2$??:94{ nj$Dc a?6le1E-r%i2¤?EsN9eOͿ6o:Yb$I˛nSfye86Dymؒ/?-߶?ق?`JI_ld`l%+d x?y7ϣÇ7_ÇWtu;pvQiY UUVPEE%uԙ.pׯYCczϻ.̝iFZ4J>񩆖/)\˗xAuaҔO݉Ol 1ӫ^}O%R ԽG/- 7Vۯg̸'eʼnO{KY)K=wӼeM:wtN|ڸk$SKyzP']A)٫/u7EM0SpDY_&i, ps̉ L'U m}5Hc'M H6olzc\oMDĉ|"'sفi'Cc5'eQ^͡8zNww"xJv0Q Iє:"!$ZڕZa`$ Q3g'1$\$U6+SRM==bD"b_GFW Xn0 1dFElWRhBI8#%9Wne&.2ƟހiL4O` [=%,a[֟#֟e:[MbrHYc [ΊN sf3pS,(Lֿѣ1={Ҹ≮Qh p,pbA2l؟?xndﰎÆL[yGQG3{[u6x7Uڳ{6pMM5=wv}5Կ@ؼZ;i¢s#Zv }7mMOLac So߾tI/=/p}`a]9jYt -ÉOJ_O|=uUO'v|r#[kǎp^*-݇ڈF(z*O%/mw~==pDliODIm1E<:yUנmԪu+sA'HȰ>0:U 5L~thG3瓦n?q"Rɾ}B_iBeE}4BLa[0K؉+Ϝu[Mlad1sFDWc/ ',rl0Omh/[[FU.1&!gD0Ex9r2üG$+W0xdF?la[`?lqZ?ڵggcwo#FO9tvlA;vn?Gova){?x$uH$GIH9tH<ڳkc# Lfyy4ř|гΒx> {:z(ʋtL!p\W\,e9BO>=yT $wޠm~ϧ-\9*^v-} }>O|*(@X2)ԭ{7{0J;}LjNBW,_FK\T4r.['q[tA*<Ӑy?.@p<\v<Ӈ}h/SI>.s yF8%JA~ey%m-ٷNoݨwOL#.Zm|0A5ƙԶ]~Vs_牖}6zH?0f\ \"_(RQR>58aWc_ N%Xϝ 8=gh}Ù<;~߯~)m矦nCcN?f ߸?##cETTHœ'8r㔧 )[ |8Nv_tf.803+rp온8Cr 5Da.#xL5nKI=0_F 9id&Llљ@ 1Wܐ<1̗_ӿ 1HfBo8ҔQ6B8Qpa^#Oa~ql0cw56ns,QNf)ʐm8 QmbLlQ!Fy?6k5Xi/?yƒN2We# liO[; S*G#5lSmlxc_lΘY8rb򒺁a'T$k];;EqY\lU$4wԟBۿ}V-ZRW8 8lDk>\9L#\GVӶ[i˖@Ջzh%rr7낡hEKMtӲuKSz1u^ǧO>@M.f=nF-sڲy3m۾vhj5G"=ǮUGppFKO3M>UYU0u1f88>ǧu<;Aޥ\O٫'5͓v81E<ϡWrz#ؼ;`6nZܥ+M2EJ1olFڽw7u߇C Kܐ~} NA ~ '9M"t|~fh ?vQiɞsh|*=xq52_?L)P'ktyi>c{x2q'}YLAv>(22X*c)WDy\'߳$u@;>D%e#Ȓ#%s/_Ad$!({dI9—ɟɟHBP" Ȓ#%s/??DA%9FJ_&  ΋ɋ8<߯8'˾.dGq\!s=bK7 +f 8.bRaO4Jܠ;#a0O6MfGfl`3k8`Á1[6 Srg= 0_le/[_٠/5@pqdiDw sBڽcvZgp|2$(e ħ wmN>nӮmێ8B<ݷ=PѹtȑBْ/WK=:u*Yp|7h:>1ٯL{8/;ǥVgi%w0K?  }?ɟ̤s:%'ykWNj_N$j+8NAEEQhxگ"琯oc'8߰&O2J'WA3b4D(ħJɃCulo(5+aSfj#$R'RғwFHHblfOƨ? t 5%V+Lu%},kͿM2;dl<1h 1|l$rtRRA.i/9JEq Pj`&~\9 W+XBlc/m!C$C܆@Gf)CXwU贃ijR!d/'f I0;a7a/[ăufBets6[*H4\_fAj'//1ztAq:XR/Bs1a/©Q n/S;@d\$ZI`Pn.}5ןr*0DȡChoўݻ]IǨZȑ&'EE%}a 5׎s$UU 48ůE}؅W_>$ H]t8II.,9 [n>x_򐙥[G#p*ٷsQ . :ÉO6~xZQ-O<bUu.E@QSӏyq9W1=WW7_rSOwYK?;WP|ǝKJj=CWXXD?^TDwN|3W-M?3F塖,#=PS G%uZ⺲gsgkPdQBR͉h !jBlc䨜F)/<:*=V 7.ɖS3V LMţA2YHh#gdB30RF&1c#pHF\ӿ3 k^lQdT!5q5*V 8( j7WVd 9~T{Fo??368D_?rJOx+RwhxG*ha$Ԫmأ"a$V*h6c6ÒHQ"?d `_bz:3>6o72D$-Vma/[WN|J]j!aÇP$O}ZdILuVZ:v 8 >{v>sTPPTZRBUG˜So߱=nݖҁυSԢU 8ARHg[Mx<8*?DK:>RbЁ7c=/j(LΝJiw}˲ѢE W*+cg)kf Nszit?cyIEϡk0\'<|:QsY]D83z߯WօH;]8Oyt7srO -9.@9ʩ@<0'͟ ǩ9s:O8>)'̬ S.֚RIQL5P1WzDB @M&E1MP}24[Ô(&&j>taJv rPqIQL5Td 0%;ɤ(*]fkETdRD ه.C5LɎAn*n2)iCdG 774QCEl ShLb"eh)Q4 @M&E1MP}24[Ô(&&j>taJv rPqIQL5Td 0%;ɤ(*]fkETdRD ه.C5LɎAn*n2)iCdG 774QCEl ShLb"eh)Q4 @M&E1MP}24[Ô(&&j>taJv rPqIQL5Td 0%;ɤ(*]fkETdRD ه.C5LɎAn*n2)iCdG 7'>Eq3`|. gP>w;8C8_bX]8R4HC$J:w?LaOP4m5/?-:z@[03leO[CԶ77tlmϦgq|੪䧡>;^ ZOr;>Xa_,șFG%7Ѣo%'pZ}LbFV:"s1MlT'[\_Og"~29%~Z9q8A!O"XT(Xpx M鏴azT$񗜕N7Ap+,$m׺ukk"2pPa)[yfpp)Q*.!v>;If *&D)qZ DZԔ8!4L֧89)qC h詥%;bzNjJ)%;bzNjJzjCɎ=d}CɎ=Z:P#礦q)a:YP#礦q)89)qC hN֧89)qC h詥%;bzNjJ)%;bzNjJzjCɎ=d}CɎ=Z:P#礦q)a:YP#礦q)89)qC hN֧89)qC h詥%;bzNjJ)%;bzNjJzjCɎ=d}CɎ=Z:P#礦q)aD'>X.ѡwsaUpI۽rxEj"JҐħVc1`=3w99MlcG?pqq;  _lx!aG%~e߶lךa?eQBяO"3f,$n??a<'ң [$x "u˯؝)^}>Or=G30N4}~ 7rB4GοF?#{E׍/wd?صvEZ>}Q.]LWş~qq_F0/I7Mt;Qo?]Ϳ?*9? IMt9'́ZzNOz1I4闿<~wЂ9s粻ٰ~-wS]`ob*D{cj8N|bbU(iK ha1sw e??t%G4t'sM8Ɵ?Ȃ??l9͠"Ks"ҹӿg ǧd!|T@\t,i \ 71F m]a {oj+vtfXϰF1V-esBzj!53N?v7433iw/guh/ ?Lb3~fey?r O~T*yt+m)=Y}4Geb՗ th7?eOנA4Opp|~ZL<g'y߄O]'MS`كO֬iW}ƕ?WE֬\+#'>hq3hNP1=|L/>! $}I 1TzTE I #H"g)У*OHl@9CL1U|BHdbt5@"G$rb*] ="$$3SjQ'$Dx !JWC>! $}I 1TzTE I #H"g)У*OHl@9CL1U|BHdbt5@"G$rb*] ="$$3SjQ'$Dx !JWC>! $}I 1TzTE I #H"g)У*OHl@9CL1U|BHdbt5@"G$rb*] ="$Wޥc&vj ;fBš!/ }_'pzCr5oF?齮Q~Oi-Խg/ڷo/=5Q2k>}i*#TƛLJeߪu񦛩CNڟњV~V?v ,no^֓!S60d?]weTǟ?'^OH"%wPq˯ˮ g9x/>\wGca1WR=RG4 gZg4?&tɟɟx]#`܉L;\5k/Lӿ6+uc 3AtQmH֓_+#W?Fl5g]ИEcMe+/DxQwĬ4[r韄gѿee% &_FE-^c! E4x B7o.-;Glz3kV. |.ǣ+FrV''i)1.0hQ}ԚH}^3?Bh֚`xp _ӿMNCQXkfysaйjdcabbwf3ߕ3/O#eq s#?E8}wփnmxN7|MIHӓm/Rs 7 }v(S|eKXs?V:r Z%Ԫu+oW g}{Ϥ= >#s<%iM!߽.ԩKOi#`ow,;DoU+/>K%%8F8mf,NjpX C6in+蝷O(YyQhǩy|7?rF俲F!!M53Mckg?6cNh1uZzֿQ̸ec_fy?j_޿x(]&"'r3/?mu.UDdU3N/W bbg_'3kW,&~H~)*_!J qW[8äpxh1L a[;G6`v*QϨ0)=\n8Vci(zA B#x֎M XZ^P¤pxd?/0)=\n8h;dNp=lO>gQ^FK⼩àW r=k?tE4Scџqss 5fD'>qdǧSh``aݷtF^vڝ$y RM˟htT:uϱ1/2RG(=ǧ}{oe$gg3Ot[iA~qtvDmqmptkΧ!y@N۴mKd}r[%''K[v5Mo*?L4_ӿM5;XAʯ +G?fДNxcO|66N5=%43'f97d٪7-ēw|s"m ]b]O4ݳ&{ҏf/acs/ e,%9Q8Y6 ˙!dXkd&nJ$cqM65{rS. ~ߊN@>?_]zpa,|) i2GDu奈SIӿtW(̵oۮUUUOplg̼z9Q ߪ֭͛[SYY>/hׁ*++\x٫w?~#N|ħu5>*WPO]?mwߤ/-kPiNAm.**qN8_Œql/hOЦ#Ks'VnO;S NzGOp,qzVN\:tP,^]>dr&5oN-scyG*N83mAv}IFWNBð7K㊧ ϝMׯ8e X=SM'[͚m?/˘닺_1Q@zV3՚gcRsƟ?*M?nְ:3_lc3k['>vNa?fc?fiOY)N|>oJ/sxd\S!/L%-: L)Jւx FMF&Mܓ b2g'T EBӿ2?yFJI lכv ?ˉO ¬`~#:C:i P&C!.'KEjp6CCܐ N;>;#0~8=A{E׍H#>Y9t;wl_|ƙP=hoh/F94cwG^1'&hE\B\zhQfim%~oGqœ'+Uӏ>={vS 'c'lBlaGko&hFԧo?2FyZ>k}Ss8iq#x//?2ɿu㩰<:Дra'BVh?񟏓ޏV~Iⴧp~rnyq?xmao7à䱐rW8?L2joLm5/? mʊ?l.I5C:v|gcMn71?ɿ?sl?Z2JR[ɟ$pLZWaAf.7'9s=;0Yg&k܅XZ*D-,٩waxE(K{=BlE|vj]}b1b ,S5P,S[dqw_bj 'd0"˥Tc(8Yg&k܅X.-C!">;5Y. ri1 N٩waxE(KP-pNMָ û/@\ZL5BlE|vj]}b1b ,S5P,S[dqw_bj 'd0"˥Tc(8Yg&k܅X.-C!">;5Y. ri1 N٩waxE(KP-pNMָ û/@\R`K DƊ DJ$ZP@؞q6 c,k;n{1}=7S+Fɇn-3wiRF5;s(Q""-ңg?GD`WsfOa&Fc'Yuܕùȑ#a::\uU}u=zZlh.zڵԹKw8DƂf*qm##:-HqOjӳ8+rW_oᜆo>Pc MS^} bO_K]p!Nvw3W+/[*A5[՛?'{Jt|u= j;8Eg>8#}MTF\L>ԓS9⫆A&عK;vQn]G'^mw}Z4ogsN]W>4}L}'? @NB]ݺvOmwߎ>},?oΫ2.% T@3c)v[K]!<pTj?' \rGXۯwklw+N3kͿfsl?֢IMjf/ز2o[֟ʁho[Y}[Kj2[ֿē4s_V] 7q+Ɩ?m^/5'>%?]zAŮ|IcGqD=Q3"GD:!=S2]F,XQK %\)?'hcǯl 4KLL&d"l1 ,q|œ>؈>1S3yp .L$mF8xMVACQ-K.s!rvc蔓ی~_F8董8%hm޴tJന~5}gV8>uԑoJ/?3f~H=x_XXD&]Ї/)v6k5|N";wvԷOdҷn%x=vQt9Ni(Oz'>B?|ħEh!M<'P5&6k8hk'%w.5VS玝D8$$pP)--!C.+G{LOaLF#Gk/,;Hqj 4TEÆ KqR8<>f R8Sq_su7Z5ܼt:tgB5t Jh_g@ҿIS_YOrUҦ 3uL7]ׯޘ+Ng|bղUka8}=HrT-/5k ւ-Nܩ3N>Y.s}J>hF/oL!w\>trSio~-N$㊗-'D}EUreߚa\+Ls 7 (NN'~ G<6}5}Gwn?` ?ŽWz]ԾcUO7fhd8)rp[~r3pJ~ ?v2g8Sm_MTxo7 rqo?L1kOWDc?0?㵿۴˧fy"1D??}&gg㯎L0kxG/xPWs&'65Y,(ѳHÀ1# ނW䜚(&!8\y(?@03^+ %L01Q$? "032]i(a?m'E{{"CuUhD>O)J?dY>eg)<`AϘlx Z$͹@[_п슑8iJ/T<}vyR@Ӯ] Z4ϓ~ӿOt37O8%JCcJZ÷:Эrssi_~Eߦm"|ݽg=zwѝf~VpㄜR88° OiL- '|UԼy>g^p&_7n< 7ܷO ;K*/?7\ѯI˟rS5!ї.@O>>Y]Ls#CAƛfR}'>=]ppfXC0yG;pC9N[lli?l&&MiƟ69w`C}ٹвe+Ol%$mAFPοFQ*kP@IDATdɟɟר?[ߋP6 `guM ։I{s@b']^ʲ[TN+X _WS|$|KO i8]Na(~ /_,' iC{$|/4Tš =tqe`ˉB*b 82s|8!#c ĹeH?|YyC+s`Q!C ,Ov9^ˮs%qc_|o!-]E̘ث}B(%4TDX[onq(HEĵti$y;gܹy$${̙33{9ycҖ[ncW+hǮNo~r4KVLzߑwFܱڙ8뿙aA,tei˰3օ| 5 !9,l_fKO?X3E?o\^{g?{_g~푖r7w(aG5.m ĮPpr4g̛ͣOW^b/YveF,R,D,v[ `WW{ێHmZ,[.\5'S(o^f=p_z[춄iø[,|}]f̰|-JGFN< &aaSXP7_ [iirՕ Elob6caX Xim-'O_^?ӱw+<Ŋ˓)'~kַH7|[Ǟiw[H uW^ S+'Oowi_?0Q4PjW/ٟnhZ?-m%߫KH=GlE=mY#←cyTgU1) ~e? j*t?{j[G{CDj " 03i2iCBdNII&B}i;:6@9&IAYVv" _;FXP.v")<B'h $]|| sNN4}-5 @(?C-<(ZnpcaT^T؊A^ioM/a7!‰m(d[ɓ'kLJ묳ل lBq#ϣ[ױǧM6 ;I_rM6uq… 3Xd7/ Ю&΅3o8^a'oc&+362a*.kX|k'?7fGviWf8]tt?,,|J$tm ||93ǎO|,b*"jҥ ꋅiNGywy< x(c}ӜXvY8CspO§맹Xe,|*.z@ } /7ps!^u?wR:}ڂ0wzO; |v\H8wYyi!Y Lnӛ6߯\{%vz5ypfO81}vnŮN`sBk,8Uꎦ7;avj@RͰ(,Nc 5f6.|%]sy8O3nt/y_LPҰ~oŇG.!W?ݿNNrʊ_{!Tnʁ~^K˺_g0A=G_μ,DHƆN'm??ȅЭT(3W`h[a/4hiiIPtH_?1&B/7W[5k&,>nAW8,\OOuhэS[>XYv|*e!<.*q%ӟou#n(" φBpP6Mz~O#BPkNHHR9𦁺| 6elU#e M=D^=L?}3fXďG#.Vp ù$ga{3i;e/}҃&̡~ݞl's!w K^R5aM~GٍυO]tَOX#Sջ}OtͰ$/.pAN*T ;>6m؉w-BwbO>Bwi 6@nϿӇ=?}i _yoBy`ЋǗ ՌCOw vYEVԋpOͰH ]}E 0pqͼ˭?qƮ\uaׁ:S)t%zw9!ȿſf86`ߑYw]7o_Zz 7scցO ˗^ąiCi.:v8=[-bC7{}~e׏oa{~^ɋ~,TkֽNlZGh|5v9lmOCK/X3?)7`RY*GolI:h8-[$]}ei n?dcַ?xutS?um=gߌaw ksU运ݿW9!/ra?W6vxe_QcUhkie҅ou>;?h z#4d eh@Ui/};>5Oc}W,|*Cw󅶷SDB|6u.K%#R䏪o|[Ћ) "???F)TPWt󅴷SD??ODEuډo#qTcUp@thzV\h0X*M{o_Н>Uo]#Z#?~ǂi76pôp1\;> N|oZoho̟ivW-]dp{wrK݇?(v6v9 pf+Mr>m=+ҁU陹sO{淿-mݎ-*BG– '4Wܷt؛N؅y,FB,:> wޒv.L,|:Ԟ_O~c_"rcǧtwKz~ d_4,;(,|q ̛|9h̳Ŵg?fbJ׆?<ݼ.k?NXDĦ?IǍ5KӢ%?i)wH[luPe˖&.{~boz[o]:me# ?O? dL; q ]`4iӦ#}z󷰨)FEꩧH{C ԸcXǟ]l6:;> kv"w|"^ӱx=wY_~}z뮏K[øeo07G?c)\m&W ҥ__uWmR_q@UIF50@VY>//Wަ.b`R_`m>:\l?4hy$####UU?qB>= HF♦qdvZ];-Y?1mZ-§K)E0>\?ƛl>tʵWu0.}̏J7|4;vMo~+/aQ~a%Gw7iGf4}*,:ϽN{>/?I&~5t|ӷn5"X0nO4nh\[wjesQnؑk\p/!bw) ']O^iX.,|| 8{f#-ӂE\牣<Oa3/~3N8 |n^^Em 'k_Zt=W.^DWCrxfmOgן+0^ێ8 3+.,/( )Fna%g86v~j/yxŖƭ7O5Ma`X|v9F|.9Oa!Uiۮ\kJsQ^E`\XY﮻Vk5%p)i܄ue_6=hkgC+MnO7'/8qR:͇֮:>燾kfeg+럼iG3 /o??hi/Rߚ4hiWBġo?*#/5q5IkxÔ9T*bo M+zOєhSOGby~Ѣxܜu+~i(LY}.|(RG1gk;A*t/ꈶ"k\VcHVڨ*Wh+Ҫ6U`E>60ڊjrX "Zi\VcHVڨ*Wh+Ҫ6U`E>60ڊjrX "Zi\VcHVڨ*Wh+Ҫ6U`E>60ڊjrX "Zi\VcHVڨ*Wh+Ҫ6U`E>60ڊjrX "Zi\VcHVڨ*Wh+Ҫ6U`E>60ڊjrX "Zi\VcHVڨ*Wh+Ҫ@q'۝ ޔW(Zg0lż^@6_`0\9]ݞ^lgyɉ'֝^Z]Z.:Kv?0¢öeeǧf >O~ 8+\Qԏ&M}tUce~3{і[mb7vkVz4~O_1Jܭ焓g/<ݫFZDZ䝥&ԏN3?X [pDW&=#ihð)v|~p[ں/qA)wi&vn:v|"+yio<};>͝Ec]cOh/<}C5&OOK.I||4| ?k׶]/GM~>W?[o9s__o2 .3oפS>aZ]r!}ӆґc wvob߂^b{iw)[nĎOwZ;Af>MߊFpr ioy=)͚J۸ |qvi\\6gS&o'T pSu3>I؎OؕAgII| M$_ v8{gc'-E݋zďk)-Oٟ?c.h cSUeM8^J/W?MG_K O?=Y1a\DK!-Hϗo]hK# _{o,n+$E/| VU}PVj(4W2SAY@Q w=>}P?8`|SH$1TLiH7!3)탲* X0J_{5S%/s X5`۷5?6xok&pW)۳D_aLN/_/vsI\Tv;][tidimxgwxѥQ,8:%أ?ÎOXtiM7MO?='}Z=Nqg?8K^W_ }v̙!:7tؽ;tA뼾 |aǧcA{X?'E4C~2KX2ϟ`vkZtʝ>n nOwrS.yיh:Y=Xa'< ͋PzaoI;bAΒ%M_V 7OZ[Dۤ({4?CZgkJo=ic<;bywđG-ڼyor3F҃J}v:z:MY{J:ق&\hs-6oH`Qv\q!;ⲋf^fvo<8ݱwi\dpD2˸ [0~|:LYsMm5n8^?R߆;5% vV }nCKhoԜ}zzo:mv|zDžOs?;Yq<ӗ]zAZ8ksXqrcqֆߍߧ?%fmN0!SZx!8=ռ 8ЦiMQA)+;X0cw,[2Td%*3deuԣ^ _|7 41[pʡU^Xȳ>`Aɨ-|[oOG)4´kNLaGO:sv|.1qpǧ7,§k |ϸC;s>4;䖬OL6w|}׼f i Lȋ]RJuWgje´y,§?O§;o%qm§>Ԟ?wZbi۵\x ;;>>/𝺬'oO<]-{f N~_Zg?ky/NG\,wydXRF k[hvmG{c;cS+W_i^^g,x=cy ? ߼̷v=zSÎ=Gbպ@{##{J?ґCh 3BדYk8 .Y桝?`vZoN;[ac1҅YˏtǭXtm?cAKGqO,]xw|?7]N.my: u o1GZ|0=vB~Qpq+믿Ze{Xd2wSaK/~xP|֚~g|S[D 6JoɦӰ22,=u_f}5W]͝go >e`ǧ ;>qH| SA؛k eBK2̆u\s%?;=='(=J.~aq݉;ő1vHg-!5 6ϖW/K8^5\HR8&Vl,oWBmWn?+!C/kʒ #MO?N?3#ȼf݇;[-+|bS>+AAC?p2'v) RtOAP:`pXL)'e@7'O?IaH'yPMG_b4QwF,BO2JGyTUW_VݦH@2PYgş?R'җ} f4ndTb rt| }P"ҁ2/jt5}X";SY?;>f3 nstŀ󗈬$Ɵ-2{0*fHӼNkX'gmoK<~8r0@^dMۏ8:1i<Y,gf`s&HIk ׿ybʖ_d,S79 C_) 6=QKmlFw}la rY!C_y,޿1^Ϳe?Au+g_g9cgNR>^lS+{7:BijVzM:ՙh"pƘ6&+&Rv`GÙƸ ^eLKq*089T}m }6D%;e;- ζ2uzPd@#D;Z2RK40P*ڐU0-V).LVm^iT+[0'g49ʫRqKps?B~,,2AEMyZ Qy-gӎ?p!c/ȐqI`++5P,| dᒢW/ٟPM`v-s5݈h C)CD j YWLvH-[o+ |IşR-dş`S!SM7 nE;^70g2\%¶P]a 躔DP͢x_`'M-֮N^@[b`RKKZt I"a0韖TҒeBD?H FI\q 0G/Oǯ.3.|g]bjA`,JaV9 Cyl3JԿ9 iIp44:ZF5he8Î!KoΕkl?F_>GP.hlQ?ΚANIlQߊ?(/(D@7UYgşVhOgh*VgY[cJ<::Bmg} ^(mg6-B1+L[ HKP2{ @7+Z!s>HLLFZكd!XԪ ɟAg`2$ V}fxH?d nV3c5;xc"&,+T̎ThkȌ}x%;fC _CϔCs!kPqfHR\ (Acg#0%F_?e퓣l6DBaBÁ@u0+ao?e-Jԣ` aj _%KO , -V+M;S51%K_gݗg/G4EB<#q1(=fm2P!%PƨƟo1L+4ҙp4K C/aL[xkS!EnsXWb F0䟈a5e@ܿifɟ_?ҿ4X``3T', .`o50ΙAB.C+O )ˍ.ٟi?6n! ҍ&b4 X0VדU7?& =ұ$OH!Y! h$hzժ_?_砅OaVqn'8cԇ[D-M]}uDr4/2euxC/kI* ~eϤGOpXARhAoV$+ѣgX B1#) O0( anN:%>4ؿ)YQj!˕zO?Pk<]Y yRwc'Ϳ-AW_*|G(p^m/,6aɧVB%?D"KIٟ 5dgL))H>e*![oW _wky>}F.X5::-bڨ d^őT`жQ9H^ővs*mr.qI #lUZAF\ # zAG)٪ʹ@F%(SUims4KQi8g 6*i 8NqVmT2 .Dq✭J+0hۨ dA\R/H;9[V`жQ9H^ővs*mr.qI #lUZAF\ # zAG)٪ʹ@F%(SUims4KQi8g 6*i 8NqVmT2 .Dq✭J+0hۨ dA\R/H;9[V`жQ9H^ővs*mr.qI #lUZAF\ # zAG)٪ʹ@F%(SUims4KQi8g 6*i 8NqVcǧD,CzCXğ3`0 YnvX;bG= RO K]{Ϳd/i)[/sЁC 3QI7P⯊*⯊?;mzzzOzOz1dW'퟾)}.;>JKv*sҨ0wi|ށd0aoI @>묓 &-b|;`ޒ.(H;}Y'L[4iav%]L/PvN2i Һ$ {K&_"Ygd0aoI @uIt1M@D:`ޒ.(H; &-b|gu%]L/Pv`'L[4i:$ {K&_";N2i NuIt1M@DZw؁d0aoI @>묓 &-b|;`ޒ.(H;}Y'L[4iav%]L/PvN2i |4$8SsVbPXb(0:Jc_5a3ɟƟOFKM?J6}1H_d6o)ݼ-CY T~D?b#m+2L=(Oٟm߲eC5'?guz_z_zRӏ?ɢz AƠҐ-[7 ?|^ϴ6?;WQ-)W*3h)׎\u \J (28-QhE4s)5*1Y)CA5Chv\J (@?x"ˬcS!ܪ5|dKRvzʨ96B+j}p(S?DcKHmX'#˩%jWG5 dAQ@O̦o)A/U=CJ@PL~PA9ؐȼP! ClA!SƐ%SoЏɄfڰ߳sr%⟜FS@ aִiMsZsGu_֟"5Ї%?(\AB]J"h{l̰5j1V;}L#C'w&č90xŸeޚ ^dN>1C6UFUcƟҿ4řO?AG)[z9RT@.+_cEGT<QUg_3 `/*s!RM߿}dQ6 1͟Ɖ\i~#-APmU\2hei! h)@O.(H iDhL}rAFZH @d & 7BZ%S6q\PF (6*.2AAVqM'o4 Km>:]@IDAT~#-APmU\2hei! h)@O.(H iDhL}rAFZH @d§p;v'" r4AZP/w3|a%MK c6l- aQɟƟogl7l,)!m)3d`d9d^wm!CΕP2_jS40ٟ?!?QQJ\x[?e)S''|̗z*mfZ0LOfTRW,ƖOٟ?e! s_Yw2_§`SnIj]ܴeN6?#Ω:$k^` ,H=6nVI'},tv뭬Ss/rpץa?L ռ6FƉ?INcviEw 붾Cu~HrNGvpNCXYN1DC8؂*/S2iIizRW_L/fOl{-G_?+BΙ?)# DVUg8zcvAN J7qDŽou#7$C7SM7(C|NPI'Y$$ [DWN5ݠŒ1h1zRVV뮿9]tٕ;&L.?stTV'zVNv_Ofkv1h1芮junek ]W|*`pǿfL[naE]?ɟd YWʽ\epaC-%I=͝`NB(7Gn8VM 'ު-P_!1b/55T)fPD5:d ۴c4 \d_;(O)zQW_J9ZLQUWş[?kc `SY7?(skWsV2jt4AHCmP-5 At4)]wˮ?&N.ւSFp6'z& N)>mֹm5-dKUÅ^|Bڠ&[kT xi +\ZЇy5R˧i*t-ߧrᦥt4Aqݫ|Q54.f0SFpR@^|ܲ|ըn8.&h.,߇y5N˧ Z-a^ᆓyiVr}W0c&n3xseQ d7h L1Py:$ 8gǹSxI) 1#WHhLAeLݐr1% 0^Zh%K'ljr'C??m%w()?̏[A)d)<ROY"CO?)63t&E)DW"0x'͡XԠ9oՕj 7એ#ޏ5^\\teנd >k 6 H4~?v|'LMS֦i窦Vc.e~ԿhV[8Bf"v! wEFF, AxEY^s\H$UKrs5s=v|l_W_xoK Oc+(50 *OQ\XyUQtɟƟիΌ۵3d/ٟɹ@7,PQ^쌓?)⯊*0 ?_XR7ΪT]Pk}_J_G@G_^gaǧr.ei |:MѰ[RF$LsCo*Mѿ뮿 ;>]~ity?k'FF|4nܸ_ tY ;>qO`´F 7Jӏ~hՖ룎}wu)߿ϥDw=iBǫ+cT9 xQ;:H3u(Z'I_nՖO76n;>\f4)oHZ2prLYUZ=Nu܀7cut2/H4 Y}XXIGW_9/;U !ӌԑb)S_? @⟊.PA/&tYr̅Y-MBZ67RI'Lj(SO?$'>}Q_,|2'눔Vf<'V]KZ7]t=M3^O\vm7aB)WpnIW^X\zI阣OGʜ 7t]&6MiiM6.N"u['Wg.|EFPo#VEG\TkzmoGݒ?Qs>p Oۘ `tk. .9z.:R@P9鵁jjUJqyOs @5*TTkzmvREG\*56PMmpJ)#i}.U^6]wё>*qM TSܮR{ZKA带 nW)]t=ϥ r\k.:R@P9鵁jjUJqyOs @5*TT^m'R} $g ݒQgiOMڵʶ_B&o](B4ښD5Ϳ?d'&_?%PA#VE_>/B5-ISQWC⏊?*ϴh[͊*ښyx?§X") 5fh& ˣ^ b L3uoޜ.\2MH]%t/*4A:x+ wQwT'},=j>ȌѴ:릿KkLX.Ta1V~[Oa$`_E?0 iM_'1Wc4lpUM~:`CKg Ѐ0?LS9Rr(?aaFιɍ`&So%?ҿI4<M3xd% O?L9bCo8&OpRMG UUW_7ş>T=3A &}N?+?׿^f?xeolyZ.pg HsPoUKy2ʓCR#Vn"p0a||,|~L_)k޸>X 51}[ғOEJSONsg\mxé<7Z;Տ;įVz9[O8.`Ս7ޖ񭛁G%?(mݿ?U>ޓԈ'g+X{=$5B˰AH%2K@j/>cf37iqU' }#b=4- 'L[[:SLeQoxnꟼ!/?yXhAC5T_?eCѠ:)۔y_ğ%(o6!n&şSQGi0⏊BTb#dY}0C'A7JeBGPUWVuw35' |27k6oB^v\5xy364ZjR/ \zgu]s+qw_L? %iGi^c,]>Isq$m&/wwGo'ӌ;xH.:䉓Ҝٟ С6,KnIӓOH9 (PzI]Nxip2OouQ.1 c:Р;&0~1'F~aF (40p/<`˅12W/ٟ;Ce)[_h/?&E`gPşV_WF]m̩.c)"-zÊ?ӹP#BGTQG?"㯳go _Z~4N@§Xͦ&he Mo>|vRu15 DR2"篻;>]҄|vG-_0-SNLƚkf?sA6wqtN=+wo/v{[u7s_)oja6iehkӉ~Wz{0ɞ2O3ޣ8*MD9m'Zb{OYBY$-xOghëw*V4L٠/ģ 7}jʥ .2oy|6ydu^,_[a{h 6&AEP??Wv!G/lDм!r@Ã2SNRβe]V*՘kK#'6Xd%Klo:9_Tf7ƊM!NeIn%S72-r +[6[̡eT@EGP/_* eȁI%l-׏72F{؟==@ʎOeDMOv;5U JrICW[tզ&.s3>v6[[Yiu7(0fw?z++'/hb'?`/-qPRb>{o4e(oZllEԔ5P)̀WqbB`P8"UҦJaB;lʌV4lC4R!444z3fN٬[v?6pLssVmxY`kgA;9/ mA"'j B˂F (KHpR[4S>4Ra ed̪?d⬐O?FSuL ]A}CS-A[/4^/( }H;?"^42lRI7/|xʼO?-'=H aBfSMX/B ,B.Pn~ aﭗPg,| C洲iZkyU?wo9Գr4vU=bt%/9?=f6(Mt0zuo+ +eEj@',o= Ro:>hrh'?P/_Fsp ag0p2J]/S,(#??ʁ VJjx_CE"'ڇO?AN6WPAş ⟊)9RW_@ )V̎6E|}SYIa⯊fׇfkE1uS>qBDRAGՋu"k)ODQf p߸>]rWxi ?o_ }cJg6[f޼t'~{rsܓSN{A[j)DZtѝӛ=uOn-}C}?=?~Ӿi=U9X!X!߄I[iIWO嵿^rp=eU7 !emt%4ַB!ir 3$|+H4O7ͿPEON)tiDN?(;1(+M'#qRM7UYgڐ:f̑&M?*ϊ+0;ƒVYgş.cusl_qo|ЦG*t/ꈶ"k\ǟH?|`_o]/^n{SNM?(eg|gS.e{OP̠Ps0= l'L_>vJ]O}wa?̯mݚE}use#\>T@AEVʹQU+VU+mT|l`iJU*"mEZFU F[VQU+VU+mT|l`iJU*"mEZFU F[VQU+VU+mT|l`iJU*"mEZFU F[VQU+VU+mT|l`iJU*"mEZFU F[VQU+VU+mT|l`iJU*"mEZ(9e+ e怑L+ENaP)@^W"HZu3+?ҿ1hFp _?! ![/_&A#xsM%+l _009?e.g "d K ӄo(N}S[x߲e\* '[2{ Bo߲ fϺΕ|Sevsa*,`/)>}PtH:崳QTJo{ˡ}'h4=7A:S_JtևO1:6=7sۤ _ESics~i?6N=g i7ɏzvK_M>ѳ+.\>k_wsVYN'N4:>݇P:`}ҙ뵋[,q!LEftO5e.냲W,*)3J _k^TA _?*oF:zM9X$Z+`$??@3"paURSft*,`J f'4FmhϹlyM_Qdfc.ՍU%>:bUgGVҿ|\@za6^o1!,]w)SF +y ݋h}p+RZɟo4c,K1_A;-XyYc=$Sb 5saZ25-%/R?Dç=Ɵ%9G8f!i4_dR#!m)4<Z赞+/n3dbي(Rc_Z*NjMşRI'jşRmIşh*(@7ߠNt[1N'732{ֽM-(ܸ,6%dsd8қ8Tp2EȦf8=l8Xqtҟgq ŒK.:7o ӷO=xR =ͬ*kP&@Y2,)ROº*S @]H j<)2BΥ6ɟOge4㭠 _PZjXwB~A9Z4 y3Va&bq#0xH kdYn@/@8ppLrcLӦҿ>^8j*0Ē sd_r:D_ ?`? _/eMmI9dor .DgfqCI FOD'UOח?e$Ü?2^'9bb"33¸!Ӥ#E'X"*CKٟ?exlsZaJ?u/vG3LeSN,T ihwjh)YjZi*Y!zh/wYz'yJ*ag=N?=y{ֹӕmzqhZgcL]:m,twfIF`ty D[-~5͝ Py[ߜ7t7&!h0=rɟ̎ ?5^zG']{3q#6lJ{θUߥL3X#ܣoM<ZWͭY_Q?$n?ҿ4f(???e%nG3+ӹO ?PE/TI7UYww@OIATAX"?ɭGJCԝ.'KfS9g#&>+k8":G}ܔ׹15\?ӟ=-Zj[4 Hg u?w޳駟]gʔk@=׋rO,N?5MZc"Jzt)\t$=GFk$m&i$1V?88Ҍlkgzjk +;U T g<5Lx ^kƗG6BjHsId#U`؞)wmF n|LaP_>=eЎ^ V)hjSD?>CGWbhVZ%SwQ ?VAşSOEW_UjPUgOhQUWş2-?ؗq[Y)u4pD\g^X-| Q͂ :Y#3\D_rQ,=eD'k קFI40jNIz:NOA?ﴛ/p WAAps šs? BkiʆNiHig^.7,U?A㋣FOͿ?81$K',F&2J_ ?+`c.(@ })ϊCB*9&Y͊?+ y0xTYgş *P9xm TQGTf oaSX6n3=ԭݪ}ȫ6gPXAsΨEpE83l[%!᙮B5,c_gJ9k5u4j]w D7\t-/8j Fσ$-& gY#`V)c x-/K0$lYO/ MGJj+d覣ώ-3fv0:!SecI/_o򿳽?(/pakMc+ogI$z@gPAl/)Khv|*f_H'|Ki ]%ܚ'}NQċL`}fu%RfĠWBcĉɟɂF )jIHZCi S/cL45^8oW#WgcNҿSPgfb{r0ň(aΨm,&f)nlKx:V?XGBapdp|p ! 3y|xWͬ# _?eXa%[oL?c O?Q!XY?xO Nş̷TI'߲^TQGmv⯊?5Aaux jaa[߫x%;!(9XɣUmfYM2oVBOqazt.URZƐɿ?Ƅ_QEAXrZj=ťS񿰂l{g%SLot_a&Kg4> ɍ?` E T˂A<6F èټ@}cήO2Ϙ%3Xo4(>`;\R5hrae)-7`2@Ep#1)?೒3|̐?X%QvH)SO?+`v?(`K))(ƄoqnT1?*cL vκv;L }$|<)b3. k[GbIӾ( :Ѕ*_#- Z*`q!5 d W8BJ47&>Uw郋lbuSL(Lo=7{@ b1=P5@k Qhyj%#C㏪ZOF5h!KoZ_?S'E)sŽƷTI'şr;:Lş%I95şRI'şy~_h++Dq _h| _QE#_9ٳ@Y2j+SiJVg@hvi>3<z[NtCUk& &#-AA2jg 3a0i Jf`P>3<$ɟ HKP2{ @7+Z!s>oλ#_ŃC"&,+թmq e1i:Կ/gʡ9Q5L8T? [). ?y3XCW/ٟeQw6"M0@:ݰEo 򿲖tigQ05/_%'G_lYÄ`VW_A+ZҕG%K׊ٳIo3LRţU"!IMP6 _gcTOGwi?L8A%!d0c-<굿)"9O,y1،|OD簚2 {J4 3O/_?e^M0_ŽB*C 0Elg y geR!P_ lFOߴd\7IhF _1o`,k+Iʎ⿊*zGMilD'$𐬐4P4=jU/ٟfs§087?` 1Ì-"fP>:o|9HU}2:!{ח$?2Igң'@8oKΠ@7+ALgm,QׄZ!\UQ膰?^'[?i?ҿ}_?Δ(5J~ѧOٟa5 Bd iUh1ߖhW/#OHdtXt6deCGM @ef0SV+hdBJYQ"%O EXgfq$Z-[+߯n<>#S,p1qTdmT2ҊA/H{_pYQϪ*.  PgX\ j$0jTDDc$/q}EQ5[ܒ<7TPf(.ϽwUuNl"U=3Gi'{9 j&y{T9KgNr@DMZs\@QH/9J#8V5ۣj͑^:sFpr&jG՚#t(d/ZM:o5GzQ^ȵ tUkҙ4k5Q=3Gi'{9 j&y{T9KgNr@DMZs\@QH/9J#8V5ۣj͑^:sFpr&jG՚#t(d/ZM:o5GzQ^ȵ tUkҙ4k5Q=3Gi'{9 j&y{T9KgNr@DMZs\@QH/9J#8V5ۣj͑^:sFpr&jG՚#t(d/ZM:nƧY /}~N9%jOȶ8*h5IH?Pq5DKq>_?&m]43`ƚt@PA _bǜjaW_eg/OOS$3lR_O?cSBo|0*P3Vo0CV/sl,G)CL䀗1sX&3RV/X&3RV/c檱Lf 1^Lf 1^Uc8JbZ= `c8JbZ= 2q2Ĵz@x2q2Ĵz@x93We2(ei28e2(eir0fdQ9epdQ9`\5Ɍ!r<6Ɍ!rj,G)CL䀗yl,G)CL䀗1sX&3RV/X&3RV/c檱Lf 1^Lf 1^Uc8JbZ= &o|MnCqN*"=s֫>*ĸQ,9Kd˦)jڡ)폛F->Bж(/_0 ?]Js3` =a670Ct~$Zg/d~`Oɉ>Hz7oby ://rӨGƟmH7o03FpUϿOJ;\o.o|Û9~ j)MZ{g@C C635/gxQKlCOt'Y}@;Z ΓO>LU#K]%tguZjYy7t:&ǧEu,G!@K<#'P9hhԹ?\ AK __?$0fQ">zP`?@5P 5`As:%,vBt0J`IGsf?1dGB[6{./1YBԬ)PwkzcP5dJq}so9en!cp|ʟG#H1opp_>ڄo/_:?jG ü{4.p3=4|y9v!ho|'Ͳi:%TxZNJ;tjO+leЊrTppN'ՙ2!=Б@<> 聎z15q VgDt39e:C z#G%yL9}\/9*cjzQ gSsN`u@@GJ=s^3:rTԜ2X!=Б@<> 聎z15q VgDt39e:C z#G%yL9}\/9*cjzQ gSsN`u@@GJ=s^3:rTԜ2X!=Б@<> 聎z15q VgDt39e:C z#G%yL9}\/9*cjzQ gSsN`u@@G <8Bho$1,xmzAԤ^fJS7C J*HjXK9>O+MiFe/f,V@ 1I?<`s)r*I:V?!vjBS d[-F7|÷}z*Frp3`a2lExx.>knC-mKItS4fAX4?0q6`p߾ E7Y*$'?kw/N*Q9ѫϘi ɉ󯭮t:O?iVX1964ɯN3/!|].N 8rՉV`_IPIMdP)I_?XW_fq/Y@TQPJ=1fAeE-O̿!a#󏰌?O?)62Cĕ 0HREb5BÔ̿``IWN柘bI^̠BJ==t jI9zڟ+$:S{4 @r㫯Jf QO^dxZ!11'P\Q$V!$SҁjtA%Ϧmw/ %5ey}1%aD/liDZlW6#O?4 zG39@#8@tT fpApAĀs󮤢Va4 ES 3~80b OZ3d -ƛ2k_`[/_0d[2 -@@&%m~e=w)72|Q}m`!"a!AU/mi_Vcvd 7bu;޸j`̨ CF]1O0uq+ԪQb`" mNZ5Qb`EZ5%2 j]@IDATuVCB- #&NH?0T ?0`3D Ɵ?ؚ̿ `#O̿20;2N?1O?Ӳ% YƧp`FZَSKT ZMƒi^ZӾM](ՌP< 6yiMB{:@V'4/i_3S?i@0Oƒi^ZӾf8pq7O4-Vܕ¯J!_Rb^e h WgZ~fJ?O,/b IG3br35柘=DnG_qAG=Ih?3柙fg׼] ?1 2 4/?1&5O?meKOqw0l| d=MN){TƎ())3]<S*N8RUͩ?aB EI{__u)TpA.FT7nyƧƟ3fj+5DykA^>2sKOSqKƁGl/?UoΧ'o'`Uc2 es'O?0Sed20 /̿*>^ߘc7}M)9O?1l82/dUyR}iI3eik Z0]0D{|nm8Kdn$E^dAne>Gpmen&Ane>Gpmen&Ane>Gpmen&Ane>Gpmen&Ane>Gpmen&Ane>Gpmen&Ane>Gpmen&Ane>Gpmen&Ane>Gpmen&Ane>Gpmen&Ane>Gpmen&Ane>Gpmen&Ane>Gpmen&Ane>Gpmen&Ane>Gpmen&Ane>Gpmen&Ane>Gpmen&Ane>Gp>IvM!! Z 餾' ʹpѷ2.y= )u#YJT$2OOߌ?1-Hiޯ!?ja'柘5҃lDRe+FI1/?O=Ĝ̿0 /?ScG_8O%g<7`kzH@(f"Gjm`:'2j];` ;J2N%(ʃ2FR̫\5C8Ω BωF#Py|l-tCT>3iՍO@h}l:5]&݈/P^/{jx6CH0##?ˋ`h)_AS8U@Ե돮\eA 'Oߌ?1d/?1#?3_3?3?-r_M(q_ˮ>Q Y̘d`NPzndG2q n@1eSQ$y #6ψǷ%#^ߧv@ƚr!@^'|}T0MI!UIы|B{Q݂%OSdp53BC++cˮ.\͗A'o?5B._?cV0 O̿1ks5̿3;x~/?d]@ogxyqK#@nDD8P/|FL,=#9!:8,99%aL8o Zg@7=qKP+ qA39P8KFpP8MO%Jdz8wB(huqPLԿ'yjQ2=;!:86%chM/LD92W_7AINjڙauҡ&M iO/ʸPdpPBm'_?a-?298&a7_?Yd/?1o , ogM7e@F ?C̿ۼPw3 k-ag>ek%Guْ~ \{!/uWK;jONCغ#ki-ǧ:|洉ئ^sGf^ؑ9883/uGֲ/xBQDr[wd-" } zֿy{?y֟Huk7r 75H$ʝA gAP)_ v@fhhm9"5?\EK]3QB]:!`K+j;1a`CVjD2`=wMU?uO.H%?,X1`0QL[2QcAxSWK;5MrTuܹ{'~ )O!(oiec?<{X E3FkАO)#䄠)pJ3e"OC&?^#BLڟ٠+JbVĵc<4/Dp:޸ҎJUDBrU~i|)Ob@L׽?le,DguLq/[t/1_lX:?>0Ă!R`7oߌ[T*Tx˂f)<ʆ; 1fATTJԙa_00b+(/?1O?\ԼV m|ʌAzF1aÒU аa}".=)ǧp6GQ(& L($hhD`%bDC1؟y g|s?ګ -W!jfjZJ3MO+g]+pDWOC-?bsad]SRpfM0b?0'M`Ah]|`柘_8bеBߘc7W̿1(k]]1e#S̘s tAˍW 45Tig CAM_X?L4 L8qrC7̣F3?D/bšy{=RWQ|9kƟ|_S/h_: F)V"R )?H_@'oF0U0bij〩_tN茀d75["s%k\0-'ߘ/(GD0 7G_E|`fWfy?c@CqxUK%1W@7>9wm z_^^zT%0 LTK`b}yzQ>72ңR-}neGZ@KJ&ޗj Ls//S/=*z_^^zT%0 LTK`b}yzQ>72ңR-}neGZ@KJ&ޗj Ls//S/=*z_^^zT%0 LTK`b}yzQ>72ңR-}neGZ@KJ&ޗGOv2Rh"~q!1W"Nx~P&PLS$r \hѬcihZYWbIMF`'oߌF]IcVUFߌ#b[aS 7oߌ4 T3f7o߲ 2VaxbK `i䟖-ԕnJX @)7 n3x`(> T)3?bmvpJ`tƠ1hDP??mFJ KƠD 0j ~h?%ߦ+ٸ)Vzp͵tm!6ǧ6;|Dr[l" KI./U&"T ˉWhfP;IV7PW?T B3`(g 0Q07̿T_E̿0UHA$ /̿T SN _a+eL (T.w5^֙ O3 OYUޅ@:eb#&S?g1|^l-3GكS^5-3Gw}E_2#Q~IQS=k`OV&Eӿi$:!ʟG(G&ˇ_`V#,(fA3`.O`?_7_b|\k~7ߘc-&d.̓fwXXn_-CA< TZ4`TVq}@j3C%n,C$V3C%??2KB%pY2Z 1y{/?*#"97z!\R+<#lB~$|4T_O8!ȐAD05`ZS9`\$RQJk/kV{b0_6/__qu-_#nV _?u:'o?`՘S ?m0OƟS0Ŗ#KI' /":0N_aHE_.Tdj~÷3VAQߒZ8%.#Mj?όيd1Ԓ 0!\]c}tnJδHae2WqOKd_.˨]')hcZOS8hV?/ E7_uA`;`E3I9O̿13W4 柙k???>bq#%ߎ쑦<6.o|lT*Gy1rNwhGwJup|UGB#.W/+ѫ^P#Q8:+#%î1W >ڟytV%WFK&] Cڟy{+iя1$aT/ F=If?&N`?tp q1 ?Lsi -_ ?g0b_b1I_e1W_ewe-;OooeF/U)fg$t6Ȉ #:+"@ )n !B*OCa^U`6@ JqcEv(FhĠ7Q???w_۞{'ʑX!!^Wò@\M n B,XUcc%JzcXzSx GCk\@'oXkf N5PE/?aP+7uoI1(  P0"8x0?T̿0ɠ?ؽ|_0A2ZI916'_ňY y9Bo=l:=ar  ي! VcPއ¦>R94(aP돻Pnir]w|yG! ׊zʝ,f%LbttQ€'p/OSdJ-?6_rk:bO3 YΦK?0`ZN?2oߌ3fAJq4D81#Ɵf Aq2@rș?06OHb/ԓ9J0'9>OVL1Y}H?Q*UChU?ՍO/د|=)˺ҫcȍiAEb78fS3ʋS38 ?_*mӖQ?O?0J6d]`WQG-03?[;? 65?mlߙgwߙ7Q?3&^2dԚ6Bp<(nKyeeL0;FOƱbPwtPl PמF[ǴCϝ4n +M\TTG:Eb1ڣgrXk_\_I9q*//4xlv6gթQg'"ރ蠯hWJ;wF4>5F&b_?mG(S?_}>hLIցFĬ|ZC[z?Rfh]nBS8()PtCB[c*řj7?Q?aKD `'&]9E7* ?&tQ5񗯛j1Ph(I2vfՒlluI>Ck p&pv*_?7es'w6ߧfd X1c5 l!6Gv#3C7 #cE VRc=?2?OQ%u/!V;IH2{t7_K5nV_PrF3beQTuY;_ƧhQiFت]pcdi|^&d/CJG՚#t(d/ZM:o5GzQ^ȵ tUkҙ4k5Q=3Gi'{9 j&y{T9KgNr@DMZs\@QH/9J#8V5ۣj͑^:sFpr&jG՚#t(d/ZM:o5GzQ^ȵ tUkҙ4k5Q=3Gi'{9 j&y{T9KgNr@DMZs\@QH/9J#8V5ۣj͑^:sFpr&jG՚#t(d/ZM:o5GzQ^ȵ tUkҙ4k5Q=3Gi'{9 j&y{T9KgNr@DMZs\@MA/SE^:I1h7%s O_ kO68*h5IGI?Pq5Sf@LC/|z.0b[ cM: t /?1cN0+̿2̿W'')G_6/'})!|7>K7D!o䀗6Ɍ!rj,G)CL䀗yl,G)CL䀗1sX&3RV/X&3RV/c檱Lf 1^Lf 1^Uc8JbZ= `c8JbZ= 2q2Ĵz@x2q2Ĵz@x93We2(ei28e2(eir0fdQ9epdQ9`\5Ɍ!r<6Ɍ!rj,G)CL䀗yl,G)CL䀗1sX&3RV/X&3RV/c檱Lf 1^w7>i^!ESp̌8V n9cph b(P%en5^Q?Mjibk h[A/.0Rl0eG!:?Vb 32?0ED$M7o1@XiR#϶X] ibX  ߌ#ê_'l^7>g]Je&ieAU j!z WIS ?3<U%6ǡ'@S,[cAU j-lƧE?eX(u}p璗Нii2+oU1p~WTBC矘 ;^9JCKk+iKW?P]C2g7̿0qh$p1O2j\Aj?1tJTY0Tȃu` A7Ha0b]~j9kjV^x^źYY倊mahSo{X/s S??hf \2GT&h,\r1W;o>:Gg来wUA9YԵ D쬽ɦsӵ?vhcf^OS0G_q A/_X0Ĩ?3SrNx Ԙb-d6G?'k "}' OetJΩ0 v!,+WiْWS7>uI0O3e9C z#G%yL9}\/9*cjzQ gSsN`u@@GJ=s^3:rTԜ2X!=Б@<> 聎z15q VgDt39e:C z#G%yL9}\/9*cjzQ gSsN`u@@GJ=s^3:rTԜ2X!=Б@<> 聎z15q VgDt39e:C z#G%yL9}\/9*cjzQ gSsN`u@@GJ=s^3:rTԜ2X!=Б@<> 聎CX{K!]$u2%HI:̔ԃ>!A J*r%ܨRe7ǧ?u'U.y)m+/Q_mV\ V4I'O*VF(6+b`ŪinI'OXA3U.y)m+'OQmV\ UܢI'O?8ԃgZ#\RVZύ\~nN@HUvE{+Z_ I ͺ*ON(ڤBrGAӵp?_~<4g`BrK~i8GCC͙WlG!9mLw^؆&uil2/NN&\3/׈_km fm퍬J%A%_@C U,C ?\vDsD_~xhEz?B2`a'ߘc-'c7ߘSXm"ou4F6̿2D柙^R $RAGc2/ L j^L}$5*/7胾% 9=Y1FBbN|@ dipqqMȆ!YTWHL܉//օ}b|AJnAgNƇA;Q6u7CMWzv#j=j:.f OIT,Q_2?4NCCךw%$_?3`f!2g_b_%`dG-g h2G/2l2-"$dGa4 +̿2__~+ ՙIhችvd 7bu?q+ԪQb`~\VU12 u`r ` gkF a" Jqr%?Dp>LA+AW'I'd$HN_Ɵ?2d'|f1d[&:) @Dl#.& `jO``>39 B2s D+r+n|_8 ϴ8~[.!r0|'s㞧EGP/?1YFYkܷk矹˴? i@6O&?Oxɬ Q~qF쁀^Eo房 p6'"1*Z>+|qqW?lʅO?`d'߰ g#3f 1/"?y_xEL? 0 ȡ^l-7>a9Ũvdӌ@P=MN){TƎ(%"[o~sS*N8RU?ْv7@V\ح;"nrHǜyƧfvX3 N"c@5&nqbėV'uԏ0NǧajD@C/iE׵Ϡ`b'oU2-̿0E_a co̿1قȯ1 V _C?eW_OlU u}G7y7 @׹#=skӸ FmPV㛓:P,^ϒw\kcx+7 u+9\k6(s+7 u+9\k6(s+7 u+9\k6(s+7 u+9\k6(s+7 u+9\k6(s+7 u+9\k6(s+7 u+9\k6(s+7 u+9\k6(s+7 u+9\k6(s+7 u+9\k6(s+7 u+9\k6(s+7 u+9\k6(s+7 u+9\k6(s+7 u+9\k6(s+7 u+9\k6(s+7 u+9\k6(s+7 u+9\k6(s+7 u+9\k6(s+7 u+9\QOSw Y\-7gH'=m4i3-}7~K^MBq5!=xpUN;5WDr͵W./~K?6Q8[ղ#EO =q4??I'̿I&X'9I?R$pt^d v\!4 @ťz߸FX2aH_ԅB:7 0(<W0w}2 }b!&ӧ@^'|?zgA0PX5%%wTAG/I EqR88PʟIu~_TYtw` 8id&D!'jaaiE+\`YqpC"j?#?2f`'ߘdgYxU ?|DDˤy*?"CD N?Ӳ/UaRӘ> JOxᓵpR`=#SM7:Jdz8wB(huqp|C]b^:G+ ]~s'VMNyigdz8B(huqP&_t (pΝ Zg?C^ZiL8N3Ɂ!/]B4Js'VǚԿ=+ tjǚb0%-$.=|,lVG-j-h\ϴ#_}?;d7E*i &Aꗹr_Oք߿‚[?T@f-YFor!ϓ}^un E՞CC?XwzI[{x3sQ /̿xK柘b ~ο-[r>[hO{8n|Jz* n18CED\wd-bLp_rrΧ?_b5?bNrW?;G@;1wV,2_DjuC9qvi JweKiE:$@dUzhT1EyA.F]VLdWƟihiAS?qNj?c5'oK֨M! '2"Ɵj%u'OՉ/f3 7>G5~Vܑ/ E*XmT9O(&i#!7o{}UuFםPMP铎\]5hȤrBϟ$ql#77HdAC&"u5Ls4/2BN%J!^!֠DVP)#;v%4%fG8V7b>?ݸ/ӕRԪx;*.J?Ex͌_OmR/}1]{Og>y~h㣬w. .,{W,^rIUn6}Qmyr>XbrӍ./z i&~Ww9gW9UHh>p[OmX=`O s kS" _?6UL__ƿeDkg?_ʟ_?G/`MzO"?u&Y/rd_eWF濇'!ChmSM փw0 ӬxH= hVlre0]NB}MOOHmkŌǫ %]kQԿlh]CQԿ6[7O6>\MIY+BL|-#9`Y`heGH:72ңR-}neGZ@KJ&ޗj Ls//S/=*z_^^zT%0 LTK`b}yzQ>72ңR-}neGZ@KJ&ޗj Ls//S/=*z_^^7>Iś\zO*[ ^pm$T ;,?|- 4r*۰7p>9.q:e%^󝧖ť\ry+._Rk!.ӸR9$~ *tS|wU6rя|\/ƛn,/:(t]C>|KLޜkq[cÙG}M]]տ @Nw^GaT>,(AOils7}VYn?)?XwMmO<_0]؆f! 6OGCg_Y6hM\,OM>[Ƨ\Ơ˖g{em|^%A)E`)M4F;hm>4Q7=MOұ%dlzSԄr1HOrQٛz[ĸ um̝3eϋ+h=xiXHZWԭZ?g=s%f1Xjn8D 0ڧM~+oߗmu/O|?o-(ؿ~}l|U{oάjl|cC9(ui8~?)oVF)ڿ ]G?ǿZV/?2g oߌ:i?0C{kF (1??/,x&{_xcŲ̖uʆ.]r?7^6FƧy铨vJ7XL0sdDk`MOu'ʦߖŧQx+\^(Cifk5g9l}!ӇAa)?OzBVq2Ga.ofG.|{ءo􆐮ؗ ;?&=[92\ǿJ6;o)_?O8uׇc~iyӞg^>Ɵ ];r챯[kדH d'_1rkt2sd99.2_kif,zL|#Oǚ ƿXtl~!$kN P_x~+l$3O=?ooZ?'_J_dϖg{>n(˗.-\ŷ0-ݽfoQN? m-^}~;Sw |qQ=f/a Ֆo.?Fkf[K6vɔ).oRϟ˗;6ԏ$8n[oJII3ew.7,w}yߙgɧ-k.ǽUʹS]?-^[.ϯp?` ƍ?m?:&I߿K}m_ʟGrW";?W_??2 qVIGCm=c0g_W0Km-_kB^=meSOx붞ʯryɳFy{/OxS+in|,ͦGS{?v=UnrcYz?|ԺzpْKAX 1`dדE&+0*UDkpe! *+773Y9iixDkVu%K7Pk<8ݰ'/_rey  (/}ɋ9_mQ xgVN|-Oؑ,Xƃ3j(?'Og1KʼZCū0qP*ÌTW>P#%-^tl:PG.u؜@R@zjֳڿiۭۜ?! ֯}H s.W_&X>ٳ=uQ\+fcW*;U|?YE!v|@D$3\0IW?wOO|SN˿{i}]GG-䇠n̿=*wH$]t >qo D~PM-V][$]AǛS% /od=eSJR=pp+XVSJA俌i0kjOש)!rп^-o{*Gb[^yrkσ}\ o|sn|n\o]^D_{y!O}fg=2R_ϊ765WoD4VKv b/p*t^Ǧ"M˦'csւc\kǷןkq̧ojm~z˻}~33/N~]Y{s[o]x{˶l[nR㎙rq*?鵪| ?gls{6PIGc-o{{'gS69tY \O:>Nŋʣ,(y^}~:z?~a9NKG^٦~{=b?sV>$0f2XZ3~˯l[7`uׯ?^wO=g>oxe 絏pH ~socgVJ1:0iwT\gtFn# [y o|fΧ?Wgs͞ϘoꛥyswdcүJ!R/o|N<|ͯqF ?>^ۆ r㣿6>xܱWyo?^N|s+'/oeCN}˃`ѭr_\ue=(p`vmǼefyo_;{-6߼sJM~pJ6JoRw['@%:Y>sכeQu8x巷Urï~)oZ\]yE{0nI妛^o|r=H;I)oY9M6=pwqGw[ΓWU?. ,,;?hY+-l/T Ιe":<@6{(> m.oO{_6g?&45nqsg?\ -YM)P˹s2rgW9oZ{UOr/sA}osyG׿.A1t9=ܫ\yt'\[uo|˜*,b{gw:!cxr6@ Lqc_WF_GʝfP-|l$ÞT=p|lzl~D,|<|7M%kl|ڱ|+x/^y3~^ڦ,eZ׈[n^bkG y`[oS~}fv~o"y+)y/{I([̶jKf(I:{ƧQ+g=v/[mePƞt3wY~r废^!G5z-r[m))˗-/?7X4>3?euۡ|Y6ϒX( _a_t7A:Q6 ʉ=Y?/I9Wh0`̃UBF7p69B2lG"i6@ RqcES??li$#̃jk3Qww۞{QAw²7 3}3$ u5S0hh}WMnAicJv ,7#],?醑*FH7/7=]xalxZ(o{8N5l@y 'Ft.OWdstˏ.OyǾ_(?4kK38}lK/fmoEUibwp}`UA֥i؛o/7>=q' ꫯ)~b6v#\?߷%7ʈJ8qmn-GyyT6>igaE_v1|lB m| iWZ)?)6>=1~ơ)W[07RWg֨1~8[C| ?ORlylz Ͳ gZNxS|WWTy-oz)eޮu Ϗqf|ʙg}7O~Grll3%oQ6`=)7guy|X)~9ϷRd;:qO(r_ys4n9OпqwC'?Z3[N_U\ޮ1_s'$CD (@ֹ STcD:d$9SVYQDcT‘F]' cn|Ad+<;`Ap  uC|OzX6@鱞N _{DȋdC6h=Z62->Ab}{\Cq-:F@v(N߯l~:Ik-㜲h"VYg{*ϖUswAw|`9]jkW☠m6>a^Y6>訣YVE*p$Zt~1\DQG>_=?7>=V;K妛n? ADxs? ۮz?/e{n{ꩧsU{ϔm>r?wv(U~Vi>:\b>Z:*'ȏ/?RWTf&+j*oRBuz,q4 S*_?cra.ɂ?Oߌ?yf9?12ӴWOƟ?0P'PYj)go,7MPX?! P6di7n;6>=)uOs\"_L}+4[ZT|;&y&k}'8ϯJZOKƧ`ʡ=D7#ճ:0zFsnv >HДYWm#_| )N8ƌ7>#o|ga9ЧU6[ d-zԎZ1fF'OƧ׍O嗾n]w^ /X+{Cm4>T~_Ct,wZ>rO4w+N%C~ƧS~\㟔. 8O6}NJ'2lwaڟ #_r~ɥM'z;>s5G+2&uԾ^.r޾@RO '{$kOuL⣝Gq#zß@u>hC kj+7twO n/uOKnSt.;l? 2/G>:eWY M2QZfEŇ&Ƥj ? x{Ova5Fhj^????F??$?9sC*H#?\;0;?b_kő}?U9gJ+\]x_ |p۟o$gIgiq贍*.َOo(6u4LY)'2/-h 0kxhʡp5v|VXSڷ`xT*S^ɵ3aq`:+__VLۿ ,yͯ~F3Ȏ:tds][w}atyG,,W'g&{߃ȣξ ^am .tv\`6?qXfOtJx]k.8pԱˮ0|6_n3\.P:k|9ҫSZ7`}%,'ĉg݋mK-nWs^Ohu}*+.Y?aNM9翪e|KXtEξk2[ȂoQz3zl_oQo3u(^߄9TӴ}utTcʴh!S0h]Ty E_99/8gQKDWkseVn_vKZMnOw`lÒK(]7E?Yt7ZKvrx |Oaׯ@ϊ?sV[#0\P`{]sh/N>vcgXwDCƾ,:b׿>{# ρ|'ttRX Yzpɲ E_$5_o!aȑ4!L؇:Ydpc]wf6㮻 'C@\3ۗ^'$hgg'?hC2fOS?Կ31 /ui=g_IDhۀV+ ?>ԟnCx{U٣xO1+Ð!ZEOp՗!>Ӕݩ\(3.훼kV ~%9r!c+zQNs))Pb$EaA5.BcWk [o_!Ir6 ]lYaӺ!駟K,Kz+E_ ;*叿Kr'ݘnL8VBKfoG'/+. v1{]v0raؾ{EJniI^дcۅ-T-/ 6$:U=|_Cr„G/|u3 K/yXecm=6jۄKJZ1݆Ujvc6 gz~Y뭷YxR^4oWke}4P&z;BW^/kzkvUWG="ACO.'{J\XhuWjvÎO{u'G#߰ w,>c5ek@O#FXu5;k(x"vVy駄?r]^װJ>*#~pЁğq),;t޻х/]v?auXo}KxOG]8D/o'x)>_vSW?RV֋OGy) >p??x/v0G$)ffg_ڿwFǎOxqXhZ|eFcz}n߇ߍfm7ŻW@ǥ v@7KF CIN!;qv{?};'8U6EvQ7 /}tíߋ>_8a7pͯU7\?OސC B`w]G?(-|Ri,lXﳟACqcV_m5CrQ'a|p_n.^  w*ߦv/kʗ>UyoRؤJPYЙaPU^2r}寝AHQxt@gi@Uygr`Π}(Q,`O|p7\.i_+#_{Mw]7b!a]$o93;1a?e]K v] ٹOW9J@Ī lpJ")/Ȣae$)MU/>lv:pǡOZڴ$I\ʿ//KIZ}Txف2$hVAK??;GF_@o؄!Y& OZю*3?0 } :/[x,|e _Z3ҙLwz 1OQnE5b: K|#Lb+T_\-&L;̌ !ua^BkںOGrˎO[5Q[zS| g&?l>S,Q >\?wg޺O|CUUî{vC{k0¶ szw=sY46_VF/vq.| +b21W%/4Ԉsz뮩q2_,-RƢc=Կ†O} \~F_a u1w?hV{?[o_4Q7mbqԷ'}C=+__?,,Z,T*+‘?8Vo'B~m@_*2ckl_t&Ok'iݪsgZZ;kݚF߁Yoļ4z]Ғ~sрlJ)V̿Za ,zR˂'lAJ&~#%ޥ_c׶ O)'?V'#*^}pj!"5R9۸=;|#StŸ,?zG}3UD-n售_#h \sbګg2"7A?Gᓟs |-ϿŸ^"SɵsS%ͨsM)y/&Y`ԛ?*DSm?>?ƢM?fnA!NѦ\EP HGRfB69f?A$"(9ҡNBG8%!lՁ #1q Apm+7:j|̓/_?uVAX7;>=pGwg υK/L?;-|܋ӮnD͑:K-5]Rd )>>/?:;*&~C/'Fоʵ!>h_q Yopi'3Oˉm/ё'|j8wpoÒX%_$ma~𩾁3B\6[n=W.|swPO}O,Ԓ _4<〺ƒƆ9WJp˯ .,pZZ$ ^W^sp)uBqWEV1G(XB>ujw;ot;*z- ?''pH~8=k^Kz'݉ݞ^=uh߫W:92O75!t"][r.!,}{/Vֱ,՚n*OqX;_q>מ IvB¢ cIr v`%!겓jX%,zE(T ^?SD[:;uO9%\yK.Xpp?$ᕗ' \k]1ۺ\,| .|ZEvk49, KPjW6 {c* t5^+|*ԛam&â+:z꟱v_>"bsݪ­9S.;ձ$ 묋S2H{9| b|PV~K,pgDw`?P,4USSŽ;EW/OE㣰ZÏYuN;ɸ‹`ǧϷÿ~a+KvI??[amIA?"+Wҏ^?sSo_;4_OfmXhGH?KZeJA`q~FO3iO??A1y1;GF4[ﰳFSԷ\FB]:)fwjSVۋיw|r'ӂ KgVJ rfEX2;>V|h Ǵ.|jy|;>=;1,Xtˍ&I3M7Wx7{K;*l٦ Z=a莻ko9@,|U촴2/oY3 'u¡X$瞉SrǧzWCs[SyioЧV [#?dH1]wpy ;+삅O1G};>mߪQMXzoo9 P=ŗm^kM'O0y$!wǰ hm6ZN֊d9i^4Ό&&䀧Ftfl419 <-kҙ|h7Ό&&䀧E{MX:3RO6-ҙ|h KgVJ rfEX:3RO5AcJibr>AxlKgVJ rӢ&h,[)ML'OycJibr>AxZ3c+9i"o,[)ML'Otfl419 <.d۸6avuQJwK_I)Xr^HJCJ(uj`ejӓY7wuGׯ>UQ"qyq՗RJ ]Zq'ϴ?:/.,̅?`ۄY, +`A:kBK•]K:p3 /pijxWCb~3}& @pp| ᬳ`W. s%>COxkxO/\v]=b4bsΓ]b{㍿ y0`raȐR,Ny- }i2zdaL/r?v}'§VZ),7`0Q~ҫa=%(BORv| plG/2:GSߍ}7n\*O=[nE"?Z{UO2699@7KO???_uAxB?3?0XDPHbr(I1OHchMa]&Mo]5مɄ/@*00?2H3OAΎy7lVaa,qw79g~ /*czYh&~}V9 8 '>,} |SYyM8WuǧGuM(й_"{pCaA+4Sùhay3yehQv|qF? .|7=٭i5 (ݔ+׺aJvkpmk!WW\Lk@v.XVY B. o#.|Bc;>95rxo6曆/mwu\aT[eL"ƌ ?:T:`?:rOdPSR-U U=f*6<-DZ@ʵ?叾zxS=s*r$}aXT W}hOҫD/-'>q̍.?@|" qIn3zfXu ~*+jMv#ʲfKZ co c|HW7N$icFKGc7_p_~ʥ_ʖ1Ob'O0~60Fv> 67Ex!wQSv)Yig?hhEaqYFD/J|8A8Eg.j>I?ŀ 3D'_2.d|Ĺ4`i,\? .o^B/540K^G>ĻH_ze,vzLkMޭgƒИ7I>KvtcƔS gl{zZ5U]le0vGVqem9zPYL˥bN ?2SO4hp7Gro7^[~lIxza%F[}[XO3b|i{G;wİ_ 'wt[;>ޜw)6BoAv|Z;.ofXT}NMWퟏӯpιcI'j-?悋c{ HbpΚmv{jbǧS_{ :wmp7M t]?`ؾ[l+ nư ]Y3a8`&v]Tw}8wB4XV ˸_bc '0 öW'n:{\ZxHt"o1`󡅑-y~V_;}m;'n\f[l\j)_+hkO_]sU̽s1GG?R qA^y9|I]tp@|lBd&OJ|xom=ugy'l>{68l0f̅ءvlvet7F|pXws>3祗 ,( bϿ|83}ïw|”װj(])[m:갰_WBE{ƎQW_/rWwv8d7J?U٦nN3V--v;_/ROb/.?/`kѿ>s`_D85/_z?0!9!9s7?u'_X7E/!i:B_ڿe~'̂㓛XZ&ePTt>We/93xVI@ua<./ G|kxXA^y6U%Y$@Q#;&8pONA(w89__§a`-i*ە_ kY܆{c묍j{'>?\Sp>-vQ:)y§QB9+ Y_K?MI焵^Kʀid&^{a@ڑ++aǧ1]w`.Um\v'//amEh78škRa={sϿ%~6f4VW?/履;CX~@T~|?AkctYW\$dm ;'7rHr%D TI@&ޮ*r$fnsNo Q9eP39ibu2 4:CB@ENmrzX!!j"Lj69v=Mΐ5PS&5ssz&VgH)M9]O3$D TI@&ޮ*r$fnsNo Q9eP39ibu2 4:CB@ENdXAˀ7<\}nbw0#Rؿ]'Ouƺ;7ZoؾHQr p>QQ` *WYҨWwNQ?OY3eDx啗¸qoͅ݋^#j| BYd0\ N K&Mz?x^8qY? 7t-YT?~SyGN3dW`,\kXr); {9C Y#᭷ c1'e~_O>?Q[6ڷپ ?m30Iߖ2}????a. 70TbaCr9`9G%H /ڟPhAAg1GʤJL Oڟ?Hc%:*Oڟ?i9Դ$ϙa> >[L] qª(aӝYv'N3u)ΏUmE h?IY>X%aV'i!,z寮 ֛9"Ӑ{G1Xde_kWјS, ZNڪb©O<K +!Ӹ~i0|d߁du-آ/9s\W^ hVF/~q?VW*k?\.|o ~ {GO뭛o  7_ʗ7 묵f蚣_;,z)ZN~mouUX/;wvjo 'ˮT`Jv3Zwr:PΡoEMe  r~m.:dGsbԒVvMA=8' ' Q gZi!+Ӵؾvʟ}@( \汤N7`0aD[t"̬OJV)ȋdb dWRZ 틤&.tlTt}?^S6_?v[wqgx )(Ÿ'GĎOQ§oJ묳n8⩽ڃ}o !U̿_I;Ob(!N?1/~eU4 Oڟ?Q>c+hMf㜠/(G͆|16;&7*f\%߶5rb^Pi]GAh_eG1 8d'&_Լhw.jO`vO!]#5;RʚQo;2pi"vZ|%R} Вeί_q%!? ;YG8dHmVߦ_03$,8jڛ"{S' 'Jz1Ai?l0##SgV_'LX{Å~{\],|ҫ%JdH\ӟN8WRwC; .|Qa9H?sCހ{GW<|8{g)A ?pӎ"e)sӺR$em &@-GTilĂK`(HR1^w(_gOC$jXGK~La).% \ kx۟~oVaɥT[/SnӐ0<__}ʤO#(iuq³oiOn9S~pZ?N''?__?f/_/ڟ3/M7oߴiM7o| /;QCwGɸtS)'13CFyMڞ:r61N 0dB8 }(rSNu4eg(IQT^:վİKp7k,H|7šnk" b-9t^®OW]uu%'! -ڔ)ak|OamÑ;mS#1JsZkUIKʫùc.. .a.iͲiҫ #w1Gͷش(#NHnîQ珹0}8@e\s׾r{_v/CsXoOx7J/܂ݽ\`oj-!F'1߭[j5U­w\ɭ6KT 2j<*s+DpbHQ{I̼EUnmWJ8K!㼼MiiJT gI:dyoJKmWJ8K!㼔SZo#%AqNaUi4B(~jXXO>$/(\?lߤdA5kgCZw ?&6oBw<.> 7x9ơaI[/,z;.bV??k?OOYcqqqqQP&?8p_f/jA| ym[{FD#I}bw#G?/h4p?:dvXC[N ZD2H 0|:w—k:*cc!YaKbk;@تñ Y<;᧯}ឞ7~+#?^W4(\}%Z79 +,wÜs_yg{wk_.b[qBԼLɝs5wx¢}2a9}yκT|7y>4wI-yj:W{ϥ:]6R"Z' evWw|5O5yg/ΣyvtǧhJT^̎n=I%f9]YmJW.)#Pؾ3(׎4 ;=6uv;2FUIgjxgizhJt#FQ˕?V\o}0_ ?SO?u/nס /73=9K\J)dyWY."vRK}|n5CNKik%Jj=oiyN5p.V3Tr+\I&Ts.[H"7ў<"p E9\˭fV.M--ϩ2\n5C%uDn=oiyNE8r*$ryKs* [Pɭp]$h[ZSejJn"D{p.V3Tr+\I&Ts.[H"7ў<"p E9\Vu')ӥN(xV774-YƊl[HkKW>Q1⃌bԿ26|h3 Km&Kh ڟMG5iK! 4{E F&r%O}j-i`' f'cWfƟf_fOOLO cy}J=:E&; (JX 2j^+`Hd:V Wa' c씟!?yX"l.Q$E_[qr@}F[ݐ5A͢E?(^Ht>ףfc %HאIkGdW]d/ ׆E"c):o3L{}uN^E??_?1+AZj+a<-A'oa7dW̆?33ό?#+|CHd$wͷ9? ?_fo]ɉm [@́QԠSQ(0BVHf` ykw?!,~:Av~z)wÄhdtSpiMe־6H=|#L Kn'O,l8 ־Xd[_v,%W` K|lg6M*3W+[dZXJR$ItԿԿ0hpE6>CGw `E$q {->Cwi/ڟfg vg1lO? b}FF(7I* D6_ƿ]MW|)>#9 J`Ɵb'6ۄHWF8ON6|F,X2{T,9e><j}'8^@(hy9Q?G/u]xރDGN4V 69(iͿVEOEsRFk Ol8Pr~Ûo]l0\sczM9uX*[ sY5$%s :|M) Z^rxy䐧&l8Pr79~␧.'8] `39~␧.'8] `39~␧. ajXjɎ/p9 >'\T367,-ֿn_'OWm[!Oug >)e^& JowdLh$V_0@nZmix`uFowdLwP9 J"M|ۼ#cZ'E#^'T.|#(JI@wf 4-gix\)Sx*2T%ԧOq'$Nr[!MZJ@' ۧ HCȃf8 _?E!tis 5X5M+QwAagDACFm9S?|I%BJ%*QwAaHDdzw 7t LTQDB@0AT7oXCw|”BSOhޑXv|JJLfFZ"%3Fr`i/e9irJi!ʟFIxZδ 9S 4 2TTJ @pqq5,4ZČ%HP߾#Z%CC.e]@a@-H$FY-<ۧ8D?D ":_٪E7 _d5{/_4UAo1&71!eW_Q_eW!!32BE֔eW 't/U9<{OŎOlڟS>Jh$ ƌNPf#co )ۧjs4[3Z19`JJOVLbf3 TK0\I1\5`>'XQ+̆GƏS&f z(DJ*f/Z1@g5P Dv)?t!e<89@pMQ)Giơ7+vrs0k;rꂽH&|`ۨF(J.o8ȗo`H=l݀G lh Έ"?E_?rA_tLo?j 7 _!3%_!a'/>(#㏌?3)f"㏌+0*GQ 3ϳoY>IH'yrxVS爒)-1,#pvNޮE]5`>ciQK*rXuyZR\3z]Ԩ"W^E-5`>ciQK*rXuyZR\3z]Ԩ"W^E-5`>ciQK*rXuyZR\3z]Ԩ"W^E-5`>ciQK*rXuyZR\3z]Ԩ"W^E-5`>ciQK*rXuyZR\3z]Ԩ"W^E-5`>ciQK*rXuyZ(Iw'CB鋇s=ޟ)0a{]b-o _ WXHCeʟ%VUF]2?PIAOn7!IO:;9'7h_IuTGF2?iI'O5+ulhV& 7o%+kc !5$K' ӧ NJv&x2l3jsc ( &0lRuCR9t,_P۠ b_ʢP۠(U!& I3cJXi3۠}swU%mmPʥN1q͞O>!,w79oUQ\ޮre*: I^l O鰧{,9J٠ >Q;9at>O}4%G ;'??5LOlԵikZrsRRvֿtxIh&h={)c`oF& Hp;o,]l_@qQJđhH_/b@_b`F%5?MAKt?f/|Nga'sIcd51#q4ό?F>%Ieq6Rac)"5 9hoT`n'qP [ Tۧ|đI%,H4@CC' M(A(I]"q+MwGe >(5ªLw##wү+뗀 )*gپFdHI?@hO堂q CƋ̿Dy8ja'sWqu."'οZ h@ڟH+DXi->?oD_4q4i0r D`AN_aHIH/_/d5#,ou!gHX ETKFQAMeHK0@5 ~gJtE1Ԕڐi-@ 9z?1sD4t#J ߰`9Dg$_.tֆ VZ$eʃԚOqQ@W_?@A'o@Sf$$I12[`U( όs???b~#ۣGNZD}SVJi A@^j9SDOWhGH QECV<jWEwz4ʿEV)3-$&Q=ii'OULx)I$E3+ (Qr?ڐǀQK:˧0㥭._`F>F5PPb'O!hI;;$1OxA'oa7YeW_ۨ_eg\Oϟw&T;>{óHz:mdĂBku&T*JlH)0eH,-RkC(Q??0JNJZh D#׆P>g>m |P6w*߉[ȋfq4XEecߒL +ۧeG?Կ:'Ȅ#οh`0ILj5)F5E_BW1 SKGeL5% /C&`_d0g),_D /2ĂdՒ81f'١./dZUzf6EƍFhO2Rfec6(H8l빰)?? ET(eTmDBkBIg?܄rMo}'fRe(Y ׍Ēb@B({:zhà JhФ䐺>!0(8H_?i/tٰiˌ)LC68[_A_QsBKI3 M80Եc[ l/' (0+?;83^bލC)( ! ʟEFCH9u!8>,) οjV# _?iۮ2&pE?-o1A2`%/O?1$ A#Ov\0w2%O?1"㏌?2#l#e٬i|[d G7tᓽbAHi,F`)dZeZ)$ _k逩Ti-BNBgKvOU-$t$ _k逩Ti-BNBgK*FTG"" ZR9/Ѭ^"R9[d~,I^]=\Hپ^=2H2<'cFz-ldBC//ڟB0c &T39BU$CƌȂG+f)#C)?'ondBd!̘">%Db _˜`7-D72 d & zׇǏӺMĆ4"[m5Ɍ;%#:KW=xQ kԿi')8:4aD)*lg F+`1"9r7{?矶{ _fՅOy+6mni$հ:`¢1kZ8)+~O8?Կ29Bת":aZQw:85K쯁£V[F2m1/X72=، z6рlJa.7$CqAC/׋ F 6QHi~B[}7T23aO ɞ& Qd ykT9SgNiFŜ#=uɞ61[P ykT9SgNiFŜ#=uɞ61[P ykT9SgNiFŜ#=uɞ61[P ykT9SgNiFŜ#=uɞ61[P ykT9SgNiFŜ#=uɞ61[P ykT9SgNiFŜ#=uɞ61[P ykT9SgNiFŜ#=uɞ61[P ykT9SgNiFŜ#=uɞ61[P ykT9SgNiFŜ#=uɞ61[P ykT9SgNiFŜ#=uɞ61[P ykT9SgNiFŜ#=uɞ61[P yÎOJ+`ir]X$3r?e'9$F!h=QǽkSQx9p/ڟa&obAq"Ɵc 0+㯌2ˌ\|||/|O|OSNAf>y_=>雏f}MIX mjBr:K|7䀧el,[)ML'OmYcJibr>AxZ6؀3c+9i2k,[)ML'Otfl419 AxhKgVJ rӲl,[)ML'OmYcJibr>AxZ6؀3c+9i2k,[)ML'Otfl419 Z݆4rL7 |)Bgz<(P2Jdcє\V /_ο:>fT4XaqggH)M9]O3$D TI@&ޮ*r$fnsNo Q9eP39ibu2 4:CB@ENmrzX!!j"Lj69v=Mΐ5PS&5ssz&VgH)M9]O3$D TI@&ޮ*r$fnsNo Q9eP39ibu2 4:CB@ENmrzX!!j"Lj69v=Mΐ5PS&5ssz&VgH)M9]O3$D TI@&ޮ*r$fnsNo Q9eP39ibu2 4:CB@ENmrzX!!j"] Xy@DWmz H5B>H!NI! #e \oY(RrS?Կq)O1GFSii!,ο?9hQJD]Z-ڟ?iISx,(r*3-F':<*XI)c'Oڟ?i!?92ʥJL A34V`ŲآI'Oڟ?erbr)ʟЧРDM8b|h j^HhAK+ӇYC0㿌adG-p 4#㏌ʗO6 Y9dGE>W_e}qjQ%o[p$0%seul?OCp$a% _y\Ot## Fnji*\se9???3* RaM2seu?R dY$^|ձ`p]l+br.jH]vJ/JI|lgrv_?i7 6A6B'odd'd>%㏌S.Ɵب@|/|/Ќ||/P|/|/|Rz OcǧtXL1e+hX HT&NiIkTƊ.BP(jŚ?' lC*J8Pگ8JMZ) $ª{t2?f;>eSE6S?@'q(7-'~ğ.<OcSW ?_?i?(& _?i[_M#{~5$ ?f̒D /?A/2 /[[ 1o4]k?㯩0+㯌Κ,|R j.9&CI9PUfM9o9\˭fV훑LS,/%\dg(F.M--ϩ2\n5C%g;*Db]cb]c]bE%H}. hPٳ{Htٝsfgg=+pJ,.f[Z0,˨fP-pJ,.f[Z0,˨fP-pJ,.f[Z0,˨fP-pJ,.f[Z0,˨fP-pJ,.f[Z0,˨fP-pJ,.f[Z0,˨fP-pJ,.f[Z0,˨fP-pJ,.f[Z0,˨fP-pJ,.f[Z0,˨fP-pJ,.f[Z0,˨fP-pJ,.f[Z0,˨fP-pJ,.f[Z0,˨fP-pJ,.f[Z0,˨fP-pJ,.f[Z0,˨fP-pJ,.f[Z0,˨fP-pJ,.f[Z0,˨fP-pJ,.f[Z0,˨fP-pJ,.f[Z0,3rvVCqBXoN3(ߒJC:h-{Bbհ;]|q"L>P$`[J-)t'D )YgM_?P?Oil^u#o?Ph-)?/O=Xs/qR7?ˇ9=) d pD= $LI JZPW .,p(qy},I~cVG| Ct,g1A 2RP3䚔3\`t-2ry:ҫ?>TeH_ L z]a8.,d/ pt:ct+Lj#W] ;}ǟh 0׹qL>bp/?+"jk_p'7??OT7ߟ76w t/)&$O!`NuN \Ik4k]0œv }G9,`K-{>Mpb߹$,ǭ`"i GѮtjhL/fn-۟n_b?g,|o?Os#{dY'8A}rd@o'7?Ŵ2wAPOB\=!0SA|M̑e)oD9Ou!?OZC  =$C@MC62<,V%iy#`I+|Hqb⌇ƿN24_9X} SUKG 5W_&'Ylb-I#N24_9)\291bPkIZv!OɉAXKG 5WSZ~[Hò8Gmݒ, F?]pgw4ahP~4A6圾_d"O4(?, e?_?R>/?ao_ןNZ'o7Mot_Qg?/Sz˅LA:o6+utZd[ˇu b۱igjgl|DbiJPnHUQ!d i2Cʴ88X ZBFٴe8%D 8}aqvd#+ ȠU6m!Ge˟08Wg{gXcR˟'2|ũȣ+^,I2C\=pE__??vu@;YUx jyJE:\[( h;]tC׿:A!n /e \|&y 'O!&  ?_,(O[3O>pqQcs% nߦ | g Vv0p|֛2[%ɲa!A_KL0@e؟rzBҖe55Pˏ72ʷJ2Pd8}08}r"Er:+ˠ"'_qı8H,"*ab럢pUh< kyտ[Ntxg_Ґ/^kJBD(2k+_iQxXɿNyqsZ`aQi [e@J|fߑ2Hi_`0?pUB#^dBV$?/5KUsosX? Os۲{ '>eUsynDŻA ]ZP3H5X&ˎPb"bm];]P&[1D ?>|eJ!J99a{d h,^Sg?~We;(:8ҹԓ pĺNb21#&0ǟ׿2|U!0q#pO}/ \ ןvCf;/YG/,7og?yd&ߙwwundAlr䉯sG?}W 7>AZ" qY)$TL2%% gЬK:}˟ \h( D$#'L$/>_PˉlDk8TDQ݅O0_ \xO, q!a%OrH=xwG3 ׿>FϿnߢ}lɁ_3Qu_7#uPhRز\ouNrtNbaXXeG?:\N񉽀ٿ'CqK>+I%`peqJ>+I%`peqJ>+I%`peqJ>+I%`peqJ>+I%`peqJ>+I%`peqJ>+I%`peqJ>+I%`peqJ>+I%`peqJ>+I%`peqJ>+I%`peqJ>+I%`peqJ>+I%`peqJ>+I%`peqJ>+I%`peqJ>+I%`peqJ>+I%`peqJ>+I%`peqJ>+I%`peqJ>+I%`peqJ>+I%`peqJ>+I%`peqJ>+I%`peqҊeOr:V(_|Mhd%0a[[^"( / blEtj9BPer]R3 (n?nҥH?}o_M2;fYSdIA2 B4F߾F؜ _߾} b#/եqp?M ź55Ca,)0)әYi qd)-U s",,b2Y W"_^dK.*SZ&KH~R d#"^6iDF r~ʋ gQßo7p7FsX&]pmY3;%;]|qksL4>_kX02d߼xuŒB`\|%GP|/__`Mןhе _d]˚_ L|o98a/q_e6y̌Xs ײ,fDl| d&j,L-N `†r?Gb#6J# ǟ>>(!\bG2>Ylڴ4N1R0]ܞx^ L*ȟIɔgyy.9FdQvaQ 8JU?J'd׿:{ hVa/n_rvgsڊq",-qgMHb I&g?F\X~22<.`eJYcVV mp!be7"0be0bmNg$ (Ӌ̫7ƻcm\FDqd-fE*8߲>m->[+~ܸY3| ?HTGyI[vq  [\NI`pGU#d'Οa*u,n#x'yl:?d9<0AaW`p/ %npK_n[fN!n ۟""/n%npS۟nSdN!n ۟""/n%n9ڟ'?7>+BEF0+)I %faU)LuUK039]|P]h %v`$)B%_#?Ѭv24fjx _B媐jbW\mc-)Ojǟ׿>`߾?B7I2D_?>FChEt;_ןv_7?qukW(!N oVJ//Sr'>ٸ?K"Y&|-KFr6cV!4+SfTNE2 I%ye ,?\HBP;1*)+dROY\-V78#^AAN;3[,.,?B`!/('% Xw)',G.>\9'5|W t<1/_0ho4A/BG YpXR,@7DŽZS`v?A!q YYI-Yx` -d3;.tx'JEZb2Ixh "l2*H)jɲ6Wzl˟? I\T(i:]ʰ2%^}L(4>o8G~$RΙP8AԉՐ #XF|뀏:eBא:|2ܖwaHO >\Т#]i/tt`c3&c |OW%_WМВ?o_߾v0di߼`L7%V ?3p?aĨe?~EJ]J*F5YD•镫3^ٗ=Q7N_X(p?# 'WR1oUy|#ZBԋQ#g\ /7«0׿ S2O䐝:.$#΂I7pMS.N Ors\:EM6;4i*l>m|jh ;]|qϿn,?6~b_PSUda_cqnӊ?0d~uo}/? }_'A^!\#/\9 h^?ϵ8[DV&th% "p3bS%\\Uqnl> Cw>K[nI9%N_HdEx>/\"ǩHGV0D!\^Iq$`9KBNNr %ő.6Rᩐ\BIqd_dTx*d*(PR^*Zn'ϡ*fMMVpwUydMM"Z,7 ~l@AD.q#v u($Lq6fV){\O,?JQuB/ؠ?>y 5M}'?rG߾5+ֿ|e|/_a>_`,aAZpsF9!Li_0/gՖ%' 4?|/|qWĸS7zpNkYdY<9 +"fW(4,%5}E3,\E28#/)?4"-V0JCLxNW4 ?騈ʂ׿sb RIa<ٰ@:ƧTʉ}6|JP:FGP$j,\*cw)?" Q%$/0w†ּY `hx^_CqӸJ"˿?}SOL&Gj0hb?rS_@?|sE6G@ן]۟nU߾pa) 1wKeHlK_0_x7#)Cr)߾}S&Nb+g_ZPYB]HGKCT4VsW> r ň*dgr9|p0%Q a>P>'8)\DDFr؃Bv0(W\." "#9A AT!;C .ʇe\m=^Ӓ/K?9rG\bq:f9o67 HH7īxvD;ڠISyEf3~k<4tx$$0dGc%Blsq.X?)?rS _?x_|o:"X&|O_ן߿9`apt,b/q#p_xࠓ\qr5}o_/)_Uu^>pR*W(aFbbAC,( 53REƛS聇A&C3BM[hFm;Z"[;}/b|/*LQ",5y`~BJOZo i@b1Bz_THm|i/07h!j35?gN~` M`ZaCƬ_o4}tn6ekWə1 |AnXoA1K+`zO.>]! } F0/ן_ןQ/rќfGI3WL_2x#\3+ZVOe+p]q'zMBFcT >(C0r?p#U+n- J5!CS7+m|Uհje4qFҰN+$0SPz܃ !^ ']uMh]qM" Di_e a'kj.ARi&W-b#B.#I$B2-6Dԧ/3%S/4j e.%ݺO`lU*YTI hB2-6k[\(ɤ4 7Ri!X BqH& hL 9Z`C2)M@geZl1+PIin>+,bCXŅLJpY!er-.dR )˴ؐcVlq8$4|VHYņc-b !&B2-6k[\(ɤ4 7Ri!X BqH& hL 9Z`C2)M@geZl1+PIin>+,bCXŅLJpY!er-.dR )˴ؐcVlq8$4|VHYņc-b !&B2-6k[\(ɤ4 7Ri!X BqH& hL 9Z`C2)M@geZl1+PIi8)X̬:(`zl xqؿK~]vVw c{iWGp1 JGj?`k }8}:=h]-1T.n̙4w葇_cEyj{q#֟&ܘرc>/)KK g5jvm̙[8wϽQÆ iBiUZ4o.9={^DS&M_"K]][}i=6ڈ4hHաj8s;f47h̨QGZ%^gi8/J{EݺܹswY?K:ӿe}ӯd pI??..?>2Y~/nk_n)?|sOO n-?on}s]κ{P+*駞iM]n޿m|KL2N|Rn3\U $V*Oq2bC-+Je7驷ʌK䦬n @<_MSlTH9VχҒbN̥2biI1'KGs EXZR2<\JQ*#st 8G1Pʈ%Ŝ,!,Γ̥2biI1'KGs EXZR2<\JQ*#st 8G1Pʈ%Ŝ,!,Γ̥2biI1'KGs EXZR2<\JQ*#st 8G1Pʈ%Ŝ,!,Γ̥2biI1'KGs EXZR2<\JQ*#st 8G1Pʈ%Ŝ,!,Γ̥2biI1'KGs EXZR2<\JQ*#st 8G1Pʈ%Ŝ,!,$ĉO(蝪j,|\(*i [ғ} ;",ng'&{?yz;j y#0arIe$FId`KS#RM=3 "PgTap_"T`[&M7=܋XcgOqn|!C%\9x_$e/ 3H$F ʖ8i2c1U88ߜ4g@IDATMK7kp8ؔ|k;}s/7[BI-eqb" SW˲k, 2\;k3?t!ћ3ak?@k (X8;ħOYH{_}-5o%}]ĉOˋxtq /Sco@\xت5˙_ӧu OVjD5Yv~ڲYs ULÜMm? :4d(%6=ٹsI> 5^ueg}iP .[/j?W(> j-_忴L?~S]\\~n/_azoA~F?agr_lO|wGf "i~L~oCt1wߥw3YgmjlKZ#h?'AիKͱn5w$/0JS P.4qb)Y_QOE_`FRE/qkr;Rgןc1bj9K8 \SF152wO^%G_#ڪ 6k^s/j|x>ǍÆς1T'>Ué9ԜRZԧOZ}5?‰=˛뿍%)qQƧ@n鏿K.nGwW^~IX(`Vòۮ,/﫯5!7>MeIv+M.QTUnZuUQ^E?=NyioCGqT//d<4f4 6LX8=ޛ:wMD?`#ϥR~t@!cr_TxLr(Om .>]'\JX1y˂y}lwu>Y?* >)L;?apۿnfۿnfҐY@}07?eBa8mƜ{;㏥1w*F^Xs {=N;~݇VYe؆a]KbF!Ϛ5vhuNűbGDJa]#!Č<+:=5?bOC9x_}ǟx> ~L诿޺t]: +4ݲXbFDeRit-3@8&"G.2LkqD5r1S AAjE?zx#N04b@$O!V&mD'ZN~R:if>$][8s`#Yډν<.㟧qc]j<muɒ#Fa6Wϛ#zzk㤧۰Ia t&؀WN]Ze5ll@g%8p_h%|af~93?ɺ^zݷsioԥ6wV[&OŻۯZH_miUV^^*M{ԧ[6ڄ-?+'\W[}u|n7@>3OF D4s _qŕ!E_"7FдᴠMӼdΝ;kɭ_>iӆ|M;S~hmmHo`7FS߃hVwY/nAԬysdMh{G !Oq˶nZ r,}'f4mJ[l%L>&BkqOՇ\4\l˯J}>ٳ6>MUQEpJa5g74gw O'ڪEs9{ޜ$Ƶ Æ߇(˱y^c ASMd^O7q"p;h[U?a?IOLܨ:Jdx\Bu?aʎr-_׿}NQWF@&_(qDGJ-et3?dZ1p9Hvo__a<o)CjJd Hc%=3x[jb+o?7>%JV;K[o=5pCZ|C`˔7'̙3Kxᅣgb!Η\"NSS!ZO+ gm _a\^9׵}Um'=5h; A ջύh Dסwx!i!@R;/#` MN-;oWes75s)'Hqڂ^g} f/tS+ |p~yɊ ~*|ϻS̳:{ヌQIͯ7k-DR*<+ŭ)o'\|A}U`-2$f[oW!?$~HF~Ȟ@#xY+?rgj,IvEN~2ElP AK7&¦Td0-K/-eJ7~i_3o?>0/.YQq7+uhu}{Bxe+/&LЯqձ#N ׇCڿz °=fc㐭F*l|B_ys yp>?-ի[O“^z=zз)]N[SlJ;8^|.zO_ kpOMl(uʉ'¹03,T[.vmdFؐѻU'IxP2\^3aG,Ͷ؂zft[J#s%'S~/jSO_FVۀA1fc 7\ř!(ɽjڤ8nBu|B_ڴjC3>Ѭ(L}z]~|#U vVZ ̷&ڼィ{_s55kՐyǿu/6љGOF׎Qo66q7q K(tya2dP?r+zҙ;u\bfm&yg^{N#͎pSN9c&|'S ֣@~ jIE~&'n7LxqBoAÐC!xo9}3ņpz\D`p݋//KM ?.2 ?&~Kr1ϧwp ϿןbױH <$a90ڿEO3ngo_]?&pv_u?_ѽ*Swy^6ߪ%m^[_ynR azpqtXR}Dk ^)ap: I%$w'k0/F6Ғxi L>ͫYvP&@@D)ѡG.V5f~*⋒[/A=/@"gtq'1H{6yƩ 3{j7q勍~V$,){gT:y86lchq-9P뮽;zR^9@6Tq bg͚mfOoLL} >_h{ QXїJ>~Jƿ˟_hSsrǟ“1@K b-(ֈ.0C[4xiJb801(Ĕ=K~6;ԣ]p3MA>Wl gzZLdi6wI@m 2~O{yh4b ?8N|pSmw݃GgqUԱ6S;Jѿb3ŠAo6Zgu'{ lAVphk92ON##G }o)Mz| 3't^3ԊjjѢ>/}h%ٶUU믿00`FąUou'O_>lfҞ^Xt~g-f:!34`Dy\Yt>9bd;p:ӑ4-@W\z>"$>sΕgznHjliILI?csU /$@*~pTч#8& }Qi}w--o`DجuT1oE[I]nOFJч8m @}5[q+|$0λ+?3=43 5jLZ '2Ic^裏b,/)vGl|jwQUCp945 5zm66>1?ͦn6tp|՗_Ӊ'帟pk{\|qO4Z!71]Bv&MIb rʩhU ЕW^%f#?RuՕ/AB'>*z8G_.O8x< N/S3x . ZӴHH,gHB/ɛ%~;owx@ȏ/ ]?Ƅ?UCȴ+2\͉>[qcJb}7(S]-G\ӛzh|ퟜn8GȂuuUqiYoX߿0Q1/Z8i}QԿ_tʪk{(_}O^ͬ9թi eHcKCz]t%dfIĘ,()aͣ@Y2"Y)"W^ӗ&cr'ē"8у.ӡMsDzتEsd"}I''zS4K_XpGuPgQs_?Q7>q%mϞ5vhoHu%8e~:iSʳbVR*bK XpHt6 _.P 9nڂOWZںvkRx_|wvK?ͯ8 XF[Қ`eLq[l1)*%]@¥Mji8Y"TNR8k -p@Y2"Y)"Dd7^Ę%#b!ZZ;NDv`?d4+#BvVe"PfpD֎Z SZ' Ѝ:^ǫ)W)`4,BTAе4qIoT%/=~m)R;aS>On[ЃȐͣr~TTP }t$诸BCzp^@©='㓔ڷODb(N)'7>q 8y7H@G~t̙_sب`1V\7zNΝ@{ѹ26NKчֿچ:`ϧ@!PM;ﺛ|\.60W^yz_qEͼ}lDG2o*op8Hh{= 'K8 ZmU[EcErRӿ< }õ32зL}}i[> +nͬxZ]ZUƱBf^?\{-u$6.^W)k)k ؤ8?SVNתWr SLݻK[v?4}=peqJ65rq8Mm`SYqm9;o6Aa=O+^Q&.ۣ47>Ohy0_ybo 6)U>%i6>mЉMtlcS_<_'*}ŗ42AnG9yՠ.t̔Pnꃟ_N:{_v饀ЈБrZ5{t'nwޜ g9 6GM&)!#`g=v߃λOR'ulY/`3b #ڟQ+\?n"nx/άa\/QqKeAE?pe@~s s۟joz=nÆR[ƈ?ƆH&,aN|g[գ8 Ux/k6\=-Zd|ZY']zי?6>i",f.hL#VU)[2Z>A9,WMrS֌Jck{!tBl~'L;/프ӷ{ʉO%uɰI6rh;R0f#~סx|ϙ-%%yExtڙg N?:픓SV@{_O;e&]èUWbD8-o/l @ GúMm/ L(sf+_ﮛۙ<- YFMdKmiӷr˭gtӚxi?A-їVZ1N!xB ֚ŗ]qhZ 5 } j.]N# mdJaek|*kcVHh%i,V|*W3jUvbrE^EE(RV,|*w/WRu7$+)k39ϸW3eO})iq   elhcJٴ .䧧z6 Mҽ*l槱?v8Af#pcg!,<& ,?r(ط8 q(_l. Cٳv OX}lR)f Ўn~ӎ>tldொ(WhW5Wƣ8nM7(j N.&[$kVt'FqGϋ"Dta> 6};G\ i=5:v8xM>~`zM'3goݦu#ҿ[(֐':Le]3gY\$Ua= oF0kǰ.g*NMօz>6:L.lUWw8S;ZN;b<|'xGQݰ||ytfΜ&ON|b9gM3eLpbСԸʒws_ bzpGtYs;Vn]Zp87^-63_bEŠ  8'"l'>5kS@g˛ Mb+?!C?y^u)DbM|<[-&Blj׾? 92-Caiu78 <1oDSQm«/<ύwtGv uUmp5r6}M8co??o޵B7퇍dMO?3O?SJl\V!C_y8M7݌O8봓OX;<5xλQ(l>~$}.j{\Tu+/`7??ryܸ3|s/@ɼWR/?t&X_ֶ|vr7B?_ԎLI?}Tc0p[w x/ l|*؈N84jzP_8LĉO1:P.hN|®)։@ڒLB`"|+NB~V!Bq̉ iMH\u$ ധ1 uk7>=`m'֋@h?:qߠ[B}f=DmV+`=h֢O>v~mݲ=8jDXVKw[ĝ gKߣ4|:a܃}bġ]#sϢ=/ep5ݸN xjN痱 k=C\s5c;駜"GiYve|{zy'0㯹Jm]b "E<ۭM6ژv .{!9+z]Sl4F  >%':0R "/YJ"%d/6@,*y oKS9Hq_wSp8-Nǟ m&'>:7ģW+VS~{mqSQi H;$$s= χ3[]2P,Ugf~`8N"65fW⓫2P6~Fkɦ'4k˱L}c5\8Qc#ConJN4Sk~Ͷ8O/E "bNԶ-NA}a2xT pR N|ZoUaԱ8iʧCw6N|ѐ=nu8ц5iNbEW[{B_n#„WpBBlf_ ^ r=h%l?cpL4dN8rI4sRƍ> Rۅ{oƉP]n]+"z5ԡ][Ni6AHDŽ/J׾65ƋQ?o_IF <sO6>OtKӦO7& OL1|m'nq'"ݥfpË&-2zJ 9g:/YB?O193,9y2T}C9nVTh)k)=.Btw@8w+jiqA1b5N Ҽb ٖ8* K2b ٖ8* K2b ٖ8* K2b ٖ8* K2b ٖ8* K2b ٖ8* K2b ٖ8* K2b ٖ8* K2b ٖ8* K2b ٖ8* K2b ٖ8* K2b ٖ8* K2b ٖ8* K2b ٖ8* K2b ٖ8* K󌪜n1C hoH3(ߒUoڲZi!_KV2Bu6? pۏ<0>g*ӿuqN8ũ;#goQp6F.qLxj2}mhQRr˵s?5('`#G*_4p 6sņ+а{ ) NFyi9%l~a] }\4?v6"UѰXqI򡍢mpbԅRv=/&?Q>΂;oҴ _^]3] q@.t7hLo﫯f-  :u⭐uG%;{u;a^džaOԱg: G`OZ5gSN#8kͅ~>@I_@ !_˞qSs+?˻c/ٟ?8"*S&?"Y][?| ?>b'?6uK,t_#džnT?5jsSZJGϿnB?rO"۟n0$돟9>@'>'^֟7>(Cn޹䓏٧O?u9,7=)?gU6>.(u6d#$ 'e(iF3v\~ t޻ )G 7T~vё?qn/ fcp 嶉40_Ï?ѓcËneY>Hz{g3W[ zU.t''W壎>N=Xt}'g+W3Ti:L*+ ofͦyS?ġDn?diS.xYu;ak$/H3D=٧Kxw9N;dD;/C~~6"1ǜ9B_Nf[Dՙ/?'~}Do pMR6Yt6U=Q]pR#l:7y‡= ա\:r뭴NWJlhti` NzJl|*'&MÑu9GGMxDSߝJ:@9?@ޚLu&fso9Aj0'YgCg`l+aM7kIir!Z.эvn3Z`^lK/>U_ӿ`6 _8qy.<LTҿskWQ?dǿ _oǟ??'?b?>]K/_.ۿ-3BYvwKcsrn֢v|zԝ}hMhϽ~M*+МCcFR<اK)p:l12ryZ(HlA!P8ۈ@Kұ^(AI32NCO%X%4IM=J*ef+dp7? '>en_zxB5֠g~ }'7U]Mmr+z`Ԉг{n?>ln[#@_|:w"UtggˌEZt{`/÷6Ҥn<2m:/18&NLues6-k}7gG|\*{dlQWPKw5H*D^yUp5Q[hwOZkoz$b;M_zouťxlmoN0wc+T"@ w񧪪8dlpfT7k;i_׬va%zyA6DQ!bwlȈg_GU &snEv,Kfxx6- ?4z `T9yTZ$IVn Ak׼*7>=Xj//=\?R6>ES5ħؽԠ}Ժq,6xTϛZH/u]DO|Mnu^kVL`3_hl|b|7tqX餓NsasנZIoRQ|S?'Qk?сVeߐ!PzGuL6X_xqo|?">}vҿH[qɛеѣ@\%=K}>C'(Ƨi}SNWcF\wYyԳ{7zNZc5S407<ب,ϓS鿭^Bdl|U}9kl1!Jӡn(P bAGǽH'>5SyÆ y(vؑ.R>S*ӦMo?l D3g̠S0n8#iwTiT7)'4,p'>ao|Ms`l|:}54akt%6D?'x9q@VlZ K#0\x i&.RyD_߾G%ޱ<?3h_ {r/' *_n/ Se3ǀWW; ǟ]?b 6k/j[G߾ӥ?|_,?pstS~9bgN?r߿1ͯRM6 lGkf|cEha 0Wq<Ëlؽr>0pqJ (F@IDAT5i(dmJ0,V#U4l-`ƧG *j{AP/L El|S_9,}̮{}ɧ:S|B.;6L*:33qbkx B;.A5^/=>:RHdž;)RH " U:ދ`A/-tIH(Ezo3w%#%߻;ws3sV""K!iq^x)hHqC X""c7<;0zƉg?mh^lEfyyب0oe>'>d[,xȏ2s'Ӯ3vSOaխMΰ 3lXz|WKoEF`N~ > _y-`ihvAa>ezj\D;n]xWq.]/.YT=v| 6ܢ..yM즅]xi:qO`S* fGl.3)kvu W1q^I6N;;\mdΟgշot,gWxbpڹna7r~l&,4 %%L=4cW)v|fSn^~Ϯ_׿}|kA }CÇ8^&cZpA,{#lͶvMӸ\s."js,BxkveW3"5^ 3vu7a;ct>;̆EۖXG /M>  PVʿ7l Z1u1?޸~Ӓ?mT28GOϻ U_OG'Lhh"h_4dO~e=Cw?V|02?uua=!#O?)dRIO}Gװc{ͿƷ:?˼lqY?ƌ|^`r{@>y3bbGQ&RV-3RZOڴ1~[ '/`h-xgC\H,8|Im o[.eiUkqKm#/^{'C>q CO=ɾiöc1>x oۣaͶfa ;}yӀF?h=®;zy8-rF}1]/}ɥW#k?̰r\, )sw[n>p, s|L@Cyjf wy{[a=X+=a 70䛅eMR%[xٴTp!YJQT-5@t9ZHgJ}_ۛFyW8!aVF! +w֓6mq[8 ozy'3vlK۩ni oE].gI6#>X2AB;2$GofddowdJI %7kE'?\_S~S1OR:Iaa<6J;AKb}`/1T3?!㏻7!^7򔒀4R2Np7y3͈{SNUQ(M^x, ݻ Í: = ͏}!XhfT)+ CMP] Ca㏇CǛM1Ɲ#>MۉLctMgo3`KQ ӎ;ݣ<5hJ+C,@} -8?vu: @o~+ 90TSk]p}rpXcOxvO&/(hӍrKf°~?3$:Ab:k۞1Hqy.퓔p.8PN%c/iI@)r Hjጩ׬:)]QKAAٟ?مhg_S5jPp&?2gU_NH鿲?eJIDOٟЎm-[7'#}j˿0Q7)0I (nl+bk~v|*CҒBILgl(z[rNSBeySq!.|bˆqSyYQcµ7𥕎Ʃ0VuEEհAy^ UYm *Ͽu^b)xgJkg_ap) +ֹ}]VXlW~믹"Ӝx7 voü΍$/\i˭ZO®;P?PێOK.+l ÐGdCþe6szXqܿzO?cuF<2˂ ߅{=j}YA 7N< _N.Ԓi9m|xUTRAUi?ɿEQ_JKfyISQRiiMg^׳`E,-?Z:m^n;;ԙJt{ܮ(?#?'K/ݐE8^,';wco;#'}0ޙVep}X{e_uw{1H3#褺W^OSbG5;_%ϡ3\ta"#B-{0`1A I.p<([ͻ\S݀m^:n ✡κ`vn0hxO7_Qqme|H\t?3y;3cFKŒ_doK;>͋:]aG﫯+vaEHď=X?x?!K_Fz<rp뮷rl,|WiMf p i?]MA^zesϬt$cw9ڽKu^ \Ҋ+3 ?8ΙrxO}~X󽅾v겵n@Ч>gw8i̳GOpMߗ_Y8xtb݅XD7e ;/&@ع\yg{~*?\rq}e0V~>&m?xeYQ\ols4wi'^?p&nO.g_zI?ζx?ƽ{\ႯOa̶;ɭ5}(IS~\,uW)A3τgy;^"|$f_,?Bz`<e?o<\|_-BO׼f]?%/34Abp__e'O?F?-g! MFYro+@5/(˧|[{]S@tзM1fSONZGd}**l =pxݷ/YqU÷|WxG_ {;>UV]BI7*QR-|* C7󙶵+D]bBgH3_nRO?2g,[Qc+^zm !qdk^ uAXgk~j͜y6_H ᏿M+* ai,s[iA)~dÝ[_bFM6Z? 9vgt>g_§O+aQs=G[Z=Mzi,"1?i[rY,|z7,aعge<>  r8 +:>m{;6xAm3V[u̿bVA\:x W8춧azn5_l~Seh"\l[+&sOZ{[+vRSHMcEza՜a=ci1iOsK @<`tvu8dZmIɟ g,.9^ &-4N|iOSu}B.wMյ׆N1>v|jf ;% m?w9j0v|A%EfFg@?vs:䓰+>P`G>-ݧwry_/juXe>"\8ahԁokå_ˊʩC<|Gs qdx㯻wq'{;Ţ7P-![?XTF[N||$U;0,3@|i?guVs[m}ۻOpǸ:7pEL5aw5\{Ν A}냏 |]Q!huCO?#5\W^ ܑ?u9Y,)v2&YXBB~ Ƕ܇slݫ董R`ہĝ\ˮ2S77zƄ@<@T_B\K xRʼnb+fq⻼3??>Q*e%9CCU8W^usbӝ!6Ck>{?K=ۄG[x-qᄣ 6Xy h6h/.|¡/6-9.JCa~[ViE. kyh+<0S~P [;>ᥧ#eB.S-lvޙ^&imw0§7Ht_sоh#Na=v5aiWu^Zqe cIOܚk0<̳܉/gʤxFW޸ EW2 YFO㞩(hkKLbz;Yulyٷv #,ݦ;g3fLUwFX,7 . _lr! \m E%7B{_;.Z.p 'ͷ/AdqO<]ƌ9;쳇S݉4nx|cG >[Xv_?ȟGF m5}C. ^L|IgLJIn=w_qc^?(|fuo{s܅r;6q)ؕxy؏?{x!3vjZal: -r:Q&-`eX4=r]ևw 3_Xm5⚜6\;q9 gy'^-wGO(k^kq'uᜳOϲ)WV +JwW> `[;b of{ÕW^i d2)f`' a*#nap q]D0"ƅb#rq>jҎ']x)ImRK]T%IQ+hIHj+#?dafylvr4eN7ٿ[|._MdK!'6HQE'TC/r/h479"W?v}oގ{Z?}D~#x^zIv+/_j4pGqr''v g;mU;m#v#oPj/[(+qW{~᷿.Ef;YyO:_O"Wy@oӢ:`A3h*rX <-Z\=-OV"Wy@oӢ:`A3h*rX <-Z\=-OV"Wy@oӢ:`A3h*rX <-Z\=-OV"Wy@oӢ:`A3h*rX <-Zqw|) >dSA m*֫sg@) r&l_(+{ۚw#:b?vyߤIIP[WQGÇGT|"T%_}uG?t衩u_,v>ؙg.} \x3_6G5kpyM _;> Ģ ?NŮD _|-@'JfS\<33ܘ <;Kg~8k%Xsw}/([}h(G駅' W_5zǡYtq~E4MWi§r9Px;>A~y`|b!˲.ݼ / Vv_ p~}p$wֱz y;VL, zed_;>}6GFn]hB}ҎO!§)5_p,#@"H QW]ue^쨮8wz_>~xEC9.CPU;>%Aa饖YqgfytI\a^{e" /lck5裏ڛ<cc::YaٿVoc,b_$SO 7U=?Z"S]+Dz{ٕWi*6'o\?w˶t+YCkϟߞ?+ؙ?̿~1~jOlM]?BF0(thUƟƟ_?4rfh#PdyM'65fϝ<?@Y@d՗J#'>t+"֝ E;di=1Giƙ4x7^/Inj|' J§ImPVb0/T8AR?JDŒ-ƂGG8C?~*8)yIaca[%e&H,r؊/EŅU8/x)=vۙ$+ vq8 .;{ [X\vΙmߋoO<yxtj!1 ͷn5^DK2hS~qv_9f d>j[co}#zζv%[9+~KoytWfV*2AbJDe%/ 3Zi!1bRR&t(`rk-ĈIImPVb0ȭU#&%eBAY f VarH e%/ 3Zi!1bRR&t(`rk-ĈIImPVb0ȭU#&%eBAY f VarH e%/ 3Zi!1bRR&t(`rk-ĈIImPVb0ȭU#&%eBAY f VarH e%/ 3Zi!1bRR&t(`rk-ĈIImPVb0ȭU#&%>k/ho!/.<52ٚą9Yna 7s`'}\" ke &ڛ-׿{b-Eebɿe31`Z,nK.ΟmZVFٞ9&t<-N xܡ¦ױQ{9w?;KX;Mݗx}} NS꿋/§E8lծW1]g<Ck4b"av sb',^xp9gx?iNjΝ~bѕC~}X'dʝq:Ps>vEr$23aC}@7_]y%qgaFԉX='A{457X|ΟvX\l%p2ƅOej =0E'vĿ ǟp\6<MIPlhϺ.Oik5s'{>aVhß-h3L[jN?n_9NHiO}~*_ADfOy$⸓1͢"4h! =Ag-fhEph_Nd`1U߲$B?C(j/qTKneF|dpdX4{>Qx̖1_LaO+&TRa GbҨQO1/^s2UGɳ:WTO/'Q&ֈđ5sE63%TWY-.|sqSux-OYⰧu^~啰 nlX}Ÿnݬ =;,,ܳ+َO]g kŝbwfXvekVۤv; _`g(? v|:;>7>m;p'?䨟c-e׾jkm|/\j Q~|N:) ;;,t믿./1/xVXe+ӎX,k윲v~8õ:¼nݍ_ƠOIQN\;=wԴrB"?>`=%<",&P\4ϼ,-1~>}>}>TSMm;M=TaѶir_ a0= SD[@;|>x?12|v!vTw9++U&Aw0/I!c qرqlM;lӌ)ȥo+3~%<.E)? snm7^k{ym7iHʃ-{Et7KXߟnR8+=y#GAgc]?˪V7X ŋO= SO=T`Xp!Y<}mv,d c +Q{/Mk|j#pM7'Yf5,av|qJ% SIog;XIpB''C J .jRHQS0o\ڿe>"P"KH?JA__? Dg ^աg+IWfGV=bT1??cF>\N ;F-#GZYE3*E8}dd3*ƴځρ;?Xe <&\s-F뭍ƚ/yDquɠIq!7YU|r_ic͋a.;Rb!^­<#6,;KiΒ?|+>2[}UÚk,COx9Jˣ|Í gJXg`R_{7ߌA~H|McE,]we0,|jws0`ސGMuvo ApNĽN|tË/{lD83EH+3BЎur8>_pw7!\|ac./ E:QX\wo~F=},^II&ǶSvV6ӝ?K "gd]/.Wj$K40Q.v6^ ż}yK(L+M+I.pW%str2ŢɎ$[V^Ivx#'?ls[%ecU79o2פ]~0`-m\dߗDwvN+ UQ=vǶ+8qB/dPo@Y*dF)ڟQFɀ$?? 4h:Gted)K'oZ?0v%?%3$XoPER+/?/C8s??\#aW(>8AQJǝE -KkC55 D M ?;7}/KuB4(Lltmqձ'ҹPX/KM_i5l3?$7&]U-N<vc,w.3h|E[~W'2+;s,8Zr&M7>ͷ;v|Zv|r6]s_` PX 2ve0z'2{c6X?;>mj;>U#_7R4xcE.@3ϾƯ@m SMpfwj*cC^|⟊㿊Ó)sao=dusd6( _?6ϊ?+sIw#֣nV?O-if9mB_+!9W%-hGoǟ?' >ċmuC;?TG~" >WU=`o!4~]"zP+bǧ9!r/"Zqd_'mw zcVopeWthܳw}7,26 GvhstalG༳;2j|.O?Lz|aV lvZe9Xztx8l6!Gm~ A{axdXY6Xoݰцh~,8^~a}i\HagG6"kuL4&saf 7L4>(L34F,kWᩧ_; !oݧ6W/2< x`/s /'];~]ۢaKh_sC?J47ֈ}N #o̿aǧd$pn3,@},ot"f"TcYFM'S7Beqõ*Lkb"i] AkML 2ܱd $g LNLcߎtwWKk޼Uejdi)&b"];򗿢Aٳ<-ҊD>K^o|t♈Om`R,O4`o^L =EȐf2?6tfǻҵVh_3SƐƟK?ҿW4WltNǟet Og&?eOɹAWҕ]&ٟ?e&!-Ct487HsT ;pd5&{IbEȄ"[/9j6pl_2 ]) ޡ딇T)ZH)rH^o,6J]WZPb3JcF{?c?N4]~V\ O)A*2=,zꃝz?aLa,|η#/$o]I{_ >D%W7 HH|N-|Q'8dZаf(bX|5RZc#mwNCKjQ?ҿ0(5%S_9){lKARJґIc*gAH-[8oW'\R-eA7JC=!CğO?FJA?&9f6؋G~!>Ǡ q!+k"?AV@?0 #ۚ.xv0} v`)z~j]+>x0lXMJư#M|F!zJ qK |q?ov7oc6PI ڋǛ3C_C{-E.su:K 4ʑELX[iNˆ8*K%?2?韨WͿ?dfR?e2_?cV7QI7UYgşV]!?y???@ԇšzհ=">3BAGմ *EV /IҊ ~ŷ1dv@,`~7GEJ 9x?VwΕ۱S Q$Co[xj'~b1] 㟈a5ˀl~+ͲHgW(?a?"|od +I]WCdUSW4d $u_ 5h=Cϛ1H &x}G_uGG5MzcI8!A/d=A׳Q%lv*΍camKCSV(8FDtT2ſ0xV$)x?C ږJ@ NHҿҿ=;귨%W+˯ҰrB-^M,z4omcjBIR_Q)dݏ(wix'";M0MMZEow)[yGGO4'#)J$9ɳ/_fzLC'a߲Ȱ.Ҵ*#C/_Q)Ş4Q %KgDO3OŞT&iZ2_OѦDAaǧ K"teD%/LVCt:*4x-J i먔sNXŞ6S(-@RΑ:qNc{(N٢J9Gz9^i8et:*4x-J i먔sNXŞ6S(-@RΑ:qNc{(N٢J9Gz9^i8et:*4x-J i먔sNXŞ6S(-@RΑ:qNc{(N٢J9Gz9^i8et:*4x-J i먔sNXŞ6S(-@RΑ:qNc{(N٢J9Gz9^i8et:*4x-J i먔sNXŞ6S(-@RΑ:qNc{(N٢J9Gz9^i8et:*4x-J i먔sNXŞ6S(-@];>qGL;@ =u`?gNUNrjFXpTH`!v;_WMPr9'#G_?ed4%SP(ENL/R*?DI_(='='hC=zzz篴M-Kh>-|J/FFD1-UiRD8zK|gO 8tOZT 9ig$41U>CxZ2l{֒&gOCxYf#I%MLϐ p$鞰r2I'l-ib|d؀#I%MLϐ6xH=akIS3䀧%I'l-ib|F [K*!<-6H=akIS3䀧 e6tOZT 9iɰG [K*!CxZ2l{֒&gOCxYf#I%MLϐ& b'{Ǧ$pخNZyz"Vk4`BCQ<MQ FknfXV_75jWEl0(69Ǒ2w`Üt][#s9S{hȖ/qоaCW_83rb)[/?+@1Sʘ/(J:SKr(ԑ?Bz?*zK=`E\Hş/zG?Y)eLEGCTMȖR3$h\lǧZP9g2`ᔰ'͘49AFԁZqdN&LQj9:qS:_O3dDLmrN|=ͤNuV394:AFԁZqdN&LQj9:qS:_O3dDLmrN|=ͤNuV394:AFԁZqdN&LQj9:qS:_O3dDLmrN|=ͤNuV394:AFԁZqdN&LQj9:qS:_O3dDLmrN|=ͤNuV394:AFԁZqdN&LQj9:qS:_O3dDLmrN|=ͤNuV394:AFԁZqdN&LQj9:qS:_O3dDL] #" vjV ԂzM򙆕p6g,@u JTmY)sնCXƟi<9Bur*fZi!Ko(8Yd]4,?!#H(8(esg#?҈BQS_ſ+ Dn-[ozl?92ɥJV`sFE+izE[d-Kh?1gsgJ,aJ9g-|*Qq&pzYipՖA1MDSÉȯGA[A[%l W>U=; ?<;OM$l '##8zHg~>OBMm'I؉ċ y\#:"ڦy~,qe_I0I (8TQԡ'#'4h!KŤ lNd+Q<(%~!=BPCQE'S-O'(o)fz1D,Hi<ۊ?*Q'*3'Hş'󘑏pmA %騈DtkL <g[U2`teNV3ぽk3‚`̩q c=*,, f@('c:T F8 .027)O~ C$Ð\|~? `7O `!63条:aA_rI-sW!H?>JT7A_ 0Pku"_?eeUԇ+_QI7è⏊?ƸJ+d`T_>U9jb+("^GTA!UUW_'#6{%5dhċ^u$%\Q8KMnGUULXJ8d &';6fU™ t4X! N; YP%3Abi2QHUo1RJ8d &AUo1RJ8d &AUo1RJ8d &A=-b5MjОnȟ -7Ƃ &e Hy:3$ AOME?(?(mf)9Й g;>E+QrZHWE3P_i깲9 YX\rC$ߧk?yd06f6oku빲ƟƟ_4j*2J{mRi깲9e;>qYD_u } q+bA#OWcu'"9UZyQ.Љ'(G/dn?ٔ/Oq>`RG_Kg8*? 4 T?#a=N~}4f$v|G)l eX4\'^Ғ)Х \HErk5BZ3t2)@B=tjr ƟOIkB7#jpBN/$Pv|N)KNQhPO\9!oZO_NA]x/S+tͿ?RN/ٟc߾-"򿲀)[0K/(/(bnOPPM7~T1_Sh⯊*rSI!}Gҙf*(8j;RoUk4RiWUc*WPEz\D{>o"ZA%*|L\SE\ŵJjUrq k׫&1-sNq * WMcZ***TR\hǴU8UU\+6^%7ўipVPImpJ.n=7WTWqz\D{>o"ZA%*|L\SE\ŵJjUrq k׫&1-sNq * WMcZ***TR\hǴU8UU\+6^%7ўipVPImpJ.n=7WTWqz\D{>o"ZA%*|L\SE\ŵJjUrq 8j;>anI \DzQ%{?:h}IGVϫa-K?ҿ/ҴZLBouKBmhI)[/|D )s볦o_RI'ş0GMYߊ?xQPAşSz S_QE'Z~ԭFSQW_?rǧ&$xl y'ہJ' vߢ-o Dl!6+3UXQP!Be?aP+le 䒆tKT g7;h-ʤ KMײoQ1Uk Ё QΤw8Z;hg'.N?c#XFa*& _O/hOD5ts_?1kD[[_?+O)⿊+z/ IϟIϟ,ozzgl|ʠz z K} KcWi-hd ƟƟƟ_ DLZЊ"σ酅O# h9ߌ*c[n̓[:wuZ=+δ ȓ늿n>1'#kS?A@KJe)[/ \ @o*Q_#Q@8SM7 UYg3DR++{i4@>wF|#oamQ} "ewG%u9uSG,{z[QE ޖE+uT+giJU myZRG,{z[QE ޖE+uT+giJU myZRG,{z[QE ޖE+uT+giJU myZRG,{z[QE ޖE+uT+giJU myZRG,{z[QE ޖE+uT+giJU myZRG,{z[QE ޖE+uT+giъNܜׂ8*G\d1+|..sJC];/ٟ]1H-[}bٱ1oRc҈CH BoM5ڏ-[o1!6{.Ӥ?w J§OmPVb00ʕ̪9mJ۠EU'Ҭ0m%\܈2۠$?vsd0&uS_jI6(b0PSCFD jPeEa3V/eQ3U)>]| qDdhm{k= A]V+4}F_iX22e2/΃Oa0~rb_%KGA&} ypSL&]?DͩCQE_QE_Q)YImG27b=<%!>|yQ/f+xJÞ (a'C_Db1GBGSkZRSjIHkN%rԵikZRSJJv{[4&3 Lj?ާb촗-jb6y_M:4Z'uo=ppÇǚ"V++ ٟ _)sBHߊ?(OYS7LF-h7)S#??H(1#ɶ9cQcieA&Ψ a2~T 6x\IAN620~fm(rm/ I#Òq[.-ԡظF2{+f,"4¡T$CpwgvѐESp K\*S̄2MϿs86hX~>^KD,圹 f:dHoQ\9@Ü QRo.??H׿>~ZrKmF5,n`L7f㮲_ Zןg|o_,-yXXcWxc 2:s?!Kp!;)\M*DKzQ#j$_Fx8pr7aJSp&8SU AR1$J(-̌6Il2씰J T WXsNpac??e0>4U>YOa\z l\@Ƈ?|O_b߾7&H?/'Vy{'sdm'?-E?mv_ִ?]6ߐ!}-$wA{EJ+(^`g.ѕi.RZ$;2Yls+jRr2(ɎLw` O5)9EJ dGEV0\JL"J#]"+m.ԠQCEx\ֈJ~ᯈ*U2ÅS;/(T8/v2#t }H!a?3, cÜK%_|r`{C6W۟nL_S_`ʜ慯?X?3#C.)?}ןv؍pBtC01E%))q0&7-X71t`b ׂ=JVI$I ]c5,zSCrk>Lq8=w! o`OTczgy!0!drQ.6xH"5_tH??L TTpdƧDVrX1x>h!&88*O?QM?63ބ_f?>۟lq%TJ|o?OrR9$A5 pr7yىG*Mofc$߾8M?lxV`,oF)Oa(r53%ɻmgdWJ3wJd%YFӗ5_.%S+\SJPհQxTjHƠ695 U8 z6!%dU˟?3:<\_?L/&_̎B' *`߲dC8#iʬwӳn.C|DW9RO~p[8$tHl"<ɲ_&5=ӱ$-_Cf_0=j#۟m|2Y$v%' @ eAg']7e-: ze˟H??C2v)d ʷ:&uϯ? m.cuӯH°2D~቏xeYg#CiPO??ؿ>(ST)ɎwD*00orjU.>Hq|A?, zE_G3e_n'04D}2:2D$U_(;|/_RX _ןN_S lhd_RS*aZ3r2C(p,RYxmaD%$4|RYCͰl !&B-4je[X$7 7bh!P3,Bv& hD 9aC4M@'%Zh1 ˶Inn>),BCfXMrpI!fr 5ò-,dhO 1KАcma!;D4|RYCͰl !&B-4je[X$7 7bh!P3,Bv& hD 9aC4M@'%Zh1 ˶Inn>),BCfXMrpI!fr 5ò-,dhO 1KАcma!;D4|RYCͰl !&B-4je[X$7 7bh!P3,Bv& hD 9aC4M@'%Zh1 ˶Inn>),BCfXMrp7ĉOeqisrğ3JeP{9C B=:PRN sѻ׿>6ni0i_PK?u_gζrߟ')G'%I|TkJ|'>P+Z"n TXSL24(#Sx 0%XzҜbJhQE4#d)(#Sx @3*J9Ŕ,!,L `E4#diTQG,)d`aJ+J9Ŕ,!,,LR=biN1%G SXQG,)d`afUKs)YU{ 2 3-6>yė?1tt8lcBҋs+QJ  b?wE&'?ǣԅ Ey8_xj c%n}ud@ E=wX_?}o?Olt$ '? Ō'9ɐpS-S?Y$xpo_d/_߾q ƪ‘Oq\WRMQ,B.Wb2C~cXi p?YtӤ? s\ 㯚\}WǼ8,a?z7Jvh+?-*Ӹog]rN@IÄ=)ƄbBeHebit-@.;F"G.3LkaD5r1qlD74붕H?N›M(16W'jbcy͖q%_INPplrFQ??!?>۟NT] le9_qP SK=_ןf/q~u7MbЉ#s80m?Wg?|s#:!U FUp v^[ay6ɰKNcÝTa_?`"mb'CU?FQ1&t>ɏ-?} J1>đh^ˬ+d߾Tf׿w'X0TJcW@ t_˧V wYG?Ddu_FFM$"~c/R0 Q@Y4"I)"lj˰ʢ1MJ͝=NDv`O&eȨ4)#B4w8V83i(FAIR8"D@sg] LZʢQPҤDd?/h4)#B4w8kبNʮ%7r`Ǿ_#IB38 ]51t͍8@tMd0.p_|) \RL)f.eਸ(w"߾`=!"|O_ן?f?_Ap*DFT\;GHt)?pf??0e^ן՟VXaƧQn&@`ui^'Kst+2+ե8Xoӵ˟8X"3 ɹXZǟ?j.ɩHI\,J@N|Cfqj V!E=; 4aF0lѥǫ.>\@9_nu?t,_xt,W,:*w_hF__%]12쿿/\_?~H& t[um_d+? _A?}?`L&JOЋq_"j?˱7o (Wt*ĮħJUAQ5eqEOY K2b H-0h>%zedkci Jdkci Jdkci Jdkci Jdkci Jdkci Jdkci Jdkci Jdkci Jdkci Jdkci Jdkci Jdkci Jdkci Jdkci Jdkci Jdkci Jdkci JdkciFUN|N v2N+iekCi(S:زW1ʗR,B9&5kBWoM9r0z%?os7?~u4vQ'|OinptO?69`3 L1-i-g^Y/r䖷'tG?X,ecNO|ʯ|D.n-F @NT>`A+1]XN_a¡ &$O/qa*_`_aLQǟ?>/%Wbc(ܓ_zȁn_}?_q&_7\?)tJ"rG?t87q]b|VHN|JV" %3w\Kz+qb̏@HKY%Mp2|`^D?Š4_|7L۠Q0%"}bmSNN?RX`!]r6ky;H-[/?'ߪyKj??0 >5sY\0XE*?fe ??֬|n,":O>r?}o_pOs_)?/XIGGfG`2?Oi{oPy Ө =DM|0#I=2hj~ҳYh5ea' j|9}C1 # 3"n ;IP|;OYJG8$qW>erbơ,Ԝ4?0$A@/?_&'YhBI#N8rS>erbơ,Ԝ4?0$A@)5tJ b:uI,~X<aV FF2_wts}oCk֫?0T% ҙ J=:8+^E?K?+&B9\+_E7ʡ˟9k}SK\ nn>}6ڝn}_ןC7<_Rt_b~' '?oF-czzeo{dl|HV^( W8 X [bA:3?4xU`?W5N6n( QK14/cP^D(X-!ub%3 ;c4ny–ZR{Ilv3y3X<r~^ Q˟7ƌ??o/ߧo҄jǨ5x䥶vDžkQjђꭱ&cg]fc~g,ո&p-O<2&|YН_o?ӦYCv|cmÚt "Xswss?6 ;T+93??/#0iD>gPXU`u,WC}Ӕn۟jKj<#ռcd^%p(۟nٟrN *R█xħȨL2ꔕ՘dإX91;+iY^qozҼa0A`9$5kݳ < %$;IΡt&ILbfg\̠"d' XdcbagpAgd' ...6\bh#˜Y^%JNIv 5=|f$/+U~с-ʐ b4-m(jx,vg(grJ/_d2:]? (_Ndlk^.ըzQE M&Ma._˟꯻?,3vi}yx- kUtI ȽM,lzHt~HߟEj֨A[m5ڵjiС4u4?rn2Rm#V<^#Znѝesz u_wF_* n4+|q_SUp_c,$?q⓮xu[zI;Q6> $44%"gҗ+)ƫE̚.za-^L**C%\OO ,\\ ҔBiA ,;˄ @2.Kb5'e DLg^y-RP?¤߬Դi p:>׆o}m %gPBSe ,<ͼ~|{ァ)Dڜ?IGaZaiu~TP޽z`﹗^fil? gˮA 4ll;zꕅ5ݲmSo5k؞MFSLA? zw_g:ԣT^=?| ui8e? g8D }]OJs.8?ǿ?,9|s>_a./?.3>>-FfЊ+D5iW矣_O]2v(s ƿ' <ؿ$ qm & \Ƣ\β%C3 cqS${f7j$'7:IQ*>\sW$m_)1>8]|- 'p@.`׿}AhqlA™'~ALz |9'`6 -iO '$mcR#FÇ i,Foڢ5m!/rs^LY?``dm'n?ok镗^V~Gk?[ߍ}J"$:;fΘןF{^Zpzt~?u]}_1 xэm[@'x<ϫCu]@ߢOޝf[^dK{ r|6>Ad.Fnߪ+B^p>6іy_l?LBwv+ D,t}2˔o￧'w?N]q_bx؟U1,k q+}IR7D??|h|?>_pZD(ßbB _|__b\ЖYVMQthNjHοgL{s |GGKXbMYRu¤|RK=rSOlzK)i. B=r:fsx 'cLRb@kaRE>)%`>oeaRK>)%`>oeaRK>)%`>oeaRK>)%`>oeaRK>)%`>oeaRK>)%`>oeaRK>)%`>oeaRK>)%`>oeaRK>)%`>oeaRK>)%`>oeaRK>)%`>oeaRK>)%`>oeaRK>)%`>oeaRK>)%`>oeaRK>)%`>oeaRK>)%`>oeaRK>)%`>oeaRK>)%`>oeaRK>)%`>oeaRK>)%`>oeaR%OfS$~)A \.7 bb8*-lY\¤߬yKj?ϛ| PTu?wv)9M7hk", u ˉOU3^ k :KԦV_QFӧܿb_{[?7wTn]_Ҍ_p t].4fH2R0wm7:(/><\m=Q]wޢKο0Ⱦ8 X*]p!5n'VwB>:+zRÍ6sr'>EMvTzwzf`8uiClb-N:7 G]v% ߉S]zdO<^yZne;vB͇?N?"i+}nbXsI1nҧ 'usEi[׿XFc3m~>@|b:/&]snL<9&rI/>ipq0!SrG&kooס=ُ |z:&NགྷVYM V9tS bj2I#If#hY H5զsN_6=IOXجMO&F @M7Q'\5-RBM&f΢%r k:KW8RiRs#0G3J eeczH:u*ۏN;$'dAT[6$-Xk*Cٿ\DBIC%B}W.ڟ V[P[c5F Gfkqړ>?2 6<05bPTp_O|A3gͤvmZC4%WZy%ZVɼoأ6r;Ql?nۢ'᠃hzZoQ%/ƛ7_r47;u9(;o^˃a{ֿ /"jܸO4zg"om'Y9lӑ#y9ԴiSi/>4ylcj-[nM'vFK^B濏>ƣSN!ؿv.Nt?aUkk > G}u/to_zaOem>cVZiIU#Dgd!#b,+G3$ Xii N1R0 ~Iɞ3cEmŜnjqS,o~kn3UZkmNau]˯#ҧWV^yjԼVve]V(-HaC;cJ4W\݃nBҞBN4BA,{K1Rؐo6B- S6L?;\2YX]q4+b8?7!W݌S|D΅$R0jQ7^'4fJZvO?@3bG\G i[nYL>]㨡vZSsZah,NBχsV_~ gsZfewF'ǀ(GSF-3&qZjc\,}y >Zw&l63_R8=>25ڨFC~@dK،g!yfyp/ J9hoSi:*hCspM8ӥiÆ 9gEc<|f{GA(YrK+ cy7&ML~16S+e[ay>cߧqXvm3h{_}%v+ow}(8¦^zk)sQ>7 ̲ d47]HkeRa}-R*N-/uŝ*zwK^p>;3f_>K?9 Жgw,":<>]}H!7|g]ΜnژHۿn#g w|ly+2OB_Nͼ'?|!|5Wڵ鈣êOwN^smk37W^,kiZ{>D]y'2vh˲?7zT9f N`crD"rL@90ܓ=lL@$>^\R%țᥚKSeW%C~͹g$)|xnqgo0Ga>bOشQ#뎛i97WuFO:RE]:N:Շ!lt\˰inїJ!bЏ37DX3+C^B^~bhoxuDg: T %0'_1o0/?+J9P.DnI:@cp@Ei׫~i:4{.4?{?J\J.>\Z$g@ni^,<@, `NLpe2相BF@®V|]4П¡O\} .4bPlz!Ir/椦 \H[&=HÛǧ[ iNR9>Cz8G y D|_*O<`` NW~aƹ wp 1vQdcw>7V8c2eJ><e*'l9夓G޴J+qa{Ԓi ޼cD?:0NZ8iftMj*l>l8]sUo)_B7k$zx=իǦgA[lU }˻KW\v)>L??*h";x۫7 SXr?p}㏖ml@gsM.d.N￱):@tmU}KGw=2]v۝9 h?xMճx>(2X'=j-8|RЫC^kZکUhr56׬H=D={F!TѩBZi!0^y!kv 2t=Z6q 37m2&gB<m*"ls`k|+Nҥlx~/ŗ$Q꟫^>3-(t}>QMCS}v`YQ:hH:GNW\~Tu=!o|B|{:[5kY<;+G3:֪_?i O?$LB3h[e+IGt>Lzᄄ=:sKHTCg|ꎳ>4B߻gzce_w-ܶ;n}\/s!i/~?\w?w㿜s2vEv]_>@@p pK( enƀ_Q@_?a<__K0]Ww_AP$0.We=OM/ޭ:KWj@~Gs72uۃ:4,Vd[n0N vw'L6>KBLE;_.6t3qo\%!-"'%ЪH(GOzu@|p{:6=m~mj%]:m'? hO60<)asV;O2sw}G~=7hАV||B6/tis6P9k"M`}Ǵ˞FZ.Tu/p=?%Q^Wо{(<=|(jw!tuVhȫҍ}n(jnsmǿ OVMBӏ=@x/}Y\oFMD1 ^x.20-Ƀ= |,8 7ŭK-ʭ1}MEW8iqi?ojl';=  3 ȉO'('P۵oOml+2ORQIc{-JC:u5x*`uON;dÏr_tԡClOmNzcpڪi\sO:SpǿYr+*ר%6?Gwrl}Ͻ#Hٯp -g\iXc;vĩYaÆQWЃ yE#2l2|SC|`NVtMr?~t晧s.C7|+NK[I3O>tx{g O'L5Sn';UH?ctw>d:A6-r? `g& f?n}lĻrɌ{!:Zv]xY8QknJe˖-! V.]_0}--WI'@}67?&: YӌƗ~k9ʴ?h>*3;}˟?U \g1 3]>}g?J?/\1\w?q_}nySf[?}8~,tomڸ >_@W|M:/:'x ĉo ?/w$֢h7(0x11?M^Hx~POƧb.w//&q%0T`K|]zӆ ˍ='l L)C7Y]NdㆲhgaB:3K-h{5N|Z} \[HY Ǝ'|tez- 0>7uX蘣50_ޢ6>AذsZV CE-,5'~?͌FBkQ #^^nWoMvY _.^Oӥk Xrmݾ#vX{JWjЩ?u;_Ak=#TVz@)~.C"F€aQ iVt~A_̉|\Zgp;9ss?U9xalɁ'%2Y@dX{R F5U'"&i9 I)^>o֌OUkp4Ţ׆xr5`q2)O# ZҴY l|ZϧH%4_N{dpjputN:t}SJigQףt~vSkDZjR{MrB cvKS~Wwߦ5qD[Ӓu@_Plx6mZTotݕNxy_C6kܘvcO4ç@+sOپU+_8g&lmVcM^xU~}qDmހ`?#Gs',: Q{NTljր믽.Zn-5h5.qB.[A|o G`yuNgOК [I)E '|"<i=v߃ U?R/:Iu{aC^z;Jozji]w§|݃Lx D}1x6GMZm̅M9޺њ8i38w\/&QM}h46jJZdGTbO;fwlf;*$:r;n @ jy]_ŧy4u9L'f ϱ3}6ц5>c}GOzh@3tp!'4N:ZqӰO>-7JN8:'DZ,5d4bNs|s|=6>Iθ#FP.Brrv-gf[qtwz^ k"KםwSO/-Zig}?̫gQ;/&c#}zU[xzXCeqߠs#幍>5}/ MNpR]7|3j3N;6nۗVF)ir ]t m2@<"%32'6)*3y+,GAws?|Ǔ^\sgf_ ߣi'wُ*OK>CNq/ U:>؞spRu,nwQ3ro_wݶ_B C6&]V\x _|ܲ|t&ޙ ηԥqD|~Wv{m y7 jAN|2lEXQo9A^CCƭ*eJPJ9I+&:_605x`Z'# ~iO%)Z0E2l~+Ŋ}.$eBvܕ+l|ZWC ԭ4x}!8e2^BkRZvTY9c :u:ph)6jh3|H:ZAՅ:3vU8/!n'>m }lEHKfㅲQE ^8[j 6LK?3f-s2$8~xIThUx{o6vn؄5_KQF5K/q#^WvIR||//1J{.o߶,CҼ2 dLKhaZF hR&#Mr5H,\! @IDAT˔Jy\e Uf,*&-jƍc|e c/ºB?܀SkC>D\NrUIBcq1'6XVd%mp4u޷5[s-qVW9ve1'=& 2fذl|$QeN|)K&/^lD@d;vi[ۉOHyOf[h5|pǎ4gkO"cq_x-=O5+j_F`Juv3{]uyIJ=qwGXqت){9;驧ȍݖc_9:eRO"pP[K>To5H׬Es:"nCϿj3믻^zHxiӦ_6y4|pP^%#?[n%fmecW',/@Yc?scЖ lzfT6mFu_/sQ"5kՠ|x Gir衈۵m#kKc$nSzoz. '>z2ğ>H@J+˵$Sh;\ V_Љ'mbnźr 8/%v߂O+W{P!Yl֛\Å[ qRp]| m4| Ʀ1i_ 8H*ŝ.l6z晧#K/끏4zXS/7q"T_x!6&6S#$eiKZ F'D1/Wn?{wڡi Nfq-kèe7 0F骫~IU|W'xg!PM6:`C?oi;0g}gC;w]p>sE|T؞a<Y8Nj_rɥv Ēud ПⴷLKέ }k??% >Ci:]|Q=kEKs&_׿?TJ}/xf>?٫ǣԗ"?AS}8^? p' ~{G K_Y۞2{|@ChG}vPN8i%y禾/]5~C?Rϧ|JO>0fEO?PP&DiY9_lvOORaF}?'?hUVo5 M5GL{w> lTq-YzZN-cglڢ/Gg{>h^?.Ŗ%K [ŮF 5A~g?MpD+hVNQWlx%N Xo ]w͕ty33G_yEMK| "Llf-w qبqKƬS8I1*>8(P4.2,A#KضbL:L _hcG-;Xl JAk)qAYɆ =l~ Prq[ScN8IU6%Vñ7hmL`7eEmVXR0}Sk> IC@j#|:ob>W9^Ek<@rN|OwiӸ݄OLN8If 6!Sˤ†`gy665?e}Y_r^B_G ?d$y N5;p68p /6۬1No]M (gASƇ8$φz}>fTP_Ps 7 %\K#AI7>N=z\Q~nT*𡈳8='AY03>~f8I6zr >ݷte_Xj$nT΀|bS '罊u5W_ϬH_hwGxxm}1|Oi_֫5T%8F+v0ʃƧ /t4N|brN8d+S&<k!՜OnUt$6L<1# L†Hl9s$ZRz]T/>+Ti9~IyiPW%k~E"%lϥ=|Ԗ .&8IqۭOTeW5\z8ok:kאUE6.%믽^ e-xL@5th}Yg }J{"}$c1,s|8ۺϾӡ*{E^MЁԈyQ޻o ũ.tħ|4dvq':='MCYr׎u`kig%0ś0Z'L"t=MD@KsR/0~gsT?_>\/2SV&*Gͮ] /((InWwy"ֿ ep?K_|u&0 ZBטjaj:aei.~s}qIzྻqX:x^3GRG?xPZyټFl|;z\7'xc8~阉wGƏ4ܸ 0My$b5r4+%#kܥJ1Bǀ*[O7JXB }>i0N|}6 2ߑ7[y}2'>}OO?/[> BY[Wӯ!3OP6%Zoo?RK믾(_$e[wJ&Oͷ>wG:G͕ᅦ꯵&$ӭlک~oKD4ӟᄟriU|NiI?nA dpcZB N|oFJ2N)G7Nʼn\:4 vpm4JǎonzN,_}% 0/Cy;l~i5PꍓN;97{y-l{ƌy?ӋyS-D=UܿI7t:tD_v߯6-,*:=&P1-w'>=[B{PÍySZ%w=yu~lbU{rЗ_׮G.knqMCͰi3|E}tY[/FbRtx#i='Iu&Οc nHr69>.8{*upgoVtι8 D_t5x#x:/"ڔO^{4嗕V?)}~˯I 7l UtR7=-(ZK)}3f)~\B_\?~XrǿFֳ\'Ӻ?[On }DC[}.D~_o.G?Xv;k0DžfO_`x}1+\CF6Ló ȡCDt<3-̲YtsfǶ6|d37|Co эO|Lpc&|-A/SGr|I\D{Iv$tpqB_9GG{ *56>ޟ_N3z(A>pg_y#"XI6Zmg|5Z /?P5si>C_y Ǒ-'u>tYRLqZw:"lI`[oӁ8/YxŮKpāx};1ehJ6>%16d}ڃviS>3|Z]%_ۤs߃tW ZjԱ][f8R ym —SN:/['זrSw؞{Op K7x z-6p~]qӷK@)NzZB][[LK4y'{ܹ4_VO:}| C*% dsBASYZ\J\$;]0P)Q!_2%J}U;4j0I"x .\eWkK*28RQl%BiIMyS>N{MCۿmpZ$NsM8AxH߬%oӬti/wg w MFtjሟp?uvt!N'w*ڷSN'x낻b(AeU ',TeCTsl88\6UO}h];N]i/ԧ%C5kRMlJoS[MN0d > *w6>[c QA]#)N;Ȧ&^p*̀AZ^mDA@%>*1;kDn _ =ڛ:w,_ 7 8UFNfbV>o7|'o=D7j)J[o-R+zlx"ڵkQ<+JYY3 _8Z{qM/ȁ^C_GQG>_ס&ƏAʼnOħq9իqUt:NÏAV 0x0ָg.Om[m"n Z|IhJ+b2xrRw> :c\s/N?,? B[9~6;mf_r%֛oH:~;~&; 0c˯~'Y&Z/Ӵȅw?C!Dm<Ko9~,.]pyQ(>A?m>-筢.&kN:\H?j,C'R auS?Dװfp 2|'|uCHx02׿̌?T3`5tEK%%C)L@]*;Ca׿s|uL׿}vC0yxE߲i3wNZkཟ~8F>TLtؑ]i:KН>{Uh+#h =wh8N7z,׺mLЃ٦D6lWp_;#J}~k=>\Ҟ~ bm[K" vG?lj?ަ-mgg<r>vEtݺsR]쨴2lg{b媠gx'{RH&ba!PFs|em+xH-fja駒fuS:MshA:]1j!߼NƧ>6ʏ L(^m,XgB:!H.PF+i"߬96='aa3E}kOkI2Ƀ!fu6i[&|]5Ҟ{={vP+ bWxv. J {w6,gWEd}C}ߛI2lf'Ivgf ӠVj(n6n .?LJpZwW3olp<2'dI'߾{d=?;k+_>'>- SR`kʆa빧9c{_P.L/0rVe JTC}k[?\OK¿IDQ.cu]s͵2'Ӛ&G5o۶8>˸/>H{8;촳t?r)xs׃dKVxBOs?h|c} 8xɲ2ց3ZT=Cr:Y 6`,"*nKN_7sݺ@a]Zr4N:/U{ySQEO>:9M9f?t {}K.;_VX._|)!z=ޛ~_=ueKr>Ң'-W7l3!Lm֚rpBoxݡ_R_tqǟ4֏l{,OO{i޽ϐpnt]fzao4(]t=w!ǨϜXEdr<ڬ+j\wv3_MD?)>U6Α]S_B{}FjѿyC% J8Fz?lj5Hn8CS~>uB>4f7w׿nO??\)u l\bK?hp/׿\N>2{@|n?[mm]zꖛnǽ9v0|LA>?u\P\s)v9h! ,T2jģI柱cF\oOi/nkgߎW)@РFPj%D/o?/4hsT/-m(mc(~K4COR(Տdmp{bԤfh97ЃpXW8;}K =^<6t+DzEmȧd᥶#Cr|ڨ&<<2۬z2g;Owj/kie /ŋR` -; vw#EX|ټS|IԶpYorMJ> ׹QkхZR{Yg1߼;tG5V'27 '"^v@= FQnv*!􍐶#ү0vrU`*R}Mh>S? E%ܩJ8_ [B.kBτ-ZC Љ-hIWФ:xڸ]Q$,GrEm8ӓ^^ۓzRtzҫG]E+??=nd 82p)vp^{묷iVv-{wS QO>OuQǧロ${S<2geu7L8H+W\Eħ=څbv'>Փలl}'|ƭȿwI:t"9Kc MСW|sϯ'تsg~"GÌڜ:>9TYB;u8P[6Ekz2w\&' ]Ǐ?X8vJ:!Tόn l `)F*ێȥh9:lҢEK rr0BhV܈/|٧ҹc?pn[8t'v9"}z䑇E8 ÉO:矫.JOz7pԷ:UOuŵ59>Yб~'+,X= OrE_ħÙBy1۵=p}r9NorUGKIAzt&hq%$/ѼwpL4{W?Cp N;wŀB F9=J\uuNn/ ^'=)A(OL‹Nюo~QAyrqKL qqm9}Cʠfanzm;J؞'7ǧ37?OWYrGq5G=q٘ד{"[m;\;NR?dSB ʕm0 rt|8YM9{40v s^8U5x}+Fa}Ωz_S_|poe΂&l?_!M?U[8KK԰ Q?,2-'Ql<ҁrQ%/X!??Կ8d!L#:c+ 0Ϡ5/OS0$P \?sfۨc{}Mmӌ^ ̲;js+~O4v3FOiZbWJ0*J\K4l @Ѭ~BYD(k&CpBWʡhL̋cOM^\~l=iSSW)ȻgFT]Rn3}0n/<5&o$]r>lcrAl\<(|حFy/˾ 6)Gq%g8eO *qnv}F]wMrFlY}ՠF?cy' bN1P0ʒolvv:7`QS__~Cp?xIqg}Op΂On_m^;d(zV^} ju?Ձj{|]y֭ #cFcKd_rZQ_&P[ ֶ'Zɱ״`qUaiZLj2a7=z<~([ZZ[D`cZs{8 N _vIB2k+Yo}88OmWL͗XJvj'3+7^oSFD\oN,YpHh p9w:>}}< ٩D^/;9c'ħKyW^sЊ=9>D D"oIf5N n~?yw޹-}q8GC(k?\s pwWe9>;'pR45<98PҜ74D 2KNe_AR 4Q_tŤCfRAy]w܉&O=9JZӲ*B7Yʪҥ[Wi|)#ݷ^8-Kri8x `W"׶=H&KN|:NZzZ,r +F9O_D?s?C ȰɋF[_+85H#R8 GM8O85Z=g7?^@EHZ;ԣ<{ﳟo4/8"?,N> ukӞp|˟k蟉ZP6I'ħ_f fnƉOpQ>GqӓА_ J[Cwlm_s8]JԳ8iN8ƴ=d:'>'jX:r '$guz=Ap c5kî]:vs1wbY.\GSo!=;uc_PgLygש:΂>S {AM_ElvN*1 :X|i-ˆr=cHLk.@QG2V] ֏j&lFz^+>OSfSz!Ü  faLđ G9st0P Eӧ,_0/h[<CKA#4Ս?3{Bǯiv:0 HQ!?߾3<&7^|qv(.[ɻ3U?+> ܱkwGChp:?M9>^|gҫ 6ivxCkYNzVȔDf~4Ǽr^B?W0^uO| ׬'w|R]zYrӍ7K_(s^M8Q6wXӺU+Sy\,E}x.;>)#!(Fh-|^^;^Tw-< 7˦pҰ;kAz<, ׄЏV]P(98p`uګ~{IQ'+߷w/c2AW0Mrh|=/'i:28mڼ2,?/:ԄrS z1=UI&[n:x>YxUE3SoDN:ăä !QJ?kA?&D3 _VkؽA,n4 W QծPG (QSOMmA.#IPe>~heoWZǣ8I'Y.tji^*"CM?1￟2{zkx1&pt\ ǧ);(H_8<QK/-^G$ܣm8q2YW_yUz?#L9,y9b4j8ʼn0$^D^~W\mV>N%8!] 'h^xAN!՜se|Xm_S[lq7\3G)nS N}3zEJ?\Yppa$.>:-k@`N((TsN5Nvt1Z$p_I:渄oF1fmkIPp8SOm '5U>KxÏZ|򮙓ݲ!#_O,/=9nvMJw pZך?!^z8+xw 6ZX{?3kSqz֪nxYn<9g#-[@VOǧk߇3=N'Uk"wuh1&8t2NRS9HǬNqӜu8YOQ')0dB yN['y_pE2}5+|fv뙀fuf6 %LJP% p2wrJO;CjhP^Fm(GsLڰu!P_Aj 6n>__VeC5i$SԿ8AQANq#qUUNQ_hR@v7oA;. \DJ ?!\Gw?ŔXc-YMmu/> dgU4հ n<+5[ƛm)aJ=+<|?)9>ES,F.8%T܈xg ^qB+ed trVLy&};K!C9荖BjQ8y]B)#$ a[8~w]tQYqd'̵=NmY^ּrŀ!֝z, Cr-wqzxA VTbF|JiDڵ#tvPVpr}o^ZP p|Gyy fiM=鋯dG+sP;+n;ஹːm\5$|Y|p|)tiC;i쿷R,'G>T`(49&IS_ǂ8li4HA(m/G;俯onSJ.:'WFE=sϓ[N{a~2"F?KڇHWw' u:?\r:+i]+JzEO pi OaYi啥O3[ok4v[ D|} ~?xPo[tL?\z,F 8| j˩z}5$}-8'C=8 _% '>Xq]ێFtip|{Yrsώ^T\u7c9J^{(W^9PZxWQ?&|aC6'Ы6>{37s0Iݹ'=)=38\ǸEᐥo6I7h9ra·~{u o]6OUv:u(߹p}W >)O Y< C{>ɤt5sO>!!Q.~|is92rci?coqhlQcoᑇJM9#+]xx8!w4SH_ ]]1Ge <[VjrN^2F7K 1oq_w[:>#4^y4x⩲k:x=:G7mڬk_J駟gK3zKUpBާ܀i88)8Oq fuV']3Ƅ؟o&|c_ͼYlxڽ[HOzoǞ{#<@>Kk?:67jz) v ^s{0O0Kh$|ukFګd_4Ǐ9Ն{ˌ./\w:K=84bmI5H'. uHħ&9E:AxiՋOFwOMTsCnCCG6:^3e'*;켫{gv{gy[vegS+F)w&%G~`8ii 8/ih/ݸ㮻X8>ibph쿞Yg5_H' VA K,<`~AOO<)> '>eץPvÎ(M;48{jN ^ZKfJװ/2{nƌ.)3=S^NPF-9qPF-9kK9E:Ax\gkK9E:AxiڒjNNסYiڒjNN;:q@iSuzV@iSNNPF-9qPF-9kK9E:Ax\gkK9z@IDATE:AxiڒjNNסYiڒjNN;:q@iSǑ8I7쀂_؟ ` MR'&}y''!ljH/PA?Iq6F_~mybҼ9E /,~+SY8pR©W_SNu1G$c#+mt^OBhhh_љ Lva. &uzic|cY=̳ an$GD&+ᔭ˯R.-lYMlGQ uF Zt1+Ի3ɓO$n9oSg +fo&36~`p:Fa}_= 9\믿Ue-pdA˺vd Wm9^N|ZrEqe''eb<(_;}X;.?\rP Nd'_F(nևgOdzJY=93N|g+W1fI8?SFE㔴qB:by䑇,mɃԤF8>uzoYe58>7Nz"bI.55;}z4 Nz >wuwYڢz,Cg1=jo9oMB4_g:_pZu<o@I瞗XVнXPtsWbk?/Z'Y#C&,7!qQB3(S̢/\ 8p`pQ gU`]uZ:o4638EA_7p%<P!\gXMoGߏiݤ8'[ͷrcs52Cܓxn`ΒMaֺ!k+w|*Zq~5^ͳco΋Q%T97oYTj@JehWǧۈ׷5?^:慱rw[ﺽj":F 'ōWS^O~pp)%v{s/*kmX"{~ Һr눛 .ZO?OK6W[Y'>׾ppST5qҙ{Y݂v V6'>mO|p/]</tC_ E xpU+\Oxk 7q [?xt|Ba_\V 2yg假1vYˊVWٯ-p;fVQߤ/>\lTwħsN|>+iAzMv^v[12ϼs[V[8h?s)0￶PzSzs|M8HPrZ︞пKK8>- &wࠕ?Sd5ך,p`9]O(7}u*S|wlRa8A8K/ /zUZ6p נN~f>Ԛ3<8iR'ՔO{ᅬk(λ*$}Qw!t8U￞ʳЂ GVA_| P/4OBp2Úo?sG1P u!OHaG?iN~3r vs)̿{9PjKR׿_}q> QW=.Az 97.Ժ[Sf1O//_Jk0ͻGCC'_npCן?hu={ N쥎-r;N|:1N|R 8TW1h!r]U ЫϽYrp?G%F'W `8Uy _Z?FL~ \^S͎ #qa1 35+ӟDsB v -^4gp IvmgNrFd{\pV}K[XN}p8C"[m!ɟ? ?vlf98׸0a<5j\FбEr#Ss57 Ǝ_&6 p/j't-Rf`sryС`ӳNl‰Wp,sS7hS('E}*r(<1s%4!a:>lvo'1gIO(}ѸRb0q=qBRK~GyכViZA]v4Qp|cmWV[ '2 eħq:x|(du͍͹'-.:VOm8,ЧpRۉ'd)=̾}z!:7i*=lIt:jsR{_E:'X}GIMcgp~5E Cv1G}=)j=z?vM77uc#U0sw?o!???p'8ۜYSX?iDBC?uPSsr+:sCC?|vG5p\M/AFfWӹ?3oz0'7۬VJ$Xc#;+q8%P.'{XƼԡ/ r2No*NS꼤NLVZS_@H  SꝌz8!:B(Z=Yl8>=OS5NWc}p77mƣ^)nAV'Dƻsm%8M;V+dMYJ_m9W2@6@NRkw:\Z:6ƉOC_Yp|j k㥷]BMׯ-~'ܕ]΋N8j܇_q`1k]#^{WYEK} r]Xώ;(tFcU\dDe&G}1~?o[^J$ G ;&|Hr2P*NzP!eRqJ$\'N) S"e:)t'TGHeT (#I98:B(H@N1 RF(DuRt=N2@8%PFrLqBuQJ)2rc:]#2P*NzP!eRqJ$\'N) S"e:)t'TGHeT (#I98:B(:>j![?^q9Rw$Ӏt &UDRPHdTRJfmҶ,Rq9g|=r>&@(8MAX~yYUUdYgq :(3d2 azιi _pZ*)W'ś/!KoFy\9pX|wpx{?D$qpӓij?3:|Q_ǩE<2sͅW;2嫯j r/gNaoM_`6 /4'ݷߢngyq*ŗ_رcۯ'LVqa/\^Ȫfi;}QTĊ2TKjACp=as3z>_~YM S~3^JKq06즀7lfp7xb3uԟ0_gYfeeɫ*^ɧb_VRz:_u;ѣX}9VWs9N3O'S?phAi@;ё/*SݖOī Ɍܩ;qHBJ M)?lQr/8\_6G0 ڟwfϿRHe ;PnO?3l|ɧbG?_~w8_l<1io(B’(z1UT\e~>l=`uWN`B*gBіAQ/OߣnE4ꇼ^|I*|N( ft2/E[^7UǧߗEqt+(Th!SV9#{OmKNx>iҊ֋:}̤V[n!VȚbת\wc9>ѫh nn9x8>z[Kz]Ķʆ' 35G}Awjvzdo|8\F%^OW 2Z=ǧNp|J~={MZ4]W]y:>A ,`g'I+J1_ԥofb3/4{9v;  2q* qXd詜8qe ?6As$ϯ]P 'L)@̿꿒yHW'(?@hmqο?h`5H=$ze#F9{k7d<2ZgCﶛ٧W }s|t)bW * dc~]dCw#; "AɬfC(%6Qħ O۷p|җB#:$:9;nEO[w/92LxQ)^G++ԣ2s$7 EN=㌐vc(ZG{k {jJ LZEn-o L@9)ҟ1ݡmf^2?I`L悙N0S/-[c/,?e_[TVѽ?WN74"##Gvwuwi~P k 1R0*zM[}B`ҧϙ&z"VSNϑ8It_yrI?PO|JO8 gNxZcd/s̅5._gR9C:t$-9O8`sWc5_6BHh f&?u[OВ\"4[{w/ Go?D1Y p:zI=SQQv|J-CEjƕq W`T$b !qƼ4Vz}QxP:BTƎ~,d(;)R+"G ?6Hӻ'K.<׻RV`(΄ d6pztmå%4X:?ũOԡo&}MSӥVeGFg=i'f?{b.73k[ Z }h-3T$Sy֣85jЫeSO/uu*k#;iMmw3ˇ~$}t1R.Zrq'ȫwmPy^6hӅִXԃ傾AE2Uɳr8!$ N'!\իS9%Bq7ɷM?;<?хdԃb:gpmt8E*TγrhɡP:yǥrugpIBqw߲hD @ PLsDsAzBxݶm.V4}Flִn&+Rєf 1%'p'UYw}YSs#cpiO.dz56G6c'>m> O>|tIi~ٶ->U=[maP^A 7gKo:$>)8qӽ?X!?h o )29 Ip~a]W=N~N^IOޅ7kdJRmrENyCI9U`NmZO?LlenJnq#`qUN sιe晴颉VhVOqYpd! hiN<%T}yo.4,$kQ|D}YK%'p{Iz7RK5+00 F7}7:Mט1P1MkySxuɹXiCI9U`gJ`rn*_ѼP y^qN7vS?uUf$\Fؤ 5pa Qa\Yaǂ6ܜ ?c2CF++nO.'lw*ܷ_֭l֦/"G0Qd%0B{GoՖCmil$oN?>AƏ׏.KSʣڌe>'o?3X_U?Q_qaZt~>wM5>[_;YRmd ep|g~M)T'jyQ, TNo_P*J+  /lJySr˖ߋ^>gU4ԵR!?Qsg;W:Q?vӝ9B7'}]1(??̌?οQ`o ;h,u6^غV P}Skئ NVrVh%iJP.X[MoDsV2֛oj͑?!oz$xj-xɏ?xRfe^F?M/_fָs@>EGi[51UQ ڿgr/i\܊ӟreH %p\EuXu?|#>mAjS ))G1⿿N|*Ԩj$ǁRYmHS`ByԷE֐ yj#dZ 5ec<ջUpH)=Q+\TVesʞ*q?\|ehA)Bs44T_aZ釺>>&bs(W'>' !??}at6MVsNT)qRg׏eLUW5(yѓz!\n'# |j&'<'=uSodҏ ҥ5(yFt;Dv喓>g&kOF_-w;vtXg4')?ЦIe& e5(y阜%uԿԿ?mj836=PC_3kVvQ! Th7W2 HB 8P h/ڟ/ '@'?QQ\u%_\q7Œxú6b|?po:?r#gDZ?pC~"K!Jgra`H믆09*T9䱖C(e!?ŗO-#&R9چnz/WS]-TT CZ5=5<oцO p,ߏ>X,2, '5P qcP< p,_ _!'y*P'8e@+!CEJ' CZ5R5`kLV5#-D_ ߬2Oׇd_P'UT(:88$ Pv1_AO ԅߘ@l1]1)/?_'?-57lS ƣ +_ϪÞbЏ3nBm>(_~N_Ǝm+b0sWV3̊J􅷼Po5n3c\ .MxH#.ҵK{+ež[6Sm|59FhHgƸi?@+B̨ʟ19GE/a.KZ3c\(ΞSd_k7kL1V*6Mt%PCk8IcjC-® OA'U(apEݡ  HDqKCG/ڟtLM1*8:oߴpGԝ0?gDq:*Cb.Üi?|q"N_BiGԝ0?HDtzwr@:LM4V'Pd7o߿zҞ wtSZd`Z_(PXR ,$9q^pQV@^汕g?L]B<. <,GpISAeh%5Y_u[3MRH÷A3ZB3#.1N:]AE@+t^O"}_gcG/οn-@5e3ڏj^F2C7\BEP!4׿\sp/K  1 ?Eu)|2Zj]U~?pA#L3r/ˌ2N|*6`vu(+r [[P HfEj#tzdHOStiW'T[5$_2DZ[P H???Oj.Yv}1)n˘+jPo(Y=+Nt|.**#?91?Կ6|G(bh/ \ OP؎EՑ`߸7p3-L_@*;>AZb @m͘Q `(X4K_"OS|<`@Ml0:X89@pMcP? iơ?[^f$zs0[;R{^2F3 VJ0DZ HHW"5p!??UdP?if8`Asן\?pOq1#67_W#gsn<A|O|o|o|ooAO Ӏo}EB9+Ke`>mqJ9+Ke`>mqJ9+Ke`>mqJ9+Ke`>mqJ9+Ke`>mqJ9+Ke`>mqJ9+Ke`>mqJ9+Ke`>mqJ9+Ke`>mqJ9+Ke`>mqJ9+Ke`>mqJ9+Ke`>mqJ9+Ke`>mqJ9+Ke`>mqJ9+Ke`>mqJ9+Ke`>mqJ9+Ke`>mqJ9+Ke`>mqJ9+Ke`>mqJ9+Ke`>mqJ9+Ke`>mqJ9+Ke`>mqJ9+Ke`>mq֊gOv:VPM_|͐#6~Q#ƽFנTdi:Oø+*#.E%8AHO\H \q'\sL>1XؚH"YJ*@߾4Oڟ?iIJ#??K&17o%\@W$OC .)?ǎyEgT],e%&0ًŞeQZCuJd*cNYpv#r̘]''pe‘P &njNHɲ:&0VC9/ʼT:Y俳*cNY就31NX~V>ESB:|:u~ S' F|9 ӈF\+6lg14CaNvpb!}GCsM48eVi4& hoՔ:4fSN#AE/ ::I36imj|^8bj'4>hz7\qi~VA`U&w+"/?[Rly` ('|iBLZi|J3T79F;&&H')6 ꏐ0`2=T9?>!tzyǮMk#i۲b`_HfR Q..SAV5a>",k&4G7o ?GU"B=UCR88/οjV$QW ?is&_\r7sן<`3ŕpS5')W?sY5߹ Owc<[?\.`8;pȴ!!TL]2k L'aUKieSG3JIq%5EIK&e% >@ 󟏞82,JĒ8WjO֫b3O {ᖻMO|eVYHuxuS3C 2вA?$AetǠ&##l8rUACŁJ0B?!ʋhg(* Si+'TryaÄWdqI F ?_2h}I'o5-1r .(ڟ ڟ&&/?ڟ2h}I'O59-1r .(ڟ ڟ&&/?ڟ2~KcAϦ QHOJr(|JFVAULUt :˪5 k?/(+2?Կ." ` /_#?Ѣ64fI%o8 F Ͱ!_aGumWknP5_9V@?\ο?hEs'o?3*D&?pO߸W-udNxJ\g???? /aݤ+>>+FU<_q/)n'RgݑuǧVݑRJ^\d{n}ζ:H,QpѠ~ʝBOz+WUyfi\ˊ=q£'OI䉚&M( 3iz ,]M6Sd F r̒D3K"㥥m_`"OS8hS_?AZjOI-pQw/?_7?d+_:3br>4-?؛q2>=[:ǵj!xqC$,ýYjnV-#6SV%44˫SgTOr,5eJjY^?EGC9mq|kf>⸠Ew8AW,_\r-$’/'U~~~`-'EG?r W?k?Cp| *6X`O}P~ s0TmX3t5 j\Pi)Q[81OPQjLj)6_4SRBMqb:/BF&rJ2UJV)NL%V((ҢƇ6M*{_TѬ^R Gfi]Zp#&}eFx(@㙦ʟz*a(g,IA sA'`!c &T*)c X*g cFyG+\qY(LHO?\'0C fLkJ$@pO ?rn0f0=__O$dg;eI~4'\]yKCs/7 JKyi &H& >O F.i%  bD%J?矺Ri)S2Og\̶|ZGfk9&^3d(hGpLүZc?'}tdpQPR:.8(_h/?_dk%;oW=PC!bo3:|KIbI;߹w31cnjJa35ny^8ت|['!.ׄ]X[BS`L*5 =:?@TETC?oԿQ~toIP j"@T ?D j"@T )_kBN a:JAEiYk$/O:ǫs0'T_fGW_S18ES-n fy_\@5O?qO8S/`46Db'?h߸`/;J~#o`pmAc ϰf6I|(csgJ|9@SʥP~%^Nf+%ř;5U Ě"{mFS8jUDS9ZӤ(JPOjjusM; U?;믠K%!8Q /?uG\rivhT/d)U8_%ǧШ#$Q8i" qux"yx^qB+ed trVLyǎPWc2+@-gŔgz)^q8& trVLyǎPWc2+@-gŔgz)^q8& trVLyǎPWc2+@-gŔgz)^q8& trVLyǎPWc2+@-gŔgz)^q8& trVLyǎPWc2+@-gŔgz)^q8& trVLyǎPWc2+@-gŔgz)^q8& trVLyǎPWc2+@-gŔgz)^q8& trVLyǎPWc2+@-gŔgz)^q8& trVLyǎPWc2+@-gŔgz)^q8& trVLyǎPWc2+@-gŔgz)^ZWs/XETZlɗ?hK 6KFQQP4$& K;Eڽ);{pߝsvΜ3;!fXb11ct1;+C4͂l9)bb<3bvAAA_IIO99ezRZd3=9Ms(fQ//h*?O,[S(9"4]:2P s<4]:2P sN"4]:2P s<4]:2P sN"4]:2P s<4]:2P sN"4]:2P s<4]:2P sN"4]:2P s<4]:2P sN"4]:2P s<4]:2P sN"4]:2P s<4]:2P sN"4]:2P s<4]:2P sN"4]:2P s<4]:2P sN"4]:2P s<4]:2P sN"4]:2P s<4]:2P s )v|2POE[1 Sq-=b(aQ:^"_=MU3Y?~E_W&% ea#2^XHGWC"AxK_( у eQ n[ѓJX\h*0dKK+F;|Y(}W$[oH ߲eӸ C/'oyM[oc;>s/)+!hg\Kc,:pʵ@R!i?u??2ʣ'ٗMHXL㙇ƟO ?^2DIQS}^r-bE"-E,bS'q,3Nz\h4_F 1?D_GQxr'MxT0WGW5LJ eBrB;"?d/So8QXJ'@LvI'9ِ) CMudQ)ڇ/ٟe/j{ pVsS2k(Ebjv!Ɵ8`&^MJKDxY}bMhX^&rm|,ڽq]gI/߁19+e#Vu9ӡ>Ⰻˊ1B|'C5#_QeVcp>_r8K|(?z?zK9`xQGg0R'4E4ɼlN}*?=r8Ly JOѴ*zS]:umdͩ!"NIf k E!E_W z*E'ӑ/*-4-%+!U4VRR%ll      RWC3ӑ/*-4-&)!Y4VR Ɩ'C8?3BӂaŸŸŸŨHc%`ll      R9C3ӑ/*-4-&\ϗ_9>SŪ(&×), uY?ϚD+)M:s_5J}-Y4𽇹Ɵ_KK$kBN)MGG4fe,Ivݢ_Єs|&6"h#:ZҦzmʾ`Pp-}JNOG7?ҿ_Ÿ&Llo3'g2=/']HO#/$o%M7L.(yɍI0C7{-?e?SA,'Ooõ G*sQ(YZE`OXr1U6 Yr`G81J04ifm@<Ûzl' 2(WƲ̘.߇4$ " #$l( '_V)x gR0\-*ί*RCYֽWX;=rwW~ճBA 9?ැ_d2Bܕ|xwL!_ ? IH`dFԲ|?o.B*x"e6"tOOOOʁ?KS3p@;K`d//y)`=oG^$%b**gi'.8a(NbO HP/ę un. VJZ]68٥C??_jIH ` dPr`T6\}hїO,]'R!y),mI w]/}[ ƿ0'`2S}1nM7`FboO3/;ҿC^ `yMxxA %%ҠEYo__$JMaBl#OotϤ4LdGS[O ?`k"--K$#dBgE=i2%kŶɋ m 9>%E o~x(p n\.z7U2Tl![$v?)T9Z P]#|]n^p *)}VҩqqhI JQ?}զu+Ut?~+#fg_D͘H/@ty/-|ڎOaOy-ſV]j E_WiA_wO~#%%>@/wd%Sa:}14̟83!' e-<;>ٔ,!NJ G&bNչ\ P՜ٜ ,ӖUF(I6&0/EVb2lj:^/Yq?`@ƟDXJ_cDP?`a ?L;8RC ,௶Zcp b'OT0"=Š2Y@]mǧh^msf\6k)3=H̯}_OO'L8JB6V?{ujԀ/rQ9r e)//OȅooI3A)COR#%9#K/_dAKdBOٟ?eC? /PI?q?oMޭ~JH&jC'wTW>gn3g& an3f qY=J@AqJj] ߔOYD_WBa __Oml'.#KXo5:喝Q/ 6-.JbL=ja?5"#KX /¿ޠ`" 84ʒT?d_/eI2j_?G'QG_9:Y5Fgi?AFْXϿ.}|@Ewvj~< ;=}6{nvM$ W6TOI,­s n&w[ ճnξ~ &JCe>apd_9??ҿ=j߶cT8WzN"%ZҪod^m*G4 KF7OD82=}9^&= P??Hɟf$MH$S)ҿ?  oodAM7w;IG_ Biy4y҄Ϳv|62O[|vzCE2(DP Pg(2%yn 6'x{-iA0Ƞ E?XWz;??`GMsGU<5<&KR eE,ڽg&)6eͳ2W}<o-CWd4?_A,4GTs?P ҿ-??h y%%)[/ٟeAO 5 / |-/?&mMQG_Yg5GP଀ᓿ";<TAmJv=~lsf^\ʄppNv@6S s\("pg(V̘dG C4$L5@)a XW6\D4Y=t/,99y~ @,%Xˣ(CK>'gx^6<]P}ce[^U -ƟD0LAטR157/ IDS[/ٟO?$S2$YVk?&=(?(?rƤ-o:nnpc(mSdoHSemp9Ź45tqd]FZbn[k@7(b}_OOKJߠ;0pHҿENJڴiZѫoJl şpqU]̏\>^e”N< F!d_Ig?hKIKJa О3>H ?R#'ِIbf/zu+RԵ!??H}1_H/vt b@cG; $;!C/ h%Sn CVQjm'x Xv|r碨y3gqsrDiҍ!}*TƲ _H"χx=ζH=H%T}2r<9 &&C6dY&J V<"g(cq &H$$ ;C #\;,~#-;c ˵0˩iR9_?(Sy8pK;3/iQ>YQ-}_5Lb!~Ɛ\J?d!COFe KD4A@%ОyXJI7BN~&oA0GдI{;>m0<AOy%WSFlP6hE ;CAzl)Xo\7(>|'3P:+'#+C#G?VŅO'/!%T#`5$^4O? :?Β?%H. [GGWOWC`E!)k!CG|QBZ(e 6d%K/P*G]cN8>>f;>K""K p3>Uvv);\kgjB ም֟ Ȋ="/xmLê?Iw~ 84($$2`pH ,C6WsƞcؕsIVҳLDHi>}.|QCm5mCxmϖDj_HDϒ&6!p$ˉa4I T____fsbO+%Ƈg.'?G[??[bM|$SOٟsB?"_Ep@\O$-?boUкo/MTRlllt^T\/g&\yOd-+Jz46[%<۵1͗5(%`.S:(<5ԐT K_ 'V4վ]+ts$ ԘÄ C"X:iXñwk>[ѬꑞhG/N??ҿAZA+(IOoi/-C'!K/_dy g%!CǍ?/_d*O-[o߲eaD;RᔔFbae4~1hgն%,?N!KB:x+P-2e,Ȱp)#,!r]B$ ;?&H%)?'աm tnbD֐ULH5XnK4~-z8N˻E&SžZ k2eE_W39BقL3 >/? yP ŸAP)?''h~a c.i//?rT+`.;b b?2C"4 /g`޿;zy!))u쏠(ԟA ';e`?:#D;0¸!zu`Ɋk4q<Y ) DM^5K\DT/X6QbZʲuuVdjJX: 7N aҲPN??_ST,?ҿ{ա}kÇA2'#k*EGW8>}6) xY##O↨¿ZQjdInޣ>b 믅E_GߠY;ߗoƟI% _HE RGWC^Kk¿_Ÿ߲?0ZC~%SYVf\)ۆE */?$O?d6$JzIG#я!jοU} bI!e yc~ J╗ $͘5_ϯ,^\s2))K$5Չ%L g  }}븜Z??H __B>GCCZ ZUcy<5MI0B3w:؛ (^_[9MU۷2&}nz]LyM5SޞэG-T_u5-`?D0aGO )Nт߄ n؉| !doBKKKKK:*CK넿%  BG2 gs_OsuVL3d'E)5ץӌsX].W*}6 `::Xeތ_Ch0.WE|2Sd?=FDGWGW1+*J Y,C[,|8"`0`?.T>.)Efajݵ{?֪jჍ?op>b})Qx;ɰ VQ( o!LQDmP@}jL@>   =$aP?HA!-C4OoUP6oex #do߲eC81"?kW?D8~\-#Q.N-gmfErf5Xi…r}gL&ƀFo JQ(0߀# <%D?2dzmLZeR5"cBWcE_ cOQ#: x <9E^ LlZ:1DfVhA§~%i#1gu#ky[,xO(]bA<&`8ˉ!6cl8YGR#ʔF97kP ;h׳Թe"FB? ^(B)Oԣҿ?Юǖ^]KHh1 &+J5-]HCye}@.&wgk,跔?z]1Wg9 GQ`ܔt;J_dZG7nl(?^9""Om'RO-"~>AQaʞa]B'h?dEڌj Jc?!KO4/~d=COٟ~o^9!`A@dI'!O83oI,{9G)j bf`'z|Z^xQGjo']3y[NQ02s?7Mt'>kN[om;n2hP*(/4_R)ߒϗۇӣ/7)Eh(T;TT`u l:X/0t>y"$5,0Aib]zX#O|wEZ Ϻ̪4ܜsal@do|OtS's>cIɞ/g_(t?d/slAt]/ϴ/'?VTj@OG*ڷomN$.gX3oKPY^|Uk>{ٵ RšHzCy+ Rj<*/)o{%WYeWߪ -iSzI?;ѽ꫉7V͜9gea_=g㏻Kc7I,5+ic?[ʝ~' <ny?tZF>rdjV! rc???ˠk?V<?/KIHHЏ?/?cOn ĥm 5 "IwcJb _=ƑUh?~P/'\]#r0,+{F< y"%%%E'hk͘>SmɰOϽ[i\<30#BnT\"+rX,Yqǧ:0˩X_,/D:H%2G!yAQ<ewgpaz(a7.u:ȭv-ƟƟƟ??έȇ+ K Y$ rRxE_9(%d,njyO'2ߍ{z /) hs뇺y?,`wLqs5 ΋P~w۵jU KzCq۬[7{v<+^)8x& ŎO17cg_~6s0 AB;ù"ǭr`uD¬ u!1e'{{eL;mm~ߚy_}{x֗&??M__v O!TжMcd0b U!_9)E%O o,b7;"='ɟ%D)wՕ׸տ͙;E H&M 6v׾]7aniǎ,%$T5N:4=Qߥe~}'չs 2˒kjUM@IDAT!C#O> /ds޵Ґm"o&7Y}ezx,^KƟ?K!++++++˒ ++++++++?u*/++?wۢgxߕ>qo`?%X%OF͞9s'/|Koe 8ݓ fbz&HDz.{^qjA$I85%o§գFcp&`)_"K 1֏ ^ 53 'X6c|H6;bh/w7MAaIҟg!0)mvh^FگyI/KOGG_S~aJeEb< tbXQ#,@jr-bYƳs]Ɉ&fOk]Pۿx;>3F;7fS~2Ï<wQbgퟢouհ`N +9mmt{&sExAnVʪ+l{=ٳ@}y_mٟcǧSmǧp(pv5n%bNlw3حh(p㿦OYT{,˿涿}t s_uݗci_9ZE4TK9 l?M0Y/䀉^f?- ?l %5u(b?"E_&/ٟQ/ؼk%<˜C5,|ڪkcף _]׍Vo}g&0θf56@břв]§(j$Qj3+!ldw2`dc_WkAJE5.F0+ a{f~G'm\&MdZƗfmsu6Mց6Oۿ6mpWx_0`Μ92ɓ_t[un` -ϜCڷ'>O>=7~{7G|]{m9 .o("6?`'H2Fر"iԞ8K7ũbg?!6vim!,#{q}.|ӷHFp41V1r,'Eڻ/k5Sٷ&X֚Pm.@bxn"1c Cj wm7B=v-߂;~lal6 X2>YnάVdQ/pݺuO/Mz1Bum{>B~_Vt)~8,9vcKchLC]LC /WR,?/E__ Ң_($WgKWWW%ih :&Z,?%=XCCCCCc [t{f7{ܒԱ{z$|]{虅Gvw묵yܛonwmÇ}:m*Ɩn ٽ 55v|*M*K0O§FxtԱ {yp} .d}:i[fP.G:y,}v/<0uon6n~k ~`=+;Xggmo§i=nاk>m>4ץ Bxpʫ G7jǎx>8׍uܴSƣW^g'zl*k} ֘ϣU>HYx5ri??-?axIyS$5ñ$Ec]\,H -?Wc 7(ovmS7 Ǝy?vg'ݘ⯯`AU΅]{%8/W_§֭  §غ:jU 3? {m۶v}qWl+k=zt]6&{饗];k~\rJ(ra9sg?ԠaNgfr95 G^xNoYwwD{wE(J+1`m}KiMW݋/NV᳍>(ȫ*6A\sM_D2IvQ6]U;?>o6qa̼=NŇ1^"}1DL̄6Jxl2llWү̓~A'dg'yvWS@_п őR_cL**gZa[/0ROlHf2Bl.J°0gHͰZ>h?B)ӭ߲?IW#dJX ?KɓdvqJ #-5{Dn-ð!y8OfGXc5b0ߩ06|]9l{QV\kqTs1壏>KBxn C]Дd R,)gwf`R64>-Pe!p!MA:. X]w[q[ntSn"UovN%.r]X´'>u _~x`Bm}̱,0{/FaӴ}u7^wmcv[1by ŗOuSN}yn%|}vqNlՇddS{:w씞?;/3jQe!~-zB^E_YkO] WAwSlӣAK\ԻOPQZrԛЯi'XT۟N},dբ]\kl<}wKu"O8]pW_7,-:=p}dMܩ:vzq}wݐ3pYg]wW%EGW\Ro6?~GU68s]v)~~yEI!>4⤉~[J [o;f(ٳg۰տ;;>;sm>HJl}=tYؾC?أw'$el=? ={(bG 3>zwOvc ьFvym];NvO\}[wxo;s&^[o98,XjٳmbNOlm׬Ϯ_\{-3ϛſM|kޭƚV7wnRnYbǟpb;άvwđG39}O>t]p!X!|;(xÇ{D$zZυi=}q&SN;uU9}Ί_:*9!D??>ZE_/1ı? pe_[DO_gjKIKKKKIF!"_40sZ /2w!NK?dQ=Aٟˤ{Zoųo}{WUq ܣ;!z0os#+?Ǯk?צ wa}~ 7p,I?`0DܳOVӍ~L޺k}t0!alpb0gYE?{~wfXоL?gl Lt_ƨyߺ!gr;cKgfweWo6_r?ژ8j;iuhצPw< p` YYV\?,DnݱdU|g8‰b)m)ӷv= oϘ=>d?-ߋ}8k[_o}mi w~Dž_| vD<-3\S^߉\.|ŽOߝwkwgӱu\uOt#GQw*o~[CvI%ߊEgc/<]w]wŕW&&+UW^_QQv쮸*| e㩆9;~کοu͞w|4᷍tQ\E_:K/wp(i1El A,|BxС8WiM=vA87n{Fun*E͚5Uҷϻ8?_nݻ7IKwv~|휄do:R|#t?o?7sk/qT' y{fMOC|\,9AµkiUVil:ʽ?9k X WUlc+ore~u)'G ;} =Wob6?qo~?&`o[?16wϨJoM7uneֿ*1}P,mEx S/0*W]rҿGW   BAŸ q.-#Z"--P?d@A԰?>h׺M=eu\G5N6]N_<|lN8ǣUz7McmGgTnڌiS\.sݕn92O_gxЩ`*@ጡȋD M|_){O&ryt ֽ\^ܔaÚkWE脯H:cUaYXpE*6x>4v_{ &L{1Mj^񐷚-? <&{&nv?Th)} '/ P%.m3~gwqGjG>rǞp"&*~xc~?uͱA>_!hW͙ b%W/IP߾[{ Z4~ﻳ>˚~tǟ//M?)uz^RoQӗé@ yICEi T0Ob[w?i LϐZmZTGaH\JUObwEZws#S(*iMO>"-UYo?gw߽wych}գQoO㮻a̢Xش}=(Z2:q܄ n}lvcY;n欙~סCW_ur|eݮv3"ox5wqa1G+=vTeMm9F3ON®I}%{͞9mӎ_x\_aGllY7{v v|*[a™FԹv|ϋ|UΎJi],l|< ۮS}K/uM$dQOg}X ?=Sp``j[׺uk.y/;lo%V?:9^1שsg׿?sۆ'~; X{ }x5Ww}}<7E^qOGqScrMᾺ\mNݵ^V2xHc?@>\>_0awB*ZaW˰3XHDŽO?ͰsS_UWY? vf2V.Ma{ǎV:f?DZkK.)<'$Nnco?mmoUn/CdHCq6v|Bvu=XW]چ|I,}_c}^~ >n1u>_{U7fm1 #o1y? }DDELk)?#}L}V#yX13%#+#+!%i_ _.E.-ݬ?d@ɱm߲d#/t?Miooo-RLTDbSm0oTSS7?9m~Âr߿^{0v;~ꁏ*(6播n}7ã?zn4`nϵW^%.n#v駟[o0gcXͺc>$|-nO~>I`!Ne%R;>_0Vx{-;AmlʳvO"51\#u=Î(ʛ  <XtrӰG.Z /sxM~#%jALz[eﲞ>D~1Ǻ_gKg~?&wͭ&Ze1kly7sz3z| qn؍7 ԉ&6_잎`|{c' dW<Ab ƺ礲cƸwyǽ`ɭZp%\6?_Ey_nG gs8L"[yFmzN;~nH|Bяwmv+@W 5?[h|.:[osG}/cNs䕘[tw F:/=7[?/IfEoߜZin%HOX̀ ࿱cǛcn6>Av8L~1N>lhy3}cJ7z w'/ Sy(N@fםwkq8Cl!JlvgG֭<޼,ag._Z+yzv2寺zvb{=}lIy̫d{ݱi.,igFYL~{a7NHス2=kְ7gwOt%yUW'e\x设z/M>qx D@n4w饿6z淿iu݆`|]\묷wvu$s2^?c?l"9ن;.t6]|ݤQ .!8eD󌼨ʹz}7rpϭW'Fq;~2o9hY=t)~NC> 0kn6kRtYaϰ?` uq@vUBA'b(e$ []ݱd~0>r®Gf6AvgR,B[~A f~8j o 9J_vs=ƎO6wY=ߡ3hz{}x?7>Vg?OcUC~ux6+wqe7+7O ݱ切O#m`t| >s@ 4\9h75?aonAg AhLdxv5"An?\$,gZg-w.&I'< >D_bd㻻vėydM?s}3[Eo*ngW\Xgy}1skرc3s=r|Y |/?o{g>gvVFӑ@D__gg}=? hi-psyJ"=!\.Gj;>j?Hh(##/}FSPf^`mR1O$ޙu\YvsGu\A1S=EMUwS>(gY\qIvqQwz,\Ov3^Fa 33SE'2g;w@Ǭs; )`prA^42ܭ*Fa§=U|]vQOݺZ{O| wȑ=v|<16o]uUn-P*|᡿Do۶v-)ݐsufo;t5>@QA}]E8NuĂm^f#͵ׅ9~7Grq뉝_⮾_2uI{> ?kc񡑼Ym W]徸6wS졿~[ u#v+"}ʿƹsc}o:bg&8dș1jn5/~q-ئ fٌ_O<߻!JW=ӝ~:wS{QT׃pӷ-< _o/qs|ߘɾvevmk|b߸cǝ;`~08"|vs(8/yGϏ i27KJKKWO J_LɵO~T E$%%%iSs韲Mw{DRXGOOOOOW?dϿX_ݾ tVZϽk{n/o UFzp/C_(#>C5ürehvԱӣ5t?>yM+ G ~mε3LoK*KXM:T2=&mSGA@Pk^҄HrnқibAn]y07xtA^Aba갠~Tзr6iη*CzAkryan]/fy$&ٝ8wi|9Q~7 J/z4=H{'|ٞ v=S#я$<J]ݹC"gѵ???8?YdJ`Jrf_sY 5U\-υOI1b)V"qI.TlK(_ڎO!"Mu%i1Q3fMɫ8NNn]r9Q\F[ =7^u%>5MQ;q1w(#,|~'cڼ~~fqΕW\I.X3|H_ŏ2qGE26 yO칇=ϫs!Mb|cr3p S§]`y>"w|"Ᾱ0i.w|ڝXg͏;G֭ۢp*k?]Ϟ= Ox/|"nH<\I.쿷xwܱhoٝxf\u{bfl*W:b YX p|Tgݿկ݆_ω'^\^5?âY=\qBGbSk,kZ;¨6ֶw g5;4bǧlXkݦuh@c!TMoĝwi=Xyh:.J.]reF],:CN]Ac~␃!T~nsӷmt(7wvX:#AZ M H=#n^Fb<>>o dic"g^-|Z)~^'Ԗ?OGWCŸ߲?@ &O%KDOٟzB Z9jg?Ock^__JM"%%%E$'D[nw|vk8h|?mVV?Bw<==cƥ?u*O&Y~ǯ=.RGVzT_[WA.L gy3fb,㺔A0"Sΰ8NEl :$ÜcciL -pu>y٢0%đ_ Dx/.XoVv‚n}P '] fu6Xԝo6g"2bjڦ78(tʼnwIpo"~ifoSX~ Z<}."xߺΝ;m1L"NK7i||کӪvX4m4_imƵê'ėWrpK/s7%*{mr믃/||n7LP;R U_yݛoNq?!v:3b&- &'W7 ўxIwiiS L^klkBdOCO>ݜ'݃>̍3ZM=WlO'k}Qs[l/} ̰c-P6 3"Ĭ}t/ H-|B5L~Ļ<!ǿ_K> [kkXECdF7vSqcgT,⦱X?;='K OmzmGukU4=$_$>.L?ө?-~q a}0w'ق5`XN!v^`ik{fϙ鯺{ۺwom-׷8Ɠ> >v80m3|"S'8) 5b0fd#_uUR(5mT|>ݸK{n3s"O=KNq H^{|]~?PkJwO~םu֨y;FFNfι]{dM,}1jAsy ݆]N;^51k?7`qn|8N<Ogc nCj){aoaĮZwc/?ϟ-, (ȳg߽bikIXj\qnx`] ?<7E|Q/iEݝo_/U[| _k0u} TiQ @~{:_C+z^q?lwpk.o{CsM6~:gumڴZOnkeA:YXWruWr`܎;} B(%t+Z:L/?d$kYƧs_OqGO}֮bAn֤?m)On2}Co=)K.fG~‹w_O_n-^n6_-v+ylCj^=* r&GogƱ;`b2NΫ}NҦM(օޏ Z_F?Xĕv 9_w'seAƌ}|G[E]8}͞/D>c׾ڿ_pv]iA=>cg-CP/O ~n. )K"#;oF'85UE_bE ! )?BZ/.,B{jz"g3[Zl-u\,#FcAQblh؁gVK= O.;Uzc'>NV֩l$:>̋р+*𩕛˅OS"؅t TO.w5=pc݄?}-^qb?4?V5 ~z؇ bÏӠA ACԭ[7yp&`'{&unw|ݱǖ=Yge{)؉(w4Hvt'xs9XC|Gכyp> b8ٍUkqQ ŅO^}_\-V,c{r v$:#X<6l۸8.W??\3 E{Ph{cAQL4lI֘ĮQ(6gI4V`FӾX @AEKQ ?)o.F{sfgYWCݖEH#dGvx!ݘ5Kjtk<(lGcmBa)h*f- +>JRt =`h6V‰Öp^|p&H͝T,A&}<ߞ^'WO?=~ C' Զ??o ![ W7O1Rrx u=\ueY&֗W7>eG?KM* rJenkv CǨᅅ*1'+f}ך=SX2Z$Me+Y39шcŤ[ËZBKx0&}cز^6>W~5dhp^yEx7HIl{D/Z#O,_=p v:~%y<'qB {gVz: +>}IO=џ^-8V9r.ߊ~_җ<}U /rr&l%38h^wNᴓBsp{qebtƌħ#rcm"וAx;Ks~֛oYh&J&}2|__i%I]=ﳜXgB9LnyKGirb9 l*1J"alwɌyy1ޭ V⟥IͰ&_=ID~h7L|3ncgG!a\ +TUMѿͰ J?7߈6QƪQ{7z[h_8+|ۭpt3p oRQva!nj",64| VXi +UpV¿=ϼyK@IDATa5k6b>B?{^^cag^ϏӞ~: >{ae^a,|4bO~O/cNj'M ruwXO{'ąIs}.]GXi>?)p'L|,{p JjߖcVgB?~v?`"\?8]IBAM|V|ɉO[m0 =w&뮽!t2JnqrN7L}8?> @^l&)i?5 Xc~!؈.;9@˯+Ox({+W-/ý;oŠOgc#駧`kZw&Pm=&>ѣ "Ï~#YXQw zH%Waœ9 wդuL8Īg}l|"o_qog5um2ɟɃ̈dAW60Dc_+37s+?k?eB/8 Q/2)?P(zQ;*nTle'-o{]locߊx9JXf`6=;%܃EfRxmn__r)P ٶv&}7-7蒶?ӦNx/Z:KGiX5Jr}4+ jZ#Q6TtEƫ5,n;[al_ؿvU7ٖ,-}ri\'VL{.KI:c%~;$7x$J+-t?M7cPC﾿J8&>qUob ^ǃcYokƍ qF'I 욧(C'MD'ȷM8:+>E6$2bDv~!yL3v 5VmYsٕw`N8F6Z6'& ie7K\i[JBa73!8d+>a'XiOꪫb5WHhkOǤe0g1h?wi0h+5{f@a~WY5\|ɥ>~ O;0 Oԧy_v+>[o ;uF\9칇O%ĪF`u#XT^",ӛo;; mrnYߠÆn+]z V{ߗ%ߑ~_)OMis ]OwפԽ|DL.B 'x^ֲ? vC4 +>߹S0'|Lj0=;ˮ+}#) Hc[wF8?i14e գvYU[[>d`oc&_Pb{xLiXy?ji1з;asE}rQ9$?"?dM6_IAfIV0?K;@JcQQMJ?5.!!wPK(V{Blؽ[oxO5aYׄ%lNalmqMu|(ڊz+~D  rS 7֫.VާL+=ƑiyՌ'K0Z%ܐ5+x[yijH?/#$]8Gs٦~hǑ_ivldhא!aMբUW׮2ٕvl5ZcFaXujolZ_zTz/e*@]ʣF].m^ v6l7…\#/W|ħDDL|BG[l ^vm/V [w&>Z=~EW*\cխ,nF_{{cƎ ؏O=%(+?_pf/N|AOY?i[ w9xq)pWbLm]s`?JNmV|b E{|G{,pp%{9 L%d%N߱kIfs.ZM?e_'*VH[6h.hEߥD"E$>5\[>pOYտݺtJ)+#D[NFڗK,/ˏ*YIUq!#؊ Mj 2??l디O֒0)hӯ-NjIbSmtС#VτG/s&vU?>=+^ry%o :b|N|DjP3X#V|@F,{'>[>t_&\)` }42ª=?obuDk ݗ]ء#¿ꤓW7]wV&*?O~l4`'L|28gu'\Orŧ7!t+4<οy9UW?u'Ao[|f {8ߖ?PaaW9gGz~m(w睇+sWY7_x1̛?<ŖX G]rQपbo׍6L|&[ ෮Fj* W_q>@IfnqլX^1 r,kªSݍ|kl'|4uxo=&>m<]sݵr5gNƽ5߿^ ;MHkn'r&hǔˡC?SH|:pJc#Vj`z1n_nU8ݷp5\R|LT[mNѾ喛[EøvYe|{"E%Xi98dd9.b"~I%qd0PO OCcGKKKM$--F]s:`,䖒#gH PHD'CW|d(g=sPVV41=|w0lE{W_ fol W;n{DX>k91W;/wxz 3AiEǵ _ro5a .i9~dx:oPO|T__Xg4?%6s]WV/e$s&676cFfH||"2&G^xP|~FWOFtqf_XoM *lu8c/RBB >g_k?;WS]^~)O a[nfΚmx•]Z'N'|%:%N|^=0LŋpA|A2&;O^kr^#8ڞ#ߩvaM |in|4?vax/U2Ugzk;|Old/~ORwfgs/n"]-sa=ʖ ^rOg9Zߞz^%C/\Z?{ڌB̈́RQyvQuAuNV9?@O%Q##a_Nk 8~39!5Faef>-"sX_n ;4S[n7pƌ?V|FU3N;W^Bޘ{DŽ .<穧''?N/!p++ gu_|J +!> ?3C}³@V|>tŊ>M1)g]ݶ7bġ[+wŗ^48V]c5 ,&L$ҿKBVE>V :x0ǥ?C÷cſr8jH;f{7ݎlsGyXw}œYsJN<u1&/Ds+ЉEuTx(V[lmGabp'Lt#E2;6;K%arWdk&q'>C>,|ΟMc _}_S{R^nJ#?6Un]O&>8hxFߞqs? fq6pa( 8ܑE'&51oW9 ;Cw=/> SO?#g]S /,ѐXS8$/|5RPz?`9$O "%)!/şR0եo!2 {?RIDž_%K@Jg[4ve7'8t>^CۤDի\}5x(V+ëtkH}v񘣰Qj[w]|mJfUN߾}.׻Ͽbם'S?8+f[c^}t N|F|N'cC0{1a߽C =|َE[n kK8aw!/\ħqሑq2N?TO I1Wovħ Jlxao~ v|; ~F??y| ֯J\i#3`}膉OY76ϑ_EޏX'ܸáGauIG?9|-7̴ ش6֪gϟZG!>[WL|2; imx &<z)b?,d䙋Dbl%#o*ϟfN.`'%{&w[ ?OCpcRtn+#_rn̞Zͷ32dkߎ?) ʕ_JX)?_:=?V:ejʗv}w8I!̚13 ?`,K:寬 ǽM{3OX]}9u#3_~_>sBB#|̄ߟ~8``GzX-pg~Ft>*U6שcueayb&N j6|a$J5K 0 ?J+8\{AX8_Qd~>2%Ld@ݗ :fB sGKпِ_ [߹cG,LVL~rRXiŕ[lpZ)'uƆ'C61vm7ǕHA-ǁ8K y+OᰅO$荧7۱yc,C^\Dza^ [^N ts_Ħ0޹ Q!ڶDNՠߋnJlf}IYN~o|^k?Gզu*>ɍ7N?޻)S0i{|3Nn &q70F7'~iM6ƊO[r^4x+>=2d}SN+6/K-ogˉOG5qiS V|;P-`'v,O~t/6eA欳hV/3 K|.w,V3k_IN|θ:ă sŧ2,vcӐyg>뮃ҊO!\w kL|*N3iߟMV!JSȯ{zo$[09댳%lF,opP-xfÙ*N\%gJ+Ձkկ~ՈK?9#~!ac!uјUu1V5_It_-R\#&0բ1a+eTڭkLBՓg  rL|²L{`2`3rA]jh[oⓕ*fߜǠ! Ie[rŧD&>m<+v W|ʛʗN?ڪ%7|cKw)b=Y`go0pxǘ=[pVCYR7i+wL #DY'C4J:?d`k\bK`tYOOo3?"f0)[D ?EU̧x?$,QOI!CGn<`gh>5r+f̜i7ɫ`1=} ~cIfv>nY,=g>^z ?]HVҥioPRJl%Ol/xʁz |4~O ^Z@tkkW^^䨔7?FqM>0/witwy+|{XTFOwk*o%&>͘m7dp&>y#8irM| O{󱅻~O8%|1}ﯼܾbMx,/~ ta#цSO ;nBV J1X-&!N'yo sy=|٦NX%?pH[Z=z(&{: 9ϳؿ{0 ne|%T-YK*_+E?"jRF_nkc4ኴvݺtM7A=R;4֨e%_(EωOL?_So9Mwlhs"púLE;6k `x;w۲p!&#[sIIdݏ4^{%u-tN;=_Cw߭Dn40 VaȰaƏ{EX'?v{V$K7W^UifG;lv. .p{1YvxrB8Iߌ|`si>iPFSO]?ixi6kG!t =2%O>8kGY('3Plo'NV;a6=NJ焛P87ƤjYq8V' YӟƍVs1>92l6v|!&/V|™gڰ,Vnj}N.#jOk X%. sf s 0SQU9лwRy?f|S;aUU +:|-Vcr1p"}@> F:K/z@~Gpv7ذ_8a=c_V|7吱'qRNjT?kN/_&_I?fJ$#/\ڈaVI`(3y9⨒hV@BuO7lmt_?b$(*(*`jQ_RL.44̩0',W%S9"%߄Z8J>׳S'&egZwZf-)TrۤҞx\N|bsɕ^2Vact֬Y/.aCj vׅkˎd{BV3l'j4k駅[oWio'Q&/߼yVu8o} AxaW_}%/?h.V\i5?yW8W2 kE/l'7,g\dp-^P5sv C w޵ Lymp>3kӷVa8%4ɿ/C%Kjat-gh;Z?}wLԈLnv׶Bmz:}[/(-ӷ+ϟĻby'6$c%yt/jEN~Z} |$USHڅt&&gݰrˆM 6`269]|dja| -Lx)hno6=m"Vm&^LN5eR聏92?|hģz?a~k_o m^ Z?N5V%{.gW+[K[o +}0q>Ͽ/~ESa͵ jgCv/=K/^UE vـO LmkC_6Lxi?fd-O>\Rj8?'_jRf] О åAG?HHH4HJJZ~5379?/vᏥooԉѮWc~~ߘ1vyrsEŕh2&VXʊJ6DٵǼ$cR(耲tЖ[:il 6ϩ{,O7N<ƉOwxZ-_C6lmL.:y.\y5Mb+>ħ6dc_Ɉ L89IgXi?N|B>„O}y?}׌Y˄ gG}fgL*%fO>p+rN*|c_a6E_.2\q#Iwndf3)v!,~n]/0!_'n1u9%={V^y0eԌ>̲zJ5jٕ_:R>60/FI);S _G]d_=ӭs'q#S,]V E|, ͮA[^C4A˻-Va-?\c?}uIO;c%/[U?>( &z6'>7e$-=3g"mR!Q&OkOcg_3?`o?#.K=}@3d* ?GK+ cAFābxL"eVP \ xl__>(2Nj'gĜfOX2Bc ON$ n})>;u:zȂWM|Q"d*~%ha9s/&r86Lqe5oяMߪ1&iWᘴ+ .\yյSk~AC/j $RƗ{ -3g o/8lɦƦZoc%5׻{fbl٦8#'NɄ0'?٫/peg=zpQG?v,V5::?[i{TOOw<0f &-soؓQ!ruٿ=)|I:\7<3Hs1|x>@צ?tAaxN|eU2}GS8׿ G_o<ڼʵ\6`/W쿱} /K֩=k鿖'ݺv868'R |dق-\m4]S?M5zg05/k~ -uj5Wzylb*kmU^{pmCWWOj(Nog`";*?̒h $%?(߶?4eddSQ(?(* RI'ş*şYږM}*,9xmOU7;&՟ce8n^9"iKalLjY͜{IHxVc ӟ c[>m͢F" ϪCBߝ+۵i>zbBN+>YqB/:.hk~w܊+Bǎ >2?v~ؿvo*_',JLocQ^Lf̜ia´2Fm:pXWVѿ?E1{VGV+k?CC==pXve7$Mc8{goՖ /^WKr~@>|6,$K&kBkؿߨjLQ$EO|V.]$i(ca'H%i iڷ~g'Q.nIQ3EٍX{ *o}o 7lf0U?{S85w&<&eԬG]`;|=̯O)գh?hȰ8È&Nyc,ԩS+/>7 g ݖV]eհ +o_T|:l'(ԯzx_/|󕯄U{KX^\CΙ^kcL3h0/Gagpo*=Wk}qZkϛKlbbL>wQOy/7M6$/-8i<& P%/_n y/4|Zj9?_0AO_gOu`YxrU!_0#w&_?ԉ&S ;jYj6JzjP__@ $/OoP?j.Ko X& x2*Z\<[*|-^^xY}GI^X< M|oB'x5EW쫆<1/uGqV-xyfx,<}᱈m"5Sp.=lWn^p'?nݡGKEj;?_OI$ I:aŧF4H_-R{Y~x+Jԋ_H`*iM R@A9~eNڷwUAe% (8\Xk<ꞚcWFg#/)GhE(j3fheQ!ʫx +e|10C_(c/M(!Ca&N1f`WF[%#M7_r`+)%C/_ 3EUA V7gI*!WW|1mi_đDoZȚXbEs~=sw5 Oqﰵ M1ЯJWU !hĵ͍_3 FeS;,|^V>9)*}պ6w!B}$v-gWöX5 ^x1{' y=Pxp! VOKG%n$]62(O v:@zڈmٽmĿmßdArzMU_Ga'"9d \O2ߟZ[W cWNN_GT &6d$Llf6 ^*: $';YKFP!K O\Y 8WWoʋYkb g\T(GE4kk萅IUF7UEyk>.Z?>x!Fyh_Z83r-ʒ?YGkG%q-񗏿n1"%(fce0:P@%ŲCw~(cɪV^|¿E>d?? S)e__@jF  7E8{G~()zLgN?͸ H:X. LЊhcSde*!#1!#C]I(m_ʑaIlPSOoXhE䇿a`z"b~/3 _m뙩!\Ӵ3He'nɲc3ZRV5wsu)lªMqQ5 kp4q03 cD|'/TԎ/Fr*e4q_ŸL?)[(1OG*C'6ƟMeU[D^qWXd/K052BH)H&IJ ̰oTD%b0E'Ǹ7?%Au5? 8:n-ۈ8g)8ոHrmluI8d0QV;Ѐ Kـ'%T?ҿ?ɬ @+~WwTKa’x2>U^Ӿ8J :X)Z9_z/[_U"+++ m?ed<//"%%)-----J?R-;?(?(\J"c{>gXJ>U}U|;g|cc<3Km~nuyά,ڲ+X_-m@D#o#ɟƟO ÉE c_,)Β|WΝ'f6>̎A畫J%9yv>R]+>7_$1ax5=O9'd9-`}_44'?I" 2BHbMxyhxM$^% .yr}_W>IHHHASaŧbabvVgQS<7}05;Kا(-CЈ]c|WNoYO0mDaPN?X%u-7]PfsS" }BۘyMܳfX]1ڴ}~<8,ԍ-O:IGWQW㳁w hCĊK3Z]x֪7{?=~nyx{}_8 +#++++ۮ_/(G*%%%%%%%%nkfwTK[)6 [ ZlxR7qS3(Ki2:XC,8V*SD '|WZAj!Fefpj!ɟƟOsKkRWSu蠓_'UʿsY'J;B:ؗ?ħlfހohd("ITl*#X f#K4FH_E(%X#)Q; `ǐC4#ĐƐ:Fm  E0|'ِld>nT+-_ŸŸ1? )EJH 'ŸŸJv pvt?|Ly/"r+mnJ,eu5,楷;E#ha g}-;s^lfi PЄ+QF,k׋O*U& p")-e,|Ky7թ۲#luM*^H".(A}V// ,E'OO nAWGWCR< ^7FLXcD0DGA7?)SwPAPP"Qؤߟ+Cşx3LPI7 jJSM7Fav1Ïf'OӦN]Hz-ߎ1 AyLy%م3^9y%OXh- N,+'ಲoI` ނ]/KJɇ!@>vT,QHHP_ q\p!֥S.8j9Eg0;Kg?9CF

=I4ߺH CLb\l 1m߸V<1=/u,[F`P  NZ6j;:ȋLD"mL!7\:2S2O____C%)S擬H[ ?𭋈?ruI$COQ'P*PWbPujdXi>~U֝ M7.Zp?Ԍ [ލlkڧ^fŬf*qPfUk-|Ծ/q6U_#"?%? d.tECCCCCpͿ  B\;_)[`G ?(CôX)Kd/ħ&񥔘kTRg9X&(A7P96ɔ$`Ucxyu-/z $8 CIIW *m,fTQm  RR)JNd?_ wʾ}ǻݷrNST{ۊO",q,%bm>Phz6Qevv//K85e`2 lPC"4(@.FV1     4̠_A&_ɻ?!~PAӊōOYXbE)o)[8*O?-'>9JQ2qg?瀾G_y(elj6"@BSNY՜g5'uRIܒs7%%?ҿ? ʼnO _ãfpt^RʫRV|ZKl̶2ggk 'W- }_'O_=?y*#"?_ -&&--CWO!*PE'şKSM7S 6g߿Smߊ+>#9[fA! P6|(\ q/\'omd' 2٭0j[Nx p vKXc$b1!# u)T @nکSĄE_>^k #$h!D&>&fôl}8ǿQutd0&}܋qCo%՚s`LJB_Ÿ?/*S?(8'_ks@gş[?'ߟ67ӞlBBeaŧB}F 1~}{TR6[ʞa o+k̸/7[ x|~o7:!? ?"II6AWCKSGZE:dRZW{ǟM=OfҒoɾ3<NJ',ߊ??S{v`6QHIHWL mK_!_Ÿ2ؕliK _^$ʊ?('Q@2s$/// .Mŏca#,[ϽMз1k7[43Plŧb~e=;OK qK;=#}_:ӯw_}>sIQsIʟ/K4|q`Xn ?_____       )/_/K/şZb'ɹi6O{+ŭV|N֎m,T[`ٕYXݜ!:[Jc9jlƬ/]͗Lj4O_V'E/dPB"ʔOOGWGWSvH_#4Ã`qDfS9o+ޘD{ puw6^w(i@?\j}9AGOoi?ɟOƟƟƟ7xlA;"%%%%%%%%%%iO탿 3[N2zJH3:_^ aMa Aٌ}ގ=Ps2:T, d?~_ @KA{ӏ}ƕlh9ƟƟq@GG___p@GGG@! K:j____ߨe/~$+++ e &P  .0ѵ,ߜ yu^KO|J 5pVncL~hv@KH +XX*X:<͸˛W}d/KcI/Wv1g?ҿh)gJRi4 [zcGLzmHi}rVpXp/⓭c*(_n:~$]ңT/?ɟOj_xt4k%԰ƍ⿲.--Bd.߿ p(&ϴ OOYe=XռMSM3Ҵ<ٗRܾky{Xn1c/}6cb@jnO^ؓq4b'#+m/_8+=@ #)KJ&!Bv,+Bavdw紝>'>1UZM:浉n[7Ӻ'ǿ|ǚ-A9g|KI??G' 0Zcɢߤ}d1 hu̺  濵C1ZᖒD"ӫjY9IeFI\ZEſ?p|0 Ž[//O"2m*)) En}%ٍ䷔naSSs ފԶ/ kK` PMMt>O6=-T<}b erVZ۵)/Eخ'E?qMiA_@7B2!+#+߈Sā=:S b5bY:NZXxjLO_[٢eREbswpE/KROGWGVI+E?   RIKKKG  sQ~-[oyA)/(τu٣LvDUor5iS'W8ŠO1vyr}W*_jUmv9@#_VD'n./1lRTkhe_dxXYC?DBI/c Sҿ? _(F7T펿Rfl֞dV:xUCW3#kJt] >nqPS٣l0iz*oevo}}X_/R??xƟƟƟO_deeeeeeehBzFKKKKM٩P^,L|*_*d(Enth{RijfM Um"K4\;(hth{_EcJǪPVIj?φ ?I^t+x2Q7" üYa6٩B!uj^GXVT~թSرcԑ;ln.//iYKHYWGGGGG'q%+K\|/oooo>______yCKKKK+K5a!$[i0oGug9u*|nv"l"kM|*.*RURyr^R2xPa>^9_״43 )iJj 3)/MiՓOIOK0+?~*k"t#q'D3\)S'ŮVA1t%tܥ.}_W*#@r ɉ/-дI%ǿƟoWGdei4?Jj!%%)]/ C-??,EA=-{?*_O?Q_%!K/_Jj͟7/̝35UkZiŧnS S#ߒ,TnuY_-.IUYEFũ]ny5 Y͢/KR9yqԪ\UJW''8.*aUYEFi>Dk444>o6 N`}V__,5u} As NEbK'%|~ΝBn;, h=t}5EY&QK4OȄJ'#+!E!9 #?}xow !C_W?)[!PVI7StT aRY={vGxg1j/K ggx\9qFH[Ì^$8\R`x%Δl+%c/I* XNu8/Tҿ?Dw98~̃ ;1|A7K9A |/C&ZrS%}1_sd򸐝FH q1&:;lid*H(l;wt'oעo酥1*F okEߟo˹1yӒK(?c߶_ӟ[]%##+!A)%) OOO?(!I.*~QA3&F-![O C&/ m?OsD9+2zو3> \B6]+Y(KJ'յ3lNNIJ'TgLe $S'$S 3K2VmjᩓSIU%+6_)T钿dw~oHl͗pJE6ŏZ xfy"q5Ul)2O;4큺9ALK>}rA٠#~kQW?ҿ?3fh^CKS3OOsL.LA_?W?(  _QEQEşRT-|Cs5MEDƙ/@"1[I?pzhj*iLz뙩9eNcjFbqC&>-;V/u c+Ԍ70*^]E U@EJz'(IUzP^CQt! !4[F`HHn{ٳ|wssI߁9;gvvvo3թŹM[1kBY!k8(5`#&z,t=T=_|eNg w֨vOCۡ_!(B/_?0fyN)c62:pFRq̀/ο8S\ct,06' #Ŀ7F8ḌΒ/6hx my9ctaUqo$+Ϳ4֪ECի0_*@{1` T*(?!jtTRT$#i.fkF/?7c0)JTa6Pf=FJՃ` T*hA?3D i.fkF/_Bn΄IKߣ4QZzKZ׈u V';nM C)KYr|<>Klm|l?S?Q9peQ?1bl}.m?8p/q_\Jc #i|vivf?nX7Z`6(n ǟK82`Uo!?'Lϊkؘg05zI), .l|2wiA{`]YL@RY N7j)3d)Ye"aaOF_jH?`{]~/FvRl]j5BUx|$2@L)?I}̀@+:S]%"0#ԥַ8꺏lh5i5nV bᢒS:jRPj_cy%\Zvj>́~J%]tQ?O{^|!Z3?==Ϝ\ \3fyFc; /?0X)JHfQV>2d SH9#wpp_P/ 9)O*aœVr) pz 73gʔ?Jc=_:)3 JwljkkVgAE4` 8VBd t2*34i59Gz) '{Z!lF@-bΑ:sJɞV1Q3y˨sΜ@prf t2*34i59Gz) '{Z!lF@-bΑ:sJɞV1Q3y˨sΜ@prf t2*34i59Gz) '{Z!lF@-bΑ:sJɞV1Q3y˨sΜ@prf t2*34i59Gz) '{Z!lF@-bΑ:sJɞV1Q3y˨sΜ@prf t2*34i59Gz) '{Z!lF@-bΑ:sJɞV1Q3y˨sΜ@prf t2*34i59Gz) '{Z!lF@] '>itH8k&L ܌"QIvQ.d,tOin!{Ih*O1O7g?8\ _?2d'OƟ?2dѰ·C}n~;W5/ӢZZZi~hytSNU mD^|Y뤁1c-) r:rX3R" AxZGKcZJS䀧.NX3R" <#Q1c-) rSV' ,k)ULO֑ҘR9 ƌ*'OuT`iXKb|ԅIKcZJS䀧u:*4fT1E>Ax꤁1c-) r:rX3R"   M؜ԊXU„^' tX]RzYײ%V*E`8AJZ&C7mTW/HeEC+Xh00EO,Oߜ#08=oߌkK7mF? }0n +Q?8R?4|ο8O?ðhw]r4bai+Ϻ'\°0i҇o{cP WU./hu :9` fUf`ru8S_ ʽsS')9NS` ++c')W0v9T~IN%Kf]*ڌ"PN(T6&鉍O R~z@c/b?pw~0`smr/_?O?0$؟:>_C /嚓:?\3:$b<1AWZ&Nj7?5Dv7?jjÑOP}fzXYpV]YZP!GkXO S>Oc. cxdCեi}z`ǟl`FUkaڛԳNq7b{jC\ܦyQ/N 1uئ( ģp:'J@FVak7+԰U*[g;sY>R̔zmpe'Oߜp12Lag2d'OƟ?Ϋ1f0f7oߌ3f`~uV~7u=?Op׀Uj@ L? Jpnբ ]:M*hO`c˿׉J86X@5zWi %{ „;5kdnǒ:CrRXG c ?'s^ çoC܏vڄN)tYBcu]WL8394TJ:0W*?28v& Ź_vz q7ߜsp/\ _T?O-&|R?kPs(ưf_0эEV0`+s>Iݫ]bV"K`/S~|kb2]bƝ%0?4kGCc>!w G `Č;K`/|}u|,mNc:D?Q0L-q-d4kb`Q{ăg^Fl ѫ~ʧiͦ,)Ruwc_e_a_LWΒC>amPM9*C}㨂۠"sT'j< 5[NlRTĐ@m'1SP_XAE6JĐ@m'1 _a-d(9*C}L*hTdN y3g+i:^hpJ hc ~?dY iӫ2c @IDAT+B-rK~L?Out" WG^?8p`?^B$Ɵ!Dpb&SM-qp1d7bPHac1t 9?2 6[?7&0&OLҍOPZ'>^KrƧU0/R|.ĜJFxes.%4RSJ}$I@li\^v1?[b(TtK,her.e" /l JXƟv2tW  &۽}A/mpWQ؏RFgħ6;dv߂/?8pg?r/_92`?0a3_4Kmo+аPƔ$nqE9*GP?,cVi_HP_Z΁ 9_?iPrYϋD/߹=Η֎OhۚlWE@k9*Ty__-d#@?߼\wοʽO{*r[עlp4뿌?Z8r/_%N}Ԛl9r/|pdvE9#, ~'#K HTyA=^|RIʵepH"Wўi~OE8WR (6\$hχ4"+ s\.UCSpʹ .I*! Bj$rTs\!rnE|H{*Z@9"\E{>=\WH-rD=p+PmpH"Wўi~OE8WR (6\$hχ4"+ s\.UCSpʹ .I*! Bj$rTs\!rnE|H{*Z@9"\E{>=\WH-rD=p+PmpH"Wўi~OE8WR (6\$hχ4"+ s\.UCSpʹ .I*! 8j'>aR.*OL+MRhN*dӾC%jFχ^9* \{|="u:ۺmFmL6#Ʒd{}fڏvslϩv???şN_8qKCCCC`FKKKKK ?3y$|=ħV*}6_>wA?I ƕ`vhhy+c% ViU-f.3e>h/}OD WՍrAH\G *Fi?ZU 5 LϦԦݩ gvy\a)A+$?eAM '_}Ң.!k΂ëz!]dds7k~i}?YK_???O??ƿ-/HKKKKK㯍?0`?02o1 G>lwqo#t鷑@p`SFqHӢa81jڟنega??08^0߹9A3F'=/ Q}!v3.dE|B'>'| VC{Z4k)fB{9kl"O(J?rY4ڿNs/οgq '4!_(ꮿq oߌ9/ο8/ο8S'/Oߨ?m30q&P.+ {m|jzY\z!rX?Kd^ Ej].P|$4p@ NgC^zQ~_؉C4Prz׻^_a'y*@ NsgC^zh8kH%'8Ν! yE zv␧" 8w00ggC`kmN GY;aI\vy?(M搳>=QMVez.[+?b%y'PE@!eͶYx0YkuuPL1a* 5]+,#[R-?n_EƟbOOOOo\So0sӼ)4e8p_>ɘ/_?0`L*OtqoXTw䙌Ϙ#H3XҽwdLIi:TS?`V;2$hze;HC k)w?~t}p)m,;.TЌ\[$^rҽI{.E0޿?S,K/5WUؽT￳_jɥk.fzWI-@jʟv:`v69[cǖ_Xi 5;[r8!??ߨ_t}Ё*]wM.g7e;d>#/4fOʧis']bR_?j_??!Jg1c]ۥ5\1ʏ<?ᅡe/z_3t_+$2cݓvK[?!6>pSi>^D[;2wSl|J,ugrzԆQ 3'DZI5j1D?ډ\K$_2DZK$Ϣzc㓎6Pw{KmČND]fZM]YCT/6inkrFNt -4]P⤧q⓪ҮSGDwήh\?= ilpU2{„;[^{yyi[:`(&zH.rkjϥ{ʣcx>zY?_qEWq-֙/UW1v&6olM >6u)lSyi`7cGӫ?(o^?4@cnIXGC'L`d>tvt7?;f ?t097t9_?q2s[{`n` 3ί{g:}֖WXAod渱r90?[&vkrg5ħXJT0lP$u\'~Z7-'!q5BN5$3I@f@ў̘ 7/ tX?5>ntR2=k6SIcbZ8k!I?~M]EOy :u'#G^}bMCr%]{RKYt2j蹦]>:_ 3v.qՑ L]vs=~wu՗zG8Hl|zSO 2 -l\Ͼ'l{!+;/ wa})g??':.7/_]hWs{GSn~a!??0`^09s4CS0Xw)n'\;?n 2fHFOky}oTZ[#쇆9e ?/kbЇl` jQY.3΁^Y-eTsiVK20cuyRFe ;z]fQY.3΁^Y-eTsiVK20cuyRFe ;z]fQY.3΁^Y-eTsiVK20cuyRFe ;z]fQY.3΁^Y-eTsiVK20cuyRFe ;z]fQY.3΁^Y-eTsiVK20cuyRFe ;z]fQY.3΁^Y-eTsiVK20cuy(=N'_{Cs #t& \V1vi{AY_8k%z{u2Is5пfBōߊ[`TwPQ#WAfɘg K-kU?|q2 .G}<;M7Xцc%O:Uo6A{Xp䉓ڕ?~n:JƧ"(ψ L@>`+uPF1|FL`(u^hCK&GcbNQ!ʊ>#&0?Pǿr+dx1SZEL/rOt^{?Xq1ijF°Lp$*Mb0xa˔n|ҫïh}s&?>}mAq-ҷuVxبſ3/׿"E_fm^^d4dYf[mmoמ:W\Q*YG'7a/soQe`{ؤ;6O~ndLOaӶ;Hk;(y뭱36Ul|7jόi,??wQyOpp:57z/:mETw=5_+0OƟ?2dG(c^7K9r/y=.ĒםwJ+믽@ǿ'+ްg-Sy♶ֶ6xR.dZB=I0ύ47wYdsOi!UV 9l}UWn]dYؓ^NPfb=dK N,eYFa֔iD7 iݻu;,roY>TjN| R=KMރ]vY֥YNn'6iv*۲r3jK&]ve酓}w'9 4XfΜ)K'n+,p*GeiIu_Lz\ &`iժտEdOy Zp\t&ߠ۟{/ɗ6Ayq;E}IVX~ypL{z}dM^ɔ~-z~n|ZoÏ8ϤDܻlFoo-mOgmY~ JVw=Y˲kHt^{OK\'0|P.ȢZ[,zz-0u H S h5 mS{\}jACxezSP$aÌ]vS&`㖷٧F gr\w +2kf\w䎻'U}B>@K"&}{MG fC<:?So_k .Tdwn|(ǝp6|n*[r츴1c\uյ/C_cQ^!W@9P&VG$?}ty3<U+Eۯevđ2mloI.h_? Eƍ+y 6:k 웛n,' rr?^9dlj^_7OQ Et l †?\tX^TV]Ynl~n:nraGekݪ}_͋rigKB *0+7tA1XH lY>i9ߴ^9߿!(# 4i>__,ɱ!8"0BK_?сXau%-.4-WC1ߌ_'B9]p' `2:M?r0p'\?SN:Ay!2k{~YZտ(?1V9a'OUI=?ɜgE!aKmVaOqAKue_ڴOaoB_zQxJ 8pq;bw~l`.HblEpF+z֌9EDX֣vS3PZHˆW^ ,ܔ?tlM7&7|09PO`lu|WƧ8ivӜ'kdl2}qj|mz*6q覧Zgw^{5u' iZak-n= 8wgʘg } ^LkvYi6l1{}jMGSp ٳgpr#T~9A6> y/mn{bЇ=(f4 tφngR0t;@~O߷7k\5 6>rIg.xS6XN*̚1+JUʹɗ [Wgsos{߼IFVOve8i={ =plN|J>^}UFS~G:SƱfUp7J&?o~7QeSN=$Р@mS.'+m7 /"N:#U<]bsWO7yĒjKHTޭ0h|V?񩆜ًzW $ԠZy<+Bu#GSTU{4=i5)yoBK/l\Pe2nV$oSi?N DRLeN5]Ԧ ͯUSj@&׍TvSԿ_UK SzS58iK4K6 _=ѣ<4wG6`oyMCSsY>axtL]*+lWC>JM|+] &K/"2hGQk̘9]ES)PK{preW`wm7Wv> ߟɈ}xgL/VgZzC lxvdi8jyh{nr䣟\xz䯿޺2*=J䭱tIYg&[m{|W瞕O>DO6L~NL9I_~9d؀곽KsZגM7'bZ^yE9SjSm%w~ѣq*Uw {d$/2NOve]D5tMN;Ⱥ}։T˰CG[q;nI?x9&CvM2'.n3N;9?i׿ƤntH`3t6>/;coMO \yԱ+˯ wW#G:{;$`7Pzذke Mȩ|mviR?Pܽq`|G{ _p ?C >W)/,8^#hh[y*52f}7tXlXnqUDg)S;矜矜s!F?,뷥,R.?8`z]uur}.ޗ\r yIZdv+[}=2s,eĒc3UO#ɳH+%yeP*bW d2u9_uy.%5 eL'ua~hvU4\B?k]~V+.&bYRz("IN&Hq>Yz^O#z k 6槪|Oj_;-凍SΓד58FwD#œj\CssQs]S VO[ƧZrz_Y)tM>*S!'`vڲƉOv';jjz>p݁2}pzNʻYO:~m)R55KM*z@OOO'>aLHO7>iF߿g?_|qyisɧfa(O|ܞgȴ暫*N|:􈣒|[$~CIVtqߗw^kewlseo|3f̐=L@;!\E/_)՚>o^| '>a3* &lX9Ggsֺ *r&ڡ,TæLbJYw}l|2#hO9]~ߤkK.@?_xWSN9#nϙou]'_]aVΖ1cꊍG>rWcO09tc=w.ݰ1PsgsgoPbS+$=x%l"Ҧ9dݬaکge]nwЦ&~OCkCBt􊸈_G_kj$˸(_tBIB^)Rt>y7QC?3?/0lrO/_6h308[Kt~UJOο8T7o -9/ a|s-?s!^|} ݡ9N^}VYye箟?x9ì'LĻ DfF'3hFdJ藵骒|uP.1p'L"kjy>c:(JIwrh?5}gAl?{0< 7m}p 5Luf+ -Nt2duj"ѳN|д`/6췯 &&U9xMȍR%?ņ)=t˭(skhD)+-oSI:ӐFt ĢधY9BMeN?'3q颧UA 7FJe[F_Kicm8Z ysģaI;V=$O|Rz2p߰y+|xP46eJVGVXa9q'/Z#_5彲UO|:S񀰺\A5W\~N.^~e9t#7^d=,h QI>|lX*nk]!ىNxkEվ ߦvي@g)^'6o3ĝn՞>?R7橼{BɅdQGMZZ>vC$.m7<^vM76ʈOʥ_`S1|rm?[qӒK-iuSɧi6?3eo57ɓO=%gHTfu(ygğ6x#ΚFx܀? 7r9_]Oe7 0`G#(.sC4_1/_jg)?'>-֭,{\bIS亟}?y?=rם{<[oE_qSxt7Gu mO)v\VCPHn0vJk2|)/"ƔPffzv3R4{[M pv7-XFG{%̽cn "t5nÍ7SJri<86̌Ռ Mif,&-_LPuSПJ$z#,Z M4M7,7b3% OQۯ|7cI9?dOۧx&N l?<Ѥ o#/6TA?;'5/V??fHi_/Oѣf {hChw?ڟ*b'|4#uQ36ʹf7۲_* `Rw~b/F?p>6A?\| NXw6OAzN|XxYB0QAA6䣏>.T!X>y$n]!EAQ뮏t#qÎJp(mk.Ƨ뮿AnNk\scF|L6UmqcoO]7p/~Qn6?I| d4ɥD6,F~Rk&4Nx˒=5Jyuo''|z/[cH~ td:5ֱ?WS?0ۋKI_OPo??O\ra?u,PRcfWq~# W_o;?GƟ\yDu:?οh s nڬOοo"2doȏtÏskw1kN,U7̙/U.jy״'ܱ-%( Tj> 4 -3P(JSGʔrzYR&{ 9 U׉:jRRJI6Zi)T)S[NKPjdSLmrR:/BF5M2jI鴿 Ux`J6U!'/|׻fM?@_o ZMyGڼ5߆=^crɎ] L&>$^~x&64 f&; "9Wh=[n2L]~{wz?4٦3tfJ Ȩґͺ ''QtS\jBuM.6]۴Zm*wOto4{ۺV\?t6䪫 U;n `lO; TRϲ{ȑGbz=Qڞ_O9PO| !˕|筷ħY]w'>Hb{O<' aR|y}w<ӡVݣD/i[׮2G\ڥBuÉOc!d-7WNEOV<(K.x}QmZr8y +l†[vr8 ߼wI̚oF? WzZmF?TF7+uG#ov1O>!]tSI?h?dTqvi_n {tftX}iSu[n|iխ\~WY/~MG7%JV\[Fff(?ov$R3fΔ2bh{&=Bq;Oooq~{X,TetT_|jE?u0WgRj8@ 1U}0"@èfbj`C;1|kœiP/_'O5M2.oSOƟj'Ƙjzy腔7oEۜOۆ ? Y|go9geX|ueB<0Y~ek=e^-2g'YI-;^ӪČK7gZūVLxD!sshH(t܆E0Pע,ӜOS4n@ ZY5:ssqhNah%30[h3$D4WO`2)O *%Ln:#0=l^Q6U,lr`7baՠ]lٯ!XeA഍OoRP=V9Ccc6@d榛o[MInƨ@׫Q6߄gM5qZSxhNjt?S|ӓۺunB^_fHYZ_п֕׭nS\EWˇDK襯w1.]yEN?twFVd5Ni U,aʸ'>]=w܎O+k '(QI-d=]&#oλp^ؤ2A$wzσ$6&I?;f7K$<&Gq5'Ƨwf1ic&Onv 5hjg՗q8Ï2ᙧډOZK.z$*O*UO|Rrx'M-MB(XwNN88߼wuOv46KlN ۯ4*"ĉO}#rߗoτK6:U7.mUs'v_/c# e`s |{(kL|6C3_Q/ˆnhTCO._7q}h I8ם3S* f=/GSoKCsЗ؊/_0`#V?8N8n9bVο8K[p5ᅵ@ps8n&>(;2 LCOj*+I~}eW^ܯ.=cr2qbC:ןA5='W^mkKóiM5N?裏?M4:oBӕ +=ӕ9BcjI؉O)'wOčOZ3xfMl|2yiXzrO.P26=91Mh26>) ֋z '>7>)Y?8Mn=v'>-=[=*FN[n軵Sg@|sV^cרBts^;|ޢKîֱG:']_r6 R'9S讻EKPH[B~iӦ'SȽݏmr#6aa^/wuV[\zwrCLһIm?C鍨=P_ڦ]wA6d5הZhF|R9缆ڳSIO%Uo:վaGZjO3a9p C0b_pv/ο_O|3oԓX'rBH9?Gp'矜rDo2,4?s_n^)|ߟ}+~YW~p6_* |Ѥە?~aYncs^Eչb,qD_ud!#H?(Bh) NPT.#8g>`0v{;Rg^ǘ5x#ƛzWeڗ*;쿯 ?³[ncX!/\*MzHt‰OO3`N|:/ħp xy}W9 \lK7=91dl'Y\\'îDƧAڱ‰OzE?R#_c''%+.[_~yg3?_#+_+KZh/2N|:)T`w{RKϞKٛA|{YF`bV>2(jUz=ȣ-T M2ffSy;zgl:c_wk{v‹2~r|_ó5sJN>Z>Ƨj=C, )'xݶ N:4a6P=E@ e_/C.?4 o|myzXyʇv«7RYڳ@Ce?MdUyAZ}G*?1 }8pO u@\adBk>4-LQYIE+/Cj;a'8c _?*/)8/22i~ٶa?ZUuQGbS_yU>={{?ZZcp6>yXMh`Gu ( (ѯci$6H8oR~Tp]RWJb3EE`FKo7y9pq u{jjܬEE%u¥G#ߴ&Dcy#)ob *ߛq '}y)Z gM5ӿM]:l~RoMO}fW? 6? N_vSTyOxweT3пUQi8M'̚ՊOk'=Ēذ=$;%?Yfƽ#rd-rǚf]?NzaL&v[~;IOW>86]h?h6čOP.P;qWӍ&M4@ljO'H?_rDw{& tn fFU}emfC=H 6\ @;v\~2Ƨz`+'V ;G6dcc5c o믹RYg|ɯ_|Q?('&QfBY?ܳ[nb2o֨s(m,y׌c;"l|OSJmtSZ 1P̜5KvƣIplʌw}N‰TmZN=D{)8Ij]TU?W7A}%bʿb=E -7Lfp^LVXAubAC R lfKWIUB Uog*pE57 5CӤdFQVjU _?f?oP/_h5 Ɵ9}$^Ɵ0_?{ WtHfGsxy?x>;HQ82`/Ɵ_zz_Zy1y⇛'ꫯRߩ?P=?Tڽ+/~FٍZySO y99z;zi3S(sͅ-Pmm`T-Pa,bΑ֩X+r2eT9SgNi 8 9f3j:osԙSNBٌ[FŜ#=u=c6fQ1HO9dO+ͨeT9SgNi 8 9f3j:osԙSNBٌ[FŜ#=u=c6fQ1HO9dO+ͨeT9SgNi 8 9f3j:osԙSNBٌ[FŜ#=u=c6fQ1HO9dO+ͨeT9SgNi 8 9f3j:osԙSNBٌ[FŜ#=u=c6fQ1HO9dO+ͨeT9SgNi 8 9f3j:osԙSNBٌ[FŜ#=u=c6fQ1HO9dO+ͨeT9SgNi 8 9f3j:osԙSNBٌλN|Ґ<7 prR_5aK@8D&H6֤mP.d,s"8h "ozHuH3UOpӗ5f}7l~ҺCE}z@~CV޿JuV|gKl RTwNN}I7ida]s'w`Y'p98]#N|:pUr˥]6>PO36 &sO-ħzˑGm8yi{N|u>SA?2&N<:iŗC?\?C=e%=%Y|1lC{fw^^UYuFn e7/$#bMg~]{vD&wy $_;툓pꛅ JIf̘fOÏ8Fx biڴ)wMjwq|nU Ȁ=ʌYU'/o?Qr_ObSZzZ?vZ ~~MiJup'o^xħbjL^݅=,e=iO<0N=[U=^=a`8 ? T]ȷ HRʟ{/w5ڟ_LgncT= ?i?AxZ+6aKcZJS䀧IZ-X3R" <01c-) r$,k)ULO֊MҘR9iV ƌ*'Ok&L`iXKb|4IKcZJS䀧b&4fT1E>Ax1c-) rZ X3R" AxZ+6aKcZJS䀧IZ-X3R" 䧗_{C^uiMhE:'ͅkِee?N|%jk<{d7z/}vˈGСopƌr/?' m&kqljOSlShn2Rq;V챇u!*O !7h_l|2\~M'>29~j 6>YìҊron8%IO>X^{MyWpҊߑ*qXyŗFrE?w'?ϲ76/Y;lS>\(d'A]|MC_~v=tPo}K?O8^v~p?t<_3>'? {8W^c(xz+)c/W/ʈ| (OױM6Gz1x㏺O%1bՑW7ƟxC 2d .'x@p`xW߈<8/7{S]/Wӧ˭.7vGo+ YV ?^A;,&?yaο&M0M?)9_`estl >ڜجbՀ^o)U;[')9NSh?_ 3(@+j@ iTU^??Ool|*?AFm\r_9RqHbT)?=\<|lGo!Zq BJל꿞]H{D GjiK.`Ua$KWX @S`E"Th/#HimXJwPqiI Gr"(EN|߬˻ֻ޽;|9䷓uu{s:OOyF!ߥOwLA1|{mwNGnezhO|&/oWߖd#7O_Y7ەt^#o|mby;?T~]R?ӥ~MUKO| t/~@KI{Mo{ۦzMoOBϗ73 W]n_Hrӿ>O?Zemտ_d;'=ϧ~Ovk[˯<ɃA:U=o{]|zӞ1(1zyBcY ?O^P>[o[mkOZ:?|Mo~gvztg~RGY_i^u_?}Pjmaeooy]xnyγ'c,xjW ߂#񯙂cCbK%?4 A)'t(j=s*Ϧ OwGk@!쒤+G:3{ ?*|pO~ҡ0}@~ڷOOᏸtCp;v9#{柇Lc\Rc)ߙ%@PcL;#QGX$d~ёiAr/c?C% ?ʶG/:Wm\%=oد(G|Wq;ȍl6N*gyObݩ~"?q<2طo9=~:y!izm}w6/o|:z/|ڞOG>\nޝZތt^0ߓI˿Im߇?_LU>}g}/z<s[ZIs#Gn紿#Vs:x[d/z󧗽k_u~J>#p~q-}{ӶMϔPm]~oooț;Z//pLd1} ]f_WCS =}b~]o_.igGP׿)[ ;qk/7ƧoXO2_?7˧?2m1黿sz?f~aS@λʛ¾xпw?soWH/#?79#g=CL_#n<7Ƀ`L^tE/%_m˿nS3W}=q_tU>I~4Tqǝ;~w =6&/Ǽ3ũm3Uj~zu#E݌VN4?_-@!D1&'7']yTV_ԟ^iP?@!b$/7p.z4$$'a73Ř!؉$0 `!Ƙ!؉$0 `!Ƙ!؉$0 `!Ƙ!؉$0 `!Ƙ!؉$0 `!Ƙ!؉$0 `!Ƙ!؉$0 `!Ƙ!؉$0 `!Ƙ!؉$0 `!Ƙ!؉$0 `!Ƙ!؉$0 `!Ƙ!؉$0 `!Ƙ!؉$0 `!Ƙ!؉$0 `!Ƙ!؉$0 `!Ƙ!؉$0 `!Ƙ!؉$0 `!Ƙ!؉$0 `!Ƙ!؉$0 `!Ƙ!؉$0 `!Ƙ!؉$0 `!Ƙ!؉$0 `!Ƙ!؉8>Ei?rYE~8@;@/L[R hiu)ɖ8T z>*RGR6?*>럔&pڝ[{_?^;^vm"e ~ .pU̻}<8$O?k~ 3>}ԏfN.7-:|ͧ?҇MЇi!ֿCoMJo7N?%}qmq0nyu'-M"u=zz/>Lrayyteyu>4}L^}Q/\y{׻[s}olN| :m^\+iv `?K!fo8^S.zg_v'@MMMMMMM-@⩸9*xC!?/$';O=Iv9^_mt_'{كOq"r*+@;8\ήl8r 4owdמ 5֛W|Wf{&?_6!6v/?ۚ痖,$KU9NT7UFYy&_t<`&pw緓T=_y.;x֫ ES`>G/TO*o1G'Qmo9>o}Ж=hu_(oKz㏹'{sțб?5@=??[q||YK]¹UY"-3Mx?\CGGG=MnRΓP~BmE7_7?$S.3iV}Or;=3Gk;i*ȅ0av(a==.:ߓYd\ \/g~o6Q X{2tK0O4Pc(=E%U ^)17lmfy?;'zRЋF8Wu%].㘜LvR׿I+ݎ1m8w-M _?ogM-oӾ ?߿:HbX?[Q4\=#g_-$p=ϰ?ECO_h@%OqxػuX@$SpbKmt%0ji ]Cl鄮?_^"exv.C%%!ȿɿɿO_}̆ UcoU]" ->ti:TH{ˤw6 @[&_T4Jp $ܽeRU`Z hJ%U8p2)*n-u4 * 8woD_:RINL .?xĮ i>|ڛQ& Җs+P1}Ij'sۯq6%< X)_Qskst_on]`Z8>\_M__%_|[e% [_%_7tM Gw$S2m?"սoX?#?c8]<Oݰ:h# 0+(WD+.!w$_____ԟ\U)"'\POD| ׿n:>ml~YNNЃS>I.Zmp]ܠMte/F?tĜG&TEÿa?xh2?fbtXUڽ;7>m5ɯۛD7;ļv%uSXdM`NW (oRMk/=3sI.Oo[_?Jv9b-;/tzw~}t}=t~~u?\?nagağT_/יX?ߙ??og'C!?-C#/KGl?rӻ*M_qEgjPTĿ9ciroϨs+?_U%8ܝ}*SJp Hl'度bV?ȿD58J\m̾SLZ Oo2=o|R4/9'cݗf'vJ'1A뇎>klC='c!${NǺC)Y;T IuRNvJ<99p> gP6x<$sr>}"@H9ڡ*mxH}k!ɞBi}UiC='c!${NǺC)Y;T IuRNvJ<99p> gP6x<$sr>}"@H9ڡ*mxH}k!ɞBi}UiC='c!${NǺC)Y;T IuRNvJ<99p> gP6x<$sr>}"@H9-f7>ɓ[vȴJgcLjce=Wƣ\j[|Xj37> L??-$C҆ӑ_/k52[_io#1vr^K"kY///O)k vfkN3$Q`vo~Ǐ'lOc\QIx JlJm,rNҞm1|xLUt` D1؟=7+)A$#5-*O#/UKC{_{I ƭm6NoajpV!LVpdmLˋ`K~WL??N_/k4??????????$oߧ7#\79꽑b+|+o|fJW>qIN`ѤzؕP,Eh".mN9'U.%9p!_:{ݘchΩB0qn's*?B t\aI@1O8.׽n؟vP>:N @u=sji"${ɋo%bT/]sɜj7lmIsLNhMC!/~rv;Nxߖ_lX|~oj8?%NuI%b 8^?MEP#@݁2@T7/ԩ*%&&&&ViyUEsr˔BEE剗ȿ?2xavq<_k^#PצX>tݕ"u | az-zvx8d~d)ΠXBF-9}bǁ X?[ 4E9}b WB@};Qf|]^Q mm41|.3ObSs7/D%m'|xϭc_/56vE%ИVw_/-_sY6T.%"EO B%V _Vq 6?]X_/#}Xm3wo s_䟚LВv6#)?fx|7>ijOD1T\c]wUK38<̛8?lG"J^Y LNV_Rg\28r匳`aeCl*ә%WyA?z" [*S5|qeᥩK}Ei\tOvG7m1O+- ־V^XIX"F@CA"V/!$$lwfiJAAAAEy7777wW,Sl[]Ai:1yxW6`0O%cIIЮmNNh~9Qp_)cX5[-Z*fI)Kƹ)d,))<?\(IN/"$}IɎʗM ~ۻg&7>I^,>x?Zon_S?U4z ?_lw//OooqbaA)_/W|-C5@EEEIMAEWoMNW_Y_nڽ3{áwSܳavZQ\ۯn8|E{ze9;%p3 e5 b@ j?+@Js ,?<@Y@B[OLYwxi͔;uNJR'W[bvTN)Ꚅ[mLeCPtߤ8.zmENnSc3o_|{UV?4yV/,?9?[ ޠF꯶t]R7s:h{B _$<hy'M_?z;[o7}Il6NKݎ!MsX2 V"?0c9H*X8W,#`,\1sX2 V"?0c9H*X8W,#`,\1sX2 V"?0c9H*X8W,#`,\1sX2 V"?0c9H*X8W,#`,\1sX2 V"?0c9H*X8W,#`,\1sX2 V"?0c9H*X8W,A7>۹"$q7amL5鷫7(&LKtw;Ϗc~f؟Xd7v X??Ml?5t%75JM°?S4A=?YSPPh.!G K{Z%}CMC?4JxTaтA˂CADFEytˑovu̿n8tU7R;yPrp&?AkRӿEԾCJ@IDAT2SZ#xGoG"m8W$=.kѧu~~o?J"R?__oFkK J#R???2K,ФHSrYTrM];ӎܐhyMFGdw-~!9s,A/o1}] -B16f1_XWbTft4 4Ɣ,Rz+hYs97b+,RH헯bfW_䮟A*,M/+ ~.>B۱GD8'[}HGC!x_OݫCEEEEE(ϾPPxSQQQQQiD%J?h=ڦCwL}V*l^O'ڵvo_Qy0n4XvOStIfmQȈfb1.3 }(X?_gy>. h+J޻epgrIfђt9m ;9rqc7Z36-!EĎ?_oId vW'?h4~GU_Ѩ%OCEAAAAa.''7gIv /_X? ]?\"Nhn>r|ޕ76Z_7ȃOrsMhK̤dy''kDz7yį7%Gm<{yrM&va8d@.J`~USPYa%mM RzXY(t6?K繁2Y`ұT [`S<`N}wUf[i&S#yQ0}8IɄ\kaЄ]yI?m@ׇl gR; Fk؟֟hAC?jw<ݔZSPy''''''R{]@O?D'@ׄf򬒹vNSg\*-Evv'otwxGXittq{S%m*alڑ |#7rF\r|EWc8pB4&m~UM_JuuO1uC`fski6SM'%\WWZ(W&QLa? *tlNJPjM&tº9c>-Oi`-2/Êt[2}Dvw`kLxp@SttyL1d_G؟.$q__ȿɿO66G O/K l_X] CmK w;-Om9*ZҔ%[n]gjUŦWן4xwwGg/$eo. WDl=*KRZd ӈH-4V׿ s<;|;BO]3 $::G ̿X2Elk'׼g? ?L_?C!D,(%5 1m_%Nꯈ__a YJ!9hu]wʿ;8:ufÇ b&>ٟk>s{iwDS86']{@9 bcFYʼn-=ł >󺇢,h?֟,&Gsa/?Jܯhq[Ɵ n|1F_:ؕʛ wvdGƺƝ'D7evݠWX۩5q3͈?_O(ێ+Q!UFusm4c4WVEgb.~|Ym_v9?-ض1K1F7bD&vCAAԗ'w?p%BK/m )!j)9D\v< ԟUF[#6PPPPPPXvkӃOH$o]7 )dB1g|cɊ O2EOf'b~:- E 2/4QƦ=WȚYgf%U̮^mffp0\MPxW3{Ha3?|?ߕCM:J+ϖ(׿jy؉k4& 4OOO__ZoQ@8BY@%_3iPWZX!vuPPPSPK ??Zv]//K=naSa꯱|fjG{Ƨs慃vHpVVrH58()`1qnh0dGRÂc`8c7p #aA1stFcZ ّ԰ 9:#1 -HjXc gnCv$5,1pv3vC !;C8Gg;[I b!3-`Ȏ1qnh0dGRÂc`8c7p #aA1stFcZ ّ԰ 9:#1 -HjXc gnCv$5,1pv3vC !;C8Gg;[I b!3-`Ȏ1qnh0dGRÂc`8c7p #aA1stFcZ ّ԰ 9:#1 -HjXc gnCv$5,1pv3vC !{)mnM(W-yI@ILmRG׭I;BՁOc7hF?_?ȿ?ނ&7'8tꡁT_?X[-_J5W7?p\_'?q)zd=mJZ>4KX \4įl z v͂KΜq6gE]d3t<b`,)O(gsVE6 .9sJ : v͂KΜq6gE]d3t<b`,)O(gsVE6 .9sJ : v͂KΜq6gE]d3t<b`,)O(gsVE6 .9sJ : v͂KΜq6gE]d3t<b`,)O(gsVE6 .9sJ : v͂KΜq6gE]d3t<b`,)O(gsVE6 .9sJ : v͂KΜq6gE]d3t<bl^&o|Ͳn'IN/4Wz}&a6B.^KֳfW?k# %{1C% R@ٯRzzMMAe:<{BKO ]!>"6QI 'C'g%' moooq\Bv[׿/q+\?{(׻:DMM-C77?>Gy \?;W8,[_lrHHсXXȳ*O77M4WƸzeX Xb \  )Fl:k@b]/DKՂ7UQ# n7ZQmg)w[ٵ6Si+js*!c~/= OKm,veZZ)C%( K ϖSPQRQjHQh=A? *@lI4]h~B? j??ɿ?z"1c}HJa0߇8vOiBشEZ3㌫Z3%:%c=B`~?kQw|#& >lCՃ.K_{U+LםS%7Sڎ|uʺUN!2r!cw˹v>9Rf ZecF4b%?ȿ42j`$$w5*'7[;Th֠ZPM1_ZHHp+grW/ڃq pu٬R{*jo<tO]׿ih*'sBHJ>iD)IH 1o)IH 1o)IH 1o)IH 1o)IH 1o)IH 1o)IH 1o)IH 1o)IH 1o)IH 1o)IH 1o)IH 1o)IH 1o)IH 1o)IH 1o)IH 1o)IH 1o)IH 1o)IH 1o)IH 1o)IH 1o)IH 1o)ISV.ttMfצ{; <\fhqtOɿ+㇫G_^G&DEI_F[OV'F7'jcqCtf׷?L}"g ?Çmu!ϒ\h30Q/=!4=I* }kV2,E.Lb MT("]L TmX?GupOf.r &`r;Wϋ -9v#/wrf1ګ?pDP6K7Cm7".JWl^b XOŃ?_YH'0P] +CRR@7`HUr/E4Wс5?|J=d",H:CJwZI|ߒB~ޱ׷*R.s ȣAMJp $ܽeRq]ڠ`%U8p2) au4UINL QbPGP*)sIaOTuk1i(TH{ˤ0'4Jp $ܽeRU.?xiere- &PDQf阿 RY 8=QfD%`l͸7cGc<] .'aٛt(3bt3%& Ww+-U k$^p+,ƎQ8~"RWJ㗣9G#K!J^@AEI=3?<@BEIMAc&O4hϒ#WEYW _\_"\ _R+F s^:|HɃO;ږ$8J֥ LAQ._ɳ ʹ?'G4(Gov?ՓH*kG /Ec_{Sw;UVkNammZM܋"_ZK]t߀'J "$6Gy T'''7%KBE/_[oSH}A?fтkW_鿞>9K^FXCN:uߏRNvJ3WKUA뇎u${NǺC)Y;T IuRNvJ<99p> gP6x<$sr>}"@H9ڡ*mxH}k!ɞBi}UiC='c!${NǺC)Y;T IuRNvJ<99p> gP6x<$sr>}"@H9ڡ*mxH}k!ɞBi}UiC='c!${NǺC)Y;T IuRNvJ<99p> I-mȪLTLv(MٖshfٽJ6Rj,Jha#P،1fKy&EEIMAEH["e%5B?D'Qdk-(7001@ 'GJI /4SmHo|=ߓyOMZqg",3Aރ3I -x =5 Rx_aU%\yMJXjF?-m5UA'ؾ? #ejBh)ڃOb@~hmTmj]t '覛 FasӒ@^^#.To W[bKpKXAAE!6\OړF/o\ _$rO\TGrYUsM|??|b|,o|݉=6dtl<Xzh" Fb0 6X>0Tx!R C!֠?m}r&!*_R==$]Roɨ{UF9=<$M#?JO< K3?<""$'NV`QR]F 'o#>u^$'OlA O?M?{NtՓ鿪FD9T#gor;q&(֯/|#YDx%p!uKKֽs*?B t\1~ᡱC]M @u[]O蚪{T~ |!uCI@1O8.׽n؟vP>:N @uzchΩB0qv21ukVZ#/{sI)bZ(O/NT{`JrBh"dݖ_c~o&a0QkZGM8/gZۓIZ!&ɿ??NHM 'oI@%(-+߼O͌G_UQҍ3g2Pp٬ߚLV/OaQsF,.E=H -5T'h 76ʸdh?-|ȎSh(BR6OOOp04bA`oQDĜ7g7-Z.sRvPBIA//Kɵs?OZ6)GEכJLƳ4NlB`~Qp\EzU:43΂]cek2u%΅XJ,3wшfESl^RU^=+zeӈ^?p/oۍP-79_;ˡ!2 X/قɿL?{2J?("*{B36*NGKOC ?@WѨ6Ct=U׮$Z F7-DQԣuozdB̏?ml6%cIIcuP)d,))s@|=|"~׊oɧN]\ie나ojJm;)+cY`t4e?_#O?WMoh__ 3V @IM_迨[TI'_ &H3gK"E7NFM,WӾG 3ov'M

(SY(*xUڳ?s~KI!A/Oo&OB(*(o_!S[?[ fA#GY BU?hiϑ>]n_)}7 V"?0c9H*X8W,#`,\1sX2 V"?0c9H*X8W,#`,\1sX2 V"?0c9H*X8W,#`,\1sX2 V"?0c9H*X8W,#`,\1sX2 V"?0c9H*X8W,#`,\1sX2 V"?0c9H*X8W,#`,\1Ido'܊"9K҇&! (EuIYz ]нKP?_ORoWaSD䥘Hݨ??H@hѱﬦ RSgE[քj×g(\"f(BMMMMMM-rCTtzO]Fw\?iccL0)BXᮐ?TU`NYp"d#?w*Ƒ`؟ o9: 1za&aE5cL0SꢪtFϷ6}d%ۂ\mbYO ˿xSKVcێ?#FX!?ȿjXK2?OC1MT5zR7///////]-F, /꯰b:PSpI-kB /_jYu~,h5H1<#oӛ'g9j8 F%cU!&&B\s*r1jZU!=Nj׃j*cxX%*_f{'{Ɍt^[4ΰ)myƻM(lo[NmIQ`2>6?,dG417MD_/_$?] bTߡVZ@M O2jF%I!yD3w?pA?΅Sؕ-LdS3!l0mUa4J?e$$$Ao9 䟪 QhA P3M̈́)´AiVaB)*!TqO?o8t|co-)OA!T!юo(Gh<0wׅ4B`5i(#@?_})sh!!/7^eKSjiG,F`ԿoKCH#|+fOh["GGu-Oz־1?X/Gb._ԟ!RMNZiOG-ue&Sggr\?p?&?Q{UCZ;)JkgƃOꝭڑm 3w΂m}.}t-ؘƨD|cêbTfh)[ ^"RW87SY\qv9oW{e}+h|"$4sINCerҖ_$̏?ߊk7hW@EIncNEIM 'oW,_OYhJ3w?p3Nr _ι/7>źQ?qkwGJgY&lmF(8gfjbF[aTѿL,x3 ¨$è~aqF[aT{?$*_9Mܩ>^aE%˜\ ho)RJ@Sn ̏-'jGGv@!Ce_ԟj 4Fmn_?i0/77ˤ?-ok³)迈>T)6GG]/pi[}݊0U'*4nGΒ=\/?_2J+1 J=)Tx/8'§!)8}@nG&&D?ڞB:W1JVlhc#)O7=OD\bEh_C.-y#,&ֈD13(㩳eDAAAAH t1]58\8R:H.Uzrm.3$7#%ږY6efMQ57doM)A`_U@ڔ_#tʗB] zѕCא?D ]oa- 'Aׄt]Vfjk }(iuQ?| dp"iebsm?{Ciэ]_hCtqCُ[C流 +w=FCia WD7p ;pp:(Nu1lGe頼ԫK)*//Ox}ٓ}l/;{I"U^hf~`s;s<_?6nuP_䟚qfɿ?5ePQRB'O?y֜{O0H(tOtFIW;M{Vp߲=9?,mi(ۇ*T՟];"7"ɃOm)\g^E}_)Y,FCo"6Q[?}G_(˥D'!:#dYnTl!ȷ)aّqkꫧg~w3Yvg\s/~smr=1_zw_ϹF;%/>WPng}t;5ϻ۟?bJY`CEzBH '2G'7777?3T誈kuԿԿ____g{5 .gP\ԧ$Rh`_0=汏ُEГGSjp8=ASR'>xt [|SȎOK^0H|R/?oT˾s\k+|K_2}>#gE_'}B|&^}t饗Nw޵3|b&;T!SPi% p yHM,g?U]IA?[/'SQQQQQQjͣH__6t ΂_tb'N$8S,wݜ"wɯ+l!duS ~p`1S0$"<ݘ-`XFX.3'׀ĊXt [RgO1b#y}\Y+O7Ͻ/{<##=bm9d^dP؜J8_K{ғ |zu6~4yf '7?o37}g~O)tiӫW *Yoӝu?+_Tn:r)[_e/{s|<aytg>?ʯyw__~k_^f7l]4-u?<_Tk!d5~IfDJSV YS|/O'4Po(ϖ~7/'O?5$h"o,gaUwy׿Vt[;XNhb'G>SISD?Onz㮒\0y7jSgi>C.x_?>ѿ~~~>}GӃ,o|+K韼i[/{<،i˾˧\#oE>[N'ro]<=ze/z<#B-o'f_joĊӞgn'8/Y_gqͿ,ɧ8zWAԆ¾0t#_j9b'____BKxڑ )}y\? \y?ShT`)/pOjMEQ3*L}3)`癪?.4|$'SLcLH DWycLH DWycLH DWycLH DWycLH DWycLH DWycLH DWycLH DWycLH DWycLH DWycLH DWycLH DWycLH DWycLH DWycLH DWycLH DWycLH DWycLH DWycLH DWycLH DWycLH DWycLH DWycLH Dt)5M]}m%hM6͖)ɖ8T zBT5{|v>h~ӟ9]pLw=*>Y__I[9t落w[-dGOyG=zO{NO~SiPl|/g/xj~~~0=򑏚>W[6]s5OxzߟozkUd[*E]*>vz.閛?w5 ?jgC?ӧ.t뭷OGywvͯ O>?{Uq?{,%* -&FcI&/bK[^bI^"hbGŊ 3gUG9;;;{933s+6w%WS5הu{)-.U/ɭ7 {,ѩ >gc}ԑ:d@eqs<4K/jkMӧxޞ%ӦM ɬ7jwQ{ٸ&:]&OON{4(؎Oi ry^-s  \P?%_Q۰Y/#&fcbzW?\c_OSLmtlEB'\rJ@%#j4p䦤4hm)1-0-/?8yZο?=/U+E3C7l_UHjLS ab{Ɵ??";c΅)I([jLjW; 2'}uGJ8s/ ‰2ʲ(ʯ(G?OjUzpm4i)dF%T>[n~Pݝuݙ4¡*p!+W'ALprf8 ƱseMܥ3` Vo߄o2v=qc7XbӅOݱI7?ᤓ[o+4cX1MrJ[X> :q& :H'^?a?Iy9"uד3G{Tֿ8ACܹsk',X9SdwHmXvvXV^dtR%kF$>O8Q}]_as}]v l7?n80vl?A:uy]C_b6~zwaOh64 jE̙3.ZO<bg&qC/!>X4P?j)1w|[>뮻qxf}8sϖt k@lr)bg=MN7k,_RXԲ@0tĻ:Z>&?ObU 8G"oP`OʿގSOQLhhVӳZP paCU;_?Α0,Z,= $/~SB-%O3`?F?4:O0̜0 QIS=@]8EO\`lUJ? Q_dS`y_.m6&xPO]`w\02SMK]$ 0ҼFM C٨fcF%0?N~[|Ýl C[;GSAc5C: khDzs$苫\%h/U>a]tm7ŷ~ XAP)jK7i,,\@\7Vn!+/nSK.B7ʨQOb.NSLӆR3R$,9rp\d'=Oǎ9îOIvnE~sŕKM/ jwߙC[o)z޽7AۜwgvQ9Yw 蕗^={Xҹs';vL7FϿ ZJq5I,z7SNG3G)ooeո#Ӊ'O* UQңW\,v!lV#R-{N^>UP$,R9УWjNXz 7D?Opaǝeac+3ֳJ+zXl;k=dɏ:fڿZ~ٵW,Z:KG!*O3^zIf0 o!nd(eL7 /Yk+6z1_/֊#'¡6: jj"Q9ZۦI=Dr8$ M9>XťӠr8$ M/Š%Gp"H@hm&S _!-$(9*ABk4VP i1&AQ9ZۦIĔ?bIo-y\G TO^I:.[i?A"5J#yhM4 Tb1.r1ϸ|t1#IMp|x*_xnʤ'}WjXrٿv|R㗾%9clbaԷdفOg- = M1_44D߆Z]rb!s/k;|ME`[…-2;߀XK.|}|6 |҉s]T=ݗsaf஺淲HK2f_LO_ ?@wb?0C ~B0OąO*ZTO<\5' QT}\TOS2?dML:T[#RxԿ+' L@n07+yk-ԿOvhV\M P3 5*^i Mh n enT8١-Y_v"ǎOпmǧLj=(Ǎgywh2i5{[>eNOWYaQ ǵ\-7x-؉iUg詐cM2M'ev|:3^ }b O.Lё⓵ZK̟/k_s墋/0Mir*/-]|ɥGÇʓO< .wأ';2? 8 X(uH P`W\~q́E3^4v( ڲ2;rHh9#mo$ggMV򲍿8ۿ zo(gbg0e|bXH+<' oU7w9? em52?.]Yϝ#^vq G_|Yt@~&;찓 ;4{/0Cܱ6s`!vkUVk.'lcUο#.m?GS_`gY^NMڟc. O8po>c*7LUhTL"C7`/sW?/_1gL1|`>y)S: pe"uSJ5jo2|$ @e #cS9?Lo> Ŝl~NșU9O7&$%@}lǧBr oF~ (ĊXFhI_(/[9_ ,O6/OWIɏ\rñ[j̝3Mˤ[(h*\]g|H#g;>uӦi)uNt>OArOQhęxlg@݂]HErϜ:`#x=bGzpzM2c 6&bg[oao9E}wX;#B.}8R^}uǧ'p<ܳu9jٳ'F'- uAЧGyCtG~1G!3_yO9Ϗq{Xo!\{v|_iL ZQxPE{=K' (.z(srj]RsPS\1j*ϩ bʩ .wIUCSNpŨS\h2?.*Q (6%5W^e~N]8UPNmpKjp+F-r\E{=9uTWZ@9.z(srj]RsPS\1j*ϩ bʩ .wIUCSNpŨS\h2?.*Q (6%5W^e~N]8UPNmpKjp+F-r\E{=9uTWZ@9.z(srj]RsPS\1j*ϩ bʩ .wIUCSNp>?p$$hb\Tڤ_COq+^J"%6Iˌ_7SgYh/ݓ>e,>=3(X˯ݺͳ>kꫯ!+b .>ӽ"sk;n->u  ?!.֚t.|: ҿ(2蠃d$w.hӆP>4ґNp[x/gݑ.>ߔSeaƕEJwZ=Ha~2A&'9lǧh6uS=d W%Q_uUr-XKs I}wՙnlw&.T:th5}Wǻ+j>W} v=/'h,ZI͛'C|ޯo27zC{>:~b2*t)mDW?P:??//οCdR#(GM/ο]l1ct'?IS}oߌ?1d`!̿ $1ZvWSY } pO *;%EA9V2*VG^ /z}!1e `v#\kJ Ň0lLfy:kQ ~d&)?:48' ;-TQScf0ZuG_ږ_ׅO:uX0rmR." ?zToK3dܘR0xmߥ_!ݺueaKk-st.<(ANH;4,|v5?윅t_Y Ci߾F; ͜iX|@~iȿsaߒ]b/8f8CN>D`XcM5b-G.g8ׅOkZ 40~hNŽOτE83c2y2@!weW>v馛ګJ2 7}ꫯm;Ex=BoRݝַa']7ntIޝ3[-*,~ބRt:U{voY6O;>aƝX?L"d^o](ƍ'N4ŕ?>Ǣ 9^~!fmYޒÿuɵ՘q#=3m: JrU`}Og}<컯.8G>Yw?`I_}v/~y/Yc5#G,?sX~cJNJ>,|Z{-y\2xp`Xt@]ԊO'bWg {QmڍFJCuٟG?.4flҎO]onnm>|k_: [ʠJJ򛫮^e7]zeҽ{wl"'m?!,nV3_^n_.[nAO?gNIv1}D\Pbt<ӥ>~]*{wĈ3xL.vNdN~_b?%VV_oר<$[)j(͊MRҖ?2yO_(H_/i/8 I[Acy0?*?L,7qA'/_.]{㏙wR0 -| 9~E_m/sp\\'8}00Oi8!K?&;dC]zx_!/sh (8s(CKޞ8u00/WȉC^:2 NSgC]zP(8s(CKޞ8u00/aif[lEXve?W>jI*p?V6eq1\~nfկ-;w m=>Pl?E{_l5iNǎő?]Dѭ{W;Tϗ] Γ{75N[ayrQG_g'?Ygervv;> ^}E 5*tם`e)_ rq'/aǬc=5׍,/| : .Pz_ :О[)b ݢ@v'> qU*Q=z"G~py7›b/awaCeꔩ5r<z K˰Sb&a2ɧ?iyY#ϓ&_3d7?8/s,JABncX;o){hEN?z>2CU#&8po Zd@?]$;촣6l8*,#?\yg]zMG(/KAh1OK7}8`FP?.ܘ Ӓ8pC?ƿ`q_7=4e.V'cr̿2埧Lkߡg= k됗+]_"trglVg#-pm*[smO7}j#A2!;25@@KND"DDݺ#cY.A 3s?ؑQTj沤rAs$)׿>[nkHI3)H (lQ h]M04U~~E٢eCm®W1(o|v/Z`q+vw7pO~b?[ԵU7U|8Mo˷;4%;{ßXf;pLB:39xw[§WfӆgwDaIC/#i V+ w$o }7p_~l>1aBXR@ ;tEޛ^?"Yk^>> 9pX| >{],={]-RkvhOk#˯X:h(Gs_x.\XĶg?kʏ~0\d;aǰk;AorHlpcؐcDZSc߭kWyk,_ ;aSñgN7N˭J*/Ϙ!{lN (?*r>1!E]Mi@ *p[=|YgudaK;[愴Dv<8*=@s|}?GC/R*x#lDD( )veZ/(aW :Ѫfq8qk*%o?` q )]Z`ʼn/_R|nUVu 00ybRm'-?z5#+&DhD5oJԩ)FSF|HjbSxYn tRӜ!8~4e9,ʁ7T哵4g/&sq 2osh+ oZj3GsuIk!ʚ AѿM&$T$kJmW([bUcL4;sœ\v}GW۲?eJuUtdU~GС,\(,,޻=?g-x2wWHnBS=hhYyG?|fL?gf(Gd@NIX}݇O#LUŽB"+ldR*a;`< 06X~3d}d̵xͮƚkc[leݩI;ޖsuWYee9'fmqWmv\[4p>G%b],k68O 549= &_۵J?`fW-Lt 6P%S,3y?8p A#p /?**3Pan2'{q?ϵߟmkDCCꯄ:Zg?aE+HOŎOŬBlO:O5T"a6b=VDx!Y\ݲ HVr|G+}(554* U#R'چZL".x}I9I3B$Ċ%+CtK exoƖ͠VhhIoҒ/og.|Q{5NO'o[*w m5,| B;ao=K?0]\rYg7:7ar-g|4 F`S<>)Q!ziugqVOcŎof3~x,lY(- ZcIbqq;Ffb*#ov\0``t;3FƏ.#>OhggMFl}$7c5` FO=KGU5;1Xk{sQҫgϺ 2wخF: cu(nhd( $׌NOG  PEICοAKB,'o2dS;`3.-igB Y_mߌbam)p/5̿0 /̿|z/OMS:YY՟.-|BQp(ǫVIQ:QeB#')?_׆2@!|bz/gjCq2+ ڦtFCHpQ p#8@=_֟^zoaxX*~zˤjݑno<o.*uUW9j߿ 8a7$& zE"*/r9g%4d8 GyMw_ag'U[4_wA.WnZտ/${L:mfra*ܘ^_{59 NbϒXT̙ݮdސO*m؁ G 'U3v+{;p3wdSW^5l>]!؟ ѱ~;Dm-]:cqWs~ )o绲{bק@y7vXduK/޿wr!M_/4}8;G? zo`wS]{UO o,{âN83@U3wINNR=U x 6\6]㏓]+X-ӟG5 >\Yd옕xXĥX~O>do.zu<]٭篎oϨN?_31?/C>U?qJY5?t&@b9E'~_0YES3AdFP.la8/_?3)?k̭.N2$ƟIBŀ%J߿ :ާVnp%+Z^fW)ZfK̮RFe ȗ ky]j/2J20#_2Яev2*e`Fd_*eTV|@Uʨ~-/QY-3%Z^fW)Zfϲ[@IDATK̮RFe ȗ ky]j/2J20#_2Яev2*e`Fd_*eTV|@Uʨ~-/QY-3%Z^fW)ZfK̮RFe ȗ ky]j/2J20#_2Яev2*e`Fd_*eTV|@U;>\؏_<ʈ#hCJh8ZHUkO?\ /&k>ZQoo+6n+ݻ&O" &8ءlء*d vzWUK[qzd ַ~ON~B^}QhwXCޛ3G"]N!]u!y -+n&ҫWO3w<32mT_u5J+Yt;p-gMe6wSLO7Ro|mwFv1 kbސ-Cs2m4={vf¢N؝j''K#gHno[+W^p,m'[et/Pû)ސAK`)ZHSK-|i>4V9/ʼZ:(Y1' H,0u9l 2렬Yc(ڟTiƗ9 LlQ (dz RFg LZtW Zϗi9>MF֚MB 5ukͺۉ#h??Xt{͑C Sxu\4B'{S\8hhhhԚ+r&a3 ^ZNA=\=pߎ_8Q!XG ?0:<-}~ѹK~Lpb7~р _?`#zf߾&#,7(/lmO0s#Õwt:/)r)1p|g Q_C,ŘX Kצ2as )^5-svJ_w-d┸2TfPޡ!Doe1_3.`4a&n4?_C3rEXOjAڣYs͞iMa'ϵ??Ɵ2 !V<&'Z^_ŧݤaoͿ2e/_ƿ7p/_ƿ'D|O{Gr f{oGTJԊ.lǧ H WMت-XMHp‘)%ߕ%$Fm Gs75Ê%??hI$a/o{}ɿn1l{ D FFO/x]VFQ5QdhA#_Y<$)*U >}wEGX4Wr`1Y 폙Wߠ/q~p>6{`*#jCP96փh27>}?*§7ѧChmTE?U"̿0DiEu(O ;0ACUCTMFF0#VbD`0bw3^ZSD#Fvp#wDCaU%#᠕:Y.+VQC/FS~[Y Sm]A86@ Al(rF҂(6`VY0_C{3>H(."BDՂvK6UpM OoW-OSυ#/^֖}W9 rkDKOBO{#/Ɵ7oߍod7ΘN3o̿1d̿23?_0{?fլ׋4"O5_v.TRѫ^f5xi Ωb6jw{I^R C5DnVї ^|Qᨑ'__>[n PQ>T^^ 60eLN,JMz} iGh¬I" !f,a/?1c$ ̿2k)f7egӴ!1ʿO)vKu~qxeSk B%F͚|R9մU6\Rq|_&նU+UʟcrW fǹf RӐhh>g?8.OB ZUsF>jG\Tt(V+Pq|2PS92pKNy  b1 TS0d-e@ЭVʄM? ?M߰?Fߌcm.C7՗`7oA0 O.'Kbcʿ>OXlcn5 aeq:Hy=c:(p6 I@- Ɓ:,!SҙW2An_U\r8v3WH;i9,g cnV1ϼs+ ku4uЌ9\ m1< n 6Nڦ^?i^8Sh8f#i9p\GΘFa> 8YbԅG83b3fp-Թc2V:xU(^[YA_ߙ`%83 /_bE)<+_,H'>*hF 4a).ЦH$!2ʱ x,71 2V Ϥ$&(SL!*+ @_׍5JS>DS:7)3)rIͷxf<JQ`D3x_WPlX׾ (^Wnաvz}^?jJM1T?p 9 :}DEwEu W0`'o 3f X2>0Oj,>g̝?YlO̿E#?2 ̿2i>§^1 )^%tB3y*iVF0ڍ+(T^ӜN'V((SRCMsb:/BFL*j)6_4dTPӜNKPQɍ?`% `*c"j,#Pb s,>~Z`?J?= 1xu:+?[=ꟊEPARhh9pqPWEw3&Gp wʘ1rW㏨+S5Î)?2d'oodCt1E2cJ$@_a :o:[md1?2;LjX''?j'dgl;e?,nIgzsZa%1-~WbFs|fPhhuV) ?4/0R\`_Xv` ̿Z@x柙fG1J4sN?3쟱gwߙg=833ϟJ!F^@ݫGs j5?8%(KF&vV;mCjEWtnz(ُP?Oo v. J!^ "RA>p3a0) Jd`PV>,Bl-W_뇎ҡ|&--5Pi'98J:'[hhT9>O A3PBcfMPpKO0;3i'oa'柂sSә's !HQ@?1ro̿1m;Fi02V/C3fwpsP, anSXeC)+=?b *ZCc:+IE :տRRSӥ i_tr|D4fOCQ(J*qCm6VM&u~h7)rXO m@ּk7BSngzrKb~JS[QȆqpYND,O%`?IvW9'om` P&|4aa'Uve_ A;,ۑ.i M;hD8iG`/_Q`K%!q@]OƟ`/;O1 T-iJ GFaǧE:2"yte"+!J:mk҉SJsfeT9K'Nehf/+ͱfӖQH/84j֚N[FŚ#tToYk:mk҉SJsfeT9K'Nehf/+ͱfӖQH/84j֚N[FŚ#tToYk:mk҉SJsfeT9K'Nehf/+ͱfӖQH/84j֚N[FŚ#tToYk:mk҉SJsfeT9K'Nehf/+ͱfӖQH/84j֚N[FŚ#tToYk:mk҉SJsfeT9K'Nehf/+ͱfӖQH/84j֚N[FŚ#tToYk:mk҉SJsfeT9K'Nehf/+ͱfn`$ k[ WIcږ*'/+p iLXR9ee̼HֶT1E=AxXIcږ*'/+c@Ҙ) r| HֶT1E=AxY3Ƅ-ULQO^V@Ҙ) rʘy54&mbz2Ƅ-ULQO^V̫1amKS䀗84&mbz2f^ $ k[ 1amKS䀗1j iLXR9e>`$ k[ WIcږ*'/+p iLXR9ee̼HֶT1E=Ax;>Yf^w@8Sq"GBaUM#ɳDX4Y9>Oi#o1Y QtA /5 ?y j  3Qj釻d=0CU'Om4NP~V___n4,]207o߰j43f>,̴I\~x7GǷ2VS^2fVR HW6=8qO@ Qyhj@edR@T'XZڊsj5 ;ZO탅O<4/BuBpuKC[ѥ:G(bJtژp8q|CS>P`.xiƣ椭?tjM' 0`?Oߌ`'c,դ T?1'eB+<O?YT"h'~񧊄?3()32f)? }U+jjŖO)OkX7ezYiK벵L&srC~j)ecp|G,D 7L /OZV;_Vο9~,6zRW`ۛ)\z٪uhmm :uu:^TlqXgTsZOSTGԿh_tfԉ'o`4Fec:%ϩ0^rARZc\WdG??̿2v\?ʃ?1߿?e,Tx'Jqj+])Qv|*%S%5"9^&:'H2PjNԜ2:ABRs$L\>  S%e:5qLNeԜ* (ש9e"u(TI@N)}\/$D(5JujNzH !@9UP&SsJD QJͩ2qS^&R'H2PjNԜ2:ABRs$L\>  S%e:5qLNeԜ* (ש9e"u(TI@N)}\/$D(5JujNzH !@9UP&SsJD QJͩ2qS^&R'H2PjNԜ2:ABRs$L\>  S%e:5qLNeԜ* (ש9e"u(TI@N)}\/$D(5JujNzH !@9U <*?j I]6]cԋ4htMiHm@E"2ڼSlŵ9>OyF?OL fqUhEҕUq4-?ISxȗ|*-fZ0'OB+$ Pt'O?!?92%J IAЊ+ %T3ݢI'O?url|ɧb~,ϩ?ý_ߩ1!PŪ(E#Д)K8z(A8֠[iHSqvxp"k $k[Q(ʓ4hA8Q_Z-%OIgڮQp8>[n46"#u]Ϥ*pW'³T?ͦWWSPp`[PZDM8EbA6o 'R4gp/Ɵ@0̿0o̿1'c7ߘ3m"ouTn! }fW柙6gud=矧L~ԵA"U[Q/IR`B&LENTzk|U;}MJ63. 0F\02 `uFP?lBn263. 0Q؟M lO2 T[S$f4W7X:@͜#igHWGzٸc Od4Q?Ha! Mf` ??0o2G ytF+x`dU)BfE]AdG=(,̿2k{ɿN}QWSS=Gg&C#_+$ Bk4N~TAmPQM9*ABk48qAE5N m$bViPQMQ9ZۦI?XAbPQMr8$ M)`寐jÉ mDL+(TTN m$bX$XO㤭Z?]&\X u|ܯ态 X`F FA?&NZ 9>xb#uYs̱&ÿ }b{/]uorۭDs>Ϫ+"ǟx*<Ґ]a䤓O1l[nIcm?_ʗ3[o#f͒/.F/~IYo]e9cc=jn4e󭶔W_U<2w9Te-lg7^.#dJS5V_dU~ɼ?7(zA8a§nuuqV4y7~Q181LaK~()?|/???~~ҹ :=P0eE*2,!#柘SHQD?2d,;>;T`§:*Z7CDeZ*7$f% gFx%6/Cr-༅td" KrdeZP(2 I`rdeZPԿLC\a7+yk>n2]4+ձ&a+bVP xGav[{K뭠:կ{[?Ckڛ ښ2KLo&+?Q +ZkkiӧA3zԱYM.ÆbAM;n_ 7!W\vixsɧ豆}1Inakj_ײqMdႅ2p@DXߐC; d>i&yir'pwY."][h{1c3R/mh9O_=`<t:4Fnl΋3^m:#-[ Rt忹Y6h sxրuߟ'/|oool]L:]pƟ묷,eyya+ݪ,_\b}濏ŏEGc~QԔ>O~׿?Yo{pVUp/x3f_?9wd^:;B>WV9Q꓀z W(\FPڟ@P?G*q 萠2Tb*俉9GL(Ȫ|%e _ߐ:0( *8>Sa|sa5"YA?l+~Z?i?-ڧrT}Pqfl 䕗_pZWb%XCwꪫ>Q7x۷1G!3_хoӨcO§2u4z)h/g#[t)wގOHm豦h#7p\wm>.|d>`ؿb?˯\yұCSٳߑ/iI#2apV'{칇/\@f,|: lq9W_o2x2Ccuו;dn„2n̘hۧsKX򴜊EXՖ[zXÿOh8rKjG8K6轡_0_E:s !OsƿQہBA+>d8#啙3GDO7[➸}kM: ^v_rpكV `"gNG}l2ށ 4*7lQ9LA&k3vtIObSNjHOF,z;_e<ʿ4z-#Sۥ :nmOZ.^Vf |?_9`3Cf(.W_?|9 ׅONHAi4S19/YV W*G=]*^ʶo8gtKxa.,zX?@oD&caÇrӍ ,҈ָjM#\$G]yuk|1&J԰S4[h#3GDq.|3Ȗ~*Xt(C>]{5m>}Ny9kXN;AN3eEF+lZpK.XD@bT͆UƢkG}o{+[n2zExXg=,t87,|~x3V>g̸  O9"G|;X2Fu6>w ZхOAE8a-| RP$˽& }cbWglo,];e.|fsɲV{pF\pcrqϳEw*{XtwݙA^!7kx̑aS{bgNO)X޿h SYzŵ?*Qȿo{QJԞ翶g'F7@(MS5噔Oߌ?fN}p?xL??i/{#5>*`lz VG^7(ya3Eƾk2^0;gm?aQ9%[D ;969k f?_F"c p0iCis ,u*Úfan?kHOɱ ڄВ7W]_zQ+w]YVXnyywR z8B^}U80fҹc3v|z;>l?noÍ7_y mqmrťVo=eQƃQ~{ݵK}w@?8pPu ;1导T.gZwY??????yEX"%Lo >atG_W@<*ߦ+UlǧJ9.GcM. 5$9/(L3 Y>אƢƩ՟HSF+2~|[-#I-l*8}ۊ4ً_6 HJҁ6k0ɮ#˖;촳:?{=vѥ=drSUPmfw&sO?-m+"zҵkWwy2k֬pz{!;츳[xggԂ,ӿ/K{M_NEwҗ,;tY^z%;<3v݁UWfo6v"ߝˆ- K.ی8\o{vm'뮻֬d1w\}`!؟1i?صř/,<'|zn #wc'ҥsGy?{qTٿͶBv޲ٳ瞗]'0xm toǎO_l]viGe0{ ?<Ʋ?m=[}o](k%/xI>ɨQo5W ;o7޿+l-du5I.T64'c6鳉痍:%}W&MT_+?? 7W {W`l+t?k8{ya^|vk'}=w C=6NbatCg_ V]faצSɍ7^/z]?zP^%k7ߔ 㰐dGwȂ_>}gϞ[C26m({mL6hł^ .:;_uUdgr_|9ybSWM5w e/E؞53!Wfʽ+>edW^{Fyo2龿x~>!q'$;6dA>5:7 ^={ޖgk鼒[A9`\-}6 \}ۭ7W^uU;ٟ{Nz)eݧ._v#F!>dǝ:[:cWu.z~=X֩{wݘUVYY:0_VYU0Of_y=vvUЩ,Vp^Z.K/$H+/׿.lt ~ /4؃q4,f+:㯴*2h`^x9jgc m}O§N驧iCZ9?󟓝o1:w,/gVn)V?Q=ԓxźP/ {M7WHk%ك|udOIfvm)my]Wcos-=!j[oW ˀ \*\`=vdmm\9aU[2nVօ>_}f}'}teO{uzE#+?`s/e;>i잾Zbp#xG[o#An[Q=ys]yYcgx'oq]UўG((*(,[l"),`# bMQc(+(bH͞=gϹ>>8[잝;g׿,Y e73F= y_*E? "ޙk~g_\?R/wH2605 :?c~5oQub^0.3(8!7LA]Or>}W2|0?_>HРIg/ =q4| ~'Tt9a~|A`Љyc(]N/$h3sx0Kć1.'̏q4|9<%tCJ|8K tq>6'diV";y:?<'-GL+ssC ,[ .rƥ<cqxά9һw.r9 J'$b\hx14aF6CwILق?/+[ ewYր;JKTwF1O ŢU 䓏oۮΌ_-nF[o2hJYr}6Sa |޹P\wGE^,ʖK˿(a::t(T,>|D ~t1?h0(8Hq\tG)fg1nTE3 `OYvM %S3KG~ea]BvO s AmZNYvf Sn) $07 M^{5}/;{tM4it‰c>X7W4DY*JC޽u>znPA?g\+kaI!C @-4l>"O%dCN:쿎wb\1sʼ?PB@3f?zuH:??{騰ʂ`F`lw25>Ǎm'=_ћKO[E'nh@IDATU2x(dr9߶]Yb%5-KLg[ og?X:?GTp L '\zi1`_le&xd6+90r:?_''~DK?+>οf|G.}qaOuo9 Ȗ"l9O{a;:P+.<悱t8ϸ@7#?=zb"O&x$DoA}Ͽiϣǣ-p/qi/DE\2byځ#BL ?*BP|]bJr.pA[WuRVbji~3?[Ofφb H6䭷ߒ}o2#?jk=.]ĕK,˩IPו={ȯAl-~]~a`躀v8a=&H%-P[kֱ t`1"ʋE_ナdW\%ukKV-`b=bkw%ժU^Vf:ido\DλGhu2dԭ__PPZ"ue)jYF ۆh]O=|;A\"YKԽ{,鱋xā ǿך6m׮] k]H*ewcREmd2hjEkbN:0+{5-1=-йFz7ab:DftAP9q5޳Qo!~喁jUD+סB @1ɜh)ھޗmvߊ>?*0@k5,Zb>UVM<ߡ3R0*D @"A[.E~9Ѵ<#( P^eXsumG!w /eWX?ߠ(P\9 ƿ|AW`d56|R&xPZ-Ie?+goP_Ԛ cZ@.m{g(9'g"=z^ w+$5~|ɧRmQÆRrex2<<9L̡v׮A.8` XRw*\4?vKv:uiZus;1kq9?O?Djo.^|-B|T%^ཊThݤ\9*wPKCpuX ~sACh*q_~}S:XYwZz] 7{bAi=2j .qEcA<$uC">X%$=ҥ_ -Mnr5- ֮D+%nYBVkI[Qxt(m嗋AK+^u,=z:ۼ%D+8Oa7^_oaC)ۂDz9k/VF~1a^wqGX4߃k9?&1uWs~-wK5,z.DQSRCv1# O \@qx;|߫0/_rP$|Ox,RNb,?:"pD'^Mlo2t@Tvu\G)=?L0# a/LD0+^Dz=br k믭?jm"/'79 |TtQܛ+a'yIy_sr Gac%0a lJ (d*+/vU?H_,Z$ݺ]u8,imQ\s^?-PE3_AQ-z2wx0V[oKXVae > bd->Aɗ ǟ54eedF+Ck+pa.U~C0~Bϵ֏?-fxвչ~ڴ2 ? SLAȍ6}O A6g˕PDl",PryXӎ<(}\ԙu(̓I+TII` .OeԘwN;E܎7lG|r^'(ˡπO#6t@%*<&2r^W]я?X.2ūVˠTJέZ(5 1Adڔq! |i}#|Ի7"XvbFZ˶]sU8_Ew^gAV)0a"ܡ9)$ O̳ !@ x&2|`e| EP&Em~=|`Pk~s Ӧ? `ed֯=r꩐%p(!ϗ [);׀'̚1A?x+NE/e[\7HUs(+/Aa>**{?CUPBt~>k <-;~֠S6iId}O̐P^'UPXo߶ ~dTQšK]:}9;G%P*lH͓P&-ISc:vhcg;O9Oz,nfj%Row\d9?bb`3 g&0@ZpΝ?l"1?" ɩ'[fc돭?Ā~bjo,>%6 t=:ŧ\P@lnFnJ\8 P1$ 7Y8$/X/i!o7#-_M 'gͿ),㢹)q$Bl g(>N.o8 H=܋%_X(S\FӬ,<j_^cSV*o}ǝPIΝ+W_;$cD7`i|^oѢ4oRqDQ5=84C]D-tY3;GeZ@;oK?^Ϻ۴ikz̿npEy 5=cxfmJ֯%Rt3utE֮Uk(F^  PDɸpͪ&Em`aiӮZь , /nC;az/kQf,A5n*婧NZͬv騈A%|PoCjՃ ]?Mw[ovM\->)FGUNZªJi֟6mcEr"viֿ)Srpѣkо8^iO/#g=wST쌦;9kok;-Gv2A?X")w҄hK~Z+=c5iَwd>kw9䬢GÖ\>_hVZe]K<[COttEDt)QED * (?G:v.+_C~II'"<5v VW? m|@b[_N]X:A,|VpF8i+֮JNaj/!Xt<\k; oE1Sql@3\ŧ/bV\ tHV|tt.u2^Pkaqɒ/LwVfC9.I*TqA{j ׿%PcL"UY~S$W: F}* UCEߣɧ,~Ei+08&]۶k'CeA/h/ vm'(咋:.2ݑG:(M/Sb{-@Ib={D|Ϸwީpϛ> E&_d2R[<=?Mߏ?:5<2']׭i*!= 4l1?痶(g&Ͽ?A/~&#ϟ_?@]}[3'̚1='1J+> V")qr Q@lpo'??lh=Qf|c&l%{\Kq2bv)>A^(zDc9S1°;f2 plNYI|3E1zKIRJlR"y%(ᲫLT_rV.RJr_xsQ#a#Q|XP 4ǟrT[h1,ZtumB|P %Z7]Tzl:H s (>!Qva{k2_Âxd_V#߯l ݩ9{jX2ڃ 2n:<9紃Uq9'vN#x6gܡn=h[ࢳT2ן:.p]UηMPNA/9k7GǤm4^ J2ꕎ(?7`LG?z T /q-n7~SajmM lWQ,SeZ+W_}Eny`jǾHvmd>~=ACJd ,>ŧlQrXYUMpdas|¯[ :Bʋ2<0 t8^}t( >27WsWO}\-|0t"4.9‹O:: |S@,_h?S]Af}0 kzwc1m1,] l%g/-́ȵ]֮[%ge 8;v@ Q/6#^Z5kQG-5A/;T Jx`*_X\C(;lZ#yԫwoBb9\2)P.W̞5[h |!A똠TY+W~YzXed[di!ۆ tsT)I3 \Ú){;48ܖ$3k jT!1i-s.oU,u뉖<N+|N ocxGٯp[A^a|Q;7反g(9Cooybnߐol3a֟Rk믭&X 66k}\k&a&KįP9HWR |l7TyN bA~uy?,Ă`P|ӂ.X oZtR AM ԒN bA0(iA_ZIA,7-~PK:)}]jI' ߴA- uy?%Ă`P|ӂ.X oZtR AM ԒN bA0(iA_ZIA,7-~PK:)}]jI' ߴA- uy?%Ă`P|ӂ.X oZtR AM ԒN bA0(iA_ZIA,7-~PK:)}]jIzq_\ GAޙj\"Sw݆IH/03jyt㟣pinYY_N.)[oOUreʹyKHU~ŊvmZ#m->9Oċ'L 3_EWg@@A`ɗ^! #{R tyyjѢŸ|pdӪ ->ar 柳˥pR Vl6_zerGiJ;_qa[Kї`k #Lbxb:r3yq']. ay~yhBP3xYzrW$=3tj)cTӇBri|2+Ӧi7uzz7hHn'4`}5G,/bPO=\QVA6F%C{1Q-n5;ChaWoggihL! }7?h;+jBPt-i;O4P" %BBo+=`gȄu4AuEr`3ߏrPdDS=֚OQE!AQa 0ו(B1gռc;^ǥ}iAӡ^rƲ!:^Zt0wi{c@g*zǗ7~yn}ޚR_3P_-EÇ@()!$3˗/sڷ+?LjX^ܓfϞ%w@IK(fgςHO_a%%4 º;#ezX qwWj+c$0P;f g멏o,3,뿧~qh_㿞/XWbk$6=JdMJ^&eW,f3/L:S\IMܸ9{^()=ʓ9d8|xttܨ'7OAf1$H>Aj: d8`&>]O?Iw4=Ȍq i3'7Oߣ*@N16VtGX2JΓ9d8`(?iK#'7O0x ?iSgW{FidN#G-݁KI>˥!ukvGY_7"Cq氺oZm K$giE]p_+q]>/ET|¥ho*󟕵lJFQ?/aLnbGN碊Ϸs7FAigXZfk\>{/r&ɣP/RJUʉrwNΝ/ K')wDN:?U:L׫'%_ZڹF wX$ +ǡ'(fA-y9հ5u:#%(>Aa*eH;;ho?!9D:w"wmGl+7š߉j:_i=V|rMH~+R-QMĉP{OS?#N>T(ΑۛQ/q0 >OZӪEs[¯:b-+zPx fĦ"(7^*T §GtF- i LKhJNӟb9u>kW0% a Z1Rj֮2LA-QjuTdv&_$?u<AQH>T'XD5> u4& Ƅ-sy*Xj ~aP|=|[[Om@{I9` <kE8/3ާZAR 80YE~¿ƴea.D,%Sȁ/k˩>̘>~?WO?+_\kDX-4c@8i'4p~rϩ(4Q')M֕古?Y_[M0ɟ&m;'?3_?__f|'9!\(>s.]c? KC.<\l<\mL_?v&("ВM>(.`Bq9GD~UP|*vǡe#Or)ǟVlŧ_;75\B:̽'R|YGk=iQ{[G`) 8KܑŧmV &)\Zsr êǟe]Zj0D_,Z,\MeړN:YXb|Uoiw v1y֙g#0{(_C~AX|eX|j)>A)֟DIV/b'[8ka Owd* )*:tѺQ׿=Oŧ*'M 3gAI7(21z4;ŕ.X>]',SnP]%mbOi}7mʕ+\}6~!uWK'Vaj|'R^D9?^aϹL;N袷tMeo~+'xPHgbX^lX#T`޳;2\ 0woXPX'%wn]XLpuөzʩ!_7H<'rW~CXwY+-|RJ7D:ЅVNCI}xh-J>˺mỒ"vk$rG6l-7w߆2Vmڶ?z~!V(-E]/E%cMO)hHOoBH>IŧPNŧzS^h=W-dܘxݵywK_` <[bپ,ߠn:i)>I&{kO| aӕK2N!m۵p21eSBwi: H&;fh/ UC~O'W U&ce]\OdJGBAcv?1Gi_Bg͍,3u9ߌ:)ᜭ c4{E8Ǡ_l93g㿶C8M57zz&Fp`L4_MvS={[ yL11 It'j^R .'ŁTo#opRIc8PZr|ÿџP/%6R| qqWz?~? Y̷8)?[c@8ZzЌ{ɝ}аvA3u$!ҿwDp2 w~; 4ż or yJïU{W1_MTaô?;OB:.t?Rmj2{zXk ?e*h.H2"Hm*󠀔WȑG"4i9{QZYJ|ƲS`<;k[?S!/WNw>,1jL}תU v!o|KGVdڵҢ% P@X$e_Z?ڴų ry${H7+: 2'Wwh ֑XO7ږh)Ӡ,|o\VK?=e8?Qrɥ+h\rQWP _ =ZM+(DY=D> )as )<_msk>LP1y*gɟnc1?M4[cWń K?SM6ۭ&?M6i!k̷1w~(>_T$C  _0s}P}6R o 9A_Ecz0s͕`6V8c%OO8 [M* ] 8%U9̈BK %8 GZʺ ]W圵&o^R\ĞFSO.7Zh `{g?i+,_x2Gҙ…"oP>}';QK&O-^ZSVY-m0#van si|}OJ*igz\],X?+X@[l9ù)Tl9 E!J/%(> rՁW>Rj֮w 3˗Z_ߛ^{i0 m Ie1ŧ['d=w)ժPv% f뮗w}o[_%#G J. ',"}g.(bEvBXkV~ͿJ{)|yg>|oX{ O?L.?*_pO_1XϿk> Wl~@ J]۶ѼZ̿kury8+Q#px(Vf[oSǎ^ IYUa9t*ɗ_%] B= O?s~13c # G^f6M2/L2Oma_k71I3~ o)';K=sgrINAL eؓ S5b.L?3ܼo8OMxg&/Rz?Qb:r=I;⋿֞' 3 (bTO4YX?y` SO8TxL-[Gq.2g Oiߎ;$cƎUP}J4}swh=V)h}(}=5W˯n6$/j} 9af'O>6.~:^PmӺ֙Ojim t^2dSZ2E3?PB*A.?{SV[h)yt52?T13wIErd=Ot/a,U yԃ.P+)~1mݤU붲~2 ;h=.p'5 ?: = aG.p!G*>?2nZfq?Q^|§U(?AٟiOb$x?~9*E-BlZ/X\GWZj,O>@,Xyb.]*];/`_hիm%{%AaV tD~=3ox3r{c">O ܠxCt+έ@IDATq&r˭ s6$tP,Ul+ǟp4Ux%hO?oĚg__`P+QXA?4h  n ֢w3EkQӦIowz {uh9ǰN%οwCz_ 9W)3?}% פH[*s fG:ud-P^֛-];X;L? DI|>/}&^Cu"[,_WBCG xbX'(} _ϿX$GԏZw8 6 78O~2cL/+2Cڷ흁`k(})h =n~(V(]~MNq^)wBh.ڒoիT'K- t̂lf gX7o)[@F|r>Te zajժ--&aST;'9-敇4˵dԭWa쯞zRf~4oJ'r?`B(ϵK/SK2]I\Jt0g_㿛O  cOk믭tu?zX+AL0S?Lߑ?f,>y+ܥg"e| 9(iy2$o.4!xe2Q}SdIFFF60B™hN0?gsgp!^ C.gc:FQ {v߉{L(/(XRKA+z0-\gEb͡<^~]:%AlXx yAX@K/N6k"KizPO\g;:CqNݺJhm'r| O:)-=7o\ P"{ɓO>w> `i*}=F%?gq&ҷwcdV*PJgEpH`y,2͙,>e8@i0-y;3hnԺupQc],wxI;o*NO4j$r8~R򔎚}Q6mi|-O!|%O:Q:c a$ƹ~yt_Ulg-O *ޣ{wY8۰qCt4潮1mG[ ?w@GQŽn]WPROX8KgĿZ[yэ-bT%)rZp% TGV,AX_J:XP|O+WJ,!PK|!]/ Q֍X<cy>QCGE:?!MúZHC hWJi]˵S[nW_yE?/ݮoSXp,W_} 7GQ$M5- >֬^#+7#jj3e!k",I }0=kv^˥rgꠃ&A| ,[44/kRl=劕d#ܢķ}+vgC;{'P׋`uµ-B0úCRɆ0 /:GoF:9(\:?j4ܡYI: Omu P`#U"q\ie/,>IQ?vQ{y-W U/?SHoiOv[򇭿aɟ&mpWE)-uMDI 8_?L0M$m宿% /®"!7~]6;ՑmZiY%ͿU.DwKtD_V2O<$i߱^6׮,eys Nj*`XTEdZwoMgN-ŧAi-#.: +`5`#"l;}רo'o/XUy/r nsh[8uaejahD=8K ~׸ͶM4XKz֒q~Hm?ތ7G^牻HZvZVp.bnֻ:t`j =w-}J``l=:T9?V?Zt; )+ê\6*u9|*'\ +sx`о|Tblg9'&6u={7h8#Deך5Xlצq{@ Ÿ`Bk[-_&FGmoy{ C7L,>+:!ItQ\I* r/C#f ,S|(чQ\8(0ORx % k[xR\8ExecLB@vd8ӹ8Oq e<*o&CCo$-!ɖLTVi ŕ]wVOO>KˡTU<֛oˢE81sTBu\4w,|'̙byt [?UNBYu%_… i_i,R>|K7s/Xߑٳf+_Pr;J1Cd[~_?5}k_<{G O`8?&LReV6lLjj A|d(b TߩvQ>c9}Yb9j{± wKu? ,'Zjp7 kzC֮!1sҠ~} 'ys6VɿBԫ %Gɂ /Wv[jkZP@nʾ˾gw̵/K,^#Mc[ȋ{1[8>8϶?ak@iD-}7ol(-";׀2CdgCy?PQݥ~RFujR?|ojd5m'HΞ%_|vo.Sh}r%%ߖo6#cK'kٟAg'%n?oO?xbB>gɟ {L6|Z?cgH&E>ٙl?LY[M_N>m]KqyTG9·S"s@i|O,ʥp侞#h3%))JEr_Ɏnh3%))JEr_Ɏnh3%))JEr_Ɏnho&MEmz+p.FUP9kB\w~8xr:pG.HA0ssQҊ??$ 0Hg󮿣#?H*Sby2GEn]/p3FZ7餉?"Va@ &N~9M6{$0Jdu;0c1[K4a}]Mv u3 QݿH7Wþ&2_Wvu#f8K8-휣(7&ISt卒\_۷ SwE9^$LR;>ϗ d ]bbő c KRZ" I'.  gG+d#t: \} 2Ϲ>{~}F Ã_Ai$E(zHN l$z:??%DW 9)P}FFR^FB3sx0SbPIJx gn+=u@4t,z̋J1!Hj,,^'Aì~h3?79l)sHd0D =2Ǩ-I. [Y&>9I1?v+>X)۵j2_Wʡ3 uIdժ?ltIs܎- ?O"tҤs0lqL6H&n$hZEɟ&L ?M4OӉHX48_3No[a7 ~V#]*7*=Nc$̗%u` O??sB)ɲbOh&_ rF_㿠[O&MU(W* Bg*FB1Af ozc35{ 0b7s#F.5w)W,ڹOoiw#6RXv|sз,Yĉ4v4=*|A€ɿJ l7;SWR=7@8qkbFl%B"| d q[C=t\C34?` 8J!Js5o럭\;>l_[m0?L0-R|r߭ U#}L͛-(9owy_/9He#E30K&S^$S1c#qhF\ 9?x e_hjp Lv r/Nb>p Lv r/Nb>p Lv r/Nb>p Lv r/Nb>p Lv r/Nb>p Lv r/Nb>p Lv r/Nb>p Lv r/Nb>p Lv r/Nb>p Lv r/Nb>p Lv r/Nb>p Lv r/Nb>p Lv r/Nb>p Lv r/Nb>p Lv r/Nb>p Lv r/Nb>p Lv r/Nb>p Lv r/Nb>p Lv r/Nb>p Lv r/Nb>p Lv r/Nb>p Lv r/;,>CwIJ)ğ3`vO飚dn.Pq(b8A=~w@|ÿџ@Kvid_[l5/?MloleO1 ()#_xOɾ?'p())0ξ7f}o;9q)~ROzѭyD'|d,U"ɦ$8ϭ6NqE ɦ$8ޏ\ss)I<s)HႹ9ٔ$|1܀+R`nN6%!~.8)\07'x?pE ɦ$8" dSxrHႹ9ٔ$|`WpܜlJC>Zn)\07'x?l.MIqC " dSx炍S\ss)I<chWpܜlJC>\q+R`nN6%!~ -7.MIq 6NqE ɦ$8ޏ\ss)I<s)HႹ9ٔ$|1܀+R`nN6%!~.8)\07'x?pE ɦ$8ޏOzGNnY Un8a=3%4BkU)~ja6kuNglQ}B&DCk_d &&_xm?lsNzpdnpfiJ4{;?N?M@86oku˾/e߿Oٹ|r4 |6^ A,p8i b(SIKj %R0tb/ 6Hs~R`8-Oi?(CS~^R˜M`);;D"!W({@AD ;atIɟ&#fwmmoG ɲ1o{o9\sQ1L>B΋5|L.Zt(k_§z?|0 `@(4 [@^M/X/\[mWǦ=4y;8{2YwJLۀqiyY̸V2Q\:>ˈe s??<0k돭&ŕ ɟ&_`ܣv]ct bXIcveo\G;GH;}W;|@EȋvhI';/v?)g*vi,1V(AbG=.7x%x-*M_{8Zp33 $tMT(3cOBf8ap=mpMd$NN<'_NNۤۻj++ B) (08TF0(_~:a돭feH':fvȃJg_Y_7+;;;';7;''H':252|mvjvt?3/v\ϟgk-TYI\r &xB0hQYH}^V538|+\Y x9??A#(Y`x(RP1ՁEV= xaZ:O>s?1 vY?`"6mb#?\:}NƵAH~l1 )4Sl!fvغB_fmXCv`vbOvfv ??s&_A9LG;W˧v4d^ħ+r;G;GVb avjvZZ_|+ΨI#c&(y_!J ڢqW[8âpExȎ1, aW[4GA ^6;PaQ{ڢq<0"PG-#1g=E!0πQ bEoHѥ &*W.$/lD6 A/|egg'Ԥ Eaד!p[Ow @쏭?KħXd a&hTgL|@ў8Ң~/!l|???Q~A71k돭fDDPe_?❟R_@?mmvU2X(_ z__Ev> ;7;7֏vt?_G@jWvjvj篿+;>9R^?|ħJvC^)\ =y61+G[`)¤ɢZ7MT7M|uX. re1b lŚwixM(+G[d_.ּKûo@\Yjv`/vdovfoXEdy S?2D/;g˔|!e7S*vjvl߿?}Eq:ŶcNSOSq|L`iJPܐˉ07Z$K@_2~5QAּFi2 >` 1rF#QxEEYZ$K@0*2o# Ddb<$;ii ԋiQ$_BEڸalG#1]rɥTuf>9_rAN~Oa1 4uLeRM6b 1d_xETz z'(QsZjK{ |Izwe?erq=1q\<(OӲik֮E=jPUX>xCzrtѡROz(n'ihժUA֞1r*Wkkˈe"3r8p@Dzw8ݙ!k(_?dk_ɔXVdO?w2o;W͝??lV ߶f47+ETHv`v`/P 9?nh@Iħ Ay "# f%.Pt>'bQS7eW?N,=$?L:!J$%9d{bgk -SK>B:K;NV__!ܭ UPS&Z$~Z?oǨL|隫 yqvZt89Q[[u"|]TA}ڴqu/&NBʕ9p)Q&p$*gfpɸߝkצ;G-ich#$HͿwP:wXl?NRUC!-\0.;)+[F}T׿Sx/R+WLu֥M4b?^kDiI-[k]}/@ 밆utm4jy8ClڬVv? VkԬA;YWl n˘4o\°_>UX.]B?s*oo|,vr!J>kV dRMS2ʼnvdovhoYR?fgٿf`Ea~Ŏl`q߶m _+CA_ rϯȋ+7*1-jFCMhR*m|SogC(>ab1k돭Pf؀wa(mo6{%!pEr#?q1 gvRl\8?6G2u68^~iKŽ &_|YZf?yʇFW_uI}3W|y޳gzaTeʴnZڥ+ʅ6nH;,S03qd*[,͝ ǧ~p|+*D!FV5uW0O3i`5BOw >OT>7oASʕ+2e0q%Zw} (O"M4I낋#/4‚mjJɏۮݻu 'ry?SuD /]ۣ)%taCVzve_zi؈2)S&ѤG4d05lҘ6@]Jӭ{wjwIؠy.u{yԯo?-ןҠmTM?_[l5Cl1m2/2/2?fc?fv| w4+)'9>8>)T[(`uiK(`uiK(`uiK(`uiK(`uiK(`uiK(`uiK(`uiK(`uiK(`uiK(`uiK(`uiK(`uiK(`uiK(`uiK(`uiK(`uiK(`uiK(`uiK(`uiK(`uiK(`uiK(`uiЋq'΅$>P:@蠂?Ov~6W UIVqJ;R_q՗_,t@IDAT_-נ&͚R W\A/𜼣?2'OOe/>kj԰AZv">u&6l$kX/ĎN߄)\rJ&; Ak׸iSO,3~7k# ]iI'n7$PȜxb{k߽hŲ4x@y[˟_? sw NTPPH;Z{'u{}/|g]V">u)@eIYF 1iK sCaƴa#:v*e=Iڋv9p|dbO p:,_͛7]{e<¶%8€(Fm%)`Oqomi\imAM[l'w+ _1@<5_ӿjp_ӿ@Dl5zѩF1tٟ~ ]ܛs|Uf))*=o'g.O$YjI)*=?V\bㇴH>&j8W)*=?()K2acp.}eR$<Xq"M@ʃJz'*LKbFHyPAbH™bǎO|I@ G<| JZ;dxĉ z}#cWwtoi ׼sf_C9D9wԌT '3^]TReZj5e6Έǧ+Z޵4T6nD; Z4Y&"W2e4@QJkܤ 4X@O">5gv)|%k#]G O6yd\Ͽ=snB>S&_ZOH+V[D.8_OIΟ'[ x.wU'4up|Z,,?d(6kWSW8>\q_~bQLB¶92uԱD |pRdsh1"sKc? }]\+O޿pU)I?ooϦ[EK~se?n˺T<&jg럭of1"i6MllG^vdmglW'_ze,ƣƐA'|^'T;6Д 4@O!F+#;)R33 1BX1S e,\UqPR4?>Ȯ!2ui$3 1BX1KizO|B㔂`eگSnFuNn˗g"z!)-?Kq$U瞡_~YÏjwUw" Gv3g.]ٯC&ݘ~-Oe38>u:nmv/|b}נP?dd}ݵWALkզUҲ++Dz?&3Prrvq?A-P>v~Gz٧ ( 8ǧ;$ vك*V(?N$Eva^P2"-_>H_3xݵ}3ժY]=|r;FopL5GiKz뭷^m[ӡB 6BiU%M(}'7">s<ǧ$^,ٳ^|af{|:ԦHoO.ӦMEħGd<p6PX-_1#!uK_-[G<7hdT?^?͚t?ꨣ ?Ѓn$j) Tߡ6+#8>3 |Np^ͭ1Gv[hS&{#=?tZc%;Ԡ]z`.nrc?5nBʗ![o&z%==o_ w]|p!?1}:so(5q7PmD>s0?;,t駈5'Oreim_pǏiMu-+To5k!į#sfϦoX߻Oqפ4`@=Lz`}=PࢋG7nkUΟ߃evjܸILyx䓏lF=i4~giL3M:wslY9 m\3&s ̣{ Ol/Op|npq^w߸^yJќf=>Gܙ{:/kVө=8jIS,}vnd8MJ,yf4e# 4Goժ5|m谐NA/>}y޽zrNkRng?*TH7xd"DId8:rT&q2P_8%9b8zeWѡ6W,3N;6z.^pFMFax7x#zu^r޹9Oy nى(O==0;Gɚ#̙O߽䫝h0 Ke4իW tݜ{vFW!H_zA=8??o>g02h!7??T/$I?nF,ӿadc럭lc/Th[/Oo,/f$f*~En"BBf2%X6V?d8_j2=WO,;u6x}ǁE8æGt{h*;a|k}Nb wh?>(^t D6ПzyQO?9 ֭WAHNի\ v"\-Y~=z³8x?).Qypj :p,iܨQ4C}{ӂQ͸B$[nc'os,[V#v]ʈR"1*C1%T[=׹П/Ys}Tll՚eD6x{쾧JǍ5DCT__xy%b=w#J-3N1Ҍǟqp|kϽC.pz߰q'v| p,Y^fG#d\wi ΝM^sl)|jޙJD¤T|zwvwMB>t(+?N\z8 /S 5jaL 8@ _x7mhK LvN;MAz絘 X|IzN^];}.QE1<ǼQ/;ǎ2u B 瞈du-֦2QM6?2γ{wЮ͛I,q|*vg 83wnpaQ߄ pݼys/*i}tg[!ȕ~XβԀ#>O_)zy* ٙg]qE_MX_X qX.73+GYL2&NUYB 7ӥSGS.g*v!u."G:In"T*d{iv~= dU_tѰ S=@~V^/GvA gi ƚ0i/W5˗TrxUt)=D/zIO>pӫ3%[Jp64~dz?13c 18;_lFC~ z4[vjciٟsas?mىO{ik,<|h ~K`RR.,ao73˪cD[3b#dԣJʲTEL1Ú$ fqPF] FR",2?Z>0__]e1,+\P۠r%_QYlb1r0coQ+-x>D@^z~YλO(iK`b; ?&oҔ)Qnox=Cq|}|Vq'=: :^U/;oKz]Xl6χ()sҰwp.ၞ}i Mӣ[WsUzv"DTlJl1ݧ_Ӈ ><CMh!ʣ}ۗ (z7hРq^DٱN*ϋ7mJ!ٙp[Nt^9exbWZ逸F8M8A^v8~dWixwP-rdn~0'I =t|yEH׿:Q.E?L0џJ1 Mn']Qж~evY3㷄GG?m?Wd '  WdxhtJM|;]} :x`N 8>M<;ǧ7P|<G[3t=d?wC_Dt>>Nء=%ߣ;NvzaH^\L5nucC}]xt`ŗ\Jr(r4o0W'4G&L|)'ў.gJ_Vf- dsT\/ ol'&XK륭ѿWB?8533+lE^ q5_n+*aH|3~[0O7|8͗RgurWjP;_0Q,E:]~85|B,$1;_֪1iC8j#5H!;{i~b@2b'y;h?f(FD~jRcR,r:lҟ @;ժwf֭<8E~^%K~vD!8.T p+E>1@?ulZj%ֳh"b'|fuyVWj 'BT Z٥F)ᅬ~j{7(:];C_+^V^CUNfKidN:1+K>4oFBs >b0zwhcF"w܁''xyҢE"رИ'xu<A>jǟǑ%K9+nȘ|X"=2륗iaS8N{ xߛ>':VWVp8ǔ:~lDhX/ s?xPDbjDk׮]:}Q|>C2,e gG,|׫WiI'fרQcqO9x_RJԠq#i'f#g Ղ3O@I'I#I{FISaϔQ Q_m21y{3y=[qwx2ϸxF???t|[` ](:ÉR*M'>v/L ӚNJv4mSD7$\מIBӿMFb[m5*^c- Jf\5Z f?پOK)3c&/|!2 ~sG|r#CF7E¨'KzHQTQrx6B,P/"%7..S.K%. Iq4+,NQdْvqU!ИMag( p"%R^MQF#IsppyuMJߢTw{\ɇ U^rYn%A80 p9(Qq=9ܿZzԴY3|6)_= *Cdr?wp_fDa6|& WL41* o.Œ{Kqw~-a>Y7D *jv$zTB"Ҍ'gxh=ᤈ }O?T5C%YNc[:3JT.R:C"𐛓k418a e!'~Jv9gO Q;9|oңdGL '2Ad>}YS=.tWi\1|Z_~q .W9GADrn g8>Eon&Oo_8>mɻ3!੻M߭[O:)^py|\ͩp-#\gGnsN7z^;GI?7C! y>Ư:|dD\Nci >x4 Q)|.=?2 DħF(c:V"L5?9X}hW.eڵHhDZ|]닚އL|M~mH-tTggʥ?/iӧ3@TOeiS\?c돭?k_6 ``4o'`5*l?8?mfgK7iXP&]}UPQ62E8nZ& RjՆnVG?+Z=Pjpn~a1c ]wU:?V֓߾e8 HI:'y2F ?^/PpݧC/~<9q̭Y5:vLmc"WL@ħeќs芾 "O18װ눶őhOknIKL}ov~ o~?6uyTV-k=Bnbӟ 0؍-_m_ Ids> ~Hŝ??h߹sWjҤiBp{4GU6yϔɩќM8jt=N5km"C״I3cq4?~]EϿ۩YK:q'և|se]dDgEJKS[r1:fD8Gi 8ƳcgC Nj<^p|H?u Q6#GmڴfϛC?-^KkQFt!Pi .Z8m£WPB׮ݝ)^tǞ :ѳ?/Y|뒘bMiˣz Ѱa#%?y$8a?1Q4nL7l.;d?]wPP! ~| E1 uOxs_is_ΐtރN_=|aG?зJ0ˍ[oۏ:l㎮AWA`S _eiDTÚLdzADzm_DwRK/CtV㫮F~\7*JI7s?Dg13eoMo^eS sg!fG$fqnvcfg??la)_lfևaX~$T2 $/ْ!(nKFTrdP];" " $/_QڑwJӕriJ(&JG.|%@o[" Yc8$PҔP&!U(m80_L$@o[" Yc8$?)JǧPW _r/_WtZ_eTZn'PΟG5 u# 􏍿U/_;D!eKY/ew>X՗ ލ^@ZkӜ9s~(?tI$D*S Ot>Ė!QeDt# r85>GTר>_Op|yfBaCkSg#?Dwe}mۃ޽i!x%">qgGt<;o'c\{}3]JYB|0s韉"SY|l?!! ؑOVJc~'tWoVv%H?iqo+bT8l,"Dvʩ1+/Zz]pzɮ͛="vrv|ztܸ"fqdUnNBw3H;8*sؿ#n#=DݤoI-D;eD+]g7n֔<(j{ATeh8cfK/uԱM6iiY79y'FrM?b76D9f֬!kT8O!;oUjjD+U7 )[֯@!"vSx ۱= +Gtu pDH<ǝjly/׈>0UVљ_vt!9#sǓEԍ+J?3OV9J-_7XSJSܶo_=C-__ŗ{Ɵ0 ʖqO'0#pħbǹp[ӏq<:*U@7"" #؉$2LuO?=w_g \iӿ±xCX'6='e- T8N2)H8RF#M㙟ʗpۇp8g82Q}{_n o)1|kg tĉehuԣ[gG@ZlEv# &ώci1i*2ӏ\8ʫmKG>jp~0")X $7i(Bcy9to,#sВ_`8-j]v#:MxMo٪%ag ^F-ώ;T{#mBJ~rgd'pBDjt?CK.~7tхr<#{%1Abŕ-? )X%c?[~`P_Uov ̌(O-9/sж;(mNoDw6?c6/fWPg??;tƑEjCa?lgчIbMkDZ9 ORu(ю?4IɖGݲ̒3l|,&rLm??r+V~3E=f3'mRzQ W]rա0_&Lnwb{*:|f擴qw4&s}AFJ?c; k)|wj O_#"濥7+0z{ެVm{8<(cG1{_N=@>~VJAD*Uh#>( hRq)s;̀c_:uiĝ#QϮ]cFhҥzOuG|P@1.7/b_()3*TnOkn UF+VA}H_#OQdB92 "> #G.p`믣>0$\s 灖6&Eݢ^\Y*_郝?_wCeH<}ܟLW~R&Gy$w~/~jϿߦ;`G;vؾ: iGG|ڵYsXp|*% Id }F">0Fs#%bcyp|{r꜒3_ 7jHzŗú>茳WB u8:7:% ds= Pļh΍|wѪp [Zkw(X벎ѺukE-/Nózjg)#G#.l4륗|#$4I ;(ލ֯~geǯ͍,cp8>u@s`m]UZ|9~کYxz_Y~=5~q޿i:3 ߿rlG*D ahJm2`J)px%/RjHـ K_"e[`r???, o_[r5FE[/? Hnΐ2W!3l/oȆ?׋NQz1nı7l~W)d\blri@++놲 ,/`Mz7l=OD"Ѝ1>z✇wǽCnᖯJ+GMwPϗƗYvoذ :Tj/4t@$HoL <|S.he4?tP{ԅnGD {̟OO}tXcZlKDgy&?x0jذ;hS5=oNb̟~QY&]GV ~M8p<D@%ENDDw0cp /]ddIk[g2/X$.? %6)Ţ?>GU&P+vE/d_f/2ⶶ?OLr2)oKrӵ壜j>uZi:ɢ(*O]VkAm*n(iSW՚lP,rZ"Uh(&j>uZi:ɢ(*O]VkAm*n(iSW՚lP,rZ"Uh(&j>uZi:ɢ(*O]VkAm*n(iSW՚lP,rZ"Uh(&j>uZi:ɢ(*O]VkAm*n(iSW՚lP,rZ"Uh(&j>uZi:ɢ(*O]VkAm*n(iSW՚lP,rZ"Uh(&j>uZi:ɢ(*O]VkAm*n(iSW՚lP ,7yz(zs\͟LJQO WH?<_rجl_C *ё?Q@LsQϝ}'=N;Z4kA.=*) >"qJ+=<OWDTCUVW,enQv6ls|{sӇ9AWj]ϭ*)o iֻCcDz{O?yUpI뿴S8s>S4!W|YW8>! BԹ#ܱs@BR&M@{4 g"Ӄk}Ow>8?rap`> ?z"g=%#'Rʈeӧ-@d-ra| ObҟD8U(ǧԷ/twYw:A|R$b%t֙9QwQ]vf\OnWY~Is亲x'ת iX9J5{w[)"'DyrZiZt* :g!ߏ?En;92xlHD(8>e9\:o#t,d?C2e gzjA}8B5*G6B_3ie=_t3φW?{8;]vQ3i-ACGP <?/G Ѱ`ZŒѢ*" vB;, =؝ƌoDx3lՂnvQ߰^ʗ+ϑ.u-PIM5)o_4Sr_^=mffaf_fiߙIz":_[3?0?HW)a֭Y~FE)'VڬӎA<=aPr#f֤K⼇45fu(3k%qC hJn̚tI %7bfM${HMSCɍY.R@Ԙa֡F̬Iy)i8` v(3k%qC h3:܈58!4 L%7bfM${HMScY1&]=)ءF̬Iy)ij0Pr#f֤K⼇40;܈58!4MfJn̚tI`1&]=1ìCɍY.R@pPr#f֤K⼇45fu(3k%qC hJn̚tI %7bfM${HMSCɍY.R@Ԙa֡F̬Iy)i4`3D|óx@ p.T%|P+{EQo|jjTB{/q'V LW_-Gd|O?ߵY3aǽpBߕ~ú+3<2[\+ukfzFSN;M05q Ѝ7"2x .>`Z Q_27>aCAڟ; תU蔞=!㎥8;b.zht"B:&MLeٳ*DjbSOڼk4t0GxrK {K{G.q p`G!t(ZjMժEmmҏp2p͙35jܘ4h.#[?v,G=C_uy @/3z] )Si£J)!0 W ] uE"@9ܳŋQ;5H:>;#ݶX9:㬳h*a|'iŊUE_j5W/Op@Hry:85jɓ;邏MNzĴz Ts8N(c'UY+ iYhpv2kᥗ]a͐b_̞C%KZ٥G7*WGw?;ǧW_ym֭K~&J pL_|5?Xv_{oB0>Oys ٞz i6\_\k|e(l|;u;8g;~*Ոr."q \oCֱ3 u=u*$s?zP "Z~4`@5kֆ-#AY(}OÇ <=v?bbǽEpc=?C2 G:J߈5MLr?"i`"Qң?"HBBMaM(f;͎⾟w%IX BBP +۹ LQ"v[JT*ʽ?岱r9 W H a"H@j7>s,/i̼O?=kyl8{# mHh hw9fKm/cC[3= $IѿQ|`!`PG)v䩐 T۞]+9,`PT搓2g+6eׁjPOW[a:huZ,qU?OmOhskF߸VOv?<\9:kaR.<Y:I; ͮHO;ky^˫W&x__! K=$C=>7k^[7t7',z /{O}=}g\rey/*y}ݷ\'C^X~|;y}_]{͐M-mi_ח'ܾH>OzѢ"3^K\+o'M0ѣݿۘܮ{OZ{P7#W#Ȟ^>nviL}g=DK?X9|<<k #Gu]ﳷ`c^7ΈO=dor=Jf|- /Ͽ#߶7m7Ov?VctT/OO]&m`"Նؿ&)ğ>1޼ W?п_/Of*,`. _f!M=o gyqXWܙN:^lL( 0<طS$6>B8GR=taT;L|W,/0m?]7?lzۗ7)rn؛|4\3`kvZևȟxA`_MA!$'7/<鴞S#5(8;?$A#WοtLOm +W_=&J+;z|kJ{LOT9NJܘd]30uWxnE;u.$( L(`&i%eu&A!f`F3N+)sݬ4 1Sw5 wZIf]IPQLJ\7"MB]fVRYibj0ﴒ2ͺH30uWxnE;u.$( L(`&i%eu&A!f`F3N+)sݬ4 1Sw5 wZIf]IPQLJ\7"MB]fVRYibj0ﴒ2ͺH30uWxnE;u.$( L(`&i%eu&A!f`F3N+)sݬ4 1Sw5 wZIf]IPQLJ\7"MB]S ގ5,^PV[^ʑf %մZ(l .b\4ܬ? ȕ/ݔK&VlE_@VOOOOOO60Y{+bf[2kl6rK7?M8?ǮR@(h6?z1fεNK>z+cj43S1Cvq|˜if±~|'!}PldmN8w! ZʤkV A =t.@y{ETaμ}F[|Afk|t1]m[b}o?_???\/:1va4 0 Fk)̈@4&IEco)8VAb2a|[s2\)1 oNȐ-BKIIIIII)Y??m#D@B  b (?wG$@êOB? Y?LD@L9ky D+v>TLеk>QX@x4sO\HB |]O3ܪ ?5;6K} mAOsc.&20 >Yfn??Kstb{ku0ܑi䫠UI>>"R+>҇yg`MI0W-_sKg B)s?)gk<ܰ#wmg'Nɿ'#ɿ@nϯ;bo|Y^>{A7q3H]v?eisy?Af ԩib5CtE:) EۧbDgOݹLa /O\7> ŪRܱ$oV~V!`КɁFN } f}Ikϰr@n@b_k7?QwS1wK=8*Oȿɇπ#G?$H"x8`QX!D@nIȿ#FM:_SUYuE]Yo|?vG NثiѱEg;~cX?SP>F>'$Oa}K9"q.5^خ3vΪBH6 1u(۵aqQ}i| yw luaE'w/gJګEuJ+]?ǔ骇ѿ$. /Oo_]"D}_?'/5'Ο⼅o+`G8l[57lᦴ7>mzħi@GD2R=h/:ڢ+$JIF%HȟFt->@пS؟凕41k|]aGia>(:O0ڰ+ymtZMth +jk:00KrpU)]BY<:E[@7U%g.Gd-\9h  `uUcA\1G/!*9~:62:E[@7U%ǏUFq]9h Hp0ں #mIF[W?VPus- h몒Ǫj#c_$qC8m]UrXu@mdȗ㋶$nJ ⺎9r| `uUcA\1G/!*9~:62:E[@7U%ǏUFq]9h Hp0ں #mIF[W?VPus- h몒Ǫj#c_$qC8m]UrXu@mdȗ㋶$nJ ⺎9r| `uUcA\1G/!*9~:62:E[@7U%ǏUFq]9h Hp0ں #mIF[W?VPusxa>~3vU>ήe_8]EJƨ~~d =gh~1῝!?)TdA# ȧȞșQKpbMAEII)iusvC$T? ?p{rAɿ_t,O?OWulUY%|FsbI7Y9&(ȵ9ɹE$;D\dOq=`R Hwۉ\jF;3s㋀A);V'ZIƲ?_ 5 M[n;k=WdOϥ>s֓Vm_Z$幮Z]ǘ}5ە$Y_|ZTCm+͓2b-F{6Sp6VATmԥ;9 2F$O#kIjnKp$9^JKK/X=oöGQ/Oooo/3FhY1DY [툗k#F ///Mĥlhs;VڨVZ_?;4dnۉ7>5!B=Hݝ]'M՗n"^q y7-t7(Β܋7{cmMSN;qKuĆ@K gKRKZJ?q(֞y?_=^k<g A`???FTeHQ)s@͙Qi.-zC%K?Ka[MQxBT Nea4_ğߊ//BmD6?H?DIx47tjo< =8EatAI O5ȉX#J~۶ka!`D?7BJd.ÎCL?A\,.,y(i2|\7mm_W߸㼻h !%j,dcI?п?<'MAEIM!,2n+ B_#ȿkO?2#H8 HR,_tߐ"DiN/>䕯6+'4UgI݆m5pÑ+`C?7%tuJFNf!X#`f(iz"@ldk]BM?=|c\ACuU{Ti̫oL^[tKvX3QSYm{섬/+=og A)M=J )7;1'ߜKNgPuX~ ٥&P#oUe420o7 Dm /OoBKJG0ѭxL1NHCY-CR"dV^?'$CC( "4a<%ECMO_y,Ex逴ڹǷ h7^=X;;(OV5X@qs`v9ܾNwPp5($]^*;ў;;(Y`~{vzwP?Y՘S`́尳3.rEXenH*_SӻT7]&q] ;8lt`ۿH8?=kB^;n>Go74/{3i SҔ_t8CD4 WhѸjwY HStq] o/OW~! !zb-< "$&󰪄gGv9!I'|mu#g>]w>23iNúSt8)@>G|Cذ/s7֝IC5G&S֝IE?v3dƢdB&,DtL^+j"{,])Qr{VG/.J24$78I`t-CֺIC!&/'7_i?,ϴW!@ ?[M?%LY;wKIw{W3zs} Ufkhm:EFﻹ5;Uf}J9C5g^.aS,) 5?}A?7őtîLtYÇzxǚc H$A2B7CMWF\M)W:Ce^1B xQJ㝦S OOɁɃm / /?%_R_/?̓7Joh#Z檺 uP??_(Mc$5ͿV߻\g<{M<{Q;ֿ;ﹸ|Wg`Ba/W?l̾i&_o:؟Uc?__n$V??WDODF,Ȯx"dRf^)PVݸ_~znǫ b(ַ yB.3{F丝B?_:馷}ϰR >'Iv:: A}G?x7Г^ɓWJ]\92Dܳf OסW܊h@jM{ܬo|cя~l]\]:~boJ_}KIG'Ż/)>}0#ܓ_W,_#w||[.<~ 9~oyoWNB;ϯxg˿X<7A~|gy=9-g?tߎ_Zz .~.˿ȇ>pr'˯/W_zyy2{G˯~Y]yv_x>ijkYN?kߋ/oc_KCgۺ7&YEѿ_bM2L?!D_o7?!C?,EqClzW@IDAT]U{^Jz4|G M$tH@D؀ EJQ@H&  $/SΜ=B̙swvfKQ,QOR|r Y*"[ #{ʍ wEJ)PK]:߼^ѡ)i=~ K37.O“R٢T\2GѳN;ʸ~.=Ig!g&esҴcɯ[_~Q=or!4`:d~{:t()'H+-\mJx;+iS΍ $kZϢ>e3Lw\ {=wQ?IGf)bI%p%d He֝2۟*X;*LE 5gC0,˱^ T:yA8~pҹP.,՗mA;켳ʿ&qZh> 8vi~@7Ÿ ykk DgFߞo~b3ދ1hM3Eh A=Yt/Ow}7544O =7nGI>Ẕci/;㌱zOt]w5zSهj.шzـyx-mЊsTegQ4k9/֫_k4d;mmw]vvқє^&?KyΝJ/F/wc'my wFVI,m>tĿK~5X(y{'w7 ׏>n؟*Z8Iwk}?F?/\NV9gAm?ߝ7o߈#Fڜ'ɏtaӴwhI'J^VP5Q8e\'D,ҋiA"Ur:T^EBnV1T9Eۋal CDbu"A!( _7,dS4Pܾ2ܴ!SsHLձH7Cz;?)ֈI *! lL]*,9=,SSu>"*0"a?\ª_)?W>™T%_eH:Q_l,m9N&+xHlf^ْwYa*ͅ ~?J{57׿U::m6`Zb_}c褳˦x158^t)ǩŧK9}{p=TnlNOAAeY{G#1^x﷿ۏCGܸ4ct3du[>Oі[nIs Ͽ@?=pԶzOKtgwKK,}ُvigѣ^}[Yo԰?PA;tPjmk=sj+QFi'Zvoeڰ#[}4u}&z칅p :DҖu}Τ[^w6X>V66F}{譙3hqcUZhБ^dT每ɌV/YNO蹩/Ǭ&Uއ2n0eV2[.~ 4_dVNz*9+ˌT5fk45U?"p|._Rc+ ?PPd~HQϡj?rl 8'4^FA ??l*<$&>Š+]G"DCH<:Skڔt,ylݫ42T:o厗l@Vyr&:mґ tUF9A27u@#orUTGrMt6Px39@TTGrMt6Px39@TTGrMt6Px397|u|q\tBSn($iqI?NђboF=x!YhW_{ _{5zG-e•a*Aq'H2~W^ Ik-\]Q#_|)ŧs0]fe7{\niŧ 'Qe6*Ɩ8mH߹2ݻD`_-R~fXd8=y !.=c|&m!tUߓK?я},_{{] xA* /975tM3]Gڛ>J{Itݵ|W_E F:L3;6s0hglH_bBj}e-YG#؟b3ٯ?z'*=.T2f#m^~e]~/ɿO_v㛷~9~t2J_D ߳֡/eVz2>-{+o!fDž/ğ{7ok? D'O?'7Cȿ-hpQ i&@IweM\ủ%ȏ>QU YVm9N+\g'b|QW׆-GHֵ?+_ޓk;j_'cV "/wOC=#Yu]n*1Ԗ=h}W|m=GMbw0/|2L_}f>Zo鄓O$~?;'L&?t,|:𠃕> ($nMQ'L/>5cfY~n9.7oʦW޴6*^s7u_ΐ]>Ւ;\vxe{10FNK;o=iny}ה_p 9~@&­hƛ: L̓^!q~یKamNo!Ӌ#Wda,lfjlhd4 O|mHTYmuB^Tj˳twکUן/AZ/8٤Fދ֧~2a&ը2nvM]/tZ"v+ȟ foa* -[?&?0z"Ⱥ# ? @F4&5g6VVJ////ocɗ̿ ` O {5aOqzbML/U8]fI ]u!kpsa$(Ȇ )ѐK"i\?]+jR؛Ԗ ĽV ՠ0;|NI݊_qpWr`4+1zdiS1Ojy S9ro<= z%^cm/jh}QbrƷMl;.ZUK >HO9XGw}/i=S<⓰6So#E ^z%g1dv'?}ŧx1o%PI'wu|gi}Q}a ]GO;557oB[axEb]t1mz_¦[o~.jРAt7jmk>} |lO% OWxexwn[CQYJ27Ix_OJ;v/xjJGʴ5uSg$ VP%\[‹~gnױalJ2'\z=sEf{lދ4K=3CHQ}Xf'8N=Yd쪛f/wOtVmǻf9 j? @QX 8ѫ5?{Y_?4_?DD4}(Ja_+?RhmQpO߈5OPZL3aZEmR7 +j@)ii[䁲LriU/0[QHo6l9DI@ͣBϑ:sldo M yT9[gm 57 =Gẕ5-C7&QHo9Fpr&t<*3N@݄ΛG#uȡPys[#89tj:oz֙ck'{[ nBM@ͣBϑ:sldo M yT9[gm 57 =Gẕ5-C7&QHo9Fpr&t<*3N@݄ΛG#uȡPys[#89tj:oz֙ck'{[ nBM@ͣBϑ:sldo M yT9[gm 57 =Gẕ5-C7&QHo9Fpr&t<*3N@݄ΛG#uȡPy/>[g/J\?g dLV$ gmue 8dgr.zw#2M,wohҥQ}> _y٧*Onjjhs'Ӊ's;\w:Or 4wޜU?ԩtj:zh&DJ3g&PKS߸3yӫ)D˖-|*KLtaG2l]y,|"zkl:S)NES쳏Ǟyz},o~t-?gΜIcO?Myd?̳hw~a#O#{|:l%K?r5b IzfZh L4҆=;ieQcvܵ'5^TZƿV& /w4{YXTYKZib^l~2O}^Ti[ʋxQSR*/J*W3m9/pZA ,kN84,5 5QDӍ? ~W:>H=o#n(7N,~ ANpنMA^{;Z:hIm kiZ\YhRU_T\d z_$,_liؔf_зdyhc!EGZꏨJum%\HU rD` ȿDȿ!BZ?!B 'ȿ%Vo?[VIcDG}/>yAcXM)b~8h7Ք"&Go񊠱g1Y?Bx[4K}jJ#䀷xEX3VS!->c5rd"h,)EL֏MRRd9m2^4Ք"&Go&}cXM)b~6K}jJ#䀷Ag1Y?BxW>c5rIX3VS!M+RRd9mqФo,)EL֏&AcXM)b~8h7Ք"&Go񊠱g1Y?Bx[4K}jJ#䀷xEX3VS!->c5rd"h,)EL֏ކA/>;Xx -J~]&ó4;̎X,DQURjcm [vؑIx'J ,C;3YaƋ?OSyj?!: T蚫Tգ7?sktTmLc?fL)'[e/>564i}~L}{e˗ѱG]_";k4c}o ֧믿c=i>,A{^{ߤ2Nl/ {~9ˬ}=&+ b1Yſ_mEo 8<ִC`?>wWU?Dvu=hAMfl]%)&c3 !C!&WXPu'q x&6@GC@9$ʐ& _ȿ / OgI¾zVLRJ@m紃mrTbd*i?,#o=xHU 6I+ǺM<{|/5ZTb/cQda]?yS=KVr4%%oxvB-!' Rp?0~A) e'襗^;6/ }CR}4D-7Ӏ90E#u6ROs筲Mj(7Ҵҗ=7]?AV魷Щ _icϠ{ر|J9B,_ЭZuǎ[k_MaN2t]yz_?Q{ig^/GzD1'9Dǯu҇O>}㢋Wm7L^g~p;Nٲ7p5mH1zJҲyp\߲zAtٛPmLK SORіWd1_]fQ^Tj*R{CIß[-+w}̆ft)eS(Ļ~BwOXup_1~ 6fx5/*ן+Ti[N{25؝ɩhe,:yAlS:DѶi ٽ=_.^՝ˈ! 0U"l[}YпUtw10輧Aݛ1 3YO;O=*b<7<Dۚjyjv9MGW_G¡)q?As2wXY*l\ ozPٹ`WY"覦&ZڪcmG۪hɒrG{M6W\?DC69?uWȗq'^'§sM#Vx§s\㯎q]B ̧w3}9{e7fDGl?.,M;몮 |c3X/> +Ze p.sQɾd f3Fяn_:\^JluۮHͽzs/m04ѭ Ͷ[J<:4{I C7\m>t/pͺŋoaIKq+7v -u"Q) *6lo~}cȘ̖o0~tt2"[-`k]2&ƇZFGYEvdfD&hvLTY?ǣv# ̓?#wZ?4A Wf1숀X ?0"@V/ğ?z#H bhpir;ȿ!ʬ"]0_?3Y_MS 6d\fS .X^%#͆BWVg<K!i}f1fȯR!AVUAI0[Ww?_= 2mtF,Ye}o"_G7s;W W_ۨI?od++ q/hAw]֬=`] )W g?w:}T{9zso{|#Xnv:jA#CGVҥ6=(/YE0njll9sЩ^TTu7_i#-gW\EC c\Ɲy-|b{ի;Th*[u߽J&s썇 +Z8qMO{$}]F?Ͷ[7m|վ~z?O-\ tg!,n\FWFԽ׷wOhm6K|R-bLK5/fNdV 6*//1}ʻO> ~[ Z~2[Cm)_A})]?ߨD2Mg ? AO4#7_g1`E|ވ?!7owLvȿ!BKbȿQ@!BDɝ}L?cڔVDVQw #eL\'G?j(n+%& _#|iCп`a$eJ wX4'!p'|=~x]opߑN R&A?3jf{k!.x>4{:.gY}oVл 3O{[i*_짏9/]Zum\SOy"׿mw:s:I\y%+mvq}huX;yaҡM___.s5?{[o M:=]I|hŊz9o>t-?zYe>}1lr'Y_| wnGI. .Rznll25P;m8/+xL;CU1^&_S}bzf]%3g.)?ʍD- tȅЍ黿jsO/(4}{/,?oΡ]wޚe΋xJV+^&*ycB,kN'l*[*arj3.M*Z+K;2ܯ q0,50j! f%lrY2\1,'wa&NAv?2;$Y4?3r?O$/?Q %[_XX PB7o?!B '"!H%rY>UŔ+3EzHȸq @MmgB甪]L<1lʒ14yگqpJLu#ޣN>mszxhѢE4}{D^t''' OrӹӨQ3ƪ_v =>}/hn -Kmsrv}:iCH2U/٦o_x198~_z47Ё-t}?'ѷ|]=b5/"vmsGkџ_bitD/>/TkvZYG*˨u /"j] :3m13\EPF,_@m6 =;}9}E(T*Vgs̎߯//2=,Xf*,>B_:eeߴ׏FEE+H"T@*0ۭA,ngiCSߦ-e2˳=Ŭ#sјu;?g/v2JxhZC)o1ԟaX-WwD]ͨ!B t/KPG3?#0+ 'B ©|X'd%k%:L9BBtvhg8`|?1L."p}mhy|/=%"H/@ m[P _{_|L_͑ʡ}n3ۃ"ADWNl"XJO~'aՒ?_}fkGq~Qz?UW]QSzI~kN.]L9kcў{UsyЩ\G?j(5V%t/>EQCc25uX>hMMt3/ٳ"]PB-|,p _|Z(*|c\_z=(]4~ł?PU2^f%^||p6 w76WScf:mf4d֝^{'siykԫvߺ=.m)=F]O7&_h:pl\lK Nm1UږpT++rC'`-/@5r\S RivԴIIOŋ|M"G]|or_ۜlړnyVziNNuOY]|2d7>?/n?FğbH$?f?ǢR̿?!DݽoREc3-Oȿ#F7Z;[?\ Oq/Rk3/|00c"Ph9еȜ/ms"<YŔw ]o:E:?!s`c̿,qpGŧbMaٟ8/77!ֲ͐1,]:.DjsϏS?/˗-ˬE+iM6׾JO=UiT'p/DVK1~B!'}kٓO]?x0}Bl/Bi߼߸/[=?3h#4r.9,?Wƞ~6sf_lѓ.p\g.ZBmFtA&"ݹsϽhq;.h=_Ӳ_ !=0*70/Yx/t%G^S/r<ŋxڻ`\9~f?|1k\.rp }űIy(",w责wwEJ€s.5RnDr}k}<2\6j "֦xel JEMp٨r+?$h[! 8Q3(V8H$޷6Cp.efPʭpH.om0\F͠[!\D{ta A)C">€s.5RnDr}k}<2\6j "֦xel JEMp٨r+?$h[! 8|T)4Zڴ!?]"2#[(?/pߝonICxEh9TL!_4ӿF.|6p0=#o]9M=kniv؁6cx_j3kߞ @|^|z٪K&5;~Wϧv(;^LBG?N[@s½z{Dc>{::x)x,nꬴڤYTEK:i2͚[7Uh΂NBopBQP|lb)O}dмM}Χu~m+eٖk!rA] `Wwֿij?P:'Oğ?"FGxٍ?!Xrن7o;Sy6^>*(sv%G(rxq jsGg`Q"K}BY*-'/3=Q?8Vd50'4̿, -']L+t,eK"rʘi,u;o+FnNƗ2XG?e* c'!$. @IDATo6Z=z67ІzkQ+YO#B@Itq;-X\yE4?6oa^L$ x/b>-N!Wwk~ h_i+xkh.Fziyujo$|_8\@Wc]l'Oߨ??/x_HLO?O?S4rEM߿51"3Z'gm3d$7&H@%x\bI_&CȟuJbNd"SQ$(حbI??[`.̿9c2FеG)|) Z~uƈ%n]!!zP0Yg%(y,#Ƈ?(SCC-XFѳL56 ]6k妷ӛ ZiVZB>T^G0FZ{Oq'!(uY22aa?,'  Cka)SX<8 PAկ7 kh0 Ԁ/ȿ%DAP@V}^p)I`3#@b`#1aSd›N&)Tu*=IƑ#gN Z_Yp P琷BoFI e&?u eQRz# BA^6C޺()=pe/!o]BYk8wP grez␷.5JJp;A(h}͈֝m}[UOEn+Vc.|X*4g{z2 oE u1C0MǺS*h~7+B"@2ġY0aXğ B O+ꯨ(󤨯,hsPT@WԟQ HEQ6Q'slT0LPFgԟQF٦Syڔ^fvix89F>y'SfqZpIO%}G6ߤ 蟼p*]_dpZbfzyn#(=%ox:7Sk#JuNc÷I/yK:D!}ޤU*~$Yd_2av !gQ( f0p/ < ]ϔ!qv_!t3Nq!dy 3L DS'oq6]ڜ)}>N%DJ"B%.Y ;af0x,z} L#TQ' U!RI6߈#p#̝0y'?O*妪/_|b>c͟:O ȓ1rAQs yZ/ePO)UC!Hu5۔pF y*rAn.u 6 ePBVP)UfcRw;ZAH\FASܷGpc  ʡ#P~!y_?٬/ğcT)3w,2O#yC ³W/,ȿX?} R@%QO?=Z` /_C&3w4X,ȿX0ȿ)0SVx1`oOY`axރze RƄA~&Tc"s0S'gX& I+x2a|'lho~/j_w8<:lx 8i 'o}ȿ"NP(>'Of ?G< 7:=H"7kܠQ& +@ 7Pؑ[~ 4iH΃!?% _ 'o6IF$A!OSqbȿQ@EmB-B\$O` , yo?#_xF#ό?$&+b?[@2hԟQ~֟eTtͻښsB] ƞ;P C&]\&gɣ^&]\&gɣ^&]\&gɣ^&]\&gɣ^&]\&gɣ^&]\&gɣ^&]\&gɣ^&]\&gɣ^&]\&gɣ^&]\&gɣ^&]\&gɣ^&]\&gɣ^&]\&gɣ^&]\&gɣ^&]\&gɣ^&]\&gɣ^&]\&gɣ^&]\&gɣ^&]\&gɣ^&]\&gɣ^&]\&gɣ^&]\&gɣ^&]\&gq|INU -TĿ0|\Ct"{1$b|y C8j ]hybo!p\O?N}fF \z(>!F0 Se@ @qO ',`E ((>!F0?,O,?wr5*Y/.l-9wUܖ?ϬmD Ggl+O?s M؟;(Qf'X6JXJJDhwv;a"XB_@ wd+뗂 ]pc|>iƠhrPHE_?<0j`'cW|ϸ:/_wO5ğ6w D8E_!&O'o)P@rK<SI'._X$x.2w /6GmC PYye,߂fw-3D,#EW2#VLZSx*KT`ϤC`4W$Am1h X78w'>bGMR76F+/sf$( Ra[ q%浣X;9ka|a_)b_?#@&D7h%)%IM 'PR,W4D&?xxxxOx?xoxoߞDi9jROU7[*U yq"~:v!;)u`|U"L U+Gwz6j_%O*i^Rb+ջF>*yJکJt4[3|9u72G 3j)/1F#I>M䓓0K[%9`A0>p ?<ߔ1d-_ ?!D%$#y 'oPA 7kYPEW_k_QEgQ@? ?=⓿LyRgSgЕWR|-U@ʦ%(LQPE+ ]=Jq5) vbSE+ ]=Nq5) _lE刽CSN x'w%F؃1~@(/_=uN Gf ?M1 BL5#B)AnȿD/?L^B+P i$#&,C&P@_4{/"A Q@E$Po'ىY" ҙ_OҩVGGøy%d;VTRi?Q5P~#g P~ jׄ0x/U/>>Iȵr.\f# *0FP{3NA#Zh1Mcd'4\I#6 Ć3}X{?00jXC`":Mm> B[-ȿ%PB 'qZy}' ϝ?inO#ꏨ?ȱől4<[dmZ6o '{_ҽ22TVqT,Fya_J[NNU(t?BV:N:TСQ"6_t*ש>A&SNU(t_ GGr(U>,-R+"iyj}%"8|d|%-aثGPTf҇b3 ՃZdt3M/ğ-B`Cv?,) YE2ȿfD? B9L R"D ȿQиP0K)Y$PPA' PB|#a@G=`Ϡۚ>7I=0v4zKSd;%::S6&wJ(~k=4瓖9 a:D9T6&c| #Պh,(ÊJ?5õ/]uSx;/_4g%_:d^ʌ pb?_U9BO6bE 'oȿ$:`) D/?i_@Q aj ?3ϖGJ6dsL?쏱QGwQGFޣ34iSJVL e#o܋G%sCUw掗lfT^z2CJG6or+: ?? < Pxo%S:mґ 79`SeP)J7u@#67|xquZ'#$Т\K9^;[/j+jRػԖ '$__?o; ڒw+EBd'ī"c8{o @s1z7p:tRZ޺BS;`b-w>jsw_sV:𭷡A:ȣ%{xbލgi?NC:'_z0SX׷/U~vϽߟEkMO|_z87 ^/Ǖx9!_V$ glGz撾l<P(v@=zT>ԓ4W*ڑ ?=Ap|zq41sFHNZg]:/ҐaCO1_\d It-տC=>iРA5^xuzHEwm%}[ߢLYZ[y+CMG_8Lʫ5oקnQu 騣4Oi5.jji)H+qtz+]w K.Logk}4zڧ_ZS#?icXNa ?_/~5A֡o^g FW^u^twXoPOJ?U_CWoȿ"ƿX1rc5r8Z5`,)EL֏V1RRd9m0Ք"&GocXM)b~6V K}jJ#䀷Fg1Y?BxG>c5ra#X3VS!URRd9mc,)EL֏ѪcXM)b~z؈1Ք"&GohՀg1Y?Bx[=lK}jJ#䀷qjX3VS!6b>c5r8Z5`,)EL֏ކa/>iJyC RpH&ٔ/*I1E"IpiQ>yS/QAxz;Dgi۞$UvY5*HBIss e9'L/ޏMn-}j_Oj?.E}Ʈ/ve %1 7\w?龬Jߍw7бWXA͘Nm4w[4s>Bl#xYg+l'dQձ|5מԻwoZ_:h^ WR<3PaÆ1It@#:??q4}ƫv[^;5淹[l .O;xӽ?ӯw6Q??o*K4m4:s8D+.wuի'ۨg$=3_C=螻'fC%㍿fR[[;u.rmlHwÆЕW''9&NOvykuS/7X>=.^?O5`۽B?k$#wu_?_mHT5dtևALKam / x$AMĕ!H=êDۃ?Tw}??d']g?"^ՑRfX*s?͍;@Ez#&ƇY`{Oq ^8iea]c=E-G1 bYx)byS<{pu[]&T~?:x[ pC1_|؝6a\#c"2}p*Z?/1"Yx/Q>iG(OzFV8<܋XxMʗygA_m1ҳ|KG#Jl+$7ySPmA|oIݯw"}VI*ʋlV/>{Ϙ㏧:X'DW=Z;_zָq4C>iO9o.|2o/> |?&HӦM ;/wle]?+s,M_{ >m]!Ti"b5ؕޛ(J/*(E:5(RUٝ}8ܶٝ۹nTD6nv޸vq3s=5=s>q|#r#_?vWt;1KӓOf9"c ]__1?OFkV]9~o~#F?A lUfaٶo ~ xrhO/_'?ɲ)%mv>oO :Sʟ9HxUxyॻmxb] …*$f)\W9_B ?㉔N WH2baLf~#@!VӸB\fwWoE Jm=NYs5hm/m f6K=22`C2q05\\~MPs߆A_G5jR8>-%K/ŵ?@o5 _r5:Bp*zw;ms&D;:sӨ~2m5j(ͥ-6)'-$Whmn5av;03}5 T<,6Rs8ʘM6tWo:Zfu#Sofǧ/$2w>2Qeq|R9埥&?'N"E\v|㎬oO?xָv=w'+Ҧ-[iㆻ SoO/T98 Ʃq/ۿGRi(X ^< ⓮'i'roXx+fMuf?ֿ~9Ͽ_[Ͻ5M,,wwnK~av`~߿[̞j7umcF+B&5XBl퟿+4*@HgR͡2i,%TPL9B& W"I5BȤRj@ T3P4pB*^Mt& !RRHūiUPΤC!dYJ x5 *ҙTs(L8KI!TBE:jIg))4*@HgR͡2i,%TPL9B& W"I5BȤRj@ T3P4pB*^Mt& !RRHūiUPΤC!dYJ x5 *ҙTs(L8KI!TBE:jIg))4*@HgR͡2i,%TPL9B& W"I5BȤRj@ T3P4pB*^Mt& !RRHūiUPΤC!dYJ x5 *ҙTs( ;>אq]Gm?*Ӗ"e;\w}D@EĆO((h_8~\#}Ǵ<厪@uO8IѬس +=8Shѯ.? W^m[`="{xRާ"Eh >gdžժE蹶}tſ?1汧s·#Z C%,ArbbkD8S=1}ag v|p">MUR.":xt2 'm}*%0ǖ-[Q Kf~ѬY?[NaG1>3__{ϟ'?HhGh;SܢE^TF :T)Z~=-ګp?c _>< h;.ߢM+C}>xf.Jvj5p%\A_RFؚ yyj[O D|][7">ü8f͇sE5Uz4}O)e{?EDW\u8: zf͢^_?uHbwtmBE&L\D|vf93$\JiTOz ۲Ek<,C~г bꫯY>lvLuZza^ "ץ^JG)/W_g}5UV2~>ַ\r _*oqZh1=?bDstɮˣ+ /[r+h֝ϩWYt,mO2@O>,}$Ӧo5j ^Eķh…x<({y/8{+$,sdiZks:@'|Z綾&8. 3?JgB/Fsw4{诜bL+-W4fq]=I-"< n_agte 3*-Zn DʕAşw׶uktcȄwf+~}*VH7m&p+?UVZMڷvY<`8M| :ġ,濭Kj{8 yw 'ЭoGl_j߶-wfvĎO>,8oݺOpvbl NwqB_{c5\+uɎ߯N !:ZJ<.N)pBwQ.38W>p=-_^^zTb| {ܱ"[SL9L gV7F0ɟӿ&-e%j_?خe=G0403_Qu!c{b돭zaf&t|oihO+vLԐ]F`ٟfb_ve?sfgx.Y:+rVWGu% ] ?+Nc-|!#qLD'Ċ!TPnclȘɠ_ӿMLHrvl!#pq闠y}4c&-Sr+7kA@'6o@y0,YWz Yf80Ρn"y֙T2k|9őh$޵1Ѫ+iY4z kg:NŊϡ5߮K_ Ǘ/u믗H;rIn9>=Oa#+Snƙg|OAT5PD~Zjvvq1cǢ V@xmTl9+ ԢYG\:)dF%K醎;s= _0};ϥ/H3~wxTāTR%?tPz pż| <8;̝tJS^OgmFо-<8Wᄃyϡ#˕2)C}|}ŗw/;>3G_~}l8A w}GZ 9J<}9* D2FkքP u?/tAP'#R'L(?^v|J }9:Cd#"ɖ[u?nw:ҥK;'/ &Ćp~4qôaM ϑBBqH) J2ߝۏ* 4MU|J❮f'8-[sB rJD:W\hK曺{`+kЃ?"&/Z/8pڰqInǎO%rpV;ZPt8o\sM[DQ*),kDZN\<!:h}{":歚p|R_HrlիW"pcDxwpR^ ^[ugT qԬΔNw4OcF? pe"nC_潚ǴcpPJ{jPGoAOgF4}hG/Sr$ul++Pb$9߿z3F?.ri%+ԈE2ig/ĂWa[Vm5daZmlI _彝JNPao2dgx O2?5lsmc 1]uҩLDXSA|9׺}}L-8BƵn&}T-8BƵn&~ ʝKPqU!Z ?%(qU!Z@ 㿄[$Uq>k>L6)n\R W2u0;&"\+qxjD% :qEJO^x"\|+y4BG&{|'3fESB=c-o O;l:#d3{ʩ1爬g.t1_N:dG2czu @IDAThDB&\8,X*/GE[9+J?0"M8ƏW27G4w֛DȃsH̱%O9">&˖-Fʡӭbr,ХMt `D%:tP^)?蠃3ΠυY^Jv"l T_5&Ж[ZiҤsprO>"̟YaDD̛?zO{$ 3흩ΑK_6 8ipp6N'P]mEtlي09ʈԷ*ƚ0n?^NcU@Dzg@WZ Ϗ=za[&jռmB4P$\<9;̙3L9>S&ӟ#o1% Rw-7TRRΞ9Ix_oSD1N<΍Gov#\JfjV@<.Ο*~fjO9D|:">x"WїA%,C|_HW(=:m, Ճ#$:>˸'.\'D*6Mt)~o76P&j)i`ҥɟɟɟ_!B6db|a m钫?_UOO 2?|/\İaX9O1x|Wڭ#RoFOC'!Zn#w 'Ё>Hm ޻ɧ#"8WT /n/yp)p_5tȧw:z߯;}:x9lTQw̙ '#XbFQ@$ԪEK8 RSDN>zSzM6M73W_{HC"]'Xc}5jt})_]"rc'ag=BmW_pt8_!;1+S?bo/9tSK@=?vwp`j-1͚qk8V>[@/χ}ʔ)#kGmdI&>퟇~8'$8f+^gيO-7If'$(J{60y1i"p"aYw|Ag:gϞ?H/ N'#*)""Q+&NؿE~HOz+ɟ@7cⳀ=wѪg ?_ӿM_g7?3 =݄O;ilD| ֬E] O1P2zK]"Y 6R)dJ_9LKC~5L)`233+Ҕ`;O1R4?0I9P_蕟jTOډ*γvʋ XQ o~}IYp|Wyy%_)_z%M&]rTX-]F78B9^(_Dyx[ѸÏc}S<V,ɧ~-^9ntA2ψgq^ʎ]Y/" Ӿ2v'E|,'MHcnjOq^g3Ci E| EpHS{fT ajѴ&ÞyAɜ?|CX/G>L R*$Kz5]uN8h#b"^Dφ_R&%v^k"M?O0o5w"MO`AeL ⸉'.qj=˨m#F1N$8pi괩4EQnז.JykCဘm#F%@.fM1BrsZ-]o/'U8ѻ{I>L4g[Fzt=?H5pc{do_8rU_^aCFm wɝSs}ΎOp``&"ҭ[ gYABK^F]:ߐ GNmUW#?KgǧY'IhOR+Ut(9><ه#*;q"v|rW>+W9jbޙG>Dt]zԶm;y^pзSsD#QYyxGb+sQ' 1g!D<⼻_~u=kҪbŊ{OЖ-4"@)>=Iz%~ӭ7,Ϩ_7Nsѧ)"'Oyg wk7D Z% c}rX 4eO0'O@ dcP ֧Mv. %ϙG A7l=*cO<85^J5 ^5l݂[p:åw0HO?$-_c9;AO?M}ع w$¿MLٲ4ߢg?ς)Gb1fԹ0ԩCw{_5z'NDyEiƥcMGħpf$t-۴+qDI)Hvb{z3;>OJd$==sUvNzÇ;n޴YB~a?SYϚh~{8L4~]'J#;>Eħ̡=@^˔/OC CXeg-e]Z ^;wr3I OGUO[)+?bE8$n(=?,YV~v4q1_H|[g_Ð=p *8U 9/; ? !.zT?6q_U3Y6+m\wp"T}]s52I;;;{_qħGIfGdX)_`5. q(Fb=L 9)]üT]A d_Vq=j@)nz"*L#OIli˴U#u bm.w#.?>bg QX'85B /O',Y3i(\_y Vж(_"0˕/GuOhhƇH~~#]v%x\z58e<1԰gp86ǎn'L"yEOhCdmC'zґ97+ Q@s/P (Hd}߻@.?ZnNÞyV"A#VDqt|ԴYsy궭[߭HOcǍGc^hժw>ɡwߝFz#XPn+@IĚT8pO@Fp|+-;Ӊ91~=1zbţश4i02 *Y`v#!C/3O0Əy i~9XTC _#N_ir9[M# Ry\H]n]rxi?L9qŊN`}.탈c\nXWNx+3ǧOFQkn"SOQ#ĴI&@^jԬA>Կ3j45ԮCƠ1mߥ_}M/#bc}r3T^k *A`pe 8?v 3O6sߌLѿkABg?, @Y/\k믝Np24oh`7sf_Ynv`v{s>A/bkKOdWT0{Էq2.*3\H\a0),SAdBOH#IN>LU>wOjxDWo)D~OY9HS̫"_^#p L> u ?ǧ' >!͇R6_r刊T, /~'.fjcwh7 ʫ-[s(#T?Q~x P֭vhTQ6oJM#J]=Xo|H?Cb>Ѡ$&MO^*Qc`?OXx3/AT!;1lܸ5i%"ᄡn:jmd]?.:J{O3g` ~AǷB_j׵hޜFMԷߦ?_T#Zftø I쫥p!N? [w/DGgbp?OoC'Xp` H cGAX۴/R O9xb躶b3' ώ_}\o&=>h`?(*Y_73*jٺ5c#W~ֲ{u\4z)KhD' 8?#>/DncYg)nh2g+~Ǐ%+jytp(O9ΉlajCh۶Qh 6gO. xdߝ={Rݓ9S8>=ȣT11l[g}:OS10D>و#ӽIf;֧jՎXՇ?SO? v[wl5 r(gZΟow8<\&0uɆoʿ,&9_R`- EXm/?R)3rv%ٟ,5i?ȑ7/g7Y09gi|eOŭf_fiw?<le/7_לOfE S :mĐH\$qGue'pAw|(|T!YW;_e)(4U$Mh !Qd]|ißIs:Jw|(|T!YW;_FG㿄O4R(I]K!Qd]|9:%|9MBIZ*$|/iJR|(tT!YW;_{׬vX>RGg'?>,6O% M#61o只@u̿iG3g R|v_ra=GD؈~tESJ_}# ^:=#9өcariH?nܠ>O_4䉧ЦOqw?F<忲> 2 8S_",ߨA#jԈnZh//cL @ :GibzlfyI8kG ';zЩ"3{/Æ L;V}a|zNs|.=7z>bJʃЁp2ˑ]|=o?8@l_PV[!j5B'[o?98-]nHѿVtan9TD|ӗ霖&pĪנA>P^nRN|TbEk8>}ǠIw޵Z =֯mt?¹();s1GA>ހԐ? ??WoT4/VϰaE pY3qZDW)s.*WL[ gAO"CpЩxN (enVZǧhs/W!">&!RZNH?i GSbϤh1*f482?nMOwэsNDB h%g9Kg<to; e)q]p|:Iֿz\%x7ԕ9\)yQz_'臋.4y2B \ު+LTT8&Iyw֍ϛ'y\^ Z"U]1p!NC ֱcG# d@/&1X( x $ۉ?Ay/^M{ SGO W1)t:/_ Bo;ze돭feٟbY#5uOSq|BzN. SD-ptB*cxMt(XkIAlxFByd:b'!MȞn&&DTs$(- >kY+}NT)WΞC}hOӉ_h_8U;N~?Uie\8c|g:pGLjXs&a,◈O',5Zp!衴c9YH:3@kVGOڵ?z4d42G"2~Lyfjִ1m#^e˖Cv5 ~W Nshʔ1'|HՄ [oÆ1"L;d02 IhqhkGߠv-O;ڍ8,ѿ+(@72W'zaCnH^x!u  <[ThRevD)Z썏 ϏAx4vD*V, 'qD B9z?ʤ_@4Ȳ|9аgt6sD=Okl2RD|@;~\h?Swp4y 4Pw []?d`@#r ϝO ۣ*GSo8ܘ$NbJ~kN2{K}{aE8- ­ԲySD$&A-g$3yka C=k6jX>җ{TlTP/>u^< ߬y kehl*%Ϟݞ 5nO◁y~[ogY%K.Zl߮!/\:Ei&L@%\JԹKsї](@m ";h͚oeP~eiQ|+&ulՅG߅+_Rjwsr{ϯҳ :uL^tofQt#RԊoTzOeI_vhňw)K#Ծ'sy ƌڇvxh̙Y_xFyp G޽ucGA,ʔI5.?9GIO>$rnI eW3QggkOރ/pW!c)lz133c) [cv(t]a#˛\5e_f ٟf APJvcfC\` Ί/J%3H.2 rcNy(?bHħX/fI)k%]G6\NSj'ڐ]sКLBdBt+%mI.NZ 4GAQ{*VHh2$- ?_VIX&_"EI.JR9033)6am$PXeA 10U]wؤ|XZrp]yC&?[ hdp6;#訣* U9˲9Ѳ_ /j|]D^' >#wŋI?w Ǭ/^BwՓ6[N O@ '1upCIӦT>YPb'-6Db3|\E+W< *#>3ӘOp5@h6G؞utsneB g _f [N)RFM쳏vL5ÔWTd#"*ZJp,7l@7g%"}&E8EreRwE> oe~4z9R֭Z\ h`޲e3>^ED2GSkӃO3g9% f͛ӵ81#> jE Rky4/؝g.ڴN| ZܭuTNW= E])Vu i ; ǿx.Mҷ߾4}4O:T~ux"!p,GEvs!ёCwqp| '25]i)hz9RJ‰uƌQʥW]Әs'Qj֢]} ">#>-_LxG8>tݠ"{z3ta91f}4^x~.QgD*Y ޕ*V~;u-g{ UU&M{^<@0r vN˟,mN'rO?=a^Fe")~߿?󇹈{%+%-QsERY $|hag%!9HfPM=t o7c(˕)oХ`Cddggg((D2`Cdd'WVDHY`ې Z3,n>J?i!B__W^]rW:1 a/M\)^(W^MSzC(N<v,31|Ǒ6mZ࿫|-?1{m?=:)zd=H W!ӳ0>T ݼRG_w^BQ=5l~ 6 < iNݺw(63m{Wхp}{RDƊz:b۵uϠ_&`nUԡ=.5u OTԨ䃟3Ћ(S ? tحxpH.1J+a?dV 37R}iSR?8>1\^xMt޹xVοqdXx[;曻WK8R*">EѪ,0;siӈ^q?ѫ*T8*gm3χazpF)aSg&{?("|;ү/8>'&5 ':LPެyKD|ZnDĠep/^^9rr~y0ox֣*TD1f8Y&፝_719[9f-v ":]/acרYΐc\<_Z7wKpBBjߡ#]|%9B8AlW/"BɅ lT#10WULa";[$9!SRSنoX_+E'ڗx+/+7FYz-c0feٟ]j_fm ?v'g} ON_^<8a߅>{+OQbJld Y3v.Up-J7yY\7+KY!A< d"r٨˓Sfg?PXg2TL[ljǞ 6r $w|= uE֥ǃcsrn/jD *y1|s3nr:4|ʩokͥ{ӄ\FbX>(a9dz豇M7 48sӍ:y ܖMi -[? AeQEc3MJ;Ay{??,)LXw5bpZoH3eTt"*Sfs!‰wֳ:LJ%~~~'O>KV7'H=[o#֓pBh^D.ŗ_E]}?#oߡW_oAhN'wA/W4@&ǓGDqGw(TLiMхecp{7k!cs\٪)o. @عo*g]ve2M]:׈p?+WJ}‹.r_{U6 ~n^T5j(ԊK׭U d#讻#JIEɆy䡇_4]T"  07vۂh`sh xwߡ'/n"*Եs p|&C/W-w914HlڵA]1*Lg?VmءKo˖m4ɧA8u:torei;70E0qc2=.\l9|B?nXqe\:s=tUԧpqKXZJP͛Ht҈4~:jp6oFԯ'u=G0[Jѳ'r zn_LCk9v/yDdGxĺ'͈޷ ~?;nqoyO:c ocm[駞xS&iʘd~=HQ:FpS&OuLAsie, ;v7OVhb7_\q䏩šOo!kxJ%_[M&xd_?0) 4o nyaPh71vX)Ο6\3&]xZ@\oy\ұ0*TEvnpKlՌi4N**E|ײ:(骨e#]XFRw-ciJQ6ߵi4J**E|ײ:(骨e#]XFRw-ciJQ6ߵi4J**E|ײ:(骨e#]XFRw-ciJQ6ߵi4J**E|ײ:(骨e#]XFRw-ciJQ6ߵi4J**E|ײ:(骨e#]XFRw-ciJQ6ߵi4J**E|ײ:(骨e#]XFhG|dؑʦ4gOZsްM<3ƕF$튟 7u{ŋGY~kVi%O?;VԂ@*Uh…'HDt)`>}%>V6իSjк%Kysh˦-%zT8ɒ%qd0@y?EgI+p4cLZ\AEJ:סC=MJ+WPpIw*?~uN<Y;/&vSSu/]4vWKhև3i?2w|i޼ybr7ΟO cE*g\A-fow$5C$c=Nt%sC]P<WjK=Hj-ܾpd{ӲK1~FvrϭWyιp Y3> ki&豵*ЊUw'nᯎu51׏?|9%4Ղq? nH $Lh2=1F!^&&dEGXCCY L1cWS? $䒜RuEiS&b?Ug+*7Xvc_CeV{o|a;_ew_ s|*!^}c*i1dC&9:L@gިg=KI}!cA(=Q' 2YZTAKD ?ϳ;|E*ҚJH}!cB%EJJWǝC6dL@/4%3Vv|JA>2p{kxW+BlC&xQy,7UձOF]noCeD_[dUN[[o`v\xPr+e˖p*!mؔ.p3/ٚf N.5_f3jnk ^,y?x6 KSjo733c)PFWk4/ȸ8NvfvՃ;=;ysw';W#oIg:XIί~=߆OdF?WvД+5i!⼂A O"Yv9T8MU 1DWH??ms 06ێL)M 1DWHӿ ׿ԬOxw8ͤ STr+?G!BR^t!81_Bl=ӶI@IDAT&2??"6/_60q'SN7?7zR"9Ԣe++eSݍLL%Եg3_?d]0=c^2iUG6[cj?l!˂?laBrʾq;ɾ^Y ͙=ĝ$E|$)TL&*M2-zFq]72o%C %h6nӾ;Șr$P2'72&&&*>^2$ R_c3`3k ȇxq?}vߨ?oC\. ?xpkAA ?ih7c>?hB9#%?FIQc{>ukпIf֭[;7˿E۫d?eq]mwW_-tԩ@ &r)2fi?zif;~$>/ﯼAWP\ne//2~D6X߰?=@(lKłЬSutqב(C*TjF??4f%5c֟jV_#?=GE6qfC۰K&C9 _sq W6aOC]`]or׍GM.o733]_1GU=3Hſe6Zh=ԫ}Z,TĒm9f:8N`en?G?^3???~#';G;ĩJW;w;wks'vȧvjiv׹?Tj6-|\j _2@U>՞œ _F0o6\z4ZT xF_JBy\AsZ4eg??T?fSNjցrN_s!YȴGAP { Ձ&ĝL?mbttGoo/3ѱSZ2yad9߿/~ʢ/ RΟgI;w;jqϝIE|q5eKHst"][.yn?.'[, qe~?3LW-8hB_ӿ0c 4h˨(JOW1K?G898A__Nor,3š%69p8~) u^a)gHx?9 ~?O勥Qm^j2OfUf_, ?*g.vbO8h>;G;g;.>g^`2lv ~`f`ΟΟ+wV|6%YQV Ѿos8>e֍l S3fpи 4$7ޭE+G\c*ka"/%Pr7#Bӿ(n돭?[&">1/\!#ֿȳ61*6Q' p z& mC "!&Hёmdhgm7~Aw)@l%__9J߶??? 60dknj=? a2hܢ͜i?kw;;?9H"> _H7|K)OqTg3[dd0-߹l| cO6 &:POxFL"Rڐ53c7֪,t26B+OB8LFDIS6#ws]H **3z 1q$]yrySUXzUF? KR??e򁻗nSYa/^.2oՃe|_7olmocΟΟX!ɓ{ tiO';7a8;_Y`? ?8' k%~}:]';y (>fr7_xԤh*P9T5.B&Hex2aTk D]lR9BnR _y ITPC@t@ &UY[&4rH%_W ~YM.s3я˼ٕK31ܧG.'Dqo2üV SF.)Lc/\m_f,gLd3sJbY2r2ô3Q,r9I?miO?hv`Bo0cI\Nb/vbO ;7^-X7_+Q & rfϐQ"a3ɤ^׸G'qBa D-:k=6pՅ4rWl*i^^ 1Waq43FHde[0o_q|o>2+N7neMҋa ?墂A 8 L*k2 -QoX2LXuVItOFMcfi7[?leOc{;EF0_ȕ-ΟΟU?AK&:U&???umv¶?ӍEdoa/vb/v9gaD{|Ĺ)c!:T.е=^Hu\?2B|3BR/ +-Z)\yupD`*_JM#xu ڬiKUD(*_JM8A5hŨ5*lʗRSkfM3}1j %TCYӌf_Z¦|I+5Um4(*_JM8A5hŨ5*lʗRSkfM3}1j %TCYӌf_Z¦|I+5Um4(*_JM8A5hŨ5*lʗRSkfM3}1j %TCYӌf_Z¦|I+5Um4(*_JM8A5hŨ5*lʗRSkfM3}1j %TCYӌf_Z¦|I+5Um4(*_JM8A5hŨ5*lʗRSkfM3}1j %TCYӌf_Z¦|I+5Um4(*_JM8A5hŨ5*lʗRSkPXϽ@($$@YT^A@TҢOP XH PA!}sD|rvvv9sffg{כ4j֚N>v|@7 'uMX@HŞ4ۮ GC i㳃) +Hg_?5f`&o?8o8ƘtCPa0o?_eW_2+~~~~'~')$3G})-|_>ϔtv|(.UyR@4jUڢ /1amKS䀗y54&mbz2gXIcږ*'/+D2_Af7\#gu__JE@q748o\=0K)H[o_TFJ\jyYՀT+Rڦ) Կ`e񚗁zNZF8- ?gpOQ8VR Yxb8߁XT~~CnsdnK^ڌKZmi)~ѿ+j<ph#rK3uh 782 3?9Sο(ΥR&`b`?j?0$,~?:8P'o?@Jnj_r7aj/{³c,ۑѹ[>%aMݱ^VZk]))#}ֿ>>c̯?HRA]xTY5abk/_mnvXkajw!^؟x Z^aZ.@a_`ιMЧb.F5%ʟ6G82`#?s܁Q95tJSaEJ8o0## e?WB2OetJSa8TTsY1?M?x5jkTJ*Jj:"^&:'H2PjNԜzH !@9UP&SsJe"u(TI@N)  S%e:5t^&R'H2PjNԜzH !@9UP&SsJe"u(TI@N)  S%e:5t^&R'H2PjNԜzH !@9UP&SsJe"u(TI@N)  S%e:5t^&R'H2PjNԜzH !@9UP&SsJe"u(TI@N)  S%e:5t^&R'H2PjNԜzH !@9UP&SsJe"u(TI@N)  S%e:5t^&R'H2PjNԜzH !@9UP&SsJe"u(T .|US dt5ۦK~ ҒzMF/‘Xj*z-RA*/\M?GCR8dcdK>#-WaV^̶2d'O+3#\i!0Ɵ?? HXB5-Ɵ?2dSx0(|(-FZ'O(*$ 8Pl'OƟ?2!?12%Jc?'>gK}DŽ@@S,tŢ/pe%^#vȯxpk k[Qʓ4hA8hY\ZR-%OfڮQp(߁o46"#u]Ϥ*W'³T?]ͮ$/[PE?+j ?0bi~1M'+A7:4j~`;o3+̿3:@2,'̵ A"U[Q(IR`B'LF'*.I5XfC_Ӓƌ8K`.Qt"WLfcF%0?H G1;̣ƌ:K`.+6AFSrჟ} 6w dތ*K1i`9fE W;G%2-?GSxD8p}X"y<^++41bοl~a!9a7ƄG yt$W ?2S柃Ƌ"&3#?#0Px_ee%:ٱzLFHW9Iֶi㨂ڠsT'ֶiq jj"Q9ZۦIQiPQMQ9ZۦIĔ?DAbPQMr8$ MjRÉ mDL(TTN m$bD8JZ~4_s@[_aRiWs@DdF FA?&NZ I1EQKJz)_ҫO/u9ӹqOyҿWX^;lɰK.Y*+I<'x")_OPE ǿ~'>Yd 䩱O =;_8h%[^I\M(tK6BK e`qJz `ג/_?p?8+9b_3: AI!dB:%T@8t$KNT`.~f7)hA[_H%ڒJMqpp"N@Tx+ȟe)vVۼR ????L`r^ɼpipB@I7ŮM-Nk"V Cct J0ɮQDZw2kϮz+ȿw_Umt]+&iSCβz,믿 W5ˬY˟=A!I+Br)r)'G5I˕\ (I+d2_.d(Iƌy@FpC,ދ%h;w>VvԩW;o'_w,\0 _}eeΜyګؽ-k‹._w&}oI]aeu֑֖Vҵkg>}wq±tV[m 龪\yzn;qkGAps:Uwy?Q-kW9?wIǟbE3Ԑ: Q48#V+eߒ_Ȼ,ߟ. wxM9UK@h'~j[5 (]Wŧk)5FPc(W *Sd($T(7 !J2V%.SpG=O@p>au\ (?eJ3)]:L`w[?nW_lJ+E@3cɔ)ʿCs'h ۯ4w:!,X c9) ('7,:t0̙3SMTcs]GM蠃69twea1\9pb%颡tӃ2{W;.]u߀g[\T?jϘ!q8?3Q9L>W//컏Q(]n]H]ōgL~th[<K> c= &9cdڴi_kCwu8i~Foq#o_r~^2z-9;( w?9@cY8eW&!.VʿP1 /?B9N?Ff_0X/_)'OƟ9K'Yp'OeߟN?ണNShd([]<uS/rG"qK쀬V$T^e~Nps7F$ri\Yj.TWp-%z(sS\rj˗*Npʩ ._h2?K8U\ (6|Ij.TWp-%z(sS\rj˗*Npʩ ._h2?K8U\ (6|Ij.TWp-%z(sS\rj˗*Npʩ ._h2?K8U\ (6|Ij.TWp-%z(sS\rj˗*Npʩ ._h2?K8U\ (6|Ij.TWp-%z(sS\rj˗*Npʩ ._h2?K8U9W AsJȍ7{oCy!LbG[@e^sO}VzV]{j8eL&kݳEJ+;?`Șj|K.S'>%gyMQ#rՕWԕJM2Ko>2{9;>- ׅO`'ИɎg|\b%fN}1 v[ҥ ZrK- ۷,?/.xQAڲ C{ < ڞ{5cQ[o~;MO§6 a/SmP+]v_^}iwOY\zm/#;֖'zw2xm8b 呜2!l俖FOs?D*DeIUJhc.=ԑO!Pu0bƟ;ll |Tl+ˮ/08knJx}@g, *C !N&f笍0L?,kT7(ʾGk??F9h:Žl `vl:+ͳG" =6  %թf(ꛞLrlYi͈#_'h-6W 0}31u3+޻FobǍŎO/BƺG&%lDbg&mZ:cGЃ?UV.'z_f|8ZK^go!&9G}/)}z1>{-iI֓/j?fuEs9oҵG?PK~O4>cs%xq"it'_o]ӷ6 ^osRi=4?|ܱG˛jrԟ8y>b*G_y `OW>u{~/]' _e2dG1qոGЃMzow%-O?*M#0ge 0e/__eDm_\8i;3qqm4Gwa$Պ5L-9"(4饩=s9\C#_ @CajgL&?E&p I'9.w05ؾCom}F qP=TYG93 D ʬ <#s̓}֕-/3O=)]X4VxM.}E:w, ._}i >6YF蹖 {3嗧<أ 0>?O?Om_%'&N|^~LnɎ_J+id= s\5-G蟊thEsaaIwaN=.nϾh~֓OXtMfϞ-_Vb7'[N>m?+˯ ^uyFn _Ё޲*+\,ʫ܄A>{6h#wXlÎ6ꫯ&o3}T_§&?Fq2#+-oK-X` "g/2-^*hAvt}{SkIpBW/}fcۣ`?D]{_zvo1UƏNFs,lUgCI?6 +=xzgi_{U|AW1UVYYve͵ה3fIDwb1[>U3le_fm*W[ES^|Q~1S-w w+(gK Q~*ޜfr+tMo͙'|Wƍ{Z~12n:*P:Ѷ*@4YoQOA?GC/1`a_?,3q0?U&y?8B4E$e ' ?_?'J?8𠱶)C1.sG5=٧r\7, DW ܼ쬓DwivcZ!]Qӕw)'3g=?!.1/( m:Czï'BNy$CKޞ8}00@+!/]BEZ'3g=AԿBO%T%oOp:Czփ@+!/]BEZ'3g=m8h nвֱ8>$E j@kemS|S%C: X`yt2%(m3o[M0?Xyid0$\L]OdC!+FzS&0Q<4<׿;G:wd2QuՅ T=W}d9S#W>2o9;>unv-鿾篋ι2?,%+/<G{x~{9'mwηeNwQGN~j t.(~ҹSpiC:Hf}޽\ hkf͒mm={yh_vY:oB#;$ ~ð3ϔ7PL|ZGs|q睍"]|t18oWnwmb1=6_|ZSQ.t;k,z1I`AύF%waNT_Kuwq  Au e]LU3g'}&tW  =P.r3}W?Кs~N?DбCXKG ?=_ơ6x:L:vd?62{_2|_dT=/sV__+d$G}4ca?=K<zb&1PEO/%/4ͺ Zj)5GC B 1-jh/<#6r0bi"g$`5o4 .v#\7o?8Oο`'ߘcY׺ Y SBtzqgrlL'pJZ4ڝ(墸'?(Ų\dL %GC^GUK^X Ɤ'ڟI#&.XVu뎌ex\h??@r p'*nݑ,UnUFS(wif㉵%:#A]cn-HF WS8=]DYjضw+1~g,|Z(cyx=.eXW^uS&M'i)S4zt_e甗^Ms]J2vetC~H{];|񝘲]GcQLsޘ:U,A J_? h?vkdP1iu]6N;$G}gyX".-SdmZO+E ӧOEj=Xtan@ ǹ9_6|s<8iSN8QqG5qv1e-'?%c9P`x_>;^ZBŕV3N?+餋|,/`&S^~e(2>bO',#2;@ >`?wiC vZp>X :Ŏm}_.6~mщ$QWN]pthc&N +, :AXp§x0ߩkDքb ]bުuwKlzkcϽL 3V9s2}9w<+d'vv[ӄ Q*[<,!={Q~#"_qnrЃ_ vEЃ ϿЃk6An[ak;M7N_P?Jl ~'2E(42L b[]H[Ֆ4w/Ɵ?O0gw ; 㥍>QT-LJׂ(Bv|AYSX@s]nBJqceʋS-]v:ۢ1ʫ=ה'`1C)hjܒ׿}`SBom5E_zin5ЁǢk?Hº5lpY_?5Oo?&C"_r}%Wn_IlF~=ݔwv|Na'%|nx9͟M2x`)g뚰 9߰k~[ay{|c[ [ՂNo*Zv=w˝w܁o첳q&'0}d+cag> :k )*oS(??Ѕp+Pe Sj jůp#uj'z DOShSȠimC-& AU'R'چZL".|4@,|0ےj.9V,Y~ɪP[͑ Џ0dyqȿwᄇV[ܟzj,v$dZywmit?k2i$93L bO/o;>a7aeX}ew9찯˼ty3hb_.d/<$쯻K]-eGM7^Tg@IDATg-=<A.]ȭ!M;yFN-h=|tMu_ye9 ;L͝ |#a /DgUcM|ϯOy eEd+N_aA.ȺvB}!Х/C3+?X7<.D'?1S7v/ ,~nЗ,d?x:cv]XI^^2WU##bI/_5#1`j:̿2aoԿa?yvV+N3g?0.R] 5r?!W3(CwEN)t?cͼ`ZfvϤ@ ovh_fƫVIQpɟAjl `9C_gU!w[Req+ątKPisVV%6j>BpQP#$ (WQ|_ T0u]']3h0˃ .JEs[خѣ'v"*ݺhϿΙ+]*;f]%L.?ޒpI;=;r7#v0P=Ahf M2lۿ[0_ԝ~p,+[l![n\sMYC9pO'?;fCߑG§;{6-P~%؝H;Mg>J}SggY|_^~e[f/- nX~ȵ5Kzowi40<*A-v|I&O,gzjjWn?;>Ev[CwtzLtxwo֒II?ߖ+{~zV >L^bphzKGb}rv|KQWdbK96z]x߿‚Hw|P߈a￞ Y+LZm2_ '6 O:vo1,_ I/Guc175 5U m_LHAPC(ƕ/E/40`NƟ?_rDalD: οC(]'FPWԓNO~FeTV|@ˬ2*e`FxeK20#_<2륌j/}yRFe z)Zfz_^fQY-3//^ʨޗY/eTV|@ˬ2*e`FxeK20#_<2륌j/}yRFe z)Zfz_^fQY-3//^ʨޗY/eTV|@ˬ2*e`FxeK20#_<2륌j/}yRFe z)Zfz_^fQY-3//^;>\Z0ŝ8qN5OË^~5l3ю(l&.i,}ŎOe2O,J|+ء,hw| /`YBAi\ Uu ٳgAQ;߄2`C^ _jo)إ#ؤv^ FvCRg촤4vLٌ7cg44P8<أh+߁E:vnl޲e1ެy![ez' ۃcO?j,1,/c'?>5 YEt}: ^]vig#W䟉oA?w9wv|e/we'ndпRq+>ݫ;>`k8_۲'|R.neE~ڏqU뭸Mnƥ|R>O&۱IngWq{K|2s(Z+Te;9,.k*yW&mqkΟ@bӨG3Uz{#Oѕu vZ;Pϝ3[^\sa.© sm{m_"ۊ\ݖArw9!Jh#',*Dh΅Ħ:(k1|֘d?95_*A%ī. э.0|֘POyԣNuZg L@U`?EYZZE2$0IMSFt>kL`)\QJE:($`rɄ ŵ?]Gy%|1ll $UA!ᮔ M&S-|_';|f;?/J:!Mh>arE/"޷R,Z,>,- `Cq;'t S]ZU=,7X\O ޝ.+bW"݁e…H4ݮsOfܹأF9`(@F]}ՕZm/.D?ur҉'&:TkO\xd6-asʩɺ}Y`Q13x łi}A,r7H.]M2kI,\i/{N9 ; vO"Guywv~c0OG4x;l#:n ϏW_jR_'Oc8d^ׅO/JW3u?2yOz8_/ NF78tOR߆ VltWCZ4ed7L>848FրoQ>5ɃW_oIn;9 WBLxO>[Щ&*޽zˈ~ Vu7v0n h}&캶?v_V0:bdp0s=]?}a???C\ԃ!:aQoSo/?8pc# ]?_?1QJ!m8PM0/?cO?9$0!8`ۢI?8ο^?\Ge@B&aS >a sDdē_ॢ2/9E;)D} |8u [T{as 5N{2ai6Ed3Qw *GnS!>ǒe[A$r[ ׌.bq%m"Bӧ/v|dtIeء քO_q &N$gq:V8zEߐv `|I4wlWd 60tpyi;ﲫyQv7$ pqD[dndN8^o6, [^@24ɯ~KګC񬽟rm? I~_ `Oov+o{Gir&>Փ;db1l9 >>{/$|e:l>_ da\#߻2h&s>FߣGsvdG+׻O/?<>/| 6IV0Y~{'ZkwHO3e`ǧce[ڭ*waX/oEV춢nMG~xxUO:dnmMr-7s}`{~P3AupŕX &vkKwWk--Wb$[ <^xlr "S3'oZZKFԊΒ_x>3P6L/@,|R7?>\r˭ސҐ%WK@BƩ`?_/#ڿ9peK p03 7G}^`Q1Ncm?8?8/?9Fhl1̿DE``%E?hN|$,^zJ}vVO:,T q2tz Rj_j_OP }jQ@Y\ԠWTn!\ 1*T#RU/{OSJVWh 'hBWLt?5DKK[*y^WoQ>u@'Hݴv ]ȧ$O%Ƣ1rRǝϵֲ,*Ϻ}!4,`QT–oJdWI/d˭>!(faBywߙ.|0kW]%kL0Q5 l'?*L!?P 6\o<{nygXd#fo~{^Nud}Lÿv̝}x6y6tie95߿ ǒ0Z#Hgw?8?ߌ oH08:^/ο8+s +bO?97O2/?ÄҎO>ziZU@7 t|86G7Dvi *UpurS?ڟ:/d%9B\iQ????0rmJ.7\E?oYX]Ftsꌮi2LQ4 Z "JZ!P)OL=drwɚEEk5$[˺}$>\/aר 7;ziԿkUNOj+Fz=;y0 /gwӼXHԹۜJW,PҶo ;><ڗH?,|zPv/ӵח,b{ۤIOmO3rX}i睬O=,|Bws>O˩iWi6]^{Zݟȑҧ̗θO?^{<+eתkGCfy=P]Gx|3riBY}*TwwzWg³W?3W آ;G۔3䈯+Wտ?p :}X}٢nw\w ~>{K&]@d_e>vqߞX,ӈ'`BJ7#ܮB%[o_;Y7B}o#n+o@---gevzL<%)}}JWAS*13A\=D?kE?ْ)B0(///:b01c 39@Pɿ3O?0b&!`3=߿hjСp p /||ŎOaHoᰠŐM1, Ӗ!-_ND?pC,ye W68 ֒קNXw,3߰g2`em,`2%<?l2g?Y{2蹦lحh2y$,CWm>vrYL[8oqh~dA'MX hvoXmŕdkmM{sZ6-OlᆲRwz՗e ='_`?YZ㿎p'?X# 0GQ"_^lOs?_濘cs?1&OYG?o#0Gc_X; Cўذч:Ak*4'A AmULRJi"0dz<Nj3!zP%djTyR{YMsbDbkSJ5IԿ$ Vy`J:U^PӜNKPQjSJ5IԿ$ 2mnMc[$FV햝bXWv-N^ q&;Q #LdB1iͨ./ߐZQ4Oa-.O(X0%!*) d8 >CeGο8,ZR8O?1V0+-noοC"81uGns|/aP/K+aE"ZRa_@cͷ7:D8+%agdwOsEt9K[1I { -|tZpJ"S?41_nG)`Kjg?jsGi9nruqhUlS>/#A䫛Ku^6PZG?po $~0S6?= zUWh1?sB?82`FG:/?9f>3̿Bn Dpa'Uwe_ :Yܠ#F~XqB_a AQ|̮W"R*pϴGo"PkJR_2hηa=9 ْw+ E O0a=/*7SԿ`i?:/ǟ (92`4g& j>.8lJÊDtGIQ0`C/Ɵj % _:,PƟ1b6UGaQ=L"݊O2d/ՄpDG/'r10 %&?xL"* ߌ?.wi?Z,%8ʨXs}C7{JN[FŚ#tToYk:mk҉SJsfeT9K'Nehf/+ͱfӖQH/84j֚N[FŚ#tToYk:mk҉SJsfeT9K'Nehf/+ͱfӖQH/84j֚N[FŚ#tToYk:mk҉SJsfeT9K'Nehf/+ͱfӖQH/84j֚N[FŚ#tToYk:mk҉SJsfeT9K'Nehf/+ͱfӖQH/84j֚N[FŚ#tToYk:mk҉SJsfeT9K'Nehf/+ͱfӖQH/84j֚N[FŚ#tToYk:mk҉SJsfcǧBN{R^ׄN $II`JzD00mF?>;ȟ +2xtWcG8h2/?9cI=D/?1cjaW_e/3r~~~'~'~rJ2'cLIi'R'Z ~A_- r HֶT1E=AxYWIcږ*'/s84&mbz3Ƅ-ULQO^ +p iLXR9eg^ $ k[ V@Ҙ) r ϼHֶT1E=Ax31amKS䀗y54&mbz2gXIcږ*'/+4V>GF~8N͸&6RS'6:!G}\49i+Wh+p/ QO08o?8/?uH\*kRP*` !+=?XL"ʂ' ~U ?2t̨p'ߜs 6̿'<;6ȲOZSR@ ֔eUek1<2gS8 ʟG,E$%o78@%<-ZV/ƿ9r5X\;pfvRWۛ)\v٪u4u t}*8bTsZj#_4A/_:27OοYcL9_4jP)TCk1 ?2>GȀ?WXhxG~W})$O̿/dY6K9m>J8l@5OӄW؎Or$*)OZ0es(TI@N)  S%e:5t^&R'H2PjNԜzH !@9UP&SsJe"u(TI@N)  S%e:5t^&R'H2PjNԜzH !@9UP&SsJe"u(TI@N)  S%e:5t^&R'H2PjNԜzH !@9UP&SsJe"u(TI@N)  S%e:5t^&R'H2PjNԜzH !@9UP&SsJe"u(TI@N)  S%e:5t^&R'H2PjNԜzH !@9UP&SsJe"u(TI@N)  S%e:5t^&R'H2PjN'Z@>1@FWm4 (-4h"O6"2 EOSh?q!O6FFCi1BX@9Vl%U<.l'OƟ?2Ա"?12%Jcd+ %T3b'OƟ?uplrɇb2r0,"Jc ̶2d'O3#\i!0ƟsOzptwj?xLT*J4e{OW, (2'\ViJ8ojAz7'ʿJ%޷`sHvhBot6 #aF_r+sz_| #BSh?? N7ȁ_؇%w"B/Ɵ9W_`柘coLdǐWIgL ,#̿_>e9xl(+hRan(ңH@IDAT!G?{??Pf?O\3?o\xf+Ϥ3+А??_/pF+?_/cdK?-YOeרI ˄#rt\x _ kHi&hNssxTx+]yF1 CtYQ~ί@?2$TTO f'Q L{A |]M<|?Ox?ǯ^?B//zۜ׵#3n_!??*,ş'E_?m?2ʱ?o|͟?1? ßW_W>0$Q;r=>Etj"@T62Ȼ#e"L\j$ְoĢžq1GBA(HmӽEL\j$pt096ھ{ `sHͭ"arl}7OA2q[Ehn=,e"P#!7ɱ<{XEFBnn G cy6@.&Fwtal. 5]$L"\&.5rsk8HmӽEL\j$pt096ھ{ `sHͭ"arl}7OA2q[Ehn=,e"P#!7ɱ<{XEFBnn G cy6@.&Fwtal. 5]$L"\&.5rsk8HmӽEL\j$pt096ھ{ `sHͭ"arl}7OA2qz|nd'x0WlDڤg4Ʉ:(9]ϫ?b dQאF$RF?~4t j7)ğ?5ş?'ϟFM6wxo`’F$?OG'şϟ()+Zjo͟?Wqz|F' 5z)3 . :w'M3V` L kAƥ X+,߈!Ͱ8i@ӟ;g,#n`JyA.ddzr&BN?@0_x-iQqfNw/'W @@Fa4P%Me '] Cxi^R qKcv8U75G |z O~"X<ׯ?k?To% #k{??۟?39??鑪?76e ^ O8OGo_y3OStB";<|i&;5輻Ep,n`L =CР7"?ǯ?~u OQŁ(гo~^X։Z6!<ɿ.2kZJO:G9<8k3ad)/y~_*?G'`.xϟ?,y1Y8/sϟ? anM?oџ?,P` ݟwq`N^+1dx7#3Y1rv-s@N;@)a,nfv"4hyR|6d&{7)nz6A;/p19"-¼av"4hye{<ِ}Lw⦇0`;47xOӤa8 N;<l?O͟7,EQUV9oJ͟?WJ D?)te@o S+՟g2"eqd/*Q+Y>ɾ8RdzTN ",S2- G!n#gb@_a1tDfV@(x S2xSZ̥04\|X$臧?_49(._ͧ62xF?_Q㴴=|`?KLrQTBx7?ׯ/_q]:,2i$9~>Oo!UUs uP!d߾}+ׯ?a?d|Dj@]FH2c̈́umfY.P[Oϟ~#3O]~RA#L##s[ᅮXg4M}vF7KڅIݺuѭiO2k[T Au_J%;Q^+qvʕS:tI{m;w!0'ڶV4Y`!pzo p][m N;FN右C8? ߯~9?炗?ߙ9򗗿/6Rx|2i)/=t;SlNM} LHf)lHt$=Ռ'zXH3y3 M?`JĤ 3G?ĝT)T'Uʄ1iD'Ǫ|,/j,cON3 'DEəd"@% $>=|#@ JjK91[7o2qj^f*eI҉#wNɌ?=8< ٮTɗ7P#Ge/R4kBuJ2jH GI3j>w&&,[Tm )_<ݳasif#$pN^˫@ҾCG) ܐK>&6oW>#'/ ő~去lYҾ]{ٻg fgԩ+ 6>\\:uxF׿B)|pP֭_8$ ^R~(,^X9sC>(VJ'dQ%J琝;vm0Y)*]řm;SKRd$޻glپM>|=S̿"ɟ WP 8W] ^KvkUǥ:`]h'dŊ.ԯ'7qojφK0"嘲!:urQdLkx?C_{l٬3eҤ 5<)/W0PoV?Sۙ+Ys)-[=yI6Ý`1uWac$K'i.y|y X?g<{oy;\ @vOqGz@K^l`_==ן G(n287d\aB\\ÂLWjK&D}'oM/!==L͛?ǯ`^!. qɿ]KI` dLc>ҹ FQBU%`csw*g EJ?Yw^a(_,y%Jy?,+W-71ZP`P :OxQS_)hL2-ř mn5&Ֆ۶y~z> VR[oDd+˥s'+gp8h.[FfC(g"W @w\&Qç.ӤSl7_ !l#yniSOٲeP!B,|B:?eO'O!ٲd25daM9=n֮M6n(;Bzμ4 {Sǟ aKYΝ'DI[O aaؽj*?%K_&[3fȔSGySHaye(z O&feW(?4O`dr W*|7ð'ɶ0|Zc Ozy&.ż?q3%{f3m$?O0_ qZf12z߲X h_7dkHdpA֌?l]9A'{Ƃ.tjrޜ=cA[}:DG9oNɞ>Z7'dXeN-QΛtg,hO( :3u٧SKt ںө%:ysNm]9A'{Ƃ.tjrޜ=cA[}:DG9oNɞ>Z7'dXeN-QΛtg,hO( :3u٧SKt ںө%:ysNm]9A'{Ƃ.tjrޜ=cA[}:DG9oNɞ>Z7'dXeN-QΛtg,hO( :3u٧S'_DG7N  8 do}*.( 1(ms9(|O/ڴr% [&ر_fށ=vT)&%J Ok׮ d+8x$IPln泝ʖ)+i y) ?Ul f\-iD_3SM3='G9IǷA}_s$畂IzAX2H3_;~ !38+-bN,\ w%IE' +OmE:u?iaeҭ -mF(DCa~'c[or [ΙDiCR_t 7kͿ> ws[O5k+fƘ׬Y-S)^z_%!`Cx__?db.f)^zZ?DO[`}siWw ?DмaB3nֿ0ǧ3 4A]?)Kh"Wz|8mz|XSFǧCOAǙM`l| eK7Zccp<Y,X#}H]Cn<ӟDB2 G?6\WN@?~_]/<&_緝?~=% ~v ?Ͱ1|JˈsʼnTw`ͨ]lTF'/r`<̱uQ8q;a0 x)>9N|Vt*O<{핇6eS]" /9 shi5lK+T~('ܶm<ޢ9 B h ܸp gȱ Ӄ;vLgR\9PyeVEJﳆOȿJΝX2lv2V>8r a8ˆMKdIǧ㧍F'TO4|S_Ŀ1|2/ܕo_dHuߩt@çӅOS!y5>=ԁK.Lz`ݖ[O )驌? b/vř8N,UFx$T˯ r3d" x$>5]IOjމ&ʬ0\:Zӹ2ʱ>>aOζl8M+|m,n+ǁ?ȏ 'z|ڀY[ϴipߓx3?0 EJgX_ׯ~믗?_gx/FP}V>FO#$T)g^n '#m>1A7ـBӟN3`ٰ}ٔp6x?so@LY<٧)n7lszoRKGqH C:-M̄L2A&KRx!h*(~Y4>rDJJK5D *~TLمrP/%<0:pܱS+_@;WnFV|\0}}駌eo{裂ʕHMՔ,UB'GukEw8AZV6+[P$)\T~_a~SkN:)\sٳOV^%s~|+RzS* n۶U@EQͷ"W]ud˖M6lZ/ޜt+j oAj;iYehoMNI';K* hѢs.YlwB;u6WjM?!c0&9rdj^+THއ:C -iJZٱ};xlϕ? I]oȕ c6^]w)U] G0YTAYreP*}GuI0`w<ǟmT vzW(/ ?[m.$>,OK/l ! wnOP<{F  +<{19ZJ[lQT Tߥ?%x=#5Xw_TDru!ٽg/{w5^+hPyÆu޻呂_ tsmDXG> 8Ff]C'^#Y.T\WZ G{?u ibc.>qzu꫅DYdwXs] Л'<( v?qhM<-5o8˵%~Œ?Ȝ~1_xY M6*O O8f΁80k!\qU5$1 ڿW{]_bw܉"jٵk,[m3fΝ;P 7i9)8W ~'oL>E^ϊ mWtK ~!%c>|CxH{lwJ. CO$7+POSy҆ !٦?!w<8r͵\-BVikWoUEs/rsr璃H/”u8d;s?M憬K|'߰n;.XL_O04#XWF?ThVÐʐ*Ub)U\~piѢT>k7ߐ OY0h-ڵkد9M \k~jդfGɑ#lܸ^CE'sx=(L >=JM{أSPFL|yj'րvc-rY0ء"W^y7loyri&;e"eZh';\ e'by{טcC*{coPOUl|x[fPdoؠpjVRUa%|͞܌{'L`ŷS ؓr<'aX]v ?/WBmkrŕWI zkN$M#+^}륗_!40Դ2A5Ja9 ΃ȃk?:-8/'`OٍeK3쩫V çb<>Qn8;q?p:78='S?C2xOߺmg^?翞*a?/= ~GUJ<Eǔ?ߺm[bAiC%JaÆx0 : ]rC2H{_?TRo]Ux t.0YnSŝ#^veh,R70Ä@mAZT(q%%Sg_t)ջ*!*}&`Lߓq0r?TY2g __{nAL ?{ (ٳ琞{CIEcxyWO(`֊Wsȗ*C41&ؤqSG*V~͛=&AsS])?ltA 3Lo  `ThafC{y(ṼP:34`9i4IB8r >[5{8߮c|< ||FCcTf,#F,E/jjRǏ'>Z_w '5Qa7_6Q1YֿRwj^ /3g ^0:`~mkhv dsegz0}q?o%`7(*sfrT~{V֪Mk( -D9y8(86mgS(u/Y^:Bh2ʝlʵoִ'@e,ߴ)`c`%kwɃ~Gx-RbΝM;b2dԌgڴ2c SΙ~ԅCӋRf|qRzZo+WoIs.G=Ç~T ض5koLs`riPoPO>*P(]O0z䡇?Ţ){ tbօ8 _~u]\~Rw<h]D~٥'D t_ܧ3k.:}N()b#e_= i{(/'/{ޔP3x'5!'n{t.oHQ=㮾?0'B#)+XxEO>atCA}ࡪf/Csd֤@k\j-[FH0z F Mǂ 4m k22CݳWo)_b/Yrc6u^D (imn] ?00܈^b)uȴ@P__ H?1i c}I[M^Wgp$ `(KK1 V\%jԾա.cSNe͒ ˱p",lʹϞ3Ft@&k3=VCXx=ԁhOV[x)6E}gG\{1v%_n=iШrxqM鿅4|…߫GŝڷgU(??d苺$ \w*BG=h/cgd- bv)WwJ}F-ψkny{ZG (KfT 3=ՈxСRt Ax F`ܿKs~FYe~GC0`lvhҤ &s.@i +ӝ l~lt?(8:z4Q#c!? te?Fr4VT8`Oh7 I?l=ާ-nK]`hFuY yۻj ɋfL6 A<'O,3ߚgkf< Sa:+. b?'qtSMB|<fp?_F08B&-_m8ARwAE.?AA!IП_@R"i(/D?DeGzذq6(*Ec0ǟǎ+0!m۶'z1UI3ިڵkdrUJe%gΜ]^Ӱ*ukVʺu( @IOƼS#6| /EVzث_ N|-( w.s(]q_A _3*zjH,]s\(_Η^=ߎ?#䋬3`(1 __bJJP xi#Ab!(׎;VYJڵk=*8чjYs4fP0$ǵB)aw1V.Z+#-}?ԓ;ZwK,S·^S ]a@ATl:Y_MiZ'AU.P"1̟MD.^:B<̆!@ɾ\ixmXT Tz{P*3N;{A (}OolݺYADMdgN:ҰQcM K 9sd m߱MV`:|kpI)QƍI;T.P?fl6G%^L] ; ą?a|p ޷ցgn >OG(W@̀CU6]Gh$C( }.2gNO0KI.] F i<^+i5| zx܎?27Պ#e=qd^Z/=XoW61?+/#'ȓ0>~mŲT.>АM. /&}aG?=R7=~Kõ}կ^:tlmb =]-K6P8aI`'M Ɛ{0W΍[{1LK@çƝO<0{W2)kuǎBX0LCZ ж_~Ezp%dwN_ :Z2D/ȉ@Y 뀟u|H9 çY!8@x oF3iqR@A9&`<>1V(C/8Fg_?O|ZF; P5~k&Ak: :ȡaz`\ az9KBK`;? !پor~DiAG)?L)ћIE3j'уg؋! h|{1 ؋p X,kS%˅}u`DF[?ф 7YƩ+Tލ}+YDgew>7=YHo^xs*PLހYυ^(πsYuV /RA=ɲ}6iެ9oM֫wZri~Y)˙(_E{!s_s@9 fΞMFsԻ%\ώZ2&n3^F1^g^rE+c0(Z`֮G0^@ˬa愐,5=N57/z?P`\qfUT&j8,ACEz|kTI=?|^ w.!Upб,DWcͅ qӛ$  ҟVׅV{k+̖=B)+QOZdMR&;=^ZUQ \o0'O!ct߽; `)?z",?VXt[$x|x:)?߸q[鱋Ǻte_Ӄ$nn6s-( < ӟX7gʿ!^<U_ynE?"'NG'n~KLx+ (h g?XQQWɌo*WQ GRRD1=z"s'&bDyeA}O41E}~_Ԭr_R71WD3>|~KOb >ާn$( _MPOWO7qlr2` cwR~Z1 1 PaGB?˰&Mʽ+"-[{M6]wΝ:.x*yHaZJ @ћsTKP.SdE&f_b%y /?KgA8#:?SɂT/kR$"o[9JoE믿j~ šʋs|q T*T' ->}xkO$Sɑ#'<> UGcBԯ_͗~|e.<(^L8&>}{e˖j*I79^~wIF_}u(AWG0qㇿg0|5+I&N$G!,>ꕑ{ 5k97 kKE`{q]x}<=?M+BuP8@GuPFS@9_ˆA>y1耯_SZ3r9e 4UoYBr!{tVZ7B]| xEӘ:Fh{ǿ&ahꂶ/9^xAFX FHbEPFsOr%#Oky_/FOçrw0eJ 5r·)j/T:JC5\l?Ǔ?LO2N OSo,'VgC!VLEǡ"NjtO x`=;m_C`4PF=M5#Ӭ_z *^c-׸IxR> RŸJa(ڹC_ V/8B@הEպrct{]y}x5p". /Vt*kf꬀!#ĀmlFc07{(eZx_Z CW>`ſ?Sx,t:goye+A'чT}[DOVT<>PH^~U J?aMq4ExU qO?-^z©f4z[1"tzB95|G?;lߪ+a xDLfG-ѭ~Iz/կGO?I,=VEÙ,c_S =& abVA-k|p#_̕;?Nw]0Y"O "PmzzׅT@Eka lZ{ވsj](%#M|ȂChO?=> Ie&aCoZO|x%|ik8u^:u@9Qܣ װG{; & T4^d!#10C{EDIxV~&zɨ&u7?ύ >2 \,x4 MZ7шSaOVӦtfPx00k ,FPç`ĮO0l <9h>o=Ƚ4HB4r$\Nt0B 5Bqi. ȃ\SmÏ؇{/1߻sUM␡_hY `)Vz΢ݟaL,tc/v؋#q̓, + >AjVɼ]jԬ)ZѺVZ%ڷ Oݳ`z|;\?UWſO}S#G&syG¬? Y4B=CR'L~w_?Y>i_L8.Hlw]_2"Rn o.J<=g;/RDļj)F矟~a|!`;#EZLD̫Ӹ8 n?nS P8FnH3ЩUUy pi5. 6S3_#x֏8R\? .1OX,.ٵk|/.?߿?]I 96n :+=7x0(6!eT/'&@y} @b TWE cg{BK9JҦ2eʀ'O$I3ǧ ah_?ʙ1OC`DkoR̿F\[qI[7`١ܷO;* Q(=PeajW_P(F 2_yĉUe?zŸ|a(W_b!o۴c7ǧ[kݦz^?yf 1XŠA:[.S@Kx(W(ѓĺu_rml< |)VxebC65ޱ,w~Tkկwϧylg'OUǠ۠1FJfoE[18njwߨWȹP|;W~ǡaGIk1A~xxiS2=~ey|Zj A\lB cSG5!eΜI&@Iƍl`7K+i`ܸ"ᚯcN@Qgk) p]x|?@Q;Joꕪ0] JӧM wm <<kw'\9yH˗o(!uZVn6LJND^N"I0, xw2n?)l Nh:M8/riK㏔{Eji O"\I `r7ʓFޣQWק<>UT(>EխEy>-Ya0xK/b=oP!) '?ˉeʨGUT>ϕy;/;`Weji;GӦMrjOaC[*ju[CcXs(0FˣM@>?s0b#ճw_|i1 >#{vv aX}8MwoJZwlߝZpg?ka?QiBk i *yDLQrsЀ5|R 4tmAn ӫoԫ':kO.lNG-ipމXF#iC.KZ)֚RxJz$Ol$/ 'sGi2>CoO@ʎնm;>a}}5 f<:8D̙l21:>-]Lp@\oA1M0փ 0!w=s$W^yt]>&1e- + {1_Z .(ǎ#*bO/?UvLҢ?~Xcཏmk5t iSbiWG4WGyF<J >B fVhQi*N6=;S1V Ry*1ì2y =+_2d QGbbY@4QoGkԋXPq6#xS)VwGo vD|7^粠]0C!ʕEš4p0_LèkҴUڅnwe5._҃_/y,^9X '+Yr DCO|I[b[:hN&7Cׄȍ0w)X Ɖ}0I{Yӟv68X⾻aqPAJx_bE7oŪDdJ9 4%tsbB?@0[Pb i10!&Ĥ ޘƋuI[O?/xP6/׼Y_9voQL;ỚjBACLDF 맛.x0_@?_oh@+Vaz|mڥz.*V?ŷlފ֧˔)*x|O׿JN`媫0a^xYMd#,~y/'<*q|򱌦. ԽC\"PDҊ>ge46d0Sm"(5'@@JP@f6mZ ʆ2B5O >T*E݊zJdyJ_.řɮL|pA|ź$dւ;38uT "`UK./RÐ,U_'alM~W#wt|}>p /Eש-'uy6=P\" 9OӋ稜r+<眣F|qct5} [ %)X(>e͜M /MJC;vh1 EAK6mvڭ-|MC̽k8LB3fH iȞ|RKz;?_60wAag;Onyc%ҵS('X#Pv7^EY*rӣhcd?Io:ʡըa~U}<z7S7ބU|f^`īÓmeU(SJ>ymիW/w7|CA<гEW+ OI"lm[gaTs~s=40뙠_z 8E2c4x{#ZFOo^r|pN<`юdTy͍'@z@xߦfܦ%E<>cPj77փc`B5d ʕ7IV#L(@LYU> Lㅬ'*g͒MV._& Ǽ6^w j/P';72}9(sf.T=ſ1MX i}G=g&OݯZv-g Xb7_> ]cc'N;vRG;Rx m[{ρ?e:2 ^Xe#{50xLXg Fcǧn;IoafDσ;~8mnq2cG. ǧd5|Zji!R 2&q:_zھu |LjFj8E?JdV`rC=\s0i>6q~5Nz@67s2"xO%=0OA;ah4Ӊs$_K?aOfEĖM7^&aĮDcg@ ϕ3ԼP*@~ɶmVd$O&.3~8(,VI ]Y(+PKʖ- ? $\S}ʹP*bLb9(cCi?edI3/dFŸ;g*oDElgf(6wٲf(S*WTIyqpCA}l=as1Nڥ,rzO(X\:Ay*OU+3Ak>DVBa7/ Agun͛ c#?1R8ѥcgYl/]B { e,24P?p呣p"jT֠nnQRKsxywB{ |!D o.テr[Tet("9|FZCx[?IYo͒a`'L |wƧQ0o/ܛ1Lo͹ t?1ƙٱ}e6xD#ֿ$ Y =-3U8OxZ.Qexj !;_v[T꿋v9PNTOhrK.0?x*?Up1s& {MVOѻd5T[jvpzv/"{mbm3s]_AӇ1 r}Or/Ho1JUViԲ cɎZ? =/@AɡCeE*/nj RBXz"4A2YwCho?,$>C8/ο9sŧ6f& `,Y*Ou)cA,|/GDo=BwEw@>+ vKb? dX8~uՀ_XmR}y ̇WCV9$˔ A?0PW8߻rAj ν+BB7h9+ `n? k'l޻VT)x_jq۷w<`cfڣr" aj۩=\;fΚ)P>0 l*\Hrʃ %E@sml;hD x\wozio!Z`=lVJ0:5$~™2x.D9iȐZw3"lddP($WGL"??{#ZM8`^ o8pE_Wo2aiuN je ;Znl0C0zi:ޫ3:Fף/?y!|dI#߶CG䃎0l~RH_B6v=oB+J=\Ez; DI0ěCP4p4"<(Xhdʹ Iz`;y"<>q_/[N^<udebo )?c<``7NyBE`_ya} ϊc$uW|ds FżTO5ۻ~˖+Tdn]{eX.=`P?ez'V\b'a, $9dPIraf5?ݺ+.\ןߑ𔗕poFҽ< zD#-ߴaJZ4S jָ L' rwhs~ atODl?O]y=o?snr5M~{F򴥿"ŋey\ۧԨYSZ{$7 7KclK7xa@x.{я?(]%Fj_n?o<2 w)5`h2_((53/sYIOK#•cL{22SaWȵK;xPPyr]U(XP b(EkMb+EDTP^]숊5T5+EAbE};{{xg9{w`Xzu F'8 7>!(|>C3faѿq=BA õU8_ ?=B҈eTB٘2 tBΗfΘ%wƮ{»֙?B/q2_jAq?{ohwn >k6LoX~sI0 4|Bݣ}ᡡƖ8r |=y?iN{d}*_Nǧ 1҈ csa(&21Oj?s$:y*{iȶ[ 'aqciBOWN|x> O?8lb^gC"_N6t/Vx~Ow |p:@cYz+G}t_h_2=yG[Q#!IWBk7m&م8^y@;VAlݤIW?0 Y[ K:igrkdqAdޑ a O_R%`L+:>x^yUDytOClXdıG<4߬MB\jZ ~xn4|Bw}8q<ȆǥųНp1l kA/G?]6)0z9F/M:sϻ@}ꅔo =hY"E5JN M<L؄7rC,O__xi] b._HGh_߿Ѱs“]tᦛka!nB 6]v93Uazuϝ"(_mO/RwØ :)B5Vc*4` q>`Ѣ7 Dm8V?둮A>h;3>IRS:פ O{Ӹx;5t;6 0B| !!5nG:qd.*w9V52H߫hl} =>}.j8 i?o 'tkѢGUh2 AݎG3?=(:g}&{#iv}w! $H:*O_ʖ$? n\gg_dR9_ ^6H9ozG6[6([(Mx m^_n&?lT1˪}7U?b*Up;q^2BvZJ P͢x^"iO10 OXϮP+K]ßR:oJ?\7b??96sKu"2kմt /26L1kٝ)?~_*9 (PLd}4"KvX*P&+}hI/17R0|—wAHFprwq~7% u~.ةe\G|y9z`A?xK?H6 3~]s=IsO=|U9A] 1w8C:>5s?LӁ3l зwx^{-7 hXup㏇x_hm.×Te&p|09SE0rf_c]2\ *J5Us$h5|⎇__/WZ}1{`@DC24S }:p@\UW^݊|o&'m[v^wӼ_alv.B/>SGw*_N]yr;.G#lm;oٝ 200=O{;Cݟu# d͗ S}  {?A\@Sa4%G0 {] V2Hqo>8lT@ _ZcEnkݡm CzGbX?l0 %~yd"Q#W/$8t X>N/q0'OzA;lأr7@?zx֜+anjoN#Ht[o&QV_4kn]iE}x'oQv훐QyJŗ^6H"~\u!/}Lr O tpg(p.^e<뮻]Vu}i&AY2 #acS\EiqU?}/h^ 25`h2w0vqci|uWO_yc w a)ݺU"{vZSg }ِA; c 껩BWK';3O25wFA AZ"JU8xAAgD-Rg.o7㠴ߦQ%_O'.ռk`[,?&mvǘw^Qo i2=i~и Ubcgwrjydr2{:o5O6.{ %/6GrȃBv0X><GrȃBv0X><GrfM׹PM'M.Sv}MdGA@!9U46B识O,"o~[qpo$gHaJ;>俇ޓZ3p-gbς) a Qr駟!{<|Ygz An^ZMܵ7$>W0;4vmYO! K@\=8,>Wk8 _0a;߉D%W9#FKE:=Ⱦ8'#?RM4Pg^ψjyWOa9麗7 #oĈ8h^1kwhC0xޅx9`7zd##-Z+id5k O0{o_rE^G'/I*רogƎ-x zkS{"znvN¥l< O|V{8c~7/q39^Pλx]^xy{}a.x'`އwM_S绠1^_c5M7  GM"8ztnӅ[_U7c!c߻l~cM/4R翔|3]'yxO08C!Ĩ |5ӆpKϬ'ム7ĸWʈ#FTf8#P-uq?w,=wֹu/, '˟G/r`lPtE'vxEsowCgJPo 8[3l$~px~+怢Aw_CB%mx_N8<@$}ɓ\ɟy8zýp{BAh ~{_ydval0|]{΢-NKY|>gGO0`?7]22H|U4o|O)KPU}Be?֥q>AGK:v1枃+p\_ =թ[Msw$ ^#|{ǧ݄=8=mW77a@?<ؿk#.^]0M~(Wͷ çƞ@U뮽ߏ xսFC 粒{Z&nր+z?%3x:|@:bN?`VF{,=NL>8b8HHa&)˩_pmY/2DxGb-jE*_! Fˆ[wמ 2/庳t<@ximQ Auܤp=z rWD4I a, {:q>qF+ BOި穬pQ[4]u#!xN{!/D%/~\d:R.OЁW+"ڰEȖ^.R: kxB?FɓS!"as ã+b*5ܽz@IDAT+[(I&Mu;kizK/>0 &p{A)q& ws̀8 +?5ks ށ "~^nv[}5d-sM0zzгyp7HX~??cf߂?llsFS5'ttȾP:ѼP[c; ! \0| AzSJ<~m./3AwL٬f o'?=!,ppdu0͵T+I{?> COTphoSܑa`J˜^z 䕾_y0N;7\^3¹?~A_Rk6:3߄1|&g-ʟ#pHo'x`U}4\҈1? 6S9kѼb 4RC8\a"r_0+?|M}B0|F6sOpx<x9{bnf.!JnǧP\]Co^h\RÕasg[xN@]b''@ΦO=Q_J4Z+x{^gș$x0`O0Z,+<`t u^ ˤ謳u7,s>iz(, yq7JF;}7;w{WóU jy}1 4ӓ&? w|5^{/|ݝcqt-rn 8I"Aw{kP iJp 6z;x5#4-7!M-葁z|'4~iϲH :)Q%O߽0RX#8B zrKon#nwʿr7nO'1g^pXatx;vL#6^?7>Pc1)M پ)^x=*x!s]%Կ聈2kxP>H_n0ܿ+yQI U ֟!kʔl^` i`wa0Fr9hl?c2yjo<':9xKIHT|>1cF_xR_!Ca0|{+pA\/Yn?i<ZI83]S;~4^)ixm*4|“pkٲmhk bX "x94]Ǟ0b-z^9r̀]()hg#\>^iwڕO߅5 2? Fc_r_rQ3/e?/ϥ#C C ;G4/IK. ПΞ={ow,zf^x]T't %U09}4H~F~;Ca̹GѠ] oS_g:>Zo/)c$=|{ICЛ0߰[W1|'QǺcg#B7 㿶 ;M>5̓O<³^ÕaFvaᓂ_|rc9lːY)u7ʛz{ӗ7`.l_pIr~'y1Pm Orsuvq׊:\sϛoIwi}~1p<\Iq\vhkx6۸}q8tuU<@7h 99/ĿCj\ N<>MOz@"A"r[/஼27F;tpg_U5^qU s7|Z%x|b͋%iO pXV.Tzx%x+U,m';yq`[_w_z'-7 4mS|Q}q Ӌ~< |~1;yݽ. ɕV\~Ͻ\;/a/ Zx^rkӦ [q% OCXaqp~;Ib}"; _g6$$w)dPȠE@QNKd=5^navD \Өqt6>8py> rhUVqW_=8at|bF=yx32&ӾǸ֑_,LxuϽAgp$06]?iupxw{r@Leihlw;^NUlD[a`y}ߟ0=48@"?חNitȑ[?U,1C6L~}Aߣfo+AC*ɟ{e9Nc½^{7‹܊8;ᭁ@HmCm%^{5UIOܫAÿ7_{s~mض5tV]U*xxF#4WC?'! 4)e=>ðaH7.~HlX@8J8l#9{rP4|RK&wr@s;/}wyuѝy_MS< tཁ>~9M|_<$ƚ_h{wЀ"n7 [^^tmv}r%;H a/A? hBNz64tKgŘZc.5s@E_}*U9ݱ0@yΎ`(qOu+zൂas>5/會qOAhԂx10x-[JLz-0.:p֎/۾|?>7 '>x ?j7r=bDg~^{9_@? u%#J?U`D#`>F(>4 CB`Y1H\N` A ӝh$/.<+6_@vlf{̐c%݉K9P?j4 .>?0ܕ5ǵh : ??pۭ?Hzy@Q@ BmiA+< =cE-;3{.xNJC<dr5},k7+>#&w7He__|>orT?:z@CTO0ǧ ~V-[O E+\"i4̼N m5p;>W(b_pW`u&7e<Q&~(*_*Qat"Q}<tiI>)HW^ヌON&z\vlSx< 爛 P7o)`޷sa}ssW*yDow|30}8q[c&b{Ɵ{})_'g9FP?&5byM4 ^!VAQh˭!NA)X3g?JꫮFȫ{.0 O! ?5!RT%iVP20%̺Thl5/qBƼa@S/(_??TZS2$g ϑSja щ#MY!&> XHITaY!*p }kX(ɤ4*l>+4SC/b !&Qgfj1Za8$$L 8@5,dRD6RhLJBJ35T-ְPIiU|VHi C_C2)M )Pc XBqH&ITaY!*p }kX(ɤ4*l>+4SC/b !&Qgfj1Za8$$L 8@5,dRD6RhLJBJ35T-ְPIiU|VHi C_C2)M )Pc XBqH&ITaY!*p }kX(ɤ4*l>+4SC/b !&Qgfj1Za8$$L 8@5,dRD6RhLJBJ35T-ְPIiUpZp& 3`s8HZn3 @1+D} Fh6,Bï>0^x(xeЃ~Wj@=gxZU^ *(CYנ nwzupxs|0Νz2 pG ]߶m[B;C@z0( rB}*? ޅ_o iuY \r(l- ~ OhԴigRˣ h$X>I=klÿ4wҞ4<|٠A}qw>O7RçjDy?qOT|yf0y cȯQc3׬o#q(TLx#GFO.*Ⳳ#Pz?|p(5x ЫI/k{_n0[01ؓc_cƌvg%?<,vwRC 1BS{e¡[> /Sg 6/ L|6 +ġ}&G >5FE_ @JكQW|~Olgn ͢jX"~O?IxǮ߉'ٳOɫmݶN i敧ԩSᱠ䪮B~AʚI=^xOxOԩ_9{OȆ4 oT9^ms; :@8.ͅf\^OmNb3 dG ba?_P<֣1^g ?zz #zux0G7rW^it)F? iu2FqQZ>H^ڭ)~ zO ȟԣ]wZOK4s?s, >ɀjxZw~boъ+0`që#0x`'> c%"Y* ~OWॿ{ ;aEҟ^vI|Vq6xv?a\e|(<?JRo]}JG>rr0A0ħIӭ>e[nN; ^ӛ޼zOnF44:8=')~қ/+p?x@Zao:7\cN? Lm$sbt@8qٝˏGJ"^L]pPELs>"u|;أ`??7X7KmJem -qW镾J+& [{z~eCŰyGSO)O) H\W|dwh8.lSc'6qς|Ok}!'!?<xܑq^_߮= ._b.!i~?ijCw 'J{p<G6O/z'f_ltMwϹ]<+r-Z3|^w 2|~ϰhT߃xZ}gݠ+A#v/^ZK.<05 II(,CG6)Dy*cXD6k; o[leu Whg4۪k ѿ1g?l]m/y>nƟ?h'UCu{?cO3|uQ ә'"-si]fsEЦbN1hU.yʀ%Ŝ,cѰkA*stiD ]ĨT,-)dӈ%X RcL#fJb2`iI1'KǘF4,exʀ%Ŝ,c0CW KK9Y:4a ,ÃT,-)dӈ XZR1 Kf2`iI1'KǘF4Е//u0\X>wO=¡풡6jN>"]%3O?]lӈͷr9[p饧M>7RYk[o cUᵂX_e {6|Joeg8+ſjP}6lun>a>ߧMh臋Đ$RJ׿1gwSN>u޼̜S5/z=g f}>7U` OMOכ? 9}|6N}1Ƞ ;r%__2qPd s=89g:h-Ș8 t|m0~0 o.:9B} "?Ü```xVbT| nG{)0~X`^notƌug NiHzۭ*<( 쀼oA×-"F/pAxPF^CxSS \Nx9^ |?/tY_/ڵggc[ <ǘo w_u^5dsLQ!0g3O?#ޠy:o;dW{5 羜q/o[W_){ԣ}B0|y4zid=Dkscp=}/Ge6=n7)ov:%7[l홧 xFƍWG`lZ?iM/NŖ{ũkŚ75X^!=A!Mτ8ӵXo>?T>n=vT{ ?!G]q HdJ+7 idB-O4P_&1uWHrB,m2kƟybSHm d?6hVJ d]sCdjH9A" Fىb+YhbDb*< `:)~hJC[RTy y^?/TRS\_cDb*t2cʟ60|ʿ:TulXPOɍt҃8˰c"<342ÿ&k ۴vk88!ƍgx!jm9~toZnM6qq8O>!q8d %mko=z!?C ;#dG`3 P4AN;A7z}0}L1³Zp'<]CwԭçiӦ9V[!ݗ^zOU+陠=E+#}GW^ŗ1jo|Yyn5Vw|/<? ]2a\0rȿڌ"ZkAk?kH_me`vq'7`\\װÏ_t`d17_z8 httq.w ^ ׶7=-rf[oIW_d2 ! ۨ=e'?tca \_`~w)K ;l9w}ɢGM?D+#~zUhv#^M;7}dcE=BJslE Qczn 1N P'd/OoV]oMS܄ǻ,i?r:g?5n6s6 &M n#>2G莛vvxV1]*i6\믿|2 >yEٛkA:M6[oy#k7 7b>L[exIjM#r˯|]$/a.WF?ze)^xM!6l^(!Ü03rWf[~=YZsϹ>>G*tpcq'RG. 궍?6lyMk7POf?6Õ6!bs׿Ƽ͏/E*|i&3zyoy˩-\5s6V_~i_?L!dK>m'~?x!fW忭~O=W5Ҵ//xAG*#%2o&&/RI 1DiJr3g_6F8/1i.=Rg?c倮L3?ΑߘwȦG<> cNbF>+I)0*@Gr1#y2)TFPH8&b$\&W1#DˤRjA f#☈+I)0*@Gr1#y2)TFPH8&b$\&W1#DˤRjA f#☈+I)0*@Gr1#y2)TFPH8&b$\&W1#DˤRjA f#☈Q0ugoe륞:tp/ϭOW>lW"O xr${; /߶M;&lKm_?LgOa??oxcZ8XE%K* n˧Bs $U硳:~v+Я4;p3ܝXBQ./jS&幇ƟlvͳLNք\?&ڔ=n?'fNޠ ޝ@'u i>S2>b IɎP,J  A70l\CL\{MZ4 O`$/YsHOdxgԃI븷zݝn˿ah)7_}{'sǑjOm+.e2‰nmҷСcGw[Gg6oϲ@5gߢ3g~[KI~_lle/[U^yuٮ*ɩΝ?Bpe@ B5u) mnj.FcDҔ7elEARRPK&p1#L1cGdB*r2j .FcDҔɟ_mZ^<G;q%/p$]~?e#NLJ( lks͚5s;^^мߟ3r(Wn=ow]w-Fiy);vO<e/-MLE*\v ѷ(5L2E!r-\O >d2?JHg8B?v0XO쑭o/HXov_m5CͿ^-O?m7?6lSh6o6ok߶d}5)[wczU㓇(OjzM0qV֢IJdf#z\RL4+g-i̗Vz!XiV1KjeH4+GD`?HaϸEbY22J#@a"HaqIJdd4+GD`?/e(iV1K?[k۾:6L72MxKճOc cAFi.@Fn=QeY U2qAWy|*6j2X1LhKSi%N6dd#AR>LC_5yZbgg_2Bb4Fx|ij>Ɵ5ڈ':WSr67zWwM9Z]A13n:(s'8o7x␱g/l5i t1'L[p>?wm|G?;$Q`?/b+Fd/'_oKcށǧx=E| f#X'F$Cd[+DB>Q̮ 2L " 2Y,xJ,.fkڇ=VAD|^5WlM0*(˰fZ*iXy,BK<_%5 P>/ÚRhb}cDeXX -|X\ִ{B kK%ٚazUQ(ab)Ubq1[>L " 2Y,xJ,.fkڇ=VAD|^5WlM0*(˰fZ*iXy,BK<_%5 P>/ÚRhb}cDeXX -|X\ִ{B kK%ٚazUQ(ab)Ubq1[>L " 2Y,xJ,.fkڇ=VAD|^5WlM0*(S U &T73(ߒ,;PP=!Py=3F]d`?Z# J%M~$,_l5/Dfjӿ[_,[ꃭm_PThO#nmof*߿bhhlJϒnb,鿿>ÕN+H<)@I^.??@*@IDAT4Ф[fA"!_ZhrOʌ FNN֐7+@&La6=)@In|R&k'?0͓uH[1B/.0K`n~6l`?G.' 6L\a韢f ]ȃ27[sllmKIw ~7~_1oWn`X~Yx6 9 WPiߌK ec$%im!F0M S op;/o3:iLCOKO2$Ӽ2{:e|1 BYKN2$Ӽ2t0Dc*З1# dHԧye`4T e/Icꡄ.şbD[1lZ3C$Yo7#'AI0ܒm^qqA1lZ3ClSD"#$!,MkfADb6o*O[2ǹi\*l{XfHeAxp_gkR)8_kNo_o6E_'&M.h(a؍9 _\HY@_&M> lcͿA@ 3k_ &7TI.?lbͿ" L8c!_y?b?QU/ӿLZhT"*?EE8Ik& ǧ(ec z+ɠmDm,'?(j8Q i/,ᤤ80e @F,V'6l+8R&E ^%DL2L,uN~A=)/e eōnO^u[ E>_'<`**R,өE?<ط_FԿm_[rޡlg?l RWޡaa韦(?-믩4,f OR*7_> d4'g `ÕkH1pD"<*f Bo7ˏ8DX艕l&L1H,Zt,-(͉Y@&~ 7l˺_n @|- O(^|uyN'ZIaŅ_ɖE^7g/x"ҿ/?m_Bm!,?L0? M0 ?DPi韦i'd韦`/up1 y?׸RRK ' \t8qX~#I y# DHX |77 q4jn&G0͛??&m )%Kmqg?wK: >w@`8 ƽpyR"A!,ܪ h}U+oL69CM8N`=lQ䟰A7<_?LHl4wi22oΫ`H[A_89?yOl \ 9LT/?M?lảz%Ogζ AQ yjz*G'!ot,'z9ЮTHt`UZږIC$DE- VYI*&ോj[&䳒TMkն4LZg%$.miJRI4]T0i%h^aJ>+I%vQmKä|VJ xږI+$DE- VYI*&ോj[&䳒TMkն4LZg%$.miJRI4]T0i%h^aJ>+I%vQmKä|VJ xږI+$DE- VYI*&ോj[&䳒TMkն4LZg%$.miJRI4]T0i%h^aҊfxbA ? pRgmүS$lZDO?b7gg̿&M5kXc?6c?8&_m_m_MF\ٯZ8%m_mͿ`B?+(Yc9__ p7s{|z1fcxMc4Fgc&+Mph2Y.IaƈtP+̨Dʔ2B81# _^fܑ -SZ&K%?)13FD>]!LH~R1f9?E${)-,ПO9lB"X Ta5s@&[ڞNC'f0?Ņ_~?pq񟧀?~v9R&څ<1C 5k/Wk6 \6.}m_mӿL2o[֟ g[z ֟?miO[.kϯ[OuwRXCd}4$ fW&3 wa ux d@!~ePGSiBqg^&bCULO*G/-moe۶N>2O 5+wfGNł iR^WM0 , 6Btqg ?޿Ɵ??g5k_&lllly o_m_mӿH?,t0s ?la[s5^16M~jJ:+z :$(b$|M6"wQfC\bg<.,#9RD?&t䄑!A%(L iݚ6"6l-iDvNIdf) q oU_2lx)? KxIFs|[_Ck-`| Z?o& Uk(M?pͿ6B4`F.ΈߦJ6 !1'yc_P_?6Bp<ke'%˴f*HT0?d?`[x`G/&"/y8D&[[MI"23!*Twq;_:'OJ spx.58pe8XTK*\/tiX )l?qJ2b4*??&uJGL鬓9Ȱ#l]GDX%MYaįpV'Ø2r6ة WX_u|u} [ǧ`q3Z\ &<L1cgQ&M6c?6`#Ϳ6k_e_i?0P)µ0e_e_-jkFnΫRBH5Bq~J|9sb8=Ӡ>-0g%%ٚaKi 5c23 Mj)L&MUDH \ƗjRWf>'ƛ8$X"?PBq_^BhRhf?7l" **,*2\\=:3*i?4pae>tF5e=gsݏ?sXͽqnvs/Ý7}5xf{퉡]n27mQ~O,o}T7b0i%kim;vrpƍW\p~/*āelg/.uUl0MPLDw6 ɢ@Ii$!3UnBi9!(qɷ`o-1Ch`1K N0b:j\ƍ"I/8^j='$}|O\ǞF}O%횬춃0l[f]_7$Oޒ)00_u?]֭$rэxy*Xqz^%2ÿo#Ֆ쳯k³u5owʡ4|R’ rh~擈 ¯r[}<~âEj.ݺz/yN>$U7] t0< vnvn_K.uk+Gu"ȓ|;c?#>u<8q!y@^ ^=zw&q4|X ̂l|_{h"|^AC#[ 8x:0ǿo9rSdyA#Uh|Y(B1F?/?ت[,6m3Ϲ?QMkB_e_e粪EGˉx5酽<1|J vBhi!6#յ,78TH0/"FGe$G ]~IR+zUt#XPPďuPOML"<豠])OnV뻷7ٽ<|[mܯ[7Y#k^{ ]k57dם߄3˱r'/|wVJ{{oTT"KG@t" *`JQ]T"-$'{IKē6d&Ir"Z,F"C./WzH*QǏRi)OTx8}x9>|X\ֿ.Tփ"=ZOs;amĚhנYi"<>ǧ 0|ŬU*P%寻jW'SF CCϰb8L;^цukiH2G裧xdOqqouυFtM5*۬) #1 ~SqgH[b߅8R0Z<-Z8g:'^-<^?'/`9Ns_`/H_b~u< 뙟PrܒR4s/p;eIy;3 qw?kom[>q=>BA!.:+F&Qui܎4 dT6HWwv@@&> Xc&̅OՆ6'$ SLdjt'6'$ SLdjt'6'$ SLdjt'̶@ʔN-[y̓dejX+/"@r* |||hyIrp¯q9T$[nu qj~52ԉ-EA ?}tpyh}Ukv =>MxOȏ%=(ը[O߻{vX^ fç;^㿔_&'>6|Nȡ@d>pSrlG 傷:VA mݴ֬%矅gӢ9/(~:<?G'w{}u__ם?˝??fn?_t3VxX ]G" x#K8^]5*8: ?Ҫ+W CdBRՈ$rp5[,O>`VtQ.çKXhW>B,?IKoNX ç<=)QƴةTy <-w 2o@U5 æ-/dd)juFmFk;EPhc ɺ'cJR-YFf${^O*+^X(ٻG#n27K&R8ϓeD?w%kc^MiSӵBBt\tIZu;|%>q Kϑ/p_!w$;ɚ~#GJ3FZ}0цxԺK7Y7+?6_/JwAWF9.]tbmُ-wEEܹC$ӠyKVAϖ0ۻmDzdC?-ϑ=;DբeR9g/\9}Dz#cLѿ7ve^`}xq`۶9 *lsPkQ|+)gÚ鏑_{MT*Td<;t~iIMDQ #ݛ|ɿֿJq_J|sw'?N0X3Ͽ?[s돯 uFc`0p_^KrÝ?CiFw_=1ӝ?q qq7:u\7\jvf,8;hgP3FpT=g88wGFyՈbgIsH@P< Q%hN0c>YROɟH@P< Q%hN.s+sq:=&?z@y*̫,ۑbY`Hxp dgK/:;jgJmĜRǁ6ԩh?r^ /'M=[ @Kn*Rr`?Y+d SZZ68(cQȒYxG}VIҲ˙`O@V*ZCĕw)Փ!7o]Jq(ܵ(^Я+/¦}薢?q./ JZ#ˆN!9x4{L~kKwU8Խ>+s˘WEoE2  a}z.x.7o>:p0+Tk?ҵy3:C-0@zsgJ*5zTA?_3~Z\hEӣGø!tDy=*XI(oB"JN1G+U~.^MEUh@<*^|WA(ԉROi*d/ 7#9۾m+僡?\4uhCw;oܘ4}p?t-doآ jK^-[Ǘ?[WrdgԊt~N40ҁ eK[Ʀ? Cn-yt+~;NY38a c"\腇[{Al0H6 %[G)DO߸~ytoBǽ&eΚb7jpSQnҙnX/agM׫0;X{suESTMx ADk:|2!T,&Λ4]FW0h'XC'~;Gh/ʫ ߎ?MX/1O9MmIgPZ(!_:f 7#EWKsƯJrjBĊJw܅A)A.]j,DO% 5#5tEB>m=l 6υ~ƟPah8h/~Askυ~ϭ?hz ӿNe!I֘$; q?v_Y#nzK'|C3B:4wp%nwsP߫Hi\ jHC{n~ BQ~Q rw֟uOV||ApKv([:yyĤy\~QoI]ۓ,-u?%rbqVV7~|^ʟO _lld#0[F W!%ϛ9u&x?*$ ]/>r ׬&cc~/O_z(9"i轕#ϓ9EջFpç=%ҦZi̇gv=xo"?IM=>nX'5Ɛ?1|m4 #%v6 cd<":0*7rxaPr_ue@tG{wmZd8ۀ0dΖ؈h?ur+P ?0|0j@5H50:B8=)ԥiSFYO!=ME|X$o3!@a'C4=1x=}z5 r#fGts)jT5ck?NY[lF)W8GOU{ѩ3T*wʍ)ԏD3բY&ݞ6&aAb20ZL])MTN㺔TqyvP ( ̙>1yL^B3UvT٨hl4i1|2ҸP|y o`4/ 4~.8@ }$#hDw'OL~`" TPgÌ;cM-1i8u>F_,v'9ٔLgP?fZoe*x1|aޘ:>nM֯ZCS_σvW<1+ƿ&eʔ#?-3:x%-[6mTE>S47#^fTPզ%0^-s4WalSĠWVs+\mKH )-xW2>?| vJ3Mtп;0"D}eoMkӶm0 ?ᵋ)Onj}zy=ؤ1nGbDRAj OL#1TW \jHW8'i=ڌSW?p`ِFC'NsPp5g/ xWy C;ޓmg{4'5g!y!>߻7 23yKq]'1{x{_y_TtY6 A8Qz igˀЯ@۲qa[;֡04d}۴Am~ :Hh:Hivt}exE P[gy upͩCuޤBX&\fg}d~' j ҞҙfTJm4:> RgB6C ./9+~{2^k\K?w8ϭ?w(EO:Lx{D)X/#VӿN*]gߝ8?./BK~_ޱΝ?9__i-@3x"wWφ~el OPs `7𒒏(45UqZVR.Ա6:U{YJj`Ӆ:&VZǡj/kZI ,rPĪBW8TeZ+aE^NXXUjUk%5lBk` ]Pj y9]c lbUuV԰"/ uM*tC^֪6Xt5UqZVR.Ա6:U{YJj`Ӆ:&VZǡj/kZI ,rPĪBW8TeZ+aE^NXXUjUk%5lBk` ]Pj y9]c lbUuV԰"/ uM*tC^֪6Xt5UqZVR.Ա6:U{YJj`Ӆ:&VZǡj/kZI ,rPĪBW8TeZ+aE^NXXUjUk%5lBk` ]Pj y9]c lbUuV԰ɻ!f8֗(.{3jķM~y^R dkuIۉ"ӟ ,dO\,Sh0gtYDd|=}m3|b84^~[wO9cʟ+#M?i:;~]:4u s?nNs/|pǝ?zcΟΟ =Ksͅj@IDAT'Y~rϭ?(:sy}%90|_;q_@fsYV*fQBw嗇KI鄎)0&\MJ't/P #k%~ޤtB> Y.&:(؀5?oR:c]DJ y G` HlȚp7)б."@bFքKI鄎# $6`dMϛNGR #k%~ޤtBX0&\MJ't죋H)؀5?oR:~ Y.&:EHlȚp7)qV@ y "R $6`dMϛN8_@bFքKI鄎}t)0&\MJ't/P #k%~ޤtB> Y.&:(؀5?oR:c]DJ y G` HlȚp7)б4<>;"9̫B'_qNj;H=9H)T(8+I{ʆ8Yh+ŏD0Xo_4= фRy '$iZ <fҷ~KE) FHDB6oIjגOk?5(Chߺ{79\:@ో?a *DY!Lӈ~hBec)6A[2kU|yF#{<)~,POWF`ax:E/ǴIp6O]8=Amm'k7 ft4x|/{Gxt=.!&+[a:ru~1հ=ԤR>˧^nX|c.݂aT<>Յ1 2bt`-{ B宽F~yn1Vݚ_q,fRB8'7W=bgdvlJڷ7?a>|HiTr <>] 0WѢa7<C>ix`Bk{QaB~,nأej?w|4lT-A,-z  tuz t1I`w! ӢUkI}~O#~UV ~bߝք,~p/A1DX#dɣ?,%sQ2Fqӿ #+ӿN:k)uubӿԁ{"p/yW+*#߿3Ҧx^-Fju`;{?>όzm^C;#8wf5fr* ?M$Lesp! NRpOi)`V&;Q"=tNǖJV&88)H?!;2Y-K:xp-$q 8"⏔0|"G`:C4OR˕R{xsaO0|@53;`8h4622D~G_H _VCGxzzBta ç0|oY hc1B*TX ih# U#TiΝ GlgKtS^aKlPhQ<~IJ?G`ĆaO 30,_B?:u2Pf!zSV+4MJaש/C/}vP")4t`4O.M3GoݪAŢ?<7r3`,\@s`J+gݲ%bSKqٻk7jՂߢSg޻e)9,7pX*s9ϰahC 7/=cL1#ۜ+ts'[N8϶?ӿN:9oq)csww_6u?n; 9xߜPq/dO~-= 1][juY=ZF݊T:6$X}R=81ae`?5[TCeH1E'-YWTן~¨d| /=합a˖={NE;KmO Åtԁ!Gt}ś'ZSܹ #Gi G6MCR7w2E/T@"K fϦkã?MZ>NzPѣxbA `Ć5Ypa2i4l9Ә3DxF<ޝK0zSj} e°%smiԬU{}{)=?%x]sˁ0ϋ=d1 0ldObHW8<}7jhmy<_'cC$  n=dg垻 j7w)5%Hhp.~b#TQ#1:ivTʔHiR%~HKȗagLO-I2|67kJذOy3|šܳ?濦czuOЮ +'̗DL< ]Za-:XtV&/e\0&Ru6|OFcf¦?%,c0r78"Ns_p@l* w~zY?˙`_twwr/w_y;󧾝;;>m99`0KZ4FFzl"əF 2*vPx^0 Oa0|~ֵcto}jUA>30m?ȥ>o/%"uGp-GsE9!9t(]yөt G:Dϛ7UZuʓ7'kleʔqt>/z%-wlmwڻxWOUh9[PY[_,fN]^tmgg<ぢŋӀ0|B <֮SM32|Ac='Iy/ⱦvlN}:za^} zOv ҩ'/(e,LSSa4{|ڷ{OQG Gz}/=رT4>N:ImՈqH@FϡRY:2NxS2B2.?Y]>5W{`d 3|2~)]1 '??y`y12;'6|"j> r/s,k +F'i?ZsC0,ԣys:}gpd2X0|< f60xr7 ROrm޴]-:mFH2W^CW,IX}ƑnMhec썐~^ҦOOn-o۳ cP*w5 qԱi:}|σ_ͼzX}AVS}x|b_0k-h߰N:3g$/#hl؅&d8fY;!TZ89۱rM%_0/J@pwbo WrPKŝsϭ?uh/U Z:οؽXAቼVQ\l B"z5Mc$$Mo`*9jvc/祤pXm[>ϸ"Pk_$[nŒd,P?NXݛԿeN. w9DZW~(Ft^(mߴWղ$Qj`0~S^h]W'z<>1I!GEʕhxR/9e55tvz}_者tcfڸ>\Я" s?cCh,S׳uKO&ӝ0|Ѕ -5 U}8mKsP4iԵE3OAQVx356[KCal(6ܑY^<dbɟTyO;(c.OwhHɖ#zu`">X[$#~;u#t08}5 3ф7=:[r%=S~{ƍ"W\! >1!lO]'xax"O9Wg,&>O-qxo^Q|y)OWpKj0=Ȟ&F?/NQ| VL 0e>,gPђ% 3:60 Cџ~$ƛov {U ,!h +3`4OBUYPo^*Ut)R%:y!:qRL\@y*(6C'l@y:EQ.#3u۔:mZn/Q>Ccç ܼ7n63tM0|0.9+bs{RýО;)x3pR?,d2ޚѣGE_CZ/W;?Q%_FGe dЄ<Ҕjg(Lu;@^On,ʐ!eoW+{ o%k{I[6mh0tȤNjǧEfx}ym*%ӤDýҳ9ȼG K~[;W;z >@PfN.֟[nN8??nuws՝?Ý?Ý?Ý?{;lrZ >r-Zes2Bwgd+ Tw$9N`+Kdg&8`s_uWt,VZIٹSй͟KNv;XfJ07x^>dLZ~r4͉;~΂ߌIcrjTO*'E?}g͐?2MC֦ pC hch%l^>=O?n;x]1&}KD+ GӝҞp: (80]^0rˁz0|ʚΘ-eiDM'~?iӁCT*ON@5l`xqbZŞ0< çy0|?XnU=N ^AoOGyEJKX!`dգUWZw(hf8 IgSǠ]eZdˮ Dޞs2۶nR&}Z:}0c ݵz=)]: L,C瘬ٲ@?֯_ gW,W^Z/3̆1lz"= Oc3ˇ7'NH`~1COEǡO:5Az- dO 3}i_5(;>S0|A/# L?9s禑/"^GeO_zHai*j迲U~<ө4СOi9Kt 7@qW</{UĞ[ {; ~1'e?O6ib4F7| ~E}q"(T(*V_n!=Yȣ[G.Q4MMӿ`;rt?ws?`!; vý~"#{)$`i KaVahGili'RhX;-)?k";mLB&cչ{r.~O:jѰ0$yv9S6y 0.>'uJ&aܒ|EvNa4[ ";sRTm0/˖DAj)9D n6/_+iC?sI$(\/~KBm ʔf}NIoq0LHE7O*cnځÐBC)wƌ2;G^$}_ 5M9d i T_eA"h0<>icGc!EZT yOZըL\z5#0`2 3;2R(2|b1l!?*3|o7m}a~QtEGx|b#sY͝ H<O :~"<{zqpqR( A{w8w m۸z5Y:F'*֢ov*xRe~;oNK|],x}-M>\&E &m\& Vpw1sF4ؒhߞ0j> PMX3Wn˔ L'OoOo(IP6j־}Esgs%jMքٻk7 UDzIƌ9r 0.^'fÐ V-_9ĈiP3|z]xAu VC{7ʚ5 ?S9'ן~s 0nA&׿`<$awڿ_BkVA+1M& V&^}C`󟽳T!wh~y8Nl ./i<=yʖݰ8>+cϘ)3TS[ʈoG@T&l)yo'̗D@PO0k۞VMZc&O>gzTGEZbZ d'T@S|9}k: uFx1ҷ?>]ˆO׊ 8p&g[]GXk#MC>*u4v@Qq4tP|R2ͣwOaf~UJ~v,94!LT|2c6 <0M//fGFU0J<,Eƈ?rHci⑉+V@.?wߤ5t^̰AAnj,<"-,? :U敍ӛ6#`Y#J}L['*!Ae_-֯] OX/0nBufZ5>H q[R}.N(Qꏟ_NO:I_`8`4̆^_0%<;`ba5ϭ?X*.n@Nw7ϭ?5 ߁߿Lwp/w9?/? M OΌ?;O'nS ,nwo- R'Kϓ3'Ήycq'c6 ұLX5 Tq8|2d cK_ ֟[0I?NBRH2׌9io5og"#$P> eYcr4` \0Qw8,^)"!.~rr{i菅c̱ ͘ŅAISñLDgt惇],kټyiB{mH g_}[ ã}E>'>>^|.3S6#^Yp4}>5{ςȠX4?02z.Sw <>p!>@MoPy=雄4Sx|^mqXTk9z'OdJm) %^]:7{1Va%˕g`:5%8e4n`4{RCP1' 3Ğ4z5&(G, hg葇H<J) {:ޱFSm *[z?G:ڜ9MOSzxo [ ~yP*1qJoUO& _jZFh`#xځ&- A9އ7RIG&C&G އ= {g9f~=>!=zІk< aO lH`D?cO"JH6ixk8boO-QAD'-w!ـkϙ+מ3 _<ޱ 4(Ǟj&5Ȫ[f<ꜹs') {S>{i w3 +y^BtMRR#5/rצ }3 01y)5xf#?L5>ojcZx3uDG`(fҧIf+݅4?ylzF֮RY7 +2B_K~G?Ks?50>u a׸QJgxi@5rAAܭMko`@xIں%4wNxzz{p?ϧ濿/~5 ; ןj"%Gçc! Y5gï0~M_~~w9/gO8ڌ9s>5N; 8!y>ӿN:˚ѝW#_οl:_%3_;)۽S{)x7u/wr/;a~t/r?' ZO&95@B _eݫ5mL"!| L8>٘r'>: Aɟ[N@K{?vC~ B8zu#dSF<>8ja ZDls.9|U*4ZM"*/ /c<{uޏ(~~9(aH\j~=T&W.࿌^SDhWΣG crR\8{ĚʓN++KcN`t^KY `؀LOhQ&ʖEgUD&QxZ*KF>m;h>c01{|ӟP,Y:>{qI m Y#N{rƯg}x|C]_lA`Z ܷ5o!i]xLCBŊRa)3 ҴI?ߙGU,挍\wF!gn e4p3D؃{Rzee:8c6 4gb%<2iϽ(z9foN^f2eƛK.Zs F 3W@h971tط]_a\$XpF:|06c/a_z᎐dcWҔ#3/TF8:Yqx]RF6]R;4FzpS/A ofQrO,z?ee<:ϗq.%ux/etV?eCK:Tu^4ABC2%lb:bi TOВ61bW4MPlhIpΫ~&Hh(UcS6MLuXUl?M$4*)Z&:\* JX -`S.yO |~ʆt뼊iRe>V?eCK:Tu^4ABC2%lb:bi TOВ61bW4MPlhIpΫ~&Hh(UcS6MLuXUl?M$4*)Z&:\* Ji 'uAwg(ݘ*U'8x稌@@R`+?<>%/Ce #?_&clyToe/wO*5i+( CZ%U'J >q/=gyD㿓?^tQ?W|J]a9'PQ0ׂj?kw <ϽiDyM Avz~ݾ~=M4j: ! :@PAڶ =݊M*TBdTB* ;k|7TJORggo}k>;Eƿg7'''', _ DIIIMFI8ZD'YoߨQF۱[A%{Q#ҸE*=7 kEkԯ7Pz_zxr (ZT=;N @Yr@mHN0zs9]O6$[Tz wA}=п'ES*= @\{nBb${ɓ/{J-(Mkb78-F_%WoWv#7bϾoڌruHg^o~C^$1]yه7+D?֟e"# o|dT#`?O{ 8 Yȿ-SuheQx"'Տ&]*eM[ oj/ɿ?u/jO?ɿm7+hɿ)g6(TZf v"|NR0 2p'yп$hCX?5A_a,G@06vSkǦL7a䐿ySBt\ [;6_'e*֟I#E@sb?/?@Hv_cS&knO{9:1!%$B=vבr+_55O{-[ҵ42C'(=S03 ľw}qMW^~1/|?}G ?&??/ d l ߬틣Ђx?T]/?uy5о/GBdiE;kiNW XC_"_[Dzey|tO*8ig@`rgE6Rs*QVP E;RJ˦Cs9e\g¨9!юTuZ|FY!e<̙XVX؟9k߹^БM?j* }(ӌuh~v}=@YN*淖蟭}֟?9t@oKI-vÑD-Tw|??"V~4^TvK]=lNN>U`y?yW d0mh~y?,E$kY;ɇ?7\"E4e ֟`UɹJX$s st؟=v.)[o' ~ڲ}ʯ 1?ܞ67mW}JJ {]5m̏U-UGdG?+:~Nt&/O/+В#\Cl!,3_GtQOOOOOOğğğ?? rc[g5ST[s O#U;׌~NZ'Bo@& aiޖ`Ad4X/G @݂"^s+ߍn45=dogj ҔO׹iGaPJp$yJKr0=gd~]ƃW0^;`m'>n?֟v`LL WT.% vğğğğeAM~UAA%^____4o/&3 6q]q "$& HqJ^#ؙK<ü0h".1]cޘ'?B9/HQ:Now; S (c_.Xu׊\hD^ V*# XwƵ-WQW¾;0mʈ*݁qhUFTkE[2J}w`\+rUz,Zі+`a׊\eD^ V*# XwƵ-WQW¾;0mʈ*݁qhUFTkE[2J}w`\+rUz,Zі+`a׊\eD^ V*# XwƵ-WQW¾;0mʈ*݁qhUFTkE[2J}w`\+r@\,XS!뇕2Р?8 I:8HƧr~,/]#5b߻"?#IW/_tzAz%/` -J3׸]4A]n%wDK o?kS .PPnBL0AŢK'^ L.E8 &пфv(. _ &?с"F8]!PF1|!&@1_ebO`:>顿Rmz EHg:!d59[O8< E׳$B ˿]I|㮚&g~/jxW?`?#a_/W5JAR}?_/% ""$& "<.OOOOOOOc-AzvWX~&瀢UFyiKv;|WtrT88+d~قX^!+-hc5`n-Ǔz$]b߽ΛGF 0i̇vvSMdG;)toS.M.$)0ޕ'f~]#5b߻"?Џ^=Uܑ_/?]#|m~ܕ ;("A7>5kphy,$f(g %mp8)-#H$G=K-AX% vp;9Z+ kr╷b9ZQnZ։Ѯ.I٨ '+U %x}xFv""㷓?yۯeӡ_[ o̼aĪ/&[h,6TBABMR?|蒸SuFW$]p%egРB` An?>4Y͕% ACI_b57 &Ae>p\֏pqP0$V84CA ?,TzvC̟F蟯_+eh- UW̪XBzD3=5{1[%YH 605g[Bf_puC:֯rW#[c?_ ???ȿC Mo_TkIZDzK]_-nhPP^}??o/7oo=piVeVТ^e+]/3w :̿"O/*TK_]Z@m! vXnOa`BbE,C+ $83/B_ B~yI0ermDBbϔYn\?[0 MOw_ _ğ=!Y?ȿ?ɿ?PDm@#G #G_?S_`;ߩ O?Os;8)>W]i7tౡ xL 1e1?Wzzր 1(-* ca?j0]hf' 18-* 笳8W ˝=!j3jYT\n7eT ᚱߒNyJlFca]?d1cSA&;ȿDB 'f%4F]fG uMx4 C?4//,HP$/f%Dߎ³D WrI;+fc|{s*4F'V:R_6jpz!lb5vnPjH.<?B'o|R>Mȭc.?/b0AT\G(Zi9bMG=)M#ODl1Ȣ`atl$%%/=t$1f&Ż?u]????ȿ+IIIoooooTJxd揳[3l'FJ +쿳{9S@K?P8Ƨ<Œv{)V fA9:bj'ÕofO4c~7dV7ɠ U"-)9+4Yo>?f%̼13%5YlLVM" NN"g+2Er5RMe 3mUuFД"uעDП )]u>,?'EW]CҲ?_s1t}ȹoqCG[_ğV]5>?ȿ?ɿ5"&&IK/"Oԟ?Aʓ}FԟD.;?YnIf?RHQb#Rh`a|Oz [߯l¡lhqavyP^kНVav@.)Ƞ(M<ҬAw[s9܊9 ;ɞRhV̏?_?3d fMb]?T0/FzXgo1 _PDɃCO5&O%R4 ('=Q&nvFbɿU,-+ۃo Oϯ¦.%vP׎G 9,H}>ꯔw +$-GCoDtڎPV.;zx'ƤB{+~ m>e=*ev6g:zU mp;zU lu9 : v9 ٜ,W)sL'@u,W)sL'@9kY3RO(h3Y3RO(hgs֮g\1P gg\1P]gYϸJcz?`gYϸJcz?Yβq2~BD['βq2~BD;ve=*eN8e=*ev6g:zU mp;zU lu9 : v9 ٜ,W)sL'@m³OYHg%թFLσ8b(0Z%CSլdv}3?GX؟0֚}vga#h _j?._1ã_ ?b#m#>_d}!$DMMM-u~(dձ_ZYtPAMMɅ_>y~vo/o|ҟG tW*h Nh5;TJӃM?U1El/QvphUwVnʐmx)nڜ8И:d=\݉֌I/G]k[+?ʂ C!v"_PҹRz2rQDI'B+{kC;!]y*Jy899ր~-dٚa\g1k䷊v) 9!ubtaջSs=J5HN?_KlM 83;z 9Mw9M붛u}I?~(=#|F x'ۺ_I0I/!ȔE?YE?7 b{MmD_?\x2[5RҎQ nֳ{0E'cdk׋fGb0W! _1Ū_4Cx`7O; sK0=gL'brpGb.| &4X?lB5 Ţ:#p0ڻ3}NFKrz%/wrb1Z?p8Q6 7Cm6߯.Wٳy_#2?Şu#u9>Na֡k='7Wn$%@ 'oKH#GYh"+&PHU[/zuEHH#G5fJ+׻KWxŃ3-"c# Gunz7+ɐSwIunz7+ɐSwIfQ 4wSPUdH;$3Q -n*JEU8p<Ɍ(п-n*JEU8p<Ɍ(п-n*JEU8p<Ɍ(v{k#MԒ^G6!7_WXG?j XPh}MfAySG_d15!"AoY%0+HT@rquq餌IMMv¬E???????5f߲k*$s>k*$s>k*$s>k*$s>k*$s>k*$s>k*$s>k*$s>k*$s>k*$s>k*$s>k*$s>k*$s>k*$s>k*$s>k*$s>k*$s>k*$s帘$OnhAVyZ\6 Wm4)ޣ{c\j,#hn#Pؔ1FKy$EEIMAE[-|ߪ!jPDH5.7PP1@ 'G?%B O)1FߨQJ?7>Iڀ<'!W9h˹ЌvA"}Vx =5 Rh_a@U%UXaksaD&G`kU71|M3gDvۨf;V*+}U5럦tOEqz D[7i vG?_[ /5ᷩ_PҚ7Sg_O?YI7eYTtwוob W^^}o61pޖ7>nDVU^_qC<6^ ,:+,Z F0+Jn~a`WS`: cϾs[(^ڷ(G%E۳NٓM+jCJV/W'0Ig\aŴ#A_zaaR_ğ_?,Oo =?PDVd&#pX^D-?Q3;AG[Ѐ3g;wߩK+ =IW#W | KgHc.g=|EJO8/g=PX.Ð_&aGg.uIճS*= @.I@цzJO8.g=?$hCBuJ'@p׳zP!:N @Y;Ȑѿ@Xv<>`EbHu "|Mr"!4ש2/Ou! vꂑȃýH3^??T4-f9 ATAIIICz 5L- & "lyK?e Q򏖈9)HEe!U[ ves;a@7>buy)WThJtF.oEv.WwZ|FY!G|*+e-O]s&֟,! HDb)h'\OI~ID7F'6cQZW"! yj׮24tYƛ_eA#ZИ=#I@GOTtKYh $\ED$zTHZSP@AH?PY/_+CG'YtKaٵ /ԟ4V{[SFڇAPFQ{my8upGa0¼ܫUL2w@% bMG'4ȼq?%cJX$scQ(܈ɺJX$s 9yIo𑚋^K'B*urSv1?T7ۛ6+Rɱ̏U-TG?Ysb0Xڡ7[/Oop+ $cG/_,BE/oߨQ PJG"QWIwߩSN} +Qp=Wga|ҀHF@UrQfq tLtՓFMA6 Xoն8 3&KA%(?XZjp\L5iڃO/l$|9O; J$A ,گw #(\]zGX3bN`?b5=$P1sP@EIMD _?Q>w-ŶJ??J+W_Ԓ#g'2ZPHQBPkiG?Z6#ǣ>ikэP~? ~QW¾;0mʈ*݁qhUFTkE[2J}w`\+rUz,Zі+`a׊\eD^ V*# XwƵ-WQW¾;0mʈ*݁qhUFTkE[2J}w`\+rUz,Zі+`a׊\eD^ V*# XwƵ-WQW¾;0mʈ*݁qhUFTkE[2J}w`\+rUz,Zі+`a׊\eD^ V*7>$#<070{:E|ZcD`P'dmp?IYCm ku , _CT /Oo򏈛<S'777q;kߙfQ5%D &&&6h!&&&&&&Hm1D!ː PsO\JwX?ZF\@`OQ٩+ bbUN 4;fQ勨 Bߕ(G &ؿtheh (bBL0c1jDbBL0cʢNFlϷ4x!ٜ'\mբYO ˿xS\SV#ۉ?`G?b7ğZ'!h 'ќ`9T9 Mj\#WD]ZEELmȿɿ>ЖaPB /_?hnRYAlBhQ|ڒ7͓q޵s VG[g`p 1?GlA,,ל2_VQda?ɎA%r6j[9*_zwydF* -L_hg٭ͳ*O`H jhǷdZf:/.uAA0GXn4V/Gc~9!/7Ή?;זlӖT 7 Y+z}ߔrUCxEuK6GGvC 'j??#>KAMOo/fɿ&_?Y%Ҵ&G#W2\Sgf??yf ?CuYP>=pi%rRZVwjEjvtռSVЁҗR`~aGA+!h1jdr=ѿaUz\W}}9&oEg*^*1JF7nbsV9oW;nX UJ!~D0Ie`[妥 IӀk3 (f;bOߨ?.YRJu4PJOYYhJ3w`!"?؝q+O9_o|urDWڍ-Iwb:⚉!f]c3T̏Ua^5`6C̺6p BXjf@IDAT6C̺6p `?Ǯ9N"#M@˝=j3jYT\o7dP ᚱߒNIuN6X[NT?k>Az C'7:Fɿ?U$h* M$\PROaVB+oHoIQ]@_ׄGSPy8yP@C3R2+k?^ ]ARbVRNԟhjy)<1O z~%m0Fχ.k8Bc~jE{#QnPq 'ə{F/VCi+1 ,B3!TX/0}'ӄ:)}@nK"{JuOao諀u6# Ftѓk1?GdI, G7Fb?_Z"CGYMS`fQS'uYN-^ &&&& IGZj81ɿ5"l +0쿲;3ZD#Qo|J#i_,Ii'|olF4ۑî/FqR;+1;X:\o!I3fg~N&i! gQ%p9ےSBVcV̋3#]2_d$p9-B g{zrѝM.S$W#EڔYF0ܦ]U7klM)B`_*x-Jį@%Q3^te5$-5!CׇF7_ +?}uAEIou5!Xc[-oooq<"rD<oLI"ԟ?Qkv#G%68+g8'DpXٸ忍`>*>(Z98c2tV/BVf2a:U u 2:W)t䟢Pʳ3YBN) Gtͨ.ērOJ=\MAEIS2 S&YU2_fTmv+_)+?ɿ?XH?Y\$SH2PBI7o-6Rl#G0eH_:߮Mdƾy&M)DRCˇG!mӷW_±f G!P=֋,X<|cHGJ?gQ9BKbxyW>}qF<n]H-WےMA(r؊J .&1x ?#ӕ`իt(K'7/ԟ,WqP@U4PhG-PLQTRuԟ?66wߩSq?S|?G}\ ?ZEg0^;zhfbS<0};CegWЖ4ÆkEnkGr2 #tgh=?íߞsΓ+iEpFpRΥ]yyy+'E f3Ofxܾ`lvٴ.CjĭE~&&AEIM 'Oԟ<8Qs?YhbT"E?QR=Ѓ7of']n4.[/߲ȿɿɿɿɿ=8 ࠟ,?,li]ȏ?l{x0ڑC|jKy:1ԧ#N@JIʐθB;:r4VM:L7+/g eu)ks[W,\XdAl7)bvȸ5t W0Ͳ" vƗ]!LGIK)CS  ]7L2sa>7BYO%".u $[o/ф6f4DѶ'UwRvW͒ll IC("j#쬛U/{r77'cÂ-E,R[BS#?GY+%F#E_Ǣ?G0"#eY2B6NH_쯬ϭ=γ&̊W$AOmYxU]_Ϟ3k3XBq4C% r@85n&9`Vm ҶU(E& 4_#<,$TٖO}eJU//?E׵!$ۣf>&"rh.UVkx Jₒ7>m [anAj m|A6D0xGT2` AvFnB-` dܺZQh9['9u ;Z/sNr3rjwD^ lhg-j@F:!ȭ[ z6uB[P #m0g G;#n0xGT2` AvFnB-` dܺZQh9['9u ;Z/sNr3rjwD^ lhg-j@F:!ȭ[ z6uB[P #m0g G;#n0xGT2` AvFnB-` dܺZQh9['9u ;Z/sNr3rjwD^ lhg-j@F:!ȭ[ ޳OjxcNGQd_mNsJޔ=InWj:¥}==)Gu";?͔D ?_Wc/Ϩ7IMAEI-4uh Oߨ?R W_R2wǃ`_b'Ef_Q/ÃOv?)io|(akL*1`缽P3Y3RO(hgs֮g\1P gg\1P]gYϸJcz?`gYϸJcz?Yβq2~BD['βq2~BD;ve=*eN8e=*ev6g:zU mp;zU lu9 : v9 ٜ,W)sL'@u,W)sL'@9kY3RO(h3Y3RO(hgs֮g\1P gg\1P]gYϸJcz?`gYϸJcz?Yβq2~BD&# hGow;B vbKA&RzxMMAe?"6aISEOև.OϸKNAbQBv[__a5HٝEH77X 5ߚ\zpgi6'ٹzİ@oAʐы^I5 {!4=$S?_^3?'Հi'ɥqbXsR ^g,"R`eG|?æ,o7ZVugP ٶr놎ͩ w%OztgʆHYҮN:{㍇ӡCv|BѾ D_] "֣YĿZBl]+?eAU;A@gW/_ğ߲?GEs #&. AIIMvKI%z`Gbe[AA+rml+qؠefņY9팪d&i=8zeF[G̏?Fx 񇇉_Ю0u[C=εfuK_}~[b{%q}L{־]BxuS?S\Sҭ̿$a$O^kP|[Hi(/??:h?ꟲ$t5j Sa?xXeEI֋/?o_PBE#'ub,&Gg_v_:xr/˔NNv(ZSsf&w0$brvzFI`d^gmC"F` g'y1o F^pƼ&k0$brvzFI`d^gmC"F` g'y1o F^pƼ&k0$brvzFI`d^gmC"F` g'y1o F^pƼ&k0$brvzFI`d^gmC"F` g'y1o F^pƼ&k0$brvzFI`d^gmC"F` g'y1o F^pƼ&k0$brvzFI`d^gmC"F` g})V;/*RQբ6}ڐRfCɣk S*A::VJA*3k3 xv}×8п\۬aWuB;??O_%`kV/K'=AmQCiI:}UZI񷙋b[?kqzJ#\j(# s"Ϯ+ 誒u%/kSc;?lrD4D`MW\Sֆ$BTpssĭZ5Æπc~voSArB+ 6Z8ک9$'E Q_=c&s&yӦDoȯcNC! 3Mg5t2(gd[W+ 6ZCb$==xI rS$}Nx;;񤓧N8o48zy=tE/c+W߰o_~X;ӧ'=IӞ3}#mIW?;z~ᅲUFwAXǺ`U D@])v:WSQa?Z?4)%p[У/ O쿩-ԘI(rd* #ckI0򿓝<$tDbvj̤i_[E@q7ֿc ,ŃO%X.*99yy^^HG蟛k֟Y4 Ta6z<{u ``lAև=w쮿=ƧMWô**%p[p/^hQX5KEl' uu)p00GM'xncJ4yө?\FtP{g=q5Zտo>ɿ_}t/w}#}~mS:yv~? x3dv0/ojE~\O]y={ޘ^LW_yU~kW~_18=<ӧ?EϏ}/Uԧ>EҰӺΎw9 P _P\LTwk?>S@ 'o[GMArZ!bA}/?ԟ-15?PL3gwXloG;=677}\]wN_du));N7>tۦxa3r[g JGUV~  y9_Jj#?b BVL*7CaqHcW{S7;Uxן~*oiڗaeu+ g.Чc}L74ض7=]{MrW'xҴwߣZm}R u5S{7mU~Tͱ_ 3}o3c>[vwwۧqS/wo'?E/7ݿK^:+|4>{fe/J_wL'p7U/ӽu\_җ~1}s'Q(׹6yARp [ĠہQ-;Re6'G#ܴ#@ߛ 訳X_\񧫇JB{fq ""@IMA!B8VqQSPMe9fJUN@Vyϟįs|ӻW/Oq]׿>-q]<$>Y]?FSpvT$eR90vr<I}o9\vr<I}o9\vr<I}o9\vr<I}o9\vr<I}o9\vr<I}o9\vr<I}o9\vr<I}o9\vr<I}o9\vr<I}o9\vr<I}o9\vr<I}o9\vr<I}o9\vr<I}o9\vr<I}o9\vr<I}o9\vr<I}o9\vr<I}o9\vr<I}o9\vr<I}o9\vr<I}o9\vr<I}o9\YO]YGim{˘MBvqsH.$&D:qLįM\L273Ծk~ç8#ga~n;_;Nf?h1?=䔇Ng~u>3_?6}gyͧ,Oٞ">=;as6y;E'~ ,oԹ=,/KTX_O>/t'70OiJ՗~]2 W|u_,>=Mt~kK|Hߦ?#VWEGGLԪtwGͺE8ZY"9a4H??1fjjɿE__!KڊЕYHUrPQ`UUӈ[] "!nF-8O?O^@#gߦC70{c=!jK.5u"ȓ1w'7>GGg{)m* .k}7UPK*f`~O&"K˹АaD{C?֟.#c~X˹X~zY v0R{lIe[w`m.]zCƫi̎=͖şv)y+0aYTyۓ0ۘv+3Nuں6Ѭ5_/Ϳ-4@=5????ĿR 'OGOIIIIIIIIII}Ͽ^顧&fmL[>}6͸zL}֦_~ۧtCPw^yyoj7 N}!gGyӌb7sU\Ex1BZhФ'p_ KE0C(̊Rr$3QyTS`1j5ޑwϾs/rm2C_(*Z74L?mgC0`y io*Yؠme0Id Ck>>]#>FP)/Cg_z‰'Oۘ>u8H}؃OMOO}5)<=>?},a?LPQ|WM2>rS}{ut_ooϥs$~^M_җI2>gto:p/O8E1]颋O:bw'gƛWSGM'p+/rXRt8Q3?:]yyE z߲$;uN<{3!2gOCnr/׼_M{']/{骫eqp}s_ۧ7,sΙ|ç??xpJ}_gM{-4>ʏ|ؾc'>/|K7XO~ُ|tʩOOO}W.ٿON__ms+l:pGr靿.OMkzߒ:5}g=qæO}oin|mƧmӶ7]fBG<;^n OS(5r>AWNW7w{JKfI9Vym7Z)`73O=v"ۍC=g>U{?q~^ O|1mL_~]>;/5/kZ4;O/t^*/~tC"In[ߔ"ïHOv?q^L_qC Rxͫ_-jF"ط!/EFn_/MOtzޠ3O{|_WI_G5/y3yty`]}m//{}>ez+_9~̯Mϖ|~O޲s%~oL䡧g=S!oo]˧~s >2OoǨK>K^ǟooI Nosz|W|e΍iO`hVUxo'd}{]{ݵOO\sϯs=^t䯒u},^|f׿N vdy/xu_uqpbտ/x{^g?haWW91_#_~ȟOmX_M펞??_ ŇS"cERPvm֋ _^t Rya/Y_D"Oԟ?O7~˃M3zOIgkN sē0}=S~dގ =4ӗ􇞥hkẴֳdֱ78xq~PSt_e48gahPl,\CtYفvh!lؔI&qJ6% ]S`֎  b?_[ 4ERK֎ 'b`bLS5%m$(j]ˡY!$}iK[ jl%xW1(§1:g[%NV]RAʛN?y?=QӉ'= 򐊾F#,wGiozڅo黟l,~W9O9ӿ+U{ޢ=?8} vwoɃOv&x .g@t[+X9M[ogwk8 =^%aDyP>s/yH_/;2>dG 4֧׾'4u77=R1X^n׾^|kc^MWɛkOG^B^7]-G}?77.ˈ68߬WmG=&y?w%wvt']C7?(oNF^_w˃7}QJ#_(>m؜ӾiӅ&"ǎ߿m_0=c1U1毋^:{_OO?/ۧ|ozϼyz߆Ah'?{Uq?jA&RU`4LO-jJ1?.0tsţ> sEHKCΛK\Cd4aWw O22O8C<\rC:?(+\a+)?OҐ18CPPP4-HiHCӘKVRS!/GJ# "`:;6faY;K+?Wfguw ҵ4ԛl-{EOp EOBoESS'q?'bS,|3_?cE+=[#饗c҈#CYz xM i>_Bg>#-?ҵ; ` 5Q?| ^?:V_Jz JOȩ3 w=;3 [ྎRÖ>_]{&,p+.zypT{-aH[`wޑuAP[ϓ= h xN*22ddu m gԿjuyaA]ksxÏȣ<*[l!]`w/ԟ7=9 ԿF/0xWO}[Cj-Ef0,].hw' Z+3f̐Cko&_JgtE*mN;4$x!y TF7p#,PhgΜ%zAy`|\·tU4{sC>"OL$ll8xCYcȟH~m}pʤŋZ䆉ʽ#kAʖ[}ٮ];ׅwݩޱ&?C{؇?'ǟ?e-/?iEf~##5*O#hl \?͠cΧj^I0^4G(@$\NhKz$-u2ACGEEt+?c[~m*۰m{_e7]RKbӁn:_AKJ=W Sb tj O[{XIV\,|i3CW󉶶 D-dYTmoH[OJFp5ЧdzAQPPPJ(U%R'ڂZL".Q|6O_,|؂:\}̠ z5JJϿ] ng8P/R]ߐ}n Vn|:I=gV߫-Wx:`:$wM\ud2'??;NK*#\vYve!*\-;n/dW.|;1A_XG(1 ?\P .pk-u,@ wI_./Rc7~kv-PD^rI_UvizKKC7OíY]^$qp}M7sӦuNdUW"k=vU-.lM6O<1ń X,vk䨣6\g=d [Կ7<3ilr 喛Kg츃߳AteW\%L"׷;z}A, g|GGF=;>fk!ko[ ?X(Gv[iuoe+kKۊXkGk򳟟%݇s:`ً#e^)o¯LVm⭇יE]k iX6c󎐅f;5^(t/zEVY;]8N#0?sfwŲꪐO{sV1ŗ @]%cƌGc^zsٶn'C=?[@IDAT#GHe' ^0/"?c;xᾐ Xs;U:q3^>9F7vl]s 'fon]?> _?ԓɏ2wX,CGo8ڿC ?]dx~0ء믿nH[NkO *IAZ;hr3g߾I*3׿;i')Kw+&ywLvd *o9x,/XŃW\Y_r]^Oګӧzɨ3v2Çcv+vfga篰[#JtH/pt?x/GCD?U_&U4_"A?O  MAӦ+?i+o흘*?0O?Ɵ7?mI/ȵW_.}+[~ ڳd]ʫ).\|?tgY9Ny :>.|ҷXz;Ql}PvQY.3ޖY+eTmiJ20#omyRFe z[fQY.3ޖY+eTmiJ20#omyRFe z[fQY.3ޖY+eTmiJ20#omyRFe z[fQY.3ޖY+eTmiJ20#omyRFe z[fQY.3ޖY+eTmiJ20#omyRFe z[fQY.3ޖY+eTmiJ20#omy(vNFSş8' 3¼W߼V N{/pk{fٿTN^ ՅOx,>{`g=׊ "tWdƌ[*0xz7oqstc7ݪÛߌEz '{kY_zIP,ql->rsm$OOi>>>cǝwP{Z_wO\tƎ8]vjصG?Sd|ҤIr4:d>$v=^U}ўƶVE͋vKcm}~&vj1Q,;cH7hvC:w9ih[.,\}]8Se+{ݶ߿.ŃAď~t|]w kwޑW6z'gl-oYh{fAOjM2/U)ub ]e ×^Q:uPFn0 H}"=uJp1' Mr5գNȗuJ렬& U`΋25WwVeI`7 L];):(+1|V0,stD*%uJ(%cN/?]JA.F@kۇ7҄hHZ {p8lW⩶gN"ƟB&Vl'_l ]OȜY={Ku+/]vB_ ~cL™Ocb]\h?]4`@g_8˸&le}^1]me8쾃%l;QC8Bv;'oEc^ð)NȰ=nq$+vr;wpCtmS=a]oɓ&˨Ii1?tI^1Cv_$uAw_Kp]p)'a,,N(߷c!U5M#կ ;I@_'{4$k Wmp9OGӄO'tpQ ?Z_i ο?hjTڿlrIGNG;P!XQs[ą/VE#jʔNuD`5_ƿiGt`ysԪ?;0$6Ə5o1dKm`R \Km`Yve僅 ҋk^Gm[6~LI|}?5EJ#Ny{s  n,x& >s X҄]bԑ>sB;4zyңG;` XM.{]K§Z;#dm5:][oM7:|'1gذ/ˌ&` ir$Gi/Q`IرAtbP9Ov2k, w0klFʫaߧQ}EG5m$v0ѿHK DP TڠnIT&TZ[-I ?#qdXF ǟ+Ē8>TjG%iPP@0JH$C6ς;uk}h,ћ2ѓrn^?EU )2 cv 7?,BH1ہ'g>f^F2}:vz6zmfˡ k">>?qM ]/^$c IG^;"d ǎOz/OG#c[e>E_#:tӞ{`ǧ;v|܁nc^r.'W^s I{oמ Ͻv t$5tTPzʱO0_]?pU;d/} 7N]k]7bl9Xw-kɋ7ސYEl;NX [cEDbGeI+e ;TO}?"=n]t'˔'B@d#d3;Vk.h{<wgΔvQV_sM1wmw8@M2-2dʎnص^vk-gc#=#b4ʿb2tZ;nyX@߿TJ+YZnwAW^ee9 |xVtW3mual`]z񏷆JplډףO]v"*ٯ~sOkjNSCu0rJt*<,zZ#dO?tPҿ߿hڭ|{ߗ6Dւu]3sv箻)\X [$9.A_TDd/_#$GS(?Կ7ss]Yt^^5G?;1Y%E?17 :|]({콯}Oɝk︋/y?*ߧ:= |s I)ϥ\LO*N@+zz7F O[!:hԦ*Px6'_7ad#AK9}GLS`|% 8I}6fR0;[u :CdVqV4`𲷢Q -.#jqҵ92';uEI}X I1 ^§Z՞hG$n&JԌflǧ%߀eβ'&KaWX2֛o!ߩؕgAV;>v]n ;>_ { 83v:w|2"R. =v|u?7;?x{& ?X(vݭsam3Er˚OsW-`ԻL/zX3z{]F1ካ[W>6wUO7?ں+֛oƎ5Xp ?X$xÂ2fm+3-^g|q~ֿRʖ[m&{_=ʵW?dKF(6ϿԿԿ\6qnsԿi:O?DO Vjߴ㖿gA,b|JN9$Ks: ?/v:UW-owɭC`<;>/{_wCc؞F;>]rx_? G tnUr%].;="}LĎO!#~C>WvꪫWa•f.wˮ4MHw`ꌿ&b=,p8A6|s?<}Z?\_L|qi] }gpMD:-~K= \VEq5詐&h׬?f4e{mV?`A+wZ9p쪻zO3wp}DJĤ+:3GmvIrUK/w5ǶCoQJec9[˨•6ɼyEXlVտ|ߵݰG=oAag5s?d F}mm#~[c0̲bQ5#O8AA߻wo9uԙX8%2vy V_w"1?Wo,p}z?)<:oœB}[9C(OŦk_SGss/ڟ> hAÔ/?eO?}g܊?_E?@)@hMK[}97NΙXW ȄO+̔'G{ϊ76_궲tT;|5IVeL+ߕxܳHZK8cG 8zxCd S?OSL$GV+٢NECCC # [V!d(ϷYvH?vX>_2)45=lh-Գ0pQB˚B`'`{_$IYgcv};>L>!=zQNǎQx)>?-|ŽOafk䡞׿!z-nRR"_yt鲂؝.e~ sOat䏷ݚXHX/O{ ';O^ÏmT}z1GϿPs=x&(>OZ qЁ?Yf] zByw+&vyZ[c=*tyǡoF հ_3;>@yݡHw*cv";樣| {pťZKNS7m-3fwWqq ~H~~&2ľ;zqzB@LeD)OOO<&cSBQ>j k:vʼnzO=zRzs ϕ>57i YgcaZXؤm/\@<`,b˄ +vS;r![Sy+mBŗ^(xk^L%8߿>oʗ WGZj.U#״9/_i6GV5Oߌ?`I_͎1#㯌2EƟB@Gnw';c*j(Z"|xWYye_MآE)h4^}~wn릖GL',h륮jHK߲#|:(1[".jy>ٿqKtqQ )/ο1QwB'U8L[w v|tu,cv}ɸuf3P"֧b0 ^(Z*}JPP)S|h/rYfLEcG=h3<~z<0CWh>S kб-Ymee;6ւv+ 7j3KA~y'dP,RY{u˱ ma(o4aKXj=B?Xh_r׈>taFn+N㓞k!9>'MzTF~hK } Ӧ>#O>񤬳ڲe9*eXx4ܴgCh~y.L.Xh?)*X\eO޻{+?ak*? "tMmA.x~o~XklS_Ǒ'(Su-wd?,qY1Jd 0$=| _6 \s381Xء\x>=z'M/ VqOsM k-gɣ]ɦK/O ǥM<玁NŃhM׻d2Ľkge- ;ecfqKҿ_ cɬd#ѧw'-eg,@,ف{: ?8 &O~\z `דvi-lC~a)ӌ + .X]fY)OI2R V]`] }k< lwZxot|Y"ߥ?OL4`eOQᐯ{ySiOR1)αiiy6#]*z9RM7o<0 OKz!|;TS1_Úw0N`R;R3C+>`BivVt ed?/C:68LCJ)4M(R8m ;+ 2F9C/Ɇ HS/AT8CcRxc-M`H6? 1[5( v Iz\xd̡A_*x]jnO,P0i]z W<@=dMU5 >?q ;dhR#zwlgf9B2vEˆF@[^~Izc6tvxMҾC;O{b'0$ߎ.ƎOփv"+\0",Pȿ]S؍_=#]2Q K!'?]x󜬽:ҡ=G/hؕ|mݜFx-ǏxmF݃QA;x[<W(oıb؂g\dg EZC6N;$lc agvEk=_K/E;1XHt=wG[+"vS:^ tfmB,|jOm*QY^4vr N*'>Z(|t[뭷dcױ"Ws/Îlvvw+"8.I/+e~ ~d޼@/͕C9Xޟ-+gw,' hc9uQ)'k|Ͽ{bt!_p&09Ogϒ?*? wiel^RVi qQ7)_8,9f^ο!lI1D_hqA'߿]mc%E PNhfEyO Yӄ^mUPt꼬̝2y|cyLVb_o>"7,|~ʡh?'ՠRN^Mbm{RPlj>u+J aSby)S40$yNKP$|ZBRRRMqOPSRBMqb:/BFL2j)6ʟ8&s̃ 7GXp*4G4 XӼ+3B%@n ]N;:k2sɫfbL&Jbնb׼J+QXշo_{p7lùW+[s͞Ә^ʘM91ҌXGyl _ wbPik~6 {1}ί#ϡ vv%%w+캫uY`E{Yͯ~%obǧF߿zr?cu~qY‹/5k*]O⼵WY7}<=**g޿*Ͽ:Hs P-IShK V] oSXȪұWPk)8a>W@L!c*Ŭ>\LLØ!CQ/_iڟڟo+/_? I; p`|JD /?11o:[n8W')T3MƄ5:Et^D!ߠDq "pαo $V"/n]>~E:gsK?t9n{F'?&KTGF4h@9+uAo`"kVV?%kz% I`:cP:/AN}VfϜԈwvJ̌W_T/4̳Ӟ*#Fh(:v ձf(.|׿;}aߚ={&n&cp/KCCo}8?hicIЃ7?'yڔM\~ ?S jիheHR}'ZOk ;5@KJ5/!|D i.S8sIP j.kF?τd$(=H @у;h#۩C7֗6t(H-K| T s.6҄Jv ]FkW>),+`ד~ء/cTk@N>4ZY\tQ]<; u3se[ouֆOGmLP}8(afB,] QFvV;E'A90:j&8r)_hQKigգ`ª1h|ɑG4ۘW,@+B1-،ƿ"*v6F( g j̃JoX-> sgYe VB'}=c]'Κ=K=ߟsx>G v|'=Fa'e<CH3 J+YY^zEyz2{LY{ud3,(ؾ y{oka@ QEWP8tdAB CJO,ԔC"&` %17  D?p(JOBἡ1u o}PcXA/&MdHi[xY@ABP%giiM73J'_^rzޠW0o34fgP@+R]&qPPb|"+[JK[_nTr>Z?͸X)wR$Ԁn~J`bȚz>+Ȍ) h-=3oG:>)2dHX |ǧO ;߻gח'ΝAxFb mI,/'p+??ߧG٠gL.mu.s?\31ag(h3KP ?w?DBSUf8*SJ OWxj ? AC%!QQ"EgnxG[w4hΌbSaQ<#߁?J>)ӷb%P--[ʱwFVFŜ#= DVBd t2*4xJ3i˨sNPŞVc6+@-bΑ:qJC{Z)٬49Gz) ^i8f t2*4xJ3i˨sNPŞVc6+@-bΑ:qJC{Z)٬49Gz) ^i8f t2*4xJ3i˨sNPŞVc6+@-bΑ:qJC{Z)٬49Gz) ^i8f t2*4xJ3i˨sNPŞVc6+@-bΑ:qJC{Z)٬49Gz) ^i8f t2*4xJ3i˨sNPŞVc6+@-bΑ:qJC{Z)٬49Gz) ^i8f t2*4xJ3i˨sNPŞVc6+@];>yI&Cz@@RŖ4گ4GCa Ak-=z3"NE!t6O:نx@9W?;wc. ΝUȋϿ /KO9p6/ڟ}Zo52@ڿiK?BX_zo|P9Б+b/ƿߟ?,s_?oi}⯅dvVF)Re"HB_- rӼz$ kK" AxwXIcڒ*'O+}@Ҙ) rӼ H֖T1E>AxZ3Ƅ%ULOV@Ҙ) rJy64&-b|4Ƅ%ULOV̳1amIS䀧y84&-b|g $ kK" <;1amIS䀧>l iLX[R9ia$ kK" AxwXIcڒ*'O+}@Ҙ) rzޑ1gl ߷Iu/'́J?03ϘV1 1 ol:c D*oqa_O>+f| XIv ?SUU2yJ H ez4DFFyx@S=RR.#szpqAP 5E9WƆJ H?xᆖbS!pwy[cSCKۡ z*_oNQt_p8fF/οЏ`A'`U8h oATMMJE/ _ʄBmX/G >oE˴ΟJ j;?3Ѝ?(ir?%0I!RZŖ `}Zz2c=jӺl-~L.GY~Z} z@qQeWPԿLQ7m`az Ji폾:Ӡn.M9&V‘d̆ϰ6JmdmGC'8pu%EnJUhbplN|?A#ڙ6OA#Ĉc0% Ky? ?QJ¸ Y_3``AxF|Mp,FE+ %d9?}jrZwԚ/m+hM jZk׃ ɞO=RuQGJ8BEGKp"G8XHPQ(N\=ZhN??fUQR~oAC@n:4aw&}:U_ NSPlr;@@?gJ_Oҟ'9pAbԉ@ &O3iCT"LNL(TXpA'o sO'㿌?2 ۈ?_h7qoE z0#PMK 0/|z/ӦL6uU{j`!%(Wp}1ae؞'K,trJ.ϱUHY&% 3. 05 T@ļ:J4 95pPh@c\OWH>- RR mq I<7o'L[_?IG'o PڠP~0Dݡ`d$KN?0CԧH``PYԙ1gVV*9.|JLξ}pFd 6eer.oӅJĬ|:74\jOtMKcc&h T\qqqsB C WkLSQ_ꟾn]+_5l>\>A=tVP xq7VGaD].<бGH/h?Y /9Ɵ@c?2oV9A߿ ߿@3'? ߿@߿ ߿K1*/|dU.}?Mb)[B>5R#IԤe"tiBdl)"Z3r(@{Tb2'פ%EAؑY%LOxu( dhk;>j'gk+NVh(>qgs *ԙ?S~@nGˉlEwۯk(<U ?f̒D /?A/2 /[S863c7T?2tA1&`W_§0BufSYkΛ)(5jKE>NApESZaL-9︢jSp *!ϩ ʩ .WIUCSNpES\hχ4?**^ (6\%Wўi~NU8UPNmpJ*=p+z-rT\E{>9UTWZ@9*|Hs赀rjURqTS\k*!ϩ ʩ .WIUCSNpES\hχ4?**^ (6\%Wўi~NU8UPNmpJ*=p+z-rT\E{>9UTWZ@9*|Hs赀rjURqTS\k*!ϩ ʩ .WIUCSNpES\hχ4?**W +u4 41Q"6^Tn^JCvhC-`+Z~^ k?O| ?`(h- jKKO?Wѐ23gO^~xlǧrAD*!h3B|^5kHr`0jʟǟ 00:'kHr/?IC;pp4ųvcS/_RuRV6pRߥY-YN['$ 7ɮ1i'_? |o0;̠l)_?iesa8E7Ba75":1,ezX$O?1f"3=o?2`bgwgwDB$!yOȪzdU9f`3XI9mS(gg' ~)IA#8Cz֣RCJ'3!g=Cc:EOmg2LCUpC!M""Ui9k@lדDui9:6@9(FV$AU7Ș:mg uٟ@" Li99{LW*zJgyGƴP=@P>wFP dk8*_xmT 䡎ANA_ Qw(?~ 8p8EB/m)HTq?m'5- ;2)1k ?ޔirJ,)cq``pCVtVRS!W6ile#!M>D^5L???UAUibq糠bFl ^s5@_~7G܄]u@TvҹճD @]yR]OXP0tDfpQP<)_FE7_>AOߌ?#/ZT /*?o10+ό?y&ʉ;3;Qg)9#L_xg>AZ ~qz `:TO5Y/Pʟ?_ i60CĔ/_PMkCq2K `/4a$L>N3 D @h8(/VF3GczA/bKOߦ(trЩOߌ?t/?10(B\l'㏈}3+㯌2L 92I*  dc!Zn㏌?2 A'0g$ 4 XH/@ϺkoX&TFe z[fQY.3ޖY+eTmiJ20#omyRFe z[fQY.3ޖY+eTmiJ20#omyRFe z[fQY.3ޖY+eTmiJ20#omyRFe z[fQY.3ޖY+eTmiJ20#omyRFe z[fQY.3ޖY+eTmiJ20#omyRFe z[fQY.3ޖY+eTmi֊t'۝ 9_3F>oK=G @F+{fٿT')p9J.,)c9\?`W%E7+:R_ML>1X̧(FHwrƘPn!DA7oߦsfM7oߘP=1ޥs0ğMBת4,|!XXe% \),Jk:NiwVeI`7 L]g":(• G@PuN!Q:uPVYa@qAQKCTet^9/1|V~ y3E.|C7hџo79 ׄhLZM6 ֶ橶gA(O6MsvJ_6AU1Ist >˶ HPM諉M?F{N GdA8cοjVQW?iJgߌ?0 Vts"H3 /?1fMc1Ij!WƟg]5?? |Yx0m$:yZT+GGZYA*u:Y:*6x좌 QP Xzgu(Rm #Ò4J8JzQyy4@CCc' K()[B%+~4i}mF0އ {я w]`=ŗ=V`ՁBF k_~ %( Q\ _ ?IO?TWu_*hB ITBWNIS_ _&&/%Te Oj,I4Ӣ?Id+1>Zju ?:ڔdhVZEwR ?/?1c 㯌2k+㯌?'FA 0+ό?C8J̽Vǵj,Ҧfه¬hX!PD%kdStC*Or,5eD%k W GQ8Taz!ԔU3\ECC? 0,p WA͝o"TgY]p/P4XEe~KN3 },{DGCksN8:kp/ڟhV3/* 0m<0%ԿbG[ Y`,)! ֔&<`B__`?w_$ĉ'~Yo*>% Zv|L )B]Z|ZuPF(™3qhҪB9LctM(49r;;>>u-cr\rXZ H[0p[QU Tʴѓm!0(8H_?i`3ӑgƦ31(>̧ K?A+jNhI?F{7o3摹?V|LaSċT?783^b>CSy඄sR R?ϓ% ,I Z-Xa aUDjmۺoMe%( BP,d<3s=yx {!̙s;g{O0G;tH?3FeYxaO4a&~/"I$8_$]P݈Q8eJX*?b%ļ3R$+PوDg`P ^S;]HF"K3aznRY6M1`2xNJ[e*c:?'Y@?/<3x~W Z1x~9-G _q+/<'h2? B-߈ȿB '6ysZ' ?IlOȿe#?"Hȿ"4ϟI7d>,AUEfG4 uT2*- wQؠm邩t.t蟋k+OLSUݠEvC\,6_[y`**- `AISE=irFTr" VȌ٭^,R>>K- R;s+ɟJG̸Cxΰ.zVB' KF_?X8! [=ue CNPPʒAse#_?!ğ?"'ooDCD!;̴D"cJB"_AoȿjǼV #0ecc_'$ B. }vJ,xR?QTaa|u[TL^m=g48 .Dn1> M>Y}щ#H?R*YC`tT? Oӛy-:mneHҋctG7z ,S?|*~tFPxT ?Ƈg/*ey,X /H ?# O+8uG_%{B>Jng䟑FY(qCIֆF3vwߑGwo3?#G^0^Ԝ6{s=H߹$n6?Bʪ=WDʹb4zS8nW9??څ<=GA`vȹR^]ЅaP՞+|@* #dP]6UONK`otTˑI\0\\;x>h#9I?1x8*PNbxԾ,U_ ?d  _?# O?!!O5'qE Jh`\QgfOD.z >P巔oIA?̿)fOWQ&J{*a1ilFKCZZ?TFSil]`|DE\fgtzb btd~? AB-F TXYlKH @"Y97Ej "Mlh/[7bpDBA!ȷ'YwE_ :;,HecK_]H, _?ΪY m㓹U6{h bC-Ft&6<9T=?8t ٰx_G2+RУ=?4?:OR!tu,"fMH4{lp8i_Klk̬0"! |'+뚼=ϽǢc|G %_(ĻPRxg;/0,ʬJoYLѰ`=/#?dbK\Ol30o:3D%U*_Q@5APP ]'OqΪ!a_T3E^V_W8DE_|#,B\Y**3?Jg@QfH+K%9W5[r͐VJ0 rjF!4f/`d+\ o5CZi^*V6ȹ4kҘTls5Ph5* i1{#[ jxkTJcR FA@ ֨\3le@QfH+K%9W5[r͐VJ0 rjF!4f/`d+\ o5CZi^*V6ȹ4kҘTls5Ph5* i1{#[ jxkTJcR FA@ ֨\3le@QfH+K%9W5[r͐VJ0 rjF!4f/`d+\ o5CZi^*V6ȹ4kҘTls5Ph5* i1{#[ jxw/>YDH~nCuL%H=q qq jQԏE:Ƈd )ԁ=b>_?-ÞM߈?!DM1'8t , _B ǘjAW_Egg_>ppp_p p ,IfRm|'':rAהtG|2ؼ+Kw6)u 1f*Kw6)u 2؀;cĔCX3V;cĔCXlҝMibJ!lҝMibJ!6`eئ41V6ƌUeئ41VtglSRw+cƪtglSRw+ XY3)ML;d1cUY3)ML;dq,۔&2Ƙ,۔&28`VmJS`ecXUmJS`e+Kw6)u 1f*Kw6)u 2؀;cĔCX3V;cĔCXlҝMibJ!lҝMibJ!N_|MnE* {>rN/Fzg!UNaY"6Mf&szH\?Lbab!k Ѻ/_l^FK<6z/?"m! &:?!GOMxЃ!yp p 4J)gY,T!F, ߈sp!_'tmV/>ka 2RRV2Y` 2/]:3c5+yv^ l?? ?jRԵrv^+ XIhX`_w"m|?C/ƈTm.Yɺ>KMq*|C+*c2`D?g?2fw:1/y/_aB$CAvwE B'o? 9Gԓ '䟐 !ǕbO?IIDON!D7J0WO?}μ5^mk9tsHGks[gZ[a$DSIWI?Ϫe /_2?j'N*=xi?̩|{?uie?ץ Dn~Isӹ?ꓱTa X+#/?#@EcTğ1SbNX ,rp /\AGF"H2Ag_#>Hox'ɲI:%TxN,rA(+P-&C/>UIe8갉0N'ř5P@ܡf6j j5qtVcpD Td8P3wk#j"{ŁC8m\+Q+jiZ^qfP3NJg5G@E5sqڸV:18*W;ԌƵY5P@ܡf6j j5qtVcpD Td8P3wk#j"{ŁC8m\+Q+jiZ^qfP3NJg5G@E5sqڸV:18*W;ԌƵY5P@ܡf6j j5qtVcpD Td8P3wk#j"{ŁC8m\+Q+jiZ^qfP3NJg5G@EBh{SA]NgS= B$0=TwnDIp[Jee*\?73` kdK\JJK W>W`b~i[? ',')2+|8Ean 'O8gX#\RZVZO?ˬ'O?arKiYiI`?_oϥ?_SyT]QCyj g{ /$YfXa|]F/ zIFM$-gŀDc{&_a|U! <+Z< H ́A/֠?ރ :#hwsI JGlB4 *8 1p>XgIS")9zGwRd71?:6q/Cf_z'v3(uɸC2-?'SjDaUXD:_+WjDA 7GԼ)Fd D|ZȰ^ #?"Ȇ@Aȿ"+ϗ-:5svfE^9"K AJx͏*3FTُ+3FTD˦i@ꂊ;JǙ!_ERuE;JǙ$ _J%" (u`g(E[*UW38ԁyG1iIʮ%97AN`}3-~9L(E:3< YR1>"҃?X\R) 2qT]T:.#BX ?!E'Oğ?"DMAJ,@xlm#.*!@lO@@}fɁ (D(C?IFB'`/A?VԵ/k.,nظk?o5OfOℑ9ּmZl2OeB# ݭI1_A>xاxH})zFb8`VYsԥ0VDV.*7xo#{3q9@́-u*rC_ -ie(`]DaUṕ޺K&U (_|*f'5,p9 DyKPKpoqA!r??0Q06b #?DX(y6)԰\@?"DJ_" /ȿ "a5OplpC 7>"k?ȿ"++o| R4ŧڤsͺ)8 ԕ=K¥2j"_Ԇ`bzJS^›hkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR*_|=e\0W)HuOr__FmzջgN;V%WPaz ?$ 6Y)jԞԓ7_?iv$WM߬!? jA '䟐5҂lS SړB_W='Ŝȿ /?hG5"ȿ"?/>Ֆ\I܀yORDQc,t s ԥAhډw\]X_QPq^@I"_:X6$<3/s?rȜ"h?$ ֲ͗n霊g?XH͏NfÓeXn|/YɺЧ?fg ).1Ha!"u?XdKk_?ߢkF 'oAsrȿ!/ȿ OOR7W{l|qy&7/ 7?|M4O5QûU%&c;jhLS0F?)LKbT?0ԣ͉p%"```` [c⤩1$/尃(۾hl" OX{d]Te2r |Bz"J?2?b1,o_n?ԗ7_?I,ğI/@䟐C3lu o Cs?!L=!&v'ߐDiY` gYߑGw);(@IDATW Ͽ &ߓU98#$>i %j|)U R9Y)j|`|C&1+E&?uB@k R%Jt0P|W9@dIJt0P|r=1JP);`!O+zb&R*%vB@R/m%[#Kp*\ mݒB\r1Xa_N5Laԡ4!40>/oT2!W_$_i L O0 /ğYD/?!o (#+ȿi>7Q ߐDWg@g3`2k3RAW OxKE}a_̿W|;vޞ}V'P\C6pZW  bݐ}%Z ѱn\E /0A$2PʨuC.:A ?I%g0!.&)B`Ԕˊh|R7d.gqֿ{;Ohq[&\=ǯY('Qvm܋@>C˶WW#T/2t5EtBABK'ˤ:!%GLgb WK4?$*^wIS5gV! ye߬?qOɳW?SSii_, ׼9K$#O9(¢ p*B"gL2Rr_}@ ? ?_U!?RH$b)$V!!/?q|RM\G 7ߐc=䟐C{TVmuYs[ymφs>ung.1SɚvIޕq C?Nt8Y&mB &???̿b4"ͺ m3``^g"m|l>bsa/q+(Sg7rX.S"j YnGE6VO5 n,%b|gfC 1&?!x~X-]r;NL 7wy =^Lc>Y %ЂLMP(80 HˆUY*=xC0`8]`;XvC,^xi@7&M@'h.BbK\X?7ȿ"+drgObe @Gi.\ o9BG7Am?@񉳀E{ u1FZ@K ֗j C/+C/5*؇Z_V^jT0 ԨP ``h}YzQ>42RB-}heeFZ@K ֗j C/+C/5*؇Z_V^jT0 ԨP ``h}YzQ>42RB-}heeFZ@K ֗j C/+C/5*؇Z_V^jT0 ԨP ``h}YzQ>42b(|"r 9vP'M@NHsc#qMg/cJvمĬe$N[|$bW.[.Wh~ s3``mGE hbE_]D G_%BE@YaB ׳'O^Ysa,65 /_x<WsY)ʩx׆t. :R7>X㲗PB| :'q N촆xo,8@^@$(3 \Q܁%m:c Əeϵ(D.͂(a"gFw@ ES\ю_Uс# \pt4FHzh1 Y OY\K4}֐E ]M O" Ei~ n`g R돮F5 OiNo8wYHا]O7dB8Ct?J"b)do 'Oğ*/_vO,?" /$? G>#D& k/ϧk Ȍ4`؞amLZӳee䋸ئ#A*!L3=qJM2rD81``=l!`W9LNV5m# 1i$/ !8I 34R앇+*4{LUz prѱz0>Ig0~Z䙳g +MK-J PCןgghw? A{!{8^_5g RCr_Yv?I CcdхO?u /ğo(`y]m0O)EapfG9aPuoM@q:ʁAd`|g3$ )|`t8`{F&ǦOR,!Y*)3*5/;q)A fX Qo^J?oaR"rYaϢaN{L'U'˸'XR]blx=f+c6cƎ!*E/_>?ϗ2H4HlaĈ!"lϖw[Rb%y` / BK,0OKcE?M}',$_l$_Y'|A ??4_PY4D" U71χʷ#gRщFE ɭdJ. Zl=t[Ej?O ڊ`1 O nlq/_#8iLRe?MF~ l{)3oNGt p=īBV{෌pc[Ѧ,W%զ˗@7 qvkٟM/K+i_.J^7\????Y0xY;XA'WG vG/L# M'(ҁO?!S,"oȿ!#?KOȿwp_4T ?=<=bX̬t#OV_Y}Bi S4$ "EOS^je&ZJL  ZUb^D+e}Ut>-y49xK/;}^:7oFV6ꦟ_hf6=?`C*/](-/< Eiλ_Az>꟯p(GN7}@?] xa/x?/_O%φ߂Ov]1UID]ogaa8h D*ׁQava~ڴs c epjFUZ !^g'RAy.]~*)Ib'dYBo "nW]标y*3hOg1a`//?Ŀ@/Z s7f /_Xb/%*o%Ix0{wg}6m+xZ*-](};<C}?XQ-_|MrG8wO4}G3 kmc=¹aWY"Ć!_cRpiPb=¹i$:cU H'X4 JGG[n/p;q}d8ƧTd+Aۣ܌e aɻznh5ưMPBhи^kޠY葴dH.^nko2_ xBpHKÆ'QeP¿>}N~uHIr(9_w ?P̿Æ+-oX:F}*/??_#Hޔ';t/_Y*C???Xx=/ y]`iiߡ?&?X`OL|1߲i$/|oW8,cjՊ4+ҚO />gFJ!ިχ<4xnG^Q&Rߡ4!Tb,]ҩw`|^ E^cFE2?FdC%"gQ: 4a`aUh2b^$֕y֨tI'؟ v{5>OMK'j(R^򝩵t̪%ha?eVWqwL$ŏŴ9r B?ON&xnݤΜaa?mWBkԨQiǝvJǍ?<]py6 ~?1υNSN.?oyG KWϞ+ʕ餙'b} (ZO :O_U /_0 =W?/u'o?Xp-~V9σ#ȿxn? ل 'Oğ?"Dx?4ȿ lo[:.);ҊҔ}M/a';z9W<'a;ᇘM:o)',ԬCYT#U[dF`|FDbY :**-2& 쏛6mSԪn"С. <]0NUvمӿ$OͼfyT1^ԔtK[fO1@67כ-3d5P=i<}6%-MOKyDy qvKMH܏|Չ/DĽ&1cr(-^+ϙ{mF_ [/{Q'\A~O&mv~hzϻϔ~(Կ4u/JM.nSȟo|"I\*tҌMv1*wc|ȟmj"X IV 6C 15Y6G gYyz|`aaӒF',Jο#Ә6К 1 [IZoa!Δȿ!PDSV\lӵO*g9mziGk# \{iiF!k^VFH=?ο[V7#3 }I`?YYƑujOiIYJ4CVI%LTP&_i&(̿(U R >dg 'JEUd5y?% ~Fv7aO;߫Wml%j4"|?%oCΈf uZ0~K>`%kOrH#vI;B_uٝ _i{O=$NAGs}gϽ& ֛v[;c: -"M&o?wxV"e˖u:m6|6Y-[DPÆ^Cb^)HI=@/NBnjF >Ǟ,4kUo劕5g{M0>>q"mZB?`Z|r^F?瞴_a*wrW?TzΒ~ڴ| j'*~nj{i˱[YZH a߁ͤ 뿬MnY.rl`pHXLea eK>/BTixa .&N%:c/_r:YGIz ?HpB*GY[;h GQ#X<4o~6KՊeҕW\Yizo;ֽܝnwޞ4^˄]?'W_?~/]lw{eǧy|}'MxL] ժ=W?Pr]ЅaP՞+|`|CȨT&S]6UrEDG*E⡢ 0ls' :R)J]ЅaP՞+|@T?QёJQx. \rxĽ!vpt$.Uf;uGəN4`# 8ь]w/_,=},T?+qըqOŋNj'o9b~z!=rO{w9j Yu>ͺqNMK; E/1r ֭[++Y0jX?O>qJEU%{`-9qԲkC?10?]mhrjBEXv;?V_0kIS%8i߬ɤX A_ψ!-*4B/Ov7^Yx!mVZ/}Ц' ,zDԔIXě,׃l?6 />Ƨ˗\jkg>tǏ~inH]U7T6DDՐHFp*\'&uvFՊdb\Iml?*sLwt)~3|òקSEg֧ÆWL~B•ks 'FگX"GjzfiIyÆ/:/Yom|Rf{OeYZ$ۑhRfG 4v/1~}GB(%COB 7R +4 [Q|X&NWtȦ- lY+ZޞdshY{}iHVBĈ}1I$䥏'}I{3_cJ{'+iC6C_|OأmY+iCPwqZoNx <7\OzI?t_J/a13gH_|ZEUs:]m Ko-uۏ<*mf,2[OO?FgE>Hғi˱c11kܸqmݚ~|]2ڐvmH_/DQ?nWO}* >~0Gۥ ei7(yٟ7vXAm_}Ӷ4S^멵k҅Ou֦nU$_t1DoI7J=鵯}4|0o|=]F34_>\ NY`U 6<E ``x>Ȥ!M2"=a?ĿjO;'xf +/℘DT.Y5C /& %?FQ߈D"[Nq0%ΌRrJS߈߇uiʔWJqыsFۥǝ( ޜ^G.:S4bt?"}Hӿ^$ǞC>hçz76>俪5II#Lô|Ԩ\3leX2g;6@ FҨv>bl2Y#[iz@ ֨\3le@QfH+K%9W5[r͐VJ0 rjF!4f/`d+\ o5CZi^*V6ȹ4kҘTls5Ph5* i1{#[ jxkTJcR FA@ ֨\3le@QfH+K%9W5[r͐VJ0 rjF!4f/`d+\ o5CZi^*V6ȹ4kҘTls5Ph5* i1{#[ jxkTJcR FA@ ֨\3le@QfH+K%9W5[r͐VJ0 rjF!4f/`d+\ 'Ε߬>[R?롍%:&GdJ$w[2GFa3,:ྸG_} LK+/Wv0忔6,F $1crli4fkҰa=tQu!#U)|/EV^Nq߱}y=m|jGN"'~L] =}w;M@vO4_~u*towǏ~D_CZR:CQjmoKg]>HJ8̚=O+IPeс|ʩ#ʟX?J]̼KI>XzYϦ@/zo_6cYba!#kNE6< \/] Oȿ O\#f"Aȿ";N?ͺry'1[oxwiUWǟv{_: db-҉sC)-zdak.Vd˓G|ɨV:WPmJS`e{X(Kw6)u GkҝMibJ!leئ41Vhm@Y3)ML;da,۔&2J (Kw6)u =c;cĔCX飵eئ41VutglSRw+}6,۔&2QmJS`;cĔCX1ҝMibJ!ڀtglSRw+:FY3)ML;d>ZPmJS`e{X(Kw6)u GkҝMibJ!leئ41Vhm@Y3)ML;da,۔&2J (Kw6)u 2;}IQ3He3m7/C!BHirHTT0Y:6tWpo-ـǏߍ6="TXKhӒ% S*U뇷m?{<'gͺJ|!>bDi>S'~<e^n: NO:4n1]vW Kֿ/O;3fHO'տPzG G>硇[ôq biάe|AI}/}I3[?tIo4VGz.)j C _?5^;`2R?3VE*7d]^yZ ^ NCbcSV u_Ƚj oٹ/z/minm|4럤CxoS˟x"s iۗ ߗ'^gdIQ uOH~XM}3n|*9/Iejza WY2G ]Щx?ϧMzXJ=ͳSZ`3|`a.`TS`XSZa!]xڟ4zq e%+eNL&̛3 dLF'wC]w_ٰ'L5'NŧO_G_|DJP7ֿt!m|Aͤ;gUUSOHG5M4oN{ ru}6}Oo lMoNgLrK{sVk|AOH_8G]pa_׿{M9@oYdZ2<ސsZ{gϚ%0aTJ (s&< Ϭ'$_:2d<7\v>`/G,_l46+_l:~͑R.;? @#BY6o#؇0Y$俑F[#i?{}4y~[uGLGo>Ɗ7 J)c3gzLx0 úP=U+cgm׿s{c3a-0>Sc'\bU% ku1B߉xF' sk7ϸ>.Ds] J${rk>[iL)i1"^,_&"bI'ЗMp/O/YA̘iI._DZ@cn?{5iX/?)SL?c/15cOEnt p[?6>zhs iUnaO+ w2:G5|ک2wt9j3i>P7>$?ggLo{;r|=B%?W[nkXT,#NjosgMg0_fS0\ /?u b/k#qM-N,r w?5'ɠq_ ?B@} _`0<GYLt<n4|ȴj.uEOP;mfi횵׊wu׽6GsTo̝M߄Wz95//1wCҵ4Nb̬^qfP3NJg5G@E5sqڸV:18*W;ԌƵY5P@ܡf6j j5qtVcpD Td8P3wk#j"{ŁC8m\+Q+jiZ^qfP3NJg5G@E5sqڸV:18*W;ԌƵY5P@ܡf6j j5qtVcpD Td8P3wk#j"{ŁC8m\+Q+jiZ^qfP3NJg5G@E5sqڸV:18*W;ԌƵY5P@ܡf6j j5qtVcpD Td8P3wk#j"{Eda@)'9CQ TPy}T fT5/wk4f"ߗVxǏ/=M/=e-^HZxa46 1cJ{5YX|yV~m756> FAq_g>EWܞ71E֬{:ͤ/;[/#LxQ#o>]z%M*U.K%'4cFzrn|ӍO+VH4So#t*o|B_|9EFGU9>;M:ږ/>9/}_׽CanɼM6 Miޡs9jTǴפ8> +c}aFA_|#ŧSfH<ѕ/>,""B?.= ol3}M}ƙ輪2+.6RAObOi}Ӷo6'Q"sWb W+%TXGP` AφpWUcZ+wilCп.%ײ.dla@g D'v; Ef'M0$[ӗz)wNB~ ZƷ7rĈtUWÆ|_4N QGO;Z~7ie)M /Lﰣ(7 >kԸ%@H0Tu5-ca|'6!hRZVE Љz Q`Sx_۟=&M!1'M7%Xx+HupX)@73;5a<ۈR'ٰ3WOէI'LMO9AW\NMHֿptʩ[n6>8,1>y쏧)Sx_x7w!.]hzYg 'ON<4~uc#FHW͞#?K=sƉ?rd9[.˛a^Y85ʔxuǓG·2Cx݃<e/?XbeCO Ŀ٣/_x%"?jY_@7g<b;|.?׋qҩinϺk0o#K_ qĿ~%?FN}י4+ >|PL~b%… cG[Ruƈ38ԁy9Q[Ruƈ38ԁy(ذv T.38ԁy'Q@E[*UW38ԁyGmT]Q"*RqfWERuE;JǙ$hCvmhUž<6jd6!/|3O`*td=a|^"Ї[ۦ/b,ɖ:>':Hͻ:IO_[?TeOÆOOYqGHW^=+ L{m bJ#FKfkьqs>o]>bxZj{5׹v;W~SO_'<\*a"Yް*Q??:eS??b`aݔ?XŖC:)#'Z 5NOh (/_!Btj7o߈?tСa+>S_95њ'J_B59vm;>6=HϺ;ӓOҋo5y}z+xTJwownƞݿz[[y;0XH8 ~5ЭU7Z D 'szG0Ki56T&e':o uqN|=OU6<-^!Ҹ]k=t.y&shа^fiQT79q{H M/D.o66\%ssieheӟlz^Fu=fH_|ZiSoZjE:y挎#O'vnOo9GP]X?XFWgUG yNrWqdc9"5_f/M/17?jc`\G}~f/I xF:Z&/MeLkO\bA#"+Ip7l GZ ?>#&J/%/=vMuץ.v cYrWo;2mvuYHj-?M`hǙgҴƔYW›hkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR\@[ຉhkބR*_|άtܐ"T$a(jR{V2w$խM $)ixݘĒ\}e={@_zO6R貘6Wm?gεi0z}阼_?}Ŗ#׿}LIt[-6m[Go MM[m{ii}Jj#̧8StF8SNOt|[9I5y?ftW/K)wޕ>bCSLa<g9ӬY|/|4z,?(O,{<Ç!=jOy-ڑobtرCX̴~jĒze_/󟥤RӄSۨL<7X\8{瓌4 Y*b_Գ7S"F7 /o9fI6WtRԨ#)_EW_ن?ՄMF/ey1鑅/5Um ~Ҙ[F~ߤy-t4_Ș,l ;ɡul pIRv^/xFE .`|RގY*΁0D??9a DGa_6Xq9`8_ȃVɅ4_S)UyG6>QR~leڛ.2>Հ嵎uL: _· }cv, m4^$pOGZ ]i ˒yيeim?w޼4wxZK6m6X]g^!yM:wcFB Y~ҿ}`qǝ7c꧞vC_|-S+V.O4S_e:ڷ tA5 NM4s)e/{+q E|35wvر5xE]HKOq>}Hrp>|[v:HF+ذtꩧ׼oQGef_s֦O]K_9^mD߂GԿo|cɄ,?/W?`?- _?ͱ; > /\"7ߔbDGߑ߸4ȿ#.N3Z;KW_7Euf;,ZOlI2'#PtԨҦn ݉ Gk&,c9݁DžzUX""QƗkp8(<\o@%"d3Z*?|_2+h,^mDċg8ijV`W-{ v=ųgE'*yVUR^  N{5Yc_䑴_,' Vkoy_#II#|e+W7bz Kc+5rl;f;ڼ<̿-"^2o@Z䓃nm1jeל[ޒSHOX0IThyW2BC?XQ c +r^?_/I k3?#Dcm_4w A 7Jn3_$_x mO6OM "{-, ON12)g /+31א/!̇9dJ*;`!r=1JP);`!O+zb&R*%vB@WĠw:ϽmKnɖKImV l!Y+kM!$^WvUsmhΩ|WyeKfX̝ #3oau5 ϠOsJ<2HO'3O>F;h##.W'^P v7W ʙ3]m*򅏈R9q0٘`^ pyCܝS ?ÃKlL'w{ 9rPE/5uŃOvĉ[$S)i<5@!}hU9Q4Z(PїK_3;yLş'+V 0b tl+"B'0U䜱⧬,{)RMVZj7*T[E=RpɲΞv2rR!տU]6AwX?Ou^AƧCs]=34s=aܑO' mn/Z,؅ 'lmXHpu(xg.ٟO%ۘ!&ס68 v!hi={B{yHE[.LmjEs)?2:+cu}u#H\ 5#?dKL᧭q7u]xS6%~iͨe>,4Gjі ??)Rc s*T/?o?3sG;TTƠ3fB_)sDg՟UV.Ag՟ceꯪ+՟3/?h%nz)e=[AT! pXRAhU/o ڋ.KJ\_i NfkSY2r'܉]2|=,'lb1޶}A~;&M ep E`PGS#x*wで;ҿrfi؟?=١'#SKx7.f/ߖzSd+hAʿ9-O(VM;PA/ʿj['՟,<I7jb1 ՋY02O*vc7 {@\+$E|w`\+rT݁qhUFR XwƵ-WI+`׊\e$E|w`\+rT݁qhUFR XwƵ-WI+`׊\e$E|w`\+rT݁qhUFR XwƵ-WI+`׊\e$E|w`\+rT݁qhUFR XwƵ-WI+`׊\e$E|w`\+rT݁qhUFR XwƵ-WI+`׊\e$E|w`\+rT݁qhU7>۹PMU/p#Z =p0NlQϢ/ü[ (ޥSc-7 D_?G^>ʿ*T b,:5Aʿ3*dS7RSA"?*TSO +m!)J%=4 _?a viUScGnsZ?Ӯ1WcL0revbpVpW4~('RR勨$Kn\8L@3- 1za&@)b=$?TU`NYaSd# 腙`m[GY]Az<>ۧ| lT6\}?=Z^6qH vn'/|v1'#"Ah'=e$O8E/i>y[/埶|Ioߞyoʿ3׊$KO^mh+EL +fL̓?t?/4h>RTPQ/BTRIZ2xן┘=PăOxos!Z*Q ҿ&b[<9(rlZU!'#j!ɞ끚 =EtV z{ՓdGBL f6iGyEW/Pآ&.A [|e=kCSҿOO<|u4 ?I33*VA'˵WoT5A'#Ⱥ1+ʿUPA՟rF*kꏪPUW_UekAW؂?p4՟ Zk^m@M 4R|+hh)'ЧU*/~%] 1,Z)cX$疒3¸ikק DK?ͿAGͦ֟jWA(PSwOHZ_GPS+,+\ꯪ謹c-?hA/ߴ'۱Oq_c\qvcgF,|%LҌ0CMh+4% lͬ^!dJiӧT`>aZO`TS\~UT`r/_?˝= yz 1 Bp zeÔpdP*^a RGah{Aca: Xd>6" 1Y6a@[~5fcH~hZ_ao[/hU [?+Ԋ,RS7m@oPE'߼hs'c UTSBGpVUW_UAg՟UVYgQWbHq'Cf,D_J+C߮_{82ʧO.nMŕ{o{ Pb\bbkv1HDG;~/8 ?z#FhUKoFЂ_?#S`'ESڅ=TI'՟T8L՟%ˈO?O? `t~Y8q[K/lj.uhdz e)Cg(8p=xi0ڴۆ 0ja/#߄0;g\m1G̳eg|zj#b !f8 O@6ߖkt0͕p` gҗ@!UP'⯮[9yХS7ߦ ?h+MDFmOvTUW >;l4c[H__CB:CK#U>u>EXŵ,nQ HXm MP`_{sҟ/L7TT-EjJh`~"0c S/f֟S?[D_np1M O;V0(]0߮^Yٟ4?WJsZ(r`˧ԡmnjuM=v;_Z)(m@íê{5 S _54lV4NͭQKO ?h ~4GF/?1JI$4Nͭ*t}(V۝'w=<į<_>k-nhp԰ F[tFMPHjX lhgnCv$5,цpv3vC !;hC8[g;[I b!3-`Ȏ1vnh0dGRÂmg`G;c7p #aA6uFZ ّ԰ F:# -HjX lhgnCv$5,цpv3vC !;hC8[g;[I b!3-`Ȏ1vnh0dGRÂmg`G;c7p #aA6uFZ ّ԰ F:# -HjX lhgnCv$5,цpv3vC !;hC8[g;[I b!3-`Ȏ1vnh0dGRÂmg`G;c7p OYFQpq/45ZkQ/vBH ?Z(KPw)=VCE t~xD? ᶱfOJ_a~p(TwPV[7\@An/kϾXNt)VNCoL.l>pg'\=[۷_l;h5;\yUxh|Ӵ 1Ξu9$VĂƖlA'{#6R5 .@j}*-<4~~&_92pq8RA&XdQ:]Q(`?LwYJYnhUQ&/8 ş-WC__?$(VQ˥~(=R?&TB+=SA`SB'ҡ&Co=⚱PSoʿl{7w]F^º#šhg\^bJ)ilsb^K@;;^'uNᚤ:_q0aCW_2raT[/?SjMEF bVꏪ?H#t?K?`EO{R'tOVerJh4NJ?lZugtȍiɞ7> EDX\pNIēLDr!؉$0 B2ƍ6EC #0I`^dm@F``'( 7 $N$Qx1n)IH ,$chS40;FXHƸѦh$av" +qMH DW`!F!؉$0 B2ƍ6EC #0I`^dm@F``'( 7 $N$Qx1n)IH ,$chS40;FXHƸѦh$av" +qMH DW`!F!؉$0 B2ƍ6EC #0I`^dm@F``'( 7 $N$Qx1n)IH ,$chS40;FXHƸѦh$av"H:T]ui7^fxʰ& RP*Sb~m/4:%EOY#^RWZ(K>+r$@qi[?*TS'׊v(,kdK]JJ )T PgEΕܱ8ZOş?*Tš?RҾBa?8Ys%w,SOş?rqhϲF6ԥP32< wj7<&("9%Z\={ 2'tj2MFKktp 6Z4ٟUp! 44J\:kg sә붛|?~;3C`:៵ lW+ ) cTi|%, ?Z(Ri~D=VmD_~zghOMHOt/oedyooOTͪ\?PUTUg'3H՟cGn<PH%]ȣ$ m= 9)3ƫgLbbU7؍f%IE%UL'3f0E9xRf.r & 6444'TP<'e"`&W8x|^,2,~/wrG kH,8olE_S>F4<1WC?БmH??OA݉hB5^X*V+C*U꿪#aTQGg$ѪBVLPQG_˧?,EEꏪ?#!TUUW_(nj2EcU]" \&d#u4+)sO.-u4+)sO.iPGSQTH'Ia4Jp $ܓˤuk1i(TH'IaT!bPGP*)sO.²?b7waix36Ҫ`ېٓXe $'4 (C0ξkMj|&bkړe?Zr?oYXH m⸹vRG *V~¼E*TSO?3Oʿ1y6V|9^[$L\GQf4~_.h!8RY 8=(3by!ҿ˵fFNꄱ9|F:}GpYgp!=zoÿ|&ϖ/[W_EoH pƧ>'"9S"9/4hE\COZSv[ =9.修_'̤K?ٟ92Q4hU꟱9Q _?{~][Gy _ ?*VAeTE՟UQE_,Vo-o #50[-TMPUW_U_Ͽ搪.q}jcdɁ{[@H9ڡ*m%srsvRNvJjcdɁ{[@H9ڡ*m%srsvRNvJjcdɁ{[@H9ڡ*m%srsvRNvJjcdɁ{[@H9ڡ*m%srsvRNvJjcdɁ{[@H9ڡ*m%srsvRNQOxRwYʴR6`Wm45{tO8^.e?g4/zі ?Pb3 nc$GR*VK'H[ e)j*QE'՟TR kd$̺*V!"LcTPA՟S_TQE'FqQogFi~OB|c=qgO\x&h]k~Hdu,n63IALftSt O0}` @9Uϊ['0nMm6ُ @IDATI?48N#[s1%"X{8^aMҿOo D[rk_?ׄfk+VKoTQ59TTWoߵ`5'+jM3heߵΙ n?o>1hޖ7>D^/wц s񋠁]+bYlCG /D*AGGWu [P\ao(GX%Y'Gd(ȇ7P*x ]EF+e64&cIW<_a?c<Oلo'TRMGeϪ?^UW]wQAJBfO@UF 1՚'onr;pz OÙEW ̣O.P.YΩB0qyh|CCcцDoC)@H#kuMճs*?B tgҿA$hCCuN'@HCzu; (PoS '҅`<dN64[T~ t!8<MըZ.lɩr}܋H kB/fs=0 .h& Sv.E0ys(?_[~rӋpZxz/şx`R_?-*VA՟TSM7,ݲU3PMG_UXQϾ3]r٬C \+?IXA3zȍ1F{Ek>RB lKFbkf5 فvhRVAlؔAМu M*VAlجdB ?*#ڱzҦ@irc# NA=oէRMČ݉`scv5 Y6[N^އ ԼA 9Ɨemh5A}U$0?Za?)륭*pR%:_?(hЇ_ECх>=c6}('ş\GCJ9*T;,\10V ENY(VC/-ߴOCCGKD*Re!U 9wes?axRQ.zQ*d*4^q`cƇ7* E;+\8 v!Hҿo>mrnVĹB ##3w?)dRgaOp oҰ_lf=otq֏i(">}5kק<eWS7_'#GoD 9ʨ4QTtOYD."P XK\_?ZPATPAU/\{ ˮ]I?O̯/UxK\7TSE?vWmXԹDǣcp ,̋5"s|>zv2!/XXq.Kƒ_w ;9KƒϙoEh%߬SR--7c<'o;) )Ā# w\;(j-O$FMlL/bBhlXeqzbAGϐ#|b[/@#5>FR XwƵ-WI+`׊\e$E|w`\+rT݁qhUFR XwƵ-WI+`׊\e$E|w`\+rT݁qhUFR XwƵ-WI+`׊\e$E|w`\+rT݁qhUFR XwƵ-WI+`׊\e$E|w`\+rT݁qhUFR XwƵ-WI+`׊\e$E|w`\+rT݁qhUFR XwƵ-WI+`׊\e$E|w`\+r Ov2d䖔/~O GCqA_29XD5>7եjͿ܅5ݻUGWOZP* CO?"nT>/_?+VXmu'):jʿg7SHg(Boʿ5) "ʿ+V[o,ʿ-FT24?Tz|OǎFwZ?ac 腙`OSٹAX]AHmvJ /J6 /qH0Do9:$bL0ٟO6gSO\;W 3rNUUw.|F۠M?7T6PqmˣZH ^ƶƗe?FBG_ւLş,+fyGFjS'ZgP?)RK/_-PS'f1-) +Z˹)l &ʿ?TM+¨//Ԣ'H},(h)?<9稝C$mU!ҿ&b圣`EiV ?=';j*mxe[%*WOT^ -L_Xgؔ!4ޓ>YW4\ApXoF-?`-<__3*VNRkAoTR/#Vhߪ?O媩o? M A3aؑǮ8"#Ø.  pX1ȩIcp7G@J?6I zƗe1Ḭ&gO̝63Y[44oUo#}o~3lc >~ݭ? ~$:AȜ<'h|@iot7)a֟\?R>CAJ(OuloӀ~ Qv{4i)´ˬ ED]/*f[mM~4oj Q -PDgSiCYFӋOD']O?*d[iM~4Oj Q -PDgSiCYFӋOD']Ɠ165Mۨ7 LF 0MUm-ٛ?6 #;~WƗe?ZjU?+P9D߼I_TJZ&ꏪrpMFϪW?hA_-w"5;#w΂KCCE]-5C6f2h:_\OeìbTfΫ>h)'ЧU*/~%s6|CW9|Dnb~`H_>"I\f?4^MK>A4/[Mh@C"܂/ş-(XYWS+,+\ꯪÔ,ϪkAeQ;+Or:Z8Eٿ{gɒnrk&iF&fJ 4OvvրoFh+$è~laZ?`TS\~UT`r /wDg+lY.$ 6o`֜rL܀e_[NhG??_[p@&/şpaYO&;[D_TJa^o?,Rߠ?GSlT>.?!hW_8,V˧JTQI'v&w>'p!ԕ|9=B\åq 1Պ0U'Q ^+Hq g{ʖe1J;w(i`J])y'B4Zuo|rC,Re8> n P= oUC2y1b=O4/Ô-L ?n@Wy衣Y+&A13ݐ멳qv[RC_sK*T ʿ+V[$,d813?(f 6AOʁ?%TPᱨ?7>ʃ_,Ii'Ki>շJx6Cf;8:b$5ڙ&`=;V 05To'4iҿiFgQ5p9۔)X^Cy s/c̍t.\7oQJ_\y'lº̐܌HDަ,Y=4E`ϾHgQ"~Uzy9e/Ch5ms_ +phBOV gO7ŲWz ǿmlm@ qnpl__A":,Ok|_qfhrUk֟jUKoʿ@ ?O+8TúV=`Ў^[PYg՟U>eqH n4k|_CϜC?q"cn릡nT?)d"o?+VKoTQI'՟<8Tɣ*EItOWJ;w]ewtj|ѤٟEt"#ge9+Q+￑ :*??Ϻ[UK9\SU\x`ܖ +?M, jtCJRTX$ٟY)0Jj̀!ۜ:%bh9ujK5V_0ڴ AW׳炩vo/|iRC;ş,%mnjuM=aRlYi'??D[<)S'}f> +V3LOmYUPK;_ʿh ~/_?[t]?-(Oʿe%M[VS4V+ o|چXSa(n.B."_m 0dGRÂmg`G;c7p #aA6uFZ ّ԰ F:# -HjX lhgnCv$5,цpv3vC !;hC8[g;[I b!3-`Ȏ1vnh0dGRÂmg`G;c7p #aA6uFZ ّ԰ F:# -HjX lhgnCv$5,цpv3vC !;hC8[g;[I b!3-`Ȏ1vnh0dGRÂmg`G;c7p #aA6uFZ ّ԰ F:# -HjX lhgnCv$5,цpv3vC !;hC8[g;[o| / yN97'J6aׁq t (\'JK??xJt?Z2fPKgTۢ[/ʿ[сCU2TQI7kEW_UUUW՟=^VxhA'?iIOQS"_T/ÃOv?+oSbo|bRjL*htXǯl }z%gNxBD;.^pəS:Pg\r攎'@1+"9 mpz%gNxBD;.^pəS:Pg\r攎'@1+"9 mpz%gNxBD;.^pəS:Pg\r攎'@1+"9 mpz%gNxBD;.^pəS:Pg\r攎'@1+"9 mpz%gNxBD;.^pəS:Pg\r攎'@1+"9 mpz%gNxBD;.^pəS:PѶ/,Gۉ.nFoou=`E3 CY F*_Mql^>q/45ZkQ/vBH ?Z(KPw)=VCE t~xD? ᶱfOJ_a~p(TwPV[7\@An/kϾXNt)VNCoL.l>pg'\=[۷_l;h5;\yUxh|Ӵ 1Ξu9$VĂƖlA'{#6R5 .@j}*-<4~~&~SsDvp̥hi;˃MtٱM1I8?xW߻`CZFڵo> q ;?:*dZsIzB}z0?OmsE?eB(WPMzPgW/*>clJ}#mA1!n ;;^'83ᚤ:a]r#=w1uWJ߿O{?_?ZcuT*PW/(U?LX#SK??1GY:]sj5DIs*lf?7_TQE_9qaBhߪ?#T}ؑ,S'{4uI\j5gl16C #0I`^dm@F``'( 7 $N$Qx1n)IH ,$chS40;FXHƸѦh$av" +qMH DW`!F!؉$0 B2ƍ6EC #0I`^dm@F``'( 7 $N$Qx1n)IH ,$chS40;FXHƸѦh$av" +qMH DW`!F!؉$0 B2ƍ6EC #0I`^dm@F``'( 7 $N$Qx1n)IH ,$chS40;FXHƸѦh$av" +qMH DOtlʢ*_>maVTjlOv‘C}QhREvj\ܯRӧ{þK:d95)b_#n8sW:GiWgE} شkVZaP5BF %zߊYs%B]ߪ[o?l?RCi؂Q٭"m%*+[?*TS'v(,kdK %zMo޷^ӂ$SQ$2@gSZdnXMfi|voIvnNb[kԁ&]u[Wp_8MGGg3'G|P $u?Є;m"zp}xA0ψ΀9,?m~%z8p`{J?"o|w߾8NuMN[{?p~w}g{?wߴo^(}ǧO? hbfǺ*g[Y9S*Po 2~`pD/ʿ/4854Srp@Mʿ*,PmNSg,t?XT`opTAT,6  l/6?TRM3v >5hrх|$f{\9)3ƫgLb_iOxO,E. ____ 1IE%U >7ln{n/wb'r*h8XՀ mn6"߯q5i'fj|Ǿs7]7=L~lL'N;;OE/ /$[ox쳞[ޙx!ٿֿ_O a~*ycߌM)Gg(Ui;Z+E2hG.@P\f*>SM ʾ;Vh+PՂ ʿ)R$(6FPA+٪r&xכd6 K~T w{r:f6)XIN{rnu.mPGS* 82) -: h** 82),C:RIN{rAn-u4 * 82),*dZ hJ%U8peRXU@uMg9id@fsfɣ>4}}\0ۿ>Mg?,»{?~7n8=q?,?}IYsiٴnQ\->CǣjCgOş*Vg~C?_k13k%5*PϺNDT)鳛OB,ŃO5ZX#\h HBd/Z2b2h|_WJ} \ÿiiii`aZ8 ?1guXWږiį*ŷzlmi+^Y \鄱Yz7__z߁?|wО֛o?qp]<2_>]2?Oẏ6w=L۾ѳogg7o0-5cyUѳ?_ؖ?GW6(tEG+R[_N]_忊?,⊿+ E=/?v?*TO?“+qڡ.isss?}]==ЃO)iOۀ#$E;J&{ @޴׏A %4~nA9@+ٟOuMu$P5?^: ][ƧvZ+LcpM}iqmkP5vO@9Z?ȱ}fL:S{x3<ᛞާ{ME߃7H}+~~sê_?-jlfgwOfŸ?0t{{{#f<Afih>Zsrϯٟ()R[7"jI?G;f2U9멝+_f`( /_?1/)R*~r ,nrʿUhUf/TPA?)Ͽ %qq>~oWSO>miCK\' ~bz2Fpv&T$gR9{Q;T ${Nz.Bi}Ui.ɞ rZCUK GP6x99po9)Q;T ${Nz.Bi}Ui.ɞ rZCUK GP6x99po9)Q;T ${Nz.Bi}Ui.ɞ rZCUK GP6x99po9)Q;T ${Nz.Bi}Ui.ɞ rZCUK GP6x99po9)Q;T ${Nz.Bi}Ui.ɞ rZCUK GP6x99po9)Q;T ${Nz.Bi}Ui.ɞ rZjo|*XNQ6fK9gWmoBvU B:oEP 5/T$S隿aZ/lSi?Ռ_{;={0hDct3[PiW^aS[?{?_ߴJ7Fzd4L \jL鱍hWߖ*PCG, 4=ѫiJ믹?p*ʫ]_?m4;>w?w 'KhRB5?>1ןϽa'?}]O7s?6}dڷ7NDO8lFz'{)-m–se ǥ:QOrh|緣.,“ ӇO3g5 ҍj_l(k\x&h֟3P淋؃OXuIR˭u₇_4aMvSm(nOWjt!{]xix?p}׺ôߺ}, ;O6(>|Iik^ψ›< ,~+a(>*x_i1hP`mş _(R[_.Dߢqc\SGͿ_T`' a O:?xe_==‹51w1q^?l:,?FaO!Uɫz1O|%)7'h~3`!R `63:mHgh)sSnձ??_8ߙ\2x2ŮZc>0>l&!VY (KyyƮM# _ʻ;;n">@u ..{ϟ8Fۘ􏮛v8P|k=ӧ˿ dw?sgty_>}1=r:߳/x} O\O}Sݻb[Mr7x3K/kA?gM80]vN_M}?"oi{6~ӭ:= ^/(̿ /,Q\{gS|??쳧K0`O]ߑֳΙqj^gCß|x:qb~tWL6=}9lϏ1w;ܽޏk6gsszUz-7g>.{mǦ[`۰o2?YN?xp%˿n|Ӊ [' ^qe}>~~<=󟟋cҿoynֿ9?wyK[7Pk}?X7)v(QPWkz[OƠCǣPtZS'___?*,|ߪ?"g~g=}+>q?2˦//EO3pßM_A~z\{'Ӈ?حL~cVx'Oxկ~t _qAxo}{;![?sx!3ƹ}w|tgCI{^N&;{z a?ʣxxGG m_Uskϟ;ϔ}ӱ[n2o7=xe|WǬS|os豁:[a|5\u}]XqC6[LsΙ~oyf],7yE_&Ւ,<;NL_Y+~o73U|z+^1߿]?'~ }Cxep<7o|#Be_7o۳;ӯ/ϝw5}?y%/ؘ{_?]yʼ*g?2뻿gzKo Poߙ>P@IDATL2?}7O}—?kޡ7x%Cxkٳ7}_HmdN?n׳b>f)_>+H)4v(Ffy8dЋ$dBGDNi9KY’6+@J9GPVwO^xKߴHo~2*iWsWROPT&q6BTAl 1('e.HnZ Zgߛ3};q6ܷiO(7Wc}G>;%!=ӛ~gzd4]vƃ 9Qs|!SO.؅MBC5z),؅ KB\8 v!hiiͧMέ2Sԙ8Z(򃇽IE[F,?+l[tH|2L-ُ.j<4oV~яWzz1zB ?z)r%Ӂ/F\u{- %o1߸[_u_;=A?-xѹz&zMM˷AL䛿MOaܛo:2۳/`z1jJPѣuNo/p0>xt-G|/w!}{Mo_75A;>8=õn/^_9\{@ˊ"}r03ĸ J (u$I6U\]FCR2y{g'"wf:ԩs6?}ئ>IczMq[o<{&ls_at5>Qqe׿hsyW>F/yu?k$Ooo(??n`:p k{*Ҁ,MLFPHPd]?h /W_ͬ*KO oh,y.$_>Td]Oş?a۽lP*PAC :N뮷ȣ[8?Ζ_amcIK9/vy~I{0~ uδTLxt3?3q=v|s{hsO Oꂚ8Ӿjho O'Gc s_7بP'1)O1-kD'1\?`7{ƚmh)bhc {GXalԮ3r ]L['-&f^|I/nQ];OKK-LzɴqHzӬk~Fy^-P 3.>Ǖ\ߗt?o.|^E4>閛niߗrlzW>^jmPO8d2`=Jx+Mskχ>{D_e?2w$mmK%{ 7NႤ`}ܳy4}cz;OX$ڵ\ö¦0謳M .J럲%/o{[v׸LqנnNaPz葇nIONˮ%qobA~}_JкM7y 'L?=4mr}߲k5X#}_4wyY'Odޑ~&]@.\ ZBsڐ{aǧW>J^xDlCz.Ỳ_dEҩEݐ̱>ǂ3>|c>_>/<mnVxi6pcg??3 k>1>O<(Nk/n+hh` `@U=6[m+jbƆLX/?(s_?7_4R`J)֜)RK/ş>/ҧP&_L\/KR%EkwY'~gk;6H|vvcB K-MzKo}k͜avCC 9 >r!'aGՋDJ _ŀ/ 3&I_`#电7Eeq2+ /`4>P/H$ _ C 1e/̄/]`O.Oǖ1maH/hyOKl/;?/|2'gԡ?t;ᤓ+.on:^¨ۇopKNeW'l-n7fqVZj%ݣ<*]p‰iW4 hh Ӿ`Mwq!H`?W]>ݩ;֬L/?N;2δ;Q=>Ϥ)b0͌[vt)}ag=v-y,Wj:ӟlFmgȡ( ~ye3cWq+4y~κCoh}In9n}$]ps2?Bcz ,hZ Ν޹%wRry7'jܚkO`g>OiSY>pkciMB6qxn\ӋW&f{;.iX}J뭿~xQʱ_{dgaG3qag3[j7t)u1WV# (wgu9<+Y(āC?(s%~kZE/3V_+~ :}Qݕm +MxpoϵH3*=kZυOIɧ<_ۍʿ__Ci 9EQVmQU+VU+mTU}|`eJU*bmEYFU F[QVQU+VU+mTU}|`eJU*bmEYFU F[QVQU+VU+mTU}|`eJU*bmEYFU F[QVQU+VU+mTU}|`eJU*bmEYFU F[QVQU+VU+mTU}|`eJU*bmEYFU F[QVQU+VU+mTU}|`eJNso( KAb9~NIF+I\ǯ~Z@*WK$iX%y S6C^_BJ|$p 2 +Kaw+kT?hߤU&S+'oO"`!͹&[o1Mo5+}l6w|•7|swY??&W8#-R>.I:0M/]=fXMSN5C>oIX?`G?[ EQc?{m~ى#Qۼ]'gBig~-- #ڳ<.=yA\Æk5wGr'>o3N?Þ?jп l穩XDG~r^O_n: MAT򎭷HsiM*{OW_yu| Xî>{oq?S@ OfԿ J$Ij,A(HKk?IڼFaddd–6BkyCo _?|3G]Q/_K)j,/_O?cT6Q(T銿_צֵX; ogXt=4qel>N7OJw}W\.`w+Ze~_㪧L2+b P^b7c\QQ+V`-Z@+b CPH]cXeі=kPN P`J駚3bXJsvdjP?HR ;p?i9!:Nly"l zS!]n'?XkN]'M\zyҤ*)nw]?'>M>/5qb:߃>fͼyӄ4gwlmWLQ9gnlɄ5ljحi'%kғhăOg5=wߓviG h喳6_g?aA8{G{7oaWlĂyםw]{p~`_1c-;ӄ2{6=#dL/x\쀟 >,/g~*goַtՕ3ҡ؉ߔ xO?0=l}1T <,1;Ks+쾕en׼uMzjηmp5gwK`R~~OLXTD>+]_XlɍdaA0 ^׽.M]%i 6a!oP;2/|bGqTZua/0ri,"nk\vCg'|3럝?g.Yk8?e撗HbK4d܊~RJj, Ϳ8m_t5qV 3yV͢/_)0R?) _?vBoz͡Ƈ6[*@[?(?:|Mm Gy8Փm޿cZ|NjO>jkWieols{q~hƇt~亙WƉz?>Wu^ K*08`+;Kh/CnSx> ֐_MI?` )uBNQl/kgXB(AEt\F=W;)d?&ar[6𾸄A[ $4yuz(:eWie,|c,NOlςˤ§DW9\`0}V[E i{}Oa-}N;O-Z;>;>O`z:6{nˤ2ÑGm_z{߇_;§Ӈ8q铇}<}?¯s@^|g NH{J&?7=wcu%%n{`k{Iϻ?EcXgV?ȶݷfJ'K[^Hs+_G. ;9o`%>+\|ӗ{}fkO߿?:a4pi 7:.1\<#Ҫn2g?3SDF[a'|B7w1? cԿ==T}t_\g>u? o?_k+g?Fz/'co5znGT>!C{ 0)ޤхʿB ?+ 8_qٰ_?*TYfgQLM7bjrg#Ύ;a?68eKFZgiV,wz?k LZH\P˞\ d(R< =EW_c(++1V[/444b㬌fT§Thi=ߔ-dnqk )FˁBkTͲsNA P虓?DkbD,Fl\ /IV<(o5~;vzz6V=ٷzD~d.LgΜ?َMԍ'p b,|½sK.|/§3na [&ߝvٙ ƨ'_-$,f3?Kv.K~ի{iyǮ>}dH΅OM19" !켵i k4 {\tE?nKRp>{ޓ޾Ŗo~33}_y&`'+K|Y򜋅psnk, t ǧW|Ӷ|gzOOO;+-.ιAk]{g/ΰI~ǰw|Ưoo-{w|Kw,>}|}|.<?tλH` ޟ~,*`uXcwi׿t?pq~FŧpWsGAy9g;>\QBX[.Wؒdޑ+oj%mƟMSae00)KvW_Ϳ2K +; +Z,Su&3W(C/_ϙ.Y?!}PBx_3?{2˥wg|2Ǐv_wME2irz[cn]ſFz[߆R҅mj~w+d!}I0,4To=ʌVWh%-*9suED!%韏?<Pu J?ļYc*򿊅τ2m={b9> < Q$.#<ׯ5ZorƫCR'5kuYLZV-œOw`xo hö,N݀lǧܭi}&Ct YH A.;XdF;Sr-g[E&sc5Ӯ;׿ 61,v±1>aq _m'#Y."ߩ_==-D:^t|pZoz6׾>E\l yo}J^ziǧeozCGvlӺ-:{mM_=t53kWO-~Zj)c15O| 6|3_<ӱn%97ygk~&M5(u-|Jioo?p{oҿo~ӿw@`{g}B`wm[d5.BUn 4ddeeeiQ)?9,ğF ΄o?T__0ͪb*cgş?*T3Oş?}'1UE'߆~)>|g 9t}T7K/|,ƅ祻f^sEI.is> ә~'kꟘX#++ۧl=e&F5ʊkO㡵W-➼jbkSeꨇ/KZKM, 4?J eAIWWeUJobWqjT,|^3ep_k@Bqο<yhf?RE?2cw-D7ƛA`~\Ock`bI>4[CIa(_@E__A] wbO<>! z-𹩄m[b%\;JbǧZN:rxj-rRXvO=_,"tY[nY3or_f铇h;G/{g uHqg蚫No緤m=H A,}/xZ}ո+qm{1H/x:̳vPZn؜6ۦ 6(}x+.<~'Z{K?t駵ƴNX!5emޙ|‹`Q9Xt4W]72P򗿜a[ַig?pQiW3{DZ}鏏e ??a:/[묻n:C7=} 7!Ay ~3^j|9i)Зc_ I{wWh맏`<q}>D<K_9•tL\)>=6]_u~,ރ{ 7f)ُGv{MW\qEzZ묝V_k o߭X@ܧ#Yg</s'wX8 ϟ_BS\8.B|3)Oi(T_?geΕD_?=CO?(ozVOʿ)+'8X_0?+6a`N/oL+>ys 9߼0;OV\aŴ+??inZd49kgjߍy&)}z۽4Ozɘqmr]a<gkz-G]|aۏ=!3T$edSocf 5u~i!Ģ%ΐG-\9܁\:QsoKc)ISMbOy &XW_sk }J˙3gbcޔx ؀-u;q3ӎh}d; v_;%.|FCA;R*LFߦ+ OӧoV).& t ?fFn>GҌ;P mmog`]wޙ~q/ғsLeiU#K>2^=^i>3/OW_u> i^^WE['찵vۦ'8n?ܗ5-m Rw1;.c'Ҏ;+颋.G%v@O`H/ 56eXISSG\|q .ॾ8*wb{=ؙjE[bg)џH5}]mފ<݋ETScԆnEq1wݵ?{{)ɟ 7W[ MK?s6n4d0 +gKO{VOn53r,\] $W_~*&򿑇wA7m/][7-C? -(ŃJ/_YK +Cdz8p_H}zaηwm?V\>݁|p/>~Ϙ7;>RC% 4v4Y c{mmSIj)d/0evHl dS's:Hq*2h5eaPaCNYCjMqhNH' )h$StÔZz(p#6](t)TEs^ G^Kxe]Jeؾ,-4i$5WG}p=)+xw`רXXL>~!wȂ?{y1{v6O8餴<-o][l%әsw|qxIi喷z;[iEMBZfeU>0?8Ӆ 7 3Xs'k~oۧ[k)`ӣ= R[i{,"Ӱݒ>qkӼ) GB`\wWҏ~^tP6o"Ϗr9y, ޻Cz> =,Z&; ,}]CvyaQ$g7m݌V79¸g>]6 ;LsBXuԑG|sijH~rvZ'YQ~EO?" !-_2.4orv?hIEy\ji)]%iob# PL(2h4gY IEฐ)SO8&*0N)T/|+y3 YΊ@ W:S?<  BF/[oN|oޕVZ,Yt??>_L6hOlS1h]Ҫ/lGAI-jUȦzv!.+_N?&Ӵ/Hbe]ϟhqtG7iSV}?~fva;owcݹH;Sr-gIݭSN c 6ﳒ?wN}>j|"4~~(}ŇCe_O n3dX0Ҝjq)t_Ϳbt.ҲOͿ?)L}TRG Uy-_8BG[ʿpf`F* [7DŽJşXy|0/Bcjaڈqe2ç&hIk|,HCp7hתZ!cɿKȆ5<-50ɵ%L:Ùd*a0ٟVڒuVL?H A=-|?~e0Yꦸ-,`bאQxd1A;|s6*)5Zw?GLZ ` ⲟͳ{~Ey" zZD7{nʤIiU<ǟx,]s/W‚5^Btv3E/|Qt3:ݎmqk`nHgcil2f}Lsҽׇd&`A:k^ttu>of0:!M]k}4]hw}i!,n¥/W4z(y}.g3?Ĩ?4r$S7&?OyGʿ(&2ߔTUs*79PK0ʿ.ʿ(D (P#)k4ߔSM7ߔsqoKY3Ą'~:|w7rtC8Wè/Zi,0Y;4Aߎ,Vv}~_;MN2=*Cٸd|n,Q|(Q-<4M<IM6,Ƒtf]nƮn+?&\ӟ??eek.LMv<(4jWo 69S814ffR e RY_%+s!IOߍ C1 "bF7L2"n:År,K/_va 􈙠\|.D/;'UȓU^?Ƒ鴥 P ҿf0 Ɵi/!0@`'$0|,;etk̈́ZE.*F)32-^i# ['M^==z\ĉhpq߿HWYlͿL<Ƒ 5aqO1PqdC#OeRS#+K?uhS95ju_%PBNyҨ {YմN>2DP*PC{?|tXLN+cWkSd@[:JYFa"VKK}l !Jok2K G!jEmr-Qs)(;\mT2`.eʵ@F̥tBsV`Q(NrrV 6*e0 ACՊZFZ R:!QvȹZQ+0xۨ\ d\J'99W+jok2K G!jEmr-Qs)(;\mT2`.eʵ@F̥tBsV`Q(NrrV 6*e0 ACՊZFZ R:!QvȹZQ+0xۨ\ d\J'99W+jok2K G!jEmr-Qs)(;\mT2`.eʵka@IDAT@F̥tBsV`Q(NrrV 6*e0 ACՊZb<<Iy(p u#9΀Q5/ rKH\Ƞא6D;xW<_yjiɫB .ٷߖfR7Ƃ?^1mozSZb%vыKwuW:cҵΒ`4hyzw&0?'Wl5jQ%+'&%C?)T3D_KD8GYU DBg:BOş_gkS6a,&( Wp}J @n Y3)]LS/PQ gS^w[02Obze8c4eۂq}J @>,.(( gS^,gاt1M@D`e8c4e8p>i ~,.((Ko}Y3)]LS/PQ-gاt1M@DYz2Obzm8p>i [p}J @n Y3)]LS/PQ gS^w[02Obze8c4eۂq}J @>,.((s/ƎO#4gޑ΂?|N yVzo(H1Q`,[ <Mq/ɭ9_pO oe&IKOh ~>[CSȒOm&*7ܐx>,|!3AH46<4i/ϙh#O_ Ƿ(S]Ecf?u GO᰺/ʿ(![oOc<޿>W޿ NZv|M 0W%g0~uԢlB5wP' ҿ242GԢtP (-p,y@dPq]kc֜ ՀRk@hR,w >/1ʭZ#G-\ ]r1 3o1Fǿ p9"*]G ?_F_Հ!+ FOL?9$8B?ݗ(T(R Q`mڰ/_PA}TBh )C!2;ϺfF#+e?KÖO &.(eʦlYE*3!;S >YlFK?=?y~tͿЉC6B!?L[aԻIL9Ǒ|{?qs9Lcݚ1չ$9bTk^/K8F_h0!G_91CcTş`Ԙ)uNEz )[=VTQGH!_O0zO}R'}G,S꜊OD4MֲR鯕5dh^lǧVRT kNLDY @\*h3gea h-r<o5 ȥR6ZpFQ`(6"JjFYX @\*h3gea h-r<o5 ȥR6ZpFQ`(6"JjFYX @\*h3gea h-r<o5 ȥR6ZpFQ`(6"JjFYX @\*h3gea h-r<o5 ȥR6ZpFQ`(6"JjFYX @\*h3gea h-r<o5 ȥR6ZpFQ`(6"JjFYX @\*h3gea h-r<o5 ȥ>Eh~j ˤ.O#2JKnFP/<GipTx-RA/Tܴ%Ɵog8h,z*mfZK(fTRZK%SO?rȇjrfrlFE+pjl)SO!#\ꩴi!0??QQJܰx[?)S''|,z*mfZLs+?{.CL *VE]ispzb~@ӖA86V_StȯvoNot-c[8VyќakW-iٚLidddZcf=1z n;EF6$\{M@<:06WLRT %(-4%b-‰8Cz?B*PCQE'ߔSO'(oʿ)fv1D,HiP<?*nVWpퟆ?Hɽ$+\fNG-sOsQ@( (Ѥ.EDŖrh(RZk1қ 9NMN-"^I4djK2EՂ4;Ϳ@kp"c\1;Xk񗃝h_+G嘸 +F> w9ɟOgƯ( ?4x9QM&sc-)TS?`&J_Q vQ_Qj˱oʿ)Fۂ_SʿPUW___6HXQv|jt֢*6.Vԝ>74\kzm`NjG0]D|KۘF f}I!wQ>K^6}I!wQ>K^6}I!wQ>K^6}I!wQ>K^6}I!wQ>K^6}I!wQ>K^6}I!wQ>K^6}I!wQ>K^6}I!wQ>K^6}I!wQ>K^6}I!wQ>K^6}I!wQ>K^6}I!wQ>K^6}I!wQ>K^6}I!wQ>K^6}I!wQ>K^6}I!wQ>K^6}I!wQ>K^6}I!wQ>KW +uG%O.vK( ׌ zݓ3Ue?P_ibӆf1+_W'!{RVK'_fGBF埔RI'̑d3FUmOJQ~Q?s*/ʿ(DO1רo?*s#\Զ |Hƞ,8n x[Fb}X5 U2$ICWYe 䒇te.iS4aca&a3lOP h(uj4x/T!CldF8aMO"u?lB/CoS +PSʿ(Ĝo?*z/zPIRzz|F=[wH` ޿͕'χlb༬v|j#bUd,q m43b4חpF&%(LOf\?*a`UmN Xj?IL^vūvsrā)*/mk&`8`nY` kED$WJlhLŴX._n?ܗ%S_?7X?C/x(Oʿ)Ȍ,m/pTI'l@I7?)zi? ʿ+ʿ#=J+%ao3Xyvm5WdU>'΀/@ɯpbҰHczg͐j9Sjz @C28aȯ +^G\9K>;_! :<$ѓ 5Sjz @Cr5zP!tJM/pBuyH\ҿFO2$ԔN.@pW3S^2m:򶖭-8D/IF|Qk DhԿo*#3aE kO44I8Ϳ?r9YLO,CO0PE'ߔS "cR(|L)SQW_)fx(?6]fo:S._UY'}˧E ʿ>7f^i]ko/(mST*\CAK69+(@] h Hp+ EaȈ@]TD`P&q4#++ "Xd.ŀ6 3zr'P$jyr.!S@hթ+"+]Y=lҿO)ҿkcbYHT/DsYr5אT W/l;(?>AM__?m |is&M8)I_?9(ȶECޅ>ѵk'zǧ"ˆux#WPLi3B~r.P]gBH;lتFPz$v40zB???]!+,P͋j_?RD-Q DHdd]_>( RPAPA&PA_8+#*zy@څʿ(M+oʿ>dB'ߔ{v߮ǎOͬ.}}<&u6Q1[/}BSLc>0ڊjjXZiZV(VڨVh+ʪ6U`>>0ڊjjXZiZV(VڨVh+ʪ6U`>>0ڊjjXZiZV(VڨVh+ʪ6U`>>0ڊjjXZiZV(VڨVh+ʪ6U`>>0ڊjjXZiZV(VڨVh+ʪ@q'۝ _+ 'E% 51拃ĪKu_Z㯕[ŠƺVGWO̥ !~UQ _?+C1H)T[cbٱ9YLTQf)1AiRP[o3v9ߊ+V[7&D#tO?Dt?zfOf^J@/|n&@x*B̆(Si6D͙PU)G mNپ(I4͈hí 6"kYtrn1Ɵo4yA6ƱF.(ٞ% )vROOG7h4h!+ކe'S'T!K(/ʿ(/ʿ(gIW˲pb#l$#>d:9.Ȁ;`QRb_1+ce~Ysppjks{0BxrBNQ55G p6A敿ИݤvN~ڗ-j<{B]F1L!(0kDC#OOg=ie}AD_k-^:X= BW (TRP[忔9}ň$rhBʿ(oeTM7D&_V]wZ: zRx.5s?#<c<1Fk sA`@'Gw>1Tr5/KbaE%-HYղ -xY ##c' +(i[A .|JeƟ߳}MYk]7>V؋~|y_. .A~-?~D:2 =s%huBAͤoMRͿ?UBB!(g{cDTmO _Y& _Y.@$h2%S7>) D7@9@TTY& Y.?!4?^)gӊ sx"R  ,O S,OEWP>/ 0 m{.Mq ss]:`HMip[QYC9b4.B#ό1ez647 ?#(B媌\-?FWGtz 剭6?0j!+?+P3DFʿ(d:Ɯo?*ْ#%5Vzzzzz/71R1rX(w~9IVfF6>leFs[tj^鹡Ё`JuG#EzjCQfbTdekOQUWz&qՌ/#G5'דO˪ԕxŮCԨFYdz|؟)kMgtY@2*R!ȿ|yhf?PE_Za:QOoi58?`a]̂⏁w_?+Oʿ)8 ɢʿ*:4(zQP-ʿ*zzPEf|j޿<޿j:J:8rdl.BgNK2!SYPDjl@QܐJKTZ/eG :Up5J'#CQۅlvJѣu]g%##k^V1O.p\$/@Qguy Ѥu$:4^aD%Db h4%_3(c?#}>u2ήK?(P+[NXIş?fAoߊ+;1oF`:! $zzz3?(CPAD<[|ł|w)mSG3d`i#*Sgf3/'/{Rh ~o"4$Mo.nq:ې©POGJyqcfecq:pҀ?kN]ۓCwF]HFDDw&̒ncfζhk ϤD] ds#Pg/C(5ddms^ _s+pBO߾XaC/şl)VX*9(O4ys^䂹S'-RIlTQGM?zz\x '^9[Wl``%JF谀LS tdڪ/%" MW!N* z"t_&+LKZ=rbgSJ]WDAIҔiFM>% E_t2/٭^)y,c!9dB1.K8f ZdpMƁ-!KoܙÝƝ2(@J(1CY(cE`rd#EOş?1W(T?({?dS/9H2(Oʿ)قQ~yCfY]yE/B(ZA/0Ժ^&ǵ-EikaԺA)HKQxP A7 Z׳CrMYk:Wi!8|:(GXV\b/3Nh0*f/K|phqhNfxܾldͿ?*XW1+V[;9hNxz|&W~P0s+Zr+g +8)ՉLH 4WJ=wz4=}S[&K4&b1+?ڎf?*ךֳG}#\'` 6##sؕtor_vƇͿ?../LG !+"bF7L2saoP?iK (SF6srKoMn(&li⯘7b@4?L$uG_ fIÎllvI~F'$Ȑ 4P4;fU/簅OVqn>2 oQl1 /E"l( -Y%JBh`| "P# /F?SMD[fp+SV/ +R嚑TyZ{Z Gc\eQ!k GYZRFZ R:!QvȹZQ+0xۨ\ d\J'99W+jok2K G!jEmr-Qs)(;\mT2`.eʵ@F̥tBsV`Q(NrrV 6*e0 ACՊZFZ R:!QvȹZQ+0xۨ\ d\J'99W+jok2K G!jEmr-Qs)(;\mT2`.eʵ@F̥tBsV`Q(NrrV 6*e0 ACՊZFZ R:!QvȹZQ+0xۨ\ d\J'99W+jok2K G!jEmr-Qs)(;\mT2`.eʵ@F̥tBsV`;>EH¦ӑF؉?g@( 9l# XA!v":Կ/5Ȧ$Rn@,#G/}F=O(R1':dP C埔SN(ʿ*ʿWnzzz/zOzOS.IfzZd|tgה>% j9k\0^㻼M@DY_ށe8c4eϺ,.((; gS^YWe8c4eav}J @>몳 gS^;2Obzg]u}J @uY3)]LS/PQv2Obz;p>i NuY3)]LS/PQv`gاt1M@D鳮:p>i ʺ,.((;}Ugاt1M@DYw؁e8c4eϺ,.((; gS^YWe8c4eav}J @>몳 gS^;>Yf^#|9f.|թFHϝw81_K%hIf~X_'JdasGhA W/[Jw+Pe =Q_flpwHɣpX]忔)3%}@z[o0z B:// hGşdQj. ߊbh(VNФG(b/twE8?HPtt`ҪBP(2'hVqJen.rp"Ab[IbiG˿*OGk ‰/KKS5TFCCS3Kτѣ8Uҿ6붍4?~D@GShРD8p0G:VXWE7\*BCr??Bo#?*E49WS»*-GTE`J+-Wƾ`J0j*јɊ//#GáPtu;6&ļ(BBqr llB̋r8!$ .'!>XӦKAE61*/ᄐPtL!-$(yQ'ڥ$dXA+Š"%/ᄐPtL+(TdE9j)`&XKE-i?jOW_}(J_amU0BAbFGA?&jII 1E??_?u?X2 0 ) AN# /ן\r'ן\r6q'aAiBACPim LF$?@?@j3.&‚˜φw| VXjcSZf L@`Cy]˻#bP P 8\OtMKcc&hRrr.oe꟒ ) \anXuer.?l'd6@q z[CLjop^0(?+ܥg4_<')?PԿ8.A'ua _\rMΙ@IDATD곤W}EAH _?___|/:AVS:O1eK@C@ʠx6 𚪴Q. Tr!h(z+!5/' (cNO% C\Q8rMZRԿ șU8Ww@rlǧBlaexqUgF⚸Xgs %T`g+'UQLe_/'OoG P+1O?0Kf%/H /bjDZ@oǠ G@lAk_/OaE+̮SYkλ)(u=6V(+Pm0#1l|y/+K PrT]Ycjbχ4?&+T (6$UW{>95XZ@9&!ϩ eʱ .7IՕŞi~NM8V(+PmpI,|HsjBYArlMRueCS c\n+=pPVP-rT]Ycjbχ4?&+T (6$UW{>95XZ@9&!ϩ eʱ .7IՕŞi~NM8V(+PmpI,|HsjBYArlMRueCS c\n+=pPVP-rT]Ycjbχ4?&+T (6$UW{>95X̩ڎOԭSD \(rO?P4Bj^1( Xj"}GC"N UQ(8([?Ԗ /ڟO}E )[gMUB' s/uՍ,?Ph-)'GĚ_'([F#~5OeMIp@ԟl\ ^Qpd:Cu|ЉGЧjH?ơc0Ale%bA;lL`(sVGf?0^JVe03? Ϳ FUEJ0\U8[?EF8J DS7n?w\@ĹM1WED#ڴO'F#|/ ̥o||T-߿;߿Ho__?{7e!v|*WJ˓VEAp/E8ƺ ,7*LC`ggz/G; *οgkt%YG9KZlNjYdJtb=\Tw@Vu^z!}Jʟ? Әv͠ af`KI~. '[`q7B7#:1iXIOـ'LOD?/5YewIH'dU=3[פmQ 3' ~)JrV``YbHxy0s y=AwyEZpY!g==|rj'C^zBN9T&Op;+00/WȉC:4 Ncg>P 9qSP> p׳mykm[c%xpn`ŊiyqYg9 ~]E%ǟiS(?* Կ6OK#XZv#3p'&isןNZ_70!L oO o?Jr@=JzLsx3P2J1B+?~WV8nvjڹ[{nyjOɬB3 U qf R<1-'5\zxzbAͼƴdD 19GȊ$1({aLI>@3:O !ep&ŴP=IPWJ%^b%0IiG;>%FyːǛb9N{5b H Ο\`sJj+J< W9lFJ8HDbbV@CCS62M UտwtfE?Ұ_їH(Ĭ.PYWԿֿ⣩I_y8CS89pukAmafeP'︨(42 %\`Y,o3j?C:a ?@?P*Gd/ Ma$']_ "7S- v|*f`g}R׹ۆk|dVQO% TUXp 2 n=52$')qT|jR]Q] HRȠJ%RO% DCU?7 >Ru?ko.K܄]u@T*s}#kg . ImIWPa鈉yDS?jWCο΍"A'o? 2͕vU#E07g3D]9Q>w07`ʽ0{lH'5*5T/.:2* g-Փ釚ЭW[E$}GCuM  |bĊ/_P_ۘRePe$u`/a$N> O3 D+ AP@2+Q_ "VFYO1 zNjtqA'oӇ\(trЩ/?Ġ70GAĶuI#|J+)S]?lv ĂGXⲊḠ+' гnZQ7>9{8\fz_f\fz_f\fz_f\fz_f\fz_f\fz_f\fz_f\fz_f\fz_f\fz_f\fz_f\fz_f\fz_f\fz_f\fz_f\fz_f\fz_f\fz_f\fz_f\fz_f\fz_f\fz_f\fz_fxdaEnr}OQ#ֿAA9!^Yח꟞-[ 6Ҫe[͚5s>eOh陑?fQQ$I^ .f9k8riI_l M# /OY'YW 6>|hh/_~W,m(Nue_Ǎv˔*|ڋ5ʳ& 9qc|j䍳‚U&0s^ pEkYe@Q4գNȗ5jkY+*D(!ekFm"Y1' H,JjrN9f,Qd5VU&0FQe(_Fm"8`|ɘpM;4I0^ _F VmBbr_<+,Non=i^?ӧNS&@/?. )AGfG#MsAY/A 0.OԦ4YϤ:Bt5O;\pjI њO?V_\;(.fOr'ן6l\po%G= ?R@ƍ {|lڕf%`?9*Rȅim 8aǀ>OQ{T\GSuccrQPs ~rk4aǤmXnykE!8I2䳑}zun H,Qp1_z竧ҳj?/o??ԿY%TyeWŪ=i_ONo|4B}* -( -4? e:үoKӧNiyP묻^lNMx%O6}g>-[ʊ+$M49s@$"p1+U J-Qc ײp #y>˯J:t`3ϔ &gWgylͶld*H~|?0qWeam1v2i$stvo;(M7gzZzI裏0qOx > hodp>#~eyp-s?ۚsW1ګŝwEZW;"Ka0NV^.Ykge5*"')5uipuF\ zTYYG5I 5y[lV! C~eR?4;kbBV%K+P^+Ip,~R3F҄>PXR!ߴҪU ءI`y߶Үz Ξ=S^RM6wҨQMJpW&X A{dر2ryͷo{q6lt8n?/ƶߔpw٤S'Y!<;}8oL_OHllq?Ћf4DEj%#?7_ `?hK_D] fo.[nڪܹse)<( /JdkVz!S-v| إ֕u՝}lmt1UiPYuT9 &3WqUij1`W.O2ο:c'[A2fW{?S ]:~z ~iZQQZk'ConӚ6 6u<h߲utуiAj_( |2a~t,N8^|sgrr0ܿ'N#;+zk\->/܍u|Au4AWM lIvU?O#_$(g}-m!+\ɞ߀iݪzƃz[>Ȓl֔?.ڳz鑇UK)N./66v8Wk}yҾ]{LQ /E~8Ce ?a| d,  >nZ VZn],fΜ)'bn5k?#i4*eᅭF.uOSαS1PmpAǔ?/ʹ?Ռn)H*/_iqV[?SԿwz@<>WyX1?8P/ZC P$,pg_n{~]0*sg˰) ~TSaoŎOAgs_aG=hL#؀ѬM^~+ں& %vVŶ>F8LXR6M?E*r$D $cY@ߠLYc0j'?A@\2wͺH}#L CDv+ `5$8ۂF N-נU;k[EiwZ ?K7wР4 $ec=ec|G9QĈKv;ի0XenUV\[V[m+W[৓ ӦinS_/fiV]er u}>j~ p/?4E7o!kmg^ЃZ?~_vm騥qǾ"Qiٲ2 cnj(dўfA#$8_ \_O%hK5ةNCr/]ѵ^'{HÎ@2fh8ϗyYο炗[nvuɈ{v4ۤӦBWir'ן\r?\|:t'ydd+s_s;oˈw|aՂJ-q7B>zRA#;eSۏJMJUZ@EAŦ kq$SL5vU5'U?ʳN-eTU'S+mji$SLu>9k[Xv!o_Ї@[b5Qd1qZӦ`=E?ঐWg.FJ3 0%u=yPt=M{,xF]ADwl#`ק)2uF_~#F#гhAn*og)͚Cu`$9az'v|wyV[meOOK}W_M.`07ߊ;ěGe$YNi"vsW{tG"_9WkWވ+r?Շ_;sۚ|]tхξ{HG B7*ƿ_?|%>;YI"YMg"i_YqY7b/_neRwI;iެ[IWxdM][ߖ`G3`"9ceoFa ~(Gu_xtgό>/ #҄OT _a#cGShZE:Կň*x/矒9$|$8p5_ |%Ws5FΣ[TF(PZ%pczWwN<>-/ ۵]WY;3O>@K>M3Ob'_>wҸq#Yw+QLq;93M4[׮R@ZFIH+agi2a9kF o7Λo.o/(0~xVYfSd3 ~Ϛ=5 f'xI&~b>mZk7cnBb׸qcirks̙Q1 + +@%2pMDԪ+lYuF#{ ;ﴋ,\PƎ}6Uj۬lӪekh>?ZzO+i%soNϿ zf**jm\{{B>'̘1 QhR8JoP4k*zu 2e7N>Z0]K57iԮs9vM6QVYue25^&?-7k"]JگL8;L\vh[q2N>WǏRr*hWƶߔyɘ/:n^k$wHp#i Y|2q섇Nb+(ҭ[t rU~Fjdܹ-V0\=wƌ Wִicw̛3;?Ԣ;y9YD$e1+~E,_YdobKYEsݙ!7mvh Mƿ<^~-"Ϊ30Fnl4z6X3{ڬIsij zo?glB/ҾIqDB`ė_6oy-q/ɿ_ݖ1mzzݭ nǮJCޘG* g21gp3a0) Jd J5/c[c=3qXtڤt(JK| XةXx ƾFvɾ?b@0۵_Oiw>hK=?-+bר賘>u vuz6]XƽgYy>E[ 0A]FCk!'p_Q4=T)?ϥy]M*hUKVD]$[#?_yCN&r7E`rIQO˥\FQH#-^t OֱA=dxN||,qt]ٷ1?Qn:z7Y{_Oh~qmԮ瞓c;AV@ + y2K5W& Gd1&1Y>t?_@rvvرgr7?ūu^GAʆ߿X< Z\wY߽=+3 v3:3dol+髻ŗ^K/o Ou=vfϑS/OW{?A/7B@g#m[ӧy'Nkwݭ9yw#=NbA4F:]hF&F$on_f`GyD]~l{ɟ8R=krAv} Ȩ'$9}-1W ;pPbw.ǝG۷  wpsr k?T9+ꫭaWAf@~ǞߛӦ@f.iӱP|_(:\ ;'׿*H\h%_d'?Կ:n eDvhvi i4\/W_ _f'3ipR ;4K` ?j_C*$ ;q?֟o1L"}Op#~ys=} 0*`G"$oN/8ntvhBRmLgEoC e=n1em IiPVkN[|_?;?V4k]lqRm$ChƼtnFh<*]jPXeYמ~;,_PM:J?1:2}ڔ7/}y imOu8.><4 |j2DVNAz\`ŇQ!G0##J6;sQY@K;/]zi ɺA/vt Vwt'}NJg-V~KUي]1C C6Lk|˭ʫXɓ?fGu} ?݋[3hhÍ7ʚkeu @d޼yFkGP3r@0"t҉vF`Y3g}t+`nIZ{ph/e?cr -C![a<9C>hA$ྵއ3q M_үt"5': 4; ̩3~/B0Qc.oذdT v^L>Hkԅ1fرUɯ=5+0 =W k`'߯eehug%9wk~C4D^ѿŕ7xtЁv)}_ O>DyIֹw' Xr~E }N]נo|󛩮i'"& (5Vg{ ̓nV['PzmN_ewC0z{ʡfosQW?ckp]uOI߾G" 88 ?3r[>mB^v[l7ot駦_ie7#hEoҜWFZv9Ro ]xQxI'g{|׮O}Pד?bi}AtN[邀9f/C.?\7YoEK}Vݿ;$r}޽ No.z:\ݐn3o1'?4h*Z hw֨(/pZW2rT1 k&|ގIRfpU0 */?`A!ƤLUpѠcc_?]A6KCuh[Md)WAhԑQu'~OX"pijͤZS*RuSa;"yrD9 b^Q'~ƅV?EU Ru{λ~gЛu]]WmPrSI YyU9-|0oio{&"4^f%݅MUԬEGH5ARLd OS0j 9 ꟨Db+?^kjX? N6]ӚKjQū>H@ለH{ϓ 'd-Ekc(> b(F`7BS^U·>f~?OkA}v|ݎO}Z.KMS?أeڴ&׿>&$oԩ4twгe.܂Ă:,.D fmn}be6~h Wegn˶FVN" h({}yg W#SLE)ygI ^5jŲv|R RwnCJC{xz!{'}v~r2tǧ5䢹_>Nk&?djmd0X9Uϗug }`{A^x9yp󭶔=4m1P*skiy B]ɞxqGwZcu쮣: -ӟKceWf:hi]TA;/<,f[{޻fht{+ȿ򟉸'd vi'鄝s,P G?\ OQ'̜%/8ZگjbvڧZvqw๯]mx g>Dye]IhWd9 %g`7oOJOZ_/\g7l˺ݰS0AA'Wy2v؝NnLy706>*Z9q1oцpb'!i2O&#G\/3/ӷ!vODPҤD?ܡ;#|_(T4Lygd;ЬyalC@~e7 ՔݿW}yN;*tXeXLO==ua`R=iS[n iٲtw_ ^T^Җ2e_|i_rNz)y'MVwS'Fc~8/5Qw.Ǽ`B{nO<ծlҾ= UA[o?{ˏsP9[^A7!#hۜ`r,=~ի7DڇStY#ٯ{xzݫ!{v:F=X^y\(["hLDŽ5aI~ c.*}Хŋɾ JCjß5Io~֭PK )@֋W_TK0?6P9@_1'?%jŜ#{;Պ+__?aPp(pGnxE[W4hΌbSaQ<#߁\pGP \p8Q CQڟb0b?eV[mcOڞ";n=0?m&7kmߛzC/">qj rQy5:֎ӄV*2墘BO9«=٬6\s^#4Tx1f㖋b =u䔆 :f trQyP՞VTlV[.9/ԑS*ӊj3qE1煞:rJCW{ZQYm:n(SGNijO+c6@-Ŝz) ^iEuf墘BO9«=٬6\s^#4Tx1f㖋b =u䔆 :f trQyP՞VTlV[.9/ԑS*ӊj3qE1煞:rJCW{ZQYm:n(SGNijO+c6@-Ŝz) ^iEuf墘BO9«=٬6\s^#4Tx1f㖋b =u䔆 :f trQyP՞VTlV[.9/ԑS*ӊj3qE1煞:rJCW{ZQYm:)̢öQpV)nsڝ~\$=v~y="rpWڗHew%>jO_~ S|`|[k.vj?;L:r[^-Yy|_w;jX.C{.`(G}ɟlGm6v{Qy{|r%觐5V[]NGk!JKSZćuDW_s}߿_`x? } "[n$~81j4i/Ƈ{x+q@? 6dSck1սGw;^aiСpqZki;)3Oe_l9 >7ӷ^啲k(Z[#Rbhߗ><] 99>;+?vy7}G@PX~C#U}qH@IDAT KU\su61i;vi :V.;ˉ'ߵ\-?-'̐?vo|;1^n?9C)[i#!-kZ"=hɢF -MEG)k .P<7#'w3l7ƭb8@[CGXZ_wҝZ Quv]?JFw/^O`5/{H(ˮ9Si@QPrQ/߲' /e]j?iE'oߴaa^/ZyW4|Tz*Sq)rB_vsOhCP4vx o~w&~v]wJRW7Ѹ|+p(~2ӗ1LWȮ_R\w2K3&f5ʒ" <-WAaʒ" r[_?^k,(P:tbxW(BY:~lyQcqc߮]=k+!iڴERvS bם/GЏh0ӾQ}Lhb25vKr>@WO.?@@IC{o#{|WUFe@u$|ӷJd0@/L YGV Ȯ{İ@^eifnHi@ඡɽ= q?]XŎO9p#Burv =G)#5,O됡v룱somIgyhZ +8Ds(_q[$`Hv TEH˖QDz|(Cm!+liٳ.?`ǧm TC̰B|-U{٥UN8AoW#%9ON RE43#p쾤ǮݲN4)l[p{Ilحa3gΔ^b׬7 GoLErGRg'i*_Pݔp_kh[\MvG7 b%Hy?h`<ЉO6O?TuB83M O-5d[e=!6CPYo o YxϽod5ִeN+T:xL!})~{,c!yѷ+Se Z* 5J4RϺTk@:=H,PPAW=4s5 24/T??_ A3(ʥ8ZR@HFACYN|*?Fj;B5cf|+lO:~]X;fZ!sLG'o>֏"ߔ:m SߐS&[e7w9Vi~B!H /۵cvi% 7u2{%sGؑI# @U2q6iOuvyvi=Gr}2|o!6?m`e|!>\yv~ꆏw_݇ ?ۯ'<;>͛3vn9Ӎuo B9b_~UqF7 e߬Y riѼ}^W=vj&BRu1U2vJШ;ݖ\:vuvFw/O :;PuW#3e'l䢋.?#8 g(H'v }Ye ;o@l[XA.ӯ7H3 $</v;Ktrz'_ˬ/Y6 v|PF!ヒQ{tz6^_칿޸zӽmCuSے1ȅg$m Br!Z)'$&Mˉ67;>[{ |uW+O;%6ߍn@[3}uV+iМbbYƏ'?hnFӪ}Fz hÍzk';Wn@*! sL/uOh;;?Wѿ7m&v)wb?wUWGt7-͚!%j@޿~Gȏџ0auiACNjʊsƎ~*r~9:C=+;3撋07~{B'.XG\;>͗p?(d<.sS0]x%c[/OxBa;sm~UWzh 4/ޜZڇR̟O}fgYMH2<?_c?/#eB2tƨS% ࡨNc:_hHKPL+a@:iE>EgBά}Mmߓx:''a:y٧ |xn2^/dwd.[ڏjk;o)?/y ]y鿉c_{Z!ן@Q{rzZQ]O?c:M@w;:\gyo1Ӽ> 'U( գ٥im /4oACοotꌏk?*Wbv9^"ZDɪףy8> 8x?hiqXcdsܯN֭v_!kڶOM{}ߪUk٤sXΚ5S&f>?nGvsvU 7f͑=Jf}0;Wu@:tӍ_ڠ eby-sJc} gϖ'ȨߍO`?쬂ݘ7HO ر(x"( ΕW&LL{ҵ҄t-!immǧyr AqHC~JQvÙk_q;]BsH[P8`yv2th-7&_+e6N3oԗ:ڶo]/_hfC?\qE{a#xO?^_?moTvߚGIf2?R}m!76^GǬ[ eW]w[cZ}]M@ap{o:ٿ?1qcKҾ?JI@Z轫_҄ S&e9t&TGHeT2 (#94:B*(I@F1 RA(UL5rt=M @:ePFsLiBuTPJ)2rc:]O#2PNkzP!Ru$\#Nӄ S&e9t&TGHeT2 (#94:B*(I@F1 RA(UL5rt=M @:ePFsLiBuTPJ)2rc:]O#2PNkzP!Ru$\#Nӄ S&e9t&TGHeT2 (#94:B*(I@F1 RA(UL5rt=M @:ePFsLiBuTPJ)2rc:]O#2PNh4W}(DzMԤbspiey>7ΞE_xAyECb*+Z*Mo'gg?}49 G~GԲ%񩠏@G`[^iv|{1ŐnKwG< Ux7̒C<6=wko#{[~H3슥?\$9 RrTi@xI|y 2Xܜ~lvuW ?*2Gt7EVYmU] Ȧ5m^sRk)7pͿԯ:8n0v{/ӖKzk ɥa!N> z ?Y;>m6Їe)qJ۷\kC?7^h塏'..sGq~Qp.}qm_ytנZ[+bϤg~r}2w}Fx"S! /i|'/vRukWyY:4];t\6ߟ+3CH|bxgȸqqe~Gɞ{JΝe͵֖F1:\hn9G0x0 Gpc5 ,РH}*ڣif;k4?C ,kѽ>> VEF7 Xer~˼ysLq[S B>>+Jx ߢ^ސ3ޓY3g!hsϠgկЋHuו1bǙR%e?EJ1BaΘ1c><3)!.A߸I#@>[I1v|v|*gCzbz!tva{"wSMdUʜyxtyM7+>)9`mPI5~6n+Hi@ᚭoF˯J:vh}yq}QQD_7o.d:'60ܯ2'eLivbנW'M29Q,SkӁbL飁OH緇t`;@  ~ǣ:e:m4/u]xֻ2{@ˊ|߰ ,  FP@M$?P7C,;Ņ%D Ffpe5>˼Uus}Xd;0߭[U]Umb?Ok`_63p}wԠ׽7/?)^s-ijדn+g\ b\.ȿ#L̹pݜ-.^{W6x#'bs w݅^6ɝx=vݵ??v8Ak-c[If'tܱǍm-9 p'O#W_6AIsNxԑK kV9gsםw9|}< '~-\w)/x l|}HO9 6&P8W?a_ OZ_yoKq+.37%cq?_"6+T/dddG/?ձq_c3M/S ["V~0C0;ASCOߊkP<t ? KJ{PX?WUuUr0<{">zx^0ů׾%z'?^ߖ/vտ.9Goz:"JLt ji/ObbZlc"Ot l%A%S5 * 0\1 }H4?@cn< DW=Mdge] okxn$Q }7:OfjbwD/pS($uqړ|5 gެVj҉Q^)F;Ԏ*:20w[>N;[.VW\q3Nkyi2_R> ZTxs|zIw۟P5y_RE.i";.;ٰa߽=;RK&msI'~ys_(+=n% ߆M j9sqsw4YI?~*6O=m|O|ZhwrÍ7}s4L{q7C1/ۤUO}`Du²6|Ϳ8ӻ&->coƦyV[?mﰶG=qs 8u/+Ć1׿5N]:}Q86L`7i/<җ&1E]X=N Y9*ӟ};^n[k/YފEbڽCE~Nb)?n?'o2kV9}\t5M9]YN)Pdޥ#uqG2y v{/7>ml߾k/??yq6>ʍO Ug{. xBX^"8U[쭶.oÉI/'l:tON|(g/d6۔;詇O WZqPYOaJ{]q|06gasYgr26*΅,o){ǔz+^YƉm3O/_* ׿#6 Q^qhH1?aͥ_U__ehlVԥ?`/C M$>L75cK[?M&h "E;_? x ?6_d_xk=.3W: )7pCKy˷/O_5>IH OB'-Ei=Iw0OD3i0  rdo5^n|u\w={Ŧ@>NwS04Ʊop}$elkUe~K_R7NVh'67"/ ?u;qrmJJ+X#!f8T^ϟ_9f9[ln_ _., >䖝fd~sgaiEs6gs򖷾;_,XP@gπbDabdN_y;O /&nBl|lB8cW/˞m/U]ߔCy]c6|҆#جk^?Lx|Go"!_/̲#8fՙ8 's7!1Bq¿Oc*Ƨqj׵LIÍO뮷{S=l.rg_ʥu$6~Nzֳme}G6T/n|cwn|{/'>}~2dsب2N2Zt|,IMo. 'NƯ1:mݷr~aCۍ#MooƲ߾8 5g֍O`y?(2u(n'xQ4<-s_8}'pյb◼46 ߻'ldxE4W6~f]?\L>fNٲ2demgkxOSg|* sw)]7wGKyW(On;8oᗿO|?BgƧݝ]璃7>>wkm _y(3ЌE0147kƒIIC؀03ҿj霧>Ic4I CD2`!^Eks)7;aJMC|D sAiݬE/.Nu[p"=vӵtU6[e=lN5Wb_?byȲ M*;ﰣe'pS K.)Ge6v}//31ðwG>A3ʫ_n/l,[lhӭ0ޢϜU/xqop"av"sRY',w43/~K|Cr!׿}F~Vy1} /ߌ?({S45YvurĉOٺ0'?*wX?؄-oB/`,JgoY9Lo&Hg*3ˇ?zRYk?sw'ȀjϽ*1L3r4N$ܪ]*|3w؈&lˍ7܄1&qr8݀ӫWqށ6?Byj$Ƨc_We}[*Ǎxf&mⴙc:6^%r[ S>ɲ܄QwIHq;,kv9 qEC-ol??+7c4WWP7e喁Q~pBm'Ԫ'bC&!CߌDI^;w/p| ex͜9Lvlpٍ'$YDy3>vL¡NNL6aT|rɟ}Xg߃YN5\s|d o'ԫp2}xrwsbuQwL%ϟ?ljOYF3 ۮ/wb)lsp6h/;ؑtْ6gQ9-/)s|%6~yq_|'NtxbYm54[},*(`N;_&ʍW_N}> }6[MNQ9lIY 5?weC˿ C~MIDAGwGI,k/~HH?^\_1fIddiUK(_i0UWo)Pg,\aǝZxd\rՕWXCs_YnЃ;݇O ~w!«x ]<~mğ%U֧2R):a.Zv(?1#|DBԑ *?_?0|'z"ٍР>?'h3N|j*[{,FFQ+ZP}'{9(Z?tb?u:@7}s6_ N\yC)l onyxxGvƧw)oYƦm~x 8"txџlU˚]w s r˗Ϟ}6ڙ,/_.?Z/+bK,bM8!ί-;K~_,T'vj۩W?x0?3lsk.oEr6}Q>aV\i{|k_+W]}ey^Tf6x` ݱ *j+lB+lNvs N||sk:$qSLsRYo_4|WӬ80{ʼnO~GSk_a? OXlLԜw=d9}b W?'2׿ultO뭷ﳏ'9^M8l$k)5?w6YgM*ȇ{W ݕRm/~fT 7>aՖ(Gyl .< dž\ā{N=c] 5&<z.\xkrʩeuإu]m}ݶ/x_< ~SWraGvCoEaS!6.N9T~/_7ʚkQN=L݈_/妛n.}>^]~09)ʐ|/\+}ؼlS]Jʾ8nl/VZgXyi9} ]wUleve94_Y<x<$nm9찷zKmqlow.;KIGvOPyZ.4:`c&6>ye]٪qwI/m͂|~M /*k:NI{fYߟMѓNƮol]m)NH9nfK%'^Yt)6ohLK^lRZps޷oD|+5ʫ^lv_:z?_a-ػJo&n}w)~*>?9VHټK/Q7}q~niW)2vf_[k(/P@ZB, +CفHhm-YlFGWُ|Kf5Xh ߬Z%P?N(R[zus/җ{ k>&M{_ŏG_۫{6+) *S/-7 7^omDJ[cQ;?5=>"H|o ``Q2S`ݬ  Ct́1ݬVߥ5Q2[An!:^{ A~}Fr*5ؾ-[ǦI䂟]yŃz'l|ŦÆeNƧ̿i9ً`Lwuw+65ʝđNvy.es-~S||pg~z\ ЏrJ5vx0w)F{Ļl~>*}`mŜrQ9d/~A[o.I'k64aU"lB86!qfOS.m̿8^_ 3d 'pD7>u/)Ekp3u-7 0dd9)#NS}c'usˍ7h(#e982?n~vY9H?_H v͝mʿ,{b&7>}c#WqN׸|/6 Sf@IDAT̿}uπL'aTRܼr޹1#/WĴhwcc>6 ?Zõo'58bP~;lR\ Rf`#ߝ8 suN|vYlyS-CrUW|~ΝYOf5֤Mo۶ 7Xްvyj6i#x巿N\urnƋ^ؐ߃NOſw߱o|'>Ƨ;ˮ "6|Xj7\;//~+k[᤼&Y 6nL9x%ns}d}~{[_1]] >͆Owio{/}su ~gnO$?tKm5=P8)S$c]eH7 ص8C'V6__?Z*qoߝ׬C/?b*Īa&7ꋯ"DOş?*T9U ^FZw x+~nzx?Pfx [ob(|S"K6>.(6jz6CAϤI̸KE>:oY{j 1p klt'IF?ZlHkl_* h}Pm|K [y/^Vߍii?LeoGr\#OYMM7/Evp 6']MJe_q\~ o^xsY& .Әƻペۿi2A6/ۄ[4y_N <jxVyoïℝqtl}ϽSTs'uLԫE8j1wI' p 8jlv~3Wiwuח}Mo:6Ů{-Ng= aiX;G-p?64O߃/zaVZqE^!>uY~>5Wyw|ͫF9sfy 6l3-DB|| _e^]mSOX&8~-e=w/`wp؉ƃXp6wa 8(y eۄrMg/{E(o(/+wݵ"NJ_ st&uA]^aEձ #:?ig@kZ7wN5swg\ ˟rNXw?jkL3Ynߺ>6͞yv)OӿQ~x2Y=2{Sn|/ssعL;nŇOǵ 7tAm$ʗtAʗa(ZƳ]OQ~{^qϑ̹裎(6'ԧj_&?OϺy(mf =-I ژ͇V߉T?Z >pߔC&P4g7_7/(C8\ l` 7Ih?d}qזYS\|=+yGUdzԊ+& }%oߊ{.N9}d>݁N|3q蠵][{*.!ϗ̈PKL6KMe 3V$~d'[MZw9uO|h%ޅ*qFƑ%ƛ>/믆Wԝ\s%6?yޓ6G.G،Ņ֚O~ 6_կ]܃OdT]I+RrٲD~ja2:B/s?/ܲ yYae$[nYğWj={r+wyلkoe+>e'Sn(͟_&qђڟǭ}}%k h˯¦k>>J6m8krqDy"6Qcpm`kUfFg8i"Bk>e2˖1|YR_5Qo-r׽w{M6gofzM*m?B䩧 l$Y8Ʝ`nŒߒqN'VvZo'Ylj-8qV^8s/z1_2vu?;?+|/_~eˆ<'ӫ)ůG=autu[䆛~_~O/6RVZydhkt>D_ϿGy1C+/SAGL?+tMUѠ/_G#CBO_?8O?SK/s[`Lŋkn6vDNY>]cjc@ލas6 @+X{7Fo 0S@Q:[r{ ay%;$ep+%7Azw^?䯓 u7 @K|urPuBuyIm2{K7 \`쨓6Љwk f 7ȗ1n4ͿMO`/̵W_i+$Ud'm#|[[nO>SIaK;/4RnI=uI{衇m|mWa>UemGd_Mw{F~Kn'}ϽVk+^[^qv"I} VIx~@p)_?h^kʿ(_x/79_]`ʼ(_A???ZcYZp_m"ZG_?#?.w+LmE-"m|z"l/`)i8F e3g>Ӵb[d-S Q-@ֲ_IbL7f/Bq1(deϖD`O0V/#kT$Y~! YmWq-|wb&ebM57L{Q j@#5Y*6.c֛ʭRn&zWgbq/\xsl%?"Ko)?niyqnOK/u;uzae[D#Spӿ~yfY}5swx'X/fmIy3U^җVZ'?kO/>_0^ {=Ok]JX^/pSI, V).vWG]}_?UXs ܹ;rV ƿ,7o宻qK(?_g>J'AYmǗ[o\u$P/?mBSE'ߔTFe.̼L/ħ.j O/ՠF;0iID.AA) ['#&j8Էaя6bqH'I:h(wdd3 <ْ4H[ֵ <)QM 1(3&ˌϚ->D\ OW]=`{+p |KǾlfĔݯt㍏Ic'XzD#= 'oy\<`q%\E/*o<`X+(|w4p#+CXdW{ぬ?tL)U,?ȇz5%)[?J? -aOOߊ+$?(OƁST~Doʿ=.4juзa '*$+(~fq0!HU+y#L_BH`'5 te2 &D'&LMGW_\ ,%|?!VmcM<_z`]Hn9 Z#&(#8@=?ii 6'UW#KYeU{5Nx]IddիmVغFn[aʆ>vm++CWQS礊H/b]/ş&/?A|4D?_?O%2_灞?X"q^(?@dƁAwߕ_Z(yj@)*=>*ȧXQQTK`"cEFR-|z`eJ&1Vi>*ȧXQQTK`"cEFR-|z`eJ&1Vi>*ȧXQQTK`"cEFR-|z`eJ&1Vi>*ȧXQQTK`"cEFR-|z`eJ&1Vi>*ȧXQQTK`"cEFR-|z`eJ&1Vi>*ȧXQQTK`"cEFR-|z`e%P:w-O le,Li2jç6@ x&U+@6ʱl')F8qJ!u%#h?_?*w_&|i)Oe0n򿲜PrA%SOɅ(PZ U-VD5 4/ş5d;o˅ʿ(UBrPE_UJTPE_R6pXa|yyw۫!'A?=ȀL0Sd8` 4/3!b7#aE4Zf OG_ۃBSMQ5-3ERWwj-2(PYݤ&.Q!!S.3@=齽D!.301Ln#(0kBj!sYDǭwGWtD:XHt/?+m_S_şQ+"V5 ?(/ʿUS'埔Nn[gA"I'K.~?׷imA#n gXz 137QFШ?D Zo_TͰigɫ̛ݒ7ٟНV4-PzI7k- ~A?<2/KzZ+#^ueQSGGgUreD_rc+xkTlt?#|؟Ym,ge ǘ&kE*O1OL o㥥 O3%ҿ1ATWhUY%Sw3 ?)T/?)$ʿ*Ӡ?'%ZUUgA-zf|D_/ z'>^GIWTQNL.B߽7ve3!-lbP52Íi(H L&gi Ue1 %`dPN+FAnLCF6>#pB䕟'VFFa1i 24ݘ:$k *&5ɟ/!C1a3ݵh *,_KΚ(?US08 y݀ P=o(`!m9" b 6>*?>6)G?>o xCތ˒?(VROş_P[o? {d%A61ϖh&HXUϟ]?WܕPA/)G;<[|łzû)* q-TWbI7eOimF zo,48Mo,ld8R5Km?٪R?06H_xU9ppML@?S?o:ǓCv&g@L\-* m? IUY plG5?x!K/ uOG ܫ~x7Zͭ/T6XaCO +VR,RI'</pW |کŖ?)[?* ܏TUg??, |㓿Bջ,m\`}dw#3Kx*4h64?DWht񿱂l L*F%doTxdW0ܘ.k $3'Sht_c&+f1>LԷɍ?`% E T˂IVs/S_~3ص+RC:CYxWOGp!grIƁm!KoܙÝΝ2(@J(r!/T]Q3 \S*TkO?ߨ?CuD*RcJ!c/ʿ(PM7?ֵBG #zټ ml?u"T8){M7EWtn 3 ͓xQ%F_}t,A1]yYд/P,MY}q1OЉJ?c#DmS2eOW.>M+9lǿEx7CqcQU5@ hy %!ҭ ?2W/(w.(T/?Ydq(uAG_-{@G^]nAg埕V($[#h(s(a\;n4HVt7 d/xWGY7?c?n"l|2+F"blk hr눱럃{ɡ%O.5I?c@8alxΠAߩ$+ sϬ[.քY!Exj|GR׳u\ o/K\?c_?Δj(FA'qUC&Dw]`țYʞ)UBдhJG%j(Qh:"_IYU'a]3L$VU_QPW](P(Rz׹Plh$KKF]RYe6>u!qFħE , ƍᥣ*AE3]4GzTI`Q(Qk5&0hZ dAJo(͵Z}T2 n7DsZM >e9AsmUk2[ 堹VSk@Fĭhr\5AGZ VzC4G9hԚj-Qq+!4jjM`Q(Qk5&0hZ dAJo(͵Z}T2 n7DsZM >e9AsmUk2[ 堹VSk@Fĭhr\5AGZ VzC4G9hԚj-Qq+!4jjM`Q(Qk5&0hZ dAJo(͵Z}T2 n7DsZM >e9AsmUk2[ 堹VSk@Fĭhr\5AN|㉂C#)2&ى?gu$f`《u^Q'J?A5%:pw_?Z3%32uєCO05С?ʿ(9բʿ*/+N_????EN%Ko㓽ה>%9it=ㇴ]AD`'pe $S 1]AD'N25h@9sI&mbz2O8djі!7((s檓LM82tep;Ԅ-CLWoPQU'pe <v G[ޠ̙N25h@y$S 1]AD93Wdjі!7((I&mbzr0g:Ԅ-CLWoPQ LM82t`\u G[ޠ`'pe $S 1]AD'N25h@9sI&mbz2O8djі!7((s檓LM82tep#d1yݎt'r"8vSZGzW}@aU&HrȇǦ)>jf3Gg]?OF+>v}1H_hvO)ݽCy 4~ WnPCL?ݶ&TiVWG/T?-9i.~KϿKϿ+LfvEz!A+ŠP[7 <7>y|+p:N|+~ Z.A齣e[QK& ?׌D-J[ǒOYi !,Ez[woZGGl},YOLjۋáKQRvF/@I\it6'76/Ct$"NfZPƼQ6 h>knԂ2捲AC^s4O<1o4[}1ylA}* ee# Vi@xL-(c(i4D5JcjAFH!@U'S ʘ7F zͭҀ>ZPƼQ6 h>knԂ2捲AC^s4O<1o4[}1ylA}* ee# Vi@xL-(c(i4D5JcjAFH!@U'S ʘ7F zͭҀ>ZPƼQ6 h>knԂ2捲AC^s4O<1o4[n|Ъj ˤ.M/x%47vܦd*TPJSmؚ_Idd:%EOZ#+_Rڭ`__V4]iJI)SOʗv+-&S'CgMWūI)SO.ʗv+-&S'CgMWūI)SO.ʗv+-&s?/"g!Ndž@n){? ?[oJi~v(ڹGA#z֓$VyOҞlMmdddz:ki mi63NNLPP3_~ߛMWS\6Ti~%MHdda?4Xm;`p_mpK=!_?@(ʿ(oʿ)'SM7ߔ3Xmou$7Fh^ʿmUYw?+RGsyL]GoS?H^{ID'ܠf`B&OVNjbAui7_Ud{פdx[lc"Nt lO=&Y0D9D8!Id&dÐ,mLԉ 0\{$Ƴ͋E)9G_Ý\\Bml'Cͨē>fzټa/${ FTG/?:d$Ko,r{YHſPA埔SWo?*UA%TQWn!zeWD?*# كB(ʿ>Z_z+ ՙIh^we wyi6ڠ3*Í޺xF\ڠ3*Í޺xF .!uƨp#h.`IA] JFe4[Oӈ%`䯓jp#h.K _'-u&(Fo]6V(n|jӥ{(؀DOp*|nky8-\Y p|Oϝ4Z/r-3hҀ03n^~~-I.LHdxjkҵi<̲x,NmbT_u\{p ~1A^ԑ8 pƧ>'"])=b}t_Id`eh_ CO8C/C(R[ʿ(,TOV0Hw==XF=====#a=.C}`N|j[x6>-Dիi@}.uiFTl+ "m!4Q>ԩT+ɟO'[Ҟmh@fVSh=@EǴYvSgv2[3L`'5k @5&D/~O).€:E_K"mWGÉP)ڊ?ϡPSO?(U2-ʿ(/ʿ(?˱QPM7ߔ}TmA˯)H V _|(ʿaW R6ɯħIg-f H]Q92ߝclz|ຮ}Lh+Қ{ r\7kej]Zu/uTfLmpKke.qݬ wiCtԽ@P92.y޺*uvP6ߥ5Q2[An!:^{ A~:#fUd,q mаmDh`!djɟɆGz9!_?ZEC̚=i:qaKD^'G *, ߽ U6s(F?̄YLjev!})_?+Pes8YS7䂗ʿ(&8n H埔RoʿPI7_, tV2(ʿ+ gZ*ͣg\9~mUQN'΀o@!<{xc"3҈@ΫS.(2߽%7Azw^XAѕAzw^_w| (JT{Knop>! :䯓 u7 @K|urPuBuyINN28ԕޒ܀Npۇ@IDAT;R6%򶖭-8D?oI]1VF|f96L19 Ф_R#3aE kO[tI8?r>]LOlCO0PE'ߔS "Ǣh(|L(SQW_fx)??(\Vo:S_UY|Yґ]0bڅOQI^4pCmJL:z k/ƌ$xEF*bl=iߘNh @ֲ_?chpn 4ϰ̏`R-/d __lp(5 _UUA~}U$t5?Z!?4EL+pS&ԥ<]r QQm'_ECޅn1+?Or%]?B 4,#'f,+PCojCCG D*Re.UU; N|kNX=ħƨeG:^H4R[:ڜ ߜ(8启wm4Pmn%M&kHabB ͆8B(Y)y8n4{txg/i/^Va=_t_3jK2 BSg_GנZɿqΈ?-+/GkPY2 %?paKTpJ)U\0PA QB?xY I?(Oi/Txɺoʿ)C RMGGrԭ续籨smDZD` zm4$0Ot ֧$\GoH?\C}[цQL#I?_g44"z#m4`fao"~ׂof)ߋjXnNz*Γ357Z i}5OHsԘ 쯭#\OЯ!Koblk%ş|G_YTEʁO ʿ)oʿ*G")NN/ߕW]wߕWF: +yȯ͎ADZG ߸J8U+y#/jl ި_(OG7aL Q3&M_`sf0Eeq2+/L`$F:~Nc0 6 @h8Ðj~ges6?g _?\bti!Ko?.\)TnQI7肯^*bTo_UUW_}dQgO0@,TQGB͵(V*TQGs&(R'f; Ƨ 0q[j Lc((}T%0OLQD>=0Ɗ2GZ+4Jj Lc((}T%0OLQD>=0Ɗ2GZ+4Jj Lc((}T%0OLQD>=0Ɗ2GZ+4Jj Lc((}T%0OLQD>=0Ɗ2GZ+4Jj Lc((}T%0OLQD>=0Ɗ2GZ+4Jj Lc((}T%0OLQD>=0Ɗ2(d!"k"`6pٸ dckͶxv%dz$/u=dfi~_'5?ZaɔɄowDi81)|PK/_)RE-ބOş? kZ(R2qWs)RYL}p˩CUK(/ʿ(/ʿ(TGImaY86PQ?<9UG( 8D>3E "ɟ)x W̚Α0 m-3ER'#x ! >EtJ_ߩƳ,v 2& /3ds2/KzZ+#^ueQSGGgUreD_rc+xkTlt?#|؟Ym,ge ǘ&kE*O1OL o㥥 O3%ҿ1ATWhUY%Sw3 ?)T/?)$ʿ*Ӡ?'%ZUUgA-zf|D_/ z'>^GIWTQNL.B߽7ve3!-lbP52Íi(H L&gi Ue1 %`dPN+FAnLCF6>#pB䕟'VFFa1i 24ݘ:$k *&5ɟ/!C1a3ݵh *,_KΚ(?US08 y݀ P=o(`!m9" b 6>*?>6)G?>o xCތ˒?(VROş_P[o? {d%A61ϖh&HXUϟ]?WܕPA/)G;<[|łzû)* q-TWbI7eOimF zo,48Mo,ld8R5Km?٪R?06H_xU9ppML@?S?o:ǓCv&g@L\-* m? IUY plG5?x!K/ uOG ܫ~x7Zͭ/T6XaCO +VR,RI'</pW |کŖ?)[?* ܏TUg??, |㓿Bջ,m\`}dw#3Kx*4h64?DWwXQ$.Y9(&̀J0{gdD#", H靉 &TWS==ޒ5kMlQn`e O!% Jd2dT{yV0L2L%2 2=M<+m&SHIB՞&6?rB5CN6C*E_tR%,S\jGf|,a"/Z_8ϛ]H>3ýz a?3, wlX ÜIӿ 8Waٟf; S0"lጨ؜{Vܜa^#+g0yff?miObAF;;p?D3H;`)vb/v9aovƫF; ;G;T5\;uҷ?!Dp#A)yM2.'%ΣV10ą龢ZON8F!$\q!ܔ/T}ɟδh`bR'3_đB 8Q$?YC_?&W[_q&gMWz1b/"1/83`hCX}ɟsa_^U5煭?2jfi?l`O$a]G;6+>[g;g;v(;x+h?vnvnvnnħ??fΟ͞)_+HL}DK`Bk*uن4ў3|D.W+ D/|<1ƦD;>D^J7f7'X )6%s/ロ" "# A؃a3P=g2s|،U9:+i8l|*Naq}1}q]l&nrq͘7Qf?aٟlq%4P N2leO?3YΟ`6g \nOvra6N<#ҔObߘ mmog[C6ne&3fG?͞{q~T\p|rUOFވd/zDMq+%q̝&1bFief7" +Պӿ;≒9l7]b{B5q<ʴy&cyj y..i mLWŒ/5F_&"Mlq_[l5CbhI(f~b5bHcV7ճf.Clov_1d4]fla/HBB7dKMK+'YvWS4ꑄLҬߘu xȬ0 Ò`gZ5/?gaOjV'x/1 km []A 3h.fQweeɟH??٧C*֚vToaL2k֟ͮ?UN.su_" OeM~=;&)MgoǔHQk_N)zE; H-0̛Zs[#Hq ?&?$+RHluYɛo}'b%7sڠ<=aP G̬Iy)ifu(#f֤K⼇4$Jሙ58!4M p̚tISC)1&]=)a֡Y.R@Ӑ` v(#f֤K⼇4E3:3k%qC hLp̚tIhYR8bfM${HMC)ءY.R@0P G̬Iy)iH0;3k%qC hfJሙ58!4 `R8bfM${HMS4ìC)1&]=!P G̬Iy)ifu(#f֤K⼇4$Jሙ58!4M p̚tISC)1&]=)a֡Y.R@ӈ1${4]Cg^ɇ/Q;zszd0$ED{8MW\ͽK73QRяBeD [l5/V fR:oK,Vrփ sg5JJ1$o?ve[iv.GO2%Et5ig Z|.Fr_F_8m`fFrhNS\eed fPM%K]]kB -f߳ǧ!OLGD^^ֹ)NŵhR #H\3+i5k upۮ*]p-Z(/O<l?bɟ?mf\POSg=??g:+s?o0!l =aoVvM?eߘvlX"Z$g߁@pi߶`=`/a#i`@/Fgr Ev2ot(<1pX9$ 4ʎ̥VZif5ͬW@}8{Zi4ӿ?hBSȒbarcR*'TɤtWLmlt ^?.ˇ$}p^R \\'7pLQKK#lY6V M)iʞɟͿX8i0g[uu4#aٿfl?^7AcpiÎ:;yļ;}?̛=3V )8dt.PL|$ƜO|AHTYrt5 @g$rb*]M="$$SjQ$Dx %JWS $}I,9TzTEI Q3H"g)ԣ*/Hj@9KN1U|AHTYrt5 @g$rb*]M="$$SjQ$Dx %JWS $}I,9TzTEI Q3H"g)ԣ*/Hj@9KN1U|AHTYrt5 @g$rb*]M="$$SjQ$Dx %JWS $}I,9TzTEI Q3`'kRf(HP5"F®'t~&+TD5jզB cAW_O ~ǭ`_^QGE}֯_!3}j럭Ѳ-RXaٿfc"ǩ@_ƻ;Tq9 }a/Ȇ0?_gd78"x Ɣ&lYdE*3Sa/׾fʾ;q__` n5v{8|t^3fJ,I'Le34NblG B#xn#gܭ8, '\qWc g=bXv8VYg@q3*, aWil+gE!~cwu/'{w??71ߵO50?wGfaTL!Mc믭{n5lg`ٟfiٟ['D'\o?aիVҢE ?o6_GϛOb@!S'}dk-eI 6JT"#H;@d;;gĨ)(a&~j%&26D1kO&f*)PB'?[ *ŭ~Y9ƛQ* $vl66OR5aT\jU'yP'ڈsgGIoV: ;~ڧ#?DNM:y[n=s1ИEW؊k:S1vTwD{?c>tA~+< 6P;ZC3LwuܙNZ }P瞧7&ϐRRnjGNM?Y=Œ%KD  ]Q>}.4t()]ϧ @g%_Fs?>yĘ,{LrgߖO_r ]wO.ֿw^1r$/QG"z/\d2֟#Scө9>,/?-饗Q-eO9v_x_/FwNq<֚K- <8|͚=J|H:)t Š 2<+4Ns4ʕ-ucwޣ{?]xхBޗ_}E,Rg?lW"?0gֿvojO6'Do7]SUa翲_JhOG-?δ+~8].߈w˨+?@cƌÈOBXM~dmȵ^P؎|uҭ.QDAiŹ.G!s!SKA~̉ԗ5,(Hej!?L_+Xc|u-"יUrGЁ;0͙߅)hccv\φN-;ù#wΡ_O5j4>߽Gժ"SK㏦؈T O2b.]?J{ 8:il8>e?2ܾo[K/Zpp|zK* i}ʋmOktƍW[ҋ/aC,OauIw>F*:8ymŢ‹/nIo~lX@6_{Ppa7aD6l3c֟n믭k믭kv?Nn7xaOwx?=S_~@?{}‹\-Zr+C+W9mL-7?~;ZiI4['Wg x78=y.dFQ?d&!,C&"#`glWJX`ӿPS[bV99k#Ƒw,x+H|-x~ʛ@d%5NF?@52 ;g\. :w$jLOԉ4u2"?#~w񷺥3*+翠p5mT3gzǧ"ǎOu=eZ5E QƍNRwtcÏeJE iyn-@s p҉=JD5WglTXQDQiO1ѣGпo!r Z~c9U.!jNLqZ8X@EsP /[Fї\WTI*.y'ވ_r\љgIɧO?D/_1՛J Z ODK,y_T)*?~K*쓏+V8U3?aY[͙={Pcbpkiը3Cpf;_~%67EURys9`.eg];`P*_ љZy|Oeʕ;*z(x1[ޢ.>r4(U7b)E/dzuO?r@e3BJ󏣽-^fV 2Qae- D5:^ʴz6u ~imA<)fgH)]FXnV^CXy(*e˗bEZr%s+_s},_s9WRY^y~R)*'jذ!ҜsJ!}ɌO_PgJ??6'["6Lo?Hmf6 ӿY$1kWV[\`lz!s ?'8~m?0rHa_m޳]E 52OݶC&{Y66o v)gV;+^Z\*! 6?+v8/W@_ЌGd&?@th%*$\z}w}~gggyfX&qbGh*GF;׻1&OO!Mfjz{@]?2ÑrLSňӘ? tyKO i8~P@@O&(r(N]MXa(vP '_&&(r(N]MXa(vP '_&&(r(N]MXa(vP '_S;:Xw^v>R%\#'R90!t(f(f\@$Z5} E~w{Yp7!<`?YӦLDt+H{w`# ^?ޔxZgȡnjrph&#GOкukZgP5jLߨDID@-\a)?-]ʇ㇔2b,O>̀ _c$>1@IDAT- SQ nf(~ E ?4ʕC" 44_W_}  +p:eMjDk ]?ִj*zчO>!>,FoW^IŋsX 7P璤9p}NtԠ4fzp xx|W?{ݧ[^fl1vNk߾zکSSl8=ԭ+m7hǎOE`NlӚ}qڗw2a4嗳1GE:K{ Y@￧駟闂#~N׃ǝ@;tGلoG65Κ9C4tH8Ŕū7G{*V:v7V@7ߠ! lftÍ)M.t&v&+ϟڶk֚xg p؛2u*=cϿCc5Mq֙tm3Fx xy<z<&n'aFӐłjpZ3u+4x wȇK|Mphz'#W+f͚o'{;[t~qZPRm\~})aWG|Rw9Z\D?٣UBX{f!EnuJGM<Қ4i,wTA}edϞt(AyD?H]~-̫p܁L:~+-FG¼2C'AOMEIg_?w5n]_rLLd돭faٟfcEY`_,߶; Ο;s7M _՝4;>3;>?*tA'plzݷ_~yK~"Ǘ6Z~X(' {? u~gr|L]- i*Oq+aWP(N&4 Di2q'=F_9j7gGj #DYZ&& Di#q79eF`6ݵ gs/y c3_xQtM2/A77O5 C+9 p[bT8=ΐg;%NO<ޡ 8pT-i@i{찃G|4 QN%qZ)!<'pɸcF1p|#GOJ_4}H䉓QO ]Eu-q&:ο<h9h4ծY-PD{m_y3]'IdO>N߷ NmE\D~=Oe*eZ 䟣nj٢9-_ G阣$oV?=/!#W6"ţNxhԨp#J‹/׷r;n+~~=pg\i_G[KO=kO3"BZ)K|8z>b8rŋ"Q%T>hǽDh{GD63nVm,rZ|q].]w4 ~ү\7e$HzŕtOI@{!/*vC.Gz:e{\cϏF/81p|* ǧĎ;Nxrr3-]?M3x\-Di`HF'WF%_Y7p]WDf:˱>=r hD,a SO2QݺlxW_~?fxD|ʥ8hP)dο%цg۰qcW58S bg R>ÎO 5ON <̧IHLRЅ]x 39mw܁)}YӧD0qRteC IpyKrׯo?6nY>I'RCڨ?hސHbgujuD cܱ}`0<Xkь~/Ҩ.:/c_@gҤ'38> 0ofL< \!z`N̜9CĠ+RR'ptY G?tH*Uj/_PD 駟l2*|DͺС#t]MHĮI²pp 2hUg͢|@*3ok%P2_{]fEdB)s!?vW@V\ǼՐ3}v%K)'c|I֬Az-ZDϛ;:^ ms>WX7g? >/= ǧ*p|B=p3gem8m^hrQFDhn+u}y_aFDwt'+p >s"1iƄDNBw+p|BT(Y;gβ~tЁK?Mxz:#"8VgC јqc/ Ƿh^pcBuExc)Q=|D^srC>GhUxq<2?EdO;rhz&ѺuCpvۭza,w;X#93GE P(;t 4=㎌sAUG|au o$0 9* H_,[^j w)쳡mj5OGd%D~{'S>u=0aSWr#XM3[<'sa}&p+wg\8)HJ.ҍ;4[? }?udz#Z4 \7mz{w?ơ+W]_"YxO?ݛ*T(Ҥ#DM |?_jpotP㒁kXNWC8Sԭ[_믾ǧ)}"g&+";u7G|4m4zQ_ 2JչO O;?StDʲ>G/]q_;FD%|ɯP˖-ztpwk{'}3tmPvp_醖׹* E7B 6HgC*tu-hٯKe<۷LyYgm|^1_rA钥tӍu+~V=|~=GM,]"ѨOR^Um誣8.W^rd~wc>݅1琊p֛oƽE$}~Qpx1SiQ{qt og"P<~}8'Np|O5jԢ;g)T لW^WO=Wȃ<3E>To2{yyꕫD4l kMA0W!2@@sU {%u-9LDfz ,7W7vߥ}v_k|F#DKsp|3ϩBӣhO?M7(.tI'} 8^RGyTqtx^ i8x,QD4i=׿82Ǎ-*xڇ}LGCv7cS(lᓷ0Laڲbϲ?7g2g_xh_V$>lk_&_c]av}iOsleOLf߶c;7j+5nL"6-gPjа8Clߧ!m rEM݀\>-[zI/b^;`7wtlH.RoI cWaW@ŁAѬEx= *jpFoӿ:2`q`P'L?l`gnoOźK.6qD? 9X/䀌)xa%\UpI p><]F&8^6^`nmCGv4#Ԩ]jHO.z 8xq'`>1p'84[1D+S 7BD D~AݬO?+xԬEsKB?x7פ9d-5nNCp҃8>1av<6"7Bsӛxc_xW 1eDE+(*jTj/87d`zaʽ73E $? /:@zs]=sFD1jP2@SV7H?O_[2A{*%R81`I瞣f_ݫ/qk)=:Aqzaz}EDaӒ%KQ@< |B)oG/ͣiߘ_{=j;Ɋ 'QوI<~v~a GdZ6|^4o=\8F42-;G]wm3q"6r,Um ƛ}Ͽ1 ^w ֫G_LiqbJtm&!\FWI[ԯ~%{p9DprF:\u{:9uE.uG*fy7},Y=w#OY\1h,wj p|b'Ecq)@裏ӑ۩#}'rvYgK?w2 NIk8F2~}/noӦ;KƏ O?!H?ODy;˨Ef~[#!hov|odJ1HxtQW(`MiI(`miK(`miK(`miK(`miK(`miK(`miK(`miK(`miK(`miK(`miK(`miK(`miK(`miK(`miK(`miK(`miK(`miK(`miK(`miK(`miK(`miK(`miЋq'Nm2+ak36]|7W ^ lacvTʋh|rɘ4W]1V㓻S5jUqVpxb.6XlǎC">/~A_twY\YgNJ^VXI|d8"/$wDVʁ:8H-YV 2qDTK/"pkS鳣?(Q}+Gs'vDaBE\S'}5lQd W_Eg}I] ǧ5V j#]z"II|6@?cL*q:/+0Z D<0h80R+K#GI;>RH_kkO)#4nP6f蟞>T!>NB| :.in?JX~&׮_KM7vrxc"e_c8\ ?ɷz" 8_J#F ]pI{}?LD=B&&OL=K#ጃyTFE-}ŽkMJzDZ˯gҝmI9s=O!ۍ7 -yC=/[uk@qt6U>| "S3x6N|G^z hy͘E|{="ڭFtP+BÆRp0\ڼiSJ4`D!_EnDFHr2|$cjҨ[hj(&e\הǀs\WZ}³;0ށd!\{s\%f;:3]K_>9O)LMފyb_Ra,lcǭ‹6r5z#l]KmW~t"O3)Mt˨ʕdTHQDr\ұpuR^(z'd+YSDN%m*>;sF!rC QA'Z6֨1c( hu{攣?Ndzp?O c=zеo ǧX۵jc.`ƒ_?X 4NGgy&PO̗wyGhT|=G6+Wf/ubO#8#; Gl!;ܹMBVt #p^qׯƈHE4e{;{&w)) 晳A;M 4@O!F+D賬ȕCYiaR&ӰV,y!dʚiҔ!&&&6L0kHӿi[G&iŠ{?ǞP`}trw#qrG%tĻ֮^DHqKxs!~r]K4DI gFJQ&=ߵx;ceǧJ@,S';'+Vҷ@u͑jjkѮ^~ ;acǁNޭc"L<,#!=, {{H͞{H;yT\YS{z?/7){}{|xuLժU/ ӛo^(XD|Gv^xTјZaoQ~o!CD<#>PDYf 6]GqhNٞg8>|2 ]tp{ `}ۏ~/㧼_+~Sӽ'}/^_*@ :ʔ.-ԗOi=#'?i њpR6E_pyK?&|"mGOL-q|(GDtBZ"p;pa5nc_Z{ފHjc >S%hFDhUAJ<]s{{gϔ/c ^>K##r+AsI ;>W%+!/s˨_T?<~Qnf 8|&WLq^%˖Rf9)Whi[(m":Gnz%Q' z {ջ/U#"7O?ّh1矨 -g]</鮻\dq ͞5Jܘ<='odu>nk݆;\{>M?(V7.HsO!p?矞L#'K'p7?8dMLm[l' o?8`#s5?=ȶ6Oma/fZmmo_;me㎧t1v#qCǎ-_FÇ(x_G}~"GMhװ_͞.t3?Nһ%b$ɂ^!Ep{9DagDiBkV3E ՄS!UtyP˽G>u~ wWL[0_0/'{?kh/Khٲed8FE">;SqDj-? ">qF OE*V-[4K< QDx(WAG'ϟ# 5H( ETL욦WWjC<m9Ȗ,Y֮[Ck׬B]'\]{ sb6Su;F#>Ӣ lz=p߽駳'Y831Ոմ w"ۄ⅋[o!9:+ҠWxgԹ\ q;<_zɥQ3gN9:>q~蠃3CҺQ_tň~w#>आ84 젅Z.W@85C7j raWA60j4jtխt9:JAFRs6=~F> s+'jo&nTkv-}xoؐ#??ivJ6ګ$N(2k#D]Ϙ85qQN:$$ᣐ_\9h]oiu# B1/)W!́x4hP6FxP8>.+]'v|Jի|HE]fdRClN5eO<$z.5k!:WC^5c㓫 B4k!~ԻW BFD?xmjI?oofZԾ}iRn]q*G1p258">q'}6wnK.[ QZڪ?`0*W {л'+}FpcNοp|:J?t Ի3t0w!goBlh1k~ \3%7Ԋ ~9tOǎ" 4zGAbǾl#^%' N/Rjz̙=[t.".3RF,O跽q֙Bypn42YD+%K-p利VSo{'}OFp?`ǟ|Bh|8m=P7Isep6mquf_eYc+::F_:s/rrD_(&֬?!/yNf[Džl<]6v&6ؿnc-l[yƇfAX)w?` ?õ;R7O?5_lio;>/W]Ӝʖ-/;QÇ=_ye#ciD%4|G):@+?dk#z{>^e+Q|4ԬN2g7%fU!s^jVSg?CL5*a&c^xE*'V]Nbt5dZ~y@n n|q̟?ėV|QFkԬ '3>NCSHMkz[Q|M0lPOg{4@dnjCħ\8>#bok/Wuͯ8|6D_׮[GM8 %5goa¯ goȁ#|N:ǧ Q#OiBWH}D JːaéT)8@}`:tjnyi`sb~w}/~$z">1ө˃J<ЕN;"r&}'UT)iq#92[9b߾,@ѳQB\i@|DtNWEo׎KwoY:-d 4y˒O~l'ٿMW?M]9?Fo߾gZL?$)l<))t?fv߶+ 6?wa8U&6L`O?9ͳl?>wESN˜W_~VXF'W;8y|?я}ݗې>Cn^s#y;LGU;y[%">LQS8`ǧ+DIxWXh.Js)R}ɟ?V^|dԥ RYi)eY*"?La@ĺ$,L!q,a߷9wLAIH!~v99]m$zq;J2n}Ey1 v4pxHO|Lé%,[;~'~F8H8_f͢GdǒUbEz!|q]y%]դ) hùcCb`q;XWBСj. g3Im;oE| /" 6mh-|BtpḂ#Cf)r<Ӈ{:HW_M֬_;h#tFħ'?{oUԋsBfI(@П8^A d@T W%( >W%L&4t'85@ $WUkws4IU^端VM{o/ۡ8]g?oy_l\[d6o)浯n}[ >F=M|+6%6=I?i-o[:aS;m n1OƧj8.yFt`ѻ1}Vp_ o/ O†ʘV/^˿ho|?'<{rz_ :'x}8K t l!3_mow;'l1lp[ &=Ӧ}]m/SŸKߧ6R0@F7mz(F"gٻg_|v8u46l9a? )O6'?4MRNy;y[}ǟ$_{mn^>8qMj??q?'xޗ{_5Mg#Ӌ_B߿m|tu|OX~s~i{}+8ȳ=|[r[5_n{"_e/~6?ߣKX~9=nkzU:?})';o: oԻsaS(tL82H@IDAT.w^v+FF_.ě^Ӧ7o\2=oZ_ ?|劯L7ƛˡ•]Scп{bm=C.޷M\b~~U] VʹXl4t֌Z@_?neǿ??J~ʿ(g Ѳ"###(MW YMȊ9X&_>qOOf;_$Cg L|~?>>uEv-CȌLh#a1sUWO?~ \nكOV3?jȡdm3ajv˳E9Q1+.A'vΚ/PڹA Dׅgy#+wS|X$RXj I  c0lo fiq/\?OJ 6濏mz›s!l [k;(, &#rwgoߐ}d^|3^u#'`>(ێ؟ď`O[oM]veGVK.46`;7N5+?XۤЇKk颋/>Oȇ9l}?Cꫯ^@k孰y}jzt{ofcf??.Bq8l7яf}g<ă)[^D̍OxE/z6>=ZgMM8?7a|L|l*:y}3?ū^9.lI﨣yϓPdWU/㧟no1l7?Շ^^wc#e)n&6] qplm׽5w>}/L}47k>6_W {{/67>M?cح ^^M}PG?L~t;Mۤ uܴuGl:Wb[6nn_6gĻ]F"={z;^7LG~+72s6w{T_~t9MֱQ~~W7;⃶y[uw-7/yNNq<͍{>1?nnv{et赿rtqXjlOustj:e׷o&>śӯ`S__u\6I᪫ =3 cGő6wG>b߭sQG}7Z{צ}XSz_沏1}>hz<~OMouʒ_?z77_z?OiEFn}g7:%9۾ o۫xz˛w.࿵鮰/}(Fpl&s6t0xW^yyoov~oEvb3dz/<\Po|rg>PFC'>¤vLӌ]i~_V@W;yKFd1YpٖNE(Tp]x=/.n72& .r;=S.58M~C<l hbp'>;OS{mBcru?N}w3s#؇@~xǻÐb#7P_S{?ċ,cϓ/}yп=Gy!=moAG7*xFȇ?ļhLlN[^6f9>? x_6= {S/_/\7]N=uz/ɟ^_ng\x=7>B/Y{6#ozaðiozt+Ep3?%ޔ-؟~۩x;6e$x?c:?M/q}]؄Lqf~؀b ubjV+݊ro:Wx:pƏ ܲUly dvYg'|{)k9?ߚFxQ7~w!6K?ozE ov%/{]=;qt&Tgb7ݤ"T?]xR|/9alj~}L^&O7 :O# ͽV 5Fplh!CgqzC/*Pm~Ú:ȶ$QlҿEYtj,X IG[Т aЙsZ`To$HFo: Cs̠rCg)[-=;-;wZkD PQ@xm_YdLAlv^kϛ]bl*)Z>o`?ƛ@3Pث]v- \lj%~@?Ƙ?_槇>ao3Ԧ .^O ~-3H}nz_M)@y;.ؼ=Ӈ֧`ӢAƧ=XŦH]K/t {}~I(14>^O x=|r{MysmU3y?m:LviϛG}r  Oqlgz%|0:^gNY'2`ۿ=Vٟ~L?v,x6` e+ӱ='?펾}X/[~4َ'䓧tL~s+W^13?/|Kxg?Y'? dMg +`+jzgt'ںo_Gk߉!{g/^WNOӧm*'Oc,0'<196GM&)W|gM/zGgi3)u;1-3~[9>uESZ>ӟ~hO~_m}ppQw/O_KҿE'#{__oDK/_[Oş?KŠBVbֿ+VT?7C˚ZZk||79a Y$DuRĸ(țxH2\\T:{#̃ah ˓W d_%U+h!]oP*-Mg[J AiUʄlRGUgז3UuÙdJ ATʄl#̣+^m|sÆ=.kC b`@a7ϐj 㺖vϯ92pP@y B]']oxl9}>zַpN7K>_韦+oz Y;]\ }DŃ*?çaeˍn@8Hs_L9M>>}}iwӛl:餝WrմoHW 9LwÝI泟̴{CE:[ttn:]իK?{5xt,~Tac}kY>yM{.3}7`ѷǛ~{죰)oG_1 qNwtGO^Yiϴy5lmkboݸ]{7ǯ|zO??^W{UW^C:d=5mox#;Nؤttϟl48y=Nnxaǰ9a'ڛ UW~e o{>sii=y Ο75'7SuUădXĵ5Z_Cz(aK/_TkXs? Oj^#BdO?h)(*TSOp?Z2 eWgW_ƳV;y`$͏ ƳC$SӑAQxЬ@w}@xvxH\?SӑAQxЬ@w}@xvxH\?SӑAQxЬ@w}@xvxH\?SӑAQxЬ@w}@xvx$Sps?!o4 ?IlH\b[Gm_{8y|ys&Z,)ebOYKsI _Ӈ>pt11Fn~q9޹"VA+}>]WLy#/gZ?lzS:}w}~v?l9u"CK ؀/v>o:ϕ=OKrfcVw6ntpꪯNg s\PVp mv \HʾQ??[ f`+(QEnQo [D7uC/Pum0ߐh}_ʿqʵaRa(_Yg[$Rl(PÖf;}#_6>y͵0>_X<,"z)ő$z Lp@7/-Y.^q,eJ" ZK /rɀ ۍR!@1y(+VlM6`Pە굙Fk%o&ۧ{z_Hk&~'̺ZCu?<}ߤ);{灶wZm_04<9æ.ӍozK/.g+ef`Iޭ?k*[ Pm ?տUw`o/HS h2ZvY_P Pô E?h8@ӵ>ba`(i- Š?zDک04R5l|v(+bsslL` y,z6uB[P #m0g G;#n0xGT2` AvFnB-` dܺZQh9['9u ;Z/sNr3rjwD^ lhg-j@F:!ȭ[ z6uB[P #m0g G;#n0xGT2` AvFnB-` dܺZQh9['9u ;Z/sNr3rjwD^ lhg-j@F:!ȭ[ z6uB[P #m0g G;#n0xGT2` AvFnB-` dܺZQh9['9u ;Z/sNr3rjwD^ lhg-xS$},@ XqkXß3 o Ib-v!p&D 1 m-JoG:ۦej;SYӇ?w?UlG]Ro=_'dړ]f~oN_y/KtIdKWW-_տTUCQT[oz\?(PCzn?6>bKa{j8o| jβ,)sL'@Kgvf\1Pjp"ev즷PՌ9 ZͿR.ՂZ1PѮ]߿h)sL'@J V j2~BDrv鿋h)sL'@J V j2~BDrCKl;.x"!n^*[-݇ .)v DZp鹀s_l~°c=֮vw@6E謳?uI??k6Ja0Q%;ſ4\oHt?(PSgJouAO 2góGwcW%Hy(VKB/_^u[oI 1E ֍OteW ïǓ1,8bٱe D[.Y%?tAK!ݸz9d-??_.? a)ވuZ?'Հu RH!#]8Dl|uQA6.Z‰u ٴGmKDHш)5AR/_=3ddZښIw+k[ ?L*(TG_t ?#VTce-x^8O0 ߲ܤo.`]cꏪ?*OT\:ziyg c67E#ݥg0vF]N׫-luעZ??->@s:-j4#s]&E s5{ݿM8®߈-&nqoo ^ ҹ8znkKHO_t?+PsUo5rJ¨RT_յꏪ?F/퀅Uꃥ?_*SjMEG˧qTa*+՟A[=io|I`sDp"`" D@N#^pƼ&k0$brv36Y!#0ȼ1o F%yM`H $02/gmC"F` g'yI/8ch519; KzFI`d^ Θ7d D@N#^pƼ&k0$brv36Y!#0ȼ1o F%yM`H $02/gmC"F` g'yI/8ch519; KzFI`d^ Θ7d D@N#^pƼ&k0$brv36Y!#0ȼ1o F%yM`H $02/gmC"F` g'yI/8ch519;pSVG.^f yM9% p,JAA5?%KdhL->BǔiAUKoCwi+h~e-?(B CH.E/#?"p*d؝ ۪[o?t?lr{ZşPWE]5sQloߊ;[^Œ$36>UtHpq:hK_ >3xow.= I_X)AvIjj*TpT4쀓oW `;NddNNLP/Kd`e(PSmڑcB;rҥ1Dtl+"yLsH90rh(#^Id% o#*9֝/$0,tl+ao|f=V@j9qO #=뗼 39h~ɟOgƯ,?__7'PS׵ϡPRSoT,R_T]TE_TZ'8 o?-ꏔ[ꯪz__3HP>F^\Ci.z빏\vr=H f.W1] $yCCk*$sr\CqH{[9@p9ڡm8$st gP6x9:s\vr<I}o9.Y;T $yCCk*$sr\CqH{[9@p9ڡm8$st gP6x9:s\vr<I}o9.Y;T $yCC<|EJO8/3r_xH,ma/y0<)h]RJO8/3 zP!:N @Cru= (ڐPoR 'ay!s9HmHN0<6ĝnk%V^-)# i=cm4u9//*HvrA6I'Ӌp?buz#WThJtF.oEv.W;Cs>, BekoE`-ioÓq޵s Ȁ-3rT8ؠB_قXB\sd hc5-'#/`d@I kV j{S&{ *&/3ts+mc ]t[%aqI\kXZ? ֓6Y׽Gz<ͨE W ş(TRP[տT bdʿC-@[_TQIc !yܤϪN A\ 8ciΐ̉J`$Fh]e D%ɖph_"i+Ú\%Z]lBvh???vʰ&WI_oJ ^6G' F1ه я?<"w~n7k?"x9i?4:!s CfR œOJi3P! )BP- Lj) ş?.\& LL+L1\THd(r{Ko4SoHr<&8&? L?M+L1\B$?i2TS'bNkL?) D'@9@TTşM& şM.?!ş4߈hAX 4[2ʈKх.RZn4V?? cG?Lc.[٦ T ?#: B媆pkёPīCK??_\_ZS_?AT'TPE'Zkr+%WK"zĩ{?MtAte\?Rw}%rR՟YO ꓭH͎N˙;ehKCCE]-k\mF |z/VU,Juחm-SGGg*^*1JF7Y8V9oXKHFE)OH=$:75d/KXS_ 4*,(R;͂w_?OȢꯪ4ϺU_UUYwH`O!V*Ot堻wxSh.ڵ ;Ѝd_gxCS\3Q3Ĭkhvy@IDATl[B(JKTg X2BEIddh0]hf' 18-!Tϡkɾ "_9b;g"h3,5 nr`-9vJ 9`?rB=iOáאu=PŠKot5+RIe@do44Of%_m.f&GWZk8 gc/PڹA Dׅgݱo|>&ֱHyapAnyÀ P=oUC4i9b#l O4/Ò[ XZ?m6RWGWn-)CGş[7=&A038.)PCf9a%*Tʿ+VJGZ2ʿa3  aWw_8-^RAƧjÀopq!ka.)Toukl}(PS7-ʿA/O?D`'?7 Ϊ?A.?YnO5ꏪ?H_UhZ?p7>'^ae6m|U|1 :X l&aRدcY@NK) M<+0N  /EAIgfЩ8`B((6ߢ :5t,Sҿ&verXkO| +Rt2/-^)+|1gkG0#L(&3% u!v~Y=?/J__Z/ş=B` !Lz8eBQQkP֊/`re+EO?+*VFTP#DZ K)!L(քo[6|ꏪ?-_wmv&NKc_ ^;eIv||ShyCWjp|Xy7ߢ"%3}A >X1W9Ț_Jk jE._|ROUiR-Uo[m|*w鋋lbwSu-'6pcoX@FU5@8b +COG^ F(R[/FOߪ?J6TTժ k ?ϞGL% GisV]wUW]wqVYg՟a{wkF`G4?F6a<;z1%'F KƤ=g?βq2~BD;ve5"eN8e5"ev6g:jE mp;jE luՌ9 : vՌ9 ٜ,)sL'@u,)sL'@9kYV3.RO(h3YV3.RO(hgs֮f\1P gf\1P]gY͸Hcz?`gY͸Hcz?Yβq2~BD['βq2~BD;ve5"eN8e5"ev6g:jE mp;jE luՌ9 6xhu;Yp^1N/4gz}a]yXj/MSL2]}/Kd4ZkQ; !݃$#CM~k?Y@G@*W [n0m$UQK?.ş?)9ۊ+i:?cu__Z?(:[oX  ʿ3_'m'\=bX۷_l>:zkv8d3UIMҒWƸzI5 {-plyhiAdr)eK1F9d3ChQ,݁O>?tsVYt]՟>5 ji(*g' x҂h/19; KzFI`d^ Θ7d D@N#^pƼ&k0$brv36Y!#0ȼ1o F%yM`H $02/gmC"F` g'yI/8ch519; KzFI`d^ Θ7d D@N#^pƼ&k0$brv36Y!#0ȼ1o F%yM`H $02/gmC"F` g'yI/8ch519; KzFI`d^ Θ7d D@N#^pƼ&k0$brv36Y!#0ȼ1o F%yM`H 8OZu;*,AkE6A8sJXWᭃ3kk~_'# ]OM.ՕvO a*r("J*SOş?WCgM.ՕvO )T PWEܰx-ş?*TΡ?lr{ZLO(Ͼ*r$Żem)TSOştPY|dKuB`?~v[xLEt3rzЯeN6xow.= I_X)AvIԜUkWAq[(NGGgX3[w| &] nMF$ x'ۺ_I0IPp`P%(hMOG7 _]l6t[:W_ ) )RBTPE՟TSM̟,OPM7TSbYՑXx!mUUYw?Lw9\O+RIiGg(肛LqlzlI 9$=oA_ӒiKba.| &`|'qDUQnI,܅/@֟֟֟لjEupKb.| &`|w ;O 'ÒoN(vapIGP덱xnjϞͫ!nH??ٟbOaA݈>ìCzt/ş(a/?HUTQGIꯐTTQWn!WQGU!0{-ꯪzyg[A܂FOTsԭy7mP&cEU8pp$@' _i#ث]PCpp|WgHk韭\, ckƭ = ǎ:NOOeٟ@ I!?eOOQWGq_?  rQSk?ʻ\?S|U1HwXF#a:ȹ^|ڻo|ka 9&,#G/]@DǶrh(Wʹ?'#ҩi:OOZP8CGoB@GǶƧnvX+LkN!c:0Kkߓ~ ڟ0.ifBmUqs8 _?{~][GY _) ?*VAx(UQE'E_TQEKUcKoFۂH ̼ꯩM|5T ucGi4e:6.⁜_>k*߃ԙ`b~|ӥޡ۠qH{[9@p9ڡm8$st gP6x9:s\vr<I}o9.Y;T $yCCk*$sr\CqH{[9@p9ڡm8$st gP6x9:s\vr<I}o9.Y;T $yCCk*$sr\CqH{[9@p9ڡm8$st gP6x9:s\YOةƂ,yZC^sd+m4Y5{tO8Qe?P_i_4!Q,6u# B'+Ҙ @̣/PYN0<.Ģ v7.3%UN0<]ҿ'ES*= ><._ד )p]zg?I@цzJO8.3kSNy V [rj\ mߒ.;bF|ѳ96L8 Mɻ_RkG,j쯹?'#-!t(ĆI?)d[_TRM7?=U3PMG_UXQ~gA0wٴCLTTUUg=rXA׃w1F{EkSB iJ, j?% \}& @uR&áK']H(f;`py(p/Ҍ(ݫFpN?GCJ9*T; 8 z L6C!3(PKg7[)cv(hhA_ʿ,j $ΡZ1d}S *FzY7rOƫ4Jglp\D!hre:43 $_7_6JYSWIkA!##37?b)Vh+s'txfi/^6f=tvҺL@ ]|\_Oٸd$֟oD 9gTe`SwK*,Z DgB2ֲO?hTÀTPATPg? B;?d-e.$TPE'״n*e_7TSE?v>Խl<:};^x#ɽHX$s,̋5"Jƭ>z2&/KXXrۼC dQ(܈ɺHX$s$#s0؟m>8| TFKM1?x溍3r`J"O?Ղ:"Úi5?B*øCUKoʿAS=vTEEH_TA7TS PQW՟U(B$)P]wUW]w72hX?t>۾G~7xӸF@*\uY,<5A65/'#a-hČyU ?w-fh`8SfM = A9PoH$ h8Ð1j~eK6I??3ΰ ?t (R΁AOߪ?X6A՟TZp»b[^E꟪?ꯪLUV$*BGUZhZZꏪ?haU'~i5BX2 121*4rFi~HDU`?N-.%%(cBL0c4({P$UN 4;fM~ eb h~JgԹMf u J \pL@b:X7> #6m6ܾ_T#PpzIξFZ~͠{ڞp;iާwϩߞd>SӇ>xޟ_}GLj'hMhA!w iZW/ş_ C7oxTqWK(bLi4X7(jlO?K*Z4?4P- ʿUP% 3UVf2UIy/}Y'G=MPXٳ\_-޼CI7ylAPBU{Xm2/0CK?[W֟[r6b[9*?n[_s)'ц7Yl+GsksS&dJƷoܛ> 7~u\&54? N>\!? Pۙ_߿_D_?_ۋ(P,(plGRF-###vVGWG?+RTRK/G_TQI'? ౢgOdnN ?gwP9pySCZ9Q Ng2~45Rœ|59h_,WI_oJ ^6GV5JߧH]6G۟' FjKIvb~><S )r8)p?Id O:wJ_t?|5߾<ҿG}oKΖ?}VT2COgNGB3QL򿐃_{KÄ(X`O P{o?V|$̾oZV_}ÚS6? *TJ?x EI7ib09`B$(hJ?y_3}>&e"˸!i@PoƷDZ˯B}y.`\"Q@h~_+BOG4[1@k߬+XBIBWZع˾Ԍ df]௰^GAzt+65hqc #^M}cpG 7wogwӧ>u}]_[[v8~ڳg_0ZqOPF`M)S ^ UTUg>ѦO_tc[/yONtѣ'jCTTQL=꟪X/"֦w}FNGX,bugw<-d~!9s,/__ u4?DXѥhЂz5Fn!<?zĴ+ihhOgA???URiWgI8s??FKpn<E&n&]><Ɍk>up$O3ot?iG[% k1iNw4]~chR_2[LW]y{ [a_߁?,M,ЯTS_8}OߒODͱʿUv7`__C_/?t?8׿=wjQϽ(Db{yy/1]Q jbhcb{7M'yi hbR,"3gpig9sff|g}ofeKe`'^j9]ACaޕX_JU=NqU) C?6FRQ$U!($](,ATՃW`6n{ 0/=7q3htWyQ0g_P?|Y*Ʃ=w9ךog>Գ'h'rq4+>Ֆ?7n/WRϙ*|җ阾}i˭e'!;:N>~t}ϙ34prGq;?}Ĥ 1ڴiC tQGnToU!!_<ŵA?? ; ˢ1b/_[Id?P?֍ܳߺ׷ 9O-YdE2A]jSurzt w^ka|q#TJgX~&!L)6z d퇯(IC?C8X6(i= %aa3?|IH]O0`!$( Ox{:JyuP'eZh6@& %4"k5?`йiiĉ׶&w{?Lk ]Ê寢cKڟ>lh[C&s_LO_?11_??x M;o/y y4j0Zou1-V|9BT^xEi3ӤF+ @ 7;F6*ҩl{Y+I;Z6SPPIoRjRtW`نn9M ̴&?ѝFL"gU}w^Bڜ\р&U9FQHCU%=,egE~>yŧn)2ɇ'@oYD5/4cX74?ooɲeGӦN 7I۵kOsٳuŧy?m޶˓˖*b~%:߹NtA~oV[F68^9z+Cr~y CⓈ5O%b9ʸݎ_oQMUTؿ&?ڃ ;?y,:?'M{F~>? F.ww/zƟӞDO{An1~M3f6I޳-mvH:Ip60T9G8s!YUl<}lGQda<9U DC(D4QAVPd*U* F!( _<50Ne*Qп( Ryj`2*TСQ"6]P'_QAoPȔTdA(c OvbBL&KS76%iW>ԫ'>=AOO^}}{)DJJfq<}SNW4{.$&O&5|ϮW_?Wuiqm{{Tׂ)~ꩧ蚫{qa9kߎ^ٹsyŧ3yŧaΜZt]Eڗ9W^#FP֛RCr:T6&:o}~jX?swf`BQ['tY/_}`0a?3J_/RX?H7FR@^iA-P m_2Z(?_W)WW7شU(?us4/~>^{U}^Njպ*CM WKNi 3鵊EJM~k !Ssu#Oތ}qbo2 ZzK3i׉ƄZO*SP*l( 1JKEM7lпѼ04)蓫URVg+sf|vodg8=0^i~fjL~ҕx|i<r1uaUKSxd^JV2TO(|i|D|G}7r+*}N;TnOOGȤ4^KiUr c=㎝h>/|o`t8%K1\G;#^}hƳiɲ%TnI]}vԓO^rM-[ŋ9dn{I?͞=fLAϯڷ@w{7wtVS]|޷‹4~zolu@r7|+miEy7ie{K ,ofq7ڙeB9ӖӪe y5a&̳>Ewމ'Zk͢^N,_xUiQԺM^i9=u϶&iwݕzu>c5wgC+?1+ղ?x,ll?{7? E9}`n[0a6H*[1Byob/lJlHFS/cׯOÃ6:/_?O^&7N;C4|,r,;wڙrؑ6x_{B{E;u-J܅,7|f><6Μ񌩌o+{_I(bqHZs;TdhTC~DwY)Ы eKE6?Cxڅ=G^e(;ǴCU]0ʎlt񈬎A&&!$)˸ڐ5vcw܄bDȋվԳz_r-Sx.6wS^P5d3ȚI2Ѱgun}6 hYT B ٪a֭iTWowCgVJ׷hAx֭6Qdl7@IDATOޣх_L;ﴋi!_ҥ׿%=׫O/KV:_9?M'zѣhܘ19OI/o3Oӟ-Z)A7_X5rK{\^jc3(Zq5Ga挧ӊ6Ϗ'>GQ+"yED3]`d@?O wJ QS )/os?wI"hB?z<1C& NpYa}XԳOl2O~L b^TeE}OeloU˟?I"H: Y'O͓4D"ٳ_Mok)_z%︾A+u_~'SyN ̧WK5,Y,Ͽ'?:elSltUjot %ڎIu00&U+*]P]5n%p+ QقZ9īZgO6ۗOd^8M╟䚲m-aGM;v]_u'QW"2qr_jW2jH<_>|Avt#wIZIOwQT @?7ܳny2 O ɭaٜ+%ɭ>+/='j/KJ&|7p??FONBwډd2צm6?Xx29h$+\Џ_xz/޿.?І?4,CV|O=?[cQ_«=5e2=ԓOA}ۏdb\…蛧-\H i d5-oPKq:I^i>cg@?L=yW}㎝}y߹Bzq̨EZQy'lhO|:A&>&7oMS_zeV&rz[.OTciOO{,M1nZ~qFs-'׿E8i]?n+X1f ku('+B W"m>MjC\ k?pizoL7}DoY]뜈aOlre5of$#j@%&#xi3 6p#0Gb(<,W?whLN-ۼĭh Gw))C@/_)%`[0\-|komg9g;=D??{v-۩;o:jՒN ϛG=?L-[z?Օ^|yj&>uf÷B_QSj2=@a#8Ȗ!J:o 5Gẕ4,C5&PsK#89Tj:o 5Gẕ4,C5&PsK#89Tj:o 5Gẕ4,C5&PsK#89Tj:o 5Gẕ4,C5&PsK#89Tj:o 5Gẕ4,C5&PsK#89Tj:o 5Gẕ4,C5&PsK#89Tj:o 5Gẕ4,C5&PsK#89Tj:o 5Gẕ4,C5&PsK#89Tj:o 5Gẕ4,C5&PsK#89Tj:o 5Gẕ4,C5&PsK#89Tj:o 5Gẕ4,C5&PsK#89Tj:n'$xeq⤄*r\LJȲN ghKWa uh5N[1ͣ9l'O^O+?H]sO2%1(.o?s} I}6As鳟=XON:D`|޽z/ꗿ{;^Gk^~{6ai-㕃2^uyvk}T߂oybd񒐈 ;a}Vj4E7謳sݓNϿz@VG۟&>N; C6ꄥAo헦~nr+]qECv3u|ch)OM۞{W|WۗHOHq!]yw{KUD~e?Wj<,^D''>wt!OJs3'eU8ѹgPH7pOZS#e'^ ,K?畿'K}z~<_Fq޾< WRn9px AK?0E'u0c_#},RM2*<BXj7/ȿq`DqC 7ߐ79>xjQw~O-G{m5b=ﰍkCoc lįYJل8 6ƿlSpL,ḟi&+>I+Ԣ2oQ^`cXI)czfZ5ڌ2G/Kf1E=BxYj3KmJJS#䀗i%Xj3VRʘ!,V6c%)r˴l,+)eLQ^LRR9e` 6ڌ2G/KmUcXI)cz2mKmJJS#䀗6Ӫf1E=Bx6X6c%)rRiXj3VRʘ!L,RR9eʹj,+)eLQ^ `cXI)czfZ5ڌ2G/Kf1E=BxYj3KmJJS#䀗i%Xj3VRʘ!,V6c%)rnϜJ`,_Vk/tO)I1 KQ*z4Jg' H{h'RӓW~M*S&'&x,#y!rʔQ^eW㵛M$򗕭d.<54hM7h0kOy'xMѿ ' eI/17{]wl=z$=Zݻ7]kDA,ZB'W9]|%,^zW^ ><'s)utӶrwKOCtE!y;hދon[uU"V|9A= mZy%g*YCUzu0x2oߣIVM߹lbzns2<ɨMk@sTaar?W|a.ʫx2՞'M\{ml/2ַ;4uх,QSBgy+/|rͶ7߻ yB{ Cʠt^vz#Πzd=jJKsO@W[&q`Lf`1a"c?? ? ?=!F;+K'>O; &{\?vnoD"ᇅO>5f<͟oJN|*?mO9Za@@par\ Z8)eC?/vtSxKÖ@%lR6??2k9h>R!# zڟ.<)9\a/Ip]'.y_2R (z>V $T%6p?R^'8ؾM*3ܠR\ .X@X?Q|)ӓSrswm̉+>eGwp 豼t+ZްuL>Dmޖ[;.Yhy?۶x|ܳ /BzMIbǎ_yǢӉyS?;ѧ}֛~|M>G嶦oiܘR)o%7rzPufVp2>/=d'~|z2=@Jd%w`tT5X/#``1aG<1F^Tq1Lf^?5 J_ÁLcN[ c`Mjʻڗ՞d5$&jO%@kk#;uLEn/Kǣe}{)ՠH'9;ٳ_=XNOzu4zj٢_㎣E3ԵlAcDZayB%'ҼyX벯nϫɄFzө_%թz>މMj^,u w C*u(_6 ۟[?{迌cw C/_>:"A#?VjOy'V!B ⯦_{llBiԲ&=Cm2)AnFT;owډ-,sߚy#cG˦V3gYg TTRʹtJI Yi ^I O˖, S'ȊL6q*n۔R>'AyRK'>w\ 2u'[{ %g$|ղ%Obc5pRأk+ݘ 1<1rcbʪ-=6U)_-kZk"" 2oƟ(@"aG_U0m8G?1? f6b? AiϧJցĿ7z~#/9}}nplnJ {Pms<ūGMգj}ߔy}|㼣UR'>;]J8kzt58BS+edd rWПJt-j[CCCy7m* awT*Qfk9lTKE#}|l!UdL`/ @0W"\W Iq;P^KӇ?_$@4e$xzj?t"Z_>ȵ/&d ]2K7WyҊ>]OQ2̎]sCBuլK l=˿3O7 ,x'9gm?u9AT>y .OӦN݊O҉Oi7v<9bD B{ߧGK1GjDHwN >_o]{t/FqΜt3;DȓLd4bĈ\[ŋ)`|>tC']iٲLuRQzQFqj:*ώaqcyU(yj _;Rm=vP>O)|Ȇe䁭M!XJ#X׺qemh`8@ ᄸ1X"cU9Q<^N??jMA0?iG$rR7$o?}jMQ8?d@S/gL?C۵VMCGz/DMۡGß4? WpFGA;J_*wۛoNǎ -OkߨPV0GG*hɑRB8[QXmC"|i C?? aH,+$& _#H 6!5 E5pĄ;`/m g{u'[B{' " 6 Z3]g^ -jh{^^eIahUSN#9@ Wk-BrS]S0(˕ `4/oj1j̒Z^}hSOTԑ#ɣn?&-[шc'1GEU3H_{K/M^|̴ݫgN::0 h1<&DS='Yi%';nډ\ӠiUw7O!oӮ}{{}uO}jͲ>j޿L6:([I,߿GC=DmV฾OK/+B _v)M>]@yM~+J21 'DLBNG?U&3+IFW~*mED<1/clgP#=<~,>g*[kjM_?}X{zh^>Mnʦ |1Wl)K u<HB)*39d8//KKURCF]1BeiiRT tȨ+q^ȿ,-W^JBu< *KQ)\H!y!^Ex)* I:d8/_֫/Ep!Ibzᥨ.$QWM]IgY VD>褛(ږ@k`NXXO_?b!B]Ia}ߜ A'!Qd]W7]]]FF8[zQھ+ߥ“k&d%ԛ1?nWe*Gh;)rcpԩsG}|Ʃ'UA;Jx`X h%I9[{=_Kn#'.rRqcy'0O 7 eYlŧ,+>j<2WxYħ{Ou^K'O}D̳ߟ{nF '%qԁ'9qОqw#r`Ǔ6IIwO"SACRة3|SZ;&v-ssW^{Qb|j=Nִּ<5o?h 'GO-x)Y~eL{Q=]qe|JsŗP~_xy%X6Id̙tE?я=Ǎg0vWk_m]+nq+xfb[RW_?l3?_Ѷ( 5nD`} ?[ 24ŗ;q?Q!؆ƿ )7/KD8vDOFTK?Y2ڀBAQRAlH4Lb&6?UۧǾAQyӇѼh{Ӂ~F޻0iоqqŒ'7@ m}3I~R&LMzO`Ov])L|r G# X rC?BD0ebI3)ם?`Rp-9K;4N]t'«HV@Vuj`}@q2)Ėb3&vyA/0f=F`_"Jr'GIx4kxRL ' M╍ƗnS^2lU䯏Jshʔ'hĿ5w~t$[o9gEKy2SY>̳Ϧ-Z<yŞxΤq5.|>𭙌d>:Ū}z x'Md ٦Nz7v,$K.!WO2I.N4Iy cxE#'r?屿doR766IN5uЁ>=~.OJ:L^)?^ϓKz-G/]tY, v[5Nk>!e< IdԝCZ6-NZһ}vr6sD/ǟ|-\ 履=SL/if'?W|j݆W|ҭ5O`YyQz>w/hۗc.S+m% Wь B/F ?ؿ``?S?M1c?" :辴Ͷi/+"c:f6)m:lCb|-?l|rjZ˗ q]6j3gLft/W.UیJ1vr1P&J"sGK_g%&͙ I#kH C$\M|YlHܑ8 B9_+>EcSX/͔œbrT¨r uEaK&ɤ^IVHmM~zYC =ur Tȟ)z.oMrC5 <>_2aɶյ+uݣNQBp\xMCǎAr#O|z4ԁz*Li&^1^H6Y邋.R^*YIdH'+>+>#F7w\'>]YiB'LkԧL6QGFd 4RvX%9mSr7z m^/T7]Zo;' ݴ>Nj/̠~~Mo"l~ 4k,wyܞ(^:J5p`^W|Zh?x>G!oMG'"?i΍Խ>ԩfjZ:)Nn/u~ik:ܹzr"Xv. YG_C'Eh_U`9C%kW9TQ0ؘfA}I[0_?5S`W`aaa1aO?!B 7X'G- 'x 1T8\.*ݥ1W !B%}*o-?IvcֿOi볋z6mtaGV_H ?c>|[~[zݷd6ioG\ɷGqŧɑNYI.3ucO*Z-[ak*XJqq9z2VxeJ2VxeJ2VxeJ2VxeJ2VxeJ2VxeJ2VxeJ2VxeJ2VxeJ2VxeJ2VxeJ2VxeJ2VxeJ2VxeJ2VxeJ2VxeJ2VxeJ2VxeJ2Vxe8oUW| KLEnҐNϤa(I8כw/GYT h$)O|b}M&$I]hmg_75|Ց$w"m6O9gЙYmlJqm/ /_.u 5K'Tk_ɫau Wѿ ~xkV$|!Q#9UǨw؉6oJMٞˏ&ovŖMo g>iC'>U)|ra{)Дp PH' ~oY~4y䤉GC?:vc A'Ãp~|f/#gF?0~>?YwRچW<{/cٲJ׏|=5jNK{o- .W7ڃ?o=zEM ݧ']r٥SJ5W_/wb:#FEcG.K.NB''cNky4鬳Ϣ>}1] #OotߧD(Mn˭ҽ=Ϛ͓s$lС7m+4~XO]UC8mx5sV-[%Erԏ>'iL[?uP,NkM'ynxbZ>?'rz+k-CkgA`y|?`````?0`?a/_16/?3F>J>|ጞp3H⤁&@%RZ">}G1!ˆ]&*D% h2 :.]a<+c $?Q>}DA~:Ǝôd= ^ +`A@~Щ3OI\-_\Co!߹Nm=sK/DOML~~+ѿVZ;Lm=-]^?_oVohijh)''}򓟤μ,F -YT;_oҪ]hm_Ky饙pU6ۜڶݜ'-w~j-hǎOk E/2;ŵ_r=v\DV|OUqӬWgќ9leUh]>A:H.˴T&k}Ҿi3V`Xh\?G 3/o+#X*V[)^G?_iGm}(f7, _T#Z~| _n E_7??f;! HOhqC#ovqE^FF8ƙP≬ݜSTFIs'.{о/!/]BEi8wP겗 grz␗.4JJp;A(hu39@ =qKPQ%G8Ν e8K(#N Z]mH=YZPoL?׉^wqs qMOfX %'zر3vQY$Rmud^k.!O''_?f~u`|:WIh,p?գsið?:^Ha}hDO?a xS;Fgb@&OCb ܙV/JmE޿HpOCZ?+O?x6Oȿ" #ojC 7+u Ɠ9JdN|JPf BJ1+{K̋*@?`&iVzrlպ#C.(CF-[$EBYW;2y4dp$ej'L 蟋 g-.z6FՌ+i(M\:J7]IAJ1z1BX?#cD&|&Óyxs9=;W?A<O|#F =ړ{}Kjղs>KW\>DKE`/8D ;^l㏺=%jU1f7Ꙭ#~$e5ߐdu@w6^!usLM!ńT)łp A3[lcE9n^GTjwqs5ߺ:h3 ps$O\)ԑUպlND¤<cHh>\*[ ̤ r!_x F|J '??r}+)5yҞXfBU!NڟݺvZ͈$C,ZI?Mri[}*x;/u>Mh-}SA5IH6OДIO.l?v͟G_;'>A t蜳ϢY<1ǭtn_M|( Eb Q·_!ݠb^QqRX_?F(,L?@cLCW䟑?OQ!l?" n@IDATʀ# H$ȿ"+lEG-B_^P=rb|1)a_8.9QVV*1ZcF-YPޑjP$%ڇCFiT* dFƍe#RGJB%&23Z?.|]-;A4D? #jOK!^Rv??_6lV\%i7ar\-9F Ns}y Ceָ1?I?,Yn7_! T1TFoK"[X@%x_xiu}̔ /ȿ /ȿ |F%]]9_q_BOY%^*AVA)U 1H>丂**(eW|B`b[b@jP$‰`,&7yRVH JQ|B`b[e/**(E',0U%]UPJQ|B`> '׹B;~eEj%rI|'dj>qu1U-֯K9&!0N~nKY(Ywh ?WI6?兏XJf4wTODs/_̊^zC?[0C,E:2ل ;ߩO5C->xUϙ!Bc-4@7oqIX4x#0 L燍?_LLjvץr-<񩁧>q3fig~K,SvN >QXMi{齩L9R9``1=n!`dxJe㰗nM+˔#ݽkEf8J(nRE(N)z!YƲuO!InsP !21iW^`V8D?f3-& YDł@7qD_CW䟑wߑ\ڐG=EߑggΘRq mZ 9"Pj`ժh$wADb#*`+ڇAB"?7Q$p}2w3u{IT|2`tKTEr`@?(5jLd^ 7 ^_4 W_w8E4"C'z ]7 @k*+?j^aGcV{b0_Ĕcak:f?#@!FW9#D[b ɾh?i@I  ޿: ȿ ?GA#(_Vyq,oA=|reD᠖ҥ5T[!A FBj?όيb8%/!$"* F`zy.]k)5p@~Tsg_M{=GFeakdWǼvckg_yڇ?l+?/ 7_a@@)o#f\䤐B G-g ~Cg1_  mc~Ҍ1{4OU˿KF'>ULHlTRV'4KŖ 9Bw@,DWFwz^2j_!O/*ihW1W|?ɬJZ/)1ڕhh[ӥ[6r&_QČ }1ƨ'ɧi[B>@8A#ORVCGžøy%;VTRri=QUP~# yoHʲAI) "_Jc.[WqҕW|7|kE=]f#%0F P{3N렞#Zh6< Mcd'4\hqW )`H_?%_3cSX0%S#t ?V'Oğ_@7o?pP?bLa $  xxxk#@/!k"PG[lEo)uSE3 ozd #^{2E.$ҔѾPE;  Out#^bKh VUj^ƨ)$0٨D N*8&B)@?ǟS4ֳv" MT=| 3ۤ*uҔ r!?(:r~ϲ_gH>%s;::dW^/!,yG_9@]a> p3``eT)a/_?#@%K'oAIc%]7DU(- 3?[;?H()P2h FwߑGwy3?o03JL i#/𷏼%sATWPfKE6Lt33F׾cPvZȆMaFGOB\d@2cr cڡLQ .VeKE6OAu$S .j @R grXuփ'WȯӲ8X&rBr5.-cLv6g_x N? y$*hY@SP}QY&TaM?D00S50[ , ˄?s-C$tjҙci'{Y"jBM@QH/9Fp%r&tjҙci'{Y"jBM@QH/9Fp%r&tjҙci'{Y"jBM@QH/9Fp%r&tjҙci'{Y"jBM@QH/9Fp%r&tjҙci'{Y"jBM@QH/9Fp%r&tjҙci'{Y"jBM@QH/9Fp%r&tjҙci'{Y"jBM@QH/9Fp%r&tjҙci'{Y"jBM@QH/9Fp%r&tjҙci'{Y"jBM@QH/9Fp%r&tjҙci'{Y"jBM@QH/9Fp%r&tjҙci'{Y"jBM@QH/9Fp%r&tx'z%y\G'EquGڇl )ԁb+>_?=M߈?!D͆1$$t " _B 4Ղ+ȿ"+/#.r??޿??yN9&ezM|/q'rAԌEOeޢ!L/RR9eʹj,+)eLQ^ `cXI)czfZ5ڌ2G/Kf1E=BxYj3KmJJS#䀗i%Xj3VRʘ!,V6c%)r˴l,+)eLQ^LRR9e` 6ڌ2G/KmUcXI)cz2mKmJJS#䀗6Ӫf1E=Bx6X6c%)rRiXj3VRʘ!L,RR9eʹj,+)eLQ^ `cXI)czfZ5ڌ2G/Kf1E=BxYj3KmJJS#䀗x'6?i`_Wu*P陳<V%A,/ %yҔj6=>CqӨGbб"hA/1 ?^FK=1`/?!=DJRL=C "?Wrކ 7F6://rӨGğ`*& ߈7o .? tg6Җ[Os9:<jɇ85/sp*kCR?- lħY?Xup;PF=8ny#+m h!Vl.xƣb'T_?2 J:O6l'P/Ŀ"F/?b"B '䟸# $Bq!Os.dS,֡񧨄?#()3o"Fӧ p5O1ΫX79c,Q2m-2і~|z2=@?%!H66Lbax>|f#51bTۥkw퇕=L'6^8;o'~ͥrly8h:YwNt8SŦs5E?OW?/e` /6"DD!TA R)6![WDG? E?W쀺/"B"?IlNIs*?j<;JTV?&@++>eIX@ dR /#3DDdX@\ޮ""2rD gRsNo 9V"3W9eduȁ+șԜ2:CD@FUjzY!"r #Jr*5v9c%9ssz^FVgȱJ9]/#3DDdXͮ%ْ&qނIeQyE[%h1GB"$ @!Q7y&HP4B0SjA{JFVEWg9ggdfĉ3wn̖nd*_P丄JfLdhd*_P丄JfLdhd*_P丄JfLdhd*_P丄JfLdhd*_P丄JfLdhd*_P丄JfLdhd*_P丄JfLdhd*_P丄JfLdhd*_P丄JfLdhd*_P丄JfLdhd*_P丄JfLdhd*_P丄JfLdhd*_P丄JfLdhd*_P丄JfLd(/>qij_XjĎ.6uǗA}ЭFqtDW-iL)d\vѩtϴa,Ͽ?9\XiYuĖOן?]tb?e\vѩtϴa0ן?9\XiK[?]t'&u9rE=ӆ\ pcJ,EJltOןSeJLsE֟u dv35wWbqF1<_ e=6uu+T9/qUJ1NPmp(_D{ǟo9Ox̋+'V^\N2OsX_^zx/߼^?:o߼yqD#qC@px-o{{D?{?mtTHֱJ[x*>SmGpWH{7i$YŃoztW(ʢh#w'1ģ +mk_X@s92'hbZ]h^R?Eo(r'l?q`8PE[G/C=-E߽:I7zO(?ǟȠD_xow,G?־JcװAn&x_>seH/JG$;CxW9W1#/7*o b%C]Q[;MoFJz_Wd+*KVhuZ)0m;dJYB#%ʶޒ&Qx+4R:l S$ve) N+-mEYB#%0#2[%%z`Mp %a{*Ƣt\OM^ Eil_L#k[YsdR0P3p]:m`vDf>yן^zן^f??;*Aښ ?uFi?xa,&jAFyty ;VQz0'g|h4ڈWԙvtH|Τ@l۟ӵ/# hl"Uwricy|so?\t}\gxQ.^y0gzO|=K?zO ?__"3?D*??]1?y=&RxC`0:M#[8A\Ϳ(ҽ ET3ri#25<>NN8AW?ǟfґ(>5Oߵ]돽+-jyן^{1KDx)_OX)7y zak_WIs7 ZۣnLMZ|d.nGݘj'>&]P$jo1N|6iMI *ucl#tA=w@U=T;٤G6z&Px{ԍvIlMVSg٤ 깛BQ7ډ&->Is7 ZۣnLMZ|d.nGݘj'>&]P$jo1N|6iMI *ucl#tA=w@U=T;٤G6z&Px{ԍvIlMVSg٤ 깛BQ7ډ&->Is7 ZO{lBghbR4{ҢSʾ{hJ+Z m75mx S -.[1+ r^yG%5x/s$XutYIySG?5_x "Y5zo_gŧ; 9yAH*C%i]EIgQ=T'|ygoay*GBbc|},"ilElvY!}j<2-FEH{88D\ UL[oT_]_O=;8\E74Q%At:zlxpk 5lNdksqӭߘ+\ryNרZ^y'y_%fC?'?R7?W?362;"\<9OS(UQ;hd.(&*6U `? _ 9G2=xO[|/W).1rGLQ|} | QlDGcC/SEl+?H?1'2^_[eG?r^e \`yw?xO#vd8"'e@o'7?zcZ@g? ߽A^=WX$U͐{M˕:k,,4?T-J(*[],DG4\7h8ei1BjlmHn#FE㌃=1²K0-g!-aITx#FEWvm?!FH mX7h8OBD7Bma$Z48>k*ms&;inCܮWRB+WTvV|a a>4 6ty|?]̑ O&_Ui+̲xa^yuzE?yo Ǥ_Y[{-o_a(T"~bWz'E 2_wYۡc>|TY" [P7uJS(M\ -7%hŸ\p}OcrcGrmź\p>BNv' 4ڃFZp> tVh^<%Mhi0_}__3v68~ U@o)jA5zI{|rQfHP<;p3˜3ANS0š:aqx':+w"`G돚EVT𨌹38x'?>en X&O?>bC,c8s|u:x56to?se ^z];z/Hȑ O ߼_,X"y߽w{EC /M~O| h CF)ThC2!N`ዚD1 ?ο3 Pa$IqH_H/8rW(#%t^|z} ȠL=x *o /S.3syyX]]r;0&L ^yL?y-b "s*p_W֔-G?{9$8CLj,*'x_#^|.@IMV}^|B{&K(AE1}J/%ʾJPQ e_d %?/BeTC2YB *ꏡPz,PE(LPc("^&K(AE1}J/%ʾJPQ e_d %?/BeTC2YB *ꏡPz,PE(LPc("^&K(AE1}J/%ʾJPQ e_d %?/BeTC2YB *ꏡPz,PE(_|_'y./BgKȏ}G~ (Wc@z|s98P:o?+2tPU۾v@?cG㬣d[aWncHQ7xVmA|燉OR^ 2[ ,x,IP1zOO^U#W'ZwD*&@?T&뒉gcQQA*GP.Um/}h/cCTn7898z8)wE䜳?gQϿ?sNuOԖ&N#=/\q _a"?XeS1&bgse4wՎοο7?9O}ك(/>6Thn0P(\Ll_ɐDb[RI؂4lF D:8zἭ# e =ҏ\472C_Tz#~S,;v><7/xCZMah[=W>.DK8<Ttnm{B94#/s7:4NGg]N41'k);t,k_%T}߱nsquXxϵF%O?^ȃHq`Q\=l/t5Y{c|oCodܶ{=}QmWOj<3~?~ B,  3婻iIq ʅ@Yx/ 8 9dƁ̖ɻ(?I=;(| w 04/hd6Oޅ@Y??o?z)B lxz'?K?οa??ǎ Îǟ^^ źU.eTRR3r1jq!oz(.*exC6dn]ݨ?H@h]?9/^{r ^1K/,x[,%9%4zXxOx].]b/>(֊/۔vsۘ;@IDAT8Qlsa4<&TwM \OϞ<K=Ͽ/6~ -9lN,`_mB;X)I45d1j5Aj}G}cl"ns4̾1U/ s|G0^_SE?laGP/0Ɗ \\0.3q;9_uˉ_!?\`x}QeR:O(+5/z^\{k714ޟ/zFv~>ont?_?O?e񵭿__/>|V΋>ŭ_|Jj(6z} ==IǑ3 ⨙&Hfߞǯp|m X t3L>2OoSm>5snkSl ĹIF)`6ynpO $n~ͷL?x,:KM,ߗ/ ]P7TT(qb 4GvXosQf_>[A+&[HWe*%NJl_e(Ous?CYϜ7qtYȞN(3Y`qSulGY?"c_ycs2qpJQ\!<夘~bX*vKo$]{s_+GAx4u?{?7}ᆯ#3xV 1Wx'j[dSٿ aUJ ,s 81fJBbsS}%q#7yl/T-w p?p [ϨF)94h(ǟZ\p [ϨF)9hP4/3ԯ=]m(^y <bc)*}D?xChB-wvk :$x|?(\%c1C|_ƌ_ Ci~~|ǿ?ȕ ^4v _Nןa ^;jJ9/B CL/?YV!zq/ڻ-=gu 7~y?k>a f0x #ԔixJ^% %QZg5 7~.z~WEa7GhG~@JY7? G{8<~OgH{+< pt(<n3h`KgH{+< pt(<n3hW_ kq> 﫴@-C%*(q!,4+ǟOusR2!p]#z<<;|2kV_QIVXQ ~+|-zQzWp=o*1_UK38?SkcPQs܏?H-[p i'=#MR'ݕJȬKKpZ z*@;z gP7LNB4 Jο2xҶ3$.pJ؞y**)z /XEOU@!^C%̺^^4$E=Bmx (&lBPN֢$rPLx/RRwE&!bƒx"(2 ܰċԝEIH% ^Hd-LB*7,ń"E*(u'kQdRa (&<)RA;Y" K@1AH JZTnX ETPN֢$rPLx/RRwE&!bƒx"(2 ܰċԝEIH% ^Hd-LB*7,ń"E*(u'kQdRa (&<)RA;Y" K@1AH JZTnX ETPN֢$rPLx/RRwE&!bƒx"(2 ܰċԝEIH% ^Hd-LB*7,ń"E*(u'kQdRa (&<)RAOKY~Tm>l?g6Oooҭڀ 77C 4W+w}&ǝ?5sq돜=\pXo?'N^fFϫgV}OJy+I?|íBa_n?\r'$K!G`xb7a 7q5^|EeԡLؿD)JYrl1"cImųtcD球*ۊgɑƈ'Q*ϒ#gӍ!CTn+%GΦ#B8FDVxB5Zya:S4 \ P4 ñG*Pϸc2XHiǟoDMRLsЋ:Hzvɱ&7Xʑ1r8B9=xEO߫F/?εr`xlZkB&ϲ:G>L#f?7ߑ ]zm V_s8/Zw;5.?O#6ȩ#s [ ͘7Tq [ ͘7Tq [ ͘7Tq [ ͘7Tq [ ͘7Tq [ ͘7Tq [ ͘7Tq [ ͘7Tq [ ͘7Tq [ ͘7Tq [ ͘7Tq [ ͘7Tq [ ͘7Tq [ ͘7Tq [ ͘7Tq [ ͘7Tq [ ͘7Tq [ ͘7Tq [ ͘7Tq [ ͘7Tq [ ͘7Tq [ ͘7Tq [ ͘7Q^|#&PŏQĦ"~ ϡJ-dFqt5DW-)^??:*8tJa?矝#4qh*ݙ6ο9hJ{*R -#Vv𮰵FݤS?_M Q +mk矰Z7s&ɨ5H)5?_p>_.Z!e{a~Oޣ I7z| Gloñq8{_X 0#{ߑ PDUz/SI~o{-ނ׬ϤO\7B_z/s?֒_s/~o_󗧿{z11UL /֫>TEAu:~k'VTHIGډmx+4R:(蝉m ,[ie?LaooIl(R)}V)[d;oFJz_a 6َ,[ie_w?' o-co,XPIjx,_(Hjx̯:"=ߢwW`FeN(o+PIs CdFY xC(?`~6q.Iy-xY~ x U C8^9V9V"qq<9UZ\;ʩ?xR_ ] 7ШQLKpN0O+N;c uFw_) ׌u<Ig XS/pX8>/4Gqևb//[y_cO8ϿqoH7W8\cU0?`_qVSŧ\5wlIJ"SFXcNJra@5NmKgRYFu.x~;lLJs9?$C4ڈ& 7O'jV"1x†/? \#f͈ʲ)V?Ƿߦ_L]8Ɣo2K`ܒFTKg_?igt/buy?h%녷UkN~A\OߎʤE?_̮9_8jŝ_PyAL:i'jKH]:::zg=|x"sC>Y">v|k{*?!tkredx`=B uE9saeLZ(]`pIs7 ZۣnLMZ|d.nGݘj'>&]P$jo1N|6iMI *ucl#tA=w@U=T;٤G6z&Px{ԍvIlMVSg٤ 깛BQ7ډ&->Is7 ZۣnLMZ|d.nGݘj'>&]P$joݟtG8X1)=c X=ח4VGlUZRfw :7BH34**p~_,#8MۿGu(j}V_}2Iߟ?S_5̙/Қ]{^ϿkÂ;+W߮?\r 3Oޮu'm||!):~k30W<=9zܽͨyRi q-_Om_羷ǿ?Oߌ_{/2+M߂dD6H\dmn%9quBx0Q!M#,T"i/"gF0OBF=c <1?w+F1=-cГ1a!g?<Se!I1eoq! bto#DθW?0QP|AO ?o0?1?R+7oow;t_uw+ZD^Xt p/_/|{O>eU_{_<=LBU9J?~d )??????q?lby_|p@> ]BW6QwuTsDM6k( idn2DшOBqs@N*pu;Odb{S:<"D9Q~!8~AB(C/Jc2_-dxr9ٸgg⿢)c}& <ڬy}<9 OHQ<:^{v̗N*zmsh+X.'"w՜oEDfY/OXgߏ?hU""ο<\fqQ͍GTaS?>…a 4.)ls^חMU7P؛}1Cq7oks;% g*/RQz/?<`Ϊ]9ϯwߍ_z:L#\'n*&w1J%TFEc_#FXz.oHhqx FH K0-g~Bڰ$*oj #Ѣqa+;#6,oHhq'i K0-g[?߼$xU?]BISq#GtSInek0qp|Wn~?⍧/7^nD3TVYLފWyV!񟑻aoEUKA0\r.ڙ/4UꏏGWI~U_$] 8z/Ę'{cWւ'߿Sħ~U`j=:{_î]-럿{_wֿoƿO䏣:E&\AGA#Hۅ$WIu#Jp'h ? H?[uKFYp> >6j[OkvM(Ҧg6b\d.8ih4B#7vl?fê ܈:]{ĩ҂Ͽ W?{d&EKz=A7VkQ g< hq1e馍8nRjxgGv}kAaoҵȺɜ'wjqNE_ 6;Ч6{8T€)\i̡aW?/дퟆf=Upu9T(9S1F*R.r,l NpG(i@ZT#e60TZpCysqhhAI_|y$7*͔4~ܭױ[k@2<>_i96Dd^t$M@a)>]aYnOpj=/hڻ4MiB=MS;F&;8ܩN͠: ?ǟc+YDtgN+o$>XmxEo /'uba|?[_'1g aon J7:}jOW憫 9wvHTVވFévt6̙#v%S:؍?p#'Qn->ǨEMh1`€2Ʉ8?ǟO$H+L*9ĄϿN$BIso7"녜52kS/? F+rCzE%%?AnPa`/8?Uq{pK.l /T`L?iO'K(AG_;۲/BpTC2YB *ꏡPz,PE(LPc("^&K(AE1}J/%ʾJPQ e_d %?/BeTC2YB *ꏡPz,PE(LPc("^&K(AE1}J/%ʾJPQ e_d %?/BeTC2YB *ꏡPz,PE(LPc("^&K(AE1}J/%ʾJPQ e_d %?/BeTC2YB *ꏡPz,PE(LPc("^&K(AE1}J/%ʾJPQ e_d %?/BeTC2YB *ꏡPz,PE(LPc("^&K(AE1}J/%ʾJPQ e_d %?/BeTC2YB-_6F~ 5g{KgwdU{RRq[y/kƧPQ`Ḅ",}d\b'%}/BhTC2YB *ꏡPz,PE(LPc("^&K(AE1}J/%ʾJPQ e_d %?/BeTC2YB *ꏡPz,PE(LPc("^&K(AE1}J/%ʾJPQ e_d %?/BeTC2YB *ꏡPz,PE(LPc("^&K(AE1}J/%ʾJPQ e_d %?/BeTC2YB *F/>u/X|6H/7gzȁ\<~X "i?̄}mj.+%aۨ}AEh#X?cn{t.Mmgs수xŜUs/X)ImP~!`aF޼կ'}ۍ<{vvMa 0Z+E`A)!yZz*8bT/KQ0=m[~ ýjOTmT5S73䋰F9iwy/Fa&?oTԅ􂕺aӳj.+%aj/,?,v4ڈ/cq|!`e䋰F?_KzJIEh#\Pž`$"lms.GXb_R|6H9#Ts/X)Im{ۜ@$_6ҽmk \ VJ/F6r5j.+%atos9@5䋰F͹a }JIEh#\Pž`$"lms.GXb_R|6H9#Ts/X)Im$mѫH ѭyz~q"y0u#R\ss\U=.{V)6YT\N݀!>q}Ҹ`Dh#}svj4ռ=~JRUm㇡>c /,v4ڈ/s툘g'*ImrMޡDBzJ䋰F?_36TŽ`$"lws"ƗM]k@B#8!uP5&mk=q_ӳ=^i??l<¬A>qBꞡj(NMϭ+{1-zCosQ?m\į)f|=Vo_Q·z:1{h(/׺H+ L9JO[Umq 6j(^r\V;5qB(q|h#NYO9j(NM?35!O-W=ݾ5\ڽ=EݫbDa?M%UOyԟP5iҚgS]w!\aU'd6=CPοοοο3[˿O#O*rحdѨY|Pցx|oZ,H^bcIz9ڭq9 :J"J% v@>+2tPU۾v@~-㕛s`.zqtC??{K5߭yj j&=9{sK +ֆ?j7\-ǟF}f]`h( 2}9ց8?ƎYGɎf5†:ǟYM *حqqqaHQ>Q.U[bOh}%%:6\='T=W%IZef}Ǿ'뗷_W=X@}AsZDZIߺ97́KTKB|hZܭW{xj5önlnsa9f 1j[ց8?Fϊ%?mFhWnךŧ? dTz%(-&ė O@bE"hBǟ3 CI#v+$cMۛ?ċH?$1;Bp}q!*+زƽ!+]ihrh׿]7!Iܳqu{&Gg T`POoN/`-~Zey??oyn'ǿ_R?v%}U]0qP-sן?x\\zڢyj,"^t{/ %O KI5n6+-UݧOʃ 7Ӎe|\殿[9DP?,@%PŒ"z/T'#s=S]ϞZND?wd[azR쳑eo墬$aWdOG"N:t0B_Z tYj*=w sv\u$ay;s)^Ty,@s6O7/_9~թ0>_Gp1 j?ԃՃB] ,frk|>٭>@:Ó u"%\BhX?#1c5O&&8%%Ix?|ruuiE(_1_o\,tJyOpS>o͋)^,$t 8;N߬:TK5F3?wWf {Q}M~Ugiuwu~# Vw\/c=c^O&aloGa?==n$03s wIDAT?XV)_ 5KH' q7Ǘ0㎣x% Ћ@f]m!$5fvpmda=9{}iʒ`30g)89΅@Y/?㫹H[PrK,?1ѓ8ͅ@Yf ߴ6Ɓt M. ,____$L @t2[&B,$ zv.QA@6e988\1++ԇvS16<;Q:NS V뽣!od?aײK yr7<ʴlkW{ymM^2B@f]s^W*ąae+2g`ȭr!PgE"HN'فq aɅal:4RZ.>cfXJ+Z^x%ǿX]l XLq_Z$YsS=矕DJiŝ.AfI6b"ϴeBMTܢbYO/5_`zl =rn?h=1?E}]yKRUq}󾖺OtEo_;&(,^T|lg_5`,p  #o6??ο Ecu׽Y&_E/k P] ӽ=3~ucj۶GZy?Cb2N*+|U|Qi 4'_҃kHۣa81+jzb%j?ǟ Ei=.L7_|X:;]\ST8TO2R=߾qt<m\V4ŗmsL3CR2K6M/N_Ͽ/=SZ8ll5-]OzH%?_;"~n ,+S20Nw_[Wy^́X,R;/ڍ|mGO%;q[q'SjͫXVfOQԹ??(ː:Ha0wG;x [u$ak׮wy15sÓn)`6ynpO $n0<78çqnpm wvS8786Xgȼ@IENDB`starlette-0.50.0/docs/img/gh-actions-fail-test.png000066400000000000000000050620121510142272400217430ustar00rootroot00000000000000PNG  IHDR > miCCPICC ProfileHWXS[BzDj)!ҋ`#$cBP (;veQ}Pyu_ϙ3)w&4?p%H kq$/Ne[ zK=dxJܜJ~葡9hI %#aDhx g>y|'<%:'?D9t@0U-2n 9=`Cf\7θgOeVT2iȮdl@"RQsEQ료5s졙>ޣ~b Պ*vULE!c|4Rr3GѦQ)I\J%rrV]]RG=^]>GR}9:TG*:*.nަh Z:VK;I{@Aph5fkTk4h\xIִdiN,ҬܯyI[ejҪ:uSW=R;V;_{uH:::|:uNkt: D4a="}gG|utszwȑ#GqstU]svor!Xq˓9sg/o/WWwZL]fs1'ga^|s|(-[s7w026tZrkY=c9rX;Y]߳}3CҐPЪaaaua=ÏG""GrxZNOwSQԨĨGю+Gߋ4ƂXNqvq&Lp681qG⻤थIw-))RjSާH3b1ӌDiMcCǮ9s\ɸO~ G&jNNܟAHؑ˭fr2fؼռ ~9K/X!x埵"y.aB-bDs"r6ύݖ۟;_-?#XG+>5lI'IcU{Qҭ2D6^T ?[  ?LITiM{VVt|:oz sg<ɚi2+sVlgw }.enߊ]W5/u^|s?)i~ 6,-r_fR~2ײϋy/<ʟd-i[t22o_h㕣W63KZ5q );*+XYszup&k}L7mQ֦M 55 7?ݒ/_jo-ex[jkkwXZvyyWȮzMw{{^{c_Ծ@i0Qє~0`K_C.8\}Dң+:{\rD-[sکSmN;vYc>{Ƌ^Z=[ہ6Kޗ.\nn~JWCƹvz7nwy_)ww=½Z+<^GwJ{ZYs燻º.e_w}e?lZFoWKo\wޗ~0#OML\Kר%\)wS6hiaFQ' z nng l &Uh$}hD>-H+f,=Bg%3?Q("?JEQweXIfMM*>F(iNx >ASCIIScreenshotD pHYs%%IR$iTXtXML:com.adobe.xmp 1812 3390 Screenshot qF#iDOT( kgdV@IDATx eWQMHaAQ! I (} @@}EQApBA@L2"2( |>Dd!) IjXU>to:VUSVUm[颋:鱱!ikڞcc{67& %ʡMfے.XJY] ٪Uaˈꮡ?lp&[Z&As)_?Q0a~PPHqfp_W_-|8\A0ԟ?S!N;w͛ww߇;v_?+\Y!%D!v/D(J>δQ+;m *?FaUvSB'ǣ)2̏?֟qdU*kc<??#B}%'N9gJc&I /?l L/_ȪМ"WE _PB%*KWRBN9g '7oߨQP`%ъ@PBKVB  4r2`QU8ܷ/E::T9k`دL{xEGYK]\dep#xaK8- P[G˱c?W J(E.;??ȿ?mlvm @EKԟGkXRs./_PQ_@MEz>Ց1)FN?P@Aw 5fz4Zsj#z^JM /_PFň'RDMWBə6G??n[n|EE-F͆-9R U PR ܶdƍM䕨dѿ%řߋ`v1Jm(MW^;?__ dW$"2 /Oo8Sj ԟQ͂/A;|-Y_p/\ ן$*,_O\ן?'/6oVp/F^ ԟw^;da;tѣm hiےOŝbg(gBe]YfпYjn=?6Vxb?Oegy}8eِrbt0g!ͽ \FՔw]OkES+oȯ*녔ou0Oh_eۛ"/6y(_I7߾[|rϩD g``~W c?:L/؁_hr֦4P5S*ǠbjZߤ)k#=p[bEMAht%%nz!&&&8D/ԟ^S{Fqv_E ACtq =סwm1o6Y̟P2cXIBՆWg eaJR6oxPVةt/UjVg eaJR6oxP*]Ozlt̑ڛ(YSKѪQ fic]BVڙo!u\Gc?/_-X`J&_ 1SmX.wɵ5 _0;ȿT ???-&"$&DA=R$Szs mP ;|PB_Prwkk{~B% C|[q(YHOel.SqJkE?+-믮Q:;tuVzZY7U+n.m){IOMK,tзcmE?__/O?ȿ?"qS:V"kD"\FOLd!&&&ֽS ' ;zlEOg$A)EM /_TNv}isۗnbE5Y4hbbGˢ0Gve74h$W\qҞS5ϯ*ƲbEf ? O1g+jGu [ɭ)qH;e=z???YAA% [IF3 @'hai>ȿȿ?)%6 ?ug5?[Ak2Ts_=維:ȿȿȿ)%6 Gk%>m"o\ l*ZQXFk钽oQАIĀ!8cf4dGRk1`'tFحY ّZA  3vknACv$VpBg;ݚ[АIĀ!8cf4dGRk1`'tFحY ّZA  3vknACv$VpBg;ݚ[АIĀ!8cf4dGRk1`'tFحY ّZA  3vknACv$VpBg;ݚ[АIĀ!8cf4dGRk1`'tFحY ّZA  3vknACv$VpBg;ݚ[АIĀ!8cf4dGRk1`'tFحY ّZA  3vknACv$VpBg;ݚ[АIĀ!8cf4dGRk1`'tFحY ّZA  z5]\)mPoIHn Fܐ6T>߶}t ) c?W#/EN_ $& ܉S?aBMAVW,x'Oߨ?R՘3w?xA?pA\b+jPFSHcFMߨ?Ro Z`i5|H7>ŇbzUΜۉpa zUΜۉ0&[.^p3vb\7H.^p3vb\)X  \)X c"W9sJo'Hy"W9sJo'HlzUΜۉpa zUΜۉ0&[.^p3vb\7H.^p3vb\)X  \)X c"W9sJo'Hy"W9sJo'HlzUΜۉpa zUΜۉ0&[.^p3vb\7H.^p3vb\)X  \)X c"W9sJo'Hy"+gtԻ4V__u~(f$ "kCW,\#޶{E???d= w>ȿȿȿȿ?ɿɿ5@C1o?P}z`;+DϾgsu ԟ?ů=PFQ>ijG Fptjp$אlɠ)ԃѿK!]_' 9dM?֟/=Cx5R5$[] b[R8>JҳMYRV`h-1M]itmtp}WG#U):F9?eA h~BtCEIMab +|+ j4z77,oUBw"&&΄i7SLHˆ l$2 /B2 !Hd^hd0EC #2( ɘ7`@Fd`g#Qx1o $F"B+$cހ)IDFVHƼS40"; yh$aDv6Z!LHˆ l$2 /B2 !Hd^hd0EC #2( ɘ7`@Fd`g#Qx1o $F"B+$cހ)IDFVHƼS40"; yh$aDv6Z!LHˆ l$2 /B2 !Hd^hd0EC #2( ɘ7`@Fd`g#Qx1o $F"B+$cހ)IDFVHƼS40"; yiCrޖ'}YHWkC R l"&(cR hEuc~?_R=԰GN$ ""D<&w6S=BImQCiK}UZIĖosŷp\lqelzD4lC%vH[IDW+_։tshW#^O MwV窱},dy} nʪ^cGm09a4wu̵ua`.k09?v6h_]O+rk95ޒj;K~eSlf9jMNIZ_ (iRY̯:CO+g'jHMAe뢭Z:ȿBDOԟtD'Oߨ?RPJ3g'RRS?lDVHmD MjK{=F.>)5]1b~'TPM^I-% ӦjR^*4S|,ߒa}KC Wc̏?֟cޱ]e:1}dG|)/JOo ?ȿ4NOooo->?䟢o%~ѳKa)LD%4&??A7q\͔KS񧻇/zt),flqCtCMMAEII)~b/[Aln2Z0<2kYj̥й*:s-{ͥй*G ̹ k67S*8w2).mXo`%U<qeREX6#gz3UIODoF ߭ŰLC@"ݷL c [aRIODoD_z3 *8w2)|oS{ߐK/Z-wk^fZL2\qA{+N̏?{Aj~klS Cm##/ˆ\)<\;#Oo1%-~HCHAI(=HTArS.禌PuęCcFK;q \shu$f'N1g>KdA41wR&\hCut ^@8`ӥ  +:}ت?tP^_:o[u<"ytT ZжڋxSEIz?lhZ.[ckUPs:^^U=U0K<#'7/ ?Q1(N\/ԟ?SL3g\_7?r^/Uzj>8y``a,E =ј~%?\iP4пTO:8 tETe xʨ??:4shH[T7CKRiź{#4sLnu^?hݭrc,l])e}>~7ZŚ k7 ğ?%P$Sׇ-ic1Efȿ? $$@IIIi"'gO[sȖ@ cZrhIMMA UA8SєN5\ocdvXErZcUKh;"HH9ڱ*m%srsv$gX6|999RNvJ>vIm] )Y;V ${Nz.҆]='Ga=gABi}֎Ui.ɞ !>kǪcdvXErZcUKh;"HH9ڱ*m%srsv$gX6|999RNvJ>vIm] )Y;V ${Nz.҆]='Ga=gABi}֎Ui.ɞ !>kǪcdvXErZcUKh;"HH9ڱ*m%srsv$gX6|999RNvJ>vIm] )Y;V ${Nz.҆]='Ga=gABi}֎Ui.ɮ]O7+V>G*GJxmyRcÊ0"J qbƑ,b~ї?g+%:Q?Fea%ШedȦI!y%e1 "%A '@G^{5QJ+WߩSn1bٵ.!#w])1޽[1DIPWbsᙠ@oghCڸ |O6TTth9e>?֟רma: Ȗ_u +0}֚XU[)iK{JUwk%*Rޒ@o5ֽp_@=#du@Z>_Շ?KAEIMAESPuGꏮKW;c~rP-oڡwgpO\߸7I/cPNvi͌V G/rPDZk׊T󛎫JRwM7N~"TQz!+"aIbB]{N9eڐ_ KoT=Tni _*5P8D0.XOm c?F`KE 5$$& "$2SxGo1IG} 8-CB7o{ܠGꏲ=j@+gԟ?i$G^ yJo1Iq66Wa϶/>Gl kpɏ1!a#l"!]z[zDc=d=1&`Gg9x"!_z[z$S'҅`z04ԡs*?DB \_:tN'HHֳ؟p]OCX7'ߒ^_x8RlCP*ߺ؃<eOu=tD=tH>˜Z?֟ܰ '7ބӔa%T䟚kIx Ob3]jR/ԟQH#G_5_ԟsAYbo|GM{aj^9Ur?vgZ8#4בPR)v_c4sj; L}DM=7UгCRFpk5ȭ :(b#ȯ%D  HGRAlpeCp۵[^٘O[eW{>e";d =cY jᢝ2ԸwΎt1%$& j"}gGMiE_YXd + ],WoU[ˇQ Fڈs(*8HCKѶע%Ge% "+}CoQ ,QLqT;FNmRYL ϒtF.taH גqV؅{pE@ױqV؅c&VY)keJ dy(?WJc>i'_u|7?/xN?mK@D7^,Bg8y-]aM!LXbED%Z 6 _ğ_=&(As;4ц[eW#OOo_tWP_PxGϹ?P@C*?P+^Zp 'oTwOYSK7/A?كO۲6t8BAϯ' K̾ocR ^Eѿ8ϓUXU3kV?U'_|)XpGDc]_~ 7-ۛիǐCUa E`)Ce$ش5,Y2Ӗ+E@h̏?9{@AnQ}$'ځez5D1#LS51Pgq9G4l;bG\ {$/_d!?QH3w\H "vBC{v>_|kiP3u~h!hhԓ4PDd~Kjct+Hq B''W񗛁n ~qeOs]Ƿ[m^> yI~~Ui+& N!Kf\*'JCOkf ?_ $& d2@OZ^tOo=PBV>!8G"}ӤHQjM7o F7O)TN,?RHߎV,mne_ d{bH*1V2H*1V2H*1V2H*1V2H*1V2H*1V2H*1V2H*1V2H*1V2H*1V2H*1V2H*1V2H*1V2H*1V2H*1V2H*1V2H*1V2H*1V2H*1V2H*1V2H*1V2H*1V2H*I'j.iUذdHK~)G >"fbéd,#X5dX*FZS{hG6rE.ʱZ94a_]A—v+JC;4IACGMAl<.= &''gĒC_8???????eCqe0???3lqI\!$c8O{)Ʉ"JYpM'H&~8Jadf0(* v~] р('D?Q7nkɄ^&a?"F-d#/cL4S(~u0za&Q]ÃOffEdU w|KZ2`֤CF6md/8du):m_?_sBWyS//GDV-?6J,u '7??>AMM!3.AAv /_4 E[?PcϫK3 ? c'QFvqcK77"HM A V)Ixe +/1*IGz.X^!?/*Qg?W3Ma'Û*Qrv"7=Ͽ)"Jыb=d/Jn#e(XmdW7To q_UW+V@A%nq5zR'7GK, 6ȿ?ɿ+r?PҶ !meU>UH(`}[Ix-~]ٿ^Vsj'9aW/ b>U19T,_l 0UU^bx_[sY Qkv Dfڒ+*!eBᾃS8@h8FwSy8lrXٶLoL1MAߢo]&ߺwP@A=YP6:jB/тAf"X` H˼ < O_ }N:JӅP5RQzjPMB>VY"B`~`m-c6(+1_> Isj->aCiQ:-mY/֢$K^ 鯿MɌ^Qa~Yp?M *`a% "fo_?Qhn zGWD%5 pǣg wPLLߩS.MQ_iWy/^]%ԭOVOKSw 2:r<W[ۈ';a%b/Q$*`cF3`a+dcz+h̀)Y'JmL=}q,?w~I3r|C߁ں՗V "'̂?K?_ğ I _ !(\-dM5 ?PHHPH%¢D'Oԟ?QZ(2PFkh$GYhL'1^Ԙ*=dfYӺmQȈ6]\&'0,(X?֟u] ›fM+6`?CϾ. #ݧdskmQ.-ʍ#brzM@{+ut>%clGOj$Haͅ +kvMo/O/hLہ%OԟQE?RԵWZy3w\ A M\ZGIE7PThZ7øf>fk!B{R%gm-kk])yFI`?ϊ VI,b ;ugOL]"I[bb4W;^^3 u>N>|-kO952GeM#n txJ*顶DEI-K2?[OK,X䟪_3 'fZ~@?oo=43W_Z@aR޻w&,V/vjCr3R㴲((ofO荘3ag~ӠN] gQ5x9ےSVǼ1Ff ׍ir6 [Qoٵ4Eĭ/֨S%WOuw| Df{S:N3c%Ȧ򽃜/g/GJ\ j}c?yLAO?_ğ ?44J)/Oo_$WPNQԁJWOPOM/_P"Oq'Oԟ?/DI(O4D'O+_Tgm @+Ap'(OԟAIg[!ehVzw׹U)C14lzMvb~ьj(diPX6 W9e24zU%tT u kjhv_a?ݵT_atbn3Odkbn}oNvѲy(߬F.!+ImX1 3?X1?_KXd`T~c[3&5+or F5cK#M_ߖ(X2%@oOz:eJ1o_3 f+t+_)?P {?}c_\[[ۛ$b*CTrCB͵(}8-w@-ʉQi:{煜BD;YcXSĩUQ=J3p3#8TOsE?>|%MK,( 1&[k0{0ʏK<_4h?1?XE?_ğ*MEIMK/E^DMVxm@BUo\+2ipG6OO+u=pSnU/vnQ@MMM<nGjtO 7JAEIIyryk[7/OP+6Нy ~ܝp06`~Chп`(M=֐`Cm?3Pz!wKs=`f f#4XC zFCi.kCNǵ~x vT;JMSЭ ¦n~R=*K Y)]ё>Xp?׈Z ea% bLLiCj //z$iYN\#PD'Oԟ<8QsYLMT"OӇ/,pag9QqPBȃO-wh~V)V fʇkvաc#?k}la2?kzJu_77>iԽ5ɫ]{&, 0Dpἥ?KZI_V"c5c"PQ=YByݰa ""}c;ya&ڄnğğ?nfFsBk?em_4Ns1Qm y>WX?n\????r_$CRh# K3豹YXZ[7;P1>>-u談*(ʌc{-o$ѡAo_T`ehL1?Ea,Z0˚/oh`HcמSR#o՛Ҩ`FP|ذMx`X}.[Q߾?_VXBնh?|Q?1T3 &V{0H0BMM+#Tm[7ZQ }-"n!3OOOO l ÝZm@AAEicUÕ<p GRk1``30Bi4dGRk1`'tFحY ّZA  3vknACv$VpBg;ݚ[АIĀ!8cf4dGRk1`'tFحY ّZA  3vknACv$VpBg;ݚ[АIĀ!8cf4dGRk1`'tFحY ّZA  3vknACv$VpBg;ݚ[АIĀ!8cf4dGRk1`'tFحY ّZA  3vknACv$VpBg;ݚ[АIĀ!8cf4dGRk1`'tFحY ّZA  3vknACv$VpBg;ݚ[АIĀ!8cf4dGRk1`'tFحY ّZA  3vknACv$VpBgfƧ~e6Z%7"m=-I塥b h/mCEYm˘GaȰ?1XD.ĩ6??ȿD E rN, E rN,1t9 $¼Ar9 $`L]d*gN 0o\d*gN -@Y/ʙSz;@.$Y/ʙSz;@d E rN, E rN,1t9 $¼Ar9 $`L]d*gN 0o\d*gN -@Y/e@IDATʙSz;@.$Y/ʙSz;@d E rN, E rN,1t9 $¼Ar9 $`L]d*gN 0o\d*gN -@Y/ʙSz;@.$Y/X9;D SJBڐfR}ek? llv_GBd,%Kޥ!mC1O$g_Bl}wg݃(JAA!AGK\AEEEEIM{@CН%1\!z0?sKD)~@7o.[IP;"(Uf0믄4ԠS-/#dHM̏\ b:V@5$[E,h `XXS~N!YS'WuUmʒڶC[m)_/hJS O oS$(m6V_z0?XO1ʁea- "G/Oo4~c_ _iPCe!۰77w&䱧4?AAE_CK "$)/ԟQ&*o֢FMh8 Am>mE }rGHPθ9/A{$і%9}_)և,֟QDZkzDxW\ZR4\8e16F۞b@+롆E=p"g_v'⁵73!zSHo3JHCX &&"J"(_\gu$({dK %za*([EJ"d]rWGNEEEEEC;bo| )o+zWec&'۟ȻtKpSV;nK c3 4csX_K Y @}X[(UͩMTp'%HuX.Zd3>!TorJr ]@)N-_e~X ?__ 6??3~8QCEo/[mMɬ?PEMC=(O'R$'Oԟ?QF#ǬX#Wԟ?_l>UݭBas$jFjo Rh"U[S4Zep La쒈g>:Q'HD6_/|Bu ţ:Of.r&brtkiJj-6Ur4FWeq _ee<SG`~ov?؍4_v*,ԉ#[?K?UAAqpkA E.Q] Kf2&j.q7H@MA!'[l_bğ&?=ѣKa)]Ԕ4kgoo/OOO ?;{ޒbsS nYRc.mΕT1ok.mΕT>R`ݷLȆ^aTHĹIGwiz3+)s-/дŲ9֛Jx $}ˤ0Un-fJ%U<qeRU`Z 4Jx $}ˤ0'֛i(THĹICfv*\zoѿ[k2'6b_0XڃhN^qb~?_ V[dRmjyyFJI1-iCEDLz@9?@z( Þ u97eD%3_?!SC̭#$6;qvRG1?{^$M j2B:PzDZUc.o(HUXleV߰җyتX?/3H: Wl׊>䇶^ěJ/z^M)gSF_M֪v$|[{(әc?Wtd% Ba_ğ_?ɿ?PW@GԌAq zL3gԟ?S'q\zA+W{ɮ7OkSuf.(AlEK$%(MOrͮ?zQ>ȧ+*kSUFeaԡC[Gb%"$ZO&/W/sfviG@ne% ea"nN) ?!g.|__];쿱8?e_ $!#&("眺>umH3mE)Կ?6CE)f'',OO#.ܜrc=v04EGGKOCG'[!ݚ.xW/a_G\VsYU#9ky𩪴SP~±Zr9"HH9->wMTm>,srsv$gX6|999RNvJ>vIm] )Y;V ${Nz.҆]='Ga=gABi}֎Ui.ɞ !>kǪcdvXErZcUKh;"HH9ڱ*m%srsv$gX6|999RNvJ>vIm] )Y;V ${Nz.҆]='Ga=gABi}֎Ui.ɞ !>kǪcdvXErZcUKh;"HH9ڱ*m%srsv$gX6|999RNvJ>vIm] )Y;V ${Nz.҆]]ɻv&#oVح>}яnqƭnz릏_'>Ic/؝~[O~ӹo}Oe!/>s|~M?t||ԟQJ;BWԠOW9* W;'_o?ۿݚ?MƧ\͌V gfG)54ZizgsE_Q/ւqgkC.#cf=\/WoLGwמSe߽!9k:q{TzyR;%*n>H"eO={vO7,?ذ=/>/N~׻>Y?2g6٢p]_sx3::{̱aIn+oO_sNӚN'^}g>lO5Lgϛ??aSZՇ`?Oo ma' G> c3θ>}ck]gz埝=}^Otѿ[nK_q}أgUNQcms;CtU'iSbyEW7S۱}`NU[=?/F7Z%7[ȼ=woekxZ!`eeՄp& К;Nof֏\e WvvN`ZU\f'#Ñ/W/XK+7>ɣOӦ_ lڲb@LhvA$䈞i2RAlpeCߔC7f$a+3z*POhjȥH,_ m.g 68O'ԈgnyzF<~>k%MK](coADQ'*Wr\WOߨ>}rK/xO>y>vEg=ӛKi3NƧ7|HY]E0SO:e/8ec/|}EI ڗ~~q?+2v[t2c`?w /?ٟp)_ViaAz?\ /k?r\ -o $sm!YƑRHu?@ L?'X@{\̰?9zk^1T4v9;WDGi;U ?_D+G IK c|_.٫Hx)~J'CeĄx ^@㬰 s ) ;c hv!߂a!+/Xg]rI+$`2 y+lC.7_6Gg>ENۖRB?~=K|zӹ|3ϐ_>  utK_jEf?L?Cs7KkwF-@O|ߦ{{MN8]r鷟tmԿ~]/:Ssm Q́?XGVL pa'????Xi֟G???G+{yt۞į_ɯ?+?iK_´O6c$·4!% ;4gݡ -MzR($ 18XV@-Ol1YO/8/7-Tˣ-V7kہBҮO@48."rT^s ÌK0s^=ݤ@|R>dgL{L=6>?86Oy6[:cy{ n0Ϛ5׹_OgxrysѺ֏e? 1 pw{nӭoyiC.|\>S~W/}s^yڡ}Okv}O?Ӄ9⟟~MZyʌSG^7rC7\1`ɑ|K}rf8K?_~7 `5sy_ig1cee|O////q~]Gb9_m:+zru519mnG؟g ^U['._Oj?}Q_m?mu7H*a 4JE|gh2JE|gh2JE|gh2JE|gh2JE|gh2JE|gh2JE|gh2JE|gh2JE|gh2JE|gh2JE|gh2JE|gh2JE|gh2JE|gh2JE|gh2JE|gh2JE|gh2JE|gh2JE|gh2JE|gh2JE|gh2JE|gh2JE|-znyI/1 M{;$ /~6A2A{?3nw`g=xz'M/|KMg~k~Ǧ})_?0k3ۧ7+i'fuW![3n5=4uyГ-NޓCn]2}~pXq7=9099ʈ\t<_c,_CQ?%i)<}:Mȃ],U<=a7k#H$1߽^Yz@^8G>6=a2ݎ2{tծaV{<:DO׽Oäg_SOO<]|W=ڿUH̥?>׺T % iϯp2?_4xZ8ztW_cF3Bs3P6mkf-S??Kvc965|(lCpWOxx\w_ Wm- _kz=şZh B 3DJ7׹eD $7za&H)_ujOd@BKQN`ѵ] Yf\U] PUQN6;eQæN?UF^ 腙h"/6׭ $O4`z)I4Cv >[" NN4Eє*+5鐱Ն I Jvcox&7tyɃOn-mn5y19{kO~t[Tu{Hy&>[xNEƣ;{OLdO=|۞qy wZRz?r$],r7y3'>55 >]ZvH~MQDRi?ɐT>[Y'9$ a::Co~`={vOxO!_ry/rU=VztqOOMwjj }?Iw!G4cqD CoA! B n׼Y[isn_ߔ^qɐSgwe]!}š q }4?[[ӗO|A?]A/~ONw%ۛǘq)d XGJT<$@⡷%ZWG\f~/iV-dB.hsU%*2Vw!?>E 7=6Ï)"JJ_qژ%CWm}zZZFN >F7?'o|:Snӳ_;Ӟ;{fUj|?toO-_'65Mߞ~pz_i?頟;oo(o{:S>?/n=5lkִyq^E?Qx>C# \^g?k_f'^ϟzRJn}t|6Twy+盾Qi?|z^ם^@=Dz[rH?uҭn 2??_^׃jE~hV-H=gccc[^?~^wϻ}!"$ebg?e@CO~{wsnMm .?t{˜Y{s~Sgț^>|'OoxÛv_|tMj/|Kӭwg>y{xo?kzϞ><&Z=7766O}zm 'yt!5Mȇ'Sw]uwYSŦ~nW"۝9k_co_s-?K.{3}qr茗f7L~f6UkztW^ I.sj-{†jQ;-mY/·J`t-H.=ԿnJBFʖ׽zMn$3ϝ?oӍRyU3ۧMQ}ͦW6gOO{3?;z& U~}C=>s+g#Y?Moz?S|zse ow^2lȘ)^>[>-OWb?|g ?WVy|&_r铟ж<>Ozշ+oukgw%{Oe~zkkkwg'YcE~됺6f4x/*Ǡk`@# 'jqcîR+2ӯun4NJ>?v>֞yy{oxR塥 __ M寲DsNt7#o|ϸ '^j{|]DN?D|Og|ο}1G>:;N_:_3KӋ^g"?OCSf骃uuq[yOFe/\ր{_'X8Џwyw:c5}3V-njy?~J|'M|M?xW>V%F&?c=Oq)g?yዦsL?t<xk?//K.xz˹o~~]>tv2L1؟q~5l^sEߨwx +*F /z_K׿'EqY1?Xq}=n'?G7>pOzcGK.0^lތ0kZ7-0*wSz›fM/0,(?/|cXwWx3¬cIv_/.#^#}p4U2>2yC9/]gqI|D9=g~v:7H[)MXwlzK_+A?*7[瑚g W;azۋ[zɟM|rX:NgV}@IT)|tхZ_‣NqAsIY JNF.HKJ:ĉ_G%%`0Ë/7}u$K#/)OMx/XHJ9gEÛ˱*!"Zcǜ[N[" C&o u4< QHMPig3f|gq륆?ei'[SgOx22i'ћ}-'De<>Јg %EcLedlƟٟ#nX;k$G9bk׮z`F3vHpXp%-se$F~"~'Uo/‚LAw ɘTt\ŰHc/JA7DY ?!2G ң͕ H~E 2G?b%ļ8#f$^?N9(GȜa\us>A 3 i1 rrW==ח{nr x&OʫFV =;z"[_yoQqq z{VX}z& L'#n |z&ȑ=N|b:&\t -^ūS"ճ=W5y/W~O|3>;b=pݩˏwCk/Q'|TqO|X~O8yDOB|N|ںu j6o}4g,*P̉猳ΣU+{Yԥ 3􃿥i یlYL?;:q Li=_݃:ǟ?o?lw~1c`ff?o_m_?2v'>;#;Wf0UOFƟl7S5g-lm0"Ǒ:m\'>ı?[?5Syx*0a*SM"}N|b?cc/{y2 3"O@fsWi*[!ogO N }tO; 7u:T`B~;wS}Vz}t:d) |s9G~7.IhQ낋p5ջ'N| |=vӪB?GB$"V-?ޗ18yů|4yp-;a0 7?K']N|r;O[ne҂M3^75~_Kÿ2ub-O ^gc:|BA'0|aVzWWN>@wKc3?)pys(MSMYv31aYU 'q_f?xo<'Ý3m!&ge?'[5oc 6%Jn1wņ5ݺuC8Z=˖+VЂ!Vg!0 ׽9B?^nlIm1{0ɶ?LzX6-Y3SL|w,B_eͻ)Zr/P3mduZs)¡ %26Rqꢲ|Kh8m:NpDf⑦2Kũʆs eOJ D+iיXu#24T?u-\7xo'#:w}05_>ÉO֮]Gny?nێG ~_n=ʡЛs^o})C~Du-N|s:ͯA!"p"Z.^[9/9|/' ޢ+e៕=3sΘYI7C8FYNOLXH/xa|rzeV-b1N{w?T>n,֟K6~[|ѣsֳҵ7o|א"\%%\Oi}EMeP/jhStb`ZnS:dӚmy?LMr8.Cƿ? Mk6c_ˋCec[Al`?[y[=J施?"?y5ߜ?ko|?!T߁~|;|'[ޟ{du(5ft@GS9ߙ@IDAT\T~SZd J5?T"(^zTR毝;w5k'F/@Gm]oM7\ ? '>x00'>m0/JK;xҵf-<ܜ▟ЅʵIIxПʄ6O>; VZMgs~ϵE]p;쓏 >zMr533;t?6lm¯c_f_ 1D&N>6kG2,'k_Ҏ9>_v O畏"c `rݛfdSg-X0.w36F܆??ӿ6W[.g̟7oc8]jj,y |=_kάʙޖ?2?PO,B\+PpU Sb7'O~+{0u1"OS$Q݄0BzMdWL7kf3Ordebc?6F6w 3`}hW1*@t]:J O"epZq}qx1kkq`~K#3%_7m᧝!/SPrI.]rρO& ab>iQIfħhh>+pdR;abx,qOw3܋< !ߵk ~*ů!oӍCX'2\d=K>ɉO[HmnNgSNS'1 'OdUܢEJ,V]S#1c΢}{#@i?~J<{i]83nG_Ν:SS]Hp΋/_~{rto,5tɠf7GZvI Iи2 #2)1*7?kh՞_z:*A\韍?h Mfxc6DLwx4m?6?c]nYSby z}Zz kT;N~RH˟qSVzĉO3-8֍^xv&qpO|ծ_zVdJ4+~hᪧU ߽?E4;ߢ> ȿ[āO`a8i =D?`迶uޤowJ#F N<1ܵKuxwyk/ϡҒ-M7)Q#CI䴧iH={t#ҕWѭ :! _N-6?0 ϟSpq5+_53H?dϒj?Pof&.& 07+?0:6cOjD匢?'xz8_`:/+2ndMA͊}?JJK&cm?= :mZ|NpG.ة@)~߿qn5pctʐ!xoޭ&ǽKY[~? <{wܪ{ ٛAtH~JEٲPc=z-՟ûé|/Ro [p!@Ȋɾ⼀~~<ʙ%j@ @'8Y&9SrpO%N„(A_'7qk䂛NƏw3MAݪJYٿ DI[թS?אmsm gwTYE7Νe}N*qH]k)٨469Ej!uZigT4hbJ#Pi(SJRWŚf}6*@M|N*qH]k)٨469Ej!uZigT4hbJ#Pi(SJRWŚf}6*@M|N*qH]k)٨469Ej!uZigT4hbJ#Pi(SJRWŚf}6*@M|N*qH]k)٨469Ej!uZigT4hbJ#Pi(SJRWŚf}6*@M|N*qH]k)٨469Ej!uZigT4hbJ#Pi(SJRWŚf}6*@M|N*qH]k)٨469Ej!uZigT4hbJ#Pi(SJRW'ħdDnaـMc]hET,JՍ~ț1W!~} P21nf!)L#q=*t rgYnڼF:Jpt'/r;hq{AV>*㪧zٮ>77r֯H#:v؁vPg5;8>b8q0t)HO~?V4,O[ 7]ye?i^CW?A4Gܧޜ7_1﫞6mڸTQ&AF=Câ<=ۛˍ5ZXU^{SUTL@&)*|V5c{0?_Ig 'U"M3YanYL 3#)L[$)igu$ sK$ 4f`GR0$IR@ 8H d1I>@ h30anIq֑&-b|4fIaܒ,&HM3<#)L[$)i0;„%YLfxYGR0$IR@Әav$ sK$ 40anI1 H d1I>@ hgIaܒ,&HMcؑ&-b|43:„%YL 3#)L[$)igu$ sK$ 4f`GR0$IR@ 8H d1I>@ h30anIq֑&-b|4fIa¸dr=P=^ŧR\mGPT(]RU)LB{˿rS| g?8}ϯZV{Υ;yk?>#6oDOF18= yT8JDAoYX\F׷p 87qoηҎ;P]e˅^?=>ʼ?y82|&3ڨpLOG0ܛv P; '4i[s_Mֵ >9ھ}kѓ<;رS~;4ծ;?4h H0Mlc̍>%M7'yfg67,*?mg/11޿ )0Rz!bȝ3㴧a'*oc9'(ƍO]g<7ue'~}wǎOݺw*ne%5mtlntIw9=s'?i424r$'p|pnmcÉOHSqz |yS?߁~oQ[?$]`9ԅgL?߿3>ua]cwq>/ 5HZozIAu?? '=C&rDzN8i&]S~*6f"i/6>k:|F?c{.?n"pHyA@^.rUJRqeQ*xӓXoXg_J*\D8N23. CƟ j)ҹ4֕%TKU2. C쏳 i9M |r0rę&"3BAe4P3NQ]5kpjypkԪQqzG?όN;ԢE 鴑gI~a~80,Y*uJsń؏;W^Α?VwC:aP}L_qSӦӏߨnN99I䨯Qp0 ` [~f*4dimRX.I_?h@_z h4gKt-mܰ9Gw?}Koy\];}[y1! y]w OQ{_Y崙I 5y'B(lx ? /ӿ9Nzk_iƿØ943סfth]@5k?6q߿ۼ_ |oHKl4ڗnݺr> /$ilѶM;+pxָ?y|nۚ.pjEһoe' 5c[4֭;X{`o[`!' |'?|RfTRM"74 wOΧl {Xpq rkׁ9kN+r+Cp#{2?wcSH3o~pw&'OTBRWE^S`9!#yiBI׏s)i\t&P?f0t淟5OXMfmUqh/^\u6/`ɿC;2x0 !pg pX?4b,ۛY|l_{sϥ8ЌUxwmܸsWԡC[iKZ*~u5=k.>!p߭ZM;i˖OiӖQiǎ lDVM-EL=m/~_:wًڴnC>YF7mI?iӁ:vHmڶF0F?tрh>-@oVlsXiS6h#w{;QII }t+ڸqIm߶MoO1ҩM)QGWx,Qh{ZRǿs1Tҡ#}Sų> F~gYf}ӿu띮 Ki?܊ #ဝY8(񘳮Ɵ\ɧ[ bxyX4&T (Q3[4_Eu Rb;/hIT)O&~ Ji U2H)4*A@Tq M'W@R!4qR*_MDHLyrJ|5 Ji U2H)4*A@Tq M'W@R!4qR*_MDHLyrJ|5 Ji U2H)4*A@Tq M'W@R!4qR*_MDHLyrJ|5 Ji U2H)4*A@Tq M'W@R!4qR*_MDHLyrJ|5 Ji U2H)4*A@Tq M'W@R!4qR*_MDHLyrJ|5 Ji U2H)4*A@Tq M'W@R!4qR*_MO|8Z 5#>| JY&v`hEX #E#k_љGE¨E_4s2oo */lSA0T=Sk?1/ܺi"5KK; p/?ƖSn=ĆiOO}W>^9Oky'#D@pO /s𪻘lLp,Dgn]{gP[Ks@4a9i :sLV6};ҋKP7-.D%>@Sc7xyO.]QgJP̿Nf?ծsGZ>7 yTa(jy#ב pJĶ-s+>=I>Is'x 6Z"8)-z݄@(I'LCG|Z"P,?QēK?-c%tym9?]ںuKAA@?r|/?a|7~LMx`9B߆uN{&v6$=c-{*8T5# ~Wh]oo/WA5!v Y|ȇ9oq7L|"T=g3i1w\VVn?̇B 7 fI>@NH-I]c-[)OЎsIsϣ} OOAp|0AO>RX̟Þ|1ھuϋi,Qbzf @4o@ǟ|Lzf-]8qig;i2qU|>]Ti=V A,pzThI$rpC_YρOlRa Laky$\Geeey򝿼jjjQ{g "(,: o/^g9ooQ{?m3fm {"E$}l~?ur1?3u^6uw#\3 ||`!_7Et= +8(/{_>mۺM?~EṯMӎ[iiO6⤠6ҥ["Qڹsgŗ^Nu઴yFy%Z}4N::z)_w]/ Ò_/_1-Gڮ]㏩vy_F-[؂nZ>={>}ԩѣ?H۶&7'>DS~>x)w?qq?vYO9|ݫ?=m [6W>t9Xħ1 Z>}õiF:u ڵC٭ 9%~SVAۯ?I]S(>rԺMkysi+O/:!@r e"?g`w/O&f&2?".5ǁO߀kL?ߟɩObCPU=AJk2Z,%i7HsW+U3!': Q~Rثb H bXt4^1*rQZjl Q1JwOP da@W{@l! ˗@IVpsy]FEEy@VҢ@I6ԈQ1JwOCm(EQ1JwOM ӿD[JAQbT b?/lPÁ t4ߠaۍi7>(W2gґ@$o2DÕ"|DSl?ҟ?#oƿ^#ef3KJ:6+_: \o/ror{{~xܽWO:qr2AȬ\>I@Ti>C Ν;'8yH߿iP/ApS|wW^>v(-A@ҥ3=8NK)m*+Nb>3 j}?:vD)>uhݧks_0b\Io޼Yv+h{maA7xUN9Js}iAJ;~m Ic_K$>p/EE&FY[*vLS+s8-I>q L4uU9ϺI(ɴLSW5s8-1Mp!iߊymqE>=%J{iOz'\|ڵh'eg%Ӧ 4G.i߸Fu7c6zR 'l=HKYgiwђg^t,^]KpTk{ 鳻} 7&l۟C1ٖe?[h~v[Mu ND@NnG~W_{U?9= nڝu[naz 9~'Ocr}@e4E2t,U ?/Qa<Õ"f>ƟlA) c7gmɕ2f8*)l`ZR?N|mbcc͹A%u4P'& nsn.Jo7g^!R&&MUl33W:dk/?6`Ϳ6+%MP?BD?m͓?_l_`l_R$IS7iY3Ɇ?9=i;=i4 m Ws1"$ןN_|{'>> ?C@rYOIKJ8 Gj{yzVn4Nⓤ#'P&f骯(L֭阮]pbEz \t8ݩ4=gO|ŧu}*<_\Z͟?>#c9"aPk!Y W-GO H\_Nlo֚S**" q6zl߷]AF?-&D[nN7x ~o\()7i4]%dњwiP*i'%pZd8ּKPR9\5bjUBqyƿ rk,Z.CJp NW Y]* S hͻ4 U(%\(8]%gњwiP*K&PL-pJ(΢57TTpMZtPEkޥo@.@1*8ּKPR9\5bjUBqyƿ rk,Z.CJp NW Y]* S hͻ4 U(%\(8]%gњwiP*K&PL-pJ(΢57TTpMZtPEkޥo@.@1*8ּKPR9\5bjUBqyƿ rk,Z.CJp NW Y]* S ceA$A6R SZ)*`@Ë)_-Y:[m'a5@!56g 0{db48;*'alg_[S8^Y??֛f77#a'>}$7#6tڭ;_>^v8PYq7t=dP2l^` 2n+BK=Wԧ_?j9p6ĜE.%wz |I 9MJ>zq RoY |/X8 K? !h |ez=\>7(ƉOOZg8U.>Â#w2pb:g?#zw^A^z.3dp 8i `Рc2g$a}--]}Om6p?XzPí[2c:a/?q⓳n<W>&HP꬙?)<|?SJjr>o.|p/өH9)2b%#[Ht3"D7HoT&]?rEc,ynGe6Ƙ1+XֲnTC d602kƜ4\҃-طl0Q>񟍰M+JgȟZn_Ɵg7g?6a_?do]mA6 [cϲnC>/2'{t+ ֽ;-Q8]!ACpړ[}C۹ ;|jժqۖItJ/ [^B/>aVtZO*As"trR?>*#[=z%_Jzz߇}4A@|-\0[s@~(vħ^)cGzm` a~WN|G6m ]Nz~KcgOO?E#7u!gp"ӟS#T!wuMu 0@hg#K># N>*/?瞝Eups{ {a?`sfcgٝT:P?N$:XoN_ D+ד&_{= ((EU3j qʹ[3Tӝwp{p/n5f@;ħ:3bFS%P%Iq!_d$ˆ<&E$ C#LL`bc6kt =5a',.B6:u!<w"1Ѽa{e@t}.5]Eowdg_0Kn]F"46?}u`mM8o[.iO n-?h?O^zQ >@;o)Ci%W߯$#ӲeKڹs'DK|@;966mڀ8MhmʼnIp*TΝCE5|nNt /(n3N>>sGK:~<,)?tp cb}pubkpRմS?W?ܭwowofw1P''>]{ʪJL\߽ҿ#ilBpӌPLg4,KG*gJg+p8c-fyT%y`()wMUpPEuuu$u: 8!/_Z?54uo҆P!/_Z'rRHS'וG]2;9%z*$u%qyB@_LL=QHSP<P!/_N(J(I]I\(u/?'ӿztp7JhDV- s^Z1@3m1>Ɲ7!"  #9<bg_l5/?lio7/{Ɇ??vN  ۻBKt2YDdez_y3\ޭ>_aZ 'T;|ej2x+/SҼo+>O[z4ZU_+~3C;N޿/APҋ?l <%.zO?']J,{~ӗ>|6ғO< 6OBd<.(?&L:E}vԧpkqYx>}zWyJ?_w CV/pϞ=mߡ];t@ xaYȝ6mh(thA<mڸQdz*E|Ӿ1s,o׬߆ڵ{?4ĉD̘3>榬?'9Nl|qb/.?DrG+,.WOӉ韊G%k_ ah@Il_"\Ni:1Q11Ϡq_,?C9 {pi8/:w  !3nʹ.WT@IDAT T&",韍?63f'Y1>|fQlMȋ ?XO_na QQA/a\CSY1PL_?xǎ_b#l`n1Sӫ߶pӃ.*-;ԡ$!~?JKqM#ߐ$=9<%< ߤ8)<<_7; :8w+/YfΕ./sW9>ҵk{ }̿=ꨣ_r;޴]?]jӺԭNVg?jyQ RjK/LZ}GhM0ᓏ2>n|/߂kr~xeȜSH=E8)۷oOpBDVZEs͕ D;?Qt|e _ wW^~QgCZڤ{LjD@r@ߵ͍+/n?  R4?F@r~ͿP[g"zۼN7}WNCYNzP6-E; %IO0``4@V*Th|dWB۴޿K RrU8M22M$8B(]luTB<4)Ka))&_v\[R ? D?fdFE@2ޑWbE(+H))H'e92h`_4bz/^.,ܑؗ,}ntog6hp)~_a8 j0OU:73C$lio, S 6Eט8?llc R7VR§%H 6"ͥ?,X8O$V"iŊeev悜 xJY-?oG;%Իo?3vI)UV2cE˖ty7"u , 2TrviS 8YISK+TJG'L:{,E3OkѢe8-}-LJW1ؾaڹk'^@.AP[gւ4҇|$siw_*ЗcnOW;O|Baڴ'v(/}+ HGKiLk+)nwߦ7^w'CY'\V|xv8?SڍzEԖnD>1Q>?9(s.Ծ};8mظ>GL奡?xJFRuY;_u rQuz*j6V ~z|ԧYPWΧ?6z@`Ս.*ؿà W~,J^+q&>SMM5-GГ;Y |2mh6柘beq:$KG/;G@Ĕ|qbIp1m$@ Hwtd sEHcMldgM6bqYseQ6bqƟ1‰OZ_S^eLºůWv gŻ toM2ndx7l%_.vԟVN"zm%_N9we>苩kz ̗!=e0>|珽?h qM6GԳG/|p;:ǯ`=Ņ.RV0|Z:.J:}k>#2ҥ VE ZƉH>m ?eħ3?[8K?>'\|Ҷmn8w_>QMu g0V!roܰ޴i#ѓ_-Ϻڵ4}SX΂atw<svN ~!N/9/uAGy'cmQKsϧ޽iOOuk?OHן<όTlLSxAg;=mտϜzn7^_CS@ih=>7ȟ䆹1;v >C+W.k|#??.ecE n/؟66t~LFyJ]|:S^ܩo*hQx? |1Lr/jz􋧣%WӸrdaQ5͚Yӝ:ʬX\6n<:A{heUﺓK5( _Xx:4|? h>m4*E܏_mKӨ4*E`D0P4j%r7 Զ4ZI\F -MVҨ(y@mKӨ4*E`D0P4j%r7 Զ4ZI\F -MVҨ(y@mKӨ4*E`D0P4j%r7 Զ4ZI\F -MVҨ(y@mKӨ4*E`D0P4j%r7 Զ4ZI\F -MVҨ(y@mKӨ4*E`D0P4j%r7 Զ4ZI\F -MVҨ(y@mKӨ4*E`D0P4j%r7 Զ4ZI\FNFJeF͇/` oI8+a" WiԙgIpKq1nv5_=Y:B֭iԳWoj!۶n7x]>LEO4?ݻ:|8]j-tr"4+/=0 ''> ˽cN8i4(IEA9׮?G7֦?l =Z?Mzk9NҥcqN燎'>6'>䦬ߟF8U?7_q_iۆJ:t;d)>~t:=ђA~O6Zj%4wիmہٽ-f-yً;nZ`+sm-J8N*6Y2P%3;)㡏f~@a{'l(q t4.-(Bn]}^}@ hnݟ=p%_rnKOs*gD(!O4p8߆pZU$.4WU>n3<()|TL^'1GAI `r8)=:JJ0gILyPR"0%<#NbJ΃G @h-qSzt>* `Bk &/ψңDQaZK0y9xFĔ%% Z3$<()|TL^'1GAI `r8)=:JJ0gILyPR"0%<#NbJ΃G @h-qSzt>* `Bk &/ψңDQaZK0y9xFĔ%% Z3$<()|TL^'1GAI `r8)=:JJ0gILyPR"0%<#NbJ΃G @h-qSzt>* `Bk &/ψңDQaZK0y9xFĔ%% Ad{ n[dI.qJ#" w1nŹ;IMgo2?P {a;OmZdYf/[دpG,[_8?e[߶`/nUJK]̅p'$tk"˭LCGu`.-?rjiӆtF;v۷*5_"OP?֭v֟ALmڴ8cM?QTRZ@6o$K~vo(B֭TځZlI'³)!ϖ-Z5k|$)>3ႉz쑇hۖ-yu\JG֮݊[K[ d9ͧ?:#h{a7"5ѓHcZK'Ϊ)'8rPlO"U{7HW>eU,pweO.pBƣfRskFet=͔E8 rʯyNi!\\'JJu9?Z)TisӘ"y! :ǔJjSnSİRs 09š5McVJftP(wn+ a o$2i˛0]+::} )1,`/$'9??f65+m"wdn4?Q$37miob/#Aךb/'(Kfo* ')p@ F0S.\0'ӿkySΝE>Z'3=~љg[u6zm7q |: )X`(YWW^'Q&wy,&>шٛss9 55/Ȱ|NBz{O&ʟOASu4E X.66l#C0Jl|D>6?fɮCOy Epd.pc*`Qu@ï+(eQ蹒_l2"o7`fmg#Bad_?2OFo7" [)I_"T.Hl`/7w֟vsD)m[+[֟yӄȂS Q s:׉hy{ 2l(pc޻N?n7Wzc˃mڰVXNV$>=wtLcXk/owfx.w Ejk׺V}C3!~9IzO@&cŁ ;˗jeIYT&m"&BoF??fX@bO4c*(Ϳ~Cl1WP()NcaSpG 1Nj + Ų@}+|*ʈq(C9hrƟ7c6: b/eͿe';_t~m_llQV<-pD{iN/z`pNOlH/)ȏIG[>a|r?]<1𝏓PD HS #O?t%ҝ~їTꕦP=ӞoUq&^Ņa\J5i#O?fJ/qa+gåIA`eb4/XQJ˿s@&[ ³hقvo῾&C-}ߪukѧ۶5ۗjD?㣛mƍGT;a7JЭ?mgP1c]^Ol?|Sc/=z߿ޣ}nHj׮\2Ѯ];iZ[o?h{B8@oo'* վԘ@? `׿竦zԸ@Y3+mS*/@8J<J?{`GqݻZAB$A&B$l|w}w `L2`9gdAY(kw_Uu{OaQ@tuuutMuuuͫk~!xC<O$?rLe9i=) *Y:9&Ӛ %I(uc.><) *Y??ȀDǽ (___y&Kj"bA={1".dcRv@EAyL4#Iu># 0q`SO ge'ݚ*EG|o wqf)M #G |6m8cҹn /Qm}߹K0baG> ~qXrFGv '?qtm?s\[udS K/.^sZ鲍;uj C Ֆצ-Y.)]ӯœ/>iX|&2Ϸ5ߦ\8~-X -csqqQPRn ?\p>C>/c?M:Dz|U-ؿ-dҭkӫOXի9kl鱥OF%?3-(' ONTV8KO{jmeqUKSLNc;ɬ'UVK䪖G9QjMv5kjy>c:(oLIwPF?οʤlUU렼 +OJS2UsG9P%Կ} ðv r'V`M(QQ&59݆)PJ.Эk7=Y&J.Wʪ⹯ Ф3 C̟f͸7ҙB:2a#F gLg~kXNF p>p`ƫ/!乍!?îz筷3O=O>=,]e٫ᱽa_˄,Uڿ%N: h/3nuQx*U&L?^xzW_=g wh[ڑokk O<(T&/[ߙk߂׶~$#W-:7&_ՙruC.\՝kg&\_Y|pqA15?L7?h4x?c>Ak?,:CϿ?o\/fqSߔ?ʟJۖK/"k%Ov%pIa],>pxᇣkk+NTSӗ!D:vc咇1Vݵ"nLCO+ Ng%rx#|q48 p19M#Gˋt\.)++]Yן)gӭ?nj̎տ)R,x JST&y7R}hڛA3XP ir;r-v/ـ&y'~dw߫96nݷ ?3۞ CguNfan6"LDd7EFytkϽ^sCNBQ[ {x~0pp8u{ֱuw$g.  3%moc}k_Nb;󜩡waycGu[_]G=<.]v S/8H*ڭB BB}Q>ƫI4Kqa(\okyM9-???0 h} 3l|'_q Xi~'Xo/axQ?Zf?{pQlGwCZ{'+?f'>䌮[/\*LmbAȯؿG6Q yxZ6PS:OSRBMqb:/BFL2j)6_4dPSNKQj$SYfC}$&cT,/Nz96݄6/y 9K8-Y*QnX7|Z[|Ot>!b֌i:M9G ħ0v`ӘiL߭{pek5fҫW0ykvЊ2:jo'O0>{u1?C~/Mv韓NvyW̡vD 24>йs'?t5uj-뢻YNbQ;~a P&R5r/s:IR?.B%sڹH\1qHN`(>esg,B! xο\ҜQ9W|K$_I T*f3)'V4S3EsŤy#9z>i֍nT@+r"XEd<;Њg7}:+\*^jƤs4,,x4~ ֭GXOh_VXg[1b0'> gL9,Z]nIp$o&D{N#uF-c5u/|d bޖ_ڵ[h/[^꿣O>kHvՎ_-W_S. byݻ/NcгgϰD>Mοݺ컥靽sC@!Oe!"~m?-]![@Fe&7R|q'v-|5P pŗ[rcM#!?tm'yGniw+,^IZƆ__*{omZ8999ePm]_h5نT:|OEhA9Dņ}pSG4 bD>lqQ"oE (2aq$^m[nn,oxaw-KFԏDhdro.KF.o|U4@J%#o| UTFJك XT/(ʟ HIP"{4@J%#@SaP) Jd`Pd~+ڲ׭Zyt7H1" d!f*ȑIx>rQa{Nxy6&- .16 ǜpbݻh֬^CUVھ^?sd>$<}Z&&yO3 S} ┙.][״oo_SFű'o;\-c5K?͛Nx?s-aB Z>.j@L@7]r_~ ρBeW<݈a֛1^vR~|ྰlR:!C*ˉR'f}mx~>䰰{nݻ3K0O>>C%߈R&A4'4C-^h`ͣ%̝4e}a 4xp p !COϿ<=ЎC o7*O붶o* ]K)=#dN8)_~aѻq¡G޻O #8M;cV)J^Iַԁ 22e6 .|ìdOS8uK2Pk,_@:JVmIEFQףiSjUsڵJ>P+?Կ\˓Feha@ w9In9GdA\GkČz?ۘ:/NZ,ruj=npi;WvrrN&O08 |=p]vDDm'>w̘/}80p:*W . =zJxI%8e(s]fLC8!"rGKsP< 1v$UkL~:v '2A̟;7 @$i/eK5xFlstA@v0Af̸-,?0N{m5FKnuPO>`n&L:+ G. 3n;O5W8ck~t,N {H\ rO&\z?R"s&#O?4M^~K/ReȐmT:!H Msk]Pomfjr_0/Ÿs"XjH]%7_ 5AůSφWX_H @k.0L~5 +Cawk矛c0&'}g'Zs'scv#jFxﴧxkZׄ>J$gO@2{[ x4 4|嗴ǟ/J!VxPʀl?^]KnRnҎ;zOGGuq+4=ڿ j !Xl ~4?g/c$Y6kedb*LoFGSP^Pl]G-I?b|D]ɉB\NjK7uHr#{Gi1C\>ʟ G)Ђ?09__@]!cVMeҵw_<߱H[8+f]vҠ/l=o:w K{GTnZ]fЌe.z̚5k>>Gàؽ ; 8iĈtk/)O;4:!Kg,$dm8~=G>˺? CqNk\B-Ii0] ސSE B+W%Ćǟ:s_&r|:3O Sʴnc^}O׸ IN.vˍS~>-X@OҎspđ(FC䯥3&=9_[wwwhVN8^.B?4W~dZk8%ϴ D^=S(DzB VpPGRi, 2idۮq߿5ys w̚K{ۍ>: mZ FpVؽEwY@xiavFskyv)P{j8ek+Obq޴u0Gl=O%oR^} ؿ/$pRDPa꟨z) odr'ޢZc {\ʢjRrQP0oicJ?-@Bh] ?qԪrodM(s- _\GϞsK*-gX^Kqmo_+~lw.v#;#C$Qe:x/bΑjH DVBd t2* JqfeT9S'NxJ3i˨sNR+bO+1fӖQ1HO8VŞVc6+@-bΑ:qJ=lVN[FŜ#=uZ{Z)٬49Gz)/RYi:msԉSj^i8f t2* JqfeT9S'NxJ3i˨sNR+bO+1fӖQ1HO8VŞVc6+@-bΑ:qJ=lVN[FŜ#=uZ{Z)٬49Gz)/RYi:msԉSj^i8f t2* JqfeT9S'NxJ3i˨sNR+bO+1fӖQ1HO8VŞVc6+@-bΑ:qJ=lVN[FŜ#=uZ{Z)٬49Gz)yTO'8F%/W-m+|w m ӦؐZ5Iv) %i!&Ekez>믾ϯ%:~cz>?| |㟄@Y`xWЫGlٲ0 ^*m$f2W>C{\;o޼Ǚ?xpYS4PD*LnOpG{/' \BINP>~-+Uhi-7 $:KPc{#:V96y#iVgN OtG$vBxӣ  &g4ax78K_ɉOG}ߣ^.^ [f͚L/{8Ilf4>~/[4葇=cuu? rr?`@\rҔl2PE!): ->?„pzJu6%?}axAwY#ǞxJeh FK']zŕh u07fNWtYݧWr&yha_}5&_7֬ZzNZ/AO\xozrWAxZT1amIS䀧5#iLX[R9i] d$ kK" <@Icڒ*'Oj #iLX[R9iMH֖T1E>AxZtWIcڒ*'Okz-FҘ) rӢH֖T1E>AxZk0Ƅ%ULO@FҘ) rӚ^ 4&-b|2Ƅ%ULOZ 1amIS䀧Ew54&-b|a$ kK" <-1amIS䀧5#iLX[R9i] d$ kK" <@Icڒ*'Oj #iLX[R9iMH֖T1E>AxZtWIc¼d4jB>3E B~/):vYm#hj;Jgպ͟@IDATBkA_EH8קOvib ~tmT4`N|".d8 '>T8IMMWK@G=3;ƫ5?mbxɒ0}ڍJd@#%?<ߎ8u͘vm0wE0ǝtNࠌip|£=çTT"`%Kb|&ڇ/|հa#pәvljO߇+V&KN:N %\D5 Tq"ӌּ |:X" I+?S̟N7$+$`ܳÛ&+_vxCGFW$uҩQ{4_1ʟ6f] ڄl*%^Ө>h!W&F@7\yۭa:;2Ik8H\6{z_N|z6˩U>8Ak+ЭK7=y{VHYW#xz2y=9܂Px1dvͱ~S"2^=b =akϽ?(pu m8aNq;|/F?s-d6ÃD{XbYX7mJÎ8*8=Gp?n}j.\H(n%Ht+%_ Wu4N|3&Yv#GS'ZMaC?}"Cӂo H(cqzTGn-{gm3pҗ .qDk}c{cF~GNF\3g po>1DS>^{U^|8(ܐ.}Ep֗zʒ*ot%KMBxGq֐ZN1좙G蟋 ]o |Qx?+M>}?x0Ns>t@'ݷw8ͨx|w ;x8 %#(ƿ9/? MlpqQ`;x) 0_0tzKn:6@GC_\OqqqɖouAhˊe^w)v7Ǧ &Fw|ҹ3f#=*믈+:Qd^\CV^߻,K=?߿qO |j҄n±[(5aJAvS[OXObؿlf(_:uϟ|6էpy ?_[WpKcG_`K^^βo#]qqdyLʀsZqvi[ӞN|~,O}!idW"C>p]wSk'MO? 38Vi["B~F#BU apʩP֎SpH#Ex3Ξ֬^~lGC8 `OSOps|48|W;@Y={~/|Gl&'YˉW:aNplg9jᢅ 9=j4j7\j {h1S)S. 3gV=7z{EL[oar US4xp8Ydp B%b(G|e >w85\Ӗq;N:Tuط s8g8hz>t㵩S%f@3p/A°'d'>Mq}8t'/dhM8zFNjǩT}A*Ӈƌ ܴS? KȹJjjjAǚ|m<NTȊOJ /tO$4lKӂ\{|uw>Zn@@R/_dgX |IQ1I'"'>͜~ T=;hm?m/OГ{ Kґ~)d^yTrN񃆶?4w~anvö3X0խANZi[ӛ.*}6Ib  &~rk*i5/W_AqM8stwG=2Sp^x| j'rn5:܍/eaHM8Y=Kyw~Sai?eE__{S:*z5:~h=ګY6%׉'viVr]{o0g[W v _!fw~av #e'5֛ߚ=[325_s+RYۢ\6x/?i_?οҢACԿ\h&!6tҝr$+?rZ;폸GfVnJO!'?<}2OSKkfQPlGNzZ?C?|s@蕽#M<,iӧ-'I#F ങvu5?c4Gڻw|$Oprхa@ay8 8/nii _ewǿ!ALǜpBaԎhIOKNKpj޿>vg8cm#<$5)YΖpzQ+Nv a%h piVG*n*ӝN;?TovSXd Օ6:0no \$ž\'9iKABO2ٳ-)ה/hp݆DFgG}ם3ظc,A׳!r=CDpR 'r}SY;+^9<֦ǟva'.< PiC*4 )h+GeiD(/˿ OCA'ot;pU '_qe?LPFl[׮k7 ~Bkʞ-bv6o/5u֨*FdJN0dAd^"C+t-ۜA}go! gsRjok-3&97\1df]tyGuB2B#X+s2net LѿnjC=y fi WLĶHQi>7G'7V 7\{6޻w.xf'!/?0U |ѝq9am #@V _n]w㴡[c?f=prШ'K= z.瀛—8澻,{ Ўl v,\^ҥ[8KB4{~uiv!4t/,[TIe"ۯ翔_R>N>Cmg@3,iDž'>݈r <&q&0C 쳟oZ=QGwWݻKN|*/r"O t ץ_\dYK1{~{""Hp@d}9w,׫W/|G/uvaO)uϾ[]_㼋~zm|5*{C=\b=xBnN-avG0P_iww-\r.u`{tϖ[nfMC/R '~ޯx?}~g{أСӼ8wɥ'zWs._=*Y*mh[F_ݡ.)|ӜSuC8Ac?Ÿ#|0ջO药»UB _:9~ ?y_.Bk^G?ʟDi<)& ??\Žd)+,ĵAO/QQGIWǫЮ@~[D/s*(ߜ)t>Dw Xǹ#C;ҥKwq2ʯ?4{NnD+?x_ᕗ_ / ;nC8B@;[E$h{9INz@ )}%' zN': QC䬼'O 0o(rם3v1ħ #)>q߬`Z@:0fa%07ʉO? |: OR'lr m OD'v)MO0QӤ{&*!оphs6<30WNwC*{ߟDpiLg}-A.°#9l% Ku1y$@ bl'#lUDݛreqLIF©g(K;Y|{|N76|?2NZF;зO_)w9wނO;1B:LCR ^voaՀ_^ɿo|G2Z)k [ӝW_fyT￸G?qum"C/_ڿEnJ ?O@KoСw ~kjJVA!?$`VKy$x,G/iOa_'m{Q~+ ED +n2/ԪsOgS$KX2M9G4D+ _@}kOmst}_ |KQ`Ae-X$ ('JC4m U*pammomT6> 'ݻ+$''O8GWs{Cw92I8i(h iTN S_&V4[pZ2]v _x* nV?o<F g~sX5?c{cE!#duo;찓IkT}aАtsN89ݨ O?H/A5O:Ka9%kyQm=8Z_,}>܇OħMC0|m9L~SP x%>tQ7 ^K`G9~O9NIj0r%82qXϒ; SC^+|"+V.O_ۉ'#'=!j8?$@/? ';ɯpEO/ꫯZ"/#GÉG8rDΞE@oɉOezE_>!L/:Υ-muoK-]:\uTA]ϒ=='_Ưk/? L/? ?`ef^[uNa {D?Z[[C+pիE'Lx>aF@2u28HuĥBd4 @1Du[T`?/M@O/ן(),[U"\m07eGQCCY 8 -hPVAK}KiIa5߳pDN|+" 0 ? ' ykZ=Ç Xi?\mܩj/q Ο5B) ɉOi_~>I2;spCq'w@8 #jotO?$ħi|iPǞvX`n>R(ɒ t |Z~NS?Q0u$c!tϝ `.B{'} Lg"3DpBQv' |KF `jيNE<чO=DX!AmY䠏QϜApyoOބCж|崾? ǟ4^kJaIvo!a0])])}|bwV6 lu*G Wf=pؙJ_{曯Ã8ku_z8cØ=Ul, oXxw,$5P mo5Nz[oJ_CDOGCo\@c&c!!rC!v:7 iˆϹ_a/\p^A_WN[ 1!0^YQEvh#peri>e2+7csb=/+T>7g'rn)\et$=sqEeLk :jٿs.u.z *TS赀rjURqyK{ WZ@9*=UT+z-ZrT\E{p*PNpJ*=oi~OU8^ (V\%Wў4*pES+\h[SNeʩ.WIU- 2\k *TS赀rjURqyK{ WZ@9*=UT+z-ZrT\E{p*PNpJ*=oi~OU8^ (V\%Wў4*pES+\h[SNeʩ.WIU- 2\k =z8,U3R(k*D* ҋ-c 4()O!H-M3%8INZSg=w 3q\g>2׶V(#ٴ_uSs' 6 NiԌVwP~jK.aaN [ d_D'{-7*'$' ɬ`>GVC }qbS+.|+%>w o!|6w-A@ܹGrk-Z07__5[?t l;b Ҁ?t߯=ma5yY֯:ן8KeƋ#OOJFG/??_:Eퟟ\qO8@??Kֶ ?M350ge:5z%}@_Pp;N꧰9(㥁=+# 3иȈlQ* HS(H"cY2ʟvŇ/.V10ge5?wNV?m SZcH\`E*mwӚrJ\J+eJlʝ')?~ R%x'9q*[I^8}Pr7>P 9qSPZI^8uPrg|r␧Ρ"< p .@+!OCEj%yyBA].ʟF{_Br %{^F9`f%n +#9C.iQ.iӝB|0PٳW8ia!6 7~Rp\):ʟ6?hKZT΍E:V46 f'3yYV W~/xmhsRO}ix`K<[A.ɤIWui9:V[ƝsŋH7 8Zլ܉ʌwlM?OpV;w8\8Ŵps8۸p!M$i'TF~&(koFnu`}O MB<.OS0d>ɜɲ_޽Ðۄ5kք/<&@."o.")M88lmc&_h&Ik ڟ?EM7onn; r߃0{AmɋP E SdQvkr\@~j>b"xSė(N-ϩ)#:CkXK418C3 iIMqN4Ґ&U"?L&f'U+_|i%CSl\=od$)s7v_T*?Կ" \PV*DQx\iIYRArM/?jg%d7BSwx?FE_TFov4oFoŮMڱotV]SZ%\ i@xal6[ͧ*D\ b?Ou:T DRȠimA-&~ 'TH?qk{3@1Ҿ |׋$|Hg&k.mL/bc pqQDt%_?\ ہ/Q#ar3?is;ͨGfd Ej7 ,?@Ca;@EE?m2FojGIM_"N/-kjkkkOAO%J=!g5䇒Pϋ ?8NS8z2b`D'FC/_&,؅%f:voF<(J&D:@Ǐ|lU4& B/{ iCKi?JW@YApAKt]?ism&]) TW O'l*k~~P3̓X~~1~n_7BϹJrI;x[f-QY.3ޖY+eTciJ20#myRFe ;z[fQY.3ޖY+eTciJ20#myRFe ;z[fQY.3ޖY+eTciJ20#myRFe ;z[fQY.3ޖY+eTciJ20#myRFe ;z[fQY.3ޖY+eTciJ20#myRFe ;z[fQY.3ޖY+eTciJ20#o:O(? ѻ+ _PB)E #HAOuYSwJV;В )OydtBx)WpPP\S?ЫI00E،*Ap!BK X-ⴠ_W/G\@BcNFo~?6ionzp#5!8S)sӜ 9T )`[MsvJOˏw)3ϜƇOe"r??gOymr9ԵimSSc@qc8p煍$rĵ\V)!3+RZs͠nچf"M$GcWT%k'GXh"O#rL avOHh_@+_ZUtيu9aqH#?UW_ WqXE8PrdK4IT(BY ?Oٓϳ4KP 888|ęI%'$Ai Ǯ'50Rq^c_/i%lP"\V㣔,ٗbFBq/ ?e}43wd`_:+~$fp/@ąRI x@ O2ĆDC;2BJ F %r7^@b<ʿ$b?D<_ 0/pA~1#2B> Wz)Y 5)h'yDMȅ'?ϴLc8)/1'HB5@prDc?Fݫ YIA\RI,TZKt_K֗flHiC:+??U1i_YU_hM[,D7U,:r_|~݃HA;MN\g??lO(׭LxE|3S/ewV/&}CYE;LOȞBT#/D+Ocg=Mt~rS8JZ%̗0镤hԳ&:~RPPJ/ya+aqZN ;vyEЎo(]VsVO:')I-$C"SPrKOu6b/pWnO|(Z~! ':N:GKHkrL'>Iѯ(6oQӚ jS?ﲙ˅˝5eD%K'u888lmOk*J240=ypu$.r6b#8K;>O`+/p#ܥuy6a!OS8:)LGBcU*7_?\17h&o?o/L/&y7AfQ]oo*g]? p4J@ȄYӒ&#.1'UDl䭓ʑVj؜'-Dk\|NJuPߘYEt(?5ugQ+uPpjp֟ѻ l"Imf%ԓjLk@2u %- Y} S6@J/YF۠bc0h1̞Q%er,ISBwv/?z7s78p'KUX W0?9C?B/FJ+g vٰ)o.]2X"Vcpv)cO1S+zS WPTL6ruJXV7ת2?Pb:FH_Fy9bpvWF1lgqQ/ֈ~8%:Γ?!Fʱ/M{3ji'@,Vw)]D ?Z??rK@IDAT1 r/ڟЅ}md;@ E)]-}X)_tO?DOЅ?$(Fv''D/RdZ" HS O?mSvL8u WJ)SBM DS5 aSRT)U+2^e?8(J RvVby)S[XY7_^àZV1*L_AP 8\dP *ͩRzM1&ҿm؅h`;bDa\`'|#my)֓gȷVbSj:')?Կ\t-}JjLBJKa?=0HsF?m/~B[b#ыa_q#_qv_rnt3)߶*SՙRQVP23B?ijmkkoHt*3QuyS4/](n/ 'RXl{QtXJfDLSϊ\@?Կ%10HC#״\6#O|Bn,E(/6e d8[@gʴG7kEX1??_pA'o?W/?q OAOQ.ŕ1Za}?XPTTFJك XT/~"+ڲ_[Ǝ0¸w/h6EݲAh: Hm(H$a˄FQ#"1?Կ\eƁژf8؝ 3%s/rq/od Fq_''329S7RI4d|P~G?B( Li7_#B˦ )LUB5D1W, M+"OCZ9Y)Կ\6;?+V_[$Vw{[Ѯ%[+dN.@HNRh}OlZ?οL;t `W)Hʨj/ά$gԿ?2}+hUf6* Ud'OYCɆJ oڟ?iLzQCaBדbasj~[YjsQDŽ_P?hH"폂fc &h$@ \%Cq&,17@ㇸ(BD^&еxH_uH+ĔGe`AKg% ėzaU0J09\ud=ŸgoZ!ɓEڂ_q6/v(hK:c__Z)ŲGC[˪/4\IAO_QQ 13/\ hyPH 7o>3|MEU_him7oD#m-qU#9C'Oڟ|MA?Ô$ $pjTG_fw~0s! }yGD߿yP8X{1ʼnO>O}uR#iLX[R9i~e$ kK" AxI1amIS䀧uu4&-b|;Icڒ*'O(#iLX[R9wV'5Ƅ%ULOQFҘ) rSNj$ kK" <ӯ1amIS䀧YH֖T1E>AxZ_GIcڒ*'O:gMusoH ̍ XB[RDQ (R&egŐl'@AQE $޽^wyI^^'/gi}s͂KΜqe f%gNxB.YpəS:P1$,)O(cE6 .9sJ ƕu"9 c,2f%gNxBĸn\d3t<bVF,)O(W lyi .Be񔒐ٵR_:[r]Q(s Yc?tOi:H?$ "{Cw,\#=tKPO>?5AC!oO?}z`g q|O[ F4 #R F` r$׀Ċdtԃѿ[!6]'9$VĂ?/=CxXȦ?Oj[Ԟ5k[LzCSW%bp_x"!SG!5.۵rc7?V(C-"6G/Oo4co _ifCȿɿɿe#0; OPPԁ???BJ 'o迉Ja0o4LAj}Ӟ4+qDZ;579Wxs%c!k~{_ѿ:S.?H@G9`0ڡ2_S߯]m#hw-j2)H=i1EC #0I`^B2֍1EC #0I`^B2֍1EC #0I`^B2֍1EC #0I`^B2֍1EC #0I`^B2֍1EC #0I`^B2֍1EC #0I`^B2֍1EC #0I`^B2֍1EC #0I`^B2֍1EC #0I`^B2֍1EC #0I`^B2֍1EC #0I`^B2֍1EC #0I`^B2֍1EC #0I`^B2֍1EC #0I`^B2֍1EC #0I`^B2֍1EC #0I`^B2֍1EC #0I`^B2֍1EC #0I`^B2֍1EC #0I`^B2֍1EC #0I`^B2֍1EC #0I`^B2֍1EC #0I`^B2֍QE)=yI|rUᘯ"V . dF=M-b?KJT2i8LQm?d1BJ$6èD4%77wW-DE?[ȦJL*([EJd_~oKC;ȿJlz_| ~Nk$']a{%)zur%yu!Vיr\%l`m5#;,V6?JUsjlӫJE|I R|˶6r曜]9CP+|g /gᲾ c?u/+gϖ'jHMAeZRZ9 BDO4@D'o??L?[Z)3BVHm7D M*33F\dpU?3PC(Y\ DU_/k>:Q<$H0.8[~Zru+Mǘá-8%sr>sN WP6x99p9RNvJsN WP6x99p9RNvJ2^PW__ԟz8U4PA/UJk ^H"lOd}ﶄ?_DPo 6I)f_ԟF}u/?H2F;_*{esBFcHQ£ LF/#?l54_fDWӶ~+ٖw~tp .WO (ƐcFOB t\z|Oc1d=kM @GgbtMճs*?B t\z$CC}tN'@HYu; (PS '҅`zs=`N14GT~ t!踞\ǂ8ic9yF~#Va"d`R6"o.{IkWC2^GZ F _!͗埖l_j[MH?!EUK??F#G?zY|:gW/OӴmoX譃fwN܏9}b+-foL@()p(|DAe&Bo PSSSG(#??HBlU'o',=R!Ch|^>okiP+M`!@mԓ4Q@d}Kjct 8 LFK!# r3а-=̳>%jQI'[wEMtrƇk-0R95e}W?_3 A?_/~SPy1NAF/Z]tOo=B&ZVjH?7S:J͠FM}T89K?oWJ[0x n2>VeH*XV*#`,Z1kX2 V"?0cH*XV*#`,Z1kX2 V"?0cH*XV*#`,Z1kX2 V"?0cH*XV*#`,Z1kX2 V"?0cH*XV*#`,Z1kX2 V"?0cH*XV*#`,Z1o8 > Ww)%C0`T2Xn۷V~㛉 ~ MfR\ J?vi(j(w5CS}+h/'| {ĕ4 /1vi(JACGMADMW]3rI! JF+g3R''''''DMW]3,ԓm/ɫS1ԟb פ|8c$R"S6_WoX!腙`/(®aXᮐпhR`؟ }^a5dB2af `Oln UWH1za&@)_uQYٛ&0L3&H{bfiM_nIq|a}?cl ;1r;9pgy-꡽ЅmQן,gmM#32WJ'UslböEzg;UME9՛?K*?_/qIiAAEI]~"/-Lh7#JkI**V@E=W3Є&C#G5=FRfP;($%У@9[ՁL?džVd#9lXc{>][G4l?_l3l]x*I wDc9%ٻJy-ž]ٿVsQ-Pu0O7 `>U19T,6ٰV UU^by_s64XOT@Afږqcz04E%?M?wC@Lơ'?iNE)A+3[t`i P6AqdI ԟ QD чj&+`*˼  b[e>i0?Kd!4]UW*ʌmTT_+P`\"B`}`m/?ټC(KAyCÅ$jye->aKi}Q:vm I{ѻR%,ՅoC׶TFJk( >,gQ=Q/&_ԟ7SBG5,'n'j/IIp?=e83ggN;w?Jխ*?WoIuǩ^2 z99y>"OvtJha/Q * 4ƔdcTd_*3J:c?WbTfiƱJΞ~MB' M-^"Vؓ{W_8 E.n!!?_/O"CӐjSnE2Ѧ?[PH%?A'O?dD#@jI_B1_|gCqv漝W!7#PfF%>۬vv7#PO4`:YQL%?u_߉qf(/g~y_ղؚ1FkɿHr \ޗ=h >[n:*EGq qRn ?_s6#'5}zV)/}C/OD_?y\A#W!L5uKĞh$G_7 ߸&sG{I@?jaWx].Ϻc,hstOC:gF+fovYc})=a +|uMo2a})471 ^3F5caC% "$QPQR'?J6=7*BD͑4KPq=4q9!?tDh?\ia% W}-cܒmv>D9PV{d+=Q= FJ  WѴ ,uslM孔bNצT|ټ~Uʗ@mjp$|97rf}W7t}[,L __ԟRHh/:~n9H@l߹_Hny4#c'>WI!paʀ,g/J(wӴsupY^`f}Fa+PY: r‚JR6oi<(M r‚JR6oi<(M r‚J?s,cQsܛ-˛7&]ߛW/V{Te ۮjSBVn**˲c؀ Wo6aɄ@j(}wȈf3Tɛ/ԣ5tD0_=$Oùv5W'!4\V=X(1Pzd@ s=`f f#4Ȱ.+zFCia \4WD1 #rh;C|oϗkudGڱ52]othTuN9T.Rx*]"V9κD5 Ű?_˃Oߖ6U0*[ ΠD7o~[)qK U/nhbiv+y%h7uD0"%@2s.o &6Fggc%]-4ޓHPM;ykqL'7\%`nUu bS g0cXRC% 7{G?SHy__'!F+ X*W?l~E;y$B _We\0NcX/1fiSI'7^Zb:GYBm M lLg#L1?UaZG"̺fA%V?v<,վ=#ؽ3Xv/ = ~?ۀWV#)hB?1T3 &V{0H0BMM;#b-F%&&MAMGs2Phw˵ȿ[$44dCIII!b-N???)PP% _ԟ.9sJ ~"9 bNp͂KΜ/\d3t<b\ .YpəS:P1l\r攎'@U;E6 .9sJ ƾr͂KΜqj'f%gNxBؗ[@.YpəS:P1.V,)O(r E6 .9sJ Ū"9 c_nf%gNxBĸX\d3t<b- ,)O(vl\r攎'@}"9 bNp͂KΜ/\d3t<b\ .YpəS:P1l\r攎'@U;E6 .9sJ ƾr͂#>YGP~@D%̳{d&v]irumnTЯ`.~JIpC%ϞA;G2J=)a8")&~(dUJ{Cw,\#=߲tKPSSb?@MP+?YBZ @`̀X z>[r+Ħ$:?'׀ĊXtԃ[`V`gO1b#y\HT-_}_o/qbR{`k>s6?EBzNp{p]+o_B?G=0S`ur?߲!bsd#</Oo?۫Wبty''lOUBwfA1 /ߚ:W@AEIMR?_?FM#7UBf z4SS:=?ݶ∴~ j3n^םY a9jAΐ5X_ lD$ V'_?8l__S\ --){EܝWnVm]=zk[o롃#"=Auj&`4|z8X饪kZ4&}W^I=eoy?_Ⱦ%_$#%6FM%zAMAEII٣BƊ?U'JnMK=F7?JJ)9iG4Rtdڝ̅3{dȿ=F_%FaTgɯ"` -mʜu(_ 9Y~aK9*6Xw-] 2`kMfa_*7Q'(n?O!|mc 4/[!w{y7_CjjJCakڝ&?*j 2Sac]P2|gXGIZ?4?WKA% '7GO( BEIMB ޠ KOW0?$@7u0B /?HbX|;zso3oKJ.37>خ45F^Ŋ\ `Xc? 1T f!$Jcbtŧ(xHf-r &`r.8[F~>'g1 $GltfrY__}5FW^+>7;P{D?_t",7j5'GL+!zf;KAEq5 EGI(g²|[ DL B?D*' ?D'- QK.t3oo1n!w1Ր!$,8H&?>ȿeO{(gWR)i'FWtsu?%_ەWYC -YC҆L /CYsiW&WRreB6ڥ h VRS Z&>u4+)s-¬/PiTu4UIN{hF ߭ŠTRS Z&?Q׭ŠTRS Z&?Q׭ŠTRS Z&29p[ [~LD{CJh6 A8{13XڃxNYqb}?_-Z ۔+2 "< !p6ȿ:F?ɿ.sAAAAAAAA)OSńOQGGO%zssSF]En.qМQ=h2 )CE$f#NH__iT8?=d?$VotII`6m]łOz97HcI*}9-8?5l"%j0oXb#`FMt ^>uĜ'?4v5K?_έM)g[j"J]׊k 㧠tGX@x1KYv__ԟ?$GK?;wpO#_WԮ=}v좼 슌uQL$Q^'ZBU3zw``p]A93g>|}o$Px=u4#CG2j7ۖG'NSvK-c&]"GV6Ak>GY$CBSoi(KCGKOC78$ Q>g码IPPOOl_QSKLDD 'N*Oݒ;G oogU쿔tcPqJ}"@H9ڡ*m8%sr>sN WP6x99p9RNvJsN WP6x99p9RNvJm[}om _eMi3kstO.Kw/t[Z?kЇI^y钋q0n~N]vvv, ]Lz3d͕SXL~yC_QOapp_?LYeKϑ8/>JRp|^h@dTl(s ,x_`"п 7h@'9e$hi/хH%?_x OLsY$vmɷ醕#lɨplr w*6؞}R8D06'>w[G~|xp&l]?X8?OlMQRŧv\N9ue]6S<}S2;!.3e=fQd^{WWtp_/c?OS/Zצ ȇĝqAvh!яsn bbb? jSQD EN????okwwwOi[F>s=\\@z*%_#l!_:g=b>w=kS '`zn's*?B t\z`I@1O8.׳؟vP>:N @zg=-l#Vb>-写6zPUv[=k|b7RVP^Q,b} cRkgvb4j/O6+7go3R9|+Ӵh|oV{.R/k_g铟 gJ<,%ZĽͿx=3#r=ٜի^G#xG;j俢?߸vuN|3c_|GmٳrKM"d#~=a_䟞Hv`GЙ1 BC#rK kP>FMMMM-16BOȿZQ:?M_Gn=x//QU'z!,cGaXm ;^&@! _gDpu(x1g.֗7zޅb }ֱ:T g.4.Dž@-c4dZ?k씍2]z!B\|WX?jϾCmT\YhlbI N28 Q]u+SCS+A{TMG?4`ZEEIMAի bOZC١ E2NIM/U8?h?C /_zUMg} 'QC+*N*7Ot'骭-tz{0 w don$|--yuq%K'Ź`^Ut`nDs<%%%; BZ9h%cII;_Sm˯mKCh%4,<Ђl/m i"aDW CvFAh?9?ߞ;[TIzM_ԟVwo{Vh2@?-oc /_܉ uOv_ !W$5 -Fc*QᐒњGKx\yW[U!_?wϛ5}%ŹJT?)$˱JT8$o其ƫCED)zs_Z5ُ\%+eWQϱ =dW7Toѿ[/$ ?ȿ-.'S'w\迴0&O?T@+W%j@XW鿪O\1CG?fԠJJkG{CCԢX@rGlT2hRJX3䜳`},wIoIJ &ј`}ΰ!w /}$P9[x?Od+vfz[D@Is$_j(v|F֊}.5UՁ,D?#(lh@<.cqKA[S㣧M/?TScNo_r5Ja40*fabɊb*cyl"N ތ0C?؀}iDO=0+;R-Iskm|)}ٓSXE#bNδp׫)51c5g>"|R#GTk.TO_WEMo/O/hLہOf?^q+Wfk) > )Βyv[\ Vm ])yFI`?`+$VHq ;Ou?ğ+)l/e/R+-F)IMS}M0cP $ג״+|)@&c ߖr(f՘ST)O%/OoVy oooooo)?|ZjVcQVQL7ԟ߶gyhO/@_j5gH{ZįzxCTrX0fimQ.gQ=L <Mv2* f?ٶr?zU^ǘ.\7''oQJ?W\9pxQv?qk5ߔMV'yU(_=jN3c%ȶ}/g/z+A`'a}?r1=_ ɿ?2J)/Oo_VPNQϊ JWO@OM/_"' zD'O ?:(-?D )YQ}:BJX HT~I7gۺ !y0e@WXހu.2L`#kfUC S!Od9m6  ZpN \_G _U/LA OpXǰd9}f s,atb3Odkan}a';b˸ժy(߬7mW)!+Em{Y]֯c?K?,QdJ ɿTL)g'=;oYoUjU8G///˛?PbJ )|r}Ϩ. ;|@ ?ύre_m듈yDOQo 5*|?"?-[W0Q0('o`!G_4q*uWTa? "#QGğ++OѮ4TZ`FV56L€K9ٔx)Vaiўb}?_?_/Oo֕@7T&~R[zVnkABUo;3ipG'JT Ǎ[Ջt &&hKCG8G)F????S=iBylz%Ūk/Ծ]bmr\rYc`c KwJ_Wt'v'io-ڄU,z8OcprIc՞pY_:׾t_]Kiyu'6ް? S% ;g1o6y}ӯK/\8گgy{ɇ o1mmovz_O:$oMO7cmKy39&7or=G/u, Fh?o3MC???r:3[:ϼJ+r7]kM}?'xt\{袋fHA^_nIsL?gHm%Rr;8n>קUxE/o%bmy΍},#L]UF}P9v3rrool]7gw}CEԭwI@': ;i9YSq C:Gm۬U6[dVaU62h#bU}؟#c}qca񿡁U#!0sYۓ&{ja7]A-vˆӂo:ŮgM7_z7,6FoMU]6fǧ/ܱ}^K.٬LjvL׹u}ӿ|37Ğ(z4~ǧ;}g˦Ǯ|閧j;7}C<뷷F_jFOtlc?jnrO_u)`V$߮{9ZlBϊzPO#dNQ-';|mu9ֿMn2ƿ;=_TX7(*l$>{g;WBzVxn?c?>/}K=q"&k-oa6`z|Ʉ_X G:#=4:J Oa?ׇ)%Uc^DS P??)pOhRob Wb->$=y8Sl !;C8Gg;[I b!3-`Ȏ1qnh0dGRÂc`8c7p #aA1stFcZ ّ԰ 9:#1 -HjXc gnCv$5,1pv3vC !;C8Gg;[I b!3-`Ȏ1qnh0dGRÂc`8c7p #aA1stFcZ ّ԰ 9:#1 -HjXc gnCv$5,1pv3vC !;C8Gg;[I b!3-`Ȏ1qnh0dGRÂc`8c7p #aA1stFcZ ّ԰ 9:#1 -HjXc 篗_|MVYh-Lkz41iVȇ:+ꯇ7|8=eXk=}?||.W7?w~̿1[WMc9I'(}hzӟ*~o}~=ޛ>ʇe{?!o?0}S:fi_#~^Wf:siko#]Mxy?N։ӇYHw>mi?>1!W]207<0x_3ٸMnr奦W}σn|˝t6/>CbGK:$i<$uK/~t—ҿzwf8sgo~_z1G|(Í:+`_?Կ?+~l_'?AR"xiccz}\S?"1=^ 7~/I7^8ٟP~̓>w ' kNH/xE#yR(u>xF2nAGGGGGGGwGJ ?n QLǵxm G?_/XKǏQ}߆E6 .9sJ k+E6 .9sJ FߨWfE-9sJ ƍ6+jəS:P1pmVԒ3t<bܸ:*ڬ%gNxBĈ7jUYQKΜqؿh9 #ߨWfE-9sJ ƍȃO1_/7%յJ|B>4uVg֮0w-c"~ů?A.铟zo]:fNIגo]oMo=u>mxnO}-oc{hi//WMUǴL׶>hJc +MxuO{S|â=yOgǃO'=L?OIKҿ{٫; ?ߔ=Ծ1]oF{ӥ~g^$4WЙgyzc"_ 9lI}^Mv52/=FꛉEkהx:&fOO|7=ЃDĿL)}nԑ׽|?O3v,~F8_>]?-wkzç˾|_t]yӵFD~mZwk^3]KzKg3 Y4/iO3S 1]I_u?ɦ{5Ja1~Jִ[r+Ħ$:?'׀ĊXtԃ[`V`gO1b#y\7cTG/>;n[\CƅۖVT&o p}لTꚾI'^Kl[07-ɯ>ћܿw5_ӗKӵO:IflM˼-Wo%^ .'=y{cVr@5<өisx;O?`?ZwJ"w-coy]osKW8 !`^S/?7籖"n~9ru>)OzR7[yˎV/锛Dʂe3o5햟T?S_},ҥL ԽU|jy@׿ ɏ~o_tOy)O!{]_ɵ[ݢem{|yӳ'ow1+Ɖѿ)GGGG!Qw3W^q8?gK4LIi '+o@/Ek>isv+e,)E&]w<㌛9ر_x}~ںDPc34̢fb.b-ulE"8Ne<o&q-tM%cg-q{ooT1))ؒFΞ[>־}雦oO7M\_O|R~lu|tô>G5G~t#ѩ;o}yb}Y4yٯiot26Mȇ?dz֋w-n?bӝ4rM/}x7}Y~oWh=a߯v.o<v5\׏[.lnO{#fnpK/?;o另.<=яI_z(׿?NF ӧ;y{M$v'~|a>6vА~} B[e(V=]|;Uj;[bsn}mUy%??>A駟>vi 'L,>m_/P]hk׽#ĻmMӅ2W~_Oͧ}B߇.܅>9u b_ӝΚNػ<{E_zG?Q+!֏?U<O'7ȇ&r]Ӈd{Wm|pzԣe5ꖷ_?|ӛ .xI_YT>}w} $zA3ΐ0r9Lr 7=4׏/]RWVZ_kZ1cEjJ譔-eD7{L?OuEx 9qZe?MCVf=9ZZQ3샿lֹ.eW^qz|!R^\-~vgU2Fn?PsW^O<;Ytwuֹ~|9pSDr {Ow=7XOslv!UλЙSdZ|Hƍ/M5W1WdhLx m `5;Ж5k|`W򗉱(Omm`"̕Йb/mZa韦i7u2;:HR`"̕pE18@e庛v4ǧ:dU. AeI3F*fOt.i7jj4#%i&L)6uHK璆p3cJsqK3ɤ]'۹n7?trQ p=PwR(P^"~E5PRVӢ6F cd߁Q;툊*?Er(˖-gi=d651H5>ץ),~mv4zk嬕+VsjCƛw#<|:/:-ZPoXڶi:7%Z^{ɑ0|";c+WZ!rS0u?f5<,^D4m*^4x27OX ɧAH+[oQ!'[mֱM˖0J]p F kW[C̸;&;s߁gƲc]AaOCޟo 6MJރ?LZ:0,9أv] |q/oNic;IgW1k(. !M?!J^=Z'AgI9ϱEy]!W"$Wse[Z oJOX+H35o6LU[i5y3|v&jߙw5>>= ={C{ɖاS]B|ɇ/N0> wN)A: tIoߏ^{-:w~]=믿~>@;N ~Ϝ5K?h2z/<@vgnA~1_MUȄx12_uo篶a_et,?i7uӿMV]Qg.`=-tuW* j3!tc9Dьrj3#.Ca_*bIT63B0.1Se 08` }iC aH>M/T @Ⰹwj*1W:dmHesK㊿ӒBS GR/Vwfߠ&ms!WtAu$G)mmoLc>Xӿ2a7?0'Lvzur5Tߦ nʦ(7`y}/ڕRk |5^p tä/R8NiM>r񰞮)hp[=LNֱZCi4Iq8˭&~J4F5-'""AWWZh('.zlRܢ4%N \n00KECi40J@aHarh`8)pÈt;O@ҟa~<\B) V=yk"w |?'p/N}nӦO>|E+[nXB&Dt<ܐO;7lr7 ;fH8&O <˜b{LYrUE^{YqV|z)G"n?_Saڻa4y(<.hH$͐ d?ևz#u4ed{߻щ*,MgIJA}գ~/A?杻%Q-`$D(. ?F9Nn |r#[GJ vt M/|GDNo8 mHovwĪC?Ax O)]YYL4|[O,OPR0{qZY"g5HoY^%8\,^,gyQJopШ}-?oڤ?^6Wt  F;-d<|ƍMg+vQG@r6ojPQ%<(9~ c9 Ю~C)~ݻyHiժ㎕/r_'mvZQ4y7bm5};_pf{uЫV_yp)Nvm ?|rrMw Y,ɿ6ܫ7ai9^g 9@]#7Lpt)!H'# 0H;yt?~,lk3kqv*x6kke8 z{^bͽ/w GA/O+/BinGoh_|:m'~OOŀ7z)ojTue +sW~??\Z=a]M5k_[l5/?HȠ(<:FZ>6diэG"P;"xJ0X\7EEӫYSUͿxYec&R 5ko$!C0Rqҙ\ϱOr%ҟ/>EvT|x9,_@>Bڃ ^HuÀU|:k5mn/mڴ:nƍ lxjowC(v۵=GKN˗/Uօg߰,_FO`ϯ|˭sfϑeo]w!^YoNsP|HAiÎ]_pv7przxLN$=Ԗnys^?͚5yͷd& xu#??2*P翣9N-&ߍ<+?5W0h*ճkoɏjqoҴ)<>ݦ{&^Y;"<>ykamoϕٗ*>PM+jJ؂.'͹kN{^瑏sbfIW[[nRYAԝ_x푿EJdC%J}9cFʣz<`6 wީ9Zy](|o_G{-S\ux.Jɛo qM375|ʀ0Fx(*#=STG:($x|W(#+W_?@xw:B駟~XIO_3N]x|7~L7?:p.[IzJ9 p2o??VAꥪL_?L2C T/7)xf!mDJ(uQyh^m.=-BYPea A #(h.=.^P0":OM?NbFM}]#u\a=x$g_#nD~ ^ȇQ~\s{zCx]?yx$.'>ğ.O`ߺv0|EyyqOIt|omHtcw1t[SԫÆky٧e ೊȒjY.0Ol4 cePao>ydWVi',+6hH0GFM +C΄7} J!x5as:biwi4 XG0&zqe?[owԁQ**k|&N/U<>m^Vq؞t/xUZ?HUq?>J=$ >Z~V鿫F1j,W9]|X? &ODӃUs|?9 Fb\i d`"H J0?yW!Wq]{k@!_ɟs{??<c׭KߠLǧFaw>az(FS'ݙ[|L䆛n9⋜] -[#R~]D)4VtR|XrY &87Og_xJ)_[.(#CV8wY 2e$T̠ǧzud;aDOUmk!m_?(LM0 r'Q;?u oAOo]Y<$`b>GIPƿ ^nTO%r왉 V*e=K.DO寯@?"DD/$SSvR"g |N?kfΐĵp>S-~ҿz&oo7_W\!VVOslfh_CV6/ ~{ZS`1 !?;@E>eɒ Z2f^yl - HUGE!}`"'?k#7/^p绕?i)g;Xڷo>OڿGp};F=c.2}Y{g0bfZn{}ދg?c>Ցw,m0 bU5uC;{w wӟvұc(ݻ%u10ɺj? 'ec4ƂusT;v4mWc=* Hֿ}WٶbK-C̟s4kk~G#-[lo+wo`t8hYh^>HzZذku(w1_+[nڸVzv2mv%)ܵOçm k#ж]vh%^\}-Y>ړ65ÿ???lf3c򗺂l6co|g <-rߝ[ej^r7 ?(D7tS⋥uǗFLk-?ᏵnG!lܪ9˖-~Hz!W]{eɇ=\CJϘ5)w '|%h=XaJkbݶ_?r礶_bοteBcRB%n1#Ie_ahԮPi韦ƿv,;0\-ݤSccп𩼼BGu@.ݣ<GL:kA9#U\x^ JH`tLJ`dZ2i)`XDŇmG/M<ۇ + #P&r?aDP²BRx#_[yOWnҾC'GZ{v|QK,m2ad[o.R"I/NzuEe\4zգGb6Mǧˢwy ^'7'rȯ-۷NjNI0_c瞣_|ɿ-7ߤhxq:Ֆwῑc;N0iOak3XoҬ9F|mz̨EOg͒3f7~Jʘ/.J1m7!ujW> fɿFv;*z|S5aᥳNJix/O|ѯo{Ͻ,~y睍S $5sཋƖ2seѢ ~۾x)vƌ3>ыQm֟' O'OQ5/;W\9Dvygeu~Ͽڬ-`9~o4yGe̘QEE=U) x?r Z2P)]1?7KѣGMKd=;yGd8xS䩧ozß<<n `{gK@V_U?)po^+!3ʄn^'Ο' СNZxy-_Ei 5?8 FH"?=0m1j?lThIU֕$?&mjg7K[l[l?+7] CDN#E{><t4+jQ$N0< 7_Ià?&t~DSQ<=!Z'5k돭yݡ@vU{_ \)B(S~%a} "q%Y~GKCNj7߮4|ԩtڡӍ hʄ|IjY/AC[oZny+ZY"sL2qO7sl}AhٲOd(?I׆np'<9-\t=_6s&\ ƿ?vxvǍW#ɱ+|m_}(Igy|U;$W]3Tq?r-7㫠WE ?gXv:]doue) u?OXٳmPS`Vu`?'6k&ç CO>uС/]Np| W,smwrƙg<(^ cD\JSrGØ9 @'(._yOP˼w!(Lƛ4or%S(Z9:#aH'?O]'W9 Z_Z?%9sj信W,U+V&cR=~z'3+>  dOW65JgUШ|PXeӦɜ$ixVV& 4B[7o\xi9֣3sjR@2ȐwEJcMx4ޙB"ʞ%8´ y@*+Ѫfq+Y8ixٹAA2"*cSQߍɉ9pzS( 4ly|ӿnݺb,G3xc8?ZGJLiԠA3PP%T$\ES[@g1Sޣ ?` BŤJQWoe Ԣ䓚_UU;&*I'cM7 O?$2_t9wk0Tt5o֢%>0V}x}دsG/GR.w{E漢,χ'>'^bmXGG@{"k߯F?&?6ly+?o?& p_ik`뾛aڞe?[OU0ߟJ<|X*W]vu"Yh2nQ]w^ZFC)fgn.' 8 C'x?gοW_}Uurʩ%"#oE:Ͽ:3ᠮ~ؾejЯ50aj7IxϢD/MՊ៉tIW^ (ץ5џtPq_*{>@ŗ\,o㭢bxsJ鍗WZt&)Hx'ØoM7QÞ&FoB`CE׸_z;b?M.1~_N#$uYE'[Fn9R}Xp[Ϯjsp\lu#}{o`.cn]~{eҔIQa?s !?ƿ=]9*%x/ ? W]S+n݉'˖0|Q$FO09G-[(c2ƢϿ)ˤ1_/(G)y$/Mʊgϯࡪ64v_KnyW R^y5z߬y =v Y3kXT 믓H8ӳGDLH֬Esr(v QsU+?V5/ l,4͚y3Ю:i`5|EQ4|O*SN:IB? 8ӛ[sidsl9Rx^w5:D6a)o Bm1x)s֏۬2KpK++acmk`;1x_-d-'9a :|jMQcg̙Ӂ/+gWgwʿaW4<`qقAznÀC@LB'u\TF ?xvg?kk̟ ?[[xԞ1μb];\y4ѽHkd_VMP;6,A<y-dPǎ0MO T!z`~zC<N쏹 p/ʃz'σӅ4dGZٽ6k˰ђQ |Zt8> sO'?l@b`4doʃZȠ4|JՐAll=և 7|p`;!xM] T{ߘֿa[,?@?ݓOҮ*yǟ$S >>4>U-j״2;W,\/dwk}_- /ɵîA뱿j߮Z[)CZ^}/I͂%{v>_}SOڃ䣏)1yf<&LFI˗(-q<?<&Llsx|JriT'w07j`^A s WK }/d^tթiN >-IEdјCP/9< 8v=(G"?⦛m۶?$}6<7ԩpBx~xBc9#|O?]/ȟ8w 7bj<@>c]v2rÈ ֬Y \kvw2^sW)^ JK[^̻kgU98Cv3egzaxE>KovZ [niX!̒'ZA?OOUwxr&(?h1ow[n%.$h[S^Pkm'd_c7Ub-@ m,&ٽ1x~hۮ&<޻2^%ǖs O l3D /H_ȕ_.-ZxlrA*i۾mѕ;Ub͚6ǖqZ+'MB6!c- Uhh7vx]\cx@*a\ͷߪјBk =]Tʰ/\qM,>0Y o O;5!0Z м7o.q&矓vޱ(^/|w^nبQ#/?V_v쾛[_yzU- ' f℉ЃvUefȑcdWx|J˺{6"W3\1Z5ZXxOAA([1S/o޼OwImxïGxo깨M w%FFX"k'&- !atV+7DpDߐ?:&:X*c45Jd(]z1A~xE+@kv=>ZMhBn;^ߗ/%Dw U3>)OKj\X>=?j=a}D@{o  uyȂ Ҏ[B>^x9敺/շ#,';.P?4`oz;o/gbHȍ8(&f@n҃8 i(ӮOe' B<_$ krW^Wd0[ô0\GIaa_̃DuJ4(?k_*"M"cWڰiM `,^\6Lb&L"P ܸ/qyidG _==fs09Qɟg !KCy8)Ȏl6anE3Jx&laz1J0o?j^ɛ~M_!< 834x4I?HZ6!2 Nj/i&qXy N>YIOTe[`$ *GrK|He>héӦJ]q<2t ; BC,  *t/&4(4naѧ/\k ;?jbWyźɓtý!.Z^6W&x8E_⤡CR:'gAYv$O_eodc{]1d<<>@93`\AOgGH3OH d0c"On0# ODOm,0&IUl:{pTB: 7KpZe3T1-+Oz_ ?mReխ?T{^aizr"xjzex:!$pyUƶMǜGM|ݺ@W;M%`n;.LMߏ?'U<ǧF4Ȋ $?O<Wkr7*phQ }R_kX =ZC+|tӪs{BomM/.E)؈+m˷?!*J_wg gof2!m1k돭ߙg; i'7eߦ G rbvTR՟9f 6!(_Hx54M8# +CŒ”dE$CŒ”d?PBy!Œ”dAO)^^+KEQA#{S/?/@(6 ^ w,d$Pvmʎ;v4*Jx9, j?_5< ܟ=#JλGaҨq#Lz7SO>Q{ﳷyҸQㄑX5xn~xg; /p)/&V??7&G+>Zmu^%"<\/1_ _xb~Ls<ȣOJ;£=\ނZ6O]wU*Wnn`|?D_z套喛oĚ ydUCe&[0/k; 'TGM7:>uGo8i+3Ee~胗?kaƏ vȏ?Ӊն_` bwx|?mWr,^:[iz=cmr9E[ ^{-}-m{K( /u⥹H3Zك N$5ʝOJ/9AJIJ F7y/2֑"W{)o}zK3 *Xb92I9WҠQz>{hĖO?L>AIռYs ޡju/~$7ߝ7_C(HRPѣ/r 9? F.-ņ/'>Sr/A_}\0xS5/yHQo\~/U_ĸDΐIp!߱N%Wk(gE 0qn 9Co{?f PtP*Tڧwoi2v(SnAΡ+W^Q[B͚51wL*/>^viFEۄD0hpQCG=6SiG>Ϗh`C'GG' _t\oҴ\ |0|rs*x|[F{M!v[f|,2k&;t(3>7=V^d=n 8Qg{Lœ} M` gH/uNދ/0|aѭ'x2 B]'[c[:= #Џp_PPxcT Wq*͚`Lƻ1WFt ?;uN%TaכC"u4_9[ D:~vܱSjt; U]{pLȣXy?Dlg@$?m$ҿΟ+fwp'N{WDj|:nЅ{P&{K;panZ,?, ZH偃:&!džM&@8'Z7tuZDjͿ?r )Ss?qS]b Wɿml'C\^iU(w9WMvN:O~ȑR 6#C_ C髯rh?Owu9Ζ>C|\*xA+πh]xb ·N4q}(QW5 9_{Jk,23ElWQbn/@&L1c@=0mMj8v3՟?&Yr7c FOdH,\nGkco0sIcBծEl7~6\ҍd#"NfliP_+a;_ +е&E(BgQ5٤(# 3%Ţ`~A_FdX/ϨlR}]ՒMbQ0_?ZIQ, FugTK6)E|.j&E(_Q-٤(# 3%Ţ`~A_FdX/ϨlR}]ՒMbQ0_?ZIQ, FugTK6)E|.j&E(_Q-٤(# 3%Ţ`~A_FdX/ϨlR}]ՒMbQ0_?ZIQ, FugTK6)E]`\;$2/0(`RbTa7/E/&#'GNT±kL o38P;E@?+ok3߇`B4lP~_('%/I<֠W?&,٘֟4|j\o[^8q"&F|WrܱbXo_R?2i@k\5ןISʦlῧyBnF{9flMO5?~"gn3k돭kSM0_e_>Qg9(9e`C4Lœů"EG!WbcZA"IFP@'Cd҅>yoR0IRe`\ii~QTU@ӣ ?l媔; / WU@ӣ ?1|Jun5bŇS|E?װ a6TTkRfk{Ꮠlf}.u! t2;K Yz K6~ouGBCɂa 9#Nf1,?nj1}d5xag]ṭk^Ֆ[:>l̞=_7{4㯃M*YEX]iIŇ<12PNV[.WUibl5Oӿ?maC ^<;/D*`iaovVx_e?pe߾o%k+K񲄿uG>쟙H =*/.^M8χV!Ⰷ4F$8Vpb>cae??N&"{H?&{O.Ɲ'R0t˕ (䤦TWx1V JWZt^pO0˟[nŗiTIdw"lqn0|2]dQbMXd^FO+/ g}d:?*6NS4oB-_ܶ!leOM+?:i;*o'ͯ 2oc$K\+{1 ?,CŐ Br!)c4\Hrrq0F??0K6ek g柟;< $o!)|uzgOdf#̒~*i<%熇.ޒXG|",\0K[5'!bF/6j?;u[Oܩry(dƳ2rjJ+9cjwʠB\}Yjya_ܻigMW k~+>` k T?v0o럭Q R;, v(MfB40( (&qQLj[頄$A~o.Ni2Y*"*JɐL'h*B: Ng%染NVDi䯭?Nj^<$aGy olKq7.cLR 7 j)Wyq})$Ӓw[|l7SaAN1U%lӿLm?leO7Οueo?>%7 ~q39Å(;?s,3/E\vjv&O:L6PFsAOa-;2uH|I'WgA}_fVőgy/Q p6 iɟT#% r%Le}լCAr}QѼ2//9-l`;k_mdv`/ED?K_! ΟΟ9v;޿w;w;w;w;/rfv1'>%G!4/NYKEɈ f /J"lx^xy\hFzBCo.5c&i`r2b$ RP0̯ܰѹS|&’Bs%?NI$XJE'Pʲ)`aՆo+??UBə0k돭U?mW'z|]Y!p횞Dk40 ry9H-9piXo7'HA^.O'VB$OBo|*IrfՎ^bJrCR#ڢtZF졎<: }xoVV%Lj/ q ğ 'YZ HJ S9ꏨr̀3 @.1]9}ȨVQDG=jB G_QoPX{XO! ڧh*]ӤclH*]ӤcZt4)![5t4)!m";9MJi;fy";9MJi;fAHwNNRڎbe^#HwNNRڎb&k*]ӤclH*]ӤcZt4)![5t4)!m";9MJi;fy";9MJi;fAHwNNRڎbe^#HwNNRڎb&k*]ӤclH*]ӤcZt4)![5t4)!m";9MJi;fy";9MJi;fAHwNNRڎbe^#Hw:)|'*O)I}*3@ع8o Ҕ6a>xĻ4˷bR>r?!,kWYF-g "@/ .q/_ȿ!D=C?P|{?g>"?;?@]O?ٯ=o[yP9,(eg0dTR -Oùx+H!'[REg+E׉ *yv bFc֟/? )VMU^9;Wo/1_ +']I|UKKjP y%|ɿ+JO^Z.X~oFy`'7,[? B ?1DR#P܆#F ?@ p]_?P)_PB 7?J(ۆPC8OYa-> E~rQ 6>.f{$%j090^v>h`!vU W ?λI^NP @7Ͳ$9/RLKu~TPȿQi/?#ꯨ+q`3Ϩ?%\?pTY,'~"A?E[Aգ30 ql$nKMo9Y'fJ.jN GjᖖIڼ]P#--y 8F*7[Z&itQpBTlo8R L5&pnikEM 5RH-2Iנjb{ÑZe6A5'H#pK$m^.jN GjᖖIڼ]P#--y 8F*7[Z&itQpBTlo8R L5&pnikEM 5RH-2Iנjb{ÑZe6A5'H#pK$m^.jN GjᖖIڼ]P#--y 8F*7[Z&itQpBTlo8R L5&pnikEM 5RH-2Iנjb{ÑZe6A7>S΃?Yg?/ @g9TD&bWI?`Dkv3'|tՕWRZ?]#vegq{ҍ7ޜsƒȿ 'O䟾H7? ~1DڐId l#2Xko|/7xS#| E&Z=Lx4ztaXcEe2ts@///GUt uDb O=IoK+oI:2`N,o4Q$auS ~V)c2뮛.\H^d`٘b]%_渉@9#|cM6ߒN#`VV '-5KQbi!7f1oD_;grFF͙Rz7nO>-}|J[g+ޅ+/?nXX-m)a!ՍKE m5 ..l_q6HuO* G H:88@5uBNZshm49"9r-Sz59"^F2L˖1Yk4]0"(w2."-Xi`$EQe\*83М[-l봨jAu2`=").r-IVn(qpD˖qaWEtC#] Hb-J$EQeR꟰齇RN%E[~\s各 7N@=Us%yM+L4mg)Kz[xizGw1-Z0kF/I'˺/Y8]{/w=?UoV 6g6[Q^|cQV!z`E 'E?_B2/ ߤJ"& !ŐFUjuDDTE?Z̿οby虹ҔK&]wݕayOtܸ4ju諡\ uӳE;?w1f7z4qvM$ГQ]'K}v;icgg'{IoB>g?t 2Ը#]H?#G-p)3GXE0+'o?؋^"ށN4w)>S /_ȿ,Omeźt!ܑ>6Ҵ>Un~/,nו bE6'KGnt3AZf??~I-W ]LԁQR@Uy2@c܃q{TΣbyk ޯuM;w7\mygz;kO~t} A?=L?? ?bG ^)hP/Ŀ!%W-DǪ\Ө4s阣?Dʉ>tGeEm'}ر,z/n:_)}̇67J .MӧOO4o)JjK.,KӧMKO/h3A_-88 u-SfoU.?kN/>gK /HftVu 78"I)=yG)6襃c[DAr=܅R9lcz똘Ge>/o|"n5R Su*PXֱ'oC wJ0C"#3H͒EKҟQ?ό?,SB*q+ [eskDYfR-ĿG@ PYOFrQo<^?VFe]Smߖt~Ӿ&M:5}y2O=iw|~7=Et r|;=4-ZHz~J{i:[gϙ̊)]F^HӧNO1OyN?gzEן{]WeV!6? I~O?Wv_ >Ŕ1aݥ+Ƴw!Ĥfi/Vdk+gBI)Z(-xMƳw!ĤVf-X& ٻbRJ+,J ^wqvlm]1)Y 8Ix.ʬ҂]$[[a<{BLJieւEi.n0 !&2kug7VޅRZ} !@IDAT`QZ𺋳dk+gBI)Z(-xMƳw!ĤVf-X& ٻbRJ+,J ^wqvlm]1)Y 8Ix.ʬ҂]$[[a<{BLJieւEi.n0 !&2kug7VޅRZ`QZ𺋳dk+gBI)Z(-xMƳw!ĤVf-X& ٻbRJ+,J ^wqvlm]1)Y 8;'I#oȣNu<-ҳ5,*r]{kCJ4V=0?RMi񒥤N҆n(̞ͯ7lfiOx|mgԋ`=d-+/Qv_29aG&_vCY%Sȑ/1 $˪/o|9tR͜˪}~3mBooo~#򪫼cf`B| 7$oޓ,x6q&??7YƜ2}z3Ә O?Kw^g}1K?0ړu7ҕ4ʥz=>'>Pf<Kb'E g_I!C"(7c-v߸Ǚuւ?qSw I͒|Z6/yiҁ4bS c6P<&KE9RG+5lDhMC"$Op%kJuh8,>i& 쯩?ߕﺧ҈lrͅۺ 4 _ =QK s>};~oYD8X_;o0ϟnO3fH7wqz :SĮGbXK쿈?"E/19| /?OcFN3gv[:)Lw}f}7}Iq/I|,:{zG)}|QO5ʿ~e4C:K;6}S;!vk~z=ӧ?k, +?\ʿP&u;U'OTsxS#&"G_xeX6c ߄"OB#aǑL fwkwDC΢#y`Ԋ+aD%PZHX7zFlѯWæz|A^AMf,b,ȿxL ~-AԎ˄w! [o%=~5rץ'OпYGJ*a_?%0Ŀ)~EAH ?^#`? 1崚^|Q5z =o|:Zak_n'tK#<#!F'Z[~3;?m@oyIv_>w4`zMK/87ikro?~#4'ɃO#| |^M\X|q c/$lWΎ44TgkF!BTk"?8=@300@5SzʖU6N$j|sbfwj|`~_0;bҁ O+vbAPʉ|1@T|z;1̠i@D㎘t m>S=f4Tr"qGL:6')cQK*J'9`9"l/!RdE" <x>xD>b^ӯM7"^F/P+HK,ro6n\zkoiD/ I~:I/`b)NaG/?"Gcͫ\Ho|>=B>>qjSNi]vNKsGC=4^infϙt9yFJf}NW\qEG{;?O>kޖ|%oD_z'W2i'zig>tR&wewYoϥ^FKӦMK8aן$%CD\D ?h"ʨ?>8P(g\k?PQ Ds?u3??so7??ѧ+W:rSP:Ɇ]27&Iom1kTb~R*42{\ [F̰-c:A0b5M=S"`7 GH2l[F̰a` \"J U,mʰ?S)?O|p&ӸDgcѷkf,oI#(_Jm:0?[oouNzɆ/a(o`qKЃO_~[n1͜1wXb{m([s@D?6l)vM_쿍/ğ?]>͘=a}휯ͨV̳Ϧ 种7ޤc_di: _zM>??'5W_9*#?R҇K{Axi?t_Lzz[V_FcsSI&߃W5g(%(C7?͝!TW ?x5кGuWx rĄ2DYY!?`SAרּ?C qYNLF+{~M Ʉ/١Z?)Qw:%XkM~%݌n2׿&͞=;kYOmOsfJ.JƌNo2V$' p/JNUll$X_I/mChO!CvKZIab)] oTDAk ['\y4s&h~øλzc|/^8]i OHm.\8?to2vl:xx硪xF(NmdN;mNo9{NҖǧ}a댔7@[?J_xA{C?2O|O&N&䮋Igo?Ƨh[^{)dëp.rXnm#7Xx=0s`$) Ӷ[ooM1bDM7ʬCo~Ϸ{Ms}GF͛rec䈾Ͼ_X9O?~_A^M?JJK/}%c7"ADS!?^ /Nhj^|QO,^8U~ƼpZnOуH_OOoğ?xwΞ|ҁmI)?1ztCu^{oyKj|Yf+8-]TXVm%uOӤNj<?h#E+sb?dypH./r?heP.ԁ?`!CG a{צ'Y ;^&h pk 8Q&503)oH@ 32`EZK͟|Pm{?Uj w!K?\ǐdNN7x~>z4{?ߑnחozJf~ ݠS؟42FI >42FI >42FI >42FI >42FI >42FI >42FI >42FI >42FI >42FI >42FI >42FI >42FI >42FI >42FI >42FI >42FI >42FI >42FI >42FI >42FI >42FI y=D\)Z .WX<))/0>tH,hPVpc~QM7KZ=n˭p`zF~qiE? iD1aKƠK}t1I]<$k"!C߷b%Ma @AƠKCvP3 n2]ƌf̘Qa?}gܒΞO}"ΞDH~~*_Ϳ맏Siz?7 ϙ=7]}im^>CVǧ3'L?;]ӟtɟ'Yؼi ?P7Wܶxw EbY?xuZqp?8$5X?dW`ŀ]w[|R[hBQG<+1؅O;BLG/ 2dpyp[HK#>W`[ӭQGR0쿶bWKf~BLGʊ%D-*)t{=|}&1BֺO% dUO}k22 CWCFK]xJf3>ϫDˣW_l8RrO-j5dKual/v,l62]E[w>2+o/ov.W Q#M'oȿ,AOğV&q8|5ftz|3:Sӄ]wz!NflS.7!B$.EgI{؟-2*)+IXޛ???[>yeUg;S AMϚOd'ul|C  T܉yJH21mG6]ZbC%/z92-]X(%2ȧ7 8뿇~b`pI7t\gEvѢ骟T?_cs'Dh[B` vZ/Ŀ& ??3 O?ׅӨi#3ӿ(Yd7m{o:cяt;nLqꩴMK@gKN?#m6zo!皷E[iĈt U=Nsg}(C_顯f\>LӧOK&/3ǪOԇu["@2WݡYW{"@ O߸/ɴz> mO#ے`} g\v9.t"pB| Qֿz*-Z˭1 d"`~+7l{GCb͸bo?r.Ymv)/cDYiK]ҋm1-qH[_:b4҃kM/75v9mͶB`ߧ{TTʪCޒdwڴӳӂ/I.ή?~[{O۟?zoيmǻz9x-/vt A?G炋/JcFI3OGGN81\}C1`{ z$:}kӧ-"}ӟM?Ӎ7ܐϟ^ʿNvxڔF͙='>{EӺISNKgvZqӱ4rto8u??K/O#F{4i L揁O?Ŀ /_/'s?Wp?7ԿְWc=,>YCP w' SWT|+iM?oA߰?_Ub_Dw4ʵAkgXXXժ ~~e0OS8;?^Gaazhom}Q`2E'_-jD0?zs~ӛEvϚ5+7B??Q ??"Gʿb -RQXU?\093|9|ׄ]wK9s%t oҩRͿ;/CJd-\ }O?ps;GJד/\wӳ>C<c=ueуYi⤉9bld/eAm_!_Ŀ5 gq iq%"G*'~or8+H7YєnBkaD6]5&4 :iQL$aaaA+)0\'CqY/Yu???C?xL$镋yx_g.˝bM{= 3\C- 乄d&c6&?~m.N75Gϯ[dqӟH%}pYrD/?ߑO&.^5;kUlȚ|mO%XXX\t_c:jیO'檖rz'~Ƨ}}RKxQ띨K@F:8Bw\P櫚>r-w??Z]<c`l7y-%t 0ʉQќ##;0*`X?l:؎8hE%T)~a}] ph-r9@/)5VUk7a/k.}T{Xڟ$/ 7/nK藇Ǥ뮛ӯΝ3'͟??5,_}#K^Re N`~33ʏW@??ԟL}Sn^YYg-_2?iSӤƧm/jc2p?U9|Bu򿦎a??١P]KRݗS/v>r[־:'%>W#|#4A-1hITz5@ Սem(NaQ!mļ$jnTu\Pm!so_\U>!SZ#'왓PgN)$#O5Yi%A~u1z"[΢ ,I/#ajDŽ5/_0"DMv@ͯ!D/TK}ASt&:;´zlt$ڙ}kq[OO{ZPC7򖈿A"ЍH#f7rA:o\o\o\GP_? k!t )KDKfBUPt-j̪)?O/^6XΣ )UCە`: ١J*XmNBljtv`a V0_=tS: =IKTc|6?|7 s,MȣJ^lRyL_/_?%P`0Yzb3C BHd]!Bf -C?"$'o#F[eI#[NRS͚5 yKq2Е /B{/_z O(mYW"-_m0 )mMōgr 9Tr( 3a~g+_\ѣ1 pRI#y=ѡˊd1?~An. |(bJ2Q/쿤?+!B8|C8L?&P@PچXДd3IG@Eq$;: OCuC#﷦7 쿈?! @EEcPB 2[y?%\,Chj,Mvo@ XSͮbyAw҅L;ZFb2Y 74tfM4|a?r/W :Ӯb`kh5.mTl$5"h̒Afd'9__`_y[_(ؑ?#BO7o1 7 q #a{*F7o]%%;Z+AiH'Oğ?3؞B0o+U'? P[y /2SVc˃OtѬ\aam-bT g q>qv =h̟W蟝)/Z.XG&,ga3…/Fn{W:7 wP"18|Xʸg\R 5Te'ԟxD 'ԟPB 7QDR;@WԟQFYb?K]J)G,c>J[.I{06e2]ݻ8"r֟GQt u4 +>!:Q]&3H9G؂yn?aO[~%5xLI:2`oxrnDޒO2^0#`~_GAne :}x R쿈?D6ȿ8Nȿ#O')a(%.&k.w#"#@A򏰟Cl3EEOu_XL'59M o?!D˝ PZxBu,gєvKHx]LՔvKHx0.[dMEZtH 8e˸p`邑qpD˖qaOE: VH 8e˸0OVn(qpD˖qaWEtC#] Hb-J$EQe\E {C^< %[ڳ̉0!$8FW-ŷTE 0? o5~+lV / 4 CJq!DM7j"F7o?x8ԀRsQT)+yjԥ\!UE?\? @1#C-)'Cϭ-D-vQP@ayɃO'ZmlPMLZձgP;֭8/R\YD7Ҵ>Un~?o*ZBzaj*Zn\##a Z6 ySE ?Kj?h\.$ecsUPM:aX?`L쿈?zP /ğ "ψ7+@ 73QU Ϩ?3Ϩ?;?#? bՀG\]ʃOr}NwyXM(37CwG9 *O4`(de#.Dj o[T)п'zQ>ˑOQDTV:_T:7>oы;_G(lܤ<܇!KY uGBօݜJ'؇5ذss5k-Ҿ??(8B@朼>ueP mYI!? /d} DO?ʾ aO>eߜCV+sNȿQ5 SДl\oug4VޅRZ`QZ𺋳dk+gBI)Z(-xMƳw!ĤVf-X& ٻbRJ+,J ^wqvlm]1)Y 8Ix.ʬ҂]$[[a<{BLJieւEi.n0 !&2kug7VޅRZ`QZ𺋳dk+gBI)Z(-xMƳw!ĤVf-X& ٻbRJ+,J ^wqvlm]1)Y 8Ix.ʬ҂]$[[a<{BLJieւEi.n0 !&2kug7VޅRZ`QZ𺋳dk+gBI)Z(-xMƳw!ĤVf-X& ٻbRJ+,J ^wqvlm]1)Y 8Ix.ʬ҂]$[[a<{BLJieւEi.Ύ {rAO{#⿆% =#Ey%*(XHva~؟,?.գ"O9$6M>rRf# _/?/WPC G_:kB @IDATW_QEgQGwUw QYb#i\U`N 3h*P9#&j|Tb'4 wAg>`_ TN;I3?ê`X7G__x^8̹S̲ CP,ȃ<eMy>xD>xLK170cbka ;?@_?#8^9eC%A*䟜#檃, Q@ETOLoEvLW]ye~_=]a7ݔo췈?@%K 1 _?Ko"Bՙ3?B(O87,ppV?y=zW%x%ח*$pLhm1Il ࿋Y,c2m k&1H2Ls?CM2J |#fX؟4 +#H a L=FO7>xYz74D5!LG`4>r[$}pOj4ruӢG:#-Ygd_ vl-1abi?4[Ϳ A [K?!-C ]pEi1m]ߧ3N;M.Y|zqͬhu,Gkz҈i9ԕH:?GkCFJskeszlq>uj4i|̼=A4aX??놌'&/꿜dqm:pPeI4Z r_xlsL+>@%8B*5OP,4d0 /Ϡp:؁C?[.mtF@ `-p:؁\6?H#OUG˒!=v(1P+>쩲GL3??CIEr.trᜠ_gdiק7R /]:tL .Z&mMocZo{a/|͘0]o&Qi֓ҬztOK/N;H6 3ftzV[){tѱ(w1v܁4cƌ4g}6h؍ C=Lwd{fӚ~ =ma cB?Eğ`}^]L94otɔ)uWB}2?]}eJ{Ge/#~7M65MxBk {jAп|e.t=/{HR?o @A1?qWa嵀2._+˩B_?q7ÔȃOT7]ۮ5>m2z6HUX "#Am褸pAHC?NVZ"jK'!!???t"Ͷv2:).\YX^ yHP2BIw \ -R $Ø*'om~2??4w20 b#|s7GfX%=q_K/O'_\xM4~{Iǟj|WHgiwOM_avX~D:o;8>{Uz^ߖlrY7.4eZ߿(ugm.-S <4rd_w=i"Y/ͯ6LnI|AEjGr?ˊ՟.4޾GӇXNp!oJ.Zp_z[:UYYgu OK_w=SKźpץTi)Lo3yӗO&M<')C"K z=i8_/y])?"@/{'t 7y\Z#_=D'/{<b'&qB/$LփUJ pѼh pk ֟/Y8.bqЁJ E!YLB_/ln{H)A7`s .{ ӯ"P;>E̛u vV $Ϲ! mXӃOO<:3nZhQ|i[ /nӛ}{mNd(u<|IB6x4~6[nf˭N_>b]~ib}iU,y{ ӃOٶ@OL;ºWvxz[: =cjҗa..tKVisgmЃOo{[_2m]y{`yr:0URk8?_r? p_b] /Ff<23{>4׽cwnczimwHt7Q锓N??Cħ Oy驧Lw7A?tءET7bGO|*ʽ f\{WvɥtTzӤI`/O? eKx^ k7ok^D)5RqE/IFϻ@{ .˸i RB+u!l,aZ CCm,aZ CCm,aZ CCm,aZ CCm,aZ CCm,aZ CCm,aZ CCm,aZ CCm,aZ CCm,aZ CCm,aZ CCm,aZ CCm,aZ CCm,aZ CCm,aZ CCm,aZ CCm,aZ CCm,aZ CCm,aZ CCm,aZ CCm,aZ CCm,aZ CCm,aZ ]ѝ'ЃOzfaA-xXVގF))J/^0>FhPo˰IKYY?~kҜٳ]}#?4ׯN_L٢]ӆS:=V=o5~t/S>}n'o|_?wƧ7htEM3-^utGn:7>ćǩߪӛDobCnr =gfK.N?Ki[~BzP~S6>_9rdiǎ%돿`~7!D O*;Ꮏx<>9]ƌf̘Q+H<LݔH?,Qoq:[ߖ?a)?tS)S.yO?Kw^z;CWT(J:*[g2S(>[&M<5gbEֿ,HeUBvM5"aoyTtW돈 #g- N!glsV |"ÝȃOl]^f#twR;j2hM#G#eI C>v][-$#tP0E{np[Hп*(QG\ҪaQd&#tOmXG p[H?Ҁ%(QGHMXk|R;`!IbO/yɆկGHw}.~G{T>oW*m|(p 5˴v>mMǍKЍBOO==+ҵ\-^ߟRW,tܾtM7[n_צAiӱc:Lzףګn^O(DuC}gzKAV['c!.͝Lz`i:sN[ښHZH膩+]wb;"/Om2VΝ+ xlݛ0qy>ngHvN4?fdm~Z4k֬tץ_,m^:]w7 ҍj9ӟT ҳti׽6mٸ!7t[o%߉Nwa#||~ln{puH@vt|5:fk&=x߽4Kg7Q('g=16ېM4-ZoOv:MAW@M<#mn/OKMwwug˄ u d<>++U:W[{҅矗y7}NCNN'/Y#5"db! `v`⏕OƌNOG5g&O>Y2;#}3^cO=87(u}|gĈte^Cdyz+_Eo|D5%oȋSOM;BudA}#Ӵ͏hֈ[cKqdIiBET!zA-ʊdMbdcc% CVw Wz.]270a`7ZS^+KHҢI 7h0JD$i c~*մдf-)x[uMbhnAQ"& {>%MΠyN%"n?+O؝7^ewŝyL}rHܻꕋW'B0?+8+5znwC Gl.]roeigvlCͿ|+7|~TOZgԨ}6HzQZ~4uʃ+YblGt Oϸ{׻!o:On0#YgͷBU;N?Oƌο"YO?dzEz`f=/\)]qMӧ?{R]h bC)QlIl%+[{7,XWc&ǒh5XbY;*V{}4w'$x|^:tQ#Gȑ# Wzء6@8{?<JRp3|Wv'sCIv=knaYaŕ]3k_u9g~FɸGz)GW!I矲s= %Z?S/GS=:)?4 ĎOS§CqaQG#[lKw4>^3!LMs?w ߍ7 bi&m},t]d {G\y~'buWS)#7Me@/H3/°Tv]|30fO.TRÜ7zXy!tGeh@^^*s*."}P'b EﱵAl ?L2,RKL,74@Q\|2ɰ$J gH8+PP,Gw|2#W ? -u5অEp߈cű}_wU? _OFV!p9_Jen&uzP܃]W4dҢe3g-ݺf l뼟|򉼃bPSЮ^8Z[7㗩}(>`믽N&6ޮ 5\w[uLsyWdv0Z{u&_V>9Ow~o!6ꑷL ؍h`g.إrI'7hc /Y#tZk7_L&8r_ZÎ8 ~"3g͔7_C&M$_QV],rMr]w3';?.$=Pa|c=N[n9аN:;LĎ?ӧOW.eFͺ[p4b~$c_y;@fXKXwɮøP/{c?*;,W.u#SXԵ{7zuBO~o\{> ( oZX&^nFu":^ Xo2x'UW8U_\ة_흷ߕʸZ M?BƛN;~GȚkcw7\t4q"C]EYv57jp[d?%t%l= q>=cZl%C 3>W>xBөS'uX_'ڷ^s!1Wh*v`7ntZܩ4m^v!q͚=Kvu׊uqg?~`i|jIw0}v'QUgz6$:@9ĒS*%&U_?'?c@LZx[u‘],|b54e}C61e#|$^cGi] s{=ߍ܄݃7; NcRfߓ_6h#Ytq> #$T'VX^Hw [uS cce@A'o|z󁚉fd0ʬ)/ß?fϠ#M7?̗?ʖd^7[֫8r߂Ruz=nAKU I.b 8>O AdIؘ0!eο?|L%&ϴr[( ?{~+`L=W iY2; ҭ+z~geYAh48W ;t-[XhGOIozQ~E(y xE[t?svL>s:nXӣsɥGG5Aw_ &' '3g̴km޼+].+b߉ǟ /c'Ͷ+jIc><8Y||}EXx2^K@sk'-g/S?[nxu䯮Y m˟~݀&{‹SxJ; y-,*Sו]fv8 Yw;-7xcWEa+g̜)-gϴ_rI݉J袧i{vՎ?ynUuU:wƌ >n?L?GO6|s*X-jZ_8"Yءiv;cg}pڕ\%+kr.^cTHտ#2?~ 89.]:ŗ\f1RFoXtx<6?^V3gQ.lr_l_~U?fZ]}IN:x_K:PG->/ edf_92ysēN 7~dW>Wd"AaZǟ[/zcUQ7Ak/J^SCiBG*?AP!+?U 87+?U?K{ȰDkl;>jNw~5o૤}я3_gC$z_q-Ra}{ԤKU->D2jhο}9PŇc[}$<"]t;^.ҹsgT@gx _V"= ;>bAvbIyRYW?ZF[f~U;?QMbTE wt.I'O&i$ƆOz+^JWV(B/kP 8~=IP;/z+OJz% KG+h4S/ʨWrb՞4Ug? UiWSD(=i5fIA4v{E0{"B?EFX_]vHOuTāp_i?u# Pzj~X_ZQqhЮQs$ET-#66< GN]e-xхOcx>Ίn^ZˬYd>X|eo '=5_8U;s5Sޚo6j X|YCXU2/6oqc/ vQrMrםwZ?~6~}'C~E2t#v_6/v!oQG˖{\C]qU& ,!`.A^'cF#9<_= t إ S9/"Pu&+>߂_YaSm|ŭE#M>;MvoS&M#?W_c QC|'| NǖfϚ-Ͽ ev<],j9?xP) ,y@S,O/>>[4>AWQO7#oRFSxF?h㓮} :T+KӊRA)kͬJEZI͔/<+?PhR0iG sc*w<+??ԿhWnzraϯ:Xg=(гh˲"}μZ,F@SX@AĶ0,v B=TU*)qUvtnFZ`'P c#[`1?语?Cy#0j> C<>ѿ*]R~]4rYQof2a+D֦8gk6h&-9 ?Î8\~66S?Cnl"[RkaGJ+]|;64'|5؁jE_^xZr ,n^W"}ɻS{ߓ0YO0y@ ۴UpTzUW^mT+JݝLwݹ;ɓ>8$c5f(cJ?vpgM:Unr-ҝt|u} .§naǧt'mOYcGmNV[m iR{lp۶m+;l{#^tӟ:p,kެ6aX~e5넝.\5 ;>)v9w|—Lw| |Í6N>v_jyijןocٯCG8Fߦ;>|G~]hm0Av.Fo‹.ƽf>6zn䐾xur7EW}'C P- _ 8pZT_οDw-օOGkzfa?C{qK5S|Gy)ureV7MmСCPQt'jx)lݏ K:37W?ZvyOφ?;>^ƍn}9[[hY?>E?c[=7ߴvƿIsq?mS E+(ͧp8 +o ]qH)5RQ/GS}]wM JAjT-:8|MO{ TeCNjaт'eMZ_50N˭M(֡/\S :.2?'/|;llR/q;hԼ~,lP5zg8D{QTt̚9#U_>;>aA/ͷ\:8 tTq,r}#w-)c޽+;#!(6ڡM緶;]"t]r!43O˙𣎒AEɓߔ@_xgWvoߥ +-'W^s-5ߤI>< 7f@kqPuׅOvz8J'?}WZ/|=gk'`׭+б4EK:wcw 2tـ W)O[cǧ'4CۮZi׮]C_+oKĺjk'_q~KrԑGT\ ',n{$XcꢱW^Y;>}z 럡:q=UTпlh kp&_GCRc0kfVb63TL`L67ciǔSC.tne]K+~y/A+/,'p| %\EpSUeW*]~^{IcϚ=KYyܩ}D's§f5wWe@W@CC' _0j9_%j\ ο?h# ?hxKN?i #؜I{1?fϞ݄qA {`R_JȫJjhr|NF]-Khc"%(bg%҆%%T(mCLcbS&6pS䱤 Ghou=4؎!|$U5"_zY=^볹mQ-WU+_Q)Բ[^u>v]vz kl6Fc]D߹ hcFXQznSߟ*? .S:yI(忕"ѱbe;x9o?{oVb%zBGG`IX4Q;N_)&pE>:ϰS ƏG(+o^Ffj>{!3f뢜_oawa',V)wa6l?W^~%ykʔ[?bl%/^Zή[kJ)&˱G%3Pwg KtA=t $;c=[tM7b͟k?p%VwDkݬiѾNZw93#OG}Eo ~A m|})N,]77|hi/oEwï;h tbi g|ͶH_s^x)1n=_l9mC]<ȣrE~p ?3~8^G"\w}:pyI qhFH%ZXo+mZJn)d-RQ˫ȟ koa__jhB n-fPPO5X݋Ygȭaǧ)S&K.\:܈N:I^ :W'ԩipɲjS4SN]vItƇd0X@r5{<~Gj_q/#F[ȸW3Qp8gu??2eQ?9rKC54&٣Ӭ$rBBiE7] P% %&L3i-#8e.siI!bZ J򟳂JP(T!SٮGPDUjRy()BAEu$l|RD,5 ;.fj[Fu>F!՚8.ʙZA;Ǐ 0Jw6:}gr_bWĢҀuGw)ҿK˶ɛo.O?T}xvv3|^\\S俶KoŮ^SO>ѸlA "6`~.{k_FnvMf7ñ{4qt|Re}_~KbQII}#S[G_V'=7lPX4/׫wygCwjvA%[nQΪׯI0Wj^tԏ~,YI~+:ݼ. [:Q#nTWSoLzb0~.xt 2'w9KkCK.Hyᢳg?aa-"waj?;hBO/t#-߱2˭n̨2b0}W>v퍖"\p<Ϫv?1Qn!mڴ~Y,>6>3:忆 ?XkТѷ. ozu O,45\-vd|1]wιԓOgi/z,Sb%^.Nk,FXUpk?XeN7/cx|׶:^v??#łOQPڤFN[§%m|#_ Dj5o~3iŎl~u0mpXLy ÜCaM<}f_p}:tS|g}XVYnywa'z2w谲|_w:eoMܩ <|o[:G5k.t]wMx)h]8+d :ゎEKymk9vu`r6aUʫ#}#})~E {[v.z#^[:l<\z)X3:U)`Git[S}'|K/v[b6V~w|ܲv_N:~`}Ueٲ׮zKm+S[qG}lm; L{-^c:*A;p͆Uʏ'??7߯.i5^SU>RZle+^}U9֮G.Wһמ`E&+ÕD/߮\}uVs]2ӿ{ilb\m|s~: Xwذr@eT WY+k^e_⺱oCԸs?I!GiSӹv?&1UG۔ο96wСɓP|@lo~G"Fj$9 V+7'M#?iEU#nj1S#ޜvurI'ˆoh>qGY1r}flSۨdo?2S_,d$??-;/ME!d'6̭ 5G $ks 5tȨk4**FR8G Th=H@ߘx(y(kF_Ϙx(y(kF_Ϙx(y(kF_bI@IDATkb[Qb;}:;P\_tP^K Κy|UX'^R->JafL^Rkvɓ=JsM/I1p`eWz|˭f6hGwՠp,A7: 4D|u]67|.n}9^C'N9qoYj)\OF:^?tp_~H]rI.KtpȠch,z J3O?C3EMףm~Wuˤ#ϐx@_q`6ڏ$+/w W e4]z\/W_w/hzs^D_~Ԩ1 pB9e&RSʿQA (S)?LzbTSR?CKK0!;>ʠ |c)fοU쵗 SOiVY?8?xb'Կ8:`m-G:q=O+z(G_ѭ`ޭ~%GGXI(?Ꟛ:RsZ1Sr[SvhVZݍ ]xO2WL`` !LkcUp.7odeқoțd2kL֚ҥK8gwx\4ؿ;*ȧxT~-IFYgɟ5Ek+O?FRHԣ{9 nz_k{ @¨{6/.|kժ%vd]~oҀ&e~W=T:6% {KpO^;d*c[n*a%,RiFva`:9~;Ԅî ұZ!(n赪 ]u /~mAW5ud=87PB]&oގ'HC Cy?nLLA!CɒK.)S`GC#1(`| aV2 _aM~.͌ ]w@lSOS_~l&W>7>Xw_.:|lJƽ:V.Ϸښk`'裤>PGQc'cǎo8A,WF9_X/όGLeÏYnOyPAQ9&e8:?2V LpppUJ)q4\ J=m@_L88ogb<4x8B&>&'s4S`Rbi˄rUgI'*IKuʠ SU"Q{!EaUkj^?U7Xw }W?DY:P8j$6E8M]J:4Nvx]~)ha5ҥk7pÍAW_JNx\ޚ29&H>P~/p$p, /ۄ+?OS<(3fͲstъb*+r@B/ȕW\k2_rawBGTׯ5޹].FͰO9@ 矋(\.؂]`} dP\K.)͚= *Clqo_[Ourɏ}h/a|cW."#[[ma(hpOKkX',̘߯5C7k >2x0v ?:K,!7 /5VQibG& X;wvƙ֯v/VK,i хOwή4_ {.+ qg%~ݻwhv ^aV$t{D_g |!v<?LH_}O' ">mwRtctf W>x_Ďaz  qusGǷQeX9Wċ?_PU?|x;>)h2k=k ׯ9_\?{i%c-m?̉5$' 2?2:\LfETW>>H9nXп kFa?F?)$K'|gPm?xDOڿj o5ht-/_ q| ?aݏk*V+*ҿsem"'ӟB~Zb_/ vig喛o;4Dʊ=>{]ЯXtw.dkXx)ҳc$# ~HÀ׈vɓO=aj KY*/\lL bؕmZͮ_ׯ+ckw`'mXUZ rdP vy[q ˽c/gV.ʿÇmXr&JP<}Ɨaǧ/ο%kTceo7KV?>ҟп?? U=SPP0ߩ7ሿ`',|:0PBD<3)iU3ϒ6J]2`leeK-͎?lɓ')ؽwڴiQl:/=?ѫ7vn4qozw1,ЅO-^~Y;0r/Q)Tx#oҿ8>Wt#՜]VUYO?haB Nټ/㏌?2HO=M5y (+k%y>BxZ3ڈ5<!BxXJmʚrIL6beM$GOKp@XYS.rҘi6F)9i:` (+k%y>BxZ3ڈ5<!UFhr u5PcA)!ED!_Z8>9><= VDB:K%Zw?iN/ăsbnL?G[)vkrzFѺ']V,>u,]lruR{Y}ҡJ_&ȸd&vZT׿:vwڭnydגߙVɤ7&ɑG` Pvaa_{gu֓_/M aǦj3,Yo` ر;$o%سjkH_&NĂqX08#B-j$,>z駍2 LB>OgB-˴\[:bw,]D&v{ձ' GhtAv|> rک'-B1ĘtYjl=wvk?;bL<k꿅PK7OoAY\OClGW%"?L>hi"9jߜAa諬\~ťd֭?Ç^~Eyu+SԚW]m5Y16^Ƈ'^z:{B]ztZ;;1x|v|bO$ܯ3 B?o ?]%LPOQԆe??aS¶8r/ڟsi PN }/|rA!4 ֯dd$nKZb.2M?xE%%ȉ< s5 4/T@@ 5E1W, u9s9 -% //doXJnҢ_*% b4fG(#-rYW8>O+_M7ʙAg햿%e Cy?UO`|P4 3j4v|ƒ^xAp)g: e)T?xRIWAu0AdigL 5ubw rnݦ xatq0L]OJc>o*'_hƆjCm7j,??h`.PU7ڿ[/ O4P>g&JK=-Va vv=U#ӟZckWe9G3?b]"PK=M[Mԫ?o.hP~Ϛ<=:M鬇yQ:,$hl 5IQ3x(洇pXc) ōڷI_M[s~Ŏ2}ƗO!Jܷ[]vt)RõO;2]ȪvqG&G~v{NNbA(TLUrzQ!BuD\%>bA(TLUrzQ!BuD\%>bA(TLUrzQ!BuD\%>bA(TLUrzQ!BuD\%>bA(TLUrzQ!BuD\%>bA(TLUrzQ!BuD\%>bA(TLUrzQ!BuD\%>bA(TLUrzQ!BuD\%>bA(TLUrzQ!BuD\%>bA(TLUrzQ!BuD\%>bA(TLUrzQ!BuD\%>;> m[O:zJxq#`YIy# z@?@. bp RhLKLʻ켓aR%4 *v^xy9Snh5;ڦaw0\q饸8Ewf$ 0w{{s,nѷO_̔8G褡(H[YjS4ЯRh3~St!b6H=HÕ՛`3 駀?2)3PT$V:v4௨H)dvPf5̖5z4oL}99SΓ;_?7 O=,_w-Z/+LpR{MCAprjTK*ڟ3Uaՙ?E+&'**i6dw`J5-g(E/_? E_Rd_lCevAN"#zY١FX(B&>PX8(T2 ^#`i?ʟT1tfX`'x9 bH4JX`'x(Rw:=A5삠ƹ-:NܚdeFC^ Ά '?O(?ЉԿazH|v?׌ PhI\f!ea7̙f$O?1޲D<b(]yso1o1+0Sՙ㏌?6#Ucc,3MsƉșcg#bZ!v8궚7Ay6*-JP;gL-(iQ G9DdHA˹Š<%-JP;gL)9g#E)"j ŷz[K𔅨o{I}S-4~OCN( D[8>OQP\M5&ٌ(5lο?70_(A<u"h3iqYߴiMNd0( )a_-rrڈhv3o?AڌG/ϠCݡm|i/`y}g l'H2T̵ #r[Jj+ysiw?wH,HprE:OCb.y *x"2KR\\Ѽд e^C#qM$$HprE:OCb.y M?]ͰFVavZ & ( }yBaB?t>9/>3NvI/3 OP1ƒqfƟWY >Re4`g!؋ը???@3.&lSxB])Q<7lx3;Q%CP]*Dt3 oHQD (l96X,5RlMbu!Mϱ e9b\lŞizM8V(G͡bX].|HslBY>jrCcQs(6$V=pPC)&\c|J .6bχ4=&+PmpI.{>96X,5RlMbu!Mϱ e9b\lŞizM8V(G͡bX].|HslBY>jrCcQs(6$V=pPC)&\c|J .6iquzgf-uB Nb_U#V Y8˚屹PUŞ'&&Y? QdTPQkPPr&_?3ڍl̙(=2IS$K70Fb7-j+㯌2+ό3;5w5Q4EK[4{v4k!Q_09'uhy+gf̺~|ls|#QB&礎1?$k7PP(T@? OxB $:691@%Y:OMKvO\PJW* Mr*ܣVgH&e>H W;TW?/ο?hMO}>>f O#㏁4#W;2G2f*|/|o|o|o|s{'w_ܞ?$;>b{1-K 2!VSA[@Ki@I 88%I]FFn%%- RC/@QvǺ`LLTuNXx^Tut@VuJ@; %ɼD|`-CCO^"Q9`f?h^TQHڟI;qu_~f ڑ7Ecx}WF87a7c1bGLj20+ό?3d^ ,R{7z|Sou 8^ c?>/0S9=#o萧y>FC^zx`Ɔ4`oq#I!g==䐧R9Ԥ' 98S(OCMZ8vR``Y_/5Bw?^oO,REn˱48>vND-*u%HCVVfYʊʒ?_9) Q9Q++*K"rG-w|ʥߌzX^5% CNԜŁl,czs)?5YkP >+ 8>OQd 2JԿ8_UG|`^> 2p(`/n0娓MmG|Ȃ0 Ao?23}B>3`>@߾V= ]7N:fL g-Փ*B%]"I/ Q L 2}bdz:-Sfߌny\40/a~!~| 0Ȥ)XMW_B0R!Ӥy(%``iK(%``iK(%``iK(%``iK(%``iK(%``iK(%``iK(%``iK(%``iK(%``iK(%``iK(%``iK(%``iK(%``iK(%``iK(%``iK(%``iK(%``iK(%``iK(%``iK(%``iK(%``iK(%`^\s,|BZp `CJ^e0W}VfhS޻!3z8~N!"a#ᬡY۝O/ 6;4./㺄o!8b^AA!;54K??`UܺJ?-I3E /_>qgFZ@'O?Ąc#.'O o=p] C7''c QMG0щKjwFL1Pj<`8>Fœ:} I*E?(`tI@&_QQ,SJ![yR?@.E8$I1*EVcIe#K8~J]'= D84yZQk(?ְzCGuFVm!घ9kD OD(zPb'hpδ)/ο?ܲ/}͌$fφڟ2Oe1x?2c& HL cugjoGp#52OaOS"bcAQWsZ簧[ebcr|__%)K/R:UW$?)S(?AKOqnr>Եiebc._uDžfM wZ}ݲXЪNl⬧h'^4Y؍u(JDrJ7IA?OХԿ*9pXi=iO?2/-r`l"M?1#㏪eK2㯌 ejWՉV3N@㏌?2c5e_ڑ-fP;eXǢ|@5Nj,XJ3 -[?ϥ'(%ŢxJck?' KP|$nt'3pe2ZjQuPօ- n,ЧCɖ˜}8UIF~QKSY*?Y9O)PPTLp4Lq1:a2qIh/ڟPP ?3’ C-N?N;tR,wqocc5\pO=\5@P4?0 jB]k13'CuiG/T!?~`!19*_21P_+H*&-|½8/ k࠸KEAKÚh =TP@ϩF(A]h -Sm]@8֢@P@77:0x5X+CjSBk0=t~G@P˲D/ǏVZA??yBňG3Gn{&l &HzWum X 1?-ο8gڲd%Q&*Sߌ?(!ÆJ%Z.iӊ>emWIV ce@~Ki-R3m<_㟋RS kEXdi2 QCgJ? SRcV:q2jK6Om;S^%L \8Wa^K4I}E$,KB_l~jI/* t :BPRr)̪iB^ʨW 4U) =igZ|ר>Ȓ~Vd8EҡZ_YLMqY^Oi⊲RKI}5Ay-yȌ/O~ +s9K{miV'ɓ'cM:u"Kj%N*|VsN9EX̜9C~~F[;uƆ0~r~jӺ[mM3[-YG_xd+Ϸh>3>^+/t(K"~휮?Y~ d+k؋Ǎg*^[mE_W?+Ow5 sG+??[4OM;I3:! w+5|Ŀl'Ҹّ ViE]fVV"-}GZ5OHSa%R6GRQPPK(}Ulr)K&UQP|c iб`Adeӥ8ʕiS# p)_ZMgҶEja3읉l,z6$[8;T Ԉz=s>/r]2J'}Ty&GΫtK]^F)# 7~i7lHiղ0^;8]K/5+rBUw>;=x;MۏW>x %cƌGUYe0Șѣd6KSѿ[nZ_fyl6Lƌmta߽{= yw95Y_Ofè!BOfp_?9ff쀻䒭Gk.n2DjT_uAɧs.~ү_N)9S=pj˭Yf׍{esΙ2m'0ӵcƍ+;?W㝌2uQPr/lO1?K'h 7@IDATI\H!R-P9/ok "г (ͧp8+Dj8cV)(LYZYGо;TpQQ*PRM?= T'5 t+b'eMZ;`):-6Y6}B{:i8_i_,_~d4>ca%Сl7;޻@5!IsMJ(-]t3wuŗ BNƌ/odרD9F:-q6EG-[|^u|gȺ뮋q1ĉ^޿wxrʻ`ǯ&v]\N9F8Q]d[bb]4B>aD%_}Ux@XOBGveвA|>)e(q,$GΣEMC/_unOSounZL"G7̍ wʝiwef;9ELBQڶ]Zn閐/{'#llìٳ^{Lč'$oWvkÍG[#Yf2n2Yߦn'xQ_l6'Q99Y?hd7G )|8X T4#y6Or (7ٳg7 ӿx 4fG]iwJ%YGyb qcU iRTʅW~ GddNP¡F8( Qr/G0fqoLe ȥHLyb*c*NO%R9ʾX]P|T_zaQR(ԳG˵hmh\fΚRn'K/=(>p6ht2e'$;wYE]݋ƌ!#Fb&GcD9cp_+;7\j5I'ZSz2 'Q7!d;a~#e -.daκ ;g= w§ /4z܆^ŽO;3J;> =/EI.J[Ao0I_Щ(P _m7OD-v|8C}z>bvfj.?{E=AE_Nܩw JG=EԳao(UQgz"ֳ`UlTd=@P $d6dͦS)]NBy/ p]\}uԴiS1cxz7t_5F}!u(}t7>J+VD?N77`?AuRIٿlkٿfk5ol=E'>SϿ: feCJ*BN1g62Օ0Jd1Y/g  (;d*ȭSlg韠 XmUrR:5ȭSnXl_;~CGX ?otR^D.~4.AȿM%-ă|K|REqRWJT5̆oVv;N}f|2]^wnխW_6$?1Q _q"jxahMjJ >Szч? CpLÍӞ 3hྵw/͛?O'Ys/Y4C@eowGB^>T4iמ{Cnw#>IJ3iʫgׯV:vj4yd]dMwޥF =܋i ;o}FM7c?DN;DT݀>.x'h]o&Mmc鞻qwiUg3:쯇VͶ!lW\\LsWc=B~벼0OmXC[o d/O~XTBnrǷhtGPm:7}O3MI8[|\B_T\rGdMD >(}@߰k+C_?vmO/NJ,[o;0žy:4Y*yV˼g½lש^LNsp߃}.ϱ|)T\1=̳you_=eJVs}cb<u.Qǰʿ?Bb<9뿑w ) mg_͍kͷ حfz?i]ws=mb+ݚ`-vu 6o6;Mh?f';܎nXi㯱(ZQRRZ,0RӆӺZT1G[ 1*BIjq8`)1/3 d4e+Nd7b?)1/3 d'i(?1W(o80?Rb R'-^fb_%XRiEj xDr^eD??S8W]D5' -ZV[m#{bl@9ȣI.&Xg?` ԰iD䓿!=WW.?mu3)#( / ;qi{9M6?λSE:t@G},Ep_{U+Q >l2tm;NpzUf1h| z9V"s?ks19~FtqKh#lvIn#CzrubJ_{:%H7v7|_8 D?,B79ʊgsdIi=X {4Uq[.f62!6O76sv:ŗؠoTvZt)-Y6$5'q(&ؠunӄc{N?/Swq72qi]hXQB^)r1'@*T㧑<#T`#Gz`|V珓i 6n]|Hs0ljUR.i 6OR\=<޽~ >|X8iɷ%؀fJɟ?V]D(;_,)2k/ȶi h&6Dx6\yGY6>g˚f"t,zPDyp |M|22B]s N{\b ͛K.TTg$qlBMlZk3z橧iС0q6>UG/'ӿ2e ~Nv2_td1/[c(ߟe/g7RH~ԉC, C8le/[[THf^ݗR7'cil*ǩ =T)D.s@sw|00ųQ(ULLDDFRك@vP &&" "#)AAT ;A(J??x * sßDƧFvF8 vSŜ+TJ.G.HI| y[VjǞkDaO8}<7jԄvigGO}˺c۴vI*615j7VJ~-NA{tqn>i-|*7r mZs%KѼysTUゥE\:,N#̙/<6S/*7jԀj⤘S rK.tNq 8-wӲqxcΓO>ާ&'1 o8j&mԴiSyǝCVܠ+."ڭN:TA)9}Eۗj~εlN2$<\t[b96](^O@۰nSL͑Qg1ӛ~ JCR٫S}.go>ͪAƤ>~Ǜ M.q9L/prV[}q\}Nz@G|FOPɱҽ܉OLC "չI8w٠OZpFMHX}YO\5\:,ț;79e1$tYg2s5{,9E16mIMԧOoe&d<}W'#{ {1|R \[tp]~|ZOdUyp/ xGI'thw ~|?+%&oǟ^XxpĂ@L~g+̈nrL4ӿ6 ǝcS5?g$>=qu*fuF6F_DgϤ>qڔPsР%Ov{}_gKlŋiUt>TpB_5=λ^||mOYMɸw=ڇzqY1+O?6k_Vٟfi'4ڟYeZdfob dfl| O>3%(~чʆY}Ũ@1MdgoQ('VlqT¨\mw9n'>Ŏq8Y1\CWd0g} p~b^re^}#0Ko:͜JCׯgT *Oy]?3p`IwE&}Db9 'v,Ǜ9-uQs FԖ#TNR9h񡉄0g zbc=М04s.]ȋ_aӹ 2_ҮUe΃} u87Gpokj8y'7æ#I'tE8od؍#͵wz.ϟnSsΑ;g.]H녴k'>awk¸q<.{j64~89+{I<>o/1o<:-=˱5";If,G~M[K8xi}>wfј1c?@]:AR*??<~+OnT??uÉL|aų>>zn 6*WL+JSAF~=S\\LX@V~;<)SzuM)/gK_\t$&w-yqKaF\40yu# 0ᄍ??' edeBG':eId?Q0nydl|On&߿>s/+>rzrs%\~(O=M;;!Vp' Gӄ /6Su^5Wf|tE6mlY[nN3DFY.YKxIj}<*? [@"slB4C6:yl0֟2&ac\p0Kfic&RAMNn`^KH6Đ0y' 4iWNR?a??P/y5_ӿ"y09mU_hbGT|&,}IQF"%Ҫ$oV NHo;+k(#/<` 83<+E:T|A /h] xysXlZV,_7hٲ#FߵeIɓiu׆_y5l mED̙#|Z?/O?=+AAǢ?U*WӞڵm<6P{\k[DGᄨ?߾}GOݱdo~$,~,8o!q=:PV-:&AZo,  لýK5X'MW'`?ĄwۀC:CB806%d\l-޵43l|ޝ3闧L.:d0=38]dSfJ7'l]GA:խ+/~R.>#]JO\GDTV-\Faؤw'u gRw;tWIB'\;fL!]+&`m^>}}p0[sZGm25lcA0cOX~cI I0i/DCt~en+2!p0D"Vy q`b8~ duzzmus5 }uOfj!vZq8&rYA4 + Xc-MӉJ#PqY>+r]k)ɨ47S"hƙbJ#PqY>+r]k)ɨ47S"hƙbJ#PqY>+r]k)ɨ47S"hƙbJ#PqY>+r]k)ɨ47S"hƙbJ#PqY>+r]k)ɨ47S"hƙbJ#PqY>+r]k)ɨ47S"hƙbJ#PqY>+r]k)ɨ47S"hƙbJ#PqY>+r]k)ɨ47S"hƙbJ#PqY>+r]k)ɨ47S"hƙbJ#PqY>+r]k)ɨ47S"hƙbJ#PqY>+r]k)ɨ47S"u,Wr0xc9xPZE(Λ"T R)U +E\doMO 5 *6!Bwi'eWjv8lbנ>N"&LAeIʉ(|rSȟ\`6n+M{Ǿ={oqҘѣA%\|'dѯplبU7lOwc#;x: +g7/gU%KQv'@x=t G4'>;}6^jg\P<,_yO<8Yljq(6AƸM4s^E_͠3;hÍt| MO.OH&kAGM.7kO_0 ܠi/6o>__Z 1*ֶOcp; Ԛ]tAԣ'NtuL裏8Y8y8h.ѣ78'|tLc^2<_#c Nï?RJ#8;RuM߬XI6.kc6eД3*ڲrOLx"[ƿ_dYH@Q5'ֿɉO8̈0bnI6'IHcءF-$)qft(sK9I:@ h0bnI6'IH34C)[IR@`v(sK9I:@ h'JaܒlN3C)[IR@ 8P #dst8&JaܒlNghIR1$1 P #dst8C3N:ˆ%ٜ$ 4 f`R1$qҡF-$)qL0;ˆ%ٜ$ 4Ќ0bnI6'IHcءF-$)qft(sK9I:@ h0bnI6'IH34C)[IR@`v(sK9I:@ h'JaܒlN3C)4'q~L0*vȏ]Jڽ݈J: ׏;kWj#25qɞ{C*VnO~}AcoP指__^'դqӸH4l@7 "l48ZѲ RNtAjԨcn X[Gd}H駟 g+|R.އN?,&0qo>lz>ǵ yoGqN;/@)2G$|#_O'IHE>gINa\io)H2\9z.&O?t9 *rT5{,۰]-DmBPr/QlPfq6[,s|`%] a<~|SB9\tS!5FJPI Ƨ:6įmuԵ;6;龜0Jb1t6 %^RjeD{ },,NqB_Ɵ?=X>ml>d-Y7-GHO<'ᄌd\s䭷ѻu//}'N|:^6D83Og_\&=IX Oѿた|| RϷ2; 7^bwB7g/l5C&RBž_ZES8 ،T&!ènzdXBO#^xyqikWRw8jK7ߦ֤v:^{-xMUSyz'+zv+ҨQw XWX>6 ɲƟ??x o;?va$Fi[A'JNvM_j$J#o?3ӳr>5ٿ0I~oɭpU1^ VA]QJ#+OTys0Ȃ_ :tq)]nJM8`d_ 6fPMNs]Yr T`xup_ԿnS2xa%ďH]~qBxWPV Tu{T|[a&4c6ی{?|2/ŧ? i]Z%7NP1=[^47@x&M†R.v?:‹D|z-7 lt?Nq 5g՗5nrZS_vzQlFb 9=*UH3׏*[J-w۝N9TYsn" Eħ\b>m:Й(DEnX]6Jth׎~'GWp) `O(%" 2?}/"i6,IoooҔ)/6t|m\sch{ٷa$>} .+uԅ7>0hɧI FV;dBYkz /[OOZNp/NᅷA|? WRFۗTJKqONhwFc_ W}?bMf3O?$\#FQD>x?bsw}Sp*T i'Y<'7TDqA,{tJ/U\tϽh>>xoi8=9ߴK]$>G_e ?S_^>/~@'<˟Cdn㿛bc9a@o[uB_l5c _cǎÉOspS^~\9u6ߚ5k .]l)'_ S/Y6=q:/;ݰƯR[G7_E*y!j֬]r{z7wlꍏ9d+&v(9$Ɖ_Y]/[oUO1jl7Vl5??qm] 6lgDg+vӐO|twU-3ōwq:$3uk"qk14Wh~}v|@\LPVT ÕWWL_Rm쏭[ GF)y R)Y KH/-u5rY_PWߐnǩ6]Tjchvz8/)W)N,+~^N۵F,fyq9>~D$'>}B$O_s=or- N͛;zw>tƿN)=>4PHq$OO@ѣ͝3;GщxQ.u>#;uE>z4c' 瞼~ؔW'dSStTm hRl|jw8߾=Nk}< {8KvۉwƾKSVm޾ԪաYZBo+w^}6caħVD)W涾TVF&:4֛o;7\"F;)O4'DUB7nN^=8yLS8P_?'q`s# rIiUWygd"d( O2gAOS(qL>/sB $8VYaͿV(Y?gԘTZ5`ۯmW޽hA< |OwƚǏGyn0<;(9K|b1?g&nuz}OM7}OF섉p]y6OӱkW$p*oex?[/#sh<Ÿ0!l708fi?x`:lDs +^Ru/oZWw-h}9!6|p mn/3nCяx21N%:GhbzǒgUZ*r߀UD,. [ߝ~]{i ^ωX&b@ElR _2T'^;"ޮBoy;m1o#yG~Z >I.|> }>3:?uh*7cfx:x"-Zț<?]G:1>>4/1vm+xU@4;`_ 9Uil#8i`,! d_ǩFўfĻ~ _&Q4Pħ\4tIE +x͝4TNmF)u=o> ;}DGm ~J/H^W㨣C`l{SR4~V'>8۷ai}#'{}ڕ;0f5]qeo}i<};N;496qҿkLxCW='1c{YugE>(^TkѿvKGqعXr[wtP=֡cOI]C}1 7|$ڴmCm\)'|+"Xl&WDwN"PYYn /k2bV&F?ɨc%2Zyӿqp2lwqS5Ot}o Tj(R:N5`OAG:[=W(87i۟Wd<_<|?OĻ aىhcpMmgZCv1+7ٜp%*.i/7r+!DP?QJd1aa<3?WmDk_fig2+"f2;kUY,a!8qK Ry[VY@Җ@qRyFYbwJ#WY&//G6lſDN` ¥SpҎ,>'#EnPOm?| ö]~eh>VDz!Cs=" Cݏ?L6~DLUA6buО1pCOŊ矗߀ON`6q_߅Mm:*laGM]xqՠ?K06fխ_W8w'c5lԄ'>_gOӧS=9Ui]O?T'1gy ,Uz%S~3>eo}믩6n1-?ENq߽gw:CWQ{G:Sh =쳎@`|tɥ Yu|!W\~i9˟6ĩT1 nBUWW^{-mBaCW.}fXpԁim桟݅C^+W]u%G@6~aܶq2װ.|";%lBׯm۶֝vɴrT7y(We>6W.YSw㹰D_4<_̩OVflla_l-QƧ90G8 "`gu4O{e{.bzGhm7FsGM:v^xNNɽ# Zw",l,bރ<`=uCE|b>q9}}98e(濮b<2_[o7g?~"5fc1_0Y_k LӿAa9?^ 0lFA|5&ɥ-!j |S?D'Ċ!Ҩ,0Ž?@ ӿM+H:; `/Ni|')Ll4 bn G bYi? :+|3W"jFmTv]9s/Ǧi7SH`)/ys3#"? {xl>X䰔n>^~e\kܤ1]7ʟqRn')X7VͶ۵߁.ũ*\7֫3 @IDAT.zD+][Ng6 8Mc^Fe7& y, OcqxsXl 0~LժG)^Ɂ7,SOO 08ڕ5=O2?FM㴡=|Z<(G;:kӆڶ~1ګ>H|؞{Eq2U]liۺ5*r-rly鿓idZujQާQظ0:l2)&u7N׭YF dZpUJWF'bcFl>CLNh q&4`E|r}mt];e_LL}53sp46AC1O}@܈n@G7>18vڒOaCYl)/džG~o$?nOíNרd M:Y-\|͟?Wo@ KkЩ#}4>6.Oㆍh ┲c@t[5Wa6v}+VFz~䑴lb/'r٦[lAc$ofQo$Fd?( ?ڹh˭iҺ)]l|fVZ <?+Jcv:{:lrI>m|:] j!{|/V'viM͟26m6mz9N9(*@wBvJ_ Uˇ5,n4~_&O?Ր??s_z1c/8`7l]]WQwԘTuh66>ᵅ?]4n Ѡ7]!ʰ7قŚW^yvk=\'(ٽ͝;8i iH ٲٖtigȦ^zn˧O'I4Z7O?x^)c1|b!/' _ӿEcͿfXfeXP a Dii ޠ(.v_x6ֽ3 YlIgp1IҲqZYlIgpҒBlut-P qV Ҳq\rIK Ҳq喤0/Ίᄓ Ҳq喤0/Ίᄓ Ҳq喤0/Ίᄓ Ҳq喤0/Ίᄓ Ҳq喤0/Ίᄓ Ҳq喤0/Ίᄓ ҲqxQJ`6 =>(d 旚qԫ*+ 8@b$5]morIMe_oo^Z0z4e O֍Zrhnѣ4SNFvoS*a ) /ONhiaTn]$-PG3OӍ7umn,;bSElp|>*^H9/|QlH yx>kL D.;$wyL!wu6|sd$A1,p=ᔢ+A#+V,> /1ǀ^|[%ؐVRZx+$SNQYӽ+CCR1a / V|9aI*mD̼7'2Oe?aCNRvً:c>&Y>?Lǎ ,`ӻ_~hp%,nS%?D%!0ۂI?)`Wй\3A6[Y0OXG?ރ? s, YUY??*Ǟ`??~hep© 7;+a aK?icq^ժ4wN|ꍍONS} iwZj|'2u~)eG[n3G8TgOHI]:Eοv$ӪA8;v IUb4&AE?s6 nt1 3[6> Z5ŵms +|ߠaCڶy Zo2/)CӐBTxA7\Oņ\wϤjTˑ^A>:P)t^'Ҫ>駞oviI;R$At-614_y58 NДaPD/;I}I=4x ڴ]vTc˹sfh1=jIuAB_>0 96|^IjCtdo߀+/>/q_߫D&?ӵ}K 33<:؈6tY)9dz4ђwoE4 'O/8x9(霾}qb|䗯[+uփ6hcW7Zs4h;S}Í&_?>mԪ%RǎrƟ>S^}h[P {GcXoxT vy+?`σ>7b^r9m馨2do. )RΫDqJ骫O[Nj''Ys{|?zƉO.CSndsMg=fEQ'!՗&8IUDƧ~YyO]pݷeec3Ml|m%Ꟶ,Uf#yJ wӿks7:?* 4fxl| =dn^w{N)8jZ[t > f4Tyu&<@_Ck(kWɜٳJ;oA7˦O^Ύ5Su yu~\'Wj>3I_BmU*ؠxBh%ou<lm5hЀ}g\\!SmE3SosZhl*>#9G -xlߢԨI#4+gl)-_ΤO>mb{QO}"lg k*V۵؎֫<ЬYseRUG9d!d+ާECkF &/Ƙ9qkXFټ6n҄cCh_2~aa|+>U9d^u=k}/51VtsT艍OبZhA[m57u*F+Vֵk=j;p|kFimiURR2'c?PF18j5=i瞥sn+ywd56:խ*K'>%amwкZ_ӿIJ1k?~?0?Mhme/[3Qǯ6>_s1'PPJ(fk5TX./@1*8iPbjl]_C c ٚvq| U(K&P-pJ(fk5TX./@1*8iPbjl]_C c ٚvq| U(K&P-pJ(fk5TX./@1*8iPbjl]_C c ٚvq| U(K&P-pJ(fk5TX./@1*8iPbjl]_C c ٚvq| U(K&P-pJ(fk5TX./@1*8iPbjl]_C c ٚvq| U(K&P-pJ(fk5TX./@1*8iPbjl]_C c fwBy kY!wV)~)/7B_-my ?%2d&_sϥ-[ʨ[oɘW*S*UVYCOGaGPupB:QN*`[^ꠃeر=-Y0$ L~R,oq뭴&5tB ^qidgggg?c8Wsy5߫ammo;=aW?!e4?kG?#[vuiŊPA_.>]2y`FT>/g;6U;F_ҁ5*3?9^}8EòT^ 2qӱp ұQ_0C!k\fO΍sL=l۝K1߽1 vvyVpF1]=r8!ApY70R`e?mlk.KZB?V^ 2'J5a}⮼|SJ9E8&-\L'b~֣7@RWV:Ta:qԬY3*? Q/L6g?V?L9׿M7ok6g6EiOC{Mħe8/pX^@wSq^SuDJaeB̒:?aEď 7 %ΰg X$1 0+MA3L]9۬Ŏs"|='%q\R#s"a(?_HMW,[E3X6>ՃQeϱG w/ZD:v}5[?zV³(pE@8!O!o e?#? 6$"aٟfCVQW𫭤ˮߛg'@l?56Vb) /~H?`G?ゃ?miO[֟l+#_JJJJ r6܏<3%IUFKB;!4QpQ.WZ?j!tᚴn9ХAO i8_]I\(~!K/4V%+Ŏ2tir0s|0KD!CIJ@ ]LL9QHcP<P(C@+?LJuA5Ix'OOIv:% 7?Zs͸Je*CAnSL!^,}ʇ KɟٖͨfAhX^)VW^,x3xP_.-\::0ڵ+r衘iTwb͛3j2;˃YF fe߶pjM[߰WWK6g c:1/?[ ̮eY[ȜD˖?/2OCN|'*R1M / Piq:VA%'h|F޴f8ED }arv:ҋJ_Tf8){OaOXeyӚtdQ֚aw5ljO{J8IMݡ:\Z&t" c7a x1!Ɵӿ6k_f:ց`C!Iqږ< a_`TF2o6s İ2駎If `_ij[.Ӝ< L`aln6`}BIw5fP<έe 'e eKINqasrHcg'e 3,%9Qo6jƅ8AǖD)h+=Q?2Z#袑R'A,-l|5.W{>c,ܯxĎ' '.4+G2cE?udHlͿfel?mm/3Ӆb'DS*)1׬/ӶmѵEKJՏpq1ဒ@R4O K~T $#" AE1Γ%%0ncc^D/B$?* `oĉ,BHki]FIhXVi ~Ԗbv'Lds9`O#ogϫV!+L8^_?Բj/Y%bϺ?Ĵ`O[&󄭿mmo6y0s1_Vlᇅ`?_?hG?1'f7GicъK+ j 1)qcV,,y1)1F/1)$5ƈƟ??n<!L&U1F +k|t7n;p/ |d1WlR\+HE*v>3سqIɟ??NeUiͿ?Z̵8Om17leO[GGn2hG5_Zl*j^g?+'o?4f ub+o&PY!+, P yS D812WsU6o70JW)gOQbO(V)1G?|%);1Z2^ot%H0/P # nǨhdIžx/|e5<~|?b䁇 L3~ȸ?agͿ`?֟ 0~  HO0FY_Mr?Ƀ!sBS/B6'`E)@.S* J"%JҖ Y o7s#Ɵӿ~, rcz?`ͿfvC1*$Nf-vȵ`LsE Mq^/dż@} _Xqp?FogO G84ӿ<$0O6lf[/2edW?]~}Ia8%A;unw_jW8 ^﬐᝾{:&uAVӑИaE?6blaٟ2km[_`qr '?Af?<\pFe3[P6h ~859+?L8k#ƃd˪ ,bIgˀ'K3]!}s` d}ǔp5EEƟ3)l {;%NSlvsPUq]p>g73*'/6k_fBm^Ge/leO[/X+^dWNt#83|1_bF7I&O2 d'^Ge/d'?OX+^dWNt#83|1~StN?t\ِJ䶐S S9 a6'U%b xr1"s(0HU%T"ZN^.f{ryIUI%&9 ӿ* ;.U Sťxҽ"%ڊ-SOcSgJp #$o7ӑfOt J<*b 1'ãXGP1#ִ6Zo|G%p,’yQV9739ͦs_qeREw7cE[~73cW,El5/?J֟6_Ǒ_d7Iv5r0#rG&jcoZ V&[J' m߶_'8 5N2VJ5 Fhx * sɟɟHJP<{NʁR9OAd$%(= d'@``' 2DrT}NpTuWy1v;rE ^Ō'&g:T:A`;{w~"Vb4YήgDzG,f&/_vWy?dI&$YH%qCnYXqB#1sag?a3t5S gJap_bY]|p㭷{r":xO<=wojټEya;O;e=aƎ4O 59Ql?l`4;_gbɎ5i?O8?#Ax)b?d(iʴJWKd*#}ɟ3c7}Ȗ/+kGVOdՌo|bpk|2˄A~\#RaJ)ljp~F瀯˕ 6Wv1w.gCeQv̈́{/8S_$`qa@6KŊtMPn)'w}G#/T7oтN>dQfefIKa` xLȚF1I_!ɸ ,6Ma>q-q&R 0<~o}ݛc}Z ]6nڔҶG<0j3X733gΤkw\M: xmpU%CfüV;;;y!K#M'̱و5^lz_֡`g{?b8q]RYF. 6ɐ4',Qrc)f鏷wӳ`hzQ@j(4320>OaDd,nT& mݑQ4dIF&c6oh*z') eïإV T MvpԌ0}ݏUIvL9p6uVZROi r# ^ EBײ}-}' NTgG=퉱ϡŋӺ뤝;ի߀ʃ+/~1//7x#5m֜6s8*VHuե­4{r99{B rhŴ~ݺiӦ/ZB׮c1i^ ZS֪Y5Z*ݸqu, ;PǎL+ Jwb@{6mSH, ֣]d% ?W,3˿ѡ=߭6d N:æ"x"3(ZC93?bIg?Go܄ p|HWɓDeM>͛+6k { n)bοz-zp(:aFԡCw|OfUE'<̟uWa2?G~G8 8͚5+pօ_2x ;" hvbg:%ǂ?lM/ο"0k?C#+9/Yml0cGT_Kծ_ӿnfDD?N(J?PDLba@zDB @M&E1MP}24[Ô(&&j>taJv rPqIQL5Td 0%;ɤ(*]fkETdRD ه.C5LɎAn*n2)iCdG 774QCEl ShLb"eh)Q4 @M&E1MP}24[Ô(&&j>taJv rPqIQL5Td 0%;ɤ(*]fkETdRD ه.C5LɎAn*n2)iCdG 774QCEl ShLb"eh)Q4 @M&E1MP}24[Ô(&&j>taJv rPqIQL5Td 0%;ɤ(*]fkETdRD ه.C5LɎAn*n2)iCdG 774QCEߖ)$Tk_. .c;Y%qtX\ \!l&cu_}V^CkCjvCM;  MSMXa~*]@\sӿeJg)mڸ:w U"^ΝD_u啴0^Tӯԫ99u*t .\`O: &}}i/!>ueԦQTT)Lqv}x;gϚA} T?fc?Rug;'O؏@;ff$o)fkٿ7EgfP_3 3GeǡjMԔ8!4KJvԔ8!4L'89)qC hKJvԔ8!4L'89)qC hKJvԔ8!4L'89)qC hKJvԔ8!4L'89)qC hKJvԔ8!4L'89)qC hKJvԔ8!4L'89)qC hKJvԔ8!4L'89)qC hKJvԔ8!4L'89)qC hKJvԔ8!4L'89)qC hKJvԔ8!4L'89)qC hKJvԔ8!4L'89)qC hKJv09dG81x5Hgk+r #nꕲ~O=-_]V6m@j֦uPeeyf$uCw., Ђh*x٦Z^{OeOОi;MOi8[oV{ftu4wp/:>gz]r!-㓛|Jv眐%94 r7O)^B]U{?][/p vf7e .S8F_+?89A9nuƍO?Gڶ sz{V1>mgԃ吡pē&%";X57?G6@kc돭?7>-Y.yv?8sNݺgU?<9i*}?7p}:O*X_73fL zѢE]xN(9rJ:m D<޸t4{L~)px\~A?뿍?<(?6l'˩/1cx?W!d_gv#/a(ObIKyT q A ]A5W\|,41Ȃɟ :ty1 ]j4M6 6T4jd,_+f5y9>Ӌg\.D ~3}@IDATh vFKTC<(hǩ.?pڏ' T6oڒwUu7믽L?I`C?jCHΚEF4{ɧ!O?ϯp>6 /men[D[$8>)[̜_/(UTyS,E{]uuv&n|:]⋜SrE:v_n7o_㓴|v|A^d $F~An8&'hAC>mSW8> s6x0n|º%py1tt?Ѡ;#z;1 ;k/oh1q_[l_&LqtY^@+vKAܜRnZ:[{ľ4>Cnxy{SJo?4~:#ˮ=8[IS͂S?8>I)[׎>0|(hEbg:DJFJ;M?겿J`f:EAD:CGOI_?̾6k돈~vm3ަMu ?єf+JBtD&zL ֘~?u<ըQʗ+C֬eK_z>ϿkC=L(~-٧F pS.9Zx\0j&o txx􃂗:sK|Ժ5)dΙ-/LMFĥE:v}هV&0Vᆢ9?P9P˽Z|!ntaYpMr*7~rTbOqnVa9Xk2vuW7 hƌo)ߒr!aCEGd5nt5Sh굸m)K%7kތ;x?t"Bނqk { m0cyT?Rƍzo7i׷E}p rOIHf1C5>p ^۸q#Z}N'z25k֒j׮E+~Zf-`+Vm~͚70#7wqWVi5c:=C7'֟XZR9C9p-ߘ7ct<^zI޷J麇[.3:vX>3ZprʩԪUkioSӦwc<'juE~2o աU~yΉH^0$rb*] ="$$3SjQ'$Dx !JWC>! $}I 1TzTE I #H"g)У*OHl@9CL1U|BHdbt5@"G$rb*] ="$$3SjQ'$Dx !JWC>! $}I 1TzTE I #H"g)У*OHl@9CL1U|BHdbt5@"G$rb*] ="$$3SjQ'$Dx !JWCFrz!?~G3"a7,Ӄ#?*Ii$-Z.cumfZUvۥ翜Be˗?SuV?hjظ7*X҈JoZB*/O7| 5_xӮ#n4ps? ji_M7(zu[&+F i]eP:{0Ec>B?oKNW.:tGqqP\L)7e!">ʅL~O)!84o9qN@)GYC_Oↅ2T47lu>t(kܪ򐽛!{Mp:ܜ̠nls1A#m&}|e*}No(O e˔-E{C9XwsJa nv|,mu#dAt}`#M5Ր`Q+iy1}T,⇃6Gz]vⶺ(Yoٺ ,ΆG\Ǵ)tFi _x8]1qFϾNs ^Qq=P]4T˟⿥.)}Z;>WFu٥ṯ Ç믾'c"#u_z% ׍u3W=_h}Øk6X%XcWW [X&bkDl9\ANFgn|XnP^zd7b(9aQ>shʕ%߼e %;7PMZM7~ܹcgڼe5j+HC;9?Jyǧ>ZeOC?l_[U"p)-]d`n\)cHͿ1c9`/;cyl°e?*wX(Eij#yu 9Rae-f&YfOx. ²iLI5EEa c褈NBFy4ӿ?K6o/踝:8eKrKTY׷3#_DFnƭ3 ϧESթq&T;v Svw.b:>t0 G P*UGڴU9x1oA/GI Q]яmXu̮/"85cQ*S|@}W6t^4~`,^:65i/I/ߵ[7:m;HZٳgMi- `{޾ALƭqFҪ!N ͿG!sq<(P\7)?uux̜=X׭SG1]x1]~iy꿳q{) x3Ox#b)⨴E(}͸̠[nKU~kntGGH)A3fR~g'r^~oX`ffi?la_y^^Gf{Ƹ$lEB줵DJdD<z@pØ7*q(-5=!ă00k_ bHSEf=`woVTPNy7 uD"4x?ċu Qv.WeҮ[xSiB#M7oZH+pPJBr!7^{VI~Qf8UHSqcKIQ;w)看!GJ;PNr|bq"Gtםw}tԯߵ h>AV͛/Wa.AOѵF@Lrض?U*йC6NES +OJO'Wo {s%=OėF=/3Q<ÆOuE; 蜳Ϧո*1c] ;©K&n܄Lʟ?N@xjFN_*ԯ&E/Xkm1&~+TgiOITaB'.v!6GSq*#c!4B.UXӉtхQN)D~-o :?gzk+KYԗ^ ;nb>(7eo]vpFܾ=>9yG tqDv| Msco&;z4nb\-;'LgdCӆ NL%v|:>C׿9/C~}Z}K~ڵlq [70C\DF~,{S:s+Ӟ ~2=;G"RT<ƥD~zޥqŽz|zGsٔ GZр;o'sQ/W=B o1;} p `lokg_;0ƧoƧK"dG?yJY|Doء=`oS3,U_'5R,+wy>77{ptOG/L` 7\?Ni&;>#tx-Eb܏?c돮?RЛ`m<5_[cfi?D)?9uɽT[Lbۅ)3i&cauFo綫6D3xePaΖh+4ͱg_0CЁ~_,^||hѲ"tRTWc/q7y-ڲeKo|*]͝=\SF@3k /Bm%S|yuk(])Q@=/׷|O?CO_|kq18+Er#O 8^ 4z$T?'(@/ =ԓxbx`uO &Ax(O,gϲ7N=)|dadTVH ٹyif"^ZAr {x%R䃐5d/s&鮌4eW ^/uQjŊs?TZ ƍOᐹO]Ƨ:Ƨ CmL2q<8tU#jN|w!Qm8/n7|)vfw:3o޻ ^~n-f{Zbe.>εQ[*JN+rOtg$5npXuW^KM߿tA7͝3O>| _Rt3Cw)9 3esG???T'ɟ??m1θ0 O|ӷtY/gnvD& O>oO]cb''LoG},nw:]dj3O?ldT4n|97lO۾ǿ 뿝bO]Klg)p&)l韢ӿ[l5?Xd`ߐޯ~r¶?~ǧH3 a$ N"VB-@ Ȧ<0 aP9Ml*0 EDS"İ꬈GB8_au7>A7љP|8 j, C=MÒ82\8jjtG _}~ZR?ޗ4Wwxm8!p8P lLy;֭ǧah;ඕ50#)A~sΙg UV2rvzc= DZ EzZ埝ʖ)#_HB!mgosQteovR -G+I8= D'΍Wyiz|Tlr&Om۶b!"Z2)ivh!/G<ʥ6/ɧu9nj÷A )͐ťУm\O4C[ OO|FiP^ u/iB'\~exBIW^{=xЁB^'8dTqY܍O>,"mN]‹wprvq{CѕŸ@z-tb {kzPPRbgvYA(!ggy@0#M*_YT*FrLm_^y mοBE8>M V2Q۹C&Z|x_><'bn#n-A?(q5ܨ 7s i떭$/tˆpf{|,pۿy|SR4k,8>O49%9f#117O?e]nͶ>Y6O?faP9_?_8>&ulF>Lɚh. }Ԍ71'Bn dNMָ __bj 'd0E(KP-pNMָ __bj 'd0E(KP-pNMָ __bj 'd0E(KP-pNMָ __bj 'd0E(KP-pNMָ __bj 'd0E(KP-pNMָ __bj 'd0E(KP-pNMָ __bj 'd0E(KP-pNMָ __bj 'd0E(KP-pNMָ __bj 'd0E(KP-pNMָ __bj 'd0E(KP-p57U>wH̘5JMi~^\*>wI>?5j6/}MSO\8K-/< .*68>Q=J/>͝ã$erSMVᅟ԰aȧ|^&6UŋLO&{AqSSF\b惰|x kșOGqYs|GrHYr0q!UZ x_n5k6;=q3*Z+n]:&PU Om+O)_retܱ oOŋ k mn䣏!o'TsϥwbUEŋ_6oZ/Uo@C`O׳OiذRs>j=Y )?p̀ G|1O> $b/]dOk[.xGf:,ďX!\͞3mcEЯY&9Jjӏ|&ɍOiӆMp|OQ9YӮCЩ7|$ĨFZB_?)O? X>1ƧR&vs¿mHҖCKNJIPK2\+KӞ=_OS>}! +pil=#֛㏣=/|"6y ;mg.Ɵ+$WldPrf; IzR7g?c돭fvƧ7_֫[&a??Khͪ蜳kWI!ɞ S8ݛ/'fc|ā?~{9z͛m)FKf^bp=M왳__tKKVO?4?Owؒ,fQ5O&e?`_=i+^+_zp` Q.U–ITԛ?_5N ^:0 `fNBװl !L_?ojEeS vv`Aad ;FvrȀZ!GpBF}f_SO?+ᦓeKN>MXƛp^[xx̟Gv:׃ ď:d]wݕ믾o0q/o/' 21sǎ%ݓ"߮R,͛=Ϣ_bE:餿7nθvH $}QW'2oFÆhup`9>e7:/`31Ñ.CK2kY﨣N8-5P#Bd?㦢ɸ}i[ HH tTC.h/rõMU P: ׸ILW P966]sU>A9] -w0k@.]:n䏙վcة sz_y͟7?movڻukfuǗ׭]2Y֟Ӡ\[;[m4n_wn|:Xk{O]蠡4qRiyM>I9(%ԫr;[[֪>RSvaG9UNAaVuܙ6bJ[L򗛃~r!YC_jsK;e-?g*KJpkdYOZ*>ߊC,Gr" Spǟ-Uڑv_Wi0\,^ѣϤy<>[^>*}R͔!Ma*ho-OQ19+}!Y-}bPssVܶT*{ Pl-1]+J?'FoYߒz"&&s!?U1#b 69;>7{̱N@&[C7z O > n+Gфqh??[Zz=ۦ7nLG9JILƧ4{L,OHG]LCXȳ<Gf}[K6zc>bCa?xL[lmovjvobF61&`$FyD8ezPχNBFYLD6+l|C | L֟iδ6oL"]22OX 6&D9W9@eĞ`\#X|E&<+ xYO vzzEv|"*W,S?\A[6eサ.n1vp)zr7IO//%wt!nQrRd񿑿v_۟3=O<y>#^d ڷwߨm8p$uYvj̿.]p|w^Zipע^tw 7^7! ;>+:)Xv)~hSO>AǏ.?u֡OB)Oo2~.q+U"C֭tױ};׆ ? _.S4do]}/W(_6y['vE{=4;C:J",:p| $_(v %=.A'$wN ϴt[N?]x O˾[͢dZ$ա!GH!J@DXL̛@ӦNu v'׿|ȷgu픶=Z;;Ltj׎Y'L{. 1GƣnRӿB>gqd7nxԢ矋VHuaSO4ʔ+/i?c 7]㟉>;ut?JZ6GQ2&7aDzc]f*<r*x p*z2L|n$3&%8I8rMLF>@1,0]{ph.>Hq5ndO.gΚɭLT18 _QڶDc/e_Zw_[eGltgٟfk ?Kgq—J'+j[r#/i'HPE:O! fס=?H-oc>)Tr|{@]1;>rʡ8t9a=A.ο9>rʡ8t9a=A.ο9>rʡ8t9a=A.ο9>RV }Ni8x}up|?3*WD+WD{ ^Ure/:Sk}owN/鉖?|+Yǿn89d:[Z rclE2ؘu}쬖*L|G@##Ni~L>C0t-]1^zϿ,c˔--7GDž%Aʻ¡h ulpmgUڕVs)b.lRƟo] fMJ.880οLk֮hF)7?~U c"cʳfpO H:u  .יM? 42 ~틸T Nw=,p4Yړ_Vm(G)SDWCR=A_Cݛ7nn+U>7)Lr]s/5m'3Ux7u@?gfEH?RϜV}ɟLKZlILf[g<*R8>dǧvđt5׈;<|m&?sLl"o>xΪ?5_WxeW_?4_la/'?T>dp0?yMXzNǧnUx|MM(LVo7ɠ3'~9#A'I"Ea2XȇLTH0Mvn/fGGfi4o>`O<5q ]䍑g _7hHۙ/?è^b^p!nY@kDpRiԬYsjШ{ߴ;w s?KUT!\z֛7Ӹq3w}7/n:|K. G[oC#53Oz7=}ӧifxa+~tg,'\yܔ7c+J x8iwM26l(_x9z'qɏJ>!,cq+9s1>TbE:ө]_ 4w}1 K.[N@5jDO0׬^M D_ákMSpR-VQk8|(yU8ϣGw{V^qa$:r'Ƅv(d^eo}鶛o/9 99kԝCw)O r ?Ϙ9<\BV/ '~nǧF<<\|#mtopE|$;Z̙oSGW%GO1hMo> ǡT2#GW^z)#뮿?4tg-V78|!28t#ɰ;gi3џ(7egۅJ~T&^B_',H@IDAT'qxOL& ;1 .8 'Ms/urR$TNhƘp2#v6,' ߸N6U) _)tE=wuk ʔƘDwcOXi:~x<:D7>1]8?Пg2eA3ofR cb2==<AHhC8?xj֬M# )VWw4mØkgAOe)D p|ӂ/ vd OAi#nӝ+%,D8?.Ԇ,_yPQhEUt_$CaD<Վb6| 1$4&LpOߎbިqcCћoˆ<?+T}T>L"՗_bZ+WzAJ7g|nmڼ ]~Ur[~m!}Ji힁$?H.M矟V~ ><lk"Ls֟T[_ qay ̎hyxߩ[xuGz4# $ !Q ɋkݓDQ!REF2"o!^i/_-(`\HCo4d2L_F S}nY{{jirSlڴʕ/-NALAta2|;; D#K8?Qёrb2E sCɧ n|S ݎۅt  UnWOZ&[QQw_¹O'$t7d` Ov2iB~4R-r_y"|l앂趛q#8ݡmf0F^l9T8޻ o? W?ġ{}wD??vбKb7c!NMD{ɍtR5Pe +; "\ƪdH)z[jUvT|EW[!Cʥh"?'v ,_omO<}? <7 { i\cv)pp%X=y Ko ]Pķ}56nҘ{ 5B_җ(~Epۋ ;9!|8>-n|8}N? /MZĺ?5>&dE=p; 1ۗF!I<7!;;y||OӦ́L l?>;!S7M08qԵf8E)^>IF h(Gq(B/>߾yU0!hHCH]6n|b'$ܾ$H8]N7'n+É+M^|!h~9(kn*pF O:94jQ&O#(t.}89:'_}K7]˹%G;̸GN 5]YL?ʧl?-Nigi#fg*В%c_i]ƈ g]|`e0>~"߆ ;nL]gSN9Ghf܌}9gӺu،FOޕY3gP߾}Ie__ZioDx?U{L-Llb:`j'ሞ=WYzι#Lp*xV+=V`!\wX&BduVHkg_$u=nzFzG g?Owo.ny-t/KߍSR>+q8ٹ57+@\`%D) R˖.2 *1̕qߥ.ժ#?EROhy~L]g9ҽ+PN +g֡pxqL (O$-o ?X.9q^>Q-[_ѣ4?@pԽ{wװrz_c7ώ {%jqu :[7aCˁӯYv]*8 ": lR2d0͚53~"u5WqQ[Q7$O 8]v|"UXɍ;١p/r;MNO:7~"_ӷ9.qR*u;Ӟn四ʒ̝_[oNAAAwz 'Ie;0H28'*lpF|7! Hdd1c[0ˉ/ [[OfGEY98i'P`("e?y/up1`6ccT\np@pu駟~u9 ˲,nSnTreڄd~ZkV_yԺrCwb͝WլY6kJԆ#7grf&8&M!\/4w;oNWZ5cEte6F͚zj*3s&-Cd&1$A.Z7n0 9DK-gee5O}B͛ NdMq ɻzj3g6A_@V>ho8[~2>kܐķ`~N@S{j%-mwf͢5Vϯ?SxB˯>od7jsD.}Zz5YB=Ke={iȪ'bg/T ?"flIpv϶q5}5g?Ϻ'+Yۆx^5> -Fia:u$?Čb8U.p?ο( ;~oQ:R4mCX-fle/`mvLD7 ĴdR {!KàdR }@KàdR }@KàdR }@KàdR }@KàdR }@KàdR }@KàdR }@KàdR }@KàdR }@KàdR }@KàdR }@KàdR }@KàdR }@KàdR }@KàdR }@KàdR }@KàdR }@KàdR }@KàdR }@KàdR }@KàdR }@KàdR }@KàdR =+آˣSs դYᰛ?J/DA׮xj]8$S a'"*_~,[O?sQ,YOqPTbU"?ak^$IXBA,o*nӷn&TD#Y-!+<()4jK/J?q4_?li733S,^ln /f0.S]vI̿7z]nUYy9jC/p|oB=77T痪SΟkFP[kڴ9 cmظvrfsEj(iyb믮" I_#mb?]J4-l5CD"vˉ5Ex?_f3}5ӝH[Fj_kOlWcO\@`vI;;o!g-yMB`8!@i 4b@ όNK4#Af 1K' u6!F+?6L8}YC5UN4$= 1BX1OVqv/QǕ@"_͏+.Q%jTW1~YЕI5g,3&6B3l8D͎OYOd;F:+R.IYϔiS!%n|JL톶<~53iFc_M]%^X,dYN0O?c4mf%iЊ?63_1l}?/ `_p7 %i{@CjqZ$p~|il Y%ʑc!'Lg0O _7 癟%|IЂ?+gOO43$wZޣ J 5jb=cXb1 XJUzĮ&DMRmHW@7;{{}{@PQw{}`Iq>I'^D#\\1,_dè|$#}++:'E ~f׬y3NΤlpKi}zzWbƿIRݷޥ}*Z!Hl|Uj -[ƍK/NUam3MMM˖afg11;O'zs9w+JFB|rQ %WQrT"J/8~O 8??o9Q %@?*G6c3VFSA !" f=΢;HcV"AnT`wJ++ɼl?Yܝᨳ f\6k_b+||m߶['[G[gk)&o=d8}''j믶L[g[g[g[w~q~x›zjf7#dT>Wh F?P$;)#/|+ }F5GWo??ӿU#9" v%Q ^{fggҪ8bcRJ-ZawJ  [g#㥁"> 5󹊜Kga&,1朩0Omaao[+z?/9f[W' eW[W[B_e⧔%_09xL7A  6`4~mo` sF7u߼`L7`/,* -'[߿#֜lM\{mmm^\~})0z\ N1???b1 f㏍e'l6yFt_6? l(]N?y6q֟d????rze/^"Hn 9ٜ;әà\fSRER,`I +gDCA®2o)"rr33slJH*4a'e&(ژc.lЕҩT$xNٟhc:K'沸I.E~69,AK|RDq1RRML`1GR6!8Sp8H":q?0/7b7 sF.0le/ _6M6Ϳm-LBho7JSco3 {Y[I k\NSll0V??1[ch}IIi1D z\T8W1X\cNO].IZn٘zx 8Q.\ 3B2?4?)0*V%2c7%N]ZB85Yo !||"{$)e<.V5??oupwgcIA _.O23I_ȍ?>6Ve_a\oC!?LdO?y N6D2$%8doo?igbMFg(dKj`8SZ @h11/VLaUl5)@֟2F⦓|L5T 0Qn*n:4QCEl 3>F⦓|L5T 0Qn*n:4QCEl 3>F⦓|L5T 0Qn*n:4QCEl 3>F⦓|L5T 0Qn*n:4QCEl 3>F⦓|L5T 0Qn*n:4QCEl 3>F⦓|L5T 0Qn*n:4QCEl 3>F⦓|L5T 0Qn*n:4QCEl 3>F⦓|L5T 0Qn*n:4QCEl 3>F⦓|L5T 0Qn*n:4QCEl 3>F⦓|L5T 0Qn*n:4QCEl 3>F⦓|L5T 0Qn*n:4QCE8)lx2a:MK:;PPUU\ur&cuf733c/CsOma/7w'Ϭ?@lE֫<%7[7[Wl.~~I<}[G[G[ ^xt^?'mڊ!` $_'D%)Y }U$~Kq??fU_le.>H?23 c8rwAV $o6ͿleOw1do ?CbB}X!|w#@n ['JllXK6>*:3JRbZIy+@E!_FY0 JDc= bqȗd/音 j)ұtK!WK¢edOP?n$VCJeW14ӥb`[@\.}]Ale&f`e(OlqH!T9v1Om! J ٛȽo"LH̆60!1N_Ϯ&6Ϳm!H[7[7G[c&$Æl`O/g~OѬWq[FT 3^́е{ǵT a}٘y9;j2h|b,,_\fůaqd;PH.庙7i``쯍?6}0/?et*S ɳ<>*PD_xe/doh믶j믶jp1g[g[%~{EVYeYnWy| _XVlE%%:.?EfYSi'eJ "4SjP!$Tv 'JWÀ!! C$i<1TTE i "H#)0*BHH @9OL1UBBHeHybt5 @*;DFSLa@UR!4rb*] "4SjP!$Tv 'JWÀ!! C$i<1TTE i "H#)0*BHH @9OL1UBBHeHybt5 @*;DFSLa@UR!4rb*] "4SjP!$Tv 'JWÀ!! C$i<1TTE i "H#)0*BHH @9OL1UBBHeHybt5 @*;DFSL!OE\]O7)8tm2oU I]&s|1>1ù%ɉ, ɟs%V3I% S.@1ShKZ/[4f7hI[p*)2p8Klub^dCo@/AN͝{N?LPJZz5xWRˮ1m!f͚t~:e2M?A{R6j=hW_ѠA'rl7w G bMͿm2I|?.qi`+/v2cWe 1Xk}bC6o67߷_?|_pv3Wwᯕ-.f%ػXR7g}Ld%pùuܲqRYl)'pRB.lU&%р'p@-' q,(8)B\n8l6e4]$'p@-'  "-% (qR ܲqXaH@I4J!.llV%"P 'p@-' `ע"ya~f+Dszwں( Ft^ijSSQ0{pzݷhͪ՞ÎL՜EԤys\0W~f͘Ns ݥ%1NhҬ?.?͛Byѷ_CP[Zs_W^7|ܯ7v =?Y;p`jYWa~}WgwmGWs?>=Jaf8l)o1zx9WIz铏>ެϽ[s=j E0R&lkשC}5lX2_5rY kJtmk[gE47>]z)j r,_"ev_&R}q3a`#1(cf_'[?Fo[RK-mRpm#Ȉ?~T/$>E$܋B;(-UP:#i`:Wf&`b٘LD'˙1cOd!`.h+413TOrU"O4qN$X9p~^#?x4W%֣\?6Å_^xYZ+#5j9ht0#^z4hS -W&LD+U?E^|"u7i: f͚zտNtN< x%si"?RY2nzt۠;\4u9`+/Aɕiڴ ܿ?RDƎx-ٲ?rz huԾmП7iBk֬:q>?m%ն 2l_2_if@s%[0_JcMƧ4BrȡTBEmituӊQ_bDze)TbE=kl?1o rͿulq!C!ؿKudgs`믶j깍6g.gVh+'/֛[E,1cALe"“J!Fd3I1* J1ɟa2Q4pܫ")@_םWER& j"t#qI6N ׃*~q'$_]`>kPN;եʕ* ֮[CO<\o5=[#l]nhW_v8d/|&ҿ^%En4Xddak'&MFT Jҥ\u .5{!.ٓ>#aWbϓyI)u;Zxmnc9o|800<6mJ7߂`܉Od T'>Ƨvmۢߟ7Vjܸla/$N46p,ŀ<_ϋhc0-Uq1kmg h`Ö4'>U ң$ʝZja#m|}<TJ%o~Oa w)oE Jݸ+EBN6Y.riF߹Dbi8-2!;qPbjl]C c .wa|E(KK&P-pH&k܅=X.-@1"!;qPbjl]C c .wa|E(KK&P-pH&k܅=X.-@1"!;qPbjl]C c .wa|E(KK&P-pH&k܅=X.-@1"!;qPbjl]C c .wa|E(KK&P-pH&k܅=X.-@1%@IDAT"!;qPbjl]C c .ZffL5wɘzťiÕJP׵T65+]g/*Vփ?cF<}BG\P왧oF~շ#ԸhB+/qڲ^ʉOEtI~ ?gZj0i"U\>6>ty۾Uk[2b$䦘͛KX=ǜx 6>b"eڟAx>Ƨ8n͏4Ƨ['\Sy7>uOiMo@[aN|ߧAXoggd@ԂUc mͯZ~%ߝkߦħhy8t/v=G]tV׳R8`ҿ_|𡈕y >2.0*9QqqouQ"VJO<5~yAԣxBO۞SqS16l}O +kҒdϺS]07|f(ni[o?%7b?m}1wc㏍?6'-]*kn&3=ݣk|i׾^;V\A1=cdH;pu݄Fr'shLȁ?܇?`Dyptd|}6ޥϔ;_~I 7*+ӜB~^.Yow (Ҹ1cO>>7kN_~%4e$Zj<(szԠa#njrJz睷ǟenq㏣fhC}ħ-| O݆kħjEWB4Rb+W&Xjٲ%N }5N$ǟ[m>=]^c;蠃i뭷[3x>pEIG4Op^>{;&2VlMoCoΝK{,l9jЃ…cMei(^\,$Agwi'&LjlnqoR_C_>`Ā_?'3'>m98 6wރ8(6#ᤧ#I99#ӽ# k׳ey64rXF^.I/29)k-os*,}ƈlħ2gfz63s_m cO69fjof돶*6?I#SM[a&l)St Lt4QIOp14OTDB~N7W#.".#N0%{70 +"~e86. >fm_? iEcـo^PBѩ Q!M;)ѸayQ'%]AߵԼ6 h.6-0ު?H͟knY}W,}Kz+5jς#_UZj𥥗4'*y&p C9ϛ\,3;uƩI'4x1Ed8Ηl|]Kwq~)e;}C>cJ_mmh1ҥrg'H?~TG̶pۜt|4h@WF6GhRo@OloUR{):a7Hb?rРٟoH/R)?=+ϰ?+_J;~" nxժ2lJ:@No|6>a%o|RR:p΂е\C5uݩ Yn KN _,+_}E]qLϿ?0ԩ} #{pyƿ)8 vBQ3n:z>T{Б!?/|(|9ۿp<HW͌_"Rh3MUK)13c?fq11v8Zm+l|prbڴ@noF7pe?/펏5rpz1Gv瓼54kl0V{N}Jd\v 2vء6=ܳt藷'>Uœl>@[6>1kO? pW:ahcP<m?HÊJJJ'coHww8>#ƒUh0{RP(A@;_Z'|RHCǩr@]|L9QHCP8?P(A@;_&&(r( ]N(v /?DNP9.'p;JΗɟ_)hZHHD`i%U,S<$3n1Ry }YHr r=c|q|qXk_ _wڙ?Wx9C'up[ѿt|KFD:}ϸ[!7b0R7dP~d#4m4ZfvoJ6i0S{=70Id^}dz0j㔗AT+/w_: DZ&Ͻjj)[zx̕p*Ӏ?lF\h6b}:3?o.7m/\U1G?BQCUs.J' axA_];6[ :'њoWE587Wc4lTp,iDf̤8Y%N*O#G ◳CG@l/iX85ggpB tzSd?;|z=5nE8mg)-^ ?xJG='|U/>_Lg}%nc&?])0 oG/40>lmWk;oqL]V،Ȧo NTH3BjQ5؜sB_oʕi 0B -}lWJԫGv+'uT 't36Yt>kNbmזTqlz-B?nvknIҰ ɧ/ʼnNu;ҷgoƧ'\Ulw;B7|{^s>."nК/ FM76_|9:N }i@YfJ(]B3aYGs= `?V'llG^y_5em3YGu.u)L M ڹ} }E6å=sqڅhGgL1b(=S_^ ~Ng|̥2|V/EML ($?<*k_ߏ5'>UO{tOWjq2׮B+p-[ 1{7>pXUAvt}\F. LQy>a~7VD}(߾ay *zwenqRߟ;>h2 Mϵ'O *b,z2Ϗ“[OBX\ :m?<酭?}T'ao-h믶`_p6x|/~/Q=y`MfNrˑqMa:Z>שr.yB$t`WxK0>)@ć9tӿIeӁer_Ej@ćqMa:Iڟp_CQ7:pȃpƆP5.f2. Q b -3;1 zoധ9)wI/{GQnSŻ8AclqrYT'nɓiҤ et~šOiO^xV'~ǝc:Ҿ+/CӦOY_+箻RS.3Ih#+^k>Czk A%8,Zt?|6gl m6Tԩvf(>Vu‰'s6-Z kc-zz?~ c6m7خ|mEQʘ=s&Ɯf2x qk_Pg%j䳿/3ת,5km2@y(_lHvG$c?0ClLaK[OxЋG=IU1KMߓ0~ɎA6.y 'y yJNNv`MU]BaȈ$/l%'';J033˪Mw#M)Gٜ|N0z01J0c'hdü'ӱ\׏i\k#x_p]>G[SLU/2JC$o8/qX2i`/> 5נ#:L,BΞ9>=W7mZ/R1\JIF9r|3]2%ީS&DW+'4ŗO?Zj5ʺ/6Ip+/DpZx)OnG/B7*@T26>ƧK/.WMDU*W%$hǓ;ImƎE=P _s>$WD=.Ӵp塿 PW8_p!, ˒ϧuT[ al(X[W`O*kŦSO?]2OkGU衇o.l -j9u94hƛN[:dྊf'\~$}ժUtJoܸ 0؜ ]ғO>S[l0e0a<ظM=c葇<:tDmN‰L~):dvFHyse}`)dz:4vjSJ'axirbԓOϒѿ!Cr:}ۓP?>3 06n~YK'q{?t#N/}8+CqPRj sk.8IkPz ˑ~ 6/d=⨣݅=J#oҴ bo kvOˍ-s~]+K (DKɟWVq,p`6V _1̋q3O|ħ> |5>nk/l`Y Wo܇9Or?7oA< s/}E‡*a˗[O;>‡\ҟ07>UٳfR^nGf^q \cq3??? (άgciyp%Ze߶L`Î쯍?0:N,?64*b/$|o%V'@nQTV8 S|FX)F!',qFJr@D1o73+d)F$$7#7% 'HUl"R0?K$_N wgKQ&TAC9=OѩMM4ޑ/ <=JiNXyqrڮޭBqq~II00_`anI?LW4 '[! KE RZ`lhltу?FKKiڳ7*%?.Ƨ`ϫAisڱvm9mr{+p7qURVƙQ +CN93wd='>ah\HWїqr's>Wj[SHu<,OA4Yyۃ4_P۰ ?ud2רّ)gFH'MvuWE>1_qM ($[oE+oTn#z0Ƨ9i&MJl9F4S|$Ig*W0gv9C/]~ŕBu駞F0ռYs߾ 6 1H)$&Jwޥ2ΧFǝp<@ҿS}6żoHध;\xaO: O!w|job\+v)x85 W^~9M.e@jSO۷ݲǟyeKh<6͒|<<+?4MO"*\@jx\ƍTJm |\EZ|u9>W\N?pK{ҧ}"k?+4iA]l:???f@_¨63^3v7A s:M?ʛi+t&SLi8PB v`e4*!8jfK4K/ 2 =ed1k㏍0Āwa-w[1fGE EǿM윢\ !xٍ5iev/>*VL< }h3%8M _; 6liMn]a4OO坁@. lI rNVbEժY6L6_4ޑnj8}؜ś ɗ^Oeg9.fX1%=GA%eg#4{}㥩RwS'9pQ:$l嗦zII\Ӡ{[/ͧ#G{b.$p|Ѥ ʤPgĉrӴiӕW^NuAGq-Nrض խMX)FO>8Nb9otx4É<8!SO0lUCUoIPxqnƌt=wE]7p1?p2'$m^l+pe?XL qİ_iIv=.Y•)}IDܸ^ކ>Wxf! 2,m2 oaϕrVa61Vt5l|e?_kZtT mjlK%8{6>:2;PG{AɉT+/F`CN%5ke-7*6,^$,׫_n /x)O}dS/,]f"? ij-ċLFM*wމz^| 5jBIO`3R!f$'>J" ?:kWnr/B]sH5[68@HG7רA%)'wt16@ħl|dL~8 H13K`sU5Ea瓋^yH?C3P͚|2!袋.uk׈,;(cc@퟊&N8g,}^sK}-z* >Ty[ElM'w>Yw94Z|9 ٻZ zo'M>!?wStK~qcǸnw. k;mO<)Ծ?8/I/S:@m16ЪիS>9m'Nc2lJ鍊SMiQe$&v[iϿ@wގcȌ{Pw=k[$\aou6=o1ezQ$ 5{/ŋKМ9s$vygλ\Jo6]sm_:: =y;L h0YqI-mζ ~C̮ɟM6Is)kRwrǟ14j4q~>ߊf4l(Vqw^ݻf͚I}zasQ''>%'> '>1k/q(>ҢE )w?w 3 7Z/??faJlI6k{ko^g?_0?/Ǘ~51FGOr!uK9%I\I2#F 4 _+y$GңQ(7|S58C?'*] 9Zﵷ^󆸎!1->o(܏S 7,n6ikC;`:lr=5&I7e?`5lؐJjɛ"W U[r7D1&;aÉg1MH`8Py5C_glőڠ+28*[_\g:KId (۸Pm 4rW`QYO.t5cۉFx>[pƎ\ric ̠%Jy?Tfr VU9`19 yN)4C԰qc:CE&N@S'MGiTXfO!xز/h^?3賄.Ѯqii_,'?bO1ku|uci_Pmk̙3wM2/W_,s7+݌X.?p]z o)_Ն\/^u_rio:'|"<&u=^>^&_v5u=LZbEhY]Ϧw{?;&FB Rm3{i[$20}tq>\عpҝkrprOzsϑXA*U?o CO3yfRh4/n?EС5vlT~חpeR'lFMTYnWcٻ_y7 kE֮f,3{ {I1L)S7qU\U'GvmCG< yNYeKUJZB?vx^UIc1c쁞|)q֟MWYS,3gz f-[_6kcaX_Ǐ en&jּe>b?=RQJ*{|s]M;*SoV$នe",}U+q3x9P߶]{jcN'F]'&U§⺖̜5.Ub WC<.n5~|4.!7 ك=PU\>m7~U̙3~s߮}[j^mk?ENT~?4o.V^:X?gj39mK-$Ƨj8O>rǿO7lUyls*|\N|jYpO(; X^췕~4<k'l{^x/>c`ҾK_tԔ!"6ٻzi_O/_d?-si/Y_֝fv߿?Y?u~?6[GygOeUj㯍6nmXcx h⏫SCGd(( KRH2L*]4o7S!Adi Ci;-I-$@ nTJ033S!AВOdH.8 "MW:"Y:$D>6YT|x-pbӮZ ϟM \4kC&gϤ{w̖B^ F_u&l`^8X^P26iX}wDP#/]V2˯ Fl ` 9(Q/}+g yѣO/ַoÛ{PkoMBbNM/;WM+O9V^NT2[O(̫8A7g|s:ոџțkэ7^x6<Y`: 9&Qʧ (lryid;$}ٰ8j,|sO3HvB Uy<ԑ˿ЗĦ@IDATMO_6NqO I-5moMWNy=`O&M^9ͰANηӑ`Fyo@,<^}qȁfzCʛゴ߹[*2\ѓKq`MO r @FmB0SXt2Ƣߏm;Uϛ+x3GVE#k߶61?aT]lH>y%<5k"4lm2˶<XT[0r~7Q<߁5]|8~t~ ~8e_6X#;b4>,]8>=9W $*yߡ Jξ,"_/Exn8l<9qi1V1N*R`㏍?*Gc?ZW"3qN1N+R 7%</_ i>萗?c@N4ogV,_[oZRBr)KhBa_igR75Q԰a'}B/TP WJC^ylҵU5nL*(NO=df͛S;QkSz ^dOIF>E?pb f;ޮ͉Ǥ'?`mmC蓏8jK}.?ӴRtqSe_>KQtzt+jsbł7A^Po[lqK**\`9n8IF ;WIx]֥بߴ%zE^pJ 'y`@a>w!\BPD *h ꮫ"r r*@N_uWO|^&yUTWWLOSg0k  ^ ]/~n){.4l,N V\z^"\{2 _v[*qġa?:;G8>]n@ ik+5|_c?4䥻O}L,D(9§Grۊm'Ig׿1|{ׄ7m{S8v=M7@wAW̶/us_,|翾m{vj8X%HD 5vhNMy?3;6|s ЃGeB_pAnaǢ'Џ~5;\zWXj }7Len4>_v֧#k_opo +ʉ'|gw,ºrFj~G?6{W)ڣ,&:ɜԿѰӧO/+f<.k?vŽOr){ oE8 s~_ڬŢxY˖c? 7sXR^x6߮xy!v٘ʺڵEO|=ނxz؜~r}Ees\ּVQEH9+a}v[?"/]xq(Kϟ =/;X]#mċ.{X$F_mGÅOY]\ w>W;!}OJ`=!,xtfB|{g/cс_li+f,=ʝϟkl\e՚oX,t\l !up9bd+\tE6߮FXlUNo}zEHov>$S^q pOb麰mb/~fϤ0 ~Pb'%\ ?Vð!SQY7c1/=avؠǖ; ^ei?!ɟ[٢;ñ߈mmXEX|Ia`W%[|{]>^ O:b@ǂ_ *i npbk? `qbXěï?w|2 qU.=Yȿ];`S =~n۸{ Kg I >ȫ๩ @".La16_:ʌ׿3Pw12>2k;> _bM;c[v?OY~kaXV`G++w?zܙ~Y1$懸n}gL<5v<<\,ěn1F<3hөFdH~'dK?g ˌNOw+ [A@NJ&BR9kfg_?6!#JAx_| GKxJ=.ZKw jEOfULK)?MC,'}Y2_Jb+P.O3og{&n7/sc0jOf4+1DzZڐ P ~/>AO'Dw-?;4;ϾsG0Wϝjnɏkw ^t|~7!+ww,Zx|ܕD v8˗ p$Ȝ%>vVAUϝRSyŮA۷v6lG!.3-ɫCBƅO}Kb6~ws\(˾f{i_oo8vW;cYy kU/x@]ۇ|½rt;s^d~>YYƈƟТ.k9ē›&ҿ<&yə:ȝxB4Ysþk(-aJ ;8|3n`hMxq_df[ -!A!<ᘣl~By]_⭸ (aÇ.2v74yONr,^w;>.f˦mm8_9Pqiv,o5jcKo$??|]_j/o;^EH'oqq^lN|yJ~O\"/.yWT.Fˤxy.By 7ۏg_g ^)6_@H§M?/umΟ;'Zz'䏝OnOX 5۟ڧHzЇ4.0Y! mw)XPu;͵.:OvP{U_MwEH1\տw/,m+:kG:]lm,k> A?Ɵ'.|Ӽ'b!y,El5#p `im2"(2QL&L/nIxn۵q\ hwOb\,OD@Vc7C=iHپG_7g.A6^۴>atq)B۵? .p3Z٠Jڟ6Y2q;>o~_|םRھ-|X񏷅/>~JOC#ʯ6A,Jyƿ8.`eiG5Ktˡyig*3f#cSm<1P~|;4wyF#{`?I'`Ֆ-7߲9|\&|\׿?_.ؽhFq}esG- SltkUio;ٿ}j;Ch!B_+ڟrӥǿy@gui'm`*5jPF!?ʰ<!؎O|FNszx@4Vpm%JWZJɤ`JO綱 wFVOO:翕a"e ߤ k⪗1dXJ3L &CKNC''GAwϰ0 6d%Ne6Ht;cG#FQd,߄Ŧ oj_re9v=v6`?v7l9teH׿ >w^ 7?v0va4 QX|BŮIÛ°a![juupuX@p)ϻ=3va{l6^O=^u j/ _w8SAil?#pwXC?Pt '^K°ìow3L>_< xl B=,οso=vl'?FR>/^ogc7ca&yliܓ~z c=T깫i0. ԿKp'|W۹o\>L|н@ ^,|76t".po&;끐wz5~m~??Q/g;=OM&U>"6%SN^Xi;u/oڍ?m&sd~},^~ib;&ߛ%'ߨQcŗpם(oh̙+&ʿySwqO)xDap.o_FnP}-iw_ϣ{Elda+;^6? D>7m_y,z.vԨ1Xwq3{6 >߮;:+WaGN3zL6K.Lz?{^pO;7 vo1hKGj\Xh˃2o?; łI]&bRsTxx3o"3A?ǘ(ܓK(&%BgsNnQ %_^2;%5S SvX|WnhѣaFWB:oپXݓ)<ڵEO(+'s4B?8:fECO{0m䣏 /]Rڵ?s'l؂],pi7;!7tgco|'^[}NS~MYbN\ŗB(Ip?w6|T.k=yc@,F;oc. _^S=v[XEw vnlo]?.|:8vؤpUuZ@iHp\(߯ϴcQq1qat('NPǙOٟ=?M>+g]cf5O3fβ.| A_iɿQ}0'wэSV)~ZڿX4喆w:wg?%z]G Y.WgaNiq,i^?w|2x;Sku;]go!K O5?kf de5h!W޿h_ӫ(`(XlS`"OTf}wqj׿h!vK K$şK(Ska{jW$_[=4fk׮ ;f AhPcHeJ8blqm4 Vg٥ey&J2ɢԹ6œ '_! TDd SG4ĺ]IFdecJpq6)XA'#3Z3giB-TKw=.WM~*tfjG3cDXg yfy1a=$׿SL /'g_40$#o!]aQشDZ+R3?gUߴq[>~5} ~}bǸk9jE?!K':y 0 6!ROgzAY.?6CY x@lׯQ7 ;_x\T]3?  ٴT~/(R5wC-|?hUϚ"!?X f;zԊ25F~&*OLMj-,t_&kUN2ZYҿ, Mת<05eZ ХYUy:`j:U˴h!gK((@z&qe4P5|oiWzM Vfp|oՊ8/{Vڧ$_o===amƆUVc\|zwTloD}UnNe y}ɿS/Zm[ߌ8K8U],D[~Y J/K| m;) c&y{edd^g>>irT߯\vYb- */8?_K)?kQctjOߊ?`({???}y}9CFOMFIb P_5j"4̔MGt}rRB/şa%*AAfD׆޸ /o\y$_\+ jjS!$Tj?!?T(IEgұ3N Cq 5er$UR(ɟ0gJcgH)1ߋ1caL%!8j omO*9Қ鶿_ ?~:/{t0{G?V7ŏקӭR'W?z4B[@5khC?A_):6ǗQr7 y`(H 4j~gNLXNVUOOldy66QGWuG (_tod @]e"!Sl8ܤ"%#4h&h-|s?l/MG4Wws1IEJG) 5\Y E͇_@?4<.qLc0YB%ھ$+voB-[G\#oxw)ާlZxC[IAmHJ'VOo+$Ve$Jm'3RAhEFhKi/de]mD(0첛Y*z[>2i߉d5."׬> rtlOAO,eU3ҿ$H:?y&FOG7v P o@J5XїbM*dV%+v _ H2@o =pHŠ?R0SVDy(R+_ H_GwQ&SL7Oߊ?g!IVD(p,|ꅺ.GTRSѢБ VWG#=uF=mSQ)HO9dO-uT9Sgi$89e j:orԙs NANقZ[G#=uF=mSQ)HO9dO-uT9Sgi$89e j:orԙs NANقZ[G#=uF=mSQ)HO9dO-uT9Sgi$89e j:orԙs NANقZ[G#=uF=mSQ)HO9dO-uT9Sgi$89e j:orԙs NANقZ[G#=uF=mSQ)HO9dO-uT9Sgi$89e j:orԙs NANقZ[G#=uF=mSQ)HO9dO-uT9Sgi$3v|t:r `.LbGcah({a_H+ZXufԾGXV2?$+=8V+N?)ߚ` T{gͿiQ??[tӤzz0 CA!{=v|,I? ^UJib|𴪮,[)MLϐZ!"KgVJS3䀧Us-PdJib| Y:3R*!CxZ5EΌ&gO[Z3c+rӪ(tfl41U>Cxj,[)MLϐV͵@3c+rӖV+DdJib|j,[)MLϐZ!"KgVJS3䀧Us-PdJib| Y:3R*!y9HWhi:X5L5 .1%/wtSb?kׁ*+k~?N -uFik>q]hKnXx+TfX7QOOGW_VKo?hEO  ԛ5 t 5ۚ??K5g?kBhocWoXM9怐_f$EO`i. Qj@M9]O33dDs&u69v=ͬΐuFΙ ԙ4:CFԁ9g2PgnsNo Qj@M9]O33dDs&u69v=ͬΐuFΙ ԙ4:CFԁ9g2PgnsNo Qj@M9]O33dDs&u69v=ͬΐuFΙ ԙ4:CFԁ9g2PgnsNo Qj@M9]O33dDs&u69v=ͬΐuFΙ ԙ4:CFԁ9g2PgnsNo Qj@M9]O33dDs&u69v=ͬΐuFΙ ԙ4:CFԁ9g2PgnsNo Qj@M9]O33dDs&u69v=ͬΐuFΙ ԙ O0͉o>xxy`N y3`n[M0 e~BFI.(+ICbH?W侒hYb[?04p &vQ_X(]ӐCOş?Q!PI ((|k?hA/d+cIߚ7=KIlN0yTf(L*d;&6.?ܶom#bDi®HJPS&\Ve.PeNt(2d~׊diN?D*(t-p?_UvУ ypRSzH lm"peRУi?\mT x`+n>ˬ`XXW1: Ծo@[idd4h! gOߊ?rDG_?kB q&Nh6zg `=4FJoHͿhE/47ͿDͿiQd5hFy CPi ΤI.]9Ľ7^tL5ՓzuZ+2c,sj_M( CiRZF @d0-5¦X|̀9ٟOτݡ7ތ drI8RBtf÷8S3Su/P?BϬCi/*jMI9/rv?|@/S7w 2mN䑥]HCT'27!;vT%Hě E0}4~otO ?i`a 3!!}Bw4+29__twk6D5#G.|%[yRMn˷)\JɡHy]AU63 y2sAU63 y2ڇ(h6͚lP͂*Q%2df+m1fE)Q%2dfD!Š*Dpf@ϓlVU™!?Of_τp߻0nƾ熈HyN&IqLMh "JIK??_i[dP8k@٘A/"z!?P( _Q; en.h9x(PC?E?!10(8<*W H<@j;HwT?+PC?gȁttM(? $[Ct$'J'H_'S$~(l?mmkKz/NDw%qdkFNx9X+SU fde@0;4Ocz."{&3ʒRaw“iƢ\9E'[ f0;4Ocz.✢L\rh3|ѫ"W3#v-BYoī}_'#˱@68!Kob|PͿh @o+璚̚)Ϳk]5z/zozzq5l|j {z]&F.3uta @[њ+R5g s}7]&pM? 5l/\%\(kpCW7$5@Fx7׍ LZTvԪƯ[2 bp¦ѦUԾ/SIrNa(y4ՇjzRrE[I_?Wo_QG&YI-Q?*@UDOş?*T߿Rc"_qGISS ,Fo=oߚ`QMqbS!)S j4sH&5ўiyE8WUVPmpH&7ўiyE8WUVPmpH&7ўiyE8WUVPmpH&7ўiyE8WUVPmpH&7ўiyE8WUVPmpH&7ўiyE8WUVPmpH&7ўiyE8WUVPmpH&7ўiyE8WUVPmpH&7ўiyE8WUVPmpH&7ўiyE8WUVPmpH&7ўiyE8WUVPmpH&7ўiyE8WUVPmpH&7ўiyE8WUVPmpH&7ўiyE8WUVPmpH&7ўiyE8WUVPmpH&7ўiyE8WUVPmpH&7ўiyE8WUVPmpH&7ўiyE8WUVPmpH&7ўiyE8WUVPmpH&7ўiyE8WUVPmpH&7ўiyE8WUVPmpH&7ўiyE8WUVPmpH&7ўiyE8WUVPmpH& f~:!E~kKaRY0Us381Aj_QOM VC_?+P\$?ahR(^4b݂]â ͿhE/s_5l.Q???-|Z7 S"iʸ#X (WӛWVv Dg[훀 YF840yHsFD b~.$?q:T(llsA0LP ߿mes?ؕ{1;{`?bycv P/SW/(RWkA/f 57?yWͿF9ؤ5w{ڠzӭOz퟾GzzzzzŎO ^f,q%">DSl)3&|Y[XJ7"ɲKa>3 ( yd5!ƕ*GO_?_=61PuE< )mt@di_<"/1Ÿ`{,~ѧd,%K??_?A5`_2ҋ)[/ş4_c 뫚E߈G4hMo+5.5g?kYbG?zM'12 3N3eGW1gã LbrYXS<yUZ3o@<э9/i,U^>f 13/+99iTy 800y!G9H*=qSPFJIp@”BOvs /_W88EO\nzzxg;>aSm"4Ü=_Ǔ̐mLi=):߅KV:6@IDAT@$3$Dۼ#SZOF0}KN8J&%q]iJ#SZO.52/gyGx\??p3;>[Ww5eJ=2$Dg'w |Q?Y9b],<jpPFI?A3[I??4)fcscD/Bl#!C/p#Tx!,T b3H o3È#/o {ntk?M7ĵa*#Bs3ըQaaʕS3}Eaحk׿h0uhpn yOiw?avkz׆%</wQ! 8qbxū^v\:dp?׬Y|0 _m,61rdXm¶5y2nEwXpA2B4h_ſW/?|A-e^O?amųOQ?FA?=O}t*_v:ģضL,?f%|.Jhd ڗ,N"VLf0UFFϬVLf0l 'Ti}嵯z="&g9dpBog!E8@yZB8r1j&gM 믿&}BÆ o7Xd7nL,_*yǢ -/SVС1QHN4'WoFf\1+ dxӽ 'x;}ou~8uZ&3*/߼XēO yB _pa8O8򟃺-XN9ŮACwLI1/_zv$ճ9|*o Hds@zzXA)7gۗ=Q!`gdg``ZQ|QWLj?€@$׎ִPr{RAdr;/"x4f B D'֙ ͓ߧi̍4cl|L}Bȗ+piQO3`L3=aO[OF%?6dгM|OX '_'àl?(s®!G_B+_O #p`P`~u , ſ5mĆ:pÈý>xB\T[npɥ_?˅ -&g߷Et.#A=0д<͘ߎG Ÿ;TO/#lVfxzSO -i4l=P.G~$L>'=1w0xO:5L9TBҫ43^#Gl"cIzE!Dol_[+J*GqRC/ş?%wxQEwSӢ:`~iQKU `_?򴨥*rXuyZRG,<-j\z]QE .OZ"W^E-uT+}@Ӣ:`~iQKU `_?򴨥*rXuyZRG,<-j\z]QE .OZ"W^E-uT+}@Ӣ:`~iQKU `_?򴨥*rXuyZRG,<-j\z]QE .OZ"W{Gp Xj|_!L_`0TMؤl)1IU#G^ ,gmF4aiG og|7+WøSqӲe7b7nc?~x _cxK~ ?J?lfd`di/5@rxߨ c0G9FCſyQ;S_ BN /1s>3"{}N{Jopǡ/t4݌te-ϝpO0WFc!`nO<׿ߵ~?\<}zdM׾>l~'|k_ |ի'|˗\Z䵾4> '5uʩ}M?*qk_v ?6<OcђB(ơOƿShRR?0Vfŀ46#Gg('&|)Obpl"AU1ATH(9GQ _3A@Rʭsͣ J f0 KY4V:  f0?,kUWLN _3O:P:KN?@T dWG=Oq,@ϿkINpʮ:6l kc.< :F6t#g%k1j׽!w>}_gIa⤃aͿY8i('>vݕ5!|+w)zn}L+[c v5|ⓟ }ЃO#8 o};(a_߂EPmor;>-[ wAªСC~o9eUa\~y wuJ7E{MG?Xq}C!w Q_o(B_>TOD׆]OG{/|y*ѣG_\=p1Geb.7_W pcz_x/Ż:7OR0fcҠAÒ ]w]x^X(.Ϩ[C?Ń>{5կ njE=ïn%:xco_p[w?˾>/75#B4QOd5i/m&_?#?48)UgόY3#ýӉf̐T?Ïj>>?"1c؜L/}.pmN/93Xyim CP*Ϳ7o~s8҅f7py {û[}n gq:3vH8͞w%~x!>J4ɮ_F?)C'z/?c==WhG_Ϫ-{V3S *ݡ*#~<%P;5j/5땧YOm?!/-լJi%1ەlh"ճf6LOO֫ʌ_c.J_虰Qld\:Oo2cR:H[8(n[Io Y}V^77{ {q'.|[&|,A K>n6l^Wo⩵5ǻ/@>?D!ShkQ4zD'W52kcC1cv9r8>N> 6_vyq'>i~t51cmxB>|h?Q|Q98~|8 fK7"lvUzM2dvf~}Fũ̟cE”S0[ W%4i/cu9ki4OAC`X~ĵO r~}VZZ1õ!(/nzzi hdɤ`J?ib:UZʸCIl\K۟ 'ax,X%T?3Zĩ/a~;kXҶGjQ. ĈwwA(:lX_~L^{퍅Oٝׄe˗e648̽uledMpp!]6bu^7wݝm~÷[aZuw|2xpXhar) p.S+@_-# _n? eQSH-I=h>5.AAT/_` 3?2 )(ͿF9(>ngD/EOLgg\aBڬ̗p*PY"OOXiP| mPQ(,+nk4>moϋwl}^ȿ =jVE ZrTXDKǺ0_,ϒ``\eKt]j§AE `g*Ԑ $8ʆtiSʳm ??i}躵M;aMKMK_C kb7Sstv,ow0FCvs$)Sy*qmD⋘f`HXvsEIEZ66/yA#EKҿ)V3Iv!Ӓ(<%1Y-t_?7m2fR]mPi陰;;{Y?hƾx>]l"?IG\naCtK7@cz'02ao{!jxB=/l&cj<0;Cw7_/~7C}o~p+9Koc~tK7^K___c?ed6v7㊸}N>ħ|\粫N;-,6@Xu N=5XonYecG+WC=8[Qo޵k9Maub9'{5Vf tkI Sl 1y|9)(EIj l _u]qAWb{k|kȧ?^](KO,3d=ؼ۽t^T٩gש{!.|+ym [hmz-_?ڧA 7_ǃg+lo/``ǯnہ(7s5d|`r+[,gҾ_Sj?J@򿢿.B7i0___XYP3lgrӈ@q-ԇρ3fiMpj!}/O׿ /$3~A q]ӧ_x]a3we˿s£=  k^Z0wάpռVO;w^\;>jW?#v\:5n?+WxDlZg/Kզe.)II$'ϒ'o)r"Y4cYK#; &/K~MXE`B?55ꁳ#I_4@Wea?p_E`m/v> _&>WVOEX!jHըJ0 x-“>rm -׽>l5zɟ'wÊ+QUߴO _q5 +VrϚvNxߊbOF.fg Wο2_uՎKOwwP81L:ɓ ,Y{&gΞ ۢGLMPtP4P+ c K,?~2Ϝ~&}Ɣ)CЦUc KM;P[TGC_r rbg W]{r.vw9=gjժp!cBƌ \|qc3 yU,ծig:W p^"r( vG. g3gAx] e'Ç S2YӽT~ڱK~x@K>lXNWe>/NWޙ?lj_%S7 q8,?__??6^k̙aȑ{ 'b磧z9kv>|} w7|%- Gu򵯇-7̆C&M W?,p~e.S> wN迅w1/wWbఈQqSQjrVGm?o(QT˲?8/O[)-[o MYrǑ`OBQ\M#~1yqt@dT;uBM"?- _ˆ$sLxюXDAǭ\2~!T0mpEXϟ?@;ӟ w1֊+V:5IAlmFdžz0e!%VI$W bx65.BMB{<9,}RLOti$:c=׏Ιϛ?!_?g>v{J,|:>3vp!pmuɕg+@gE;~ȪXlupu7f,>Mʆ8uciɠ-"SFASTf'pA4 >X˷iuqko70g~4o?Q~4pMFOGWGُ6+L^Ɏ`ؑix'|w#m%ş{gE[Kaܸqig|3Zo^p҇NfaaG>bwVqsn;VQdQ'/O[ď>(أZ''veުC'Y(SLߺ?34D#3gD_ lh4jM |Z?%YGe"C򿢗egiETc'?Oɕwy*,I#}u=j.SR1}_g6ZOGu脩? x:N%VQj9O=[Vni, 00R<" ơ;sbVӞfj@r,|^-["v巷*܁ݠF^7#Cw޹Aʟ vLg 6 /*t O KLH9>mp74drGU).腑ϙ>/\p[zۜh P.|zhC֙I j ys? rIhXȬ>$\^Jqe)-BF!\.B7^Nf\z6V"C/ x4ai㉋.x+φƯsϵORAlTe}.|⢻͝3 &Y *bC ʅO\W=D.eߏEw.$ҏ4 RphpڔS?^EmHvȿ{OkwiEU40xH]( +”#dObGS?P7 t̘9+1"w>xBKkߑءyo'6-⯽;?bE!ÜٳUx o{[xߑG ]}u߇0jЍQԼign!UX.;;2,>4"}O~>wg9;NǎO%P6?SԴ=e#'''4kCG&"6i;5wZa# ̤-ҀJ6&7.)P8X+?OQO=`ֻ`E"˹to[Ql2@h5amDž\FawՈ~-\pd/l/_?ޕu;> [ouRZBYR5vӰi/䕫WbcL"pc ^Sn2%mڟ81S?ovk?rilx>1[}.BE-Bb4Ɏ}mߪU'i/[ZvƦ6; V%Z?W/ bC&7e(Bf(Xtw%];ڴ?Ѱ?65ޓ &ݨqb4vNp Y"P$.% _ސI*LS<$( )=F'Z o #ɬj KA߱g2빑_3f§{ 't+_ [=g+9kذďxy?^h wÅOGyhm㏅>:ybuTg?7ƿpQCUgK׬GH(9;>w.Z0Lv F9Vσur0!NW_|W(hhjI15qH+CO#UT;oԄx$CDύ§^r!RJ9GzZ08if!L:orԙs NANقZ[G#=uF=mSQ)HO9dO-uT9Sgi$89e j:orԙs NANقZ[G#=uF=mSQ)HO9dO-uT9Sgi$89e j:orԙs NANقZ[G#=uF=mSQ)HO9dO-uT9Sgi$89e j:orԙs NANقZ[G#=uF=mSQ)HO9dO-uT9Sgi$89e j:orԙs NANقZ[G#=uF=mSQ)HO9dO-uT9Sgi$89e j:orԙs NANقZ[G#=uF=mSQ)HO9$N.aH`!ͣɓ./eD-O,ׇ:If3j#{q;`u߿&Xnj:+Bnܣt ?pn,|gNYVZ;Ш>ߨcŗ\\ӿ3W]uU,[i焞pDZ݅'4؏OtP8h!VqLK,:5׾/O t߁&( z;ÒK gG@&Ii!_jXD_=jLKj>{ٟ>'?j%>aMQ]#/V_Pl+̿ïd?8{ڧF@Xww"G51W?w%Jgh3T?dѺXwAυOc'4?{Q᥏ hga!Сy9mЃ3l)t sK. p#wH?Ǯ'SXjP \?JCρJ4hy?3?{Uq^@b"rQl{LLlhbW@&6Tbr*V &D%`;ٳ{ŋ΁{vvvv?sfgg=[!v|§޽NYoE~tj; Zo0Ndzzzn@lhL7w}.]ati}4k&ҧ b1a~ /|❣gL 5Ϳa,SͿya?X!r r{iLh?bb_?6ͿjnzV`*b=*;,R@ӬrHJ1Y>@ hZ5C8҄%yLf GR$R@‘&,,c|4cW9҄%yLp4aaIȑ&,,c|дkp$ K, 4@4aaI\3#)MXXd)iƮr$ K, 4-!Ii’<&HM3v#)MXXd)i HJ1Y>@ h+Ii’<&HM fGR$R@ӌ]HJ1Y>@ hZ5C8҄%yLf GR$R@‘&,,c|4cW9҄%yLp4aaIȑ&K*Щ(8@𖼾%/HWUa:Cuj ESH7hHoBϥX#d U]`|6K$_?2oCd:)l^#Ksf6Ϳ ?XO_-lg?gĎş-lg?Xş9jdg+s,D-ai0},X?!Q~Obkhi>Üx4L2ڸ/EYxHG2r"d dvW*:l_l5/?)$Ow_ޗi;liO7y7,x[6?miO&,bϟ;4 ;ϰ Nz's euO`zd_V{N'Nf%Ipf)u*:l mҏpR+AK8"urrVd},jW?\7@DOL X3ZfKcagدG]!&OAla 65?"v_,~>'*<(/]oHNnfIILZE*Ǩ.lӕ.8D`@IDAT&|1*r˦QZkF-P 1*A\i#de@b8.&8|C,+"ŁP"k+kQ,jĨp˦ v! eĨp˦ Ħ_-e٠(1*A\iDai@Y6(J@Wl[Aex .r=~&9KYFwvOmG%w$͡Qog_ PcoeBm5u._G)޴|og]}H@7@Dcڠmm";Ρ \ FWJ 9t eiBL9Jb'|Kuqq 2o-)=leO3' s=EmV dZ6]6fe @0KL4uUӜi_AY+ Rx&2M]4pZbggoC.g2-UMs%\/|rݬfnWD)_r)&GeJ`5p-mk0㍿<6^rI46'[/)-ʱ|@bw[=/ɞG{j_Q_e>bݻ\$q&LG@)Kّݡm3 0jDBp1:Y3P•8S f(J(26wu;>6s+G?'5<Ju4rӦP*og쏏9$fX?YxXrs?"H86c:6˽9 Q8^&itla/~aO ?miO6t_u,`? ")[B Ϳmm36fqhS$)Q}[ 39hͻ4>*2S V y]CJp N*2S V y]CJp N*2S V y]CJp N-]ZEjiHć#?؁9*aH<{@ .tlP$KFacvB 2QL_?2o Ϳ-`]N4@|^ '{f?}uf=՞W{j_=%?v|ʹ2caqR:~P%Pq. _d$ˆ<&E$ P@#LL`bc쿍6kt ?UV _/ CːNd4@xĴ5˻L5|,5]Eowdg_0n]F"46Ϳ]!n-h7CaG_7s@ ,fo`.-jg?[<"i-_xLr<~.񷲪jT_Ő-n^]7G-#JYZ?@#.g>sc]Nkh(sֆP!o39)T|v%qyB@3&'ӿLOT%$.p:B|/4U e+<0sr0D!MUBYJ@#.g>LVQXfww˄\1@3m9jY,q@pM"ܦN_C^1cyD`_m~ e)ͿD2s ?y6no:H7,TrOjt0QDbſ-o?,b'Y-hW/ş-n7LȎOXDV܀ \_xMG+ҧi16@ OI yE4M"&C%g8Jz%Q]rE4MLT<*Y?fJo]#IbtWO쏊GhTtO|𓜲w^kP);5nBwS0&?tO'X3c0O;#c%RZm꡾%kBGly6o)!s>Dv#"WilKm,',Ϳ6XgX 6[!ět'@N bIoz}u6P eY⿬G>9àBrf#*J SBz qm4.S8+ -TJ #Ǎ.w*!MUqeP\ΰG/mԍ i-)SWx"?frV#袞R&. "),|9.nW>_]/$<d)%PbqogS"GJaA!&gYaǧ^]]^᯳1<ySmR@UL|o `3,4ǂ0Ϳl)2Ge?xaD_,d?ZWtaX%,b6O[/uYoGD :DX%~[YUUUuXV+.6j؁hVR>1_zZ,C.A&?<q`D:d쯍?6aS܁!l+y+N7<.*q%n\,J'B|*@ST2/``zKp\LXf7`쯨jqU82>J¶ђ}"/req_?GyC!~ `q#㮍]On? I`ѻ616vcuKi&$~4ۋ_3P$sm,?Y4lCme/gC94 oo#~aϿ6Ϳl|_{:p>cnov/ 32<lx.t-Pj-E& IogYg+"fAZPa㯍G<Ͷ, hiqURKkZl P/x!q"U(9kMd;[7Z^G2ߧim~Cs>MCㆴW7hЀM~!J?~bUe2"o_]%_b㯍Tc]Ԡ^Tlf+d]S_YM?DO}ޯX_$bq:f-Q3co2ę{ +լy1SCG{2U cgԿe]\Cm۶Eґ.2.=lp4nrt¿rmLP㏣ٸ?ٱT^,hYx1/͘J~ڶlgYAX4aW߸ wSZ7ޠ=_YJK[oE&g4LG+gU'_z;jjР}=k.:9l,j e-餓{zXxOhذ!믁Qq_}P75bm^x1tE<Q߶5kL.=T1}:}K#'^ߢe+8h0~qM05FeUտƌF3ޞA}OMM:WZEaG}^06jӖ,]LGvb7iLiV{﹇*+G%r:ksͷ؂Zn%>}OfD45j7oA}{it9]:H]SNO>d-Z 5رcЯ0[oӵ XyyFmOߕߍNx0[9_dkAU?_և?macmFUE7fi={K\vL.%ϟhG^u,thu->@ t`q|g޴.GXcv_-~J1piitv߾<\ғ, ]>ZF688x_e_:&`'e2KaoϿl5_l ;`NMgcAigAp)8 J8%??IpA1lW$PD$68?6]=bӎ,E~ݡ /+HSM %)qEȹk cj\̓@ +1VTPͶ@YJMyϟA^EcOV@dzWylق8o D,:7fӍK`3X>9, /մ7V׏%?_s.6L.ߙg;Xi3_ O'L7'kڴ݈,YDGzwM§Ds7UY1ݻQNO~QֿK/Ͷ\lS_޻#-t9:`e^SXo#FWGffaN)BMڟu^n6*Ueɓv:{S6m$/UsTWZgc~'֚\M|-=ܳkZkM5UC>H'; hm_Cw?;Ͽ54?PMĿVњ sF'5O?MX1lfmGr"Ϋ?Yoyn\uaϗ1KAmmW+-tjVXs4@ݗS+j;#gi#*zXĘI/pYy88:p22Q/9*>J4C"RS ??qaX 12$chȪSѡ#;(_yQ~Nt?A+ԭ. e )rF!-rWg ]w+"z T o,\O(͟ O;+nc5}Bz՗h-œXd~p*/ZҠؽz2qX;n*cƎ:ukc;Է/nCYk-[!Z^W_;>aG%߸I,|Q=rD}M[q4;>YZ-JP=, +]A 9߼Sxǧyo٢%]MĮscj(fǿ&v|:DmUz[oU1efm86RdۄX*b54kև2iiGj> :!\eaӚk k_A~[:sQVF}9yiP,VV9U-8 ҝ#G Ó#FҎ;Dz&m|'70AiMk:ۯ,ߏ?l?7w?f1kO6 ~ t >sKp@ ϶,iė?ļN`&O|o~#d [((f[oWU`1c)|#SIzAt=9A\bXlST)PP,''?V0I$gEaǧEKSg&][83:u۞5mFfΤy^i(}t=TY95.nR?T>rY)_ ?klЄ+1}9_͖z|{@_۷ߔ|9ca3,vҹæ.Όn>-wwegb=`[zsޅ|/aYn1}gtMD~{:4s"w~G_ۍؘj&}G+axR_s{Wq:A;|hm~MEK.H駞ysBQUR妛ȑ׿D 4ٸ'oO&uX.GעÎ8|+Z:W5<}mzxؙ>_~o$v;Vp"}ozi!?ulsXE`~:6nҘw_k{ZcD9Ьf s?UUw}7և 1oAϗ?6|3j{c˻3ޡGLCV^?/o؆>czGW ҌgД^sq]uߋrw}GvܞܿQ#F/o W5qw""kBN xQ0L(j_ֿΝ&N.o}Q(=N[O,v|ܥ 5Z-Zc&zOǟb3_C! [㿍?Y dzfQS1Ϟik"=n7I":锞)xĘߠ7PMӝXS,mxйG cwǿ^qߴ=sN7-|;>o?w";Ocy'!g!3?f#̩?2+D'qܝAZU?{:-f֌pv<:.U 62;2WC.DD& %nbɋ=6_g\L➦b/.*1̇?ViיXu#24ٟX*NeT6c?f53x ^ē*XX 1H-mLx!)?йܸRn|poެ9m@VS{6t3j֢nꔇi|)9TDOo^O6jחb7d@zOէ/OW@r|.b,8YTpzFâD#/ "]2w=+=g \'{ !CQSTJN=r_ h$zTVNNc[oH?+/ʄ14iϝ=':|aZ.6y__XӼ ;D}_Ӆuh֬hX1 {+N8_-;~ժ]h*.t\Nt_τ.)'垤׏ib/oբ]=Z]r, ݵ 8."zuQ6Bh]~^H`?RgOHO?[@]{3"!л#\3y&,*=u(lPfx7wex2[nI_rrd ,T{UXOˏr7䆛d… ,H]km܊2/b ztE8{9ʿ~#m}5֠|U/hTʛۊێިⰀ?,W\E*uH,Lk?G;I_ѯ~<yz{~/_K1~rF|/9}Gn5nw)k〨?[ 7ioՉ?$[nO5.LJ~}F \ڟ6bKnŇ2O{aiyo:lF^~tx b 8C5^l*݈d_eca΂yi~ᓍĤK_;?qOlx}b??6婃Gg#Y4qCj2SuDϋ#LOw-^Xvsya=h^~iSN<$^{I6 IOb4{w! F&~EVB,z G9_,-[i~Pmڴ>v9 agͷԇ|(l\L3B.d]XꫯR mv1ht>ϭw'ީpq4ggǝw"-,ͻ̜!mljúx #2?ēءwAE8vXǸ e˂yh&}ev`Yw}j$pp9>-PXvb!v&ϩ;X!$ct\θV>f%QU?+|'t O8 rYga: /[;jwE EX /Taݰ8 DZ{p&5=ٰF&vEݻ oVZ<]:7ؠ)Am}vЛ'4|mcuoi-?n6Sq;e=[jΗ4mtjּ_ `~qJ7Y[aԂ PmܔٷY{QR2}=(56h]L[ȶ;ʺ+؁,ŁhqΜӠ (w YK~F= w&vԤA㯿p ;a9િѳxTx鑣++TZ :CgÞ\yՂK._?j}_yFԔի[nN]wlm /Η\uÎK^u6aOO4uΟ/# E d]!'쯍?6ror?D#*'y S8!?ppMع ·y ctyFSMv;b'`y`[3̾N{a׶mKO?P㘃?x71cC<7|lzmdWc&uyK۝v_wZn-j׮>a_Y3{s 8aUCJ%k7_V( B4r"X1Ò_6k_fͿl '>W scA$>"/$"OV,5a^f##,$0&?Hӻ\`K?JV~W;nD]x_4VpY2ȇ+++'rRGsh"m"'λQ<2~ys[,i֬)ȎO˓`S܎O4[hI ݘ8~<;PRHryɋ9ly)xؐ!èM@YFw,?xg'Ҕ%Q۶ԸqczKX6_?~aG7 k[n^gmDVoWrb TCZ)FK<,8昣3[nMb'>&?4/2BχqN}1aԩ. gv‰%xӧ㷣?imoҽ4jJz,j-yX׿EݎEBBdtI'_-D7Zn1|LyQih{zQ7M>+}΢з^x]_聗xNapAN#y!^ܥ3tpA4q^ :t(HezjSi^ӝw!x(&Xr_;~πt=<@)$mL~SlNfuJY\{DJny\}}:ށ h40ܹ_Sw,z2/?Ӄ^WEMOƌ)?>lp%^:§ڵj_EӦOs>w\g}O=M\tlw ,6w]X4?;Y}F ^j&3^(YK -w5Az_vv\ۜa7 Zuj=QX؉m'/v? nФ>r4)Յ|1z)A{p"v6[ZaPz|〙Ψ|oZ0sMîz(:{ p,C?~rv?aӰfLʻvtG\ņf}$6[2@IDAT`ࡂZx yġ]?&T{?ޅ'zjvc{wSe(fݻaQܟC>v!O}G[nɷB7c*^8`{;nbU3=vv@K[n6 ??Tۯ~Xv]?:z_vvN ы/H\׿_J[l_^Njm1zx|]lds.tFIAO+ɿ xv;}b/=a<zͨgnu=C=( o~\?~OH68[?r6p0>u#nkE_ "A1'`fm@t2bCA^2{}} 8iK;G_~,dsŋ?o ,cy0;L/q'9p;jv?Q7 6@3Xq+M~!<; %6jDwqMt^`j|_7/3{Y/G/Uwg%?9,V_} Qw~vpGbae;mn ;C]]o7i<3Բe+qXM.ټueH\r_0w|‚ӧ9gχ_lu;:#ai= lq=CTYaK2Pi7w ߻8%CXl2)hbJ#PiS)RS%+bMs>FҦ(SJRWŚ}6*@MQ>HM8@5lTJ|N*qH]k+٨46E"5U␺-4WQi*m9Ej!uZigTsTC X\F)hbJ#PiS)RS%+bMs>FҦ(SJRWŚ}6*@MQ>HM8@5lTJ|N*qH]k+٨46E"5U␺-4WQi*m9Ej!uZigTsTC X\F)hbJ#PiS)RS%+bMs>FҦ(SJRWŚ}6*@MQ>HM8@5lTJ|N*qH]k+٨46E"5U␺-4WQi*m9Ej!u|;>e ~$_y> cXtOcx/T>0eynrݼ_٫7~=D`ѣFO=I-_9vk%4~//|?g9@VS W^y.}|4XaaT,o~Q1ݎ*?{{k=ʑslwjp;>a?9ϙ.0.AXq̿iky]Inڞ.ZLq ֐Cy3Ȇ{uwqT. vRb6XŻoTSQM{܂~;Y3D9hĂO`&GE|뭴:J; ha5`KpGtX$/x\ӃX U^}Z[|Bm-SN=n)I8,y]?x~=Obj$K_R'ލw p|*߽XNjGݡoѢ ]p'&`ǧ2DȻu?LTW]Iڵb$er}AGCq۴݈`A/=w䊎XܷzEoByq髰A*Q2_ԯ9B2|_42 [n#fۘF?? 5i B9c9 .?‹Ÿ\{=mfCJ(j.v{N>\X7 GͼJ?~7zmq[W^}.ꫯ68 ]rEq{[_Y65QP s޽uǼS'fy;,n:2?QG) %>kwKÇOdp!aRpG&?y,G4?^ 1- :ޔ>|O1&kfio>o'XqMοX5YWx1 Ic/w0Þ?w.i6/6s{d26/{v|b/',u8҄%yLb#)MXXd)/)'҂*,c|д$wNDUXd)ɿJ $R@ӒMJ $R@SI 8TaI%;TaI&p"*-’<&HMKr~_OZ#k2c$D 5d kveU`pr} !ESHƿC-hv2أx!~~xY2:Z0rPudG$]*˿E4w|O?%-[3ˊ"9~ˇ_vQn~Jk6v;B͛7z)۱cqI,|vqw<˵ɿd͙3&s=<H/?{~}}((egYӉwO^|X*r\NE?, '|n1x9ޣ3Qiۖf׿EÎk}Wgjubӹ)=/-M׿>sw YrIf\k=B|-7 =zq}煟fͤo^慆zE?&%qH|F^?7)ZɟzH?nD?f}DOI\ 9_~qJ>)_˨Fm;bv 6Ygfc3 I@d13Xn}C~~!"]CCo _ok)~8vӧ a>؅ v~褫]LgO&۱kv^Vv#~_լ+YիG,d"%Wzu~V],ctqd7:?5m#_},0_ճ+P]w?wJ?Lҿ0^p믊Jntigk.GNK0aY]vC՘G_~%,񜩪j K4ug}sK3ȑw7vv|]fLFS̟/8\W`M{&y%(o9g㏍6c㏍?6bX4}hWoq/* T&XUOY(pĎ R.>L9MWxRB."T|?t/t2Hs)֕eP*@ec??+q"42)J"\Ƈ?Ѕ?n$>Va CU ~qQ:?A;\8-~wAT 7`7 i $UִzCޞ1.\( rʕi$}=V§%]gUSͱ0g⯟q;b!EYM?M/Ctxl"ӽ-oR:{YwD»,Awq`1+&?`Sj׏Z& m<܎;hytyKhwGi;GRFk”;%a~1p߲5v|~ ޞ6܌ 2,":^ǎ/kz\F ϕcP]{R,|LtܚοBMJ7NR?pPjwݒݰ[}j:_zkXEbwS%v ޭ;,z`_dҠza5nX2O}mg?ϟ^/5k.7H_shTQ:X! PA]zm]|EM;lF]WӁϰhKRg˭:FIa"TCo0vjO WG?x$…ғ~myfY[},] 1X\Ҩњeilb|!\N|c]tlO§D믏{FE˰^}8(h+^kmi'f͜ΐw9"VRo"^;vc bP@[uaǧZw">__ig]wM]x>vK f͛/b;5ҷ nT xڕHV=]7XK穽h=~/ob-)7mGzi& S?F,ܠ#|*]wݝN;~OF]c%dGnGM WoHw4m4:_ew^~M5os&Nq'5_OybSw0>׬Pڻb^yWsۧ# %1XCڵOlᡡ#Ra 8lkEQr!ja_i?xHxa?ʠmw!~,|/fQ7ϟy^Hj+ 곝BFRx4Psg6{Y3 iq j0k㏍ί2jYG}xŝf@՜_-Ëd$sf9 !Ǵ|Djn rKX/Dy9]|^yp7TNU7/|N/Kc/|Z; 8Hhl嘂F#cW^}.F[f˭ʼn)vt|z?Qg9!_O㨎4OX>z`w.:PkT.'Lrwم|'! Gu1;ʨuV݄˫U_YB> ^NX&݌_yϊʱXȳ.|קY&BnUꫮJ]_iu֦E Qg|ZW\E*ڣj:ӎ `§Ѿm+ݔ:I~ S^ů7 .]7ؿgyFvdCϾ cYX5yەx ϿqN8Q>5oxR?j߰񢖣v}bSaqpvX|1.]ƎA<$;>ɥfo.}8p7nCҞ{Ec1,+64o/ b'941{ܸVޝB]jcǹOB)B!mMG] <| hLgb!IX~ˎ#GcO xaoа!h}lk8)zIahl.dXl\3uee.*R0,۠ic|=@disZwt `zc_*=Ww{%5ԪU[/]_.bԫ&ymWmaQʼnUV[DU3^h]]G~vNokEn%R$2e@D^?\~/Ӳtxg: ? .hK9_ʿ1rD=^][sk+"X *G,bG"[g_xeqpza,Rst)__:/`綋bqء7 +/ 8cd];xwyJ][{<|r4< q˭ˮs&m6lC첛cǍŎ'_qs/|OÑ?7j(z.>~e73f3vcy?l5ǿa_e.⑇VhׂҩVg|Pʬm6^Ȝ"ݾC}q5ɿ ^5/ˬ|/y ;Wв|jЯ*.N]:cG"$eQY?C#pV쀴&vBqAί(\?nݲN".Y /"ݪ/rЌl #oEm\+쿿ݺ|b>夓ddԥ\3|rgOk|m[0@~+?fx| L]GGoqۖNjS5mc' x;m2lʔ) _h;Fky 0P%`j 任O .63v1f]ste}Ѻuargag$vQ]wdM6vЁ7cNy$kt'>-}'%b-vؑ;J}2?u-vD_\m F@Y}޸vbt27eL[B<Ħ mio,}DU9[I/Un8l9<4 6m_jȱp1p"׎?!:`4O~,{8gVHM&clvJ:[oվ~A<m$\tf|OpvƟux|.ݳLĉ}ak^:l!2Y}ٙ} eINTu[nz{kg Tg9w2 [6mțn*1c")v\{Eek}pK.y|3.WcuѷrU?flxN8Q8Shۯ􇝵z|0f 7O^D=OV۷ @{!,L+6붕n!SDxXB>{oE/g*wGub׼}b0a¶Ŀ- 7\q>uȎ! ;]=D}E!kS]F{cI^YE Fyz-0z¿V? D3g>^q|VC.<x(*#> mM9Kځ2 :[(t]?Z|&ov|jo̙(+*u Cco8s5|rAAb_pigV[o0~-&?A>U}nLzwQ n44gA/DKl["(oӇwC\oO1o>fNj凜'P'^mEBO?toFGp{EVp]>豠#yzWf}@ޖB8}xeJ7 ػ<grw+\@x;^vO^'5>2AhsO{{C*m7wYK>8TnΌ<7|*H<>?lC>\?5Ϡ.DE]>i ^b&^oP"6Ӏ^q՞"t C?1QCnkl|z O#wuENi;˱'ɯpg's=O6cI'(ӦM)؟j0Rv^d]r;4N: A ~Z#8R0[rQG 7K|\aIO.y>g UOg%?K?Ww6݁=Bv v\s\P:RϾo>~PpLq%ùjq}%t{BgIkOLhe#uG~94 m@dI9Y+VRiɹ]T'RHzT,LF@Ҝ??n&!(n(H+`.͹u4ۻ¤+8Ct"Ո#Kr%ΐG*^̩Yf,vR9WMcl/f[عJ="sͭVZB[n%%M&Es?^%?n 䩧v6Կ=ѕW-.%a=HԿ^{ɀ}_L?\yT~<]vŕi]'xB1^(zSNFg^ <Wz0?179jLLǍ TٲesdA0f͖C=8\g_H {V<w]vY<)sQYӿOwhWg1NwAӦ '_~cgz/MLϝ+lKο"iʝph@Pr=z4^ܺ<'=Evv3;dw(Z#xԯc/WR\\ IQ##/12i\|Es}?C>?OpvMGkE]Ƶ3|N6Al|[urekƌ]Vy\úu[OHj;謁5_}nr%w b~WSoŗ];ߐ~2.Brע%x&{$$~Ϟr!~-n ^GةH}~Mg&p=ʉ6hi[ڀcW?~uqc^C ]o6MX56uo.cÆ KrI !O@]k8izscm+A"a.P{yuN<Aa<AXb%)1~'y,ӧOǜlCL2Y5 V׿1®&"Wb-dL'ꫮ Z?>S|adX'qؐ_T(YBpe_{ޥ?Ȣ?ס.I-`UЭ? v_|E/p/~yѯܻ̎l~Z7֫jK<2yW(eJ_(.eԚR9Ep9dCi4y2TNQ)dP(mh+VUR8oɠP0:4_Ex)*sIJ1ZYZ"¹$ ˿,-W^J\҆i_/Ep.IBi4F/KKUR8Aau*KQ)KҠP0~y߻Xo~%\W$s8 2ԯf\DU #$|ɑ$ڞV'lzcnY2cp|-{x\ kS UM~|g+: ?JC=\vGp +,B8—(,}":K |5_^///^0aA@o9^D:WuRߞ]\NI<;1*]v<Ӆ_z9 A8JvC׭[LA \>K+n6U'^|+Sv]v"CqJGĀsO{5m,X 5oPO:4?/U:8m$}. O]PZΈE[o{d*vf9 l88,]/;vd3<8x&xmG,`e2sG;C7#LAﺻ0$fp>lKoEAW6Ι>(3Iݔ%'u~0baiAB?ڠEM[*ڠgzx+F(ʟѵ+wɞc p8)ʘ@;>I-mp_{r#/˞?`F՞?mcm=>@.]/DCbGˮN?;X A6C2E:% ݸo?Ocǧj{Bgݗv}^4@|qsvN?t]K]yz0Ta_5}l5 >,@x8leS}׃#>Q>?;>@]:ls# >!-=VShyfW]Ÿp |J8\pY vA;<[R~/s#/k.c25~<,#9Fv[_|%9jcJ>;eƿwfO=~j6I`+kocm/#)xvX'B{)`sƒ<@`GqPz6@,^$> er@B#g/ȡoOB/PWV>jtΟ̑DCЎ#Jy'jLT/?9EfBc& >q!O7Ty,C&B$2KCb.m]%"H FbcJhZKM1s۟BD0\dVfiZxO_x3}QN3ln6qV*x mY۬A>VƓO |'H=,Sy_ro@M}M^ݏ(s,>3dAdݾHZ^XBkJ$wg#V[}U?Di٪e-ZD&*9s>@ŠClwfx oxqF{=WD )n;xtŮ65xo{ \'`wd=4!<Ϲr<9wοl:z"woz-@sW4Z҉?iSJ:y vlifk.|y;N]dIѺԿ%?v2K$ѭp*^ץ{ˢe`dT/ZZ7 4X_G}j7vo w?}_Z0Fot59 /qmW@&߬ٳ_J~=7(iH&Q7nSO9ZV/~A!'{קO]9|~KTU?wԹ3[A_gI727v"_pŲG| У_5֐>/m]YHKf6m=<= .3i:֖^nIW.Rў2H3h~AnHdm# ؠp,z^K>%zd^Yk>dO"Ъuk9?=zળ'#`o߾75Lcg#q#"ѓ"8;>\Sc^!x*41]_3 -WctǸJOԀS+O?3=t?n)Q ;}( =;h\6ۜN fy衇}"n۬Vn;; ޫ:.D6pwJob-of]y͡ǎ%w_fHJ6.AThC4_ ՟ۯߡCsBU3;O48IkU@IDAThH}؀Jyr3p?<6#o  )|s;GZ_>>&#gzə㰃wL1bxxM5~O ۴k+#G\؊ )t7_faƛnup/ ?b@^U8S<>xqпàLB[yj$ɖ&yM퀯qX$j'@oڱV+u\>OjTngr>l1t7™3x)㱻a AOb$v;厭y4wG=O3g΀UlXkW8K0wx .Ω f ?T4`RO`j߼ >㏏CYF_?)1;KY?r/4) pٙ!}' xLգHtąBdhYU^0a['5 ,R8 ?n(ny)|': RPd|sŽOM5d#RE4|ݡ`(+:I?$Yu}c_+WlҵkWydiӐun={7wL6/*yE"ST[(-Vn)j~8%j8 s [nCkSSuKxǛo)w?Ov$Hݐ}4We,7hc&/xnǟ| 0tLAG+VMp={>os?' ?YrLIVsԫd7dH΀7xC?ؕɿZgcw>>Hco:u|x&äŠ>l*+fΘ!0GHin!oÎ;`'Oo<#sUﬕJhZh)<݌sgn5A37KV6eֿv:(o~~̙Qn=!U 6du֒gyOa.ӂg ~,VV-kZ/5ԧjz_i]]s\txT+vnv ^n5+}٬Y3S_p?)&˔)S#h)~Ϟ9g͚_6WpYkV:w?d'#)Т?/ןPAE](ni'"a`IaVlwio|2Oa?/3/ED u7 +ciM[i1PI5-+|zV5Rjˌ22)gm19iaTZvbS)5)\.J.VeCcFp9J.VeCcFp9J.VeCcFp9J.VeCcFp9J.VeCcFp9J.VeCcFp9J.VeCcFp9J.VeCcFp9J.VeCcFp9J.VeCcFp9J.VeCcFp9J.VeCcFp9J.VeCcFp9J.VeCcFp9J.VeCcFp9J.VeCcFp9J.VeCcFp9J.VeCcFp9J.V)w-2Y:! vx5F u5熡, &x|W SN;Mf+w|&7޶н:t2@-e՚`-|ƿZ]G?; fF0;><m59sG&GTxZg 8_r%?nJQc_n,/u#FnAL-v1]:O^OђsoUlK_\fV۟kww>C 㿿fmoѓ_UmCbs2/LIN4z|>ce'm(TH,2?p]nQU ?v?AuLoM:0k,s39Vg_6X%6&9) c\[n—8AEW?Eɩavh"x<83e\]_V<w ˳{۟ͅpCi׶,\Ph]2~Թ35!lg.m{Qǿ>qgɾ.lBYg]yo~pw5{̘1wCAto|Yns?}돾A;│5迿q/S`Ud'}L)hA}T<2"cd$_*HR3򇺸}F!7(h2"GEȣ=1[A"_X  5dsy5_Y@B~$D;@hhP.ys 2 z>uF7̘ caC_~8̺;>͓R_^.m%8[u;r1|_ ?ucϿ}! ?w?>/|?x\Ld<8 ?>wFʂ3Oߦ H <<~Fհ4P i#` B癇w 4H*=<0`A4Q'CgAdI(OCIZuP0yA4Q'CgAuһK\s%Om2>ʗc9 h6PAPϪpEԚ`x%r͙ߡ䯎>%p?VcϿ}_mm]8%+_,|u]W_yKןKn?r #|Qw|BvFz$ny:ZH2jސYZL&Y_0@&#K"A7d% CT2KIWa\Gj2UK2K량'*(7d?n+ӻv|RcjrPC,؄ ıSp.?t' ,_?r3>toP=̷j&t_1AovoṙHlȅJm%m?儅_O?5=`Po2|yd3DJV%LALRDԃ/O0\mee9dejIEqpxЕ$d3MJ kIEqp]ܸVX҂?{U'Aqd5r.)$>C$'q?p$ky6#d 'hdYjX/+qk=CS|u/?@'*s_>?V\|%Lip/_'R,`_'״AUBʼϿ}o>&K>>YȀagN2:4/4>Ͽ}M" SJ^'n]U0ח7||<QEH9 _(<(4qq j\Vr>V,D/sޑ{=SUTb$?]NzE;Q9)+ *18@Yqǧ{a׺Fpy8h,~": & J'F`1SZ@Ѫ6Q'=^wiѮ n1pXCgϿ|o]w:<a>$v?ji4V7_?~?/:O}f_gu?Š'.s3TV:Ք'8P@=+ւP!(qh*Ā0AdD;yrap+p`_7dsWn7|_|@rZq?r ??“h(A||-L( S _}}]Ų`4ƶ/s浖,MQI.-KV$ ֖I+ETK|@kҤ"*%`BbeiJ0!_1ڲ4iJr hmYRD%LW ,MZ)\&+Z[&QI.-KV$ ֖I+ETK|@kҤ"*%`BbeiJ0!_1ڲ4iJr hmYRD%LW ,MZ)\&+Z[&QI.-KV$ ֖I+ETK|@kҤ"*%`BbeiJ0!_1ڲ4iJr hmYRD%L7'{ǴL$V( /*! qX\j3%+ ђs )pEN-64]s%>_+Q1p @}S fD:UܻBK3 E > 7#"|O>'D:UܻBqz/Q0>74''cj=""P JG0qco.pL)k')GK'o!RZT.p"?hr(t,S JF0y(YK2CWAiF 1?E"]_'Z O."SD8w8͟d`(UjP V#ÏZD\^-&?_fhBV 73k0*3 mf"Q6`t>RR?}>Ͽ?>(B6ZKf0Zd|_|c>}1(|}1 H|1'||߂}ye?,YQƑ9p`KS"RQaG!_"8iZkiJF]|yC TN4)E zq86Xjִ2M)R(}6ÍfM=d7n$}nY#ԪduZ~BhPG+fF S(7.A[X=>&P>Ͽ-r}|%&8Bן|}_}_\_*B |_a}61& ??c5|_WWq?0zQ,#*(P 2DHOʴ,\s ],ETr6Yz&x>$&JcmnNv--uL7pJ, 7GR Y6Ysd_ 2r\A_h]y?sd0OGI@ n@Mp0uG堂/Dv00 f&wPz>ݾ_p432C*L& C$>f7Ͽ9v? "OT2`矔A A5A5QT9`L$ȸ_p*L:' #  X:]*jJRW%o˔,Ak"p.׿#q$ac:ߐZW? _P&U߰ 5py 别ZJ'Eb( Wx5̈ VjQ^8?50,UpO:_> ~Ͽ}_||QgFZ?=S3Dן}ןS8(W_/+6| 7qu Sשs 6iʴ2h0E(qo(-8t)Wwyf!:B_|u/?2ɠUQ F}!hk,CxO_OOOOU||_Թ?k\hg_^u'>%G;@yY7ZK+JRV)JAr.T/L,(+!JY?H@eRE0)?alLK+JRhFzB!?w)eƱqd3\f·I~sG_a; No[u>Oyk C/36f2۟`#a1iaՄ7pO5Ͽ|o[_@'OokG_GpF_}+|J?`ZS|ԉM37z8|FO0l"ڤZ_M#(%U:j?ieuC[Z Y 8??n}o| { $J,SpXƃK#}/fϿ}oߘ8SO:*ͱ|I)>>|_|o_믾믾s_Udyɒ%uخaZ:aLQYI,ʴ 89eU_D _ČeJ zTIK_%t#Hv)bKzs7>Pl\2nUA6*L"N*8&BA>w-8Cؙkh߈碄}Im?gr @StuܺdjLHwys*'|u/?a QaϿ|o_hiyf`H8 ן26qןtן|ן|ן` }ן8 (N|ן|ן| sEE#'0L.OS;gu n.QRTPQLB@2,c U 2`EǫדdT)( W j*z=) Uʰ)T)dʔ!/TLGO2+o>~lJu `bh91gdyxqڬUbfeLкwypKi|uC%u!uH}y?C,77Ͽ|/8_>R_>Ͽu)@H}&QtJ6%>}w+/`#__xo_|XYR[[׈0O?CFAuMi/(IX+!Z6垗SH=„]ySԢ0!?n jg;|MmDT ?RKg50GXXhK*%95s.@eL'W~BV&{(?9??nS_?rod>Ͽ}_#[~J'_R#_Rn%fo_?/4c%I?rуoGf|šÌc 3>?}Ugߞk8xpfGfSrȠG(sʣϝ#*4 h\PdAR:'X T ׿ ?UՑdAR:'X T ׿ ?UՑdAR:'X T ׿ ?UՑdAR:'X T /mvu]7gthp…nNNa-O#h#y!2b˟#(qr xsp+8c!To!vϿhx_;_:vl:DÏȃ]8e&/3ʭ뿴|rj/k@|!f}>YȰhb錌?O?08`NjZߤIc<Yh$=)׿eiFG~8hUU[P[|U̞-^;|rr'k?Ճ ?_SM۶3}g[䜳ϒ >ɬna2ǿe谺FWs{`K㏏?>:Oƌ-Zhc_+~:k%ނE(aNqHi`&M$2T|6,}6fYq'8scǪu$ 4e.!q/%(E?d&>6QD ZL;t$q3! hC %V.>icI|`(hzZB+Z=]?}UfjIfxZuK )LzqnR]2(pB({Rדb,?vRҤ4gE+vfqNg :"Se|z ;A*',\87iT)ݻwf-ZJ#Nq͓^x^}m+ճWO\cxs̛?/USt]O7o. Y(V}"uٲA6?7fxiެL6MN8n=j5t]v߳'u Wk,iߡ\x}2f(H2|5K0>#[z<8o |h)UV i) G(bK#Idh,gHK8--g٤4rԈc RqMJh,gHK8--g٤4rԈc RqMJh,gHK8--g٤4rԈc RqMJh,gHK8--g٤4rԈc RqMJh,gHK8--g٤4rԈc RqMJh,gHK8--g٤4rԈc RqMJh,gHK8--g٤4rԈc RqMJh,gHK8--g٤4rԈc RqMJh,gHK8--g٤4rԈc RqMJh,gHK8--g٤4rԈc RqMJh,gHK8--g٤4rԈc RqMJh,gHK8獰SH,:<20l%X5_JP79^d18C/o]YBcL]wVV#c Qz?Ye߹kfص=AƏJߘwj82er ߵkWvp<:na Aa|WOTҎd^Z ߿( + ^C4;U0lV1y>BX7W +Kʘ<!,#I%eL*@R?aeI#d\sD 2Ҝ]H',)c| k$V1y>BXI%eLVp~ʒ2&GKsvP 2 9"OXYR`iή $V1y>BXZ5G +Kʘ<!,U@~ʒ2&GK+@R?aeI#d9 (OXYR`iH',)c| 4gW +Kʘ<!,#I%eL*@R?aeI#d\sD 2Ҝ]H',)c| k$V1y>BXIiIo>ϦyC9HoQJ@1]#TBjjɡa,u AЂB_z%}|%أȼs gpTWŋ[3ސ9̑ş,v;HWd?,vSz=Αy|Ͽ ) ׎W3AƍJߘ H3 |,CO>I3:gwt}҉'ԩAzc9^mF^~E tzo/J쨳N5_?T i>տ4OP_w?F#`ǧŽOf憙e_xK-^?-x?w??ʦr^н4L5|#sAb"PYɿ /]K% |y2t 1#^@ImjFN?/}.ߗfΜ!uJ_X[wjj]@9@ j=H&Md ŎO>{]8׿sPB*se,v@D i @|p|uH3?nwǟ/>Yt3ta5~ 70i7`fRb.'YLSĉr*S,U :1wC\bW0g=%Ys,U 21t_ e0KQ,?Rb.'(D"۟?^>Fxu}G6x(P5N.YL!:\͛]}HF.D5_Mأ\>o-*sfϑ7ޜV!nxf-B+u>?#y˿3v/>|2$_oD^~'P^{[ u|Yzrǧ2;>GC׾}{dQ)G(cOȡC4kVNuR9RjWwזnMjό7fq]4;>8By' |EЪ *W_ {xz_%Y?O T.}ށZ_4XyU}Rcƌ| ;>9Mb E&P:|c߽lyjI2h w u2;R7NNWɓ'ɩCO)[ZCu~} {{M7oy$_?{X&#T>it7{NPp'*vC"}%u[]~_& q/ |ֱ5kJ ZZl o7,fN+ɵjik) kiZrt]~@]\qt|tȌd1NaXKKu|*?| 7=usikC~+'Q0Y 8=*m_/wf`·tH:ugQ#k<7g&LY.,}?ՠ%ȯ^[57)Qk暲ݶ۩ty߯w~7oӭp_e=֗՚&>M~iy=ɣ칾ݿoAyd֜9 9?&|׆e]q|gW?X_s>-?ko.mV7k*~B1SWXn{d#С3uLJAz[iJAEkq}v}_z"3m^b,+gwܦMя61o]Nofk8`]}727 ѽ;{' NK k~'ݺ~/(-~I>]^g=y䑇eT@-[ʔ)SN^Jo߃>(o53Rlleˡruᰖ_a'=FZ|OGUX*n{7zRVk oq|{]uq:C;T6콱y=Ae5Zwޥ/w`:{iaι sm_p%һWoq<-W^~iq4NVvKi*L dO/ #Oӌh|(4;?> B}}}WgK!_Q<dvX_GM-߄ї7H st04V1(☉@J("c&E*94FR#"P(ZI "@8f"P$3Jki$5(☉@J("c&E*94FR#"P(ZI "@8f"P$3Jki$5(☉@J("c&E*94FR#"P(ZI "@8f"P$3Jki$5(☉@J("c&E*94FR#"P(ZI "@8f"P$3Jki$5(☉@J("c&E*94FR#"P(ZI "@8f"P$3Jki$5(☉@J("c&E*94FR#"P(ZJRT\Vs:mBO.a)R%iOf51 .imUwEA@>"T:uꢲ} |Zv`>5kj7=IWn=t.U\Dv< עys9sQye+rYg…*㎓K?*Zm/>;t5{mfgK.${^{xFvoU~_kIH-Z.w5{v6:$ս[waE;o%;tԶ/RiS83޿>}hQv5m}.^Hw%k߮-v|X} jM">Y'l^JӞ{"` CӜYq cEh\lK5W_3ϔ-R9ŵZp95rֹ?S ׯOŗrr+9??[&_suСβ`9b≡ >(aCdݿeșg~{@IDAT.3geXj>߼e \K ,rt/O@ U&M k2]LBx.?+Ɵw=6Gv,aW_$̀.5+fz:1߾4mR=d?B 4POoS43aL`bv :3"K. U9J_]VOjLLf C-w϶I:]AGL]^xdi2CTrnLX0nhoQ)JQAI?S-LtTx+4@/UW_Nς"֬R'Տzu^dw{NG$ 8?nzMC{HNnpX(ڌs\w rӉ{n4=_/VG^?ʀ(.GlN@LeC1<2bL.%/l/Q$~ߡR>x h"y; Fwzi;W|U^Oߡ!+hjk'ȟzѭ[w򪫵*׬׽JY> 8+XD3x8.]帟m&V^ 9xe$xo&vz _%Z1}9D~Exn.-dԭiA/Θ|ŸVx@|C9Xfϙfva'T8MNc3g̐;Hk=Ffɡ|Ec.U;d͵֔fϖC>Xm=cs?HuwѯHZ4WiS_;fx*pG xcgYݒ4ѝw=iڬ^jkV]e]N['qm-gW4ҝx響G:>j;( .QğtTO"kOB`sp; 3aOf̜`끺|c3y oV^~]ɜ`)Ѷ߾ۯl˖fзݻkYȻXd햛4 pԣ6ǿ4HGgK3xϵNߥk7voʻo4ꍀaC,ŋIo1.H/p.9>CY-oĵ\R(??iSd \ߥsguAp|w`e84>eu׏zٴƎgQ/"yoϨ|-KhcJ.E *.Oc%<cP_ -O`LÐ:(,>?w Ooa=ZvQm2̛?OOT0wPC.@8 |@[+S) |__4sG!rګwos> ;@s4h`;puKI'}4ړiO>NOjt(RUTIR dX_RsZKgJIS!jh!H|AwB_}`v:]N\rXkUѡլHi_F@ӜwySY)X4Riuڄ0$5 & ]#tiO>[@n D;Da<⹘n8|̩NBGH Jf&IlοFn[ɗ,Z"-Vf[ع=/]fce6B[?L%hEequRC*{!xjTzP 4NT<44JlDf|; _+#oA~G ~Ϟ_E~N5HSڔ)2d(WnMY{m8HN;7|3Uy%߸Qc3~4 M3Xe_iʿkrհR~7@ms7^~ˁB! d>jQqk^64+NtO?;mK_+Sݔ"6 k @;dɎ<0?*[l!g!pM_/cԢ8FMl1&Dc71J;wX;XDS5M`oE7w}!Cm;$I<2F1?J_ 0:޳ҐLm;ހAq0W:mtǍr@&n7 ǟx]8dutytcm۸>óE^nبՈq 0f{U?(x>Ow2'M2 /5uϙ߿j9_P0810GC/qSs&`l[n-M/8E+wm19c:&lMOT&s~:t@{B J)yMwa|w^\$_+lsJFð+!paBwE}<7ӭlL^87xPx&t 7'KnwO?;eߝODD?};q9N1?&0AJ?eUab?AWʹoGFK/?`pDm&%⼠/k˼|KF!S\q!QtI4+Cҗ6 *BKrƳ4KQʧz%Ӭ41_0"$]B4+gԘ/mFaEjIxiV(1_0Ԓt Ҭ4QRca5%Yi<|i0 k/RK%KxFI҆a_Kf (췗zл +X4gҍLyŌK G[-ߖR!ϖZz3y/G |1x:ySf[;ВOs>/F.k}wMˆxgIek& `to_̺n"<{[ `̓'_}IÏK`X #~?Awޖx@H? _Sn޼{i NwTNGO:M O/>?2asͷ!LVwe]|#qn;7#G w{ ' OQ=(&$[l  O7#pLaˆ)<|s=f-?C.މmi$W?L?]9~=WG.{/^&N"F6o??nxUלCG^hoc$+iu>!逸vGq2o9mF9w^h{$7kLS X3AO}a^c|҄ [nm/y{IOiE'?]vƘx!0,`Xܸ+j7Eο}d l* (}qkW#Ox~_?b( ަ8_ %4k&jo985ߴiSgq+jhW.F?& )M\4[$ Jѷa^M[j<><>-OkĉػOMľ)3cɟDBhj2 }|i?;h/\A/:D [\&@~K_m[>BQJҶYq @1~,;kc{ʛot u'<>j(`n,W !w hMY.!wp]K3ޜ^:>$C0yy{ QށW Ξ<^n~Ï=,XOOMp4ӝ RlogsaT+(376&-[b,t_.̿5Z.G[5_  ~:)5k  ?oW F<,-GcSϘ<:m&2f]J |]ws|P&x8Htu(h>"3sGBٟ0aWQ΂WA@_]_ h4&ʿ#ڻ>P33o~ (tȠiBH< %0L\kʹ>v ac/= 3V?أn-[mm}ޣ;r'"q>g5{s-|om? CFƿZ(x[/kʽu:xJo}/P?s??K/q]ts <jd~Q@]޸MGtic-geOKTf73cO\MWҐ&cۊ>pKRem覗:&%YuAnW 8PV0I_u* 8v۟`=룏>W;3/c:<>5GfľA<>x%9_ѿ凉qGvj4&L1cS`=/[>!1byu,W__JZ&h I ! ?(c$l1 Q+'(Q*X[. c$l翰xOM?l/Q3>_ NkRp:lA.Z/}#Bٳ#6| ;!t?!{%d!Ekw z?>|.i > gj;Ӑo`Թrxf l$,"t,cgؿ? }WZy%7|;Qϙy!w5W8gf,_gOw@1Nm~#w #BL>|e]AbDvk]sݥ0u m.#?#ǟ=% @ jM YnF7޾Bp  O_:/Rץڹv/q;z`wツql7ȞWnŗ;0R%0"5`o<>:NO7կB@c3Ci%Ia=w?A]v!vm9lŸ쵗?b@ߍE aXɟ,qvXxя~vƌ9mw͕Wƚk9o q26"D).˯\~,r'k#z|#mTgy{grݝ/޻¶qWUi+/t/;z?/}MeOQB<5yBw ėS9x+j݉4FuwW]yjD&Z2"4FaO_OnixgՆoS*"^-@G^0?&(ɟk7O[zF_Z'S0|裏O~qq'HE;i\+GϤ^SQ^;7H`_|/>n7m.,\=ϧwvyg|c %>أCSFO͚fٰI.ɬ44s0X#^阧qӿgot!n Ԋk?&xIrAP?&|!ߘr Dv W2)R&MCao*MçtIϖ4 Uf+{B/ÚRhb}cDeXX -|X\ִ{B kK%ٚazUQ(ab)Ubq1[>L " 2Y,xJ,.fkڇ=VAD|^5WlM0*(˰fZ*iXy,BK<_%5 P>/ÚRhb}cDeXX -|X\ִ{B kK%ٚazUQ(ab)Ubq1[>L " 2Y,xJ,.fkڇ=VAD|^5WlM0*(˰fZ*iXy,BK<_%5 P>/ÚRhb}cDeXX -|X\ִ{B kK%ٚazUQ(ab)Ubqݭ&hL^=HEHZ|BZ8)/ԇ}=keg>S-ɶ^8jw%<<2eW!r-/Y/y{> ӠbwrMăK_&<>]&j܍mej An}w&wC oDOAiK;/wY{mi܈ʵ0~אTS:}k Wf çįW^l}>͚"AW_;iW;WPU6^smwȳ'z |H཈ϹV\]}59=B2E;8p6ugk>ݨ0le0l[Dç?jxx>jB8#gW[gnEI{7t2i2yOﶇ61:4|R%3vkסȟf_~7ހ݈cqܧ|N j4hRĽ8L-[gmK_syb$_~>h!< #/Khr jOܰ#]!'溾VqrW^çޅ' 1jx׾êd`Lu*07 0a8ȭ>?^h/6B{Kʠ?SKf:/6usalٿ~Q?`g/+ÿN;C @y-0);nww[nzCަg#4$fO/ {I ~?s{,Ze6MEwϙ_}Y?|G-iHnye'YksU:??&Eb._J[p_?LOL%…u <+|4'eF\>[A7Ip٪7dI撏&1)? s 6 41S_>D&׫8I_1,oeŢi/c,_6?Nw ðGNQs(T/l@׷ ˓+!Er7km]|1+Ɓ / ޫAm۶uW%vs_#b_xN;M\Me$MOǧ͚W1'__TȵՖ?p;ﺫҥY#&yKOQǟxؤ<}n˥+\]r٥2'|{T:wrFb0|:t{έWW^up'ǧJO:ݵl½kE+*+㯒8}8&+ƭr!C3>0\|mJS&O`Dǧ?S?mzܹ68ӯ `Mc=&o o_EbgƛC.Kg].2 ~E}ȡ$Iç[n%LN0bv'7u޼o┩ ~1߭;{ CW=g*-Q؆l ϭ?:O|G׾]{?x~| Jw Ƞ_2/*~!=:?W\Vn-b{{E` `I9B?FRqp?-ջc>Z Rݻ'OI׹[o5K]wݮoG PU<n>4P_ޒ4T[iԡj{#?v}w ;#:d5Ns[l-n A0'fc= r+g4.Ӌx(Wۤ'4 6mRY86r.̟ XLsQCB?_zkUϛοOikohYI /iJ1~PW'!_/ |dYXgcS Mk$T҇[%~Ix"L< 1taoH?@rkk{B#A*PK:/bMkj5|+]=V?΋ a8,Wj~S^j LT ^ AeO\ qLq|>AA|bƛoCD]E_JٟGt~]Oꮟ1CY0uYMg,gO0]sQ 4FE'Kool7g?g?F\$/[|οlo/,?MƺbvH<>HDO3a=N e̋Ub$%\$Qf~*CF_2i'sÓ"G";$ ԋ 4@ZE,?6*. wR 1w!br!B@}9ɸ{Fe|}Qj11 ;keoŗ ?3#ݟlתr2^/{|wZ>r햛ot&N.tx;K|/Jk=/'w׺W<4 ϗ:}k֬{Ux@O㯺8".^pճoho4"osx2Өr%.&N>D1|ܩ OgO=VpW^3A >x)W_uZ!^N ? Q6r "W_S^qw?FI'P ?~&OǧJ 4ѡCË9t@N;Zw线=E3<}h7oܵiV N?Lx~l+]80jDB6cxx:ce!VA6?ǧ07b:p|b2?#GwDF tCEcቩ]~@}0H<]&c߷=>y/^Gs{72p?ig׿sۺcox{I;wh4t0: 2@_]p[T=(xzQk >r_}indTan5ג^bP]oC]x;b˭f`8>RZ3xE|SNncUW0xnA8꘣ݶnz|T7%N^$~7+0^{\Vt_`Ԣ_;ESLagC]6298ya: /У dzkõ@3Sj)߳w׻OC`d zJ?uD Yސ]sP8WFcv܈uErxVi\9>GM2]]k~vGT&Oygw?.=xt#`)xٹ"-re5>'C1W?j,ٚ/>;|^FO<^9NDoGT?e駞; <۩' ]̞y{TO<@*Aȿh ȃh*T,ſJn<=TM7\k!nnEҋ O_{ÈOzBi3|‹33_߳WOS:܇}lx^;d`' ٧M+βg9v07SsT Xvcpոy_@OOk*0Ko)QL4s#Oq5Ѝ*_ lW [j 'z|:7H.xO?T /T60|S̙iԥ,hh5Ù =7'w,<8x;{p%g=֟Ibfa6e?d!\ "Ņ&&LVɔ䯬ӶӐko[M0G;l:DR1G4pmOs#|-%J#&AK!Hv>C&~вI -aWhVZ?&4Ԗ0kCGQ$C>;/o3:iLCOKO2$Ӽ2{:e|1 BYKN2$Ӽ2t0Dc*З1# dHԧye`4T e/Icut xcGiT7ȝ}ι2y#[{(vN!,Kt"ݳ>VktW~2=^_}]s4>9V/+@ڛ"c;I?nPfPЄ `@sM7I'o5Æҿ<){ͷQC7i͇ʿC p;N2}}`t^ȕ|<_&:wV[~9x&X osv0惑#OOz(aF_}/6e(՘0L/Va7><5$p0aO#1ʪ/ÿ;[^F w{oUt9&~y"htpan7]w6:g4~=ݓ? >*E?'}Ş{'ʬ5BiJ!O>"M؛bj4˜ĊfdOwy/b7gWg;~zۓ=*<䑿XHX~+RGV[<=8Id]٧L) i;H0=[⫆??e__{<|z7}He%?‹\u `ocj'h|0hz)4. z{d%'_l`<'" %FeXK<qdUyfi<7xx1u1zI+FH0HGs}K+n-'"Trnݮ됨xz7oޗn}ֺhS{ ccӧONK/$^"`5xpT+b A HϦS_Z4ǒU2l'[_o f=N4^$f韵͚"q8jowԑЀ?u&͚B?q* E4Q:d&=Y7gߒ[dۋeg5ӯ0\?c?ai7w%U<ik:q2W,Ҵf0$HBԪ C) DDB?tI0< ?1Lb~iZ3Cl)y&m1 D#*$BX/MkfAD8uO[Ԣfd[%Бu omع;o?sP+6lVY !_|_O @HGݴ)^?=_9K䚫rc/ shcw9ga +aЪ%2jܕ0ӟ q2^|--0|PމW!]i/<8z;vmw/ܑG zpgwsu˼̰W_u'o`|@IDATBzw]﮾J79nڻUbW@-xQ ഺxPO R 0nMj{pfn7nXNVY[taXe kJ{A#hc$ Zkvq^~ws0/"a+x /E||(<#1sfNn]w

t{΅ޣ<хǫCUQԽ^#_|H?~\{Gk|}i$`зB[x΃ls:߁,:}gkalG]vuj 'VZq%wᥗ1#s^1}/}ݹT|gSj:9n;w} O4vxc.=CJ%Oy?3x*_mm? GZwYgn$ w0}`P9h@;?|2@*0ȏO?i?aa5{ gD"~1x⟇_/ՏaX.W\Th͚bL19Uj4B/E{ء@2[iCRhp|"~#Rm}:Cv= >C[4F!.A6 :gڴ ;|`\>Xg: [A %|O1 +uL`COQ"ql: A0&)9&*{0_=fjTz >ܫ? "N[O# E3AC?x%_)2B(_J,P`:Nj&Q0<}D8[n¾e ۺeR7tS^B2% u{ܳ*gZ%4w̱NjL|e\R*GS44HE&;YoY8xDFF!m?Wبq߬.e 2_{@Mc돭?<]/~ʹӿD}M(AuғDHza\S |A6$nGôLYY2 8HlP!4L4e1-PJ* (J4ʲXZθT'F_qژE(IQF A+d5klIfJUeQL _?¡qfɗ*}/[s5ܥÆXcL/UǒZ]ŗySIfǧa#F 3<OϺM披g2{|b/5R2\b ߇ZwWw&BFiMV}z<wegw(^8`]ie],çI%.Mqd;?p+ʫ,`Z cߤ x{093%܌o#y."Ï]{uz&ׂs` <+_n/6vn7H> ~:QOe?o 0 O1yFE`5bte&z`]_BDJǟuB3g+28ҵl)@ a‹_+W;pIh3~-a뉗!>,\P玁ۿQW.>?@A?G,/Xv9 x!:^l;7gV4 l~55+^WN;UO,{V%y~50u̞v|0+N}>G;*ˡ x5:HI?S#4B=?!#d=WA`u /OoO0 '0|" 'zz_1򿌉*#Hii /Avo+|E e+.{F60t`ͫT(B a?itgҿ z z}|v⤡C [m ^8/Ȧ1 ~4W $DXOWEx_jWm@<>k?oYqy*l@ѓN.<}Ifx> d+~z'@9 c¹)XTȅx!|FwTPNOߋhdSe;) Xz|FwWbDOK=>JS45c"~zMK*FH4|R_O'Qt"7p%{efFӳUCcBO*8bDX>?3i7:#ue_^ *T?(2Ehi:<,6 _+(Z߆ǧ# W2GNU2~xM Ŝ7W;LY4ҋ/v<@Ϳ]wp"|n\||TR_$ֿj.>!7!L1e|I/d)0kpS6m̒?W,g䯭?U/?MB?lOvUvk2'8}p'KOݪ5?G1$'+1_ E ?T%Ԯ  b7gG6`)cʂʜEd?[+>fIUYP665'z|Jـ_ Z\qߊ%c2$08(IPKb$4r|<_I שB Fz`@rx@c[xYp~, }v1_Ǔ\`W7;]V4z /x?(ߡxQv~k ܽw8c愎h~:&/q^44/ljalX9kwU{o5'rVm0=`4yN# '^{ULF38=m۶  5oOUw^3h+>+"!i|Ы  ך=s0h ] OP'#wjBt B?vhwđG oMŗ>LXc jS/_'ON^=S=?^n΍WvGgϽ\= I [ ^#/E^ʿw폗ī;H믹_~{"Fo<a_ ⋹n}K_S/׿QIYX ֛+rOQ) ];smںAxmc- W{!<-p'|0&uчmߡ]x;lDZjԬ3W Qh~?xdKG~WFVԉ׵31.kwY[D?ORḴߞs.2ds>9U-mEk=\KK6?vðe 7 $пdEn~ee~IOK-)oyD ^g=?#4| >Uǟ=3wI'(]DςDߵW_nsO Mi/F Da)S&`|)C¸[_~'yr۷wc/۫qSLt7xcn oT4qL' Ϟ`tgK?ࠃI#TaN@E ,:Wh`C'/ )_eWi΍\M?udwT #z<} 0-U򬸵翱W\[& qu]C^wxn >uxL) yI1A5f?-?+U_S{%|uFֽ{E3,Ai=5*8S)Nͧ2M67v[3 x_ ^ _{ELS[q%)QOy$k]!l;cǏyA+г51qLJJUooM܀Cq1, }O̓{a SNzy<3 8|܆ی8@q-BeٳM =-_c2z<</Dl*/BW+1d>??߮}a@K۬䃠nU_Z`=?9 WmU?Eaƿ'NZ.jqǟ~m2a,'4aE[Uȟ8|q]8=44;o_z BG{{wѦi 8#aACMxM+?\Y2'/Sr'!LFoӨ 3uOn7oi돭?bȅ_a;lOzʁ韦?j7d8w_pÊbȅ9hAXMJ8Q/dHRSJIhRBޘe7#C&&Q1kO]_QIF'2$7[Mf6XHQCFix~!տU_\PEkrux{ !ps1hFڴm:^uG6UCUa[j՗_ufKHq^Kκn-K+^y*9ހaqG ϶?[nj摇rsK"fx3?|Zq=6!& f͚9xn7y_kִ~|g[ob7#fΜ97ϙ8j!x w1G-:kFq{1yu?&}V¸G ]]6m`6^0-_m7q酂!ӢEsw+_r30*%=u\muWӤ{Ws0x s[Y3Gi5/`/\6s[n%ԭ|1.dW&W4lfyxsho%-`W1d?C0cgv!. gҤJj}na>gnln5џ=Og#K#FCs çGHF"dO(Zviò M0/S ]:?|G9H :?(aR ωG vc, LtRQoJRI4/nD0i'hxQmKä|VJ E- VYI*&ն4LZg%$/^T0i%hxQmKä|VJ E- VYI*&ն4LZg%$/^T0i%hxQmKä|VJ E- VYI*&ն4LZg%$/^T0i%hxQmKä|VJ E- VYI*&ն4LZg%$/^T0i%hxQmKä|VJ E- VYI*&ն4LZg%$/^T0i%hxQmKä|VJ E- VYI*&UJL71H dZ"&;~jw`dk&Ѩe3 W1wʩͷ\߹?LǗL, {駹7Rg{Í2׷Zl7o^L{"YutM 8w-:W^vp + #:2W%ۿ؎c yo3uWjW=z3_zG{^N.1uIdT'ٲV5~D[iUooEV[Wi'nwuM59#[oveѿ:>ۮXTO0_/;_[m7_EyWslˊ!s%L ;?E*_I`_yb 6Z .fyVKdZYlsEyy)Bi׸ [i\! ~l<=)2pH)EabW(?3r):*"+?6LxyP.!Lu*M+"+ҕz|Ob} ̡q]j8yB]f 7s}R}'H/O7?F?r??&Z%oç:79A~'mkl5f Vs_~1çE'vb-_d{eAFZ_m߶XT@:(!e$.6Li韦ivo~/>7TU{6#{?ZTyz]r"_7 \K BpF f_H* =Pq3'GQ1K>2DWۭ[CqI[D[X7=G\?F:͙3߿E?N:[qPPw{UWc֔A9g*o[M-d/R2/ӿN\&KCm M1k돭a_݇?leOA HE .Hb?녽b ߶? ]OY>$VKBRCrT~H2*D,@k8o7g䯭?\m AAЗ0La !ż>eKi7<gX/lmo߶}TaeORAmlio3=x`vbOk?zw;W;W#?/# .Ezr)O;p 1 %XėIAN_((䕛PyF獔">eJXR??&SaH /^ƈ(cWhi# .oB,j[؄ <bMXC|JWDSc_Zu5 l,ԲW帳>>`;gCT~??r"1M x_?L2opQN;^rBw&gCΟ]__ :bOpfOvdOvdOvdOGmSvdOvdOv""L"# ??ΟOa2 WJ.QBE13( a1'W%(B8Bz~PFXr5xˑZ';Lrnpߧi$5a7fK=>3D.*U-E* $ZJy`(2BӿH ꁏ Qd0m3wUL&Y<Ð2rdle/G_7ld3BMTd!-lx%rbv`v|/5 ki/TUTT!Ȯ) sE%ڊMge ǐc.`\>Jad:lLPIgE*Q8c&LpvʈyLH%?C'`V6dJd@NrxdSN?2M:( )ci?©lio;H_ 'yy^C@k&FH;RAa`?Vr> ?ܒ.r600oӿm$tp2ᚢb?m?s]=/Azf}x>2Ksg_3k ^!h` 4g񟧃0HQyT3OAx$(<dgre`' #3F L0O?\nrxA!IƘiT[ԼE?l?L0#d:ҪRPžӿ `L7ΐ<,! ӿm?l,?2ç@^ve ]/9,ԫz [HB  }) -i诔¾B& ^J%_aVrʠ_[L6X8UϤ7|H$Ҡ Cxb 4"2a/[Vl1[eU[l5O @ϟM2̐ߦ)"k1oӿuf蚊0,Кm~Rm79_AP"בTa%T)$c韦%)òb?la/larB?EyL| ç:Bya>+4Sô}krI"*l>+4SC/b !&Qgfj1Za8$$L 8@5,dRD6RhLJBJ35T-ְPIiU|VHi C_C2)M )Pc XBqH&ITaY!*p }kX(ɤ4*l>+4SC/b !&Qgfj1Za8$$L 8@5,dRD6RhLJBJ35T-ְPIiU|VHi C_C2)M )Pc XBqH&ITaY!*p }kX(ɤ4*l>+4SC/b !&Qgfj1Za8$$L 8@5,dRD6RhLJBJ35T-ְPIiU|VHi C_C2)M )Pc x_IΆ( >0tw-֠8 M7W6Yh ь6L`_?Ds2+Gji?lN$v`/r^%t)Rgg;~"1r41jMvfvjE%tOIvBCEIAVstiDAVstiDCEVzꀕ%Ŝ,cѰfyꀕ%Ŝ,cP:`eI1'KǘF4,Y:`eI1'KǘF4Td%XYR1 KjXYR1 YIAVstiDAVstiDCEVzꀕ%Ŝ,cѰfyꀕ%Ŝ,cP:`eI1'KǘF4,Y:`eI1'KǘF4Td%XYR1 KjXYR1 YIAVstiDAVstiDCEVzꀕ%Ŝ,cѰfyꀕ%Ŝ,cP:`eI1'KǘF4,Y:`eI1'KǘF4Td%XYR1 KjtS"_FJ Y5VŬ/_vO.) INB҆o)??&?R@1yӿLgӿ3a)rQ=le/71fo ?C&(!D>C&,AV O "1~"ΟIR~7;7;[oPT)eȋ;j4Ii}d\T"1@jC^^0SA'?O4-cDb*a韦d;l”0FAejOnΟ__#;g;g!`/r*Gr󺒾RE;R^w;8qH$\Sܴ 2TbF>+RjA f#☈+RjA f#☈+RjA f#☈+RjA f#☈+RjA f#☈+RjA f#☈+RjA f#☈+RjA f#☈+RjA f#☈+RjA f#☈+RjA f#☈+RjHPz|s=hDg^]e\3q1"maB9T`og_[jW5DC4 i_f"1k4;ml-lio;kv cDi ӿM6;qĈL!;qVӿMeAJid tIULӐoό+"g㭎uӿL2/ӿL.ӿ52E<>)6[t+jEww(6v|JwҠHK/,`!v Ұ͜{={˂sY=Ԝ33'ޙ;J`ȰWp9D~+c?&7T#/% fOM=y!E-f⋳gʟ'0 y$!ܬ'ӵo oJ7evr%UF|a ΛlHcCJyQ]_Ps/Ǩ8m|1nyU?Hf_;s0;/;t2O䩢]\82a.pW?8 o{`oUV:SA+u/fϚ8ivOOw]vA05dUi #+j߸flĹIp% gsӏu&n7 7 ? b04 h6A7`(`R_Wt )&|n H>r*nKjew™y~s9»o2ODJ͝JF}\'`=pxKi"M[ƍ%$ iɕ+78y3+˝+'9{Ο;οLFcvק럿sZ_ҘvCWnlb߮Pv/g0Ay+_/e_viߐ`_`qH'W J8%;3Dr/{`nyR،2^M:RSΣj^݌fv3r7CW/W7e n@l,D2]BޫK(3 ܀JM9EBޫ(fv3r7?-^]F1̰ Ԕ-$u,UX'Ȕ1ZVꖚM7U,mڶ5v6|ˎ?vaWG)2=4=$jc? 5,|KJVQnOlՕ v(kP);}n_E Qw"V7\yy3@IDATԝa?b$N0(%1 4ܠ(*4P\. !/n $PdOL?a av ݀0R&YW>M<ѫDssr8v.}`T]f #d^ZQ̙Lﮥ3g4or+)V!/Yr9|>kE -]Fckb(2*=޹zRL۷0R߿Mbba\>=ݻU_j䨑bXrb<5_uuAh/M:UrXb`dڔF܎n+"m6t'-/IDھ  7nBO~=FkGG~ECǍFi8s2f@+WNb׋w]/FO`t5|Rh^{EEΝ;w&[Œ L׃?XzA{voq"&oiK;onڼ{ZT769j*O`RG&ʕ)fB5-[cO<)*{|SZi@i"{L|]==*Mj=9|?<-VG ,B6|RYOG.LͰ63&AK3fޱ_3VL'uYnc_;/GL@+f[ )c&>:H]:*'fŋӘP|7ߠ )L-ZTlBM>qc$;/޼#i۶:r0+Wnxvr}z= .ŗJ[193At򏓎+/]Dۇ=>yf_vS2{a;+qo K([\egY1{ˎÎv21ovcVF_; 'sH13dN$/&Fw4nt. ߣI- I&Fw4nt.ABfn Ɂ]=ͻ[KyP["nr`~WOA@RqT/d新ӼEйT %/&Fw4nt.ABfn Ɂ]=ͻ[KyP["nr`~WOA@RqT/d新ӼEйT %/&Fw4nt.ABfn Ɂ]=ͻ[KyP["nr`~WOA@RqT/d新ӼEйT %/&Fw4nt.ABfn Ɂ]=ͻ[KyP["nr`~WOA@RqT/d新ӼEйT %/&Fw4nt.ABfn Ɂ]=ͻ[KyP["nr`~WOA@RqT/d新ӼEйT %/&*UF>YSS_f)n P|*xS)퍫HI]Z ? j=/^HmMgϜC(=N A;On|n隓'OЇozxkZbAF<>r5 -th]0|vzAϙ3;M5|N짮]:VQti>]bçi!VXF_wdç'R~lFy|Vs%WsM3^ N;6|zgDt#$׵=Q42dkE&AzGYW\kOxO6r&V8r,5îӎ0^IkK(4O5\ReOK*UZQ4WԸaL2ٳg:w{Wuh#gʚ7iyTF ҥ+k]Y-^ i0|^PkP Y{eǮϮ׮yΥkb*?'jU_[S3"EI+VXkտGS?jw%O ć&.UиiQQT;cNRoe!AK4F?!g5Vi\[ a/oG0X4FA տB7"*[խGYйs!8}'qFxry}YU uӹǟ|XY__k֬I=p?ɝgHGOô~(o$/w}!~ifO? ~q3M6n=S4FE+G8(YW9vl.II)JO>,1?mL׬{Rҥ`t֫T<TZ5*T ?nДEX,[0|b۵ǧ'~?+-/h,PN} CA  4˳ ܊8g^<}׌0J8>y'|@>Ĥ$xGQ= 7܀/gG~^@w]wS%*PmݺMxNU+ÎL_Љy^=6:~+{ KG+(/ѭի]:|=e͖5j,}g-o/mt7dɒt ?S ̞3;vvcĕUh}+vflԨ1`ڷߢ_KZg;0M>dc>jҼ)(^rN_?pjѤYsʌ/z:xԻxm *Vw'(Y9 NmtUhx9eS%x %O҆,|K@x=Ե]ǎ?vM(Sƌt <>)Ϝ5{:9Po"ի]G &?ۡ#=B?Þ1h)#N}L6LeqOoҚX  ]]&G;ߔ~L'kOfL /߿h\vCIԴws1eF0I t:?4tҍ4͢f8Y3ň?F&Z~p2n3͢f8Y3?+V@aXcjMoF wtvR5Y3"r,7dˆ(>< gp^1 gAoKIUABʭ^mX*U "N׽Egβǧџ{e<Ahu4&:u邏Dj& 87~8&kc)}d7oF'gE_V0&FOc^5 {^ƍ'o¤ITP!R|0|-T/ խ >0F^ .O?L߰~=M2Y1kBWvԅ"a.vQxg:TE[=)=鿍ޥ)SbTݳςC5pt7oH`* Vd(gيҷ!Yddž`Æ aa\24e՗_p, ğ33, :)0;RMSU\rckO--/7Y+?g׿vo?wʀOW?b.JEgh֔?>zj4ŞO*7V4~GF@n^< Q}gP W O5gL+IROڎ?ve_8/;ώjہ*pvo=S|KUHA&n hRT|c)/iU݀oDHP/ _сhj~Sn F;WtDSS{3 ۈz;_,y|C)=U݀mDHP/<>!*Lwn@6"$Η?EITRec99i`Dsp˵r^ʸ\1 FDD$=/޵6-U_zB>s&UϘ)U\Ѕз|}п^tM7 _ǗK(V{q:r͚9kgΠܹAִee&C*6 0~KmիO?a0axڵ{7ebŊSܹ`l3EQ_/a$QQ/Hpeާu;wJ}4"X{J짜hRp*#-;֬Y#)}0aDց_x =O"DaT gC=Ux1vC/=yq$A 1ݺ=nf&pX5?+07܂>M0ۥD_ e( ={9~(;7{{Nq`o.Izv,9I޶ tR"ؙn:t\yH}q N]T2C{́ӧaN2XDI?&s^{vB޿:{p/xy<,6I;~ȐDʈ2>1Y( I/c"^>'6Bbziʘ5 0N³xR /Yd-o ǏgA?*TPE w۷kDž {<`:L&Y7Ó'sE2g\t(f2c;{Ϯ]0LBEPQ졯) b@C?l \*8t8n RA1?6mBΜ< σ,K0ls&ʖ!HhB@!#'8ѿZQV8BgωB2>ѥ#>/[BQZM4Q-x~ >te{$ѧ/ej^N:6^汱~]5[6J.ЗizoF|Sڢh<:1,[bSǟ|Zl)\wnקӐC@Q04ٹs'#RfϘ̙m[dsNxu>1BAl| ƌx~^ȗD6l7IS˖m,ٳgPe49ŋ)}0DK *TjUz*Z0WQb൧aӳeB̓*0Ct5^zO1T >7y'ӱ5Pp-X@7F|!WݺR֬Yi<EӧqV.!eT_p0(qK!*\<*¨{_oUFb*˓'F[`{c4+W2=𹍍7§I &ϝ;O=wGaD u{j;g$?b@t؈(ƍ3:#a#%q93|'1LxM0oG_Z5y‡>X\ÞNefp=E^ o;<%G+HZ| -_*HK- QP0JHP_ҽ/\(M x-[Ga`!W rRª4Cr!jDFS;`Իe?fq6Tx%װQc]cy0xXLJ/IǍ* cM'{ʔ+KG еK'8yXrF1eC q>M]F118E\_…)^jK`8lc%xi+-]}k\?bh*[ J2|G0 EO!=ڶQпHѢ0| -] >M_q1 #{'Z{rO6W6O4 (5+U#aL ϳ0\:ƆpnWo)X)@: KM7riCfEFѥDj>aus"` H°L^&zP_l)_Rj/((5m""d`ϝ;ϖ#Kl8uuƟc}T?uH ߤ e/!%u<Ә,-,i)cR lϝi4w)#<OS!CG\ew!>|j Ͻ 1叩p/=r:ó`o]l9j\_|FΩN}kb|EXW‡\4pPW,Dؾ_ X3y9aJs"8A;WtzXgQcGտZ[`ӎ?j4㯝@0п?hɐ'Ǝ Goԝa;ǎvOͿHƻKҳP:؉ ,f5=l_TD0x1@c̙açzJhBNe l(V%#N5k[lOa пOn=;vٷwx !;a .pm':b8/_whаPAj6s8vZmK=v8xv޴b޼t2^2'f͜ . w֬+R U$g~;X_V. !hxTJèLNݧC L)]84j۹Y\&Fg`p N{qԸw^'j+_$[I0/#ؓ@ahfj1 \gUHQ71Z/K>1nہ@zCSEyJZyh1TtInmGG%J@0j٢.a,F{sT ܻT[Q)c%ve矩g/xk D䫀?9ꟿS.X2d@Ν:(Wd)5fJvz5kEl]wڷ-<]Ο5kkl߶^-QNwnm*R['}֛&$|61<"ӱǧX7?w ēSn:8<*V^m oxΞ:éJ[q࿈t{|:}:Ug7VبK'Oߨ"(zDᇥ˖"@+ Z0 @<8^iвUf.̑͜I8΃"Μ:C|͞3/@Lj`)_H O)gΚԭgcM'N+Wm4 =p}_ϝ#mt/Ŋ8i=m׎TX1?l0(0s,ia/ Ŕ!}zǞG/U49Z )+24jPϕn?ޯ[i'Ƒ/n0nYC@-[RpjNǎz1cR%_.\ x$Жiӧu.  oբ8,Y\ї /QcPɒԢIcWժ hъ2dH 9sh͚H.X #1P|!-tSCg΢ i׫M0&4?cZ1OOW.S< ЅQ0|: çnjHNj?ӧMw'~]5rʱabdw~=k6m ܶO˗9x z@Mcd)?wB MB]ѓpf0 /~pYɬ`4^ɐa썌g~PjH5zԳWo{5/>;ӽ'" ~T ~z C {ɓOp`:u4:z/Ɨ)R/[R^h=v 49oּ9 oK ٳ^Cl66DeM(YN9gQE>W U$ˍ?P?@-xU+ bcDzfa?i.G(2ЁC+>WZ>zluYʔ9#kh6('SB8WQ*̿ٻ? ? Os_ЂXӥ㖰ǧH uxs.;](5d8q%Himv#,\eן7k_;jk_;[^׎vX[Q؝eA.4*GoF~uA]~7#hdK?ZQƛ4_]PץF-(ٯ.OfWuQ?x3F ӨeA#u]i2ތꂺ.4jGoF~uA]~7#hdK?ZQƛ4_]PץF-(ٯ.OfWuQ?x3F ӨeA#u]i2ތꂺ.4jGoF~uA]~7#hdK?ZQƛ4_]PץF-(ٯ.OfWuQ?x3F ӨeA#{`J0|Bگqvmx|<ߠbr(F R'\^:A[ O8a.#ӎ;EbŊSN!Ν;"=zNq4wlzHO tz+m׎rO @f0my5[6Jי4jH/a|;10EO$} O[a=G5{z>F B_}?c*= S7ɔ[n^>A 4e2K?lvR<5_ו)gR޼ywՃG ҥj(q6kO W6ţ/r ӦQ| 6"6eg#Jj">c*qC` ("2y,g Ek3 _jX rbEc{R"M:mAD^6^ ./ZC+-KC>$_㠓@7s}|i[㏲5qk>S*Ԡ2+0 j\Bk 稨()A'1c}/n&*)8iY·N+JO>}m aLqhz4>cfM1f0dێ1oo|%_9I":I©?ΗZݼ9/$a Bhfƣ?QlÍ/YLG,.+V.?h)cFx=H]:wdZIf o=r$MA??>Sc͛ %{63k||>ҸA  |0\rP$`A|u(U0|`'S.)/;ǎ?z,C4׿$lv9]An?,ݘvXbOCs 1#5o;?0bN/;F_b}эčhB7A7.⽘թ͜ Q"Ft>YuARDYB8n X,u>s^o$A7`?'#tD7ݠpz1I n _gYeI$DӼEK6ooE m%TgɚaO2 K:FM俈pG`tq8 ԧ$<5}Lڱzˁϐ)3U^RJIpۏ_+N0_~Gw?x&FGswKҘEz%^ f+ aDa0|2_çtѯ{Q7Ʉ;w.15N#GLg̞Ms bO~|ڵa =a_b%8O߼e >=őԾmKx|:Te+0@tu },9>gҟ1W(槻:Ȇ(oM2E;rgçq>u.[b>3RCzorbqIG}T3([t@NnznڔŴP׸]tFZ"[B _à@\q/y3gVp+#Hv3=!FiɆO#Q'|5|eAt7H|۪O'q&xaAWu@|_aLԡNbvi/sk0eFiuwd[iQ O׎?;rb_;/G=pa׿ 7vT`J+z@IDAT ?d'GM}9ݩ_#uX?}|/f33y{b.LΩ駮-auN \渂s?5):t F/!{3saʟ?+V(}\CXkl|z4I4sa{)WF Lnԯ >17Gb ԀΓT-HA獏&*§~abE9Lʮ?eu HlO+\/!0<\k/\MG"~p|3UqK5}; p.z5ȑSjz׷U i̙fz wlڭq2c&ˣ"lތΜ>RJGc'x|O U>f5x|b>l>4/\Gҥ*)w]$?1:ç8xpmQӫWi/Coڼ9=6b')9|ƭ~ÆT.UWӗ0N2/%6Ba7_}d8H+P/YMR A5Gߡ}[xgMfc0ԺUs1;k%Q υ7 {|bm2w¤TFo|AJ3(<12ZΞ>͍{9G5gjs_= ~v'KaC蓴nUy);xj!7ed0>[&ulYz aC7|%P :p.yңBxq 0|:t`|ūgɜ-/B>,ȲxRnbbW^'>: ?`nwަ8ƌEo K'/XQ<x"DJ#|rgAX: DML^tR0.+Fjtgf̐,Z8Ֆ. ~ ٖ#//#o0ñg{'<ѭ;/I[n{POxe x<>(˫!d(?/ĵpXrgXo;?xu9{8P3+j_Xk_;׎i9\[ +^'FN-7I+ ܚ--i!r$C ьf.[+Vi1̕O(7 ^-?+V8!WJ=>$;=?#,|#U ^u9¡YltrVN%U8E`*֩9RAժxӆwߡ3gϠGAI=O[aZxK 83 i@ė_} A8(p(0+_~6(BKh/7ZTA%/؟*WF_G?oYN!T5g<d?NeKy?JשLzzeHo Sb%h̸qq^='*4iO?Sx_zm\ IaO@1,Z #6|Gݻ)s-ـb4oڄc.uH!ϫ. WE|4Ky _Α=/b:<ɇ)zx'O6C@S {~ܹSH.]9m۷s t,u^w6iMv:?=x հg"A$Bvq-BMAY秩S ]5nq -僿 6x0}7(Ε4a0km$/ahȗ /cӔɓs'UPmvg0uĥ:w/CY>~ r?tݳDZ0%5^J؊fS, %4%7_~2mn 0WՀ kītȄẖP@`s {Ū.pY?xIq0Z6?OBR`o02R .w% n?;p9@SZEr'?g^;O3瓇?Ŕ jhg_;9POv9CV7()j$?t#* ,",|KJPYc# x(ǼvЃ0LՌR%J) 7> Ub^@y>plpV0PJn#wߦg"q 摧S8rq.ypn왳~ZtصI>X%iSO?g#.%K1c,E̝Zʔ-K 57@C:rh#e˖Ӧ?@$, jU^=q(G׫? 0(Yr~ssèe75O_} .18^!݃/EᓺLO>jڬu{!x92t K" a>=׶3Ϝ9֢/Wzjު|rZ$O3xH֬y]а#x  C6T#}c?QЂ .ᆬaCGL1KvK{t༣FqhkSFC!ZvJ.&Sa/>oߨH\͏{GӧLU?ԃ';k֤?DSQǼW Y:|ʻ.db4:}4;F._f]xY)#}&F J'O,/OwD/2}h!ySbJ"})~ut[<ӧMquʗvWG_xLaxҼ'x ={|Q#vx Ok㓾L[iC=6jmn豔-WN^?+TkB_V0kZa,wlxab,],<)eVLmdd86ZçO87.R=i?c(LG,C?zg+ZO2d+_>(kZvME{'|p @.|^lՒoAox>rY}yIQPL <~2zZ[*K2y1e"S4*UtYVXcO/Ltha hrao2~J#[Re=I烈^П3cӌW޹-IBN^4bZDY)ҿ{|ޘZ:˞tXRO9v˹ޡQvу=(80ч>kӶ=ͅ#{w4p2|B _$x2rxM_>6n/$Bޗ%JҘlDTX<>1^G[~B9rPO8U>})PMq *Аa%?[@'!!vLB sϵ|PH}DXZ`$Ka BK hƪ}G=w'ʡ4<*Ȟʠ:S+U "-91|2W`Us9:x< N3OCs!T͑ bE'\0^<+!8hY;{Nj1Q֭ -^DأWoҕ9 gMOX>UCCa׬ ?^,x.;/ѤJ _sc/6_XyёS6x'F۷h R]*NFH0qXFEA^iarldS m c+tObK"GT *FH4i/P2B2&Ot1j`Ї=>5a/S|@sy9] O ym/׃S}Ѓ{K_aw4uzʿƟ ?識?SR;,ѬR+rR, b)S 0|Rf({U%wgӇÃ87ǟzkXHLK5'-ռل%jݪ9RR7.:hg'>ׂ҇AX9vJOa`VWs~Zg?-ve?;O?^xIaWtο.GP;;Hi! ȩ/xW?DJ1 `FY7M|"^-B 1YFS.diVXc/x QvkOJ7 :lHiD8';SsÍ `S A8N*|U^ϛe[TN-UQ"E´a<>C0^.b( 1xۯ4y>ѸIz(sL+҇6MXUk9sFIc>  3ޔN0k 5{ ^\bwi4&G~ 98VJ6"ECT />w ؈W4GE$s0d7wmX9?tp*_zA{v@Y5B=Ӿݻ)? O&_6|ڲeN 17_aTPA|uzW2$~Շnr 7$ ɪ 4.g)̄x(d`(SL>a|ѦW**@OeMx+[ =`L8 odM7R˕-#B0fMM%Z3@_4ʲ7ěy 2Ø#*//͸s7VwםwQkQd͒5YsqZO.Jܹ Majt =6eB9O=sNz~b\kW 7hYoH;]ZK*'Ž{$n~yiRӘ2τG`"u"I krе^_6M~L <q'7 ͋}J"8uՅ{6SYg۶c@^f8| 1ᓢKW_GB"wZޣ^YBb9{ RDl{og" *f}ħ>qޗI2I6LvQ5)U1HI8Mb N!lS͸.ߵ?\\_}htOd9eHlOfP,)W s> >1'7aMڿnYKaS\b=ٜ7gl?'ӃWr2S?o^vO0M5ƞ?$K6>[1LyYйHT/KZ(Hgɸm fIQ/-j&Lf>:w6DihO;Ϳ6oۺ0Y`#ǭ?o6a[cYu%H8KHĥ]]S ϕ@69|c:W‹+U+H?>dKUhw&zoh$4HU&5FZ36͝;fϙM|oM6Fvx1ߠy4,i߶Z55_j'Zx bW'5H-WJec=唞W^~VKE;/OU.Yc_^C;R)hB_^>Cihg䧵ϽngZR*Z`!|vFՄŸߒoԸ1ncR>>Kw+Wsq*ӶN:TX//yqF=ϼ7ǧ(ᦋuw3_(vs`&*TD'a7g=§yծ]Wx`96ˬ\*6po$MUWHTۗT7x%z記mP V㟦oeke&&LD[?c'LbgC".+6kSkXy'-5Ǧh>:>=́6|@ڟiI6Nmehi0+4LLPjm_ _W4t/y ?l l2]L9/zʯykX?wJqQJTQmY _ lk_`+<)BI5s!b'G߀(1h^2"^c'bӿ1W$)KV KX﷓۲ GP+؊tޔ_˂?U SDFNJ>E"ry.z8R7Qh=U}?V~sn{Wz6Sr65W)sl+31=4hf?{Klw_^##c"&x0'R%C%m??cM[y#׿^~E|`5׿)R5kƧEٿfUٿfoOau`_7Z2o{*̓C_{?~w[MY N|J>&x+Q$ɬ # 6LM2dѓ?KT/yr$x*,-'?vʤa:%Q$Ic򢛻<{sͿL?ef )JT"Y.#7۸qTc8X=OdـTx tEpctDJŢnVhXZhA5kՠ5k믿agJQV9NݪYn^{?|n͢I'  %f`LÇ8in`&eswvЁQʔ--O.EKKc"3_?˧_,MdN䰍c?━`nVaZ4? rd0?r4c֟Yg)=[W?`y/=0O?#֎bC_PPPV1d:\`%ąBp[" 8Օ<W{\6?]7-ƺ 2!^2ȗC K#$)e|Ԏ+ZF???#c#= y/` !le$+Q43Yoiٟ^/ܢcSA\?6l ls ?Bt_ЛL\<,;f돶r:T E 6ƔY"&QA?>l l/[?/r~%Bf<ǚe'X"?f9aOfm\Y".ywɍS+Gy˼܀fKJt xTAhd%j#g%`'(G1-O#9$#khA_ӿJLb?`amCTI޾}fRD eGYRWժcP<`4ٵōY>42myc@ۆ</ˏuzqBek_=,g2???mg:=gri9O߶`/ 0RpSkOf돶j϶n=r>=o͞A%F?Fİw[w[V?;x`XO|Ed yq9܈98!46';܈98!4sR(72s)qC huG܄Iq)?'r*3'=9[7w$M̜tJsR(72s)qC huG܄Iq)?'r*3'=9[eD\e #Zd1krm|ŋ%.,U(v$ ]iK@Q#./Euy !koggZQ6̊_l B?3/?O0VuM>f?@6/?4_ `A3ռKBYf}IcKOr* =9%%AZ`tF< ]d,ڏݥh<<,q*YZFCFuW"uY(/ 疦8/"?@0L8YO8 )l}wЫ~"iYɏ0]9Gmj2Jp#Hsui\a= *nLLxδtp\@ 44l֟ly-%W tg[g[g[g['{f=tϏu{*8;@˓=dĪ3Ł)[9d-ನ1!Bb%`O*I:Dl5JoÝ$=Z,SuOQ–t]?. ˲ F?ȅJ0O1zW/ӿ6afb^06Ƒ_ns@`(|N "񕢖@/?yy/?0O?! i2/e_PCO?f2r !zKm,3$P`ƧR:*TUA,3waP,C!">;qriq1b ,waP,C!">;qriq1b ,waP,C!">;qriq1b ,waP,C!">;qriq1b ,waP,C!">;q@IDATriq1b ,waP,C!">;qriq1b ,waP,C!">;qriq1b ,waP,C!">;qriq1b ,waP,C!">;qriq1b ,waP,C!">;qriq1b ,waP,C!">;qriq1b ,waP,C!">;LnѺ-joVȫ>]}κgLR|7JbF,'+TnKԬdMvY"Y&DgZ?6V_fyd`4~#rʔ4IK/[[O[[7[WʿI_m_m_mmm]lD]dUwζ#&iI{P?Ƨ  T)]dp O%r QRo s6}!Q@KAzAry Ld$qLu`1@)Yɟӿ6k_fm_+xS[4?[wGGqKp[N!d{bϟ=o͞7#!8)ˌaZxt mI<YxX43Pk_h. }Bn) %L03 Y³ɟl@R~wm&&<|',<C::q!</`^`yQ>>owdgg?AmUAB?&#[fm_l϶hob1?חm&77[7[n`m# h믶l϶l<#87m1zWx^7|*ܶ}9ɏ;IUCTHCňø-q=A.ο|iygƺaqZz@]~L'4t ]Na(~ /_FG㿘OP).';H/?G㿘OP).';H/?G㿘OP).';H/?G-Z2aA(8,p}NA2(MP< tKm5ul;?[LŽӿ63?2o?%]69Ce'{󪃈IupkZjGʔ fe^{QVdƛo}c?[He%`Lfi}Imڶ+VaC6Y+V@6~h%׿?UVݩW+hWH^I?_̿-Zc>T@GիVBzYLSgdFېbd1[TW!q`?f  J_cĉTBEKu՗_o59x ͜ݦ[Yb.m^9rըQ3ٟ}Fw_Y gELT?k7fQ7?S06l-16cٿf{ 39<?MM\O;)/q apCdd ־rJ! << %'#;H0IFyC << %'#;H033SqJ>#  /-6O6>b$J2 "aR !3~ICeu}ˊ ' QN f}Gވ_re{ܳOњXEw /ԒbzwK,ppfͤ_K,~IX_TyZrZ?/b hт֯[Ggv&c2W7q*W-\zd/-7r;5mڄ^;u"ǿfZt'^bgΤ'ڟ4u /[iNgՍV,_!4qd8W fM{ݺfПǿRJTn c!͙=fO p%-YtЏn_{`DwՓ- m7lH+gHq5L4lm?74~$hh)b 4bw?vYTj{~G= T:åT=llA3 +Ÿ9ʑI!Yދ:G=S+M6TNφ+O?^0?7)b:3gXwq?kxwv?6a_?0C.ٮOJ[zՑ+< YR<BƳ^־8izhzjDeLL b h:1332S@eJysP~}W>  4]*_a-~8y*+[.Z@zpcSe[n4mJQSl|J_9&8=bhgay ۊߨAz=Lvr:}WW/:say'7mT2yrp3=dcN {xlߖ@3Z90OڟEWoy?E? |/ /pʑݙb.~!:Q!ܦS}i{G{w}ye_*BF>]xE~S^),ttԵ?k˖ٟͦqs>=gy? K\*p#HX1+??6=0/"CVۛCm?m/i.tAAA&Ko8 0B";0H28_j5[2\oWCxd90HI)cg?P6؀wa0ϛ[r6bF2Jw B8*( HE\f3wDFf[2N1~qqժ"韗_8*]o嗟/[ OqA 2 ޛ?WtKƧ1vyt%6>P_:h!2Oxm|*8ߝvjC'v8Id֛oeHeYg%_!׭_Fg /bTfqTN7Mbqȯ%6H헯P=h|hklrBxjwS.yWjаYʡFz!C^=MVJˉOsħߛf랻A|Zua. X?boƉOMqus܉OgƧ ħl6>s,6>:3iES_Ϡe޻⽯KA_|aNSq 2ħJ>jt?8͗S&M?Niu_?d YgJߗ?aW d/g_$ 8*V@K{?^/jݺ5|<4q͜1=<|DÉSe˔ӥɉ{K{clWj+;ɏ=;gjXt]1(O1985j@~xI8(s,}1?)?Ș }_M#V6Fs?(6e/TA0/8cniգ_h-*~K6>1uY$W҃Lz3qd정 1s'Y*=`ЌB曘:K_Yr$I)I2=Vb퇴HS?+ur Ӄ0I#Q~dz&X"p&B,$ӃL:Eb㓛D( O ~e_/^(rGjCEyxKŅ\ZƉ~Hl[~;Zzխ[t*g|VEiWٺ*p!2F~O8$^ƿj*{ ->_1F^{KwU\{]Szuϙ=^}J_~:RVqCfQ}YƴF6>'TԐC:r]q Fdc%㚵kӦ=@߯X-H{`*6J(![nI8B֯_GGߎרIU*oE.Oo-z镗z5i ӧS5=؝ʕ-/'y״Y3:䐃IuժҥGI? x窐YD]}5\ɝ:S*Ho ~/WhʕTL 6cRqu ; ccRzp6h>c4Z땦ܡɴӎmv]Ds̥Λݩ: t{%_`}|q3hW~%1ܿf;v}7S6-^F?u<#*ϧ0hyv:tI, ;<\~CWȗQd:N=d=pѭ_-x :ms|zf? m6>zWhmh[l讐10|=4!.}F0K1.ҿ Tk˜~quW`U,N>LL^6Rq\?c󯣃vK?TbZ.^׽Rm0VNDSϿ;CĦ_{o?O6>1vۃ.l|dS~jѲG^[nY^m+Ҕ)]>6>>Wk3/?y#__l?5M> Yelɿ?gS,o>-}۰a}a~~)r)kCM0WZX&sv9~/B`/NdIKGzLJ ??^eӻv%LKTʉOFZ]yT~iFLBlT*o^L.vuWؾ=ƝUoByэ &S?O>(.Wݝ QwƦ˚<ܫG/ZwzǦ|CmQ0iSf@m߅s#F5jѺ5?ӏh*NKSpSp7ߤ;vc'cBB!&!g7+-uOpA_xA_rJ4Nt ǩt?r0 [߫_?g%ϝTz#EOk #GkO?Iwk翩Sħ1$2/?6olѳ-0)`fgf,){yQ$0P| }i v<2"'y}i־O( K0kO$x)AfθaЗ`$Fv$ />]g]yb|+P'@|KF`P1c},6y8MP{Q:iLY!`HVvK I'r4No_zVʸq o/igW9pԤQ#߭JG1wӼsG):ն}Gk~>SZ_H'R;+{I -K.b ũ*[mUഢmUpr.L"PqV-Ӛ:!?sr"+Naش:hB'1U >5nXaK.&?`[.%NZpl{h,U*NG=GO;R;\2ذa#A_-Bt=cЇy^+fZ]~@y>O㏩,^*l33g g}śآhJ 0Gņ>.?s;h.řVU8ճ't|O&N'׬]C!mU25k #W@tMD3WF:nS|'Mot7nDzԡ}FIƛo{tA(orҏ32Xsɟ܋73/1'@ "gPthyXE\hWlЈ> >|▿8@l|.]80l|bS>}qR0o|GlF|7_}M>FqܯyUR~MO=.'2@/vRSN}ٗ|{M ȥq;_?,kXC]*/M֟̽$|1ӿ6`5DԃͿ݌koD [q`R3loy0[ws24y44?'OYq;+|9ܠ2K␃ABU $E&, o{Lf(1"s`0fl )%c;$<3ߞhi  ]/YJ比 |qx2iQ[Qؘҿ>^Tn=ڀf{!lD(Ƨ=@ϧ|~&)iR^Rtq49K,CM 6S&OAq_w N9kWf#/Џ֭]'}-]:+ 5k ]~e Nґe}=NIGΈ7mFjkҳ_o7{K@1+AX&+#ɠڵEBlHra$Іj*z*6QGM`CH'Se'it1Rn!4Os)S|4v'>I1饗..Y3iܸB4J|N ukR)ǽR &!X?\WmpW `x3f̠I)}>cOt66>}t΢qjV%`'1p _ .=.ʕqc=O]G%Ϧ&Bz7n[^}O>E?Dc'kUVdoI _Oz=M L8a^ꂱ=j_n-I|iw ƹ.< ?y{$]>D7~dl,M{HR\vT諯vc2n6Ș:l.{Kr| ^K/EnLzaL}<6OAXZ~O)c?0נ )<~&Lct-'oI񉊴DN| 7,kPm[*Iڟ0:v!&ƺ€~Qw重O{훳y \NF?/?_olj'x"իkK?r{c_3ю9'>MVd?h_}l4[fFc?;3e_eWⷁpepgMPF |͐ = yF&X4IW~I+_iejTC]Fhgg*a$C_^xEr5ˢLLLRFLRuHW E붒#VN!}S:Dϧb#aiY_ߐxܜO6h:8d1HSHO ƞ~q3A2?xT蟏'>}+&/L656z v-޸+m"x|R/~Kod\Y?ʕ+KmNO/~u:3 cO͚MK7nԘnF#[oY6pm3]Æ }5oN7N? iɢ%me?o|*W-f޽zf7>utƬ D[. Ek׭ 3pJ?!gtIQot"&dmOzlƧC\꟣>yco1mj\:t"BmZP񆯿|0za 7KN;Igm>Lig0Nzs СZ;tծ iHZH߫vi'ɾKq֧3ֿ1&bmN:nRYԥ3xIǍG=64w9T:>)2|&㔢P\Q+Z'8i+˛F㤵q.lz{3$'wٖ6PG8wO ׽hG1tx|_]8VasTZI&UMl|w=#$?dSn3NFTA[777w`f#3!g _D-|~Q58/LW\ 3R ,aoW BNÌTB*j M&L233!]&Sʥ|d c0k@ו@Gq"ENjǘSH6811,@ TI鼸‡Y-L q4F@t GcSVN|zKz!CeyI،?= G d(çZ^8뫥KBlpB " I[߂VǏW_yIp:3lO<ʕ-KsP>ħNlب^O>]|$Х\O?i؈_N_F%]5>|}jnn PYa6-tՕWЇ~(޸żhիGeJӔ?CxܼuhbG hu('W\SXv),!>J#>J6)ppS.szr9-6>i:zM׎GOa} _nںւsG}L_ܾNYK]N(nȰ;q Smk訣Χi4m?TiTf lW*Sml{GAG#$sʰ_w4nj(K!%u5aõ6k֌%8) HI8|yZv ~2gKj3^;~~\\c={cc:ƪӮn]U<O1;wEO?4=,ZdIۗS {N2w?2]9h iTt^TJnT~ѹKh}N|>gkAbsێpǥrϿqSh'ƍȑ&$XskƝf&-}ߖܥ̷8 Ow| ȼb^}- 6lxSv~xBY΢ƹfi??L_EoBTH$Kgi !ӿ 8lw$='Q |{wlq&t- M2ՂbժU,'ퟆ QW<*6iL]{PN8_թo1CP+O|~gkXO J-@pAOؑU/,Ȧ٫g`+ITW03?=܉9lGT_7%?mٿfZ? k"Κd3*|]18Il|qp`8!pT"KqY k /h xGY}Gkug3POi !l'B?(}֡lUiC8*%)=ؾ{E+a,\\"q )㒸 cZ<aIB|/ïrwۍ7>=cz*P /~S ,W_}yzSoħΒHh:6LV\7[< PPAq3(WN瓵QrbѫFֺTBʖq?}46wٻa!Hqlr٘SD nq8)[6hD x$/(Tu!CK>#ڶ6tʲxN*z7rDl*_<-^=/A|d+xͷ"4{Жk,#yW~ZԾAAo"w/km8*L3q¸|1C*Oq [M?}ѣFS8E#6p-prJlx`Ls{>8&@~5n܄VZMg`3C; /uregkc{F:dŷBƔNhe˔E6:)/cpZ c>!3F={hN<7n8~.bS o*OӗZy.s˭QMـچGFOuv*#O/Gv`F9>^EXۇ"EJkis;GJ eUy`3+ƆyЇӟ:/>)Ob㎡Ta`896o ־HF(u+kdL_yg섉TRE%vwaJDŽG6wدݾߕXU%g9 o]vݍ.JQvK~A^6mUV:r ~z.=S0Qr8D7^IgOJٟ{ÉO)lJ6kxX2by0ӭla_077QIQLKS6毵4?0/?ˆ |HdFQ~-c"t6*q*[|R%~|AK ~HCO: ц)fQē/ J 1k?N#fYQNrldqIm"A8۲ڇ9$Ep>-ezt+/p4'dk_w?Ok)y'̙Z__T&5?Vh:E9>F韇P-[mZ ;o65ysf)Aנ> ϣ܃>&'$OA4+rE;T1,S;Lk7n5hԈve}dŦķ2G7x=Srɓ\r'3CwyglN(?4j8>J]6>d;vtȻ`CAx7niU7M?!}igѕ>8?gul,S?jTGhgJ'P$X§d OFI߭ 4^ [h1]rE4_/[6|H^.ڡ5]su$w… モStjTAmI@4B_7kpԮKk~ XY_ۘ6C/K5i? l6pҟJ*eS:ukg6AwO'p>KķfG >)iπBk;':-\dचp]Ѷ|*/ՠ?/Fگ_>*u1w @IDAT;Mjikf WF"s{W}Vt KzA4?lm+nYL}&y@M۷6{t o8&J/'}ur׮6A'݇p8?5jց:sqw U>͚ No+ب օ*nU O sY?T⿰4kocxM4sfHt G2 54Ouc73c&6 ħ/XL_toFC=z:UI,,\nfg^{nA|SӦ<;L 8oG{%֋z-]x!EL6fӥMܯ2 B ??=""N`92 1^_65$0ʼn|?m_?2?o' ?60/?*3U4\Sz%$"5dds4j{R0ٌ̓#%SHflOt?O &_&HIT"Y #ϓf<9RIO|7{.N|/UE{Ͻȣƍ`OCN~Yo}Q^/Y6d?fn,ƛʼnOCG|!6(]N|m>hoJ~6'>-6>pᶵmu܍prkt7eߘm sR wpe,ÓNgF{_է*Ƨ4qxi>l_318V\oW(ހÎ;09SO?F ![C^+Mo:n!GpQO4|{4~8gfjѢT6^zEiuprۑt61& $mJwrJNĉTBi]NAҡ rr`fݧ&A?OÆv%)dO8A~W_lеvr?^i䫈kTI?/V7)<ԓtBtB bOK~S&M$ԓmh;`tƗҿN)gONC\.t>-UhԷO?o㟭}o;" aqEG9j`npBUG{,ѵ$9zP KFR\'u 70Ϡ?Q}~&N+C'ܘ1GgtChgOJ{/~߅W\v)tqnzu|9ڗz)rQKXuDJ79@6ພ_͔~~)Xn)iݜҟa}.F3 Kri*UJ:Vy㧫A'qQSt E&iy2_(׆}Bu>߫pr9_6~(RnJmwTcL&џ9K4iNH*NB0ْ8|}/7A7mV>յjݚ_b%Ϛ7˗o$`عg‚E qBxZpc 15nL~iI4i_1BbC6>iT[\ Ţ!n2ä0c?64@c_-E?bV%n9PDpT}sLYl9+Tґ7EʝGab q8=q!3p]kyq+yc/_rdm퇔V*CxfqӗcI43#lX%2r?6Xzf[ bCJ .^-Qa_fqW6z%ELjrDmk?aGtyE$%cG~_NfZP ꔋ ~z9'D:11<4sN >J9p\ /t޹/忻/U/駠hT,6Q=7հh̽O~a#Na&#G4/qz*m8 6[+Ħ8jխ.4>ƧmnMw%(o!S&Sim|T1N3ϐ-K.CV2Xf׻Wg|p"KN;4:@[yD x]Yt0' u3NzX=r)Vcg}.qnfo897W˖-G Χ+. w-j4̛TLqݺJWjЏYr?! ũ]uD:w} ǟ), gtrg:GG;gԳ APD^SOSrzR*o&lv{<to3I&d2|94 0>6~'jc*'AؙO|)^@y4QYg-_kϤwTVM >t~O5{+N8 W;[7eF|ydĽfm.6l+=qr~/ӄ~v2կ+T9s3!~g}I'8ǎ*UH?HWPU8 `9sp&_ꍸ`}Md,vdW'$ puku##CRUqKӿ?)%K\ծU3_cѿ|cc#X\<߉> XfV;vbgu&v8q8NT6s'zYƎ:BIpg~s:QE׮] 3#pȘLb*.iɷ Bk?Yc>ȟ?DF/~)?;{(goWpe_|I}/ZkǎS*II ?i`.F2G0_X4b_f7{ vT߃m|icYlGV?miOmm5]~S 1Xd?#6qrM!&NVsw|OFQQaPqK% *T}Np0;>aI g *T}Np0s|0aI g *T}Np0s|_[8>9NJfep y|9B3a.'~–ӎPƍ{_~/ZX.W?R?g?^O`}Eq8э7\{MYc ]}Օ>nO rJlP/R|.ɐҿ(x4yt,_t:N"ܠV;^ݡ]5e>v|;\M_v)N|i6&|t{KPK ӿa.KQ=̌O9]||9pڌ<b 'Nⓢ|#p|*vm7"wN4μg+,tNb9.nL? pb,Hg}tp2X-i u 'vc=VO8d9Fo$p 9TՃ?'E׾~3M *|S#8>-Y:@АFp&:?JK/@I+% ܊p[b'?]9d(O@3DŽ}:膂_:˶mG_~+q$)Ϙ寸B=4a|U` > !~"wWV[o# UZ!:,ā{'C '$<ǸJNhrȐ*y'Ak ~pb4o0NS_})VYo1XR t75#J_? vY/4=*$uգ!}p}:oc7t l'!FA N|eѯ_.N0z|bWېFÇ85oDY1\:# ʅ@7ac٫/H-r\;$/2~A){[̏a}{|"0/=JoO@ d#b){[oCFX>ۋ/JTjպ5u#ʶlK\u%}GFFoF*U*ӓ?y^4Z_Cc!|wIM6}yzp7Ah:m* IoDGq'~3wS,4HKȿ;M6sJgvx͚5p9idqӂ0;>OĘ{Oԁ[܉OplD>N>T.zᗣ/^Bڴk5>;>u>s+^< jժ {qjʋ/@pMh]wz\ȎO|O>W&t3^sp ŋy? nfj{M)&Ӎ_G?4&$'>1 Y'>i)Na'& z|*H8TZhWel1ojnNb=c?)s`~v;dy3 dO˴eo֬9n y-/sL{6muN~G<Fv8-[)[Zu @~X;Pn=ڵo/zr37~F@p>:ޔS#ψ # i4O>QyPu夓o>}z2Wzg+E^cJPw[擺 IC߱N_wũscͦ\qh~ )1}y8>r.cǧ2pq(b~F!Snos72nd?ҿƛS0I?pYpa?2.FvkY89Od_s۷s,'鋩_G,>OGg2"#c='֑}1q$qXbtiQ05p^^ ?^WZ~2oZe8Ba^ށu*M3=< ÏD7+\+[ӿ,)?62 7ѱEecY7 O< ?6o{E1F1OM)`L)2wpfA6XB8 |e1_Ɵ_,;6̿ "Y冠rh}mD" >6y7I٫!ou0G!ᐂ6_sT`_a_ӿP"y1ySMmES˯?Lyq/,۬^ܰgw Ze;>)PN|zu!ktAAln;]P88 (VsBXzp|Nw=6jepzp|p4t`+lS[-h-ynF@>q?+ ._ 竪AoyiPߴi8> Y QwlE-v8> 'K/IVfstt.JpK}kP@w†]f؉|lʹ&NJZ!l7j't:g3pEJƔO<AKr=zO_24*Y8Sy+W; jg=Oɇj\[o?O?ܳ8"v]b[8u 'GU /9A.rs.xݐ݆cĉ'h3zvu7ݷ/p] pz79a R2W`G_38~R8to׌3=aqCA1qGD:ETf-t`@"Ưg[n%nW±n)C+Wn9ݠ+}ߝSo%_A-oE7sgrO`"8{V2TG?/ M\z┻:]觜XpS˟οr{Iyi:6K>8(Wtb8!tw# 2Oqv|۟d:!1I|oO[jetp~ɉFҪOz =!0]!u *Ucg4wb>%vD)j*Q'e7yrz4wVw9OO(}ϴ{>I_x\t7BoMɟ??NO +xQ.C:mmorp:g,K,Vj9p5i"{o bώOzV)Oĺ? 1ߙuW {BN?U쯘> 8499uG!FJ?V581bY.Qd/Ā48 `GlU4OV foQulIsN\y̦xG1kRQ"7S"hƙbJ#PqY>+r]k)ɨ47S"hƙbJ#PqY>+r]k)ɨ47S"hƙbJ#PqY>+r]k)ɨ47S"hƙbJ#PqY>+r]k)ɨ47S"hƙbJ#PqY>+r]k)ɨ47S"hƙbJ#PqY>+r]k)ɨ47S"hƙbJ#PqY>+r]k)ɨ47S"hƙbJ#PqY>+r]k)ɨ47S"hƙbJ#PqY>+r]k)ɨ47S"hƙbJ#PqY>+r]k)ɨ47S"hƙbJ#PqY>+r]k)ɨ47S"uKl;^m0 NsKa2]p[x+BQ˔땢M.f2F퇹gr԰I蕿HK,*ÎO3^_2.p<8oTMdJnNļov^HW8GnV7oc;iT z2Bt%e1O([w.]N&pN*.J2}m81$>ɦeppϧ"=;>g]{ph'"ҷwo6mZn_MhABO^ԇ!_2?MsxM^]~ÇC%ܘcPUԴYSğ}ˊ6Ďf,?u/m.عaؐ!t^?AcJ )=L37ޤ=D0tE}oENn>;nӡ8;ϲhȇ>DZjMXs4?X?Q6Թ?Zt fWgǧJ)'Edl74SѤk[g_d T$1K2xy% 6c?l/iүdm+ƒ"b6&m%ⷳ(TT!P<6q P #dst8C3N:ˆ%ٜ$ 4 f`R1$qҡF-$)qL0;ˆ%ٜ$ 4Ќ0bnI6'IHcءF-$)qft(sK9I:@ h0bnI6'IH34C)[IR@`v(sK9I:@ h'JaܒlN3C)[IR@ 8P #dst8&JaܒlNghIR1$1 P #dst8C3N:ˆ%ٜ$ 4 f`R1$qҡF-$)qL0;ˆ%ٜ$ 4Ќ0bnI6'IHcءFKI^6ސ$A /]*nzR+8oP,}1&OVZQ-Qm|$=NȘ6>_vM6bggP  am&.;SB[oE.t;<݃rr˶Ԯ6V-:?;lԾVx5}W4e$ZMRrS-hƌ>rJr:Rk8Y,Z'Mʡ_fm'bg!{0߶h֜o݁*!|5c:~m|2-\'(ujkjԠ6Gf)OhNN+ϧ͝ 0y}TJ\u}[_:ǧ:˓2#jn9;4G !q\]OL*TwEN׿ޅrԪԀS4<t{G=䦜g hƿG6׍mioG'>9Nʧkt`~%jp` ԧX_,/J 5kդv[طX }D~%yzk?D7j(?Mz"d4o9\E]!&&kqmRnȥ6l06l9 _}!F68e3c H$Dfk/_p!q|as7؃:SRAJRZX8`0l9͠"J纲Jxb/Ɖ0L:u֞dT4c~qO|e]8,!YBa4} =zzco7K~.vY̵W_I~xdragg~vA1_Ӈ>ߦZ*xcp㏧pk-n\N'>2şBy:w{dNU/ϋy㿗0cՑ_$?jb+McͿLa]Ͽm;lJ1yb+R)Y K--u*F"ߜ1')d Ǹ<ƅf:FoWpm׆i@KDS6"b'wvo8 .?-]NWN? }*yJ~[]Ftru|1GRq*֭xz+.Bq̿ӦM}q*NH-SIͯ?xP|p gE? V?Zџ;t56hzv?fΜihٟf_?􀘲<1@ִ/O_}0_?Q2258 ǫj}a߿e3'bm\ПNcϢ:Q]Ym`L'^*x |Ei UH#I)8*BH@9OJ1UBFHDyRt52@8$FΓRLq@UR!4rb*]"4*SjP!dTqH 'JW〪!# C"i<)TTEi UH#I)8*BH@9OJ1UBFHDyRt52@8$FΓRLq@UR!4rb*]"4*SjP!dTqH 'JW〪!# C"i<)TTEi UH#I)8*BH@9OJ1UBFHDyRt52@8$FΓRLq@UR!4rb*]"4*SjP!dTqH 'JWcFǑ?ӄ|]2gXF!`7ś /#G%RƟӿnJ Aw p| Oj<꼆jehD>K ]BuV\I=3o]2̯0Oգ%KIiLs;]1팓b0 ' H:ͳnaϖ_UW1g GE2o!\/ґ6Pɇ6aaG9ן5ҋ93 0;37ʂɠg &ӿӪuk8+yf?q%%+i„ 2lђ.ՒM_i_5\SKS7h`jР!-^N9Ovx76E ),Al߷E뮻h!t=#)5Ke<\)i_?_b7}ɟ?<L6AY:/Xgz@-T4^U ,"-At(\ 3i*S!7rO$#KbZGcWNdih01c/5gʌNtҩX6l\`y^b6z՟df)cm])R} y-mk0?ŝ7?L\`8@$_fm[A3߶`/Pdo{)au 2gggw{`o?G_h_{_Iޯ½9J2Q>U"( \ӭ$L~O4W-J1 ȣɟ??5R;21<ưtH $Uwt\YB*薠e]2ႤQ/ϫId,._4¥Q~i druH{`tkTf~e3sӿNi4~Y%z;k*P.\mr cF1]=r@G \n33c0Oma/쐕@IDAT['xmhOfn_d˼,vsDg/?9{o?W{j_޿ħ̂H>f 2=FS_TS(ߤqA38fI CyŠo %03E"?6o@6MLTE.q7G)ܧd"!g/~1.GFdPۇRU4ɟ?? 0!lM"`C/?v[}5[`OhG['f$???bnpl b߶bOf6yfOW tf?O  ]7}WQDm51re|c<ÌIZ?@ ]OƎSՕG4_9L9QHcP<P(C@+?DNX9Į$.p;Х/4V%+Ŏ2tir0s|0+6y߿dH$)yreÂ7zy-xfb}qq@cEܦn}ʇ K K 6Ll1j0OZS '1/l!,(l`O^uc[ӓƅ~hC/{Egggo"-mwY9 9 OT,EoM WjQsIMk520?kl~޴f8ED|?2Q@yӚt6`9?D J&?0,.L#?erӿ2XDyYhpRNgĎlJ٫P%+1cWǒ?z5Ϳf@X|PͿfOmoxR m֟T[֟(0)t L8֟?miO[bBd1OHK-?mY]cO[Clo)O F48 |&59pǥe'-stxJEyJd—9 ?:ڤ=CDgAH_Y8 +؊#"ƺR,nÍ1qn 'яd7uWMMcjYy`t֦gس.Oma/1-E/֟U RWe}fg㿓 ?.5˪!fk=qٟf/,$bn֟ȵ?M &7Gj֒ʦ+_mj_Y':[QwmY9xGG z5 LCg1$j@6O.|ƌ\չOGO<(I[ V\8`Ɵ?>~dHF?K[8`o]Obdy"._xs+Axʕe~ʼc%\7EF_0C,ֿ&nB"0@G]0ٟq| 6|d,VS* J̏T\EWWm)ʎ@m"d!'\3sHc((ӿ6g[ avr0aͿ*GflGxQcI4y%RK¾P%إZ P/ |(A_o7[/ɧJujաO 4??Ӷ;lOKw=P^_zuݧ/tF1=S*yV#TvmV8^@'_N˖.6c OK?AլE~g.t 8#i@ LZ*uϻ^zOE6Q!>,_[_Z/_6#zϷޢouߵj֤yaq=ԿCw lM4٥mO@# F ??lOOoK .gN/{6 `_A&lmkcEvby"c_&'@9a1!hRasiS!K $VjRc?08&&6RZ%N䌗0蕠h\&5x6?)'rK\J)i,S?7013x_πb&0b.-&%q a Mj-eZtin۞$ +/ EԲE+1;gΜAK/ q5jڔVBΥ9sQPapiݺ -_NO&Z/715hGѷ_ٟf5@:Cc_km wFCa_0aĚWZ}3ϢM6am4iР;@ YDz첿&{l<7%a2W_uEjX-Yn[jؠ9㬳{QYfZ?U #\ kGbUfy&2z??0۾~ɉO9je8_q5)ddRMYF?y61_e22I?8 <Ø8Ouc,:4)dd6l `lȨzY6Ƀu$3I&(y ,7dߦu \YBv>zMҝ.ѸGHW{d8R2M:4_CAdM9 o?v. ǧzꙒo@brtˣ֫K<$~I=zTGC5knCzkj֬藳4O52֖mǙAy$D|wG˳;sۯ]o&M'{Gi1f318>UI'ı/GFJq*;/Ϳ]N>d}m`(wΦnu';|kϽB bGNZHC2הkk5K?Xma?f!/mQF9))K3cW?6ɾ/Ԓ?q|9K<09#Nǰ'K"\e5^5lq:}%Ӈ-D9┝O{}&;b1clddILK't\ hm;.TTEyK^u5ԡCEдiSYϿBG9&ovj޲X =eǧ'|F?< SN;;i r\B뿫:l覾/M+;cǧ qaLO<(Jp2-f|g8|DX"'8qu1Г!)W~.](8 {9pFkBCyz^s:uUA4;?XagOFj&?aT΍u\M 6$,l!%<۔ W9i294_۱'ǣ_,Y =U@fV~>\upJW>.,\*tp.;KU崧 Ŵt2SIpƿ_!'Q)ҷ߸ix'N/Bt,7v1cQ*p:<~!f4{ 4c G_ħ8i9N|رnzp|*ԓOQ߿nzi#?3i.N|2vդ{ z4s,:WH;ptS8O|=ǐ<5&8q:7ɯ="~=Dc_?{T MΗ}=y12/;{ѷ[nZlE'tߚ<qp9=>m,S_nSK/lpv4់?Ϛw=Ϩ݉Of͐5]Gt' DQR:)5{caw~ZW5jl=8aHSȚfN}}U?csN8?,_U{bd-%l=l?^zXq_?@wbin%2k}0WIb8pUTT"fN1gQXl3 OLrM+m&S '%SDnt f_IT*[!80/f+<rR2JV)L7 `k~[׎2:ߜ2ArߥyOG\W\RO %U͛JT5=ޏjn^~?NA&Y)EZxO;a=k4}-l'}dMh]vxƗ_gOD{ꩧh7H.Ԣysq>Kz{k)-Zq;lƴxqyw?ihA[iK췿SA"Z`ϷXw} ^RZJʴpB/>?U]vUW_I}a_}jtIJ8|l_V-ǟaChW|uG 6L?n9gG /|oܴ1?ڶm+LOg^@ Zr9{7•aN;_nHfΤ E#O|<<4z(W'SN=hħ\ɽffp"aSkV~=i)pG~+mڶm;\zy|eў#4> yǴ۞{] /̼OofeVO2:CiG}:믿<,ͿmZ?1< k1-\ W-wߣOp L]+ϿYWT8ԦU[R#*}'rZ&N6Lڱ>h0ې=VB1V=ܓVAb|nԠ~}jW˭g3NCq zטN??>ۿ!N l?k D2HժUof͢czYG꠹Ys曡R:^N9瞇فD7tlыO|u7#cWJqPjU^EgpYNR7O*ĸ/!i3Y&hU3z4= ywr2tѠx w8\|︣L z%KiOK]H{Qz|pg"먻 R%NH;~k7qiI +6"璳Cr0"1r-7ҿc?] '}=x_w;d9rRѮp#c)hv)XAթ[㤻j=Ͽb7#GDciE":sCՋn(uW9 xw=y?@\r f#oHDπVòN~npYz#(MIR@8y2>hl~b~)]qT8=0GĽvOvƎ{Cde&=! &kcǢd3kĶB>]H?1pŋCAsRzo/ӈa|1(vC{w|,;^#ۉ;A6lW_OCL_Ǝ)XMʠLyflb#ڿ:6Ȉ3)?mWձ C.u1_ =L7{Sg<){x_|A;[QS+ T)D-5'Rrw|oˍ@O³QJ~rC&o68kJP* J?x * J??x * J߉ MHv6Ha\q/$ S`@( &#q$$E qw|~G ;i4RN;ǧƌǧh)׭WvmO)gb`"a\?Ň/%O/vn'T Q7ۢ9R*2 'iEw/Mi-18ɣvZğh#ڷoGٟ~G3Nׯ 'iT 4i5qR'pXeHt$_MSbhҟ)2;Gcg}?1}:M1'Ԧ-ZPug{ڷҏ_sΡ(<aoݍ1_nÎ< v Sw؁qӦ?n2rqtA C7gSDqNo8>|ΰHrgW3[8Zj'l@8>N|R?3t0m=!|Y3Qo.vA'>YvCn)]wur"OYI'Yp0c…4c0,ndSKg 85 > 'd*U,ӱA D@_9Ξ 9NzaG4q)'*T8ewvt=\:' 1y'Ɏ@^4Ӈ6iuoS(wO8E kᮺcӨNú4Xg%͚1lѼc?1G{/jIqӗ_~!_5cSN> '-AB~͛ |CӦMqp+0=я~>V'Օ :R)QG l,2ڴݒ* )SNxI?qg3τ'`3v+KY 2DC 8Bħ5NcNqM7һ#XL8 hH}7-XG> =b{+lȃ>DncNڸpT\)zY+#뮾>ĉeLc=aɽSXG3}gUt"_ɩ]|w$z}c29fGC9T_Jej$NΥrJC=$V]@d!O.J9`OE9EpЪ-7m}/?Nuu{ w<(V[.8;9divc9Ο[e|2+dKG=>"Ѯ~S4Y'*@ʠr"{$)u>VkSq'895jL+}V>(: 6r Auħ=wl%+}I&tAr׏8=Q ;r"~siO[/_TzCl>ؐE˖Tn]zg„?1OsEpH18=O\N"{ᔛ%$!_CnjʠT ~f62CW83 ;N;48 d!?4T"'Me.v܉K虧Q^U3ώ$Ďw9]iB.GZO|GN=tt8 8>y;IFHAoj}R/;]|ygL^8hMjЃ/D/rD _4A oSݫ}ᇡٹkp\rHg{vN_>5O|*(|Ɯ&Qc:4|0h}ZzIg0ON쿿/=K>/G N)hp3'y@gRt1GIֹ#Dܶ+B?eFq.33y'\ce:]xwZMvEkf7&H{ HQDT`5{' *~;{{}& s 77fL ( ÆLJGTaZZ^׿ܕ]jlɧiTn;NݦNyǝ//)6mۉܧxy2 yn5WA^4늗3~K׫Y69vXছo[K^N'DC7NqfR0`>4^*>wǼ{Ji~{J|^tvjQq"LaP0GaN'v/ͤ7&w'rHݧMwM7q6AXǩ'xVI'wB~["0c0bnxÐǴ_b'5G<ӗӇG˷m{KwXvǧ}T3I;[o%$  u 6Q.h4/f`:C\X}u74ܩAI3d!n@%}Ai?F_?sv(zq>uc#*DvkDN2ŝ c'տpb$P!g>swy߾@?T%u*|~ެ)=:/9i;y?f<,ɓ9g 2zJ,æg18 Wq 8>$ƟW0V ?uc?m?ڞS?y!6(amk_vw./V 9$-m5IR2ç' @Jhzt!Z F?,Â3z-nMJ'1R30iLͿ?|DS3,?RAaYR+fjU* ɞO z븽_^z1M G,@䍿ߠ|{kx! G%x1nY/FnxdUW]b ^&򗾨3ϸ}ȳW^ o)[ wR. q-wg)}IRg^\Qiђ^_*=Յ0P8S=^;ͨ/M=HŤpkdS/MUn08M+mR;tGLO(yw,<>Y; - "=萃=7) " ^Eo.4?VFJ ~>np}Bjwp\tcV? x=SÄgg@&MH- ^vH 8 /mv9n^lKׅ7_ :K+L[n' #GpB£IidCC^g:<\?>!a2L @ơn'H>J^d81TrÍBcWBɃVG^^?~ Ƣ`7va0W/He菁a>PB lV+zpwNƌ=F2@t_vd{}c4]:O'  >5a7~@Y1^STc #Lرk~6ޣ.~z}]ç2i<>-DD~ +t+J}vJ^p勮W[Q| 4T̳Ζv*HqPV>8p*׵ !!{)}ADɹW rƵe[ow{| w6 xwڅlLwNb@cC'epV:,0bc9y;`]4^L_?zlftp=+C2{4بpoCi4>b( Ճ̞3׵k rnç~ꫯz#{ûы/FDB_{Z4|OOשxa^{uwk<5կ#60SȎmCx$1?Anw%Ut8FTt`.p{彤M%&? 7uk&h\&+t[o #h~@הxxsj׶ ^J>0\I.)Xm ׸icЫ,oRD\;7``8Կtxo* Zxda qoWo\# cQ-^ұ*T}?ŬX_:4l{n5yҩ8 !$3Gꫯeomފ^r~E~;n/x1x/=죚? 0ORΔ嵗i+_cߌ/oƿ3meOOl;¢ 9r-la[?˭?3O O(=.?M/f)aZ{Ks)Y϶Y5xPߒ]l%6rF+_#TT KǾqk`|eߢvn[<\fE;<>5n&G~}?k^E"VD2R?~As/wjxe14|\}0}]. O|ĉnnuWSK/ 50^?z4xGۖHS0/\e}i_L2vi_ 0#Y n2'`K~dXZj}qzPEoZU>Sз`FOL&COA RUyz򗯁p:ç 0|*s'v*7/t*}z*|A_wu'Pͷ?,ܩ E}<+?|!do6Jx 7{ 4ccx|3ҿ޻}K߱3=sIVu}{! 8΃;B߱cG_O"$-Nڶ  Ƽѝ]ﻏT|Fwڽx5jq#½0Ή)nZ(N ܦܳ>›Ҷ}'-ko~huj1&Tdϵ"Y?2_7M c-'>!M/֬ SgDowv{6]dMS \G~tAļ3{/#n fc^tޙ<'6)/L_=kznȴ5f`OԠ1}?a 3?1K?0C'D_ӿT vZo;xP@gmI'eet؅ݐ;@ jLCMχ1WK4!//ZEϏ )X>e+@e6s+L`͆ИxXi yYҬIsTYx-0Ę4)G#0PG?Y1,x͝=׽3u2D!c6h#||CX >n‡/Ma3M c`@S'O׏{.[vmwױS聇KO]|6aJ֭a@4>ڿFt]?3_zn_?9nZn[N@b1nU=w: M*q'wˣGܐA$U tEyxV¬04`9GoHWKb,1bfA;8wSG>+"K?ȣ >qx]&u{zߺ^g+]5G9`Cm .@ Un۸K/?R>s7m44q;*7rw/<TT>ͅǯ6)ai?O/Hs縧aD㉇JY\Z{%mH]uB֔/x"W?.ߦM[w 7od)dn7ORA P>pڇ{ðl֖z>NjHҠRn^ :E}Ŵ?S) !6O$!O}Aaq>kqSzAO_~60>1niz }!MO5pssmZ_ڝrBF܆\0`z#z0𒋠`?O*KΝӣW__ר}BM@0~0͉~NKi[\CwUz}y.Ǿ_} vxƘ;&,>GXeءa"+=IW̿F3r:0c>\ZMte_ӿMey]lG%¢B)kXG G5L9N/IJzӎh%ZN<.jb/ Lb\TE*] Y$qqc%cB#uяӡGʼ@˗nXǩxQW_!̕[)w^QY? -^O?s87vūۤ[EA9P~buOnwp£;*n! ;ڴ>-X@Vq0:OۊR)'֭cx9mOI5O?u]vǯDv: ,? Fh ]_><>> &w9I`z˭2۽ rXQçӤn>_wuݍ7 CJ\nZgm79^\*E-QY;E{jKhxT3Hޔ!a `|kmZkߦl$olx矗l~w mqV<>t3!G܎{a:{lסmYO;'+R( g_t衇O|?k֨"g:yB'T.GW!H#owl[f-7_c8|rw7?f ׹SG__(-J!}(ՖIZFpB`lBv}_KS2h򗮿lSL?L_#Fv\~B'g-iNz%_!^GK%;};>LR,!Zq7kaѣG!|_#7 .^g|dM^{ZV cǍ;dYlq _arG?zQG_/::MLL'tLa,w"ӿle~Mv,eAg(e:E{.7SFLE y ##)0*BL@LL1UbBeHebt5@.;F"G.SLaDUr1qlٳ{g <>5k$wx|Z{͵M {_^z\U)ѷװWw z|SB6'5 };S2?/ש] S8OjϽ3a 9x);?PS)}9VQ0.@K mz\e# hA2?|_CWx*Xu;;Y{i{RwΝ韣pF kc|N8~տs=ȃ v)б ^ƍ"ݲ^*#%,╊򟲷>@V/}/ҽr_IuKy܈{޿-<A,_5~ ytH! &d~2GOkvOE ٧Sç/ll>W.1|SNig=ϦSCxCb;uR^T:Νt7 :Mym>^0dB+eҗ Da<>v8͘ T {9d_%?^ <@}N=Іhn ZI1}wC = |rxn 7|~ቯq@thAQQHC;Եm9c qABr>ڟoӖǾr|iKD%=0gTO,~SA͌ç]weޤwyg#=xܰoJ]@w%N"#` cD?D||هz+a9<2bKAϷg\ ^o]x ro3݅uReYw1a}~n7ضEӿAN˜Yw$<>կW}MXSˮj+{gzk:ݘX u@Z¸w+ks_촳{˫ nMO<tҎmA(LMYYYZ/D^c?`ߐڒL8Qjlh"[d!Bfro#4p$4@_QJd1-ma/[AHmHlEʲW ;^ 9V#FTĒY]&j=vVh4o7fKƒ@*Ǫ 8ȯ GMF{KFu_0TOC<5D*}kR'_Ņ_KJPO5]@cyckq8ieEqKyYs#1kR@_FM|!J/Ǟv a "W\ST rt^] }ZjЩ<@9V0(9G;a60OO# l?-ËuVq-|׽0|+&0d3wkӪ5;(P Ѓr< $ VVN-Fii6l.w,0\rqBtcUKŶ۸K.LʳON>{U:jYͣGEj[G"1VKj;R ^tW^ +XHhVm7c^gm91 ghtm_?J8 X}U^v<~6FO5Ot }Rt 0?nbu |uy`nu4dʫ }^V_zG/eN0'$q|;xBbuXmbw*S>}Kւl#+mhj1C{z>׿ ޣ>8Oe+it#(i" Fi$㛺Of6u0?u4|E'p+s'uoڤ0h0q<6a Ji>u}n0<_>4Dꨀ1h8@玝_L/OdbOY_rިJ7b tz+Ǘ10 ]vk/UW_|sxsSq?_A7L7voidgIKEJ۟)>kI??ne\?q3`kt繒D& >I\;ν٣|t)Gu ]@~?"Cnq kA7YY;^8d1ę5k_`MV[n}ګLzVD^[ q>llT*oF}|8?ax[o[cbm.bW^ v>}aS9OtKC캻y&P ݑu,t 1so_~Qo9ڽ7u;voLׅ'ܑ0aӓJNI:6-^]?Clw0*񩇛;)|У$>ç[=bKՎQcƹUh{O?,?+S`pSOsgro+\mz.%AG nܰ^g:ۮ^F'_ e+`PQ'*,ے*\oE-;ޗ_ο_r  Ca+D5|mExpjҴ <>͆ D3Ga cǍ7 $y_]w=w1Ǹ=n` w-r7_ zi>c'm.s>oqE( $x{zҬS\s5`\&J,t=qOAϜ!濱u02wuM;3ç^S~ûF_ĻɗQr0τ.zzI⑨?AF>ߙkοmrGx{xTHQ &{-@}_Nȵ+)K0tw|7ajt/~՞G}Au(cn]:<:0UCz* -'J8sw9&^|UoUB܍7q  ]wǸ~)7x0Y_:b*i߀\x/k)0m֮]zg*?/{ț9;胾nқq"֟-nœ }_|9" }}89ԁ~kӶ=*!80nQި Q^u]x/GQ_>WaiƄBo rCn1ON@8w_}vpೇ2Y i1Vò߲_?+1jj]1 NtzݩS!?6Xc\מ{SN{nwߺ7̵pfm,Cם OQo OQX3V~kcz5=:|hAR[f-6,6Ek/WԶ8F(? oZy_g5AkͿ^`Ϳi3֟GXLW'JF|+(|+cB-2Ӥ.T]4NV-2ӤjR.GqKVʕ)&pVB>w8kܒxI)qR!h5%2KR8B>w8k/rKe&pI|q_0/MJጓ E(-a^'Q\[/ü4)3N*s+/+ʙ| AEgPG]"I}n"5PHJFI.Lp )L@F5O=XNxY}(?yJ P / h|W_{\7`C1ǘb[޻s}ݭ"8 .G#ض:k 9s:C#F _"UhOs=>*?;=\Ϟ0H 1 K<#n To=xRݙq(ȯׄ/{4|2XY|LAK >MɥU({Hvn]NC 5lA`C:$\|XHx1:=WZU޻ yç;t?>4LE#r䜁"}ƙG Yv" `hVOOĥVVvȓ ~0| HmX"ګhH|! K|ͣ͝OhN# T3Owg9 8aR\܌Ɵ75?#FܧIrm?bSn?˝Ȳq] /|Ƴ}]&Mz/b$۴qԃ 8_w- I/w;jKon[ok~|;v~ ØU`wؙ- Q7^0'yW׮mTÐ? 029 o"n\%9vp( O/j\450 kлE4޻F0j=sUIn5po_ EߤI3Hjr|w0| .xz6'm'jWkլץVG\ʣ*ޝإ+ *`"=M["`H1ђ_l?m0;գ\xI~;>wv:g^n~ ( l %7q=B_7uk#Dȁu/Fc/?'nG~n+,I{-JtTU[vm#]$QXr$6V/?kdgIO_}{ݽmF ܥ\>Ye.7>|닯C&r2ĥ7:h0&|:_K~gq(k[0|:/3Yj w݅ƞO~^厛\>_[<UQd_WS{,Oux$*u鉉 ٘wl|3 O@g]+ cƏYY?naO(W,oLV\ k}?/E&>HRo׻^7'M9?͟?F4QεjςJO./NN=f^,O<f w Q#胤OM}0fSs>ݞ{S^N?2xPN{>{d["3#;ϓ_mKxE<zҫuj+>Q[`xU)l|z-x8ki'{>#NG!?O^]3{Ũfej0vmg7jmYsרicK=oYBh)|fn6d# 4}ݲous7܄>t }6Ec5;^6គ7gZV[l^{56 ׼X>M6t[CM HLX9>A6lSys$^1ͷpΔuabSO:O(4<٘}bWNóNv4)^*Bbm]SxŢ}$^>02#[?hװtY}TUn׆gg)m6xCt_~ޝ.;+"ƛ}07͘ Q]駟v53 s܏j/j|sgiӨ&8u7 ynöwNmMK٫wǧ}۶m|?:k m϶N<Cx D[oSxwo7o?6~~o LJ2yA?8?Vvax\mv{qVb묻ko`IC7xu:XwM4 GhkȮf 5kw-nG8FrGQ쿌>9`7[~^Y_ӿ6kͿ le!1|*hAĬb}cgH%pe1qXbjb}c2b /azE(O˨fP-pH.&k܇=X>-A)"1qXbjb}c2b /azE(O˨fP-pH.&k܇=X>-A)"1qXbjb}c2b /azE(O˨fP-pH.&k܇=X>-A)"1qXbjb}c2b /azE(O˨fP-pH.&k܇=X>-A)"1qXbjb}c2b /azE(O˨fP-pH.&k܇=X>-A)"1;MnbGow +-ŧ!/UK y 8|)$ 񉚕IFlOFV:ߠ!7ǧa<Үmu+jn1_=Y)]_'v^],/IK6ɭzxܱQ??uu;ƿ?2 nKuhW0rדOަi9o4HE{30΁Wx(p"%ie?_9b_ɿ:72m?l9`[;ç +~'Yx0'y`8_k]@}v㿈G"KLI!g#'k)Hȥ/">m %c<ܓ< aKK5O1[(mف_ta%t!a0bTN3\8Ts}ϗmVFWF 9fՅ韟D6rK_7{gWW3` פi0yUipg7p`C4iߦ*OcM_ϖ~v<+K׮n} ԮM7{6l٠aC׬Y3wG[68ϴU!LOlouSΟ 6~7G4!;;;_;J<>6(J ƜBb$+DJPOed%?A>!`/p/FKP?LmaOTgEo*X[Ϙe6g9@/.)IX~{"^@c) }㿗%?LLIt2cυ:0oigڷic &a3-̓l򜫋o0IUA~lݻ}.>~O/s]wK9AϛN=$7}g७m/R41kͿWX_+?J0ҝ?oƿli>$?\` vLLGB_~OU\d)ՋL;nI2CjuT;WSbVLr-K|0af:|čJqyiyI! =һI#Oqy=L29QHCP4?P$A@睗ɟ_&' iBG8$2|0D! CYsG@}w^+5o<^0{rwkuVnΜ9焻[p'kqNf_D[?`Kma/3 L?Y5^ֲ_>dMM!1;k[߶?lťAmh/X,0K(d?X?'>9W^ʩ|u ,TGe@WҺ AKf@W51 !u/PrDekbɟG9k_ qhD@I_"51Gh\4oO&cEg;m*rQ#}fNH~Y |oQJ$D`gG_9Yk֟6_ԵuOl~O0*#?Et9C琸cO M ;/x?la/ ]`?m)[SA r' ɲ)$fo[˒"H;m@c1[`sFpWCIER\~xn,`1|M< mNaũ~T 1M~VCs},ˠ"d' dapAd' &&&:\b#DØY^%JNIv`ƟⰉdT"Iv$iUJ͑ $?rB3T)b'?HTNKLc?f?mmߺ[?_?bCɵ#N.v@%;;?ο~`\0 v`v`v`ٮ_8+_ `oP)) 2~G1| $cB,/B -􋥘Ezx,(M$o7K|6:xO5Ң5l1o8P*b<*(M$m_)~jkU 1n 7aSʏяK͚?!?+GuM0Zlfӿ6T?leOΑ{xa?m-(;;7.g B;W;g;g;/̕vn?`dvn^7vlv`?r›euO?A=P05mjm+l֟di)z z׌,aB-_%haX??q_;; ;G; c?󄝿׏/NJ TըQ3REjLi2Oa S^/<5J#9P~)KSm3CbO~nR9Piibbo { W^ S>]\*8AY&:T_F X `W>Es㿗 ?.5KUiͿ[ jt4[ac!a/;qkv`/a Mvdovhvjvvʥ+_j_ZQOY9yG;G; r=\-bIfbiL "tbyciFo'gqd-&E@ .UKgƟ02$Ɵ%P-UK0c],+R^ceo&D * 1'8|*qy>JТh>ˇAkLj($0?2k[q(_;0`dTpaio;?GK(%0O;Ο8;55$դ#|?vK;;a-A~"' A1E1G`pc1|"WzY2輗rHKWeu ORVӑ`'?^;x]h %4c.KHRJ0`Ϳ*Gy?o}^=1UJ)Am*qJ! P_6L Dr]пFogOx LrV.llŷma/+D;;7;W917YgiM~߿!N/'vnvL~k?'E\vj?W8|KMz雭"[9s U*xo?mmv""Lg`;;F?L??t?Q~픝???a@H;}}ә)Οpx| C /^"Hi %L60^u0Ŕ\\)*Xc fEr(2Hص[Hila܌d{ JyXLE&%a_2Ɵ?raܘEJd3#-vX*Nc't#y0Y ╡V)Ԇf)Qn&61LGRm! %YLBh/2ÿz!am y][-^`lA6_le/Y7ld3&*N SDg2~̐bv) H;;\av`v_~󗊅U5h/]2/Qe\Š8L]ȮIh-Z6)CNrj2$o7ӑfOt J:*RL͉m7Q8{ljZ~O4>B XR(5?7*Pk6dʏϓ"jݤ݊,473cWV6k[߶Ҷ_#=~J';Q#/;Qn8x b篙!{K-F\`R/pKE``o[A3S*G#)Fma/+=WVqᠱWPiR ϕ{Q;KXJ(W-#C!9A APMr(W^&&" "#9A APMr(W^&&" "#9A APMr(W^&&" "#9A APMr(W^+m çʤrbܑ;nrdpƒnnjO`n#H%Y!}xD@?f9Bg?6_~q kLpw[ʂ`_Jap_~eK\rkܸtuJ{pjn[&w^t7<'ۯ_Ѐ0 LЅv#+c?la/h=hHh'wĒ5ii~r?òAx?aXZ]>$Jx#VWV-.QpXk&rf)lZ_[T;R:l]mAO\WU:v[^L.@ y"$]UҞetދX;VDޥwnJウtg O{J"(E:,LNrrνwAxKI2$$lԑ,OJeϐ19B)g(?˰]M>Ny~x?~k4nKP=eJ{MyBK'O򴍧QN?/%jFs4uT:v_)9ӆ[?'۟hs9/y (sJ@'Ǐ>F.v!ο+g:!܂L uE?mtY۴i=ݻ>D,/ެ)~I(7Gp AuͩP_zZ6=}VVJ_VÝ˝?wPSbwı[z`Pog/) M=B0~y[eEhV Xd8Y9\C\'MNn'#􏿔2_!nq pHAֿe+\ ]į> a4y-[wHǑ#G諯Dn"uYTYZ&mjا>B2!'?j*PѲe+y&zwo-)2ӿjoY $KtwEiH#㿧9}X 6;1S k ο{#ޏVWÝ۝R$h) DGkm0nēXvO<#8?AKhm<_aub@RJXn/t5U.qKZqY^JgX#XbUj7t5U.qKZqY^JgX#XbUj7t5U.qKZqY^JgX#XbUj7t5U.qKZqY^JgX#XbUj7t5U.qKZqY^JgX#XbUj7t5U.qKZqY^JgX#XbUj7t5U.qKZqY^JgX#XbUj7t5U.qKZqY^JgX#XbUj7t5U.qKZqY^JgX#XbUj7t5U.qKZqY^JgX#XbUj7t5U.qKZqY^JgX#XbUj7t5U'!O l+#^z:q//PQzMGK d}wW.r"hoxhT_sTX1?6$ u}Lw(_Ha3zŋ()iGE(I)CeݳD)Bnjm޸z)R2<6o^zS? O5rߨwOwH=C' ~_?{|]´ϑB"4嗄s4crPb#Fs4~BYҀ}rBYҀ# %6bdI8OH:E@ %6bdI8OH:g(؈%?m ')؈%?m 8Pb#Fs4c\Pb#Fs4~BYҀ}rBYҀ# %6bdI8OH:E@ %6bdI8OH:g(؈%?m ')؈%?m 8Pb#Fs4c\Pb#Fs4~BYҀ}rBYҀ# %6bdI8OH:E@ %6bdI8OH:g(؈%?m ')؈vIY>ɍ4~Q,v-ئ&E\GU[!ĥ[AYIJLQe|oV?v,:*VfENm(Gr&POax["aRcK, ]h eçԫgKzXWV=w[+wΛZxqq'j=G❊/g2Q-0h|`4OP +-Ӽ5{U֝Q`fx3'+^ztՕWɞ=_ j ۵}*ro+0=ƗKpo_"?$jzc?yꫩfmx{C;#@u}?PqWȿ}wu#VIN_0AEq?{.ԡPXq9z?kVq R-([(^MG6K*yIU*u(:w=3g{M PÓ}믿^e*՚>tlߤ%K(!!lDEO62pBH?ab } %H ?wD[J/NB?n ?{q?끗{H>C?X=PAu'n9s!o[Vq:c!ʏ),L1oX5tJ*7kJ0) Mq_ւ?# N+% 2ה `R>ӿs+N8u,xI NXM&e<9߼ᓚIYM)M|\{Sꒅ1(K"-S^[!6)Sfzr>y2ft OOG|$~YɎb4 {رcEBx[b0|J!~~ 'އFϙ3M1SvVVfr{ȆOiOvHKG'M_|%Οp7{=puQV0|ڿǕ:6UN>c]lk͙3'M>yϻK1aFTL޽z.-ZF'0q).%%-nKpϯ-;OψL既s_֟;B[Ȫnu?ւp/0Znw,=4rπaTRw$eK1,QtIjXyoզ5w߃?{ zK/JsHW_{ϙMZ:w~Bڝ6u .^ çx ç'a֟?NBI\ Q䉵+/ըp>ߝ>N簿_)ݿ`ys\zTSp,ɝYL[Wld帿?K >37 TX8X췫Ssj"z}qt cq9=8-[X׏c\5sG+N:W8:\^R)N4q.N4 $H0q̉[* ۸=|dnяʕoyrѡat .w8\tyr/}F;wnNeblٳMoyv\-Ņ[o*t(Q2@;vlk!—kխK./N?NO֮Wљ,y==UC=JY::Ѻ #OmѝwMyLa zxZwg^tM7 @eɒ7yTc].ɝ[8-3{zZu*S /P~lD˖-ǨQT︋]~9,^]<][n~2$ۥt}vuᚏԿ,wJmҥmTz/U2dȈK{{(޶n݊~h(c~R#G?2x7JN?-X8<Qu){S+SE˲`hrLuaVϟbN6oB C6S#dCtTnmꪫ)deȱ-:.nݶ>UNGٰ*|mq\[I_&ۛ_3KSu2\BOڏ>[EO=Ŋ+{#=ax6+_(ni\f\\'Hr*twժ7OnJcA¨-Z1/kԤi*V'Cw|Co䣍Itԩ/w|ȣP2A3 ͛@,z/Sr;Y3$=Py쏧O'cN7д)S̙3J3矫*U YInȟv>z7"ߨQ#ʒ5+k7`N(ZjEц wW-Zi˔Ko˟;7,D(w_wu$KN;+[|J?p 4SN{$ɟs)s, k~5mLʑ+'MAJ[v\g |,ٳgAx;C7X|)lhhlR54ŋFc3/ ]oG#_OO>nj;oFݺv zÑ[`ֽ;<`d:x }H/c蟄 i0.eZx=U_.ɟ+~Sx|^[lOQ1|[Թ3 m"uƌ Щ뮿N(ŵK_5Ӥݯ898)P}uj{n`Bxo Lֻ֯~=+FR67- !C$ d&O@Ot ,牮UfڴWP_>;4޽f-L?S̐D%ZƿT u'd_298+7YDYz~-%9)DLJy^;4iz^pٻMl3FH7r[uE&"?P8^=Op_3y=g=?km;Ta],|T4!4(ݞU]1f%~d:sX=Ѳ$~ƪpa~yrӿNѲuuӿnw?e$Zǹrם/ rRpZY|]}H3-Apm" !Vx)膊7S;^7 -?##՗xٸqEDt׈Ld1HťQg {ضu Ǘ)ӦS\P'N8A7lca< U&ի7JܲǶF*ܹrӷ0li;ruɅzZ [>umG]y\fc/h[^]T ;nd~v^y0_%) ;glz嗄mѽU87f }bŊӈ.-^\ ۾ y+MeࡥK' }nv=|KLۏq 1INƼ@Ȧ4ƥ_ Z8OQiqeF[lA='T uGs0NwS%z0tD}Ra^bfSe-dlIKcGݻW2^2f$8۶D=K  0+P< qy_3R[V nݺѭ+6a]p}*Ux籦Mg|;_˕ ^LHhayt%>M?c-ͅu[ Fmf+dFP^nm .T `mm۴RQkԽ+ `HiϿcBy.)ZAa-q6o,U^Ĉ D =;SHsg?| whߑb'~6t 2Wѣya/s͚7W^zI?zXzufo@`?yQ#髎0?=~G?E1 n9ç L8xs(ç=xЩC==ϟ{Yh1G8NM6@[}=0|)[9 <BBχ}y@)[#džJl6\_h/sz ȼC|W">j8ĥKS҂^?ydWfEˆ@3<x&yqAOhM{aq˭Nɓ&;Je*ڏ?8IEĔ~ڲz% %SϤ\9s 6tW\FE;֋=t񔘔Dq(4 )N#q{:fΚNuԣ:uJӫp jĉx .޷dSӆ ark#?"Ú۶Ð T(2G駟dJ;w?9GAV1y/}Q'[l4sl '}6tÂ{5P_F+-yQ35kF 災ܿ?C{sͥ,#:h2d 7ғO=-4ATW{e͚f͞+z7h)50,gkš/H[ kW_#_<7q2}Ykު`oh Mi> g˖oMF^*PL(NSØm߾}* S_sf MT6AgI4Gi&1gpF-'ס][bC/x5sFcҏ30խ+x<+ly^Z6o2H,u$Ў!ݮ# [`| C7HC&MN/5honsrfM_73ga$ 0gs/XO&1m>/ y"琓?qӿno_H/$o; Q{ujy{#(m۾]*^z8Lxv8|H>`wK+t̚>Ϸ~ըY 7q~b@ekI#͛aԛyx킨>!wi?sYO-?_pWrwA?OdO{T[N߿;?fp~uw y]I޿{?0+5/ݥ#({YV0m|0 cK:Je;ˆ#z6_KIhgٰA0*M GVElgٰߒTi8Wϥ-4v Ҵq ?XۦOFY6l J1Ȏ`/-I#(v Ҵq ?ɟ/-I#(v Ҵq ?ɟ/-I#(v Ҵq Lʖg*q#?#{ gxi 0"wkBQ@(*[jG?^u>n  c'q`qE_5JMU;H'H0|+`aԀS5@/} ?%9 0)xHip?ZC# SYwhG{? _Sΐ!m7^m$1RF?uDhWF-ծ%Kn w^Z EX4|(y0lګ>=+tǏK/~:NxU~G0ʔI>u7##IuT7X6fxyf?"m1l3aNTZ g'WT6ǧh-Z{iԩB#vh=_ F6?X׮ =EU﹗ØbAȉ'?n]]$X`jxQG҇K; 矧JHGM 0fbo> :Q; !r_N:2/&D(.Oiatϭ?_ֿb$N72xx4@Z|Fe:VU)9Gɟ[0laP$u+`ʮ?N8ciVc3.ӱL<]֟[v  g~n]I˧aV-p>K9lj4Oofxy)$mx|+LϘ!=:tV?TAd-:zDG,cƎ[ #-Y 񸴓 oN|,K+D*ٳg%;͝w?H́qGr=>%H[l^ u.ysfF}-wVx?2f$6hjjth-V/} :˔/ Cu}*cO}~ᇘOC&Mn0|>czD,t=,]jSm!GkF =|1F[N-AD".hk7kތz F4泯L*Uw;Ôw+n؄w}@r`8q]0AC.ݻZjE`=s;5M?;aU]2[͞-ϟup5g 78ݮm;u/QCNC!T2Ǽȇlۃ,r~ҥ`c5ˍ@2읢F K SM呮CָoS}TboXVbOll;b~}d '1h%{ROT{%+D`MbkG%0M.) c.Y.0Z\ߖXw!{b^bsO7馛g':{ںg?:,TX۷|L$Cz۵慨cioxjE}}hX6U-/QFH/V?ƒYwիcWS E?hcȲ[p+?دWsggͿC2Xe/ޠg^fi9%#ZRxO3nf >*cόD4lHTwc)+/GI hN9s0߿iZ3f3f͚ґCGboa5I8{g> s"x|OǧMa=>n47wp/wT >Ih؝?ϵjNaApϿ_?"OQ歺^,˧Ý?Ý?L''$fǚ_TǠJKzp 4/VfdCh'Hcy ϭ?4QA-/#S/_>pkvŁ;Gt<79Ddf(ơ?vyZ8⊫ 9buÍaRD=zpl]Λt(_H!J lJ_}9 IBi/k' FăE…"X3F);X"T:r5kD`n*g4 |(̖cxĚ5k&sN_s<=!{|י ɽ]ƦiLr*Ե{7NZͦ X^kKq<(5# { a!:Eġ7}dZ=F0S9hY"C }'.X ";ݞ*m?%JaÆKի@'L2 #?;W&|D\oU}_b%W8hl̵fO0*I%J̿:%,/L4o 7j{De3KˌHrry1C%ax:Rժ%7׿Y0/K2i痂 {+6(RAS6,z0\bF_ctTzAl)sK/d/L"A 5GkڵUAZt9kh&2e:fO[O<>e'x /孮 tڵ;>Q8m\Y>byFxݸReʐAJ؈x%]E䩓Oh9}MbOi[/&e6?NQb?{asϭ?ɧ#hFK9om|pRSΗ7*ABXۊ?ӝ?ӝ?Yb<[OJո ߃ULq8[Ul*4ۈsApN5Uh,S![`Siۿ |>dc b:bTTOՇllULq8[Ul*4-p)g봊_SRy>UV1lVkX*ϧC6*8*MKT}8XuZ@c<pN5Uh,S![`Siۿ |>dc b:bTTOՇllULq8[Ul*4-p)g봊_SRy>UV1lVkX*ϧC6*8*MKT}8XuZ@c<pN5Uh,S![`Siۿ |>dc b:bTTOՇllULq8[Ul*4-p)˖-7KU'b՞zI:ص7jMP=q-ݘEyq!ؐK˾CMtT2۷Z./ϥ+/-?_T0ۯE (GBo4.KBA=S- Txqi'*dBR0~!GpQ%d`00}ݵ*H[\r+_'` ^L6o½P ɯ뙳SNCUWhq#<~9{ =n]'BqF2*U^(Y|)-A#Elp2aÆOIIPxaMΪU{>eC`V`7ѤД)SCS/\P; tsN 1Sf:xޯP\4`@1ߋzgA#X>>_B{iJԲ{S'S ο--S /(Sǟ?vL8$Y#e˖ΜM4|*00"QӾ$!D&OG|ҳw1'*:/0l;o+ËWǛSvL=GnAQ$B0<\/Y9u|򋷸"ŋCvmPagϞtЫ8:t,x@;amkHGRbEjպ5΅:fGֿ_Ȟo@ժ? O=Pz=kM?_ GqO?o߆~ }#CpSJK:hg~X?jph@ j< yà۷ky-YdO? çnɌߢ܂ ڵo<>}6+d+]<1jצ #c)oS^?]Ov%F_F ħwWɟ[XaZ9&HpWn ˚B+?sSڳ{<>u:pS*ΩMa[(g?oga4~T:|؋CtG'NGヒ%m|+$q`/|$^W_yʖ-Kmοk7{('-^ Oh˦-0|^!bw9hIN"%\5wgS?ͭ?^!?rчZ?h5;;oww?/=>)<5btl F"&'s#F@>ː5V}pՁ ~2cP !,?NuPk kQ!珲W\#ԗ}"is:c_6%@0={C3gB7t =CTD 1LUw^Ю{1[bz4vhWhq1jA^=[PB4fnOOo?Rx>cՐ!ig +,\D2e[qq2^濦+w.:uO_"i3fQN$'u2> ͷL=zû҂匎T OLu x|:x7ű+QJUǏ3B h_/%'|"㯈端 7mJe˅/YH#Gч}(5ZK VXZ_ '0y Rf`?q[+Jݺ4~옘oظ Հf}ݻG 7++TrǎG|.+ޟ>ʛ'ztt>/4A ;?_2cc"JtЙ3)԰~]16#P&Ksf"6:Ǣ9%tA?@]H][Œҥ]ptk*_ˮ>_#Te'wx۾m̷S2F`z&bn=zr.0g'#|0'&޾m[N`P>1Zǃ s=%yzO>~ o"B7dBsX3s4yaAxozx\SGaԹSGJW||z:7˶?w[ZKG~X 佰qѳ9`S?{]?#lʣM]ӏ6~_0yBc iߛ+1ƪN}ղ}l9g"cMx뫦o۶ϲtur45P!SgSx~8Ȟ0+|:r>gUQ5Ҽ"('igh翉G"<X0za|\c(Q*,ϴ%-ćKO8clټz 4s:?K'}ud &E-M8;WɉsK33ߝ?C)_wpw)XO;CF@2zV;ю 9PpOZiSbg8ӿnpOH{bVDq$.'B@pB8ǚW2&7d͂ jH"qig$ Ά;&k;9r2CVP.ǦZϟ tr}w /:*PƎ'c[b͟7_IO [/K ()Ywoٔ#{!Khp" ۶Y9iP\?DxEʛ2!LMoJǎԺ2z9 ǧcFI3zç… (>Xy~YsH* 4>_ԏFmۨk@aZA]u?SfFO'SzuڣU蟞=aU&`M4ǣBmŲ(FOuᕦN:"/ /VrZjӆg6UT=ɛ !ƍG@bt.;v*X hT14")O޼o҈ }: չK Yr mZӽ00x@ϙ@wn6/ة~ Fg_4g΄b}k)zurW Sއh4<G2̕C(I֮%9*boiү Ouw Y`:Wmܴ -,ǬcFO@5jתlfCkrI?OJ]ЯU:2-!&өP*E9mߑJٕKu3й,o‹iӤ)[{!&ﹳgSG{Dϣ!d=iѓؒ?_![uvOIa'8˓u[X N@ D_V{pG;,_= ~οV?L㞿{۞?F|r㯂ȱE{9Fi8 U9>t0_UbP^c(nhXcC?kmeAw}>iHNJS* loe_ɟ/'ұV*Ϳ)>8DC:cUbP?'hHǚC~Jr@c[4rlk?|])ir%ٌ@*FR4^3 ,+*L tر-J]w#%[ (rYƛ+Q|StPt`3tK0"  : Toc t*9ŎQ%%y 0:Xh̞GY/Z4\-(sҥ0au)*/+^8 G!n7 6ÐO7`³7l4ж}Ig z΂1Z208/*}ozj4z4n̘/_Jz~@)۳sut04x|a;ZZlݚޝdrzS\Nu0I>s0ih..|5fo#Ad1&P>ϗT*`ނa4Ē 0KNkWV(OcsXWEh{R- >{{?_<;N,Ƅ 0;ܴw &{w_]VY<EKx/}_?qUGC^{~=.@|0+S qt k)ydKwك^6׭SS?҇hOU]Xcޘ>w;_3]?BIK(CB 6$6Rx=s;ƍ iR&0 0۷_at)>p2.g?3^ҥA zL_?]+lOIӿ\9${:hP=xJ!37 W5/u10x'`nD6|WOo ٓRϓBZétRT/N:.9c]& lѢ$ <0Er_ z?Tpc=_dW)t_K2<#."El :u}c:~'3ϩTdI>b, If͘AoA*] . 7\u5 |?}W(S"eh,>O7VzdU P-=ګʱDDY̟O[ (gkP-64~VB^#aTx1iZyYC{h'xDЫGOODi {X°GxbVgF[)0||=Z<4d۷S'D_GIӦLV L=?v,ЀAdn~2~]qo^" 2gBFMqΛo. V7X%S⼹Q3NVȅ]!OpuV<:xЫe̔Qyo*2e2x'ܹPxߪ\6DV5°"f#EŊGb-6L?9FKW9AxYmܴ^<Ԝez顇Iء=wU]di㽵k{ta' C@IDATG%8)>|`a_xCcG("?_xAi V=a)dƊ7QDys+0M4Aݦ.WTiӧNݹ2>M8VK``d4 '{8 ўsuujcNlh+} Ϳ=fo9x5O@?1諚@㿓?4[D9*A v.;sM k,;+W.sOTz"GǎGދJx4_F>t>?g0 F#eKR' ghԈQ `Oz!Ͱ `}Tyym~ ^)uN1ڄQ, e8fj_DUϿJw8d #X?n6O8~KkQw\[^)FwwH;S92_#0?ᓰlTAj>8XR~$p􍒳y9cL~2KIDmZf8cL~2KIDɟ?\LWMe>d (%V[n^6>IAwg9;?; #ӹ'CZ;w̋X *,\|OI%DPmz"O;l\loӶ-U>Bű'caC6R8̙d\N/H~7|-m{G.azF 1sO>עhŗEK0ԢQm/@k׮jDEcrxx *p9j2 ݳeB7Q ~@6c}P_^2&%j@py0ݳgi+Gri<&Nwޡp>C@oVH&ʝK2g130bxCاdQso ?r0Zs ,+Tz啗hUZ0p=)nCbe ,2fb/x|B;/\)e<>.{6j{^|9`h{FQ'+0N F 8C_bGT_F C3W.q Xkw^sѿr4`P5w]\Xx00_PWgE (l4 Wk58&-2[ }n)_r Eea韆bO8(2ޡ0KF蒽 }YxJ)`L-,Qp >|2dA<jV ΄Y2q^:pZh?ꬖ iYH3_ZIsam!{7l0Ɇ\}9z5k堉 ܨq#16bv'.Q! :nA>`LStY{j$mT߾cOL"?{B<7A}-IK}?l=%槖W8 (Eq;_%BlO{zx#S8}MSc1F6 [i=>MiǦ8x_8F2=ՆA?_CWcNp1M=63=s.-4E_~k6R3t҉p!K:|k[[:% 8|%j|ys۵;_=_tW.i-2m "4h 'zǁn! _w㍴^ K0?χ|^yoEqN695hXnev3R/D{Dwy'<ci$-Gt/ؑ#R$c"8XT>*k]迹gGƍOt7RլQ m"qT G-no i=\$/ gX_ҙDAxM>;ѿ=1x"ұsnc5ftfM?GX1k0h:GJ#EWGxpv"D6Ea:~XW*_z_p+Ikgx&x~:vڈ*v-jY3i"OM0!=~׳;2oUN]lqn~Eͮ;;: Rz^DR I;9|r!>Й,G7x5eĎ]:W_ 7G?ݬZ5EF)t<݌8n_Ҷn,0#}giCCt%!NzE+',y̞;vB¡s@Uk=Eq atOY Q"KG|BCЙgs翕+K[һoC˅3Gx2xkN..*<~wABsrG/?ň6DpIB/O>XWTfq|?;ذ?nn\kԬI@7rDZCKpC9k)"u-&"=thx|<'aROh7RۣK锖.>iVkn] }x2yr,_z .cD}7ǟDܛgsiSOȕ?!(x/0sƿ/~LJO^p8U&b(U9X>U3f9X抲yߛodxC3ύ[7j,Qvڹ3.ZSh:vLUU!V,ZݜB9D"Wygn??O1 (?ݦ䒓_l2o[f9 Kn[TꉱgeZe?0t'om-*))) NO1"#.tZ5O\?@Z-7+KA!A?b_b7GGjѲ%",_8'_>^W_ѹSfg&uֶMV3j{&?Tp)֭wz opvB"ì)\ vS8֩ -b]0c :SNҎX'ǵ0kuPmS5ᅤB'OY-U=oՊ^ʕӧ±K?O^%aչ+V35ޜ n C?ʟ!xzN[_#ʲN0 <ȕ!]{6P]? _{; DE$.wqLL5˟?{Z?????6aٟfiٟfnH{X lZS(E`iL(E`niJ(E`niJ(E`niJ(E`niJ(E`niJ(E`niJ(E`niJ(E`niJ(E`niJ(E`niJ(E`niJ(E`niJ(E`niJ(E`niJ(E`niJ(E`niJ(E`niJ(E`niJ(E`niJ(E`niJ(E`niJ(E`niJ(E`^lOR;3@9|$~AWca" !IIZM4mY >B _ /] 3,I&~bDmOkr'-.9;-.:UAjB{jޢ<_|I񋥨ӝ'vf ˃Ħ[EMVfڲd_N+֩0oKLZ2Vf'gy/9ǘNfoՃ ~7M~ 돢+W擷B>.4uA*cİ"a #Ϗ!\OSm-71bX1?yg#x,?.*I*r#5_ӿɜÜ|&iÊ۞Zƍ[+-%CXqW|ro)C.u%W,ۏ'b&'эsɟӿn.qr?CT~~L;ě6W>A'i ">Y|'5q鯽Ρ9sf6ofqpoggߐ?`9ѭ^I׃+9?ra[2]Lif޿lUVOXrx4++Yu+T%jwl @\=vOK$AJLLt^d^ykw5kWK$AJP3n\׮y)G|#?^Tu?~ ]9b|9ĵ|kNf4Oeo@VpF/,NLΑ(M֛eOͩNҿLi2~[Yy7yV&=zС*ON'KX@żY3YJ+VofϦ7D_} #6yE!M;`d a/ѿL [B

lioޓí3ĶWu????`ud?~B'^漞#?UM:Z>kCO?X(T򕦾RʆWDo??V39" z%(WYM^}fgg򗒪8c򗙯cRJ-Z١wJsKu?̃2ӿs)KaCGβ&A-1֜0OmaZ*Ʋ'S@ mlio`bOk?:gWWY#?o$+W,Fp̥ہCf0I"N*|3p]ޗ=Q/b:A/IeF㍘""R81kUDKzq:FHBӿB G'ӿQ_niѺ O ?5b 7.M ??t?2SdOdOEV|,@:˹0hO.dO`)EA>kz.Ier[ȩֿS9ʥa$uI*, d2ŠL@ !*O)2T dg(ْ%L?<\``bcFGJRsMLBE]+ӁX 'wr^˳*HjkX{/%Ev*ͺ֭4ӿ6\_?Pc R QDf8owUf8aa&le/[A9__e )@HmQrJ":kldiao+`/`ɐI?? 7f/>_V'b8Rgǵpy@u)ހtHreޓ:'T…ro7SI3KEQ!?SlgX:luD`@?bMk񉝏JP, KfJFZ (42p4}%ݤUlix'oggX6k_fm+m/[l%87Ijy+obaZH+ ?ms%˃z-E N6o[x`/:T9:ɤ9Eը?leO[sYRBkl$z\Vpz3V)D6wRPYa;:,bO$@9Ç񟣃0HQDÕ}m;LG9$\ ^F7/O`LNLGDIrA џ4rQ9_l5/g w6S AgJaP_bY]xMrEl_llllp71m dpK 0]lA + >Ґ3N(b/b/ )E3x^l̬4Aʂ&M[F?MLԡӛ\a ʎ_Z9G|b5o Y)||"{$),O8X7yഃ;;XU Rpur_XHJ:^DR%%Y [F?H&L6  k}Pfeg",!"f'Q4? ,H=le/[֟7`@D7`1Afg?V dO/8>*+JJrz=V0S>?x/ JiJP+@EhZ)&& &N3Hҥ.9ZB.Ab\LJ??AF8''I|f*H?/b\?hw+8unyٸmksoggQFYfň?6Fa_fm~3WTWJDXfm7o&B6$gfΩz6V ?mmBA?!6$go[ |x<)@2[JYWP6fjCNC@ޓ}Z~ -4}XYy9=j<hZ}r4,_M]a?6nmr(j5r)˼ R]cκ=Q3(.嶹og'ӿ6 4n%˩xMe/&#(tʰ^0gxC[8mDm756CʦC&LT!BbiB?23`v.kwXK6[߶>O4G-*d6D*@DE]DomayG4GzĦDbiȄj7cgWRH~[7/2/aW4GzH'%nM&ݜ‚pҖ@8\a'XgbqIu>J^'?g4'4J Gf\*333KfP"KdO,k=oL] ۢ"mYåNZ*QRe/p Ya.ż&:v@\/x\ەg3$\K}Qk3͌& L_EfegNdSo[KD,'c lmA/W\s5mSnj_zR~b?woj}KQnE{Ecn~?mi0hO[?EmAv]A0H?dM¦fl#1RQY&W;FiJEJ. 9og':!V Fq*+#/0 0k_ b4WYaGx 9??-Z|Hj;oLI>a<_Z&9KЬlv`_=n[u֝j֨I~ $G'ڥh޼t!k,ժV\ JeSOG7 QZwXƺiŦLc/yAD+yb|Z`? a?6c? e2d;jͿkk<<|$UVىWo& z4yP+غF-po5yTN'N@ʸs_̌v,LL.ko?j] 5cl%+?4O?DrtX 6?6KKK ݎoLծ'(-<E1]5Xll@b8 ծ' {Z&%ـp@]5N@A V|C$+eT\򀮭El".Wjlp@I60J\!v80KE$%.WjlR%"P p@]5N@`ע.xExD{f'+D\HaW)8b%zoyuC@_}/Ya<uLM~]wܿ_ <&1?,_Y?mgU򧒚#lOmG7goWhMwaoooo?/?MVzUX?o'O0tb GC@IDATI@Dt}ַ9`2|$lL4>1ui"2F???PzrjL ](a?Mas cͿ`u__5SuD/5,oּ%qGG3'^yyZHӧXԠqcWF4~G4fXsg 3i ">X.NkuԦ; [JO>8xdxԳnݻG-*t'_Iqٚ,_'FԬ<#o=d9EΝrƎOgМsoبsB@>ƈ~!SFap!S}џ94g< !B^'8_;wBO<6=6^̲y `H| -SX9ol[yE╣e9寧#Sp|5ztONoAi؇[~g_{C"vP[T7hЭpg㣔.r]]oNoMh}J( o| K-)`K?#3P&~9O)9"x l?k.+)[ef-d'-?ͫm6k/`mMu.2ߔ?r|et 93::/ bͻ4>K(+eP"il]%˕%&P-pP-ּKsbN_Świ|P,W@1KBuX.ʒ^(8}Ikޥ9\@\Yk/ bͻ4>K(+KzM[%:[yp reI c $Tg5.X,5blӗl]%˕%&P-pP-ּKsbN_Świ|P,W@1KBuX.ʒ^(8}Ikޥ9\@\Yk/ bͻ4>K(+KzM[%:[yp reI c $Tg5.X,5blӗl]%˕%&P-pP-ּKsbN_Świ|P,W@1KBuX.ʒ^(8}I[nCs?0U|7JPW૒wC\V[mwR;+WCpA-]F-/<-ZXZW^3f|E=@|l\od$S`Ms wl,7r(*_"M8O/^lotϰ7x_ӹvdZ3׮ M4` mtpRY3SG">#'KsH#?Ou?M$oU PZ4t9= ?;>{"gqT9߸72_}D_u3|:(5e5lH Ji >Q$/;"П,=9хo}TAMETw";`ǧo'h~.eeulflȦ ?)=O,OO'9:)C~Lggg)OUi5YW#R֭GGJCp*_"-[:tbJ2)navK̀y'LU7ߌz?瞥z{o\)}CϿBMF=6i҄Ip|^b*?)dqL\㵇?l\i97ݒfCL(Z/[(NjTP#lcٿf/U5g6ǧ+K\9e#^Q Jץ}#<3&<'m_Hҁ93B??HNJ0o ULD">?@c:ӿ C(#k\gg'W%9ۢUґ,S=y,% M]r,^Q-))h+8㏴`OX_w8>-Z$_^T^J?8{#HoOu|x=xi_H4gO>))ޗvsjd;8Ӧ;EU_ͨ N:Tmhň4y-zWiٲeKEt =|h/|{>~AL5k‹Li3^~%\{6*/. FC#Z*uUF鞻~o:?2v*J[n% 'Nc BU 裏9qOAS8>-wȫ8(mݩ6k&λU Sёp|~ ">E0p+ۼE ڦn]4iD8M6#?CYwXТnZtȡ؃*UD3̠xmʔI~aYs: o%͚3>b'=w_wx>*ȏ`O< _/Bm̋ G7!9L?(jٲ%թ[4Q GbrDf/ଢ଼vډ޺?w "R=@۷j%EY_ 'h^&& `^BKrzOno(}Ι߃=Ԃ~7|zhvG$j烩SܕT&v>̫LS'OMÏ:G4я~Ǐ>r+UVey7iO C%%+9G}ÎNbKNB/}9_GCRQ})t㠃w:h :$ EyN]ҟ9=T|wQhي4s}pd/dmly2l}BO=deW[<ԾÉNH<~ɓs4uT tD%e gՓ Gnwy7_cpXNlk[RQ9 ۹+KWPz7‹]vnajA`bO@zm5 <:5 ?kӿrͿ6joӉ=lu\lIyt2?O?Ʈ!?l(c5lzG"Kqz.RYKۍ1XB$v6Qx(`eo,~BAof_lm.97dR>/u 9s ߩ`\.u[*e=K]$W^\+W^~ZڑA_|.O?4~QF+E/8h-P&M1,joAįJ8`pSW^~9-g&ԱKp,2:uAy}4snW7A)=|>zgސTی~;;:4jB75izT?Ou)o۶-]tɥ9;<)+{urr~TV-8!Ӊx+ * Ymсf>;poO+#lGd:#> '80uQ ?}9r\nzͷR]r;p@}v?.o.HKiD#* /yٙ+X2Dt%;{61iO?r @9??.fYfu h(hEBcSr7zDC+?z;#Narċ|v+֛B-T|_:wBļEd࿁5^'5^U\+\?4~87ߊ>[M?, Do`M{7Z >@ԹL ǹHD A[͊|p4t19[pn|8<rat=۵sG^"X/>Ȍ?#5+3[pr6&}g>8A{T_b%Q͚B(tPW7hQ+s vCo r-rj1|V?ZB8ى?fLa7`ٟfi'Lg=SR Rl^9\g^x8.Kp CɅ iʵ^|wt0'|J$u5q}Q.g>>QHSP>P@@3 (R(I]M\(vT ?G㿄OT)&p;*̇_mxS҄rimDl3n1rF{ -+"f痒xđT_֝2y"߇P .\#7޶ iӖ/>3@vE%|iy&M06t(MCԖz/ըQS^_hM}A; LU0RDOW=ouWQg#)Sh3DiԨ1m]ck8|JW\v*[8' q4noɲrm127ыQgi`s^pĚ6+9k ]Ӧx =4n8N:g?Ey. Ljx͉I&48>y)SR&M|?"*VƍU3sM!GB<$ϴKgL䖯XHDەM9-Oҹ}z++D(Suաm=L:N83g̠?tڙgFGϟÏb؃Hlq)'KǎpH`!"}Bԥ9T /mG>nlIԗxu v-d<^ Ƹh|,{\f6U 6i46o|?p}4y*tpzbU=dl=a&;D CI_~0{Dyxj%đ8Enq 7 8n1qƌeN*h$_yKk,;DB7hH4пCyȝc@|^EP9ш/Y&W| ྫo 6 _3aI_|IU["zT̏L(BQ&݃@rhg3jDsc*RD_g{WgtOCU j "{g4=X́'c8pݤhԬi3Yuzয়h)4NP\|1uf. ρM]VBɐeMVI/{]a\wq1ȅ ; ; }ao99-2\+oMBO Ǹ*O9݈T=Qݲ3C4Y<nxUFGiM5ȧ +eZ\cg`O>6nv| zd'g51PR8'1?ǡ"}&;> ]#_v;ygհu.خ*o#B-F"fy'} #Jݵ-5G' H5$>hK/~Ό_+ |B<o&aW`7uʄsef1icΘ_?ljoƼ(U'/KɏNh7UR<'y-i::6 TڄG IM'M}B4iF j;0tK4I[o{9z߾  utđGR uŋOiG#3?*U#4:E\BmwM}葇B>2ѽsRD[շ،=4/ߟuxY'ym./XӈG?yȣ%ݬpҭܝ.by2Υ7Gt7/ҽܝ Fb{M?7m]hf?;m} 'O2=kǎ:kwKO/^B쾁@2#͟?>[ 3Э<nCT$zQYҨ7"? o|.3F>V;pr%S8|w#VhOcЯrxxl~Oӻ2LJ~H]}ВCeɏ#"s,)uյPv?3Cp"ԣ[w#Ѥ!2_87qy[E[nƈ"˗/sO'E|ԭ[n"qS GU#RW_y9}x?;-q4p,ʡC#UUG翀N܇,!HSpߩsDk%N6噠Fm'3yrD|L?bp>X$B8?dG6/rlߏ[:o%NĜ"/Ʒ/ Pbg="3QA ɟӿ*[HY xO?~'|^= G.G3CXl=`|aD|u|l>2 |?hP{菈*z6X|G38K1[t ?.E|W#NK~sњ_0mLy"we eLTw23O2 ~[ &6ahIlƃΑ?`q,1&\M1uזO؉;x<rIm-soQ+e) 2^?YtÍuD58d8ǧt>B|DhYg"/K~4QjvV?଄(MҘ1Q@8` 5oL'8x{ֽuԟP_J">pc ~t _|q,sI. sJ#%;>H0=t .hwˮdz݁ꫩyv)(S8>y#ViW]>GT47FŊ8k'¡a tS۸J=XTw/#Do*?#L8 ^y+#LՉ?D3Z^1ԩU0ʵS&M}{P#y%8*;f AޕO,?ֿ֖'_I;1kOUhLD|-]{ݍԪbc *z`CL7s;9~;!#}5u.?͛N0@]Daޏ;T뜽݉OyS?Ob]=y$_l[h_R~Yd`^Y}u2?vT:'f*y]U[d|Ϳ6dH w3a_37ЙЛ_⯒C-mˆQc, nWx8H6.ɭ- $o|"B\Pr+rK=lg_? *܊ܒo0O[(ŰYbp *?2i+'>"%U5 ? ~OK2n]W^O*SÆ}D1덚b>xl,Gy TI4ϾKxlEX  m_&/͢O;?Z"ϼy"l]3dUr#Dk9խ_WaCY)q |'U_X~MBz{}pBhSܿDڹ;?ᘂ^ T2-]:w# c?X8(ó#7&Wr3{}iӧgZ{ăoϤ.C!KD=Y+U8{iqNH$KpBRX蔑-HX_=zAݫ0! q"D|"ǁp0OпHoYRuˮ/_\"qij?Il̆SOr{{~|,TY̿c~(UPF_;sX\UB|)]Hqڿ?Gy|)mNp|Ohf8afW5^V?ϔÙPGF}h8j5D[L];uL_c>!_籽+8 bˎ_FyZ~OM<_y'8"w޻R7Jr/s!sCgCQP"v ^t񥰍ڊ9|ȏ_1(%ƿD gD1G?JU3f,' Vϱn۔|k km;;>xE- u=8=؊ԅ46EWDR2C볟~ ܹẴ q.b}<ܳJWg$fe_ V$3쏴L%@/))) NOlk0:W;0*k4+)7j: Wi.F?rH80*DId?6Bac܁)fayZny 87/MB<~| dbH—2o`0>% a.f֪ΈjB+E3Abjx῁`*WqRt1 -ύ{rdØG _C$r @˓5V[nEwJOz‹EpBzO+- pΪP|!p|ZEקwĦy?|OO>\ǭUG9q7ze6FFMtM8 zmYýN<"ȖPD{/p8JTTs"SF6/f 2ppjAGmϟ/>c9`K˥m(ղK%.޽;q2{D;˧njd[/_{Tp/ws gt"GOUsDLb>gÏЀ[nmݎq[NA=0d\*#<@=^o HU' DR҃ISGD":\ NJJҵ^MMnG vO 8jjy;BeykBw '?E_MJƤw}wic Tws~:y .]wZpGs8tW qF+W_ϐHǏ?_NT:Yp6rs˂9B;1]6n=t9?"|U߬:-^:w(cqqC{7&]ta?xF#AyD2N=8eIRq|%B >L3fͤsG|pc}j*mhҗĹH]CZ5݇SGaOZ9Υ ֌p:ъkIX{T ,W+8GW_y>-#bM?vc< ]J:*zk0r'l = IxP"=zD:* )rg(EĂl *M@t-x]wvd&߷5 o'LvLfv솘<12kSlGqߘycwrQQ.2BږQ3iTliJ"0"/miFEj[FQQ.#ږQ+iTliJ"0"/miFEj[FQQ.#ږQ+iTliJ"0"/miFEj[FQQ.#ږQ+iTliJ"0"/miFEj[FQQ.#ږQ+iTliJ"0"/miFEj[FQQ.#ږQ+iTliJ"0"/miFE -[# ];3@9;f2QFЂTtqX{8z8|R5kNEj_~8foQlm;+#vÓH2;LX;Kpo:䶼G^$G5l؀ߗ6m:I珃6zH_v|¯Ϟ5[v| &6ؾ=ڣmx'AzBK/E լ!XvǝTfM*A0[в2# ;O}!v kLFO!iZ"t˯Hyp)?;TUB||vF #n4w>8hmԵsGovo%vN*|s4a1|:P>qɲh1T^=ӟj O?x>㦱ER?|rJ*_A6E'agʕ[t% ֭[_!_ΥEpFp=m睋k_6-~FI)^M(ݑy0|廧!V/L}M/;>5nHK/?O'̿1}iS"_BgK򃯽^|91]C ]<gĒ|k =8z]h $ \@mȣjΫ_}Uzd8A zrtRѵ0 61vZ|_yǧ#GP{s /wA2Gw`E/ǥvi=NJx'2>ntI'Qmo&YW=9L\,ŽO=/_m۶te]лs@nˁ[;vAkР!qc/8>LE4OrzQc Tȫ?L'buEKl Z_xh[J;uku<7[5zO̟E@?bs=8bc,`6L@>̟}ˇ?)-Z˯o:̂)|*ǁO39(__/h$n5c' X/o&=O:NA v F?L!›c?jKt]DJ(0k=߿D.ɘaGC >* `Ğk䔏 |T^ DzH˞s(*N`2%,tң3PR"00ٟ%+dfL K$d_#ҲHĨqDQa-ROdE04$S^)Sro]Hkhqp1e'G9";IS5?ȼ7[4ݹ~TF-t/x$D宩<ZϟC?pAYרAˎ3\_9|п->>?蠃N8`tLHU>% g}HY+WF;3[n%.*/wɒs',X"}2g.bulLcoEd5㥗A:kR |zhc,>$3~|>b,n,@IDATŐ<;v|ZdyZi#uW#[uG<ˇt=t t;v0a7a\3@w5RJp==3_mw'y?b( Z'~cs|? a)pWy}Hͧu:]a2 ^3gQBխO{;c~QءAE)>݀ǸMB TVܑdsO.Sxb''K,UY_uM&YyJqG' :|zᅂl֜w_V;U-S〔7x=vBGCJtغ?_;lG=%?;gtBI:) |U߲gv˭u)"_ ㏧#s:q*y Fc5.K￿2߂jAX~Wzui=}?t= ϤQGIYFgM\r"ʕLl<"FK]O)5&cS!O>\4"W#c܆\w=m%/] ?[B bcfTRb#b|ϻ=@l} me yϥLbpהl!CR ׄqMO& ?`5TBUXG,U_jlcB6F1V6oB*Tj8cM0+~0drtɸRz7Σ5~cS/ż]aooWht7ȽA +L4ʟMVG v:'"6'k<b̜5k_ql'ZA_?bO}!\u=w>iMAfb;ߋ"ؽV%tܑ9p(ט+}:ڌa"λgSR:M4a4&x%C:jMӘ"?f=ȶffMu4M[(ܸDka/גo?au}KOpM#a|1K]mW`%1qWvUwi欙y򯌏?`,^xD7jBñ#KƏ_!:*‡_z`X'݂y5 .OIlS|3#tnG7KU箛Qcoz]p<Ï_͛Ґ8 ;>fScK;o}ނ_}zh> SRe9S~݅<Իٸ 1.':׸ p߾}z:C@ơGp@>OC;rPU]{2C)=NE;HrzV;&?gĺvaw5p x篥X$ܗN9n]kO>OFCgыg?d0>=_??vIZzGi,>Vu(| ޽s%'.DV+Bd.\CS~wXϘiXNXo.[4]/?xW#Dpa Y'QصI9c&Ó=wߍ'xT{A{Ƙ؁\˕c{ˎv_Ns]/zNww|z .u$\b|p{7Z;u`wR| _;ۄIRɟWIjw$\uԲe iy-?u,\!?]w457!ԓ'M:W#x+ v]lWg瘱cG̓Y'"زRi}tzm0:oM">[of'8T0q_GguƯ>]9xVa]xA| o.y;ipC?w<~,PX3{/>ZEoO}1]qْ䎿SwSgG[??5D_8)?,_:[SI8PG5qRJ4(w,՚e7W{XNEv3k{owmn̴oxS]'?p/oفH%<PKBm<0:zɺjY3c7o$ V1PyP6]'g$-Vj#?I| vҒ_nFd_q%.sbY~A.% Ld8L`U < wFBcO?dE; ˿mPF[Yu^6lr}ycUrot4n"w٥zGW,Y]xŴݟ/zw\]9;DKMvXw粟㗝yuGNlצ6t+t%B =fMn`D a_|;r ;>;>sM4A>4;H,bT&bp\7Z{@%yo:3Eg4!`)[ յ6%/;>MɟλB}r"@6t m+ S,uVWBEZ :ߩ={pD ׭ >PFGuM}#cn_f߿KɁ5%oORkw}!#SO;şW\avV`'uGBq }8 D@ax3=XϏcÎO"ٱϿ"Î, :Or=͛Ncg>Wt:1Y^}3]ywSEܰ,@Lr@/.~蛧+#1f;uB_zB_~]ϼn,>0?}`P)3'G;> ./_x!۴v;>1O2ep2v\|rGÎ?Q__}{ιdx]qUT?ZK!蠣\kU|Xzϲ}2ݜe xc>gqU^SXYBO?5|!*nEK7} B\UcYȆRy6xCqי\ ƀ7^Hu6]7nu׊9ԯOo <:ڢ>gz˭Sʫ!m xNNE4/n'x#*[<MDZeȠԿ&bʒ"MAC4=34;Jmz=O|!%BTEhw$nݗo .+ve\&7 tuTv[&m( !whl. Îu1I'H#Fb+`*V_bv*l;ĥ5Db#D@O?tϥO;HSp#I51E%ԶK.@bWsKOլYsAr/=]0`-᮳0 ٟBfe skMrh3Ck*??jO!?9?g;2V\ɎO. \-G9KgDM zn9?n$䵉w!?Wi|*WD}/ڱrQuu;HL3!C7ޘWX9en'8aSmĜlc_?63[FR,3ogO}m7?y֜kÑh G&u@C+og/eUL^ e!쏛P ÍAOlO6cO0@^IjV_h0Q|K9V F<><[-$azi Da~12G'I'C 6B"y cÖA`~=< h?);tЁ 5'OYyw'޹"?ROd6Ey>Xyr _:GOҨG ^OG;k]HpWf̠k 4u>*W,KJW2]~ITGH m٦trAmt 2v|j,;>!bZj'^} ^zY4h؀F8Z.G]NJeW#U7vFrOhaŊҖt~8%SNAK (&MR:޴fS׼O;T $ /HvAm/X@g~\ڿOeȐ /q&vB5zo' wJ UbU* Ot GZc|,w_oy/d˷/υiQE?t|<ϻ䊰sftvb ȅX?Q԰aCiW;a"w(X61v*@pQ).eÎL `q?ZjEW\u=X;o=J^OΟ#=-Ta=D@پc|jp==|^nD!qY_˺a#Ďr^$?e 2_`;j@5 _9eG&$֖Eҩ'5kn{ hਣ[pEtabTbnV0:( ;hu1:A hAr?Ÿ,#<)RO co|\;>! upT[lkqboЕz*~&}֙n*Frl0ؿXxw*֧]&i=z`|Ӷ-̻-y ; @,J7΃ Ecn-W!`w|R $C.  @<VPSLv|;>gy)4 L'GO+UW_y(XʟC oT6moOrՍJ?~2UZOnY= ۦwU7>Sr=睛<9{Kz\ݒyaU=N~T/_N>/.3i|'HH f0Ɵj7>{%&LOЈe?a'2.d㏍?Y_a+?7wd [M$?7';>ȭG25Ϥ,+ye9T\FA2&X/T4+AdM I`b?.SIҸ$e(y ŋ?e?-ZCO9`Q pcJ" s s|+-HeWyI)*aE,8%mÎB ;>-FSwmOS瞥-ɟݺѾ@ժT;} ZO;zCժU29XhuC"'/nI{W!EU YOFG9 Dpw!r+䗤҈7 ?2>tqʕwt͘2+_5ovbZN] 7Z_><<ѣo3¨{ロ&O8:HT%؟F)=R@&~?Yp!=5Xr4zMTn= GEp.||;]/x0xRwؠO4wu3]v"xc#FFMc׷nNJ}Y.>@_Fgtۭ"@Ÿ (֭%z4z*8k+T}DkGu8gH˒3۟WP+āj!l'ׯWjoRGv s'gPUzf+~PjUS"gN6XfϽsv8\'vbQǎ[O?IanY7z&_]tvS nuާЃ6~9Z❜Vu5j֠3EB*Y8|'N̬3M:p[+BC!+nnuTU˭$/в\?2~98nuDװ3]pÎW#A RV7ݴ "=eṌw'iu7KWbu 7̙3_uvYgS9W DrQG{1ԩKyI녙[ |u=pصmv- ?\ƍ]v)5l?n.5`Gr\=>T]`oUP$&q=wY  mbaW]95sdiX_ wcT/t&O l0QD#(UBNHꞿɿ_b_u~ >>Ls9}h=wOgf݈^5pA㰳q |5 xw|@YfR}S?6uk㯍blynaA #S(>f`aC*NVe.z i7޿_kU2>1bLvt,ׄUZ\q>} ^+'ogO{C8fD"16k4z;.l"^*q lଖbs/u|1WgM<`1&_5kԤ6۴ARrW$*A 8 dgϦYΒ֕o٬95mmR.}+>_߸Ns>t{/cW(`A3~$`瞧W(=ߝW[lElCo?}½\3Kf7m#;|\_S<ޑMmVO>_{V,_uV@͙3f͜ǿ-)޺3[lA[3)G|3 òmԤ@Oˇz/_?WάBX\koףg瞣?.ngA{W1Oĸ7jdPdzPmRڵh>>Lpևb/WymϿF!(OT6l,_9զM[>7o>Df-ʟ;BYmK^)nԸQjN4wz7?u|Fgɑlr?>?1Iw0&?ka%쟭?ן0Q~@|vo4r06jvŻ!}w2vZoW{A̓/.a}qFhxtc]_M&?,?EbG{*^p<63g#6e}qlX/\rꁳJR!oʕXEwŸ;D}^-]YRWq9K8QxWyRlT ;ɻ',q2GBI@?|tC±'"KNf|1hEZ"^LI"] ǒ"1!6KXFŒMihz;60z\(!V\1/Mi1J9Č1 $\* $>@p;g`P?vj| l(sWHo3&\ UBx\{ N9@6\㧥?!Hv:_ogWEog?(?[b̉cIW[gYaeoᅭ_AL: m@rt]>WGJ*@^1#^LJL~b?18+p1o< `R6%ɯWnO/_y `R:W+B7 `+OLJR yAk_Zn瞣28['Hby^C?"?FK=ȗV"ŻT5,o-Z ҥ襗fX3#vR +Cn]ׅXB3^aO~q2GB4cjtk9}wtBtArraRj۶-]z@?_khMJ{;ȋ1.cSZf?`@ ?la[q|g?dxAu'D)g9X, "65Zr.0/Yq޿idjxW_ 2Vɂw9c)ZYRRʿv*)8ˣRťp'\hɘ{Rt .PU@7iO#֊YĕG@5p_?ʡZbN/>h >l)+)xU?βkN ?2ʤ { \L$ |>b$5hl4H p.jAF\qHY:jz隫vj`OA6m5or~ [︓6Y) x6Ç@<4ZK|˼LɈo?la LfA$ۛ+gHHlKČ=3j믶 O V(<5_#=Iur1]Fla*iZgGɾD[c?$A'cutnmy`>O prNjLSőL0?J5>MPx )NVs?'?Qёx )NVs?'?Qёx )NVs?'?Qёx )NVs?DSItpsvXN:r x- F\#qe Dg"? BmV4rf=B,1?fgS '&)[컎+W_|AJl0*ReY/܀GydWxMTLȷں5]~Rr-7#?,\nBRZh!M?Ͽ4_iit)l0~|-\zm$kc,^ITy66B[aO8PLXJd~c,ߘ A8omWoxwSr<'gVNV5E)@?OI,ɘYdO.吂R?0ْA_*L%(Ư0hN,zZ8}p+6ͪ _̀Ř?b`,&fMxD"}1u? =@l1~5CĀD&SoVКe_Sek;Db e03Q?xAmệHğj'_(_ 8꽋81o wc6ОNb'l>@]'5;Vp_5$e"PK|N*qH]kSQi*msTC XӜbJ#Pi(SJRWŚlTJF"5U␺-4gT4h9>FҦQ>HM8@5)٨469Ej!uZiNFi)RS%+bMs}6*@M|N*qH]kSQi*msTC XӜbJ#Pi(SJRWŚlTJF"5U␺-4gT4h9>FҦQ>HM8@5)٨469Ej!uZiNFi)RS%+bMs}6*@M|N*qH]kSQi*msTC XӜbJ#Pi(SJRWŚlTJF"5U␺-4gT4h9>FҦQ>HM8@5)٨469Ej!u|nI:;jg190|x0mCPYWԁJ&a6_gX&d_?d0o͝lr?j(8):{b*̤o޿$Ew?zо`a֟m:XNv|EdMy+p8„%$ 4-ю0a~I.&HMA 8T~I.&HM rDTXP%$ 45QaAb|д w'‚/$)ɿ *$;T~I.&HMM%DTXP%$ 4- >iɄ   !6$go{ |x֟( {-?HS)^qx*u$44Yrcdvl jɟ??]qtBL XXf_a㏍?6e`e5yװ˥ ^EH5t8um2*-pNgbsz]'?4'2J 'Df\™YK:j/ ?F™53oBƲ:b*#>a ~ݥDPƁJ}c/W~8!!`icB}W kg?fmAgU46~Da?xq˹%h,vo%MnEL>ȇ4f:2({k7Dr6k_l*4?l~BͿmmo^|B6vD4^$K1^TƯJ>`_`?@IDATlaD`` A?D0ә^$%1C@6m6`5B_JKKAԂ "urR%Y\jgTQ1ߦ+]5MR+ZcT '-)JWM*ׄZ$cT UbG'%@b8&-2Y$b8&! -%٠(1*A\iDah@I6(J@Wj@lQ%"P b8&7kѺ{^,ȵuڳlf$0Z(J CK-=??fy,C?~A Ev֍y9//'=t4IN?5o6o93J7lNAWCU\4Ѐtgma6g  (Oׇ0 ͿEOxtl_ kOd'6VC/ *挔GTBx&2M]t.n'% ,qZZGSGL&PeqapoJ4\ܞ?r X 6fB\_'wpU"{R)]=.)Fkd^*%GKsmi\a *oMx̴rpZD 46eͿm_` llRö d\l֟m֟m֟m/޿G{hzAj㣽'y' wxRr@*٨:(% @h [z@9_ٟؒ fI +Q Gl-aǿO^V,SbEC-2\A˲{ 8%(8amhX2ksa#Qsr_וLrHK]L?yu_6xaO6?e\ͿA:J6N<=rzK9<Ϳm8CCIJTG?cV7JUBA.Z.ϡ rk\]CJp NW Źhͻ4>* S sњwi|U(%\(8]%5P*K&PL-pJ(Ekޥ9TTpMZtPּKs@.@1*8yPR9\5bjUBq.Z.ϡ rk\]CJp NW Źhͻ4>* S sњwi|U(%\(8]%5P*K&PL-pJ(Ekޥ9TTpMZtPּKs@.@1*8yPR9\5bjUBq.Z.ϡ rk\]CJp NW Źhͻ4>* S sњwi|U(%\(8]%5P*K&PL-pJ(Ekޥ9TTpMZtPּKs@.@1*8FhZ߬O}wϔzĵj*EF,€+VmCjQ%v K&?YxQw_l54.tA.;\F[g EE?Hʕ%T. ∴ׁ9*Bɣ^ av3N+niED,2?!05@pD$ǽ0 D6ց9*3 a'mh@awr0KD!MUBIJ@#.g>LL=QHSP<P!?'ӿDOT%$.p:B|aCпe,I'/BA˄_\1@3m1R bz_Ey$н\vSbebWPebm1v_0,a?B`yf/dBeOWlŭSO H 4ƔKG{;:yԢU+ :`\g2~-g2ޚM_p!JaÄߐͿ_>l/JlOxn߸na'*Nmg.~s~)xMGdt16@ׅCk&$xDf^>M'm_3CN%rE4xTfF%I^>M'fT<*F?f~Ek/ş }X 8zyrnO2>RPybYXXJVbo OMlB6=evn;Zh1l*UO߾7_=ſ_TN]gJ\]t%ӒKM[?u|bކ=x j%fQa]l#k`mw'R*Uŗ{2}4(vo_Eʥ* c^4`@i? @Bȝ-|E N!_[e= t8C68:o?x)c&C-f%dm6!;-=A*rzw s8׋XsԼDT6gJН JhnдJI$!̫/2LqIYiRW!aĴ$U i*,r$8BM&ݨ1[XJRW!1SжD= ٟR>X,<Sa+/Ho'<2qFb_Q۞zO%KD2xԺuRKVЂ/>7|-]ʿ; 7o\{޼OiOlxMTeZBZjѢ|IskM<*!nt޹90k_O͚mIwLNbpoЀF,"{/M0>)Tb%O=$Zp)g4` Vkt%_Ky3ފtI:Xj5jԸ)g`˂gK ֡yQ uK9?8l%(rɽ +W9ϡ>睳U`n?\4]{IWNwߥ?8Wn}:ӨiӦ+3f19ԶݶTFo_}FN7Ǒo9aFTbZd)}[%h?f0oH¿*BWz`| 18@T[,Nm$7_p0&?F-߈1o_p/)ѿݺQG?/p$ҧswv DߴiSiѵ{|Yk/6d:OkE=TE6s_4`tV?lv Hߐ';ODU}N:=fmF=O;Zjϳf΢P`\=樛g>ޛ]Gj7 :|S6T^Gu6#`]w'$?s m7/c6c%6,+0~o„Tje|} |҅Δ?!%_ԾN?=Z)@U*Ua'X ׬Aq_;ҟ^\ڕ-[& .;mßц˼/EЩ'w_?SF˗?ObaA!{ {}[7VN?7oz"{kǾoyʀ?{~2 a{eAU0}N*Rbǧf[|u1ؒ{9iID"9O8zr2-R& %1->Og}Vr:q<3uǧ T0 ~q7/LnʟJO,O>L^zFl7& m*}U'u_;~$Z ͛9M3Y2C;R)g͚I8):t㏿ x\r :㴞17*ƍѰ#W_c"** `Bk &gIL()|TL&ψң3PR"0%L'1GgDQaZK0<#NbJ@I `29xFĔG @h-dr8)=:%% ZqSztJJ03$ >* `Bk &gIL()|TL&ψң3PR"0%L'1GgDQaZK0<#NbJ@I `29xFĔG @h-dr8)=:%% ZqSztJJ03$ >* `Bk &gIL()|TL&ψң3PR"0h |JL2fZSXsJ#"F\ p9GCF{M7C} 0 TJO>XL>SM"0KOP>(Eb'8z{M[ohN;e'ϡ?u]w/}|yݨNi-]^|ESц5m,ֿ-mIuקPhӓӟDβ-Z^bDYD?W'W^AZ?P3Rc{.vOXgӓ؉W_gU v7^;eZw܉_:Q76~:rz(_n԰!K/> OD|Qi&Wr(3߰"6iwѷ/{S˖["r nݒ/V Xqû;T^}Y:}إczW矕6m~Ӗ͚W_}I}7կ[TbEZ<8~"v(O5oNm|+F4wޑ,-C*s;_qeƛh_J]Jլ-[mݚ8oGJ?+W-7 gϤA<Aih!G NPmaGrU߃g#>Ls?T. j S6; 5= }C X +Hr_q#_jU㏗4 Aܮ!/0N8V};WfM:h͚RڵhҥwI~GgfUVw|Nc=tpϽӦLhK(T|n2f[җ 4pS;^:!=ɽo'v qO^PI?S\:/Lp+MLXڶ7^ahY㯖߳OƁOgY:G[a<ͤoG`>(\O?]ߌ^k$u~_ LRZw9c;N-תM7zx׉WSi9sW]}55 E NԪXs/) !b4H)t`#-H``v<%lP39]S΁{fwvggg99}>HS ӌ'?l$.&o8x5kͿ<;gϔma/_nƔT^_gTx 0n8?OO+J!8,biZ>|C~2FCz1cQ:R]+?6L8y^B5k?6ԯΦIV,nܯgt/_qMre7AIZ±.Cٲy>aBP'(硨tX#J "tT; M^tih1G]TjՀxKsKFE/Q* .Lq;ըY+ eҥ^:wD)Ey8ߧnMU8OS(,\+b3?+> #DV=f,Bwc(MB=p8J/+Z(̈́r ɟ~\sq]VJCp{`r?|5TP0kLÆtWBwܱ[RBH]$oJw~#(f0NQ*S S ID] /HeCK~>HCOEVX|#bi+.xsm|sgBB W[EshԈaŴ>qװ~}ŝmAG}4ڑK ]%H"(=LO>VYm?I(P  >vXvc7=z#]u%[."J?-hP4g7"Yf#.ٵmsm Us\_/]1gquԑ'IgeÇPK+X z,P@?f͚Ҷ[B6U"mMm#_2].NQ*S jߜy* 2%$گ%)Rf8KL1zumq L[s5?#9bSXe|jΝh?_AWv"mX:_qƎOe˖۶[i?XK?Cp}C[s뭂ޢAFE^\3fi1(PF iWNqZA\ß~3;.ύng:k?6$ns?TxԩC=^/^X1V|֐Oo6S<z4hPYWr>~^CeSwݺ^ 2tU;|>T8׏M G x4anxl?$^X柼_[|5CIP>/\*3|8R1&_}T%⾢U*mغ4i+WΝ;Z! VݺS:K*M&Ov^z5h <AưB*ZBv:NvO>P^١ ,>͙?ӿeVtɥlDiuCX?өk7(i\ իP :.qer ;v/t 'w^m9J2m'Xks5ɡ RP> {sXhoai_~A=o.uT3e T$V>ں};{X+D˔24N;õc` i[tYg+r_M9`^d⿶׷.8_ e_Hi7X:_"g:/X$׶ ކk%?V7c,aSCEob yp .ӟ-}u˦h#[s% J.1XJUi/A} `ʔh W-0\>s|,D\wYy+K*Tfϛ˭GuI0TTMZ.OW7Rg}*rtܥ}zHo;w CUʸ\+ڵ+ʌ ?V"gӏxL4d2!P+R(Z6nP?$;p`iOwz;Fӟ@c_ _%7F`c/N cb??Flsfkq._Y|ΫAJ󦛘@&֫]~`AQ]y{soT!s+ӈ/ߣhGEV$/`7mH󠨔/_~ g}=X s>R͚iF<4Mzo|X@ΏZ^={H m=?°/pg?{_׷ƂmE_(>A<2(!;^`tPT.WanD3c7 pd(+?6CM80 %\_%[YLc"DZ g,,H.Ð8 ݨgm MN8d:b%k3O<9P|: P|=} %}GשKժ:֭]KE%E J+4Zq=:lߣ?[k1jB\(A8RXi٪}创{D;ϟ JcL>E").v@g_zuX)KzuE|/W,n%)SEB[(imO? Z+++Z-Nm76种j($_ժUDד?BSҠa#jР%O?CǏ/n 9Da!f3.Oesϧ ӗ$لw>tqPC?͜9K*lYJ*ǶԸP?neɒ%EIXz(p }o 4WR3ZlMr ,>tN#tX* F$8 'P/ ?+W]:Ci駞I'Uegg|Vrŗߤr[|,;F-4ʔ*`( S0N#lIŰ5s,0 r^Ij8a_by\ݻ"ر쳥G]L3NK* _=XJD*q)󊫤_O̙P\>!I?(el޽f''hQ(4ƍU?%G]8}3J+DbOPX sJR'uM8 Dw]x]w][;Ѐ;;Nl{c>JTGWn];LzGMBj0''~\VA^u0?7X1d^k&I'Aq'W|vmӖ.-"zgN:^zK%I^w;%/{,|1g?ܙ73s0t0Lο'}bŧlr݋8?8q2*[F,nׯw7ƺ},Ep؋FY">j3 5᳇i_.~9m\ sֽ̱O/9y 7\x9X+4l:*Tϖ`,^ϻo|Y| b_ǃ/mug,_l/H_K}lgm <)C| }Md0vKz6_Zu:K߱c͛7XOG˥ ONieΝfm,9;Hq^{ ߱};-ͽo(|\7AEL Bya5nXnLhO7n.JqϚ1 F)jq(:d(pխ{ ťG`F͚4h~ҩsZjMϊOruM .l(fB4bNSbE9 wl ߲%4]~ȟE)J5a9Ete( gŧu"!Ts%RkO=$ML|Q2B\(K}(0sw:_~wQuod;f4=sE%s<#p핗_/GhR;ng:(IOoX eF0t(~u6׶,sO.O7'欙CIojJFw?E5^\zɧhW\&UiAX DQq_P1ubQ碅 Re]A[6G KI+H$t[PB(EeE -Ko@ 5_t$IFʕlڥ#` VJK;wիX P\{2T_?)Ǝ(O\޴)SsY#ǎ U*m֯B/%K3EUE,f92 "(f M[#_&ZLO72~/=OE?'tSkg?]ؗ_f̓P|ZC:S`+fe˖#,=M4sl|h8ܵBIdW_ E/Je=],‚qkx_F#tXR'| ,G2Zc &cyc?Co,HU˺<ߵs}4T_@[NǞ(?,|9D5ٚ\}uE2Y_[?By_JDGv&DqleO1?$_*KDA nJZ""l&2FM/MIKD$$ a(6l*wMIKD$&L ~Q6gOuQ1Lt ЅL}{@/+ 0xg8)LrfKn)Z زKp 2ğ\p%T@",U0IVvgM7_K0e˕wDm[A %ЛQ":_4b(4Xi\\ڟk:ٴ3g}gb(>\'G ҜY3^R;]zE㠰Q\O?X>C^ *\ɼ] )L[lPD/%_ժUvmG|@qj`(9.pB(#m>(#~VbdEnݺ, ?[uv U\rQ}o|"ĖT3_tŢe?asJoѺX|brBIKC~.]ÚBUPbڰaȳA+/0@~mժ9z0$;jZK-ؚv,:S51f]Qi;_;1dq4bJ2ԋob JDSRK%e5aå֨QC sj}|\0q=V m۷8Yڟ&twPo 3*k7OBrSl2*~'g// JhɳK5kG΍dOt}:7j? ߁Hqq߇`<:C_Xól2u AIVymwU{1ZtgÅzF;m,(-P~zXW8V|ZÊQhg\W+Y| ?0G#gcr KگoҤ]ż=PRM9Y3gfeq}3lٻ_`ǣ+k?g֜T[|ZC.[|e``}ͻ6go9HA!XMfk4aTZ5PK{Yi ڴa#Z Q^2yx1ګ ٯΚ=|Aj׮{oH4#gB) |RJ_'1GOڵ syf˨gv&?j?6aac[o,G~ma/[۝߶i?\h@IDATt#G[߶D ,<R9PnDbZwAZKB"MKa ?So9!>mAB cO_lͿ3`Eh5 ;G4'*Q|kL"㏿)S #2F%q~w;oYI .Ou /u?6]%dQϞqs;{J*EM5N=]:x<,>qX珨`)u:@2U=p-hGaժWOX| uᲂ[es6D&=/K1R8Zs_Qpo[οmiO[֟XG!XF$nfdgyqpYCN~6` [ûϬ)XsP'IH4}ris̝;dž~Nr <dE#C:1m B(

L`ȧQG %wߡV|t_4g7փg俺u[`%o,X~/f|rscJ*8{ӧMKUANѕ8BA/Ci=<Ť6mRbˉxu+iT|UdCW7nDwmWZ&Ǎr;qUn[/ީSQ,8?@esuӍ-$1Dh%- cr-jѣRJP*A6tIEțzPI(U kU(̚_ eV ZQ,S?JXe'?sR6=,܎~V^%VFOPkq)lb1g^p(|DG=t[5ʂei%,hzSVw:͂VU5fU26|%i3(`Fij1B+\镰%(B (ӧQJʗ5nB;C1pSX|_,gӷ`Lp?~DA9{<_*>(,:\㤘aūEt [L|܌_r%tt0 gJ.չyO?2̗IcjTPlټ@ (僅^={ƍ V-[? j~egƍӥ^4{_yPFiy<.5~7oKww?G,**{~'?w?0ʂvϚ4nC/Ls]Ϧz֛f}WxتyS*ZM'ϡړ/&ǟ$ݓ1@R1ݎ???We?&Lb^i5Y|ԩc=^/Q򥰆Owb=ާ;nMŊ˱gy㍲k̓ Ν8NCI[@wEGu$g*\@q?Ǟx}:V-_j!":v(w…?q9 qheow_[l)N'ao/_'o ;&Yؘ5 >D<]&,Gomajtg&MBcL'oy jY!C=*+]z~waϔ~\ z_`V:%x@G}ӷDrш1, F;_lN:tEubO~/#P DSV,*SN:.bVk8ohvzԭ[7i/=OG:uϰBQ7VTF "Χ}LսS!h[oIz?->+>u,y|1iB7 ~Oww& he,zWB9?Өۍ74g]Ohٚ.gmaukTC[( q5-/HO?w,?B|i1Xnݪ9M>Gfϔ:T^ye/낋.k7J|0e +ZVjִqsP"E}͛6CɮFvJL_|F᪜_+toqfȷeӦ b&&?y/[ytyQ(Idɳи c42% wwr |8韗C M (CC/>{Y*[<u䑴m;ܠh?!5s~:r;YQp"PZ~"d?];wL=g|Q\%v'A*[(ǹ8c8cWr`J1X2jٺⲠ7y8n\u97N:.ri7 \.Q1?/8'o6(|dp]K9=|͆G7gqٯ9/}v2m.+MKIϣ X$?m6[<?5>@ˆU$J`|(#R..F򟓳|R.V ?/`~wT8ϭ4o wpoq ??U^ۯ} `ן*>!rٲԫWӋλ eKZbX67 bXi}C&- 'L?ʕuJzWx}j%,$ϢU+WJSjj*uUsJ9o+۲bG@5-y`8>"7rR%咱?_0ɟ}X(X]xim /,_tY:/VO|_2@%W`X bi&[ g ^~^'w-0gQ|*P\%,Gu+S|aai@|IeiƍBP{J4tp/JY=`sX =Fhb@I֛iPP|Jk|/_^:wꄮ ~DžP,۶)>)uv#zY|Ӽys쟗xao  +Vo1ȟ6m҅\(o@?$i_Rr +Wy"^v7P>}T^rg%oww %KuԦu+ܭ q3CI}|`B@Im<U-˥F CC{ l\x/vqM'X.PYȄu׉w;'(ok})t73ϢN]`7|c{ӿ"FB?k[g{֨NC,ehPL (DKNnI'@'xre|n4IM0m;W(/]ai%,1d(>/!OϙEBLnϖR([wMa gƵ~ctYgK޽{RaUoҽ=,U= e'˟=忲Jz$Z幰1ݨoV<Jd۲e(6f lRehI1ϛ;!)Vp*9sS"E3eͽz _J aqLZhZyZi7#BW9?E SÆw8آuOi}&LDp3w>94hL.mMI98#;~V4g>Ͽ1E+wawsL7F? Z4%x|>|xlR81]L00ko$hQfGM{2oY:+͡t q5{6,>⟏Gnnق+'| >o6i?e%X0u/W79]߮\X^$Y,P| cO%?M6&dkU?m:ȀeLʸ/Î?ndK7NF0eX1oo;vb (֟rO_lm63pl B[ sOLD `Y'cKw ܓ!Zws`f1J@8#b9񟣃0HQ~GbN`7X~c`' <c̿AS>ٱOKnhY4h)JŖFli.Z|)ԣ./D#G,t, q?|nq-+)G,js]("[nfPBjܤ)]UpX6vjW/&Q8~'([sqa)jtZbi3_->UӖm߸nuP&:‹4Od(IxP۱s;pk6t睠2 ޻|/%+8}{};(3zOGmԩcǔs"c۷omө3f YPMgk= -~MȠi4 ƹ8?5w_pdw0sGD:g_i1g-ZkԾ=K,ISϔey)bŋtyhԨ?btuxg< `1X{ue,zxqWP[p1эQ{[Byjw;X= ?%bfSy (/7뺉ib7?Sֿy?2^6L5rl_[K$?M(xax~yh$?0x ?d &'_ŧ(G-.2H"F*@CQ|ˇY0diOF*9Go3[d]dOav[\cBv.{qi 9H#y"c?l\衇!h3sb -F]v]%>Xn- }$'"SU$mwL+J*t,>#>_. #a-P|:`ީSX?#s^ _nޢ%K\͛PZ5_P/BW#n3P)R2| ʗO|ȊOl IJKhӥwrًϿ(Ah#~Ia]&Ƈ/[NM??..:bʿ#X.(ކ`}M<t׳a [0%h(>ŧm[S$͜5 v_- ӿԁP}(Xp(h U"MxLORI P>d(1o߱]kyRϿO@ł>}j+[Cp7x^sf q%˖-Ga}ڵjB!|S 7ޜA״?2I~4z,7X̿MҖ͛_taIl9mU!-[ҙg<V8}31pȸW_{~)~pOQU#a&}8%'ky峕+WR7hA (MPxaB:Jy(0Uq]AeB[o<xX)hsTYNJ`Ņ뮹rv]D(h$| `j!U'ϊO5lC6BWr6Db\ZpB)TXW$ `@> \eArJJ RPqmauq(>42I;8RleJFq6'icuQ8e%nG؉ 2Zu tQ9?5~\8EBe+@q '6h;{NA͢JJw~FHn`aL~Ae\Lঽ(o5s0`  G@?q3kۃ~ :dZ{1TL0T~3XsbkEȆ No8藺?g/|vs>T+|ɧԧOo7r9V!4wuK,t|v7 )x/_WC셪Z;*&=pSσ2=[lfV7U+TȖjyҟ\61"Hr1Ox!73$1KqÂi?w/#!28H7Pdc/?7M N0J)Ϳ`@8Zc Hk/?7lϡpo^DOϢةEMJ7kH7m>G_)\gy$"6L0OM 4]5%-Lcc ;o#@O_ORp |$~+>Z =':'璧MPP`ĥ.%a u_yn]g^tyz/`8# W,MUly-]nw9Ay>E bqTArC @%-PNG]nvBuoA `"OvlUawqsoŧ/`[%hs,>MAӛH͢L?zx g2'|tى`e6yZF.%%ۙw%.L?p4g,b'cNtgK ?HmC-F,R9=[߄ሟqsɧP=RNn )K{ &yD0U0X ĥ->W]1Z;J>~_O}RFF>a(ݷ4#ZO5jO"`A^L n?x3O ğ=\ *d!u _㾐]l3&L߲O9sb#yͿN.UG᫯o[rysҶ-ۨ+,~)tJ2ݴY3t*\ ZWO~)˲AZhC7KlE+7L7w(ݿ~?ov +~'B(S)μv6& BF|1c6$bXR^8ʔ.#<נޕB+=t҉'KOwEPs\.+e0+Lʥ3+]Y)b P~+AM-{"Ynr+eY(Lw*!+"uև!xG_:>%}tGR{W^!%n$7Bc(񓅱Vhð%1Tlyu ohaG;0~$ʗEMa} ɊO/oT ?\ ;z+|ns5Z%t蓯3.`U8 B>::W?+z}aPٰqC81SO=Z+Qͅ,λb9RX7cnќoEY+T@իB|Zn_q #Icat3`t8T_o7o1~)VN=֡>^zǤ{2W#kue:[*U&L$Ӽs~(VCC V6n"OҿdI.Z̓ų |gq`t F|f\h ƿ/U0l~Ctl{m׵Zs`.k~bK i|Ѩ+Ekh-s^_hΝMbtZ l~ڊҬIݎҥ{aL[@џܝFngG俍?& \ewyT_YC:C;KLdЛy9lm9X=r1싴L&?B7Ytoמ=]ŏ`8}翋7nԴNr蛯P~w?~K9̀)ɘ(ԣn (dLMIDЧu#t)>05%CzME8̀)ɘ(ԣn.@2$cpS)X05%CzԍХHfԔdL}Q7k@2$cpS ¡O=`"HfԔdL}Q7Bs SS1Q8GQ ¡O=FR|$3`jJ2& >5p SS1Q8G]ρdLMIDЧuSF$3`jJ2& >K9̀)ɘ(ԣn (dLMIDЧu#t)>05%CzME8̀)ɘ(ԣn.@2)" >E+ .z{rF**.v{SWnʎY o?[p( 9%m۶iӦ f%#<*\ @~V|%/< r¢C-(-Ҋ/˖X-o_5J*T_|3KH&Ne+WSP+Y$p҉buW_M7?\;P:GV`SjU}đxr*e {!իW;o-< H5div._,V ރ+[*ըQGP>tª+qÆO|ِGQŃ*RqkZl)vnvbP\}a]LM_J6nX/Ԋ+)H՛N8ͳUWߞ̸߼yS*xIb~ OcڌTd XƂBg~&X|?lţ='KRhww4o7wlwן66։V_/ol/2DO# "qRQx(Ңw*0r?_(mYAX +̓ S<8c??p(sA%E<ui;LOBi1^0?N2ĥu0Nͩ)r/XD t1iـ@AnG8PF8D0}xdrT0m07o7C|םwc?s Ro<ϱwS(m{o朹{(mP4FI\mNV)>5k ID=z$my睷JGzomcQ N'f|Ta*צ駟kZ uq<lref(>٫7Q6?3g81miO[s+D<9~gƟpf=&L1c%!6`0ѬU7T\0 e>GmA40~7kO4*±zdc[|nH*7]wGΑ8VݼćG\1\L,cpQŇM(D@IDAT ggg/F'/?&2`1YpT,_dmjtG#ҍXNgU/r_fܝvDćxM\D -BFƟ&L5kRree~,?eUT)#7'g .o1 ^2"{%Px@߱s'+4z(:x{ t9e*ЦEB==zD'|#K4u$^!oq"eȵ=?2O3_&M+n%1?lxΟva/[_%rF LjE$֟ĆlO~?Be*x߶xB~_;b>`YD+>yz $uLT \ = Ɵ_0xyL=zL>5L5kWd/;]tWDb[OliO3Xο^];;;p;:mo]hbo#2$ *ݿabg;x́KD^҇%'Ih GDqԼa\Ih G$Լa6/Mf?G%ϥ ?I- !#Jϥ F$$x~(>7ԒpQ?\j0 kORKiGsy(?I- !#Jϥ F$$x~(>7u_v>fg \DC5`ݚVpP6F?y6L?O0|#s68R&њUr 6:G3&kͿx?[֟@rao' µ.(m-|»+F?mmo߶%d_Vwxlmo0??9H;Uo'YmӋd·8ݪUCΓ)S5M0v9衐t1|ggMSe‚v/2KFx-Oѱƿ?6z"_`)4M]5rqbc'څ܌5Y9.l6્|*G?8W9دog_ M6k^e?mmߘ_ _ $]~~_'wnoKd?~'Y\^2OtT#zUv8FsX`m">&m_[78XQĶ5?ݪ;z'EX/_?urmmo;?ݿ;t(!?BIp𙋝?aoLvb/O:zY'$x a0 < "χYd,(F>Z,ar2ZaxEX#-x09a0 < "χYd,(F>Z,ar2ZaxEX#-x09a0 < "χYd,(F>Z,a]v]U'(%CP_wM/$hK3B?91YüX\2q?<K3 b=clI~ux]t,S=;50oy\ə'Wmm2/(|́S?}GCKC.)bHĕ9،'o̿#?2h BXmhEcܿ2xoy.VPXnH7|Fb CSQk_0`ScE,U7ˆ@*ge>aXznķJ&<)< +:!Pk۞pRRʈ?d^|x;bD5hȧ9!&V)3yN2q 1!h6I>!ǓڿDRE C_jH^)XB 1_)\z.^Q@MD1ĊHPuh>//C ?1dϖUt3(HCd4E+O̿Y@~{iZYa_`Xh9?-d2a %RzpR`_XA~{i y'}iQ6få>z1i`9 m7qPPmäcBdm#}Y4&1S?_6i 7Ѱc &??M qq^8/CBAEN'iz L+}.o,=*W\ަYzT%0 MK`b_syfQľ26ңR/}emG^@4KJ&>iz L+}.o,=*W\ަYzT%0 MK`b_syfQľ26ңR/}emG^Lp5PKZg0+/+#r8Iah#lso֝쎖2 HA᪁QE9ZlvI.-mWJ(_ Їzj??X`G"ljENdǒ?P(#=0r׌`'O?CD8q҉?24zK Oߢ S>wD L(SWYD03g&PJQ|"AyP_aNoLP'PH@咄`?yM;W; 2+> Gh;KM R6 ϲH-YYuSi"i\FɨPy5r;&I5.j+YVpgug%p] r<1kjMixdU/\hDY0dj2l~7o~7BK -`_XB*^e2 YdiX~7Xc#ηwqnÆ[W By fv.Ixdi 3ao}q92\ͻ?H`zpY4%/$?g 7:BC&oݚ̑aܴkZwY`pq,a抾dF]g8fڛEmhW 74GcW/1 8ƟBHO?Ku7돬?"+믖KPW_E XeU"믰+zՙg#돬?^W_"Wq~zph^6@1Z.ӎJ&4y[1ZOS|}@oSSw6K߇Hpݦ6F @CI(^n_ @E:`@A nh`ldd_ \!2̓uiSa쟊$D ?&r[z?*L ?1 Fg 0oSDh_Ù1 eZAS[Dۄ7oX`A "NT0g3$D %RDP9& O E"_jM~a1PbPjOG -J`hoH#*J˕,aOxAp}ʟg;iŘ:2`qCO݄n{q-6aNi|F( p :JZd: 0_WVQXzrM7S??_Hn ]_u/-2s?a 2f3N?ɸfs?j;d+?N"9x﬿;!ɜ'g *4u;u9h )V@#} +o+ѻo$O_gUrg_21Jzɓ*3/ve^V)YYDjqYnژ/;a¢#tزѡ8+b!,Lӎ1yNnWy\ p֭+߼O _J?? jh`igΟ3aw24W?濰Ã'O߬/*_X^ (֧YD`BXc7/&l𗬿:S#돬?FeEpnrc𹍖6@ :Lqf ;oGbХT&(???y_vD ]_њz}ϟ^/,&~4JaE *~%rZ Z`_Ur\H}8f`9a"ⓞZ~;S?U_~$_']vIPC_taoP??_W5a%_?? 2,5zrYY`Glֿ`KI+gr`S7XcMXUR[U돬?#돬?hW$6µ֟J>돢 ?LW}I\L=rbTgx/ U~oP-MZ9_ؼf 1~˵]Д?wCj%3L %??^vKCK{]k`{bpyaAo#Մ2Vej41hK>ӂg1R&.*ןV.k~ )}O׉DU{_Vark~ڟ{kײ>(VR/W]uOea@4_TK5lCXX! xP 0~ ?h(OƟ?30jcM b3_?׍/̿yo ORs`YHsAR"lX6lX;}ٰ5gRբ*R2;@9:SGU{1Q+Rz2$CSYlTVnΪRrk2I\ PeO3śTzLZJ)t{׬?V1-YE:m ̓^V- .M]Ge)xӪrM7RetکzZjČ.Ϝ"o;X8I*+rJș7ťq2`?{f T 0e?HYbO@Z러-5f9#f ? U/3f[*?T?dGYt_XZY) .luS@aL),t댇!tbgө30"Щ! 7VNxB( 6Xyf`::#rn[f_Dž.(Ж(J&>zի KΪCW.jհi>`?77XtZ_sO;Ul~ gk|p'Xvy?//7PMaM*y? ,B͝*RUqWS]1bxq?0G i'NŅtPf) $yX`X ?E?Ԁy?mXXX>tUh@Egs |ԔkH/v^EVZ)c9:Xj/^lӜ-,K%D_2CNsAqetv ؕ<37vc>AH̏wA9n)XH ʄQtƤN_oG=ZeugN)}w_i~__|ݮ<)Of_9,ˏ*}wsRUom ???g1eI. ?N"ő/E1e̤2dM9e'O /5tC 4̿1)nFyY`,3HY"g35b&5̨wTctz qnZtpp}C(PTH36uA39PTTG:Ef1lƣgr2tR# tcԍG@SePGưDj@&=I?-<(BhD^O#HhtL4<79@2.U[̗Uwry_-oy~*N=\~]~Ke|e?(_>mb^d,?6+۴zICGOG_ [g?5Ik̿Apxm=ˉ'O ߬???XgX@&ͪ EbFG"_̿1b_SM%Wg0hR=G0ܣM+FTɌq)Fd?c1 /GS1wx~qȫ][+i9f ,-@F1\Sx'9l[ /ߣ!ޯluCԿsٰa췿~~*O)]n79gO7ݚ+;<@շ(?!8X(#_l\Y*+tC} `忺9l*nfciD%&Ya!/Ɵ\<~ YxH--@&!!*1uP/Co.:?pL6?Cnf(΂a=V[-6Sc`@crx}>\~R5̻KbRT0F2  r&DC#q{;U&rPRf*IgEj8Pmkaygls{> ˗tvT&=yOׯS Q[mbN9_ˍ7ܠ4vqᥗ\\.ʟSC_u<|O5K(j&CG _iiiiiiLWˇKhkXty?)x￀&[ΊY\}X=mmuIs\@QHo9Z#8v5ۣjϑ:sFpr&jG՞#uhdoM:o=Gzȵ tU{֙5k7Q=3Gk'{; n&y{T9[gNv@DMs\@QHo9Z#8v5ۣjϑ:sFpr&jG՞#uhdoM:o=Gzȵ tU{֙5k7Q=3Gk'{; n&y{T9[gNv@DMs\@QHo9Z#8v5ۣjϑ:sFpr&jG՞#uhdoM:o=Gzȵ tU{֙5k7Q=3Gk"o|jEZD1/D-n 8*h=)[C#s2~=uq2'`dZSն[kϝo}w?iR~]'=>Pߺs\WgGyH[o?qaO`c9??u?`{T ?5{ɌF[t0a?n:MYe_0֢ aofZXcW_9;﬿0FΔc8 1Kv=c8 1v+c8 1Kv=c8 1v+c8 1Kv=c8 1v+c8 1Kv=c8 1v+c8 1Kv=c8 1v+c8 1Kv=c8 1v+c8 1Kv=c8 1v+c8 1Kv=c8 1v+c8 1Kv=c8 1v+c8 1Kv=c8 1v+c8 1Kv=c8 1v+c8 1Kv=c͘)qq AD@oY΂T2؟aanA,O;Cfm5k^'+}攲!7>~Z;Oׯ7|i']/߂*jwEj6}ΙPLA77Ool .m_1{PY`Ƿ?XjBm h ?ߢoߌ3f1=W^7Ctx$^"æ[h>EXAZ Ư4UP[:z>^PGP^tZ\]VM;5T_l? n)^5Z;U5+[H4?? ?nl']5/[jQܺ74c40 -G>8U0y=en*" Ox@aU֥妛n*W\ӟ8\y.{j-uͷ\~]Vg:V:ݱ˟oO3e/aްo1 f!$?" D1@eK+0b+m){e:$0f!jM2dS6O 1d~D}&Oxuo[vk)VvyizG ).?3iͰ0,ϠTBKKC[M*ZPeA{usWчB.ew̝e6tP2/x":\?g=G_iH^ 寿BUo}inr˭7$]zCg>%oZGShS#n58 10?֋Fe?2d'O 3)2f/oVeMYQqbMl:Xc7/xx8_6‚^i7!:|s ^gDt3O6X!=Б@IpQ^$zMA^..Jj(MoT2kɓW꾈A P?2}QOͺ! 1b)RCO8dYE3ԣ9 @'ܠW¡N3M?GO˽`ʘ{\qMȆ!"M`hhhhBf"Ko 0=ڟٟk֊ȯ"8?Q 2M6 ӣ*Z=dZ[_PF\JD+>O~}N^~\ e]v){<_[n1I/GMEt*o{w/9??gC+?J&{&(oBd?5'Uy4b!C֟@2b 0@*29ȇm_Zt)$Ue3EP}h?_b"uk0`!OY%?D?ɞ`e!ً] xS=E6?WJ G6ѝL3~vΐ[3*94O5p!..ƭPcFe80<\HVu12 ui`" mrVuCP`K3/(Ժ(`K3ODAkڢP놢dT!.?iBQ4O0iz;I ![wd,$B_CA 4lUg7j>XGs/4ǃO'v)$WXCU_:ur/ ]F6jk#qpqq1`.3x:TGMAZ(C$"! ӎƟ?`oB莱m#;'OƟ?2?D&-T)h`䟑< $fbcS6/_g_"PP8<"ꈉǤ2$OƟV{*d\ObmaPƇ≅+#Ma`s6~K(ՌP< 6ykCB{FSe +`s6)?o!7`s6)w6Ko/zh§3-WzqKn ڏ,>(8« C<_JxxI$x?)ot^^qN;lrOrݵQ??b?p[LOGv+Ĭ#\rңP1K{n/` zW? 2f_Xx1Gx?7byb ~d<\49ZlQ:(4➤vti ::Hk??ڟ0t"u<=/T=:UQlLr_{fyRh7g>_Ѷ##Mu&mަr{mݶr5Wk7Pp~G&[@OG_Ͽ#hy:* sqHC 3awK`K&O̿3f]e^M"/?fyݦ&PQ}ҪbH7XcY҃O9۸!Aom>˧\YZ " }k9\kz2 ޷6cej2 ޷6cej2 ޷6cej2 ޷6cej2 ޷6cej2 ޷6cej2 ޷6cej2 ޷6cej2 ޷6cej2 ޷6cej2 ޷6cej2 ޷6cej2 ޷6cej2 ޷6cej2 ޷6cej2 ޷6cej2 ޷6cej2 ޷6cej2 ޷6cej2 g5@IDATkeff>$g1%8ȣ׀F-ʕ9d7sa6i.C!OSR'OnTG"z1`50b*HS,bU En l 2Xa_Xb?P{dG_YYO}뿼O돼돼)]6lX(VyISl`:' C2#?"o`뫀, LDE*j>@7F'BBcP@s0TYgh V?tiH)l7.,ȟ*a+//>Jhkt{ Bqev9iOe'o̿$߬?֐'X+&-H}*j?\SEC3֑6SK??_6hċE2dOVF`!ꬿhXG4bԓ U_eo0o"Xc7[G="d`W֟YfgxK#Yd׫:!?Fx7$(U 5a)hLn3:s7N3oa|ƙm8B(h}qx䐷&|6J'or5=q[Pk qA39P8KFpP8MO%Zdz8wB(h}qPLw[f~RҶ}s-B(~QyMXpq0}ǒ@l)1q`NOɅwpeP__xq ?1d7! ^H٘<4sЄ'qߨ:6-X'?}pg^Dk?7 O#돬?#ȗϬl}Ǜ`ɾ#k7iC %G8L% !Lwdmqnol_nȧ}Gֶoh\<.FڟYFWrYjTߍƀ[f S?OYhh0biDzD Cy3zxl 걦/_30#c7o#u#W!RY]GOW?2YN̿D ?@ ?y`Ch4i'"Ha:3zo^F`"뿬B63>apC8l 8pi!!ϣLs4o2"'ח/zݹuy逕2"'OSøhG ӀOH< ACC3-K;e&OH >!Ǖ/x_t?^_[?$+R,Ѐ4q֎J]U*׫eP4(h4QUVk???05b7_-ߩf)9ȟ_!hY2ff*EX`F? /֟,2\X1Ԥ2YbMt'֟_sOM?k@0~,Oӵ$c1; _ ϒЊ h1a O!8h؏!c &??Mװ}q^8/:,QA%8$H6D:}X#8OSh [)/o0YdYkU0byG߰z` #5러j qKXaf4/@x6oq4'b7u"X$7XSos 6X0\(YZ%]mq 7J 㜬#r}KHqyɀ՞fR4N??b025[C\ĦzWn|@<5I'BWELNe6 @Nx%0*FMh?O</_v0d%nT3d/?##h3V$ּgU [xx-//)^ۆιFG^+4SJ&>iz L+}.o,=*W\ަYzT%0 MK`b_syfQľ26ңR/}emG^@4KJ&>iz L+}.o,=*W\ަYzT%0 MK`b_syfQľ26ңR/}emG^@4KJ&>iz L+}.o,=*W\ަYzT%0 MK`b_syfQľ26ңR/}&yI=Y HO~BAI C V'a_|Sfw\d|.$PFz?PW tR֢4ߨV2kahh}/B#v5(2g7?!"x8ZtD2Xg `'_8 ?2d'Oq']:'O柑f]?9I\a[;M?:ND 003g&P\_$rI 0_A1ZM: Q|"@0\?ˢ=z J 0fLJXiY((> 닠hzkQk&(H@咄`"u|j5C-CE@kar%zځɫayt6hNvQ_Ɋ8۾|\p,'ʟWL v֔GV,0O6H45 O?ihv''3fK)To /T ޢn X`'ď-_-`G^'Xc7>|{6luq~~UAj p9m̑aQG֟氀9g#)ܼKwMYNS2Mspsq~!??or=֭vM;[f5~p}yak6jKfd,ul`my^цpIrM?fKia*E 08cGM,41d^T7aqO#,믬j$XeUW_, hWYvIl\>?#5Xe.RW80z *n 2mKHL?wOgK~ T>61Z???>ugh}$mjc??4^Ou Q$!@-h(eFk&_*\_ qP"_j(0@,./]_?Z  ď5d |'oX1KuT/?a' bP0̿ T?U+T1\xSD'o_TC3$D ̿D j"ԄGJc> ZFaKEᠶU|')/oJP??f+pP[_G 0Ch!__#wco)@f76{-(eZ*-0/WVYS??5Z1!g ?*e'o?1d_XbG_b;Xf4>ʵ4\^al ﬿m&???H?)+wɔB|gwzq`JOCap}??+땷]o7'?*3/v% QmICCYL XVY,"8i`,D,E(ז[6:4"̂S?0 H?//_?O$0P FʥXB̿Q`XݧKO?O?4Qd`7Y0 ?j.#QhaT]gp2yAW)nQ\wzz6@ ?dB0g1 ;ގhĠKCC+:?B϶/bkEďUV\5L[>K,@-Ư`a˝5Wcv| C\qUc6hFńU/ dO^_@/<돬1h#돬?b/aF+믨<#bw//5YB| ѰQvOU;N4a@9HrV YVst ' ׁ(oB3߫4TG3n;! W A#R:??wYеd-MZՄ6vej41hK>ӂg1R& ?No`!xJ*p@1d-[B3;3` ̿3f[柚>i.5ȱB*_3 Oߺgz/?'7o?Zh g_YeWXf.Rްa";vȡ,ܘ*E18͞BASf*ATQ*F[JNM@?lU?Jy1fIWeaQYU*89&4VY /®'fM x%W:݀.y, "^]y%,9.g<㟀:S??U9*0b)7QF!b7H3Z<x ?Yra_Xh~'u8O?$'֟GYt'֟Xb'`aqFW@kG' OU.?t'ԟ9CtsG7g5f:Gpt!`E׫ɨ*BB! גN]gOACKJL $-/n=0H{}Ɵg &0XLa =@ ̿1b%Ƒ/_71b& L $-oKZ:BQ o3+? vSX`W?}crG_6,,,I8=-Wo4C 5@a)4?)bThh;503voxdKKsG<0%R#X9 Pa&l ʏt?_i矸>OH/ƟԪ4/̿Y`IqRn-raoyî΀q?Wb?'n!= 0fG ̿:8hS܌2`'ϻN)מ,[|TQ ƣActz qnZtpp}Ch(QNQxn  #TH36uA39PTTG:Ef1lƣgr2tR# tcԍGf{ɃO j]^¤g9ihAB7y)vAB4 ๾A!2#?)D3@chh0@cL S" %v0i0b?%o,pгX0 O?O?d!O5Ǚ7 Y1X*ra /08hYNDXa_E|E3XESf{iCșcxjOS#r̴cYJhg +㯻m` QBWzK( qm*wd:Fc?aJx>Ov&EZ8F3\xҥ0[s{뮽r-f],]fֆ9<:j{J/-@FcQVWp뚢:_;?0p,h.&_C5۠;Xx Yߌw޵S ћ]уa$s^GK-ׯ`4w!^?&S*\-"ʡI*ؗiǭ !`hiňLU0YYj#* \n$pn-j@!GZX,^uхEVM|5 oVxd*[muYXX,^K.)]?l~j@nw~Ǟ{#<2b}_C=yh*lxǏ|FFnJY5eժUO||')ַ[vn2Oup?o*^pA_˛z:gwUq=9)x泄wcWH/B?-пxoYgAP~r5]^N>~(bsy'~mo3i?77_^җ'?)emu BW/8\wuUQo~~//oת0?IUNgK_,]%/_upPPxT"TɃd]!ʠBz0a'W›T TA'0`ˌrnd2}.4a__U)܍yISb}zpL6'褩@[g['Gk'{; n&y{T9[gNv@DMs\@QHo9Z#8v5ۣjϑ:sFpr&jG՞#uhdoM:o=Gzȵ tU{֙5k7Q=3Gk'{; n&y{T9[gNv@DMs\@QHo9Z#8v5ۣjϑ:sFpr&jG՞#uhdoM:o=Gzȵ tU{֙5k7Q=3Gk'{; n&y{T9[gNv@DMs\@QHo9Z#8v5ۣjϑ:sFpr&jG՞#uhdoM:o=GzZ% 7 } 墝g> !ml:cܢ 2a|owaIK7.q֟/o!w齃,y7_!6[wک~uq|Gb7o3fi PQYdg0bTZA"t"xd/M$ޑ?T䴿"io|BUXUN\c9xl1ei6V2qLbZ? /c8 1jcXf3)CL䀷ec,ǔ!rXm l1eivl`e62Ĵ~@xc8 1ގ fSoc1`,ǔ!r1ٌc9m6e62Ĵ~@x;^602qLbZ? ƀfSoXf3)CL䀷0ٌc9xl1ei6V2qLbZ? /c8 1jcXf3)CL䀷ec,ǔ!rXm l1eivl`e6c]Iq9 <gjd^#P<3ƧxGIrhs\'=l򦦅`RW^1eoe\#Nn^Y>W~|֧E?K]E<6OLBKFa{˃OGARZ~]U b̩圳TQo<<jdK_rBq6W蠃nGwر~j]ο(?LޤY=|`y1o/s|-ҿy]v)eǝwetRކUm{.ϕnA\uX\78X7{=D7rs7Q>7jzu_6ەgӬo$ξ@?B~$1 OKK7)Ebً9tONgc<濲!27ߌ3f;_c.0\=)EFaSTNJSb|U%ǡUҔhkIz9 D1tMpV3s[yLJ@&8@AC#@[,Co=؃O 꼘E-Wjb@Lbd6/PK_oul}'=);ׯ+zJkRq$A}ݵוNV_3c mΦ?p53չ=?} osRވg?u .?}t/U|~r~=yS7>=Aο7>}V^Ov;y|yɉ?)xW>{M76w7>/o|q%W/+r-N\[/]W?P2O+^1Kh22?xu ?%bYsY}v2??iC00B^nȿA;}0d'o!6!*BkgM?2dǟӢ9<^QKzۓۼ ~\-7cᩁퟋ#~Pd3~P2m]5py8ڟWhiU.wa:E b_~B+.Y`nz1ڭ:N).oscq&dyKӎ&Nˏ|Tﯲ?g+~tyˁOͲ̩_>Oe-R??_?B{[V寔'54?^`y)y|rys+̗}{U?6jǃctϿ>M,o˃OOXW(Y>G7>[L>+\}Օ/{`?Tf.=ƛo˽˻O/K]c޿j>}){]ȍ.ff);޶,c~>XAsDNw_|=U?^a.3\ɥyA6?X]c1)0BR@X2t0ǒ‚Fgͨ05o9:=u VgDt3O6X!=Б@|B`xx#Clr{쪟W|R]ǿ[y.y_ ꖂ,?=?㖐?D(/fI%dui#/??r=E3W`q.?_ƿ|μ|ΕHC+" lubF|$qoF戴QKm.aƐnḾh\r/"!N*OQf)P^{F\ARm#jdmh8#o)TYA 8:oA/4x 2Ii0U?Y7xU7xCr˭ ]w]wS~DZc?Sˍ7, />OF͕[nl֊W,o;a_ĝ#{K9ߴ$Dr,'pb9Hlv-Ƙ SG__u!e[zi:r'#xt; QEcrᇕ={^岵7. {|ֳQozSeZʫ*G!k>y{>>];ὲ9g7&;Llcx/|pw#l=~=MJ?Dmw2K>G^3.?}qbo:Uem.GyL/grZ?_G[ٞ/oP`YeXzs6ev§ueFJ _Ͽ w/ɚox.{8dY_q{G>q]K.5gDN^}d#+)ƾgɾ</?Xִ&.W^-o R7Yg>"vsc߿~wx, LDuO.g}n;R|B>؛ϾjA[muG=r?Ճ& HjNPt9+?h'yc{E(w<c[* _e/K_R+~?bmnz2YBl$~,bSI?mw$>Ktj|(G՘:!W@pw#%>x~č}Ox?HLr$r]v lL/C?[iw'BB%q'Ob=MX_-n-ytOccYw'I<|gG͒m49"*,W/I~]sWʛ cwxz h7>su`_tOOHJDGOq(???/͊'?0`BVO(Y~j/1l.7 e`<9+.|h$W1$W[Ef)P>/IL//?dgpAɔt`aI|GCCC6!dUV1rffAy 6QptŞNr"M#Ԫ|3p^<7;lr^-_ogǵNV?汏+n֛o)wny~_t.w@9o$:k1o{+?W 1?ò<7ɚ/z [CY?fp8~_˱xDz_;y!ze}Az2]ҿ.5{Ǿ<`!wAXgg=K aXܼJn^cuo/=x\+I'P>.k!=uoT|??˹|I|'.?rN;=R߿䏹b^WXyho8>=ؠ8k^](Xn2 zdq^z rU:t#w7@T{qj,MG^* K׿Mſ{g9ct .:!cTԡ,ş9-0o=0 '}l[n+TD݁.7?яWtOYv/ʃOxL7Ko+oGCn]sA3r-!`Ǣw$Dgv_oH(~AbXvq;Yb-$&ϿFĦ%_)*F|8>D5?ˌ%&eGQ_&uGQNxgYg[LfQ$&yĦw[i幪~%NbӷcqmK~u3B״;?_sI?$6}Q 46h-B&ӿ%/zы_P^,v4?}w`u;?M?׳LoYn.`s}#D4i?//Oŀѐ_?uwh\aP:϶'t?0TrrqqA"8jF"qf< ?182NzsoB*I$K ҃b灢齊>}O*!})=DTP T$FI3gvv$$-a̙3;ߞ=sܩ/p_ aa9}߸OU$@r_Z'w\X eNg!}N]/;\y U}`mj| ZvqOOHlݰv:/Ƣ9̮˥طuz~§eLn|ٵoSvr۽+:dwǿ;=]G}8 eGUPٓ_S9v0Ye/@Ɣ^}g_.{[E{w<87{"07gGW_$':DtP-sȞc\sTtbw$nW?cfd|5?AƟ:)_u;.\~tTǞȟ @IDATAr 7\^ [$:hE<Õ;>} 輣)a>]׷$KCi=dᓍ˗-O7ׯ2t(vzv }5 =7kL%#~.qwMرӿӿzX,& W=6{Ady8d_胉R{jNPo'O:dh_~⛊.$z^,tVvePqI7=xA/ەI$FP]z~c'\T[?^Дh}/nDT2u)Wg48u ߿nxQ09d.3 1r8q<mqJBxBkމMPA\!*Ը' V=5I\,OFd\P+ /u- -R܅%YETiʵz??οLC$0  {S?>gSӉwe,|CQ׷^D()Q(ԉOk$uY{ugk U* c_xAbԝ#Gɝk-ayh }> r6>?7 v壡O>駞)bH(??\JA8!ϪrKt f\gxdb,Zj~ueg"::y¿[|̱avlfǷaǧ]xv|ңqdT.|GzsX}P|[v| h OE\cǧWa',|v?ӱ^[/N;5ȮhG{pτ ~MkѢQ 28Ŀ -+_9髓£ζ]ܿ+/?jnQH4*oǬYᅧ$g*?`?`l"=0b{"B>yUK{ 0R(TW:R.%EP,Ua+CSwʠsP!='P%EU+KԿԿDţ$]v|n׊C|CQoyO1\Ei #oa 0k0rVҋaܹa\[;gGō? ˖Pm(;Ã3gW??QQzBсQ+j 8h2ߖ[ڎO'ރ*O=`i݈.<PXw!|+_3 9m;>Mcwk:tv:Y^ŎO=x>!wnAD]t4vXհgu혎ra0INLow#yzp&kA+O7D'*`T;壬-UFAKKC+:@a^?+,-Ewnd/wELQI_WlS0.疎rTE{p*y NR̲\E{p*PNpKjne~N]8Q (V%5W^2?.pŨS+\h[SNebʩ.wIU׭ϩ 2\1j *VSrj]Rsu+s WZ@9.9uT+F-Zr\E{p*PNpKjne~N]8Q (V%5W^2?.pŨS+\h[SNebʩ.wIU׭ϩ 2\1j *VSrj]Rsu+s WZ@9.9uT+F-Zr\E{p*PNpKjne~N]8Q (V%5W^2?.pŨS+\h[SNebʩ.wI9zqejK#%F(W'" 4nElbHo*_I~l;n?x:Qυ?]?Z{xx-O<eqa⿽]7--Xȵ79sœsˆ#;:*酒 ߾H|D̝;/7.J4E0`0fh##w=?/Z\;Rk._P|< 003:jS~{ObEƇ~dL?ʳzG~ug1UaL<^x&ᙼ3o<<籠oD:dFoA٥f=1097εŢ]t`O>< QQ^~23xr1vg"'Gur8vv8F?c%:ɻ߿D11 *fP4G1+M#Om7Cda8ɐaCSw'UAȁ̦A]ρ>7w>\/3tX|_GAM “9s!X s3_=rיݿgUD _dOtX^GwzIAA!{cЧgGOdO~xe7pA5/7"bGEs s #1cYAW[$ϤD8=hqEk%v|:Yw| ុ7?wԧ~ˀ_Khj);>Mn:~{-|}Dߧvؑ Nk'Bi.RW} x*\EG~/]P BM_>y+'g@?k:~OǯF R/r`R"vu;>|8|=-fƒY߸qc` DG?=)bFra^S?8k\(*/;̚)>I+b,LG1<dO972XlqmI*g{"";"{o[oQu}}:~:GN64SeOt&]?O}9oHg~rרh?<i~0J?W7YӕyT!ǟ+6{eI./f \Y$M?$E/@?ш5ih_Dk˚_?2I? /Aے>őyfM ~%|d%5'|/n9CE/ Yf(?(9%]#ASIhi00;gmJuߜge7Ll}(Ja_iGف@t1Sܛ\0@E~n"B+­#߾k13,?;ܒ]v X{s7l˰ɦbpo4Ǎ{>:)dc7sƌpܱDŽgƍvr>Cxlghu53ɓW\2 e_?%þ{?nzk:\vy4p)tK¾'v3"'AguӮ2[u7 vr.Yg0嬳C4]Yxr?գ}|{&`sCE8w}9r08LE_?ΕƗ]֎?X|lNJ +?m7>'OӮl]]ɟ>$tPǗgrW^z-H-W; ʁ?,ar7zuhɒW SƷG,w>]?hcYgƏou!sdo5ۿc H7GK W_/ kz/qdoƳ?[mu8'§SO'Ȕx&R6gs{GYX=d e1 '\7l(q{80~|ȡo{n&sKc(zv߽_Gď?9}\}po~{hEᓏ$JG>~1no{駅;o|K˩Kfu?E]aq>8cÙD D z!'#e't$E[ J `Yk?~U9͘1 qd>qآOo* l5WM> b1bPVh':HZSyP) gN=>8cjP ٹOb1?z"7<7$a-bĪt/]:hO {=^|1b1Ӯ<ƫnK1$&ǘz&+E9i5?A=y>V-X@~`p__*bΆ/?׿iwN:qj*2}_hEW@dB"]‰<f;>U,br"#e&(MpK".f%OC^(٤O熱"G;jII*ڟ76p `aD>W~c@UX9@P>6Zd5!àMGi9k#Fwm ޺1x_Ĺ>@~ #Q>̲EH=XpܱXpaޡ TLC lYdx|.z',;-Xv)N揌/oN>D5b|u5, >% S;/PL}^>iojWD>Gu:Cs=?r3fBqLf?|>#ɳk\)eqX|2uYa\[R~&'V}zGrt/Kqs߃d̨йrp|-O]+DaaXtLzDϜ.|rЦ }0xYׄ*'~+k>O3 _p+j>=![nU׿w`׭0r%:fͿ^]~t ÙSXIOn:~{{{3O'9{\p!~ϵOQ/ |pVLB lG#8 C!ߧO ;EC /ca#w;Y 6}|G`λ|D{w׷2+n }GU2Dv,v(BĢ5M',t^g8A |ӽxo,7dͱS,?? ,>? ip>k,N;:4.:f|'rGbM''!ɟaýaWqLO}pcA"F)-V-u??*27t:+LR@zfRAIqAISPR@ z?IO"Y1^5jZbϖ' 6m39~ /2?6N!C^ Ng.g9寐t NSg.g9(_!'y*Jk Z]rPBN9T֒'8N!(aUѲH~'"4$% B S_B }좉dU@d 9r"7bׂȍhǝ `B}Y{[{%L|0I0h̝濰 6, 2,ݿ]DYLc51#1&nLF+2v'|RJ=& j/:,3tH_/,"9-# H}b!%* mt]Fh|rC_>ᙌ`_w'3Y636۷/_o1d駞ØzɄԓO%KC!=_h| c${'1 r zb/ 2?-=<{q#͝9Xoa%DdDwY.JzseG óO?B634Czrԧ_?y]>ӡaѢiN1GĘ=?rOOC"cFA1J]h,}(Bw_My.įF-3/̟?.tP"?j|qЭ~'v堻4tТ+?W9gS._J=gj-I|37)J[?s!|Rn9oc]oxg G\‰'tvN{Io;qp܉'jSN.z#;w㏅/?~͵jC=|8p2"+C;áBw&=~ih pp,v|+>4{؁Y\c;??|"?QgB/-}P㗃]ٿCG>=/?;rya05Vߵw/Lj-]p?Gxtk xȰ!`M^E5*m:WGJ'ya>|5Hr?XtI?QJ!{@%tqΙ𺈉ց?_s%pȚnØ bU/B| ~a$"jp˸!5?B è1/?yHSޓQo6 0dznuBԮP_^!hQ{Ӟ?')fE__h*qqiY7oKZ/ƟVr,w(@gx'~__,NDU݉bY.A ߅{@"DDmݑ, ~ p|es;9E/a.Kϑ,?gO)ʍĚ8bYrAs8ki8J"U|mݑ, ~MM;>!tK%(GbA;#>e|\A.Jא+a̘1mvx'E/G[o>H%;Ɵ,nG?+[x~(h||,r=Gf ??(M(8eVBTkaØզ:3HKge:+y .Hb{B8 ;Dm8 5vj /$7m˱#>a)>waa>5v8v&p=\ץ?_|Dn8L˖n&\~[KKt t/~M$a뭶 &Mkugi‰ Gy䧾k.Ы7^|0|pt?wskeDEmzYYE%ّ: 6y\FP8ES'KR7g#j)AKT/Lץ2wdH<FA3:[b8E"9^2HGTPyS_]dFNb\j4׊ ]3D(~U+rk7璶44gߠ^|x@DV@U:mihiV6S3J AOt/O4_\2:JLcL%8AirᵔSWK 7| _@&ǎ7J޹>c>pp>Q T_xcDGOG_3&L37D]vlŖSNQz7>} N sW}z>;6x[,N}??7ܠ~Յ_]!?0bmtS<#ے;,|*zb?gO2p7(4v?W+c~<,|:#7(./}VK?O? FbǧS_v{.‚dhzBWZ'ui>/e0/_; l_?Spޥ!{ME/hx0"BSF b DAA;wӠ12K>a'(WLpӬdS%;tTn7%M}?? AsSƆFL".Qg>W1;>fIЈ/aοv|@+vy_WK I=vCU/Bf*-WvX_xq۰Kڧ ,waђEg9"`>Lӟn#L=R;/Wz3g{ڿ.4H yƷn3pYg[%޿w'mxa#{.T&eX,*;¹%`W_s?gOd)t*5O_?1~jG QA'O3h'%_2o#%oߌ3fmIXXδI]r\D%mvH` ǫZIP"ޛ9>"e GM 3DOLEˉv-A\khNyLpY$u+/hvd>WP#8px]量XBEtL!N?``v߾Wx X k??bxXpa;w> )?Կbhh]&?G6t0 ~0s挰x 1c.>ȣ#‹e|3fW9mb5?Fǃ7X]GG'/_G?"+2}t` i'OL U;!>y|ĐZJ~5 %oJ0/bߠE h멌jXP 2L20#_1Яev2*e`Fb_*eTV|@Uʨ~-/QY-3Z^fW)Zf+̮RFe W ky]j2J20#_1Яev2*e`Fb_*eTV|@Uʨ~-/QY-3Z^fW)Zf+̮RFe W ky]j2J20#_1Яev2*e`Fb_*eTV|@Uʨ~-/QY-3Z^fW)Zf+̮RFe țnOhwavbRj 'cMӒ#hhf K'f3oB/_?1t"3/Ɵ?2>ZwɅPF1f$B "pѐ*/_1b Q𮼑?5tI*s+"kPڢ1 >|,dhMf@Mk ʗ9 L6RtYp'ִ֠\Yc@?@1#pv )#-4n9/PZ"KƜ&6uN!ie@Mk J;(>kLJ 2DRu$($d*ְJ4z5dcZK mV\BYܷ\0r-OxPο\OPP}3_?s3`# O6xK'` w3GӜ~0dX …h-`k`_$~(*~b!O?Yt-\OUK:[[{fJ:!2+pis˜ 9Tp4xz=a/jeNNx'!"9oҤSRPPP>ԿԿ+f&l5+:764? ܓ-^-A7Y@_A+%[hWю Nmh/ ,2 &A??ӥԿ*ih!?A-6zOIG ,n0b;"fB,M?1#eW%WW_!̿2 D=sxaGLVW_$Wĸzą0`SbNV5@7ၘL;b M9^(6ZΩ7OS|,͒b%Tk*So>}"?% pƽ2@CϮd'u;plѿ_^x ZP P"hOH )r6D|&/)2y_sZDX#0Wtf폨24H'eOb<_TZD1G5IC2)W]^R^6/;7W*yA_I$Ec^23??οҬ+{3'0aڢzSG8uO!G-NAEC*MP4yq%@Ck1gɞE7_5A&O?0Rb V.fg柙jw?ggwߙgwkl̿3&u'Y$9QC2狶^6UvS\MCf..w^6U*P0&Gqqqm/*J2p=yϕ6F Y3oYI%{҉8.rNyNDzruyxqEe#:uRDQ *TNԿ??TI/Ɵ= ^3̿ho?2*AfdQoo̿2*gf]? $ErM%1^60(2a޴̿Cߘ{tȪ"ԫm A9ҚpV /h њ Gy=c73_iOuY4 6#E ʯA#j\:??Ll`D'u@ZZ!PO" 0%*ڤ1k: 1%ROS8i(FߠcG? ocO69D)0boߌ3fOKUb,Ɵ'o3Q<$/?'7o?k3̿2?3&?/_SÒ",1EŖ6mH[Ǟh1S+zR WPTL6ruJX7ת2?hTKz1j x18;+p͘R?L|x0;ԚoU'y:H;tWD1HZ:,8KVu/?jL_ehh ]HQFI8'oA zQ #/ O/̿0 /ЍfGR!'柘b'柠 bI( $b'柘b EQr*@+$ ??E0v|r@6{z*WhhhoA8T@"(,oI LEWYHFU(.@Ϧ} Ks|mԜѭ_ߦsGsJk6ڵȷdBF F)V;q$2Je>iZOS8^0`g1]Pki̿8"yRBnhd+*x2C*L?D&0٠ISl(0PP!b2CR/HĠU2g30Ǜ1(>EC UjFbя7xXrZZ*<*h"?e KUXzΠ9P+$6*#7M_~$*yQI pWuS3 9ƒ8~?r@/0+?Կ5W4nhhhؤ'ŏ(PXC.u@E:CWRQH/ [7{JN[FŚ#tTZ7{Yiլ55GzĩoYk:mk҉Si e9V t2*JsfeT9K'N5xXZ3i˨XsNJkf/+ͱfӖQH/8^Vc5k@-b͑^:q*4j֚N[FyLQ@IDATŚ#tTZ7{Yiլ55GzĩoYk:mk҉Si e9V t2*JsfeT9K'N5xXZ3i˨XsNJkf/+ͱfӖQH/8^Vc5k@-b͑^:q*4j֚N[FŚ#tTZ7{Yiլ55GzĩoYk:mk҉Si e9V t2*JsfeT9K'N5xXZ3i˨XsNJkf/+ͱfӖQH/8 `ǧ%Il$ъF n@%u9"h5Xс_ux)v~a8GXi?zN8Oߌ?YS {3fW)y*N?1#30;?JIW "hhd51#?7_% ^'?քk߄~54'llbzf\GIsƖ*'/}H6T1E=AxY39acKS䀗>XMi$ [ QFҜ) rK4愍-ULQO^֌(#iNR9VSIsƖ*'/ku4'llbz)9acKS䀗5:H6T1E=AxՔFҜ) r˚qe$ [ jJ#iNR9e͸2愍-ULQO^`54'llbzf\GIsƖ*'/}H6T1E=AxY39acKS䀗>XMi$ [ QFҜ) rK4愍-ULQO^֌(#iNL§/D @@UJ@ P_Z:]g{@MRh?"WsQPʧ? H?냂Ag17d]( lD@?`>Ȕ`Q|%~0bOߌAC 0n BY2"g 3߿_D%0o̿1۪ȿ ÝR)jiXH ZF8)?d򗦂O:)6OaԪ@edR??_ \SkeԪ@))&mrPP@Tx->L̪VLNM0 MFi tꚸJW6qQ@7QџE1&OQO7f+|+o*c"&jCkNTQO0`|!*/Ɵ()_b7ߠ&fCk̿1&x rD ux :ҬEWvq[[&qt]is$Wpys%ERt3=Jp>K&V:&ԿԿWǦ[LƖ혇E_C/wJ]~2oA iWyEix팖VqS-p|A//faQSyL 0 ?q(O?|0柘cW_eWF13?K ?~YVM=|%'PChO0o츾6R&[dUל ID QJͩ2qM)}\/$D(5J55qLNeԜ* (Ԝ2:ABRs$L\SsJD QJͩ2qM)}\/$D(5J55qLNeԜ* (Ԝ2:ABRs$L\SsJD QJͩ2qM)}\/$D(5J55qLNeԜ* (Ԝ2:ABRs$L\SsJD QJͩ2qM)}\/$D(5J55qLNeԜ* (Ԝ2:ABRs$L\SsJD QJͩ2qM)}\/$D(5J55qLNeԜ* (Ԝ2:ABRs$L\SsJD QJͩ2qM)}\/$D(5J55qLNeԜ* (ԜRHeǧrĪ'Y$ pU`/T$!T *Fhٵu55!(5ndqQPI5WC=0$_?YcmU)aO?3?&T]̊4WSoUnMF?[,%FFDiA ,"JdVa^|Q[E/_8ăWf##_t'gfn ۀ˿;6k)&F]gBùfu9*Ѕ,)ϜGd*x&-%WLnb.)O3 VҵQJ8_נ'l5Ȥ+KZ| 8҆(,uVIMrNPa>CA + ]gr|OACKC ߠ/V?Q\Uv:$~ҥ/[;评 o4;#?O?%x39'OƟx _ ~?/Ӊ?I''gh@^U0$eCH`&IOSqy_.]6&x%. P|^?OuB2RQ& -eDv&@I\1 j]6f]@S$ow%5|u}*o[EpB@yfT T SM\>!*5 W9qA?,Վ,+TR&(?Rk6lw;l0zdhK]h&D''>ȝOSW2۷o, C_=CHy!|wϺ8uy0 bDYIThB4C88~o{vau ;2ϼ0Wkdc".Zn=c|\~YQ>)Xc]P&Jv[k ?xŃw뭻nxc摿VV}'âŋ\^c x;]'wK.^|}o!Æ%Kljk8t^Ɵ|2_JezunkÅ?@8q0r ڇz8CXqw[2'`%F'[1*Gc@E~k<-q&͡T;"? Q fkM4@rA1cJ'OtSRHeW?EO81H ,Kqic5^^^K\35Dfx!6/kf8o.$, p3yֵ\3P(Կ I` ^ȼKZ[888p3yֵ\3pOv&\7ϟDHqY#YZ$o#tήזV x/\qO'? wVMnYeƟ]{?2p^|uSZWi0I,)g*l{)?ƌ9]uUae_ugm;e-W]NU7y5+O9,Xt4מ%{nx8^5?8 'wlx`^VǺub .vлw/P4髜*ol^G^ybyUuWMHQ.MW]_?Wn`ɿO T@]Ԉ$/.U"̆)8p$P8 i*F_tHPR* %@ ?twg|'WSn%E yOQ6\Ei5N;_s=9=<~Cx،aٲWn><$)6si`3I3§W- ! ޼c\W]yEZdJ~7w[[px4v}KG}}WKB6*~ߙ*հϞ{Duqǧ'§Irc|ъӌ߯p̱q-w}iXxٻ-|:fv|R 9:>o#1pɘCf9TSL//8Evu)B\?0`G?Gލ%b9sKjne~N]8Q (V%5W^2?.pŨS+\h[SNebʩ.wIU׭ϩ 2\1j *VSrj]Rsu+s WZ@9.9uT+F-Zr\E{p*PNpKjne~N]8Q (V%5W^2?.pŨS+\h[SNebʩ.wIU׭ϩ 2\1j *VSrj]Rsu+s WZ@9.9uT+F-Zr\E{p*PNpKjne~N]8Q (V%5W^2?.pŨS+\h[SNebʩ.wIU׭ϩ 2\1j *VSrj]Rsu+s WZ@9.9uT+F-ZrԜ'l>W=tJBGK~PXN| "I8kBdB#/Ӡh7TZ[ǰdɒfbXk7\W!)2)D4eYi#7`ۛO9v|]B|sq,%Lr,|, `Wӿ60#Osk2Ee@Ou]jP>|`[]S+OӃd2\a7_kXKcM&?|T?_ ' W|5+ @b_~| /zO#^fM ~%|xFzݚe8(㥁9k# 3kD6(X^Q50;gmԿ`C2פQU'l6QҘelEDTnD%5b,:18e7Zz(\P?pB]2tݰ3=|. kY+,[<%)m6iyo~w~w_݌i/OWvT|*>!C~aM6 l02[0/\ms[:8puۭ N;~hV[W惐 /Vj>alF-Zf~8tMY3+GCfaЭ<`]rǟ:8![}PoJ'z2S{&Em;6x0du<p%tݟ3~2䃗?&=LKU;a8x3hҋ/G}$}]ޅR/?1fMUOtɩS}g/å./|nߌ?52cd?d;>S#HcS{".~$Gp|I h{ќWK@SVdE'Hr//+_IH*3?ʊpI69sEQ/Jp!"<뷧B=|ў;S?`PZ[AZ -ӅO俽ٴiGC [5oۻn^|!zЁ /?˼:{? megر)SBo,6n~aE2;m#;so[ r8γ>c#zp'oԳCX,gwO~ ^'#8Tc̘~|Mxz/uy83lI쪿Sm _ dQ+Tr`p!X@uv_y?sg:J/'e4(?r?pхM2KS5e'U+G,~9rcc_bBox‚pN'G~V^x!pOrwD8}K]_ݿǝpBvⶪN:$]X&@}zGaAذa6OX돩ys-߿ZwC9`5A=ΟLq?zOy_p/S5r7d2A?ȁ弄/1ߪttohUH}mjWկ(a5 P4NBAYPA琗\:YKޞx ,7>9SeC_MSg.g9?/䐗Ʃl-y{BAY@+!/CEi-y{BAYʟWȉC^:Z'3V?寐t NSg.g9L7a{FjYrJM~$% B @>CR/]@#u-Crq|etGip<,Y $Gf=§}e 7`'?8liO)6ѕKo~?p0iұlFr%3gP0=M\—_I?]h|0bԨ֮Ot'.??a ˲#)jᆺݎcτ 6@-٧e~ŮA=⊉_L idV>,HwwW6N=+oo `Qʾ{Y1?Ok-|:P,|b9W/bsO4ǽ}_R7`1ُ˗ƅl^{^~%v^/&QU[0? 8XwGz;Nuԑ2g~k)Ybv~0~˛^]v.RL ʃΞUӯopS8h`ṯ =;Æo`YC(r~j.utЄLvz;͟@ W _ݺ:;:zn<tIZ3Bo,\zY,4vނgom,¨GAv}q_K?CGƌ/^O qJb˭ aWG~J]޷b"t!JOÎW}@ yyGQA^ 7E _k /Hgc'}_u׿/S&)R'/ɷt__r-(__u?TRq?μX7"8?lYT ?|,,_?n[w|J,/HM 0tk뎌eW?O'Ϝb"g@"ҦnD؆ksqqi:Gtk;?.(U\bY.8{m?+m&lLfK%~˷^RdU~\azvPqpNav|RVٻS*p95, ?K ;)gב?"ο8wDRBnH:,'Sδ^]PR- Jh3v;Bw=sd2a_r.D/K/<@7O|l]O ԞRNAgcW$UXpq嗭kʔ0kw-|md&4 r _umw~어{(,9i , _sb;eV~1@%pu'Ӑimv ҮO>6tJ-=F_yX\Pq!a:|8.=) Ygqm~~㍊[6,zip7y'=CЇ=o!/dMrYp{*ʁ׿yjb-4{Y޿jnAۂg%sLʳ>bx8NS/=D2jYv` 믻6\9ۧ"{2;ŎO~pM^w5A,|œlA+?D:f|?O-KG!ɀHOKJӭ)Ug???WԿP1y7s7߿2YQP uCDGbD'2m0R F8OG1Z?O>)(ng,Zh+*44g}˼᢭Kmihϟ%>CL PP֬44g??οq7> @tМ!888&ͭl4gb荚Ib<#/`$K Q$Y+O(퐿Kn)seǧ~zyql+2:  駞 w'LfyE%??ƢTv //Z*r EKV%ΧY7O ut!Hs>=0_Z]]o}:gvJ#`G嫀?8\$ô˰FU,gL+X/x$O<X!;_ ?m'i>>O1cDŽ 9υ#ˍ"O#>vΠ |uhQ]/KbE^hFԨ VDXQ:&hlR&/ 4tPTvܹ D ̝sOwQ6bl\|хV:dhN1S@o5RN~{em01qsUx2o<7DDħE˰!vDl'vOw񵘟P'?]u5ϾhW"J/͛UccR4 (B :`Dtk[Akg͊*O>rRQ@ǔ)S菣e[qK "k) MT7a|N߿ߙBEA8S xwVJDM}'jc, ㏣::~j_uFsq):2ZgvreO!8>z!syp#3|m7oX/#]1b#> rf3WoDo7Q_?m?(p@c:US2 m[+ho%<$ss{X_La_TǧKѺz<3ropy|ćρU6HL b:)D39qtL7쿴PRB$>]G| J eP$[L+9dE7Sэ,pۜzTfLDG9o2vW&RGD:vA"y+/AVZ8̇GʊJEzÿџ6&Tvxto&-mͨ d{=rpw! .=:{<%;찃ۦ$\1 +~!Rirp|LXƳA6Qv3bǧF̈OQt(5?G$mOW|"E3K#Ѯ;&: ؐ]7oDg){R)0v:wvm|7¯!1kڟ(LԾ}8Tsg?裥?w8D= OKɈ+1a3:\F|xdE|,5D*4{~圴[ohqY> ey+sl 4 NT Se)9ПH.gV6v׿|sFK Ͽ |!)7~:Z|םw;]Hw}G_|IfZcأ?$ieNIqc6nߡ"> 3%<<sIyQf گMO{\1آEJ5$$=Bo*) -Kkmm?80:&l1zk2kW1?MYP`m_fo.t|Ft5?_S'l J7NO4H 6\+|3*v m^yb_!vX \^bbK ;'\d؛eksfdOc?mȊ+lS؟f&|dcs '{gou*g۟)'J}*!;ʝ502gg\rŠ`F]=wߕ>VpSxQU ϑrY_d F9?1y?"E 䐖DLG6Rhɟ_vLS3P5/?) /{C?;䄭?58lEzQJJ_&rtӦ Pڪ}p$&|_ dPiIߗ$ ToZA/ɬ.H՛}kK2+ A%}_ dPiIߗ$ ToZA/ɬ.H՛}kK2+ A%}_ dPiIߗ$ ToZA/ɬ.H՛}kK2+ A%}_ dPiIߗ$ ToZA/ɬ.H՛}kK2+ A%}_ dPiIߗ$ ToZA/ɬ.H՛}kK2+ A%}_ dPiIߗ$ ToZA/ɬ.H&'FAtfw 2[ρ?:H_zkH/3ΝVFA 8JL:+_+4t?nx8uV簾e ǧo 'u3m6C'whViOx?F  qcnsi-"} RW_Lq C¿P8iL.X(# yt1Cz6v̘,'R^^.K/W\'dW*ƹO!| Nlл)%30RRS]-SӽGMgħ34>ֽ\{uW>䣏?VG+WI}}o{o?8ɓ'NYY{K#e!G9D8'oi=]9Jsd|9q2NLp0a(;G+ 8'@&G;>yQ#Kh~P'D +cC\$qϻ9 UrdɉaE;5YZAa24uD(͑9_ׄS` =!^8: ӇЕ:Ƥ6m*Eo<:e'wмys9ȣ~z%+3=%͛#S9|@!ogG~Y³ˣ2oH'6'?nȩ T{gz]FBSTtä}핗_|Q 8"W:#L2E_Zssf/nM.pI;ք#>&-]ωNۭp|͌iSdCeР 5o D'-rbL ϩ3"͓#Gh߅&Yq2 E_~Rf&3>iՙg%2uxpmȃ=:GEO%"zW!{r4WO;5H989ߙ@;ʄͷȞ]w:a̚5+?#z*p?90ZFkU\Ȃ~uUW/ʋ2ne+2i31)gH%m8^zuy'~O gADBc%R;]ܣOd}T=G6Fdd b DcԵ+;OǍO#3>h9u{=N o7#g;0K N'SiaMّfPvh_r?0/*a`R_m'FPhc_%?[3UWWPVϯ=97nஉߚaWU箑 W[5}Mo#1M!F{a0q 0k7=&װF5lӵhdܸ[4p 72Ta7 1õ'H-b;\׆x{mV8 9Q{wk])GIDAT@GR3Sл៛7F15&Lsig]S[+'>I5`>c_HϞ=>$]|AvڱLvOG&%MH9~FŪ꼫0 bFA_瞨 'pB1#rY ǧ眍^\?E|6m̄O!ri1cnF498?NN;L?>M6MEħr4rF߇yTZj%5)Ǐq" uO8A^~eWȣSei`>W_o yv,u>w^O6qǝNDC<>w1O _ pzN;m٪g"d\rrA?~aOo!b0w~ {;'|O+Ϛ_?%6|i:D|D#:> P s*"fQK;Dux)9H~߾COO=)?9:iL{#|H%OHWE4bs|*[Ř(IoUfllXfO;Ȱ57ZIE_0- l6/YL5KN6=%6ӓmo[e$?}`c/AԘ42ċDZ˖[#A+r;BQ:Ί%@MW[#a F7"K%&@^.VB}iG &Mz8C/10gݰ̷-Fo?F|R#Ɨw uha+rXtQ!W+@iSԂ2`s'?9VOp><i^Y)o~O:Ńџg_a䟓׹N(qy_D3rh,ȩ}JuZ09wD{Q8_\r 쟊 +Eu6r?Re'ύ#2DCYn醼7$;2p|BS _zes>%_([G.BV@'u|riF n4}T#|D|s-2Î;Ȥ5tDod6۶U+W)|9ivբip)kV&͗Q#Fè3v7\8/ߚv|@ڶmvp6}~^N>w<~諮p~"94r5JP=YjC{ z$I|v$+酈Ogadሐ5C2V[I]}F`y_ti[yO#2Q.sL?wy W^ޚ䈞{>H2?h%2+?󉧔]ħ[>&=iٲM/EBڶk+_|u7>3k~3t|z=HcAUUo?tնm܈ho9hrSf UE,^_7+j?QglkUVjʋZBfd $(?*' LcoCI1k:u_u7(ֿ geeeў^4G[?HfIh'Մ!i'To:|QE$ .3}+R+Mծr"J.dÆЃџ+^Lz+XHxa#LnG׽Ͷ0sRyDӺJ=te!Wyf6e/Q K;;Kߖ_&Wfmd/5z>RPѨo vmGP'h]t'}|?ϐɓ&&e &Mm>?XՉK,I'SSCtg7IPM7\'V#i⨣&ʠ w}we.R}1YErɞҺ͙+cǍF9O1]*UAN;w| ;!ӮUUpZ/}OFlFr8N,/u_p6|7+W\\BS]4Ip|ǧ`z\'捻eۍɟaGȿǿ}JVb>?wIH6meeJ7D: mfϛ'G #/&\w?1nQd)++Q}AUʋ.aC/O߫FwoٳeqqR>һOMs_E8:>(O?Sz{]dL4I>|]ӻG=Yy<4Qi(S w}#mv{2"0F_ގq!ә:#1W Sx~?f8EϚw}hǎoiG`Ģ>D^xF~x3geoZQ'D0_~ܳZy!O>Xq@d'5{ iO]ZvŬW^Q{ù.t䓏sgw=:O?<ЃC{=nP#e!謢<%#G]/@ɕhSh!tz??dLr/ AߥBbggFl$tr?;4&ddhc7?U;K /?Ufm7fB?la[֟B |ʋ+0$O9Avɾ5*gg FO%Y( 58EO&MMH&_XĂƕ[R2 owҞ kmE? ce|47P%e,'-g1 e Rm.y†(+?4 =;@kʋB{+fF{4FM(ٌ?::PSUV}&?+z[_9t9"Ga9{nbK 㚁(:Ӧ=޴CE;fy $h٢Fiݦu/9>^ x1L.X~~u.\ 4wp!50 9>=i>DJ;Ȟ1<3twgq'NS:7Gjr?S#>Sg>zyhǍ#zB$94 R**Hl)rǐ CG7_N'sRDLzȠ{G3Miw9h:3i%i'Oy$yo!rgGog/}0 Q[?'~rL>LFafa_\xvc|֟wg'M29#͎eaYeLrYi3 OwUqk (Nr &233Ɖ7ӼI_CI (2>%B?&.vN%`Q^Ejy ^+Om;vox]|\o*ƠUU#YEʘ\SI֮Yc?ٵ3G%,Yx Az;L+@/ǣ`J %2eC ߿RNN8C'\X #YRɦJ uI7t:~guС\wu%9}Lu",hϞzirGV-[%O0^^5k[=38D<=!#ɨYYxt_i!nܮ9TJ0oC xcSd ,^|ֿQ??28 9/ɝ߾Ao̙ͷޔAXw/~!pqVʨa壏'jD89œ_]V\&KkAMS{NsΖGNa?sʢRÎpI,[&w1%89E|bi~^wdϣ_lpԻ#Ppd3>yy?`i hWƏ##T&Gʀs&کb MS񩲢aCēp³̞:~lϑG-gO#G--~啣ѫX(S'E,T4.Xf<駠QeU?vwjС^x=!| (S?BWL=oggGD$m ZemZ1cT=\ٟOS,fMm֟jI?_lE p9?M|0̼Vnau-sjȰJͬ#Fx9C" .l6%Xd >LQ @_lOc&ҿ]>,v=rBҤr '—Zelm\[0zs+"W{3VZKsz ~*K?06 J'O-dt?^~5@_?#ym]4bK3{=uTϝPɐ͚IwQڴm#,ZP>FD-ITT/Hݺ.K,*6eeo8#R7o>:{챇t]V|B(?B魐mۮЉ}mC$WeŊ1sgW%++}zjk7 W/:>?~GҿW]^TSvIq?cd7Ʉ?brv[p7>df}4vQkYZaCh@''}"o 7m܂7pb8>]O~c4 E[Q%b2x3GĞe(?"pŦ?TE`Wds*:TUi֟}cvִ։5VS?5kW߼`k.ѽ}-v%zAh(ǥvS #(C2@ 1#?*(BN5sb'=+d7@J:i 62LD$c!"MI9+J)IX㿮񟾴҈"ϏeP c]: eݸµ,9*w C?⎉o۴mפ'jR RW<ݢVHOE`zҿ+@ܥ0zAY[$L+>=ñeRW[[so@ML+;;doƯ8Y0>,+ȴ?`ډ[ڊNYa5:a7BW286_O\Ge?r(~2"ESL >ŗtt Sf0A G_?]N}8_GF*/μD#u66t +O U۽?Kݻ*?:_?ٶ׺:F: co/خYޭJќZ1WF%6H a,iJx Mx_7; }:29b777?&L/L1K60OE=_g\Ae_f~ S$(A˱#$qAV13h$:*dhɬk"͌g F XPBBESB$ne@ 1*66IT&AVqtD_6IT&AVqtD{~<ѭKf~\X}Qsլ>چYtr''П~s\u몥E`HGɒDNIWB;;>_7Z?f_`a ?!$)P= {MƺD 6,%f1uuh'I cQ uց׮:8nl,ŏKvѤMQҍϿn܃>HK~Xg?OͿ?{%?yBhӿ?ycߺjɡ߳A)dkIs|&U>|]V6hW Uf%xJ??i+ /7]j;Ёpz߉.;u=0x<"u~ 4j ??^TT)%6쒎;>#{=c̙39>fJg=P<ȢO(iaAka~*UxR7cw-ᖰIbc a73>W蔯.?ڦIHw%m&U)U:3t$= c,bQ9]aT?70p@{_ ZxT%_SuM1Y yܯKa{9zJ!FJ+̿PD3 $mfvnNi/)iuD1_H:CũDf _f:OОf憭?J# ^/xW `(;,5h>8,do -ѣ %nsKo!ђbwf:<Xqq;y1  D4N\U2rGɟ+d#> E'x(KH++1uY??Z:| \_9!<&uчbuBc寮Ajj#B愄ZMqom2M$%?= tmNk?H#} ɿ| "}ꟑ66|:?~z?oG|\xŎeK"gӭ (={Bo)᩼ѹ?Fd?RhaK d-lVp%nl#Ni/FᗈשYEO26yx,Uk":)S̿:u&joE=Z46DDH+E2 οDR鯩? # 9RM_ ~9GjL( Hߑ<WhiǑ{O.O+ sG"[zߪu+r2q-!+.?=$uC+m&J^J?l=߲XƒpjZV^8_e) Jܘ?8;,d4,1=̨^_^^_'/~HOxB8'E(clX{J"a ֭_Ri?!79WR/r GHN>%Gy1E-ITcww,z=@͝ #?8}׀W)Gzis{vu⣋J\Ė: tAri6#o,ZPZ]$k8Twչ((E1a}_Zʚ/,FQ;Vakg*bE? +᳁!ي0Y)W6/V~jZU^|?~(di)7jt!N`wk4p|\2:VTύS BϯJ])JM4p"T4 a,c'ٟg\TO+MD#Qf_!mxb0't0/'@2;lmEY-)(2lȪ_Yi'a79rjHžK4DV3ָͣ_dd#D`3kCF??/9%_J94Ln̠_D쏮{PJ_o7|H܄ iL"٭n83 ;6t 3'D|4 H71ii='4??&S1CJpG$(q1K=bٿ` ,?)3#Pɴy(FSVv?lᄂ?lAJpG(phhxFٟa'yO]0ģSU[9t_rB_"%#Rz_#HQУNXei@IDAT eUq.mfFeE.(ݘ(&$Yp4L%~/qB 1jb$QfD&ft (2 CZUn. 4ߦ٫=ujժ3 =r9[vh&e{RŜ Gk g{;`W4q=bNօ5+ tٞT1'zMlOuhlo&n]'Ủ޺ppvE7.ۓ*Do]8Zc8@Is.1]M9[vh&e{RŜ Gk g{;`W4q=bNօ5+ tٞT1'zMlOuhlo&n]'Ủ޺ppvE7.ۓ*Do]8Zc8@Is.1]M9[vh&e{RŜ Gk g{;`W4q=bNօ5+ tٞT1'zMlOuhlo&n]'Ủ޺ppvE7.ۓ*Do]8Zc8@Is.1p~؊e^Zqꂴryvk͈t\~&?p[1p|m*GCGyG _+0bi#o/̿"H0(@ O+Ϭs¥/p/%Jd ߡXeYlW_e`g,X ۗ8ϔD 9CJr<6cΐv0fFMd34< `.8 ) ocfD 9CJr<6cΐv0fFMd34< `.8 ) ocfD 9CJr<6cΐv0fFMd34< `.8 ) ocfD 9CJr<6cΐv0fFMd34< `.8 ) ocfD 9CJr<6cΐv0fFMd34< `.8 ) ocfD 9CJr<6cΐv0fFMd34< `.9sS BM7 Qћ.f$Rc6yӡ|Okwi>`/,vZA2b ?0g 1b%S/K^'O?$;`/|<_dEW Sζ(x?a .7XCrǻ|B%hqoOWP[ḤSU &]dh6]㘷iJ%0 6A<b ?131oMfx%1AC#@S{fΘU24sN1𱡅U7I(ެHHWQUV;>8>Oߨ (/iB`QO?4^@ Ơ_~/_̿d%Ը ?z9QaU?2T'oT|D;`X`A#PB[6cf]U!`}o} /}e"Nv3D?_mS=蟋ÙR>\hG9&<GM0,OuRcjX^ɺ)rDja~Җi +vsc\p|GC/_?3`7$$ZzS)GYB.gYXd?p?Yfg֟5/?/)gVTEp!nf]$A聎H%}\oC;z Kކ :v 0q QBt@'`.z.؁ O\6D] =б m@zc@/<sIu @$^x>!A聎H%}\oC;z Kކ :v 0q QBt@'`.z.؁ O\6D] =б m@zc@/<sIu @$^x>!A聎H%}\oC;z Kކ :v 0q QBt@'`.z.؁ O\6D] =б m@zc@/<sI[O3 Uo! HMPhdF>M.'UdU6MimV\ tpT/ 8g2fEA1d@c#KOS0Yb'=X `_Xa֟Xc5NdGYdQb?j?C7L=ڗdȉ6SBFz2 @3Ky3E `t%H>$ @2FC63b؍Dn’ @lx[9%^`em|Ia+O5qO>h?_4",7GLWCv?\0bijA2'oZ( $glㆌY616s3?0`bFC`jU QGGP3P1vBGBd?՟Jq>K¡ WDxݦ!G\hmei.6.e6j}`Ɏ[E2ZAYZKdǭ"Kڠ,p%CstFmPV!qk9RFk6(K+w 층]p)Q{Hv|.ڨ ]=$;nm>G\hmei.6.e6j}`Ɏ[E2ZAYZKdǭ"Kڠ,p%CstFmPV!qk9RFk6(K+w 층]p)Q{Hv|.ڨ ]=$;nm>G\hmei.6.e6j}`Ɏ[E2ZAYZK3yn*2~Au֮g=$Ƚ@z-Hz)i2UڌtN<_Q7 4۠7ןV集엕*g 2/8>G8pe'o̿$߬?ސ'X+믦-H}u߸8yնfWr+_׍y5i͌ _ܳBS/*??ZJxH&p|qVIxUI0O|\60?\2'=RƔjF~ H %M  _<,(i]{?D:r|lGCGVP6hċE2dOVF`!ꬿhxG4bԓ8 U_ena29D!o?돬?򈐁G_Yfg֟"X#^ 12 iĤ'}63?? Gůb蟭aKlX]Ar`"C޺Dk5҉8=5|n!'s'5Mq2?\>4gԿ!o]C5NK'㌃gz5;q[Pk҉8hN5Zd~t"(h88h VCXڶoN%l%ׄ@2dgXЇ _<沥d^7&X Onء+, ?1d7! ^H٘>4sЄ'qߨ:4-X'?TWU/߬s֟XcGYdG_/?֟YLI}*ݫu;lUƛk7i{6x0wbm& pQ3j$n+z(,X۾z\??:bj$D) HCs?s+O833C̣EPnu 1w0]m|^ZK8oܗw-pC99"?-1yQXwI2c>6u,!?1I'B #Haw Pd}ew 1w'ojO].kh̘41ex {K%_kKF؈`\rekF+b IaG]^w>i4Hm9x r@5fk۞$iE5PM-۞Kn4ԓrFDN[iL3q('kD(>uur@9G[ǏHBHRdfXB±vVNE9R}ϕvEu(5%?s?P5U[n^Ͼe})[oX.9/_-7Rͯ+PLS-TR+b;G[sCjgg\0cE0POxͮL(H(KKz!f1b/_-!dr=OK!h³,30d/?ʠ-O?xFs> A~9<NN|&P/ ނDxHcJ7@8>OKs͎8m3Hj9i *Nd܄hchg?Ƨ[^fe*``dB$YhHmEXj,E=W5B[؄?ȣ6-_T߿{o+ģmJj0/|+_~Rϛ^6?ƿ)xT[(`#@>/@|?g0kyhBc7oAi*(o̿|yKdb0bgeu(6`_Xڄ7f~~~!zC"`qN;T>jH~V19%4N8=@ LOt2)'_?\0`efeY"6wW>ݰy(??*yNԄTh䤅WG.kqAN`ߔym532?p ЯNGeX}G嗕kcu}=K{WT.DK8 W_?u58_1OD}s%u]5"0c_W?L&_? 3fCkcXa2S[j29돼#%K"F\d}d !]ID(QP="R!^7?bW_S.bWpeժG_o£i?y P`\T ƿ2!<'S;:OƟ?}-a߉[lOt/???/7~M?\3ag~sxT_k%mv J7c] bV3* : ߬'?TwyQ;WcI̚5w,.S©3L<:tHȰ _%&,">\L}a?25֭if $G&{HazWq%2\6gnAEƪw[VD@ArW^3E_$}AWyjWhNJ͊62LJ |Z|y馛k><ʅܱ|b"OKhg<???5Zc\0bi13d4)XϬ[gOqZJ#믬?3ϱj35Hb﬿U) zֈ )ܹ&z 5 8!KZ w޴??p3h^B̋ DoqgS'ϳ%m)x-0'uX!_ש (xF(xŭIh(䀘*S-6+ p|+TvͶrm7ۢvo(?ܔbmxR>_ J 7O'A\ Y_ŝXuCo?``kMFo Jd`K ?2fX@PKM0/h w|/rH1>5Htj%~ (C/t!p|-gJyc8-/ab71 p`za2V0\hNc23 `O'VK2fg\̿4Ȗ?21̿37o+^`ђϬ? ` |gg6 ;\Ii@n8*~:zW :MIlrqt^5##WQoCH???Whdf2br4?z,cH"s d7WqirהnΖwءlv')˗u><`~k˧ߩ!?`_P _)281eGep ?1Dw<O? 2&x?4'<h(9.7 P LԿf ;oGaD $???/6{9Ӝ"|aq>GzY[Rf~]WaQ.E,4rt]:d{!=ܡ Y=u| 29>O Sӆo_X-T ?y܂f)&'OƟ(t1HZƟuM5u03kfR5u9J :|J\@Zgǐ B_ EpMad*81P84ʩl#j:D5K?\Ӭ%m-2Y;!U+C@A8~oſx 7_<?Q Q 9n@p}pDE_W6]'pG\㯻w1yW.}մYU<?l6B/s)9 ?ϧ1ߺ??XH}Gp0XXB Ɵ?A\ O7)#믬?׻bXɤFHr '_,.GeҖ߬? /'6ymP#f̍t(;w\tN& u-ԿDg(U=L!7@] 8hڟHg(U=L!7@] 8hڟHg(U=L!7@] 8hڟHg(U=L!7@] 86_|O1NZ*´g9ұ!+,B@̓ z ^$3M̲ٲf p,#xtf׾R.eQn{_x˷ _F뚺EZa#p_1E+⬉̿iav0d_-*-Yb,7YdGYdQyH`QU&QߐaV}eK)MPZ"5#ŏE._@23hcOqLcYˊ`r;u0Xg'D E^Z9YK &.\LRh'9lZ,Wte=*?/+7xiw*Ȳݶ۩X?*jο>вSMzm;':_(?2.qstuPlنǨ\R0ua> 6$ l>V`wa<_?b b-6S-Emf j_QODX??i`uf(j)a,0;1r E=abUf'u~V)#_1oy5c|D1fY2koiZ"j'*nt(Կ*'cPD.ɚ{)JUGUL:?sTO^i0r3e_^?(d ?c#+.~ȃ-ψ_§ףg>kȸ81O+O%xQVOwP? ??QHcAr_?~i2-Kj4eOU-v˪u20f(aaށfjWUj[ee`?S``G](au45`U _3BtfYC5ROխ04}0dӜOƟ;B!ͽʃO27`Up'Տ73T8! YmuvpvE7.ۓ*Do]8Zc8@Is.1]M9[vh&e{RŜ Gk g{;`W4q=bNօ5+ tٞT1'zMlOuhlo&n]'Ủ޺ppvE7.ۓ*Do]8Zc8@Is.1]M9[vh&e{RŜ Gk g{;`W4q=bNօ5+ tٞT1'zMlOuhlo&n]'Ủ޺ppvE7.ۓ*Do]8Zc8@Is.1]M9[vh&e{RŜ Gk &o|jE:BE1 P`ܘG <;xF^Ea#j|B&{5SzЃA8,|D_{ݵ+_rͷ'?l{HY}j'6>-D⺢_"H`R1e?'뿬{TFXcO21$J˧Xmg֟Y`_YeWlBW{3Ϭ?/^no|Ih:5Ls䀷md"ǜ!9hF0cΐ 7Ld34< &2]pR޶FLs䀷QD 9CJr62cΐv4j#t1gHix@xۆA&2]pRގFm.8 ) op#D 9CJrѨ`"ǜ!9mnt1gHix@x;Ld34< mÍ .8 ) oG6Ls䀷md"ǜ!9hF0cΐ 7Ld34< &2]pR޶FLs䀷QD 9CJr62邙3'>+M SJB35Ra=J?z̼$0CYJ1<&|ee-8͔믻\ue5QԢi?XFc>&K8{8>ڇ ? {aS< :S?u]TXdZ(u,SXd]Z$‚-gyMNV8l .x06?_2f'oXaIrCIT[SX]<β+&Yf)~//3Ϭ?k _x_mS?݉ BxûH<;z Kކ :v 0q QBt@'`.z.؁ O\6D] =б m@zc@/<sIu @$^x>!A聎H%}\oC;z Kކ :v 0q QBt@'`.z.؁ O\6D] =б m@zc@/<sIu @$^x>!A聎H%}\oC;z Kކ :v 0q QBt@'`.z.؁ O\6D] =б m@zc@/<sIu @$^x>fdxA(|cC5dPztm}\^%%-O:zɪl B8ڬyCܢA/%_d&:1r(" ?1d V` ?bkX`El߶Fd߸(!%B rBE0NV"@SͅgԶ3f o[#pWZ#aPE&[aFЙB A+-Uڵ'StmfNߘtQXQJlt4/GS쨑z+$'??6C2hy, ϭ8Hm&6W}KT 9df V/'CT6 MCyZ˗-]2X#4:Ĝu19t6@6!0f֟#믨% ̬?wYgwY_'q rƸ>{g{Vcgh0GyPh Wi!߀^R uWsq4Yod%-tT#C?\${Ϯ'͘R{%MmPvKdǭ"Kڠ,p%CstFmPV!qk9RFk6(K+w 층]p)Q{Hv|.ڨ ]=$;nm>G\hmei.6.e6j}`Ɏ[E2ZAYZKdǭ"Kڠ,p%CstFmPV!qk9RFk6(K+w 층]p)Q{Hv|.ڨ ]=$;nm>G\hmei.6.e6j}`Ɏ[E2ZAYZKdǭ"Kڠ,p%CstFmPV!qk9RFk6(K+w 층]p)Q{Hv|.ڨ ]=$;nm>G\hmei.6.e6j}`g܊Uref>$]Ϣ{H{ᯁZJ RBdvkU HyΥǧiES=+/Ju!qO?PAQ0(_tZ`jh /@GYeYCd=Y?qo#1?Ok̗e˼$RK)60O舦O{[,K9Q'3s2 !tX9G4|x ohA{o?s7 /+Ucd^TSy^&Z my/TNhqu.|p|qrO?1-H̿Y`E!OhuW_MZ42U n3'qqmr+_Wrkz ,֛3-l3g^UZ ~H5#L㬒] @*>Bo`$ ?ڟla>\se!6O{<;p) Ռz,>;K@@xYPҺVa"~uԿ돬\=lЖ/2"d/̿CY'񎬿iĨ'q?ֿܰerBXc7Xlq Y!돬3Ϭ?cE4G}jcdXӈIOJmf~~~A2_?[>o&Dp%;ZGuֶkx AAq-5{xkܮC6O MOykgd~|"(h88ىC޺Zk8N @kv␷'AAqA3=8kpDPpqLͭX߇mߜ|K/"J< 6 "d AAvy, eK1\27PnnLܰCC/VY0bnB@,1R}h Od̿QuiR[X:O6/Xr"Zd_ֿY/?#돬?#돬"_?M+g}Vp`'gfp;5GFĭp c`RڟL' ,?\2`:"2fǚb#̿D7oߌeԉ+_5Hag]:$bǖ?s`%Kc50;?7?hN?D1u&-U]1fs ?Di"Ylb>dbqHS%ps2*@"E>v o3kUΈ_wkPVΈ?ON RFOA?^#$k.͔2Mz$_Tro} 9|>U ǏHABIZ;f+jTnW`h0"iP8p \2fe;?e}@'A6DR<:O߬?\Y`j /Ҳj_X@OZpaIP6SvIJO2r6b ^r 5yPGӎywI(=1 juJ 0fL԰NY' 0/mYG@T/I9'jT\Sj&"] Q2k'UiѫɅfkV =g\K:D8{ Q_Ac՛r#aӢͪg7_Z_`̿3|?Č̿J-Ղ_X^AV:-X`֟??ZF#돬?ֹ y`7X3?άYs 4os,Y".%  ,as9_mf $ǧq.͇3_Nuo:nD]rV$7=?+"`safdF\q]T+6+  *2AoX R_J?\ 08@cGM,61d^e+M?#咬"T`W_Y+|Ŋ^uf5aq#돬?ƪ+HUr\=i=TOuphܝL;*GVC29Go8>OٓY̒6߂wSmϧO,>T+N[Od'EZfLlxhA 3B5y9>bhjR^_BK9W6ǥ._0b}0wUQ/k(ko[;ԅR cdEt O Xav`1<$$O 5J2d?G96FP̿ Q/ 3aQX{>AyãNFBQRz8-~UZ>e%.oFP??+pP[_?QHB\1os4=#s, @^*'< 5/U _ +`8JB Z%XEg^Z_^iv;6j-kgk$}a[rmٿ~ n+Fm)O?Xk.BUݲn#Gox<+*ƪnǕW^YNx;˓]WUnz5iz]W_%vk10T=ilj{[ Yg;ȣAV^}Z۲!oxf9/W\qEy;߹'S1O}*\nc˄0;/}L7oŊ~2o| i1ne7w)˶ؼt~ W;)׾ ݅^ew,_c? ?@t|^Mp>֙]vީ|[n??ZXLھzRSwi뮮?o?;3`?ÆN4*P>I|g v$xDfEǧi\O6usοt~t[sFqu*#1Rކ㏑>փ[JF2sCZ>gd|tu1KD6"ԣ~.G$gxe?@ *@hC)ɺyͷ(<]xʪKA5,j^*0^kVnu-N/cVf۳pqV`;젱 >k(ַ)\v%r)Ļ&kѰ[o's`17=g?[(^>t__~yY"U%is.o/{z?_>i򲗼\+峛 yoٙYNd]e]~{3cͿ~+;>٥U?ZjUy~<,ɏ.Cݿyy睷!./X~9&1eիoO_וG?jn?_<4]N}ߺigY6|.*ȿ~g=c ~aM)}O?]Ǘ"-^w}wI,(>C|(uDם-vKyɯQUw(_wn׿^U [e睑cVI_,OyS[n+eDdy8KdXȮ7XƯL+bs^CO};-\I>Z3YGutY|[ն? :sV貗܈R\| ۨg<({񈇗Ku?('gCS8l!7]x_k=I'~guf967w>E/ uhnmc=nw3.׼?c?]_]<;gO;P‹lxgU6]/嵯>n[E/kɡVշV}g>zmƲ|mj|R?ti?ɛ vb-@%@:är}{MeΕ5wuŸU6:I/M/+8g]t07c5_uU@7.w_WtuSOG\Y"<v8Ͽ~OrqTU2i~|i/̟+_u|syd1iqeٲ?}MN9 Ô;֬)? 7?-7tC\YzfySl"~'/_׿뽧}~z#-gqF9;r?Ǜg#MB_(C#v}ƿ+?bϏ9Yt?,m84IGc_Y+tUrmֿ78y9k)___0b?Y^s3Z_3F2f1o}1ι0<ć RarF:CDp8M)qiéGC;Z}|hdj`J\\r߹VYVl69/?~q? s9 Q 5zh#]K֔y`LUC'IJ\n_3_."J ͔K.X~ њ(?{>W/tMv7^.B7>ſZ|1jOx+57>G[//`M.>/5~u|Ϟ{]NqgUNǃOF:DB 6y0c]nJ4}n ykluty@r+ ϗ,>_'Un;Ntb}_gU|do ϽDxMt/1>`,e>?HxNx[m߆Q?Ϗ7XY??>_Uo}[!fm]y{O˜)_J>r o|ƒOj vǕWR3A/}p9Ih[o.'nAj/{y_:vYӷ^G_ջ.OgKc-tr|ߔ!NtQ_rwi׾1^b}3Y?2ЪSmw/{)b_B呏!.^ޱVAHA!/WCo?]8IP+0?YdU|fu#4soԿq?؂pnZo?Y+;$`,c#g_Ɵ?;2lSvlXɾZ>ay{'꛿8SO_׿x[NqͶj__߿T]m'yy塻'%<> y];g_ȃO|Pێз]ׯ< |t :g-o-7Aig>YOϾKǺK^rѿMGY_07OT=_Ly8GSe⍜WRGu_[GW`Ig>-1آG?և&?Kܚ(ӷ &(^ry;M4w~aKhgL[uI>}7QPjR/=s|N'}}ड़vP::?ƿ;㟻0 _#ƃpϿ9dg)9,Sb\_2G? Xd_RӻRkį8,1x-K; u0RXCJץCZSb|z=q|ь"4 Ru-zT!n#^O?>RXCJץCz@80mu:9!#6VyF'h\d BJpl_T AJ>c<P?a;G]/_^noэhDo.k'?lٲr5`n'“wRWHnH7ᗼ97aΔƯkVqxgׇO\|Eziǯ󔧖<-7*߾rʹ}ό[?H'{ʓ͕\rrS} 1#~\Gy8+P>,` _bWb7&W }}fg V^-_?<<<λn(\xA?i=vwؾrcDw+]|x仹?|GyTyUm'}U?\tE>?T}\z%чR= ާtÍ _R93?߷t['>Wv~{C+GyDweGyGWs3˼<Ϗ+:9 b{qQ׷}5IpV_B؞\{v~'?aeOyH߉5z-;츓T2@וԪ^F@  AD J*JwwwZV,T0h:ٳ}{~{'֞5f͚g8x{cǵ/>fUo5ca{OhO<-^L,q4[J8zzPQG <,n0/IV?ӆ tm:?Gn/wݻhQmݾ ?UwB6GgΜIuR}F$9ScY9&URr匙&@`i &˟[wGOU +Oy"y"lU%$#~ ^Ͽ8s<+3>Jx5tk/~S&3%RhuE9vu3t g+/{!_+3L'~7|}z|jU\ xr7iX*WVrȎ}fyeoj?i4)2 oN:-1.x{]g7`h)OjK]w谮Doly=RdIX+i(\`C`o'C>:R?n0U]2ΙBOcx+/ė1wUg<"9 5J`V^CP/Wm6;omC oBb^+tvZYl̘=Ю]T[g9KO>-5W>/zP;vg}*s uW,]OYM{zJQ#*0[M5v 1ӧzQ7v,ǥ7K+dmNeRc>$AGc@fNc'|Ѩ3g{+UoI}n ۞?0'\Zeڞ_a:ǤQrzK&M3堾CjCO>~$I\9ei.Hj?SMg wM7, ̓W?_t)'.>[OK*/E72/1V5X`G/ZbE?5F_u/7CEGpMf(G0K.)#@bgOcWC'O7_?ROV&5jT`O۷u%ֿ֭+_K2ḡ=zp(گV_y1}2B$CB >@U ҥ̿gH0wիWO*?kaKҿ[4nzՍ+ c"}.n ]~ 6\2g_KWW9h9R>\y9ߎV9ghP\_Z0a<pP|baoBocOA!y[Wٹs2]Ty M (k/\c,Z9f Ҽsp?zgs<1 5= ɟm3r|uBi(=_xQ2c{K=ŘT1 ?^ u ,`%KVѣ\U8DgzCN W\uՅ\i0O/N$UAqVzcB7Ow>tgX}'_aVB;(xk$@rׯ[W*?tgܱ)錵?CgVֳ_)vE1&}z;F΃#GAGKr#W^~` .?͛g/\O_ދyuS_eCxBڽ[`l'3;{xxRH  ?f(? >⌧#牄)~JI%޿赵+p|jo? y.:: y>>iҤ0=_Iz}TIA&,?sLyeKD˿q|ҫNjx|iMNmNp ZHM)#X&x-_^)z: ؛}{|I@V|]J?SOK2@дgS׬ֶ|2O+-}}2OA%0O/@jGF֯'{UK}&>K)@-۳`@_o cݣ"D?q)xA x;ONwl"?x(X@W~CTw_y[wO~pm/hO1Xң_A1Z4 ^D'Cr"iVdCPx:Bod#hhVZcߟI 2z?||c -^v*q2< .S!5AGpXy&"FtUFA9Ÿ% <C$#H #Xiq@IDATEqă[lL0Dg*H@Q #8G,< 9Dʠ:PG<% <CFW'cr#"Y U +.zGyhd!qGlF=boZ-0wG|(6_!GƌrCufL`(TmۺE^t\S_!=^ 6ܾu+d^m Kl '}#iX2e, T+W.ٳfzŅLzd߿_~yzj)Z:OC|>_oRxqɚ5ۤmIoB>ٿߖN8'"L>y_)w;g_ryj)=z]MM{DZӲe@h'&vdrʣ|y|˖(?<]ø4# 92k_@A;ppO>el޼DHEʐUD]v˾?Snx)mӛBx j*>=|H?zr/͛O HGoU dqr2(S2ezkW"G(c J1xbȝ;FߦMxPlL_xaz1/.~͚>Um OoW9e:4R9ر[%ЋG=QL<)!l=FL@:pGxjVcrVQR̙3ļ̢dեJJ~}'iܨ!Ý ~<]޵~@ӛc'x1Ȉ`% (c! ֮{=,MyFAY]8^ɒ$s Z'7cO>W =-1Beku=%VO~RY` USK[1hizଓ|btqAT.X0,Dex,oS Hͨ<bҰW 0M4h?W.]J5=ؽV$<@l\;]->0 x( 3nRӶ!$ c޷|-}|[;h;6c?O/F\K;wjye#aQp׈[hCZ Fhz%8(k\TG_FoAw^;pň[&B ƔH:0Gg,7>9[8#\I⼑-L5xb'>V韾D/? mht~VbAd'ZΝhذFo_Ww8D׮oз ; ,;DR9̴mߕ}<Y4 l2Dxp*o/<͑Bɔ9%No7AgV{uzs6t-kME֨86|7hHӍe?<>)_ye$x!@ @2٧\s5Jǃ3þ803TzU>\BCSDxpο˔3%ٴjOоNXE"kԝ;7t1?3^Kd02F?t. q^_<॥)Rf? ~/Z@<[YqyqF <_REyNZ ?OA4C K/ h@v wFs%M>#fԃ)˙3CG0@Lc<ͮ"}kWmPN}U'.sɿ<$l0O^ \AqA" G)C9N]x6o1jQ'Ysz΁Wkrs[s<mH݇ɓcDƌe z(R4gVF =q 38cƎNS{.x,+G0Y0q"pJ{^qB+P0 =>œ?@uÆM &,=|V o $9aاgV,^׶mۦDpظqt.{q u2p )V 7uAkN{x C?GO3?%Aa<v-lßh62۶y-S+E2 @ .g8;SAK-SAe,ԿX;Fb]8.7vnzemTh;x:9eV xGA~szxd#RGJ_k^/c"0OI[KF#ou|^^pXaA:aڵ{7π~]v/=xӶ/ۿڰe%kh~3*p'{8M^x?t0)R=]T)\Lm y e˖GVȑ#to:s'3;~W9͍7^S{i3f“][[luVg͝EǞB۬g>x-Z YF -CԷ>xkXsޢ'H̯B/Y=g\²U^hm9 y\OoF/Sd2o=>/_i,}4oI([p%NƃO= R6}O=)R߾]\9Z%Z7p/*7PXcǖ˗W?p˭eUWXݻ^7^}M,Am;,7e(k=l:u#LxsCg1gҲr.f?#hEͿ@ h_̉h ^P~ŬJ,DDc[t謱̛zXҧKu9%;X!c|jȊqF<(h%"u4O>T<w0'{C/ICap3-np0<8;idɕ+^3g9?f2GT[ ?|)>TAz㏽ 7yYy衇4u3?U6' ϶=$9c?؅^T4hۖßjծ%3+ǟ6^xGCM؄ÇP6^1hⰹIS!ջ\{͵|DPF|.%}/lᇯgMzs ]K{jnC^h˵juRv+@`Ái[ԅ'P< 9pʉ8Xl7ߐpdD\b<,U$_KHtx @q\d$/Xj -z!A=oHa? aQ`QA Poo iG&6 @dUa.ZF70kڌ *BO^ǃg6^}H{?oA28 `D5mx\ yn߄`s5ùL2Urɣ6y140ucMt<%(0W/Y8fx|: `3=b:'zv<ϲ۷moK^V{`.2N?`SvOߗ ?fWj)0[O.']<*Sgf5z2DZ.4VtC U?1_.?d5CP~ȟ2Y?^5pQN3#5@7ro:!d3D e3OT _xDVHQܢ7Z9OxDhc6?LSζB@F_L /D-;? mxP(h/Oԣpc"'e3GۻK%|QKrR6-{7CNWZ`nݻ)*vR_ʹwKM-P6l[bn l,'e3wS`=T$} f9)iؽ[lb'+E-m0IL{b{;I_/jiYNfڻ%v{IJ}QKrR6-{7CNWZ`nݻ)*vR_ʹwKM-P6l[bn l,'e3wS`=T$} f9)iؽ[lb'+E-m0IL{b{;I_/jiYNfڻ%v{IJ}QKrR6-{7CNWZ`nݻ)*vR_ʹwKM-P6l[bn l,'e3wS`=T$} f9)iؽ[lb'+E-m0IL{Z͎o+C+f};5&AGYI@s)doXF] 8AQ9I/ aX I pP_g8C>xQd@/x଺I9QX(o@7W O8?vmJ'~ K6nޢ`ῬYE 렼2 c ?C߯_ozI6m^68e*o%Q'L??>v܄#8'SBNil%,Yc^{8pH=ldd)ϟWa<KIY A"Bx%!(/yuI;uB4QRO8֮ ķq87TRy(; ȟ=?eg!x"oӦ=[m6sJH??@+r^_ } Ǔn_@*GK|ߒԾ>sZ~^ʒzJtN{K»պe3Tmֿ֭Z˝ܣ0uΜYx#x~&zgcޕwI"}j _7 7 $ZT'i&[lFi4;&oGlmf$GI8,? |\[oȔuhW:+SA1%N@~SB7ڱ@HkUW A=~ϿlހeK^L]_N2FOF| 4I^qc$w*ocGSv9y 0@ O=x'x?-Gg—' KlX T]ۍ晫d!ߺeo4z<4{$)X0"՝AQ_*䉪 ЫO/)]:.{BF«+߿vQ ~+[V @xlG[7mU)].zlzk˃[N-qjŘ/Ӽ6pKЍo^zcLؗ:\\Q;T,oEcJ K+W5` sˤYr+$x5|{bY'Nzx#v?uCo5j ;^pE<`]&gLs\Rogwy/R7m܈}y[*W+顷` Gﴶ߭ t=ֳ#Rf:{[<x|ZY,iʟ?Dž9aRxnȖ= 8KxjC\l4MEK9)=]QC-28wIsֿ\2eTCoo2V--/ OM6 +B:y o~{)+^}Oǟ9Ǯg5C^&MzK?3*V,c'si;Y32_4K뗿a߹߮??v#HG_GS" hB_obf/o޿1ҿHD?_&!p5z~*F YGTn¬e۪pvc6b11C0$ݘ{ W/Ð$&- xi7f#Ą%/lcz$1alI8K1w]L̐$&- xi7f#0$ cK9^ڍو{bb$1alI8K1^!IL[nFc3$ cK9^ڍوp2 Ibؒpvc6b!IL[nF=aHƖs{ Ibؒpvc6b1\ C0$ݘػ.&fHƖs{eĄ%/l=v11C0$ݘ{ W/Ð$&- xi7f#Ą%/lcz$1alI8K1w]L̐$&- xi7f#0$ cK9^ڍو{bb$18O;rTCndųg2P!H:/hy{2ƼH?(RW_+ୀ u?S228GMH] 2+_'x Nm7?Fb|郃 gV,_z y{-[iC5w)^6ː+g.9ÂR`|4̱R2<+d`(8&], U`j`4HdHRF?xOat=x?@k%;m knr7+OTF3 Jb5F/] ?p ӪjbP_!]4}v[i?,=˿<4>Ylk??2g݃8+a#ǬK+JO:[?{ǎz5\MHߖ8X z5 66(Z5RYdש=Bx6Xmjuvo!T%V?KO_BўܹaW6dRV8t1Re Я^IYtmK{"J?o2zyYx|R/3(H:oF?ڽV3T.S S2~ F1ZIi.ૠ<3̕D#N#~O(֎h3CEfT|rӽ?*~ȟk˔Qpݻyf:;Z[}zoFugd*$:r(iIYd V l>jL+8h}͕ *>/~@oڴI:k?=1cT2x|d$ׂF#J5nA3+r樾O n5A!fpW{6*H2܏bb߾cG DVwx wʔ!}Nm9 `&ڿ| 痿}UڳOɓ ^Aߛo=y$?@N94;Rw ϷmЛ5ec_@[o- O`_@,A:˖. $_mF??c7?ҿha Oo<ֱo&DϮE?F/,뫮x#hhh'tGݡq_bPQMJ;J<Φy-Ո<"*H*Dgf)T0הyWT#n#cfG/ГS!?\MٻϤnFT 1D'?ЅS|>+g?*N VL1:5+WslmJT 3zwY%<??z@Jc+C_?w}[V >qǝ ~#Jr؟vmCF:VYIӦ lw8S'058|)DPgd~5`Om+ݳ2޷=AGzCq(s_xx yh EL8I=gQn^'?vxg[;th? z9%zျ͸=}oX~_ ogwEjO@̙W_GgL1tD=?o2~$<_}zϟOV efmohR hkw1zBRH0g.sI |B~_rx|, -*X@F'ˀ4r__twc  oc+p@^;d[ʖ1 һg/ g e (;p{C]v&?rpVx7u\)|GĤ7 *z#]zK5}h ϑ :}RjFconu)o%!z'ʤegd.8IkI ,w<ftq_k3kxx˟}1!% -<3n-iLY3kG~g">|6ݺA+'7E0zR۬\R?W2p ?=NJYyeKoBƔ.]ZnUKs̙ƙSfT aaF)Z cwލYZs7 b%˖GC7*Bfd[6JcZ'On=vdɜz"SL7^ݩˌԡQ) T_ pܠ!CK˼ysa3fX -1;=n Uq@ *( ݻ:xĽ"֏QZo8?X OoojoG6S̀NakRX{?7NWY Tf]uU10hCl ws-Za}ݩr_s5:쿑8<=oA ;a!Cl[gӿD7uRakQ}3M柕wn?ɟ"/1XG7:-'ZB`#h0|_;L!bDoEGALGoP S"rJ`>DOGKk7yHRS [AkR^p9ܮ# X@*$ׯ?73/ :԰ķ.~ڻ ֮F'?֟hQ \FSXpt{fsú4'$H2RR; 88fcܽ2#Zh׮^O3`C?2#znaʿ5enqViSy[6jOTxHw?Oǧ) OV$sfϊ*I3g) &ʟ^xp+$ OgZ+!CLřK76iϹ`WoT7ԩ#7t3w7m(/XwyI;xG/Y.e8ج@%qo1< 0OEu6T_%KT/̛5gNy%9sHV>vԯ['nboO_:uKkų.x| ٻQ?jZҧ/X'%z%'O?G2clӏ?Jx0|O?ے8[~2BgSNKpO םMg e6>ǧZ*iQzMi-1JDp1knZmu՗UApړgx|ƛ5x|zT9b_h Bg5bxƟLJS5n7H_8 ?@zǜO?slr#<*E~S%-[<?y $=>oclB,Wa{2?>AVZE;^XARDq9uUu_=rW*Wygqh̓ftO5x7 ›ը.Ke|x+J#"ʟya7~+Uυt2͛7>B\! k}b)bJ+cAJ b>Tv3+VQg΀=Xu㒦_ 4uVi湀?'@ O~O>PUKeɜU·-kn](;%?aZZˎm4yf_͚j5`YOV>5WaCgE:.o&SOv?OCdu{XzyrI|G?}|v /W݈i_;$ҪE˸P2rX}ds4,?9dJ/d tk? "FWYOsf*CJ<JLիYX03f gFjr,`?/Xgf3«KFzqêSB) ozsB}~}嫯RJa?kH}2Yy"XuϯGֹ<E K^طWAa8)gHNx.c;^E/tODdC"s- fpػ&l.2Lՠ{<:!8Q^@ʖb%p@oZ>6^ :fwv\O ;OO(Ghđ։sDI_8oK]_dX3ѺYtu!?#ZqʕKL ;c˾hLmb,a,"EÇR]$޳趣]t[|EU/ cXݛEFxC|_|o'<][:gii/<- 3EeⰮ/ 9z,<>Ҳl`V= ŽAhʈЮXre}{U'`o??=G,OD]9{YE$oujP㌿+SX\FKaH;C"%7( S hL[JΝ$i;"C ])5?YAkq+SS7l# D?F`W:qd* O^}U-KĿjժRv0K݋ S"WIx-# M=knM:tګvb^//\Dj‹\ΜDzux2?|P9t`ߔ?e_ b%d<>![?m6'O06 5) eY$Ǝ/j? pSeH/ɤ;ox iR>!4s&Pm'J݈Rjr9.ʡ}Yl 46?,Y>!lQŚO^L`Xzexޡk?4T@xm?\f)G9ɖ-096j úJ?KGuD$JWW5갷OFF*'GIP H"_d]7bLIl K`_w%G Doh_0 -dpV+FodG`ofʽh˺9c`ZmLx.>$73$ E#G`p''3ҘٟD'I%ٟTbUh3EoRAF*G\ӗ/a:+IGQpzu>t8t4kqq)W~Fx؏6׿[q@}G EE<,?Pٹ`I-Os|$F:Yϐ3Ҡ=ҜXUBGrd|}"x 1{]'s|ʟk&ڕ‹? @c3Wg8WUǃ<<7yGx.'rsٲҩ׭9d:dFD@MW ՗_w#? d9sScNiݲy][:ٳ+Fa ۿK]-}pCb+V`ue۶o  O֬Ybo"~o8n]1!X*O ?āFiѿOZ(qcFn/O+;vHV-)}^2'ORH^W&~_íSZ. fːNB/80|@$zWsxe 6:iwAF>y(<*s0&p9tgYD%`.\@%Y#%sræ1$?߶]{)zگj韟?VkЃ߮ O[6;8Յ=ҠϘ4?u@' ^wn`-8̰xK/'ˬ^Cr)=K>1w=O|?F# |rV%~KpI'!f‹م w= 쁕?&(aeA KX8Cf*?Sп;H9=W_o"l=>]U>s[?5 6('CLs_>@<) =տt3tyUd/yG'y{s$ֿxvZ"R<O(>p!]妛oٳgE;e1FIǫ P3 (;3am0Ճg>͚5 ?B3*Cz=uȉǕs]8 >֣~MLz/^$ ǀ2Ʉ}],|8?k\#c/ O ӭ #8x m?#\7a~ԩ p lg"zyO<.;(:w&7CGhY^Hi4&'0cjTCW]u0]Kch Jzݴi3PI@wS%wʿ>XOm8l(auJjzkއσ~J|6l[ ۷w>H0f8(Wa2 e~<ۜ᠁Z?ѹr]W,[Os/0AUǎS+/\b ϵ^z̙x68pPձc{ Q2ˆǟ'O,%r{G*V9^e;qB19ڲiW;(<׮]w( ~We zGHg=hgzO?1 Oߎ>﷿$D|gaX?ͿhSnEoÈ,t(?o+/oDo_ 'Z&DowNПM܍$j}%V >:7F֟G/j!dU f*qn$?_od#6ob k>ju#x98E"}Y˂r:7Tŗ8'_rXF8V~ ǣ R×$-w{9쯦vQ—hmOx>!oA|6b>kKWȾ?!m)4_9T_:S*bW>&|'`<;?啖T hV  9{FyV&M I x@!wI6N0ܭ*t28$S}xO8< ^sx`˗6G'Y֮R?G}؛=o.,{ڿ3!sTYS*QA>?~ jDPp蓞pt_Q8 ÐCeUl@_U1e zX}q9h!%lxOPɋbo0Pr%𪆃)8`zx0m1щ°M9"N>%3q7pߕWڵju_ԁ%K挲tR>DS!)r-ҾCGpa˟cR2UxX|߿oomaq཯҉[;0?~< zc'3CmNzٻkW`U!Ec0yx_u§Խ >?-N@iFd?oY:"EFD)o*~zC)s-tO/[Ofϙ'6mm."dJe@XE֨'M~Z1B ?]q1;>Zza۾m*V/\ C/S>GG=5:?N<,U:]ڠABtVG`{ 6l3-U[4'{צ@|B0[dHgiV)l}p\hM%>gjkƌdօ Ȭ啗_XTS8@}=g`L}1sĆ'%tEnfmǷw}@He_~C,`!U?!P6BhW'*k\7=_ {gN.p@e9ȋ'+0F$0&G8&l3 _a@ת ou՞wC0j{Hi ?7Oqש@*C&豣Iuk,J5 zw)?7t ?NLRl peڌYgȋ/t?C< Fҭ~F VmǿHQ8xPjH)*"E crZjG4o߾B#p9lYcKc?[6nۺO/W'8;7xon ?YaڔI::-eg4W%eV?$w ^U|I*}ǂsCc"g}k3 އ`$SN7_ Q<`[z5oolujrFU$o޼Z/'>w+|sz/:%ţCyqھn G@ְЁ+~šd立+ !̱?ǞtĮ e>,4t}|,6˗-$8w%/$H&በi _z 2nظSֿ/>_G~o7}W|Bs\s1$s,;P.<Ah`?_ ގ <+yZk7عുY$iy葇\8^Js~:u=U˟ ̎{+AG*s.뮗{3g>=_clO n&!X/-3v y|_'/zǺgUMBW~Xkѓq^}O?V?LW,FA9 /=z/>B=(;\Wֶ nWQ'IB CD,!7dQ}'4OA[E)>ٯvA=*Vy QU@@$I pyժZI{wnUUkWﶿQuUJ|'?c~E/nI;QC?ߎ7M;kz!ޮS~6?4`S'?l7s}f|~ƃ*ǀ?\qa=xo$g`*9q0)ol$OGXm$Mg$_; |"m ix-Jy={nZ |K×⿧ /^b\s4{\[n(Oxpl.`p} Ph ֏Bu>?M62'(|s?ާoŃB?-o5)G"CBO~ҷI>}66|)Ͽ=y}Uo9dV?[~NΊ>OX~ Cg>iM>z ~ }. j'?>?pӯ~|~pw֗#[<ҿ?4l 7oFYhqՈ/4\=\;RGT٤@yQڏEȁƴ[ EM)rjEEds!##+׌7|{8Io{qYy#ԵqO`1Ãں1&Z{u֗noMf*hjU4YGGG&<ق{ ~|; d7[rv27N4킏+rbn1Z.xsDžx\aIo[7M'bWMp&Cmo{Gp]! De/g?\.AvACw}S07M*{= cx1I7sNRH_7߽fzko%y! o{'ٚMwx{k^Zo3nX5ƃO?f?&Uw=hV]??M?xLG> igoTEϜs8//PFx ^ߴ7X[>3 pi:ɥoV|>ތ9[?|xw?S0hwc1o: y:7J\o8f?7ߢM )Uwǰ~iKo/?>_!tu[^cZ'<>}*gyw<J?=9ӗéPiN?ͿK_==?? oO/~o@~'׷Swgַ[7ɟ33N[?mo}?8ON{؃]`6k[~o_r/O/0ϫ_7x'? tϞn}3C>__.!d]ozο7aH~|s6tu\3vCx 7[rx泦K o>߬!=@7Y\7=ᥧL~Z?qQ?bV?ߞ>_jX!;׿|?:W=x#Cn3)m{+ |{mnx aSAяƃK|z}{-['>?ȇ(L׾Y8ǯ'?MΝ~o{D?tJ癭^[-|8% 2|'sϝ?0x-߿oJz.86NwIOϽͩmOjEB~7ɟߊ]3=a/K/)o;}|//M7p>xؿ)NA-y=t xwN_]K~{z>ө<\1=o8w$q"p2yz]x>??9S [ӋEsZK/~ŹIBoK,|[ knO<.<,XԿ9-nq ͮr?84}%\oA_s ~o g@?0@'FǛ?oekvo~REo{3p;yC/J7~u#xκ7qq.%ϤD${D?_"?*Dʺ 4?*Q/S?i3 aM)R(DlAq?’F|j7#r8~圬FK'a =ce,~geD#֗ćLo`(US:3t%4r(Pq'&?nZ͘8Wp׍Caz?vS(s AӆmMZj:3S]a>ʮ}&~X8Rn9N/crct 9^sMo{ۦ+R7|nwM}W@Qq|+ap>To<t/ty{'qm0:^9Νcӻ_>Ow w<oOڞ65<9;+|,߭ww:thz;߉@cOΞytO\?]/q>as(G*#wݦ~J{+?e]9}lYއ* mm;;Vw%t]{W@<=nӡ+7\qLq>qхsCW]fB[|/naw]x(a>Jyح/K.,?=o?/׾R셽?w~[ǵxh_އr>ϣbm[~핻͝-o}?|8sΙ=<Ϟ( 7H8+oG+揄@7~OW B`[`Q}@]GSZKʼ’]^%]?|?Խ ##sttڜ ߲]VXWWım7t C6z!q~DȒ? $L&"AwJgR????h=/WߵE=r -@dz9@)#/1{m=D8鋍Z_w]iF`_22TyO??:[进Nϓ?'nU98GOJ('EM7(+FWE@TڻcS6v*1%Y^))}y:_@y89N 癇w9/.$mp0䗼 wA}yxP.zvJ'@癇ru= (ڐPoR 'ay!s9HmHN0<]O6$[Tz wA}yOwfmWZ-h$L8\ɻ `"bۼnHybwHLE+??__3l~|͇><׿a+T/?*SnQ2wYQ=WκO/ѧi/onpd%l 4h~ [;6e6և=M/"B묎Q]-K?@H^˽b?,&Q S@hiA v_cS9 3aqbA3G~ȲwYY>H)B@;Rr8/F`P=aEOGWGW/ş :#c L[#bK:Ո5#ʿ n`BGS[oz`%l IIOş#-UBA@eC1(w@k@{ aѤ@.f1t)5Y)VAʽDa `D-Eԃ0^h6VI|Ǎ tPmi ZFY B^~w!hCU:a,!Kҿ0.C-#4cZ dddfVGtel a'cٿx\`l0YbY֏Fi]/KQq+nB^"a>$c_?+PŀrNʿUPEUwRU`d'tT4 )]+VAn*e_TPEߪ/Z՟<2 %՟=oeYo2 ~sƞ0'UH7+ i$,10i}_Ggr7ѼC%&;&???n 47"~. KL2wL??7o|ǿmuw w [AbĦ6a"QD6;/KdnR_n ?l>ľ7[@7~z>C1V\s؆ `B0 ?t ??S_LQ@T+W KZ6o?j&&T41ꯪp vϪ?1EUk~_'v|}V3ӈ*&~+2ψ*1WeUz,ch,# X\іYFT-+`asE[fQW¾?0抶2J}`meD^ +2ˈ*1WeUz,ch,# X\іYFT-+`asE[fQW¾?0抶2J}`meD^ +2ˈ*1WeUz,ch,# X\іYFT-+`asE[fQW¾?0抶2J}#xA<*y|,x~LAbގciEVLsi.!z! ᮈ6ojU8NW2!= O?2VhŒ/_?l#Oa3QCO?xR=&(ʿ#n! J(Pe>#T]_ʿ)RK"GWAύ=rʶ 2 1ʍ;\+ևL.E8 & CLaftKp2vb H:wKr6 (/u;FWYX$HR`?Iw9];r`/80,COF )M(PSYEJ,@ c;Ek8՟TB`S'?S3f#T}ʿ+Z4[oϵb[(T:,eA /+vRnaOno:o1Bvn3%$KW+ppl+GSKya]C\+-hCmppJ??J`Bz]Wsө'kuָ?B Mj~'d,_GmM%z]zюprc#K?KRS*P8VЂ(T"N/MC(f֭/?DO?q'DO՟TYPL]퍪o! ?5Teٌ$-M՟TRI'ZcUBÎ ٣0JQ NT$I.D%pks@%_l3]wLGh}ΰ&w_xI!#js4ٟu7>YOʋ7-*Mpt 戉_0`n  6~ZA\)2WmY`OkQFf2\&4M%h;Q^(RΓ]88CC(RK?` K4ْ gUUӶO?*t 4C R;(6Qa/ S&_ѳ*p{؃O 2"@kil,T>瘩 S$ ߥ&K:(#@kedFo$Xp!+zĈ?2F` {5ڡeV0qqm h>`@IDAT}_׌ mDؤq I k&'__ TCOQ_`Ԭ/<ꏪ1XԬꏪ?r/Ƹ꯬<3RYw/Ph֚td$}! aЙsJ!BB Uඑn1쩡 k%{EC頎';lr&V>v#?ڭ͓B̋YmH"m+i}v/K`1dd̗*@ɂ)@hQ~C&3+=CYĕ7ܫbqdPA1(RK/_ʿ,nRSoK,V'Q=2$EBwT;)??oL_Ee6D#"U"-R NDXj3e .|+?N!tS| 1h?i}_'#k_?+hUi_?K/E^QI7IyRn+rQGouïbghOI-beoߊ4ˠ#H>%̨_?*<~O\{٥DYl4hfƳÃy` zq0-;<ˡe4?TbP&4НFa<;<.)Ƞ(M5G p^ Cbh4ݑĀj&UZf2ؠ?˪5Xxuɀ +XUc8"TbNmflWӆ3ٵ At/κ-;Ȋί&*KϿ|{{7uOqLn KͣB ^lMm㏰f` SKZ_ ~Q*P5 -vFÄ1IW3Y Oş?=PT8_] ?r?(6LC?B3L$~ja/O?zx?pzpŗ :6  ق`J1߈j@F:!ȭ[ z6uB[P #m0g G;#n0xGT2` AvFnB-` dܺZQh9['9u ;Z/sNr3rjwD^ lhg-j@F:!ȭ[ z6uB[P #m0g G;#n0xGT2` AvFnB-` dܺZQh9['9u ;Z/sNr3rjwD^ lhg-j@F:!ȭ[ z6uB[P #m0g G;#n0xGT2` AvFnB-` dܺZQh9['9u ;Z/sN^xS/ҵvlhmpϣC-Ev3na$MOgŜe~dX.>쫧qL_ܬxRiccz?lf\RO(hvlf\RO(hr Y63.)sL'@U;Y63.)sL'@},9 Ū,9 ھr͌K bՎp͌K m_n9f%evjG8f%e/e32~BDX#e32~BDۗ[@βqIcz?]βqIcz?- g̸1P.Vg̸1Plf\RO(hvlf\RO(hr Y63.)sL'@U;Y63.)sL'@},9 Ū,9 ھr͌r>-# e, -;Vj%cΰLaH d9o?ᏘN?igggzϻ߳*w]O>yG>z>夬Wݹy=5 9_}~?GH^%<(AAȮ@*Q Pm³[PTZPD+VCczR/_}odtT/]/] _)DWy|ʿ_"2_ 4ҋƲ8%Հ)  $21eo:j@:0ђIZ 2E[Tj@V8H]ɭ aыy873m|VhuI }])tAz}{p͕#.?M#nutuO_[:_x}n'ot-na5W.{+o_/'Oc|VqwGb`׋3nZ?(PC K #7h?PAASHi?_ʿ)RBnzʿ1~`ʿ( ?=sK@mL3/_ʿ>=WGn8avt{Q~::G`#hsi}g:uF[Gh_UqsϿq_gfx}~!;ؙ(JZ+/ujss?{tgN]w/}6+_A*kKPK*UG_VrJmO?ΔJ?y[e꿪sꯪꯪό {`)ꏪ?VerWGO߶vv^ _68͘G!#0ȼ X7d D@N#J/8ch519; +uM`H $023֍6Y!#0ȼ X7d D@N#J/8ch519; +uM`H $023֍6Y!#0ȼ X7d D@N#J/8ch519; +uM`H $023֍6Y!#0ȼ X7d D@N#J/8ch519; +uM`H $023֍6Y!#0ȼ X7d D@N#J/8ch519; +uM`H $023֍6Y!#0ȼ X7d D@N#J/8ch519; +u%+|1 L.'f萫A/ss-Z+h >1}Z<R$ D?_Fjz>0vzԭꫯ.{+$W]@_٣M.u+~9{T;Ŀ=vp)Xʤq.C_*TSOş?=Y#5ڕH4wO i+pb[(PC (+(1BӋJHqOşP}W^I@7%(EM?VjXn]Hp2'~6 j<N˥åGnphIpе0?织Dp[4jnKmn-q!W{KYj<-jbmch| XnG;c1඾39ɘCBZyw/?ӇO7_ue_LMm3fnIJ]-~s YȞ7^ 'w:*WB ^ Cs?W˨ͣS߿u@g3/etIoOGOOM'jA'Hϴl܌O$0p 8JL e46{ kK0=/K&TP,{ wK0HJCWWWlB5 Ţ:'p0ړqsŐdw ڃL۔$/5S㜜Aÿz:M:U^!ݫjz\>-Gtt|/O{Bo1{fC+aȧO? _ʿY[A'Hyd=j~SQSOߪ?-nȲ(7d`/ _n6;Yrmb,.8+_CL׿U9Oȗvww ƛ3cXᴎ 8uodnvsԻXQN7O2k}n` TEU8p<,Cz7* 8uodAҿ-n*JEU8p<,(][ Tp2$ԽyYQPejL7} < l}&d"8{4؝<`ah_?riOCǯ}t[o:|{;5鶷7EGtI'CWM].|$*(C ~ "gH\<.M i_?D;TɣR"('`NM L@.1?3/ȁ&_GGVP(2qtRF@*T_h7_?*TS'cfr`2- EOn 2V؃O'h10pLA:bRX T֍1:ث$?u߰ҖBxn광g<]1ː"j0ddWS_`M^M]ne8})ۘ Z̪犹90xamowb+|w/3 |˷:]}!ӣ7>*/%W/jFE??z8ȱ*d)U@_k@Xh z[oʿ a\P5P>?ϰ?0?ۃOߴ_WkԼf⃨ R*žB߽V_ş. <E2yG/Y6ʿA)R/_POʿ};9](>U9nP3M)sHr\_CxF_W\:b $yCCx%pz%ؚwt=5Moۦn! >i:^2_OLx;~}7ma!'/'OG_)Exr? t mS[C/l[Z/ܔ N?O?ꏪ?he$̺h*fB (VM]CXޙN:)nl&x˹[<a3CkMŋ=ZdTd`9a<9|n1H"@:X΅& a=!3ݠLr$g(tt,!##+{!S&A8"|%][nX{ùG=&^ΔzS۳OdqF@/8{z}d35u9L{.O>d(>}xR?S= !'ŜQ"2o x_A'#`DGGC?)T"x.($T7hjKoT]B]# ]?LS_!e2QIϥ.iJee#nno8?%-6R;_@<ɛ@GobDN} Ā0Pﵶs 62 hnص"/B{qS"3ɲwlmKv4VЇ=b:3LCOynT'oO~cXӟ_r_ ?™[QK(S_?UPG/P=k("eTaTe55& տUSѯvAװL͋TQGUTQGUTQGU<G{}VZp&l t69*>D֎0-9~֎XKl7H 6Ik~ [;6?!$!0WlؔEbN0w ă'~H>?fM<3Nwy>6κYӅ^2y3M\ԧqlPfNǘt٫^ѾK?d!oZԔ?m+7DwD1nN+OÿQu6 ;GVYIngKl!"*eqyPZ f]z .O^?^7u&$<|_y7…-w>Ked` y G_*YTB+_cu-տ& ҋF՟T^Zp[;+V/?%o+2?n>Ă$(YZQQ %P)oPC$#C $<,>Tb҉?P* ˍ;fh@7|&Y|w~iig1S퓦}GӧwlMOͶ<>*PS_?36TA՟T<ƀ9꟪BT85{2ma'x8A\Vb…t?I7s} h1J6抶L4J}`meD^ +2ˈ*1WeUz,ch,# X\іYFT-+`asE[fQW¾?0抶2J}`meD^ +2ˈ*1WeUz,ch,# X\іYFT-+`asE[fQW¾?0抶2J}`meD^ +2ˈ*1WeUz,ch,# X\іYFT-+`a{>jZF? 8k}3Hގl./.2F&Ls,"{I֗ HXTݔuaVb >6w}>D䒣% R_J_h_08şJCO?Ks7ꏪ?"ꯞKPAW_ +mNJQuV9$ ꏪ?PU׎CԼX@rGh]bMrT4y$ @Kҿ=u.-Q #js4??>mgXD/}$9,'e~]?/xtHsW/BYɆl\dA\)2WmY`$ _ s3mxO`iHp(pۡCOş-]9q*Waq?1WezO"Qm[7}?ȽlL?) D׿ ࠚLz?M& :̚(C:Sa>daϵ|b0?Gh h(M2RQFh-UB>W(Y"@h}_;BOG4bfy@0?EP-0!I=A_aL3zDP۱Q`'֢w%(+`<^Q}h}_gƂ6nAddU!#COߊ(RqoTQI7-c[M]$^]虚mϪ?\m謹O:EV |rP>Ya{'G/2hbֵa[!T֗C7^E07}v'muedd= şR{E2t ~5Ia2b\ V#_<`˝5Wsv~y֗FMj(fByPKyM?)TFͪ?z`ɓO+Eͪ?#^oo3#(՟U7+&]aɣ$! MQ#v'T[ yWsXVPtf!tZj._6p](yGHd7lg'T[Ʊ9dhv _y##sρ.&6i yjV;V^31uGGqυϴ|Y.5˱R*Fo3M=X~PA՟tSu[7=4YW_UUr՟U>NχeobҍQZYiFh˙, oL1_Mv2'd U"m)r@?jU?JyqcfKFd1Y58\&8dP:(sρCM`kh߈gQ"~l ]45& ,ۤIǙzy'01Z_iʙŔ51$#COB?GytJOߪ?\vFgvzqsKtÐaA&@\h)9f2tf _NZ1UR@&=Oȇr؂lO/3 :sNB|¶%TJ 3؉9 Pa&li6$n$F'/Kdd-RUKo*KoT酣(?/?;R#YmP.v3BZ  ]PA?i\\lQ[fuqtIЧUKOOk;t^7ͬWxvx3T;AϘ#ew9FJ ăf34g 3e0tghAg`:2(J p#0?ϔtdP&4НFa<;tF7dŠ{COşi8y7OQᲁp4rHm.H?\??`(P~QGGHC4jcs ù>F?܀*Pq<賱]٣A_KaHcux;ZD*vCLfѕCWgyY0!.CJr_djS#ѩ7@|&$-acDKn>z0Z f@{Il*R99hȰ$/  qO?yr;ݠիL^j@ [.hVsbXsR ^gȢiUG?A?h(R[H1~^?TQI7T}TBnzDy|ۃOh+8"Y팚fߣ'>ζh*ӘJvs;*t4Co`*+kqg#8avC3װ˻»̷H*96}`P*/.:Z_iiaECO?<˲tTʿ #eT~PʿU4K՟TSQW_UUUWF TVYg՟YBo]CXJvX)i=4 ꯺謹e#h+r!'fh519; +uM`H $023֍6Y!#0ȼ X7d D@N#J/8ch519; +uM`H $023֍6Y!#0ȼ X7d D@N#J/8ch519; +uM`H $023֍6Y!#0ȼ X7d D@N#J/8ch519; +uM`H $023֍6Y!#0ȼ X7d D@N#J/8ch519; +uM`H $023֍6Y!#0ȼ X7d D@N#J/8ch519; +uM`H $023֍6Y!#0ȼ X7ZO[xyO='>#U10;,3'o(s(i}_'#+.UC zH]awX{Ww6?)R[FϾM.σ.Hp?_07 dN??<`kn 8_#^-rmbNlr/$ ~eE6? 6b1Cg q19@8)3_G!#{?t?SӭN;mzыsWRco}Ї=l?0Q[XWDY\1Z_WGGw.RC?(0 ?(PCH@1SaXrd }==㬧=%և4$لjEupOb.| &`|'###c6bQd(=SULj/ƸJj+NLۜ Gk#O'gq qNΠ%Ӄ]pc LJwwOܚ._zϒ;}6Sh,җtz_og ۬)axkw}瓧CO#?MSv+<4='&k(Y=wzԣ[/]K=%Lsk~\?ſxܯsg?7eS7 Hed`뉞ѢX>?%K?KWlA???]`W7!BvO;⿽LMC(Pvp߈ wGS ވ#:AUdH{$sc:AUdH{$և(6z wSPUdH{$QH][ Tp2$ԽyYQHԻ(UdH{$um1wSQ*ɐSIfDп/º[(=&7AYFqM;5yhb%Z~vg}^ Aafz}]Mh)&O/e1 /O{m_=O>*أ(M$Jڛ"tD?DQHo :(4!"%HKb@Wi)F @zyۻ48ݹ]g}?Xz?kom`BVVvQihu"Kh}]d~az&` DwA^hi ؃U17kN ,{B,eaʻgm[Gn_U@cc|/upEGj_R-?w3rO? _ |O_=`BŵgE':əҷ@gqH,*\hFw:$_ըVfKnq؋F 5,ժǟ5e&zЫvn]LZW[yW,GN۲à"ԾqԤISȩ(Jpܸ7 L-چzAg1.P#s.2f;ӤsϽ\!_a8ct5{GƎ_[<5APۺdbѭksj݊&?f(Ш.s=+^蔙3fY3E'/FWoT׶=-]wƒ';@@M mH}CM…wnbCVuҭu^O?&=I`*0joպ1hC#-9ٻ?H<9W./O}/_TUx/-s@]oZ֗|qwO/|>%)x*/GR)> @ɛ@_*j|+^CJ.dP|%78q3?'&?<`9vTOmboڼ&:$Tÿ)/_^OӦNVAldI4cQ h5}e=i̙M(ѱK/.PIU߹4u )yP743g|-y έY|sWdrX럤ٜ/?>?>`L&J17q=VI?p?H'rLR2L8UbqmyM{gۈ?D*-"E5M R\5RjUbqmyM{q͠Z|X\D[^0*e\3(8_%і4*Jq JWE5M R\5RjUbqmyM{q͠Z|X\D[^0*e\3(8_%і4*Jq JWE5M R\5RjUbqmyM{q͠Z|X\D[^0*e\3(8_%і4*Jq JWE5M R\5RjUbqmyM{q͠Z|X\D[^0*e\3(8_%і4*Jq JWE5M R\5RjUbqmyM{q͠Z|X\D[^0*e\3(8_%і4*Jq JW)C=2Y #t)Jk0‚8kekY`*!c^ɉO|.ߪ R+-'知{/|g׵G*5Կ_6ʏ_w?:ti=u$z8ħȿ3kݚ&2f TeNen-OT,-Z6mo {-]ltYW[G~N:{~'Dhz2&>‰Opⓞ,5xu,5O|kUsCA hyM^B-Cu_$y\0lq}?׿БқY{UϷ/C?$OnyɺL>#>_ߟ #xIlrj> gQ0'ea&yMG[r?V@`rOʔ @ 2~!Jt,qt-euuڥd1M^{M 5d5nҘ9. UsO7NxFw\ib'2pٴ*?n)Rm64g\?Mzx2_ֵ;n[>z-~_!vY͛7}UM4x {ѱ4j>k ymc('3<"+(}t0ui'=s=##-nۖ4udox5n $<}!}#ho$;➻ߗwNoioh:GH(V}̤ N&?}G\f{CMlB)X<4a']1v.[FƏC=4ù? ..;8 o>N%zkDy?;wfл7^{}({> >/H>a}pw1{ ;?' ͣo64M?ƎMf͎_6Fڹh~:K':Cm[b-裏>]?{?dpj8On9?Я }njM ,_̟OPKvڕ@-^LocLVq鰯} .wCw؁;Ї]hЁΟAKDVfC@= +.>O~o~}O}/_1?_:Jل???eoʺo?TTɉO+8. "t3#>4)B|Z5+HRgcB?8"FE@%j W??n`0V>>F!ѡ p.dٞ1ɸ>1]e}"5/IMboρO fO.>gn ]w@(x /Z?a~OkӺ ])"/%W=*~_-۶P$/m#:LOMZ3g.tpU We.C 90`ZB>F߷wO7A?V]][0@a+7 FO=0m>)`~^(ݻYRfL˜~Iq~:\O=ExI _V˖/+/_$^s=il)'*:3Peփ_{f|xhVsYg&̯ 'G֣=Fw_&$6 _tQ|u?*zh䙙/ iυ|N>Ḋ ϥ [&>XyBlHK.81~x7lԈp!>B_3Gr.a|Sk>-ĉOݣ;h-xK&MVgm\vX0i?{wӗ1<֙JiCD~)o7pj׮%Vx?|p؃?3?7ؐDtgF3V;A۶CG-^= ]QE]YW_?{w"Ū6?H0|O6j؜*soO0f9wQs/V?|)֢فH e?|O6$?ZW[.j/_^ ɰ!孨k_|I RUڬ~Bl)i/㖖G8F <ʦ K2kIZ}P|3=1RPjIZuP|OATKG;_*׿LO $ZG8F :&I#@>0A?x!":dÏ+/MiaL񌋗.ݺޟ+sϽ tO :d>VC;S3qZP'qwO<?#NNE|"?ZVOZZ`,#ϳ˘//iIVOl Ƒ@$TnRnDg؊}' írscʁTȴ(O '2C,]D=)Nx"=NtOP""ɮV0PcgyWtPc,wMmA_(9f4)y?Ah9> 4u@_[ah@;8U5b'O5ruAnХ_&?EiNdF 曫$lu=x1VXFᅦ0>?_JoԦm[91gh&,<.]PO4Oޞ~|Oc]v =/iĈ{b[l9r賆>7AzC?S.<M2M#l;馛۵4gl: OViMƩQl%#??sJsЦn*˸2X+ "jА@yPh"q$mgyg B#.Q(j;/_UvD5j39E clf|?)c3lB λQӉ%|zG q|῿4AO?!P{)6lGD&&r/?mg;`ro |RdK2 2K8ADE I-˟-;*N0q* T>qrļy-NiNwߙF}( O .I'h81mŖrR'hN̟{ G|  &ySDM#GHD3cDf8gwq9g~ϣ9XEMe8xյGb91ՙ:jۮEUG~H:q跿-NǹMks?ͷR];`[Pa-[Э|2~ @;MUCpCuh #@ps~{ Jx  OzSs>ĉO'\&2SO <,N9t?O2{]rɥRwNko׶5j~X?)MO[ӄ~'mdgz}0c:hFȺ]xzAE3~Q8݈Ok/'>]hoA=ͳ|P >Bb3:~x;o]`k[b%}y81_ q:?SgE۴jmnmRz =_*9}?'>P-DpVcڵ uE{F%X9g JU?Aq/<jԛ>XSOMÆJ;̏M7Lnq@&j cfУG#\T%+D`3\~9ꫂg9~?#jOQ4Q"7OtZrāO|J ?pPCܒeN=? vltD0fX߉|N8'Dw QG_kNz|j$NjР-Zz䛕!3g.N9.G~N`#\sWO̷CӛK./؇XC= N;DRԎRe 7~d9~Go͛k#P+ѿ9;Wh9{WA`ESf㴣SN< O FmhBݫL0+]z ħIogu_u bvoM|:\6m$, ʼnOY =@gǏvm7|PdVmi ;6č'B['\KwI}x3O?ޛ>^ڶm//OҮ_y<:|sS9Y&BǟH_<&Ͽ>F?I?n}F?b`qlߟtO?WÚ˗Ǡ'v1ƍS-n F`:obCwM?€@\i@ &|c럏?(۟8~Nv7Rn`Bh` RtU$~^ OZ`:lF meeh;PikT|H7G|;rz /#O.OMF!f̜ArJI:u瞋N\Ozc;]u\^dON BbD|Q]S^V4lņUx;n?yAre,K-i1]wI[!VmZӐ7 |zhC"n{]ڿqJP]:Zt uڭnFӮKpS=O =kr2k0@5ȣݗӿ}kt98 BtNy'6]Ҟ{|Y'Ӭ3Y$RVsY%Ev?+տzV-D!|(?[W5,3_ BLY@6NXAf?+n|ms'6|6_d"U** awK-5 +.roGPn?| lN}5E O4߰0K,{q`G%̨,Mɣ\&kZ[&QI.5-KV$ ֖I+yTK|@kҤ<*%`BfeiJ0!_3ڲ4i%Jr hmYG%L ,MZɣ\&kZ[&QI.5-KV$ ֖I+yTK|@kҤ<*%`BfeiJ0!_3ڲ4i%Jr hmYG%L ,MZɣ\&kZ[&QI.5-KV$ ֖I+yTK|@kҤ<*%`BfeiJ0!_3ڲ4i%Jr Ww'^ޙXXr:v3{rKu? bX߬Ys:oG/<*CM7L>A-ly*2nْxU,'xoәg.NoDߏL"L:q` _i$_Ћ祝u#NkN| urQvS-A-Zl%ذ؟_=K:eJN: :P2f.vIА"[nCC /@TUi-SHBk@'>&U'T'4 '>!)\|հaÅQ8jHdaљ3~7@/B:v谽<|Wʿf-QcTې]N7ܠ|h&]sotÍ~h7wyAV 6ӥ]/('>= 6Al_b'r1.p:-8(H=B?Kwnˊb ΟCә jg& >[eӇgCO -=zVħ=GdT<~himavga4ŶmnvD]v9>ceC-[ãh$ۃpg5) 7TO]949Ɵ15_eBYuz3Is򇮦D\--f4`9猇 2矜 %>dB(|2>T>k`@,2ju/K,@Q0lW_'<) a0unNLgtDqTC4)ӝiRPR'@2*hE)eGr&D^@f)p4')e@DIa#[0#NRʀ.AIF aJ9F]'@l-Ôr8I)%%O #Z)qRt JJF0 S!0$ >)`bkC`IJ%()|R2L)2KPR"0eR')e@DIa#[0#NRʀ.AIF aJ9F]'@l-Ôr8I)%%O #Z)qRt JJF0 S!0$ >)`bkC`IJ%()|R2L)2KPR"0eR')e@DIa#[0#NRʀ.AIF aJ9F]'@l-Ôr8I)%%O #@\SfE4.y&hX6i `5R,h]phaYBA#o~H,R]>|4g\W39P_t_>lj+ΡSO<> tdE@IDAT{/}~4p}{G3=}#F/l2S׾=-]#/o8}ԃ@l'WӮ:3ӋΛ/0W1_U[!ꠃo|"8![oe6޻ebcƎQ!aMUYST>זRk&Y3t2Wpz ^f4N3(~`&,_|z9tJ]4`M|k4º(~O]qe|Z|T gx4‹r||e|56hԈ&N@^tA|.o&tϽ> A?0.?OvĆ'?Fۻ͟?_6mE2jXۀ.ZK+ҿ1< 㔥)8muILWhB>31ʽ\ⴲ|+ |?GQ_=~8Fӱ3Oߟ.K^ve,)Ͽ5>!X/ |'^qii c>*??ɪ?*+1K 蟍Hhj;p¬%jV>N9?SR_} V_3 RB\sűS(.v;'l9AlB?|Sf _xa 6O_NTC)tUlZ|Ta=95pi .*Rj27RLS6J((ne[jҬLS6J(!>X=RljO=Hau_k;t^,L{ ڿZ077nBuZX[az|qZ[pY8VlK}Uc&Oz?GPӦMEzQ3?vwIo-[v\Cmi?MųN;B^w~n_k2&u74h#i7-yk + C~ wy}ȲhZڎ (G}Ÿ$+ )N8%Hє^']OS]?ݏ&Mh!D0E& A-ԟ? maczw鬳xտ=vߝ~ yKAߋ_?#TC^s5PRU/{7L-[n'o^ė4{.}mLjڿqrVweh{caזMZ Ϲw>M‰OE; ]}<N,7p87Wϒ K lيtG[eڵ {Cd \?)f4Gőnƌh萡cYfe?_5s]!0r]T* CA|pTRyRz<}q> eJ }]mQ_?J߾//IƓK~i{?(NW7 HDN"ZpDE`5f6wF$qs0̺WuOQϴi]4?'qc-TEYZbvJaQ@㏟>f2oUCS!H_XUQ_ 6M7?^&~b_?P~ijk ŋ跿WOdEו_О{}Y>?A@&4{)SH7@>0r$5hА-]F}Ekl5ڠ4pߖ? %|"Mu_{)kWnU];?m4:[Om%Qs׈_ƌ3Sq 48=%*\mU~Ae9a:,YSKx<8l~ķN5{rI(lɧ kjh4N{'y\_鬳|sGݶCp WXp& bo4{LUe/T?c>L `_{Uty`ulԮ]{as=KҼ?wC5ۄ<4'q;]?F׮J}=sqӠgrڋ8ٽ;}Q`5iN㫮;Sw xaЏɧБG Wпoi9hwGȑU Q6>e\@A5t=8P*~pJvѤ&nm؀F.˖TޢL' ɩrƿw>t5}teWЗ[w>b%Y3חIսܥ+uCaS]{i[GC db՝TOIVf M/cb'2fV-"/_Gn-pf#|a{ u_փ}-Og@|S)ϩ֝>Q0QHG?`?֢%OleZ,'j^CCa`{ lS %Nj$ g63Aᖌ}qϿoQG d@KsB u\{T!191*4R_)k2c\@莖|<_m=tIߢiӦ fmF_}/A,>ȣٳfqh98d>5n܄ZmG§ĨIߚC%TX߄.Em[ou|%ĉƛСC4(N(2e ,SbGΝA9o"0`v4fZn;WrSN]p:>}4|0DKJ;؟qҘ3ggcsGБ-X09Lm;U_G/<,=S>`؟-ZΥNv4ڟPF8n}Q#h?>]; ܠOߑGI't 8̟O{']Fր̙SNݦMK2&ɏ9FAS"; OH?{wɥ8!g}dM9g·]˷YfԿԡcGӳ_[>5_{ O3U:3j=%h)~@7 (+i/C可vMpY.IL1?1_ oXرV۵.ݺRWtTOg ir{! p9z,5Ɵa~x^U3;Av$ w.Ϭ=?gmh9FJou ͸geY.VX\XtGWew>j Sm/lt_'bXeI}|O_ŶT `2ſxo+<#ȊlP},a4:>+ІptY4S1^B?n}d ZW'|'7qZHq.;t $<6$ͧLZbZ.wXPDF;]ܓڵKRNn.38=bY9s^R.YB;.@. (8aÆگ2{N<͇s8v1Zl:>cxclIS;>il:hT8,U瀑iUn{^A@NtϞ3N>Qs)n-7Gdf qUx\{t֙gDl'Oa'רHwYr?mNUM2iOP|Z>ӚAfQ}<0cY3SNUk4O|"4$JYԤ^xyPf!N;x.s BnԫpO QVMEO ħO|15Ѓ;$BR[ݸp4yۡ1mNݺa`?z… h sħFG!6R}E?g)5g AHoB069Ht3fUx8']?įɿ[0p `|Ggf*r+)d݄`NkءC.•G_^CQ6?nq3ΰ{vӛ9X)>MG`ve$:s<*{p7Q?o8g5؃~S¸ͧa3m!ih4{Ɵg(?km?]JAkgwr%?+Wu/4>S_?*r/di&ޔ忿?|/_ן:ﯘrh<˥e)h-(+ Y&Ibr(d]ȤD0)lc6,(+ Y>@glȨv7)! T:,IIArl;t2|[/:y!E@= 0Q?.'}s?2RY^@W쫍 Ѯ}{Z`}4 Wά+W-[O:ۗ4+Cs?C'pB+F]L{l}Ff;{~qzW-誫-8%[E=wE?ӫwo;A4 cuߟX݈vhq8).?ۇ˯'S5t2gR>}h%$i;M7,1jC4f|!ԯ~TKksN";ࠃ4???ErZqN^ӛVUN9t:mLfͦ+wb's:b^t fiӡ8 f/tZ cs-)ѿF6hw%5W7)ӿ:я~rh =I9dv85wUR4p4e{V6hD4]v ?7S|iWƟŭ?p&o~Mwy>W}7uL.ټaiS{o4SOf|_|)}ǁz3QQ =yYܮ]mV=N{lu/^zꁧ;^ro<%t,a1t/^yJG_a?|9_?});.deox1J)*t"^6@o d*6S8T,A9J h럏 lѠUKPֆ/?!׿DiRT4®"SĻ۟ja=t9t^85pR DYא:lr&'v$7FS&ӆ8 A.!HC|8lɏ%ȟOihB8d4|L.E"gmَ^|yzO$Yǁ>ډ6lszwhzO@녎'_@|A]];iW<Дɓ7> A ۶ܖ6ٸ;vz'LܽvlŰTj$߳;?R{]?n"M|k"mZ_N~ڥcG1}S{tiǧ1=4A3Z|lMߟ d:y^>jʔGoH;#NZܺrlxRѥ*MӮR6uW_@}" Y_bmh]wM7c{~M`:Xf}.rK'a~)>l7>?\u`*Hbc?+?2f%d/?:4q/Y?;6fgaojEks3Ȱ>oIŠp|;37c6&+fa˖-ipO/Qi!//7U$轖eu]-H*hr/REd\" *HD./JB Faz_PTL$"-8O/C<>+!F&4d-QوJ`x&:gSs9[_ ?9S-]rMpw.?Qh 6:A,ۿ8i_G#?a^\!o_Z;89O8_?:ЯK^h% S?J=-ruom<_?n}4Na`m?.t|\vQ_:N_}_|ɿ//97Y9WJ.SDE1#™jοRxU092*н(XlSө\BEq_Ry`r:TV(Bw`U*OLNr QQ,6׿J婂TqwP_z|s!ň\&5$.aԓ/X(ZG-7ҬR:럏?X ~l*/5xjsQ6xBڿO>r?')Oyꩧۿ-*Bh_?2( w_wn1>>aA| ?yk-_^_+B=V؁5C>R.|B& RU$ &H2._$b][,4*]>@q 5&1̗_95jKЙTu"4۟T*2&1̗۟5?GqjS-~Q?p]ʬk@L IbMܸ4 I3bkR9jp.CHN0/)ΣV+"-{P^ __+2 *#Vs// :S $UJ\}rpe)J*`%P>grS92%ItF(W3|'͛l&XT;䎛? /jYNYzEH#V)㝿ʇ%w~۟wܑn F<xBiAf_?ro_K1?7v0vH/‚K&w|/ɸsgp-[nm4HT߾'qKvoӠjOa)Wmq$cl[+k(?&TV8̈>"aiy1Q?>ǎ|k}=z^xL*@HKP8)ԑ+:럏??b#ӛ`G!>N#"P`g9qFs]: g&)|i?>B|M|saBl_,\*;jBGl&)|iF}d{c,AILy6>B[O8Xb(`fs_B%JrKK7Bt?trgOO]&;WyiVVNV5D_*I,˸3YOǟ!吂R?0A_&R%(Ƨ0v贻X*f#VRdҤ"i5 zY dh̜?Rnp eU3®A<"px1n]P 72jG`P_BF_A=̤r̪ZrK_& %?u'L v[9#>G"p Ӫ?T(_ zx E7m?ld)0CewPW貢f &U*AU2+JI&<* iT Bq& hyTR#XMJh3FS-bK !&Q!gHK8Z`ŖC6)M@ͣBΐqL--lRFG!-5j[Z(٤46 9CZj1+PIimrԈcVli8d4<* iT Bq& hyTR#XMJh3FS-bK !&Q!gHK8Z`ŖC6)M@ͣBΐqL--lRFG!-5j[Z(٤46 9CZj1+PIimrԈcVli8d4<* iT Bq& hyTR#XMJh3FS-bK !&Q!gHK8Z`ŖC6)M@ͣBΐqL--lRFG!-5j[Z(٤46 9CZj1E:;ng-90|PsXV(*ό Hmzh0o+,T2?n:~gq?|k'_|.???࿿O+)7 &1l1 }}=zЁ/svm"[s_KIV1Y>BXZ7:aeI#dοTDUYRd`iU*ꂪ,)b| _U*ꂪ,)b| *wQuAU1Y>BX*QuAU1Y>BXZ뿊*K,!,uW*K,!,}FdƄ? q_ rYp1Kk+ArKuP {F-p]0xH~<}u'a rllXK, jA}ןl|oJ/O 饫' }|)|AġG-Y|.ղK-_'kh5)^ObXK ]5fM;ik4?˟'׿0>0\|<:ax|rU,,Wƿ*n_?>~NƑb^.sg9`!U_PyjٶYx8]m3w' > tʒTS2ҟR_d2_||_}_}_cϾϾ[?ֳWyBI_TW|?5˗8/LjjXOǔ Fy W3ZI "@8f"'.4AD\qD O\3Jki$5☉@$gHjr1Ü ql"đ6BHږhjl Mu%s.?nSϿjyt/?QcYXן#?(FJdqoQJdĶ?/ ~6ϔH ԕ< Pp̴"JxTa\~[w/r/W2GȉO& Nu& \UeZ*%n2?WWꬎ/M2QtI \idA*Lf\ùJl, ?f ùuC/ATۊNX*ʌ˰ ݥ7DPƁJ}coW_P!#`,1R2sc?>7q/?,~"_2.˜Hd}-←M' |||}?`}Yve+}} YpeJ*{HU k.+,Tc]s.?bRÐXWXP'tH _nMH CbQ\aaBE0Bt. deI n<Ns/G:J$q܂w}iuLef]Q$o#|-T7&_O_߼a| A[gdV(bL|F~ "o_H`` 7L~1^d%1Eclv?} ן/Q[RV,M=J2EjɗTNQ)\٦&U|IYKiiQ e#aJH-]1M$~tF-P)*#At4Cl e(‘ ZbH(\eDb?/lT‘ ZbHQe"PR8D@KWL?3qw{ ~z"gg9̉aDfHj9 Q @4EK-9럏??ny.S?aI6EN֍y EJ'O a{XYvoO v&ա5`T\).4qiiTu߾?|_}F_ ןj`OCЇEOT<*(#(ê'OrF+TeFS#% .WRϥ9lz( +В:*M>smBі)+si{>|"?b@j0X'8k __z?KJ%h 5w%r#i[6`؎*❿ǟ<ϙ>;, $߾,?}SOW5E????o?~AkUu ?ǓVTL#d3dꠔPN$%16oZE R<7-r 럏??% "V?>!CGizl-a'&8ZLO{!u[Z>2\A˶ .? qJ2Py?fw--hXǎϿ68p_ Α48 q}kNue ]i 'ןP`>|O_b0ן̋?0Gן )אabWađkN_x ?T?$ODu3f3fz4_%і4*Jq JWE5M R\5RjUbqmyM{q͠Z|X\D[^0*e\3(8_%і4*Jq JWE5M R\5RjUbqmyM{q͠Z|X\D[^0*e\3(8_%і4*Jq JWE5M R\5RjUbqmyM{q͠Z|X\D[^0*e\3(8_%і4*Jq JWE5M R\5RjUbqmyM{q͠Z|X\D[^0*e\3(8_%і4*Jq JWE5M R\5RjUbqmyM{q͠Z|X\D[^0*e\3(8_%і4*Jq JWE5M R\5RjUbqmyM{q͠Z|X;t-߬O}j{3]i-~ZԨMЄu%ʾ Q[e󇼰w㏷+o55aua L:wZޣ(YP ;XJQRYvE+lvU<5 t $=@NeVLIf3;La~M&mI;;O;;7;Ww___]lD=dSwvζc&mIq|*..rHW$Q JR K7M l}aQKFf?Llat  Re X$`t{Tg~e3sӿN6s?K{/+\O`ޠ@TO&w?xNyZ/ ~^|.wH/33c[0Oma/'xO_ܹ?:>Ȧ|*7vevH;vn?8{_~7~`./|cvn￶O |Nǣ;hKDPH1}q̒;·?2@J\`gDm_? 鉰M,T]`S\K q$Z<,^0^@ԟkhNLl1kVP[l`/Vٟf_;Fpn/b?(7( ;t/+[8`ߘ`?&vCvhXdG;g;g;m#w"pb{bK9+()))EWaq푛*HT58]IC4U$M7|K;3崅3'}hŏ ty~'4u&p?*Η/4U%Ŏ tye`ȉB*bG<2s|0KD!MCIj@]|9>q}K-Aaˆq &6e%f|q|qY6/&?`_[l?viԈG>OoZtfosmIw͙3nw ?>t;M2 v M;:o?[vy>wGp?þ\ole$\0*\Gq3r+[7>M'5`3Ss5+JxP@yZt }ar.Ϟ9A>Ч ͖kOIDDɟ0C9A*;HuZɧO٣5'M/do5@To*ݵ ' c3*½%{2`˦Ŋi͚b&??лMso6m.$X&NHƌk`Z?g_Zx :T7[_=ôv˿ ۷o?:Ĕy2ч ^ZU6vfʫ^v4﨣͚Qڵ<}5h`-[4ySN ȣ7;Wxa>a|tƛo{7t|DH;_yډE3{-e9`?AZT:Cm[lb`돝_AXsf YlMzyeO,K%~P6@IDATsx}&6L8>9ŭ͋.'<-2^ z 2֊i\pR@ZTGF?3NCu 'u uJMNuT`7ˇz*1.U 4]I5KtL! K,TG6lN0R&N<It;a Gp>;$%|7\#uWY~L=Cimk QǤ ?STeߠaCڥnTZU>^… A+/oIH>Stodk>C{oo/En՚Zi04it=CuԸqZf5nuB핽f`Ŋ+UL;#T{)M2Eϒ?pm 1}:GUW_-14bs"']J:ȣd0=п?Ŕ뮻w!uGBzGikN<{RlU,_|o:+zt3g?:x0ծSWdsλʫȣ0=؏yL2~g {I^b%uh{>.홪ߗ_R/V~'y&6L6e'Z??Xl_[t/ߤfeTɐߟ nf_?~%OaDZe<' OIR 1naCi{0%ˏ܊ܒ@*ůмp潲dQnEnI@N }ɟͿD)DPVd5"$ 'L1c'Q U"|@ͭ- ͥBħ:BDy--OEA@#S$ҙ>#S F.|%(ے{܉TZʗ;+ s#i0yh,|mq-\X^g2FűNJNԓO9i$>^W>Ywhƻњb:e+N_Ki.GW6 ku?08"oCkUW^IG 'PQe=RGi͇qlIm@#hyխ[:E x5͚5 N?m s]x=~y`+;x*yjת#TTDGq7?R̜42MsΡ۵(nU2Od>$Td>?&&6x4c :?1O_?_[m5/2Sƿ$n~Jlzkwh}!?9kO;+())) NO ?R.W4`zdFYIE0|VK4) $5^YW$@ [(cvL{KEE +kOG%~uסG|ZD;]"8b'TReZo,\kcCVڂsE!~gn~l(ժU[ݽ.G|{^u 5?e GE :r0v5W(ڟRGdr8S*0{X7t6鿿3%}zuS8+qw\*ڗQG(ڗQ/(ڗQ/(ڗQ/(ڗQ/(ڗQ/(ڗQ/(ڗQ/(ڗQ/(ڗQ/(ڗQ/(ڗQ/(ڗQ/(ڗQ/(ڗQ/(ڗQ/(ڗQ/(ڗQ/(ڗQ/(ڗQ/(ڗQ/(ڗQ/(ڗQ/(z`p|B-ϰ3(T ⫤^8#ѩk>_?2{-uKzb8^}ǡc?VJ˖}OoGfz|9:3@S/oelZKoe7O Y?k#GrЩL_WEï;">͙- 6р԰Q#Zz5iʯ}{hkN4|iS3jO͏g„TĎO~{<]p!u'MK/&_{Ce><>z+3g6urOGua=M9:G|"ǧw ÐOG ǧ">{sQGI޽z/s@*d?o ~WY?r&:Tdɗ?P>n3HB9?5o?fk$ݘ}{ )ѐ gߟu6KC1.A9OR甯e'-stxJ%yj—9 ?ͿdFyR=RIǍ)*-z5N9>%gvr,ʼnur|d\ a[q7tTPj)v>kϕp_=N$TjUZΎOoqxfd=~0f̘!4/ߞMhb2d(Uj+:c#Sw r=5Iz:5nܘn;Zh}9e 3 ?pk.{m[eiԯF$?w*U'fbΜ~^{њU?^xh8^?Qmʕ+GےhڔիK+Vd8d_*pN\J't2Tii'ѷs悢ӏYWz jwᅈ֐j֬AXE.:ƹpByﮈbsq.N5kԠYgg~Jcrף>p~T/}E/_Ɗ;;~ןw">طOϾ絪e6dz[x "1ǘԬIv:5`":y y_}1d=f5>h:éQp0qd 3V-+=l $4r.]&ώAb:1>+3*WZܗWL171G/YJG0fHZrezN;LګY3 KqR$[>cC=]Cy-u/ :);<{B_SO>A?AUsT81ݷ~}|ݮyh!p=;utءQ]v 'Bgsyw߃ׇ# Rڵh o:tDc=HVuE޻J8> =8 OpG͚M)7z}! go ~mbDNg%&,,")B*e6M ֟XOnB>`w_U2.2$%+bȔk믓m牭 \faٟf_< l))|`,v`RxMiaa4jx21F +Tp)1Fc7GԜPTFS.TXTT&ƈaE233A~ a&ISզiÊiW6nhS='U. NO 6 .# `8LMіs[s6 Q^Zb/g'vp|zM?c=U&I׍&׵t'ީW݈Ž$z\wҿణy#{Ϟ71羁h<>DEEB m[i˗K1^N͝3jשG񌉶*5kJ;oO>D>n;vǝTZ 4gs#gg{_@#:f8:rӍp,gpe֮Yqo.]D8YgKM@fB9z}Iש[nwToR;tb_cШ1^ 8xs|Z7z$[oՒ)ns*%|Byo4h 8=AQÆGߤ~w(Kz9z 蔗ȾX;lOs+߳ǥ^2zPq=_J>#͞xOtE+hMzit+"/U^>/ =0~_d~q/"/hB9+cԪU"d7ꫮK_ߣ}pD}^'$O\_9:+ǿ Die߿2+ztpkGJ87F1T;1ԭ{O`R~}833AaCGo>8 {A ы5^Ku#U=Cp }Kڱyls|bѻ!t8;>k ;I+,}vL>c5wR@|_ {Nu? /oiZ7g?;ogWbAk//^Nv7?M ;5H$f,ﯼj_>PDRTZˣW?6 =5,5,T׹?Z0?=< $o(G56l3C0KlzXe܏JCkLG|##˿uA/BW #!7:W@^0*b4oQ*<2ˎSURDxXAW~1ix~w?3Br>CjhWnѾD;wM/?i̿].N(Oۀ^-E1W`F*N,ieKRh*cL Op뷿 &]pux`'E.CvA_(#o9ϙTɞ a/_NCZ@sDbdvؼ~ t5z(=b{fN}L :寨=pB(~`  bǧFQr*JpercӻQdn4p ڹA̴i_Ys$Z^w5rhg*Lu@GA]i+hﱳY=ȼ{ hԘ1rT\RLO_$f aCCMV 3ypZF,QL+?mq:_Ja[j_fi?lyKdr9VpTxd17lI0x.snń_nOfl+?Y?x3ӫ 3S3ɽ=G-ɻ7sξ#QPR^RDU)BTs0P`p5I3Uײ:A2J7`_#[! fp" Jjrml\PzFs渌rtK9PJpJ&_c@|;QG=n=ZcY|?o>Mzէ}|oMm|vV^f7ˣ7z);>nVZjٶoIΝ+(O!:R*;#>#ax ]wbh~,\ UTzAu0*/N?^~E̛=>Cƍ7 ˻ӱ+T~MzZlImο@꾂A>l8Ekn-.mt# ۛGC02[{.AN:$b2ֿ|11Y=0W_K!+\v%};۠{ gcW^y籲qi]謳ϒ? '4OYr+bx x֭G}!G&Zt1F9f,t( v}>‚wMÁh5n*)R*`q)%ao }Ax +~R .ZD=/مϤ^,x8KsϖwR9(O?K'=Kٌ3j8s^.:ӾO3f|Nj&/SO<_ZGVkVvp[Z~ӀVZVNu]ґN=t+Q#GИѣ?S]+OL8RSŊ%:k؁r2e?爐/;?A5߹gż~Y}_7`1Q,<>mAc3Yr??lU$Mcfmi'M?yd7Wfˆ֛p2a+֒7l*'t!/44摩+Twl},+ <,sE+$UWjVS!fN&Ԭ39% *L4WYM~1c'UL|+^ f?'c+(?w k]gg/#]ߘ" h=r; /?XD|B 並רAUVs|†n?&wwW)b9͘>C ʇ\sh{M n)^F'p" ˖хpLpW)ŝ;yhcS}>!TNm*E-ϓ7nݺ܂k_R^׬3yZ8g tXa98wh G'<8mSK z/;@SvtgIu}=G6Ηщ'X)~f V[S6;n1 o6{eM7\G5 >sצ>j9p/+g}~% ]lu<ֵ04I">wMM4fmZKSOK:Bq?"2wcCVxݐwD8/*SFpjѪ:EAtTӜ97?ig[i1ύJ[o-vUp|6]V^xii7sLsA=7?_7xҟc]+_4+q|Z5&gfFtSDk\c]Γ_~9O5` Ԁ^4R1Ƕnov|'~"65D.wy;}AZFa崯k)D׮t}s,\~h䢋hɒ%?8pfC*8M-ws!N< OoN/_f3(tڒO_Qd,>얏kꫯÏh.fҥT125 &M7@AˑPo#=ft?c;\h!u;05EOZ9Lf"GD%SNGK:IÆ=N򊌿Έ4~. 0@ZziҎ{mǟ|R#?[qi5 OB%KЏC?Y-mim 4XovmI'LxO]Z|;$Do_Ԯzbǧ|Vk hA5򘾓߁j o|Ҩ=GX>THjevK#$u92/ 9&)wc'VjU8⮠qwͿ} >2Hi_Z+m]6أԠQ#DO> w~Ё !qa naJ_MzOq]9SEq|֯*-w܉{~ gQF,piB">/*GO#S ܳry veqeNјSΥ]d~M_rw26տC3zƚF??ɟ??8?g믭k/70z_3k !zSNp/o0X~ q>=B"U.;С]KΕ0ǰo;_ 3.Uq>M ǔp֟gf[﹟"oK $WsnƇR!HI6[?מ[icwo"gix7gu[plZy{cs?Ӿ2mץ˥tIv8O:QF cAg]Zu;o⪫G'?kЬ3iO^c_A "\sewM7//A0˜qЬ ]}ElJ}o|NN;LN_s=py{1P$0FCm5EW© D&#{?X7H0+TD91D&K͌enݒKs+яߍ_gt7cpO6h,bɵG Ƕrp|aλnL,)է.yO?3^Æ $m8VlL'j8vQ5vg+/=o#qDͣ.];{7jqqx ڶmON]"|1擿O_x҈Okֺ[#p_ 6^}eOn}GOo q8i(Dcїzk];4G;S@cƌT-;u!dCMelB9&W:-eӯXq+zV&M9nfϦ?}-?p_Ŭt\sc#h5K6l1U#?...Xj]yY{&dSֺKQ8[͸ ?2(7+D&ICl\ |d##eLg")JR@D cZR6LijƱ7ݏ leuUBT$49Tϛ&--czz.BZYu/BNdgxիWG@v\;q67Z͏SL{n.T7_ gN8AdKN6_䦬Ǩn"o'b"^z% 'XѼ9%]L5kl=s:qT)他g3`N׫W:C+G p"1rIS\zgJg̠+Oj݆Z3t#dJ릯? ʕ/G_|xG|~o{h&QZcRNz2?3 f_|%1}TaFzOo ;쉧Zh|E];D|:\ ~Xh;Ν=w"<+x8n=K!/3g/ig0?&/ldѱvAħS)u<\V׿|MM:txQHp >'+TDꅈO:D`W>|}9FC?-Խ;SD/{G|b,AgC5tG3ONjl=n',uLj2V~ ܝʟp>_!}4\()m6+a5kOq,[ԍӿ<6g}ko+D¡?[$1g devaeNJtc3cokF8[WX+$! x52=p` ud*mSnXl32JR26ȩL7 ` O%)JerTV0LrL2 rM+mA7LG,7o@QFa\Ji5kX S_`*YD[l [mM'tiY?ӨBŊTH-c._ QZ8^t|@0'+<ɟO].튈)']xQZdZ5k&oZ|`Hv(i~Ts:.{[o#=,oYϘ3{63.yz5̛ۧ6p&|I;X7glqy7'=P8Rѳ<#p;ӽ! 董h*tdp:Կ'|A%w]wGoNUTggzq~,m8TR%Z|9uh%찺oљ+YT7g2<`9)|rؓ|5c!RQyOyw?ڽp)j Sڷm+F7pamOqħOGp2*ڗC˔"E_?7*n-xх+{CtDW"rҙgE.`)=ĎYFB 7?N;7j(5G=Aws^6sM^tȡɰ||GBs٭">M޽hw#6vhDGcKw18L‹E 3?i G|?3ƪUI Χ.9WB8ֵ4+6Q}=Qx-< _\T_sq,z4;Y2Lxr26c?Ld/?uc,bo#7O?Jf* v\?OTA.1sKjQNEJǵ˨NQ]$%i%ITc )+.5FokC+n$g'%"|3˳֟XGP7ִ^^ 7qcqaL5ʇ|]`v3'S.MMhFGv}Mc|y{$"f[K/K^v@r(>4ioߥt'B:K.$6gw|)xI);︃>:HyU"fϢ럱c1WDZjJj{x{ԭKk zGérʴ;X F|g@t/S'm4Hbs1p|)&"}ҁL# y Ud(tRv).alۮÅtYg1'e9ij1g)_F z'/k=Q9x7kyԵk4`f>{Sy={ƈ.O9Ƿ]Iw~O|<"x׶ ; x:6ǟ|uԵ%ysD$Yg-[#'<pKǎptYa= 9Svmϧ+Wdۉqf =4[pZo\Lh`5j+Pֈk}?kE7_*ß`Ohb|E?Z=7z m(p_B{613ecSOܼ JqۢsIh5dG2ĝYx 3"#F[oo-2? MA7xl*nƆ4"8n1>C e1ݜ1g0V͸10k_[l5O?4?las ??Dsfs*8\=g t\Se'R9×w|嫑Q J _HJP<{Q J _&&" "#)AARFq(՞3|9>0ųI :T{e+&p|X gg;g3 t7l[ChB.سM8N¥\n#s1B N8*W*%r~(uhꗓ=]rSߥs{1'7Y)}7ib*ctI'JKeI$]H/hOvП5kWC|x>ZjA.'($]@t?$Vmi)|7.9`]D?t{"T#7Ws~lw{_ƌE#GbG8Q(VOp\@ӥq)t}Jܸ |I'K믽FC<&0jDsq˛}c_ a۳t֥g͜I+WOg+5^M_OJ>;~,]T*;~imnyޠxw1;>٦e[wD9c1vwg._"9S#8>c;ea.w]HeLe)e6 OtyN4oe@x?pգyTf/W 1Gi .DTUVJ?@VʋcSпᆛvmo#W|)3S8KJ0(1'ܐ鳾<;GyFt:}ҔATN$$Hcz˯D¥3OSj3ШΗ|85rOmx,{<,@ħΝ䁕wE{챇;f4#T*n]_ xXeһ d-9={_r7O{O޿?aɟ??x|sm9M^q3A`O>0*mf4?la/[OdB:e4{FʟK j F4?ӿKDY%ɲboxʔQ_[g}i !kߍf9)|:(aJiS+5}_>#Ϛ9-j܆b'ٚի^޼xgS9G.hvuwk}k1k$M1tJ' _ib6Ea)SwAmR!N rUPnwIF y衔"RSWPӦKi{QXǎ{9q'@IDATB>{!tZ2h5pFӛo{ MoDI!ƛnٛA1zԈvuO4f;E D|!Ex<^DG}4^@)8 rwDz^dI+瑧yC[~O4Gġ|Z"jU#ӻC?#\Y^CϞ5yit?^0%uw?D|ڝx$E<P7Ai M=t;qD +C޻_C?ɧ|R Sћ [YOØѣmdD#Fޗ<ܘZ+},4|40O/_Nڵ\9+ZW^=>*zH3‰!O3U,_. O7u,3 6UA‘HMv2^s|B'iתU2Dhr*= 5 Ï?@c0~8eըNDx;5F}*1Bma`kct[ֹ1]G&k~Mk@ t\dv5&" 60!3쿰.8f@=a_l? ٟfCRA$Cʜ2n |T#`w λj6$?$d:2?L3(}1mzɫalӿeLg4n)*,N2WI E+ۭTvi+S]l`Y>,VU;c Fv?˿L@gt0oSO,v#Rvmt~6)%FsAKkODwIDz/N8ލΙM1p|bƓy"kVKwP@ ўIpλ hKY~x뚫@@">w5zSc=uhDD|R;wgw52˗+Y@./gBprȡtM^B ٩| :~牧ļ"lBҿB1}//vBh8Qg%pN01jUҐ'9}ם6eʴ/gz_{DoSkTiMxBS0޷'?6j'5t>Ob: 3I q>qv?;:1i>;CF'vHF!;uRCm۵wY~\<.˾_NUW^O+\pw"y4pPR!Ay9;+pt G}J1텢?cJ}Lb,HҸ1Oܻo+?Y#SDׇ#>?`D]x/x(Gz ;>Me s5d/r*">-#xZ9h1}QP6 !T_]2ϴ>mu-7KWAX+td,O!, dcʿuYf? \6d1 }i_4dO[\m/3fb{Qfa_j4%KOgKl8WM?uYUC/gkvnN:az^~p|*2.9-4n jMZ D⦋|N 5U䐺 4SQm*nPSEjM3>F⦋|N 5U䐺 4SQm*nPSEjM3>F⦋|N 5U䐺 4SQm*nPSEjM3>F⦋|N 5U䐺 4SQm*nPSEjM3>F⦋|N 5U䐺 4SQm*nPSEjM3>F⦋|N 5U䐺 4SQm*nPSEjM3>F⦋|N 5U䐺 4SQm*nPSEjM3>F⦋|N 5U䐺 4SQm*nPSEjM3>F⦋|N 5U䐺 4SQm*nPSEjM3>F⦋|N 5U䐺 4SQm*nPSEjM3>F⦋|N 5U䐺 4SQm*nPSEjM3>F⦋|N 5U䐺 O!na;tw=a(]Of2F_wX>(g\| /ߟ+zo:8"Fpz'\tm7۴S.t'̿t^_QGۇ%&?|Կ";~TVg5ztzwM-|I7|^rO"ʹv! t]G{Np|o/-O]:uJ?5U]l[mgaom.yN2?>epDa٭^*~@~1}7>Zd1d7?SR`#$}6L;#]C{yֿ%u%㺗ggOC=F$ʼnsCMoA"Yo!X2iҏPtgNi>?{6 7?+&a6T7~QRRӿiagF?U1\L[l֟ye|nRIyi.?4Ӿ~ߟ&|D|b-c*]\ǰvgK|4i9sk%I>@ hC5)p(e#dK|4!9sk%I>@ hC5)p(e#dK|4!9sk%I>@ hC5)p(e#dK|4!9sk%I>@ hC5)p(e#dK|4!9sk%I>@ hC5)p(e#dK|4!9sk%I>@ hC5)p(e#dK|4!9sk%I>@ hC5)p(e#dK|4!9sk%I>@ hC5)p(e#dK|4!9sk%I>@ hC5)p(e#dK|4!9sk%I>@ hC5)p(e#dK|4!9sk%I>@ hC5)p(e#dK|4!9p|ʵ > R1]2Cl 7JApZ;0qzK%UR!lTJUT/%KS1">l] RשU,.ew8"YwKqK?ݻ/N{ BjJ io1ԓO9Kf{ю;nOudŔ/o9Ov#3f8BMfF줱N1'֢xN6iMiwX6=ܓ!ZOy48LNzqʢ_r@woH6Kj8q$x=_~[Nq$?tY" ?ްa#/NVh2-[^Z?0O~AeTKIϮU`dWҁw]J-%jS֩G{m6Z8&Oano̳V@T"ưN:$*WiC)/܍zu}]ZFRʴ^͠ҷxRvݸ]=:1yo.fF$1=of=+oq|IZ| LwBS@ "-//<5Q0s3CgJ:.uu= r B\Ǘ??a*q!=4C!i|1Y0?$w!5?Ÿ?ӕB` yq}^Fogos1N'D23ۜ[RJp[NڷYοO>:"J?#ؒ%kOIQP Χ5gwD5;:k/i<矎Sfc0Y$g?vm^C`J7ffaVֆ?7Ofe;bO ~`:<%~38z IYw^ēDmH-'Ka.]V8Zi6)Pڱ;chq ^ u\Fb?Ȅiʕa1Qkǯ+McWn6IB!&{YxºTyh&Nn94^p51.qR}ɟ?Q 6Osħ[6;}.FMlJ"w~X"ao=h"߸ѣi䈑[;"3r?b?vAva?vevivkv?:;MsWoߟL1c/ nM5k7ֿ%%r:]lK&ZSf'cJMCEi U2H#)4*B(H @9ON1UBAHULyrt5  @:dFΓSLi@UPR!4rb*]M"4SjP!Tu 'JWӀ C&i<9TTEi U2H#)4*B(H @9ON1UBAHULyrt5  @:dFΓSLi@UPR!4rb*]M"4SjP!Tu 'JWӀ C&i<9TTEi U2H#)4*B(H @9ON1UBAHULyrt5  @:dFΓSLi@UPR!4rb*]M"4SjP!Tu 'JWSFO.φ?;| KkQ,) LGԷx!>2<_bV&ǐ1KfE+peU;/ǧ[nY]%l1!O߾o{0.vfoΙPK.1.?b/L:yPfl۾F'bf]LjQfC2+ 7.-b"/PtKJM !c돭?&"̕82<0C/ȃ}`/ebĦDbims "*p9%Rؗ_UVkMge4qIFK}_nqKp3yTɟ_,Cb'=76L$3$RWL5Ozm~_%JT2.1K;fǨsn.]B{W |og b1Ic:ĆQcQr_v-6l߭Spcgŀ*\Gܟw73h-z.~J$[dݟ[(Ouԡ5kҴ+Wod@&ٟcg_mwvhH]ݑ{L<n<e/x`z_OXY&;2GeO0~?/[l?1?fk7|}Sb"#nT&ߟfǶj~/W,--y{1}֎rx @I6 E1j׎MJ1.Wvl ^Η@IVBx&;kQ®,4b8I!Wv}[.O(rkQ\0/.ᄓ ڵ(?-a^\ 'rkQ\[ü(N*j׎,$yqQ 'TծGq\7n/,|z3a_y.r֚S;WƟ,:#l2?yLK?`&`GbJ%jxdiqɚmf_%l)lqK08?lqbmmogo2)l vx~$$0P] 8(Acmyoq|OgoԄAr1ƽLd'\4DḢ|R[4#Ѳ[v?p ( V)笶ԡsq3?Li V!b'wM]W uL=k5u_I ݕ8}s 5TMl1k?i@fɟΘaPv`/v{bdߜYk???&;W;Wg/V3;g;w~_$}!?ǎ!ZU F́)|HG[( ,.3 1n]O) c2g'֤)E\ӿO3+VI?3/~q_?T?\'& &"8"b.!PYolHթ6\~V1?~)N0k?j]beuf1K'ٟffmնpGܞCn=$pKM, bՇle/L_u_ !j(;mo 0C̖0sxio;arw9>E:Y(M7 bͻ4&˕%T(8$Tg5P,WPM[tP-ּK{h@\YB5blMBuX. re N7 bͻ4&˕%T(8$Tg5P,WPM[tP-ּK{h@\YB5blMBuX. re N7 bͻ4&˕%T(8$Tg5P,WPM[tP-ּK{h@\YB5blMBuX. re N7 bͻ4&˕%T(8$Tg5P,WPM[tP-ּK{h@\YB5blMBuX. re ЋѤ4=b~ * Rg,(tz zRJ*L2uVLIf3;Lyc n35P,WPM[tPYybjbͻ4&˕%T(8$Tgkޥ=4X,@1&:X. re N7 ՙŚwi|M(+K&P-pI,ּK{h@\YB5blMBu\\^I\uϘzŭiõ*pB﫸Um+ԪtO0&2l֣JkMӿk[ fi]&?Oc~M&mI;;O;;7;Ww___]lD=dSwvζc&mI8>__Dz$+^FN%vr kߥm6({Tg3&60sReld,~0D:ց=3 f?D23sӿ;[nKs/ \O`ޠATO"&w?xN/ ~^|.wH/33c[0Oma/'xO_ܹ?:>Ȧ|*7vevH3vn?8}_~7~`./|cvn￷Ob1. 2`GwЖ"o>.Mc8 %.0%w70 +"~eY(qɟt\,A|l[ '/nծ?hb*_  ej^`D_%ѺaQ| -]Cowdg_[ff{MF"41?su;ΟM,FAQ|_17;C1G;&???3niv3 v&[AQQQ1.*F[> ЫIUCܕ4THSHҤmpQ.w3c]N[h0{҇P@@;_'|RHSǩj@]|L9QHSP>P@@;_&&(r(I]M\(vT /?DNT9&p;*Ηɟ 5c,I7?_=/q\b-X7G t?.-1{Ͳw|1|0;Lc/X0Om!eCv'mͧ2M|jvΩ ;R"rVivkvo????~LMN~H'>Q oj?xPS.Ny-i:q;-^F_&C9$ )x-og+xqK|AhЧ$"m`ʹ,>{VeKl>Z[ 5aG^)/șBZK?dgI0K|yμ4DD v=D|)_E;tfsƏ }Aa@|}&Bg?ab.-ؐlW34k߶AwS[vg,vi!H63&4]_f{yյ( #c돭?5#ZWm542;qɁX_0/? oo 1!x?q|rY7T8yGAQk *4%ɪ &6ԋMP%P&dUG6l˜6anE3%/N<3laze11*0?{'(3P+Kr?">%_Z\K=k \ &?rj`l@m3Yw\,OE@Ml 2Jm70"H?f9]]C?>Del3W ;`.__Vjᧅ?ۏɾ~GG;G?cN9`u%J jZ))icV,lsc89SXS-;1bX1?5c!6aÇ\r#z6L{1^TN4Um1ov0Poܸ݃P|V$AfЖ}ONppk# }]kWlEs7^NLlq/J[labefma/; kv`/~Mvdovh珬_%M;WH+ԢNt:rFcvhvV ;׭{\09_<rdHP3f\Zn=`&:{yfI2BQf56l3C0KlzXef5?~#>]5fu/7d7܈\qy n䠏Q ɒ}F_,3;yakǓ9'yr 0_O\)r1A%f41?2 JOo@Hapim?vp.f%l-|x,7O;;B71*90 0~ .ٟaDf3C a煬_B凞lhTD-EJL/$.B9 LA[[0KXc88]UHڟmC'1:A"i%r"쒥vF\ ܉Bso7'ʂu#u_^U[ُjT&]洛+Vlˮ?|??/_p߶?m-FV??}g|&gvXv&?9=?4Kbο;Y;l2fKe7ytYOYQdU(7U܂ ueoOhJj* o7Kͪ85_0Ds4?RZ%d͗2蕠hL0ӿY;ѿ5+x܍H@dFGC?ŬgWmBβ7C9*W"|rlg4s7)7l|~~H w6´#Ϣʕ+O캫s)mM̿]wݍm -^} !}mlْݫ6ee~/ZnE6kr5k& Hb@k/a?t qsv&԰Tj5*,,+iӾwA+W -+UD=Ik֠ ӺuiK/ҫ¤p%Lhj85;pИ lUo84c8`>׵moK'}J> r4. #+ͤ,GE\dwEiV]FAFOr0&.23S˅;M2 26l _}Ȝ[\d_g"LduQjf2LJó1"n8|(O\ 4DqK !Í)H ~OnDWnc1ΘS'M ֧T/he 'sc׎b@JLMYTDp_6mDVa^??IJ;zX*U֡)tU^cPR9u*Sban߲U+jڬrݻ_Nsfe_}p .+(S3A=D^4_|1zs8+ye]˳J{@Q>Kֈyj,5Jڙ 6#9_Xe`ߖ[y>kj_?feW/=1oCCmeOοjΈei?8>1b8yХᅻ|!5_k#G+-NҘf 9's]m7!J3Ja?,1j[mu="WG6Y4YW9i# [HWĭ]_Ss%&@gpRC*_"/9g%[ ½9k}p48`?}ykK58{gt?iӦ59ҩ3-??[뜐JҴӨwo8!Ekn=w/\?e5J7٫וS^ߪukD||ynCfh7?[,)S F!3S+5m{1r^hM57o>rjciw-slg82~/=1*m_Ig̜I_vejظ=~~oO>طD f?*ԣN:?^{s+D˟h&&6L_[lafWV?l{SLdmy9q_(" = 2Yo܀wt 煞uuI[Ǖ]-ЈQh Ƅ3s]_Ĕƒld2/">J$, Kq }p%VHnys].(lMUV*YMB XG2R4mTݫh񿲿Zbǧfbtڕ tB7蠃U+w< _^}ݥ|Нwһda! Ŏ˺ty t~/ZH:^7h`[j؊'Wa+1>Oɟ?VO~^lhO[K"f[ٿ+_9g9}9a@ lLb CP7ይ?;Pl=ưgaȾ.;_cf!nQ']e„6J5Ie[gUs>O fMRPcH Y\N~>&_Dqqz%*8KU믁7nl9#?}m׎C>S=kqT޾f:/g'1i~’ԴٹTN=iiY_k4h[j=}gOBr<󿥗>D|_ Dii֢~TrU/_A_yCۃ.^mގdRq*SSQ.s'QjNJ͛7xuS^u? \sI'7Hy+WsD<M}?_ ^8H:ij;QŊi2>#zw-\/Ŵw{ P$DBd 'Nr3>3s[{EǞp,dJ׮FЀrq5 >L s?Qsv؁*l GZx ?]0~]fO^Sii5/ҧ9d Ru!;V7LEĠӔkmS,5oقխOAM2Yԫ_7k!]ih}2lgEקW\iWF_|53E%K{?ۇnO?ۨO'3Ǖ݅E"tEC/]:o/g?#=%ˠA뮻AdywA?Ovwh{V1ks/ʟdkooǵlo:wyM7KcٿfD?ȗ urI:9ZFr<)#ۢ%D9E=0_x<$\qJX}ɟs?_pkRp|1 9i2NpHĚFe' 韔TIXt<;>E}[,t=1k"{_Yp p| =2?aC8>UUu8>`ߖ󿰰N;y׬^yI Go&Oƍ~7: ^ڼ矣CLӵt,qt_v 0.*SdXIO۶m*KCF˻Q!"kȄ_~=} N't ٳ' v*|ÍFh9xF@LI&?eDnԷ-P8|Ҹ1UsVJ<רA7x#3ţ㫀^~%&܆)gA8r_y=>Iv z7҈ѣgΘA=ztwCŠ6tp؄nD|btR4uK, (!OJ-[Qhw{'i zR_<_}H'k?Xadk8\G?[1/ѬY?lODb뿭f?f7opefCk,\ѕ80j@FpRy@;>x RH'R9×/ 2$y@OAd$%(=H'R9×ɟɟHJP<{)N6s/?LJ߹ 'XR_7l}fH)A@\){9IcD:+]w|`0O81Pl+|ReV,[N3gNseMA_}9>"~/&9˽KMJUo\Q5 r;L{챇8#߮-qI?(D߸RXf̘IsM;ժY ~TL/L1.Sסc'jܨ!!b qaǜ%u1|ߟ~BW$δ-"s|hXkE>ƒ[;W0%aOֿęc[lDawT|zXp;zQCJ(,AĮ%*]D*rkn N-a( rlCC _x^1yyꙧ4N h]D+.Bdjʰp#Lٲe˗# TcYVG~mS?qH+d#YK!Ci;i9{@ʚWL>(d9^w"Gt5>ވTƯ53uB ozec'enܹ4|*Wxգ]qeA$Knٻd~\hFӾAXOϷ&Iu'.9>vD Aϋ?SXhsiuq5SUsk9v\@gqVX9"[ AUļ>2Q#MEBGє^~۹RQ$:$\\[n+Oyis…tӍ7Pi ]p1p\]Ս*59o  0RruEHSH{Oܴ?Fp*1-;zwi*6'" GK/cmx[!9gMǟ|UBZ !Qo5; :i@c*|6I+{G#o\=g @ޤI  !NO>YX-gu&h}>vʕoߟ>#or]}5fΞI=*S$@?vj)c6絅3kֈjӤɹTD^ڙ̛h+ƈ)|: 2k7[nUv= 裏PI7z/!pD%KkR۶Ѻk'RJ¿K:\$N ڿLƛQ}  oue5 VSۡ?, Kg t<>Rn>0-{WA'vqE7S??#Ty{~'pp1G̚9K_F3蛩SWO8 nDz`^:Y}s~Vؾ=-X|)QOfR44)(APHN|]ڹ$oC@kvO^~!r@;7NCc@/vaO\k~ڴnM1Oka]tjďÅc6 1I2t26ˮtGÁpؐ'40I?+{1G/(fk/D t1t)H Dvs<^G[u=Dbpw1૯J=ЉhH^(J?s <&>x^|0s? YmlgLd5/_ ZwwsLsg`֭6E3%G |u?M @6p"d8Aбf8ހ9fgȆ׷*7bf֨؃?0/dӱȨJ3k$bxQA?:j%;'ЅD~l.FBe!Ǖzl[#I6@1s׀Dr2ȌS!9kM@_['c/֮h*^2SXy}I1"٭X -vxbذ!"TWZA*T3\ș=@wUR( 'Hp/Z }l^:lՊ8 '3zjt/3ȋkik̿>UPӦ}2ovk tΛ'"?pC1w1PO8Fo_9)J/bzWGG؁ySDX:^҉5j$8SҒߺm:OL48N&}掔I}a8}O|y:uH?( p2d(#\# :v"b&N C2ea-j|SO/0C[և#G~ڶiGTWyx!x]VMDRkϿQ5dIE$mmG+u/WlyЖO+NAJN;tjEhW@șsFeD?p &y8dlTEޢnrH}'Uf:W+p/Usso0J@ =3=݃Ne1QcRi[@e5A*~y)G|:C/p|^{-x].#bd|[I~9QwNGaq% D>{LT\vwwH5k9yk u=Tz 7Dt3k>ZӨ1<J @l3Y<)'Qg0+H?yu</=  X"6vΧTq1I\Wѡ'N]w5pB'&oIm'|)]$O=B=I1pʹ/E}zSУp'Ec\ҁzVA15;ѡGr>N+ w 5v \boUk1>50.WSO(︲gK_4hJDX!yA7'l8䏧Z2􏈅_ӿf;hoE6`p?eMnNrbo7Y߈~Z_uJ/X $fG?/-ƔA"BM 4 L*nPSEjM3}6@Mj!uZiFF"BM9B5ͨ٨67]sZ"Uh>F⦋|N 5U䐺 4gTtiRW՚fTlT.9-TC*Zӌjj#PqE>*rH]VkQQm*nPSEjM3}6@Mj!uZiFF"BM9B5ͨ٨67]sZ"Uh>F⦋|N 5U䐺 4gTtiRW՚fTlT.9-TC*Zӌjj#PqE>*rH]VkQQm*nPSEjM3}6@Mj!uZiFF"BM9B5ͨ٨67]sZ"Uh>F⦋|N 5U䐺 4gTtiRW՚fTlT.9-TC*^d1vKRׁyJumtv蓫vUW,"D/}=wDC? R@5#:k}'ip;_Gs:jr6>Юg(k]wd:۶jI?^-2|Y׮tq'bXh>~&;Ig6=4(("DO/>́g^_J:LD5Yr*dwۉ]wщkU#7"s $}3sx̜)C&t7^by|x_]"tC݃/ ygQԳ6K-/lͅ.s GMZh(c7z8D)IK--muiElxqD{)Xn[H-/=lٲ4|(!7ߤ$KU oA/ Ӝِ=~،K{:׿Y3g/}1WEwg\Uժ;HNF;Ћ ea/Cpp)S$M/m }'x" va'* QiwO<(?j4">E|_񷁳9g#*]ħ$>X7irg˺q'/_:h0qf׊K_,-yנ&^yl֜#X,6.U /bi>2?1d+~6qI oN8r7{">!> Z=MC"P%6Vf z5~l@I3Ϣv/~! ;#(? SF{a8|85gGP3~rw^lޔ֮[Ǩ'f͘E{ÆRY_~%]wմ p8O?7sLf(I{{M1ms kve_Ѹ oZ?fgfBKپ1?mfN1&_,s6)p(k2K|4!95%I>@ hE5)p(k2K|4!95%I>@ hE5)p(k2K|4!95%I>@ hE5)p(k2K|4!95%I>@ hE5)p(k2K|4!95%I>@ hE5)p(k2K|4!95%I>@ hE5)p(k2K|4!95%I>@ hE5)p(k2K|4!95%I>@ hE5)p(k2K|4!95%I>@ hE5)p(k2K|4!95%I>@ hE5)p(k2K|4!95%I>@ hE5)p(k2K|4!9qMm8>e`%Tg}%"е'|xRBA}tq%UR 8IF?zu?ծ-ZC|/@dO;ѳ/>'~K/Q$5Ed-ZS¯0ko+]tC6!g۶ET}%QJ!8 \_ޥ=׈?hDpw _ :GP8wxϝwޅ(5}!{`XH& 2\! 23f΢+_EBxZH+VHKv@bς;dAڿ px2ČF'v4yI"{Y98];LX.-=\oŴ:woER΁B Ww׃sÏ@^1+!s\đGQYW^FAM4;LAicOF ՉȜRWzCdʦ?)8>"ԴԻ'"%nOxN/IM$CNd3¹V3FJC=T螕/N't` D}\!s[8· Nq5@۴j>} BJ_/ygcǷhwŎQ@ZL]^N[Wy۴!_Bޥ2.IƘϤ|D|_o*{FyB7~m|J+TK{__u|b͜9]Yczan1=KX%o'=?.dOSХ|q)Sҟ; NEt B^΄ o+1}W-ڽ_F_ߞ4<9pVuϙhs.oKZ3c,2[f DXC~coo?[x&~_ῑ#p/UL_ N8A_"=z! ${OJ:PUі)0u7+W7ވ(>SPjا ~)tUuCq?Q3鄣 >B'^sp@)gGw!t iO^n\㞁3wߝHw vw1G+o?g== doGRs"z/<NuŽ΄ExIB#H弔~lVQ׶x!U?9pԪ bGZ\ܳG4<;}yΝ/(,[oъp?%Ka]l$\8r܏Q#GôrBuTT!WB< 1ʉiբ9Jܘƌ}ZtuETXgKq,|~tD+i_-ۄ?NF`_QF\NMMٿ,)[M1"ӿXUl 3l_bCWbe~B`xf1_7?s_hf$jSab'A.5k8ZiFmM@jG} 0b|HQ\n\V|ir4㲎(9y_a7˖F-Y7s9\tv{ӄKԜժT-[a3mS\J~;^|y;ȡh8?~޿&ӏ!2zN:e qQ3w?:S,u J7qwŧ;HGstr#Vn0;k&:=xXܯ?Soצ tyD|j$/q(9"/X^֩͟`M~!g 3O?oC# cQw)W?0:THΗvN?cdT̓cE׮֟U>sk7w]օ:g-#8S٧ÇII8'p}ݤֿqUeQ';Z# ; ǎMWǏG.AoK쳏oE?\TlDnzDr_x'>zQk<[.˳;ǧ$[">%bvծ7 螻;_SNiL;^"СϢspn:eag+9WkDRHe邈O2wsTN](f 58`?9k81Df-%e:~<6_TT*:ŹMs_! iܹskD G y _G *GFĮҴl2_qEW8Ab:󬳨 8rlAK1W?C YDY>dA ' MD1O @:dFΑSLi@UPR!4rb*]M"4sSjP!Tu #JWӀ C&i9TTEi U2H#)4*B(H @9GN1UBAHUL9rt5  @:dFΑSLi@UPR!4rb*]M"4sSjP!Tu #JWӀ C&i9TTEi U2H#)4*B(H @9GN1UBAHUL9rt5  @:dFΑSLi@UPR!4rb*]M"4sSjP!Tu #JWӀ C&i9TTEi U2H#)4*B(H @9GN1 p R_G9SB1gXⳁ4@0}Qy~ G*?j94acf Dqw|۰ѩ*?񯽂󜭏%J3<6nH;"B_<vfi8"2\@`1Kfexpr_vU- |}tnÏ3慈fb ?4x(:Loh:/JƍBtqP˻ϝ;"o׏>B⮔T䐿KwzB+džߺyԴɹB/Ygm6.ۛUСO=A["DF{g+WG{B(%-7M?ĕкu+"vi Jqᤉ%+G]w͙3סc'8a-}?8qWXY΢nbD[chs,Wl/"9W.#%Si>}:q򥀞m[""<-/:{H,~ QWJ_*GnSq0,D{j0n>RC=DuG G'`嬃*Uet5@}ƍBu .9f 4c#<;;@C#O-i8L{ラz{p Q8Zq6vjynt7^nyw S }6{3ݴo0/Ka^ʕ1ē@S+ c^f26;<98ؿҥKSC }mϧƧ`=T#AA!.]R裔VYK8htp }Կ__Oe_~kUpXk֔fÏ"[5-p]S|7gP-@gC3 㝃??'3|goc믝?^fE:/ ?vpfuiw"q%y㲑n5/0H'O7G6۫3ٟrqvϪH7~DX1XΜw9_UMO6;ih2o73{r'sI l钒ͯթ2?LdO%np@16:rҵ.UfwozۙO6TkQf*։ _+C .GGG@yh/x\ğ˺?&F<)#s$ϱtI t0 >5ucOM:ywA6_*-Q?1a&2{ep7l(b-toy.*}k@7 (?SEk/RlLTXxIO [H;v ׫G7/̙C.,K.Mk֬vW1uؙ5:t;>}BC{ݏ?S(/LpLf^?ש[G'P6 O#{.(, J!/*3QkZG`g_Da D&0TPEK`J|~>RJezNS\hBء#sǝ&=t4[?@.LJ VC%)"q(,I:ǧ\5{9}xa: pyXp]‘ВUt}з]81RJu-Y5%wKh8)¶IA#";jԞl`rp*_<sC[ #El8sUc@2x0yY.nڣWb{ Jȑ*+C>&mDR??1k돭*䰿7ub:+?Ŝ?3_myOulcآi,Nt%<;p!I+z@pij 6]HV00猾X1di VF^`a_ӿbiTn2Žs6jk!  | $.0sZ_.M|0>yeYY)Dx~ЮV3cٴ{DAmJh Z|Pګ/#dϦ8+{xh='m^khҤ4 ѝ-ZgK"]`7ɌzolQJc>LѡpFG$z^\IK2;Heʔ~~-w|l.zCp$7m pO{e"Bva;eTTXߛ8cU@^G:y Ǡ!٦5nܘN; Z*ꢎ\u9>X\ݦ5jA壀V\A>Cuȹ~[N]5L">=h @T!˖/E_5Ïs5]vۍMQ߰#hڴohW_ȼLgy6ۼy^@IDATc":. gF |^z5A9f)g;t=v &Aթ[Gk醿\G_=Ja:DwAġ*)~ eiTOO3 [@}N(cϽp $ uLjnݨNDs_?sLKd$ۀO9]t_p|jO` G0Q:F1rәgM8%\5ֿ75YL/o)wE@t) {ep }pGy]esƶitzJ_L͏۱?lSF-?Шe=u0 ]G۪uk:sѪ<ѐBwsU#G]vV,oİa, L߈W@ ~_DO~{9?j]1*㷳-2=61yߐlo?,8+)& ;&L<$bK~4O?Z͈#}KA4ϩ\Llhpvv8ILlhpғBv8X-P qQ  d&%ـp@0N@6`/[.P b8 n'  "-% (qQ  d?/l(B\qXaH@I6J\!v8W{x}OTYQ 6>ϛj0wժqDJȾO򍸡\F?~H53iCE9λ!=Ђ O2e Ɓ4N& ̳(f% e# w.|Zg?y]YJ* p{sxz^Rgow+焒#hJqi92O۔-#tu+Ʌ4 ̛Lĩ3?UNaFӅx*#@~MG ?Ec'88NR!W.uLy<./c+[l9q88ss^;N{O(+OS:8v,x~|wԩ#"']l#>+dyxGו=h̙1cW OS*SsjɍH#쬇CjiDbus3!}\Se|i==+/SNO-Z+NhKfTx'|!;і*SZN5@_ȮF{Olկ_?] G\ךWS)?sL˳06᪋NqΪ%YJBbUu_:q2NMxc<}V.0͙*ԯhx7GYgOk85]ss|b$姰ν^={Ќ3}Wt5A'?ąY^|hI֯}@?LSO3_JL >#q_?kK2/] }T i*aix;ā7sǟxC.6~̵d҄ `qOoYsF?b7]}3L7go7[lt[mx-q|#/w@weҒx\Mm8ߋ ,pr'O2Lsqw&6l4D+ ?!dmJN:?lÎO5[_l~ɤȪJ˧bv\Se%,<CxW܂a Bf9K~5&UWWKGG+WB9_?cZj)'KG[& XuQ".<xp~r*DBm%b,'p""Fh}uzᇂ4CU\ - 7[Ŧ S_ N*={{oE / /P2c'Dj.}lEEmEDшp@?2mr濣Iso- :I /Gj@<ڄ0V>gPJvh\C8[zrx K+TtN{'-ƤQ7Ik{eW+C]d5֐wYZf9i7(|,lr-e=f#T7x]rqiW_%IGX]vyM7,+i?N:#h,P/9'-F$67F9'2g_h㍱AoFG. WUOxx2'Q- 't, ;)`r]ww}d3lr;vqދxA73J_|"Q 3'tqc?A֟_+_mvkoq>믿.Gv~}Ulņ<՛gy8,l{__ ;q矞ȑӟg??plޕ?>r?o?pj\pOᯯ?\qOm> BLOOOOZ6>#umT~YĀXP$R+yv4J H­JmpL_Ɂ /b,%sL/07uGH>G;!u4iW`>$VϊUz:J#N7S|ܳ #_[lQYa>"6iP %\B!3ZF8if_[߾}eN_ Ho+qsVsg1*`d NHғjMO黜,k&թo =r'Iz+M*q8q<:Ӂ(_yV ?@|))_le%!{= {@Tfo>_6e+ \ om?~B|HݭD_k?5T6?-ܲ" |x]^}ٶwĉ7 -/o<vӗ֞_dA[-O NTbTk/XtKDOo $'A^}e/,C(O>?;}w~CV[C>#+gE{tbق 5Z^ Ee_ڟ-Sk ދ.&bccpZL%pb7ZKF<8' bgvRcu.r)??Uj!1= tu_b-?>Ql`a+؂`E~U8G/_tEb` o_u! O[!m|nИmb%չ.]lS>cPEBVXE{>=Ti N2[)=sqE2赀 *! ʩ .WIUCSNpES\hχ4**^ (6\%Wўi~OU8UPNmpJ*=p+z-rT\E{>=UTWZ@9*|H{赀rjURqTS\k*! ʩ .WIUCSNpES\hχ4**^ (6\%Wўi~OU8UPNmpJ*=p+z-rT\E{>=UTWZ@9*|H{赀rjURqTS\k*! ʩ .WIUCSNpES\hχ4**^ (6\%e=>uD /IүZf9Q_0V+bE!FSlfq+HL[r=< s'xb\Tt =sҵt FrgnMe}n3 Y%?ڿiO> >+8@fƟbY}rGk㏶񩩩Y:cC  `vʌWF/XZo~ q)e{VFfNT_AӨlQ Ȧtl{VF f?L*sMˀ,y )98\!쨻V&`XAlT:!T&U*w}ӍqޣT8u}}͋hA%eO7ﭷtn|:aFOwEqZ~Vnx|GZd;iA_i^?0q0ƿ,L/?wO?30_a5*~}̘r @q,]LqJ".˗f0LhlV P8LDS!??Կ\7V'_e0|] I:a>҅*_\RZda$~V3Td%//{ӉO\^PAd\x/e eWfnۭiC2FqIGj2_2i?1 B/?kQ}5K/B $ kzM[,^3*[KE4_e1pͳiED B^zyXh8!K h2!w>/䐧S= NgC^zBN9T$/Op:Cz׋@+!OCEJ'3!w(BN9T$/Op:Cz׋@k<޷H`ۆ%}9bVF-RX+hNK[+ְÅIwG3ߛoM:tlgzFF8\ۣo~b}l2i&#=DOth/O_e;H:G.b2O?i#~f v>I6\xe"@(^A3(.nU|ݼ#cZNNbdSLb | S7 o<[6_yz'U|ݼ#cZN9{OQ$ p!i_7ȘosROI^vj,zCYy~MH%m&:'lpQPrK`:+b'rZ?T<ܶEmM/oP0.#M7o6 ÊW!23.h`_ImKե?愆y&0(;?Pm@'YF 3ΌKWxڪsIeGF8O*eW`[lSP (,n694A(ue4a$"v O22O8C t9]?!C/ Iq/x`E ՗AUT?0| /0KU3S ,dƟT3ŽLƟ,0?m|jԐc[H?ԁlpX_n/bf<8;1:A? /8kI* *D|-$O TNj>U-$of{K#NymiWƨ^zC&G۬~ )B)] #&$Gdҕp-lT-ci~w#oՌv)CdF02kvCy //ZT{_T7Lch'ly%7Db7h%mz .Uj8BxR)J?z^l/?/ S Qd2ިp"A+. uWZe5[e4.6`WMj%ZUtҫ/mp)`5c`OR51AW?\iR].ڟ Τ+~fƟc`#3|`Vuό`߿ ߿ t~=.*2*e`$m{myTFe z[fQY.3ޖY+eTmiJ20#omyRFe z[fQY.3ޖY+eTmiJ20#omyRFe z[fQY.3ޖY+eTmiJ20#omyRFe z[fQY.3ޖY+eTmiJ20#omyRFe z[fQY.3ޖY+eTmiJ20#omyRFe z[fQY.3ޖY+eTUpR5YݕؠTj!./2T'5fd[Ѻ -y[A1ȑ?xhhNgDDڂҜ5 Y1 %? /C\44?ڟ3Q:Wa]z!??-I% '_pw&I'O?bATUX^H'f~lr]C7/_6>u5AY& U-07z)ob%cN@MnkW/AYg L@ekNiʘ$n6v[NuPVb0 ``OY UJAQKƜ&lW_Ƨ"fhAt\ߵ|W2+.=%GXkhRߊ nJY{m/`-M'Ճ?A{ԦԿ\p*_3X%f O?iiz'bMS?(j /D"N `'  ㏌?2u7c-Gdž-Rn&ye{ӗ" B>E02=jӜ".O9Pp`CΧz "r??0rk4az ƒF&xA}G\j52-%;!P*\#[BfȢ9囮 OХԿ*pXk=)'oѱDA'\`%.B'dQ5㯌2|I_T`WH㯌B-2:1؊uf9xaGL㯌+|\,`[\"P (VYRm]2K,IT(JrO'gi-g)Mpqq3Ò4K8|O,I3nT]Ofd7I5xb]&ʿVd(AF AJZ?jHq͸?ұіξ֏M 7*;_TDXxK]?hTc0iGF#٬P1?u͠@;`%ąҒ x O:Ԇb`CT5I;2¸AӤ#??3K`AG?ܖDX퇈C C IW+@ +˧Td5T UіO S!W?ο4RPrQ㨸|*TC_.G?*jo0ulnQ K#RED4܂) { ?Կ?hT7_?/?1#1eQcw0(;=dHugg=י|||[A?IE\2:_qS^˿l5.m'((Iw6h\V K*QXYO密?οV35%/Lz%)PYOO ?JZ%̗0?`eӢn(AN%KE Znj.s+RG`?/dAWd?/?h]P{:o'^ł Ц1 `ijd%}O?1O?1T'o?2XG50h$㏌@ ό?{#GpڼEYwZOk*J֪NAbf..w֔U,0aL kc>/\xZSVAT??ԿY h~eֱ qS[>^c\Z| _yv@;ᮭxm"?OFu뤈 :S5PQrAO[5iEjf <1㏌`V3㏌?2s!\!eU#jA1i 4ƚ;xG`MkZx`vO*R5NZ:(G"MC(RK#b?,E?\iIGJI_/?1=FPn DkF=3M-f* A:S[]MG tptFW?IxܢWpF_QYK5 vR<bRы>DH%I+sR}E |0%I+sR}E |0%I+sR}E |0%I+sR}5JԜ=ŵQF7+4h[F3 Q4F"n$UX Bcw(#*1?Կ\1?` 6S2/_7X C0O?1O8d)X̌ Jx/+( K/02/M.ޕ$j$Ū^ExlnAX4')"rQCk5g4+V+ZQO|RYpko zzG@iu'\aZwEO&87r;OgO玝gϞGA3ϺS54D}Z?G6&qe3=}_3_ BcQR8AC/A\ibGh 1s soVxԼpz&?hz1X^N hl l Iaa8i؜AYݞb㓩f{Bt;-Kׇ+FR,$" ,7ͲpqQ`~ԟ"+[J S3(u?\ _GLN"';Y ũڬ?uZ6ѡ/l͵בZd?7^ih ^fee|Y^oMMM{SO?)S|f /H+^ |+'ceJ^?οEt,y?WEۡCbRz/[4nL>u]iZ;x!ۮK,!:vϦ~&G+/\^92kGI .:s|kcǎ'__x"\+_ANIua'% DYMvmwYcұS'쳩8&ɐDj216P8x,?raL.߬ǺS*ok<_aRPt+H?h!p\}e0TD{?p(Hyj6aTbb4?h]15B$.q Qd'ØXcˬGdq$ޢZ5 _?¤KW%!\QQ" __ E'6> =]EY9Ӽ=Md%D@-bΑ:qJC{Z)٬49Gz) ^i8f t2*4xJ3i˨sNPŞVc6+@-bΑ:qJC{Z)٬49Gz) ^i8f t2*4xJ3i˨sNPŞVc6+@-bΑ:qJC{Z)٬49Gz) ^i8f t2*4xJ3i˨sNPŞVc6+@-bΑ:qJC{Z)٬49Gz) ^i8f t2*4xJ3i˨sNPŞVc6+@-bΑ:qJC{Z)٬49Gz) ^i8f t2*4xJ3i˨sNPŞVc6+@-bΑ:qJC{Z)٬49Gz) ^i8f t2*4ħIF;Qh4WCact[l@Qd@]뵠M-nؿ{Xt GQ矮/-' O7䗞t=wʤIoԩ3~jVoi:ܯvy6X1c hѳ&y|jEر-ӦNkyҀSUĈOgy;4+,lWԋ/ʱcϯyϟ:ן+Zz-Mq= |Ě0 :k=}+\zS࿾qgG7C9diIő/&?ܯɿI3OOR\Tq3_ ` MyK<1UT JJ/_\i@W`/5h1?'pW4? #~д<*N| m0|)Qzũ\ZjE>AxZm4 kK" AxWI넵%ULOV;uڒ*'O` i) rjY>NX[R9i_ $֖T1E>AxZ4 kK" .~2on?;l&6>1ɗ58(YgoDyᅑ2jԋ8bW䙧#NT=oFaFw>c'k Y} 4]vqG6mj&)Gy :zM0A?cfl2HG.2W5L͜]vl?D|.=zUW_2GP?أS5H֏]vIN 'y14e'1VqLP{Ø^qƧ١n;Yd䚫#q[~yو7bSRxmJo~{VS=\a@<\Y__(w.oFCFi>]o?QA\rI_Z})c6'ݻK`ImE rء'˅w=~OǤAzrsϖ~SU!7c[`dD ct1ebcr>DodɎ?:]#) .K?fq#5'/E;ʭ7C?lBx3şt/\HO@73whMБi?3)y`1R-®^I?k/&fpcIi4} |_?o>c=kXs5(_c8 )R RꟸPRrU*߯Xi!XZ:.S^a]ҏ ! p[l94TgSHh/ۛn.ݺI&ʽw9xͤg6aja{?dbz0XV]u,&qk&wN*p\6gec啗Fm݌?Zќ~C˥s.ƛz+,|?T2wAze?u^z)>L?|[ZK/47‹/,:h3|I_}5ҽ=Ͳ#6(M: t- ɯtjO'jM7[G3<Þ_K;HYgo&s:cV͓_(K-7z2hЪ9C76>&W]s3TV bL_ß1&@IDAT{b7;GG7]u8hGWCYng6|~8irsSQSS3;w8GhG?~&WپNWjϐIgtsJϳi`Yw}{1c {-/d(MMMF[nΝ:ɔ)Sp06>L ƿ4X- -rJFϟ\zUa[}^˫sI'58=R,-gut2y"8k Ni ;WƤzo}͆i#;LN?Lvqt mnjѝ>^vlm( ~y; ;֯FƦ8?^_[`eN<$4d5[[> yll[~E9~Gs.>h( T\*xUP/n||->876::\'2pUl|ua֛ofΝuLnF61QigyI'@ ' f_7=(66 LVĥ{~S[C/tN|\AwXuBD϶'\_[j\zA4_ terZ|8Rцfɶ+?@PѷcA!J`R\MDoŬHs%E;?Jv-m?8I5\+pW֌-p3*"M Cdբon"둀r{&Q 8pQ)Mf#\Z#j૝j3NVՍ J,jC)JE6[(&c/l96>&kYNLƏ/ypK-;e= w+Zhe72O8AP抎d1t&%IN psLl 2Oks1e}=۠0NZyU"x ; r1 4Nyd2.S{VN:D+pҍB?$pӛoS>IFK~K뮻Ȥ Jg6C?pӎt.~~˰Cw_ q2LҫL%kɟ%4=,92Ƨ7uS|~=! i?Ębo2lk4߭=v c2Ξsϗ-g4aLtLT&'O$]ȋ:&SB2L@ 6_2/F+\_`:COඩmsUY6)*i`첿1__?ܨN4C e __?h?"#tE'oPtI_w6u>/tDoؓ˹чc8!e:6F8.G ]~+TÏknrݍ77&/{+6lQvi'cBxi]em9pJۘ\d|מu\s-9co'j]}ue.ˣd<1ȑܗ\z,"8HG8J(ޱ-8Lr_h9 ls|]lܬpɞ{JϞK|R@(X.4-pJtI#NUW$ӦOv6˝tpOkaLƘ4&;_/tWF,ƍnC7/&&e]. /SmY{}\ϯ9@Є=VigV?c˟~yC+]+_@PP2BG[????]G? '_bK 1A2O;ha3&9Pn@zل\0o`?33o &$ߋ4 F|8W\oj`Cn2/W2Ujשrt4E*TQ9\P(1ZWr%BiWe:Q9\pҡP:c%ܲ|.8P(1ӒUnYrTt(Θi*,_y9* N:JgL[ü' 3qZ-a^႓8b^}ìWy}DJ߃4р6&UM6*z ȧ8f¤ ءQ @u |'aW2/4T-K888p׍ORAMA8p0ˬKp\{d؏A߀tuוދ |Mũ3c|"'[3o'>a㓞zr؈oI<{yܟ1lGkd-%XZYdaFl%H=Lv8$|l&6Y *P(^]]ʈ~Y\%¬ 2WgƠs!'qQ$ (lWp7|aQdp]ÉO:t@|4u^3pu$}g q/|QF]o $˯ޗ}N[ѲŗXB:ֈOM?.:ظoVԥL;~3A1Ш_7 J)_;Cdo} *ܠ@iStUWa*le4NG͕W3>&}ιҷrBA4JTv%sK~4;S=i!o'l`Tx޻cbcW^c];NF2PdРؘK=9']uZkm)#*YW/<[\trCm~کkm&no?Vלr|k㍭;\^'ƧA8 ӍOo&~)$ rplS0&8J=UTWZ@9*|H{赀rjURqTS\k*! ʩ .WIUCSNpES\hχ4**^ (6\%Wўi~OU8UPNmpJ*=p+z-rT\E{>=UTWZ@9*|H{赀rjURqTS\k*! ʩ .WI9!hYfjC R_ViCC+jL@zQ%  >={. dScޗGgPJaiz;pM'H;Ao3OO^U%[CN2mdqԺaU5y>2t-mCi-yw;2a<68iV-_B?(YneP+<N_GM!'6w?ba02u4 %^&m-shEz[oool{/i+OV>ORK#ggWq“:Jǎu/roO M:9pz"\p,RpT3'HnoD -/QG >D/1++OދJ (S+_C%j0Οձ~`g Ce¤}Bse!l0 '}"?_NrqQPRRן!JAGf[/hE}A/_ڟ?iٞOԄ/0c'~2 `v<`V.Fb!jlx잕F`B“=P4oW6DzT\V:|JŅ&`?>|O ګƵ*W? OqbIDAuZck 9,tO' ҹc{[?x<{3/𢲮 oINۛnSLvo7]e s`'<' .qS=oll8fߑ!&:6i‰e;G8L̄@Ufɢ, {=rFr@wɓ&ϓ=@ew yfRӮvZb㓞S>Q8LY}^%wL]{w\y%a#[oP7ʶn#x-2VYevcWyc@4!CNF9>9](K/mxǠQ-=8O/пķXF>?R~zh}~͢l^\W/t1)䮿Yk{/{1{bc>FLnlf${칻L8Q)˜xmLf7nؚμSMߘNz~n߹gM3gҧ\)eo6I[dhIG2hE/{3G/9d'>?E',NWXe%eY^]5$91BCpJ2D33tY^T!??Կ\8T'_epp:p4`o,]|U΄տӡ5B}f5CEoQ7Ϛ7ߐyIإKgm> _>uqxQe}͎-N;g;mg6̿={UW_mǰ_ɯfELt#O?EW^e'9i+?=hKhφm$ nSth ߳bcP??UgY~2thAσT~gFβͶXÇ,ot٩O<$5ĞޖCUJut˭ұSG'{.?ZAo~Ȕ)ζi1[u)6{M(~lᆀZ믗?>yȲ,ҳG9S /ґk7UԹ xtE7] 'uԓPWd/lg:&7zt@nTSHnvmWN=; vlSӴN{^s 7#e̠d_TXwgABNc/xj Afh10_Arcb_&?./_i sb?3*'Oڟ݀܂>PS OwIڕ! yUA{!Ot %yy2!w_ȉC:4 NSgC^zQ(8sHCI^8u00/WȉC:4 NSgC^zQ(8sHCI^8u00/A!|ohi9pɾtPn4ШbVF-VX #lizizia/ 86"(ۛn.=n~`透1wi,̲ߟ9yevnVu PSֵ\M,ѣ49?h`9䓁StM4qcf'(韟8yOfFŜi?@gSp ? WuYMV'lƒqk&n&x /EÏ>cLi3q'k|c Q7W]qy[c.jz/(.zjiסCke>ȋ$oL:5U -,kA7Yw`׫d}-qt䓱cgJ\* iI#NUId r6Ms߰uLrkX삓Դ\xy'x]s Pތ1crյI]mqCoo0? 2qQ*lo9æ0mErge?OPZfmACCF'oC/Gd 0*/:0!^ /"__e'>a}bVY{S(`Fy'i9:6@.YƓDui9:6@9H$,i=GƴP=@p7kLi_7ȘʟYH!$bZ;2$p^A?RXcڍM)qfIm"]^]Zj)y~m8i4E - 5 06z`ÍNjqCDZoe~{L< %V6H\}Օ]&,i"?urDy]| q}5Ffш\䞻Ͳ:kˡ.-=!iW4y ϙg+~w<a@Zkm9#mÆݶ0[AN!ˍ7`t{-2LV^yGyH>Կr!+˯?Sud[}2i2N: ?>8iCM '>a\ȟPtyO8N=yEe]w]~Vh뮹FMGډ^㏃]ny9sr֙gസd5ה9|m1"hknw>6[.kH9 {_ (C|]7ka8ͣ;rɨG矱֏֟pKB#ɧ,t?1c 3NqnS:@U|6emnR9ֱԍB.WKDl&l`cmu^կ~Y?9 8ةc#C:Pƌ 2 qIA\+e>>+7*w:`V_o/pmO'6>7L%UwK>mHS(fEu˲ˆ.@д6WkGz/"ÆʍR޻Qz\qůKa39q#m=tџG/z?q)8 ko~衲Fֺo&ê-r66Muoc2|>6Li^UZ^bPps=MiG*WןS]|\)g?wnTs_PXŸqJRo75ƿ> ZjS䫼XA'I?_k/_MW6 WͷJXʉ@{-!XYSZO2jS)װO/]U%Rͧ:D\ P TU"|"-$Ѽ҉Oӛ}҈S^[-hcE*Ŗ[bF]T6y{ѣxJvc CgF>Y_o鵿Znk&,Ϟzo\ruכcSqV=Kt>~{g4۔Oq ;D~[O|_0&l*[u^o_qNAE|4׿ cXtA 3$6+nMv%] [_ ?Ts//PsM?挱 ?CG00!?̅斴 7!ڥB,`:To5[A(dK:` f(OLCGC Eo]…%폯*͌7[u6*`0YWWs_E@>pWYUcV| چ)4kӌ_?nҭ{ww8S|>LVc 9z\@cSϦℤOe6djuFAIȳ>+/Lb}zKW,&'O_{]FL>mC2`,:F-F18Fɿ2`;)7ߐ_~Y&HgFd+Vg~ ^\5-ѥC=˺g:쑇I'Qۚ,bqLyi6u=ٳuy<2qd i31P%/?mFGf@L9?*=ƿ8P b@CP~~b/:8c??dRfoƿ:ƿjZ4rXцiD20#omyRFe z[fQY.3ޖY+eTmiJ20#omyRFe z[fQY.3ޖY+eTmiJ20#omyRFe z[fQY.3ޖY+eTmiJ20#omyRFe z[fQY.3ޖY+eTmiJ20#omyRFe z[fQY.3ޖY+eTmiJ20#omyRFe z[fQY.3V`JϧqƖHv:"BJ(fIѺ# z[;1(z#h zQ@sRrh[ ZmiJdfNPnD]CA3?bOM?X, xU.E'O% a ]IA_Xxs֕EmI_\OY(p4O`̞.4#uJ렌Ya(,…t$ˀ:uP?p1' 88QEx"S#?0,stD*%uJ(%cN0G_Ƨ"f`A4Zy.ťVhXvk 5 íѶ@\N(?Կ/`y{hM"EK_xTnO G`hC>O`t0]IwZޣJEET`TK Mł4 "5*bAi^{I^i{}QQg|c/d*xm߶ X(?mm;zbɳ; !'v`v/vb;)*)YSV\\N/lN] Y!/.SX; 1x Kp)1ֿџ?5c !6MdIc&qÊiN&Mfu5ƍ,ܸ=tO1P87W⚃UD#پ'V8Ց>U 2We[L`O"G9FA6L8YjE? L0 b1W{91cW[Xxa%Xv0 ӿL4OD65NCla/;?N'~ G^?5meOt[#mpk(&{B5p0@{+?ow!O 9I>2QXr6!,lDUq]m\(; ?染NVDCAM' k [mU>2㗡4m\E<G;HSWYCRReq3܎rֿؐ NpI?&yUI/5k&7Oӿelio; Qlovhr>%𙴝;udpO1vjvnvn޿'ɾrF{K|dϏ/_2B&3'HPI=Pf+=XFWjٓ0Vr%0|/Ԥ/6lJș/qa+AиRMjL?)'rK\J5jLJD)?Ih/g`re9AБYXF?A,E"1k돭ey6/_yXQU$m??Cv`h/ ;';';';< vdovhyD?^5?oRm#G q IYe22I&yy ,诼9eL!Le?6B9eLDL@FMd*װ9y^0K_a1Rr0{Rs:Wƞ`%s!_(m~1g/V [6*韢5 ^?M|pG v`/vdovUsBvv*;f?#;_v($.vjvjvgNKgЂ > 14';st-??GwMI p7>7Yq: K WY!cȓu\kJh? Q(q:M#Jc돜ba7"Yc2㈢FM 8 7MMƕ 9aQQZf8_Nk <]>7 7J? 4l!&# P6L1'O\,Y&mq_? %L2o^ele/P?e/c L6/4żdo;oLy?miO^;l*2{ o2?3=doKʁk󇒒2`Fz8i’Wi!4#YW&d7@IDAT)Ir(N2E /q!^21.qq)]N?L)\mF<&3˄_eJlwTp.f0%8aggOesFȔF:1?G'Qb4jڌ8$ČsRJ: eZ.c_e\]Ws;(rB\\/wֿ#_6Lu^eG _?L2oF@gwE3Ο?u޿{b_9=?'_1/U>!U%ȭSݧ9ʥa6'U%bd!\DX $TZ%ET"ZN^.F&{riIUI%9 L LmZеL8!q]0B:tgE,Q!?&SlW[xvˈ <Ē̛*]6bÆ?lJ. mV{>/3,*\'G6ֿ~E_?L2o7? x@ IᜒفY#( Ra?M(#__XWmmo _I_~e|C ݀?NW RN d'R9wtoF)BbDu@`wt0 3œQaP>'89: 3œQaP>'89: 3œQaP>'89:1 =!i\og'*R3=Qby")4 ?eWXD81DP_oi'p Ϙ -`'韦 YO5G'*ݜd.lqe돭@ aa]4#1V_L0 6Hts s;1N#1| }cWN@ s% 5k#Jcߓ>/-i诔(B& ^J&1r?XaS$?h=S#to8_$-0SY @άĄZey/Bc돭Ia/(gӿL3l`5Dm:3tMEU]hM6o7)L69/(בX~%T)$c韦$)b?la'laB?Ey+ϫ^x8Sq\A`WTF@Mgfj!vZq'TtOiƊbWg}2*@Mgfj!vZq'TtOiƊbWg}2*@Mgfj!vZq'TtOiƊbWg}2*@Mgfj!vZq'TtOiƊbWg}2*@Mgfj!vZq'TtOiƊbWg}2*@Mgfj!vZq'TtOiƊbWg}2*@Mgfj!vZq'TtOiƊbWg}2*@Mgfj!vZq'TtOiƊbWg}2*@Mgfj!vZq'TtOiƊbWg}2*@Mgfj!vZq'TtOiƊbWg}2*@Mgfj!vZq'TtOiƊbWg}2*@Mgfj!v|$~gç( 8.0tw-8M5\ mr'khNqL ?MLYoo;l9:\_Ygg;N]J?Dh;G;Ǡ5??oj,=O~ 築':!Y6$eovk S+@_Wc돭?xfpَy(b5r˼2 N2e{> /Q3.㶹ogOD ?&mi?.KS_ LFQA oΟ__+Fvlvl|`}`/r*Grq~S|`;b^w;e鸼6ͼUh'cJ"4*S8*BH@9OJ1_"4*S8*BH@9OJ1_"4*S8*BH@9OJ1_"4*S8*BH@9OJ1_"4*S8*BH@9OJ1_"4*S8*BH@9OJ1_"4*S8*BH@9OJ1_"4*S8*BH@9OJ1_"4*S8*BH@9OJ1_"4*S8*BH@9OJ1_"4*S8*BH@9OJ1_"4*S՘QS`ĆOlA k}98 D!o#j[qXo7g䯭?nIש!$4/?Y8%M{`f/W;Hӿ1bU"4Pߦ̊0W SοE\Doӿmaz6HOXH4 YPMqLL"JxVa^_u$M2/ӿL2LHO-ɢUW,'m vR<?hV$;%p1sJsBrJh%?L0O?M4OӿmS?L4O?M4O?M4ObĽw}d_g"Y,ɀ}͙56AH~ \Z|K.@o7'2! DtFH q?&D&Ă!-TZka0&24nۨi3Pͻ.?23_!A68ri>5O0D/ENamMn_r%Zr&"WN &?EXDjڊ.J\7ȋP^61%/&6`4v폢wǁBsk*T@o^ϟAE8& ,OtNKۨ6ۈ֧}) 4Hj_ ܨߠCV8a!ߙd^&'ow$c-]@7x2?YcvQfM7O?M&өyiWBd_9!omxi - HLW rq1چm9d.,穒|,Tb8MWvV[y*Y1+];*]ld@b8 ' ` $b!t8)"tC8+J*J׎YjI:N(+];ԒtY1PR!Wv5g%<ċb8Bt8kRKygpBI\q蟥/Ίᄒ ҵ(GFMQO/y*(.~ęM9çc&1WwjREOi4@C4-b>[J评_LKF4B+V_l)}GqiGx#mQ`fz\"w ?fG_t(hI4uxk#;7 +8fؓK׏IK.-5IK;TUBkJK蛹>JB{dߑGC|0m ch>}: 6Loqۭn4ݯ!tg Ƿ}FǏ˖3I O{>'O>͚5*zg5 /..Gm==-ծ]ʕ+ |NOWnaƙ{Yٮ\Xb%͞= 8tn!9Qb-Aȃȃo {zn>O=,Ϧ9'q!@UlFo_ce4iy/ިR ^ Z)ȔG1m7voe3lpjа!||GǶpS!3 ?"@ )=A/?wK/M-E!077w 0W6T˾W27o;GYg_3?A kI~wxqpVN]#W\(ѴLcW5ryZֿ$+1g4-UM\u`'<%1.hZN<-13'! @ ֠_ןzrqI1>*ːҶlTksTJU)Kয়~B.RiTs->?zSB2j|Pl2bo?uw؞FS&Od<4&[hIMшk`0h@! V[nM`HYrżS'ѤI,?]pm|کtG]-]Fgч,^jeUys XHg=c3c_ cEtG|8\o/ jᢅԷWOZj}siS*+.e(ժUfQI)4i"䁴ZXNr?!gty$ףt֍>tQR?{blk;p:wڷӿ\0O?M4߮)Ou9 e*|@^oSSRD$[I'ưaj&6D1kOXBEU<ư_[7y|%xwA,a4agVAJusn.?َm>+̯g8B_Q7ajk@7u >l|bxHKس@Y1ҿho7)7 O*RiI書70Dc.oECB[l e"u /_-0|B֌/GiUcf2-YF'w? re X=j֬)<=?NCSzwwWЛoW*Vtd =S4glj0o̥>}zOLE`|xV[Q b Bo~apޠsi:<@ES t6k)^y_0|<۷9d])>O`=kLjhKTϬ;tC1 @Vzu=vo^{?pwb ٵKZh]"ju/EL>9;9?'HGuoi.^6#r~$C_Teh){ѐ)~h(>!LӤɓ~)ƻ6t;o#w_\97^ T쒋֟aDqJ0t ss.tl2} ?<%<w+g/J;tĉHيpF>4{,D/#G/OÇvӏm G\~w}߮Q0|:eӇIֵi1brߴ 7'fcM'r ~D;K/ш]sjX?i}t? 8p Y\3L| ytQ'ȃ:B* ΃iNǧ_FH #$O $8φOGsH޽{< N6q 95^ta7?iI6?&L,HBZj#1rS:[l_?i/^!~;篖~-_>R9v2F FרL%z|߈4FloP)kTf160sry\d䯭?aXQ٦5jL~!ǭ? _Kp݁#ȯL=B>6ApL]^[A-[L w:NHdbp^j ?}ޕJ6O4YXv?>m9]9~a[okoKMl˟V@wٕ-ZH[_qGMl]?jxLBϿ/:CU\Y3Ν+ lQtTw?'$}ð'f|E{/K+jP>-^TޠN $h#խ[Vë>-4gtPeziܸ{ Jh0Q#FHy'hyhb-0vein]:OQf,<*p"qB{-(s+/FN:ԹkWz_ojѢ%p(WD/' OqK/O>ѝ)Du(jԺA xq9-5jԠn'@vo^5hՊ«?z'i1bw^9utH۶>vmG_=^6c7mڠTyʸיC k'xcF.S`q !&*̕O?NZz F_ilCժU_H =3b ̣>kA0.92^C@<>KA6|kH4dʟͷ6x>s}scOժW^ڹZR_st]c[9o2`ȃC2<25h7tL ӧ4ss?I'w+N߯@S 5!ƥ_Yv|NӖ[B_eϱ6<};uB5L 6iBlW_K ̿^VVBwq!ED 73@Ja믭6mO9N~l!f\\#/0.D뺇Q4QoRU3osTj`$[VٌZ|l|(2")TXV._AݺvYkz+4Hd-ο`(p,%{)Ƣw mWwޅxڱS-20,dx>yOwwflB S{F3i]+Ø[!gynfnXŽ8K.yO7kZcC9T{@ql Qx3k>N;qu<<Æ >P:W/+H#`áбEʕt_W\znç{'xG O_u95>=NCAg??5 Ь>AX ރN^]{AnCexD.w {O\<2ٛ1bO}G Ds'QF]O8>ɛ:u*uq!qt8f?tf/-[_}."$/6 \HϿapVZ%̡?1v폄ǧ.r>dAbaXM7 ?zAU2s0֫W_xsQc`iSSǧN7tޮN?]w?*s?/=%_vmK`D?;8ԓO!wa޳W"2/Z.2!=\*ǽEg .^-x]+ǧN=o|:3\<<8n{RT ϟ-Q6՗~9< O%Xn"xMRxV$ z\qU"lûSjե0Xt-j%=| "C}V@{0RGyTQSx(>Y،>qgrG89,!zPo' |>3 rҥOزx{bC0ZĄqc!xr b4 iрvJaDE2Uҵ[gC׿-e+@QI|?rt*Wkq}iSnof'< hޜ 0<0I@'0 Ն~N3^UyөϣܡN]t :C!}ޚX5Q~>W)Iy‹t_tUq}6|2ת,YN*?`W1G`,O?Xw7-}Ǝ+L}nД͆לϿ.wqy^oUk+1\Q~!1ngʐ% {GroڵyӘC'O[kQO"xoC?zRΦ-[R~W|Oa^3DrLdc No!oK̽;X^ #jUȽMz衇yetԿQy< ߘ/{쁺~eKDNd.z?CGdBeŐDbt -[%k2_Ӝ9(rsŔ%xk\M]:vrxAƝut~K2PGun"zg:5m^ssdѻ{Ni⤩>`щ0YRQ]N#c==hqXu oXF<aʇǏzdSO=Ewqݯ?ܟ s _³7.tͰke mKEcH7"FO?{_&G:ߏar'?Ѿ=~%>ګ䉓9eEtN^Ө#QT|zpMx/|Sf9p9ܹR+qYԪՁ2}55GH<ڣ'RE֛oҕW\J5aߟLO<א: ӗZIp?>c4YCt#0rCNQ0|G3|mM7Ã-ZDhD&$0` n? 5l3zkz5x[рqoKy_~9yb(`s#jo]௡In"DXsۡ:|EpB<4|x|!fNѩNm?Պ?L ڛt=ޮM&vlDŽTOySy{?o>e0_`%?t+³|y3M >oy}w:F%M(@X`2Fo?huBa5a½K蔓NfR:$o4w7ss60LdRbFq x*X>ss:<}4?S^=k3hh-<>O T_.hN[ȊFQ `jrTD-o.B_~92f:~TyX~Cpkanol"p{'RJ,W=S\F@w6S{/?i/ag\ڱF,Fq*UJW]odb Ywv/4~.{&0P̷Ǒ?I`1㙋`C0o돭,G'`?L0/abHI?M4SD  TvbtM2/ӿlURсY$zg/0bH>b$ 2ge(S*$Au Ls#RH@H(*PJr /;m܋fJA$%9Q?& ʖh1SJRSeJ>?p2LRFb=3oܷFamy\t"ZvL&>@\˖-TcT +gϚ_eQӿeg x&QoN@IDAT^}s:ABk><>xt5Gdܮ$=CmL_i|sձ9˟{ar*ӗ1?A6ӢᆪzП ?? ç}<|zj޳ R<ʳf֬Y˨:<6;Nyg7g>pE>^ye$=>_A={ҷi7CA0kl:8?hÆO6dž*cCAwW^~) 0*T+:笳p_-,kQn r 6+(Qx.sϥiM5<4xҸSOx3eQo5股67 M奿Xr/w9!7ع!ur @ñ;}G0J Õ΁+V7|#?Ğؘp|:bd"v ݇~ lG;dx|b` zzJx&7q߻Ox|:Hzyw鲋<|1{ /<Ԝ'/IC*w31'Gǧ"zэcZc:zr<{[tP] /ٷ\D>g1vVSt?1O68F_*duÇڸב09B0|Ccϟyk]!iL+kNbO<8}հq~)tba5* !֠=fim;N=4ylHu'x FByxbq# L[п?AL7tFVUċ6t'^L1_[, Tk<+|0O010oG ^:A?&|b/_?L i)[ :>Ddӊ'[ : wXx8H6o7K0A(.h 1k럭r gH6? 'x|J[嵬Ks CXo"eH#αOa;fc}p|>E+ _FMZ;`xVlo@xla=x}wUFk֔o"b+cf^>|_w57 /Wkhz3f|401KB$<`e|/K~o>ܶ>p c+Y ;xN97+7nD>0ܱ̿QRg:r}1㛹=G Nwe˗s={P^yeqp?c~W-0{C΃3`|"M7ͪN,~ިc7n+]qU{忿8dFe* Z p{d}7h CS劕!ChG{WysӾwwqX)<_oZ۰y~DC6DQNx%'#oǐ{ӼE x|BT ?=ǺG=;|-*waLT9 3,C~of@ Siؒ_i'{9DE4jK_9x >uoЪ# #F 'o|OUW˾W.a]a$5. sM}HU$o `6^51^\T 'F(,--iY]"]&T}aT% Cq*怗+ow$trw{Ľ{g[oT·H7^#PW-?#/>:a=PdxP[O?C51cE ȃh4G~0F˔3~D:jďOߞ4o b!MRqRw:_Zml] o7`ĶN7|wec+f{C?sַ%D=Z=>-np<mA5ɓI]2a-ˍfc] Ypڵ_cNԡsGY9= GqNU2xYm]b`jHjL1XUeCIЯ{p΀Լy gŐʡ5nn{~C/>D }׍D<0+(Eg&]&LP?B['2L0ӿLL?a߿?1WQ)~ 6=ܽ/3gX2"r`(/Ŋ:ߺ]@H b qBD@F\G󅳌`azp._ (q`ؚ/W5Rn^`A1] T7~ H~,QE"y.7Ќ{ nC=f1j;M.ӏ>1%6a,^"ho?d?qd7W|u7~x+(.G 5RY|9u1QŽ\F?u'xawJ) ^Xh< $oHK-"~G]={1r,<5= y]{ (^Knt!Ze+.,5MeW }[nqTRR 1'r7[nv?w e{ͷP>q=̳U<06\7~7uU0axw‰HtАϿ@w}'-A[D~K/ Wm| *0L6|3#0ѩ0ENu5vx mbc%N}C[o ާ`,ݧ aZs cC[+.Gb|ϸn)8ptNڵ;8:u<+r|a祽'qxb˚t۝w?66|i1NoNhOD;ԭK#o)=I!˹|[QKt}۷oK }a}ͷ*2OѤ3[ě9=FM5a3س3g^* _f޷ih}0;˴~ n&)T|<> >AVmПwW;XH'KB./~φgTِ|YwqqQGC֣}z$nC 1+AtA|z/_uO> ͙ۧQ#~zbӥ#ehx'|iSݍkuᵎX=$Z"*'t04ĉ`ܟ? MA>E-'%,Ahа!] /<^xMY 㯭 Y@CO;~- kvgzjzN3E?H?(?"-L[u5kF 2:`xLk[MӿL2/?Mlwe|(>T*ږQC(ږQ+(ږQ+(ږQ+(ږQ+(ږQ+(ږQ+(ږQ+(ږQ+(ږQ+(ږQ+(ږQ+(ږQ+(ږQ+(ږQ+(ږQ+(ږQ+(ږQ+(ږQ+(ږQ+(ږQ+(ږQ+(ږQ+(zAqS>}஌,P(@ (%-xiG椲Nju͕O2,\, 5ՁmfY7wT~}Uh4{״~+/q@=ޭOR5Ngߐ? PVvGܮvE#%X=>Ux>xL1|}06ӹo= }j- ڧoQo}*g78{I^z)p=L__6n0?2۵04ຓ'OO簶孁QFy168}pmo-lx|4lq ]56w * ?[?^#}n1c=#0xwmy ?6x=a$֦ARs  ^jJz z> /+nuɏG:uL؃ @ lu#p ^ @ O~s$xc(/i z1"4q:};*h1; >yӻ ",ra{m`D6;ի;H%ek`4| Eo{ 7/`̬㗛c(̙=W$7];s}5ٞN:dy'.IHБ8eUW^0w΍s-'>Ekゥ駋:w<.[N]r}$Ͽ|gqa!_OL^| 5q߫'d~;A=(D' vob$F9'po:~6ܺ6`oaϮs?0+i$4Megq | џ;:o$bB&1iX&9FMy:P6MAND%8i߶ĥ?u1}Qʲ^DB_O% 'M4O?M܈>UXG8* `!rd|gɒɏ EL:ʆUUH ~~[ ˿îW_GIݻ^g X&J_u5G)s=C-՘}7qcңΝh<|,.{O$<3E#w}aպ5H?N_w}WAfNG/6HY": S/ RјXqs#染%ng?yoq{N|t/Ô5WVp\--.g?:qIOY S.yWov߾2s[o7=UXJcIHTbyZJ1|r&ok/[ޖÛ{ؔ?{m};-*Qj0gȅCƋ?O-JN}zxA`O5OFOedrja8< O<_aAھqamOC/s]wm QWKϣQ7펄7rzJ:-=׶AΎ;VЩcCq'ـ~4|pwք7/]y>{ã}t ~ѠvܑS,\w˨ˆOC.')v-VUJO4*K/Y?.YF-[~0|{|Rkk#R /^L'O[vہeb(wX7X Xx'o>NfSy!(L`D?t Ay;7<v4?OƂ=nc:sЦ1{8@Ga:[ߠoJ{G d))OnXGgO0ڳ7){&-<,WqD FXH4/yz뮛iѽ]}X4Icy%b ?1hcS)A|Vzj~^~ۮC϶J+W!^Kx_HKҿv%OHeó4o8"[\Yi߅{׀yV}4v:->g>cUW{Y *N7n);,]s/84wXd1]wACgt9CͰ۰؈ .bgp:Xv=2y?썯K?яrCwb-M?Re~e/Nwa$m[b}>G} nz׿M7w#cqO)LG}_L߿0-{o5,,Yd<ǮuܱME->7ǃAÎ4矟~ֳt.浯O;촣~>Es[aQ`hw?(Gzb'k,z|Oy*v|zޠ؎9;mz/gt{>탅OSVߎ??һy+^~}ү fw`ײM6k5g?O_mء{ ;>lݴ_@|6Ň疯)Mvc[1{?6y,R,"m<\o f ο v5'>V > EHǑG5miO}>Ч?ߒfk| v+q G`LbgXsgCm/EǞ{NiԿwNGg/~){g` z2nv1ʱ]|{:;n /|v{/:aqYSyAx^ta:`m Um?_kkB4&ߜ_zK/ <7V \"ؠgAqdN`>AI1&zs"CBeOEZ?%d APOƙ,XMgr0HPQŬي7wh>Pde5ІjA=%24?\B$sǍ53vF ?GT?-|4<< q׶jVٵT)q%M͈ J?ߘ3rj B#?o b|<v(juÃe_Y+B_!AY&.#|Ex{0]mao}{e r~.wK#VkN_M)EML_?s(⊴zM[ew.~6]. cEc!?zn N?vrKKl4)m=XSOq۟w!u/щ?Io|k6vΧߜqW6ÎOXEOǎO.nn G |O'>f/:o~aÊZ,R'=~}&luoZk;>fg>s}'>\|7_ab}wi1t=i_w9 f#\9O?=rQ?q̲`5?SLGmA_lOb++pimtYz^ wK\[uϋ7z75X=? 9}S>dzܷ⠷R',y_m?4,v$0h51ӱ_:vz/8n';vzY=-=}_J>=Zm_ oYGqd:ʇ>$= X7+S8ߟ.S=tMˤpv]{ͳ;SzKZmv5/z鬳n#=4Nch^J,޹4[X}u0u]wM/~K!wd}d^5#ijj̉|/}qkm^M?O[2/vCi>WeX&O(_4G*a?<ᇶ5[%#M!<=sMѩXhGƛm7YHs{`SvSO9 ~Dbw<9u~Djye?_;a.[b.I?jy;lgϹ7ybovz#HƳb89ͤM`!.V?7D?v>{ޏg~埯J< hqE}+¾khlqG>232j/z ӕW\%XąllEX0,_G$3ZkǦ}x/pYzAϸAφqs㟻I ʸBQO= 3\oWtxeؠ6s#"Sf/6(cc;q??]~ŕi0q'ʇ~g4|xpz:!]|%̧5Z+= UXlm@#?!IϿ߯3.vC۩??/SE'4/Ϳ% K''Q8h3q oz8Z/ş=ιQPA8X8?,#3;v{VCkpNj8xI^+Lj }t=/K1ՃґcEgqD)ogUhbWqjT,|Kٕws[~Q^Ȍc\:qr $P!jt].O='7E^{?jbi Mwߜmj ~{Y݃O;0 dJ06xӶl~O}q؟O|IG㏷}vڠ sMa3'k RIG-poŎ&wywdbDX§7>Ob?~ÎS\]ḩ}vO-{?voI:']f^n8cs"񞂐K;`M!-JGa;a:{B)vm.Og;>;>APv.>?O>7aR7h ;G,cEq3m_ɿ;fEb|3ӳԞ{b\s69 wK\s-ya+wqƔ~7u`,;M_ ?jaSem&eګ!Ab>} o?p,J=}rwEXHL bK8lE^+cX< cCH,p|n>0}4e~cG؟/~ MߍoO3φ=x~M[+-}PwYpvuM[ox7s'5!jpm]z8\ҧ8a?dywxM +J>m{ޞҵ>RΜXߎţnK'  /X1:?ʚ˰C7>?ĂX,flW_o>tbwx\I1p…-|ƮxEoĽ<$m`y$"E𞮁o` y5~Oܧ_iEk_Y/yγ]o8ZϟxߺCO?4* g#I__# jiM?d0Ddd5` 8柡4j! :BM3Rn('i*_KGc;>E:_QMCk6@ p-Jg%6@ ?$`2 %ml"]#1ji@M>6&xjQ hx.DZУnde\cA>rZ8#f.aeR1qX>2sz˨$X5[v^jhRVa(/`a(v=. g;+ wǴӰ2<3M esE?(ҽ}oo/|))v'ڿArؙg_ّ+ҏ~􎷿md:pMߣ?}M;nu?QzQ_bCk C\Y/~WvoǸtI'WXkOŖwgb Q?v'z3v1'pWaob;~D{cg(,P.\vvO9ڰvn{ի%m 9 ~sN93yPZ6#/~6.WX_ ;8=9b֖o9>?#PX7ӝzkxcS1>g,,dX cqx_q]w]^ZnV/s`MhEW_$==Eim`Cd1sQ$QG9ʿ?h;u^y%Oɟ;>#^X,[r!~m=:CXlJIMCfSmǡ_$bKikj&=O˟6czk߈E|;|xK8wׁ?riaβ^:X\W:mu:K}{7q74]yi<s9$A=/wP睳Wհ-@>Y'|ӛOwj+.O0C1ñSՁ 7bO;;2]mp fҦX ׾1sӏ~#v]^y-]? 7^]s5=!GWp-\(vٰ?wg?7܀e0`ڿ]dyQ YYDMOOv@2>Ɇ27ϥ/!`&b- ,njϻ?`?qV郃3?6&Jt} *So#.>5cFT[o)vr9GaGǰ¹Tf'1rhPz &DׅRΚ4 ]ͿJz%!;HQ5ip&`LQl=RDD?un^6i5]]VB~X@xzo\ct>NJ̀J!?jOmFiǝvLw;/?7}i}ya?~P8?lI箻s=7㟤k_c-Em={鏐%3_o῵v3Rqءf.Ogs-ȸjE:l񦶋o:3zK/3}6T6.t dSJwaǴvۤ_◶5m?-R.T#,`jFnW3t \{XD±]xߞio^yL:euA4+@IDAT&]wW:r켳"|WdႧzZ"ZQ7]ɸПun.L>s!s5N?CL2!Duc=>N? 㓙[mvYZ<7ߜ~dczs׿iwIv~~_+̮4`6ێZ?z{Qηs-G@Ƴصs~k;%S?ˊ~j 4!ҁ6H??2Wdav07H !??Ke>P~FB ? c _*VVY|9vÄP>Ĵ"ifpPrZi Th/OoZb:fjT%#3YlLVY"7gNP*(#G[,cNÙY)*Уj_]pnwt0x/ҿ$I|N2>;g~| D%L:ΙFeG@i]L`6M4h|so;$iGȤvzϿ 7ܸ?`+^2ܤ[:묔?_?me/6kcJAWyN*m L7M46zd5h!K/_y331`;Ix}A}UtÈMIhl=&]e|TQPlXy`:*#rbg ө2n0"K((6Xy`:*#rbg ө2n0"K((A/ůBeG΃F'RvA?s$xTn}tjU/Ŕ\A<9=tto!VOSf676/B c OHozNX#Eke!uEWW7F vhQG9^*},kR2C d(I((lPyQ'KAOQb })Rz!oiyzP2RSqQ瑤W[Xgo{ CKVڒuULҿv4ZʄlX#CGS \[δS8Ii!(ٟV*2!'ז3d.|9$6f >?1LGFe;`lm"SOOG7{46ihdzܴǃltOƎOW3d <&w=x̧m{a+?gMl3G\taFRO?jQ)F޿c*R_0ѓ/MDz=:PM78b@00G?_}s|@4[L3jE@kK6p]p5A]!zԻ%&g͑i( e5SЕ:=+Hba$Bī2bGɟÕ8I\"?_?dz<ޑ~?YO>/E Ӯ:?-`c9n1Ιg&{>‚Wv8U,`(G ;W/uCOnN3|ヷ8߿7Ȕ[4CgOx2E5cih$e0m͂hXA!3hX86g5If7?",ɿ(OO!] R4従ܳ[ohCv'PKo?(OeTOOߔS &1'ݘrʠooʿ)[aSQW_Ue+??m;>- ^&CYAKqxLbj@D9l8t1eem 8t1eۂqcS pcS q,ǔ! @1,ǔ! @n Y3)CL((KocY3)CL((LgSZ/PQƀLgSZ/PQ-g8 1^,g8 1^w[02qLbj@DYz2qLbj@D9`e:2z6e:2zrm8t1eem 8t1eۂqcS pcS q,ǔ! @1,ǔ! @n Y3Xdo E`@}J shgȍv98lF~]k2 RO&Ju_?pzý'7c#GF2L=)]W A?(PC/:~Ϛ0A*T ?pxnA*VCB+PAPC]W-AJt0JTtlMV(TJ K_.HPA#IԢt\Z8<44 e(heKzP ( Gb8YI ∛J[-FPz̭PPzu[UoԿ/Uiqj M/m e_[a%gA.?b ٰO?K@sl'(R4 ?)TC ?O>QI7ߔ}TBӆՔS=V)o3I>q./^n}(r]7fw۷W(C*s2t"|v)4h9mwX =iiaYf"+漵h~B3f?_ij+COߊ?)T/?!6Dl7;55 | UMG_9@~[gA_Iv@__VYg埕Z߿}۪kR1'1#MQVP=БK=ZpFQ`(ȥRyB-8( k0DtR)@<o5 :rgP 7 T 3Ogea 聎\*'Ԃ3CA@G.jFYX z#Jz ~,P=БK=ZpFQ`(ȥRyB-8( k0DtR)@<o5 :rgP 7 T 3Ogea 聎\*'Ԃ3CA@G.jFYX z#Jz ~,P=БK=ZpFQ`(ȥRyB-8( k0DtR)@<o5 :rgP 7 T 3Ogea 聎\*'Ԃ3CA@G.jFIV4z3rt]Ќk,Vk'S8wmC}dN]eiN?D8a:]<N'k)zTѮ=ƟƟO!-LpY!xΠ?k@KT 8fVK|o4U;Phɿ0s]e fqjzb Vnj0. py sǕ۠Z-- Cb¬! M8TEP- Cb,Cj(JjP0K _j(JjP0K _j(JjP0lx.x3H}am&d(ٳ&^Nh m%Ɵ/٦O4(℻+X MÓ-hQzӾ^NpA7(RVaOÓ-hQzӾ渠HIL'Ud Z޴9.(?f< OEMアwK\nj9o"wZnHEl]b9yZqm [A _ir.s_?3Nv)[/ş+O0ʿ)+sI6s" I@%Cp73G65VQOO'?P6y<OMJ55dh#O?"G7=e!@[)Q?*@UBOş?*T_)V9/?pݝraQ+1"K𩑔N| owu/si W{Pmpߤ{ٞKkZn&j_'GG5O˗ϥ "%Sƍ`snh& ]7 D]V&F6&C&FN6nd@t)x:Thl͹B&Vgd(9,~4YɵrxvAS=2|yވ%_0^^LOI??_?)[/şIʿ5TI7=/+m'o_լ?޿޿޿޿k-[\q{hO^jmo2nERdez@7Q4(r#!Ƶ*QGO_Ϳ?@_w}b_/℅3(iU9@F#ko#}l-]?0j J/e)S_?{AWWg`3N0?ʿbloʿ)o 2(?+3g#T1k:?FFA7yRo3sss8,*ls><<_o0Yx%?jÀ ZkD[nzgXE(=kD[ozg^W9K=; :<$I@Qj锖^w0<UO2$TK ^癇 zP!Z: :<.[d=OO/B[—Ìms[A\}y,Dmi_?9#`Z!Ko21dSe*ş3`$?(y*|\(!&SE,W+ʿ(?*?*xV]0en_l',}JVހof'e_45߅#ZV DQ2bb=싦Կ #$'CYIBW"\/PFb \O'(#s ?`'|33εs,Ԙ;!߸/b;T8 ?htWLfOφN&  }0#)k_:7z!Ì/_;)-[w #zbaOߦ.ةb4@es^zB]"K/ o?VAUO8hr* gzT)17oM3 gK6*4d2ʈ ?4 ESVieDn/K9b 2"7??)c)Syڑ8d A$>ELM/`Y T<+ٞ/)#L4? Q1)=B /Z}QZi 6H/Zdϟ?_uU:SөlYnpi-~ۧt.Is$LI@o +-w iHʁlG+_ωq+PAODjJxYtȀQBKbaI)o?>*4˨[oߊ+hSCRƏ(4 :R,v)`_0V8^\U(埔RI'[C>cҟu#zP0V 3+[YHd(OT/5 a4Ƙ\0k\ut ͩjLc gXo?eǧV g,\Aj r@$ Ole (F(^>*Z]vz=ͮFA(_yՕ+_?5_}ia= {0Kg?MgqZEWy[ǟ__?A5R/AᄎW+ayLpTȥ/ʿ(6oFSEPF埔xB7ߨ?`PQGT37<3777_=1!IUέL@ﴃI&; &VD?vA6?R$.K4yqAd{btcտ _ڢG> /7,ӟ.$P^Z6iM.Z/>,&e,KgڷIބ+oB9I??:}f d5A4c 4 _&R?ſېdl(W?)Ȝ oʿQ1ASM7sIGʿ* ?QW_MtõP oʿ\Q 8-Gjj XWkE\G5lWkE\G5lWkE\G5lWkE\G5lWkE\G5lWkE\G5lWkE\G5lWkE\G5lWkE\G5lWkE\G5lWkE\G5lWkE\G5lWkE\G5lWkE\G5lWkE\G5lWkE\G5lWkE\G5lWkE\G5lWkE\G5lWkE\G5lWkE\G5lWkE\G5lWkE\G5lا.'P=_&Q/H1_)H|,)WTflz@rN /jF4(:WwiV[[7g~~≣_LTfu楗]C.N.Ez~&h__KX&U GPUʿhO?O=0sGzםg7 |F_DQ ? >4l|j"S9O6S;2~(o,@ "+xmy,)n#@"( ҙ "6b PV1V38:ĕo,AI1Wc}=tA&F,Ĥ׏y|u51|C,`Vi[-|9[KSD8Xߵv=%l?Xa;xj ᾨȆ/9skXU ̂tJ_^o/ǮNw68Il' ./[ ?.J*IXeikkkߪ_߿iO?\bUFg/v~vvۏ(Mqpiqߗ-G V o*\/ZEɖGW-G n&[ (Ú˖SGGGGl!ev)ʘM%;}_Y?`! xd mmMͨ5.y? vO&_SOχ>2&~S2 jwjoe@UeX P[<[Zi|?b㬌: 5Uaq'3s|u|&)T$^cgMF*?y-ҥw39k_JwҦnֻmW_t%餓.ӥ.J {zģ6NQ_M-J{;ꪴhu.K'鬳δ~H?,?לdP >tas!&  7=0@E&^)Q7D L?dPf>/_ԃseZWOBg?T"oߜ/PADgy'MFOPS[~m hއG6% дJN)*Z14!(x Uտ/c1Z'#V;b2!TH@htD_ͿnV4#@+ow;o1PԈV`'4IsȒY+K:qv͌{0V_cf&tͷpu_4qکK?q(_wcZ~?I=ɧN/%?FM _?n pI׃?0' ?ſPG1,*ʿG|'z35!Ү'?(Ck3QI7ߔʿ)+]f5( ˿b'튅J)86]t񅐫h˻lvy)j)]pwCq-Kӂߟw^:]?Aqs'X$CY eTȟ U/!6T?ƃ8kz`Γ?@Ŀ,T3 ?IPRMG_G)?+[!(?`,޿?JGЁnWzO+xd 0^򑳰Qad)`ɨsnm.tֺYhU>z P߅RΒ}&ДC[X$0A$\(GOai4c c9fYWMù{FdP d>LZNoa㱰dQzl]m6]s \~Hi1^z%iٲeiͷijK_ϥk6mݢv}SNN'璿OOIN)$r dCLG_XfFQo_pˠK/8u\ Az$SOş?loߊQV0?,6iXZp1j۠:vIJ `W=#]$QVsݰ%ps6$pn F4 _cfeDSq!ic/YJϤHd}Oe4,gq^'c7KzoY1`c[`>mSNU:_=L뮻 s|{fg +'t9;Niw5'38Yw]oUU_/_uU5"''''jeeeeeeWϚ4iO?|FߟG, #y5O 08x]IWlyb)ut:UG"t&+LS]e`D.BQPlҿLt:U F"t_&+LS]e`D.BQPl7-^_':3&@E:;ɫH!Y ZEP.*g]n/~N;4e.Ai 60A3d!maxTZh=5>.Z7_cZx[{wy'W5iU?ݿG? n!ͱҳ?} (3E ?_T 7 ;R ʿ-QwTs&TNTuL({m B7 ?K?V\S)R 3/_7?}4ǒ3&_kf;!COK+ˬ K?s1PdQQEȔ_N L+xS Bڑia0ٟ?\Y).Q3lmVd @]jM"̋ż˨*u׻mz''d$=k=ƅ L&nW/_?Qw!iuױ/~>]y՟mIU E/'O??<16ʅGdБ1E)RE'ߔT#?J'埔RI'Ɩ1iO#8Uء;byPAlmP ҨsEC"QߔSM7ߔrO5KDE{E@k=dq;tek Όv8c-MW+zCeY]9d񠘂 uY!s9HLLG:EA1]ڳCr2tŃb 2\Եg 3e0%tek mOsMw^80v3؈ ]]&衏+-Z}ak>^+񐇓5]y+_RFl}vхul<ڭv{~J~+'K4Ŷ8<KO+qb&(&R5`_&KٟS$khGeLﰋYj%* -$ / y o;?Vj gZk͵ K4`̝W\~yWYQ6Ѥ6$^',c\ dm( [h* =*e0 Ar@Նڀۣr-Qs)(\m =*e0 Ar@Նڀۣr-Qs)(\m =*e0 Ar@Նڀۣr-Qs)(\m =*e0 Ar@Նڀۣr-Qs)(\m =*e0 Ar@Նڀۣr-Qs)(\m =*e0 Ar@Նڀۣr-Qs)(\m =*e0 Ar@Նڀۣr-Qs)(\m =*e0 Ar@Նڀۣr-Qs)(\m =*e0 Ar@Նڀۣr-Qs)(\m =*e0 Ar@Նڀۣr-Qs)(\m =*e0 Ar@Նڀۣr-Qs)(\m =*e0 *EoU H/_4*UOş?*VA:H~R[ߺ)FuI@g0*|tlMB(TJ K_.HPA#IԢt\Z8<44 e(heKzP ( Gb8YI ∛J[;F滛̭PPzu[8UoԿ/Uvh?018_?|JΦ\?@I!Ta5?4TN(P7]i(R[H|(oʿ)P )z <2Sf:-|i3OT F91 cNrr`g9#Q-F*s2t"|v)4h9mwX -qiiaY^39om5`᭱_P3?ُ?4%S_?+O  [NMn(F26ynySQWVYw?VYg-/G?/}*gĚTs |HxG4?iiU0DtR)@<o5 :rgP 7 T 3Ogea 聎\*'Ԃ3CA@G.jFYX z#Jz ~,P=БK=ZpFQ`(ȥRyB-8( k0DtR)@<o5 :rgP 7 T 3Ogea 聎\*'Ԃ3CA@G.jFYX z#Jz ~,P=БK=ZpFQ`(ȥRyB-8( k0DtR)@<o5 :rgP 7 T 3Ogea 聎\*'Ԃ3CA@G.jFYX z#Jz ~,P=БK=ZpFQ;>-0e/y`;>* Wƙ\VS05P\ZQVICbH?:*X)[6cKCW_}$.+B+Q= ߊ?)T e(OJ@7D[+/d+9oMRE0=L/ʤJ04uYrIF%Hlhb(h+C"**VB ?K.RI'XhBi0TE_QE'ߔSď'*?*hv1D-Ji.?B]J7t')5ij*>tW=5|,15/K4&5)#1"6",J????f!z3+$6 _ `|mMG%K7ľ d/rgI8rA/= eTF+ok _7=>A?ƟY^TjMIV/5/rdͿ?ya CͅB4z !#r"&" B?0> ) KWO2Qã/ջxSUCw1"Sg3 !3 <4zW 1KM__k({;fd(*CnOhܢZx|Mr[}BJ9u<rjalQ-\ <+AZ[T 8uo e,Ck:$۵7 q/h"Mu/PYv7BٙKS\$/h|QzR_?\ro?+Qb1a ?-E2__UE֟o?G5|Z\W+8҃C2G\9ioa @P(eHFQPz8IG2 ʊOOu D26$ߨ/pRmQ= 7| RG\ 'gidݣF;Aa!JO9|q○~? _T߿cw@4?'Dw}O5c鷯լ߿W_?ǧX?f2q/\4J4\REi. 8&IJ6̧i鯤ҭ Q89A,?B_8Qq2Ĕѹ,!˒h_KA,Юeh|qvPMm׿/Re~?!W՟ Tc  +F8B￱8@77=ReGgg~wcdM5&=ܿW H5U }lUlxV~6Dd@&{ !kh) ">} & :*d56䬅2)l0@!_k3:Y@7i:M|Tɐ/?/KYlPק4aQ&C XbP>M 4ep tpR8i:MtTɐ/_úw5a"XrgՐP#('MԐ'p$&>]L?_`_|厀m׿\t2_J=9ϟ<L%SSX~d6SE????߿7gO߿'>Ip}o7l:rƢ )($G|.k%Rd 8EH8~%QrLx<%X\oI1MNYw3RCVTUFtpQ!8~ׄ._.\hR:~ {nMtM@?c<߮#u!d_֑O+?]ttKR? /@2ϟݿ?4nmu겔Y5EQDϝQbgguY*gZkp٘E"ZOq@jd]R*ɠ@|IO4Xw寲7 _!?&Trd?~O~~t޷`ЋgW2{A?mA/߿߿@F9vE(}d}Y/rQ2_eqK(E|֗Q/(%#KZ_G䋢\.i}Y/rQ2_eqK(E|֗Q/(%#KZ_G䋢\.i}Y/rQ2_eqK(E|֗Q/(%#KZ_G䋢\.i}Y/rQ2_eqK(E|֗Q/(%#KZ_G䋢\.i}Y/rQ2_eqK(E|֗Q/(%#KZ_G䋢\.i}Y/rQ2_eqK(E|֗Q/(%#J[j% (Vi)W'Mr?YVLr49! ̪wFH르 Y?.m- WS0! \t~ ciV?~~$R ~m;ϟ~?OlTKLJ?ϟ1+|_ЫS`??S:\KD<EZQeLiӬ2yEPDIi2R̘!NKԖ(6ZU4JL<+Q[o&DJͬ$'LKiGi2M8~O2H+-Q (]"4dv9çP/"Z:=̲@/qp 2ƆZٺg}! `c:9|%"De˟ yo"M]Y%b/ fBgC럮_Z\?}~7׃o~@*$߿߿$RE,?f*D~Z@>o~o~#e+WVzԴ +u8ϧc8mP8 Qȗ s\gi8x(B|@N8~c8'+˟d|bI8ڵ&M8=$7ZWKr.B2Q'3h⤧TO4цI+BPIDr ?_.,uKQ?\X,֞X~H~󧟿#~~l!O~~H~,T_~~JtEugD15_בWq5$>T],IEi" F4BRQ q]h&ik$VOU(MX5HϖO24JW?S #ik$\z|R%#5Vu›F ?j(KFk.9}ҕ8~+[aKFIhw}u/.??5~!cJ{~{_/FQ/߿Wu(AС(!)&BO e.$?a*?9sk?$~"%@? A6A #!Rc5|" Cb y/Q Kj%Se<*)LZi9 `r/H +"aI]Qld%"?vv(ֿq]58:,DzrmC[rRh+_cR R%Fz] ˠժUK-] :!խ+ XVl)e?+H۲_|{ hP?0id_ɭ7 Q׿T,UX]?fWf8'w,3]?./7EWrbWg:2.NO䌐Y*߿߿2pDS=_ ٥ hx'_%%Wo|eqRiYu 8󟯿T3E"LJ*hBe-NJ3_|VUW_IJkQkTˁ78A$W 9z4Ʃ RWc}q l"J9~'!KڵcǝӜ~鲥˛o^)˪Wm-͚v-g~iuRLn'.6y∟!kֲ||[? eK,_L?8p10٬Y3(/z{^ex1v exG+6m*xc.Y"={t_#;Qҵ[m3xyg޼uNUl@,{?_{ٲ];Ybt]wT-HB:otR_iզd ='7`?9e]Ug!gkrC=7!X/~io?]iիM"իPz=x}2mkngs?Y 7T]jɒow_x6jTnic]wɤ ֙~FUmOiǟ^/?`2JV5}?֦~_ZPHֹg8lRbSfQAp!&uc;ij?cl+v_ա\w ?fz~?z|?r} ..7X LJTE?.Fw NP@iR0qƘ/lY\TWPPx@h^zdBSkWYb?ޅ|@j4)`f)bKuu3iOsÊ 7=̤IZ²oG(5dKh54f>a7oRFqɌdSwiRz-2x-a|uѺ|}{Y%_^#Pz'~ή?գF,9sL2U9,Ec?5k֔^G͡hP,S=ֈt"]XL8C37tʾD}0 &~ʃSn U>mçfƾ[j)}O/jY+ 0 Thذ{{H5죦pgnk4[n'7jt2U?{fï/$D hu ']_Gh tҽs5J 4ƎUw2amw?WO>Mc?uD[7H.,)?pa>~?Dj2>纮9;'ꞯ_~@C?Ji_󷟿FAJ?~[~󗟿Ξ?[)Ȳ+֕.2_B20$x Bq>N'-J9@یǐr'$BP84-Q7%uT([q?m1@{E. Uz&eUH Bۄ"}aL/gK' I0^:ׇ*HJ>}/^ҼYKQ<ȃ7lH~~,joѢ\=rndtL Qc"?S͐jo)g#5~K.mVyAeܷz#y2դ''ή0gsƌ2u* /*pG-4 Y CȞjTuߡC9`pՕ]4| <Oxa?Qv?Bv'_˕W>iϙ?۽{w9K07^aYje]f|S.K.ݻVy{9<pi2;k)1)r@.rf@=-^.o[+[UK N:r9)ͺNyי5E t_޻*۔”sW=w-/Ϟ]ѿt8K\.}?Ur;׿\uovGO`w|__zg|]r\/ ^*X IMJ~CM WxJث/TҤQ1+͗Xďӿ4,pÇ)o(* O)_=hẗIi||ūkJ)A(bE?.4Z%%.цqS%Mo`cY& id^JH\jfR~Y_G2D,@#m~nivKФ\Λ+NjR,п bLFpb/ÜڲbJyy7oBF?sT: ~a2uԬ]OseȐAo`c7oԪ.~*<~UW^t Oyj\ x3CTz|\(tGJ-deңg9绐4WA5ǧx5~ G;`@}=u{}MA00%rΙCJ3 (,\$!Cz㕺;NgP`?nTz^,Zԭ3!] ׀E ^*o0A>coxƿ&åue=>u'sUQҥ;<>@PF&3(qU#}PWwKɀ:M?o'[Q'& ~K?|Wh(l˞rMr.YHս’\\2OWDr UܒeUH} RUL’MsBHEIlWx*)T.Sܠ:%_J y*)Ti~@G+C77G5n y~l菸,Mc u&3_M u&j!nC?N4p!I5xDA%KpXK5ko=Tܲh\U.|<ӐUh[[!ァ4m4lP;̕^|A~Iů  /<; '׫kxΣɿ~Imzu>ٯ,wq'!-DwN_Y2~8i۶i?x|:sdMce i8BT2o˂/@~=#z쏲|%dڑia(ٵk߃ISȟ<23|w:lѶ,/o]za&W6ed-}~ 0W_ HHJ w'V7N 7h((>IOgsCOI&ۥ.,]LzSL_=j4o\>ϱ;(qw>$[mU:}X͝KRiGY:_oA]|cƴ)rQ]953x{ ~m{QZ7܋>??s}Ҳuk{̲KKxU{_/A?$_~ ߖmPy+_G#}JɟN[`|٧r3!S줌ϋ>q ZשWG>FiNﱇԯWO {}{8;JCÿ5OOSL! ç.]O}̜y'4K? zI݃ؿޑA/6o}-9ΐ ?dK';S6nt ;KCĉNvvkv9:3{F|%tv-R>xl]v >&OηÚ+?P)!8-_A"­  fw L!+TPA,b?.=7I|GJο&?µO?V߉.'OO?zp.KjjBfT B),2सJS4$|sc[PnVF@$1B9|Tȯ N\$ޢ@I+im@X\T bai_b2!VbN3B }d9>72t~~`Xn7<$S*'Z e"Tj` J kbHW_kG>3TO;KAϺBï/R7fHy/9 8aЋ&.; .)\4”z?2lAs]: \sl馕<8]u֕ ț޿s9sSπXBr=#MI909 _} TZU s%ҳg"8M cHxt;}D%&XH;vTo;\o! _~ߤSd:0@(i_{5 eJUW֭//0Ri`dݺv&O8/ P = | m>raGh3fΐ.GuNk ?Ip,4Ƞy:~1%5B􏉓n:ua^a$H"$$-ߞW>h9CLi; Q[V u3MVz5m VP&)?/I+akYף |3jw^4{ r'C vg.'bph ƿhbӫgs'xRΑ??kdMHD/4_é*_{kÜl&K.뮻N 8G! #٪zɰK/0bǯ`6.h,\~㌾|pX3` Ӏ'Ϊ?:)-?@gcWϟ(o%p;e`h߄CFy@IDAT 4 Uhj_0cgr F ?4|ju\ __ ?z-__}l\tk'\ b\*) V̵g3!o gUNe!0o0 `5\{fCB]QPI5J3դrap:8GrQ%jR08:8)3(%!J3դrap tpSfP1JBDgI3V0|*ȭ5I|Uav?N?EtJ=+$OU2;@Ru6ҡOQPoCˆY0'kG gACKc}ڍ{0`BKj90PHP&cͷH5t_ k=aԨUs}M|. g|Gm0tt޲x”::tD 󶞴nZ$V ^Z'+G $N[ɆMWxeٵ+4e(S?p4_L xf #s⋓^{.>$zW>N<^qp|^-Vz)<"@ƺN+[X3Q?xxaі'K/]*Kxg6Rdiz:4fulm{Y/ :l9 vOnOA[-o?4:XHZHMYحK0|C&YC|֛p"JS2^Ҏ߲%={#`4Hcol O?[®A!Xv俷aPA]i `  W@kO;xo?S |*+SY8v:~ o_ZP0>3|R rgi=Hc?&_4l@أ>OhM>m5X⧷q0l9UW])Æ],`8gx aT3O4vS:~μo,lҬY0L8@>7#=SƜ90\ [{F!70=^:8ka+T/Ke smf aCs 9@s0)gO4to'?i65oL̺[&?J?&5XBF5hisȧ{ oڴSM

~mo  {XETM*7h vsxU^{U#4Ҡ= 'M*{7GIm@0ʪE]"n/2@okAЧOQuuቊU@4z:ctr ?))*_ v>dB'|6~u5e2y}'lconXInK8?E2p`p>&/%5_0,29c xC>yϜ y>Ƙ?/ SW\.`d'>)NU aCߠ;Cjdգyڀ?q\Wj V3 X~4֠W/\ wl@Ȍw!H\G`(ʠ!h|Tk:~m415u;B07ĺ3:=Bmg3~>s7;> [I1>GarO VEhq&賿ou>ϪOM HQQ2o\sJ_x^/S 3 ||1=)'܋5k㏓ۓ{ѻ*h< xm:]?P' 10|?Cfm*4o+O>A ۖKbW1@w/atZ:Oz0;e"!OٳxÍ!J_5bЈrي_f0v=> ӭ{OzYC.r&c^>0R? O0 r.Mp`/mVF]}<_ ]`0>†9#Oƿ[ŗ_sM 9Ft'|B_bnc7MI0 ңg/ xYKA[rZц1R U Kz7I>QnzК01 %fO.UeY!7UA[yIFf '/IBf%y-lW:E1LqeR2p D0n[z0 )`O9X%ݚSzsFwU6WxИ{w~$3l "%(=B-_gi<`8X1Q:P|ԩ[xXmdDhէw/5ow1ƹ:g~ZsWAm%erjCx ?*Ӹe.<  1_n'c<P\=n{ȑRlarQ؊2490>J)ƍMِN;d:?W#@קA_j\ 6rfB}@m`ËH|K:>MQvg7?V%ˌJx0'N8i4 FJ ʁȅ =fiz|aǿp1!ߘ#!H>mߛ0=BiS=>C=>907ҐʫK6?yt0:O5;(oIƿMm^H)S&#wΘ@- 51]P8{9_O)'Wҟs}F׼/qx/\zѰ"d_m1#g>?r d5 Q0\Y318$ ~?Ư 2Whei?ipaRXuOI "_AN)M">#0\.3=O| p \en$ٚU0?A3S?￾/p%6JOX~fHl\P?3Y0V]OF勒ZdjS\A/JrVhqj lT% 6_bNPaT'٨6Jl(Yơª-.NQm4|QB 8CU[\Pd(i$gp :FQ`EI -64VmqAuj拒Zli*$FI%9+؀8TXI6/JrVhqj lT% 6_bNPaT'٨6Jl(Yơª-.NQm4|QB 8CU[\Pd(i$gp :FQ`EI -64VmqAuj拒Zli*$FI%9+؀8TXI6/JrVhqj lT% 6_bNPaT'٨6Jl(Yơª-.NQm4|QB 8CU[\Pd(i$gp :FQ`EI -64VmqAuj拒Zli*5<>efM57 Ȇ(fplGKv:0('8خhd&|Й /Zv>'L? HB+x|EO0|[߬EsxOçS9h7mR akJ2|4 |Jc~6`d}Q[K&NgaSK-> *? rz|8ݴiW^yEf_Wd>jߤۧ{ImK9\jc={@8~}Onʙ0}F1he$*ՁV|<fy'| WZW'x3"\ w;vT†q-`4P~}:#ɿf^6jtl?I'  ]ʈ/]OAV"чO}!Զ_d>Ӳe03)ugmnGI~'O wng toce:BJU{?? |MP?DWГ.^@snG /y6NJQ:d0g C6?YMux[Nc2c fU/Pןk?ѠjWo?]$\vo׿/O 7NT\U|/?'f8< +5&WR@UVSXӔ%,H5%Y>MY"YA$˧)KX+Jk K|EXR9`qMaIOS8CW d4e fr’,,aq(@*,),ia H5%Y>MY ]Q*TX\SXӔ%,.šk K|T$˧)KX\5+ d4e 3tER9`qMaIOSkV@*,),igRr’,,aq֬ TX\SXӔ%,H5%Y>MY"YA$˧)KX+Jk K|EXR9`qMaIOS8CW d4e fr’,,aq(@*kX xA%E_iߪE#P(u(+3GAy[UZiaߡOU֠B|g_aT@_rTQ]V߻J|СRW3|Z"# 9nV4~T)ߴ &dPa܌< K 1}zk۸qcƛzur0{ ao`񴌻V|$Rc2<>Vç7SFJ_b!c=ACD0~ΏЃ$_WsB}=2ixtƘtbf#N6O6~>T^}HA"ԋ/ʥ00gA_r|r-V(x|;SO  ya$pCPg:[#8 q4OqM KO/xr*2 ǧ@Pį@׹K|,Q2h@>c5BASX? @:IϿ\AB?P{o.F7 D|k=A7kc(y<MƇ$U_òv8:6l!?kkaP׍Q6i 4ʠS?z <>1O@.1< 6jxz[!J߸dرA5}Zz8. $_~O^t W}nD)qk(~-z*Cd=vWs>KT`n6Mj͍7@Mz 9H?3|ZtE80 q ~/P/h䃷z <m Ex.<>7O!|)OzuɤIuv 1lV{%:Œq&֣-w*}.݋*#& B >Gn:?5Q3)XJT} +<X G0|j<>uԺMp  UHȧ(&Mat PEX ;h- :"$}a6~ny1~2̙w)(eïJSD 9sqL2(f0|5.Q4EN 7P E" Xewy|Grq*z߼L_AUֿ ONA'a O VUֿbrN"O?h1CT7Rnn? R'm'w׿ $('/럮*ҪB2s; #P$7p~?$~DIPj I/-1j2A8Y̲j"EVƘ+m)+8a+%˗7Drž|O\KOya9#%ZMcp'] k"SXIG@Kyď]d(tJUoRmÏ[m#۷W+ګf r?i }'~AJ/Z0|`AAA߬E  /9俙3a2ej:/g_?@J|~w`6tS ;gk> B D@I/>oƿ^{ɱ'6h]|Of92Yn& ^hPHY*x)>J47|^o=֛g{>[x~^yU.8$O_:߉})ng< @Il}iSoCt8ix}X_q啲51t=Yɯ크 rK.,+Wȧ~&#_.RGӍ6aF`LP_ 5 4 pmO[n,-wa}`0asy҉0TMa!^ x#8,i^OÎT~}shӟ*.?Am?dr?VyPa?~;J'7mڔq@0ZF0[8]un%0v4o7gL͍_3 &gv+M> '}go'hnd) zvw@ꘀE  @bdv#`.|BmxH}NTqcב>7;~tvҫO/([eX+e!~N.ؓ^:Bq3j"lGç#+Be&G{ɬY*چ_>}7 z6m!=puX4kIO?0xK9 zxe$ɿjՖ4{WM>u!BcTu'&OR ^w`0B?>)צ_ 'Ыn:W_qKY%w%hd#?A:/ (aec?p@}QW!Cx+À$﮸BBF̓O<'IZv r]w7k.@`7u* p/Ox0/2?N8? ܀@\nƐ˗T0|H~0(cx8ι3ʤ`CBWttqGxWP;Vn _fHՓJ)jyzO!ݱ[XQVw]5|hJq&B!ծWOvgr06mv#c?RCڶ!Ͼ'{bo~B(QPǽDlW&FŋK=K_6ZkifwF#0xq5'xq֭oҤpX 3ç @űπ?}ЮTwC(Yw%!lMQ 7zK!oSGwçI0b `0I絛?^zЦ ]ϪsDOKs{P17k7Tۺumg`/ ^3d0f1fr)BU]aïϨPQ.Zb ̛r| &%~U!?\ÓaT:/P?T_~e/?ϟ 4˻YV? $* 'MXMA}^X60 U4.3Hkq jiA>N3i"\"g҂|"WfDD )D:ͤN3i"\"g҂|"WfDD )D:ͤN3i"\"g҂|"WfDD )D:ͤ_Nr=wesU&<>р{if͛]w)&N,ـ ٧ZJuz=\0w924cSM2F#KtT ?"C윞@úb̾!O.\cUk{rQG^Yqg[%\c e4͒ ?_UzS\͛5d<{LhD SlO $!'M5jd}תU wq=*7CZL//L jz߻'G#S8cç%0xyR 4o6w?MOnFØx{rXb Ho[V4I?T:G|h!.b%FS4څOikBUc1ʤR*vD_p푉^qO0٪HJpdAo9%x`4_?cG ?#Ur?PEePO!~),͕_U +Mg}i ?WÕ?f-Jh/cF~orŲ7`,uXegׯ/(-Y,xK]StvOeL!XlTF{ihdjHiMc3 s6le`?m Oo4|:OLԛ ~iq wMd9ʔ%11|b xbMema7ab0|BB4Ec4 =uGG3ǴGjW$9PoZgEGc_V_KNzZjD`Ws5N_|>uD@]mٷ??.}bP=pk */q O0L߿￾_}_Pd%!d?Ћ{)XB FIۗ/bb]T4 Q51641KPAHP~vvvvnnvfvF&buzo LBmc?tBJZ%P4P)7M'B6ZP't6C-!oG(O {ڑ=,sae=i/4=7 {t7Lcxedmv=6ybx&[Zڮ֞6Vo`]lT)]aP,XG_7\t ; o(O;G_t1>nR |&Zo[r' 3^{ƀY/b]Z܅݉fL/M8SfV-?]ExfӧϐYN}q)ꄾ jg<ɞs?K2T2=k\2te,| hǿF__(/kl@Qk/TWXcOCu_ <8ի1ue@IDAT;\u =Ϊ,W?;Pswklڴ27޲]8Lٸơ?u駟iG,|µ`A6aKx3oOgaI8jI' s͕^=zY/M֚v!ƪYk&Z9Εc3X 29߰ShkX?HN94;z}cFLUVc;^z%}ae=.>%k\pᯥjm&`0UW]WF?b0.iC,(\^m+Neǧټvuƙga1 ~qqox>a'5ܴ.|zw O>@*=tؑvG+CMrI Nu޿oG xMڿd:>Unʞ@ށ$grvcŮVx& 73Ȟs[|#tAZW@ K3>7\ڵoo}hJ t$3fNǍn\ wM6‚P^/s۱Kr^7/믿.38slqd7Mˤc.,8-ի8?o%]zo '_K/m&آ)Slv@яa>ǡ`CmN?ݰwBvzg9j= .&#nYZha21.kd5u7~i~/ 6Wc_?C7y$a2y 7hn5kH7af{a^h;򗿔XgJc"A>5m&'M@v|kwYK.W\*׳O~n&_'tyfLKk[v(^t3Q9HriEm#ovRt {kow~MNU^D5֝tA\ˮ' 9v3>uMxœCugrg)/\8 #hhh1 JGCe|ED< &jWkW0_-&p_6O?$F}Ǐy|Ǧ'P8M^Lm*ST -9JqZڠ< ST Gi"q𛲳b^)* 8--Wa^Jᜓi/sUR8Cq%ܲ|楨9P(mi2,_y)*sN:JqZ-Wa^Jᜓi/sUR8Cq]q߽WLu =~/}T@dy+)ՠHBQ_,ffS7Gܲu.b5R?4>ߐ]4)'sy֞9;{-2,y챿Ï]v] mP3|p k0 ou< .6:=~H~lmuS݂*? O=-]]&Q,D3N좤 ߹SgaT'LxUN; kK ͇\C7)al#{f[zC ®\y'vp@={J hÞQ-;v.?. YM+a|↓#G]6jZ>N#Mq޿Qs_| ;"+*hvIv=ߦOצ$`ǝaَ;,Okevg^>j%,FH6T*޿߿vnq2nrݙLJgsvΏ(J?|cvZ GtsםkG);9q!zvd-J@Fe<:2iɟ. <˅&M1^_bε v'e.]ӱX4m'{ tohc}I^ê@_w MP  Xki옱FU6gcoڐ6o;Vá TzaHMn:{HW9tg]_<"yV?nwep- ^mbMegb~fmpgoGN8),*Fb֎6CU -v/X]G8OJqZ vvskUvpv!B-k>/MM14|Ľ§Xl>X9/?ݹN Qr>v SXt{ebH)|Rx&iv8lk UT󘏋vo#^J@§u txG2)־@T`Ƹ𸔃g>EA/V.)?*Կ* QGnއJ ?sV0iACu 7h#hiulDuEK߽"?:0x[R%P 4+-DK[~qo;K N,D#'(f 4Oˊ4\')`RAC nrTb.'ڟDCD0X.| C^fOӧFgH 犠Џnц~eYPwmyJ0hgwvA.Sߒ>[P){cw] |oLm#,_d~d!ĽN+A]z</~~[l jV7BtI;B~{," 0`y嚫4x|I|r`~ҩs,~3'e01/hf5~g[[X}kdΜOdčPV[c5weX 4ՉN8";_wyWi 9Џ](@/C?E aUViSsSɥî.8 /Y<=^QێO+. s"/N&A^| pᨑM7OF.M]p3\ir'K/,4jy/rv5q:Tu[mߟƆ9X6#_ _9C8 |C];\9|F=܅cyΐ*1Q}GCLFnE۟SN>Q&NP9 ױSG wvRYewߍFd${fy{ y*[}1ع)a&5_:AW|zW_?B Pؿ?)v;뜳AٻnNҪ5t"v ;"_7aP?)vHAjW_§õïQVm]@޿}by ;up҉+]zƠZqJt)vRWҷD^:l֣ E;Xy7wuSqV vzz]|ߩsXλ%OjaW_X/`ǾOկtV'-aז>m#ӡ&+2t/<\d(޿҅FگN"^*~fKM .suXG>3W<װ]axi3@ί3V u$YuW忲j**>X>=W۴M6D:u$kڔ)&s k.k9|*6!^T[گ+Uu*ҥ[Ys5eIɔקTk\uۿ%w?M6TV[}5K&Lӏ#Z& 㬋`S_'λ߰F}2w|t̚=Q ;>caΧs`ƲF?EZYN6t=F oz{d]ߖ7^{]g#|cE?l'^ow<_}U/_c??kE5cdʁUQQTo|//dĀ8?_}Mv+z;p8p1ȔK>%D QKhχ4=**܌) .,ўizU8UPJmpJ,.=p{͡bX\F{>9VTC)*|Hs.5RjUbqXS\k2!Mϱ J .VeCcNpy9R\hχ4=**^s(6X%ўizU8UPJmpJ,.=p{͡bX\F{>9VTC)*|Hs.5RjUbqXS\k2!Mϱ J .VeCcNpy9R\hχ4=**^s(6X%ўizU8UPJmpJ,.=p{͡bX\F{>9VTC)*|Hs.5RjUbqk3b&QJ?Zz5Jj[l^wEŖl/|ʟt|ꩶc=GiѢ4[iϭY§F®bl}ι" W;XwヲK>6hNJy/$ǒ_Up'٪YahlZ%/QY/_}㟌rq'矜2?*h O1h#'/+㯌c?§ I$2{d `rNl[ xi T3RȊw Fo Jx䜔`S5*@p~t~ +A&礌0~p2LyC9)Tߥm~1t*u9O'(ufYYP\JdsiGe0(e>HVU?ؿ_Qoںgߟz: %?]qvY?}!3聲v|RwpeΜ[w /uҴT:p `j:`AX8br(*&ylk*?smShW&l.ZsU!-9hڡ,|Ԛ[Tc9uG 7`םC @ >YS1^<{MX {~oUW]5unD.Rۣ[i;?ALa_&W?QK A2E'o9/?/οr5uuu8]K)F́U؎a`YcPN琧V\8< ׳?!}p1O"Os:"m:AzOy8CIZ8}00@!OCyJG!g=(\N9$-p:Azփ@!OCyJG!g='k3Y+r4HM58smgUC|t`X}x=M__&":_ItߠoB?UY-| Ï|mItʿ!+?.w{?=^{ 7JUۚΘ9Cnfyt7*[Qu_2oP0.#M7oHcE+!339_I}Kե /0AG'߿t@7N!ƌ3R+ߜxmձyM#'HE2r[+ œdD| 8MP2J]yMN$ȧӴ,S+(N9Lfp4`$64\1̮ J F0raΝJi_D0?Wyt^RZeĆO #2" $I)3t>)`b9H0`0X߽)YYYC]`C0[XkhRۊ NJ˺0M'U!+ LRp*S _63?0?s83s?So?(2k /dZ"?0 O?*e1(dl, a11oA?yik.\P_[$NjDpZ氧)}N)Rة0AQWsZ氧ZeRS_?ޥ)|HT_ARp^GCBCSM.'6LSvʯ׽Woh܄Cv΋p Q-j6A]Eg-E?!P*fZPׇoj A??꟠KUUB ZG7_rldfB-DbGU#0+a. 2 )`WE_U'_ѣΌ?;'o??2#j0r׎l CY Vs@6做pd%D*xLBs'gq-"?Wkᓍ K(s{YgJcm??_w;>];5FL&[% VҲb~ Tp(Y6rd 2o|UA^TRt_6,`?O9PP@t03 1>c2%t/PP ?3’ C=N90ƿt08l̐`7Xο9V?@!XГ9d r /pA~P11X4>c%2mB+??f3 /̞'uGv9U `(RpR)sU\L&"OSˆ1fx1?ߐjW? _Qƽ+o8z WgN,j)/P_L_).CBʫOS8LYzDAPPU_Mο8 ~3ߌ?0o?ڌY͂~+ό4$ ՝ANfTg2;3_A QW__S:|W7]Yaûx9uNM2mv:UOe+;rP\< =iUW*ibQDEJ=i'OAFR/{mf%YAd?I%xi^3SRxrep0`?/AW$__2PοfU4mο5F?0"; U/b'Ɵb'ƟbGm.#13Uv|ҵOy8P}޼,;e%D)k W Ee3 ;O+JRO0&Eqqqۘ ;V,/d~4#w=qa/j\82~H3+pC\*rHp6 5j ՚G4Y*(QUt(?ug^*( U;/oաYF{LU6t:_M-IESuuN_YeZm/ך >ud4qQPQ|acJQ N顲D'o y3q ο9oο9āO>\4So8L&~`Ɵ7k3㯌2fy9?/\^',GvjYh daPf&YIǞ(1cv2*7PLl pr!ScI@?T1-a%S#9g7ƫ#N8 ϗgL <Ԛb7kPtT>-Ǽ4׭LZ-pr>h;W`hu?O *gؠ'_BCQa)ο8_0WPJQϚG(^ O_a_a b'Ɵ.d'GiNb'Ɵ\A*E=k`HtxE??e|aB)Ig6tGJ!SBE"T:+T2P)S 6d|z;pDQ9djT`y!SYXo'_^J1*L_EP*8\tP)(BzE1ϗƱ 1X\'y]d5l^Km uYVi1n;fCqAcPP-U}@K%s!ȘbcF?ØQ^7|B[F9cο8/(Gο8&ο8o(d Rο$*NSLgj a(/8d_r#Î0R``+`/,KºZ]T\Tg)T\S x+al{^tq,$#(L?Og:J%Fa bgC#մ?']|TBM,U(ϯ:ul1Sl.]PfU|u?Vb?d3"Q=H@ 5/g`2R=H@ 5/g`2R=H@ 5/g`2R=H@ 5 "aS]r֛7gGcg,h4E:AU:0?)Hk$/RH?@_E 4vƉ8GCKCKWp C84ay9\Y{w5?Qv&=A/A QB̟)SQ(/h*霏r?xM?)E~%,b FL,)EVgD4BK#uj%(׆zu]mSV{b#UPPVw(PZ#hWN7_̛;oߴiLjdt<*qQQ]PY`(`k s*OVSKY?t[}iӦo/"cV|E_G|h*:PxqdlH-yo|KU~9ASQ@$V,EWZ<M Rei |nla ,Y2ƍ?\/rN90X0g?ՆD62 G#@_է c/_L9d'')fVաCqp_E#_d7a & oT"jY&Aխ@fKu<.y CKYYD8T&K#òV/>__ĠX:}4 (?OJFa (Z j3m_1qͷW_CV¢'yd҄WeWZeh87mLv[_v*+l%:šΙ3G{DC?j52A& c,c7\3K :L??˳U\o LdN*~:'wCkjs7ߴ/;Io7 .PFXp%PFx$eVҡCKI'Y|-ҢeK5k}=ї_zY6=4عhRfΘ!3O/[\y&t}4b_Oduױä?L N§%R?_JqG%$Q3RfK???jT)sY( KcÉiXiӉOfkjsrni=Pr<_iVDOuPjp*Mtr`v;v(]>m[Ge/բ.СC>g~Xp+4kcQ|y >[@fN@*O_d=v7y?#wH~7rbiӦʱG\cIf2y$t҉.|kms]wH,|?ǎM§Q,+oe3D ʍ]6OI'OZ'?I'OKw| GOHVySyI#䀧y (4LXYR9iE9"4LXYR9i]H&,)c|H&,)c|4 $ V1y>BxZk$ V1y>BxwW +Kʘ<!<5G +Kʘ<!<ͻIÄ%eLV#IÄ%eLU@aʒ2&GO+zaʒ2&GO*@0aeI#䀧@0aeI#䀧ywP irӊ^sD irӼ (4LXYR9iE9"4LXYR9i]H&,)c|H&,)c|4 $ V1y>BxZk$ V1y>BxwW ӒXT@I,OW)kjSC-:AMZ?9t Jnǒ޿ƾaeVr)ӅO?t= 7L@߃iiWccO맖j_\'W?ʟw????? d_$ ? >~?0tHۯaOުI@4\O:3R^ilRb.qzgeÆI䆏-c19NS=88 ?q(P+bCY~\NPcPġyOX/qR S6!FÑ(SY[q}ݻt북mʔ)eC<忾ls9ckҥl P},˃)#LS9m/qK>-§Q?,|꺞_>Zc5٫??j(Oa'dYodio \Ǩ1c>M5§ )'$8_CKxٌ?tdqP)2*؇/ ?8G|/X~| ._O]~iȑMJXsnLyXkиc=ϕWe%a0y0R]DE:c=MkNԫ?Կ~C,Fo;-ߛVv^zKyȬT8Sۖ,c' (U]mk??򿦦V~ßHm&gO~Gi.\P.GCKoQ`Cڶ|ڛ+/g >]wމ]qtqH󝭶o~t붾4oz<Ág7}GڭiZ>S8]|b/cnM~2u,g6u v4_vߕ5ڭ)|0]^yG+_M6ﴣtUZZIޞr睷EAOoETnCۊyM2~ߐͷRϛ+7i" mW]գtԝAqOR>=;zK?Od7΢2y/<篕ViޖcPua equu>]tg삳J9~v~y7!ߔm^âYfӐqC?lӣƲe߾xأʔ) פI>3d˜O?ɨ? &O55viڴL'cmaI*!/85)3s9@CKS?h3_ƿs U KgMKKs4M󸅆phiiiuNB/]NJ_M]}f,#0tc'|^Tz8ADBqDH\%ޯ "c&E*9~=NEP3(W9i$u(☉@J)_O#DD(LUrNzI "@8f"P$sJHQ 1"qSzFR'"P(4:ADBqDH\%ޯ "c&E*9~=NEP3(W9i$u(☉@J)_O#DD(LUrNzI "@8f"P$sJHQ 1"qSzFR'"P(4:ADBqDH\%ޯ "c&E*9~=NEP3(W9i$u(☉@J)_O#DD(LUrNzI "@8f"P$sJHQ 1"qSz*T(x=opx}5bjR%iOk2yFvw1ξs 9/>5rS9[iYHMҲ?`ay/TvX.GkNk-g}lؽ{m+,gLY c;Nv;V='gyfteHk>p|?CRPK.D{g,o}mб |Wqc`QP?;l 8 |<kC/ eg=#}Xs?/Kj^~y9κk[N"ꇺ)?)d6=&ˮv~qXR[g#y٨G]vz+Hpri;.u=A\/:R{];SOol^/{{G'͚4 (Kv{{wY>\,[5c^m8{OaxFMނh-e괩rU;RG#G*\8r_^y~`$?J5W>(o-mܶ.9bDxV)PG0Fϻize\{0sB*x"wur͡EzM-cONSO#mox˻mÝpۋ;;xqn4SQ%qQεBPCAm |аE?Gϊ,@Gn/df@/F9ښGi ??"ذjPv7vVdU 7:Et/=fsdqkn{͍K?'Y}5CNҶj%#P/Ȭkz,&[?}JSQ?B%$@PQۧ?kt0}{3S%btUNÇkM*?W_{-lv;˼s^ J{َ6c>,`J7-9Si)S%vpҥ‹/ʙgjJ*r)'7`C[/0xeW7H@쳷 Z:E96p :d]tsiPk v; _ndǘ '/ uC>yX5@Zn)ɃN®8Ф҅5k.7r4o>͛7L>P:A:t^.iwl[0;T}EaڷfXrɳˮm} =넉eΜ9K6m?=K9`k_i%w-|q˖I{c '(Ѭ:ڪm_ÎD͝gs4`9"U@_6*vjr]5în}y˭mLv1G b-'ZۙMs~&#<ֿS.'x&a4>=͒V+aWN;.?v+5on>6r=wʈoBZ0nͷJ-ZB&OƮSBfaa\5W_-OvM @ifWԓOB?rjX?v U?8pOG???:y!F4Jql B|PYdqϜriJ /Ֆ_8KWvG_mFVKS(m~j0';ee0>9Gc:!U F ` uBP)7M'!Ѩl0N"Ks +@N#KĴY1g~ `^ʒM>zn"ta_Ν*ȹ+sI&d{jk`DŽSmrSAPc v%;Rcv\?_E߱S'o7VƌQ?|!C^m ᜌ[r~#ۯmqکX2`0 'lս+0:3e-,y9!SoYWNvQF~_]r~ՅOS>2";>e a)??G%sE^~`TN?^_OXJ£pHairgʬ>^ja]ur.vzb~޳0`L-Qgsyhk!?^vYXp̵X,?_۷ݐ';#},|Jکi;7YzFa GΓM6km5\CUҬYS,Z '⾓BáOG\,;jXi'M,N?ǿkCUG[}1o1( o2_<#/0|G'oT1!9S|F]yAC";ro/( %,z}}8/^Ml)PRLm*ST C66N*S[JyKij^)* 8-/sUR8Cq%ܲ|楨9P(mi2,_y)*sN:JqZ-Wa^Jᜓi/sUR8Cq%ܲ|楨9P(miW\wG_K3K>+ o{͜46,/ FC24P8[Z/?߾ߖu[o'fۮO#ԜٺSx [l)GعoFPg-ʩXǓO<ݐ:_Zw=@InkH<\2Tuf ި_8lagƍ§j\9 ;>/|ҫ [~;>kW+?Ϝ 36iҴV^Î:'pw|wrb{GNb;Oaa.I t]/ qFEvYf40쌤 ?Ģ%,޻Oz>)Ue=t񔈶;,!Qצ*r֟1G@Ӥ^;m2t< [nV-[KaQ.|.^§bE . 7ݎ:|}0sv'+,|jةMߜ~nb<zOBȗ^4X|`'6a9Ii~._^>?ߟ|>H7D 9ˣU mW<&R93uچ(oiqÍ'*_ǟʂ?a 0²' o۳۫,W 2h#PQ'<ڲ^@S̥?OKAIPlh4qer\ H????`R!yj1p^O>#]/ћos+锹&TW~uxWC[i AkeW:()b%֗޽ />|G7mWmZ_ٟ0^M qToE?lSة v3fq5h(qi,_'2%Oѳ:ywX,߁'mgΘ)#G@ݡLG7Կ-Z̟v|Zt8l3AvPzche1lr Xw|z*+\"ݺv{q YLyjuhCKK.2R]lUݲl< ]vuWr5X5{;[}Wwp>]>3G/Xh{Z޳w[mW>`O(Tݧp~VZﷰH ;i~9SGaH[j!]v]*kiڴr1QcڎR&aw~RGO.8⫺{IhIśÎOW^pO#FDmS[Y$??O?뮗=h\ghZ#U3,8U9;>)6),ƿ^?hK+>ŗ?WP8 zTEGO 979?s<jUU///@_*/;/_!KOsphQU Q%?U6kߛ,&ݖNE 懲  @?ɏHF WP'R% O I_`*_.(J{%0UJ:}{CvG3V#ݤIZ}I6DmΞ5vʹjMO7[[ޛtϗT 3m_D}.NƍQَOr҅:lS-z;Veߗ22~x4Zr)v||nV*Ȍ3c1 ;GeQoJH`'=?׳6;D;ߵ?_Ȕ&FpGiV{@u7vg?vm=,5.vkB.{ri75k Ana(T:],r~b&*CKg}F;GI֭d[ӰI}F'4i (QO_+|oMګܭ;>Nc`o!8^w2+6\8L?= W_suA؃8ԤbSX$~=_O>R^9waP9M4TLHE 17h|Ko?A=y-J'oߜ@ {.Ns_?2+c!Qe3Yp r5BTKhχ4=**P. \X\F{>9VTC)*|Hs.5RjUbqXS\k2!Mϱ J .VeCcNpy9R\hχ4=**^s(6X%ўizU8UPJmpJ,.=p{͡bX\F{>9VTC)*|Hs.5RjUbqXS\k2!Mϱ J .VeCcNpy9R\hχ4=**^s(6X%ўizU8UPJmpJ,.=p{͡bX\F{>9VTC)*|Hs.5RjUbqk3i&]*i-zm2U V6B82Q٨!΄W^_z1{9׶a'iJ=wCy{ +X xϿiS2-iډ@̙l H8jiv3lXX>:>"_ \2·Q;oO;-:]"럅 ȍ7 ~CgaSc#I_N˱xFcǧw"KO-7f v@R~orSءɏ!+/*n ȌXo?좴rrUW<`/WqӮXYgFyq2,!#n?_d=W'ȩ _oe*A〇4ƎOMmǧ إJw|*/_F?_ogQϟϿ1'?A+LԏI7Q_n8zCPC?X#/@eq訡m…uҤD2䜔YW1˜kaEV T6o Jx䜔`S5*@p~g.#NXsRf?%^kK+90`OY09'e?0a ,ɚW_׽fK{:"꓇)ATm6տLecM~fh_69ߊ.][JzȤ2#mv5=w.x5i.;4o2XeʔIsP??3?s5Տ]נnMw3Ag6+ #n6_:=%t>}Ȯf63i y!+!C/ݺ]?vEGaXv§qrԀa27ыh Ov>x,Co襗Ier~ͪt7x#>fL#~~[ߔAN{o@9 vOY}(ugCgc't Y}Wݿ_?cϽMbӻcا'v;[k§ݭLw|B5Z@~9].KiOSMcO޿?|1z,vAI&)'b٫'x+4^/#oQmaǧ+Ʈ#n*.nhޙ {RfeNdurȑZXqw4iZ+&LETe_ré~4$r/b[ `MpPϲm=_MTѓ6_R']@'MRV*$;>0OfLl2T/(+h>+ `x\d$yvTOS88CTPnPD_cETtR$E@a,}j=d RY-V-(bII/߱"Oj;5kS>]~ -[P8;  P_LL4q551yY41'*Yދqkxhh\DT$QAٙ:UNM@zSU:u~֛;_.[n||K_>(h _3#I_(eZ aɋ:/:-o. /&ev{ ߋK=O~ғ/rAzGCΘO;rQ){\[G^g)Wŧe&}%?}KU>E^N0 ^rGkV?}{U%|]e/}<[ŧwx}i)| uk^y{-^/\v/r~|鱏Eeg?N/.zsby4^zO}S˅3WgPe.8 UyE^TOѾ+}\p~W4-*/>^W"B8Ƃ 9C=^|zUZvY ƥR>'^rKy_'skúsŧO?/ƟCߡAUaWڈA(ĪO ׿լ?/?oߌ?EM+1b0xş3 Y˾~ߤ^yw/ J=5c,n|yiy'VMNyi{dz8B(huQ&_t (pΝ Z{l?C^ZiL8N=6Ɂ!/]B4Js'V@[,s;NR}4MsDKIWh n ьXAwVE}>He7!06-Kqү5 uWO>~*wg嫼w=~/͔w^g>-0OQKkb#+?,V^7?V.XfA'kQRsR珞r;^Ly_g=wGݻv]^[~{|y)9\f\p~y+={+_%/^>!s43(GK]w.y|I:ǩ2(߿_>կ}(E)_פ%~l/W^~L#2>Yt{ˋO'./>f1e]&2 #_9b?&TyN?po{T_d0>;| WoḠSv|2*ۥ+1֛Ug8Jy؎~cһiW_7u6s?mBƗn'_?jΟM ʯ_Ӌ?C?4dY"E q\`ΤX%04/_ Roj~0KK 9dRd$cO f_|`ܬNQ5F%%Chݑ4H`˄K]ಓҚ&3wDߔ?O3u69w8h\9Tr-e_psظp!F>Ij96D3O:-f0.D6?nc!r/.yӦr{ٺu쳟d7.wrUvʯsQ1$KߺP~_s %5?1\uƲN7|\u啶rQG 5!x_w]|g坑5?/'pRyIg>(7oVT9}j͊Oݩ=M# 呏y^/><Wˋ_|Wׇuŧ3_g7N^|1_._ڶm?=˿(==՞xf݉fhXŧ}8gH^ :\+_z[::}{%ŧ'G_-=={_%_7G򐇕_'׺.V&wIO/>ݧ~IsK7:sì^?O~# ;5&q/|*+*g/Q^h-ҀRwS9-o1*wLy_W-R52[YgMPP ^z6^{g|jOg#Z,?M:^nɝw$Ber|]=zI9>d O=-9,a___?\A#Oڎ/ Je[E /_tȎ/l RI_\߁ZI_7d9i9s52nkaR& [X^Ԟg\)$4'7%e9h rJ 'OS|D3 $ *ei~O)SyLR& As} 5~;xy;}A+%3{xHN< nHil*~r{ܫ!/ϗYyѯW_]/Y(=]>ș:얯NrixMh.7r Lb"\2ZNGo[O)>f` y (|Ur}\y0\+/Am5]']gŧ?.8%Y-y23]`tg]J*5lٺYjE-iR.+ŧy=<x%8-JM*{v_[6lܠO;#p@3ʑG_‹Oh ŧW+<=!YX0=IKޥ/t' O~{d=SrY_Kcss\c]X/E"_z>Ygǩ$w^X:Hie (d4/:}BÄTkK^r[B˸?@ ._:[xWv/7QiJOU/>6 @  'g zF~I?ǂeꑽ򕯐ު'ד26>^{#eףFڷZ]˜甹c1NOBo豃q8>uCY/z޹S=T鱎Okn`|c.ٟ6?>O2!H ?Yy[K_?]I?/1cϚAd{\H/]aHU h 0b7_ޜ쁢uH F04[f6`IL07@8>OKsIL07@8888QHЈ :Isg_?ŧ/W^$fl I<ҤxwcD? PXS{i;̿}|3gsCnfr Y͔kMԿyT*?!kAi@&| gɗ'i;QO?<}-[ŝǧ?gg> />a oߓ7c LxW|'=(6oR*_,r@K_KrJN_@xx)]-oybyi 7ᵯCݤ'/H?.օ,y )z;A9QGަڵ<K(e/y~{_"_|‹Ox`y/ 1G~_=%cϼh gW8{?Nt*.n?0_/|zU^O?.}i`)!-'~'˼//OMӿWkʖ-o=E^|Z;ޱ<1+[>>ז{̕SO/>JYo{N!_x|o! 8G003(o^X~~S=IVN>r(cN>|.7Q^^|C=G?ǐ:tOiS+*WmGy?//Os_sh?p=d\)"k|%?D7 bC(`IF ٙ Lp{UKƒ NV9>*E;(Dɀ՞2);_?\eje6Y"6OT7^n輜 5ԭuqFW@1a9&Z)G,>T'0oB=*_~yן-"fL0#dE / 7~owr+*wr_+K?+?z˛w^S.8|˞k*GyP~5\j@gͬ_w'^&N(|o~|_(W]u 6J:$_5:HA~pgcr 'ȹ bz\o[:]/|Ey_([||_5ֹ~ɱss/_||S._2y|[V_˹[O3kkD(*"?0 폪]?\V{ ^?/_- [iE]C TK`^#}yQľ62ңR-}meGZ@KJ&ޗj Lk//S/=*z_^^zT%0 LTK`b_}yzQľ62ҭ@IDATR-}meGZ@KJ&ޗj Lk//S/=*z_^^zT%0 LTK`b_}yzQľ62ңR-}meGZ@KJ&ޗj Lk//S/=*z_^^zT%0O!/> U5z*@''_GAŗʘ #!dR reA`|xWu۟֕}[x+_ǔؖUʺ2_p /ȉƈ+?=z#jYPWpoL61jOiL\#/=M+?%֡2C1 gE`W1H|7ox$Wh&t+3&A%&8[GLBfVjFˍ?/NjJ?v'$46~g\4w]ghha fO_4u ݵ0>EZ\߯J }1'x,F운&HA/5>宿q _m,_kn}Af8>b=>%nO…r鰫Կ)1! k?D6??afְ`.6Y4',$? j"eViu"//oL3bC#A' Cf WҗA5D 00f~s[#((> ㋠t~rkAmPGPJ`1Vp,G31(0תsVOQ8Dڌ99T#"iD 0{;^|urӇ 珈:)~ȿJVyMy7hFFD H@K8:㋌Q7%n:bٹsWټy3HM_%餏%ZfCl`j0(-5ה +/7vU6mڤ'29cά1qu[{ɥuз C߹sR_ǮɱeӓX^]b6ynf=3߮D%Kgϟןr>V3kw6J/̬[%nڸQoY-%Uoz"E⤵17L??u5Bbiw݌}Cv_+/l ȏUڟݢ{DL/gvɃ[xowC\?;z+?}MIޖƻX+EHt5w<:CxWp5we_'hf_?'~e5ߋz6ku_9<.?| |5sK?x?{I />Ɂҋ !'lջxi&=Ez}/!F\ ە?'/&.?.NjO[$.>ȏ`Ll8c _Rtji\o(:kڃj WHpc;{:]kuPCn/>CfbOo(}_pyՙ& \O^MyJFk0b3*0/o 1㆏?$ǯݼAQWt_݄9>[m=9Ko[h\Bxpf\>Z 9]zY!&@ WUFk(O:3Y>D nUeǧOZ,|I8\Q}X?

g+Q{pqq^ [>p=İAp:˫  `ʕWuSkȣv-;A# m8 ˬ,y2Z9z*+m媫cߔ.6O#/dMocO;0ֿ-[?|f6gC XȚi4֢+xvX+z¨"VM\ӕ__DRei BT)zuL5]?v]۰l]BJ3ӌ '- *Q\e19۶mt3.]AܪVzV`|p}hSǭ]^V5"": G\_F5ϒ` :$>ؗo?!9.@xf;X8u-P)P;;JOш|Vg%__?\2 oFCd q)o >`?)ea! 7^\Kl9 'rt/;G'kG(ch!z3 8>OA__Qj|В_nfiާPPA+,M;I[v~O =llR$=LBPҝNF^yY^R6ߥG98h:+2î5W {ͪ\Yq6S/GpsA:r _Aַc|._B~aZ+BsԿ:8h>v(_?\9dfi@7̿Dhf'柘 o̿èseg柙f$?3i`Y)ow}CtFxr6@ Lq#f ;/'hĠJ LFQnuZL3.KЅ'\K܎e&IXlWQ[FGeE q#lSΉ~+7ga1ǧEoDwL9LIT&E9"33Lv?27pk(/0^3Oߦ<1 O̿aaP'ߘd7'Y?232 Oh'K ̿B'ԙfU+g<18/>AWmˉ!`r=Sm|{kUcb GP~F=7CeMS8bPvE*"ihhա צ#(HO۟NLW bgf(z4CW 07LPhm}ɜ^-AO_RP??G_?Xf t`[J7yٞO܀T7̿08ubğHHd0VPQs2@?aV 3fK?0?0 q4bFclA9 8 `V_gTZW΄(UFkm^]h:㫔T&cc 寲0٨D N{I( G,tc0TtGWU-|JiU!B=jdIZbQY?s;N-dIYU+9TG2vq Zcrt٣VȞW,P??U9?*\@lFJ I/?M +d Dd_ 7oT:.j`01l?X8 O̿12MH`}|E@TZy6E00W_ŧha,WuMd 2:h]:'&b&]eȩ6Y\ )Lο0a PYzLNWl7AA)FO*LS]e9N Q@lԿI噂tL6 Щ! :п'Z?.tEyAJuǗrfs@Zi/R_j畠U>v!ʟG#wPE\ESeu7aB5u6g yVb fb/11T'OƟ?Q`B )Z  OB2f@\af013t /̿0"k/̿0 CvK}(V{ 11-">;P8vz 11q|ʟ3_٢4o7ۈPDZrV 'qsAV1e6`|_6pڙ2 )O贿\E7M2fAt'blm/?IMSv̿$\ӈOf?N:G0 /̿Wb#oߌ#p]ЭV?> Ofmhk$7ľ x J=b)VO+VwQfTwN07􊡮[Tq|CBJtR#tcXڣgr2tR#tcXڣgr2tR#tcXڣgr2tR#tcXڣmѿcŧtq9;IG&C ,VbA N Q?? lf4t/;,/?m΁8؞: D Jf`)`?0?0-&a'柘b'9dɼ33o" B5@.?T"#a ˎ/oE^|px J-ޒL$ǧj9hIY hp:wL7nŅ"vmvZ+0'4 P@`)b3ژ̕8|ͦr|ʟWYۛMg2ªBrIW_uAcݙB &_ l?b Rnf(.:C[dD[@SO?.q;]9Pz&uuf6WH\Lp!.h0CRd% j|s řԺ ?eB> f =W 6h 7%ǯ`}e 3R.)KSpy0GVq/_p'71)\ %i uGmca0_,z(new˪/4\IA?[5RXQCT)B5ԀMgReZۤM`[5R0:k :.!U?4kuYm2a? ՅB ?1T1a/ŧ1Յ#Uk27PN2:D$y{T9KgNr@DMZs\@QH/9J#8V5ۣj͑^:sFpr&jG՚#t(d/ZM:o5GzQ^ȵ tUkҙ4k5Q=3Gi'{9 j&y{T9KgNr@DMZs\@QH/9J#8V5ۣj͑^:sFpr&jG՚#t(d/ZM:o5GzQ^ȵ tUkҙ4k5Q=3Gi'{9 j&y{T9KgNr@DMZs\@QH/9J#8V5ۣj͑^:sFpr&jG՚#t(d/ZM:o5GzQ^ȵ tUkҙ4M 1+D n ulҒG4ԏ֮vSȿ/>Ixg1RtI9ȸ2錓!rKl4錓!rˑqe,')CL䀗>Hi,')CL䀗#:X3NRV/}X3NRV/GuLg 1^`#Lg 1^(c8IbZ= FJc8IbZ= Q2q2Ĵz@x郍2q2Ĵz@x92e:$ei)e:$eird\GtI96RtI9ȸ2錓!rKl4錓!rˑqe,')CL䀗>Hi,')CL䀗#:X3NRV/}X3NRV/GuLg̔9yi ƁL$ j4ml0 7>mJHIrhS?") sQ_?\a mAg!:?7ca͂dL )q/_1dm?4 f, 3_`b@7ߘcȿN)Jl`ƯTPK:j^P#[PZtJl]TI3׼4pT_L? n)Z5ZU5HGt'j쏽d3 {̪YR`N1qC+mQ8/Yᐦ&.k_1vr?Gl0 )0 l\ ᓃG"_?3P(~m&&7pM[&o M;r_ST;px&/Ɵh柘c7̿Amo̿?UQ<Ӣ4Kl,r@~m2ўo{puaLu~t3;J#:ho> 7JK~?\1ǟ$Z>.PfᵱP2/q"8qiaWfaQS9b%0BFA5e/a7eW_?33R|ͲjYw+<&E+ʺ;7‚fZ47tyVGvDI}`u@@GJ=H9}\/9*#5q VgDt3Ԝ2X!=Б@O7ֆ /MS.)$;9MF 2i5?ο6a\RHv??VVps;N-2m`Nrկꊏ_MR0X.H /rV+PHWW?gh _&Yֿ!3ʟAC3? YD0yQDpj8ǰT^e'&2H柘b'柘cG#eg.Vf5;7$>֭)H W%T\&xwQ.I hǧjaH%;H KWmB6 ɢ$1q'P\Y8IV?I-xis+SGM$;p1D}gD6n(;wV2+2}ʟGC֏suiޝTK87}TaO $O?4'OE>O샾Hd/[tBI@O$;?3SB/1% ?Tg_b֋] x82<٧QiZiQn=9dԥyhVU12 ui`vq+ԪQ4O0s|̦WUCP`K3/(Ԫ(`K3ODAkڢPdT!.?iBQ4O0onljrg'>GXp}ǜ),@[ji0hV߼qS9w,|pٴiS]s-_9˝9Gʏro\]ה}?/0.oL9jhLX jAէ\]A!#D0E"m\2`7,ca6㏪<+U6j8,\7鄌0e`;"v1b/Ɵ7DR'"*=`غ~vlB "1~IzrX1wr `llNҚo寚@V4/i_3S(,dxlNҚ59GfH #4<؜5ks Mu'۰vCE׷OL˕^9(ȯ&!+& . *]۷Pr{u!P?gkʿRkTxfR*)W|.rs]f#Rl/ ?)?,za WR0`/Ɵ?3?GtOH'WweedwߙSO_/>YYЀ˔v`U,4< [(}V LZ:F:lu&T8Ԯr ig(8a_|ԗSZpX'دˆ7z?nޠ 6Z_&eF.rE+.l۶_9[ ֗w]!wwO[vK[.w˕W]Yl\n)>.ļ?Q.8|ʟGG/Ơ_=9*]vCݬEp'DІQ>2h1ɁGOM%÷lqSȌ?, 1b%jP/_d20b񗮋?"8wo/Ɵ2m0[b0f>DgnF9~DCAW!Yk}6jg"K!Kԥd&en&AneGpmen&AneGpmen&AneGpmen&AneGpmen&AneGpmen&AneGpmen&AneGpmen&AneGpmen&AneGpmen&AneGpmen&AneGpmen&AneGpmen&AneGpmen&AneGpmen&AneGpmen&AneGpmen&A'I4}IJςtp[haIM OkЪF 餾'E^rAN*G ~k~BfrDue~aXCnVr^.-(??_?HQ_\:^hN- /_'o?1{d7o^zD S W lo#?2#̿W}i~~:K6}-y})֥]3]j#; 7uT%YF0T??9n246j>hq;H }qalj^gvp|Gwq?EKAH/_r0ۗ} ձ9~C^(pΟ Z{lɁ!/]B4Js'V@kz␗.V%BAcgr5=qKP+ ձF39P܎T$ߡe$B $ #h 7!_1sO_1e?=AbKSf<4rքȆ2GLݘeWO.eRd柙w̿3;̿3;O]$>/KE ^T~;}r|M0C. ;}>z!l@"*bZEpQ"ϬW5T!\wd-qe8GbҐO뎬e_xB@7C 7Wl (jڬFp%Wv9L[ud;DUm?U| jg*1lqF/X]KT֖R8d>F \1+4GDWLY3a !CpB>JBOPuٸp:"5_?EpK]3QJ.MHE&v`CV`yezBm  R);_"j:T?'O@k' lE͋(+oC_|2 [SԗL y{ŕK5VoeOZ5hȧ rBp|^pļO3e*t))e???SmK)SyhKI)䄠+폾\j+xRkh/9 J= XÍvMJf+V9~'-; Ƥo~\u.[A9*W^y%ԓq!֫h+yԁUԿ?(a2 G40AGoi f??\a;u OVHW /*VN'o00/_&`)`R7/S4"O$0$`-'O؇k2b$ӽSdt,SA_|Zw8UŮu!Le6ӢHe&TxɰM& `n0q|ʟ'yzꤚ$LbRrs 7RȰIL07@sS~_Yj1PPD)vJMGi[+z\sAA @bܾ:~ˏ\^n?g K.nstNP_9*áwkX6mRn٪}Νڵ+d>,?_[*hh:sCp e՗'%?0MuD-re񧮛I[H?kh| oQ?Z _?3 Ov?7ߘyF[ UE̿2+̿"-J{yyfaaa1^zC$z9&26̙J60!ƫZb5H;'+_a&d@ LjOt2);_?\eje6Y"6O8Vn輜 nn3 ~!*s$bs*M@SOX}rO`߄v‰w,Gq]\>tD86?)֯+{v.xۅ ֭V k)֭/'trn%̔K/~9}gu?psEOG|Z73Y.cOb_ƿ`*\3%`eRt7oQߌU #C#j/̿0nD\K _b7>?3Gq?˿Z!pD`uQ@]s}y:Qľ62ңR-}meGZ@KJ&ޗj Lk//S/=*z_^^zT%0 LTK`b_}yzQľ62ңR-}meGZ@KJ&ޗj Lk//S/=*z_^^zT%0 LTK`b_}yzQľ62ңR-}meGZ@KJ&ޗj Lk//S/=*z_^^zT%0O!/> Uu.qHQ~HkOU:m&~q2HRd3S9{*/K_nwv9oZy˶ /s._uY҂"Ԩ*L4WU*3ؚv9m o `F˗f5.Tr'o yٚwD?/YB0RcP7W T1b/_ yٚwD_/YB0Rc/|D$O&ߴw4Jʚ aMT0sNGq|*+(:46F#(mD 0a8~Pҙ@`kUӎI9+}Z'bPmF ̜*4|"h\y@IDATSl(wl@ )˶W> ΣݐɆ[RKɊ'8۵FA_Gqd9wg?Sz޹ޭ|f ~۞Pnc?.)}۔?O,߾nxjןW/?Ooߴ׵@ &Qeo+Uxfd?0E: _?4=o|N44׉ő\3{ggׅy)p% .ip1!oqɱKmvNOcP 7u.'/ݚL#ICCCk`Bk뉗 ˹':7=VoiϬ ff~I]{ ?zhZEkmh_~PS% .(h-[l- gu U}-oQ?ц:k9`t~23??(i ? uO]`4?:VZ@.2Wɦ/_?2a+'p?0b)yG ̿1hZ#̿;?51߽dG_mFۨ;柙vAblb@5IIؐ *feVEkn8Npq|_t2 5lY??߰!2hVBL+\Y̒67\UF~$OEZBqHH x@@3D: ܂VߏR6U*WPٰacv~Oy;Β }Vy^p͔_YaæMe_n}X֭_/ _sNʟg/ퟘXh\BZQgsD \G_??]tm٠i Q dJ w90M HcO?0vbX&Pi0 U/xG ԁ'[/xl`.ZTp x|*>7vOlu7 44j jvW0CȻ 82 O3`"Y >|^L47!A>n*'Lߒe5k-Xi+i_†eVB*2jB%w/sGKG>2??_6o\w/[nbg>UvWU嫼{C]Zz޹KWʂ9O(6mQޫ FSF}|A'hhmše`\ëi\?D`ec?0UDo(ǒ?1#=2?2L_fwߑ|g0^M̿3| 3Ovz .=KBPҝNF^yY^R6?HRUɕ {aWի^߈=fUp ,+enIJQ/G"~ fi?#-l,$ı>:_~v}=Un*2s~aMZW^] [#lXf!۾=lk9fpUvַU>/ 2f|A$-(m/w'?嚝WkpKS8t3-0`˪=,ra~z?l :'̚KރX3M .6<`A1)I`Ecm_a73M`B|f柘Bd~3O̿1(G5̿2+T ɵ}9/>t\pm16Fz F'apM(\w}qlHРziU#"cB=?CW w=%s΂fYsSMU۫\m۶۶͛*oaҧ:80hhj?5bhNc_-b'oߌ7oߌyU.DaEov߼$VIhd'|Ͽ>bϿ/b_շ+)<T!FEUJ]wn%6b+sB60Ձ㫰D8j@2?ͦ &d ? fՀ'*.iɩiVTp ?恕);79dc%Æq (3)*O-HY4яP@JYЭA}[!{oU>u^pگ::GŠ/_?3`? /?1#0y}VȞg?3,Ӂwy //OdGG?/>J}thKJIWl=A8ǷGG'4)!kUS$uE LHyWl6AV'4)!kU A !p*`A +ں9U&O9h';DǮt.Yw~@$ u/L} 5Icc_ <ؠ( MM_\Sh:r|ʟG62V;*f!JW&F*řR"3.΢'A'ϰ X[|5FjnRh\&pM `PAK&"s7yac&UJ،&/_QseJ#U?2]|p0#?ĺƱRCJ>C&K7?EtW7>dשuC ftt+<ڼ";Y]o~T5$*Ũ\?2?Ƨ(F?ba%#__p#qsǟJuҭw%J.w%i uoQ#`mca0_,z(B6SxT"u'00?6)|B ˿q#ʐՀG]`/3D $BTլEM _ UC)O2lj@?fTӠ`uzD.?L124PH h.rA7Au>f3.)(dȋO j財fgMSa*Q$QH/9J#8V5ۣj͑^:sFpr&jG՚#t(d/ZM:o5GzQ^ȵ tUkҙ4k5Q=3Gi'{9 j&y{T9KgNr@DMZs\@QH/9J#8V5ۣj͑^:sFpr&jG՚#t(d/ZM:o5GzQ^ȵ tUkҙ4k5Q=3Gi'{9 j&y{T9KgNr@DMZs\@QH/9J#8V5ۣj͑^:sFpr&jG՚#t(d/ZM:o5GzQ^ȵ tUkҙ4k5Q=3Gi'{9 j&y{T9Kg+_|jA:u"9 P`: ZM6yt $͸ @v'`JFNx'o,vb 90fjq(?1#?3OCE$oobkc;̿3^#̿'O"{of,')CL䀗SX3NRV/9T j2Ĵz@x9ut^tAMRV/)0M$eirtAMRV/)0M$eirtAMRV/)0M$eir9y[. x@ u]BAHpAC6km 3 rӦtZco,|kwE?\jK mF1ns3Df,4`oT!ƿ` ?%/?0 O?A͢'[ b670Ct~0ԌEʷ4 ybh0_K{<89_?zS^BK)'̆`o$0`7-<1o̿1&7-Zc7U* AӢ4uKl,r@~͘zlIϽs8BRXLu~tuGt|v)o W ?\0c?I,|Z桚ykˋ[3H-.96}kcd^\/Eq8>OS@C미?â, rLK3aW2dY̿0̿2+̿kLjg柙f)>?Q5;yZna?e]aF}faAmqk%L-SI}h 聎z摚s^3:rTGjzQ g9e:C z#G%y> 聎z摚s^3:rTGjzQ g9e:C z#G%y> 聎z摚s^3:rTGjzQ g9e:C z#G%y> 聎z摚s^3:rTGjzQ g9e:C z#G%y> 聎z摚s^3:rTGjzQ g9e:C z#G%y> 聎z摚s^3:rTGjzQ g9%XŧyyQz‹Ox=`TTT9xPG[ߦdT76OS8hhؒ\ aHYnwX[w6?$dc7F`OZ#bdWyB o۬N!\$J7?~6VJirɮD4tA-¡ٴ"t%*W'Ou{EJkd~Җ۶NSTt}oܭ \_4QC7]RHv?sdj2Qm, hh`hiWav Zd6?B*Y_I a]?{`E]KF%"9+@,S/g"I# b8ArEd #ftxf1$HW==eEW0өuM&hȁX-J~ IƸ8o|ŘKFw|og _?&da韱z"UEӿma/ќd_rP's?]Է2,B8NW_?]ԷF)S(e|a8ٔI} g.2!fq d\ᓻNz7ODpv9.QNW)P]  ~`6\]n`ػJ7?R<4kہ%U!ӿL4gm_ ll{)ኁau 2/l϶l϶l϶l`Oh?n 5|_oNIjB:נ8r)'Ec\Yj-\sRs|ϺO)_񟐓0 y|DJ ǨX?&!"h`*[ph Rǘ=C7xң{>K&0S={\%PP[éEh=.I(̭"qrzwArq $pj89=ڿgx sj sk8H3E\\5 5Z$NN"\..N-'Gw q|.@MBan ӣ{>K&0S={\%PP[éEh=.I(̭"qrzwArq $pj89=ڿgx sj sk8H3E\\5 5Z$NN"\..N-'Gw q|.@MBan ӣ{>K&0S={\%PP[éEh=.I(̭"qrzwArq $pj89=ڿgx sj sk8H3E\\5 5Z$NN"\..N-'4Bf{WXaW*Y <Ѻ!.'֤.|ao3+k5cj iw M[`F|D2TM_/wll_+恵&WWgww&;wݡ2;ugTM~i׮R$ {RJ* 7|4.܃4?0kHHɀE:}Ǻ`pҌ%4r07//+XO\Sy7dO noyTH4f>xh^VL/Ol1ki?leO7>'sfrUo4e O;n?8n/fofA]/vGSڂX3qacxtm8Qt-N&] 9_q$]q--#KagDL>63o@D;!`BPe]X=< O LHCf1\zY- |ÿ%?5}aE"M46??;jzGw|_17pBlll1Gx`j϶l϶Lhѹ^ CQ_7՘|e޽;Wa٪~呛I#VdeaMJ 3×;Р{睗/XKޓ:|8o wy?Txw)az>A;/ÿÃ_B'>Cӥq8A;,:!J.%Lq"4ye`ЉPt)az>wA;/?5hm,}&#Q"(y]ah-@A1TD y"Ą5b~l^ ><1Zl&LR"@,a韦/lR|ATjui=m_>?yaO?xaRD*mm'GGGWm~Dos_z|P "p dɕGFԇ[i2:$= yL96pJ#%@#g# WdxsqK2z>aU ??`Ϝ$3D}dL}@|_N/vï| t.+KXXv^?O@)\Xm83'WPͅ?Jv_-VX?!ѿpr[;d^FDKf7'""W0(^\n#=RX$׀IՓ++7nSֿʗ;X֮[$3<@"[2]G>rQGˏ?m s94 \pGH i]|%rQGɚիe~iX9uȐAuV O&h:<>{@ZI\%qv]ߓ9?BN:D9JR fO>)|2/5X;-[N<)W ,(7nD?q>}z m7o%zpݺ7cnq'b1l0)0q'ebo#?i0c_@0V`r so-ۋyH`Ty5/ӿL2+-dd| l':Yg>9oY@d jJ "aY?4NҒOOMɑDQxǐ Գٴ|Jÿ??$O!p|jJ Og A IKBA5%GraͿiq3GD$( |j5ݫ_%!;[%K$cϖ$h]gEQ&RlY)Z۶ɒŋdѢQNL&rQ2[]R> SM"E>FHwk_rd츇$|d$+?WVU+&׭֮u6~5!W]7+W51?ev-[~m/jRx1*]'@{~^Bʕ0KUv4_Q?~V:hX\-`~5GxT?(Z# yy2~ {!=' oYZߢEsi2z]S-[6ٺu_iߓ =%=&y#vyH8gK׮]mk eo_U8Elj>xr]NݺRt)mn߹C34q|k8PAfbE H4lnyb,(Ǣ7m )R,]Lz"[J,!͛O94A 6ȤIƿ"}UĬ'dʔGc{ 7)GC?\GvrFy߹kW95A(ɒ֬^W<T1oS]7vHb=䨣R(l?x_3&O=#)%KǨܾc,X@?CA⡇*xd_&7QFҮCG };>J |qd 6fKr&#%I?zIenb_h?]&MuwR.+KL '׵_mcdah> _w8"CL8y0c@:8g΄1q$LodvPNLgNd? SBL$=Κ3!gL9 ? 'P]3[˹7!PW|a*-@k `g7B1WZ8eJiA "qŸBߺm]Z?r‰U|֛rq5.ʂgGIjЕ,MJ8 HO==G~ISME mK?+O1j1st1u~7 vE7KҨHO`k?uL)\,YɃxߺm[kBVKHbq} o2mԠ LME WK0&0&zmoBEpзCO;Sm[#_0h!-/vz)˗/sc~"U.Gv͚5CM5S{+W"Fܧi@{ߖ"b 1rT/w . ].X߭?(gY=?@は_B^A}>xr?d޲cNesL, ' y5Y3?|6~tYvW5dv>e1oMN6\Ѻt?9sB ?e˖. e˔{裏w`KXr!2Os4濧Tz_) >yk/v0. 6 0JSG yݕNh$飑ZFCj5k`_DI6|)W΁¿ S#A%JDB xO?Otާ/ӏc+]ӿѿOO;z7G]*9_&3cB/?ZƸ3ki?lM2bؘo\f޽;;6zBRIqBAW}(" T5%|ÿ')?!G  .DDDFf蟇PxUg(zP D>u E|4qyz\K-b_ DgEp瞇`l __*<pXJR_}ѣ*N!d4&}i|D>Çk8Ҟ(Q Y3mg(/qг05{L:eD8~sECN)l/&?LAXkZkʌY=BAe`K!&ӵkWo' Η08Fʐ!sF0^eڴnc| pؿ1F6t~VVEd1 Ɨiqߟ#GIjsCCdĐ׭*D85FޭtLhӕC?>bUk &k(yw䓏I1Ȱd=/_UڟG UrW ozeq'| *{RVgS#P˖-Y*} IIU=<~*SZ3|* /M7ǝ>##mwL8^}|ïŇз9OCM,QB]g>1 ev*WnϏ*1{1Hn(#fa`sLcZz8؞ShϡA!PK?#0߶pk]L'AM.1'9^[ qg7od t'cMԨ-&2ϠԨ-.ϠԨ-.ϠԨ-.ϠԨ-.ϠԨ-.ϠԨ-.ϠԨ-.ϠԨ-.ϠԨ-.ϠԨ-.ϠԨ-.ϠԨ-.ϠԨ-.ϠԨ-.ϠԨ-.ϠԨ-.ϠԨ-.ϠԨ-.ϠԨ-.ϠԨ-.ϠԨ-.ϠԨ-.ϠԨ-s OHzm3 Ԛ|i_u@'-y)Y^|#q(v:z a%y9XF4j!N`)w:>B<`YOa?/g!8<^iժi6i O^W4|"ѭMvt~r޹kMNÖ#6hSo3}]/&_tL0Ƿ@IDAT^{Y Tod.Hˏ2z|%޻O_Yp<ԓQ>) ƿk+/Dm_C"Oп̆Zx|Wi}T\Yqyǧ{:c+Lkq ]wZT(69#W?^S 1NoRc}]^ 1??.Qƹ[PW6mS_Η&37a5$?ᥰVZi0{nO*N@ _7<5p.L~`?pw&LCSG75&LcB HWU%>OArbOQa#JU_ k8\vFAbHWSR3Di`a%1?E*!5Cߣ*@N16Vt[3)$8`(?4PGD_) K8lM6l%3")'a*a0E8_çdH7Q"\|y#BzdIy+R} ea5!cve8'8$N^K d, qݫ,]JN?lgkrҩ+.~'x|ڟ0dEjת-+VwCwO˧| |N;u4Ӎ֮ϓׯ/<ErYn{9#o0>x/ȗDYv: _/ifӟ,G7:F+&˗/'իY,:Y8KupV7[oa{ȇ|8J֭9X+~@qi֢]LֲeK9򨣥lrM6Ȓ%Kׯ?301QTI|DoeP&OyBplϑcm/*?`-]D^{5Y`QwPR^Y/ _ZNQg6Qy'75W'lǧ65mkש#g}ԪSWJ*%߮Z%_~^9J9s͠ݘ'|e[T27y-ټq#O, =//0ŋu3^~ `Ogt?#O蠃d[euޒW_ڱ=Ozu௳1&вM9&swߓ?|/ "ׇg.5kԐ˩' y)^"?OhD㓶^ gyxߏ XG4cu(sxUVQ/&K_?~? O4^jg%a;bx7a5 p$~@/"~"6)aET1cN02៭x)0*:^^zmyWbtk:aԩMO>[ʕ//ŊQX;xx$)?b\}=`x?@{+a1qd .cjs?jo@-iUh-[ZD~Iz#7Kľ (e҄IRNM9󬳥U1ۄqvxQXi=#J,:"A\;9s仈4A"&W,[.oyF'>qv .D=8/Y<*Laz<3[&9]ǔeu/QXt)`OArigH{ʪ.F9 X_\>E|9(z6Gڋա#jU緡+WPg]f~_GEN?8 a_a65&!ZBAk{j"XqKǿ7O<HV-Չ*[ʔ)+e#ke]GnWHAX#O̚[ ӎۅFL!|!>P/^q)djv6 ށvOoWGct㏱cߓFЀ?r7^{g&xzxT-߭ruζ|jS^MGJzywԛ!:{dxX? ”۵k1ᯙ&K/رcSRDI5m N͐cɶ:zMȔ}K[ȖJ)Slr0΋-`}9f''y~2d7?&~bi'L6oӿ%X|?&zۇ#G(Sp'甛 ,|-_>gnqa$T,L s\>?|9°ωa6T"p1 k >F:!2ϐsO?r>ag2s?麎Ǔzn> @pu`Sss-qˬYz- eLi%yXǟ ~C_|-/P09@fZHVN@! p&:.k)/~ݵzXSvzj<~{w)JH+pP"GaY^IY{RcngxCnGx`Y۸^ϿtE98hFZ@{_/Xp 51]|B)8-M.\ C#?o' Iʵ}2lԬY ˹+Ʊ׵o~G'zp?hT] ^w2wxpCR|ˏsYgUw)%av)۴k'G?5k; :w ߐ#fr?xDσ]OҠQ W[?zښdfѠC`ߍxObλV-4ӏϛ-}s0ڑ2'|#~Ӧc{g}Nt4{!`=Ǘ5khPzuۡ{h7SgtLn@c {Ǻ sctcz ~ ɿ3@;pDf 60 ='~t9!t{qñ[ /=wqeBuߏSE)&+nO' 25|r@n|ZLooR`A>mWC-˕܋@`n"!?_|9 !]hKvFɞ c,?Ã53iwPפ1 H.a PX^)KFa/4 ^}L21(]ֱ@MY;-A!h? cVV>լUSa_ CU:F4oR6lh5e53kkCe˕Gv .iࡌm3ľ ǟ }oh!jtFBQ<<[o>\&E7O2PgȇK̥+/xwv˰T|rr0ѣڛ>2FM#k=墅4@<0{+._ X%\ĪAiSeyeKG7Ҽ-F|w}oTK8DސeHvwwj:H 4cxXjux历^0Kx C=Pz7?u|=h?XviM֭[ukEV8^ZYV'w^:cmk2EE{a0V| //C .M<^ x 10D>@aVh0޵(7/ZH~_)RuPWl'M}h W!CG ,쑲:uãdpu|'9#W?9Б9 ބ)]=^B݄y:@.7nlSOdJ?/}2M킾v)XwiD!"x2t˞{*͛7AfcdQKS׭A>ƣ5ԺZ4o&XC&@.+[ɒ^^ g_-ܨ2e`6^O?'[\ۯ“1'qGܯYǵherĨy5|*[~U0;u]'M:vyP轐?9ecX炿˟tk-ڕ]Ŀ?~k=Ĩ֑G s _N˱?G)?1c0Hnf8/y]6O?0OL@?kQp`[s"M>H$1GH׭zg99r 6ܼqs%1>OzΘR'S(A?L1ߠ;76܌v!ƸZJ3{QK Q_EZ 2EnGa4? ~#a\5RUQYvƩǧ7^_]OdN|{;iviRUrwQ!3];S~H蕄4 Mơ>f;V}'Nd0VsX=hS+W<>;+cnjW^Qjq@<_F0O>t ү}p0[Ϳg +vMv-sy~?wu@g~Oh3Vڵ"zW+d a#<ãg88}nrFÀ㷤*ժe?΅;iFC?=9{OŊrc9?^'}qF^1_ {8~Q*-~}p8K(OQYOiF>04QOt x{{ "J`ry|?K;xkC9lqzx||=B ^_\9X)>s۴w‹tWqzs_Q "#nAve~KTרz!:nJO;uҾ,wp/T>pȡ*n&=C7^ʔBk %)Mm2lT+.JztTq`1HFX q8?P |y|'<>!K~o<ԅQiUKOz15qi &myP/*{mһ%*vp{ox^f2IE/aԖ#\1#,yg#~Ix4\A T_}pN}rE^}se7o+R6EDnfzȵnS>NBgՕ݄nYƅX;#XOH3 /c7k״>SKx1?5hlKӜFU! WGkF? n_?#9c֛i43a7N9 Yc_BfpJ2^FhoG0 o4:n/?ƕx4׬3#zwPyfOfx @wt6<2,wx$nl9,J.?M1k_[PCW/[b̰_*<)>FG?0=J9!gj։|~i4A|ÿ_Ċs̗8?3Jc B^ "2—%LU<\8Ϳ4oO W _r̗01+Rv6?}-3cӄ+njy-CP({ sO8A*ä~@Xkٴi)SE ՗CK< JVxBx5胗>~=zJӦI6>s88!! <# y{u[f+_$+TZlM廯¯Rp'g͜F ȣR;v}[xvٖq y!P`芖_sUj_4iӥ(t !?F s0nÄO%k=0jpU$OjѢhEp3|ᗀj9Wǵ(K!C^pŗ( 2j-n0z@TQh{{o&,3'ӧNsW3ERJ2Fġ3|¡meI=;΀qtߊ-s _#fr?axFi/Fv ;#τ'ZK[?3 8P;ujs34\[o _ OǿfU g iZHҋV?` #22 $aIFM5zyO=|?W^v%}لK>}儓NyF~g(W^_ȟZlZ@/PBu#a">@3ǿ tNjq=2 ހ2 jtOga.uhؔهeKaԫk _0C&s/>Q[ Ieɧ6nܤ6qM=`5kio,1O'a&xf7jIUfAfQI^+W8=0~ Q˖. `ހ?f̞ | zY玪{yҩKWVl%,qeI3:cz$O) ;?ѪQs;_:]FJax؛R']iN?]x n^rq'[ԅ:߉ͼ>~QLSbZ?! w_m7/=lo/?SCy_t/&M0!1c4oJmk_[7`qp_'Mv%IZgW-q(o҅;̑j (N2 &g染|?sE1c4ITd^h_+5hH,AwD#;;@ė'Hd.W^1Ckƹgڕ9 j)θ)՛ _~_9լU[<_j 9Ɗ7xM֯[ӹ0|p8çc~n̤V-.xPpHK;)(O?z|:1ņO 8;cy=ԓ>{ټy,]L Ip~ei@΃cj{x @[o̕Çy8lݩ3D?0>OOd |pЏ;Њjww˂Q&MxW&~܀=3f.P4ꫯ»ӓ HWZFk~zxǧD0XTTPN)uT\ pkߡ1xe1Q_Xh!<Q>CCayC[;[0:(/>"N:z ?O/@{mo|0|xi>45Kz[)6ո˿0,Q{J*Iҥ"_|͒Ll3Pg`<{/~bzG$a-3"կ[p檘^} =mAa_?4/4}y|SpoԳ ICI!06iy4#iެ/x|Z|)#`kAqefY|uH'c=ŋ5j(w>۴wvAx+Gs W?9?ȄߚGw?Z v nß1s6l Nx[tD FgA{O3v *%KO:3xaKL]"eTn?F B[qDzql@XuxvmZw-7O`ɃN>Ah4<gmGCP%J*-rjz|3?4Sl#TT id3g͚Fwt?yG߀{ᅫN]Ԝ--]@p9ӓ⣏?,Om" WTYF!ZjM ?OFm^.f:Zb~B$?c +0Q~KZ=jj_yE p|FzԵS\t#`ɺ(~-}Lr5l${  ; Ʋ"|OOkTV0l4{O6߅^$ڵWO=4dכ09iC+Zp ,/ËND̓?j'<>`vر޸g!U aaxkCs+Ԥɓ&PϣOS,-_Jçu `~7ꃇ[uM*6:FON.c  WNyq:HgC++\ J0(΍XW xSƍڡ=O5砃JNSı +k;] >>ew]0YՖ-[H'бP:@E0j L/_K2A' vr!l pg!>`$ gM4hQ#>5gYw@K~!xOFg)F ޏ`_ʿy7e6l㿎KPf,7gz\UJYJտM!'$&M7p.F.aYqD9G?YX2&RIL0ӿLп)x SƆa8*!ʗqIj#Zr\a8*!;w?g:C ð_@qH&Lz&zaDAG gтMӀ&HKc W 3Lݍ?WI$L+K[5 ; ^q AnP{|"a}Z}r)<-u?_ ֭<>ʗ;^]Od%mp荞D&"?8y:6*3ecg%"{8jC4>*L/e2AZ:|MCqߟq3 FI"KDv (NkzvVsNc?˓T8lNf9O?¿urgE\ lټ9~]wPSƌO{K/qV u>{4X*R?FzmNK?U`蠴K2boӦpyV o!CFZfQzuм paחa`|/WzBE> Fq p'(M?I'bvL ̑G{Ko5w.<^LP>K Cf o0E F~o؈Bםǟm 5ZS7c,Qᅦ4Ð=ͼywޥǧ /C"=V^-x|ir\c߼Et7(7 M]C{>-/Gx2~g  6a~*63G7o,;>NWNZJޜ9sԣE}'?( %,"v2@+UA?׸ȊiǏҌֆ[Z*U;x|joc{ czuapCZ/4ĮQӁO! m|~pYqw PУpo9I.TW#䙑M^4hDNиTNl\?DoW`As Z㕧 w/B'f͖S:0a|~v"¼ڴq}ۯa΄׮[Gnf) 5y?BnBZR_?MO_! J y+`(Xw.8B Ŋ `(6o"]:wROL1c;{"[rx~~?dpY;48s! T6,0ΡWeKSn7BXe{wqnǏ%Pck~ ictni9F~ ]"2x"3=s>'?lc+Uk'A10O#=rGݯ""KnYGf iӦB0vkaVz2ԨQCk]!=5jc~|1v}@{셸l7<9Mz/SZ|z^˺#]w!C/a%yͿI+Qa$ ڈFgؽ1^D,ΈLc#cc7s $B_!2?NS1k9L/?WʥQaӿ8/H ~z0Ȱmovn`S/E&{{k04CxSd+vaOX iLJ{_$h7ҸXF)"a>5/qMd ɾ?4"BqM/FQg`<ezNGt6X OvvIժF0 Y 0=?\`Afwx} $ gu߉gRׯ4+|Dcg0KK~_^ SO"_ cNr~\ WV/NWwZ,YY7$rL>xFhosXp%Ϙ6]fN3:K]0|tT:eb:`UaP _E_so? 87$P?x0)W|0\{'m=os*CvIJdɪ+zݱs҇cC 8 8ju?ae~qTÆr!w6;.DJx` Lf*IGH0m`HBc)wr1}3c ѱ{z3f%җ^_xA_gǧhf AJѸO j9WgkȱxMO҈quhzO25HcpxYѼgǸKOs+z˗_嵔,o"~Xם `4EJH^:2<4 7B O:?CȩS借_'>Qd$<>1Bz7#5jx ~X'5%߭Xork@IDAT ҵkW)[low;E᳢cwRd/0I79NᏀ7oOǿ[`!M!*h|/IΝ!|pW_~%6Pgb׮38_EqX_Dž1 F/xWA%pi&t"]! 7 ^JB5^6K? %iXn=<%]I6b}eri hŽMFД^O {Ơ _}9pOUk3< S?P`>wCw›6OnLF(Ym?z) # RxTa:xl׸s'ɒ_|!zcUK!mM?zi0^Ou]λ#|x6"/^ځ _hLV7eЙv2?|#Q#4C<5Ը\ 3Zό?wM>PO'ł0`^l􆞙 ~reԘ1WdܸqG( wڭ]. x;}GQϊQ]& GȾrez`ʒ˻3.ME7<^Msvꁓ?} cJ(˻t+6g*>iH {QWm]xY¯[0ORos ݵi{λ _ѭhb?!C'h~Q:uk@w%1޻vޯ:w[Gp2:sS@!>|?oO?A%eDN"oo&LbO_BF&M5ki~_o*p+HK r$3BD?'BS)/9 Hnh3I<ĤTK9cŨ ڌrO.1)4@F1*6ēKL M,#9F_ 7z z;ߵmzlIioXŃm<'vQO7O:)?줰-v`7!ԟzq=> x]wxoGŎ ;B ԩ`Xuz D r$-?;px*跼z[hұog(Oiߪٲ6ml÷Çqכ;讖O``6΋}M[sݼCN;yEYkV? ^v~0~̳P7܄qܖ P,d@3?u.&!*㰫 w$\翍)}1? sQ9=<3p\lpMX?^㎐\Kgqz:Sc[ne /J}V҉EtՕW=T?8ywpS?{73M-.9X_=*= xxl >w41pOC>RbIs)ۘ6c[fk;+c3lq_kxP{XPvE ڬgyn߈73gbtƔ9Z'?BG;ot뮓>d6u҉eo4qD^aqj i4|c-c|llVo21+簳)S=~?p >fwe.X,#07Α]yMoz~%?vZaB8z-lÏ^p_ث-7m}|\`RX.B^fVIc$lWSNIXd4 (:OQZ]:ý0\^<镭גUa?-50ɵ%L:‰de5~a?upQ<4ÅOæa{Ly>?_0ƴ1erHG%<8ƪN17).Y4U2 |w&Z}ݛlvd96`">dG_c+ڡ#2~L_mdtNp;)͍m7ݘ>~/|͡[b\*>QO'ڮOr.8;T=HY;pG!*.G  t)v+'S<o/l'S8? )eCy?@?CX7!-?唓ONr+^>Q {;v!ȇc0c!].vėk !)?KR _Z9 {׻%y'LN_{{<8v݆+Ŝ<(=/7tc@;ܗN2lG{sbOG`͍7CӏD8x9`܊;>#PQ:> ~{,y#2Lj#OƧ`YgiZi&qH-s҉'̒igֻ3}O!|!؁`Ecʹ)# M7ϖjg=+M [\n07uX6#_g7N;n>t-7IO^y} ~iV5moGݎB ,)5|&X|/=@ly㰫#NNgZc(-(cq&*,|c]Q:EVwygzϱg/ǢΑ9"o gx+bƁX#,Q@V Ѵ/qW uNo_|Ea1>ޏ^o/}o7ceb=xӝwpݳPąOǂ?oOy,ZCݩP|Y~祃#RTxE'#XTqG꽱;g\7V`;MoۙMXt'ҞL={_=m͟(20ēNf̀>1ox؃þ|w}V: ~3vs<,4y^d1X5X3h%/|ch}Ox~3a728C4LcmgJ?@z/%/p:1 qa|S _yUin睋yJu"±-/O`.2bAX6,C P,~t1\PZa `O_o0YصȯYttnOkC;o׺.;cW8 n[rP6_'M}GslZve[9gWX K?OQǤg᧦Y?'*mcؽ o߰?#Svb_rЎǽ~-".fnw}ٮwΎkCءZ=| l;KǻCqab*y ďP" a3q[ǡ7|˴z&.sGصL,}no"#c5A7ߤ iRg"ҿ;\?$(#;>1#o AͿ4˿cՍœ}bx7_1ū^ 6b9rP\Zزs0&)c,3<吣?T(YV]dv/b{+kv$?Pq>=p,LBsk_OC؝eo6cǤ?63X?Zt:>qקZC;rǧtA_]rIc -p{ލor˦V&E? ]߱i?gg~gN[mmZ%kyb(]}Օi,/_i_Jw݅XXG-1ht|K_~~ڸQ(/lnÎOm~ 2u#>w= A> O,`G]&}Ӥɓ,dȅ#oyǦy5_z?0\}b3Oo-;p?7msoŅ?1u?zj+r v݉'.>yK^b,>a!?b˰q,R!e_w`cwӱ;Radmx,x,|̔j,|x.#=s{?`aҼX(v5Կca>XSBZߛf9P,jX.3HsW]qO|2o.ǽ4"o7i%,|qw.UN$lnOL7=~?s>{\tGncw@jcsM{s!<_]NXg ǩ[o6;q ^-j^◘OBHa7wǣ/%LT8^!wOz衇Yu0 6cbwLgr2&3[o7sa88=BelǦlj =|µh?τ%PijEn骫wE.E\(ǧvx{gzዱbs]D?HvS͠h~?}ta7/.@{l'.1?>}}l-X(=׏FZbŌ?w$;.)7&H (d_qEk651ǥt}Xdwf6z54I,@N}#cx"^Zxկ} JP~Cjs1`b;:3|҉~O]g=>9y,,>Źv"QRi1_ }>0*zi' <ŏ$l]x=?w Ü <>3mi&v1fp:`q~j4m=~6gXtV'a|dlqvg묓> ?MXK2AX+qfv߇/}4Bm`xOڷ `ͺ//صgI?% SL 8ͪY?Tlc⢴8|sdg b/^S?P_6J G`+*p"fS&k=C/?gĿ4F$iqR3,}ο)2|ZdH="4 #6M/FOg e5hw 6򿞲J^7wkG]%[6 00R<LV?nZ/`$?~^ԩCPoIWs wBŎO].z?+^j[v:x|y?7}[Jwsof6~^*Wc͆bYptd~y/mg RML?)SMꗗ:`s!;Q_M`~d,dX(=>23`?>J;l',L§c <6}眳ua>#/RPs !Ic!o/̈H؜ ~S?.(!%p:뭏pE>jѽs{X&Y^ +s/a+'?b% b}}XO5=#i~a8,WP:E,bKס~?A= ]wҗN~ LG|n7s;7grݰb'X9KD/t<qà[5w9:ӽ&RT@^ wv`\[ATf]>hC>n2\ 9@i_yUD[XC[׶5J ->9Oq >g&X?#ĉz06O_:/.IBx}qکBlטQLOv84kl'pf~W=.Jxx<`[nVB/`aO<>? @/&gϿ"1>rq=w^?,b,s݅.$&M/?wYg[o)-}]zCKh2DǠ{=XxF hBcrG>cǧ|fXԕ?HD^{@Ac`o z l#>mZYMb"lp}߰AQe 6E gk<Վ90 ruX,<$,.;l )Jԁͷxp +pSOEξ~Q?!vƎDB¢ 6,Pc6yʪ{[ q? o-,bu{ 3K,x: 0arqMl}ny0vpq\jv:˶LpxfV[w<`tͷ’=?,ʃ/q\ԏ6nkHz=~LpmXH Ne?ڎ^p<≛06A__kak]v F!]C;7_:lљӟ3]Ž<^[ﱧpWW\yvăg^l#`:Hn:ƙ͊\ZB;_2y+s? '{@| \ 9'Mz)bC~y?q;a\ ;ϘW-}Q:՘c=C?:Ϥ,(q-aB[ڎO]*O:O:>bn6r!wߒk&} cs7EY;G^JC\+lӦ<=u_Nnz*8~ eWߖC_Ew|?6q,;> tF+ūӇ :E:> wG}ΚKӁ~nu+b`2!~2%]N^&/Ï%ݖNf#@1(;vv]i WYmXSӳq/oM<E҉E%ga%bqK.ib|yؗ|gZkO3:c?ǚkO…}O[5dURǏ@M>1*Yfgbȟ;#]!M/D:#m1Xسw[\@QsOu9x؎O4F@zk_ߣ$?2 AdYnQ nL,q-1CÏ<;,w)gE\С,_v3?ex&mlfiͶ@O$:>w9 Jb87 e c.1f;*>_Kڳo~5Hp=g[k;̼uŮ; BAKod;޸=Mu|Ƞ.EÃgࢋ,J\S0˫§ȱԵ6>(eG? â(8팳l L9f'b>zڴ1fUV=ڃrBjny;mJ<g?{K01pVWu8keb7_lj# ĸW='H:[<Zȣ< b'Y_ēw|Ew>ڰlF?\fQ|׼ ; M.Biĕ *Bl !xŜG`;4\FERsPr#s*98OC pH}-\[$%܁,} ǎO,<3Wm!.[nخ4%s`oW`gȏ.mVY,|6mɍC?rg֭/\d!,WjVCq.dݹzGc|c9ث/z-Y?Y9W7δu+B?VbIdZǝPjqD׿6̊T5k_e(%FQO?$6yc%UuaE7 ovLh-? :vQEaA\RG::g+lm(0 .#i]sQi [A.ʹ(4K@GAlm\F%uD#sV`жr. # :"Бv9[a+0hE9qIH;蜭HttV vQEaA\RG::g+lm(0 .#i]sQi [A.ʹ(4K@GAlm\F%uD#sV`жr. # :"Бv9[a+0hE9qIH;蜭HttV vQEaA\RG::g+lm(0 .#i]sQi [A.ʹ(4K@GAlm\F%uD#sV`жr. # :"Бv9[a+0hE9qIH;蜭HyҔժIB>q:u\1#d-Nv( j}bQI44!ckXr[o|+ɟ;ce;Gfv]xވѲwugzۛR6r˴ƛ̑{ m)~},94#^vy:faG|zʩtR_~ĞW/~Iy K/KsWϓc[;;i%7i∇_[: ./ݿ __'~vֹ?jϟX7Ѯgwn8B+<owqǥs9X\ ynWSʰ8,g?Zzvۭc>&\ qi܍a뭷¿碈A[?~}鯰Tc=!)H -}FvvâzGB]vݣqы ~s{T0()Xp6"v9]w >Nyav-E/BSEasvV;vl֗oޱ1t ޿C[x}j7,[> ׽g[m7S5C_в?%o/yB82/aW.ߗ;X.no?X|j]wb!r .YX\t]XPZ=Mh}M6FE'޴? 4Y2eR.`;;(]k `[^Ő >;VCk/.uL&'[XQ?6Džv? ?/i/D]/7'괲wos?V!`׼yĭ9trPMo ([G? p;>ݑXhӟ4?R'cN mW}'$1.qo/?6n}K^>?ַ`_Ο5ŋ}"gwn]dd?W  7)Wc׏:2}}Eg¯9d. zO#7slTW|n~tЕ>yθHIXE/̲iK /pڮg^E>>mб8jbA^K~v1^UkX% l P̑ɿ~uЗ?,P9|K;E,#oh=jj)#4ÜͿ4?<͎ODGL묓 &tK|f؁d0a/[ @uIb%M@DZ3N2-i :$ {1ݒ&_"v`'L؋4igunI/P ; &tK|ó:`^L(HkIb%M@DYgd0a/[ @5$ {1ݒ&_"N2-i ҚavnI/PvxY'L؋4iͰ;`^L(H;<묓 &tK|f؁d0a/[ @uIb%M@DZ3N2-i :$ {1ݒ&_"v`'L؋4igunI/P ; &17BP0@@tP}FHFⵝ`hX: YCYIt/iI<@{'Og.OW^9bk 7]߬-K/LZ/M_c!Gu47MJ_>ga*SVIKagԅZ^[nUVVgϝu\x]vtxaƟ~IB Y7͜x/~y.1jX$uv S7 'MjqqS~)@;U.'K/WPY?ƒf'::8iG?96_ M@L4&F@9Cky(Os6I'Կm>FzʸJ6X*v5*(c#3"  $21\q͹` (%?Dt?7mH+Rk@ tAt mH{.XJ"2<>̻c7!|sBߕsJ/1?A G^~C%/ =EyT>ش袋aC/سl4LIlC##y0}+iT|ΜHK (m.F @IDAT2FZHd & i! RZ)@O.(o4JAhKm>  (m.2FZHd & i! RZ)@O.(o4JAhKm>  (m.2FZHd & i! RZ)@O.(o4JAhKm>  (m.2FZHd & i! RZ)@O.(o4JAhKm>  (m.2FZHd & i! RZ)@O.(o4JAhKm>  (m.2FZHd & i! RZ)@O.(o$OC qśiByLI H.UuhȋbJQdR4D e'7R)*g+Jdd5hRH Wϵ^7hõ??^jf|_+Y;!3Yh)_/CZ$C'gKO5q?(E_2ؕ$OeZ(\VUլ-pTrZe1@~ō, IZq2u7rpRS+^GaZ&Ze???^3R3N2 w֦{,9hWKI;@)F0m0R8]Q` SME\=tҒQgddi 4h! O d~kvu7\.ׄGv}/qD~'rh#C/kn5i޿cX'IǮ+_ g%?+_q倩7H(sM.`α&͕tB[|R+s/K&Ԇ(c҃iTFZdddd&ԆmT% Xٟ$ego'NYR.L 3?&^ێf_' ծYAn؉=iL K?d:@l ]_?U)d@dC>?!Kx@T&,PO1@]`@gJ7C?4ʆ A;yӇ" GSOͿPE_ (26 # 7SuONG9iSEha?9T汨=4!גco?&J8+_b-?zT9N'3BgKmQHGͿCO?9v0P,SO?5SO?+Ϳ5ƘBQRAş;>ya?uzK9ph3Sa7R-|$eqAu:T8R@PyYõjjU [yOs @5*-TT^pmvG\*/k6PMmpJAw#i}.U5\6]ő>* TSܮR{ZKAe  nW)nq=ϥ kt8R@PyYõjjU [yOs @5*-TT^pmvG\*/k6PMmpJAw#i}.U5\6]ő>* TSܮR{ZKAe  nW)nq=ϥ kt8R@PyYõjjU [yOs @5*-TT^pmvG\*/k6PMmpJAw#i}.U5\6]ő>* TSܮR{ZKAe  nW)x2:!ܻ'eu-^ )("C H&SZq\ U̹ _W]?ٲ2DEO_C* f1+E*u v e(/(0⏊*l.ڳ&o'7GǧG[4sH3&B"9d\V g°7mDB[ <<7r (RT}vL/p*0<]ҿFO4$Ԥ.@PWzg?ѓ" 5cj| U癇 k$HCBM_uU`y!s9<oy ei"&,|9̹KPLa-I\)1y`Vހo3g2M$ GaNI$ GlLI!}QvR16@ &qJf% ](i;xB??J(@tھTe]:GaNۉO'(#?`'|3ε#LԘ;!bNo&A,} K?t' ,?4%xvx DA+[GTׄhyh&t91:BX>Dv档O+?oI[[NXͿATŠ޿Zv&JJYV5zʾDa `D)Eԃgc 0\9lT]@и!ua4 a& Aָ\.Rǃ}v!HCu6L*%_ۄW[SPݫGpeOhi@,j/_^yPAڇA(/(̪Q=>YE'!O*Lş.(痊?oiPoemxքKAতd7x-Jyq4i`zKI0.?hu[RDO)PۉR[RDOWv|jzut:- ex(pBG۬@$@n>x2?@[ @Ww!f6RggaC/?m=7-¨_ROOoh4QEwREEӊ(B=_ )H'lx!B7J}(ohY U @qAVYKyb?z6#r)<q*:$#G/ _tW5:B%=qq+WBLtNQV%0s aE:tc߅&K`ddM 88pW/?C/LQ@S ,B)2WTmJ7k| }0T)`$)b<x}SduBWS",ڲgOSi6%}%lSM+d O[J`I K%@bzOMЂTLw-\N|EϐYsp8l kAc!Dcnl=83`"$_64!f+d9[S_?g͂/to3Y/)[Ϳ̵48ߚ?ġ}FͿ9J(@)B_VE?(Oy*3 T1$?o)Gǡ3S8Z DYiM߆k*L-x0׸#zӚR%~+?j9kRkn?ٟziX޴|zLÍfgC~ a _sk^k(&3Rzsà^,pKr/IdܖTj -! f{bOߚ䉅%_j]ma#M?)⏴*%_YT6}ň:+pل|TQG˨O+v,jo޴/I-x"L產t5פ뮻%E]4z$ƌ?STAeL Mk/G_8 O<(c<Ȍߊ?@\,[oͿ57'ۇ/zz4P(⯊ϬSM7`l'}Gq489\]:U>H%Z/B"u :Y$`2#HOO/^Nk:MZƸq=zD'##3gլugo7Ar_2OR`;`&_9"dܩ~'Ú;{0/ x`2"uy;fɋR y}~%%\:κFSW!s>KQ 3{}لl>mV'4}}AZ(]>tp.?(f`T_şlf ͿM%Pc=hw9}@O )äo?*JѼ'-|Q=&f|5LMn8/,gu%Z>`\OQ\pg$KzO؎Q1 IQ8vz?44L?' l1#C܊MkeGFXxk{[x#YF)1cǦ7er?Og/PZnicӏx~q\>FwߝzADZ_G/Sx 6%8 y'jp,g. J4_!C3e7c?9ӂ@$,Sha3/XJEͿ4+ &h柚ڜ)Os,?9]ݠ\(AO̙3Gyn `۳ln%v&q*<*zW&oR2Md$d%pu6$Ҁpntzdʄo.i4+C&R?_݇?0#XJ2LK\6&>)_U2Of)3hìَ7C4LWxY'8dZZ+l$p 鏿I? +/9n\ZkGӯ~;.Kߘ,d5h!nOߜpB?UO_{=(ъ?(qć')⿊sQ'ߠnYߴ TͿ)P%QE_06-bjzz+=i͵3>5 [zx}ޓ/i3,NO0*#ჶqo $#G_hY#{NXTKB~P0j柚3"~VA _QE_QEwq2S",WI'TcfÀ;ufFJP LVg>Vɫ&lr+L2F1A` nP6E-&Zi(Leo-Yd46@/ Xq@$Ί +!3Pe? iY|2˩'yhF!nd#{j5?rCOſR+ƅ^Z"~UQ-+}r*DQ DGwP/C??)\I;>˖"Z&;̫<o\Ie-&T-XFQF#r/6JjS!?__V. ߹։C34( R+Ca:ٟDy=?s8:[?R(j`Ɵ,H>eV?SW#y@/ʾ`w5-5!O=,Ê.Ϳ4ˍ_Q?8j7:CfB)),H>e*![o7 ] F2&H+zH YT`жr. # :"Бv9[a+0hE9qIH;蜭HttV vQEaA\RG::g+lm(0 .#i]sQi [A.ʹ(4K@GAlm\F%uD#sV`жr. # :"Бv9[a+0hE9qIH;蜭HttV vQEaA\RG::g+lm(0 .#i]sQi [A.ʹ(4K@GAlm\F%uD#sV`жr. # :"Бv9[a+0hE9qIH;蜭HttV vQEaA\RG::g+lm(0 .#i]sQi [A.ʹ(4K'aǧ&H#KB`Za}"`V덢M! PzZkcqӲE]t= A6m5=wݑ.B1e9رiyޠ?4k~Zlŭ']IOO?C04)E!k#9D@G?5o;(}şRS*Io,OTPAgş#⏊?*#f-X?*͎OKLU*/Bq8j0ݒ&_"m*@N2-i M &tK|a9`^L(H{6N2-i ҆]$ {1ݒ&_"8`^L(Hv= &tK|kS$ {1ݒ&_"m@N2-i M &tK|a9`^L(H{6N2-i ҆]$ {1ݒ&_"8`^L(Hv= &tK|kS$ {1ݒ&_"m@N2-i M &tK|a9`^L(H{6N2-i ҆]$ {1ݒ&_"8`^L(Hv= &1)fMC 'H(S_G6#¢%f? `ax{CC-0L/J+L;Jw}WB,lo}[3vLz|ƌtߝ#;OzÛj;?+j6z& q0+_s}tog i7B6rEB[nK/t ^Uy⿍m/cv$V?%Y y(⿊*t d U[§j#0tug44JJ2<_.HJW=I"` (,ʘPS.!,E;.u\s.XJ!YdkRE?K 7 R74B&0(Py[*YCt+<9M25W)ui2.`,^b~(kL__O_ ZCH/G_!śt$!CGB3lXNeB" V^l'7V]B%?>pf4JAoaGGXF/%mޣ;swh'n7T~"|$*{ӮO& ixҟ6IFNf$??tf:ۏښHîjcV:ƹ4_g0Q(#d٠ȇyN a״qĞ(&/_~w}_G⋙{̏0zZ륥Yt߽J??ٟbda75i`Ckc٩i7'/Vjω;C((*;쀹A_Q ?Ƀ޿*hG^\s0KO(> do/bSUgu J3cHK (m.2FZHd & i! RZ)@O.(o4JAhKm>  (m.2FZHd & i! RZ)@O.(o4JAhKm>  (m.2FZHd & i! RZ)@O.(o4JAhKm>  (m.2FZHd & i! RZ)@O.(o4JAhKm>  (m.2FZHd & i! RZ)@O.(o4JAhKm>  (m.2F}^Eޛ ${&IKREbAE%|"R"|W>QN: ɽs$Nr3gfvvo$D(LurNzH !@8eP&sJS!j[Gyk/BETHRYxH6Oa]>ތ`}>ڣGٯxVo]?=7\ K`e:*2$2?p9 M _xRp%*ʶÌto6B2G#JEpKЊ+ P"?ϖl|]7C$+ ^oURl/_!12%J CO_? H3,t'O?]I¦mat˿L:Is*"M 3lZqO DRLI"M G_u5m#ypQh ɡ%//o2ƒlr6G'\H%~]Y^LRXz cQS~uƺ@0_ohn{V=,Y8WׁgX~Nyګ[o1ksdn}=V'?*M4KA_?_l_XH?0NIidoWS6bYieEYO{ShB ")wjXA|idCkqrcnfzo\ϿPWHʒ 6 yjU˹9B$0lLYєsy=ڟwOv"Ow_6zHiYV@vL-o[j[AU/|nX[yfO{ WOz+Ϭ,#NO (Ofkoא8|]XLs-"7y?0/?O?1d>{7gc7` +)ǙdQ$$fMoxxH Ă$jQ1ul](&Jm_THPITb2#GL(Ȳ|^%e __ ]x?q}{_ Y/X✸8'WBOםJzZ5e0'u$au/,Zc͵B>}/^|aAX҆OZo%ƚgϞ[_/.x!ګ?_P?K8r(sToP -ƃ_οIs+EHc+3Q¬tTWο8/?9+@IDATct8f(qg))qs(ͱ(Wqls),ϩ 2Ff'rn)\fY*=oi~NU8^ (V\%Wў4?*pES+\h[SNeʩ.WIU-ϩ 2\k *TS赀rjURqyKs WZ@9*9UT+z-ZrT\E{p*PNpJ*=oi~NU8^ (V\%Wў4?*pES+\h[SNeʩ.WIU-ϩ 2\k *TS赀rjURqyKs WZ@9*9UT+z-ZrT\E{p*PNpJ*=oi~NU8^ (V\%Wў4?*pES+\h[SNeʩ.WIU-ϩ 2\k =hhYlWH={I&~jj/$ 1ZŷrKvd?O5'hiĎQ8 6ҝLMӅ)ΚHB8obOf0o{syo1㏌2s.{Ypј){3;Lw]dI[Cbqd윕)Qv| 6eQKsVFS5"@p,RA?@fc Y/P蚔Qhjmn]qwf[/V[93/l,D0^YBsQQ*JBT`>G/9Oo|h/?1fqG:iF|UBzLp07~w0P{'777793{CSeB3a@VZL'Ty!_y$.F<俲"G[!?l\.I|8s(+ |+􉁪 !އ7!]:bBL6EX?@UdGC#(_w4A E_rmaR\udM=F=P0h/3 ݰƿ`o1㏅ ㏌?bxG_fgƟeDi$㏌?zU&Jcn50z}4h "7 F"-QTtS(Ң hBAYon弆F6~Mg-/g9>/䐧Ʃl%yyBAY@+!OCEj%yyBAYʟWȉC:J'3?寐aSh  ^TDN]U|ݼ#cZNl% ;sLi"(De;mDq+""Ui9:: ` \ #jx:q:ѱPB+;ș"nޑ1-'x?D9ĀDui9:6@.AC&aWo (W{oVgY-H؁6`?P?8zJ>6r@Af?sWvp?8;ySn1P eD1H>DҘ (||-nkbld9?8pMcF6r14s;q@?>V*2GřC>a)0'KW(Ng)#:C$C5,u O˥eߘKZRS!?ƼxZCDQV@U:-)?6I2MiHkbabyO]$s<bqG/Th:嵽CX  $/9HR| & ƌN-%b)C|X')?ڟh @o;%fQl$O":ː!u@0#?8RpS8Q>8fƿSA :Voο9v)pH_a L`7ewA#x"R~ߚӢ'y xjIPfy !u<%b-B$?_25@f@ ў2)ZN?8eb Â"k鍊o JJظ؄NWM✢&RU4zKH*\BXXoL#)?_d/v_6tԦRq^)x?9F_bMHV8G"mdG5A xЌ1ob `7ɔ6`M\'5?2#dadfc[rmpڢ2BޖY2*e`F94krwޥ kςƇOe"r&Oݚ֦9E;{4dKhtnloya }ٲXttl) ֊`VfP[mCapdqN&?oD-S//ZIp?s'78l\`%2Bo?2(W_$*0+W_ahGvNo??2#i`ו$9q0)bN2@6 vMrPeVsYΩ6OS\{r=KZR[B%+.SjQ>Q34IZB>$θeJSm??u#;>݆;5E]&ʿ #2AJRf [/@ !K&k.N 嫰7yKQ4OS`A3Qe,G 5a/00 ?Ip?w39f!r+1A%p?0 肜ԩ$2~F< 0!bCDa4GSq CK /?!蘡l ] 4b(Qޥ"ᠦ"Rme*M$<FPhh. 1u/rapT.?me gZJ$HQ$ٿA@_E=D3Phh9ۥk =zS2EXR3jUw@ԧ?z|[ 6O"d?{ir,#ǟB, ߨ'6ịֳEbc7<_" lz_TCCBOߜ@*46rI矜sX2f7=$ZdY*ExLjP %`?O=oS +8dQJ-RcI-`k"ޔIT@9 QsNRh}'Ve_8}a Roжd![lewM?.+ &كRY7d!a뭿^ҥߵ_jiEO37x>K}]w9{Q:vӑ# ?ʐ"$Lj=Ù6z:v7~:wU& tЦa=Bg,K&lN7w[G~& V?:{QE M!P:mQTh /@t"Z ChsDdP, O(*(cR1Qh!G"Q/@HG3S+___ ~=}7_hS~Cdq9IC8gϴtg_<15Uh/>d' JܬDdojQ6"Yig›⺬R`X]&QT?Џ*Ђq@)Ԭ>//ĠX>w[I[>Aj bTH dګ`߽*am>Zk / . <`xZah*Jp0uz^Y>Olk/,kfOgV>rd:tl^{819OD&O;¶~LZ" =̚5+\u")Ilwem)_{Úkx Wi^{ԯD'OmzMs^N9U[SO;5|T<2ɬg)W^ jdǰ_ٟoy >'J=>C)X_޽E^n=H8U\JЁ- 6$^^5Z}aaĈQN{B3Tyڟ dcs_P÷п.,GG!ie \O.ώxrx‡%[[=gyBiV!~E5PhV&b8p~/ 5RmJt}UϚkw9t믿nOvw0o<%#G}PhZRk v#9oA?\xn|_=sf瞻&L-7 #SQ\Yoaz3gMSj_P|L)si =|Ȅq}DseƏE Cg\}c;k_nۡp`T޵[C5]>ss5]t >ɈCa#F?vX,|zG߾}äs=!`J :pЁūg͔Jzt_V?9_zKq?Axz1amIS䀧&4&-b|4V Icڒ*'OkM#iLX[R9i0Ƅ%ULOv0FҘ) r[-`$ kK" <6a1amIS䀧ZH֖T1E>AxZmIcڒ*'OSo4&-b|ۄ1Ƅ%ULOj#iLX[R9im c$ kK" Axz1amIS䀧&4&Ka{쩁iJBQy(YSӆɀHZ <Znk7/oAcݺu }oo{{sxX47ʋa ݺw o}+ȓg{&4aQ㞻zj^jpTKSFO7v|c Ϊ᾿ݧ?nbRZ~\3)X6ؿ1c;3L7@&oGfyWI%ĠǍyo \Fގ lUӦ]/<02'b`"4jԈA[mU_y0^z9ϟ;)b&N>Oy9s:>MR%۫&43uEx&}1ݟM2gH+yٟ{&+R __tRW?ؠ!2D"Oo胨KB`8P?f_qP/_+6H?I_b[(V&^75 vazEyrJHq/,[rJH6WBK =-BTGzxSS)9NR9?B'>$Y l<ъELeB!+lQ8fPp*U i!?[nUhmXcaq_Gwgw%BS?5ʫ%[eȑX 0Lo̱9x8?H^w~6V?`}켼C@,|Z mQPi.ݡUT畦Y*g`ԩI#8S[C@d^<_p]:BZEolYO$3;REҋ/ 7e0ir菅O x=TG>}',\;)'y/ݏ<-)Gxy?D#&0#yK1sF!a_ q`O ο Or}iu$e0?I>k/:8ܬIi4kݏ7;]~Z} z@?>W_&ӔPͣi .RkPJK~? cͷnmC5ba%/D UvR;\OmgrF#yy2vi[aMMa=t - 7݀ؗ |?clC ꪫ f3<5\3<ᦛo b;>A?&}kBTjϽ [l>$Î$|3<71<jG е>jXn[= qbw&íh_X' 7 ]G/{gb'̙ }#r0 >Zk/Gң؟O~rfU뿶CA{=gNxJ55paP {wϽ_{_Iw.K6~aEXC /YX ;bc(mqg?DxWܖ‚y5ЗjB[9 [o 'ڗT?_@ȼ W_=$/Z _5_[@8.w^4'_G:r)S8LV4-r@ƃ/߲M2@pC)K[47/|EBҾv矜rDp'2FpOi@ oݢ$y='L:;>aR\o)k . .'>f6*v_K?o'G__WK.vk4:~0c0aW^؟^~%#p3:g"vji)݊v0lᆊx@i.>:b #h-/ X43aoƎL~7 a1CiI>)a(y/C G>'ƿmu_jؤhl]`Fƞx(A'g"<دys_\[H4?qR9.Oz\7_mt4}tv@._w|/po9}a#&|]s,dj'§ُ뽺%vKH>Nla戀ɮ]DS ïu^Ob} ƮO^Zvz¥oaa˭e̠:1P}rt/"#ڿ?Ogj_Kڰ( ;ҿ%d ^OzToW1:\2oZ_.D_z?(evrk%Wd%b+eQQ +bWӏ|EK?PB} I4yS8фOο`?܈:w4\m2Ω+i,W٬&@\9'U&rU!5%eDH@rnPhhi&䆡lT+V0Cd$0Jhhh:?l i8C4,#&bZF3*^A!|oCleY{Ҧ l`K{o&Qp7#|k@ٰ6>,Jgv.|#J_˧w sq,48鄱rh{}L ?9+l:|Ȅ,b,;ŋ߸qBKkkx7X8V?aB- #Gx?=7a_`aXV[8 b!npikv蜠 t&3\~U^ypء+^;yˎQ8).1SL)]oz\7n8X,q7L:;qE4#wЭ[p%a!j*@rDzY|֚k /?x F r2(%wO GRږ,ƍ BG--cx>uv?v<9r?N=$[gۏ NEYSxrhRiYө3',9[,BZ;pR_9Ƈ֖Vߛa8uݿ\/2-<7ղөXD(ǜ9s‰m)B-X#rF(@IDATZ*ÎXlu6+Sv.A]N8pr)ݫd@7; μ>.:hD,ps o] EJXv|]+ѣâE 0_- [;9zaQy?o5#;5PK]_vłr̜1=L"EZ:Xbךh=pVOW? BPPyk Qw$vr'ߥ !J)"*̬?qsgY/?8wU? oߜ&ђOο9CMTyH9}_m\o{{4X~i:5"J'P*RkNõmZi4E*TQ9\䐕vL> Dr8$J;Iq/*0Gp"HvL?X!æz8+TdrT'Xi4+BZ*IPrT'Xi4VP iQ&AQ9`$bXA+E"%Gp"HvL14d+vߊdah.aчbKʓO<`AI,p٧9vzϵ\r4cjoLJv> wy N5-'C@ AF`CG?R7M jO/0| c+AEo ~ziG 'Mvd#Zׯo<<:LjJM<\oя8KN^,mO [[b,Z5|֔ڮAmC+he,\/§ӗ8"^8ȣ%`<#:*g5cz vNJ8O<$v#=\ݡQ/eoL |so:.H} QYܫ^N"caӿ~O>=tx=p8;>U?kn§z?>.,\=˼\vcpGh7p~+ҿQއ`nN>Ewm oWgg KH!S3Ճ§~mq(YbS'aǧf?t. ͝;\?~l;mpםwjӾK!s')\,|` t蜏" RGcʼn4815ڃWcIP ?GAeO9$K\jʎҿ<7QX$_U?OJ* N!`L!MmWHiGJ'%1~5OfR Pvmm!0hgva7H /B–[n|=lەt>މ ,[eagv=tハ^yUҒ,W__^_ :%7mlq\ʵoqz3c5 jIµ^aֈm5?}isogLNJ+VKШo֖;v,ݫlp_m5,yL:e= _<0pG,}5DNuHH? 0u5]DaS`[ñrQc=b#'_]h S+Y¹S&;>?_ŽO;?n"p& Pӿر' j' /eW {>V{83Tޥȭ'1'-tM‹.xw*d[v{ap_pxKo'LӢp(ؒebo{81~|’g&vop2\+j=+UF!ٳGBr|svO_;聡`Sjm[gaͷmh C/ⅫE} P{ uf̘'=_E&m𕣏 <,Sטg!ȳ@%y_V<|Q!Ae SgeP9Ȑ?LoB e*.Spc[p ;0ڎOM"h ~R| j! %GFb8M$VZ_q? F)ߚ{tkƮ/Í7\r;vކݠ^nPj7e[{9s׊#Sg ] QGY#`O_cW'|=xa_8_tF =]R,_|'W1`MdwV1haBYq_0 A/Z\\lp_v: /(0V@ǘcN;}³,7wn}{?LsSԩXkr(k:V Fo+8ndԓcXg$߉&L8G2eGbGbG.}/?ȁ I[ o!Cw=~_gj5ѯr"ݻLᡇ * *;+7D(MẐMv|:><. *ڽEyt [; vOO)l]Ji>GYBH|&>M2%/m$$+O/YXgu47t:-;ˏY8$;'!]?l ǟ8? (Q?D+_! ___(Ce< xa3!L?|\9A,!?Q_OE(.g)gi1͡#@\%Wў4?*54ȹ3RPE{>㊪eLk*WIU-ϩ 2\k *TS赀rjURqyKs WZ@9*9UT+z-ZrT\E{p*PNpJ*=oi~NU8^ (V\%Wў4?*pES+\h[SNeʩ.WIU-ϩ 2\k *TS赀rjURqyKs WZ@9*9UT+z-ZrT\E{p*PNpJ*=oi~NU8^ (V\%Wў4?*pES+\h[SNeʩ.WIU-ϩ 2\k *TS赀rjURqyKs WZ@9*8G5ZߌP Rk^y-Z@\>k* ҋ-i؟_\?~Oa%k3W^~9{H=\n_{;}Rc%.E|1_>՜~DsU7&}bsa]vg.FFw=`]5_,V?Gv3jF R\H^zAXouoZ"v䵤N[+$#;~bp衇5XP'`w-IxaGsϝiSr"y[~,|gur#;;hQGJo;>AO'w1 _fLݬԮ/X{ir돉?9o;`ֆ>wfĎO]ƒ>~zrn]$7Ѓc [c#[7(q.@{Ww%-ĎO{6/^~#F)§'f?nL~voW\i~{AY=ww?.Y>)[ l=c׿O(pMa?,|wt8%MB'UR' 'WYeUma˵Q}WKGR=EC"0OY?`,kqǟz濅'/_13w 7o5Y-^7BƜp)FM 矜|O]dI>>q8:?2 4z%D ddM !?@mdm25J_ d>Ň'A8٘:+ ~d&)?L\ǠͶ_z_62A'8U Ħ5GR_"JBTx?@Kj-a7}Ё^S3ݟ>τu>W vk8'?A§IX$mYt҂]b4t-Usa×Io;L{O+,*>w$8~aǝvR;ē;ϣ0—O?;cqa3hzz^WpGrSoēNV/M_udI2{2;,|BUّ ^ S[Py?QIޅ"?_θ:tÂ7XF:Qv̙3;0ty9ܨЕ~+Y4zpҏC x a]*_z()\_{[}otAa,|裱(}Ӿ~.|8tr?k0eʕKݿ_uƬYK/;{z}6=So wVZ{~S]G>JT4JL?<IX !'€?@/q'A/lK$TO?]|-\Ƹ+8q@0g;>UdD#4+^EH 4\Xh\C#ؿ~v$ORğP?TAaD _H_eEƏ7$G.V9N~F 6MHY))@oV0]?@[i>uWpI?kv=V]U<꺫wtAX4b/})ٹ*.bqbWD؎ Jp s_s5/O ݊8u#,b:g}0xfmX\||ѲS]āObbL$O}*bǏa>X!?Cae࿷#w|ou׎W\zaqFL׀9޶Ϲ&⪫ª؝c9&][nU7yǝa¸2T"D̞?-⹑XY8,h = X"vԿ3lHp"v|={`0({w9=7i[>d'<| ~Z، a 70L>/:\ {&p֖0nqln_%G o{O9؝6h׏P>V@-nPڑ!(i%S<w_%,^fW+={jM7%տX-w뮷7D?om>aɓo]^_ (]9hSCsnPƢ[AhѢNUdǠVYEð0cO=dea…z -$cyD ^efxkiOޫKv _zw%LC;k'Lbְ QF §xuN;e̘¼9O&E4_b#)~ q7X4}4Sߝ?k1x E5 `w%U[s5+"c￳Y+_3|3<:c1΀GX,އ vLݛ3*E/袰Zkźpw7z?ށ&i F?h]:mUɹs,Uw5,bzE,pc=Ts77_'6jBaڔ)5[ë/*TkwN{pKEF:v^r]Ci#-4vlxlҵ9\5e>%KF !nݻM:~X+Gg~OGX,&FSI"'wO?A]7]нC#?_v| 7xi>{o;?/Kcg.xJG+7lh2h4rQ6&_?'P3Ox.*9BG9_KZwL=9_ K+ `1*LɤI:Wui9: 98o@"p!YؚPGDž KQL ?g? I5J*> OrHuF0+`ZGKi¤hCb͆l64X/< *aǝw&=e_c=jYh{oh"/ßS7 r+p gڰZ}ډPp_ouÏ?n obqGz8qrXk5L.|D?~x!套^ ?X r_g;*^ X0ޣi6PAcƊ4Qc1*Œ5|_&%lQTTT@PvΞ=^ʍs=g윳J3VT'Z>|UbG]ֲ;,8;bAlَ_d]\W>u&Mbg ,{я36;Ϭ#^vtesݶI+ˉ}o`ݍ 8㶫I˖-F<1Сi>h;̙)gb2={hO9#d)"3OM6Tѱjhkuδ?vS-^{DwyF% WaSh믓cFg~j6$u"NuC@4u(ߩSlD!gʁX uJ4N\c#H\ٿ>e3)~$K@')%SȎ2,q]_?2*?}8A+2"cFB||w_Ʃ&?I?8#+~%o? I29Qoο8 D;0K5?§pafY?yZP^Tg$(Ni4䊲 )jfƷqZ'Jހ`ѝ3j~_w[A̙#-K%u7wH zig~k~w}P^[ Rt͜ٳlwTUKmp3M6r]ƂvM!(L#?d+տVڶma+t  \ /b0?Zo썷׷ Oms4mݬSX_5t,ujmwmI4g k6w.WoA~MٟZkeɓp}Ak'vy~z9e7׌^M1/kq>'d &y_`+նS9/_sg,2fζwre(Zp.zM?j=Z 3O;lJհ>lGIt;ʛM+_^Dv?Mw12ؐCEG)T/,/_?Mw UY /~e 딻~8כ;>bBܷu}d$^Ʉwޖ^4o;*jΣ=@6c%8͐Mg_>';锈SO:tbw߇zDϿ+ϾҢiLlt,йx-ӷ:˷+`c.k@&=&@zG9m,uX̡WǔOB&;jJNn¹Z_wMՠ^>"SEI \9tph?"סcFbQ`fj5UVrgfmŵ]or%ص<-m}93mW"Kď&ʕXL5bP 23z͉J~}ɟ4ܳ>3]:A74iu|.v,3:K8r}Pڏhm[vm7itG,?؃'MP!CsHX,D0 ; IG,:;E3`.jڑlearvjKL R/Up'W৛m8pUOο`x+mGS?9?zv}U޿_W]~J5-zr\#>M(vfYK((P O,3ߥ:(B=kEAhzb\d_Q )?`cs#1} '|mq8[!_=lVՌe s mM:(s+w[~yYveԩX,2vioݺ8ד&,3>_K,ldWѣF_(_yUd 6g„weĉXuU]p,N'XҥSgԷߒ^OMӛ)-Z m(go&`Xeŭ6.+/_Spt5Fn]Zo_~ ;@a!HbOw&~iYjxӍee4#~df:uZWgN/@YguDT*mgÍ6cl7W_zE&~Ampo_iU={]y}{X@VlxMO>he?_gp2$a{CBbBKs3AF<_cXq:67?=5ds{FOs,j9sORP܁1NeTiL20#omyRFe țz[fQY.3ޖY+eTyiJ20#omyRFe țz[fQY.3ޖY+eTyiJ20#omyRFe țz[fQY.3ޖY+eTyiJ20#omyRFe țz[fQY.3ޖY+eTyiJ20#omyRFe țz[fQY.3ޖY+eTyiJ20#omyRFe țz[fQY.3&aJxƖH;f6)ƷX˓ub?UHA.d*X?C<\44e۟mJ֭!~ɸFm7%Z$z,)0"`S dtQuv[G)d s-›_ӧo_~dr0v={=B|3?F͘+M"?o8@KM 8pIL8L1T2Xj?l)8X-/hiwSH//*,A1/OgZ\ Ouu$-|r9Mi>Ed >+L`/ )JSPƗ9 L6QT;!_>(: Wa9/ʼ\(Y1' H,059l 2kYa(ڟ嫔(Ɨ9 Ll_§Cl(BOJlš֨ZC@рR+6m8DOU֝+' є?(Կ ء|쟩^f##0W-^sPy/_&9v 37ͳh 3p֪7W_o]?㟌U?.Q$\4@\Xa|a#9Vߜ3fޜs/2S3OusioeirȚw8N[zm-a 7 }9ZuSSlf%W'OjsvZGAm AK[]N<Ѥ:)r)OnōF&D;/׃D1\,?WRgFRB+.J׃1H 8?O}=5W_#wm_]8wo,|MG}?XxgJ_ǐ^-Esc'a2?GaowwN?}O48Q&c,D޳ qj~s'?ɶ(7:F?0C3-o̱ ?`QPJ@4 *?pTYeC wڔ?o22XJse6zзJW\4m?Ɍ|vܲ_׋>Ed@$ZI¶x_0į+XUI lz+,#QTy/%6} 0@PY:ʫ쟙n\3z7*n׮*8j_|Af|եCO.q̳$p|o95,a#E'o?ÒsGο8oοa wyac-Ht!,0#.0d%\,'+uB ] wj8h>Ұ&Xj7p@4GCuEZ/7s pP*W0uVa3w )jt-TfVKeWPR""Pn c?gBmF# WG/|/?706caA(bgDKw|?{V '?3sn3gw蠈W_])(o++L˧ZڤO(6+Nƃ@6|eG!X T˕г&:_??_ɪ*} ]I&zDGSOڟU3U&(]mb%Y4$* xi^ַʫ~reUp0`?Br`+?/?]c F9īhp!9ڜk`!Ew!?`_a_1f'acFMƟZm']9Q/rzZUVZ5(QwӪ DEOj0&GQԿ06zvӪ DE2`?Q^DvX Y8$.r6a el K#^ZSamdSNDkں>Oy1OSبpQ?Fb5'_??Q7qkf 6yb7ՁfdQu!!eU#A1Y 4ƚ;xGMkz8y`q>C\2@92l26Z UGey>c(YUt(?ڟ*붳( lG(oG@K[p%?]$LdMjC(aT4V X%QQ5N@iB} S'@FoPcG? (ǂ?JPYE7Tf_oο9oο1qӦO6cq\`Lo8t&`'_f+㯌2jsƟğΝۨ#;TJ5ځF4*İH( pvV-'JCTfĠgAc#3?~i)@IDAT 9GMpJ:VUY 3/Ƙ)8Ck1^E8;p͘Rӵ&:Q`kԾ)^Nf:h9i]n]D1VHwXHԬf`qFCC$Jك tA0T_3zP(& &#%AA T=(?D i]*׌ʟ HIP"{4.kFoO Z\[oޜeDqA t^ |"MH!ųxK='_J _s`>fp™9 J_j_%ߌ?`G4#?0O?1O?53o036T /?>?#aEh'_GaE§lQYIEU,Q4@&Mg#"IZm9[86;?6[k]I֮E%+T'l`` jNձO8Z?_ :s1ݤ UPPFSqfE&9pQ EW8S1PʄA61Hld. b2C ?8#?8PIG(p_>§BG{Q2*i^PŞ&"dӖQ1HO8=(٬49Gz) ^iEqfeT9S'Ni(bO+c6+@-bΑ:qJC{ZQYi:msԉS ӊJ3i˨sNPŞVlVN[FŜ#=u┆/8f t2*4x1fӖQ1HO8=(٬49Gz) ^iEqfeT9S'Ni(bO+c6+@-bΑ:qJC{ZQYi:msԉS ӊJ3i˨sNPŞVlVN[FŜ#=u┆/8f t2*4x1fӖQ1HO8=(٬49Gz) ^iEqfeT9S'Ni(bO+c6+@-bΑ:qJC{ZQYi:msԉS ӊJ3i˨sNPŞVlVN[FŜ#=u┆=;>/IF( 4GCa,ZفXIllʧpzhSh7gXi?GC /q 9+̝8T>3m`UsO1 ?3]HN???$ƠN"ь?2#kbG_o(J,սO~,b' O.jiJLOQiJLOzg5@4auI%'Ok@4auI%'Oi iS䀧5uT iS䀧Y44MX]R) r:*4MX]R) rSFH&.9i~H&.9wV# $MVTb|F $MVTb|; K*1E>AxZ_G K*1E>AxHIӄ%" <ѯIӄ%" !"TRX?自H?_ԗ_5P>냁Ag! c8vDA?8*G8_q'ߜ8?0Pf(%6b9 3߿_$0J7cmQߊONz JH- XƑJ Hq/+kJyTj@edT@K@ -E9WƆJ H ŴLOR?aS$=VC-/ M]@0'b[2WVQh`mOjqr)+h'_?sa>7Q}(o ٰoӄT?/u5 p'ߌ?)k0o>2L( 1)aƟ"+/-|jK:]^92c=(MeN=ܟcNv4>|S_ /QȄ;eY5aa27QJKk~? c 6ƖC3ja50hl ynնײV%9>HtG3Ӡ_?Get*SqԈ0*y(矜3`,_bG_eW_c3ό?3!~?EY-l+<1$J+ew{]CEY4nɫ`>iSzH !@8eP&sJD QJ)2qSz&R'H2P*Nk4:ABRq$L\#ޯ  S&e9~=MNeT2 (9i"u(I@F)_O$D(L5rNzH !@8eP&sJD QJ)2qSz&R'H2P*Nk4:ABRq$L\#ޯ  S&e9~=MNeT2 (9i"u(I@F)_O$D(L5rNzH !@8eP&sJD QJ)2qSz&R'H2P*Nk4:ABRq$L\#ޯ  S&e9~=MNeT2 (9i"u(I@F)_OTw|*Fz҅OY*֌ D&'el#kVS#Ԃꁌ?/ǟ0r y?," uNs?0eOοcH&+Qx(B7o߅V$]If.2J7||l)9ȗܕ(< P9? H*㫎:/_C<ecd 4 Š[˿+6 mMx&?L]ȒA8Q\ iI GQ /TA845lmw!on߅i?UqW%F|-CR ~ݥ^l&(ӅZ}S+W?P(&|bRP DhgOAt鲖zϜ}i2u6r]<߽Wvi'y_\hdI/D[) oS ?a 7ߜshaI'7f\<koj+| \tV 9Kja9 L} 6\^ͥt*J ؿ Y =yf]`tyGoM&r$*,̨3&ܠQ?frÐYγ0sm\wܒZ'[HQw#& vo4,rCKJe텆=ܵ?6[3ggby%TGQK fOy@,`ƫoHpѭKqw]w 7X>:EnV͵ꫭ*~6]9wcl.ƛm*[nP*3~E٣?/p=6)An@%E SRʆ)Peփп={HO[d1}M>㌅K]דs=gu{ڵ;n}Ǝ{rWl^o̘;ֿݷO9tu$ vOݠz{R?nѣGɠFlgmu&O,Gyi~_ߢ^Fiv y7qOaJ Ӫe+eܯި^G&B߿+m؂CE Z!hooW\:d#˵LτB'Aˬ<iI=ٳgcG o][~9i _pgƌͷ3:S#!/B~zp߰{V }Oɚ3wL0AO _&lǧ-^ӍҊ+,O=`~'$[o=(l 4_k・WQAy;'OZ򪲤0O1Gj3623T9]/ТA:*F 'o߈i?M =orOa;}/}h g}Fp#Gqug}oDu[w,-Sݐ@I8Qhha aq Ef7*E)8p L@J ?_v|m%&\1&SgrA-4IPVu^S g 2;>ٸ`g{-lL䓰ìf#$Q|*렃io\F 7q4x-|ݷ 묳iF5}dE8G9v|҅O0,S&§uD%dr n&5enfi8o_,iu> `2HWOn,QqV%׷{-[,@;Rp{ =UOƿ 9rxq)1SO x4/2Î;ۣyݷٿ-5OOѐ([ouZhOaBa ߫A"'wo?hpIwjڿgIFmg(u|Q*i;>i&OƂ3Iw;ﲋ{zMxaҦuxֿ;eڿjqYݿu{*?-|µ\i;><ǎOd3sh,Lq?Omgv79sZ6([omVW eaA*?O*O#H8E炽_.{0;3ROA~GMο>͝ۀ@ȞCsVfQ ?67e `v0AAsfFeE>2윕 ]2O1v]bgihDT0PMSb/fso8r;츃t vXA>4 ;=,OJ_ndXv*L9܏(SLn.i={/mB{R#vJ?+۟9Dڵk'|ywG?l2 %^}ydDӄoRw_wUV?9NÎlc_{U/dh|vm?|63mdM66mޒ;nM>K--z٩,ܲ2bO|QSNjE;ڲ2aҿ-aYiqﰽlfƚkʒdK/$#GsXU{>>[c圳hף؉mXǿSoMWʟܲ&y_uUqSd34irk 6BeslUwԥLx<1ȭ=~#;i}:S{J0Wn馐9orKh +K-N^;Vc2OӮ=#C;o'? k̜5KބN˯=[u(Ko%ZlO<ݥy!kZt}ϽҺCzfO~?pQ2 7ǎOgc]u7~!Jpmj82kJEk¦kJ?>MF== -Wy5#m۶{FYo|q;'yA[o﬷>$0rՖҥZdocom1a|f{Vi~`{O}Jƛu';> Oimml ,]DC,b𢋵UdkkRo=gWyz;-)j>9uV4[44[z*i`eJ?W1l">fw_G'o?83Usw0O?/ߜC㓺a,nDD/ne: TTejWoFW =4 OB}Q{?ԭb)rg{[k>?zzV^E.؉ r=Clٳ瞓-gp]Sx_з#eϿ{u!̀e%U+XnO:/#ǥY Xt%];M=rmXŨN^y55忒LD8]۷o7%[ߒSO:)_d,ԍx^cdf7>>uIr>Ͽ)[ge?=) >lOKϿR#}ǮzUf#x.︓Dkm2f$ .:ɬ9s {Boo oѪvi=, Y믿^x\,[iŕ?ԓ;>aml ĎOU~*_+mZw I>M ]俔k$1OgJWuHyJoO kX)o$fNA81_:fTw|vA?tA?5fA7?8Oug]CCC#|c,Up$8 @g=^KP'8^!Czփ>8sHCI^8u00/WȉC:4 NSgC^zP(8sHCI^8u00/WȉC:4 NSgC^zPTv],-8.ٗ-Rㅍt.@a>V$TAmGsڇڢyٹ v~̸?Ac!Tey9>r:y핗.k'!,"c]v'~fBɓ>h~Wҋ.^xVݷc] s}j`gu`ko> %sӭHSkƿ&v*,tYkmoB9 fr;" 3w(2y2vzzAV_Cظި; AJ6mr`͛,F>pnvQc ,:zv&0o|G.vjo%?ǂiZ.4K>~,o J#Nt\̘1 z?s|UEU&Oگ}&>zjo c.,ݿ6\rw?b_qoߜ[j%niT?svϛ5ltu3;(𣏬Z?y]9ŗ].K`aUG,ngϚ#ܷp(O꾍S67 dKh߉';o|b_ΝM22$d)n;9ObG!̚1Wd»r]om~]KkOwR[yeN?: ~T(0doL6НƽBU+<oGydxe38__{ݵ,Z\d_zOykzӍk?S;Hg N"!GcАfr9Ya[> خ+]+:l;D>pyl 76l3َXHWd˴iӬAW]uNFbӰK N죍ʠW3!C {]:!ccK:]C=ӱXt]+*kv47vޓUX# 6veseEj`y W'b3]kOJS).[Ҁ1~}, :_L42O>1I\uOM|??08tL L} !)j ?8J#LVE7qYߌ?0Eqe*'1ǯk1ɾ֋`xrk&% s%fޑ1-'Y'Uor9WH_3Șo*8fDOAD;2$7f8G(&eEdbXwdL |-JI KtwdL 폳'%]a'=úx˧Z} uh]TO[i?dn7ߔ5t2mȿ?e,ni#}s_EGvM%_~q!o_v,:?|DؚF󮻥]%L/Ryg|LH(oɯ}749O'?};n|<aE͵|g?w)>`iɖ[me}>vw9ǟWYUij d*v3|}XB^Bs΄L,wy+̎uǧ'vkoW/byoq:lM AX|PM2EN88(8UnVzgdk 2Wc&*E*5~N?O:YJ:@>տw_@m!rˇ wbQ r 7b2 6r6{֬p A;Ŗ倞{T_8#G?İ{@HwENmVZbae%agpXzeX6s&1U^㨐}7_/ECп^ڽFH֭ ,<($^} p1l8l 'Zs3dsgOٛcadO3wOuu"|kZן?'ٶM[[|sq7hgo.f(\iGvvI5_I4' Q ˮVA-Lvu ::DS+BvaRhb) H5/ `E]FA@OS0^ژy: +΂(B qIuGOzi'O ƿzT5QPv(bHb/5!.)IwT`pV§ H|<4/s(+ /J3DTR\Zcկj$C>m6Ӕ&iEEzU11C4i[2Mii.YIUqF[15`I_AuɰTcΤAJ+K VDSY i8cI̲{6duJ!gةa9|ڪO>a);vyEM?Hfd3/E3.5C98e]-e鐃{Gז=S?RwX 7t tͲvl}Kr=vnQ:v:ĎOڏ=m'sB}}  Z`~ZLoY~1G-OdlE.vc.ңn+"}{% ưU>2;[S?ZF{74c/ŲFZcr|֔nFma'$ݕ#Ge jd}{2cOz }w.yŰin#кE{E1ЅGhuAE+3Nk_u=[lӳG y?H?r v,Qn agƆNB!C3v;%?[[h)og$a؝mXRez³[{<:a' ƏeA._C`a菉2;>}-n.`D"m.o2Qs@,|ҥ \§hѶםtG.mҋ~!ϿBUV M_1xU?\^vx.yTeu6n~!aLmKAoQ?_0'B|G㿚/S(?AK3AÌ,sR'XWe? A cGe /T?JCM`/ՆڡShT(/Cu;> O QS%7)rޱs&IS?GcS0D҈TSjL".s\v\R&7a߷r1W H!:K"'/Tlƌ+4[Zb pV*X_.0|eO>>rd|ߞw'G )P‚vA:><2/?Hm6;ogS?3Ҫ rVzYveL;y%,&^0Y< cM O6cd7ނ+h"k8;X5;)CnZ`OA>#X}+{ 0]v|ZG`ן *d,c<N:YU,mM &^{U= |Gr?bK9 g}*oƀu-PvEw[sNv=G:,o UζaOdڨת#Yg߷s"HG+-Sru4LsSyo;>@꿣ڠapa~u8@ƌyUagczuڷ|89K-ӺUp}Nj/%\5#'N,_"_̎tO)_ϟrFJgQ0K8ĿE[?l 9k@IDAT/{iV1 _}'(WИ=TwS8BxR=) D[A(d俋BKQd  ɘih=Qhh9`\?{c 667ʜny(~a毹WLJf){$/u.mXbӾG>QO,LZl!sf͒G}xDjϰkM}C OhȨ-B;cew39;sACHkUT 믓A|l sd»[o5qLⓓT?v&9|lYrUzwX;ؼe;2ӿ7Tν| 7]aM,:<r]FN{u; Ft2ztIo]SVDnTpu2TzUurt͂ȜGh?ڶ# ]zcӘ^܃g4.9>i 9L{ʻuj NDT<˷;L Rt$X̓84uwK/#hhV{:Hgo㱫,8vd8QBJ;d]v2OŎPbaqa-5/\rݿ!ߠWJ.iŽi7l]~qm~70?_o9ղ^پucǢӿ{maQ+ϸqrکOkߡrl?|p1^N;'v|zf3IC:wlsxn~1d#P5d y^bB,j=k+AX?tv\z̝R-_/Eu?HS%>P _CKk.LWP( Կ/ECCC7?/?AG-}w?B9;ʨ,y@oӬ2*e`F<4kr7 v >'VF)_]'? vjN6kH[ӨQO˕C{ j̙SOŲПrX r#i7oͦz_r饤vʏze~GfL֕_/=i =s~7Bm?Pϊ:XmfDixث,n[gVyztD;H.]dgd}<߿ITV9aT_/rYne[o3]0=9 /5^;>1NNׅOّo;>]u?"ߎ'h4`yfTxhOuꌅOgv'doYȞ.|*ȵcG./Ej]\uމ]3y!uRqaҶMQc,(/.щc"?.}?OS?` i"@_s&|/_'M34g L@9Z(헒5PVYa*0?ES*>+L`p҇|M(s(c0 H}{("UsSp)#J &0)\!QJI(8`|ɘPJ>e7.HCa_h4dWp/fcux:1mEJkOa؁&ߖ;u,2`Kءfc/o >Dt< FR,Oz\>6-#O[w4vuM=P6u<‹/ 7AϦ_ v;yݰJu%X'C _[?=,81.υ@  @|? ;ǨzZo˭)nʯug'4;>]}UvM#X.(v[ SN;,ݻo-K.0E](/"{e%CE->X~Rc"xV'Ř|է_%y@VYÿ{;a/`o.|jn^s<#\^h~T˰Ӻ]iȴ0xZ/5yW{ӍJ˟W>C]O*;iY,>,uX}UZ߲E7`Ǟ*n{6m9йzliܯo\(TWǶ_?x -;oi#ykX']ِ0ϩ&[n=\">]Wo=ѝaǧO§߱2kF  5~&gc7 /t;dOir|GoWo'US޾)& zJo#Η?SN#=K;[[!L*[`˝&sHGڗq/_9qOM&Y$WM7ﯫ]7wz}va%./sSNsvJ{y)t )xt:OCZ"\"ب$W.x.Sj:OSNZ8OﰧN[9?ڟ`j[܄W; $я фZ )Z@]Eǖ*bCsn ˲,/q7|O]LA~75vm3?>ꬷTO[w v|e7]$Ԣ8XKXIl j,{],`GM,Qv bCi3{}C@T񸝝ݽݻVwIa% v͆u_䕗_?o 0zeM/\ߍq3fL^I)zn]yuؙ̞3Gz`~4mLGAv]r(6uN|=m'\߃#v:S^|bdJ;;O>7ʋ{[v7p4~<ߣ{wǞvuZW}GXE:iv){ =a._q,ۮ@-Fg9m{`Kꤻoy@TaÇKuu}r/P*4nb=MsGAÎOYӱi?tțo5OUW^YC*[.!`ǧT/ {aǧeꟶ;O~iܸMc4IMW;`_>Wy}wOϛ͟.C Q7ʋ__S??r 'x88Bk?q3/M|FGWf\ A.s;+J6jױJcmP'R2rʆ)?h>2`I(MJ 8q㪓YԒ\"*^qX ܪVf . %(~, :R\ Ρ̿uW2^O*gM ?wx̚3[}>8)>0)~`e7ӧ=lp)Zg]qa7_Q#G~!AYA |vle4f]|4#9l?<ڠgX*ڍ۟-Z _p 9 ɟp2uk/g!]\s/&"р;X[}Qۿn;׷L|.r_/Kk0뮡PIp[mskA&d0o~J"CW>؍GyHP5;̚9_PߤYSYvv&z5?ۏ?oAdwΡҸIc{Gu3lݐLbd6- w519'f϶J_5gi;, rr:tg{->i;>!enK~/L~ּ*=)=z'~$CRwwHJ5{wr-7o+EȠ| >F֭_O4^u5fcW2gg  I?Wﵧ^Mg_п/2YЩA`@J؝e.C:/E5KtWO>?!|ѣw4v| wZW%c>-|mҴEs |>/_x>|>uDP[۲ {YRvg}.VG#*?? 6ӦWz)艠=..c2UxIO5G+U|peGv9^#7Ӊ~hGMj8h Ձ8 @o"M4?HGDbGLufN]Au-(u9ǢtvM`9X-#΅j0KZ:BXS\+  ەyvNa8q"%sCf[J2^뛯*ca]~{,>pA o2տk6`wWS`V_Q\%v?ѣIӦvɎ;QOFHhUW^U8sr'vb/,råkW/ ?`.C`{ѸAK_WiݺsSO> 8ؿ.;_:f#PSOQēNjec+%PӠa&mlm)`b:>HmأȽGnSztB͠O8Њ HCߠ~r6D)z)̩m,6T{_rWXz֠r~5ڟoVr;#2y٧P;ﶫs|1qz/jLu;Ak'mݚF O>-esΗNk,鉀ƿs;WVqyYWQ b׾C!:|u적O|nVI;}* +Ʌ\d?mT`yw2 W蹧}*";W_oGbO.?]׿G$s SHEq~0n;  EP/lGNA֯_;z9P\c QAGuU[Ԭ9vDJO8Y{ub  [JَO=TnDgdvFwYzO@_dn,x{xTvڿFTdKKzߘDÞwOch2sNK?L_9r50OZnK2 U>pY¨xaEk?0?:p?lly49*% hP$Sv/'Jd _PriVYOVh')J3e*-z-zHG+'O2}I ]f?knQ&g?V7%Wш~Z2Pk0A"PꤱQD~/MNF@='̲<#ld~c0a@AS~x;~6ۚ [XjI+IF)\^}WɧYc5LG:i;/}i o+JXkD v zh4;E} 'sΕW+ڏQ^=^C1uhܸq~i;>wЂrð  :PX?sPsSfg?=Xɓ'ˁWfrش_w` ?)W^,[;CYJ_"k݂ޅ.cK "b/L{vdR xs7iA<F;h`~B?=sy 5mR5Ѻ̙v!Lf5 F`[ǎefTھ7 uVqםby]qk.4@cvugT 7>;vJ ?}e]WウmڴiҼY3G c?̺UUE>\aZRw$k԰af#_-n1WriF$?:;nM:MAAgw lW9ZU7eK#{λfڲD"jh}jb" {{`N4E%P(z? -Vgwذ;e]ìm`^;K]Wr)XkY O,)࿶\ʟL g?U~w%ۯMS&G|@gn_n*?E.8/_{v| #?0?Q,;ee%U3\giYY $KƓ IQ?ʟT.\<-++Ad?ȀFGgô"YVe\*̐%%ٜBA:uYZ,N&3.{غ4*IJicY{0~%ITgB.D, }\ D(R-c;@淛Rm2\ >HP&Im/w,#z, ]J2n_=\V,cwiG{?[`߿z7JN;d5n0? ',m'lȹg)/r؝~.QGq QP5hsIe]*N~{߭%^(W^;A}+{ﵧ{>Fuρy7oB:@\kMiԨQ |rOdw졻0e> ;U&>բU T̙+gg?$uggϞݳ 4:7%\|I/׾ Z[i@#tE/qIB}`Ƕn9s?yѮUO~_;7k/~Rڟ~;rVIqW '"묳nvwߥ_CY_ܳ^^^$+w\Yf̜!{Ṥ+n@`+ȞTΫwACAB\8J7]tŲRW_\/'e*qqvd 5[j9պW:A3{ JAU////dE??qkSg2[?.vp'JRp[]_9yYNC‘QLO: پ=٠~5RvS8XpfUG+J JOjO`JO&|6?➿pțo)r4kBu&3f@ыejDJOlא.]p^{U|Hc75:z[@θFoE#8j!L*cǎQ#Ga留8ߦMYk-tߑxݱCܥ|!ɨQ2Al&GsSm|DJ;xY GnU^fY䵖^5t#y`gIid~3*/~~Tkvȯ~Ns\?פI3l:-"PtaTr !EN/}0_րƕ?cxaV}, śd 4R?9gAor6_{fK|*. -#?)/O3\׿?7 oppa3Ͽ̙S aSzY~׼E^ ;[8>2a5Aٿq(PTLr͠/ld pr6D0%i1Qe&^ve"#|Ε"& 2y\Q~,SuF{Ym_(↑b}V Y4ՠΠƊ]gs[wd`_# ?Gm6ͷޔN=&p1nC4i,ӾFݧ"; p~+sÍ7IV-elk/=s&o!۟C([n9v-[f Iv?tIpY ZT;sxϴ?` O' p^K?d㯺g9r?]El=-???WNҽz@N(T)d[(+VꤌA<,262>^c?8c 2vT`y!S^Xo'_^Ơrb U RJ{AL()(T!S^GN] zBq `-yV{%B5U - _Ƹڅx>S(*u6R=4f?OTgĈIm=O|2JGolqo◓PH@CC?OοvO?'׿???|SWL~@EޣX/ $Ȩ$2IL#?p\C߻V0 S gzdf5E\=͜B/e?# v#UXBcg(#*1Կc !Փ7^]8TBwqGciޢy0y瞕+.K7 'dq,#翜/?u _q_qOοp/3 _ߠd+Bg%FD FERJysJu ˛a?tGS -ٲr[۰_Ouvw%c TA=BY%߉3@iuVe?م`9nR*G()_qfeLr!K 󣏿ղmu23 U9Gdʙt 8q$@ Ix*JQf pG}?s|\1 _ 翜֦6& %YeRws] ba#g06 ~))<7o8K,Ek'|*1%)tia2(/ 6BxZl KJ1y>Bx{+I݄%<!<-6bI݄%<!<nRLw1nRLʁ@R7ayI)&GO˻@R7ayI)&GOco@ #䀧FL #䀧r MX^Rrn#&MX^Rr[9H&,/)9iyH&,/)9i$ub|ۈ $ub|4V KJ1y>BxZm KJ1y>Bx{+I݄%<!<-6bI݄%<!<nRLw1nRLʁ@R7ayI)&GO˻@R7aZ OFBSM'eQJ@5gȍ \Bj0aah:B C GS~</?txP=I'\7TCL?|aEɴ'RX8~Σ?8?8Kp(d5aO?sP 137#!o`Aoοsy?p C>yq JTZ&pY s 4Ճ_TW:ה'4`KϱԀK?dU,[b e9s9-e //do|K5"Uk l% ]/U+?Aay \ڊBQh`-`T'`58h9pM•#?(A'o/u0׻TGC EL͆'>q[]I/?9C>R?qo\}2!6,7>[7Vix\w$4Y.;*S8Ӵ`s%u0euq2x|ruXXu_ߟX뺰еRΨfZ5rj Hֆ 5X(|C1`}JiPhh 8'o?IEd8o?]lBX ,\Q3\ן\Sj p/\߸'r\#.f6돶(; GˏdGSRt+iM<@CǬbRlXF')? aHMJ(+LI#@YK????f!f") ε0M"Ks??e:uYr]@8!@"Z% G(/rfoq&x1g~ c¨ʓMm&*OA3ڋܺJMf,s?!_`8E3 I<'o $,Db/sEo5GP!?\' $_%Dp0` 9 FK]H&2CLr Q7TXC''d< , Ow&B>C'؋ܻB|q9jkkp5]p GR*.o3Ν&UJm ST -9JNלڠ< ST GҹDLsjl$LQ) "JN?XfӬ)Ȩ‘ t4+\Z ʳQPRT GҹDbXA˥Š<%Ep$@(;M$\Z ʳQPRT GҹDL:uYϽ K?>Ѱkֹm&kCl0VMBN_$ VOQhhu,Ȇ?xkl9sPޘ^DB(7 ;@IDAT2B7A?,tsC?8?8/u??L 1O#GJ*B Bq(4@r;w?spϨ9ԙ1#G[CH`ONq?=EO |M`mՠ'QDkju< U9O(,Hp]x%2OCb.༄d" KR\^ɼP 8/Q8& .yj1p^B\O¡cJ9~"I.HgTcn]tUJ@򶵆¾T)?t<1/?3NvIο87'q믺T` Kws\;__5:>߿Zb޳oqP(N3Et(- @h [ɻ-G(R7]ơs!M)?ڟ܆m2\H p7&$@x7۬Wp*j-u T%2ϸݠ[8ĢRCcNpy9R\KўizU8UPJmpJ,.E{>9VTC)*XS\kRCcNpy9R\KўizU8UPJmpJ,.E{>9VTC)*XS\kRCcNpy9R\KўizU8UPJmpJ,.E{>9VTC)*XS\kRCcNpy9R\KўizU8UPJmpJ,.E{>9VTC)*XS\kRCcNpy9R\KўizU8UPJmpJ,.E{>9VTC)*XS\kRCcNpy9R\KўizU8UPJmpJ,.E{>9VTC)*8Ew.ZlP'+i-jR] Rd*̈́B|e')?,+.f G_U@',L(8^$bja p/\CGr\d;gM||O|o||4gNԫK"ْq09'e ˣ^4{emo Jx䜔`Gd# 2w! ˡ?@bc2_0A r@e:u^v o} RK?UtL Kfs}ՙں5;}?GC/_?s \YC?qaݕ믁he?gLm'o_ëYWWWW_dǧ>fLq)"_ ME:}QeO<"UOpI`%wo4#@+~De$)GKE"? EEN]AE:`}hRхY-! %_Pr9qSP<pa`Y_/Pr9qSP<pa`Y_â kXOOI_/"Ÿ ֹbVjY r9L=E=M,ÅIG;?8ꈀa/9Џ_ƟN82~&Tlo]u05R?p%Sq)ן>`jUr\?pO\#G?r:_ןP~f+g?/BU77l5gW2O"Awdoz]8fd4D Q1,-&I'ؿ19GA$3!qY)GbBs8gihhMjD$/ bBq6O.I}SU]c j4U=:Z07Z&AJϕx 43g~Ͼ 5ٳfI|DSejh̠rs1i 8-RmrPeNZk-;lp`f4<[7'~(Cɿ~nz5µY>27U8̎/ǟ?/i9pGYO>퇈xpeL@y\[0.#q?ā'oߦa1S8'#gRILAgS0md&(O22O8ADE!u OEH7Q(3CQsbie9TJg%e '3'?O22O8AP(?Wx  /ˡ@+)+N?TmGhJ4_ |4֢z 3M?K^RXyւ.VD[5pTg%YWF euח%\R5l.~;c5RFqT";H.]IVS#>D^{dY?xfT?ߴ;()?XkdKK>TżؿMr˷ѣFd{# pS_a_&M$&M,?#W\1ĉ*AO6.d_T瞲{j9|a2~8_|)j*yWeWA.ˮ6[Kzeڔ)2z] SNsYrQH+IdلG~(g<,[yQNA`]O:u?8~/8rmGMA'O?1$,_:p[MÜ#}Af,<[Zjzd<(;>>"j9|9P_i>Rc"qDsȭTr7?"R(5"XsD9/)~kkm5uU*9y:=Q :ӏEkfg 3LH[oD+٬VR]_# ?}tyCքn[Yݲl|?DO&iA/ߏuz-캫b>lտۆT9m2.iP~ :e2}6@tѦ'&GсN k}Z> ?`1ΎyM7L<"cǎ<?"p\9WƠ']P\l R\zc0A(g-ՓCIV ?"E H&l<1cbh=qK bus{JIUM!ȧ+o긣]:6̹W:SIB%_% Av; ,j믾O>ҴEsY Ҡayч on97gqv1ҺqUYfxU2>FGRTi?7ڿ,~: ok`hC݅q?z :({Fك 2t[CI}{c}" a=[j,3ySiǼ_F[o n~/7l 8k Q  ,{HnK6;t=\dmV->Rq?GxÒpdWY,?_!;\44KEzT;>}jA\h9{>5hޗc??O)SLSh~{n0GeG8-w 'ʯ__6M"\ J?# ߗY~M/|<*Js(v`}I=|ʼn.x=ݻw6{=9c>!s'8dHWs8s fhhh3#pF̕9)?]E&?<'_ ?'/_Kȼn/*"cdT% (+5|R$>&/PY׍PVf0``W*rhPZe F0S^r"w`0 `Qr("eV^W'G Q50*$'@{Y|ߩ֭ܺ&@'uBCi5Q;j@X+6tX 8m' 8_ ^v<lx˴iC|ߡ[%O?v~*/2#aCv)^,>=~߸iȯ[_ڴi-4?Bƌ-9sk~mޢի7y |8` e-;)S_#9vtEV3 y>wޝl߃mQF)ɧɓy_w9Юzﻯ4kT^{Upx~״Ƚ#b?JǟjO FYvٶ2mv=9 moO{nZ~-yem 6Pڶm+#WpfWUCֆ-fI\vz|0f2L+L:umT+[oôSKY+/E<ӗ}2ot۴tlToƎ@^~eyAڿNuЧJN>_Px }WOuep["Jnf Y#kl_+z}5cvm} 2ʫH 46| m m\*uV2W?ϥ^Za{_eaY\>ypE֯'vw^C͜kU|dHf&&ƍKw28t^t'?Ы" =A׮]eWg1؃wܿswqƱ;W :lB |{ -[7ߢ( ~#I79(ֶ9 \O't ҋ/#zi#dkjw=eo Sh7"L{9ߟ5΄="Eb?ÃYm ˄뽧|_Os>ֹ˄=C\ \M Sg:r sY[ zFCCkK89sfV㥺qօKpZynY)u临aO]2tW`w߻w/7VڟM7Lxԫ]_i̞]#^rxT=XnqQ ygvw PR`C[wy^3rvswvl6RK[>'®DJ+)aC/7p]6׉W\iK5k \>ݚ˵[<5JV]uU`ke v|x||_q4؃Vt@oVU)sW ;P/?_C?  һ[-#g~1dXt4v|Jo!%_xhkaʭS2!:`<_}P٣Gw `SƲ_:,w-vN<sNӟ?b98_ԩ (K=9AwPqq 񙓦/>zoSQ r>p?7߸ؑx QGT2$>l8K"RRecmz$׷W4@Q\}2Ͱ$j Ȓ8+dN6vFЅ_uLu¯PZIB >&̿T2^Ol5;3ZYCGYw]r?ēJۥJˋF3sL˯D]d 70O4Qů%ͶT'l2K/#_u*RZyq2ty;(/(s(W ϧ.䒶k#dw96=1HMeW%h#ozɡ^r\vyZB̦| xeIGR>2 vVY׸I7qіQnG$,SS[#;L>cT m[M|N?V^F_>gaǂzp5ÏL@OVN[M䖛n{מz^Ovukt&NU2;Ǩ~-B38}z(Ogحiء vC@T&G#p춛OVO6cfg>4ֿ_o yW_>bv!vO8I~v?ﶋ=?~t vq_1!m%,)ozIh?<>k;(>i+#Ue7yo_i;=Ďr:tDi\(=MoF0Ms A#dr W;|a&#F|V-nb~)}ϳeuNBj@# X.~3:V-C]cw5ת; ~r`du kv0 - 9Zfh`l+:!q}" v;_;OìA<ڶaz>hp5W_->}o6خCs70t(i~֭k1&36m:OWmB UR/o0)t:ϟ/*og&JH39PV\p, ?B|׿,afLpA'o?8TA碾Pab4!/sC%Ju?\hh1ǒ ?kzB X5ZaTbH '|yZF&!7AWqR[Ɣ:9U(bߟѩ7^U  )N\ RZ-;衔XS\+xc1s5e;ǎa5pL7mp?zR߸i3nc]$ڴogaC"h`j&sEY9܌{tױ\^ z 7gャm~&_uՕO@ƃQa_yUDL 4mTn2j4([? WNY^3{N?smwHMrvNy啗u 6?:7nu@EfhAP駝fC'{>{q 7:п^{w4ʿSt&vr'" A5ٱfZ׿e93kZgA1.mڴA3̖},hV%s hRnuq8غxfF]n@I'oŊ9Ce8cg+w;v́La`c9̜?o BPRӰܾ{T>]߉K{Wl(3k׮vI\tAZG!S-ݿ?}'S?}f~7._k&{'Zh }.e6Kڎ}:@&"@E;^>g_zxw f[~}`>RxIj}0W^sj}_41d]Ұayh95{ZT+ńOM&'(^OҶvM1]m6U١tWYU4?/]!_<^t``vt/,_cϽQZUoÍ60yW&O5l-b@s[~+avc>+yD(y?##v2 ?r"qtYڃo)R+An `f>3]_Kл0{scHb1['$/0=~61o[s_]]zŘs-7AvP>G!(T/\O vҝw9ʋ/({]йwA4ulu~@h-{'}Ǟ^(+тf9FÏ\~~/zߗo ?4Կyh___?b 77_/_j.0p/sCzSOUCz|7q_:B<_5]^~2ԥ_*Aɑ-)6Ef)yOea_AT R s4+e2OQьpա(/ >zzS`Le\HSu ^? zQWbh -z+L}jcG.ٿM,n#T`1a6|LN"%Lw\g23 o4h V=z%# ;󁌸k/R~wv>ZkuLw\>|YmUAOͬ_K˕W_cbvq'^6Y w5ɒmۘ9nn9l-v|B/vWzK>X>O%M}+Mzտ>a'9A[_cy_ohJn84a%?pfiup;JFl={.a'* |U)  ͷ{홵+x~xVK.eҷ|L ر#ڪN;Vz% +@c4)yCl㯖ߢeK[L>Aazz1 / /U㏻T䤓O@ %*&L weu)=ēOo6ú_XîmzcP@dy`ftHƛ-\mxWi>ױH&ءv#OMۦb#)\pz‰'B?U>4*@%kЦpǢO4_2_QhˆEC矜Ӽ. qrD뿶fBL$J?/_%F1?I?Џ _a@LRzZVV(Z5U(HQ?6)_ J?8`<EmLӲDIG /dkzJQ7O"*KeN]&\2\ҏnuw+_iU*Y3(.\&N۲ʳT X<7&p@yO02~t\AMkGar7X^fYv8RAygd$X.Rp%rƂ-׬YSf}Mۥ(rIMc1;j -R;L;nU^Ng6 TYS.A'|;S~QIMΔ)SLquFsI'oS! Fo!2|y{;ӄ`CŎPzSp,?F򗳱~XAց:+o!vI:.쒤kkA*0[߼Y3Y:?ǰ+ m۶sۛoݺWد/"Ljh@Zh/D~* vh;(x7`ǚ :ᶳJuhR7iDnÎbzN[?/_Z<6mMd oqn 4_*CR!?r7U_oUWe.#M.k"-ͲE"7"x O6]ߟ &㓶v| OwVzؠ 7y$*~ʹ/FK_,VR=zt`J_=Mw#SoM7*-[@tٻWЗQYr5ZӞk`xp c&dڴ\_eժUCnkmp/=rհOKe}?3+zMt>/cnj:O>Y}5@)(;J~ƲnvĿڈ+Pgm\\r%:캥!vi;6&7xY%#JOĎxl*pkR]꒿O7؝E|%?>Ư*Yw_ +u0O yM˄;Tׯ.*3G>kW좳*vQfO|95sڵ 7/|^4F"zɮlvuQyaǎP!^o< #_l''cĦ{ہ,<*^ZĮu/ i5gn {ʞp?#eM7=g|Gr7[oYfX:1p|`TH#'{AةimAUrW_}%kP8ж*W} x;> }5:.9\~Rsz#d7윣W_ƥSeWW_3ޏ6MGz'M(ݰ_W=qB ',VX]iRxf #fs\uבO9 ZyG+6H?{UqKWXE j4^k*6P[l5_,DE}3 (V"ٳ H4|s9o.Fk:wߣMuOСCbIÏ8B6iE ^^}啪?"ƳtԿϿ-տJٛ"rm G&s33f5 V} ;>aw\678piӶ5.޿K֛n4VajݺAݔX-OՎVO}a'~lwR:wNBk*Poݲf$pQk{ͷwiS]wٹ<, zGAV_]N943UFs]w#ȯ^>S9AWY8*rեs&h Mj3hz?ImBJwyzѿW\fwO-[Ke:}leW_??MWJ!i~?y_ڿ\,`L?}`׿3 uPi,/Qy]4|`|3f+I Y!i9&F pv`_&HC'ת:68Q̈bd|/^84cXx]N6*Tm cf+rE!PgX`^+(+xdת6V{NŶziB@Ӄz@qlUVYA٣{$=lB]vi'ro% 3c4;cO~'[l:0;ʸc8۪}HnL+ 0@&~yE.br1N_Oct>cɔ+{,.JՔ2bwCyS~o}?gGG rAʇ!@Cuֿ+[M[Ǒ0tz~l&kB/<3ikM5hd]oLuT1ihJuGsvO~jϑG,Xnv"Рt?z,\pp^8Dp Ѷvª]W$O=\4t(z/-]׭wuUsYjYxnϣHw7އ}&>[7țo!A&*8#`o;5ʃq|Z;>B2ac9F݊|7a C߄3Lwja c_]w5j$v:Awo QoGlٞ=e*?O yW]wƔ0w|$[bk&z}Ow|=X6tSko信Q^Ѧug 2+ϟt@*ꅡBCJ1eʗ朅-"]6Q^/\*_?,?v?L"y{kme'O$2;rwv_{RVœ@۾C{#C\;lNa2b/_nB?urd;nOmΊfс__snSW9V_OS1WWg77?00 \do8#S|]{_?GS/?Ap޿EϯgCW |ӗstUP OŹTXUDf^ OK Uʼn|6_)T)S]81XlU O L2)6_)T)S]81XlU O Le^cTr\lEAxѥyuGZ_٠TKdH&+iR5?tKձW_<.u e_nzb?cr8B -X6gc_/=?W_o]vYGڷoqոz?>GyޘH)ʌcݎVؙe;PA?3eUW*LD@.=lVqe>ɖX}d\i ]Q|7Z_J6hϷ чW^A:l씶ɔ/2ov|r-I}AR?AL0v6oW_}]- A&vQ5o`=4o S Ֆ={H]~5`R79a! ]w'3,wXCP/JGkH{=r-:CGn.Qй'`J}Oy;]4S0\t[daYÍo& /=UW5igs %c {zQ̾5 @B7gC: ?]Gx&=헶gEJ[S AHU~,B-K/H?j[ɾgrwU|t' :LiGzXWWvvWUq5Ug-+Ơڝtt_j_@Y]Z6oll@Z.k~}wuT-Klj~8`}^uY\ǚ?mjbS^`?O @*_Tղ+Slh_&ȏnP,#3)??M? ןfw[*JS_0hyjƠQL=NqKG s YԬkBE:)T|s0-j ̱:Aa=p}-t-V眎")٨ eCs GS =i2NDԿԿB'Ae8o4t'u>4F}أ6~6W+?W 2XŽzX _NeM75e7|k jBПrMֿģIDY~˳a'H_}ԛm,`͘6M?w>( onw$7x=?<8cr5"o! |%tvI'Ȉ#LMx5Fo(~qcup?/[n ?6ڙ]bǧ-2  Q^2+_]vaGǎ>Qk?bo>ss]gfWw;\JO`.ވτy1tEzdysL*ﶫ?%a.d}S7{A_!aVO< 0;Kn |(>WFꦧ[oFrᇃJw}a=}m/D}ۯEW>{˧a1?5t]LY=ĕVVk[oa'JW7!c mNN"Gq E?naN1awzk۶{^V8Pm$riʫho~[YxQmK/v\:wn Tݿ^=Gzc76wvY{;)͎wa7d;Ɖ>{5@NK.ǟ;`kCՂ;+VE]zyav=z3+}C\z +ϟغud&8d\.?}>*C/DZzi\4Z$>U{L0wƘ+ =:>/>MMSݗ!^EEת׳Zk'`>sɘQ']{=e .g.W_s, vwCc!P}9Jp[v-+{ߜG<*^_TrmpK/_PmhOisW>GG[3L;notԿ85Tt\8(_T\(?7:b|TGTifPlG(s23=Pf`ƣb1,R}A>& &#%AA T=(?D i]*׌ʟ HIP"{.fkF_\G[ l>T3N3p0 z3 6EX#EBgh6m[ l7poͷRRN3Yݎxyѹq2c|=!C)U87vH;$Ͽ%sɧ?^dԓOl韎woلO> h+qߗñ3FKn/:T"s;>md`Iޘʭ&AS?eB _&?XOo]33P/NohN[WSvnFC1[de:v]n*Qlig_6VO?!^${K|sϕ7 ,`|JuC+y}rQȎ|=|I> g5u\܀ǃ>!{+A΂i {aWο1|}wU91os;f-bt-2?f ,1ڶ/ZA}.Bڋֳ?'n7Δkcg;^{dmK+vK;,\[ N>TY}5RN;Dy (߄} Gz98ײ]gl ua<>JîBvƮK _ݶȎYb%_ٕ-&oyS6 ]s{on]vNMwJtvW=!cŮ3A]zt~s_*i"^5NA*Bx' @ѣCu``֝>eOZ^aϞ'~|jAGu" #pYqOɅ\G;q&2P6rrϿ; ײ-)AW:->dMmQߝ{>C@پl5jlBP]v]} ' =AfO_gc[nƷ.iJ__"hP,VY^ o梬.]ʵQLiӧˉz1ina9o;+꡷wu>:ֳ1B/AZVY@oȞ_x_{A/8tGs&Od5w)B}N8>4 ga:wiJyhp\uw+^ƌ370No~Ǘ hhACw|zDgBC<w9ҘY@uYWv }3v +NKC?۶m# CX[!IG=m(yj@._r*h;vø ;̭;>6Yll̦[o? ݪ4C /kcl̉c=y|6mpZ_cLv :W)H#A2?pGOy?RD+L8)1b,n1|DCCki? Sř/`|J#]*!A6Oh[00 ׿*ȣ?ױߊ'0g">t.AA4:VMXI)#k20t%EMQL80>j,PR:j ?k>)o*O%u8iGa7 QH߯j5۴kc;h<'pDAG(kۙd.X]^\~5U"Is=o?_q,b`jaiIkU]<#rGWX=56)Uбp!ˇ|hy:hPw~"(18 IGAh2[la @/ʫd޿;n4 k\ֿLղsr?y K&y/[k[{K_|N]DM&mIJ ˳Ç礌KwW¿ wg!0ImKBG 9X8ӝ\A}soԪF p 6*4!q:}t/2#ʞ_=Ȑߨ_eW\%۵5]/v[ҎR}tVڌ_ݧ~#_)]P 3</T̴CPF,FIhx&%vx{f?Կlu&vJ# ] ƻ_̴6uO?Ú F |gd0tPԣ{wgw1]MQ#\hLbK50Hw:vW]uпca\6J$zOq4yYjw7jrWS Ü]ʿ;oSNc L*6&b{mE2*/ pV'DfSso{:9k\˟K/ThǮT{~pv>t]/a׮TS=k&fT)'$~[?pOWM<`z(hq'>(h ~G[ Ql~ qh$^aV!/_h&i1NH Q֢ ڟjMO>MVF*"f 8Kt^DTBd t2*4x1fӖQ1HO8=(٬49Gz) ^iEqfeT9S'Ni(bO+c6+@-bΑ:qJC{ZQYi:msԉS ӊJ3i˨sNPŞVlVN[FŜ#=u┆/8f t2*4x1fӖQ1HO8=(٬49Gz) ^iEqfeT9S'Ni(bO+c6+@-bΑ:qJC{ZQYi:msԉS ӊJ3i˨sNPŞVlVN[FŜ#=u┆/8f t2*4x1fӖQ1HO8=(٬49Gz) ^iEqfeT9S'Ni(bO+c6+@-bΑ:qJC{ZQYi:msԉS ӊJ3i˨sNPS$][pվռGf,Gk:P1}J\:^3b =>~^geBǽQ(tYHNف+ǐouvZ~ 1=|%#@O>{)cw u/66gҶ=c*Ï<]~e0vv:ešƍK.;2U4@N5XU*BxV|[f{Txioϡ$mӎb;+ arA7tg[뷳]ZY eR^K.ExvbW/6l)Ǐo>#k.aǔ1eQrIǣ?p=ZncE=]n_cםmJ+}.{ڎ?Z61kX(Rw&}:yHIBYg2H}VU' JsYs_ۜ]o&yQUq04k!wC®}a ? .@` Z0DS!뮕,0JeF#Y~֩^;[}!?Ol,"Iw"+v}: lno?"6ˠA?z!0+FS=Nvzߴӹs'93{U]nfCvo/7|*?ar҉!SP蝍64>&}X9vu{Lngرcy~bM}ʥ^#RR'6mAM?ͷhպV2Mݻw7^ ,zyPkƜmǟ~'ϫw!_qۜ88???'mf /rZGi')a@`,@PKDO9lWafA?sɅӒ(3>|9W.U\yIeE>AxUkeJLOQeJLOzg5@2auI%'Ok@2auI%'Oi iS䀧5uT iS䀧Y4LX]R) r:*LX]R) rSFHZ&.9i~HZ&.9wV# $-VTb|F $-VTb|; K*1E>AxZ_G K*1E>AxHI˄%" <ѯI˄%" b#j&,~vXy%jFAR]v:v'矍F|||:wF2uW1y$c1xaBXʟױS'-MWeĈ*)ۑݰŲ.'] ;|)c#å OV%kTqG};O5{F"+y]ٌ]B|ȢdW]{cɘѣQr2ݗZH>yk30j< W^3O?U:v\@`=:e<ܳ2y⤙?s J+ʧ"/"ߜȿK,}=?Eו7EЉߒ v{zL@:%ԂW޿=- O>Ƙ=pF5Cw@W #~y7eUV]U{]yA#؍ 2#Y'ݺ-",,AGcކBPtB? I_~EI7mJWYuVK2iY_:îsñ]J]4@jзYȟz&o_\kIE&ct&</&k}os~hȿS3N߰ڵd y????E^XXן3Lי@N!W/_οI`u?YP2gA[>U4WՅzTSIҳJU=D|Qi.(w=eGY=(P54j??F U X#yEyv|GU̝qiSUأ0vmMkPg׉l?DvhCfp|s?8q8c֦Ck?ShGΆTm^ ,I_믉Cıvǔ%|'Y~Zm z@ؿ~JGP꣔kAhePJ__?J_?_i5PزZG)0/5k^{9C a:4TcʡTc5tW"(}h??ؿ1qa(Pw-䥗^Qiā?iG?~ [ۼ6O*ߟ~d"jɿKG3?oxǃN` 紦~kKL Ul)S>ϱg:!W FP&U%eDH`ytBJf]@SIY^W+ 8B^ GL!)Jęlp6wUY{ڦui\_Eo3l_TU N*5t\pE/me>AG!?*:_= *Q\>p'\s'l(VP,[dbӿТ_zss8X_4T(RIL%kTQ9\f(9MQ5*.Zr(ΜiAE6N 3Iю( *0Gp"H@(9M"f`1flPMQ9JgN/Š"%Gp"H@(9M"BZ *IPrT'ҙ$bXA+Š"%Gp"H@(9M"W>xux{Ekע׭ Վ_þR9RPh@vb?W"iP)ȏ”P š4I#8_ο9rsԘ1l+7(h$I./RAԘ e _\qDoSA]$w?p3\sw' F^]_4JHMkmYi)zp%c-mYrJ+n5(?wWqqIY$ r f˫QPP4D+LLjhS8tRz&aW>neV)C=-MֱzJ`3p-o[k([AU?Oչ:gr<ʇ H E7\A3r7@DKW d%_gg ?d{rR N-TgfAiHZDwhr+E L]uJA7yqQ:(3vTsELOX:pJ߉v|nR߉/U8s(k>U~K',a/䐧S9 NgC^zBN9T$/Op:Czփ@+!OCEJ'3!g=(BN9T$/Op:Czփ@k^W3y߿T($9{PGhl/>V@ /׃KLC[Ctg|!]>\TZTJ0qQPFZ/ڟNf/0\4pn__i7AO/AH+CiggߌEBX2Fn+gmPߧ/Bޚ s;2Do6FٿM0ʏĚ$._3Ș6O^SQFA%ݡ7? O:&lpQPrK`:#b'rZ\xmۚqA7oߴicPV q(D8'On[.#hNh \ * eן|T>ad8q~DTgƥ+\xܪcIeGF8O*W`,)(WK'UPIpd00dlk;yEYyVRU!?tsyӢr8C?rظ*[V B? *d QXtHi"|t=_z^Q/+^/,'P\R)B>HR/ο:? l._?isWTsAPv  _e'? ՗AUT?@|C /BK`.? qQY_eDd't}IӷfJuG>2= L ˵ͷEߌgGV3SP'rZ|.$OQ9*JuA5&888~v@IDAT/T~3ۛks=u87FW]%i]hUЯ E(p %C|Ą8OS8L/ο@EՑ?/827\qi:GU3ڡYB OI /RNjQi_Q907{"ߔ7NouMMM)I$VR\/[:TfYK(PyB$?L0CD}bz :-S]~>׌nyܠ*i>$a^CB~U7`bVU' `Pz]Kh&\JXXFS8M tr_T'o? IW HR*+'?Bo?lߪ k03߃0-/|/|C|ݦ_7BϹJrI<giJ20#34krmyRFe giJ20#34krmyRFe giJ20#34kr.O(UY J(P qxR]@V~JuG%Z!c#)*pЬ99|γbt_Kz5 _xhh/hLj<8 O%,4A1_>qw&O?O?1!X(K/O?2+|c/Չ1\r a':HkYa =j?8`|ɘ`ŚQp'5PVYa*0?EQZE;2$0&SFt >+L`?ESB:|5P?p1' ׫T ͉"C]'}E.]5Q; /ᦔŸF;Є|")Q= 1]A4o8GmJ/Z/<Ybl_fZ^bou()[B%+~4' K(>$θ~Gw|2# wku([%VҲ! 5b|m-Z?6% !`__#QQXa?4./w9CΏL )\8pN%ĉҒI x@ O:Ԇ`CT5wdqO Ko|I?ے\)'bCńƬ̫<+@ +˻Td5T=-&\yBS8v"ZJCGR`** 8ru9?zj t ⚬Ic॰Z P_L_ U\DN]`̵iFM >۴m+SN#)?InF|'sM MR_s^5[_hFs7\qwT?%DTnqpݯїO|o||߿I'i+vߙS0|\]6ʧZ6myK/Ak )/_h*F_?"\/_o?rp_3[َO~G1VrzZUVZ5(Qx69_VU *?8`<EnǝUe,d ~èCKKwK՘zAV'r4NqqbҏF"qj P pRXwYR yLTVν: 7ñ/+z ږyNzlxw2E?Fo";wP͞#G&#GۜsGm>}s?!=Q8n{;h?(?cY  ctr?c;.Yi8S}˯jr_%sЋGK/]S1RN>З]GyI_wÍÝGyλƣk1' pb/ׄg♼q33ԅC.{,]1)̣,A W n^(?ˢ?|7߾7l]lO&?8*R0Ctig/Uk~&uIE8?߳?-ơ򁩈<ñF E8-@+G{@yg_Zg,Oѐ %pREԿԿEʇ'c %0qKSkB2,::yD:46V#*ʴ (˜n¿P_k@( %z ZVlevݎ替,RҪM+yD)߽2g5k3fK/< ɪ.>!|\qn]=M[K@|gro;TF+/t)_x Tsm=evuG~`A+ߴ=d>557ʈNyOzawM~k%t/$~ZIױx&Y:"{Yyɚk)c7MfXT!h_N,&j{i߾-"t+9a^{lvxKqc|;#Sc| 7݄1D./OLV7yj(lB[qknLb?ϷniNw lG{T t^H?r%<(xAXr?ڿq?m?OM]_C?Q,Y 0K(|(x|ќGA\5666ѿpؐ6[Q](+z;cgkGV0!f-g%co౱ o1^E8;peL)@?I6*Fȸ/R!c)Ne /C:>h0%Sh3LJoW5^WSSB]LJ"]m uQRZdxGz,pM21^jwֿ6m16U&O2#6f,>ԓsaǧָSw5Ȍᄃl6>@S߾ Mz!׿= .AA^0`ofm $&/x(W!Je{an+s'ZIcc| X| +ͩ_}%3DGݼyeY[7A`/HGv`Nd/~>x(W :Tzi|]wmxugP F9S*ǗXrITWSnPRo3:vq>>yS)^?QQQQQ͛{1yo~T?] WhvRRbE6fiBF+f(T)S]DN?E2W=xZT)S]؆8.(3ՃLiL2mى!^;:/m 2 @_X.F3imᬌ^MUXT/CkROy z_I=>g0ಙ_`<ԝÎ܌m3ܩ=?^i/s ݎZ W_x޳u-]d~g֔v?Ǽ)q+Ӣ\oYۢ2|ɔ_bOc?v1eQAGwv޹ju&&N7|C|/WwY~md^dEɄ ߐCիV[6pcIZi۶lɦB .,}ȓOt.N:^aEYrޞI'3ԁ(^s-Ȝ>+J]l1V:Hy1Ixұ]wUfLjt]vkvR'߾&.p?3\.|:'}1}+ϗgy{Ђym_re~$ƍgU:9K ͷJL wds.r-*?Ͽm=ᙜ?x&:뮫y=ݽ:oLGQ?p`^/[c0Nr3h9?ǿ'N*#8880WQ7ӡ;3%T00BhJ(I' ڟ?g73t ]\oZa":/u U_9KqDoEo:^t(%#[(̈i1s%VW 8SuD?cqs%Fs %y.0.Wǟ> zZYl~ p k]D!{J.OUNFxp/B ˺l`/Ff;Ϸ <{W{.أ _}GK-'L@= ;m6771##J7ȟ'[n)ql&-W_yU8Tk? ^9je]iY=v)_~Yp9å]8\r<䓡,~oaJ\0x0v9B;u+/w%M &Kv_RY筎9ѿ\y,,kohFnǮMg"i>`jpieѲ;O=tYuyF2b!ތO=J9bm҄9#UW^ߣ8\O>Ol6(Ceٞ}wrzǞ ͆ gcedQCއ\xEJWOߢK'>cp7'' Z?濱/y@GGGGN5?p?h EʇQ_+W=R?%@,R}"wG%Fb$- Y@у| MLFJكtA0 T_3zP(& &#%AA T=(?D i]*׌-'l~v5q Hq285M^GyrEX#^RųH{ X@4#x O[Ǿo | >=87% Iw.9Cõ3N&}!_zGsS jSfSҥ^y% :{[nmO֖c?ў{}3-0|􏖒\P^O=_scAk{"vyzdXŤ'A4i=ɓ&JYo}9 A{J=JR8XUgs-~iDx3da3l̳ŗe;t'Q*筮ʆbTC71n®ZO>%"ΔUV]5QG!oF_B3{3ϰw 7Ï8cʔ)ҡ}{g2 D /Xwn4;hPο]g2KiڴL0'CW?A9k+Lh\ MV5 ΁+go? *A?W hhЁ`Վ\p? +/MA_?i+ym*7 +JWcnDWgNm( ?O9EZ9YԿ88vhXi}ot'[l1a#UPPVwH(# +вWz-oyK-=0k a7([v|тVlɦҩSgye̛o5vҪMϣ17`[nI>;.*:#]',ew=u]J=YdF~[o3ٞ' 0 vrj%leFSc!g7^9G^xyk[OkxIy9 BUA/oe4rL=_{!C}.w]va'@MrAG|h$Re $E.D9b]\# .6KwԞe]N'/?W'chv衇/Zo z*C/Dt,ā,P-giNrvOۤzQj'XNƙUVYɂmw49*|¡;>i0^ dx&zO%]$;oVi.< ]}Ս\#7\+ .gҤddud:wI/1~v,-dyVPwN?3?1o"?(OdD<( \q;s'Bp1p s οiYy*|;}l9_?i_\z+?KuʅCL9ēLSR `")hJl9gA*1TƜQz$U,e5'NJ _&(&\? jR@ 5aRTy.S*I_Ql:\cC_ >< 0p jX3g cWɎ;.],rA и>0: ҵTnW[[c-`'+5_n-{3׿UFۈHT ` ~2-jx-MGЁX`Tek'pf]lO|LT4yDzmd1/v?4"l>^mlwَN3.;~]z?@e_"wtU G2gws/g5ޜ?Kh;6D=]r*vT g.wy(<_}5䤓e^{QOQ;;>۩_rk_3Yg4$3P$rx&ztS#.}J?{Uq=R{,&15c5hTD ػ{(jXb4nb|vK,(E@:sE!gvvvvٻrUX?>'Bi4aקc'Ї/*^}~A]AU <,L| SLL ~ fT_:AU ҡ2j')ER 3#Li'Z_?VKFW :?vg V(>?# KYuCK'0(RMW4H<~E3N?uD 3/? kg.ʨsyɞ&"dQ1HO9dO+ͨeT9SgNi 8 9f3j:osԙSNBٌ[FŜ#=u=c6fQ1HO9dO+ͨeT9SgNi 8 9f3j:osԙSNBٌ[FŜ#=u=c6fQ1HO9dO+ͨeT9SgNi 8 9f3j:osԙSNBٌ[FŜ#=u=c6fQ1HO9dO+ͨeT9SgNi 8 9f3j:osԙSNBٌ[FŜ#=u=c6fQ1HO9dO+ͨeT9SgNi 8 9f3j:osԙSNBٌ[FŜ#=u=c6fQ1HO9dO+ͨeT9SgNi 8 9f3j:osԙSz_'>A|վn[zE0WZ) h~rS V63zLmUw>&џ'xVg*+"}zk>c_ɸb-.+*m6\^ĩQso6i׮=6_L =/=UM`}SԿ{uQٶ, Ni~ӿ_VZ*L1>=WsѣFɍ7^/O?4N;6"}rw#޷6[n?p`㍭wyeQf0V]vyrOp;[n 돓vi'kƧQWc;.\b b#>nMKy;dGoO=8-ɧ:&ơr]w~ [n%pr%{ofYÂ2v)OwtᄇLAxZ4Wƌ*'OkZ-1c-) rӢ(4fT1E>AxZj,k)ULO@1c-) rӚV D`iXKb|h ,k)ULOִZ KcZJS䀧Es5P`iXKb|X3R" <-KcƜj=C(0=_%ձiICJ2 CS XZ>ބzkV-2gknx&5y1llXڴm#ӱ-[l%:uF(_ `qJ΋_|[o5۱L4-vm})a|SW6n"oGZ6N#;!t"JiӦ-r%& O= ZljT*l?<=s 6 K3{t P7\ߪyE]q6HʼnO[mpvo(ϳljO;dP= 9۷K/0-`CrWmzءzG}d.?1G-w䩧"_=:Hlm/PEZF2?*#?i'^2kN=]Y{20A䷙oƉO$xMCEpc8媷,(6OkOs4d}ʩ'vx}r%~{b`3Hlokkrs4E\>obZ _Կ_\rM//iߺ@g ۘ/,9IME]ǃ]:Ky_'p)L\q_16t0\BACOALREjA9\.o$PrNԣhOCOi(psQ4Tj@elT/O ?2(@+j@ hsM*  RkH:/nhWU7yp3֕7ޕk~nה={_eyWUV*m560u2s~I\tﶲF"흩Ӧ┤2lh<2rGVG~s9,дOfHvmuaqSO9 Zx&}Q '|ED:/f^x}r}rM70Qج =20o W},f?_ypQTLeiG5E/ο9y@0?`4WQsA ƃ'O?/?g:/+s]wpJIןI?4fvXQg4/zu0oJ {suU{^dd*g"gYa@9t֭$v=IKa~Eo,!r~aVl0u5%uNљ[mK8iۮԿoMlq2A8IO v O>Y 8iӦY[,Ŧ5'ӧH]w&(YjeM7-F\r>d/W?tYWOk~dIrv6f銍\_O '>MCYmjg%?|09?I6' -?\{hFh.,Җ';=R)醨Gg̐2hݻxɠʳ9g:gQ(dk׮UuL)Y_\&slV^}E?8S_궏f>>أrB uӟ> p]v96-$2MOvT2NCJ?Cd٤I}YWN8DЛ>+gۚ sךzxdGs3_d::=O9rstvGc/__?:3· KsaO:sp  8''(/;Ga;믦N Q MƩя/cOS gH2P"LurzX!!@2 (39ibu(%r$\'ޮ )2ssz&VgH2P"LurzX!!@2 (39ibu(%r$\'ޮ )2ssz&VgH2P"LurzX!!@2 (39ibu(%r$\'ޮ )2ssz&VgH2P"LurzX!!@2 (39ibu(%r$\'ޮ )2ssz&VgH2P"LurzX!!@2 (39ibu(%r$\'ޮ )2ssz&VgH2P"LurzX!!@2 (39ibu(%r$\'ޮʪ'>5-/^.Q+3lMq:&j~BFqR6do_!1k`KCW#m^/VZfʟ0Yt\ViG&O,v߭xȖK_Neu[WYl8¶Wf$XLt|Bʪ!8gQ{;F^}5k'&Qdop7':d{ͶiO ?~oN?= ywg *'ێO8D{6zA~(hnƦvm~ܧ@&A*q@&2%lZ4F  M7qnLCM6ύ7 qHϓ7BJTGYT͞UY˟Ν/\jjּPf>  -msM OI[-ؠˍ7`{ml;%;@VI3d26o0=1=.Té:, wOo ~wkȖ?By.בUi[61_#Q.a [bҠ V$ ؍l οr?&|*-fZr,FE+ !̶'oa;l9TeuիiC,FE+ aCEf[~sO|ߴ9{,*݊ AR[cP8{7a8pSSȕt-2p?_F  VQJ8__ݣgo h_[dž By= }H-:0|*o|pk (07z'oOY;`V[5xg<`:>ONYaUSbI~47YuC 7 jF&UTM7''htp(4x>o κ멕?^^yUk6tIzOީ^={dӭ_>6L:^{'lM2P7>`+֎L=[~h_|E#kk?p`ȏ?O؏ýoI7ᴧ`wq٣@"?\8 u E&2Clb7i#aOHﺫLG̮/6ƙT*USU\֛oYunBa^\z7z;v,pg~SNk9쐃w)qF|4Nzѿ?*aSf 㴨Z]'Oix| voũj{$*C?rCOGesj1 9Tzb@r sœ9Efis\YT7o?/O~-K L9-X-􃒤^]JgJL\OE`<~ @IDAT)ǟل0dbLj(eDVI`ylBnF3/ Ho@j+?2UpDAL?;+]Y>oAaKv+ i}l??5זa'SO$lұcG /[~sx(6|{2q$;!ʫJ+ ?p=2mڴ ~ϯ_7ߊSeڷ3dȵCo_j|'r鿨es UH v݂Ml/EW_u/_|W=tzvqb 6Δs9OX`A=^OˑG f{O~:m6>M7 ۿ]ydgsΕk)Uv=w' 0t(l6+g)}e9YusY3|w}9Qnyo}壏>2ˊ]W3ΰz=xCm\rqO.>Sdml|zOu }r~'u'}{OV4>YϿ`Եk853u_Wa^A[cgW8#ЬUS1 >?AeM6yWӯC_N=P`&NpIG!AVL0*Oљd ?DC˴RéxC!\r'ןOX/@l Q1Ώ%JLu 3PgSr[NEMy۠"sT'ysc nlbQ93IlPI *IP9*Cu<((B[ *IQrT'y3bPMr81$ PgΓlRÉ!:s_}z^~goDNw #Q!j쁚xh l?m{o) wXB֍>ͺ.&<@ݎk5B{";<-|8q}[}7?AdܧgRA:Fz{(}>eDLM k'8Ty;T6xSv^rWꣃhJ_as'T'OaJ۷ ^?_w~?>?_8RH}!$[Ż9W@r& rvkn?w;49倂$vQU A:IF:6BۯwrAEsԘjBqDyCI*'`/5I+$DIesALAL(GG[P#A١OvU\]#GP)lN4->O ǟYd, 4OCr.񗍐& 0i\9/! L@>`xbuϟDJ72-뜡R4].#@σTK( ^cw~o2`K,9=b3 [JNf2h2 5 WԹN:'%1̸N8) pU#Gݺwj*Zqx7xW)[`Ggq{8tg^f993E3s?c|*Gq=:V't㐃w}Z{ DlO6bkkŴp=`K 2\xgKN .sc#iWzkqC/V5sUN+Tο?}35K/_LQ5a|@_j?CϠ} b6>`I@g0u*1fVE9ؾnPI8P??4(,[E"\',L=Jʁ _ο_N|mRk?)>JzZ%pe$~]t^dlZ'+3Ze~2\*XeȂ:gT26ZPWK;K{2.#/k_XK/j]Z&M,o6-.ӦNv7i#kZK[~9YS'l!Pn$Ny"c{ҳWO;9w#Ç7g1*Ԡ̬&f5eM_a^@3{~Շ 7Hf4|J&Nheiw5'={/POǿMO}g+ "?^se(ʟ?qdo-)?!dޕsQ`Ⰱb[s0y'Ous0?yZr{__3T+&4@HWўi~OE8W4 I2,D=p+Z-rD=p+Z-rD=p+Z-rD=p+Z-rD=p+Z-rD=p+Z-rD=p+Z-rD=p+Z-rD=p+Z-rD=p+Z-rD=p+Z-rD=p+Z-rD=p+Z-rD=p+Z-rD=p+Z-rD=p+Z-rD=p+Z-rD=p+Z-rD=p+Z-rD=p+Z-rD=zo6Ri/)ӯZRo xtIaOSldqhH/ο:kE3zdcΤ#.J\4eOoaO,0o?ZnU㯌2+㯌?3;ۇ?dר;\FyBqє=i?Ƨ3ZMŕffG>V1Viֹ)PaMD,3a<9%[D Wkh ">u$fF aHW+TWQ??_?IOnj?`40o!c-_Ыt#._IgC0w777_};k* b1` tgtX-tY>/5,9훌s$Eh>@(2y$UA*ԇο?_=zA7t²,;/;ZN*9"l^(_ h> ۧ??_L4F(]8<ˠ^u\_?p wFP0 O1!8N` 7/?1c7ǐi) ?dF3cP l 7ȃ7cmn5f0fXdC^zyKx8{QO p a`]// 99iT~800@+!O]BE(9= p a`]/_I"*l/PO)Bcfkyg-.0[[=uJP uĕ%1DDݼ#cZNZz?G|@%H _7Ș ?K8KuO鎌i9x\qDJ3ŴwdLIֈ K/&=q^o9p7߁=`>O@KDŽ ?_?xv%:y LKU-uRu_:o00#M7ȏ6 NJW!23N_I}K\ /AOj 0o2ܸ<@L3Ro?T=|nձyM \&HUD2z0?)7K75PIp`d212dlK;9V@N(5 ѵ}噧rF!gʟUq)ael?_hGcߖj,tl"Œ?[8! Ws,ۧ?5/esA0"  K9pA'oԉk?oM _Bd*HC ƿa cVw 0/?2JH57\so0!d_aXU᜼83`Kg]^Et/<\q7_foK?ƧV&/zS$DLAKu; [l&${iVK20c=4ruyRFe g{iVK20c=4ruyRFe g{iVK20c=4ruyRFe g#&0{6>13 "pi(ZCFť0GXm RȆ',t]  pl@ˉqE&lO)/ο?ܳf fC7\kivO?yo3r*8[0 /*`ÂaIb]?㏌?2y7c-GǦ367I-4/9G;< ai{զ9G;'ۧ]J \N49Gt??ڟ0ڟz[4a眷={AsV]}GJ525%?!ԢP \3[Cf*( 9 Oj*9pX=)'o?_\riBg71㏌?E`W_ZWueZ+0M GvIٸ|dGӬ+sIk\L`["P (fYRi*2)$.rrPrV4OS|,b%T,4???>qdXF ǟI$ pRJ폞dNv T-e oE 2ʠ T-=b )Rtlb\Ud?O3c6# BCJqqKOusןo_bG[1봠_413~"%; =fHmgƟf93;W褈W__qS:|3W7Yaû|9uU2v>5lu;; JP$WFg=M|ԿyrS8JV%ԌJ24YOOO"T| SJ,Sp/1$l\pg/o ?mdkOTd'6fzh_Oo 2+㯶F`$8̦"(oI zGGF$p[Z?_tQ  ͶT>.0Z+5f`\|Mޭ ?}ʟGCk"ο?GJs'ߌ?0R<a7I 5rc5&*_ 3aoj12h&?ԹR]Vb&#ZtplF7\p'ן\=O{ni+,F_ѬYK5 vKNO>wETfbAqECC%JŃ`T^3zQ #%EA]0|T*A?SӑD i.>*׌^Կ )HIQx4@ kFDVƧq-oΎ "HY_euЬ|URR<r0y@FWe+(qprKo{&g0kO:M:l~ dz\s՜!?8p:4rb7b"_%S10\qE/_|s9ōot?tkR&`9ƧJ[89,4Ūjщ(ٰlX[5ۧ#r438ءذ_Ouv-ds [zZ=ߙ#S2V^0)_ :{1ݤ UP@fٟ;wC=~]w)/"L쿞8bK1eY&b|V&+`m&*f~ l?IlneA*cI~ӏ Hڵk'` GY?9k_`%L4aX#ߠ.,a7D &}J6kgL|m{uerqocF.8R@(N@OeFʘ,p(js'DjCr`Vpay( ?zб3-oBem &H\ACߟu c6 1"Ag>6|qYߟ *fl44]KR^ l? M)_(S]!QL8$QhKk@h1RK?+$?_ۣW3VVO<d5(Tǿ~j ǟ1kJW >Ǐ'O=7Jڷ,~7Vxuy{MeE~`tX9WƏ]?Z kWrԱǦvhL.| :T&Nhמ/!4ֈߕ)Ӧ#?lomH@VZj)iۦ-OA2yȀeevɔ)SeĈګW^}՚Yտ.VXַ]GC[zbpim|:#Пw_"o T>|doJWDgiwX,6U 1[[ZK۟g{*d/?m6szo/7O?~9[D6b??a&+:9ᵕϜ"ou"ZՖjHѬ]ыx&Z F' P|1?S{!DFT9ӼdO[ e2y˨sΜ@prf t2*34i59Gz) '{Z!lF@-bΑ:sJɞV1Q3y˨sΜ@prf t2*34i59Gz) '{Z!lF@-bΑ:sJɞV1Q3y˨sΜ@prf t2*34i59Gz) '{Z!lF@-bΑ:sJɞV1Q3y˨sΜ@prf t2*34i59Gz) '{Z!lF@-bΑ:sJɞV1Q3y˨sΜ@prf t2*34i59Gz) '{Z!lF@-bΑ:sJɞV1Q3y˨sΜ@prf t2*34i59Gz)  Y\j=840y"rŏVc)̼"( ĢV>޴\+T6]LM-+s寒<3yLAԭo)f,TL/<[:߂|Lot`s</|4M?+\0bwzr-L'+)yW7p9HeEX6}h3p:N~:cx r߽\riOl|zq+R?H` gcƎG͘V3f#>:4[q'K/S=K.=UտnMnfj`oviۮmSvĦO}W>C$C`*7ͺN;o?#@smq9*,SN]GoϯjH?oS2?8fkDk<EV%OOO?Z(pwc)i֟ʼnO7>^ ԲR" <6aKcZJS䀧Z 4fT1E>AxZlƌ*'OSk@`iXKb|ل ,k)ULOjҘR9im X3R" AxZKcZJS䀧&L`iXKb|4V ƌ*'OkMҘR9ij,k)ULO601c-) rZ-X3R" AxZlƌ*'OSk@`iXKb|ل ,k)ULOjҘR9im X3dS_p% ꢧzr YOCSUSڥ Yf9Yv9=a A[[q@&... wZؤ4W套_.˭J t=Z[qᎲ=|2fK3>*n׮}=G[nʼnOѽp TsghP֤yW^e;dlCPGM0Nv2_u"6Aw[Nv1l=㷧ɿߦt!'D`S~WY6H_+7?ٟ6'݌(1w .T*N( !z馓p[zz }_wGu8rK7BڴicuSN>`$߳C߲޷חoZkƻ46ʽ+\ {$Q{l{M:{VqWKo<˼66>DZ&J?'~VaGY?'ǣӜ>ھn|ʪ2}T O7>nU> \)j?%_pͻ>=;ǿK$tGlwRlk,?8A:i oojReI&{_My+6>!t>Q:TƀKbR^ldB'U0fsՀ^?t/ `RselD5 dՔt' ڟ`s)zWj3LJ-#o41JZ΀18h@#@6xjKl7fh V)S iβf[ƍ!T+"^o$>.}'kjZsϰe^?+\xԊMO4iDzlJlp1b^ڶin ,`2;Sl?y6|'>@Lؐn;dcJrW`nJsΓ'zxM8!J7fp#bY0[:{q|9YJ&a_p2մy~elcUlȮt]d%뮻N&M'$ݻ,g{աc;8A8G?2{'MwyVrǝW[ md^j 6槻l0l:u$7n ۶O嘣 h#N_1N_R>؄4/G_msGn|)h>YMOAM63W/fʇg8iihh9'0/???9Q K[ ACCf"ڊld ~CaЍys6>_qmJ[d3\7(>]3wu-ӅjOپ+$i/jB[dHpy Iv7 _B&*Q5abT? aZߛ[5M2c!',8U4iE2v€r^qV[/^G&thy_[ߑA[lW© &t-3"Qqd)o]f.rYz٥Q𱹩snSzo.k3&mZ_4~[c'Z_fO8A]w=]xy86_uYl13LNYhE![9_ixt ⱞ|7^3~U̿.#{V6pSu=ƧOW\y%!С2h@A]ZxUW-RVYmUܩ36:|(ܦS:GNJ{JndEņ))6@~O2fؒVoh ՕB黭| -{3>#>kK6| Yyn~_?yWb=z0~}\ esK9?پKq u?`S ?Tf}?\H?_DTW/<bJ/Z{ 7o\`̾?Y֦|N3_ZZe}8"}N"JZ"L*ܵYdVü.*+i2 pfq  D0L2 hP@;'ہd!@$D(S&e:9v=MΐeDNTYħ&2[[_|[Lx_Z(WX362lMq:&|Tg2rEkm|8dCz9P\`Aǻ g@*)38GndnۏW'K.1l6>ᄞeo5? B-3fepIow_Q.ҍOxѿm*m6k'kDP8YSNED/A1Z!^Oc|͞i9>/6\-Ra.mKG~X.Ru䤓OEտ!؀?޾۟޲u߾ւn0Yxalme:6h?oח{9P[Z)'| |y)OCNRX|_ Oϙ@ϩMSpvR ac#bf@wu\T{cW u;nxq~(Ο+{Ĝk&wOuɾ{1q'\t }C '<qj،i"N9D9 _;l8:7>ywdf_|%:W{op[[p"^G}%+HsΕUh.Eφ Q2 f@?W?qS0eNuOm۴7Ƨ@ 틜w`ڵٟ_{Mnfyo9+fPf:vUv5\>]wMs=WMlozmU*䟷鰶uk^sϻ@wSN,kysζh~am՗K. JiZ̛:zZ޾fW%h)]M_Ns\afk{ms)3 NYtR1f~a'4]pE%>>OdzȂ;؈|wPlSNr5`>nX^uYhCj Zmx`Ы]<9f?l-d<~ԳX4 =%沋/6ZE:U\6a{P1q0H%ۢk{.%e .@Vݞ#i&o0;L'\ 6,Ա= 7\/${/;츓l\tv䑲zrN%*)'85ˮٜo: o/b<;˞WZoYgm3>xW]A^b' m8䠧\x_~e/5 ɠ=8=pxÍük릕%\ʡ4.o=3L&孷&V@ ɤIS]KǾ6>xq1d NZ<<(eOeo>cpӛUW]:2aDNZ=);n};|8Eh Ah> b+zRӑGc8b[Fp:K/,'xk?j^'5d*d;z48AN_zN@ټB+vX j>^7>郤r>T6oƢvX4mt۴uC`M_ͩ'fhM5O,m 4Sk[Y }=nP=}= >D\ǎk?oi !ocWve儓N}-=g&p=>(@ή]3uVSym]fYʦ{Bg'xcAK/tfZzS_0n>Ml?r ?5r$Nl 㴡nݻ;#7HG?eX'-(`\ojˮ3Iذg)~9/ݻug3#ظSε q"m|ղ"6 } iu+,ء܀֤}w[m^xkNL-x Z7O. nB~n8i$w|̲H+BC~u!jU}V!{@<"OF~L뇉*?&$qw~bL?^C& 7D@YPo}&^}E^{Fj:WLg}<#ŘT9aWe '>Ƨcq`tѐ{?˕W\Vm4-iyF>,Ya!*5zw_"a=64]uu8Qwi'0OZk-k\dŗ\\. Yy@Otc=N55Xn~kumO!s?o=imn'9ӬMm^llMohs˯v\0utl@'qǜҿ{mN5 kz~mTM2:;]G콂b^hW,R *.`^XXb]T b~7{{}QԄ9vvwvvnvvv7ʊ/QzJÏjϖg}ZVj ŽqXn?˼"GL*?*?^"a{ :8DE+8Î;jti<2t4Eǧ#}d[9.#*7ႋ.83dhTD);^7Z{.weDZ2C/-x}ܭW3yeNND$7|CfD+_B{|AO?@ ف ]~ty}(^t8U'ܣXV9W_muDSڭL;F l&D|7[nO O8w8lrmMtnpd}zhB+](B&n*Vi'w߃9Fm$G@)/:U;u* :$̓e⧟~."jnZžN+1">}9rD$\hu^3jؗїM7L>zCyihd]~& Qqy-In:YO-te.DriDZ5pLr пK{A>J["kq9g O竑pТ <#Ȩ>Ⱥ'b^}D=Ss<L@˿3@|ԷC9|Eק/S>A?~篁Eg|q돯&Ї A+=⿿y_nQw-u5?Ds~_ggY__ӿ${] 2ݟ- $6)ckJ( c9By6"E)"jƉ:c+g#bZ!a .۪pW(FFE)"jƉKBy6 JZ!aVҢPpD@m'".(gE)"jƉȿ[k~Mu^yAKFYH=B$ݜƛ ?x뇾9+klv~#ʥd%mǷscA V!({gd9)?0./p't]tI cs!>>U:lQf$L4lD$rʩs_J?&⋉ҫ{Pσl+|2Az>8\5r䐾}Tփē\pu<t|:+8>ѡW2IўML@'f+!+Oo1pZh84co1O |}=HÏ>=T6tzA2;yg䜁19Seu8>?NjY`/gK.E|BCqFVς .玓3d3O?-c4KC:u,F O_#jU /6տ ZG"MG52/~1Ir(2ri;;:|2 Nt{%[ Ǔc 1={ǥSO9`k)/n?P+I'AV2z,lK 1/aQhW8?}XK# Ӂ9vm۶QU}(-)#tV`Edqupܱi'B8?!;o']D?NGp|Ϩ_:"wDԚǿ;Jg뮻wSo$?Q}[AxHZ Ө=>#w!9A?D5A?ǟ' Y(-]:н026.m=t}{TBWMυǧp௺z:>MBħh-n0rsU1LoVi (fW=ѧ/ο7PukAdG7;о}CWo&pj 6t@BMuo'`8s_vi/rYxEѾN:/Z!/?9^?f㟑lU?+fEQ\| J/BT⧬)~W\B- ƹۿAц?T G| ?0;@0;q-9n #߲B, MPf5NĔPT^/My]Ks_!"Taq nMcs0ut:K_:>H.7j?Fh}ڱq-4X-Cu( }YlAP.wߴi3|r[jDn'e'Qf5'>G˂ .$o#8<]g޿F|iS5ZH}g(ܞ1F"\CoYt~dR7_#"g{UYzU1zg}" П>qΝDij8ԗO< 2Db]Bez /` cQ=@ǀ_(xwnYUkUwFҿ`xJ{D|:C︷!BQZCq MFz|썺by1v+~\:FCoTR \z eYt:"[ G5d8__π3::9Bux>hZK Gq=)99}N9tH7]wUe㯶o&_:@q2j5_z +dUWj\H k$kO&O??#>c(1> O_ ee0AE!Y`/8Zp8vEFs3W}/];VAvF]v!AFx8vij˞>/Z{H?DPk'I~nq*dM*Bʒg!KgCQ+,Z-Ɏ;튈Ocoҟ?ϼRNJiY+qS'\"]w(H޽d+8.Y,rנ/D:׌3WSy7ujr2 y⋈(}PM9~u*A>x1W.x'/#>h1 /wOtm|@nVuVM2(uBu]~X_~eZ,Ҳ"`~7-Bk?L^)IO'‰ǧ>:ToZ~΃E1xR:{x˄SIucGW^W\[-NQ!6>'7:Q5ANt^kF?a+b=ZΞ&tK##&U=~4Rt\`t'p<"&cF7K5lͮuGoy/_rqʀ?Q0mx{h.G!ԜR;Aϙ|DY.?|[h.+C XUOwWDu4󫀘- "Tpө2d.>\@KLI1|'|Qd|?OM?|403ormJW [?a?Hӯp*(^LJox;Zo'ke[/Y+Nj6U_m='17Iӹɏ(;rӉ<9U?_f2 0k;ο>֑f#;(t/kO|h x-xe|Pv+pjZ~H.@O-tqnUnnTAvتat5x9ԓOiԳ{w@1{Ens&?+t"P54;uM8YTN w~J3}lK(8lF>~ѵ*-|milgESีf~^. DH^ԉ]}^qU cp\U%t)K{W#R)L'G+m/pQnIDO9ʖXrI tF8ĉHFSj}ݑNeS1FB]z#CN o\2bL葨՛O[+΅e&wGh<B O'jd":ҋt%ꃉ>5MR'oƾH Zo/4n*ƽ%atcNa>'RK/%\x1_*|Fc^;]T9w!uG#U y唓NT^U+^7+cƎ)-Jz9T$0!ʖ[v\#o>h0ף_x9y)p<̳d -pjh:y7c|DIVϿ͑')l믥WϞr3 Og&HUW^):wI]{<@Dgut_Wшւh<^{TgjGg6m*}}Ϊ_ $&MuYGq4(YG;z:t>C5SpH$| ' v'~&>X5 Oc+Hd蹸tx%R $5v21zO5 8z$t Wt6Z΋_.e޽?Lqp|u gp_| i GgkZߴk#'tjҗ`R~H795*aw׭;BħᘍL??pZlE &/aЇ&|?3dVա s;Lܘ]7n#݂2T?>5Zg%GvNH( _ p)Z8%1Qpj֢Oy_FE I{ ͆oP8`~PH/D|_Dԁʼr " Ñ?;9ԓfN|Rҧ8 :-{ͨJ5r%#~Dc/Şr?Se5B:9GL[7|jz;N:I <rV<8-ӲLK.D]| ]xAɯ~~m=eeҝ%J9:kfOd_%OUj5 ??@Xɫ_|71\y|"|۟?ے:l{agѮPmPuɒj~[vX'+= 4"tPD_Ip$:&<8sC ~-LDO0mWY 4_<2YCOv:Q+?ǜ aͶT^1i<(v&!G_eդMv`zͯ{)゚"}i #ճf|GOgqA$:ruJD,j2SO>I^~e}5t{MX*7|# /Y] 6 τ_@|ĊN8|tv;~1Yg]sdEDO2t*y饗 cdq9(nv\ἄh"p4J ",\Շ*=H68]w{n08[WZlǭe7y祓$ իoo O=ēDuH˨GYhOCHO8|Zx'WX^.*Yhԙf/D2SDD *9eEY:LF5em5הmGքM*[j\I媑믾,'a6~~xR}YGǧnxr8w 7_`6nƟxpkXDt{yeԵסynC(K*HSWk^ZPC|<Lt˭/|yJS8]8ꨂWbKCOc<%\>*7^;ܯ__r1(-Xr iW:'Ɵe{:.9ZsשSWuDn);+(ʾXdo˯'I8>)QKE[ 7PJ+j1>ŘҟYs믿:C_z\sՑ~5AJtנks+ea BgqO]y^dQgAc_q -vS1 Q+M0rj,ҹi~oSh74H8f:{Nrny? ?|գkBڿn۟ngNNւʛn?|/Dݯ}D|*亙O҂0\(c@vHӦ)\8}qʒȻ78 ?"J@JZD}_? ʼnoڮ&hbݺ`Fq.\r=a&qYk߾o7H QCl,d< ƛm!G23o?zmO3~>|=w ] h M5G{c|BOfNuXR?6?!;Bi/B#7q'H-屇!m}ⳉx:YO# ލ11\vjKPm#>aȫ[YN?NK5(_ ??8O'3ۯ 'Qpʺ48W^ye94AQgp80oԭ{w矤_>F\ve8^Y$ WXQ:$A#4E'O-]zȢtgߘ7ňO/g5Z[y? rC~hXu lBjhѯ7~U>W_8*JIv {>PtNN&<e4Kƌ#ҸFFΝ5XC>lpoW=00os11Wr0#>%F\ѱ.jSwjddg B^9jvrtF +_P($wniK$1(ow~6?H8ЊFiwǎ "P^͟Q:bWV?3oo*>^L<]\|KSs?G?زQ;U!` d4gE[_p?L,|_׿_׿ˏ|73翾oE~>Mmmm.I "ն%N 5R@Oz}UtGCw^ 4`PG8(rs91RP>0@睗__.'YjPG8(r |p KCyjGCw^..dq(OCMZvR`kNvO_Z܆=~ǽKPLFGHgM$AibgjMlîx?};|7R~?{!gyß|7Af3|ɈO,/L4%7bĥ˸ߒ hPρ=zȟAt''dw?|> ЏS,"ŽVZ0DcMp.Io +Osѥn#pt/0ǟߦs5i?O*"gy*F^#d[~a5nq+"wL駪)̮gT>ES?(谡Öv?>*4~ްRGϥWtfḟ(:s2>nrgJyP:Z[Fǹ ~Æֿ/ӿǯ}oac_HsۭȦl"?J8v^_GA9\x vTtxU[14|oU_Qp4#)a lz&?G84jpR(g<I =U<)FX&>q/2jR%Mq?׌RGrp>|^p[\N#6TŢ_Ce%h JzNy )F?Ԉ\i7i=S`g^?Z c!na֜oV-r cП$84zT :_ɨh.ў4ofw8RCO1›<(?J49?S ~jj?uKoK7V/ ;_HVv~?~~ g'X$U X}xYIռfi1IX@Z@cID 0KIBWf`GLHLVJaifi1q3g]q!N$IKRVӼfi1qc16q_ڶG'^䝾N& UzhÊ01N*\N+FV]c e'/_D~EjvTcy;I-d: mZyݜcѡYch \*os߽CV?2"RؓIJݜ_z,2q2裂ۻc߆g(1 ˩g$^O#8lƲ۞{JK:*#[:ēO1sGO&Lg. yGzgNbnVDAZj9dyAi\vǞn]d鷈xt2N&|]wEtУB'F/ᅼ #@䚅}Iko޼wGĒoђnfBOTZk%'x|<{7e#u=Öu#d:u88"HǎȦo"?SEM6| {/&?ڴm++ Z C?Y [î|X%]wM:ubĠN?%OĖ-[i_> 4uj 'p G.].p|upi㏗C'".J?<ȠsJM5#XZ85K}LWXfSΑgz 6rՐۢ%܈HMpofDRKA @ﶛOH&/Di'ܷh>%)kFK?O+ ٔH@R=8n^;!UVYU䓏s|r\xZ3 n@ʔd(xuDd~K:fkQq l!١Ckd:x^\Mgn@x⧟ʑ^Z{mpqxMKǧxa|w_{ x52- zaU#ȷ^ |K8J '"Пg ضi#]vNw#!#qDSO=-C=WW_cu9L#?L>J[.:HNnGv|R[Dn< ˸731>'mɤF3z7^Ά7 nl'Οu 3?: SHƟ]K_t&)q2 ?5hןTόϿ [֫?\l9\u5*!20"Au폸_?0\_n/\*P{;,aͰ5$1;p /?T Hܻ1?0oSu| +9g7suu9dujMEuR'aXZ-$MWt8}df(r5IW6qn%3^t&|azU01)pOYmGh%^5ҿ )#6^MǞ?j}C'H\XNf[8+C}[3RK.-n{)r<^Ʒ1'1!Ş;HOj\w|@jsu]cr-3N!M:љ95F|Nvy5Aqoj9>|8NOc_XSO>? Ae]NcSNfd_A;$L2G ǧ脛G67? QG>HtS g]ߥ~.p A!Ms;'p\a#*:[~r$>77kL_p>"-mP'z2}Eo&˧|"l޿8> Bxm2.\^t1ϗ:pӏpP3A&?|@.zmmP BhY=|Wr` G/D҈3?d2,hQڽLvI`vJԘϪTE^ǙiOt&R9EԢu[Oǿnh[t9dV4o言>r1j={ʟ`+9C:sn6EE>p6,9픓_z G&mOQ )L]qOom.˵nS~MtLdn6Ϟegp$s>0G}(AN$zV1 t:T͈Op|2<{Zs-y䫯D}b "Ҋ@Etove9Z!zM6Q|Vڷ|24“=v߭@< &dkX7aΐ~ƍ<{u>~\rɥo<z>`clfʟ3 2Lta X 5\s)Ab$ >7OA$QIG>;=[;ulxtFG? : #g_|^NRg/JeW]- .BgG0( +-2d 3N:~>C$^p7co_Y8}p߅ٷ?LD ?a.>TF+`C0o#ۙmO?.f_A3dkԼ"{ _04g_׿V9U'Q~ld=Բr^`z$=Ead)ԄL^9TVTDw3S˓3$"|/W TV"|D,9$?~'F|ʥ:|hTE<<!X=6CV|#~ғ3(pmV}j/-z;w}'܏(3ŗ\B[oc|  !#12MC}?06?u~?\v,HpؓX0(D!`uw1[oW_pEn1}7}?T9Oy% Pĩf 6Dwvme@D|5j5r+\jcGDd Z?Nd~^ C z=h.F':se[OŇsGWwmF^ya9DBjgd x>(=%XJNBBL|}UX^f$7oF2cW_}YIdʔo WネA/:B1tyC)DS0ekIg|MQwndYv pܣ'" coY:Ͽ'Htd<>{^qu*̑\ ;导~uFa}qN;gx_rr*"H?𮰗pvƟu@a.2zNG6LjZQǚ=&McduזsD]}WݐU1MAqfE8}L6|QqOj[L,ׯlӎO]- T9}+?_?|ŹNOܐ`9wC(&>ɤżq돯PnĀBDٿV]S1jtS1@~x|HºȿΏ" ~68EMؔn@{ E<4c~`گA,&M_:]|)cVZH&L Ǐ4C/#"j ǟ|ߖ'R}TYCJ/ҲG$/>"ӃxM5[o]Yыz)D׿_iodڭ,m۴3n[Bֿ[@ڭ,x˸7ߔSQг+{ *]jK[ ~`!c!DNYs͵ա%0B,KJbK? C!:/͌EGUW]Mm ssywMvIv^@[uz ?FkJ{+xpWF_*oeAD>Hp[fL} `ħ'3k7cͪW3/-" FlgRKz@g|:tụjWWj#/!=fXa4zb,v;ߕw? \O]tQYm5d8}`Lv P¢YXgZdA/8JQg$|oF{oiۺ_|*G`J07?P7Yg>гDk?OPv}Kns'[qo t?AAGf"S?sOdp?p]#@swAis6bQK@l֗IGŢ$ ֗I/Ţ$ ֗I/Ţ$ ֗I/Ţ$ ֗I/Ţ$ ֗I/Ţ$ ֗I/Ţ$ ֗I/Ţ$ ֗I/Ţ$ ֗I/Ţ$ ֗I/Ţ$ ֗I/Ţ$ ֗I/Ţ$ ֗I/Ţ$ ֗I/Ţ$ ֗I/Ţ$ ֗I/Ţ$ ֗I/Ţ$ ֗I/Ţ$ ֗I/Ţ$ ֗I/Ţ$ ֗I/Ţ$ ֗I/Ţ$ z`p|Bmدd /p)b֓U1p"B/dIn9;\B2!`}d+:>ҹ|.Zne#&?nj\ns>/1B\r}8F#saD4fTv'F> ?^? Ҡ|O 抁!q'9„dk?r/?լHtO??|S+N*E9jRCx^A>HjIq@M*#[^S^ p*EIe#(e+NUji-O*#H+/q)/gJm"翱*aN#T尲3R̬JhyR8}0OQr䫐TR(_D0>k[p| ACd"g#<'~hY#4bjpz eYQ9}(c0C-?й'#h];\Fħk}fdo(nJ__o9?ZȺ߾P[d_j...6|S]??.?½\)uEY|L>Q* U8Fy0@raJ䰵fI &/!_YjU)F w]?r Wu'KMT)F ?\}P]Cu[\MN,դm2'A/k֟F(f W#h,cih \#ׅ֡;]) (}7 t|O<jH؃n~OgӬ}O]|| _?pxjWz_䃟~3>$8o〟????>/~}=^D-j3)-"Ybk|L$OVI*\Z]5w M,AeZNܴ|[͝tYϷXk8Kil ?6}I%ȮśƏ#ӿ.?0 C[69?*Q;SY ` h.;l +B+{A^\|$U/y5_kge?nCC컏ÏpqKO][”p;4iL`}ldf֟{O>hi,! e|*ϟ0?|tČ_RRamwZavn*WrnCm'͹ @1+79}}M9雘闭:j9 egZtEw_pOl2h/0ZS*-hhWjwzF2UQ ~{I?x~F|?r+?'K ҊRA)ʹJEZ&\YZQW*(e]IƤE>| kc:/LXZQW*(e]q ?P_m& Y:$.lV)𷌘I>{zK߄ؒ1SyԠ  :}˟?jST'd,q+5J _|hKYdO>), > O5uНC}lI'-jI~/~ ~o~~ {~V?k?dW?W?C_ wzQ%_J"+ Uug %ZMW4Y*EN?0%ޝEsS}MwM Jj\plϿiiZaN ]DT iS05\XC\rmU1О=4VP.>Tg6_0kWS zB@?q/(?G^??=c:Cio0S⍟? %ă?7+;7?7?ę_???O^F,Gs'\zt&:Jܵ!nSJ/qY٫`<żXRc7kX(ʆ ɔ \2)ζP2y|~KgR^Q5sFՊm޴!nRDYm 5{V(3,硤UG#db"4b}h;qg{!a?,g`P8}˟??ʪtl_pOB}}TFq;/{E*Eޙ#X?e|??n 눟????A?qQN?? ԋT3 0$G?@?O~8J">qrfS /^&Le,6pAuV0BB*X U3*Pd[Lejeޜd{*yX.)4)dʘ.a_2矉?raœ*d*WTs߶ ؄:=2E n9C^/oVo% 9?_r|v|oFA7S;l2Eu&k| yLV_rW)~~X+ݘ˿fzmm]#z",UUwYqZk u2|"%x˦:cűPP\Oe.6|NRIgEQr׿1⁻?:" `ߵG8XhK % `sQkV9<ʜf3N?괉y7kE-;]|q?۟n#;?}~S?$y#r,!_5W#d~̠x\+9OnLvod_\:L9IpM15sWgIzej=-%О^\ z/ Z}Y 2>d;?D ({S#*g_˟ HAP2 8GTh /?dAROq0О^..* *#A؃aP=3~'Op\Wc;nzbpƒnnOao#h'y!;xD@?W8B?W0 C`C0%S/Q??եh7??'?'?'?`S`7!lh _)A 4􎛟owǧ̔'(F+n1mXٵwO:Rsff%+\os_WF|]W+횟$k PW7 )`jm+L+:}˟ϿL/A6 PŘ1ɘ_ȍ?>n@W_q]P݂BL ۟\C? *Z \@T0]`T_T *|8PUH}GUTIտad7|HdҤ*pWݚsS' YqEbN??Rg_X]e׿UlY_?2E$??!pG|AXj+k%y>BXZ+k%y>BXjĪ~ʚrIVkE~ʚrI*i@\#dUZQ@\#dFJPG)`iVPG)`+k%y>BXZ+k%y>BXjĪ~ʚrIVkE~ʚrI*i@\#dUZQ@\#dFJPG)`iVPG)`+k%y>BXZ+k%y>BXjĪ~ʚrIVkE~ʚrI*i@\#dUZQ@\#dFJPG)`iVPGLk pR᥄ljjuj Whjj;'ۆHywI@׿_ EH?냂t/?\Yރ!SW|/߾.B??亁B?t = /T ~OW ~o~o[D+T/3J0JHjJ LrEUX@%VƔwC\TIg3%YJX@%hVƔ?q* 4E1W, u=*s9B<c/? TL❳T0d/b3(F@pF\f}˶wsݨԟqdBp#_nh?@WLWjJk"n7 ͹qCnk?2=?M*!H~~? 9?7xe?e?~߿?н"ZZ)cNzVji4~^T.tȄEYգauW _|?a[u-hhl) sQ 7돯n_4V1y? MI2Wr#|/ O?}m| F33? uC65_)^S(#~o'u|ҠO"Lo^]0G {}塿H8\w? QYD U3VQ%Ҙkzr_׿`JZrYi1v:>k`@'"(݁gkZSA6>XЗ-T:Jeԫ({oJh!@B$E@@yA}*R***] INhҋbQD:k!ɽ=sߔ(pvvvv?sfgg朽R/U/qmJFaTsϚ93]{5oJYjy2#x??e>0?ڿ`eG?P0z'ƟDADOaƟaw0ldE8O|O|O|5zlWGeY!ժtŰ@Q[R  Sp|7p&(Pt>rQPVkHCQbMSpcpp [N|nMKoIQP+9j7Uo_H?rs s|8mieK-dF忦KYIwqG_)w袋7cӬY35W_ ??( _՝\2AjQbRM!&*^1%D+bsSxF!5\rdK7_.aъ6^ U nzI7@ 0I ?B47nN7o4RCZaS6"TUs&T6^<^CFg'"v6*h/G;jZTVPEzRD{x-M8Q+(R+\oR^C.@IDATh/[ 2\5jEjMJue4TFHpInly&pը7)M-S"&Zp*UVPVޤT7^<^KNej כ&˖ki WZAZzRD{x-M8Q+(R+\oRh/[ 2\5jEjMJue4TFHpInly&pը7)M-S"&Zp*UVPVޤT7^<^KNej כ&˖ki WZAZzRD{x-M8Q+(R+\oRh/[ 2\5jEjMJue4TFHpIqгjB)_#֪_vr76W{Ұ;j+`+~ݵ/[RK/>J&Ƨ뮾B R?j5?p#8"F/ ]LhI?Te?/| d ?hLq0Ȃ%_a_7j0Oon|=; Df1xkӗZF^TUVZߔ W^3??̜j L#Nf)㕁 PC֤Vֿ]c'_z^-n,L ,yDuf ,:QxfARZ/y¾4hȠBy3ϦŗL~_7ߜ{fof͞ _ZY_K\HihA.[?3bOozaSop2dG0#Xl}5ػfcW_eό?VpS,`^E}'q\'MK}2.n!GޑŸPEn@ IDpqA"QćG7HE> @(D/߮kaAv:Da}\r_-("eLo}?~i]fGI?09->i,D۔?v29E1A"q3A\^ $PE_x7 u"os̚o\i2E'Oڟ"ʚ@7] pOߌ?x9/j'1P8_D!)AՆT:߲UװRr C*KՇ/pPr9~'<7NūBA+Uo|UrΡ*X_8u@(heJ(8sʭ&N ZY(_%'yr.SV$ʟדMPyy%9BE¨`E#vMPB6B2$QR|Y/s[l ;]} \)NfϚ68I E???hO_03a!#T$h(w7=j>;{?Ƅ"gW_eW_eW_eWƟ_P#\$ǫQO||E bZJyեdT۲#s^ w!y 4h[vdYWf8#Α,*-|) sYvy=9{ OSn&mّ9g?g8PTC\I伉o[vdYS'IIh~eǩ0iPȭ TѝCǟ#/L>,"=>P6<4sv+#3gs_^dlm1~yɔ?d/_hI'/ O\NUu9)/?fAv?-|ihMO߶<Ŕ?|E9MgQ߿iHmK1*Db,~d'aCT.6uvGi&uzj"QzS^ktZR? js!pM55-ABQV*I5-AQӦ0Sz+AӫA$ XܑV (^n H_Ym~D;QWp:8\>\9{ ק^x!sĢ7oi`;ZeqD3Wc\%6X.C/Ye.>y?j!'/_ 074Hr'X!8tC ?@10H'ooĘMğ@'^T½,1XEľy1VY.e?5[ҍOrtTGٵ(d-咷Vb q֌ ]f'rs OS8TGŐᦾiK֊VL!QQsMjNf4ih ;a*7'utTANWI/߅[6sA%f~vXj4 ˀ JbK/5c4x4k֬tW??W6?Կ\|6T9_hγi/KiE_G/_Քt9VC߿TKё|`daW|O1#㏌?y F{-ŒW_GwwwO$L L& *BE"(,Zaw@B$[ d`@dy-/JC[(_Yҩp}cƯfݢ$P,e.6Q")VL3r%UBc 5شj+um; iil|rGC+k?FK}~1)hN A[" +O]u?a *OԱ/_bo@aW_wd??dg/.]yt }yB)oy襎 ޗ硗:*z_^P ` }yzB)oy襎 ޗ硗:*z_^P ` }yzB)oy襎 ޗ硗:*z_^P ` }yzB)oy襎 ޗ硗:*z_^P ` }yzB)oy襎 ޗ硗:*z_^P ` }yzB)oy襎 ޗ硗:*{nj'\p * hP*Jaҿ甬vzw4^r'WR(3fͰyikqjӬY3 6Ovι/OqQi4JOEN3kN?"ӨMfWrAu JC(T_\}g4P.r,3aprS/\=! a??e;,8DfB3?0CqN0'p/@ljE!֍O:Ta3 Jk* XD0v2ۧH)ڠF񡲀`;@6(P?OUv emj۠Ce @FqϹJ:j mj۠(%0xS_Wmynė(0sl'> NDFV2(C0._b7TO?o fk07.|RmF\Qz]?1_(hUlZY[,r"JP\igW~/ڟ?i,)o wz._ƿC2~9MmMeZW՘|?"Hwٳz:;Ch-8HqA v"(x)l:=ZHa?@'y&="NKCCCk5nMV6nlR^x\l`ds+Zu$= m{*k"Xk s=_Yd:J×yW/J>|e4kLz'):#z[o[qcY*hOjؚ#{|%?(ZF'oa':0oI$G㏌?2O f+{ԙg焬Ă`wch?0dH `3l>5ʔk4+Txur~5OS|yVfI5 pO<34+’8+/PPFv7T>^lѿ_^8 jP9H8 UG7,UB@K G΁'Jy>ktU~b\YiWo'Ґ̙ҵנ=PT8tnٔ'+?brC?,ò~ ]fr ? :1~p5 AO( β,S~d.2MhC,H@/eYV?2pBt/_"&H2M@K?g \Ur/Y<_4˰'B뵰t㓘+͔EB!ZeX1t4j."?˅<`wQ@p|g37dhG5qSAh5~VhśQV K\E 寅?οV+^)jyi'OMB|EqF-+s;2UvRC1Gz[^tYKP~E< _&n\pr_OnךQ߽[n'O g)5eO0D$m!?r]?r fƟkd=0TMƿ-hO?O|1o1oo${#GO; ϼxhTD']6\yR@4?p@y҆1֩8g*2zTq-|ɬf8ȑi<2.? z >qAL78 ,_jA>;s)/way,_*%:thh͔ӦOK7\s<8&Vʥ֚FZ8sV{=[I|R8dr}?w6A^h<*?| "5?1C53`]o%?| jN?YBX2t`_oc7z'3|5Ur3A-=ګuK6ZUc9¹E7zH")I!ŦBmPއUW-!q !o*X0r K)~;`a"̻;(`u/XR+Pœ^Z@Ti8>O#"l4l p)UR'IdOߘ?57o@\+>O0=Le'O.?Ms|yM7ohcI[,h +bA _Pz={i [.沎Z]1^K\`n8XH@[$73Uc7+&I~vf8>O_h!~/ xj@1t"4d8Q Je1/ߌUcv/0J?H78^TV?~ OQZ#3bSz?vóQ/FS/^ 3V5BW7" պ$o|oTDMP2{KA@SaP Jf^\Z{)H(* *#5AA " Tk/I?OAe&(=zAWsj "c;ܮ8ʌaqGw&@8BVVTITU Oe!ɔ^q1Ơ/ڟ8P P`doߢ$1#dd^qa8/?1O?1?\`T /?0"B) q7Oٔ33Yl^$Kl^Sխ쒔%UFUjlVH/+V_oYkU9I]+;2' P0r%Y];߉3Qjm/ ɦh9>Oz]Mv\@IVGqfe&9Pp<]A.r1TQ¤CKdBOڟ2 "!3#ߪ? ?17hY*|ѕ'Cx|[YjsQDŽ_P?h("폊fc&h$@ *\%Cq&, a7S?GǮRޚL[JOmȪgַe`3/Ή^ėziaU0J09 \m䍳?Ư޲ˏD!f _iv/OFr%qlD@__pQP ?lR?)+ dEŀ7o"@h3TyY7o6)hI%2D;ZFsHŇ'Oڟ?M3uCe:CWQHc«=/d5D(i\rN\rjչjuT.9s'.Ux\ t:**Fu.:mK܉Kn^y:Cm%Gz% Q6N[G#=w[W{ިP@rɑ;qɭ«=oTb QHϝV՞7s1i\rN\rjչjuT.9s'.Ux\ t:**Fu.:mK܉Kn^y:Cm%Gz% Q6N[G#=w[W{ިP@rɑ;qɭ«=oTb QHϝV՞7s1i\rN\rjչjuT.9s'.Ux\ t:**Fu.:mK܉Kn^y:Cm%Gz% Q6N[G#=w[W{ިP@rɑ;qɭBħ%Il$щJun@%eIalZr{@C=$6w它u`Wi׃> L#)?ԿP\PˉW~'ܠI/ zߌ?`60*OՅ'dUlƟ3||P9*C-#㏌?2X&dg~曢$_݋N|Mn$41U@xf\GI5MLU.`mr#靰r6:Hz'librkI5MLU.QF;akMS >XHz'libr͸2 [k\ XHz'libr͸2 cM6>~!RQ⨴RNMR-m,Yk# viֻCUiRh?"+ 9S_?\EAZH?냂Ag57d]) ㈕jD@?`>ȔQ}%~EO@$o3`J7PC,"W[AgJ`'+c#Vm|+TK jnXC&ZJ)P:NrI,PTI3扗<7lZj(@8%qqA8T3^cZJ"(A1DCY)Sa~m|$WUR=`/O1w0 hj1 5p*Wڶ&OS8uèOp '포'_?iP{A>ו5њ7oߘ oߴCk*'b_L@Oߌ?T/?1oЏ eCK1&X 2Sf֍O=xi!+ܬ8Fm&s;co)yl18~~(S_.G ngԋZ__+pfcOƑ혇E_C/HY~2#cWyixmH+8#}8qj@C/ha^Sѧƴ0 ŸU?'ot O1+㯌2+L#1fgƟ%|(bϓKr_Sk;5:TYnI\ IBQjեP:qSR'(:P.ԉ۔:AAԁZu)Nܦ> ԪKu6%q=/NPuV] )9y!uR(@M)}\ DUBmJNz^H @ P'nSrJBQjեP:qSR'(:P.ԉ۔:AAԁZu)Nܦ> ԪKu6%q=/NPuV] )9y!uR(@M)}\ DUBmJNz^H @ P'nSrJBQjեP:qSR'(:P.ԉ۔:AAԁZu)Nܦ> ԪKu6%q=/NPuV] )9y!uR(@M)}\ DUBmJNz.rSv9`דl| ϒ] , #(e# AAu#?-\P 4 IjVfX[wmeE7FȕFVDei ߴiW̕b[EЭi/lgJI#/є, ]Pi9?+(RUW_uTiE/Yr=$-բۂ_UƆU_ s/F]gBø 9Е,) όGdܪx&55WMB\RVͲUQR·&Ȥ+┫zJp!HQX.dSClV+$\)l@0W)Wr|OAC/lhYD1i"ωUw@EѠ0DƟ'Ɵb'd?㏌23ϪNdYJa~Yǜ*!ط 8PŒo0+ϱPz/M tꄨF1p:?@///ꄨF5p:JK?s?]&oHjxFN$R^,B8e|)ߍnm#!CI'U(! jǨ/+*շԿ'ʏR]/Q?icAKZI7o >O0aKT ^E&D\QM ,hAGXOl7_LiA>hbN4Ee]J`SiM/?@9'䥧Dgp[-"j̲}ViWhRkM㈊pkV;gUZmGT98V*ˆp!(Ιg;V*ˆp!(Ιs|BfpU*FET Av4+JZEP"*…V;gBL+((TDT Av4VP*iQ*AXi &]s h@n=aNnF,$ W{ka%&Q ԍhV~?Wւp.)z,_"2+1Ŧq'o|؞w?PM7oߴ)3>1i4L)atvYm "ڟ&.~M?QA&OSP | qP|kw({;G?0aI}ljM~|a1SRJp:Mpj, /dl|$ehSvЫ]e>SZ;Do&G{oi!s|GC+kYdK" d I/hF`'XJfd/?33ό?33||O||/QYU7>u/IjT+*ՙ9(u+'2tVRP6:wխ|1_G5iMQ:O+OňȬ\XX?\u瑔R7t'oߌ?ȜaEXʁC81BuzRD{x-M8Q+(R+\oRh/[ 2\5jEjMJue4TFHpInly&pը7)M-S"&Zp*UVPVޤT7^<^KNej כ&˖ki WZAZzRD{x-M8Q+(R+\oRh/[ 2\5jEjMJue4TFHpInly&pը7)M-S"&Zp*UVPVޤT7^<^KNej כ&˖ki WZAZzRD{x-M8Q+(R+\oRh/[ 2\5jEjMJue4TFHpInly&pը7)M-S"&Zp*UVPVޤT7^<^KNej כ7=߬O}[f J~PX h_)oC UB?Og矄DZkM_?\i@']E4Gvʜ5uK_0 O2+cWʵ51+㯌233ڈd;LFv68k4?C{fNxHP)HPhWND3.6+lr|eQु0CA̩ jVD?@бk3*@&u?:7b_?5v=Jld*wc- 61MK2;G Hm>ȔV: /?hMO>eƟ#u_Ы^d㯌B_`.~0;oħC3F\D2hD[/@҅rlȒ»)ʊ·B?t\">\sO7BՁ% އw ]K(J,i/LX2^'mi 9>oD믛 {QLF"iA'o #0Pꌿ#oj1G|W [8 ` a7cbG,b20+ό?3F2cWe^`M-&o[GwwwRꔿ ?[>slW7UAEH'KUC \%_%'yr.SV$ʟWɉC;jb} *g|UrΡ*X_8u@(heJua,ͫ'$/B/žWE^/ @nD7h/%1$IOw9wpaiq_?\eE@O?#O\6_ԡ)8o:49X'?~TWU2/ߌ/?1#㏌?2#㏌?3M#go/z>N=05WY*r**5mˎy=3OKv8*B0ؖ_R2ŭ"Ȉ z6 \ 3ZXb:q.:ѹPC+;z3dD۲#s^c.0G|T@%o[vdY[\'I&To W}of~=Hځ>$qל;̙3?O2䪏:g |HT'HGv䶚 9V[-mJyI'i^<6ds/<~rکv\pY%\?o _2xpm=ϮKzkCAEnj`|߲ N+@g~?O+Կ\Շ[y/_R RF|09.#( .3/_r?_ h2!ԚK!͊Ҫ:Lo0L2n| azb7oӄcϫDxȡ39IV 0ržohJ+MEBBPl}n|̩xeqs{_t,K1+ Rh}HY:n-u\]M+<:sʹ >5/{;{ 2(9:8rdZptsЍ-7Ozǀ«?[yD[~3O=y7MwRWWWMna:[hr#O=Sla?oz_z*K:?^6 =_" 0`eO'b?%WҎ;n?_ĉivkWwz 2@#WM}ƬiۂwW79?|eӗkZiH7o餓~\ֿCwlZk#=/'kҷsفOz }g~:`3~ٵW_.B@\r%_M?8U>OU0MRKO'r9g0DM7i]v.fyU~Bgufᗿ|a{H7[러6kDȔIV+NxQQ 2|ſDh?^J B+o!_?\d}+HM*`{/Q n`*!RG?uS. ^ +_Ќ6ҤS+D9_͎IjhĎ3GCO(CWZъi?8嵧 N^% nK&rcpp@IDAT#VMuCF4 ]hTy@6 ?o6{z^tI2o rEiA{Im7EGX!wd03?3ҰņiSuo/TS#ov}όHO?DҮ_ _"GG}LZqH=t*a[jɥI8W^uy:̳U濬w|{ޕ?iҶMҹ`?*L yVa16]t!Au9n5'kg r_?1+Ta6ZTk7Bdd>_P?hA?s7 ްWT[_GwwwO$1=4IJ".%T;!m\%/jj- K 0wh̓BE"(L69!eţWTYdR\ǘkFy0CIjkC@CBWP%ԇ-:R!e~g̲˧\QGq:J @n l;Iss逯]$]R1cƤÏ8UYA'r3Ҏw^윶jgxnZmX/ܵ<49Miӎz3>:rhv73-o~So/K~'N.MOXz<ܖ_qe[oo?b/r‰e !~fPOGC,Fl'_ u @I[|0?t%8!Q@7C e7TmQZ|ŕK?j2 N=Lz%_i4a{ ?~_D>Er‹R??=i06>}F˿)'ٙ~[|ȉO['IzO6D%\r T~W Rx'{\Zq%l|zyFulp9u HINX\hϽelF/7Ӡ΁iڴE9sI_vN/A4I6>iQ̙36IO'S~z%yN^("v9999+??jhGmmVHJJ+]ӍOJ! Jk* XK1M&_)3E(>Tr< m"K`N @qTQA_i̐Z֦ J(>T?`׿&xЦ (_s X7uu6>Ǝߓb->ut q7II |㏵u]78ANa:?|UW,ߨ+IKK//}&OJ7Wuuu 7(s,ni/? /oM7z#$-RiAiKң=n馛ng/yvhOߞv퐆 [Txy?'L+{v:S/[n4~"6$?] y[&kzZ|ɥ^Lw_M{w\\~:kSqȁ$ext?cW[ '},Ɇa=LC~J|P.:_H~j=tcx:mJ>`_~_ntNL?7V\p@mCn }:/J/(gO|rԵ꘴?t}v)C'WG~X|R_osI0ƽ45Oddӟƍ/l{Mw)v*Mi 4,ҍ[t02K/ ^sƛn}}b^/8/808He|'GwQt#=4-:uٳfScȑ# ApWOͯGB'< rpZe.m+؊{N|d|𷿍J&{ 6Pq&otзRKɟLV2|{GQ;OщiwKQ}3~rzл/'{O/|?,)]trJEH|z+ SX+ĝ|XZ 5W_NmYਣN 6)0|̎;_<ȁ&vNY~'w\om{_j_~/'翷3|B7ЍV>0jnh|_ii l8CAۑ}Cj=6,?zӿ?ĩX#/Ѽqz;: Zji!q_\&i 6`W>*ʼn3_Sv@7'?d?ǤFC ؘkAS.饘"Eo'͚5+m7q[Wj/M7Te] ?ͦ7ؠ(I;>ec6ʦ_|ᅴ!Iq=tGj_-[n5zwMe.{wܙƬ (߉y>{ACϯ>F?'[^dtgI׺Ylw|`̖AN׵>ؠc؉Ovivmn$'~kO9=>X貕p&qrr=?6]~P>twJ#1~7ͧ! LEϊꚲQK_2+[p oi'<Hx*Ctfz_;-l<2lD[&c;;8?3cs8ԑկH_yle;說 /2/v[kY .z=pn^ɖX{fOʹKz>kN{'6rv?r|c)a}|SAU/+Gڋq#_.ͷL]Z`mgI6~iQ@垲ҭyּ? rAf!췏_)my]/W}w_8%RS5/_]R@BK5.?|p5)EW?hSZA_B׸˄W_u:'B/z8$\*MdI_?z?cd/oEFu*(Uc$ Y}BȀ˥Z )_*)?ԿE}d͠Yx!u<5\iԉ̒jT|5wTwb1߿|p,HAA4:ChR!C2^.(Wd~̙OAyv+3g!G ω -E|aO? ~o/ƻGTyygӓrtrШPn %.PZ 0P JO:'?I^y5 <)qD}J/ⴈpz׳=`F4w)IY m'm\k,+ǦgI=(zB{q} Н4!6QJ#<XB?,6 ~5zd'A_]6>m}$8dx'~H~='Qi*Nfy'R6`-d|9A_F V\q4c:N|'>e+o$<Ηv26% ߋ->8Q>ޟƮ;n٠<Ǧ8g4|ɥ$8I' /$ 3/tGo"-iyCTw]N8MP}Cjd#bQXN?T$|ipޠ% Yoۡ֟m&n&iHs1ʣB (9 gw4 cv !q{ƌ|*}g%H'z7uilsݑN?Tfv(Ͽ 6>}RR!Tq_I8,ħ?'P-B{+d?, NN̎:8Mo4hlϢ90/% .` 6>]K)(>7:Wݴ^H`sD*#8l(~o6ؼ6j&N&{rC trj -dLb! Y8~i=h6#K#^w}lTZ'/I>Z,+tOvi'Ӟ">'[]il:0kW3O<Zz lux]UGyvT? "ྩ8$?꿏a}t̀Ɍ `lC;a Y<>^{'FQ૪ O9$sY`s`l|"lsw-'5{EݺƟ<YN)9q6LOz晧 q0/]X"Nn{ 4,҉?:jѰϒh5ތWg$!w^Z+ɧ?e@s+:KI;oS 1c8?1f+a6s`]~ <'V3ߟq|?/ʟ >9GCK \TAR|in۴?K_?hM/j72cQ ?e kyO牢YE2kkэOfr}U@ȋZ}@ʢ/x6pPsiuJW0.Jٌs-A͹pf1*@*-cv_ށ) / N>J2&^Y@{+L29ΛZoKO\w=eC>no 6 Q#pR±8QDbr TLp|~U'L|3Jb#75x"6p`'NWQZzwo"}癑>zA|P?;G>>_‡ʟ2v 8F}]pͿ=,Aq5>>3c#$ՙ3.wL3Aܿl.8E|S^?'U_fwj; #VL4K.r0EnZ']{-tW'~cI\^} N|։.Ʒ&_K.9

    ah o#$[lˮHg}f-=ޝS2onH?j_ǐ@=}Ʀg[ƗMUbcK.T95Gُ֫ 6ͶG6؝{Ա~~w:젃ͷB]>1BԓOIr1jkᅬl"{P?9M>)O*|}/u\A?//矞t;t饗*{'H7H=LɆQ)G,Dw3t" 뉂p\zӖ8)H_/]?hEs oHh>wnSb&O޾?oq2̙p2d)&!x^_F!d9?<Jӯ_x^|Sk??؉1#IAKaCi:xl/1LͰ]l0ՔES VaOCNk}_~Y:G7>uFvUW܋ __n7 v&(`Ap?ƛng)w O>^?)^.&nC{m> Hy dq80P 硫<1h_o` ^O_©anZv/9#&y&d#'q$qX6uc-S~i͓|N|t<<)^x4~b~soY)>_nQǟw~&/OJ>ʟ?qs>?/_ڟXNS.h~A,fM6і`E'o?^C]<ŝfԮ-bSV0/ _E#8ocs="?\pd7As#CMt`S.$|Lަ 2I`OaKYtR$O/ĕyȑ+51AsQ1'Gk$ g{^Saf͚v of("}ױIҟtQ?dVu{[z3>>TGrװSo6+ 2X7al?i̛o~6nLW\~y'︓m|e:tN'njcCLrWl;t߃ a/J??bEȁnx'2lj?oc럅Ά ?׿|pGhdFOB+NW6W^r|w6mʭr6뿱c&9H68mlZhHN'9 p9O|:NW|M[l>S$ɩ4[ƷOm\cwn:i[nK}@cc?ᾲENqǴpZMw^l Xq]_O>o[cң2'ޞ?.I7>'Y_ش%oqؑoVȞ''mG{嫱13~RѣWIքM7qX[ӍO8+}OgwwжN69PN|'{esSO'{+_I7F)r |9vZ}'mmzX]:;mléD";\f374' lN>w\vc"2wV;sKO9 lD/0ӡna9 IL44_z$tes!ힿl8[|%T/zRGVL~{%8!s Hӎ؜ 6ISú 駰;.'~&Nm ot8连=˻~8#A x&2┦à_|6&/uM7E(u1{lfm_锓$.{>c؄ ??`˜4?_^')u z>On1o/3"OMhw?W<h4#FE|-'" gQ?|V-jpGs@Byaw_FH~O(}c0gL.0Fuvo[i獼wY)Uo87CmN) `e/:yw \p"j#J dgs™шѢ>_nC^ڭ>H'>S}GL/ =,U9(7)ď/"v'zJ!wmֆsJ+Z,R/nn=􀏦EJ5Fr@>4>ֆs<8GSiGp Ky'dI"˴jj&r{?uߐ.pAK4c;0ͶBs F!# { ?/2x矏k(vMCO">#=퇨OJ Y6t3: oORvo'Օ1t2xe>7>S,>,4i;tj08>a G+jD1Gӧ=448tqtQG"j8~T.ܲnYDHS?p1GV~!7\[nе+X <'ykM6%E7h@77s;|_s9k*?AGri2vwoky pZn 5 etז,eP۬VpO?Ok\8!"Y([k^xgg#I?}/p췟T䏻@?즛?>չ1 Ԝx@n͚7s}]y%B( >}i㏗t?u)밞;;D|4qx"@%:$|R+Hʫvm L8 S\ȏJp\{͵eݺtAN[@G2 N]583\t&%M+?MSV??8>琲uZs?aͮ[a U_/mӰf_7Z vh/’39oMο1/ο>'xƂ4Lp"vPk\| egJ.7?t6$iQ6+([pc=}ob Y|Բvl͝]7 |ϫ.:-^UG?#}>/Z묅`'Qa9y&:R F!I"l=">cqS:85rck8TiN4D?^Dιy8ILK F9s 6-(">8>eSfywD?R1x_\'v1uA>,?I>8N;}eƉ*pFĺ sn+1i'_]s%2Qr);w$3kE4Nٻ8#D$ 8İ o`I'#ܞ{2ڑP,箻WݨofpOlaȨ~Qd,7\?Ds^7b؈w,o3)N:~?ܖ[nLjMF &K812tyJd,RnH Q 3{vEn횷lOpW 3oe9xsZt|vxGN}}ccn*_'KD[o>3j˭#K.鿭}qOECc1hpbbEщ&L஽*8!ZPckmWy ѵ7/<ʫ][8>9+otEC^ǧ50湞=AYVl zy:>݀vUpۯ|ҿ;Vt*BmNN_zF4"N膍 ~mGYhUtC0š߽{D|m,u/JsU( _6Y yawUW6'q?<զLpdbCȭ n \ף C9-uVO_UV4u3iR7?Tz)txLoP~D?xbUW_]g>Ǹ1c駂myw*Q(}/c|#Ĺ(ڬ;8F5.=ys݈܃;ҋ/YVDom^fY۱ov٦oO"i1v,0 P]nFh|p-8} 瞹s0@r{87QJo p#?"h9λK;t&}reYs [}l׫wOaw_޽NUx";t\B;BW:2]ANlGǟ|<"Ͽ 봑we8[B8MpB_.u1_f#SwደqzFX 1~L%pģ%q)qǧ r##RWO:O@ZirJ" wtP`dHv=~ow@Eᐽe\DơϴrܕW_M)swgn;waG; y/H?_t IKrG~&M' 'D2Hu(GW{WpZβ,{ɧ^x눒0_{ + 3҈1~7nN[`-:slk`ET?ճgo뮻|zɐ*E?ē$UPWR񬐪_~NV& ڵ_f'Ju"_ѱ:yAW1~DC%8| ~roZ /Ocr ߘ;Hݨ8-7U2qwѩ)i7!~{!S:݉H2: Y'}<7t̿] '6" o0dөK}DD$2 ?1)/?:Ҧwu4-o>gy_\t)7?Lar5cOnI W[lI_l{d<`;k+v<߁f~ KGa;Kο |1/J~2a_D+{MyE+$)BGVmRP\AIud_dfW*<Jr2˔6(L7 LJBINr%Ց&d_T(T.Sڠ:2/l[WӱGn=}A ;A)6W.S$"7̏M7v״yS~Ž5yFNC3  x݅H?G#zH|ܞ%Z yW# , s#16B׺^=yutӧ#>M4^/zpH@IDATj_?=>VipH:!eߖ[mA$uW砆̿}"w`Rinn_8-q>w=eD>G.t~݊+]{U^')L.G4/җH?cRd>)O.]^{ 'NwGYnԭ {cOlgz{K[sl6ǽX5X 7əgO5+=[@U+8,쇈B䟝 S#>͞ G^=sg_n]{vc&uQۑ>HGIpŎy!-Ͻ|8L+htx'|w{ cR/p#?c|P[f8̅C7)#TrH?Î; Rǯrnzջ/>I?:>C!'z">m٦m=cd>ꠝ:r4ݫt/QFGiC:ݝ:G#B"#!{- { ~:>a,M|5[nxPV+th Jڤ rO飕vK0"R'Mbħ_>TKY4ӣ,;){q%<!_gOQv?ݧ|\>~KEvk)k?mGpMQZ{m8z+תU+/8$֧WY {x˽ хfOp&?<{A.2l{7g6} Q\+k p߽#o ʶDݴiuW ӼS=p5>\~oOS['w#>!hpC^c.1r\寃D|:W/0S[8!̈́S:>L++\7#Mx藔)BxrwWܬY g$0cF߿D; S,҅^n?ɟ?LÙ`Eq!5OyWGle/mmvS>W[[ǿ]_P*+}ciA'Y+oHe=0/_Ş[g)<lАJpE<^6l@7/IATbmPn'i()W(o#韜T%L*:#:>Z|Z"l~~`Y?3|̘='xܰ<4ahz_n-A1<?GFʕNOZl)5o>Mxs< +Wi]|{`-Yc27q d>vr0djߍGe^Zԓ7|33^VȖ|ǧ&MSކS LAa6PУ[s+"bwQ9w[{J :{b,h]Fsι2'{]~9O_:Kd>qQNwo*.B{7?P{ak<&:DNP86EDI)>j'tzۨ[]w˽M6 :ֹ|t BxC8q`7t ӿW#j8?pG>@]\kmP=C=ѸsG{{̍ww}W?(gĀIlR$NK,CPxTw"~mͣF?}o 6m!W\)`Ԩ$JgBwgE|8`1\Dc#^Cî?@z͈)xR\ɱqFW~xwo߯?ɴiHOO,O˭74-K=}hNwCwz>#/2lx!AZW#B822?pM;ĀnF}SIꕿMv"]>+K.>"&!8> uGTV-OpHyt#_|tZ%NtЃQhSSΑph+ks50tr3{{gP_V]u5׾};x Y>ju=dCߞݺ(Gu2]7v/qcTWxg]td43y_/,?_~ ^鯌~qéK ˽^{ gr)32_ed}uOSGh o"> BħZȆO?:$8>ݻD>8u"6GKǯYQ|v\yr-wϽ%_KYr{w 7PC(Q?nv!t&s=|F;F-'+U@SQ {Sn ? '^|_Comio;e=2_Pf/b`|NJMj#w?2A7Tra4^ގR!$s%lG2OўTtG9~_g?>aqBiót|s |\{fx}χ]QQI a>P=3 P!ʵgɟɟHNP{T(3OAd$'(=H*gre3uOuwf,!wܰ gJhsPR4aǬb"hOYn=ȑ.b)"sއ_[Q1xM~k"cW;|wyEt8/_oJ[g"?.O/lKܳ^owR+.wxQyr7! <|޷Oo7Q6gtysf sdB!% k"O}T?oOwy?gq[S')pp{7_c2Du/'GwՖ[w|dW2PK=wD[u{8*]n9gG7h9R͚5s#,:Da4)=z nw|ر."1\:pt> |#Gt±_qKOepL]Op]2&Srgϫ)k?H!h?A6l??lhbܷ@ç̚o Z_AQQuAef?~r+MMh`5L8$O8>Vi%h$_;n1Ѳb o7 nOEZ9A)m1b5'kÈOjBfMZ9!#%ו9 yLi#9pi\_^ǭwx{8$ [nYpRy-8=އNy,èpkq>kD6RBJW#9pɈ.Æ&yuq={v},8F߯x]v͚5uw=أ6B_ bqǟ.Cn(It(GBpsO#OgS&@Aoղm\Dyg}>P/Y@ ӲE/xz)5ڭ D:$?^|8tM b}WB|'8?W[(z inmD :3O?nQV\qwGw\׋.Q*T>^s{g aEF(xQwUVc.1 Cp/>ƴ9̈́SQ: "YbH=a v )gu1r3nG gno}2أtoNEf[B/tgq{睷%8NnDBc'x _W^ɝ{ne Y'eDsƨA|+'0Ӽ9މ t<[QQDVC)^?Y`SOw  ޝ:U(|ϻ}K>'֠Ԧw u=rwtPfݝxoATcn:/[.ѣ'o#3'|K[c1q.ucsf~ü<̼}ٓ_q$չogt{c.eϦȡ]h>p|B1>+ p|:i@+lk(wEH[;C SOZ(]v&pj"0F_ENxc{%o%?^@Bd Y6k`]1c(I%m= A)OCx%pP{'f`1}2 z/kdEGǿ&oբ8Q"Zꟾ~ߺ_ݽpęwN;qDJg&F'FFpl֢9^w{Gܵ^jai@䢭F]N%uO=t8=D5YG8Yy48QO0Q5eΝI܉pnJ?h;>?.D'F|RI/B_F$I5-uXo]7D.n Ne(#uΚɈOAzYc@6AdjO[n^K"#pR#+081&; b$F&pؼǧX_q` Gl'$UpxZ OɇoYH dIwW6+aC&柎KFÞPdh!VH;V]tGa`8>$MuK. Cّ 4GgDOߕ)&D17$:>m&%QhY.\UV,Dc8XU!}w5 % {8< KBDvA#D|bYB)8ݥW;oc@L~'DvTLY];wqEoj^O/8>O?andΤ%aIE_g˧&OuB6^GyTڞ/|,">ݡ"!oMbn]1uϋ>rt4|Mp2_Iqc4fĦ~E1v'eƨP\g)?,NpЉ7t-=>!^l8,7AtKO!G#bQ;>٪lCvHǯcyԨ 5swT*8uwJHUwL*-; zd=2q 3Bޑ*?i[nǗ;ʆXڲOqC/'^t^ftCUf3F2m?AKpBG%/uV.?O g‹~0wL{g+D4=x?l !ɿ_TAW'hd$?!mϧpӊSW/3QHgTCQFa6dHD1kr#il0?0#e'ٟf镢WPЌE_U\8Em-9-Tc+ZBu& BM9B5-TlR/ 9-Tc+ZBu& BM9B5-TlR/ 9-Tc+ZBu& BM9B5-TlR/ 9-Tc+ZBu& BM9B5-TlR/ 9-Tc+ZBu& BM9B5-TlR/ 9-Tc+ZBu& BM9B5-TlR/ 9-Tc+ZBu& BM9B5-TlR/ 9-Tc+ZBu& BM9B5-TlR/ 9-Tc+ZBu& BM9B5-TlR/ 9-Tc+ZBu& BM9B5-TlR/ 9-Tc+ZBu& BM9B5-TlR/ 9-Tc+ZBu& BM9);$"_>FQ"?`&݁GP7CG&;l ~\\f|8>a]@>0NyO˜Œ{ӎe4J .KSQ6tSw,r, w "lm]|Mv}T]#}NLe΃Zk.&o@w6>J^р/?d1:π InuusOǣګn})@czFD: Q[Fpw0DD ;}9Y%)%^n35ATagjtȡjZf)dz vW߻w'"2`GD/6t`J_C$6Ao=0tеge?]uw=ᜡ1W3bϔ3:N;Z-^׹x vcnR]?򖑮 DSсH_}q'苼'ƛFx'(;wFH㎇͖-?<ԓR ο8۩3ŝ;V?Vw'^y}Sz)*i}G;:ܩ-vGcpz9y🎐k o)og}H*Mj?ֿ⨥UZyK7k1|U%c䨣L.q'p/>s':M{S:n;5I qnΏ"lzɧ\NZ={Pfr{ H_NVs#O?v[D(eo߸ pp6svUiW OSYgO?0ſog/& 韆?ma/a[?,;c돭?T:Kk믞a\;xK??C$`Y%o6{aY'/Y:dtS!嬈]eŒ,!4@2biM$GHMKf2biM$GHM3r%GXZS,R@YGXZS,R@ӌ\ Q*#K|дjVQ*#K|4#Wyʈ5Œ,!4-xʈ5Œ,!4ȕ@2biM$GHMKf2biM$GHM3r%GXZS,R@YGXZS,R@ӌ\ Q*#K|дjVQ*#K|4#Wyʈ5Œ,!4-xʈ5Œ,!4ȕ@2biM$GHMKf2biM$GHM3r%GXZS,R@YGXZS,R@ӌ\ Q*#K|дjVQ*#K|4#WyʈiM J qLyNB"'"`έҊnkmVr3妼=&IE%k6Z/},S&i[D|*ӧd[>1rk]|2XʨkvUͷpN}ǽ?,oVApz{d73<3nvYa=8m dA^{+oP/RpNw\>}wÈ.OAmϘ_¼d֭Z)֢X+#/ԒCG׶*:k٨7_3z'zwƌnԩ"s_X]z5Cǎ?q/Ù뫯Z,?/TSthc ^v_n5Na/_/3ҿggJgT5 5ӿ[ya٥Ϝ!L5khzɟɟVb hݘGVxS/of=6lw^OfO^#ME$;vUPвkNS^VK)//5GQ03CgJ>/u= sBn?ȉ8Lxu4Q) k2edO Gx'?xb}_bӗj`Fyٸ7߉'!bfd9{py0g 0G_-\SC=v ? ?l;~۫84vrgTOs|C7~}ǿ NwQ*G{c$!ҿQ6J9g濭 hw_'j`bQ[2!tr_fksI`K/ \?_?mioG ,i?R'~$TD'WY/RM _/IۧRMt\FbU?Ȅ yU0ljMu_[l *XwBչZqºT< ur&75-IyqG}7Uvq+}7{{6eO2dj+mFƁ2?]v~i;!٧Oo7  $F D'ӿo'q|Ab9Y+DyT~VNfw,"0~~QFBKt5 @:f"G.SLiDUXr1)G7;B*JMl-+S<\P"*g?U.{! 4s&,a>߆trg -#΃䟢x,'vZߝ~Y"Æ O pK/t\9.R{o}[1_@m?f(faf(JΨǕny̰?(TDYPD_feבHll5aG6+\->-2/佬H԰6Sȕ_UVY_&B+3x\zy[ ܌`ad-LLlU=a@1c\ s$X\aK#~c'mER3CX$Jut$ f[rT x\M'CG`ImT}5:0JO&[fmDZ2Q+%?Q4C*ܳ>"x#qJjviGtQf0:@$_ǎ"7p{@-s7[?j7gٿ6?veF8'DUX}[() [L"7?`9b[ `BC"40!fVqo_fme(;-R_ ls>4h F/*Jo@E Yr<^l0h2%$2AM"Ks&&ث̰G&$$Z#WQ$x9?Lԯk:nyB1Cj$\!!m% 8LX&E؊*IS}?L?S}iWTMt3 ӿk_TfmiOaH֋lw%ԗLT1g?miO?CbOcJvƴ!Le`_@A!~/دV{7%n^3))bKL(Kdؒ/8-J'|m8|Ͱʲ1-J_[?NDH-PiQ Gq"+8me5],pD'" &-e((iQ Gq"XaI@Y6 JZ!~lVe"PpD'"䯦cgwKS< dx6˂B`$O-}${s5?Lr-K?aE60EfP60p37vD[/q|O6_W#>Q *M4M;K(,Hprii>˴ɟDR9ѴNS4eZcggo2C"tTN47|St|nJ9R.ӷc ,fsW&u(}ilAXCAˍӿ\ lz5_?he} w2Oma/b}??A?+ϒvd/vnvnvnvn?/djԀWq|ҟE 74TG)HG[(KFP3 aUu rA/lgOCE7W,98a7EHr?]}'fοjp߄3tfuGnW;Y9TmS(*FogO8ЏsE kQ~ɎPr9o#Ic?fkloщ@*әxagi\;( ?miOm5dvbO~:0t$yQ %n8lmo;Am)[jA3oŚizMJ:˨fP-v\(k>eY|IF52b}c2b oŚizM(/˨fP-pI.kާ=6X,A)&Xybjb}c2b oŚizM(/˨fP-pI.kާ=6X,A)&Xybjb}c2b oŚizM(/˨fP-pI.kާ=6X,A)&Xybjb}c2b oŚizM(/˨fP-pI.kާ=6X,A)&Xybjb}c2b oŚizM(/˨fP-pI.kާ=6X,A)&Xybjb}c2b o⚎gquB=1J[i[᤺JalB$N~o'3LP+5Mc2ﰻMM`F~M&oI;;O;ɂ??{=kW;W;W;w;w;Qyi;{(k`?,~?ӼyQ#=J׃=Dɣ]fLc=A[?T[@8Ki.AI 8eI] >aEȷPAǥ"[l@~"WA Uz,^::w!j.i,Iֵ˷D z|.-}Codg_[ff{&#H?lio`\_~'hG;QnPv?ߵW pxο19;7;7;BvhXi2??sEH;];InO_OG~g CRQؓ iY#n;)ysBS޳>}č'<TSפ'<,&(r(K}MZ(vR /4UeI#N yyy>erʡ,5i}#I>;/?χAj:n$Xfoo?/ž ^%(&n5:q"~h"<~\[byO,}ʇ >1c["`Y0/??BM '@IDATeCv'w橃Ls*;ΟT?b*UvbOvfvhvhvh/;w/ O:*]~7/l򂙓倀IDeZ|>¥-3 hBAټ4$D }arvx BR( K0O٣5c̆85"$/IYOZ|bG٣l4c'j:"/SUN_Z4jD=oÊ]'.o7D|✐b_[l5/?y@hCG!IqCmK.jkBFl~+6o)!3 6Dbv#cٟWfiږԥ_ 'Xf3$h̨:.^mK6P %)c8>yŠBrFLX K/BR,ik4S8 TjJ]C*?4ˠԔT'_qڨ[Ŗ?L$L)h̢KfJE 信{\@|}'х|^yl>pă''5!FJ*2 RgTէ&6L_fp/?]N?>p%O/2I]&mio;//)v`v`?;;;vvbO2'9p'!l*L;7Ȃ?vRUoe*zƂYIH^lAʎ,-eLiI!?ɟ߬EȀ$"g&&MJ+JK"r??#>e_jDyN+pׅ2ȫUL=mR =D4COPf&6Lu%ӿfEHig8 0컫mM(;H;';O;!V`Ѱ;v;Z=m/vB9d7;7=?,D9zVU[[[8!xtQj&lYIyc?vZ-/?Q=`RL&)_[l"0//\%f~gWn<HG%}*x: _E@>lq&)@|%؇ӌ5i?P Lpq b돭fE]/?fRR Jv`/vdovhF;Ο~Vn~g;6?A~,e/s_7Bϩ J/_0.x}i/Jr /}i/Jr /}i/Jr /}i/Jr /}i/Jr /}i/Jr /}i/Jr /}i/Jr /}i/Jr /}i/Jr /}i/Jr /}i/Jr /}i/Jr /}i/Jr /}i/Jr /}i/Jr /}i/Jr /}i/Jr /}i/Jr /}i/Jr /}i/Jr /}i/Jr /}i/Jr W'Ҽg!r'@9 Ad%.N  hU/ Z =i_F?@1M(R`V3DZmU(ϲٕ1s֟l_? ph0k1oDe̺J;?Ֆg!A?ma/]8o&,?miOXi<2R+miOmG&`WGS4LJyRĦYI<3Ml@"׼_[l5C- ,{֗i?l%3['lmos>emUȅZK X-´;;_;; ;G; s?넝׏/ǪyUW7HLS)iSV,lcx9SXS4M1RX1g?$=H??~>!L&MU)F +  ƍ=+/׼|*'AfЖšh'^XHÐvo틍>X9Gq7{ 2gRӿT )0/Refmܰ?mȵ;Lpv??#5TW;B-+uΟ7;G;Ǹj.&?y*XlPl 7IY%|EІ+gOOYbOȒ(W[0cIZט-eod *8QC@,(Aa%6lrF_Jv!`ɟ#6$h\ӿȺkfq*ћ?曻ܟ%s# BkY\?G{Pn~oK_xufF5[Tef\O9ᆭQ*_,gz}ivm4X($ 0 Pn'9a߶$._ӿM秽X[ze(H?RPPRnDUd}&/))E,GFyb7絃PPR?m@vJP  lW쏟Q~R?@Wa2s{XV+AnRI+_̰,_jQ/?v_(oҤfϙk7g/9e_Tcb. 'b>n֭_|G?WZi%ݶۻ5o.zWS/wmag_7XQl馮G% /<14e-|:׵K?٬Y3acCujXxUW_V\yŜM8 x62 ={mmvO8<Ĺ8vevοi~}n?fk/f8lSMz闭ʹdR>ŊGa@6Գ'K!riԬ䯄6MlJ)/ie+QZjL?9fJKZJ鸑ԈeS?7 kf'x_w u^*QY}N}(SO?zZk]n9פinf͚^{?3aU3] /W/[Vw-l矹O?d?[~9˻3g}ҕ\ӲeK׶m[W7M2GZ\µi|I n=5͞==KX .y8]{.AnwˈDud#f6Bgj7iD7p mIlHooLx,ybz]??"c&vh믭vn?/2i?le/p?miϟS">9~WsY]Z Yi&ee*"oWLBNӒBA!kO0&-g_yzGӒBA!k_Ȁ@fcgrY>ݟj,|R9`'̿ ,3WID>UL$7᛺aje&n7/a<˄w(/FonVOO{0*Aو <穕TP Zo35i2o'/*گ^?z!jbS M>փhګ۳b M>M(Km5zkڤ{oTw̱G/ReVn؈QF.t{(~_qwK8> ǧ9t|s?/gkݶF^8a;i,w]cOroFԋGYk_IWhk7jHA]ﶱc]FݤIEg9kj_\폨kck_eko뿭fgٿfz&Xvf_^pHbylcr6y(mӿ?#O fs: )B_Pb i\| egJŰˉw &9LqB'(?)nOq7k돭?[a#&AZ?~lIS^k-/bki-Io۴iVZM俰%yrݒK,)8uimݧ~>#7yn%nʔ?LXoC&ptdw  !]ptGY}iOY pWo8>u?VyG[^}nCh0y"p@b_@*v\s }ƛ/ S\רqc7NH'?Foa^BH]%"~—SNxM7$Fȍ אOV-݉'zO|E?(߂]ޤIp|:5nM|s;y#>QlοE7of7?oМI?c2  9}7.Jkٿޚ2w_pr;d?laiD| /O=<{I.Sڰ܍}3d\hЕ\yIuddfW*<Jr2˔6(L7 LJBINr%Ց&d_T(T.Sڠ:2/l[WӱGn=Xoo$y:;ȥV Jk&<©'l/"6mvî/=#gj.ƍsᅦ3##L[~ݚm VO?/11ܿҋe_Wn-6wۯ5i⦾{٧?GZkuV\qERwU{/$[P&B *C]R!D +J ofgϞs}Z;gggfgX5svxթ!ꗿiNsbb4pnI#>YXl l_I%gF`/!7`ꠉ}1 I]]Q.K8UNXO}S_XuUZxh[nE$y!wy04)l]e5ӧH~;170uO{pǏP& 7 ޶tЯr|4w OO_˳Wmyg?S _/_!I'~"6>=Rɉ>q'>6|7ɓ _߿СCî{V_}ys_"S_{]kfx'=962M*#Q.M`7LzphS/Ho[Ud(cRN`,ʖZq D~ܫg}|uZZKgu:B&" |O6'+SF_UI*DԻD>hmηbxLsYD 2Ndwc(R,*zN0//Ho*-QfrIk1/犊1¼)Ho*-QfrI'4c۟+*2r$"DE'bpOuab.6R92s.ėY??()2N,a?~>|ΰu6|(3x޺o_z{|7Ι~;!Tn}6^4oQaw&S?s2Ɵo~cZ1 0 tʩ؜13#D}$~)a>Ne>'?Ͽi̪pơ]TSZHzoʪo}з_߆wǦ,\! aM7i.uǿ诙_A#:XÎa]D%-=~8sOroN 2w¹>?X()8B##[>t)aVdr ζ^{xR(xM?eYY'ñG]C[o#RvS Ƨ>QtPhroB0~iau׍OOhÏN=%̛7D\KJ+*_}Y=zmn{%c?LO*fp C)1YZqF_>xt#U7/vuSxcHq*_qZWNl!V*DGs^BT4$ J£b6RyFx9D h\ ,*g˟OAd$(=$ J|pa) JdRyFx)q[p(An1yYCt7N8 8Ah'Y(Gb Yy eI4M6Pzz_sG/L4f쯏j_Z7MvcnXC;6'x:s=c 85hgq  ΃p)8ڸ~#Xd!+P8!F'kNӥK[nL~jrJDz_ǟp"2܌ԜSb͵גӘ8y :uxR˭bXr Ą;fƘN1ExC{bdNx /<fMV^uU9G*c~b7!~Dʸi d8j9RdvvO=Yy"UW^5~5Xc<IEc1 @/N=骯Ρ?_ʫqG!<ȑG-,O*gِ-[j蟁'UqǦ0n| nf1N9q˯}r@yή0|pH6PN1li8k_ ^ <yi9F 8(;lvcO礸IOH'o%t`CL385^ '(l ?\MSԗ_y%<`bgX<^il}]GsSO;-l$cIhOlgf@\6 /nbMG}$k8jrX 2,NSb: 9tշ_0-={㵰2doǐ!{/0>rKj?QnGt::lMl7=,>tƚk?|>_YCK)vR{JQ)UT 'J,kOވq[;D4J)|b^Z?x'J=7b~V2 0B4joI1tT{2,>SO?=%^6>|;dЯ?t3/yO7OBr.n'Bc 2] 7uF'cgl4}ۄ=Cpz0&\|DN`?7}c]vimb!D/\4=1jQW, ha?,2nܵ{%%_z;ĦҦ*Qv olb8E[?O6X?8aB B}4s4-As5rW^>"9쐃 @e7V];~| !܄rQGVd3Cs>qjY{9 ['ƧG$?{/6<(N|SwDIxOl:b\ށyo_Nʟx#Raj m6 S&?<=!}kn9>ӉԩG|}XyRxG{'D6L߅-~װa?<#gQŗ\Bt 2 _&<,վq` rOpUWI>on)iIe'-sYRN?6p G lK-Lzp'MqfY5pzIӒ\%`MKcW\.믅*Wv*kP&|  LM6#1ԙGb&y%K%I"ϐ#FTpHE2MiwA!T7  "q7, AA|dv_qcчdE3$MECoto@ԭVA*>h[EU3NI_nE|Y,?>'] F9^i͒:%-KTBY_ѠWxfQ׮ŝ\l!&b;?PA˜e?>@0|}an,J~*ieUH˃U5޺eF KVZ$?'=F<,>O~_7^=0M_v{pP$^+8]T]`Q DnB Ԏ'Émo &O9Q*l M"B0߽L`CIoB'y{#? <=eJ8#J-pMOQa3}2AFM9묻<#!O|zG'_k D;{fAq.n`s$l J/J@ v< ' >HXu'K[=‹Ɔ~TNaFHopӍ7Iy_qŇNVe{} ӰR'܈SyӾf'tEv64*Ff?JbyiڨZ"}-ỗ_.w6>]7n6T)_ߖoȁ%޼tbS_'W2SQDb4+YY 2,7 ch!P3,JvfhD 9aVc4@-'Ř%Zh) ˶Ynn9),BCNfXr3pI1fr 5ò-dh[N1KАSma%;F 4rRYBͰl +1fᖓb-4je[XɎ,7 ch!P3,JvfhD 9aVc4@-'Ř%Zh) ˶Ynn9),BCNfXr3pI1fr 5ò-dh[N1KАSma%;F 4rRYBͰl +1fᖓb-4je[XɎ,7 ch!P3,JvfhD 9aVc4@-'Ř%Zh) ˶Ynn9),BCNfXr3pI1fr 5ò-dh[N1KАSma%;F 4rRYB}}T,YG*g{us~(_1+fi ˆ f'm(> D)Xu2dͰo~_F?sp OlI0`@l|_\?g# .2ҳAKHr_oÉOC|@ғqӭ]MaI=Bsυv( CZ?EW ](niV=PkF x-l XŦ_s6;ǍOlӌ^j[yf[|*a Úhwl>}FT/mq0NzĚ׏?<O|ڪ| `CZoύZmhy_|%Ys ;L6e'f 7c NzNƥF򧛻0wv'ʩ>t['zg=,\zYXnYzp 6<8? Uz{m$;U]Z||a͵ +`lǡ +BW_}eO~5=`p‰'!Ds-7pZ4GۢI2F1[lpAz;N{*sQ%?W_y5p~Kǿ~xw7Ho~oGOUVY5\paYd/?relƧ뱹ߞu믅 Va}~nwIN‰yŞ4?/L"^//eA[UO{?߽1xC_^>gKo_/|4nb_}U'O^r/t',/Lᴸb|UUWSx (\)JcڜjJOP-1bmN5' r54Fͩ`a "AQ#TSx W)JcڜjJOP-1bmN5' r54Fͩ`a "AQ#TSx W)JcڜjJOP-1bmN5' r54Fͩ`a "AQ#TSx W)JcڜjJOP-1bmN5' r54Fͩ`a "AQ#TSx W)JcڜjJOP-1bmN5' r54Fͩ`a "AQ#TSx W)JcڜjJOP-1bmN5' r54FsaSS_`p e5oiď*05zAGҊօ.ɷ$KRwma 7\f`x챇?{&WN:5T~;\?DJx?2#,I xnn :xa6J.ir&@f"ӧO=k%* <Z(L9=5\MPs's=7Zaa.zOIY3)՛`}뇇Oly*ҝ8Yg \yuCNy4q.O|"nob)F?S"uwYd܄6>lFG"ljOxHō>~>wwӍm'-ȑxJNjE:'6#7t$l|:'6WBh_nlм6/ _ftpS?=.lg [ˉO{'y?sƯ^)N>ZzeP?VxG^^z X? 40\3:gy: !n8n뭷AVM'<5pQ9^?zq!V)?χ?HLHD[Z&\=l|By'O|6>8f<=er8#K'7$9dtˆ+*>1iZ8aql3ʠ/_UʁxWpCK_|)%pP̃aq}Sb6Tc?>p>*t.D|Euw)yEDŽԨxAhf1+*,)Wp,!//VD$EbjjrH rs,%UpS`+j^qOX^0??Ie([Y8IaޙψM 3, â . gFBV{1! Λ?\"xžHߘ[!K$Ud7˟_YLŨ&nA9b7?VId? 8Nz'㎉RS+`cl9IBUn典_!tRr˭:(9MHɱή03DSKϹ:/暲eHl|NÕPލ~'>yc/Y=1G9{fMHxCp/أ7KJ+$tac/ͷ,ə68 ي'>5Ƈ4eS#qGia; j!9WguvXwz8h^ZνJ6>uЍOc/_a38dyWWN83yG>oRK3fgzl8o[oMm='&>o0<~Q)Sk.'-ӧޏ :,wu G" Hmaxe0շo?Hzs]0㬳\{G6mZWCB?tbUtl|4iR8a|< {W[6l6Ƨ&Gc;R=?&ު/9epݵb,~} oQxg_s57aֈxnƧIӍO@_6D3QNNQ\\G|_q^ś<*޿<>Wvdl'U]KŤ'¾Y~oK#쁯#h}=\֔Q,Jn>J@qL/VR-K.Og*0W?:CYHGYb>ZX.Gn}Lxk6#{7ۃq8q d,Rw `c"xIa9.u\ͺI7K,ԧRf<6+իΆmYw>??na|Q:0a> $'mo06~'ӣ|(vI.xz6[~ ơ6^qv Bn&*g[XsuL1JN|⳶NUkYl|-gpѲ.-4tsoԨa (7BCoUW c^zd9(t갅f\XllvƧ[m@IDATQ¶a#ðyӢ]wl|L6Bnu}#Ƨɝ?׎ZB2r7= =6>ŭZk%}B_ kM?qsC10k_[ԇn!"&>Ͽ|O,_Йd&>n[mN?ӫ6hZ'dTRB(eHubit-L@);EPF3LkaB5PJ)2ra] !2PN ZP !%Rv$\'fF„j) S$e:14&TCH e" (#׉ѵ0BJ(I@N0 RB(eHubit-L@);EPF3LkaB5PJ)2ra] !2PN ZP !%Rv$\'fF„j) S$e:14&TCH e" (#׉ѵ0BJ(I@N0 RB(eHubit-L@);EPF3LkaB5PJ)2ra] !2PN ZP !%Rv$\'fF„j) S$e:14&TCH e" (#׉ѵ< RtS~x*T XҨ,j/O]n!42TS4?OVXAO7+o ?g&Z\(H;HG;-aַbhԆii=qd+"k4Qz7`H_@2ySᘣL .!I9};:K/:(Hv!}?,掇ڟo{^Xk͵p:cge}]Ivf'@sЯ}]|y6~au?r]v__?<<ߧ6mv8gwi%_~D5nvuT[f9rT~JG3SGl)9xZ6>Q.t:qNj7J9>pw#u|daatDEm vcC|>18atW-?.,>tHka}Fd8a-6B|nGȻj?‡э]?+\}u_3zlO&N|(|=‹/I^yWpͰ;}iRsܱ5o<݇O/y:dhqRq^/2K/OKG:ҳ` fiki{z;U]oVvA{p7|Qw}o3oV#ɦkX8).Ƶ-?hKr_3wri67%.Rnz?2%=蜕Q"EjMPvd_pcb2 p?p?GqJ[ŌRZUe*P%n2?jPD+Ҝ>F|y^=b \Zd-f\\\jaj۟F#XF*uf ~$U,ri1UNiK_Åbw;B ] NYmɎ*"/,#̙'U|a/>0{l-:J?vwO9 ?$ 2迈(( $ʿofȿ=OP>g]L:m5^{uɦE]'UMØ#,owzo_gR/C>HyX#L7 N;3Mi]c/8O]sdod{)Ȟի@7do0%- ƥэO?7>]HU?n\c͵$o}3xL5ϡv%&;[e4Giehl|ZegaoD?YrfFt+ԋe_r@DÛ?na6_>o/+XnKz-$Jv60e\߿'N0\$ҔהQ(o;}˟%8ȅzǵ_aY՜])B" gbE 0K+cȠ9`Ѵt13a9O L)ɠCL 1Ӑfx L1?G&s˭F씔%0q۳=l8>K3QN,Cvj׺Q4{F3X2r:W>T6>pCnL aSO`_}ww/m]x?N}SΐYnm 3g{'?]E*'k}g)]̵~{fQFYZH'HR9}$X*TǟLU;t? ª.4܁`򲎉b _c57ytWy]7?uis=? 771I[{;NP8(l|qp/c#O<M>_)/-~Y{igxa8%q  .87x꫅sϿ@eƴacG†%|rwUW P`cH|nm^xvϜ9;N|UV_4y:NNy'Cܹ7 7^Oil|:'>Of?τ:XKOaǝn{*Wl|~;ia^|F@#Q_N?s:a6qSqHG>QAguߧ~?s()ϴko:AkS~.G묳Ny.}Qπ3>6"];r 74!yف'MI%ȿkÝ'z{dvwIPsgϒ]wX8f0tťcJƟ+>WӟXV'+N>bQ>Ӎ8w}НfՔO>_;w/edodopWk>֍O]*m /nGqv1[pϼ0C'=>v /yuw7e/xM1sRv%RŖxyRWCTs{)JU%^pEMin8[RN<) ܞq W%:˓rA3:ܒxI9\p pUnI.8ic*$^yyR4Hs{1\[ü<) N=-a^' ܞq a7Ƃ7~{oP q~LC$& ݛgBRRK;z_fA{+̘>C ;:×N:E?+~˻Qt+QG98"\"'wUto`|G+o@?=b]_iEh,g/j`.)`[!de*RLh2;] ͻ'rraS?s)CU;s[n[Jq71sg w"N2gy6/ս ~;Z{`pr͸B;Nm=Pk'%~8ldF'6p/Nxd|. /p4 ^rIXi(wЄX0~?Jq#g Z$3aȊ+(4N_ݡ+bRܢB߾}C< 27źkCV^")Tz3PE㎕(dr :$\qUظ!ؤop_}rі#0yT?;:HgO!x- %҂2s_IY瞋u()ヤKoa=ԓNI, 70r)mMv gϞ$u'lza/7M]SS=3|yXC:ȑ;COP ? pեhl$i?D94FXq.{'E^h_i0bGEZ=YOyp4NFqVzRjyzq}~V&N9'4NGK;J T=gQ_? Yx2,?|F~.?ڹO<^7ʿTZUHLz ']'zUS">~o_N%#E)_ɥ/>ߞ}wᎿ\6/0g!L:Rhi w_cvB_|0/cn*!.%}_?8{EthRV(c2==VYU%Čl%=+a`FN98]\ѪOv# 1եsp ㏏?>㏞,`ǁq@*W[?˰8_9}0ʿ0?x >Ƅjoi^GDĤV#/&ͯLȳova!uU2dpFaUW /bSOyjpkp*ѬYl~ P4'Km BC >lxlcZ +A?GL߷/m2KqĉfVd`8fUW&cCѓO>1^w]яe]&'d뭷ݣO!WV} Ǧo?Ιןz :8M̆~zlzc4i!"bk?M7!Z8DlҚөDc_feoR&N 3IM믷^X ː_aӄ9srw؋*8QTi8:MB^m $o~cw/79̫'g0N'-15~?D2q? R/W 2.L% vLrs7q㏏䃣_q-xnOK͡Cw]ER^5Taiw'ri,2)lq {*4ϸ^p"ej5Ҵjj5Ҵjj5Ҵjj5Ҵjj5Ҵjj5Ҵjj5Ҵjj5Ҵjj5Ҵjj5Ҵjj5Ҵjj5Ҵjj5Ҵjj5Ҵjj5Ҵj 1T7^K!*11b߻:tqV _mE/kPe俽#tu\\k I5Z>oDKz vwy\yz-0 CS\9 <Ŋ5mtwwE7ez'gרk@(ڪsvB~ʜ=*J߃v#-Үi>OP#rwAY|}bONÄH׾Z?nm Ҋ!}\?mPOt=`jPǩ?3c9n,j~3,,WXכ_vD/mk/Ur jvy`XvW?}{6ZXNoN@{p"NZXoǩe z-xQ<c?68|? [G%ȳVƿ6zݠ٪M W]}47A_}dN3>~˟d+L <6KY+ѧ_+38![s倲RDv-> mbʟfopi?O/A,jfҔK[_yΰg;N*O?77Gۂ_:ݏlgo~1 yR>? oU~ookJ4(VCǺIj-hʿ orܵ MB,DrS6OQXt˄_>ϿUZ}Sҩ2?l|/we*xڹ%P K6NB6h? f׏ }_{Q_9QR͵ǏS_8"II7Iy5CaAoI[뷢}na;,ms['vB_'{}_wغ3Ѳ, -=Q%͠rư;':E',aC#K,Ƈo)if-{o sh Ϗe,JSǿ|of㞅1k)mOiwτo::Sڕ9 ޠ"Wr4Ee\O, ;c^b Q:hz AZY2G_DMYc_XmJ_ tO| I_OT8''Tr_gga2ߜYB;&$C\q- Gmi)pe wo?g\/ok['2aչ-€b3ʻݾT?yo/gCρ7Fg+7{>7T\-?6Թ/6ݙ\-ҷb.7́CF^7_湹mlyd>{_ nh$AxdW8lpg *?1|[JYfyUֿ(lQYo?X߻bOC=d^xpᇅ.|_bw-+yaFo~ٔcA(~ЛdhSg;8GєfyM7eImu?e~-oe'Ѱ7ߪg_}boɆ7/1' D[P sp.K\ <8̘>V1?w#~V &t3Te*xAa5_smPPfb_jT@OT+F{Ǔyـߠ!iӥ+ˋ>jvυ_7\hcG `٤d4$S976$'k?7LjвV?=K*OMy*gZ?7+?{MKlá]\lXأgΛ+3ƟVEM_nٰ:ÚcVv-6-vco?#<ؿ8/s)ZM]8 I~(k!ifJdn&gs^īUIbo}vİa6PO胷 W:.ͳZߐASM&nmW9Ж_p5>CV k̙ԱmrKCdaWpxV#i:[׌k~VOU\L{K;ҪupC"gԘ:xʼn#Gy"g\pHvrssy,?,eE.rWq@ &hU-1 #vƍsEG8KH 2Ah$ߐbX\=`HCİ^7n1,cn4$D 1>l8N|XؠNQDoݹ@gbo[o- Scw5ЛJ>=QKEb׼AҒ edI!_n]l?b'} eOH_=FӊC#z# 6/+jJroEX: Dbx0,K:AB* U=̤1,""'iiȢi0w"J0%i 8bL>H|,,j+*dg _Um4!ۿ\,? mK) q4dg O\DS-}%~8#!c$?.q gT8)qwkR7()f0?b%86g WݡR^` Q,)폏WuUqNJLeA?6ꍸ/?d. 9~_> gz_|?|TyZرḫZ9"vG>r&> ;i|j|ZxџEթ/,x$?ģ۸fWT^:)E^P_7@˔ZUzx¬ͨMI$wt,z$W 66%!\\\\ AU#R'ڌڔ\@r`҉OݎS^1ScpN°lY ;qBpƷ"T_]UKuL~QOF- YDd? R%tsP/?=0|r>Ͽ :O_@JϿ}o|rW4~`Rx%YϿ|ek:>Ͽ}m6?r%b(m]]]if%X)VtLbY-*!oLr-q?$)%DyfJ2o.n㯊0DG8k 7tA9Qf\ڰӉ??~|jB栈,J7y|%X&2WeIGUa\MqSQz>6Rq@+G>L$ ChLϿ|o#>{tAֵ't(?=O>iPOL0`#_|b@JoodޕP*'e 4^VYE,z@¬rR weaVK9)e`;020ChuYRNb,j)'e {Z]fXf. ZIY,3ށVY-,z@¬rR weaVK9)e`;020ChuYRNb,j)'e {Z]fXf. ZIY,3ށVY-,z@¬rR weaVK9)e`;020ChuYRNb,j)'e {Z]fXf cru,Y7s S(nLΖ0>g;1o'bO?9S6>g\cr$ɑ,3 ><)Ƭ"7#:u>8 |ɘ8&sg*.Ie&0dЈ2)^sI#~)N?ʁ:ܩ_2$0` +m|o<*_B]%}NQq 5 mXӗڱ2֍K3I"n$crŃQr޻FK{DȿdA6~?L /ps_ȇ?rg 㟏j-u_u|3GI傮s!EČ֮Q?.ʌ?ݦeV}u>u?~}:;ww$ 3'5%4 g9~1rذ-wǀ#;3B61r0G*%O[hִ61r0u㏏@} {cI(m i 楥ڂ2L5eT-#cZZ>YD~)hM^n)QIqsK_?ԏArD4?}}>oϿ}6&hn_0NpЫW}-w\3W<þ ׿B{#==5G?C__5 _,c7~؜bSRJ7`6)IX?))-fTwE͐ iI1))V0g5C%6b'$RJpgQ?'?,c-j<#Oxo( ᆯTmaX럾뿾_|oQF}dJO~ol|[Xsb4h 0PB2[j*+%ԀVE@ W8]\. Ѓ1u0q㏏7Cw3!)ޅ _cLh3MWZ!1KJ P$t+I)E]@y /vbZLu?NHʟ(syW,wwpXn}_hupe-ΣhN矜U >_1~돾Ͼ=&E_zW[wIJ /(qq'Enq2B'*]Y"TR> [3-ja_S #SFjU1[;,t[TjOɪ}3]IFs-ja񷆟n)Y 9h]P9sV[7 % oŬ}2r1H?:Mq%T׿-?< #bD%Ò7I3zLSkjn ~_?>Oy՘ȉOď*syyZXWIDȓd3 ; k* 8 <ØP{Ĵ_ ߋO=}wɔ??bs+o+ȧ_-X{b}+}wA_6>A3UdhB蒬x.3Ԉo6ZYr\ ( o AuXbn^w;j`=Qvkܙ;Ԁ0 qwV8SO~oʿYvT,\,,jfO*Y>r1 $CJ@Fh:{.5ؒʅKOAG|O_r[݉)r sw?9}#~o?X'L&bXPGip3X0:gS럋}`lٸ[_լRoCܽUag _G_G :Vs|`0}O?ewkvS4pb3wT-\̈́lGQJ<-Ej+vAQtOnjgM-Ej du7` X1j^ŀ,n7;eŷIa,Pf8Oz%E Q(O-ҏ?e ! u1Lq?GkF`A۰ ݪ|iKnO%8gAX9QOWw~#͛?Px3W)]ob՟?{oP`^bj)ʧ:ӻNjOx't`_lCnw{+n4uyn S7\zzfW"_gU?*((9W~};^h55n>W af[H}?(R~ƆA`ah0T p<lAwgp%c`A` #y p<l򿰃ϝ}dp4vS8Mv}~7H,>wv-)10A6} k,#Nkr[?ވ A{c8tI'ipFGy]m? f柚Gx%T ,֟)n[;>au0H}uY??i?͎{pZ@`f/0 C<XQ6@/W+)#Yb{۝q8Sʝ( +i_jӾZHLޞ3#^HitpSܔ5gD_LkV0]fMS*ZPq{_|B?/q5Bf'o K/ oOBn_o8UϳS?_t?Ȍ7h_|>;Bn&8iE`Fs),>CĜR0˖1/-$??^~#'k|8=)3e~Z?Lx}1 ǿr_MߺM76xz]=?/'J,_>|I[i`2jqW29P@hkg) q6S)"(<+}]?|?l*² N C `8MEZWWW8\ᑛz>`bg'x?Q./>aŔ6zI/sFF?|ʺditaDgcd+nJFFpʺditaDgcd+nJFFpʺditaDgcd+nJFFpʺditaDgcd+nJFFpʺditaDgcd+nJFFpʺditaDgcd+nJFFpʺditaDgcd+nJFFpʺditaDgcd+nJFFpʺditaDgcd+nJFFpʺditaDgcd+nJFFpʺditaDgcd+nJFFpʺb/l_|7ZDM DxQ5%C8_#q8>=ށ-ns9\䜠 w?yY!&[ͭ`.M<ܴ=tŧ_|&6p3x$i g.ZB}+n!k_gٻHH=}F6WW[?ӊ#9Z@巴hf?j56G$?@EKl.rN U\c)2}fb:O D 19K5Eq0q5ԝ?/Vֿ,>"Z?5x> n})*rWA6Dg7?S{Q+ԋĦe_/23Hܐ}I)) y l Hc Eإ-#E-h@MG|'=j\'b4k|훆sTKy8SO}f5N_7^?Ǧo>rtol>9a ;['`NECqC!3N6z$%Iwt o>}5>7mZS 0Gj;?4_FN+(i/>|6yCB7r g:o4u9녳g[ ?\eLf.8:GM5%PQe]UUUQp:_CBd}!h<L[/ "h6qChc7}sڳ؛~LxfߴgZ:?>~'?=k ݝ}g)jg Y`BR+)#k?ȧߍW/#33Y2T)*=Q2fn6b+?(_՟/̷?K/p5_~wR$p_'Zg0cmiT.Sl[݌nTڻ LܘOXT(ƈ " (jr\RB1FdQȨ@Q*1"BFTPE2*/P丄Jb .Qy&%,U*cDq 59.aR#2(dT^q K A\D!EMKXT(ƈ " (jr\RB1FdQȨ@Q*1"BFTPE2*/P丄Jb .Qy&%,U*cDq 59.aR#2(dT^q K A\D!EMKXT(ƈ " (jr\RB1FdQȨ@Q*1"BFTPE2*/P丄Jb .Qy&%,U*cDq 59.aR#2(dT^q _|ڳ}6Mdx!jVT΍ M K- dl&FK?NeK/[4ӟ~o~w^ܳ_ytOW ? _<avvrc{%wn{Ǘ7@nzb?]V?(_?N PT۩PC(CEoxNP9ޝ'>dnF?LϔSUǂÜD?6nAl޿WU]ϸtINpu6.?`$<܂<WNGe_oΡkQQRH$ * U}Og#Ͷޔ&PQ1PiQQRPP[?K,W|>?xiAUgi#ڵs9f;ϕBk{Wl8-?)RaYE@*ؐkӣJd_~ƌh_DpŁfW> <"exӅ=E_>0, &6{gt%7N[oʣ0]~7W|sz~Ƅ_23eNۥ^G̬Ɵ=`1֚Bk7]U*d21aPQDR"OT{n䅁Q=x<__kT=o=zx1j rdG>ٵ/m=߿?oQO=+?uᾯ/ OJ5Z\ɿ7gݝȿ5OgÄ_0?.\gsUةwzz=%\AgT2}3+)_ }b>j $'oz>%/,+Eal:ӆ+1$#u|?n|'>Os3I_<{?iKO7N7ݘ&g7騃E ?>h;ܩacր)FUɚ?i7د6XK_)3*vrW?$տLٳW_?h)?7?*?5C6GFS:ɾW }=w~5@O= h_>bRO$ن~JE[3|}xx`>Vm1L܅.fF\酃{Vo4uQsmY=D,uK6mY=Kn)|M۱FbR($uJY)0mc,C/BB]e3߼űF/BB]f _Yҳz vR)[kd9JR($uJcgSoL|ί׍w?xehPbCZ:_,?O>|П__jO}Ϧqo^/=rt 4C_L5;Mk.}L (8p1p8 2:/_mdsy嵸"] 'H}?ΡSA  P {ToV?_ ":*F{F[/0\]W꿝_qvq2GaƇeqHş/>E?C^r;$[%x+Cy`/xn pY5{ٿ|-kMB {{'>q7/~ƍknKӳ/>v:~d/-lu~nxO_OOOLe?Qg3%du/[7}'.).*~/л z9jC@,nh#\ե-t섦8mYڰ3~;QCǒJg0Oc@J!C?d)yաg0???/>Yn-?˩>P[ƯK FXG"qF18<ܗ4Ǧ+>6`я~hgV{wzg=ekxy?\-O0+^/>=/+/wK1֌?Ct$?Nҟ~v #O7m|`?foƀmxOǗY u'}?=``=z>_s8n{\O^>G_? 3$-PjKZGV7q= ;?{/RT}9 3 ]'בˡuymϖoPc ]5>{d w? IޗIENDB`starlette-0.50.0/docs/img/gh-actions-fail.png000066400000000000000000012441161510142272400207710ustar00rootroot00000000000000PNG  IHDRZ miCCPICC ProfileHWXS[BzDj)!ҋ`#$cBP (;veQ}Pyu_ϙ3)w&4?p%H kq$/Ne[ zK=dxJܜJ~葡9hI %#aDhx g>y|'<%:'?D9t@0U-2n 9=`Cf\7θgOeVT2iȮdl@"RQsEQ료5s졙>ޣ~b Պ*vULE!c|4Rr3GѦQ)I\J%rrV]]RG=^]>GR}9:TG*:*.nަh Z:VK;I{@Aph5fkTk4h\xIִdiN,ҬܯyI[ejҪ:uSW=R;V;_{uH:::|:uNkt: D4a="}gG|utszwȑ#GqstU]svor!Xq˓9sg/o/WWwZL]fs1'ga^|s|(-[s7w026tZrkY=c9rX;Y]߳}3CҐPЪaaaua=ÏG""GrxZNOwSQԨĨGю+Gߋ4ƂXNqvq&Lp681qG⻤थIw-))RjSާH3b1ӌDiMcCǮ9s\ɸO~ G&jNNܟAHؑ˭fr2fؼռ ~9K/X!x埵"y.aB-bDs"r6ύݖ۟;_-?#XG+>5lI'IcU{Qҭ2D6^T ?[  ?LITiM{VVt|:oz sg<ɚi2+sVlgw }.enߊ]W5/u^|s?)i~ 6,-r_fR~2ײϋy/<ʟd-i[t22o_h㕣W63KZ5q );*+XYszup&k}L7mQ֦M 55 7?ݒ/_jo-ex[jkkwXZvyyWȮzMw{{^{c_Ծ@i0Qє~0`K_C.8\}Dң+:{\rD-[sکSmN;vYc>{Ƌ^Z=[ہ6Kޗ.\nn~JWCƹvz7nwy_)ww=½Z+<^GwJ{ZYs燻º.e_w}e?lZFoWKo\wޗ~0#OML\Kר%\)wS6hiaFQ' z nng l &Uh$}hD>-H+f,=Bg%3?Q("?JEQweXIfMM*>F(iNxASCIIScreenshotti pHYs%%IR$iTXtXML:com.adobe.xmp 478 1706 Screenshot iDOT(e yo5yo^/e5u#&.\eʯr"EN[2NFKMcLatr 7V-3$$Lv2G;jՆWEο?Y}UWD_ yYF^..) 7y5F^BȥGvYk#%?:645d`3ˉlyo^}U)_)RRJm͍fDKh>Q%cMA#jW$vIn Z[$(Ca@n?Lބ%4(w?_?)86xd K)A6-yTpr τ%  ܖ N[1aےRi7<02l0p[sY*8m9gTP nKz?K-pLX˜ ʰmIg KSA6-9,3a c*(%=ǟӖ<*~8m!U$'3A<rpo\qC _H&gZK;0{#kvq!R:AYjO*2uWP7<'o^5EIC E=C/|?ԅz z b)w>;?AkB7||A %K)/[Z->(6wv_\|o.)^pצy/ɊIeIe\y ibBu3a5Eg]'Yο?Y_*y_y)w~:Gx"K~D7 |Bv[~\oW._Z:rE9xv 82L*X J7mVnN]V,_rh9E ZeP!ȑ0)e8Di[nr$.LJ&= lD*e8 RCOoi!HJ&= G¤i[nFRCOoi!ȑ0)e8Di[nr$.LJ&= lD*e8 RCOoi!HJ&= G¤i[nFRCOoi!ȑ0)e8Di[nr$.LJ&= lD*e8 RCOoi!HJ&= G¤i[nFRCOoi!ȑ0)e8Di[nr$.LJ&= lD*e8 RCOoi!HJ&= G¤i[nFRCOoi!ȑ0)e8Di[nr$.LJ&= lD*e8 RCOoi!HJ&= G¤i[nFRCOoi!ȑ0)e8Di[nr$.LJ&= lD*e8 RCOoi!HJ&= G¤i[nFRCOoi!ȑ0)e8Di[nr$.LJ&= lD*eHd˞{ʎ{wm;vJd}_uTYy[kk;:]nFXqoks}fB@{JZZUhmx/޼Ls4X%y3~ҵZ6Gc!MO_7h|ilDƒB^l*G+*EԢU}mo^5#xB Y2 R9޼Ls4X'?6he@Z+FEns.Xkꨕ#q?}P5;Ǧ]n'; GQVX.y l*/ `$u:q2{re[t;"_y_y%ϼb @> 9&?3?i.Wuiֲn]1 .+[zDU̙b ^:]{57UrG#W.cHGOWm8q! "nS D&B3Dܦ Lą4*f M1# iTApb G40Ҩ !6@$h`".QA0CmHD\H`$x=ܳgZf;?5Ȥ s#]t9d$.?FD7UH s-%0Ѣc 75\)rK쬚]߬Y'MTJ'?ygĸpVc;AZ?YdLFT?qr<絜9re ( gu:42೑7o߬R|apUNv<絬?Yd (Y8&e ײf詿)W_w3UyeͩT…n3t۠'qpֲ~&AzرZC(F&`@s\S؂jDo;;RW%o#&[&;;\LT#zF09FןR-jś<61r?JE6Z57ylꝝcmj o;;9(9hT( wvsQ*r"6Pc#P#TkEPSmxF09FGF@&`@sR㯍AMMzg9"_-jś<61#fݲβirQ+1+A6>B7tClQn+ﹷtܪrزC]3uVAF>K|,?dH 91,Lӭ{km"'je`z\6l65_?DFA~3 >Hm5s3Ġ?aOٙ6/矛! Cx4 iOο9 1hOSvM6xrfA~3 >Hm5/_?7C iAjӨ 9u?Ѓ738nYZzp%=Ƶ:ԓ… h ZМŰx\6qvFw(2z?O#GiIZFn:UgU/_Zar'?yoW7 ym0pd|?G-8?_493?FBڵ\}eA˙=U}vא?=Ɨ_uc7oQwt=$=nQl{3t~oM!7CWքXjkQl{3t~oM!7CWքXjkQl{3t~oM!7CWքXjkQl{3t~oM!7CWքXjkQl{3t~oM!7CWքXjkQl{3t~oM!7CWքXjkQl{3t~oM!7CWքXjkQl{3t~oM!7CWքXjkQl{3t~oM!7CWքXjkQl{3t~oM!7CWքXjkQl{3t~oM!7CWքXjkQl{3t~oM!7CWքXjkQl{3t~oM!7CWքXjkQl{3t~oM!7CWքXjkQl{3t~oM!7CWքXjkQl{3t~oM!7CWքXjkQl{3t~oM!7CWքXjkQl{3t~oM!7CWքXjkQl{3t~oM!7CWքXjkQl{3t~oM!7CWքXjkQl{3t~oM!7CWքXjkQl{3t~oM!7CWքXjkQl{3t~oM!7CWքXjkQl{3t~oM!7CWքXjkQl{3t~oM!7CWքXjkQl{3t~oM!7CW9S.F 7dk3*k8$N]!/ KA90mDU_;W|?GEsaɓ9R'OtswË.=?7*t{Kɐ|'y_kC18+6"?~7%Cy^FƜFh݈u*a;)> zIxaBQޚE֮7d3nY~ d%.6n:0xC?c>%9H*\>lt`@?Yh!a'o߬qyT|X yO^K5~ߪGGUe0_ V8#P!{u5˟`*NWyaR ]C Uhܕ%f{=57llg:ywkHU"5& Pu R3~w̿!_'@P~vmA"CM {rirq 57llg:yy $2Ԥz߰A-ǟ!_'@P~vmA"CM {rirq 57llg:yy $2Ԥz߰A-ǟ!_'@P~vU[hr*opQ m6 pa2 ?į*ΐ-ު:lCY]NuT(F?) '0VHDg3eT(r!=l^GfM $UQ* YdC`E>Xe.$B?I2^Ȁ%c "҃?O_ 65 `TGu"҃f?^}=´P%?,{ h }]}#gʹ]r Na|!ۤ@X"C| )2zS1#! 3p;C90]Lb@Ákȹgv9r&~o*dfce< Yf-nLrLgI<3dg23% ΐ'O֟f$@?QUI3BUWыj{wMl^Cb39rS3YT0O߼?}uC RO|9(>5EeZ\^d EŁd_DzݨCb?y?"ߦG?ʅOdQ:W?Y.ϔלe?H U2XB'4(E*w|Bjq'3ԟՈUz*w?/*2(R8dLRdIW@:C'2̻*y_: ]"o;DuJw U$;;←G)Z!]u#_=*SP%W@49Ui ҵ&9s MNs%栣 /HK49AGD_hr>7 ]/4}n}A^i: tDtAz&9s MNs%栣 /HK49AGD_hr>7 ]/4}n}A^i: tDtAz&9s MNs%栣 /HK49AGD_hr>7 ]/4}n}A^i: tDtAz&9s MNs%栣 /HK49AGD_hr>7 ]/4}n}A^i: tDtAz&9s MNs%栣 /HK49AGD_hr>7 ]/4}n}A^i: tDtAz&9s MNs%栣 /HK49AGD_hr>7 ]/4}n}A^i: tDtAz&9s MNs%栣 /HK49AG_׍qέQ5\1kc m(#G3b*Z;̓w@3`,G7b؝Ӡ__̿E?F3@i@Rۈanzf5#v4h _4ڌ0'ufYBNogKkM _ο;~,iL~In}9?QE3O'گšxF@]s#u]ߵZ1i+  } Z9|A 2di76w5W.c"fWox C߬GyPs@yo^Q7* 9^0Ȑן`'?yUL@yy놟1~ǘBf'7ǥ\O95v\}ljPNز/*qa k;p4-Bf|ʋw99ϗ6Z3t@]9| U`5.?/;0T'@: SZ`>eWn0_ :Bfd1OYfs(%PP`!*d_JL_^zՍGv'\"SL&L+]v>u6Nh[ދmMo=;A,oӯOϙ;C6ʈÛ2eϙ6fK f)'_.fdAqm5֬`$1ޔ7o߬\3}]@ :CJ38)O֟?Y`9uNfbqxS֟?Ypuur *6𦇢OFU=Q'-^u7[/TMyϫ4Zc_Θ,dGVH)/-({\ cV]g:GcEC9$#)I}߬Yjݠّןт ǵ)&Yf&8'Ko(qM݈ }yo^czK?ƯKB_5S27[ڀr.Rq O/kOU 3oLH|̻vTR6!3'mh0/KU"+;<_'dB+[ݭ[lٺM5O*3; bwƧy!Ifߒ؁ӠtDRn -O1=BKSAPs/?͊{?cXQk~9r'y .cWh My lI@q[SAv1pG&M69cjJP nKzK-pLX˜ ʰmIBoOTQnVUw)%e)*=IJpBpL! ]L aoĭMR0O8)gsarbBrc޲d @Ft1㇎1?Ӑ?>+:d'O2*x?t?~!QY|Vt 71-O֟0 dTNGK3~CIYLCAnXc[֟?aȨ:f1DeY!ܰƘ?Y0Q;-uc %ei3khNf5}*)IdqffVhNoߤBTEŴHu 7nkh|k ;N#$$ԈP(Z07~Ph o̓ԇDU7 s#V:jtt> 6&̍ڳ[__0PjzHLa?(g2dRCbA=+< c$ F Y-ǟ!ǟ #a07~Ph o949d0 ĄB{Vxy'AH(5=$&̍ڳ[?÷ߨ!{5/M FIETǯΤEE{jl{,euߵƷ1m^ĵD9c4%'>15ӱϠ9re6O֟y+dLk*Yx kYd#5WQtl3h eg#o߬Y&*Yx kYd#5WQϥWHg_rT OTm{['{TYyزpS$ΰ*=[{2eWv|}$}ZnVu|Lb)y`JD[RUmC:ӖקX ` 4 {#Й(ꝝZlG{ǭ' llAM57ylꝝc:[PSMzg9S*t쒼$ϛ[$ϛ[$ϛ,W_ҏ5 ΟG7iA9ߞ&Gf&Wd[p@6Iqj"A'j@{| /,u9kcy,0,gSA la$"_֟?~MY3e3-re O֟?Y\4h ASvvM6xrfA~3 >Hm5/_?7C iAjӨ 9rbЀ0L)]sTk7ݢ/ijmXOGN8Xe;J NR3qQ s쭁^S\q%>Oí!i *b|G_[HAPтmS,o>|5uj22҂)vR_N?2.kBa-c˼&*$'O֟?Y߼ 7 &cX #?#?̥ʇ<{Y:Z*-wLU^q*GN%wuvcV,,Oattzټco/m~ۗUw<9vR1<jG?nz;Sx} UoTųz* Y'i!zOXuDYqv>Y] z3t~,R[v y0oE]W\.='/QM[%G3R]jwLeؓgb՛cڷnȜ}jU=:b ZԆ<[plb ][`Emȳ&U5!ZԆ<[plb ][`Emȳ&{)eѻ+zak}FKPV7CWքXjC}3@.ęt$j}#^ v" ]Ow֢6٣*#N2-jC;hŒXς(<[plb ][`Emȳ&U5!ZԆ<[plb ][`Emȳ&U~ߞ[o){キ,\,?  QlQEmȳ&U5!ZԆ<[plb ][`Emȳ&U5!ZԆ<[plb ][`Emȳ&U5!ZԆ<[plb ][`Emȳ&U5!ZԆ<[plb ][`Emȳ&U5!ZԆ<[plb ][`Emȳ&U5!ZԆ<[plb ][`Emȳ&U5!ZԆ<[plb ][`Emȳ&U5!ZԆ<[plb ][`Emȳ&U5!ZԆ<[plb ][`Emȳ&U5!ZԆ<[plb ][`Emȳ&U5!ZԆ<[plb ][`Emȳ&U5!ZԆ<[plb ][`Emȳ&U5!ZԆ<[plb ][` QCUN?gM˶&z?'/Y =oݶ<W/ʒ nݱE89iy5'}}N?ɲ |b+7O/mֿerԓ/_Yt5Rbù!Cմ9H,9}zwϕW_mq~wYvΙtrBw>}^k [l#}XпRkC~8c[?g<.7տ8l7/W˼y0<ה6)ZX>2~dCӏnJgU/ϖ{˓*-σ3ˡsZz5r2^#/cG=\?rٍ;hjaWn~'-=x; L߿׺v}KNxsc_r~ϊ*NKOZxsUU2 [ko߬b ԁ KZH˝ Ԭ;z9x}Z(#cm= 6V/)\Hݸ& Q'|%-!QY/} _a]|PPś";N8Xi?r_v|Zz篔fw=Z<k ݷp ? ˇϥ#y.*WpCNӵp?x7._|3ʮ͛y[QOy2%THv9rhv73;6> |ˎ}+~~nͥLmp`wG kr?Q*k'>o8V¸Dž>xC_^ŠGGk@z߼ U)*ݦ}ǴPş~ჸ\zwr,v _nɷE۝EϠo8Pu=Qu‘D՛8gz@O8V;?QE7Lc(Ex2ţ'hts66'>z*=h\v>U*u޿mV*Yh)cɪ5K筽wh< Hez߰A$m~h(y_N LuUZg|ֹe.!"z=OB]FQ??߫Zx9h|TIA)n۳esV?SK8:i om'=YΟr߼%>Ή@{{9@y{Z@*[ho\;@y#뇑ϡ!@ٞxˢ+ T' U=o?Xvm:Eַ#iʢ<\t ^ y{0_GJ_suoV/t=O}5.Rݾj!НA }CT߷>޸w7-O@)W63Te598DT63TT^D>\t8=Q^K:`8݇*_|-TU9PuSba ècQXZE!΅.TAoa2 }>, 85Fu}w|SM;Zln* Xe#}!_ 2gy4B50VCٻʍtp\5| }ea,[vN{[nk}-,ozvъD7k@_^odi_3<7qc0Xe(K1_ο?Yr QF$ Yd&KW}T(FזvW-. Uq!鉪?>q[֖U+޸eOYy}mAеyϮQ,5Mw:ህeB)!]wέ{ ^[r0/:)E꿣oT=_L6(>XY#~bM ~r'L/.?tm9NwzJ:}֍ie`_9bOR^@ U~sw޽.$)%B^<ҫ55ha@U*MBOV|f}f躵R<3S$|Tth#$N0O%iDXtιe-PLSOuqm.V$ X!}\k>H jX2(}ގ{%k֔<߾R6_蘔Y慑{˲NP[1>/T}>#^?*I] o7=o'̿|rngx?;-Q'捌PkͶb U- 3p;CLuWixngx =M _s{gt.|-!o@!{: >I_ +7% 9.!9vv᜵Br7%vd4ukȹgv<~ؼs3e3,GkDg'dmq3eg:K!#<~vZ8]x*N*If'L_G 1ٯZʷVWk{]_?]=~[US_OTz*.T!Cw;li/8}-pAK&] me:*jv - 1ڭ UoTp}sI*>C~xi翿ʖ{w{%^{s\9[7(;^rRD me#|./e>g~ W?/)'~B,igy1}ύKYL3( s}Mオ%=rn{RZ|ӏ,/~QMц]*OTXuF=72@U+_Bmf5;L163̧җBoC=~PW1R}U5քH|I+4+_&zj?lZ|wh1@Ё,[?,E*\c׽̜\zB {~9SEuoN{,A_9ϣ\D}OGܴYj(? OT=)Dds3(:9ɓ:;CkO"?r9-Tq!%PiU\}Sj0MavCC3/*w_y_,=O׍~/o^sZ9Wۮ+{E>,>|)5Kjz2Iϒ_wѴP[8";~D*ôQoe~26?OP$?M ӿrѿn hݯX]_MU~-壴@6u|\n\߯/{Q~#ǿGP[(m rΔ<:NĿ{ˏ3S/SُYLye㖽'z=g쩇x)ҫh5y/vB'fyV6oV*P"@;<PpC7`=$O2шF DdIN|*fkxA"جng: bD|v3o1֊׿i"}6_bnV>KVZOǼEDcBNC$/>e|1O,<ܟ?s_(E ŷ[9*eӿ|ܷac9>%_twe?~lYrƙpzrǞWpv#wӄ>ɲZ^^g1Rw}?0u:5<M 3Gvse+ٮ;(n-KW.K<,]sFYB<WI:+a$ j?'_W߾ZVnY~e3gv1}}eJ}SZU9:{FjGm*ЌW\BW\vRؽβcʲ,N?,Uj}|~gWmd;mXҤ}=7}kG>Suח{vLReFc :UtupsdrU?=_vK)`;GXw8Tew|G9v13w?VQ>rӸ|zm$.C]\oӝ:(ƊovS<6eWM^#eՏ =7T*;nEׂ%Kh[ԧyJD|eLso-->IOi,_̞e驧Frނ5T#T{]6WmnngGYDׯC= sBK#oKoz>,_ 6z}}~͵eu7mW_M7"%t~KO=U&|CgA|S8?.)oN\|[v0HK>_:ϖ{iލw/zVYFʢ#u(tzͶ^27]wnl-se4JBil~jsAP {(ՠ#F0o(k7w(òS(*z̞:k)ۯlZM4~:@XB}뿐~q׮~Rv?y3r}p)Tvo -ƾrӂVq};-'eizVh rYОb֮tO4î$"yǦxK|z\"y39<_rKZ!&7+YH'?yܷٴ?Ru;⒃wM߇ysM蛯,)SʂK#yCׯdz/XQw^r -gO*LCpO9>&LB3U|Uoe^y/Xr>q[__x/ i~,Owv}.▲>o˟zrt]z Wǖ8}igX.]:o8={=Wˋr)+Iw}bca}rǔ{Qvo-Os/>aEy:g3o+f1zj|oyYUh6n!7栣mzH,:$I'+_ϿETm1tY.m^3_ 'ߪ!5:{n>zA֛Xp)qA Ȧ/قtr mֻ˵o>S_ 䧖5py[aGDKxZgUГN,/|qlsrвee_uJz=>$wd nGRA`/ rx9̣VOr,N(Sn ;$Qu{SnMo.|><*<5bnŹkO(k5XҵK.)Wxӵ 9$`p~PU[Q>;c9}?ò`>ZȹoEG1N{Kˉ/|!swܓ"fb׆ Ϣe4j5~u9Gi!9CWg*O}\fzmho϶#f9 8ͩW2тru+g6hvo";?6nxWz3g$\*d6Z_E;ʙBE|Ng2ԿK8Ӣig/x"ťs/eP/|Oƨ=QW=y-|.>k.{+ʝm\9~j<^wg<-^We5yƍ7]5Qw|'=#JsԱd;'^`}'@}#nԽG8sH16گJ9Du]uYyܷxa*׽喿~rOO[UۮOΞϕ Hچk`yy$H6Ú3]]3uu]]ל*JJ9 qysPn+ÙuM@L{R!uB X:.[Fu2rVwOeq@- rA2@߹Ѳ8 \hYPI\ w.i,$AA.H;4ZT $K-*IP %$(}FJdsIeq@% rA2@߹Ѳ8 \hYPI\ w.i,$AA.H;4ZT $K-*IP %$(}FJdsIeq@% rA2@߹Ѳ8 \hYPI\ w.i,$AA.H;4ZT $K-*IP %$(}FJdsIeq@% rA2@߹Ѳ8b ZT-}Q`+RgkIh@ڦЛ~Ef˝&{й2|"I`zaC%~}:9wTpUaw-/ #_L(<孥n:is3,wN .W9<$; :_=ol)BQww-Q GTb6i5Sd]3Rq_b"DN]&ZB~*Ҫ^p YP;I|R[eZdhT/oVi W;÷OtʾZa}<9r \5 nIb^gNt;Qed:VmjP\% ZA)JϠ rʧJ +0^ $C>&=.?'STepҚUsQӈCHxIGxQ"jG ;)d !/׿ze=A'}-(hjéb, -QxP% U+RrQbL'X jEeUUsOPQ"Cbre[pX]V^wݥVxP蓛͓\(G*V@{b*O*cOgrΕ].,XYׂ}F+L|E - gƪ<(x#8R$ƿtqzXl|g8G .bP~t7('gOF"_Ԛ)#.EoRZla¡8w~2pyv*kzTTMS#pg4٦5,:˪HJq(+x On)v{A)5h*PmgUٸ!QʊJ7m ]'+ I2NZ|iX4 ju99PQQeDL.Yc[(( w?^tlZK'N t&?/#:J!sb3yB-a?'0-&ڸtifܥE>*BMG9t}{۵}_ȄiE#2/2ZNx+ n  TQu_uBQ%[P YJƒ(%lh  dxŐPIA34 H)<(Q"CrbzpP?$r %DNX"ɴΣ#Y@Z0JFo e},$  d䚋gGr\, UxP%Dn_na+"vk.|%  dƐ_ߔ?]uT>)2Usn_(xR|ՈerK _#VP&CqƁcˤ>\G8v6mŰ9",bAND_7 V[[}ʍm] ֡?TT0NT/lja2_C)a-t^afZ ,l\Y1UT zՕ;dn^ %?!ˋѝ^5;|\\\+dP*+TRʧCԕAC.Y*>zjb7WvGyaGou`X]X+`)7 N֎RH֌^ˬ'bav-E̖op[6S)yGVk OFFplʏ| ӤtFU+7[W*YW"BelΝr,bmܠlVQa_Ld6ItFCd 65>WLnF Eab`ZIֿޑn ydEUr!ͰjUK_?밙sl0OƆIh6 6lHƒ̆ouq +'.+$8=BXbM2#Lfn?' sAOVɯ(DImlV6 EUzkz4EJ6^L#"ӚG<܊p>b@)e^Qi܇g!o Ny7#'c-zI!J-X_^"8ZݻVL<>o Utw;l),fPb1<*czz9޳Zʁ{ZcUݏ+y/k~5X.xlʟrө}Ok{i)ի,\O߅]Zkk,'@-d>O*Z$Iz;%s"P@Aiߌ~iíCpoCâjpiraV%5q|T-z]v۝*rл݀{~—cEx.F9{j #1,|A7 rlIED?^U J=d׫Z ߲Țˬ??wο}=51'NsSN=E.mpI붟k4knQL *z<Cd"y{CS-ZJ.@@kh?k*̨G:]9DS=iv?X|pRAo裴ˍsL'K_9DO> _t9TGlHz)6õ%l6ܷ_(SJE%!aVU6n YJUUqT˭WF*ɭ?{G"&_G?gGρ7LU[M*mXά;yajQKbPXTͅEU7ZT]FX՜sy DXDܥ%r\G6,p<4YلjwS?Oqؗ7p[@ ~Ul\\5U30\*XT_;i=ܿƼ}k{i$QgINp_HGo XHLA]\Iߎ5_&g<0[T? e?[s0 םa<`aYW<R_pWP}(XE\R*g>8[&)ZT{֕i0",`tkO .b$K/7& fLܥXVƜ:cZN@?M׽U Fx`Mu,?)8ܠ%5N}U+o 0t[J:K!g?;c|A5\pS)rM̟x\;8Ud˚r(*?P@yd?? S`X^z MH nZnNv rVUF-tG8l "{ |%ນVn'z{Z;p?O ݆!aE{$e:3p@6 /rng?!㰘s 1l4˴7"ׂnoU裏U6kwe\U _1ƽ]Y]c<-FX@IDATѸ/A*c{Omb0_& M~cC>FHɊP؏?u\O&,{ϠI lIO?ǿ \챧=*,xG@nw,+@ ~,ͳܯze(|Is"?hWPe|Vs}eNI1u1T*{:K?D&p9K/*թKg؃ASnV as1ǃ|,pZ n0URb^Z5j(3ZB2/~}p8YO D-;JW够c$¥YnUN\%l^ZT8eVW Bp8bH:@<&s $fIs翛g&_nٮ[ ^n+ƒ)[ & ɽrR޿McX AQ#}wUN$?\v\P߿OD|oը/j *KӂJ+ `=QQu3elw߿Hn RZEG#eҦiUyshrV-WGπtbBq4H-2X+?+u(vk?_2? ~P 'Ypim<\[ECh“J_XT1> UvExSctqx#N]6-a!?ο ޾yU'Ö?I8{NbpZ{jW`|-d`";66YZTeHQA.DZğHE:кi'`Y N,#AR05ǽTǜ%5-at-6ѐCnɜq9Pۉb_lJW!lD*^wѵ8x̡p8].b[`{kcInseFGi"RaO|{6*Ǟ?\*"'_Z&~Mgyz\]ɼ J1\]?١{t`GCIZ7iZ\y%Ha[V%be+. 8u 1t%&wp!aAPZ&|S;LtW]0D!q ?ڎ@sl|{X=mDcg[,QKHtbX2?(*=_~)k7/_( b3NI|W7W(s.@;ו:v9*Qu^0cMe gV1p7Ք44H:G[(R>듮-,UP Ç[6}pyQjum[?qGʑ_D/-vg|]n'B9lai" |a?|(k'NP| tnLDH5 r6srkz˖|@y?ul:Zp{PU)T"U)ƟOZ{5O?\t Y氋~'*`6)%ѵ8,]a:bHwa%Ï^Xs@#vJp#ucD~P5ŖX[Df??5_#1aZ5RrϺ3e-?Xbd37r/2dhԦŹrɽ992Sn?Y%cžв`=hE5"o[ UT ?-ܵ9 %p؍eRk2u;9/\ŝRg߯E_>>[O_Z({"(k$h-V.}r.Οc˪rJ"#1,?/,X6BlMP㎪78:Y [z7|E9^tי吽!^Fׯa5~CjPuuLjңEU?EVh}Ti, =.Hr-JaUdt'2>u/y2ca5j;xI%$~3WFD1})pD"?)yJi*%ɳMV(ɟAwDƞy:{ %OteP%GM#f"(AźlH#8fwǐS,갛Jϧ4SE1CnK/uO):(e6m P<__UEiQZaQu94r5眛 (:p3aϺ8'po &Тj7mw6Q2›Vbj9"pOit=|AK7eE>cp_^Z-ty ەn@XvͰ[R"M`Qq~~=uLT`"u⾱UuT_Wu[[qN$CNi&Gsʺ !{udn45GwŊCEɨlﮌEUGUV0O$ $rxѓ'6M^eO$Jɐx`7'όy`?S\ʈ^p;bY1pWx\]/b0zߴpl-E+ dO;Zgͫ{ma`yY cɯCwC>߲r|y 6 &<dnQl-]&Kt-ϻyf=j bp# ¤Æ3q~`Q?X0d&8džbka }h*)_98um}`iRM3HBōD%4c.Vܭ~+Sa! \`Qo;Fݭ "`_sG鉃(4vV`Ί(Y peްL E /zbNqgAMdKp1K*僜L2@#TՋ8Gͫ؇< ˙mw1'`<{jf6[oQEcÊl>L\ǟT]O==ݭCo1]s jj eiL}:ۓVt("{q_wJ m>ZiHN4䗸a= K9sPHuh ~ ,*Ql"vFC- ?~u?d]-Aݬ6:wR6)1 Z>U[TE =wCQ(n$Ȱ DJǯ PQ5P[cGX9><ղ~szOAJ6d̒?Ӝ== ZTxm9N^Y.:Gi٧@>JC?̏ ۤmjMwAb.W.4 Ȁ,)3k6H&tsbe@EN@Cax@(\D+` UL 4pq9UCIIwd[zu/e?4KܙSi)k]]KcO?]? Yo.?cSaE@0Εd#c8pVP4t?t[X@_eOqA* D;;%?',c &7roѪHJċ)tI ޿GU֣3*9ۜl\QȌ#7('un)?t4YW7oU'3-OEU=|`]*CoI-/0k&ћ![ӟٿG;F}T6H<}HrFժTsi(}:Ԓ+w?m_[$6nWJ&m1a\:t.%NJrMeeRk߿ XTAQ*X3Nk0âjXT1d?쩌ٷ[7{'g?Z!ؤT>4Ï̝it><}S T.. 뿾cȓ{_Y,/JGnTMN]}٫} kOø|L_*T #{83dڭr$otVPG]Wޫ4SYFO]'x,u-w=kGt/ן1ox~>Y(IAm4bjR*:{iը,\cƑ:)Tؑ_ZU *L늭Hx YA$2>3#[qDj UǟO*t]P\XOeoſ>e012[8L6x%ï wPn<}ρ{˵Xo/++AϨp|ۺa\*w( zRѨ2(x*KthaQ5Td- K5QU'2 A`SPȯU7p~ 'Z8\r*}6XG2apG>?ƒui $w80f,qpռaxkq|Ezm dJFL+!Z$Q2sSph+%"-8)͋:Uy*E!f7[M._亜8Z,3YY ń?}=qGݞ~w-x^/S.8ؿCvɟ]16k:uʍKYgDǟKVJ `UǶLݐW?$S<⊄j%,oKHޡV*Q^F2G;G*UtSj TNOoۺ 2r}k$ | BܿVtDzO>E +TmD&BaUe)+Zu|n -}[]6kdQ[9ޟUBr;u{OI̻#_CAzY4pYbJ, XJl!<Xan)œ&j VQ#i=(WbT)(_CA?ƂZno+]hAԧɲ-kvf/g=:Q߹ۜLv+.4#ZZTz{!Tux[ȿ/\ViUUN״e"}xf"Y-8bdILd23s\Eآ )4$!D&i$2e$DȤ1sO$DҐĜJdҘ!h_$˭=$ ID&2-ɢ[M*SL|w<,GpԻcC_4ŤrsQ˝?߄ P\<w&!{ZT5rBJg>L}PCJBDgizjU*0[b  ㉜r,(K X]G<SϘEQ|0f\W|znM'7cDe,?` yj8Kx";LĻ92SWS:I?u T$]Qqr?K6d\-W]8@PХТ ,OJ9륅t/Hͪ7PQ6B6J,߮yUy"Sbğt4AdAX}XJ"YmU pei3<햫ـ5|7ՌaelB C]+3<1t%='B 9"xi;koU8<8`A!7ChDHwA;QaV(*}`9o ){|?, Twdž_/w7F|){O+7>*Oxܔm2|p(!ߡ yґEY}  i@ޔX5*{Ed\;:,%'aIvsqpmPq;ʵ02mQPT٦ EUBwVv͞69Pp)S ?4Sȸq,g::ʖP%Ch}ؕd@+R"'NEo)?ġzb:K0a}͈˻犯R#Xxᅲ~tYR .;ޓ>=;S`iE\<ǫ~NtUvaᚲ>u]2)vy0]dTd 8Rr)2K5wTpAў(Td0oͱ_d4*FN#]~{9{ǐ)w:W'4lF(*BG2Z' x*]tyM*<m-e%oBZŗ~ݓ Cf]9wq`SwHdM ݙ0<"ƫ-Kx,&kK;o |:VzE#n81h3X ʟ.аPj1N?.3cƞQWΑhrX"7r`!Mpa!"'V/[<{t>ʀ5d{[KeeŒ *j\In>tok(v܇7߿^Jv6W28;Y'O㎪ѷPD^l7ÂHa5ʣh!ʆÉ37J"0Y6 `Q;q]pǷrզqW_ ny2}feMZƿnrLVxV7=4] 8p^۾(I$Ƞg;′1PXԄ aR}&倅*Z&1\>gy-߄k2P2y߶ I :<. Uߙ ~aOgC?D}lm;QERʥMp,nwNn-& &ᰞtW|WG}3`/+mq͢j.( 2J۱ 3hQuhmi_z$ *Bj7Pz*>r)4`͑׎a{ 5?itmK'ȏg':P#*F'Kb`iQ徴/XT/!2 mbּNJEQy3pЖ'zOc+AafFe<_-P8]GZ~!m`_qai\Xz)|ͥ#N:blL~lHLVpN("Ny{p˶y @E_ȃ!pPMϡA;>|jC6Yh ]7H :'(u|oʴ{sRs'b*e|*>mjGU[??$0+d ףYz>l]VF?y4vjlڈz18ah5(/"*Y `vŚ{6|/X5GdxW7'(-Eޕrh]EXgR QZ}VȯXf(-<ǟ0dyI4-\2[I-{  bZG.udϘ0G0*,ֶVWU'%˗WM+t=l½vdGVT9k[W`٪U8)J(a" C|NŃpT~n9i֟5nv31QIU8FA*QrN#ŃpT>3 䐛:t$&r1R0染Cnd9(^<;H%3-}L~ҤRc9\-_.*KeLt5saYJ *K*k@Tⵆ2lG-B޵aV / 6>b5"򑊪3Иr9!Hq/+ K*Q!x?~,qZTR}&c` 2T ZiQj25LĈlbe \*yBYY4~>o L?-c~Ԗ"b1A\:DWތʲ3x t42DM8Lv(2 _o\XɅ#F@M6 l,sna pCMpHax\U6m2jQPAʺe@*uצEUAEp5,m YrvƆ??{EKժ4J'= g˘4a֭d!nxn7/4tu,+/?^xI˺uR$eJ! n;Y9RI{(`ZV>W(*Z;h ujuDu,zh!:@UTw^i4hqws7nig9gpRk]3R+ eYgiའRbpliW>|{ɲ]bᱲ7̥"SM?ʀY/=i"HXUV^2Т`$" S gOZ=1\D^$T"Z\z>T d"ht 4* 㯮N?=JF NQl?rǛ⽅w'?2\^9O$' _ׇpkH08;jla@67JKJdD* 9Mp'ų𭷱v22}xS J7np)2%:2 eYV-@LFA5ƞP,*R\{p/ĚPkX+`_t ȥ \6vHjcX> AnӁ_R%u?p?OjF" Ep.*aTvs2Ӳv7bm`ci#;vf*w-&>0Dzk:裺Y|{Ɏ>;U#*amkb?vxG㏹1?76^"su%8'/ k%ͽ3ϟyO%rz~z`:Dbi5HtZZݷ Q?<%TT?b3mg9H?UlCJ|YmcCthi֕B\@6/\nYcJ\([p0 Lh5BH h.5wk$aD|#UP2*FU$*XTפɧ~upt Y:i{!U7Kd\]>.g[:q4c)9<\ix*j@}FtSH^S&3Rs < :*I_-xG/(iL\G۞'O a1G PJy_Z[EǑv}?orЁRkgٲbZf }Wo{!U*sXM W| Xa[oN>`u޽ܝOHm7׶ XgU}%z8 {(\O<)ϽsRw=Pʎj[1616fܺf-a4ߤ)*/N?ɟT>(g1-O8^@1Hg͂Bps8(;z ҴKUBrQ5\oQź.QUl:seJSnc?`T[O-:B)uwi\ⷘ3 PP25zթ#>G bUgJ_wzoWI]r:'??,I#@2{,.BX9=n"DI6`?_Y79ǂ ヹ_yY !Z2_yj ?/ȌD Jc:]`O]{Q_{@k4Q1CyV]#KȝZ,͎t= |uo_Vp]ѧz=PWTB**s~&|ZɁJuI\oT4 SXA?EJEă{rZi]GsZizu?TT~1;?;Z( 'ʐ]M]\-c_QsJB+4'+Ԣs/MY[:{rOnȾD09 kinM{a ҿ?~/kJh,W_?x)3jE3rGt $ 7 9[B/xgo"ZPpRDL$ h!G+bZ;dDKCemHZXFka-Mp3zu#/z%w+ٽG FI(G =ۑOET>p~"PPQA{UQ.Pv&QB*|iw񥿨M.]9B<}'">-К ۭ􀥀|wID~|˭/Uk]dr}̱zxKƟTr`m+#pn/rƟi}_¢j 44IFx '9Eb=ԅ,?۱v|l6?0a5? bXPtgrхz`X$ -x҄he?1ƽTrAܸ^'=l)7W;܁(̶u2bc@70f,tv&paX'LtTST5 OpXJe(iNyD4IbCbW`}6( -6(vVlqg iIbCbW`}6( -6(vVlqg iIbCbW`}6( -6(vVlqg iIbCbW`}6( -6(vVlqg iIbCbW`}6( -6(vVlqg iIbCbW`}6( -6(vVlqg iIbCbW`}6( -6(vVlqg iIbCbW`}6( -6(vVlqg iIbCbW`}6( -6(vVlqg iIbCbW`}6( -6(vVlqg iIbCbW`}6( -6(vVlqg iIbCbW`}6( -6(vVlqg iIbCbW`}6( -6(vVlqg4@IDAT iIbCbW`}6( -6(vVlqg iIbCbW`}6( -6(vVlqg iIbCbW`}6( -6(vVlqg iIbCbW`[)wT%҈AilQeH,C}fAϒ*2C&4$G)KXH9XzlpƇY ?;|\~ഇI" )ZPT-(`QDkRw4&nQKӌg9oJyK-ok@"d]LL\ܛոT0(&\ `{ՈqTR Pzdާ*g!n2ɩ!mEWTzqG%SE LP*Q}>\&Ays8챻t}U[ͳNN7mW%8p߷0_j)wY7]C](_W1*Ѣ XT_jA@]?kLM U6nCw.|[֬ɸSj1(*f5ᒯ#ºIKXTmU*[TY [XwLj f>oZ[Vz-p1:D^Sr\I֏dmvbfI磔%,J%iHR8ǿ\ 8/̒4$G)KX\.w#f!q>JYr%DT2KҐ8,aqsDT2KҐ8,aqNJ|Ae!q>JYrQ,IC|9+'Y(e 垛ND *$ Q_TfI磔%,.{n;/̒4$G)KXp"*_P%I3@UXwXT0y4tÊȰB>UD 0 Ƙ|+2 UX}W;|Ң,вl !8mpwǺ ]L r.RpKiL$ԕϨTQN6lܗgo\4y8+-?A RE(M\0Z;(eȲ|:@L88ۣ\& 5ơ*ݮAyxDcH9 !Z>ϙ-n(OF|.p5_Ud5p:,rQ&\n \Y-x5{5rU^]&4?N,a ?Q.~~*!J"l[AFOB_3-[x⵲F,**%nBe"7^mo Cb_w뵗w{I:e3\-.< WƑÆH4I7~H4l$uv].<_=!Upo59kX1*68~2ov*|[Cu護?UvN1ע<ٶizjdl3/oFB=<7P돋ǢԹ_519 Y6ckٿ?׻mc\Gi5RyGrG~T.7݀= }ְ2 b1i9/n}X/:Ӱr)H?h;)=Y4HFrY0XƐ[Rȭ?3$wYpϨTQ.@3c0rOrlHPW?RMD!'d\JnX'7^\r;׮"DϘJUc*3X$hsrM Ђ S ^0zjfL0pE}+5L‡;23Rl)Q5WCJ*WXLkg H 0Edf5"կR*9M0&HTJ SLf6\#)R*5L3crpHԠ 0Edf5"կR*9M0&HTJ SLf6\#)R*5L3crpHԠ 0Edf5"կR*9M0&HTJ SLf6\#)R*5L3crpHԠ 0Edf5"կR*9M0&HTJ SLf6\#)R*5L3crpHԠ 0Edf5"կR*9M0&HTJ SLf6\#)R*5L3crpHԠ 0Edf5"կR*9M0&HTJ SLf6\#)R*5L3crpHԠ 0Edf5"կR*9M0&HTJ SLf6\#)R*5L3crpHԠ 0Edf5"կR*9M0&HTJ SLf6\#)R*5L3crpHԠ 0Edf5"կR*9M0&HTJ SLf6\#)R*5L3crpHԠ 0Edf5"կR*9M0&HTJ SLf6\#)R*5L3crpHԠ 0Edf5"կR*9M0&HTJ SLf6\#)R*5L3crpHԠ 0Edf5"կR*9M0&HTJ SLf6\#)R*5L3crpHԠ _@ި3k2 0a?1LbM႑l~ɲ5$9^~)|ҷB9*I\*q f-eW=NeȜMHu1[n`ÄTCn4۪%,د.dY]Ao*S,߷?nVObFL KKY_LW{a0צ9SƟ2DlLWƟ2]J! s8OyO}5j9:#q;y#juyYټJ8*@Lwe|ӯY)qk DW43 z?Ǭf &AG{=vc^b_uPwnwMam?2C'aъ-2׿kvc//GӠ-$o&զaXcJ>hDJ+ ~`4㬈1RSƟ27ۦѡXch񷌿e-/ ~`p#m5q^*OSF2P k uH a. NɌ*a](ۊ=F#*_W$Z^y#OGs.aFv%U)-NTͼ fU8*ϛ[c67߄U7_W*4@{Ü;d0aĪAY)UoChhT#sI4Wyƈm*ϧkLhh@kG(_%ϫ<"X(ER9Ql5Z,ϫ<"X(Ŀ-kUOTNmc[_5*ϧH*'ֶ1-FyS$kŖWrM)ʉmbKb&x^I6F%h\<|rbmjX Wy>ER9Ql5Z,ϫ<"X(Ŀ-kUOTNmc[_5*ϧH*'ֶ1-FyS$kŖWrM)ʉmbT;%_GT=q`QtLKq?f|:᩶ٺ;Z.un^۸߭WŸ]쯚9w%̽Ik'ڔJ\Z=T߼d18?@y6TKW/e߼5%[%__iW3%_Jk|%2?eq#|3}Rlg[2XcQA(߿*"g:|߿^պ.gj[[y$+x 7ŒFkVB\Ui[\VA;N hLD#d#*a͵awrYJS ǜ5(dF?V̦²G?G"BE*zig3t% Ubem/I.EkK%hcÇG:R5Lsh?NZIYy5qH^U50[n˿by)ځjs"f‰ERU,ԟHCekCUT4$KE\U,ԟE.yMG31sUP"`%5q|^UBيQy4y3W* g+FQK^E\U,ԟE.yMG31sUP"`%5q|^UBيQy4y3W* g+FQK^E\U,ԟE.yMG31sUP"`%5q|^UBيQy4y3W* g+FQK^E\U,ԟE.yMG31sUP"`%5q|^UBيQy4y3W* g+FQK^E\U,ԟE.yMG31sUP"`%5q|^UBيQy4y3W* g+FQK^E\U,ԟE.yMG31sUP"`%5q|^UBيQy4y3W* g+FQK^E\U,ԟE.yMG31sUP"`%5q|^UBيQy4y3W* g+FQK^E\U,ԟE.yMG31sUP"`%5q|^UBيQy4y3W* g+FQK^E\U,ԟE.yMG31sUP"`%5q|^UBيQy4y3W* g+FQK^E\U,ԟE.yMG31sUP"`%5q|^UBيQy4y3W* g+FQK^E\U,ԟE.yMG31sUP"`%5q|^UBيQy4y3W* g+FQK^E\U,ԟE.yMG31sUP"`%5q|^UBيQy4y3W* ŖQ<%tL?U_d*u@&棍$+o%d1.3X304ѡ c&S&)`70̼2"g9yk;V8bxݷWvGUUkZ;ħ?OIW˥5\.>_iy{J7#U{\.W_3w*?e)Ok|)'#y4iIS/diBK4 S8QeUfE8UWDN5oNXiwRF\@ׂeI1;aUeM ėD$tg=KεNQ>r,N7WLY;fhxE?1cJ@1d[ixEit&aͧ?/5 Pu 2?eŘHyO0&\y)))_{cD(?Yn?_^}_ZVz+Bxc*Q {*YmNTJ>PhJ bXxc̶IÇfVLSSIMK3psc%=d`LoɲIVgX`^;vשU( NbvNtCOqRNDʟx`Vd:Q/q(/joYLGiR;QNF(Qx()t'q(/joYLGiR;QNF(Qx()t'q(/joYLGiR;QNF(Qx()t'q(/joYLGiR;QNF(Qx()t'q(/joYL0^USZ^40DW8/Ba)\keUF߮"6Wʒa%]E&dkͮ:ܥk:'"i61j894x兙^m߻3ֻI*#͉Xs;?a_?70}X%UK_X vh %пƨCҊf5A[7NrͲr7Ӭ)^?%~CH ̮vr{fQVVBШȓɣĿ0jZAШ2?e)oK*[FC1?,O#PƟ2_#bN?" '_5tUȿt\v"y;$˥uCVÌ*AEtx^ZUx%q|lV8ha'HQAF v%f"WT,s $H@?5sS3kWb?5|t"܌]@l\x) V)WѿIgF'!)?[@5 9(28 _C#uNAh҉TS?hc݃;tE|oyFWXu BȔNK?~Wp#* hK@݀eH!ۣʕfV*us x5XOE$DC0Ir 4LA/خ&8 QbT~JzkZϵNXvPT޿\X|}JZRW>W9ɱ>VRjUNrպZrc.\$:xXK%W9ɱ>VRjUNrպZrc.\$:xXK%W9ɱ>VRjUNrպZrc.\$:xXK%W9ɱ>VRjUNrպZrc.\$:xXK%W9ɱ>VRjUNrպZrc.\$:xXK%W9ɱ>VRjUNrպZrc.\$:xXK%W9ɱ>VRjUNrպZrc.\$:xXK%W9ɱ>VRjUNrպZrc.\$:xXK%W9ɱ>VRjUNrպZrc.\$:xXK%W9ɱ>VRjUNrպZrc.\$:xXK%W9ɱ>VRjUNrպZrc.\$:xXK%W9ɱ>VRjUNrպZrc.\$:xXK%W9ɱ>],(j1!7 [EDʑXD7, DJ*R$GFeXƶO R9N:xq"ʳLC kAE--i?M~ѢSP`Gt (+jb _cڒ&,S]PxkL?b.EGiF%XcZ*G8..8ST>!=.?XkT\h1W@9=<2ZkTla3kՖ4#"5*5jKZ[Xc%M興GFu-wFcڒCtD#F;XmIS!:"Q]b XcȨQh1V[zxdTרzg4-ij=DGD<2kTla3kՖ4#"5*5jKZ[Xc%M興GFu-wFcڒCtD#F;XmIS!:"Q]b XcȨQh1V[zxdTרzg4-ij=DGD<2kTla3kՖ4#"5*5jKZ[Xc%M興GFu-wFcڒCtD#F;XmIS!:"Q]b XcȨQh1V[zxdTרzg4-ij=DGD<2kTla3kՖ4#"5*5jKZ[XcFNCɈD("FHlo#^6j ݻvJ56pRёjnU:ft^?As)B|hIjҴ"NҤ#Q=T3jX$RjSR6R"gl%.իVDK}Jk:&kʩosWTiמߟowQr+?e)Od<!oRoS^&#<2?e)E~,oIMGx^S?|HHiFUL|z֞4$c(&%v=t3aP}!"YQ o"Shfsb)TƼOTs@ Xe=Um$OaﯰB?ƂHlL6.8]'+ ĿCp<|;Vb VLi3%-8]J)ĞzI.j?e{%e)z5 cL`[2j=ަeZi0ohF+u=e0<[o_Ms7,r4ՑJ7Œ ]ݱJpj'^uZ6 ϳL?Y5.YE TFltr/Yh프 <9wH{Rq9w*?W?/08A)/]F{ ϮUceZKCHNx i(_ZiE=,2|~棝> e+㟶2dؔҍ2-q۷؆Sh6_ڎߏnTiyC_}/vmux:SDU#L(QJG@uT,o1@"] 'VHKv*pKqy[yUoKT#*yJ+?<+=Y~(GCSi4~!W_6xx+6ЈUE+OCdtx7[oǿ 7X׵c?;.~L:mYk9Aarl[]жx?,iٰBLC%uv5뚖' 8I't0DM7_ f{qh50\WpEE{ƿJtW_ُ(*bJ oU?YM`?e)OjXE T1Aj ^UƟGjDմlFU}s˚ 盠xUJ f˽?{mVtkUdTJZ /M{Xy *̢ |lXj% +t k~wе e_^I XFu 6{f6^e8(;aEg5Kڝs+n7!wQ56a-6eo݋5Frd0]9Re?Rxa;$:-l㆐h{ !3/0tOZ߫X,^eW|1<fv6l y0'7Zh[U?O'ܢqxҊd>.^k)`*{c~73:ѭu9148rj6Nj)k8=U&zM/7&z3_=p u*ڠ hnlUk3ؿTdSMlR3ԇy\6RBcpFTƟV$pwr9+t:j';PhzOR8|W3嗭^γh)?:zf]ye[Vj[j':cz0\{prӰ/BZ]^:}n\hpYO'B̈?�8UrE%hfE 3"'P$~?s?Ck7.;qa +{8m?/:0idN㟡{x-\3'pS;߱2K|OCT{+YDnbU7e%toߔ0j )DF茎?ͤD/~/ k~z?%45|{Iy/ 1Qe69x<8_t0sTs_"~Cϴ wS$&bw׊ |~QGfyfiv2:ӿtO8iJ֡Ϩ]פɓ?^X  4~ (DZl׋_Ϥ:8*Oc'GwͦYjstn-ŗ_}BY2:2EyKҹ=OGM? J+Cr1mYy(OWؐu9k(5Q'T< tKJm$k(1< M 0.+OIJm$k(1< M 0.+OIJm$k(1< M 0.+Oo+#qXYX?$6i Mӌ*:! Tm])#KXبIK]1L8)ͺw[&n?? <ci4?Lᶻ§ǘcKKv)tljXɧ x[%ش̈́K=texy'<|Ǝ6[ ;z?W_wK@IDATxs[.7߼Nۆѽx ;yږ=GzP2U)QE`:sȹ[ӸN y an,ٸv[yxv}xlvŽðG]%}F7~wx{&QBG:.+o07'hz>=gvExfSO3{Ü0kk2hC;t괌?%* \ymrCbtNm:oI/JTK.P>l< +`>>6|*,+-g* ɧ^>_N3,|%~z32K_\N;B(Z=r5$ihOQ}t\]C܎<7ۓO`Bt4SrAY몞vxP}17rY{ $JḣVm057_ 1?\k nob7$F~\{Z4,fl6نtǞk;,?~2yM1K3f>]wcIT%?o7娏F[á;p5r c?:v$ iwݐͰgzo(RMS?K[c'פnU_߿@?e-/ƈ)EѨI-^RCqȖGQ~MeY׿^QEUuAAF=jǫiÏgvQoA_$|)S+|0\sߝ{t'_zl|a[~u+HbAZ+S%>ڪ)τ / ~ҏ? 8`^p,?"QBoSG:~pܡTw3H^h!8{'kx꯸x=|Qvia ÒF<☾cmR:!EOأ=l?TO:xIj:WAigW_{îZbe>fO;(ZϿ84}A?,Gr/duwo W\sSpB<(zY<E+!#>|=ŠwvaH8|Ys/y/Ntʗ]tmU1au7^y:CG%-yV|Xoݟe^2 Uw? t>Ң$"(!AXkm4GϿ0t|㈀dh$l\]KMnUˇ>!D'˦Uk  h;?գ%JEZͪb—၇ l~5\X1^dyfgҵ.߹G3@A nCXw"~B~Nե`˻:JT=fcQ|Db;tAn+xH?x?>DXz=u1V,bbf},eU4:4`ZSL'w]IJS#,dp>{Zu_4;m}ݐX%QcPO_F{}XDo> U?|~|D'MC8en= #2Sf$P|h4ԁl 7Hx8]8N\e؂J{ 3{~w]K 93hߝ:D8D>:b̲Ka)7;Zég]^25=>qXyZFXo#2ͬx Rkg x:,/m;x_dΠC+A3oz ]y֛|F*Ϩk4H /w|gyfrurbO)a.H.&gT]r^̅gv"=3ڿ)l{frp572pE$S$$K,J1fPr3; (%pͱfTђ+bFU&3 Qu-wVw*3,.G0/n<;ړIG{@Ì3hFJTQMWj[e%*ĎJ7\yݿ Dy'CÏ cѧ;vrODeBHs`Iq(mz46Z$i$Dhjl2Jz/_BtlO¾ڵ0ݿS7v|Xb0@ǘs?=ƾF+rǰXfJlD? 7p.8k!^y}x3h-%w"FF˯ {Y:nM'\?i,Nnfl0ȌάXtQuc%hhk.9/4%J/ÇkZRh P1,0rT?ٵ؏Y)Kmjz*)u ׄ{*㬲±6[mC^w?:.80a?TNCrXaKAUHHUu}D+$:w}]\Ҫ= \|5 =JV*%O/ȣO#|$!߰4+ 3-f:-GD~7??0-l??g?J=fQZiyfu1\y١L7Qȝ0c7=+$JW8ob6"hSӎlI3 оPc=8>pDy-1}%57[o[vPO3=Vn3[|GȋlWf0#yM6~jx-,{^N g$. kލ/tc%Z1GPOVDuDkfΗ.%pHuD(9qHɤ\+t6+3&%@VKKNJP 衒R78̘֬T e)B+GF|PI`g2c(e)B+GF)r)׊-ʌI PB,Q)ҫoіa:g߂e]*̐2cuQ䕍$N}OWU_OYX|M߶5K՚3CA3Z~50ϟ?0>-ϾJCQ_ >lfu#j_aUW La,}v f7,\O^ûop2G.84J>psq%O={meqE@s J$q^03(fV0EsRx CH%dzI{a%İ篑PC<ïi=TϾι-أj+ޣ*GDh}3<_LW^}3$!W_~>J?tk=~Y)]ԁ?!qvht~rbk{Nb} Zˊ7hkC{Tь[3xt ꟮-!3$CKqpqXnJ+ED4Ct$%W{T6awkoBbQ4!$hFf"w%W3чcߊTB.9-<+aF Q}S*3`UӌQUjx"g2 IWA`&k$E_U)r&3`Lx>;VePUzӺ{%v B\Rjy֘Њ=g믿&OGand->E>$fC;AXNͫe>+c5%=BaO5j8gZ,HK(u}-gOPzf\)KDZ wݛa~s`g_}UZ3G=`^SKTaFU޲?"(Qu=/d <<$w.%"9Grt<Ug}?MTiD^Զq%K34ҴE]跢(gCeNCj1$ZwPnk#!$E-}z{D k 5zO'K]̕^6zw'޸nHT]SOX|_wXừbCiu_f}v{>`Gaх `>n3]lczs2d)uk yCCm5?-1'^H:$6KvM_eZ2<}3cDY^6qrl隨m؈0s~8ג/U-n&6{fVU,tc2hK,81ҟH?Ch/݃ ^ gw .Xo-h9}Gfup+.烇 MTѳ>Eg#a~;!F3}ΈKe!G92'd~ÉJr$ͩ^]b_`%+Dxb Aa쳤퇴f}ѳuOn /k/%5;ԥ=&(7Jͨ}L3pi)Q{*s6i(3)t)2#Ag }W]r͘s `[j2QuOTI8& ӳIm2wy…gzXཐ;x&w*1f3eVc5<K y" |'K~691 wGՂ`pL4VOQoH~)9׷ O'9w!z_In9_Å4O^|mXcDGĿڗZ6rg1 R[j_$m#pS"Q_>;FҦѡXcSƟ2 _S?S?_JlFu8ca; }e$:nkXKgXW4Q% [N0ۜQh`S%gˮrg:Y,C)#|4]Ok*}o;NX6Iv>3fA*2YpKr8|ŸHkihOܜw^yD :%7܌bߤc7 302P"xr0Ața=(Qc,ơ_cbkm`/Y{YHJzhI>nQY^o Q5?:?FcK/>^sp5J/|н\|ީ<+.mL*UE\SثER9Ql5Z,ϫ<"X(Ŀ-kUOTNmc[_5*ϧH*'ֶ1-FyS$kŖWrM)ʉmbKb&x^I6F%h\<|rbmjX Wy>ER9Ql5Z,ϫ<"X(6?-GSJ?ET=q4>o9Dd&>c2cye\\imۯ+_b%i~ i}:*|՗L{z)r۽H Q|K}S4i?1H# 9DS0 3u.~4 !z)ypBabFYw⩁f5{=L |H(or̊hFբ)iCɲF8HpíwG{)~=M.h ;luŖ2[J؈W_'`?29Ψ __g_x)7 ;m5a)g@F4lT-gvWr )a„/% _*; grk¬^(i?k l#m'ڔJ\0)B0ͣl9&|u%%WVLOJmJRi)WHI\W_XcQƟ2 ơmFXsɗ(z {u$^rЧ[[i'ש1VY7ŒCETV}?a#ߑmvRl@裏z}՛߅1O X_/,g?Z=_;"ӲnWxoCo=U]i?QDNTu%6ZKaz [1B /^zA$QCGb^H@AP/œ3f,ljTUho #^{o.o}$wށ e-cu m}v}7Γۋ8$/B^e0+v膏J];{q0c _okBc 25KzPCwq}ۦ%?9p -IiUVZ]x湿wÖ?8t4??P?pWǝyKNӃk)n#Ji]?,iML('VHsDiWƟ#E}T~ Io$VYy#ǺV9 񷌿hS?/%软y#bq،O֥t)V",z֚楒y4y3W* g+FQK^E\U,ԟE.yMG31sUP"}=EzWJ$ТYKíG%7~U^S IvŊT퇮}WׂtEmUl4EߺT$( ! $!?e>g˗8r甙3gy~eC(iS|r)T=+ڸ>-u;g?`ylN}Tl6-H̥.B7.sE-Oxg8&ϟ+ߗ-|ou=-l[9F 7O}>QX~3КR:Eϧel!p;BO~4=^,QUh0>ǯ{IJm!}ci-0{/#;d|Q?WX~ʝ& D?I;wŅ>鷿ezKEP-ų=hp#-2Z\"bo7OoʙNnt8zy=Zl#oTћ+PşinuMxΠ7~HoTxQiMm<ϟMۯonSuӉx7kڮRKm7gog.]cz #០ΉrP/Og9\BP{%g/zUzd3~Zoқ^{s׋^MݶVfj{aNN9[^oI#\]P>(5|Nr 3mO+d}R**yjIHoRw'+'6κ#>g[v5S9ތQ (|#Mse#5$}C#a]hQzYQW}$Rj?HuAʏb2+G@mA(կ>uoЪt>Q!o|]ڄL?yn!`76Mm USdAu{S7߲4s#zmۧ? %zˁMοN Ev}ndzq[۹-O|G DUQqo GozAiu3o(Z_SvVZ|yQ ݶ[o,,.Tm~s7٨>w u9Զ'I\o~ Yhϕ??^F5a ϧO}{ 9O?O;]v~b ϥ1;ߓEӶn+#'5AOi8zzo.deL3U;HO~"t %g9ɗtX*ק]~v" -<^oJ?HӵsS-omKܮm=^p Dρ[|-sMuP,-}?JY;M7I k!P#3+d#iooH/7^K1/uCoM?~}+귛Hԯ]Az[pErfTD6R.k2~x?a~"?|(\RN=-_I{;0?.;(&1}f[[O2CUp|h@|nc *Sg}^!DA'o{qbw 51c ue?ŽŊM}b7ONq?<AJWwuӘew^t;c}x QEJeʪP:<;5@ r^dţ}?UY;;H?Qn޺~ZYnK۞^N`Ӵ5DE]~<󗺨x@͈{1߼Gk9{93niQeև(qtx9F-/߽hqn-fy -brre*+9BƚT,@IDATfMH[ћܕly[%~f+^"z^x…kxA}PJv[ްZuh1k[^LK;2-6*+b cߖk2Ae˱Fo 7@=CiҎ; 6z Hw}O:B%_y oN4^0L| ] on#oj7Xc)[r)'K \BϋZ.KYe^0_N(`u?Ӫʿ;ʝv@ǣ&mxɡ2e 6G1Pw?]>ք޷L o_zC"(1 "+?4@ "F ܱ揿,gD/(.*m}NySy h޼d_{jް;@y[~pO;(Cl T|_{xaw! (roϨo1"#ִ9hfV%f\#gDMzR[іqd/_%)8L"MLۊČ ̽ ӧJH0L._**٘KnV(~g9ԨO~n45ʻh?-I V* F`.O?(DSr# Vf+T{LN&E̻ȿ#FDקOɍcW !Fy;P?o1rÓMe.1g?5/ =HbwʋK|䐾.Tk*+-"AxY[$( W\o1"o(R9kY ƟG1Ϧ.c G?bq?hbt!2`PuyPJ'~$/* u V rh4rp:~"H0Y4Oȿ9bOc-O08/N'7%WlQ-X/1hSx٣ڷ⥡~eF`A#_"pp)O?7;R f%Xȿȿx߹.?uc!|d~L}*E0#n}k2JhYދCE#_jW|vlE~>yC`I‹Wo_?O?3E)Ju# L`- ^&z. =V@U(gΘ*r )9oʪʴ_ 'pF~?/_VjdAW[1dzcjĥR`ȿ=ȿ!$j^4Z<3Ķ*:'Ɵ](0cW3BcU؆&_rXilA?*J̿l5o>}"g|olFgq;|ܟB7Xu%koZ S7cYO+[)niEQ򯏬**[)n%dG.1<=OUL@K-]Ov]rDkwIէ*]'9f;OS.RKד]?rW3ڝGRih.+_#TŴ d/#͡*fK|c!*~9maT7bo 2??R.H>LW~,0qYƼue|QVb#yCOGG{ 9ƼEAZa(M%Fȿ>+,dc?/_Ӟi3 y?+- sy  icj48* |c"D@w-9f|蘅E= 㽢!0ǘ?0FK:fF|OgYT^Ca1od3<Q E9AW`Uިn}e}|U2[~rTVQPU>ފQ!*PJP(* oC *P{(* oꇈ? *P{(* oꇈ? *P{(* oꇈ? *P{(* oꇈ? *P{(* oꇈ? *P{(* oꇈ? *P{(* oꇈ? *P{(* oꇇ!_B/oTՑ|\?[H7&ߨMڕjVy1t oۆmI6o^:G9ao;-)nk(Nao;PڒV"DfW)I/)mG%ŭ"D")m7Ɵc?E[RJ?bsHJhc?:׍Fǧuø;^~3A6獕:";Ϊh|qL_?J"y$OvLwFȿ%_#DEsH㲉<3\H̿c ԋ:^ϐ"oOD/ 1މ'Ɵ~#O1ȧƓ7OW>~#ZTN{K*7eAJa[2!(jІ:N lkQ QU@ Pgim-06 A:EFU5hCYu(sب*m3¶eBPUԠ ufA֢A cά:Z9AalTP6ԙuZa[2!(jІ:N lkQ QU@ Pgim-06 A:EFU5hCYu(sب*m3¶eBPUԠ ufA֢A cά:Z9AalTP6ԙuZa[2!(jІ:N lkQ QU@ Pgim-06 A:EFU5hCYu(sب*m3¶eBPUԠ ufA֢A cά:Z9AalTP6ԙuZa[2!(jІ:N lkQ QU@ Pgim-06 A:EFU5hCYu(sب*m3¶eBPUԠ ufA֢A cά:Z9AalTP6ԙuZa[2!(jІ:N lkQ QU@ Pgim-06 A:EFU5hCYu(sب*m3¶eBPUԠ ufA֢A cά:Z9AalTP6ԙuZa[2!(jІ:N lkQ QU@ Pgim-06 A:EFU5hCYu(sب*m3¶eBPUԠ ufA֢A cά:Z9AalTP6ԙuZa[2!(jІ:N lkQ QU@ Pgim-06 A:EFU5(s/]8ɨ$rZa Qy PXvP5Ns,O U`U4%7Zk!57lkmZjo4%7Zk!57lkmZjo4%7Zk!57lkmZjo4%7Zk!57lkmZjo4%7Zk!57lkmZjo4%7Zk!57lkmZjo4%7Zk!57lkmZjo4%7Zk!57lkmZjo4%7Zk!57lkmZjo4%7Zk!57lkmZjo4%7Zk!57lkmZjo4%7Zk!57lkmZjo4%7Zk!57lkmZjo4%7Zk!57lkmZjo4%7Zk!57lkmZjo4%7Zk!57lkmZjo4%7Zk!57lkmZjo4%7Zk!57lkmZjo4%7Zk!57lkmZjo4%7Zk!57lkmZjo4%7Zk!57lkmZjo4%7Zk!57lkmZjo4%7Zk!57lkmZjo4%7Zk!57lkmZjo4%7Zk!57lkmZjo4%7Zk!57lkmZjoԒQeF}49AFc7XBLLquxG jΑOq~ej36%dLyojTͽi c[w)8P6`3)o?BGAhUisoZ93ȘGg]A &RՕiW zX/I? 4]K)Vq-O?"hf8PiM+8gS"DXc]!fd+{ 0"\JȿO"n]:{U枵,XWUO&.Wf(ϔ7C+hjJUu,XWt"\5&RC~TmWQt[@ (#EK 4\2tv~4ԗ??1o'7_1C.;֡Mt[@ KGGǚv?5Lg NFUefo_yFOT-Y(UUjc ^ K j``Tjc ,.5;8X]P3 jP1PwpDf ԠRc6`vA&A6@m킚) LPJmڸ%5SqK j00A *1jhLa`Tjc ,.5;8X]P3 jP1PwpDf ԠRc6`vA&A6@m킚) LPJmڸ%5SqK j00A *1jhLa`Tjc ,.5;8X]P3 jP1PwpDf ԠRc6`vA&A6@m킚) LPJmڸ%5SqK j00A *1jhLa`Tjc ,.5;8X]P3 jP1PwpDf ԠRc6`vA&A6@m킚) LPJmڸ%5SqK j00A *1jhLa`Tjc ,.5;8X]P3 jP1PwpDf ԠRc6`vA&A6@m킚) LPJmڸ%5SqK j00A *1jhLa`Tjc ,.5;8X]P3 jP1PwpDf ԠRc6`vA&A6@m킚) LPJmڸ%5SqK j00A *1jhLa`Tjc ,.5;8X]P3 jP1PwpDf ,+_Kn4E$bkJbEJ`VD;kBj]ʰI%sw.36Q.U'VKAM T"/+$v"D}*fq%7o0"=l&v1OwǩƚlRb'Ɵ)*A'Ɵ:;K)%;֍uU^e)%wr ?^1WFzUftggЀbFd^Ѫ|Dvv DYw(#*3h@<s"*=0sAbE( GT:kgg@Fȿ#JNeT#*3h@<'O?|bp%{`D8o9;s#F]K(pӬ\6*fRIÉd#Q*5 *UEՎlc9UkA5C/ vd3*MXٯЁkNe; |}r6T֜ʠ #'g3@hͩ ?|!'g3@hͩ bЀ0l9A/_?C p͠բ52hEzAtZTM\1hw}r6T֜ʠ/! COfЁjњS47oDCΚ1Nt^A6nYJʚ`NQ, tUUaXY u Z,.k@UpDEǟɣPׅVJs-"F }ު &?cT/$*Q:!E2-b7ߘt%1W̿bE _~2UϢt!ER,G?b9/T֍d`Fng@4FCEv.yU#FbW8XhO?1RΐDsG?bPN)+?|e1;`֗|ܡ֧!^(T0o-T'T߶bu@RMS6N PyHayFfkE@ ' P߫ T%N@BU *{"%N@BU *{"%N@BU *{"%N@BU *{"%N@BU *{"%N@BU *{"%N@BU *{"%N@BU *{"%N@BU *{Fy%>^d_@y,Tyk BuTpAn0ӚJFi?m YTy!m!珪Z%YCiM: ڽpa|bNLkQ>B~!̴&x6ƿȿ1Hoa$Ӧ0ӚD{?"D!Xj0$iSCiM\# "\  eZ??O_ 5 dڔwfZ?p\_DWK|4Fe7>EU.('LQ_B4sƔ<'i`q,MKѾ|:+:PѴN礄a:+:PѴNb=]AN-P4-Dmb#F)z}4UcˉN7ozJM~/v?"Szm"{I4-D7k3oTq}FUkQ_Y7g[Y.3LwMKf%MJm@F~?Y5IhK_#D/* 9m&&omE[bQb?ȗ|]ӛTڊ0OߘJ2HDIɛi[іqd{D#_x&-q~Q<{)-TNOEi_/TIr}g rܡgUZwBysjǕ S}#Fi'TQ#X(PAzĠ!O!bD]Z8`uZjtAjEsЙQ9Ag>D]Z8`uZjtAjEsЙQ9Ag>D]Z8`uZjtAjEsЙQ9Ag>D]Z8`uZjtAjEsЙQ9Ag>D]Z8`uZjtAjEsЙQ9Ag>D]Z8`uZjtAjEsЙQ9Ag>D]Z8`uZjtAjEsЙQ9Ag>D]Z8`uZjtAjEsЙQ9Ag>D]Z8`uZjtAjEsЙQ9Ag>D]Z8`uZjtAjEsЙQ9Ag>D]Z8`uZjtAjEsЙQ9Ag>D]Z8`uZjtAjEsЙQ9Ag>D]Z8JA^7?ƙbV@+aڭtMHh lw@fgH<ou"ш) ) {_4;}D DEIv,a. ewD#r4h //b户hD XE{_8;ȝҠ?yg#57==u"ш) 0INS4'GDG;jˬ+ r4h //@5n@oO<"wJEkz;?9Ǡ&?u#~sj6/TunwPB Z!&&EuGrَ.P}+R+׽A,G&\0hr)Aʢ&LѾ\ČEEF?1GE?X1;?+?;? *?ѳ;D< x)+'juQkGG}YEc\p~Dfm#EA~7Ɵ#1g̿{F%Ew</xHϖxoq{)\tm`(۸!*grcs/gy GH8X'4`Hz0ƖeR]cKvt| /k[Te|~ S0DEWbmNsb!1!)?x6E2W?4q_%3eB!K<O7(K<)_.Y&1 U&y"?UjMXyz^MB oSYAR~`t+!MD&FD5 " 1R:.Ȝ͛Dȿ121#_1Qf1;rFx/L!Io8VySggx@D<!ϗ2?-aB/$ȿ[#1$0b;?+?N7[צSxB)q7hA~FtAvR< G/%^@_>A=C: rR72Jl}im.-TqVލިZ!%sdjZI 3uqD&Qܾ>G&[;K MmHKpdȖ*⏼!(_ȿ2n//C&]:` 䙕>T4c>_1`Xyf5S 1w̿e܈w̿cqExEqNsyS<1=6_&Ki)z}5> OTɲ_q*sX/"DG(0ߘD?cMy1? [΁-ĻU| GNnSJg'ȸҁ"?;? Tվhjh\" cG̿3S.EsC,䏸TЈoqqnr O&_?I%;oD<"b?Vcc)1g̿)7T2߼X(OW$͸.Kx̟ V*bb~f1|o(MB URM1:P?4̆!-#3pn'+58 ,<`G5n'o?1Ұ 30a"]Lf>Y rL<:/]"Cq/;T4Mި n'*8e+. F؆n|y9 ˁy„aC4 4'E!?pK1Ɵc/J1wWR2xas q i_ToމO#OC(?xϟ8'x /3&硓L|7*3c GoTQ*NU|]^>3%:ٓ@U9%b V,MnG?^'/F}hYL W/T9N͹tY:yg^?ɵ%v|H8A-3-|t9>˸\XPiU˔D;3}]{Iw}q>{ןz묓[ 7ؐ/~\#EA1_c?qqESkp- ߗWꌓC!?#?!W,]\4]}7ܔv[{t] db< ʊ>7s˲e¸kyԵOz lzӤIɻ7#"^*I78pf͠76i%Rtzs0 +fy9IČ\%\Y9˛W$e"% _rb#1G?hrʀV=馛E8e_ӭo+_%%yIķ߸|DĞ kp@8熰_`a:/Qܖ[8?CJkHwR}+uǦgveR1Uo\Js&/)m\](?I/}跪Km7d4y{s{E;R3O?"7)p<$ͧEM6$3kF],}?Kv{z Z:wtg\~Ry~*鍽Ox$zP -*Zx6eG d:O; vfDOrpI[Ñ RtÇȄ*:r$3_xhIPz|d}U/OڝaJ|\~M<˗n1]uՕiO.&nmyҌ3)U5_5}ē7De}:2l^nsI;sr-ҦMvlu_}]c_?"p"&O0YMȿ#FO1#_1?GߦnҶn=u~;_nm}m|}Q5DoTMel_W(t P&*(WC h._~,u![ .<C\ #MLֺYVvմ>w_M&zu:.me&ֱ&pӧM[+kN0qtן?w!|3QE,[OC)[ߒ;K_:K^>wiuI;Ci#$j/ͮO~:k(6|qK^kX mc]1GĿjH-o?֨b1{Ϣ9:pu_椟~zA_+FSrt׾+{5*,k%K) ij&%6s0u*ֶCYPS7 52vS/dŝh5X+!VNt\>S$EPѤ:zD .JG"ׇC4ވ\:\ i@>\sw}wk}?yvRq~j-w̧ؿz}=/Z.7o|~xjka ?nҏ#g>g)Mnyq08>ph̖,$6=6WO(]jq|McM4}Rʶ>x$}>PK7UUkiD~Wq??eh]dg8TV|my0l4LO亩ZlEys ߿?oOM,mcG{L >9|.ync6O|? Z"ƟS>\d}o:3.4]׿qJ=;JO{g>/B} ы_URꓞNrG+V<c;sM/؟d??+'AASwMfLSNw Eۂ>qO_Z@瞻yY'X,闿F _BEwr`TN;#}Sr8m6NK믿T*_NcMɱB裏Mvى ?R?Z>׼Ho}\7/V\+HnI=i>eZz6܄l {ߛn9]pŋtf]iNOM_˃<;9?KƪSӢ+Hm3̰]+[q)S'uƯ$YPL/NQk*{MᏉ+;ߙvab:e2fv{1o};B'<ߗ>5<`a5Kڅ*u\D`5?5Վi:[>鷊^M䟔^vM˜=ii3 Wko~] =1:C: ͷH Ho~ViF4ݜo8=n҆iBEPEgO^9QBlx`6b͘6A`˿uC5C>朿zp(]s5.zo}K:J;MyW;S\"\)Xl* ?=-X<)餯~#miDɔĢo{jFm'n~u/U,]qrS&OJ}V[x#+_?ԞHhJzrPפڡ SJCU>Wԧ}hK_vPZBYs_Ep`/??37wi:岌|Hv=Nvi3賩=׿k/|Q;%ľ@(ӟFF:1 ~^B*^bI'cics%U]'_h; 3x`]qt>3rc4&Sogyʏd:矟ge?(O_c`Fwϱpg2O8kK>E_>wqC U9/>7[^@ ,C5"dgǯүRϟl0f^vߞtA=1ҋ4_S_:?} mOߥ@j-o4—FşFӋtF ^4'}Sz_r4oӫ3Pݷ^{=?Ϡ#zyUÕnfkΙ/x1~czC?>?~U8b,\~?6xhz{Ϩx~כA.,?!NIzq^~g=<tNɏ8~ky _ eJ:iY3WZǟuwK ckl? 88׵/GdMǧ\/FiV"הSM>gm}|? ھ)I~GpW_*i)rrCGN6EȻZ8ߨU7.O.G]|t&\6a' h5X)U Hj_ߤߔrWI%ͪ/?d:xz`KCtu׉Oo?G^{,n?~|0!e Ǻ[ot%\.KOgt"Am&oϥԍK;Hen[=}鷸~uţo,)=G@~򓟔N2_Jo4MoI7t6N{ѷneXU.LigZ|k_=1}co>DΈ4X?Ie>U_c[l猚 u^/!l???9OW1؞{c{Mo~Jzw__SsJ U}>No_6g~K'e G}8WB>o+L/y(&: ̷kP9ɢ/8९ǥ:@($Ჴ/هK.ٛ?O~>SӭޖpEGfsZ#O?{_UѽIDTʤaZ`w)Nii  F?ϙ;}م~F|;9w9D_g2b$eWݟ"8y)9pԩYBlZp_v7v-&M2w/_aMlPdϞɤ!q٠ikeiq:+ A9fD;6?9h!4'c|K{~VLbB2+7 Ώ[w:uXVB2v e33M-p_4/ԨטĊ}Rr3dG:롽{`+"l^/o|?t?o9rL6,Ӧ@8^ᒕ{>T*E x?:f3q=f8>Iږ'9Se_oIKUT}ֹvҢ4Y@yr#+CE&߁o nCd /QXr`T*OYp ;#r%0!P O&dQl`%|eB ,/K LM(*G4Iu&OL;)Q>hBP"CX5+'tl24{xS6R|i[ }^Pٰa䄯:H 3w'"7n!Ceݺum 1c&6yQ8qb$}_bNDa [h1 kժ8|$Lsr̯*IÏ0l|7֗[^ W Ϟ%l撒{ A~r~l=sJҙ+lzԅTն!Cd޼@TH{!~%DPlzql߶]"Xx< gߗO0^APe۴n*m`*W3U `=s8 ӽ<0/h5+48cEtC7.-F4ټ~Dm߻wO,:A"̬iqi h2nߖܹyکefҨApx^jo\%01Qˬy?4d9qTQjْ- DA#5 ըQ[~=ndϚEƍցO?գ'N,Uc eHA|\,\B֬Yf6XG0eڿ_{TUbN `HfT?E0kd2UNO7GXg~0Y1!81Ћ;i3΁O1^>!͛֗R{?Hl;pP۹^#G_ 5ŀ`\ =hF|LHOX]{!߶eSI %?Jom,sCc!1pp? j`)UN+ Z5:98 n*?K+,eK (t|4d8P>88x0tPo,z f2VJC&xo規xMS7OhWoFoȰ*oҠ$Oc~a&c.gx7{y5CO-۷Kq0?bhAgL!m+B ;vYpC:7b[P#GAŋ/2?oCu$k:w/  {K}-f:]leD"FBq$&M!UtFG.QPE$`9 A\+I`4? O4ЧI19y2{p[pC3[?2%h^]'gWO;RH'/牷e lv0GS/7> b !U'%%TnT?ljWR.F&iФ0a(R$O\v%ʚwyG'IS?P5%0_sD&KE|yj_a&N(!t·稐&3&睻w g\8?^]FԌ ЬAjT'_o`>@~3,>ջ߿ wߍMs8Dʡ6ԨQMTtOUm?:ˠ?9rZ*TuD^i>*R%zGÇh]>N &9KԻ=yH۟e%L>EoȽ{j? Ol FߔcM5Ʈ +/GJ8=elI$'NL0s2C#cG\r"A':ur2Hd@ѣI\b\ΜxĉG,YyOPXfpK4)L9-e B_0LiygC$jԨ!̙xNx:z\V3 7 5^`/ wnIƲs? ki.\yhJ9 |UTQwv Q` ߼i=>R->G[|K@8٬Q0˪UkT*$= jfj\|M>x Oˬ?y@&G}Sĉ Bܑ+  w㾫~vq;9&a[W@Pt*#c%Jd8U@P@B*w2aEB<|P\& E 'Fayc\7mNdFoޔj{8aAi??f;`?OZoM A_!/H돸ٖ㿩)~CaY?i*ЦU3p(ϙX}|f̝.R׫ ἱ`U7i2fKupeVA >FUkN>] UC;n/8k>J߄~1:s,8h|n!.>BgM"p~}1&^nMUhRu|*SIg+x忻g|SkN>' xڶj©~)3_3zb}{x~-K,$0"TM>C_3<U/?ǡ$֯ބlIw.4B JXҶ\g?o}wlֿ]'eOAZ }L|]`VpU:>Q[1 0g?JYn fu)m^v]bM}C0qN(| 01F#*E` qcbxMhq`IgkΧv57,oخ:$>3Q5K(*eK >bC '{$7@Se!pBsYzM#pJ)yK"ː>x"F-[@hGtC,&qĈ0Z ϝ+I`YMol&-[CgQ(7@7Q&L ѣGIzo0>7"t! }… z#&_"r>Q_AB,\xDPr edIPwkVѣǵ0XrPQN8qj:9cD5jXr@ϖ3f/۷yfҴqCYlTXIXh!4"&#M´ǕݺҪ1YXϼQ+o>Sd>OP ).̻85`ڟ¤"Ct&<_|Ii޲4w~p%&xs=g,egF\n]ii]!_^aUU bzP94(pռZ ~~`(ӛ'˴3.Rɴt.WҿooT7ky?{ Yif"SO|*94yTiv(^k7;)?{l7fiAYM]ySmWekM8ZIFS tWl֭e|chCohPH,gdk2U&MӼJɵ yN5s&i J>YAC˻K/IמP0ZP>ܽŚϞ%ԯ[]K_e(pyPMwwq8s2upFu0:@+v_?*U*~>8q/ $|e9ܺ~;xA2ghFڮ?mme=bZ&?~?#K?O?/֪D#z%DTjBÿɹ+0MfcD5Ya UuG;}c!zC_r/sR%q-2ժq PT_$ժ*9v5\cXrMrNjӓ$vW8<q=c^Dan &`-[JM{#SppHiqÔ__0(L?RƒϏe+V?Hi.Y< ?Y1 ~`|#)?<x}i l}A4jGiTf|+}+,??4Ibx[ZCPd?QxG3A&Mqa?ߖ-~:?-h^~*8W-G!MM._r/g) C@ mO2I'N Sئܔ?qbUVIMy_<˝:toCPuOhH7on/^I_x$&H<&B6cϚ_\1eɘ1]~hiV9rg{)6p_U1XGfv\9ѭG/C\N`wԬU[BROOl:W,Mgmsg 7敖~j_ Z}hp>~d+4ʓǏ1%iI5X/T K4?h -mXڋ$j*ڣM3g?y:S&Л7n&9fyhL4ּ"*~"[+|s@6U%Ш})۬>W5̅UsfROKu4>,|j;͙=]}H!јzvI Aq2\/#QP$<]`!0t |9_&0/oO |e;w?u24m#~d|8xjLn9{*Ud =ဂ3)iYDCLP:ʂe+,楒ŋz_h鿈 8O%oA+[덟oyk3TS _h7 6{,!}"B?7[M$S!m˱N{7Hp [&#oaL>ď ͱ=@CM$n~ %Dzxc"Bmnk@IDATcxC.œlAA\s,Gb($&nZ?D-(4BMb3t UsyE0W1:1ָgOm=:C6̻H y=~*(%]ZT / j.}8(R&ʮ׮cYG(8\7{K~r ݤ7:l8n:YeXǧV݄dK(mb77|d￝47y߷MAPpqF!dn<Mΐ~sA0b{ο*l;N8ptٟś~?st1 q6$yq?Vy{uŬ,Դw\?YDҵ}lqƴ?; 33S?wm8 gL*ā8aF)%4d jyA"!.It.}ϔY4xĞZq#k_8TqT) GZ!6nmsƌ\_cu3Y%}ZtꨇiӦNt*DJx?~wPTԬ^Ag yaA*7>S|i{Zqݬd\5M$`9x澉r~?NtOR'j9*;?ez[z6,֊=\%nF°(F>;]i?w]LkH'aT1>Q{SC_RM25謿cDH]oқ(wbJ5g~w (+x %~|!vDqLO%H*`ruci̐M|7=8yǰ!V c>@<7SmU0g/v OgC 0f966o&Sgp/=Zl5!L ?&dіw Zr933 r?7gM7!h>Ⱦ0e0$ nqfʔuFP 6@-uz?+qw =o6 KLgAm &A\$}*H"D\,֏ԨRA*чJ֔ Ş/U\qԨ /nߪM{ٴi!i6N^ˍZueʖi #05 _dՄ"}SAC5l,9NmhC xjT*c|x?պ 9uVݷ߮6E?g.q:)6OtKv\\pI8k]n7Zp"^m !|uL1Oa ڌ liJ*.Ow>f~ }BgۗL-d7ٴm 3N*뿇Pmզ3Bs94gxm0qhQ79 } f`n=w% $8eٔa#iG 7T !yy4'r@ 6T&V5b9;;Gex-I'ɐoD5*2(0; __ÙeF2$`(QH~5tݼGhS?6,0m?riΰp<6'hfr06Tl1L C.vS+U.O`wz޳_ , {=La#J岠M$*L.5Xh_^ zw6D~32c hwe~8/G_h*6t*tY w?CKp#T-[-H?G8TRH!I)Ysy ͅ2h ilE O%g@aͷ~9-3f*>s߀dνxT\^>S7u5NqBp6?4-:zd9vߠ3{˴؉SdkM2ad72L0V2Csa1Jw聹%XPYXa K}a(4 ;kt(gᐣA C Rt)+1 qN'wڂs" (Yjk+13xrVhz3?D{}̏;59HEA[>JgH)n&}<>ZRz$ A In2i gt1KbIQ+bZ忻 A?X{aMj 7+f.$Ƀy4I6J űnQ2yRit`{%MҨ2G!' ^=~sKUI d,Ǟ|p>">yh'9S xϘF{?xx>068ϜB$8>IULH|,l̔ŧ N?*Ԩ?NQW*4 6q *? q?P#f z>;`Nz< .kҤNXUI;mo7oA/4SYUOs!C,Z4idxSoԴݍG8|)6|6KrhOPk6*Hʹ]cV8A4m)?9Y6&?˗8>k׭… oV{Q$5W:CPf/WCH1H;fQ*#!jҰ~3\N*`>z5aA6_FMiӡB*U°YWB6kG?tiܸ!7 \n 36դcNU=0V(.ݺ7 -7;b0ɈS@jtX|:ΐ!֋l% pJ׍z[A#&oҤYD "^S(6c۪C|LjM,Z$Xvd O!/ujT)QUfL~j6C6y+? w#{ѯThs;#Y5dR5?i= Nk>K7t1x9Wfmc$K,-~+hml4X .?#[&QxE&TV:w@j=2s" `c5Ha0j&Lk&UCd9~7>S%WVm[l7gF|rgŨ%aàjCZO܌E06| RaPZu]g)/U(;?vkׯI,ÇzZu%}̊|+_ ]S% @KPfݾuDø8is/H>O84 t.t>!_Ҡto2?lmWoFAA8y `C!+{^/H& PHt0UWB#10sR%pʳ7پMsyv1g>ivT0Sґ Isl. XJ1f21FU5+R88ӹ6o6Mh@Jm}e^|ECkϣF"~0+LvD?~⴦iTY->#6^9w!p0df<.l6-괞xb_ϙ-F ^{wD=9CTfUyt-2o"Ure<&hZ˖E in MAGsW!'!:?v4\,#_Iɫ!''NUk!Dޥyth-oRo/ _5&MSBP: m~;5i<&*ANHhǏBɞ(˴M:v_/[_f;⽯d 0c̴Äq`l /h]`)$P5x>cbqL4Yأ h#bNmp4OmQEJúwj+ɒ%Vm?y&vޥ,Z$LS0Kz._5A[D!˛;E[3Lf~4SJA< 2T1 3/3yJzmk|mb?gЫ_zPGv^Gw[hTbw"ޛcƌwVYobս{pЯQDI by 8ty;zDhHE|3\q 3ERPl8{򧛲=S,oK^4mym8D'7RTK4*V!< !S J Y?L?!'OT*R}a6QX'n(ܼuƍ8:?&M +s+:o2#-O4oD#f M[؈eW煘iBRn`#e붊6{4©YMD |?5 ="_/^c,)~'+Wwjߖ&`k@{(ߴU?klٳʸѣM`7(hԤ9|mi7CaA!/P'<'NW=C'N(ժT]+"G\[4k&M /NĎ)vze /I}r떍z*؍υ1ϛ/*1NegȄ ($G S.n|ƑqO G%a/Q|AP ^sJ?P@nj\(5 ~@P)? 𩕑T;Z~g_ aDuk<>YY@ q]O|}ၸU޽!~h`M:.[@ss4ɕGUPzM6m(*&ޣ7r =6B?*c4e=IQ+S گpB3YKs\EE6i3Q ;?j5o~5{4ykKi0>]z@TwU*UV4}-_ fۑKqh2UDdRo -e֮Vᣁwtի_ԃ7~vd(i㋃*;¹@g-80HO?I&-9 t' TG}D@4Y @k@lyt۶yO;w4 _xM09Z`ou, h,[݊aǟ)$ISf? LD| s'nv1ŋYr3'6XI Mj_X;w6IBP|A64eYX{>٨fٮ j{=iن&>7W6U2do[4156l)K7pm&E_6 1#b; j$G]0RKjm3UXAFҴj˃'-Ysi\q|IfSN/]Z}w&s駏)_b\a*/),~mATrb:ߛguBcMC3+ٵG?Xn|e~:u&8B#)y붮' 4Ci78?w^-tgLz 9^z(I JAvslи16z$ 䓪_bxͲ6JjLOb\Ie0EMI4l }w7h!{إ0Id?LĶ?_9s5w+W%BARG9~j6$ya֜:afCwYȫ]N=499 o2|x}ޠN!;{I2 >4bjTv2(FgUTh1#E <\yZ|~S=>;TAA!-'w\88x:ذ~mA!#V:`G\Hg ) AgB d5 .|b]3,<ѭ ePonGU@mPMo/q'v4s/Ȫxx {UߓFs-$pEtXJ?9lMH^0CLZT&֎~s˱$v7dpaj`ZRt<|f"ҾP6 w3Ulm>A+dd*P>*cƕͭkݷ"ɊI0x'uy@`:o?8߿?KCQ XqN2&0״&W Qe""_|k%6GjPÆEޠ`1NVߔ&|9jEiQł_1eK7< A8ЯPƿE? Sk'prLN3+#q Gj'ɚkhb.3mxV9ǯ?s,ldcXlQ^dGna C$v|JZ[h43\їP4+_}FưvqY`H]5kQ}"@? 3s$^jeֹ_Uк"U<`G\!*?H,5*J:fL&7~˴8a:>su69r[? 2PC+k6`_3g㺵ȃtKX13x?QtS.O>+h5nP5k,tG9ȏ2~ھUބOn  R툐vS8})K.cփ*JWEx,Or֬FS p xJU˗jBŠ s  +< &lC||,z LB=})fDK@X4AMVw?;y2ԃ?v(ə w#+W`NO KM ߺuhTmB=;{ӟ@l^SJPw\ÏPcdqN_-O[IK17G/r| XhCĜƐf?LGG*ذK?Y|4F!i㯙og=C?U0QȺwب`fԕ,9<3Lz^9< [6f3{IBڿ`sLJiɀ8LTTXhTv0FAM5xr91 >JɕSkۑ'qFAӜlVƹ:&HzhPNWw6IM!O˱D}w' =3o_@>+Ѿ#{_D08PN>AUThcR:4i GjVY S+"lTn~ӵd( GBy UpƊ(0F8$qkA0@۴hlB47ntc3Ƌ_A#&BDNC|A?G;ۮI1 KUB5B;:MP)DK1: pQIo1}Z9 ~e0v ZT`MN3s\)&2b2#/4@J'.ǺEMگ_/f8f&şB~ 9h[}X3,j#j~:oŒx#w~zf#AKd31ݻTҮʗ-^46Fe'q QiR Lo)g.?,N1`Pwy'p~x{^=7QcjTF0w rr]\rKX+dD93uӴВ⁏ԭ[[ : ;fɕ דּSY`U8ZmqEX(=׷BFj֫E$<ѬX 855V&SLceԩJ9Tb0Ϟ='%ʘg:M_ .GXE0gD|_(=^U|H&3Ȥ?KSDv̓>`vӲ yyB>nDM%Шr-e7yݓJ"+sEiaz_IxLE&Ix Y[/.%S_75FFm.Q/oĴ2p=7I -I3aܹ *W˛d!aFӴZ{i &?NzV*"ցHE>I^#`>ȭOQYlKE-&%?xlHm X\jIZ'{ɒ|:A8R_QS_#P|9&CV.Q 'KLM!Ss+#|h@ɽ.gaN4!Zq2LɂJB[H49?I;, gߖۤ5ϬШJvh0vcvpjX]i|ԩPzyOZD}2e<EytTi6lM?ϝ; 0Pds,X ؈7; dNC~Aޡ}fƱNNd`R}zH8U7xh {( $7晿m۸QXt)&c wMgbF<0Luƈ"v/_ ZsH|U*Wnƈ&_+a :wϿ 0 he/NjC=j$H5SRbijj0Ƃ1Uꔊl:T o ԢF#Y~Ea;?YblU ˫`B#y ~LY0`gϘ)L֐yrkOS@ 3-0mZիf_ zR|sEhzdPlX|Zk&d U֟oU)!޶us>T=,6M.!ai&Ry"y:qv-cF翆dς62h.'.7=478,X0꛵x*Q sBh4|(6fap>ǎ! 7rp_${ZiSƎ@*zǿfB{*Z$fB?5DT,lZIZjTNUB4O:4"?@Y>)l 4 W/?r! Oގh M[@i׺ixQ[|S~>{ SsU9B |vO7x׷eS0;N^%<,t/Qu7Fdɑ5͛>`&;ֿiPI+cԨ>ŋ~7>M4+;Tq9953O._n0I5*K<ٵ/3||4kX@U+!2yY$H?V}N?i5IS+h^< T[4 uܮ6]DK~mjTP8J[+DԭSˉvc-@X5[ F~P8qdJ&pB6jPkvy`Q;>bn?|& 'Th~('^uXrSL::N77wm+Qq ?2^biЄU= >_رВN X4 /&"۷_|)>w9+pߩsW=LM| LB@E|繘iPZEwL_:55zjk1np#CкZO?Xi%}a[ҟ>OHP.aw@$, ~o]XrLi$wz+qߍ{8DsF>];(>2x'/ǟGPJ-m*MwN~8LA+K&<4W#q"K X'<#EaFD-5xMto@hTg]ĥ6K'rSzaɷi?4& UmQ1 egmWU*%P|b,( ^Gh$f cVfl.?pX󤬲5 Y\W34 4Rcw'I>@42`d`#DH;=5q2}tiea)Ш /ߎqtTǯAtL7ƒb~o?4VJO0OΜ&PfXt2|a 5 EQҢ6L` ,d)ljoaLĉ_KtM^ =P vU @<>KDf853>YeˬgNy@uJ87~-%r(n .wK4L4Nc3RnڼlGl7˿~kf*X3ٽg5jXENtcAsNx;SGQ+ pEMN tN3pi\I\bR,[ }>,U$![ک <1S-˛z ߣaz&|H` 8<ࠝ~38~jI`:PM9(&Yx"y! //zyI/Gz+Gzn4m<,3Xf$LS+DE`m|@53QDs4 nr 6? IG[v2a0>/@<Uv~1}Y|Ҍ!-X"߯߈(U˛ < ΍>WPKi@=,a#G$1b#Z49r섖AST4e˦; B`oӴlAսNa4`7k+aa?N8&*->-A|nm [vMj ҥ+CuG!a7` TZ[|~z \z-Eب1diGhk K i0GV069}Vv5-߼uK6?U3^JbNg#ǎɷkk{D HcMYpq?`ejܤF(0gO>A80f@Ҽ79؁$n8`\10a`7/s ҴAg?2jA" Cҿd Uk0qRǹG9I>ۭ70c hRM.dƯ2ݱ{?%?`wΜE> p`Ϝim0AB/DC=EA!538PqFLcGQZ಴nM䜧9H%v Q^:,p9y,wYƕ+˛0?h X!Ać/ Wk c=wVV5Qii?q",>SQeCÅ|E Dtxo3>zcʸW po&M_ȍWsi9GzNYaJL_= uMkiq Մ`gHӣN}#Z<O/n{*7)a8g7*z &03mCgI3K+! !忚F1!J`-S*'`cLo;4":;3}Tu?c*RYPG*堠*ay>_MӄQbwP-"`|l0Nԟ%A}P{RN\h;'ȫ0*|/b]YS 4/Xe˚Yì7A2Kx۟4+p\ C5 xѢ7@+2-Q@IDATlS^/+Wu UV`4)yzyEm۟'iӺUT7~y'4v0>LAc:NxP /|TAuaؽ';s9֭掮h_ )SksƿhO|wJMXKe9*$~^Dh!ߪM{ٸi.,t ڄjg4۶nFސ2g?|2*\ !9Wz|m?c Y=L`n?GQ~.i(ضmڈy?""gR, ͅB{8~ƌS}0( fً🹉I;jstCߍ 2Bh[,k7lQUlI -Osجry$UP ]~KjTYAL1l  |0E}XJ 4$Zddzc4n7,yCq4)@1 Ե䆚S:/sOSv٤BR*HP6 *b10MmUӄU j}x ~_9A6_#}wep"BIB }z|#CnW,en];Q5]駏T)̻=¢։Րr᫭xң\:f?=f:Ʒ3:gUcYs_t,o򂾧ΝG)O 1ǟ'Xfj7oIN=u <5?*6TJi ClF{7.Nbz?O2[O ?Q_cW+kwk5蔄 s'8Ϙ|fGDuT‹_Qٵc~&$?2*ypgTŞҌ w.]'9 f#{*a@+ ֟QH74nEKcnжZc&̙ dBT}{reJ￟%ͺ ,WGSe̪}*Rj^A޳k9ZwVQ#AЪЧРqhz;4{WSRH)%K%YEڅP(*ʒ.RDٵٗwyOȖxwlg̙3sc8@ @oa/Cxo׺F-d{WaEfOUeU(ʢl~,zou-2]¹SO׻t쏻ۖmV厪Ԓ-GQ?)o乏#@e ԕpc "BO/(wTI}YOX^}߿(֑\)upnXR@^rH$Ew{/ԟ^1s.gJQr& 1$Ə^Yc85ʦW>_8,hc+_C5 Xd|3s'=_U} v|.T{ 1:). o 4AQP2ѕ(^($|ڟύ1uR y88cڷ ."?RfzsMmlVJNxFGEǠo" ]"TRaBNw d;AD t^Y7 "p5_ ?\b -=|Z :(IBCH{ 2%_~A y0pN#{*lnAU|1UϝP}N1SC|r-?N*xP. ֟=^ƼK/]ڗ S?+v5Ѩ9y*"gA$#'Faج"A YDq79`nf)EߡC]{U0&j n4(55Dt#> i۾'nZuI<)p!l4îts:]=g.*==*atw4WG41;_r73c9r_[(zxz DF¸d r|fܬ8·>71mWi#!! .o&?Fz:!Ⱥ KBYÆtӐ]yj;h]nV Ӌ BFAT40cOQ ߑL 3/Ym۶AԨRLOו<+b3{У; k/s,J4fM4pNÛVth~9]O៦ڇwv&Yw}헗4 h4?'(PㄠGԒpR*q/`ϒv;\i?o$G0JCqm@ISF?1/$|3KaAM',7HM { -a/ ;p@A OFΣXϙG<4PVAK/ՌYMB¿f"rG #Z=W3RO?͹C=£#JҐGȽtIR#& 4o`^.7Màȳ[^/Vvm:t=ם_ ;VWhK> cǂoCO;ڶinAXϮo|ǔk\0y?A8w:Bc;lEhz45 Ju ՑZi2I .L)wǭ*c1SoN5[#Uڒ A"6j}v% pӧ4&_]Q(=Qkm;t IP-3RG/j۲4&P?'2OA 1TM>jivڶvM[Si}CS?v,̄p9/6RT822w?,xo/CR.{GGmQoo3ɟZ6- 5?{L8f',c5\kD:b^G{e`vck{/޻[kG:1|0mii~Y? ~*C3[CH:6eGvLZ'zuckǿ`ľUIX7pηK~8a#!Xz]t'`b.X`'hרcZO`OfѢ_ ְdq_wwU_z1w?]-1gzOT8d:qɏW^ZT7Q@CO"4VuuHZ}\GK>QjבC?Daq[{eΫ~i()sq[⿷"Ts'w0wV{Qu¾ȡ)q21GNnoA( v}q5u^,6̿',hTu?2_ Z3dB@֯yqWp>]W~s_*ɨQ;o!z'AᐛKca/?܋uE.>31ŏaQ7t7bd\)x6hIm oOU,1` 鿐)Y}$/F!((Ÿ-C HE" oDJ`hHm0ο1MϧnB`,n ̙J;^WJ_/wT1`B8 2*Ο'?M6.] Ĕp\M6V &_E[RChҤI1 ?'W\O*D&GdM7kzGn8$hQͭ'hkFCw2 umH1 /={EO͊Ȕ`&0-e=,@(Nбp6V$u˖Ys OF/뻮wޑB҆EկyK4 W^#/ .w.58r)<2w}݂?|X6}jVkq"QճߖGPnpEt2|CYѿV S?;Z4Df5[-Fْe .&{){xuh5-nfOq#li?UdB!ЌWWD)xO\3 =9j5kZCzd6*iZE4-sFb{CH0jb64C}q@V y A>oOWLd[Zl0 İ!rbLԩ\Zfs(qW ioVLBJqj$<Կ,yrG0! )C)0,aIbdOߦ-Rw:G3GL Sj9#}z<0RQWa8fh  n?_4V鿶[ nÑ~0~[ldWF6 $S{`Z;0/:aGy }/L; 6cw؀ zDD۞JQE DaįO{ J Kg\&OnP 6UxQW P(7Y,R ~I_ tq" _`7au,\>I&˨ϋyxq9L1F 1q& Q3x;qH)oߚkkrYUbPPu<%Ÿ:  xgbr?Y@qIwT+=Mp{9.&{ɧ\vjw8㘽[Om\ظ c;܃ZZBi\U$JEA7UFU\] j6GBᆪM[؇l9r {O$H_|k['Gl#CFrE@[ہߴ򂪷tfgMFM܌ |o:Xi%[pf7a@0 T ) ƍww[rH ϺD`!ÆnڡR%2d "aT/}qm9Vy=5<H*b< cTAPEXX;:vUSf Yp?<@pV8X9ì6IX/}i OZ1!?1`7bH|C4srK{s54`ʏuiX 4%@WC~ҹB#RElpG׍h_Z[KOFۤz|WbxKYnAanP]qVa[@7͆024V)+aFڮ$O2f:57&wTu?I~ ;/]ѝe62!rc~n3-@zxJ%r@`א,)?̑QR WFZ`,0f+DaiĐUjyo;gl26@{6O{I|޼CMvd|?qMLA ynlrnyk?wzQO^hT(_Z9= ,0Px{ɑ|u駉iɟ|SIؠef-BJ,Oon{hK!?"f]j=zzH涇D[C@M8 &gk]3x'Mh?UdhOf͕|.R\ &T\&z&6xg}. {B_F >@): tк8H|F>Yԑl|05h*$AS.47n1umf(8M&D'Ġ$#Ѽ߰qz© ?Ę#ڟB>p[AK1]s@psˉD+J(fd ֟tg"5X "B,jTC07݈(d#38 wGOn--[ߤsaJ*z7a„{'xʏ@/}wkhiS0UM σ ӅZ\8&5OE򃽡Q;BJ  a̞*f>M[-@rTZaQƿ' #ϪU ͢n ֭۟zvtbà7j ME_wVXr ?e).ԟ8?A,_hK q?8@@ӫfq/ Ahpϻ=ޟ$Ad5\1WǾĉV) w.BMA0]Ӣ]-QUk׮" Q? rM&NS^G/%H?ZSo=zq |[xI^zoO}+Ћ;uB|]7`Ff͂>=ю7jTJWSs Gu͹}ᥱn54Xm[y3ђڍ&,'"tG+ ɠ3*chTᎪ%vE0g_t~0A0q1D=ԑ_e@78nr7jxN}OF?*/ !haW<;I.@V F4})~_~ysjʀ/IU7d _fSWlJɎ^X:zLt!7eJD;A ~{ r};4OFO=+?i/9˖䝚܈ψej)~Q?>Y8B5CЭ1='ҹ5;GsxM_mC`| _݉'Vq*;A \1ie0a*) E_/h&>ҝyɮ8=k;]+7/T??8q[hn4g%T) {pd/v„oH}xpwCZP[~{iޥw =3@{/O85csx VGdx ' >lgoџ^}AE+qmM QP%bǓ!N߷| \{[RKZ]=s-^̈́F#@썤ݻIe\Ft? LzN `:ukyOL<)$A^BX7Mha7KKOFPzx7M{_TcusR^+Rk}ۯ(#zqY.um]CX9'~ 6O Xj: $Ï~U#Fۭn-ߟS/Є!' }5kl |nFa1H}W|aS a)nYZ0{R6cV~n·.#~ם]5GA:ck9`!#/UG0GAkWSZkL}r[#pᎪ 1]!wspg45opnr{RHXfAywTI%79U`2c.@DdM|&%&R%FPÙ7im#| πVˊN@Xu:Gf3~!+Qup#+$B*5GD`局kw֟E?& >}Fon Ml*xGL||bkڬ J 8h>nnH4(jwܮxQE]_(ӣ^`]*(IpZ-Om裉rV&A O9eHǔ{䒆x~F'#W'9Hp6n]8g|fƧ0S tb^VC$"WokMW 6܏{r|`dL\y{u̸-fp9(%A~{fLUmmWy. ״Uuz݇_=g2|b!@T?quc+UgO\fiP]|t%iT|˭^-Ku KQuUEvOax׬qV890;C9Ʃx_#c&?ZAb~SrE(Fi`2I HAeyy'"[CpzkȐW]q_dy9QU`mq*8Aø]^}_h1x/>5([~oe˖"<# 2 E׬uB UR-?J%7iFk0oMn&Iɺ{ :% MMohgn"_: {P7w[ccqDCgzFW,U?y==pjLLHe/#Qmm_D#U?O4_8ŨSaB*iXkfPwMKs`_L>><0 ϗf~r28?r"2noh[WOL)}E{x, qIS<7r4Os]V11};KrHEb >ѡQu4peK󏖏%/C۝bln{1zO3>ߓ jq2(\΍HjȽ->!$?NUE+|8x+^u6M/_AUgt4qS.W4<^hXo!8 3ZZHjX˗wk6hCsq 0T G%m*)s ~ds{x?֟~tMw51w^¯&FzqboEH`Iil8|!?Q*iB2b ́>|;S&:QHS-)gʀ^O^xo4K[t1fŘNk?sCi2qJ ai?w<,r`- NNO>B7k?I^{m1x@~T!ZҥE|lG֟FnĩԬњv#{DbƗRCŤ^l_/>SZ] 68WO^|67hP.ɟx#4a0bO&cW>Xשc{o->aꕮ4&N 3hk?yun&ob T7rvE3G@ol6)N>Xӟ>p/Ұ]/㟶x<Äf [lέ}vdP 5Yf5LOV(gB'Yԭw,W e['1Ҡ ErFrG˖4a‹/GMDEA,W/C@?_1N,׮r1mjcA[cHD >(ݽ1F)_R0A#&;a)~ ( ¿T̋~|8hסhCgV_/Y# ^|eOvUM8vl/շ 2ibPM.vs: IZ/S?싸sZRAgw6r *7O.73sޞ}%6qjLR2Fh0{],v!.heU G>jHd}i2ooIC20S<$<-}0mN8Qpc{ɫ64f?kBwړBӡ]rU? ︅?-B1Č9n4#/\cRP5%;CBƊG вC}e#f:uxBX 'owݺ^pӾ-ГFÜ~rewW5iӸxi6fJ_znͺWdQwݕhd#mmc9?,zVn䫥<|CqW6 C؃4{wq{s%Ttk~UR8 4;Y0fS7ޖo_e.Ϥ@ B`zmwK&]˪O8Ge9wG Ϙ5?m 9wO؉XKۖO;7[❘0,m+C7%X꽪،<5[-eπzaE;į/U@,CLO?{z3YbsLlU`I7߂:1ht.FSOmESoV!E TA[#oas+V0ȷ_VN Ym!pŸ`s%+ R?m dشQN3nذ;W ?JCqM`Z/vipڄMjtrlJ4+Ol /#O'{0T)K8HOuQnS#,g/֭]'f+Nv$] NT٧y}rMY%0g4Gd2!\' e3д \%!|@_r;Y ۵m뮹$j#?M]n88 &æ֌_`ᏥK!IAbO yi?'-4A qXP9̓ٷB0MD\"0I+V0-8s]͚5]>ؠH!Spn2,}Js+kŶB$UI ^Y=FG@!AҴ]ߓ u@oWB!7 LR'%fUB`[L*?vP^t 2G~weyI*0/b?6M܈nٽ~UQ]ަM[%?/ ŽG/dO9T.pS ~KwSgCOC2v5fsGVI?m/Z=-`eca>0.p?mO` 'LYB?2嗞-OAjTALL:RrGW2PN@džK8nˮUPE|Q_]>5hZ5'6C C}*Sw,WM͚%JIDATe7w71襻gY:w~AX< yr}Zf5Nwk4|l!)-de_j*׻2[hJkTAUsoϿ&.Ͼ\ZB8LJ7W,[~*hk ӁDa#G*Dİ'[z#샃@%>/^ 0uUwZEy9(oi/dTcN/i)O;qYߊ0GZEF/bO#%`p̀ ea e}7^G!U#mO ay ~!?' i jV;].,?w]w݅Fn8QLOf8%ƥ.-?m/]L^ ؂Y\JH3|> F>t%QIK1vc3l3ols8q&K7}?AT~>:QGi\l"k]qK`+W]3 ?E gT}T?x$J U~ǢolH\z—jjFQ 3yw&#ȦzЍ~YpD0p09@*k?v{?;.Z’|9(.̌^܀TWhgbzg؋kmٛ韍=s߸Ƽ.ty+|߮dl99M1Xq8ᄪ{&emS.dm{u nPYLJu[}/zF/'0GrVH FDFHr,Wя9xܠWhޏP]Lb BR~fG93;X.wVm T ߩ}&:5ԕ~>z0/?z}w핍pTD3.}|̊?PnQuI'HU~s#F=Vw]ί{.WaמΜ]?ʧ K6UϣnxtSϕCJn QHeI!i{Ucɧ5~igRf#}ObJ2@$- hBim',BC~Jq+Teq՞^^2lşaCC} nYT.T}ᇮ‘ĿGGP5\+m$DL(:T` lfwZ3p,|s{׬y !:oU|wt bW?HB8ݬPv8{垡rGu+ǽʽ Y۵/3g!ogp)lzR2.##Cep\z!9!~HǶ;K$J0xHc 8+?+<sp"P]t{,c(E/>Aۂu{w/?}ѮA5'R=BHJN,_Bɢ7Or*ҵ5vrÑj]R'*ŗ>shC[ʧJJ23%gΜƌM 1 [_f.wRm?Q+V08oנn]Cm)? \}\2s֭S^x-?y_%O?tF\ME9rqJva/;w{F'_ĀgQo笹%k3gٯlwWߺo6`_UV=֕,QRvH=%Z ;x}7o6t\ƍ]뛹yrO>bù^{ & ÇC@5ʭ"MP {{E_&=\0"ve?_?c   JY"86aWae'G+q%{L*$Wp!Ww>(Q\+X'O.j03ukׯs˗.w-X9{[wq?Թj<|Əy<{C筿2pGjT(v_pث#`*5pSM!PAT"")@Mc02zǡя!xy48|7_ >tׯ5эl`4VΔlL׶]{׬ys$OsEus.dB"lo0O9m[)=[4t+׿e_;Z/v~7-seb߄oqTC$UywlS؉&IF/O4u?@>W1㫸BO?efm?g[ 7@P(q<9/{JT*[fhN c~| x0~w6چ!"$K44eT@6BM.>˿)YgGGw49i4 FcͿap.4ɝ ŏ" qmv<i}bşn͆ 訛fޜiTY{_:t/}ǻ5Ss&JVԥ*Jj?ް4K4ҠQΌT/ ҋ@E|LƐDP,UpU6'f)_Z bJ6"EH塹 F%O +1-7o2Q7n86n -[NtWHUuB`?6v% 2wtKАذ7dYl7OH"-ch7@@mH#;'AK?O:$gg]AU2B#xѼO:) `H~aM+:I[MClA>B>*o$ǯjhX| >p0CyD)@-?ȝUD킹[o.c,xMD"W湥'duZМ*tP!W|9w 'jvJ#J&}V\\kY+K1ǿ-f6Q?6pDO2pfQށRO_faRɱ~`R@eF_ ?616Mh ^mCl58T . 0anO &^S})gK-Wdhg$ue00#qV'`Z'^e2GFHc mE(b%P]_r[ J3yυ_@T`CJ\­p aW?6gџh8%ۙmͿ6 m5/vf̆ ש$ ~+U,BnqF0G"M/)'S.̀'/DapQ8|{ӬDՓ͚5ׯ[æM*q{3gNO}\}uy: -# m5cK_)2( !6?V"i  A0Ϛ#XL neA 8TE GW+tG3黈/|b a#}8L!J=^nu hdO@04!Ac/P#6-]=Dޢ|5]i1' w?43R&Sޢ|P#$F>4O?I4w̪* b$*E*%/T+SYŒAJ I/#JwLtYSZB\ EFi?Is1WJk'E&Fb\eQ_lh0-6kG4&P+/?6le_a~?0E?yf%\)3p*)҅ A&hSأGObLnY+Sny) "8EoX>RT"Q?p!b3[ Ɵ:(}_eߜlX?uƄI!m_l a #GW\cEAE%#U'HD8aT!aL/y;Mg fO!laG0L#hͿ`'9mH a?lE^֟9T+,ќ7w;ćym14Hǰmo̚PJb#fCYTb<)?1a*|pG fArШUZE $隡h0g*f+qftA4OOOﻊ x 2àCLa06aͿ\+NipKr|R@c/[OG֟[!.,ml0l_bϹ$&D%03L\Xx+d <}b)4G2wT\zq<9 ïm)s@r@dF&ĔP /~GOOq&b|ÿv%&?l?Č 4Po_6k_bBCma/diOa=j_[ZDmm DA&T](|'rlm̜JQ%#_<1SxCJB6$x BPȋUteaO| @R8HăI)|"HRJ7/c|1hoƟџFmJ҆!m_pFO.8V6o㿣5z9DF@3Mŷ_%CKlY(ig7*??~9鿐呔̗U =BUp@].2 T%*0*\Se4Y%)% aƟP"?$B/cͿ"tT0C(@H,z|i?td?$#_\mogc^o?*otoKv7?f?ʗOœE/!`#3 D,I?S~FK/2(P@F/SrzaӔ9|ʸ'V:PHoɃ6k/P?2co\9$'la/[;NJ l_l|C|ll[vo*iѕҹ$x%4OxY>5J2c.ֹ @^$~i;6,{.0SL |ÿdpȘAG|%F⳪_t eQOl7'16ly_3Ol10>8D43c7߶l0K!sle/[ `ax BhTXe܅;>~"ɷb/͕-S E٫_) OE< 0no/"ih/> 6Qutg/?2ʼ*)D̃6aBa?leOD[WVl8N`\ וJ' /-O#ӵZu{r"¢)XUxY)gtʞI*S$20oqGy.5;1appk#1zXٰU3kF&0I?/^0Y@ȗQaH&g…agw |JNJz䏓AG_p7rO7v7鲛d۟^q9aChm%H'=ͿͿۭ??6nߥ_%_4OvЈ*&yFknK8;r@Ed'8 ~"O|VpK%:׍?_Q.P^EWr/C 7to 7|?Ϳ7n#8roo0:p럦p9;OY?GF#+FO࿚/@x0.^em_n))$ R<%_,h@Z-' '̙ s䏓 ght# _tp7rO 7viOiGU~???Ϳ9r[M2m RQź836w_Q ëQὮ^EqrdɤL:BG<Ӈ3G(L'Fx6ɏ!ڕ"!)~&` ;@]ai 9䯎лDّnnn*['1>4_;Z[sonu@fKtV^2~O2oUazG'NaV82 c!7B^DfWmмB`py)=/k ' uÍtƟ :J7vp®!輞r/nŭ2 [ro fQ6b 4$OE@ kak}ӀQű\NQ /w瞬X3.X06mREX HKO1'kN8sfvq_nnK@c[sn#ImEqwTqY0OVF\jlM'CQ}UfL@ 3_/l5NT1b,m^ UFM4i(,I3r ;VUM!./T'G3pAC?A\d?98vzC 7p/7to G7 9"Q΂l_n po7hpoLjέ?}rs[u/nR?lUtD <\MG|5j~;0y n?E^<* \ "g8ʀ&}0wR"1wLߵE÷ Pf'8s|:'ʹ9TNu7rO7?84f7 "Ϳ6Y47"Ϳ[q/nŭ?a֟0Jcio/OT*4FU&$/6#fUX͙-ne %P߄h~Eh8ci0%H,l1fxoFF3OV#_ 8HӦ>@lTxcKs']_+ %WpO7/nɹ _'%֟G_N*@ Bnf=QUY9R !@d^TQItvEHdމ*68DI#i;W~T\Yr0<uT1kNuÍ0FІX72(l"nS:71/;H87Y[y Qv7n:#/Tf[{]1I8TĹ@ÓkӶ(rgSYtEkWEzEqdy0xm0rd%fu 2\1RcPy$6=T PlM>>hi)cqweޯ?NBŲQTx\bGY#:2<_2Jpd%$cn>p_yR4uuMnEQ_%v + O0 HB 'e[pǟIk'؉rʩ8Hs .r+_(qĕ;C6kF9?e:Hc۔yGP>\_=\__T*RpS̮סO?*^ky):eYW3RE W&kOAoKtdP\,O-$S:Q'o*-LeNGE0(Pf7F `׬ߪ(WD,vX(o*"k4t(Q( b<$9 ;vȒ%Kdʕi&9t萀3"KP{]^C+|[ҤI-9s< ժV̙3 ]_RJVq\qkNx*\VEnA ?zwO7v7M<77r}hí[y)O?CNlԩ$gl1czI&H~Z3XXs* n3rq9pڵW6l*ja+^Dʗ--I$|u7?6SQ>.I])tʛz{G6H忈5 G܆iF@PVx̌V"3VeMKyM*Xjypjq,Ď[vo!/,\8?j{UfyEV%_#ұs'Ɉ#J*$N];/῕͆oL 'qNqo, (Lt-/n_nƟnƟnyMϟ~^%~= ~XW-\Wdʈ5[ I+X޹}jeoZėjU*J"uֿ+N^s Uʛ;{ hL`i~К &9fQ3O[sKID6U/AX1Q1`W1p3$Iտs_;cߍ/fnMrn_nn!8|tO7tq`=EE̗7T(WZa knU%9Gyfv_޿|R}F5\OWժ[vYpc/T_OT]"#ο;p#DM] |w*-NTEtu#;Y@qUŬ޵]ZE.BP^ $;uҦM i0~a߶cL2U&M(9r S!^'!cI*$MԯuLտWK6?ț7[#,dpƎ?q7ҁM8䏓?N8xWy$IH $];snq}ȌߒOŋJ1niںۿhoܺSrg^oUTY g ]и&AYU yGӲ!MpiU!O?^sQ ZcMuF~7N;=\yL|8\RN+s^-U*W(L`x,n4lHvC& _ɧ)Sf3m:I ϼn%*ΞqcIXqn8/O/\$'1#Feȑe7>.x_Pۼ]N?}PҧOk?K> JuP<x$IX~\`TDqI3FE?+LƏ.SAeV4bʪOZPW&ї{d0[-S_7p޺m+Y2jdM󟝻`sdžMXc$OTIjDE%׬]/l޶S!}W:)R(ԨVY>u=b T>m?،wulYH8qn:(}8ѽ6nmD~ʟPSa!CzZ.Ora^is+Q6oن169z,o%9e|{s* 3|+Vk口Lʟ?E'4iXOt7bV={oK=^f_ٞdwZKWU/;s?GN%q^ҼJ*#7(ϻˎ?DgN &HϿg,J-mE(;+w&Gw:+s  Prfɨlu_0:_ ~|g:1>߭eeO_ S$@P*偹> OeՈѯD 'rʉ| B?asgMXDXe?L;Tw_SlT~бbԙPCL2a(,YJ&M;c7#/>EXM~Ÿ&?L ¿d۶ZYH:{>۪4h=գRb9iMKgj,M?5iPұx#ۿm(0/Qlj,d ,:Sj5ٷA"gzƈåR&P3;d2e±%} ɷiA5|LzꡥDÒđEʛ-, ?/T 0WڡSPbp }ZڽǩS߱Q`}3J ȯQvѵǏAY_JJ@i\?ʨףPF[ *Tu)/UֹxZ4eSCveJSvW >Pʕ}Hf,[by*_Rwug4gE8FnYyFX#V@X,d{&8FEm2uqRO?MLeD _SEy2I!xfL٢Weի 0)g՜?00r ߹g\bUهJˡf16?w/] 6P#NQ9V+`R@wП8)Se#L^(QB?&D脿fLw!k12a!iӥTQE05Y$m1dɒ2ao*=w\䣹h~1Po˥ ;2@9Ѣ7/-[F-*L2g( 2.LFJ,*ڄkjDyFFOaYsg#;H cDf&C^7ZyTbD=o|~tuqfOE]h4uwq?@Jz ~BG\Q74qa{NPsIEU|(x`ȈZ۶…\g `$3f)b*`: w)v"% );vSyF 1 \k!c_Zj)y ^?)+Q٧A>Jɸe|ޓG #g2>p𐆑GƎ7onIܳ L [#5®pKˍB;|SIWR$O&_/]+^k\ٟA8Ѯ"+̿7q +[P֢o/І0`GEvu_ٗtz:5"ߢS?Gc8RJ%ŊHQ Eoߪ_ԼKRۡ{U>}1fϘ&  c?ڏ)uTf諭Viⳛ&>]cj22BaյnZ)yo_.Jl |~ o"6WH)kw *by#dY^3*~=Z|O0glB2'ʼ2_bhUTx3 >=ĕH 3g.At8|c{N+%Rjq%6lacpJaKJ+;j{TtYzb+wN!Ξ/7߾cVC{ܓ2?;w u=:KeD/4ygz&Pc_嫯Æ_~ss`6f͜)[4ɀI$4WYh(#8r`b9Po kYO<8c3k~$IqW'2ڵVE%ɻɭgA9F`}0MxwJ4hϞ%qQ3/2VQ@Y\^go|"I_;*OUy.:qj=Q<ƌ4ar!J+pBq8Cyo%9 k σ8+ppSGiټFuyc#՛|wDN_!|#&C[.[E&KyA '{)iqGZb'NW]m#n'͟l yg{sEw5 VcǧUK3VT1폀Y5tQFQ7hQLC׃7\u_˄U1YȎ͞ pd [3'&"zl⛬#="UxB:'`|eI1C%q„=GL Z7khFOgpYm2x$Uaҡ]K‰*ѵK;1-Y|a+T@HOu|Fb*vBQJq\?^9v<^yUY?J5.{_on=P&O-?jrnE*8-^c?J&L :?Ć761ȡ=iT%hqi۪n7C 6˓uW؄3_UvjБ wm߹S =%E2bK?~-oQO)=K,!oDJǡ¬ gP * |V󿃏F0?d+}BjT2gmQBJ:"i۲u_QqkdcQ=R*WV4^|-4ۢF_-/2n >[47B*gz]W aiع jҧ;ƸWY7ßH^(lVǏ%Y┹N _02 _ɥC->b;0Ԍ_X\X$ |2-y_+%^lfSIR5g}`IwD3"_+ߠuyӢ\w4##'Jr⏘\D/{c7'B8PF&1;1×BZɽ|ʸ'P:QE"B|M?W wRm<,Tqqß#YZޞݑ&p:i'*" x|Lmj_$vEP&ϰ׎-#SQURE'Lvn&ǎb}8v%,Ybn!s>yN,gTD Vʕ{Hvz&>gY>Qd_ -v+Bb!+[xT Ӏ# ?v 4ڪxr'k֬0^!b$w!>۷/ +ߋ] P$I"SDÿߊwȱo7lPz|9\۝9}F3Nn?i({ ,yyZaRb2zGj L}22^ XԊLȦ͛!6yV.-'0٦٣4."㢗?LU e8_gI& sY+MesQȿRs04EknNZLkҸfG>3O I~G> .L>\M>AˡCL(?;v;t2wP.X1#G@&%]zϑG1.vĪq{UOxĢY@˔)_!x]3مO:$ϐ;M4%}˶؝Ut忭`WN8SXٍ`-'7n܀9{%n8PgSOYc&4SkY;vᧅ 1ޒwLF&0';Ic|mP&`s1Aqbf ~ISP4ӘD/?/vτjhGUY 1V['JG>"W.%<,gp;=4ѴAQ?k^a/N4`9XZi?ImҒX" ?qB>Xޔ0S E& Hٌ;b?LhswW9VܾwJk[e30:NTa)㩨#DΜuE-7UȧDX`lQQPLE#>|wnE;R3C=;qoo=Q('0'c$nk]dV=`:pG;k`_4M~m5 Q kајGP^}^*xRHT؁S׀fAcᛰotD$Wۭobb9vȟqǟu(4p@?I&#0ڳw/L~/q'Q1iq_GO"?&m7U f΀58 +0 =cҿu VOl_ UlRH0q(yV,9(_[gv=)uJ&#b>fU襊w^ bIRɤcw*7 >oIy=7m *wTE@"B'&Љ*>M(MpYa0`Y>@I,ui蛨&c>Y`R`bD~5§NXVURAyhKχECByLԬhuF? ǝU&3q->\pI\ryw^zL;Mv˛ i }2&)-]*eʖSAk6;\fO:`!㣹sfJXx'L"'NDIpE~_}S'L$/TTу&+Ts}z%_ 2?܊SX9u7`|a֍L |?z\J-9̈8")?AEWCPtbfj5<d(Y[ _,+ch);`Kؾ>+9k\X} >WX˯PU߃wcu|_{ER3#7k)iۦU 2mky盯 ܬ#Qw{'~A<FgꎝA)4GnJџ~fg&ySܔHG7hB<,H;dCFLF ?F=TV<3g,po b,f5o2ſ#ěǥpGsg+Ly&y_(i.AQ>k/dN_ҀܳU|mP<0p4ZBe A2r0TBBTn g1|0B|*/t>0=q?_~}Uek|C&' %kE6ע8}ԯ[9"[l:>(&a3+RcM =LFy>P)R_(M⚌E<w9 ȌYsA=~`JȮG`zR0O@(G[@>i`cwy XGjH(3Q/2HFJVz [ĭ^ T pOM >NwBZ|TP:WoT_7غ y7f b#0GhR_}㆒F(^zEğyصƌSaWWgر[f4/X{Jn S`3ͨaLR/e.Nql eFWsbug7GSwVq[^ߴQP ۤA]&'?lVxϖ5<׳G 6fd9=_$FxRL);6}(Q ߺySI{'(7 c`d)l8Q5evzJEUw9й'RtutiA5YtPTXVzyߖJ4P'@E> ^9"M-D}<7~l̑rE3ISRGOӧTNHYL={,y4_G Ǐ=j& Ir(N)QsO4E(1 Կ௙Z0YSX8/966!lߚH?yzaq-684#/ W:aaAo 68ܰGT#`SaI_mR6~(Q7hAG+/Rz%#S$g]ޓ`Ao *lDx"l@IDAT6K[?I}~GM-0ƴޖxzU5Lrfˀїy w _Le1 XA/ ¯~vEMG`qe (H-(~TCM^ ?2aM\L0|yJ$cݝntJ^Fi"BB> |ܸq'D~g(9KxWInd6ߥKqSg0^=#k')Sϲw;wsa0˲^ZnSP Z~< 2ŸƂ8AQ:pFU:DjTT ؔϨ)pHRfL,Yd %.uBQm1ӫGz B !N^=3v>XZN:}Eƈ>h{T?w,e%M?M2Y3ԍowSOwěse'ASz=0<y7kgD`uMgUUT0ogʝCc!K{s$;Dݓ"cp3q >/3W)@ɌbIH,c'pJ(n*0i?=&DZi"2Iԡ _=gr_2u&"R~'KJxo8O`3#>oa!c;!N6oʼn* rSX+7L"9P|z>((";bLٳfظ+Vl2a%,\]zhg:YZmXd8t_ trFDa8Q3#xzKy,D?}{Ӫ>d= wyPtNSj2JAmWhj>yr>/)ԲP05m祁e'N-}y4g0|MWXQy>/K7AKF+oqjtE~ߤ OwBO gX)fc1g3l JRAI!}"}ztQ`o(كg*l^`el+G.hi,@.ٳgt.܎C^/ *Mk]A7jPh,Ǖo?- C{K#6;L8J')T5n]%k,S+dFv3!k~x xxO1ϵ?Dy)0 ߋ@Hb~mmiſmҬRj vu;hRnpa_y4ȚBU߶hj% MnX0j⇇dr0KȷߓPl&?tړmn }W+ ;#>{As@Y}Vw&$ bSʓŃ_ͨ-(_YrPٍ# lԋ c_U Uz R|"̄THe6 2ҏb m'e"k.%X~:`F2w. Wj/҂$IaTW@w$j%_9[.'OeUټ>8QeWX4dоiBذg|y?0cFM|$'Aҥt' I5s.8 rO<&kMVcghUQEW 8Q7ĉ?p!:玙YӠ;y6V %ިzm$хo>猙3-LϜ _ .kRDIKd:Ui>a2wβx_"ϝ+#FQğw=UD4_#jEA G-vĻQ'Q/_v B$ɀ.2 fo0~,,~ͷ:߼E3 ɫߪs%Xߪ哐YwÔ^>c1#C)Y+ߞ=5 Z˞=`qc@ ?9w*2,ͲIBd_Q(3NzMbauGe_O=%Ca: 'Ks`˄e0./t۫+'ɾNT'Q1UvNDO6Ssթ]S۸~LX|"iSLMXX>#[)?8jJbwV~Z/OEWT6;]j:+(|{O?Wنi4(fΘ"`ƭ^6̈@ti$頦h CN$ NoP.8q fiOBa^OYjÖ́/-[vl"^]p$N[ar+kV婱kġGd,t;q晸ii`&4a8&Վ!s2nլ>yO4O|x_J@K~[|ȠSVw{OдKRAy}ɝiϘ,_6-|?wo#z8N۾ِu;xΚ;]ux(1zf[i/8bKPXkDWCj\?a_Sg(];?Śl)<cƸ'2 Ƽta6sȱx :V WI2l5r:p>/ ftc+dL"E~$!?E?\j%ɂ8ty]yܫ=T RPHz폦b-d,y3a&{|;$b#Omǥ[/Am%HoϾFhsܨ!'q·_[;voymo˶튿UrXS)ہڶyҬU%T 'BJ*_ЛwE񇡆/!~<__![swvLӶGȸҩ]k >k-ZUT}UT)1gʿU'bŊa#8`jq'g I;䑑m~c3yr] sO?\{#/Q `u^{ͷ$:P\ [p_Kf}υEAUQf 8l~-d֭zAQml E6(UO/PaM>jBU-uyL6m*ݺw޽!.oqDLEڶmݙ/ekՂ,] ф>,pU}XQQk'XҦMk=5gy/!W0QPD}{"bo明\rX$0̑Rk]i޼ +dS{,2j26t0sf\+]oΝ,>Lhn`堨U^Uq*|6w-_9JTԇd[ni+c U~&Bw+N )/]\&6Qi'U4\N͛rbp l$Gũ:HiKFUğ#`:y#G `_-mX{*0wNB?~Oi.E`oU'D\SQ0r6ԬZ.2iuy9B&ކ_NNYVF(COCw`89!}z@EcOpOGZ/&l!#"L* `&Pɐn=ܸW'cZѭk;WFW;yאISF[nWkh+~T* c^8UaVPu{>M=@:B8tMDk{'-Q}W~gdtԜb\>=i(SX_+=w nI,|1λqK*L-<1J P4fȘ^=Ӈ??glȉ#͠>o*qX>=bz7eެo.Le?i,_A%kj;1W;`7w?T$j7c85e\lz[E=|x?  J?n89ZV.俟1ߙsglJM7W;0Ǎx'K;˕6i3` ڵΜ-ZcIGZ0{ Qc[0WFܕq8_GHG9]5`:8 6۬0ß EU{#ˀfeР~Xcy0-UU#x .\;ZҜ3|Nm&j]zXs5-[<K`K}4 Bn; C|%Gmh >5A# -Z@Ÿ' o_C?0s<=\ac;V߉8QQ'M .ߎ?.vۀp~k1'.H(}AдBJ)/ ʢ_;)D<(' L>pV<6hҬXL:I(HKh_MI=_D唒 5;NOO)Z'>i^'״=*iE.E=L^RwH목qR+파i{)/ %$&?Os,{~ F,)t{I, Ro(;$:;1GWvXD]TRE";:7A, yyqwOd "ՅRS_NTQF {LJ*PTY{O43o3ۥ0w{2`Pϝ+˾Zӂ)>BB[CǶ?N^Bƌ a>'_ť7CWFCXD+gj'*H߃~)?;Upj5@¢±)R\N:bd fԺP"㤂i/oCQ/Ա#_T%iVPUre 䡲TҥqFaDSO5Oedŋ?ĉeyMg Wƿv 5WӁ%h_q ӼߛockKÆ ^6dX*#H+@ `ogy XBBŸ>u 꽰fy#>cNFS4݇xF<:ԟ|j.Jx(i+JSkпKd'J:8'*U`Uwy|X'|Bvੜ0Ăl[rTbiAgrD5Gl*/k}HFC*iE>LSpٷ.eryͷdQ |A8z0YH|4i,]@7N|'zja*L! Jާ?ͷk!'+qr4:+Lfi<-xKWk?uv 拓҈U0b@{z81B#߿O>X('5!Ske je|vs>˓Xjm/8 uFhU`V~Z VOw]@PTїmv %@?47_/YcdpiGk<|.+?=.8 `ii0#YOxJ/tSp^ː5+mqK+ 6q=FwΆ8޿T3|Sq/~k3E@=ЧHge҉QO3{<2T;/7Ԣ*[oRUT("ܓa NSi#^_ݜ!&-TTY\¿t* eÚ8H*H#1?q?y,Щ"'OP H>I Z׭[ E4eVt0ZϜ1'ֱvFg֍@Ϙ1$J#oxl,  f΀(HRFzgK^ %+Bw|⊮ufk̙.Zkp-27 L?Ynօ&ѣFx"o߹`eNYYc>Ym&-SQurj(n{@Z4BgUQ7wUCZT*~޳GT4(p.3F`5kTcVocwXp@ъ2+W ߮P"4/xR2RgjJ)b$On-`#Quf-""wDٱ}D9>d@ zU\WE6(nSimE˙ӿk B꘱_jbR?k&㾏5;(8S?-brȡC'U0t S?Ϙ_ X@hѭ+r4LE ؾCV>ȱ_|G.ۊ0# -SN늬X' h駢.,=v` 8?`ZB:uUQE]>&8ʬ5qGE?U3gBхt (@56,J?XVߤIs(x=hd 1lQ:.}3x;m$ة M d횕:** *!'˗W*3pUrWEU^(w= w" իQ yaclsx cΚ@Ϗ68;2ڵkpKDuzxcGtMHNa6F[vUXS@F/L7mTWIҿ  zѥ$NEr.X`*hyO*䄰bm, K+"3!#0 O4icq](aQ4|`#:nVLpdB .=/]]zE&bQyFk&y>)+4k7tUY3Kjɏ[ԩ2 BU01~p qcO9 0U|DEƎR߬QT[Ҧucb?ayҍʟp'ڹ['uDx^#SG_P> B мoi(IB3rp 1pPp 4 z zk]zkZ?E*&| F{x $3U6PT"8 M3yK qWŊSz3'Oz a<b"gه6Y\zo_ZZx/K>LMއG0s 7{;z\PQ\q,؏~GfʅyH  9F&M788tAN>剅[Jþ+qw&2aܹr(~- |<|[ϜC?hw-Ƙo,|pRE(v&=8iƴ)V=׀vLFQb}ҤJ왠wv;iu',Akf?.=w}aL](_٧ '6y0v?~Uh]: &/-.^s-sU*%R1bTHsD!L#U߻I_-km/뎤MLlgC ?)=b1s²ywSTowCZO`ΏRBQ793U \ʶ';UT0Nd<;?-O3x$UO^h4_r؛\Yż>ڎu_^0N<9բ$>RJ-Ĩ"2fsߟ\г^t㚦?|4ū^' H5CU?'tf..Z(*+ RQO"61X-䖿HGn=)8[l^@ %\5j!?ʿQJĊ% $z2(4o' ڏa}߾ nk=\9%"T񧨨"TBi!ҮM[ON2(bq}XTAtW,PܫE]9gAFH w`bܡ?/}*8ѹnL*MǿEHG׷?OUSrC~|?i ėبK+M΀m'~DI t!^EsyR˫U.aP4ůTr6/re5)yۣW/Y<|AgNE޻`G-X?i:v(\ž1$ n[2<ӪVu nCϟvFG7v ͚U*W4-I~2k s9g׸t\10,y4#-+ly^8=̚5'))78h"~SaCE':џ]acu$ J wGyll=ϝ3 >!=R]~޷"@1DFQMMXTԝ~dr"r;;̆k´|#~ܹ qӠ0pkQ-mH V&ڊ+0=ʼntW*7o9#"q٢q"uuk?!HKypo+= x8/9B -C3-T8-IY^i6 Vp,/Z- ެI`7jFFR._p{u %GOjj72}X )" 5UlϴlY6# FUT("88;E Yz5i3cccx7b^1 W 1Ժ Al6a~ޫ1?8i!BK&Nu Wuc\QQ8WoGAa"~%N8[unnܠai _vC+_5C鎐#wy2tx/63'niҠ*0Ň|j(p8 ,~pK-s& ȓ-0u%,[`7ֹ6apߔ ]i1SƗ GʚMAuj`O˟]zG\/$(*ۿ*Aٛó<ǿL]Ւtrj1 Vopƕ{! 諔CT:s^PXpiep;G}ቱ?V?H%̳;tEPF>E+ 4~,\kkt Xm[X&t[ۺ]*VX 3g(/{PImo&VY,8t !B_WG`ک}s7mXƟǟ9@ڲTAH̼\n}.Fx筷u0AW%fɈ v w.'+ -mZ h<|go$B޽XT鍾E\jZTY8UσxҥEՌ)<<*o(-5`4(wC=i-d h%^1+0COS|i⧢qe }\E?%;wYɄڎͿƞQwO% bG;͏*ŋ"-$4Rp+!n?݀xxe"H 17,B[ܓx[߼WAr}ܻ)CSK$E ?6\fCU?vHgEMLu_``;UrRNm8VPn;y\7MyһO8r?Oۅ1s.>F*(*VY3Ɏn<~ZTCů}8+xyPW(e)t{CSzK-eO P?t(,5|8,G xRlX|K쎲x˗b#޻ISX!f{e\ת٣y2kzUgQ'OU ܷj:QLZxFK 4'ht}e@IDATG mߦM9|( yxb6g|߶?1hhW(S?RCcp Pğ/bT *oUnQk7tMᏟG4׮_˰$GWטg&m,Ep5qϿ<~L1_a>٣\V`>,=WZ7o{Bn(_CYJ."N;qPn~,qGamve F eJ E2K*İyǿ}1`Q5bϙf,GO>~./^&1ǔ-K8w͠bG*5,~'$m[pڹ[r|a؀/V3\?Q1{ 3v7Mٙb"i9Ŕ-K&#70Y3寫yvWC8OtP' 4⣴FfnΟ?E,tU,Ӹ̍kp}٦-͝K h󟩓O|OX5?5aOa] * ڪ_T }l kB4|BÏ&/n5f??#><1`fIQyvwܯ5K'O"Z0AB,(qͿy :k`? :SAV*䔋oU]@L *cHfkIvsY={/PALtY>axn_T{;K?=Jc!KݰFY-{n'#pח8w ǁNh8]?_߳QwᘶżJ`xǐO8TlCކ!4RmIE/`$ڔ`QKzTIcvuz6އL!BU]6"pZTG&GʥѢJ]q ?%OrxǿI_R ǖ5J^?痓gL{MVH%N?p&G Y<%<u|UG0nFsaQûlCG:b*\*YaykǜBǏ_]1L7qkԁ"ġtxkˆ_]؀Ϙ1رv޼yʝ[A@J'ACo;z(SZ?իW+>ES)LV{.7E5njCfNE,!iҪu[#&W}O |'{8M۶yI?+)6 ȡ_q;,im,;؆S6Q;)S6 sȦ.ClC|hc̺̝3C{=d(ƁƢY;wcNZ.fƒfSL,V87iZT112uǻ OcZK ),toRK2cIH8 DŒCb@Lj&01Ywm& pbTO(oUcIk?*ecNEWA 묰;z4OpOv4u{5jl+@TT%7 BiQU^I2j5FY-E tH}XX1\1.Q|yfgJ6|g6)]6c/?'uPдQ&ZT])}h*|7j *lupSlryvʒ(G tQ#ؽ9x]zvn(CkO '-BQCDq3FHOETsusЗt2;ܯof8t#\jCR" 0wVtE WHAru6#h n\a#'Rj%C{CFTXB&b}kJ+W ?JApPT)N_Ϝ6ݻw_zAHSpZb;KX~޿_mA˼e?&\RtXazKmk~.,wӿLT4m\_>HBZa DRBB 0>Y&#np~`온uۿK>5ls`,_z_Ӣ c ,-ZhE¡wO'!"qLj]oڪh/ɒmb^&gLю'KV$-^Q¢ϵs(H$ < ~;3 pXCWB|OIuEq^Lי 8(~VL @*&;i|+mC`8޼u6^Q^q`j֡Nͱq%64mhQeF '/8ME\[7,zϝƘ߯ cĨׇ8kUD*w5}_6]$χ=V8%zIGj5pp9EUUr팺L:{_id"|w7ϼ-} 5F.EU ,@ߟ~ ̹~ +IZM3 Im ?pߙ$,Ĉ$c߀ DN~XTi*ܹo2˚?6bHx)Dgn:@{!^֓PɡE3ZM;L~||܇՘-H$ZPzQdfXcT S-s*; FX>Wqm׷%n-, ̅M N)x re=>Z!LEɚdIL=?UpUaD((뇻Ktx؜{?߱=w~< Θ6LnK3)d?6R%OTZTAQDO}4=EBD8Jsn࣌~gx:%2TՂL O:g.@]=0ojčZ0D mf@MѣM^k׾XE#նnݬ1,.DMw cU(CJkBEUk= J7`QTvMfCI={b e,W\ %˖IgD+~~w^߻VkW4OD|džz0=wV }VTg"mK W\0 =PQuU|U}{2yPqǿqNQ?N3ܹT!c Ҧc⧢*ǟ(~֡zUGn}V eaQM&RaQ9,/WZAY7Jؼuo׺ZU7( n<?U*âoPT!r$!(4sDjhtan-WAcUl3@ݗX"cD2bw"Ff3Ο'oO-Íu`5sd&G.,ϓ\p˦ 53"UpD%2˚Mkf5ܹ;Q'QPG3Ξ9]< cIk?9N*J{LCmXK,OKMZ@QIQ1U'I.d^S?QN)Gt#,?ʋ>}wA2"*;t<ğ7Ucf̜ % G{pa>.^x2=A~+,].QW ߬["nuo3ZkN\d{zwxaiު ZԌ]tR%iSaQej ;6m쵾Bzv7}ߓ?)lФ)_b=eXn"^ )IzN84:lM†+}9 OoбƩ9q^fQEEUZmHE߸uVCQE7a(׽5TS\۲m§U`э6}.XWe8=DpiAe㰨⺗E7h"B+;jo񓌛<]QH w1*k# AQ奟tVUK(fQ ϡGd*nc" U`٫91h3jHCeBKQNqƑj@ZXra}56%$Ca=y}[mp`MȸzrYxTia;Vi o}ed-(Ԣ*c^i(rnWHEU.@a,7oՠ$Ξ5O&_!-#bQL)4}?^i"P.R9Xޖ_+K&(@}7?J%m ~?oϑ$m7rLfϳV)nw3=318뿐5aQS-oƟUPmA!Gz3fL7lHC-B2^TL!ilЊҰ x2F ->-WU%}L+ue+!sa@nvG]?SQլ:a2 '$2ǒ߼-K-0=QQECUwqVZH^$$pJ72wQdml dZO4U/y?0U!?>k+r][:V ApkmC?C1wS2ܥX֒\QQEU#SU\~w{W@oHfhcf?$Π5ݿ4O5FS'BaOB!ă)tƢ őm6G"KaEŋw~+ܦIc?~r4F?i"HV^ĎƸQV] YtIg{!dnw`g͘c&?*rZ 0a|lϐx(.9vfp9&䏞ӼؾǠ5XBgիFجՏF8x]`>ܗtҀ?ˏM9-zv&|t_- z#Nm7_`r}ĦGAe΂Ǵ--r5G.O6*!lW⡿DbҩS)N-[?w($#҄v*SZz?_r蹂x9bT1}_/p`_+|%}ǀau4 ɒC<07oLXq׎S'AQŽ9W%62b\ā:5ä?P“,Ooο?S߯bR-B@ijL~פ8~!&$]heDr&2Y }w?K<F5r7dEȗ^åoZUnHXTqUʶcZ2QU5͟`7P_q$EwMB>ncQd,jHv`&SM%Ϩ_}~~wE" VxLy'\a"i6s5L c,lxDdX`X̿[ap9|W]+~-oljG9 ܵ9[E~J;I'JQ[Q"ŧCF_ٵ[d0Ok ~\?7oX/y5p XϘIl1 Sgp-5+nTM߀+Nk Xtć,-A^ES(ԷWXΉ@Z*XcRA$;H?X$LP3<ƍ1p׭ ehcХ[9o<2l*_*iƿ +!&{3!use ~*TDȟ{ժQMr̥,I\p2~-b[ty9+6Q^]kʹx_hQڵ֗UJZTA?cTQɢJjʿ/^(&($U]ƟI71y:t1Em}~A# )A؄|Mrf&%}+N_aZ x݅ejL;va֓)扥ۄtŬܸ^Hzs1$%hayN,=rLOQ8j2 dYZUKITT;_JXT-YweCO 1*.g2JVZ۷nJ]Pd)("Q38XeɌY+X/K?&嚖J-~j]<֭;\-%pj;XܺYTQUC!"64'~]~W4,g|p` .֯[J-;Mh2/xfƎxfZ_Y?X Y,~7ӵOJQUT>xc+wYF X`$pZ7KTU[Dn>-6qp`0w b}5"7Gș?k/iP fҼU^ :26=ժAIh,\d{*,.+}aDܸ񻭈=uDs|k B<4wf-EfT$?= pP(R2 ?.+~\6[m],vwtϐbU0Igæmn-pWiQr:}BD*νwӊ&s"o$_ 6F8GҠN V@@ ˭H4[ul~g_S6"qe|/ 0UBe)k2`מ|Ч;Ḱ;#3Cpg˰3{O>.U\RR7=.;Q/{!𓶿#ߎ{@$^>]>.؞t Eիפn/H&=g`WO9?\=X _l݊r^Rc?uj ]ss űg8I9|܄F,KJ`o-R3 _[ʕdb{T)SIbEtؗ0kO㡨2<qLRC_ELi&@|?xDR;pP5r8huB~T>hzE]fox(Wr ۩hXǒ8j6y~׺.p߿n3iĉSp_Z|n`ʋOһ1_>O\iEUpϏa$P#+ʙ6 ?O=+v_Sv) u~ѿ$A(2\_#W8#ɪo( i T@Q{~!F1eU8lr,Xx|33yX3ds[Z}]t('z6GQDQeV*l?/'5ϧ6GmN<5o=מ =i^3I2\X-qG7pSCպE#\NO w'AXs*Ht!]C&K}N ]vlGV%g'm&S[WCN h޾Hf6SHTO?#7liӧuj n.pӤGk?N!OA_ȿ-C \{G7+ueKܽlFG>ܸῂ7aһoYl9phobhq'"C;!o9YbWP^;ThQEoj|vZ#xI ?O-wKZ/ u῿qP1-J_n *ŒQdKoǿ9K~I?Ն<4_{T,nf.Ý,Pc *nۺs/M'0FŲ=R#G-[!:wO]= q`uB;xPcѥMK1?d Doؘ{3|ҼESO;Ҫ];(s" (%;`m?z3E dtIq;ʕuI,@X|RQN vozL67|7^ƐV?qW7KL po$juua0{?2W% M67nU*Sq3r0@FƺOZ5jօ+ȣJо_[CWj'm#}QM)ũ!)ܹRpƋXP-CN>{`c&`,ԏ:hm)8TK g-Blިkǎk"eYzb8guoc ;nX?+sZMS }huY (ujQEC8k!rD۲ X<K4OoJFQĻQդA_e{+(8(4  D{#Cܼyۃ?8] 'Ţ8 ԽT924;8"j.bH?gײҭsI8Z D]6hT*h+H2~Ut_>x*Sz *(x"AmD.'ŏFrLTސv-DrRZKãreKJ(R/]V2. o\?z&$xcر'TZXѣKM4NF$~ޫEbƌ+fI}*mb>g"L$7۹hooRaJH=vYyd~.oC;pИcZZTZT A-ݻ`-xT*Vw-o.]:a<\B|-u|k_Y2}"?0跩GI ̀wWӹUE6vƴ—οva N.\ T3tB}x/ZuY*V6Я7d lRSL,~K?lo8+g J4}r3H 7=C+Wv\ao փ7~1-V>JDm͎wg/ߓ}*sc8-m,I7㶌\~I~=w[wMst:.^E,+6bUŖDEx#ׂ<׼t|ɞ&\y_6.3א'(ekv",z\7$]WHp)U.=6,^#ĢB<|>$KUB5.'i`R1/ q_ϿEU)&Ǵm>\|4ik7a!]ȡT?Ǣ eN \eIuxY);mf)Ằl.t?-Im5ipţp/Lq:@B(#͛&d?I2l7~X!~ƨO(;e#G8ВniZ!52xڒpB6}jv(| PG4K)lVV 7=nprS5|Y+&M1n\ZժTʕ+Kय़nq2L`Fۇc`W_rX"JKqe9QԺU 6zm6'#"[pSƏ[͛JMQ(}P̼۴nF 4iPjժC c1̛:yʃ16SH}Г&O|Lńs֠^]ltLI  s1?dcv@xSaX3eHҫ{7 ~c:O( ϑouTW uݺHq˖.۶m1u~TojJ/Bx%C Peglar[A=[--_];eQE;.PoeL~VsW%M]qʱRA ZzBImFOZVmiڟPS\Bn6j׬VNp=CA|b[\tYFCZ?%JFq)[sb,Zbq[ $y;̓AnDW}^cQXXBlXG"Ǧ-#JUhM$L@ʖ*qp—nv2KC{REyYzщ`F Z@w`w_ ֿ>ƋyIST6F۽LI 0vYQ9gjzc{6 sCCTNxѢJ1rH(}7o KUU<8,Y][ڊPx# bUUMa/n{؋7 ]2 )i1E<ua̧:u_k<[>w[ ?s R B&gac* Uk5QCWEćf_..\Ӊ2W_Sjc>ځaaު]>*In( ˟)Ix[Y⒏E2wSfyE2Q̩8Wb 'J[Ʌi7&z$$geO+iqp _3;#kszgp}bM8T9T6nPC^Oy] 47{"kVp\i3"XUVSEϖ!>1gkӧ=}cGZ/Rs]y+b8Yz`3{A턲i"]eRS% ARp7?BRTT ʍ? q BӧM_~YMߧiQ~E4-~2~fM4z7*ZBknp P?D=ó͆ dI N]#kH5w1l}_a5E'h8e7uq? ǐ!Nwy@IDAT Nݒ~7)87h iWNXrQf}}GUuO"HgeWqҮg:(-%2~ƨ]L&/+bT8Һw"ls**!/˨I$+?χllS0;j E;-C¯*R&NΏb;|| ~ClT2͏¼4h 93WZĖ_6,=.t &xb*0;EWFFϗ~7~%g@Qeyj6uʀ2Q)u=F3g6C9 @-eʕŇMNɝ'~Q DHNzj 6ͶI"%~6"x烈eYSoskN.\(Ėnbƍ8an+@npDVIhv}U.:csIlNoC'K+n>?؜8u'JRlg$lnEtN< 8;I&UH0oZ:Y֝oHem#VxH=&ƶ3g0Afv?6iYO9t-HT~0fEB(F"GXW9[GߣxD`CHBċ^we.@Ɖp*Q_F?/km޴ gU|Ɵ@ly CTF=(%LS/s2]$R\D??,K !ѐOBs,E?Ê118>p8fpGHa.Bq_acUTy`c8yR'KpŌ^C} ɰW󏢟w+p5-х?i(e,C'n8Ə|ɖ#~SpIk΅%yJHXXӭՔ1u ? իB1gkmu'GUl'Xf|? +Q)i_G._>/644;-~+faS\sEF)TW38 Kdns> h\4Tѹ pTېS~W2恴ɒI\ݱϽmMogA?aAKrEm/>qE_xT.g|G2cܳ?$"I1ᮈpX+e6<ŌY7x.]2jN^D|\ny?GiUyz.N]eϿp~9ua͵ut0 ~paMo(s*6ֳ?ZMEUO29ora^~)F?m9:fXv %M?AkWa XδpVř3eE ܩ5P7~/g'5?ȧP`R`AY2]Bfb0B_o=}Sr$kRpFFos{g,_mK._úh BQխjb7e2 yn1;i(ҩr"~(",R EU <A4CC -e)^gmzDW:׫Ҳt~ +n3cQm=@L:+ʺТEkdl<^E.[y07#Hjc2Ifr>à`,E̓y[m,OB .U&)݄ [B2 3zeu[o! DV dUt¥Iē ڵGe80BܱXi`so*\2N`vb~}ɚ%+WTa ?  u!ik:V ':;L/ggv}A%Oql[<{ q+7q0d䓌]0]iIc;nw7]EG`?%K5 jlR94F?TZ<+w}yW;q"IPXw+ 1_B/PXbVYϭ/ZTnd!9uѿ"*w4udҁMhB{f~;h6Q>x)TcxW\v"?OOopòZ=?|G*=ߦY#IN'nSIE~oD~@@Νk׮qJ/҂ \!eΚEN%OB.^榟mN;\ |"~ԨQp ?]Gwo<9FeV_zilLorJ5O~aZA"?ǛYv&E^7|~"ῄeŊP1cFe[fVQSjA9Blg$F3Hl*B9 ߎ >L2Q 40ܢo OX柾}Ȝt˞-Fy?E߮S̢%\tq5S|Xa:}FGŸ@̶":Fj?|y"LmOeg L& ߝ?EpӌT81'8'* \3_|$zA"=2~Qk.I[r?x7*oB{?8 f0r}Qk&uV7k fda$Joe)x'Y~duz~Ƭ?/H1𫅖owwH^U-Ȩ[lٺU먼q .6]/#i֬YR~}uY*U*douMAuo6G&gɖ=##~)G2nd M3_w\{o  ")ϑ3ܸyCEcx'Ы7|)#g0;M!ǿo 0,@zB܌p\4nU&FTTd8/_!:uǏ;2^޴PTq'/od\+8f07[ndGѣH"n-do( ݋Y_M#s_87Zi6m_7t8w1W'K*mZ6ј`}(| _;?^yG?UhUl R҂ ,(6` v v i`;-鳱@waA@;wv3w̜3gNMܑz3OckELI?vUUvD?O,ģ_Oyeɒ'qy4OiH_|8*bP EsDU,AxH="9Љ*0y9A#h:2&5j2$#0XUDpK[O!3߬dUK}{RT ߤr *k*o^lw1@n[Mŋˣ<$} `QyF+-wLJn馡kt;'wQa puӹKgLBKsJe{[ZuEdQ?jmo]||msTO ڹ>2h1N6P\h\Z={t׏Ao a|7qCO7w*}edӌoC6i&Y2 +(jժmWXS3q1ԢyK(0Fo/,- Gw lQ<m-BOK3eW;,\*bG~5J&[׃p4ɿ!7g?*&U4~Do>4hP?3Ca/zsoܴ ?Ooo-? _xi,]Xv蔓s14Hص,Iߖω*򟶜3KD>!E>^~܄L[K$ KýFXHHpQFUKм!.Qu)j5slO8YwVLϧR~™o]/_BfYYrDCN;$ooNl!>8fwp.DV w}5{{U 0Q傧 {2v&23U^aFRvm١|yOGo[ӿ߶o'̋-+lq`k5k/G`a+ɪ);U%w\Ϣ7c~oRQSjT= 2)T[‰*Pj'POU H}<wK*/BR{ݽΪ,>ꏿg_&q+z21>F/|) "Y5;BB=DM؉*q5lϜYZ  /*)I޽ߨP<Q uh'a޷3Δ#_G-#FH2eqt v1+]S셏J/Lk&fwn֤k?:?hw+_?atEֱL1cɟj{ͷ?(kբt`g,U(ɿ)1G>+virQKAgꯚ() y>;:YKH7}O5j(5p_ŊN*N* >) 3yQfO?F6K5"Q/ҿ&L` &Mp?4L+HO{j:ːgH#|__i%{ DZO?ln_Kio;4#oJbc+L ')vT%:xj@h_~4Ut :w{ mgϞ%+W7^UI&eʔ^zI>}@ʞ{vB7p>/"o~GjԬ.=(&~$v ;;aäGereN|3fsگEDQ?JUJz ogOb\;&6]P2kf5oe?Cޘ<.L&K.On5k.ד5kH+IrK orm%&-X$5OgΒISܹ\کc9pRZ7׋o7y i2u&Fpb!6OTL?Ϯ}x<5ӣԄ"1GKs}>Ji|7k[j6s~Q~EuH9Li6?7bĥ=C/x @e_8 ?ay9|䧱KRo^v#E/UmgVSh'ż*; ~Th-{'JUu]qHg?= L[;Gp;0Rgxw"cg*NT186 __l)f^_믹ٗsS<΍])~]b"7'8; 69sX o2g_Mh]3taT6gЄa-mN1Se֬dblqsC>~L\N\dҹyc" ÇtvKլQ J:>ӨA= -TD)~C$PhٟOFƁt/;ijNTQq sbBAӺ 2~ƎRoTA䙔K~HA0r9?n9塰:8W!on)fpƟYZỲ8 >F\7˖.oStOFd $ ka^ʣ:h9QÆdYP?F6r5cӿE~$O?M4oӿM6oӿM6쯿5%sdNTqR#nuFXLTQjU&`lw.ex:aXI' g*N%rw=;E8p޼yXmZ?m4oI'<}TçMl+^vG:GKUǙ͛5SU6J߾\9^+SNsz|JFly?N<9&t1_?L2oeB435^ (/ggG_?&HUW0*E;-b:2Ii۲1L 7GʎѻcشY9Z/ӿ;!S n%:(KOĤE)@twPp"Rt7/r(B/,kn)SF\J*iʵ*G .CO42LaWNFPrY_?8L7O?M4S5nӿ0_e1"fhu!6#/ܵ0O7hlj*PDFanI0@PL&W^8% ]Xs/}Xg &JBA$86˗+Vyk׮uM>!7ҥl2RnrR|yX81.(ws/7yd_?&M5kӿhOo nH9<(>F7fXtAǜ?N5~@ 1SϤPd*z']}SeSqSGrG?ĉ)bh4B,@L0>lU%pr=&9whg_?&c*5z_́KA`ٟ ## o?b1o?p@mfT9&<8Ei}` < .>2rIDUΎQ4F_WZ*ȉ*0q2ze~WjnJ7%4ĚOG??8C]1(Ӎb2Vi|siNf-0@^NRh-d6уoDZߦ;0#27tt腂?(~$/E'7f.sX?MN QUHvT%2qra2. BXjzAigv_.oj8<8!4")fҋ7#{0c䏓&܀+a ;~@!ɞ0/?c07Kf7@FUѕd9Y;BLu$2vb4쨪?dH&Nj;ML^8^kAQ(Aw_Q8@HqF_Qb/.U$2@njW_?GL8'w4XtQ|DH1KTa_%Tig«aw$Ltl w? )<2KU 8YAx1!>lGD һ4X)Ct֣ҤYcLTi1PT*dzX!/jh4oa%)`GƟ` ؄rozj% \Jef%z` 9/+q/"4ʌ 6Teg ~eW?Ki3t'ctxN7 W/Tf i8y4"$^7d;aLwT@'#OLq9̘ϬӀrsZx 43CzXߡog$?_0G?&M0 Oӿ0O0C@2T[jD1h?GB2D`7li2݋N:&OtGUR!78+QJ\Rw>-&=\$pO}$<ЁuQZ}x\/oI_C1 !hN L0O7*b7 (v(cԶAfa_fIifa481ҩдٟ݃I+QY3T2 ?$b~)?:9QREA7Uxl^_6B|u\`1Q:k@xV>8fw4 ,e[ei'l!5k'&yaj.70/%OTDэy|Y5Mo/,jpaRɠLyxr>}KqEyp+9(c=HAF6@ TDpx%4Y 䏓@_?Liߐ f@>fiCi/@)A4#lm}x%(2O?K9)k&vdH u7bXZr͕Qkn=2ٳ4q4˧\ejgysy06.5BXs=y9U*UL1*o?]E-;գOdKeٟfmΠz.f1݉x"oio?&?y[NTcA?xd,nÌv,;a"i#ɏ8(!-@dN^HRK t0mx|  82a̯?]eoifUM`ߠ?2zA >^=0mGj+I)f9e:4)A QMxpbUD53?ȏen`<04& }42⵬D2b m F6H )deДA 4xAa2 PwuDuטE_feg1`?¸0?PRE^l?U7b͊1a,L7O/ ZGp/bqFmfF!DXscڕ>ʄU hO9[EW%|ÿџ??M5_LM wBfmf ^15f/"?0?h0nd*ڶL!5(M¬DN%տULجQP1ř$$~i$j{xU])+uT3,Z-D?Jjyp&'LU*ӿL4fAy6HҒ0^Yi7.tl!1"@2ܜbi2QvTh= @Zt릩lO<>f~*N$񵘜sxl)^՘QazD|E^➣Ď*oz菿״( G5Op~${`iz7n8VZ cђNbulLL!^,A1CƟc$X4@JP韦18 ? /77" O =S Lfe$fzީ?,o$S^ L6t&AIҿr ,.oTw]|>G)XU0иY VO&``\BO#Tc@fz'&ĻQps|ÿџ?d,1k_̈Ș0/?9F@ZS4,tfG:_jgu76PӲuJushj$D9JNT!YSJuxHd1 uuIVYT.,3 *Z F6(_?A>)*if-,46R0@~i?-jVW/2?6y 6-ӡ7(g/AHJ'"ODeckkx>;H`rFq@xp}>jh7k,6E\y̩G*l1kGT5 ӿT_4ӍϞ$/ 4I Gqx0_bp\dGp ujg&u+柢U.>5W9~R@8Q8H(]M .A,WG>Ãj1D )4Kp'.7s5џ?p ?Mxy%_?LROoXf1HcOz1`mbo`7&ef%E:_oGg VuRQU ,Q&@YQߕUEn[hզD̯/!on)fpO=K,x3;pdџGp6:1v*NL(x`wOoG?2S`okFM}MONɜ|!CN |܎*B3I=*:cG> 1__D{dd SQ\Lew IEi5xƟ7Mpr/(1 SI92W0 A"z# P韦q`ߦl9E *Bz̘2fiJ9Ii۲ognFY >Q,=2g3 ;!SKJsD:MR2+9ek}ۊE5b:|sW:j F6#45/?L6 fQK@PmfۚDŽ: qZeFH9):6ho6[5 ?4?2yZFt8B=1hpnu<&t|e'PfFhK 67:ԼKNN૽I(`k(kCI ??hle 1k_MT9"# 7&txP|Wf*tD /ڜJ1(fe_fw&eTa;ṬSY_d#d'{ރKŜ7wT14KH"G<7 j-Q)W K|͕_Ty W+VȪUeՒ.rnO+UJʔ)#ʖw(/;/XGkE% 0R6q&(M$_?@&M) 20^3W]?T+23#y ?ux][L>CYehY `?YJ'~?~R)_WGr('\Q4Ec v^#G;˖-+U*U5IuQҨQ%fMѿ|>Sdut /:14Ṩ.;q-0Ϧis(ψ.)*Lrӿ(39w姱KNLL|hlG]w|/&j`uϧd> +I:90'Rr%iJ:^jTjod"H^&+ngh8yns1?}M,Cr?cg(s;AEs ɊIW#Ep0/Jfxrl HJb+sjyjj)SZ$+1y曯eҤ2o\a'TZi^4oLkO9[7iذEeʔի*SnߚsxHXs&jH_&M/8 E0O\5?/]&sӂfҬqoPWj׬·iFi\ymaq:sŪUxdz2yj5wD{^Ouz6C:! 4c7ߴl}Oc/WVvtl켨}W7CH< (1*brV6UFUD&RQIR}/GafUZL"PF(5z\nB6$s)bƉL8-(M|ņqľd-<-[3^yIZe2ēfG(-D|RnՍ7'/kJZ57HKA*}!*tџkJ (58_ʦ_>`韦mTߕo,ڥ]8kr(M3A6̙|qwc>_m-gN6C{OtHGi8hDz=b섩ZP3QÅ3G*rt s:0 \Ng"#Yg.o /|̸iaʛo#'Mj;UkM]^^@IDAT裺(&%WY~D=rwǤׅEB=OwVխ[?A[. ~ۆ*b#TID6@#(*K3g'}55cӿL,/?PSg_|U~muޱNnk_혟dAikfrIϿnJ993[ڶLu}2EwT%%XqQi&iUaq;D@$" |.h(ZwK%1>. >C7 7%Ң9&ueq|րu̙-+W*W]uUFeݣoֻ(%at= /ZPfLƇӏ?F$J7a7$w+SFԩ ;߶ʈ"1W4b}#]$&!9@"%]6g9|I/_%>«2~$T>4ߠDUmcoI3GKUrr"oO&gPEǐX̡^''J# *<6K2M'Ϸn\n>.\4Q:d@+A'Q;{N3 dVAt~-n_ɪfZքud]tۿxb7o>svah:m?w/B\7D6~*V(}#GZl⣫ZZV0el="?? G4eBf>0mtiO?9 8i<$a*-ju7LKO}W>|Kqyp+9(ST'฿wΨ8ί0'L"1d` dCݵa(f,Yv _F_멸fx?眳aävZ6*F2a…2tPpZ&YBcG&eJo'E[?fKj;J_Il9KW5W)?6?&& Lp>ɒ'y};ʾ}4l w3bcZLyg#cJBʵ;?i?66\h:QntnQH"߹r_S*HR$oQ $'X0! wllU .dT,[W,_!CfΘ.ݺv:Ÿ5˳>']=T5YDoEj/BzKfXq~R ܡZǢVD۹o[_f.UZIuCeѲC#dϽj[?uȑd&&mI :uwznYOBKy۵n-\,_w͚]n"S`탱]^|Y`,mF:w֧`w&Mkw [2?Ae|-klvە&)EN?d2dUrdۓ4oQl_\qy8B~@I`$vDUɢ&>]<1KNFlF LfbTG:g2x4Ol݂JcHGRӲx^8W{MMTl-섺X1)'Nά;1BF~bybyч;Dbgʍ5O4ipars/pz>*vO|8 oiҬ?\~7.Z*>OvRYwljvz:V%YV*WU;wyfyE2^~W4yrvM]ee}뛢3pG{#o [$ֽ'˖-Gr[on>}ˑO<Y ùifѶ4iG*&6t}=,I'% vmM7'L/oرjJi߶=-0Q:q?idyȼsӛHVJJ;͕W_s~˭;nrvniWfNR׫q2d Xx?eAO) ƿt-yφmcyTi!з[S3~$SAwKaժU͚Jfd:JiN\EuM̬lUrՑ4}큿s\)*b8y(ܹsJ8sw'{w&EI3fȳ/$Y0p$Ri3na$x[7z_#=#\r[Uk䋯)S3e*&/^"vp#fҬYMٳz*+ GWťJS TU4StA-/8/!wr)Ow1?H]Z[EȠ<o/pϏӹ/__ON1Gu/`Zyy8 rե\<+/rUm/ǔi3h$yũiQDt5#L* Q&Y SQP<"-G,J1a(UAyOQ22kY1e<@ zO p_+0Gư'b;pwh5uk Qٳf_#})_|xٹ^= F(='韧 Mןɾ |Bgls}NrS: xmsPTJJu{Ή\M?E qOHW_Ftmzz#ب\ɀA姟~,C/e˖`zDWnU+9#| +q~>$Nͅ_X3cfy̱QzX7eG{?C>е-dZLY:;P4LTe"6ULU 0 C[r.9g)^; N~]p%*-ڏ7WsP P8Ϲ4>wvZDo{,&2I?"z C ɕc;Qf<ؽۘo*+B}cg[K_rEzKԩH#.nq2mz>p}R qغ'dܸ_YE7Roݺ;ɀ.ʕ[S1 <L9_|5= 3U 8Vcn'FUJHP( j? ^/Sf;8uZ`t; _ cp4oXvoV%{1 Kj_:}U)jZa#/A6&} m$ y{+7_ 1?,՟ ß=g,_"תYSDqQ@`?<+# 5XV Gy\ӏK ǟrO I\qRzUMw͎o)lQy;S֬4[#$_-DsEG ͐NNT82zh?)f(oT{Q}%G;\'5sP.*fFӹ% n=ڕGMJxF˕dLR^%T01}\\IC(sl&ڏ c8?89E/Wnvsـ Tf!$0%CY.ېf)>j*0UL%2 d_x)@=1XG}42J0B,+?h2x@w4SQ_ο@M{Co?{ga'~~ⱇ0h1QMic /r)'~gs1y6VN?lE3O=% ) 0wޓ!W]P:G7~NT ETLIӧ4ҺѶKmy+O.\}\ٹ^]AXL->R}ꈣs;L':DUF(6^:^{(o#Ϛ q2T5MqtSxZ#hbJŋJp=PcTHK!YbZFT\TہQ LRqӆG!1Gr!USx >W[V+ȝU(8r٩l+iOP]d'Adʈn~W\ tz|'e}#p/ʾAB6B>So}ҪUkl IgSrYgi&~ssQF(0S?}U ȰW_}v*[@*Vw)p_?䋯do1Q1k-=AkNrхHzzc[)~'7|+&)1}Ii&Ï΀] <$E?S3|y/iv=Xwv1OOir#oa?`.^}Ey^S?DܾK/U<0b;b239;dBQwBuA >cSCQ_˲Q|Ԯ]C J~'(\W~)SfC5 b!^}I/c/_~?$VUoߍ?`zύcxt$wM)c"$EJm&AS诠W|֢.EAoh9U20nR%e?ڧr1GXݲ-8tG C_*M6p/_&z18q!6!ZE{4GMژkUཷIres[GQT\]Jk[NkoEGʑ%.Ӻt1NNso[wK&wr.Jq#¾gyh )-'ܠoˮr%}]7c0QO*_vy8w'~ʎU#9D_G|'s7}𹻑ccFۗ+CLn]>Cwحwu.r" ;t~d$u(v'Eq<܋ÑGRɃ~S^_6Y5V15|/sa ؐq%KY_b#N܅,?w篳9\Qgy" -Qj܅~C r)aWŃ}O+*zUj?\a  [ $PX/k!' )_rfYEY2G-^'+Vvx47>icw(N[dpi 7,((?̓l8)-Rl޼_IO[iYۭqέӔ5MV?56TI ce( x>ЮrVJǒcQ:#o/s̒W_{%8O<8@>3~ d zߤaJ}?g6mZdh5$oɊeۯ9s(%;a[A_xqGYt[ ¤jr ߵU++V1/?E-Y|Jz&;#Ӏ,\Ér)w I\Ub_숕(Ub?d~B`#MڍٿcJ )\6|0LbENJҥ{%9)Lɵ ;㨧]1ڵ{%sT_W $u?[7~?{Q@4?p@?9wo-xPm' p~^opr _kbXO;׳&hzTzH,=FvUB<ۿj&7&(Y4kXjFd7pas](IqQG6nӪO>K.|`ȿbŗ~Z5=,E'LB^XժI*XAt[ ӱ۴zG~5d*[*w"?4}K4I m?ˍBr 0qٵ#1<&g]xV4ZR a%`;NNr9ҠL⟡A!NO>Ξ.kܸ1r0ԇ_ 9kL|{p*۴ߔl~[?8j)ovuWw5\~?Ӽ3 :?S/ǟs9Q~tg(I MLRr2/#ˠ6pW,6]7cOvE*T) j튕espŧrӭwH&[oT ~D3k `>TZtly_b پxXSG ~ײfnYNfaHY,67@5ynԱ9;bՏtGU}7O[l̟7c:R:/޷T@?EW`:n sF$4 2ƄUCoUW=3O+>rg+f fԁ|vye0ʡCwꢀ$y_aolAk6?ʃ<GU?[>ƔsH+|Z0͏}%ZL\]R@zpLG}ohI ρ K`Uiՠ+q ?+W̚=[6R2n7A=ۇ ouT͏ca'GiJ.G%3?>\p.ERۿ1_H_x1+1DLD_Gxwu"|;)D}7ơR BBט ^O WF4=b~7sϿ4yGH;Gpw̛;Oy4&-c_qJWLT='_Ma*2gޙ']?cRؽ`ut^IN=Y00I=;Wdž椶SaoN)ӲMT)R/$@MLT7}tJs&b ߬q=-f.h]&qISCѮyzx|FAL>3||XgOAKNyQ8WO8U iw+|nz]~&3pvhzW'߬) ֮]ÜgRڏt,׽ϼ =wS8[PxJD>8LT?3zbρֳx89hvFף{=xt&w(#kwx: gr :9Qruk~7^qza9t0yPT2||UW~]:+fSk#!WE~mg쿟y7,Cx߰C;BxF0[n5\ zG,~;/e?S?:K01 ٱ;2X$?r뮹R8:6;71M.B7nd[e"? ꂾL7\ ?<-TԈ!M)OɧƓ+c⧧'T'jvݝr#=x^ @Ro+gcJsW^|{RJnrVն 8k7uz~kJ]݀"t$_q& }p˰81]S.4ƽۭ7[jSOgGY~8 u rYgaP|r;v%˟#&]{l_? o$r?z)r{l 椓N@#'r\p4އ8q~{@MvP 8|Ly4tup䦛o2qe:;pgQG ߾9z\{PayWUβk(谛jbP[B3+\J?lo?%s2.۞{|_]xy=_ 0#v|,^, Jܫ'pYU^~ wlEk>A h'NsQ_Y1H+ 7i"gzN@3m\L܋`a mG.Fo?K7deG;BGg8,&OG|cSYo`0:>p?9cllgo6t,uo!f,^XKcl';ޒްcڷX^c?wtڷWߐq{w>?;y .DowN]H^ݷKSwL^b Ǯ'{JeF_J drN@@}\|?h7AؙEi_| 0_>NXB _\Ͼ1?Q|q5b:A:2ؽ&%e5:)zW ϿbxD8xrb|oN3X ο?x<ݏ_}S|+Eӥ٧a苹RG@&!ޝppwO f>ԨZ3)-Apԓp$\f4_6t &[nj;V)p*8b9}pj@Np~k>C.{vSCgcگ#-0kWc%PK?x^;'~!¦R8 7<[ -;խ\{w|: +'3_ y2rX}o,⊺jK%,pVYԗJ47?Ɠ#/tr]hýN5?NZ´W7<:;/Zn\$;V".%?'b"iXؾ.$aG=ǥmo|~zྲ~ ~am%ȕCORu@5=/W==K>:b;7U>qfrreu2cU++*Ϗ'j3ꠌx/Y#sVKͪIM|KH0t&@;=UXRjk叅k%v)_c 74 Qʼnt aKzvӴIDh룼xV"wTÑTT˜,qi.>O+BA<"ph3U5}G1p/qWP~v$,k;+߻~h;&ZЈ ?_x|pE5yWxIgձ{gN(~w :Q=W9/ 8C@}-[6`U'ѥLDñꖛȃ]]?cu]w_} mz(PLu#1R_ { v]qX&b-vp <܈UtU=~>[R.-[c>,+Vp IOó+ Qw# %k Uүʍ7щ0S1_>}ϗo@k,w< KL(|u|G1\>S8zx jN:#Y0r@Ƙh&lXx?孖_߹>r=wb'"7; vMe"ÎJ~k*/hZS=mt"6x+ ]}iɏi&Gb^{uZͳg{UG+5W.wO#H'G{cN>-5(뮿AFb?ϫ/<7wo' 4NO^_1yanc=Z۟Jywuĵ?݉&MVW uk*K]#w(a+y lab`iNJ|៌Y?OpJ/_~{w4.8͞=G:P~icweE 7 pW[n]kc;j6)9GF*[č`ğK?r07X?U,ηXZ8]qL"T􍯓i0J/ֻCx; ~T(|s&#{tĄ٧; ϗ|+?|~=|zhG ,n~]קyO$~+2чQc7>M?c^:)N}KTH Ï>@@e~IuD.â֭Z( ;>8)VMTKT]">M~u=Y >xoo6D 'TX.O$˹gҰ y2 lJV fpBb;z dB&Itu[qx Թ=&t< ؇$qr]4.ۿEz =wޜ(6|e,$y4pUTl?;/lCENqmq͔|-B.y Td7oAw* C'p*Ir"6)!AĻ8 9"(Y:`Jp7by\ޅҮ9!2b[Iwu7lbysewyZ I#8Y(vUC}k?awfH,na#HYp\Άz+`Gxt}Gmy#SnqZ'} W㔉/Z>(]|l{ֳw÷Ml٢9?Bnщӧ`TdCp|('/4 ;ѕ'Ä:"X)^ɥyϚx`g[#=ntEd+ѩ\sNc<KF~Pb-e`;6 7ZGV ||L-ȮpRu)޸eGx?mt<m=|,f͞_Lt>J.%BºW296?u#{vGAciY,T5lj ɰq25 `cQ؎x@4aR ش[XT ?y?Uʷd=SɟuUz*,3pt߶}.'Ma8^O 1u3G<9z4hz/SyI*3ʙ՗Sh[?ʗP/gF/Kn:,E ASiwN(l{#TɒRϲ͛Ҩ)7J uYjIZZjIIzp+&[e&j-1"8^( *_[Ŋi̵o]U\Qހ;{;=+* iITU… `[={vSQ֛.hQeucњ0UG(6!NpmiԸ P.z@ Dop[w?s;f~p _aY6hqPcyiY֥u tݼUZ3Xj:.h5 nÂJ JWZ/*. ?=o^3Ģ$]q#tjg]K?d% |8||VDVdO閘O u»Ybs jy.VcGɋ/bWqC$pW8/c_kt7*}7sпÚ\ْ+Gv~Wq6ŏ Nó,K8dPEu䱮ƬnآH^aa>]ńeCl$oPu˲|Y.R)oܲMwm]`;^b勐QOh_*, ӨG(U*cGS&\,_gXV5B9y'NX9Cн r3E- 1a,xMw2", ۣ ᏖW]{@i~*F),g7Kdyz-**|g[E=7UJus<`7i6@IDATH5#~`<vl05om; IInܼW_ EH*<] vk=b1IB,tr7X-K?%ϘaG0ݷ6tNR]nݾ[~T(f۴l "/]z5pU]%؍~i}!ǟ)OK gY*I9?kBZyt=tL<ubE i}OFF J^fac( evo6?1m48?Ƿ)k6[Zx(;;:sQʯWH-͚kڰ7?߱e۔V~P>Yӧt5WAҫ ﴩ;#ԝ`z _vxy]|y(O>g >a#֠R#2XabaX$P Xۛ?o. +䉓)|iPT 4~E/&3Yq⅒^4<#z G5) [N"~s}(,##Gэ_+}a*̮啘Tg(mH` Oʏ=^|+iY;S_KpKd^4!YC5kg ^&XF/ \Q?KdVtٜ2md,Zs҅nPi&qjvRD@niݦ.l4 &!r_Zv *Ų}XSG6-ZI6\BPa^ _J w]fݷ5/ip>V;guk>ԗE]Z,nK|ZٺǂEѲobaH&/ $ժOV`;0 'a|q~I*5z%rv.|:c4o({%yϙD b(m9ksi/&/`@r̶jv(9x֮]`53.T_ `No r@a4BD>;>H_H\On'=aB2̯fO:*ZL. g矜pg,}x.(vR&J K/Ҹg X;σyz('!Nl~r V K- ƱxpPTNMqf(BQē'U;wǢ]+刿f KXcl~kA~KlVg΂vk")|K‡yxj~B+gcqwyI PÚ?R7IIQ7bEO7aLUԿH̹/>I7k(!Hheܭ}<<=~M?/2M*#:oe*%~Xz։'be^#aBLy_eF?jf7/-q`\Ŀ:X{}/ cE?c&wJteu8 M'!;Ki$ w89 ِ.?{,^BizܽsX}(ci<9t V|As Co"2qs?(;G=6yz?1@OpIDO=i3Fuk2wg!&?i؈sr,eVYd6YJl<]p+M=4TR%&_۫Ň^`VsZ*fece˖)-Çâ TTEsfEռYJ<ի덧mJh䈁`~OHM~pJ7˛*+ q-[e!x)  5xʀ3JUl;AZYw p?^9sp1NY~ U=XT<#FUj`?/?Y8; VųowzCGYQVGE&Rza4o;6"^՗c_e͂FTy$5q -ɤW'$U׉ dR%.ʳcuJ#屢b(0>&zUn~R`biY> KWdlx> E_3h`sQ6wdENaȓ&}uf΄_|.: @' i\ԎߊkrG3[&VǐŐgu_LWE]hJQUab@g@9F*u~_ p݇b#G!]m2M=FbkX&% r-ĆЄ'B#b!ups͌5mvqG()RNCNɺ&>XTBeW`]6 (T[,jL#XiSe gaWIZsaG2pP.=Pdp=-]*CWw͂"*?CA+o~ıX, ^!k( ^;m 2:0ģs;M<qkwQ8Wx%K8ix_'(94~lU^G($p]&L݇[ż sMK5`>fA:Jreq_EbEeQȂS FU](r^(|Zh^K/X9/x)Y9(n1c*|*8`/v"=!\;%h>dTP%_ɸѯȟuS S߸qd9wAԍ1/6pJbX[|,PZ]t1 !Cc.WVP(1.".lY ?mۤKJOm3և[?, 7[6]k ݺ˶5OƍHC*Ď!CᠴZGN7lpa_ C)_yg)ʿ 4?E;(@7S(A0;s`?Y`qdd1}MCsXG=[`qnC!8aln*ʡ<~.a)-',7> i6 遃#zu7r 5 rοߧ-Z,ݻvՓBj2Kߋ8X6Q C`- Rg= Sf8ɒ*(Xxl;B0EH[o/{6P%dgcf I" %cbpfuV@̗(S|XTZf]4OUT?ZuQ@w`Eqsҳ : _!wOyVӺKb 8?gp}"c_k}ʔ,gj[T'ڎzEc~LJHk@:]~)]^04jTO:CQ-;Z-C7+)6*?fPIW6XsVc { >uT׀I^?iPྨU -$J17 N=uy@ ST`l(wMĦf܅Kʔ.?}]F}8kK&U^ 醏r-1%\pIN@BMĊIQ3$FHWȪq m;Oܑ3~R`QBOQ25QAk?}I3)+y8_J9=,_˿w?1/?sGYȷ+_LH k#|u)FCHΙ6<[--6͈kLS xIi~Oc/~wiF?9mLG| UL+RQU^co +vt1<3f ߼ n Zr䕈mUBۂ8?|Wn.lQXN'͍#.W*H& G^4{XTuV]EËl|Bd< S'cʘ,w&2q_p SjA $CcU<U`QE4dyG?fk͛؊%,>dB3TElՄu;M.l} WZ;w68i EƢ (`jg%jÏM<{>Nㆆ޽{(lG>>;0N/ܶYRAxI1;nUPA,MQ˟i>?͝gh"s%J]U X@1<1@ǝ~ mdp_Xu*lC狕qaXkm%=sӏ;_hN>#jSaMT*Q\f܈m.ngf̅*^G=pۢҠϫ0~)MS9~sd׬yfp@}"a.1opv {rN\d+[ԩY]ZT ^KyXh9Bg%W˦-ۘU% BeOiXtv>*M>GE8qd9!FyXT䐁(iF*5i|cQ G~yF5YxXv^)#KŔ^6lkĐ8|;v1/oQzB*]PHzCGaQnti'-O%g`z+U+-2rm3^6sLIr섩z&;,vznjźV# >lSA[0drir`-#;ǠO`1?ToК zc`O9aXY&WQB|UPh^ ‰ l 2;抩Kd:Y#&&7']HN&KW*V{@ e2.QX[o,6(0mtɅt'i==}hϻGCIdxX(M-bk͌? lt;٦rEBc#DGT1+8/U.<.O?En*!)>u ۔ V~X4P$=.\TyL4F7nςoy8 _;?x•ȿj*Ws9* Qtj>Nas&=^KbUV&ͫWAg 7w\1w1V)ơL`rZY4B W4(SwVܷS^t ̛7W?y}M|>Iy,>8 !REX@ls  ,.m($jrsGbupHh('13AnaZWHΗD\$e&Ʃy[[}p}`"O̢=hm 1"gElOL<aaa|^YMN %-MHw[\M~.TN4b`IX1v*vQT~z޶?͛߇J+bTPQdqme(zu8o]USEwbWpFر&r'5td>*?sH6`u֏ ֓TQ=1rD|{0?ݼKauBeS q0.ŤiI-Ml(-6iL2`SWOt.ҨaS%"=e"iS!*X.{~n>m1rb²sJY(0~Q;[AV({*{o͓o{=(|hl.g֥3ڭȟ- ncAϝsƎbu3ݺJ >-[u5 ƃzuk6棨ٱ[6AQ]B(UUWQ?{yÇי,]h@YjʫIʎmͨDX{3kύ߆'#{8 >Q?H>p X`IR/ڠk`u`Wd \fPHI}Ģ*0ze"\g̲Aa# }_f>֞JD|Reܣ? V {XCH{舱r n_rIsX)9!gwCVJ+WӾ<٦sy aI'(@Y,r4wJc/FQ㘊J|>gXiռ1kb^ZS jsy饗e4!QTѲifY u˷{ߔsQDp Y1{>~Bܮ~õ~/]kcM`|LD'N ex!yƗUD?v#K(6YD d ȜBz+IK>}Zw IZP+L4kE (,Tзj٢hbTE$X8rrܹ}[̐!czu?p,>g M(C =_|dioRTZ_߁z~|/3bxȳ-ZxIx=wpb;kZnyv3JD # DZYUcو? \b:oڰVgpw*\1F@ BC ˿ˍ9WL)(s#XRQETT͛HnFr ο'd`y͓ 0vY/Xl?Xɕ "\{q6m7=v5M FD,>4Ȧ&0煻x<{l nhM[?AR1:Wq!1m8G`t̀ , ^U w&bWu WI\(v (h݄Tep7Pg=<[Z43c-c4iA < QOPTTk[ ?^j`YDOGڶ {Ago,rx'-rNA6*߆U5,Z>L YkuY!MW֮ǸPեo-ԝF&:Lg͚Hߗ|y>O.0yӱ'h 5kIShv_(0UTiI` ͚6u#tvN^Ec:c!Ԇ2*.˜8r{Зշ kĨԭHz7oEhYYұU8e;btGX?} P.oiܽ%w*Q?d"u(އڇ\ǗqodF7Qt\~3i-&?FZB,-UTFّƿ**XƷר/g,QT:fnрy j:$x@G?{#̿;uļ;oBb%>^]e*(*oʺ">eHTT=zI[Rtv/Eԝ)5Y {:|X-dV{IZ5AWRMt9؀%j(99$mXmHh/I٤|/A,M6GIq1m XMz/.w"6[o L ýJ_37ٷJP/TTZQ$(㩢*gzAŋnv`[c)EKc'}TQ8Z<7nK 3Նu䇰4']wUw~D0C Ou꪿x'1Ĉ X ysKb(&oM!&IYƟ.#o?yèq%98ʣ=0~:WcXC;4,O x/qCxEx]j>{OW+*+`oTd BxX߱\K;~d{TxɟqVj,HgȠY\^ۏ˗/ˇ*:p]`UϟTT8yJmpso3Gܟ^ݶfef݄#GɼؤTQbcQ^sps`~ nAS6.J"'Kِ&1}1&3bɩ6{'WnPzITbA*[ Uo?zGflQX G*7K- 67Oj(![ص#,3Y9QeS7#:|wn|ZTeUBaJ}Ё}G]=kWh]wZppoU_z .1H(W9z %|K_FMXTkEk/X0Q4ƪa+66hEwSvQպ%n۷f(g;R˖-W)':-7BFZ|RϷ(]_TuvG7ۮ_U p3$ }"Ux> `߀|X.B8zoߖ&~Ov./ā{HSD EU#(؈B ~G P1BDt䯀8_&Ug5%$8H?uL쬞Z֮YAC e py dIt!ON:k =_`.E?X>(`lN7n߇Z](2dH$<A!e%1,"u$gי~hucƍKyN{E*Xae\_l>yZz9r\sRZ/Z(%GG? gBDEwuH%RnoZ[O`r}ǟfdgk99'PnTkK5ev+W~e+1C|os3Y,|ÜAEU߶mUŋ#~;7h`Oۦ^Gy`V*?bAT44y moo;}O=t)2ZٹCcֆ t |OљOb O=ѝM۴n7Kc|1|JHd⶝^ GK-;vhRZE%n?uwR%Ŀx.}vmXYoWG.ԯcdjuGQ(￾\¶m h+!ue3Z|!FչPp%?>U?rXL_|lںS1P+Aw?ˑKqE ;/|]Q+~9s/EknaGbY/,ͮVTT6w,Z4k`]:g,LA=4UQERQUxQoؘ2xh(ݍkV.PסVԒha7'mZ65tF7?g# c( O|Q?SOaƆCGdp w޿@cZ R%7ba0g:kN;唏f4NǿZTAedW`p,H1v-K7x?%>6 s-u7JTP9 sivZT=EU-뿧ru% fc9+B2,U4rt1ܓT]Zɞwߗȧ?"*, 2.JJ]s&)G߸uCa &~%Y Ǡ 7JcEbn1.K932eڧ3e,?^+1[n2."ԉ*ǍP`B\aG +49hPb. q<_JUq]ꩱjYZ6G?։O;"Z͚5ҷo'J_j!nKn޾,cgKŵr+: ǒ>mZS|9KHʕCQ(7e 8y֥ ,ҤN%K/ScQgwG4̕'TM6@(Xq˿Z?Ӹ"XhusV B?8qbE(PCSDl:y,j`>]q|yi-in|~!v>1BCUyƿu뺔PX 4Ț+?M| e(qvWZ@(~N!?Y!iҦG's ؾ .+FȟR?t֒N㷦?_n!ϝ=OwAPTXkpz[1?[tg544J[|IݥGe3ک}{({u?~<6^q K-̏'Qi0薏 UVQ]GYsf'awz6 WXm[瑿uG Z"%":6YX|~?H ҏx돚k,5#&Y& ~CQu0qywVES@IDATjJ< +*`vϿ7[$fAL- +ulB6J-d&͊5c2U-狽wjwtHb5k\/Pwe9 }wqW7iD6?72rD_@^;Ν;ҩ[gsSpc~XJ? ۙgY${UJ@++K̍o:s8~>z?OCNzcva/<܃;p#lb?ٸ~$Oކ6Ip}M֯{˞̸2g.^(Y~;F a3J]?cTPQ-9Onbs]>}zRf x6oZ2b*&ʓW۟`ϛf=СEK)7ΚX˖Wx>j(?b('nȄXׂ*7Woxwٳf:Oyf6HQPaq{U'w^+~Q+K,AInIF^nt2qH AXsz|(F~Q ƭ"v`љE1g}Ĩ2E$o FHBpWS4 hЩ섲W2%]z%ȝ{w?% 菛!v| i_gԝOL.R$yXTg~?Z/!Ihnp u _-+ (P1n خmkGQeOBI1WR#8?}ԬUQñhi, _z'LPvn ?X~tiPH VKl9ZABehXt>OyG}UG0>ͩcr8nhʔdْ;UkՖs?Buexݍ,,bq].`u&a| 3g/\00Dx[oڟ;sQO¬ (TTo';Y,goujӤI%}b*?ᙏg;"ϱAUT!KlȏEkbl$D3bm @ ?{uZMCÆ?2}l\l Nׁ[a~t[|Ⰿf!_ a=)=y=suʹG[~ K2*1;o.߹˸9fѫveQ2 ǟxޤ?xL9[玭%{VUk-oh܄  _& G'Uczl$cF RL{E*ypݨUaQ3'3Fq3.꽝9;M.HX>SzmMz 4z[y*ߋ?6δܙ2#?0џ)/#Cac˖[*>7L ۷nK<|.xyid@k&E@1}I{ r"<{#OS?Hwz?m]ԩ@Uj)jQ<>qݹ}} =6z swJ,i?<~Dy$9n׬]+r}޸Mdž)i;mDl60qcHFMRUMK eJEU\zs1*3ԧE7v8Zt2"|(,1x n]7 kSCΒ ~6a$a?x;S2>N$GQuZa.Փ\= z LiRKt4笿T =+\ Yė]<'_o˞H6{K1ǎc%x%|$*%_5pɿ~yEF >jO3=0dO<~f øL%Mp{X.䌖8ɀ Yxi,Pk>c9ɏ!2npa/L=ǿ=E&ugT*4fO<2M9(yS ݃l*usZDN5C 𩨲=k*3𙞆? _ł9=u;Dc? ܅V((c~P[Wti\4-`7ת I.z;`Nyo xzŝȑ#X1nZlmcTK/?`l Bz֬;wI]M) o@iEeW'{(hK, aDaeˠ츌*XKGcܹg9$IO8K6Oϐ.dʔn)BREğ1忞 꽰P?ucg܃T^QXTA!GBQժy3;;,(ROG*4 8asyOw' `;G9у&ҲE (-Z{ 4?{-9/.cGzt)E(w+TEՠAߍ,YrfX?C.?< @ ku2U$szv͚Bm;c SOKrKErV$IbdRך_o񩨪>H̆K|֒׈+W`_^k?J4:|(\T=cTkMUt~ҡ][C kUOefɒű9셕{e_f,.Y + XON~ k3*@qG*OI0n`1Ɂo_3nz %`qq^⫔_(*mӢ<-pX=7~Hc6,3XCm[Z^.X@fcT!SaqӨi3 -r3c3eXMn7cՐ]5O](l~g)n/#*4ԙ$H Yf_."alm`-VKN ݂X˚"F v|TtKOqW֐T|-)ZOogy[1o[Ixio>p[n@->yRPo*گfʰɨʵ&'n?PШiђp[eʠrz3Er*o|˕*EUW eJWznA#(T_=(*ʎ?jT(S YgA;cq'Otg n|@[mȗT~ǟ_~A˖ժx?cT=wĨȱ䧊5.spWƒ5vPT#JWX,} }_/_U#ER7pQq6qDP$K&lF6JagWW"w8p tJyAO$jbTѢ]ۊQ +Y$1Gp"8D9+ϸqge)o.muSպWғ$Y*=?/].۶2y*8̗Wi,_T vk ]_Kԩ.3G ̹ݦ*OcopmA;yf 3ZTeƶkn3#_CYT2e -ET yiQ:/za<U0XGZTq1=P(H/|gƸPfJRΜ9/w"rcҶe30[Δo)U4*-C̞<@9&pMuJ ӧK+/ym0{ &@_?=eV_:ڊk $I^fMHOʜy7_G)PIŘF>YY2s柡X e~f %5D_> Ɯ6) jҦn[x^FLHP(gJ+Hoi粖{?HؔPWߗ0W\$rAkj7u2,ANlzYB^YU =:aefjg,UpGpӻ`l|&[a ]?~4>B(^ϛ)ߒo&{ ZPWt@ʜ)<3}$:l|H_C狯\6ܳ$pQ\ O!ݱ.Mgئϭ; UxK(ZTOv+Azl/ɰoB kϲq=VFU 2bxvo?G9eRWi@R1pJزaPF-CcL!DIuElx?k3Gs>Y^ߖb^˞&gWUteib Vc&~,/ɘEY9? ħZ%烼XYYǢqgoթsJ*&ӌ!ʪ Z7vfpgTkL,ubXedyK?I\pH#|~(E9( 9yPwf'rGba ?r02 GgZ5 _6\(NCIBwkTh>?#F9' q_uQfhMjP ]؅ ,f^4i#UIwGv*Щ'>g=W ^|*2wl,D&Q`ŗ2tZ9`-ɅiRZlM]3(h1~iH#gvD=~O Gݱh|"c|j%M>x(;u/\m\ܸ~/6g ֨*ۿLo1;U 0pHـXG?YLǔG0PVaq49Wdqx 7 fz_ ҵXFP)>?JYĨ|y[ǿ0-^ J|*ڷmhl byB8ĨPs&O_AZ7@!w*Քg?-`O^W_ZrgX#ms2k޻Y嫓'pgV+{6X8pIhHDYs=,[!b uo J w~.#5¢^iGKe˔#*I[P?Џ79b.@:"}舱S%\M"}>KAw^ YR@>gƿGD4y \ZN>KgX+fh (avYx' 7;jepMiV3!U7AXTAiL Gabƙh*iZtuPl>ff}^g_tԭq M( /U+U%g0ڵkwuOwE<-~T#`LU8zvɏğ8e>MrD2z8]H+7}~9ʹR)OgGNTyu?DY'ynN>|ٿ8pϮ$wR:#>4ETT!2Uo};snlܴƼ*DJ{wk 5KؐgF9/qN/wZҍtҨ"b' CEg#b7vwJ)tt33,xΝs̙SS̨[n=ӻy;&7l1hE ~Os҉;D y }*ns%wrYڿ]{f 3@_ñ j#9\nϓ3>:|Y8;9|5炟?42wkXsSo#|TYyI4y>!3‘O޵̎*ጪn\Ff8X:K.\/L["UPB^!Clx~[&&Y<k9S$CoϗsVkgv"WMA?d +{VUJJ5+ƿrnux|7f<&ok,U+UC.3ʺ6ƻ}pFt@%ThTjG^?Q,?tڣԫ^Bf/\+{}|3ص.=q^2BЬ ĠU8{._7G,3a ^w/Ă8í:4aԚ/Y/!CtfpW=p%|W7~*Z̾W R<Ꮗ7 F>AN<nsq2^\ܢAHCᆱ2L8:] Ըggm#t(q {x #1[ksܟȐh1n,QFjMt7[qfbn)s9Qo9댮_sfFYV`+8}.˓#9jzU=X w߰a`ǣ@B0/Aڭn9+7ߊ߿UtrO0@E ]0}h֭T2~تM0ϥ؞gIW췆 ӕ_SL{Mi;F>S2V1@Zou?^(Gv CFڄ3V`EY$薈9_bϺ} 2s)p4ПFLߔOf`!VD՟+/LQ*|[7'~. GKVpӻ Q <<pj*O<DVܺ^zBcǍj3ʮp?VNʕ3Fs?Nһ?up)JժXVr-PJs*UȓO<$ܘǠ?;t 򇫏N*^R +|ѸK=H;B CA&f>ex,Y29{-Azo K!m2wDw%#1m'֮5连rg \J_ly随5}rRVv{,\}9x)OGn~y*m+ {w?օтo'˕-<+Wz^:vE]ٰ~2h]ڟ~Β!>Š*ANA^{3m'/Ŷp.b2cY}UNMlaiiO|2oE P$@UC ~}][+2kK$yD]h?G;t NdUIgv;Mr< |˂ !O\I?S'`EIKa Z\78lBqB]uM%gc6?[_@[?(@JJez ?qV^sCq5SLi9$ŰmO''ʸ_>7Gv:??p櫯)_b6C|q)K8S{DqЃ㏑n]^lղ\٧w?|y / z֌Aw` +P? [ 10С=+ρ2k}ȶ/Nx+>{bs:Q4"c5J\ut*A۾hepgvz9,%>0X) <3-w ـ~|'*Z `]7d) O뷡Eãf((40}^W`2<7eʖƪfrY]7aB& |XnXz:@zZȷOD|2Ra Ep#|"ۉ ۂ`b=BrzIZD .3E9&@Y\ݟeo!w0})raIխmz1 7)~-'MTQf7Z4d0K XQC<. }‰IU;n+贰۷Rsz` d2A>|Znzzϗv*gc򇻯ܥPWoۦ\cƐS`'vm o$Ν#?;JLĩ'>ߥ?_9KkҕtkUNt+eJ(?8_VyMΟ+"Uv9ΏKr[YVVLJ@&m!}JFս 2r pFU.r8u/Yݒ% Z6?5FeN|" ֢[&iyS*b9VTi0hbe55jEcc9hIQ H÷ӿt͖;~V:aIWVi[ 8–m, jLR[;n5@2:r&gp#u'j@.c-}&?|1NXoSO=ې۫(u2}чn,]!n4ܭmx;]:3.UvU0+Wa!׮["<?gݯӭ8I}UX^-{!A +UZ/xJ>??k2id/Q#= (/q|CАmKs OL>\XNiԸ8ґby3?. *s>}['_T)v>r+Jl谮U;g4C2p[ 6/`{l Pq~;~ŋY[*y[ kjU)ݞ*^\V 5\/an:y9K/pWVFacy?C~lTnAbKh+xFWo6?k=z*?rՖe&Xh@S7/Xro \-'UR85B~oj~dzϜփPSynI~P9>6 X&&ZU&樟o?۞7?^=̃h-Je?2\ϗ?S)Dq61}ZָBExs۸N.ot̳u  mٳ;Yy6@Հ[nJsGEءe9&UŶ7+Kq?KPR >ηôؾS #'Lt*&{5+9MrF)>i\?k˥Ut1yTUSYJg+nzg?[(}l]WԎO3,UXU׫VBn8UN|̣ ˽88JoǬP(O^@v@>"\'c )Og[-gclW*-&'` FE`\0Mx-wB]>/h yE;rdnQ/)}/E<_2In8z3k >ҹY\_:j|y׳P:ԄE!l*.&R`E?%38*2v! 3}bQ8k=Wt`v运,>}D7ugsЊ}֥ e xJ׈Kv}01{34jHo)~/m͂o/3lzZamy+f\ -2Y'gϞ@작 ~4ỎCۧTkhx)ܘ~}}!?~xE|3,IW忣\t&C_oS! =_߫xOlOx};"[5 YU4?ٵ?tݍb Ƀޡ+ȕ;nokgSwCk9vGe &pc?:P(V ,6=qbN r[嫱<ʣVR< tz3}qbT}qy0g]킁4@y?XNhop uk%1b@&@B&V#7~~ X@iAE0CL>p)xisCX@^4kT_0+F9_F!c, It&߹> _&u~ )T{άjl /)j'Zce g IC9Ȗ-7tλY &f0tM>h<jԨgD|C1d)` Dk<#b>Z )mG_?_o*L3v?%ݻ#}yݘU( 8šۊm?#.J❷M΅8PuYʰgYFjH必-od_QSؾ ??~N_ AϨŠjlq'CK/m7Zޜ_?'?׎p!w_eV03Ȱ%vha?`=y2Htg/Sz༳aݑ!#ؐGCuw2 l~xEk϶I8ڑ?';Tǔ37FWT"GQhd\5nH>:v=8TLH \Q [iB,X2$5(1ޭEKzFM,-\ x͛5,cJ*ϳcЫ(ٺ|z qy?||A矗.g}!MuqyzcOrϭ*Xp 5{znF>Fsxxm=1-I oSnA Tbw]r衇Dnk`k2`<@b;7n4Kxr(̈́58SmՓN8n@ ͞n?6W`?rhsptQrmE. ; O\QJDOAnNwυ568u#_`Rf6&t1LN! l%|އ;PjA.WCZJS`;#r͚5ޗ=ڶ&]x%b lWM><JTin]H4l+pyV | `M)[&zekߕ m~o'_њ?G3#Y=O?1cgK^18fs]cQ~a8ϤA*|<Ǝ~}5M&c?0&Q4>CTbEU $'?$2r\&faEU= x#W#8%=CZL,A ]( Ϻ`++* /NM\gR/;4Ϙ>S֭_'J}_x]mxXߣ 3B3r<ۂA-Q_FM:E|)wޕs{+|ߎ,?cewKq0_6m~CoG`с2R3 ?5c|*Pxc 85?|B⹨bMػcEe@IDAT l٭UKq$`AؾE̶n+~X$H}ڷ@d&\q8ajuI2# gTE0܄kc. K)!eWWd[Ib \eݠ*( O'q1.WF')omUdz8~ͰWQ%_e˖ʂ*S=HST<x r=wK H5kVc벲Վ=֯n] 9s\wu2[]1VLyi0mAltl۟(ڟ蟬0?%5cde_G{~ eg{k-j' aG#Ծ9S̐_Ж%KɑG&Vhm#ӿC-B4ei'z3z@Ys$=ȑc'U-1:q (o/0gro4(nݒ.yMywߕիO<.CyV֬]`|8ԮTn*k`oov^1q3\5;a_L2kKO?c2UH˜a?cWϺ jիIugZJŊշ$8.=l#4V^+K,3d¤2oBH;)u/O4{g0c?&L/Mڶosmt+EFB(04Ŋ*7':aЗw"n?~ &b.x_6/z[VfΚrHj44AN4(.?ۈ6}Cj_~ жiRvm)Y$ַ*G&gg/'g?KsȠAh>)G2/?]7ߦhby1lHKh`y_}`^K9G/yW" ~.PkZemo_Q2[1} ޑ˔gq &Q0Pf\F?Tzudi6 (BҰJiE=`)0 `,EF xg8;HŊ2oE믽*7_]ْOmUoBRErir"'t̒kHٲV_%B/i7?}L 3k<-WO@^u'_^4"eG_2A甉mcO:]L&3f͖8~eul8V]Ko%r[P eXS+#+U :8[4jP2֍46@.N"l)yӋBێgTL!IUmteƟF5YǬf4 Oĸ/'%1a>P@9CX i -OrWeb Y0N2E zX~m%mc9V.}4j-]]U(oboLÄ35~ơ:韦afokbf/O1?L0Y9 -mZTyOM.+2$qfȱZ^ %CHxRR80)rT sSB|c'e F+ϱ2> ݚh"YiS䓏?~?eA)ڀm%~C9ztZ{6k&{u(t iժU%ݟѿ[ :?-i7X韦zca`_y#ߦt&r#a<Kwlˁ*59~ T#cpK S=Y<Upe9(R}AlĹ9xo<^pe_l,֯z=(!*V }d\G1k/?+0o?w4JTvÒҋdz3 ko201'NM&NM")CIJF3P('iA9eW6x0ǐ|HPQ4^kY`x@/ \JVZA +'J/.%R%KKe𿴵ѿRYk/!h)&\3k_L1$AH#І-Le韦i'ioUeq mHDQugT%BZhE3THpc#pFyI3Q.urI,C;9`@L'9Z>WLl ^"ë &La韦21#X_V_f&?W28Yb'K0?X# QEmˌ{ Kz9TBKDXos_n$VT1aFAZP@ $J*|Y\? iQLj(90rpxa&<~w0៤AH Qqjgtb ?&uOӿ=`uL"3 *2a'`'ITL4ϱ?2O ?#/?40vt{Ψbp+4^ hg(oWnNSRB-Y,r4WTaґPR|- a./]` 6>3rWIO! O̅40!@!M8qO چi#EZ \T1PB? x6;`Ё`pĠKz )Ӵac BCF[GM(E*0fLw:Shxs ɢp5ds<:1mƉMox\`o')0.h{?)ŏC;Ӭ1k/}o8Ya%=ni7h0zٟv1OMIao*&9:_uș,D]QU|p=#?Au D@U2 yB&:X,ϯIՈc'Tyܧ)kbؔdL}ʈrnBIHTFàX3c!?d&M0\@фbi'C~UITzLD_26&dft`ӿ{TI6ɎaA-8"X0D9 SڷcOc1DTX娱x-M3;&:ZB hr"|!d8uT'޹;Vw/֕cˀ!#a/a7XSޕNL?aoq \ƳOA3~<w$3dij7b&M1 8ۍ 1doӿM%T :ܘ 3$P"En\*̭"-!x;[cC\HuI05@K廱&qR{^1,LcH ģo&*1ahEH .b_?&M0K֘|4o?2|o+/ ;=fG&k4#AC >{^ 0P[MMD4/\N'"K r#e4Pu,-4JP0m-Ny8<//[/Z._Mo7C/}>8_?&M0Oӿpj7e'E6_A98W'wo@f7?Yj'PãuƑ TA;hDT,A6*__30gfٕ߇uaӄ;DH}jwG{eߣwO_ L4pa1ct$r& Е&c$~&M0BO?I U*@QO?9%A!z_|iN,?*P𔼢*JLsҁ*puY˭ %AʄJ{7;*F"8^RZow_niDrx\L)Jnb'Unp6zg߈תbQ0]if`|4baNJYsqo[T$H@Uv|`8I\:)nj6o\qre9fԦ|~ť>K`cpIryCKg`'7 N~8^i4aфi7e fl'&4_}o4_ȁ*06DƟgTyK/^N<waኤVu_pT-R{rxY|<&m,.x0L5zLaџH<Ћ'07`NlAKacbz a_f:EO/;2TAj' /@mAEF&q ںU*z u\ bMt0Шq {L9E; 7\E\!G4gOLweLͅ(+) c1c_?L2oU fiu8D@_Zc-3JigCFb?a”ijU  7>f Tm4đ(=ӏ@5ŊMWeoL@f,s"dL|EoIV'YT6,3 *Z Fq1kA?0:&$UBifi'b6AOO) 4 5++fq¤:Ӻe PoI2#"'uѱ:B<ϣM{޹wR8_[+ |HaӍr4'> @ 5"Q-M?OxeoGc0y?]\HK  3v3q+u&2ģSj$eAD?IQE,IJ8os#˸D*tTi\H=1#>|`nE nȧmNa$(*I4KTIu/ĥ#&BÄG3 I/1SAJK4DT@1clX3cW'0"Mf\N}ϦBZ0h/ H0`iaߦ0oӿ0 zpJNo2LbfGgNvm۲k_mTײ-߰b>* T)xπ>:v<^R#WIOYPIKrvO|,5,>Ƈ_/ga1k J&M0}Oӿ9/?ں@R߾ybٟfIifma”i!i ן|QCLYT4BEf6kT) ["djި6J_F!|ɯawOS{CA$,>ÿCTB?gp_B7)٪W`ӿ0/6z_@/ b/19C_]QuF5ďz"]SA90Nbh4i.Cp2 &I |pت/ INiݕx<ÿџ??c"ߚ1k:_ olYJbaٟfCmf:qUqIAiGJ8ܘm7(dQHt"RO[*_(!#;'ݲ\ۦ:PK—ynylE(r"!ȝqJ X%,I%4G3$ ? ?L?8jXi'S䝗!W t@fD/fy.+5oeM% ?0cG?s?6-{I:91~?}?Q_FUHVTEY0A)|q< X*):z0/LrƄ. Cቸ! r|ÿџ??M8~MaԟM6OI_fm;:a?EHIi_=o gT%9ȓXQb ..I ;/ +dTbЋ"B$.S*U똙thf܇4zXߡog$?_0G?&M0 Oӿ0O0C@2T[JG1h?GB2D`7tm /:阤>{UIɢ&ܣ XbETG0|P|x{r L~^BlDs_To7go8=`GĉӴL"nXhE(O-a_feu/!e??4oCdS>ai9][1__&b|)e?))㨅a 2+ڵ\zc<25P.?# mW?Lr&D|*'}D4 ?&M0Oӿ_Τy@ |Tǩ1:aٟJV67Qfj??4ϝEN Dэ&?kY5h/L#B&H $w)b),d>p"M<,+|ÿ_r{?PaKE/!} ^H/&|:LaM?Ml0x0O6JZ0H5}J$C^+ʜOTd_f۟3g@dKUdtѭeEUJZ-#fjy-L7؍=I[û|YYW^!rKwвt|,VF6 > F 9_[1١RvraM6Ńӣ c_fmfM1I*?(a?"ǂҿGUX>܆X ;r$u4m@ӹ|: Kȼ'ҕ7K l()P(7A/z 82ȯ?:xeF_?AR%L0OӿP/?Af/2HJv^c?6#(SfM&thCJ1vB QMxuXlX=pXvml?i4O賩pEײ_ǔs(o7g/eIA/ &LaC3f9zٟf{Q/RijW1a?^i6e"ΨΨ1JUctXU/@Z w#3 gTQm3"rNb:tfqژs%)@%Ʋ\dx\7Y3c_?L2oZ&f+j3OdLpOn,o;3L*3g͖ eKeuӉ4%Sa3?  īA'G@*֫gTl2CBw-JNUMRYoX>wFbEl֨~(SwJII# Uf&)|Uux,u/;%.!1D ~Aղ7@bŊIRDI)Y.Y:jRk v Uc7?&Li@S!5m.94|JafE~?FKEjВ(E/ &ԩݙ/x/04mֲWvRm*U~D:'gm{wΨbp+4AM"~XQ?.2h $t79`A =]~D&>JG5̜侘Qaz? x6˗Ɋ10P_ m_B%)_o^kߙ 5cr9L]o0cM1㸭_?Lȯ|r_~S1Gk5i֤ԯ_Wj֨&*W2%KŒǘu{]f,o3L>CO, ,Pӱrʙm' qG?&N]D*ڽP5UxjָYvg U𣝝opa J3F0'ˣc8[n636]opg3!'20?)t[k %kzɓߗ~I& / @w <|k36q FtxV4mB:v(Gy4jiK+)+UJZ[>{?#PLLo7 ?5kӿL4ofP6c#Ţ`<||' hFnVr+9qG?O>]~>B}K)-t9L{?*-MD]QUx o\O$bp1CCL5]Ҹ* 8@wsF K2'B\Zp^al ._ ]tщ_ EIb293Szy{۾!׻q'\rd4n,7d.UJy H¶dgBvI(`eG2]t} ӿO90Q(/p? ׮Y#Ζŋ#<,}OaRَ4rmm3_W\qY~ԮU[J,uUB7l'r 5OkW \@HDL@"&L1GVU|__ /&bBrƩ'bTMMr*NN6U^x-Yt9V50Xe`W<=0 U۶hO+ĢLU;FבMV4h G1uS@NlS ~sHB0WWO.(wo hdO_l,\HfΘ&Gt,YYi\+zO3{qytb<۟>Xi UVl *8kJ2Ϛ5K첋.]&@ѡk*qB@#$O`ݓ7?ϑ??M5񁸲商x_M4Cːe矣77FI@>/#a).y4hghigSMO UrG^{%akFU$ sgS(ar2!J`7o\WD:v"Đ5\N~FD/`Gl]GAii XK?sL N~W]%~;jvj=ΓK<!j&J$rK <͹=x%=ԭ[óZ_v/V Պ7t )[{睲h;ְwdYm;-s?/,\Ho[~<$/Bؘ7;綪űjzqXG-|ΞYt|"R6UAO)S>t3[-=[ʔ)fjyɧ#pDҴIc< 8'Tؓ8y;30ȝY',QGYԮdRreZlGkأHrebJ8aLʜ"WwvmevKC;nM۾)&ӯojN'U,GEM_^(CZ>w&3PϨIB0ѿa@k??;-_)<𨬁.u<ΤgvE)'N_F;_?-YcQsTTlE2a9PEۖU9xKŽPM'5f(#d W~7YTײ)@}T..Y&Qr}U7Ĺ|"Eo\ oWZ%t><_Z5ynPܥOzeLZ$?(ɒ+.|a`j;ʘ1cd׶][ٽ^{gVϘ9]>Dٲ~ɠPP?Fje+V*69õS)9Р2v)̒gei8 &5?WpNɓ'+wz\"n5v81#G ѮlBٻa/.像>v`=q gʔiyJ[p&hذ0uW?%o5rɧʌ3oxJneW\GJ/6Ew睷;&_w\O+˯D]Ҥ[ka 2Dn*QSl >B֯azr W,WҀ;&[*3d3Ͻ809c͖׌( UK9n[D+(qdY*6'-7ʕǪq(_~m/s2S(G?/^T /iK:u_Lصe iH'u7idx}j_KڶmS%xlB' #L|OgT]yF}EX ѫ{U cє2=_r&cǤ(`sEeɒ{uM7pl;' mȶ-iﮭ}X9w)tQG%Ft4W\quTe*ӵM4{>ڴQ @P5kUO>@6[2ej&"M2`Xx PrukySN}  !k*̢>. @ݙg!R5k+k3\bm/9$X|{-L[r ˤuUA6䥲u):y# !K:@T9d NW }aBS./PW5mY~=*,O<s;qaXwͷ$\U̧LJ Ve*j̋{ yAUVsϨ4$7yn_eWY?BXtVםwHC=6f7}}꿳7%3seI'ro7 cOԣ_xu] ]1@]¼{A*|4)dcfRw$.[Ϩ hzULxREQ2q-M3XΠQnSuҵ 34o(_<}WYU!Sٳe f_г|ݷ9~7 oz.!p͚SC:)t5nlR쿟 ~IRq^Umڲo׮~~ J?x_iˏ?xwGGӧOs)/̽)\ACt 2k߯&/4W_:,ӪZrns}Ii'CAŬkAJ*gX=ɋq2g|-^ #y;y8IJH[${۳ceJ']UN@I]~yR~ ; v)rײOUn/MV!|1Puy7_\reI0m8V_/ ?`@wLM???Z U>@UՔ*ǻKg Tm?Pª !~,Bw}e#neFW}mvU{il1 ~6vG_u-8srq O p%̖Ƛǟs0tԮìQ{rN5osA# l-5*Tm8|2ݺ]wHȟ^8{/ oV#O[hRA ~컗4omϿʬ9sU*][*KpF?GҟDd1<>>8$ϯX萧#oҸ֓?1i;gmg]`]2m )W@@p('N"**b%#XT([^WժYo΍3ɵdJJ͒+Gy$)NuW]Ɍ 7?}un~DCm@IDATnZXW:/6Xʰ3_++?r2?G[K:||Smqdo*96U1)| c*>7_} E]S/ sSO=oI|\أmp῏Wt N8/0Mmhs$KVgKk1X\l֫QR.?{9o.%{4)-T`W0PTEzI{_>-'_Y:Ṱ_t6:(鯵 |FohEnj OL?UH+hh2ih>>N^]o0C`z7<9޽z3BfbTnR{͂?Ié\ ;B90`l7ʭ4MŊKb.Ch1@IΖW辺U04cB9Bר!_p&]4wq\7 d֭[AƎl]c}Ĭ Zp/_Axʶ?r~Idsͪ7pj ޽]\ )nVyC>-qQJ3lH7PE`3OvoyW.to*.d}Z3g|E~cʋҬY3bLTp{kY$.#ݻg~E'*lmn]OUW ͭ?Y6r+bmjլ%&i!CF!\s,{V2}ŧRDIְgC?y[QuIuöGwh ^|ukCCCkc۟+`EU?~ ΀*R%+lw%pɧZmEh3T9+8PŰ2§]w~\駟U6AsDb7n)O?qo!W_wTvz Xa/p2i*VoŊ*"Oa?~31ߛ08trc| v8G.yb !_0'/We?!7nUVXBY}`5v,Ҥ==Oxuロ\vE[_]=p=咋np6C+Ꮓ 3wq[bM_w  /_$sd@U TF >?O<+*V~WFUyf+k'.&5K͈6ed0թ*V%UwX(w3VoJl~ xyRvJՠCuXWTS'Sk7at[@}}G8D(zLU>mI2Q&+4ӭ0ۧF <>!8_(i"8NM:6MqE OH l۳GOI *Av[ϜxTÑ9SwUW];w s9[*9 †!jS_pL~gz.^H=>3ҽGڿ}6ghob8Ia>-[| 矘A;Gkmvn,]"03NjUJ#yuq:BzFzlirWYݺ)fPyŰ⬞ƧHfjSL)^L>C6dg'!vGulVNDUbھ}'[bh83bTYZF1utK7n ZN͈{8GKj3zh>s&VՕ&pR NM o>G7A=:[AKƅ4yl =pQ^_(y~smR 9Pu饗D7EO>DX,ȕN=+:h ?/w'ԩO8XMɾ!i,ĹXbX &6{钥Rv-iբ*fZJ摮i0)4A1!=ϹVT>[ӏ?#?Ck/;JgBϋP Y2l`Ngq~ll-;FJ< E7Ν;WO$ڵjaV7ꁻM31#sT(˫!V7m6_ }+FjJ+wѺ0-3sXL$Ϥ|^h8grza_.[dZ|Yt:T,j cݺEYׯrJ\RVz[nNX)%eK=K|TT8|"n4 s|+Ͼf TiH۰AfR%K__^ϊna?Ψ*WvSCcIYn)WgXLn'|_֭-}am!TF/)^}ʷkk|3w.Mz^y?/.]G;`UE΍SgUNv֩ZRpBR3 <){g_J%Wr?\tW,ݖB~?kց }:Jsv]ȓC姟UoFAN۟Fm…3G(ɵ9?y@,Jw %t/K-twwH- *H *4~gܽ ȫo?F|̜3q9g]MmԲ)B}DnXn'nr5dtW?s&-ɨ!aJQ FE@<b.U~-wc"pΎ1ʣk_S!t뾗 DKI[bوC#;Jĉ=2kE P^ 'OTO$Sa.;bŊ WeKu\߸.zJ9"_!R@(Oيn~eYF =="P 1.^K,)alG,UZ7Iay5Xǿ-[ZqVHm(/eU!sشΗ (\9r}]Ӫ{f?T*pl%JHsOX"yO9>/,'N"3f2  ԬŸ;k߰AKYBLdlHjXv?{朔-W?aɝ+_ o۟-=꒔}gʪE2|7Cβn:SŪ:6udqo+,C[{kpVMnhി 3PPɄA⸉̞/CoOvn,C@eZFF Zu "K5Ɇuk}٩O  Ք6@ Q [P Ue?ݱ,TԼ"RQE%ѯI=w 2x_F5iqܾU`ㆎ'}d-6G}ῆnMg ; ]W*`{[zdQܿw;+N*QOj~*Deի ?$$h3MB[" \J0ǃ">OyWpq[$D%XndŲ%.lzש[*k/4XO{ bC^rwtUG~kX\ķܒf|W|))S7`8zӿ_3{֥WqMԱ;J͏*a<}I7gҶ?˵k~8>Yc `!\{peHe1{{>L5d i!yeųl?ow]f,^9p4!NO>R t>pp§a$,ԸMf>6ר oX3`5M]zegh)UL9K.3fMˇe!#Zeɑ610a3(ېB:k~A(i 8TХko!]jX4q2?(g#)ypmmب.cF_ߔS`QEEݻI#yJclYQZQp8=(`]^Zu80:j^]Ⴖ+N7L^aPఖOI\@fTA_|Ua눝Z }>=UYh޽y.ORZ%mk8,zj=O i?N8UXo_Wr$ Q߾`=U7[kl3'6?xL -F?0lkG3fͅ[yf'З ܍Z*/5I(+GY-+zM^'ϵ{^2BFșk{#=G۴u۸Erg&eKOߓ7.hͪ=A&Zn!]}^d =_{r-]硟_1]ơ7 ~nҎnb߮?/|VUa% CDV ʠ8uS\%#d4  `>-y*C1ɂgϞ> j2 wu~0Q&NI͡ÇF.AFEct7l)R0 GRKx2Mt;nXG_sXKR:6gJ67lu[|p1rNedϱ.cl.|Z5MhG594Dے%V,[$+^|jfϝ/M"d g6uLf mn_Z~K?Oj~x*黠"B~~jI+@e(< bE =1~T?g<(37\~ Eo-ܾEt1 rjC2edo.j8+a%fZc/cǵq+Y VrC17<3n"?NA6[HZKa0E5}~1{$:\JQI߿7lSCR>]D&޶';x$뿎=UHkBHFٲkU4OZٵE괰(#anߑmMT(SR;4\z a}zӧ Xga\z庴MgʐQ¿>STsӼp@-gzyV0(;[R’{X[ƔI`E?n)3`}(-U\*+z _qD~TXNFyxٲe{.qW^k駅{(,|u_*6S|3\m2gL4G+ѵ?DG?hQlS`[YMa/W+SV= 'mb} B>Xi,PZoܬiڣ+בΘpת&옱"P+SZF?JR^L;"2{Lk7'Hj}[ң=O.ZÅ9u u<}#ɿՂb`|':G,I@K V퉢 BL.-fM+]; tz/JO4UXc37j3[f%~/|X ~3L8b?A1-~QoӌzHoTu@Xbwm<,=]=sJ[P6BԱ}|QtzY3f̈i&7qS&OY2fOG ZKp\CE~ Hi?cCS4sqr (q:=Tv"d_˖_CCGDZ>U֬YPj;g]93 $do (˦s񌋰LY E4j\ &P,NtO@˗-F?zXf\bh’VF,3ѣK90CFڨ)~]6(ϞO[.,ò1GF{Y??M[e Z ,HKZc{s1Dn ?}l.@k4q *bժ,lbLx-hHkso\>Y; eX[}Kyf0(`2{/wp$|1a٢jE7MiQeUh3Qe_(6ڪ=]V ƨr?I'~:ygs`Q5d̢Je8>e@ڵZZˑyHܹ"\'P̐x K@l͟ IF]hnؼ!Do=Psg:E}V'Q"\0EE \ᦍw?탹LisRT ۵m+iҦS1-\GOoǖj9e"X-[|My2xZ<"$E%4ٷJ|iRsy.ѵ~Ǯ:'+!.y A|^"w0^Foa9S%5oY1,Wn;KXtwWK(IKA^ n׹@)gVZQRÊV|D[E\, 8P>*3Ck0M( PX@rƤT9ciW_#/kَqf(jK`ܛ0 ?V#nݼ-W^{ 2nt.U*@9`qE0*!=iC}zOb_vC%JbL4weXnPD|OێԂ߮?3eHK&n*hSƇ~·/:6slǩVv0l 3ŋI8Ȁug떍LF~(\&9{NUVt9{pL](ͩ5tr-#vrC?3KCC߭ᵟiUPT|oMŻp@~X01 y.Z/H)!۸XPlI< T^wɣ&WZ' >'E5, J[L$n8Ln7WYCRP&rlKؠ/q94QKwц䏺l@~*:pKU([)k7lVb!a4[~C&}ě\2QFt֙,!p2':L-:˟7oI* `ܬG5w'W.O i CA/ >XWW?mt6;=M{&Qe@X /GMhQWoOg߷ԭQ SOXo͏kx ~2%}2?c/F X?$Gܹ0+Ipm6d wտoo)Y,t^A!43Ӛ*S+̞5լU'i_|HzCQE5>C߿{_|2 ZH c>˳w&]iB' /Cd`E!2;^'/WQ:xIV~5J[;I?)?ߑZOC&yH`};'o`ޜC}QfvR})UScC:;IAoKq<焢WEUo9ްSr=W)_z&y'?c ϐRf ՛4L<=p>N@ 5Yʿg|nz9֩9U+i-Eԫ/oZ1cP8Jo)eĀhdeI>?wm/C GAk2pzL2tP1'-t!OT5U6m܂s0C=(Jfn02 c8¿s\L5o|7?<uMJX;O8!wE'fۦ[ȗ`F*ؓOJ'6dϷz]( cX⏇ Ua#4VWPt/8H傢o٬4ҿBWNDG=jaaCjth6sp[ɪժk(kG?M<۹J1p՗[AoQb%`EJWWNjשuMQSUV}a6vkۖM_¯Zx/X @(22g׬xiou I?th۟6Ɔ;{2'S2p@(^\o*o6oaْؔǂTP)Ħ[&e`$CTTv-.NMӍ¿uZxXE/2ʎm9MF$߼4yXn2xpC?i(P]ciuᒈU3g`㾒mZ oAPoүv;HDlHC6d(SXtϜYZZ ?bF[~`-jqQCo}ny nXn޴IPYJ*AEUPPZ[aMD@鞿P1үFOF;\(T9 :ʘ#% >xd&ׁ;74)sǓPIzj QMwrWK{YE{b(Xp )/L:žt{9=;x b^>%8BDnj${|W;e3jnͫNDÈB!ɉ Y:YsF%[>U%[6,dq<Q g͌uR=n3İՠ\# 8HV-_PPTPWP>u 76 pw[+ n޳K?E}/\TRj]JKATt\I7g+忁ϲI( {z-k(@NfG.X1XO2Sv813,L9 xUܼXQl 必)B=3 IŸ4fq/WsTޕA-uCʮ@ۭW?pjӽh.ơwAש M6y4=n*[:BQl|W.~+̟;[cQ~URǿ* W_MO3;qSE"|ĔΆVοK-^ǂҥKs JgŋCh'ʜ$~fΚaX{~Ì]B M=bMH8?|lx ?DqN-Z"F;_qjzМHJ <*-/V8EgN 'v*5uOyV \_| EBWҶ" DA?n :]#҆/R# ibyY7Ӷ*i$r'CuK)zWjI'&bLNj)ieX}$G)}Evw7LDҵ( K)ImE1D=9@桢| 3sMįjTL>p@eT%:d~ _nyffL~rHJBQ\ }Q T U }Xd#Wɇiys=_э?5{NQ%o|8\lUX+$^үW_ɠC\Dd¸1+W2ʟ *^CѣjEc'%'.ٴa 9釒Ī~Һ7[a!$Ub(}MB6/#F²OhQU-p`͛7Ax!+Wn=.\@{=Y @Y?5:i ciSt)X8E\lN!24> Hߠ^]U :M+]GPhPG&K? YL+ٿq*qYY&GϾ pG:*5!Hq~o᳀^k93tvf4n(^/uk߾&UQ1y4p8ı w8\QN=W骢GGX)EH&XX nI3O֏|irՑ S&*fҿd1梔)Qsô}3b߽Hph[5l(#f挀v17uU8w.g.r=r ݢP`(R>+cO2 U7\Z 8?j߅ӧ$bжRi۷UvEz*lH+PN|' 9 e_KpXY8GũhV+۴e;\.`@ &°RY+(Q @2v#~T+6%LI(+W*x3%`Eq`^mmmi6Xw4w_apP~MvO~!c"t54v(hV8G}_/wƨ}5c i MŌ͛j %c7P"~ F_ϓZ~oEiUM$}ԑw(lM/Bh?`lG% (~\] 17L "^i&!+E)]iΜѯ>~7o ɓa;gڲm>=|b}g$=RKv嚴b6?wmeeΜXǰpO)qd vM,e Bn=oEUL!J8+/nDS,1ӠO& ׻v+cG9%Ҷ?W v3D~MQ|pE Ni>t+{~&}{-:yFMxzq^Gmܰ{}{&3m$RZ/q_k+a˂fNqc}z E6?y sI3dLzi}.ʞ-ֻQTQ0,9ۤ*ɐ"Ӄ{·OU\V:݇Aa]x`@kheb肁#? Z CEu[oH=ނ[I' HX9 ^§E&ꊵ$+/)Q)<]UQV_ * lA7};>wK߯$S3uMKWCJ_ Ync?m?g i:o>ܟ;_7%N@y[I.G]:5P*C]lmݐSNTQ"+Byi*z_b}S-7~tzR2ۋR.9%6ZT).H{saxCf2_fqZA1Ѣ=ӧ @IDAT VZx,IlK>_x? 6?"HD.i} GgN)TTE]\Aп 8^|L27fLSC?ѵ?k=q$K̩|bX\]~݅O̟ #P@Ź߶ۥeK(XJ,.X896һ:V.޴1srOnYT;uL3IzQ,l@ؤ8iSZT}Iƽ gL_}-+WBuZ 8*KE 3C?7F9TQlj Ru(;w?Ugjk2Z(X0j?N׭EZf RPsk-Z;WL;$N ?| j\6!{^7 _G-`nΤy_eGKca 8n{(PXnR7#_NhhI-iAE ?UVȍXYv-Gh?Ə$Xe~RnJI$)?e#L\'6WįZoe `ڴi>^,Ux2(ߡ`L?T^0 wȿ!yM˵r?vT!^E!dF%:ZAuiaDo f:A&pBp7d,Λ ezT~'y=HNEzDeVd:.TTq2\1C#\4 2 ߼ɼC>7?+TPT#M;+/?C{?b<1pI oG`vnxW!~|(Yjߌi^l6R)׀;/24:q¯f+H$l**ʖE29UI^50~hQ5z[pǶ*Ƃҿ\q/Qqe2Gt Z`i\Y ȧ&#W ð6ڐW*k&O{LAsR{ cVFb a1\1M˕l2,] b~൅Um71N\RQY] ,=xLcR"˷KZV?Xn gϜԫ[GڂVqq.{r. Hb%{gM7}Cka *;FgyV~"*uޡ:U_E`i䳯w@wK!ɓVsoĶHF믜iQETTZXhܬ CBЕyb:A0ʋV5-DU*+&8;sź8Ϝ ]y?dI'')O>}--UɒIny gHtGjhFwߜP9AΞ3-5Qbo KqDEOH6 XO* tزO3iOJ}WcvRVMEҥKj5txW˷b 4 ^Dl~%>XTY4q$F1fm[(l˗O'V n~ZKx)[Q~ul"uƨRxySQej*͜I9*|)EX}ZhRR.g^2m ]igJ m|r'E{Op̓9-N-{Ý-XXPX̟+PHJW4nJf^I=lSfOx9іЦ&| ?KYB"gC[ W_@2zX-vQfHn٬1}^9NæJ-p߲Y#/ؗ9&.f¦mZ4 }S&Czz1hڿ7u{GU`iU$@b:V{]OQ?|reQ)+o?/ PTDo­aʔɐ۔!Zi@tiH[(|۟g 1@.a9*"<~ UjT??8LT Sd|dڳǟ^pWvi_`#ĨrU:FXw^99l!B]ڵ[*Ҵ|5~tk Z91V1㦺 sA}ngV7}´Vڶk/6mQX3c2>7rC Gڵgүp#`J)|L( ,^3ADBHWۉge!O{$ cQ dG7^yN:VA[ rv8!1?;,EB=Y!^A)v[ݼW ֝;hTv\waP+.?QZ,~EOJdyA e|A2/ r#3D?GӿB'N%R)s9p5U3ZM"4,Ke=,PKDZHI@\.)dz]IO{Hp5quf@.;;WԩNwTի rx˚Ld"Z #ǎwSSK"kwRslb`sоt` `ȊY߾=_qTw&JgdsYJU9yuǍ:0@|ƍq I~2kTO!j<.4x5́INW+a6,~QEKŋ__Z|g͒E2`#*;T p~wPh+>]!$G.Zd ,\oݪԇ7*'6|PL'FuRۿjժ*0ĩ[p;ۃya34T@yںQ^LC?qd7n" {ZqzukՊA39*iúUY?z ޵E!֮$ ʃE ?Po:¤ǔ{;?P sZ^ єūw0\iNS! qc?Z!lQ2},^g? fh>S{qr/0TXyzQS8>~1UHPCUG3g;1baw8WW*/¿zZN(.W+Tz(tm;eyxj_tCC WQ h]A˦a}&Ew!"ߺ{ׅ/8?ď"*`Cx؍jbMmOA!WU48q}~]`ĥ1U~P\u5(:ɗ}U3d*f{*6   gT:Qm_EC}˛= P4UP@|Ix5c(ݑ4Sc|OS5^^~Zm|39w) LKnݼa6Կ{v#!h8 q̧+#%uĢ^g}g-ÆȦGKش~NL #b7I;whcDP'afdr s?*g1EKi}3g @q={;׬Uovc X .%mZ#і ku~ۃaQ,|M(S?I/2rT|"[54j0m{:kޗǵ_P#Dz?S2Pl;СӷQO֘*#Y1ά醏Ruta¶dџnuFèTԷ"ޖq:+!FUǏ^|y gn)>IH%X`"aj s!FK1'@͛*6Y'EUR@I2K1%Fk^S0/Bq6Y©-{|n49`*Oӯ2ba-M' \&ymk' o9#sBUYA؀oѬCZR%^?*zҀp.w88)_6҈]T 9脻qAlCIolEerwrD3e1WL[2Uנ *sq$spXLbiYu==å`@1bS1ٸs3_G$݀K*?]n,6ll+fKjXyRčcNuJĨb*L*n,â  wWT\Q4+$=z_ߘpqHWC_ A[r΁c5ka͝V@_r . Bjp> QÁyܿ3BUS`7{,#n >oвxb?nѥKGa|,&i F-<׏ì9,Za&+Z_^|Wt/\ ң\b]TTB%뒗TLqvѢ UrYiPt ^P AUǢʡ`u7EǟPT9c5k۹#e{#zY:v `LiM`2ӶˈD Zw aWO ,SqDȓ[*V,T|#xMZ)b4y)PT@8Uٲ"J?PVXT5kXp]ܼu_P!*L,U=Z 4Pbn%=߿@ X.۪T*$\+:%kiΘɐ=|ScL!6ElY3{eJi}tl)kQBmZ6Æ*O ?@9 4uשܰy\Ɩ#TA/UaQԈ{fq;UBi,PTyYZzpc _6^am&p(Ze )PR@ʎ A*s-.\ ?;EQ'Oś/&!86!d>FP2E]qs%zҸo&bTq뿔^;q#kW]uh hR2F=!|SգDG?? @:ƺ =ѭ"gasa;;75E9b\=>cDu >/E&~B+ݻaQo/V¢7 ut&EUv\,EU/|sg8|W /I 33c.3݇EUqaY;Ԅ[PqFþBo7he#KbJsEرcc- w`cٻwq- wEZڶE- &!2>+ 4/]f%4n.m 5kSo?\1˘8Z`EUłj5`Qն&\vfp;l?pOi<^sWc1ċS^JSƷy[^y5F^>u!LIӘO/܍ZOƏ)/č+rm-B_xObr']u? tqxT5·S?dɶ+%,`i7\I[%qK X+"Gyp^ؿ]ď|I6}lΥC|pj*)(#J[yC]:elfrx/u=Gy?7eC z  ~qwߣSI3eE1Jwm >Q钥R"7, V'p:kE*J-?"iպ (7`S;{v,(.3/eO\'JHO,E `n OHRkМ9oGAȿ9Ŏ O',,>ҾC'mU?f rrDo.]B˪7OܱEO]XZ)PM+ĦM|rmUPT9=o@]o KIpA"^Il (tIj(Y'˗-Zm[+^旘A]b+ )Efe ȸ$c%{').R>ES$W,lO„n/hHEթ8Œԥsg Bj{@l@QIoӖ- Bg$sgᏺ v=-CeƟDj{5kN]OM>dbZ (0sB9ޣtXR\8j?A\rH߻ s.|}\Ϙ1PTie4iC-D(([́uyw{ȶt VTr%=DzQOi8_Itq Z ]=׵Gwm^_Mq QJ^C\3XT*fRq|T<)tJ*L\#J pm7n<3Gܓ b`c-QJG壏j9>-7u2["bLZG E>kM]̳wHw f+Vr` HZ-w3*"j۟u\SBETR@\Lk?HY,mރ< w|I]Y<7/| I&ڽT1x_ǐP(.UE7QHDc_x^Qj{fE-ic*RPT-+p:\_W!Bm.+`y EU;(x]J% 31F]n8xP( /AZ=1BwP="Ɵ/`TTqcZsx/NwS.b9&cCkE(~saㆰʖ~`zOm- w ŦeI8]+ZJ*(H"<~Ė!_`A| | bM߿ww/GNϷQc'IC̸j!J)>j>p忊hEq+m[)-OXTs?m1j5nnKтXd;`bȯ/G?xTF?ȏd\? l۩eGxz0/\5,6DZN?O]puVs9k=QŘxOwR7( SCYq[ʟYs*,UTk'KkFRPm[ݰy 1,v=E >K?Dw?Wor URҎOT:f vH/֮Ob \׽ ѣdڴ{??ɦkYC U*#q@/.J*}_@bTMl͐=NU̡B^`{ac~QQebq=߲?l-F~׺g/u1ȑe̙:%Ο?W>z[op~3׸#$oY/2\S3־=?5}j=bFR@aSd{+b)E|KW_hc5 $(' /vY, ɑP|d2.ghDQ%iz*/SXQƨ&;m ˻Nqcǐaߒ )+#\[~G?1"QTnq-; 1c'%5Oɟ 6YJ %}/kΚar`"h=0?Ʒ@ڎ9ʽUx`S?ҫ 2|G0؍2p,Y1BB^8I ړOK$$&/W1Mk$N*i9:O-Xyq"W^8qajkœ?I&E}}ۿw"q_ ʷpg(D)Ipɓ6uo7gZ_@=Ѷyԩe.NX]*\Yu[{CbLߦM;ٲ|eK XqJ-{7q 6 o͌.|\d 4#ڡh]a:l8{r,¤d .h!$P|Xr_F5Xtt\d}.|ZՀ|rp'-PFT~dA0F+꼋[aae#ںi)Vr֮$:B!g=ܔ6|`y A.+((8Q9ֿ|WƿS8qJ" Ը] @ߒO`Un+R 1&UʟRj۫}TEcTO&Vt7sZ? Ƃ8Oe#]7ZϛEUj`Udxάʶ\Q,_( QZY&8VX.Çbq ?6cMW7nt+gL䵅ߠ>U w#OY_ e[o-1֙O8Ba nc|X4l߶5!;o>b $]:v{NJz ?B|aHmnq'W^TNC S&M\'d͚ҩH03+bߌjAO%֫wn߸{B-Mqgσ n,)8mJ?իYC0~1sd MD;$[~XI@CQsrZZ 3cgf?CGk6?`@?)Yʍpz-PFrT|_|M2+>^‰A%ח.٨ >WpFA3f 梼m"[D{Zih3nK2%RvXk7,@ÆH@6 ok%N,Ţ0n |i/|nMo(>=o¿~On ֺ%K*=;DU 3Vn5]SM(@^B*/WbTf0XTkX.㦡p/E 6X  CoPt ]߇+"6:b `Ċ c{XE{,X4n4[Aқ *{@َٝÂU`dgXXCm۷ o;rGGw=X` T<}n_k,#qg/'V[-lj ,.miW޷Wy^x=wűo/*LtRO=y)8x쨚0e){ġu/7 xsx+ɡ} |SwUh'c lV޷^?=8p=0ܢu H:QdR@罁C'j/nv);,N~e4_É*QEu|<Ԗ?wvrq1/8wf6m /lI7///|'G@zy4IkRL'>7;Ohl7Ta{a ]v# <>b#x+x D&x E8 eWa(&.^tNi,=ӎ*Җ iKX㤘A?yU\@]t}@ۿ{'jpо{W x.?jSۆc_PQqM?W5&naaJ7:wͻ6D. *&L7!f.fɰ&MsG@#Џu &Ho*,6Ǝv^j<Ƀ2?}9dο QR:K͏*eO zU0sC쨢c8kH(v).a>s,Q印"4'h7zTB[[GG|cxxbBk(sG)?GaEЀT)߭z!d9TwX)[-%NqXp8EΣ`RpVsR| Mq묃o.0C>(~衙|G~w~E_=wg#ҋC rKuナb߇9Qk6fİH <$kܝ#^RF!LiHCF]1CC@~A]Q݈>vG U*0SNJ#Fy3s?Bz*yByW5n+w(}&jC3YHUONTU~3KR@>͚-7/}8Dt:>N? "}k;H?H}J< ki@}Gq ģTOOpv~ 6]4`c [0ǶE6`[ą Lǫ-eDZڒ~+­m:uZ2́%;dGB-pZkM{w>^X Q,o1yɉ*[m{p%Y8Q5S/g9oW*<؁x쨊wpj3L(KUģ(n +,8s×C;,ǜpG_jzÎg%޽YnK$F|_  D3΁,>耽1!VGjlza5VbfywqbWʹX-}nr͛w<_>1ANM|^y)aRώ=:OOށ]Ʈ|o"rOȇyBګdb;ކb„Dy?uYbɯ<죅#7 c>Z\Vލ THXaUOk}1G ge[q@%YWV[nXݝV(jiWr7 ΕUwT ߌa;Hsz"oq_j0d';7[uUx0Q%n"}C>0QvTqN`C<.<\&8Ґ/@&q@W}[omjߕ-;ݜ;}->ĉWBUwh 0l?r*Ly>( "V}G aZ eWc{/ݨFb.۲\׫ }74\pyrZ󴤾}B=XA.;8yPg؍{?N*ythV-[x@W̃!mS|g82~4:v3[]/*pVEvTqLzQ#õ7E Cy@P3;8A.:v%EAWbN 믴peC8“oI-1"{qaoҘ6`1|} H̗.c!@o;;0n).]>K31Ʌh\ɵ.\tko8QEXzL!-\,}ZSamڒLΓ0#Rkҏ1 f<;?>%)*G2R)/3ཡ”Z[Ka!0x`# xA|")fi2N 8|'󎠸 oĝTQ; on}+ʷ'nɪYc0tx+./h;2aM65F7k]U)ځuĒ!I֭[~gh ([bV%U}y4G 5m]` e*?@8GFxE1Lo]-J'} .ǧu&qɧ|(ZFwn+#$P{g=3z ~-P~Gc_Mؒ;=;b/yI~:H^)s-}S| [wPâU&?; Cl {anj~,7Xo;.;0{]yG[qGJ<j͘=VW?pE~AKڹc5JbB^/7Vkwl*b'DxG$? Gw}yBZhC=G(_?#N73s1aY̗6Մh<ޘ8Cп޻/;8!玪ͱ D]9{sxmEtT!VmA~,★ 1Cu_zstpX~EmFBybJ(}6[oxLcx,QuK/#cey҈R㬠O "

    )qg4/m}}mQq"㩃>C>hXc'v ty-%BcKZ-N>C[ 9 ^'xױRdZ}s%'q|ODx8bM͖ݙ1saCGKƉ*&Dtѡrm7‘(0n1gĞ07|߇; p{y>7<=;Fa]߯q{XP! W[O?CpQn(\kV8F<Ɵ ث/ឿ?$ڸ/u#~!2B ?sk3aNT\oRWN c>.<è : eO'7B{a,Y|^71\a;l反ξcpw&܇tؘWq ב~;'zxߍ\˜oٿ;_k }i3.57]8'F0_30s/ื# [ly8#p_5G>&DՄoSQGozHkV܏c8rR?mڵ!2er}ᮿݍ3?+HB9S2!] ߭~uM7UHebg+\9x2LŇ+~Bԛly|BǎիHcx_ʽ g>eq`O8^gZ;ﲻ\N|WXvnEVL ּCDhw1@$[JwJ4HYĽ?XyD>c28B]4<+qG SF/].Urܱdž-A8!V~bhs'Mmծ][yUqG{~:߷~7a"z4<úݶ(<*I߯a b!NۇSO$uxEiw 2y՗ý#\zeQrve'_3 ?-8<14Σq_?Oٕw3a":U2 O=ϰ8&KȈϱn 6&}Ј,)~3p5ׅ[|Q+]~eOޅ O?,9 ݘ·=Xc 5t%{<܈2؇GB^a-Zqd&ۢ›De\{4t4ޭ0r=Qۿm*ux&uzLw#xT,DGUo/)͓L);pZΟ&u?Ǝn r:> xawnZ[9?J+,/aGʼn7GQw岫b% ur|E| _vٟN:.pr:OIoцaG,n9}5 q?M$C99QZ??Dφ/1:ګc}/ 2$0?gБJ׍6XT|HĽ__|E1G"%Is醓=+)b a_|y8xyi7Ռױ~sm;jAZH~dY~KWLyNM#-d0pԹI' ?/\Md#'!_Kw>d=C]x >"};a@+7e'9>?"qϽߪ̓A߮}L_cN@_OLTmQa)oNu {%l3NVNH,|ڴZ;vwª1D_aig` G)yrұ]۶Kvd Z3J_^ >%<}ӯIퟕ'# }*׿(&mK.F쟣xiQ<3&rXxWD>c)P~'F7XOOiB#q•XX<\$ N9HEmC̸(_|INS\$hkk{>}58j )O<5\yxwb7yjynɴ8)bp#$YZmmN;\[}52Vw3 ;.J91DyG%ѡÆD‚_7IxcpOiYߗ5(Kvù=Qd)R?ȉKF(kbIm>uh'k\ZP8k;? E̤1r&Ay쨚U_oDZ¿p߉/}`S^B~ȭ)c |Ǒ¢ Ԯ[ks_Ma諡 ^I'71 Fxr- 45wvTqM<CADcqDT芘ΤWp篼\h-B3&lX|aI'5h,59Ό?R3/NT <X52ɣ3ÏԛTwȳmӺ 4'sV۟103h l2z|+J|e_nW$|_O BdG\1IoՔ_%\2ŸiQ1I(څeD_nh|ɆeE]f?39'\m?#? 1cD QsN3?A ы@?s_M&m2b!}f~Cy|옏JbҔ³CЯtYqc(qaZϺ ֛??ygZZ};|?5q!Ǎ`itFwl}21ڊO?~hw?Ͷ?qUcw {;_l1JvkE2U3+??s]Sʿ[?q>ߏSN^zN+`4'h>C &=KE^4|lI#Hp?39G.0뮽>NT!Mj `pAݤ!X߱?SDT'`u%Z!CЩ^w┇Zk@.>U._};9l| _8%r4nXh ˩òV7~.0pDak;igL 5] jϓ{,|>a2pzĪ3N ~?? >)Nx_J~%SX&;n}.[Ȯޞ'n,{22\FS~x Lcy㯶b]rEXD.З~[:/ qsjv%n6>'?=F>24d?LלkJ&8N pp\8 ~)@pqcNܞw0KWk <)%?U:},}񸣡gځ&!~١-m 9@fzy䭰o^?_>?3bMDW^ mGbgϠp$ PSBkŮzLTDGtYʫqU>͒c@ϴ7})Ni:oXW g BحHf׸/cFMFne O _(VK̏EV.,. aoM崷|Ia !ΠCUbxq5e(ĩ GPbJ&ʕ˦'yoAL)*Bĉdp€d>zzpWR,O(-86LOU&OGdRÑc3E+ÍTI_Lm(_Yݽo.[n5Tᮦ.X:~H S dKgh߈(y OMc*E称?nV9CjN,|6V(&[,9'ZCmɝ/p8S]X lEQ!c -GgR[mN;wnm3Ƒտ"2Hd>1?ʌIyǿ~W_=*xHnݩ|Z7 vU}5rxcxR߈u7rquMqۭv)1gn.5M>,oxڟ*bQyGUI%v@ QQa2wTѮ0g[>gJn{aQ+Pc g)cR"HX@*g<gt[1T\xK}GZcͰ$.(? ƹ|J^N }5WP3MWR ᪫FoqLWO΃Nڴl-?j1+I?^{ݵ5qG`7|k/n7;>]tȿ۟2,:U;8ԵS;R*{nUE$Қt4)?vT#V R Áꫩ+fD'øMW>S6Jlvyə f|l>s[ AwēO [_H~J-B g~K B{`Zl^FIp}poMh{OxkX)_~UI֧Cpg31SG,\IX~aEۇy1$r?Y^}&[^!5tZ%|x+_n74J?.l߯;n9( Ό?.)~駥Us4vlgN첿&Πp/E ~6Us :4v=0,Bk; y:%sRϨ?7o 5[lir,h9C__+P;反GViH:&]㏷ᮢ^XxCws?P z #F;/rB5ƊmhdMhfpDz*>qGkiŀ 4+L1ɋ S?`ŮD̃acML&V/_ axKGq#[f~ipK.3%)8eU/DV99+ϖI%"0^ ?bİЪu-;Xa"lupEY4,_^0׿hBuP7{ֆn7 VUХ?K?bHb?x ,%;?;PLf5V˯ݿ8;-TPz>RNT VE:g8O &`xtly,7v8<&Ē1d~9fWPd""3.t Hd:߆>(>UXY>JK1e@[da!{aİayqE&,X]0fϬ??Fl #MO}/xC:'Ķ8U@GEU}f>cy,t[/,ԒO7տ1 )τ(꫆m_6}9-)=hhۦmXY39^KYq%?ؠ3$aq˿*%ZyN z9r6q'ou*/?Cb)a@xK/yӌD-)MYOIGO>lx׵+<˵ÂVa%EY84PS~o7~0qaC_1l5/> u\0U|縣z*˿mDUb"\',R)psRLGa<~K#O2 00c!ao}wO8S`y,Th Fń/gE??kBA&UHdČyl~ ]tеJaUV ͚5ŷGϜ D\V %][Y*R #HLTM\X%= Pc[CVdL(.Aa*@Zc0x0vd )"+ѴVT)ɰ1ey pwOƅoö`x>_ Q~m!Fypk6tΙBtIbGUjQ3eoÍ|V͆6,x&gpVgPO`&IϢ0[8fBU|b3 %y84SJ%]s3pї[ȬqT3 z9}?W3yp۟^_?rͣXnfx|`d/5D*I }Coz"߼Oz|??${)Y>8t|ګdo/U:k,p *1MjUC#=>dFd`7GjSR &'vj#&Ɵ0ApI?J7Hd/  $%7x#lnЅH3ҍ/z|})7d=<Ǚ|e>:x(]?#P?x@|б'ŀuQg:0P kq2AnNO ) fb0S%GB;-߮eHU4č 9JD<y 5Ψ`c\~#.˝*.!F̵xG;}_ ^\_?ĢrK,Dvt'Z@!ȇbl|_uo??ˠ#ѬԄ.+C Im+B4NDcL'8 Dضr(uqCl ;$Q]~0Œ[aG e\LK)+ -0G3/UV{sW4?۟hxmHb0'6(kpǮoD (MLa2}~EvTI͗:&}#PB=H(IpbH*>qF+,"\ H O%G|||hNU  QUt_-ѠbG(SC[U-#I& $rXj#A)Kuj ud5 G JqN_X-<bC2%]XmU\@$b+D*P=u+_捷?GܹHG/YnQ۟Ũ߹}p;޽/ yKL qXq׏4l#%Ea U\Vi`p2W:DdS <48hS M4" 1V)t !^ Z Q/ԂsڮD554Io_?D,/?UbjEO/k]z_?i3ِ_4yxs2|tYhhojĎfX 58/:H"v5ɨB\aO/OIaSd=S3ʘ~q xSr92E-|H$8p-YwuJ/?ԡ۟n{_2?P ̘Èdkѥ;>_!''74tt.5=Q#;JhٓzS*;<4OIOe"HF_%Jp 3D0<>1<`w㤯??ő!fZ٦Ha?r5%֊\Wf'#)1ҷA?x -jmc-,'yRp%dAFIG)JzJ_H02g{b$dUxl0irBGV)tqA/q:8}?dADFJLC8)_2x ?hy]nGi^M Xm SC:u,~ ~q#W?pO?t3n7飯>P/>> f@pwP$4 4Ё&s$ 8Ša̅i8W6e8KDTy9(R\o`{z2Eo>IDATZ\Ҋt?>Jv3Оԙ cw!gGe?.+T'RS2zvT[;Lp13VANye_x3 pF@6NFv`~ Tx3l3Bbq2p"P͂b,2c] BZ*YPl3Bbq2XWH@7 pF@6NFv+\ ifAA.`_!-,(6!1v8p+E›Y8#d N'#.Tx g idd?寐 odጐ;mV"P͂b,2c]9E˕Q!tDcyt*k1Q5+jBi͌3ە)}6QʹM`hTūԍ8eMeŜ:Y0P WӨQ>Mղd ‰qƤe_ %+/뗦"S\yh f* ?!`ucDٗx폷? X!:ߊP$ʌ1)o`\_84Nݘaoֿ +VtZ.3z:u pLSd gVSƳAIX𤋩xB (b!GY *TNcJ\*1翈˟??V̎ Xf2?РKOI8_nJnIQo%&Ip_ou.۟n U5VTaUmT,njFUe@b*CB HRwKR2"n5'Tjks d.'`G$+T b \NꏮI(V +$GW]PVP- -p9I?7'X1Z@[r] VtoN@bXA,$9ߜbŰjYlIrt5Xѵ9 Ŋajks d.'`G$+T b \NꏮI(V +$GW]PVP- -p9I?7'X1Z@[r] VtoN@bXA,$9ߜbŰjYlIrt5Xѵ9 Ŋajks d.'`G$+T b \NꏮI(V +$GW]PVP- -p9I?7'X1Z@[r] VtoN@bXA,$9ߜbŰjYlIrt5Xѵ9 Ŋajks d.'`G$+T b \NꏮI(V +$GW]PVP- -p9I?7'X1Z@[r] VtoN@bXA,$9ߜbŰjYlIrt5Xѵ9 Ŋajks d.'`G$+T b \NꏮI(V +$GW]PVP- -p9I?7'X1Z@[r] VtoN@bXA,$9ߜbŰjYlIrt5Xѵ9 Ŋajks d.'`G$+T b \NꏮI(V +$GW]PVP- -p9I?7'X1Z@[r] VtoN@bXA,$9ߜbŰjYlIrt5Xѵ9 Ŋajks d.'`G$+T b \NꏮI(V +$GW]\%;jBNrҟ*Oe.掬gNqBNRW9T1g8m~q|p+D!uCcl|3&@/BNRW9T1g8m~q|p+D!uCcl|3&@/BNRW9T1g8m~q|p+D!uCcl|3&@/BNRW9T1g8m~q|p+D!uCcl|3&@/BNRW9T1g8m~ 8Q.&"MC @&lbduᔶpeDN&XL~p2DI2a 1~ZܜI ӯ-;u3~ᩆ䖝:oKÉ*_k`rˎ?er?׿HmU#ZI[ ӯ-;=Z?\jȀ*Vk`rˎ!yO+ _@fZAܲQzԆ\52$:ܲG٣u?DOC=ZO ]M0O ;O6A]X1Ԋ6 RR@Ԋ6N? rH]pW@Ԋ6RJ*3tUBԵq qqJLh%ZC( D (1M?^?pFSˣiak1u^bjJ8Ԋ6\WR/$1M?-ԋ3;_QVLU|+3c(\{GU=6w5lqU3sC2r;]쒳zx/,kU*#j**U%RgC2r|Q=5*C _tJJFܪ3j!?nF^ ˚zJ! q FSCQvDT SG\I vTż++.hyH1/з 5UQ;]A@ɨz׿hz"[#ʕ5 $& & nnE1`48rOՎ]cnG[ovE1F؟ۓ@EgƉ*Qu(KwTϘORפ* z@K]K9 hj^\Ag@0PRR2>􆁚&rР7 Լ5πa楮ɥd|4 5/uM. 3Aoykr) z@K]K9 hj^\Ag@0PRR2>􆁚&rР7 Լ5πa楮ɥd|4 5/uM. 3Aoykr) z@K]K9 hj^\Ag@0PRR2>􆁚&rР7 Լ5πa楮ɥd|4 5/uM. 3Aoykr) z@K]K9 hj^\Ag@0PRR2>􆁚&rР7 Լ5πa楮ɥd|4 5/uM. 3Aoykr) z@K]K9 hj^\Ag@0PRR2>􆁚&rР7 Լ5πa楮ɥd|4 5/uM. 3Aoykr) z@K]K9 hj^\Ag@0PRR2>􆁚&rР7 Լ5πa楮ɥd|4 5/uM. 3Aoykr) z@K]K9 hj^\Ag@0PRR2>9o8Ug̊51cLOSJoSGLTa ˊmEZ2ߣH ,f#Hb$Df0N?NEUN} $Df0.. SŒZ\GH`\\\ E(éb:$FMd3!N0~fח@Md3Wi)*,R\A#&2|/BUɝH``TQ[ʘ)n"3??F5bz"Df0Eʁ:SG8 |1`MwNuDUO;s!; IENDB`starlette-0.50.0/docs/img/starlette.svg000066400000000000000000000407421510142272400200440ustar00rootroot00000000000000starlette-0.50.0/docs/img/starlette_dark.svg000066400000000000000000000410051510142272400210360ustar00rootroot00000000000000starlette-0.50.0/docs/index.md000066400000000000000000000127641510142272400161740ustar00rootroot00000000000000

    starlette starlette

    ✨ The little ASGI framework that shines. ✨

    --- **Documentation**: https://starlette.dev **Source Code**: https://github.com/Kludex/starlette --- # Introduction Starlette is a lightweight [ASGI][asgi] framework/toolkit, which is ideal for building async web services in Python. It is production-ready, and gives you the following: * A lightweight, low-complexity HTTP web framework. * WebSocket support. * In-process background tasks. * Startup and shutdown events. * Test client built on `httpx`. * CORS, GZip, Static Files, Streaming responses. * Session and Cookie support. * 100% test coverage. * 100% type annotated codebase. * Few hard dependencies. * Compatible with `asyncio` and `trio` backends. * Great overall performance [against independent benchmarks][techempower]. ## Sponsorship Starlette is an open-source project that relies on community support. You can help us maintain and improve the framework by [becoming a sponsor](sponsorship.md). ## Installation ```shell pip install starlette ``` You'll also want to install an ASGI server, such as [uvicorn](https://www.uvicorn.org/), [daphne](https://github.com/django/daphne/), or [hypercorn](https://hypercorn.readthedocs.io/en/latest/). ```shell pip install uvicorn ``` ## Example ```python title="main.py" from starlette.applications import Starlette from starlette.responses import JSONResponse from starlette.routing import Route async def homepage(request): return JSONResponse({'hello': 'world'}) app = Starlette(debug=True, routes=[ Route('/', homepage), ]) ``` Then run the application... ```shell uvicorn main:app ``` ## Dependencies Starlette only requires `anyio`, and the following dependencies are optional: * [`httpx`][httpx] - Required if you want to use the `TestClient`. * [`jinja2`][jinja2] - Required if you want to use `Jinja2Templates`. * [`python-multipart`][python-multipart] - Required if you want to support form parsing, with `request.form()`. * [`itsdangerous`][itsdangerous] - Required for `SessionMiddleware` support. * [`pyyaml`][pyyaml] - Required for `SchemaGenerator` support. You can install all of these with `pip install starlette[full]`. ## Framework or Toolkit Starlette is designed to be used either as a complete framework, or as an ASGI toolkit. You can use any of its components independently. ```python title="main.py" from starlette.responses import PlainTextResponse async def app(scope, receive, send): assert scope['type'] == 'http' response = PlainTextResponse('Hello, world!') await response(scope, receive, send) ``` Run the `app` application in `main.py`: ```shell $ uvicorn main:app INFO: Started server process [11509] INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) ``` Run uvicorn with `--reload` to enable auto-reloading on code changes. ## Modularity The modularity that Starlette is designed on promotes building re-usable components that can be shared between any ASGI framework. This should enable an ecosystem of shared middleware and mountable applications. The clean API separation also means it's easier to understand each component in isolation. ---

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

    — ⭐️ —

    [asgi]: https://asgi.readthedocs.io/en/latest/ [httpx]: https://www.python-httpx.org/ [jinja2]: https://jinja.palletsprojects.com/ [python-multipart]: https://multipart.fastapiexpert.com/ [itsdangerous]: https://itsdangerous.palletsprojects.com/ [sqlalchemy]: https://www.sqlalchemy.org [pyyaml]: https://pyyaml.org/wiki/PyYAMLDocumentation [techempower]: https://www.techempower.com/benchmarks/#hw=ph&test=fortune&l=zijzen-sf starlette-0.50.0/docs/lifespan.md000066400000000000000000000044761510142272400166670ustar00rootroot00000000000000 Starlette applications can register a lifespan handler for dealing with code that needs to run before the application starts up, or when the application is shutting down. ```python import contextlib from starlette.applications import Starlette @contextlib.asynccontextmanager async def lifespan(app): async with some_async_resource(): print("Run at startup!") yield print("Run on shutdown!") routes = [ ... ] app = Starlette(routes=routes, lifespan=lifespan) ``` Starlette will not start serving any incoming requests until the lifespan has been run. The lifespan teardown will run once all connections have been closed, and any in-process background tasks have completed. Consider using [`anyio.create_task_group()`](https://anyio.readthedocs.io/en/stable/tasks.html) for managing asynchronous tasks. ## Lifespan State The lifespan has the concept of `state`, which is a dictionary that can be used to share the objects between the lifespan, and the requests. ```python import contextlib from typing import AsyncIterator, TypedDict import httpx from starlette.applications import Starlette from starlette.requests import Request from starlette.responses import PlainTextResponse from starlette.routing import Route class State(TypedDict): http_client: httpx.AsyncClient @contextlib.asynccontextmanager async def lifespan(app: Starlette) -> AsyncIterator[State]: async with httpx.AsyncClient() as client: yield {"http_client": client} async def homepage(request: Request) -> PlainTextResponse: client = request.state.http_client response = await client.get("https://www.example.com") return PlainTextResponse(response.text) app = Starlette( lifespan=lifespan, routes=[Route("/", homepage)] ) ``` The `state` received on the requests is a **shallow** copy of the state received on the lifespan handler. ## Running lifespan in tests You should use `TestClient` as a context manager, to ensure that the lifespan is called. ```python from example import app from starlette.testclient import TestClient def test_homepage(): with TestClient(app) as client: # Application's lifespan is called on entering the block. response = client.get("/") assert response.status_code == 200 # And the lifespan's teardown is run when exiting the block. ``` starlette-0.50.0/docs/middleware.md000066400000000000000000001045511510142272400171760ustar00rootroot00000000000000 Starlette includes several middleware classes for adding behavior that is applied across your entire application. These are all implemented as standard ASGI middleware classes, and can be applied either to Starlette or to any other ASGI application. ## Using middleware The Starlette application class allows you to include the ASGI middleware in a way that ensures that it remains wrapped by the exception handler. ```python from starlette.applications import Starlette from starlette.middleware import Middleware from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware from starlette.middleware.trustedhost import TrustedHostMiddleware routes = ... # Ensure that all requests include an 'example.com' or # '*.example.com' host header, and strictly enforce https-only access. middleware = [ Middleware( TrustedHostMiddleware, allowed_hosts=['example.com', '*.example.com'], ), Middleware(HTTPSRedirectMiddleware) ] app = Starlette(routes=routes, middleware=middleware) ``` Every Starlette application automatically includes two pieces of middleware by default: * `ServerErrorMiddleware` - Ensures that application exceptions may return a custom 500 page, or display an application traceback in DEBUG mode. This is *always* the outermost middleware layer. * `ExceptionMiddleware` - Adds exception handlers, so that particular types of expected exception cases can be associated with handler functions. For example raising `HTTPException(status_code=404)` within an endpoint will end up rendering a custom 404 page. Middleware is evaluated from top-to-bottom, so the flow of execution in our example application would look like this: * Middleware * `ServerErrorMiddleware` * `TrustedHostMiddleware` * `HTTPSRedirectMiddleware` * `ExceptionMiddleware` * Routing * Endpoint The following middleware implementations are available in the Starlette package: ## CORSMiddleware Adds appropriate [CORS headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) to outgoing responses in order to allow cross-origin requests from browsers. The default parameters used by the CORSMiddleware implementation are restrictive by default, so you'll need to explicitly enable particular origins, methods, or headers, in order for browsers to be permitted to use them in a Cross-Domain context. ```python from starlette.applications import Starlette from starlette.middleware import Middleware from starlette.middleware.cors import CORSMiddleware routes = ... middleware = [ Middleware(CORSMiddleware, allow_origins=['*']) ] app = Starlette(routes=routes, middleware=middleware) ``` The following arguments are supported: * `allow_origins` - A list of origins that should be permitted to make cross-origin requests. eg. `['https://example.org', 'https://www.example.org']`. You can use `['*']` to allow any origin. * `allow_origin_regex` - A regex string to match against origins that should be permitted to make cross-origin requests. eg. `'https://.*\.example\.org'`. * `allow_methods` - A list of HTTP methods that should be allowed for cross-origin requests. Defaults to `['GET']`. You can use `['*']` to allow all standard methods. * `allow_headers` - A list of HTTP request headers that should be supported for cross-origin requests. Defaults to `[]`. You can use `['*']` to allow all headers. The `Accept`, `Accept-Language`, `Content-Language` and `Content-Type` headers are always allowed for CORS requests. * `allow_credentials` - Indicate that cookies should be supported for cross-origin requests. Defaults to `False`. Also, `allow_origins`, `allow_methods` and `allow_headers` cannot be set to `['*']` for credentials to be allowed, all of them must be explicitly specified. * `expose_headers` - Indicate any response headers that should be made accessible to the browser. Defaults to `[]`. * `max_age` - Sets a maximum time in seconds for browsers to cache CORS responses. Defaults to `600`. The middleware responds to two particular types of HTTP request... #### CORS preflight requests These are any `OPTIONS` request with `Origin` and `Access-Control-Request-Method` headers. In this case the middleware will intercept the incoming request and respond with appropriate CORS headers, and either a 200 or 400 response for informational purposes. #### Simple requests Any request with an `Origin` header. In this case the middleware will pass the request through as normal, but will include appropriate CORS headers on the response. ### CORSMiddleware Global Enforcement When using CORSMiddleware with your Starlette application, it's important to ensure that CORS headers are applied even to error responses generated by unhandled exceptions. The recommended solution is to wrap the entire Starlette application with CORSMiddleware. This approach guarantees that even if an exception is caught by ServerErrorMiddleware (or other outer error-handling middleware), the response will still include the proper `Access-Control-Allow-Origin` header. For example, instead of adding CORSMiddleware as an inner `middleware` via the Starlette middleware parameter, you can wrap your application as follows: ```python from starlette.applications import Starlette from starlette.middleware.cors import CORSMiddleware import uvicorn app = Starlette() app = CORSMiddleware(app=app, allow_origins=["*"]) # ... your routes and middleware configuration ... if __name__ == '__main__': uvicorn.run( app, host='0.0.0.0', port=8000 ) ``` ## SessionMiddleware Adds signed cookie-based HTTP sessions. Session information is readable but not modifiable. Access or modify the session data using the `request.session` dictionary interface. The following arguments are supported: * `secret_key` - Should be a random string. * `session_cookie` - Defaults to "session". * `max_age` - Session expiry time in seconds. Defaults to 2 weeks. If set to `None` then the cookie will last as long as the browser session. * `same_site` - SameSite flag prevents the browser from sending session cookie along with cross-site requests. Defaults to `'lax'`. * `path` - The path set for the session cookie. Defaults to `'/'`. * `https_only` - Indicate that Secure flag should be set (can be used with HTTPS only). Defaults to `False`. * `domain` - Domain of the cookie used to share cookie between subdomains or cross-domains. The browser defaults the domain to the same host that set the cookie, excluding subdomains ([reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#domain_attribute)). ```python from starlette.applications import Starlette from starlette.middleware import Middleware from starlette.middleware.sessions import SessionMiddleware routes = ... middleware = [ Middleware(SessionMiddleware, secret_key=..., https_only=True) ] app = Starlette(routes=routes, middleware=middleware) ``` ## HTTPSRedirectMiddleware Enforces that all incoming requests must either be `https` or `wss`. Any incoming requests to `http` or `ws` will be redirected to the secure scheme instead. ```python from starlette.applications import Starlette from starlette.middleware import Middleware from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware routes = ... middleware = [ Middleware(HTTPSRedirectMiddleware) ] app = Starlette(routes=routes, middleware=middleware) ``` There are no configuration options for this middleware class. ## TrustedHostMiddleware Enforces that all incoming requests have a correctly set `Host` header, in order to guard against HTTP Host Header attacks. ```python from starlette.applications import Starlette from starlette.middleware import Middleware from starlette.middleware.trustedhost import TrustedHostMiddleware routes = ... middleware = [ Middleware(TrustedHostMiddleware, allowed_hosts=['example.com', '*.example.com']) ] app = Starlette(routes=routes, middleware=middleware) ``` The following arguments are supported: * `allowed_hosts` - A list of domain names that should be allowed as hostnames. Wildcard domains such as `*.example.com` are supported for matching subdomains. To allow any hostname either use `allowed_hosts=["*"]` or omit the middleware. * `www_redirect` - If set to True, requests to non-www versions of the allowed hosts will be redirected to their www counterparts. Defaults to `True`. If an incoming request does not validate correctly then a 400 response will be sent. ## GZipMiddleware Handles GZip responses for any request that includes `"gzip"` in the `Accept-Encoding` header. The middleware will handle both standard and streaming responses. ??? info "Buffer on streaming responses" On streaming responses, the middleware will buffer the response before compressing it. The idea is that we don't want to compress every small chunk of data, as it would be inefficient. Instead, we buffer the response until it reaches a certain size, and then compress it. This may cause a delay in the response, as the middleware waits for the buffer to fill up before compressing it. ```python from starlette.applications import Starlette from starlette.middleware import Middleware from starlette.middleware.gzip import GZipMiddleware routes = ... middleware = [ Middleware(GZipMiddleware, minimum_size=1000, compresslevel=9) ] app = Starlette(routes=routes, middleware=middleware) ``` The following arguments are supported: * `minimum_size` - Do not GZip responses that are smaller than this minimum size in bytes. Defaults to `500`. * `compresslevel` - Used during GZip compression. It is an integer ranging from 1 to 9. Defaults to `9`. Lower value results in faster compression but larger file sizes, while higher value results in slower compression but smaller file sizes. The middleware won't GZip responses that already have either a `Content-Encoding` set, to prevent them from being encoded twice, or a `Content-Type` set to `text/event-stream`, to avoid compressing server-sent events. ## BaseHTTPMiddleware An abstract class that allows you to write ASGI middleware against a request/response interface. ### Usage To implement a middleware class using `BaseHTTPMiddleware`, you must override the `async def dispatch(request, call_next)` method. ```python from starlette.applications import Starlette from starlette.middleware import Middleware from starlette.middleware.base import BaseHTTPMiddleware class CustomHeaderMiddleware(BaseHTTPMiddleware): async def dispatch(self, request, call_next): response = await call_next(request) response.headers['Custom'] = 'Example' return response routes = ... middleware = [ Middleware(CustomHeaderMiddleware) ] app = Starlette(routes=routes, middleware=middleware) ``` If you want to provide configuration options to the middleware class you should override the `__init__` method, ensuring that the first argument is `app`, and any remaining arguments are optional keyword arguments. Make sure to set the `app` attribute on the instance if you do this. ```python class CustomHeaderMiddleware(BaseHTTPMiddleware): def __init__(self, app, header_value='Example'): super().__init__(app) self.header_value = header_value async def dispatch(self, request, call_next): response = await call_next(request) response.headers['Custom'] = self.header_value return response middleware = [ Middleware(CustomHeaderMiddleware, header_value='Customized') ] app = Starlette(routes=routes, middleware=middleware) ``` Middleware classes should not modify their state outside of the `__init__` method. Instead you should keep any state local to the `dispatch` method, or pass it around explicitly, rather than mutating the middleware instance. ### Limitations Currently, the `BaseHTTPMiddleware` has some known limitations: - Using `BaseHTTPMiddleware` will prevent changes to [`contextvars.ContextVar`](https://docs.python.org/3/library/contextvars.html#contextvars.ContextVar)s from propagating upwards. That is, if you set a value for a `ContextVar` in your endpoint and try to read it from a middleware you will find that the value is not the same value you set in your endpoint (see [this test](https://github.com/Kludex/starlette/blob/621abc747a6604825190b93467918a0ec6456a24/tests/middleware/test_base.py#L192-L223) for an example of this behavior). Importantly, this also means that if a `BaseHTTPMiddleware` is positioned earlier in the middleware stack, it will disrupt `contextvars` propagation for any subsequent Pure ASGI Middleware that relies on them. To overcome these limitations, use [pure ASGI middleware](#pure-asgi-middleware), as shown below. ## Pure ASGI Middleware The [ASGI spec](https://asgi.readthedocs.io/en/latest/) makes it possible to implement ASGI middleware using the ASGI interface directly, as a chain of ASGI applications that call into the next one. In fact, this is how middleware classes shipped with Starlette are implemented. This lower-level approach provides greater control over behavior and enhanced interoperability across frameworks and servers. It also overcomes the [limitations of `BaseHTTPMiddleware`](#limitations). ### Writing pure ASGI middleware The most common way to create an ASGI middleware is with a class. ```python class ASGIMiddleware: def __init__(self, app): self.app = app async def __call__(self, scope, receive, send): await self.app(scope, receive, send) ``` The middleware above is the most basic ASGI middleware. It receives a parent ASGI application as an argument for its constructor, and implements an `async __call__` method which calls into that parent application. Some implementations such as [`asgi-cors`](https://github.com/simonw/asgi-cors/blob/10ef64bfcc6cd8d16f3014077f20a0fb8544ec39/asgi_cors.py) use an alternative style, using functions: ```python import functools def asgi_middleware(): def asgi_decorator(app): @functools.wraps(app) async def wrapped_app(scope, receive, send): await app(scope, receive, send) return wrapped_app return asgi_decorator ``` In any case, ASGI middleware must be callables that accept three arguments: `scope`, `receive`, and `send`. * `scope` is a dict holding information about the connection, where `scope["type"]` may be: * [`"http"`](https://asgi.readthedocs.io/en/latest/specs/www.html#http-connection-scope): for HTTP requests. * [`"websocket"`](https://asgi.readthedocs.io/en/latest/specs/www.html#websocket-connection-scope): for WebSocket connections. * [`"lifespan"`](https://asgi.readthedocs.io/en/latest/specs/lifespan.html#scope): for ASGI lifespan messages. * `receive` and `send` can be used to exchange ASGI event messages with the ASGI server — more on this below. The type and contents of these messages depend on the scope type. Learn more in the [ASGI specification](https://asgi.readthedocs.io/en/latest/specs/index.html). ### Using pure ASGI middleware Pure ASGI middleware can be used like any other middleware: ```python from starlette.applications import Starlette from starlette.middleware import Middleware from .middleware import ASGIMiddleware routes = ... middleware = [ Middleware(ASGIMiddleware), ] app = Starlette(..., middleware=middleware) ``` See also [Using middleware](#using-middleware). ### Type annotations There are two ways of annotating a middleware: using Starlette itself or [`asgiref`](https://github.com/django/asgiref). * Using Starlette: for most common use cases. ```python from starlette.types import ASGIApp, Message, Scope, Receive, Send class ASGIMiddleware: def __init__(self, app: ASGIApp) -> None: self.app = app async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: if scope["type"] != "http": return await self.app(scope, receive, send) async def send_wrapper(message: Message) -> None: # ... Do something await send(message) await self.app(scope, receive, send_wrapper) ``` * Using [`asgiref`](https://github.com/django/asgiref): for more rigorous type hinting. ```python from asgiref.typing import ASGI3Application, ASGIReceiveCallable, ASGISendCallable, Scope from asgiref.typing import ASGIReceiveEvent, ASGISendEvent class ASGIMiddleware: def __init__(self, app: ASGI3Application) -> None: self.app = app async def __call__(self, scope: Scope, receive: ASGIReceiveCallable, send: ASGISendCallable) -> None: if scope["type"] != "http": await self.app(scope, receive, send) return async def send_wrapper(message: ASGISendEvent) -> None: # ... Do something await send(message) return await self.app(scope, receive, send_wrapper) ``` ### Common patterns #### Processing certain requests only ASGI middleware can apply specific behavior according to the contents of `scope`. For example, to only process HTTP requests, write this... ```python class ASGIMiddleware: def __init__(self, app): self.app = app async def __call__(self, scope, receive, send): if scope["type"] != "http": await self.app(scope, receive, send) return ... # Do something here! await self.app(scope, receive, send) ``` Likewise, WebSocket-only middleware would guard on `scope["type"] != "websocket"`. The middleware may also act differently based on the request method, URL, headers, etc. #### Reusing Starlette components Starlette provides several data structures that accept the ASGI `scope`, `receive` and/or `send` arguments, allowing you to work at a higher level of abstraction. Such data structures include [`Request`](requests.md#request), [`Headers`](requests.md#headers), [`QueryParams`](requests.md#query-parameters), [`URL`](requests.md#url), etc. For example, you can instantiate a `Request` to more easily inspect an HTTP request: ```python from starlette.requests import Request class ASGIMiddleware: def __init__(self, app): self.app = app async def __call__(self, scope, receive, send): if scope["type"] == "http": request = Request(scope) ... # Use `request.method`, `request.url`, `request.headers`, etc. await self.app(scope, receive, send) ``` You can also reuse [responses](responses.md), which are ASGI applications as well. #### Sending eager responses Inspecting the connection `scope` allows you to conditionally call into a different ASGI app. One use case might be sending a response without calling into the app. As an example, this middleware uses a dictionary to perform permanent redirects based on the requested path. This could be used to implement ongoing support of legacy URLs in case you need to refactor route URL patterns. ```python from starlette.datastructures import URL from starlette.responses import RedirectResponse class RedirectsMiddleware: def __init__(self, app, path_mapping: dict): self.app = app self.path_mapping = path_mapping async def __call__(self, scope, receive, send): if scope["type"] != "http": await self.app(scope, receive, send) return url = URL(scope=scope) if url.path in self.path_mapping: url = url.replace(path=self.path_mapping[url.path]) response = RedirectResponse(url, status_code=301) await response(scope, receive, send) return await self.app(scope, receive, send) ``` Example usage would look like this: ```python from starlette.applications import Starlette from starlette.middleware import Middleware routes = ... redirections = { "/v1/resource/": "/v2/resource/", # ... } middleware = [ Middleware(RedirectsMiddleware, path_mapping=redirections), ] app = Starlette(routes=routes, middleware=middleware) ``` #### Inspecting or modifying the request Request information can be accessed or changed by manipulating the `scope`. For a full example of this pattern, see Uvicorn's [`ProxyHeadersMiddleware`](https://github.com/encode/uvicorn/blob/fd4386fefb8fe8a4568831a7d8b2930d5fb61455/uvicorn/middleware/proxy_headers.py) which inspects and tweaks the `scope` when serving behind a frontend proxy. Besides, wrapping the `receive` ASGI callable allows you to access or modify the HTTP request body by manipulating [`http.request`](https://asgi.readthedocs.io/en/latest/specs/www.html#request-receive-event) ASGI event messages. As an example, this middleware computes and logs the size of the incoming request body... ```python class LoggedRequestBodySizeMiddleware: def __init__(self, app): self.app = app async def __call__(self, scope, receive, send): if scope["type"] != "http": await self.app(scope, receive, send) return body_size = 0 async def receive_logging_request_body_size(): nonlocal body_size message = await receive() assert message["type"] == "http.request" body_size += len(message.get("body", b"")) if not message.get("more_body", False): print(f"Size of request body was: {body_size} bytes") return message await self.app(scope, receive_logging_request_body_size, send) ``` Likewise, WebSocket middleware may manipulate [`websocket.receive`](https://asgi.readthedocs.io/en/latest/specs/www.html#receive-receive-event) ASGI event messages to inspect or alter incoming WebSocket data. For an example that changes the HTTP request body, see [`msgpack-asgi`](https://github.com/florimondmanca/msgpack-asgi). #### Inspecting or modifying the response Wrapping the `send` ASGI callable allows you to inspect or modify the HTTP response sent by the underlying application. To do so, react to [`http.response.start`](https://asgi.readthedocs.io/en/latest/specs/www.html#response-start-send-event) or [`http.response.body`](https://asgi.readthedocs.io/en/latest/specs/www.html#response-body-send-event) ASGI event messages. As an example, this middleware adds some fixed extra response headers: ```python from starlette.datastructures import MutableHeaders class ExtraResponseHeadersMiddleware: def __init__(self, app, headers): self.app = app self.headers = headers async def __call__(self, scope, receive, send): if scope["type"] != "http": return await self.app(scope, receive, send) async def send_with_extra_headers(message): if message["type"] == "http.response.start": headers = MutableHeaders(scope=message) for key, value in self.headers: headers.append(key, value) await send(message) await self.app(scope, receive, send_with_extra_headers) ``` See also [`asgi-logger`](https://github.com/Kludex/asgi-logger/blob/main/asgi_logger/middleware.py) for an example that inspects the HTTP response and logs a configurable HTTP access log line. Likewise, WebSocket middleware may manipulate [`websocket.send`](https://asgi.readthedocs.io/en/latest/specs/www.html#send-send-event) ASGI event messages to inspect or alter outgoing WebSocket data. Note that if you change the response body, you will need to update the response `Content-Length` header to match the new response body length. See [`brotli-asgi`](https://github.com/fullonic/brotli-asgi) for a complete example. #### Passing information to endpoints If you need to share information with the underlying app or endpoints, you may store it into the `scope` dictionary. Note that this is a convention -- for example, Starlette uses this to share routing information with endpoints -- but it is not part of the ASGI specification. If you do so, be sure to avoid conflicts by using keys that have low chances of being used by other middleware or applications. For example, when including the middleware below, endpoints would be able to access `request.scope["asgi_transaction_id"]`. ```python import uuid class TransactionIDMiddleware: def __init__(self, app): self.app = app async def __call__(self, scope, receive, send): scope["asgi_transaction_id"] = uuid.uuid4() await self.app(scope, receive, send) ``` #### Cleanup and error handling You can wrap the application in a `try/except/finally` block or a context manager to perform cleanup operations or do error handling. For example, the following middleware might collect metrics and process application exceptions... ```python import time class MonitoringMiddleware: def __init__(self, app): self.app = app async def __call__(self, scope, receive, send): start = time.time() try: await self.app(scope, receive, send) except Exception as exc: ... # Process the exception raise finally: end = time.time() elapsed = end - start ... # Submit `elapsed` as a metric to a monitoring backend ``` See also [`timing-asgi`](https://github.com/steinnes/timing-asgi) for a full example of this pattern. ### Gotchas #### ASGI middleware should be stateless Because ASGI is designed to handle concurrent requests, any connection-specific state should be scoped to the `__call__` implementation. Not doing so would typically lead to conflicting variable reads/writes across requests, and most likely bugs. As an example, this would conditionally replace the response body, if an `X-Mock` header is present in the response... === "✅ Do" ```python from starlette.datastructures import Headers class MockResponseBodyMiddleware: def __init__(self, app, content): self.app = app self.content = content async def __call__(self, scope, receive, send): if scope["type"] != "http": await self.app(scope, receive, send) return # A flag that we will turn `True` if the HTTP response # has the 'X-Mock' header. # ✅: Scoped to this function. should_mock = False async def maybe_send_with_mock_content(message): nonlocal should_mock if message["type"] == "http.response.start": headers = Headers(raw=message["headers"]) should_mock = headers.get("X-Mock") == "1" await send(message) elif message["type"] == "http.response.body": if should_mock: message = {"type": "http.response.body", "body": self.content} await send(message) await self.app(scope, receive, maybe_send_with_mock_content) ``` === "❌ Don't" ```python hl_lines="7-8" from starlette.datastructures import Headers class MockResponseBodyMiddleware: def __init__(self, app, content): self.app = app self.content = content # ❌: This variable would be read and written across requests! self.should_mock = False async def __call__(self, scope, receive, send): if scope["type"] != "http": await self.app(scope, receive, send) return async def maybe_send_with_mock_content(message): if message["type"] == "http.response.start": headers = Headers(raw=message["headers"]) self.should_mock = headers.get("X-Mock") == "1" await send(message) elif message["type"] == "http.response.body": if self.should_mock: message = {"type": "http.response.body", "body": self.content} await send(message) await self.app(scope, receive, maybe_send_with_mock_content) ``` See also [`GZipMiddleware`](https://github.com/Kludex/starlette/blob/9ef1b91c9c043197da6c3f38aa153fd874b95527/starlette/middleware/gzip.py) for a full example implementation that navigates this potential gotcha. ### Further reading This documentation should be enough to have a good basis on how to create an ASGI middleware. Nonetheless, there are great articles about the subject: - [Introduction to ASGI: Emergence of an Async Python Web Ecosystem](https://florimond.dev/en/posts/2019/08/introduction-to-asgi-async-python-web/) - [How to write ASGI middleware](https://pgjones.dev/blog/how-to-write-asgi-middleware-2021/) ## Using middleware in other frameworks To wrap ASGI middleware around other ASGI applications, you should use the more general pattern of wrapping the application instance: ```python app = TrustedHostMiddleware(app, allowed_hosts=['example.com']) ``` You can do this with a Starlette application instance too, but it is preferable to use the `middleware=` style, as it will: * Ensure that everything remains wrapped in a single outermost `ServerErrorMiddleware`. * Preserves the top-level `app` instance. ## Applying middleware to groups of routes Middleware can also be added to `Mount` instances, which allows you to apply middleware to a group of routes or a sub-application: ```python from starlette.applications import Starlette from starlette.middleware import Middleware from starlette.middleware.gzip import GZipMiddleware from starlette.routing import Mount, Route routes = [ Mount( "/", routes=[ Route( "/example", endpoint=..., ) ], middleware=[Middleware(GZipMiddleware)] ) ] app = Starlette(routes=routes) ``` Note that middleware used in this way is *not* wrapped in exception handling middleware like the middleware applied to the `Starlette` application is. This is often not a problem because it only applies to middleware that inspect or modify the `Response`, and even then you probably don't want to apply this logic to error responses. If you do want to apply the middleware logic to error responses only on some routes you have a couple of options: * Add an `ExceptionMiddleware` onto the `Mount` * Add a `try/except` block to your middleware and return an error response from there * Split up marking and processing into two middlewares, one that gets put on `Mount` which marks the response as needing processing (for example by setting `scope["log-response"] = True`) and another applied to the `Starlette` application that does the heavy lifting. The `Route`/`WebSocket` class also accepts a `middleware` argument, which allows you to apply middleware to a single route: ```python from starlette.applications import Starlette from starlette.middleware import Middleware from starlette.middleware.gzip import GZipMiddleware from starlette.routing import Route routes = [ Route( "/example", endpoint=..., middleware=[Middleware(GZipMiddleware)] ) ] app = Starlette(routes=routes) ``` You can also apply middleware to the `Router` class, which allows you to apply middleware to a group of routes: ```python from starlette.applications import Starlette from starlette.middleware import Middleware from starlette.middleware.gzip import GZipMiddleware from starlette.routing import Route, Router routes = [ Route("/example", endpoint=...), Route("/another", endpoint=...), ] router = Router(routes=routes, middleware=[Middleware(GZipMiddleware)]) ``` ## Third party middleware #### [asgi-auth-github](https://github.com/simonw/asgi-auth-github) This middleware adds authentication to any ASGI application, requiring users to sign in using their GitHub account (via [OAuth](https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/)). Access can be restricted to specific users or to members of specific GitHub organizations or teams. #### [asgi-csrf](https://github.com/simonw/asgi-csrf) Middleware for protecting against CSRF attacks. This middleware implements the Double Submit Cookie pattern, where a cookie is set, then it is compared to a csrftoken hidden form field or an `x-csrftoken` HTTP header. #### [AuthlibMiddleware](https://github.com/aogier/starlette-authlib) A drop-in replacement for Starlette session middleware, using [authlib's jwt](https://docs.authlib.org/en/latest/jose/jwt.html) module. #### [BugsnagMiddleware](https://github.com/ashinabraham/starlette-bugsnag) A middleware class for logging exceptions to [Bugsnag](https://www.bugsnag.com/). #### [CSRFMiddleware](https://github.com/frankie567/starlette-csrf) Middleware for protecting against CSRF attacks. This middleware implements the Double Submit Cookie pattern, where a cookie is set, then it is compared to an `x-csrftoken` HTTP header. #### [EarlyDataMiddleware](https://github.com/HarrySky/starlette-early-data) Middleware and decorator for detecting and denying [TLSv1.3 early data](https://tools.ietf.org/html/rfc8470) requests. #### [PrometheusMiddleware](https://github.com/perdy/starlette-prometheus) A middleware class for capturing Prometheus metrics related to requests and responses, including in progress requests, timing... #### [ProxyHeadersMiddleware](https://github.com/encode/uvicorn/blob/main/uvicorn/middleware/proxy_headers.py) Uvicorn includes a middleware class for determining the client IP address, when proxy servers are being used, based on the `X-Forwarded-Proto` and `X-Forwarded-For` headers. For more complex proxy configurations, you might want to adapt this middleware. #### [RateLimitMiddleware](https://github.com/abersheeran/asgi-ratelimit) A rate limit middleware. Regular expression matches url; flexible rules; highly customizable. Very easy to use. #### [RequestIdMiddleware](https://github.com/snok/asgi-correlation-id) A middleware class for reading/generating request IDs and attaching them to application logs. #### [RollbarMiddleware](https://docs.rollbar.com/docs/starlette) A middleware class for logging exceptions, errors, and log messages to [Rollbar](https://www.rollbar.com). #### [StarletteOpentracing](https://github.com/acidjunk/starlette-opentracing) A middleware class that emits tracing info to [OpenTracing.io](https://opentracing.io/) compatible tracers and can be used to profile and monitor distributed applications. #### [SecureCookiesMiddleware](https://github.com/thearchitector/starlette-securecookies) Customizable middleware for adding automatic cookie encryption and decryption to Starlette applications, with extra support for existing cookie-based middleware. #### [TimingMiddleware](https://github.com/steinnes/timing-asgi) A middleware class to emit timing information (cpu and wall time) for each request which passes through it. Includes examples for how to emit these timings as statsd metrics. #### [WSGIMiddleware](https://github.com/abersheeran/a2wsgi) A middleware class in charge of converting a WSGI application into an ASGI one. starlette-0.50.0/docs/overrides/000077500000000000000000000000001510142272400165335ustar00rootroot00000000000000starlette-0.50.0/docs/overrides/main.html000066400000000000000000000006351510142272400203510ustar00rootroot00000000000000{% extends "base.html" %} {% block extrahead %} {{ super() }} {% endblock %} starlette-0.50.0/docs/overrides/partials/000077500000000000000000000000001510142272400203525ustar00rootroot00000000000000starlette-0.50.0/docs/overrides/partials/toc-item.html000066400000000000000000000012171510142272400227620ustar00rootroot00000000000000
  1. {{ toc_item.title }} {% if toc_item.children %} {% endif %} starlette-0.50.0/docs/release-notes.md000066400000000000000000001314511510142272400176260ustar00rootroot00000000000000--- toc_depth: 2 --- ## 0.50.0 (November 1, 2025) * Drop Python 3.9 support [#3061](https://github.com/Kludex/starlette/pull/3061). ## 0.49.3 (November 1, 2025) This is the last release that supports Python 3.9, which will be dropped in the next minor release. #### Fixed * Relax strictness on `Middleware` type [#3059](https://github.com/Kludex/starlette/pull/3059). ## 0.49.2 (November 1, 2025) #### Fixed * Ignore `if-modified-since` header if `if-none-match` is present in `StaticFiles` [#3044](https://github.com/Kludex/starlette/pull/3044). ## 0.49.1 (October 28, 2025) This release fixes a security vulnerability in the parsing logic of the `Range` header in `FileResponse`. You can view the full security advisory: [GHSA-7f5h-v6xp-fcq8](https://github.com/Kludex/starlette/security/advisories/GHSA-7f5h-v6xp-fcq8) #### Fixed * Optimize the HTTP ranges parsing logic [4ea6e22b489ec388d6004cfbca52dd5b147127c5](https://github.com/Kludex/starlette/commit/4ea6e22b489ec388d6004cfbca52dd5b147127c5) ## 0.49.0 (October 28, 2025) #### Added * Add `encoding` parameter to `Config` class [#2996](https://github.com/Kludex/starlette/pull/2996). * Support multiple cookie headers in `Request.cookies` [#3029](https://github.com/Kludex/starlette/pull/3029). * Use `Literal` type for `WebSocketEndpoint` encoding values [#3027](https://github.com/Kludex/starlette/pull/3027). #### Changed * Do not pollute exception context in `Middleware` when using `BaseHTTPMiddleware` [#2976](https://github.com/Kludex/starlette/pull/2976). ## 0.48.0 (September 13, 2025) #### Added * Add official Python 3.14 support [#3013](https://github.com/Kludex/starlette/pull/3013). #### Changed * Implement [RFC9110](https://www.rfc-editor.org/rfc/rfc9110) http status names [#2939](https://github.com/Kludex/starlette/pull/2939). ## 0.47.3 (August 24, 2025) #### Fixed * Use `asyncio.iscoroutinefunction` for Python 3.12 and older [#2984](https://github.com/Kludex/starlette/pull/2984). ## 0.47.2 (July 20, 2025) #### Fixed * Make `UploadFile` check for future rollover [#2962](https://github.com/Kludex/starlette/pull/2962). ## 0.47.1 (June 21, 2025) #### Fixed * Use `Self` in `TestClient.__enter__` [#2951](https://github.com/Kludex/starlette/pull/2951). * Allow async exception handlers to type-check [#2949](https://github.com/Kludex/starlette/pull/2949). ## 0.47.0 (May 29, 2025) #### Added * Add support for ASGI `pathsend` extension [#2671](https://github.com/Kludex/starlette/pull/2671). * Add `partitioned` attribute to `Response.set_cookie` [#2501](https://github.com/Kludex/starlette/pull/2501). #### Changed * Change `methods` parameter type from `list[str]` to `Collection[str]` [#2903](https://github.com/Kludex/starlette/pull/2903). * Replace `import typing` by `from typing import ...` in the whole codebase [#2867](https://github.com/Kludex/starlette/pull/2867). #### Fixed * Mark `ExceptionMiddleware.http_exception` as async to prevent thread creation [#2922](https://github.com/Kludex/starlette/pull/2922). ## 0.46.2 (April 13, 2025) #### Fixed * Prevents reraising of exception from BaseHttpMiddleware [#2911](https://github.com/Kludex/starlette/pull/2911). * Use correct index on backwards compatible logic in `TemplateResponse` [#2909](https://github.com/Kludex/starlette/pull/2909). ## 0.46.1 (March 8, 2025) #### Fixed * Allow relative directory path when `follow_symlinks=True` [#2896](https://github.com/Kludex/starlette/pull/2896). ## 0.46.0 (February 22, 2025) #### Added * `GZipMiddleware`: Make sure `Vary` header is always added if a response can be compressed [#2865](https://github.com/Kludex/starlette/pull/2865). #### Fixed * Raise exception from background task on BaseHTTPMiddleware [#2812](https://github.com/Kludex/starlette/pull/2812). * `GZipMiddleware`: Don't compress on server sent events [#2871](https://github.com/Kludex/starlette/pull/2871). #### Changed * `MultiPartParser`: Rename `max_file_size` to `spool_max_size` [#2780](https://github.com/Kludex/starlette/pull/2780). #### Deprecated * Add deprecated warning to `TestClient(timeout=...)` [#2840](https://github.com/Kludex/starlette/pull/2840). ## 0.45.3 (January 24, 2025) #### Fixed * Turn directory into string on `lookup_path` on commonpath comparison [#2851](https://github.com/Kludex/starlette/pull/2851). ## 0.45.2 (January 4, 2025) #### Fixed * Make `create_memory_object_stream` compatible with old anyio versions once again, and bump anyio minimum version to 3.6.2 [#2833](https://github.com/Kludex/starlette/pull/2833). ## 0.45.1 (December 30, 2024) #### Fixed * Close `MemoryObjectReceiveStream` left unclosed upon exception in `BaseHTTPMiddleware` children [#2813](https://github.com/Kludex/starlette/pull/2813). * Collect errors more reliably from the WebSocket logic on the `TestClient` [#2814](https://github.com/Kludex/starlette/pull/2814). #### Refactor * Use a pair of memory object streams instead of two queues on the `TestClient` [#2829](https://github.com/Kludex/starlette/pull/2829). ## 0.45.0 (December 29, 2024) #### Removed * Drop Python 3.8 support [#2823](https://github.com/Kludex/starlette/pull/2823). * Remove `ExceptionMiddleware` import proxy from `starlette.exceptions` module [#2826](https://github.com/Kludex/starlette/pull/2826). * Remove deprecated `WS_1004_NO_STATUS_RCVD` and `WS_1005_ABNORMAL_CLOSURE` [#2827](https://github.com/Kludex/starlette/pull/2827). ## 0.44.0 (December 28, 2024) #### Added * Add `client` parameter to `TestClient` [#2810](https://github.com/Kludex/starlette/pull/2810). * Add `max_part_size` parameter to `Request.form()` [#2815](https://github.com/Kludex/starlette/pull/2815). ## 0.43.0 (December 25, 2024) #### Removed * Remove deprecated `allow_redirects` argument from `TestClient` [#2808](https://github.com/Kludex/starlette/pull/2808). #### Added * Make UUID path parameter conversion more flexible [#2806](https://github.com/Kludex/starlette/pull/2806). ## 0.42.0 (December 14, 2024) #### Added * Raise `ClientDisconnect` on `StreamingResponse` [#2732](https://github.com/Kludex/starlette/pull/2732). #### Fixed * Use ETag from headers when parsing If-Range in FileResponse [#2761](https://github.com/Kludex/starlette/pull/2761). * Follow directory symlinks in `StaticFiles` when `follow_symlinks=True` [#2711](https://github.com/Kludex/starlette/pull/2711). * Bump minimum `python-multipart` version to `0.0.18` [0ba8395](https://github.com/Kludex/starlette/commit/0ba83959e609bbd460966f092287df1bbd564cc6). * Bump minimum `httpx` version to `0.27.0` [#2773](https://github.com/Kludex/starlette/pull/2773). ## 0.41.3 (November 18, 2024) #### Fixed * Exclude the query parameters from the `scope[raw_path]` on the `TestClient` [#2716](https://github.com/Kludex/starlette/pull/2716). * Replace `dict` by `Mapping` on `HTTPException.headers` [#2749](https://github.com/Kludex/starlette/pull/2749). * Correct middleware argument passing and improve factory pattern [#2752](https://github.com/Kludex/starlette/pull/2752). ## 0.41.2 (October 27, 2024) #### Fixed * Revert bump on `python-multipart` on `starlette[full]` extras [#2737](https://github.com/Kludex/starlette/pull/2737). ## 0.41.1 (October 24, 2024) #### Fixed * Bump minimum `python-multipart` version to `0.0.13` [#2734](https://github.com/Kludex/starlette/pull/2734). * Change `python-multipart` import to `python_multipart` [#2733](https://github.com/Kludex/starlette/pull/2733). ## 0.41.0 (October 15, 2024) #### Added - Allow to raise `HTTPException` before `websocket.accept()` [#2725](https://github.com/Kludex/starlette/pull/2725). ## 0.40.0 (October 15, 2024) This release fixes a Denial of service (DoS) via `multipart/form-data` requests. You can view the full security advisory: [GHSA-f96h-pmfr-66vw](https://github.com/Kludex/starlette/security/advisories/GHSA-f96h-pmfr-66vw) #### Fixed - Add `max_part_size` to `MultiPartParser` to limit the size of parts in `multipart/form-data` requests [fd038f3](https://github.com/Kludex/starlette/commit/fd038f3070c302bff17ef7d173dbb0b007617733). ## 0.39.2 (September 29, 2024) #### Fixed - Allow use of `request.url_for` when only "app" scope is available [#2672](https://github.com/Kludex/starlette/pull/2672). - Fix internal type hints to support `python-multipart==0.0.12` [#2708](https://github.com/Kludex/starlette/pull/2708). ## 0.39.1 (September 25, 2024) #### Fixed - Avoid regex re-compilation in `responses.py` and `schemas.py` [#2700](https://github.com/Kludex/starlette/pull/2700). - Improve performance of `get_route_path` by removing regular expression usage [#2701](https://github.com/Kludex/starlette/pull/2701). - Consider `FileResponse.chunk_size` when handling multiple ranges [#2703](https://github.com/Kludex/starlette/pull/2703). - Use `token_hex` for generating multipart boundary strings [#2702](https://github.com/Kludex/starlette/pull/2702). ## 0.39.0 (September 23, 2024) #### Added * Add support for [HTTP Range](https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests) to `FileResponse` [#2697](https://github.com/Kludex/starlette/pull/2697). ## 0.38.6 (September 22, 2024) #### Fixed * Close unclosed `MemoryObjectReceiveStream` in `TestClient` [#2693](https://github.com/Kludex/starlette/pull/2693). ## 0.38.5 (September 7, 2024) #### Fixed * Schedule `BackgroundTasks` from within `BaseHTTPMiddleware` [#2688](https://github.com/Kludex/starlette/pull/2688). This behavior was removed in 0.38.3, and is now restored. ## 0.38.4 (September 1, 2024) #### Fixed * Ensure accurate `root_path` removal in `get_route_path` function [#2600](https://github.com/Kludex/starlette/pull/2600). ## 0.38.3 (September 1, 2024) #### Added * Support for Python 3.13 [#2662](https://github.com/Kludex/starlette/pull/2662). #### Fixed * Don't poll for disconnects in `BaseHTTPMiddleware` via `StreamingResponse` [#2620](https://github.com/Kludex/starlette/pull/2620). ## 0.38.2 (July 27, 2024) #### Fixed * Not assume all routines have `__name__` on `routing.get_name()` [#2648](https://github.com/Kludex/starlette/pull/2648). ## 0.38.1 (July 23, 2024) #### Removed * Revert "Add support for ASGI pathsend extension" [#2649](https://github.com/Kludex/starlette/pull/2649). ## 0.38.0 (July 20, 2024) #### Added * Allow use of `memoryview` in `StreamingResponse` and `Response` [#2576](https://github.com/Kludex/starlette/pull/2576) and [#2577](https://github.com/Kludex/starlette/pull/2577). * Send 404 instead of 500 when filename requested is too long on `StaticFiles` [#2583](https://github.com/Kludex/starlette/pull/2583). #### Changed * Fail fast on invalid `Jinja2Template` instantiation parameters [#2568](https://github.com/Kludex/starlette/pull/2568). * Check endpoint handler is async only once [#2536](https://github.com/Kludex/starlette/pull/2536). #### Fixed * Add proper synchronization to `WebSocketTestSession` [#2597](https://github.com/Kludex/starlette/pull/2597). ## 0.37.2 (March 5, 2024) #### Added * Add `bytes` to `_RequestData` type [#2510](https://github.com/Kludex/starlette/pull/2510). #### Fixed * Revert "Turn `scope["client"]` to `None` on `TestClient` (#2377)" [#2525](https://github.com/Kludex/starlette/pull/2525). * Remove deprecated `app` argument passed to `httpx.Client` on the `TestClient` [#2526](https://github.com/Kludex/starlette/pull/2526). ## 0.37.1 (February 9, 2024) #### Fixed * Warn instead of raise for missing env file on `Config` [#2485](https://github.com/Kludex/starlette/pull/2485). ## 0.37.0 (February 5, 2024) #### Added * Support the WebSocket Denial Response ASGI extension [#2041](https://github.com/Kludex/starlette/pull/2041). ## 0.36.3 (February 4, 2024) #### Fixed * Create `anyio.Event` on async context [#2459](https://github.com/Kludex/starlette/pull/2459). ## 0.36.2 (February 3, 2024) #### Fixed * Upgrade `python-multipart` to `0.0.7` [13e5c26](http://github.com/Kludex/starlette/commit/13e5c26a27f4903924624736abd6131b2da80cc5). * Avoid duplicate charset on `Content-Type` [#2443](https://github.com/Kludex/starlette/2443). ## 0.36.1 (January 23, 2024) #### Fixed * Check if "extensions" in scope before checking the extension [#2438](http://github.com/Kludex/starlette/pull/2438). ## 0.36.0 (January 22, 2024) #### Added * Add support for ASGI `pathsend` extension [#2435](http://github.com/Kludex/starlette/pull/2435). * Cancel `WebSocketTestSession` on close [#2427](http://github.com/Kludex/starlette/pull/2427). * Raise `WebSocketDisconnect` when `WebSocket.send()` excepts `IOError` [#2425](http://github.com/Kludex/starlette/pull/2425). * Raise `FileNotFoundError` when the `env_file` parameter on `Config` is not valid [#2422](http://github.com/Kludex/starlette/pull/2422). ## 0.35.1 (January 11, 2024) #### Fixed * Stop using the deprecated "method" parameter in `FileResponse` inside of `StaticFiles` [#2406](https://github.com/Kludex/starlette/pull/2406). * Make `typing-extensions` optional again [#2409](https://github.com/Kludex/starlette/pull/2409). ## 0.35.0 (January 11, 2024) #### Added * Add `*args` to `Middleware` and improve its type hints [#2381](https://github.com/Kludex/starlette/pull/2381). #### Fixed * Use `Iterable` instead `Iterator` on `iterate_in_threadpool` [#2362](https://github.com/Kludex/starlette/pull/2362). #### Changes * Handle `root_path` to keep compatibility with mounted ASGI applications and WSGI [#2400](https://github.com/Kludex/starlette/pull/2400). * Turn `scope["client"]` to `None` on `TestClient` [#2377](https://github.com/Kludex/starlette/pull/2377). ## 0.34.0 (December 16, 2023) ### Added * Use `ParamSpec` for `run_in_threadpool` [#2375](https://github.com/Kludex/starlette/pull/2375). * Add `UploadFile.__repr__` [#2360](https://github.com/Kludex/starlette/pull/2360). ### Fixed * Merge URLs properly on `TestClient` [#2376](https://github.com/Kludex/starlette/pull/2376). * Take weak ETags in consideration on `StaticFiles` [#2334](https://github.com/Kludex/starlette/pull/2334). ### Deprecated * Deprecate `FileResponse(method=...)` parameter [#2366](https://github.com/Kludex/starlette/pull/2366). ## 0.33.0 (December 1, 2023) ### Added * Add `middleware` per `Route`/`WebSocketRoute` [#2349](https://github.com/Kludex/starlette/pull/2349). * Add `middleware` per `Router` [#2351](https://github.com/Kludex/starlette/pull/2351). ### Fixed * Do not overwrite `"path"` and `"root_path"` scope keys [#2352](https://github.com/Kludex/starlette/pull/2352). * Set `ensure_ascii=False` on `json.dumps()` for `WebSocket.send_json()` [#2341](https://github.com/Kludex/starlette/pull/2341). ## 0.32.0.post1 (November 5, 2023) ### Fixed * Revert mkdocs-material from 9.1.17 to 9.4.7 [#2326](https://github.com/Kludex/starlette/pull/2326). ## 0.32.0 (November 4, 2023) ### Added * Send `reason` on `WebSocketDisconnect` [#2309](https://github.com/Kludex/starlette/pull/2309). * Add `domain` parameter to `SessionMiddleware` [#2280](https://github.com/Kludex/starlette/pull/2280). ### Changed * Inherit from `HTMLResponse` instead of `Response` on `_TemplateResponse` [#2274](https://github.com/Kludex/starlette/pull/2274). * Restore the `Response.render` type annotation to its pre-0.31.0 state [#2264](https://github.com/Kludex/starlette/pull/2264). ## 0.31.1 (August 26, 2023) ### Fixed * Fix import error when `exceptiongroup` isn't available [#2231](https://github.com/Kludex/starlette/pull/2231). * Set `url_for` global for custom Jinja environments [#2230](https://github.com/Kludex/starlette/pull/2230). ## 0.31.0 (July 24, 2023) ### Added * Officially support Python 3.12 [#2214](https://github.com/Kludex/starlette/pull/2214). * Support AnyIO 4.0 [#2211](https://github.com/Kludex/starlette/pull/2211). * Strictly type annotate Starlette (strict mode on mypy) [#2180](https://github.com/Kludex/starlette/pull/2180). ### Fixed * Don't group duplicated headers on a single string when using the `TestClient` [#2219](https://github.com/Kludex/starlette/pull/2219). ## 0.30.0 (July 13, 2023) ### Removed * Drop Python 3.7 support [#2178](https://github.com/Kludex/starlette/pull/2178). ## 0.29.0 (July 13, 2023) ### Added * Add `follow_redirects` parameter to `TestClient` [#2207](https://github.com/Kludex/starlette/pull/2207). * Add `__str__` to `HTTPException` and `WebSocketException` [#2181](https://github.com/Kludex/starlette/pull/2181). * Warn users when using `lifespan` together with `on_startup`/`on_shutdown` [#2193](https://github.com/Kludex/starlette/pull/2193). * Collect routes from `Host` to generate the OpenAPI schema [#2183](https://github.com/Kludex/starlette/pull/2183). * Add `request` argument to `TemplateResponse` [#2191](https://github.com/Kludex/starlette/pull/2191). ### Fixed * Stop `body_stream` in case `more_body=False` on `BaseHTTPMiddleware` [#2194](https://github.com/Kludex/starlette/pull/2194). ## 0.28.0 (June 7, 2023) ### Changed * Reuse `Request`'s body buffer for call_next in `BaseHTTPMiddleware` [#1692](https://github.com/Kludex/starlette/pull/1692). * Move exception handling logic to `Route` [#2026](https://github.com/Kludex/starlette/pull/2026). ### Added * Add `env` parameter to `Jinja2Templates`, and deprecate `**env_options` [#2159](https://github.com/Kludex/starlette/pull/2159). * Add clear error message when `httpx` is not installed [#2177](https://github.com/Kludex/starlette/pull/2177). ### Fixed * Allow "name" argument on `templates url_for()` [#2127](https://github.com/Kludex/starlette/pull/2127). ## 0.27.0 (May 16, 2023) This release fixes a path traversal vulnerability in `StaticFiles`. You can view the full security advisory: https://github.com/Kludex/starlette/security/advisories/GHSA-v5gw-mw7f-84px ### Added * Minify JSON websocket data via `send_json` https://github.com/Kludex/starlette/pull/2128 ### Fixed * Replace `commonprefix` by `commonpath` on `StaticFiles` [1797de4](https://github.com/Kludex/starlette/commit/1797de464124b090f10cf570441e8292936d63e3). * Convert ImportErrors into ModuleNotFoundError [#2135](https://github.com/Kludex/starlette/pull/2135). * Correct the RuntimeError message content in websockets [#2141](https://github.com/Kludex/starlette/pull/2141). ## 0.26.1 (March 13, 2023) ### Fixed * Fix typing of Lifespan to allow subclasses of Starlette [#2077](https://github.com/Kludex/starlette/pull/2077). ## 0.26.0.post1 (March 9, 2023) ### Fixed * Replace reference from Events to Lifespan on the mkdocs.yml [#2072](https://github.com/Kludex/starlette/pull/2072). ## 0.26.0 (March 9, 2023) ### Added * Support [lifespan state](lifespan.md) [#2060](https://github.com/Kludex/starlette/pull/2060), [#2065](https://github.com/Kludex/starlette/pull/2065) and [#2064](https://github.com/Kludex/starlette/pull/2064). ### Changed * Change `url_for` signature to return a `URL` instance [#1385](https://github.com/Kludex/starlette/pull/1385). ### Fixed * Allow "name" argument on `url_for()` and `url_path_for()` [#2050](https://github.com/Kludex/starlette/pull/2050). ### Deprecated * Deprecate `on_startup` and `on_shutdown` events [#2070](https://github.com/Kludex/starlette/pull/2070). ## 0.25.0 (February 14, 2023) ### Fix * Limit the number of fields and files when parsing `multipart/form-data` on the `MultipartParser` [8c74c2c](https://github.com/Kludex/starlette/commit/8c74c2c8dba7030154f8af18e016136bea1938fa) and [#2036](https://github.com/Kludex/starlette/pull/2036). ## 0.24.0 (February 6, 2023) ### Added * Allow `StaticFiles` to follow symlinks [#1683](https://github.com/Kludex/starlette/pull/1683). * Allow `Request.form()` as a context manager [#1903](https://github.com/Kludex/starlette/pull/1903). * Add `size` attribute to `UploadFile` [#1405](https://github.com/Kludex/starlette/pull/1405). * Add `env_prefix` argument to `Config` [#1990](https://github.com/Kludex/starlette/pull/1990). * Add template context processors [#1904](https://github.com/Kludex/starlette/pull/1904). * Support `str` and `datetime` on `expires` parameter on the `Response.set_cookie` method [#1908](https://github.com/Kludex/starlette/pull/1908). ### Changed * Lazily build the middleware stack [#2017](https://github.com/Kludex/starlette/pull/2017). * Make the `file` argument required on `UploadFile` [#1413](https://github.com/Kludex/starlette/pull/1413). * Use debug extension instead of custom response template extension [#1991](https://github.com/Kludex/starlette/pull/1991). ### Fixed * Fix url parsing of ipv6 urls on `URL.replace` [#1965](https://github.com/Kludex/starlette/pull/1965). ## 0.23.1 (December 9, 2022) ### Fixed * Only stop receiving stream on `body_stream` if body is empty on the `BaseHTTPMiddleware` [#1940](https://github.com/Kludex/starlette/pull/1940). ## 0.23.0 (December 5, 2022) ### Added * Add `headers` parameter to the `TestClient` [#1966](https://github.com/Kludex/starlette/pull/1966). ### Deprecated * Deprecate `Starlette` and `Router` decorators [#1897](https://github.com/Kludex/starlette/pull/1897). ### Fixed * Fix bug on `FloatConvertor` regex [#1973](https://github.com/Kludex/starlette/pull/1973). ## 0.22.0 (November 17, 2022) ### Changed * Bypass `GZipMiddleware` when response includes `Content-Encoding` [#1901](https://github.com/Kludex/starlette/pull/1901). ### Fixed * Remove unneeded `unquote()` from query parameters on the `TestClient` [#1953](https://github.com/Kludex/starlette/pull/1953). * Make sure `MutableHeaders._list` is actually a `list` [#1917](https://github.com/Kludex/starlette/pull/1917). * Import compatibility with the next version of `AnyIO` [#1936](https://github.com/Kludex/starlette/pull/1936). ## 0.21.0 (September 26, 2022) This release replaces the underlying HTTP client used on the `TestClient` (`requests` :arrow_right: `httpx`), and as those clients [differ _a bit_ on their API](https://www.python-httpx.org/compatibility/), your test suite will likely break. To make the migration smoother, you can use the [`bump-testclient`](https://github.com/Kludex/bump-testclient) tool. ### Changed * Replace `requests` with `httpx` in `TestClient` [#1376](https://github.com/Kludex/starlette/pull/1376). ### Added * Add `WebSocketException` and support for WebSocket exception handlers [#1263](https://github.com/Kludex/starlette/pull/1263). * Add `middleware` parameter to `Mount` class [#1649](https://github.com/Kludex/starlette/pull/1649). * Officially support Python 3.11 [#1863](https://github.com/Kludex/starlette/pull/1863). * Implement `__repr__` for route classes [#1864](https://github.com/Kludex/starlette/pull/1864). ### Fixed * Fix bug on which `BackgroundTasks` were cancelled when using `BaseHTTPMiddleware` and client disconnected [#1715](https://github.com/Kludex/starlette/pull/1715). ## 0.20.4 (June 28, 2022) ### Fixed * Remove converter from path when generating OpenAPI schema [#1648](https://github.com/Kludex/starlette/pull/1648). ## 0.20.3 (June 10, 2022) ### Fixed * Revert "Allow `StaticFiles` to follow symlinks" [#1681](https://github.com/Kludex/starlette/pull/1681). ## 0.20.2 (June 7, 2022) ### Fixed * Fix regression on route paths with colons [#1675](https://github.com/Kludex/starlette/pull/1675). * Allow `StaticFiles` to follow symlinks [#1337](https://github.com/Kludex/starlette/pull/1377). ## 0.20.1 (May 28, 2022) ### Fixed * Improve detection of async callables [#1444](https://github.com/Kludex/starlette/pull/1444). * Send 400 (Bad Request) when `boundary` is missing [#1617](https://github.com/Kludex/starlette/pull/1617). * Send 400 (Bad Request) when missing "name" field on `Content-Disposition` header [#1643](https://github.com/Kludex/starlette/pull/1643). * Do not send empty data to `StreamingResponse` on `BaseHTTPMiddleware` [#1609](https://github.com/Kludex/starlette/pull/1609). * Add `__bool__` dunder for `Secret` [#1625](https://github.com/Kludex/starlette/pull/1625). ## 0.20.0 (May 3, 2022) ### Removed * Drop Python 3.6 support [#1357](https://github.com/Kludex/starlette/pull/1357) and [#1616](https://github.com/Kludex/starlette/pull/1616). ## 0.19.1 (April 22, 2022) ### Fixed * Fix inference of `Route.name` when created from methods [#1553](https://github.com/Kludex/starlette/pull/1553). * Avoid `TypeError` on `websocket.disconnect` when code is `None` [#1574](https://github.com/Kludex/starlette/pull/1574). ### Deprecated * Deprecate `WS_1004_NO_STATUS_RCVD` and `WS_1005_ABNORMAL_CLOSURE` in favor of `WS_1005_NO_STATUS_RCVD` and `WS_1006_ABNORMAL_CLOSURE`, as the previous constants didn't match the [WebSockets specs](https://www.iana.org/assignments/websocket/websocket.xhtml) [#1580](https://github.com/Kludex/starlette/pull/1580). ## 0.19.0 (March 9, 2022) ### Added * Error handler will always run, even if the error happens on a background task [#761](https://github.com/Kludex/starlette/pull/761). * Add `headers` parameter to `HTTPException` [#1435](https://github.com/Kludex/starlette/pull/1435). * Internal responses with `405` status code insert an `Allow` header, as described by [RFC 7231](https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.5) [#1436](https://github.com/Kludex/starlette/pull/1436). * The `content` argument in `JSONResponse` is now required [#1431](https://github.com/Kludex/starlette/pull/1431). * Add custom URL convertor register [#1437](https://github.com/Kludex/starlette/pull/1437). * Add content disposition type parameter to `FileResponse` [#1266](https://github.com/Kludex/starlette/pull/1266). * Add next query param with original request URL in requires decorator [#920](https://github.com/Kludex/starlette/pull/920). * Add `raw_path` to `TestClient` scope [#1445](https://github.com/Kludex/starlette/pull/1445). * Add union operators to `MutableHeaders` [#1240](https://github.com/Kludex/starlette/pull/1240). * Display missing route details on debug page [#1363](https://github.com/Kludex/starlette/pull/1363). * Change `anyio` required version range to `>=3.4.0,<5.0` [#1421](https://github.com/Kludex/starlette/pull/1421) and [#1460](https://github.com/Kludex/starlette/pull/1460). * Add `typing-extensions>=3.10` requirement - used only on lower versions than Python 3.10 [#1475](https://github.com/Kludex/starlette/pull/1475). ### Fixed * Prevent `BaseHTTPMiddleware` from hiding errors of `StreamingResponse` and mounted applications [#1459](https://github.com/Kludex/starlette/pull/1459). * `SessionMiddleware` uses an explicit `path=...`, instead of defaulting to the ASGI 'root_path' [#1512](https://github.com/Kludex/starlette/pull/1512). * `Request.client` is now compliant with the ASGI specifications [#1462](https://github.com/Kludex/starlette/pull/1462). * Raise `KeyError` at early stage for missing boundary [#1349](https://github.com/Kludex/starlette/pull/1349). ### Deprecated * Deprecate WSGIMiddleware in favor of a2wsgi [#1504](https://github.com/Kludex/starlette/pull/1504). * Deprecate `run_until_first_complete` [#1443](https://github.com/Kludex/starlette/pull/1443). ## 0.18.0 (January 23, 2022) ### Added * Change default chunk size from 4Kb to 64Kb on `FileResponse` [#1345](https://github.com/Kludex/starlette/pull/1345). * Add support for `functools.partial` in `WebSocketRoute` [#1356](https://github.com/Kludex/starlette/pull/1356). * Add `StaticFiles` packages with directory [#1350](https://github.com/Kludex/starlette/pull/1350). * Allow environment options in `Jinja2Templates` [#1401](https://github.com/Kludex/starlette/pull/1401). * Allow HEAD method on `HttpEndpoint` [#1346](https://github.com/Kludex/starlette/pull/1346). * Accept additional headers on `websocket.accept` message [#1361](https://github.com/Kludex/starlette/pull/1361) and [#1422](https://github.com/Kludex/starlette/pull/1422). * Add `reason` to `WebSocket` close ASGI event [#1417](https://github.com/Kludex/starlette/pull/1417). * Add headers attribute to `UploadFile` [#1382](https://github.com/Kludex/starlette/pull/1382). * Don't omit `Content-Length` header for `Content-Length: 0` cases [#1395](https://github.com/Kludex/starlette/pull/1395). * Don't set headers for responses with 1xx, 204 and 304 status code [#1397](https://github.com/Kludex/starlette/pull/1397). * `SessionMiddleware.max_age` now accepts `None`, so cookie can last as long as the browser session [#1387](https://github.com/Kludex/starlette/pull/1387). ### Fixed * Tweak `hashlib.md5()` function on `FileResponse`s ETag generation. The parameter [`usedforsecurity`](https://bugs.python.org/issue9216) flag is set to `False`, if the flag is available on the system. This fixes an error raised on systems with [FIPS](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/FIPS_Mode_-_an_explanation) enabled [#1366](https://github.com/Kludex/starlette/pull/1366) and [#1410](https://github.com/Kludex/starlette/pull/1410). * Fix `path_params` type on `url_path_for()` method i.e. turn `str` into `Any` [#1341](https://github.com/Kludex/starlette/pull/1341). * `Host` now ignores `port` on routing [#1322](https://github.com/Kludex/starlette/pull/1322). ## 0.17.1 (November 17, 2021) ### Fixed * Fix `IndexError` in authentication `requires` when wrapped function arguments are distributed between `*args` and `**kwargs` [#1335](https://github.com/Kludex/starlette/pull/1335). ## 0.17.0 (November 4, 2021) ### Added * `Response.delete_cookie` now accepts the same parameters as `Response.set_cookie` [#1228](https://github.com/Kludex/starlette/pull/1228). * Update the `Jinja2Templates` constructor to allow `PathLike` [#1292](https://github.com/Kludex/starlette/pull/1292). ### Fixed * Fix BadSignature exception handling in SessionMiddleware [#1264](https://github.com/Kludex/starlette/pull/1264). * Change `HTTPConnection.__getitem__` return type from `str` to `typing.Any` [#1118](https://github.com/Kludex/starlette/pull/1118). * Change `ImmutableMultiDict.getlist` return type from `typing.List[str]` to `typing.List[typing.Any]` [#1235](https://github.com/Kludex/starlette/pull/1235). * Handle `OSError` exceptions on `StaticFiles` [#1220](https://github.com/Kludex/starlette/pull/1220). * Fix `StaticFiles` 404.html in HTML mode [#1314](https://github.com/Kludex/starlette/pull/1314). * Prevent anyio.ExceptionGroup in error views under a BaseHTTPMiddleware [#1262](https://github.com/Kludex/starlette/pull/1262). ### Removed * Remove GraphQL support [#1198](https://github.com/Kludex/starlette/pull/1198). ## 0.16.0 (July 19, 2021) ### Added * Added [Encode](https://github.com/sponsors/encode) funding option [#1219](https://github.com/Kludex/starlette/pull/1219) ### Fixed * `starlette.websockets.WebSocket` instances are now hashable and compare by identity [#1039](https://github.com/Kludex/starlette/pull/1039) * A number of fixes related to running task groups in lifespan [#1213](https://github.com/Kludex/starlette/pull/1213), [#1227](https://github.com/Kludex/starlette/pull/1227) ### Deprecated/removed * The method `starlette.templates.Jinja2Templates.get_env` was removed [#1218](https://github.com/Kludex/starlette/pull/1218) * The ClassVar `starlette.testclient.TestClient.async_backend` was removed, the backend is now configured using constructor kwargs [#1211](https://github.com/Kludex/starlette/pull/1211) * Passing an Async Generator Function or a Generator Function to `starlette.routing.Router(lifespan=)` is deprecated. You should wrap your lifespan in `@contextlib.asynccontextmanager`. [#1227](https://github.com/Kludex/starlette/pull/1227) [#1110](https://github.com/Kludex/starlette/pull/1110) ## 0.15.0 (June 23, 2021) This release includes major changes to the low-level asynchronous parts of Starlette. As a result, **Starlette now depends on [AnyIO](https://anyio.readthedocs.io/en/stable/)** and some minor API changes have occurred. Another significant change with this release is the **deprecation of built-in GraphQL support**. ### Added * Starlette now supports [Trio](https://trio.readthedocs.io/en/stable/) as an async runtime via AnyIO - [#1157](https://github.com/Kludex/starlette/pull/1157). * `TestClient.websocket_connect()` now must be used as a context manager. * Initial support for Python 3.10 - [#1201](https://github.com/Kludex/starlette/pull/1201). * The compression level used in `GZipMiddleware` is now adjustable - [#1128](https://github.com/Kludex/starlette/pull/1128). ### Fixed * Several fixes to `CORSMiddleware`. See [#1111](https://github.com/Kludex/starlette/pull/1111), [#1112](https://github.com/Kludex/starlette/pull/1112), [#1113](https://github.com/Kludex/starlette/pull/1113), [#1199](https://github.com/Kludex/starlette/pull/1199). * Improved exception messages in the case of duplicated path parameter names - [#1177](https://github.com/Kludex/starlette/pull/1177). * `RedirectResponse` now uses `quote` instead of `quote_plus` encoding for the `Location` header to better match the behaviour in other frameworks such as Django - [#1164](https://github.com/Kludex/starlette/pull/1164). * Exception causes are now preserved in more cases - [#1158](https://github.com/Kludex/starlette/pull/1158). * Session cookies now use the ASGI root path in the case of mounted applications - [#1147](https://github.com/Kludex/starlette/pull/1147). * Fixed a cache invalidation bug when static files were deleted in certain circumstances - [#1023](https://github.com/Kludex/starlette/pull/1023). * Improved memory usage of `BaseHTTPMiddleware` when handling large responses - [#1012](https://github.com/Kludex/starlette/issues/1012) fixed via #1157 ### Deprecated/removed * Built-in GraphQL support via the `GraphQLApp` class has been deprecated and will be removed in a future release. Please see [#619](https://github.com/Kludex/starlette/issues/619). GraphQL is not supported on Python 3.10. * The `executor` parameter to `GraphQLApp` was removed. Use `executor_class` instead. * The `workers` parameter to `WSGIMiddleware` was removed. This hasn't had any effect since Starlette v0.6.3. ## 0.14.2 (February 2, 2021) ### Fixed * Fixed `ServerErrorMiddleware` compatibility with Python 3.9.1/3.8.7 when debug mode is enabled - [#1132](https://github.com/Kludex/starlette/pull/1132). * Fixed unclosed socket `ResourceWarning`s when using the `TestClient` with WebSocket endpoints - #1132. * Improved detection of `async` endpoints wrapped in `functools.partial` on Python 3.8+ - [#1106](https://github.com/Kludex/starlette/pull/1106). ## 0.14.1 (November 9th, 2020) ### Removed * `UJSONResponse` was removed (this change was intended to be included in 0.14.0). Please see the [documentation](https://starlette.dev/responses/#custom-json-serialization) for how to implement responses using custom JSON serialization - [#1074](https://github.com/Kludex/starlette/pull/1047). ## 0.14.0 (November 8th, 2020) ### Added * Starlette now officially supports Python3.9. * In `StreamingResponse`, allow custom async iterator such as objects from classes implementing `__aiter__`. * Allow usage of `functools.partial` async handlers in Python versions 3.6 and 3.7. * Add 418 I'm A Teapot status code. ### Changed * Create tasks from handler coroutines before sending them to `asyncio.wait`. * Use `format_exception` instead of `format_tb` in `ServerErrorMiddleware`'s `debug` responses. * Be more lenient with handler arguments when using the `requires` decorator. ## 0.13.8 * Revert `Queue(maxsize=1)` fix for `BaseHTTPMiddleware` middleware classes and streaming responses. * The `StaticFiles` constructor now allows `pathlib.Path` in addition to strings for its `directory` argument. ## 0.13.7 * Fix high memory usage when using `BaseHTTPMiddleware` middleware classes and streaming responses. ## 0.13.6 * Fix 404 errors with `StaticFiles`. ## 0.13.5 * Add support for `Starlette(lifespan=...)` functions. * More robust path-traversal check in StaticFiles app. * Fix WSGI PATH_INFO encoding. * RedirectResponse now accepts optional background parameter * Allow path routes to contain regex meta characters * Treat ASGI HTTP 'body' as an optional key. * Don't use thread pooling for writing to in-memory upload files. ## 0.13.0 * Switch to promoting application configuration on init style everywhere. This means dropping the decorator style in favour of declarative routing tables and middleware definitions. ## 0.12.12 * Fix `request.url_for()` for the Mount-within-a-Mount case. ## 0.12.11 * Fix `request.url_for()` when an ASGI `root_path` is being used. ## 0.12.1 * Add `URL.include_query_params(**kwargs)` * Add `URL.replace_query_params(**kwargs)` * Add `URL.remove_query_params(param_names)` * `request.state` properly persisting across middleware. * Added `request.scope` interface. ## 0.12.0 * Switch to ASGI 3.0. * Fixes to CORS middleware. * Add `StaticFiles(html=True)` support. * Fix path quoting in redirect responses. ## 0.11.1 * Add `request.state` interface, for storing arbitrary additional information. * Support disabling GraphiQL with `GraphQLApp(..., graphiql=False)`. ## 0.11.0 * `DatabaseMiddleware` is now dropped in favour of `databases` * Templates are no longer configured on the application instance. Use `templates = Jinja2Templates(directory=...)` and `return templates.TemplateResponse('index.html', {"request": request})` * Schema generation is no longer attached to the application instance. Use `schemas = SchemaGenerator(...)` and `return schemas.OpenAPIResponse(request=request)` * `LifespanMiddleware` is dropped in favor of router-based lifespan handling. * Application instances now accept a `routes` argument, `Starlette(routes=[...])` * Schema generation now includes mounted routes. ## 0.10.6 * Add `Lifespan` routing component. ## 0.10.5 * Ensure `templating` does not strictly require `jinja2` to be installed. ## 0.10.4 * Templates are now configured independently from the application instance. `templates = Jinja2Templates(directory=...)`. Existing API remains in place, but is no longer documented, and will be deprecated in due course. See the template documentation for more details. ## 0.10.3 * Move to independent `databases` package instead of `DatabaseMiddleware`. Existing API remains in place, but is no longer documented, and will be deprecated in due course. ## 0.10.2 * Don't drop explicit port numbers on redirects from `HTTPSRedirectMiddleware`. ## 0.10.1 * Add MySQL database support. * Add host-based routing. ## 0.10.0 * WebSockets now default to sending/receiving JSON over text data frames. Use `.send_json(data, mode="binary")` and `.receive_json(mode="binary")` for binary framing. * `GraphQLApp` now takes an `executor_class` argument, which should be used in preference to the existing `executor` argument. Resolves an issue with async executors being instantiated before the event loop was setup. The `executor` argument is expected to be deprecated in the next median or major release. * Authentication and the `@requires` decorator now support WebSocket endpoints. * `MultiDict` and `ImmutableMultiDict` classes are available in `uvicorn.datastructures`. * `QueryParams` is now instantiated with standard dict-style `*args, **kwargs` arguments. ## 0.9.11 * Session cookies now include browser 'expires', in addition to the existing signed expiry. * `request.form()` now returns a multi-dict interface. * The query parameter multi-dict implementation now mirrors `dict` more correctly for the behavior of `.keys()`, `.values()`, and `.items()` when multiple same-key items occur. * Use `urlsplit` throughout in favor of `urlparse`. ## 0.9.10 * Support `@requires(...)` on class methods. * Apply URL escaping to form data. * Support `HEAD` requests automatically. * Add `await request.is_disconnected()`. * Pass operationName to GraphQL executor. ## 0.9.9 * Add `TemplateResponse`. * Add `CommaSeparatedStrings` datatype. * Add `BackgroundTasks` for multiple tasks. * Common subclass for `Request` and `WebSocket`, to eg. share `session` functionality. * Expose remote address with `request.client`. ## 0.9.8 * Add `request.database.executemany`. ## 0.9.7 * Ensure that `AuthenticationMiddleware` handles lifespan messages correctly. ## 0.9.6 * Add `AuthenticationMiddleware`, and `@requires()` decorator. ## 0.9.5 * Support either `str` or `Secret` for `SessionMiddleware(secret_key=...)`. ## 0.9.4 * Add `config.environ`. * Add `datastructures.Secret`. * Add `datastructures.DatabaseURL`. ## 0.9.3 * Add `config.Config(".env")` ## 0.9.2 * Add optional database support. * Add `request` to GraphQL context. * Hide any password component in `URL.__repr__`. ## 0.9.1 * Handle startup/shutdown errors properly. ## 0.9.0 * `TestClient` can now be used as a context manager, instead of `LifespanContext`. * Lifespan is now handled as middleware. Startup and Shutdown events are visible throughout the middleware stack. ## 0.8.8 * Better support for third-party API schema generators. ## 0.8.7 * Support chunked requests with TestClient. * Cleanup asyncio tasks properly with WSGIMiddleware. * Support using TestClient within endpoints, for service mocking. ## 0.8.6 * Session cookies are now set on the root path. ## 0.8.5 * Support URL convertors. * Support HTTP 304 cache responses from `StaticFiles`. * Resolve character escaping issue with form data. ## 0.8.4 * Default to empty body on responses. ## 0.8.3 * Add 'name' argument to `@app.route()`. * Use 'Host' header for URL reconstruction. ## 0.8.2 ### StaticFiles * StaticFiles no longer reads the file for responses to `HEAD` requests. ## 0.8.1 ### Templating * Add a default templating configuration with Jinja2. Allows the following: ```python app = Starlette(template_directory="templates") @app.route('/') async def homepage(request): # `url_for` is available inside the template. template = app.get_template('index.html') content = template.render(request=request) return HTMLResponse(content) ``` ## 0.8.0 ### Exceptions * Add support for `@app.exception_handler(404)`. * Ensure handled exceptions are not seen as errors by the middleware stack. ### SessionMiddleware * Add `max_age`, and use timestamp-signed cookies. Defaults to two weeks. ### Cookies * Ensure cookies are strictly HTTP correct. ### StaticFiles * Check directory exists on instantiation. ## 0.7.4 ### Concurrency * Add `starlette.concurrency.run_in_threadpool`. Now handles `contextvar` support. ## 0.7.3 ### Routing * Add `name=` support to `app.mount()`. This allows eg: `app.mount('/static', StaticFiles(directory='static'), name='static')`. ## 0.7.2 ### Middleware * Add support for `@app.middleware("http")` decorator. ### Routing * Add "endpoint" to ASGI scope. ## 0.7.1 ### Debug tracebacks * Improve debug traceback information & styling. ### URL routing * Support mounted URL lookups with "path=", eg. `url_for('static', path=...)`. * Support nested URL lookups, eg. `url_for('admin:user', username=...)`. * Add redirect slashes support. * Add www redirect support. ### Background tasks * Add background task support to `FileResponse` and `StreamingResponse`. ## 0.7.0 ### API Schema support * Add `app.schema_generator = SchemaGenerator(...)`. * Add `app.schema` property. * Add `OpenAPIResponse(...)`. ### GraphQL routing * Drop `app.add_graphql_route("/", ...)` in favor of more consistent `app.add_route("/", GraphQLApp(...))`. ## 0.6.3 ### Routing API * Support routing to methods. * Ensure `url_path_for` works with Mount('/{some_path_params}'). * Fix Router(default=) argument. * Support repeated paths, like: `@app.route("/", methods=["GET"])`, `@app.route("/", methods=["POST"])` * Use the default ThreadPoolExecutor for all sync endpoints. ## 0.6.2 ### SessionMiddleware Added support for `request.session`, with `SessionMiddleware`. ## 0.6.1 ### BaseHTTPMiddleware Added support for `BaseHTTPMiddleware`, which provides a standard request/response interface over a regular ASGI middleware. This means you can write ASGI middleware while still working at a request/response level, rather than handling ASGI messages directly. ```python from starlette.applications import Starlette from starlette.middleware.base import BaseHTTPMiddleware class CustomMiddleware(BaseHTTPMiddleware): async def dispatch(self, request, call_next): response = await call_next(request) response.headers['Custom-Header'] = 'Example' return response app = Starlette() app.add_middleware(CustomMiddleware) ``` ## 0.6.0 ### request.path_params The biggest change in 0.6 is that endpoint signatures are no longer: ```python async def func(request: Request, **kwargs) -> Response ``` Instead we just use: ```python async def func(request: Request) -> Response ``` The path parameters are available on the request as `request.path_params`. This is different to most Python webframeworks, but I think it actually ends up being much more nicely consistent all the way through. ### request.url_for() Request and WebSocketSession now support URL reversing with `request.url_for(name, **path_params)`. This method returns a fully qualified `URL` instance. The URL instance is a string-like object. ### app.url_path_for() Applications now support URL path reversing with `app.url_path_for(name, **path_params)`. This method returns a `URL` instance with the path and scheme set. The URL instance is a string-like object, and will return only the path if coerced to a string. ### app.routes Applications now support a `.routes` parameter, which returns a list of `[Route|WebSocketRoute|Mount]`. ### Route, WebSocketRoute, Mount The low level components to `Router` now match the `@app.route()`, `@app.websocket_route()`, and `app.mount()` signatures. starlette-0.50.0/docs/requests.md000066400000000000000000000151501510142272400167300ustar00rootroot00000000000000 Starlette includes a `Request` class that gives you a nicer interface onto the incoming request, rather than accessing the ASGI scope and receive channel directly. ### Request Signature: `Request(scope, receive=None)` ```python from starlette.requests import Request from starlette.responses import Response async def app(scope, receive, send): assert scope['type'] == 'http' request = Request(scope, receive) content = '%s %s' % (request.method, request.url.path) response = Response(content, media_type='text/plain') await response(scope, receive, send) ``` Requests present a mapping interface, so you can use them in the same way as a `scope`. For instance: `request['path']` will return the ASGI path. If you don't need to access the request body you can instantiate a request without providing an argument to `receive`. #### Method The request method is accessed as `request.method`. #### URL The request URL is accessed as `request.url`. The property is a string-like object that exposes all the components that can be parsed out of the URL. For example: `request.url.path`, `request.url.port`, `request.url.scheme`. #### Headers Headers are exposed as an immutable, case-insensitive, multi-dict. For example: `request.headers['content-type']` #### Query Parameters Query parameters are exposed as an immutable multi-dict. For example: `request.query_params['search']` #### Path Parameters Router path parameters are exposed as a dictionary interface. For example: `request.path_params['username']` #### Client Address The client's remote address is exposed as a named two-tuple `request.client` (or `None`). The hostname or IP address: `request.client.host` The port number from which the client is connecting: `request.client.port` #### Cookies Cookies are exposed as a regular dictionary interface. For example: `request.cookies.get('mycookie')` Cookies are ignored in case of an invalid cookie. (RFC2109) #### Body There are a few different interfaces for returning the body of the request: The request body as bytes: `await request.body()` The request body, parsed as form data or multipart: `async with request.form() as form:` The request body, parsed as JSON: `await request.json()` You can also access the request body as a stream, using the `async for` syntax: ```python from starlette.requests import Request from starlette.responses import Response async def app(scope, receive, send): assert scope['type'] == 'http' request = Request(scope, receive) body = b'' async for chunk in request.stream(): body += chunk response = Response(body, media_type='text/plain') await response(scope, receive, send) ``` If you access `.stream()` then the byte chunks are provided without storing the entire body to memory. Any subsequent calls to `.body()`, `.form()`, or `.json()` will raise an error. In some cases such as long-polling, or streaming responses you might need to determine if the client has dropped the connection. You can determine this state with `disconnected = await request.is_disconnected()`. #### Request Files Request files are normally sent as multipart form data (`multipart/form-data`). Signature: `request.form(max_files=1000, max_fields=1000, max_part_size=1024*1024)` You can configure the number of maximum fields or files with the parameters `max_files` and `max_fields`; and part size using `max_part_size`: ```python async with request.form(max_files=1000, max_fields=1000, max_part_size=1024*1024): ... ``` !!! info These limits are for security reasons, allowing an unlimited number of fields or files could lead to a denial of service attack by consuming a lot of CPU and memory parsing too many empty fields. When you call `async with request.form() as form` you receive a `starlette.datastructures.FormData` which is an immutable multidict, containing both file uploads and text input. File upload items are represented as instances of `starlette.datastructures.UploadFile`. `UploadFile` has the following attributes: * `filename`: An `str` with the original file name that was uploaded or `None` if its not available (e.g. `myimage.jpg`). * `content_type`: An `str` with the content type (MIME type / media type) or `None` if it's not available (e.g. `image/jpeg`). * `file`: A `SpooledTemporaryFile` (a file-like object). This is the actual Python file that you can pass directly to other functions or libraries that expect a "file-like" object. * `headers`: A `Headers` object. Often this will only be the `Content-Type` header, but if additional headers were included in the multipart field they will be included here. Note that these headers have no relationship with the headers in `Request.headers`. * `size`: An `int` with uploaded file's size in bytes. This value is calculated from request's contents, making it better choice to find uploaded file's size than `Content-Length` header. `None` if not set. `UploadFile` has the following `async` methods. They all call the corresponding file methods underneath (using the internal `SpooledTemporaryFile`). * `async write(data)`: Writes `data` (`bytes`) to the file. * `async read(size)`: Reads `size` (`int`) bytes of the file. * `async seek(offset)`: Goes to the byte position `offset` (`int`) in the file. * E.g., `await myfile.seek(0)` would go to the start of the file. * `async close()`: Closes the file. As all these methods are `async` methods, you need to "await" them. For example, you can get the file name and the contents with: ```python async with request.form() as form: filename = form["upload_file"].filename contents = await form["upload_file"].read() ``` !!! info As settled in [RFC-7578: 4.2](https://www.ietf.org/rfc/rfc7578.txt), form-data content part that contains file assumed to have `name` and `filename` fields in `Content-Disposition` header: `Content-Disposition: form-data; name="user"; filename="somefile"`. Though `filename` field is optional according to RFC-7578, it helps Starlette to differentiate which data should be treated as file. If `filename` field was supplied, `UploadFile` object will be created to access underlying file, otherwise form-data part will be parsed and available as a raw string. #### Application The originating Starlette application can be accessed via `request.app`. #### Other state If you want to store additional information on the request you can do so using `request.state`. For example: `request.state.time_started = time.time()` starlette-0.50.0/docs/responses.md000066400000000000000000000163061510142272400171020ustar00rootroot00000000000000 Starlette includes a few response classes that handle sending back the appropriate ASGI messages on the `send` channel. ### Response Signature: `Response(content, status_code=200, headers=None, media_type=None)` * `content` - A string or bytestring. * `status_code` - An integer HTTP status code. * `headers` - A dictionary of strings. * `media_type` - A string giving the media type. eg. "text/html" Starlette will automatically include a Content-Length header. It will also include a Content-Type header, based on the media_type and appending a charset for text types, unless a charset has already been specified in the `media_type`. Once you've instantiated a response, you can send it by calling it as an ASGI application instance. ```python from starlette.responses import Response async def app(scope, receive, send): assert scope['type'] == 'http' response = Response('Hello, world!', media_type='text/plain') await response(scope, receive, send) ``` #### Set Cookie Starlette provides a `set_cookie` method to allow you to set cookies on the response object. Signature: `Response.set_cookie(key, value, max_age=None, expires=None, path="/", domain=None, secure=False, httponly=False, samesite="lax", partitioned=False)` * `key` - A string that will be the cookie's key. * `value` - A string that will be the cookie's value. * `max_age` - An integer that defines the lifetime of the cookie in seconds. A negative integer or a value of `0` will discard the cookie immediately. `Optional` * `expires` - Either an integer that defines the number of seconds until the cookie expires, or a datetime. `Optional` * `path` - A string that specifies the subset of routes to which the cookie will apply. `Optional` * `domain` - A string that specifies the domain for which the cookie is valid. `Optional` * `secure` - A bool indicating that the cookie will only be sent to the server if request is made using SSL and the HTTPS protocol. `Optional` * `httponly` - A bool indicating that the cookie cannot be accessed via JavaScript through `Document.cookie` property, the `XMLHttpRequest` or `Request` APIs. `Optional` * `samesite` - A string that specifies the samesite strategy for the cookie. Valid values are `'lax'`, `'strict'` and `'none'`. Defaults to `'lax'`. `Optional` * `partitioned` - A bool that indicates to user agents that these cross-site cookies should only be available in the same top-level context that the cookie was first set in. Only available for Python 3.14+, otherwise an error will be raised. `Optional` #### Delete Cookie Conversely, Starlette also provides a `delete_cookie` method to manually expire a set cookie. Signature: `Response.delete_cookie(key, path='/', domain=None)` ### HTMLResponse Takes some text or bytes and returns an HTML response. ```python from starlette.responses import HTMLResponse async def app(scope, receive, send): assert scope['type'] == 'http' response = HTMLResponse('

    Hello, world!

    ') await response(scope, receive, send) ``` ### PlainTextResponse Takes some text or bytes and returns a plain text response. ```python from starlette.responses import PlainTextResponse async def app(scope, receive, send): assert scope['type'] == 'http' response = PlainTextResponse('Hello, world!') await response(scope, receive, send) ``` ### JSONResponse Takes some data and returns an `application/json` encoded response. ```python from starlette.responses import JSONResponse async def app(scope, receive, send): assert scope['type'] == 'http' response = JSONResponse({'hello': 'world'}) await response(scope, receive, send) ``` #### Custom JSON serialization If you need fine-grained control over JSON serialization, you can subclass `JSONResponse` and override the `render` method. For example, if you wanted to use a third-party JSON library such as [orjson](https://pypi.org/project/orjson/): ```python from typing import Any import orjson from starlette.responses import JSONResponse class OrjsonResponse(JSONResponse): def render(self, content: Any) -> bytes: return orjson.dumps(content) ``` In general you *probably* want to stick with `JSONResponse` by default unless you are micro-optimising a particular endpoint or need to serialize non-standard object types. ### RedirectResponse Returns an HTTP redirect. Uses a 307 status code by default. ```python from starlette.responses import PlainTextResponse, RedirectResponse async def app(scope, receive, send): assert scope['type'] == 'http' if scope['path'] != '/': response = RedirectResponse(url='/') else: response = PlainTextResponse('Hello, world!') await response(scope, receive, send) ``` ### StreamingResponse Takes an async generator or a normal generator/iterator and streams the response body. ```python from starlette.responses import StreamingResponse import asyncio async def slow_numbers(minimum, maximum): yield '
      ' for number in range(minimum, maximum + 1): yield '
    • %d
    • ' % number await asyncio.sleep(0.5) yield '
    ' async def app(scope, receive, send): assert scope['type'] == 'http' generator = slow_numbers(1, 10) response = StreamingResponse(generator, media_type='text/html') await response(scope, receive, send) ``` Have in mind that file-like objects (like those created by `open()`) are normal iterators. So, you can return them directly in a `StreamingResponse`. ### FileResponse Asynchronously streams a file as the response. Takes a different set of arguments to instantiate than the other response types: * `path` - The filepath to the file to stream. * `headers` - Any custom headers to include, as a dictionary. * `media_type` - A string giving the media type. If unset, the filename or path will be used to infer a media type. * `filename` - If set, this will be included in the response `Content-Disposition`. * `content_disposition_type` - will be included in the response `Content-Disposition`. Can be set to "attachment" (default) or "inline". File responses will include appropriate `Content-Length`, `Last-Modified` and `ETag` headers. ```python from starlette.responses import FileResponse async def app(scope, receive, send): assert scope['type'] == 'http' response = FileResponse('statics/favicon.ico') await response(scope, receive, send) ``` File responses also supports [HTTP range requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests). The `Accept-Ranges: bytes` header will be included in the response if the file exists. For now, only the `bytes` range unit is supported. If the request includes a `Range` header, and the file exists, the response will be a `206 Partial Content` response with the requested range of bytes. If the range is invalid, the response will be a `416 Range Not Satisfiable` response. ## Third party responses #### [EventSourceResponse](https://github.com/sysid/sse-starlette) A response class that implements [Server-Sent Events](https://html.spec.whatwg.org/multipage/server-sent-events.html). It enables event streaming from the server to the client without the complexity of websockets. starlette-0.50.0/docs/routing.md000066400000000000000000000213121510142272400165410ustar00rootroot00000000000000## HTTP Routing Starlette has a simple but capable request routing system. A routing table is defined as a list of routes, and passed when instantiating the application. ```python from starlette.applications import Starlette from starlette.responses import PlainTextResponse from starlette.routing import Route async def homepage(request): return PlainTextResponse("Homepage") async def about(request): return PlainTextResponse("About") routes = [ Route("/", endpoint=homepage), Route("/about", endpoint=about), ] app = Starlette(routes=routes) ``` The `endpoint` argument can be one of: * A regular function or async function, which accepts a single `request` argument and which should return a response. * A class that implements the ASGI interface, such as Starlette's [HTTPEndpoint](endpoints.md#httpendpoint). ## Path Parameters Paths can use URI templating style to capture path components. ```python Route('/users/{username}', user) ``` By default this will capture characters up to the end of the path or the next `/`. You can use convertors to modify what is captured. The available convertors are: * `str` returns a string, and is the default. * `int` returns a Python integer. * `float` returns a Python float. * `uuid` return a Python `uuid.UUID` instance. * `path` returns the rest of the path, including any additional `/` characters. Convertors are used by prefixing them with a colon, like so: ```python Route('/users/{user_id:int}', user) Route('/floating-point/{number:float}', floating_point) Route('/uploaded/{rest_of_path:path}', uploaded) ``` If you need a different converter that is not defined, you can create your own. See below an example on how to create a `datetime` convertor, and how to register it: ```python from datetime import datetime from starlette.convertors import Convertor, register_url_convertor class DateTimeConvertor(Convertor): regex = "[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(.[0-9]+)?" def convert(self, value: str) -> datetime: return datetime.strptime(value, "%Y-%m-%dT%H:%M:%S") def to_string(self, value: datetime) -> str: return value.strftime("%Y-%m-%dT%H:%M:%S") register_url_convertor("datetime", DateTimeConvertor()) ``` After registering it, you'll be able to use it as: ```python Route('/history/{date:datetime}', history) ``` Path parameters are made available in the request, as the `request.path_params` dictionary. ```python async def user(request): user_id = request.path_params['user_id'] ... ``` ## Handling HTTP methods Routes can also specify which HTTP methods are handled by an endpoint: ```python Route('/users/{user_id:int}', user, methods=["GET", "POST"]) ``` By default function endpoints will only accept `GET` requests, unless specified. ## Submounting routes In large applications you might find that you want to break out parts of the routing table, based on a common path prefix. ```python routes = [ Route('/', homepage), Mount('/users', routes=[ Route('/', users, methods=['GET', 'POST']), Route('/{username}', user), ]) ] ``` This style allows you to define different subsets of the routing table in different parts of your project. ```python from myproject import users, auth routes = [ Route('/', homepage), Mount('/users', routes=users.routes), Mount('/auth', routes=auth.routes), ] ``` You can also use mounting to include sub-applications within your Starlette application. For example... ```python # This is a standalone static files server: app = StaticFiles(directory="static") # This is a static files server mounted within a Starlette application, # underneath the "/static" path. routes = [ ... Mount("/static", app=StaticFiles(directory="static"), name="static") ] app = Starlette(routes=routes) ``` ## Reverse URL lookups You'll often want to be able to generate the URL for a particular route, such as in cases where you need to return a redirect response. * Signature: `url_for(name, **path_params) -> URL` ```python routes = [ Route("/", homepage, name="homepage") ] # We can use the following to return a URL... url = request.url_for("homepage") ``` URL lookups can include path parameters... ```python routes = [ Route("/users/{username}", user, name="user_detail") ] # We can use the following to return a URL... url = request.url_for("user_detail", username=...) ``` If a `Mount` includes a `name`, then submounts should use a `{prefix}:{name}` style for reverse URL lookups. ```python routes = [ Mount("/users", name="users", routes=[ Route("/", user, name="user_list"), Route("/{username}", user, name="user_detail") ]) ] # We can use the following to return URLs... url = request.url_for("users:user_list") url = request.url_for("users:user_detail", username=...) ``` Mounted applications may include a `path=...` parameter. ```python routes = [ ... Mount("/static", app=StaticFiles(directory="static"), name="static") ] # We can use the following to return URLs... url = request.url_for("static", path="/css/base.css") ``` For cases where there is no `request` instance, you can make reverse lookups against the application, although these will only return the URL path. ```python url = app.url_path_for("user_detail", username=...) ``` ## Host-based routing If you want to use different routes for the same path based on the `Host` header. Note that port is removed from the `Host` header when matching. For example, `Host (host='example.org:3600', ...)` will be processed even if the `Host` header contains or does not contain a port other than `3600` (`example.org:5600`, `example.org`). Therefore, you can specify the port if you need it for use in `url_for`. There are several ways to connect host-based routes to your application ```python site = Router() # Use eg. `@site.route()` to configure this. api = Router() # Use eg. `@api.route()` to configure this. news = Router() # Use eg. `@news.route()` to configure this. routes = [ Host('api.example.org', api, name="site_api") ] app = Starlette(routes=routes) app.host('www.example.org', site, name="main_site") news_host = Host('news.example.org', news) app.router.routes.append(news_host) ``` URL lookups can include host parameters just like path parameters ```python routes = [ Host("{subdomain}.example.org", name="sub", app=Router(routes=[ Mount("/users", name="users", routes=[ Route("/", user, name="user_list"), Route("/{username}", user, name="user_detail") ]) ])) ] ... url = request.url_for("sub:users:user_detail", username=..., subdomain=...) url = request.url_for("sub:users:user_list", subdomain=...) ``` ## Route priority Incoming paths are matched against each `Route` in order. In cases where more that one route could match an incoming path, you should take care to ensure that more specific routes are listed before general cases. For example: ```python # Don't do this: `/users/me` will never match incoming requests. routes = [ Route('/users/{username}', user), Route('/users/me', current_user), ] # Do this: `/users/me` is tested first. routes = [ Route('/users/me', current_user), Route('/users/{username}', user), ] ``` ## Working with Router instances If you're working at a low-level you might want to use a plain `Router` instance, rather that creating a `Starlette` application. This gives you a lightweight ASGI application that just provides the application routing, without wrapping it up in any middleware. ```python app = Router(routes=[ Route('/', homepage), Mount('/users', routes=[ Route('/', users, methods=['GET', 'POST']), Route('/{username}', user), ]) ]) ``` ## WebSocket Routing When working with WebSocket endpoints, you should use `WebSocketRoute` instead of the usual `Route`. Path parameters, and reverse URL lookups for `WebSocketRoute` work the the same as HTTP `Route`, which can be found in the HTTP [Route](#http-routing) section above. ```python from starlette.applications import Starlette from starlette.routing import WebSocketRoute async def websocket_index(websocket): await websocket.accept() await websocket.send_text("Hello, websocket!") await websocket.close() async def websocket_user(websocket): name = websocket.path_params["name"] await websocket.accept() await websocket.send_text(f"Hello, {name}") await websocket.close() routes = [ WebSocketRoute("/", endpoint=websocket_index), WebSocketRoute("/{name}", endpoint=websocket_user), ] app = Starlette(routes=routes) ``` The `endpoint` argument can be one of: * An async function, which accepts a single `websocket` argument. * A class that implements the ASGI interface, such as Starlette's [WebSocketEndpoint](endpoints.md#websocketendpoint). starlette-0.50.0/docs/schemas.md000066400000000000000000000057331510142272400165060ustar00rootroot00000000000000Starlette supports generating API schemas, such as the widely used [OpenAPI specification][openapi]. (Formerly known as "Swagger".) Schema generation works by inspecting the routes on the application through `app.routes`, and using the docstrings or other attributes on the endpoints in order to determine a complete API schema. Starlette is not tied to any particular schema generation or validation tooling, but includes a simple implementation that generates OpenAPI schemas based on the docstrings. ```python from starlette.applications import Starlette from starlette.routing import Route from starlette.schemas import SchemaGenerator schemas = SchemaGenerator( {"openapi": "3.0.0", "info": {"title": "Example API", "version": "1.0"}} ) def list_users(request): """ responses: 200: description: A list of users. examples: [{"username": "tom"}, {"username": "lucy"}] """ raise NotImplementedError() def create_user(request): """ responses: 200: description: A user. examples: {"username": "tom"} """ raise NotImplementedError() def openapi_schema(request): return schemas.OpenAPIResponse(request=request) routes = [ Route("/users", endpoint=list_users, methods=["GET"]), Route("/users", endpoint=create_user, methods=["POST"]), Route("/schema", endpoint=openapi_schema, include_in_schema=False) ] app = Starlette(routes=routes) ``` We can now access an OpenAPI schema at the "/schema" endpoint. You can generate the API Schema directly with `.get_schema(routes)`: ```python schema = schemas.get_schema(routes=app.routes) assert schema == { "openapi": "3.0.0", "info": {"title": "Example API", "version": "1.0"}, "paths": { "/users": { "get": { "responses": { 200: { "description": "A list of users.", "examples": [{"username": "tom"}, {"username": "lucy"}], } } }, "post": { "responses": { 200: {"description": "A user.", "examples": {"username": "tom"}} } }, }, }, } ``` You might also want to be able to print out the API schema, so that you can use tooling such as generating API documentation. ```python if __name__ == '__main__': assert sys.argv[-1] in ("run", "schema"), "Usage: example.py [run|schema]" if sys.argv[-1] == "run": uvicorn.run("example:app", host='0.0.0.0', port=8000) elif sys.argv[-1] == "schema": schema = schemas.get_schema(routes=app.routes) print(yaml.dump(schema, default_flow_style=False)) ``` ### Third party packages #### [starlette-apispec][starlette-apispec] Easy APISpec integration for Starlette, which supports some object serialization libraries. [openapi]: https://github.com/OAI/OpenAPI-Specification [starlette-apispec]: https://github.com/Woile/starlette-apispec starlette-0.50.0/docs/server-push.md000066400000000000000000000017541510142272400173450ustar00rootroot00000000000000 Starlette includes support for HTTP/2 and HTTP/3 server push, making it possible to push resources to the client to speed up page load times. ### `Request.send_push_promise` Used to initiate a server push for a resource. If server push is not available this method does nothing. Signature: `send_push_promise(path)` * `path` - A string denoting the path of the resource. ```python from starlette.applications import Starlette from starlette.responses import HTMLResponse from starlette.routing import Route, Mount from starlette.staticfiles import StaticFiles async def homepage(request): """ Homepage which uses server push to deliver the stylesheet. """ await request.send_push_promise("/static/style.css") return HTMLResponse( '' ) routes = [ Route("/", endpoint=homepage), Mount("/static", StaticFiles(directory="static"), name="static") ] app = Starlette(routes=routes) ``` starlette-0.50.0/docs/sponsorship.md000066400000000000000000000263571510142272400174570ustar00rootroot00000000000000# ✨ Sponsor Starlette & Uvicorn ✨ Thank you for your interest in sponsoring Starlette and Uvicorn! ❤️ Your support *directly* contributes to the ongoing development, maintenance, and long-term sustainability of both projects.

    67M+

    Starlette Downloads/Month

    57M+

    Uvicorn Downloads/Month

    19K+

    Combined GitHub Stars

    ## Why Sponsor? While Starlette and Uvicorn are part of the [Encode](https://github.com/encode) organization, they have been primarily maintained by [**Marcelo Trylesinski (Kludex)**](https://github.com/Kludex) for the past several years. His dedication and consistent work have been instrumental in keeping these projects robust, secure, and up-to-date. This sponsorship page was created to give the community an opportunity to support Marcelo's continued efforts in maintaining and improving both projects. Your sponsorship directly enables him to dedicate more time and resources to maintaining and improving these essential tools: - [x] **Active Development:** Developing new features, enhancing existing ones, and keeping both projects aligned with the latest developments in the Python and ASGI ecosystems. 💻 - [x] **Community Support:** Providing better support, addressing user issues, and cultivating a welcoming environment for contributors. 🤝 - [x] **Long-Term Stability:** Ensuring the long-term viability of both projects through strategic planning and addressing technical debt. 🌳 - [x] **Bug Fixes & Maintenance:** Providing prompt attention to bug reports and general maintenance to keep the projects reliable. 🔨 - [x] **Security:** Ensuring robust security practices, conducting regular security audits, and promptly addressing vulnerabilities to protect millions of production deployments. 🔒 - [x] **Documentation:** Creating comprehensive guides, tutorials, and examples to help users of all skill levels. 📖 ## How Sponsorship Works We currently manage sponsorships *exclusively* through **GitHub Sponsors**. This platform integrates seamlessly with the GitHub ecosystem, making it easy for organizations to contribute.

    🌟 Become a Sponsor Today! 🌟

    Your support helps keep Starlette and Uvicorn growing stronger!

    ❤️ Sponsor on GitHub
    ## Sponsorship Tiers 🎁

    🥉 Bronze Sponsor

    $100/month
    • ✓ Company name on Sponsors page
    • ✓ Small logo with link
    • ✓ Our eternal gratitude

    🥈 Silver Sponsor

    $250/month
    • ✓ All Bronze benefits
    • ✓ Medium-sized logo
    • ✓ Release notes mention
    Popular

    🥇 Gold Sponsor

    $500/month
    • ✓ All Silver benefits
    • ✓ Large logo on main pages
    • ✓ Priority support

    🤝 Custom Sponsor

    Looking for something different? Contact us to discuss custom sponsorship options!

    ## Current Sponsors **Thank you to our generous sponsors!** 🙏

    🥈 Silver Sponsors

    🥉 Bronze Sponsors

    ## Alternative Sponsorship Platforms

    📢 We Want Your Input!

    We are currently evaluating whether to expand our sponsorship options beyond GitHub Sponsors. If your company would be interested in sponsoring Starlette and Uvicorn but prefers to use a different platform (e.g., Open Collective, direct invoicing), please let us know!

    Your feedback is invaluable in helping us make sponsorship as accessible as possible. Share your thoughts by:

    ## Community & Future Plans 🌟 We want to express our deepest gratitude to all the contributors who have helped shape Starlette and Uvicorn over the years. These projects wouldn't be what they are today without the incredible work of every single contributor. Special thanks to some of our most impactful contributors: - **Tom Christie** ([@tomchristie](https://github.com/tomchristie)) - The original creator of Starlette and Uvicorn. - **Adrian Garcia Badaracco** ([@adriangb](https://github.com/adriangb)) - Major contributor to Starlette. - **Thomas Grainger** ([@graingert](https://github.com/graingert)) - Major contributor to AnyIO, and significant contributions to Starlette and Uvicorn. - **Alex Grönholm** ([@agronholm](https://github.com/agronholm)) - Creator of AnyIO. - **Florimond Manca** ([@florimondmanca](https://github.com/florimondmanca)) - Important contributions to Starlette and Uvicorn. If you want your name removed from the list above, or if I forgot a significant contributor, please let me know. You can view all contributors on GitHub: [Starlette Contributors](https://github.com/Kludex/starlette/graphs/contributors) / [Uvicorn Contributors](https://github.com/encode/uvicorn/graphs/contributors). While the current sponsorship program directly supports Marcelo's maintenance work, we are exploring ways to distribute funding to other key contributors in the future. This initiative is still in early planning stages, as we want to ensure a fair and sustainable model that recognizes the valuable contributions of our community members. starlette-0.50.0/docs/staticfiles.md000066400000000000000000000043101510142272400173630ustar00rootroot00000000000000 Starlette also includes a `StaticFiles` class for serving files in a given directory: ### StaticFiles Signature: `StaticFiles(directory=None, packages=None, html=False, check_dir=True, follow_symlink=False)` * `directory` - A string or [os.PathLike][pathlike] denoting a directory path. * `packages` - A list of strings or list of tuples of strings of python packages. * `html` - Run in HTML mode. Automatically loads `index.html` for directories if such file exist. * `check_dir` - Ensure that the directory exists upon instantiation. Defaults to `True`. * `follow_symlink` - A boolean indicating if symbolic links for files and directories should be followed. Defaults to `False`. You can combine this ASGI application with Starlette's routing to provide comprehensive static file serving. ```python from starlette.applications import Starlette from starlette.routing import Mount from starlette.staticfiles import StaticFiles routes = [ ... Mount('/static', app=StaticFiles(directory='static'), name="static"), ] app = Starlette(routes=routes) ``` Static files will respond with "404 Not found" or "405 Method not allowed" responses for requests which do not match. In HTML mode if `404.html` file exists it will be shown as 404 response. The `packages` option can be used to include "static" directories contained within a python package. The Python "bootstrap4" package is an example of this. ```python from starlette.applications import Starlette from starlette.routing import Mount from starlette.staticfiles import StaticFiles routes=[ ... Mount('/static', app=StaticFiles(directory='static', packages=['bootstrap4']), name="static"), ] app = Starlette(routes=routes) ``` By default `StaticFiles` will look for `statics` directory in each package, you can change the default directory by specifying a tuple of strings. ```python routes=[ ... Mount('/static', app=StaticFiles(packages=[('bootstrap4', 'static')]), name="static"), ] ``` You may prefer to include static files directly inside the "static" directory rather than using Python packaging to include static files, but it can be useful for bundling up reusable components. [pathlike]: https://docs.python.org/3/library/os.html#os.PathLike starlette-0.50.0/docs/templates.md000066400000000000000000000111651510142272400170550ustar00rootroot00000000000000Starlette is not _strictly_ coupled to any particular templating engine, but Jinja2 provides an excellent choice. ### Jinja2Templates Signature: `Jinja2Templates(directory, context_processors=None, **env_options)` * `directory` - A string, [os.Pathlike][pathlike] or a list of strings or [os.Pathlike][pathlike] denoting a directory path. * `context_processors` - A list of functions that return a dictionary to add to the template context. * `**env_options` - Additional keyword arguments to pass to the Jinja2 environment. Starlette provides a simple way to get `jinja2` configured. This is probably what you want to use by default. ```python from starlette.applications import Starlette from starlette.routing import Route, Mount from starlette.templating import Jinja2Templates from starlette.staticfiles import StaticFiles templates = Jinja2Templates(directory='templates') async def homepage(request): return templates.TemplateResponse(request, 'index.html') routes = [ Route('/', endpoint=homepage), Mount('/static', StaticFiles(directory='static'), name='static') ] app = Starlette(debug=True, routes=routes) ``` Note that the incoming `request` instance must be included as part of the template context. The Jinja2 template context will automatically include a `url_for` function, so we can correctly hyperlink to other pages within the application. For example, we can link to static files from within our HTML templates: ```html ``` If you want to use [custom filters][jinja2], you will need to update the `env` property of `Jinja2Templates`: ```python from commonmark import commonmark from starlette.templating import Jinja2Templates def marked_filter(text): return commonmark(text) templates = Jinja2Templates(directory='templates') templates.env.filters['marked'] = marked_filter ``` ## Using custom jinja2.Environment instance Starlette also accepts a preconfigured [`jinja2.Environment`](https://jinja.palletsprojects.com/en/3.0.x/api/#api) instance. ```python import jinja2 from starlette.templating import Jinja2Templates env = jinja2.Environment(...) templates = Jinja2Templates(env=env) ``` ## Context processors A context processor is a function that returns a dictionary to be merged into a template context. Every function takes only one argument `request` and must return a dictionary to add to the context. A common use case of template processors is to extend the template context with shared variables. ```python import typing from starlette.requests import Request def app_context(request: Request) -> typing.Dict[str, typing.Any]: return {'app': request.app} ``` ### Registering context templates Pass context processors to `context_processors` argument of the `Jinja2Templates` class. ```python import typing from starlette.requests import Request from starlette.templating import Jinja2Templates def app_context(request: Request) -> typing.Dict[str, typing.Any]: return {'app': request.app} templates = Jinja2Templates( directory='templates', context_processors=[app_context] ) ``` !!! info Asynchronous functions as context processors are not supported. ## Testing template responses When using the test client, template responses include `.template` and `.context` attributes. ```python from starlette.testclient import TestClient def test_homepage(): client = TestClient(app) response = client.get("/") assert response.status_code == 200 assert response.template.name == 'index.html' assert "request" in response.context ``` ## Customizing Jinja2 Environment `Jinja2Templates` accepts all options supported by Jinja2 `Environment`. This will allow more control over the `Environment` instance created by Starlette. For the list of options available to `Environment` you can check Jinja2 documentation [here](https://jinja.palletsprojects.com/en/3.0.x/api/#jinja2.Environment) ```python from starlette.templating import Jinja2Templates templates = Jinja2Templates(directory='templates', autoescape=False, auto_reload=True) ``` ## Asynchronous template rendering Jinja2 supports async template rendering, however as a general rule we'd recommend that you keep your templates free from logic that invokes database lookups, or other I/O operations. Instead we'd recommend that you ensure that your endpoints perform all I/O, for example, strictly evaluate any database queries within the view and include the final results in the context. [jinja2]: https://jinja.palletsprojects.com/en/3.0.x/api/?highlight=environment#writing-filters [pathlike]: https://docs.python.org/3/library/os.html#os.PathLike starlette-0.50.0/docs/testclient.md000066400000000000000000000170141510142272400172340ustar00rootroot00000000000000 ??? abstract "API Reference" ::: starlette.testclient.TestClient options: parameter_headings: false show_bases: false show_root_heading: true heading_level: 3 filters: - "__init__" The test client allows you to make requests against your ASGI application, using the `httpx` library. ```python from starlette.responses import HTMLResponse from starlette.testclient import TestClient async def app(scope, receive, send): assert scope['type'] == 'http' response = HTMLResponse('Hello, world!') await response(scope, receive, send) def test_app(): client = TestClient(app) response = client.get('/') assert response.status_code == 200 ``` The test client exposes the same interface as any other `httpx` session. In particular, note that the calls to make a request are just standard function calls, not awaitables. You can use any of `httpx` standard API, such as authentication, session cookies handling, or file uploads. For example, to set headers on the TestClient you can do: ```python client = TestClient(app) # Set headers on the client for future requests client.headers = {"Authorization": "..."} response = client.get("/") # Set headers for each request separately response = client.get("/", headers={"Authorization": "..."}) ``` And for example to send files with the TestClient: ```python client = TestClient(app) # Send a single file with open("example.txt", "rb") as f: response = client.post("/form", files={"file": f}) # Send multiple files with open("example.txt", "rb") as f1: with open("example.png", "rb") as f2: files = {"file1": f1, "file2": ("filename", f2, "image/png")} response = client.post("/form", files=files) ``` For more information you can check the `httpx` [documentation](https://www.python-httpx.org/advanced/). By default the `TestClient` will raise any exceptions that occur in the application. Occasionally you might want to test the content of 500 error responses, rather than allowing client to raise the server exception. In this case you should use `client = TestClient(app, raise_server_exceptions=False)`. !!! note If you want the `TestClient` to run the `lifespan` handler, you will need to use the `TestClient` as a context manager. It will not be triggered when the `TestClient` is instantiated. You can learn more about it [here](lifespan.md#running-lifespan-in-tests). ### Change client address By default, the TestClient will set the client host to `"testserver"` and the port to `50000`. You can change the client address by setting the `client` attribute of the `TestClient` instance: ```python client = TestClient(app, client=('localhost', 8000)) ``` ### Selecting the Async backend `TestClient` takes arguments `backend` (a string) and `backend_options` (a dictionary). These options are passed to `anyio.start_blocking_portal()`. See the [anyio documentation](https://anyio.readthedocs.io/en/stable/basics.html#backend-options) for more information about the accepted backend options. By default, `asyncio` is used with default options. To run `Trio`, pass `backend="trio"`. For example: ```python def test_app() with TestClient(app, backend="trio") as client: ... ``` To run `asyncio` with `uvloop`, pass `backend_options={"use_uvloop": True}`. For example: ```python def test_app() with TestClient(app, backend_options={"use_uvloop": True}) as client: ... ``` ### Testing WebSocket sessions You can also test websocket sessions with the test client. The `httpx` library will be used to build the initial handshake, meaning you can use the same authentication options and other headers between both http and websocket testing. ```python from starlette.testclient import TestClient from starlette.websockets import WebSocket async def app(scope, receive, send): assert scope['type'] == 'websocket' websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() await websocket.send_text('Hello, world!') await websocket.close() def test_app(): client = TestClient(app) with client.websocket_connect('/') as websocket: data = websocket.receive_text() assert data == 'Hello, world!' ``` The operations on session are standard function calls, not awaitables. It's important to use the session within a context-managed `with` block. This ensure that the background thread on which the ASGI application is properly terminated, and that any exceptions that occur within the application are always raised by the test client. #### Establishing a test session * `.websocket_connect(url, subprotocols=None, **options)` - Takes the same set of arguments as `httpx.get()`. May raise `starlette.websockets.WebSocketDisconnect` if the application does not accept the websocket connection. `websocket_connect()` must be used as a context manager (in a `with` block). !!! note The `params` argument is not supported by `websocket_connect`. If you need to pass query arguments, hard code it directly in the URL. ```python with client.websocket_connect('/path?foo=bar') as websocket: ... ``` #### Sending data * `.send_text(data)` - Send the given text to the application. * `.send_bytes(data)` - Send the given bytes to the application. * `.send_json(data, mode="text")` - Send the given data to the application. Use `mode="binary"` to send JSON over binary data frames. #### Receiving data * `.receive_text()` - Wait for incoming text sent by the application and return it. * `.receive_bytes()` - Wait for incoming bytestring sent by the application and return it. * `.receive_json(mode="text")` - Wait for incoming json data sent by the application and return it. Use `mode="binary"` to receive JSON over binary data frames. May raise `starlette.websockets.WebSocketDisconnect`. #### Closing the connection * `.close(code=1000)` - Perform a client-side close of the websocket connection. ### Asynchronous tests Sometimes you will want to do async things outside of your application. For example, you might want to check the state of your database after calling your app using your existing async database client/infrastructure. For these situations, using `TestClient` is difficult because it creates it's own event loop and async resources (like a database connection) often cannot be shared across event loops. The simplest way to work around this is to just make your entire test async and use an async client, like [httpx.AsyncClient]. Here is an example of such a test: ```python from httpx import AsyncClient, ASGITransport from starlette.applications import Starlette from starlette.routing import Route from starlette.requests import Request from starlette.responses import PlainTextResponse def hello(request: Request) -> PlainTextResponse: return PlainTextResponse("Hello World!") app = Starlette(routes=[Route("/", hello)]) # if you're using pytest, you'll need to to add an async marker like: # @pytest.mark.anyio # using https://github.com/agronholm/anyio # or install and configure pytest-asyncio (https://github.com/pytest-dev/pytest-asyncio) async def test_app() -> None: # note: you _must_ set `base_url` for relative urls like "/" to work transport = ASGITransport(app=app) async with AsyncClient(transport=transport, base_url="http://testserver") as client: r = await client.get("/") assert r.status_code == 200 assert r.text == "Hello World!" ``` [httpx.AsyncClient]: https://www.python-httpx.org/advanced/#calling-into-python-web-apps starlette-0.50.0/docs/third-party-packages.md000066400000000000000000000277731510142272400211160ustar00rootroot00000000000000 Starlette has a rapidly growing community of developers, building tools that integrate into Starlette, tools that depend on Starlette, etc. Here are some of those third party packages: ## Plugins ### Apitally GitHub | Documentation Analytics, request logging and monitoring for REST APIs built with Starlette (and other frameworks). ### Authlib GitHub | Documentation The ultimate Python library in building OAuth and OpenID Connect clients and servers. Check out how to integrate with [Starlette](https://docs.authlib.org/en/latest/client/starlette.html). ### ChannelBox GitHub Another solution for websocket broadcast. Send messages to channel groups from any part of your code. Checkout MySimpleChat, a simple chat application built using `channel-box` and `starlette`. ### Imia GitHub An authentication framework for Starlette with pluggable authenticators and login/logout flow. ### Mangum GitHub Serverless ASGI adapter for AWS Lambda & API Gateway. ### Nejma GitHub Manage and send messages to groups of channels using websockets. Checkout nejma-chat, a simple chat application built using `nejma` and `starlette`. ### Scout APM GitHub An APM (Application Performance Monitoring) solution that can instrument your application to find performance bottlenecks. ### SpecTree GitHub Generate OpenAPI spec document and validate request & response with Python annotations. Less boilerplate code(no need for YAML). ### Starlette APISpec GitHub Simple APISpec integration for Starlette. Document your REST API built with Starlette by declaring OpenAPI (Swagger) schemas in YAML format in your endpoint's docstrings. ### Starlette Compress GitHub Starlette-Compress is a fast and simple middleware for compressing responses in Starlette. It adds ZStd, Brotli, and GZip compression support with sensible default configuration. ### Starlette Context GitHub Middleware for Starlette that allows you to store and access the context data of a request. Can be used with logging so logs automatically use request headers such as x-request-id or x-correlation-id. ### Starlette Cramjam GitHub A Starlette middleware that allows **brotli**, **gzip** and **deflate** compression algorithm with a minimal requirements. ### Starlette OAuth2 API GitLab A starlette middleware to add authentication and authorization through JWTs. It relies solely on an auth provider to issue access and/or id tokens to clients. ### Starlette Prometheus GitHub A plugin for providing an endpoint that exposes [Prometheus](https://prometheus.io/) metrics based on its [official python client](https://github.com/prometheus/client_python). ### Starlette WTF GitHub A simple tool for integrating Starlette and WTForms. It is modeled on the excellent Flask-WTF library. ### Starlette-Login GitHub | Documentation User session management for Starlette. It handles the common tasks of logging in, logging out, and remembering your users' sessions over extended periods of time. ### Starsessions GitHub An alternate session support implementation with customizable storage backends. ### webargs-starlette GitHub Declarative request parsing and validation for Starlette, built on top of [webargs](https://github.com/marshmallow-code/webargs). Allows you to parse querystring, JSON, form, headers, and cookies using type annotations. ### DecoRouter GitHub FastAPI style routing for Starlette. Allows you to use decorators to generate routing tables. ### Starception GitHub Beautiful exception page for Starlette apps. ### Starlette-Admin GitHub | Documentation Simple and extensible admin interface framework. Built with [Tabler](https://tabler.io/) and [Datatables](https://datatables.net/), it allows you to quickly generate fully customizable admin interface for your models. You can export your data to many formats (*CSV*, *PDF*, *Excel*, etc), filter your data with complex query including `AND` and `OR` conditions, upload files, ... ### Vellox GitHub Serverless ASGI adapter for GCP Cloud Functions. ## Starlette Bridge GitHub | Documentation With the deprecation of `on_startup` and `on_shutdown`, Starlette Bridge makes sure you can still use the old ways of declaring events with a particularity that internally, in fact, creates the `lifespan` for you. This way backwards compatibility is assured for the existing packages out there while maintaining the integrity of the newly `lifespan` events of `Starlette`. ## Frameworks ### FastAPI GitHub | Documentation High performance, easy to learn, fast to code, ready for production web API framework. Inspired by **APIStar**'s previous server system with type declarations for route parameters, based on the OpenAPI specification version 3.0.0+ (with JSON Schema), powered by **Pydantic** for the data handling. ### Flama GitHub | Documentation Flama is a **data-science oriented framework** to rapidly build modern and robust **machine learning** (ML) APIs. The main aim of the framework is to make ridiculously simple the deployment of ML APIs. With Flama, data scientists can now quickly turn their ML models into asynchronous, auto-documented APIs with just a single line of code. All in just few seconds! Flama comes with an intuitive CLI, and provides an easy-to-learn philosophy to speed up the building of **highly performant** GraphQL, REST, and ML APIs. Besides, it comprises an ideal solution for the development of asynchronous and **production-ready** services, offering **automatic deployment** for ML models. ### Greppo GitHub | Documentation A Python framework for building geospatial dashboards and web-applications. Greppo is an open-source Python framework that makes it easy to build geospatial dashboards and web-applications. It provides a toolkit to quickly integrate data, algorithms, visualizations and UI for interactivity. It provides APIs to the update the variables in the backend, recompute the logic, and reflect the changes in the frontend (data mutation hook). ### Responder GitHub | Documentation Async web service framework. Some Features: flask-style route expression, yaml support, OpenAPI schema generation, background tasks, graphql. ### Starlette-apps Roll your own framework with a simple app system, like [Django-GDAPS](https://gdaps.readthedocs.io/en/latest/) or [CakePHP](https://cakephp.org/). GitHub ### Dark Star A simple framework to help minimise the code needed to get HTML to the browser. Changes your file paths into Starlette routes and puts your view code right next to your template. Includes support for [htmx](https://htmx.org) to help enhance your frontend. Docs GitHub ### Xpresso A flexible and extendable web framework built on top of Starlette, Pydantic and [di](https://github.com/adriangb/di). GitHub | Documentation ### Ellar GitHub | Documentation Ellar is an ASGI web framework for building fast, efficient and scalable RESTAPIs and server-side applications. It offers a high level of abstraction in building server-side applications and combines elements of OOP (Object Oriented Programming), and FP (Functional Programming) - Inspired by Nestjs. It is built on 3 core libraries **Starlette**, **Pydantic**, and **injector**. ### Apiman An extension to integrate Swagger/OpenAPI document easily for Starlette project and provide [SwaggerUI](http://swagger.io/swagger-ui/) and [RedocUI](https://rebilly.github.io/ReDoc/). GitHub ### Starlette-Babel Provides translations, localization, and timezone support via Babel integration. GitHub ### Starlette-StaticResources GitHub Allows mounting [package resources](https://docs.python.org/3/library/importlib.resources.html#module-importlib.resources) for static data, similar to [StaticFiles](staticfiles.md). ### Sentry GitHub | Documentation Sentry is a software error detection tool. It offers actionable insights for resolving performance issues and errors, allowing users to diagnose, fix, and optimize Python debugging. Additionally, it integrates seamlessly with Starlette for Python application development. Sentry's capabilities include error tracking, performance insights, contextual information, and alerts/notifications. ### Shiny GitHub | Documentation Leveraging Starlette and asyncio, Shiny allows developers to create effortless Python web applications using the power of reactive programming. Shiny eliminates the hassle of manual state management, automatically determining the best execution path for your app at runtime while simultaneously minimizing re-rendering. This means that Shiny can support everything from the simplest dashboard to full-featured web apps. starlette-0.50.0/docs/threadpool.md000066400000000000000000000025501510142272400172160ustar00rootroot00000000000000# Thread Pool Starlette uses a thread pool in several scenarios to avoid blocking the event loop: - When you create a synchronous endpoint using `def` instead of `async def` - When serving files with [`FileResponse`](responses.md#fileresponse) - When handling file uploads with [`UploadFile`](requests.md#request-files) - When running synchronous background tasks with [`BackgroundTask`](background.md) - And some other scenarios that may not be documented... Starlette will run your code in a thread pool to avoid blocking the event loop. This applies for endpoint functions and background tasks you create, but also for internal Starlette code. To be more precise, Starlette uses `anyio.to_thread.run_sync` to run the synchronous code. ## Concurrency Limitations The default thread pool size is only 40 _tokens_. This means that only 40 threads can run at the same time. This limit is shared with other libraries: for example FastAPI also uses `anyio` to run sync dependencies, which also uses up thread capacity. If you need to run more threads, you can increase the number of _tokens_: ```py import anyio.to_thread limiter = anyio.to_thread.current_default_thread_limiter() limiter.total_tokens = 100 ``` The above code will increase the number of _tokens_ to 100. Increasing the number of threads may have a performance and memory impact, so be careful when doing so. starlette-0.50.0/docs/websockets.md000066400000000000000000000113241510142272400172250ustar00rootroot00000000000000 Starlette includes a `WebSocket` class that fulfils a similar role to the HTTP request, but that allows sending and receiving data on a websocket. ### WebSocket Signature: `WebSocket(scope, receive=None, send=None)` ```python from starlette.websockets import WebSocket async def app(scope, receive, send): websocket = WebSocket(scope=scope, receive=receive, send=send) await websocket.accept() await websocket.send_text('Hello, world!') await websocket.close() ``` WebSockets present a mapping interface, so you can use them in the same way as a `scope`. For instance: `websocket['path']` will return the ASGI path. #### URL The websocket URL is accessed as `websocket.url`. The property is actually a subclass of `str`, and also exposes all the components that can be parsed out of the URL. For example: `websocket.url.path`, `websocket.url.port`, `websocket.url.scheme`. #### Headers Headers are exposed as an immutable, case-insensitive, multi-dict. For example: `websocket.headers['sec-websocket-version']` #### Query Parameters Query parameters are exposed as an immutable multi-dict. For example: `websocket.query_params['search']` #### Path Parameters Router path parameters are exposed as a dictionary interface. For example: `websocket.path_params['username']` ### Accepting the connection * `await websocket.accept(subprotocol=None, headers=None)` ### Sending data * `await websocket.send_text(data)` * `await websocket.send_bytes(data)` * `await websocket.send_json(data)` JSON messages default to being sent over text data frames, from version 0.10.0 onwards. Use `websocket.send_json(data, mode="binary")` to send JSON over binary data frames. ### Receiving data * `await websocket.receive_text()` * `await websocket.receive_bytes()` * `await websocket.receive_json()` May raise `starlette.websockets.WebSocketDisconnect()`. JSON messages default to being received over text data frames, from version 0.10.0 onwards. Use `websocket.receive_json(data, mode="binary")` to receive JSON over binary data frames. ### Iterating data * `websocket.iter_text()` * `websocket.iter_bytes()` * `websocket.iter_json()` Similar to `receive_text`, `receive_bytes`, and `receive_json` but returns an async iterator. ```python hl_lines="7-8" from starlette.websockets import WebSocket async def app(scope, receive, send): websocket = WebSocket(scope=scope, receive=receive, send=send) await websocket.accept() async for message in websocket.iter_text(): await websocket.send_text(f"Message text was: {message}") await websocket.close() ``` When `starlette.websockets.WebSocketDisconnect` is raised, the iterator will exit. ### Closing the connection * `await websocket.close(code=1000, reason=None)` ### Sending and receiving messages If you need to send or receive raw ASGI messages then you should use `websocket.send()` and `websocket.receive()` rather than using the raw `send` and `receive` callables. This will ensure that the websocket's state is kept correctly updated. * `await websocket.send(message)` * `await websocket.receive()` ### Send Denial Response If you call `websocket.close()` before calling `websocket.accept()` then the server will automatically send a HTTP 403 error to the client. If you want to send a different error response, you can use the `websocket.send_denial_response()` method. This will send the response and then close the connection. * `await websocket.send_denial_response(response)` This requires the ASGI server to support the WebSocket Denial Response extension. If it is not supported a `RuntimeError` will be raised. In the context of `Starlette`, you can also use the `HTTPException` to achieve the same result. ```python from starlette.applications import Starlette from starlette.exceptions import HTTPException from starlette.routing import WebSocketRoute from starlette.websockets import WebSocket def is_authorized(subprotocols: list[str]): if len(subprotocols) != 2: return False if subprotocols[0] != "Authorization": return False # Here we are hard coding the token, in a real application you would validate the token # against a database or an external service. if subprotocols[1] != "token": return False return True async def websocket_endpoint(websocket: WebSocket): subprotocols = websocket.scope["subprotocols"] if not is_authorized(subprotocols): raise HTTPException(status_code=401, detail="Unauthorized") await websocket.accept("Authorization") await websocket.send_text("Hello, world!") await websocket.close() app = Starlette(debug=True, routes=[WebSocketRoute("/ws", websocket_endpoint)]) ``` starlette-0.50.0/mkdocs.yml000066400000000000000000000061561510142272400156140ustar00rootroot00000000000000site_name: Starlette site_description: The little ASGI library that shines. site_url: https://starlette.dev repo_name: Kludex/starlette repo_url: https://github.com/Kludex/starlette edit_uri: edit/main/docs/ strict: true 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" icon: repo: fontawesome/brands/github features: - content.code.copy - toc.follow nav: - Introduction: "index.md" - Features: - Applications: "applications.md" - Requests: "requests.md" - Responses: "responses.md" - WebSockets: "websockets.md" - Routing: "routing.md" - Endpoints: "endpoints.md" - Middleware: "middleware.md" - Static Files: "staticfiles.md" - Templates: "templates.md" - Database: "database.md" - GraphQL: "graphql.md" - Authentication: "authentication.md" - API Schemas: "schemas.md" - Lifespan: "lifespan.md" - Background Tasks: "background.md" - Server Push: "server-push.md" - Exceptions: "exceptions.md" - Configuration: "config.md" - Thread Pool: "threadpool.md" - Test Client: "testclient.md" - Release Notes: "release-notes.md" - Community: - Third Party Packages: "third-party-packages.md" - Contributing: "contributing.md" - Sponsorship: "sponsorship.md" extra: analytics: provider: google property: G-Z37GTYBR6M social: - icon: fontawesome/brands/github-alt link: https://github.com/Kludex/starlette - icon: fontawesome/brands/discord link: https://discord.com/invite/RxKUF5JuHs - icon: fontawesome/brands/twitter link: https://x.com/marcelotryle - icon: fontawesome/brands/linkedin link: https://www.linkedin.com/in/marcelotryle - icon: fontawesome/solid/globe link: https://fastapiexpert.com markdown_extensions: - attr_list - admonition - pymdownx.highlight - pymdownx.superfences - pymdownx.details - pymdownx.tabbed: alternate_style: true - pymdownx.emoji: emoji_index: !!python/name:material.extensions.emoji.twemoji emoji_generator: !!python/name:material.extensions.emoji.to_svg - pymdownx.tasklist: custom_checkbox: true watch: - starlette plugins: - search - mkdocstrings: handlers: python: options: docstring_section_style: list show_root_toc_entry: false members_order: source separate_signature: true filters: ["!^_"] docstring_options: ignore_init_summary: true merge_init_into_class: true parameter_headings: true show_signature_annotations: true show_source: false signature_crossrefs: true inventories: - url: https://docs.python.org/3/objects.inv starlette-0.50.0/pyproject.toml000066400000000000000000000070171510142272400165220ustar00rootroot00000000000000[build-system] requires = ["hatchling"] build-backend = "hatchling.build" [project] name = "starlette" dynamic = ["version"] description = "The little ASGI library that shines." readme = "README.md" license = "BSD-3-Clause" license-files = ["LICENSE.md"] requires-python = ">=3.10" authors = [ { name = "Tom Christie", email = "tom@tomchristie.com" }, ] maintainers = [ { name = "Marcelo Trylesinski", email = "marcelotryle@gmail.com" }, ] classifiers = [ "Development Status :: 3 - Alpha", "Environment :: Web Environment", "Framework :: AnyIO", "Intended Audience :: Developers", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", "Topic :: Internet :: WWW/HTTP", ] dependencies = [ "anyio>=3.6.2,<5", "typing_extensions>=4.10.0; python_version < '3.13'", ] [project.optional-dependencies] full = [ "itsdangerous", "jinja2", "python-multipart>=0.0.18", "pyyaml", "httpx>=0.27.0,<0.29.0", ] [dependency-groups] dev = [ # We add starlette[full] so `uv sync` considers the extras. "starlette[full]", "coverage==7.8.2", "importlib-metadata==8.7.0", "mypy==1.16.1", "ruff==0.12.1", "types-PyYAML==6.0.12.20250516", "pytest==8.4.1", "trio==0.30.0", # Check dist "twine==6.1.0" ] docs = [ "black==25.1.0", "mkdocs==1.6.1", "mkdocs-material==9.6.15", "mkdocstrings-python==1.16.12", ] [tool.uv] default-groups = ["dev", "docs"] required-version = ">=0.8.6" [project.urls] Homepage = "https://github.com/Kludex/starlette" Documentation = "https://starlette.dev/" Changelog = "https://starlette.dev/release-notes/" Funding = "https://github.com/sponsors/Kludex" Source = "https://github.com/Kludex/starlette" [tool.hatch.version] path = "starlette/__init__.py" [tool.ruff] line-length = 120 [tool.ruff.lint] select = [ "E", # https://docs.astral.sh/ruff/rules/#error-e "F", # https://docs.astral.sh/ruff/rules/#pyflakes-f "I", # https://docs.astral.sh/ruff/rules/#isort-i "FA", # https://docs.astral.sh/ruff/rules/#flake8-future-annotations-fa "UP", # https://docs.astral.sh/ruff/rules/#pyupgrade-up "RUF100", # https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf ] ignore = ["UP031"] # https://docs.astral.sh/ruff/rules/printf-string-formatting/ [tool.ruff.lint.isort] combine-as-imports = true [tool.mypy] strict = true [[tool.mypy.overrides]] module = "starlette.testclient.*" implicit_optional = true [tool.pytest.ini_options] addopts = "-rXs --strict-config --strict-markers" xfail_strict = true filterwarnings = [ # Turn warnings that aren't filtered into exceptions "error", "ignore: run_until_first_complete is deprecated and will be removed in a future version.:DeprecationWarning", "ignore: starlette.middleware.wsgi is deprecated and will be removed in a future release.*:DeprecationWarning", "ignore: Async generator 'starlette.requests.Request.stream' was garbage collected before it had been exhausted.*:ResourceWarning", "ignore: Use 'content=<...>' to upload raw bytes/text content.:DeprecationWarning", ] [tool.coverage.run] branch = true source_pkgs = ["starlette", "tests"] [tool.coverage.report] exclude_lines = [ "pragma: no cover", "if TYPE_CHECKING:", "@overload", "raise NotImplementedError", ] starlette-0.50.0/scripts/000077500000000000000000000000001510142272400152705ustar00rootroot00000000000000starlette-0.50.0/scripts/README.md000066400000000000000000000007451510142272400165550ustar00rootroot00000000000000# Development Scripts * `scripts/install` - Install dependencies in a virtual environment. * `scripts/test` - Run the test suite. * `scripts/lint` - Run the automated code linting/formatting tools. * `scripts/check` - Run the code linting, checking that it passes. * `scripts/coverage` - Check that code coverage is complete. * `scripts/build` - Build source and wheel packages. Styled after GitHub's ["Scripts to Rule Them All"](https://github.com/github/scripts-to-rule-them-all). starlette-0.50.0/scripts/build000077500000000000000000000001151510142272400163120ustar00rootroot00000000000000#!/bin/sh -e set -x uv build uv run twine check dist/* uv run mkdocs build starlette-0.50.0/scripts/check000077500000000000000000000002761510142272400163000ustar00rootroot00000000000000#!/bin/sh -e export SOURCE_FILES="starlette tests" set -x ./scripts/sync-version uv run ruff format --check --diff $SOURCE_FILES uv run mypy $SOURCE_FILES uv run ruff check $SOURCE_FILES starlette-0.50.0/scripts/coverage000077500000000000000000000001341510142272400170070ustar00rootroot00000000000000#!/bin/sh -e set -x uv run coverage report --show-missing --skip-covered --fail-under=100 starlette-0.50.0/scripts/docs000077500000000000000000000000521510142272400161430ustar00rootroot00000000000000#!/bin/sh -e set -x uv run mkdocs serve starlette-0.50.0/scripts/install000077500000000000000000000000471510142272400166650ustar00rootroot00000000000000#!/bin/sh -e set -x uv sync --frozen starlette-0.50.0/scripts/lint000077500000000000000000000002041510142272400161600ustar00rootroot00000000000000#!/bin/sh -e export SOURCE_FILES="starlette tests" set -x uv run ruff format $SOURCE_FILES uv run ruff check --fix $SOURCE_FILES starlette-0.50.0/scripts/sync-version000077500000000000000000000006301510142272400176540ustar00rootroot00000000000000#!/bin/sh -e SEMVER_REGEX="([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+)?" CHANGELOG_VERSION=$(grep -o -E $SEMVER_REGEX docs/release-notes.md | head -1) VERSION=$(grep -o -E $SEMVER_REGEX starlette/__init__.py | head -1) if [ "$CHANGELOG_VERSION" != "$VERSION" ]; then echo "Version in changelog does not match version in starlette/__init__.py!" exit 1 fi starlette-0.50.0/scripts/test000077500000000000000000000002441510142272400161750ustar00rootroot00000000000000#!/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 starlette-0.50.0/starlette/000077500000000000000000000000001510142272400156105ustar00rootroot00000000000000starlette-0.50.0/starlette/__init__.py000066400000000000000000000000271510142272400177200ustar00rootroot00000000000000__version__ = "0.50.0" starlette-0.50.0/starlette/_exception_handler.py000066400000000000000000000042351510142272400220200ustar00rootroot00000000000000from __future__ import annotations from typing import Any from starlette._utils import is_async_callable from starlette.concurrency import run_in_threadpool from starlette.exceptions import HTTPException from starlette.requests import Request from starlette.types import ASGIApp, ExceptionHandler, Message, Receive, Scope, Send from starlette.websockets import WebSocket ExceptionHandlers = dict[Any, ExceptionHandler] StatusHandlers = dict[int, ExceptionHandler] def _lookup_exception_handler(exc_handlers: ExceptionHandlers, exc: Exception) -> ExceptionHandler | None: for cls in type(exc).__mro__: if cls in exc_handlers: return exc_handlers[cls] return None def wrap_app_handling_exceptions(app: ASGIApp, conn: Request | WebSocket) -> ASGIApp: exception_handlers: ExceptionHandlers status_handlers: StatusHandlers try: exception_handlers, status_handlers = conn.scope["starlette.exception_handlers"] except KeyError: exception_handlers, status_handlers = {}, {} async def wrapped_app(scope: Scope, receive: Receive, send: Send) -> None: response_started = False async def sender(message: Message) -> None: nonlocal response_started if message["type"] == "http.response.start": response_started = True await send(message) try: await app(scope, receive, sender) except Exception as exc: handler = None if isinstance(exc, HTTPException): handler = status_handlers.get(exc.status_code) if handler is None: handler = _lookup_exception_handler(exception_handlers, exc) if handler is None: raise exc if response_started: raise RuntimeError("Caught handled exception, but response already started.") from exc if is_async_callable(handler): response = await handler(conn, exc) else: response = await run_in_threadpool(handler, conn, exc) if response is not None: await response(scope, receive, sender) return wrapped_app starlette-0.50.0/starlette/_utils.py000066400000000000000000000053661510142272400174730ustar00rootroot00000000000000from __future__ import annotations import functools import sys from collections.abc import Awaitable, Callable, Generator from contextlib import AbstractAsyncContextManager, contextmanager from typing import Any, Generic, Protocol, TypeVar, overload from starlette.types import Scope if sys.version_info >= (3, 13): # pragma: no cover from inspect import iscoroutinefunction from typing import TypeIs else: # pragma: no cover from asyncio import iscoroutinefunction from typing_extensions import TypeIs has_exceptiongroups = True if sys.version_info < (3, 11): # pragma: no cover try: from exceptiongroup import BaseExceptionGroup # type: ignore[unused-ignore,import-not-found] except ImportError: has_exceptiongroups = False T = TypeVar("T") AwaitableCallable = Callable[..., Awaitable[T]] @overload def is_async_callable(obj: AwaitableCallable[T]) -> TypeIs[AwaitableCallable[T]]: ... @overload def is_async_callable(obj: Any) -> TypeIs[AwaitableCallable[Any]]: ... def is_async_callable(obj: Any) -> Any: while isinstance(obj, functools.partial): obj = obj.func return iscoroutinefunction(obj) or (callable(obj) and iscoroutinefunction(obj.__call__)) T_co = TypeVar("T_co", covariant=True) class AwaitableOrContextManager(Awaitable[T_co], AbstractAsyncContextManager[T_co], Protocol[T_co]): ... class SupportsAsyncClose(Protocol): async def close(self) -> None: ... # pragma: no cover SupportsAsyncCloseType = TypeVar("SupportsAsyncCloseType", bound=SupportsAsyncClose, covariant=False) class AwaitableOrContextManagerWrapper(Generic[SupportsAsyncCloseType]): __slots__ = ("aw", "entered") def __init__(self, aw: Awaitable[SupportsAsyncCloseType]) -> None: self.aw = aw def __await__(self) -> Generator[Any, None, SupportsAsyncCloseType]: return self.aw.__await__() async def __aenter__(self) -> SupportsAsyncCloseType: self.entered = await self.aw return self.entered async def __aexit__(self, *args: Any) -> None | bool: await self.entered.close() return None @contextmanager def collapse_excgroups() -> Generator[None, None, None]: try: yield except BaseException as exc: if has_exceptiongroups: # pragma: no cover while isinstance(exc, BaseExceptionGroup) and len(exc.exceptions) == 1: exc = exc.exceptions[0] raise exc def get_route_path(scope: Scope) -> str: path: str = scope["path"] root_path = scope.get("root_path", "") if not root_path: return path if not path.startswith(root_path): return path if path == root_path: return "" if path[len(root_path)] == "/": return path[len(root_path) :] return path starlette-0.50.0/starlette/applications.py000066400000000000000000000241531510142272400206550ustar00rootroot00000000000000from __future__ import annotations import warnings from collections.abc import Awaitable, Callable, Mapping, Sequence from typing import Any, ParamSpec, TypeVar from starlette.datastructures import State, URLPath from starlette.middleware import Middleware, _MiddlewareFactory from starlette.middleware.base import BaseHTTPMiddleware from starlette.middleware.errors import ServerErrorMiddleware from starlette.middleware.exceptions import ExceptionMiddleware from starlette.requests import Request from starlette.responses import Response from starlette.routing import BaseRoute, Router from starlette.types import ASGIApp, ExceptionHandler, Lifespan, Receive, Scope, Send from starlette.websockets import WebSocket AppType = TypeVar("AppType", bound="Starlette") P = ParamSpec("P") class Starlette: """Creates an Starlette application.""" def __init__( self: AppType, debug: bool = False, routes: Sequence[BaseRoute] | None = None, middleware: Sequence[Middleware] | None = None, exception_handlers: Mapping[Any, ExceptionHandler] | None = None, on_startup: Sequence[Callable[[], Any]] | None = None, on_shutdown: Sequence[Callable[[], Any]] | None = None, lifespan: Lifespan[AppType] | None = None, ) -> None: """Initializes the application. Parameters: debug: Boolean indicating if debug tracebacks should be returned on errors. routes: A list of routes to serve incoming HTTP and WebSocket requests. middleware: A list of middleware to run for every request. A starlette application will always automatically include two middleware classes. `ServerErrorMiddleware` is added as the very outermost middleware, to handle any uncaught errors occurring anywhere in the entire stack. `ExceptionMiddleware` is added as the very innermost middleware, to deal with handled exception cases occurring in the routing or endpoints. exception_handlers: A mapping of either integer status codes, or exception class types onto callables which handle the exceptions. Exception handler callables should be of the form `handler(request, exc) -> response` and may be either standard functions, or async functions. on_startup: A list of callables to run on application startup. Startup handler callables do not take any arguments, and may be either standard functions, or async functions. on_shutdown: A list of callables to run on application shutdown. Shutdown handler callables do not take any arguments, and may be either standard functions, or async functions. lifespan: A lifespan context function, which can be used to perform startup and shutdown tasks. This is a newer style that replaces the `on_startup` and `on_shutdown` handlers. Use one or the other, not both. """ # The lifespan context function is a newer style that replaces # on_startup / on_shutdown handlers. Use one or the other, not both. assert lifespan is None or (on_startup is None and on_shutdown is None), ( "Use either 'lifespan' or 'on_startup'/'on_shutdown', not both." ) self.debug = debug self.state = State() self.router = Router(routes, on_startup=on_startup, on_shutdown=on_shutdown, lifespan=lifespan) self.exception_handlers = {} if exception_handlers is None else dict(exception_handlers) self.user_middleware = [] if middleware is None else list(middleware) self.middleware_stack: ASGIApp | None = None def build_middleware_stack(self) -> ASGIApp: debug = self.debug error_handler = None exception_handlers: dict[Any, ExceptionHandler] = {} for key, value in self.exception_handlers.items(): if key in (500, Exception): error_handler = value else: exception_handlers[key] = value middleware = ( [Middleware(ServerErrorMiddleware, handler=error_handler, debug=debug)] + self.user_middleware + [Middleware(ExceptionMiddleware, handlers=exception_handlers, debug=debug)] ) app = self.router for cls, args, kwargs in reversed(middleware): app = cls(app, *args, **kwargs) return app @property def routes(self) -> list[BaseRoute]: return self.router.routes def url_path_for(self, name: str, /, **path_params: Any) -> URLPath: return self.router.url_path_for(name, **path_params) async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: scope["app"] = self if self.middleware_stack is None: self.middleware_stack = self.build_middleware_stack() await self.middleware_stack(scope, receive, send) def on_event(self, event_type: str) -> Callable: # type: ignore[type-arg] return self.router.on_event(event_type) # pragma: no cover def mount(self, path: str, app: ASGIApp, name: str | None = None) -> None: self.router.mount(path, app=app, name=name) # pragma: no cover def host(self, host: str, app: ASGIApp, name: str | None = None) -> None: self.router.host(host, app=app, name=name) # pragma: no cover def add_middleware( self, middleware_class: _MiddlewareFactory[P], *args: P.args, **kwargs: P.kwargs, ) -> None: if self.middleware_stack is not None: # pragma: no cover raise RuntimeError("Cannot add middleware after an application has started") self.user_middleware.insert(0, Middleware(middleware_class, *args, **kwargs)) def add_exception_handler( self, exc_class_or_status_code: int | type[Exception], handler: ExceptionHandler, ) -> None: # pragma: no cover self.exception_handlers[exc_class_or_status_code] = handler def add_event_handler( self, event_type: str, func: Callable, # type: ignore[type-arg] ) -> None: # pragma: no cover self.router.add_event_handler(event_type, func) def add_route( self, path: str, route: Callable[[Request], Awaitable[Response] | Response], methods: list[str] | None = None, name: str | None = None, include_in_schema: bool = True, ) -> None: # pragma: no cover self.router.add_route(path, route, methods=methods, name=name, include_in_schema=include_in_schema) def add_websocket_route( self, path: str, route: Callable[[WebSocket], Awaitable[None]], name: str | None = None, ) -> None: # pragma: no cover self.router.add_websocket_route(path, route, name=name) def exception_handler(self, exc_class_or_status_code: int | type[Exception]) -> Callable: # type: ignore[type-arg] warnings.warn( "The `exception_handler` decorator is deprecated, and will be removed in version 1.0.0. " "Refer to https://starlette.dev/exceptions/ for the recommended approach.", DeprecationWarning, ) def decorator(func: Callable) -> Callable: # type: ignore[type-arg] self.add_exception_handler(exc_class_or_status_code, func) return func return decorator def route( self, path: str, methods: list[str] | None = None, name: str | None = None, include_in_schema: bool = True, ) -> Callable: # type: ignore[type-arg] """ We no longer document this decorator style API, and its usage is discouraged. Instead you should use the following approach: >>> routes = [Route(path, endpoint=...), ...] >>> app = Starlette(routes=routes) """ warnings.warn( "The `route` decorator is deprecated, and will be removed in version 1.0.0. " "Refer to https://starlette.dev/routing/ for the recommended approach.", DeprecationWarning, ) def decorator(func: Callable) -> Callable: # type: ignore[type-arg] self.router.add_route( path, func, methods=methods, name=name, include_in_schema=include_in_schema, ) return func return decorator def websocket_route(self, path: str, name: str | None = None) -> Callable: # type: ignore[type-arg] """ We no longer document this decorator style API, and its usage is discouraged. Instead you should use the following approach: >>> routes = [WebSocketRoute(path, endpoint=...), ...] >>> app = Starlette(routes=routes) """ warnings.warn( "The `websocket_route` decorator is deprecated, and will be removed in version 1.0.0. " "Refer to https://starlette.dev/routing/#websocket-routing for the recommended approach.", DeprecationWarning, ) def decorator(func: Callable) -> Callable: # type: ignore[type-arg] self.router.add_websocket_route(path, func, name=name) return func return decorator def middleware(self, middleware_type: str) -> Callable: # type: ignore[type-arg] """ We no longer document this decorator style API, and its usage is discouraged. Instead you should use the following approach: >>> middleware = [Middleware(...), ...] >>> app = Starlette(middleware=middleware) """ warnings.warn( "The `middleware` decorator is deprecated, and will be removed in version 1.0.0. " "Refer to https://starlette.dev/middleware/#using-middleware for recommended approach.", DeprecationWarning, ) assert middleware_type == "http", 'Currently only middleware("http") is supported.' def decorator(func: Callable) -> Callable: # type: ignore[type-arg] self.add_middleware(BaseHTTPMiddleware, dispatch=func) return func return decorator starlette-0.50.0/starlette/authentication.py000066400000000000000000000112161510142272400212020ustar00rootroot00000000000000from __future__ import annotations import functools import inspect from collections.abc import Callable, Sequence from typing import Any, ParamSpec from urllib.parse import urlencode from starlette._utils import is_async_callable from starlette.exceptions import HTTPException from starlette.requests import HTTPConnection, Request from starlette.responses import RedirectResponse from starlette.websockets import WebSocket _P = ParamSpec("_P") def has_required_scope(conn: HTTPConnection, scopes: Sequence[str]) -> bool: for scope in scopes: if scope not in conn.auth.scopes: return False return True def requires( scopes: str | Sequence[str], status_code: int = 403, redirect: str | None = None, ) -> Callable[[Callable[_P, Any]], Callable[_P, Any]]: scopes_list = [scopes] if isinstance(scopes, str) else list(scopes) def decorator( func: Callable[_P, Any], ) -> Callable[_P, Any]: sig = inspect.signature(func) for idx, parameter in enumerate(sig.parameters.values()): if parameter.name == "request" or parameter.name == "websocket": type_ = parameter.name break else: raise Exception(f'No "request" or "websocket" argument on function "{func}"') if type_ == "websocket": # Handle websocket functions. (Always async) @functools.wraps(func) async def websocket_wrapper(*args: _P.args, **kwargs: _P.kwargs) -> None: websocket = kwargs.get("websocket", args[idx] if idx < len(args) else None) assert isinstance(websocket, WebSocket) if not has_required_scope(websocket, scopes_list): await websocket.close() else: await func(*args, **kwargs) return websocket_wrapper elif is_async_callable(func): # Handle async request/response functions. @functools.wraps(func) async def async_wrapper(*args: _P.args, **kwargs: _P.kwargs) -> Any: request = kwargs.get("request", args[idx] if idx < len(args) else None) assert isinstance(request, Request) if not has_required_scope(request, scopes_list): if redirect is not None: orig_request_qparam = urlencode({"next": str(request.url)}) next_url = f"{request.url_for(redirect)}?{orig_request_qparam}" return RedirectResponse(url=next_url, status_code=303) raise HTTPException(status_code=status_code) return await func(*args, **kwargs) return async_wrapper else: # Handle sync request/response functions. @functools.wraps(func) def sync_wrapper(*args: _P.args, **kwargs: _P.kwargs) -> Any: request = kwargs.get("request", args[idx] if idx < len(args) else None) assert isinstance(request, Request) if not has_required_scope(request, scopes_list): if redirect is not None: orig_request_qparam = urlencode({"next": str(request.url)}) next_url = f"{request.url_for(redirect)}?{orig_request_qparam}" return RedirectResponse(url=next_url, status_code=303) raise HTTPException(status_code=status_code) return func(*args, **kwargs) return sync_wrapper return decorator class AuthenticationError(Exception): pass class AuthenticationBackend: async def authenticate(self, conn: HTTPConnection) -> tuple[AuthCredentials, BaseUser] | None: raise NotImplementedError() # pragma: no cover class AuthCredentials: def __init__(self, scopes: Sequence[str] | None = None): self.scopes = [] if scopes is None else list(scopes) class BaseUser: @property def is_authenticated(self) -> bool: raise NotImplementedError() # pragma: no cover @property def display_name(self) -> str: raise NotImplementedError() # pragma: no cover @property def identity(self) -> str: raise NotImplementedError() # pragma: no cover class SimpleUser(BaseUser): def __init__(self, username: str) -> None: self.username = username @property def is_authenticated(self) -> bool: return True @property def display_name(self) -> str: return self.username class UnauthenticatedUser(BaseUser): @property def is_authenticated(self) -> bool: return False @property def display_name(self) -> str: return "" starlette-0.50.0/starlette/background.py000066400000000000000000000021421510142272400203000ustar00rootroot00000000000000from __future__ import annotations from collections.abc import Callable, Sequence from typing import Any, ParamSpec from starlette._utils import is_async_callable from starlette.concurrency import run_in_threadpool P = ParamSpec("P") class BackgroundTask: def __init__(self, func: Callable[P, Any], *args: P.args, **kwargs: P.kwargs) -> None: self.func = func self.args = args self.kwargs = kwargs self.is_async = is_async_callable(func) async def __call__(self) -> None: if self.is_async: await self.func(*self.args, **self.kwargs) else: await run_in_threadpool(self.func, *self.args, **self.kwargs) class BackgroundTasks(BackgroundTask): def __init__(self, tasks: Sequence[BackgroundTask] | None = None): self.tasks = list(tasks) if tasks else [] def add_task(self, func: Callable[P, Any], *args: P.args, **kwargs: P.kwargs) -> None: task = BackgroundTask(func, *args, **kwargs) self.tasks.append(task) async def __call__(self) -> None: for task in self.tasks: await task() starlette-0.50.0/starlette/concurrency.py000066400000000000000000000031361510142272400205170ustar00rootroot00000000000000from __future__ import annotations import functools import warnings from collections.abc import AsyncIterator, Callable, Coroutine, Iterable, Iterator from typing import ParamSpec, TypeVar import anyio.to_thread P = ParamSpec("P") T = TypeVar("T") async def run_until_first_complete(*args: tuple[Callable, dict]) -> None: # type: ignore[type-arg] warnings.warn( "run_until_first_complete is deprecated and will be removed in a future version.", DeprecationWarning, ) async with anyio.create_task_group() as task_group: async def run(func: Callable[[], Coroutine]) -> None: # type: ignore[type-arg] await func() task_group.cancel_scope.cancel() for func, kwargs in args: task_group.start_soon(run, functools.partial(func, **kwargs)) async def run_in_threadpool(func: Callable[P, T], *args: P.args, **kwargs: P.kwargs) -> T: func = functools.partial(func, *args, **kwargs) return await anyio.to_thread.run_sync(func) class _StopIteration(Exception): pass def _next(iterator: Iterator[T]) -> T: # We can't raise `StopIteration` from within the threadpool iterator # and catch it outside that context, so we coerce them into a different # exception type. try: return next(iterator) except StopIteration: raise _StopIteration async def iterate_in_threadpool( iterator: Iterable[T], ) -> AsyncIterator[T]: as_iterator = iter(iterator) while True: try: yield await anyio.to_thread.run_sync(_next, as_iterator) except _StopIteration: break starlette-0.50.0/starlette/config.py000066400000000000000000000105121510142272400174260ustar00rootroot00000000000000from __future__ import annotations import os import warnings from collections.abc import Callable, Iterator, Mapping, MutableMapping from pathlib import Path from typing import Any, TypeVar, overload class undefined: pass class EnvironError(Exception): pass class Environ(MutableMapping[str, str]): def __init__(self, environ: MutableMapping[str, str] = os.environ): self._environ = environ self._has_been_read: set[str] = set() def __getitem__(self, key: str) -> str: self._has_been_read.add(key) return self._environ.__getitem__(key) def __setitem__(self, key: str, value: str) -> None: if key in self._has_been_read: raise EnvironError(f"Attempting to set environ['{key}'], but the value has already been read.") self._environ.__setitem__(key, value) def __delitem__(self, key: str) -> None: if key in self._has_been_read: raise EnvironError(f"Attempting to delete environ['{key}'], but the value has already been read.") self._environ.__delitem__(key) def __iter__(self) -> Iterator[str]: return iter(self._environ) def __len__(self) -> int: return len(self._environ) environ = Environ() T = TypeVar("T") class Config: def __init__( self, env_file: str | Path | None = None, environ: Mapping[str, str] = environ, env_prefix: str = "", encoding: str = "utf-8", ) -> None: self.environ = environ self.env_prefix = env_prefix self.file_values: dict[str, str] = {} if env_file is not None: if not os.path.isfile(env_file): warnings.warn(f"Config file '{env_file}' not found.") else: self.file_values = self._read_file(env_file, encoding) @overload def __call__(self, key: str, *, default: None) -> str | None: ... @overload def __call__(self, key: str, cast: type[T], default: T = ...) -> T: ... @overload def __call__(self, key: str, cast: type[str] = ..., default: str = ...) -> str: ... @overload def __call__( self, key: str, cast: Callable[[Any], T] = ..., default: Any = ..., ) -> T: ... @overload def __call__(self, key: str, cast: type[str] = ..., default: T = ...) -> T | str: ... def __call__( self, key: str, cast: Callable[[Any], Any] | None = None, default: Any = undefined, ) -> Any: return self.get(key, cast, default) def get( self, key: str, cast: Callable[[Any], Any] | None = None, default: Any = undefined, ) -> Any: key = self.env_prefix + key if key in self.environ: value = self.environ[key] return self._perform_cast(key, value, cast) if key in self.file_values: value = self.file_values[key] return self._perform_cast(key, value, cast) if default is not undefined: return self._perform_cast(key, default, cast) raise KeyError(f"Config '{key}' is missing, and has no default.") def _read_file(self, file_name: str | Path, encoding: str) -> dict[str, str]: file_values: dict[str, str] = {} with open(file_name, encoding=encoding) as input_file: for line in input_file.readlines(): line = line.strip() if "=" in line and not line.startswith("#"): key, value = line.split("=", 1) key = key.strip() value = value.strip().strip("\"'") file_values[key] = value return file_values def _perform_cast( self, key: str, value: Any, cast: Callable[[Any], Any] | None = None, ) -> Any: if cast is None or value is None: return value elif cast is bool and isinstance(value, str): mapping = {"true": True, "1": True, "false": False, "0": False} value = value.lower() if value not in mapping: raise ValueError(f"Config '{key}' has value '{value}'. Not a valid bool.") return mapping[value] try: return cast(value) except (TypeError, ValueError): raise ValueError(f"Config '{key}' has value '{value}'. Not a valid {cast.__name__}.") starlette-0.50.0/starlette/convertors.py000066400000000000000000000044001510142272400203640ustar00rootroot00000000000000from __future__ import annotations import math import uuid from typing import Any, ClassVar, Generic, TypeVar T = TypeVar("T") class Convertor(Generic[T]): regex: ClassVar[str] = "" def convert(self, value: str) -> T: raise NotImplementedError() # pragma: no cover def to_string(self, value: T) -> str: raise NotImplementedError() # pragma: no cover class StringConvertor(Convertor[str]): regex = "[^/]+" def convert(self, value: str) -> str: return value def to_string(self, value: str) -> str: value = str(value) assert "/" not in value, "May not contain path separators" assert value, "Must not be empty" return value class PathConvertor(Convertor[str]): regex = ".*" def convert(self, value: str) -> str: return str(value) def to_string(self, value: str) -> str: return str(value) class IntegerConvertor(Convertor[int]): regex = "[0-9]+" def convert(self, value: str) -> int: return int(value) def to_string(self, value: int) -> str: value = int(value) assert value >= 0, "Negative integers are not supported" return str(value) class FloatConvertor(Convertor[float]): regex = r"[0-9]+(\.[0-9]+)?" def convert(self, value: str) -> float: return float(value) def to_string(self, value: float) -> str: value = float(value) assert value >= 0.0, "Negative floats are not supported" assert not math.isnan(value), "NaN values are not supported" assert not math.isinf(value), "Infinite values are not supported" return ("%0.20f" % value).rstrip("0").rstrip(".") class UUIDConvertor(Convertor[uuid.UUID]): regex = "[0-9a-fA-F]{8}-?[0-9a-fA-F]{4}-?[0-9a-fA-F]{4}-?[0-9a-fA-F]{4}-?[0-9a-fA-F]{12}" def convert(self, value: str) -> uuid.UUID: return uuid.UUID(value) def to_string(self, value: uuid.UUID) -> str: return str(value) CONVERTOR_TYPES: dict[str, Convertor[Any]] = { "str": StringConvertor(), "path": PathConvertor(), "int": IntegerConvertor(), "float": FloatConvertor(), "uuid": UUIDConvertor(), } def register_url_convertor(key: str, convertor: Convertor[Any]) -> None: CONVERTOR_TYPES[key] = convertor starlette-0.50.0/starlette/datastructures.py000066400000000000000000000536601510142272400212510ustar00rootroot00000000000000from __future__ import annotations from collections.abc import ItemsView, Iterable, Iterator, KeysView, Mapping, MutableMapping, Sequence, ValuesView from shlex import shlex from typing import ( Any, BinaryIO, NamedTuple, TypeVar, cast, ) from urllib.parse import SplitResult, parse_qsl, urlencode, urlsplit from starlette.concurrency import run_in_threadpool from starlette.types import Scope class Address(NamedTuple): host: str port: int _KeyType = TypeVar("_KeyType") # Mapping keys are invariant but their values are covariant since # you can only read them # that is, you can't do `Mapping[str, Animal]()["fido"] = Dog()` _CovariantValueType = TypeVar("_CovariantValueType", covariant=True) class URL: def __init__( self, url: str = "", scope: Scope | None = None, **components: Any, ) -> None: if scope is not None: assert not url, 'Cannot set both "url" and "scope".' assert not components, 'Cannot set both "scope" and "**components".' scheme = scope.get("scheme", "http") server = scope.get("server", None) path = scope["path"] query_string = scope.get("query_string", b"") host_header = None for key, value in scope["headers"]: if key == b"host": host_header = value.decode("latin-1") break if host_header is not None: url = f"{scheme}://{host_header}{path}" elif server is None: url = path else: host, port = server default_port = {"http": 80, "https": 443, "ws": 80, "wss": 443}[scheme] if port == default_port: url = f"{scheme}://{host}{path}" else: url = f"{scheme}://{host}:{port}{path}" if query_string: url += "?" + query_string.decode() elif components: assert not url, 'Cannot set both "url" and "**components".' url = URL("").replace(**components).components.geturl() self._url = url @property def components(self) -> SplitResult: if not hasattr(self, "_components"): self._components = urlsplit(self._url) return self._components @property def scheme(self) -> str: return self.components.scheme @property def netloc(self) -> str: return self.components.netloc @property def path(self) -> str: return self.components.path @property def query(self) -> str: return self.components.query @property def fragment(self) -> str: return self.components.fragment @property def username(self) -> None | str: return self.components.username @property def password(self) -> None | str: return self.components.password @property def hostname(self) -> None | str: return self.components.hostname @property def port(self) -> int | None: return self.components.port @property def is_secure(self) -> bool: return self.scheme in ("https", "wss") def replace(self, **kwargs: Any) -> URL: if "username" in kwargs or "password" in kwargs or "hostname" in kwargs or "port" in kwargs: hostname = kwargs.pop("hostname", None) port = kwargs.pop("port", self.port) username = kwargs.pop("username", self.username) password = kwargs.pop("password", self.password) if hostname is None: netloc = self.netloc _, _, hostname = netloc.rpartition("@") if hostname[-1] != "]": hostname = hostname.rsplit(":", 1)[0] netloc = hostname if port is not None: netloc += f":{port}" if username is not None: userpass = username if password is not None: userpass += f":{password}" netloc = f"{userpass}@{netloc}" kwargs["netloc"] = netloc components = self.components._replace(**kwargs) return self.__class__(components.geturl()) def include_query_params(self, **kwargs: Any) -> URL: params = MultiDict(parse_qsl(self.query, keep_blank_values=True)) params.update({str(key): str(value) for key, value in kwargs.items()}) query = urlencode(params.multi_items()) return self.replace(query=query) def replace_query_params(self, **kwargs: Any) -> URL: query = urlencode([(str(key), str(value)) for key, value in kwargs.items()]) return self.replace(query=query) def remove_query_params(self, keys: str | Sequence[str]) -> URL: if isinstance(keys, str): keys = [keys] params = MultiDict(parse_qsl(self.query, keep_blank_values=True)) for key in keys: params.pop(key, None) query = urlencode(params.multi_items()) return self.replace(query=query) def __eq__(self, other: Any) -> bool: return str(self) == str(other) def __str__(self) -> str: return self._url def __repr__(self) -> str: url = str(self) if self.password: url = str(self.replace(password="********")) return f"{self.__class__.__name__}({repr(url)})" class URLPath(str): """ A URL path string that may also hold an associated protocol and/or host. Used by the routing to return `url_path_for` matches. """ def __new__(cls, path: str, protocol: str = "", host: str = "") -> URLPath: assert protocol in ("http", "websocket", "") return str.__new__(cls, path) def __init__(self, path: str, protocol: str = "", host: str = "") -> None: self.protocol = protocol self.host = host def make_absolute_url(self, base_url: str | URL) -> URL: if isinstance(base_url, str): base_url = URL(base_url) if self.protocol: scheme = { "http": {True: "https", False: "http"}, "websocket": {True: "wss", False: "ws"}, }[self.protocol][base_url.is_secure] else: scheme = base_url.scheme netloc = self.host or base_url.netloc path = base_url.path.rstrip("/") + str(self) return URL(scheme=scheme, netloc=netloc, path=path) class Secret: """ Holds a string value that should not be revealed in tracebacks etc. You should cast the value to `str` at the point it is required. """ def __init__(self, value: str): self._value = value def __repr__(self) -> str: class_name = self.__class__.__name__ return f"{class_name}('**********')" def __str__(self) -> str: return self._value def __bool__(self) -> bool: return bool(self._value) class CommaSeparatedStrings(Sequence[str]): def __init__(self, value: str | Sequence[str]): if isinstance(value, str): splitter = shlex(value, posix=True) splitter.whitespace = "," splitter.whitespace_split = True self._items = [item.strip() for item in splitter] else: self._items = list(value) def __len__(self) -> int: return len(self._items) def __getitem__(self, index: int | slice) -> Any: return self._items[index] def __iter__(self) -> Iterator[str]: return iter(self._items) def __repr__(self) -> str: class_name = self.__class__.__name__ items = [item for item in self] return f"{class_name}({items!r})" def __str__(self) -> str: return ", ".join(repr(item) for item in self) class ImmutableMultiDict(Mapping[_KeyType, _CovariantValueType]): _dict: dict[_KeyType, _CovariantValueType] def __init__( self, *args: ImmutableMultiDict[_KeyType, _CovariantValueType] | Mapping[_KeyType, _CovariantValueType] | Iterable[tuple[_KeyType, _CovariantValueType]], **kwargs: Any, ) -> None: assert len(args) < 2, "Too many arguments." value: Any = args[0] if args else [] if kwargs: value = ImmutableMultiDict(value).multi_items() + ImmutableMultiDict(kwargs).multi_items() if not value: _items: list[tuple[Any, Any]] = [] elif hasattr(value, "multi_items"): value = cast(ImmutableMultiDict[_KeyType, _CovariantValueType], value) _items = list(value.multi_items()) elif hasattr(value, "items"): value = cast(Mapping[_KeyType, _CovariantValueType], value) _items = list(value.items()) else: value = cast("list[tuple[Any, Any]]", value) _items = list(value) self._dict = {k: v for k, v in _items} self._list = _items def getlist(self, key: Any) -> list[_CovariantValueType]: return [item_value for item_key, item_value in self._list if item_key == key] def keys(self) -> KeysView[_KeyType]: return self._dict.keys() def values(self) -> ValuesView[_CovariantValueType]: return self._dict.values() def items(self) -> ItemsView[_KeyType, _CovariantValueType]: return self._dict.items() def multi_items(self) -> list[tuple[_KeyType, _CovariantValueType]]: return list(self._list) def __getitem__(self, key: _KeyType) -> _CovariantValueType: return self._dict[key] def __contains__(self, key: Any) -> bool: return key in self._dict def __iter__(self) -> Iterator[_KeyType]: return iter(self.keys()) def __len__(self) -> int: return len(self._dict) def __eq__(self, other: Any) -> bool: if not isinstance(other, self.__class__): return False return sorted(self._list) == sorted(other._list) def __repr__(self) -> str: class_name = self.__class__.__name__ items = self.multi_items() return f"{class_name}({items!r})" class MultiDict(ImmutableMultiDict[Any, Any]): def __setitem__(self, key: Any, value: Any) -> None: self.setlist(key, [value]) def __delitem__(self, key: Any) -> None: self._list = [(k, v) for k, v in self._list if k != key] del self._dict[key] def pop(self, key: Any, default: Any = None) -> Any: self._list = [(k, v) for k, v in self._list if k != key] return self._dict.pop(key, default) def popitem(self) -> tuple[Any, Any]: key, value = self._dict.popitem() self._list = [(k, v) for k, v in self._list if k != key] return key, value def poplist(self, key: Any) -> list[Any]: values = [v for k, v in self._list if k == key] self.pop(key) return values def clear(self) -> None: self._dict.clear() self._list.clear() def setdefault(self, key: Any, default: Any = None) -> Any: if key not in self: self._dict[key] = default self._list.append((key, default)) return self[key] def setlist(self, key: Any, values: list[Any]) -> None: if not values: self.pop(key, None) else: existing_items = [(k, v) for (k, v) in self._list if k != key] self._list = existing_items + [(key, value) for value in values] self._dict[key] = values[-1] def append(self, key: Any, value: Any) -> None: self._list.append((key, value)) self._dict[key] = value def update( self, *args: MultiDict | Mapping[Any, Any] | list[tuple[Any, Any]], **kwargs: Any, ) -> None: value = MultiDict(*args, **kwargs) existing_items = [(k, v) for (k, v) in self._list if k not in value.keys()] self._list = existing_items + value.multi_items() self._dict.update(value) class QueryParams(ImmutableMultiDict[str, str]): """ An immutable multidict. """ def __init__( self, *args: ImmutableMultiDict[Any, Any] | Mapping[Any, Any] | list[tuple[Any, Any]] | str | bytes, **kwargs: Any, ) -> None: assert len(args) < 2, "Too many arguments." value = args[0] if args else [] if isinstance(value, str): super().__init__(parse_qsl(value, keep_blank_values=True), **kwargs) elif isinstance(value, bytes): super().__init__(parse_qsl(value.decode("latin-1"), keep_blank_values=True), **kwargs) else: super().__init__(*args, **kwargs) # type: ignore[arg-type] self._list = [(str(k), str(v)) for k, v in self._list] self._dict = {str(k): str(v) for k, v in self._dict.items()} def __str__(self) -> str: return urlencode(self._list) def __repr__(self) -> str: class_name = self.__class__.__name__ query_string = str(self) return f"{class_name}({query_string!r})" class UploadFile: """ An uploaded file included as part of the request data. """ def __init__( self, file: BinaryIO, *, size: int | None = None, filename: str | None = None, headers: Headers | None = None, ) -> None: self.filename = filename self.file = file self.size = size self.headers = headers or Headers() # Capture max size from SpooledTemporaryFile if one is provided. This slightly speeds up future checks. # Note 0 means unlimited mirroring SpooledTemporaryFile's __init__ self._max_mem_size = getattr(self.file, "_max_size", 0) @property def content_type(self) -> str | None: return self.headers.get("content-type", None) @property def _in_memory(self) -> bool: # check for SpooledTemporaryFile._rolled rolled_to_disk = getattr(self.file, "_rolled", True) return not rolled_to_disk def _will_roll(self, size_to_add: int) -> bool: # If we're not in_memory then we will always roll if not self._in_memory: return True # Check for SpooledTemporaryFile._max_size future_size = self.file.tell() + size_to_add return bool(future_size > self._max_mem_size) if self._max_mem_size else False async def write(self, data: bytes) -> None: new_data_len = len(data) if self.size is not None: self.size += new_data_len if self._will_roll(new_data_len): await run_in_threadpool(self.file.write, data) else: self.file.write(data) async def read(self, size: int = -1) -> bytes: if self._in_memory: return self.file.read(size) return await run_in_threadpool(self.file.read, size) async def seek(self, offset: int) -> None: if self._in_memory: self.file.seek(offset) else: await run_in_threadpool(self.file.seek, offset) async def close(self) -> None: if self._in_memory: self.file.close() else: await run_in_threadpool(self.file.close) def __repr__(self) -> str: return f"{self.__class__.__name__}(filename={self.filename!r}, size={self.size!r}, headers={self.headers!r})" class FormData(ImmutableMultiDict[str, UploadFile | str]): """ An immutable multidict, containing both file uploads and text input. """ def __init__( self, *args: FormData | Mapping[str, str | UploadFile] | list[tuple[str, str | UploadFile]], **kwargs: str | UploadFile, ) -> None: super().__init__(*args, **kwargs) async def close(self) -> None: for key, value in self.multi_items(): if isinstance(value, UploadFile): await value.close() class Headers(Mapping[str, str]): """ An immutable, case-insensitive multidict. """ def __init__( self, headers: Mapping[str, str] | None = None, raw: list[tuple[bytes, bytes]] | None = None, scope: MutableMapping[str, Any] | None = None, ) -> None: self._list: list[tuple[bytes, bytes]] = [] if headers is not None: assert raw is None, 'Cannot set both "headers" and "raw".' assert scope is None, 'Cannot set both "headers" and "scope".' self._list = [(key.lower().encode("latin-1"), value.encode("latin-1")) for key, value in headers.items()] elif raw is not None: assert scope is None, 'Cannot set both "raw" and "scope".' self._list = raw elif scope is not None: # scope["headers"] isn't necessarily a list # it might be a tuple or other iterable self._list = scope["headers"] = list(scope["headers"]) @property def raw(self) -> list[tuple[bytes, bytes]]: return list(self._list) def keys(self) -> list[str]: # type: ignore[override] return [key.decode("latin-1") for key, value in self._list] def values(self) -> list[str]: # type: ignore[override] return [value.decode("latin-1") for key, value in self._list] def items(self) -> list[tuple[str, str]]: # type: ignore[override] return [(key.decode("latin-1"), value.decode("latin-1")) for key, value in self._list] def getlist(self, key: str) -> list[str]: get_header_key = key.lower().encode("latin-1") return [item_value.decode("latin-1") for item_key, item_value in self._list if item_key == get_header_key] def mutablecopy(self) -> MutableHeaders: return MutableHeaders(raw=self._list[:]) def __getitem__(self, key: str) -> str: get_header_key = key.lower().encode("latin-1") for header_key, header_value in self._list: if header_key == get_header_key: return header_value.decode("latin-1") raise KeyError(key) def __contains__(self, key: Any) -> bool: get_header_key = key.lower().encode("latin-1") for header_key, header_value in self._list: if header_key == get_header_key: return True return False def __iter__(self) -> Iterator[Any]: return iter(self.keys()) def __len__(self) -> int: return len(self._list) def __eq__(self, other: Any) -> bool: if not isinstance(other, Headers): return False return sorted(self._list) == sorted(other._list) def __repr__(self) -> str: class_name = self.__class__.__name__ as_dict = dict(self.items()) if len(as_dict) == len(self): return f"{class_name}({as_dict!r})" return f"{class_name}(raw={self.raw!r})" class MutableHeaders(Headers): def __setitem__(self, key: str, value: str) -> None: """ Set the header `key` to `value`, removing any duplicate entries. Retains insertion order. """ set_key = key.lower().encode("latin-1") set_value = value.encode("latin-1") found_indexes: list[int] = [] for idx, (item_key, item_value) in enumerate(self._list): if item_key == set_key: found_indexes.append(idx) for idx in reversed(found_indexes[1:]): del self._list[idx] if found_indexes: idx = found_indexes[0] self._list[idx] = (set_key, set_value) else: self._list.append((set_key, set_value)) def __delitem__(self, key: str) -> None: """ Remove the header `key`. """ del_key = key.lower().encode("latin-1") pop_indexes: list[int] = [] for idx, (item_key, item_value) in enumerate(self._list): if item_key == del_key: pop_indexes.append(idx) for idx in reversed(pop_indexes): del self._list[idx] def __ior__(self, other: Mapping[str, str]) -> MutableHeaders: if not isinstance(other, Mapping): raise TypeError(f"Expected a mapping but got {other.__class__.__name__}") self.update(other) return self def __or__(self, other: Mapping[str, str]) -> MutableHeaders: if not isinstance(other, Mapping): raise TypeError(f"Expected a mapping but got {other.__class__.__name__}") new = self.mutablecopy() new.update(other) return new @property def raw(self) -> list[tuple[bytes, bytes]]: return self._list def setdefault(self, key: str, value: str) -> str: """ If the header `key` does not exist, then set it to `value`. Returns the header value. """ set_key = key.lower().encode("latin-1") set_value = value.encode("latin-1") for idx, (item_key, item_value) in enumerate(self._list): if item_key == set_key: return item_value.decode("latin-1") self._list.append((set_key, set_value)) return value def update(self, other: Mapping[str, str]) -> None: for key, val in other.items(): self[key] = val def append(self, key: str, value: str) -> None: """ Append a header, preserving any duplicate entries. """ append_key = key.lower().encode("latin-1") append_value = value.encode("latin-1") self._list.append((append_key, append_value)) def add_vary_header(self, vary: str) -> None: existing = self.get("vary") if existing is not None: vary = ", ".join([existing, vary]) self["vary"] = vary class State: """ An object that can be used to store arbitrary state. Used for `request.state` and `app.state`. """ _state: dict[str, Any] def __init__(self, state: dict[str, Any] | None = None): if state is None: state = {} super().__setattr__("_state", state) def __setattr__(self, key: Any, value: Any) -> None: self._state[key] = value def __getattr__(self, key: Any) -> Any: try: return self._state[key] except KeyError: message = "'{}' object has no attribute '{}'" raise AttributeError(message.format(self.__class__.__name__, key)) def __delattr__(self, key: Any) -> None: del self._state[key] starlette-0.50.0/starlette/endpoints.py000066400000000000000000000117531510142272400201740ustar00rootroot00000000000000from __future__ import annotations import json from collections.abc import Callable, Generator from typing import Any, Literal from starlette import status from starlette._utils import is_async_callable from starlette.concurrency import run_in_threadpool from starlette.exceptions import HTTPException from starlette.requests import Request from starlette.responses import PlainTextResponse, Response from starlette.types import Message, Receive, Scope, Send from starlette.websockets import WebSocket class HTTPEndpoint: def __init__(self, scope: Scope, receive: Receive, send: Send) -> None: assert scope["type"] == "http" self.scope = scope self.receive = receive self.send = send self._allowed_methods = [ method for method in ("GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS") if getattr(self, method.lower(), None) is not None ] def __await__(self) -> Generator[Any, None, None]: return self.dispatch().__await__() async def dispatch(self) -> None: request = Request(self.scope, receive=self.receive) handler_name = "get" if request.method == "HEAD" and not hasattr(self, "head") else request.method.lower() handler: Callable[[Request], Any] = getattr(self, handler_name, self.method_not_allowed) is_async = is_async_callable(handler) if is_async: response = await handler(request) else: response = await run_in_threadpool(handler, request) await response(self.scope, self.receive, self.send) async def method_not_allowed(self, request: Request) -> Response: # If we're running inside a starlette application then raise an # exception, so that the configurable exception handler can deal with # returning the response. For plain ASGI apps, just return the response. headers = {"Allow": ", ".join(self._allowed_methods)} if "app" in self.scope: raise HTTPException(status_code=405, headers=headers) return PlainTextResponse("Method Not Allowed", status_code=405, headers=headers) class WebSocketEndpoint: encoding: Literal["text", "bytes", "json"] | None = None def __init__(self, scope: Scope, receive: Receive, send: Send) -> None: assert scope["type"] == "websocket" self.scope = scope self.receive = receive self.send = send def __await__(self) -> Generator[Any, None, None]: return self.dispatch().__await__() async def dispatch(self) -> None: websocket = WebSocket(self.scope, receive=self.receive, send=self.send) await self.on_connect(websocket) close_code = status.WS_1000_NORMAL_CLOSURE try: while True: message = await websocket.receive() if message["type"] == "websocket.receive": data = await self.decode(websocket, message) await self.on_receive(websocket, data) elif message["type"] == "websocket.disconnect": # pragma: no branch close_code = int(message.get("code") or status.WS_1000_NORMAL_CLOSURE) break except Exception as exc: close_code = status.WS_1011_INTERNAL_ERROR raise exc finally: await self.on_disconnect(websocket, close_code) async def decode(self, websocket: WebSocket, message: Message) -> Any: if self.encoding == "text": if "text" not in message: await websocket.close(code=status.WS_1003_UNSUPPORTED_DATA) raise RuntimeError("Expected text websocket messages, but got bytes") return message["text"] elif self.encoding == "bytes": if "bytes" not in message: await websocket.close(code=status.WS_1003_UNSUPPORTED_DATA) raise RuntimeError("Expected bytes websocket messages, but got text") return message["bytes"] elif self.encoding == "json": if message.get("text") is not None: text = message["text"] else: text = message["bytes"].decode("utf-8") try: return json.loads(text) except json.decoder.JSONDecodeError: await websocket.close(code=status.WS_1003_UNSUPPORTED_DATA) raise RuntimeError("Malformed JSON data received.") assert self.encoding is None, f"Unsupported 'encoding' attribute {self.encoding}" return message["text"] if message.get("text") else message["bytes"] async def on_connect(self, websocket: WebSocket) -> None: """Override to handle an incoming websocket connection""" await websocket.accept() async def on_receive(self, websocket: WebSocket, data: Any) -> None: """Override to handle an incoming websocket message""" async def on_disconnect(self, websocket: WebSocket, close_code: int) -> None: """Override to handle a disconnecting websocket""" starlette-0.50.0/starlette/exceptions.py000066400000000000000000000020521510142272400203420ustar00rootroot00000000000000from __future__ import annotations import http from collections.abc import Mapping class HTTPException(Exception): def __init__(self, status_code: int, detail: str | None = None, headers: Mapping[str, str] | None = None) -> None: if detail is None: detail = http.HTTPStatus(status_code).phrase self.status_code = status_code self.detail = detail self.headers = headers def __str__(self) -> str: return f"{self.status_code}: {self.detail}" def __repr__(self) -> str: class_name = self.__class__.__name__ return f"{class_name}(status_code={self.status_code!r}, detail={self.detail!r})" class WebSocketException(Exception): def __init__(self, code: int, reason: str | None = None) -> None: self.code = code self.reason = reason or "" def __str__(self) -> str: return f"{self.code}: {self.reason}" def __repr__(self) -> str: class_name = self.__class__.__name__ return f"{class_name}(code={self.code!r}, reason={self.reason!r})" starlette-0.50.0/starlette/formparsers.py000066400000000000000000000255161510142272400205360ustar00rootroot00000000000000from __future__ import annotations from collections.abc import AsyncGenerator from dataclasses import dataclass, field from enum import Enum from tempfile import SpooledTemporaryFile from typing import TYPE_CHECKING from urllib.parse import unquote_plus from starlette.datastructures import FormData, Headers, UploadFile if TYPE_CHECKING: import python_multipart as multipart from python_multipart.multipart import MultipartCallbacks, QuerystringCallbacks, parse_options_header else: try: try: import python_multipart as multipart from python_multipart.multipart import parse_options_header except ModuleNotFoundError: # pragma: no cover import multipart from multipart.multipart import parse_options_header except ModuleNotFoundError: # pragma: no cover multipart = None parse_options_header = None class FormMessage(Enum): FIELD_START = 1 FIELD_NAME = 2 FIELD_DATA = 3 FIELD_END = 4 END = 5 @dataclass class MultipartPart: content_disposition: bytes | None = None field_name: str = "" data: bytearray = field(default_factory=bytearray) file: UploadFile | None = None item_headers: list[tuple[bytes, bytes]] = field(default_factory=list) def _user_safe_decode(src: bytes | bytearray, codec: str) -> str: try: return src.decode(codec) except (UnicodeDecodeError, LookupError): return src.decode("latin-1") class MultiPartException(Exception): def __init__(self, message: str) -> None: self.message = message class FormParser: def __init__(self, headers: Headers, stream: AsyncGenerator[bytes, None]) -> None: assert multipart is not None, "The `python-multipart` library must be installed to use form parsing." self.headers = headers self.stream = stream self.messages: list[tuple[FormMessage, bytes]] = [] def on_field_start(self) -> None: message = (FormMessage.FIELD_START, b"") self.messages.append(message) def on_field_name(self, data: bytes, start: int, end: int) -> None: message = (FormMessage.FIELD_NAME, data[start:end]) self.messages.append(message) def on_field_data(self, data: bytes, start: int, end: int) -> None: message = (FormMessage.FIELD_DATA, data[start:end]) self.messages.append(message) def on_field_end(self) -> None: message = (FormMessage.FIELD_END, b"") self.messages.append(message) def on_end(self) -> None: message = (FormMessage.END, b"") self.messages.append(message) async def parse(self) -> FormData: # Callbacks dictionary. callbacks: QuerystringCallbacks = { "on_field_start": self.on_field_start, "on_field_name": self.on_field_name, "on_field_data": self.on_field_data, "on_field_end": self.on_field_end, "on_end": self.on_end, } # Create the parser. parser = multipart.QuerystringParser(callbacks) field_name = b"" field_value = b"" items: list[tuple[str, str | UploadFile]] = [] # Feed the parser with data from the request. async for chunk in self.stream: if chunk: parser.write(chunk) else: parser.finalize() messages = list(self.messages) self.messages.clear() for message_type, message_bytes in messages: if message_type == FormMessage.FIELD_START: field_name = b"" field_value = b"" elif message_type == FormMessage.FIELD_NAME: field_name += message_bytes elif message_type == FormMessage.FIELD_DATA: field_value += message_bytes elif message_type == FormMessage.FIELD_END: name = unquote_plus(field_name.decode("latin-1")) value = unquote_plus(field_value.decode("latin-1")) items.append((name, value)) return FormData(items) class MultiPartParser: spool_max_size = 1024 * 1024 # 1MB """The maximum size of the spooled temporary file used to store file data.""" max_part_size = 1024 * 1024 # 1MB """The maximum size of a part in the multipart request.""" def __init__( self, headers: Headers, stream: AsyncGenerator[bytes, None], *, max_files: int | float = 1000, max_fields: int | float = 1000, max_part_size: int = 1024 * 1024, # 1MB ) -> None: assert multipart is not None, "The `python-multipart` library must be installed to use form parsing." self.headers = headers self.stream = stream self.max_files = max_files self.max_fields = max_fields self.items: list[tuple[str, str | UploadFile]] = [] self._current_files = 0 self._current_fields = 0 self._current_partial_header_name: bytes = b"" self._current_partial_header_value: bytes = b"" self._current_part = MultipartPart() self._charset = "" self._file_parts_to_write: list[tuple[MultipartPart, bytes]] = [] self._file_parts_to_finish: list[MultipartPart] = [] self._files_to_close_on_error: list[SpooledTemporaryFile[bytes]] = [] self.max_part_size = max_part_size def on_part_begin(self) -> None: self._current_part = MultipartPart() def on_part_data(self, data: bytes, start: int, end: int) -> None: message_bytes = data[start:end] if self._current_part.file is None: if len(self._current_part.data) + len(message_bytes) > self.max_part_size: raise MultiPartException(f"Part exceeded maximum size of {int(self.max_part_size / 1024)}KB.") self._current_part.data.extend(message_bytes) else: self._file_parts_to_write.append((self._current_part, message_bytes)) def on_part_end(self) -> None: if self._current_part.file is None: self.items.append( ( self._current_part.field_name, _user_safe_decode(self._current_part.data, self._charset), ) ) else: self._file_parts_to_finish.append(self._current_part) # The file can be added to the items right now even though it's not # finished yet, because it will be finished in the `parse()` method, before # self.items is used in the return value. self.items.append((self._current_part.field_name, self._current_part.file)) def on_header_field(self, data: bytes, start: int, end: int) -> None: self._current_partial_header_name += data[start:end] def on_header_value(self, data: bytes, start: int, end: int) -> None: self._current_partial_header_value += data[start:end] def on_header_end(self) -> None: field = self._current_partial_header_name.lower() if field == b"content-disposition": self._current_part.content_disposition = self._current_partial_header_value self._current_part.item_headers.append((field, self._current_partial_header_value)) self._current_partial_header_name = b"" self._current_partial_header_value = b"" def on_headers_finished(self) -> None: disposition, options = parse_options_header(self._current_part.content_disposition) try: self._current_part.field_name = _user_safe_decode(options[b"name"], self._charset) except KeyError: raise MultiPartException('The Content-Disposition header field "name" must be provided.') if b"filename" in options: self._current_files += 1 if self._current_files > self.max_files: raise MultiPartException(f"Too many files. Maximum number of files is {self.max_files}.") filename = _user_safe_decode(options[b"filename"], self._charset) tempfile = SpooledTemporaryFile(max_size=self.spool_max_size) self._files_to_close_on_error.append(tempfile) self._current_part.file = UploadFile( file=tempfile, # type: ignore[arg-type] size=0, filename=filename, headers=Headers(raw=self._current_part.item_headers), ) else: self._current_fields += 1 if self._current_fields > self.max_fields: raise MultiPartException(f"Too many fields. Maximum number of fields is {self.max_fields}.") self._current_part.file = None def on_end(self) -> None: pass async def parse(self) -> FormData: # Parse the Content-Type header to get the multipart boundary. _, params = parse_options_header(self.headers["Content-Type"]) charset = params.get(b"charset", "utf-8") if isinstance(charset, bytes): charset = charset.decode("latin-1") self._charset = charset try: boundary = params[b"boundary"] except KeyError: raise MultiPartException("Missing boundary in multipart.") # Callbacks dictionary. callbacks: MultipartCallbacks = { "on_part_begin": self.on_part_begin, "on_part_data": self.on_part_data, "on_part_end": self.on_part_end, "on_header_field": self.on_header_field, "on_header_value": self.on_header_value, "on_header_end": self.on_header_end, "on_headers_finished": self.on_headers_finished, "on_end": self.on_end, } # Create the parser. parser = multipart.MultipartParser(boundary, callbacks) try: # Feed the parser with data from the request. async for chunk in self.stream: parser.write(chunk) # Write file data, it needs to use await with the UploadFile methods # that call the corresponding file methods *in a threadpool*, # otherwise, if they were called directly in the callback methods above # (regular, non-async functions), that would block the event loop in # the main thread. for part, data in self._file_parts_to_write: assert part.file # for type checkers await part.file.write(data) for part in self._file_parts_to_finish: assert part.file # for type checkers await part.file.seek(0) self._file_parts_to_write.clear() self._file_parts_to_finish.clear() except MultiPartException as exc: # Close all the files if there was an error. for file in self._files_to_close_on_error: file.close() raise exc parser.finalize() return FormData(self.items) starlette-0.50.0/starlette/middleware/000077500000000000000000000000001510142272400177255ustar00rootroot00000000000000starlette-0.50.0/starlette/middleware/__init__.py000066400000000000000000000025051510142272400220400ustar00rootroot00000000000000from __future__ import annotations from collections.abc import Awaitable, Callable, Iterator from typing import Any, ParamSpec, Protocol P = ParamSpec("P") _Scope = Any _Receive = Callable[[], Awaitable[Any]] _Send = Callable[[Any], Awaitable[None]] # Since `starlette.types.ASGIApp` type differs from `ASGIApplication` from `asgiref` # we need to define a more permissive version of ASGIApp that doesn't cause type errors. _ASGIApp = Callable[[_Scope, _Receive, _Send], Awaitable[None]] class _MiddlewareFactory(Protocol[P]): def __call__(self, app: _ASGIApp, /, *args: P.args, **kwargs: P.kwargs) -> _ASGIApp: ... # pragma: no cover class Middleware: def __init__(self, cls: _MiddlewareFactory[P], *args: P.args, **kwargs: P.kwargs) -> None: self.cls = cls self.args = args self.kwargs = kwargs def __iter__(self) -> Iterator[Any]: as_tuple = (self.cls, self.args, self.kwargs) return iter(as_tuple) def __repr__(self) -> str: class_name = self.__class__.__name__ args_strings = [f"{value!r}" for value in self.args] option_strings = [f"{key}={value!r}" for key, value in self.kwargs.items()] name = getattr(self.cls, "__name__", "") args_repr = ", ".join([name] + args_strings + option_strings) return f"{class_name}({args_repr})" starlette-0.50.0/starlette/middleware/authentication.py000066400000000000000000000034101510142272400233140ustar00rootroot00000000000000from __future__ import annotations from collections.abc import Callable from starlette.authentication import ( AuthCredentials, AuthenticationBackend, AuthenticationError, UnauthenticatedUser, ) from starlette.requests import HTTPConnection from starlette.responses import PlainTextResponse, Response from starlette.types import ASGIApp, Receive, Scope, Send class AuthenticationMiddleware: def __init__( self, app: ASGIApp, backend: AuthenticationBackend, on_error: Callable[[HTTPConnection, AuthenticationError], Response] | None = None, ) -> None: self.app = app self.backend = backend self.on_error: Callable[[HTTPConnection, AuthenticationError], Response] = ( on_error if on_error is not None else self.default_on_error ) async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: if scope["type"] not in ["http", "websocket"]: await self.app(scope, receive, send) return conn = HTTPConnection(scope) try: auth_result = await self.backend.authenticate(conn) except AuthenticationError as exc: response = self.on_error(conn, exc) if scope["type"] == "websocket": await send({"type": "websocket.close", "code": 1000}) else: await response(scope, receive, send) return if auth_result is None: auth_result = AuthCredentials(), UnauthenticatedUser() scope["auth"], scope["user"] = auth_result await self.app(scope, receive, send) @staticmethod def default_on_error(conn: HTTPConnection, exc: Exception) -> Response: return PlainTextResponse(str(exc), status_code=400) starlette-0.50.0/starlette/middleware/base.py000066400000000000000000000241351510142272400212160ustar00rootroot00000000000000from __future__ import annotations from collections.abc import AsyncGenerator, AsyncIterable, Awaitable, Callable, Mapping, MutableMapping from typing import Any, TypeVar import anyio from starlette._utils import collapse_excgroups from starlette.requests import ClientDisconnect, Request from starlette.responses import Response from starlette.types import ASGIApp, Message, Receive, Scope, Send RequestResponseEndpoint = Callable[[Request], Awaitable[Response]] DispatchFunction = Callable[[Request, RequestResponseEndpoint], Awaitable[Response]] BodyStreamGenerator = AsyncGenerator[bytes | MutableMapping[str, Any], None] AsyncContentStream = AsyncIterable[str | bytes | memoryview | MutableMapping[str, Any]] T = TypeVar("T") class _CachedRequest(Request): """ If the user calls Request.body() from their dispatch function we cache the entire request body in memory and pass that to downstream middlewares, but if they call Request.stream() then all we do is send an empty body so that downstream things don't hang forever. """ def __init__(self, scope: Scope, receive: Receive): super().__init__(scope, receive) self._wrapped_rcv_disconnected = False self._wrapped_rcv_consumed = False self._wrapped_rc_stream = self.stream() async def wrapped_receive(self) -> Message: # wrapped_rcv state 1: disconnected if self._wrapped_rcv_disconnected: # we've already sent a disconnect to the downstream app # we don't need to wait to get another one # (although most ASGI servers will just keep sending it) return {"type": "http.disconnect"} # wrapped_rcv state 1: consumed but not yet disconnected if self._wrapped_rcv_consumed: # since the downstream app has consumed us all that is left # is to send it a disconnect if self._is_disconnected: # the middleware has already seen the disconnect # since we know the client is disconnected no need to wait # for the message self._wrapped_rcv_disconnected = True return {"type": "http.disconnect"} # we don't know yet if the client is disconnected or not # so we'll wait until we get that message msg = await self.receive() if msg["type"] != "http.disconnect": # pragma: no cover # at this point a disconnect is all that we should be receiving # if we get something else, things went wrong somewhere raise RuntimeError(f"Unexpected message received: {msg['type']}") self._wrapped_rcv_disconnected = True return msg # wrapped_rcv state 3: not yet consumed if getattr(self, "_body", None) is not None: # body() was called, we return it even if the client disconnected self._wrapped_rcv_consumed = True return { "type": "http.request", "body": self._body, "more_body": False, } elif self._stream_consumed: # stream() was called to completion # return an empty body so that downstream apps don't hang # waiting for a disconnect self._wrapped_rcv_consumed = True return { "type": "http.request", "body": b"", "more_body": False, } else: # body() was never called and stream() wasn't consumed try: stream = self.stream() chunk = await stream.__anext__() self._wrapped_rcv_consumed = self._stream_consumed return { "type": "http.request", "body": chunk, "more_body": not self._stream_consumed, } except ClientDisconnect: self._wrapped_rcv_disconnected = True return {"type": "http.disconnect"} class BaseHTTPMiddleware: def __init__(self, app: ASGIApp, dispatch: DispatchFunction | None = None) -> None: self.app = app self.dispatch_func = self.dispatch if dispatch is None else dispatch async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: if scope["type"] != "http": await self.app(scope, receive, send) return request = _CachedRequest(scope, receive) wrapped_receive = request.wrapped_receive response_sent = anyio.Event() app_exc: Exception | None = None exception_already_raised = False async def call_next(request: Request) -> Response: async def receive_or_disconnect() -> Message: if response_sent.is_set(): return {"type": "http.disconnect"} async with anyio.create_task_group() as task_group: async def wrap(func: Callable[[], Awaitable[T]]) -> T: result = await func() task_group.cancel_scope.cancel() return result task_group.start_soon(wrap, response_sent.wait) message = await wrap(wrapped_receive) if response_sent.is_set(): return {"type": "http.disconnect"} return message async def send_no_error(message: Message) -> None: try: await send_stream.send(message) except anyio.BrokenResourceError: # recv_stream has been closed, i.e. response_sent has been set. return async def coro() -> None: nonlocal app_exc with send_stream: try: await self.app(scope, receive_or_disconnect, send_no_error) except Exception as exc: app_exc = exc task_group.start_soon(coro) try: message = await recv_stream.receive() info = message.get("info", None) if message["type"] == "http.response.debug" and info is not None: message = await recv_stream.receive() except anyio.EndOfStream: if app_exc is not None: nonlocal exception_already_raised exception_already_raised = True # Prevent `anyio.EndOfStream` from polluting app exception context. # If both cause and context are None then the context is suppressed # and `anyio.EndOfStream` is not present in the exception traceback. # If exception cause is not None then it is propagated with # reraising here. # If exception has no cause but has context set then the context is # propagated as a cause with the reraise. This is necessary in order # to prevent `anyio.EndOfStream` from polluting the exception # context. raise app_exc from app_exc.__cause__ or app_exc.__context__ raise RuntimeError("No response returned.") assert message["type"] == "http.response.start" async def body_stream() -> BodyStreamGenerator: async for message in recv_stream: if message["type"] == "http.response.pathsend": yield message break assert message["type"] == "http.response.body", f"Unexpected message: {message}" body = message.get("body", b"") if body: yield body if not message.get("more_body", False): break response = _StreamingResponse(status_code=message["status"], content=body_stream(), info=info) response.raw_headers = message["headers"] return response streams: anyio.create_memory_object_stream[Message] = anyio.create_memory_object_stream() send_stream, recv_stream = streams with recv_stream, send_stream, collapse_excgroups(): async with anyio.create_task_group() as task_group: response = await self.dispatch_func(request, call_next) await response(scope, wrapped_receive, send) response_sent.set() recv_stream.close() if app_exc is not None and not exception_already_raised: raise app_exc async def dispatch(self, request: Request, call_next: RequestResponseEndpoint) -> Response: raise NotImplementedError() # pragma: no cover class _StreamingResponse(Response): def __init__( self, content: AsyncContentStream, status_code: int = 200, headers: Mapping[str, str] | None = None, media_type: str | None = None, info: Mapping[str, Any] | None = None, ) -> None: self.info = info self.body_iterator = content self.status_code = status_code self.media_type = media_type self.init_headers(headers) self.background = None async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: if self.info is not None: await send({"type": "http.response.debug", "info": self.info}) await send( { "type": "http.response.start", "status": self.status_code, "headers": self.raw_headers, } ) should_close_body = True async for chunk in self.body_iterator: if isinstance(chunk, dict): # We got an ASGI message which is not response body (eg: pathsend) should_close_body = False await send(chunk) continue await send({"type": "http.response.body", "body": chunk, "more_body": True}) if should_close_body: await send({"type": "http.response.body", "body": b"", "more_body": False}) if self.background: await self.background() starlette-0.50.0/starlette/middleware/cors.py000066400000000000000000000156061510142272400212550ustar00rootroot00000000000000from __future__ import annotations import functools import re from collections.abc import Sequence from starlette.datastructures import Headers, MutableHeaders from starlette.responses import PlainTextResponse, Response from starlette.types import ASGIApp, Message, Receive, Scope, Send ALL_METHODS = ("DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT") SAFELISTED_HEADERS = {"Accept", "Accept-Language", "Content-Language", "Content-Type"} class CORSMiddleware: def __init__( self, app: ASGIApp, allow_origins: Sequence[str] = (), allow_methods: Sequence[str] = ("GET",), allow_headers: Sequence[str] = (), allow_credentials: bool = False, allow_origin_regex: str | None = None, expose_headers: Sequence[str] = (), max_age: int = 600, ) -> None: if "*" in allow_methods: allow_methods = ALL_METHODS compiled_allow_origin_regex = None if allow_origin_regex is not None: compiled_allow_origin_regex = re.compile(allow_origin_regex) allow_all_origins = "*" in allow_origins allow_all_headers = "*" in allow_headers preflight_explicit_allow_origin = not allow_all_origins or allow_credentials simple_headers = {} if allow_all_origins: simple_headers["Access-Control-Allow-Origin"] = "*" if allow_credentials: simple_headers["Access-Control-Allow-Credentials"] = "true" if expose_headers: simple_headers["Access-Control-Expose-Headers"] = ", ".join(expose_headers) preflight_headers = {} if preflight_explicit_allow_origin: # The origin value will be set in preflight_response() if it is allowed. preflight_headers["Vary"] = "Origin" else: preflight_headers["Access-Control-Allow-Origin"] = "*" preflight_headers.update( { "Access-Control-Allow-Methods": ", ".join(allow_methods), "Access-Control-Max-Age": str(max_age), } ) allow_headers = sorted(SAFELISTED_HEADERS | set(allow_headers)) if allow_headers and not allow_all_headers: preflight_headers["Access-Control-Allow-Headers"] = ", ".join(allow_headers) if allow_credentials: preflight_headers["Access-Control-Allow-Credentials"] = "true" self.app = app self.allow_origins = allow_origins self.allow_methods = allow_methods self.allow_headers = [h.lower() for h in allow_headers] self.allow_all_origins = allow_all_origins self.allow_all_headers = allow_all_headers self.preflight_explicit_allow_origin = preflight_explicit_allow_origin self.allow_origin_regex = compiled_allow_origin_regex self.simple_headers = simple_headers self.preflight_headers = preflight_headers async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: if scope["type"] != "http": # pragma: no cover await self.app(scope, receive, send) return method = scope["method"] headers = Headers(scope=scope) origin = headers.get("origin") if origin is None: await self.app(scope, receive, send) return if method == "OPTIONS" and "access-control-request-method" in headers: response = self.preflight_response(request_headers=headers) await response(scope, receive, send) return await self.simple_response(scope, receive, send, request_headers=headers) def is_allowed_origin(self, origin: str) -> bool: if self.allow_all_origins: return True if self.allow_origin_regex is not None and self.allow_origin_regex.fullmatch(origin): return True return origin in self.allow_origins def preflight_response(self, request_headers: Headers) -> Response: requested_origin = request_headers["origin"] requested_method = request_headers["access-control-request-method"] requested_headers = request_headers.get("access-control-request-headers") headers = dict(self.preflight_headers) failures = [] if self.is_allowed_origin(origin=requested_origin): if self.preflight_explicit_allow_origin: # The "else" case is already accounted for in self.preflight_headers # and the value would be "*". headers["Access-Control-Allow-Origin"] = requested_origin else: failures.append("origin") if requested_method not in self.allow_methods: failures.append("method") # If we allow all headers, then we have to mirror back any requested # headers in the response. if self.allow_all_headers and requested_headers is not None: headers["Access-Control-Allow-Headers"] = requested_headers elif requested_headers is not None: for header in [h.lower() for h in requested_headers.split(",")]: if header.strip() not in self.allow_headers: failures.append("headers") break # We don't strictly need to use 400 responses here, since its up to # the browser to enforce the CORS policy, but its more informative # if we do. if failures: failure_text = "Disallowed CORS " + ", ".join(failures) return PlainTextResponse(failure_text, status_code=400, headers=headers) return PlainTextResponse("OK", status_code=200, headers=headers) async def simple_response(self, scope: Scope, receive: Receive, send: Send, request_headers: Headers) -> None: send = functools.partial(self.send, send=send, request_headers=request_headers) await self.app(scope, receive, send) async def send(self, message: Message, send: Send, request_headers: Headers) -> None: if message["type"] != "http.response.start": await send(message) return message.setdefault("headers", []) headers = MutableHeaders(scope=message) headers.update(self.simple_headers) origin = request_headers["Origin"] has_cookie = "cookie" in request_headers # If request includes any cookie headers, then we must respond # with the specific origin instead of '*'. if self.allow_all_origins and has_cookie: self.allow_explicit_origin(headers, origin) # If we only allow specific origins, then we have to mirror back # the Origin header in the response. elif not self.allow_all_origins and self.is_allowed_origin(origin=origin): self.allow_explicit_origin(headers, origin) await send(message) @staticmethod def allow_explicit_origin(headers: MutableHeaders, origin: str) -> None: headers["Access-Control-Allow-Origin"] = origin headers.add_vary_header("Origin") starlette-0.50.0/starlette/middleware/errors.py000066400000000000000000000175451510142272400216270ustar00rootroot00000000000000from __future__ import annotations import html import inspect import sys import traceback from starlette._utils import is_async_callable from starlette.concurrency import run_in_threadpool from starlette.requests import Request from starlette.responses import HTMLResponse, PlainTextResponse, Response from starlette.types import ASGIApp, ExceptionHandler, Message, Receive, Scope, Send STYLES = """ p { color: #211c1c; } .traceback-container { border: 1px solid #038BB8; } .traceback-title { background-color: #038BB8; color: lemonchiffon; padding: 12px; font-size: 20px; margin-top: 0px; } .frame-line { padding-left: 10px; font-family: monospace; } .frame-filename { font-family: monospace; } .center-line { background-color: #038BB8; color: #f9f6e1; padding: 5px 0px 5px 5px; } .lineno { margin-right: 5px; } .frame-title { font-weight: unset; padding: 10px 10px 10px 10px; background-color: #E4F4FD; margin-right: 10px; color: #191f21; font-size: 17px; border: 1px solid #c7dce8; } .collapse-btn { float: right; padding: 0px 5px 1px 5px; border: solid 1px #96aebb; cursor: pointer; } .collapsed { display: none; } .source-code { font-family: courier; font-size: small; padding-bottom: 10px; } """ JS = """ """ TEMPLATE = """ Starlette Debugger

    500 Server Error

    {error}

    Traceback

    {exc_html}
    {js} """ FRAME_TEMPLATE = """

    File {frame_filename}, line {frame_lineno}, in {frame_name} {collapse_button}

    {code_context}
    """ # noqa: E501 LINE = """

    {lineno}. {line}

    """ CENTER_LINE = """

    {lineno}. {line}

    """ class ServerErrorMiddleware: """ Handles returning 500 responses when a server error occurs. If 'debug' is set, then traceback responses will be returned, otherwise the designated 'handler' will be called. This middleware class should generally be used to wrap *everything* else up, so that unhandled exceptions anywhere in the stack always result in an appropriate 500 response. """ def __init__( self, app: ASGIApp, handler: ExceptionHandler | None = None, debug: bool = False, ) -> None: self.app = app self.handler = handler self.debug = debug async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: if scope["type"] != "http": await self.app(scope, receive, send) return response_started = False async def _send(message: Message) -> None: nonlocal response_started, send if message["type"] == "http.response.start": response_started = True await send(message) try: await self.app(scope, receive, _send) except Exception as exc: request = Request(scope) if self.debug: # In debug mode, return traceback responses. response = self.debug_response(request, exc) elif self.handler is None: # Use our default 500 error handler. response = self.error_response(request, exc) else: # Use an installed 500 error handler. if is_async_callable(self.handler): response = await self.handler(request, exc) else: response = await run_in_threadpool(self.handler, request, exc) if not response_started: await response(scope, receive, send) # We always continue to raise the exception. # This allows servers to log the error, or allows test clients # to optionally raise the error within the test case. raise exc def format_line(self, index: int, line: str, frame_lineno: int, frame_index: int) -> str: values = { # HTML escape - line could contain < or > "line": html.escape(line).replace(" ", " "), "lineno": (frame_lineno - frame_index) + index, } if index != frame_index: return LINE.format(**values) return CENTER_LINE.format(**values) def generate_frame_html(self, frame: inspect.FrameInfo, is_collapsed: bool) -> str: code_context = "".join( self.format_line( index, line, frame.lineno, frame.index, # type: ignore[arg-type] ) for index, line in enumerate(frame.code_context or []) ) values = { # HTML escape - filename could contain < or >, especially if it's a virtual # file e.g. in the REPL "frame_filename": html.escape(frame.filename), "frame_lineno": frame.lineno, # HTML escape - if you try very hard it's possible to name a function with < # or > "frame_name": html.escape(frame.function), "code_context": code_context, "collapsed": "collapsed" if is_collapsed else "", "collapse_button": "+" if is_collapsed else "‒", } return FRAME_TEMPLATE.format(**values) def generate_html(self, exc: Exception, limit: int = 7) -> str: traceback_obj = traceback.TracebackException.from_exception(exc, capture_locals=True) exc_html = "" is_collapsed = False exc_traceback = exc.__traceback__ if exc_traceback is not None: frames = inspect.getinnerframes(exc_traceback, limit) for frame in reversed(frames): exc_html += self.generate_frame_html(frame, is_collapsed) is_collapsed = True if sys.version_info >= (3, 13): # pragma: no cover exc_type_str = traceback_obj.exc_type_str else: # pragma: no cover exc_type_str = traceback_obj.exc_type.__name__ # escape error class and text error = f"{html.escape(exc_type_str)}: {html.escape(str(traceback_obj))}" return TEMPLATE.format(styles=STYLES, js=JS, error=error, exc_html=exc_html) def generate_plain_text(self, exc: Exception) -> str: return "".join(traceback.format_exception(type(exc), exc, exc.__traceback__)) def debug_response(self, request: Request, exc: Exception) -> Response: accept = request.headers.get("accept", "") if "text/html" in accept: content = self.generate_html(exc) return HTMLResponse(content, status_code=500) content = self.generate_plain_text(exc) return PlainTextResponse(content, status_code=500) def error_response(self, request: Request, exc: Exception) -> Response: return PlainTextResponse("Internal Server Error", status_code=500) starlette-0.50.0/starlette/middleware/exceptions.py000066400000000000000000000053401510142272400224620ustar00rootroot00000000000000from __future__ import annotations from collections.abc import Mapping from typing import Any from starlette._exception_handler import ( ExceptionHandlers, StatusHandlers, wrap_app_handling_exceptions, ) from starlette.exceptions import HTTPException, WebSocketException from starlette.requests import Request from starlette.responses import PlainTextResponse, Response from starlette.types import ASGIApp, ExceptionHandler, Receive, Scope, Send from starlette.websockets import WebSocket class ExceptionMiddleware: def __init__( self, app: ASGIApp, handlers: Mapping[Any, ExceptionHandler] | None = None, debug: bool = False, ) -> None: self.app = app self.debug = debug # TODO: We ought to handle 404 cases if debug is set. self._status_handlers: StatusHandlers = {} self._exception_handlers: ExceptionHandlers = { HTTPException: self.http_exception, WebSocketException: self.websocket_exception, } if handlers is not None: # pragma: no branch for key, value in handlers.items(): self.add_exception_handler(key, value) def add_exception_handler( self, exc_class_or_status_code: int | type[Exception], handler: ExceptionHandler, ) -> None: if isinstance(exc_class_or_status_code, int): self._status_handlers[exc_class_or_status_code] = handler else: assert issubclass(exc_class_or_status_code, Exception) self._exception_handlers[exc_class_or_status_code] = handler async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: if scope["type"] not in ("http", "websocket"): await self.app(scope, receive, send) return scope["starlette.exception_handlers"] = ( self._exception_handlers, self._status_handlers, ) conn: Request | WebSocket if scope["type"] == "http": conn = Request(scope, receive, send) else: conn = WebSocket(scope, receive, send) await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) async def http_exception(self, request: Request, exc: Exception) -> Response: assert isinstance(exc, HTTPException) if exc.status_code in {204, 304}: return Response(status_code=exc.status_code, headers=exc.headers) return PlainTextResponse(exc.detail, status_code=exc.status_code, headers=exc.headers) async def websocket_exception(self, websocket: WebSocket, exc: Exception) -> None: assert isinstance(exc, WebSocketException) await websocket.close(code=exc.code, reason=exc.reason) # pragma: no cover starlette-0.50.0/starlette/middleware/gzip.py000066400000000000000000000134131510142272400212520ustar00rootroot00000000000000import gzip import io from typing import NoReturn from starlette.datastructures import Headers, MutableHeaders from starlette.types import ASGIApp, Message, Receive, Scope, Send DEFAULT_EXCLUDED_CONTENT_TYPES = ("text/event-stream",) class GZipMiddleware: def __init__(self, app: ASGIApp, minimum_size: int = 500, compresslevel: int = 9) -> None: self.app = app self.minimum_size = minimum_size self.compresslevel = compresslevel async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: if scope["type"] != "http": # pragma: no cover await self.app(scope, receive, send) return headers = Headers(scope=scope) responder: ASGIApp if "gzip" in headers.get("Accept-Encoding", ""): responder = GZipResponder(self.app, self.minimum_size, compresslevel=self.compresslevel) else: responder = IdentityResponder(self.app, self.minimum_size) await responder(scope, receive, send) class IdentityResponder: content_encoding: str def __init__(self, app: ASGIApp, minimum_size: int) -> None: self.app = app self.minimum_size = minimum_size self.send: Send = unattached_send self.initial_message: Message = {} self.started = False self.content_encoding_set = False self.content_type_is_excluded = False async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: self.send = send await self.app(scope, receive, self.send_with_compression) async def send_with_compression(self, message: Message) -> None: message_type = message["type"] if message_type == "http.response.start": # Don't send the initial message until we've determined how to # modify the outgoing headers correctly. self.initial_message = message headers = Headers(raw=self.initial_message["headers"]) self.content_encoding_set = "content-encoding" in headers self.content_type_is_excluded = headers.get("content-type", "").startswith(DEFAULT_EXCLUDED_CONTENT_TYPES) elif message_type == "http.response.body" and (self.content_encoding_set or self.content_type_is_excluded): if not self.started: self.started = True await self.send(self.initial_message) await self.send(message) elif message_type == "http.response.body" and not self.started: self.started = True body = message.get("body", b"") more_body = message.get("more_body", False) if len(body) < self.minimum_size and not more_body: # Don't apply compression to small outgoing responses. await self.send(self.initial_message) await self.send(message) elif not more_body: # Standard response. body = self.apply_compression(body, more_body=False) headers = MutableHeaders(raw=self.initial_message["headers"]) headers.add_vary_header("Accept-Encoding") if body != message["body"]: headers["Content-Encoding"] = self.content_encoding headers["Content-Length"] = str(len(body)) message["body"] = body await self.send(self.initial_message) await self.send(message) else: # Initial body in streaming response. body = self.apply_compression(body, more_body=True) headers = MutableHeaders(raw=self.initial_message["headers"]) headers.add_vary_header("Accept-Encoding") if body != message["body"]: headers["Content-Encoding"] = self.content_encoding del headers["Content-Length"] message["body"] = body await self.send(self.initial_message) await self.send(message) elif message_type == "http.response.body": # Remaining body in streaming response. body = message.get("body", b"") more_body = message.get("more_body", False) message["body"] = self.apply_compression(body, more_body=more_body) await self.send(message) elif message_type == "http.response.pathsend": # pragma: no branch # Don't apply GZip to pathsend responses await self.send(self.initial_message) await self.send(message) def apply_compression(self, body: bytes, *, more_body: bool) -> bytes: """Apply compression on the response body. If more_body is False, any compression file should be closed. If it isn't, it won't be closed automatically until all background tasks complete. """ return body class GZipResponder(IdentityResponder): content_encoding = "gzip" def __init__(self, app: ASGIApp, minimum_size: int, compresslevel: int = 9) -> None: super().__init__(app, minimum_size) self.gzip_buffer = io.BytesIO() self.gzip_file = gzip.GzipFile(mode="wb", fileobj=self.gzip_buffer, compresslevel=compresslevel) async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: with self.gzip_buffer, self.gzip_file: await super().__call__(scope, receive, send) def apply_compression(self, body: bytes, *, more_body: bool) -> bytes: self.gzip_file.write(body) if not more_body: self.gzip_file.close() body = self.gzip_buffer.getvalue() self.gzip_buffer.seek(0) self.gzip_buffer.truncate() return body async def unattached_send(message: Message) -> NoReturn: raise RuntimeError("send awaitable not set") # pragma: no cover starlette-0.50.0/starlette/middleware/httpsredirect.py000066400000000000000000000015201510142272400231610ustar00rootroot00000000000000from starlette.datastructures import URL from starlette.responses import RedirectResponse from starlette.types import ASGIApp, Receive, Scope, Send class HTTPSRedirectMiddleware: def __init__(self, app: ASGIApp) -> None: self.app = app async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: if scope["type"] in ("http", "websocket") and scope["scheme"] in ("http", "ws"): url = URL(scope=scope) redirect_scheme = {"http": "https", "ws": "wss"}[url.scheme] netloc = url.hostname if url.port in (80, 443) else url.netloc url = url.replace(scheme=redirect_scheme, netloc=netloc) response = RedirectResponse(url, status_code=307) await response(scope, receive, send) else: await self.app(scope, receive, send) starlette-0.50.0/starlette/middleware/sessions.py000066400000000000000000000067641510142272400221620ustar00rootroot00000000000000from __future__ import annotations import json from base64 import b64decode, b64encode from typing import Literal import itsdangerous from itsdangerous.exc import BadSignature from starlette.datastructures import MutableHeaders, Secret from starlette.requests import HTTPConnection from starlette.types import ASGIApp, Message, Receive, Scope, Send class SessionMiddleware: def __init__( self, app: ASGIApp, secret_key: str | Secret, session_cookie: str = "session", max_age: int | None = 14 * 24 * 60 * 60, # 14 days, in seconds path: str = "/", same_site: Literal["lax", "strict", "none"] = "lax", https_only: bool = False, domain: str | None = None, ) -> None: self.app = app self.signer = itsdangerous.TimestampSigner(str(secret_key)) self.session_cookie = session_cookie self.max_age = max_age self.path = path self.security_flags = "httponly; samesite=" + same_site if https_only: # Secure flag can be used with HTTPS only self.security_flags += "; secure" if domain is not None: self.security_flags += f"; domain={domain}" async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: if scope["type"] not in ("http", "websocket"): # pragma: no cover await self.app(scope, receive, send) return connection = HTTPConnection(scope) initial_session_was_empty = True if self.session_cookie in connection.cookies: data = connection.cookies[self.session_cookie].encode("utf-8") try: data = self.signer.unsign(data, max_age=self.max_age) scope["session"] = json.loads(b64decode(data)) initial_session_was_empty = False except BadSignature: scope["session"] = {} else: scope["session"] = {} async def send_wrapper(message: Message) -> None: if message["type"] == "http.response.start": if scope["session"]: # We have session data to persist. data = b64encode(json.dumps(scope["session"]).encode("utf-8")) data = self.signer.sign(data) headers = MutableHeaders(scope=message) header_value = "{session_cookie}={data}; path={path}; {max_age}{security_flags}".format( session_cookie=self.session_cookie, data=data.decode("utf-8"), path=self.path, max_age=f"Max-Age={self.max_age}; " if self.max_age else "", security_flags=self.security_flags, ) headers.append("Set-Cookie", header_value) elif not initial_session_was_empty: # The session has been cleared. headers = MutableHeaders(scope=message) header_value = "{session_cookie}={data}; path={path}; {expires}{security_flags}".format( session_cookie=self.session_cookie, data="null", path=self.path, expires="expires=Thu, 01 Jan 1970 00:00:00 GMT; ", security_flags=self.security_flags, ) headers.append("Set-Cookie", header_value) await send(message) await self.app(scope, receive, send_wrapper) starlette-0.50.0/starlette/middleware/trustedhost.py000066400000000000000000000042531510142272400226730ustar00rootroot00000000000000from __future__ import annotations from collections.abc import Sequence from starlette.datastructures import URL, Headers from starlette.responses import PlainTextResponse, RedirectResponse, Response from starlette.types import ASGIApp, Receive, Scope, Send ENFORCE_DOMAIN_WILDCARD = "Domain wildcard patterns must be like '*.example.com'." class TrustedHostMiddleware: def __init__( self, app: ASGIApp, allowed_hosts: Sequence[str] | None = None, www_redirect: bool = True, ) -> None: if allowed_hosts is None: allowed_hosts = ["*"] for pattern in allowed_hosts: assert "*" not in pattern[1:], ENFORCE_DOMAIN_WILDCARD if pattern.startswith("*") and pattern != "*": assert pattern.startswith("*."), ENFORCE_DOMAIN_WILDCARD self.app = app self.allowed_hosts = list(allowed_hosts) self.allow_any = "*" in allowed_hosts self.www_redirect = www_redirect async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: if self.allow_any or scope["type"] not in ( "http", "websocket", ): # pragma: no cover await self.app(scope, receive, send) return headers = Headers(scope=scope) host = headers.get("host", "").split(":")[0] is_valid_host = False found_www_redirect = False for pattern in self.allowed_hosts: if host == pattern or (pattern.startswith("*") and host.endswith(pattern[1:])): is_valid_host = True break elif "www." + host == pattern: found_www_redirect = True if is_valid_host: await self.app(scope, receive, send) else: response: Response if found_www_redirect and self.www_redirect: url = URL(scope=scope) redirect_url = url.replace(netloc="www." + url.netloc) response = RedirectResponse(url=str(redirect_url)) else: response = PlainTextResponse("Invalid host header", status_code=400) await response(scope, receive, send) starlette-0.50.0/starlette/middleware/wsgi.py000066400000000000000000000123461510142272400212560ustar00rootroot00000000000000from __future__ import annotations import io import math import sys import warnings from collections.abc import Callable, MutableMapping from typing import Any import anyio from anyio.abc import ObjectReceiveStream, ObjectSendStream from starlette.types import Receive, Scope, Send warnings.warn( "starlette.middleware.wsgi is deprecated and will be removed in a future release. " "Please refer to https://github.com/abersheeran/a2wsgi as a replacement.", DeprecationWarning, ) def build_environ(scope: Scope, body: bytes) -> dict[str, Any]: """ Builds a scope and request body into a WSGI environ object. """ script_name = scope.get("root_path", "").encode("utf8").decode("latin1") path_info = scope["path"].encode("utf8").decode("latin1") if path_info.startswith(script_name): path_info = path_info[len(script_name) :] environ = { "REQUEST_METHOD": scope["method"], "SCRIPT_NAME": script_name, "PATH_INFO": path_info, "QUERY_STRING": scope["query_string"].decode("ascii"), "SERVER_PROTOCOL": f"HTTP/{scope['http_version']}", "wsgi.version": (1, 0), "wsgi.url_scheme": scope.get("scheme", "http"), "wsgi.input": io.BytesIO(body), "wsgi.errors": sys.stdout, "wsgi.multithread": True, "wsgi.multiprocess": True, "wsgi.run_once": False, } # Get server name and port - required in WSGI, not in ASGI server = scope.get("server") or ("localhost", 80) environ["SERVER_NAME"] = server[0] environ["SERVER_PORT"] = server[1] # Get client IP address if scope.get("client"): environ["REMOTE_ADDR"] = scope["client"][0] # Go through headers and make them into environ entries for name, value in scope.get("headers", []): name = name.decode("latin1") if name == "content-length": corrected_name = "CONTENT_LENGTH" elif name == "content-type": corrected_name = "CONTENT_TYPE" else: corrected_name = f"HTTP_{name}".upper().replace("-", "_") # HTTPbis say only ASCII chars are allowed in headers, but we latin1 just in # case value = value.decode("latin1") if corrected_name in environ: value = environ[corrected_name] + "," + value environ[corrected_name] = value return environ class WSGIMiddleware: def __init__(self, app: Callable[..., Any]) -> None: self.app = app async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: assert scope["type"] == "http" responder = WSGIResponder(self.app, scope) await responder(receive, send) class WSGIResponder: stream_send: ObjectSendStream[MutableMapping[str, Any]] stream_receive: ObjectReceiveStream[MutableMapping[str, Any]] def __init__(self, app: Callable[..., Any], scope: Scope) -> None: self.app = app self.scope = scope self.status = None self.response_headers = None self.stream_send, self.stream_receive = anyio.create_memory_object_stream(math.inf) self.response_started = False self.exc_info: Any = None async def __call__(self, 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) environ = build_environ(self.scope, body) async with anyio.create_task_group() as task_group: task_group.start_soon(self.sender, send) async with self.stream_send: await anyio.to_thread.run_sync(self.wsgi, environ, self.start_response) if self.exc_info is not None: raise self.exc_info[0].with_traceback(self.exc_info[1], self.exc_info[2]) async def sender(self, send: Send) -> None: async with self.stream_receive: async for message in self.stream_receive: await send(message) def start_response( self, status: str, response_headers: list[tuple[str, str]], exc_info: Any = None, ) -> None: self.exc_info = exc_info if not self.response_started: # pragma: no branch self.response_started = True status_code_string, _ = status.split(" ", 1) status_code = int(status_code_string) headers = [ (name.strip().encode("ascii").lower(), value.strip().encode("ascii")) for name, value in response_headers ] anyio.from_thread.run( self.stream_send.send, { "type": "http.response.start", "status": status_code, "headers": headers, }, ) def wsgi( self, environ: dict[str, Any], start_response: Callable[..., Any], ) -> None: for chunk in self.app(environ, start_response): anyio.from_thread.run( self.stream_send.send, {"type": "http.response.body", "body": chunk, "more_body": True}, ) anyio.from_thread.run(self.stream_send.send, {"type": "http.response.body", "body": b""}) starlette-0.50.0/starlette/py.typed000066400000000000000000000000001510142272400172750ustar00rootroot00000000000000starlette-0.50.0/starlette/requests.py000066400000000000000000000266641510142272400200530ustar00rootroot00000000000000from __future__ import annotations import json from collections.abc import AsyncGenerator, Iterator, Mapping from http import cookies as http_cookies from typing import TYPE_CHECKING, Any, NoReturn, cast import anyio from starlette._utils import AwaitableOrContextManager, AwaitableOrContextManagerWrapper from starlette.datastructures import URL, Address, FormData, Headers, QueryParams, State from starlette.exceptions import HTTPException from starlette.formparsers import FormParser, MultiPartException, MultiPartParser from starlette.types import Message, Receive, Scope, Send if TYPE_CHECKING: from python_multipart.multipart import parse_options_header from starlette.applications import Starlette from starlette.routing import Router else: try: try: from python_multipart.multipart import parse_options_header except ModuleNotFoundError: # pragma: no cover from multipart.multipart import parse_options_header except ModuleNotFoundError: # pragma: no cover parse_options_header = None SERVER_PUSH_HEADERS_TO_COPY = { "accept", "accept-encoding", "accept-language", "cache-control", "user-agent", } def cookie_parser(cookie_string: str) -> dict[str, str]: """ This function parses a ``Cookie`` HTTP header into a dict of key/value pairs. It attempts to mimic browser cookie parsing behavior: browsers and web servers frequently disregard the spec (RFC 6265) when setting and reading cookies, so we attempt to suit the common scenarios here. This function has been adapted from Django 3.1.0. Note: we are explicitly _NOT_ using `SimpleCookie.load` because it is based on an outdated spec and will fail on lots of input we want to support """ cookie_dict: dict[str, str] = {} for chunk in cookie_string.split(";"): if "=" in chunk: key, val = chunk.split("=", 1) else: # Assume an empty name per # https://bugzilla.mozilla.org/show_bug.cgi?id=169091 key, val = "", chunk key, val = key.strip(), val.strip() if key or val: # unquote using Python's algorithm. cookie_dict[key] = http_cookies._unquote(val) return cookie_dict class ClientDisconnect(Exception): pass class HTTPConnection(Mapping[str, Any]): """ A base class for incoming HTTP connections, that is used to provide any functionality that is common to both `Request` and `WebSocket`. """ def __init__(self, scope: Scope, receive: Receive | None = None) -> None: assert scope["type"] in ("http", "websocket") self.scope = scope def __getitem__(self, key: str) -> Any: return self.scope[key] def __iter__(self) -> Iterator[str]: return iter(self.scope) def __len__(self) -> int: return len(self.scope) # Don't use the `abc.Mapping.__eq__` implementation. # Connection instances should never be considered equal # unless `self is other`. __eq__ = object.__eq__ __hash__ = object.__hash__ @property def app(self) -> Any: return self.scope["app"] @property def url(self) -> URL: if not hasattr(self, "_url"): # pragma: no branch self._url = URL(scope=self.scope) return self._url @property def base_url(self) -> URL: if not hasattr(self, "_base_url"): base_url_scope = dict(self.scope) # This is used by request.url_for, it might be used inside a Mount which # would have its own child scope with its own root_path, but the base URL # for url_for should still be the top level app root path. app_root_path = base_url_scope.get("app_root_path", base_url_scope.get("root_path", "")) path = app_root_path if not path.endswith("/"): path += "/" base_url_scope["path"] = path base_url_scope["query_string"] = b"" base_url_scope["root_path"] = app_root_path self._base_url = URL(scope=base_url_scope) return self._base_url @property def headers(self) -> Headers: if not hasattr(self, "_headers"): self._headers = Headers(scope=self.scope) return self._headers @property def query_params(self) -> QueryParams: if not hasattr(self, "_query_params"): # pragma: no branch self._query_params = QueryParams(self.scope["query_string"]) return self._query_params @property def path_params(self) -> dict[str, Any]: return self.scope.get("path_params", {}) @property def cookies(self) -> dict[str, str]: if not hasattr(self, "_cookies"): cookies: dict[str, str] = {} cookie_headers = self.headers.getlist("cookie") for header in cookie_headers: cookies.update(cookie_parser(header)) self._cookies = cookies return self._cookies @property def client(self) -> Address | None: # client is a 2 item tuple of (host, port), None if missing host_port = self.scope.get("client") if host_port is not None: return Address(*host_port) return None @property def session(self) -> dict[str, Any]: assert "session" in self.scope, "SessionMiddleware must be installed to access request.session" return self.scope["session"] # type: ignore[no-any-return] @property def auth(self) -> Any: assert "auth" in self.scope, "AuthenticationMiddleware must be installed to access request.auth" return self.scope["auth"] @property def user(self) -> Any: assert "user" in self.scope, "AuthenticationMiddleware must be installed to access request.user" return self.scope["user"] @property def state(self) -> State: if not hasattr(self, "_state"): # Ensure 'state' has an empty dict if it's not already populated. self.scope.setdefault("state", {}) # Create a state instance with a reference to the dict in which it should # store info self._state = State(self.scope["state"]) return self._state def url_for(self, name: str, /, **path_params: Any) -> URL: url_path_provider: Router | Starlette | None = self.scope.get("router") or self.scope.get("app") if url_path_provider is None: raise RuntimeError("The `url_for` method can only be used inside a Starlette application or with a router.") url_path = url_path_provider.url_path_for(name, **path_params) return url_path.make_absolute_url(base_url=self.base_url) async def empty_receive() -> NoReturn: raise RuntimeError("Receive channel has not been made available") async def empty_send(message: Message) -> NoReturn: raise RuntimeError("Send channel has not been made available") class Request(HTTPConnection): _form: FormData | None def __init__(self, scope: Scope, receive: Receive = empty_receive, send: Send = empty_send): super().__init__(scope) assert scope["type"] == "http" self._receive = receive self._send = send self._stream_consumed = False self._is_disconnected = False self._form = None @property def method(self) -> str: return cast(str, self.scope["method"]) @property def receive(self) -> Receive: return self._receive async def stream(self) -> AsyncGenerator[bytes, None]: if hasattr(self, "_body"): yield self._body yield b"" return if self._stream_consumed: raise RuntimeError("Stream consumed") while not self._stream_consumed: message = await self._receive() if message["type"] == "http.request": body = message.get("body", b"") if not message.get("more_body", False): self._stream_consumed = True if body: yield body elif message["type"] == "http.disconnect": # pragma: no branch self._is_disconnected = True raise ClientDisconnect() yield b"" async def body(self) -> bytes: if not hasattr(self, "_body"): chunks: list[bytes] = [] async for chunk in self.stream(): chunks.append(chunk) self._body = b"".join(chunks) return self._body async def json(self) -> Any: if not hasattr(self, "_json"): # pragma: no branch body = await self.body() self._json = json.loads(body) return self._json async def _get_form( self, *, max_files: int | float = 1000, max_fields: int | float = 1000, max_part_size: int = 1024 * 1024, ) -> FormData: if self._form is None: # pragma: no branch assert parse_options_header is not None, ( "The `python-multipart` library must be installed to use form parsing." ) content_type_header = self.headers.get("Content-Type") content_type: bytes content_type, _ = parse_options_header(content_type_header) if content_type == b"multipart/form-data": try: multipart_parser = MultiPartParser( self.headers, self.stream(), max_files=max_files, max_fields=max_fields, max_part_size=max_part_size, ) self._form = await multipart_parser.parse() except MultiPartException as exc: if "app" in self.scope: raise HTTPException(status_code=400, detail=exc.message) raise exc elif content_type == b"application/x-www-form-urlencoded": form_parser = FormParser(self.headers, self.stream()) self._form = await form_parser.parse() else: self._form = FormData() return self._form def form( self, *, max_files: int | float = 1000, max_fields: int | float = 1000, max_part_size: int = 1024 * 1024, ) -> AwaitableOrContextManager[FormData]: return AwaitableOrContextManagerWrapper( self._get_form(max_files=max_files, max_fields=max_fields, max_part_size=max_part_size) ) async def close(self) -> None: if self._form is not None: # pragma: no branch await self._form.close() async def is_disconnected(self) -> bool: if not self._is_disconnected: message: Message = {} # If message isn't immediately available, move on with anyio.CancelScope() as cs: cs.cancel() message = await self._receive() if message.get("type") == "http.disconnect": self._is_disconnected = True return self._is_disconnected async def send_push_promise(self, path: str) -> None: if "http.response.push" in self.scope.get("extensions", {}): raw_headers: list[tuple[bytes, bytes]] = [] for name in SERVER_PUSH_HEADERS_TO_COPY: for value in self.headers.getlist(name): raw_headers.append((name.encode("latin-1"), value.encode("latin-1"))) await self._send({"type": "http.response.push", "path": path, "headers": raw_headers}) starlette-0.50.0/starlette/responses.py000066400000000000000000000516671510142272400202220ustar00rootroot00000000000000from __future__ import annotations import hashlib import http.cookies import json import os import stat import sys import warnings from collections.abc import AsyncIterable, Awaitable, Callable, Iterable, Mapping, Sequence from datetime import datetime from email.utils import format_datetime, formatdate from functools import partial from mimetypes import guess_type from secrets import token_hex from typing import Any, Literal from urllib.parse import quote import anyio import anyio.to_thread from starlette._utils import collapse_excgroups from starlette.background import BackgroundTask from starlette.concurrency import iterate_in_threadpool from starlette.datastructures import URL, Headers, MutableHeaders from starlette.requests import ClientDisconnect from starlette.types import Receive, Scope, Send class Response: media_type = None charset = "utf-8" def __init__( self, content: Any = None, status_code: int = 200, headers: Mapping[str, str] | None = None, media_type: str | None = None, background: BackgroundTask | None = None, ) -> None: self.status_code = status_code if media_type is not None: self.media_type = media_type self.background = background self.body = self.render(content) self.init_headers(headers) def render(self, content: Any) -> bytes | memoryview: if content is None: return b"" if isinstance(content, bytes | memoryview): return content return content.encode(self.charset) # type: ignore def init_headers(self, headers: Mapping[str, str] | None = None) -> None: if headers is None: raw_headers: list[tuple[bytes, bytes]] = [] populate_content_length = True populate_content_type = True else: raw_headers = [(k.lower().encode("latin-1"), v.encode("latin-1")) for k, v in headers.items()] keys = [h[0] for h in raw_headers] populate_content_length = b"content-length" not in keys populate_content_type = b"content-type" not in keys body = getattr(self, "body", None) if ( body is not None and populate_content_length and not (self.status_code < 200 or self.status_code in (204, 304)) ): content_length = str(len(body)) raw_headers.append((b"content-length", content_length.encode("latin-1"))) content_type = self.media_type if content_type is not None and populate_content_type: if content_type.startswith("text/") and "charset=" not in content_type.lower(): content_type += "; charset=" + self.charset raw_headers.append((b"content-type", content_type.encode("latin-1"))) self.raw_headers = raw_headers @property def headers(self) -> MutableHeaders: if not hasattr(self, "_headers"): self._headers = MutableHeaders(raw=self.raw_headers) return self._headers def set_cookie( self, key: str, value: str = "", max_age: int | None = None, expires: datetime | str | int | None = None, path: str | None = "/", domain: str | None = None, secure: bool = False, httponly: bool = False, samesite: Literal["lax", "strict", "none"] | None = "lax", partitioned: bool = False, ) -> None: cookie: http.cookies.BaseCookie[str] = http.cookies.SimpleCookie() cookie[key] = value if max_age is not None: cookie[key]["max-age"] = max_age if expires is not None: if isinstance(expires, datetime): cookie[key]["expires"] = format_datetime(expires, usegmt=True) else: cookie[key]["expires"] = expires if path is not None: cookie[key]["path"] = path if domain is not None: cookie[key]["domain"] = domain if secure: cookie[key]["secure"] = True if httponly: cookie[key]["httponly"] = True if samesite is not None: assert samesite.lower() in [ "strict", "lax", "none", ], "samesite must be either 'strict', 'lax' or 'none'" cookie[key]["samesite"] = samesite if partitioned: if sys.version_info < (3, 14): raise ValueError("Partitioned cookies are only supported in Python 3.14 and above.") # pragma: no cover cookie[key]["partitioned"] = True # pragma: no cover cookie_val = cookie.output(header="").strip() self.raw_headers.append((b"set-cookie", cookie_val.encode("latin-1"))) def delete_cookie( self, key: str, path: str = "/", domain: str | None = None, secure: bool = False, httponly: bool = False, samesite: Literal["lax", "strict", "none"] | None = "lax", ) -> None: self.set_cookie( key, max_age=0, expires=0, path=path, domain=domain, secure=secure, httponly=httponly, samesite=samesite, ) async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: prefix = "websocket." if scope["type"] == "websocket" else "" await send( { "type": prefix + "http.response.start", "status": self.status_code, "headers": self.raw_headers, } ) await send({"type": prefix + "http.response.body", "body": self.body}) if self.background is not None: await self.background() class HTMLResponse(Response): media_type = "text/html" class PlainTextResponse(Response): media_type = "text/plain" class JSONResponse(Response): media_type = "application/json" def __init__( self, content: Any, status_code: int = 200, headers: Mapping[str, str] | None = None, media_type: str | None = None, background: BackgroundTask | None = None, ) -> None: super().__init__(content, status_code, headers, media_type, background) def render(self, content: Any) -> bytes: return json.dumps( content, ensure_ascii=False, allow_nan=False, indent=None, separators=(",", ":"), ).encode("utf-8") class RedirectResponse(Response): def __init__( self, url: str | URL, status_code: int = 307, headers: Mapping[str, str] | None = None, background: BackgroundTask | None = None, ) -> None: super().__init__(content=b"", status_code=status_code, headers=headers, background=background) self.headers["location"] = quote(str(url), safe=":/%#?=@[]!$&'()*+,;") Content = str | bytes | memoryview SyncContentStream = Iterable[Content] AsyncContentStream = AsyncIterable[Content] ContentStream = AsyncContentStream | SyncContentStream class StreamingResponse(Response): body_iterator: AsyncContentStream def __init__( self, content: ContentStream, status_code: int = 200, headers: Mapping[str, str] | None = None, media_type: str | None = None, background: BackgroundTask | None = None, ) -> None: if isinstance(content, AsyncIterable): self.body_iterator = content else: self.body_iterator = iterate_in_threadpool(content) self.status_code = status_code self.media_type = self.media_type if media_type is None else media_type self.background = background self.init_headers(headers) async def listen_for_disconnect(self, receive: Receive) -> None: while True: message = await receive() if message["type"] == "http.disconnect": break async def stream_response(self, send: Send) -> None: await send( { "type": "http.response.start", "status": self.status_code, "headers": self.raw_headers, } ) async for chunk in self.body_iterator: if not isinstance(chunk, bytes | memoryview): chunk = chunk.encode(self.charset) await send({"type": "http.response.body", "body": chunk, "more_body": True}) await send({"type": "http.response.body", "body": b"", "more_body": False}) async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: spec_version = tuple(map(int, scope.get("asgi", {}).get("spec_version", "2.0").split("."))) if spec_version >= (2, 4): try: await self.stream_response(send) except OSError: raise ClientDisconnect() else: with collapse_excgroups(): async with anyio.create_task_group() as task_group: async def wrap(func: Callable[[], Awaitable[None]]) -> None: await func() task_group.cancel_scope.cancel() task_group.start_soon(wrap, partial(self.stream_response, send)) await wrap(partial(self.listen_for_disconnect, receive)) if self.background is not None: await self.background() class MalformedRangeHeader(Exception): def __init__(self, content: str = "Malformed range header.") -> None: self.content = content class RangeNotSatisfiable(Exception): def __init__(self, max_size: int) -> None: self.max_size = max_size class FileResponse(Response): chunk_size = 64 * 1024 def __init__( self, path: str | os.PathLike[str], status_code: int = 200, headers: Mapping[str, str] | None = None, media_type: str | None = None, background: BackgroundTask | None = None, filename: str | None = None, stat_result: os.stat_result | None = None, method: str | None = None, content_disposition_type: str = "attachment", ) -> None: self.path = path self.status_code = status_code self.filename = filename if method is not None: warnings.warn( "The 'method' parameter is not used, and it will be removed.", DeprecationWarning, ) if media_type is None: media_type = guess_type(filename or path)[0] or "text/plain" self.media_type = media_type self.background = background self.init_headers(headers) self.headers.setdefault("accept-ranges", "bytes") if self.filename is not None: content_disposition_filename = quote(self.filename) if content_disposition_filename != self.filename: content_disposition = f"{content_disposition_type}; filename*=utf-8''{content_disposition_filename}" else: content_disposition = f'{content_disposition_type}; filename="{self.filename}"' self.headers.setdefault("content-disposition", content_disposition) self.stat_result = stat_result if stat_result is not None: self.set_stat_headers(stat_result) def set_stat_headers(self, stat_result: os.stat_result) -> None: content_length = str(stat_result.st_size) last_modified = formatdate(stat_result.st_mtime, usegmt=True) etag_base = str(stat_result.st_mtime) + "-" + str(stat_result.st_size) etag = f'"{hashlib.md5(etag_base.encode(), usedforsecurity=False).hexdigest()}"' self.headers.setdefault("content-length", content_length) self.headers.setdefault("last-modified", last_modified) self.headers.setdefault("etag", etag) async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: send_header_only: bool = scope["method"].upper() == "HEAD" send_pathsend: bool = "http.response.pathsend" in scope.get("extensions", {}) if self.stat_result is None: try: stat_result = await anyio.to_thread.run_sync(os.stat, self.path) self.set_stat_headers(stat_result) except FileNotFoundError: raise RuntimeError(f"File at path {self.path} does not exist.") else: mode = stat_result.st_mode if not stat.S_ISREG(mode): raise RuntimeError(f"File at path {self.path} is not a file.") else: stat_result = self.stat_result headers = Headers(scope=scope) http_range = headers.get("range") http_if_range = headers.get("if-range") if http_range is None or (http_if_range is not None and not self._should_use_range(http_if_range)): await self._handle_simple(send, send_header_only, send_pathsend) else: try: ranges = self._parse_range_header(http_range, stat_result.st_size) except MalformedRangeHeader as exc: return await PlainTextResponse(exc.content, status_code=400)(scope, receive, send) except RangeNotSatisfiable as exc: response = PlainTextResponse(status_code=416, headers={"Content-Range": f"*/{exc.max_size}"}) return await response(scope, receive, send) if len(ranges) == 1: start, end = ranges[0] await self._handle_single_range(send, start, end, stat_result.st_size, send_header_only) else: await self._handle_multiple_ranges(send, ranges, stat_result.st_size, send_header_only) if self.background is not None: await self.background() async def _handle_simple(self, send: Send, send_header_only: bool, send_pathsend: bool) -> None: await send({"type": "http.response.start", "status": self.status_code, "headers": self.raw_headers}) if send_header_only: await send({"type": "http.response.body", "body": b"", "more_body": False}) elif send_pathsend: await send({"type": "http.response.pathsend", "path": str(self.path)}) else: async with await anyio.open_file(self.path, mode="rb") as file: more_body = True while more_body: chunk = await file.read(self.chunk_size) more_body = len(chunk) == self.chunk_size await send({"type": "http.response.body", "body": chunk, "more_body": more_body}) async def _handle_single_range( self, send: Send, start: int, end: int, file_size: int, send_header_only: bool ) -> None: self.headers["content-range"] = f"bytes {start}-{end - 1}/{file_size}" self.headers["content-length"] = str(end - start) await send({"type": "http.response.start", "status": 206, "headers": self.raw_headers}) if send_header_only: await send({"type": "http.response.body", "body": b"", "more_body": False}) else: async with await anyio.open_file(self.path, mode="rb") as file: await file.seek(start) more_body = True while more_body: chunk = await file.read(min(self.chunk_size, end - start)) start += len(chunk) more_body = len(chunk) == self.chunk_size and start < end await send({"type": "http.response.body", "body": chunk, "more_body": more_body}) async def _handle_multiple_ranges( self, send: Send, ranges: list[tuple[int, int]], file_size: int, send_header_only: bool, ) -> None: # In firefox and chrome, they use boundary with 95-96 bits entropy (that's roughly 13 bytes). boundary = token_hex(13) content_length, header_generator = self.generate_multipart( ranges, boundary, file_size, self.headers["content-type"] ) self.headers["content-range"] = f"multipart/byteranges; boundary={boundary}" self.headers["content-length"] = str(content_length) await send({"type": "http.response.start", "status": 206, "headers": self.raw_headers}) if send_header_only: await send({"type": "http.response.body", "body": b"", "more_body": False}) else: async with await anyio.open_file(self.path, mode="rb") as file: for start, end in ranges: await send({"type": "http.response.body", "body": header_generator(start, end), "more_body": True}) await file.seek(start) while start < end: chunk = await file.read(min(self.chunk_size, end - start)) start += len(chunk) await send({"type": "http.response.body", "body": chunk, "more_body": True}) await send({"type": "http.response.body", "body": b"\n", "more_body": True}) await send( { "type": "http.response.body", "body": f"\n--{boundary}--\n".encode("latin-1"), "more_body": False, } ) def _should_use_range(self, http_if_range: str) -> bool: return http_if_range == self.headers["last-modified"] or http_if_range == self.headers["etag"] @classmethod def _parse_range_header(cls, http_range: str, file_size: int) -> list[tuple[int, int]]: ranges: list[tuple[int, int]] = [] try: units, range_ = http_range.split("=", 1) except ValueError: raise MalformedRangeHeader() units = units.strip().lower() if units != "bytes": raise MalformedRangeHeader("Only support bytes range") ranges = cls._parse_ranges(range_, file_size) if len(ranges) == 0: raise MalformedRangeHeader("Range header: range must be requested") if any(not (0 <= start < file_size) for start, _ in ranges): raise RangeNotSatisfiable(file_size) if any(start > end for start, end in ranges): raise MalformedRangeHeader("Range header: start must be less than end") if len(ranges) == 1: return ranges # Merge ranges result: list[tuple[int, int]] = [] for start, end in ranges: for p in range(len(result)): p_start, p_end = result[p] if start > p_end: continue elif end < p_start: result.insert(p, (start, end)) # THIS IS NOT REACHED! break else: result[p] = (min(start, p_start), max(end, p_end)) break else: result.append((start, end)) return result @classmethod def _parse_ranges(cls, range_: str, file_size: int) -> list[tuple[int, int]]: ranges: list[tuple[int, int]] = [] for part in range_.split(","): part = part.strip() # If the range is empty or a single dash, we ignore it. if not part or part == "-": continue # If the range is not in the format "start-end", we ignore it. if "-" not in part: continue start_str, end_str = part.split("-", 1) start_str = start_str.strip() end_str = end_str.strip() try: start = int(start_str) if start_str else file_size - int(end_str) end = int(end_str) + 1 if start_str and end_str and int(end_str) < file_size else file_size ranges.append((start, end)) except ValueError: # If the range is not numeric, we ignore it. continue return ranges def generate_multipart( self, ranges: Sequence[tuple[int, int]], boundary: str, max_size: int, content_type: str, ) -> tuple[int, Callable[[int, int], bytes]]: r""" Multipart response headers generator. ``` --{boundary}\n Content-Type: {content_type}\n Content-Range: bytes {start}-{end-1}/{max_size}\n \n ..........content...........\n --{boundary}\n Content-Type: {content_type}\n Content-Range: bytes {start}-{end-1}/{max_size}\n \n ..........content...........\n --{boundary}--\n ``` """ boundary_len = len(boundary) static_header_part_len = 44 + boundary_len + len(content_type) + len(str(max_size)) content_length = sum( (len(str(start)) + len(str(end - 1)) + static_header_part_len) # Headers + (end - start) # Content for start, end in ranges ) + ( 5 + boundary_len # --boundary--\n ) return ( content_length, lambda start, end: ( f"--{boundary}\nContent-Type: {content_type}\nContent-Range: bytes {start}-{end - 1}/{max_size}\n\n" ).encode("latin-1"), ) starlette-0.50.0/starlette/routing.py000066400000000000000000001026311510142272400176540ustar00rootroot00000000000000from __future__ import annotations import contextlib import functools import inspect import re import traceback import types import warnings from collections.abc import Awaitable, Callable, Collection, Generator, Sequence from contextlib import AbstractAsyncContextManager, AbstractContextManager, asynccontextmanager from enum import Enum from re import Pattern from typing import Any, TypeVar from starlette._exception_handler import wrap_app_handling_exceptions from starlette._utils import get_route_path, is_async_callable from starlette.concurrency import run_in_threadpool from starlette.convertors import CONVERTOR_TYPES, Convertor from starlette.datastructures import URL, Headers, URLPath from starlette.exceptions import HTTPException from starlette.middleware import Middleware from starlette.requests import Request from starlette.responses import PlainTextResponse, RedirectResponse, Response from starlette.types import ASGIApp, Lifespan, Receive, Scope, Send from starlette.websockets import WebSocket, WebSocketClose class NoMatchFound(Exception): """ Raised by `.url_for(name, **path_params)` and `.url_path_for(name, **path_params)` if no matching route exists. """ def __init__(self, name: str, path_params: dict[str, Any]) -> None: params = ", ".join(list(path_params.keys())) super().__init__(f'No route exists for name "{name}" and params "{params}".') class Match(Enum): NONE = 0 PARTIAL = 1 FULL = 2 def iscoroutinefunction_or_partial(obj: Any) -> bool: # pragma: no cover """ Correctly determines if an object is a coroutine function, including those wrapped in functools.partial objects. """ warnings.warn( "iscoroutinefunction_or_partial is deprecated, and will be removed in a future release.", DeprecationWarning, ) while isinstance(obj, functools.partial): obj = obj.func return inspect.iscoroutinefunction(obj) def request_response( func: Callable[[Request], Awaitable[Response] | Response], ) -> ASGIApp: """ Takes a function or coroutine `func(request) -> response`, and returns an ASGI application. """ f: Callable[[Request], Awaitable[Response]] = ( func if is_async_callable(func) else functools.partial(run_in_threadpool, func) ) async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive, send) async def app(scope: Scope, receive: Receive, send: Send) -> None: response = await f(request) await response(scope, receive, send) await wrap_app_handling_exceptions(app, request)(scope, receive, send) return app def websocket_session( func: Callable[[WebSocket], Awaitable[None]], ) -> ASGIApp: """ Takes a coroutine `func(session)`, and returns an ASGI application. """ # assert asyncio.iscoroutinefunction(func), "WebSocket endpoints must be async" async def app(scope: Scope, receive: Receive, send: Send) -> None: session = WebSocket(scope, receive=receive, send=send) async def app(scope: Scope, receive: Receive, send: Send) -> None: await func(session) await wrap_app_handling_exceptions(app, session)(scope, receive, send) return app def get_name(endpoint: Callable[..., Any]) -> str: return getattr(endpoint, "__name__", endpoint.__class__.__name__) def replace_params( path: str, param_convertors: dict[str, Convertor[Any]], path_params: dict[str, str], ) -> tuple[str, dict[str, str]]: for key, value in list(path_params.items()): if "{" + key + "}" in path: convertor = param_convertors[key] value = convertor.to_string(value) path = path.replace("{" + key + "}", value) path_params.pop(key) return path, path_params # Match parameters in URL paths, eg. '{param}', and '{param:int}' PARAM_REGEX = re.compile("{([a-zA-Z_][a-zA-Z0-9_]*)(:[a-zA-Z_][a-zA-Z0-9_]*)?}") def compile_path( path: str, ) -> tuple[Pattern[str], str, dict[str, Convertor[Any]]]: """ Given a path string, like: "/{username:str}", or a host string, like: "{subdomain}.mydomain.org", return a three-tuple of (regex, format, {param_name:convertor}). regex: "/(?P[^/]+)" format: "/{username}" convertors: {"username": StringConvertor()} """ is_host = not path.startswith("/") path_regex = "^" path_format = "" duplicated_params = set() idx = 0 param_convertors = {} for match in PARAM_REGEX.finditer(path): param_name, convertor_type = match.groups("str") convertor_type = convertor_type.lstrip(":") assert convertor_type in CONVERTOR_TYPES, f"Unknown path convertor '{convertor_type}'" convertor = CONVERTOR_TYPES[convertor_type] path_regex += re.escape(path[idx : match.start()]) path_regex += f"(?P<{param_name}>{convertor.regex})" path_format += path[idx : match.start()] path_format += "{%s}" % param_name if param_name in param_convertors: duplicated_params.add(param_name) param_convertors[param_name] = convertor idx = match.end() if duplicated_params: names = ", ".join(sorted(duplicated_params)) ending = "s" if len(duplicated_params) > 1 else "" raise ValueError(f"Duplicated param name{ending} {names} at path {path}") if is_host: # Align with `Host.matches()` behavior, which ignores port. hostname = path[idx:].split(":")[0] path_regex += re.escape(hostname) + "$" else: path_regex += re.escape(path[idx:]) + "$" path_format += path[idx:] return re.compile(path_regex), path_format, param_convertors class BaseRoute: def matches(self, scope: Scope) -> tuple[Match, Scope]: raise NotImplementedError() # pragma: no cover def url_path_for(self, name: str, /, **path_params: Any) -> URLPath: raise NotImplementedError() # pragma: no cover async def handle(self, scope: Scope, receive: Receive, send: Send) -> None: raise NotImplementedError() # pragma: no cover async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: """ A route may be used in isolation as a stand-alone ASGI app. This is a somewhat contrived case, as they'll almost always be used within a Router, but could be useful for some tooling and minimal apps. """ match, child_scope = self.matches(scope) if match == Match.NONE: if scope["type"] == "http": response = PlainTextResponse("Not Found", status_code=404) await response(scope, receive, send) elif scope["type"] == "websocket": # pragma: no branch websocket_close = WebSocketClose() await websocket_close(scope, receive, send) return scope.update(child_scope) await self.handle(scope, receive, send) class Route(BaseRoute): def __init__( self, path: str, endpoint: Callable[..., Any], *, methods: Collection[str] | None = None, name: str | None = None, include_in_schema: bool = True, middleware: Sequence[Middleware] | None = None, ) -> None: assert path.startswith("/"), "Routed paths must start with '/'" self.path = path self.endpoint = endpoint self.name = get_name(endpoint) if name is None else name self.include_in_schema = include_in_schema endpoint_handler = endpoint while isinstance(endpoint_handler, functools.partial): endpoint_handler = endpoint_handler.func if inspect.isfunction(endpoint_handler) or inspect.ismethod(endpoint_handler): # Endpoint is function or method. Treat it as `func(request) -> response`. self.app = request_response(endpoint) if methods is None: methods = ["GET"] else: # Endpoint is a class. Treat it as ASGI. self.app = endpoint if middleware is not None: for cls, args, kwargs in reversed(middleware): self.app = cls(self.app, *args, **kwargs) if methods is None: self.methods = None else: self.methods = {method.upper() for method in methods} if "GET" in self.methods: self.methods.add("HEAD") self.path_regex, self.path_format, self.param_convertors = compile_path(path) def matches(self, scope: Scope) -> tuple[Match, Scope]: path_params: dict[str, Any] if scope["type"] == "http": route_path = get_route_path(scope) match = self.path_regex.match(route_path) if match: matched_params = match.groupdict() for key, value in matched_params.items(): matched_params[key] = self.param_convertors[key].convert(value) path_params = dict(scope.get("path_params", {})) path_params.update(matched_params) child_scope = {"endpoint": self.endpoint, "path_params": path_params} if self.methods and scope["method"] not in self.methods: return Match.PARTIAL, child_scope else: return Match.FULL, child_scope return Match.NONE, {} def url_path_for(self, name: str, /, **path_params: Any) -> URLPath: seen_params = set(path_params.keys()) expected_params = set(self.param_convertors.keys()) if name != self.name or seen_params != expected_params: raise NoMatchFound(name, path_params) path, remaining_params = replace_params(self.path_format, self.param_convertors, path_params) assert not remaining_params return URLPath(path=path, protocol="http") async def handle(self, scope: Scope, receive: Receive, send: Send) -> None: if self.methods and scope["method"] not in self.methods: headers = {"Allow": ", ".join(self.methods)} if "app" in scope: raise HTTPException(status_code=405, headers=headers) else: response = PlainTextResponse("Method Not Allowed", status_code=405, headers=headers) await response(scope, receive, send) else: await self.app(scope, receive, send) def __eq__(self, other: Any) -> bool: return ( isinstance(other, Route) and self.path == other.path and self.endpoint == other.endpoint and self.methods == other.methods ) def __repr__(self) -> str: class_name = self.__class__.__name__ methods = sorted(self.methods or []) path, name = self.path, self.name return f"{class_name}(path={path!r}, name={name!r}, methods={methods!r})" class WebSocketRoute(BaseRoute): def __init__( self, path: str, endpoint: Callable[..., Any], *, name: str | None = None, middleware: Sequence[Middleware] | None = None, ) -> None: assert path.startswith("/"), "Routed paths must start with '/'" self.path = path self.endpoint = endpoint self.name = get_name(endpoint) if name is None else name endpoint_handler = endpoint while isinstance(endpoint_handler, functools.partial): endpoint_handler = endpoint_handler.func if inspect.isfunction(endpoint_handler) or inspect.ismethod(endpoint_handler): # Endpoint is function or method. Treat it as `func(websocket)`. self.app = websocket_session(endpoint) else: # Endpoint is a class. Treat it as ASGI. self.app = endpoint if middleware is not None: for cls, args, kwargs in reversed(middleware): self.app = cls(self.app, *args, **kwargs) self.path_regex, self.path_format, self.param_convertors = compile_path(path) def matches(self, scope: Scope) -> tuple[Match, Scope]: path_params: dict[str, Any] if scope["type"] == "websocket": route_path = get_route_path(scope) match = self.path_regex.match(route_path) if match: matched_params = match.groupdict() for key, value in matched_params.items(): matched_params[key] = self.param_convertors[key].convert(value) path_params = dict(scope.get("path_params", {})) path_params.update(matched_params) child_scope = {"endpoint": self.endpoint, "path_params": path_params} return Match.FULL, child_scope return Match.NONE, {} def url_path_for(self, name: str, /, **path_params: Any) -> URLPath: seen_params = set(path_params.keys()) expected_params = set(self.param_convertors.keys()) if name != self.name or seen_params != expected_params: raise NoMatchFound(name, path_params) path, remaining_params = replace_params(self.path_format, self.param_convertors, path_params) assert not remaining_params return URLPath(path=path, protocol="websocket") async def handle(self, scope: Scope, receive: Receive, send: Send) -> None: await self.app(scope, receive, send) def __eq__(self, other: Any) -> bool: return isinstance(other, WebSocketRoute) and self.path == other.path and self.endpoint == other.endpoint def __repr__(self) -> str: return f"{self.__class__.__name__}(path={self.path!r}, name={self.name!r})" class Mount(BaseRoute): def __init__( self, path: str, app: ASGIApp | None = None, routes: Sequence[BaseRoute] | None = None, name: str | None = None, *, middleware: Sequence[Middleware] | None = None, ) -> None: assert path == "" or path.startswith("/"), "Routed paths must start with '/'" assert app is not None or routes is not None, "Either 'app=...', or 'routes=' must be specified" self.path = path.rstrip("/") if app is not None: self._base_app: ASGIApp = app else: self._base_app = Router(routes=routes) self.app = self._base_app if middleware is not None: for cls, args, kwargs in reversed(middleware): self.app = cls(self.app, *args, **kwargs) self.name = name self.path_regex, self.path_format, self.param_convertors = compile_path(self.path + "/{path:path}") @property def routes(self) -> list[BaseRoute]: return getattr(self._base_app, "routes", []) def matches(self, scope: Scope) -> tuple[Match, Scope]: path_params: dict[str, Any] if scope["type"] in ("http", "websocket"): # pragma: no branch root_path = scope.get("root_path", "") route_path = get_route_path(scope) match = self.path_regex.match(route_path) if match: matched_params = match.groupdict() for key, value in matched_params.items(): matched_params[key] = self.param_convertors[key].convert(value) remaining_path = "/" + matched_params.pop("path") matched_path = route_path[: -len(remaining_path)] path_params = dict(scope.get("path_params", {})) path_params.update(matched_params) child_scope = { "path_params": path_params, # app_root_path will only be set at the top level scope, # initialized with the (optional) value of a root_path # set above/before Starlette. And even though any # mount will have its own child scope with its own respective # root_path, the app_root_path will always be available in all # the child scopes with the same top level value because it's # set only once here with a default, any other child scope will # just inherit that app_root_path default value stored in the # scope. All this is needed to support Request.url_for(), as it # uses the app_root_path to build the URL path. "app_root_path": scope.get("app_root_path", root_path), "root_path": root_path + matched_path, "endpoint": self.app, } return Match.FULL, child_scope return Match.NONE, {} def url_path_for(self, name: str, /, **path_params: Any) -> URLPath: if self.name is not None and name == self.name and "path" in path_params: # 'name' matches "". path_params["path"] = path_params["path"].lstrip("/") path, remaining_params = replace_params(self.path_format, self.param_convertors, path_params) if not remaining_params: return URLPath(path=path) elif self.name is None or name.startswith(self.name + ":"): if self.name is None: # No mount name. remaining_name = name else: # 'name' matches ":". remaining_name = name[len(self.name) + 1 :] path_kwarg = path_params.get("path") path_params["path"] = "" path_prefix, remaining_params = replace_params(self.path_format, self.param_convertors, path_params) if path_kwarg is not None: remaining_params["path"] = path_kwarg for route in self.routes or []: try: url = route.url_path_for(remaining_name, **remaining_params) return URLPath(path=path_prefix.rstrip("/") + str(url), protocol=url.protocol) except NoMatchFound: pass raise NoMatchFound(name, path_params) async def handle(self, scope: Scope, receive: Receive, send: Send) -> None: await self.app(scope, receive, send) def __eq__(self, other: Any) -> bool: return isinstance(other, Mount) and self.path == other.path and self.app == other.app def __repr__(self) -> str: class_name = self.__class__.__name__ name = self.name or "" return f"{class_name}(path={self.path!r}, name={name!r}, app={self.app!r})" class Host(BaseRoute): def __init__(self, host: str, app: ASGIApp, name: str | None = None) -> None: assert not host.startswith("/"), "Host must not start with '/'" self.host = host self.app = app self.name = name self.host_regex, self.host_format, self.param_convertors = compile_path(host) @property def routes(self) -> list[BaseRoute]: return getattr(self.app, "routes", []) def matches(self, scope: Scope) -> tuple[Match, Scope]: if scope["type"] in ("http", "websocket"): # pragma:no branch headers = Headers(scope=scope) host = headers.get("host", "").split(":")[0] match = self.host_regex.match(host) if match: matched_params = match.groupdict() for key, value in matched_params.items(): matched_params[key] = self.param_convertors[key].convert(value) path_params = dict(scope.get("path_params", {})) path_params.update(matched_params) child_scope = {"path_params": path_params, "endpoint": self.app} return Match.FULL, child_scope return Match.NONE, {} def url_path_for(self, name: str, /, **path_params: Any) -> URLPath: if self.name is not None and name == self.name and "path" in path_params: # 'name' matches "". path = path_params.pop("path") host, remaining_params = replace_params(self.host_format, self.param_convertors, path_params) if not remaining_params: return URLPath(path=path, host=host) elif self.name is None or name.startswith(self.name + ":"): if self.name is None: # No mount name. remaining_name = name else: # 'name' matches ":". remaining_name = name[len(self.name) + 1 :] host, remaining_params = replace_params(self.host_format, self.param_convertors, path_params) for route in self.routes or []: try: url = route.url_path_for(remaining_name, **remaining_params) return URLPath(path=str(url), protocol=url.protocol, host=host) except NoMatchFound: pass raise NoMatchFound(name, path_params) async def handle(self, scope: Scope, receive: Receive, send: Send) -> None: await self.app(scope, receive, send) def __eq__(self, other: Any) -> bool: return isinstance(other, Host) and self.host == other.host and self.app == other.app def __repr__(self) -> str: class_name = self.__class__.__name__ name = self.name or "" return f"{class_name}(host={self.host!r}, name={name!r}, app={self.app!r})" _T = TypeVar("_T") class _AsyncLiftContextManager(AbstractAsyncContextManager[_T]): def __init__(self, cm: AbstractContextManager[_T]): self._cm = cm async def __aenter__(self) -> _T: return self._cm.__enter__() async def __aexit__( self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: types.TracebackType | None, ) -> bool | None: return self._cm.__exit__(exc_type, exc_value, traceback) def _wrap_gen_lifespan_context( lifespan_context: Callable[[Any], Generator[Any, Any, Any]], ) -> Callable[[Any], AbstractAsyncContextManager[Any]]: cmgr = contextlib.contextmanager(lifespan_context) @functools.wraps(cmgr) def wrapper(app: Any) -> _AsyncLiftContextManager[Any]: return _AsyncLiftContextManager(cmgr(app)) return wrapper class _DefaultLifespan: def __init__(self, router: Router): self._router = router async def __aenter__(self) -> None: await self._router.startup() async def __aexit__(self, *exc_info: object) -> None: await self._router.shutdown() def __call__(self: _T, app: object) -> _T: return self class Router: def __init__( self, routes: Sequence[BaseRoute] | None = None, redirect_slashes: bool = True, default: ASGIApp | None = None, on_startup: Sequence[Callable[[], Any]] | None = None, on_shutdown: Sequence[Callable[[], Any]] | None = None, # the generic to Lifespan[AppType] is the type of the top level application # which the router cannot know statically, so we use Any lifespan: Lifespan[Any] | None = None, *, middleware: Sequence[Middleware] | None = None, ) -> None: self.routes = [] if routes is None else list(routes) self.redirect_slashes = redirect_slashes self.default = self.not_found if default is None else default self.on_startup = [] if on_startup is None else list(on_startup) self.on_shutdown = [] if on_shutdown is None else list(on_shutdown) if on_startup or on_shutdown: warnings.warn( "The on_startup and on_shutdown parameters are deprecated, and they " "will be removed on version 1.0. Use the lifespan parameter instead. " "See more about it on https://starlette.dev/lifespan/.", DeprecationWarning, ) if lifespan: warnings.warn( "The `lifespan` parameter cannot be used with `on_startup` or " "`on_shutdown`. Both `on_startup` and `on_shutdown` will be " "ignored." ) if lifespan is None: self.lifespan_context: Lifespan[Any] = _DefaultLifespan(self) elif inspect.isasyncgenfunction(lifespan): warnings.warn( "async generator function lifespans are deprecated, " "use an @contextlib.asynccontextmanager function instead", DeprecationWarning, ) self.lifespan_context = asynccontextmanager( lifespan, ) elif inspect.isgeneratorfunction(lifespan): warnings.warn( "generator function lifespans are deprecated, use an @contextlib.asynccontextmanager function instead", DeprecationWarning, ) self.lifespan_context = _wrap_gen_lifespan_context( lifespan, ) else: self.lifespan_context = lifespan self.middleware_stack = self.app if middleware: for cls, args, kwargs in reversed(middleware): self.middleware_stack = cls(self.middleware_stack, *args, **kwargs) async def not_found(self, scope: Scope, receive: Receive, send: Send) -> None: if scope["type"] == "websocket": websocket_close = WebSocketClose() await websocket_close(scope, receive, send) return # If we're running inside a starlette application then raise an # exception, so that the configurable exception handler can deal with # returning the response. For plain ASGI apps, just return the response. if "app" in scope: raise HTTPException(status_code=404) else: response = PlainTextResponse("Not Found", status_code=404) await response(scope, receive, send) def url_path_for(self, name: str, /, **path_params: Any) -> URLPath: for route in self.routes: try: return route.url_path_for(name, **path_params) except NoMatchFound: pass raise NoMatchFound(name, path_params) async def startup(self) -> None: """ Run any `.on_startup` event handlers. """ for handler in self.on_startup: if is_async_callable(handler): await handler() else: handler() async def shutdown(self) -> None: """ Run any `.on_shutdown` event handlers. """ for handler in self.on_shutdown: if is_async_callable(handler): await handler() else: handler() async def lifespan(self, scope: Scope, receive: Receive, send: Send) -> None: """ Handle ASGI lifespan messages, which allows us to manage application startup and shutdown events. """ started = False app: Any = scope.get("app") await receive() try: async with self.lifespan_context(app) as maybe_state: if maybe_state is not None: if "state" not in scope: raise RuntimeError('The server does not support "state" in the lifespan scope.') scope["state"].update(maybe_state) await send({"type": "lifespan.startup.complete"}) started = True await receive() except BaseException: exc_text = traceback.format_exc() if started: await send({"type": "lifespan.shutdown.failed", "message": exc_text}) else: await send({"type": "lifespan.startup.failed", "message": exc_text}) raise else: await send({"type": "lifespan.shutdown.complete"}) async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: """ The main entry point to the Router class. """ await self.middleware_stack(scope, receive, send) async def app(self, scope: Scope, receive: Receive, send: Send) -> None: assert scope["type"] in ("http", "websocket", "lifespan") if "router" not in scope: scope["router"] = self if scope["type"] == "lifespan": await self.lifespan(scope, receive, send) return partial = None for route in self.routes: # Determine if any route matches the incoming scope, # and hand over to the matching route if found. match, child_scope = route.matches(scope) if match == Match.FULL: scope.update(child_scope) await route.handle(scope, receive, send) return elif match == Match.PARTIAL and partial is None: partial = route partial_scope = child_scope if partial is not None: #  Handle partial matches. These are cases where an endpoint is # able to handle the request, but is not a preferred option. # We use this in particular to deal with "405 Method Not Allowed". scope.update(partial_scope) await partial.handle(scope, receive, send) return route_path = get_route_path(scope) if scope["type"] == "http" and self.redirect_slashes and route_path != "/": redirect_scope = dict(scope) if route_path.endswith("/"): redirect_scope["path"] = redirect_scope["path"].rstrip("/") else: redirect_scope["path"] = redirect_scope["path"] + "/" for route in self.routes: match, child_scope = route.matches(redirect_scope) if match != Match.NONE: redirect_url = URL(scope=redirect_scope) response = RedirectResponse(url=str(redirect_url)) await response(scope, receive, send) return await self.default(scope, receive, send) def __eq__(self, other: Any) -> bool: return isinstance(other, Router) and self.routes == other.routes def mount(self, path: str, app: ASGIApp, name: str | None = None) -> None: # pragma: no cover route = Mount(path, app=app, name=name) self.routes.append(route) def host(self, host: str, app: ASGIApp, name: str | None = None) -> None: # pragma: no cover route = Host(host, app=app, name=name) self.routes.append(route) def add_route( self, path: str, endpoint: Callable[[Request], Awaitable[Response] | Response], methods: Collection[str] | None = None, name: str | None = None, include_in_schema: bool = True, ) -> None: # pragma: no cover route = Route( path, endpoint=endpoint, methods=methods, name=name, include_in_schema=include_in_schema, ) self.routes.append(route) def add_websocket_route( self, path: str, endpoint: Callable[[WebSocket], Awaitable[None]], name: str | None = None, ) -> None: # pragma: no cover route = WebSocketRoute(path, endpoint=endpoint, name=name) self.routes.append(route) def route( self, path: str, methods: Collection[str] | None = None, name: str | None = None, include_in_schema: bool = True, ) -> Callable: # type: ignore[type-arg] """ We no longer document this decorator style API, and its usage is discouraged. Instead you should use the following approach: >>> routes = [Route(path, endpoint=...), ...] >>> app = Starlette(routes=routes) """ warnings.warn( "The `route` decorator is deprecated, and will be removed in version 1.0.0." "Refer to https://starlette.dev/routing/#http-routing for the recommended approach.", DeprecationWarning, ) def decorator(func: Callable) -> Callable: # type: ignore[type-arg] self.add_route( path, func, methods=methods, name=name, include_in_schema=include_in_schema, ) return func return decorator def websocket_route(self, path: str, name: str | None = None) -> Callable: # type: ignore[type-arg] """ We no longer document this decorator style API, and its usage is discouraged. Instead you should use the following approach: >>> routes = [WebSocketRoute(path, endpoint=...), ...] >>> app = Starlette(routes=routes) """ warnings.warn( "The `websocket_route` decorator is deprecated, and will be removed in version 1.0.0. Refer to " "https://starlette.dev/routing/#websocket-routing for the recommended approach.", DeprecationWarning, ) def decorator(func: Callable) -> Callable: # type: ignore[type-arg] self.add_websocket_route(path, func, name=name) return func return decorator def add_event_handler(self, event_type: str, func: Callable[[], Any]) -> None: # pragma: no cover assert event_type in ("startup", "shutdown") if event_type == "startup": self.on_startup.append(func) else: self.on_shutdown.append(func) def on_event(self, event_type: str) -> Callable: # type: ignore[type-arg] warnings.warn( "The `on_event` decorator is deprecated, and will be removed in version 1.0.0. " "Refer to https://starlette.dev/lifespan/ for recommended approach.", DeprecationWarning, ) def decorator(func: Callable) -> Callable: # type: ignore[type-arg] self.add_event_handler(event_type, func) return func return decorator starlette-0.50.0/starlette/schemas.py000066400000000000000000000120601510142272400176040ustar00rootroot00000000000000from __future__ import annotations import inspect import re from collections.abc import Callable from typing import Any, NamedTuple from starlette.requests import Request from starlette.responses import Response from starlette.routing import BaseRoute, Host, Mount, Route try: import yaml except ModuleNotFoundError: # pragma: no cover yaml = None # type: ignore[assignment] class OpenAPIResponse(Response): media_type = "application/vnd.oai.openapi" def render(self, content: Any) -> bytes: assert yaml is not None, "`pyyaml` must be installed to use OpenAPIResponse." assert isinstance(content, dict), "The schema passed to OpenAPIResponse should be a dictionary." return yaml.dump(content, default_flow_style=False).encode("utf-8") class EndpointInfo(NamedTuple): path: str http_method: str func: Callable[..., Any] _remove_converter_pattern = re.compile(r":\w+}") class BaseSchemaGenerator: def get_schema(self, routes: list[BaseRoute]) -> dict[str, Any]: raise NotImplementedError() # pragma: no cover def get_endpoints(self, routes: list[BaseRoute]) -> list[EndpointInfo]: """ Given the routes, yields the following information: - path eg: /users/ - http_method one of 'get', 'post', 'put', 'patch', 'delete', 'options' - func method ready to extract the docstring """ endpoints_info: list[EndpointInfo] = [] for route in routes: if isinstance(route, Mount | Host): routes = route.routes or [] if isinstance(route, Mount): path = self._remove_converter(route.path) else: path = "" sub_endpoints = [ EndpointInfo( path="".join((path, sub_endpoint.path)), http_method=sub_endpoint.http_method, func=sub_endpoint.func, ) for sub_endpoint in self.get_endpoints(routes) ] endpoints_info.extend(sub_endpoints) elif not isinstance(route, Route) or not route.include_in_schema: continue elif inspect.isfunction(route.endpoint) or inspect.ismethod(route.endpoint): path = self._remove_converter(route.path) for method in route.methods or ["GET"]: if method == "HEAD": continue endpoints_info.append(EndpointInfo(path, method.lower(), route.endpoint)) else: path = self._remove_converter(route.path) for method in ["get", "post", "put", "patch", "delete", "options"]: if not hasattr(route.endpoint, method): continue func = getattr(route.endpoint, method) endpoints_info.append(EndpointInfo(path, method.lower(), func)) return endpoints_info def _remove_converter(self, path: str) -> str: """ Remove the converter from the path. For example, a route like this: Route("/users/{id:int}", endpoint=get_user, methods=["GET"]) Should be represented as `/users/{id}` in the OpenAPI schema. """ return _remove_converter_pattern.sub("}", path) def parse_docstring(self, func_or_method: Callable[..., Any]) -> dict[str, Any]: """ Given a function, parse the docstring as YAML and return a dictionary of info. """ docstring = func_or_method.__doc__ if not docstring: return {} assert yaml is not None, "`pyyaml` must be installed to use parse_docstring." # We support having regular docstrings before the schema # definition. Here we return just the schema part from # the docstring. docstring = docstring.split("---")[-1] parsed = yaml.safe_load(docstring) if not isinstance(parsed, dict): # A regular docstring (not yaml formatted) can return # a simple string here, which wouldn't follow the schema. return {} return parsed def OpenAPIResponse(self, request: Request) -> Response: routes = request.app.routes schema = self.get_schema(routes=routes) return OpenAPIResponse(schema) class SchemaGenerator(BaseSchemaGenerator): def __init__(self, base_schema: dict[str, Any]) -> None: self.base_schema = base_schema def get_schema(self, routes: list[BaseRoute]) -> dict[str, Any]: schema = dict(self.base_schema) schema.setdefault("paths", {}) endpoints_info = self.get_endpoints(routes) for endpoint in endpoints_info: parsed = self.parse_docstring(endpoint.func) if not parsed: continue if endpoint.path not in schema["paths"]: schema["paths"][endpoint.path] = {} schema["paths"][endpoint.path][endpoint.http_method] = parsed return schema starlette-0.50.0/starlette/staticfiles.py000066400000000000000000000204451510142272400205010ustar00rootroot00000000000000from __future__ import annotations import errno import importlib.util import os import stat from email.utils import parsedate from typing import Union import anyio import anyio.to_thread from starlette._utils import get_route_path from starlette.datastructures import URL, Headers from starlette.exceptions import HTTPException from starlette.responses import FileResponse, RedirectResponse, Response from starlette.types import Receive, Scope, Send PathLike = Union[str, "os.PathLike[str]"] class NotModifiedResponse(Response): NOT_MODIFIED_HEADERS = ( "cache-control", "content-location", "date", "etag", "expires", "vary", ) def __init__(self, headers: Headers): super().__init__( status_code=304, headers={name: value for name, value in headers.items() if name in self.NOT_MODIFIED_HEADERS}, ) class StaticFiles: def __init__( self, *, directory: PathLike | None = None, packages: list[str | tuple[str, str]] | None = None, html: bool = False, check_dir: bool = True, follow_symlink: bool = False, ) -> None: self.directory = directory self.packages = packages self.all_directories = self.get_directories(directory, packages) self.html = html self.config_checked = False self.follow_symlink = follow_symlink if check_dir and directory is not None and not os.path.isdir(directory): raise RuntimeError(f"Directory '{directory}' does not exist") def get_directories( self, directory: PathLike | None = None, packages: list[str | tuple[str, str]] | None = None, ) -> list[PathLike]: """ Given `directory` and `packages` arguments, return a list of all the directories that should be used for serving static files from. """ directories = [] if directory is not None: directories.append(directory) for package in packages or []: if isinstance(package, tuple): package, statics_dir = package else: statics_dir = "statics" spec = importlib.util.find_spec(package) assert spec is not None, f"Package {package!r} could not be found." assert spec.origin is not None, f"Package {package!r} could not be found." package_directory = os.path.normpath(os.path.join(spec.origin, "..", statics_dir)) assert os.path.isdir(package_directory), ( f"Directory '{statics_dir!r}' in package {package!r} could not be found." ) directories.append(package_directory) return directories async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: """ The ASGI entry point. """ assert scope["type"] == "http" if not self.config_checked: await self.check_config() self.config_checked = True path = self.get_path(scope) response = await self.get_response(path, scope) await response(scope, receive, send) def get_path(self, scope: Scope) -> str: """ Given the ASGI scope, return the `path` string to serve up, with OS specific path separators, and any '..', '.' components removed. """ route_path = get_route_path(scope) return os.path.normpath(os.path.join(*route_path.split("/"))) async def get_response(self, path: str, scope: Scope) -> Response: """ Returns an HTTP response, given the incoming path, method and request headers. """ if scope["method"] not in ("GET", "HEAD"): raise HTTPException(status_code=405) try: full_path, stat_result = await anyio.to_thread.run_sync(self.lookup_path, path) except PermissionError: raise HTTPException(status_code=401) except OSError as exc: # Filename is too long, so it can't be a valid static file. if exc.errno == errno.ENAMETOOLONG: raise HTTPException(status_code=404) raise exc if stat_result and stat.S_ISREG(stat_result.st_mode): # We have a static file to serve. return self.file_response(full_path, stat_result, scope) elif stat_result and stat.S_ISDIR(stat_result.st_mode) and self.html: # We're in HTML mode, and have got a directory URL. # Check if we have 'index.html' file to serve. index_path = os.path.join(path, "index.html") full_path, stat_result = await anyio.to_thread.run_sync(self.lookup_path, index_path) if stat_result is not None and stat.S_ISREG(stat_result.st_mode): if not scope["path"].endswith("/"): # Directory URLs should redirect to always end in "/". url = URL(scope=scope) url = url.replace(path=url.path + "/") return RedirectResponse(url=url) return self.file_response(full_path, stat_result, scope) if self.html: # Check for '404.html' if we're in HTML mode. full_path, stat_result = await anyio.to_thread.run_sync(self.lookup_path, "404.html") if stat_result and stat.S_ISREG(stat_result.st_mode): return FileResponse(full_path, stat_result=stat_result, status_code=404) raise HTTPException(status_code=404) def lookup_path(self, path: str) -> tuple[str, os.stat_result | None]: for directory in self.all_directories: joined_path = os.path.join(directory, path) if self.follow_symlink: full_path = os.path.abspath(joined_path) directory = os.path.abspath(directory) else: full_path = os.path.realpath(joined_path) directory = os.path.realpath(directory) if os.path.commonpath([full_path, directory]) != str(directory): # Don't allow misbehaving clients to break out of the static files directory. continue try: return full_path, os.stat(full_path) except (FileNotFoundError, NotADirectoryError): continue return "", None def file_response( self, full_path: PathLike, stat_result: os.stat_result, scope: Scope, status_code: int = 200, ) -> Response: request_headers = Headers(scope=scope) response = FileResponse(full_path, status_code=status_code, stat_result=stat_result) if self.is_not_modified(response.headers, request_headers): return NotModifiedResponse(response.headers) return response async def check_config(self) -> None: """ Perform a one-off configuration check that StaticFiles is actually pointed at a directory, so that we can raise loud errors rather than just returning 404 responses. """ if self.directory is None: return try: stat_result = await anyio.to_thread.run_sync(os.stat, self.directory) except FileNotFoundError: raise RuntimeError(f"StaticFiles directory '{self.directory}' does not exist.") if not (stat.S_ISDIR(stat_result.st_mode) or stat.S_ISLNK(stat_result.st_mode)): raise RuntimeError(f"StaticFiles path '{self.directory}' is not a directory.") def is_not_modified(self, response_headers: Headers, request_headers: Headers) -> bool: """ Given the request and response headers, return `True` if an HTTP "Not Modified" response could be returned instead. """ if if_none_match := request_headers.get("if-none-match"): # The "etag" header is added by FileResponse, so it's always present. etag = response_headers["etag"] return etag in [tag.strip(" W/") for tag in if_none_match.split(",")] try: if_modified_since = parsedate(request_headers["if-modified-since"]) last_modified = parsedate(response_headers["last-modified"]) if if_modified_since is not None and last_modified is not None and if_modified_since >= last_modified: return True except KeyError: pass return False starlette-0.50.0/starlette/status.py000066400000000000000000000143271510142272400175140ustar00rootroot00000000000000""" HTTP codes See HTTP Status Code Registry: https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml And RFC 9110 - https://www.rfc-editor.org/rfc/rfc9110 """ from __future__ import annotations import warnings __all__ = [ "HTTP_100_CONTINUE", "HTTP_101_SWITCHING_PROTOCOLS", "HTTP_102_PROCESSING", "HTTP_103_EARLY_HINTS", "HTTP_200_OK", "HTTP_201_CREATED", "HTTP_202_ACCEPTED", "HTTP_203_NON_AUTHORITATIVE_INFORMATION", "HTTP_204_NO_CONTENT", "HTTP_205_RESET_CONTENT", "HTTP_206_PARTIAL_CONTENT", "HTTP_207_MULTI_STATUS", "HTTP_208_ALREADY_REPORTED", "HTTP_226_IM_USED", "HTTP_300_MULTIPLE_CHOICES", "HTTP_301_MOVED_PERMANENTLY", "HTTP_302_FOUND", "HTTP_303_SEE_OTHER", "HTTP_304_NOT_MODIFIED", "HTTP_305_USE_PROXY", "HTTP_306_RESERVED", "HTTP_307_TEMPORARY_REDIRECT", "HTTP_308_PERMANENT_REDIRECT", "HTTP_400_BAD_REQUEST", "HTTP_401_UNAUTHORIZED", "HTTP_402_PAYMENT_REQUIRED", "HTTP_403_FORBIDDEN", "HTTP_404_NOT_FOUND", "HTTP_405_METHOD_NOT_ALLOWED", "HTTP_406_NOT_ACCEPTABLE", "HTTP_407_PROXY_AUTHENTICATION_REQUIRED", "HTTP_408_REQUEST_TIMEOUT", "HTTP_409_CONFLICT", "HTTP_410_GONE", "HTTP_411_LENGTH_REQUIRED", "HTTP_412_PRECONDITION_FAILED", "HTTP_413_CONTENT_TOO_LARGE", "HTTP_414_URI_TOO_LONG", "HTTP_415_UNSUPPORTED_MEDIA_TYPE", "HTTP_416_RANGE_NOT_SATISFIABLE", "HTTP_417_EXPECTATION_FAILED", "HTTP_418_IM_A_TEAPOT", "HTTP_421_MISDIRECTED_REQUEST", "HTTP_422_UNPROCESSABLE_CONTENT", "HTTP_423_LOCKED", "HTTP_424_FAILED_DEPENDENCY", "HTTP_425_TOO_EARLY", "HTTP_426_UPGRADE_REQUIRED", "HTTP_428_PRECONDITION_REQUIRED", "HTTP_429_TOO_MANY_REQUESTS", "HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE", "HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS", "HTTP_500_INTERNAL_SERVER_ERROR", "HTTP_501_NOT_IMPLEMENTED", "HTTP_502_BAD_GATEWAY", "HTTP_503_SERVICE_UNAVAILABLE", "HTTP_504_GATEWAY_TIMEOUT", "HTTP_505_HTTP_VERSION_NOT_SUPPORTED", "HTTP_506_VARIANT_ALSO_NEGOTIATES", "HTTP_507_INSUFFICIENT_STORAGE", "HTTP_508_LOOP_DETECTED", "HTTP_510_NOT_EXTENDED", "HTTP_511_NETWORK_AUTHENTICATION_REQUIRED", "WS_1000_NORMAL_CLOSURE", "WS_1001_GOING_AWAY", "WS_1002_PROTOCOL_ERROR", "WS_1003_UNSUPPORTED_DATA", "WS_1005_NO_STATUS_RCVD", "WS_1006_ABNORMAL_CLOSURE", "WS_1007_INVALID_FRAME_PAYLOAD_DATA", "WS_1008_POLICY_VIOLATION", "WS_1009_MESSAGE_TOO_BIG", "WS_1010_MANDATORY_EXT", "WS_1011_INTERNAL_ERROR", "WS_1012_SERVICE_RESTART", "WS_1013_TRY_AGAIN_LATER", "WS_1014_BAD_GATEWAY", "WS_1015_TLS_HANDSHAKE", ] HTTP_100_CONTINUE = 100 HTTP_101_SWITCHING_PROTOCOLS = 101 HTTP_102_PROCESSING = 102 HTTP_103_EARLY_HINTS = 103 HTTP_200_OK = 200 HTTP_201_CREATED = 201 HTTP_202_ACCEPTED = 202 HTTP_203_NON_AUTHORITATIVE_INFORMATION = 203 HTTP_204_NO_CONTENT = 204 HTTP_205_RESET_CONTENT = 205 HTTP_206_PARTIAL_CONTENT = 206 HTTP_207_MULTI_STATUS = 207 HTTP_208_ALREADY_REPORTED = 208 HTTP_226_IM_USED = 226 HTTP_300_MULTIPLE_CHOICES = 300 HTTP_301_MOVED_PERMANENTLY = 301 HTTP_302_FOUND = 302 HTTP_303_SEE_OTHER = 303 HTTP_304_NOT_MODIFIED = 304 HTTP_305_USE_PROXY = 305 HTTP_306_RESERVED = 306 HTTP_307_TEMPORARY_REDIRECT = 307 HTTP_308_PERMANENT_REDIRECT = 308 HTTP_400_BAD_REQUEST = 400 HTTP_401_UNAUTHORIZED = 401 HTTP_402_PAYMENT_REQUIRED = 402 HTTP_403_FORBIDDEN = 403 HTTP_404_NOT_FOUND = 404 HTTP_405_METHOD_NOT_ALLOWED = 405 HTTP_406_NOT_ACCEPTABLE = 406 HTTP_407_PROXY_AUTHENTICATION_REQUIRED = 407 HTTP_408_REQUEST_TIMEOUT = 408 HTTP_409_CONFLICT = 409 HTTP_410_GONE = 410 HTTP_411_LENGTH_REQUIRED = 411 HTTP_412_PRECONDITION_FAILED = 412 HTTP_413_CONTENT_TOO_LARGE = 413 HTTP_414_URI_TOO_LONG = 414 HTTP_415_UNSUPPORTED_MEDIA_TYPE = 415 HTTP_416_RANGE_NOT_SATISFIABLE = 416 HTTP_417_EXPECTATION_FAILED = 417 HTTP_418_IM_A_TEAPOT = 418 HTTP_421_MISDIRECTED_REQUEST = 421 HTTP_422_UNPROCESSABLE_CONTENT = 422 HTTP_423_LOCKED = 423 HTTP_424_FAILED_DEPENDENCY = 424 HTTP_425_TOO_EARLY = 425 HTTP_426_UPGRADE_REQUIRED = 426 HTTP_428_PRECONDITION_REQUIRED = 428 HTTP_429_TOO_MANY_REQUESTS = 429 HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE = 431 HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS = 451 HTTP_500_INTERNAL_SERVER_ERROR = 500 HTTP_501_NOT_IMPLEMENTED = 501 HTTP_502_BAD_GATEWAY = 502 HTTP_503_SERVICE_UNAVAILABLE = 503 HTTP_504_GATEWAY_TIMEOUT = 504 HTTP_505_HTTP_VERSION_NOT_SUPPORTED = 505 HTTP_506_VARIANT_ALSO_NEGOTIATES = 506 HTTP_507_INSUFFICIENT_STORAGE = 507 HTTP_508_LOOP_DETECTED = 508 HTTP_510_NOT_EXTENDED = 510 HTTP_511_NETWORK_AUTHENTICATION_REQUIRED = 511 """ WebSocket codes https://www.iana.org/assignments/websocket/websocket.xml#close-code-number https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent """ WS_1000_NORMAL_CLOSURE = 1000 WS_1001_GOING_AWAY = 1001 WS_1002_PROTOCOL_ERROR = 1002 WS_1003_UNSUPPORTED_DATA = 1003 WS_1005_NO_STATUS_RCVD = 1005 WS_1006_ABNORMAL_CLOSURE = 1006 WS_1007_INVALID_FRAME_PAYLOAD_DATA = 1007 WS_1008_POLICY_VIOLATION = 1008 WS_1009_MESSAGE_TOO_BIG = 1009 WS_1010_MANDATORY_EXT = 1010 WS_1011_INTERNAL_ERROR = 1011 WS_1012_SERVICE_RESTART = 1012 WS_1013_TRY_AGAIN_LATER = 1013 WS_1014_BAD_GATEWAY = 1014 WS_1015_TLS_HANDSHAKE = 1015 __deprecated__ = { "HTTP_413_REQUEST_ENTITY_TOO_LARGE": 413, "HTTP_414_REQUEST_URI_TOO_LONG": 414, "HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE": 416, "HTTP_422_UNPROCESSABLE_ENTITY": 422, } def __getattr__(name: str) -> int: deprecation_changes = { "HTTP_413_REQUEST_ENTITY_TOO_LARGE": "HTTP_413_CONTENT_TOO_LARGE", "HTTP_414_REQUEST_URI_TOO_LONG": "HTTP_414_URI_TOO_LONG", "HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE": "HTTP_416_RANGE_NOT_SATISFIABLE", "HTTP_422_UNPROCESSABLE_ENTITY": "HTTP_422_UNPROCESSABLE_CONTENT", } deprecated = __deprecated__.get(name) if deprecated: warnings.warn( f"'{name}' is deprecated. Use '{deprecation_changes[name]}' instead.", category=DeprecationWarning, stacklevel=3, ) return deprecated raise AttributeError(f"module 'starlette.status' has no attribute '{name}'") def __dir__() -> list[str]: return sorted(list(__all__) + list(__deprecated__.keys())) # pragma: no cover starlette-0.50.0/starlette/templating.py000066400000000000000000000201451510142272400203300ustar00rootroot00000000000000from __future__ import annotations import warnings from collections.abc import Callable, Mapping, Sequence from os import PathLike from typing import Any, cast, overload from starlette.background import BackgroundTask from starlette.datastructures import URL from starlette.requests import Request from starlette.responses import HTMLResponse from starlette.types import Receive, Scope, Send try: import jinja2 # @contextfunction was renamed to @pass_context in Jinja 3.0, and was removed in 3.1 # hence we try to get pass_context (most installs will be >=3.1) # and fall back to contextfunction, # adding a type ignore for mypy to let us access an attribute that may not exist if hasattr(jinja2, "pass_context"): pass_context = jinja2.pass_context else: # pragma: no cover pass_context = jinja2.contextfunction # type: ignore[attr-defined] except ModuleNotFoundError: # pragma: no cover jinja2 = None # type: ignore[assignment] class _TemplateResponse(HTMLResponse): def __init__( self, template: Any, context: dict[str, Any], status_code: int = 200, headers: Mapping[str, str] | None = None, media_type: str | None = None, background: BackgroundTask | None = None, ): self.template = template self.context = context content = template.render(context) super().__init__(content, status_code, headers, media_type, background) async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: request = self.context.get("request", {}) extensions = request.get("extensions", {}) if "http.response.debug" in extensions: # pragma: no branch await send( { "type": "http.response.debug", "info": { "template": self.template, "context": self.context, }, } ) await super().__call__(scope, receive, send) class Jinja2Templates: """ templates = Jinja2Templates("templates") return templates.TemplateResponse("index.html", {"request": request}) """ @overload def __init__( self, directory: str | PathLike[str] | Sequence[str | PathLike[str]], *, context_processors: list[Callable[[Request], dict[str, Any]]] | None = None, **env_options: Any, ) -> None: ... @overload def __init__( self, *, env: jinja2.Environment, context_processors: list[Callable[[Request], dict[str, Any]]] | None = None, ) -> None: ... def __init__( self, directory: str | PathLike[str] | Sequence[str | PathLike[str]] | None = None, *, context_processors: list[Callable[[Request], dict[str, Any]]] | None = None, env: jinja2.Environment | None = None, **env_options: Any, ) -> None: if env_options: warnings.warn( "Extra environment options are deprecated. Use a preconfigured jinja2.Environment instead.", DeprecationWarning, ) assert jinja2 is not None, "jinja2 must be installed to use Jinja2Templates" assert bool(directory) ^ bool(env), "either 'directory' or 'env' arguments must be passed" self.context_processors = context_processors or [] if directory is not None: self.env = self._create_env(directory, **env_options) elif env is not None: # pragma: no branch self.env = env self._setup_env_defaults(self.env) def _create_env( self, directory: str | PathLike[str] | Sequence[str | PathLike[str]], **env_options: Any, ) -> jinja2.Environment: loader = jinja2.FileSystemLoader(directory) env_options.setdefault("loader", loader) env_options.setdefault("autoescape", True) return jinja2.Environment(**env_options) def _setup_env_defaults(self, env: jinja2.Environment) -> None: @pass_context def url_for( context: dict[str, Any], name: str, /, **path_params: Any, ) -> URL: request: Request = context["request"] return request.url_for(name, **path_params) env.globals.setdefault("url_for", url_for) def get_template(self, name: str) -> jinja2.Template: return self.env.get_template(name) @overload def TemplateResponse( self, request: Request, name: str, context: dict[str, Any] | None = None, status_code: int = 200, headers: Mapping[str, str] | None = None, media_type: str | None = None, background: BackgroundTask | None = None, ) -> _TemplateResponse: ... @overload def TemplateResponse( self, name: str, context: dict[str, Any] | None = None, status_code: int = 200, headers: Mapping[str, str] | None = None, media_type: str | None = None, background: BackgroundTask | None = None, ) -> _TemplateResponse: # Deprecated usage ... def TemplateResponse(self, *args: Any, **kwargs: Any) -> _TemplateResponse: if args: if isinstance(args[0], str): # the first argument is template name (old style) warnings.warn( "The `name` is not the first parameter anymore. " "The first parameter should be the `Request` instance.\n" 'Replace `TemplateResponse(name, {"request": request})` by `TemplateResponse(request, name)`.', DeprecationWarning, ) name = args[0] context = args[1] if len(args) > 1 else kwargs.get("context", {}) status_code = args[2] if len(args) > 2 else kwargs.get("status_code", 200) headers = args[3] if len(args) > 3 else kwargs.get("headers") media_type = args[4] if len(args) > 4 else kwargs.get("media_type") background = args[5] if len(args) > 5 else kwargs.get("background") if "request" not in context: raise ValueError('context must include a "request" key') request = context["request"] else: # the first argument is a request instance (new style) request = args[0] name = args[1] if len(args) > 1 else kwargs["name"] context = args[2] if len(args) > 2 else kwargs.get("context", {}) status_code = args[3] if len(args) > 3 else kwargs.get("status_code", 200) headers = args[4] if len(args) > 4 else kwargs.get("headers") media_type = args[5] if len(args) > 5 else kwargs.get("media_type") background = args[6] if len(args) > 6 else kwargs.get("background") else: # all arguments are kwargs if "request" not in kwargs: warnings.warn( "The `TemplateResponse` now requires the `request` argument.\n" 'Replace `TemplateResponse(name, {"context": context})` by `TemplateResponse(request, name)`.', DeprecationWarning, ) if "request" not in kwargs.get("context", {}): raise ValueError('context must include a "request" key') context = kwargs.get("context", {}) request = kwargs.get("request", context.get("request")) name = cast(str, kwargs["name"]) status_code = kwargs.get("status_code", 200) headers = kwargs.get("headers") media_type = kwargs.get("media_type") background = kwargs.get("background") context.setdefault("request", request) for context_processor in self.context_processors: context.update(context_processor(request)) template = self.get_template(name) return _TemplateResponse( template, context, status_code=status_code, headers=headers, media_type=media_type, background=background, ) starlette-0.50.0/starlette/testclient.py000066400000000000000000000663121510142272400203500ustar00rootroot00000000000000from __future__ import annotations import contextlib import inspect import io import json import math import sys import warnings from collections.abc import Awaitable, Callable, Generator, Iterable, Mapping, MutableMapping, Sequence from concurrent.futures import Future from contextlib import AbstractContextManager from types import GeneratorType from typing import ( Any, Literal, TypedDict, TypeGuard, cast, ) from urllib.parse import unquote, urljoin import anyio import anyio.abc import anyio.from_thread from anyio.streams.stapled import StapledObjectStream from starlette._utils import is_async_callable from starlette.types import ASGIApp, Message, Receive, Scope, Send from starlette.websockets import WebSocketDisconnect if sys.version_info >= (3, 11): # pragma: no cover from typing import Self else: # pragma: no cover from typing_extensions import Self try: import httpx except ModuleNotFoundError: # pragma: no cover raise RuntimeError( "The starlette.testclient module requires the httpx package to be installed.\n" "You can install this with:\n" " $ pip install httpx\n" ) _PortalFactoryType = Callable[[], AbstractContextManager[anyio.abc.BlockingPortal]] ASGIInstance = Callable[[Receive, Send], Awaitable[None]] ASGI2App = Callable[[Scope], ASGIInstance] ASGI3App = Callable[[Scope, Receive, Send], Awaitable[None]] _RequestData = Mapping[str, str | Iterable[str] | bytes] def _is_asgi3(app: ASGI2App | ASGI3App) -> TypeGuard[ASGI3App]: if inspect.isclass(app): return hasattr(app, "__await__") return is_async_callable(app) class _WrapASGI2: """ Provide an ASGI3 interface onto an ASGI2 app. """ def __init__(self, app: ASGI2App) -> None: self.app = app async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: instance = self.app(scope) await instance(receive, send) class _AsyncBackend(TypedDict): backend: str backend_options: dict[str, Any] class _Upgrade(Exception): def __init__(self, session: WebSocketTestSession) -> None: self.session = session class WebSocketDenialResponse( # type: ignore[misc] httpx.Response, WebSocketDisconnect, ): """ A special case of `WebSocketDisconnect`, raised in the `TestClient` if the `WebSocket` is closed before being accepted with a `send_denial_response()`. """ class WebSocketTestSession: def __init__( self, app: ASGI3App, scope: Scope, portal_factory: _PortalFactoryType, ) -> None: self.app = app self.scope = scope self.accepted_subprotocol = None self.portal_factory = portal_factory self.extra_headers = None def __enter__(self) -> WebSocketTestSession: with contextlib.ExitStack() as stack: self.portal = portal = stack.enter_context(self.portal_factory()) fut, cs = portal.start_task(self._run) stack.callback(fut.result) stack.callback(portal.call, cs.cancel) self.send({"type": "websocket.connect"}) message = self.receive() self._raise_on_close(message) self.accepted_subprotocol = message.get("subprotocol", None) self.extra_headers = message.get("headers", None) stack.callback(self.close, 1000) self.exit_stack = stack.pop_all() return self def __exit__(self, *args: Any) -> bool | None: return self.exit_stack.__exit__(*args) async def _run(self, *, task_status: anyio.abc.TaskStatus[anyio.CancelScope]) -> None: """ The sub-thread in which the websocket session runs. """ send: anyio.create_memory_object_stream[Message] = anyio.create_memory_object_stream(math.inf) send_tx, send_rx = send receive: anyio.create_memory_object_stream[Message] = anyio.create_memory_object_stream(math.inf) receive_tx, receive_rx = receive with send_tx, send_rx, receive_tx, receive_rx, anyio.CancelScope() as cs: self._receive_tx = receive_tx self._send_rx = send_rx task_status.started(cs) await self.app(self.scope, receive_rx.receive, send_tx.send) # wait for cs.cancel to be called before closing streams await anyio.sleep_forever() def _raise_on_close(self, message: Message) -> None: if message["type"] == "websocket.close": raise WebSocketDisconnect(code=message.get("code", 1000), reason=message.get("reason", "")) elif message["type"] == "websocket.http.response.start": status_code: int = message["status"] headers: list[tuple[bytes, bytes]] = message["headers"] body: list[bytes] = [] while True: message = self.receive() assert message["type"] == "websocket.http.response.body" body.append(message["body"]) if not message.get("more_body", False): break raise WebSocketDenialResponse(status_code=status_code, headers=headers, content=b"".join(body)) def send(self, message: Message) -> None: self.portal.call(self._receive_tx.send, message) def send_text(self, data: str) -> None: self.send({"type": "websocket.receive", "text": data}) def send_bytes(self, data: bytes) -> None: self.send({"type": "websocket.receive", "bytes": data}) def send_json(self, data: Any, mode: Literal["text", "binary"] = "text") -> None: text = json.dumps(data, separators=(",", ":"), ensure_ascii=False) if mode == "text": self.send({"type": "websocket.receive", "text": text}) else: self.send({"type": "websocket.receive", "bytes": text.encode("utf-8")}) def close(self, code: int = 1000, reason: str | None = None) -> None: self.send({"type": "websocket.disconnect", "code": code, "reason": reason}) def receive(self) -> Message: return self.portal.call(self._send_rx.receive) def receive_text(self) -> str: message = self.receive() self._raise_on_close(message) return cast(str, message["text"]) def receive_bytes(self) -> bytes: message = self.receive() self._raise_on_close(message) return cast(bytes, message["bytes"]) def receive_json(self, mode: Literal["text", "binary"] = "text") -> Any: message = self.receive() self._raise_on_close(message) if mode == "text": text = message["text"] else: text = message["bytes"].decode("utf-8") return json.loads(text) class _TestClientTransport(httpx.BaseTransport): def __init__( self, app: ASGI3App, portal_factory: _PortalFactoryType, raise_server_exceptions: bool = True, root_path: str = "", *, client: tuple[str, int], app_state: dict[str, Any], ) -> None: self.app = app self.raise_server_exceptions = raise_server_exceptions self.root_path = root_path self.portal_factory = portal_factory self.app_state = app_state self.client = client def handle_request(self, request: httpx.Request) -> httpx.Response: scheme = request.url.scheme netloc = request.url.netloc.decode(encoding="ascii") path = request.url.path raw_path = request.url.raw_path query = request.url.query.decode(encoding="ascii") default_port = {"http": 80, "ws": 80, "https": 443, "wss": 443}[scheme] if ":" in netloc: host, port_string = netloc.split(":", 1) port = int(port_string) else: host = netloc port = default_port # Include the 'host' header. if "host" in request.headers: headers: list[tuple[bytes, bytes]] = [] elif port == default_port: # pragma: no cover headers = [(b"host", host.encode())] else: # pragma: no cover headers = [(b"host", (f"{host}:{port}").encode())] # Include other request headers. headers += [(key.lower().encode(), value.encode()) for key, value in request.headers.multi_items()] scope: dict[str, Any] if scheme in {"ws", "wss"}: subprotocol = request.headers.get("sec-websocket-protocol", None) if subprotocol is None: subprotocols: Sequence[str] = [] else: subprotocols = [value.strip() for value in subprotocol.split(",")] scope = { "type": "websocket", "path": unquote(path), "raw_path": raw_path.split(b"?", 1)[0], "root_path": self.root_path, "scheme": scheme, "query_string": query.encode(), "headers": headers, "client": self.client, "server": [host, port], "subprotocols": subprotocols, "state": self.app_state.copy(), "extensions": {"websocket.http.response": {}}, } session = WebSocketTestSession(self.app, scope, self.portal_factory) raise _Upgrade(session) scope = { "type": "http", "http_version": "1.1", "method": request.method, "path": unquote(path), "raw_path": raw_path.split(b"?", 1)[0], "root_path": self.root_path, "scheme": scheme, "query_string": query.encode(), "headers": headers, "client": self.client, "server": [host, port], "extensions": {"http.response.debug": {}}, "state": self.app_state.copy(), } request_complete = False response_started = False response_complete: anyio.Event raw_kwargs: dict[str, Any] = {"stream": io.BytesIO()} template = None context = None async def receive() -> Message: nonlocal request_complete if request_complete: if not response_complete.is_set(): await response_complete.wait() return {"type": "http.disconnect"} body = request.read() if isinstance(body, str): body_bytes: bytes = body.encode("utf-8") # pragma: no cover elif body is None: body_bytes = b"" # pragma: no cover elif isinstance(body, GeneratorType): try: # pragma: no cover chunk = body.send(None) if isinstance(chunk, str): chunk = chunk.encode("utf-8") return {"type": "http.request", "body": chunk, "more_body": True} except StopIteration: # pragma: no cover request_complete = True return {"type": "http.request", "body": b""} else: body_bytes = body request_complete = True return {"type": "http.request", "body": body_bytes} async def send(message: Message) -> None: nonlocal raw_kwargs, response_started, template, context if message["type"] == "http.response.start": assert not response_started, 'Received multiple "http.response.start" messages.' raw_kwargs["status_code"] = message["status"] raw_kwargs["headers"] = [(key.decode(), value.decode()) for key, value in message.get("headers", [])] response_started = True elif message["type"] == "http.response.body": assert response_started, 'Received "http.response.body" without "http.response.start".' assert not response_complete.is_set(), 'Received "http.response.body" after response completed.' body = message.get("body", b"") more_body = message.get("more_body", False) if request.method != "HEAD": raw_kwargs["stream"].write(body) if not more_body: raw_kwargs["stream"].seek(0) response_complete.set() elif message["type"] == "http.response.debug": template = message["info"]["template"] context = message["info"]["context"] try: with self.portal_factory() as portal: response_complete = portal.call(anyio.Event) portal.call(self.app, scope, receive, send) except BaseException as exc: if self.raise_server_exceptions: raise exc if self.raise_server_exceptions: assert response_started, "TestClient did not receive any response." elif not response_started: raw_kwargs = { "status_code": 500, "headers": [], "stream": io.BytesIO(), } raw_kwargs["stream"] = httpx.ByteStream(raw_kwargs["stream"].read()) response = httpx.Response(**raw_kwargs, request=request) if template is not None: response.template = template # type: ignore[attr-defined] response.context = context # type: ignore[attr-defined] return response class TestClient(httpx.Client): __test__ = False task: Future[None] portal: anyio.abc.BlockingPortal | None = None def __init__( self, app: ASGIApp, base_url: str = "http://testserver", raise_server_exceptions: bool = True, root_path: str = "", backend: Literal["asyncio", "trio"] = "asyncio", backend_options: dict[str, Any] | None = None, cookies: httpx._types.CookieTypes | None = None, headers: dict[str, str] | None = None, follow_redirects: bool = True, client: tuple[str, int] = ("testclient", 50000), ) -> None: self.async_backend = _AsyncBackend(backend=backend, backend_options=backend_options or {}) if _is_asgi3(app): asgi_app = app else: app = cast(ASGI2App, app) # type: ignore[assignment] asgi_app = _WrapASGI2(app) # type: ignore[arg-type] self.app = asgi_app self.app_state: dict[str, Any] = {} transport = _TestClientTransport( self.app, portal_factory=self._portal_factory, raise_server_exceptions=raise_server_exceptions, root_path=root_path, app_state=self.app_state, client=client, ) if headers is None: headers = {} headers.setdefault("user-agent", "testclient") super().__init__( base_url=base_url, headers=headers, transport=transport, follow_redirects=follow_redirects, cookies=cookies, ) @contextlib.contextmanager def _portal_factory(self) -> Generator[anyio.abc.BlockingPortal, None, None]: if self.portal is not None: yield self.portal else: with anyio.from_thread.start_blocking_portal(**self.async_backend) as portal: yield portal def request( # type: ignore[override] self, method: str, url: httpx._types.URLTypes, *, content: httpx._types.RequestContent | None = None, data: _RequestData | None = None, files: httpx._types.RequestFiles | None = None, json: Any = None, params: httpx._types.QueryParamTypes | None = None, headers: httpx._types.HeaderTypes | None = None, cookies: httpx._types.CookieTypes | None = None, auth: httpx._types.AuthTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT, follow_redirects: bool | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT, timeout: httpx._types.TimeoutTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT, extensions: dict[str, Any] | None = None, ) -> httpx.Response: if timeout is not httpx.USE_CLIENT_DEFAULT: warnings.warn( "You should not use the 'timeout' argument with the TestClient. " "See https://github.com/Kludex/starlette/issues/1108 for more information.", DeprecationWarning, ) url = self._merge_url(url) return super().request( method, 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 get( # type: ignore[override] self, url: httpx._types.URLTypes, *, params: httpx._types.QueryParamTypes | None = None, headers: httpx._types.HeaderTypes | None = None, cookies: httpx._types.CookieTypes | None = None, auth: httpx._types.AuthTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT, follow_redirects: bool | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT, timeout: httpx._types.TimeoutTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT, extensions: dict[str, Any] | None = None, ) -> httpx.Response: return super().get( url, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) def options( # type: ignore[override] self, url: httpx._types.URLTypes, *, params: httpx._types.QueryParamTypes | None = None, headers: httpx._types.HeaderTypes | None = None, cookies: httpx._types.CookieTypes | None = None, auth: httpx._types.AuthTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT, follow_redirects: bool | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT, timeout: httpx._types.TimeoutTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT, extensions: dict[str, Any] | None = None, ) -> httpx.Response: return super().options( url, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) def head( # type: ignore[override] self, url: httpx._types.URLTypes, *, params: httpx._types.QueryParamTypes | None = None, headers: httpx._types.HeaderTypes | None = None, cookies: httpx._types.CookieTypes | None = None, auth: httpx._types.AuthTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT, follow_redirects: bool | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT, timeout: httpx._types.TimeoutTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT, extensions: dict[str, Any] | None = None, ) -> httpx.Response: return super().head( url, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) def post( # type: ignore[override] self, url: httpx._types.URLTypes, *, content: httpx._types.RequestContent | None = None, data: _RequestData | None = None, files: httpx._types.RequestFiles | None = None, json: Any = None, params: httpx._types.QueryParamTypes | None = None, headers: httpx._types.HeaderTypes | None = None, cookies: httpx._types.CookieTypes | None = None, auth: httpx._types.AuthTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT, follow_redirects: bool | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT, timeout: httpx._types.TimeoutTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT, extensions: dict[str, Any] | None = None, ) -> httpx.Response: return super().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( # type: ignore[override] self, url: httpx._types.URLTypes, *, content: httpx._types.RequestContent | None = None, data: _RequestData | None = None, files: httpx._types.RequestFiles | None = None, json: Any = None, params: httpx._types.QueryParamTypes | None = None, headers: httpx._types.HeaderTypes | None = None, cookies: httpx._types.CookieTypes | None = None, auth: httpx._types.AuthTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT, follow_redirects: bool | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT, timeout: httpx._types.TimeoutTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT, extensions: dict[str, Any] | None = None, ) -> httpx.Response: return super().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( # type: ignore[override] self, url: httpx._types.URLTypes, *, content: httpx._types.RequestContent | None = None, data: _RequestData | None = None, files: httpx._types.RequestFiles | None = None, json: Any = None, params: httpx._types.QueryParamTypes | None = None, headers: httpx._types.HeaderTypes | None = None, cookies: httpx._types.CookieTypes | None = None, auth: httpx._types.AuthTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT, follow_redirects: bool | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT, timeout: httpx._types.TimeoutTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT, extensions: dict[str, Any] | None = None, ) -> httpx.Response: return super().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( # type: ignore[override] self, url: httpx._types.URLTypes, *, params: httpx._types.QueryParamTypes | None = None, headers: httpx._types.HeaderTypes | None = None, cookies: httpx._types.CookieTypes | None = None, auth: httpx._types.AuthTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT, follow_redirects: bool | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT, timeout: httpx._types.TimeoutTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT, extensions: dict[str, Any] | None = None, ) -> httpx.Response: return super().delete( url, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) def websocket_connect( self, url: str, subprotocols: Sequence[str] | None = None, **kwargs: Any, ) -> WebSocketTestSession: url = urljoin("ws://testserver", url) headers = kwargs.get("headers", {}) headers.setdefault("connection", "upgrade") headers.setdefault("sec-websocket-key", "testserver==") headers.setdefault("sec-websocket-version", "13") if subprotocols is not None: headers.setdefault("sec-websocket-protocol", ", ".join(subprotocols)) kwargs["headers"] = headers try: super().request("GET", url, **kwargs) except _Upgrade as exc: session = exc.session else: raise RuntimeError("Expected WebSocket upgrade") # pragma: no cover return session def __enter__(self) -> Self: with contextlib.ExitStack() as stack: self.portal = portal = stack.enter_context(anyio.from_thread.start_blocking_portal(**self.async_backend)) @stack.callback def reset_portal() -> None: self.portal = None send: anyio.create_memory_object_stream[MutableMapping[str, Any] | None] = ( anyio.create_memory_object_stream(math.inf) ) receive: anyio.create_memory_object_stream[MutableMapping[str, Any]] = anyio.create_memory_object_stream( math.inf ) for channel in (*send, *receive): stack.callback(channel.close) self.stream_send = StapledObjectStream(*send) self.stream_receive = StapledObjectStream(*receive) self.task = portal.start_task_soon(self.lifespan) portal.call(self.wait_startup) @stack.callback def wait_shutdown() -> None: portal.call(self.wait_shutdown) self.exit_stack = stack.pop_all() return self def __exit__(self, *args: Any) -> None: self.exit_stack.close() async def lifespan(self) -> None: scope = {"type": "lifespan", "state": self.app_state} try: await self.app(scope, self.stream_receive.receive, self.stream_send.send) finally: await self.stream_send.send(None) async def wait_startup(self) -> None: await self.stream_receive.send({"type": "lifespan.startup"}) async def receive() -> Any: message = await self.stream_send.receive() if message is None: self.task.result() return message message = await receive() assert message["type"] in ( "lifespan.startup.complete", "lifespan.startup.failed", ) if message["type"] == "lifespan.startup.failed": await receive() async def wait_shutdown(self) -> None: async def receive() -> Any: message = await self.stream_send.receive() if message is None: self.task.result() return message await self.stream_receive.send({"type": "lifespan.shutdown"}) message = await receive() assert message["type"] in ( "lifespan.shutdown.complete", "lifespan.shutdown.failed", ) if message["type"] == "lifespan.shutdown.failed": await receive() starlette-0.50.0/starlette/types.py000066400000000000000000000020211510142272400173210ustar00rootroot00000000000000from collections.abc import Awaitable, Callable, Mapping, MutableMapping from contextlib import AbstractAsyncContextManager from typing import TYPE_CHECKING, Any, TypeVar if TYPE_CHECKING: from starlette.requests import Request from starlette.responses import Response from starlette.websockets import WebSocket AppType = TypeVar("AppType") Scope = MutableMapping[str, Any] Message = MutableMapping[str, Any] Receive = Callable[[], Awaitable[Message]] Send = Callable[[Message], Awaitable[None]] ASGIApp = Callable[[Scope, Receive, Send], Awaitable[None]] StatelessLifespan = Callable[[AppType], AbstractAsyncContextManager[None]] StatefulLifespan = Callable[[AppType], AbstractAsyncContextManager[Mapping[str, Any]]] Lifespan = StatelessLifespan[AppType] | StatefulLifespan[AppType] HTTPExceptionHandler = Callable[["Request", Exception], "Response | Awaitable[Response]"] WebSocketExceptionHandler = Callable[["WebSocket", Exception], Awaitable[None]] ExceptionHandler = HTTPExceptionHandler | WebSocketExceptionHandler starlette-0.50.0/starlette/websockets.py000066400000000000000000000202201510142272400203270ustar00rootroot00000000000000from __future__ import annotations import enum import json from collections.abc import AsyncIterator, Iterable from typing import Any, cast from starlette.requests import HTTPConnection from starlette.responses import Response from starlette.types import Message, Receive, Scope, Send class WebSocketState(enum.Enum): CONNECTING = 0 CONNECTED = 1 DISCONNECTED = 2 RESPONSE = 3 class WebSocketDisconnect(Exception): def __init__(self, code: int = 1000, reason: str | None = None) -> None: self.code = code self.reason = reason or "" class WebSocket(HTTPConnection): def __init__(self, scope: Scope, receive: Receive, send: Send) -> None: super().__init__(scope) assert scope["type"] == "websocket" self._receive = receive self._send = send self.client_state = WebSocketState.CONNECTING self.application_state = WebSocketState.CONNECTING async def receive(self) -> Message: """ Receive ASGI websocket messages, ensuring valid state transitions. """ if self.client_state == WebSocketState.CONNECTING: message = await self._receive() message_type = message["type"] if message_type != "websocket.connect": raise RuntimeError(f'Expected ASGI message "websocket.connect", but got {message_type!r}') self.client_state = WebSocketState.CONNECTED return message elif self.client_state == WebSocketState.CONNECTED: message = await self._receive() message_type = message["type"] if message_type not in {"websocket.receive", "websocket.disconnect"}: raise RuntimeError( f'Expected ASGI message "websocket.receive" or "websocket.disconnect", but got {message_type!r}' ) if message_type == "websocket.disconnect": self.client_state = WebSocketState.DISCONNECTED return message else: raise RuntimeError('Cannot call "receive" once a disconnect message has been received.') async def send(self, message: Message) -> None: """ Send ASGI websocket messages, ensuring valid state transitions. """ if self.application_state == WebSocketState.CONNECTING: message_type = message["type"] if message_type not in {"websocket.accept", "websocket.close", "websocket.http.response.start"}: raise RuntimeError( 'Expected ASGI message "websocket.accept", "websocket.close" or "websocket.http.response.start", ' f"but got {message_type!r}" ) if message_type == "websocket.close": self.application_state = WebSocketState.DISCONNECTED elif message_type == "websocket.http.response.start": self.application_state = WebSocketState.RESPONSE else: self.application_state = WebSocketState.CONNECTED await self._send(message) elif self.application_state == WebSocketState.CONNECTED: message_type = message["type"] if message_type not in {"websocket.send", "websocket.close"}: raise RuntimeError( f'Expected ASGI message "websocket.send" or "websocket.close", but got {message_type!r}' ) if message_type == "websocket.close": self.application_state = WebSocketState.DISCONNECTED try: await self._send(message) except OSError: self.application_state = WebSocketState.DISCONNECTED raise WebSocketDisconnect(code=1006) elif self.application_state == WebSocketState.RESPONSE: message_type = message["type"] if message_type != "websocket.http.response.body": raise RuntimeError(f'Expected ASGI message "websocket.http.response.body", but got {message_type!r}') if not message.get("more_body", False): self.application_state = WebSocketState.DISCONNECTED await self._send(message) else: raise RuntimeError('Cannot call "send" once a close message has been sent.') async def accept( self, subprotocol: str | None = None, headers: Iterable[tuple[bytes, bytes]] | None = None, ) -> None: headers = headers or [] if self.client_state == WebSocketState.CONNECTING: # pragma: no branch # If we haven't yet seen the 'connect' message, then wait for it first. await self.receive() await self.send({"type": "websocket.accept", "subprotocol": subprotocol, "headers": headers}) def _raise_on_disconnect(self, message: Message) -> None: if message["type"] == "websocket.disconnect": raise WebSocketDisconnect(message["code"], message.get("reason")) async def receive_text(self) -> str: if self.application_state != WebSocketState.CONNECTED: raise RuntimeError('WebSocket is not connected. Need to call "accept" first.') message = await self.receive() self._raise_on_disconnect(message) return cast(str, message["text"]) async def receive_bytes(self) -> bytes: if self.application_state != WebSocketState.CONNECTED: raise RuntimeError('WebSocket is not connected. Need to call "accept" first.') message = await self.receive() self._raise_on_disconnect(message) return cast(bytes, message["bytes"]) async def receive_json(self, mode: str = "text") -> Any: if mode not in {"text", "binary"}: raise RuntimeError('The "mode" argument should be "text" or "binary".') if self.application_state != WebSocketState.CONNECTED: raise RuntimeError('WebSocket is not connected. Need to call "accept" first.') message = await self.receive() self._raise_on_disconnect(message) if mode == "text": text = message["text"] else: text = message["bytes"].decode("utf-8") return json.loads(text) async def iter_text(self) -> AsyncIterator[str]: try: while True: yield await self.receive_text() except WebSocketDisconnect: pass async def iter_bytes(self) -> AsyncIterator[bytes]: try: while True: yield await self.receive_bytes() except WebSocketDisconnect: pass async def iter_json(self) -> AsyncIterator[Any]: try: while True: yield await self.receive_json() except WebSocketDisconnect: pass async def send_text(self, data: str) -> None: await self.send({"type": "websocket.send", "text": data}) async def send_bytes(self, data: bytes) -> None: await self.send({"type": "websocket.send", "bytes": data}) async def send_json(self, data: Any, mode: str = "text") -> None: if mode not in {"text", "binary"}: raise RuntimeError('The "mode" argument should be "text" or "binary".') text = json.dumps(data, separators=(",", ":"), ensure_ascii=False) if mode == "text": await self.send({"type": "websocket.send", "text": text}) else: await self.send({"type": "websocket.send", "bytes": text.encode("utf-8")}) async def close(self, code: int = 1000, reason: str | None = None) -> None: await self.send({"type": "websocket.close", "code": code, "reason": reason or ""}) async def send_denial_response(self, response: Response) -> None: if "websocket.http.response" in self.scope.get("extensions", {}): await response(self.scope, self.receive, self.send) else: raise RuntimeError("The server doesn't support the Websocket Denial Response extension.") class WebSocketClose: def __init__(self, code: int = 1000, reason: str | None = None) -> None: self.code = code self.reason = reason or "" async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: await send({"type": "websocket.close", "code": self.code, "reason": self.reason}) starlette-0.50.0/tests/000077500000000000000000000000001510142272400147435ustar00rootroot00000000000000starlette-0.50.0/tests/__init__.py000066400000000000000000000000001510142272400170420ustar00rootroot00000000000000starlette-0.50.0/tests/conftest.py000066400000000000000000000011511510142272400171400ustar00rootroot00000000000000from __future__ import annotations import functools from typing import Any, Literal import pytest from starlette.testclient import TestClient from tests.types import TestClientFactory @pytest.fixture def test_client_factory( anyio_backend_name: Literal["asyncio", "trio"], anyio_backend_options: dict[str, Any], ) -> TestClientFactory: # anyio_backend_name defined by: # https://anyio.readthedocs.io/en/stable/testing.html#specifying-the-backends-to-run-on return functools.partial( TestClient, backend=anyio_backend_name, backend_options=anyio_backend_options, ) starlette-0.50.0/tests/middleware/000077500000000000000000000000001510142272400170605ustar00rootroot00000000000000starlette-0.50.0/tests/middleware/__init__.py000066400000000000000000000000001510142272400211570ustar00rootroot00000000000000starlette-0.50.0/tests/middleware/test_base.py000066400000000000000000001235071510142272400214130ustar00rootroot00000000000000from __future__ import annotations import contextvars from collections.abc import AsyncGenerator, AsyncIterator, Generator from contextlib import AsyncExitStack from pathlib import Path from typing import Any import anyio import pytest from anyio.abc import TaskStatus from starlette.applications import Starlette from starlette.background import BackgroundTask from starlette.middleware import Middleware, _MiddlewareFactory from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint from starlette.requests import ClientDisconnect, Request from starlette.responses import FileResponse, PlainTextResponse, Response, StreamingResponse from starlette.routing import Route, WebSocketRoute from starlette.testclient import TestClient from starlette.types import ASGIApp, Message, Receive, Scope, Send from starlette.websockets import WebSocket from tests.types import TestClientFactory class CustomMiddleware(BaseHTTPMiddleware): async def dispatch( self, request: Request, call_next: RequestResponseEndpoint, ) -> Response: response = await call_next(request) response.headers["Custom-Header"] = "Example" return response def homepage(request: Request) -> PlainTextResponse: return PlainTextResponse("Homepage") def exc(request: Request) -> None: raise Exception("Exc") def exc_stream(request: Request) -> StreamingResponse: return StreamingResponse(_generate_faulty_stream()) def _generate_faulty_stream() -> Generator[bytes, None, None]: yield b"Ok" raise Exception("Faulty Stream") class NoResponse: def __init__( self, scope: Scope, receive: Receive, send: Send, ): pass def __await__(self) -> Generator[Any, None, None]: return self.dispatch().__await__() async def dispatch(self) -> None: pass async def websocket_endpoint(session: WebSocket) -> None: await session.accept() await session.send_text("Hello, world!") await session.close() app = Starlette( routes=[ Route("/", endpoint=homepage), Route("/exc", endpoint=exc), Route("/exc-stream", endpoint=exc_stream), Route("/no-response", endpoint=NoResponse), WebSocketRoute("/ws", endpoint=websocket_endpoint), ], middleware=[Middleware(CustomMiddleware)], ) def test_custom_middleware(test_client_factory: TestClientFactory) -> None: client = test_client_factory(app) response = client.get("/") assert response.headers["Custom-Header"] == "Example" with pytest.raises(Exception) as ctx: response = client.get("/exc") assert str(ctx.value) == "Exc" with pytest.raises(Exception) as ctx: response = client.get("/exc-stream") assert str(ctx.value) == "Faulty Stream" with pytest.raises(RuntimeError): response = client.get("/no-response") with client.websocket_connect("/ws") as session: text = session.receive_text() assert text == "Hello, world!" def test_state_data_across_multiple_middlewares( test_client_factory: TestClientFactory, ) -> None: expected_value1 = "foo" expected_value2 = "bar" class aMiddleware(BaseHTTPMiddleware): async def dispatch( self, request: Request, call_next: RequestResponseEndpoint, ) -> Response: request.state.foo = expected_value1 response = await call_next(request) return response class bMiddleware(BaseHTTPMiddleware): async def dispatch( self, request: Request, call_next: RequestResponseEndpoint, ) -> Response: request.state.bar = expected_value2 response = await call_next(request) response.headers["X-State-Foo"] = request.state.foo return response class cMiddleware(BaseHTTPMiddleware): async def dispatch( self, request: Request, call_next: RequestResponseEndpoint, ) -> Response: response = await call_next(request) response.headers["X-State-Bar"] = request.state.bar return response def homepage(request: Request) -> PlainTextResponse: return PlainTextResponse("OK") app = Starlette( routes=[Route("/", homepage)], middleware=[ Middleware(aMiddleware), Middleware(bMiddleware), Middleware(cMiddleware), ], ) client = test_client_factory(app) response = client.get("/") assert response.text == "OK" assert response.headers["X-State-Foo"] == expected_value1 assert response.headers["X-State-Bar"] == expected_value2 def test_app_middleware_argument(test_client_factory: TestClientFactory) -> None: def homepage(request: Request) -> PlainTextResponse: return PlainTextResponse("Homepage") app = Starlette(routes=[Route("/", homepage)], middleware=[Middleware(CustomMiddleware)]) client = test_client_factory(app) response = client.get("/") assert response.headers["Custom-Header"] == "Example" def test_fully_evaluated_response(test_client_factory: TestClientFactory) -> None: # Test for https://github.com/Kludex/starlette/issues/1022 class CustomMiddleware(BaseHTTPMiddleware): async def dispatch( self, request: Request, call_next: RequestResponseEndpoint, ) -> PlainTextResponse: await call_next(request) return PlainTextResponse("Custom") app = Starlette(middleware=[Middleware(CustomMiddleware)]) client = test_client_factory(app) response = client.get("/does_not_exist") assert response.text == "Custom" ctxvar: contextvars.ContextVar[str] = contextvars.ContextVar("ctxvar") class CustomMiddlewareWithoutBaseHTTPMiddleware: def __init__(self, app: ASGIApp) -> None: self.app = app async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: ctxvar.set("set by middleware") await self.app(scope, receive, send) assert ctxvar.get() == "set by endpoint" class CustomMiddlewareUsingBaseHTTPMiddleware(BaseHTTPMiddleware): async def dispatch( self, request: Request, call_next: RequestResponseEndpoint, ) -> Response: ctxvar.set("set by middleware") resp = await call_next(request) assert ctxvar.get() == "set by endpoint" return resp # pragma: no cover @pytest.mark.parametrize( "middleware_cls", [ CustomMiddlewareWithoutBaseHTTPMiddleware, pytest.param( CustomMiddlewareUsingBaseHTTPMiddleware, marks=pytest.mark.xfail( reason=( "BaseHTTPMiddleware creates a TaskGroup which copies the context" "and erases any changes to it made within the TaskGroup" ), raises=AssertionError, ), ), ], ) def test_contextvars( test_client_factory: TestClientFactory, middleware_cls: _MiddlewareFactory[Any], ) -> None: # this has to be an async endpoint because Starlette calls run_in_threadpool # on sync endpoints which has it's own set of peculiarities w.r.t propagating # contextvars (it propagates them forwards but not backwards) async def homepage(request: Request) -> PlainTextResponse: assert ctxvar.get() == "set by middleware" ctxvar.set("set by endpoint") return PlainTextResponse("Homepage") app = Starlette(middleware=[Middleware(middleware_cls)], routes=[Route("/", homepage)]) client = test_client_factory(app) response = client.get("/") assert response.status_code == 200, response.content @pytest.mark.anyio async def test_run_background_tasks_even_if_client_disconnects() -> None: # test for https://github.com/Kludex/starlette/issues/1438 response_complete = anyio.Event() background_task_run = anyio.Event() async def sleep_and_set() -> None: # small delay to give BaseHTTPMiddleware a chance to cancel us # this is required to make the test fail prior to fixing the issue # so do not be surprised if you remove it and the test still passes await anyio.sleep(0.1) background_task_run.set() async def endpoint_with_background_task(_: Request) -> PlainTextResponse: return PlainTextResponse(background=BackgroundTask(sleep_and_set)) async def passthrough( request: Request, call_next: RequestResponseEndpoint, ) -> Response: return await call_next(request) app = Starlette( middleware=[Middleware(BaseHTTPMiddleware, dispatch=passthrough)], routes=[Route("/", endpoint_with_background_task)], ) scope = { "type": "http", "version": "3", "method": "GET", "path": "/", } async def receive() -> Message: raise NotImplementedError("Should not be called!") async def send(message: Message) -> None: if message["type"] == "http.response.body": if not message.get("more_body", False): # pragma: no branch response_complete.set() await app(scope, receive, send) assert background_task_run.is_set() def test_run_background_tasks_raise_exceptions(test_client_factory: TestClientFactory) -> None: # test for https://github.com/Kludex/starlette/issues/2625 async def sleep_and_set() -> None: await anyio.sleep(0.1) raise ValueError("TEST") async def endpoint_with_background_task(_: Request) -> PlainTextResponse: return PlainTextResponse(background=BackgroundTask(sleep_and_set)) async def passthrough(request: Request, call_next: RequestResponseEndpoint) -> Response: return await call_next(request) app = Starlette( middleware=[Middleware(BaseHTTPMiddleware, dispatch=passthrough)], routes=[Route("/", endpoint_with_background_task)], ) client = test_client_factory(app) with pytest.raises(ValueError, match="TEST"): client.get("/") def test_exception_can_be_caught(test_client_factory: TestClientFactory) -> None: async def error_endpoint(_: Request) -> None: raise ValueError("TEST") async def catches_error(request: Request, call_next: RequestResponseEndpoint) -> Response: try: return await call_next(request) except ValueError as exc: return PlainTextResponse(content=str(exc), status_code=400) app = Starlette( middleware=[Middleware(BaseHTTPMiddleware, dispatch=catches_error)], routes=[Route("/", error_endpoint)], ) client = test_client_factory(app) response = client.get("/") assert response.status_code == 400 assert response.text == "TEST" @pytest.mark.anyio async def test_do_not_block_on_background_tasks() -> None: response_complete = anyio.Event() events: list[str | Message] = [] async def sleep_and_set() -> None: events.append("Background task started") await anyio.sleep(0.1) events.append("Background task finished") async def endpoint_with_background_task(_: Request) -> PlainTextResponse: return PlainTextResponse(content="Hello", background=BackgroundTask(sleep_and_set)) async def passthrough(request: Request, call_next: RequestResponseEndpoint) -> Response: return await call_next(request) app = Starlette( middleware=[Middleware(BaseHTTPMiddleware, dispatch=passthrough)], routes=[Route("/", endpoint_with_background_task)], ) scope = { "type": "http", "version": "3", "method": "GET", "path": "/", } async def receive() -> Message: raise NotImplementedError("Should not be called!") async def send(message: Message) -> None: if message["type"] == "http.response.body": events.append(message) if not message.get("more_body", False): response_complete.set() async with anyio.create_task_group() as tg: tg.start_soon(app, scope, receive, send) tg.start_soon(app, scope, receive, send) # Without the fix, the background tasks would start and finish before the # last http.response.body is sent. assert events == [ {"body": b"Hello", "more_body": True, "type": "http.response.body"}, {"body": b"", "more_body": False, "type": "http.response.body"}, {"body": b"Hello", "more_body": True, "type": "http.response.body"}, {"body": b"", "more_body": False, "type": "http.response.body"}, "Background task started", "Background task started", "Background task finished", "Background task finished", ] @pytest.mark.anyio async def test_run_context_manager_exit_even_if_client_disconnects() -> None: # test for https://github.com/Kludex/starlette/issues/1678#issuecomment-1172916042 response_complete = anyio.Event() context_manager_exited = anyio.Event() async def sleep_and_set() -> None: # small delay to give BaseHTTPMiddleware a chance to cancel us # this is required to make the test fail prior to fixing the issue # so do not be surprised if you remove it and the test still passes await anyio.sleep(0.1) context_manager_exited.set() class ContextManagerMiddleware: def __init__(self, app: ASGIApp): self.app = app async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: async with AsyncExitStack() as stack: stack.push_async_callback(sleep_and_set) await self.app(scope, receive, send) async def simple_endpoint(_: Request) -> PlainTextResponse: return PlainTextResponse(background=BackgroundTask(sleep_and_set)) async def passthrough( request: Request, call_next: RequestResponseEndpoint, ) -> Response: return await call_next(request) app = Starlette( middleware=[ Middleware(BaseHTTPMiddleware, dispatch=passthrough), Middleware(ContextManagerMiddleware), ], routes=[Route("/", simple_endpoint)], ) scope = { "type": "http", "version": "3", "method": "GET", "path": "/", } async def receive() -> Message: raise NotImplementedError("Should not be called!") async def send(message: Message) -> None: if message["type"] == "http.response.body": if not message.get("more_body", False): # pragma: no branch response_complete.set() await app(scope, receive, send) assert context_manager_exited.is_set() def test_app_receives_http_disconnect_while_sending_if_discarded( test_client_factory: TestClientFactory, ) -> None: class DiscardingMiddleware(BaseHTTPMiddleware): async def dispatch( self, request: Request, call_next: Any, ) -> PlainTextResponse: # As a matter of ordering, this test targets the case where the downstream # app response is discarded while it is sending a response body. # We need to wait for the downstream app to begin sending a response body # before sending the middleware response that will overwrite the downstream # response. downstream_app_response = await call_next(request) body_generator = downstream_app_response.body_iterator try: await body_generator.__anext__() finally: await body_generator.aclose() return PlainTextResponse("Custom") async def downstream_app( scope: Scope, receive: Receive, send: Send, ) -> None: await send( { "type": "http.response.start", "status": 200, "headers": [ (b"content-type", b"text/plain"), ], } ) async with anyio.create_task_group() as task_group: async def cancel_on_disconnect( *, task_status: TaskStatus[None] = anyio.TASK_STATUS_IGNORED, ) -> None: task_status.started() while True: message = await receive() if message["type"] == "http.disconnect": # pragma: no branch task_group.cancel_scope.cancel() break # Using start instead of start_soon to ensure that # cancel_on_disconnect is scheduled by the event loop # before we start returning the body await task_group.start(cancel_on_disconnect) # A timeout is set for 0.1 second in order to ensure that # we never deadlock the test run in an infinite loop with anyio.move_on_after(0.1): while True: await send( { "type": "http.response.body", "body": b"chunk ", "more_body": True, } ) pytest.fail("http.disconnect should have been received and canceled the scope") # pragma: no cover app = DiscardingMiddleware(downstream_app) client = test_client_factory(app) response = client.get("/does_not_exist") assert response.text == "Custom" def test_app_receives_http_disconnect_after_sending_if_discarded( test_client_factory: TestClientFactory, ) -> None: class DiscardingMiddleware(BaseHTTPMiddleware): async def dispatch( self, request: Request, call_next: RequestResponseEndpoint, ) -> PlainTextResponse: await call_next(request) return PlainTextResponse("Custom") async def downstream_app( 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"first chunk, ", "more_body": True, } ) await send( { "type": "http.response.body", "body": b"second chunk", "more_body": True, } ) message = await receive() assert message["type"] == "http.disconnect" app = DiscardingMiddleware(downstream_app) client = test_client_factory(app) response = client.get("/does_not_exist") assert response.text == "Custom" def test_read_request_stream_in_app_after_middleware_calls_stream( test_client_factory: TestClientFactory, ) -> None: async def homepage(request: Request) -> PlainTextResponse: expected = [b""] async for chunk in request.stream(): assert chunk == expected.pop(0) assert expected == [] return PlainTextResponse("Homepage") class ConsumingMiddleware(BaseHTTPMiddleware): async def dispatch( self, request: Request, call_next: RequestResponseEndpoint, ) -> Response: expected = [b"a", b""] async for chunk in request.stream(): assert chunk == expected.pop(0) assert expected == [] return await call_next(request) app = Starlette( routes=[Route("/", homepage, methods=["POST"])], middleware=[Middleware(ConsumingMiddleware)], ) client: TestClient = test_client_factory(app) response = client.post("/", content=b"a") assert response.status_code == 200 def test_read_request_stream_in_app_after_middleware_calls_body( test_client_factory: TestClientFactory, ) -> None: async def homepage(request: Request) -> PlainTextResponse: expected = [b"a", b""] async for chunk in request.stream(): assert chunk == expected.pop(0) assert expected == [] return PlainTextResponse("Homepage") class ConsumingMiddleware(BaseHTTPMiddleware): async def dispatch( self, request: Request, call_next: RequestResponseEndpoint, ) -> Response: assert await request.body() == b"a" return await call_next(request) app = Starlette( routes=[Route("/", homepage, methods=["POST"])], middleware=[Middleware(ConsumingMiddleware)], ) client: TestClient = test_client_factory(app) response = client.post("/", content=b"a") assert response.status_code == 200 def test_read_request_body_in_app_after_middleware_calls_stream( test_client_factory: TestClientFactory, ) -> None: async def homepage(request: Request) -> PlainTextResponse: assert await request.body() == b"" return PlainTextResponse("Homepage") class ConsumingMiddleware(BaseHTTPMiddleware): async def dispatch( self, request: Request, call_next: RequestResponseEndpoint, ) -> Response: expected = [b"a", b""] async for chunk in request.stream(): assert chunk == expected.pop(0) assert expected == [] return await call_next(request) app = Starlette( routes=[Route("/", homepage, methods=["POST"])], middleware=[Middleware(ConsumingMiddleware)], ) client: TestClient = test_client_factory(app) response = client.post("/", content=b"a") assert response.status_code == 200 def test_read_request_body_in_app_after_middleware_calls_body( test_client_factory: TestClientFactory, ) -> None: async def homepage(request: Request) -> PlainTextResponse: assert await request.body() == b"a" return PlainTextResponse("Homepage") class ConsumingMiddleware(BaseHTTPMiddleware): async def dispatch( self, request: Request, call_next: RequestResponseEndpoint, ) -> Response: assert await request.body() == b"a" return await call_next(request) app = Starlette( routes=[Route("/", homepage, methods=["POST"])], middleware=[Middleware(ConsumingMiddleware)], ) client: TestClient = test_client_factory(app) response = client.post("/", content=b"a") assert response.status_code == 200 def test_read_request_stream_in_dispatch_after_app_calls_stream( test_client_factory: TestClientFactory, ) -> None: async def homepage(request: Request) -> PlainTextResponse: expected = [b"a", b""] async for chunk in request.stream(): assert chunk == expected.pop(0) assert expected == [] return PlainTextResponse("Homepage") class ConsumingMiddleware(BaseHTTPMiddleware): async def dispatch( self, request: Request, call_next: RequestResponseEndpoint, ) -> Response: resp = await call_next(request) with pytest.raises(RuntimeError, match="Stream consumed"): async for _ in request.stream(): raise AssertionError("should not be called") # pragma: no cover return resp app = Starlette( routes=[Route("/", homepage, methods=["POST"])], middleware=[Middleware(ConsumingMiddleware)], ) client: TestClient = test_client_factory(app) response = client.post("/", content=b"a") assert response.status_code == 200 def test_read_request_stream_in_dispatch_after_app_calls_body( test_client_factory: TestClientFactory, ) -> None: async def homepage(request: Request) -> PlainTextResponse: assert await request.body() == b"a" return PlainTextResponse("Homepage") class ConsumingMiddleware(BaseHTTPMiddleware): async def dispatch( self, request: Request, call_next: RequestResponseEndpoint, ) -> Response: resp = await call_next(request) with pytest.raises(RuntimeError, match="Stream consumed"): async for _ in request.stream(): raise AssertionError("should not be called") # pragma: no cover return resp app = Starlette( routes=[Route("/", homepage, methods=["POST"])], middleware=[Middleware(ConsumingMiddleware)], ) client: TestClient = test_client_factory(app) response = client.post("/", content=b"a") assert response.status_code == 200 @pytest.mark.anyio async def test_read_request_stream_in_dispatch_wrapping_app_calls_body() -> None: async def endpoint(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) async for chunk in request.stream(): # pragma: no branch assert chunk == b"2" break await Response()(scope, receive, send) class ConsumingMiddleware(BaseHTTPMiddleware): async def dispatch( self, request: Request, call_next: RequestResponseEndpoint, ) -> Response: expected = b"1" response: Response | None = None async for chunk in request.stream(): # pragma: no branch assert chunk == expected if expected == b"1": response = await call_next(request) expected = b"3" else: break assert response is not None return response async def rcv() -> AsyncGenerator[Message, None]: yield {"type": "http.request", "body": b"1", "more_body": True} yield {"type": "http.request", "body": b"2", "more_body": True} yield {"type": "http.request", "body": b"3"} raise AssertionError( # pragma: no cover "Should not be called, no need to poll for disconnect" ) sent: list[Message] = [] async def send(msg: Message) -> None: sent.append(msg) app: ASGIApp = endpoint app = ConsumingMiddleware(app) rcv_stream = rcv() await app({"type": "http"}, rcv_stream.__anext__, send) assert sent == [ { "type": "http.response.start", "status": 200, "headers": [(b"content-length", b"0")], }, {"type": "http.response.body", "body": b"", "more_body": False}, ] await rcv_stream.aclose() def test_read_request_stream_in_dispatch_after_app_calls_body_with_middleware_calling_body_before_call_next( test_client_factory: TestClientFactory, ) -> None: async def homepage(request: Request) -> PlainTextResponse: assert await request.body() == b"a" return PlainTextResponse("Homepage") class ConsumingMiddleware(BaseHTTPMiddleware): async def dispatch( self, request: Request, call_next: RequestResponseEndpoint, ) -> Response: assert await request.body() == b"a" # this buffers the request body in memory resp = await call_next(request) async for chunk in request.stream(): if chunk: assert chunk == b"a" return resp app = Starlette( routes=[Route("/", homepage, methods=["POST"])], middleware=[Middleware(ConsumingMiddleware)], ) client: TestClient = test_client_factory(app) response = client.post("/", content=b"a") assert response.status_code == 200 def test_read_request_body_in_dispatch_after_app_calls_body_with_middleware_calling_body_before_call_next( test_client_factory: TestClientFactory, ) -> None: async def homepage(request: Request) -> PlainTextResponse: assert await request.body() == b"a" return PlainTextResponse("Homepage") class ConsumingMiddleware(BaseHTTPMiddleware): async def dispatch( self, request: Request, call_next: RequestResponseEndpoint, ) -> Response: assert await request.body() == b"a" # this buffers the request body in memory resp = await call_next(request) assert await request.body() == b"a" # no problem here return resp app = Starlette( routes=[Route("/", homepage, methods=["POST"])], middleware=[Middleware(ConsumingMiddleware)], ) client: TestClient = test_client_factory(app) response = client.post("/", content=b"a") assert response.status_code == 200 @pytest.mark.anyio async def test_read_request_disconnected_client() -> None: """If we receive a disconnect message when the downstream ASGI app calls receive() the Request instance passed into the dispatch function should get marked as disconnected. The downstream ASGI app should not get a ClientDisconnect raised, instead if should just receive the disconnect message. """ async def endpoint(scope: Scope, receive: Receive, send: Send) -> None: msg = await receive() assert msg["type"] == "http.disconnect" await Response()(scope, receive, send) class ConsumingMiddleware(BaseHTTPMiddleware): async def dispatch( self, request: Request, call_next: RequestResponseEndpoint, ) -> Response: response = await call_next(request) disconnected = await request.is_disconnected() assert disconnected is True return response scope = {"type": "http", "method": "POST", "path": "/"} async def receive() -> AsyncGenerator[Message, None]: yield {"type": "http.disconnect"} raise AssertionError("Should not be called, would hang") # pragma: no cover async def send(msg: Message) -> None: if msg["type"] == "http.response.start": assert msg["status"] == 200 app: ASGIApp = ConsumingMiddleware(endpoint) rcv = receive() await app(scope, rcv.__anext__, send) await rcv.aclose() @pytest.mark.anyio async def test_read_request_disconnected_after_consuming_steam() -> None: async def endpoint(scope: Scope, receive: Receive, send: Send) -> None: msg = await receive() assert msg.pop("more_body", False) is False assert msg == {"type": "http.request", "body": b"hi"} msg = await receive() assert msg == {"type": "http.disconnect"} await Response()(scope, receive, send) class ConsumingMiddleware(BaseHTTPMiddleware): async def dispatch( self, request: Request, call_next: RequestResponseEndpoint, ) -> Response: await request.body() disconnected = await request.is_disconnected() assert disconnected is True response = await call_next(request) return response scope = {"type": "http", "method": "POST", "path": "/"} async def receive() -> AsyncGenerator[Message, None]: yield {"type": "http.request", "body": b"hi"} yield {"type": "http.disconnect"} raise AssertionError("Should not be called, would hang") # pragma: no cover async def send(msg: Message) -> None: if msg["type"] == "http.response.start": assert msg["status"] == 200 app: ASGIApp = ConsumingMiddleware(endpoint) rcv = receive() await app(scope, rcv.__anext__, send) await rcv.aclose() def test_downstream_middleware_modifies_receive( test_client_factory: TestClientFactory, ) -> None: """If a downstream middleware modifies receive() the final ASGI app should see the modified version. """ async def endpoint(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) body = await request.body() assert body == b"foo foo " await Response()(scope, receive, send) class ConsumingMiddleware(BaseHTTPMiddleware): async def dispatch( self, request: Request, call_next: RequestResponseEndpoint, ) -> Response: body = await request.body() assert body == b"foo " return await call_next(request) def modifying_middleware(app: ASGIApp) -> ASGIApp: async def wrapped_app(scope: Scope, receive: Receive, send: Send) -> None: async def wrapped_receive() -> Message: msg = await receive() if msg["type"] == "http.request": # pragma: no branch msg["body"] = msg["body"] * 2 return msg await app(scope, wrapped_receive, send) return wrapped_app client = test_client_factory(ConsumingMiddleware(modifying_middleware(endpoint))) resp = client.post("/", content=b"foo ") assert resp.status_code == 200 def test_pr_1519_comment_1236166180_example() -> None: """ https://github.com/Kludex/starlette/pull/1519#issuecomment-1236166180 """ bodies: list[bytes] = [] class LogRequestBodySize(BaseHTTPMiddleware): async def dispatch( self, request: Request, call_next: RequestResponseEndpoint, ) -> Response: print(len(await request.body())) return await call_next(request) def replace_body_middleware(app: ASGIApp) -> ASGIApp: async def wrapped_app(scope: Scope, receive: Receive, send: Send) -> None: async def wrapped_rcv() -> Message: msg = await receive() msg["body"] += b"-foo" return msg await app(scope, wrapped_rcv, send) return wrapped_app async def endpoint(request: Request) -> Response: body = await request.body() bodies.append(body) return Response() app: ASGIApp = Starlette(routes=[Route("/", endpoint, methods=["POST"])]) app = replace_body_middleware(app) app = LogRequestBodySize(app) client = TestClient(app) resp = client.post("/", content=b"Hello, World!") resp.raise_for_status() assert bodies == [b"Hello, World!-foo"] @pytest.mark.anyio async def test_multiple_middlewares_stacked_client_disconnected() -> None: """ Tests for: - https://github.com/Kludex/starlette/issues/2516 - https://github.com/Kludex/starlette/pull/2687 """ ordered_events: list[str] = [] unordered_events: list[str] = [] class MyMiddleware(BaseHTTPMiddleware): def __init__(self, app: ASGIApp, version: int) -> None: self.version = version super().__init__(app) async def dispatch(self, request: Request, call_next: RequestResponseEndpoint) -> Response: ordered_events.append(f"{self.version}:STARTED") res = await call_next(request) ordered_events.append(f"{self.version}:COMPLETED") def background() -> None: unordered_events.append(f"{self.version}:BACKGROUND") assert res.background is None res.background = BackgroundTask(background) return res async def sleepy(request: Request) -> Response: try: await request.body() except ClientDisconnect: pass else: # pragma: no cover raise AssertionError("Should have raised ClientDisconnect") return Response(b"") app = Starlette( routes=[Route("/", sleepy)], middleware=[Middleware(MyMiddleware, version=_ + 1) for _ in range(10)], ) scope = { "type": "http", "version": "3", "method": "GET", "path": "/", } async def receive() -> AsyncIterator[Message]: yield {"type": "http.disconnect"} sent: list[Message] = [] async def send(message: Message) -> None: sent.append(message) await app(scope, receive().__anext__, send) assert ordered_events == [ "1:STARTED", "2:STARTED", "3:STARTED", "4:STARTED", "5:STARTED", "6:STARTED", "7:STARTED", "8:STARTED", "9:STARTED", "10:STARTED", "10:COMPLETED", "9:COMPLETED", "8:COMPLETED", "7:COMPLETED", "6:COMPLETED", "5:COMPLETED", "4:COMPLETED", "3:COMPLETED", "2:COMPLETED", "1:COMPLETED", ] assert sorted(unordered_events) == sorted( [ "1:BACKGROUND", "2:BACKGROUND", "3:BACKGROUND", "4:BACKGROUND", "5:BACKGROUND", "6:BACKGROUND", "7:BACKGROUND", "8:BACKGROUND", "9:BACKGROUND", "10:BACKGROUND", ] ) assert sent == [ { "type": "http.response.start", "status": 200, "headers": [(b"content-length", b"0")], }, {"type": "http.response.body", "body": b"", "more_body": False}, ] @pytest.mark.anyio @pytest.mark.parametrize("send_body", [True, False]) async def test_poll_for_disconnect_repeated(send_body: bool) -> None: async def app_poll_disconnect(scope: Scope, receive: Receive, send: Send) -> None: for _ in range(2): msg = await receive() while msg["type"] == "http.request": msg = await receive() assert msg["type"] == "http.disconnect" await Response(b"good!")(scope, receive, send) class MyMiddleware(BaseHTTPMiddleware): async def dispatch(self, request: Request, call_next: RequestResponseEndpoint) -> Response: return await call_next(request) app = MyMiddleware(app_poll_disconnect) scope = { "type": "http", "version": "3", "method": "GET", "path": "/", } async def receive() -> AsyncIterator[Message]: # the key here is that we only ever send 1 htt.disconnect message if send_body: yield {"type": "http.request", "body": b"hello", "more_body": True} yield {"type": "http.request", "body": b"", "more_body": False} yield {"type": "http.disconnect"} raise AssertionError("Should not be called, would hang") # pragma: no cover sent: list[Message] = [] async def send(message: Message) -> None: sent.append(message) await app(scope, receive().__anext__, send) assert sent == [ { "type": "http.response.start", "status": 200, "headers": [(b"content-length", b"5")], }, {"type": "http.response.body", "body": b"good!", "more_body": True}, {"type": "http.response.body", "body": b"", "more_body": False}, ] @pytest.mark.anyio async def test_asgi_pathsend_events(tmpdir: Path) -> None: path = tmpdir / "example.txt" with path.open("w") as file: file.write("") response_complete = anyio.Event() events: list[Message] = [] async def endpoint_with_pathsend(_: Request) -> FileResponse: return FileResponse(path) async def passthrough(request: Request, call_next: RequestResponseEndpoint) -> Response: return await call_next(request) app = Starlette( middleware=[Middleware(BaseHTTPMiddleware, dispatch=passthrough)], routes=[Route("/", endpoint_with_pathsend)], ) scope = { "type": "http", "version": "3", "method": "GET", "path": "/", "headers": [], "extensions": {"http.response.pathsend": {}}, } async def receive() -> Message: raise NotImplementedError("Should not be called!") # pragma: no cover async def send(message: Message) -> None: events.append(message) if message["type"] == "http.response.pathsend": response_complete.set() await app(scope, receive, send) assert len(events) == 2 assert events[0]["type"] == "http.response.start" assert events[1]["type"] == "http.response.pathsend" def test_error_context_propagation(test_client_factory: TestClientFactory) -> None: class PassthroughMiddleware(BaseHTTPMiddleware): async def dispatch( self, request: Request, call_next: RequestResponseEndpoint, ) -> Response: return await call_next(request) def exception_without_context(request: Request) -> None: raise Exception("Exception") def exception_with_context(request: Request) -> None: try: raise Exception("Inner exception") except Exception: raise Exception("Outer exception") def exception_with_cause(request: Request) -> None: try: raise Exception("Inner exception") except Exception as e: raise Exception("Outer exception") from e app = Starlette( routes=[ Route("/exception-without-context", endpoint=exception_without_context), Route("/exception-with-context", endpoint=exception_with_context), Route("/exception-with-cause", endpoint=exception_with_cause), ], middleware=[Middleware(PassthroughMiddleware)], ) client = test_client_factory(app) # For exceptions without context the context is filled with the `anyio.EndOfStream` # but it is suppressed therefore not propagated to traceback. with pytest.raises(Exception) as ctx: client.get("/exception-without-context") assert str(ctx.value) == "Exception" assert ctx.value.__cause__ is None assert ctx.value.__context__ is not None assert ctx.value.__suppress_context__ is True # For exceptions with context the context is propagated as a cause to avoid # `anyio.EndOfStream` error from overwriting it. with pytest.raises(Exception) as ctx: client.get("/exception-with-context") assert str(ctx.value) == "Outer exception" assert ctx.value.__cause__ is not None assert str(ctx.value.__cause__) == "Inner exception" # For exceptions with cause check that it gets correctly propagated. with pytest.raises(Exception) as ctx: client.get("/exception-with-cause") assert str(ctx.value) == "Outer exception" assert ctx.value.__cause__ is not None assert str(ctx.value.__cause__) == "Inner exception" starlette-0.50.0/tests/middleware/test_cors.py000066400000000000000000000450601510142272400214440ustar00rootroot00000000000000from starlette.applications import Starlette from starlette.middleware import Middleware from starlette.middleware.cors import CORSMiddleware from starlette.requests import Request from starlette.responses import PlainTextResponse from starlette.routing import Route from tests.types import TestClientFactory def test_cors_allow_all( test_client_factory: TestClientFactory, ) -> None: def homepage(request: Request) -> PlainTextResponse: return PlainTextResponse("Homepage", status_code=200) app = Starlette( routes=[Route("/", endpoint=homepage)], middleware=[ Middleware( CORSMiddleware, allow_origins=["*"], allow_headers=["*"], allow_methods=["*"], expose_headers=["X-Status"], allow_credentials=True, ) ], ) client = test_client_factory(app) # Test pre-flight response headers = { "Origin": "https://example.org", "Access-Control-Request-Method": "GET", "Access-Control-Request-Headers": "X-Example", } response = client.options("/", headers=headers) assert response.status_code == 200 assert response.text == "OK" assert response.headers["access-control-allow-origin"] == "https://example.org" assert response.headers["access-control-allow-headers"] == "X-Example" assert response.headers["access-control-allow-credentials"] == "true" assert response.headers["vary"] == "Origin" # Test standard response headers = {"Origin": "https://example.org"} response = client.get("/", headers=headers) assert response.status_code == 200 assert response.text == "Homepage" assert response.headers["access-control-allow-origin"] == "*" assert response.headers["access-control-expose-headers"] == "X-Status" assert response.headers["access-control-allow-credentials"] == "true" # Test standard credentialed response headers = {"Origin": "https://example.org", "Cookie": "star_cookie=sugar"} response = client.get("/", headers=headers) assert response.status_code == 200 assert response.text == "Homepage" assert response.headers["access-control-allow-origin"] == "https://example.org" assert response.headers["access-control-expose-headers"] == "X-Status" assert response.headers["access-control-allow-credentials"] == "true" # Test non-CORS response response = client.get("/") assert response.status_code == 200 assert response.text == "Homepage" assert "access-control-allow-origin" not in response.headers def test_cors_allow_all_except_credentials( test_client_factory: TestClientFactory, ) -> None: def homepage(request: Request) -> PlainTextResponse: return PlainTextResponse("Homepage", status_code=200) app = Starlette( routes=[Route("/", endpoint=homepage)], middleware=[ Middleware( CORSMiddleware, allow_origins=["*"], allow_headers=["*"], allow_methods=["*"], expose_headers=["X-Status"], ) ], ) client = test_client_factory(app) # Test pre-flight response headers = { "Origin": "https://example.org", "Access-Control-Request-Method": "GET", "Access-Control-Request-Headers": "X-Example", } response = client.options("/", headers=headers) assert response.status_code == 200 assert response.text == "OK" assert response.headers["access-control-allow-origin"] == "*" assert response.headers["access-control-allow-headers"] == "X-Example" assert "access-control-allow-credentials" not in response.headers assert "vary" not in response.headers # Test standard response headers = {"Origin": "https://example.org"} response = client.get("/", headers=headers) assert response.status_code == 200 assert response.text == "Homepage" assert response.headers["access-control-allow-origin"] == "*" assert response.headers["access-control-expose-headers"] == "X-Status" assert "access-control-allow-credentials" not in response.headers # Test non-CORS response response = client.get("/") assert response.status_code == 200 assert response.text == "Homepage" assert "access-control-allow-origin" not in response.headers def test_cors_allow_specific_origin( test_client_factory: TestClientFactory, ) -> None: def homepage(request: Request) -> PlainTextResponse: return PlainTextResponse("Homepage", status_code=200) app = Starlette( routes=[Route("/", endpoint=homepage)], middleware=[ Middleware( CORSMiddleware, allow_origins=["https://example.org"], allow_headers=["X-Example", "Content-Type"], ) ], ) client = test_client_factory(app) # Test pre-flight response headers = { "Origin": "https://example.org", "Access-Control-Request-Method": "GET", "Access-Control-Request-Headers": "X-Example, Content-Type", } response = client.options("/", headers=headers) assert response.status_code == 200 assert response.text == "OK" assert response.headers["access-control-allow-origin"] == "https://example.org" assert response.headers["access-control-allow-headers"] == ( "Accept, Accept-Language, Content-Language, Content-Type, X-Example" ) assert "access-control-allow-credentials" not in response.headers # Test standard response headers = {"Origin": "https://example.org"} response = client.get("/", headers=headers) assert response.status_code == 200 assert response.text == "Homepage" assert response.headers["access-control-allow-origin"] == "https://example.org" assert "access-control-allow-credentials" not in response.headers # Test non-CORS response response = client.get("/") assert response.status_code == 200 assert response.text == "Homepage" assert "access-control-allow-origin" not in response.headers def test_cors_disallowed_preflight( test_client_factory: TestClientFactory, ) -> None: def homepage(request: Request) -> None: pass # pragma: no cover app = Starlette( routes=[Route("/", endpoint=homepage)], middleware=[ Middleware( CORSMiddleware, allow_origins=["https://example.org"], allow_headers=["X-Example"], ) ], ) client = test_client_factory(app) # Test pre-flight response headers = { "Origin": "https://another.org", "Access-Control-Request-Method": "POST", "Access-Control-Request-Headers": "X-Nope", } response = client.options("/", headers=headers) assert response.status_code == 400 assert response.text == "Disallowed CORS origin, method, headers" assert "access-control-allow-origin" not in response.headers # Bug specific test, https://github.com/Kludex/starlette/pull/1199 # Test preflight response text with multiple disallowed headers headers = { "Origin": "https://example.org", "Access-Control-Request-Method": "GET", "Access-Control-Request-Headers": "X-Nope-1, X-Nope-2", } response = client.options("/", headers=headers) assert response.text == "Disallowed CORS headers" def test_preflight_allows_request_origin_if_origins_wildcard_and_credentials_allowed( test_client_factory: TestClientFactory, ) -> None: def homepage(request: Request) -> None: return # pragma: no cover app = Starlette( routes=[Route("/", endpoint=homepage)], middleware=[ Middleware( CORSMiddleware, allow_origins=["*"], allow_methods=["POST"], allow_credentials=True, ) ], ) client = test_client_factory(app) # Test pre-flight response headers = { "Origin": "https://example.org", "Access-Control-Request-Method": "POST", } response = client.options( "/", headers=headers, ) assert response.status_code == 200 assert response.headers["access-control-allow-origin"] == "https://example.org" assert response.headers["access-control-allow-credentials"] == "true" assert response.headers["vary"] == "Origin" def test_cors_preflight_allow_all_methods( test_client_factory: TestClientFactory, ) -> None: def homepage(request: Request) -> None: pass # pragma: no cover app = Starlette( routes=[Route("/", endpoint=homepage)], middleware=[Middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"])], ) client = test_client_factory(app) headers = { "Origin": "https://example.org", "Access-Control-Request-Method": "POST", } for method in ("DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"): response = client.options("/", headers=headers) assert response.status_code == 200 assert method in response.headers["access-control-allow-methods"] def test_cors_allow_all_methods( test_client_factory: TestClientFactory, ) -> None: def homepage(request: Request) -> PlainTextResponse: return PlainTextResponse("Homepage", status_code=200) app = Starlette( routes=[ Route( "/", endpoint=homepage, methods=["delete", "get", "head", "options", "patch", "post", "put"], ) ], middleware=[Middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"])], ) client = test_client_factory(app) headers = {"Origin": "https://example.org"} for method in ("patch", "post", "put"): response = getattr(client, method)("/", headers=headers, json={}) assert response.status_code == 200 for method in ("delete", "get", "head", "options"): response = getattr(client, method)("/", headers=headers) assert response.status_code == 200 def test_cors_allow_origin_regex( test_client_factory: TestClientFactory, ) -> None: def homepage(request: Request) -> PlainTextResponse: return PlainTextResponse("Homepage", status_code=200) app = Starlette( routes=[Route("/", endpoint=homepage)], middleware=[ Middleware( CORSMiddleware, allow_headers=["X-Example", "Content-Type"], allow_origin_regex="https://.*", allow_credentials=True, ) ], ) client = test_client_factory(app) # Test standard response headers = {"Origin": "https://example.org"} response = client.get("/", headers=headers) assert response.status_code == 200 assert response.text == "Homepage" assert response.headers["access-control-allow-origin"] == "https://example.org" assert response.headers["access-control-allow-credentials"] == "true" # Test standard credentialed response headers = {"Origin": "https://example.org", "Cookie": "star_cookie=sugar"} response = client.get("/", headers=headers) assert response.status_code == 200 assert response.text == "Homepage" assert response.headers["access-control-allow-origin"] == "https://example.org" assert response.headers["access-control-allow-credentials"] == "true" # Test disallowed standard response # Note that enforcement is a browser concern. The disallowed-ness is reflected # in the lack of an "access-control-allow-origin" header in the response. headers = {"Origin": "http://example.org"} response = client.get("/", headers=headers) assert response.status_code == 200 assert response.text == "Homepage" assert "access-control-allow-origin" not in response.headers # Test pre-flight response headers = { "Origin": "https://another.com", "Access-Control-Request-Method": "GET", "Access-Control-Request-Headers": "X-Example, content-type", } response = client.options("/", headers=headers) assert response.status_code == 200 assert response.text == "OK" assert response.headers["access-control-allow-origin"] == "https://another.com" assert response.headers["access-control-allow-headers"] == ( "Accept, Accept-Language, Content-Language, Content-Type, X-Example" ) assert response.headers["access-control-allow-credentials"] == "true" # Test disallowed pre-flight response headers = { "Origin": "http://another.com", "Access-Control-Request-Method": "GET", "Access-Control-Request-Headers": "X-Example", } response = client.options("/", headers=headers) assert response.status_code == 400 assert response.text == "Disallowed CORS origin" assert "access-control-allow-origin" not in response.headers def test_cors_allow_origin_regex_fullmatch( test_client_factory: TestClientFactory, ) -> None: def homepage(request: Request) -> PlainTextResponse: return PlainTextResponse("Homepage", status_code=200) app = Starlette( routes=[Route("/", endpoint=homepage)], middleware=[ Middleware( CORSMiddleware, allow_headers=["X-Example", "Content-Type"], allow_origin_regex=r"https://.*\.example.org", ) ], ) client = test_client_factory(app) # Test standard response headers = {"Origin": "https://subdomain.example.org"} response = client.get("/", headers=headers) assert response.status_code == 200 assert response.text == "Homepage" assert response.headers["access-control-allow-origin"] == "https://subdomain.example.org" assert "access-control-allow-credentials" not in response.headers # Test diallowed standard response headers = {"Origin": "https://subdomain.example.org.hacker.com"} response = client.get("/", headers=headers) assert response.status_code == 200 assert response.text == "Homepage" assert "access-control-allow-origin" not in response.headers def test_cors_credentialed_requests_return_specific_origin( test_client_factory: TestClientFactory, ) -> None: def homepage(request: Request) -> PlainTextResponse: return PlainTextResponse("Homepage", status_code=200) app = Starlette( routes=[Route("/", endpoint=homepage)], middleware=[Middleware(CORSMiddleware, allow_origins=["*"])], ) client = test_client_factory(app) # Test credentialed request headers = {"Origin": "https://example.org", "Cookie": "star_cookie=sugar"} response = client.get("/", headers=headers) assert response.status_code == 200 assert response.text == "Homepage" assert response.headers["access-control-allow-origin"] == "https://example.org" assert "access-control-allow-credentials" not in response.headers def test_cors_vary_header_defaults_to_origin( test_client_factory: TestClientFactory, ) -> None: def homepage(request: Request) -> PlainTextResponse: return PlainTextResponse("Homepage", status_code=200) app = Starlette( routes=[Route("/", endpoint=homepage)], middleware=[Middleware(CORSMiddleware, allow_origins=["https://example.org"])], ) headers = {"Origin": "https://example.org"} client = test_client_factory(app) response = client.get("/", headers=headers) assert response.status_code == 200 assert response.headers["vary"] == "Origin" def test_cors_vary_header_is_not_set_for_non_credentialed_request( test_client_factory: TestClientFactory, ) -> None: def homepage(request: Request) -> PlainTextResponse: return PlainTextResponse("Homepage", status_code=200, headers={"Vary": "Accept-Encoding"}) app = Starlette( routes=[Route("/", endpoint=homepage)], middleware=[Middleware(CORSMiddleware, allow_origins=["*"])], ) client = test_client_factory(app) response = client.get("/", headers={"Origin": "https://someplace.org"}) assert response.status_code == 200 assert response.headers["vary"] == "Accept-Encoding" def test_cors_vary_header_is_properly_set_for_credentialed_request( test_client_factory: TestClientFactory, ) -> None: def homepage(request: Request) -> PlainTextResponse: return PlainTextResponse("Homepage", status_code=200, headers={"Vary": "Accept-Encoding"}) app = Starlette( routes=[Route("/", endpoint=homepage)], middleware=[Middleware(CORSMiddleware, allow_origins=["*"])], ) client = test_client_factory(app) response = client.get("/", headers={"Cookie": "foo=bar", "Origin": "https://someplace.org"}) assert response.status_code == 200 assert response.headers["vary"] == "Accept-Encoding, Origin" def test_cors_vary_header_is_properly_set_when_allow_origins_is_not_wildcard( test_client_factory: TestClientFactory, ) -> None: def homepage(request: Request) -> PlainTextResponse: return PlainTextResponse("Homepage", status_code=200, headers={"Vary": "Accept-Encoding"}) app = Starlette( routes=[ Route("/", endpoint=homepage), ], middleware=[Middleware(CORSMiddleware, allow_origins=["https://example.org"])], ) client = test_client_factory(app) response = client.get("/", headers={"Origin": "https://example.org"}) assert response.status_code == 200 assert response.headers["vary"] == "Accept-Encoding, Origin" def test_cors_allowed_origin_does_not_leak_between_credentialed_requests( test_client_factory: TestClientFactory, ) -> None: def homepage(request: Request) -> PlainTextResponse: return PlainTextResponse("Homepage", status_code=200) app = Starlette( routes=[ Route("/", endpoint=homepage), ], middleware=[ Middleware( CORSMiddleware, allow_origins=["*"], allow_headers=["*"], allow_methods=["*"], ) ], ) client = test_client_factory(app) response = client.get("/", headers={"Origin": "https://someplace.org"}) assert response.headers["access-control-allow-origin"] == "*" assert "access-control-allow-credentials" not in response.headers response = client.get("/", headers={"Cookie": "foo=bar", "Origin": "https://someplace.org"}) assert response.headers["access-control-allow-origin"] == "https://someplace.org" assert "access-control-allow-credentials" not in response.headers response = client.get("/", headers={"Origin": "https://someplace.org"}) assert response.headers["access-control-allow-origin"] == "*" assert "access-control-allow-credentials" not in response.headers starlette-0.50.0/tests/middleware/test_errors.py000066400000000000000000000073271510142272400220160ustar00rootroot00000000000000from typing import Any import pytest from starlette.applications import Starlette from starlette.background import BackgroundTask from starlette.middleware.errors import ServerErrorMiddleware from starlette.requests import Request from starlette.responses import JSONResponse, Response from starlette.routing import Route from starlette.types import Receive, Scope, Send from tests.types import TestClientFactory def test_handler( test_client_factory: TestClientFactory, ) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: raise RuntimeError("Something went wrong") def error_500(request: Request, exc: Exception) -> JSONResponse: return JSONResponse({"detail": "Server Error"}, status_code=500) app = ServerErrorMiddleware(app, handler=error_500) client = test_client_factory(app, raise_server_exceptions=False) response = client.get("/") assert response.status_code == 500 assert response.json() == {"detail": "Server Error"} def test_debug_text(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: raise RuntimeError("Something went wrong") app = ServerErrorMiddleware(app, debug=True) client = test_client_factory(app, raise_server_exceptions=False) response = client.get("/") assert response.status_code == 500 assert response.headers["content-type"].startswith("text/plain") assert "RuntimeError: Something went wrong" in response.text def test_debug_html(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: raise RuntimeError("Something went wrong") app = ServerErrorMiddleware(app, debug=True) client = test_client_factory(app, raise_server_exceptions=False) response = client.get("/", headers={"Accept": "text/html, */*"}) assert response.status_code == 500 assert response.headers["content-type"].startswith("text/html") assert "RuntimeError" in response.text def test_debug_after_response_sent(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: response = Response(b"", status_code=204) await response(scope, receive, send) raise RuntimeError("Something went wrong") app = ServerErrorMiddleware(app, debug=True) client = test_client_factory(app) with pytest.raises(RuntimeError): client.get("/") def test_debug_not_http(test_client_factory: TestClientFactory) -> None: """ DebugMiddleware should just pass through any non-http messages as-is. """ async def app(scope: Scope, receive: Receive, send: Send) -> None: raise RuntimeError("Something went wrong") app = ServerErrorMiddleware(app) with pytest.raises(RuntimeError): client = test_client_factory(app) with client.websocket_connect("/"): pass # pragma: no cover def test_background_task(test_client_factory: TestClientFactory) -> None: accessed_error_handler = False def error_handler(request: Request, exc: Exception) -> Any: nonlocal accessed_error_handler accessed_error_handler = True def raise_exception() -> None: raise Exception("Something went wrong") async def endpoint(request: Request) -> Response: task = BackgroundTask(raise_exception) return Response(status_code=204, background=task) app = Starlette( routes=[Route("/", endpoint=endpoint)], exception_handlers={Exception: error_handler}, ) client = test_client_factory(app, raise_server_exceptions=False) response = client.get("/") assert response.status_code == 204 assert accessed_error_handler starlette-0.50.0/tests/middleware/test_gzip.py000066400000000000000000000157711510142272400214550ustar00rootroot00000000000000from __future__ import annotations from pathlib import Path import pytest from starlette.applications import Starlette from starlette.middleware import Middleware from starlette.middleware.gzip import GZipMiddleware from starlette.requests import Request from starlette.responses import ContentStream, FileResponse, PlainTextResponse, StreamingResponse from starlette.routing import Route from starlette.types import Message from tests.types import TestClientFactory def test_gzip_responses(test_client_factory: TestClientFactory) -> None: def homepage(request: Request) -> PlainTextResponse: return PlainTextResponse("x" * 4000, status_code=200) app = Starlette( routes=[Route("/", endpoint=homepage)], middleware=[Middleware(GZipMiddleware)], ) client = test_client_factory(app) response = client.get("/", headers={"accept-encoding": "gzip"}) assert response.status_code == 200 assert response.text == "x" * 4000 assert response.headers["Content-Encoding"] == "gzip" assert response.headers["Vary"] == "Accept-Encoding" assert int(response.headers["Content-Length"]) < 4000 def test_gzip_not_in_accept_encoding(test_client_factory: TestClientFactory) -> None: def homepage(request: Request) -> PlainTextResponse: return PlainTextResponse("x" * 4000, status_code=200) app = Starlette( routes=[Route("/", endpoint=homepage)], middleware=[Middleware(GZipMiddleware)], ) client = test_client_factory(app) response = client.get("/", headers={"accept-encoding": "identity"}) assert response.status_code == 200 assert response.text == "x" * 4000 assert "Content-Encoding" not in response.headers assert response.headers["Vary"] == "Accept-Encoding" assert int(response.headers["Content-Length"]) == 4000 def test_gzip_ignored_for_small_responses( test_client_factory: TestClientFactory, ) -> None: def homepage(request: Request) -> PlainTextResponse: return PlainTextResponse("OK", status_code=200) app = Starlette( routes=[Route("/", endpoint=homepage)], middleware=[Middleware(GZipMiddleware)], ) client = test_client_factory(app) response = client.get("/", headers={"accept-encoding": "gzip"}) assert response.status_code == 200 assert response.text == "OK" assert "Content-Encoding" not in response.headers assert "Vary" not in response.headers assert int(response.headers["Content-Length"]) == 2 def test_gzip_streaming_response(test_client_factory: TestClientFactory) -> None: def homepage(request: Request) -> StreamingResponse: async def generator(bytes: bytes, count: int) -> ContentStream: for index in range(count): yield bytes streaming = generator(bytes=b"x" * 400, count=10) return StreamingResponse(streaming, status_code=200) app = Starlette( routes=[Route("/", endpoint=homepage)], middleware=[Middleware(GZipMiddleware)], ) client = test_client_factory(app) response = client.get("/", headers={"accept-encoding": "gzip"}) assert response.status_code == 200 assert response.text == "x" * 4000 assert response.headers["Content-Encoding"] == "gzip" assert response.headers["Vary"] == "Accept-Encoding" assert "Content-Length" not in response.headers def test_gzip_streaming_response_identity(test_client_factory: TestClientFactory) -> None: def homepage(request: Request) -> StreamingResponse: async def generator(bytes: bytes, count: int) -> ContentStream: for index in range(count): yield bytes streaming = generator(bytes=b"x" * 400, count=10) return StreamingResponse(streaming, status_code=200) app = Starlette( routes=[Route("/", endpoint=homepage)], middleware=[Middleware(GZipMiddleware)], ) client = test_client_factory(app) response = client.get("/", headers={"accept-encoding": "identity"}) assert response.status_code == 200 assert response.text == "x" * 4000 assert "Content-Encoding" not in response.headers assert response.headers["Vary"] == "Accept-Encoding" assert "Content-Length" not in response.headers def test_gzip_ignored_for_responses_with_encoding_set( test_client_factory: TestClientFactory, ) -> None: def homepage(request: Request) -> StreamingResponse: async def generator(bytes: bytes, count: int) -> ContentStream: for index in range(count): yield bytes streaming = generator(bytes=b"x" * 400, count=10) return StreamingResponse(streaming, status_code=200, headers={"Content-Encoding": "text"}) app = Starlette( routes=[Route("/", endpoint=homepage)], middleware=[Middleware(GZipMiddleware)], ) client = test_client_factory(app) response = client.get("/", headers={"accept-encoding": "gzip, text"}) assert response.status_code == 200 assert response.text == "x" * 4000 assert response.headers["Content-Encoding"] == "text" assert "Vary" not in response.headers assert "Content-Length" not in response.headers def test_gzip_ignored_on_server_sent_events(test_client_factory: TestClientFactory) -> None: def homepage(request: Request) -> StreamingResponse: async def generator(bytes: bytes, count: int) -> ContentStream: for _ in range(count): yield bytes streaming = generator(bytes=b"x" * 400, count=10) return StreamingResponse(streaming, status_code=200, media_type="text/event-stream") app = Starlette( routes=[Route("/", endpoint=homepage)], middleware=[Middleware(GZipMiddleware)], ) client = test_client_factory(app) response = client.get("/", headers={"accept-encoding": "gzip"}) assert response.status_code == 200 assert response.text == "x" * 4000 assert "Content-Encoding" not in response.headers assert "Content-Length" not in response.headers @pytest.mark.anyio async def test_gzip_ignored_for_pathsend_responses(tmpdir: Path) -> None: path = tmpdir / "example.txt" with path.open("w") as file: file.write("") events: list[Message] = [] async def endpoint_with_pathsend(request: Request) -> FileResponse: _ = await request.body() return FileResponse(path) app = Starlette( routes=[Route("/", endpoint=endpoint_with_pathsend)], middleware=[Middleware(GZipMiddleware)], ) scope = { "type": "http", "version": "3", "method": "GET", "path": "/", "headers": [(b"accept-encoding", b"gzip, text")], "extensions": {"http.response.pathsend": {}}, } async def receive() -> Message: return {"type": "http.request", "body": b"", "more_body": False} async def send(message: Message) -> None: events.append(message) await app(scope, receive, send) assert len(events) == 2 assert events[0]["type"] == "http.response.start" assert events[1]["type"] == "http.response.pathsend" starlette-0.50.0/tests/middleware/test_https_redirect.py000066400000000000000000000032411510142272400235140ustar00rootroot00000000000000from starlette.applications import Starlette from starlette.middleware import Middleware from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware from starlette.requests import Request from starlette.responses import PlainTextResponse from starlette.routing import Route from tests.types import TestClientFactory def test_https_redirect_middleware(test_client_factory: TestClientFactory) -> None: def homepage(request: Request) -> PlainTextResponse: return PlainTextResponse("OK", status_code=200) app = Starlette( routes=[Route("/", endpoint=homepage)], middleware=[Middleware(HTTPSRedirectMiddleware)], ) client = test_client_factory(app, base_url="https://testserver") response = client.get("/") assert response.status_code == 200 client = test_client_factory(app) response = client.get("/", follow_redirects=False) assert response.status_code == 307 assert response.headers["location"] == "https://testserver/" client = test_client_factory(app, base_url="http://testserver:80") response = client.get("/", follow_redirects=False) assert response.status_code == 307 assert response.headers["location"] == "https://testserver/" client = test_client_factory(app, base_url="http://testserver:443") response = client.get("/", follow_redirects=False) assert response.status_code == 307 assert response.headers["location"] == "https://testserver/" client = test_client_factory(app, base_url="http://testserver:123") response = client.get("/", follow_redirects=False) assert response.status_code == 307 assert response.headers["location"] == "https://testserver:123/" starlette-0.50.0/tests/middleware/test_middleware.py000066400000000000000000000014101510142272400226020ustar00rootroot00000000000000from starlette.middleware import Middleware from starlette.types import ASGIApp, Receive, Scope, Send class CustomMiddleware: # pragma: no cover def __init__(self, app: ASGIApp, foo: str, *, bar: int) -> None: self.app = app self.foo = foo self.bar = bar async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: await self.app(scope, receive, send) def test_middleware_repr() -> None: middleware = Middleware(CustomMiddleware, "foo", bar=123) assert repr(middleware) == "Middleware(CustomMiddleware, 'foo', bar=123)" def test_middleware_iter() -> None: cls, args, kwargs = Middleware(CustomMiddleware, "foo", bar=123) assert (cls, args, kwargs) == (CustomMiddleware, ("foo",), {"bar": 123}) starlette-0.50.0/tests/middleware/test_session.py000066400000000000000000000170111510142272400221540ustar00rootroot00000000000000import re from starlette.applications import Starlette from starlette.middleware import Middleware from starlette.middleware.sessions import SessionMiddleware from starlette.requests import Request from starlette.responses import JSONResponse from starlette.routing import Mount, Route from starlette.testclient import TestClient from tests.types import TestClientFactory def view_session(request: Request) -> JSONResponse: return JSONResponse({"session": request.session}) async def update_session(request: Request) -> JSONResponse: data = await request.json() request.session.update(data) return JSONResponse({"session": request.session}) async def clear_session(request: Request) -> JSONResponse: request.session.clear() return JSONResponse({"session": request.session}) def test_session(test_client_factory: TestClientFactory) -> None: app = Starlette( routes=[ Route("/view_session", endpoint=view_session), Route("/update_session", endpoint=update_session, methods=["POST"]), Route("/clear_session", endpoint=clear_session, methods=["POST"]), ], middleware=[Middleware(SessionMiddleware, secret_key="example")], ) client = test_client_factory(app) response = client.get("/view_session") assert response.json() == {"session": {}} response = client.post("/update_session", json={"some": "data"}) assert response.json() == {"session": {"some": "data"}} # check cookie max-age set_cookie = response.headers["set-cookie"] max_age_matches = re.search(r"; Max-Age=([0-9]+);", set_cookie) assert max_age_matches is not None assert int(max_age_matches[1]) == 14 * 24 * 3600 response = client.get("/view_session") assert response.json() == {"session": {"some": "data"}} response = client.post("/clear_session") assert response.json() == {"session": {}} response = client.get("/view_session") assert response.json() == {"session": {}} def test_session_expires(test_client_factory: TestClientFactory) -> None: app = Starlette( routes=[ Route("/view_session", endpoint=view_session), Route("/update_session", endpoint=update_session, methods=["POST"]), ], middleware=[Middleware(SessionMiddleware, secret_key="example", max_age=-1)], ) client = test_client_factory(app) response = client.post("/update_session", json={"some": "data"}) assert response.json() == {"session": {"some": "data"}} # requests removes expired cookies from response.cookies, we need to # fetch session id from the headers and pass it explicitly expired_cookie_header = response.headers["set-cookie"] expired_session_match = re.search(r"session=([^;]*);", expired_cookie_header) assert expired_session_match is not None expired_session_value = expired_session_match[1] client = test_client_factory(app, cookies={"session": expired_session_value}) response = client.get("/view_session") assert response.json() == {"session": {}} def test_secure_session(test_client_factory: TestClientFactory) -> None: app = Starlette( routes=[ Route("/view_session", endpoint=view_session), Route("/update_session", endpoint=update_session, methods=["POST"]), Route("/clear_session", endpoint=clear_session, methods=["POST"]), ], middleware=[Middleware(SessionMiddleware, secret_key="example", https_only=True)], ) secure_client = test_client_factory(app, base_url="https://testserver") unsecure_client = test_client_factory(app, base_url="http://testserver") response = unsecure_client.get("/view_session") assert response.json() == {"session": {}} response = unsecure_client.post("/update_session", json={"some": "data"}) assert response.json() == {"session": {"some": "data"}} response = unsecure_client.get("/view_session") assert response.json() == {"session": {}} response = secure_client.get("/view_session") assert response.json() == {"session": {}} response = secure_client.post("/update_session", json={"some": "data"}) assert response.json() == {"session": {"some": "data"}} response = secure_client.get("/view_session") assert response.json() == {"session": {"some": "data"}} response = secure_client.post("/clear_session") assert response.json() == {"session": {}} response = secure_client.get("/view_session") assert response.json() == {"session": {}} def test_session_cookie_subpath(test_client_factory: TestClientFactory) -> None: second_app = Starlette( routes=[ Route("/update_session", endpoint=update_session, methods=["POST"]), ], middleware=[Middleware(SessionMiddleware, secret_key="example", path="/second_app")], ) app = Starlette(routes=[Mount("/second_app", app=second_app)]) client = test_client_factory(app, base_url="http://testserver/second_app") response = client.post("/update_session", json={"some": "data"}) assert response.status_code == 200 cookie = response.headers["set-cookie"] cookie_path_match = re.search(r"; path=(\S+);", cookie) assert cookie_path_match is not None cookie_path = cookie_path_match.groups()[0] assert cookie_path == "/second_app" def test_invalid_session_cookie(test_client_factory: TestClientFactory) -> None: app = Starlette( routes=[ Route("/view_session", endpoint=view_session), Route("/update_session", endpoint=update_session, methods=["POST"]), ], middleware=[Middleware(SessionMiddleware, secret_key="example")], ) client = test_client_factory(app) response = client.post("/update_session", json={"some": "data"}) assert response.json() == {"session": {"some": "data"}} # we expect it to not raise an exception if we provide a bogus session cookie client = test_client_factory(app, cookies={"session": "invalid"}) response = client.get("/view_session") assert response.json() == {"session": {}} def test_session_cookie(test_client_factory: TestClientFactory) -> None: app = Starlette( routes=[ Route("/view_session", endpoint=view_session), Route("/update_session", endpoint=update_session, methods=["POST"]), ], middleware=[Middleware(SessionMiddleware, secret_key="example", max_age=None)], ) client: TestClient = test_client_factory(app) response = client.post("/update_session", json={"some": "data"}) assert response.json() == {"session": {"some": "data"}} # check cookie max-age set_cookie = response.headers["set-cookie"] assert "Max-Age" not in set_cookie client.cookies.delete("session") response = client.get("/view_session") assert response.json() == {"session": {}} def test_domain_cookie(test_client_factory: TestClientFactory) -> None: app = Starlette( routes=[ Route("/view_session", endpoint=view_session), Route("/update_session", endpoint=update_session, methods=["POST"]), ], middleware=[Middleware(SessionMiddleware, secret_key="example", domain=".example.com")], ) client: TestClient = test_client_factory(app) response = client.post("/update_session", json={"some": "data"}) assert response.json() == {"session": {"some": "data"}} # check cookie max-age set_cookie = response.headers["set-cookie"] assert "domain=.example.com" in set_cookie client.cookies.delete("session") response = client.get("/view_session") assert response.json() == {"session": {}} starlette-0.50.0/tests/middleware/test_trusted_host.py000066400000000000000000000034071510142272400232240ustar00rootroot00000000000000from starlette.applications import Starlette from starlette.middleware import Middleware from starlette.middleware.trustedhost import TrustedHostMiddleware from starlette.requests import Request from starlette.responses import PlainTextResponse from starlette.routing import Route from tests.types import TestClientFactory def test_trusted_host_middleware(test_client_factory: TestClientFactory) -> None: def homepage(request: Request) -> PlainTextResponse: return PlainTextResponse("OK", status_code=200) app = Starlette( routes=[Route("/", endpoint=homepage)], middleware=[Middleware(TrustedHostMiddleware, allowed_hosts=["testserver", "*.testserver"])], ) client = test_client_factory(app) response = client.get("/") assert response.status_code == 200 client = test_client_factory(app, base_url="http://subdomain.testserver") response = client.get("/") assert response.status_code == 200 client = test_client_factory(app, base_url="http://invalidhost") response = client.get("/") assert response.status_code == 400 def test_default_allowed_hosts() -> None: app = Starlette() middleware = TrustedHostMiddleware(app) assert middleware.allowed_hosts == ["*"] def test_www_redirect(test_client_factory: TestClientFactory) -> None: def homepage(request: Request) -> PlainTextResponse: return PlainTextResponse("OK", status_code=200) app = Starlette( routes=[Route("/", endpoint=homepage)], middleware=[Middleware(TrustedHostMiddleware, allowed_hosts=["www.example.com"])], ) client = test_client_factory(app, base_url="https://example.com") response = client.get("/") assert response.status_code == 200 assert response.url == "https://www.example.com/" starlette-0.50.0/tests/middleware/test_wsgi.py000066400000000000000000000117341510142272400214500ustar00rootroot00000000000000import sys from collections.abc import Callable, Iterable from typing import Any import pytest from starlette._utils import collapse_excgroups from starlette.middleware.wsgi import WSGIMiddleware, build_environ from tests.types import TestClientFactory WSGIResponse = Iterable[bytes] StartResponse = Callable[..., Any] Environment = dict[str, Any] def hello_world( environ: Environment, start_response: StartResponse, ) -> WSGIResponse: status = "200 OK" output = b"Hello World!\n" headers = [ ("Content-Type", "text/plain; charset=utf-8"), ("Content-Length", str(len(output))), ] start_response(status, headers) return [output] def echo_body( environ: Environment, start_response: StartResponse, ) -> WSGIResponse: status = "200 OK" output = environ["wsgi.input"].read() headers = [ ("Content-Type", "text/plain; charset=utf-8"), ("Content-Length", str(len(output))), ] start_response(status, headers) return [output] def raise_exception( environ: Environment, start_response: StartResponse, ) -> WSGIResponse: raise RuntimeError("Something went wrong") def return_exc_info( environ: Environment, start_response: StartResponse, ) -> WSGIResponse: try: raise RuntimeError("Something went wrong") except RuntimeError: status = "500 Internal Server Error" output = b"Internal Server Error" headers = [ ("Content-Type", "text/plain; charset=utf-8"), ("Content-Length", str(len(output))), ] start_response(status, headers, exc_info=sys.exc_info()) return [output] def test_wsgi_get(test_client_factory: TestClientFactory) -> None: app = WSGIMiddleware(hello_world) client = test_client_factory(app) response = client.get("/") assert response.status_code == 200 assert response.text == "Hello World!\n" def test_wsgi_post(test_client_factory: TestClientFactory) -> None: app = WSGIMiddleware(echo_body) client = test_client_factory(app) response = client.post("/", json={"example": 123}) assert response.status_code == 200 assert response.text == '{"example":123}' def test_wsgi_exception(test_client_factory: TestClientFactory) -> None: # Note that we're testing the WSGI app directly here. # The HTTP protocol implementations would catch this error and return 500. app = WSGIMiddleware(raise_exception) client = test_client_factory(app) with pytest.raises(RuntimeError), collapse_excgroups(): client.get("/") def test_wsgi_exc_info(test_client_factory: TestClientFactory) -> None: # Note that we're testing the WSGI app directly here. # The HTTP protocol implementations would catch this error and return 500. app = WSGIMiddleware(return_exc_info) client = test_client_factory(app) with pytest.raises(RuntimeError): response = client.get("/") app = WSGIMiddleware(return_exc_info) client = test_client_factory(app, raise_server_exceptions=False) response = client.get("/") assert response.status_code == 500 assert response.text == "Internal Server Error" def test_build_environ() -> None: scope = { "type": "http", "http_version": "1.1", "method": "GET", "scheme": "https", "path": "/sub/", "root_path": "/sub", "query_string": b"a=123&b=456", "headers": [ (b"host", b"www.example.org"), (b"content-type", b"application/json"), (b"content-length", b"18"), (b"accept", b"application/json"), (b"accept", b"text/plain"), ], "client": ("134.56.78.4", 1453), "server": ("www.example.org", 443), } body = b'{"example":"body"}' environ = build_environ(scope, body) stream = environ.pop("wsgi.input") assert stream.read() == b'{"example":"body"}' assert environ == { "CONTENT_LENGTH": "18", "CONTENT_TYPE": "application/json", "HTTP_ACCEPT": "application/json,text/plain", "HTTP_HOST": "www.example.org", "PATH_INFO": "/", "QUERY_STRING": "a=123&b=456", "REMOTE_ADDR": "134.56.78.4", "REQUEST_METHOD": "GET", "SCRIPT_NAME": "/sub", "SERVER_NAME": "www.example.org", "SERVER_PORT": 443, "SERVER_PROTOCOL": "HTTP/1.1", "wsgi.errors": sys.stdout, "wsgi.multiprocess": True, "wsgi.multithread": True, "wsgi.run_once": False, "wsgi.url_scheme": "https", "wsgi.version": (1, 0), } def test_build_environ_encoding() -> None: scope = { "type": "http", "http_version": "1.1", "method": "GET", "path": "/小星", "root_path": "/中国", "query_string": b"a=123&b=456", "headers": [], } environ = build_environ(scope, b"") assert environ["SCRIPT_NAME"] == "/中国".encode().decode("latin-1") assert environ["PATH_INFO"] == "/小星".encode().decode("latin-1") starlette-0.50.0/tests/statics/000077500000000000000000000000001510142272400164155ustar00rootroot00000000000000starlette-0.50.0/tests/statics/example.txt000066400000000000000000000000041510142272400206030ustar00rootroot00000000000000123 starlette-0.50.0/tests/test__utils.py000066400000000000000000000053341510142272400176600ustar00rootroot00000000000000import functools from typing import Any from unittest.mock import create_autospec import pytest from starlette._utils import get_route_path, is_async_callable from starlette.types import Scope def test_async_func() -> None: async def async_func() -> None: ... # pragma: no cover def func() -> None: ... # pragma: no cover assert is_async_callable(async_func) assert not is_async_callable(func) def test_async_partial() -> None: async def async_func(a: Any, b: Any) -> None: ... # pragma: no cover def func(a: Any, b: Any) -> None: ... # pragma: no cover partial = functools.partial(async_func, 1) assert is_async_callable(partial) partial = functools.partial(func, 1) # type: ignore assert not is_async_callable(partial) def test_async_method() -> None: class Async: async def method(self) -> None: ... # pragma: no cover class Sync: def method(self) -> None: ... # pragma: no cover assert is_async_callable(Async().method) assert not is_async_callable(Sync().method) def test_async_object_call() -> None: class Async: async def __call__(self) -> None: ... # pragma: no cover class Sync: def __call__(self) -> None: ... # pragma: no cover assert is_async_callable(Async()) assert not is_async_callable(Sync()) def test_async_partial_object_call() -> None: class Async: async def __call__( self, a: Any, b: Any, ) -> None: ... # pragma: no cover class Sync: def __call__( self, a: Any, b: Any, ) -> None: ... # pragma: no cover partial = functools.partial(Async(), 1) assert is_async_callable(partial) partial = functools.partial(Sync(), 1) # type: ignore assert not is_async_callable(partial) def test_async_nested_partial() -> None: async def async_func( a: Any, b: Any, ) -> None: ... # pragma: no cover partial = functools.partial(async_func, b=2) nested_partial = functools.partial(partial, a=1) assert is_async_callable(nested_partial) def test_async_mocked_async_function() -> None: async def async_func() -> None: ... # pragma: no cover mock = create_autospec(async_func) assert is_async_callable(mock) @pytest.mark.parametrize( "scope, expected_result", [ ({"path": "/foo-123/bar", "root_path": "/foo"}, "/foo-123/bar"), ({"path": "/foo/bar", "root_path": "/foo"}, "/bar"), ({"path": "/foo", "root_path": "/foo"}, ""), ({"path": "/foo/bar", "root_path": "/bar"}, "/foo/bar"), ], ) def test_get_route_path(scope: Scope, expected_result: str) -> None: assert get_route_path(scope) == expected_result starlette-0.50.0/tests/test_applications.py000066400000000000000000000435061510142272400210520ustar00rootroot00000000000000from __future__ import annotations import os from collections.abc import AsyncGenerator, AsyncIterator, Callable, Generator from contextlib import asynccontextmanager from pathlib import Path import anyio.from_thread import pytest from starlette import status from starlette.applications import Starlette from starlette.endpoints import HTTPEndpoint from starlette.exceptions import HTTPException, WebSocketException from starlette.middleware import Middleware from starlette.middleware.base import RequestResponseEndpoint from starlette.middleware.trustedhost import TrustedHostMiddleware from starlette.requests import Request from starlette.responses import JSONResponse, PlainTextResponse from starlette.routing import Host, Mount, Route, Router, WebSocketRoute from starlette.staticfiles import StaticFiles from starlette.testclient import TestClient, WebSocketDenialResponse from starlette.types import ASGIApp, Receive, Scope, Send from starlette.websockets import WebSocket from tests.types import TestClientFactory async def error_500(request: Request, exc: HTTPException) -> JSONResponse: return JSONResponse({"detail": "Server Error"}, status_code=500) async def method_not_allowed(request: Request, exc: HTTPException) -> JSONResponse: return JSONResponse({"detail": "Custom message"}, status_code=405) async def http_exception(request: Request, exc: HTTPException) -> JSONResponse: return JSONResponse({"detail": exc.detail}, status_code=exc.status_code) def func_homepage(request: Request) -> PlainTextResponse: return PlainTextResponse("Hello, world!") async def async_homepage(request: Request) -> PlainTextResponse: return PlainTextResponse("Hello, world!") class Homepage(HTTPEndpoint): def get(self, request: Request) -> PlainTextResponse: return PlainTextResponse("Hello, world!") def all_users_page(request: Request) -> PlainTextResponse: return PlainTextResponse("Hello, everyone!") def user_page(request: Request) -> PlainTextResponse: username = request.path_params["username"] return PlainTextResponse(f"Hello, {username}!") def custom_subdomain(request: Request) -> PlainTextResponse: return PlainTextResponse("Subdomain: " + request.path_params["subdomain"]) def runtime_error(request: Request) -> None: raise RuntimeError() async def websocket_endpoint(session: WebSocket) -> None: await session.accept() await session.send_text("Hello, world!") await session.close() async def websocket_raise_websocket_exception(websocket: WebSocket) -> None: await websocket.accept() raise WebSocketException(code=status.WS_1003_UNSUPPORTED_DATA) async def websocket_raise_http_exception(websocket: WebSocket) -> None: raise HTTPException(status_code=401, detail="Unauthorized") class CustomWSException(Exception): pass async def websocket_raise_custom(websocket: WebSocket) -> None: await websocket.accept() raise CustomWSException() def custom_ws_exception_handler(websocket: WebSocket, exc: CustomWSException) -> None: anyio.from_thread.run(websocket.close, status.WS_1013_TRY_AGAIN_LATER) users = Router( routes=[ Route("/", endpoint=all_users_page), Route("/{username}", endpoint=user_page), ] ) subdomain = Router( routes=[ Route("/", custom_subdomain), ] ) exception_handlers = { 500: error_500, 405: method_not_allowed, HTTPException: http_exception, CustomWSException: custom_ws_exception_handler, } middleware = [Middleware(TrustedHostMiddleware, allowed_hosts=["testserver", "*.example.org"])] app = Starlette( routes=[ Route("/func", endpoint=func_homepage), Route("/async", endpoint=async_homepage), Route("/class", endpoint=Homepage), Route("/500", endpoint=runtime_error), WebSocketRoute("/ws", endpoint=websocket_endpoint), WebSocketRoute("/ws-raise-websocket", endpoint=websocket_raise_websocket_exception), WebSocketRoute("/ws-raise-http", endpoint=websocket_raise_http_exception), WebSocketRoute("/ws-raise-custom", endpoint=websocket_raise_custom), Mount("/users", app=users), Host("{subdomain}.example.org", app=subdomain), ], exception_handlers=exception_handlers, # type: ignore middleware=middleware, ) @pytest.fixture def client(test_client_factory: TestClientFactory) -> Generator[TestClient, None, None]: with test_client_factory(app) as client: yield client def test_url_path_for() -> None: assert app.url_path_for("func_homepage") == "/func" def test_func_route(client: TestClient) -> None: response = client.get("/func") assert response.status_code == 200 assert response.text == "Hello, world!" response = client.head("/func") assert response.status_code == 200 assert response.text == "" def test_async_route(client: TestClient) -> None: response = client.get("/async") assert response.status_code == 200 assert response.text == "Hello, world!" def test_class_route(client: TestClient) -> None: response = client.get("/class") assert response.status_code == 200 assert response.text == "Hello, world!" def test_mounted_route(client: TestClient) -> None: response = client.get("/users/") assert response.status_code == 200 assert response.text == "Hello, everyone!" def test_mounted_route_path_params(client: TestClient) -> None: response = client.get("/users/tomchristie") assert response.status_code == 200 assert response.text == "Hello, tomchristie!" def test_subdomain_route(test_client_factory: TestClientFactory) -> None: client = test_client_factory(app, base_url="https://foo.example.org/") response = client.get("/") assert response.status_code == 200 assert response.text == "Subdomain: foo" def test_websocket_route(client: TestClient) -> None: with client.websocket_connect("/ws") as session: text = session.receive_text() assert text == "Hello, world!" def test_400(client: TestClient) -> None: response = client.get("/404") assert response.status_code == 404 assert response.json() == {"detail": "Not Found"} def test_405(client: TestClient) -> None: response = client.post("/func") assert response.status_code == 405 assert response.json() == {"detail": "Custom message"} response = client.post("/class") assert response.status_code == 405 assert response.json() == {"detail": "Custom message"} def test_500(test_client_factory: TestClientFactory) -> None: client = test_client_factory(app, raise_server_exceptions=False) response = client.get("/500") assert response.status_code == 500 assert response.json() == {"detail": "Server Error"} def test_websocket_raise_websocket_exception(client: TestClient) -> None: with client.websocket_connect("/ws-raise-websocket") as session: response = session.receive() assert response == { "type": "websocket.close", "code": status.WS_1003_UNSUPPORTED_DATA, "reason": "", } def test_websocket_raise_http_exception(client: TestClient) -> None: with pytest.raises(WebSocketDenialResponse) as exc: with client.websocket_connect("/ws-raise-http"): pass # pragma: no cover assert exc.value.status_code == 401 assert exc.value.content == b'{"detail":"Unauthorized"}' def test_websocket_raise_custom_exception(client: TestClient) -> None: with client.websocket_connect("/ws-raise-custom") as session: response = session.receive() assert response == { "type": "websocket.close", "code": status.WS_1013_TRY_AGAIN_LATER, "reason": "", } def test_middleware(test_client_factory: TestClientFactory) -> None: client = test_client_factory(app, base_url="http://incorrecthost") response = client.get("/func") assert response.status_code == 400 assert response.text == "Invalid host header" def test_routes() -> None: assert app.routes == [ Route("/func", endpoint=func_homepage, methods=["GET"]), Route("/async", endpoint=async_homepage, methods=["GET"]), Route("/class", endpoint=Homepage), Route("/500", endpoint=runtime_error, methods=["GET"]), WebSocketRoute("/ws", endpoint=websocket_endpoint), WebSocketRoute("/ws-raise-websocket", endpoint=websocket_raise_websocket_exception), WebSocketRoute("/ws-raise-http", endpoint=websocket_raise_http_exception), WebSocketRoute("/ws-raise-custom", endpoint=websocket_raise_custom), Mount( "/users", app=Router( routes=[ Route("/", endpoint=all_users_page), Route("/{username}", endpoint=user_page), ] ), ), Host( "{subdomain}.example.org", app=Router(routes=[Route("/", endpoint=custom_subdomain)]), ), ] def test_app_mount(tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "example.txt") with open(path, "w") as file: file.write("") app = Starlette( routes=[ Mount("/static", StaticFiles(directory=tmpdir)), ] ) client = test_client_factory(app) response = client.get("/static/example.txt") assert response.status_code == 200 assert response.text == "" response = client.post("/static/example.txt") assert response.status_code == 405 assert response.text == "Method Not Allowed" def test_app_debug(test_client_factory: TestClientFactory) -> None: async def homepage(request: Request) -> None: raise RuntimeError() app = Starlette( routes=[ Route("/", homepage), ], ) app.debug = True client = test_client_factory(app, raise_server_exceptions=False) response = client.get("/") assert response.status_code == 500 assert "RuntimeError" in response.text assert app.debug def test_app_add_route(test_client_factory: TestClientFactory) -> None: async def homepage(request: Request) -> PlainTextResponse: return PlainTextResponse("Hello, World!") app = Starlette( routes=[ Route("/", endpoint=homepage), ] ) client = test_client_factory(app) response = client.get("/") assert response.status_code == 200 assert response.text == "Hello, World!" def test_app_add_websocket_route(test_client_factory: TestClientFactory) -> None: async def websocket_endpoint(session: WebSocket) -> None: await session.accept() await session.send_text("Hello, world!") await session.close() app = Starlette( routes=[ WebSocketRoute("/ws", endpoint=websocket_endpoint), ] ) client = test_client_factory(app) with client.websocket_connect("/ws") as session: text = session.receive_text() assert text == "Hello, world!" def test_app_add_event_handler(test_client_factory: TestClientFactory) -> None: startup_complete = False cleanup_complete = False def run_startup() -> None: nonlocal startup_complete startup_complete = True def run_cleanup() -> None: nonlocal cleanup_complete cleanup_complete = True with pytest.deprecated_call(match="The on_startup and on_shutdown parameters are deprecated"): app = Starlette( on_startup=[run_startup], on_shutdown=[run_cleanup], ) assert not startup_complete assert not cleanup_complete with test_client_factory(app): assert startup_complete assert not cleanup_complete assert startup_complete assert cleanup_complete def test_app_async_cm_lifespan(test_client_factory: TestClientFactory) -> None: startup_complete = False cleanup_complete = False @asynccontextmanager async def lifespan(app: ASGIApp) -> AsyncGenerator[None, None]: nonlocal startup_complete, cleanup_complete startup_complete = True yield cleanup_complete = True app = Starlette(lifespan=lifespan) assert not startup_complete assert not cleanup_complete with test_client_factory(app): assert startup_complete assert not cleanup_complete assert startup_complete assert cleanup_complete deprecated_lifespan = pytest.mark.filterwarnings( r"ignore" r":(async )?generator function lifespans are deprecated, use an " r"@contextlib\.asynccontextmanager function instead" r":DeprecationWarning" r":starlette.routing" ) @deprecated_lifespan def test_app_async_gen_lifespan(test_client_factory: TestClientFactory) -> None: startup_complete = False cleanup_complete = False async def lifespan(app: ASGIApp) -> AsyncGenerator[None, None]: nonlocal startup_complete, cleanup_complete startup_complete = True yield cleanup_complete = True app = Starlette(lifespan=lifespan) # type: ignore assert not startup_complete assert not cleanup_complete with test_client_factory(app): assert startup_complete assert not cleanup_complete assert startup_complete assert cleanup_complete @deprecated_lifespan def test_app_sync_gen_lifespan(test_client_factory: TestClientFactory) -> None: startup_complete = False cleanup_complete = False def lifespan(app: ASGIApp) -> Generator[None, None, None]: nonlocal startup_complete, cleanup_complete startup_complete = True yield cleanup_complete = True app = Starlette(lifespan=lifespan) # type: ignore assert not startup_complete assert not cleanup_complete with test_client_factory(app): assert startup_complete assert not cleanup_complete assert startup_complete assert cleanup_complete def test_decorator_deprecations() -> None: app = Starlette() with pytest.deprecated_call( match=("The `exception_handler` decorator is deprecated, and will be removed in version 1.0.0.") ) as record: app.exception_handler(500)(http_exception) assert len(record) == 1 with pytest.deprecated_call( match=("The `middleware` decorator is deprecated, and will be removed in version 1.0.0.") ) as record: async def middleware(request: Request, call_next: RequestResponseEndpoint) -> None: ... # pragma: no cover app.middleware("http")(middleware) assert len(record) == 1 with pytest.deprecated_call( match=("The `route` decorator is deprecated, and will be removed in version 1.0.0.") ) as record: app.route("/")(async_homepage) assert len(record) == 1 with pytest.deprecated_call( match=("The `websocket_route` decorator is deprecated, and will be removed in version 1.0.0.") ) as record: app.websocket_route("/ws")(websocket_endpoint) assert len(record) == 1 with pytest.deprecated_call( match=("The `on_event` decorator is deprecated, and will be removed in version 1.0.0.") ) as record: async def startup() -> None: ... # pragma: no cover app.on_event("startup")(startup) assert len(record) == 1 def test_middleware_stack_init(test_client_factory: TestClientFactory) -> None: class NoOpMiddleware: def __init__(self, app: ASGIApp): self.app = app async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: await self.app(scope, receive, send) class SimpleInitializableMiddleware: counter = 0 def __init__(self, app: ASGIApp): self.app = app SimpleInitializableMiddleware.counter += 1 async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: await self.app(scope, receive, send) def get_app() -> ASGIApp: app = Starlette() app.add_middleware(SimpleInitializableMiddleware) app.add_middleware(NoOpMiddleware) return app app = get_app() with test_client_factory(app): pass assert SimpleInitializableMiddleware.counter == 1 test_client_factory(app).get("/foo") assert SimpleInitializableMiddleware.counter == 1 app = get_app() test_client_factory(app).get("/foo") assert SimpleInitializableMiddleware.counter == 2 def test_middleware_args(test_client_factory: TestClientFactory) -> None: calls: list[str] = [] class MiddlewareWithArgs: def __init__(self, app: ASGIApp, arg: str) -> None: self.app = app self.arg = arg async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: calls.append(self.arg) await self.app(scope, receive, send) app = Starlette() app.add_middleware(MiddlewareWithArgs, "foo") app.add_middleware(MiddlewareWithArgs, "bar") with test_client_factory(app): pass assert calls == ["bar", "foo"] def test_middleware_factory(test_client_factory: TestClientFactory) -> None: calls: list[str] = [] def _middleware_factory(app: ASGIApp, arg: str) -> ASGIApp: async def _app(scope: Scope, receive: Receive, send: Send) -> None: calls.append(arg) await app(scope, receive, send) return _app def get_middleware_factory() -> Callable[[ASGIApp, str], ASGIApp]: return _middleware_factory app = Starlette() app.add_middleware(_middleware_factory, arg="foo") app.add_middleware(get_middleware_factory(), "bar") with test_client_factory(app): pass assert calls == ["bar", "foo"] def test_lifespan_app_subclass() -> None: # This test exists to make sure that subclasses of Starlette # (like FastAPI) are compatible with the types hints for Lifespan class App(Starlette): pass @asynccontextmanager async def lifespan(app: App) -> AsyncIterator[None]: # pragma: no cover yield App(lifespan=lifespan) starlette-0.50.0/tests/test_authentication.py000066400000000000000000000275521510142272400214060ustar00rootroot00000000000000from __future__ import annotations import base64 import binascii from collections.abc import Awaitable, Callable from typing import Any from urllib.parse import urlencode import pytest from starlette.applications import Starlette from starlette.authentication import AuthCredentials, AuthenticationBackend, AuthenticationError, SimpleUser, requires from starlette.endpoints import HTTPEndpoint from starlette.middleware import Middleware from starlette.middleware.authentication import AuthenticationMiddleware from starlette.requests import HTTPConnection, Request from starlette.responses import JSONResponse, Response from starlette.routing import Route, WebSocketRoute from starlette.websockets import WebSocket, WebSocketDisconnect from tests.types import TestClientFactory AsyncEndpoint = Callable[..., Awaitable[Response]] SyncEndpoint = Callable[..., Response] class BasicAuth(AuthenticationBackend): async def authenticate( self, request: HTTPConnection, ) -> tuple[AuthCredentials, SimpleUser] | None: if "Authorization" not in request.headers: return None auth = request.headers["Authorization"] try: scheme, credentials = auth.split() decoded = base64.b64decode(credentials).decode("ascii") except (ValueError, UnicodeDecodeError, binascii.Error): raise AuthenticationError("Invalid basic auth credentials") username, _, password = decoded.partition(":") return AuthCredentials(["authenticated"]), SimpleUser(username) def homepage(request: Request) -> JSONResponse: return JSONResponse( { "authenticated": request.user.is_authenticated, "user": request.user.display_name, } ) @requires("authenticated") async def dashboard(request: Request) -> JSONResponse: return JSONResponse( { "authenticated": request.user.is_authenticated, "user": request.user.display_name, } ) @requires("authenticated", redirect="homepage") async def admin(request: Request) -> JSONResponse: return JSONResponse( { "authenticated": request.user.is_authenticated, "user": request.user.display_name, } ) @requires("authenticated") def dashboard_sync(request: Request) -> JSONResponse: return JSONResponse( { "authenticated": request.user.is_authenticated, "user": request.user.display_name, } ) class Dashboard(HTTPEndpoint): @requires("authenticated") def get(self, request: Request) -> JSONResponse: return JSONResponse( { "authenticated": request.user.is_authenticated, "user": request.user.display_name, } ) @requires("authenticated", redirect="homepage") def admin_sync(request: Request) -> JSONResponse: return JSONResponse( { "authenticated": request.user.is_authenticated, "user": request.user.display_name, } ) @requires("authenticated") async def websocket_endpoint(websocket: WebSocket) -> None: await websocket.accept() await websocket.send_json( { "authenticated": websocket.user.is_authenticated, "user": websocket.user.display_name, } ) def async_inject_decorator( **kwargs: Any, ) -> Callable[[AsyncEndpoint], Callable[..., Awaitable[Response]]]: def wrapper(endpoint: AsyncEndpoint) -> Callable[..., Awaitable[Response]]: async def app(request: Request) -> Response: return await endpoint(request=request, **kwargs) return app return wrapper @async_inject_decorator(additional="payload") @requires("authenticated") async def decorated_async(request: Request, additional: str) -> JSONResponse: return JSONResponse( { "authenticated": request.user.is_authenticated, "user": request.user.display_name, "additional": additional, } ) def sync_inject_decorator( **kwargs: Any, ) -> Callable[[SyncEndpoint], Callable[..., Response]]: def wrapper(endpoint: SyncEndpoint) -> Callable[..., Response]: def app(request: Request) -> Response: return endpoint(request=request, **kwargs) return app return wrapper @sync_inject_decorator(additional="payload") @requires("authenticated") def decorated_sync(request: Request, additional: str) -> JSONResponse: return JSONResponse( { "authenticated": request.user.is_authenticated, "user": request.user.display_name, "additional": additional, } ) def ws_inject_decorator(**kwargs: Any) -> Callable[..., AsyncEndpoint]: def wrapper(endpoint: AsyncEndpoint) -> AsyncEndpoint: def app(websocket: WebSocket) -> Awaitable[Response]: return endpoint(websocket=websocket, **kwargs) return app return wrapper @ws_inject_decorator(additional="payload") @requires("authenticated") async def websocket_endpoint_decorated(websocket: WebSocket, additional: str) -> None: await websocket.accept() await websocket.send_json( { "authenticated": websocket.user.is_authenticated, "user": websocket.user.display_name, "additional": additional, } ) app = Starlette( middleware=[Middleware(AuthenticationMiddleware, backend=BasicAuth())], routes=[ Route("/", endpoint=homepage), Route("/dashboard", endpoint=dashboard), Route("/admin", endpoint=admin), Route("/dashboard/sync", endpoint=dashboard_sync), Route("/dashboard/class", endpoint=Dashboard), Route("/admin/sync", endpoint=admin_sync), Route("/dashboard/decorated", endpoint=decorated_async), Route("/dashboard/decorated/sync", endpoint=decorated_sync), WebSocketRoute("/ws", endpoint=websocket_endpoint), WebSocketRoute("/ws/decorated", endpoint=websocket_endpoint_decorated), ], ) def test_invalid_decorator_usage() -> None: with pytest.raises(Exception): @requires("authenticated") def foo() -> None: # pragma: no cover pass def test_user_interface(test_client_factory: TestClientFactory) -> None: with test_client_factory(app) as client: response = client.get("/") assert response.status_code == 200 assert response.json() == {"authenticated": False, "user": ""} response = client.get("/", auth=("tomchristie", "example")) assert response.status_code == 200 assert response.json() == {"authenticated": True, "user": "tomchristie"} def test_authentication_required(test_client_factory: TestClientFactory) -> None: with test_client_factory(app) as client: response = client.get("/dashboard") assert response.status_code == 403 response = client.get("/dashboard", auth=("tomchristie", "example")) assert response.status_code == 200 assert response.json() == {"authenticated": True, "user": "tomchristie"} response = client.get("/dashboard/sync") assert response.status_code == 403 response = client.get("/dashboard/sync", auth=("tomchristie", "example")) assert response.status_code == 200 assert response.json() == {"authenticated": True, "user": "tomchristie"} response = client.get("/dashboard/class") assert response.status_code == 403 response = client.get("/dashboard/class", auth=("tomchristie", "example")) assert response.status_code == 200 assert response.json() == {"authenticated": True, "user": "tomchristie"} response = client.get("/dashboard/decorated", auth=("tomchristie", "example")) assert response.status_code == 200 assert response.json() == { "authenticated": True, "user": "tomchristie", "additional": "payload", } response = client.get("/dashboard/decorated") assert response.status_code == 403 response = client.get("/dashboard/decorated/sync", auth=("tomchristie", "example")) assert response.status_code == 200 assert response.json() == { "authenticated": True, "user": "tomchristie", "additional": "payload", } response = client.get("/dashboard/decorated/sync") assert response.status_code == 403 response = client.get("/dashboard", headers={"Authorization": "basic foobar"}) assert response.status_code == 400 assert response.text == "Invalid basic auth credentials" def test_websocket_authentication_required( test_client_factory: TestClientFactory, ) -> None: with test_client_factory(app) as client: with pytest.raises(WebSocketDisconnect): with client.websocket_connect("/ws"): pass # pragma: no cover with pytest.raises(WebSocketDisconnect): with client.websocket_connect("/ws", headers={"Authorization": "basic foobar"}): pass # pragma: no cover with client.websocket_connect("/ws", auth=("tomchristie", "example")) as websocket: data = websocket.receive_json() assert data == {"authenticated": True, "user": "tomchristie"} with pytest.raises(WebSocketDisconnect): with client.websocket_connect("/ws/decorated"): pass # pragma: no cover with pytest.raises(WebSocketDisconnect): with client.websocket_connect("/ws/decorated", headers={"Authorization": "basic foobar"}): pass # pragma: no cover with client.websocket_connect("/ws/decorated", auth=("tomchristie", "example")) as websocket: data = websocket.receive_json() assert data == { "authenticated": True, "user": "tomchristie", "additional": "payload", } def test_authentication_redirect(test_client_factory: TestClientFactory) -> None: with test_client_factory(app) as client: response = client.get("/admin") assert response.status_code == 200 url = "{}?{}".format("http://testserver/", urlencode({"next": "http://testserver/admin"})) assert response.url == url response = client.get("/admin", auth=("tomchristie", "example")) assert response.status_code == 200 assert response.json() == {"authenticated": True, "user": "tomchristie"} response = client.get("/admin/sync") assert response.status_code == 200 url = "{}?{}".format("http://testserver/", urlencode({"next": "http://testserver/admin/sync"})) assert response.url == url response = client.get("/admin/sync", auth=("tomchristie", "example")) assert response.status_code == 200 assert response.json() == {"authenticated": True, "user": "tomchristie"} def on_auth_error(request: HTTPConnection, exc: AuthenticationError) -> JSONResponse: return JSONResponse({"error": str(exc)}, status_code=401) @requires("authenticated") def control_panel(request: Request) -> JSONResponse: return JSONResponse( { "authenticated": request.user.is_authenticated, "user": request.user.display_name, } ) other_app = Starlette( routes=[Route("/control-panel", control_panel)], middleware=[Middleware(AuthenticationMiddleware, backend=BasicAuth(), on_error=on_auth_error)], ) def test_custom_on_error(test_client_factory: TestClientFactory) -> None: with test_client_factory(other_app) as client: response = client.get("/control-panel", auth=("tomchristie", "example")) assert response.status_code == 200 assert response.json() == {"authenticated": True, "user": "tomchristie"} response = client.get("/control-panel", headers={"Authorization": "basic foobar"}) assert response.status_code == 401 assert response.json() == {"error": "Invalid basic auth credentials"} starlette-0.50.0/tests/test_background.py000066400000000000000000000054151510142272400205000ustar00rootroot00000000000000import pytest from starlette.background import BackgroundTask, BackgroundTasks from starlette.responses import Response from starlette.types import Receive, Scope, Send from tests.types import TestClientFactory def test_async_task(test_client_factory: TestClientFactory) -> None: TASK_COMPLETE = False async def async_task() -> None: nonlocal TASK_COMPLETE TASK_COMPLETE = True task = BackgroundTask(async_task) async def app(scope: Scope, receive: Receive, send: Send) -> None: response = Response("task initiated", media_type="text/plain", background=task) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.text == "task initiated" assert TASK_COMPLETE def test_sync_task(test_client_factory: TestClientFactory) -> None: TASK_COMPLETE = False def sync_task() -> None: nonlocal TASK_COMPLETE TASK_COMPLETE = True task = BackgroundTask(sync_task) async def app(scope: Scope, receive: Receive, send: Send) -> None: response = Response("task initiated", media_type="text/plain", background=task) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.text == "task initiated" assert TASK_COMPLETE def test_multiple_tasks(test_client_factory: TestClientFactory) -> None: TASK_COUNTER = 0 def increment(amount: int) -> None: nonlocal TASK_COUNTER TASK_COUNTER += amount async def app(scope: Scope, receive: Receive, send: Send) -> None: tasks = BackgroundTasks() tasks.add_task(increment, amount=1) tasks.add_task(increment, amount=2) tasks.add_task(increment, amount=3) response = Response("tasks initiated", media_type="text/plain", background=tasks) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.text == "tasks initiated" assert TASK_COUNTER == 1 + 2 + 3 def test_multi_tasks_failure_avoids_next_execution( test_client_factory: TestClientFactory, ) -> None: TASK_COUNTER = 0 def increment() -> None: nonlocal TASK_COUNTER TASK_COUNTER += 1 if TASK_COUNTER == 1: # pragma: no branch raise Exception("task failed") async def app(scope: Scope, receive: Receive, send: Send) -> None: tasks = BackgroundTasks() tasks.add_task(increment) tasks.add_task(increment) response = Response("tasks initiated", media_type="text/plain", background=tasks) await response(scope, receive, send) client = test_client_factory(app) with pytest.raises(Exception): client.get("/") assert TASK_COUNTER == 1 starlette-0.50.0/tests/test_concurrency.py000066400000000000000000000030511510142272400207050ustar00rootroot00000000000000from collections.abc import Iterator from contextvars import ContextVar import anyio import pytest from starlette.applications import Starlette from starlette.concurrency import iterate_in_threadpool, run_until_first_complete from starlette.requests import Request from starlette.responses import Response from starlette.routing import Route from tests.types import TestClientFactory @pytest.mark.anyio async def test_run_until_first_complete() -> None: task1_finished = anyio.Event() task2_finished = anyio.Event() async def task1() -> None: task1_finished.set() async def task2() -> None: await task1_finished.wait() await anyio.sleep(0) # pragma: no cover task2_finished.set() # pragma: no cover await run_until_first_complete((task1, {}), (task2, {})) assert task1_finished.is_set() assert not task2_finished.is_set() def test_accessing_context_from_threaded_sync_endpoint( test_client_factory: TestClientFactory, ) -> None: ctxvar: ContextVar[bytes] = ContextVar("ctxvar") ctxvar.set(b"data") def endpoint(request: Request) -> Response: return Response(ctxvar.get()) app = Starlette(routes=[Route("/", endpoint)]) client = test_client_factory(app) resp = client.get("/") assert resp.content == b"data" @pytest.mark.anyio async def test_iterate_in_threadpool() -> None: class CustomIterable: def __iter__(self) -> Iterator[int]: yield from range(3) assert [v async for v in iterate_in_threadpool(CustomIterable())] == [0, 1, 2] starlette-0.50.0/tests/test_config.py000066400000000000000000000120751510142272400176260ustar00rootroot00000000000000import os from pathlib import Path from typing import Any import pytest from typing_extensions import assert_type from starlette.config import Config, Environ, EnvironError from starlette.datastructures import URL, Secret def test_config_types() -> None: """ We use `assert_type` to test the types returned by Config via mypy. """ config = Config(environ={"STR": "some_str_value", "STR_CAST": "some_str_value", "BOOL": "true"}) assert_type(config("STR"), str) assert_type(config("STR_DEFAULT", default=""), str) assert_type(config("STR_CAST", cast=str), str) assert_type(config("STR_NONE", default=None), str | None) assert_type(config("STR_CAST_NONE", cast=str, default=None), str | None) assert_type(config("STR_CAST_STR", cast=str, default=""), str) assert_type(config("BOOL", cast=bool), bool) assert_type(config("BOOL_DEFAULT", cast=bool, default=False), bool) assert_type(config("BOOL_NONE", cast=bool, default=None), bool | None) def cast_to_int(v: Any) -> int: return int(v) # our type annotations allow these `cast` and `default` configurations, but # the code will error at runtime. with pytest.raises(ValueError): config("INT_CAST_DEFAULT_STR", cast=cast_to_int, default="true") with pytest.raises(ValueError): config("INT_DEFAULT_STR", cast=int, default="true") def test_config(tmpdir: Path, monkeypatch: pytest.MonkeyPatch) -> None: path = os.path.join(tmpdir, ".env") with open(path, "w") as file: file.write("# Do not commit to source control\n") file.write("DATABASE_URL=postgres://user:pass@localhost/dbname\n") file.write("REQUEST_HOSTNAME=example.com\n") file.write("SECRET_KEY=12345\n") file.write("BOOL_AS_INT=0\n") file.write("\n") file.write("\n") config = Config(path, environ={"DEBUG": "true"}) def cast_to_int(v: Any) -> int: return int(v) DEBUG = config("DEBUG", cast=bool) DATABASE_URL = config("DATABASE_URL", cast=URL) REQUEST_TIMEOUT = config("REQUEST_TIMEOUT", cast=int, default=10) REQUEST_HOSTNAME = config("REQUEST_HOSTNAME") MAIL_HOSTNAME = config("MAIL_HOSTNAME", default=None) SECRET_KEY = config("SECRET_KEY", cast=Secret) UNSET_SECRET = config("UNSET_SECRET", cast=Secret, default=None) EMPTY_SECRET = config("EMPTY_SECRET", cast=Secret, default="") assert config("BOOL_AS_INT", cast=bool) is False assert config("BOOL_AS_INT", cast=cast_to_int) == 0 assert config("DEFAULTED_BOOL", cast=cast_to_int, default=True) == 1 assert DEBUG is True assert DATABASE_URL.path == "/dbname" assert DATABASE_URL.password == "pass" assert DATABASE_URL.username == "user" assert REQUEST_TIMEOUT == 10 assert REQUEST_HOSTNAME == "example.com" assert MAIL_HOSTNAME is None assert repr(SECRET_KEY) == "Secret('**********')" assert str(SECRET_KEY) == "12345" assert bool(SECRET_KEY) assert not bool(EMPTY_SECRET) assert not bool(UNSET_SECRET) with pytest.raises(KeyError): config.get("MISSING") with pytest.raises(ValueError): config.get("DEBUG", cast=int) with pytest.raises(ValueError): config.get("REQUEST_HOSTNAME", cast=bool) config = Config(Path(path)) REQUEST_HOSTNAME = config("REQUEST_HOSTNAME") assert REQUEST_HOSTNAME == "example.com" config = Config() monkeypatch.setenv("STARLETTE_EXAMPLE_TEST", "123") monkeypatch.setenv("BOOL_AS_INT", "1") assert config.get("STARLETTE_EXAMPLE_TEST", cast=int) == 123 assert config.get("BOOL_AS_INT", cast=bool) is True monkeypatch.setenv("BOOL_AS_INT", "2") with pytest.raises(ValueError): config.get("BOOL_AS_INT", cast=bool) def test_missing_env_file_raises(tmpdir: Path) -> None: path = os.path.join(tmpdir, ".env") with pytest.warns(UserWarning, match=f"Config file '{path}' not found."): Config(path) def test_environ() -> None: environ = Environ() # We can mutate the environ at this point. environ["TESTING"] = "True" environ["GONE"] = "123" del environ["GONE"] # We can read the environ. assert environ["TESTING"] == "True" assert "GONE" not in environ # We cannot mutate these keys now that we've read them. with pytest.raises(EnvironError): environ["TESTING"] = "False" with pytest.raises(EnvironError): del environ["GONE"] # Test coverage of abstract methods for MutableMapping. environ = Environ() assert list(iter(environ)) == list(iter(os.environ)) assert len(environ) == len(os.environ) def test_config_with_env_prefix(tmpdir: Path, monkeypatch: pytest.MonkeyPatch) -> None: config = Config(environ={"APP_DEBUG": "value", "ENVIRONMENT": "dev"}, env_prefix="APP_") assert config.get("DEBUG") == "value" with pytest.raises(KeyError): config.get("ENVIRONMENT") def test_config_with_encoding(tmpdir: Path) -> None: path = tmpdir / ".env" path.write_text("MESSAGE=Hello 世界\n", encoding="utf-8") config = Config(path, encoding="utf-8") assert config.get("MESSAGE") == "Hello 世界" starlette-0.50.0/tests/test_convertors.py000066400000000000000000000063001510142272400205570ustar00rootroot00000000000000from collections.abc import Iterator from datetime import datetime from uuid import UUID import pytest from starlette import convertors from starlette.convertors import Convertor, register_url_convertor from starlette.requests import Request from starlette.responses import JSONResponse from starlette.routing import Route, Router from tests.types import TestClientFactory @pytest.fixture(scope="module", autouse=True) def refresh_convertor_types() -> Iterator[None]: convert_types = convertors.CONVERTOR_TYPES.copy() yield convertors.CONVERTOR_TYPES = convert_types class DateTimeConvertor(Convertor[datetime]): regex = "[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(.[0-9]+)?" def convert(self, value: str) -> datetime: return datetime.strptime(value, "%Y-%m-%dT%H:%M:%S") def to_string(self, value: datetime) -> str: return value.strftime("%Y-%m-%dT%H:%M:%S") @pytest.fixture(scope="function") def app() -> Router: register_url_convertor("datetime", DateTimeConvertor()) def datetime_convertor(request: Request) -> JSONResponse: param = request.path_params["param"] assert isinstance(param, datetime) return JSONResponse({"datetime": param.strftime("%Y-%m-%dT%H:%M:%S")}) return Router( routes=[ Route( "/datetime/{param:datetime}", endpoint=datetime_convertor, name="datetime-convertor", ) ] ) def test_datetime_convertor(test_client_factory: TestClientFactory, app: Router) -> None: client = test_client_factory(app) response = client.get("/datetime/2020-01-01T00:00:00") assert response.json() == {"datetime": "2020-01-01T00:00:00"} assert ( app.url_path_for("datetime-convertor", param=datetime(1996, 1, 22, 23, 0, 0)) == "/datetime/1996-01-22T23:00:00" ) @pytest.mark.parametrize("param, status_code", [("1.0", 200), ("1-0", 404)]) def test_default_float_convertor(test_client_factory: TestClientFactory, param: str, status_code: int) -> None: def float_convertor(request: Request) -> JSONResponse: param = request.path_params["param"] assert isinstance(param, float) return JSONResponse({"float": param}) app = Router(routes=[Route("/{param:float}", endpoint=float_convertor)]) client = test_client_factory(app) response = client.get(f"/{param}") assert response.status_code == status_code @pytest.mark.parametrize( "param, status_code", [ ("00000000-aaaa-ffff-9999-000000000000", 200), ("00000000aaaaffff9999000000000000", 200), ("00000000-AAAA-FFFF-9999-000000000000", 200), ("00000000AAAAFFFF9999000000000000", 200), ("not-a-uuid", 404), ], ) def test_default_uuid_convertor(test_client_factory: TestClientFactory, param: str, status_code: int) -> None: def uuid_convertor(request: Request) -> JSONResponse: param = request.path_params["param"] assert isinstance(param, UUID) return JSONResponse("ok") app = Router(routes=[Route("/{param:uuid}", endpoint=uuid_convertor)]) client = test_client_factory(app) response = client.get(f"/{param}") assert response.status_code == status_code starlette-0.50.0/tests/test_datastructures.py000066400000000000000000000411561510142272400214400ustar00rootroot00000000000000import io from tempfile import SpooledTemporaryFile from typing import BinaryIO import pytest from starlette.datastructures import ( URL, CommaSeparatedStrings, FormData, Headers, MultiDict, MutableHeaders, QueryParams, UploadFile, ) def test_url() -> None: u = URL("https://example.org:123/path/to/somewhere?abc=123#anchor") assert u.scheme == "https" assert u.hostname == "example.org" assert u.port == 123 assert u.netloc == "example.org:123" assert u.username is None assert u.password is None assert u.path == "/path/to/somewhere" assert u.query == "abc=123" assert u.fragment == "anchor" new = u.replace(scheme="http") assert new == "http://example.org:123/path/to/somewhere?abc=123#anchor" assert new.scheme == "http" new = u.replace(port=None) assert new == "https://example.org/path/to/somewhere?abc=123#anchor" assert new.port is None new = u.replace(hostname="example.com") assert new == "https://example.com:123/path/to/somewhere?abc=123#anchor" assert new.hostname == "example.com" ipv6_url = URL("https://[fe::2]:12345") new = ipv6_url.replace(port=8080) assert new == "https://[fe::2]:8080" new = ipv6_url.replace(username="username", password="password") assert new == "https://username:password@[fe::2]:12345" assert new.netloc == "username:password@[fe::2]:12345" ipv6_url = URL("https://[fe::2]") new = ipv6_url.replace(port=123) assert new == "https://[fe::2]:123" url = URL("http://u:p@host/") assert url.replace(hostname="bar") == URL("http://u:p@bar/") url = URL("http://u:p@host:80") assert url.replace(port=88) == URL("http://u:p@host:88") url = URL("http://host:80") assert url.replace(username="u") == URL("http://u@host:80") def test_url_query_params() -> None: u = URL("https://example.org/path/?page=3") assert u.query == "page=3" u = u.include_query_params(page=4) assert str(u) == "https://example.org/path/?page=4" u = u.include_query_params(search="testing") assert str(u) == "https://example.org/path/?page=4&search=testing" u = u.replace_query_params(order="name") assert str(u) == "https://example.org/path/?order=name" u = u.remove_query_params("order") assert str(u) == "https://example.org/path/" u = u.include_query_params(page=4, search="testing") assert str(u) == "https://example.org/path/?page=4&search=testing" u = u.remove_query_params(["page", "search"]) assert str(u) == "https://example.org/path/" def test_hidden_password() -> None: u = URL("https://example.org/path/to/somewhere") assert repr(u) == "URL('https://example.org/path/to/somewhere')" u = URL("https://username@example.org/path/to/somewhere") assert repr(u) == "URL('https://username@example.org/path/to/somewhere')" u = URL("https://username:password@example.org/path/to/somewhere") assert repr(u) == "URL('https://username:********@example.org/path/to/somewhere')" def test_csv() -> None: csv = CommaSeparatedStrings('"localhost", "127.0.0.1", 0.0.0.0') assert list(csv) == ["localhost", "127.0.0.1", "0.0.0.0"] assert repr(csv) == "CommaSeparatedStrings(['localhost', '127.0.0.1', '0.0.0.0'])" assert str(csv) == "'localhost', '127.0.0.1', '0.0.0.0'" assert csv[0] == "localhost" assert len(csv) == 3 csv = CommaSeparatedStrings("'localhost', '127.0.0.1', 0.0.0.0") assert list(csv) == ["localhost", "127.0.0.1", "0.0.0.0"] assert repr(csv) == "CommaSeparatedStrings(['localhost', '127.0.0.1', '0.0.0.0'])" assert str(csv) == "'localhost', '127.0.0.1', '0.0.0.0'" csv = CommaSeparatedStrings("localhost, 127.0.0.1, 0.0.0.0") assert list(csv) == ["localhost", "127.0.0.1", "0.0.0.0"] assert repr(csv) == "CommaSeparatedStrings(['localhost', '127.0.0.1', '0.0.0.0'])" assert str(csv) == "'localhost', '127.0.0.1', '0.0.0.0'" csv = CommaSeparatedStrings(["localhost", "127.0.0.1", "0.0.0.0"]) assert list(csv) == ["localhost", "127.0.0.1", "0.0.0.0"] assert repr(csv) == "CommaSeparatedStrings(['localhost', '127.0.0.1', '0.0.0.0'])" assert str(csv) == "'localhost', '127.0.0.1', '0.0.0.0'" def test_url_from_scope() -> None: u = URL(scope={"path": "/path/to/somewhere", "query_string": b"abc=123", "headers": []}) assert u == "/path/to/somewhere?abc=123" assert repr(u) == "URL('/path/to/somewhere?abc=123')" u = URL( scope={ "scheme": "https", "server": ("example.org", 123), "path": "/path/to/somewhere", "query_string": b"abc=123", "headers": [], } ) assert u == "https://example.org:123/path/to/somewhere?abc=123" assert repr(u) == "URL('https://example.org:123/path/to/somewhere?abc=123')" u = URL( scope={ "scheme": "https", "server": ("example.org", 443), "path": "/path/to/somewhere", "query_string": b"abc=123", "headers": [], } ) assert u == "https://example.org/path/to/somewhere?abc=123" assert repr(u) == "URL('https://example.org/path/to/somewhere?abc=123')" u = URL( scope={ "scheme": "http", "path": "/some/path", "query_string": b"query=string", "headers": [ (b"content-type", b"text/html"), (b"host", b"example.com:8000"), (b"accept", b"text/html"), ], } ) assert u == "http://example.com:8000/some/path?query=string" assert repr(u) == "URL('http://example.com:8000/some/path?query=string')" def test_headers() -> None: h = Headers(raw=[(b"a", b"123"), (b"a", b"456"), (b"b", 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" assert h.get("a") == "123" assert h.get("nope", default=None) is None assert h.getlist("a") == ["123", "456"] assert h.keys() == ["a", "a", "b"] assert h.values() == ["123", "456", "789"] assert h.items() == [("a", "123"), ("a", "456"), ("b", "789")] assert list(h) == ["a", "a", "b"] assert dict(h) == {"a": "123", "b": "789"} assert repr(h) == "Headers(raw=[(b'a', b'123'), (b'a', b'456'), (b'b', b'789')])" assert h == Headers(raw=[(b"a", b"123"), (b"b", b"789"), (b"a", b"456")]) assert h != [(b"a", b"123"), (b"A", b"456"), (b"b", b"789")] h = 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_mutable_headers() -> None: h = MutableHeaders() 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_mutable_headers_merge() -> None: h = MutableHeaders() h = h | MutableHeaders({"a": "1"}) assert isinstance(h, MutableHeaders) assert dict(h) == {"a": "1"} assert h.items() == [("a", "1")] assert h.raw == [(b"a", b"1")] def test_mutable_headers_merge_dict() -> None: h = MutableHeaders() h = h | {"a": "1"} assert isinstance(h, MutableHeaders) assert dict(h) == {"a": "1"} assert h.items() == [("a", "1")] assert h.raw == [(b"a", b"1")] def test_mutable_headers_update() -> None: h = MutableHeaders() h |= MutableHeaders({"a": "1"}) assert isinstance(h, MutableHeaders) assert dict(h) == {"a": "1"} assert h.items() == [("a", "1")] assert h.raw == [(b"a", b"1")] def test_mutable_headers_update_dict() -> None: h = MutableHeaders() h |= {"a": "1"} assert isinstance(h, MutableHeaders) assert dict(h) == {"a": "1"} assert h.items() == [("a", "1")] assert h.raw == [(b"a", b"1")] def test_mutable_headers_merge_not_mapping() -> None: h = MutableHeaders() with pytest.raises(TypeError): h |= {"not_mapping"} # type: ignore[arg-type] with pytest.raises(TypeError): h | {"not_mapping"} # type: ignore[operator] def test_headers_mutablecopy() -> None: h = Headers(raw=[(b"a", b"123"), (b"a", b"456"), (b"b", b"789")]) c = h.mutablecopy() assert c.items() == [("a", "123"), ("a", "456"), ("b", "789")] c["a"] = "abc" assert c.items() == [("a", "abc"), ("b", "789")] def test_mutable_headers_from_scope() -> None: # "headers" in scope must not necessarily be a list h = MutableHeaders(scope={"headers": ((b"a", b"1"),)}) assert dict(h) == {"a": "1"} h.update({"b": "2"}) assert dict(h) == {"a": "1", "b": "2"} assert list(h.items()) == [("a", "1"), ("b", "2")] assert list(h.raw) == [(b"a", b"1"), (b"b", b"2")] def test_url_blank_params() -> None: q = QueryParams("a=123&abc&def&b=456") assert "a" in q assert "abc" in q assert "def" in q assert "b" in q val = q.get("abc") assert val is not None assert len(val) == 0 assert len(q["a"]) == 3 assert list(q.keys()) == ["a", "abc", "def", "b"] def test_queryparams() -> None: q = QueryParams("a=123&a=456&b=789") assert "a" in q assert "A" not in q assert "c" not in q assert q["a"] == "456" assert q.get("a") == "456" assert q.get("nope", default=None) is None assert q.getlist("a") == ["123", "456"] assert list(q.keys()) == ["a", "b"] assert list(q.values()) == ["456", "789"] assert list(q.items()) == [("a", "456"), ("b", "789")] assert len(q) == 2 assert list(q) == ["a", "b"] assert dict(q) == {"a": "456", "b": "789"} assert str(q) == "a=123&a=456&b=789" assert repr(q) == "QueryParams('a=123&a=456&b=789')" assert QueryParams({"a": "123", "b": "456"}) == QueryParams([("a", "123"), ("b", "456")]) assert QueryParams({"a": "123", "b": "456"}) == QueryParams("a=123&b=456") assert QueryParams({"a": "123", "b": "456"}) == QueryParams({"b": "456", "a": "123"}) assert QueryParams() == QueryParams({}) assert QueryParams([("a", "123"), ("a", "456")]) == QueryParams("a=123&a=456") assert QueryParams({"a": "123", "b": "456"}) != "invalid" q = QueryParams([("a", "123"), ("a", "456")]) assert QueryParams(q) == q @pytest.mark.anyio async def test_upload_file_file_input() -> None: """Test passing file/stream into the UploadFile constructor""" stream = io.BytesIO(b"data") file = UploadFile(filename="file", file=stream, size=4) assert await file.read() == b"data" assert file.size == 4 await file.write(b" and more data!") assert await file.read() == b"" assert file.size == 19 await file.seek(0) assert await file.read() == b"data and more data!" @pytest.mark.anyio async def test_upload_file_without_size() -> None: """Test passing file/stream into the UploadFile constructor without size""" stream = io.BytesIO(b"data") file = UploadFile(filename="file", file=stream) assert await file.read() == b"data" assert file.size is None await file.write(b" and more data!") assert await file.read() == b"" assert file.size is None await file.seek(0) assert await file.read() == b"data and more data!" @pytest.mark.anyio @pytest.mark.parametrize("max_size", [1, 1024], ids=["rolled", "unrolled"]) async def test_uploadfile_rolling(max_size: int) -> None: """Test that we can r/w to a SpooledTemporaryFile managed by UploadFile before and after it rolls to disk """ stream: BinaryIO = SpooledTemporaryFile( # type: ignore[assignment] max_size=max_size ) file = UploadFile(filename="file", file=stream, size=0) assert await file.read() == b"" assert file.size == 0 await file.write(b"data") assert await file.read() == b"" assert file.size == 4 await file.seek(0) assert await file.read() == b"data" await file.write(b" more") assert await file.read() == b"" assert file.size == 9 await file.seek(0) assert await file.read() == b"data more" assert file.size == 9 await file.close() def test_formdata() -> None: stream = io.BytesIO(b"data") upload = UploadFile(filename="file", file=stream, size=4) form = FormData([("a", "123"), ("a", "456"), ("b", upload)]) assert "a" in form assert "A" not in form assert "c" not in form assert form["a"] == "456" assert form.get("a") == "456" assert form.get("nope", default=None) is None assert form.getlist("a") == ["123", "456"] assert list(form.keys()) == ["a", "b"] assert list(form.values()) == ["456", upload] assert list(form.items()) == [("a", "456"), ("b", upload)] assert len(form) == 2 assert list(form) == ["a", "b"] assert dict(form) == {"a": "456", "b": upload} assert repr(form) == "FormData([('a', '123'), ('a', '456'), ('b', " + repr(upload) + ")])" assert FormData(form) == form assert FormData({"a": "123", "b": "789"}) == FormData([("a", "123"), ("b", "789")]) assert FormData({"a": "123", "b": "789"}) != {"a": "123", "b": "789"} @pytest.mark.anyio async def test_upload_file_repr() -> None: stream = io.BytesIO(b"data") file = UploadFile(filename="file", file=stream, size=4) assert repr(file) == "UploadFile(filename='file', size=4, headers=Headers({}))" @pytest.mark.anyio async def test_upload_file_repr_headers() -> None: stream = io.BytesIO(b"data") file = UploadFile(filename="file", file=stream, headers=Headers({"foo": "bar"})) assert repr(file) == "UploadFile(filename='file', size=None, headers=Headers({'foo': 'bar'}))" def test_multidict() -> None: q = MultiDict([("a", "123"), ("a", "456"), ("b", "789")]) assert "a" in q assert "A" not in q assert "c" not in q assert q["a"] == "456" assert q.get("a") == "456" assert q.get("nope", default=None) is None assert q.getlist("a") == ["123", "456"] assert list(q.keys()) == ["a", "b"] assert list(q.values()) == ["456", "789"] assert list(q.items()) == [("a", "456"), ("b", "789")] assert len(q) == 2 assert list(q) == ["a", "b"] assert dict(q) == {"a": "456", "b": "789"} assert str(q) == "MultiDict([('a', '123'), ('a', '456'), ('b', '789')])" assert repr(q) == "MultiDict([('a', '123'), ('a', '456'), ('b', '789')])" assert MultiDict({"a": "123", "b": "456"}) == MultiDict([("a", "123"), ("b", "456")]) assert MultiDict({"a": "123", "b": "456"}) == MultiDict({"b": "456", "a": "123"}) assert MultiDict() == MultiDict({}) assert MultiDict({"a": "123", "b": "456"}) != "invalid" q = MultiDict([("a", "123"), ("a", "456")]) assert MultiDict(q) == q q = MultiDict([("a", "123"), ("a", "456")]) q["a"] = "789" assert q["a"] == "789" assert q.get("a") == "789" assert q.getlist("a") == ["789"] q = MultiDict([("a", "123"), ("a", "456")]) del q["a"] assert q.get("a") is None assert repr(q) == "MultiDict([])" q = MultiDict([("a", "123"), ("a", "456"), ("b", "789")]) assert q.pop("a") == "456" assert q.get("a", None) is None assert repr(q) == "MultiDict([('b', '789')])" q = MultiDict([("a", "123"), ("a", "456"), ("b", "789")]) item = q.popitem() assert q.get(item[0]) is None q = MultiDict([("a", "123"), ("a", "456"), ("b", "789")]) assert q.poplist("a") == ["123", "456"] assert q.get("a") is None assert repr(q) == "MultiDict([('b', '789')])" q = MultiDict([("a", "123"), ("a", "456"), ("b", "789")]) q.clear() assert q.get("a") is None assert repr(q) == "MultiDict([])" q = MultiDict([("a", "123")]) q.setlist("a", ["456", "789"]) assert q.getlist("a") == ["456", "789"] q.setlist("b", []) assert "b" not in q q = MultiDict([("a", "123")]) assert q.setdefault("a", "456") == "123" assert q.getlist("a") == ["123"] assert q.setdefault("b", "456") == "456" assert q.getlist("b") == ["456"] assert repr(q) == "MultiDict([('a', '123'), ('b', '456')])" q = MultiDict([("a", "123")]) q.append("a", "456") assert q.getlist("a") == ["123", "456"] assert repr(q) == "MultiDict([('a', '123'), ('a', '456')])" q = MultiDict([("a", "123"), ("b", "456")]) q.update({"a": "789"}) assert q.getlist("a") == ["789"] assert q == MultiDict([("a", "789"), ("b", "456")]) q = MultiDict([("a", "123"), ("b", "456")]) q.update(q) assert repr(q) == "MultiDict([('a', '123'), ('b', '456')])" q = MultiDict([("a", "123"), ("a", "456")]) q.update([("a", "123")]) assert q.getlist("a") == ["123"] q.update([("a", "456")], a="789", b="123") assert q == MultiDict([("a", "456"), ("a", "789"), ("b", "123")]) starlette-0.50.0/tests/test_endpoints.py000066400000000000000000000132241510142272400203610ustar00rootroot00000000000000from collections.abc import Iterator import pytest from starlette.endpoints import HTTPEndpoint, WebSocketEndpoint from starlette.requests import Request from starlette.responses import PlainTextResponse from starlette.routing import Route, Router from starlette.testclient import TestClient from starlette.websockets import WebSocket from tests.types import TestClientFactory class Homepage(HTTPEndpoint): async def get(self, request: Request) -> PlainTextResponse: username = request.path_params.get("username") if username is None: return PlainTextResponse("Hello, world!") return PlainTextResponse(f"Hello, {username}!") app = Router(routes=[Route("/", endpoint=Homepage), Route("/{username}", endpoint=Homepage)]) @pytest.fixture def client(test_client_factory: TestClientFactory) -> Iterator[TestClient]: with test_client_factory(app) as client: yield client def test_http_endpoint_route(client: TestClient) -> None: response = client.get("/") assert response.status_code == 200 assert response.text == "Hello, world!" def test_http_endpoint_route_path_params(client: TestClient) -> None: response = client.get("/tomchristie") assert response.status_code == 200 assert response.text == "Hello, tomchristie!" def test_http_endpoint_route_method(client: TestClient) -> None: response = client.post("/") assert response.status_code == 405 assert response.text == "Method Not Allowed" assert response.headers["allow"] == "GET" def test_websocket_endpoint_on_connect(test_client_factory: TestClientFactory) -> None: class WebSocketApp(WebSocketEndpoint): async def on_connect(self, websocket: WebSocket) -> None: assert websocket["subprotocols"] == ["soap", "wamp"] await websocket.accept(subprotocol="wamp") client = test_client_factory(WebSocketApp) with client.websocket_connect("/ws", subprotocols=["soap", "wamp"]) as websocket: assert websocket.accepted_subprotocol == "wamp" def test_websocket_endpoint_on_receive_bytes( test_client_factory: TestClientFactory, ) -> None: class WebSocketApp(WebSocketEndpoint): encoding = "bytes" async def on_receive(self, websocket: WebSocket, data: bytes) -> None: await websocket.send_bytes(b"Message bytes was: " + data) client = test_client_factory(WebSocketApp) with client.websocket_connect("/ws") as websocket: websocket.send_bytes(b"Hello, world!") _bytes = websocket.receive_bytes() assert _bytes == b"Message bytes was: Hello, world!" with pytest.raises(RuntimeError): with client.websocket_connect("/ws") as websocket: websocket.send_text("Hello world") def test_websocket_endpoint_on_receive_json( test_client_factory: TestClientFactory, ) -> None: class WebSocketApp(WebSocketEndpoint): encoding = "json" async def on_receive(self, websocket: WebSocket, data: str) -> None: await websocket.send_json({"message": data}) client = test_client_factory(WebSocketApp) with client.websocket_connect("/ws") as websocket: websocket.send_json({"hello": "world"}) data = websocket.receive_json() assert data == {"message": {"hello": "world"}} with pytest.raises(RuntimeError): with client.websocket_connect("/ws") as websocket: websocket.send_text("Hello world") def test_websocket_endpoint_on_receive_json_binary( test_client_factory: TestClientFactory, ) -> None: class WebSocketApp(WebSocketEndpoint): encoding = "json" async def on_receive(self, websocket: WebSocket, data: str) -> None: await websocket.send_json({"message": data}, mode="binary") client = test_client_factory(WebSocketApp) with client.websocket_connect("/ws") as websocket: websocket.send_json({"hello": "world"}, mode="binary") data = websocket.receive_json(mode="binary") assert data == {"message": {"hello": "world"}} def test_websocket_endpoint_on_receive_text( test_client_factory: TestClientFactory, ) -> None: class WebSocketApp(WebSocketEndpoint): encoding = "text" async def on_receive(self, websocket: WebSocket, data: str) -> None: await websocket.send_text(f"Message text was: {data}") client = test_client_factory(WebSocketApp) with client.websocket_connect("/ws") as websocket: websocket.send_text("Hello, world!") _text = websocket.receive_text() assert _text == "Message text was: Hello, world!" with pytest.raises(RuntimeError): with client.websocket_connect("/ws") as websocket: websocket.send_bytes(b"Hello world") def test_websocket_endpoint_on_default(test_client_factory: TestClientFactory) -> None: class WebSocketApp(WebSocketEndpoint): encoding = None async def on_receive(self, websocket: WebSocket, data: str) -> None: await websocket.send_text(f"Message text was: {data}") client = test_client_factory(WebSocketApp) with client.websocket_connect("/ws") as websocket: websocket.send_text("Hello, world!") _text = websocket.receive_text() assert _text == "Message text was: Hello, world!" def test_websocket_endpoint_on_disconnect( test_client_factory: TestClientFactory, ) -> None: class WebSocketApp(WebSocketEndpoint): async def on_disconnect(self, websocket: WebSocket, close_code: int) -> None: assert close_code == 1001 await websocket.close(code=close_code) client = test_client_factory(WebSocketApp) with client.websocket_connect("/ws") as websocket: websocket.close(code=1001) starlette-0.50.0/tests/test_exceptions.py000066400000000000000000000174001510142272400205370ustar00rootroot00000000000000from collections.abc import Generator from typing import Any import pytest from pytest import MonkeyPatch from starlette.exceptions import HTTPException, WebSocketException from starlette.middleware.exceptions import ExceptionMiddleware from starlette.requests import Request from starlette.responses import JSONResponse, PlainTextResponse from starlette.routing import Route, Router, WebSocketRoute from starlette.testclient import TestClient from starlette.types import Receive, Scope, Send from tests.types import TestClientFactory def raise_runtime_error(request: Request) -> None: raise RuntimeError("Yikes") def not_acceptable(request: Request) -> None: raise HTTPException(status_code=406) def no_content(request: Request) -> None: raise HTTPException(status_code=204) def not_modified(request: Request) -> None: raise HTTPException(status_code=304) def with_headers(request: Request) -> None: raise HTTPException(status_code=200, headers={"x-potato": "always"}) class BadBodyException(HTTPException): pass async def read_body_and_raise_exc(request: Request) -> None: await request.body() raise BadBodyException(422) async def handler_that_reads_body(request: Request, exc: BadBodyException) -> JSONResponse: body = await request.body() return JSONResponse(status_code=422, content={"body": body.decode()}) class HandledExcAfterResponse: async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: response = PlainTextResponse("OK", status_code=200) await response(scope, receive, send) raise HTTPException(status_code=406) router = Router( routes=[ Route("/runtime_error", endpoint=raise_runtime_error), Route("/not_acceptable", endpoint=not_acceptable), Route("/no_content", endpoint=no_content), Route("/not_modified", endpoint=not_modified), Route("/with_headers", endpoint=with_headers), Route("/handled_exc_after_response", endpoint=HandledExcAfterResponse()), WebSocketRoute("/runtime_error", endpoint=raise_runtime_error), Route("/consume_body_in_endpoint_and_handler", endpoint=read_body_and_raise_exc, methods=["POST"]), ] ) app = ExceptionMiddleware( router, handlers={BadBodyException: handler_that_reads_body}, # type: ignore[dict-item] ) @pytest.fixture def client(test_client_factory: TestClientFactory) -> Generator[TestClient, None, None]: with test_client_factory(app) as client: yield client def test_not_acceptable(client: TestClient) -> None: response = client.get("/not_acceptable") assert response.status_code == 406 assert response.text == "Not Acceptable" def test_no_content(client: TestClient) -> None: response = client.get("/no_content") assert response.status_code == 204 assert "content-length" not in response.headers def test_not_modified(client: TestClient) -> None: response = client.get("/not_modified") assert response.status_code == 304 assert response.text == "" def test_with_headers(client: TestClient) -> None: response = client.get("/with_headers") assert response.status_code == 200 assert response.headers["x-potato"] == "always" def test_websockets_should_raise(client: TestClient) -> None: with pytest.raises(RuntimeError): with client.websocket_connect("/runtime_error"): pass # pragma: no cover def test_handled_exc_after_response(test_client_factory: TestClientFactory, client: TestClient) -> None: # A 406 HttpException is raised *after* the response has already been sent. # The exception middleware should raise a RuntimeError. with pytest.raises(RuntimeError, match="Caught handled exception, but response already started."): client.get("/handled_exc_after_response") # If `raise_server_exceptions=False` then the test client will still allow # us to see the response as it will have been seen by the client. allow_200_client = test_client_factory(app, raise_server_exceptions=False) response = allow_200_client.get("/handled_exc_after_response") assert response.status_code == 200 assert response.text == "OK" def test_force_500_response(test_client_factory: TestClientFactory) -> None: # use a sentinel variable to make sure we actually # make it into the endpoint and don't get a 500 # from an incorrect ASGI app signature or something called = False async def app(scope: Scope, receive: Receive, send: Send) -> None: nonlocal called called = True raise RuntimeError() force_500_client = test_client_factory(app, raise_server_exceptions=False) response = force_500_client.get("/") assert called assert response.status_code == 500 assert response.text == "" def test_http_str() -> None: assert str(HTTPException(status_code=404)) == "404: Not Found" assert str(HTTPException(404, "Not Found: foo")) == "404: Not Found: foo" assert str(HTTPException(404, headers={"key": "value"})) == "404: Not Found" def test_http_repr() -> None: assert repr(HTTPException(404)) == ("HTTPException(status_code=404, detail='Not Found')") assert repr(HTTPException(404, detail="Not Found: foo")) == ( "HTTPException(status_code=404, detail='Not Found: foo')" ) class CustomHTTPException(HTTPException): pass assert repr(CustomHTTPException(500, detail="Something custom")) == ( "CustomHTTPException(status_code=500, detail='Something custom')" ) def test_websocket_str() -> None: assert str(WebSocketException(1008)) == "1008: " assert str(WebSocketException(1008, "Policy Violation")) == "1008: Policy Violation" def test_websocket_repr() -> None: assert repr(WebSocketException(1008, reason="Policy Violation")) == ( "WebSocketException(code=1008, reason='Policy Violation')" ) class CustomWebSocketException(WebSocketException): pass assert ( repr(CustomWebSocketException(1013, reason="Something custom")) == "CustomWebSocketException(code=1013, reason='Something custom')" ) def test_request_in_app_and_handler_is_the_same_object(client: TestClient) -> None: response = client.post("/consume_body_in_endpoint_and_handler", content=b"Hello!") assert response.status_code == 422 assert response.json() == {"body": "Hello!"} def test_http_exception_does_not_use_threadpool(client: TestClient, monkeypatch: MonkeyPatch) -> None: """ Verify that handling HTTPException does not invoke run_in_threadpool, confirming the handler correctly runs in the main async context. """ from starlette import _exception_handler # Replace run_in_threadpool with a function that raises an error def mock_run_in_threadpool(*args: Any, **kwargs: Any) -> None: pytest.fail("run_in_threadpool should not be called for HTTP exceptions") # pragma: no cover # Apply the monkeypatch only during this test monkeypatch.setattr(_exception_handler, "run_in_threadpool", mock_run_in_threadpool) # This should succeed because http_exception is async and won't use run_in_threadpool response = client.get("/not_acceptable") assert response.status_code == 406 def test_handlers_annotations() -> None: """Check that async exception handlers are accepted by type checkers. We annotate the handlers' exceptions with plain `Exception` to avoid variance issues when using other exception types. """ async def async_catch_all_handler(request: Request, exc: Exception) -> JSONResponse: raise NotImplementedError def sync_catch_all_handler(request: Request, exc: Exception) -> JSONResponse: raise NotImplementedError ExceptionMiddleware(router, handlers={Exception: sync_catch_all_handler}) ExceptionMiddleware(router, handlers={Exception: async_catch_all_handler}) starlette-0.50.0/tests/test_formparsers.py000066400000000000000000000662511510142272400207310ustar00rootroot00000000000000from __future__ import annotations import os import threading from collections.abc import Generator from contextlib import AbstractContextManager, nullcontext as does_not_raise from io import BytesIO from pathlib import Path from tempfile import SpooledTemporaryFile from typing import Any, ClassVar from unittest import mock import pytest from starlette.applications import Starlette from starlette.datastructures import UploadFile from starlette.formparsers import MultiPartException, MultiPartParser, _user_safe_decode from starlette.requests import Request from starlette.responses import JSONResponse from starlette.routing import Mount from starlette.types import ASGIApp, Receive, Scope, Send from tests.types import TestClientFactory class ForceMultipartDict(dict[Any, Any]): def __bool__(self) -> bool: return True # FORCE_MULTIPART is an empty dict that boolean-evaluates as `True`. FORCE_MULTIPART = ForceMultipartDict() async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) data = await request.form() output: dict[str, Any] = {} for key, value in data.items(): if isinstance(value, UploadFile): content = await value.read() output[key] = { "filename": value.filename, "size": value.size, "content": content.decode(), "content_type": value.content_type, } else: output[key] = value await request.close() response = JSONResponse(output) await response(scope, receive, send) async def multi_items_app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) data = await request.form() output: dict[str, list[Any]] = {} for key, value in data.multi_items(): if key not in output: output[key] = [] if isinstance(value, UploadFile): content = await value.read() output[key].append( { "filename": value.filename, "size": value.size, "content": content.decode(), "content_type": value.content_type, } ) else: output[key].append(value) await request.close() response = JSONResponse(output) await response(scope, receive, send) async def app_with_headers(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) data = await request.form() output: dict[str, Any] = {} for key, value in data.items(): if isinstance(value, UploadFile): content = await value.read() output[key] = { "filename": value.filename, "size": value.size, "content": content.decode(), "content_type": value.content_type, "headers": list(value.headers.items()), } else: output[key] = value await request.close() response = JSONResponse(output) await response(scope, receive, send) async def app_read_body(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) # Read bytes, to force request.stream() to return the already parsed body await request.body() data = await request.form() output = {} for key, value in data.items(): output[key] = value await request.close() response = JSONResponse(output) await response(scope, receive, send) async def app_monitor_thread(scope: Scope, receive: Receive, send: Send) -> None: """Helper app to monitor what thread the app was called on. This can later be used to validate thread/event loop operations. """ request = Request(scope, receive) # Make sure we parse the form await request.form() await request.close() # Send back the current thread id response = JSONResponse({"thread_ident": threading.current_thread().ident}) await response(scope, receive, send) def make_app_max_parts(max_files: int = 1000, max_fields: int = 1000, max_part_size: int = 1024 * 1024) -> ASGIApp: async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) data = await request.form(max_files=max_files, max_fields=max_fields, max_part_size=max_part_size) output: dict[str, Any] = {} for key, value in data.items(): if isinstance(value, UploadFile): content = await value.read() output[key] = { "filename": value.filename, "size": value.size, "content": content.decode(), "content_type": value.content_type, } else: output[key] = value await request.close() response = JSONResponse(output) await response(scope, receive, send) return app def test_multipart_request_data(tmpdir: Path, test_client_factory: TestClientFactory) -> None: client = test_client_factory(app) response = client.post("/", data={"some": "data"}, files=FORCE_MULTIPART) assert response.json() == {"some": "data"} def test_multipart_request_files(tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "test.txt") with open(path, "wb") as file: file.write(b"") client = test_client_factory(app) with open(path, "rb") as f: response = client.post("/", files={"test": f}) assert response.json() == { "test": { "filename": "test.txt", "size": 14, "content": "", "content_type": "text/plain", } } def test_multipart_request_files_with_content_type(tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "test.txt") with open(path, "wb") as file: file.write(b"") client = test_client_factory(app) with open(path, "rb") as f: response = client.post("/", files={"test": ("test.txt", f, "text/plain")}) assert response.json() == { "test": { "filename": "test.txt", "size": 14, "content": "", "content_type": "text/plain", } } def test_multipart_request_multiple_files(tmpdir: Path, test_client_factory: TestClientFactory) -> None: path1 = os.path.join(tmpdir, "test1.txt") with open(path1, "wb") as file: file.write(b"") path2 = os.path.join(tmpdir, "test2.txt") with open(path2, "wb") as file: file.write(b"") client = test_client_factory(app) with open(path1, "rb") as f1, open(path2, "rb") as f2: response = client.post("/", files={"test1": f1, "test2": ("test2.txt", f2, "text/plain")}) assert response.json() == { "test1": { "filename": "test1.txt", "size": 15, "content": "", "content_type": "text/plain", }, "test2": { "filename": "test2.txt", "size": 15, "content": "", "content_type": "text/plain", }, } def test_multipart_request_multiple_files_with_headers(tmpdir: Path, test_client_factory: TestClientFactory) -> None: path1 = os.path.join(tmpdir, "test1.txt") with open(path1, "wb") as file: file.write(b"") path2 = os.path.join(tmpdir, "test2.txt") with open(path2, "wb") as file: file.write(b"") client = test_client_factory(app_with_headers) with open(path1, "rb") as f1, open(path2, "rb") as f2: response = client.post( "/", files=[ ("test1", (None, f1)), ("test2", ("test2.txt", f2, "text/plain", {"x-custom": "f2"})), ], ) assert response.json() == { "test1": "", "test2": { "filename": "test2.txt", "size": 15, "content": "", "content_type": "text/plain", "headers": [ [ "content-disposition", 'form-data; name="test2"; filename="test2.txt"', ], ["x-custom", "f2"], ["content-type", "text/plain"], ], }, } def test_multi_items(tmpdir: Path, test_client_factory: TestClientFactory) -> None: path1 = os.path.join(tmpdir, "test1.txt") with open(path1, "wb") as file: file.write(b"") path2 = os.path.join(tmpdir, "test2.txt") with open(path2, "wb") as file: file.write(b"") client = test_client_factory(multi_items_app) with open(path1, "rb") as f1, open(path2, "rb") as f2: response = client.post( "/", data={"test1": "abc"}, files=[("test1", f1), ("test1", ("test2.txt", f2, "text/plain"))], ) assert response.json() == { "test1": [ "abc", { "filename": "test1.txt", "size": 15, "content": "", "content_type": "text/plain", }, { "filename": "test2.txt", "size": 15, "content": "", "content_type": "text/plain", }, ] } def test_multipart_request_mixed_files_and_data(tmpdir: Path, test_client_factory: TestClientFactory) -> None: client = test_client_factory(app) response = client.post( "/", data=( # data b"--a7f7ac8d4e2e437c877bb7b8d7cc549c\r\n" # type: ignore b'Content-Disposition: form-data; name="field0"\r\n\r\n' b"value0\r\n" # file b"--a7f7ac8d4e2e437c877bb7b8d7cc549c\r\n" b'Content-Disposition: form-data; name="file"; filename="file.txt"\r\n' b"Content-Type: text/plain\r\n\r\n" b"\r\n" # data b"--a7f7ac8d4e2e437c877bb7b8d7cc549c\r\n" b'Content-Disposition: form-data; name="field1"\r\n\r\n' b"value1\r\n" b"--a7f7ac8d4e2e437c877bb7b8d7cc549c--\r\n" ), headers={"Content-Type": ("multipart/form-data; boundary=a7f7ac8d4e2e437c877bb7b8d7cc549c")}, ) assert response.json() == { "file": { "filename": "file.txt", "size": 14, "content": "", "content_type": "text/plain", }, "field0": "value0", "field1": "value1", } class ThreadTrackingSpooledTemporaryFile(SpooledTemporaryFile[bytes]): """Helper class to track which threads performed the rollover operation. This is not threadsafe/multi-test safe. """ rollover_threads: ClassVar[set[int | None]] = set() def rollover(self) -> None: ThreadTrackingSpooledTemporaryFile.rollover_threads.add(threading.current_thread().ident) super().rollover() @pytest.fixture def mock_spooled_temporary_file() -> Generator[None]: try: with mock.patch("starlette.formparsers.SpooledTemporaryFile", ThreadTrackingSpooledTemporaryFile): yield finally: ThreadTrackingSpooledTemporaryFile.rollover_threads.clear() def test_multipart_request_large_file_rollover_in_background_thread( mock_spooled_temporary_file: None, test_client_factory: TestClientFactory ) -> None: """Test that Spooled file rollovers happen in background threads.""" data = BytesIO(b" " * (MultiPartParser.spool_max_size + 1)) client = test_client_factory(app_monitor_thread) response = client.post("/", files=[("test_large", data)]) assert response.status_code == 200 # Parse the event thread id from the API response and ensure we have one app_thread_ident = response.json().get("thread_ident") assert app_thread_ident is not None # Ensure the app thread was not the same as the rollover one and that a rollover thread exists assert app_thread_ident not in ThreadTrackingSpooledTemporaryFile.rollover_threads assert len(ThreadTrackingSpooledTemporaryFile.rollover_threads) == 1 def test_multipart_request_with_charset_for_filename(tmpdir: Path, test_client_factory: TestClientFactory) -> None: client = test_client_factory(app) response = client.post( "/", data=( # file b"--a7f7ac8d4e2e437c877bb7b8d7cc549c\r\n" # type: ignore b'Content-Disposition: form-data; name="file"; filename="\xe6\x96\x87\xe6\x9b\xb8.txt"\r\n' b"Content-Type: text/plain\r\n\r\n" b"\r\n" b"--a7f7ac8d4e2e437c877bb7b8d7cc549c--\r\n" ), headers={"Content-Type": ("multipart/form-data; charset=utf-8; boundary=a7f7ac8d4e2e437c877bb7b8d7cc549c")}, ) assert response.json() == { "file": { "filename": "文書.txt", "size": 14, "content": "", "content_type": "text/plain", } } def test_multipart_request_without_charset_for_filename(tmpdir: Path, test_client_factory: TestClientFactory) -> None: client = test_client_factory(app) response = client.post( "/", data=( # file b"--a7f7ac8d4e2e437c877bb7b8d7cc549c\r\n" # type: ignore b'Content-Disposition: form-data; name="file"; filename="\xe7\x94\xbb\xe5\x83\x8f.jpg"\r\n' b"Content-Type: image/jpeg\r\n\r\n" b"\r\n" b"--a7f7ac8d4e2e437c877bb7b8d7cc549c--\r\n" ), headers={"Content-Type": ("multipart/form-data; boundary=a7f7ac8d4e2e437c877bb7b8d7cc549c")}, ) assert response.json() == { "file": { "filename": "画像.jpg", "size": 14, "content": "", "content_type": "image/jpeg", } } def test_multipart_request_with_encoded_value(tmpdir: Path, test_client_factory: TestClientFactory) -> None: client = test_client_factory(app) response = client.post( "/", data=( b"--20b303e711c4ab8c443184ac833ab00f\r\n" # type: ignore b"Content-Disposition: form-data; " b'name="value"\r\n\r\n' b"Transf\xc3\xa9rer\r\n" b"--20b303e711c4ab8c443184ac833ab00f--\r\n" ), headers={"Content-Type": ("multipart/form-data; charset=utf-8; boundary=20b303e711c4ab8c443184ac833ab00f")}, ) assert response.json() == {"value": "Transférer"} def test_urlencoded_request_data(tmpdir: Path, test_client_factory: TestClientFactory) -> None: client = test_client_factory(app) response = client.post("/", data={"some": "data"}) assert response.json() == {"some": "data"} def test_no_request_data(tmpdir: Path, test_client_factory: TestClientFactory) -> None: client = test_client_factory(app) response = client.post("/") assert response.json() == {} def test_urlencoded_percent_encoding(tmpdir: Path, test_client_factory: TestClientFactory) -> None: client = test_client_factory(app) response = client.post("/", data={"some": "da ta"}) assert response.json() == {"some": "da ta"} def test_urlencoded_percent_encoding_keys(tmpdir: Path, test_client_factory: TestClientFactory) -> None: client = test_client_factory(app) response = client.post("/", data={"so me": "data"}) assert response.json() == {"so me": "data"} def test_urlencoded_multi_field_app_reads_body(tmpdir: Path, test_client_factory: TestClientFactory) -> None: client = test_client_factory(app_read_body) response = client.post("/", data={"some": "data", "second": "key pair"}) assert response.json() == {"some": "data", "second": "key pair"} def test_multipart_multi_field_app_reads_body(tmpdir: Path, test_client_factory: TestClientFactory) -> None: client = test_client_factory(app_read_body) response = client.post("/", data={"some": "data", "second": "key pair"}, files=FORCE_MULTIPART) assert response.json() == {"some": "data", "second": "key pair"} def test_user_safe_decode_helper() -> None: result = _user_safe_decode(b"\xc4\x99\xc5\xbc\xc4\x87", "utf-8") assert result == "ężć" def test_user_safe_decode_ignores_wrong_charset() -> None: result = _user_safe_decode(b"abc", "latin-8") assert result == "abc" @pytest.mark.parametrize( "app,expectation", [ (app, pytest.raises(MultiPartException)), (Starlette(routes=[Mount("/", app=app)]), does_not_raise()), ], ) def test_missing_boundary_parameter( app: ASGIApp, expectation: AbstractContextManager[Exception], test_client_factory: TestClientFactory, ) -> None: client = test_client_factory(app) with expectation: res = client.post( "/", data=( # file b'Content-Disposition: form-data; name="file"; filename="\xe6\x96\x87\xe6\x9b\xb8.txt"\r\n' # type: ignore b"Content-Type: text/plain\r\n\r\n" b"\r\n" ), headers={"Content-Type": "multipart/form-data; charset=utf-8"}, ) assert res.status_code == 400 assert res.text == "Missing boundary in multipart." @pytest.mark.parametrize( "app,expectation", [ (app, pytest.raises(MultiPartException)), (Starlette(routes=[Mount("/", app=app)]), does_not_raise()), ], ) def test_missing_name_parameter_on_content_disposition( app: ASGIApp, expectation: AbstractContextManager[Exception], test_client_factory: TestClientFactory, ) -> None: client = test_client_factory(app) with expectation: res = client.post( "/", data=( # data b"--a7f7ac8d4e2e437c877bb7b8d7cc549c\r\n" # type: ignore b'Content-Disposition: form-data; ="field0"\r\n\r\n' b"value0\r\n" ), headers={"Content-Type": ("multipart/form-data; boundary=a7f7ac8d4e2e437c877bb7b8d7cc549c")}, ) assert res.status_code == 400 assert res.text == 'The Content-Disposition header field "name" must be provided.' @pytest.mark.parametrize( "app,expectation", [ (app, pytest.raises(MultiPartException)), (Starlette(routes=[Mount("/", app=app)]), does_not_raise()), ], ) def test_too_many_fields_raise( app: ASGIApp, expectation: AbstractContextManager[Exception], test_client_factory: TestClientFactory, ) -> None: client = test_client_factory(app) fields = [] for i in range(1001): fields.append(f'--B\r\nContent-Disposition: form-data; name="N{i}";\r\n\r\n\r\n') data = "".join(fields).encode("utf-8") with expectation: res = client.post( "/", data=data, # type: ignore headers={"Content-Type": ("multipart/form-data; boundary=B")}, ) assert res.status_code == 400 assert res.text == "Too many fields. Maximum number of fields is 1000." @pytest.mark.parametrize( "app,expectation", [ (app, pytest.raises(MultiPartException)), (Starlette(routes=[Mount("/", app=app)]), does_not_raise()), ], ) def test_too_many_files_raise( app: ASGIApp, expectation: AbstractContextManager[Exception], test_client_factory: TestClientFactory, ) -> None: client = test_client_factory(app) fields = [] for i in range(1001): fields.append(f'--B\r\nContent-Disposition: form-data; name="N{i}"; filename="F{i}";\r\n\r\n\r\n') data = "".join(fields).encode("utf-8") with expectation: res = client.post( "/", data=data, # type: ignore headers={"Content-Type": ("multipart/form-data; boundary=B")}, ) assert res.status_code == 400 assert res.text == "Too many files. Maximum number of files is 1000." @pytest.mark.parametrize( "app,expectation", [ (app, pytest.raises(MultiPartException)), (Starlette(routes=[Mount("/", app=app)]), does_not_raise()), ], ) def test_too_many_files_single_field_raise( app: ASGIApp, expectation: AbstractContextManager[Exception], test_client_factory: TestClientFactory, ) -> None: client = test_client_factory(app) fields = [] for i in range(1001): # This uses the same field name "N" for all files, equivalent to a # multifile upload form field fields.append(f'--B\r\nContent-Disposition: form-data; name="N"; filename="F{i}";\r\n\r\n\r\n') data = "".join(fields).encode("utf-8") with expectation: res = client.post( "/", data=data, # type: ignore headers={"Content-Type": ("multipart/form-data; boundary=B")}, ) assert res.status_code == 400 assert res.text == "Too many files. Maximum number of files is 1000." @pytest.mark.parametrize( "app,expectation", [ (app, pytest.raises(MultiPartException)), (Starlette(routes=[Mount("/", app=app)]), does_not_raise()), ], ) def test_too_many_files_and_fields_raise( app: ASGIApp, expectation: AbstractContextManager[Exception], test_client_factory: TestClientFactory, ) -> None: client = test_client_factory(app) fields = [] for i in range(1001): fields.append(f'--B\r\nContent-Disposition: form-data; name="F{i}"; filename="F{i}";\r\n\r\n\r\n') fields.append(f'--B\r\nContent-Disposition: form-data; name="N{i}";\r\n\r\n\r\n') data = "".join(fields).encode("utf-8") with expectation: res = client.post( "/", data=data, # type: ignore headers={"Content-Type": ("multipart/form-data; boundary=B")}, ) assert res.status_code == 400 assert res.text == "Too many files. Maximum number of files is 1000." @pytest.mark.parametrize( "app,expectation", [ (make_app_max_parts(max_fields=1), pytest.raises(MultiPartException)), ( Starlette(routes=[Mount("/", app=make_app_max_parts(max_fields=1))]), does_not_raise(), ), ], ) def test_max_fields_is_customizable_low_raises( app: ASGIApp, expectation: AbstractContextManager[Exception], test_client_factory: TestClientFactory, ) -> None: client = test_client_factory(app) fields = [] for i in range(2): fields.append(f'--B\r\nContent-Disposition: form-data; name="N{i}";\r\n\r\n\r\n') data = "".join(fields).encode("utf-8") with expectation: res = client.post( "/", data=data, # type: ignore headers={"Content-Type": ("multipart/form-data; boundary=B")}, ) assert res.status_code == 400 assert res.text == "Too many fields. Maximum number of fields is 1." @pytest.mark.parametrize( "app,expectation", [ (make_app_max_parts(max_files=1), pytest.raises(MultiPartException)), ( Starlette(routes=[Mount("/", app=make_app_max_parts(max_files=1))]), does_not_raise(), ), ], ) def test_max_files_is_customizable_low_raises( app: ASGIApp, expectation: AbstractContextManager[Exception], test_client_factory: TestClientFactory, ) -> None: client = test_client_factory(app) fields = [] for i in range(2): fields.append(f'--B\r\nContent-Disposition: form-data; name="F{i}"; filename="F{i}";\r\n\r\n\r\n') data = "".join(fields).encode("utf-8") with expectation: res = client.post( "/", data=data, # type: ignore headers={"Content-Type": ("multipart/form-data; boundary=B")}, ) assert res.status_code == 400 assert res.text == "Too many files. Maximum number of files is 1." def test_max_fields_is_customizable_high(test_client_factory: TestClientFactory) -> None: client = test_client_factory(make_app_max_parts(max_fields=2000, max_files=2000)) fields = [] for i in range(2000): fields.append(f'--B\r\nContent-Disposition: form-data; name="N{i}";\r\n\r\n\r\n') fields.append(f'--B\r\nContent-Disposition: form-data; name="F{i}"; filename="F{i}";\r\n\r\n\r\n') data = "".join(fields).encode("utf-8") data += b"--B--\r\n" res = client.post( "/", data=data, # type: ignore headers={"Content-Type": ("multipart/form-data; boundary=B")}, ) assert res.status_code == 200 res_data = res.json() assert res_data["N1999"] == "" assert res_data["F1999"] == { "filename": "F1999", "size": 0, "content": "", "content_type": None, } @pytest.mark.parametrize( "app,expectation", [ (app, pytest.raises(MultiPartException)), (Starlette(routes=[Mount("/", app=app)]), does_not_raise()), ], ) def test_max_part_size_exceeds_limit( app: ASGIApp, expectation: AbstractContextManager[Exception], test_client_factory: TestClientFactory, ) -> None: client = test_client_factory(app) boundary = "------------------------4K1ON9fZkj9uCUmqLHRbbR" multipart_data = ( f"--{boundary}\r\n" f'Content-Disposition: form-data; name="small"\r\n\r\n' "small content\r\n" f"--{boundary}\r\n" f'Content-Disposition: form-data; name="large"\r\n\r\n' + ("x" * 1024 * 1024 + "x") # 1MB + 1 byte of data + "\r\n" f"--{boundary}--\r\n" ).encode("utf-8") headers = { "Content-Type": f"multipart/form-data; boundary={boundary}", "Transfer-Encoding": "chunked", } with expectation: response = client.post("/", data=multipart_data, headers=headers) # type: ignore assert response.status_code == 400 assert response.text == "Part exceeded maximum size of 1024KB." @pytest.mark.parametrize( "app,expectation", [ (make_app_max_parts(max_part_size=1024 * 10), pytest.raises(MultiPartException)), ( Starlette(routes=[Mount("/", app=make_app_max_parts(max_part_size=1024 * 10))]), does_not_raise(), ), ], ) def test_max_part_size_exceeds_custom_limit( app: ASGIApp, expectation: AbstractContextManager[Exception], test_client_factory: TestClientFactory, ) -> None: client = test_client_factory(app) boundary = "------------------------4K1ON9fZkj9uCUmqLHRbbR" multipart_data = ( f"--{boundary}\r\n" f'Content-Disposition: form-data; name="small"\r\n\r\n' "small content\r\n" f"--{boundary}\r\n" f'Content-Disposition: form-data; name="large"\r\n\r\n' + ("x" * 1024 * 10 + "x") # 1MB + 1 byte of data + "\r\n" f"--{boundary}--\r\n" ).encode("utf-8") headers = { "Content-Type": f"multipart/form-data; boundary={boundary}", "Transfer-Encoding": "chunked", } with expectation: response = client.post("/", content=multipart_data, headers=headers) assert response.status_code == 400 assert response.text == "Part exceeded maximum size of 10KB." starlette-0.50.0/tests/test_requests.py000066400000000000000000000542401510142272400202340ustar00rootroot00000000000000from __future__ import annotations import sys from collections.abc import Iterator from typing import Any import anyio import pytest from starlette.datastructures import URL, Address, State from starlette.requests import ClientDisconnect, Request from starlette.responses import JSONResponse, PlainTextResponse, Response from starlette.types import Message, Receive, Scope, Send from tests.types import TestClientFactory def test_request_url(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) data = {"method": request.method, "url": str(request.url)} response = JSONResponse(data) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/123?a=abc") assert response.json() == {"method": "GET", "url": "http://testserver/123?a=abc"} response = client.get("https://example.org:123/") assert response.json() == {"method": "GET", "url": "https://example.org:123/"} def test_request_query_params(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) params = dict(request.query_params) response = JSONResponse({"params": params}) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/?a=123&b=456") assert response.json() == {"params": {"a": "123", "b": "456"}} @pytest.mark.skipif( any(module in sys.modules for module in ("brotli", "brotlicffi")), reason='urllib3 includes "br" to the "accept-encoding" headers.', ) def test_request_headers(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) headers = dict(request.headers) response = JSONResponse({"headers": headers}) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/", headers={"host": "example.org"}) assert response.json() == { "headers": { "host": "example.org", "user-agent": "testclient", "accept-encoding": "gzip, deflate", "accept": "*/*", "connection": "keep-alive", } } @pytest.mark.parametrize( "scope,expected_client", [ ({"client": ["client", 42]}, Address("client", 42)), ({"client": None}, None), ({}, None), ], ) def test_request_client(scope: Scope, expected_client: Address | None) -> None: scope.update({"type": "http"}) # required by Request's constructor client = Request(scope).client assert client == expected_client def test_request_body(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) body = await request.body() response = JSONResponse({"body": body.decode()}) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.json() == {"body": ""} response = client.post("/", json={"a": "123"}) assert response.json() == {"body": '{"a":"123"}'} response = client.post("/", data="abc") # type: ignore assert response.json() == {"body": "abc"} def test_request_stream(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) body = b"" async for chunk in request.stream(): body += chunk response = JSONResponse({"body": body.decode()}) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.json() == {"body": ""} response = client.post("/", json={"a": "123"}) assert response.json() == {"body": '{"a":"123"}'} response = client.post("/", data="abc") # type: ignore assert response.json() == {"body": "abc"} def test_request_form_urlencoded(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) form = await request.form() response = JSONResponse({"form": dict(form)}) await response(scope, receive, send) client = test_client_factory(app) response = client.post("/", data={"abc": "123 @"}) assert response.json() == {"form": {"abc": "123 @"}} def test_request_form_context_manager(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) async with request.form() as form: response = JSONResponse({"form": dict(form)}) await response(scope, receive, send) client = test_client_factory(app) response = client.post("/", data={"abc": "123 @"}) assert response.json() == {"form": {"abc": "123 @"}} def test_request_body_then_stream(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) body = await request.body() chunks = b"" async for chunk in request.stream(): chunks += chunk response = JSONResponse({"body": body.decode(), "stream": chunks.decode()}) await response(scope, receive, send) client = test_client_factory(app) response = client.post("/", data="abc") # type: ignore assert response.json() == {"body": "abc", "stream": "abc"} def test_request_stream_then_body(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) chunks = b"" async for chunk in request.stream(): chunks += chunk try: body = await request.body() except RuntimeError: body = b"" response = JSONResponse({"body": body.decode(), "stream": chunks.decode()}) await response(scope, receive, send) client = test_client_factory(app) response = client.post("/", data="abc") # type: ignore assert response.json() == {"body": "", "stream": "abc"} def test_request_json(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) data = await request.json() response = JSONResponse({"json": data}) await response(scope, receive, send) client = test_client_factory(app) response = client.post("/", json={"a": "123"}) assert response.json() == {"json": {"a": "123"}} def test_request_scope_interface() -> None: """ A Request can be instantiated with a scope, and presents a `Mapping` interface. """ request = Request({"type": "http", "method": "GET", "path": "/abc/"}) assert request["method"] == "GET" assert dict(request) == {"type": "http", "method": "GET", "path": "/abc/"} assert len(request) == 3 def test_request_raw_path(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) path = request.scope["path"] raw_path = request.scope["raw_path"] response = PlainTextResponse(f"{path}, {raw_path}") await response(scope, receive, send) client = test_client_factory(app) response = client.get("/he%2Fllo") assert response.text == "/he/llo, b'/he%2Fllo'" def test_request_without_setting_receive( test_client_factory: TestClientFactory, ) -> None: """ If Request is instantiated without the receive channel, then .body() is not available. """ async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope) try: data = await request.json() except RuntimeError: data = "Receive channel not available" response = JSONResponse({"json": data}) await response(scope, receive, send) client = test_client_factory(app) response = client.post("/", json={"a": "123"}) assert response.json() == {"json": "Receive channel not available"} def test_request_disconnect( anyio_backend_name: str, anyio_backend_options: dict[str, Any], ) -> None: """ If a client disconnect occurs while reading request body then ClientDisconnect should be raised. """ async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) await request.body() async def receiver() -> Message: return {"type": "http.disconnect"} scope = {"type": "http", "method": "POST", "path": "/"} with pytest.raises(ClientDisconnect): anyio.run( app, # type: ignore scope, receiver, None, backend=anyio_backend_name, backend_options=anyio_backend_options, ) def test_request_is_disconnected(test_client_factory: TestClientFactory) -> None: """ If a client disconnect occurs after reading request body then request will be set disconnected properly. """ disconnected_after_response = None async def app(scope: Scope, receive: Receive, send: Send) -> None: nonlocal disconnected_after_response request = Request(scope, receive) body = await request.body() disconnected = await request.is_disconnected() response = JSONResponse({"body": body.decode(), "disconnected": disconnected}) await response(scope, receive, send) disconnected_after_response = await request.is_disconnected() client = test_client_factory(app) response = client.post("/", content="foo") assert response.json() == {"body": "foo", "disconnected": False} assert disconnected_after_response def test_request_state_object() -> None: scope = {"state": {"old": "foo"}} s = State(scope["state"]) s.new = "value" assert s.new == "value" del s.new with pytest.raises(AttributeError): s.new def test_request_state(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) request.state.example = 123 response = JSONResponse({"state.example": request.state.example}) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/123?a=abc") assert response.json() == {"state.example": 123} def test_request_cookies(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) mycookie = request.cookies.get("mycookie") if mycookie: response = Response(mycookie, media_type="text/plain") else: response = Response("Hello, world!", media_type="text/plain") response.set_cookie("mycookie", "Hello, cookies!") await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.text == "Hello, world!" response = client.get("/") assert response.text == "Hello, cookies!" def test_cookie_lenient_parsing(test_client_factory: TestClientFactory) -> None: """ The following test is based on a cookie set by Okta, a well-known authorization service. It turns out that it's common practice to set cookies that would be invalid according to the spec. """ tough_cookie = ( "provider-oauth-nonce=validAsciiblabla; " 'okta-oauth-redirect-params={"responseType":"code","state":"somestate",' '"nonce":"somenonce","scopes":["openid","profile","email","phone"],' '"urls":{"issuer":"https://subdomain.okta.com/oauth2/authServer",' '"authorizeUrl":"https://subdomain.okta.com/oauth2/authServer/v1/authorize",' '"userinfoUrl":"https://subdomain.okta.com/oauth2/authServer/v1/userinfo"}}; ' "importantCookie=importantValue; sessionCookie=importantSessionValue" ) expected_keys = { "importantCookie", "okta-oauth-redirect-params", "provider-oauth-nonce", "sessionCookie", } async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) response = JSONResponse({"cookies": request.cookies}) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/", headers={"cookie": tough_cookie}) result = response.json() assert len(result["cookies"]) == 4 assert set(result["cookies"].keys()) == expected_keys # These test cases copied from Tornado's implementation @pytest.mark.parametrize( "set_cookie,expected", [ ("chips=ahoy; vienna=finger", {"chips": "ahoy", "vienna": "finger"}), # all semicolons are delimiters, even within quotes ( 'keebler="E=mc2; L=\\"Loves\\"; fudge=\\012;"', {"keebler": '"E=mc2', "L": '\\"Loves\\"', "fudge": "\\012", "": '"'}, ), # Illegal cookies that have an '=' char in an unquoted value. ("keebler=E=mc2", {"keebler": "E=mc2"}), # Cookies with ':' character in their name. ("key:term=value:term", {"key:term": "value:term"}), # Cookies with '[' and ']'. ("a=b; c=[; d=r; f=h", {"a": "b", "c": "[", "d": "r", "f": "h"}), # Cookies that RFC6265 allows. ("a=b; Domain=example.com", {"a": "b", "Domain": "example.com"}), # parse_cookie() keeps only the last cookie with the same name. ("a=b; h=i; a=c", {"a": "c", "h": "i"}), ], ) def test_cookies_edge_cases( set_cookie: str, expected: dict[str, str], test_client_factory: TestClientFactory, ) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) response = JSONResponse({"cookies": request.cookies}) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/", headers={"cookie": set_cookie}) result = response.json() assert result["cookies"] == expected @pytest.mark.parametrize( "set_cookie,expected", [ # Chunks without an equals sign appear as unnamed values per # https://bugzilla.mozilla.org/show_bug.cgi?id=169091 ( "abc=def; unnamed; django_language=en", {"": "unnamed", "abc": "def", "django_language": "en"}, ), # Even a double quote may be an unamed value. ('a=b; "; c=d', {"a": "b", "": '"', "c": "d"}), # Spaces in names and values, and an equals sign in values. ("a b c=d e = f; gh=i", {"a b c": "d e = f", "gh": "i"}), # More characters the spec forbids. ('a b,c<>@:/[]?{}=d " =e,f g', {"a b,c<>@:/[]?{}": 'd " =e,f g'}), # Unicode characters. The spec only allows ASCII. # ("saint=André Bessette", {"saint": "André Bessette"}), # Browsers don't send extra whitespace or semicolons in Cookie headers, # but cookie_parser() should parse whitespace the same way # document.cookie parses whitespace. (" = b ; ; = ; c = ; ", {"": "b", "c": ""}), ], ) def test_cookies_invalid( set_cookie: str, expected: dict[str, str], test_client_factory: TestClientFactory, ) -> None: """ Cookie strings that are against the RFC6265 spec but which browsers will send if set via document.cookie. """ async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) response = JSONResponse({"cookies": request.cookies}) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/", headers={"cookie": set_cookie}) result = response.json() assert result["cookies"] == expected def test_multiple_cookie_headers(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: scope["headers"] = [(b"cookie", b"a=abc"), (b"cookie", b"b=def"), (b"cookie", b"c=ghi")] request = Request(scope, receive) response = JSONResponse({"cookies": request.cookies}) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") result = response.json() assert result["cookies"] == {"a": "abc", "b": "def", "c": "ghi"} def test_chunked_encoding(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) body = await request.body() response = JSONResponse({"body": body.decode()}) await response(scope, receive, send) client = test_client_factory(app) def post_body() -> Iterator[bytes]: yield b"foo" yield b"bar" response = client.post("/", data=post_body()) # type: ignore assert response.json() == {"body": "foobar"} def test_request_send_push_promise(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: # the server is push-enabled scope["extensions"]["http.response.push"] = {} request = Request(scope, receive, send) await request.send_push_promise("/style.css") response = JSONResponse({"json": "OK"}) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.json() == {"json": "OK"} def test_request_send_push_promise_without_push_extension( test_client_factory: TestClientFactory, ) -> None: """ If server does not support the `http.response.push` extension, .send_push_promise() does nothing. """ async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope) await request.send_push_promise("/style.css") response = JSONResponse({"json": "OK"}) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.json() == {"json": "OK"} def test_request_send_push_promise_without_setting_send( test_client_factory: TestClientFactory, ) -> None: """ If Request is instantiated without the send channel, then .send_push_promise() is not available. """ async def app(scope: Scope, receive: Receive, send: Send) -> None: # the server is push-enabled scope["extensions"]["http.response.push"] = {} data = "OK" request = Request(scope) try: await request.send_push_promise("/style.css") except RuntimeError: data = "Send channel not available" response = JSONResponse({"json": data}) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.json() == {"json": "Send channel not available"} @pytest.mark.parametrize( "messages", [ [{"body": b"123", "more_body": True}, {"body": b""}], [{"body": b"", "more_body": True}, {"body": b"123"}], [{"body": b"12", "more_body": True}, {"body": b"3"}], [ {"body": b"123", "more_body": True}, {"body": b"", "more_body": True}, {"body": b""}, ], ], ) @pytest.mark.anyio async def test_request_rcv(messages: list[Message]) -> None: messages = messages.copy() async def rcv() -> Message: return {"type": "http.request", **messages.pop(0)} request = Request({"type": "http"}, rcv) body = await request.body() assert body == b"123" @pytest.mark.anyio async def test_request_stream_called_twice() -> None: messages: list[Message] = [ {"type": "http.request", "body": b"1", "more_body": True}, {"type": "http.request", "body": b"2", "more_body": True}, {"type": "http.request", "body": b"3"}, ] async def rcv() -> Message: return messages.pop(0) request = Request({"type": "http"}, rcv) s1 = request.stream() s2 = request.stream() msg = await s1.__anext__() assert msg == b"1" msg = await s2.__anext__() assert msg == b"2" msg = await s1.__anext__() assert msg == b"3" # at this point we've consumed the entire body # so we should not wait for more body (which would hang us forever) msg = await s1.__anext__() assert msg == b"" msg = await s2.__anext__() assert msg == b"" # and now both streams are exhausted with pytest.raises(StopAsyncIteration): assert await s2.__anext__() with pytest.raises(StopAsyncIteration): await s1.__anext__() def test_request_url_outside_starlette_context(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) request.url_for("index") client = test_client_factory(app) with pytest.raises( RuntimeError, match="The `url_for` method can only be used inside a Starlette application or with a router.", ): client.get("/") def test_request_url_starlette_context(test_client_factory: TestClientFactory) -> None: from starlette.applications import Starlette from starlette.middleware import Middleware from starlette.routing import Route from starlette.types import ASGIApp url_for = None async def homepage(request: Request) -> Response: return PlainTextResponse("Hello, world!") class CustomMiddleware: def __init__(self, app: ASGIApp) -> None: self.app = app async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: nonlocal url_for request = Request(scope, receive) url_for = request.url_for("homepage") await self.app(scope, receive, send) app = Starlette(routes=[Route("/home", homepage)], middleware=[Middleware(CustomMiddleware)]) client = test_client_factory(app) client.get("/home") assert url_for == URL("http://testserver/home") starlette-0.50.0/tests/test_responses.py000066400000000000000000001036541510142272400204060ustar00rootroot00000000000000from __future__ import annotations import datetime as dt import sys import time from collections.abc import AsyncGenerator, AsyncIterator, Iterator from http.cookies import SimpleCookie from pathlib import Path from typing import Any import anyio import pytest from starlette import status from starlette.background import BackgroundTask from starlette.datastructures import Headers from starlette.requests import ClientDisconnect, Request from starlette.responses import FileResponse, JSONResponse, RedirectResponse, Response, StreamingResponse from starlette.testclient import TestClient from starlette.types import Message, Receive, Scope, Send from tests.types import TestClientFactory def test_text_response(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: response = Response("hello, world", media_type="text/plain") await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.text == "hello, world" def test_bytes_response(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: response = Response(b"xxxxx", media_type="image/png") await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.content == b"xxxxx" def test_json_none_response(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: response = JSONResponse(None) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.json() is None assert response.content == b"null" def test_redirect_response(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: if scope["path"] == "/": response = Response("hello, world", media_type="text/plain") else: response = RedirectResponse("/") await response(scope, receive, send) client = test_client_factory(app) response = client.get("/redirect") assert response.text == "hello, world" assert response.url == "http://testserver/" def test_quoting_redirect_response(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: if scope["path"] == "/I ♥ Starlette/": response = Response("hello, world", media_type="text/plain") else: response = RedirectResponse("/I ♥ Starlette/") await response(scope, receive, send) client = test_client_factory(app) response = client.get("/redirect") assert response.text == "hello, world" assert response.url == "http://testserver/I%20%E2%99%A5%20Starlette/" def test_redirect_response_content_length_header( test_client_factory: TestClientFactory, ) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: if scope["path"] == "/": response = Response("hello", media_type="text/plain") # pragma: no cover else: response = RedirectResponse("/") await response(scope, receive, send) client: TestClient = test_client_factory(app) response = client.request("GET", "/redirect", follow_redirects=False) assert response.url == "http://testserver/redirect" assert response.headers["content-length"] == "0" def test_streaming_response(test_client_factory: TestClientFactory) -> None: filled_by_bg_task = "" async def app(scope: Scope, receive: Receive, send: Send) -> None: async def numbers(minimum: int, maximum: int) -> AsyncIterator[str]: for i in range(minimum, maximum + 1): yield str(i) if i != maximum: yield ", " await anyio.sleep(0) async def numbers_for_cleanup(start: int = 1, stop: int = 5) -> None: nonlocal filled_by_bg_task async for thing in numbers(start, stop): filled_by_bg_task = filled_by_bg_task + thing cleanup_task = BackgroundTask(numbers_for_cleanup, start=6, stop=9) generator = numbers(1, 5) response = StreamingResponse(generator, media_type="text/plain", background=cleanup_task) await response(scope, receive, send) assert filled_by_bg_task == "" client = test_client_factory(app) response = client.get("/") assert response.text == "1, 2, 3, 4, 5" assert filled_by_bg_task == "6, 7, 8, 9" def test_streaming_response_custom_iterator( test_client_factory: TestClientFactory, ) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: class CustomAsyncIterator: def __init__(self) -> None: self._called = 0 def __aiter__(self) -> AsyncIterator[str]: return self async def __anext__(self) -> str: if self._called == 5: raise StopAsyncIteration() self._called += 1 return str(self._called) response = StreamingResponse(CustomAsyncIterator(), media_type="text/plain") await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.text == "12345" def test_streaming_response_custom_iterable( test_client_factory: TestClientFactory, ) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: class CustomAsyncIterable: async def __aiter__(self) -> AsyncIterator[str | bytes]: for i in range(5): yield str(i + 1) response = StreamingResponse(CustomAsyncIterable(), media_type="text/plain") await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.text == "12345" def test_sync_streaming_response(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: def numbers(minimum: int, maximum: int) -> Iterator[str]: for i in range(minimum, maximum + 1): yield str(i) if i != maximum: yield ", " generator = numbers(1, 5) response = StreamingResponse(generator, media_type="text/plain") await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.text == "1, 2, 3, 4, 5" def test_response_headers(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: headers = {"x-header-1": "123", "x-header-2": "456"} response = Response("hello, world", media_type="text/plain", headers=headers) response.headers["x-header-2"] = "789" await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.headers["x-header-1"] == "123" assert response.headers["x-header-2"] == "789" def test_response_phrase(test_client_factory: TestClientFactory) -> None: app = Response(status_code=204) client = test_client_factory(app) response = client.get("/") assert response.reason_phrase == "No Content" app = Response(b"", status_code=123) client = test_client_factory(app) response = client.get("/") assert response.reason_phrase == "" def test_file_response(tmp_path: Path, test_client_factory: TestClientFactory) -> None: path = tmp_path / "xyz" content = b"" * 1000 path.write_bytes(content) filled_by_bg_task = "" async def numbers(minimum: int, maximum: int) -> AsyncIterator[str]: for i in range(minimum, maximum + 1): yield str(i) if i != maximum: yield ", " await anyio.sleep(0) async def numbers_for_cleanup(start: int = 1, stop: int = 5) -> None: nonlocal filled_by_bg_task async for thing in numbers(start, stop): filled_by_bg_task = filled_by_bg_task + thing cleanup_task = BackgroundTask(numbers_for_cleanup, start=6, stop=9) async def app(scope: Scope, receive: Receive, send: Send) -> None: response = FileResponse(path=path, filename="example.png", background=cleanup_task) await response(scope, receive, send) assert filled_by_bg_task == "" client = test_client_factory(app) response = client.get("/") expected_disposition = 'attachment; filename="example.png"' assert response.status_code == status.HTTP_200_OK assert response.content == content assert response.headers["content-type"] == "image/png" assert response.headers["content-disposition"] == expected_disposition assert "content-length" in response.headers assert "last-modified" in response.headers assert "etag" in response.headers assert filled_by_bg_task == "6, 7, 8, 9" @pytest.mark.anyio async def test_file_response_on_head_method(tmp_path: Path) -> None: path = tmp_path / "xyz" content = b"" * 1000 path.write_bytes(content) app = FileResponse(path=path, filename="example.png") async def receive() -> Message: # type: ignore[empty-body] ... # pragma: no cover async def send(message: Message) -> None: if message["type"] == "http.response.start": assert message["status"] == status.HTTP_200_OK headers = Headers(raw=message["headers"]) assert headers["content-type"] == "image/png" assert "content-length" in headers assert "content-disposition" in headers assert "last-modified" in headers assert "etag" in headers elif message["type"] == "http.response.body": # pragma: no branch assert message["body"] == b"" assert message["more_body"] is False # Since the TestClient drops the response body on HEAD requests, we need to test # this directly. await app({"type": "http", "method": "head", "headers": [(b"key", b"value")]}, receive, send) def test_file_response_set_media_type(tmp_path: Path, test_client_factory: TestClientFactory) -> None: path = tmp_path / "xyz" path.write_bytes(b"") # By default, FileResponse will determine the `content-type` based on # the filename or path, unless a specific `media_type` is provided. app = FileResponse(path=path, filename="example.png", media_type="image/jpeg") client: TestClient = test_client_factory(app) response = client.get("/") assert response.headers["content-type"] == "image/jpeg" def test_file_response_with_directory_raises_error(tmp_path: Path, test_client_factory: TestClientFactory) -> None: app = FileResponse(path=tmp_path, filename="example.png") client = test_client_factory(app) with pytest.raises(RuntimeError) as exc_info: client.get("/") assert "is not a file" in str(exc_info.value) def test_file_response_with_missing_file_raises_error(tmp_path: Path, test_client_factory: TestClientFactory) -> None: path = tmp_path / "404.txt" app = FileResponse(path=path, filename="404.txt") client = test_client_factory(app) with pytest.raises(RuntimeError) as exc_info: client.get("/") assert "does not exist" in str(exc_info.value) def test_file_response_with_chinese_filename(tmp_path: Path, test_client_factory: TestClientFactory) -> None: content = b"file content" filename = "你好.txt" # probably "Hello.txt" in Chinese path = tmp_path / filename path.write_bytes(content) app = FileResponse(path=path, filename=filename) client = test_client_factory(app) response = client.get("/") expected_disposition = "attachment; filename*=utf-8''%E4%BD%A0%E5%A5%BD.txt" assert response.status_code == status.HTTP_200_OK assert response.content == content assert response.headers["content-disposition"] == expected_disposition def test_file_response_with_inline_disposition(tmp_path: Path, test_client_factory: TestClientFactory) -> None: content = b"file content" filename = "hello.txt" path = tmp_path / filename path.write_bytes(content) app = FileResponse(path=path, filename=filename, content_disposition_type="inline") client = test_client_factory(app) response = client.get("/") expected_disposition = 'inline; filename="hello.txt"' assert response.status_code == status.HTTP_200_OK assert response.content == content assert response.headers["content-disposition"] == expected_disposition def test_file_response_with_method_warns(tmp_path: Path) -> None: with pytest.warns(DeprecationWarning): FileResponse(path=tmp_path, filename="example.png", method="GET") def test_file_response_with_range_header(tmp_path: Path, test_client_factory: TestClientFactory) -> None: content = b"file content" filename = "hello.txt" path = tmp_path / filename path.write_bytes(content) etag = '"a_non_autogenerated_etag"' app = FileResponse(path=path, filename=filename, headers={"etag": etag}) client = test_client_factory(app) response = client.get("/", headers={"range": "bytes=0-4", "if-range": etag}) assert response.status_code == status.HTTP_206_PARTIAL_CONTENT assert response.content == content[:5] assert response.headers["etag"] == etag assert response.headers["content-length"] == "5" assert response.headers["content-range"] == f"bytes 0-4/{len(content)}" @pytest.mark.anyio async def test_file_response_with_pathsend(tmpdir: Path) -> None: path = tmpdir / "xyz" content = b"" * 1000 with open(path, "wb") as file: file.write(content) app = FileResponse(path=path, filename="example.png") async def receive() -> Message: # type: ignore[empty-body] ... # pragma: no cover async def send(message: Message) -> None: if message["type"] == "http.response.start": assert message["status"] == status.HTTP_200_OK headers = Headers(raw=message["headers"]) assert headers["content-type"] == "image/png" assert "content-length" in headers assert "content-disposition" in headers assert "last-modified" in headers assert "etag" in headers elif message["type"] == "http.response.pathsend": # pragma: no branch assert message["path"] == str(path) # Since the TestClient doesn't support `pathsend`, we need to test this directly. await app( {"type": "http", "method": "get", "headers": [], "extensions": {"http.response.pathsend": {}}}, receive, send, ) def test_set_cookie(test_client_factory: TestClientFactory, monkeypatch: pytest.MonkeyPatch) -> None: # Mock time used as a reference for `Expires` by stdlib `SimpleCookie`. mocked_now = dt.datetime(2037, 1, 22, 12, 0, 0, tzinfo=dt.timezone.utc) monkeypatch.setattr(time, "time", lambda: mocked_now.timestamp()) async def app(scope: Scope, receive: Receive, send: Send) -> None: response = Response("Hello, world!", media_type="text/plain") response.set_cookie( "mycookie", "myvalue", max_age=10, expires=10, path="/", domain="localhost", secure=True, httponly=True, samesite="none", partitioned=True if sys.version_info >= (3, 14) else False, ) await response(scope, receive, send) partitioned_text = "Partitioned; " if sys.version_info >= (3, 14) else "" client = test_client_factory(app) response = client.get("/") assert response.text == "Hello, world!" assert ( response.headers["set-cookie"] == "mycookie=myvalue; Domain=localhost; expires=Thu, 22 Jan 2037 12:00:10 GMT; " f"HttpOnly; Max-Age=10; {partitioned_text}Path=/; SameSite=none; Secure" ) @pytest.mark.skipif(sys.version_info >= (3, 14), reason="Only relevant for <3.14") def test_set_cookie_raises_for_invalid_python_version( test_client_factory: TestClientFactory, ) -> None: # pragma: no cover async def app(scope: Scope, receive: Receive, send: Send) -> None: response = Response("Hello, world!", media_type="text/plain") with pytest.raises(ValueError): response.set_cookie("mycookie", "myvalue", partitioned=True) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.text == "Hello, world!" assert response.headers.get("set-cookie") is None def test_set_cookie_path_none(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: response = Response("Hello, world!", media_type="text/plain") response.set_cookie("mycookie", "myvalue", path=None) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.text == "Hello, world!" assert response.headers["set-cookie"] == "mycookie=myvalue; SameSite=lax" def test_set_cookie_samesite_none(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: response = Response("Hello, world!", media_type="text/plain") response.set_cookie("mycookie", "myvalue", samesite=None) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.text == "Hello, world!" assert response.headers["set-cookie"] == "mycookie=myvalue; Path=/" @pytest.mark.parametrize( "expires", [ pytest.param(dt.datetime(2037, 1, 22, 12, 0, 10, tzinfo=dt.timezone.utc), id="datetime"), pytest.param("Thu, 22 Jan 2037 12:00:10 GMT", id="str"), pytest.param(10, id="int"), ], ) def test_expires_on_set_cookie( test_client_factory: TestClientFactory, monkeypatch: pytest.MonkeyPatch, expires: str, ) -> None: # Mock time used as a reference for `Expires` by stdlib `SimpleCookie`. mocked_now = dt.datetime(2037, 1, 22, 12, 0, 0, tzinfo=dt.timezone.utc) monkeypatch.setattr(time, "time", lambda: mocked_now.timestamp()) async def app(scope: Scope, receive: Receive, send: Send) -> None: response = Response("Hello, world!", media_type="text/plain") response.set_cookie("mycookie", "myvalue", expires=expires) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") cookie = SimpleCookie(response.headers.get("set-cookie")) assert cookie["mycookie"]["expires"] == "Thu, 22 Jan 2037 12:00:10 GMT" def test_delete_cookie(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: request = Request(scope, receive) response = Response("Hello, world!", media_type="text/plain") if request.cookies.get("mycookie"): response.delete_cookie("mycookie") else: response.set_cookie("mycookie", "myvalue") await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.cookies["mycookie"] response = client.get("/") assert not response.cookies.get("mycookie") def test_populate_headers(test_client_factory: TestClientFactory) -> None: app = Response(content="hi", headers={}, media_type="text/html") client = test_client_factory(app) response = client.get("/") assert response.text == "hi" assert response.headers["content-length"] == "2" assert response.headers["content-type"] == "text/html; charset=utf-8" def test_head_method(test_client_factory: TestClientFactory) -> None: app = Response("hello, world", media_type="text/plain") client = test_client_factory(app) response = client.head("/") assert response.text == "" def test_empty_response(test_client_factory: TestClientFactory) -> None: app = Response() client: TestClient = test_client_factory(app) response = client.get("/") assert response.content == b"" assert response.headers["content-length"] == "0" assert "content-type" not in response.headers def test_empty_204_response(test_client_factory: TestClientFactory) -> None: app = Response(status_code=204) client: TestClient = test_client_factory(app) response = client.get("/") assert "content-length" not in response.headers def test_non_empty_response(test_client_factory: TestClientFactory) -> None: app = Response(content="hi") client: TestClient = test_client_factory(app) response = client.get("/") assert response.headers["content-length"] == "2" def test_response_do_not_add_redundant_charset( test_client_factory: TestClientFactory, ) -> None: app = Response(media_type="text/plain; charset=utf-8") client = test_client_factory(app) response = client.get("/") assert response.headers["content-type"] == "text/plain; charset=utf-8" def test_file_response_known_size(tmp_path: Path, test_client_factory: TestClientFactory) -> None: path = tmp_path / "xyz" content = b"" * 1000 path.write_bytes(content) app = FileResponse(path=path, filename="example.png") client: TestClient = test_client_factory(app) response = client.get("/") assert response.headers["content-length"] == str(len(content)) def test_streaming_response_unknown_size( test_client_factory: TestClientFactory, ) -> None: app = StreamingResponse(content=iter(["hello", "world"])) client: TestClient = test_client_factory(app) response = client.get("/") assert "content-length" not in response.headers def test_streaming_response_known_size(test_client_factory: TestClientFactory) -> None: app = StreamingResponse(content=iter(["hello", "world"]), headers={"content-length": "10"}) client: TestClient = test_client_factory(app) response = client.get("/") assert response.headers["content-length"] == "10" def test_response_memoryview(test_client_factory: TestClientFactory) -> None: app = Response(content=memoryview(b"\xc0")) client: TestClient = test_client_factory(app) response = client.get("/") assert response.content == b"\xc0" def test_streaming_response_memoryview(test_client_factory: TestClientFactory) -> None: app = StreamingResponse(content=iter([memoryview(b"\xc0"), memoryview(b"\xf5")])) client: TestClient = test_client_factory(app) response = client.get("/") assert response.content == b"\xc0\xf5" @pytest.mark.anyio async def test_streaming_response_stops_if_receiving_http_disconnect() -> None: streamed = 0 disconnected = anyio.Event() async def receive_disconnect() -> Message: await disconnected.wait() return {"type": "http.disconnect"} async def send(message: Message) -> None: nonlocal streamed if message["type"] == "http.response.body": streamed += len(message.get("body", b"")) # Simulate disconnection after download has started if streamed >= 16: disconnected.set() async def stream_indefinitely() -> AsyncIterator[bytes]: while True: # Need a sleep for the event loop to switch to another task await anyio.sleep(0) yield b"chunk " response = StreamingResponse(content=stream_indefinitely()) with anyio.move_on_after(1) as cancel_scope: await response({}, receive_disconnect, send) assert not cancel_scope.cancel_called, "Content streaming should stop itself." @pytest.mark.anyio async def test_streaming_response_on_client_disconnects() -> None: chunks = bytearray() streamed = False async def receive_disconnect() -> Message: raise NotImplementedError async def send(message: Message) -> None: nonlocal streamed if message["type"] == "http.response.body": if not streamed: chunks.extend(message.get("body", b"")) streamed = True else: raise OSError async def stream_indefinitely() -> AsyncGenerator[bytes, None]: while True: await anyio.sleep(0) yield b"chunk" stream = stream_indefinitely() response = StreamingResponse(content=stream) with anyio.move_on_after(1) as cancel_scope: with pytest.raises(ClientDisconnect): await response({"asgi": {"spec_version": "2.4"}}, receive_disconnect, send) assert not cancel_scope.cancel_called, "Content streaming should stop itself." assert chunks == b"chunk" await stream.aclose() README = """\ # BáiZé Powerful and exquisite WSGI/ASGI framework/toolkit. The minimize implementation of methods required in the Web framework. No redundant implementation means that you can freely customize functions without considering the conflict with baize's own implementation. Under the ASGI/WSGI protocol, the interface of the request object and the response object is almost the same, only need to add or delete `await` in the appropriate place. In addition, it should be noted that ASGI supports WebSocket but WSGI does not. """ # noqa: E501 @pytest.fixture def readme_file(tmp_path: Path) -> Path: filepath = tmp_path / "README.txt" filepath.write_bytes(README.encode("utf8")) return filepath @pytest.fixture def file_response_client(readme_file: Path, test_client_factory: TestClientFactory) -> TestClient: return test_client_factory(app=FileResponse(str(readme_file))) def test_file_response_without_range(file_response_client: TestClient) -> None: response = file_response_client.get("/") assert response.status_code == 200 assert response.headers["content-length"] == str(len(README.encode("utf8"))) assert response.text == README def test_file_response_head(file_response_client: TestClient) -> None: response = file_response_client.head("/") assert response.status_code == 200 assert response.headers["content-length"] == str(len(README.encode("utf8"))) assert response.content == b"" def test_file_response_range(file_response_client: TestClient) -> None: response = file_response_client.get("/", headers={"Range": "bytes=0-100"}) assert response.status_code == 206 assert response.headers["content-range"] == f"bytes 0-100/{len(README.encode('utf8'))}" assert response.headers["content-length"] == "101" assert response.content == README.encode("utf8")[:101] def test_file_response_range_head(file_response_client: TestClient) -> None: response = file_response_client.head("/", headers={"Range": "bytes=0-100"}) assert response.status_code == 206 assert response.headers["content-length"] == str(101) assert response.content == b"" def test_file_response_range_multi(file_response_client: TestClient) -> None: response = file_response_client.get("/", headers={"Range": "bytes=0-100, 200-300"}) assert response.status_code == 206 assert response.headers["content-range"].startswith("multipart/byteranges; boundary=") assert response.headers["content-length"] == "439" def test_file_response_range_multi_head(file_response_client: TestClient) -> None: response = file_response_client.head("/", headers={"Range": "bytes=0-100, 200-300"}) assert response.status_code == 206 assert response.headers["content-length"] == "439" assert response.content == b"" response = file_response_client.head( "/", headers={"Range": "bytes=200-300", "if-range": response.headers["etag"][:-1]}, ) assert response.status_code == 200 response = file_response_client.head( "/", headers={"Range": "bytes=200-300", "if-range": response.headers["etag"]}, ) assert response.status_code == 206 def test_file_response_range_invalid(file_response_client: TestClient) -> None: response = file_response_client.head("/", headers={"Range": "bytes: 0-1000"}) assert response.status_code == 400 def test_file_response_range_head_max(file_response_client: TestClient) -> None: response = file_response_client.head("/", headers={"Range": f"bytes=0-{len(README.encode('utf8')) + 1}"}) assert response.status_code == 206 def test_file_response_range_416(file_response_client: TestClient) -> None: response = file_response_client.head("/", headers={"Range": f"bytes={len(README.encode('utf8')) + 1}-"}) assert response.status_code == 416 assert response.headers["Content-Range"] == f"*/{len(README.encode('utf8'))}" def test_file_response_only_support_bytes_range(file_response_client: TestClient) -> None: response = file_response_client.get("/", headers={"Range": "items=0-100"}) assert response.status_code == 400 assert response.text == "Only support bytes range" def test_file_response_range_must_be_requested(file_response_client: TestClient) -> None: response = file_response_client.get("/", headers={"Range": "bytes="}) assert response.status_code == 400 assert response.text == "Range header: range must be requested" def test_file_response_start_must_be_less_than_end(file_response_client: TestClient) -> None: response = file_response_client.get("/", headers={"Range": "bytes=100-0"}) assert response.status_code == 400 assert response.text == "Range header: start must be less than end" def test_file_response_merge_ranges(file_response_client: TestClient) -> None: response = file_response_client.get("/", headers={"Range": "bytes=0-100, 50-200"}) assert response.status_code == 206 assert response.headers["content-length"] == "201" assert response.headers["content-range"] == f"bytes 0-200/{len(README.encode('utf8'))}" def test_file_response_insert_ranges(file_response_client: TestClient) -> None: response = file_response_client.get("/", headers={"Range": "bytes=100-200, 0-50"}) assert response.status_code == 206 assert response.headers["content-range"].startswith("multipart/byteranges; boundary=") boundary = response.headers["content-range"].split("boundary=")[1] assert response.text.splitlines() == [ f"--{boundary}", "Content-Type: text/plain; charset=utf-8", "Content-Range: bytes 0-50/526", "", "# BáiZé", "", "Powerful and exquisite WSGI/ASGI framewo", f"--{boundary}", "Content-Type: text/plain; charset=utf-8", "Content-Range: bytes 100-200/526", "", "ds required in the Web framework. No redundant implementation means that you can freely customize fun", "", f"--{boundary}--", ] def test_file_response_range_without_dash(file_response_client: TestClient) -> None: response = file_response_client.get("/", headers={"Range": "bytes=100, 0-50"}) assert response.status_code == 206 assert response.headers["content-range"] == f"bytes 0-50/{len(README.encode('utf8'))}" def test_file_response_range_empty_start_and_end(file_response_client: TestClient) -> None: response = file_response_client.get("/", headers={"Range": "bytes= - , 0-50"}) assert response.status_code == 206 assert response.headers["content-range"] == f"bytes 0-50/{len(README.encode('utf8'))}" def test_file_response_range_ignore_non_numeric(file_response_client: TestClient) -> None: response = file_response_client.get("/", headers={"Range": "bytes=abc-def, 0-50"}) assert response.status_code == 206 assert response.headers["content-range"] == f"bytes 0-50/{len(README.encode('utf8'))}" def test_file_response_suffix_range(file_response_client: TestClient) -> None: # Test suffix range (last N bytes) - line 523 with empty start_str response = file_response_client.get("/", headers={"Range": "bytes=-100"}) assert response.status_code == 206 file_size = len(README.encode("utf8")) assert response.headers["content-range"] == f"bytes {file_size - 100}-{file_size - 1}/{file_size}" assert response.headers["content-length"] == "100" assert response.content == README.encode("utf8")[-100:] @pytest.mark.anyio async def test_file_response_multi_small_chunk_size(readme_file: Path) -> None: class SmallChunkSizeFileResponse(FileResponse): chunk_size = 10 app = SmallChunkSizeFileResponse(path=str(readme_file)) received_chunks: list[bytes] = [] start_message: dict[str, Any] = {} async def receive() -> Message: raise NotImplementedError("Should not be called!") async def send(message: Message) -> None: if message["type"] == "http.response.start": start_message.update(message) elif message["type"] == "http.response.body": # pragma: no branch received_chunks.append(message["body"]) await app({"type": "http", "method": "get", "headers": [(b"range", b"bytes=0-15,20-35,35-50")]}, receive, send) assert start_message["status"] == 206 headers = Headers(raw=start_message["headers"]) assert headers.get("content-type") == "text/plain; charset=utf-8" assert headers.get("accept-ranges") == "bytes" assert "content-length" in headers assert "last-modified" in headers assert "etag" in headers assert headers["content-range"].startswith("multipart/byteranges; boundary=") boundary = headers["content-range"].split("boundary=")[1] assert received_chunks == [ # Send the part headers. f"--{boundary}\nContent-Type: text/plain; charset=utf-8\nContent-Range: bytes 0-15/526\n\n".encode(), # Send the first chunk (10 bytes). b"# B\xc3\xa1iZ\xc3\xa9\n", # Send the second chunk (6 bytes). b"\nPower", # Send the new line to separate the parts. b"\n", # Send the part headers. We merge the ranges 20-35 and 35-50 into a single part. f"--{boundary}\nContent-Type: text/plain; charset=utf-8\nContent-Range: bytes 20-50/526\n\n".encode(), # Send the first chunk (10 bytes). b"and exquis", # Send the second chunk (10 bytes). b"ite WSGI/A", # Send the third chunk (10 bytes). b"SGI framew", # Send the last chunk (1 byte). b"o", b"\n", f"\n--{boundary}--\n".encode(), ] starlette-0.50.0/tests/test_routing.py000066400000000000000000001224631510142272400200530ustar00rootroot00000000000000from __future__ import annotations import contextlib import functools import json import uuid from collections.abc import AsyncGenerator, AsyncIterator, Callable, Generator from typing import TypedDict import pytest from starlette.applications import Starlette from starlette.exceptions import HTTPException from starlette.middleware import Middleware from starlette.requests import Request from starlette.responses import JSONResponse, PlainTextResponse, Response from starlette.routing import Host, Mount, NoMatchFound, Route, Router, WebSocketRoute from starlette.testclient import TestClient from starlette.types import ASGIApp, Message, Receive, Scope, Send from starlette.websockets import WebSocket, WebSocketDisconnect from tests.types import TestClientFactory def homepage(request: Request) -> Response: return Response("Hello, world", media_type="text/plain") def users(request: Request) -> Response: return Response("All users", media_type="text/plain") def user(request: Request) -> Response: content = "User " + request.path_params["username"] return Response(content, media_type="text/plain") def user_me(request: Request) -> Response: content = "User fixed me" return Response(content, media_type="text/plain") def disable_user(request: Request) -> Response: content = "User " + request.path_params["username"] + " disabled" return Response(content, media_type="text/plain") def user_no_match(request: Request) -> Response: # pragma: no cover content = "User fixed no match" return Response(content, media_type="text/plain") async def partial_endpoint(arg: str, request: Request) -> JSONResponse: return JSONResponse({"arg": arg}) async def partial_ws_endpoint(websocket: WebSocket) -> None: await websocket.accept() await websocket.send_json({"url": str(websocket.url)}) await websocket.close() class PartialRoutes: @classmethod async def async_endpoint(cls, arg: str, request: Request) -> JSONResponse: return JSONResponse({"arg": arg}) @classmethod async def async_ws_endpoint(cls, websocket: WebSocket) -> None: await websocket.accept() await websocket.send_json({"url": str(websocket.url)}) await websocket.close() def func_homepage(request: Request) -> Response: return Response("Hello, world!", media_type="text/plain") def contact(request: Request) -> Response: return Response("Hello, POST!", media_type="text/plain") def int_convertor(request: Request) -> JSONResponse: number = request.path_params["param"] return JSONResponse({"int": number}) def float_convertor(request: Request) -> JSONResponse: num = request.path_params["param"] return JSONResponse({"float": num}) def path_convertor(request: Request) -> JSONResponse: path = request.path_params["param"] return JSONResponse({"path": path}) def uuid_converter(request: Request) -> JSONResponse: uuid_param = request.path_params["param"] return JSONResponse({"uuid": str(uuid_param)}) def path_with_parentheses(request: Request) -> JSONResponse: number = request.path_params["param"] return JSONResponse({"int": number}) async def websocket_endpoint(session: WebSocket) -> None: await session.accept() await session.send_text("Hello, world!") await session.close() async def websocket_params(session: WebSocket) -> None: await session.accept() await session.send_text(f"Hello, {session.path_params['room']}!") await session.close() app = Router( [ Route("/", endpoint=homepage, methods=["GET"]), Mount( "/users", routes=[ Route("/", endpoint=users), Route("/me", endpoint=user_me), Route("/{username}", endpoint=user), Route("/{username}:disable", endpoint=disable_user, methods=["PUT"]), Route("/nomatch", endpoint=user_no_match), ], ), Mount( "/partial", routes=[ Route("/", endpoint=functools.partial(partial_endpoint, "foo")), Route( "/cls", endpoint=functools.partial(PartialRoutes.async_endpoint, "foo"), ), WebSocketRoute("/ws", endpoint=functools.partial(partial_ws_endpoint)), WebSocketRoute( "/ws/cls", endpoint=functools.partial(PartialRoutes.async_ws_endpoint), ), ], ), Mount("/static", app=Response("xxxxx", media_type="image/png")), Route("/func", endpoint=func_homepage, methods=["GET"]), Route("/func", endpoint=contact, methods=["POST"]), Route("/int/{param:int}", endpoint=int_convertor, name="int-convertor"), Route("/float/{param:float}", endpoint=float_convertor, name="float-convertor"), Route("/path/{param:path}", endpoint=path_convertor, name="path-convertor"), Route("/uuid/{param:uuid}", endpoint=uuid_converter, name="uuid-convertor"), # Route with chars that conflict with regex meta chars Route( "/path-with-parentheses({param:int})", endpoint=path_with_parentheses, name="path-with-parentheses", ), WebSocketRoute("/ws", endpoint=websocket_endpoint), WebSocketRoute("/ws/{room}", endpoint=websocket_params), ] ) @pytest.fixture def client( test_client_factory: TestClientFactory, ) -> Generator[TestClient, None, None]: with test_client_factory(app) as client: yield client @pytest.mark.filterwarnings( r"ignore" r":Trying to detect encoding from a tiny portion of \(5\) byte\(s\)\." r":UserWarning" r":charset_normalizer.api" ) def test_router(client: TestClient) -> None: response = client.get("/") assert response.status_code == 200 assert response.text == "Hello, world" response = client.post("/") assert response.status_code == 405 assert response.text == "Method Not Allowed" assert set(response.headers["allow"].split(", ")) == {"HEAD", "GET"} response = client.get("/foo") assert response.status_code == 404 assert response.text == "Not Found" response = client.get("/users") assert response.status_code == 200 assert response.text == "All users" response = client.get("/users/tomchristie") assert response.status_code == 200 assert response.text == "User tomchristie" response = client.get("/users/me") assert response.status_code == 200 assert response.text == "User fixed me" response = client.get("/users/tomchristie/") assert response.status_code == 200 assert response.url == "http://testserver/users/tomchristie" assert response.text == "User tomchristie" response = client.put("/users/tomchristie:disable") assert response.status_code == 200 assert response.url == "http://testserver/users/tomchristie:disable" assert response.text == "User tomchristie disabled" response = client.get("/users/nomatch") assert response.status_code == 200 assert response.text == "User nomatch" response = client.get("/static/123") assert response.status_code == 200 assert response.text == "xxxxx" def test_route_converters(client: TestClient) -> None: # Test integer conversion response = client.get("/int/5") assert response.status_code == 200 assert response.json() == {"int": 5} assert app.url_path_for("int-convertor", param=5) == "/int/5" # Test path with parentheses response = client.get("/path-with-parentheses(7)") assert response.status_code == 200 assert response.json() == {"int": 7} assert app.url_path_for("path-with-parentheses", param=7) == "/path-with-parentheses(7)" # Test float conversion response = client.get("/float/25.5") assert response.status_code == 200 assert response.json() == {"float": 25.5} assert app.url_path_for("float-convertor", param=25.5) == "/float/25.5" # Test path conversion response = client.get("/path/some/example") assert response.status_code == 200 assert response.json() == {"path": "some/example"} assert app.url_path_for("path-convertor", param="some/example") == "/path/some/example" # Test UUID conversion response = client.get("/uuid/ec38df32-ceda-4cfa-9b4a-1aeb94ad551a") assert response.status_code == 200 assert response.json() == {"uuid": "ec38df32-ceda-4cfa-9b4a-1aeb94ad551a"} assert ( app.url_path_for("uuid-convertor", param=uuid.UUID("ec38df32-ceda-4cfa-9b4a-1aeb94ad551a")) == "/uuid/ec38df32-ceda-4cfa-9b4a-1aeb94ad551a" ) def test_url_path_for() -> None: assert app.url_path_for("homepage") == "/" assert app.url_path_for("user", username="tomchristie") == "/users/tomchristie" assert app.url_path_for("websocket_endpoint") == "/ws" with pytest.raises(NoMatchFound, match='No route exists for name "broken" and params "".'): assert app.url_path_for("broken") with pytest.raises(NoMatchFound, match='No route exists for name "broken" and params "key, key2".'): assert app.url_path_for("broken", key="value", key2="value2") with pytest.raises(AssertionError): app.url_path_for("user", username="tom/christie") with pytest.raises(AssertionError): app.url_path_for("user", username="") def test_url_for() -> None: assert app.url_path_for("homepage").make_absolute_url(base_url="https://example.org") == "https://example.org/" assert ( app.url_path_for("homepage").make_absolute_url(base_url="https://example.org/root_path/") == "https://example.org/root_path/" ) assert ( app.url_path_for("user", username="tomchristie").make_absolute_url(base_url="https://example.org") == "https://example.org/users/tomchristie" ) assert ( app.url_path_for("user", username="tomchristie").make_absolute_url(base_url="https://example.org/root_path/") == "https://example.org/root_path/users/tomchristie" ) assert ( app.url_path_for("websocket_endpoint").make_absolute_url(base_url="https://example.org") == "wss://example.org/ws" ) def test_router_add_route(client: TestClient) -> None: response = client.get("/func") assert response.status_code == 200 assert response.text == "Hello, world!" def test_router_duplicate_path(client: TestClient) -> None: response = client.post("/func") assert response.status_code == 200 assert response.text == "Hello, POST!" def test_router_add_websocket_route(client: TestClient) -> None: with client.websocket_connect("/ws") as session: text = session.receive_text() assert text == "Hello, world!" with client.websocket_connect("/ws/test") as session: text = session.receive_text() assert text == "Hello, test!" def test_router_middleware(test_client_factory: TestClientFactory) -> None: class CustomMiddleware: def __init__(self, app: ASGIApp) -> None: self.app = app async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: response = PlainTextResponse("OK") await response(scope, receive, send) app = Router( routes=[Route("/", homepage)], middleware=[Middleware(CustomMiddleware)], ) client = test_client_factory(app) response = client.get("/") assert response.status_code == 200 assert response.text == "OK" def http_endpoint(request: Request) -> Response: url = request.url_for("http_endpoint") return Response(f"URL: {url}", media_type="text/plain") class WebSocketEndpoint: async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope=scope, receive=receive, send=send) await websocket.accept() await websocket.send_json({"URL": str(websocket.url_for("websocket_endpoint"))}) await websocket.close() mixed_protocol_app = Router( routes=[ Route("/", endpoint=http_endpoint), WebSocketRoute("/", endpoint=WebSocketEndpoint(), name="websocket_endpoint"), ] ) def test_protocol_switch(test_client_factory: TestClientFactory) -> None: client = test_client_factory(mixed_protocol_app) response = client.get("/") assert response.status_code == 200 assert response.text == "URL: http://testserver/" with client.websocket_connect("/") as session: assert session.receive_json() == {"URL": "ws://testserver/"} with pytest.raises(WebSocketDisconnect): with client.websocket_connect("/404"): pass # pragma: no cover ok = PlainTextResponse("OK") def test_mount_urls(test_client_factory: TestClientFactory) -> None: mounted = Router([Mount("/users", ok, name="users")]) client = test_client_factory(mounted) assert client.get("/users").status_code == 200 assert client.get("/users").url == "http://testserver/users/" assert client.get("/users/").status_code == 200 assert client.get("/users/a").status_code == 200 assert client.get("/usersa").status_code == 404 def test_reverse_mount_urls() -> None: mounted = Router([Mount("/users", ok, name="users")]) assert mounted.url_path_for("users", path="/a") == "/users/a" users = Router([Route("/{username}", ok, name="user")]) mounted = Router([Mount("/{subpath}/users", users, name="users")]) assert mounted.url_path_for("users:user", subpath="test", username="tom") == "/test/users/tom" assert mounted.url_path_for("users", subpath="test", path="/tom") == "/test/users/tom" mounted = Router([Mount("/users", ok, name="users")]) with pytest.raises(NoMatchFound): mounted.url_path_for("users", path="/a", foo="bar") mounted = Router([Mount("/users", ok, name="users")]) with pytest.raises(NoMatchFound): mounted.url_path_for("users") def test_mount_at_root(test_client_factory: TestClientFactory) -> None: mounted = Router([Mount("/", ok, name="users")]) client = test_client_factory(mounted) assert client.get("/").status_code == 200 def users_api(request: Request) -> JSONResponse: return JSONResponse({"users": [{"username": "tom"}]}) mixed_hosts_app = Router( routes=[ Host( "www.example.org", app=Router( [ Route("/", homepage, name="homepage"), Route("/users", users, name="users"), ] ), ), Host( "api.example.org", name="api", app=Router([Route("/users", users_api, name="users")]), ), Host( "port.example.org:3600", name="port", app=Router([Route("/", homepage, name="homepage")]), ), ] ) def test_host_routing(test_client_factory: TestClientFactory) -> None: client = test_client_factory(mixed_hosts_app, base_url="https://api.example.org/") response = client.get("/users") assert response.status_code == 200 assert response.json() == {"users": [{"username": "tom"}]} response = client.get("/") assert response.status_code == 404 client = test_client_factory(mixed_hosts_app, base_url="https://www.example.org/") response = client.get("/users") assert response.status_code == 200 assert response.text == "All users" response = client.get("/") assert response.status_code == 200 client = test_client_factory(mixed_hosts_app, base_url="https://port.example.org:3600/") response = client.get("/users") assert response.status_code == 404 response = client.get("/") assert response.status_code == 200 # Port in requested Host is irrelevant. client = test_client_factory(mixed_hosts_app, base_url="https://port.example.org/") response = client.get("/") assert response.status_code == 200 client = test_client_factory(mixed_hosts_app, base_url="https://port.example.org:5600/") response = client.get("/") assert response.status_code == 200 def test_host_reverse_urls() -> None: assert mixed_hosts_app.url_path_for("homepage").make_absolute_url("https://whatever") == "https://www.example.org/" assert ( mixed_hosts_app.url_path_for("users").make_absolute_url("https://whatever") == "https://www.example.org/users" ) assert ( mixed_hosts_app.url_path_for("api:users").make_absolute_url("https://whatever") == "https://api.example.org/users" ) assert ( mixed_hosts_app.url_path_for("port:homepage").make_absolute_url("https://whatever") == "https://port.example.org:3600/" ) with pytest.raises(NoMatchFound): mixed_hosts_app.url_path_for("api", path="whatever", foo="bar") async def subdomain_app(scope: Scope, receive: Receive, send: Send) -> None: response = JSONResponse({"subdomain": scope["path_params"]["subdomain"]}) await response(scope, receive, send) subdomain_router = Router(routes=[Host("{subdomain}.example.org", app=subdomain_app, name="subdomains")]) def test_subdomain_routing(test_client_factory: TestClientFactory) -> None: client = test_client_factory(subdomain_router, base_url="https://foo.example.org/") response = client.get("/") assert response.status_code == 200 assert response.json() == {"subdomain": "foo"} def test_subdomain_reverse_urls() -> None: assert ( subdomain_router.url_path_for("subdomains", subdomain="foo", path="/homepage").make_absolute_url( "https://whatever" ) == "https://foo.example.org/homepage" ) async def echo_urls(request: Request) -> JSONResponse: return JSONResponse( { "index": str(request.url_for("index")), "submount": str(request.url_for("mount:submount")), } ) echo_url_routes = [ Route("/", echo_urls, name="index", methods=["GET"]), Mount( "/submount", name="mount", routes=[Route("/", echo_urls, name="submount", methods=["GET"])], ), ] def test_url_for_with_root_path(test_client_factory: TestClientFactory) -> None: app = Starlette(routes=echo_url_routes) client = test_client_factory(app, base_url="https://www.example.org/", root_path="/sub_path") response = client.get("/sub_path/") assert response.json() == { "index": "https://www.example.org/sub_path/", "submount": "https://www.example.org/sub_path/submount/", } response = client.get("/sub_path/submount/") assert response.json() == { "index": "https://www.example.org/sub_path/", "submount": "https://www.example.org/sub_path/submount/", } async def stub_app(scope: Scope, receive: Receive, send: Send) -> None: pass # pragma: no cover double_mount_routes = [ Mount("/mount", name="mount", routes=[Mount("/static", stub_app, name="static")]), ] def test_url_for_with_double_mount() -> None: app = Starlette(routes=double_mount_routes) url = app.url_path_for("mount:static", path="123") assert url == "/mount/static/123" def test_url_for_with_root_path_ending_with_slash(test_client_factory: TestClientFactory) -> None: def homepage(request: Request) -> JSONResponse: return JSONResponse({"index": str(request.url_for("homepage"))}) app = Starlette(routes=[Route("/", homepage, name="homepage")]) client = test_client_factory(app, base_url="https://www.example.org/", root_path="/sub_path/") response = client.get("/sub_path/") assert response.json() == {"index": "https://www.example.org/sub_path/"} def test_standalone_route_matches( test_client_factory: TestClientFactory, ) -> None: app = Route("/", PlainTextResponse("Hello, World!")) client = test_client_factory(app) response = client.get("/") assert response.status_code == 200 assert response.text == "Hello, World!" def test_standalone_route_does_not_match( test_client_factory: Callable[..., TestClient], ) -> None: app = Route("/", PlainTextResponse("Hello, World!")) client = test_client_factory(app) response = client.get("/invalid") assert response.status_code == 404 assert response.text == "Not Found" async def ws_helloworld(websocket: WebSocket) -> None: await websocket.accept() await websocket.send_text("Hello, world!") await websocket.close() def test_standalone_ws_route_matches( test_client_factory: TestClientFactory, ) -> None: app = WebSocketRoute("/", ws_helloworld) client = test_client_factory(app) with client.websocket_connect("/") as websocket: text = websocket.receive_text() assert text == "Hello, world!" def test_standalone_ws_route_does_not_match( test_client_factory: TestClientFactory, ) -> None: app = WebSocketRoute("/", ws_helloworld) client = test_client_factory(app) with pytest.raises(WebSocketDisconnect): with client.websocket_connect("/invalid"): pass # pragma: no cover def test_lifespan_async(test_client_factory: TestClientFactory) -> None: startup_complete = False shutdown_complete = False async def hello_world(request: Request) -> PlainTextResponse: return PlainTextResponse("hello, world") async def run_startup() -> None: nonlocal startup_complete startup_complete = True async def run_shutdown() -> None: nonlocal shutdown_complete shutdown_complete = True with pytest.deprecated_call(match="The on_startup and on_shutdown parameters are deprecated"): app = Router( on_startup=[run_startup], on_shutdown=[run_shutdown], routes=[Route("/", hello_world)], ) assert not startup_complete assert not shutdown_complete with test_client_factory(app) as client: assert startup_complete assert not shutdown_complete client.get("/") assert startup_complete assert shutdown_complete def test_lifespan_with_on_events(test_client_factory: TestClientFactory) -> None: lifespan_called = False startup_called = False shutdown_called = False @contextlib.asynccontextmanager async def lifespan(app: Starlette) -> AsyncGenerator[None, None]: nonlocal lifespan_called lifespan_called = True yield # We do not expected, neither of run_startup nor run_shutdown to be called # we thus mark them as #pragma: no cover, to fulfill test coverage def run_startup() -> None: # pragma: no cover nonlocal startup_called startup_called = True def run_shutdown() -> None: # pragma: no cover nonlocal shutdown_called shutdown_called = True with pytest.deprecated_call(match="The on_startup and on_shutdown parameters are deprecated"): with pytest.warns( UserWarning, match="The `lifespan` parameter cannot be used with `on_startup` or `on_shutdown`." ): app = Router(on_startup=[run_startup], on_shutdown=[run_shutdown], lifespan=lifespan) assert not lifespan_called assert not startup_called assert not shutdown_called # Triggers the lifespan events with test_client_factory(app): ... assert lifespan_called assert not startup_called assert not shutdown_called def test_lifespan_sync(test_client_factory: TestClientFactory) -> None: startup_complete = False shutdown_complete = False def hello_world(request: Request) -> PlainTextResponse: return PlainTextResponse("hello, world") def run_startup() -> None: nonlocal startup_complete startup_complete = True def run_shutdown() -> None: nonlocal shutdown_complete shutdown_complete = True with pytest.deprecated_call(match="The on_startup and on_shutdown parameters are deprecated"): app = Router( on_startup=[run_startup], on_shutdown=[run_shutdown], routes=[Route("/", hello_world)], ) assert not startup_complete assert not shutdown_complete with test_client_factory(app) as client: assert startup_complete assert not shutdown_complete client.get("/") assert startup_complete assert shutdown_complete def test_lifespan_state_unsupported( test_client_factory: TestClientFactory, ) -> None: @contextlib.asynccontextmanager async def lifespan( app: ASGIApp, ) -> AsyncGenerator[dict[str, str], None]: yield {"foo": "bar"} app = Router( lifespan=lifespan, routes=[Mount("/", PlainTextResponse("hello, world"))], ) async def no_state_wrapper(scope: Scope, receive: Receive, send: Send) -> None: del scope["state"] await app(scope, receive, send) with pytest.raises(RuntimeError, match='The server does not support "state" in the lifespan scope'): with test_client_factory(no_state_wrapper): raise AssertionError("Should not be called") # pragma: no cover def test_lifespan_state_async_cm(test_client_factory: TestClientFactory) -> None: startup_complete = False shutdown_complete = False class State(TypedDict): count: int items: list[int] async def hello_world(request: Request) -> Response: # modifications to the state should not leak across requests assert request.state.count == 0 # modify the state, this should not leak to the lifespan or other requests request.state.count += 1 # since state.items is a mutable object this modification _will_ leak across # requests and to the lifespan request.state.items.append(1) return PlainTextResponse("hello, world") @contextlib.asynccontextmanager async def lifespan(app: Starlette) -> AsyncIterator[State]: nonlocal startup_complete, shutdown_complete startup_complete = True state = State(count=0, items=[]) yield state shutdown_complete = True # modifications made to the state from a request do not leak to the lifespan assert state["count"] == 0 # unless of course the request mutates a mutable object that is referenced # via state assert state["items"] == [1, 1] app = Router( lifespan=lifespan, routes=[Route("/", hello_world)], ) assert not startup_complete assert not shutdown_complete with test_client_factory(app) as client: assert startup_complete assert not shutdown_complete client.get("/") # Calling it a second time to ensure that the state is preserved. client.get("/") assert startup_complete assert shutdown_complete def test_raise_on_startup(test_client_factory: TestClientFactory) -> None: def run_startup() -> None: raise RuntimeError() with pytest.deprecated_call(match="The on_startup and on_shutdown parameters are deprecated"): router = Router(on_startup=[run_startup]) startup_failed = False async def app(scope: Scope, receive: Receive, send: Send) -> None: async def _send(message: Message) -> None: nonlocal startup_failed if message["type"] == "lifespan.startup.failed": # pragma: no branch startup_failed = True return await send(message) await router(scope, receive, _send) with pytest.raises(RuntimeError): with test_client_factory(app): pass # pragma: no cover assert startup_failed def test_raise_on_shutdown(test_client_factory: TestClientFactory) -> None: def run_shutdown() -> None: raise RuntimeError() with pytest.deprecated_call(match="The on_startup and on_shutdown parameters are deprecated"): app = Router(on_shutdown=[run_shutdown]) with pytest.raises(RuntimeError): with test_client_factory(app): pass # pragma: no cover def test_partial_async_endpoint(test_client_factory: TestClientFactory) -> None: test_client = test_client_factory(app) response = test_client.get("/partial") assert response.status_code == 200 assert response.json() == {"arg": "foo"} cls_method_response = test_client.get("/partial/cls") assert cls_method_response.status_code == 200 assert cls_method_response.json() == {"arg": "foo"} def test_partial_async_ws_endpoint( test_client_factory: TestClientFactory, ) -> None: test_client = test_client_factory(app) with test_client.websocket_connect("/partial/ws") as websocket: data = websocket.receive_json() assert data == {"url": "ws://testserver/partial/ws"} with test_client.websocket_connect("/partial/ws/cls") as websocket: data = websocket.receive_json() assert data == {"url": "ws://testserver/partial/ws/cls"} def test_duplicated_param_names() -> None: with pytest.raises( ValueError, match="Duplicated param name id at path /{id}/{id}", ): Route("/{id}/{id}", user) with pytest.raises( ValueError, match="Duplicated param names id, name at path /{id}/{name}/{id}/{name}", ): Route("/{id}/{name}/{id}/{name}", user) class Endpoint: async def my_method(self, request: Request) -> None: ... # pragma: no cover @classmethod async def my_classmethod(cls, request: Request) -> None: ... # pragma: no cover @staticmethod async def my_staticmethod(request: Request) -> None: ... # pragma: no cover def __call__(self, request: Request) -> None: ... # pragma: no cover @pytest.mark.parametrize( "endpoint, expected_name", [ pytest.param(func_homepage, "func_homepage", id="function"), pytest.param(Endpoint().my_method, "my_method", id="method"), pytest.param(Endpoint.my_classmethod, "my_classmethod", id="classmethod"), pytest.param( Endpoint.my_staticmethod, "my_staticmethod", id="staticmethod", ), pytest.param(Endpoint(), "Endpoint", id="object"), pytest.param(lambda request: ..., "", id="lambda"), # pragma: no branch ], ) def test_route_name(endpoint: Callable[..., Response], expected_name: str) -> None: assert Route(path="/", endpoint=endpoint).name == expected_name class AddHeadersMiddleware: def __init__(self, app: ASGIApp) -> None: self.app = app async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: scope["add_headers_middleware"] = True async def modified_send(msg: Message) -> None: if msg["type"] == "http.response.start": msg["headers"].append((b"X-Test", b"Set by middleware")) await send(msg) await self.app(scope, receive, modified_send) def assert_middleware_header_route(request: Request) -> Response: assert request.scope["add_headers_middleware"] is True return Response() route_with_middleware = Starlette( routes=[ Route( "/http", endpoint=assert_middleware_header_route, methods=["GET"], middleware=[Middleware(AddHeadersMiddleware)], ), Route("/home", homepage), ] ) mounted_routes_with_middleware = Starlette( routes=[ Mount( "/http", routes=[ Route( "/", endpoint=assert_middleware_header_route, methods=["GET"], name="route", ), ], middleware=[Middleware(AddHeadersMiddleware)], ), Route("/home", homepage), ] ) mounted_app_with_middleware = Starlette( routes=[ Mount( "/http", app=Route( "/", endpoint=assert_middleware_header_route, methods=["GET"], name="route", ), middleware=[Middleware(AddHeadersMiddleware)], ), Route("/home", homepage), ] ) @pytest.mark.parametrize( "app", [ mounted_routes_with_middleware, mounted_app_with_middleware, route_with_middleware, ], ) def test_base_route_middleware( test_client_factory: TestClientFactory, app: Starlette, ) -> None: test_client = test_client_factory(app) response = test_client.get("/home") assert response.status_code == 200 assert "X-Test" not in response.headers response = test_client.get("/http") assert response.status_code == 200 assert response.headers["X-Test"] == "Set by middleware" def test_mount_routes_with_middleware_url_path_for() -> None: """Checks that url_path_for still works with mounted routes with Middleware""" assert mounted_routes_with_middleware.url_path_for("route") == "/http/" def test_mount_asgi_app_with_middleware_url_path_for() -> None: """Mounted ASGI apps do not work with url path for, middleware does not change this """ with pytest.raises(NoMatchFound): mounted_app_with_middleware.url_path_for("route") def test_add_route_to_app_after_mount( test_client_factory: Callable[..., TestClient], ) -> None: """Checks that Mount will pick up routes added to the underlying app after it is mounted """ inner_app = Router() app = Mount("/http", app=inner_app) inner_app.add_route( "/inner", endpoint=homepage, methods=["GET"], ) client = test_client_factory(app) response = client.get("/http/inner") assert response.status_code == 200 def test_exception_on_mounted_apps( test_client_factory: TestClientFactory, ) -> None: def exc(request: Request) -> None: raise Exception("Exc") sub_app = Starlette(routes=[Route("/", exc)]) app = Starlette(routes=[Mount("/sub", app=sub_app)]) client = test_client_factory(app) with pytest.raises(Exception) as ctx: client.get("/sub/") assert str(ctx.value) == "Exc" def test_mounted_middleware_does_not_catch_exception( test_client_factory: Callable[..., TestClient], ) -> None: # https://github.com/Kludex/starlette/pull/1649#discussion_r960236107 def exc(request: Request) -> Response: raise HTTPException(status_code=403, detail="auth") class NamedMiddleware: def __init__(self, app: ASGIApp, name: str) -> None: self.app = app self.name = name async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: async def modified_send(msg: Message) -> None: if msg["type"] == "http.response.start": msg["headers"].append((f"X-{self.name}".encode(), b"true")) await send(msg) await self.app(scope, receive, modified_send) app = Starlette( routes=[ Mount( "/mount", routes=[ Route("/err", exc), Route("/home", homepage), ], middleware=[Middleware(NamedMiddleware, name="Mounted")], ), Route("/err", exc), Route("/home", homepage), ], middleware=[Middleware(NamedMiddleware, name="Outer")], ) client = test_client_factory(app) resp = client.get("/home") assert resp.status_code == 200, resp.content assert "X-Outer" in resp.headers resp = client.get("/err") assert resp.status_code == 403, resp.content assert "X-Outer" in resp.headers resp = client.get("/mount/home") assert resp.status_code == 200, resp.content assert "X-Mounted" in resp.headers resp = client.get("/mount/err") assert resp.status_code == 403, resp.content assert "X-Mounted" in resp.headers def test_websocket_route_middleware( test_client_factory: TestClientFactory, ) -> None: async def websocket_endpoint(session: WebSocket) -> None: await session.accept() await session.send_text("Hello, world!") await session.close() class WebsocketMiddleware: def __init__(self, app: ASGIApp) -> None: self.app = app async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: async def modified_send(msg: Message) -> None: if msg["type"] == "websocket.accept": msg["headers"].append((b"X-Test", b"Set by middleware")) await send(msg) await self.app(scope, receive, modified_send) app = Starlette( routes=[ WebSocketRoute( "/ws", endpoint=websocket_endpoint, middleware=[Middleware(WebsocketMiddleware)], ) ] ) client = test_client_factory(app) with client.websocket_connect("/ws") as websocket: text = websocket.receive_text() assert text == "Hello, world!" assert websocket.extra_headers == [(b"X-Test", b"Set by middleware")] def test_route_repr() -> None: route = Route("/welcome", endpoint=homepage) assert repr(route) == "Route(path='/welcome', name='homepage', methods=['GET', 'HEAD'])" def test_route_repr_without_methods() -> None: route = Route("/welcome", endpoint=Endpoint, methods=None) assert repr(route) == "Route(path='/welcome', name='Endpoint', methods=[])" def test_websocket_route_repr() -> None: route = WebSocketRoute("/ws", endpoint=websocket_endpoint) assert repr(route) == "WebSocketRoute(path='/ws', name='websocket_endpoint')" def test_mount_repr() -> None: route = Mount( "/app", routes=[ Route("/", endpoint=homepage), ], ) # test for substring because repr(Router) returns unique object ID assert repr(route).startswith("Mount(path='/app', name='', app=") def test_mount_named_repr() -> None: route = Mount( "/app", name="app", routes=[ Route("/", endpoint=homepage), ], ) # test for substring because repr(Router) returns unique object ID assert repr(route).startswith("Mount(path='/app', name='app', app=") def test_host_repr() -> None: route = Host( "example.com", app=Router( [ Route("/", endpoint=homepage), ] ), ) # test for substring because repr(Router) returns unique object ID assert repr(route).startswith("Host(host='example.com', name='', app=") def test_host_named_repr() -> None: route = Host( "example.com", name="app", app=Router( [ Route("/", endpoint=homepage), ] ), ) # test for substring because repr(Router) returns unique object ID assert repr(route).startswith("Host(host='example.com', name='app', app=") def test_decorator_deprecations() -> None: router = Router() with pytest.deprecated_call(): router.route("/")(homepage) with pytest.deprecated_call(): router.websocket_route("/ws")(websocket_endpoint) with pytest.deprecated_call(): async def startup() -> None: ... # pragma: no cover router.on_event("startup")(startup) async def echo_paths(request: Request, name: str) -> JSONResponse: return JSONResponse( { "name": name, "path": request.scope["path"], "root_path": request.scope["root_path"], } ) async def pure_asgi_echo_paths(scope: Scope, receive: Receive, send: Send, name: str) -> None: data = {"name": name, "path": scope["path"], "root_path": scope["root_path"]} content = json.dumps(data).encode("utf-8") await send( { "type": "http.response.start", "status": 200, "headers": [(b"content-type", b"application/json")], } ) await send({"type": "http.response.body", "body": content}) echo_paths_routes = [ Route( "/path", functools.partial(echo_paths, name="path"), name="path", methods=["GET"], ), Route( "/root-queue/path", functools.partial(echo_paths, name="queue_path"), name="queue_path", methods=["POST"], ), Mount("/asgipath", app=functools.partial(pure_asgi_echo_paths, name="asgipath")), Mount( "/sub", name="mount", routes=[ Route( "/path", functools.partial(echo_paths, name="subpath"), name="subpath", methods=["GET"], ), ], ), ] def test_paths_with_root_path(test_client_factory: TestClientFactory) -> None: app = Starlette(routes=echo_paths_routes) client = test_client_factory(app, base_url="https://www.example.org/", root_path="/root") response = client.get("/root/path") assert response.status_code == 200 assert response.json() == { "name": "path", "path": "/root/path", "root_path": "/root", } response = client.get("/root/asgipath/") assert response.status_code == 200 assert response.json() == { "name": "asgipath", "path": "/root/asgipath/", # Things that mount other ASGI apps, like WSGIMiddleware, would not be aware # of the prefixed path, and would have their own notion of their own paths, # so they need to be able to rely on the root_path to know the location they # are mounted on "root_path": "/root/asgipath", } response = client.get("/root/sub/path") assert response.status_code == 200 assert response.json() == { "name": "subpath", "path": "/root/sub/path", "root_path": "/root/sub", } response = client.post("/root/root-queue/path") assert response.status_code == 200 assert response.json() == { "name": "queue_path", "path": "/root/root-queue/path", "root_path": "/root", } starlette-0.50.0/tests/test_schemas.py000066400000000000000000000154251510142272400200060ustar00rootroot00000000000000from starlette.applications import Starlette from starlette.endpoints import HTTPEndpoint from starlette.requests import Request from starlette.responses import Response from starlette.routing import Host, Mount, Route, Router, WebSocketRoute from starlette.schemas import SchemaGenerator from starlette.websockets import WebSocket from tests.types import TestClientFactory schemas = SchemaGenerator({"openapi": "3.0.0", "info": {"title": "Example API", "version": "1.0"}}) def ws(session: WebSocket) -> None: """ws""" pass # pragma: no cover def get_user(request: Request) -> None: """ responses: 200: description: A user. examples: {"username": "tom"} """ pass # pragma: no cover def list_users(request: Request) -> None: """ responses: 200: description: A list of users. examples: [{"username": "tom"}, {"username": "lucy"}] """ pass # pragma: no cover def create_user(request: Request) -> None: """ responses: 200: description: A user. examples: {"username": "tom"} """ pass # pragma: no cover class OrganisationsEndpoint(HTTPEndpoint): def get(self, request: Request) -> None: """ responses: 200: description: A list of organisations. examples: [{"name": "Foo Corp."}, {"name": "Acme Ltd."}] """ pass # pragma: no cover def post(self, request: Request) -> None: """ responses: 200: description: An organisation. examples: {"name": "Foo Corp."} """ pass # pragma: no cover def regular_docstring_and_schema(request: Request) -> None: """ This a regular docstring example (not included in schema) --- responses: 200: description: This is included in the schema. """ pass # pragma: no cover def regular_docstring(request: Request) -> None: """ This a regular docstring example (not included in schema) """ pass # pragma: no cover def no_docstring(request: Request) -> None: pass # pragma: no cover def subapp_endpoint(request: Request) -> None: """ responses: 200: description: This endpoint is part of a subapp. """ pass # pragma: no cover def schema(request: Request) -> Response: return schemas.OpenAPIResponse(request=request) subapp = Starlette( routes=[ Route("/subapp-endpoint", endpoint=subapp_endpoint), ] ) app = Starlette( routes=[ WebSocketRoute("/ws", endpoint=ws), Route("/users/{id:int}", endpoint=get_user, methods=["GET"]), Route("/users", endpoint=list_users, methods=["GET", "HEAD"]), Route("/users", endpoint=create_user, methods=["POST"]), Route("/orgs", endpoint=OrganisationsEndpoint), Route("/regular-docstring-and-schema", endpoint=regular_docstring_and_schema), Route("/regular-docstring", endpoint=regular_docstring), Route("/no-docstring", endpoint=no_docstring), Route("/schema", endpoint=schema, methods=["GET"], include_in_schema=False), Mount("/subapp", subapp), Host("sub.domain.com", app=Router(routes=[Mount("/subapp2", subapp)])), ] ) def test_schema_generation() -> None: schema = schemas.get_schema(routes=app.routes) assert schema == { "openapi": "3.0.0", "info": {"title": "Example API", "version": "1.0"}, "paths": { "/orgs": { "get": { "responses": { 200: { "description": "A list of organisations.", "examples": [{"name": "Foo Corp."}, {"name": "Acme Ltd."}], } } }, "post": { "responses": { 200: { "description": "An organisation.", "examples": {"name": "Foo Corp."}, } } }, }, "/regular-docstring-and-schema": { "get": {"responses": {200: {"description": "This is included in the schema."}}} }, "/subapp/subapp-endpoint": { "get": {"responses": {200: {"description": "This endpoint is part of a subapp."}}} }, "/subapp2/subapp-endpoint": { "get": {"responses": {200: {"description": "This endpoint is part of a subapp."}}} }, "/users": { "get": { "responses": { 200: { "description": "A list of users.", "examples": [{"username": "tom"}, {"username": "lucy"}], } } }, "post": {"responses": {200: {"description": "A user.", "examples": {"username": "tom"}}}}, }, "/users/{id}": { "get": { "responses": { 200: { "description": "A user.", "examples": {"username": "tom"}, } } }, }, }, } EXPECTED_SCHEMA = """ info: title: Example API version: '1.0' openapi: 3.0.0 paths: /orgs: get: responses: 200: description: A list of organisations. examples: - name: Foo Corp. - name: Acme Ltd. post: responses: 200: description: An organisation. examples: name: Foo Corp. /regular-docstring-and-schema: get: responses: 200: description: This is included in the schema. /subapp/subapp-endpoint: get: responses: 200: description: This endpoint is part of a subapp. /subapp2/subapp-endpoint: get: responses: 200: description: This endpoint is part of a subapp. /users: get: responses: 200: description: A list of users. examples: - username: tom - username: lucy post: responses: 200: description: A user. examples: username: tom /users/{id}: get: responses: 200: description: A user. examples: username: tom """ def test_schema_endpoint(test_client_factory: TestClientFactory) -> None: client = test_client_factory(app) response = client.get("/schema") assert response.headers["Content-Type"] == "application/vnd.oai.openapi" assert response.text.strip() == EXPECTED_SCHEMA.strip() starlette-0.50.0/tests/test_staticfiles.py000066400000000000000000000536771510142272400207100ustar00rootroot00000000000000import os import stat import tempfile import time from pathlib import Path from typing import Any import anyio import pytest from starlette.applications import Starlette from starlette.exceptions import HTTPException from starlette.middleware import Middleware from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint from starlette.requests import Request from starlette.responses import Response from starlette.routing import Mount from starlette.staticfiles import StaticFiles from tests.types import TestClientFactory def test_staticfiles(tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "example.txt") with open(path, "w") as file: file.write("") app = StaticFiles(directory=tmpdir) client = test_client_factory(app) response = client.get("/example.txt") assert response.status_code == 200 assert response.text == "" def test_staticfiles_with_pathlib(tmp_path: Path, test_client_factory: TestClientFactory) -> None: path = tmp_path / "example.txt" with open(path, "w") as file: file.write("") app = StaticFiles(directory=tmp_path) client = test_client_factory(app) response = client.get("/example.txt") assert response.status_code == 200 assert response.text == "" def test_staticfiles_head_with_middleware(tmpdir: Path, test_client_factory: TestClientFactory) -> None: """ see https://github.com/Kludex/starlette/pull/935 """ path = os.path.join(tmpdir, "example.txt") with open(path, "w") as file: file.write("x" * 100) async def does_nothing_middleware(request: Request, call_next: RequestResponseEndpoint) -> Response: response = await call_next(request) return response routes = [Mount("/static", app=StaticFiles(directory=tmpdir), name="static")] middleware = [Middleware(BaseHTTPMiddleware, dispatch=does_nothing_middleware)] app = Starlette(routes=routes, middleware=middleware) client = test_client_factory(app) response = client.head("/static/example.txt") assert response.status_code == 200 assert response.headers.get("content-length") == "100" def test_staticfiles_with_package(test_client_factory: TestClientFactory) -> None: app = StaticFiles(packages=["tests"]) client = test_client_factory(app) response = client.get("/example.txt") assert response.status_code == 200 assert response.text == "123\n" app = StaticFiles(packages=[("tests", "statics")]) client = test_client_factory(app) response = client.get("/example.txt") assert response.status_code == 200 assert response.text == "123\n" def test_staticfiles_post(tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "example.txt") with open(path, "w") as file: file.write("") routes = [Mount("/", app=StaticFiles(directory=tmpdir), name="static")] app = Starlette(routes=routes) client = test_client_factory(app) response = client.post("/example.txt") assert response.status_code == 405 assert response.text == "Method Not Allowed" def test_staticfiles_with_directory_returns_404(tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "example.txt") with open(path, "w") as file: file.write("") routes = [Mount("/", app=StaticFiles(directory=tmpdir), name="static")] app = Starlette(routes=routes) client = test_client_factory(app) response = client.get("/") assert response.status_code == 404 assert response.text == "Not Found" def test_staticfiles_with_missing_file_returns_404(tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "example.txt") with open(path, "w") as file: file.write("") routes = [Mount("/", app=StaticFiles(directory=tmpdir), name="static")] app = Starlette(routes=routes) client = test_client_factory(app) response = client.get("/404.txt") assert response.status_code == 404 assert response.text == "Not Found" def test_staticfiles_instantiated_with_missing_directory(tmpdir: Path) -> None: with pytest.raises(RuntimeError) as exc_info: path = os.path.join(tmpdir, "no_such_directory") StaticFiles(directory=path) assert "does not exist" in str(exc_info.value) def test_staticfiles_configured_with_missing_directory(tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "no_such_directory") app = StaticFiles(directory=path, check_dir=False) client = test_client_factory(app) with pytest.raises(RuntimeError) as exc_info: client.get("/example.txt") assert "does not exist" in str(exc_info.value) def test_staticfiles_configured_with_file_instead_of_directory( tmpdir: Path, test_client_factory: TestClientFactory ) -> None: path = os.path.join(tmpdir, "example.txt") with open(path, "w") as file: file.write("") app = StaticFiles(directory=path, check_dir=False) client = test_client_factory(app) with pytest.raises(RuntimeError) as exc_info: client.get("/example.txt") assert "is not a directory" in str(exc_info.value) def test_staticfiles_config_check_occurs_only_once(tmpdir: Path, test_client_factory: TestClientFactory) -> None: app = StaticFiles(directory=tmpdir) client = test_client_factory(app) assert not app.config_checked with pytest.raises(HTTPException): client.get("/") assert app.config_checked with pytest.raises(HTTPException): client.get("/") def test_staticfiles_prevents_breaking_out_of_directory(tmpdir: Path) -> None: directory = os.path.join(tmpdir, "foo") os.mkdir(directory) path = os.path.join(tmpdir, "example.txt") with open(path, "w") as file: file.write("outside root dir") app = StaticFiles(directory=directory) # We can't test this with 'httpx', so we test the app directly here. path = app.get_path({"path": "/../example.txt"}) scope = {"method": "GET"} with pytest.raises(HTTPException) as exc_info: anyio.run(app.get_response, path, scope) assert exc_info.value.status_code == 404 assert exc_info.value.detail == "Not Found" def test_staticfiles_never_read_file_for_head_method(tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "example.txt") with open(path, "w") as file: file.write("") app = StaticFiles(directory=tmpdir) client = test_client_factory(app) response = client.head("/example.txt") assert response.status_code == 200 assert response.content == b"" assert response.headers["content-length"] == "14" def test_staticfiles_304_with_etag_match(tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "example.txt") with open(path, "w") as file: file.write("") app = StaticFiles(directory=tmpdir) client = test_client_factory(app) first_resp = client.get("/example.txt") assert first_resp.status_code == 200 last_etag = first_resp.headers["etag"] second_resp = client.get("/example.txt", headers={"if-none-match": last_etag}) assert second_resp.status_code == 304 assert second_resp.content == b"" second_resp = client.get("/example.txt", headers={"if-none-match": f'W/{last_etag}, "123"'}) assert second_resp.status_code == 304 assert second_resp.content == b"" def test_staticfiles_200_with_etag_mismatch(tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "example.txt") with open(path, "w") as file: file.write("") app = StaticFiles(directory=tmpdir) client = test_client_factory(app) first_resp = client.get("/example.txt") assert first_resp.status_code == 200 assert first_resp.headers["etag"] != '"123"' second_resp = client.get("/example.txt", headers={"if-none-match": '"123"'}) assert second_resp.status_code == 200 assert second_resp.content == b"" def test_staticfiles_200_with_etag_mismatch_and_timestamp_match( tmpdir: Path, test_client_factory: TestClientFactory ) -> None: path = tmpdir / "example.txt" path.write_text("", encoding="utf-8") app = StaticFiles(directory=tmpdir) client = test_client_factory(app) first_resp = client.get("/example.txt") assert first_resp.status_code == 200 assert first_resp.headers["etag"] != '"123"' last_modified = first_resp.headers["last-modified"] # If `if-none-match` is present, `if-modified-since` is ignored. second_resp = client.get("/example.txt", headers={"if-none-match": '"123"', "if-modified-since": last_modified}) assert second_resp.status_code == 200 assert second_resp.content == b"" def test_staticfiles_304_with_last_modified_compare_last_req( tmpdir: Path, test_client_factory: TestClientFactory ) -> None: path = os.path.join(tmpdir, "example.txt") file_last_modified_time = time.mktime(time.strptime("2013-10-10 23:40:00", "%Y-%m-%d %H:%M:%S")) with open(path, "w") as file: file.write("") os.utime(path, (file_last_modified_time, file_last_modified_time)) app = StaticFiles(directory=tmpdir) client = test_client_factory(app) # last modified less than last request, 304 response = client.get("/example.txt", headers={"If-Modified-Since": "Thu, 11 Oct 2013 15:30:19 GMT"}) assert response.status_code == 304 assert response.content == b"" # last modified greater than last request, 200 with content response = client.get("/example.txt", headers={"If-Modified-Since": "Thu, 20 Feb 2012 15:30:19 GMT"}) assert response.status_code == 200 assert response.content == b"" def test_staticfiles_html_normal(tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "404.html") with open(path, "w") as file: file.write("

    Custom not found page

    ") path = os.path.join(tmpdir, "dir") os.mkdir(path) path = os.path.join(path, "index.html") with open(path, "w") as file: file.write("

    Hello

    ") app = StaticFiles(directory=tmpdir, html=True) client = test_client_factory(app) response = client.get("/dir/") assert response.url == "http://testserver/dir/" assert response.status_code == 200 assert response.text == "

    Hello

    " response = client.get("/dir") assert response.url == "http://testserver/dir/" assert response.status_code == 200 assert response.text == "

    Hello

    " response = client.get("/dir/index.html") assert response.url == "http://testserver/dir/index.html" assert response.status_code == 200 assert response.text == "

    Hello

    " response = client.get("/missing") assert response.status_code == 404 assert response.text == "

    Custom not found page

    " def test_staticfiles_html_without_index(tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "404.html") with open(path, "w") as file: file.write("

    Custom not found page

    ") path = os.path.join(tmpdir, "dir") os.mkdir(path) app = StaticFiles(directory=tmpdir, html=True) client = test_client_factory(app) response = client.get("/dir/") assert response.url == "http://testserver/dir/" assert response.status_code == 404 assert response.text == "

    Custom not found page

    " response = client.get("/dir") assert response.url == "http://testserver/dir" assert response.status_code == 404 assert response.text == "

    Custom not found page

    " response = client.get("/missing") assert response.status_code == 404 assert response.text == "

    Custom not found page

    " def test_staticfiles_html_without_404(tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "dir") os.mkdir(path) path = os.path.join(path, "index.html") with open(path, "w") as file: file.write("

    Hello

    ") app = StaticFiles(directory=tmpdir, html=True) client = test_client_factory(app) response = client.get("/dir/") assert response.url == "http://testserver/dir/" assert response.status_code == 200 assert response.text == "

    Hello

    " response = client.get("/dir") assert response.url == "http://testserver/dir/" assert response.status_code == 200 assert response.text == "

    Hello

    " with pytest.raises(HTTPException) as exc_info: response = client.get("/missing") assert exc_info.value.status_code == 404 def test_staticfiles_html_only_files(tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "hello.html") with open(path, "w") as file: file.write("

    Hello

    ") app = StaticFiles(directory=tmpdir, html=True) client = test_client_factory(app) with pytest.raises(HTTPException) as exc_info: response = client.get("/") assert exc_info.value.status_code == 404 response = client.get("/hello.html") assert response.status_code == 200 assert response.text == "

    Hello

    " def test_staticfiles_cache_invalidation_for_deleted_file_html_mode( tmpdir: Path, test_client_factory: TestClientFactory ) -> None: path_404 = os.path.join(tmpdir, "404.html") with open(path_404, "w") as file: file.write("

    404 file

    ") path_some = os.path.join(tmpdir, "some.html") with open(path_some, "w") as file: file.write("

    some file

    ") common_modified_time = time.mktime(time.strptime("2013-10-10 23:40:00", "%Y-%m-%d %H:%M:%S")) os.utime(path_404, (common_modified_time, common_modified_time)) os.utime(path_some, (common_modified_time, common_modified_time)) app = StaticFiles(directory=tmpdir, html=True) client = test_client_factory(app) resp_exists = client.get("/some.html") assert resp_exists.status_code == 200 assert resp_exists.text == "

    some file

    " resp_cached = client.get( "/some.html", headers={"If-Modified-Since": resp_exists.headers["last-modified"]}, ) assert resp_cached.status_code == 304 os.remove(path_some) resp_deleted = client.get( "/some.html", headers={"If-Modified-Since": resp_exists.headers["last-modified"]}, ) assert resp_deleted.status_code == 404 assert resp_deleted.text == "

    404 file

    " def test_staticfiles_with_invalid_dir_permissions_returns_401( tmp_path: Path, test_client_factory: TestClientFactory ) -> None: (tmp_path / "example.txt").write_bytes(b"") original_mode = tmp_path.stat().st_mode tmp_path.chmod(stat.S_IRWXO) try: routes = [ Mount( "/", app=StaticFiles(directory=os.fsdecode(tmp_path)), name="static", ) ] app = Starlette(routes=routes) client = test_client_factory(app) response = client.get("/example.txt") assert response.status_code == 401 assert response.text == "Unauthorized" finally: tmp_path.chmod(original_mode) def test_staticfiles_with_missing_dir_returns_404(tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "example.txt") with open(path, "w") as file: file.write("") routes = [Mount("/", app=StaticFiles(directory=tmpdir), name="static")] app = Starlette(routes=routes) client = test_client_factory(app) response = client.get("/foo/example.txt") assert response.status_code == 404 assert response.text == "Not Found" def test_staticfiles_access_file_as_dir_returns_404(tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "example.txt") with open(path, "w") as file: file.write("") routes = [Mount("/", app=StaticFiles(directory=tmpdir), name="static")] app = Starlette(routes=routes) client = test_client_factory(app) response = client.get("/example.txt/foo") assert response.status_code == 404 assert response.text == "Not Found" def test_staticfiles_filename_too_long(tmpdir: Path, test_client_factory: TestClientFactory) -> None: routes = [Mount("/", app=StaticFiles(directory=tmpdir), name="static")] app = Starlette(routes=routes) client = test_client_factory(app) path_max_size = os.pathconf("/", "PC_PATH_MAX") response = client.get(f"/{'a' * path_max_size}.txt") assert response.status_code == 404 assert response.text == "Not Found" def test_staticfiles_unhandled_os_error_returns_500( tmpdir: Path, test_client_factory: TestClientFactory, monkeypatch: pytest.MonkeyPatch, ) -> None: def mock_timeout(*args: Any, **kwargs: Any) -> None: raise TimeoutError path = os.path.join(tmpdir, "example.txt") with open(path, "w") as file: file.write("") routes = [Mount("/", app=StaticFiles(directory=tmpdir), name="static")] app = Starlette(routes=routes) client = test_client_factory(app, raise_server_exceptions=False) monkeypatch.setattr("starlette.staticfiles.StaticFiles.lookup_path", mock_timeout) response = client.get("/example.txt") assert response.status_code == 500 assert response.text == "Internal Server Error" def test_staticfiles_follows_symlinks(tmpdir: Path, test_client_factory: TestClientFactory) -> None: statics_path = os.path.join(tmpdir, "statics") os.mkdir(statics_path) source_path = tempfile.mkdtemp() source_file_path = os.path.join(source_path, "page.html") with open(source_file_path, "w") as file: file.write("

    Hello

    ") statics_file_path = os.path.join(statics_path, "index.html") os.symlink(source_file_path, statics_file_path) app = StaticFiles(directory=statics_path, follow_symlink=True) client = test_client_factory(app) response = client.get("/index.html") assert response.url == "http://testserver/index.html" assert response.status_code == 200 assert response.text == "

    Hello

    " def test_staticfiles_follows_symlink_directories(tmpdir: Path, test_client_factory: TestClientFactory) -> None: statics_path = os.path.join(tmpdir, "statics") statics_html_path = os.path.join(statics_path, "html") os.mkdir(statics_path) source_path = tempfile.mkdtemp() source_file_path = os.path.join(source_path, "page.html") with open(source_file_path, "w") as file: file.write("

    Hello

    ") os.symlink(source_path, statics_html_path) app = StaticFiles(directory=statics_path, follow_symlink=True) client = test_client_factory(app) response = client.get("/html/page.html") assert response.url == "http://testserver/html/page.html" assert response.status_code == 200 assert response.text == "

    Hello

    " def test_staticfiles_disallows_path_traversal_with_symlinks(tmpdir: Path) -> None: statics_path = os.path.join(tmpdir, "statics") root_source_path = tempfile.mkdtemp() source_path = os.path.join(root_source_path, "statics") os.mkdir(source_path) source_file_path = os.path.join(root_source_path, "index.html") with open(source_file_path, "w") as file: file.write("

    Hello

    ") os.symlink(source_path, statics_path) app = StaticFiles(directory=statics_path, follow_symlink=True) # We can't test this with 'httpx', so we test the app directly here. path = app.get_path({"path": "/../index.html"}) scope = {"method": "GET"} with pytest.raises(HTTPException) as exc_info: anyio.run(app.get_response, path, scope) assert exc_info.value.status_code == 404 assert exc_info.value.detail == "Not Found" def test_staticfiles_avoids_path_traversal(tmp_path: Path) -> None: statics_path = tmp_path / "static" statics_disallow_path = tmp_path / "static_disallow" statics_path.mkdir() statics_disallow_path.mkdir() static_index_file = statics_path / "index.html" statics_disallow_path_index_file = statics_disallow_path / "index.html" static_file = tmp_path / "static1.txt" static_index_file.write_text("

    Hello

    ") statics_disallow_path_index_file.write_text("

    Private

    ") static_file.write_text("Private") app = StaticFiles(directory=statics_path) # We can't test this with 'httpx', so we test the app directly here. path = app.get_path({"path": "/../static1.txt"}) with pytest.raises(HTTPException) as exc_info: anyio.run(app.get_response, path, {"method": "GET"}) assert exc_info.value.status_code == 404 assert exc_info.value.detail == "Not Found" path = app.get_path({"path": "/../static_disallow/index.html"}) with pytest.raises(HTTPException) as exc_info: anyio.run(app.get_response, path, {"method": "GET"}) assert exc_info.value.status_code == 404 assert exc_info.value.detail == "Not Found" def test_staticfiles_self_symlinks(tmp_path: Path, test_client_factory: TestClientFactory) -> None: statics_path = tmp_path / "statics" statics_path.mkdir() source_file_path = statics_path / "index.html" source_file_path.write_text("

    Hello

    ", encoding="utf-8") statics_symlink_path = tmp_path / "statics_symlink" statics_symlink_path.symlink_to(statics_path) app = StaticFiles(directory=statics_symlink_path, follow_symlink=True) client = test_client_factory(app) response = client.get("/index.html") assert response.url == "http://testserver/index.html" assert response.status_code == 200 assert response.text == "

    Hello

    " def test_staticfiles_relative_directory_symlinks(test_client_factory: TestClientFactory) -> None: app = StaticFiles(directory="tests/statics", follow_symlink=True) client = test_client_factory(app) response = client.get("/example.txt") assert response.status_code == 200 assert response.text == "123\n" starlette-0.50.0/tests/test_status.py000066400000000000000000000017141510142272400177020ustar00rootroot00000000000000import importlib import pytest @pytest.mark.parametrize( "constant,msg", ( ( "HTTP_413_REQUEST_ENTITY_TOO_LARGE", "'HTTP_413_REQUEST_ENTITY_TOO_LARGE' is deprecated. Use 'HTTP_413_CONTENT_TOO_LARGE' instead.", ), ( "HTTP_414_REQUEST_URI_TOO_LONG", "'HTTP_414_REQUEST_URI_TOO_LONG' is deprecated. Use 'HTTP_414_URI_TOO_LONG' instead.", ), ), ) def test_deprecated_types(constant: str, msg: str) -> None: with pytest.warns(DeprecationWarning) as record: getattr(importlib.import_module("starlette.status"), constant) assert len(record) == 1 assert msg in str(record.list[0]) def test_unknown_status() -> None: with pytest.raises( AttributeError, match="module 'starlette.status' has no attribute 'HTTP_999_UNKNOWN_STATUS_CODE'", ): getattr(importlib.import_module("starlette.status"), "HTTP_999_UNKNOWN_STATUS_CODE") starlette-0.50.0/tests/test_templates.py000066400000000000000000000366761510142272400203740ustar00rootroot00000000000000from __future__ import annotations import os from pathlib import Path from unittest import mock import jinja2 import pytest from starlette.applications import Starlette from starlette.background import BackgroundTask from starlette.middleware import Middleware from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint from starlette.requests import Request from starlette.responses import Response from starlette.routing import Route from starlette.templating import Jinja2Templates from tests.types import TestClientFactory def test_templates(tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "index.html") with open(path, "w") as file: file.write("Hello, world") async def homepage(request: Request) -> Response: return templates.TemplateResponse(request, "index.html") app = Starlette(debug=True, routes=[Route("/", endpoint=homepage)]) templates = Jinja2Templates(directory=str(tmpdir)) client = test_client_factory(app) response = client.get("/") assert response.text == "Hello, world" assert response.template.name == "index.html" # type: ignore assert set(response.context.keys()) == {"request"} # type: ignore def test_calls_context_processors(tmp_path: Path, test_client_factory: TestClientFactory) -> None: path = tmp_path / "index.html" path.write_text("Hello {{ username }}") async def homepage(request: Request) -> Response: return templates.TemplateResponse(request, "index.html") def hello_world_processor(request: Request) -> dict[str, str]: return {"username": "World"} app = Starlette( debug=True, routes=[Route("/", endpoint=homepage)], ) templates = Jinja2Templates( directory=tmp_path, context_processors=[ hello_world_processor, ], ) client = test_client_factory(app) response = client.get("/") assert response.text == "Hello World" assert response.template.name == "index.html" # type: ignore assert set(response.context.keys()) == {"request", "username"} # type: ignore def test_template_with_middleware(tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "index.html") with open(path, "w") as file: file.write("Hello, world") async def homepage(request: Request) -> Response: return templates.TemplateResponse(request, "index.html") class CustomMiddleware(BaseHTTPMiddleware): async def dispatch(self, request: Request, call_next: RequestResponseEndpoint) -> Response: return await call_next(request) app = Starlette( debug=True, routes=[Route("/", endpoint=homepage)], middleware=[Middleware(CustomMiddleware)], ) templates = Jinja2Templates(directory=str(tmpdir)) client = test_client_factory(app) response = client.get("/") assert response.text == "Hello, world" assert response.template.name == "index.html" # type: ignore assert set(response.context.keys()) == {"request"} # type: ignore def test_templates_with_directories(tmp_path: Path, test_client_factory: TestClientFactory) -> None: dir_a = tmp_path.resolve() / "a" dir_a.mkdir() template_a = dir_a / "template_a.html" template_a.write_text(" a") async def page_a(request: Request) -> Response: return templates.TemplateResponse(request, "template_a.html") dir_b = tmp_path.resolve() / "b" dir_b.mkdir() template_b = dir_b / "template_b.html" template_b.write_text(" b") async def page_b(request: Request) -> Response: return templates.TemplateResponse(request, "template_b.html") app = Starlette( debug=True, routes=[Route("/a", endpoint=page_a), Route("/b", endpoint=page_b)], ) templates = Jinja2Templates(directory=[dir_a, dir_b]) client = test_client_factory(app) response = client.get("/a") assert response.text == " a" assert response.template.name == "template_a.html" # type: ignore assert set(response.context.keys()) == {"request"} # type: ignore response = client.get("/b") assert response.text == " b" assert response.template.name == "template_b.html" # type: ignore assert set(response.context.keys()) == {"request"} # type: ignore def test_templates_require_directory_or_environment() -> None: with pytest.raises(AssertionError, match="either 'directory' or 'env' arguments must be passed"): Jinja2Templates() # type: ignore[call-overload] def test_templates_require_directory_or_enviroment_not_both() -> None: with pytest.raises(AssertionError, match="either 'directory' or 'env' arguments must be passed"): Jinja2Templates(directory="dir", env=jinja2.Environment()) def test_templates_with_directory(tmpdir: Path) -> None: path = os.path.join(tmpdir, "index.html") with open(path, "w") as file: file.write("Hello") templates = Jinja2Templates(directory=str(tmpdir)) template = templates.get_template("index.html") assert template.render({}) == "Hello" def test_templates_with_environment(tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "index.html") with open(path, "w") as file: file.write("Hello, world") async def homepage(request: Request) -> Response: return templates.TemplateResponse(request, "index.html") env = jinja2.Environment(loader=jinja2.FileSystemLoader(str(tmpdir))) app = Starlette( debug=True, routes=[Route("/", endpoint=homepage)], ) templates = Jinja2Templates(env=env) client = test_client_factory(app) response = client.get("/") assert response.text == "Hello, world" assert response.template.name == "index.html" # type: ignore assert set(response.context.keys()) == {"request"} # type: ignore def test_templates_with_environment_options_emit_warning(tmpdir: Path) -> None: with pytest.warns(DeprecationWarning): Jinja2Templates(str(tmpdir), autoescape=True) def test_templates_with_kwargs_only(tmpdir: Path, test_client_factory: TestClientFactory) -> None: # MAINTAINERS: remove after 1.0 path = os.path.join(tmpdir, "index.html") with open(path, "w") as file: file.write("value: {{ a }}") templates = Jinja2Templates(directory=str(tmpdir)) spy = mock.MagicMock() def page(request: Request) -> Response: return templates.TemplateResponse( request=request, name="index.html", context={"a": "b"}, status_code=201, headers={"x-key": "value"}, media_type="text/plain", background=BackgroundTask(func=spy), ) app = Starlette(routes=[Route("/", page)]) client = test_client_factory(app) response = client.get("/") assert response.text == "value: b" # context was rendered assert response.status_code == 201 assert response.headers["x-key"] == "value" assert response.headers["content-type"] == "text/plain; charset=utf-8" spy.assert_called() def test_templates_with_kwargs_only_requires_request_in_context(tmpdir: Path) -> None: # MAINTAINERS: remove after 1.0 templates = Jinja2Templates(directory=str(tmpdir)) with pytest.warns( DeprecationWarning, match="requires the `request` argument", ): with pytest.raises(ValueError): templates.TemplateResponse(name="index.html", context={"a": "b"}) def test_templates_with_kwargs_only_warns_when_no_request_keyword( tmpdir: Path, test_client_factory: TestClientFactory ) -> None: # MAINTAINERS: remove after 1.0 path = os.path.join(tmpdir, "index.html") with open(path, "w") as file: file.write("Hello") templates = Jinja2Templates(directory=str(tmpdir)) def page(request: Request) -> Response: return templates.TemplateResponse(name="index.html", context={"request": request}) app = Starlette(routes=[Route("/", page)]) client = test_client_factory(app) with pytest.warns( DeprecationWarning, match="requires the `request` argument", ): client.get("/") def test_templates_with_requires_request_in_context(tmpdir: Path) -> None: # MAINTAINERS: remove after 1.0 templates = Jinja2Templates(directory=str(tmpdir)) with pytest.warns(DeprecationWarning): with pytest.raises(ValueError): templates.TemplateResponse("index.html", context={}) def test_templates_warns_when_first_argument_isnot_request( tmpdir: Path, test_client_factory: TestClientFactory ) -> None: # MAINTAINERS: remove after 1.0 path = os.path.join(tmpdir, "index.html") with open(path, "w") as file: file.write("value: {{ a }}") templates = Jinja2Templates(directory=str(tmpdir)) spy = mock.MagicMock() def page(request: Request) -> Response: return templates.TemplateResponse( "index.html", {"a": "b", "request": request}, status_code=201, headers={"x-key": "value"}, media_type="text/plain", background=BackgroundTask(func=spy), ) app = Starlette(routes=[Route("/", page)]) client = test_client_factory(app) with pytest.warns(DeprecationWarning): response = client.get("/") assert response.text == "value: b" # context was rendered assert response.status_code == 201 assert response.headers["x-key"] == "value" assert response.headers["content-type"] == "text/plain; charset=utf-8" spy.assert_called() class TestTemplatesArgsOnly: # MAINTAINERS: remove after 1.0 def test_name_and_context(self, tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "index.html") with open(path, "w") as file: file.write("value: {{ a }}") templates = Jinja2Templates(directory=str(tmpdir)) def page(request: Request) -> Response: return templates.TemplateResponse( "index.html", {"a": "b", "request": request}, ) app = Starlette(routes=[Route("/", page)]) client = test_client_factory(app) with pytest.warns(DeprecationWarning): response = client.get("/") assert response.text == "value: b" # context was rendered assert response.status_code == 200 def test_status_code(self, tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "index.html") with open(path, "w") as file: file.write("value: {{ a }}") templates = Jinja2Templates(directory=str(tmpdir)) def page(request: Request) -> Response: return templates.TemplateResponse( "index.html", {"a": "b", "request": request}, 201, ) app = Starlette(routes=[Route("/", page)]) client = test_client_factory(app) with pytest.warns(DeprecationWarning): response = client.get("/") assert response.text == "value: b" # context was rendered assert response.status_code == 201 def test_headers(self, tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "index.html") with open(path, "w") as file: file.write("value: {{ a }}") templates = Jinja2Templates(directory=str(tmpdir)) def page(request: Request) -> Response: return templates.TemplateResponse( "index.html", {"a": "b", "request": request}, 201, {"x-key": "value"}, ) app = Starlette(routes=[Route("/", page)]) client = test_client_factory(app) with pytest.warns(DeprecationWarning): response = client.get("/") assert response.text == "value: b" # context was rendered assert response.status_code == 201 assert response.headers["x-key"] == "value" def test_media_type(self, tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "index.html") with open(path, "w") as file: file.write("value: {{ a }}") templates = Jinja2Templates(directory=str(tmpdir)) def page(request: Request) -> Response: return templates.TemplateResponse( "index.html", {"a": "b", "request": request}, 201, {"x-key": "value"}, "text/plain", ) app = Starlette(routes=[Route("/", page)]) client = test_client_factory(app) with pytest.warns(DeprecationWarning): response = client.get("/") assert response.text == "value: b" # context was rendered assert response.status_code == 201 assert response.headers["x-key"] == "value" assert response.headers["content-type"] == "text/plain; charset=utf-8" def test_all_args(self, tmpdir: Path, test_client_factory: TestClientFactory) -> None: path = os.path.join(tmpdir, "index.html") with open(path, "w") as file: file.write("value: {{ a }}") templates = Jinja2Templates(directory=str(tmpdir)) spy = mock.MagicMock() def page(request: Request) -> Response: return templates.TemplateResponse( "index.html", {"a": "b", "request": request}, 201, {"x-key": "value"}, "text/plain", BackgroundTask(func=spy), ) app = Starlette(routes=[Route("/", page)]) client = test_client_factory(app) with pytest.warns(DeprecationWarning): response = client.get("/") assert response.text == "value: b" # context was rendered assert response.status_code == 201 assert response.headers["x-key"] == "value" assert response.headers["content-type"] == "text/plain; charset=utf-8" spy.assert_called() def test_templates_when_first_argument_is_request(tmpdir: Path, test_client_factory: TestClientFactory) -> None: # MAINTAINERS: remove after 1.0 path = os.path.join(tmpdir, "index.html") with open(path, "w") as file: file.write("value: {{ a }}") templates = Jinja2Templates(directory=str(tmpdir)) spy = mock.MagicMock() def page(request: Request) -> Response: return templates.TemplateResponse( request, "index.html", {"a": "b"}, status_code=201, headers={"x-key": "value"}, media_type="text/plain", background=BackgroundTask(func=spy), ) app = Starlette(routes=[Route("/", page)]) client = test_client_factory(app) response = client.get("/") assert response.text == "value: b" # context was rendered assert response.status_code == 201 assert response.headers["x-key"] == "value" assert response.headers["content-type"] == "text/plain; charset=utf-8" spy.assert_called() starlette-0.50.0/tests/test_testclient.py000066400000000000000000000354371510142272400205460ustar00rootroot00000000000000from __future__ import annotations import itertools import sys from asyncio import Task, current_task as asyncio_current_task from collections.abc import AsyncGenerator from contextlib import asynccontextmanager from typing import Any import anyio import anyio.lowlevel import pytest import sniffio import trio.lowlevel from starlette.applications import Starlette from starlette.middleware import Middleware from starlette.requests import Request from starlette.responses import JSONResponse, RedirectResponse, Response from starlette.routing import Route from starlette.testclient import ASGIInstance, TestClient from starlette.types import ASGIApp, Receive, Scope, Send from starlette.websockets import WebSocket, WebSocketDisconnect from tests.types import TestClientFactory def mock_service_endpoint(request: Request) -> JSONResponse: return JSONResponse({"mock": "example"}) mock_service = Starlette(routes=[Route("/", endpoint=mock_service_endpoint)]) def current_task() -> Task[Any] | trio.lowlevel.Task: # anyio's TaskInfo comparisons are invalid after their associated native # task object is GC'd https://github.com/agronholm/anyio/issues/324 asynclib_name = sniffio.current_async_library() if asynclib_name == "trio": return trio.lowlevel.current_task() if asynclib_name == "asyncio": task = asyncio_current_task() if task is None: raise RuntimeError("must be called from a running task") # pragma: no cover return task raise RuntimeError(f"unsupported asynclib={asynclib_name}") # pragma: no cover def startup() -> None: raise RuntimeError() def test_use_testclient_in_endpoint(test_client_factory: TestClientFactory) -> None: """ We should be able to use the test client within applications. This is useful if we need to mock out other services, during tests or in development. """ def homepage(request: Request) -> JSONResponse: client = test_client_factory(mock_service) response = client.get("/") return JSONResponse(response.json()) app = Starlette(routes=[Route("/", endpoint=homepage)]) client = test_client_factory(app) response = client.get("/") assert response.json() == {"mock": "example"} def test_testclient_headers_behavior() -> None: """ We should be able to use the test client with user defined headers. This is useful if we need to set custom headers for authentication during tests or in development. """ client = TestClient(mock_service) assert client.headers.get("user-agent") == "testclient" client = TestClient(mock_service, headers={"user-agent": "non-default-agent"}) assert client.headers.get("user-agent") == "non-default-agent" client = TestClient(mock_service, headers={"Authentication": "Bearer 123"}) assert client.headers.get("user-agent") == "testclient" assert client.headers.get("Authentication") == "Bearer 123" def test_use_testclient_as_contextmanager(test_client_factory: TestClientFactory, anyio_backend_name: str) -> None: """ This test asserts a number of properties that are important for an app level task_group """ counter = itertools.count() identity_runvar = anyio.lowlevel.RunVar[int]("identity_runvar") def get_identity() -> int: try: return identity_runvar.get() except LookupError: token = next(counter) identity_runvar.set(token) return token startup_task = object() startup_loop = None shutdown_task = object() shutdown_loop = None @asynccontextmanager async def lifespan_context(app: Starlette) -> AsyncGenerator[None, None]: nonlocal startup_task, startup_loop, shutdown_task, shutdown_loop startup_task = current_task() startup_loop = get_identity() async with anyio.create_task_group(): yield shutdown_task = current_task() shutdown_loop = get_identity() async def loop_id(request: Request) -> JSONResponse: return JSONResponse(get_identity()) app = Starlette( lifespan=lifespan_context, routes=[Route("/loop_id", endpoint=loop_id)], ) client = test_client_factory(app) with client: # within a TestClient context every async request runs in the same thread assert client.get("/loop_id").json() == 0 assert client.get("/loop_id").json() == 0 # that thread is also the same as the lifespan thread assert startup_loop == 0 assert shutdown_loop == 0 # lifespan events run in the same task, this is important because a task # group must be entered and exited in the same task. assert startup_task is shutdown_task # outside the TestClient context, new requests continue to spawn in new # event loops in new threads assert client.get("/loop_id").json() == 1 assert client.get("/loop_id").json() == 2 first_task = startup_task with client: # the TestClient context can be re-used, starting a new lifespan task # in a new thread assert client.get("/loop_id").json() == 3 assert client.get("/loop_id").json() == 3 assert startup_loop == 3 assert shutdown_loop == 3 # lifespan events still run in the same task, with the context but... assert startup_task is shutdown_task # ... the second TestClient context creates a new lifespan task. assert first_task is not startup_task def test_error_on_startup(test_client_factory: TestClientFactory) -> None: with pytest.deprecated_call(match="The on_startup and on_shutdown parameters are deprecated"): startup_error_app = Starlette(on_startup=[startup]) with pytest.raises(RuntimeError): with test_client_factory(startup_error_app): pass # pragma: no cover def test_exception_in_middleware(test_client_factory: TestClientFactory) -> None: class MiddlewareException(Exception): pass class BrokenMiddleware: def __init__(self, app: ASGIApp): self.app = app async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: raise MiddlewareException() broken_middleware = Starlette(middleware=[Middleware(BrokenMiddleware)]) with pytest.raises(MiddlewareException): with test_client_factory(broken_middleware): pass # pragma: no cover def test_testclient_asgi2(test_client_factory: TestClientFactory) -> None: def app(scope: Scope) -> ASGIInstance: async def inner(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!"}) return inner client = test_client_factory(app) # type: ignore response = client.get("/") assert response.text == "Hello, world!" def test_testclient_asgi3(test_client_factory: TestClientFactory) -> None: async def app(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!"}) client = test_client_factory(app) response = client.get("/") assert response.text == "Hello, world!" def test_websocket_blocking_receive(test_client_factory: TestClientFactory) -> None: def app(scope: Scope) -> ASGIInstance: async def respond(websocket: WebSocket) -> None: await websocket.send_json({"message": "test"}) async def asgi(receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() async with anyio.create_task_group() as task_group: task_group.start_soon(respond, websocket) try: # this will block as the client does not send us data # it should not prevent `respond` from executing though await websocket.receive_json() except WebSocketDisconnect: pass return asgi client = test_client_factory(app) # type: ignore with client.websocket_connect("/") as websocket: data = websocket.receive_json() assert data == {"message": "test"} def test_websocket_not_block_on_close(test_client_factory: TestClientFactory) -> None: cancelled = False def app(scope: Scope) -> ASGIInstance: async def asgi(receive: Receive, send: Send) -> None: nonlocal cancelled try: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() await anyio.sleep_forever() except anyio.get_cancelled_exc_class(): cancelled = True raise return asgi client = test_client_factory(app) # type: ignore with client.websocket_connect("/"): ... assert cancelled def test_client(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: client = scope.get("client") assert client is not None host, port = client response = JSONResponse({"host": host, "port": port}) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") assert response.json() == {"host": "testclient", "port": 50000} def test_client_custom_client(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: client = scope.get("client") assert client is not None host, port = client response = JSONResponse({"host": host, "port": port}) await response(scope, receive, send) client = test_client_factory(app, client=("192.168.0.1", 3000)) response = client.get("/") assert response.json() == {"host": "192.168.0.1", "port": 3000} @pytest.mark.parametrize("param", ("2020-07-14T00:00:00+00:00", "España", "voilà")) def test_query_params(test_client_factory: TestClientFactory, param: str) -> None: def homepage(request: Request) -> Response: return Response(request.query_params["param"]) app = Starlette(routes=[Route("/", endpoint=homepage)]) client = test_client_factory(app) response = client.get("/", params={"param": param}) assert response.text == param @pytest.mark.parametrize( "domain, ok", [ pytest.param( "testserver", True, marks=[ pytest.mark.xfail( sys.version_info < (3, 11), reason="Fails due to domain handling in http.cookiejar module (see #2152)", ), ], ), ("testserver.local", True), ("localhost", False), ("example.com", False), ], ) def test_domain_restricted_cookies(test_client_factory: TestClientFactory, domain: str, ok: bool) -> None: """ Test that test client discards domain restricted cookies which do not match the base_url of the testclient (`http://testserver` by default). The domain `testserver.local` works because the Python http.cookiejar module derives the "effective domain" by appending `.local` to non-dotted request domains in accordance with RFC 2965. """ async def app(scope: Scope, receive: Receive, send: Send) -> None: response = Response("Hello, world!", media_type="text/plain") response.set_cookie( "mycookie", "myvalue", path="/", domain=domain, ) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/") cookie_set = len(response.cookies) == 1 assert cookie_set == ok def test_forward_follow_redirects(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: if "/ok" in scope["path"]: response = Response("ok") else: response = RedirectResponse("/ok") await response(scope, receive, send) client = test_client_factory(app, follow_redirects=True) response = client.get("/") assert response.status_code == 200 def test_forward_nofollow_redirects(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: response = RedirectResponse("/ok") await response(scope, receive, send) client = test_client_factory(app, follow_redirects=False) response = client.get("/") assert response.status_code == 307 def test_with_duplicate_headers(test_client_factory: TestClientFactory) -> None: def homepage(request: Request) -> JSONResponse: return JSONResponse({"x-token": request.headers.getlist("x-token")}) app = Starlette(routes=[Route("/", endpoint=homepage)]) client = test_client_factory(app) response = client.get("/", headers=[("x-token", "foo"), ("x-token", "bar")]) assert response.json() == {"x-token": ["foo", "bar"]} def test_merge_url(test_client_factory: TestClientFactory) -> None: def homepage(request: Request) -> Response: return Response(request.url.path) app = Starlette(routes=[Route("/api/v1/bar", endpoint=homepage)]) client = test_client_factory(app, base_url="http://testserver/api/v1/") response = client.get("/bar") assert response.text == "/api/v1/bar" def test_raw_path_with_querystring(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: response = Response(scope.get("raw_path")) await response(scope, receive, send) client = test_client_factory(app) response = client.get("/hello-world", params={"foo": "bar"}) assert response.content == b"/hello-world" def test_websocket_raw_path_without_params(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() raw_path = scope.get("raw_path") assert raw_path is not None await websocket.send_bytes(raw_path) client = test_client_factory(app) with client.websocket_connect("/hello-world", params={"foo": "bar"}) as websocket: data = websocket.receive_bytes() assert data == b"/hello-world" def test_timeout_deprecation() -> None: with pytest.deprecated_call(match="You should not use the 'timeout' argument with the TestClient."): client = TestClient(mock_service) client.get("/", timeout=1) starlette-0.50.0/tests/test_websockets.py000066400000000000000000000574161510142272400205420ustar00rootroot00000000000000import sys from collections.abc import MutableMapping from typing import Any import anyio import pytest from anyio.abc import ObjectReceiveStream, ObjectSendStream from starlette import status from starlette.responses import Response from starlette.testclient import WebSocketDenialResponse from starlette.types import Message, Receive, Scope, Send from starlette.websockets import WebSocket, WebSocketDisconnect, WebSocketState from tests.types import TestClientFactory def test_websocket_url(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() await websocket.send_json({"url": str(websocket.url)}) await websocket.close() client = test_client_factory(app) with client.websocket_connect("/123?a=abc") as websocket: data = websocket.receive_json() assert data == {"url": "ws://testserver/123?a=abc"} def test_websocket_binary_json(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() message = await websocket.receive_json(mode="binary") await websocket.send_json(message, mode="binary") await websocket.close() client = test_client_factory(app) with client.websocket_connect("/123?a=abc") as websocket: websocket.send_json({"test": "data"}, mode="binary") data = websocket.receive_json(mode="binary") assert data == {"test": "data"} def test_websocket_ensure_unicode_on_send_json( test_client_factory: TestClientFactory, ) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() message = await websocket.receive_json(mode="text") await websocket.send_json(message, mode="text") await websocket.close() client = test_client_factory(app) with client.websocket_connect("/123?a=abc") as websocket: websocket.send_json({"test": "数据"}, mode="text") data = websocket.receive_text() assert data == '{"test":"数据"}' def test_websocket_query_params(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) query_params = dict(websocket.query_params) await websocket.accept() await websocket.send_json({"params": query_params}) await websocket.close() client = test_client_factory(app) with client.websocket_connect("/?a=abc&b=456") as websocket: data = websocket.receive_json() assert data == {"params": {"a": "abc", "b": "456"}} @pytest.mark.skipif( any(module in sys.modules for module in ("brotli", "brotlicffi")), reason='urllib3 includes "br" to the "accept-encoding" headers.', ) def test_websocket_headers(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) headers = dict(websocket.headers) await websocket.accept() await websocket.send_json({"headers": headers}) await websocket.close() client = test_client_factory(app) with client.websocket_connect("/") as websocket: expected_headers = { "accept": "*/*", "accept-encoding": "gzip, deflate", "connection": "upgrade", "host": "testserver", "user-agent": "testclient", "sec-websocket-key": "testserver==", "sec-websocket-version": "13", } data = websocket.receive_json() assert data == {"headers": expected_headers} def test_websocket_port(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() await websocket.send_json({"port": websocket.url.port}) await websocket.close() client = test_client_factory(app) with client.websocket_connect("ws://example.com:123/123?a=abc") as websocket: data = websocket.receive_json() assert data == {"port": 123} def test_websocket_send_and_receive_text( test_client_factory: TestClientFactory, ) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() data = await websocket.receive_text() await websocket.send_text("Message was: " + data) await websocket.close() client = test_client_factory(app) with client.websocket_connect("/") as websocket: websocket.send_text("Hello, world!") data = websocket.receive_text() assert data == "Message was: Hello, world!" def test_websocket_send_and_receive_bytes( test_client_factory: TestClientFactory, ) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() data = await websocket.receive_bytes() await websocket.send_bytes(b"Message was: " + data) await websocket.close() client = test_client_factory(app) with client.websocket_connect("/") as websocket: websocket.send_bytes(b"Hello, world!") data = websocket.receive_bytes() assert data == b"Message was: Hello, world!" def test_websocket_send_and_receive_json( test_client_factory: TestClientFactory, ) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() data = await websocket.receive_json() await websocket.send_json({"message": data}) await websocket.close() client = test_client_factory(app) with client.websocket_connect("/") as websocket: websocket.send_json({"hello": "world"}) data = websocket.receive_json() assert data == {"message": {"hello": "world"}} def test_websocket_iter_text(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() async for data in websocket.iter_text(): await websocket.send_text("Message was: " + data) client = test_client_factory(app) with client.websocket_connect("/") as websocket: websocket.send_text("Hello, world!") data = websocket.receive_text() assert data == "Message was: Hello, world!" def test_websocket_iter_bytes(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() async for data in websocket.iter_bytes(): await websocket.send_bytes(b"Message was: " + data) client = test_client_factory(app) with client.websocket_connect("/") as websocket: websocket.send_bytes(b"Hello, world!") data = websocket.receive_bytes() assert data == b"Message was: Hello, world!" def test_websocket_iter_json(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() async for data in websocket.iter_json(): await websocket.send_json({"message": data}) client = test_client_factory(app) with client.websocket_connect("/") as websocket: websocket.send_json({"hello": "world"}) data = websocket.receive_json() assert data == {"message": {"hello": "world"}} def test_websocket_concurrency_pattern(test_client_factory: TestClientFactory) -> None: stream_send: ObjectSendStream[MutableMapping[str, Any]] stream_receive: ObjectReceiveStream[MutableMapping[str, Any]] stream_send, stream_receive = anyio.create_memory_object_stream() async def reader(websocket: WebSocket) -> None: async with stream_send: async for data in websocket.iter_json(): await stream_send.send(data) async def writer(websocket: WebSocket) -> None: async with stream_receive: async for message in stream_receive: await websocket.send_json(message) async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() async with anyio.create_task_group() as task_group: task_group.start_soon(reader, websocket) await writer(websocket) await websocket.close() client = test_client_factory(app) with client.websocket_connect("/") as websocket: websocket.send_json({"hello": "world"}) data = websocket.receive_json() assert data == {"hello": "world"} def test_client_close(test_client_factory: TestClientFactory) -> None: close_code = None close_reason = None async def app(scope: Scope, receive: Receive, send: Send) -> None: nonlocal close_code, close_reason websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() try: await websocket.receive_text() except WebSocketDisconnect as exc: close_code = exc.code close_reason = exc.reason client = test_client_factory(app) with client.websocket_connect("/") as websocket: websocket.close(code=status.WS_1001_GOING_AWAY, reason="Going Away") assert close_code == status.WS_1001_GOING_AWAY assert close_reason == "Going Away" @pytest.mark.anyio async def test_client_disconnect_on_send() -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() await websocket.send_text("Hello, world!") async def receive() -> Message: return {"type": "websocket.connect"} async def send(message: Message) -> None: if message["type"] == "websocket.accept": return # Simulate the exception the server would send to the application when the client disconnects. raise OSError with pytest.raises(WebSocketDisconnect) as ctx: await app({"type": "websocket", "path": "/"}, receive, send) assert ctx.value.code == status.WS_1006_ABNORMAL_CLOSURE def test_application_close(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() await websocket.close(status.WS_1001_GOING_AWAY) client = test_client_factory(app) with client.websocket_connect("/") as websocket: with pytest.raises(WebSocketDisconnect) as exc: websocket.receive_text() assert exc.value.code == status.WS_1001_GOING_AWAY def test_rejected_connection(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) msg = await websocket.receive() assert msg == {"type": "websocket.connect"} await websocket.close(status.WS_1001_GOING_AWAY) client = test_client_factory(app) with pytest.raises(WebSocketDisconnect) as exc: with client.websocket_connect("/"): pass # pragma: no cover assert exc.value.code == status.WS_1001_GOING_AWAY def test_send_denial_response(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) msg = await websocket.receive() assert msg == {"type": "websocket.connect"} response = Response(status_code=404, content="foo") await websocket.send_denial_response(response) client = test_client_factory(app) with pytest.raises(WebSocketDenialResponse) as exc: with client.websocket_connect("/"): pass # pragma: no cover assert exc.value.status_code == 404 assert exc.value.content == b"foo" def test_send_response_multi(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) msg = await websocket.receive() assert msg == {"type": "websocket.connect"} await websocket.send( { "type": "websocket.http.response.start", "status": 404, "headers": [(b"content-type", b"text/plain"), (b"foo", b"bar")], } ) await websocket.send({"type": "websocket.http.response.body", "body": b"hard", "more_body": True}) await websocket.send({"type": "websocket.http.response.body", "body": b"body"}) client = test_client_factory(app) with pytest.raises(WebSocketDenialResponse) as exc: with client.websocket_connect("/"): pass # pragma: no cover assert exc.value.status_code == 404 assert exc.value.content == b"hardbody" assert exc.value.headers["foo"] == "bar" def test_send_response_unsupported(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: del scope["extensions"]["websocket.http.response"] websocket = WebSocket(scope, receive=receive, send=send) msg = await websocket.receive() assert msg == {"type": "websocket.connect"} response = Response(status_code=404, content="foo") with pytest.raises( RuntimeError, match="The server doesn't support the Websocket Denial Response extension.", ): await websocket.send_denial_response(response) await websocket.close() client = test_client_factory(app) with pytest.raises(WebSocketDisconnect) as exc: with client.websocket_connect("/"): pass # pragma: no cover assert exc.value.code == status.WS_1000_NORMAL_CLOSURE def test_send_response_duplicate_start(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) msg = await websocket.receive() assert msg == {"type": "websocket.connect"} response = Response(status_code=404, content="foo") await websocket.send( { "type": "websocket.http.response.start", "status": response.status_code, "headers": response.raw_headers, } ) await websocket.send( { "type": "websocket.http.response.start", "status": response.status_code, "headers": response.raw_headers, } ) client = test_client_factory(app) with pytest.raises( RuntimeError, match=("Expected ASGI message \"websocket.http.response.body\", but got 'websocket.http.response.start'"), ): with client.websocket_connect("/"): pass # pragma: no cover def test_subprotocol(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) assert websocket["subprotocols"] == ["soap", "wamp"] await websocket.accept(subprotocol="wamp") await websocket.close() client = test_client_factory(app) with client.websocket_connect("/", subprotocols=["soap", "wamp"]) as websocket: assert websocket.accepted_subprotocol == "wamp" def test_additional_headers(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept(headers=[(b"additional", b"header")]) await websocket.close() client = test_client_factory(app) with client.websocket_connect("/") as websocket: assert websocket.extra_headers == [(b"additional", b"header")] def test_no_additional_headers(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() await websocket.close() client = test_client_factory(app) with client.websocket_connect("/") as websocket: assert websocket.extra_headers == [] def test_websocket_exception(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: assert False client = test_client_factory(app) with pytest.raises(AssertionError): with client.websocket_connect("/123?a=abc"): pass # pragma: no cover def test_duplicate_close(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() await websocket.close() await websocket.close() client = test_client_factory(app) with pytest.raises(RuntimeError): with client.websocket_connect("/"): pass # pragma: no cover def test_duplicate_disconnect(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() message = await websocket.receive() assert message["type"] == "websocket.disconnect" message = await websocket.receive() client = test_client_factory(app) with pytest.raises(RuntimeError): with client.websocket_connect("/") as websocket: websocket.close() def test_websocket_scope_interface() -> None: """ A WebSocket can be instantiated with a scope, and presents a `Mapping` interface. """ async def mock_receive() -> Message: # type: ignore ... # pragma: no cover async def mock_send(message: Message) -> None: ... # pragma: no cover websocket = WebSocket({"type": "websocket", "path": "/abc/", "headers": []}, receive=mock_receive, send=mock_send) assert websocket["type"] == "websocket" assert dict(websocket) == {"type": "websocket", "path": "/abc/", "headers": []} assert len(websocket) == 3 # check __eq__ and __hash__ assert websocket != WebSocket( {"type": "websocket", "path": "/abc/", "headers": []}, receive=mock_receive, send=mock_send, ) assert websocket == websocket assert websocket in {websocket} assert {websocket} == {websocket} def test_websocket_close_reason(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() await websocket.close(code=status.WS_1001_GOING_AWAY, reason="Going Away") client = test_client_factory(app) with client.websocket_connect("/") as websocket: with pytest.raises(WebSocketDisconnect) as exc: websocket.receive_text() assert exc.value.code == status.WS_1001_GOING_AWAY assert exc.value.reason == "Going Away" def test_send_json_invalid_mode(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() await websocket.send_json({}, mode="invalid") client = test_client_factory(app) with pytest.raises(RuntimeError): with client.websocket_connect("/"): pass # pragma: no cover def test_receive_json_invalid_mode(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() await websocket.receive_json(mode="invalid") client = test_client_factory(app) with pytest.raises(RuntimeError): with client.websocket_connect("/"): pass # pragma: no cover def test_receive_text_before_accept(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.receive_text() client = test_client_factory(app) with pytest.raises(RuntimeError): with client.websocket_connect("/"): pass # pragma: no cover def test_receive_bytes_before_accept(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.receive_bytes() client = test_client_factory(app) with pytest.raises(RuntimeError): with client.websocket_connect("/"): pass # pragma: no cover def test_receive_json_before_accept(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.receive_json() client = test_client_factory(app) with pytest.raises(RuntimeError): with client.websocket_connect("/"): pass # pragma: no cover def test_send_before_accept(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.send({"type": "websocket.send"}) client = test_client_factory(app) with pytest.raises(RuntimeError): with client.websocket_connect("/"): pass # pragma: no cover def test_send_wrong_message_type(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.send({"type": "websocket.accept"}) await websocket.send({"type": "websocket.accept"}) client = test_client_factory(app) with pytest.raises(RuntimeError): with client.websocket_connect("/"): pass # pragma: no cover def test_receive_before_accept(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() websocket.client_state = WebSocketState.CONNECTING await websocket.receive() client = test_client_factory(app) with pytest.raises(RuntimeError): with client.websocket_connect("/") as websocket: websocket.send({"type": "websocket.send"}) def test_receive_wrong_message_type(test_client_factory: TestClientFactory) -> None: async def app(scope: Scope, receive: Receive, send: Send) -> None: websocket = WebSocket(scope, receive=receive, send=send) await websocket.accept() await websocket.receive() client = test_client_factory(app) with pytest.raises(RuntimeError): with client.websocket_connect("/") as websocket: websocket.send({"type": "websocket.connect"}) starlette-0.50.0/tests/types.py000066400000000000000000000014111510142272400164560ustar00rootroot00000000000000from __future__ import annotations from typing import TYPE_CHECKING, Protocol import httpx from starlette.testclient import TestClient from starlette.types import ASGIApp if TYPE_CHECKING: class TestClientFactory(Protocol): # pragma: no cover def __call__( self, app: ASGIApp, base_url: str = "http://testserver", raise_server_exceptions: bool = True, root_path: str = "", cookies: httpx._types.CookieTypes | None = None, headers: dict[str, str] | None = None, follow_redirects: bool = True, client: tuple[str, int] = ("testclient", 50000), ) -> TestClient: ... else: # pragma: no cover class TestClientFactory: __test__ = False starlette-0.50.0/uv.lock000066400000000000000000005645511510142272400151250ustar00rootroot00000000000000version = 1 revision = 3 requires-python = ">=3.10" [[package]] name = "anyio" version = "4.10.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, { name = "idna" }, { name = "sniffio" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/f1/b4/636b3b65173d3ce9a38ef5f0522789614e590dab6a8d505340a4efe4c567/anyio-4.10.0.tar.gz", hash = "sha256:3f3fae35c96039744587aa5b8371e7e8e603c0702999535961dd336026973ba6", size = 213252, upload-time = "2025-08-04T08:54:26.451Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/6f/12/e5e0282d673bb9746bacfb6e2dba8719989d3660cdb2ea79aee9a9651afb/anyio-4.10.0-py3-none-any.whl", hash = "sha256:60e474ac86736bbfd6f210f7a61218939c318f43f9972497381f1c5e930ed3d1", size = 107213, upload-time = "2025-08-04T08:54:24.882Z" }, ] [[package]] name = "attrs" version = "25.3.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032, upload-time = "2025-03-13T11:10:22.779Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload-time = "2025-03-13T11:10:21.14Z" }, ] [[package]] name = "babel" version = "2.17.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/7d/6b/d52e42361e1aa00709585ecc30b3f9684b3ab62530771402248b1b1d6240/babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d", size = 9951852, upload-time = "2025-02-01T15:17:41.026Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2", size = 10182537, upload-time = "2025-02-01T15:17:37.39Z" }, ] [[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 = "backrefs" version = "5.9" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/eb/a7/312f673df6a79003279e1f55619abbe7daebbb87c17c976ddc0345c04c7b/backrefs-5.9.tar.gz", hash = "sha256:808548cb708d66b82ee231f962cb36faaf4f2baab032f2fbb783e9c2fdddaa59", size = 5765857, upload-time = "2025-06-22T19:34:13.97Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/19/4d/798dc1f30468134906575156c089c492cf79b5a5fd373f07fe26c4d046bf/backrefs-5.9-py310-none-any.whl", hash = "sha256:db8e8ba0e9de81fcd635f440deab5ae5f2591b54ac1ebe0550a2ca063488cd9f", size = 380267, upload-time = "2025-06-22T19:34:05.252Z" }, { url = "https://files.pythonhosted.org/packages/55/07/f0b3375bf0d06014e9787797e6b7cc02b38ac9ff9726ccfe834d94e9991e/backrefs-5.9-py311-none-any.whl", hash = "sha256:6907635edebbe9b2dc3de3a2befff44d74f30a4562adbb8b36f21252ea19c5cf", size = 392072, upload-time = "2025-06-22T19:34:06.743Z" }, { url = "https://files.pythonhosted.org/packages/9d/12/4f345407259dd60a0997107758ba3f221cf89a9b5a0f8ed5b961aef97253/backrefs-5.9-py312-none-any.whl", hash = "sha256:7fdf9771f63e6028d7fee7e0c497c81abda597ea45d6b8f89e8ad76994f5befa", size = 397947, upload-time = "2025-06-22T19:34:08.172Z" }, { url = "https://files.pythonhosted.org/packages/10/bf/fa31834dc27a7f05e5290eae47c82690edc3a7b37d58f7fb35a1bdbf355b/backrefs-5.9-py313-none-any.whl", hash = "sha256:cc37b19fa219e93ff825ed1fed8879e47b4d89aa7a1884860e2db64ccd7c676b", size = 399843, upload-time = "2025-06-22T19:34:09.68Z" }, { url = "https://files.pythonhosted.org/packages/fc/24/b29af34b2c9c41645a9f4ff117bae860291780d73880f449e0b5d948c070/backrefs-5.9-py314-none-any.whl", hash = "sha256:df5e169836cc8acb5e440ebae9aad4bf9d15e226d3bad049cf3f6a5c20cc8dc9", size = 411762, upload-time = "2025-06-22T19:34:11.037Z" }, { url = "https://files.pythonhosted.org/packages/41/ff/392bff89415399a979be4a65357a41d92729ae8580a66073d8ec8d810f98/backrefs-5.9-py39-none-any.whl", hash = "sha256:f48ee18f6252b8f5777a22a00a09a85de0ca931658f1dd96d4406a34f3748c60", size = 380265, upload-time = "2025-06-22T19:34:12.405Z" }, ] [[package]] name = "black" version = "25.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "mypy-extensions" }, { name = "packaging" }, { name = "pathspec" }, { name = "platformdirs" }, { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/94/49/26a7b0f3f35da4b5a65f081943b7bcd22d7002f5f0fb8098ec1ff21cb6ef/black-25.1.0.tar.gz", hash = "sha256:33496d5cd1222ad73391352b4ae8da15253c5de89b93a80b3e2c8d9a19ec2666", size = 649449, upload-time = "2025-01-29T04:15:40.373Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/4d/3b/4ba3f93ac8d90410423fdd31d7541ada9bcee1df32fb90d26de41ed40e1d/black-25.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:759e7ec1e050a15f89b770cefbf91ebee8917aac5c20483bc2d80a6c3a04df32", size = 1629419, upload-time = "2025-01-29T05:37:06.642Z" }, { url = "https://files.pythonhosted.org/packages/b4/02/0bde0485146a8a5e694daed47561785e8b77a0466ccc1f3e485d5ef2925e/black-25.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e519ecf93120f34243e6b0054db49c00a35f84f195d5bce7e9f5cfc578fc2da", size = 1461080, upload-time = "2025-01-29T05:37:09.321Z" }, { url = "https://files.pythonhosted.org/packages/52/0e/abdf75183c830eaca7589144ff96d49bce73d7ec6ad12ef62185cc0f79a2/black-25.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:055e59b198df7ac0b7efca5ad7ff2516bca343276c466be72eb04a3bcc1f82d7", size = 1766886, upload-time = "2025-01-29T04:18:24.432Z" }, { url = "https://files.pythonhosted.org/packages/dc/a6/97d8bb65b1d8a41f8a6736222ba0a334db7b7b77b8023ab4568288f23973/black-25.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:db8ea9917d6f8fc62abd90d944920d95e73c83a5ee3383493e35d271aca872e9", size = 1419404, upload-time = "2025-01-29T04:19:04.296Z" }, { url = "https://files.pythonhosted.org/packages/7e/4f/87f596aca05c3ce5b94b8663dbfe242a12843caaa82dd3f85f1ffdc3f177/black-25.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a39337598244de4bae26475f77dda852ea00a93bd4c728e09eacd827ec929df0", size = 1614372, upload-time = "2025-01-29T05:37:11.71Z" }, { url = "https://files.pythonhosted.org/packages/e7/d0/2c34c36190b741c59c901e56ab7f6e54dad8df05a6272a9747ecef7c6036/black-25.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:96c1c7cd856bba8e20094e36e0f948718dc688dba4a9d78c3adde52b9e6c2299", size = 1442865, upload-time = "2025-01-29T05:37:14.309Z" }, { url = "https://files.pythonhosted.org/packages/21/d4/7518c72262468430ead45cf22bd86c883a6448b9eb43672765d69a8f1248/black-25.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bce2e264d59c91e52d8000d507eb20a9aca4a778731a08cfff7e5ac4a4bb7096", size = 1749699, upload-time = "2025-01-29T04:18:17.688Z" }, { url = "https://files.pythonhosted.org/packages/58/db/4f5beb989b547f79096e035c4981ceb36ac2b552d0ac5f2620e941501c99/black-25.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:172b1dbff09f86ce6f4eb8edf9dede08b1fce58ba194c87d7a4f1a5aa2f5b3c2", size = 1428028, upload-time = "2025-01-29T04:18:51.711Z" }, { url = "https://files.pythonhosted.org/packages/83/71/3fe4741df7adf015ad8dfa082dd36c94ca86bb21f25608eb247b4afb15b2/black-25.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4b60580e829091e6f9238c848ea6750efed72140b91b048770b64e74fe04908b", size = 1650988, upload-time = "2025-01-29T05:37:16.707Z" }, { url = "https://files.pythonhosted.org/packages/13/f3/89aac8a83d73937ccd39bbe8fc6ac8860c11cfa0af5b1c96d081facac844/black-25.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e2978f6df243b155ef5fa7e558a43037c3079093ed5d10fd84c43900f2d8ecc", size = 1453985, upload-time = "2025-01-29T05:37:18.273Z" }, { url = "https://files.pythonhosted.org/packages/6f/22/b99efca33f1f3a1d2552c714b1e1b5ae92efac6c43e790ad539a163d1754/black-25.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b48735872ec535027d979e8dcb20bf4f70b5ac75a8ea99f127c106a7d7aba9f", size = 1783816, upload-time = "2025-01-29T04:18:33.823Z" }, { url = "https://files.pythonhosted.org/packages/18/7e/a27c3ad3822b6f2e0e00d63d58ff6299a99a5b3aee69fa77cd4b0076b261/black-25.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:ea0213189960bda9cf99be5b8c8ce66bb054af5e9e861249cd23471bd7b0b3ba", size = 1440860, upload-time = "2025-01-29T04:19:12.944Z" }, { url = "https://files.pythonhosted.org/packages/98/87/0edf98916640efa5d0696e1abb0a8357b52e69e82322628f25bf14d263d1/black-25.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f0b18a02996a836cc9c9c78e5babec10930862827b1b724ddfe98ccf2f2fe4f", size = 1650673, upload-time = "2025-01-29T05:37:20.574Z" }, { url = "https://files.pythonhosted.org/packages/52/e5/f7bf17207cf87fa6e9b676576749c6b6ed0d70f179a3d812c997870291c3/black-25.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:afebb7098bfbc70037a053b91ae8437c3857482d3a690fefc03e9ff7aa9a5fd3", size = 1453190, upload-time = "2025-01-29T05:37:22.106Z" }, { url = "https://files.pythonhosted.org/packages/e3/ee/adda3d46d4a9120772fae6de454c8495603c37c4c3b9c60f25b1ab6401fe/black-25.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:030b9759066a4ee5e5aca28c3c77f9c64789cdd4de8ac1df642c40b708be6171", size = 1782926, upload-time = "2025-01-29T04:18:58.564Z" }, { url = "https://files.pythonhosted.org/packages/cc/64/94eb5f45dcb997d2082f097a3944cfc7fe87e071907f677e80788a2d7b7a/black-25.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:a22f402b410566e2d1c950708c77ebf5ebd5d0d88a6a2e87c86d9fb48afa0d18", size = 1442613, upload-time = "2025-01-29T04:19:27.63Z" }, { url = "https://files.pythonhosted.org/packages/09/71/54e999902aed72baf26bca0d50781b01838251a462612966e9fc4891eadd/black-25.1.0-py3-none-any.whl", hash = "sha256:95e8176dae143ba9097f351d174fdaf0ccd29efb414b362ae3fd72bf0f710717", size = 207646, upload-time = "2025-01-29T04:15:38.082Z" }, ] [[package]] name = "certifi" version = "2025.8.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/dc/67/960ebe6bf230a96cda2e0abcf73af550ec4f090005363542f0765df162e0/certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407", size = 162386, upload-time = "2025-08-03T03:07:47.08Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5", size = 161216, upload-time = "2025-08-03T03:07:45.777Z" }, ] [[package]] name = "cffi" version = "1.17.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pycparser" }, ] sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621, upload-time = "2024-09-04T20:45:21.852Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/de/cc/4635c320081c78d6ffc2cab0a76025b691a91204f4aa317d568ff9280a2d/cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382", size = 426024, upload-time = "2024-09-04T20:43:34.186Z" }, { url = "https://files.pythonhosted.org/packages/b6/7b/3b2b250f3aab91abe5f8a51ada1b717935fdaec53f790ad4100fe2ec64d1/cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702", size = 448188, upload-time = "2024-09-04T20:43:36.286Z" }, { url = "https://files.pythonhosted.org/packages/d3/48/1b9283ebbf0ec065148d8de05d647a986c5f22586b18120020452fff8f5d/cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3", size = 455571, upload-time = "2024-09-04T20:43:38.586Z" }, { url = "https://files.pythonhosted.org/packages/40/87/3b8452525437b40f39ca7ff70276679772ee7e8b394934ff60e63b7b090c/cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6", size = 436687, upload-time = "2024-09-04T20:43:40.084Z" }, { url = "https://files.pythonhosted.org/packages/8d/fb/4da72871d177d63649ac449aec2e8a29efe0274035880c7af59101ca2232/cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17", size = 446211, upload-time = "2024-09-04T20:43:41.526Z" }, { url = "https://files.pythonhosted.org/packages/ab/a0/62f00bcb411332106c02b663b26f3545a9ef136f80d5df746c05878f8c4b/cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8", size = 461325, upload-time = "2024-09-04T20:43:43.117Z" }, { url = "https://files.pythonhosted.org/packages/36/83/76127035ed2e7e27b0787604d99da630ac3123bfb02d8e80c633f218a11d/cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e", size = 438784, upload-time = "2024-09-04T20:43:45.256Z" }, { url = "https://files.pythonhosted.org/packages/21/81/a6cd025db2f08ac88b901b745c163d884641909641f9b826e8cb87645942/cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be", size = 461564, upload-time = "2024-09-04T20:43:46.779Z" }, { url = "https://files.pythonhosted.org/packages/f8/fe/4d41c2f200c4a457933dbd98d3cf4e911870877bd94d9656cc0fcb390681/cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c", size = 171804, upload-time = "2024-09-04T20:43:48.186Z" }, { url = "https://files.pythonhosted.org/packages/d1/b6/0b0f5ab93b0df4acc49cae758c81fe4e5ef26c3ae2e10cc69249dfd8b3ab/cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15", size = 181299, upload-time = "2024-09-04T20:43:49.812Z" }, { url = "https://files.pythonhosted.org/packages/94/dd/a3f0118e688d1b1a57553da23b16bdade96d2f9bcda4d32e7d2838047ff7/cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", size = 445259, upload-time = "2024-09-04T20:43:56.123Z" }, { url = "https://files.pythonhosted.org/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", size = 469200, upload-time = "2024-09-04T20:43:57.891Z" }, { url = "https://files.pythonhosted.org/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", size = 477235, upload-time = "2024-09-04T20:44:00.18Z" }, { url = "https://files.pythonhosted.org/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", size = 459721, upload-time = "2024-09-04T20:44:01.585Z" }, { url = "https://files.pythonhosted.org/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", size = 467242, upload-time = "2024-09-04T20:44:03.467Z" }, { url = "https://files.pythonhosted.org/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", size = 477999, upload-time = "2024-09-04T20:44:05.023Z" }, { url = "https://files.pythonhosted.org/packages/44/74/f2a2460684a1a2d00ca799ad880d54652841a780c4c97b87754f660c7603/cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", size = 454242, upload-time = "2024-09-04T20:44:06.444Z" }, { url = "https://files.pythonhosted.org/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", size = 478604, upload-time = "2024-09-04T20:44:08.206Z" }, { url = "https://files.pythonhosted.org/packages/34/33/e1b8a1ba29025adbdcda5fb3a36f94c03d771c1b7b12f726ff7fef2ebe36/cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", size = 171727, upload-time = "2024-09-04T20:44:09.481Z" }, { url = "https://files.pythonhosted.org/packages/3d/97/50228be003bb2802627d28ec0627837ac0bf35c90cf769812056f235b2d1/cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", size = 181400, upload-time = "2024-09-04T20:44:10.873Z" }, { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803, upload-time = "2024-09-04T20:44:15.231Z" }, { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850, upload-time = "2024-09-04T20:44:17.188Z" }, { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729, upload-time = "2024-09-04T20:44:18.688Z" }, { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256, upload-time = "2024-09-04T20:44:20.248Z" }, { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424, upload-time = "2024-09-04T20:44:21.673Z" }, { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568, upload-time = "2024-09-04T20:44:23.245Z" }, { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736, upload-time = "2024-09-04T20:44:24.757Z" }, { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448, upload-time = "2024-09-04T20:44:26.208Z" }, { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976, upload-time = "2024-09-04T20:44:27.578Z" }, { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792, upload-time = "2024-09-04T20:44:32.01Z" }, { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893, upload-time = "2024-09-04T20:44:33.606Z" }, { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810, upload-time = "2024-09-04T20:44:35.191Z" }, { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200, upload-time = "2024-09-04T20:44:36.743Z" }, { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447, upload-time = "2024-09-04T20:44:38.492Z" }, { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358, upload-time = "2024-09-04T20:44:40.046Z" }, { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469, upload-time = "2024-09-04T20:44:41.616Z" }, { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475, upload-time = "2024-09-04T20:44:43.733Z" }, { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009, upload-time = "2024-09-04T20:44:45.309Z" }, ] [[package]] name = "charset-normalizer" version = "3.4.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/83/2d/5fd176ceb9b2fc619e63405525573493ca23441330fcdaee6bef9460e924/charset_normalizer-3.4.3.tar.gz", hash = "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14", size = 122371, upload-time = "2025-08-09T07:57:28.46Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/d6/98/f3b8013223728a99b908c9344da3aa04ee6e3fa235f19409033eda92fb78/charset_normalizer-3.4.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fb7f67a1bfa6e40b438170ebdc8158b78dc465a5a67b6dde178a46987b244a72", size = 207695, upload-time = "2025-08-09T07:55:36.452Z" }, { url = "https://files.pythonhosted.org/packages/21/40/5188be1e3118c82dcb7c2a5ba101b783822cfb413a0268ed3be0468532de/charset_normalizer-3.4.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cc9370a2da1ac13f0153780040f465839e6cccb4a1e44810124b4e22483c93fe", size = 147153, upload-time = "2025-08-09T07:55:38.467Z" }, { url = "https://files.pythonhosted.org/packages/37/60/5d0d74bc1e1380f0b72c327948d9c2aca14b46a9efd87604e724260f384c/charset_normalizer-3.4.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:07a0eae9e2787b586e129fdcbe1af6997f8d0e5abaa0bc98c0e20e124d67e601", size = 160428, upload-time = "2025-08-09T07:55:40.072Z" }, { url = "https://files.pythonhosted.org/packages/85/9a/d891f63722d9158688de58d050c59dc3da560ea7f04f4c53e769de5140f5/charset_normalizer-3.4.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:74d77e25adda8581ffc1c720f1c81ca082921329452eba58b16233ab1842141c", size = 157627, upload-time = "2025-08-09T07:55:41.706Z" }, { url = "https://files.pythonhosted.org/packages/65/1a/7425c952944a6521a9cfa7e675343f83fd82085b8af2b1373a2409c683dc/charset_normalizer-3.4.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0e909868420b7049dafd3a31d45125b31143eec59235311fc4c57ea26a4acd2", size = 152388, upload-time = "2025-08-09T07:55:43.262Z" }, { url = "https://files.pythonhosted.org/packages/f0/c9/a2c9c2a355a8594ce2446085e2ec97fd44d323c684ff32042e2a6b718e1d/charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c6f162aabe9a91a309510d74eeb6507fab5fff92337a15acbe77753d88d9dcf0", size = 150077, upload-time = "2025-08-09T07:55:44.903Z" }, { url = "https://files.pythonhosted.org/packages/3b/38/20a1f44e4851aa1c9105d6e7110c9d020e093dfa5836d712a5f074a12bf7/charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4ca4c094de7771a98d7fbd67d9e5dbf1eb73efa4f744a730437d8a3a5cf994f0", size = 161631, upload-time = "2025-08-09T07:55:46.346Z" }, { url = "https://files.pythonhosted.org/packages/a4/fa/384d2c0f57edad03d7bec3ebefb462090d8905b4ff5a2d2525f3bb711fac/charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:02425242e96bcf29a49711b0ca9f37e451da7c70562bc10e8ed992a5a7a25cc0", size = 159210, upload-time = "2025-08-09T07:55:47.539Z" }, { url = "https://files.pythonhosted.org/packages/33/9e/eca49d35867ca2db336b6ca27617deed4653b97ebf45dfc21311ce473c37/charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:78deba4d8f9590fe4dae384aeff04082510a709957e968753ff3c48399f6f92a", size = 153739, upload-time = "2025-08-09T07:55:48.744Z" }, { url = "https://files.pythonhosted.org/packages/2a/91/26c3036e62dfe8de8061182d33be5025e2424002125c9500faff74a6735e/charset_normalizer-3.4.3-cp310-cp310-win32.whl", hash = "sha256:d79c198e27580c8e958906f803e63cddb77653731be08851c7df0b1a14a8fc0f", size = 99825, upload-time = "2025-08-09T07:55:50.305Z" }, { url = "https://files.pythonhosted.org/packages/e2/c6/f05db471f81af1fa01839d44ae2a8bfeec8d2a8b4590f16c4e7393afd323/charset_normalizer-3.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:c6e490913a46fa054e03699c70019ab869e990270597018cef1d8562132c2669", size = 107452, upload-time = "2025-08-09T07:55:51.461Z" }, { url = "https://files.pythonhosted.org/packages/7f/b5/991245018615474a60965a7c9cd2b4efbaabd16d582a5547c47ee1c7730b/charset_normalizer-3.4.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b", size = 204483, upload-time = "2025-08-09T07:55:53.12Z" }, { url = "https://files.pythonhosted.org/packages/c7/2a/ae245c41c06299ec18262825c1569c5d3298fc920e4ddf56ab011b417efd/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64", size = 145520, upload-time = "2025-08-09T07:55:54.712Z" }, { url = "https://files.pythonhosted.org/packages/3a/a4/b3b6c76e7a635748c4421d2b92c7b8f90a432f98bda5082049af37ffc8e3/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91", size = 158876, upload-time = "2025-08-09T07:55:56.024Z" }, { url = "https://files.pythonhosted.org/packages/e2/e6/63bb0e10f90a8243c5def74b5b105b3bbbfb3e7bb753915fe333fb0c11ea/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f", size = 156083, upload-time = "2025-08-09T07:55:57.582Z" }, { url = "https://files.pythonhosted.org/packages/87/df/b7737ff046c974b183ea9aa111b74185ac8c3a326c6262d413bd5a1b8c69/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07", size = 150295, upload-time = "2025-08-09T07:55:59.147Z" }, { url = "https://files.pythonhosted.org/packages/61/f1/190d9977e0084d3f1dc169acd060d479bbbc71b90bf3e7bf7b9927dec3eb/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30", size = 148379, upload-time = "2025-08-09T07:56:00.364Z" }, { url = "https://files.pythonhosted.org/packages/4c/92/27dbe365d34c68cfe0ca76f1edd70e8705d82b378cb54ebbaeabc2e3029d/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14", size = 160018, upload-time = "2025-08-09T07:56:01.678Z" }, { url = "https://files.pythonhosted.org/packages/99/04/baae2a1ea1893a01635d475b9261c889a18fd48393634b6270827869fa34/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c", size = 157430, upload-time = "2025-08-09T07:56:02.87Z" }, { url = "https://files.pythonhosted.org/packages/2f/36/77da9c6a328c54d17b960c89eccacfab8271fdaaa228305330915b88afa9/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae", size = 151600, upload-time = "2025-08-09T07:56:04.089Z" }, { url = "https://files.pythonhosted.org/packages/64/d4/9eb4ff2c167edbbf08cdd28e19078bf195762e9bd63371689cab5ecd3d0d/charset_normalizer-3.4.3-cp311-cp311-win32.whl", hash = "sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849", size = 99616, upload-time = "2025-08-09T07:56:05.658Z" }, { url = "https://files.pythonhosted.org/packages/f4/9c/996a4a028222e7761a96634d1820de8a744ff4327a00ada9c8942033089b/charset_normalizer-3.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c", size = 107108, upload-time = "2025-08-09T07:56:07.176Z" }, { url = "https://files.pythonhosted.org/packages/e9/5e/14c94999e418d9b87682734589404a25854d5f5d0408df68bc15b6ff54bb/charset_normalizer-3.4.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1", size = 205655, upload-time = "2025-08-09T07:56:08.475Z" }, { url = "https://files.pythonhosted.org/packages/7d/a8/c6ec5d389672521f644505a257f50544c074cf5fc292d5390331cd6fc9c3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884", size = 146223, upload-time = "2025-08-09T07:56:09.708Z" }, { url = "https://files.pythonhosted.org/packages/fc/eb/a2ffb08547f4e1e5415fb69eb7db25932c52a52bed371429648db4d84fb1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018", size = 159366, upload-time = "2025-08-09T07:56:11.326Z" }, { url = "https://files.pythonhosted.org/packages/82/10/0fd19f20c624b278dddaf83b8464dcddc2456cb4b02bb902a6da126b87a1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392", size = 157104, upload-time = "2025-08-09T07:56:13.014Z" }, { url = "https://files.pythonhosted.org/packages/16/ab/0233c3231af734f5dfcf0844aa9582d5a1466c985bbed6cedab85af9bfe3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f", size = 151830, upload-time = "2025-08-09T07:56:14.428Z" }, { url = "https://files.pythonhosted.org/packages/ae/02/e29e22b4e02839a0e4a06557b1999d0a47db3567e82989b5bb21f3fbbd9f/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154", size = 148854, upload-time = "2025-08-09T07:56:16.051Z" }, { url = "https://files.pythonhosted.org/packages/05/6b/e2539a0a4be302b481e8cafb5af8792da8093b486885a1ae4d15d452bcec/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491", size = 160670, upload-time = "2025-08-09T07:56:17.314Z" }, { url = "https://files.pythonhosted.org/packages/31/e7/883ee5676a2ef217a40ce0bffcc3d0dfbf9e64cbcfbdf822c52981c3304b/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93", size = 158501, upload-time = "2025-08-09T07:56:18.641Z" }, { url = "https://files.pythonhosted.org/packages/c1/35/6525b21aa0db614cf8b5792d232021dca3df7f90a1944db934efa5d20bb1/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f", size = 153173, upload-time = "2025-08-09T07:56:20.289Z" }, { url = "https://files.pythonhosted.org/packages/50/ee/f4704bad8201de513fdc8aac1cabc87e38c5818c93857140e06e772b5892/charset_normalizer-3.4.3-cp312-cp312-win32.whl", hash = "sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37", size = 99822, upload-time = "2025-08-09T07:56:21.551Z" }, { url = "https://files.pythonhosted.org/packages/39/f5/3b3836ca6064d0992c58c7561c6b6eee1b3892e9665d650c803bd5614522/charset_normalizer-3.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc", size = 107543, upload-time = "2025-08-09T07:56:23.115Z" }, { url = "https://files.pythonhosted.org/packages/65/ca/2135ac97709b400c7654b4b764daf5c5567c2da45a30cdd20f9eefe2d658/charset_normalizer-3.4.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe", size = 205326, upload-time = "2025-08-09T07:56:24.721Z" }, { url = "https://files.pythonhosted.org/packages/71/11/98a04c3c97dd34e49c7d247083af03645ca3730809a5509443f3c37f7c99/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8", size = 146008, upload-time = "2025-08-09T07:56:26.004Z" }, { url = "https://files.pythonhosted.org/packages/60/f5/4659a4cb3c4ec146bec80c32d8bb16033752574c20b1252ee842a95d1a1e/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9", size = 159196, upload-time = "2025-08-09T07:56:27.25Z" }, { url = "https://files.pythonhosted.org/packages/86/9e/f552f7a00611f168b9a5865a1414179b2c6de8235a4fa40189f6f79a1753/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31", size = 156819, upload-time = "2025-08-09T07:56:28.515Z" }, { url = "https://files.pythonhosted.org/packages/7e/95/42aa2156235cbc8fa61208aded06ef46111c4d3f0de233107b3f38631803/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f", size = 151350, upload-time = "2025-08-09T07:56:29.716Z" }, { url = "https://files.pythonhosted.org/packages/c2/a9/3865b02c56f300a6f94fc631ef54f0a8a29da74fb45a773dfd3dcd380af7/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927", size = 148644, upload-time = "2025-08-09T07:56:30.984Z" }, { url = "https://files.pythonhosted.org/packages/77/d9/cbcf1a2a5c7d7856f11e7ac2d782aec12bdfea60d104e60e0aa1c97849dc/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9", size = 160468, upload-time = "2025-08-09T07:56:32.252Z" }, { url = "https://files.pythonhosted.org/packages/f6/42/6f45efee8697b89fda4d50580f292b8f7f9306cb2971d4b53f8914e4d890/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5", size = 158187, upload-time = "2025-08-09T07:56:33.481Z" }, { url = "https://files.pythonhosted.org/packages/70/99/f1c3bdcfaa9c45b3ce96f70b14f070411366fa19549c1d4832c935d8e2c3/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc", size = 152699, upload-time = "2025-08-09T07:56:34.739Z" }, { url = "https://files.pythonhosted.org/packages/a3/ad/b0081f2f99a4b194bcbb1934ef3b12aa4d9702ced80a37026b7607c72e58/charset_normalizer-3.4.3-cp313-cp313-win32.whl", hash = "sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce", size = 99580, upload-time = "2025-08-09T07:56:35.981Z" }, { url = "https://files.pythonhosted.org/packages/9a/8f/ae790790c7b64f925e5c953b924aaa42a243fb778fed9e41f147b2a5715a/charset_normalizer-3.4.3-cp313-cp313-win_amd64.whl", hash = "sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef", size = 107366, upload-time = "2025-08-09T07:56:37.339Z" }, { url = "https://files.pythonhosted.org/packages/8e/91/b5a06ad970ddc7a0e513112d40113e834638f4ca1120eb727a249fb2715e/charset_normalizer-3.4.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15", size = 204342, upload-time = "2025-08-09T07:56:38.687Z" }, { url = "https://files.pythonhosted.org/packages/ce/ec/1edc30a377f0a02689342f214455c3f6c2fbedd896a1d2f856c002fc3062/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db", size = 145995, upload-time = "2025-08-09T07:56:40.048Z" }, { url = "https://files.pythonhosted.org/packages/17/e5/5e67ab85e6d22b04641acb5399c8684f4d37caf7558a53859f0283a650e9/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d", size = 158640, upload-time = "2025-08-09T07:56:41.311Z" }, { url = "https://files.pythonhosted.org/packages/f1/e5/38421987f6c697ee3722981289d554957c4be652f963d71c5e46a262e135/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096", size = 156636, upload-time = "2025-08-09T07:56:43.195Z" }, { url = "https://files.pythonhosted.org/packages/a0/e4/5a075de8daa3ec0745a9a3b54467e0c2967daaaf2cec04c845f73493e9a1/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa", size = 150939, upload-time = "2025-08-09T07:56:44.819Z" }, { url = "https://files.pythonhosted.org/packages/02/f7/3611b32318b30974131db62b4043f335861d4d9b49adc6d57c1149cc49d4/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049", size = 148580, upload-time = "2025-08-09T07:56:46.684Z" }, { url = "https://files.pythonhosted.org/packages/7e/61/19b36f4bd67f2793ab6a99b979b4e4f3d8fc754cbdffb805335df4337126/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0", size = 159870, upload-time = "2025-08-09T07:56:47.941Z" }, { url = "https://files.pythonhosted.org/packages/06/57/84722eefdd338c04cf3030ada66889298eaedf3e7a30a624201e0cbe424a/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92", size = 157797, upload-time = "2025-08-09T07:56:49.756Z" }, { url = "https://files.pythonhosted.org/packages/72/2a/aff5dd112b2f14bcc3462c312dce5445806bfc8ab3a7328555da95330e4b/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16", size = 152224, upload-time = "2025-08-09T07:56:51.369Z" }, { url = "https://files.pythonhosted.org/packages/b7/8c/9839225320046ed279c6e839d51f028342eb77c91c89b8ef2549f951f3ec/charset_normalizer-3.4.3-cp314-cp314-win32.whl", hash = "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce", size = 100086, upload-time = "2025-08-09T07:56:52.722Z" }, { url = "https://files.pythonhosted.org/packages/ee/7a/36fbcf646e41f710ce0a563c1c9a343c6edf9be80786edeb15b6f62e17db/charset_normalizer-3.4.3-cp314-cp314-win_amd64.whl", hash = "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c", size = 107400, upload-time = "2025-08-09T07:56:55.172Z" }, { url = "https://files.pythonhosted.org/packages/8a/1f/f041989e93b001bc4e44bb1669ccdcf54d3f00e628229a85b08d330615c5/charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", size = 53175, upload-time = "2025-08-09T07:57:26.864Z" }, ] [[package]] name = "click" version = "8.2.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202", size = 286342, upload-time = "2025-05-20T23:19:49.832Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b", size = 102215, upload-time = "2025-05-20T23:19:47.796Z" }, ] [[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.8.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/ba/07/998afa4a0ecdf9b1981ae05415dad2d4e7716e1b1f00abbd91691ac09ac9/coverage-7.8.2.tar.gz", hash = "sha256:a886d531373a1f6ff9fad2a2ba4a045b68467b779ae729ee0b3b10ac20033b27", size = 812759, upload-time = "2025-05-23T11:39:57.856Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/26/6b/7dd06399a5c0b81007e3a6af0395cd60e6a30f959f8d407d3ee04642e896/coverage-7.8.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bd8ec21e1443fd7a447881332f7ce9d35b8fbd2849e761bb290b584535636b0a", size = 211573, upload-time = "2025-05-23T11:37:47.207Z" }, { url = "https://files.pythonhosted.org/packages/f0/df/2b24090820a0bac1412955fb1a4dade6bc3b8dcef7b899c277ffaf16916d/coverage-7.8.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4c26c2396674816deaeae7ded0e2b42c26537280f8fe313335858ffff35019be", size = 212006, upload-time = "2025-05-23T11:37:50.289Z" }, { url = "https://files.pythonhosted.org/packages/c5/c4/e4e3b998e116625562a872a342419652fa6ca73f464d9faf9f52f1aff427/coverage-7.8.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1aec326ed237e5880bfe69ad41616d333712c7937bcefc1343145e972938f9b3", size = 241128, upload-time = "2025-05-23T11:37:52.229Z" }, { url = "https://files.pythonhosted.org/packages/b1/67/b28904afea3e87a895da850ba587439a61699bf4b73d04d0dfd99bbd33b4/coverage-7.8.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5e818796f71702d7a13e50c70de2a1924f729228580bcba1607cccf32eea46e6", size = 239026, upload-time = "2025-05-23T11:37:53.846Z" }, { url = "https://files.pythonhosted.org/packages/8c/0f/47bf7c5630d81bc2cd52b9e13043685dbb7c79372a7f5857279cc442b37c/coverage-7.8.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:546e537d9e24efc765c9c891328f30f826e3e4808e31f5d0f87c4ba12bbd1622", size = 240172, upload-time = "2025-05-23T11:37:55.711Z" }, { url = "https://files.pythonhosted.org/packages/ba/38/af3eb9d36d85abc881f5aaecf8209383dbe0fa4cac2d804c55d05c51cb04/coverage-7.8.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ab9b09a2349f58e73f8ebc06fac546dd623e23b063e5398343c5270072e3201c", size = 240086, upload-time = "2025-05-23T11:37:57.724Z" }, { url = "https://files.pythonhosted.org/packages/9e/64/c40c27c2573adeba0fe16faf39a8aa57368a1f2148865d6bb24c67eadb41/coverage-7.8.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fd51355ab8a372d89fb0e6a31719e825cf8df8b6724bee942fb5b92c3f016ba3", size = 238792, upload-time = "2025-05-23T11:37:59.737Z" }, { url = "https://files.pythonhosted.org/packages/8e/ab/b7c85146f15457671c1412afca7c25a5696d7625e7158002aa017e2d7e3c/coverage-7.8.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0774df1e093acb6c9e4d58bce7f86656aeed6c132a16e2337692c12786b32404", size = 239096, upload-time = "2025-05-23T11:38:01.693Z" }, { url = "https://files.pythonhosted.org/packages/d3/50/9446dad1310905fb1dc284d60d4320a5b25d4e3e33f9ea08b8d36e244e23/coverage-7.8.2-cp310-cp310-win32.whl", hash = "sha256:00f2e2f2e37f47e5f54423aeefd6c32a7dbcedc033fcd3928a4f4948e8b96af7", size = 214144, upload-time = "2025-05-23T11:38:03.68Z" }, { url = "https://files.pythonhosted.org/packages/23/ed/792e66ad7b8b0df757db8d47af0c23659cdb5a65ef7ace8b111cacdbee89/coverage-7.8.2-cp310-cp310-win_amd64.whl", hash = "sha256:145b07bea229821d51811bf15eeab346c236d523838eda395ea969d120d13347", size = 215043, upload-time = "2025-05-23T11:38:05.217Z" }, { url = "https://files.pythonhosted.org/packages/6a/4d/1ff618ee9f134d0de5cc1661582c21a65e06823f41caf801aadf18811a8e/coverage-7.8.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b99058eef42e6a8dcd135afb068b3d53aff3921ce699e127602efff9956457a9", size = 211692, upload-time = "2025-05-23T11:38:08.485Z" }, { url = "https://files.pythonhosted.org/packages/96/fa/c3c1b476de96f2bc7a8ca01a9f1fcb51c01c6b60a9d2c3e66194b2bdb4af/coverage-7.8.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5feb7f2c3e6ea94d3b877def0270dff0947b8d8c04cfa34a17be0a4dc1836879", size = 212115, upload-time = "2025-05-23T11:38:09.989Z" }, { url = "https://files.pythonhosted.org/packages/f7/c2/5414c5a1b286c0f3881ae5adb49be1854ac5b7e99011501f81c8c1453065/coverage-7.8.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:670a13249b957bb9050fab12d86acef7bf8f6a879b9d1a883799276e0d4c674a", size = 244740, upload-time = "2025-05-23T11:38:11.947Z" }, { url = "https://files.pythonhosted.org/packages/cd/46/1ae01912dfb06a642ef3dd9cf38ed4996fda8fe884dab8952da616f81a2b/coverage-7.8.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bdc8bf760459a4a4187b452213e04d039990211f98644c7292adf1e471162b5", size = 242429, upload-time = "2025-05-23T11:38:13.955Z" }, { url = "https://files.pythonhosted.org/packages/06/58/38c676aec594bfe2a87c7683942e5a30224791d8df99bcc8439fde140377/coverage-7.8.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07a989c867986c2a75f158f03fdb413128aad29aca9d4dbce5fc755672d96f11", size = 244218, upload-time = "2025-05-23T11:38:15.631Z" }, { url = "https://files.pythonhosted.org/packages/80/0c/95b1023e881ce45006d9abc250f76c6cdab7134a1c182d9713878dfefcb2/coverage-7.8.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2db10dedeb619a771ef0e2949ccba7b75e33905de959c2643a4607bef2f3fb3a", size = 243865, upload-time = "2025-05-23T11:38:17.622Z" }, { url = "https://files.pythonhosted.org/packages/57/37/0ae95989285a39e0839c959fe854a3ae46c06610439350d1ab860bf020ac/coverage-7.8.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e6ea7dba4e92926b7b5f0990634b78ea02f208d04af520c73a7c876d5a8d36cb", size = 242038, upload-time = "2025-05-23T11:38:19.966Z" }, { url = "https://files.pythonhosted.org/packages/4d/82/40e55f7c0eb5e97cc62cbd9d0746fd24e8caf57be5a408b87529416e0c70/coverage-7.8.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ef2f22795a7aca99fc3c84393a55a53dd18ab8c93fb431004e4d8f0774150f54", size = 242567, upload-time = "2025-05-23T11:38:21.912Z" }, { url = "https://files.pythonhosted.org/packages/f9/35/66a51adc273433a253989f0d9cc7aa6bcdb4855382cf0858200afe578861/coverage-7.8.2-cp311-cp311-win32.whl", hash = "sha256:641988828bc18a6368fe72355df5f1703e44411adbe49bba5644b941ce6f2e3a", size = 214194, upload-time = "2025-05-23T11:38:23.571Z" }, { url = "https://files.pythonhosted.org/packages/f6/8f/a543121f9f5f150eae092b08428cb4e6b6d2d134152c3357b77659d2a605/coverage-7.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:8ab4a51cb39dc1933ba627e0875046d150e88478dbe22ce145a68393e9652975", size = 215109, upload-time = "2025-05-23T11:38:25.137Z" }, { url = "https://files.pythonhosted.org/packages/77/65/6cc84b68d4f35186463cd7ab1da1169e9abb59870c0f6a57ea6aba95f861/coverage-7.8.2-cp311-cp311-win_arm64.whl", hash = "sha256:8966a821e2083c74d88cca5b7dcccc0a3a888a596a04c0b9668a891de3a0cc53", size = 213521, upload-time = "2025-05-23T11:38:27.123Z" }, { url = "https://files.pythonhosted.org/packages/8d/2a/1da1ada2e3044fcd4a3254fb3576e160b8fe5b36d705c8a31f793423f763/coverage-7.8.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e2f6fe3654468d061942591aef56686131335b7a8325684eda85dacdf311356c", size = 211876, upload-time = "2025-05-23T11:38:29.01Z" }, { url = "https://files.pythonhosted.org/packages/70/e9/3d715ffd5b6b17a8be80cd14a8917a002530a99943cc1939ad5bb2aa74b9/coverage-7.8.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76090fab50610798cc05241bf83b603477c40ee87acd358b66196ab0ca44ffa1", size = 212130, upload-time = "2025-05-23T11:38:30.675Z" }, { url = "https://files.pythonhosted.org/packages/a0/02/fdce62bb3c21649abfd91fbdcf041fb99be0d728ff00f3f9d54d97ed683e/coverage-7.8.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bd0a0a5054be160777a7920b731a0570284db5142abaaf81bcbb282b8d99279", size = 246176, upload-time = "2025-05-23T11:38:32.395Z" }, { url = "https://files.pythonhosted.org/packages/a7/52/decbbed61e03b6ffe85cd0fea360a5e04a5a98a7423f292aae62423b8557/coverage-7.8.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da23ce9a3d356d0affe9c7036030b5c8f14556bd970c9b224f9c8205505e3b99", size = 243068, upload-time = "2025-05-23T11:38:33.989Z" }, { url = "https://files.pythonhosted.org/packages/38/6c/d0e9c0cce18faef79a52778219a3c6ee8e336437da8eddd4ab3dbd8fadff/coverage-7.8.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9392773cffeb8d7e042a7b15b82a414011e9d2b5fdbbd3f7e6a6b17d5e21b20", size = 245328, upload-time = "2025-05-23T11:38:35.568Z" }, { url = "https://files.pythonhosted.org/packages/f0/70/f703b553a2f6b6c70568c7e398ed0789d47f953d67fbba36a327714a7bca/coverage-7.8.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:876cbfd0b09ce09d81585d266c07a32657beb3eaec896f39484b631555be0fe2", size = 245099, upload-time = "2025-05-23T11:38:37.627Z" }, { url = "https://files.pythonhosted.org/packages/ec/fb/4cbb370dedae78460c3aacbdad9d249e853f3bc4ce5ff0e02b1983d03044/coverage-7.8.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3da9b771c98977a13fbc3830f6caa85cae6c9c83911d24cb2d218e9394259c57", size = 243314, upload-time = "2025-05-23T11:38:39.238Z" }, { url = "https://files.pythonhosted.org/packages/39/9f/1afbb2cb9c8699b8bc38afdce00a3b4644904e6a38c7bf9005386c9305ec/coverage-7.8.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9a990f6510b3292686713bfef26d0049cd63b9c7bb17e0864f133cbfd2e6167f", size = 244489, upload-time = "2025-05-23T11:38:40.845Z" }, { url = "https://files.pythonhosted.org/packages/79/fa/f3e7ec7d220bff14aba7a4786ae47043770cbdceeea1803083059c878837/coverage-7.8.2-cp312-cp312-win32.whl", hash = "sha256:bf8111cddd0f2b54d34e96613e7fbdd59a673f0cf5574b61134ae75b6f5a33b8", size = 214366, upload-time = "2025-05-23T11:38:43.551Z" }, { url = "https://files.pythonhosted.org/packages/54/aa/9cbeade19b7e8e853e7ffc261df885d66bf3a782c71cba06c17df271f9e6/coverage-7.8.2-cp312-cp312-win_amd64.whl", hash = "sha256:86a323a275e9e44cdf228af9b71c5030861d4d2610886ab920d9945672a81223", size = 215165, upload-time = "2025-05-23T11:38:45.148Z" }, { url = "https://files.pythonhosted.org/packages/c4/73/e2528bf1237d2448f882bbebaec5c3500ef07301816c5c63464b9da4d88a/coverage-7.8.2-cp312-cp312-win_arm64.whl", hash = "sha256:820157de3a589e992689ffcda8639fbabb313b323d26388d02e154164c57b07f", size = 213548, upload-time = "2025-05-23T11:38:46.74Z" }, { url = "https://files.pythonhosted.org/packages/1a/93/eb6400a745ad3b265bac36e8077fdffcf0268bdbbb6c02b7220b624c9b31/coverage-7.8.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ea561010914ec1c26ab4188aef8b1567272ef6de096312716f90e5baa79ef8ca", size = 211898, upload-time = "2025-05-23T11:38:49.066Z" }, { url = "https://files.pythonhosted.org/packages/1b/7c/bdbf113f92683024406a1cd226a199e4200a2001fc85d6a6e7e299e60253/coverage-7.8.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cb86337a4fcdd0e598ff2caeb513ac604d2f3da6d53df2c8e368e07ee38e277d", size = 212171, upload-time = "2025-05-23T11:38:51.207Z" }, { url = "https://files.pythonhosted.org/packages/91/22/594513f9541a6b88eb0dba4d5da7d71596dadef6b17a12dc2c0e859818a9/coverage-7.8.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26a4636ddb666971345541b59899e969f3b301143dd86b0ddbb570bd591f1e85", size = 245564, upload-time = "2025-05-23T11:38:52.857Z" }, { url = "https://files.pythonhosted.org/packages/1f/f4/2860fd6abeebd9f2efcfe0fd376226938f22afc80c1943f363cd3c28421f/coverage-7.8.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5040536cf9b13fb033f76bcb5e1e5cb3b57c4807fef37db9e0ed129c6a094257", size = 242719, upload-time = "2025-05-23T11:38:54.529Z" }, { url = "https://files.pythonhosted.org/packages/89/60/f5f50f61b6332451520e6cdc2401700c48310c64bc2dd34027a47d6ab4ca/coverage-7.8.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc67994df9bcd7e0150a47ef41278b9e0a0ea187caba72414b71dc590b99a108", size = 244634, upload-time = "2025-05-23T11:38:57.326Z" }, { url = "https://files.pythonhosted.org/packages/3b/70/7f4e919039ab7d944276c446b603eea84da29ebcf20984fb1fdf6e602028/coverage-7.8.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e6c86888fd076d9e0fe848af0a2142bf606044dc5ceee0aa9eddb56e26895a0", size = 244824, upload-time = "2025-05-23T11:38:59.421Z" }, { url = "https://files.pythonhosted.org/packages/26/45/36297a4c0cea4de2b2c442fe32f60c3991056c59cdc3cdd5346fbb995c97/coverage-7.8.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:684ca9f58119b8e26bef860db33524ae0365601492e86ba0b71d513f525e7050", size = 242872, upload-time = "2025-05-23T11:39:01.049Z" }, { url = "https://files.pythonhosted.org/packages/a4/71/e041f1b9420f7b786b1367fa2a375703889ef376e0d48de9f5723fb35f11/coverage-7.8.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8165584ddedb49204c4e18da083913bdf6a982bfb558632a79bdaadcdafd0d48", size = 244179, upload-time = "2025-05-23T11:39:02.709Z" }, { url = "https://files.pythonhosted.org/packages/bd/db/3c2bf49bdc9de76acf2491fc03130c4ffc51469ce2f6889d2640eb563d77/coverage-7.8.2-cp313-cp313-win32.whl", hash = "sha256:34759ee2c65362163699cc917bdb2a54114dd06d19bab860725f94ef45a3d9b7", size = 214393, upload-time = "2025-05-23T11:39:05.457Z" }, { url = "https://files.pythonhosted.org/packages/c6/dc/947e75d47ebbb4b02d8babb1fad4ad381410d5bc9da7cfca80b7565ef401/coverage-7.8.2-cp313-cp313-win_amd64.whl", hash = "sha256:2f9bc608fbafaee40eb60a9a53dbfb90f53cc66d3d32c2849dc27cf5638a21e3", size = 215194, upload-time = "2025-05-23T11:39:07.171Z" }, { url = "https://files.pythonhosted.org/packages/90/31/a980f7df8a37eaf0dc60f932507fda9656b3a03f0abf188474a0ea188d6d/coverage-7.8.2-cp313-cp313-win_arm64.whl", hash = "sha256:9fe449ee461a3b0c7105690419d0b0aba1232f4ff6d120a9e241e58a556733f7", size = 213580, upload-time = "2025-05-23T11:39:08.862Z" }, { url = "https://files.pythonhosted.org/packages/8a/6a/25a37dd90f6c95f59355629417ebcb74e1c34e38bb1eddf6ca9b38b0fc53/coverage-7.8.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8369a7c8ef66bded2b6484053749ff220dbf83cba84f3398c84c51a6f748a008", size = 212734, upload-time = "2025-05-23T11:39:11.109Z" }, { url = "https://files.pythonhosted.org/packages/36/8b/3a728b3118988725f40950931abb09cd7f43b3c740f4640a59f1db60e372/coverage-7.8.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:159b81df53a5fcbc7d45dae3adad554fdbde9829a994e15227b3f9d816d00b36", size = 212959, upload-time = "2025-05-23T11:39:12.751Z" }, { url = "https://files.pythonhosted.org/packages/53/3c/212d94e6add3a3c3f412d664aee452045ca17a066def8b9421673e9482c4/coverage-7.8.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6fcbbd35a96192d042c691c9e0c49ef54bd7ed865846a3c9d624c30bb67ce46", size = 257024, upload-time = "2025-05-23T11:39:15.569Z" }, { url = "https://files.pythonhosted.org/packages/a4/40/afc03f0883b1e51bbe804707aae62e29c4e8c8bbc365c75e3e4ddeee9ead/coverage-7.8.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05364b9cc82f138cc86128dc4e2e1251c2981a2218bfcd556fe6b0fbaa3501be", size = 252867, upload-time = "2025-05-23T11:39:17.64Z" }, { url = "https://files.pythonhosted.org/packages/18/a2/3699190e927b9439c6ded4998941a3c1d6fa99e14cb28d8536729537e307/coverage-7.8.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46d532db4e5ff3979ce47d18e2fe8ecad283eeb7367726da0e5ef88e4fe64740", size = 255096, upload-time = "2025-05-23T11:39:19.328Z" }, { url = "https://files.pythonhosted.org/packages/b4/06/16e3598b9466456b718eb3e789457d1a5b8bfb22e23b6e8bbc307df5daf0/coverage-7.8.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4000a31c34932e7e4fa0381a3d6deb43dc0c8f458e3e7ea6502e6238e10be625", size = 256276, upload-time = "2025-05-23T11:39:21.077Z" }, { url = "https://files.pythonhosted.org/packages/a7/d5/4b5a120d5d0223050a53d2783c049c311eea1709fa9de12d1c358e18b707/coverage-7.8.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:43ff5033d657cd51f83015c3b7a443287250dc14e69910577c3e03bd2e06f27b", size = 254478, upload-time = "2025-05-23T11:39:22.838Z" }, { url = "https://files.pythonhosted.org/packages/ba/85/f9ecdb910ecdb282b121bfcaa32fa8ee8cbd7699f83330ee13ff9bbf1a85/coverage-7.8.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:94316e13f0981cbbba132c1f9f365cac1d26716aaac130866ca812006f662199", size = 255255, upload-time = "2025-05-23T11:39:24.644Z" }, { url = "https://files.pythonhosted.org/packages/50/63/2d624ac7d7ccd4ebbd3c6a9eba9d7fc4491a1226071360d59dd84928ccb2/coverage-7.8.2-cp313-cp313t-win32.whl", hash = "sha256:3f5673888d3676d0a745c3d0e16da338c5eea300cb1f4ada9c872981265e76d8", size = 215109, upload-time = "2025-05-23T11:39:26.722Z" }, { url = "https://files.pythonhosted.org/packages/22/5e/7053b71462e970e869111c1853afd642212568a350eba796deefdfbd0770/coverage-7.8.2-cp313-cp313t-win_amd64.whl", hash = "sha256:2c08b05ee8d7861e45dc5a2cc4195c8c66dca5ac613144eb6ebeaff2d502e73d", size = 216268, upload-time = "2025-05-23T11:39:28.429Z" }, { url = "https://files.pythonhosted.org/packages/07/69/afa41aa34147655543dbe96994f8a246daf94b361ccf5edfd5df62ce066a/coverage-7.8.2-cp313-cp313t-win_arm64.whl", hash = "sha256:1e1448bb72b387755e1ff3ef1268a06617afd94188164960dba8d0245a46004b", size = 214071, upload-time = "2025-05-23T11:39:30.55Z" }, { url = "https://files.pythonhosted.org/packages/69/2f/572b29496d8234e4a7773200dd835a0d32d9e171f2d974f3fe04a9dbc271/coverage-7.8.2-pp39.pp310.pp311-none-any.whl", hash = "sha256:ec455eedf3ba0bbdf8f5a570012617eb305c63cb9f03428d39bf544cb2b94837", size = 203636, upload-time = "2025-05-23T11:39:52.002Z" }, { url = "https://files.pythonhosted.org/packages/a0/1a/0b9c32220ad694d66062f571cc5cedfa9997b64a591e8a500bb63de1bd40/coverage-7.8.2-py3-none-any.whl", hash = "sha256:726f32ee3713f7359696331a18daf0c3b3a70bb0ae71141b9d3c52be7c595e32", size = 203623, upload-time = "2025-05-23T11:39:53.846Z" }, ] [[package]] name = "cryptography" version = "45.0.7" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a7/35/c495bffc2056f2dadb32434f1feedd79abde2a7f8363e1974afa9c33c7e2/cryptography-45.0.7.tar.gz", hash = "sha256:4b1654dfc64ea479c242508eb8c724044f1e964a47d1d1cacc5132292d851971", size = 744980, upload-time = "2025-09-01T11:15:03.146Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/fc/63/43641c5acce3a6105cf8bd5baeceeb1846bb63067d26dae3e5db59f1513a/cryptography-45.0.7-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:67285f8a611b0ebc0857ced2081e30302909f571a46bfa7a3cc0ad303fe015c6", size = 4205799, upload-time = "2025-09-01T11:14:02.517Z" }, { url = "https://files.pythonhosted.org/packages/bc/29/c238dd9107f10bfde09a4d1c52fd38828b1aa353ced11f358b5dd2507d24/cryptography-45.0.7-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:577470e39e60a6cd7780793202e63536026d9b8641de011ed9d8174da9ca5339", size = 4430504, upload-time = "2025-09-01T11:14:04.522Z" }, { url = "https://files.pythonhosted.org/packages/62/62/24203e7cbcc9bd7c94739428cd30680b18ae6b18377ae66075c8e4771b1b/cryptography-45.0.7-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:4bd3e5c4b9682bc112d634f2c6ccc6736ed3635fc3319ac2bb11d768cc5a00d8", size = 4209542, upload-time = "2025-09-01T11:14:06.309Z" }, { url = "https://files.pythonhosted.org/packages/cd/e3/e7de4771a08620eef2389b86cd87a2c50326827dea5528feb70595439ce4/cryptography-45.0.7-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:465ccac9d70115cd4de7186e60cfe989de73f7bb23e8a7aa45af18f7412e75bf", size = 3889244, upload-time = "2025-09-01T11:14:08.152Z" }, { url = "https://files.pythonhosted.org/packages/96/b8/bca71059e79a0bb2f8e4ec61d9c205fbe97876318566cde3b5092529faa9/cryptography-45.0.7-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:16ede8a4f7929b4b7ff3642eba2bf79aa1d71f24ab6ee443935c0d269b6bc513", size = 4461975, upload-time = "2025-09-01T11:14:09.755Z" }, { url = "https://files.pythonhosted.org/packages/58/67/3f5b26937fe1218c40e95ef4ff8d23c8dc05aa950d54200cc7ea5fb58d28/cryptography-45.0.7-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:8978132287a9d3ad6b54fcd1e08548033cc09dc6aacacb6c004c73c3eb5d3ac3", size = 4209082, upload-time = "2025-09-01T11:14:11.229Z" }, { url = "https://files.pythonhosted.org/packages/0e/e4/b3e68a4ac363406a56cf7b741eeb80d05284d8c60ee1a55cdc7587e2a553/cryptography-45.0.7-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:b6a0e535baec27b528cb07a119f321ac024592388c5681a5ced167ae98e9fff3", size = 4460397, upload-time = "2025-09-01T11:14:12.924Z" }, { url = "https://files.pythonhosted.org/packages/22/49/2c93f3cd4e3efc8cb22b02678c1fad691cff9dd71bb889e030d100acbfe0/cryptography-45.0.7-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:a24ee598d10befaec178efdff6054bc4d7e883f615bfbcd08126a0f4931c83a6", size = 4337244, upload-time = "2025-09-01T11:14:14.431Z" }, { url = "https://files.pythonhosted.org/packages/04/19/030f400de0bccccc09aa262706d90f2ec23d56bc4eb4f4e8268d0ddf3fb8/cryptography-45.0.7-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:fa26fa54c0a9384c27fcdc905a2fb7d60ac6e47d14bc2692145f2b3b1e2cfdbd", size = 4568862, upload-time = "2025-09-01T11:14:16.185Z" }, { url = "https://files.pythonhosted.org/packages/bc/4c/8f57f2500d0ccd2675c5d0cc462095adf3faa8c52294ba085c036befb901/cryptography-45.0.7-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:81823935e2f8d476707e85a78a405953a03ef7b7b4f55f93f7c2d9680e5e0691", size = 4202233, upload-time = "2025-09-01T11:14:22.454Z" }, { url = "https://files.pythonhosted.org/packages/eb/ac/59b7790b4ccaed739fc44775ce4645c9b8ce54cbec53edf16c74fd80cb2b/cryptography-45.0.7-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3994c809c17fc570c2af12c9b840d7cea85a9fd3e5c0e0491f4fa3c029216d59", size = 4423075, upload-time = "2025-09-01T11:14:24.287Z" }, { url = "https://files.pythonhosted.org/packages/b8/56/d4f07ea21434bf891faa088a6ac15d6d98093a66e75e30ad08e88aa2b9ba/cryptography-45.0.7-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dad43797959a74103cb59c5dac71409f9c27d34c8a05921341fb64ea8ccb1dd4", size = 4204517, upload-time = "2025-09-01T11:14:25.679Z" }, { url = "https://files.pythonhosted.org/packages/e8/ac/924a723299848b4c741c1059752c7cfe09473b6fd77d2920398fc26bfb53/cryptography-45.0.7-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ce7a453385e4c4693985b4a4a3533e041558851eae061a58a5405363b098fcd3", size = 3882893, upload-time = "2025-09-01T11:14:27.1Z" }, { url = "https://files.pythonhosted.org/packages/83/dc/4dab2ff0a871cc2d81d3ae6d780991c0192b259c35e4d83fe1de18b20c70/cryptography-45.0.7-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b04f85ac3a90c227b6e5890acb0edbaf3140938dbecf07bff618bf3638578cf1", size = 4450132, upload-time = "2025-09-01T11:14:28.58Z" }, { url = "https://files.pythonhosted.org/packages/12/dd/b2882b65db8fc944585d7fb00d67cf84a9cef4e77d9ba8f69082e911d0de/cryptography-45.0.7-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:48c41a44ef8b8c2e80ca4527ee81daa4c527df3ecbc9423c41a420a9559d0e27", size = 4204086, upload-time = "2025-09-01T11:14:30.572Z" }, { url = "https://files.pythonhosted.org/packages/5d/fa/1d5745d878048699b8eb87c984d4ccc5da4f5008dfd3ad7a94040caca23a/cryptography-45.0.7-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:f3df7b3d0f91b88b2106031fd995802a2e9ae13e02c36c1fc075b43f420f3a17", size = 4449383, upload-time = "2025-09-01T11:14:32.046Z" }, { url = "https://files.pythonhosted.org/packages/36/8b/fc61f87931bc030598e1876c45b936867bb72777eac693e905ab89832670/cryptography-45.0.7-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:dd342f085542f6eb894ca00ef70236ea46070c8a13824c6bde0dfdcd36065b9b", size = 4332186, upload-time = "2025-09-01T11:14:33.95Z" }, { url = "https://files.pythonhosted.org/packages/0b/11/09700ddad7443ccb11d674efdbe9a832b4455dc1f16566d9bd3834922ce5/cryptography-45.0.7-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1993a1bb7e4eccfb922b6cd414f072e08ff5816702a0bdb8941c247a6b1b287c", size = 4561639, upload-time = "2025-09-01T11:14:35.343Z" }, { url = "https://files.pythonhosted.org/packages/59/aa/e947693ab08674a2663ed2534cd8d345cf17bf6a1facf99273e8ec8986dc/cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a20e442e917889d1a6b3c570c9e3fa2fdc398c20868abcea268ea33c024c4083", size = 4142233, upload-time = "2025-09-01T11:14:41.305Z" }, { url = "https://files.pythonhosted.org/packages/24/06/09b6f6a2fc43474a32b8fe259038eef1500ee3d3c141599b57ac6c57612c/cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:258e0dff86d1d891169b5af222d362468a9570e2532923088658aa866eb11130", size = 4376202, upload-time = "2025-09-01T11:14:43.047Z" }, { url = "https://files.pythonhosted.org/packages/00/f2/c166af87e95ce6ae6d38471a7e039d3a0549c2d55d74e059680162052824/cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:d97cf502abe2ab9eff8bd5e4aca274da8d06dd3ef08b759a8d6143f4ad65d4b4", size = 4141900, upload-time = "2025-09-01T11:14:45.089Z" }, { url = "https://files.pythonhosted.org/packages/16/b9/e96e0b6cb86eae27ea51fa8a3151535a18e66fe7c451fa90f7f89c85f541/cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:c987dad82e8c65ebc985f5dae5e74a3beda9d0a2a4daf8a1115f3772b59e5141", size = 4375562, upload-time = "2025-09-01T11:14:47.166Z" }, { url = "https://files.pythonhosted.org/packages/16/ce/5f6ff59ea9c7779dba51b84871c19962529bdcc12e1a6ea172664916c550/cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:06ce84dc14df0bf6ea84666f958e6080cdb6fe1231be2a51f3fc1267d9f3fb34", size = 4149533, upload-time = "2025-09-01T11:14:52.091Z" }, { url = "https://files.pythonhosted.org/packages/ce/13/b3cfbd257ac96da4b88b46372e662009b7a16833bfc5da33bb97dd5631ae/cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d0c5c6bac22b177bf8da7435d9d27a6834ee130309749d162b26c3105c0795a9", size = 4385557, upload-time = "2025-09-01T11:14:53.551Z" }, { url = "https://files.pythonhosted.org/packages/1c/c5/8c59d6b7c7b439ba4fc8d0cab868027fd095f215031bc123c3a070962912/cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:2f641b64acc00811da98df63df7d59fd4706c0df449da71cb7ac39a0732b40ae", size = 4149023, upload-time = "2025-09-01T11:14:55.022Z" }, { url = "https://files.pythonhosted.org/packages/55/32/05385c86d6ca9ab0b4d5bb442d2e3d85e727939a11f3e163fc776ce5eb40/cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:f5414a788ecc6ee6bc58560e85ca624258a55ca434884445440a810796ea0e0b", size = 4385722, upload-time = "2025-09-01T11:14:57.319Z" }, ] [[package]] name = "docutils" version = "0.22" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/e9/86/5b41c32ecedcfdb4c77b28b6cb14234f252075f8cdb254531727a35547dd/docutils-0.22.tar.gz", hash = "sha256:ba9d57750e92331ebe7c08a1bbf7a7f8143b86c476acd51528b042216a6aad0f", size = 2277984, upload-time = "2025-07-29T15:20:31.06Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/44/57/8db39bc5f98f042e0153b1de9fb88e1a409a33cda4dd7f723c2ed71e01f6/docutils-0.22-py3-none-any.whl", hash = "sha256:4ed966a0e96a0477d852f7af31bdcb3adc049fbb35ccba358c2ea8a03287615e", size = 630709, upload-time = "2025-07-29T15:20:28.335Z" }, ] [[package]] name = "exceptiongroup" version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/36/f4/c6e662dade71f56cd2f3735141b265c3c79293c109549c1e6933b0651ffc/exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10", size = 16674, upload-time = "2025-05-10T17:42:49.33Z" }, ] [[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 = "griffe" version = "1.14.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ec/d7/6c09dd7ce4c7837e4cdb11dce980cb45ae3cd87677298dc3b781b6bce7d3/griffe-1.14.0.tar.gz", hash = "sha256:9d2a15c1eca966d68e00517de5d69dd1bc5c9f2335ef6c1775362ba5b8651a13", size = 424684, upload-time = "2025-09-05T15:02:29.167Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/2a/b1/9ff6578d789a89812ff21e4e0f80ffae20a65d5dd84e7a17873fe3b365be/griffe-1.14.0-py3-none-any.whl", hash = "sha256:0e9d52832cccf0f7188cfe585ba962d2674b241c01916d780925df34873bceb0", size = 144439, upload-time = "2025-09-05T15:02:27.511Z" }, ] [[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 = "httpcore" version = "1.0.9" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "h11" }, ] sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, ] [[package]] name = "httpx" version = "0.28.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, { name = "certifi" }, { name = "httpcore" }, { name = "idna" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, ] [[package]] name = "id" version = "1.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "requests" }, ] sdist = { url = "https://files.pythonhosted.org/packages/22/11/102da08f88412d875fa2f1a9a469ff7ad4c874b0ca6fed0048fe385bdb3d/id-1.5.0.tar.gz", hash = "sha256:292cb8a49eacbbdbce97244f47a97b4c62540169c976552e497fd57df0734c1d", size = 15237, upload-time = "2024-12-04T19:53:05.575Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/9f/cb/18326d2d89ad3b0dd143da971e77afd1e6ca6674f1b1c3df4b6bec6279fc/id-1.5.0-py3-none-any.whl", hash = "sha256:f1434e1cef91f2cbb8a4ec64663d5a23b9ed43ef44c4c957d02583d61714c658", size = 13611, upload-time = "2024-12-04T19:53:03.02Z" }, ] [[package]] name = "idna" version = "3.10" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, ] [[package]] name = "importlib-metadata" version = "8.7.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "zipp" }, ] sdist = { url = "https://files.pythonhosted.org/packages/76/66/650a33bd90f786193e4de4b3ad86ea60b53c89b669a5c7be931fac31cdb0/importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000", size = 56641, upload-time = "2025-04-27T15:29:01.736Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/20/b0/36bd937216ec521246249be3bf9855081de4c5e06a0c9b4219dbeda50373/importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd", size = 27656, upload-time = "2025-04-27T15:29:00.214Z" }, ] [[package]] name = "iniconfig" version = "2.1.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, ] [[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.0.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "backports-tarfile", marker = "python_full_version < '3.12'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/df/ad/f3777b81bf0b6e7bc7514a1656d3e637b2e8e15fab2ce3235730b3e7a4e6/jaraco_context-6.0.1.tar.gz", hash = "sha256:9bae4ea555cf0b14938dc0aee7c9f32ed303aa20a3b73e7dc80111628792d1b3", size = 13912, upload-time = "2024-08-20T03:39:27.358Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ff/db/0c52c4cf5e4bd9f5d7135ec7669a3a767af21b3a308e1ed3674881e52b62/jaraco.context-6.0.1-py3-none-any.whl", hash = "sha256:f797fc481b490edb305122c9181830a3a5b76d84ef6d1aef2fb9b47ab956f9e4", size = 6825, upload-time = "2024-08-20T03:39:25.966Z" }, ] [[package]] name = "jaraco-functools" version = "4.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "more-itertools" }, ] sdist = { url = "https://files.pythonhosted.org/packages/f7/ed/1aa2d585304ec07262e1a83a9889880701079dde796ac7b1d1826f40c63d/jaraco_functools-4.3.0.tar.gz", hash = "sha256:cfd13ad0dd2c47a3600b439ef72d8615d482cedcff1632930d6f28924d92f294", size = 19755, upload-time = "2025-08-18T20:05:09.91Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b4/09/726f168acad366b11e420df31bf1c702a54d373a83f968d94141a8c3fde0/jaraco_functools-4.3.0-py3-none-any.whl", hash = "sha256:227ff8ed6f7b8f62c56deff101545fa7543cf2c8e7b82a7c2116e672f29c26e8", size = 10408, upload-time = "2025-08-18T20:05:08.69Z" }, ] [[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 = "keyring" version = "25.6.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/70/09/d904a6e96f76ff214be59e7aa6ef7190008f52a0ab6689760a98de0bf37d/keyring-25.6.0.tar.gz", hash = "sha256:0b39998aa941431eb3d9b0d4b2460bc773b9df6fed7621c2dfb291a7e0187a66", size = 62750, upload-time = "2024-12-25T15:26:45.782Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/d3/32/da7f44bcb1105d3e88a0b74ebdca50c59121d2ddf71c9e34ba47df7f3a56/keyring-25.6.0-py3-none-any.whl", hash = "sha256:552a3f7af126ece7ed5c89753650eec89c7eaae8617d0aa4d9ad2b75111266bd", size = 39085, upload-time = "2024-12-25T15:26:44.377Z" }, ] [[package]] name = "markdown" version = "3.9" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/8d/37/02347f6d6d8279247a5837082ebc26fc0d5aaeaf75aa013fcbb433c777ab/markdown-3.9.tar.gz", hash = "sha256:d2900fe1782bd33bdbbd56859defef70c2e78fc46668f8eb9df3128138f2cb6a", size = 364585, upload-time = "2025-09-04T20:25:22.885Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/70/ae/44c4a6a4cbb496d93c6257954260fe3a6e91b7bed2240e5dad2a717f5111/markdown-3.9-py3-none-any.whl", hash = "sha256:9f4d91ed810864ea88a6f32c07ba8bee1346c0cc1f6b1f9f6c822f2a9667d280", size = 107441, upload-time = "2025-09-04T20:25:21.784Z" }, ] [[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.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload-time = "2024-10-18T15:21:54.129Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/04/90/d08277ce111dd22f77149fd1a5d4653eeb3b3eaacbdfcbae5afb2600eebd/MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", size = 14357, upload-time = "2024-10-18T15:20:51.44Z" }, { url = "https://files.pythonhosted.org/packages/04/e1/6e2194baeae0bca1fae6629dc0cbbb968d4d941469cbab11a3872edff374/MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", size = 12393, upload-time = "2024-10-18T15:20:52.426Z" }, { url = "https://files.pythonhosted.org/packages/1d/69/35fa85a8ece0a437493dc61ce0bb6d459dcba482c34197e3efc829aa357f/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", size = 21732, upload-time = "2024-10-18T15:20:53.578Z" }, { url = "https://files.pythonhosted.org/packages/22/35/137da042dfb4720b638d2937c38a9c2df83fe32d20e8c8f3185dbfef05f7/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", size = 20866, upload-time = "2024-10-18T15:20:55.06Z" }, { url = "https://files.pythonhosted.org/packages/29/28/6d029a903727a1b62edb51863232152fd335d602def598dade38996887f0/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", size = 20964, upload-time = "2024-10-18T15:20:55.906Z" }, { url = "https://files.pythonhosted.org/packages/cc/cd/07438f95f83e8bc028279909d9c9bd39e24149b0d60053a97b2bc4f8aa51/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", size = 21977, upload-time = "2024-10-18T15:20:57.189Z" }, { url = "https://files.pythonhosted.org/packages/29/01/84b57395b4cc062f9c4c55ce0df7d3108ca32397299d9df00fedd9117d3d/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", size = 21366, upload-time = "2024-10-18T15:20:58.235Z" }, { url = "https://files.pythonhosted.org/packages/bd/6e/61ebf08d8940553afff20d1fb1ba7294b6f8d279df9fd0c0db911b4bbcfd/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", size = 21091, upload-time = "2024-10-18T15:20:59.235Z" }, { url = "https://files.pythonhosted.org/packages/11/23/ffbf53694e8c94ebd1e7e491de185124277964344733c45481f32ede2499/MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50", size = 15065, upload-time = "2024-10-18T15:21:00.307Z" }, { url = "https://files.pythonhosted.org/packages/44/06/e7175d06dd6e9172d4a69a72592cb3f7a996a9c396eee29082826449bbc3/MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", size = 15514, upload-time = "2024-10-18T15:21:01.122Z" }, { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353, upload-time = "2024-10-18T15:21:02.187Z" }, { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392, upload-time = "2024-10-18T15:21:02.941Z" }, { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984, upload-time = "2024-10-18T15:21:03.953Z" }, { url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120, upload-time = "2024-10-18T15:21:06.495Z" }, { url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032, upload-time = "2024-10-18T15:21:07.295Z" }, { url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057, upload-time = "2024-10-18T15:21:08.073Z" }, { url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359, upload-time = "2024-10-18T15:21:09.318Z" }, { url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306, upload-time = "2024-10-18T15:21:10.185Z" }, { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094, upload-time = "2024-10-18T15:21:11.005Z" }, { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521, upload-time = "2024-10-18T15:21:12.911Z" }, { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274, upload-time = "2024-10-18T15:21:13.777Z" }, { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348, upload-time = "2024-10-18T15:21:14.822Z" }, { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149, upload-time = "2024-10-18T15:21:15.642Z" }, { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118, upload-time = "2024-10-18T15:21:17.133Z" }, { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993, upload-time = "2024-10-18T15:21:18.064Z" }, { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178, upload-time = "2024-10-18T15:21:18.859Z" }, { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319, upload-time = "2024-10-18T15:21:19.671Z" }, { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352, upload-time = "2024-10-18T15:21:20.971Z" }, { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097, upload-time = "2024-10-18T15:21:22.646Z" }, { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601, upload-time = "2024-10-18T15:21:23.499Z" }, { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274, upload-time = "2024-10-18T15:21:24.577Z" }, { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352, upload-time = "2024-10-18T15:21:25.382Z" }, { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122, upload-time = "2024-10-18T15:21:26.199Z" }, { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085, upload-time = "2024-10-18T15:21:27.029Z" }, { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978, upload-time = "2024-10-18T15:21:27.846Z" }, { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208, upload-time = "2024-10-18T15:21:28.744Z" }, { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357, upload-time = "2024-10-18T15:21:29.545Z" }, { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344, upload-time = "2024-10-18T15:21:30.366Z" }, { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101, upload-time = "2024-10-18T15:21:31.207Z" }, { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603, upload-time = "2024-10-18T15:21:32.032Z" }, { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510, upload-time = "2024-10-18T15:21:33.625Z" }, { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486, upload-time = "2024-10-18T15:21:34.611Z" }, { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480, upload-time = "2024-10-18T15:21:35.398Z" }, { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914, upload-time = "2024-10-18T15:21:36.231Z" }, { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796, upload-time = "2024-10-18T15:21:37.073Z" }, { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473, upload-time = "2024-10-18T15:21:37.932Z" }, { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114, upload-time = "2024-10-18T15:21:39.799Z" }, { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098, upload-time = "2024-10-18T15:21:40.813Z" }, { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208, upload-time = "2024-10-18T15:21:41.814Z" }, { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739, upload-time = "2024-10-18T15:21:42.784Z" }, ] [[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 = "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.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown" }, { name = "markupsafe" }, { name = "mkdocs" }, ] sdist = { url = "https://files.pythonhosted.org/packages/51/fa/9124cd63d822e2bcbea1450ae68cdc3faf3655c69b455f3a7ed36ce6c628/mkdocs_autorefs-1.4.3.tar.gz", hash = "sha256:beee715b254455c4aa93b6ef3c67579c399ca092259cc41b7d9342573ff1fc75", size = 55425, upload-time = "2025-08-26T14:23:17.223Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/9f/4d/7123b6fa2278000688ebd338e2a06d16870aaf9eceae6ba047ea05f92df1/mkdocs_autorefs-1.4.3-py3-none-any.whl", hash = "sha256:469d85eb3114801d08e9cc55d102b3ba65917a869b893403b8987b601cf55dc9", size = 25034, upload-time = "2025-08-26T14:23:15.906Z" }, ] [[package]] name = "mkdocs-get-deps" version = "0.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mergedeep" }, { name = "platformdirs" }, { name = "pyyaml" }, ] sdist = { url = "https://files.pythonhosted.org/packages/98/f5/ed29cd50067784976f25ed0ed6fcd3c2ce9eb90650aa3b2796ddf7b6870b/mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c", size = 10239, upload-time = "2023-11-20T17:51:09.981Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134", size = 9521, upload-time = "2023-11-20T17:51:08.587Z" }, ] [[package]] name = "mkdocs-material" version = "9.6.15" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "babel" }, { name = "backrefs" }, { name = "colorama" }, { name = "jinja2" }, { name = "markdown" }, { name = "mkdocs" }, { name = "mkdocs-material-extensions" }, { name = "paginate" }, { name = "pygments" }, { name = "pymdown-extensions" }, { name = "requests" }, ] sdist = { url = "https://files.pythonhosted.org/packages/95/c1/f804ba2db2ddc2183e900befe7dad64339a34fa935034e1ab405289d0a97/mkdocs_material-9.6.15.tar.gz", hash = "sha256:64adf8fa8dba1a17905b6aee1894a5aafd966d4aeb44a11088519b0f5ca4f1b5", size = 3951836, upload-time = "2025-07-01T10:14:15.671Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/1d/30/dda19f0495a9096b64b6b3c07c4bfcff1c76ee0fc521086d53593f18b4c0/mkdocs_material-9.6.15-py3-none-any.whl", hash = "sha256:ac969c94d4fe5eb7c924b6d2f43d7db41159ea91553d18a9afc4780c34f2717a", size = 8716840, upload-time = "2025-07-01T10:14:13.18Z" }, ] [[package]] name = "mkdocs-material-extensions" version = "1.3.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/79/9b/9b4c96d6593b2a541e1cb8b34899a6d021d208bb357042823d4d2cabdbe7/mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443", size = 11847, upload-time = "2023-11-22T19:09:45.208Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31", size = 8728, upload-time = "2023-11-22T19:09:43.465Z" }, ] [[package]] name = "mkdocstrings" version = "0.30.0" 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/e2/0a/7e4776217d4802009c8238c75c5345e23014a4706a8414a62c0498858183/mkdocstrings-0.30.0.tar.gz", hash = "sha256:5d8019b9c31ddacd780b6784ffcdd6f21c408f34c0bd1103b5351d609d5b4444", size = 106597, upload-time = "2025-07-22T23:48:45.998Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/de/b4/3c5eac68f31e124a55d255d318c7445840fa1be55e013f507556d6481913/mkdocstrings-0.30.0-py3-none-any.whl", hash = "sha256:ae9e4a0d8c1789697ac776f2e034e2ddd71054ae1cf2c2bb1433ccfd07c226f2", size = 36579, upload-time = "2025-07-22T23:48:44.152Z" }, ] [[package]] name = "mkdocstrings-python" version = "1.16.12" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "griffe" }, { name = "mkdocs-autorefs" }, { name = "mkdocstrings" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/bf/ed/b886f8c714fd7cccc39b79646b627dbea84cd95c46be43459ef46852caf0/mkdocstrings_python-1.16.12.tar.gz", hash = "sha256:9b9eaa066e0024342d433e332a41095c4e429937024945fea511afe58f63175d", size = 206065, upload-time = "2025-06-03T12:52:49.276Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/3b/dd/a24ee3de56954bfafb6ede7cd63c2413bb842cc48eb45e41c43a05a33074/mkdocstrings_python-1.16.12-py3-none-any.whl", hash = "sha256:22ded3a63b3d823d57457a70ff9860d5a4de9e8b1e482876fc9baabaf6f5f374", size = 124287, upload-time = "2025-06-03T12:52:47.819Z" }, ] [[package]] name = "more-itertools" version = "10.8.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/ea/5d/38b681d3fce7a266dd9ab73c66959406d565b3e85f21d5e66e1181d93721/more_itertools-10.8.0.tar.gz", hash = "sha256:f638ddf8a1a0d134181275fb5d58b086ead7c6a72429ad725c67503f13ba30bd", size = 137431, upload-time = "2025-09-02T15:23:11.018Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/a4/8e/469e5a4a2f5855992e425f3cb33804cc07bf18d48f2db061aec61ce50270/more_itertools-10.8.0-py3-none-any.whl", hash = "sha256:52d4362373dcf7c52546bc4af9a86ee7c4579df9a8dc268be0a2f949d376cc9b", size = 69667, upload-time = "2025-09-02T15:23:09.635Z" }, ] [[package]] name = "mypy" version = "1.16.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mypy-extensions" }, { name = "pathspec" }, { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/81/69/92c7fa98112e4d9eb075a239caa4ef4649ad7d441545ccffbd5e34607cbb/mypy-1.16.1.tar.gz", hash = "sha256:6bd00a0a2094841c5e47e7374bb42b83d64c527a502e3334e1173a0c24437bab", size = 3324747, upload-time = "2025-06-16T16:51:35.145Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/8e/12/2bf23a80fcef5edb75de9a1e295d778e0f46ea89eb8b115818b663eff42b/mypy-1.16.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b4f0fed1022a63c6fec38f28b7fc77fca47fd490445c69d0a66266c59dd0b88a", size = 10958644, upload-time = "2025-06-16T16:51:11.649Z" }, { url = "https://files.pythonhosted.org/packages/08/50/bfe47b3b278eacf348291742fd5e6613bbc4b3434b72ce9361896417cfe5/mypy-1.16.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:86042bbf9f5a05ea000d3203cf87aa9d0ccf9a01f73f71c58979eb9249f46d72", size = 10087033, upload-time = "2025-06-16T16:35:30.089Z" }, { url = "https://files.pythonhosted.org/packages/21/de/40307c12fe25675a0776aaa2cdd2879cf30d99eec91b898de00228dc3ab5/mypy-1.16.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ea7469ee5902c95542bea7ee545f7006508c65c8c54b06dc2c92676ce526f3ea", size = 11875645, upload-time = "2025-06-16T16:35:48.49Z" }, { url = "https://files.pythonhosted.org/packages/a6/d8/85bdb59e4a98b7a31495bd8f1a4445d8ffc86cde4ab1f8c11d247c11aedc/mypy-1.16.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:352025753ef6a83cb9e7f2427319bb7875d1fdda8439d1e23de12ab164179574", size = 12616986, upload-time = "2025-06-16T16:48:39.526Z" }, { url = "https://files.pythonhosted.org/packages/0e/d0/bb25731158fa8f8ee9e068d3e94fcceb4971fedf1424248496292512afe9/mypy-1.16.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ff9fa5b16e4c1364eb89a4d16bcda9987f05d39604e1e6c35378a2987c1aac2d", size = 12878632, upload-time = "2025-06-16T16:36:08.195Z" }, { url = "https://files.pythonhosted.org/packages/2d/11/822a9beb7a2b825c0cb06132ca0a5183f8327a5e23ef89717c9474ba0bc6/mypy-1.16.1-cp310-cp310-win_amd64.whl", hash = "sha256:1256688e284632382f8f3b9e2123df7d279f603c561f099758e66dd6ed4e8bd6", size = 9484391, upload-time = "2025-06-16T16:37:56.151Z" }, { url = "https://files.pythonhosted.org/packages/9a/61/ec1245aa1c325cb7a6c0f8570a2eee3bfc40fa90d19b1267f8e50b5c8645/mypy-1.16.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:472e4e4c100062488ec643f6162dd0d5208e33e2f34544e1fc931372e806c0cc", size = 10890557, upload-time = "2025-06-16T16:37:21.421Z" }, { url = "https://files.pythonhosted.org/packages/6b/bb/6eccc0ba0aa0c7a87df24e73f0ad34170514abd8162eb0c75fd7128171fb/mypy-1.16.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ea16e2a7d2714277e349e24d19a782a663a34ed60864006e8585db08f8ad1782", size = 10012921, upload-time = "2025-06-16T16:51:28.659Z" }, { url = "https://files.pythonhosted.org/packages/5f/80/b337a12e2006715f99f529e732c5f6a8c143bb58c92bb142d5ab380963a5/mypy-1.16.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:08e850ea22adc4d8a4014651575567b0318ede51e8e9fe7a68f25391af699507", size = 11802887, upload-time = "2025-06-16T16:50:53.627Z" }, { url = "https://files.pythonhosted.org/packages/d9/59/f7af072d09793d581a745a25737c7c0a945760036b16aeb620f658a017af/mypy-1.16.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22d76a63a42619bfb90122889b903519149879ddbf2ba4251834727944c8baca", size = 12531658, upload-time = "2025-06-16T16:33:55.002Z" }, { url = "https://files.pythonhosted.org/packages/82/c4/607672f2d6c0254b94a646cfc45ad589dd71b04aa1f3d642b840f7cce06c/mypy-1.16.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2c7ce0662b6b9dc8f4ed86eb7a5d505ee3298c04b40ec13b30e572c0e5ae17c4", size = 12732486, upload-time = "2025-06-16T16:37:03.301Z" }, { url = "https://files.pythonhosted.org/packages/b6/5e/136555ec1d80df877a707cebf9081bd3a9f397dedc1ab9750518d87489ec/mypy-1.16.1-cp311-cp311-win_amd64.whl", hash = "sha256:211287e98e05352a2e1d4e8759c5490925a7c784ddc84207f4714822f8cf99b6", size = 9479482, upload-time = "2025-06-16T16:47:37.48Z" }, { url = "https://files.pythonhosted.org/packages/b4/d6/39482e5fcc724c15bf6280ff5806548c7185e0c090712a3736ed4d07e8b7/mypy-1.16.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:af4792433f09575d9eeca5c63d7d90ca4aeceda9d8355e136f80f8967639183d", size = 11066493, upload-time = "2025-06-16T16:47:01.683Z" }, { url = "https://files.pythonhosted.org/packages/e6/e5/26c347890efc6b757f4d5bb83f4a0cf5958b8cf49c938ac99b8b72b420a6/mypy-1.16.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:66df38405fd8466ce3517eda1f6640611a0b8e70895e2a9462d1d4323c5eb4b9", size = 10081687, upload-time = "2025-06-16T16:48:19.367Z" }, { url = "https://files.pythonhosted.org/packages/44/c7/b5cb264c97b86914487d6a24bd8688c0172e37ec0f43e93b9691cae9468b/mypy-1.16.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44e7acddb3c48bd2713994d098729494117803616e116032af192871aed80b79", size = 11839723, upload-time = "2025-06-16T16:49:20.912Z" }, { url = "https://files.pythonhosted.org/packages/15/f8/491997a9b8a554204f834ed4816bda813aefda31cf873bb099deee3c9a99/mypy-1.16.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0ab5eca37b50188163fa7c1b73c685ac66c4e9bdee4a85c9adac0e91d8895e15", size = 12722980, upload-time = "2025-06-16T16:37:40.929Z" }, { url = "https://files.pythonhosted.org/packages/df/f0/2bd41e174b5fd93bc9de9a28e4fb673113633b8a7f3a607fa4a73595e468/mypy-1.16.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb6229b2c9086247e21a83c309754b9058b438704ad2f6807f0d8227f6ebdd", size = 12903328, upload-time = "2025-06-16T16:34:35.099Z" }, { url = "https://files.pythonhosted.org/packages/61/81/5572108a7bec2c46b8aff7e9b524f371fe6ab5efb534d38d6b37b5490da8/mypy-1.16.1-cp312-cp312-win_amd64.whl", hash = "sha256:1f0435cf920e287ff68af3d10a118a73f212deb2ce087619eb4e648116d1fe9b", size = 9562321, upload-time = "2025-06-16T16:48:58.823Z" }, { url = "https://files.pythonhosted.org/packages/28/e3/96964af4a75a949e67df4b95318fe2b7427ac8189bbc3ef28f92a1c5bc56/mypy-1.16.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ddc91eb318c8751c69ddb200a5937f1232ee8efb4e64e9f4bc475a33719de438", size = 11063480, upload-time = "2025-06-16T16:47:56.205Z" }, { url = "https://files.pythonhosted.org/packages/f5/4d/cd1a42b8e5be278fab7010fb289d9307a63e07153f0ae1510a3d7b703193/mypy-1.16.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:87ff2c13d58bdc4bbe7dc0dedfe622c0f04e2cb2a492269f3b418df2de05c536", size = 10090538, upload-time = "2025-06-16T16:46:43.92Z" }, { url = "https://files.pythonhosted.org/packages/c9/4f/c3c6b4b66374b5f68bab07c8cabd63a049ff69796b844bc759a0ca99bb2a/mypy-1.16.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a7cfb0fe29fe5a9841b7c8ee6dffb52382c45acdf68f032145b75620acfbd6f", size = 11836839, upload-time = "2025-06-16T16:36:28.039Z" }, { url = "https://files.pythonhosted.org/packages/b4/7e/81ca3b074021ad9775e5cb97ebe0089c0f13684b066a750b7dc208438403/mypy-1.16.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:051e1677689c9d9578b9c7f4d206d763f9bbd95723cd1416fad50db49d52f359", size = 12715634, upload-time = "2025-06-16T16:50:34.441Z" }, { url = "https://files.pythonhosted.org/packages/e9/95/bdd40c8be346fa4c70edb4081d727a54d0a05382d84966869738cfa8a497/mypy-1.16.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d5d2309511cc56c021b4b4e462907c2b12f669b2dbeb68300110ec27723971be", size = 12895584, upload-time = "2025-06-16T16:34:54.857Z" }, { url = "https://files.pythonhosted.org/packages/5a/fd/d486a0827a1c597b3b48b1bdef47228a6e9ee8102ab8c28f944cb83b65dc/mypy-1.16.1-cp313-cp313-win_amd64.whl", hash = "sha256:4f58ac32771341e38a853c5d0ec0dfe27e18e27da9cdb8bbc882d2249c71a3ee", size = 9573886, upload-time = "2025-06-16T16:36:43.589Z" }, { url = "https://files.pythonhosted.org/packages/cf/d3/53e684e78e07c1a2bf7105715e5edd09ce951fc3f47cf9ed095ec1b7a037/mypy-1.16.1-py3-none-any.whl", hash = "sha256:5fc2ac4027d0ef28d6ba69a0343737a23c4d1b83672bf38d1fe237bdc0643b37", size = 2265923, upload-time = "2025-06-16T16:48:02.366Z" }, ] [[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.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/c3/a4/96cff0977357f60f06ec4368c4c7a7a26cccfe7c9fcd54f5378bf0428fd3/nh3-0.3.0.tar.gz", hash = "sha256:d8ba24cb31525492ea71b6aac11a4adac91d828aadeff7c4586541bf5dc34d2f", size = 19655, upload-time = "2025-07-17T14:43:37.05Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b4/11/340b7a551916a4b2b68c54799d710f86cf3838a4abaad8e74d35360343bb/nh3-0.3.0-cp313-cp313t-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:a537ece1bf513e5a88d8cff8a872e12fe8d0f42ef71dd15a5e7520fecd191bbb", size = 1427992, upload-time = "2025-07-17T14:43:06.848Z" }, { url = "https://files.pythonhosted.org/packages/ad/7f/7c6b8358cf1222921747844ab0eef81129e9970b952fcb814df417159fb9/nh3-0.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c915060a2c8131bef6a29f78debc29ba40859b6dbe2362ef9e5fd44f11487c2", size = 798194, upload-time = "2025-07-17T14:43:08.263Z" }, { url = "https://files.pythonhosted.org/packages/63/da/c5fd472b700ba37d2df630a9e0d8cc156033551ceb8b4c49cc8a5f606b68/nh3-0.3.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ba0caa8aa184196daa6e574d997a33867d6d10234018012d35f86d46024a2a95", size = 837884, upload-time = "2025-07-17T14:43:09.233Z" }, { url = "https://files.pythonhosted.org/packages/4c/3c/cba7b26ccc0ef150c81646478aa32f9c9535234f54845603c838a1dc955c/nh3-0.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:80fe20171c6da69c7978ecba33b638e951b85fb92059259edd285ff108b82a6d", size = 996365, upload-time = "2025-07-17T14:43:10.243Z" }, { url = "https://files.pythonhosted.org/packages/f3/ba/59e204d90727c25b253856e456ea61265ca810cda8ee802c35f3fadaab00/nh3-0.3.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:e90883f9f85288f423c77b3f5a6f4486375636f25f793165112679a7b6363b35", size = 1071042, upload-time = "2025-07-17T14:43:11.57Z" }, { url = "https://files.pythonhosted.org/packages/10/71/2fb1834c10fab6d9291d62c95192ea2f4c7518bd32ad6c46aab5d095cb87/nh3-0.3.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:0649464ac8eee018644aacbc103874ccbfac80e3035643c3acaab4287e36e7f5", size = 995737, upload-time = "2025-07-17T14:43:12.659Z" }, { url = "https://files.pythonhosted.org/packages/33/c1/8f8ccc2492a000b6156dce68a43253fcff8b4ce70ab4216d08f90a2ac998/nh3-0.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1adeb1062a1c2974bc75b8d1ecb014c5fd4daf2df646bbe2831f7c23659793f9", size = 980552, upload-time = "2025-07-17T14:43:13.763Z" }, { url = "https://files.pythonhosted.org/packages/2f/d6/f1c6e091cbe8700401c736c2bc3980c46dca770a2cf6a3b48a175114058e/nh3-0.3.0-cp313-cp313t-win32.whl", hash = "sha256:7275fdffaab10cc5801bf026e3c089d8de40a997afc9e41b981f7ac48c5aa7d5", size = 593618, upload-time = "2025-07-17T14:43:15.098Z" }, { url = "https://files.pythonhosted.org/packages/23/1e/80a8c517655dd40bb13363fc4d9e66b2f13245763faab1a20f1df67165a7/nh3-0.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:423201bbdf3164a9e09aa01e540adbb94c9962cc177d5b1cbb385f5e1e79216e", size = 598948, upload-time = "2025-07-17T14:43:16.064Z" }, { url = "https://files.pythonhosted.org/packages/9a/e0/af86d2a974c87a4ba7f19bc3b44a8eaa3da480de264138fec82fe17b340b/nh3-0.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:16f8670201f7e8e0e05ed1a590eb84bfa51b01a69dd5caf1d3ea57733de6a52f", size = 580479, upload-time = "2025-07-17T14:43:17.038Z" }, { url = "https://files.pythonhosted.org/packages/0c/e0/cf1543e798ba86d838952e8be4cb8d18e22999be2a24b112a671f1c04fd6/nh3-0.3.0-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:ec6cfdd2e0399cb79ba4dcffb2332b94d9696c52272ff9d48a630c5dca5e325a", size = 1442218, upload-time = "2025-07-17T14:43:18.087Z" }, { url = "https://files.pythonhosted.org/packages/5c/86/a96b1453c107b815f9ab8fac5412407c33cc5c7580a4daf57aabeb41b774/nh3-0.3.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce5e7185599f89b0e391e2f29cc12dc2e206167380cea49b33beda4891be2fe1", size = 823791, upload-time = "2025-07-17T14:43:19.721Z" }, { url = "https://files.pythonhosted.org/packages/97/33/11e7273b663839626f714cb68f6eb49899da5a0d9b6bc47b41fe870259c2/nh3-0.3.0-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:389d93d59b8214d51c400fb5b07866c2a4f79e4e14b071ad66c92184fec3a392", size = 811143, upload-time = "2025-07-17T14:43:20.779Z" }, { url = "https://files.pythonhosted.org/packages/6a/1b/b15bd1ce201a1a610aeb44afd478d55ac018b4475920a3118ffd806e2483/nh3-0.3.0-cp38-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:e9e6a7e4d38f7e8dda9edd1433af5170c597336c1a74b4693c5cb75ab2b30f2a", size = 1064661, upload-time = "2025-07-17T14:43:21.839Z" }, { url = "https://files.pythonhosted.org/packages/8f/14/079670fb2e848c4ba2476c5a7a2d1319826053f4f0368f61fca9bb4227ae/nh3-0.3.0-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7852f038a054e0096dac12b8141191e02e93e0b4608c4b993ec7d4ffafea4e49", size = 997061, upload-time = "2025-07-17T14:43:23.179Z" }, { url = "https://files.pythonhosted.org/packages/a3/e5/ac7fc565f5d8bce7f979d1afd68e8cb415020d62fa6507133281c7d49f91/nh3-0.3.0-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af5aa8127f62bbf03d68f67a956627b1bd0469703a35b3dad28d0c1195e6c7fb", size = 924761, upload-time = "2025-07-17T14:43:24.23Z" }, { url = "https://files.pythonhosted.org/packages/39/2c/6394301428b2017a9d5644af25f487fa557d06bc8a491769accec7524d9a/nh3-0.3.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f416c35efee3e6a6c9ab7716d9e57aa0a49981be915963a82697952cba1353e1", size = 803959, upload-time = "2025-07-17T14:43:26.377Z" }, { url = "https://files.pythonhosted.org/packages/4e/9a/344b9f9c4bd1c2413a397f38ee6a3d5db30f1a507d4976e046226f12b297/nh3-0.3.0-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:37d3003d98dedca6cd762bf88f2e70b67f05100f6b949ffe540e189cc06887f9", size = 844073, upload-time = "2025-07-17T14:43:27.375Z" }, { url = "https://files.pythonhosted.org/packages/66/3f/cd37f76c8ca277b02a84aa20d7bd60fbac85b4e2cbdae77cb759b22de58b/nh3-0.3.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:634e34e6162e0408e14fb61d5e69dbaea32f59e847cfcfa41b66100a6b796f62", size = 1000680, upload-time = "2025-07-17T14:43:28.452Z" }, { url = "https://files.pythonhosted.org/packages/ee/db/7aa11b44bae4e7474feb1201d8dee04fabe5651c7cb51409ebda94a4ed67/nh3-0.3.0-cp38-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:b0612ccf5de8a480cf08f047b08f9d3fecc12e63d2ee91769cb19d7290614c23", size = 1076613, upload-time = "2025-07-17T14:43:30.031Z" }, { url = "https://files.pythonhosted.org/packages/97/03/03f79f7e5178eb1ad5083af84faff471e866801beb980cc72943a4397368/nh3-0.3.0-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:c7a32a7f0d89f7d30cb8f4a84bdbd56d1eb88b78a2434534f62c71dac538c450", size = 1001418, upload-time = "2025-07-17T14:43:31.429Z" }, { url = "https://files.pythonhosted.org/packages/ce/55/1974bcc16884a397ee699cebd3914e1f59be64ab305533347ca2d983756f/nh3-0.3.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3f1b4f8a264a0c86ea01da0d0c390fe295ea0bcacc52c2103aca286f6884f518", size = 986499, upload-time = "2025-07-17T14:43:32.459Z" }, { url = "https://files.pythonhosted.org/packages/c9/50/76936ec021fe1f3270c03278b8af5f2079038116b5d0bfe8538ffe699d69/nh3-0.3.0-cp38-abi3-win32.whl", hash = "sha256:6d68fa277b4a3cf04e5c4b84dd0c6149ff7d56c12b3e3fab304c525b850f613d", size = 599000, upload-time = "2025-07-17T14:43:33.852Z" }, { url = "https://files.pythonhosted.org/packages/8c/ae/324b165d904dc1672eee5f5661c0a68d4bab5b59fbb07afb6d8d19a30b45/nh3-0.3.0-cp38-abi3-win_amd64.whl", hash = "sha256:bae63772408fd63ad836ec569a7c8f444dd32863d0c67f6e0b25ebbd606afa95", size = 604530, upload-time = "2025-07-17T14:43:34.95Z" }, { url = "https://files.pythonhosted.org/packages/5b/76/3165e84e5266d146d967a6cc784ff2fbf6ddd00985a55ec006b72bc39d5d/nh3-0.3.0-cp38-abi3-win_arm64.whl", hash = "sha256:d97d3efd61404af7e5721a0e74d81cdbfc6e5f97e11e731bb6d090e30a7b62b2", size = 585971, upload-time = "2025-07-17T14:43:35.936Z" }, ] [[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 = "25.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, ] [[package]] name = "paginate" version = "0.5.7" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/ec/46/68dde5b6bc00c1296ec6466ab27dddede6aec9af1b99090e1107091b3b84/paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945", size = 19252, upload-time = "2024-08-25T14:17:24.139Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591", size = 13746, upload-time = "2024-08-25T14:17:22.55Z" }, ] [[package]] name = "pathspec" version = "0.12.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, ] [[package]] name = "platformdirs" version = "4.4.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/23/e8/21db9c9987b0e728855bd57bff6984f67952bea55d6f75e055c46b5383e8/platformdirs-4.4.0.tar.gz", hash = "sha256:ca753cf4d81dc309bc67b0ea38fd15dc97bc30ce419a7f58d13eb3bf14c4febf", size = 21634, upload-time = "2025-08-26T14:32:04.268Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/40/4b/2028861e724d3bd36227adfa20d3fd24c3fc6d52032f4a93c133be5d17ce/platformdirs-4.4.0-py3-none-any.whl", hash = "sha256:abd01743f24e5287cd7a5db3752faf1a2d65353f38ec26d98e25a6db65958c85", size = 18654, upload-time = "2025-08-26T14:32:02.735Z" }, ] [[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 = "pycparser" version = "2.22" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736, upload-time = "2024-03-30T13:22:22.564Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552, upload-time = "2024-03-30T13:22:20.476Z" }, ] [[package]] name = "pygments" version = "2.19.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, ] [[package]] name = "pymdown-extensions" version = "10.16.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown" }, { name = "pyyaml" }, ] sdist = { url = "https://files.pythonhosted.org/packages/55/b3/6d2b3f149bc5413b0a29761c2c5832d8ce904a1d7f621e86616d96f505cc/pymdown_extensions-10.16.1.tar.gz", hash = "sha256:aace82bcccba3efc03e25d584e6a22d27a8e17caa3f4dd9f207e49b787aa9a91", size = 853277, upload-time = "2025-07-28T16:19:34.167Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/e4/06/43084e6cbd4b3bc0e80f6be743b2e79fbc6eed8de9ad8c629939fa55d972/pymdown_extensions-10.16.1-py3-none-any.whl", hash = "sha256:d6ba157a6c03146a7fb122b2b9a121300056384eafeec9c9f9e584adfdb2a32d", size = 266178, upload-time = "2025-07-28T16:19:31.401Z" }, ] [[package]] name = "pytest" version = "8.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, { name = "pygments" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload-time = "2025-06-18T05:48:03.955Z" }, ] [[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 = "python-multipart" version = "0.0.20" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f3/87/f44d7c9f274c7ee665a29b885ec97089ec5dc034c7f3fafa03da9e39a09e/python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13", size = 37158, upload-time = "2024-12-16T19:45:46.972Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546, upload-time = "2024-12-16T19:45:44.423Z" }, ] [[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.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/9b/95/a3fac87cb7158e231b5a6012e438c647e1a87f09f8e0d123acec8ab8bf71/PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", size = 184199, upload-time = "2024-08-06T20:31:40.178Z" }, { url = "https://files.pythonhosted.org/packages/c7/7a/68bd47624dab8fd4afbfd3c48e3b79efe09098ae941de5b58abcbadff5cb/PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", size = 171758, upload-time = "2024-08-06T20:31:42.173Z" }, { url = "https://files.pythonhosted.org/packages/49/ee/14c54df452143b9ee9f0f29074d7ca5516a36edb0b4cc40c3f280131656f/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", size = 718463, upload-time = "2024-08-06T20:31:44.263Z" }, { url = "https://files.pythonhosted.org/packages/4d/61/de363a97476e766574650d742205be468921a7b532aa2499fcd886b62530/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", size = 719280, upload-time = "2024-08-06T20:31:50.199Z" }, { url = "https://files.pythonhosted.org/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", size = 751239, upload-time = "2024-08-06T20:31:52.292Z" }, { url = "https://files.pythonhosted.org/packages/b7/33/5504b3a9a4464893c32f118a9cc045190a91637b119a9c881da1cf6b7a72/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", size = 695802, upload-time = "2024-08-06T20:31:53.836Z" }, { url = "https://files.pythonhosted.org/packages/5c/20/8347dcabd41ef3a3cdc4f7b7a2aff3d06598c8779faa189cdbf878b626a4/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", size = 720527, upload-time = "2024-08-06T20:31:55.565Z" }, { url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052, upload-time = "2024-08-06T20:31:56.914Z" }, { url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774, upload-time = "2024-08-06T20:31:58.304Z" }, { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612, upload-time = "2024-08-06T20:32:03.408Z" }, { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040, upload-time = "2024-08-06T20:32:04.926Z" }, { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829, upload-time = "2024-08-06T20:32:06.459Z" }, { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167, upload-time = "2024-08-06T20:32:08.338Z" }, { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952, upload-time = "2024-08-06T20:32:14.124Z" }, { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301, upload-time = "2024-08-06T20:32:16.17Z" }, { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638, upload-time = "2024-08-06T20:32:18.555Z" }, { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850, upload-time = "2024-08-06T20:32:19.889Z" }, { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980, upload-time = "2024-08-06T20:32:21.273Z" }, { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873, upload-time = "2024-08-06T20:32:25.131Z" }, { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302, upload-time = "2024-08-06T20:32:26.511Z" }, { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154, upload-time = "2024-08-06T20:32:28.363Z" }, { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223, upload-time = "2024-08-06T20:32:30.058Z" }, { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542, upload-time = "2024-08-06T20:32:31.881Z" }, { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164, upload-time = "2024-08-06T20:32:37.083Z" }, { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611, upload-time = "2024-08-06T20:32:38.898Z" }, { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591, upload-time = "2024-08-06T20:32:40.241Z" }, { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338, upload-time = "2024-08-06T20:32:41.93Z" }, { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" }, { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" }, { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" }, { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" }, { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" }, { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" }, { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" }, { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" }, { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, ] [[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 = "requests" version = "2.32.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "charset-normalizer" }, { name = "idna" }, { name = "urllib3" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, ] [[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 = "14.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown-it-py" }, { name = "pygments" }, ] sdist = { url = "https://files.pythonhosted.org/packages/fe/75/af448d8e52bf1d8fa6a9d089ca6c07ff4453d86c65c145d0a300bb073b9b/rich-14.1.0.tar.gz", hash = "sha256:e497a48b844b0320d45007cdebfeaeed8db2a4f4bcf49f15e455cfc4af11eaa8", size = 224441, upload-time = "2025-07-25T07:32:58.125Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/e3/30/3c4d035596d3cf444529e0b2953ad0466f6049528a879d27534700580395/rich-14.1.0-py3-none-any.whl", hash = "sha256:536f5f1785986d6dbdea3c75205c473f970777b4a0d6c6dd1b696aa05a3fa04f", size = 243368, upload-time = "2025-07-25T07:32:56.73Z" }, ] [[package]] name = "ruff" version = "0.12.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/97/38/796a101608a90494440856ccfb52b1edae90de0b817e76bfade66b12d320/ruff-0.12.1.tar.gz", hash = "sha256:806bbc17f1104fd57451a98a58df35388ee3ab422e029e8f5cf30aa4af2c138c", size = 4413426, upload-time = "2025-06-26T20:34:14.784Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/06/bf/3dba52c1d12ab5e78d75bd78ad52fb85a6a1f29cc447c2423037b82bed0d/ruff-0.12.1-py3-none-linux_armv6l.whl", hash = "sha256:6013a46d865111e2edb71ad692fbb8262e6c172587a57c0669332a449384a36b", size = 10305649, upload-time = "2025-06-26T20:33:39.242Z" }, { url = "https://files.pythonhosted.org/packages/8c/65/dab1ba90269bc8c81ce1d499a6517e28fe6f87b2119ec449257d0983cceb/ruff-0.12.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b3f75a19e03a4b0757d1412edb7f27cffb0c700365e9d6b60bc1b68d35bc89e0", size = 11120201, upload-time = "2025-06-26T20:33:42.207Z" }, { url = "https://files.pythonhosted.org/packages/3f/3e/2d819ffda01defe857fa2dd4cba4d19109713df4034cc36f06bbf582d62a/ruff-0.12.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:9a256522893cb7e92bb1e1153283927f842dea2e48619c803243dccc8437b8be", size = 10466769, upload-time = "2025-06-26T20:33:44.102Z" }, { url = "https://files.pythonhosted.org/packages/63/37/bde4cf84dbd7821c8de56ec4ccc2816bce8125684f7b9e22fe4ad92364de/ruff-0.12.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:069052605fe74c765a5b4272eb89880e0ff7a31e6c0dbf8767203c1fbd31c7ff", size = 10660902, upload-time = "2025-06-26T20:33:45.98Z" }, { url = "https://files.pythonhosted.org/packages/0e/3a/390782a9ed1358c95e78ccc745eed1a9d657a537e5c4c4812fce06c8d1a0/ruff-0.12.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a684f125a4fec2d5a6501a466be3841113ba6847827be4573fddf8308b83477d", size = 10167002, upload-time = "2025-06-26T20:33:47.81Z" }, { url = "https://files.pythonhosted.org/packages/6d/05/f2d4c965009634830e97ffe733201ec59e4addc5b1c0efa035645baa9e5f/ruff-0.12.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bdecdef753bf1e95797593007569d8e1697a54fca843d78f6862f7dc279e23bd", size = 11751522, upload-time = "2025-06-26T20:33:49.857Z" }, { url = "https://files.pythonhosted.org/packages/35/4e/4bfc519b5fcd462233f82fc20ef8b1e5ecce476c283b355af92c0935d5d9/ruff-0.12.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:70d52a058c0e7b88b602f575d23596e89bd7d8196437a4148381a3f73fcd5010", size = 12520264, upload-time = "2025-06-26T20:33:52.199Z" }, { url = "https://files.pythonhosted.org/packages/85/b2/7756a6925da236b3a31f234b4167397c3e5f91edb861028a631546bad719/ruff-0.12.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84d0a69d1e8d716dfeab22d8d5e7c786b73f2106429a933cee51d7b09f861d4e", size = 12133882, upload-time = "2025-06-26T20:33:54.231Z" }, { url = "https://files.pythonhosted.org/packages/dd/00/40da9c66d4a4d51291e619be6757fa65c91b92456ff4f01101593f3a1170/ruff-0.12.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6cc32e863adcf9e71690248607ccdf25252eeeab5193768e6873b901fd441fed", size = 11608941, upload-time = "2025-06-26T20:33:56.202Z" }, { url = "https://files.pythonhosted.org/packages/91/e7/f898391cc026a77fbe68dfea5940f8213622474cb848eb30215538a2dadf/ruff-0.12.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7fd49a4619f90d5afc65cf42e07b6ae98bb454fd5029d03b306bd9e2273d44cc", size = 11602887, upload-time = "2025-06-26T20:33:58.47Z" }, { url = "https://files.pythonhosted.org/packages/f6/02/0891872fc6aab8678084f4cf8826f85c5d2d24aa9114092139a38123f94b/ruff-0.12.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ed5af6aaaea20710e77698e2055b9ff9b3494891e1b24d26c07055459bb717e9", size = 10521742, upload-time = "2025-06-26T20:34:00.465Z" }, { url = "https://files.pythonhosted.org/packages/2a/98/d6534322c74a7d47b0f33b036b2498ccac99d8d8c40edadb552c038cecf1/ruff-0.12.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:801d626de15e6bf988fbe7ce59b303a914ff9c616d5866f8c79eb5012720ae13", size = 10149909, upload-time = "2025-06-26T20:34:02.603Z" }, { url = "https://files.pythonhosted.org/packages/34/5c/9b7ba8c19a31e2b6bd5e31aa1e65b533208a30512f118805371dbbbdf6a9/ruff-0.12.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:2be9d32a147f98a1972c1e4df9a6956d612ca5f5578536814372113d09a27a6c", size = 11136005, upload-time = "2025-06-26T20:34:04.723Z" }, { url = "https://files.pythonhosted.org/packages/dc/34/9bbefa4d0ff2c000e4e533f591499f6b834346025e11da97f4ded21cb23e/ruff-0.12.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:49b7ce354eed2a322fbaea80168c902de9504e6e174fd501e9447cad0232f9e6", size = 11648579, upload-time = "2025-06-26T20:34:06.766Z" }, { url = "https://files.pythonhosted.org/packages/6f/1c/20cdb593783f8f411839ce749ec9ae9e4298c2b2079b40295c3e6e2089e1/ruff-0.12.1-py3-none-win32.whl", hash = "sha256:d973fa626d4c8267848755bd0414211a456e99e125dcab147f24daa9e991a245", size = 10519495, upload-time = "2025-06-26T20:34:08.718Z" }, { url = "https://files.pythonhosted.org/packages/cf/56/7158bd8d3cf16394928f47c637d39a7d532268cd45220bdb6cd622985760/ruff-0.12.1-py3-none-win_amd64.whl", hash = "sha256:9e1123b1c033f77bd2590e4c1fe7e8ea72ef990a85d2484351d408224d603013", size = 11547485, upload-time = "2025-06-26T20:34:11.008Z" }, { url = "https://files.pythonhosted.org/packages/91/d0/6902c0d017259439d6fd2fd9393cea1cfe30169940118b007d5e0ea7e954/ruff-0.12.1-py3-none-win_arm64.whl", hash = "sha256:78ad09a022c64c13cc6077707f036bab0fac8cd7088772dcd1e5be21c5002efc", size = 10691209, upload-time = "2025-06-26T20:34:12.928Z" }, ] [[package]] name = "secretstorage" version = "3.3.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cryptography" }, { name = "jeepney" }, ] sdist = { url = "https://files.pythonhosted.org/packages/53/a4/f48c9d79cb507ed1373477dbceaba7401fd8a23af63b837fa61f1dcd3691/SecretStorage-3.3.3.tar.gz", hash = "sha256:2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77", size = 19739, upload-time = "2022-08-13T16:22:46.976Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/54/24/b4293291fa1dd830f353d2cb163295742fa87f179fcc8a20a306a81978b7/SecretStorage-3.3.3-py3-none-any.whl", hash = "sha256:f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99", size = 15221, upload-time = "2022-08-13T16:22:44.457Z" }, ] [[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 = "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" source = { editable = "." } dependencies = [ { name = "anyio" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] [package.optional-dependencies] full = [ { name = "httpx" }, { name = "itsdangerous" }, { name = "jinja2" }, { name = "python-multipart" }, { name = "pyyaml" }, ] [package.dev-dependencies] dev = [ { name = "coverage" }, { name = "importlib-metadata" }, { name = "mypy" }, { name = "pytest" }, { name = "ruff" }, { name = "starlette", extra = ["full"] }, { name = "trio" }, { name = "twine" }, { name = "types-pyyaml" }, ] docs = [ { name = "black" }, { name = "mkdocs" }, { name = "mkdocs-material" }, { name = "mkdocstrings-python" }, ] [package.metadata] requires-dist = [ { name = "anyio", specifier = ">=3.6.2,<5" }, { name = "httpx", marker = "extra == 'full'", specifier = ">=0.27.0,<0.29.0" }, { name = "itsdangerous", marker = "extra == 'full'" }, { name = "jinja2", marker = "extra == 'full'" }, { name = "python-multipart", marker = "extra == 'full'", specifier = ">=0.0.18" }, { name = "pyyaml", marker = "extra == 'full'" }, { name = "typing-extensions", marker = "python_full_version < '3.13'", specifier = ">=4.10.0" }, ] provides-extras = ["full"] [package.metadata.requires-dev] dev = [ { name = "coverage", specifier = "==7.8.2" }, { name = "importlib-metadata", specifier = "==8.7.0" }, { name = "mypy", specifier = "==1.16.1" }, { name = "pytest", specifier = "==8.4.1" }, { name = "ruff", specifier = "==0.12.1" }, { name = "starlette", extras = ["full"] }, { name = "trio", specifier = "==0.30.0" }, { name = "twine", specifier = "==6.1.0" }, { name = "types-pyyaml", specifier = "==6.0.12.20250516" }, ] docs = [ { name = "black", specifier = "==25.1.0" }, { name = "mkdocs", specifier = "==1.6.1" }, { name = "mkdocs-material", specifier = "==9.6.15" }, { name = "mkdocstrings-python", specifier = "==1.16.12" }, ] [[package]] name = "tomli" version = "2.2.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175, upload-time = "2024-11-27T22:38:36.873Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077, upload-time = "2024-11-27T22:37:54.956Z" }, { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429, upload-time = "2024-11-27T22:37:56.698Z" }, { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067, upload-time = "2024-11-27T22:37:57.63Z" }, { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030, upload-time = "2024-11-27T22:37:59.344Z" }, { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898, upload-time = "2024-11-27T22:38:00.429Z" }, { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894, upload-time = "2024-11-27T22:38:02.094Z" }, { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319, upload-time = "2024-11-27T22:38:03.206Z" }, { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273, upload-time = "2024-11-27T22:38:04.217Z" }, { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310, upload-time = "2024-11-27T22:38:05.908Z" }, { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309, upload-time = "2024-11-27T22:38:06.812Z" }, { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762, upload-time = "2024-11-27T22:38:07.731Z" }, { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453, upload-time = "2024-11-27T22:38:09.384Z" }, { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486, upload-time = "2024-11-27T22:38:10.329Z" }, { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349, upload-time = "2024-11-27T22:38:11.443Z" }, { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159, upload-time = "2024-11-27T22:38:13.099Z" }, { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243, upload-time = "2024-11-27T22:38:14.766Z" }, { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645, upload-time = "2024-11-27T22:38:15.843Z" }, { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584, upload-time = "2024-11-27T22:38:17.645Z" }, { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875, upload-time = "2024-11-27T22:38:19.159Z" }, { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418, upload-time = "2024-11-27T22:38:20.064Z" }, { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708, upload-time = "2024-11-27T22:38:21.659Z" }, { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582, upload-time = "2024-11-27T22:38:22.693Z" }, { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543, upload-time = "2024-11-27T22:38:24.367Z" }, { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691, upload-time = "2024-11-27T22:38:26.081Z" }, { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170, upload-time = "2024-11-27T22:38:27.921Z" }, { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530, upload-time = "2024-11-27T22:38:29.591Z" }, { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666, upload-time = "2024-11-27T22:38:30.639Z" }, { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954, upload-time = "2024-11-27T22:38:31.702Z" }, { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724, upload-time = "2024-11-27T22:38:32.837Z" }, { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383, upload-time = "2024-11-27T22:38:34.455Z" }, { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257, upload-time = "2024-11-27T22:38:35.385Z" }, ] [[package]] name = "trio" version = "0.30.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "attrs" }, { name = "cffi", marker = "implementation_name != 'pypy' and os_name == 'nt'" }, { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, { name = "idna" }, { name = "outcome" }, { name = "sniffio" }, { name = "sortedcontainers" }, ] sdist = { url = "https://files.pythonhosted.org/packages/01/c1/68d582b4d3a1c1f8118e18042464bb12a7c1b75d64d75111b297687041e3/trio-0.30.0.tar.gz", hash = "sha256:0781c857c0c81f8f51e0089929a26b5bb63d57f927728a5586f7e36171f064df", size = 593776, upload-time = "2025-04-21T00:48:19.507Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/69/8e/3f6dfda475ecd940e786defe6df6c500734e686c9cd0a0f8ef6821e9b2f2/trio-0.30.0-py3-none-any.whl", hash = "sha256:3bf4f06b8decf8d3cf00af85f40a89824669e2d033bb32469d34840edcfc22a5", size = 499194, upload-time = "2025-04-21T00:48:17.167Z" }, ] [[package]] name = "twine" version = "6.1.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/c8/a2/6df94fc5c8e2170d21d7134a565c3a8fb84f9797c1dd65a5976aaf714418/twine-6.1.0.tar.gz", hash = "sha256:be324f6272eff91d07ee93f251edf232fc647935dd585ac003539b42404a8dbd", size = 168404, upload-time = "2025-01-21T18:45:26.758Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/7c/b6/74e927715a285743351233f33ea3c684528a0d374d2e43ff9ce9585b73fe/twine-6.1.0-py3-none-any.whl", hash = "sha256:a47f973caf122930bf0fbbf17f80b83bc1602c9ce393c7845f289a3001dc5384", size = 40791, upload-time = "2025-01-21T18:45:24.584Z" }, ] [[package]] name = "types-pyyaml" version = "6.0.12.20250516" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/4e/22/59e2aeb48ceeee1f7cd4537db9568df80d62bdb44a7f9e743502ea8aab9c/types_pyyaml-6.0.12.20250516.tar.gz", hash = "sha256:9f21a70216fc0fa1b216a8176db5f9e0af6eb35d2f2932acb87689d03a5bf6ba", size = 17378, upload-time = "2025-05-16T03:08:04.897Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/99/5f/e0af6f7f6a260d9af67e1db4f54d732abad514252a7a378a6c4d17dd1036/types_pyyaml-6.0.12.20250516-py3-none-any.whl", hash = "sha256:8478208feaeb53a34cb5d970c56a7cd76b72659442e733e268a94dc72b2d0530", size = 20312, upload-time = "2025-05-16T03:08:04.019Z" }, ] [[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.5.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, ] [[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/0c/56/90994d789c61df619bfc5ce2ecdabd5eeff564e1eb47512bd01b5e019569/watchdog-6.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1cdb490583ebd691c012b3d6dae011000fe42edb7a82ece80965b42abd61f26", size = 96390, upload-time = "2024-11-01T14:06:24.793Z" }, { url = "https://files.pythonhosted.org/packages/55/46/9a67ee697342ddf3c6daa97e3a587a56d6c4052f881ed926a849fcf7371c/watchdog-6.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc64ab3bdb6a04d69d4023b29422170b74681784ffb9463ed4870cf2f3e66112", size = 88389, upload-time = "2024-11-01T14:06:27.112Z" }, { url = "https://files.pythonhosted.org/packages/44/65/91b0985747c52064d8701e1075eb96f8c40a79df889e59a399453adfb882/watchdog-6.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c897ac1b55c5a1461e16dae288d22bb2e412ba9807df8397a635d88f671d36c3", size = 89020, upload-time = "2024-11-01T14:06:29.876Z" }, { 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/30/ad/d17b5d42e28a8b91f8ed01cb949da092827afb9995d4559fd448d0472763/watchdog-6.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881", size = 87902, upload-time = "2024-11-01T14:06:53.119Z" }, { url = "https://files.pythonhosted.org/packages/5c/ca/c3649991d140ff6ab67bfc85ab42b165ead119c9e12211e08089d763ece5/watchdog-6.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11", size = 88380, upload-time = "2024-11-01T14:06:55.19Z" }, { 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 = "zipp" version = "3.23.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/e3/02/0f2892c661036d50ede074e376733dca2ae7c6eb617489437771209d4180/zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166", size = 25547, upload-time = "2025-06-08T17:06:39.4Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e", size = 10276, upload-time = "2025-06-08T17:06:38.034Z" }, ]

    Build Status Package version Supported Python versions Discord