pax_global_header00006660000000000000000000000064151346376430014526gustar00rootroot0000000000000052 comment=634d16686b7707bca8ed3534051982791b9ef355 vutran1710-PyrateLimiter-634d166/000077500000000000000000000000001513463764300164255ustar00rootroot00000000000000vutran1710-PyrateLimiter-634d166/.coveragerc000066400000000000000000000001311513463764300205410ustar00rootroot00000000000000[run] concurrency = multiprocessing parallel = True branch = True source = pyrate_limitervutran1710-PyrateLimiter-634d166/.github/000077500000000000000000000000001513463764300177655ustar00rootroot00000000000000vutran1710-PyrateLimiter-634d166/.github/workflows/000077500000000000000000000000001513463764300220225ustar00rootroot00000000000000vutran1710-PyrateLimiter-634d166/.github/workflows/build_test.yml000066400000000000000000000107031513463764300247040ustar00rootroot00000000000000name: Python package - UV on: push: branches: - master tags: - "v*" pull_request: branches: - master concurrency: # cancels superseded runs group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true env: LATEST_PY_VERSION: "3.14" REDIS: "redis://localhost:6379" jobs: smoke: runs-on: ubuntu-latest steps: - name: Check out code uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Python ${{ env.LATEST_PY_VERSION }} uses: actions/setup-python@v5 with: python-version: ${{ env.LATEST_PY_VERSION }} allow-prereleases: true - name: Install uv uses: astral-sh/setup-uv@v6 with: enable-cache: true python-version: ${{ env.LATEST_PY_VERSION }} - name: Lint run: | uv run nox -e lint - run: uv sync --all-groups - run: uv run nox -e smoke check-others: needs: smoke runs-on: ${{ matrix.os }} strategy: fail-fast: true matrix: include: - os: macos-latest python-version: "3.14" #- os: windows-latest # python-version: '3.14' - os: ubuntu-latest python-version: "pypy3.11" steps: - name: Check out code uses: actions/checkout@v4 with: fetch-depth: 0 fetch-tags: true - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} allow-prereleases: true - name: Install uv uses: astral-sh/setup-uv@v6 with: enable-cache: true python-version: ${{ matrix.python-version }} - name: Install dependencies run: uv sync --all-groups - name: Test and Coverage run: | uv run nox -e notlinux check-linux: needs: smoke runs-on: ${{ matrix.os }} strategy: fail-fast: true matrix: python-version: ["3.10", "3.14", "3.14t"] os: [ubuntu-latest] services: pyrate_redis: image: redis:7 ports: - 6379:6379 # Set health checks to wait until redis has started options: >- --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5 pyrate_postgres: image: postgres:18 env: POSTGRES_PASSWORD: postgres ports: - 5432:5432 options: >- --health-cmd "pg_isready -U postgres" --health-interval 10s --health-timeout 5s --health-retries 5 steps: - name: Check out code uses: actions/checkout@v4 with: fetch-depth: 0 fetch-tags: true - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install uv uses: astral-sh/setup-uv@v6 with: enable-cache: true python-version: ${{ matrix.python-version }} - name: Install dependencies run: uv sync --all-groups # Run linting (latest python version only) - name: Build and install package if: ${{ matrix.python-version == env.LATEST_PY_VERSION && matrix.os == 'ubuntu-latest' }} run: | uv build uv pip install dist/*.whl # Run tests and coverage report (all python versions) - name: Test and Coverage run: | uv run nox -e cover # Latest python version: send coverage report to codecov - name: "Upload coverage report to Codecov" if: ${{ matrix.python-version == env.LATEST_PY_VERSION && matrix.os == 'ubuntu-latest' }} uses: codecov/codecov-action@v2 - name: Upload dist, if this is latest if: ${{ matrix.python-version == env.LATEST_PY_VERSION && matrix.os == 'ubuntu-latest' }} uses: actions/upload-artifact@v4 with: name: dist path: dist publish: needs: [check-linux, check-others] runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/v') permissions: contents: read id-token: write steps: - name: Download dist uses: actions/download-artifact@v4 with: name: dist path: dist - name: Upload package to PyPI uses: pypa/gh-action-pypi-publish@release/v1 vutran1710-PyrateLimiter-634d166/.gitignore000066400000000000000000000003361513463764300204170ustar00rootroot00000000000000.coverage .coverage.* pyrate_limiter.egg-info/ __pycache__/ dist/ docs/_build/ docs/modules/ htmlcov/ env/ test-reports/ .vim/ .vscode/ .idea/ .coveralls.yml .DS_Store .venv xdg_cache *\.sqlite* _build_html coverage.xml vutran1710-PyrateLimiter-634d166/.pre-commit-config.yaml000066400000000000000000000010231513463764300227020ustar00rootroot00000000000000repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: - id: check-yaml - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.12.9 hooks: - id: ruff-check types_or: [ python, pyi, jupyter ] args: [ --fix ] - id: ruff-format types_or: [ python, pyi, jupyter ] - repo: https://github.com/pre-commit/mirrors-mypy rev: v1.17.1 hooks: - id: mypy additional_dependencies: [types-filelock, types-requests, types-redis] vutran1710-PyrateLimiter-634d166/.python-version000066400000000000000000000000041513463764300214240ustar00rootroot000000000000003.10vutran1710-PyrateLimiter-634d166/.readthedocs.yml000066400000000000000000000006131513463764300215130ustar00rootroot00000000000000# Read the Docs configuration file version: 2 build: os: "ubuntu-24.04" tools: python: "3.12" commands: - pip install uv - uv sync --all-groups --all-extras - uv run python -m sphinx docs $READTHEDOCS_OUTPUT/html -b html -W sphinx: builder: html configuration: docs/conf.py python: install: - method: pip path: . extra_requirements: - docs vutran1710-PyrateLimiter-634d166/CHANGELOG.md000066400000000000000000000172511513463764300202440ustar00rootroot00000000000000# Change Log All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [4.0.0] Fourth major release with significant API simplification and breaking changes. ### Breaking Changes #### Exceptions Removed - `BucketFullException` and `LimiterDelayException` have been removed - Rate limiting now uses blocking behavior instead of exception-based flow control #### Limiter Constructor Simplified - Removed `clock` parameter - each bucket now manages its own clock via `bucket.now()` - Removed `raise_when_fail` parameter - no exceptions are raised - Removed `max_delay` parameter - blocking is now controlled per-call - Removed `retry_until_max_delay` parameter - Added `buffer_ms` parameter (default 50ms) for clock drift tolerance #### Clock Changes - `TimeClock` removed - use `MonotonicClock` instead - `SQLiteClock` removed - buckets now manage their own time - `TimeAsyncClock` renamed to `MonotonicAsyncClock` - Clock is no longer passed to Limiter; buckets have built-in `now()` method #### try_acquire API Changes - New signature: `try_acquire(name="pyrate", weight=1, blocking=True, timeout=-1)` - `blocking=True` (default): blocks until permit is acquired - `blocking=False`: returns `False` immediately if bucket is full - Added `try_acquire_async()` for proper async acquisition with asyncio.Lock #### Decorator API Changes - Old: `limiter.as_decorator()(mapping_func)(target_func)` where mapping returns `(name, weight)` - New: `limiter.as_decorator(name="...", weight=...)(target_func)` with direct parameters #### BucketFactory Changes - `schedule_leak(bucket, clock)` now `schedule_leak(bucket)` - no clock parameter - `create(clock, bucket_class, ...)` now `create(bucket_class, ...)` - no clock parameter ### New Features - Context manager support: `with Limiter(...) as limiter:` and `with bucket:` - `limiter.close()` method for resource cleanup - `limiter_factory` module with convenience functions: - `create_sqlite_limiter()` - `create_inmemory_limiter()` - `init_global_limiter()` - `MultiprocessBucket` for multiprocessing environments - Web request helpers in `pyrate_limiter.extras`: - `aiohttp_limiter.RateLimitedSession` - `httpx_limiter.RateLimiterTransport` / `AsyncRateLimiterTransport` - `requests_limiter.RateLimitedRequestsSession` - Time is now monotonic by default (`monotonic_ns()`) - `buffer_ms` configurable per-Limiter (default 50ms) ### Improvements - Migrated from Poetry to UV for builds - Switched from Bitnami to official Redis/Postgres Docker images - Pre-commit switched to Ruff - Improved multiprocessing support with proper locking - Better asyncio support with thread-local async locks ## [3.9.0] * Introduce MultiprocessBucket * Update documentation to include MultiprocessBucket * Add delay configure * Simplify lock interface for SQLFileLock & MultiprocessBucket ## [3.8.1] * Keep Retrying until Max Delay Has Expired * Postgres performance turning * Fix cursor leaks on SQLiteBucket ## [3.8.0] * Add FileLock option for SQLiteBucket ## [3.7.1] * Update package metadata and local dev config to support python 3.13 ## [3.7.0] * Add method to remove bucket ## [3.6.2] * Fix table creation for SQLiteBucket ## [3.6.1] * Support creating/getting bucket asynchronously ## [3.6.0] * Use psycopg3 for PostgresBucket ## [3.5.1] * Fix dependencies for "all" package extra ## [3.5.0] * Add PostgresBucket backend ## [3.4.1] * Fix: unnecessary warning during async check ## [3.4.0] * Improved in-memory-bucket performance ## [3.3.0] * Fix background task for leaking ## [3.2.1] - 2024-02-13 * Fix Redis CROSSSLOT Keys following issue [#126](https://github.com/vutran1710/PyrateLimiter/issues/126) ## [3.1.1] - 2024-01-02 * Fix broken SqliteBucket following issue [#132](https://github.com/vutran1710/PyrateLimiter/issues/132) ## [3.1.0] - 2023-08-28 * Allow to pass rates directly to Limiter to use default ImMemoryBucket with Limiter * Allow to pass *Duration* to `max_delay` argument of Limiter ## [3.0.2] - 2023-08-28 * Critical bug fix: importing redis fail crashing apps ## [3.0.0] - 2023-08-28 Third major release with API breaking changes: - Drop python 3.7 (only python ^3.8) - Bucket must be initialized before passing to Limiter - Auto leaking (provided by BucketFactory) - Decorator API changes - Limiter workable with both async/sync out-of-the-box - Async RedisBucket built-in - Contextmanager not available yet ## [2.10.0] - 2023-02-26 ### Updates * Add change log to sdist * Improve test coverage * Force check some bucket-keyword arguments ## [2.9.1] - 2023-02-26 ### Fixed * Fix unit test to make test results stable * Fix remaining-time calculation using exact 3 decimals only * Increase test intesity to ensure correctness ## [2.8.5] - TBD ### Fixed * Fix SQLite OperationalError when getting more items than SQLite variable limit ## [2.8.4] - 2022-11-23 ### Fixed * Build both `wheel` and `sdist` on publish ## [2.8.3] - 2022-10-17 ### Added * Add option to expire redis key when using RedisBucket ## [2.8.2] - 2022-09-24 ### Removed * Python 3.6 support ## [2.8.1] - 2022-04-11 ### Added * Add Sphinx config * Add documentation site: https://pyrate-limiter.readthedocs.io * Add some missing type hints * Add package metadata to indicate PEP-561 compliance ## [2.8.0] - 2022-04-10 ### Added * Add `flush()` method to all bucket classes ## [2.7.0] - 2022-04-06 ### Added * Add `FileLockSQliteBucket` for a SQLite backend with file-based locking * Add optional backend dependencies to package metadata ## [2.6.3] - 2022-04-05 ### Fixed * Make SQLite bucket thread-safe and multiprocess-safe ## [2.6.2] - 2022-03-30 ### Fixed * Remove development scripts from package published on PyPI ### Added * Add `nox` to run development scripts ## [2.6.1] - 2022-03-30 ### Updated * Replace all formatting/linting tools with *pre-commit* ## [2.6.0] - 2021-12-08 ### Added * Add `SQliteBucket` to persist rate limit data in a SQLite database ## [2.5.0] - 2021-12-08 ### Added * Custom time source ## [2.4.6] - 2021-09-30 * Add `RedisClusterBucket` to support using `PyrateLimiter` with `redis-py-cluster` * Update README, add Table of Content ## [2.3.6] - 2021-09-23 * Run CI tests for all supported python versions * Fix issue with deployments on Travis CI ## [2.3.5] - 2021-09-22 ### Added * Use `time.monotonic()` instead of `time.time()` * Support for floating point rate-limiting delays (more granular than 1 second) ## [2.3.4] - 2021-06-01 ### Fixed * Bucket group initialization ## [2.3.3] - 2021-05-08 ### Added * Support for python 3.6 ## [2.3.2] - 2021-05-06 ### Fixed * Incorrect type hint ## [2.3.1] - 2021-04-26 ### Added * LICENSE file to be included in PyPI package ### Fixed * Incorrect delay time when using using `Limiter.ratelimit()` with `delay=True` ## [2.3.0] - 2021-03-01 ### Added * Support for using `Limiter.ratelimit()` as a contextmanager or async contextmanager * Separate `LimitContextDecorator` class to handle `Limiter.ratelimit()` behavior * Package published on conda-forge ## [2.2.2] - 2021-03-03 ### Changed * Internal: Reduce cognitive complexity ## [2.2.1] - 2021-03-02 ### Fixed * Incorrect check log against time-window ## [2.2.0] - 2021-02-26 ### Added * `Limiter.ratelimit()` method, an async-compatible decorator that optionally adds rate-limiting delays ## [2.1.0] - 2021-02-21 ## [2.0.3] - 2020-06-01 ## [2.0.2] - 2020-06-01 ## [2.0.1] - 2020-06-01 ## [2.0.0] - 2019-12-29 ## [1.1.0] - 2019-12-17 ### Removed - Code duplication ### Added - Thread lock for Bucket's state modification in case of Multi-threading - Html Cover Report ### Fixed - LocalBucket's default init value being mutated - Typos. A lot of friggin' typos. vutran1710-PyrateLimiter-634d166/CONTRIBUTING.md000066400000000000000000000033741513463764300206650ustar00rootroot00000000000000# Contributing Guide Here are some basic instructions for local development setup and contributing to the project. ## Setup & Commands To setup local development, *uv* and *Python 3.9+* are required. Follow instructions at for installing uv. Then, in the repository directory, run the following to install all optional backend dependencies and dev dependencies: ```shell $ uv sync --all-groups --all-extras ``` Some shortcuts are included for some common development tasks, using [nox](https://nox.thea.codes): - Run tests with: `nox -e test` - To run tests with coverage: `nox -e cover` - Format & check for lint error: `nox -e lint` - To run linting for every commit, run: `pre-commit install` ## Documentation Documentation is generated using [Sphinx](https://www.sphinx-doc.org) and published on readthedocs.io. To build this documentation locally: ``` nox -e docs ``` ## Guideline & Notes We have GitHub Action CICD to do the checking, testing and publishing work. So, there are few small notes when making Pull Request: - All existing tests must pass (Of course!) - Reduction in *Coverage* shall result in failure. (below 98% is not accepted) - When you are making bug fixes, or adding more features, remember to bump the version number in **pyproject.toml**. The number should follow *semantic-versioning* rules ## TODO Planned features: * A rate limit may reset on a fixed schedule, eg: every first-day of a month * Sometimes, we may need to apply specific rate-limiting strategies based on schedules/region or some other metrics. It requires the capability to switch the strategies instantly without re-deploying the whole service. * Reference: https://www.keycdn.com/support/rate-limiting#types-of-rate-limits vutran1710-PyrateLimiter-634d166/LICENSE000066400000000000000000000020531513463764300174320ustar00rootroot00000000000000MIT License Copyright (c) 2021 vutran1710 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. vutran1710-PyrateLimiter-634d166/README.md000066400000000000000000000661241513463764300177150ustar00rootroot00000000000000 # PyrateLimiter The request rate limiter using Leaky-bucket Algorithm. Full project documentation can be found at [pyratelimiter.readthedocs.io](https://pyratelimiter.readthedocs.io). [![PyPI version](https://badge.fury.io/py/pyrate-limiter.svg)](https://badge.fury.io/py/pyrate-limiter) [![PyPI - Python Versions](https://img.shields.io/pypi/pyversions/pyrate-limiter)](https://pypi.org/project/pyrate-limiter) [![codecov](https://codecov.io/gh/vutran1710/PyrateLimiter/branch/master/graph/badge.svg?token=E0Q0YBSINS)](https://codecov.io/gh/vutran1710/PyrateLimiter) [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://github.com/vutran1710/PyrateLimiter/graphs/commit-activity) [![PyPI license](https://img.shields.io/pypi/l/ansicolortags.svg)](https://pypi.python.org/pypi/pyrate-limiter/) > **Upgrading from v3.x?** See the [Migration Guide](docs/migrating.md) for breaking changes.
## Contents - [Features](#features) - [Installation](#installation) - [Web Requests](#web-request-rate-limiting) - [AIOHTTP](#aiohttp) - [HTTPX](#httpx) - [Requests](#requests) - [Quickstart](#quickstart) - [limiter_factory](#limiter_factory) - [Examples](#examples) - [Basic usage](#basic-usage) - [Key concepts](#key-concepts) - [Defining rate limits & buckets](#defining-rate-limits-and-buckets) - [Defining clock & routing logic](#defining-clock--routing-logic-with-bucketfactory) - [Wrapping all up with Limiter](#wrapping-all-up-with-limiter) - [asyncio and event loops](#asyncio-and-event-loops) - [`as_decorator()`: use limiter as decorator](#as_decorator-use-limiter-as-decorator) - [Limiter API](#limiter-api) - [Context Manager](#context-manager) - [Weight](#weight) - [Handling exceeded limits](#handling-exceeded-limits) - [Bucket analogy](#bucket-analogy) - [Blocking vs Non-blocking](#blocking-vs-non-blocking) - [Backends](#backends) - [InMemoryBucket](#inmemorybucket) - [MultiprocessBucket](#multiprocessbucket) - [SQLiteBucket](#sqlitebucket) - [RedisBucket](#redisbucket) - [PostgresBucket](#postgresbucket) - [BucketAsyncWrapper](#bucketasyncwrapper) - [Async or Sync or Multiprocessing](#async-or-sync-or-multiprocessing) - [Advanced Usage](#advanced-usage) - [Component-level Diagram](#component-level-diagram) - [Time sources](#time-sources) - [Leaking](#leaking) - [Concurrency](#concurrency) - [Custom backend](#custom-backend) ## Features - Supports unlimited rate limits and custom intervals. - Separately tracks limits for different services or resources. - Manages limit breaches with configurable blocking or non-blocking behavior. - Offers multiple usage modes: direct calls or decorators. - Fully compatible with both synchronous and asynchronous workflows. - Provides SQLite and Redis backends for persistent limit tracking across threads or restarts. - Includes MultiprocessBucket and SQLite File Lock backends for multiprocessing environments. ## Installation **PyrateLimiter** supports **python ^3.8** Install using pip: ``` pip install pyrate-limiter ``` Or using conda: ``` conda install --channel conda-forge pyrate-limiter ``` ## Quickstart To limit 5 requests within 2 seconds: ```python from pyrate_limiter import Duration, Rate, Limiter limiter = Limiter(Rate(5, Duration.SECOND * 2)) # Blocking mode (default) - waits until permit available for i in range(6): limiter.try_acquire(str(i)) print(f"Acquired permit {i}") # Non-blocking mode - returns False if bucket full for i in range(6): success = limiter.try_acquire(str(i), blocking=False) if not success: print(f"Rate limited at {i}") ``` ## limiter_factory [limiter_factory.py](https://github.com/vutran1710/PyrateLimiter/blob/master/pyrate_limiter/limiter_factory.py) provides several functions to simplify common cases: - create_sqlite_limiter(rate_per_duration: int, duration: Duration, ...) - create_inmemory_limiter(rate_per_duration: int, duration: Duration, ...) - + more to be added... ## Examples - Rate limiting asyncio tasks: [asyncio_ratelimit.py](https://github.com/vutran1710/PyrateLimiter/blob/master/examples/asyncio_ratelimit.py) - Rate limiting asyncio tasks w/ a decorator: [asyncio_decorator.py](https://github.com/vutran1710/PyrateLimiter/blob/master/examples/asyncio_decorator.py) - HTTPX rate limiting - asyncio, single process and multiprocess examples [httpx_ratelimiter.py](https://github.com/vutran1710/PyrateLimiter/blob/master/examples/httpx_ratelimiter.py) - Multiprocessing using an in-memory rate limiter - [in_memory_multiprocess.py](https://github.com/vutran1710/PyrateLimiter/blob/master/examples/in_memory_multiprocess.py) - Multiprocessing using SQLite and a file lock - this can be used for distributed processes not created within a multiprocessing [sql_filelock_multiprocess.py](https://github.com/vutran1710/PyrateLimiter/blob/master/examples/sql_filelock_multiprocess.py) ## Web Request Rate Limiting pyrate_limiter provides three extras for popular web request libraries: - [AIOHTTP](https://pypi.org/project/aiohttp/) - [HTTPX](https://pypi.org/project/httpx/) - [Requests](https://pypi.org/project/requests/) ### AIOHTTP ```py from pyrate_limiter import limiter_factory from pyrate_limiter.extras.aiohttp_limiter import RateLimitedSession limiter = limiter_factory.create_inmemory_limiter(rate_per_duration=2, duration=Duration.SECOND) session = RateLimitedSession(limiter) ``` Example: [aiohttp_ratelimiter.py](https://github.com/vutran1710/PyrateLimiter/blob/master/examples/aiohttp_ratelimiter.py) ### HTTPX ```py from pyrate_limiter import limiter_factory from pyrate_limiter.extras.httpx_limiter import AsyncRateLimiterTransport, RateLimiterTransport import httpx limiter = limiter_factory.create_inmemory_limiter(rate_per_duration=1, duration=Duration.SECOND, max_delay=Duration.HOUR) url = "https://example.com" with httpx.Client(transport=RateLimiterTransport(limiter=limiter)) as client: client.get(url) # or async async with httpx.AsyncClient(transport=AsyncRateLimiterTransport(limiter=limiter)) as client: client.get(url) ... ``` Example: [httpx_ratelimiter.py](https://github.com/vutran1710/PyrateLimiter/blob/master/examples/httpx_ratelimiter.py) ### Requests ```py from pyrate_limiter import limiter_factory from pyrate_limiter.extras.requests_limiter import RateLimitedRequestsSession limiter = limiter_factory.create_inmemory_limiter(rate_per_duration=2, duration=Duration.SECOND) session = RateLimitedRequestsSession(limiter) .... ``` Example: [requests_ratelimiter.py](https://github.com/vutran1710/PyrateLimiter/blob/master/examples/requests_ratelimiter.py) ## Basic Usage ### Key concepts #### Clock - Timestamps incoming items #### Bucket - Stores items with timestamps. - Functions as a FIFO queue. - Can `leak` to remove outdated items. #### BucketFactory - Manages buckets and clocks, routing items to their appropriate buckets. - Schedules periodic `leak` operations to prevent overflow. - Allows custom logic for routing, conditions, and timing. #### Limiter - Provides a simple, intuitive API by abstracting underlying logic. - Seamlessly supports both sync and async contexts. - Offers multiple interaction modes: direct calls, decorators, and (future) context managers. - Ensures thread-safety via RLock, and if needed, asyncio concurrency via asyncio.Lock ### Defining rate limits and buckets For example, an API (like LinkedIn or GitHub) might have these rate limits: ``` - 500 requests per hour - 1000 requests per day - 10000 requests per month ``` You can define these rates using the `Rate` class. `Rate` class has 2 properties only: **limit** and **interval** ```python from pyrate_limiter import Duration, Rate hourly_rate = Rate(500, Duration.HOUR) # 500 requests per hour daily_rate = Rate(1000, Duration.DAY) # 1000 requests per day monthly_rate = Rate(10000, Duration.WEEK * 4) # 10000 requests per month rates = [hourly_rate, daily_rate, monthly_rate] ``` Rates must be properly ordered: - Rates' intervals & limits must be ordered from least to greatest - Rates' ratio of **limit/interval** must be ordered from greatest to least Buckets validate rates during initialization. If using a custom implementation, use the built-in validator: ```python from pyrate_limiter import validate_rate_list assert validate_rate_list(my_rates) ``` Then, add the rates to the bucket of your choices ```python from pyrate_limiter import InMemoryBucket, RedisBucket basic_bucket = InMemoryBucket(rates) # Or, using redis from redis import Redis redis_connection = Redis(host='localhost') redis_bucket = RedisBucket.init(rates, redis_connection, "my-bucket-name") # Async Redis would work too! from redis.asyncio import Redis redis_connection = Redis(host='localhost') redis_bucket = await RedisBucket.init(rates, redis_connection, "my-bucket-name") ``` If you only need a single Bucket for everything, and python's built-in `time()` is enough for you, then pass the bucket to Limiter then ready to roll! ```python from pyrate_limiter import Limiter # Limiter constructor accepts single bucket as the only parameter, # the rest are 3 optional parameters with default values as following # Limiter(bucket, clock=MonotonicClock(), raise_when_fail=True, max_delay=None) limiter = Limiter(bucket) # Limiter is now ready to work! limiter.try_acquire("hello world") ``` If you want to have finer grain control with routing & clocks etc, then you should use `BucketFactory`. ### Defining Clock & routing logic with BucketFactory When multiple bucket types are needed and items must be routed based on certain conditions, use `BucketFactory`. First, define your clock (time source). Most use cases work with the built-in clocks: ```python from pyrate_limiter.clock import MonotonicClock, SQLiteClock base_clock = MonotonicClock() ``` PyrateLimiter does not assume routing logic, so you implement a custom BucketFactory. At a minimum, these two methods must be defined: ```python from pyrate_limiter import BucketFactory from pyrate_limiter import AbstractBucket class MyBucketFactory(BucketFactory): # You can use constructor here, # nor it requires to make bucket-factory work! def wrap_item(self, name: str, weight: int = 1) -> RateItem: """Time-stamping item, return a RateItem""" now = clock.now() return RateItem(name, now, weight=weight) def get(self, _item: RateItem) -> AbstractBucket: """For simplicity's sake, all items route to the same, single bucket""" return bucket ``` ### Creating buckets dynamically If more than one bucket is needed, the bucket-routing logic should go to BucketFactory `get(..)` method. When creating buckets dynamically, it is needed to schedule leak for each newly created buckets. To support this, BucketFactory comes with a predefined method call `self.create(..)`. It is meant to create the bucket and schedule that bucket for leaking using the Factory's clock ```python def create( self, clock: AbstractClock, bucket_class: Type[AbstractBucket], *args, **kwargs, ) -> AbstractBucket: """Creating a bucket dynamically""" bucket = bucket_class(*args, **kwargs) self.schedule_leak(bucket, clock) return bucket ``` By utilizing this, we can modify the code as following: ```python class MultiBucketFactory(BucketFactory): def __init__(self, clock): self.clock = clock self.buckets = {} def wrap_item(self, name: str, weight: int = 1) -> RateItem: """Time-stamping item, return a RateItem""" now = clock.now() return RateItem(name, now, weight=weight) def get(self, item: RateItem) -> AbstractBucket: if item.name not in self.buckets: # Use `self.create(..)` method to both initialize new bucket and calling `schedule_leak` on that bucket # We can create different buckets with different types/classes here as well new_bucket = self.create(YourBucketClass, *your-arguments, **your-keyword-arguments) self.buckets.update({item.name: new_bucket}) return self.buckets[item.name] ``` ### Wrapping all up with Limiter Pass your bucket-factory to Limiter, and ready to roll! ```python from pyrate_limiter import Limiter limiter = Limiter( bucket_factory, raise_when_fail=False, # Default = True max_delay=1000, # Default = None ) item = "the-earth" limiter.try_acquire(item) heavy_item = "the-sun" limiter.try_acquire(heavy_item, weight=10000) ``` ### asyncio and event loops To ensure the event loop isn't blocked, use `try_acquire_async` with an **async bucket**, which leverages `asyncio.Lock` for concurrency control. If your bucket isn't async, wrap it with `BucketAsyncWrapper`. This ensures `asyncio.sleep` is used instead of `time.sleep`, preventing event loop blocking: ```python await limiter.try_acquire_async(item) ``` Example: [asyncio_ratelimit.py](https://github.com/vutran1710/PyrateLimiter/blob/master/examples/asyncio_ratelimit.py) #### `as_decorator()`: use limiter as decorator `Limiter` can be used as a decorator with `name` and `weight` parameters. The decorator works with both synchronous and asynchronous functions: ```python from pyrate_limiter import Rate, Duration, Limiter limiter = Limiter(Rate(5, Duration.SECOND)) @limiter.as_decorator(name="api_call", weight=1) def handle_something(*args, **kwargs): """function logic""" @limiter.as_decorator(name="background_job", weight=2) async def handle_something_async(*args, **kwargs): """async function logic""" ``` For full example see [asyncio_decorator.py](https://github.com/vutran1710/PyrateLimiter/blob/master/examples/asyncio_decorator.py) ### Limiter API #### `bucket()`: get list of all active buckets Return list of all active buckets with `limiter.buckets()` #### `dispose(bucket: int | BucketObject)`: dispose/remove/delete the given bucket Method signature: ```python def dispose(self, bucket: Union[int, AbstractBucket]) -> bool: """Dispose/Remove a specific bucket, using bucket-id or bucket object as param """ ``` Example of usage: ```python active_buckets = limiter.buckets() assert len(active_buckets) > 0 bucket_to_remove = active_buckets[0] assert limiter.dispose(bucket_to_remove) ``` If a bucket is found and get deleted, calling this method will return **True**, otherwise **False**. If there is no more buckets in the limiter's bucket-factory, all the leaking tasks will be stopped. #### Context Manager Limiter supports the context manager protocol for automatic cleanup: ```python from pyrate_limiter import Limiter, RequestRate, Duration, InMemoryBucket # Define a simple rate and create a bucket rate = RequestRate(5, Duration.SECOND) bucket = InMemoryBucket(rate) # Use Limiter as a context manager with Limiter(bucket) as limiter: limiter.try_acquire("item") # Resources automatically released # Or manually close limiter = Limiter(bucket) try: limiter.try_acquire("item") finally: limiter.close() ``` ### Weight Item can have weight. By default item's weight = 1, but you can modify the weight before passing to `limiter.try_acquire`. Item with weight W > 1 when consumed will be multiplied to (W) items with the same timestamp and weight = 1. Example with a big item with weight W=5, when put to bucket, it will be divided to 5 items with weight=1 + following names ``` BigItem(weight=5, name="item", timestamp=100) => [ item(weight=1, name="item", timestamp=100), item(weight=1, name="item", timestamp=100), item(weight=1, name="item", timestamp=100), item(weight=1, name="item", timestamp=100), item(weight=1, name="item", timestamp=100), ] ``` Yet, putting this big, heavy item into bucket is expected to be transactional & atomic - meaning either all 5 items will be consumed or none of them will. This is made possible as bucket `put(item)` always check for available space before ingesting. All of the Bucket's implementations provided by **PyrateLimiter** follows this rule. Any additional, custom implementation of Bucket are expected to behave alike - as we have unit tests to cover the case. See [Advanced Usage](#advanced-usage) below for more details. ### Handling exceeded limits When a rate limit is exceeded, you can choose between blocking and non-blocking behavior. #### Bucket analogy At this point it's useful to introduce the analogy of "buckets" used for rate-limiting. Here is a quick summary: - This library implements the [Leaky Bucket algorithm](https://en.wikipedia.org/wiki/Leaky_bucket). - It is named after the idea of representing some kind of fixed capacity -- like a network or service -- as a bucket. - The bucket "leaks" at a constant rate. For web services, this represents the **ideal or permitted request rate**. - The bucket is "filled" at an intermittent, unpredicatble rate, representing the **actual rate of requests**. - When the bucket is "full", it will overflow, representing **canceled or delayed requests**. - Item can have weight. Consuming a single item with weight W > 1 is the same as consuming W smaller, unit items - each with weight=1, with the same timestamp and maybe same name (depending on however user choose to implement it) #### Blocking vs Non-blocking By default, `try_acquire` blocks until a permit becomes available: ```python from pyrate_limiter import Rate, Limiter, Duration rate = Rate(3, Duration.SECOND) limiter = Limiter(rate) # Blocking (default) - waits until permit is available for i in range(5): limiter.try_acquire("item") # blocks if bucket is full print(f"Acquired {i}") ``` For non-blocking behavior, set `blocking=False` to return immediately: ```python # Non-blocking - returns False immediately if bucket is full for i in range(5): success = limiter.try_acquire("item", blocking=False) if not success: print(f"Rate limited at request {i}") break ``` For async code, use `try_acquire_async` with optional timeout: ```python # Async with timeout (in seconds) success = await limiter.try_acquire_async("item", timeout=5) if not success: print("Timed out waiting for permit") ``` The `buffer_ms` parameter (default 50ms) adds a small delay buffer to account for timing variations: ```python from pyrate_limiter import Duration, InMemoryBucket, Limiter, RequestRate rate = RequestRate(5, Duration.SECOND) bucket = InMemoryBucket(rate) limiter = Limiter(bucket, buffer_ms=100) # 100ms buffer ``` ### Backends A few different bucket backends are available: - **InMemoryBucket**: using python built-in list as bucket - **MultiprocessBucket**: uses a multiprocessing lock for distributed concurrency with a ListProxy as the bucket - **RedisBucket**, using err... redis, with both async/sync support - **PostgresBucket**, using `psycopg2` - **SQLiteBucket**, using sqlite3 - **BucketAsyncWrapper**: wraps an existing bucket with async interfaces, to avoid blocking the event loop #### InMemoryBucket The default bucket is stored in memory, using python `list` ```python from pyrate_limiter import InMemoryBucket, Rate, Duration rates = [Rate(5, Duration.MINUTE * 2)] bucket = InMemoryBucket(rates) ``` This bucket only availabe in `sync` mode. The only constructor argument is `List[Rate]`. #### MultiprocessBucket MultiprocessBucket uses a ListProxy to store items within a python multiprocessing pool or ProcessPoolExecutor. Concurrency is enforced via a multiprocessing Lock. The bucket is shared across instances. An example is provided in [in_memory_multiprocess](https://github.com/vutran1710/PyrateLimiter/blob/master/examples/in_memory_multiprocess.py) Whenever multiprocessing, bucket.waiting calculations will be often wrong because of the concurrency involved. Set Limiter.retry_until_max_delay=True so that the item keeps retrying rather than returning False when contention causes an extra delay. #### RedisBucket RedisBucket uses `Sorted-Set` to store items with key being item's name and score item's timestamp Because it is intended to work with both async & sync, we provide a classmethod `init` for it ```python from pyrate_limiter import RedisBucket, Rate, Duration # Using synchronous redis from redis import ConnectionPool from redis import Redis rates = [Rate(5, Duration.MINUTE * 2)] pool = ConnectionPool.from_url("redis://localhost:6379") redis_db = Redis(connection_pool=pool) bucket_key = "bucket-key" bucket = RedisBucket.init(rates, redis_db, bucket_key) # Using asynchronous redis from redis.asyncio import ConnectionPool as AsyncConnectionPool from redis.asyncio import Redis as AsyncRedis pool = AsyncConnectionPool.from_url("redis://localhost:6379") redis_db = AsyncRedis(connection_pool=pool) bucket_key = "bucket-key" bucket = await RedisBucket.init(rates, redis_db, bucket_key) ``` The API are the same, regardless of sync/async. If AsyncRedis is being used, calling `await bucket.method_name(args)` would just work! #### SQLiteBucket If you need to persist the bucket state, a SQLite backend is available. The SQLite bucket works in sync manner. Manully create a connection to Sqlite and pass it along with the table name to the bucket class: ```python from pyrate_limiter import SQLiteBucket, Rate, Duration import sqlite3 rates = [Rate(5, Duration.MINUTE * 2)] bucket = SQLiteBucket.init_from_file(rates) ``` ```py from pyrate_limiter import Rate, Limiter, Duration, SQLiteBucket requests_per_minute = 5 rate = Rate(requests_per_minute, Duration.MINUTE) bucket = SQLiteBucket.init_from_file([rate], use_file_lock=False) # set use_file_lock to True if using across multiple processes limiter = Limiter(bucket, raise_when_fail=False, max_delay=max_delay) ``` You can also pass custom arguments to the `init_from_file` following its signature: ```python class SQLiteBucket(AbstractBucket): @classmethod def init_from_file( cls, rates: List[Rate], table: str = "rate_bucket", db_path: Optional[str] = None, create_new_table = True, use_file_lock: bool = False ) -> "SQLiteBucket": ... ``` Options: - `db_path`: If not provided, uses `tempdir / "pyrate-limiter.sqlite"` - `use_file_lock`: Should be False for single process workloads. For multi process, uses a [filelock](https://pypi.org/project/filelock/) to ensure single access to the SQLite bucket across multiple processes, allowing multi process rate limiting on a single host. Example: [limiter_factory.py::create_sqlite_limiter()](https://github.com/vutran1710/PyrateLimiter/blob/master/pyrate_limiter/limiter_factory.py) #### PostgresBucket Postgres is supported, but you have to install `psycopg[pool]` either as an extra or as a separate package. The PostgresBucket currently does not support async. You can use Postgres's built-in **CURRENT_TIMESTAMP** as the time source with `PostgresClock`, or use an external custom time source. ```python from pyrate_limiter import PostgresBucket, Rate, PostgresClock from psycopg_pool import ConnectionPool connection_pool = ConnectionPool('postgresql://postgres:postgres@localhost:5432') clock = PostgresClock(connection_pool) rates = [Rate(3, 1000), Rate(4, 1500)] bucket = PostgresBucket(connection_pool, "my-bucket-table", rates) ``` #### BucketAsyncWrapper The BucketAsyncWrapper wraps a sync bucket to ensure all its methods return awaitables. This allows the Limiter to detect asynchronous behavior and use asyncio.sleep() instead of time.sleep() during delay handling, preventing blocking of the asyncio event loop. Example: [limiter_factory.py::create_inmemory_limiter()](https://github.com/vutran1710/PyrateLimiter/blob/master/pyrate_limiter/limiter_factory.py) ### Async or Sync or Multiprocessing The Limiter is basically made of a Clock backend and a Bucket backend. The backends may be async or sync, which determines the Limiters internal behavior, regardless of whether the caller enters via a sync or async function. try_acquire_async: When calling from an async context, use try_acquire_async. This uses a thread-local asyncio lock to ensure only one asyncio task is acquiring, followed by a global RLock so that only one thread is acquiring. try_acquire: When called directly, the global RLock enforces only one thread at a time. Multiprocessing: If using MultiprocessBucket, two locks are used in Limiter: a top level multiprocessing lock, then a thread level RLock ## Advanced Usage ### Component level diagram ![](https://raw.githubusercontent.com/vutran1710/PyrateLimiter/master/docs/_static/components.jpg) ### Time sources Time source can be anything from anywhere: be it python's built-in time, or monotonic clock, sqliteclock, or crawling from world time server(well we don't have that, but you can!). ```python from pyrate_limiter import MonotonicClock # use python time.monotonic() ``` Clock's abstract interface only requires implementing a method `now() -> int`. And it can be both sync or async. ### Leaking Typically bucket should not hold items forever. Bucket's abstract interface requires its implementation must be provided with `leak(current_timestamp: Optional[int] = None)`. The `leak` method when called is expected to remove any items considered outdated at that moment. During Limiter lifetime, all the buckets' `leak` should be called periodically. **BucketFactory** provide a method called `schedule_leak` to help deal with this matter. Basically, it will run as a background task for all the buckets currently in use, with interval between `leak` call by **default is 10 seconds**. ```python # Runnning a background task (whether it is sync/async - doesnt matter) # calling the bucket's leak factory.schedule_leak(bucket, clock) ``` You can change this calling interval by overriding BucketFactory's `leak_interval` property. This interval is in **miliseconds**. ```python class MyBucketFactory(BucketFactory): def __init__(self, *args): self.leak_interval = 300 ``` When dealing with leak using BucketFactory, the author's suggestion is, we can be pythonic about this by implementing a constructor ```python class MyBucketFactory(BucketFactory): def constructor(self, clock, buckets): self.clock = clock self.buckets = buckets for bucket in buckets: self.schedule_leak(bucket, clock) ``` ### Concurrency Generally, Lock is provided at Limiter's level, except SQLiteBucket case. ### Custom backends If these don't suit your needs, you can also create your own bucket backend by implementing `pyrate_limiter.AbstractBucket` class. One of **PyrateLimiter** design goals is powerful extensibility and maximum ease of development. It must be not only be a ready-to-use tool, but also a guide-line, or a framework that help implementing new features/bucket free of the most hassles. Due to the composition nature of the library, it is possbile to write minimum code and validate the result: - Fork the repo - Implement your bucket with `pyrate_limiter.AbstractBucket` - Add your own `create_bucket` method in `tests/conftest.py` and pass it to the `create_bucket` fixture - Run the test suite to validate the result If the tests pass through, then you are just good to go with your new, fancy bucket! vutran1710-PyrateLimiter-634d166/benchmarks/000077500000000000000000000000001513463764300205425ustar00rootroot00000000000000vutran1710-PyrateLimiter-634d166/benchmarks/stress_limiters.py000066400000000000000000000151131513463764300243500ustar00rootroot00000000000000# ruff: noqa: G004 import logging from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor, wait from dataclasses import dataclass from functools import partial from time import perf_counter from typing import Callable, Literal, cast from pyrate_limiter import Duration, Limiter, MultiprocessBucket, Rate, limiter_factory logger = logging.getLogger(__name__) BUFFER_MS: int = 1 # reduce the buffer to improve measurement TEST_DURATION_SEC: int = 1 # time per test PREFILL: bool = True @dataclass class TestResult: label: str requests_per_second: int test_duration_seconds: int duration: float num_requests: int percent_from_expected_duration: float def create_mp_limiter(bucket: MultiprocessBucket): limiter = Limiter(bucket, buffer_ms=BUFFER_MS) return limiter def create_rate_limiter_factory( requests_per_second: int, backend: Literal["default", "sqlite", "sqlite_filelock", "mp_limiter"], ) -> Callable[[], Limiter]: """Returns a callable, so it can be used with multiprocessing""" rate = Rate(requests_per_second, Duration.SECOND) if backend == "default": limiter = limiter_factory.create_inmemory_limiter(rate_per_duration=requests_per_second, duration=Duration.SECOND, buffer_ms=BUFFER_MS) return lambda: limiter elif backend == "sqlite": limiter = limiter_factory.create_sqlite_limiter( rate_per_duration=requests_per_second, use_file_lock=False, buffer_ms=BUFFER_MS, db_path="pyrate_limiter.sqlite" ) return lambda: limiter elif backend == "sqlite_filelock": return partial( limiter_factory.create_sqlite_limiter, rate_per_duration=requests_per_second, duration=Duration.SECOND, use_file_lock=True, buffer_ms=BUFFER_MS, db_path="pyrate_limiter.sqlite", ) elif backend == "mp_limiter": bucket = MultiprocessBucket.init([rate]) return partial(create_mp_limiter, bucket=bucket) else: raise ValueError(f"Unexpected backend option: {backend}") def task(): assert limiter_factory.LIMITER is not None, "Limiter not initialized" try: limiter_factory.LIMITER.try_acquire("task") except Exception as e: logger.exception(e) def limiter_init(limiter_creator: Callable[[], Limiter]): limiter_factory.LIMITER = limiter_creator() def test_rate_limiter( limiter_creator: Callable[[], Limiter], num_requests: int, use_process_pool: bool, ): start = perf_counter() if use_process_pool: logger.info("Using ProcessPoolExecutor") with ProcessPoolExecutor(initializer=partial(limiter_init, limiter_creator) if limiter_creator is not None else None) as executor: if PREFILL: # Pre-load the buckets, after processes created limiter = limiter_creator() [limiter.try_acquire("task") for i in range(requests_per_second)] futures = [executor.submit(task) for _ in range(num_requests)] wait(futures) else: with ThreadPoolExecutor() as executor: if PREFILL: # Pre-load the buckets, after threads created limiter = limiter_creator() [limiter.try_acquire("task") for i in range(requests_per_second)] limiter = limiter_creator() limiter_factory.LIMITER = limiter futures = [executor.submit(task) for _ in range(num_requests)] wait(futures) for f in futures: try: f.result() except Exception as e: logger.exception(f"Task raised: {e}") end = perf_counter() return end - start def run_test_limiter( limiter_creator: Callable, label: str, requests_per_second: int, test_duration_seconds: int, use_process_pool: bool = False, ): num_requests = test_duration_seconds * requests_per_second # should finish in around 20 seconds duration = test_rate_limiter(limiter_creator=limiter_creator, num_requests=num_requests, use_process_pool=use_process_pool) percent_from_expected_duration = (abs(duration) - test_duration_seconds) / test_duration_seconds return TestResult( label=label, requests_per_second=requests_per_second, test_duration_seconds=test_duration_seconds, duration=duration, num_requests=num_requests, percent_from_expected_duration=percent_from_expected_duration, ) if __name__ == "__main__": import pandas as pd import plotly.express as px requests_per_second_list = [10, 100, 1000, 2500, 5000] test_duration_seconds = TEST_DURATION_SEC test_results = [] logging.basicConfig( format="%(asctime)s %(name)s %(levelname)-8s %(message)s", level=logging.INFO, datefmt="%Y-%m-%d %H:%M:%S", ) for backend in ["default", "sqlite", "mp_limiter"]: backend = cast(Literal["default", "sqlite", "sqlite_filelock", "mp_limiter"], backend) for requests_per_second in requests_per_second_list: logger.info(f"Testing with {backend=}, {requests_per_second=}") limiter_creator = create_rate_limiter_factory(requests_per_second, backend=backend) result = run_test_limiter( limiter_creator=limiter_creator, label="Threads: " + backend, requests_per_second=requests_per_second, test_duration_seconds=test_duration_seconds, ) test_results.append(result) logger.info("Testing Multiprocessing") for backend in ["sqlite_filelock", "mp_limiter"]: backend = cast(Literal["default", "sqlite", "sqlite_filelock", "mp_limiter"], backend) for requests_per_second in requests_per_second_list: logger.info(f"Testing with {backend=}, {requests_per_second=}") limiter_creator = create_rate_limiter_factory(requests_per_second, backend=backend) result = run_test_limiter( limiter_creator=limiter_creator, label="Processes: " + backend, requests_per_second=requests_per_second, test_duration_seconds=test_duration_seconds, use_process_pool=True, ) test_results.append(result) results_df = pd.DataFrame(test_results).sort_values(by="requests_per_second") results_df["requests_per_second"] = results_df["requests_per_second"].astype(str) fig = px.line(results_df, x="requests_per_second", y="duration", color="label", markers=True) fig.write_html("chart.html") logger.info("Output written to chart.html") vutran1710-PyrateLimiter-634d166/docker-compose.yaml000066400000000000000000000011661513463764300222270ustar00rootroot00000000000000services: redis-master: image: redis:7 command: ["redis-server","--appendonly","yes","--requirepass","changeme"] ports: ["6379:6379"] networks: [pyrate-bay] redis-slave: image: redis:7 command: ["redis-server","--replicaof","redis-master","6379","--masterauth","changeme","--requirepass","changeme"] ports: ["6380:6379"] networks: [pyrate-bay] postgres: image: postgres:18 ports: - "5432:5432" environment: - POSTGRES_PASSWORD=postgres command: ["postgres","-c","max_connections=1000"] networks: - pyrate-bay networks: pyrate-bay: driver: bridgevutran1710-PyrateLimiter-634d166/docs/000077500000000000000000000000001513463764300173555ustar00rootroot00000000000000vutran1710-PyrateLimiter-634d166/docs/_static/000077500000000000000000000000001513463764300210035ustar00rootroot00000000000000vutran1710-PyrateLimiter-634d166/docs/_static/components.jpg000066400000000000000000007757231513463764300237170ustar00rootroot00000000000000ÿØÿàJFIFÿâØICC_PROFILEÈ0mntrRGB XYZ àacspöÖÓ- descð$rXYZgXYZ(bXYZ<wtptPrTRCd(gTRCd(bTRCd(cprtŒ4z5VV5}è½½ä1[Ä,Ñ2fê%¡íG&ö˜÷ÙSýRâCì%”ýïöñ‘íüJŸîLÿbÛÂ&Ñæ=NpÅ;ûúë<·t粬>¢ž!¾lÿÕ1üÑôSÄ7Â-Ÿú¦?šeÌ~ù;EúXú”û•Ñ‹ú)âáÏýSÍE¥>ãF/览o„[?õL4}ñ ð‹gþ©æ™@>ù;EúXú”û¿¢ž!¾lÿÕ1üÑôSÄ7Â-Ÿú¦?šeûäíécêSî4bþŠx†øE³ÿTÇóGÑOß¶ê˜þi”ï“´_¥©O¸Ñ‹ú)âáÏýSÍE¥>ãF/览o„[?õL4}ñ ð‹gþ©æ™@>ù;EúXú”û¿¢ž!¾lÿÕ1üÑôSÄ7Â-Ÿú¦?šeûäíécêSî4bþŠx†øE³ÿTÇóGÑOß¶ê˜þi”ï“´_¥©O¸Ñ‹ú)âáÏýSÍE¥>ãF/览o„[?õL4}ñ ð‹gþ©æ™@>ù;EúXú”û¿¢ž!¾lÿÕ1üÑôSÄ7Â-Ÿú¦?šeûäíécêSî4bþŠx†øE³ÿTÇóGÑOß¶ê˜þi”ï“´_¥©O¸Ñ‹ú)âáÏýSÍE¥>ãF/览o„[?õL4}ñ ð‹gþ©æ™@>ù;EúXú”û¿¢ž!¾lÿÕ1üÑôSÄ7Â-Ÿú¦?šeûäíécêSî4bþŠx†øE³ÿTÇóGÑOß¶ê˜þi”ï“´_¥©O¸Ñ‹ú)âáÏýSÍE¥>ãF/览o„[?õL4}ñ ð‹gþ©æ™@>ù;EúXú”û¿¢ž!¾lÿÕ1üÑôSÄ7Â-Ÿú¦?šeûäíécêSî4bþŠx†øE³ÿTÇóGÑOß¶ê˜þi”ï“´_¥©O¸Ñ‹ú)âáÏýSÍE¥>ãF/览o„[?õL4}ñ ð‹gþ©æ™@>ù;EúXú”û¿¢ž!¾lÿÕ1üÑôSÄ7Â-Ÿú¦?šeûäíécêSî4bþŠx†øE³ÿTÇóGÑOß¶ê˜þi”ï“´_¥©O¸Ñ‹ú)âáÏýSÍE¥>ãF/览o„[?õL4}ñ ð‹gþ©æ™@>ù;EúXú”û¿¢ž!¾lÿÕ1üÑôSÄ7Â-Ÿú¦?šeûäíécêSî4bþŠx†øE³ÿTÇóGÑOß¶ê˜þi”ï“´_¥©O¸Ñ‹ú)âáÏýSÍE¥>ãF/览o„[?õL4}ñ ð‹gþ©æ™@>ù;EúXú”û¿¢ž!¾lÿÕ1üÓæ¹fÜBÛmÕWj ¡éKæV¥ª4W#Z«·«ñÓ”{7¼*?³q áh.ß¢Š®Æ“1&ž¾ãDÕ¤y×+ÓkE|¨IëëéiäF5ˆç+—¹­DD6ò?аÞ'ø=¿¤â@>y/õò)èòÿQß"èkćØK)ûÞ/íã#Úø•?Ü™þÄ$.$>ÂYOÞñoÐÿÄ©þäÏö!Æ|/üŒ}ôV°âO@ŒÊ?½›¿Þٸɘ̣ûÙ»ýáQý›Œ¬åVþ”{`K:öÄÿ·ôœH ?a¼Oð{IÄ€}’ð_ê;äSÑåþ£¾EÐ׉°–S÷¼_ÛÆG´?ñ*¹3ýˆH\H}„²Ÿ½âþÞ2=¡ÿ‰SýÉŸìCŒø_ù>úÿè¬?`Äž€”{7¼*?³q“1™G÷³wû£û7XÊ­ý(öÀ–tì7‰þoé8ÿ@~ÃxŸàöþ“‰û%à<¿Ôwȧ£ËýG|Š ¯a,§ïx¿·ŒhâTÿrgû¸û e?{Åý¼d{Cÿ§û“?؇ð¿ò0}õÿÑX~À‰=à2Þ8¸sÄn³Ù¦Ì'ºTS?³•ÖÊ9*"k¼v—dcööµU ûJµ×Ku¦–¢£O2˜nÑ¢-M+ã|5¢÷+£z#•¾É»w龿ÖþG™ál|&þºmþtÓ1yqÓ¥Fú5J€ù®w;u–ÝSw»×ÓÑPÑDùêjj$Hâ†6¦î{ܽÔDUUR¹ññÃe¶àêò‹j1ëª)ms:$ÙvUEr"¹>4EßÀØ`rœvg¯ÀìÕsN{±3§~‚ÄXÓÍNÁ5Z™.Ÿä”׊u‰ï‹™¯ŠDëÉ$oD{²¢ìäMÑQS¢¢›9‰zÍÌ=ɵz™¦¨á11¤Ç|H @c2ïfï÷…Gön2f3(þönÿxTfã+ùU¿¥Ø΀ý†ñ?Áíý'èØoüßÒq d¼—úŽùôy¨ï‘@ô5âCì%”ýïöñ‘íüJŸîLÿba,§ïx¿·ŒhâTÿrgûã>þF¾¿ú+Øq' ©ü~jÞ£iMŸ ŸOrª›,—*šÖU:F啨•¨¼í^îgw{K`R)÷ü…§ÿ}ÜBY°Ö-bsü=«ôÅTÌÕ¬LDÄùtO%Y>¬.%~nŸýÆ÷eùàƒPóMMщ²<îý=ÞäËÕM2TLÖ5Éc‰ZßE:+áârŒéÏ“—ÞýQÿH«?²€ê~2¬$ñ˜{QVýÂ{¥ÆVÉ:ÅÌŽìÚkXÆîˆ«ÊÝ×dÝWdÛ¸gþr|vS{‡Šª®å3N“NšoFšÌòáφ¼^tK`ƒ½+§uW:^o o|ŒŽzúªÕŠ©õ•™eÛÁ^ŒOÆr´îVOŒXs<~¿Éí±\-W8Vžªš]ùdbüi²¢¢ì¨¨¨¨¨ŠŠŠ…V¸y4´‚¦äêš Ï+££{•ÞmÚSÈ­ßÁ¯X÷Ù<7E_j©Öö lòÌ‹^­3½5DÄk¬DiÃŽ±§r“»É‘Svnw™ÑÄçû˜ûDΜËËÛ¤ÛEÓ»~WM×å:h:7¡ú¡xä˜î o™‰RöËYYU/iSW#SdtŽÙ¢o³Zjn»"*®ûñ ÚÜâÆ{›\Æá阢tˆ×œéϳBTj+œ¨ˆUWÀˆÝů rµurɺ.Ý"§ô£O“‹íMM.Ðl†çMQÙ\®ñû‹nTvÎí§EkœÕö¶$•éñ±D’mŠØ[;I…¹‹Å×U4Å[´îéÇHÖyÄõÄGœ™w+ɬ9Š&Æ.pÜmuìY)ª¡ß’V¢ª*¦ý{ÑSñ2àóÞÕ‚}á'ë“̰Ôà±·°ÔN±EUSóÒ&` ŒÊ?½›¿Þٸɘ̣ûÙ»ýáQý›Œ¬åVþ”{`K:öÄÿ·ôœH ?a¼Oð{IÄ€}’ð_ê;äSÑåþ£¾EÐ׉°–S÷¼_ÛÆG´?ñ*¹3ýˆH\H}„²Ÿ½âþÞ2=¡ÿ‰SýÉŸìCŒø_ù>úÿè¬?`Äž€yO¿ä-?ûîãú|¤Sïù Oþû¸þ„ËÁÿù ßWðT¤¨ ÓŸ'/½ú£þ‘VeÌc§>N_{õGý"¬þÊ®xPÿÿ]?j´€ç Õ5j¾¶Õ¥YÒÙW--e?q¨§ž'+_Œ¦‘Í{U:¢¢¢*/µ ¬Óu§ì9žÑ›§ê²xбV¢:ŸlK}QõðÏšÿ^TüòÂð/«º§™ë´V\»QrKÕ½Öš¹V–¾ç4ñ+ÛÉÊîW¹StðRœgÉãð-oÿ@}5µYvÞIŠ®‹TÄÅqŠc^]Ï0ê!E|¡z¨Ø&sŠQaYÕúÃOSi–Y¢·\%§lI•ÎF97]ºn¥ê9ßå6û!áßeþÝN%àîÍ»ùýª.ÓF•p˜Ö>Lõ«(Oâ‡Y1ìâÁ|¿êžYrµÐÜi殤©ºÏ4SÓ¤‰Ú±Ìs•»9“¸²|Rqãs´^k4ÿC«iZ´ŽH«2&£'æ“í£¦k‘Y²w,‹¾ë¿*&Èå¡d‰¢œkÖTìk‚(â¥cf¯¸Tª¶žŽ%]‘\¨ŠªåÙyX]²÷"9S·fÛ9‘ÍêsLuÓE¨bb"žq¤Õ:qˆŽ:ëË’~ÿ©z‰•TKU’gWûœ“9\õª¸Ë"*üH®Ù؉Ñ<ßÕ}NĪ¢¬Æõ!·K îÞÂã+[ò+y¹\Ÿ¢¡m¯>LKÍ=•óØuj–¶êÈœæÓTÚ2¿mѽ¢LõjoÓ~UöìÅ.ȱûÆ)}¸c9 è®vº™)*éÞ¨«¬rµÉºt^©ÞЍ©ÕPÊÊsl>¢«8 ¦¸§;ºpîª#‡›E×…9krë½>œëUeUÕ VÛïÎå“ÈR*†¢#åMù^œ¨ªˆÕM×uÒxŽãï+º^ë1-®eªÏG+¡}íŒl•ÊÑs"¤Qï¾Êˆ¯TD]Û¾Å0%á·<âñSMŽv6ûM¿•+®Õh½Œ.^èÚ‰ÖI:ò¦È‰ÕU»¦ú\FÇìîUН9ÅSM6â>LüˆyÄvðˆ§M5åé¥uh—Œÿ;Èf}Eÿ4¾Ü¥{¹œú»ŒÒª¯·Òr™,_Xµ[ «Ž³Ô\†ÜøÜŽäŠá/dí»‘ñª«Ÿ‘Pµ“/#¶X'¯Ãu2žõt‚%{h*­žhÚ‡'^VËÚ½ª™6ßmÕªRÚÚ:»udöúúwÁSK+¡š'¦ÎŽFª£š©à¨¨¨o2¬Ó%Ú UQšnSO Ý4×öjˆá=Ú(é/†ÕHÞJjmúo²õ{öè®rª÷í²t#fâo‡UáÏ"³Ø0ú!÷Z‰Õ¯¹þiÙm"³——´“›»}÷O†Nñ’×€¹·^Yf<"b9õLDóëã<Ôn–=kÖfÕObÇuG*¶[©¬§¤¤»ÏQ5UUQ¬k‘7U^žÓ7dâ]å¼ÐG.±æocê¢kšëÝB£‘^›¢¢¿ªny?×V4ÒŨŸM”µ{·§ó?p{~Çi͹üá¼Þ®þªw›Õ¿ÉŠ´5ôÕ«­¼éO3%åúÛ›•È»oç];ˆ®7jvJÍÛ–oUOŒ‰˜ŸÁÕ>TN“ÇsUÒWœÓõWUð½Äj3,âçæÔq/g LNiª¦TUl13íž»/±UUSp9=Æ~´ÖêÖ°\môuî“Åæ’Ûl‰«è9íTlóüj÷µv_ä5‡Øíš¥ÌigÀƒÝî6½µ_‘Û>h÷{¯mWävÏšYð`÷{¯mWävÏš=ÞãkÛUù³æ–|X=ÞãkÛUù³æw¸ÚöÕ~Glù¥ŸVw¸ÚöÕ~Glù£Ýî6½µ_‘Û>igÀƒÝî6½µ_‘Û>h÷{¯mWävÏšYð`÷{¯mWävÏš=ÞãkÛUù³æ–|X=ÞãkÛUù³æw¸ÚöÕ~Glù¥ŸVw¸ÚöÕ~Glù£Ýî6½µ_‘Û>igÀƒÝî6½µ_‘Û>h÷{¯mWävÏšYð?Ô¿U8uÎ õg÷Ñ·Ïy©¨œ¼íÛ¬mG§¥ËÜIô?ñ*¹3ýˆm¼Bý†òo¸Eý´f¥Cÿ§û“?؇ð¿ò0}õÿÑX~À‰= òŸÈZ÷ÝÇô .ùH<§ßòŸý÷qý —ƒÿó¾¯à©IP§>N_{õGý"¬þʘÇN|œ¾÷êúEYý”\ð¡þþº~Õ!iÎ/A¦ëOØs<ÿ£7OÕd7#MÖŸ°æyÿFnŸªÈfeÿ•ÚúTû`qP³>O|Tkú³gÉãð-oÿ@}KµßàX¿ÝÕìx‡QwùM¾ÈxwàY·S¢;ü¦ßd<;ð,¿Û©Âüÿ˜mwWü2õ*duÉçˆQØ8‡#Ž&ùÖOrª«–]½%dOZv3b,OTøÞïiËã®ÜÄØxfÁXÎå£ßjeUÿZ'­ú­d´[¦~Uȉ}± Bg9cå²ÓÚx¹USÂÈýÕ¶ÑVÉÊ›s?‘bUùW²:œsÊ3þQÿi1ð[\ÓžÌGM{i•eW¸ði‡Qá¼:b1SÂÖOw¦[ÅSѨ‹,•WµWÛ´}›SâjŽ;?ÃûQº§(ÔÙ>…-+ý4‘©4ðµzº2Û¢xU^³æ¦tö© øä?¶jkÙÕ $,Š9+a¬V±6Nyéâ™Ëò«¤U_TëÁÉž9}ô¹·ý›û:˜Šx&®c8»ODÚŸUT{Õ”w+{¤Æm=ws¨iÕWÚ½›NÉÅ?½k?àúìÚo|/~/ ß_ýT„/Çg½{.û¥»õøOaã³Þ½—}ÒÝúü'¿‚ð[Ÿ½«øh%xü—ÿò¾¡ýílý*‚ýÉÿ+êÞÖÏÒ¨/Ñ̼#˜ñÔ*ÃÞSo².ø_íÜS2æyM¾È¸àY·qLÎݰŸåì/tÿ©.½pyïjÁ>ð“õ‰IŒ‡8<÷µ`ŸxIúĤÆ|ߟÿ‹b¿y_ñJ°Àj@üOÉr¨öç³Z+. ß»xa{ÓôN!=ï‘î’G+œåUs•wU_j ×èf¨Ð½C†W´~-uDDñþå“§ãîüg޽àŠÝ1…Å\ŽsU1æˆ=²¤·Í Ϭš]«öÚ*.t6Y¥¨u-;š’=ý‹Û¢»§£#˜ïú¥Õÿ„ÛNþ ²?Ê ýå Áð<·Rr±\"Í%Òë|fÁ]•ä–œ^ÖZËÅtèîå–YÆïøÜ‡Ñšÿ~WïÂu_ڸܸe’ñ§­‘¨äL‚Û/µ$EOõ¢@ß¿8\¾«ô󦉟E:¼ºÅ¥Z]ŠhþA„âT,†ž’4íçåD–®}½9¤_¶s—údM‘ ¼ä+÷îbnÕzõSUUN³3Îf^Àd fQýìÝþð¨þÍÆLÆeÞÍßï ìÜe`*·ô£ÛAÁoi2ègØûÁ¿¤¦ô}’ð¬ïqµíªüŽÙóG»Üm{j¿#¶|ÒÏ€+»Üm{j¿#¶|Ñî÷^Ú¯ÈíŸ4³à Áî÷^Ú¯ÈíŸ4{½Æ×¶«ò;gÍ,ø°{½Æ×¶«ò;gÍïqµíªüŽÙóK>¬ïqµíªüŽÙóG»Üm{j¿#¶|ÒÏ€+»Üm{j¿#¶|Ñî÷^Ú¯ÈíŸ4³à Áî÷^Ú¯ÈíŸ4{½Æ×¶«ò;gÍ,ø°{½Æ×¶«ò;gÍïqµíªüŽÙóK>¬ïqµíªüŽÙóG»Üm{j¿#¶|ÒÏ€+»Üm{j¿#¶|Ñî÷^Ú¯ÈíŸ4³à Áî÷^Ú¯ÈíŸ4{½Æ×¶«ò;gÍ,ø°{½Æ×¶«ò;gÍïqµíªüŽÙóK>¬ïqµíªüŽÙóG»Üm{j¿#¶|ÒÏ€+»Üm{j¿#¶|Ñî÷^Ú¯ÈíŸ4³à Áî÷^Ú¯ÈíŸ4{½Æ×¶«ò;gÍ,ø°{½Æ×¶«ò;gÍïqµíªüŽÙóK>¬ïqµíªüŽÙóG»Üm{j¿#¶|ÒÏ€+»Üm{j¿#¶|Ñî÷^Ú¯ÈíŸ4³à Áî÷^Ú¯ÈíŸ4{½Æ×¶«ò;gÍ,ø°{½Æ×¶«ò;gÍïqµíªüŽÙóK>¬ïqµíªüŽÙóG»Üm{j¿#¶|ÒÏ€+»Üm{j¿#¶|Ñî÷^Ú¯ÈíŸ4³à Áî÷^Ú¯ÈíŸ4{½Æ×¶«ò;gÍ,ø°{½Æ×¶«ò;gÍïqµíªüŽÙóK>¬ïqµíªüŽÙóG»Üm{j¿#¶|ÒÏ€+»Üm{j¿#¶|Ñî÷^Ú¯ÈíŸ4³à Áî÷^Ú¯ÈíŸ4{½Æ×¶«ò;gÍ,ø°{½Æ×¶«ò;gÍïqµíªüŽÙóK>¬ïqµíªüŽÙóG»Üm{j¿#¶|ÒÏ€+»Üm{j¿#¶|Ñî÷^Ú¯ÈíŸ4³à Áî÷^Ú¯ÈíŸ4{½Æ×¶«ò;gÍ,ø°{½Æ×¶«ò;gÍïqµíªüŽÙóK>¬ïqµíªüŽÙóG»Üm{j¿#¶|ÒÏ€+»Üm{j¿#¶|Ñî÷^Ú¯ÈíŸ4³à Áî÷^Ú¯ÈíŸ4{½Æ×¶«ò;gÍ,ø°{½Æ×¶«ò;gÍïqµíªüŽÙóK>¬ïqµíªüŽÙóG»Üm{j¿#¶|ÒÏ€+»Üm{j¿#¶|Ñî÷^Ú¯ÈíŸ4³à Áî÷^Ú¯ÈíŸ4{½Æ×¶«ò;gÍ,ø°{½Æ×¶«ò;gÍïqµíªüŽÙóK>¬ïqµíªüŽÙóG»Üm{j¿#¶|ÒÏ€+»Üm{j¿#¶|Ñî÷^Ú¯ÈíŸ4³à Áî÷^Ú¯ÈíŸ4{½Æ×¶«ò;gÍ,ø°{½Æ×¶«ò;gÍïqµíªüŽÙóK>¬ïqµíªüŽÙóG»Üm{j¿#¶|ÒÏ€+»Üm{j¿#¶|Ñî÷^Ú¯ÈíŸ4³à Áî÷^Ú¯ÈíŸ4{½Æ×¶«ò;gÍ,ø°{½Æ×¶«ò;gÍïqµíªüŽÙóK>¬ïqµíªüŽÙóG»Üm{j¿#¶|ÒÏ€+»Üm{j¿#¶|Ñî÷^Ú¯ÈíŸ4³à Áî÷^Ú¯ÈíŸ4{½Æ×¶«ò;gÍ,ø°{½Æ×¶«ò;gÍïqµíªüŽÙóK>¬ïqµíªüŽÙóG»Üm{j¿#¶|ÒÏ€+»Üm{j¿#¶|Ñî÷^Ú¯ÈíŸ4³à Áî÷^Ú¯ÈíŸ4ÃUëø¦Wf±f·ù(pžì_AB«$N‘½Yíâ襸*ߟf<3î4ß­8 ~y¨ï‘OG—úŽù@MÃýø'ËWú -‘Spÿ~IòÕþƒ@²à#¾!~Ãy7Ü"þÚ3R¡ÿ‰SýÉŸìCmâì7“}Â/í£5*ø•?Ü™þÄ8Ï…ÿ‘ƒï¯þŠÃöIè)”ûþBÓÿ¾î?¡wÊAå>ÿ´ÿï»è@L¼ÿ˜ðÝõJJ€5òtTÓE  –¢6;膳£žˆ¿Á@s(ÿj2Œ˜€ÍÍÏ*']5å¯F±íR8;¯ç´ý—ÿtAç´ý—ÿtC…ç?zýsÿãÿ÷5wf:šy]Ëñ½{ök‘TÔu§ì9žÑ›§ê²îòx{âbü [ÿÐÖŸ°æyÿFnŸªÈA3­ŸøµZÁEÍÿ‘Vºnó«–šÏWZ±ÅÅBÌù<}ñP~­ÿè ÌYŸ'¾*Àµ¿ýô×bÿwW±æD9ßå6û!áßeþÝNˆïò›}ðïÀ²ÿn§ ðkþaµÝ_ðËÔ©‘מ½í8'Þ2þ±)Èc¯<{ÚpO¼eýbS¡øYÿ ³ûÈþ”„ÈsÊ3þQÿi1Ó£˜¾QŸ|ôzûIˆ/‚ïñïôUö+*¸vƒ@>Á:sÿDíªDq|í€}‚tçþ‰Ú?Tˆ˜ø\ü‹ ôçØ¤7Ó“œŸTõ35‰iòýAÈï0ªïØ×\æš$ùç+Sñ!Ìü^Çf7q4b"š+ªjù33Ó®œâ'MzÍ]¨½Úi/öZû{y©nT²ÒL‰ãŒV¹?¡TâQŽÜ±’é‹^!tU֊ɨª©¶ÒFõjþ-Ó§Ävçþ÷m_yAýš«.n·šéµ¿O­³VNèÚÜ‚‚ž>iÞVÕ1©ÕÛ5¨×¢uÙßÊTÐx5Ïlå9…Ì&­)»¤DÏ-êuÓ»X™óé Ê¡èf¦;Gõ_Ô?5uL6ª—yÌ,]%<ŒtR£|9¹åMúnˆvGȬ™e’‹$Ç.p\-·[=5LG2F/Š/·ÁS½ª37m=Ö½VÒ¥ziþss´C#¹ßOÒJw;ùK ˆèÕ~>]Ή¶»ñžhÄaëŠ.Óq×Iuˆ8Æ“3¤é<Ô‰ÑÚs𮯡¶RKp¹VAIKUòÏ<‰qµ;ÕÎvȉñ©Éš¾6x ­…`›Tçk\›*Åk¡‰ß÷™ *IåÚ“¨ôÉ6mšÞ¯jÕæck«d•Œ_óXååoâD ¸O˜ú«ÿÊÄQM?³½Túâ•uvk ϰÍD ªºàùꊊ­ô3TÑ¿ž$­kœÔws½±wjªuï3åOòký‚/?ô®«õJBØó>˨Ês+Ø+s3M¤Ló‘ÃÌ×ûò¿~ªþÕÆéþO¿Ò~š^kýù_¿ Õjãtá‹ß §ß‡é?M©sð‹¿»«øeæ!½€3(þönÿxTfã&c2ïfï÷…Gön2°?•[úQí"hgØûÁ¿¤¦ôhºö#žðoé)½d¼[âsìdž}Æ›õ§«|N}˜ðϸÓ~´à-øåþ£¾E=_ê;äP=7÷àdŸ-_è4¶EMÃýø'ËWú Ë€Žø…û äßp‹ûhÍJ‡þ%O÷&± ·ˆ_°ÞM÷¿¶ŒÔ¨âTÿrgûã>þF¾¿ú+Øq' „8Ÿá8 Çè~~‡VÅ5D¼þæùßmÚµ‰¶Ý¬|»r|{îMàÍËó NW‰§„«vå:é:Dé¬Lr˜˜å=BˆÿÁwÿ¿/ü3ÿËcþ ¿ýùáŸþ[/p%|M¥ýgþÿ‘MGþ ¿ýùáŸþ[ð]ÿïËÿ ÿòÙ{€ûâm/ë?ð·ü†Š½Ã¿‰ šˆÜùu7ÝÞZ)èüÓÜo5þ—ÒçíßÝËÝËãÞXŒÓLþâKYæ‰{¶U[¼ã³çì»h?.éÍ·6ûn›íÞ†düÇ:Çf¸¨Æã.o\4"9qŽ¡Dà»ÿß—þÿå²Máã‚4Ð]Ef}ôÍ÷w’Šz?4÷Í„åô¹ûw÷mÝËãÞZmñ{sŸãìW†Ä_ÖŠãIÚ#XžØ¦'Ðh߉¾“ˆÜ†Í~ú`ý-¦‰ô}—¹^wÚó?››~Ú>^ý¶ÙK [™â²|DbðUî×é:Dóá<&&=J¨üûòÿÃ?ü¶[ÍÓ´Òm4°éÚ^=Õ÷CçžoØvÛÈçïÉÌî_[m¹—¸Ü±Í¶§6ÏmSc0»¿LN±´Ç&>m1<¦TÐ+¼¦¿ê yÚj_¸<–èh<×Üo:ß³sÝÏÏÛ³¿Ÿm¹|;ú–p9^mŒÉoü+^ízLk¤O 옘UDà»ÿß—þÿå²è`·Ð6 Ža^ç¿CöšK_œö]ŸoØBØùù7w/7.ûn»o¶ëÞg™›í6kžÑM¼ÂîüS:Ç“LqÿLBšM×>Z5Jõ©iª¾ã{±æÛÑ{‡ç—eO?ÂyÃ9·ì¹½TÛ}ºí¹l‹”ç8ìŽôâ0îW1»3¤O ˜<¨˜ç(üûòÿÃ?ü¶^KU [-tvÔ—´JJxàçÛnnV£wÛÃ}¨ÆÑæyôQ…ÝýÍtòi5Ó_“Õƃ®ÚUôëÒë¾›{½î7º®¦wžù¯œv]”ñËü;9·ìöõ“m÷ë¶ÅOÿ‚ïÿ~_øgÿ–ËÜ ¹NÕæù‰Ãà/nQ3½¦í3Æb#_*™žQˆ …þS†ê¼Š«èïè‰oÑÓGËî_šv=ŠÈ»ÿ '6ý§Å¶Þ;ôŸ@5™ŽeŠÍ±5bñ•o\«MgHŽQ¤pˆˆåCç¸Û¨.öú›UÖŠ Ê*ÈŸE<ñ£ã–7&Îcš½QQJg©¾M|jñržë¥ù¬–(ær¿ÜË„ S j«Ý¨ä{ZžÇ#×ã. 2òŒÿ1È«šðfyÇ ‰ï‰Ö<üÇ9aòfê³§VÏŸbl‡~bÔ¹Û¢±"¬Þ0ß&E¢ „ŸP56ª®Tþæ´Q¶_–YUÿÑÉøËÄ ýÿ»C~Ï÷SLO§Oa£ò£¥Š†’ (7ìéãlLÝw^V¦É¿âCõ„LÌ⪽j÷º-ª•s^é(ª1[ÌïYf«´ò¶)Þ»ª¬9ŠªªªªÞG*÷ª•îóäÆÌážDǵFËWþ‚ÖÑKNåO²'ú΄‚W—mÆ{–[‹VoÌÓ¢¨Š½s>mTÑÎZ&n«9ûUçØœlß¾5©zíò,Mÿi¿aþLŒzšvÏžju}Â$ÙVš×DÚ_•Y&è¿K¸ ÌG„]¡ÄS¹ã¢žêi‰ô鯠Ѫ鮗áE7Àl©m·vΩ{;WÈùfsZ×H÷=UUÊŒj{6DDDCj†^½srnÞªjªxÌÌë3=²ª^ü™‰x½\.é­}ŠWUKSÙý órs½]Ë¿&ûo¶û!šÓ'‚iÆ¡cùâêÿº>áWÅ]æŸCýmÈ»òóù˹wöò¯È\pJ®mæÐ]³6+ÄkLÆ“”r˜Óóu䦀ˆ*Ì£ûÙ»ýáQý›Œ™ŒÊ?½›¿ÞÙ¸ÊÀþUoéG¶‰¡Ÿb<[ïþ’›Ñ¢ègØûÁ¿¤¦ô}’ðo‰Ï³÷oÖœZB­ñ9öcÃ>ãMúÓ€·à—úŽùôy¨ï‘@ôTÜ?ß’|µ ÒÙ7÷àdŸ-_è4 .;âì7“}Â/í£5*ø•?Ü™þÄ6Þ!~Ãy7Ü"þÚ3R¡ÿ‰SýÉŸìCŒø_ù>úÿè¬?`Äž€”{7¼*?³q“1™G÷³wû£û7XÊ­ý(öÀ‘43ìG‹}àßÒSz4] ûâßx7ô”Þ²^­ñ9öcÃ>ãMúÓ‹HU¾'>ÌxgÜi¿ZpüòÿQß"ž/õò(€ ›‡ûð2O–¯ô["¦áþü “å«ýeÀG|Bý†òo¸Eý´f¥Cÿ§û“?؆ÛÄ/Øo&û„_ÛFjT?ñ*¹3ýˆqŸ ÿ#ß_ý‡ì8“Ðc2ïfï÷…Gön2f3(þönÿxTfã+ùU¿¥Ø&†}ˆño¼úJoF‹¡Ÿb<[ïþ’›ÑöKÀU¾'>ÌxgÜi¿Zqi ·ÄçÙ û7ëN߀_ê;äSÑåþ£¾EÐSpÿ~IòÕþƒKdTÜ?ß’|µ Ð,¸ïˆ_°ÞM÷¿¶ŒÔ¨âTÿrgûÞ5ÂÓs¾é^Aj³ÐÍYYQ iµ\÷ªJÅTDNþˆªDÙ{ C—øJȳ îŒ4`-M{³^ºLFšîéÎcªU†Ú [è“;øÊ¿'_Ü>‰3¿Ì«òuýÇ*ø‡´_ªÏ¦ŸæWVÒ [è“;øÊ¿'_Ü>‰3¿Ì«òuýÃâÑ~«>š˜Õ´ƒVú$Îþ2¯É×÷¢Lïàs*üpø‡´_ªÏ¦Ÿæ5m Õ¾‰3¿Ì«òuýÃè“;øÊ¿'_Ü>!íê³é§ù[H5o¢Lïàs*üpú$Îþ2¯É×÷ˆ{Eú¬úiþcVÒ [è“;øÊ¿'_Ü>‰3¿Ì«òuýÃâÑ~«>š˜Õ´ƒVú$Îþ2¯É×÷¢Lïàs*üpø‡´_ªÏ¦Ÿæ5m Õ¾‰3¿Ì«òuýÃè“;øÊ¿'_Ü>!íê³é§ù[H5o¢Lïàs*üpú$Îþ2¯É×÷ˆ{Eú¬úiþcVÒ [è“;øÊ¿'_Ü>‰3¿Ì«òuýÃâÑ~«>š˜Õ´ƒVú$Îþ2¯É×÷¢Lïàs*üpø‡´_ªÏ¦Ÿæ5m Õ¾‰3¿Ì«òuýÃè“;øÊ¿'_Ü>!íê³é§ù[H5o¢Lïàs*üpú$Îþ2¯É×÷ˆ{Eú¬úiþcVÒ [è“;øÊ¿'_Ü>‰3¿Ì«òuýÃâÑ~«>š˜Õ´ƒVú$Îþ2¯É×÷¢Lïàs*üpø‡´_ªÏ¦Ÿæ5m Õ¾‰3¿Ì«òuýÃè“;øÊ¿'_Ü>!íê³é§ù[H5o¢Lïàs*üpú$Îþ2¯É×÷ˆ{Eú¬úiþcVÒ [è“;øÊ¿'_Ü>‰3¿Ì«òuýÃâÑ~«>š˜Õ´ƒVú$Îþ2¯É×÷¢Lïàs*üpø‡´_ªÏ¦Ÿæ5m Õ¾‰3¿Ì«òuýÃè“;øÊ¿'_Ü>!íê³é§ù[H5o¢Lïàs*üpú$Îþ2¯É×÷ˆ{Eú¬úiþcVÒ [è“;øÊ¿'_Ü>‰3¿Ì«òuýÃâÑ~«>š˜Õ´ƒVú$Îþ2¯É×÷¢Lïàs*üpø‡´_ªÏ¦Ÿæ5m Õ¾‰3¿Ì«òuýÃè“;øÊ¿'_Ü>!íê³é§ù[H5o¢Lïàs*üpú$Îþ2¯É×÷ˆ{Eú¬úiþcVÒ [è“;øÊ¿'_Ü>‰3¿Ì«òuýÃâÑ~«>š˜Õ´ƒVú$Îþ2¯É×÷¢Lïàs*üpø‡´_ªÏ¦Ÿæ5m Õ¾‰3¿Ì«òuýÃè“;øÊ¿'_Ü>!íê³é§ù[H5o¢Lïàs*üpú$Îþ2¯É×÷ˆ{Eú¬úiþcVÒ [è“;øÊ¿'_Ü>‰3¿Ì«òuýÃâÑ~«>š˜Õ´ƒVú$Îþ2¯É×÷¢Lïàs*üpø‡´_ªÏ¦Ÿæ5m&3(þönÿxTfãôIüe_“¯î>[µß=¹Z«-ÍÒ ¥‹UO$(å¦UF«š©¿wÆda6h-â(®¬4éΞ¾óTÉ¡Ÿb<[ïþ’›Ñ§hý²áfÓ,v×u£––®ž‰¬–[Êö;u]•<©¸ŸN¼€e–("|ÓHØãªç½Ë³ZÔꪪ½È kº£¦vÆÊë–¢ãܲ¬÷zxÑŽßm»ú.ý:øšü¼Ið鯆m}ÓˆäÊ×±ÙU 9®NŠŠ‹/EGIõ\pÃðó„\CûÇÕqÃÃÎýqï[Iõ\pÃðó„\CûÌ•/ü9ÖvIM¯šv÷OËٳ螉ªîäåY7߯vÛ$ƒXµêŽ™ßŒ²ê.1pr¹Z‰Kw§•UQ7Tô^½Q:ü†ÅMUMY jhê"žïË$oG5v]—eNè ~ [âsìdž}Æ›õ§«|N}˜ðϸÓ~´à-øåþ£¾E=_ê;äP=7÷àdŸ-_è4¶EMÃýø'ËWú Ë€¤qåÑí­¨ÅqýdŒ‚E_sjb}¾’mœŽyÚåÝÈôo3ЍœÛ«\ˆ‹Y“1ò†ñ™õøÕDøF^ÕŽŠUµQÉN鑦¥¼½æs1Q¯M‘\­v;0Âe–¼~2å4Q×TÄG¯§±îŠ*¹;´F²è–£kÞŒi"#uR¬69œåjSOTŽ©UF#×hY¼ŠœªÕß—oI¿ÊMë^må[áÛ{©ñ+>S”ÊV¶XhÛIN棶ææÉ'Tê‰Ù÷/^UèFú{ä°Ãi^—YÔ[­ö©Ï|’SZØÚX\ª©·4’sÈýÓ™US‘wruôU]b°.xrÓ7—Ò«4ÕtÌåmeÊ5®]ÓwóN®årªwµmÕdUCœæ^ò,Í8XªìöF”újÒ}Ë>ÞYz¾5i ·]åF×üýëI¢ü=Rv¯{bÙ̬½HŽV®èÔ°§6û*n‹Ñt]÷LtÙ·•wSœ°ÐÛî¸ý+¹ÌeºÔŒÙvæçŸi—Ú­G.éá±Ðú:*;u,t6úHii¡o,pÃ1ŒOb5:"|‡ìC1žñÕÌü E?Jf¯fë*Œ¦ˆùuO÷ésª«„ÿ(^¡6FfºüêZu•ªúj¼²¹Ñ»ª¯;b‚7Gºn»oʽÉÜä¹ÔŒ’¡•Þ¾ÓI"57‘(g¯z//TE–Xútjo¿TO ¶:*íÿ »K{ä\¦Žê#þÛÌŠrÜRþ'tέhµ³‡Ê=¢ßtu%ežW'3v^y{V*lªˆ¨Ý—™«×oJUÂ<¬Ú||TÙ®#”ã¿~y™uÔÑúKÞæ9²/NUézªx"­®’8æÐÍ_Ú­s\›£‘{ÑSÅ·<áo‡íHí¤Ê´ªÅ-LüÊúºZ4¨W/6îY!år®ïrõUÝvUÝQ FÃEš¦)Çaf;hª'Õ1ÄÆ¯)Ÿ™W¥½é×:«>oŸê¦?u©ªÛ²£ó¤‚­Ê¼Û'›ËË*/ åÙ[¾É¿q$œóÏü–YylµwœÞñº‡;™ÖFË…3Sw/*&ì‘«Q^åDoTr©¾ŸÊÁ•+®6ûìù¦%O¢XÖYoT±7tj¬Oåš™¨›;vr³ª#•{Ž“íîCUì_ŠkŸ›_“>mxOšeƒwzÏ£‡cªÀ¥|:ùNtÇT*è±=T··ÈjœØYVé¹íU/w×]³ U^ä“v§òÕK¥±O&†FÉG1í]Úæ¯TTTïBbÅz*ߟf<3î4ß­8´…[âsìdž}Æ›õ§oÀ/õò)èòÿQß"èÕ3-YÒ½:©§¢ÔLÅ1ŠŠÈÖZxo7šj'ÌÄ]•Ìl¯j¹zn†ÖróÊÇf‹"×]#Ǧ™ÐÇs¢uäjnæ6JƱ\ˆ¾)͸ÛêŸá§ü¡ôÏó¶ƒýèú§øiÿ(}3üí ÿzUOø4?á;9ÿ½GþäÀñ¡ÿ ÙÏýê?÷ Z¿ª†Ÿò‡Ó?ÎÚ÷¥dÅuÇEiø¨È2_ÂbµLµ]sò FÓ¿v7nYNUßâSÿƇü'g?÷¨ÿÜø4?á;9ÿ½Gþä )õLpáþP:mù×Aþô}S8”›~uн+_üðœÿÞ£ÿr?àxÐÿ„ìçþõû,§Õ1Çù@é·ç]ûÑõLpáþP:mù×Aþô­ð*zxc{Yþj«§s•½Š»ì›F6¿h'f²›˜ú)Þ®4Šbyk<µìŽ}ºiÃ]Y[»O$ƒÃ¿úO£1C|Ê©ió,©»9+k`_6¥ÝˆŽd0*«¯2¤EwvܽP³à%f™¾;:¿8œ}É®®ÞŽÈŽQ‘“ÛµEšwh åÀ}â‚#רgººŠ¶ž;[ÁÞÛcð8û9V&©®ÅÉŠb'ŒÑ3Â7g«]5ŽQc=f?EtMÚcIŽ=ë»KUM[MeDSÓÎÆË±=ÉäÝ®k“¢¢¢¢¢§yú•ÛÉõ”×åœ#àUWJ‰g©·ÁUjçzïõªz©b…©Õz6Äßú½ÛlX“ét|*ߟf<3î4ß­8´…[âsìdž}Æ›õ§oÀ/õò)èòÿQß"èOÔ-`ÒÍ'¢÷CRsû;òr6¾µ‘É':ª7’=ùߺµÞª/F¹{šª¸­×ùAôºé ݤ:u©š˜çlÏ`ÅêHïgK:1XÔw3Ü‹³š½6ê|3qMÅ]á&%Á=\TΗ“·½f´4¯F°+yÑ6å]ÑWżÖb³¬·;¸¬EOíWL{er›7+ù4Ìù–È]vã½Xúˆ8iÁ˜‹*µ”ïÊÚéèªäTjû< ª&¸¼·O/»¼ÅWJÞ]¦¶g´*äÝ<#syÕQ<6ÙWªTmfC\éÛ_îSï{œ5èù“è[U(^e•íÕÕ\˜Ç¾ºç޾ZFî×*ï$J«¶íåEFõUë¶Ë´Í¦e¥¬•yQÞ…<èÉ\ˆ‹ÕQªˆ»¢õEBT6Ë@Ÿ¨ZÁ¥šOEçö,v%ääm}k#’NuTo${ó¿uk½T^r÷5UpXºùD4’¶i(t—Ô=MªW¬P?ÇfóYˆœÊ²ÍȨÄUÙ\Œ]•7õvqñÏÅow¹Õ˜WS1ìkêoÙ}º§_¬«wTNž“\îåé¹®ÅçvtÅb(¢jªcÛ+”Ú¹_ɦg̶`¨ï×>;_Õ1pÝ‚Dz¤tÒeHéU»¦Þ’lÅè½û§rôî?vñ-Åý²«žõÁ•5m3w>×Ñ:F¹WdÙnîøÑ¹wߢ¡FÖd5Αµõé÷½Îô|Éô-ˆ*…”ÁdW¦²h&ªéôF®¨¹ÕØŸWm‰S½<â.®MÕˆŽF*nq9 Àè¡Ó­W°]j§r2:%¨Zj·¹QU)æFJ«³\¾¯‚›«‹8ªwìWG\LLz–j¦i&x¼ s7Êï–Ðÿæ¿hFtÈæo•ß-¡ÿÍ~ÐŒ™±áøÍ5“ð†YûU§SŽXð‹üfšÉøC,ýªÐ:fãˆm[©ÐÍ&¼ju68ÛÚÚ_L×R:«ÍÑRiÙ7?#û–D]¶ëíCuÆoQd˜å«"ˆÈî”0V±¨»ìÙcG¢oãë’=¸˜â“ˆø£¹²:úZübª†–¢Ûd«b­#èÞÆµÏj·•í—µ†oIUv]ú+vif¸yâçK¸…¶ë5K­C"|Õ*µU•±µÛsÇ'*2fí²¯/¤ž-Dê¡ëz–¦~“ôØsÉáĵ·HóZ­4Ìê¡¥Æó ˆß|ò£#·×5Žk\õÛÔ—ÐUWf«X«³y”èçõ-Lü'é°¤Ü;ð­…ñ)ÁÕ¾*õm¯(¶Ý.Ii¼ÆÄW3w¢ö3'|«—}»Ú»«U7r:·WòëYLÙÍb|MÊ¢‰˜çDγÇ^ìÄpêëå9x*nMÝmsŽ=ýŽŠG$sFÉ¡‘¯íG5Í]ÑȽʋ⇣˜ø¶»ñEÀ¥ÊݦúÇ‹ºý†£¹($«#{ª"¥ZtÙ©²ö2&íEjrÆŽE.¦Šño¡úïÉGˆegxÿ‘®Ím5jÿ¢Þed¾ß­¹Ûxì|ålfa•Qð»:^ÃϹG•Nºk»Û¯ xk-õœ]gvxUÕ)DY@a«œKh¾ˆ²H³ÜÚŠ ŒldžåS='®sæµصy‘=-÷vÛ£\©¾Êdá0xŒ}ر…¢k®yE13>ˆyªºhj!'œÑòqAcÎ&¤Ðý>»SÜ-¶ºŸ<¿VÓª>9j˜Š‘SÆô]œŒÝîz¦é̬MÑXä_ß9âÓˆ~-ò:Í,᧯³X*Z±UT£ÚÇRȈÕuTû¹”¬ß›ø7s*tG;¹~ýGàÞÁ×9ýÿ –ŠõW2ÙMÂs £‰n”¿Y¦çDvËöÏTG;»dDØë/³ø]•Ìp،MuQM»113L×1Ný}»®±}¼µ˜›õbmÕM˜òb'Yîè…¤òhûÑ1¿®®JZB­ù4}蘿ß×?×%-!ôcBo‰Ï³÷oÖœZB­ñ9öcÃ>ãMúÓ€·à—úŽùôy¨ï‘@ôâYb‚'Í4Ž8Ú®{Ü»5­Nªª«Ü€{" lâ“KtEì±].ß³ƪ[q;$kYu«•X®½„hçF×í²=è‰ìßeBÎ8Ô-}É®:WÂM 6j8ßMj=d’Ž‘îk~µnåTI§Dw¬»·Å6NY FøjÒÝjÜìvd¹e5Hçܲkš­Mʶwÿ "Ë"ªÇΪªæ±Q½w^«ÚÏ~Ìk‡Â_üØå[ÓÑÝÏdGnsår§¯ÜÔç©ã?_é_&IÒh^1]±mvI[]~s~¸­sªùQ)ÕQÐ_õµéꋚÁø?Ð,&x.²alɯ‘ò:KÖK*Üë&‘ˆˆÙ²ï\ˆÖ¢r1¨œ©²!3ƒçüïnóÜò©‹×¦Š?6i§Ï§ÿTËwgfÏ(ÖzåùÓSSÑÓÅIIpAQFÔkƦÈÖ¢tDDDDD?@|μe–fuÂæ€ê3ÝS“i}›Ï\þ×Ϩ#Z¤‘ç#ûjucÕyœ®êªŠ½ûìJ`ÉÂcq8 ünåTU×LÌO¦j¢šãJ£Uz·a\ZèEÑÕºEªi©ø¢»šLc;¬{«£nèœ”× •wDîGò±¨ž«””to-Õ,4ç!¦¸à:‚Çö2ã}ŒÒJéO/©:.Ë˲£œQ»u7CEÕÓml±¥“P1èëßG] –Ê<$†fúLT]—n­UDæk“¡ÕösÂÖ;TYÎ)ñ¶ÿ:4ŠãÙz§¶ZÌFYE|mpŸR‚”cºÉ«\Üi±y¸Ü³Í&ý…³4†™óܬ,G/,w&±ªé™Ê­úênïEvG*£r,WÛ6Of¢È±Û¥-Ê×r•T•”²¤‘OÓv½ŽNŠŠ‹Þwܳ4Âgjqx*âº'¦=“â{%¤¹n«Un×K귚©ùußDxH³ÅYSo{)/Ú…<¬[mŽEvÒ29ªÚ™šßb®Ë¾Ír"¹¸ØÌf/³V'\QE<ægHïÖõEW;´Æ²˜õ׊áæŽ™Ùõöyn×V[¬vºuª¸×Hœ¾„q7dnüÍÙÒ9UTM÷TB¿^øÍâ._4§ª§Ð\nfÈ”Ò-fMRÄ{›Ê²"5”Ü܈ätj×3=)St7!áÏÒZºÌ•$¬Éó+¬¯¨¹eWÕeM΢GµèÙywŽ5ÛÔo†ÜÊí·%Cƒí'…Û÷j›%;”þ}Q­SÝLð>³Ù Ö+¦<«Ó¯bÃx3з}¶åŽ£&Û<ï"˜Œ%ùÝ›W•O¢y§Iíc]ÂY½ò©âÐ4sŒü?6¾.œêÝŽ£Jõ.D÷ ý;[r;tI(êUÉÚ®EDNŠª‹Ë̉¹bˆSô‹Nµ—úÔŒ^’óD×+áY7l´ïTÛž)¨øÝ·‹U7î]Ó¡ÛuYø/­’Ÿ=–ó©š'º2–ðÔIïX»7Dk*U¢­Ý9ü6N¬ôcwyÙ/ X ªœ&.y’fv·ªý'Ý*dV5¯Úw¢¹ŒvÛò¢õߪ»d ›W·ÙvËþ ó"y})ã»è™ìÓ‹7 ‚¹ˆãÊ:Úò» §u-MîƒBñ:‰\½•·û³#©¥sž­GÌ×òR¿‘"þ Zö¹ÏUUÛ³2˜O?áu´÷ÉpÅɯÐön’ó’ÕIrªžF"£$rJ«\ˆ©·$mDåjí»QRlÏÙÞÞç¹äÌ]½4Qù´kLyôgýS-Ýœ›<£Yí~tÔÔôtñRRA@ÆÇQµÆ1©²5¨Ð3¯e€]ŸpÁ º—+ªò½3´>¹\×¥}EV×µUZîÚcÕQUWªª/MÑvBQN‰ÀÜñ¸[•QW]31>˜yªŠk*UæÑ§Y)[GsžgHG+–5]щ¶ýÝ}£CÆÂGM¤\1é>‡Þë2 >¡»ÓÕ×Òùœþyx©«c£çkú6W¹wjuN½þÓ`Õ½Áµ»¦Å3úZê‹}%s.6޾jG¤ÍŽHÑUñ9®Tå•þŠ®ÝËàƒCÆÃy1¥Ü$è¦åqæ˜U¢ïÖ($§ŽJËÝ]SצÎTd’+wÛtßn›©½ê^šâz·ˆU`ù­-MEª±ñI#iªå¦“š7£Ú©$nk“ª{z¦è4KSOj£|²FÚš¹jdæ‘ê÷*É#œåê¾Þ‰²&¨ð—£zŕəçTÊ›œGMÍM|ª¥±±=¤q=­Nõ]öÝUThxØLàÑ´“G0mÆêqL–ºžßW\û„­¬¯š­ë3£Ž5T|®s‘9bg¢‹·zø©¯êï zO®º<ƒPhnõt¾g™Þ*iØùÜþ­‰íE]ܽW¯w°hxØK Ž4{A4ëB©®”šyIr§Šîø¤ªmeÎzÍÝ9­YœåoG®ûwôöž±ðù¦šïîGÓ†åQîœyŸ™Ý*(ù{nÏ´æì^Þà™¶ûí²íÞ£CÆÂKW¤5i>†Ü®}>µÜ «¹ÀÚi䬻TÖ}m®æåjJ÷#w]•U~ˆeµwE0 p²QãúƒE]QIAUçyÂzG¶NG3«¢sUSg/EéÜ4zËÕU[7«UÛ2YÝýë¶ýþÓrÕ.Äõƒ“ Íc®–Õ,ñÔIl´¯{˜»µñª;mö]·ë²  À¦O'Ǩ´”9]Ís\ÉàÊ+»HÕ¼Ò*oÓØnšAÃŒeU×ˬj%êÕYB´Œ°ßï‹]CJõ{“B×5×#cäEU_EÎÝW¦Íñ˜¡ê>·éÆ’^q{. ß=Ç\ºªj;}\ñ9),lG*M?©üÍFó*nª»tk•7Âq11¬¨ kÇ–M¼Z0k>'tÌóŒ‹-·¶t‘ÑîäI$+•UcöÙ®_AʨˆŠ M ˆ4cTu³9¾×Û5CA&ÁhéèÒ¦šµ÷†U¤ò+Ñ.V±6^Us•yºm¶Ýzj9%g¹ŽG{ƒ ¶à-ŠÝW4鮓I[UrcQ“nƹ¬cöEÙÌkš‹öÀX åEu%–áUldo¬†–Y)Û#UXéQŠ­G"**¦ûo²¡èî·çšÇÂm÷S–Zv_¾òÈ$ §úÌP²EÍŽU~û}mUª‹×Û±÷p±®¾§ý`z­j ¢Í0 “m÷%¡El,z½#Zª¾1?uEÙS•Q}ÉýCi©mUÕ–lÎå@¬_µ‰ÑGÛ|±¿ú@•¸FÔ<ƒTø|Å3\®äµ÷šÆÕÅ[Pæ1‹$‘UK*µˆMÚÆ¯DNóÇ%=Æ^³J‹M]E5](ê™$:7#[W?VõÛ‘^iÞMêéßÃõe†«ÑŸÉ«íÒ3ù+Ë«ø·•ÖL\HÚûÃþ¢Û[È÷ã7#jwºHà{ÚŸ÷š€et‹ Žû£ØfQS;ZÚìnß[,’;do53år¯vÛ®êD×n?xl´Þ&¶&Ks®¥¦• žéEkšj(Þ¾¢&îN‹²µª‹·MÈ®í™]Éu âÏPöL¶H,Ò=‰º¤ qmÍ_‰cGµ~%?}-Ï5~m°iöŸpN—^²ÇnžãÒÓSÜ™,H¯Ñ½æíUÊõr»uæÜ}Ykpi5Y2+jÛŸr¤m¯–Y+ckÈÈQUÏvܨÕTôº.Åq»ñ!ÅŸÐõV¡ÙøSe/Eêß ÒòÖÜŸLÔW,‚r½ŠMÕ½›—¯NnóòáòPxBáƒ,¸k5©=W=ÊÛEO]îX¥lmlìÝ­Þu^½„UÙ{×¶ñ[¯xM. dºÍbÓlfÿGçÔö»=’*É|ÂFnÅšyÝè*±y—•U6^¨ÕôZ­YÎlœBð;”g–:I ¦ºcóW:šW#ŸO5$¼òFªü¯Û;dÝdÜÒ¦â"÷pÓ¤ºu¥[ާçí ®Ï6{¨ÙI •²oº"7³*»¦ís—v±È|#sN óŒ5W´FM|´"{[5‹·Æ³/úÈgAô_T-ú=`â³F²ŠÛ¶aÕUÓÏÔ3´†kdNV:š$ß™ËËÎõb*n’z=¨¯‰év'~°{eƒ*Ë«ò{ÔQóÜ.•’+=Cº¿‘Õ£ZÍDßuUUÀê·šc¢÷ u¯<¹\)ê®°ËQM-®¢«š8ÜÖ¹Ubc‘6W·¦ûõOjnÐMwø€Áá˱y{ ¨¹aº[$z,Ôuc½­^ª×í³“Ø¨¨’HÞœçöQÃmùÖ0ÚÆÛ.}¯`•”î‚o­ÊøÌÇuOJ7míM—ÄÃj¶°Ú4’žÝQuÄòËïºo•‘³´º¹ñr#UVDj§*/2l¾=}†ú‹4«ˆF¬ä5Øõ·N³ëÐÒyßäO2§™9šÕdnW«•û¿¹ZT‘ï7/q¬õ×0¬®óij|ÖŠ.Ö¢~F«»8™ºs=ÛlÖ¢`šÜygÍaÅl™St[Uñž=Pêu¯Éq¯2¢ššm·‰eíõÄ{Z­M»–Oˆ¤ôõuUÒO$Àöɱ¹Zö=tsU:¢¢¦è¨\Ï)–±G”ê5³H­JÕ¤Ãâóšù9z¾º¡r1ù,‹“¹}i^ŠžŠG\jŽ´CI“düÉâ³=Ϋ"_;ª~«+²ì©Ü÷«[âœÝÀx ãSs Í´K?§Ÿ%‚§«Z[Û»I+©Õ›I½TŠª’G²r#ÕÈ®nîvý,Ç“[ÞÁCøfáúm6½yЭ2ÐÎ µ2ǧ˜ä4k-‰ÉU]"$••Š’5Qf›ng"*®ÍèÖ›š§“[ÞÁCøfáúm9w…ßòü~òŸeM–Wøÿ7¹e2)ä—ÿ$Í­ÏÓ¦ª=ºŸ ½*Ôù§WFÁÎGØ|«¸Ò2J[}tp·~d¬³Uurªl­•UÎ^¾ÅDM½?²j/•B‰ÉK>)]4‘µÒ6Énz9vïæbrªûvé¿°|Aªç9†¨ýïÿ©ðÝ9Û«ÐèÐ9Ïôÿò˜SÔrˤ5’öOÙÍú{˜í—ªs5z¢ûQ~E>ϪOÊEðÿ…jÿÞžgÁî>9blOÿír¿£ójô:sý?ü¦±i d]«ök~…^Ö7uèœÎ^ˆžÕ_•EF§yRëættØUeͳ‘بQ±ª¦Û¢ÈŽDë×w*§â=}ïqqòñ˜xï»ãáÔôSW¡Ñ€s‘Ö+LŒóªÚú8¥o/h•VJ>TjªõlJ×¢ª¦Ûíº¢§ú¿†¯)fæ6ÿ­ÓZYÙr9¯Ë* b£‘UZöÒ1Èåðê‹ßÑvÜ|HÃZü£4ÃGÑ®jõDAðʧäÛ«Ñ£¢’I1¾i¤k#cUÎs—dj'zªø!¤äú颸c_ôSªØµìkØÏw&r"ì¼±ós¹Qzlˆ¥O&n·å‹j6½ÐÌÞÕd‘Qjî]šªzNol±ó;}Ó¯.é×t°y(´Ö›²ú(Õ<šá³%ó jz>gø+yÒnTø—”¬d;+…ã‰Í&¹ê·j¯âaO‰«äÛÓ¾Rn_åá’X(ò›žE4-UVZ-²=Éö­|Ý›¿;—ã!,ŸÊu¼T%ŸH´VjªéšîÂKS¦zª5ë·šÓ·w""5Ê©/r9:tq>b~Oþ±V£¤Óé/u ºv÷k„ó.ʈ›vmsbðUß“}Õzí²$ߌàØVOæ˜nd°ÁÊ­ìí–øiY²¹\©´mDÛ™U~UU+÷Gcrïɰ—qGMÊâˆôQÎ;&‹¹òªŠ{£_kžòRyJx“c¨+™_‚Yf‰a™³±lQ+_.ÎG7e«zlÕÝ6Täow§éÈzeä¾Â­Õþîë6o_—UË,“OGIÏK®W¢¢É72ÌõTG+•‹»ûýÝxc·ù—‹œ>[E[sÑj˜¦g¾®zöÆTà­ë½rf©ía±3ÀlpcXV9n±ÚéúÇICNØcæ]·r£SÒríÕ˺ªõUU!/(½<ÿ²ÿiÒ–¯>P/z.yÿeþÓ¥4Û5r»»Aƒ®äÌÌÞ·¬ÏŸ.qb¸Ž©ö2^Mz&/÷õÏõÉKHU¿&½ûúçú䥤>ÍDÀ­ñ9öcÃ>ãMúÓ‹HU¾'>ÌxgÜi¿ZpüòÿQß"ž/õò(€ S¨™~UƆc[§âáeÑ+ Cèò[í2º ²š¦*¶JW÷­*z¯sºúÉ˾{ŠÍEȵk3¤áG2(ªîùÖ ^èݺÙmŹÑ}çÝÉßÊäEôål¥„á˜æâv¼'·6†Ïg§m5$åw+ªª¹z¹Êªªª½UUU{Î[án'gìýÏÀUÿ‘\qŸÌ§¯éOGTqê×e€Áøùñ•ü˜õ¾¬{±âV:kµÓÛmvØ[OIINÄlqFÔ舟ù÷ªî«ÔÈ€|Í]u\ªk®u™ç)Fœ U~5´Tw*9í×Hj©*¢tÁgV·b<ЧQ6zꎉéˆãÆ5a‚‹…·:c©wÀfj@›jÆkšq_Öèö”dµ¶-(Ǧu&i•[Þè§¼ÕµU$µPÉã&É,‰è¯2¢îÝ›6k‹mPÊ3œ†›„ºÏI”ߢe^YxÎclEÙ_»Ñ:M2*5­Eßguåçk’@Ó½=Äô¯¶àxM±´‹\]œ1¢ó9Ê«»¤{»Ü÷9UÎUïU9‡„]·ø»b08¿ò+Ž™O_ÒŸ›ç™è×c€Áøú·ëù1ë}x~Šàí'…Ø(¬ÖŠrSÒRDŒc}®_9W«œíÜåUUUUU3 1ܹ]ÚæåÉ™ªxÌÏ™ë™Hb"#H•@M5=e<´•pG<±ÑËG1ìrl­r/EEETTR´+2293<=—+ΆÞ*œì‡;iq‰år/ŸÒtßÍúlø·M·ß®è­³gçSMOYO-%\ÏìtrÅ#QÌ{›+\‹ÑQQU’l¾Ôc6[œ4ëDüªz*²c¢z;µ‰ÇÄaèÄÑ»W>‰o˜ÎMæxý¿*Ånô·KEÒÔÑÖS=ѹ:9ý©ÞŠŠ‹²¡“)•Þj¸1Öô¦ðú8ôwS¯55xíÂi»4Ç.¯êªú)ŠÄlIÓe]ÕU{G-Ü>¸ÊsL6uƒ·ŽÂU­ƽÝq=±<%»n«5Ís€lVÀ™¾T|¶‡ÿ5ûB3¦G3|¨ùmþkö„`tÈå¿Æi¬Ÿ„2ÏÚ­:œrÇ„_ã4ÖOÂgíVÓ0 â/GrÍsµØp*Lɶ<2¢¿µÌ …®JËÊX^ž£^ôÙëº.Û/¤ˆ¬vû¨Ù&žiþKžW#V vÓWt{\½Äé9~UåÙ:ª©ðécxÔ=0ÅóËõ‚+%nCk§¹¾ßJÎ6f#ØœêÆ.üŽjª+S•U[×mÖ°ñr©ˆàÍãx݇°Ðbø½¦šÙi¶@ÚjJJf##†6§F¢çÞ«º¯U2@˜à 6a†âÙþ9]ˆæ–*KÅžã¡©¤ª™j¢¦éâ×&û£š¨æ®ÊŠŠ›šæ†éuFŒi͛ɖÕä4–‰geºz¨[”ôN‘΂›¢¯2DÅFs*î»w56jo„OÅ>eŸéÖ†d¹þ›VRAxÇbŽâæÕSvÌš™’7·bwò»³W9¨¨ŠÔÝU)/tLÄ¥°cqœ†Û–ãvœªÍ/io¼ÐÁp¤3Wš£lŒ]ÚªÕÝ®NåTö*™#Ë z×íÇ®T¶{¶ªc1×ÖJÈa¥Žã³9Ï]›»ªæ¢ªôUDE7ð…³ÜŸ‹)²šË—i† Ki§™Œ§¾ä7©fŠ®71¯óx²Çʪ¬T]×™ª©ÌÝ•dœ—8¢Ä-Ôº“tµÜrHØô¯©¶@èi¤w;¹y9{·TUDD]3ÒI1ºYdkÆ«œç.ÈÔNõUðCgÍðÌŠåQgÇòë-ξ’&ÍQKG_ÓC—f½ìc•Íj¯rªl¦µ«:¦Zá ®“SlS]©lòË55;k§¦g:øh¼¥CrD}à ‰,k+·ßfÓs¤h½Ëõºžïcýª[‚×þ-ÚÏr²f–¶» Î1§èËý H÷¶=÷ì¥g3UíÝ]·¤›s¿½¨¡4ªì›”³F«5[X²îù­Y ‰ÐÝä¶P㸤¬£¬cÆ==NÊåUkÚŠŠŠŽr9Qˆˆ²¾è^ºÛ³›^eªüK]rz{3¤u=ž†Û,îtnyÒ5ÚM‘û¢+wED^c|à7I.yE×"²åYÆ1O}™g¹ZlwvÓÑT¹\®r+79ª«èól›ìÞP"þŒc^kˆd•×Ëb[¡–:úêÏ:ž¢ZgÅÎ|»':¤³ÈÝþ#rá!ÃÄ?¸{ו«‘ÁvžÄžJ—»ñløÉ£áÛG´ÂùE’àØt6«•ŸÜ(§Š¢_J‘eí\’5]Ë#Üþ«#‘^»"o²"]¯ì™-×1´ãt—Ëâ1.5ñD‰5R1wz¢"&ß ³×¥Ÿ5׬ÕK.u<ìgù’É3í½Š”èZ †ÖËå‚çe‘[p£š•Û÷m#¿ùŸM= “MIET;žgÇ5dwµÊ‰Õz¯U?p*Ï šWu¿p…6êÎ-w²²²[ ”µ´ï¦¨l2ÉÚ6VµèŠŠŽ‘Uª©¶í0˜F/ÇVƒXÙ¦˜•“ ϱër,k•uc©æ¦‡}ÚÙ²1ÊÖ¢íȜʭD.ÃôÛUsÍ2ʱ'ovk”™Z¾6QØ£ìâ¶Ó+6=ÍEsÑéΊîmöÎB5Ǹ%Îè1öiµ÷‰ü¦³Oaæ¶**RHúw?™`}Gh÷,jЍ­åå]×djt-€8ѽÁô2“!¶`î®e»!¹¾æú*‰Zøi\æ£{8vj9DMœ®^‰ÔÊéF’áz-‰· À¨ª)mm¨’«’z—ÎîÑûs/3•WíS¢t7 µŽé¦Ÿb7ÛžOŒa¶‹]Úòç>áYIJÈå©W;™UîDÝww¤¿Se¢§…­ ®Õ `¹`tµÙS’YW#ç¦YÑ6íûªÇÚlë¶È­G"#·rÊà q±ïRÔÏÀr~›WÉ­ï`¡ü3pý6“Wõ-Lü'é°…|šÞö Ã7Ói˼.ÿ—ã÷”û*l²¿Çù½ËN>cH@¼ù@½è¹çý—ûN”°Åyò{ÑsÏû/ö)½ÙoñÜï­ÿ+ŸÄ×Ý>ÆKÉ£ïDÅþþ¹þ¹)i ·äÑ÷¢bÿ\ÿ\”´‡Ú˜U¾'>ÌxgÜi¿Zqi ·ÄçÙ û7ëN߀_ê;äSÑåþ£¾EÐñ ­–´¢ó©7¸¼æZHû e*£® Rž»"ªs;½Q•¨çl»lI9× §ÓÇŒ ?FàŽZŒgH ú/Écsw‚[´Ñ¢[¢vÿm_Ú§z+d‘6éºk³|ÊÖO»½òmÓ3ß§(ï™Ò#¶W-[›µÅÒËð¿¤w½3«ï™Ý[ks¼æá&C“Um×Φô’_äÆŽTÛ»™_·EBdøÃ2Ì/渻˜ÜLë]s¬û£²9GbYnŠmSSÊ„öÐõÇK(õ“Lï,õO¢¬¨*-uÌ‘ÌuÂ%禾—£"5Wnª›§‰÷ðq¬÷mXÒ˜ìùÄupg¸<‰åPÔÃ#긷k'W=™f­•vîsœ›"l«¶•òïr»è?X¾3ðíiŽŸ¾1­DH/Q"û2ªmÌç·ëMÝUQ½²õÙNÅàhªÂcjÉïO‘wY§²¸Ž1J#ÓÖÕf–7¨ñ±Î=‹œ>‹h@FµjÖ5¡šaÕ,­\ê 7jFäI*fr£"…›ôæ{ÜÖ¢øoºôE+× zsY¬·­aÔvógÚ£V—ÛËWuJ(ºÒÑ3tEFÅ‘«ÜåVõF¢Ÿ?]nâGN¸k…[WbÅìï2‰»w¼”îTþS¤U{£™+½žNáhª¢-äv'œEu÷käÓééÿKs•Ø×[ÓÝà­Ðj:±¦XÞ°éýçOršh䤻S>(ætH÷ÒN­TŽ¢4^çÆåG'ɲôUCnÛîa®ÓzÌéU3¥Iˆª4–…ÁN­eÞžÜôïSê v¢i•¸ c{“3eu-Rrz<¯›÷«á‘U}‹RO«ºh/86çNüg5t8c9UöÏÞŠ³eÝŒ“ÖvÝ*zR®÷\û#eóÊ6‹*µ§Mj*ˆèª8Už1Ù0ŠblÍ‹“@$ ¡ë¦­Y43IòMR¿+] މÒûe©©vÌ‚øß#˜ÝüU| ð§nŽùžÚ÷nÜÝ®(§œ²/i¾EŽcMÔæ:]HÔzŸw2)¥‰#’›™>±DÖí» {'"ú®sÓ}‘&°Œ3\ÊþqŒ¹ŽÄε×:ÏÙÙÂ;!,·n›TEò€`.4}kÒl[´Òó¦ù"9´÷8š°ÎÅD’ž¡ŽGÅ+UQvTsS~Z®or©ýàÓ[/Ú¡‚]pDGG¨zi\˜îLÙ%ITö7h«‘Q­Ý“rI²íÕcz¦è¨«»•Ï>ª£Ð-pMn‚_5²êo. ”#¤X©Ò¥U‹EU#¹Õr$|U›6$ô‘«"Á&ÑÕ‚ÇÕ”^ŸÁÝÖiì®#þј†«3±¿GŽqì]pôsBÍò {å´?ù¯Ú29›å@÷Ëhó_´#¦@,xEþ3Mdü!–~ÕiÔã–<"ÿ¦²~Ë?j´™€Ò5³LÛ¬zW‘錗ÉlìÈiR‘õ±ÀÙyÚåÙŽTEÝ©Þû§SbÆlTؾ7jƨÝÍOi¡‚†%åFîÈ£k»'DèÔ膩¯º­ôÒ“U}Á÷kè~¦ó:ónßžfG·iÈþ]¹÷õW»oŒÝ-•žèÛi.ŸgçPG7&ûòó5mü{ÏP³uô€ ­TDUUDDꪠˆ²fX†M4´øÞUgºË Qò2†º)ÜÆªìŠäc—dßÅL¸aê³<>†ðÌz·+³ÓÝe{Êk¢eCœý¹#Ws*»tÙ6ëºlfQUUªª€"É™b4ÒÓãyUžë,-GÈÊè§s«²+‘Ž]“2à ^WŒÚ3L^ñ‡dîž×~ ¨¶WDÙŽ’žxÝG7ej«\©º.èe gTo·_LòìšÏ#c¯´X«ëé^æ#šÙ¢§{تÕ討jtP«%‡â¶l³á˜ìÃj±PÃn¢ŠIŸ+£‚&##j½ê®]šÔN«àeÈφ¬ó Õ Âõ*’ .÷ËcjªÝIk"¹Éèµ;“¢aá“€TÕiu_Lk²jL2ƒP±Ú»õs^ê{m=ÊjdF1^åHÚåvÈÆ¹ÝÝÍUðP6  õ6KÆÞePú{iöD÷ì•w›´·IÒ$V§4m­Erîçµ$czz.F¯P,)‡Ès,C…j2¼®Ïe‰²+î5ÑS7‘evò9müL•V% pt.ªH›Ûº«cY6Nej*ª£wßdUUز®4O9ÌŸæZwm½ß0ºzõ’hÕ‘/ ÞÅÎX¶öúS¢î€m8^y‡ê-¡÷ü ¥¼ÛYPú_;¥UtN‘›s#]¶ÎDÝ:¦éñ˜MY¾êÕŠÏC&à–¼žåSXÔÇpº%tr¹{eÝ=4ݪ^dW"£\›í´Ø±Ü·²ÓŒØ­öŠö䦡¥eñØ1Ø¢Ÿ ¾[í‘Ï"Cë*Y dz¦èÖ«Õ7]‘z'S W¾2ðº«îkÊè»YTHÙ¢djäì'FóH»"íÊè™ß²låëÜaf8›˜<-wíÓ½4ƺ{}źÙܶÆošYÀânxºnN›Úk¤é:zgHó¬ÉÙ#r9®DV¹tTö¡ý9õ¥ÞÆûj6 4Ù©›µGŒ³ùôÇ/¥éõÇkNãcÞ¥©Ÿ€äý6¯“[ÞÁCøfáúm&®6=êZ™øOÓa ù5½ì?†n¦Òáwü¿¼§ÙR3•þ?ÍîZpóB¹ñï¹×:mdÊð­­¸_o™.î™’ÓÍ"ìsv^hÛ×~íÊ™jãûŒË…£èžß¦Ö«9ÕkcÆk_K誣¾ºÉyz*.þ—M”™dû šgx*qøi¢(™˜ê´cÌÄ»Œ·f½ÊµÕÓðSž¸ü~ºætúaŸbtvl‚¶ % ¬·Hõ¥«|lt’F±¿wDäc\ä^w"òªt]¹®1£Î²LvÏâ§£v½5çÊbc£„û%zÕê/Ó¿Dð¥t3ø¯Ö­]ŸÍv!ê^Kl±¥m‘‰n¤¹K?,‘@²'f×rìås•zuÝN˜ëgod¸\&*åqTb(߈xF‘:O¥bÍø½UTÄ|™ÐåðâsŠlS†KU޶ýd«¼Õߪ%ŠžŽ–fFôŽ&¢É*«¼_vÿ?â30~'4ÄÓ„ÁÑ5Ü«”GN‘¯OdHhY"ÁM»•–4íj*ªrì©·10ñ»˜Ë‚pŸ©—èÍ’K#íls]Êæº¶FR#‘QeNßÅÞßY>m ÄÝ‚iN†HÞYl–:ºªï,pµ¯_Iz¹½ÉßÜÇ"ðŘÎ)µ‚§ÿmzÏu¯¶im2«{×f¾¨ö¶àó{~ÏevkÃÖY ™³û¯e—ûcàÝdeEÒtäjzÎV±íDÙz»¢o±3M5=e<´•pG<±ÑËG1ìrl­r/EEETTS3.Æ×—c-c-ó·TUiÕâår‰¢zYÝÔ:mZÒŒKR©˜ØÓ#´SWËæ¶)Ÿv±¢;®Í“»î»òÕw"¬y9ï3®‡^ôê¦9!~œæw¬b8¦z:VDÉ’v£¼z-C™ºÿ!Q:!iÏ·­\¦íržSúQ '@{PPâÛ{Ï Úb4ºuêÛq·¥Î¶®j§Â¯bË$}Œ V£Ù٣ܮæèö¦É¿1)è7ZKÄ=µóá—At§j-Uš½l==db*¤Œÿ=Š©íÙz.FOæ²é߉˜ÓT¶žªƒ­JI\åDmL‘¬p¯OÑìÙGÁ`¤šfú]'š4š_[¯ð’?Ùò'rIgÆ[U˜Õ›gXœ\òšæ#èÇ“Oª!,Ã[ñVi§°õð[Äöš7V´#1Ââ¡mU|Öé*­¬ìÕîóØ>» 3eEG9ìFnžTTr*µdε:§Y8~Áµ"½Ñ:ºïjbW:'«šê¸\ègTߪo,O]ºí¾Û®Û¯ìC>OšŠ› ‹Ut†jgEM‚j ΖÛè5JÜ’DÖµ½›£ß²l›HˆÇyð1˜Õ4b²ê§„i\yüš½”´¹µ¾4׿[Ý`¤q_Ç5džíR±àTz{æ–{|wKŒóÕ:É ’IYO³UQbr«œŠ‹êì›smÁho:IÄ ¡•˜.G\ØÄu]–±R*êUÙwWÓjnŸ\b¹ž*âYb‚'Í4Ž8Ú®{Ü»5­Nªª«Ü…,àæ²}AƒQ¸†­§å—S2º™èeX'>×F«OHÕj9SÑÚV®ýy‘Û«º)=ñkšTéï :‘•ÐÕËIYMÕAKQ/<5·°‰íÙz*>Vª/†ÛõØÔ4f¢&*”ý„” &ÎÎͽ»¢k¥UD芲9ê½ëº®ê«ÔäÞ3Ãdöðtó»_êxûw[<®ÞõÙ¯ª=­ü|ÖQÅN> 9šÞŠÛ%Ým’µýœ‘VR*TD±¿tìÜ®—›tèåÝQI\X]Ì¿okåQTUñ:¼×LWLÓ=/£‡­N‹YtK ÔÈݼ·ËT2Õzlw-[7Ž¡»³fô™’'DowVµwjHeRòxV¾Õ§ú¤òú?KÍ@¼ÙécG;‘´Ž‘%X×.ìj½òª&Û/UU-iöõ‹Ôâ-SvŽUDLwO>cvt]P Èü¥ø¼dºoži¤Ô¸Õ’ë-¥µôÓ9ÕŒì¤V-K¢r#_ÑíkvTj¢¢¿t-Þ©&©cÐe:}”Ð_-“µ&¥“uU7ä‘‹³â~Ýìz5ÉâˆÈs7Êï–Ðÿæ¿hFtÈæo•ß-¡ÿÍ~ÐŒ™±áøÍ5“ð†YûU§SŽXð‹üfšÉøC,ýªÐ:f:âJêu»Fòm,¤¼ÅišÿP¶²HVVÃÉΰ̋NbÃóKõ‰•TW'NÛmÆjT•Zø9UÉ“™SuÛ~íÔèÁ̯,÷˦?xÝ?´§)/t|¦¡©z%ƦéDZòÎ%nµ¶zh¨ªê`¦Én´m¨|lx¥úÜ©Ï+Ȫ½ýÊ›íu8×Ì«]øú0Ô9ã’ïc¹ÔÚ+k› D•iQJ“+[è¢òLˆîTDݪ»&ûKZ¸LãÍ¡ÌÔçX>Œ1m5Éö§d•õ.¤ZÞW¶†6=˜ŽOUwDEÙµ<q¦^n×úÜzŸ·é̲¶ô”¯|ÉV÷5²%CyÕ^¯•ÎäF+—g5ʈ‡ª¸Ãn¿ùKxN±ÜŸmƒ/ºÝ»9;7Ô[í:TïTsѼÉñµÃtêMºC­ºe®¸Ó²½0Éá»ÐÅ'aPÔñMM.ÛòKÑÅÛ»tÙ{ÑU:œå±jΔê{²;>ƒy8cʨ+&õwJ‡,õ0¾eWn’v¥#·UV±“lˆ›5ú|ÕõPêVndŽóy¬4õFŸløê6bü¨’=?ÕI¢4Õx5ŸŒn´ì˜æ{š§»}Ÿhëe¾õu5Q;Db+bUEED{šª‹º&ÝO:;Ŷ‰qëµMoõ³Ý-ôVTQUÛ¦ìƒtg?2·³Tæ{Sdr¯^íŽxp)€ãOñA–dÚÍ@ËÿgCYICXås'«’¦6"ÈÞœÌbJïG»~N›&ÇLð}Ñí¨È¯Úg‚PcÕwêVE\´Šô퉬FÆ®VF›½Ûò#wé¾û&Å*ˆ§‡KŸÞHO²f}ø Ÿõ„.­Wœ?Ǫ_I»vK_xÊ|ý-‰KjµÏVÅ©ûf$Œj±y:ó®û3•ÜÊœ«·ô—]³=±fVìWPܳ |VÉ.‘È­šŽ™¯WËÙlôÙ¨ýÑXœÊž’£›Ðÿ%†•é%&šTêÅšº+¾oW<¶û›¥K§ò›ð™<-’\ª÷NåïŽK%B¹>^TTþ…)Ÿ@¼¢uÙï8½Mã¸]*®ôÏ–•,ššxÊyY×–D‚EcU;Ú±n‰º5ù¡V»&½yA>Ñí>Jl–äûLUÈÛKMN”‹ÜøÓxØéfæsë#¤EÙ9UQª›‘£¢w¾*tWÔ»&“^òii2‚– Ú&KI#`X¦k¾eNFnŒ^õMº—q‡¡ºÍ©5š]§Ú۽Ίšj·Ô²‰ì¤|q9­z²Gl®Ng·eDÙ{ÑU:œýòŽãŽË8ϱb0NÚg^m–ks$åÝ#Yg’4vÝ7DæßoˆºÑp×£|%iVo©zGŠÔSevL.ëµÞzéç¨c§í·s剪²A½5eÙQJM1Ëj·Ü5hþESˆä™´•ך'rUÒZiV´ïßecäoÖÑ註³›™¾(†í¢ÜGèï45š_—Ãrš…k(¥‰ðUÓ¢÷9Ñ=Ü«ÝÎÝÛ¿M÷èsÛÉ¡:e¬õúƒ—j®;I”TÚÝEOMÇyX×Tvï–gµWg½Ý›Q½SÒñ^˜¬*ÇIÃ÷”ê M;jk*ßc¶ù£$sÚ”u´Œ‘ð»uÝÍeÝ9•vXš«º¦ãRiŽNƒÞø´Ñ<Z#Ð þµ™œµt´-¤mºgEÛTDÉbNÕÉÕ’±wßd߯q˜Öî!ô»‡›]²ñªzª k¼ï¦¥trT+¤cyœŠŒEÛ¢÷©Ï-]TO+E ª¢óO§ÿ£èÉSÊý4MÀ´î^‰#îõ¯k|U­…ˆ«ÿÉ'ôMØÖ×/â;J°m$´ë~Exª‡½ÇI-K(¥|mK9âÞ$Ndݽû§O;Êü¡¼+âTvºªŒò{„—j8k㦷PK<°Å*nÞÛ¢6'íÕcr£Ñ6ôz¦ð_Å…¦_xc?ªž¸*á+DóÞ§Í3l.Šï|ÊYtT¸T"¬ÔL†I ]þ¶¨±+÷M•UÝUQ»k+§¤Ù¦ší‹®_¦9$wjæZyÓ³|SSʉº²HÞˆæ®ÊŠ›¦ÊQU:‘Þ¬qÍÆe²`ùne<ךW5µ”öÚ)*’WÂWµ9QÉâÄUrtÝ:”ßÉ%x«¶ßõM‘#¤…¶Z:ÇBŸo$O›—ñì÷'ã4¿'V“a¼Bkf_’ë¾,öúÜÝM\ªæUVÔÏéÏ+Sd~Û¿¢ôæz.Û¢ M؉_¦¨ç¸~¨yG4ÿ=ÀïÔ׋ã!Ä奩‡tî};ױȎcÚæª+ˆäÛªu9ªS‡h甇Å0:PYfÊñ»„Lz¹´®š¢|mæUTo:9ÈžäDèˆuÜA_B‡qßÇ•ÓIï–Í;Ð|®Þüކ¦eÈæZFT²•#¦úãUŠõUz»—«ymÕ #¢WhÏw •§M/µ•ÕVzfUV6{|ÔèÈÜîTTWµzø!Ï*Þ‹búÉŽWã¸ý ¶¦ûhš¾ç-4(ÇUÔ­KÑe‘SÖz§Šõ:3E„èG øÅûQìØUƒ¡¡¶º¦ëYn lO}» <˜¼²ËתIm;YÍÑ:µ$zwx¨Ôš#MW;Sxýá—Jòj¼>÷™U\n¶ùV Øm42T¶žV®Îc¤èÅsUåTTT]—¡¹iÚ;Ä5žó.–äÒ\fµA½u4ÔSSËNGr+’F¢*/+¶Vª§Eö·ÍôÃR¸4Ö»®_¨Z-fÏq:ªš˜ ©¾Û¼úÙ[O4¨æ½$TT‚§dDôÓ™]²9«ºß5+‡DÃó íÓ¸ð[Ì®Ž£#²£Õè׬nlO‰Ûò¬=$DFµ›/6ìo2+š•S³y!>É™÷à*Öºµ\jpÿ©}&íÙ-}ã)óô¶%-ª×=[§í˜’1ªÅäëλìÎWs*r®ÜwÒ]vÌôbÅ™[°I]CrÌ-ñ[$ºG"¶j:f½_/e²t{Óf£÷Ebs*zJŽoCü–W¤”šiS«jè®ù½\òÛîn–4I,ñ£·mCe#Î5í«z/‰jMöŠ’’¿  JÉà¤G$1¹\äÙ¼Êçm²'z’á“€TÕsíUÓ}-¥¦«Ô<ÖÓ`ekžÚT­©k:·—Ÿ³g¬ôo;y•vænûn€m@4¯_t«Zë.ôšg’:ðÛ"BµsyœÐGÍ"ȈÖ,¬j½S³ÝU¨¨ˆöuêlù½^]AŠÜ*ð;MÎý´T•’öPÊþv¢£ßºr§/2ïá·r÷(gbÎ2¯9ªõŸäúuYa©õ¶k-õ3ONŠªæ:i•QTTMØ»tEMº¢Î k9~§éÆ “æù݆Ƒ·um}Â(^ïE\ˆÖ9Èç9Q®Tj"ªíÑÍY¯̆ÏC²VÇYn¹ÓEYIQîÉ¡‘¨ö=¿µQSå#ªNø|¤È+r•Ò\~ªép¬žáQ=u?óTJõ{Þ™\ÖúJªˆÔDoÚ¢!%ÑÑQÛ©c¢·ÒCMO yc†ÑŒb{©ÑëUòÍr±Ü­Ö½"Ò[nM\N’®éq¾ÇGš«´n‡nÒErw9½Wªx§Ù¤pë‹hn:ãWˆ¾º¢XßEO²t‚š4fÏc–oIÎUD]÷TÝU¢!¿€5½DÓ¬CU±*¼;µ{£e®|/¨§IŸ¹b•²7gƨöúLMùUmÓÄÃ`Ú £k3*°3ÇíUqúµ‘Ñ1õMM›Ñ'~òmèµvæÛtß½UMô·’êF‡±ÎÉrë]šª”• YUS½4Ýë¶éÜž)í"Œ›Œ3µ*ÅPÝ/’n¾›"óxvÙ|dôûöûOoȸ8œÏ„üuȉê×£›y—lÖo›i8<5uDôé¥?ZtZ{LN%µã9›“O4Þ6SH»²H¨¦«sQ©ÖUåoUjuEîîOÍØ·¹£–[…ê¶Ï¼®j¥Â$Dß»–yÛ·Žéºüf·ã «¿“Z®çlSÃÓ)x?Äá¿ÄñVlvUr&¯Dkí[ Êê+|+S_Y4(¨‹$Ò#º÷&ëÐ×.z¯¦V~d¸çøü/nûÇî„NMþÑ®ð_þ…|§àÛ1¾HÊœ×Sã|¨›ªÇ µ‹º®îD|Žb§Ë·³[¸(ÓØw[žOU*9©¡…»x¢¢±Ê¿‰P|;6»ø¼4SµT{!O¸›'…áˆÌª¹=1nÔûjá-âãÄÆ‰[wI3x§ƒi©g—~ï³—ÇÛí5éøÄÒž/“"¦üÌ¢DDø½'¢Ÿm z+F¨µJúí‘iî¦ý;þ¶­ù²RèÑòöZ{jw&ûv¬t½þÞu]ûüJéžÜã3nŸ­*oì>4Šq7'¶mÓ®(ùüjéz1Ë=”«¶^TZjtE_{uØÀäü_i¾K`®Ç«ð‹åM%ÊÓNǾzj¢«W™Û9:*.ݯ6Á£zONõ|zoªªméÛbzCš¨kz¥A¥ÚWÝr¨ôÿŠ¡‘öT‘¶ÓNÞÚ¥Û¤mTFõDUW/ù¨âÎ"ÎmEª«½~ˆ¦"uòuáçf`1{){nÎz«•UOá4ã¯\¸ô¨ш÷$nUnëʪ›*§Æv?JJºª ˜ë(je§¨…Èøå‰êDZÉܨäê‹òœ’:Y+ÕÏr¹vDN«ñ!!i~…gz¨öÔÙi#¤µ#ÜÉ.Uj­…»s5¨ˆ®{º÷"m¿z¡ÌìX»‰¹ìS3WcéL~; —aæþ:¸¢ˆç5OîÝzºzžµC‰,«,áç;Ӽš*ù*ì §¹3Е6ö›JÏݩ̛.ûo¿U7o&·½‚‡ðÍÃôÚl¼DhF¥\)j]e–’Z»³¬G%Æ­üÒª+Ùº1©³XŸ"o·EU5¯&·½‚‡ðÍÃôÚeøE±ŒÃìµ4ckÞ«ÆÓÛ¤iW ž—Ë™Ö;(Ì3š¯d¶¼]­Þ=5kƨ§æÄÆœ8r×HÕiÀÏ WåUûâßôª?Õ*JýÃ×”=ÑÊ 1§ÒÇ^ªíòÕJÊ×Þ;ܳJéxÒ/£Í¶ÜÝvïBÀùU~Â8·ý*õJ“Lá#VxIÅøn¶XuŽ¿uÞ)«Ö¶–ãiJº‡ÆéÞ¬ENÉêýØ©²uéÐîY8j¶&Äbð•biñÓäQ5Dëåy^O#–œ¸´÷·£;µE<9Ê(ò~á¯Ô®&WRî7›-¹ÖY+.ËlŽvÇ=TÓ²FòÁêäŠ5—™]܈o]×l§”Û ¿Zø†¶Ó[/uô‘.-FõŽ —ÆÞe¨©ë³U~ˆFz QExãg®Ò }Eš£2’¢ÝMÕ¯†ÓÚ½Ò5S}Ñ—W§EU$O*ULAYk$RœR—³‚«jª‘Éò¦éý(Jë³3¶ø{—g…XyÒ‰ˆÖˆ‰å<õã¬ëß¡‹ÿ‡TGE\ú×Ûˆªššn³ªºz‰"˜SÛ+­{]Ø/TTê‹ñ•[ÉKz¼]ªµ5.·jÊÔŠ;:Æ•¾NMÖ³}¹•vßdþƒxâ3‹¼ð£s¡Æs‹mÊù•Y"·SÚiåæª…òµ­•&bn±r7Ÿu~Ȫˆˆ«ºÇ’j4–mT‰\æ£á³·v®Ê›­gqϰYf#±”âíM7)Óz4žÑ¦½–uw)¯ovuá>ÉEÚƒªzÛÆ¿ri¦’ÕÛ¬ÖTAj¡mSंŽ$^jšžÏ×sšÅw¥Í²¿‘½é¼í kŠë.;“Ϫ4Óâ´O}EÂ]eM4³¹¬r²ò5ñºNNmÜ»¢9:•›„LÞÍÃ}–§È¶ºjo>ǮƻQÍÍÊz"*£{HѪ¾åUèŠtÆßÅ6‚Þó;&Œê-¶ý{¿Ìøi µ¹jXœ±ºG:I»›5{ݺ¯r/]·{g‹Ír8§)É,áÍž3oDðꦭ8LGuý©×Uœ%6ï~ôùZõ¹çÆZsqâæî‰½~>›ªì‰õšsq⫊,׉-B£Ð$­¨´-rS­EŠÇÞ*Z½_Ίœ´Ñì®ÝU¼ª÷.ÈÝ£Ž>mu7Î1¯–Z7FÙî h¥‰dUF£ä¥­ÝQdÝSÀürÜUüŸÝåTµÐÝéä&‚²8Ý5Æ%kR®è»«Uvߪì±Èˆ‹è¤›‚Áb09eê·jÅS‡ÖÍ|™ª(¦fg»†\f9kõ×]5܈áN÷ŽõéÄð»o6d™•ÚáQ’dt”)[s«¨¨{™SXª‘ÁO2îÈ[$ný뻜©º£R鎞q§äY>¬q GŽSÐ>%kî• sd™üÊØééVX™lFõTÙ\›#•\©x8‡¿Zø“à—%ÉôÎI«á¹[©îqAo3KSÓÀö'üã'¢µ7ꈩ¿Mè š[Ãn«Ow²kn¦\°ë¬ŽKd‰_KIIU¢£Ú²O‘$k¶è®MÑɲ.Ë´kdj®2ÌÃ6ÅU4ã"æíUE¸®º"7xEÊ5Ö'†‘ËÉᑊˆñ”Z§äiË]"|é_…ÝcÔâfɳÆå8ÅÊæÛ6ì®óšdšdo›TÓ=UU›«£G1oMȨ®j*h>P,/=Ä5ÁõÎy.J—èfº[îv¶ÝDê™[+Z«ÊÔkXžª"*î«×u[§0pKdÖl6‡ ×ûÎC–AtŽçk ¢¹Ñ×C,´{Ô«e|êÖ7h]º+Ú«ÜU ʳM3us«s"“XÚïk›U*¹?=¿Òm2ŒË ˆÚÜ=x:&š®YùªÞäÕ4ë¥QƺNºsÓI×E»¶ê§ TU<§‡tìLü#ðy¨:a˜c:µzÕv]­rÚDµ5“§*TSú »œ­ôy“ÃáugBõÿF³ WıÝD³V_«l”Ìeª:”u[2:V>4êÇ5ýÑvõWmɘâ»SŽÌ±ù„ÜÍ)˜®8F´îù13§ #^:ñm°Ô[¢Þ–ùz@dyò{ÑsÏû/ö)aŠóå÷¢çŸö_í:S{²ßã¸/ß[þ:V1?‰¯º}Œ—“GÞ‰‹ýýsýrRÒoÉ£ïDÅþþ¹þ¹)i´0«|N}˜ðϸÓ~´âÒo‰Ï³÷oÖœ¿<¿Ôwȧ£ËýG|Š sÊ"úªÆñÈ{>Ç"Ïlº”“}–7N²mºuo§:§]·%‚ ò„¯Ä4†¥ô¾qOI«ØìÕóòo-KU7ïMÕÈ:¦ûøùó÷†š¦qXJz"šýsæó)&©mÀÏŽ›~C¤46Ë~²Ú´êGÞ¡U«¹Ü%£§®jC.ôΖ$Wÿž‰²¢ö}S¹S%iÔÛƒp¥kËò}I Ë¦µXÝæwGÖs%î­­rÅNróI»‘‹ÕÜ­æ^å"*§Ø/ÿ¥°þ§ThZ›¦ø–SäÜÃóëÍ’Þ°Ë,N³ÎÙÞÆÂµW#›™ˆ¼¯ÝDô‘vðØê9VUc’eÔc+Ÿs4ÌE4ë¬ÄÄqá:LéÇ„LΓ¤C[rìÑzæäqŠuMü3qµ†êÖ%F¦ä˜®3”Õ]Ýn¤´ETæ:v*F‘9­‘ÊåW=îjuÛ¡`s<÷ Ó»R_3¼®Õ` sÒ&Ïpªd-{öß•¼ÊœÎÙvMסC¼Ÿœ2hþ¥i¤§—X*ª²+>O'™Ô2¾h˜Ï7lżmr5vzªõN½ÊC¼fê5¿.㲋R_s«Ãq*Úkc¨(o4cXú†ÆŽsZ‘êÿOt]¹’†UíŒÊ󤿗eÕWE¢ª®F‘:i1M¾Ö¥­Ek×—m“›§z/Vn,´;‰mWÈl7 Õÿ ê )!¯ƒè‚áoíæWî×òÒÆæ»fôÝÛ(ï”Bþ™:<ÝG²Qö—Ü ´¬“‘¾”ÖÇíç-_ogÊÙ‘UvkY.É»ŽRZ®×[ Êšõc¹ÕÛ®R¶zjºI ÐHÕݯcڨ湹QwBñjO üqiþ~̳n*ÛYë˜ìÖôþÚ=¶ì‘Ž…îzª1«²«‘—G׸æ¹CQSnª§£—²žX^ÈŸÌ­äzµQtê›.ÝP¤ïúü¡åUÿŽoŸîÔoå ÿ*¯üs|ÿpDŽÇ(®6ìz×o»ÕùÕ}-ÕOÚ9ý¬Íb#ßÌïIÛ¹w^«¿S"gU¸Vã‡*Ô¬›$Áø÷¹\ç©¶Ð}]éüÚÏUd}”P«²lœ­UDð5_¨ßÊþU_øæùþàˆ;áó Ô=?Ò#ª¹WÑ&SAç^tóéë<㞪Y#úôílå‰ñ³ÒDÛ—dèˆH€Q8—á׋}JÕ ò}×_¡\qôTð²ÝôOs¡å™ˆ¨÷öTñ:4Ývë¾ëâE_Q¿”/üª¿ñÍóýÀ)ß”ÃFbδz›Rmt<ל"e–Yæ7šÝ/IšîeMù^‘9»s*zhôÕRUáGKµ³JpÛ½›\µèÂíWsZšJ¯uêî?dÆö|õ,k›é5Ëʉ·]ûÕMóYïØ¦5¤¹…ë8ìÝa‚ËVÚøäj9&‰ñ¹‹*ôr½\ŒFø«‘<@á †ý{Åï™9v«¶\è%I©jéetRÂôîs\Þ¨¥ôáÃÊoYCØbÜEC%d.{#‹$¡¦NÒ&÷*ÔÀÄôÑ;ùâNm¾ÑËÔçà­<}æ¸þmÁýENt¤¿YòËÕ–…³ÑL’2XÖ¶)yQ[ºóoQ[ÑÈ«²ø¡5GpÆÈa¬Fµ­M‘¨È‰à‡,,ú®86‘Ûµ/¦šÍ†\2ûÙkÞöK[:Ô"GT§V5ç·™Ê×9ÓtDSª'ðÕ\ÍÜW>º=ÍÞQ+žï´9¸Wþ7¬Õ÷ýKe»W­ºw,—jý!r®’’ž­;9w¥|±¢½¨ï_¢.ý–Ê›n~˜}aÐÎíyfaª”‹,Öª—ÅyJÞfݧkåttð=ëÍ"¢¢Bß¶^M×n»G~To{¥¯þ–Qþ­TFWM6ij/&~9–_èešå‡Úë«-2¶w±!–[‹˜õV¢ìýÚˆ›9éÙ^Wg³ø(Å×1jæ'vb)§^4Ì|®ÆxO"']'H†ºåɦý{±Æ)Lœ1ñˈj¶)QY«9'‰äN¼ºßElŽ©Ñº¢ŽŽDlŽW*ºI$oEÛÑ,v_›áÚhuÿ7Éí–+s^‘ùÍ©F¯^梹Sw.˲'^‡>¼Ÿ2èþ®i½v¡g6 šÛÝ—*}=ñ×Í XÈ ¥™ˆ¬c‘«³ärõN»ìGvê$WÒãùÔ÷ ðì>j QÑl“y³£Šjµäojõ{ÚŽUN~3ñ;•æûMw,Ëj®ŠmÅU\"tÓv"›|xë3ó¹v¼S‹¹k.i3<¿«¥.¿h¶¦\–Í‚je†ñqF¹éGZ$îk}g67lç"{Q ®uªšq¦-¢~¡f¶Œy·'HÚE¸T¶™YËÏË¿~ÜíßåCŽºÉèWÑN5•ð¿ŠdøEM¥Vj”¯©í6¨ìtBåšW#º;™Q:7d]ÜY)òLŸNôK%•œ¯»QV×9»m²ËÕ?ù#Íß)̰67îQk¿Å1r‰¢™ž:kLë§Â1óâë«H™§N\§UÖÊ8ŽÐŒ/ v+”êÆ5m»FîIif®g<Û}¥ÛtvT_MS½»2×=Óê žc©8ý²šëTÐ:JÖ9já]¶’&µUÒ3ªzMEN½ç?õ3ƒ­<Å8'¤Öôžé6o%º×}«ª–©]¾{,(øV5èˆÖÔzÞ²¹WeØõÁWzK~Í5"²ï=S+f±Ù’Ç1´,Ž&IÚµ>Ùyç]šïGÑ^ž‘VÈìå¼YX»ž.Õɵ_‘NµUÃäqáuã¯ׯ…b&¿»Ìk}®Œá™æ¨¶fä.Qm¾Û•ëÔPÔ6VµéÞ×l¾‹»º.ËÕ ñÍ%ê¾-DÍñÖÔ?̪l°Ö¾.eåíb¬k¶îßiœ›/"[Ó³YµÌ¾Š÷©&&yé1¯î^¶V÷Â-Es6ÈBü(ÎËWÜKbMŸxÒ·»ÄÍëÔP½Ó/UTN«x*ü‰²[2ƒÃˆç:‡¯OaúE•7Ëk-8kiî‰Y=ÀörK&ó@Õ‘Ð5Y»QwG#W¦ûaþ£(_ùUã›çûƒí –®ndx:ªç6­ÿ"X˜ÒõqÛ>×DFt§…n8q]JÆrLãˆÿv1ûmÎ ›•Ñ…Þ£ÎiÚôWÇÙK 1û¦éÊåD_óÕ쎊ãqÇ®–ûE_š×ÕQO ,ý£™ÙLæ*1üÍô›³•tê›t(Ôoå ÿ*¯üs|ÿpDÎ 8Hò‹Ç#ØÞ"ëäk\¨nytÙÉíMÚ‹·Êˆ§E­°ÔS[©ië%ígŠ2Wó+¹ÞDUÝz®ë¿Ué Z—÷ýGÊï¸vº×Ûì+Ýu]ª‘¹­Æ§£’wºÒ6',hÖ+S•½m“¢AÍï©/Ê1þP×ÏËŸÍ/ãö¤Xæ3ªÉ/9E2²ã]%l•në4Žj¬Òzoô‰ºû6ð@¥ÜJðýÆV«·\›Gõ~¶Á‹ÔCJÊZòºê±ì…‘R‘XÝÞŽ]Ó¿½@º æ÷Ô—åÿ(kçåÏæ–Ó„;Ö4Ó‹•‹]s)²[ü÷¹ªéªå»ÏqVQºÈûI‘ˆd«Ê›~õP)'”ûE)ðýH¶jý’(ã¢Ìذ\"j¢r\ kS´ÛÙ$\‹ÑÓŽG9wzoV4¿WµFr¢}6ÊjìÕ®j2dgEPÄ]ù%Ȭ‘»ø9nôÙz<ò˜åX½Ÿ†ùñ»Ç§vÈ.t‘ÙãkÕÙ!•²Ë*¢/V¤Hæ.û¢,¬ñÙS’@u[†ÿ(îŸj;hq=]HqšF¶&×*ªZëeÝ6zª­;—}ö“Ð辞ê!_)ä‘ÍÄŽ†Í |ol.k𻣑kãÙQ|P£ök%ç#ºSXñëEmÒåXþÎšŽŠóÏ3ÿ’ÈØŠç/ĈKÚ¹¦š©¥Y.„cz±[3«¥­e]¾‚iÖW[hŸUMÉNª«èª=$Ubtj¹SÚm€Xð‹üfšÉøC,ýªÓ©Ç,xEþ3Mdü!–~Õh3ñ9¥÷ýgЬ³LqzË}-ÒûM 4ÓWÈöS±Ì¨ŽEçs÷"lÅîjõجôrÛí449®’šš(^­]Ú®kQmü:MQÔŒkH°;¶£f©mžÊÈä«u4]¬ˆ×ÈØÑQ»¦ý^Ÿ‹sb¥©†²š*ÊgóÃ;$nÙSv¹7EÙz÷)ênó~€«@Eü¤|5k^¾_0ZÍ%Âý݆ÍI_k½Ñ¤¥ì#áV&ÓÊÅvèÇz»í·]º V'vurß!ÑO*^ªbQénræÓbîŠgÁ-ÆÍO Å/#du¬¯jrµv^mùzÁ¸— á3ÐGdÔ•YFfžWqk^ÚFVF±¾žôçìZèZŠåNeç{¹{š— ¦¹rïCô?Ê?¤˜õóF°lbӎدõ¯–®ñW[E"R¾HÙç†FHé:Ç;£s“mÑâWà„ýbáÏXsºÌöÅ,5÷[­whë)ÞÚþJ–«dH™#¤Æólö¢¦û/Rö¡5̹“œðaÅWÚçqÕ~ÊÝ]5D´ìŠª™³RÓÌîgÒO SšÙX‹²5[Ì»5®^W&å‹áFÑÆ•Ã!Êrž(ªû :»ch¬ö´¨¤FÇ/?3¤Hiwcztæzóøw¬ š¦cG<øàÛS´Ó'ÍݯÚWEKh¿ãëi‹Îkh«RfÉ'×¢Ú ^棙ßÜ‹²u> +჊^x”¯¾èö6a¦µó¶ ¦%æ†õ6ç¯25ÑÏ3Î Ýy_²#•eFÈäN…DTTTݽŠï̹«\눎2r HájÇpÎýÈŽÑnvºiè)Ñ-3‘­¨WB°?g½‹"5Êç9ÈÝÛλ£¸Èã…¬¦Éd× /°ÛìWöî·SÚ©éxäl®§–•ýšHÔTõ¹¶Ý»¦ÊŠH¿ð~q£YÝß$áC]-v eÞMÝItt°¾8‘ÊæDôl3G?'2£\æµvUè›®ù«“ßT5#?¶gÜ[ë‚f´¹®ŠÓBǺ ZŽGvJ÷µŠ5TôšÈ‘\ŸlÕêQïZX¾)øa×PãÕ¬÷K·û†ú›‡ºTpöiJÉ*öRÊÙ•Š‹Ñ«¿rn½ éx´ÛïöŠëÚ™µ7*ii*¡w«$R5Zö¯Ä­UOÆ}`ô·3«—ô\(q¹ÂV¡Þî<2ICa¼§b“¶Z5t#•bmM=K›´¬ævÏtõº¢9ZI< ðS«ög¨âG‰zèW$Ij*©hª:‰ß[3U®¨™ðªÂÖµŽz26*¦êžª1o¸)¢³\ËžÜnpu®™.ºÐñ ¬¹\æUÁ\UQWR#[ì핬‘œ±ÅÓuw3WÑT^‘Ʋð¯åâ2ÃIœê­¾¶óg•”V¬n*Ê w²žTWOQÌÉ™¢£ž¯výÍF"/TЊæ×^¸}ÕÜÓ,F±œKÏ35Š*ÛoŸÒÇÙ:žŸ’dí_"DîWtô^»ønIü i~s¥¼+X4Û;²{™‘ÑEtlô^s Ü‹5eD‘ýr'º5Ý’1z9vßeÙQPžÀSztÑC|œ\1ë~ƒeÙÏV°„±Ò]­´Ôô[•WjöÊç9»A+Õ6ENôD"ÚÎøÁá›\®y‡ 6ønvj÷M 쫤ٔR½”µQU=»«­ôÓt^F»vª«S¨€h®ü뫘”üñƒSÅŸk^¢RÑå3M{³_rK•-}$,¶ö5Lç§ìÜö9ý”11~´ÅjïÊÞeM×§`&­TÊ9Âf¥ëÔ˜¾o¥6Ø.÷+<ô¶×TDzÂ÷£Ù$n•Íbò¯i»Uơ̈̄oÕm¦üok6›gzmÄÕE-ªÑyÅ–Ûdt©B²{ ×±ÑÍ7šª¿oCÒÝS~»7rï€oNš9q¡ºå Ðúþ—éÖ+h³ZïÕJùïu´2ÇLõogç0½$Yv#WnÍÎM‘yw$þ¸DÖ~8ƒÌ/Í–ãrØê­vëÜU´îm{Ö²ìrBÙ4|ÌÎT{SeEMצ÷à šæ\ë»ÍåSµÑÞ0*Ì2Ñ—Úk’jXêëk¨GÓ¿tÛu‘œÉ²ÿÏ1WÛº“ÿƒíCáöÝ•eš˜êJ[ÞKG5¦š¡³­,LW9Ë4ŒU^ç+QŠäDj¯2ólÛ¨ŠopÑÏ>x6Ôí4Éówkö•ÑRÚ/øúÚbóšÚ*Ô™²Iõè¶‚W¹¨æw÷"ìOƒJø_â—„ž%+ïº=†M˜i­|í‚©‰y¡§}U¹ëÌtsÌÅóˆ7^WìˆåEÙQ²9£`h®üʆg7?)æ!Ÿå´~/lË1Þº[*Ö{Ÿ3a¡’g¬Qõ’9–5jrɺ&ÛuCß¼êÆê-ëYµ†š‚Ë]]A= %š’h¤{]4Ì|’¿°UŠ6¢FˆÖ1Ëë®èÞTE¾h¦÷ WÄåøå6c‰^ñʉ`§¾[ªm²ËÜñ²hœÝúnˆåTÜËLç%ú Âr Ç̼óÜ+U]ÏÍ»N϶ìatœœû/.ü»o²í¾û/pUÒ 8¢Ò3Ç´ÒÛržáMQ¥U3±$¨Š«ÌäNˆ½| À®ö>9t> #Éu.ûô!tË,±ß"µy­eòòËW¶†Ÿ•Þ”/N¨Õéݶʲ^”릕ë}=Æ«KòŸv¢´¾8ëæ54Ý“¤G+iãb»tc»·îêxdÇ&ú ?Îñ½3Ä.YÖ_W%5žÒÆIU4pºW1®{XŠj*¯¤äîB"ĸäáã9ˬøN1’Ü*îwÊ”¤¦G[&†4•Þª9Ò#Q7^‰¶ýU>€U\ÃÊ;¡¸VQtÄ®xÎs5uš²z µ‚ßMÈÙ¢‘ѽ¾CW£š¾Z `ðlºßŸaö|ÖÕIYKG{£Š¶+#k'nèÙ×9É܍н|MSW5RpI-±iö‹WgÎ®Š¡ó--Ö*$¤t|œ©"ÈÕMŸÎ»mºúéÐ Æ”fÚÇ—V\Ùª:"Üžš(V…ÿD”×U«z«ûD^Á‘ˆÎôëºþ-¿0ú0ú¸ý{ôCد¹þìv¾eÚî›vÝ—§Ë¶þ¯P3ƒ1[KÛ+³lÿMiŠ¢¸PÛ-u.tðs}y¬’NUkùwF»»}•S½sC/á‚Lß'¹d}~Õº*ZúŽÙ–‹FEæ”07›~ͱò;ÑîñEO ¥ ÓüJÛ†Úî*ê[\KU*•¨©z+•ÞœŠ‰Ì¾–ÉÓ¢"'€ž]¨ú}§ñÅ.uœXqöÎŽt)s¸ÃL²£{ùîEzüI¹Á5£Jõ>á[kÓüê×~ª·1$©ŽŠUfÅw*;}¶TUñESîÌ4ÇNõ ªßWža\‰ö¦ÌÚ$ºQGTÈR^NÓfHŠÝ׳g]¾Õ62,GÅÚæã8ŦЎo+’†Š*tTß}—‘©ÓuUÖS{›Æ®¹ K…âKeÕm·Û¢I*ª–6+»(™ºs=ÛlïUTDÝzæ=®ší•_¬ô4<)_­vŠº¸#¸Üï7ÊZWPÓºF$²¥:§<ªØÜçr¢£•SdEÙIÜ ¬ÇAµ“8Én•õ¼Re[ TÏó+EŠß”p+÷FyÓ"íÜåo2wní·YÔƒÂ1Vá­¿eþñ{J9žè^*R¢¶¡\÷9]4ˆÖ£Ý»½m·]ºî»ªþ—Ì7Éêèn.)g»U[;_1žº†)ä¥íNÉÏj«9‘­Gríº"oÜfº–:+}$4Ôð·–8aÆ'±Ø®¤q§kÚÑ×Ý=Ñ»Gº{@©$­w²GoˆèåæÙwF©c‰³…£Æ^ª)ŽÖn.Åæ—£‚·5×=ùçª;g‚J5Ü¿Q0Œ &K—dÔVÕ‘ªøâ‘ûË#QulmÝîN›nˆ½vNõD+3õ¯_õÆ¡Ö}1Ç–ËDVÏSJ»¬i¾è’UHˆÖl›.ÌF½v]·Eå3˜wSÜ&móUòÊŠÚÙœš–’Ez¹9z#êé9}]öoNUDUßtÒNsÃ-³5GçUäÓïŸT¦±±Ø,ŸËÚL]6çôVô®çŸMbžùÖ;_VUƲ{Ÿ§øeΦEHâšµ{&+Õz#bg3Ÿ¿DDÝ«ºü]ue¢âÃ[\’O-F9i©#QÏuºZª»'*o4‰¶ëÕ›"/ŠofqM5Àðv#q\VßozmõæEÍ2ìÞTÞGnõè«Þ¾+í]öR¿rq˜ÏËñ§æÑäǧœùÔ¬Ê2Ž˜«ô—§~®ø§•3Ý:v+V/Á67JŒ›0Ë«ëäEæXhcm<}éè«Îç'Gn©Ê½Sm¶ë,c:¤Ø—dûVo|ñ7dž­‹S"¯Mݼ›ì½<6ÛuDÙc}v'Àa?j5ëž3éZ,Çl3Ü×XÅbj˜žˆØôS¤?Œc#cc¨ÖµÔM‘؇ôf€Åf¨ZƒhÇ­¸M±nðUÍ-d ‘ªH­kb¦änÈ‹**ïÓ™=ªNÀÅÇa(ÇáêÃÜ™ˆ««Ÿ=[L—6»‘cíæ)Šª£]"¨™Ž11ÇI‰éÖ8óVý'á Ëg—}N|wJýÕYo‚UóXÚ©Ó´]‘Ïz/±Q©þwyca†*x™28£j1ŒcQÖ¢lˆˆÈˆ{Œ_‡Ë­ø¼=:uÏL÷Êîw´†Ðßñøû“TôGͧº9G¶zfP—õ-Lü'é°…|šÞö Ã7Ói5q±ïRÔÏÀr~›WÉ­ï`¡ü3pý6œïÂïù~?yO²¥Œ¯ñþorÓ€˜ÒaÄX_ø­#œ\ïT4vëƒnQIjž(¥YR7dz–XäEnÒ;¢".è}°;<–=5ís²íBz"¢«]q¢Ù~%Ú“rプíNq•XŒ6 UF³¤rãÍb¼5«“½]:Ê(Ñn´g@Ý5^ŸcΦ5†k¥l«QVøÕQUˆ÷tcUZÝÚÄj.È«º¡úëÏ ÚcÄ]’’Ó¨UlžÚ羂ãA2EUKÏ·:5Îkš­w+wkšäè‹ÑQ”…÷g0œdfz¯?YÞêçÕ§ 9iÓߊ·¹âôáÔªX“g‡¬.âë¥Õo™T½œ‘Ç Þx]O;U¼Ýœq·™È‹Ñ\ªˆ»*"*&Ò?ü)éç ò_¤Á/9zäM¥mWºõKÈv¼œ”1í¿lí÷ß¹6Û®ó031»QœæV볋ÄU]5é½<'vuŽ£IãÁâŒ5«sM:L+þ¸ðC¢ï}~Y~¤¹ÙoÓ5¢áf¾©Q³2F=ŽTDDæDG*tU]“l6Šð£z)šÐê ¶ï’^o6Ås¨Ý_Uaîc˜®FEËÊåOIU>"Ì‚´mNso9}8šüV›»ºôrÓ¯M8i®šp' jkßÝUëSx ÒVÕ¥ÖL‹ Ë)ïK5Ý…]3)y©šÆ³Ñ|~Ê‘·OÛ¶Ä­š%ƒkî. žSÔù¢ÌÊšzªG±•4“7ºHžö¹ªÕsWvª+\©±¿¬÷1®«Mêµ±Âß“§/D=x›q¯|ûP÷¼0áü7SÝ­øF[•Ü-÷‡²Y¨nõTóAÍM»XÒ8#V½[³\»ª*5»§¢›G:“äâáç?½T_í±Þ±:Š•ç’ $ñ2‘^½îHdèÍýŒV·â-82-m>oc^:Ö"¨»^›Óò´å¬r;aIÃÚª˜¢iá á¡ühÖ…ætzƒc¸äw{í½%JI®5‘öp,‘>'«cŠ6"ª²G§¦®DßtÙSsz×îô׈û%§=‚º ‹[ß%Æß+c©¦çåçj+šæ¹®ånísWÕEM—©*‚Ýí¢ÍqÚs—ê›ÔðеãÇ„vqž§Yë"źh›qO V} à#Jt+=¢Ô‹&K“]/ÖLÊVÖÍ@ÎÖ'DõV2&ª¯#܉»¶ø‹0™æØÜæ÷Â1÷&ºâ4Öz£YÓ×/VíQj7h õÀ¯>P/z.yÿeþÓ¥,1^| ^ô\óþËý§Jov[üwûëÇJÆ'ñ5÷O±’òhûÑ1¿®®JZB­ù4}蘿ß×?×%-!ö‚&o‰Ï³÷oÖœZB­ñ9öcÃ>ãMúÓ€·à—úŽùôy¨ï‘@ô­yHéÖŸ–º—Î"IJk-êf¤œ®äm[aô|UgDÙ}ª¾±‘Í&†F¾7µ×5wG"÷*/ŠŸx<úö¢a´‘ö•uøý[©ʎ稉‹,-ëí’6&ýé¾éÕó†Ì ÷@ð¦›+êl4Ô9¼»yÌ,HgDåUDD–7¦Ûî›l¨‹º'ðÓ„š¬á1qÊ&ªgÏ1ü2Üe5qªžä’8v©>Rœ#3Îôgµàøë!­ƒ'†¢ZkUµr²$¤©j½Ì‰®Tnîjn©¶îDñ>›~æY¯“Ú—I’ÉWA“MŽÆ‘Û«¢u4ÉS JNÈ^ÙŽrÆô¶OI7Ù:–´{;QˆÃåølº#ð|m5qã1Ê&:˜Ó†¦«•W3Î4s#… û‹}†=´pûv©¶Öß㪫«¹ØkX´L‘cŽeçj±œ¼‘£šª½û¯¤Šˆ›§œ:kNÄ?aŸ!{ç§®ª¡§§ó™©ê£"s|ݾœ°ÈƦü›¹ïõS•Nƒqson}ÓœÎÆŠ&ºj¦å¼V£/ÅÕTΜ»NÏŇ9ÍæÕŽX8U¨²ºz¸b¯¯«³Ö,qEÌ£‘Ò¤qÆ»o·:»äU?/)æ›ê}[§.Àð,‹#m WT©[E®zÄ^´¼ˆþÉ®åß•Ûo¶ü«·r—Ęm®³—æv3‹~+{ɉªw·¢iã33<5àõVk·6ë®gUaâ¯Ë2. ¤Å1ü^ís½ûbg¹´tRMUÍÔë"vLj¿v£\ª›tÙwî?¼âf!ÃÐþY‹Ý¬—O>¹?Ì®4RSTr»Õ^ÎF£¶_K: líÙÊ*Ê7#v«¾7^:릚w.Eˆ‹¾7^ùòfiŽ¥`Y¾kWœéîKŽÁUj¦Ž nÖšŠ6Jô™UZÅ•G*']è0­¤Ïnm&c^cvˆ¦jˆ#ŒpˆŽžåpöcn-Äê øð_¯vüjÅqÈîÒ::U$Õµ/kUÊØ¢b½êˆUyZ½­4Õ]QM1¬Êœ‘Gn–ý©e4Ó舄>º·êšºÀ˜ò¡þT½hm›²èm®g%^@æ^.»9QŠ)!b§r£æb»âXÚ…ÑNõK_²Xôû’Xü•Wj–HË}£Íõéš×#US¹¨ŠõðjzÖ^4_^òNO©õMe}¢5céë$§íéùùÒUŠŽV£•ûl¨©Ú?eëÒMÇqÛ%c¡Æq›U5¶Õm…´ô””ìFGmNˆ‰ÿŸz®ê½@®¼4ð!¦z -.U{Vå9;’X®s±Ì†‰ÊÄG6y•»¢óm#‘_Õ6åê‹ôùElUwÎóÅ ‘Ì©¶¶‚çšþM’ ØõßÚŒGªm²îˆY#MÖl-QÒ\ÇNäcUÙ’²ß»¹“I’'õé»_ÊäøÐ W½Sä˜õ¯"¤o,Z(+bNdvÌ•ˆô꣓ªà×+n_Ã>TåÚ¢ÙlK%DNDkᒉΦå{QW•ybjõÙUЍ›ìMÃùžpÛØJ¹ÑUTú&a0·VýW\ ì*¿”w Ëó·Yð¬VñWÇ“RT>–×C-\͉)êQ^¬ªäj+šŠ»mº§´µÙdÙ•y>>Ö>Šw¦Üë¤ò•»¶âíDôªî‘éV[à&¸YªìùúQ2ŠçéeŠ¡óÎè›#ˆæ"ª±z§s·*Y|6Óß4çáÚïs’ç^Ú—û£b­s)ækR7=$ZÇF­kzórôEGuëÕ Ip{iUŠqvq8j.ÛÄW7&š¦tеׄÇŽ^†=XMf™¦©‰¦4PÞ6øgÕ‰5vÓĦˆÚ¦¼ÜhÝG=m3J˜j©U© Ì‹¾f+Xƹ‰»“—¹Z«Ëò»‹Þ3òjx±ì[„ºŠ ܈ÉYSd®Xc‹¹dF2/‹´z¢xî_ÀRÆÙSVÎ0Â[¿6cvŠªš¢b:"b&"¨ŽˆžIVËš­Õ4ëÍF¼¦Úw¨9õ«N#Á°KþDú.kVËE²j¿7çm//:D×r¢ò»mûùWnâF×|C-»ð ˜m§»Ößþ†1úr©¨¥’³µŽZ5‘‹Z¯æj1ÜɶéÊ»÷)gÁ‰kjïZÂàp±n4ÂÜšâuŸ*f­í'ª:8=N&ªê×åFž­wÉÓ‡eØ>€ÕY³LZï`¸;"«´—J)ifXÖ(É#Qܪ­TEÛnŠAžM=+Ôì U²›†s§9>;K>>°E=ÖÑQI’yÌKÈ×HÆ£²*ì‹ÜŠtTnmû‘˜DÚüɦjã>NìÌðëçÒ¤ab78ü€CÙ` p¢‰~⟉Â9\úhjñû=\Ä}=$½SmÑèÞˆ½Îß½fzšˆi)嫨$P±Ò=Û*ìÔMÕvN½ÈE~O;uMvŽä:¯\’vú™^2f$ŽUV@é»ÛÕ¢vTôStrtÛdNËàc 5æœ^œ)¢)úÕDÿѩͪÒÝ4öÿ~Õ£D4@Ïï*¦¯IEiÆtVÏrj:âç^¯P±}.ÉŠ¥c¿Ísûgª{bb!]áEuÃ8¶çú…d­«¹[ic£ìá¬t0ÔÂÉVF¶V·«¶W=7EEV¹QUvo(rOCøpÕ~ îÏ·éå…²RSJØ«n•rvTTjäUNÑû*ªìž«çuNNžðåÀž“hCíÙU|2d¹­+õ¹Õ¹{ Y•»?Í¡MšÔö9üÏNôswذ˜î;cĬt8Î3j¦¶Ú­°¶ž’’ˆÈâ©Ñ?óïUÝW©‘±ùGí®á;%¼FŽ|˜í}ªîØ‘ÈÔ•[ÕUîNIïníNòG´ÜéoVª;Å ¹i«éã©…\›*±íG7tð]• ¾¾à_MÎ4ý½¯m|±UÓS¬MærTvj±*7tæúâ3ÑÝ7îÝ7!޳vê˜Fê¶ÔN–x¨*ž›î³ÓoŠíÑ™]ªøuÝ7EE8Ÿ†Œ×…Âbâ8SUTÏú¢&?†[|¦½*ª”´>~o_Ê;†åù΃[¬øV+xÈ+ãÉ©*Kk¡–®fÄ”õ(¯VFÕr5ÍE]¶ÝSÚ~:u¤y–Mä÷‹Ij¬u–¬–®Å] t(]K3j®Ybd‘Y̨ήDèä^â×Kgiñ|²Æ[nˆüØ»të¢c©8zfäÜ™ç9uÂöoÅçðWiN;ÃÕÚ¶šåymmD·+ nÔ¯rG¯í­b±YWmÓtUE$¾28mÖ>¹Pñ=¡¶iïµm–Ž®¶†ž.Úx*éÚØÚô=)b|q±ÖîíùÕz.é~º½·×g3û©‡ÃQEUETÜŽ3"­5еžÈÓO>«1‚âêªg«±B©¸·ã#0ž“Æ8P¨µÜ&•‘TÖÕY«V(ºúnNÕ#d_;•ã2^S½;Ïóë~Gà¹F´3]¥¶‹dÕ‹=´Üœé]Ë¿+¶ßmùWØ^0bXÚÛ Ë˜à0tZñ[Ü"jéªÞ333â#µî¬,×n«u×3®ž¥`×|C-»ð ˜m§»Ößþ†1úr©¨¥’³µŽZ5‘‹Z¯æj1ÜɶéÊ»÷)ãÉÓ‡eØ>€ÕY³LZï`¸;"«´—J)ifXÖ(É#Qܪ­TEÛnŠZ k«Ú;µå7rÈݹwÆë¬ë¤FÜãv.ëÊ4s«É§¥zj¶SpÎtç'ÇigÇÖ§ºÚ*)#’O9‰yéÔs¶E]‘{‘NŠ€ZÚ\þæÒæfhŠ&b#Hã#N•pö#FäN Ð¯€=ÆãCh·Õ]®uQÓQÑBúЉä]™Lj¹Ïrø""*¯ÈV"j#˜ˆ¸Aç¼qÄ®`ÆÎè*r 5•²½¨Ö,”rFö¢'‹yÓ¯Š+WÚ[°y;ìÒ;A«µ.­Œm^¦åWŒ²V÷Ée¨X˜Ç»uæ] æø¹û·ÝVÏŸnåXYÀà,agæQM?V˜±»VýsW\€=àÈŸ(¾µý4uÊ\>Û/5›í­1tõëUÉçoüO‘mÿ±ßÄ×xtàƒV¸ä½v_B˜· ïv.t²u1Ûõ¤‹dó¶ê¼Íg‡>ý¯Ü>Tê­ÏWkÅε×ÒÖÍÍASÌéR¢5êçnåI9Úªå]·ÙRuŽ8áÃYkZ›#Q;‘Á‰t+…Ý"áþÕ 8v9 מɭ«¾U·µ¬¨‘­s‘Îß±j|­Ùz¢®ê´§Êï–Ðÿæ¿hFtÈæo•ß-¡ÿÍ~ÐŒ™±áøÍ5“ð†YûU§SŽXð‹üfšÉøC,ýªÐ:f$âËOrVáã3Óì.Ž*»Õâ–é!’fÄ×¹µ=Q^åF§¢Çw©%Ø©¦£²[èêYÉ4±G#wEÙÍb"¦éÓ½6Íq}:Å®¦iwŠ×eµ±²UÕÈ×9±5\ETj+—w9©Ñ¼ÊÒÔÃYMe3ùá’7l©»\›¢ì½{”õ 7y¿@U G-âXõ·ºNôS7›ıi_C]GO ÒT$ ެrºF;—gòÓ3n窹wEÙ"ß(vK‘Ú¸ÌÀíö¼‚åGK%¦ÌçÁ\‘Æå[B*«Z¨‹º"'â(÷jê>íúÇ‹Ú*² –ñEj¶PƲÔÖVÎØ`…‰Þç½Êj|ªGXÇÜ:æWèñ|kYqjë¤ò¤0S6½­tò/scWl’*ø#Uw*ó¢SÃ|¿Ø±‹\÷Ì–õAi¶Ò·žzÊê†AMö¹ïTkSåR(ƒŒžª.M´Ç®x§nç#QέFú®ßª$ü4™L ‹¸”¹õ5jUÞÑ_߇]*)ª©¥ðóI¯cÚ¿"¢¢•wÉ-|½ß0 þ[Õâºàø¯cªª*µnˆ®UØ+§ WÌõ·ˆM¼æ §ö}SÇ+²GTÉF–ÊjæIP³Ç¿;9Z«Õ¼®ßÙÊ»÷AqK½¹žEUÅm“(§ª©ºµ˜¥5Þy«;WmÔîNÎ$¦^‰È«·'Dj* "tlšÍ¥æµzs>¡ØbÉèbtõ6©+XÚˆcl=³œæªôD‰yÕW¹½{~ÃÅ7™FI#ë6)]v¨‘!‚® Úy¹±½} ¾ÕUP¦’”ð_² -hªÈ2kͦÙEËSY[PØ`…‰öÏ{ÕÔùT‰âã;…yªd¥f¹â¨øûÕõ|¬_‘êˆÕüJ Òe3ƒWÀuCO5J‚¦é§Y•«"¤£™)ê&·Ô6fE'*;•Ê˲¢•×ÊsuºYøaš²Ñrª¡¨÷~½­4Ήü«ÚnœÍT]¬è¶@¦Üñ¥šuÂ~Ÿ7W5ZÕkºÜ=Ó–6\ëùª¥Ý:¦5êÕU&íVó*mèªoж¶ «ʬùV3·ÝlõQ¬ÐWÑÔ6h$boº£Úª‹²¢¢û 2€Ò° jÒ]T««¡ÓB±äu¶Z˜íõm™Ñ1˲9ÈȪ›nÚá¤6,â5¼j5Š*©š x­UµµO–n^ɈÎýßÌÝ“Çt*hÝÁ‰Ê²ìW²Ï’fy¶Çj¦Ù%¬¸U2ž*®ÈŠ÷ª&ê½;Õ{ˆÿâ·‡ Æ÷9Žk>-Wr¨• ‚k›§‘Wddjý‘îU]‘ª«à °9Å&M‘ÑyI°«EAr‚†KÞ*×ÒÅW#br:xy‘X‹²¢î»ôêtW?Õ4ÒºzJ­GÎlØäUïtt«q«d=³šˆ®F"®ë²*o·véíBŠÍ:hÚÁ€´çøM÷n Z²›døÓ¡}J]¼á­¥ì˜ª‘dvÍF¢µÛ»}º5Ÿ‹ï÷ÆcvlĪ.ÈØbÝ5²ÈåÙ­cݳª½«º•SD° 3X5WÑ<½jWr¥¦§¶RM4Í;cueCX®Žž=×Ò‘îDj"uêW¾¸øÃ5w©¬Ö—ÃòW^Ýn¡µÇVèÝSÅ Ç"6W9Ê®’IÑvô>R†“1ªÛƒGÔ]rÒ $|0êN£X±ùêYÚCOYVÖÏ#;¹›nõné¶è›oÐüð vÑ­X–J;Ôì~ùVÖ+ÝKG\Å©kvõ»%Ùû'·—b¦’ßD´‡ˆ}bÒ¾2ï<3ë¾k>Kh¼Êã·:ºx |nsZWoŽíXîÉɲí*5m½í(Lh ¨,û—2ÁriÎ÷r²TgUUé˲n»"ˆ‡âvlµáØôREk³Ó2ŽŽ9$W¹±6kUËÕvM“uëÓªªõ î*øI¨âVáÝiµèj|rÙNÔ¶-Ojù×*«’f+6V3eD]º¯]Ók¯%pÑ—pðì¦<£;nDËÄ´þf±I25¬»ŸŠ¨×ª¹6åUé¾ê½6”õž¾ómÒü‚«§È&¸ù²ELÜ~šà×½íg< UDW7››ªí³UW¦æè£z=«:ŒýKű|‹_5ަ¾ºyñ|¿M™O5kŸ­ª‰^±¦Ìw¦¼¾ª¹Ë².× Ì¯Sø¡Å²{5·†Ú·Š­í¡¯·e4ô³¾›™¼Ž|3"¹_²®è›&è½Qu–pËÝã#Åí÷¼ƒªÇ.5Q+ªmuS2Y)^ŽTV«Øª×'MÑS½:'q ]øaÌmwJëö’ñâõU“ËV´5ÒGt¶¶W¹ï^ZiQÆó9©²o³[¶ËÞ“š–ãEg¡¢»Ý=Ò¯§¦Š*ªÞÁ°ùÌÍj#åìÛ賙ȮåN‰¾È¥©ZÝ¥š?Qi¦Ôœ¾žÄûçmæ <2¹’ö+Ié1ŠÖíÛGë*o¾é¾Ë¶W Ô­<ÔHeŸÍìyiÿ†Ku|U‹uÙ9ÚÅUnûtÝsFÕmrÐÌ7)¥ÓÝ^Xé›q…‹ UÒÒé­W«·‰Ó«]\ˆÆ9Èí‘HÕW¿m—LlÚ*Úz¼«G-X|p\ù#«­Ç`¦c'sS´kdtˆ®D—›guôÓ7€as%“cUÄ· }ë*d¥jìæ²©›½ÏV웹ªo¿Us²N2ô»ÉkñÍFÇóLY”U2Ó²çpÇçó¦µíD’ÆŽ{šä{]Õ‰ìño0O ÇãÙ›+±[òlz¾:ë]Öš:Ê:˜÷å–Žk‘eMÑS¢¢*w*"™Ös¨ønœÛ}Ó˯QQ±û¤Q"+æ™}Œ»¹~^äñT<\»Ešf»“Ó+Ø|5ì]ر‡¢j®yDF³=Ñ ”u#ˆ-8Ó^ÖŽ¾éîÚ=ÓÜêI%k½’;~Xü7G/6˺5H6ý®š»®yñ-!´Ô[-®k[4±¢%JFõF«¥›uH›ºý¦ÎÙªõC~Òþ±Ürowu¦ šì÷¤« šçRÆþ¼ÜÈþ³î«¾ïDOó|M渌¯•Ñæº¾Oš9Ï÷Á=£erýŸ¢1MwJôÖ,Û˜šçéO*cÏË”ëÁ ÍœqÄ\¯¢Â­ÏÇ1ɬ|ñHèbåßeI*•9åTîVÄËÕž$‘¦ü%`X—eqËôMrnÎ圴q¯ÅëÏâžšª/*ŒQEO ‚&GmF1Œj#ZÔM‘¹eü>Gj+ñøº¦íκ¹Gu<¡ƒÛlUVg”ÛŒ-Í£åOÒ¯åLú5éÕùRÒRÐÀÚZ*h©áfü±ÄÄc[ºî»"tNªª~ ¨ˆˆÒ¹™ªuž`ª€Kz–¦~“ôØB¾Mo{ᛇ鴚¸Ø÷©jgà9?M„+äÖ÷°Pþ¸~›N]áwü¿¼§ÙSe•þ?ÍîZpóBçÊïEÏ?ì¿Út¥†+Ï” Þ‹žÙ´éMîËŽà¿}oøéXÄþ&¾éö2^Mz&/÷õÏõÉKHU¿&½ûúçú䥤>ÐDÀ­ñ9öcÃ>ãMúÓ‹HU¾'>ÌxgÜi¿ZpüòÿQß"ž/õò(€ [Âý¶=)Îõk‡¢–ã+ï¶FÉ #GÙî l£4F¹æ¹ȽîÛ•œ¼©tŠÆ=>jÆ Åõ‚'GEE,xŽvÈùZÙ­5R#`¨‘UZÔH§sQ\çurÓ§ªÅB%¶ù$çÙì-¸òâ7©úTñÓÏÇ•ƒ½âoESË’uçMSOYO]$ñÏìl‘K‘Ì{›£š©ÑQQQQPýæ4á)H@nÕO@éc‘'•ŒNÖn_’Nw¯Æõ+<Èø‚ãZ’ž&:|KA(䪨‘ NEVˆÈãr/EXX×=:²HœÎ.yõWƒ,’r|Š‹—cJïNü÷O cÑǾeÌoxÛÓÊ8¡°@–pñIC¤ÚÓ¬|9,͆:+êæ8ý73œžåW²79‘+—Ô†NF*l›9껿™U.™R¸Ù··K²Í>âÒ†‘‹«KW,q«å–ÇY+X›5#wðRÈç7ÒgYU»ª½6‹m¦K9þI{ DyzoSô©ãçåçdá/x‹ÑTòM@üéªië)⫤ž9à’)cr9c“tsU:*****¡ñÜÆœ%*3ŒÌŽãmÐû†ެrdZ…WM‡Yé/#ª'®‘"sÑæÖM÷Ù>>äYÌ€0û=¼gOu_ŸbzDÊh¢Ûš rj—?Z½ÎX#¨äïd±·»rkàû$œï=³DÇ‘nwêî¦uˆóΑݫ{ÄÙ™éž Q§xE£M0<O¬.•ÖüvÛOl§t®æ{Ùˆç/µvÝ~SbúáfùP=òÚü×íΙÍò {å´?ù¯ÚÓ –<"ÿ¦²~Ë?j´êqËŒÓY?eŸµZLÀCdaÙ>Ã>uˆa¶yî·› ¥£ƒnÒg6¦'ª7uDß•®_ÄJ˜ôRÁ`¶C4nŽHèákØäÙÍr1QQ{”õd6 RÏSeË}ž×FÔuMu}K)éáj¹Šù¨Ö¢ª¢u^õD>È¥Šx™426Häj9jî×5z¢¢§z¡fï7 U üªêII5[ÑU°ÆéÅ7ÿÈýOãØÙèÞÔs\ŠŠ‹âŠ5ü’tÎÉs[Ô+»Òk³¢ ‰ó/{–®j™¦_Æø¿ˆÕ¼£¾ý|ðE—ö•I±y8f~‹ñ?ª<>ätuL|4Ë2rº¢[|òròûyàžIQS¢µª¾ÃéãçIõO2âóÉq 5ʯ–ŠK]¢:‹…¶ÍQSM Ù_PçµòÆÅkU­s\¨«Ñz)Hä½óØ+–¤ßdÎ1 $‚¶H¬ôö”¿Ô@Þž¢Y¥…Šÿo#`vÞÎÑߊµëVOÂ%ëOì–½ ÓÌÊÃ•Ûæ‰· •ÚvÉ ÆÍÉ"½‰S"2E“‘ÉÈÆ·ndöm}¼£|%çÙ ‹Tt²‰×,‡¦} eµk&©¤çYøUU7{é= ÷r?Ñê›;B¶ñ£ÆìvZ|UÜ \jòx£m;î3ã·Ç#û’WÀÖ5¿zªHïTÙ:)ž¢D·ê¶’ç^O fíÅKW³# užJˆ[Ú\jjé*eŠ9 NWsL‹Lær+z*¿¢©HuŽóÁ…ëLªéô#GµÙ~·Í3!ºN²SHÞѨöÔ5*$c9š«ËÊÆ¯2·¹·\xh®¹kOY–SâU5ùf;H“ä¶;l<Ó2zªhVgG yû9bVò³™v~éº"ªCÕ7N0õ“†Zn¬5Öc˜ö7i‰÷ŒÖÚŠY.‘ТJÈâŽF·žy%‰ŽVÆsäTõQ\ zÒç ù Öýä¿Ï ºUËP–‹&Ko¦tW+`m;žÖn¾ í;‘:!Iô·Š £Fô;.ÓõûÖeqõWv9êJÃÈæ@¨¼Í•êåENF§£é*9—£†Í8Ô;“·R0›Þ‘[²*ê<‰´¶Š»\ðÖβR#cF@椎W/F싺ôMÈÛ‚þ i5 Gu/ÖÝ,»ãWë”ÔôÖk¥âÑ5-]5ŠöËN“5«Ê’#yùvçOE˱R&#]SÏ“¿†\L4¾Ù«Ü(2£1 eC®PzqÐÓ?¯šBª›£‘SiW¢«Ú­îj¯„oã,Î å_¬Êo\ TñÃŽ¥\´R´«4ªÂ®!¦»ÓYjê-öúÝùRxê'šÌˆœÎßf¯+×—ë‡ÁÂî“êž?å̳KöšåVÜzªé’ÉÚ²ÍQ ¬–¢E‰ÍÌF9ŠŠÕEê‹ÓrŠuêˆx›Á©þQû¾¥Âzò;Ý¢ÛQQí$tòÐS6eo‚¯f¯è½¹znd|¡œ)i‡ø5ïK"¸ÑEyu]-l55ŽŸšHR'2V¹ÝZåçr9§Fì‰×y7/Ò}S©òŸÁŸÓi®U..—ûdË{eš¡Ô mðµÏó„ggÊŽEj¯6Ȩ©ÞožU-9Ô-CÆtö Èrih«®©ež×=k k£…¯Hšåj*¢ì«ß²…bxÃAò€^3ü¿ƒÍ Ë䨪žÛs ·×äj¹ÈúÉíñ>È©ÓngTuwÛ9¾%~â œ$7‡=.vºŸé†±Sý$kP³ŗμãŸÐGùÏ/.Ý9y¹= ‹+Æf]Q…p¥US”»Ê+ìXüw zxe޶®– &2hÄnñrOÙ«’N]Ö'7uTåZ÷§º¥yÑ[Ÿ'ºð)aŸÜh Wdw[5Å;g5©P¯™_$rìîf¢'2îÔNˆ§“¥éůNøvÃcƒ¦Çî׋M%Âñ#s%ž¥Ñ7ë³#½.Ñ[ʪ‹¶Êª›&Û§•+Þ±7ý ·ÿþB]ákˆË'º^Ý@µÙ¥´URÖÉl¹[ä—µJz–1^I6o;’1ÈîTïTïE#¯)—g<6ËbÂq[¾Ar[å ÉGj¡–®u½§3»8Úçl›¦ë¶É¹U¸ù\U…Î4·Y¸RŸR²j˧ÑMá—µTÅV¬†ßæòImì½W¢ÉœînôvÉʽO¯ÉCœ^oÔý8¨«|–Èíñ^iawVÃ2£â•[ìçNËtÿ1>3Pòn=8uÐÇi«D®ÕV|¦ŽJ›etVZªªÛJU¢¤±+bþ]ÕÎHæb9¯r®Ê›"X¯&× Ù–aù6g©Öyí7\Á°ÒSÚê=éè£GªºV÷±ïtž¢õDbnˆ«²Qî©á:¡o$ÙPÿQÿnãÄÚï*ž4r*³&ÅÈž ÉJ¿ìT52ŸºàkY¯Ñâ:-xË`®ŠKbI žª®ŠãiÍ ñËO¿+ý^U]ÑäsQvTûmZ;ÅmïŒ]>Ö=YÒ»ïdyžÿp¨·Úçš’ÙNÚ¦ÆØ§{ÌcŠª±ïW5œŠåÝT+Ó2ÎùBo7íaãÐÞd¥´SÏi´Á'¡UÂHûJ…O¶w,±'ÄŒÙ6Ýw¶Xw“›†ì0ÅóŒz‚üË–-WtI=Ç¶Š®xÓv>f=ª›µü¯NÏ‘9šžKÊïÝuVÉÄn‰Ùk¯U´QR%e-º.Ö²–®–Nh*#‰=)Z©ÈŠG+V=Õ6^™='⣎RÔŒ;»h,¸Õ‘.”¿D—EÇ+)ÿ¹#{®U;³‰¼ÞŠ"¿ù+¹Wž3¢ ã“+¡Àü v|âéO=E;SŽÝª"ƒnÒH©Ý¯k7Ù9•¨›ôÜó¡vªß(UÙFµåÐZ¬”é]9îkå£l›2’:mUQe‘yºu37®-43>Ô>=qëšéFO}Âë+ñê{tz™h—´µ $ìo#ZŒææ^dåM÷T?N,xVÔÖË\'á÷9áž­&}¦Ál’§ÜÚÆµyÓ°…ª¾k39‘[·**½»¢=ˆ‰":Y+.m]ŽY4ûEñµe·š ®4T¬ì¢{`VEM#vN͉Ú*3»~EÛÑB§êOÂÇF-8þ›éæglÔjR­eò¶vºš¾DDJ„|~rö±ªªç3’4Tåj/EU/Úžñ›¡øN¬bXEâÁœX"µ¸µæ™ô5dœ½´líÚÅs›$HèÕyQì{¾ÛfšF'Æ®%oÀë¸E»Ý² m+(£¹Tã·öèÆò2Iac½\æ½­wUM·(S<8>jÛU«]<™49þ¡¶ªç‘iÅ5m-¢µÕ/j³–©‘1^TI6#g¤‹êïÞ»Ÿ/“‹…ÖM1¯ÔŒûª®¿Xò×ÓQOÂxZÈá§¥™ˆ¬c‘®Ùò9wTë¾Å¸ÊpíUÖî gf§¶gù;"Ïok[l­G,‘Å·2£UŒoU]·ê½åáC<ã3‡Jzý"Ƹo¼WS\ïl®¨šçWíH÷68ehÅcŠÈ˜¨ª»n›¢ª)U"u‰Ñ«ñ»ˆßtóŒ ¦¡jæ_”awšøj©Y%TÔ´÷D­ófTÅÖ'ÇÊ­åOI9Qvår*Ú>h¸+Èõãè5 ïË™h}-F5y«Y–’Ò1dž^¯YU­j¹$r¢9ZÎ~¿†¹ñ-Ũy†Ÿ_xUMCÀ§«|v©bª–*šUDÙö6HeMüˆäñð#~xpÕún"jõË%ÓZÝ?Æ)Ûq}=º® )•ΩG6:Xa—ë«m~è÷&ÛFÞªªS¤ž4ñ~þSæ3 âHu>Ú«Ê(X½£{÷¢­dÑ®ÞÔYÝ×âOaÒã™ÜqLºáÇ&™è…<élþcMpìúºÏ7œT*üL¥lr/ŹÓ¯5r€Uà5ÝGÇks <Ê1+d°EY{²ÖÛ©ß;•±¶I |mW«QUŠäÝQvðSb1¹6AA‰ãw\¦ëÚù•š†{…OdÞgöPÆç¿•:n¼­]*ÓøwÓ»Þ’èž!¦ùU MÏ·6’¦Z'½ð=èç.ìsÚ×*uñj|„Škšužcú¡„Yõ’y-Êdª¤tñ,r,jªž“W¹z)±ž1È@-ÎÕk½QÉo¼[ikéeElTÂÙcz***+\ŠŠŠŠ©ò*˜ÜCÃð |öœ'·Øè*j]Y%% †ÙÍk\æÆÝšÝÑèÔDéÜgN­_uOÆâ»éFmÊ®TsUÛjîi$´ý›ÿ€z¢·´çì×gtV£‘:ªm‚Ò=wS¯7 Fï¦ùv‘Ùé#«­¢½PòÃÊõåE†vª¶Fï¾Ê¨Õ]•Q:.Ò˜y’8æÐÍ_Ú­s\›£‘{ÑSÅ wk˯X¥}·Ê¡Æï³5žgsšµ¬[#\äX\¨ŽG5Í÷ôy¹ºªl±fžj/¶ìö›O5›Ihê©«{E¥Ëqyëj5ŒWtG+•ðªí¶ê©»œˆÖªuoŽ8á°ÃYkZ›#Q;‘ÁÃV4—:Íïvì›×,“¸PCØ,ðG[n=5GÉI&Í{÷~ʪªŠjmº"¤¢ÐôŽÓ¬Ö[e}²eØþERÚ•÷>²×@úY^³·~NníšÆìˆ‹»ž«ºf5Qð­+Æä˳ûìv‹DSENú—Å$ˆ’Häk–6¹ÝU{öÙu]‘Müê)©êáu=TÍöædG5v]Ót^à`pýFÀ5Ôàù¥–ýmæ¹õÑάNenîFª«SvªuN»¡X´FñlѺ…Œé½ŽÑd/µtÉNˆ×îT›FŽTUE/2¢ª*›ÖKŒ6ºÉlôÐÔW²žGRÃ4‹rL^F¹ÈŠ­j»dUÙvEîêt·ñ;©me-›^¸xɬRO-5+o8÷-ÚÚù¦^TW+ståE‘ÛííMìXÄÓEOçžVGmW½ïr#ZÔMÕUW¹ s¨8–œÚ=Úˮ̣îXâj5_$ÏÛ~V1¨ª«ñ÷'Š¢ní™ê÷W¿¡üFŠ¢Ë‹Å'eTæJæÄŒwKÓd‘vMÒ4éñ/¬j³ ÚÖ bÕ1¿vySüýP”ä;+‰Î©«v¨µ†£å]«…1Ù=‘ÓÏMa¾j×6Û,ïÆtº¯We‘"ZåokHœÉÝ#·•ûª"}®ÿÊî5¬†<ËP®_F:ã{¸1òì‰F³#ªäFú¨÷®íþŠuÛù$ˤº †é< ª¢‹Ýã£XçºLÕkœŠ½QŒæVÆž:¯Š©%Vò›Øú¢þiV½TGÉŽþ¹þøÃuˆÚ¼Ejp[/Fî¼*½T~¿£ù”úùp‰†>ÅØñ‹lvŒvÓIn¢‹Õ‚š$»øª¢wªøªõ_ !¦˜¢7i!Ïî\®íS]É™™ç3ÆdxB\l{Ôµ3ðŸ¦Âòk{Ø( Ü?M¤ÕÆÇ½KS?Éúl!_&·½‚‡ðÍÃôÚrï ¿åøýå>Ê›,¯ñþorÓ€˜Ò¯>P/z.yÿeþÓ¥,1^| ^ô\óþËý§Jov[üwûëÇJÆ'ñ5÷O±’òhûÑ1¿®®JZB­ù4}蘿ß×?×%-!ö‚&o‰Ï³÷oÖœZB­ñ9öcÃ>ãMúÓ€·à—úŽùôy¨ï‘@ô`³¬/Ôl2÷eTžsh¿ÐÍo¬ÝœŒVªµv^W¦ûµÝír"§T3  OÂþ[|À/WžuBªå:wL³Uº£™/Vg¢¾ñ"µ»ö1,q¹:"5;Úý¬i§q[ 7ýS¶Y5K.ZuCšK†;XæµXÕb¤´9U>µ*z=W•Uf¹Æ#@õž×­Ø >FÊt·_hÜ´9™üÍž×pU²Ã#³Ûé"«y“}»ú¢¢|Óá;cêÊ1sšá)ü Ùã§Í®yùªçS¬pàeدG‹«œ{@å ˜«ê^¤â:I…ܳÌÞæÚ+]¶%{º¢É3öôa‰ª©Ï#—£[¿~ɺ¥Ë6nb.SfÕ3UUN‘ÎfyD)3ƲŽx©ÕËÖ‡R`úu½V£çÕ dÆhâÝed’*6J½“ÕHšîdrôG+wj8œøÑLw‡ý-´i¾<çN´­Z‹lŠ«%}t›,õUë»Üž F·À‡¸KÒ<Îÿ}®â§]({Ç("Çl“±Ëô/h]ù!j=¨±Ï".ïTD]•wÙ^ö¥§>µØm•§e²ØµsI½_ç·¢˜ì§Û¬ô£ÌOÂnk£&Œ@Á~±Ú2{Ç¿ÐE]k»RMC[K*nÉéåb²HÝñ9®T_”¦ü9KuÐÜÊïÁæmU]U><ÉnømÚª&±·[jò"£—yb•ò5Q>Õ]râ燚­pÁaºàÕÚµ/•.•å&X_èö¬9éö’±ªÝ»Qܪ½Qc{U³¶vŸ-¯rt«3ÕTržîq=’ÈÃ_œ=È®h"½ÖøuzÇYo¿ZŽç8ÌÉA”cÕ É5 R'Wµªªå…뺱Ý|SuTÝeCä~–bkÂb©Ý®‰Òb¾SÎ'¦8¥WMÊbªyH1À)â?W+ô§TÄ©™qÎ2IÙgÅ-Hˆùk+år1®l{îæÇÍÎïUS™ ÓPsüWKðûžuš]# ´Ú¡Y¦‘ÊœÎ_µ‰öÏrìÖµ:ªª!pÃ¥YF©jG:Ù`©·WÔF´¸=V©µ–Ôæíç/fÛ¥LÈ®UU]ÑÄgAð±õí.:/ßü{sTôU<âˆïéêŽÙ†;z4§åO÷ªaá“Cè4I혂¹*¯õiî–IrsÖInYQ<¯‘Þ“ý/Eª¿jÔñÝVWú®""4„h“c8þgÜ1\ªÑKt´] u5eKñÍ“«U?ؽ訊›*0-á²»#Ò\— á?Rî uËwáµSº6>ñ=Ïdk[ë>%‰ÈÿæFõäU,9©qaÃÕv²cVܯOe£µjvW×»JÔMß¹I+¼a‘:*;vómºl®EÀè6³A¬X½\×+Cì9f;XûFMa™ß^¶×ÇÑÍÙz¬nÙUŽî_I7Uk¶ù·Â~ÇU•â§7ÂSø“åD|ʧìªxöN±Ó þ]Š‹”øª¹Ç®Xä ¬ê>£áúQ‡×ç9ÍÞ;uªÜÎg½Ý_#×ÕŽ6÷½î^ˆÔïù7Rå›71)µj™ªª§Hˆã33Ê"™ŠcYh¼Ojýn–`-¶âTÓ×çY„ÞáâvúfsË5|©Ê’"&>drªôß‘Ö%îtV‡@t’ϧpV¥Â¾zËÅÉw毸Ìîyçr»Ò]ܼ¨®ëÊÖ¢÷Ç Zeœg¹ÚÙmž‚ïz…ô¸M‚w»ÿ@Yž«é9Šˆ‰<ÍFª»½Zª»7Ÿ‘¶ÐúÇ`öR6[.Ü»ÆõÍ&¹êê¦;)õÌÌòÑÆâ~sXå€8a€3|¨ùmþkö„gLŽfùP=òÚü×íÀéËŒÓY?eŸµZu8å¿Æi¬Ÿ„2ÏÚ­¦` ¾8¬÷kÿ ºg±Zêî5õ4tÍ‚–’M4«çp®ÍcQ\åÙz'0ãÑK‚٠Ѻ9#£…¯c“g5ÈÄEEEîSî«©¦¢¥š²²¢()àc¥–Y^dljnç9ËÑUW¸óMSM[MeDSÓÎÆË±=ÉäÝ®k“¢¢¢¢¢¡ênó~€«@ ïªÜcÙþ¹Xx„ųJü;-³ºÏ-+&޽ÑlÖ,­r§|{Ä6Eîëb ë¨ )w¼#j¶®ê)­ú+q “$Åé ¦÷:²VÇ̰T>¢ btˆ±+‘ò;™¯Ù½WªN[aò£ën#Y¦Yn)†âÖ‹Ä+Eq­óª4tð;£ÑëÓ¹­Tè½›vî: =ER†xLá΋†=&‹eÝ.·*ÊÉ.—ZÖ1Y•R1ŒT«ÕÖFƦýû+¶EvÉ3UI@P?ŽæVª1Q·ETÝOè»èw¸æ‘ê¾G­·üÒã™æÊ©]_NÈR‘frºeUMÝèµ§+Z›"©b ÌꀬêŠã”iž]ŒÙãl•÷{}+ôk]4´ïc\½ÎNªlÆ3ˬ8'wÍ²Š·SZ,tr×VÌØ#™ mW9Q­Es—dîD ´Þp\‹LôÀòÚh©ï[[)«"ŽVÊÖIÌåV£›ÑÛoÞ 8Çã·ëVUÛ2{Cª-·Š8kèåtO‰ÒA+ñ¹XôG±U®Eår#“¹Q¡<2c €>[¬õVºÊ[UÁ´5³SÉ5S¡I’ UªŒ‘cUDz5v^UTßm·B¿bYwZa“Úð­SÂáÔ{®:*|·ka©§G9$­¦]šÖ¢usÓ•¨ˆ¾“Ô±`r¢âU´–üËXpZ+ë–Ù—ãIWosÞåHâ©‹¬±9z5é9SÑÛwc@A¦Å>+’ß3=(Ô›.Qo®—·‡ɨ{6@wŽžª'5QQ6F£öoUæUTÝfN»"¹cVêü¶Å šó=;_[A ZT²ž_$¨ˆOú{̰“Uøx ÔŒž›?²j_†e”4+AOp³\"t\ÎsY,EkØŽs•ZÕfûõUÙ G¬š¯b’Z5ƒ.µä×zzÉKr¡¥Zuš•šÌÍ‘©77>ü½6VõUÝT7€|µ—[]¾zJZû•-4Õò¬4±Í3XéäF«•‘¢®îw**웮Ȫ}@yådqFÕ{Þ÷"5­DÝUU{‘ð‡²Ö¾#qÝ1¦’Óc’’ñ’;v¥*IÍ"õô§V¯EEÿ›Ý¿æ¢¢š6­ñ5q»]!À´=Ë_]Võ§’ã *ç:EUNJtTÙ|W´ÙSn­ééႇzez[ûåíá§|‹,4Îïæ„²*®û®íEÙSuêGqì}ÉÂåœtùUüÚ{ºçû펇—ìÞ"ÃÓšm6±Æ‹ºûj›O_Oª'JÂt+Põ¶òÜÿY®•ô–ùU%§¥zí4Ñ*ªöq±Wûž-þ-ÕtN¼å¨±cö lò‘—û ò+(òªF7¤OðeB#QõÙ¦ê›n¶€1X[8Û5añÅTULO)‡ªjš'zžjÕ¢Úýƒku¶£Ü'Õ[/ö¿­ÞqÛœKÆÙ/r¶HœˆªÝûžÝڽ˳‘Z’Q¨ëÿ VMWº3R°,†«Õ+t\”=±<å¨ÔD‚¶=¶¨…Q½}&¢7ªµއì¼NdšSx¥Óž/ñ5Â/oÚž¯šÁ{Tï|s#v…ÈŠÞf;£wÝÝžèÔùËkübòªªÅe7lþo:éó|èíŽ=qÃVû ˜ÓsÉ»Â}KΚ¦ž²ž*ºIãž ØÙ"–7#˜ö97G5S¢¢¢¢¢¡úšcNÙ€.qÅ4Rä“i¯xEn¬æÑµ½´6y™îe»™\ÞjºÔÞ8¹\Ý•ª¨›¯*¹‹Ý²Ê²|vw~0Ø s]]œ£¶fxDvÌ­Ü»Ešw«!#j¾±éÖ‰ã.Êõ#†×F®Xà•džªOý\17w=ÝÛì›5:¹QU#ÍÑLï_ó»oÜEÙ§³Ù,ò¶¯ÁgwüS¹Ì¯®oBôTbõj÷¢l6á:çI“[õlj•s}LŽ$u%3ÙZqÝù\ØèáFíÚ±S¬Þ+Õ›wºÌŸJlOƒì6ÌÄbñ313þm=”ëë×Tñ興×Xþ/V#ɧ…>Ðtv¼ñ!þC“Þ©µÛB«),ڳѾ–©j-ú‹mÖ†©Q7ÿÕɺ+WdUDåtx׫®SÖX«èeÆó«¬-\¼µvùš¨×*"íÚBª©Ë#zlæï²®Åœ Î!xPÃõºJ|ÊÇp› Ô›B¶[F]kb6ª75ªŠtM»xU¨­UÝ¢*"¹®ƒíŽÃàö®Öþ»—é&½9þÍ]q뎎˜œÌ&2¬4éΞ¦Ð íEÄ.{¢÷º| ‹\9öæe%{nóXn²tk]#šßîW»½QÈOIUÔBÀÛ®6û½ ;M}=mKH*)ål‘JÅîs\ÕTr/µù“;ÙìÇg¯øŒÂÜÓÕ<髺yOw8éˆHlß·~5¢_@Ò¯¯©:—…é&#Y›ç—¸m¶º&úÏTçšM•[Mï|ŽÙvju]•{‘U#mE⛳eé>“Y+µR¥î§±ÚކÉ:>ª¥ÊØãmù\ç'DTo2)‘Ó.ëòœÂ lâζٗæpö2Ú,”]«l¸ò7ÒäŠ5zöïæê®“™»¦þ’¢8é;#àãŸÕN#kÏY*¨ý˜ž‰üéáÕ«_ŠÇÑcÉ£L&—èöiÅQkÖ¾!,~åà6¹’á„àUQ5d•Û*2¾çÓÒr·g6Uj#º¦ÜÝ­Æú_.˰¹NŒˆ¦Ý<¢=³×3ÎfxÌóGî\ªíSUs¬€5à+\:æwŒÎ‹ˆ>.”v­IµS6’¾‚­Ë¿'·µwóZ»¥Nèå]¶ÙW5ÇÇdg†³Œ³U‹ôÅTULO˜•iªiêy«^Žë¶+«ñWÚéèë¬9]…YûºÄèk­³*uG5ÈœìßtI6^›£Uv$“Tâ„ÜOY®´Ú‡ŽÞ«p­J´FÔµeÅÙû±wdu1tmD^ ×uÙU7åÝ«[xÍ´zûI§Ü`a±âU•2-5·1·9fÇîÎj.îí6GS¹Û#¹\ʪä‰~sÚÿø¬²ª±yƒ’ÌM3¤ólÀE@<â¶ÅDÍ2Ћ#µKP*^èYl´T5)(ÜŒzóÔÖ/ÖXVìæó¢¦Ë̬6Y^QŽÎ¯Æjk«³”vÌòˆí™…»—h³Nõs¤$ÍLÕLGñzŒ¿Pr*KU-wf’ȉ-TˆÕrE 7ÞYvkw^нR1Ñí ͸–Ê,úÿÄ-¢[N-jŸÏpŒf¢±Q{;…Å®Eç™QQXΈݑvDUGlšUÂmß0‡[x¦º[3ŒÕ`bÛl­£ÿиÒ.îtTñ=ÏIÞÕTÚW¦è­EM܈òПIlGƒÜ>ÍDc1zW‰˜çÑG\SÛ×Wš4uÐc1Õb<ŠxSíIkÀ™¾T|¶‡ÿ5ûB3¦G3|¨ùmþkö„`tÈå¿Æi¬Ÿ„2ÏÚ­:œrÇ„_ã4ÖOÂgíVÓ0 òÍA‘Ù.õÖ.ÖŠéK-LËŠF+Ÿ®R à¶×¨xV–Vi£ãõÔµZ{x«±ÛîrÒv÷ŠzÉL¯¦ÞWòómÜEUz?k|õõ¢¢¨­e$õN‚'Ê@ˆ²J­E^F"ª"¹vÙ7TM×½ ÃÅq¬?PFš-ÄkºgbÕÓÑ^íÍD»ã×(–žçl“}•“BôæMÚ¾ÝúYébc@;‹í;Ô}_Ó=*ÀmôÒRd·º2*ɪ[™Z£™²Ë#Z®k¤^hÙ»Z»«y‘;Ìî¹ñˆh}%]Ã"ËoîXl½¢>Ö¾ç7rlÔþ4_ZEîD]‘ÎNUßp»†IvÄíLÇm‚ùUG·™R”u ÔWÄ’³Ñz5wNdè¥&W(¦fueii¡£¦ŠŽ™œÀÆÇwUÙ­M‘7^½È~ WÀÓþ&ñ¬+ŸNu¸iÞfÊ•‚šÏ}{. æåcéjõ©÷è›1Wu_G="e5œóL´ÿSè)­šƒˆÛoÔ´u ª§Ž¶e"*.í^ôEÛeNç'EEN€lÀó$‘Ã¥–F±Œj¹ÎrìDïU_0ø~k‰jŠ› ÈhoV¹Ü沪Žd‘œÍ]œÕÛ¹É⋲  &­h–œëm¢–Ѩ6GV%«= L3¾ ŠImÝŒTTUåMÑwEÙ:tCáÒM/Ì´Æ¢ãkºjõó1Çh¥½Ã•´.j¿´çªj5Ó¢¢±™—•vøäËqºÚìð6ªír¥¢…ò²ÉS3bjÈ÷#XÄW*'3œ¨ˆê«²QƒÍ0|GQqêŒW8Çèï6š­–Jj¨ù›ÌÎj÷µÉàæª*x)i^]´w)äÄuW ŸZi)tVÕ²’mÛÙù½Cþ¹-N­§zª*«€˜AøÖVÑÛ©d­¸UÃMO y¤šiŒb{UËÑý€aòܶÄXj²L’½”´4­ÝÎ^®{¼Äûg*ôDCÍuÓn™®¹Ò!rÍ›˜‹”ÚµLÕUS¤Dq™™å¶ëu¶Øíµ7‹ÅlT”T‘¬³Ï+¹ZƧzª•7>՜³ôçJlÕ0XÕíJª‡*µÓ³›nyÜ"‹Ç“ª®Þ*¼©š«Sx¶Ëf¢¢¨’͈ÛåG+]» §O=nÚuMÕ}“uÙZŠª¶“NtßÓ z<{¦Tnüõl³TÉü·¹7ø‘:"wš®â6‚©¢Î´aúj鯲:£·ÿŽ“F°4EìdS{0á4Ñ΋]15iή¨èç5ýÐìWJ-q:h+¯Ò3ûªç$h¯ÝS«"߬lë¶É²»¢»~›I >ÖÜZ³N”ßæ†+5ÄUŠÆW5×W9ŸduDtDpŽ€_a5MXÁ)5?L²<­åHòMU½çr¤rI£¾ÎÙZþW"ò®ÊËÜso€}h¦Ð\ß*á«WgŽÄú›»¥¡ž®5‚8î-jE,R:Dkš’²8V5r57fÝò"O*ßüã¼JÚ]•c.¦³ê Š–ºEs`¯‰»ªSÔ"o·zòȈ®oD]ÛÑ4ÙþI‡Ú,¾æ_‰ár˜çbcº}1¬.ؽUŠâºS 9­…ñ[Äwšm+â[ ¹^m0±C-D¬ó¸éÚªœÔõI»*£MûœåTèÞv¢#Rêé?ú­ôßAYí¹n5=Ñ[+i® r&êÞÁëÌý¿”ÎfügË{E°ùÆÎW3zÞý®ŠéãN½4ùüÓ<Ò;ËWã„é=IPCÙ`yª¼@èþ‹Ûå®Ô,âÝoš>Œ dµlÎåG#YNÍä^Žo¤¨Nf«•w/á°·ñ·bΉ®¹åÄÌÏšjª(j!!”ÊA¯öËݾ†ÌE¼_+î>õ$K3£s\‹#Q»ªÌùŽV·ÒNV·í• {P8ãÖž$r }#áK º['º5UjUÌmÑÈÇ«¹›"IØÒÇÈæsœ»*ªs¢zÖƒ®è´Rêš©«— \“<›ëÔÌMå‚×#ú½è÷ušuUTY6DN¼»ï̽Ï`üâpXª3\Þ7f‰Öš9νTòáÎ":t×M4>70¦ºfÝ®ž”óÔÕè–‚ášeq‘¯¯´P+«¹ÌÖÕÏ#çvþ“[,¯j/Š".ɾĠÜÚ`«|N}˜ðϸÓ~´âÒo‰Ï³÷oÖœ¿<¿Ôwȧ£ËýG|Š ”bxÆod©Æ³zÝ{µV7–z*úfO ‰ñ±è©ºx/zx`HÈø-Îtê¿èƒ„}_¬ÄØç~!‘O5~?.ûnŒEç’Ÿ¢'V£ÝѨ†*óIJé$|ºýÃNGIM;Vý‡Ïêß3XÇ9ò¹VËLÅåèÙzíºªô.`"¹ÖÅä™üïâìFÿçSäÕç˜çþ¨–Mœ]ë)ž ¥ˆqƒÃFmN³ë ‚žIœŒl79–ß':ý¯-B3uðéº*í²®èK˵ª÷GÆÍs¤¯¤•¨è祙²ÆôTEEG5UäT6 ËDô{Q²çZ[Š_¦vß^¸Z žTÙÊî’9ªäêç/Eûg{T‡îÞNŽîuì¹Ói|–ª–szVËÍm2/7ù­—•;Õ=N‹·r&Üûà_ \ë„ÅUL~Õ1W®&c:œÚ¨ùTÿ~´”~5•´vêY+®pÒÓBÞi&šDcžÕrôDùH­þN–)©a¬Îख़ë#©£Êj{-÷ENŠ«¾Û'UÝz'Sé¶y7xA¢¨óÊý6«¼Ôòµk•ú¾Ur£ywTIšÕUOjl›&Û4x«_/òßÿ»ÜæñÑG¯ú=e|Oðó…6eÈuŽJ~nÖžšàʹحMÕ9äEÛ¹9wU蛩¢[ø¨ÍõAƒ‡N󌻶nÑÞ/2ÍgNhÚö½*%UíÛ«=^œª¼ÍRÆá¼7hŸ=&ôo¶T7}ª£´Bê•Èí»g5dÛvµvæÙØI“-ðE’a'{Uwgªgv=ñÿ“æiz®ÄBžÓp•®úÛo‰8¥Ö·[í39$ŸÁ[æ”’1Uêè*j^‹$ÍëU«ÌÔäw+•Ê’SM4—Môs‹Ó,:ÝÛbj5c¦b¬’쪨éer¬’»Òw¤÷9z÷›p:N/Âe–¼FÝ4QÕLDG«§µ]Ê®NµÎ² Ç€;!Çl9m’·Ê,ôw[UÆ%‚®Š²Ë ñ¯{\Ç"¢¡W.œ Ý4ꪦûÂv±^4öYåtòã—6û©a¨^þDŠM䃙{äE‘È‹³Q¥´>+ cjlbhŠèžqTDÇ¢^©ªª'ZgIRzÍyâFè∞ïuT°²U¨ÉpeK+d–HwGÓ±Sw*Èôé¶Íßv·iÄxÂá·3›ÛõbÍATìMx{­ÒµüÎN]ª›®í^ˆ«ÞßMíy§æú;¤ú—²êšã9Û·,·;\53nîW½ªæû:/wNãœfž ²,tÍx}ë3û3­>еõL3íæw¨áW«g¿Ø²V×X/T:w5Ù¨êY3}•ÅTÙv_èSï#kÏ“›ƒÛ½KkY¤þæÔµé"In¼WS쨪½Ù¹ªïº56DEÙ61Íòppí Ô6޳;¥Š§t’rš”b·¯¢»ªª¢"ªuU"×| ο‚Æðí·ÿïö2c7ë£×ý¥emº–Jë…\4´Ð·šI¦‘Æ'µ\½>R8Ëø›á÷I[“k/Ð5]%4쪨j#yúÃ<›«U—uÝ6ßsñ¤òmp‹LUwLåy–5ˆë†C_&ꋾꙨ½wéêõ^„Ÿ†pÃÃÆžÕû£‡èÆ%o¬ææmR[#–v/ù’HŽsâj¢X_Øzg\V.ª£öhŠ}s5{jͪù´úÕÍü]ÞµI-¼5hFi¨µ‹š+œÔ‹k´µ_'gQ:'¢»9û*3Ñozlõf^“…Þ#u¾è—$õu˜®3­’ ;¨’ÙQ[çUÏD{º¢s1í_Y‹—Ü—`²,ލ¹bÎõqó«ò§Í¯žØˆa^ÆÞ½Â©áØÓôÇH4ËFqöâú_…[1Û¢²6’/®T9©²>i\«$ÏD]¹¤s·MÍÀbÄ fKŒc™Š³ËlT7›EÂ>ʪ†ºÍÍÝÌr*.ʈ©ìTEN¨dÀëÀöG¦W:œ›„}Y«ÂVUtÒbW´’á`ª‘WÕê«-:/]ÞÔ‘Þ åC[¯ÜBi *Þ"8e½¾ŠÕfÈðW6éAÙµSi]:ÉOÛª¬¯Eè›5wÙ.À#ÖÆä¹üÍxË¿?:<š¼óüú²,âïXáDðULW‹Îrõlví]±RT9ý’Ó]euºfÉ×v+*Q‹¾è©ÓtߢoºžÿbÈi[]`½P\éÜÔsf£©dÌT]öTsSeÙ¡M£6Ñ"Ô™V£P4ÇȪ¬gœ\­0TLj¯*$j¹7^åñ_jíçÉÍÁíÞ¥µ¬ÒsjZô‘$·^+©öTU^l܉ÕwÝŠ›""ì›óà_\ë„ÅUL~Õ1W²hgÓ›W*ŸïÖ’OƲ¶ŽÝK%u®Zh[Í$ÓHŒcÚ®^ˆŸ)·ÉÁô+PÚ:Ìî–*ÒHaÊjQŠÞ¾ŠîªªˆŠ©ÕTýé<›\"ÇS]Ó¹^e…b:á×ɺ¢ïº£fj/]úz½W¡GZ·¼¼oËþïs›ÇE¿èý2¾'øy›2ä:ÇŠÇ%?7kOMpe\ìV¦ê‹ ò"íÜœ»ªôMÔ âß$Ô”} ¼>gìÏ‰Ë Ö²™-VŽeV£UjgTEïWr¯"¯.ȽUͱØO Ü>éÕL•ØfŽâ–Ú¹6Þ¥¶Øä™fÈôs𛵫²*&è‹Þ„šHòï9&¨¯]wgªgvŸE<äǹš^«…1¨p·Ä¶Ü)î\E뱌qª’ý`}:9ÈõV¶¢½Û¾DÙ±«‘Q\ª¬ìÕ¨«côÇH4ËFqöâú_…[1Û¢²6’/®T9©²>i\«$ÏD]¹¤s·MÍÀ'–àò«1cn(¢:"4ôõÏlñ`Wr»“½\ë ÍxfùP=òÚü×íΙÍò {å´?ù¯ÚÓ –<"ÿ¦²~Ë?j´êqËŒÓY?eŸµZLÀG¹>énW¨V]W®ÆÛK—XêYQÞ‚GSTT#Ê‘T:5NÞ=¹S•ûôj'vè¹íBªÏ-ø}ƳLìÖ«¶KcZ;K©é¦^ѼèùŠ­^Ï[Óer5dUSdW™¦*æ‚tóP¸³»eV»f£pëa°Øær¶át¤Ëa©}:#¨öÀ‰»‘^M·Ý{úî][‘Û1‹¥Ã°Åz½ÓÒÉ%¾Z¦Ó2ªtOB7Jíш«¶î^ã2 ê§‹¥_±Jã¿$µPäü2cö»=Mt\+¢Í ô´Î‘©,ͻլW9Wm¼IÚç5u-¶®¦ÝAçÕpÁ$Rö©o"5U±ó¯Fó.É̽}Ϭ I·J¸Sj—2ÔÅO ¸Ô=íl’ýÓ»‘ª½]²3uÙ:ìXÝ”ô¤Û¥\*uK˜ªeŠ›…\jx˜÷69~ŽiÛÎÔ^ŽÙYºnv,%±× m´’Ýi₵ðF꘢3*µ9ÚÕñDvèŠ}`jMºUû&Ô®1(2K­1Ã&?t³ÓWO¾º\ÒULÙ‘LèÕ»±\Äk•«Õ7ÛÀš1ÜŽçŒZîu†+-9+íñU6¥”³ªzq¶VìD]örw™5<](/>Ô>+¬ù}ÊÛ§ü9Xò ~µ´W*œ¾ I*[ÈÕs–%j«=%rl¾ŠIÚstÎo˜m¾é¨ø•63‘OÚùí®š½µ±Óí+ÛÓ5Í1ý¢¹SÀÙ€Ôñt¡QÏ8™°er[t³@mU‰FæÜ«2¨(_$ª›½©šªˆÞ‰º÷ìªnZS|Ôì‡}ÃV0:FõçRFÛ}Ñ•ììË"ÊÔDÝU]èølžÓtSÅÒ‰õw1â½ÑÓi‹Ú3;d´½¥MUfG¹ðOÎäìÑjó'*5y“Ú¨e´ƒ#ÖL–Ûp©Ö5¶á•qNØè©hï,¸öñòîéö"#zª"7¿¢¯°€Ôñt£McʵÃ÷#é5¤ÖÜÛÎ|ãÝ/<¿GmóN^ϲåçEí9ù¤ßnîDöŸžeÚí“TÝ"Ö=¶ápÀÈA-AÇÎ\ªîÑ®F5›"1Q|w_a'©âéhZ»‘êÞ5d£©Ò 5¡ÌîrÕvu4µ—˜íÌ‚G/hz/2ór§*{UMI3^#2L’¦‡WtBчYã¡|°WQä±\_%JI6EDV:Gsw'"'‰.©âéj£|Ô\{’á¥Ø6]~íãŽ;}MÑ”öj¾œ‹+ÑS¢'ªUU=ŠhšižqEËémº™ 6!r¹iþ5Md1®¢¶ÔÖ¥$u.çj9«*¢£=rî¾(ˆE8N¡ñoxÊí–Üׇ,±O:6¾å_ [é¢ÙU\ØšÔW¯M‘>=Éà OK“U_h1»­v1hŠéx¦¡ž[} µ *ª[–(]"ôb9èÖ«—¢o¿Øõ;Œª«Ý¾šýÂæ?Clšª(ëj¢Í©å|+Ñ$‘¬äô•­ÝQ¾;lX`5"Ý/Â¥ÓÅM,´Ôý¼Ìc\èÞw"tnëÑ7^›•Ï髯ÿù&ã_Ÿtÿ0²`jEºaçe)õwøíW®Ò.ƒb•7èg•”ô’f±µò1¨¯j+û.Ë´äÙUˆîdê›tRmâ[Z©t?Lêò(ÞռתÐÙ¢V#÷ªs¨÷5U=#UÊ¿è§Û!Ê åâÙ|§Éhn3Çt¤«et5|ûÊÚ†½Ù7^÷#‘uñ&[9²ÓX¹ˆ»TÓO*{jëžÈìç×3ðytb)šªów»KcšïUd·Ôߨ"¡¹ÍK•´±KÚ² Õˆ²F×ý²5Û¢;ÇmÈK.Ô~/m™=Ò߈ð×Þ¬´õRGo¸K˜ÁLú¨} šªÅTÛv¯q¹ð÷¬vínÓ;~_gÆ=èîÔ­_à*؉ÍÿUÈ­{vߣÑ7ÝJ"x›p—j±z4ª™ÒXUYñuM5G`°šÜ²çŠ[.ņšË~¨$®·ÓU%Lt²*¯ÖÒTÙ²mé'E]ö"ÝFÔ*,y•Â×§=XòlvËÌ®•9l4RTo&𹪬å‘^ΫÕ‹âM೫ϋ¥ªi¥ã?¿â·-LÂé±\Úk‹+£¨õF9%j"/3yWoUCIÕlã‰,{'e¿Iô"Ñ—Y<Ö9p¬Ê! nªîhÒ'5WdDo¥ãºû „ OKGÒKþªd˜ÝMv®éåx޹ñACGveÅ’S$q«fYˆˆª÷HÞ^ôäEñ0z¿˜ëî5r·Óhö‹Ûs:I`t•µU™VîÂNm›Xöª»¢*«»º¢{IP OJ9Ñì›Z²jk¤ºÇ¥¶Ü.Xh"£½Çqó–ª;´s•ˆˆÍ•ˆž;¯°kM­XÍ5®]ÒÛni,ñV^ã·y³QÙ¹ªôT~ê¯EO “ÚHÀjxºQ^eÚÿ“\®kÚ0º( k¨å£È#¸¾¦UwVª1©ÈˆÔßuïÝ6îS9«wýTÆñºjí"ÓÊÆñ%s"ž†²ìËs#¦XäWL’=Qí¼½ëΫàojxºPö”çId9;íú±¡ŒFÉæ²HÛ…&Q {ûtVòƱ5¨»*+½/ “ÚnÚ—xÏì…UËLðºl« câm=¶¦âÊäj½îY\ЉÊÞeÛÅQÚÀÔñt¡ 9Ô*/™•¾×¨ü=Xñœv~×Ïn”Ùl5²SíÝе¨¯æ‘΋Ñ«àJYµÇ)³â—;–E_`]Am–µ´Œ©—tDk¥r*1:î«ñlg@Ôñt ,GQø½¹äö»~]Ã^?e²ÔUGÂácKé`UôälMj+Õ}šäÛ|šïKd¸TØh"®¹ÃK,”T²ËÙ2yÑŠ±Æçýª9Û"»Ã}Ì€“n•u¶jwuW*Jk ˜Õ $ÓÇõ_FÐKØF®DtœˆÍÝÊ›¯*u]¶,FÊzRmÒ­ŸM^7ÿÉ7üû§ù…Œ¦tòÓE-M?a3Ø×I:;‘Ê[ºt]—¦çî¤Û¥^ošÆU-îáMaás®¶CU,tURæÔñ>xê‘Èærz*æìªß ö',fªû_Ú«²{DV»ÅM Ü(b¨IÙKRèÚ²Â٣ѯW5müL “n”›j?–Ì®çoÁøk±Þ¬4ó¬t7 œÆžšJ¨Ñ답U›®þŠõDÛrVÀn9•ã¶Üµ¦Çò ØçVÛi«R®:gs¹Ô•þŠ5wOT6 5<](WRóÎ(¬}U·LôÇ•cìdN§¹TåPÐÉ#•ˆ¯jÄöª§+¹“DS{ÒëÆ¤_ñHîZ§…Ðâ·×Ï#]m£¸¶¹‘Ä‹³²µ]ÕvNíÑ ¼ OJ Õì·‰[.MGkÑ!Çr;D´lš¦ëv¿6‘!¨ç‘b‰Î¨lNG¦é»Õ6é¹°hÅvµÜ±zª­w±c‹ê×½)ilK,-¢HãåY#¼‹'mê®Ü¼ž;›ø›”µM$ÓZD­Õª\2ÚÌÂáSTÞ{-ê1‘£y—»Ð‰ÝdÛÅwÛ€(öUÛ†Op52Sô7-“ª«¬Ù-ª{[mÚ\«¼ÝW’9ùwÙÍM·ë²9\å@|wš:»žºßo¹Inªª¦–+#b=ôÒ9ª•­^Š­UG"/EØ‚´ËR5Ííš%¯ /¯c¡ÇókM<’ÓÝ;6«¹*؈«ý›U\«³}/VýqBÀ€Ä嘞;œãµØ–[i†çh¹ÅØÕRÍ¿,Ý:¢¢¢¢¢*****"¡iÆåº9—RG§Ú­r›OÙSŠßXµÞfœ«ÙùB¹QÛ'"îݕʼÎÙRkÉqën[\±{ËfuÚ’Z*¦Ã;á{¢‘ª×"=ŠŽjª*õE+CyÕή¶ŠgÔ¹þ_3 §µßÙÞíµ:$U ß·©²+ž7kQ¼µzõ¼=¹»vt¦9̲pxdEÙÈŽEårn»96r/TTR”jï’ƒN¯•3^´S1®ÃªÛ<ÚÕ}eLŠŠÞY•ݼiÑwUYuENí–ù9tìÊyÓËMEnsf£{¤ÚšVÞÙ2+˜®åŽDJÍ•WmšÔTôÕ=cèÇ<§ù®)V– lÑ7Ã_±&’ŠY(fcz#•ÔÕ vî]œ©éµ;“ã:zbòSËiA•ãv«Õ3ÌØnqÔÆ‹íFÈŠ›ôB-™lVAšë8Œ-:ÏM>LúiÓ_;&Þ.ý¯“WÚ§˜”›†l—³Žñs¾ã¿•.vÇ=œË¾þ•2Ê›"¢u]½døö—1Þ&8|ÊáI¬šËˆÉè$œ÷H©åFªíºÇ*µéñî7MûÐó–ðÂne$µú9j šW#¹íMoFª&8ØÑ:ªmË·ô&жGäкèäv1Ÿæ–™ÜÕäó™iªácºl¼©©ÑwNôÛbŒð;“Þp×nQÙ¬U¸‰õ²èÍnÇʈ•® ¹[®´éWk¯§¬ÝÒÁ+dbôEïjªw*/ã>‚€Üü‘e­ÓÔáZýJéUŠ‘6ªÍ-"®îõ$s=vÙª7ªýªƒ8ò€bu úâ& `åF¢C–ÜâDDnÈŽñr웪'~ÛoÐb< ^Éñ‘=ôL{*Ÿbý9´|ê=n‚ƒžh•[|žçfU÷Ëwµ]‘ÑN’*·¹¡ß‹gl›õøÏãé|®ö„e©."7™±cõ=W½èŽëñ*†Æ²ç¬æ'ðwíO|×ô•ÈÍmtÄú½îˆž9¯•r–gA. ^ç7mÖ;%¾FõMú9»¢þ%??£ß*Ïø‰süß¡ýÆ?Þ?ý%¯­Wò=}Õ±Õ?ßÑ0s³è÷ʳþ"\ÿ7èqî6y]îó6Ñ\²µÍÝÔØü(‰²ïé«S•}‹º.ýÝOTøϧÛQþªÿ‘Oº¶z§Õït@ò‹Fü«—Çs\2ºÛbÔ5Í>Ao#DEOþ·r쫲l­ëºïÑw=³‚(fa“*â”pHäí)ë3Œ‰·Vª¤pÆè÷åðÝ7æïê»fÚð1™LþDwESíˆxœÚßE2è%emº–Jë…\4´Ð·šI¦‘Æ'µ\½>SBÉxˆÐŒ?™¹¯â4’·—x=Ö†IöwröLr¿omЉMä–Ô\Žo8Ïø‡¥íZÄV¾;d÷sª"97–h•dN¾;'D7ü{É£tr¤™F¥æ6µ­ô(ÛMF×9=mù£•yWØŠŠŸÊ78oÖ)ã‰ÅÌý"=sU^Ū³iù´úÛ&Wåáw|ÑPå\†Xy‘̵Z¥TW5våkçìØíûÑÈåj§‰ ä¾T˵ê¥,ºA¢“ÖWÌ×v\ê3ܨ׮ÞkNÞg""5Ê©/r9:tqj°ï'Ï ¸kUÑil‰Õ۬׊ɪÕQtNG;³Dùº§EÜœ1¬ ÂáJl;²X¡F$I²ß +Qˆ»£v¨›oàJ0> ¶w17(ªìþÕSì§v=,jó+õò;œÐއÊwÄ+beË ±Ô1Ïr2ÂÅj½Û.ëýÖäTM¶MÑZ‰ºlýÝ$ig’g‚Fßu×QîÊ¡¯–ª†Ï¼vîßuuL›Ë2nªíù"UvÛôEGt¬Y‚Ë(ñx+TÛÙˆNœØuÜ®äë\êÕ4çJ4ßHì«i®jǨ^ä|¬¢ùÜ›ìéd]ß+‘dsÕU¦ûXsÀU¾'>ÌxgÜi¿Zqi ·ÄçÙ û7ëN߀_ê;äSÑåþ£¾EÐÌß*¾[Cÿšý¡Ó#™¾T|¶‡ÿ5ûB0:drÇ„_ã4ÖOÂgíVN9cÂ/ñšk'á ³ö«@é˜ùÏ<°IUU4pà I$‘ÈÖ±¨›«•W¢"']ÏЬ\}jNK„iU=ޤ°3,©–ß_XÖîÖÒ¤KÏûtY9¶ßù,‘ºWYlwÚuó¼V›•-‰Z®Eó¨ã_àÊÔo+6nß#P%0÷Y5’äv;«VU]êš©A@ŽÙÒ»ùoþLh½ëãÜK8ŒE¼-¹½zt¦9Ë/€Äæxš0˜J&ªê"#ûáÓ<¢8ɬšÉaÒ;Õ«*®õMT  Glé]ü·ÿ&4^õñîN¤¥:E“ë¾@íVÕꚉ-’¹«MN¿[Z¶µz1¨ž¤ Õ:l®Ýv^ªåidzÛ‘¿VµjIf¶Í'iOO"+|÷eôZûX܈ž·wvê¶Ú(¢§‰A#Ž6£Æ5­j&Ȉ‰Üˆ„zÅ‹¹íÈÅb£K1ò(ëýª¾Èû9ôv; °øz²Ì®¨¯Tivì|λv篮~Ý"Ÿ’¶Ý*Øç´Øª›h“ÍMG<01ÉHîEloljœŠŒ]•©·M»ˆ#ÌøÒìÆ×§úÃ}ã÷jÆPÛ³k7g-?2òµn4ÉèÄ‹»wz*5½SyUzXPIâ4ái33:È–ë%Æ]d¶zhj+ÙO#©ašEŽ9&F¯#\äEVµ]²*ì»"÷–—q:Û¦O”kv-6Ÿêܬ‚’«0»'7+_EP¾ŒˆåÝ»ªîŠW*.ŸVøœû1áŸq¦ýiŤ*ߟf<3î4ß­8 ~y¨ï‘OG—úŽù@3|¨ùmþkö„gLŽfùP=òÚü×íÀéËŒÓY?eŸµZu8å¿Æi¬Ÿ„2ÏÚ­¦`‰à‚¦'AS rÆí¹˜ö£š½wêŠ{BÍüe²}÷Uûåï(…›øËdûî«ö3ÉNÌ|œoî.}ŒÜ+ŸFW¼ñSDØ)¡Ž(Û¿+ÔkS®ý`‹0€¶¸Zõ¦¦Én½è~CGOz²Ö%TözøcZ[ÔΧ|®Nh—mÕ®kš›÷ªts~½ÕÚ-cÅg¾Çݱû…¶º[]ÖÕrÌ–Š²-¹âæTFȈŠÕݾÔEF®è›ð ~Û¨]ß1»éõ·#£Ÿ#°Ã EÆÚ×í4ÊÔtnT^ôTsUvßnvo·3w×u“Y,:GaóºµeUÞ©ª”í+¿–ÿäÆ‹Þ¾=ÉÔ³ˆÄ[ÂÛ›×§Jcœ²ð Ng‰£ „¢j®©Ò"?¾3Ê#ŒšÉ¬–#°ùÝZ²ªïTÕJ vΕßËòcEï_äêAA¤¶äoÕ­Z’Y­³IÚSÓÈŠß=Ù}£~Ö÷"'­Ýݺ«H4ƒ#ÖÜúµ«RK5¶i;Jzy[ç»/¢ÔoÚÀÞäDõ»»·U¶ÑE;ÍÖ’Ãg®¾\O5·SKW?g½ýœmW;•©Õ˲.ÈTÖô»W4ûY1Æey‘ÓÝ)=ÎÆ¯,Ô²*oÙÍúLwËÑvÝS©¸φl Ú©kÖFªá‰_©ª[-Ͷy{kÄ(‹¼U0§¢¼Ê©»‘7]—}×e@—@ ·ÄçÙ û7ëN-!Vøœû1áŸq¦ýiÀ[ðËýG|Šz<¿ÔwÈ zy©ÜBè–Dé53S,V9S›û–ZŽÒ­Û3yiãæ•ÞŠµz5}f'{š‹_n>Qɹ¡ÐŽsÜÓ´žor¯‰¶›lw"¦Ó¿Ÿ¢6DUݾßÉ^tÇÅc0ø*/Hí˜ëê_ÛÒÙg¦umÚãKENÝù¦¨™±±6E^®r¢w"¯âSRºë–‰Øš¯¾knj5«WRBˆÕ]‘})¢¯O”£Ñða “V­Æýa»_ªUy»[êªWwïÕZöï×uÙwß™wÜÙ(¸dÐ {;84›rlúý/l½;º½U~Uññ#8 ù¥›jóSö™õ3èÙ,\üªéO¹h+8«á’†$šn!4éÍWríMG3·ù"®Ý;ûtÜSðÍWj"âMÚ×ï²K”QFî‹·VºDTühVø4Céâl1èö­nû+ìT¯wйЫý'ò§@´:©‰º?†5y¾·d¦¥¬EüFßÓ-×òJôï¥wâÿÒG¢VÂÓ­;~–8,Z³†Üd™­tl¤¿RÌçµU¯]ÑwM¶ö¡¶ÓUSVÀÚš:ˆ§…ûòÉÑÍv˲ì©Ñz¢”6åÂï·f2:­(°±#^dóhVWåX•ª¿"šü\è­®£ÏqrLV­ÉSf¿ÕE+¨»lç½ÞÕëßÕvØÍÃøoÈnp½fí>jf?‹_RÕ{'Œ§äÕLú}΋‚€E¦z÷йWLøºÏè#ˆØiòÅ|›;tjvè›7ùWm“ª&Ëž·ko;˜û½Mu*‰‘¹®Š–Im7 ›ò»Û@Ý÷MÓ•{¶N^õ”åþv_0Ò)ÅEÕ\M>¹ß[]{ Ì,s·¬vi>Î>¥áF¶yF°[$ì¤× 'Ï4ÙË'dúê»r×[˜ªé·9œ‹È›rÆ»«ºn‰ÌX:Ö ,ÕËzÜôÏ?±d²6É+h+Y$°#½T–-ùâUþKÚÕø‰¾gD]±\ULôÄÄǦªèªÜî×Okpž™¾T|¶‡ÿ5ûB3¦G3|¨ùmþkö„`tÈå¿Æi¬Ÿ„2ÏÚ­:œrÇ„_ã4ÖOÂgíVÓ0ˆY¿Œ¶O¾ê¿c<½å³lŸ}Õ~Æy)Ù“ýÅϱ›ƒåsèÊ÷€³u“Y,:GaóºµeUÞ©ª”í+¿–ÿäÆ‹Þ¾=ÉÔ³ˆÄ[ÂÛ›×§Jcœ²ð Ng‰£ „¢j®©Ò"?¾3Ê#Œ¢~2¬-%²‡;¶Ý¦ÇµJcv;u¶ª6¥É•V:„î}7UÝ‹Õz"¢¹®Öô[GòÍk½3VušwTÒËÊöCʬmsÛàÆ¯©N‹¾ÉãÝíUýtƒH2=mÈß«Zµ$³[f“´§§‘¾{²ú-Fý¬ îDO[»»u[h‘%52CEMH™ËIè16MšÞˆ¼©Ü§°Ø³w=®18ªt³­Ï9ýª»:£ìç>ÇbðÛf¬»+¯TnÝ»¨ë¢ŽÞº¹Ç }ETñ2"dqÆÔcÆ¢5­DÙ;‘öCZ/¯õ¶GvÒÍLÇãĵÆ÷¾{Oj¯†¶—u䩤‘ß³—müS¿»ºe$Îm3¯cr\zÛ–ã×,^òÙAv¤–Š©°Îø^è¤jµÈb£šªŠ½QHsM0]uÑìÖ‡¤¼ÓæºWPǶ–²ëT‘ݱöGò@ª‰µLj¨Æ·dÝ:ïÈNiÔ¿¨Î#Âîòi¬¹²vÓ9mŒ¹¹Í¦tÝ=uo^íöîE]·TMÕ#íâGÔ{ÌÚ{•Y«0½D·1V¿º',ŽTEU’šEÙ*#V§29½y}-¹vr„ÂU¾'>ÌxgÜi¿Zqi ·ÄçÙ û7ëN߀_ê;äSÑåþ£¾EÐùUUSPÓM[[Q==nˆí#µ°ÀåxœÆt³O¹åé÷&œßʧd²`ºŠÝõ{!‡™'[ Û®™v^^ֽ豣\îTíe_K™9V&¿Òqe®N®MXÖÀ1êµì™`ȑȰsz]­sÑdW9©²µÌ^mùZœÌYÅq¬2Ñ ƒ±PÚ-Ðue5 ‰›ø¹Q«—n®]ÕWªª™C€í†lÛ0ªmeTÅ‹}|*®|óäÇtF±ùÉ– e°Öb*ÄNüú#ßëó#Œ‡"ÓÙf®³bÕ—:™Q=ÒéýÛY$ŽUUwk.êÞþ¼»o¶ëºõ$pMÌ1y•Ù¿Œ»UÊ禩™ŸZIjÍ»îZ¦";#@a®€?’FÉXè¥c^Ç¢µÍrnŠ‹ÞŠ„G™ð±£Ùeko¶ë ˜­þWR]ñÙÝA=3Ûê½­hÕÉÓÒVómܨK ØeÙ®;)»ã°ª·W]31éÓœvO‹ø{8šw/SGl#+NiÆ–ŠË;ì]ŸX±¦/;mÙ"­-éÛÔŠ©ˆŒz÷*ºU]ú¢5I«F¸åÑÍRº3 ÉY§¹»U#—É›æ²:Eð‚WlÉw_U=»¿ÁÞq¦Ø¥ZÝgα[}â™É³|â/®EñÇ#v|kÕz±È½W¯S¯lÃ1k9·¨üêt¦¸ó|š¿ãÞcvVÅß+ VìõO÷Ç­rÏë ¾ðÊÆÍ Wés\F5N×É«\ÿ5‰<-ÕN]áñúÛ·oŠ£Ô±Z Æ6•k•L˜«æ›ÎèÙWâwÅì+c‘7Ý!W"6¡½}Ies[ºoß6{jr­§±ã²ë±TÇ:g…T÷ÓÏÏÆ'¢e ÆåØŒ¾½ÛôéÛÑ=ÒÀ…„Íò {å´?ù¯Ú29›å@÷Ëhó_´#¦@,xEþ3Mdü!–~ÕiÔã–<"ÿ¦²~Ë?j´™€BÍüe²}÷Uûåï(…›øËdûî«ö3ÉNÌ|œoî.}ŒÜ+ŸFW¼E˜@…¬š³kÒ<[ÝšºgÕWU9` ¦DTl²í¾ïwÚµªø¯r¯ß·†·7®Î”Ç9eàp8ŒËF NõuΑýúg¢8¿-dÖK‘Ø|î­YUwªj¥;gJïå¿ù1¢÷¯ru Ò [r7êÖ­I,ÖÙ¤í)éäEožì¾‹Q¿k{‘ÖîîÝU¤A‘ënFýZÕ©%šÛ4¥=<ˆ­óÝ—Ñj7í`or"zÝÝÛªÛh¢Šž&ALŽ8ÚŒcÔFµ¨›""'r"Û.ç·cŠ,Ç(ëýª¾Èû9ôv; °øj²¼®¨¯\ivì|λv篮yëÛ¤RŠ(©âdDÈã¨Æ1DkZ‰²""w"!ìNæs:ñ–³é¦ •å× Æ©k/˜Ä¯–Õ\îfËNç5Z©»U9ÛÕUíÑÒDEDSf®>[žàSÛp<»Èíõ]-uó¬qOU«£‚§n®îÙŸè»grò¨oà´#U¯©ŠTϕᗠ_'°Ö:Ó}·TÀæÄÊÆ5®s ‘wI#s\×&ʪˆäꨭ{¤>\zÅ=öŸ(šÏFûÅ-4”p×:¬ñÀ÷5϶èÕsª›íº¿œçøvšØÓ%ίôö{ZÔÃHµUîFË+ÑŒEV¢ò¦ëÕËèµUÊˆŠ©œ§¨§¬§Š®’xç‚v6H¥Èæ=Š›£š©ÑQQwECãÈ1û&Wd­ÆòK]=Æ×q…ÔõTµ æŽXÝÞŠŸù÷¢ì©ÔŽ4gC*´Jévµã™íÚ·¨‰Žµc·íýÊ\«/c;—Ÿ²^›GÜŠ®UUUUP•À ·ÄçÙ û7ëN-!Vøœû1áŸq¦ýiÀ[ðËýG|Šz<¿ÔwÈ z…¸—âwáâÃI -sd¹¥ùË=ŒQ9V¦ºNå{¶EVDßì¾ÄE^ï5×MºfºçHŽr¬DÌé ûTuGѼ"å¨:ƒzŠÙg¶GÍ$Žêù^¾¬Q7½ò9z5©ßò"ªR̯Tµ÷‹j¥¥µ²ï¤ÚFµ»sIG“^áìúµîk•‘@õwsWªxʋӎéfgª™su«Šos¯9ZµµXi÷u¯…6rGjç5òsuW+ž›¦üÎ]œMÏûqá{ÅÕ^_³ó¬ò›¼ãýJ|ÑÊS<§fw¢/c|ÔûýÞž¦·iƦVFcø69Gj¤j7´XcNÒw"l–Eô¤wùÎU_Äl€>_Ä]Å\ªõú¦ªêã33¬Ìö̦”QMºbš#H€Y{ S´gÕªHY•ÚÞÚú.¶ûµ‹u ÷ݯ†dꊎÙÈŠŠÝÑQMà8ûªýŒò÷”BÍüe²}÷Uûä§f>N7÷>Æn•Ï£+Þ"Ì ×Í~Ì,•¯Bô7‚ù¨×Êu«|•[¥žªyÄëÜ«ÑU¿NЍªæ1á-]5²æV=ºeùö9%·Û]'צdmW9Û'ª›5ÛsmÍÊí·ÙO³*ÄqÜÚÒ¶<ž×}Íý”‰öñ¹ÕEN©Ý²íÞÕr/ESŸ•Xî¾ðS©M×ÝN£³j5¿#•´wËÌ/’Zº.~öÆéÅ…W¹»5cTbGènÔ:#jºPÞítw›\é=}ãMúÓ€·à—úŽùôy¨ï‘@ôñaÄ£´/·ã¸]¾ î¤åò­5er9É¿sêæF¦é [y¶ÛtDs›âåÊ-Q7.N”Äk3<¢#œÊ´Ó5LSO9|üNñBºJú}3Ó;CrVÈiûKM{(W™<ö­ýÈZ­]š®Ez¢'DÝÉifŠ} ]êµP2JÜËQïLÞé¸H²+7DÞ fª"E Q¨ˆ‰Ñ6Dkvc~Ý"Ò™ð8®Y6]}“&Ï2y¼ó!¿Ô&òTJ¨›EDV@Í‘ÔDNÍNV¶D>Tð‰á&öÐÜ«.Ëjšp±Âf8MÎÙꧪžžutDt\“"£L_¿ÜþëÛè"I@.a§¾³]¸x¸ÅjÍ#síišNKnIL‹éERÄÙM—Ñ“tÙQv»g¥¨áûˆüˆ;dö(êmí¦È1Û‚rVÚêvê×5v癑ܫѩ‘f¥b9ž)”Rëþ…¶ž—Plp¬U”¯jö³¢ÉCPÔõœ¼ŒV;¢¢±©º*1Ìî ¼&\Ëk£'Î*ÖÌð¢¹çGTLþgTüߣÊ%žä4߉Äá£Ëç1×ÝÛíï_F|?ëæÄ>Ošbr­=TJ”׋DîþêµV¢}ržTTEè»ò»dG"n›uD“¦¢bcX@@P9›å@÷Ëhó_´#:ds7Êï–Ðÿæ¿hFL€Xð‹üfšÉøC,ýªÓ©Ç,xEþ3Mdü!–~Õh3(…›øËdûî«ö3ËÞQ 7ñ–É÷ÝWìg’˜ù8ßÜ\û¸>W>Œ¯x‹0€ nó©8;•Úp[æ[m¡¿ß¯·[ç5J"ªz(¾ÕEDöª*&ê€l‡‰eŠŸ<ò²8ãj½ï{‘Ö¢nªª½Èˆ|wûõŸ²Wdy Æ e¶õUu3.ÌŠ&&îrüˆ…8ÔÌżjê–7¢šažÉO§-²}dÕÔ*±ÏRÞÛ²JW5É»^ÕäÙDMäW«]ÈÔPµXέéfiušÅˆj>5z¸ÁºÉKAt‚yQ½Q¬rª¢xªtB¥ëmòûÂÏ ÄMÚÁWuÂ3{TV{•E4\Ï¢sY ˆª»#÷¦ŠDETGµ^‰ÕS'¬œâ¶ÙÄFU‹æ´PSæ¶yµú×S 5*ZÕåó†ÄäõUɳٷ þŠˆŠÕP‹us[éxϵ}O\>Z«ëénóRÔdYuᤵÒG3eNŽÙË"¾$éÓ~Uky·Ulߟñ ü3Z-6Q•¹µ6ê))m”±ºª±°GXÇHèÍÚ‰²½[Í×mú•×_mZñÃV«äfˆýEiÖ «]Š‚D•4•싲…¼¬EÝdT+™´‰Ì›ì«2èV™SM˜ê›fùåÏš¦çvº³ÎbïMÞØR]ýª‹+½7uõQy@—t³WtÿZ1†åºwŽç@’,§#£–žTïd‘¹ÌvÊŠ›¦ÊŠŠ›¢¢›‰M8#µYÝ­ºÛ‘é” œËrŠŠÚª%,µ,sÜîŧ#QÎVíÑ+»b倯êZü ½fQØ.µ³QÉYæöµg›ª5¨u^õÙdrì‹øé¾£âZ±†Û³¬*äÚËeÊ${z¢I öô¢•¨«É#W£›¿vé²®ÌFØ6„bšo¨Ù{…×\-”¹<)î…‚'µ-«W΋çlmÙ"¢+WeåôÓ»`’@ ¥‹Qjg yÆ­zqwÍtÏ9Èt «²F’UÙ*êU­’)¢UDìQQˆŽUkQ~neV–´ê§=?ÔJ}'Åð<“;ÊÖ+kmö([#¨`TEGHª½­r;níœÝÕ9›¼{–Òè/´7­C±ß.úyªXeçš®©ò[nö^ÅŠäó¨ܯ…7ôœ›ú.TGµUPØs->Õ &׫οé~'kkË詨r;jYO_ákÉé_'¢ôåcwUWj+!L²–åÇvµÓc4s.aÁ¥’—)¾ÎøÝr‘7Vº$‰U›ª£‘Ìôo¦åîäpZõC"Ö-Ƴ¼®±Ýj™==LŒb5•†gÅÛ"'DæäÝQ6Dw6ɶÇ͈qE¨ZéxÒ|žïdÆèÜ·œ–)Ñ)©«¹¶m;SoO}œÝÑwæk¶EkUÄm®Z‡r‚²ÑÁ¿ pCI‘UQ²–ãWJª‘cv¤j#œç§VȬT]ýdG&Û¾F)÷e—ìÝ´i¶šZ}ÙÌï¯ók5GÏSu¸¿fº®v·ª±­NTÿ26ª'T >Ÿ†½4ÎtÛ{533¸ä9Mú²K½ÕÕ ,4“˲º¹­o.ÍW+•d%€[âsìdž}Æ›õ§«|N}˜ðϸÓ~´à-øåþ£¾E=_ê;äP=|·K¾Él«¼Ý«"¤¡ ‚Jªš‰]ÊÈ¢cUÏ{—Á¨ª«ññ ®Ø§ZqYœäYêž¾gf¶ÄŠé®wµ{xÚWuN«àÔUö"ÔÓܦªç]®zÕ"\5/,Þj…z*²ÍHåúÝ ;\«Ùµ­Ù‰Ýêîí•Îø±ûõÛŠÍ_¨â'e[p|ryhtîÑRÅdjÔUl—7Æ«²ÊõEåUMÓdñªMGÍÞöî¬Eʶ/«È§ñµGLþgt|î¹áÑ:ζk(Š)Œmøã?&:£¯ÝÙÄ1C9µW ú¡GÄæ‘Yå®äbÒç8í2"%êÚ½Vv5?úâ/Y½U­^ä{_z4ãP±MWÁìÚ‰ƒÜÛ_d¾Ó%M,ÉÑvÝZæ=>Õì{\Ç7½®k‘z¡_H›Ks*¾uÒ“­«­úNêuciic{Øè,òîÞ^eEŽžF£·ðM÷îwú7ÁÝÕˆŠv0«ÊˆüSÓó'¶#äöpè„irˆ£\mˆá?*>ߥÀ~C@™¾T|¶‡ÿ5ûB3¦G3|¨ùmþkö„`tÈå¿Æi¬Ÿ„2ÏÚ­:œrÇ„_ã4ÖOÂgíVÓ0ˆY¿Œ¶O¾ê¿c<½å³lŸ}Õ~Æy)Ù“ýÅϱ›ƒåsèÊ÷€³#ÌûD´Ó7Ì,:£“br]2:u7)М¿MusÊÚ¨e¬¶ÕãÓNÿ7¸Òª1ïrƋʛ.ÍWíÌŠè•=S-Áõ6w«Uõøƒ·ë6#lž·L²7¾Ý]iÌú¦r>Jm×ù*ÆÉª§7gÈ«Ñ\²‡ú”Xò n)ô¯£Ì±Ç%MÞ–™›ùü nΙž»‘›¶FÎG¿‹vt§¤ú—¦œdh¥T7[dG[˜d6Y»èê7Ý«ßʪœñH›/D^Žj¢¹äv<¾ÃA”cW(n»œ ©¤©…Û²XÜ›¢§³ãEꋺ.Ê…c×î3·jí‡_øn¬¡´eÉ[wªz‰;*Z˜Ý躡螲+wl¬MÕíTs}4^oË…m/×NµK$Ò ÚY/ZV±ºåj¼Ï27ÍÞõ^VFÞõ{¶T’4Dj9©"*súvÌ ûÅÞˆçú·ˆcWÍ6¸ÓÓf˜EÒ;Õº7HŒŽyZˆªÖ9þ‹^cÕ£èª.Ûî‘ÝV'ÆßÖè°S§²in##+Ô¶É5uщÑñ±,ˆÆ?»eV¦Ê»öôVã5Í=ÓÜKKq # ´Çoµ[£äŽ6õsܾ´w{Þåê®^ª¦ÆƯëFI¢š…ÜòêÒ»ÜN¶ÖÝa†O9´\ÜäX¤¨^ejÓ½¨­NV¢¢«•ËѨ鎞¢ž²ž*ºIãž ØÙ"–7#˜ö*nŽj§EEEÝ Çì™]’·É-t÷]ÆSÕRÔ3š9cwz*çÞ‹²§SÕŠÇhÆlÔ8í‚ß ¶ÛNÊZJh[³!‰ˆkQ=ˆˆÜGÙí‡%ÃtÏ&f€bV8rŠÅš¶–™[4SVJäí'wNWK¶îNuDs‘¨åD$`Æ,˜1uÔ-Dº¥ç2¾Éç7zçIÍSw¹?™Í¥…Îô•ˆåró/ùò9¹?^´g,¿dõ4·—!ºG¾S|Uc±Û×nѼÉÝ#šäEëº#šÔôÞŠÍ¢—7ᣂÜ2Õ¦W<ÂŽÒè#l¯#}M}\õª¦Ž¹È¯V¯¤¨Ù¨Öôj"ø WNuOOµnÅôI§9UòÙÈøÍ|/Û~Y#z#ãvÝv{Qvêm@ ·ÄçÙ û7ëN-!Vøœû1áŸq¦ýiÀ[ðËýG|Šz<¿ÔwÈ z)wZ‡S«‰làï¸Ë E;/YýuÛMK@Ý éº5ó*Æç"õä|k²µÎ,®ºjÕ“C4Ÿ$Õ+òµÐØè,0+¶Zš—lÈ!Oò9ßÁWÀ§Ü;à/Œ×æz‚ùgÏ3ª·^²:‰œ«"HårÅõ葵ꜩѪç"tØ€øFÚ¸Ù\žªíOáîëM¾¸žš¿Ó{昞mÎG—}ÑÅDUE‰9i¾¾è¶¯ìÍ5ÔìzÿQÙ¬®£¥­g±‰öΧvÒµ:÷«P…¤’±ÑJƽEkšäݽ¿6á—Ds¾yîXz¢«.¦y•LoÝ$æ‹dsÑQ6W£¿ –e~ì×1Ng…šj‰×þ5iüRÖâ6F¸p÷5ì˜Ó×å÷Æßņˆ\’£NõIº—Œ5í1ìâ¥ËXÖµ¨Ôm=sº9Q6N~V'zµËÔ›t‹ý.Ô,™ÚqœP×é¶wßú#s#eNë²--R/e2.é²z.w^V¹\uÌ‹jò}¤§\¶üU:k4òª;é'Ï˵ÆeØœ é~‰ˆëèô¬P‘0@™¾T|¶‡ÿ5ûB3¦G3|¨ùmþkö„`tÈå¿Æi¬Ÿ„2ÏÚ­:œrÇ„_ã4ÖOÂgíVÓ0B<@q¢ü:Å5a~óÌ… I¡±P§iTþfHèÕþµË/3»¹š»l»”“)òªë¦W\¬Òm$³[h™"ïçqÔ\çsvj'3˜±1½UU}õš›ôUwšë¦ÜoW:Gjí›7qÅ»4ÍUODF³è‡RAÉ&q÷ÇDG¶ÝiD_åX˜‹ý ãûõ|qÓþ³ÿRGóŒOºX(ÿÝOÖ{i9œÌkK¿í×îu°“ú¾8éÿÙÿ©#ùÃêøã§ügþ¤çû§‚ý5Z=êü[ÎT»þÝ~ç[É?«ãŽŸð}Ÿú’?œ>¯Ž:ÁöêHþpû§‚ý5Z=çżçõK¿í×îu°“ú¾8éÿÙÿ©#ùÃêøã§ügþ¤çºx/ÓQõ£Þ|[ÎT»þÝ~ç[É?«ãŽŸð}Ÿú’?œ>¯Ž:ÁöêHþpû§‚ý5Z=çżçõK¿í×îu°“ú¾8éÿÙÿ©#ùÃêøã§ügþ¤çºx/ÓQõ£Þ|[ÎT»þÝ~ç[É?«ãŽŸð}Ÿú’?œ>¯Ž:ÁöêHþpû§‚ý5Z=çżçõK¿í×îu°“ú¾8éÿÙÿ©#ùÃêøã§ügþ¤çºx/ÓQõ£Þ|[ÎT»þÝ~ç[É?«ãŽŸð}Ÿú’?œ>¯Ž:ÁöêHþpû§‚ý5Z=çżçõK¿í×îu°“ú¾8éÿÙÿ©#ùÃêøã§ügþ¤çºx/ÓQõ£Þ|[ÎT»þÝ~ç[É?«ãŽŸð}Ÿú’?œ>¯Ž:ÁöêHþpû§‚ý5Z=çżçõK¿í×îu°“ú¾8éÿÙÿ©#ùÃêøã§ügþ¤çºx/ÓQõ£Þ|[ÎT»þÝ~ç[É?«ãŽŸð}Ÿú’?œ>¯Ž:ÁöêHþpû§‚ý5Z=çżçõK¿í×îu°“ú¾8éÿÙÿ©#ùÃêøã§ügþ¤çºx/ÓQõ£Þ|[ÎT»þÝ~ç[ !fþ2Ù>ûªýŒòú¾8éÿÙÿ©#ùÆ!œdñyñrxðlA·…Uwº Å©’§uo*¯k¿?Vª·¿»¡·Ê¶——Eøªå3ã-ÕGʧ†÷O5ûsk{\Þ11øºýÎÁƒ’WÇ?àû?õ$8}_tÿƒìÿÔ‘üãQ÷Oúj>´{Ö>-ç?ª]ÿn¿s­€äŸÕñÇOø>ÏýIÎWÇ?àû?õ$8}ÓÁ~š­óâÞsú¥ßöë÷:ØIý_tÿƒìÿÔ‘üáõ|qÓþ³ÿRGó‡Ý<é¨úÑï>-ç?ª]ÿn¿s­€äŸÕñÇOø>ÏýIÎWÇ?àû?õ$8}ÓÁ~š­óâÞsú¥ßöë÷:ØIý_tÿƒìÿÔ‘üáõ|qÓþ³ÿRGó‡Ý<é¨úÑï>-ç?ª]ÿn¿s­€äŸÕñÇOø>ÏýIÎWÇ?àû?õ$8}ÓÁ~š­óâÞsú¥ßöë÷:ØIý_tÿƒìÿÔ‘üáõ|qÓþ³ÿRGó‡Ý<é¨úÑï>-ç?ª]ÿn¿s­€äŸÕñÇOø>ÏýIÎWÇ?àû?õ$8}ÓÁ~š­óâÞsú¥ßöë÷:ØIý_tÿƒìÿÔ‘üáõ|qÓþ³ÿRGó‡Ý<é¨úÑï>-ç?ª]ÿn¿s­€äŸÕñÇOø>ÏýIÎWÇ?àû?õ$8}ÓÁ~š­óâÞsú¥ßöë÷:ØIý_tÿƒìÿÔ‘üáõ|qÓþ³ÿRGó‡Ý<é¨úÑï>-ç?ª]ÿn¿s­€äŸÕñÇOø>ÏýIÎWÇ?àû?õ$8}ÓÁ~š­óâÞsú¥ßöë÷:ØIý_tÿƒìÿÔ‘üáõ|qÓþ³ÿRGó‡Ý<é¨úÑï>-ç?ª]ÿn¿s­€äŸÕñÇOø>ÏýIÎWÇ?àû?õ$8}ÓÁ~š­óâÞsú¥ßöë÷:ØI§ürÓ½’Ëi³ÊÖ¹YîUñ/+·Ù~%O”Ú1o*þ²âõIG«:=f¸±ëQ:{dÈÕUëõÎÙ®Û®Û#QQ;üKÖ±˜{ó»jå5OdÄû¸¬§0ÁS¿‰±]×U5DzâD-Ã÷z/Ä„+M‚ße¦¾ÃÔTØî1ö5±ÎDEVHÔW'¤Ç;mÓ}·ØšL†¼5Z®Ô+fœßîUl¢¸eTôn’ÛMXåHä‘;Ñ=gòórµU]ÊŠ¨ŠªEüOq)‘pëvÃî`/ºa÷ZÅ‚õvlН¦M—h£btI6úâ+×g#ÔÙU\Ù·Èl™eŠƒ&ÆîPÜ-w8SIS ·d±¹7EOܽQwEêuá›W4÷Š[D5:‰ˆÚ©8},öÛ•5mD†dHåš&=:2N^W·mØås}W'49|·d¾O}gnQb†²ã£9­JGWHÕW­º^«ÊŠ¿ó‘§2±WøHÑÌUW7™6^1´‡!Ò,®›‹ýrÐ]ís±Ù%lÞ˜Þ¨ÕÌM·k·FJž(䢭s–xÓ¼ëK8ÁÑy%­µÓ×[n‘yêÏ;÷’Š¥Xª›**.ÏŽDÙvårl½7+έéŃN×Uîym1E¥m[.M“ž9XïU‰º½î^ˆÄEr»¦Ûô!<†bÜARëÖ‹çT–Ì&·º²åh§dеeDs¶ca2J‹¾ìr*59_³pX¿“kIly5·œ»%¿ãôuuMa¬•§Y?ö®b':woÊŒUÛeUMÑm¬AKt´°Ç 0±#Ž8Úk‰²5:""tØ`Ëu¡uÒ×YlmuUÕÓÉTÒ=< æ«{Hܨ¨nû¢ª.ʉÑO¨_¸Ô<ÛÈÝÃV³ÇQ6Oc£tÖ+úµVŠ×£[/7]§cU¨ôUW.ʪªíÕl åcdl«Uíjµ®Ûª"íº"ûdþ„<ùÅ?œy§ooÉÚv\ÉÏɾÜÛwí¿MÀý vGAuºc÷+mŽò¶‹U$°Ò\Ì´’¹ªŒ•îåUEÙz.ÆD]±:´poÃöa˜RH—üµ”‹ÅÞ©²\«ù\¬G*ª¹"G»¢o¿¤ç/¤åR ÒÍ=Õ­¶Ùx·¸ZàÕ£+dW\®•ô}Þßÿ]eEŽõ¹bs9ãNTôvõQëÊq«Fe]q‚™j-—ª9¨*âG+UÐÊÅc‘:¢ì«²§T^¥|Ò85ÿ@o–½¿a•ÞÛ¥%‡(·Íjm´ª«ËlOTôcoÛ&ȈˆÖ«ÕQ 7I3m>Í8Ñ÷@ž×c·œ'Îòµ¤…ÐÓ>¯µÞ'>=‘:sFŽ]¾Ùþ<ûÜ„sUÊÔr*·½7ê…nȵ{‡žµ:íˆáÚqz¹fYCãº_hñOM#}ÊÞv£Sg9üŒEõÕêˆ¯ÝØ,ÊѦzÝh¾q¡«rÅóÌz…ÒUÔ²®H’?6Ê”· )·F3f¹=Tj®îôÓ}Âׂ6áÏT«u£E±I¹Û™E[v‚VÕEHûhf|29›ªª5Î\ˆªªˆ¨›®ÛŸ#Ä65žk=ÿH±=uÒ,f$¹ß©Õ®¡§«çV­+—Åݪo»šôÛÐUV*ߟf<3î4ß­8´…[âsìdž}Æ›õ§oÀ/õò)èòÿQß"èYÔÍAÇô§Oïú”ÏÙZñêk§ÙQ'*z1·~÷½ÊÖ5<\ä@*'ÙoÓ»‰ŒgAíßÝ8¶šreY_+¾·5ÉÌ_1¦w‚ò#‘êÕèä{Ñz´ÞÈ…üVånÓçêSP꼫Q*Ÿ“Þª¤bµï’¡Uñ³eêkÝÜŠçmÓb`>7ð›´sëž.gȧÍ>Tùê×ÍêàX:w¾U\gÏÊ<ÑëÔñ»~Ut´õÔ³QUÄÙ`¨ÑK»žÇ&Ê‹ò¢©Šà/6—­ÌøRÈ«&’áU-Ï|êíê¬U*×5Ž{Õ[F*ótI£nÈ­qš!}m¸E£úƒ€qGH³Æ¸}É–œ Eþé²ÕªÄô~ÍvéäækU:¬‹²£‘Šu[G÷;Œ Ùü#J{«‘>~4ÿª:‘Í¥Àü+ ãiùTqótûü·ò¥ª¦®¦†¶Š¢*ŠzˆÛ,3Dô{$c“v¹®NŠŠŠŠŠçê}hæà‰eŠŸ4Ò68ãj¹ïrìÖµ:ªª¯rì©zÍÆ=îïz“K¸M·Ûò¬š ©hï9}4ëc±+wk¦j#f›U¯jmÕÕ¦‘©úýžq]r¸é΄Ýê±}.¦‘Ô—ÌÚ6+koc¶}-»ÒNHœ2¦êнɻ%Ù°LÓl^‹Ãí‘ÐÛhYÊÆ7«¤rúÒ=Ýî{—ª¹NO·¾pÛ3®/Òæ'§óhú]u~ϧN2<Ÿ ¯¥ëÞM¿\÷vvú.Ÿpýl±_¨š‘‘\óí@—³–kíêuiäk\œ”­wðQ';¹[×n›r숒ÈËÙ®oŽÎñ3‹Ì.ÍuÏLôvDrˆìŽƒ‡ÃZÂQìÓ¤Z¾Πi®ª67ãÙÖ;Ku¤]Ö5•»K—oN)gÆî‰Õª›§EÝPÙ{ˆ»…»MëM5ÓÆ&'I‰ë‰Ž0ñ]ܦh®5‰è”E†çšñ ÑRÆë®ªé/r¾…U%¿X`ïU…îTJˆÚˆ»1UnŸ[MÜ·cLuOÖL>“;Ó|Ž–õg¬Ý­šTtR""º)X»:9ºnÇ"*n‹Ü¨«ÆA§¹¶æ•ZïÃC££¾MõÌvþa’BŽærro´SúÊ×5U\ª›+ŸÏô&Âx\›ÕÓ—mƳ›¼¸õWÑþ¨ÿTs© Íökv&þ ;é÷{½N†‚6ÐM{Á¸†Á¢Ì°Ùä†h_æ×[UO£Wk«O^ ™ÞŠ‹¾ÎîruOI$ú&&5„,™¾T|¶‡ÿ5ûB3¦G3|¨ùmþkö„`tÈå¿Æi¬Ÿ„2ÏÚ­:œrÇ„_ã4ÖOÂgíVÓ0¢ñûÆ ºŠÁéÝÂ?¦BÄ|Ok["Ú¨·TZ…k‘Qdz§$mTÛ×rúˆŽµ÷‹­ŠÓ[{¹ÌØhíôÒUTHç#Q‘ÆÕsœªåDDDE]ÕQ!»*¹ñ®yF³åqó2j¾Þš•îæHêÓBžÔŽ6"o⨋â¦cŽ·–ákÅ]åLzg¢<òÜìþIh³;9få\5êˆã3戙~Æ™Üò „¹¾ª]+ow{—×¥m|ïšg¹ÉëÏ#Õ\÷íà«Ónª½É&SRÓQS²–Žž( ‰9YLF±©ìDNˆ~ áÙ–kŠÍnÍÜEZõGDwG÷/¶¶se²Í–ÂÆ/·=5Oªž¹ž~nQÑ jDU%t¥®¥†¢¦ÎŽV#ÚäøÑz)û±3LëÞk¢›”Í5Ʊ=£%À/%Ú›Qô¢áWj¹Ùæmdm¦‘RHÞ½¤NïùX»¢¢ª'OD釜dPq+‹»Ê_6¡Xi{[”QÅÉ}:9¬J¸‘:7«˜oDkÜ›"5ȉIˆòÚÖðÓÄN-«–ìèR®¥blÙ©´uql=(ßÌÕÙy^¨äOE²Ew_À1s­Zy3<çN‰ëáÆ'Òù§Â׃Ü.Wfs쪘¢b.Q"5"ªc¢&t‰ˆá¬ÄÇK¸ü©j©«i¢¬£¨ŠzyØÙb–'£Ù#›µÍrtTTTTTï?S ¸G\xÂÑ}ª÷%»TÝo›nëM¡Œž¢$ۢʮsYû§G9¨»£U—A8ÌÒ-º?±I_e¿µ‹$vÛ«#cêZˆªåÌs›'*&ê¶ë˲* LY^U`øåÃ-Êî°Û­6¸QUS2ìÖ1?Öª«²#SuUTDEUD*ŒÜoêÖa^G¢¼/ä9%E#‘.µ‘Ž«c:?³Ž8Ü›¢ïÑ®‘SÅz'Ÿ)mÒzl´Üdž,fá“ÇîÓ¡EæV25V·§¢²¹ÅX‹à[{ ’Ùb·ÛñªzX-4ô±GC""Bب‘£9zròí¶Þ@Zc¯š1ÆV'}Ó ŠÇ5ºå,†çŽ\܉?"m¼°=6æä~Þ’#^Ç5ZßEVÓ ë%à7Uj4KV+j«4Îý3êì§Fç2—™Ý^ˆÉº¢Mz®ÚDMœªüçz`ºgv°qa¦(ËNGgºÁÕ`o+j¹·Hæz&ÛªªvOO·lˆ‹Ü»Ú{Þ!§Úý§¸óœZ–ïg¼ÑÓÜ⧨Ý É9®dTsˆõNfª.ʩܠAUq?§7­7­Òm)¼Ðgyf{Ù¨¨¬³2­±6tåt’=›µ®DUF³~neETDETßxpáOáùîÈ,õ·5½]¬´7ju¬s¨–¦(ÛÛM~*ù9œŠåw/3‘œ¨åCdÒž´KEk$ºiö MEr•ªÇWÏ4•U(Õïkd•ÎXÑ|Qœ¨»&û’€â7F2ÔzŤuÒ[5?¦w¹’±ß[ºRµ\÷Ûæjú.kùŸË¾ÈŽwUDUTœ@œJñrÈ1‹]òóŽÕXk«©#ž¢ÙU#-$Žj+£s˜ªŠ¨¾=Ú]Ñ2ÇÏq¸RZmõWK„½•-/¨žNUw$lj¹Ë²"ªìˆ½71x>mŒê6'lÍðë¤w=ÞÞ–¡ˆ©Ì›«\ÕEê×5Ís\ÕêŽj¢õ@3€*õïϸâ,Ö»ܳÌO>§¥Žå–&Íw´Ï Q¿[…UhŸ¶êTðßnD熲š^6õåö}6Â/85¢Ç”9æCPÅ£®®‰$DóaÊÇ;x•’s;¦îDHù]Ðb+Î1ëÆé6Fδâ‚|‚ªyk)è"s"kêê$NÖ¡Üêˆõj*¹ªˆ¨Æ±6DD@ŠuÓR+qijpƒÃ=4TÙE] tµ5P9RjÔDtÒI×’Ebï̾’#‘Þ»ãÞFÑË&…pï†ÛtÖÉžcPUI+|æj›¥ãMúÓ€·à—úŽùôy¨ï‘@ôSï(5íÙ>Ã%¾äø$Ô+Ëk/MŽr¥ž‡ëÒnäõÒ¶>U۪ƻª"u¸% ’ÿôÔã7T3hÒÚp* \Ý*óò:¡®Yk‘Ýì®bòí»U«â¤cló™È2,N>‰ÒªiÒŸ¥W“O¢f'ÌÏÊð¿ Æ[³<¦x÷GIÑÆÈ˜Ø¢cXÆ"5­jlˆ‰Üˆ‡ôáÇ\Âg•¿<Ãï8m×¥-æŠZ9¶êÎvª#Ñ7N­]œ{ÐÍ‚å›ÕáîSvÔéU3Õ1Æ%æªbºfš¹K)À¦Ü³Îè±|ž¦äºsY6tŠäzy¦ÌÏcšŽEXyÌ»ó9UTw3[dŠEÕê£NøÒÌðŽt´jn7M’Ólç,QÜ(ܰÈÖ§*#UìW½êŠ«Ò=ûÑwO¼2Òœë+±˜Sÿ²ˆª{&cŒy§Xqüfp˜ŠìÏÍ™€mØÀGøœÕœˆ\ÚíÂæ•V­#h‘°êK¹UîkÑ_h§szs®Ü²®ÿËbì{d•øÌ×,ƒM1 ^œéš¹ú¨óIj°+·˜FE¨¯~Ȫ‰ŽÝeÙW›ª5HÇHôÎϤ˜-¿ ´½Ó:Yëj¤UWÕÕ¿¬³9W®îww±©às/ {oñW|$ÿäÝù?³OMe=s¬ñÒa¿ÈrŸº7wîGàéçÛ=^ÿêØ1ÌrLjØè±¬jÙºÙn‰!¦¦…»26'úÕUwUUÝUUUUUULˆÈ—.Wv¹¹ru™ã3àŒ’5dFúÊ×9±«»Õ²£WtDÛLÉߟy9u6¾éŠ[fÈ´·1IIC=CšÊz´b«#t›;’Vwsl½¤H»îænÌÎ5†°q=CšŸ¬c¹=Þ8kqˆí í¡·Ru|[+$E™¨Çó7usÜç¹È•QnõÓG¬릷M<¿½`J¶¤Ôumg3¨ê™ºÇ2'ŽÊªŠ›¦ís“tßr¡éÚ™ÁÃcÑŽ%p«½n?nw›Ø¯Öö$­ótß•Œs•­š$M•©Ì’FžŠµz5¹¹/>P®?å[e®ctýó@Õ¨«liñ±SÍ·UW2TN½K3¡ú›xÖ| ,¯&Ó ® µV2ŠèæIÛµ;äb*5ü›îˆ¯›÷¢*.àUÌÛ5Í8þºÚtëNqÎ;¥Ôu¬®¾äWHÇÕ+7åŽ$EVîž–ÍG9U\×;‘ÖñÐPQÚè)­–úvAKI ‚&'£lj5­O‰ÙŒdlHãj5­M‘6DOaýBg¢ynŒê­Â<óJšUEQ_Qb¨ßšÑqW7d£Û£b“™Ê­îj1S¿—y¼…—ë.-‚ê&+§™--Â’Lô†Ýt|(” VŠˆÊWJ«Ògî¼­Ûªò§{ß@ŠõûFëuއ††ó ñ\²Ý‘>9£W2¦8©${§V»‘ïV®ÊЍˆ»"ó$¨gÊq¬†®çAa¿Ûî56ZŸ3¸ÅKRÉ_I>Û¬r#UUŽÙ{—¯zw¢™BÔíÉh󨵷@.ô¸þi,°Å{¡©Oý¤çNt¨b&é*7ªHÝ•vÛtUG Nà[âsìdž}Æ›õ§«|N}˜ðϸÓ~´à-øåþ£¾E=_ê;äP=Äå¹&!ŠÞrÛƒú[%¾¢ã;Yë,pÆé‰ñìÕ(W Vë“4r›-¾ò­ã6¹Wd÷5ˆÆ¾j™•QȉÑclk·†ûxÊ—ˇð‘ËIIUy§‚É}_çS²'¢'z¯déWtO•4Ì6ÄÜ_±cLM›i¶ÒТl‰Ò(šÎäéö¾áË0›9fLþ2¹ª{¨}Q>d·d¬ïb.^Ÿ›zgú3æDø5-Zfk&šd‘éË•¹+­ò¥¹Z¨ŽívûEwD~ÛòïÓ›cm#~#î×K†fw{%ʪß]Kl|URÌ襉ÜÍôšöª+WãE6Y5º¯f8{tDLÍtDoF´ñª9ÇLuÇL,bªŠlWTôDòçË¡ðiEÄ}-vFíg“![K£(’û3äŸÎyÝ̱sª¹˾ÿj»·—Ä‘uó‰LG‡ÿqá¿Ú«îu7žÙÑAD¬GG|»½ÜÊ›"«ÑÛ²û€=AÔ Ë+Ëir¼Þý}ŽžÙ ”ñÜîST²7¬Š›µ$ròª÷n…râIºÃ¤Ë¶×²¢þ´±É!•† g9ÊÈãFz-j/7Ný÷UÝUU{ekh6׆Í&Ý4ÑM5Mõ£{Z8nÇ>¤×:óÓ¯„RsZ°YUáâ©™™ˆš¸éǧ¿¢[±]¡¿Y-÷ÊxŸWXªØÇíÌÖÈÄr"í∧ÜR^´—‹^g‡dùFcxŸcc¨–’\šI¢ZW@½›Vz¢¢nÏGn›|GÑÆg9n'”?ItÆæëuE41ºíp¿Ý –DG2öž‚µ\äNmÜˆŠ›.ðIؘÜ)ÄÛ½¬MSU3äÑ3OÖ8wÌÃoÍ6°“‰ÄÑ4ñÒ"yÌéк@çQ¥Üe鮺±tÏïíŠGQ[ YDÕtѪ¦Îž5^W"*§2"¿n»¦Èª–wƒÎ!.ºáˆÜh2ÎÍÙ;$Lªž(Ò6UA";³—•:#÷cÑȈ‰Ñ6æÙ-ç›s,˪Ͱ8«x›4U»\Ñóg„qçÃYˆ×^˜4—¬&qMûñ†»nhªcX×¥`Ë맺׃kVO5›6½ÝÚéAIl®®žª•¼òI|+•»±UªÄDÛv¢m¶èu.ÏÅæ–QÐêy–evö]&HÛQýïtR¹éÛ›Gº5vnܾЧ†Ä†8ˆ¹jÝümª&í14Dë½Té¬Ó𞦳óäÁ¥£vª¨µTîÏ¨Ž½{]@8ñÝjâLjË}¿N°:ùᨳÓ,—+þe5Cwåc矙9WnˆÖl®^eT]ºiÖ-i×Þµ1öŒ§%¾O-¢©‘Ýl× ƒª¡ž%ås‘¼ÎsQ\ÅElëé"ï·EñkÁ>äÜÃü*×Âh‰«ÅDëVîºDÏTUÃMc¦5Ñê­¦³Ní~.¯<7´á¯Û£© ññTÁLGG+ìrxµStSÙÈæ4%$CÚÏP¸.©hεÒS±$Ç2ú{MÂvt•-×X&ñôÑʈޫ»úlŠå:P+qÔÉøzÍè'=ÔÖït[Ê­Eo›=³ªîïŠ5ßnª›¢uRçhæa&¡i&Ï'<Ù?o¹Ì¾Žý¤Ôì{Ñy6j*9ÊŠˆˆˆ¨©²WøÌg³Ó†ªxÚ®¨ŽéÒ¨õÍNsµ6"Þ6.GΈŸšfì´V(%w.Éà²IÌçœTèâh> ~ÅkÅìVünÉJÚ{}²š:Jh›ÜÈØÔkSãèþ'Þ|3µõݥͯfW9U>LuS)4sëg¥×2ü8 56)èçÛ= ³@]Ô\Ñ©x=ë¾·ûŽóJêw=̰¿¾9Z‹Ñ\Ç£^›ôݨl@½býÌ-ÚoÙ*¦bbcœLN±>iy®ŠnS4UÄð}üêåß;ÒIôÛ9—lãJ꾆/Ls¹41;¯W5ñ±Yν^è^þç!eÊU‘3B¸¬Á5]ՆǨ,n l³::h¥{ÑôuUcšŠŽENölŒUæF¬Š_Óî=”ϨÚ\¢ÎeLi5G•UG £Ó;4rLÇ8 Mv'£—w@$Læo•ß-¡ÿÍ~ÐŒé‘Ìß*¾[Cÿšý¡29cÂ/ñšk'á ³ö«N§±áøÍ5“ð†YûU tÌããÞ‰¨ÿxÓ~¹Ì-þðâûêoö¡ÓÞ>=èš÷7ëÂÐÿï/¾¦ÿjí¹ÿ §Éuÿ_æj¿u_¶”€9ë`ŽuãûÈïè¿EäŒG:ñýäG÷ô_¢ós³ßâ–>”"þXÇ~î§Ux&÷©iŸàF~›É¸„x&÷©iŸàF~›É¸îï†@¶ºŠÛK%uƲ Zh“y&šDc›íº¹z!I˜ˆÖU¦™ªbšcY—îk:â¯Kqߢ½ù%{\­ìmÿÁ"§‹¦_AS¿eg?ɲîD©©K룚˜-²[£¬kQEõˆÕÛ*9V¥ë̪zF©¶íÝ7ÙM6'>ÂY¯ÅZÖå}TqõòLrí…Íq–¾ŠˆÃÙüû³¹hž3¯G '­cs­_ÓÝ9kÙ“dTñÕµ­˜Âä’¥Zªˆ‹Ù§TN»õÛtEÛ}”¯®"5wW.NÆôw«¢yy¥…óµ‘Q_*í)ÌצꨊŽÙz›FÁ¥’žX®š‘Ô^jÜå–¢’‘ÎŽ½W¹Ò¯×êªœŠ»§v˽±cöãMúÓ‹HU¾'>ÌxgÜi¿ZpüòÿQß"ž/õò(€T?(…_º45€¶X¿ôî£Ûêg…YÌù)©˜õ•S¢¦ÉÚ7~ž-ðÜËç*û·\>XÖ¥5r;´›ì¼ïm4)Ȩ»r¹7ïûeñD63æXüã‡üÛzýjªú§û%oL-uõÕ§¢#Þ$–YÅ'½ó:üÿÒi)š½â÷Ü×GrÌW¡óË¥ÎÞè)`íYhõT]¹ž¨ÔîïUD6Ù Ê,æ¸[—&"˜¹DÌÏˆŠ£Y™èˆcc)š°÷)¦5™¦}ЇäÜþý³ÁTÿÛ)§qÿö~wàZ?öÈNh>«éQ’Üu÷&žáA ÏóêiùÞÙU6†G*töì{ãG† ãUoöÝBÓšX®5ÐQ6Ý]ntñÂ÷1s™,jõFªýqÈäW"ìÖì‹Ôî–¶*±áæ6¬E&»qLWDÑ®í<ê‰Ò9iÏš#V^GM¨¢w¢­tÒuç=Ö[MÜ×éÞ,ö9×YhUtTìÔæô÷ñ)˜AUZÊZ‡Þš±Ô=êÆÂÇ5‹ÕÉÕ¬V.éìÜ8Òî0¬ùÎ'M”Í’[ðÛSzZ›ëR§jmÙ$M•UíÛdFò«QÀ’ø¯á£Xn-Ïð*ª:L‘$5”µ„w³£Ú'«"7ÑÝSg"5[˺êö_•ì.Ó×N#nå»ôUôNõ4L׬ESé¬GˆÖ5áÅ‘˜QˆÍð4Zªš¨˜á<&xqÑWpÆ=êÝ5¾å­ðWÐÖD±ÍùUÊXfÉÕ®jÄ­sU<¢’‡Ü3ê&ƒä—û¦at±ÔRÝhc§‰–ê™dwhÙ9·r>6&Û*ø¯y Zp_(6-m‡³.C 3{8Ë­‰ÜÖÊéZÔNäæM“dÙ6,× úkªÚ{‹ÞåÕë›êï7ºöU§mqudñµ#FªI"ª¦û§Ú¹Éñ®Í1¸|–þ¬~åºæ"(³½ToGÒ|4×§«S,ÃÚ¯Eqfå3ñªgHáÛÏԣؽ5üaÑÓT5ê ¹ÍTÝ–½]²ü] ™Ç£îkÜæ¢«.tJ߉{M¿ØªA¸¿ Úçnâb›Pk0~ÎÁ^û£«=Ó£]©V©ÏI9^UQvåßâ,¯º}—êvVâ˜=£Ý+¬µ´³2ŸÎ"‡v1û¹y¥s[Ñ>2öÓgY~#ir[Ö±UnÜQ½1]3ùQ®ôÄé9ë£Æ ~Œ*Ѝ˜šµÒ4g‡GZòlÒÂÜg7­F'm-}NvÝU­ŽEDþ—»úHCŽÖ5¼E]ÜÖ¢+è(Ußö-Oö"›‚M ÔM!Ʋj Cǽɨ¸×A53<î ùØØÕw…îDê¾;O|4kf¦k=Ã,Â0¯t­SÑÒÅGºTîæFrrË+]Ñ~#/&Ï2Û~q¸ë˜š"ÍTiÍtÅ3Âß«]'”ôôv-â°—êÈíY¦ÜïDòÒuùÝ×[þõ¬ÿƒéÿ³i”> ~–z ¶Š©œ“SÑÃÝg5ˆŠ›§Eê‡Þ|ýˆ˜ªíSsíLè)ˆ—°Å}´Á~²\,uK´7Yi$^TvÍ‘ŠÕè½¢÷ï'>E.C ʵO:´ùõªvò£U‹ dÈÆªoº*D±ï¾Ë¾ë·S|~NJ™áÓmHŧ¨ŠO¡½N¾Û¡kU9’- z+»·Ýï“eÙ;¶ð>ð‰˜¹ÃOLQTy·¢}°…í}¿&Õ}ñì[ ôRkù†¡`z{KO]žf–=tàqÄV'>e£E²U—Z5¹Û¥cù$Šª™RxÜÇU—›tÛ™zí¹k8~Ô”Ö Âõ)Ísg¾Ú ¨ªk•Š©R‰É:nÄFíÚµûl‰Óí[ê¤4|žN‹“ízmšèôÉ#SN3[®…®EÛÌ&o “uUô$˶ê»**ªî}à/4š­bòʧ”Ó\yüš½”úP}®ÃéU¼Dtëíµl@Ð`s7Êï–Ðÿæ¿hFtÈæo•ß-¡ÿÍ~ÐŒ™±áøÍ5“ð†YûU§SŽXð‹üfšÉøC,ýªÐ:f¿ññïDÔ¼i¿\€æ‡ÿxq}õ7ûPéïôMGûÆ›õÈah÷‡ßSµvÜÿ…ÇÓdºÿ/ó5_º¯ÛJ@õ°jÒ¼2ŸPõÃ…UÖÉG Þ­´òOQÎcvUUD^›ô-çü¸gÂëòhŠÍÃ?Ùç ü&ßÑqy¸¦Çµc$ÀmÔZ=-Ö;Äwˆ¥¨[uÅ(¤ód†dvïW³vó¬~Žýû.Ý ÖÍåØ;ùuìV"Ǫ™á®³Â8FŽ!áh3|Ðá2Ì20ÖîQ¬ÕVîìNõQ¬ÍQÙÍ ßüž5L¦šl_S¢š¡« =}µccìt¬‘ÊÔøÒ5*fQŒß0Ì‚»ÉmòPÜí²¬5?½®ïEENŠÕEEG'EEEMÑNŒð»ëž7ŒÝ)õ®ëSS$• [l5•­¬ª…¨Žíó5ÎÝ®Ug+UÊ©Êîíʯ¯5¦yÅÔVêVC[n©»Z­WC"òÔ9(¦Nf®è¨›ÆªŠŠŠÎžÑŸdØ:0VqxksjºêˆÝªg§^q:Ìi§¢yjl6Øæ÷³œfW™b)ÅZ³D×hŠtá»Â&˜¦'X™Ž:ùQÂtÖUè[Š^´sNt†»(Ã0ÿs®pÕÓDÉýЪ—f¾DG',’9½Sâ"¾4³Õ\ºÿlÏl^êSQ[™<ùÔÐrH²£Uw‰íUè½Ê»;û;б˜Q–ÕU;õF±:Î=šôu&¸/9f;!½´VíÜ‹6§I‰ŠwõÞQ½1ó£QÒ¯ œx½Ól3L5:ߎàv_sh*,U¾¨–~i<íWsJç;ª1©¶ûtîï'½à³OìØ”9±SÉq¹ÔÓ6®¢’Z§ÓSÛ[Ë̬rÆæ«œÔßÎw/M‘:s-pû7Åc.`­é­¿•:Îìyô×r™‡„LŸ,Ê0ùÅýýÛÿ"ˆˆšç¯†öœ:|­8ÇLÄ(™k82Ñ3Õ%®Ï1†]g¡¬‚*w:ªx¹æ9U6íEÝ}¤·|ÒÞ r zïq·³™–jjêc¼ï<1FÅUz29½:s5QWÚk~OUjâÙŠ±î>È«º¢vnñ7™NAÚͼLÑršâ®^TpŽ˜˜ëä…mNÝÕì®3—Q{rÕVâf¯"|ª£äÍ5kËŸ.jÏÄŽ#`ºÕ’b¸¥¹(-T.¥ózt‘ò#9éb{½'ª¹wsœ½WÄ Kª:/’ëge‚ÌÕ§ ¦}·;‹™¼t­÷ží•ÎõTUèÔr¦ï®ºYÂÆ„á‘ÔÖ`~êdQv6ÚYo¨ú™ˆ‹4¨Éšb/Wr¢"ªò·múkq9ìEÜV*™¦Ýª+ª5«XŽO b"yrõBE—mæ…ËrË‘rþ.õ«S4Ñ¥UDÍεÍUS¦¼j™™×Mj#IšF ¿ ÔÚÉ%VY—ÍSO[ja…y__2'3˜ïcŠÞeDÝy¶EEET°é¥œ.Eô«Ke‡ÝÄ““Í=Ñ©óŽ×ÿWÛv›óÿìù÷ø‹X ˜Åc¬Sˆšé¢š¸S½:M]Ü'ߨÊÏ<%åy.:¼¾›Wo\·×â銢ˆéÖfc— z#”ÌO<‰'Jx}Ô}e¡¯¹á´tkKn™K-]Gd×HäæåoEÝQ6Uös7ÚH¼CðÃgÒœ·¸Û.óÁ…ä7(觨©r9ö·¹È®EríÎÞÏÍUë´nG*ìŠë¡¢Ø†ax³K«a¯²K$“%|u-¨óÉ·ä’GHßEÎÞ>UÙ—dDÛc;'ÙZñêðøîG8‰ã:ò˜ìíóshö¿Âœ¿$³˜d±¿Uéòfªgv'ÊŠ¸Æ•p˜ˆ×·–“<¤š)æ’ SgÆåc“}öT]”µÁÆ5ªÚagÏnY•Ά{šÔsSÁnc;:‰"M•z®éÿŒÉq„ð™iÓ<‚é§5¶匒¥m.A5LÊçTÆ’í¦sWëk&þDÝzlN|ûÜñ?–¿õéÌœg¬ÓšU„ÆnÜɪ7ff>TG>yúZíµÛüeÝ™£5Éâæ¿ç~šb©US¤NônÌé¤óÖ%ÿÁë…ü!^¿&ˆªzá§tZQ©÷œ ßqš¾žØ”êʉ˜{ûJxå]Ñ:tWª~#r¾?‹vîjý[ì<ê^ϳ[—'':íË·M¶îØ+&¸Vfñ»U*¯Î—Ï!Šó%Sžëƒajµ¯MæÝ{FÆ›5‹¶È›lj³‹¸ ¶âÞ 6ªÞùS3¦œxqóO™)Ù.{†Ä׈Ìó*qV÷'J)Šu‰Ö™‰áÙuË^@SM¸%Ójzh¯u8äõCÑ÷ £ê敎MÛ"Ä×*"9}ÑOaøjZG™àÕ>“RÇm¹-"×[墫|ÔuÉÊŽkU®s‘ÈŠs»+‘W™bý[ŒñuM»”UU1¬Ók>Æ ¯ ¹Lß·F#zÕªçJnWDE:ýi;µž¸PPHZ£÷MkÎàÅ(ªGGNª¸V¤|éOznˆª›¹ÎVµ~õß¹»2p÷†–ÐÒ3.¡²ÓÉPÎÅ•YÙZú§5™È×½¬æêŠªÆ¢&éÜ`å{;ŠÍmN"™¦‹qÃZ§HópþÞÓøBË6cNåÝ¿Tk¹n"f#£]f9é<#YӌƓç!&b<;êVk§õÚ™g¢£m’…•2¹õœ’²óHæ7oI:9©Õ:µPµ¯Gø`¡É0*+Ú OY4µ—ªMHÚâUWsH絎t‹Zäô}}Ñv-=‡Ó»&–ÅŽYÒ‘˜_¹2"=*W±}¬sä‘fEßg5îz½í•w79^ÈøìEÛX«”ÌQ6®™ˆ˜èå¤ñá܇í7…Ÿ‚`0¸œ²ÅqUê¸øÊ9SMUSTF•i5ÍQÂ5åÆtàä°,ט‡ ˜þ o«Ñz»$·¹.ñGP”7¹k_潌ÊåV>W¢':Eém¿roÔ4ƒ:\F“1ÕújŠÚË2T²Öé¤¦ŠŠ'zMYÇ5î“—eTUj7™Z¨ª›š‹[5‹¿Œœš©ªb"f¨Ÿ&"{tõh–b|#å8,¢œßEËtÕTÓMSr©ŽzS½¦³TGžb&’ƒ£h úŸoª¡ÄhlUO£bFú›ÛžZevè×;‘îjªì»+Úä]—¿b“k®ŽÝ4O:—¬©ZÊ9¢m]º³“—·Ê©ÕWg5ÍsU>-û•9¦Îâ²»Qˆªi®‰á­3¬Dö®lÇ„,³iñU`-Ñ]«ôÆ»—""f;4™ë‰Òt8ÄLk(ðÌx$Ñëõ¦†—µÉŽT¶²jªã¬¨¨|”É¿i[,Žj9Û¦ÎÛ¢¢w¦è¸Í^Ò>4»O'ª“ µHêÛrTÆêÙ]ZúwVBÙÕ’$œÝ’Ƚñ÷v3bšî^®ˆ¦˜×]gIá¯V¼;»µhpÞ²L}Ë60–n×rå[»»´ëÌDLùZq׆“<¸éÃZ Û¯<)i%«H/¹F›b©Eu¶S6å ì¸ÔÌ×Ó±QÒ¦ÒHæªv\îM“}Ñ:g1êîmuveku}†Ë@š$žH¹ê%w,MWFæ»nVÊîŠXž#fñ˜lu¼SU|bc]:uè׆šÏMæ_á'Ìr\F{DWM»¥TÕÅzðÓHЦ<©˜ˆÖcލ'Œ\ ItÆûaÄ´ëm¶¾Ji+î2yåDûÆçrBÄídr"îÉUvMý_+±«Ì0UåØš°×*‰šyéËדd9Í­ ËíæV(ªŠ.DÌEqVšÌk¤LÇ5Ž<´nμyýý輑ˆç^?¼ˆþþ‹ô^nv{üRÇÒ„CoÿËïÝÔê¯Þõ-3üÏÓy7ß„ß Æ¸\Ó/²Úªd°G3!­¸EÜÅ’DG#^äUMÚäß»t_a)?[t‰ŒsݨÖF¢ªíXÅ_Ĉ»©Ü+ÅX·:W\DöÌ>'³–c±Åvl×TOLS3ì†ìùü@hÓç® ÚÕŠ«²½Wñ"7u0×.*4JߺG•KXôïm5ëìñs«ßíðRÅyž ˆÖ«Ôýh÷³mlÖuzwmá.Ïú*÷% @744•$m›!­‘ÐT§Š8Ü»ø«¤æOoª¦³qãz'ï ‡N¥’Wú1º¦à‰étÛÐlkÍ×~œÉàaÜÚ²ß;±=Ñ3ì†ßàûiq?' T})¦Ÿâ˜Z@T¹5¯Š\ÍÒ.'€Ën§åw$ÚäM•?ç'ÝŽro܉øºndÒÎ.3‡£r|ÊKTR«’HßuH™²í¾ñÒ"µÝÝ»äܳ÷~.þMbå}»ºG¦}Ìψua¸æXë{7÷ªú±}+1æØ†'¦Érkeµ·£SRÆ=wETDj®êªˆ½<в~/ô¦ÊŽŽÊëúdTDójuŠ.þ»¾^Uö÷5wù:š‹‚{|’º¯4Ïkk$•ÊùAcr¹UÛªË'?2ª«Uwbx§]÷%lg‡­ ÅQ®£Âèë&jªö×Z§*ïÑv“v¦Þ"w{zb¾EÚŽÙÞŸWJ¿ØÌ¯ñ·®âªŽŠ)ñtyæ¯+Ï„ªx™ÖFôS-+w×£Õ’1©Þ÷5"nÊ»õjõV'_¶þPðŬ:‡WÏVs§Ó±®oÖd¨ulÌnÛ«Zˆ½“:®ÝSurì½9­…===$,¦¥‚8b6dqµÖ§±:!ú¸?ì}ê®v|š}NÝ}Ï̇ o ¦ýÏ­WºQF Ã.–`òÃ_îKïWZ›TÜÕ%j?}ÕÍ‹db.ûlªŠ©²l»î«*ETñ2"dqÆÔcÆ¢5­DÙ;‘ö Æ c NåŠ"˜ì„C0Íq¹µßŽ»UÊ»g];£”Gd!¯iôšQ‡[õF»X()*)²¥¶;]s¡Ì‚ª6*+$–$èùÖµˆ÷n¨ÔDNãp!­ú©¨Z)šX3‹”5ÚOVèmWçG’ªËQ,¼¬®{Ó~x}&µQ=›+œÝÂoçOQOYO]$ñÏìl‘K‘Ì{7G5S¢¢¢îЇè¬šIaÖŒ-ø…ò¾án|U1\-÷|†¶-Ö)ب»*µUz/·¦Êˆäд÷QµcOðLÕœCZ#tº}Lúˆ²xÜÈ©/ôÉžÇ5¨œÍ›Ñk\ˆÅôœˆ‰ÍÑ~~*ø´³pÍCh§ú¨È/wÎÕôÔݲÓA1쎑ór;uæsQÔÝSuUoMù±­ÜWk&¼ºZ,·!óKže’Ü‹ l»·7WJ¨¨Š‹"»eMÓ`0šgª×s_lzÁw™Ï¨L·[“šõÞFM2­J#žî÷1ò&îr÷õU;{‘Íf†F¾7µ×5wG"÷*/Šçðí/ :’Ìû‡,C3¼×1²ÓZüÒãS<ЉÚRo ’È÷¢zÉ;—¹9—¯MÀ˜G¸‡òža8%Ò§ÐË9ÞBפ ¹öÜö–ÊäNT‰br¾­w^UF+×Ñ{»ŠÚüwŽ..ÙîŽ£æµøÞ33詪•ÔÒµÌåÙ”P¢:DV¯¯*l­{¹\íÕYšg9~Kgá…êmÓÛ<û£œÏdDË#…½‹«rÍ3Tö:©¼gpդΒ›(Õ;Tõñµ‹æ¥u}FîEV¢¶r1UMZ›+”ÝëF}åxÀmΩ¥Ó]+¼Þž×:8j®ÕqÐĽ‰'#W¹¼ÈÕFª±UwV*ljxW“ÛGìMd¹…Öñ“Ô&Üìt¾gN̉{DÝw_ᢢxn³¶%¤šc‚zX†cµÉÎY ¢bJ®MöU‘Q^»n»uéºíÞrÌÓÃfK…™§j»Ó×ò)ôεÅ!Ãì¦*çÕE>¹÷zÕ¶«;u:en›i]-ž•»¹²ÑcóN¼«Ê¨š¥Î‰Wd]¶kwG/E詉¨³ùM3ÖK%óS/6D¨•^Îýü­J¬jxµ6ÿEKª.7ÆsvtÂaíÑ»ÕO§ZcÔÛÚÙ,-?Œ®©ôG¿Ú£2p%®YT\¹þ¸SÔ«Þ÷H×TVW·ªïͼ¼›ªª"¯Dîßu2Öß&µ’.ouõjº§¿—Í­ ƒní·æ•ûøÿJ{:ÝF±ö®ÿ,LS”Qíšf}lú6s.£ÿ^½ó>õU£òsèÔ[:·+ÌjßfÔÓFÕo±S°UöõEC5MÀð1Y, BªïÍ%ËeO‹Ñb'ú‹ E;Úk¿+sÍ:{4dÓ“`)åj= ûMÀŸ1Y.7s¨U]ù¤ºÎŠŸ¢äOõ¯Ô3Çø¡]ýmSóÉôó¶›G3¯Ã®ÿ¹W½ïîVô4ú!_çàW‡9btqã\»lö]ªÉ×Ùʟê1õ<pÿ;‘AÓª.üÑÜ·Uø½&*¨²õFÛí%±×|õÕ>ÙRrœ ÿé§Ñ ¯_äéÑš‡+è2|¾‘USÑZªi‰·r"‹ßת¯‰­\ü›ì®zÙµZåJÕõª×B§_l‘ïÓ§‡^¿sAŸgÂNÕXùʼñM_ÅL¬×‘eÕóµ¸öJŒCÀ>±bkÛéþ¶SRNžš+Uoôû÷æ‰^½íg_‹âMþú|ÊI§²7ècVî÷ÖÆÕk™2UÆÔèÝ‘•û"&ÈŠ:'±z`Ì/†=§ÃÏá*¢çÒ¢#øf–%Í—Ëëù11Ý>ýTþ‹o(&˜v¯Ô4!¥‰®Ij+±ÇµŒånê䚉Ywnª¨©·6ÛmÒ@Â|¯ÄÓEC©š=tµ=«ÙÏSi¯eJ#¹‘{[µ9·Nw.íDë¿KkyfšéövÅfe…Yo*©Ê’VQG$ÿEêœÍùQP—eþnDÅ9†&:è«OøÕüMmíŽvnúcísvÓ^98aÕd6}P·Ú«^ÝÖŽù½¾F¯"9Sš]£r§T^WªnÕÛtÙVwŠX§‰“C#dŽF£˜ö®ísWª**w¡ÍüÓ€-ÈÖJŒi÷|bw§¢ÚZ•¨³º«&æwz¢ª#Ñ6nɶû‘e&“ñ£ÂšI[¢YÅmæÊ÷vÓÒZÓ¶j«W›wPÌŽEròí¼hç**¦ýzôŒ—ÂvÎguEºoxªç¢änúõšäÑbò v7¦èë§«Ÿ©×PP ò£Ø.Wp®#1Iq Ó$Jin´±?ÌÒMöúüúí?^õôÓ½W• Ûm¹Ûo4]l÷ jê*¦$°TÓJÙb•‹Ü潪¨ä_j)Ð"b¨Ö94³p—Ò*[âsìdž}Æ›õ§«|N}˜ðϸÓ~´à-øåþ£¾E=_ê;äP=¤|KËç²,Ÿ_-õ ´q箨c:tYaEßtöµ¬éá·‡S0@ºy‚k¥Ûµêá¹›±ûãu‚e«‚é5’QÈÙX³BªåErÆœ›wµwß÷x ™û¯‰ÿÇÿjQ=®üksû_dº@o}I~Qò†¸þ~\þi$péÃÇX.²cÙV­k-m÷¡ó¿t-òeµÕ­›ž–fE¼2§#ö•ñ»¯w.éÕúu] [T­Y}÷Mòk.tm·$®µTÓÚë*ÄT¾5F?UŠŠ©³‘7Eê€m ç5g~RÚnNÇ[ªjù·ß±Ë'N_—­ïø·î?:n|¥žqžjå×°çokÙåÎçä߯.ý7Û}·£ ç¾U‹ùSb¼Ü'Æï53[_[7™ÂË…Êu{–=ÖENæò§UUùz©Š§´y[éflñËZç7}’JÜzFõMºµÏT_Æ€tt¶–³9f›ã)©²5ùo¹TËzVö[%bÆ‹*}e=ÑÛ¢òz;§£ºl¦Ò›ˆ QãßÕ¼š—Ip ›Žé›k{lñUîß7´s\ÝžíåWª¢ïËÝÑŽéø‡ò˜Ã3e“F«jÝ÷ŽLJTkºxòª/ÇÑ@èè"^³=ZÏ4¾;þµãX2e¸TÁ%íÒQrÂÅDc’9\¨½W›uEðèK@Vx·âk[43,µZ4ÓJ#ÉíuVĬ«­’ßW;`™f{5t*oFµv^¾‘SùF8žlÍu_RD›ó6;mÁŽ^6r¹È~%£ ®üq+™qnÉëòÜ›÷jXiÙj½·jÙÊ«&ÝÜîö– ®.x”­á“ ³å”8”7ù.·T·,2Ö-:FŒ’snŒvëè"mÓ¼¬Ÿð¹ý>ÿâ¿þS¢©œ/qçõIjTºyôªúìí“Ü|óÝÏ;ß³|määóxûûM÷æé·wRÙ€­šŸO£]Ôê»D—H¬PÇ3¨ã™"t¼ò²4Dz¢¢u~ýËÜSøZñïõã?ÜÊ]åAÒK¦i¤Ö]J´,’¿ª™k)š›ïGV±2I}ª¬’(z'Dcärú§Ã§¾SÛŸã8$:?_E&Ix¢´6¥×–=!Z‰™=[ا27Ÿ}·Möï.NWŒY³Ljç‰ä4qÕ[nÔ²RTÅ$lz+›o³Ñ[ºw¦è»*"Æ~8ÃÕîk¡§´]¤½ãMݲØ.3¹ÔÜ«ã õXñ·¢ý³\u@x¶Ò!éc§Å/·ä)ÉQa¸í\hßYÌÙU³3Ç™Šªˆ©Ì^‰ÆLû¨Às¬¬«Žª|ríYi–xÚ­d¯§™Ñ+Ú‹ÕUЍ‹í1Vë•ÆÏ]ÒÓ_SEYJô’ Ši]±=;œ×5QZ©íEºüBä’áú ¨¹E<Ί¢×‹]*iÞÅÙÉ3idXö]—eçåë·Nò¨ðÛgŠÇ ˜>¬–*ZÅô•})Ø“;ýr/O¼[øîÔŒ›A³}ÔˆÍvÇ.ÔÙµTh¹ÊÙÓºTäkÑÑÈ»ssøZ­0‚Zm4Ä©§o,‘X¨ö’ˆ©Ðá^/M9~ÏD×Tú)ÓþÉ~ÈÓ~å]Q¹þ˜|Òž5ÝCÎ-Zk…]³«Ý=TôVx;y¢¥b>W§25¨ª‰Þ©ÕU;ÔÆé6«Xuw¤Ô+5%e¾†¥Ó1Ñ×5¬|kÕ¯UTUj·vªî‹Ý߲â7&½aÚ%–ä¸õS)®44Hè%|ÌÖªÈÆ®ì‘®c‘QÊ›**u+Âê²å¼Í–Û/––Õo]Oy¨’•”Ï÷9øÖ:fAFת+S~T麢£¶Ro“lÕ9¶SEøÝ¦ªñÚßšæ4Þ§]77tŸ¥½®¼4éjqXùÃbfŽ3DÕ¤GTõëêÓ·U¾±dXþQomÛ¾Ûîô/s˜Úš¦TD®NŠˆö*¦éâ›™’pEbâk†ógÌìÐi´w¤¬´ÉªG"*9ZîÁ]ÕêÕþ:"ü‡ŒŸ‰ eÕ­[¾`ÚMžãX-’Âé˜ÚÛÄÄ•}”‰¹d‘’.îvêÖ±©èúÞ&v+Áíÿº¸Œn«vbfªæjÒˆÞ˜ŠkÒ™ùÓ•1Tv¬ÛΨø5®ÑTUWŽxk¬qåÛ:.ð*× o“eRKàó_5;;Ìò-ÕjÈëî–8_QOaRƱLÍû4F¹Ïf˶ýº®é³5ðs™å|Eë·mUUˆ‰ªŠj™ª)ªtŠ´ÝŽÏŒÄéЦ<Ãâk¢Šiª"¾35ŽŽkZ ÐjüÕË`âƒ^p®YÖ’é !¥G;v1ë Ù:õN÷=íîÝ#ØÚ‡ÔGhïš»¨”¸ÑÛ4Ê’êê(¤HÝ2ÇXÈÚÞuEåêç{SeîS°x½6öŠº"xUj¯UTOØŒí]V'ª¨öK € ðµãß7ëÆ¹6,Ê‹†æYU—¨Ò{Õ÷«5¹’²ã̶‘±£×vµWevû|]çÕnt» ¢ôžV0|Š•Ú[”C/GEQO"ïìÙ\Þýw>¿øWtoàç3ÿ»Kþô º  –Qg˜N=œÛ©¦§¤È­T—h!ŸnÒ8ê!l­köUNdG¢.Ê©¹œ «žyG´7Nó»ÖŸ_±œÝõö„¶ê©é¨iN²FîW9ªµ(õoMýT]¼ wü(\6ögýWûà-Ø5 %Õ kYôúÕ©X„u¬´^;7mdIÉÙO$.æj9ÈžœNÛªôØÛÀÖ¾/4k@rª\;Pën°Ü«-ì¹ÄÚJNÅòI*¹¢óBþŸ'´Ð?á.á{ü+‘S¿÷Gx¡¼jÞ‚ñu›_¬™ÍÆ‚ëp¸-Ö’ºŽ¡[ÚQOéà ۺ£Ûv‰XôT^Ë}¶T-G~RüO/u.)®”ãWg5±Ç|ƒþN¨r'U™«éS¹Wn¾“:ªªÆˆˆ±ßÙœñS£í×Í(¬¯‘Úo]ªðÚØŸž–±ÌF9­r¯3™2Æ6Ý%z¯ª…ý ÓTÓÖSÅYGQðNÆÉ±½ÉäÝÕNŠŠŠŠŠ‡4¼¨ùmþkö„dÃÏÚµÃÅl4–K“¯Â9Ë6?_+–›Ò]ÜèWªÀýÕWvôUUW5Æ×ÅŸx¿:­¢9Î5m­¶ºš­–úê*­œè*[[ Õ­zt{U²5QÉ·TEèa@Xð‹üfšÉøC,ýªÓ©Ç,xEþ3Mdü!–~Õh3_øø÷¢j?Þ4ß®@s Cÿ¼8¾ú›ý¨t÷z&£ýãMúä0´?ûË奔ڄ;nÂãéDz]À—ùš¯ÝWí¥ @úØ&ðÏöy¿ ·ô\_.$õ–ë¡øESg³Ò\¦¬ºÇotU/sZÖº_Ìœ½wÞ4OÆ¥áêél²kV#u¼Üi¨(©®-|Õ52¶(¢o+º¹îTF§Æª_üç(á§RmPÙ3|ûºÐÓÔ6ª8dÈ b6TkšŽÝ’¢ú¯rwíÔè»)r¯¹WíÙ¹\š¸LÌFœ#÷ž¼*X·ñ£ˆÅáë½bš<ºi¦gXÞ«‡ 8ùá‚áˈ¦ñòÕwÄc¶ÔZâ‰fFMÛÓÔE/;UÔåõvå]÷EùP®zͦ¸æ™ña†Ð┣·]ëí7VÒF›GN÷Ö¬ocÁª±+‘;“›dÙ,µ»R¸XÑk K±\›¢§+¥†ÍPÊºŠ‡&èÔrD¯{Õ7TEr웯TMÊE¬úá[©ÚºÍH·R:Ž Séã´C6ÊöCŠö,›tæsÜçª"®ÜÛ"®Û­ÜÿjÖ_fÖ.í7oÓTN´éË^<º4Ò:5ž†>Áåx¬V}ŒÄå8k˜l vê§v½tš¦˜ˆç®³½­\&wbf5ã¤ÜÞ6˜çhÕÍjª2º‰]ñ'l‰þÕBòyÑM&[—ÜZÕì ·SÂå۹ϕU¿êŇ´j¶…kÞëUâýf’–íNÔ¯³WÖ¶ ˆ\œ®V«UÍ äEIÓv¢µL.Ÿp±£·X4ûÈì>ëö•U5‘\[5;]z$õoz¢*ìäk9º.ý™9¶¸œ5ŒFog6‹ôx¸9ñ™ã¦ž˜÷"ÙvcËöO²µ`®Î"ªæ©Ò&šcvj™é×È8i:Ç/ÅŒu\Wiý-Ão5ššÑû÷vkp™þ­ÉÏŒŠªú^ò7P=ìI$£Šw1U"uLh©ºx*ìÕö¢ªx•g\¾Ãë¢ù†dÖë¬T¶*f¥]¶²:†G3jjËÎÅTG&í]»ú§´³:sÄnŽë6î>wz²Û«êiYKwµÝ¦e#eTùfec²ËQ]NøYq¸CL鑹Z’97D_a«Éò¿¸™µv‰™ŠõÒypá¬Îœûº]¯ÚŽ›)øí4ÑU­7éÒjÖ½gH~NœxÏ>…·ÑXí׃-ñÓE__#këšÇ'k+•©dzwíË1»flÇ6ø±°j—XîÕísëýÐrÏj«DÚQn½œq·¹œZæ÷ónåß›™ÛV£ë„¸wI¯·›cIÉITÙiëi<Ö–${[ÑÍ]•7F½¨».Ê……Ö{ž€ñ¦‘Ñ¿Tq šÂ•ÖzŠÛµ<3ÒNæ¢òJÇ?ˆäÙ¯b¦éÑvæj<Òþhð×°¶ªŠ.YªtxU¤ÌkÑx÷ON’lÆàó2ÁæX›svÆ.Õ1UQDÍV¦b&c¦cw†¼·©×†´é¾ cœ;c‡ngÉ^évþWžLê£M²áÀµ³2žÿ[YMCIsudÓ9÷NvV¶^w9SÕÝ$E^í·#N8‘²élušc¨µ‰¥Õn’‚áÓEK*®Ò1îb®ñ9Q¯n芮U^Uݳ^M¤|#êMî¯7«¿còOS"Í]-DÈá–Eï{Ñ’l×/zªrªªª®êª¥ü&*3 ³N-U]¸ˆšntLFšÇW-{{á…šå•ä;I¹šÕ‰·fýUUExyÒ*Šªš·jׄÄD馼'¢buhZk–jV“:ÊåÐ].°Ü©ª©ám,ìTåGµÎÝìDõ^äïñ%Þ½îX—ÿúõAVø­¡Ð£Ç4eö*if¨’¾Klþtõc‘œ‰%FîçêŽÙªõTëÑ7%þ õË¥Ó:m:É2+}šéf¨Ÿ°muKaeT2ʲ£˜÷ìÕr:GµXŠ«²"÷/L|»0ŸŒ5Î2º7¼^î´Ï“3­3¦³<ùÇ™Ÿ´91àþÔe¯M?ÆM7"jÉœÞf=èäÝªŠ›§TTSgp?qsŠíß¹LëngXž*8NºqáɱðƒürÙXŒänߦ™Š©ã:[®fb"gZxé¯[ pãû ·×ÔÐ?½½ÔÓ>rO"«\©¿ÄWË2î*¸‡¹Émílöû´Ò\ê"£å§¥g+]¶ÝêªÖ§‚+¼QŠÿ,sßnSC#_•s9ŽjîŽEzª*/Š º¥dÒmX†÷’½bµ\h¥¶UT#UÞn×¹lŠÔEUD|LEÛª"ªõÛeÐÎu{8ÅZÃæuÄÚŠã^œf::Óšv7 ²9^+³v¦1Sjb8ÍS¯ áLÌÆºÆ±qž‹5•h‡zk·Ë¨´otÕÑÓË[YW=ERµ™Ý” Ù7MÕMÓ¹U ËKª°šÝ>³ÔéÕ:ÁÉ ýÏc‘›GÎä_FOI››¿ý†‹ªÿ ÚÇEm¿fù…†¦–ÕÏØVAŽr=Z¯cœ×쨪Öüi੺Ÿf¯Z=–K69›XlÖÛ ©k¥†¾¶*4’8ãfÏ…²¹èý.Tr§Uk»û×¢á#€ÆUøª-Ìy;ºEsË]g«ú>{ÍjÇç™Mº®N*ö"š¦noë6©ã1LSf*c«N1¢òvE Ôç³9¶k-jøòªÔªÿ­GÜtÔܦ×'A[Ì”ôöŠVÑ¢÷vKÎç*8²'â5¾õ²ŸE³çÖÞÒgØ/ù¥Å"g;âÙwŽdozò»tTOµ{¶ETD.†WAÂî¼2Šï‘Þñ{Ô´pï̼ù½DQ;Òä“’F=½y_ꪻ¢*©À[·œäåönSMÊ*Öb©Ó^3=úi=\áÕsÜEýŽÛË›A‹Ã×svˆˆš)ÞÒwi§§H×ZyLÇ µs4éåŸÞ™Eÿæî?Ù¨UÞ-ÓB¬¸î3‡é±õž†¦yªÒÖô¨r1ZÔNÖ¡Ê÷nÎz¹6ölO¼7k~šåºKcÄ/y¦‚ék·Gg«¶×Ô²'LÈÙÙµÌGíÚ5ѵQ»ìª¨¿vok-ÇßÀÜ»LÌÑÃ^˜Ží{Þ|"ã±;G‘`s¼>å4Qvfi˜ò¢˜Ö"f#”U§>1Ç0ç}¾:Y«é¢­•b§|ÌlÏNö±\œËø“s§TÔ\è¸|Ì_eY2ÒC »4ëØ>xÙ2|“¤ßâÜ­|Ré×86ÒÁÖväR]!l‘S^䬴ݜ¼ÛÆé_ÊÞnN»']º’Ö…ñ?§‚Á†ê…âÝo¼ÇGæñÝžØénQòò+Ñï^EW·Öc•u]‘P®GbŒ®æ'*Äݦ+¹LiTOUFšÎœxë£ÎÛc¯í5Œ·j2ü-ʬá®ÌÕETéTÆ´U®ìM^LîÌL÷+ו(uâ–*nÂ{edu»wv(Ôroñv‹ýD•ålø ‘¶T¹¢ìU¿ÜÛoø÷Ûñ“7G¶€­}úÁzƬÕtß]‘nëWS$¼Ü‘5Ò>EETEåbzJßuDÚ–q)­«­¹â]mÑMŠÙšÛ!™¨×«Uw|¯DUDsÝá¿Fµ‰ÞŠxÇÑo%Èj˯\¦«•Õ®”κF±=“§®r¿‘Þ¿¶[ukhp˜zíá¬Û˜š«§vj™¦ºz&bgZú&|šu9:®9ÏÑŒ« ³T>žº–Ôÿ7™‹³¢{‘jø+y·OTK,³Êùç‘ÒI#•ï{ÕUÎr®êª«Þ§F¸„Õ]/½hnUi³jF/_]SoFCKKx§–iÎÎc^®Uø‘q˜ûsˆ¦ö*ÔQV±ôN±®³ýþp0™^&»öæŠææœbbf"˜ÓŸDLÏ­Ò.3Ê}IÑ K-ÕYQW`k¬u‘?eí k~²ªŸÉX•¬Ý{ÕŽ2\3i,Z9†_(êܽµ]òºGO3Q®ZX%t0+—ù*ÈÖTûª•S¼î§ÖÅ´}WJúg±©º6xZéb‘|z"Jßç7^âÓñu¨@Z)wm4Ü•ù¥š—¦ë´¨½ªü[BÙ6_+I&M±,£2¿Æ»ÕOª=syæ\ëkò,niolætµŽ®ÝqÝ­]MST÷S ¬™äš™©Ùh¯rÁ_Xä¤EEj¶•ˆŒ…<³kwø÷4ÀOzõx‹•]¹:ÍS3=óÅõF k‡·…±QE1LGTDi [ds¯ÞDEú/$b9×ï"?¿¢ý›žÿ±ô¡ÛÿòÆ;÷u/ö€pïêç:Y‘Ýï·:š|Z2™#Vr¶ižŽTsUUw‘|S¢!¶ÏÁ:æ"Sg—Ý¿U}oM¾DrWÞõ-3üÏÓy7ŠþG—âk›·mÄÕ<çYû%òm³ü¶Å8l.&i¢žS:Gž%V§àjÏE¦ÔÉ#nÝQö„zïò¤È`.<f‘oîFee©öyÌrÁìþK_ñÿB{z\@bW²ù]qÂÞÓWÛ-­Ÿ ÛOju«Gm}”ÄúÔRãÂ6³QmæÖËe~íWs×±»/³ëœWú>3R»è¶°bÒö•˜%ê73þv’%¨kwUO^r'røø§µ7èÀ0nìv ®6ëª'Í?gÚÝa¼0ç6øb-[®;ª‰þ)S™-Ìs›t‰™Uö•ë·;Rºf/źs|ë6l{P5.®FAµ\($w,QÇ]v¬Fl¼¿l­X؉¾Û¹SÕ_ ·èß°_âì/Ö;}Ê4ûJºfLÞåNç"ø*ÿJ‘ÆGÂþäQ¿“}ªgï´ÖÙݵWn¨ÅæÃ»—nª`W²ØÛ­‹ÛÝ“3O²e¾±áG%ÆÆæ;6æzb(®<ûÑLéÝ¡kOÕ„”\1Ì•/Tª›¶jk¾¹ªžª.îWsw/·ª*ŸÓŒ‹¿ô†#QqåoT÷"9‘vN«ýÏ·^½Éâ}¤¤æö$©Õ>W5=¤ÅñŒÂØÚ˜]k½ÛæEFÈÕŽ¦§Š"¦í^ä6ØKxŒU;Ø,~÷dÓ>}xÇ¡Íq9~YsÅç9çm7+¦<Ó4ÏšP…šo:£nöCJª‰é6(dj.Ýç~NŸÐm6Þ*4Já²I•KFõîmMéíñk©ÝíñCj¸èö•Ý·ZÝ<ÇÜåï|tÆåîïs{“ÄÕ«øYÑåW3’•ÊŠŠ´õõ á².ÊõDÛäùw2ü^ykä×n¾ø˜ö5?ØŒO˳ˆµ?³UGü¸¶»>®é}ýî^}c•ÎDTõŒŠN«²zTwÅâžÓkŠh§%‚VHÇw9ŽEEühW˧ZyPÇ-§$¿QH©èö¯Šf"ôðäjû~ÛÇÀÕ*x4Í,³­V©Tí‘ÌÇK´ŽM“§¥¿®ê©¾ßÄ>›Yün*í¦¨öOî&Êbçÿ2ªÜõ\µ3ÿ*tˆ[TÇé瘌NeŸ.ží¨‰Ñ“ìÔ^æ¥R"ü›uÛ§ÄXx°ÂܬɰWÜØ›#¥šÎç56DUÚJek7ÛåñéÓd}ß‹_”X¹Gnî±é‚6 ¼O¿bïd\Ò¯DÇÚ¶€«–Î6Û ©O“éÜð9ªœî¥­ÝÈ›uúÛØŸ‹Òî_éÞìœ\èåÝèÊÊ륡UQϨ•Qw߯‘¹;ý©ñí‘g?Ëoð¦ìG~±íѯÅìÑà£ZðµL~Εÿ Êh¯ê†e-g¸­ž­ïõaJ¦6^å_àܨô芽SÁ}†Ðm-Ý¢ôo[ª&;'Tc…¿„¯Åâ(šjꘘŸD€âÀžá_Ij ©ºWÌ‘SQÂú‰¤ws#cUÎUù¤˜w•ªbOŸi=îÛDéÝuö¹ÙU•6]œÙ>UFª*¢=˲ïìñ‚<Òn 4“[i_6f4· ˆYÚOA",5p·tEs¡z#¹wTNdEnëÞH`†ùb³dÖŠ»Ej¥¹[k¢Xji*¢I"™‹Þ×5z*pç·Û­öš(-–ªz*:f$pÓÓÄØã‰‰ÜÖµ¨ˆÔObAƒÎ1ªŒÇ»bô™ÒÁ=Ê™ÐEsµÎ°ÕR={¤éÕ<6Ý7MÓ¼Š8gÕ<²õÛG5n¨õrÅ]Q$*‘Ýh•ê”õѹ•QíÙ®ê©Íâ¨ÐœÀarŒ# Íéc¢Í1-þž+£†éAS«¶ê‘ªˆ½»Ø„9•p'ÂþVåšM7ŽÕP»'kj¬ž•7UÛ³k».»¯^MöÙ7ÙŸ@(òWéõl’?Õõ¡äV2áG r1¨èˆêˆÒ#¢JÆÖˆ·f˜ˆŽ `/#=gáëNuÂÙØeß7¹ÂÅJKµ"#*a]º"®ß\gùŽÝ=›/R¶h¶°êŸ“÷U§º—5UÛLïS=S²ÞF#7OîÚFªïÚ®okÛuNªŒywÊíÇ–?f»pýp»Ü#ožY+¨êhËé$™°½»§r,r=U¢«[âˆuŸ;oÊs+MÚ¦¼=Ú¢ˆ¦xîÍS¤M=Q¬ñŽZk<ø£yþSgb¼M1¥tƺõé×ö:l¹Q^-´—{lݵ%tÔÁ'*·ž7µ×l¨Š›¢¢ì¨Š}%tò|eWL·„œ¦ï+¥žÝU©’9êåX)êdŠë܉¬b'±žÉbϬœà*ߟf<3î4ß­8´…[âsìdž}Æ›õ§oÀ/õò)èòÿQß"è(âr”|nimÅñϽǺÑ5Û}ox¤tþÝž»÷÷·¢w›‰­q½L¶® 8uÌÒ8Ò&Üo¶YÞçõWÕRÄØQª‰ÿ­ëíTïè†Ê|¯áºÌÛÚ W:*µO¦*®=·²uk‚ªžª§Ùã‰@·7â{Côã%ªÃóLÕÖë½Fé©Ö×Y/*={UNc·k‘z*ûª*ÎO˜ãXn1W™ä—VQÙ¨aJ‰ê¹#[ª"*#\íÕȈˆŠ«¹°¹”æbÕW,WwäkMQ¿®šnpòµÖ9kÎ:Ö)ÄÙªjŠk‰ÝçÆ8wõyÙFxZ+ªq\5K•Ñð¾vÓ­¾ªf3neGKZ»oݾÿÐd5+]4¯H*hhõ*m¦k“%3Ž¢¡^Ö*#•{ßÊ›¹;öß®Ûì¥Ú²<ÒŒT`jÃ\‹ÓÅ•oÌqã鮜'ޤbðónoEÊwc§XÓÓɾ æxÎ[ŠÒæÖ+£f²V@ê˜k&ôíXšªŠõIQ®jz+ÕÈ:÷]Û-·I¨ Tö=Y$”–ú™¢j§;cåz|lW &G™ãîWg ‡®º¨áTSES4ÏUQÂ{%K˜¼=šb«•ÄDòÖcrn4MD×=)ÒzÚ+n˜SÚªî GÁ Ã,ÏsU¼ê‘µÊÖÎÙ:/S/êN ©Ö…¾`y5â®ä‘Ъ£âwòdÈbøìäETêV>1pî² F³Õên¬×âWÆZ¢GSÃhžµ•]´ÜŽEŠŒ?j›ª¯DOG¹Wm³9Œ~o÷?6¦í1Vô[¢ª®DÄpòwj˜íògÍÍÅ×g ãðÓLÏ &f"=:ÄzÖâÝp¡»[鮶ʸª¨ëaeE<ñ9Éb{QÍ{U;ÑQQQ~3è5}ඬó-ŠŽã-¾YÙE ÔN¬uDª×+cjò"ø+¶Eð&}4×(ÕçÏOeÔõõtÍç–’H¤‚¡­éé$r5®sStEswDUDÜÓg[1Ëoâ.[ÃÜø=ºë¦+šgIŠj˜‰š´Šz9òÕ•…Ì,ߢˆªºwæ"f5u˜×–º·àB\TëÅ«HtêçKjÈi Ìn0$6ªV=jËmºáÉçôÕ=žü´M.ýûn;“ú¤òRZmT,Ô6ÊJy¼ªè¡kSÙº'wDþƒëÂ¶ŠŠãK% Â’ªi›Ë$3FcÓØ­^ŠŸ)„ú\içø‡ŽÿUÁóMˆ¦ÀpZ:ˆ«(ð« ÀöɱÛakã{WtsUº**"¢¡¨q¬t:£×ýC¨tn¬¦‡Í­p?þ~ºMÛ 6ñD_Mßæ1ËàI¥Dò‡h†·ëŽ=…Ùt–Ïîź¶²ªíCçôôÛ̬´Ó}}ìk¹Zµ-èíÓ´î]÷@äõMMEeDµ••O<ït’Ë#ÕÏ‘î]ÕÎUꪪªªªMÜ;p}«LÍ1¦ši¤Æ¼{ÕC…¹8Ȳ žý£U}ǽε-3®w*Ù¤íÛ+·tMe‘ˆ¨±±wæßâCZòj5©oÔl›¬ÖÄUø¹jz—UŒdmFFÄkS¢"&ȇôÔã¶×áx\v-U1‰ñZMwj¹U1juã5FµoN¿›ôD²lå^*å››Ñø=îTÄDïpåÃO>ªEÀ2'ÓKTWn¨¬Oþø˜üøP÷åêÏú7¿Ú°—„†Þ|:ö>÷ÁôøUº-é¿®îäDkòc{]9pÓ®^,äþ&›4ïëâê™åÏ^Ž|=`çØi\8Ûhò4uQ× 7UÓPáv»t‘OI¤²¤¼ªŠŠywD]¾ß¢÷›©‚àbßuoˆ<ýû>9²v9œö¹Yî};Û#Q=U•ª½zªuꊫÙ<á깟ݽÑM©ôÍTéö¢ûY\Sƒ¦žº£Ù+Cô¸ÓÏñþ«ƒæž£ÓÜ48>>Éäs\Ûd(­TîT^^ŠlúÏgÒWFþ pÏê_÷gÅQÃÖUÌꊽÓù¥~ÜÏ“¢s—dÙ7U~ä$Ím¶Û¬Öê[E¢‚š†‚†SRÒÓDØ¡‚5ÈØÆ¢5­kQˆˆˆˆˆ} ^¸mÐ,ŽïY~¿i)p¹\&}MUUM¶9%šW.î{œ©ºªª˜ªÎxe®äí´Ko&ûv4)·“mû¼Ix…ðÜ_O±ÊLC ²SZ,Ô§›QÓ¢¤qsÈé¶ê½ï{òª™ 5/†íÖì6¤à4—Ë5#hb¨–¢xÕ°5ï{Y´ojlŽ‘ë¾ÛúF§õ p¡ð9nü¶¯ýé;€9¹ÇÍf—èOÞc”–Gf_2( –Iiár%;\²9ÊŠùYÍÑSd‡»Ò(m8ÐŽ$5ïŠÜåmšaw^{«©©«g…`·¶‚¶*y|âM£Ùб’rµÊåUvÍUÝ {ï“ÓKtn¢Ÿ5ž<ã$k•khã÷>‘û¢£¡ÈåWµSd‘î^äVµŠ1áË€-UÖ™â¾fUáXšµ^•ՔȵUjŽDVCNç5芛ýqèñN~ãîã[DðMÕý Àð 9ã¢l¬©¨¨ª‘$©«Õñ#¥•ÈEvÍjtj"#QëyÌß*¾[Cÿšý¡29cÂ/ñšk'á ³ö«N§±áøÍ5“ð†YûU tÌããÞ‰¨ÿxÓ~¹Ì-þðâûêoö¡ÓÞ>=èš÷7ëÂÐÿï/¾¦ÿjí¹ÿ §Éuÿ_æj¿u_¶”€9ë`ú-´ñV\ii&r¶9çdor.ÊW"*¦ÿ)ó‚±:N²¥Q3::e§<:èÖÖÖg4µ³¤ÑÂæû£{­‹’Š%õùÆ3tè®]ݶéº"ª-Câß\(56¥ Ægt¸ö<É ¥•Sd©ê¬ÉãʨÖ5»ø5W§6ĺª"*ôNàI3-¢Œ^à8[1jÞºÌD믪?¸‡8ÙÏÕeY¬çy¦2¬V"#všªØ¦4Ó„oUÇMcœGá¬êÓ¤s¯ÞDEú/$b9×ï"?¿¢ý›žÿ±ô¡ÛÿòÆ;÷u:«Á7½KLÿ3ôÞMÄ#Á7½KLÿ3ôÞMÇw|2Ž3Žô³<í§¸ã¬ ®™Üî­·*A2»ÅW¢±Ê¿ç5HNíÃ.­iÅ|·Í Ì䨊%íYN“­=K¿ÍVÿ/Oå*oü’ÙƒS‹É0xº·æÚ¿:žêûR¼«msŒªÒ®™“7¹S¹È¾ ¿Ò¦‹xáÃEï[¬ø5%;×mG,”ûmñ1ÈßõP1ïa0øÆÑwÄKa„ͱùä—ë£èÕ1ì•s¾pO„Õ"»Ë/ç®Ý*YK¢÷"#¿eõ½¾Þš¼œ5ëÞÇ;ÔžÚz°A_=Ÿ»Q=EÞ? º»Á¿ŠÚWsg2úçzŠf‰ë¦f?§©'ÃøDÏíSâïÝ‹´u\¦š£Ó¤O­R¦Ï8ÂÀ$å¾ã³ÞajìŠës*ãꩲ«évTözKöÛwíµŸÄn7k¾-h»_h㤸VÑCQSO9 b9Y³º¦Ûí×Å °2°8 ðUN·ª®™åNºyÚ¼ï>³œÛ¢)Â[³\N³U¸ÝÞìÓ” Þ63Ÿ .³*إ䪻R¶ËN›ì®Z§$oÛãH–WÕ1|i¥¿áo¶^­tÕ?D‘K{¬†x[$s%C·‹™®EEúÂB}„Cå$»We·/Ð{,©ç™ÛÎäg,{i©•SÅeŸþéªj•·Œî °ª[Ý«[©2L:–xm‘G=fš™ª×$hæOÕ‘¢1œ’®Ê­M¶6Hãóâ¯O±Nø‘ÒœËEi¡Çî·Úôu]®‰{:täžÑR6®ÌŽfË$ncvj£dÝTè™Lt…ìÃQ³lsŠ. 5&—/¸KIIt²QÑF©mVö”êåäcX‘«¹Ò&1´ÝUW¯7Ùź«xÕ› Ü9½)²z¾Í×k²rªÒ5ìçäG*9#kbT‘ò"+‘¾—x\ RkǼliU¡ù¾ ÄÅË4¹Ñ1ÕUVK’M+'F¦îŽÎù["®Û#v’¨»Ÿ œCQñ¦ŒÉ¦£Ž†ûl™(o4‘oÙ¶tj9$uUìÞ‹º"ªª*9»¯.ê0#¸µóLåÖ)´!.õF“­*RHèÕßnÕ¨­j¤{;ÒV÷¢&ꨄˆå’ëkŠãž[•++çfŠ•Ó5&|iÑ\ÖoÌ­Oj&À}@!šˆÒX%dŒ]ÑÇ"¢ì»/TøÀöyHãI2FÔ‘ÍF¹ÛuTMöE_bn¿Ò§ ”’5‘Ñ$Wµ¨ç7~¨‹¾Ê©ì]—úôWMUijÕˆøƒÒ»mUâÛ‘Ô[íyÖ7GMÛOW ?²Šº‰²ºhÒDNTïEÝvj½RÄÇ#e²µˆö£‘Õjì¾Ô^¨¿è%ÆÇ½KS?Éúl9]ÁŸ49™UXrÚ·CŒdHÆM/"*RUµQ#™ËÞŒåW5Û{Z¿juGz–¦~“ôØPŽ8~Â5ã…ê~E¨î”—:ïsîÐ5zeWµUªì]º±}»¢¢õ!1¹f'›yÅ36.ÕU4ó§]f+ˆéݘ‰÷ò¶Kks½…Ÿ.˜™yOgŸUÔ¤«¥¯¥†º†¦*šj˜Û,3Dô{$c“v¹®NŠŠŠŠŠýN{Á~â_‚:ÆÛ®ôqäXDõ È#Ÿ-½‰‰éRÈäëÈäÙU¨×ìªYM*ã'F5.ÖßbÅnÛ'iEy™±]ÿ³U#^ˆ›µËü“æ\ç`³ ¯‡eÓœ,ò¹oÚ¦5šf:yÄuëÁ>ÂçoUâoþçM5pôO)N€þG#%ce‰í{ˆæ¹«º*/r¢ŸÒ Û€€ êÇZ7¤ð> ¼…—˺³š;e¡í¨“ªtí‹ÙÄQ}'sl»£\gåÙ^77½|ª®W=ƾž¨íž 7ñ°ÔoÞª)ŽÔÇ$Œ‰Ž–WµŒb+œç.Ȉêªs¿Ž"lš•r¡Ó¬êÚë–wTWV@ät•{rµ#r/¦Æ"¿ÒNŽW*¦èˆåû¯z¡Ä_—Ü/Nm-±á®‘a«r¯g'2¹žwS²¹W—mã¢ÿ%Ýæãª|2áZÂŽaUMnYETØëîò¢ï²Ü)•b…«Ò8÷OôÓ™Wf£{Êd9~Åæ¸k™Õq^6åtÓEš&'ÅïÌS¿ryDÄN±Ù1¯:cŽ2ök‡¹N4µ35O í8éO£Œÿsn|š>ôL_ïëŸë’–«~Mz&/÷õÏõÉKH}6€€[âsìdž}Æ›õ§«|N}˜ðϸÓ~´à-øåþ£¾E=_ê;äP=©¾QŠZ~iî¡ÕI?Aº‰f¸K+Èå¥rÈÉ£G*ìÔ]ت«Ófa»q¹„7P8SÔ«BÙe¦²Kw…~nÒ‰R©»"¯2ö*ÔDïæÙUUHƒJ²£]3ŲÇIÏ%ÖÑIU2óó*Jèš²5WdÝQüÈ«²uC篸ÿÃÇG/.‰õM?öMvB÷ãlÏdý“ö6óÊl ¾Q¼'Ìs gP)âTŽíE%¶¥Q:$°;™Š¿™*§ÉûkV±{»ÁnmO5uþXm•ms½'2Þª’9}ª²G¿ëîO¾róÁÙÂa°—­S¥S4ë=zÄOµ>ùB4¯£ÇéµzÕ¥þºéIj•VmáX ×£6è»ÆÞ»ûM/„4ÇZôúí’æÌºº²Žòú¼Ò¯²gdBôÝ9WuÞGuù «ÊI=N„ÑÍ 7e&EI4«ü–¬3³ûÏj~2*à“_ô§Kt÷ Ç3ü¶z§Ýq‡žšiRh L^^ÍŽÝȱ¯Nþ©¶ýM6Oίx<ßË+¹Uê.nÆæ³TS"#Ž‘Ë©•‰³…§;ÓM:ñå¯[yâ@´ç#©Ãmw}l±`ðãÖFZè©nÊÇË<ª5¯Et¬ßdDE]»ÈCêUÑßò¿Á¿îCÿÓ%°Õn´÷ŠX±½@›*¼SQ­±Ž }Äšžm¤kÜÙX®EÙÉÑvøÐÐ?àáÒÿñë)ÿï÷fÏm¥Œ³-·„Åfwm\§]ê"ÍnÎôÌÆµQ3=s¬óà»Ê«Ä_ªå¼=5S:i;óðŽˆ–«Ã¿Úi…ë&;“Xx‘Å2zú'Ô¬6ª&Æ“TóSJÅFí;—ÑG+—Ñ^_”°z#UZ«éò¯Äh3œmÝ£Ï-f8¯1¢ÍïEVâžÕy3MƱÇ]tž}ŒÌ-ªp8J¬^ÒÄÕ3¦•kÑu™ççPÝVÖ]UÕ;­ºÏ­W›¶’^Ù(éíL`Ý«+`s£í]¶èœïM·r"¦ë¿C8_f”A¤VÚM¹>ºÏJ™§o-K«e—·nÉË'VôîåååUnÊW.58„ÑFÀ)0ü2åAwm|uM«Š™íemG#ö‘íMÕÛ¢lÝÓmÕvÙ7Ø|›¶[Å.#˜ßj›+m· êX)ÍTk¤‰’v®jøÿ .Þ-%»afs=ˆ§s8/\igHŠjÖtÞÓv™×ŒÌkÕ<õÕ­Ë*ø>m6¢¸»½kç1Ã]5Öc³Ð¸ çÄÔ‡Ìï­ÅðûîJõÙ¶›mUr®è"‰Ïï^ŸkãÐÞ¸Æ]Špƒ¦ôFÖÉWošæåEEW%UL³µUQuä•©íDDO»ñ}y¨¶h-þÛoIqÈ$¥²ÐÅ¢:ig™V'ËIòü]åïÀñjlÇpš%ÞŸµRZá^Y-½ÈÔîbw"|‰Ü}5à36²ÌV6~}qOšŠuö×(×^Þ¿n×TkéŸè΀â‰=´^ຫ¬ú#W*5øÞ]=ÞßöI=ϸ'o {_²+U]í‘;‘Z‡BJMÅ%ég8¦Ã }ÊÔËl˜uÑ]R‰Ù×Bô’’Tc¶êîd¢ªlŽôQÊœð_ Dç;5‰µDk]¿O}gþ:Ƿȱ?ÇÑTòžçþº70ñsª> ‚õEX.YÊVÇIj£š¶¡îUDlq1^å]‘W¢5|Ïy<1š‹7 –œžã ¢¹çW;ŽU^Ž‘]%DîlnÛdÝ¡TTDEEéÓe n*ëîw,*ϤxÔ±¶û©÷Ú<^šG7²Žiµ•Q½Uˆœ­w‚$z÷Ç-v5iÄlÞok±ÐÓÛh¡ß~ΞÛmßÇfµúkÀ†Q8|ºþg\q»TSFŽsçªf?Ò€ín'~ýxù±¬÷Ïô[&;Š$Íò {å´?ù¯Ú29›å@÷Ëhó_´#¦@,xEþ3Mdü!–~ÕiÔã–<"ÿ¦²~Ë?j´™€¯ü|{Ñ5ïo× 9…¡ÿÞ_}MþÔ:‰ÇeµÜ$êL19¨æÛ#™y—§,u1=Í]¾3—Zö»cZ»«*æk¾%è¿ìT!ÛqþJ=’ëþ¦#iªýÕ~ÚRä­€9×ï"?¿¢ý’1kÜÌ §ËéK_5>F=UÕþ´7;=æ¶4üèCü Õì¾:gôrêÇÞõ-3üÏÓy7ïvém|-é…4¼ÜÏÆé*S™œ«Ë+{TéìÙé²ø§_b;»á £¨zU„ê}Qåv”–XØæSÖB¼•ûø±ÿ/^W"·~ôR´^ðfᎲlŸ»­×t¼õ-HÕñ£S¹*aðéÓ´bôþSwD.)ü{#G5ȨæªnŠžÅ58ü¢Î2¯O‘v9UO óõ¥YÖã2z> r"ö~UªøÓ1ٯɞc†¼f%iX~ªAhËUù¼¶é¤ßŸ¯|OTNÑ6ë¶ÜÉìÛªÊE|Õ¾í Òdúk,v;Ë^³º•YM3Óª+6þû§zz;ø'y­i·9V |ú^ë­%LO§TÝ£Už]•½ª'ðŒÙwG·uîõ·Ý0íf—ðÆ45áÇÉžþ©õy›ŒVËà³Û5cöb©«HÖ«~2£ùôúùq™àµü©*ék飬¡©Š¢žf£ã–'£Øö¯r£“¢§È~¤Š'^0çÓLé<ÀPPnú;©y·ÖýIÉñ:˜p¬fÞÕµW½Ì|SvP/#}*±Þs;Þr"ìÅ]‰Ã‰œé™ Ù®!µMEªJš6mÕÕ0m4(žÍßSäU$áÞ_òujæ|;ÒXj§WÖb5Óڟ̾’ª“B¿"6Ub}̸.¢‚õÅ®»å7Ç$—º],õUs#’¾T“—~äoc~$]»‹G¥sEVy–\kç–ÇK}¹«QÔÑÊÈŽžEßdXçzn½W•7DêVm/â‹"N#oÜDêæ y¾Al·>Ê­Ç©ûj{.îDj5Îr³•ZÊŽù™d{‘v.þC,|7pPÈdd58Ž$ÚXž‹²:½bHÚïúÕEÿ¬GþM¼èc‡´Ég‡–£,ºÔW#œ›;°‰RÛòsE#“ý0%º}]ÓMкDfW&1‹äu,»\•´o¤tu7>îw+\’ôEæÛtN¾&3…·èN•&-kÎÙ—S\«å»Çq†6²Í•‘µ­…÷§&Ñ£·æ]Üç/‰yKr)`À°½!Ç`kk2»ÚÎÚhZçd(Flšjˆ×ãV/ÆLå{g¼&]"Ç«_IQãÔö+\ð»–FNö²š9X½üÍWv›÷ú* N` ÚęΖZdÓ­+¶å,·ùÄUyCTÖºäô™ÊÖÄ‹4 è5[ª+÷V.îEÝZÐ^1.Ù¾¤?Cõ›O&³¶µëmW­=SÙÈæ£]»£Uí^gµÈ‹³·V¢…Ÿþ1ìz*±ír"ª.Ë¿Tï@? 6ÿ’ãØ­wšùCj¥–¢*VMY;ac¦‘ÈØØŠåDW9WdC$iú¹¥Øæ²iõßO2ˆÿ¹.ò²v±%,ÉÖ9™¿Û5Û/Æ›¢ôUpi 2jü8Lö-j¡jÞìw‹m5Ù’Æä½ÑF»CZ¬jªÆç¦è­z#—•öÛ$–%ÆÇ½KS?Éúl*·÷º?µ¿¤…©ãcÞ¥©Ÿ€äý6[€{ÝáZßÒC‘øiÿ-ÓûÚ}•$»+ùtýöÂÄOPIMS &†f,rG#QÍ{U6Vª/EEN›÷S¸Ñ|þe¸Ùh¥Ä+ÕwZÆÓ=vTjºS‘6]—Ðä߯·t° ù—*ÎóŽïŽË¯Un®Éá=ñÊ|ñ)î# cNåúb¨íPÏ©£‹­ ªßEówÝí¿ñ…Š’®8Ú"l¼ôµ.Xœ½Wm•Ûíà»!ûÁƯk*Rjþ‘2xÚÆ¢I-$öÉ^ääÝVEGÆ»£“£X›+ÓÃf—°ñ<TÄè*ad±»nf=¨æ¯]ú¢“O¾ ¬Ëü/µˆžšâ&ÝÉ犯²!«û‹UÈïUGgʧÑ*µŒyD4†êøàÉ1ì†Æ÷¢sËÙGSÅ7c‘ëáÜÏowŒ¡ñ[ÃÖHŒóR´S9ÈŠ­¸+è¹w]¶U­Nÿãîê}ù/ Ú–5Ró¥–gm¼”tÞg"슉»àärô_o‚{hÆùäûÐ{£œûlÙ%vô[KplŒEÙzªMÕzõ^©ÝÓb“^ÀæfœF®É¦º}zÔiœÙ颸óÄû–Í—ây¹¸öQhº+W•ÉG[û.Û켎_¦X¥w&µªY^û­UÓGé+"¬´6gwtE{%gǺòø÷të‰oúýŽ#¢Âµ²Ž‘9X‰][Eºn‰²¤hýº#}½Èž”ø±²˜ž8\æ#²»5ǯ]û¡˜ÑøÌ.½ÕDú—¨Yü>qÝjçó=dª­æ/L®­û¢oé'lÔÙ?¡z§OcèOÊ=nƒj[ÕUW3÷Vû¥m{“§~ò¯wNíü{»Ê|CÁ\üFo†Ÿ¥\Óí‰>ì]§åá®y£UéWùJíLHö¬zHªäôlµ Þ>’§ÉòügŸv<¥?úšïÈlß0¯Þ檸Ӛ`æ?}ÿê§ÝÈŽx{¿Sú¯`(³&ò–\â’¥S›s*ÇdÝþ ¨Õðð_—¼þ&+å ¹1cª»VR£ŸúJØÅwŒNUüKñûÞQGãs\$w^×þ°¯Ý¹Ÿ“‡»õªõ‹O¡|{^erVê½U"t32i¡jª&Û"BŸùmÓÚÁ÷÷HüÃ\ifsûÕn•õŠþ»¦ý£Y⪾=~^‰y=®8œæÌ}ª¿f‡Ý\U_# WŸH]‹¶IŽØv÷rÿn·nÅ‘<îª8wjw»ÒTèžÓ@½q?Ãõ‡´óíX°KÙ1ï2¨ZÍÑ}‚?™~$ÝJñhòkP³gßµjywБíßöî•Ûø}ªx§Æo¶?'Ɔ[«t¬ÉnïEÝÉ=s"bõN›DƪtM»üWâÙ÷#aðŸÌnÞýÝ­ÏãÔøNmwäX¦Ÿ¥V¾Çá’ùBô^Òœ˜ý§!¾J«ë2™”ñ"oÞ®‘Èï=—b6¯ãŸ[u¡mz9¤mòH‘µí‚k¤é·¥öcº"ªî×l›õéÌZ c†½Ä7Y4²ÃÚB¨è嬃Ïdc‘ÜÈä|ê÷"¢÷.û¦ÈÈ„‹KIKCO%4TðDœ±ÅŒb{¢£>Øü¶uÀeµ^ª9Uzç¶Šu¦{”øgñ×â˜ê¦>Ùâ¢k¡Üj뼊šŸ—ËÚeGȰUÕ²8ÜŠÎ^T¥¥è½:}qÑ^½UËÍ-i·:A†ÈÚì²z̾±nZÄH)y6UHXª«ºª¯¤÷mèíÕ7[. ,„\ëkà¸I§ kó,ÓG¦<¯DÇríœ n¯r&å]uN¿ÓÔùmV›]Šß¢Ém¥·ÐÒ³³‚––ÅMþKXÔDj|H„5Æ·½—2ÿ³¿hSyq­ïeÌ¿ìïÚÆŸdꪽ¢ÀÕTë3~×ÿô¥•™DFôGæUì”­äÑ÷¢bÿ\ÿ\”´…[òhûÑ1¿®®JZCî‡" ·ÄçÙ û7ëN-!Vøœû1áŸq¦ýiÀ[ðËýG|Šz<¿ÔwÈ zøWÐÒ](j-— vÏKWàž'ú²FäV¹«ñ**¡ÏN[rƱL“G¯²T:妹-Ãwn×s>²«á‘Sek‘ÎåÛíZݽný(¦¤Ù"ÒÞ:®}„…¯WñxnlV£#c®´ èåb7›w/`«•utª»/¤ãœøUÊ~êlÍê©jµ¥ÈÿO ¿ã57›;‰ø>>˜žUy>ž^½(øéÓÀöÍA‘Y.ýÖ.ÒŠçK-K?•ŒV9?¡T0>t‡OsNmj½åUu¶j†ÕSÃ[ULøVFïÊ®F@×.˲¦ÎN¨…ˆß/ϳ,ªÍÌ6 õTQs…Q§„Ç4ËöÆ"ºk»LLÓ˱¡k6‹âzç‹SâY}MÆš––µ•ñMo–8ælcÙ¶ïcÓelŽÝ6ö{ ˆpË§Ú ]u¹b÷ªÚ›´QA,—9á‘cc˳;8™·2ªo¾þ«vÛ®òÐóìÊÖ_VWEê¢Å\fމãíˆ*Áتôb&˜ßŽž—Ã|±Y²kMU‡!µÓ\mÕ¬ìê)jcI#‘½û+W§z"§±Q­—ÿ'–ŠÝ+d«´^rk;$z»Í¡ªŠXXžÆö‘«ÿ¥êZ\Ê65Èw¾æßªÜUÎ"xOlÄð×·GœN ŒÓÇÑh„ôw„m,Ñl¹e†kÕÆñU7 ¦ªD×·•ÈÖFÖ5wMýdrõè~šÑ†ë®SK—e׬ޒ²’–æ2ÝSq,l’IU$…ëͼ®ë¾Û"töÍ»ñ«:œÝ9ÄÕãôÝÞ׎QÕó÷; â~âãsžªyÆ^hv™áš9‚TË º¾Öûdõµ,d³IGKP¤[òòó=»ÕžlŠiš/Á>™êZókÞ«TË5Ê™•Ãlt Ž‰ê›ºüʯjôw«²¢ôñ-Ʋh–®8ìXþeM;]I"ÍE[JôeE+Õ6r±ÊŠ›97j¢¢ìž(Š•ž&¥½Õ|ôÚÁPÊ]ÿƒ}®“oôÒtOþDé›7µ¹]¬†œcjÁbwêªåqkÆxÝff8ÄLÇ ˆèÓN˜–‡–â*ÆMßméLonîòVMnÁ±]'ÔÆX4Ë>vG$pÔ6¶Íí)jùÝõ¤’%ÙÏo+ÌݶWm²+Tèn«ð׊kí7Y¨×KåÂÍD±¹-uÆ×I*1dæí"~û96ÛÄ×´‹‚]*ÒÛÕ.QYQ]’Þ(dI©e®ådHž«Û z+“½Êí•SeDRší³ÛøÆ^Áýǽ]W0ñTM鈦ª¦¨ˆ#N¤tÇO.Íü¯&›TÝøU1×1äÄë§k[ÓŒ ϦU¯°TÖOo´Fø ’±í|ÎG=Ï^ekZÕ]ܽÍN›5Wº[W©ïÕ‰oÙR]ß{KúÀÚª6óŽß¶ååì9¹9ºm;Þ>$ú{…Ú Ïzö#zªk»®üÇ:µg^ùn®`°÷i¦Šè‰ŠyvhÃf8~;ŸcUø†Yme}ªåeQ•[º"£‘QQQZär"¢¢îŠˆ¥kw“›HVµen_–¶•W~Ç·¦W'^î~Ç»ñ´r§Î2*µ—b*·M\f"xkפëǶ8¼ârü62b«ôES f/Ž[q jÕŠYÒD ³ÑÃCL’?™ý”LF7™|WdN¦LIråwk›•γ3¬Ï\Ë.šb˜Šc”xÔ.tk?Èkò•ªÈ,÷ Lµ•kEX×G,ò½^÷«fcÕ7rªìÕDMú&ŇË*ÎóŽìÞ˯Un©á:O8íŽSçXÄá,béÝ¿LUª½ù<ôVÕYeâñ“^[·u4ÕQC‰ìwg?ú…‘Çñû&+f¤Ç±Ë]=ºÛCgOMNÄdq·}ú'ƪª«Þªª«ÔÈöo´y¶}¤f8Š®Dr‰žÛ5íÑã Ã`õñE:€HËDÙ•2êú%¤±Ï¦¥»Kš]QQÜŠŽ}:;í\×Ê×5QQzòø*—ü¥|Ù_¨Gjþ¸Ï ]n°y¾d—–7#$µ¾’n»£û%Eß«fT_W¥Ô>Ùð”ýÆÙÌ.cJ¦ú»ëò¸÷kærŒëð¬uÊã”N‘æáý@2jÀâËC›Ä‡ßpj5H¯ÔèÛ¶;UÏÈê{¥:+ TÚsîèœïµl®TêˆL ¤ÄLi"‘èÖ¡Á©ÚyjÉÒ:ˆ«»4¤ºAQ Å%=|H¨È­otˆî¨ˆŸw&ìEÚ§‡ÃÂÿn¿ÐÓQÚôÃXŒw/g ¼Ž69yvïk&cÛ÷,’¯ªŒMåâ­¾ÙŠ¶W9¹†¦?_•DþÌôwÓ<=ÒêÙ6aŽ.OÊŽßýy€Ú€OYýÿ°Ûð:UŸPsº¶YqÚX܉#d‘È×Ô*¯F66»~wtjª*ôEÛc”åxŒëk…k¹1Ù×3ÙÆz¢18Š0¶ª½s”F­ƒ†¼fÛ­üNd:Ø÷yÞ;¥”ÿBÖoÏ×yQ_YPÅõwŽ9E]ù˜ï.á èFcú¥8ö˜c±EÙYéÚª†1µ•nMæÞ*¯z¹z÷&É܈oÇÜù.Ug#Ëì娓n˜Žþ¹žÙf{܈«z«õóªuÍŽÍò {å´?ù¯Ú29›å@÷Ëhó_´#¦@,xEþ3Mdü!–~ÕiÔã–<"ÿ¦²~Ë?j´™€×u¤Ô=?Ép:åjA‘Zjíos“£h7ʜۢ§TT8•£O¸b÷Ì‹MòJYh.ÖÚ¹5$½DNX§ÎkšÔÙ=‹ì;®sSÊGà óÊÛÅF˜ÑË$RÈÅÉ©¡5™ŒkXNøžÖòËݳ¶rïÚ9[«ÎrèÍpUáuÒg”öÇþ½‰6Çí [/œÙÌôÖšgJ£®™*óé:ÇlB-«‚j §6¡GDöÁp‰©ç®^¨¿Êoò›þÏj8V+ {vl_§v¨ç¸rÜÏ œahÆà«ŠíÕÄÇ÷Âc¦'ŒO †pDº£KsÏsÌcKqÈ%ª¸\*¢…‘DœÎtó½vÝtN½vèîôMͧ?Ô{NG$ •³ÝdgÖ)š»«wî{ÿ’ÔïÛ½|)õ-³ùÝWl˜åD*×=$o+«Ýºw9®{cDM¶Urtä'û’]®üf7£Jiù:ôÌð׺#§¯¹Á|2mžÖ v{ TUv¹¤üšbuÝŸÚ™ˆáÑÇœ:Šc–ì?³âVx[’‚žÝKQQ¬†Û7U]‘­Nõ_”Ê€uÌ€¤ê†‘b¯kmCJ±ÕÀ‹æµð"$ð*¢ôß홺î­^‹ñ.ÊnÀµzͼEjí:Ó=ÉÁãq}úq8ZæŠéå1Âcûõ©£"Õ~ïÉbȨ=ÕÅ+&WGʪ°Ê‹Þøÿ5'N±»¿¯N¨òØaÙ®7žØàÈ1{œu”“']º>'x±íïk“Ø¿*nŠŠ}Y5aËmRØòKU=†}¹á™»¦éܨ½íTðTÙP¨ùvð¯—Ç™áU“×ã’£$l›ò+w] ¨Dé¾Ê¼²lwÛeÝ91ˆÙéÖ5¯ ÿ*=ôÿ}ýš°#v¨¦Îc§ åEîÉüÚûz{ySr§éž©bÚ§aeë©å•¾U®NÞ™þÇ"w¢ø9:/˺&àI,Þ·~ˆ¹ju¦yKœâð—ð7ªÃbhšk¦t˜žp Œpó$qÍ¢•{Š×5ɺ9½_¤Z‡”iµ}Sœé#´L«9º¤h×1ñ·µG«S¢""&Æ•qò|^¨õ‡Í)óšì®ßEp†¿'®¿×+ëj ˆö¶6r.ñª1¨éïIz쉵áVÏ(U¾ýqáŠøË$µÁ[EQplMW+iY*+ž¨ž fª¾Š«Ñ7>Þ5ËF²­+Áô÷ʨ!È-ÖJz)ì³?³ªóˆaNÝZ×"vˆª×¿™»¦ËºíÕÂI%c¢•{Š×5ɺ*/z*N;¡úAˆåK›bºqa³ÞÜÇÆµt4mܯõöFlÔßÅvÜ ›¨?þ9ü£ø¶(›ÍkÓºHjª:±²ÂÅ«æùViiã_ô~#'å/Èkî–=?Ñ›ö— ®÷ç’;nnÍšï‰ÒTîŸ`0°:ÕܳY­½]ï/l­«el±É¤É+Ò˜×5ªæ16r»dj")ê/z‰¨eašµu‚ß. ‹ÒÅØòÕo4sBÙebº%DêµoVïè±vÛd „bV¬ ²áV8ù(,tP@›uVÆÄo2û\»n«âªªS,ýìÔ)ž!k³F¨¸}®ÜevÙc†z­Ü©ß¿œEü»šYb‚'Ï4dqµ^÷9vFµuU_aFx†]NÖí^âµs+êßCo|‰ÝDË2±=œ‘ÅNßnÎù@Éq™’纮ø Ø~ISb·dGp»TÓH¬|¬t’îŽÙQ\Øâ§‘èÍÑç&ýÈ©ñj×v]Ó[¾©hN§f8åÿ¡u|Î’âtQ§4fÆlåj.ÉÕŠ©Ê­ëºbøL“\ø¹´ao†ÏŸiÍœÕdµ•½Œ=’+$lkfåscuB&û;™fz+U©Ìlºƒƒq÷­¸»ô£2¢À1ûk¢eÎñCPþÒ®&¹[Ê{¶ÝÊÖ±œÛmº"ªŸàË1â·Q,–ë>Ëq{æ uޱù)–;´O…òDÖýn8ãë${«—Ÿvûz[3QÒM6³é›Ø4ÞÅ+¥¤±Ò¤=³›Êéås•òÊ©ºì¯‘Ï~ÛôæØó«6l×!ÁkìØÍ–ëÅK¢Hê–¥ô#\õkØŠ¨ªˆ©ò*–ïW6­Õ\F³®‘Î{KâqY®¸¢*˜‰ªyS<ç²9·T„ÊxÅÓ·"\ìµwÚXšFÊæª"&ꯃëž)º«¼}ªd¬œjÔRL´YÆ$3Fª’:Šekš½zvR¦éö©ë{W؆’£ÂS;¸ˆªÜþÕ3ÍSKžójé›™}vñõÛ®'Õ:}«J“âŸF¯èÆËOi™êˆ‘\iÛ®Ý^ÞhÓ¿Åßq$Xòls&¦JÌvýo¹Â»út•,•m·EåUÙStÝ»skc†Å~&äUÝ0‹c²\Ç,ŸüËÑÛU3éÓIdÀSXî ¨xf¥ZªoX=ú­töÚ—ÆÇ±ÐÕB»IØôG5ɺ/TêŽk“tTU؈J×£™q & i·f˜–q Só\õjÈ©î­|Uð3¯<’/;Ý‘w*¯¤œ¡6€„¸Ø÷©jgà9?M…Và#Þ÷GøV·ôµØX°òƒ£!Æ·½—2ÿ³¿hSyq­ïeÌ¿ìïÚÄ‹dÌ8ßZþ:X9ŸäW¾…^ÉJÞMz&/÷õÏõÉKHU¿&½ûúçú䥤>ér «|N}˜ðϸÓ~´âÒo‰Ï³÷oÖœ¿<¿Ôwȧ£ËýG|Š ªùD°ÊÊ!µkF;G™“Þ©ïð=ïF=ô.sc«ª¨©ÊôXžäïT‡¦ë³VÕúÇhÉìwjÿAu®íI5 m,©»'§•ŠÉ#wÄæ¹Q~RÝë4b-ÕjìkMQ11×Âaêš¦Š¢ªy­X¯49’ß[$磹ÒÅYNíÑy¢‘ˆö®íUEèäîUOŒûˆg‡–ÔéýveÃ}úã%EßLî復tɳ§´Î­$©»«è¹w訛±QU®i3 íOs Íoå×õÕ1´ó¦|ôÌK¯`qTãpô_§¦=}>°i`¥kN¡3K4»"Î~´³ÛhÜ´Œ•vkê^¨Èš¾ßMÍÝ=››©_mTZíÄÖ ²P-}‹™sl³n¬c ÉGO'‚¤’ÈÎv/{dj§q+ج†v<±˜Öw«úñ«Ó˾a®Íq‘ÂWw^<£¾y{Ö_ƒ—D8vÄð»ŠDëÄÔîºÞ%fʲVU9ez9Éë«æEÍâ‘!5}Àä  #Zt×=4¾i–cJÙ(oÎŽ9ù9¤£¨D^ʦ>ïN7ìäë²ì­]Úª‹L´o0ɱÛý燭_«Š<ï ™ÔôÒ¹ªÄ½ÚšÔózè÷UG«›ÕÈ‹ºtWlîdN‚_|5ÑëÖ+OwÆëcÔlQ]_Šß#FµÑÔ5Ršglª´ò;drl¼«³¶r#˜è†Úl–kòéÂ\Û”ñ¢¯ÍžßÙžS~q žU™W–_ñ”ñ¦yÇ\{㡦‚6Ò=\LÕ*ðÜÊÜüsPñÇy®AÕz3E3çbð’'¢#ÑÌÝÞªŠ×:I>2ÌòÌVOН¢h¹Dé1>Øë‰ç&8éX¿on.Úi`/ òùhÆ­wûýÆ uNž¦¦wò²6'zªÿøo܇ª(ªåQE¬Ïˆç2¤ÌSËâÍsLsOq{†a•Üc¢¶[bYe‘Ê›¹~ÕŒO¶{—fµ©ÕUQ߃­ºe—é¸¸Õ ÊkîANúlFÑT©Ëf²;ø7òÿë¦j«•|õþZ¢hš'¥÷þ/3{n¯j®®Ý£¸åKj±‹Rr;#­þmLjž•:l¼¬wGwujÈŽ¾§Õþ vvk÷GOþMÈåù”ÏGÒŸÕ˯^sŸç?¯ÄYŸÁÇ®zûº½ ëHØs7Êï–Ðÿæ¿hFtÈæo•ß-¡ÿÍ~ÐŒ™±áøÍ5“ð†YûU§SŽXð‹üfšÉøC,ýªÐ:f~U4ÔÕ´ÒÑÖSÅ=<ìtRÅ+Ì‘ŽMœ×5z***¢¢Ÿ¨žœJù0[qºÏŸpÍr‚Ë^çÉQ6?Q:Ãhª«ýÇ2Þ¨‘»ÐO1b©ä¸·zBù)5 HïRCLŽGÕ:Þéáåj7uóšetNDG'¥ºõUÝUPí¸0±™vbmÅZuÇ4ónr¡Ír¦¼¶ýVõç<'¾9OžŸ_nôR­5vÈgb';$Ìr*¦þª·tïÜüþ¨zÏñZÊ׿é«â¦Oú]^ô£ï§µß®OÔ·üŽ }PõŸâ´?•¯ÍT=gø­åkóNôñS'ý®¯y÷ÔÚï×'ê[þG¾¨zÏñZÊ׿ª³üV‡òµù§z@ø©“þ‡×W¼ûêmwë“õ-ÿ#‚ßT=gø­åkóGÕYþ+CùZüÓ½ |TÉÿCë«Þ}õ6»õÉú–ÿ‘Áoª³üV‡òµù£ê‡¬ÿ¡ü­~iÞ>*dÿ¡õÕï>ú›]úäýKÈà·ÕYþ+CùZüÑõCÖŠÐþV¿4ïH2Ðúê÷Ÿ}M®ýr~¥¿äp[ꇬÿ¡ü­~hú¡ë?Åh+_šw¤Š™?è}u{Ͼ¦×~¹?Rßò8-õCÖŠÐþV¿4}PõŸâ´?•¯Í;ÒÅLŸô>º½çßSk¿\Ÿ©oùú¡ë?Åh+_š>¨zÏñZÊ׿éâ¦Oú]^ó冀߮OÔ·üŽ }PõŸâ´?•¯ÍT=gø­åkóNôñS'ý®¯y÷ÔÚï×'ê[þG¾¨zÏñZÊ׿ª³üV‡òµù§z@ø©“þ‡×W¼ûêmwë“õ-ÿ#‚ßT=gø­åkóGÕYþ+CùZüÓ½ |TÉÿCë«Þ}õ6»õÉú–ÿ‘Áoª³üV‡òµù£ê‡¬ÿ¡ü­~iÞ>*dÿ¡õÕï>ú›]úäýKÈà·ÕYþ+CùZüÑõCÖŠÐþV¿4ïH2Ðúê÷Ÿ}M®ýr~¥¿äp[ꇬÿ¡ü­~hú¡ë?Åh+_šw¤„-Ú~“Œ®>óSîx[+Y@äEÏ|â?®5vÝ>´ç"õD_fû©Ù¢­t³;j÷¶9„-³ÌbôÚÆþ.‰®u¢ß*f"~g>.BýPõŸâ´?•¯ÍT=gø­åkóNôƒÏÅLŸô>º½íwßSk¿\Ÿ©oùú¡ë?Åh+_š>¨zÏñZÊ׿éâ¦Oú]^ó冀߮OÔ·üŽ }PõŸâ´?•¯ÍT=gø­åkóNôñS'ý®¯y÷ÔÚï×'ê[þG¾¨zÏñZÊ׿ª³üV‡òµù§z@ø©“þ‡×W¼ûêmwë“õ-ÿ#‚ßT=gø­åkóGÕYþ+CùZüÓ½ |TÉÿCë«Þ}õ6»õÉú–ÿ‘Áoª³üV‡òµù£ê‡¬ÿ¡ü­~iÞ>*dÿ¡õÕï>ú›]úäýKÈà·ÕYþ+CùZüÑõCÖŠÐþV¿4ïH2Ðúê÷Ÿ}M®ýr~¥¿äp[ꇬÿ¡ü­~hú¡ë?Åh+_šw¤Š™?è}u{Ͼ¦×~¹?Rßò8-õCÖŠÐþV¿4}PõŸâ´?•¯Í;ÒÅLŸô>º½çßSk¿\Ÿ©oùú¡ë?Åh+_š>¨zÏñZÊ׿éâ¦Oú]^ó冀߮OÔ·üŽ }PõŸâ´?•¯ÍT=gø­åkóNôñS'ý®¯y÷ÔÚï×'ê[þG¾¨zÏñZÊ׿ª³üV‡òµù§z@ø©“þ‡×W¼ûêmwë“õ-ÿ#‚ßT=gø­åkóGÕYþ+CùZüÓ½ |TÉÿCë«Þ}õ6»õÉú–ÿ‘Áoª³üV‡òµù£ê‡¬ÿ¡ü­~iÞ>*dÿ¡õÕï>ú›]úäýKÈàÌ:ûy­‘)­øƒ%þ£3äUÛªú(Ý×¢)¸c¸OZÁ$”˜‘ß …$H–¡(]I]ÑyV¢¥[.Ê›¦éÑS~ó¶À½gfò«oÑb5íÖ}³,Lg„m©Ç[›W±µi?›»O®˜‰Pžü™tx•ö Dâ2ëmËn¨Õ’<}#Zš(åTMŸS$¿ñ—"nŸ'"*oÍ"l_H¢Š™ 1¶8ãj5ŒjlÖµ:""'r»ˆŠcHBꪪꚪf@Wùîúµ öË$UT•Qº)¡•ˆæHÅM•ª‹ÞŠ‡Ð LDÆ’­5MS:L*«hþS¡yÓWI*ê#µÅ'4ôìÝËFÕTUcÓ®@ªž=Ý7îGÖë%‡W,>wH¬¥»Òµ¾]»¢wòÙü¨Õ{—ùz›üÑEQàž&IV=j+\ÕM•½ “«úA‘è–FÍZÒY%†Û ¥E.©ÿTkìVËx¥CÜ— ºPȪˆçQÍKãô¹ñuü~2 “‰­½µˆÜ½”2¿—x«©ä…Zª›ì®VòtꊼÛtù7Ûozi§™%ó ²ÖJîùd¢´îÛ×DæîDñðObë… »±éMc¬µÈôDí(«dÝ>4lŠöÿ«Ãå+;±ònQr;biŸWq;Žüe‹Ö&2¨®˜úÜtIvL»ÉXÇr[]͹*ã•S}ûѪªËßì_a–+ã‚;Rʳc9ým'+‘Ѷ²‘³9:ÿ-Žg^î¼¾ч^ø—Å#{q]IíéÚÞXá§¼TDªÔîNG¢1«Õvô½½zºyŸÇáf{iª'ÕÍO‹{=Œp9¥1ÙrŠ©Óý\½¶€©‰~ãK•V¶ÕSu‰%DåóJj¦»¢øÃé£UÚ›/±Tò¼Yjþ4äfm¦tÑ#QQyéjhž»l›ªÈ®Nþþž;tðÖÿEt}*gìÔûÝfWÿ!½fÿйíÑmA[-œnâr±ó„Ý©]ºn”³ÅP›xõwgÿëø¦ÙÅæ×òùÕmÖݾÛùÍËÝßÙ+ý¾Åø·Ê·Ÿe·~MèóðöèÖâ6hð¿/ \ýŠ¿†e5=·q£7=üÛPmŒÙ¨ïîŽz~‹÷F·¯ÅÞmVìË»ïîNUg­Ù¨õózè¤Ù«Ü¾‹—¡o‡½ø»‘=ÓÑâ2œ~ò‹Ñô©ª=°ÄÝu_²jEŸJ.·gSdwêkíðIÛñÆí•­•S‘dèõäEW"1UQ7o6ÜE¼Bi õŽ,zêû^U`¨mïºC"1iî±Ý’9û/Öžªˆí·ðvÊ­D$,vÝ6?l§É«ië/QÂË…M<}œST£%{¾«UüÊ‰àŠˆd5쀃Ês|K †š£,È(íqÖKØÀµÛÞ;'~ɺn½Éºn¨gŒ|&« Àèrª»I1º‡:v¦û¥<Ü­{‘zìæÅ¿Ní×tD]ðs,EÜ&»öiÖªc]=¾­e»ÙÌ¿ šæ¶pXÊæŠ.N“1¦ºÌNï>jÒ<éê’®–¾š:ʘª)æj>9bz=j÷*9:*|‡ês—Lõ—8ÒºÇIŽ×¤´R®óÛêw}<Ÿ.è­wùÍT_néй:QÄ.ªLŽ‚9’Ñ|rzVÚ©S™ë×øôIz&û"#¶ÝU¨MfU´x\ËKuyõOOtô÷sIv§ÁÞg³šß·6Ä|èŽ1ô©ã1ßÇ\Ç&z–¦~“ôØUn=ït…kI SÆÇ½KS?Éúl*·÷º?µ¿¤„ÃOùnŸÞÓ쩤Ù_˧è϶,| èÀ Î.õ£0Ñ Ó’a‘ÛßW[we ©[¥gf°ÊþˆŽnË»×iZ­ÜjqU[lú!¢À­µÖ´æU«ŽÁVúEvw×&Ý6]úôØœäžs|ÿNc…š"ÝS4Æõ[³¬trj1yÖzl\‰ÞŽ<#WBVøiãEÚÅ•C§Ùž5Kk½ÕÃ$”UT2=iê_Uïc~îyç"ó9eN‹¶öç¹?fñs‚ÌhݯMcŒLLO)‰ŽqÂ}OngoÆØcí™”ñ#«ŽñTìbßßíö„ª´µ(i«äŽ Ÿ*ôäEÛÒW.ý:î¥ü$ÙîÌÞÈp˜<]Úâ¨ÄÑ¿ð)'^Ÿ+¡ƒÇÑŒ¹vÝ1§‹'·Ÿ¸–xqÄV7Ãõ¶ÑWy´ÔÝjo3É´òµŽFFÔWȪïW1?ë|Fv]—b³lU<]ʹDtéÏ>¢efýûxksvìéLt¥|V;¤wË%¾÷N‰— XªšÇ.êÔ‘ˆäEøÓsí0뢫uMsŽ ±11¬Ê¡q­ïeÌ¿ìïÚÄÞBk{Ùs/û;ö…1"Ùó÷Ö¿Ž–gùï¡W²R·“GÞ‰‹ýýsýrRÒoÉ£ïDÅþþ¹þ¹)iº\ˆ*ߟf<3î4ß­8´…[âsìdž}Æ›õ§oÀ/õò)èòÿQß"è)㫟J³Ì;‹ì~•þil{1|æ8X«ÚÚj$D†¡Èë®Dö¹Î§oªÓm‚x* Ž¦šfM ÌI#’7#šöªnŽENŠŠw,vk‡Øu¼aEj­WÊ)hjâsZ»Ç#Uª©ÌŠˆäßv®Ë²¢/CôF¦ý§nSÂîsS4׌Y%šªiït,RmæÒ3f7~ÍŽ‰ŽïÙÎFïèª' ðѲӊÃÑŸa©ò­ù7;i™òjÿLΓÙ1Ñ ~Êæn¹Á×<*ãý1çû;S(ù©<a3Œ¾Ñ€b7|Îý/% ž•õRì»+ùSÑcÎs¶j'й ÷šYwÇ´Þå­YÕ7.e«I~¬æOJšwó:tߪ5#r½Á$kWÕ!Kþ7QÅ¿Ú8z£í× Ä–;þWvëí>aðœDaèŸ&Ž}ý>Ž^—°Ø‘€ħ XκÃM–Ø+þ„õ*ÇÉ%)¥ycV+• ¨j ¹ÜŠÕêœË¶è®c«®#¬7¬o"¦Ò!l¿Aº€ØÕbY•©o¼ÆŽV¶¢’t^EçV¯¡º.û¢uEDè ¢êþ‰i–»âÏÄ5?¥»ÑzN§‘ÉËQG"·nÖ SÒÿ.˶ʊ†×lV]¶x·ŠÛ”üšãåGgm=q>i‰âÙå¹­ü²½mñ¦yÄòŸtö¡0FyN–qÂ;'Y!¸kNžÓ9Z‰\¹¢Nˆ­MÒ®6¦û*";ÃÐj&Ù 3× 4Õ¨ô‘E%tH¾ql©N¶SÖGÂî½¢¹»·å§Øëeªª¬M½ëQÊå âd‘ÈÕcØö¢µÍTÙQQ{ÑPö§T=^Ó@ò¨µoJžú{:H‰S*¹”®{‘)öÐ=yQ:ô]“t^E,~™j^?ªXÄ9ý›ýJºG½JY|Xí»ÓÅâ›/N¨›-ÂßCv¡žÙs¤Šª’ª7E42±É©²µQ{ÑPÃa8#§v·Yñ È…L²ÚøÁª²Ñ^±|¢[ͶçO ]%Lw*Y[43’5gT]•ŸT>æß¸Ü£òOn¨¨NŠÊŸ"1W¿ã&´— Ñ|fí…\2¿vlqÞ*gÇ!z=ÒÛm¯Tì©_#—ÓåÙ{‘6UwUEDl¢SîSø¼MØÿ_ôWãäÜü~]†«·Åqöª{uG‹ûr¹*pê»6uÞÈçïÓ}Ó²TÝ~$þƒøœDq1BæC_¤¬UOI{[sæïþš"{7ÛÀ¶ ¯ÜlM?'_ŸISã†[_ãr«3Ý­* Þ+õz—µ÷CJ"NÏ¿jj¨ù6ß~m÷ÿËcòú±óÿƒJOûÓþâÚŸróŒdýX÷‘´û?ÅPú´2ªh;JÝ0‰9}i<îF7¿§|k·‡‰ñ\xÒ¨»[êmW3¢¨¤¬…ôóÄû‹¹díV¹«õ¾åET-á£k^rºy¦·œŽ ’:Ô‰)¨{·Z‰•ªˆ½ü»«þF)k‚Ì,ZªåxÏ&"fO(ó³2üë Çbíáìdñã+ª"4¿r8Ìé8úç‘cY±5Íb¹yZçs*'‚*웯Dz=ñ½²Fåkš¨­r.Ê‹í@÷¾GºI®s•UÎUÝU}ªKZMÃ~m©~mw©-üª×­lþ¼ñó*/bÍ•\½«¶oŽëÜsL6ö2犱LÕ=ŸßÒ9–iƒÉðó‰Ç\Š(Ž™ž}‘Ó3ÙZÎ{¯™­ë‡¬ïMrU[µ-F=RÚzÙ7óŠ~ÍéÎÿ·nÍVõô·Tê»l~ü{Þèÿ Öþ’·:G„igÚ¡MŠ[^Ùê,.mMeD¥Dû=»s;¢"|MF·ÇmÈ'€{ÝáZßÒAáG ŠÁìñuïUãióFí\5éþáóÜÏ,Ͷ†¼NUgÅÛÝžÍé×ZG uꎭgŒÌ,Xù‘¿Tÿ(ߨÿ¤qþ­9 hìÑ-¢Óøté×jš)*$e[®ŒnYesÓv$N^œÛwõÛ½ ¯Ê7ö#Çé«Nj¼3êW öƒÛìÚ¥[‹­Î9k®šºØ•39Ž™êÔTìܮݪ›'^‡Ð8JöÄc0Uâ©ñÓäQ5DÄù^W“ÇHå§.(f2nFq_Š»çr8Κtpâø(ÅžëúçÕ×[M ­/ª¹-½“5“TK+^ÞXaß›³b˺¯rlÔëºíò^ï6ýo ‚‚ï[Mã´®VCPö7~Þ£®È½ý F¦¥ºqkb¬Ó )©-Se/ž‚¨è­½£Üö¯Š"S󢢪ô誦ñ夞-l´Õ=Š‘TctüŽðUmEB*|©ÓúP™Wfgop×.Ï“^wh˜ˆš"'”ó׎³¯|r†®*Ó&¹M<â¾3×Ú¹ºçQ<<æ0O$s3¨sdc•Žì{ÑS®åsòoÝn—*@Kʪ©#e¯“·™ÏåÝj·ÛuéÜŸÐmÚéÄΓ]8n¸QØ2ú ûÆGiކ lsTDùÔ“µbu‘¼ûólЍˆ›î†‰äÖbI.£F®TGEknè»*oç]Ç5ÀeXœ¿`³IÆZš&nQ¦ôi<+·¦¼tׇ¥½½ˆ·{8ÃŪµòg”öTŽómEÕ®,µµø~© ³IU<6ê6Ô:hicE樟“×rµªî¼Û+¹[ßÖcÑn uKIõRÇM¨”óc”|ÕÑ[ªª)ä™ÈÅVDø¶å{ü»îåÝQP€8dË­ZÄ?g¨O[u=?žY+g‘‹µ,»ìŽr"*£y؈«àŽß¹¿´\EhÕÛ*´av ê‚ów½Jè©¡·9jœ¬Wª¾FîÆ&Í^õÝW¹;ößmÖ77È"œ›!ÃÇÀ¦Ç¦ÞôO ·ªš´á1u×ö§]XyE¬62gŒ¯ð»ý5iÕ¤ißÃÔ¤T§7nè›ÖÙSu]“ø( §ˆÞ!òÍyÍétWC¤«žØµiÏE"µ÷IÚ½]΋èÓ³evê».Êõ艶‰Æ}º{¿·{M+˜“V¥²ž5zìÔsé¢jn©áºŸ–M†jGº¹aÈéë"¹Á$),5QÆèéë£TD©¥z.ꊊ»oÕvXÞˆ‹Ñ%yv‰ÀeW«Ý¯F[ëáLÕQ33Û4êã1ËZu×ï^¢ö"˜Ö-MÏ.cœF³Ãûîï¸XÖ)AÂ6‚ßr«•l÷ëí5UÜ*f™îlõJ¨Èag2îØ‘ïFûWw9SuÙ*Ÿb™—»æA©ZßKb‚Ѫ:á3\×ÊíÕ¬‚›´¬cQ½U6DUM‘UWku®‹v½ð•È0Ë[} 7ábo+OôL_ïëŸë’–û¥È€­ñ9öcÃ>ãMúÓ‹HU¾'>ÌxgÜi¿ZpüòÿQß"ž/õò(€ ¿Çä×ìvϯbŠ™¦˜:[‹éÒgµ.¶tjÉWB­j/3œŒkš›oÑíOIÈ©hg‡µŠµU‹ÔïQTLLO)‰á0õEu[ª+¢t˜S=6Ô ¨aV¬ß¨cé®Tì‘ñ$ˆ÷SKÊœð?nç±Ê­_“~åCf"½eÃÛÁ9¶ºvi¦\§¨»ÂÊet8Ýíü›MÌž¤3®éËÜÞUDÙÄYN9+,OkØôG5Í]ÑQ{•ø»n¶JöÈæuaô™³^³n®ºz¦:žSæž—TÊ3*s,Dj»—w5ªˆˆÕUTE麢;cg²cÀtK{8[qfÅM1Ê""";¢84u×UÊ·«g´ž@™¾T|¶‡ÿ5ûB3¦G3|¨ùmþkö„`tÈå¿Æi¬Ÿ„2ÏÚ­:œrÇ„_ã4ÖOÂgíVÓ0<ç)¥Â0ËæaZ›Ãf·Ï\æì«ÍÙ±\‰²uꨉøÎrå:u’ã6 <½AØIz¦Ãj3-–'nŽeÃÏUˆ­TíÝS¹ZäÝ©Õ-ïÓ^ñ¼_F-²¹.~¥·¹­ÎVÐÃ#%©—¢¢¢3ëJïkUÉñ§Ãª6klüPiu’­ÎJÎ7~´>7Ùñ%2ªµW®è­UïþJw©—b¯õë>ˆÿë¬ì>6r5´ÖnÅë“tX·Vžjª›‘?E;ã×Ê žÁlÉmOsè®Ôp×S9Ȉ«¬G±WmþÕÉâd7„[¥}6žÜ´Âù#vÓ»Í]‚g-:ÅÚB׫¡‘:ª*9®TEN»5wÝéÈÆ®Ê¦—9βøÊó ØHi¦©ÒzéçLù队8<µ€kgze vv3ËÛYU3ê+]6ÒVÖªxGé³wè¯r£SÅwTE’JïUÁ˜_µºó¬ÙÕuÇ'÷BfTRYn2,´”ÒlœÜÊåU•ˆäô"]˜Ä^^W"&ÁLu×[u³^é,¹f¢ZïxNŠ]/1Pµh W±ìææt¯UåuKѨåjì‘îÅF§2.ýÑ Ò#ÃimúYk¥ó„Ô>çΓOrk›»e’o·EEÝ6bsz(ˆGmªvÛ>%ULèíóÊúŠI¤ìÑêö¢6Neè¼¼®M¶ßëŠM`ÅÆa-ã¬U‡»®ìõz[<Ÿ5ÄdxÚ1ø]7è×McX㻥é/ ˜žÊkÎd‘ßo±ª?—uZ:w£·jÆÕDWªl_ÓüÔ'`coÅáéÒ=½óÒ®oc³ÜDâq÷&ºº:£²#”GrãcÞ¥©Ÿ€äý6[€{ÝáZßÒBÔñ±ïRÔÏÀr~› ­ÀG½îð­oé!Ë|4ÿ–éýí>Ê›•üº~ŒûabÀÊŒu«DqMwÇ(±Œºáv¤¥¡­Jøßm–8äY7³eY#zrìõðEÝ©3ÉÓ¢-r9rlÙÈ‹ºµk©6_‹¥6å¥-Úìï'ÃÆ‰ª‹q¬éµžlùn_Œ½n&zѾ“ðó¥Z0²Ôá8÷%Âv,RÜj¤Yª\ÅTUb=z5»¢nDEÙ7ßcôÖ]Óýt´Ó[sZJ–Í@ç:ŽºŽTަŸ›ntjª9ª×r¦èæªtE詹"îægðèÌæý~>9W½;Ý\ú´á§-8r]ø%â7#s«N á…ð¢¥s®7%¼dRrHÆEsš%œÈ­æìÙyœˆ½Ê©¾Ë¶è†õ¡Ü8àúûËðë­ò±o‰N•éÏ œiËÉÙÄÍ·í]¾û÷'wŒª ì~Ö癥«–q˜ªë¢æ›Ñ3ÂwgXáÊ4ž<4Z³–á0õS]«qé=üЮ¯p¤ZÇxvIy¦¸Zo2¢$õ¶©™ª6DF¬­{×*"m̈ŽTè«Ñ6Åé?šY¤Ùe&mo¹ß®·[z¹Ô«[QEœÕj¹ª¼®Tô•Sâ'à(ÚìöÞ rêqUø7wuù¼´×žšpÓ]4áÈœ³ Uß6ã{]uíëB:Â6›j>¥®©ß/y,e––^Æ’¦ÓïXÖz.…ÎÙQ‰¿¥íÛc{Õ­$Ä5£“Ì ŸÍ–VTCQLæ²¢šV÷>79®DUEsWtTTr¡¹ƒ½ Í+«Tß«[oȈӗ¢#‡ˆ®"ˆòþWoz/Ñ>1}‚çEˆä¹%m ÑÍ’Z;DÂÉZ›vŒHâbµÊÝ‘zì¨Ý:&Ú.yÀ–ˆf—iïT1ݱ©êšHm3FÊewФOc‘¿#­ø‹ ‹;Wañ•æ±5Sv½7ª‰Ó{N[ÑÊt퇊²ì-v¢ÍVâiŽQÕÜ‚4‹ƒ}+Ñ쪗6´W_nwŠ‘)¥¯ªgg ¾7Fõk#cwcÜž—7M—©¸ëN‚`:íh¤¶fpÕÅ=½î}u­Ž¢m¹ÚŠæ¹ª×r·tV¯rm²õ$`[¿´Ù¾'FgwTߣ…5kÆ#êŽ3Ôë=r­ 5»3‡¦ˆÜžp€tƒƒ-7ÑìΓ<´ß² Ò²²*å…!oi£r«Y*¯+ÕÒÛâ'à \×9Çç—ã˜Ý›•Äi¬õF³§v³>•Ì6ÎbØæ c !5½ì¹—ýûB˜›ÈCo{.eÿg~Ц$[#þaÀ~ú×ñÒÁÌÿ"½ô*öJVòhûÑ1¿®®JZB­ù4}蘿ß×?×%-!÷K‘[âsìdž}Æ›õ§«|N}˜ðϸÓ~´à-øåþ£¾E=_ê;äP=Âf¸v;¨xãËmí®³_h¥ ­Ê©ÏV®ÎN­ro»\›+UQQQ¡xÝeÂÆwjáÓS¦u˺ºHð,¡³j¢jïæ5 ö“3™ž »Q:+vèy kމ`ü@iõfç”’>’g¶¦’®rT[ëŽHê`wÚÈÞg'±QÎj¢µÊ‹Ú}šÁíV_V´ÕÓM]GÛ1Á›—ãîå×âõ¿ÏȲ<&Îà(ËðTéE>™žš§®gúG‡,Æbîã¯Më³Æ}] Ã9›å@÷Ëhó_´#:ds7Êï–Ðÿæ¿hFL€Xð‹üfšÉøC,ýªÓ©Ç,xEþ3Mdü!–~Õh3‰x“Ô‹Þ „CcÂctù–aR–K Lß’È›>¡6îHÚ¼ÜÝÈåb¯MÏTÓ5Îì3rÜÜÓocåW:qås3ÑÌÏDDËZÓIn:¯ÄN]©ÕQÿó=‚²l>Â×·t}Z=«YPÅöú<œÉÞǵ<ýõí âKA®®†>U¨È(ß"¹¼Òѱ¬Mûת¹Q=½:nIšU§¶Ý,À,ø5±î•¶è>¿;•UÕr¾iUW¯¥#œí¼Q¢!q(ô ÏtJòä‰;<Úg5UßÝ äÙ6öíý<»—©ª*¹¤rÒcÔ˜àqÖ±ù÷‹ÃGàbÕÛTG/'Äܦ'¾©™®j©|™ítÚ-Ä…‹På{™ŠêdqcwÇ®É=Ê$þâ™Û"w·vnå]˜’ªìjÓµ{NéuOO.ødÓùµE\I-Z*£©+#T|"§¤œ²5ª»lªÞdñ5ε»3Å'ÅrÙ¶Íð©}ÆÉ!]ÕVxÜæGPŽTNvÌØùÑÉÑW›nˆ‡Š¼º"®˜áî÷58ØŒÛ*·Ž¢? b"ÝÎÚ?õW=ß‹™èÒˆçRT‘pÕÌ~ÿÄÖ=/½ZjaÃtæ’;­['R:¶9+Þ›ôse‘aƒ¿ÕêQP°œ@ñC¦|:Û!“,ªšºóXÅ}š‡•Õ37uNÑÛª$qîïÙyQÊŠ„¬Ûm½—.ì¡§mtвšJ”;WÄÇ9Íb»½ZŽ{Õ¹Ëí(ß šujâ [õˆS‰—Š«.@ú =º©ÑR9ŠªÇ9‹Ñ{8Ò6±¢/3•9‘%nã+ŠË½ s»w õ3áíglägœ­L°÷óÇ'/¤Ýºó$.Mº–[Bµ× ×ü&,ÃѾ7$7 |ʽ ûoÈôNô^ö¹:9=ŠŠ‰"”£‡Ùí6î?µzŧogÐÌÖ·OpŽŸþ.Ûƒ$¦í6Ù6G6yj[·†òmѺà4k¯â×ÝWÈ´r(ë)r r‚šå+*cF2ª •Q_¢¯;Y¼\Î舲µ½èäM䊵ƒGoÖ]‚j’Gdx}Õ5[Øç²²Õ&ËSI#­YêÆlŠäDôöTWn’¨—õ-Lü'é°ªÜ{Þèÿ Öþ’§z–¦~“ôØUn=ït…kIGá§ü·OïiöT’ì¯åÓôgÛ >Pt`„8Ö÷²æ_öwí bo!5½ì¹—ýûB˜‘lù‡ûë_ÇK3üŠ÷ЫÙ)[É£ïDÅþþ¹þ¹)i ·äÑ÷¢bÿ\ÿ\”´‡Ý.Do‰Ï³÷oÖœZB­ñ9öcÃ>ãMúÓ€·à—úŽùôy¨ï‘@ô;×-Óþ p×âÝа½j-—*göu–ʤM›Q‰Õ®EÙv]Ú푊…8¤Ëõ;@s "âZ&K ÂE§ÆóšvrÐÝÑälu+ÝG*7Ñ_o]÷G¿¡f­©šcƒk_€ê%‚ ½–âÔI`—v¹ŽN­’7·g1í^¨æª*IÚ}”Ëö³ 8\uEðTïEEEî2EiFÍÂ6u4Œ£©—G²Ú˜•^×¹ÍÅ®r¢îÕ^”Ò*µU|dïj$–N ં:ªY£š˜’G$nG5íTÝŠ:î+§wŒr•ìã+§U7ðÕoáîq¢¯m5iʺg…QÝ1äÌLûP¦YÆ­<,kÿXô/“5Ã37º¯ Æ©Ñ{zz”W;ž4j9ûs>G5Ìk‘ïk›²1ÅÍQŸˆn0ø†…pÐëÆI^ކ®÷\²µñÆ»#••2Çp®Ê»ò#äþB¢¡0hÖ—i‡UpÈ3Ü‘· ‹™=îñ>éÛÌÖ¯%=;6íÝü­DW¹\çl›ò·yâW^­<;éFq]Cî…tó¶‚×CÌ­JЧµÎDs‘•kç/ù»'UB²iŸ z£Åæ‡Zx°Èë=˨bTZ±˜°¯`íœÔV¢ÿsD©·¢ß®¹6W9ª›¨Mü9qZ¼Eæ=N®öì^Ñß{¨MÙQ&û>9vôc‘QÍsXÕrò£•Ê›¢ÇcØí‡³Rã¸Åž’×l¡"§¤¤‰#Š6û©ÓãUñ]ÕOíCaº\®kmꆮ¾Ò±¶¾–†>ZUz*±%j.ìW"*¢.Û¢4l›XqLGSq],¾Ãp§¹fPÕIj¬XZ”RI"¾H®EI6j5Qy𛢹¨»Éq £N|&MÓÜŒ§¬eïº"òù¥ÊU‰^äk•#WlŽÙmšäEV¢(ƒç·{¡î}/ºÞoçÝ‹<çÍù».ו9ù9ºòóo¶ývÛsèãcÞ¥©Ÿ€äý6[€{ÝáZßÒBÔñ±ïRÔÏÀr~› ­ÀG½îð­oé!Èü4ÿ–éýí>Ê’]•üº~ŒûabÀÊŒ‡Þö\ËþÎý¡LMä!Æ·½—2ÿ³¿hS-‘ÿ0à?}køé`æ‘^ú{%+y4}蘿ß×?×%-!Vüš>ôL_ïëŸë’–û¥È€­ñ9öcÃ>ãMúÓ‹HU¾'>ÌxgÜi¿ZpüòÿQß"ž/õò(€x–(§‰ðÍdŽF«^Ç&ísW¢¢¢÷¡Mõ;‚\O¯5Z“ÁõÚžÃY<šãƒÖ¿k-ÏmÑÝ–ëýÏ"§wTo‚,iÑnX1q˜,>cb¬6.ˆ®Š¸LLkýú—-]®ÅqrÜé1Ó …ëí’ç7Nu"Ï[€jNH§ÇïLX–YÊÔZiU• z§ ­]ÜZŠ›*ÊdÑ«ú¥:ï¿Ôü:†ïfæSÕ:4m]ªzðLžœk¿^‹²íÕ:/%Ð~*8sWϧˬØ6ý•¦¾FÃÐÓ§s*'-O+vNˆ®]¶lmC€m_z©™ÄìõZÇèêŸáª}•}iLòíª‰ÒÞ6?Õl{½ 0–q¦º‹Vû7¬Y$v56 Ü^g_ »ì¬ìßë®ý6jªûQ;‰4áXü·•^œ>6ÝV뎊¢b¬vǾÍûXŠ7íU€Â]!ü¯‰|V— L K¬—=LÍ%Ý#³cq¬íQvWOPÔs#cW£•9•ŸlN¦Ï*ɱùåøÃeÖª¹_TG.ÙžQ³1 |F*Î~¨¦;¾)€‡nZûS—e5:eÃÎ#Y¨9u<†ªX#s-6­äF,•U=•ª»ú¢ì©ÌŠ›UƒÝo×DŠáÄÎrì?‘ç`øR,“'+y™[[Õ®Nfª¬lI³½µSrÝiîœ`úS‹SazwQج´Ž{⤥jòó9wsœç*¹ÎUïs•W»¯D;ÖÊx·kw´oO?LðÿU]=Ôéµ0‡f;SUZÛÁFŸµ?d{ý ù¢|Zì·¨uGˆ«Üz‘Ÿ9¬‚©¢ÇhW?™©CO+Q[²l÷"uMÑ­vê¶œ¼aðö°¶©³b˜¦ŠcHˆ"#²!®º®U5×:Ì€óÈs7Êï–Ðÿæ¿hFtÈæo•ß-¡ÿÍ~ÐŒ™±áøÍ5“ð†YûU§SŽXð‹üfšÉøC,ýªÐ:fó\®Vë5EÖïp¦¡¢¤ÓTTÔÊØ¢…ˆ›«ž÷*#Q½Uv ÓL×1M1¬Ëé+¦yšäCä:9¤òÁŠA"C—eÔÏúÚGÑ_EG"z/‘Í]œ©ºlí—Ñß·+Ìx¬¹Uâúqs¬Ç4²šGÒÞrH™ÙÖ^ÓmŸMFoÖÙàçªuEëÓv>xÃ0ÌkOñªGµEoµÛãìá†4üjç*õsœ»ª¹zªªª—¢"×çìK¨³oet½Šˆ«Κ'ŒZêªç]qΛ7||—¼K°àØÕ»Æ(GkµÀ”ôУ•Ü­N»ª¯UUUUU^ªªª¦\Ìμe»v»õÕväÌÕTÌÌÏ™žs3×!ñ/k[Æ€ç´k\±Øêj¶r"ÿÞ×~¿è~âL0yÝ›èÈqîÏŸÝKU].Ûóv¹›m²ïë{ä=Q:UÍÊqÇØÄ~etÕèª%ðé=ËÝ,Ãnüœ¾}ÛªyvÛnzf;m·_oµM¨‰8L»û·Ã¦ [¾ý½ÔýÂi!ö'þ¯ÿÖ½ä¶+Ú¦3Ì<àóÜ‹ »¶ª¯gSO#V:Š9|bš5êÇ"¢üK¶íUM•kUFõm_ñ«3=`¶Ñ .6tRñ­ú!UgÆbt÷Û\w›}3UjŸÇÃ×ÅÑÈõjx¹­O ¤œrèÖAƒA.¥e؆Si‰)¯V»„RFöÔGè½bo.ïEr*ò&ïor§MÖË•§ˆ^ éø„ÕL)½eŒ¶ã6ê7Gp¡¤¢µ•óîŠÙùwÙÍåEWórviÊßMU+Î8´ÕÞ$² ô§„,v¾–‘QpÊ*[ؾ(œªŠö¹wJf*"ìåÞW}£Zäë¾iÞ–é¿Øe^¨j þÿ~»ßj  ¾]é¡–h ídææXQƒG§Y_ÌõUÙ»+ùOÈòÍàïM©é¥Š‹´BŽJ+m;J»„¨‰¿+Uyæ‘}i»&éÌäB­Í?På§¥ŠM>ÑöÏé=èåu{ZíÓØµOÝ7Ù9ab§UW57 OŠq[¡yÞyA§Vgîåâá“3Ìè§| k¯^yUˆÄè‹ãßÑvUD%Âðƒ…ÞxxÖ,Û@/8{ê骘ÛÝ›,‚ßÖ¦‹Õl55=Ý•®TD‘²¢nŽid³=bÓ==ÈlX¦g—ÑZîÙ,ÉOk¥•çÎõr57åj£®Tj9êÖªôEß  W;Ôì?M¥°Ç˜\BÌŽèËEïRÔ=Ž{RIWfFŠŒ]¹—u^ä]—m¨Õõ+MñWĪ0̲*…¡žh*%,Ë ðË ­‘’E"uc‘ÍDÝ:쪞&ÉO)i⦉Ò9±±µd‘Ò=Qdæs•\åöªªª÷ªú„¸Ø÷©jgà9?M…Và#Þ÷GøV·ôµôL_ïëŸë’–«~Mz&/÷õÏõÉKH}Òä@Vøœû1áŸq¦ýiŤ*ߟf<3î4ß­8 ~y¨ï‘OG—úŽù@#­VáßE5¶’j}MÓ‹-æybì[p}3c®…©Ü‘Ô³iXˆ½vGmíE+u˃ ôÆuŸ@µîõ–9•ñã9Ý;¥FG·V6¾$tŸZŒcSÅTºÀÀÌr¼mkÄcíSržª¢'ÏòžØâ½cw Výš¦™ì—<ª5Ó:ÓXe¥â+C2ü>Z.t©¼ÐPºãer5õĨ‰]ÊŽWµ=$E]•Ûï¶ï…k—j#7Âó»=ÒOxêQµ Nn]Öm""®ÈŠ­ÙwM‹§,QOáš6ÉV½ŽMÚæ¯EEEïBÔN ¸dÕ×Ýr½ ²%ÊEsÝ_mkíÕ/‘ÊŽí%3£Yº"ó?™{Ó¹U•ç²LlÍx •Xªz>U>‰ò¿ä‘av«kH½\z'Ýêh ÁݼŸ·«pèÇ:‡¥<|Ò^Ÿ摈ˆ‰ÊÈÜ‘ò7§ùÛ*ª¢x*­ãËM­Yž–gtñ«ÛÍp¦©·UÊœ»µÜ±5"jo·_vóÌ,òƳ…»näwÍ3è˜ÓþMÕ¬ÂWÂå5Sè˜þüÍäl÷N4,/å¿p‚êø‘œÝ½£.¢—ukwvÑúNïTDEÙz.ÜÇÂýnÔú6Áî§:ÖÅ•W™(ñÇÕ#Q¿ÑTð_·ëìÜŒb<m^|¬$ÏuTO²¦Â Ë«åsÓb`/MÄÒNõd¼>ke:"oÍ&õEø½Ô‰™ä¨Jj~uÊw¹ýœ}žåíWdåN×~¾ ¶æÞûiõÓàUú?ªïݬ¿ô°šAÓë.±]QÅÁ殾Eçn×RÐ7™ºzRx/·ñ&ëÐÉЯ™,¾ÏµºÅI3Uí¨¾eÔª»&û#¢iXåéÑ[ÓeÝz¡Ÿ‡ð]µx‰á„˜ïªˆöÕ¯©f½ Ë¨ÿÙ¯tO¹&ƒJ¶péÇ^¨ÉukO4þ)žÕìl¶‰.³Á]ù¼ãf9ÝÛ¢9Q{ÑS¸Øm^Në ÙMd×JÎÚ¬kf ÷KÜët«ÉÊõZxùœ›îäé&û9QUÝä§àC:¿¤ã/[·šÕ>"?ä×ÞÚÌ-Š¢jôD}¾Æ¡›ñ ¢úx’7)ÔKD5¢ªÒSËçU ²¢l±EÌäÝU;ÑʈÝÜHÞªŠß¶Ý©Ž»ùCéëqÊÛž£\®¹U{—‰Ü+©ö ºW+ÚÎÉîj§+‘®äkœ«Ê©»W¸-f…âø Ž· ¿\`¶WIfUJ‹4“»–7=wÙZ×wúè©Ó™S{pVfgŒ®]½rýÉ»v©ª©ffu™™é™žr -„7©ü>%ó MLÒ{û°¬ö%G>ºU¤¹"ÍÖBž‹÷þ^ʽz£¶nÓ =STÑ:Ã?.ÌñYUï…«I˜Òc„ÅQ<骙Ö*¦zbbaâ¥ÒÑØhœˆÙªê%¸Ý§jnÝžW÷ª1¨nê¨MÔ«”¾Qþg­Ö ¯tið]0·Ö*W­] •³ÖÆ­rṟ5ÊǪukY³X©Ìå“•C¢ø,7ë.Qf£ÈqÛ¥5ÆÙp‰³ÒÕSHŽX×¹ÍrwŸx^°êÞ%¢8~ æsÊÚ*>Xâ‚GMU;º2ÑU\åß½QUUJéfÔN=uš™2Ì Ãð zföÖøoê÷ÕUĽZ«»\½S¹V8ÑQwETêm|yØ«ªô¦Á™Ci’íoÁò»~Cv·5¼ÉQE;$Ýuë(Ô ÎG¥zµS㺉‡«º–™Ê´õ´ÎÙUûìÕW7tÝɳب¾—+gB1¿éÖžãºÉKÄ÷*’Ít–×*اª†:®Öethîfó:W9ÍkQöéГ€×u ¡Ô?ÉtúåPêzl–ÓWj–v1è[ãMúÓ‹HU¾'>ÌxgÜi¿ZpüòÿQß"ž/õò(€jO<=éäƒPuo¶UÅÍÚQ2§ÎkÊåjïO>_Y®OW½ªè¤{ò™é¥R¤S¥ZœÊ©Ì•0ÛRЇ—gí¼Òª¹U‰¶ñì¨îþdå<×]6ãz¹Ò;WmY»ˆ«rÕ3TõDk>¥Æ ºqÝÄõÒyŸ‹pçY©•°÷g"ó©ªurCɶéö½6^õ_~§‰Ž9îò²y/ú[bjúÐÐZª§DôS¿¶s—}Ñ{â½W¢&y¶ß;±æ}ݔα# _ž7}º:,m&¶qÅ4ï|ÚéŒÓÆåW5°âÔïFõèÔænû|ª«òŸÉõ§Ž&òù¶½c²wós┬ÛäÙ«¹kîî_®ž3Õ>æ_ÄŒÿM~>š™Ò`s¦Ÿ‰Þ:m YvÒ«ê¶ET޶ÙU ¹ª›"}iíîïÛoUî3Ö¾<¸ž³TªeÜ8c—Úd•e±d>h¨ÎíѳöŠåÝwîNåEÛ¼½Fm¹ònÓç=¬;û+aø×†¯ÍÞÍWàîÅå4Ò¨ÈuOLõRYê­^wDßEÎôf‰yßêªtÙàŠ©;é·«¾ožjÆ=v©ªÛ±¢ó¤‚±Ê¼Û'›MË2.Ìrì¬ßdß»c:Šé¹Ñ:ÃIvÍËn]¦iž©'Ö“@¥°æo•ß-¡ÿÍ~ÐŒé‘Ìß*¾[Cÿšý¡29cÂ/ñšk'á ³ö«N§±áøÍ5“ð†YûU tÌ9Õ. t¿H¹hò‹÷ox—•)ì¶æyÍÂw;ÕD‰«ès}ª½ZÕîEß¡Ziš§Heà°8œÆôað–æºç¢˜™ŸWG\ò„ŒEš™ÄnŸiÅÆŸcë2Lª¹y(¬X|æªWó+vr§¡Îj¢ó/7ETj즗ñ-®èçT¶]ÃæEFµŽI/õlV»g+•ͽ$jªlɪnäÙI[Nô‡O4²–XpÌr JŠÖ®¾UY«*Ü«º¬³¿w¿wní·åEUÙ¹»M+ŒõG½½œ».ɧ\οsôvê"z«¹Ç}4oO8š©”S”뺹·]oÊ%Æ1J¸Y„Øçs^æº=¶¬©Dkœ¨ïIcÙíÝÕTTYËÅ1¬.Ï ƒ°ÐÚ-Ðue5 ‰›ø¹Q«—n®]ÕWªª™Pyª¹«‡C]˜çxœÆˆ±:QjŸ“nˆÝ¢;tùÕuÕTÍSÓ ðÔ*V€jF¢Ù6«h~«d–Ìvj ¢ºùl’íPÊh«­•ˆg#ި׹7V§_OdEåvÚ€inA«œËa×4¼XòÙï¥eCyù©¥kãU_et¬ßm‘ËÕ:*ãQ´+Hµn¢š³Qp+eꦼÔL×2f³}ù;F+\­ßuåUÛªôê¤9«ë“`…·†žôÂÝyÊ(í쨚%kb·Y©WnT{Zæ"/+šåW9­NÒ?]_Ê7ÄfUÆv§é5}«*кVÑaX.wš¨kYPúÇÃ#U­‚4{——›gª'?Fzþ¿ºæ]-”—(Øæ6®çk\›*#šŽÙ¤£8W|oÏoËó)¬vQnÀo5VŒ‚É kcLˆ³:gG5}—w¹yWÐ_“¦:…bÕlɨx×h–ûå*TDÉví"vêׯý•S™kš»*¦íP6pž¡éNŸj­¯Üœó£ºÄÔTŠYË<øÇ+v{?¦þ;‘Lø7:-¤Ò¼ª=EÆáÙ[äÒíp§Õ§¬EN~‰²$ž‹Q6Fª–é¹4ÆœáºÀgؼ¿ƒU¥Ë<ü]q½G|tÓ?µDÓWjÀø§Ó|¢½qœµÕ8&S µ“Ù²4óWóªì‰Ù’n¾¯s—ù$ÅŒ•–'µìz#šæ®è¨½ÊŠas Ô ;ì9¦;Cx ~ëÙUDŽä_å1Þ³þsU=¤3š—¥qO/Z¯=-Wnj䱭m.è¼±Kü$)ßÜŠ«ºn½7=iE|¸3~’æšÎäá®~mz×n{«ˆÞ§²*¦c®¾•‚?–÷=‚Ù6MMMMx’Ž\!¦rºêUˆ²µŠ½U¨þdE_BÌøÌÑ +/¸a55÷›­}™U.²Z-RÕÁoTõ’Wµ>Õz;—›eÝeED´WFåSNºéÕÆ<ÉÌžŸjƛꭱ·m=ÌíwȈ÷²ští¡ßÂX—i#_‰íE6ÀòwÚœi6šTeZ}€Te—wTÅG4MsÒ•y[3ãg×$j=XÞFlª¯N¨›ªJ I¦<gº¿’ŬaäWJév’—dÛG }ídÊÏF&'cÝz¹Û«š¶ùØìMø'Ð¥¸ãéÖ•mL¤ci{%M•š'*&ßúfž+€cõYVg~£³Úh›Í5UTˆÆ'±©âç/r5UW¢"©Iòî#µÏ‹‹õ^™ðµe¬°âìrÁtÊ*·ëôÝdMüݪQŒÞg'_E9šo‚«Äx>¿ê×XÍæKžfšk•¥]+¤mÙ;#’»ªoõÔk—ÅÐ*ø©uŠç¥Zm¡¼ iûêrÌÖ†–áxsãx¯^ÎZé‹´PBœÎäo2ª1¼ËÕUʾ¦™ëv”k<õkœ[ïkJ›Ïjèª"nû#Ÿ ˆÙÕ^ˆånËà ok•²Ûy žÕx·ÓWQU1bžš¦&ˬ^ö¹ŽEG"û …«þKÍÔ+.˜-MúT¹¯jPµ*mìw^eóWª*"îž‹$cSdÙ®÷Êëüyh4Ëô¢ÍÛ’ÚbéO ºäÔåè£èë#j¯:»f+Ñ›uöàå㉭%™(µ·DäF5D’¦‚¢×+܈ÍÕdV¾'nŽnèÖ&Êôøšu´ó,QOáš6ÉV½ŽMÚæ¯EEEïB9šl†ELÕŽÂÑUSÎtÒ¯­N•zÙØ|Ï„áfäÄusDðs+ò‰é5Íc‹&Æ2$¯TG=ŒŽªní·W5Ízì›*ìÏj&û&òm‹ž/îk)5>ßNõMÕµÐOHÙUÒ±­ñð^¾–[1á[‡õ¿üÓè¾)<œÜË==½”“ªï¿Y`äz¦û®Ê»u_jÆKä¶áZúõu®‹)Çwôm—…z'¥¿ÿ]2eîéò|}H.7À¶Îâfj±UË}‘TLÊ&}m½­ªÇQ¸¦¯7ºcØû­‘§yÞàç¸åË~ï4ºA6ýÿÉrûúØc‘’±²Äö½Ds\ÕݹQH!ò?`µ-jbšÑ~·9é-Â× j*ïÞ‰áÙ6Ý6ë×®þ—QäšÕ»"~¯6ž×Ué%5M7tÛv¬n‘UW»¹:x‘¬G€‹sÇŽ˜ì›zúâ¸ö3èÛ ùö½ý¼£€<¬ò¹,Ú÷E]t‰Ü©ê«ÑÑ'UÝz"®ÝzûxTò•Ú4Ôyû«œÏA­nNפ‰ºujLˆ‰íë²íý¦ç€¼Ê?Š¢{â¨÷²iÚë:ÜúaoPit Ê‹IÍÙ]Üî}·íoVÙ;½œÊ»wø'ғʵþ ®þ¶°ÿ½1§Àvy¯ E¯Mȹ[„颯W½rAOåÐ_*=|QIQs–#wämêÙš«¶èîÍÛ*§Ê©ì=ýKžS +«9ZUUæXþˆâcÛ¶éÕbM—Û¶ëáâz§Àns?+j>¼ÿÖgk°½Uê÷­è*4\qû~Ï»kµ.ê’ö5y…ÍÈŽ]÷DH¡{QS»§N½7CëÉO­×Æ6 Ã_mN…¾‹[WXˆÝ‘QQ$V&üÈ>$]׸ϳà'Wã±´Çu>Ú©Y«kíÇɵ>>ÉXûž àVF½÷œÞÁ@Øýuª¹C7¦ýyœ›tëò5ïŠîì|uÚ«h•X¼«æI-bxw, z/z|~Å5[‘ó§ßè—\.õþš*y–*M™âžœ²õ_ðö)&ã^K¬S$·Hòì¨ôgs»£©·«ýË+·~ÿ½Âø ËhŸü¬]u}¦Ÿnûæ×_ŸÅۈrÉ|¡º3jrÃÙ²;ãÓeIM<*›ª/¥#ù÷Ù}Mº§]÷DWÕ:†Ú4OEê‰^Ø÷§¦¨»Ì×"s*"±Œcz"ªó5vnëÓmÓ¢xg¼3àÃQŒè¶1ôíFÅ=e'ŸLͼRJ…{‘Ý}m÷øÉZ††ŠÙI¶Ž JhË0F‘ÆÄö5©²"|„·.ðS²ù|ÅSbnLt×TϪ4¦|ðÖßÚ,Â÷ ýØì=|ýnY[8Qòƒëû»}EʈÚez«¡¹Ü’•®g21ÈÚJ4rª¢"«RTb.ʼޖë?hÿ’·D0Ÿ5¹êeÞåÝ!hè_ýÅn_§bÅY²÷óJ­vÉ»7EºÀža08\¾ß‰Â[¦Ý=TÄSˆÑ§»zåê·®U3=³«b¸Îi†Ã‰X-öku;ZØéhiÙ mFµž‹Q~Vµ7ïÙØe2–À­ñ9öcÃ>ãMúÓ‹HU¾'>ÌxgÜi¿ZpüòÿQß"ž/õò(€19NWaÌ£.¾QÚ-VøŸ=M]\©q±­W*î½ë²/Dê¾XÓõ;WôËF1÷e£šÛ1Û¤‘º®_®T9©º²š‹$ÏD]ùck·]Šy©üwjF¦MQp§c‚Ýid®†\ß ¤r1ìXãs_EK"#•Û¹ÝeÍÙ»[ͺBVý#·ÖdÎ5.ÿsÏòɶY.·éV~M•UNUlloÚ·ÒäûUDèj1ÙÖ­3;ÕuGÛÕíìK2MŒÌó½.QNå¹ùÕp4sŸgj}Êü£ü­–¾´†ªëN±£¦ÈòÄ} ¾79›·’/i2"¹Š»9®è¨Tr=!,¦‡\ufgÍ­ÿ’\©çªY¬J–«{QW£ȶíQ›"½9“uô—ª»mO´xÌDénw#³Ÿ§Ý£ªå^2œEXˆ›µuÕÂ>¬}³-GÒM8Ãbk,…¾)›vòÇÛL½wþMÝß²í¾Ý؆Ü£¹v»Õo\ªf{x¦¸|-Œ%/DSOTDDz€m|4ì£GôÓ1k½ÞíòJåÝj °›ŽHù\¿"ª§Än ¹níË5o[ªb{'EŒFÆ.ˆ¢+§ªb&=mg~¿i Ñ»HõòöÛt.ÉdÉZ—J7£#V$|Îôâb§*m*¢&ûônÓ6å»b÷3‰ ºYddjäX´­´«ví$cÞ²B‰ìæ‘Ëü”î#óøö6F«Ôs\ŠŠŠ›¢§°Þá6“bt»åÇo ôÇÛªšx;ÊqÑ5a¢mUÙÆ>¬Ï²a´ûS4ÿU±ø²8Ëí™ ®]“·¡Ù»mù$o­ý­z#“Å ˜åº`¸í鹞Žäµúy”F»¥u™êÈgM÷ìç§Ý#‘нè©×ÇtèMÚeÇæy€ÖÒc\Uáð6Úùs›n}#UWfº®š=×mÜÄDÝzG·RYÎp¸ý)¦t«ª~η*Ï6;3Èõ®å;öãçSÆ<ý1çáÚ½àÇcÙ‡-²Qd¸½âŽëj¸Ä“ÒVÑÌÙaž5îs^ÕTT2&ÙfùP=òÚü×íΙÍò {å´?ù¯ÚÓ –<"ÿ¦²~Ë?j´êqËŒÓY?eŸµZLÀ[²í{ÖLïR/Ú[Ã.!a®~%#i¯ùC,¡‚¥wÞž&F¨ç=ªŽE_K«\œ¨ˆŽ_£Bø—Ê2-Gºh.¹âôΡ[ÛÓùŒ®uÖ^~hy•ʋ٪?ngnœËè«\Ô G:¥Ä—é-Q~íïò¥=–ÜÏ9¸Nçz¨‘5}oµW«Z½È»ô2º£†e9Õ† 1¨W,?´¨Þº²Ý¢Z~ÍéÙÆõô¢wh±»ª‹³\ž=1ºk ZY¥ÍqÄñ¨ÖíR÷¾kµkÝU["½W›ëÒnæ¢ïÕ².Û®ëÔ¹LQ­^†ó/µ”ÚµðŒÂº««¢Ý¤ðüë•F”ÄþÍ5Οšú¨uãÿsX|ßÏ_ê£ÿä|Û}¿Ì{ÿX„¥¼?i~‘sVböÞñ/2Ô^®/ó›„îw¬«+“Ðæûdb5«Þ©¿RF«“1¤p…ÌnÑâqg…¦,XŸ™oX‰úuLÍUÏÓªcª Ñð«zSÇ–¥ØoѶ)³Ûºëdé²ÎÊh[±5}»¶UÛÙ ©i›ˆ"°-–ÛžSC]rºÞ¤}5®Ýn…¯©©Vòó®îTF±ìEë¾ïM‘@¬uº«œèֽ떘iæ˜Ý2Ûîes£­´2ŸÜÔ³TRóË,ë·«õæ/]›è;™ÍN¥£á‹Knš3¡¸¾žßfŠK2Í[Ù.ìdóÌù*t^NÓ“tè¼»ø‘8­â_(éðg‘ÄÇÿQ{­u+\‹Ü¼’Emñó©«pϨ¼a]µ74ï–LvZ;^HÊÛýæå,µVx«\²%=Œ‘èèÛ]ÈÕæj*"n›¨hÍs¹Ûì¶ê«ÅÞ¶:_QSQ3ёîsÜåèˆˆŠª¿BxFâG4/Ëm:q®¤’í‘Ö×ReIiª–— …6kV7¶5r*+^¼®DDí;ù•ÈKÚý–çÚ««¯á ¬³Ø­÷Œbk…þñp§uDËM"¬}4Hö"¹:xõæUôQ‹Í¨½8©àû ‰—H±­SÓv²F²?3¸ÐR7dEÙwEk~>ÙQ;Õ¨› a¸`Ñü 9Ë3Þ)s,&lrÀ·ößq ¥žj/6¥e–j…cÖ:'¢ÆªŽG3Ðz&é¾û­ƒˆŽ(u¾K†[ÃÖ—â±àôS¾žŽ¯(šhênÎbìå‰#‘¨Î½:¢µ¢½U‰µqE—?;à·%Ͱ5™i¯¶::ø¹ÛË#håšLŽDßeHVDro·E4 &á–éM¦8¶{Ã?¹55ÊÓKU=K™p´ÔÔ¬iÛoNdçGtzµy‘6jÐ^ i5rÃ.Ma~#’áuN¡Émus¢²íG/j’.ÉÙ/$W»‘ÝU6rýx¯øNy«õšO‚ÈÛûmvunº ˜å¡§rÈÖ²ÕT{Õºò®É²§z9è–˜çZ8ÝlÕŽ$&±Ü>ˆ¢eerP¹%£ª¤§†wKõ§µ=$œˆÇ·uÙSn½bž8S‹QtÖmjf]’iþK‘Ýë+-3cU>k =IÊØÛ:.ѲlÔV¢±áÞôŒLóJFFùeŸ±^ïIïÙ;×dê«·‚w•*ŽkFEÄ5Ÿ’W`8­¶š©oïËé[EU=g.ÑSµåHª­w3Õ9“™6M‘T-Ø#­fÔ¼£ÓÆfZm€Õgõ³ÕSE¶G;´†Uë2:6½Uˆ›uDTNdUèŠH4òI,Ë4+ b9ñª¢«S«wN‹·p LjM1Ò=PÁ™A¬ÕÔöë²¶‚WË\Ê4í]•gôk^Õsž(F¹5l‡_8máËK¬õøÍ]º£žwQZ¨qNÆ­j%j#¤åV½®MÑ^ç¿uW&ꪤMƶ?wÄŠéÖwvª¢Àï•¶fÅ2ÆÙ«QÈÔb¯r9Èè£Gw¢Jý¶ÜÃñ?ÁŽ5§Í³pña}²ï‚Ï Ò¦Ø³KUL09¯íÑ%s•_"9ɾÏb;§2&á­àÔ8_œcä—]D÷RL{´ÃQdÇ.Lu$ŽcR&«d™’=ò9¨¾“žÝÕYè®ïÅ–œa<3G‹ñ£vÚœiši³Ü:Ãm¶HU¨Ù$‚=ç›nîÖgo$‹þ“” ÷hĸÙ×µû;̨ô‡§©Ž®+5¡½µ|ÈÇ£šÙœŽîTMœŽ‘ªïm†\ÏnPÌ%rkgÑ”îªm­*˜µ]‹vÝý–üÈßI:ª±@Ì€o‰Ï³÷oÖœZB­ñ9öcÃ>ãMúÓ€·à—úŽùôy¨ï‘@ôPø«ã ûd2h_ϕ›Ýï1&£ÆâTïz*+_QÕ¨äoNf»~SÅË”Z¦k®tˆ^Ãáîâ®ÓfÍ3UUN‘ÎR|_é÷Ñ&3LÕÊ5 á-« r¬òªí³ç{Zä§eæÝÞ“‘ZŠˆåJGÛµ+]²¨óþ#/ì¹v:Kf#Jå[5­tO­*«e“eTW®ê½\äDDý°]?’¶û{»Ôä9]æEžï~®rÉSW"ª*§3•U›&ÍßÁ7ðÛn ù®ÐÜÄLÚÂ𧯦}ÑëvÍ—Ø §™ÆýÞqOͧ¿ó§ÕßÍæ(¢‚&AlŽ8ÚŒcˆkQ6DDNäCÐaÒâ4á E<pIKUsC39#‘¨æ½ª›+U¢¢§EE?@W‘1KOáÕ²9s./iTË=ß ¸J«k¹n‰Ì±n¿Üóz-Dz*mÑ9‘ˆ¬uçáË‹:â.Šª†ÙN;–ÚW’ëŒ]YL½}&wvÑô_M©ºtæF Ó3}9‹"¯¢Ëñ»¤øîge{g´ßhÝÉ423uk_·¬ÍÕwO|QeVÑWfbÖ.u§¯¦;úã×Þæ;QàþÎ2*ÅeQ\ç4ò¦®ïÍŸWw7US¸^ã6|ÖïK¢úõCOŽj;#k(«í¨2TFõ–ܨØåééEܫ՛u–Ä›Ñr›´ÅtN±=.+~ÅÌ5ʬަiª8LO €{ZfùP=òÚü×íΙÍò {å´?ù¯ÚÓ –<"ÿ¦²~Ë?j´êqËŒÓY?eŸµZLÀ5ÍEfs& {fšMAP´o÷-õÍޟÛÃÛ¶ý7Û~›±ŸÇ½¬j½îFµ©ºª®ÈˆjX÷"®ÃiérZË~kl¡Š;å%º­«Uë;³r¦ë2ì½S¢.芛7¾^xðÎîxV¥¶ë†c˜ 3Y|Å(k6}}ÑÕ³y&Ùb‘5»nUÙzîï­ºïâ7›6šhö#aŸätÏ®£¦|¨Ú**&¹Z꺙É´|È­DG&ꊜȻ#µ)â/U-š»…ñ/‰Ù¬WûÅ:Õã÷;CŸæU航°îç;Óô_²î[Ê­ÝZ®Šl §‚.+¬sÁ=SôïQhd±ÑÕU¿´[]K¥cÒ?ù=ª1QWoBW*î±¹Ë:ñ‡¢Õú­¦¬¾â $9¾?»˜õD õå–=œøZ¾×£­ÿÚG†àVöK¬Ú}ĶyÃÆ7ŸYðZ-H¿Ï”Rä5Ô®tw¬Tj«È²/2Çér¯4.ås]²,ÛUpíÁ69SÞ¤šýš×µÝ}Êt«¾^*]ÑY»«ª¨ŽV¢"&ÜÊåÛ|–5iozeZ‘‰*×v/‰óGÍOQEXÕFN°Iÿ«s˜ŽD^fªrî›·¦gKø7Ðý,È[—Ûìõ÷ÛôJŽ‚å~«ZÉ`TîV&ÈÆ¹6MËÌž €LÖšôºÚ¨î‰ISJ•”ñÔv1¬sEÎÔw#Ú¾«“}•<ú€Eº‘¢ÒgZ³¦Ú£K{†ŽL zçËK57j•‘ÔFÖl‹ÌœŽo*ª;¯UîèJ@«Ø4ׯsl›P¬ôÃ{ËüÓÝi–w¹“y´}œ[1W•»7~¨UWshEZÏ–ÜŽ¢åuÇ2ÛU¶¬ŽËQØVÓ5UW‘]öìÝÎôWªs;eo2ïä¼.ñžZ$ÀsÎ+g¹áµR7Ïb‡‚žº¢¹²t­]ö]“uUT_rt-8eÄqë%E‚Ûí±{‰AoŽ×$©Ú1i™F‘»›~dV¦Ë¿]Êû?BwJ›Ž‚k~a¦ÔÕ’,ÓZ©äZÛz=SeVÂ÷·¯Dêç9S¹6N…šW~3ìy²ð}Çñ·×ß+á§ †á;«SQO±¬ò«YÞ«ÉÌôDÛ•_àm¼1êV•gºWd¶éUÑ&£Ç-”ToÌž‰É*2T^œËÈ‹²ª*ï¹-ŸžÑj’¢[]ªŽõrvµ‚Ƴ?»™êÔNeøÔ›+Ém˜n1wËoRöTZëê]â‘DÅ{¶øöjíñ•Oƒ="°jnšåZ·«Ø®ù[ªÚ›šÅq¥l펚9Örs¢«>¸éÕ»z<›w!a5çºê–ezb¸GEp½[ßOM,ª¨ÎÑz¦êw/*ª"ìŽ^‹ÜEü?ç:ƒ¦úGYŒk6“ÔâtÚc§=Ö:˜å¤¹AOìè¹U~¸¬wlªŠåß§25A¾d\gY4“N¯¶lIñ¤mÒßC+ÙK<©D^W£QôȈ¨ª”».ûí“ËøÙ±aš÷Ò*Œ:ï{¤²Ûc{d±R¾²º{‚ò9ð6٪ĎMÕÊæò¹ŽEßtÛZàêo íÔ)u ªÚìʶ¿#«~ÊŽó:u‘XÆï׬‹?*'z9›x^0Z§`÷ÍxÊéšüŸRîµ7's6s)Wr±»õFº^Õý:+V?ä¢,hça®×Û1úÊKÕ©Õ¶[­2Ò×@ÔTj¹cU]ÚŽTj«UvUD]·MåŠäØ%Gøéþ‰VgYµ“áóŒS]y75ÓZ.GG›1ògÓÆb¨Û" ê·Ú+¦•ÏÇ-·*ŒË'íìøó<åý¶ûr>Dô»ôV¢¹éü’|!-H—EøOÂò}g¶éõ¶ ]Cæ‘ÔÑ"UWÖÔHª‘öÎEs¯sœ¨ž‹ZŽÙ½"Ĥã‰Þ¾¦—CðúŸù¨¹¥¼Ë§Šú25{Ó¾ÿ5IWE8FÒ-¹7'³ÑÖÞ²¥Gö—ëµBÍR®z*H¬DÙŒæG9Q¼ÊЍ®R´}ñ‘¨š³‰b:©’i6wo¨¸cð[­‘ÌÄ|^—›JŠöÈ’+6r£äUNf7•ÊÔŸ4RµJÓªzáq¤¼ä{lw»5þ–….¶ÕzF«#dl{‘:']ŸßËÎà°À[âsìdž}Æ›õ§«|N}˜ðϸÓ~´à-øåþ£¾E=_ê;äP=~UUTÔ4ÓVÖÔEOOO¥ši^Œdljnç9ËÑUW¸Ô»S¼ \8éå|Ö >EYž_âkU-x…7º.Ur£QvªAº*ìäIÉÝ˾ȰõçÎ 2v9tˇ+uŠTHë2뻜ç¹Íb¢­,(DZªíÓwéÕªŠÒÅìMœâîÂgö£Y±¯uTÏ«{WICmJš©Þµ ù•]=uKº¾Yªªªª«ÑUvßñ®Ès¬ã8¯0¯rŽã”uöÏØúdvJÖAf/^ˆªýQÆ7öiûg§¸4ЮgX-Ÿ>³¥¶ä²ÓÔSÈ•5Ôî䨢¨oVË“ª**'ÊXN8·¼]oü?qY>sO-’öïBŸ%§oDT^ä©DOI¿mÕSÒÝ5}DÂ!Îl¢†©Ôj9Wi¹Dç2j¶*:9Xöìæª9uEßn÷&Î*Ëëñw8ÛŸWl}¨NØl•¬úÌâ,F—éŽùß³?dôw:– ÍÁ¯µÇnªÒÝI-Ú£ˆR¢ÝiÑ«Ù\iZ­ck¡]ÕÏ:x9計ŽDK2tJjŠéŠ©b_=Ü·]šæÝÈÒ¨&'œLtÓÀs7Êï–Ðÿæ¿hFtÈæo•ß-¡ÿÍ~ÐŒ™±áøÍ5“ð†YûU§SŽXð‹üfšÉøC,ýªÐ:f F_t‚ÇŠ^o7˜-ÑPTNë„ûvtœ±ªö®Ý¶û*/qR8fâ§^5ò“Æqœ>É4øóé“4È®µhÆË Èí’ x‘“Iél¬G£º56ÑjÍê“Ó ®ó[p®¡†–ÏVå©¡kÖ¦Xœt\ž—:*§*¦Û.˺w•;„½VâCZ«m˜…ß.µãTšjêhr(jèŸ5êòˆ®FG+eþ ªÆr¾DT:s/76ÉwJ…ÄͦåÃÞ´ã¼[âTs>ÏVèìyÕ%;wíiŸ³YP¨‰ß²17UDçŠûgógŸýIWÆëeÑYÛ5mŸè¯ª»ôßeè½ ¬Ðª5ÃN©µbÝ¢¯»Ìì¦é@·hM"ÄèQYvåEVF÷"oÜžÕD]ôüsZö«Ôs\›**nЇô§jV•bú¡§7/¼-]ºËs‰‘H–·¶žHÚÉö£=j'3StVª*nŠ›)’¶XáÀ°:lsµ-K1ûSi-”]£X³v1rŽÛ5Ü­Erª&뺙ð{à·I2Ý6ÓëÕÿRmï¥ÍsKåUÚðÉ\ÇHÏ®9¬j¹Š­TUí$M•†4Œi~žœyÞò5TŸÑ«b[)•v-Î^v¹U;·G:¥7öÓ³ñ[³\ÄtëÀª/xv7Ij— ­[…ÉÔè©ç ›+ÕvOÙ6MÕWmÕUBˆApÕMNâc9×{nQju‡ºÏŒÑYê+Y é ¶lôñÈŠ~Í{Õ9\¼Ón‰º"·ìÈõkÍø¢Ñ«¦é­ûÎÛzuOCq·%ÒP¿³k»Doð©ÙùÆÎTEÙ»*'£´­yÀuã†ýRËuEq \ÿ Î+VëvDZ)«i+\®t’BåEEj¹Ëê£×eF«=y1éwrÕësòLËE¯UÆËT±RG~§omÌèý9 sš×#y]Ê®DM÷Të²&ƒc—,·¯ÇìùMíªHÖ ¥ݵ;Ù#^Šˆ½—•Íñkœ›¦ûßÓ;^tf~ËZ18ó^&rýâô¿Ý1uþ®“tF¦Ý\èÑÔNœÊ{¦øá<[Œ¿'¯4·?¹O‰ü\ÎíUG4ë¥5O8ÝŠ·¸p‰Õ`ƒÃóŒCP,ì¿ay âû'kK*;‘’öúÌwù®DTöÃÌÄÇ jïY¹‡¹6¯S4Õ&&4˜žØž@¢Øç¸Ûè®Öú›]Æ••¾žxŸêÉÚ­sWâTUBŸãµ—uÒ¦ÅqYŠ_%d}³Ñ[©œ»Ç6ë¾ë ½ÍwŽÜþÔ.Akæ“Ój®--4Q¥îÚŽž×3Õvk•Z²F»w£ÚݾTjølçrýâpÿ·ÆžÞº|ñýñLv?9±‚½s.Ìxáq¹_ìÏÍ®;ižž®æÿ:g„ôUÊc¾=|:˜Ó€ÆöfZU_‹Rº®ç‰\©rXiQÞp”ÊîѪÔõöïw/"m×b}V b–'xv±ë‹¹Õ9N/WO’Y"…9ê!­Qg¢sSª¿mýõÜÈöÝû8pÒíc¸j=ïˆÞ RŽƒ%¼ÚÛeµØévV[(;FȨíœîW+šŠæs“™êåÝÜ©‰ÕÜëWiu~ÝÃ/ ¶¬_¨÷r+•Ö¢’6Ãn•Ì^H‘Žg.ëÈç9ÏOUå\ž •åú¥eŸQÅlÌ[jíRãc¨t]í’¯/œÓ®É³šþŽjµíÕ›#Ú–}à÷7Êî6 ³I³»»¯Ý0¾Ka}Ñ\®um*+» «Þí˜ö®ê®Ù­æÝÛªØ [âsìdž}Æ›õ§«|N}˜ðϸÓ~´à-øåþ£¾E=_ê;äP=•UU5 4ÕµµSÓÓÆéfšW£›¹ÎrôDDEUUî4­bÖÍ5Ð\>LãT2H­6ÖÈ@ÞGK=TꊭŠšŠç½v^äÙÎVµSžÚ—¨úÃÅÄÌ—P.¦ì–Ih1Z eвᯠû‹÷ÙWdEF5:ú¨©Ì¸¸Ìmœ ¿zt\÷6™NMŒÎïüF³Ó=s=ÙèXdò[©k§ÃxcÆ©µ"ý‚ªðéœË¹ÈTs§nͪßuôc‘»ò®ÎUèµ£(Æu/ZçÜFjÏ(U‘Ò2Ënw˜Ú©‘ÎV6²4k¤O­G³—eéºîåWe®×n²[©í6š8©(é#H¡†&ìÖ5;‘úˆ>;hñ8™Ý³äSÙÏÓîv¬—Áî[—D\Æ~¾ß“Ôôùõî†:ÇØ1š6ÐcÖj+u;Z䦅±¢¢o¶û'U꫺õÝU|Lˆ‚ª¦¹Þªu”ö‹tZ¦(¢4ˆèŽ/@½ãÖ–“Ì2- Ê™"«§l­Eö¢9eøÓ©ªjšgZgIy®ŠnS4WÄôKKÆ1MCÑé'¯áçV/˜s¥•f[=CÛ]h•ÊŠ‹½<­r5W_ÒTé¶Ê‰µ‰Ò($4”Ø_XüEâwvty:Kz¦ÝýÜêg®ûìýÙ²*«™Ñ«5ÆÛo¼PÏlºÑCWIRÅŽh&b=jø*/E7Ø¢Åa¦)½åÓÛÏÓïA3¯ÙneLׄs³äÏ}=m<î’ÐWÐÝhiî–ºØ+(ë"dôõH’E4ODs^Ç7tsUeEÜýÎ\é¶e«|'\¥¸ire8]BOsÂjær¾Ÿu^ih%UU˾êÝ—}“tN^膼éÏxzf:wt–X¢“Íëè*ãìkmÕn°ÔEºò==¨ªÕÙy\äêN0xëû~2ÌëÙÓî+›ä˜ÜŽÿˆÆQ§TôOlO÷1ÓÀ[Rx–X ‰óM#cŽ6«ž÷.ÍkSªªª÷ wšûŽð奵ùýæ×W«›Gfµ$ŠÙ.UÏþ슻tW9QfµËÕvE 85‚üµ·FÔ ¦×ç•JÜoU\»$JäNJhÓíc»5=û#vËjn/úóU¨±ÜU§˜<϶áУ•!«©nÉQpåûdW¦Ìrø5ÊÕß2Bv“3ß«àv§„|®þ¯7Oos´x:Ù¯oî¾&Ÿ*¯‘Ñ5yùGgx"NªÒ³›>Ug»Û5J뤷縒:[t±µ•õí)%júìs\ôF¯‹•:snt[Aõ·â M-º•‡vÑSÖ+ણ¨Ù'¡«v– >Ùª¨¨¾-V¹:)GŒf‹jS8W×v^+Øi¾¥NÚKò69^ËUÉî©­o¢‰#ÜÖ½vßerýª!/Ù¼Îb~vx|ßw¹É¼"ìÔWGÝ|-­du/zÕŠq[„¿@Y¬4öŒ²ž–%HÛŒjÁT‘¢tô×'Dô¢åï•L–”âü0c¶X8ˆÔÍf¶jAU j]dU‘ªÓ=›±§¢UU‰í^èù]#W£ywØ–4Ó:°q]§¹?ÑœÕC…\ke·[–åèû¯Do÷CZ›:5í9¶TõU­Tw2/(I-ͰçÖY­ÌÊ-nªÈbtö˜[VÅ}tmghçÂÔ]ÞÔbs*¦é±»Z-wëeU–ùn¦¯·×Dè*ijbl‘M“g1ír*9;ÑH›IxFн¾®Q†â²:ðÔ{`­¯ª}L”Ì~è­‰¼¬èªœÈœÊЍ®]×y 7ÑÍ,ÒçÔK§ØšÅ5^é<ô”ÍlÒ5W~U‘wr·~¨ÝöO7 ¦Ùüâ·ªÛž¦jJËY5Cåšæ[;šårª±ÎÍû'r&ê»!ð{¹äÁÓ”Hà¢Ån23¹¾eYxæ_ôžÙý+±8^x9áÏ#ËîyÖE§Q\ïz§ÖUKQ]R±ºW.î^É$Hú¯ù¦;S¸\áŠ=<¼ºç€ã½5Ò¶óM)&¢sZªÙ»f쪭TEÙʨ»m²î­†×áَɨxÕ¾™ô÷;d2ÛêÝHØæm$G¶4Ý9˜Ý•=äSc!~3Ü—RxtIJ¬º¥õWGÇQI-SÝ»êR ‰!lŽ_+X›¯Š¢¯‰4 gå‹Wº:ÚEìî6ª¤Hëh%îVKû§TTG&íUED]ÑQ)UFõÎm‰PåÖT{ ¬k‘ÑH©Ï UkØí¼QQ~TÙ{”Éd+nOc¯Çnðö´WwÓNÞåårlª‹à©Þ‹à¨ŠT½/¾Ü¸qÖK†å3rXnó1©;ý$å^d§¢"/7+×oßÕ#7?ü&;ÆGânϪkëèé6?þ´É>!1#ôöÏŠK}™þg|²Ô9V¢Ó\ÔNÒîÖ«›¾ü¯åDrx5Èæ6R9Mp¬Í4C/~¿hÔ•â’4÷~̨«K~¢EÝì‘ÿœDÝQé×tÝ:÷ôÃLu3 Ö Õ¨˜ Ù·-Þ.Ö Q9^Ç"«_Ú½Zö¹®j÷*/Êt¼»0·˜Ùñ´s鎩|á´#g±s†½Æ'5tL}“×ÚKiíU_(N¯\ðý+¤Ò<.¡S/Õße¥HÕyé­èˆµµ ·TjF¼›ø$ŽrzªZ£–µ¹üüBë¾]®¯U~?F«Œâ z.ÉA Õd¨½Ý¬›»~ôæs{Á̱‘ÃU{§£¿¡»ÙÜ¢¬ó1·ƒ“wãYk£Ã²˜»ÑŒ™éæÕ(Ôß«$åUTMùXæ·¬‹¿P©—ã#†¦ôsž}ý/—³ü¦¼“0¹ƒ«”O ë¦xÄûûukLÍò {å´?ù¯Ú29›å@÷Ëhó_´#¦@,xEþ3Mdü!–~ÕiÔã–<"ÿ¦²~Ë?j´™€G"ízÓ)1*ºZ¯4‘]ìծߒØ‘ÈÎ}º£U¯{USuo72"í²Ê²HȘée{XÆ"¹Îr숉ު¦ϱ]H²Éá÷6×Û㬨¢íÚÕF>H^¬rµ{œÕÙ®MÑQQ~"ºNš®Óbívª½M34Ó1:p‰t‰žÝ'Nå:¸å:Ç®Êtcˆ,ÛÁ1\Ööæw ªnÜíí™O{¹#k‘Wª"*;¢#‘U‰$[8æá¶®ãC€ÓQßW©{,^ªmYœªÔbBçÈî~^^‹ÍÈW¦êGšù‡è-V&ëMªÛd±ÖbþéIq«©}55ââÉ{8ã©‘\‘µŒŠ?óUÊkÕÈ­i•ÖL—â‚ÕIÃvJjë =m+ïy%-Gg²ÓBîtŽ"#_*íÑÑQUUÊÊ-%ø8+ázŸ"vNÍ!µ-[¤Y{Í;éËì¥t‹ßæòrûš ‚ X#¦¦…ÃQ‘ÇQ­cQ6DDNˆˆž›1À×9ÉQˆ®vîTDÛªø©ì+ZxÕ-TÌvǸÉpŒ})"…ö›DOkŸ+UÜÒv¬™›s"µ6T^åö‘­ïɹ„dÔ/\—Yµís¶¶âk½«ãW/ýôùIŸ^2^"l ²A {bÉf¬Z„¹MvªlQÑ#{>ÉQ«4Jôw4›ìª©È:‘$¸Ç”k1g%f§X\ô‘(`Y¦cW¿—š)Súè¿·™…γ ¾é6EGo‚ï¥wy1‰d·Ó¤0UAHj‰Ñ®+ÕÈž)º¢+¶'Ò#á¿@)ô ¹ÐUdõY%ÿ!¸>éz»T1Xꊇ'r"«—dô—w9\ç=Ê«Õ%ÀIªúܪïM¨ºmwÔfëMu†$ìk»sCVÄEíX©ºn¨ª;Ñ6%°z¦©¢u†v_˜âr»Ñ V“ÊzbbyÓTO ©ž˜˜˜”O¤zá.cw¬Ó­B°ý ê ¡œõ–§½ T^Ò¿uí#TÙWªªoÞ¨›’ÁëFŒÐj¥®–¶Ýpu‹.²H•V+õ;Q'¤™»ª1ÎN®‰Ê¾“;¼{ÐÄh¶´Ür{^˜j}¾;¢Ø™ýÙGÝ Æî«¥^ç1ÉÕQ;·öw{ª˜ª7©óÇ÷ÐÜcp|ËVe•Ó»»øË\fhýºuã6æzõš'…S11TËàÒ2ïº>íLÄ›t²Ó>\†È×>Ž6*'œFåoiïÞ»"¹¿ç&ßl¤Ä l^Þ6ÅV.Ç ¿½|ÍŽSšb2\m¼vt®‰Ö:§®'²c„öJ áoXâɈުX·Û -cSe樢b1Œ•U{ÜŠ¨×Õ_¶Rr*6½á—½ÔJ-bÀúzÚŽj˜`–yQÍöéÙÍé.ÞÞnïD³8khÔ,Rƒ,²¿ë±îè•È®†DèøÝ·‹Wtøú/rš¼Ÿr&¬¿øË}?ODûүʰõÓo?Ë#ÿÎ?GsçQ>}f<úpÓ]€oP`¯¼g;R/¸“JtÚß*Ôê-æ;uÁ¾¥#˜é%æÛª5ÌüËü†Èê…‚kºwØ4dz`8Å?em²R2š-ÑÒ*u|ŽÛ½ïr¹î_rŸu§Ƭ•÷ ‚Ýn©º=²WKKLÈRö¢£]"µÈŠ©ºî»C[³j>f7í>´ßc›!ÆYO%Òb’9)Ù;UÑ;w5è­Ùwb»dswÛ™»†ÈU¾'>ÌxgÜi¿Zqi ·ÄçÙ û7ëN߀_ê;äSÑåþ£¾EÐ)Æ&µUhNƒß2»'¥‘\9Ÿq©Ý±«Q}ecRIy|{5:q•b&gHU~0u³ˆl~‰ÛëöÓÍ7–)ò(âUD»Þ\Ь¦s»–8£šÏYÛ¯f­Ç1¨Æ5֦Ȉ›"'°Ö4Ó\¢²ÔNêš÷óU\j^õ{ê*ä^ids—«—™vÝzìˆm1Î3 Ì1TO“#ßç})²Y_MGákã\öõwSË¿Yé©(Ó†MI«áÇ][†Þ¯m¥Ú•<®‰j¥c)í ÷{vrú‘ÌØÕˆÜÎgr1U3ZÔŒ&P°»¦)V¬c«!U§•Éü íô£·dr&ûw¦éâm2œ|åøˆ¯æÏ îþˆÖÕdTgÙ}Vb? O'·«ºyO§¡Ô€@<k¥f¸èuNM3þŒ±IŽäÑJíåóÚtF¤ÎñU•œUÙ´YZž©?:&&5‡ÍS4ÌÓTi0 ¨¯ütêÍÇH¸qÈ.õbÓäY°cVG5¯Zª·+\¬åêl í_å1 }‚bTx.!jÄè]ͺ#sÿõ’*«¤ÅÌ÷9vøÉ ŽœšL÷‰m<ÒH®¶`öɲû›REä’®WöT­s{¹ãìÚôÿ6wÙ Ú¬VõÊ0Ñ<#Œ÷Ï/WµÚ<å‘ow1®8Õ;±ÝgÓ:zuP•^Ÿãl†:WTºÙC=[ao|‹Ü¿cÕ4ÍuE1Î^.\¦Õr¾QÏ™” ¼@dº§”Wã÷Û ²èÛ"#Æò?™Îß~~ôÛ»»Ù0äY^7ˆÒG_“^©-´òȲJ‰ˆçì«ÊŸÈ«øŒœN ö÷ˆ¹Wg».ΰyžáÖ*üÖxi§^¬¨? ú+­ =ÎÝSE-TMš£]Û#›µÈ¾ÅE?sbbt–Κ¢¨Š©b@E@Æ¥atš„]qj¦§=T ´Ï^øªéFïÄäMû·ETñ.÷š³]¬ü9â9uòªz‹í=3­7—ÔDèåuu+–)ôU]ÜþVȪ7zôjîÖÔƒoòå …ën¨è…Kãe%õ‘g†sHßIêØjÑ­]Ø»¹bêÕEÚ5訛G/Ù\TÅuá¦yñdýž‡&ð¡–EV¬æ4GÊ»§>‰×Ò¾€hã`Ìß*¾[Cÿšý¡Ó#™¾T|¶‡ÿ5ûB0:drÇ„_ã4ÖOÂgíVN9cÂ/ñšk'á ³ö«@é˜y®º©’`5Êj=¾WÊËeЍªúºùW–6"x¢uz÷nTEÝQ´Ó5NÊÁ`ïf8š0˜xÖºæ"#¶}‘×<¢8Ë@Ö¼Šã«Ù¤|2`· Šx’«6ºÂ›ù…¿¢¥+eNÚ]Ñ:÷"§G"»–oÆ1«&Ðbøå¾*+m¶ÓÓÁQ¨Ö§NõUÝU{ÕUUz©¦hN”ý*ð¶Rݪ½ÑÊ/÷C"ºHîÒZº×õ~ò*s=ŒUV· ×dW)#ëª>E<¡·ÎñÖwhÊð­‹S<I_*®O*#¢ˆŽ™«]{2Ó¼ Q) ¡Ï0Û6A+ÖHq¢Ž£±ríº³•WdEÛmÓ¼ÈØ±ë/l†ÉŒÙ(-6êtÚJfA iþkˆÔüHdmF|GêòènŽßõž‰•u´QÇ"«S+Ò8Õû*/#UÜÎDTUFª"î¨SUÒÞ$-úw›k'y,59ÎUo±×Ûm52SEfeO3‘YÈöƲ5¬]ѱ¢"·Öwymø»ÓÞ­èK‰cºkË[ }¾»ešX%l‹wzNc^Öïöʆ§Ä>ª:ÅÃ-‘öœ>hóê:«Má-2Í_lOFÊœêôfÉÏ#·æMÚž Ð F’]õSCuFϪóœ{*µÔ\±›Å{\µ°Ë+¤§•Êç+‘׮ꪞ§/.êÔ´ÅjÑ=Ö‹ÖªGÄ'7›sr*;|–ë&?kÙi­qIÑîW5ÊŠåGH›s?~}Õë³ZÛ*‹5ïFÙ©Øû/äîµç8ò:¯»@îÎXªé$.wþ­êœ«¾è›ól»*,¦TÕ4ΰÌËñ÷ò¼M¼4é]3枸˜é‰ŽÂbf%è–¯Eª¶¨î–¹,¹^?+hr<¨­}VËé5U{'ò¹X«¾èŠ›¯*©#ÿˆ EF“ä´|Pâ4556¤Žß•[¡“•·S÷bH©·Y"zÄä^횊½N–ků!´Ñßl•ÑVÛî2¦š¢'nÉczn×"üh§ªé•O)m3¬Ëyž,]Ö4ç¹\i½o^zF±U3<é˜ç1SìÑð+)Æ,Ùž?[Œd¾qAp³™›ì½×"ø*9ȾÔB¨i®KwáŸU«tï5›“ºH’%K‘yZÕÝ!ªoNåÛ‘éá²ÿ#e¸„QÄV‘Å©ød“Û b_¬í}MÛ,“µåu6þÇ®Û{ðU4™Æ åqN3 øÛ|c¶:iŸïÚšì†s‡±UÌŸ3ã…Äp«ö*ùµÇTÄé¯fšë¦‰\÷…bŸ%¶»Mr©eKí–7-<“ªóÔSµÛ+Íÿ9èݻը=)`Œü6Þab›ö¹Oªzb{š ó&Ädêð8˜ãO)èª:*ŽÉG.p Ƥ!Œ‹NòÛWø¶¬aÔŽšÑy²ÕØrö6V±#Š$íhê9^äG»µTg£é£{‘Q]´Îo‰Ï³÷oÖœZB­ñ9öcÃ>ãMúÓ€·à—úŽùôy¨ï‘@ôsã‹ÜÒ·Sø¡³éÕlczW@Ë­Æ&9\¼Õ±ÉdM¶æŽ.W·mùUÏ뺪'@ªª`¢¦š²¥üÁ¥‘Û*òµ©º®ÉÕz!Ê=%¿\³öeÁ{d¾{žä5—f¬ïGÊÊTg.TDM£k­DM¶Ûm‘vM6}‰œ6 ­Þuy>ž~­Rý†Ëc2έÅqäÑåÏúyÊa¿jú8÷p½–Öi_íÇê%ìñY¶É ³¾8a½R³®VoÙóɈ»#œç""è©É­l©ºã¸í³R±Ôb^p;ÍCDõÙšS™ª«ÑZ¨»«WtTnÛ/D:©Ž_hrŒzדZÕËGw¢‚¾ŸŸnnÊV#Û¿*ªo³“¹U>5:NAŠœN ˜«<=½Ovó-Œ»9®h)¹åÇ|óÿ”LùÙºC wQ²va:{“ær.ͰY«nŽ]Ú›$>N÷tOWǧ´lÃ’K¨ºó¬Ú—$íž¼¡ÖÍšêKsÜÍܽÞW.È›®ëÞ»&ÊG\?ZßnÒ›5Lû-UÕ$¹Ô½©Îùž¯æ^TOµVü›màH§-ͯxümÊûtôpûOl®à96ÏìÄÏ}^Tû@®oÀ ›^jqÜ2ýQÅ •ËeUdL™ª±¹ñÄç5ˆ¨ª›¢o²§O4jÚ«ö0ËÿWþ®òõŠb«´ÄòÖ=¬luu[ÂÜ®™Òb™˜ôJáÃXïÞepǪ±lfÓL–ùkÜëU  |’¤±7ÒU{‘Siá¾ûu"N!µVñ¨Y Vª‹<¶«}šI›M ª½¤Ê®åY]º"uäèˆ:õ]Ìïÿdû—à)ÿX§?N2¾ÉŸÀqo95³fÅŒæmÓGÍÖ;8qô¸¾/Çl|_¹ztߘª4*5#^ˆ‰ãÛ'¤zó©þ{ˆàÉ‹[–ÍÚQÛ<ëÌj;O7ݬççí97åë¿.ß1ë^¸Úô’Žž–:/t/Uìs驹ùYví$^ônû¢"wì½SmÍ‹HþŸàJ?ìZSî&ëj+5¢ûüÈÚVÓAWÁžo¿¡UÊ¿Œ×a¬aó\Æh›{´Ó¬Î“ò¸éö¤YŽ70ÙmŸ¦õ7æåw&˜¦f#ȉ§^âxG [ŠñI­±R·#›¶¥¢G#[2Ûjzí²KÚm¿‡?hö¯ÙõnÇ5u%*ÐÜ(\ØëhÜôw"¹7kÚ¾,]•Uwj§Æ° ÃTõöåŠÍ‡M£¬e®z% ì£ÇëS’.NTåôöEDÛeÛ¢¢w ¸ÖgŽg÷%½ã{uM¥íY*襅‹#f‰Zˆç5}•ý>Rö?‡« ]ÍÊhªž[µk¬v°ò<ïk5³b/\½jç ·èšwjë‰ê×Õæf/ÜTä8®§Ý1»Õ–Û-†Ù]QL÷SC'¹ŒG#6s¤äß™¿£¶Û÷šŸç‰p¤ÇìÔÖù^îÂ)©¥z9©à²s·™SÅSoѳûtWz»Úgß³­ÉLý—eå|èÕëøËAĽ¢Û†Ý¢ŠŠã¶-Ò1ŒDl?ÝÇè¢wzrtðRõË8 -xz*³7"#»—:õ–%Œ^y™ÙÇÞ£4S‡šªˆÓŒé¬é¯ ""žøÊ>®ãiñš&ر6»%™ëDSs>•›w9œª6þ®é¶ËÕz*àñ¾0sJ;Ôpfv+lô /%BSC$3›쪛¹Qyzú*›®Ûn‡íÁ…–†¯ ȯ³Ó±õ6újx`{“u%sù•=Š©&þÅTñS]âæ†–V54,õ–ºyæV¦Üïæ‘œËñò±©øvð™ÃjËâÏFºëǯHóJÍüÓ?ŒšÖ8¿»¹ÄF‘3Ï\ÌÇÓ»©tiê!«§ŠªšD’˜Ù#zw9ª›¢ÿAúæ›Èùtï–G+žû- œ«â«7Sc!7)Ü®iê—gÃÝñöh»ùÑé€x] "vœñE£Z‚²¬tU·y±Jý×f9µñ¬pó{²*¿ó~ˆgˆßˆ(k#ÓZ«õ±Ñ¥v=YIx¦íŽo<35zïñ+—ãîñ6y=Wnžžj9µØ?‡d˜‹]1Nô§Êûk;¼Å‘ãÖ¼†] wJ(+Y×w1²1UOæØÈAó(s7Êï–Ðÿæ¿hFtÈæo•ß-¡ÿÍ~ÐŒ™±áøÍ5“ð†YûU§SŽXð‹üfšÉøC,ýªÐ:f@õZç¯×\Òàèêq]*«[=Š69U•…cU;ÓÅbݬo†ü®Ozâ QãÒÝ$È2ˆª]ÉÔ΢´£™ï¯™ò·í¶róª%Ž?} Ó }"Ó+>×6JØ£Z›B.ëQ['¥3Õ{×ÒôQW¯+Z]§È¢jëáïI²ïÿ•ÝÌuÒåÙ›Vû#H›µDý¦Žë•u7àicl&?•P-Ó½ÐÝhÒY ZŠ:†ÍhÇr¹¼ÍUMÑPÉO“=úuÒË¢}cxÈîýûTrîž¶Û|Dì{®Ê¦–Ó;ËéÊóØ:'X¢©ˆ™éŽ€xjÀ'‚ ¨$¥ª†9¡™‹‘ÈÔs^ÕM•ª‹ÑQS¦Å~Ðú­.ÔŒ«†«ÝUKèè/¸|µS,Ž–Õ&Èøçm¿dôÙ½Wµðj‚ø¢·ËŒRãõg ž{–žÜ™5cißÈê‹LÊŒª‰W™»ôV«wæDô·j£œ]·ÇZ'§ÛГlåt⪹“Ýù8ˆÒžË±ÆÜùçZ'ök”è‚¶–çCOr¢—´§«‰“ÂþUNf9Z»/TÝ;úŸ¹i˜šgIæ€ ±Ä–˜Ýp¼¢\túšVËRUÝ‰ÌØfjµ[7*uV?ÒGø{}e'=%ÔË^ªaÔ¹Ç Z'e_HEu4éÑQ|yWnfª÷µSÇtM²ão¢»[êmwvTRVBúyâ«$ojµÍ_‰QU }[ û„í\ZÚ%©ÃïŽF7Ÿ¯iOº+™¿þ¶%rì«ë'_¶THÎ"'#ÅN.ÄÜŸ.?6¯Îþ:V_];m•ÆUvó,DÍ©Ÿý”G;s=qó{#éJäƒäµ]m·Ëm5âÏ[]\i,Äîf½«Ü¨§ÖIbb¨Ö99½tUn©¢¸Òcœ¯ ñܵ˜&¯jî‡UÄ壤»·/²ÌéÖg:–âœÒÆ®^¨Œ‘½9·r«Ÿº¹¶[âsìdž}Æ›õ§«|N}˜ðϸÓ~´à-øåþ£¾E=_ê;äP=…¸ÐÌ$Á8XÔ¼†;9}–‚7z=TæÓ5}-ÑzÌ<{“®Å'Àm>ààøý™[³¨­”Ð¿Òæô›QÝ~]Ë%å1¹ÏOÃS,²C’å6{UCQW~϶íú's½(›/N»ø!ý¬¹ÂÕ¾ùö:{…}-®‚¦ç_2EMG çšEîcÕs—ñ")éÞ¾`º›}¨Ç¬ ¸ÃW N™‰WXÙ˜ÕDUbµÎö§EÙvðè¦í“Kmƒ»My¦uE¾:ÝW Su’Êö§Tê­Ý;Ѐxx¸hlÙÍT:}bÉ¡»IG,‰5ÕbtqCÌÎf3‘ë×~^ªŠ»oׯ]ž jîíÊéªfžS£½ÍsN2Âáí\¢š+™ÞŠµÞŸ£ýóìYUN'5¾–å%6ƒÞêØû}Sßr©¦{âNѨ­lMrl®DUz»ÃtnÛíÓcÒž&±Ú1ŒãEÔ]äJ{t•.Ž'Æéžäg2½eæVí¿Ä]œ“ðjqëѧ޹cS¶ydæ5åõWéåkÂj<˜Ó©bÌóœc³º÷”Ý#¤§Eå¾´“?oQN®_“»½vN¤EõdéÏvCùaÝÚö0ïÿw´îü{üF/Åb©ß³DÌ6øüû-Ë.E¬]êiªz&xú#—=ƒ‡f¸Ö{fe÷¹ÇYJåä~Û£â~ȪǵzµÉºt_j*nŠŠi5ÜF`¼ò]?¹År¤ª‚¥ie¬™‘6‘ŽåßuzÉÌðß”ñFýʪ¢š'ZyÇL/_Ͱ8{t^»v˜¢¹ˆ¦uá3<´”¤&ãÆ›QÜßGMj½ÖÓFõbÕCh×íöÌkžŠ©ò쿳Öq!¥Tx>[îÔ“GR÷E LE¬íë5cUN]‘Sªª7ªl«ºo~¬¯FšÛž<¸0­í>O{sG“Æxô}¾mRx!{‹4½]"¶×R]m-™üŒ©ª‹ wîçV9U¿.ʉâ¨I¹7Eݱ‰Â_ÂLEúfY¹~m‚ÍišðW"¸ŽztwÇ0c6 vIje÷ºØåg3.4SÒ9»íºIµS}ÓÛíBÙp —Ï™ð§uµ‰#jm´Ùdcܪ¬J9ä§bn¨ŸóqF»xo¶ê¨ªUâiòfO$z-™ãîj$Xþ¢^­í¶ÊÄe<žž2»ÿâLvNç¶û§Úä~0ñ»†¿µɵn€ÉÇ€v¹q‰¤=æ–|P=ÜZë½"W¬´4I44”î‘ѶIU^×*+£“¤m{½Ývï)áÞ©í6[‚äTW«E^éU,œÍæNö¹;Úäñk‘§\9bwmfó ¤w*tÍ>ûû~»Ñ:ñ…ÉýòU?ôµŸ¬´´L¢®ˆd›öŸëp’€=b3ovÅÍÍ<^<ôÓ³‡.Õ¼Ê| Ãøí~½ÇwMÝè˜üé×M{s‚á³ôh?Û9ªq…öS£ü ö³8(η3 ±ÛœãM5ìˆç§gRÅÝŽñ™ 'Žù3®öï?*gäïvéÍ­iŸØßü Cýƒ ”Kr¿\××)Ž׈µM­u݈Dh  ­jm³Ý:Éí‰$|öжÆ×.ÉÚvNV/âr"þ#e?ÚfÖÑÏFý¹g‰Ñ.íÝ6r*wx÷—-Wâ릾©‰YÄÚ‹ökµ?:&=1¢ãðw‘Ë•p·¥÷yœ×HÜfމîlœüΧg`®U_¶^Ëuö*ªY¼›—/t¸3À9æí%¥÷NšOGn^[O+{ºìÅg_ü÷,É×ß$+üüspóA« !¼äÕ6«²ªZ‹•t †ÚÊ¨Þæ>]è+U«»œÖ³Ã›~„ý‘Í&†F¾7µ×5wG"÷*/Š‹òŽiÒç_ª2«m¯ÍlÙÌ+u‰ì]ãuj*6­©Ñ6r½Y+“¯YÑwëÊÝC‡ž3õ{‡®[Eª®;ö2磟e¹½ÎŽ?jÓȋͯŻ7ê­U´§3|¨ùmþkö„eÒÐ.)ô—ˆ{k]‡Þ›K|Š.Ò®ÅZöÇ[ÈœÎkwúìhª‰Ú3tê›òªìRß*¾[Cÿšý¡29cÂ/ñšk'á ³ö«N§±áøÍ5“ð†YûU tÌ ­uæºç¥:I4ÑÖK™]cEzrÅJŠ”¼Û"µZé‘è¨äûTMÓ˜žHJ ‡$âWó7HÙÛf‚×ÐÉÌ®ìÛØ¤•1¢î­O¯1ª¨wïD]÷žK·8iOT{x¤›E¦œ.Ÿýv¨™úWcÆÏ¢+¦Ÿô€Ò6øLo›QꥱÕ]«¨µ6ù"¯ToÖv]·èЍåùw'‚ášf73Öºák<òª}ÛÓu‘©¿O•ª»øîO%Ûß.RM®×îÅÚ§¦(ŸMÏÚ HØc2Œ~‹,Ænø­Ë›Ìï4úŽUT^ÎhÜÇl©²÷9L˜:q{·r«UÅÊ'I‰Ö'ªa p‡’W]t~ Vö­KÆ_S‹×3šMÚêglÄÙèŽM£s·w¢½Ûr¶k ½.‹èc‰½ZÆ;W¬ÚKNGJÇ;£‘ñN©¿UÝûuNˆˆ‰ÞN…Ë¿/Xéãéo¶¦Š'4¯j4¦ìSv#«ÆSÌyªªcÌ hðjz›§6=OÅ*q«ÌĮ²RT}µ4芑?§eOUCl»¶¨¿DÛ¹Äð˜daqW°WéÄaêšk¦u‰Ž‰…NÐ]DÈ´‡0v‰j\~gFùž”SLý™M+·rr¹z,2.û*w=ÛôÝÛ[â3E)µ;}òÓ.Kg§zÒ«S­\I»–ÞÕUæäö9ËÜŽU5þµµÙ5Ze•$±_­0¹”ò˾õQGÑZíú¤ŒNŠ‹Þß½à/W•b#-ÄN´Oâꞯ͞Øèÿâ}Ÿa,íNv/¦"í<1GDþ’;*éôÏ*¥`€‘Î@û^çÕŠ]'¿Tè“iÝ—Ã d¡IcdŽV£ÑdìÚôV:NNnTr**웟ÔknMwÀ2;fušÛ©µÔÇkª…XŽŠ©cwd»½¨œü¨«ÓdUÙQvTÑ4o\¬9/öm_Íotvبí»_ª%z£iêà^ÊtsU9‘Ë#wFl®^v£y·E^wRùA¸¬²Í%×*¡ª¨ÏŠVVØé£{ŽêŽHØÍœ›*m·Ê›‘{¬ù¾E%’¶ª]†KEÙl–Îxh¶wsK7fç9UÊåUDUV±¨ÄcUPèGÌ×z¸i¾?‡y¾2Ê êhn2=Þu#¢sS´•ž«ôwF÷¢òÉjŽyy+0ÈäºgZ‡3[ÏOOKe¦_¤rÍ2/±>µËרt4Vøœû1áŸq¦ýiŤ*ߟf<3î4ß­8 ~y¨ï‘OG—úŽù@)÷”æ¦HtO!lªÈªu6ÍÛ5ªÎ­Þ?Z½éÜC¤ßå2¥ª–‹2£YjÍ,Õ“=S£ÎøÑËÓdô¤g~ÉþÅ„VÖGá-OdýŽÏநø>&žÚ}’‹«09÷÷‰‘þ¬þÅÅKá ì¯7àŠÓŒ¶™÷÷‰‘þ¬þÅÅKá ì¯7àŠÓŒ’å_ᘞï±Î6£üÇ–÷϶ø±Å1ì_3¶ºÁkЉn4’UUvj¿]•evï]Õzü„Õ£ZI§8.)•O‰Ò>ì´°VyÒ«ùûdTr?¿m÷D^â3ãF‚¡™7sXÝØKE4íºsµèåMý»= ƒHx“­XŽ3„×ÛnËt‹±¶í 1º%U+_̯EÛeE^›¢ïÑ{ÌËñŠÄe6fÄÌÏtžŽ<ÚœYfj±”c¢ŠiÒ7bb4×Éž9£Î-rJ»®¨:Âú‡:–ÉKqÅö­’V$wʨæ'ÈÔ=;;áÁp¡DÓûϺ^gÈ—?5ƒ·ó®_á{N×›n~¼½ÛtÛn‡ÙÅÞ_kΡÌÛO½¾õq,­OV¢&ò«]ìUb5SÛ²ûØq Zá¶|r‘r½=µQÝ¡…±Ô±¶8¥l²""+ØäjôUë³¶TîëÞ¹–柹ö*µEUDiò'N=:õñÕ¨¿Ew±Öñ7mÛš¦t›´ëLòÝ™åäéör`x9½ÖRç÷+ Nÿ4¯¶¾gE¿£ÚÆör»ñ5ÏOÆhšÙK-nµdtpmÚOsH™¿w3‘¨Ÿí,îŠeÚWšß¯`{Ieuª(›ç©E ÌÙUÛ¢#Uõ´^«×~䨮:›ï‡¹~‡ô˜0WæîgväÑ4ÎäkæêìÐÎ0Tá¶o b›Ñv‰½:U駘{uL:à{‰hýmÆÇktw[D•ì¤~äöGµË<)Õ„ÃÓÓ½>Ïê‡þ¨/)§ÁÇóEä§ÃF¯q»–êå¶Ç­zwWkÄæ§©uUT¸û©7¶':/®/r«Ñ©·ŽåÎáÅCGÖÛÖsŽéNK{ÓKl•ùE%¾×M*Ô:Yùšˆ‰uwE^†ðæ÷Õå4ø#¸þh¼Íàºñå®Í±ê,«Jká²Ô]i"¹HìUñ£)]3RW+“ÕDb¹wð: æ÷Õå4ø#¸þh¼}P^SO‚;æ‹Î€5½4¸d÷}8Å.¹­©2*Û% EÞÐöKkàc§b³í$W'/†Û Q=iÖÎ>l:«“Y´ËM+ëñj:çEk©n0ùÒXQg$Ÿn›ïÔÒ¾¨/)§ÁÇóEçH@w Y>ªåúEj½ëMŽKNY$ÕL¬¦’‰ÔŽF6g¤J±¯vìåêä¢+‹mQã Ô{m«‡ì®õŽËd†¢¦¢+«Qµ«<í{9Ó¹R6¼¿çoâBT”ÓàŽãù¢ó¤ óÁþ{ĆujÉ¥â'šÇSGQLÛRKjZ™Žkû^‹ë"*3¯†å† ïÆwÄ– nÆ*8vŪosÕÍTË«!µy÷fÄlkª'Vî«'_³}P^SO‚;æ‹Î€* š±ÆNe©ÓYµë«´cKjžXêe°>©¯‘½§vêÕ“¢÷–ô#n"òMÅto!¿hå¢K¦_KæžçRGFµN“šªË´Iëm¤_‹mü OõAyM>î?š/:B¡šC­ÞP;Þ§âöAÒúÚLj²ç7Z‰1—@Ø©œí¤zÉö»&ë¿Ä_0ÆeW*fï[e…Ó\)èj%¤±¬Šù›•F§W*¹6ñ9ãõAyM>î?š/:Båî¡ëW” Àò6 iéUÛjv}N,袎—³U’GHªŸ+Q]Ϻ+U¼È¨©¹HN¬yLu²l I¨ôÆËSÙÝ3§ÉS˜ôæŠÝ µeED꣜Æ&ý©*xºÆ±œ‡1½Òc˜µš®és®•°ÓÒÓF¯{Þç#Q6NäÝSªôO1„ËA¨šÓ—heßÈîw[ÖŸÛn¶vÇ-k–FQV­\iÌïIÑ,Ë٢율¨ñ¶ü9y2(¨ÙnÌx‚¯’ZÖ=³ý Ò:5‚5kº6¦v«’TTïd|©þ{‘U ÊCŽÙñþê(1ûe¦Ód½Zde%%;a†|åËlNTMÞ‹²"'yæ¸Ö™ˆ\µ1MÊfzá €<úäÇÞ2=rßï–ûk&w$n«©d(÷{\©ºõCÕ4ÍS¥1¬¼×]6éš«":eˆfŠ¢&O¬’9ŽcØäV¹«Ü¨©Þ‡²Q:ñ€|ÊqœaÉ’d6ÛSj[ÖU2‘SmѼʛíºw{JÓMUÎí1¬¼\¹Eªf»“Ói>h®Véëf¶Ãp¦’²™é©Û+VHÑQÍEÝ7EM·ö…b™«]#’Í[-ƒŒ-8¼Æ’#r¼jëazµé²¶—z½œßfîO•vöÁë§÷&¼èEßëéÙÝnô|Ñ÷}~•ÙWãåö÷stRtžx)`’ªªhá†,’I#‘­cQ7W*¯DDN»—kãM3ÙöÊGžDÝÁå÷zfÌÄ÷Ózí1ÿØ~€ü©jéké㬡©Š¢ Sš9bz=Oj*tSõ-#“Lé (³‰-¼SÜÛ¬Ún²RÝ-è•é—–Eäê•,ö¹£ÓÅmù·²`ÂÇàmæfÍÎ1=1= ÖCžb6¼?Š©žUS<éžÉõO[ :ÍM«XÂùû¢‡ ¶í| è’'ÚÎÄþK»•<ŠÊÕYH¨ºË¥—Ý ÉâÖ/•iím©GTS5«ÉHç»ÔsSméÞ«Ë·M•Q?’¥Ó-KÇõK‡#±¿³©WH÷¢ÉK/‹·zx£¼SeéÕ*Ç]š§ávŸùGçGÛÿÝ7›Q‘᩵Ny“qÂ]ž]6«é¢®¯ÙìáÕ3¶€ â­ÜWpkŒñl[ö0Û}‡8¦ëÁñ«!®oŒu\W/ù²"+›Ý²§C•º§¹†—eU˜^ueš×v¡r$ɲ£š¾«Øäݯb§Tr*¢¨ÕrÒͲI|ÔŒ¾†ÔƱ_3žŽ©¨^IÖÇzNWvOF÷"ªm¾ç5¸³ãgâ6ª,?Nt!o“Ò/%¶ýrí›pG+Ót† g#»5Nm›$ŽEWµÊƹ»-&b#YVšf©Ò˜âº~OŒ+è?†k%dŒä¨É«*¯s7}öæzCïÌ©Ö("wM¶ßeMÑUe<ë_tOLäu>yª˜Å–¥®åZZ›”^s¿ÜQVM“ÅyvO•â¼dê}Ї¿ç5˜¾/Ai),ëq}-44ѵ‘µ‰OOºÉ³²,Ê®vÎsœªõs²8·Xµ²|¿-¯¹¹wCGi£ßdôUʯs‘›ªrªîÛ.úÛÙ¾Ç ¯Yìãý<ÉgÝ&›3LuÕäú§¢72ò ð³ŒvñÙn¹S4^‹R×js÷uî}JÄ›"÷ªoíNbÈü°4 SázUQQ+vl—ÓXŒ“~‰ÙÇ•éÿ]ª`,7h¶=Êê|’²TÛy+Þú®eMú«dUbwõDj"ôöÕ«ÇlLlvK¶ÞÖ&Ím-,q#S¯DF¢mÞ¿Ò¦¶æÒÚÅÑ3ßÃÞ’aüâëü¢õ4÷DÕíÝF—)/ùc•˜.ŒÚ(©äjrI’º²Vª¦Ûö‹"G·¤ÕêÎ7UC WÄß”£(—²·M-¡’Æ»²5¶ì­O·¨j¹«Þ¾².ê¾ÄÚw{Kz~EúϹ·µàß½T÷DG·Uu~Så¼9έÔÛÅÔ5Zý®”‘#mº$>ªôïo]×~óã›ãÒä­¨©â $ü¼¼ŒÌk¢ÙW½#ôU~>þâËÄí.yE1æþ¬Ú<e4óšçýQöS ¿.Žq‹<¯šn!+¤’G+ž÷e—Esœ½UUUTóô—ãü *ÿ:îŸ0´@ññƒ×…ïˆY?æÕõ•wé/Æù@UþuÝ>aõÉñãE"UCÄ6K#ãETcó:ùÝ;¹_è¯ã,¸+AŒŽ¯CÌìO<¢¨ÿWôW*;ÿ”fÂ÷-¨Þêù^ÕšóORUnÛ"O¿ô/D^¿”¤â?ÊW‹GË[[=Ò(œ‹Ë5®ÙR»ur§4-çr/wzªtDØžAv£ÅG:iŸ4ûØ×<e•|‹•Çž™ÿª¤òñ‹G$™vZj d|«5N=]M³›Ñ_ÎÙŠ‹¿^›wm·rí¶O,°HÚ\ÇAÛ·i- õQS»}¢’ô•7±>3t>ŽËz²¼ÙèkÙÓÑ©§d©Ó»£‘Lš6š~}¿DÿFº÷ƒj'œDùé×ׯï‡ùT8cÈ^‘d-Êqguæ’¾ÙÛÅë"&ËLù^½Q=W|[Ï8'ú©rÇM„êî1qª™®s(üýÕ9­ß™R ydÙ9U}^í—¹QVŠßxtÑ|?º°: g"WRm×~蕨¿ß&à— ®ÏÅr‹ªnômKUM“‘Éà›ó.Ûw)Ÿkhp•ð¯Z|Þæ‹àÿ5±¬Úškî'×·_AÇ+&Æ~„:5Ò]R¸U[©‰OGKpç…Ší¹¨ê‘aÛÓrò¢97]ûÓr]Ó_*Ž a×ñ¾#tÂIÛNÎÆzëT K]Ú7½î§•ÉÕQ[Ñ®½7EDM­ŒUŒLkj¨Ÿï©ÆåxܺtÅZªžøáæžSétÀnŠñ5¢úÿ@•:o™SUVµœóÚj~±_Nž<лª¢-œÌö9IHÈ`[âsìdž}Æ›õ§«|N}˜ðϸÓ~´à-øåþ£¾E=_ê;äP=xïÆåÊøEÔÛ\0ºWAhK’µ©º£i'Ž¥]Þ!U_‰;—¹j'tKæ+f½#•Ép·ÓÕ"®û¯¸÷mÞ½ÛX<Ózí4MªjÙçðŸ2íx<5ËÔâk·Lܧ„U1Ñ“Î9Ï¥§fzC§zƒr†ï—ãÞW Mžw<[FŽs‘»Fö¢õs—}·êlÖ‹M¾Ãj¤²Z©û *OO;É©»•UvDNªª§ÖW®×D[ª©šc”kÂ;¡Kx<5›µ_·n˜®®uDDL÷Ï9ó€Ó$ñÞ®,³Ù«îòú”4ÒÔ»¦ýÅrôñî,ï“·ªÆ¸DÁÖágYxmmânˆœéQW+âwDNø{%ñþŠU¯W è4êªÅhæuÏ&©‚ÃE\ée©*±åUVs¦È›¯‡]Ž¥`xµ6 ƒã¸MïOÚ©-p¯N¬‚ÆÞäjw1;‘>Dî';+fi³rìôΞþ¸Ÿ…d\ÆXÂÇ̦fÕ?þ¾¶tJœ¸Vx§àvŸ‰I°çrê–­öÆZ«iÛoJ‡K &–Vº7sµåYžÕW#‘6jì»*,»¢œ=én€ãì±éö?S«9*®Õ,÷ ßK›ëÓ5­W"/sQ‰àÔ$¯Ü~X~ˆø?Ô»4­ì­°×ïy—ûšª¶ö}kªø&êXVÕ\]Ù¾—æ[)Ý;¯ö…­"l‰¤Yéß*9Uª¼Ûn«²Ï,bà—|jÓuIRT­¡‚¡ŠªŽç®ß¯^»™2?Ð;Ãoz?ŒU5Ê« ™¹z¢ÂçEí_"§Ä©Ñ;‰äx›~*õvú¦cÑ/¬rìDb°v¯ÇΦ™ôÄH,3+®yƒØ«_m½æv;}\hŠúz«Œ1HÔTÝZç"¦éÔÊÕ\((¨d¹ÖÖÓÓÑÅË%D²5±1ˆ›«•Ê»"m×~â©q—Œy¦KdËaf\)_G2¢tí"víUøÕ²mÿPÍgç¼(YåJ…ó»³`³H»ú[ÂåíÒl=ÓOi½§(¦í›mU3ã'Iìþô”"æÖ׆Æcp¸š"&Å3]<~TpÓ^ýiäŸí9Ö~¬mºÅ˜Øî5nj¹°R\!šEDïTk\«²Eï*Æ1žÇè#µÚ¼ç›±óÚÈàí9væåçTßmÓ}»·B‹ét· <Õ 2órocÁÐÌÕß§›T+¡W/âW/â6þ.27Þµ2Ÿ§r½–Z(áV7ªöòýqÛ|­X“ñUlý? ¦Å5ÌÑ13¯wne{sîEÜuÛQi®)Šu'z5‰ëå½è\;]Ö×{¡Žçf¹R×ÑÍÍÙÔRÌÙb~Ê­]œÕT]•ãE0w=NÓ«5ZÐ]3›5K\¬|2WFc½ŽM÷oãØ…õ®ýrÑÍÅôúÅPúJë…:SOQ ùÖÆÖºuj§TW>DëìW{H·K4§L2¬bKÞuªvû-lò=”Ôi]O‘µ«·<­‘w]×}š›tD]úô±‡Ê,×fq7k˜£YŠtfxófæ[‹³‹£-ÂÚ¦oE1U{ÕnÓLÌDéé¯8ééŽÕÖ¶]­wº6\l×*ZúY7äžšf˶ïÙÍUE î%têÓ›\lµuzaǪ)¡’4§»Õ¶Ë¹^Í×}Ó¹zl½:¦Ä5¢UÃN5Ž bŠù }¦áp[Tî‚^jj”sù#›*¦üܪ‹ìUOlãGûçÇ>ð—ûC+ –WÌè·n¾DÌNODµ¹–ÒXζnõüEž4UM5Q½:k¬q‰Ž:{´â±Úig¢Çð+–Ý{ŠñOIHØÙ] ÑñÏß»˜¨ªœ»î‰ÕvDD?·KÓÜz­ô¬ÖËGUò¾ +#I¿ç7}Óñ¡Õd—\W„Š­–gÁV¶Ø)Ù3gD’LŒs‘|•ʈ¾ ¨¤YÖŽâz¨ËõfSYVå·¬1Ç<¨Ç"È^Ñʨª¾®ÉáÑwÜÅ£-·r›Ø¼UsÓTÇã3¯>®–ÊîÑâ,\ÂeYmšfåËtÕåU1M1»<:ç„Oõèµ Õ}/‘¨öê62ˆ¿Ê»@‹ý íÈ7ŒšÚ;•ƒ¯·UÃUKQ-T‘M ˆøäj¶-œ×'EEö¡Úðû;µ‚²¢¢ªÛîúÚ]4FÈøûu‰‹²¢x*ôîßå&n-¬vükÁ±ûSÊ;zÔÓÀ×¹\äcY&ê½êlpùuŒ¿0±âꙚµž1Ѥ£øý¡Ægù:q颛{´ð™™Þߧͧn­ç‡ŒŸÅ´FÍU’_­ö¸¥ž³³u]C"çÚwoË̩̿!+cù~+•±òcYºè‘",‰IRÉ=û¹‘vþ2 èÞ€\µouöï“Ïn¶QÈú:Ò%™Ê¨¼ïV¢¹¬æz÷w¹]ÝÞº/zA¬”ô,­Ú¦Ñum$ÒGѳÀ¯F¹6ö=‹Ý῵8œ£Œ¿{ÅÝü$LΚpî÷®eûY˜e,â0ºaªŠhŠ·¼©Ò"5Ó£¦b&8ÇOJìêfmG§ØUÓ%¨šÏO’’)‰ÛT*m;×ÒTßoUð# â™eºë6¥døõªzyãm+ež:E{ª®TG¿ÒÙQ:¡‰âçOb­´&¤>óP·Ç(yw‰y¥vïß~Š¼É¿OµB,н ·êíºë]]T[–Ý4q5±@×óó5WuÝSnâΫ,ªýêºxΜc—÷ö³3|ó:·´”`°võˆ¦f(š¢"¸Ò|©å¦šp‰êí]šê+$W mdtµ GÅ<#ã‘«Ü­rtTøÐýÈ+R´{>›Ä1=Ì›A‚–jj‰f®–‘Õö|‹´h¨»r»¿»Œ¾‘B|'S~pU|Ó]g.Ã^§ÇÄsá1ÇŸO4ƒ´9†ï‰ø ué¬Ó1¦³3Ý31æ[b­q•k•V|Ü Á ucQÖæZ•ÈúØús=ò¦Ê›/G7tkSm÷EG/ß§Ú;­–<ÖÏw¿ê –êJ¦ÉSoU¬ŒNôäsvwÈ¥•Ù7Gl›¢lŠVš­e7âºf›¼<Ñ*]·ŠÚ¬ Ú¹áf*xƵGLtp}1ÇXà¡ùN ®zcEY{ªºÐG$bÔÓÝ;GÅ"ï³^¬zªo·Tðßuزü7êÛR°ú”È^Ùn–‰ÛO4íj7·ÍÝTNˆîŽEÛ§£¿‰ñgªöÚÚvi•ŽvTKížé+WvÆæú¢ø»uÝÞÍ‘;÷D8^ÀnVŸ:ºñ Ã[~™+V7•ñCʉ]ñªnï‹½Úæ7~•ÅüUMÉŸ'HÓ‡ÿ>Ä[g°ßsöš¼YvªìSLøÍgXÞóië§F¿*:Óˆº¸`5à¶œ#¹¶U‰Ô¶š¹šöªnŽlNTÛöÛã3ämÄEÆZ-&¼RÒ»û®èè-ÔìçkVGË+Z­Ý}¬çü[÷&ê™8;~;E¾¹ˆõµù¶"0˜ ÷çæÑTú"Wû‚[Ðç Ú]oæ•ݶ?~ò7•ºUÕmìúïEñM—Ä›Œ>Aˆâ´ë-× k¢Ì2[µÎºƒž;­uƪ¦Y%|퓞["ª¯3¤ÝëÕ=Ȼf³]2µŠÉC-mÂá;)©©ânï–G.Íj'ƪuÇ@ôŠ×¢ÚkkÄ(à‹ÏÖ6ÔÝjßQXæ§híüQ6F·üÖ§Æebk¦ÅSeÔ<"æÙ~ÅåuZË­SN'‘1½Å1LÌÏ=)§JiíãÑ)j_(€6øÉÓœ¿Fõ’]PÅïUÔYmDµt•´U2E=5O+Vxœöl­ÝÎW7eêÕTëʪtÒ5ŸL-ºÁ¦÷œâæÆúØÔs¹Už­a‘vê¨Ûtñnéâ_ÃÝñUë<ºSMƒÚxÙ|Ú›÷£[7#räsòfyÿ¦xöÆ±Òæ¿Õ]«UŽÅj2+…5ò¯ ¸û¥l©­‹yþEbÇ:µQeb§G÷ú^ÌUª:ͯ¹=-¦õ‘\¯5—Z†RQZázCMÎ÷§# v=$o¤©¿¢Šç.ÛšnWŒ^0¼–é‰_éû ¢®J:–'Tçc•Z¾-]·EîTTTï.“ûB‘Ï­ÙE¹ªª®¤Ç™+WtDé5R"ôÙwXÚ¿=U]¥É·fŸÜúo?Äd;!–UžY±oz#KzDqš¦jˆ§ª&fjÝ8k+O¢ZlÍ"Ò럥_Kl§_9™ç1õ=ÒJ¬æêŒç{¹Sdé¶é¾æð¥ªf©Ö_c1wqø‹˜«ó­uÌÕ3×3:Ìú@F8ç¸[ènÔ3Û.t‘URUF覆V#™#6Vª/z*û3Ã3^óXóœYjñš¹7²EW5«¿›Ï·ÿ ÿü÷E¹'Çx´[/öº«-æŽ:ºØ ðÈž‹Ø©²§µ>Tê‹Õ ^g–Ó¢*¦wnSÆš£¢}É6Ím%̆íVîÓã0÷8\·<ªŽ¸êª:%†ÓÌþéxµ6SÍÍ¿[ž/§M:"+âÆ›§ÊŠŠ ”§WFÂfm&Agd—<*çSÙ,jýÛ$}íŽ^ž„ÍE^Wí³¶_sRÔᙞ=ŸcÔÙ63\•4u)²¢ô|OOZ9ö¯Mú§È©º**øË3*±:áñ1»zžq×Ûq+ûM³´e»¹†]WŒÁÝùsÒ2¾ª£·Ÿ~±À·D€—q¹Çšèré>¶šçŸKÈ•µCÛÃjG¢+Œî’¡Èæª5wkQQ\‹º4³ZßžM¥ú=™ê#buV?d¬®¥l»r:¡‘9bk·Tè²r¢øõéºô9=Â& Up½ëX¯¹]p’*Yj=%ó‡"I=Bïë=VF¢;ÃÓïUé‹ÅÓ‚³7ªã§µ´É²«™Î2Œ%¹Ó^sÕξ—íŒðá¨:³y~¡q˜^ª®.EZiê»z¹#N­Gʪ䉉º¢DÔè“m‹‰àøŽ om³Çèí56^Æ?NOï]Þõè\ª½΂‹ÌqÙÖå\:£—÷ÞîùNÏà2j"0Ôy]5O§ÏÑÝ@0› Ä並7˜Û_hÊ,´—:GÿÍÔFŽå_å5{ÚïË´Õ4Îõ3¤¼Ü·EÚfŠãXžquTùÅÚ¢…ôuó+·|³ÓLúwJþ«éÉÙ$‹Ýëï²"¢!-r«|N}˜ðϸÓ~´âÒo‰Ï³÷oÖœ¿<¿Ôwȧ£ËýG|Š œ0+k^²ÃcÕûk.4Š¿À¶íHÖÇts¡“í£vßlÕè¦tåUÑUº¦Š£I‡Ô¶oQˆ·MÛS­5F±=q ð¸bòŒŠÝ‰c× –ë'--ºÓÉ׫¶NOWdOPõM3]QM<åâåÊmQ7+"#Yž¨‡Ù¢X¼Ú¿Æ/gŽ–ylšY²[¼­•cck¤j%k²zNGr½tݽ§‚*/JÊÏÀ—Ýðvs˜ÑKO–jE|™Î9¢ä’žz”þÞFÂÖ½î­Yžž˜:®_…Œ‹1Ñ{ú}o—3ìάã1»ŒžUO£)õDkÚ Æ Ê|KŸNµCVô¢dVÅŽåÕ4,z*=´5]¦Ý9Zcåvè›*¹vÝ»)º™Ž2±¹tû‹Œ_:dKf¦Ød´Ô+¢b±µô;+UŠŽMãtMDr.ë¾Ê¿óxs›ílcªžŠ´Ÿ®El>1¹%ºzmÌÓ>n1ꘑ3D¼PãDzK_S|õY£¸Ç·+UY'âä{—þªÝ×ë…×´àð6IšåSSSíÝ;acZŸ"ÆÿûçEîöÊ[ݦ¶Í\Îzjúy)¦oµjµÉý ¤‰ðOäö¬†«<óøíµqU­7¹]Ÿj±¹Wv˲n‰à¤§%ÍpøL=Vñƙ֞=Ÿß1Û-—Çæ™…Œ:Ó]1Ms¬F‘DëÆc_6¿%ªñ]…G[0zû{yYACî3¤oED…­Xºþ9Ò´õµ»ÄÖ²Xê®N¹ÎÕN†M­wļŒgã-ޝé…>¬b¬Æåºûœøj㫊§ÍûnW5®j§/3wÝ©Þk3ÃÕ.’_+oÒdÞìTURù¬Ü]‡dÕr9Ëü#÷Uåo³m—Ú{ÃgmåóMu~"¨ŽÓ=|¿øµ™lŽ3´ݳGþ,ÕEUq5¢4ÓMuôGÎhüiÙꥷãè£{©é¥©¥™È›µ®‘#s>Mû7ÿA¥h¾i¤ãIQzÌn47Ø${*¨ÙUiË̪DZ¯bªµZ©ºî¾’/wBÜä¸Õ—/²Uc¹ *è+–'*§rQQQ:¢¡^/\RIU$¸þu$îr«!«¢IÄösµíßþê2ìÒÔ`ã räÛª™áTF¼9ý¾ÅÝ ÙŒTçf–0ôâ(®"*¢jݘ˜ˆbfcª:úxt¾ìB46ÉœÙi­º‹_W|†©•”´M­§•^è~»³Ñ‘zªnˆ»¿?ß>9÷„¿Ú&”pÃA§M&_Y–Or­¡I;¢¥H"Nxݹ·s•Ý»l­ë±–ÖúoÜí·¢¿r}ÏðryoÏÌí÷ß´fßë³ ³wk½5ÑLO‰ç:ò5êWcq;? gM«µ×LÅÕ­14ñ™™Ó^}1ÃNŸ‹›† VåI5¥–ÉRȶí­ÝÉÉ¿N~dEný7جZ[gÊnµ÷7á…oÅ\œ±¹+¯ G$ñ9]¶Ü©éòíÕQ:*¦Ýå„Õœ’] Ñû. G5榺 -­T Ø] 7ë®XÑ˺ª=Í·U^»l±>›ð¹ÏñzL®\¢‚ÝM^×>ž4…ÓÈ­G+wvÊÔjî‹Ñ~=»ŒÌ¾å»8{×î×»EuNìÌkÆ~o÷êióì5üf? ÂÚšïXµñLîÌpŽúôkÑ×Ú’ô7@ì8æG[zÍmWû½*¹ðSÛêX¢‘Se‘ÎUæzì«¶íDE]ú®Û|ÍÓÚY ³´æxí~/|‰d¢¸EÙIʨŽjîŠ×µWtG5ÈŽEÛ½®5Ô-[’—P£JeUV¬–ÕY›ôED“eùz|ˆ[ËñXJðà±5îk:ë¤ÏW¹?Ësk9íœã.³bš7f7¢8ùQÓ1Ñ=¼¸¤McÒHµÞ–Áu°eÔPRP²¡Y;#óˆçI>­s\‰²vkíï#O¨ªíþ?ÒW»ç–;ÅbÂ1+f)cê™m‡±IžÄj¿ª®û&ûw™ÓÞqŠÁÓâ0õù3§å¯soˆÙ¯6¯á¹…ŸÃW½¥Ui¬DFœ'Nh®X ,71´e2æ”ÕL¶T¶¡amš¯Dðßvþƒïâˆ&bÏ„áuM}òFòUÕ±wJªz­_ýj§ýß—º~+ÎkÂOцYvÊ>˜iî¥Sê{r»NÏ™wåæí“—d20˜ëXÌL^Í*Ö)Ž9ñéÒü×$ÅemXM™µ¤Ü«Êò¸ÄiÎ&ª¹ÏáË£{ ¸Ž™CSu©™µ…j‘ý­²¢º5r;}ûYÑW«·êŒ_•Ýz%­°fø~W4´øÖMmºKQò²–¥²+«²*¢/Dܯ_Q/þó?ý ÿýÉE´éAs¹\¾ŠýÖ÷BAÉæ=‡'+·ß~Ñûÿ¨½›]Ác"«Ôßšªè§IˆîäÄÙL.u”M:ðTÑj~]{ôÍS:s*xðÓN hF5…±ÖgÜBè®›QƯŽ|¹o¤¬jSۛ۹ȋ·3Qè‰â¼©º*¢›9²p;ˆ¦}ÄÆ{«µp+íø²RÔé)Õµ³9d©{¿oZæ*ø¶¡<;÷»;‡ñØè«¢˜™û#×(G„|`òZíÄùW&)N³ê<ëþ:3çæo•ß-¡ÿÍ~ÐŒé‘Ìß*¾[Cÿšý¡29cÂ/ñšk'á ³ö«N§±áøÍ5“ð†YûU tÌÜ—%°aÖ ü§)»S[-6ÈSWWRôdpÆÔêå_ü»ÕvDê¥Ö¿+޾ºÉ¢XŒ¹5l{Ç Þæ®§ G£œŠô…6–flTMâß™z§.Î öEß¼9i·£—ë5M/"ÉæôÕ^y:56ê±S£Þ›î›z=zí¾Ë· ²]lâËŠ{ÃìRä9fL•Sª{f…ñÑÇÚ1Zt0"1ŒkÓšMýÑUz½W|Óï&¯ùsa«É£³b’³´T¸UöÕ;*nÝ¢ƒ™wÛt{š©×tÝ9MFeŸe™h]·båß‘LÊçäUŽ-íµQfWÇ&èŤµÇ½vUYåb¢tOµUô“§z$­~RmÖ}?®Â¯Z/‘9Ò*OC:Ü¡jÒU5¬™wÙäVíé"«zoºe±$ö%Næ?3Ö ½ÁÍWÇl¶EF¨›uj>GͺïÜî^ï}·ù0¸n¢ìüæ»2¯äß›Î.‘'>û÷öp³» »“}ú‘ ÞösWàîU^4Ñ?öÝl°V1Ø+ôb°õnWDÄÄÄñ‰„ ÃWzU 8Õu­úIz¸Ý®3¤µwX«ak§boÉ"§ Ö"ôNeÝ\åéÑ yXxrº9ÑÞ±ìÒÊäwGËAÑ«vß}ã™]¾é¶Ü¾)׿l}G“†©¦t±Ë—@ÕÛh㺱ZÞžÑ*ü}TÓr/%šÔµSÕ<šÚî»-Æšžµ;ºt!ñëòtøÊ[𳳸Šõ¹]tëÓ4Oýu^Ìã2ͱUãq•oÜ®u™áÇÙÂ#„-^Æ º„æEë-†)ÞÔ^Âæ÷Û¤EÙÊ©µKYº§#·Ûtîö¦óLRÅ4sÑ7ETTæ_”Ž1¿%W«._¬ÊGAm´ÝT–I¥;?ÆHôLN©cÚ¯!Í«­nî}™ˆŠêÔm:l‹ìU_Ewk²«S¥5Í]Ñ?nŒÊ2ìN»ÑOzµhÚA¤¡[¨ieòç$¬³Ò>á ºØUô¹ÕŸ^z7ÐGz#ž»*ªmkì^W ­•‘_ð ÒØŽk¹¤†*j–5Éܟµʊž;t^›mÔùêü›6Ôòv,Ê)ywß±º¢ó|¼ñ»»âÛ¼×oþK½¬îÇs|ºÙ3›èùÄ”õQ5zl¼½“©ßºsøølyøë—^«Zæ¨ïv­®q7ÏoÆ+1¹ã+ˆŠu9G(áýs¬ÏX<#ÊÂ~nȘÍNŠÅU&ûÓ^é%£Vz*¾”ªÕ‡Á{¤^»'z¦óí‹!°eæ^1›å¾ïA#œÖUPÔ²¢9«³‘ÅVª¢ô^§)³%¦}@×Ë‚êU–òœËËÆ–Jí»vMÚ²µWevëÓÕOnÉ^4“оª¥ÊÙiÊñ‹hå»Ùk—±Voº$“S=Z_ä½Q¹SÀÚa3¬6t±v&z¹O¢t–Šæõ®5Ó.î“:!åRÕÌB®;v³Û Íír#ªàŠ*;Œ îݽ›[¨‰àæµÊ½ï:¡Sè¿t›N²}îP±Uf¯Íëé‘•ª£Ñ<_žÄßnmúF:[Œu³‰ áöß f¦eQQTU3µ¥·ÂÕ–®¥‰#Xç2$ꨊôUUÛ¢;möP$ã|Èlͺy%òßi£GrùÅuK ›evÜÏTMök—äEö²Öï*ΧåÑ­£E±ø0š%jv—®Î¶á"ø£ÍìboUOUîèŽG1z•Ö ø„º;"º.I”Í4®wºJ§,-s‘7ä’g#œ¬jr³¢"1=T<\¹Eªw«˜ˆí^±‡½‰¯Åئj«ª"f}N¸g\p¡ÈêjT¤½TµÛvV($¯EOIcE‡dÿOuð܈²_+n…[¦X1Œ2¼ò=Z饊ž’'7nŽb¬®zõðsRÜw‚,¶&Ë“eöËR»uìé }[š›&ÛûïÜ«áÕ{“}µðE§Ð1ñ•_êäEEúÂÃÚŠŠÇ¯_‰Sÿ3Ys;Á[`tOÿL>ÅçXˆ×ÅnÇíLG«]}L_|_iµç6ÜÚLr UCwmî9kâb¢5¨›m‘ˆ­çMûÓvú=l6-åcÑ»¦†Å‹d–«}+)ééèªiåd(ÔDF5¬ôQ7ëßÓ»©ÇÁÎŽ²FæÞäs·ÚGW'3zxlÔOéE>J® tžh•\ò:w÷£ÛWºíâ‹îŸÑòž'i0µÄSTΑؑc¶sj3 œ&ìWjÌLQN÷-|ѯTk3¤p!m±_* ™[)nWŒ‹IÕIn¶‡,håûUZgK²§Šªrü{u'Ý?Öí!ÕV1tïR1ûô¯giæô•ÌuCZk•] ªHÝ‘íßv¦Ê».ËÐäõó¨•$“Ôµ}%Žê$]útE‘ŽMº÷¯'wN±†KÂγâsyÕ™—x¡w;*-uçµQ}F;–Mú"ú-]ºuÜȳ›`ïð¦äyø{Q<^Êç(Ö剘ë§J¿‡WyÁÄ]2㿊}¯ŽÙSœWߨ¨åڢє1ÕkÓ§"Ë'÷D{'s[""{¸¿ú å,ÐíXš‡Í].Õ}mq‘o’M»™WÑ¿]»V±7NTUUMö<Ú ‰‰ÒVìb–)âdÐÈÙ#‘¨æ=«»\Õꊊèz >+Õ–Õ‘Úª¬wÊ«h+cX§‚Tݯjÿ±QvTTꊈ©²¡Qò;&Ân^샖K–!u•­tsuc‘~Æm½IQ7呪oÓÖiqOŽïgµßí•kÕ´5lìæ‚f#˜öüh¿ʋފˆ¨jó,¶1ÑÛÛ´ü𣣲zâR}œÚ:²Jê±~†¹Âå¹å1×UGDÿIŒ.žê&3©xô95X’1ȉ=;•ji½WâÒÁ`’\oMafCx—x[Y¹©a‘z5Y²/ní×¹»7ã^â¿èŽ`š_’kF§V×ÇyzÓºš’©*¯©Š5’~n­ôäl{"§NäDi¿Ë0&íñ^Lk±Ó3<¸u [Kžü3 {–FüÅ35Õ&šb5ž<¦f8pöºmäÑ÷¢bÿ\ÿ\”´…[òhûÑ1¿®®JZBlâàVøœû1áŸq¦ýiŤ*ߟf<3î4ß­8 ~y¨ï‘OG—úŽù@9¡¯z7 ¼@VK,±C§Z«[5Â̼ê‘Ún¨}M;“nXÙ+åW1dÛf¢zSì/>¸èæ)¯ša{ÒìÆ7% Þ$ìê#O®ÑÔ1QÑOùÌz"íÜäæjî×*/:1êü—Ì/:ªOs3*®1ø¹žžº~Ú|ñÑÜ=ÖÀ ¦~þ'8€·`R[|óOôþ¦;¾[,‘ï][QÞm@»ôz9Û«Û²¢µ¯ß«S|.a|Ë/WÊ"Ò[d—lû$b¶Ž&'Öíð/GÖNåèÆ17TUéºuEî^‡pû¢Ïš_lÓ¼m½¬‘oWt¯Yn7 ½½L‹Þªåj"oÜÆ±½ÍB]³™\ÕWÃ.Çù>ÿs”xCÚzmÛœ£ W•?.c¢?7¾z{8t¤€5qdò‡iܹ— ºÕKïzw[O–PH±9Ïki½B#™Õ©Ø«Ü»¢·ëmUDÙÚÍß(òk»! {Oq¦Ž¥œ®æDG5möN©¾Ëº"îQ—ÕRÓWSME[OE=DnŠheb=’1ɳšæ¯EEETT^ó•˜î1ô˜Õ,ï‡Z„š8±Š÷\l]²*,öš•IcVª½ÜÈÅ‘ª‹ë;ª#¹‘#;O„ñ¸xÄSÎŽ}Óý]+Á®m\}x “äÝŽJŸ|kè†ê NæÒ5kJí:±¶Épª’ަšNÞŽ­çXdÛeÝ»§3U;ÓtðëЂ¨¸aÖÛ=5©t”tvê\jéù¾5ŒTßñ–°,.k‰Â[ñTLM=S(ög²ùvkáW©˜¹¦›ÔÕ4ÌÇnŸýW?„H#»6õ¨¹K¯IGÒÀŽFÌ©ÿ¬•ëÌä_DEøËÆ2668ØkQ­DÙÁè,bñ×ñµEWê×N]QæfeY&%¢hÁQ»½Îu™™ï™â FÔ‡Ì2JLCºäõª•¶–JŽU]¹Ü‰è±>7;f§Æ¨[N4ÑúwÃn9_s¥…—ìÑ–^%¼«,µ«ÚÅÌŸj­ab·¹×{Jm.!¹kŽŸè±Ó[k+~ˆ2f±\ˆÛ]*+»7ªo²JôäNž²³ªo¹ÔØ¢Š™ 1¶8ãj5ŒjlÖµ:""'rí™Áøœ4ß«~ÈpŸ 9·Ã3pTO“j8ý*¸Ï¢4Žý^À•Ι¾T|¶‡ÿ5ûB3¦G3|¨ùmþkö„`tÈå¿Æi¬Ÿ„2ÏÚ­:œrÇ„_ã4ÖOÂgíVÓ0»qSÆ®šðÏA5šy=Ûͪ)Vj $ º1]Ñ’T½:Eývõ܉Ñ6ê‘·ÜyÅ¡}¾–éLÔÕ™äð#ª«×’hlmw«Í¢¶IÕ½QŽNV¢µÎG"£Vˆpõêqk™Uå·»…l k_-ó'­wk$󝤸âG.óLíú¯ªÄ]ܽZ×af9Ž)ÃU‹ÆWQO9ŸduÌôDqž‡»vê»Ví¬°ù®¦qÆÆ¥Aj¨}múãVõ’ßÛätVêkvs£ŽG«"M½i^í×IËиzäÍÅ1·Òäšå_EZŒI=ĦsÙGÕ±ªvj£¥V;´ED^G'.詺-°Ò]ÓÆ×Ólv;]$Iª$Y,õRí·i,Us—âõSuF¢'Cv>vÚŸ xüÖª°ùV¶mr×çÕç“Ýk¢7¸l¶‹^UÎ3êa±3ÀlpcXV9n±ÚéúÇICNØcæ]·r£SÒríÕ˺ªõUU3 ªåÊîÕ5Ü™™žsfõžß—Õt÷U醿—[»ÆŽêAœ"yB0½vó,Q[MŒç¯åŠórÐÝž½ÍÜåUdª¿ó.ïÝ9ýÕ­¸ø¶ào%Љ¦Ô=7’¶ñ…¤Ý£¹Q_Wf芋*µ=(·ß–TÛ—dGl»9Ó¿>PYke¶hž¼Þ²«YIbÉ*_éJîæSÖ=W«»šÉW¿dGî«Ì¿EäùÎ =ÂÓŒÀ×½Dúbz¦:&?¬phnÚ®Í[•ÇG@Ñl4Mb× 2Ðla2ÝOÉbµQÊõ†š4ÒÏU.ʽœQ1Î_jìnè®V§SS⇊†,Ù@ö×ßkÚøì–HäFÍ]2'W*õä…»¢¾EN›¢"+•­^F^ïÜ@qɬ-š¢9¯7z¥åŠž¾;m–‘UUUÉ-黕UÎvÛ«ÞäßÅË”Z¢k¹:Ds™Všf©Ò9¶Î%øåÖ%.2bÖ‡Ô㸔³>ž–Ék–VÍpîDck®^ÝËÓÐDFn½«é.ÿ žM¬Ç#– ‡\*~‡mž„‘Ú)¦l•Ó"=ª­•[»!k™Ì¯E^¨ÕM–ÚðÛÂFðùl¦¹SÑÇṳ¦X«ï’ó*¯7W2*òÄÏ ÑÎOYW¹'SœçeräÍœ¿…?<çº:<ü{›Ì.WM>Uî3ÔÑ4ËCô«H(YG€avÛl©#–µ kªçåb7y&Tçr®Êª›í»œ»&êo`k·n^ªk¹TÌÏLñmé¦() @Z×ÁFˆk,5—X#Æò:ŸI·›S;7+÷ÝVXQR)wñUDzø9}ëOÚáÃeRf4ï–áe¡™¯ƒ"²>F:‘Ûú•©õÊußdæêÍÕª¨‡`O΢žž²žZJ¸#ž ØèåŠF£˜ö*l­r/EEEÙQIW´ØÜ¶b™ú:§ìžqììab0¯ñÓIë…á?ÊyVÊŠ‰›$29´ôÙ\låtI˲%dmOIQµj"¦û¹«Ó¤VÛ¶óAÖÏp¦®¢ªbKM4­–)X½ÎkÚªŽEö¢œÕâ£Éëj¸ÑVçºnóK”{KSF¨T7¯3©wõܽžüª›£yWfºàÛ\·†l˜&oçµø ÕOeeºF*ÔZ&s¶|Ð"úI³‘Uð÷*ó*"9UW©e™®6µãpóËœO8ï÷òG±k˜j·kvlÜk%°f6 §»S\í78SIWLô|sFäèä_ü»ÑwEê†HÙ,åUUMEM-eeDPSÀÇK,²½ÈØÔÝÎs—¢""*ª¯qó_/–|fÏ[ä7:ku²ÝêjêêdHâ‚&&î{œ½¼ä7|åZýSU§zmçVL$F9må{·ŸeôaßÕ…;ú+ÕW•¬ «‹?)Ô4î©À¸i«‚©$ŠJzì¦h‰œ›mB×+}&õúëÚ­ßÔEMžR¬Hu[_nõ9Ue}UDUs¹ko÷Š—Ìù¥D뻜«$ÎîMú¢xª®‚ð¥E¡eEéÒ?ÒþIka†*x™28£j1ŒcQÖ¢lˆˆÈˆFóú›36°Üg¯£Í×ìïtmžØZñ”Ӊ̵¦‰åO*§¿ª;9÷"=á›Lp6ÇQ5©—Û‹J«Œm‘äW+U‘¯¢ÕDr&ýzµ«ÑP–@"w¯ÝÄU¿v©™u\ —ÛñXZ"š{#Û×ç¦P^Ì4ÿ Ïè’ƒ0Çi.q3ÔtVÉú5Qìÿª¨UíMàÎ÷n|÷]3¸%Ê›uz[jœŒ¨b%’/£'ýnUÿIK„ ì&cˆÁOàêáÕ<¿¾æ“6Ùì¿9§ÿ&+ó£…^žžéÖ׆Þ55‹† £qº¯8½b±Î‰[ŽÜÜæºŸÁÞn÷"ºÿæì¬UïnýS­ÚÄ™ñ ˆÁ•iíö)ŸÈß>¶Ìäme¾UDÞ9£ßtÙz#Óv;mÚª…Õ­ÂõfòÜ K}é¬FÁu‚4Y[·rHÝÑ$gĪ‹ìV• ‚»XøHÕZkõŠá-¢óEÍæõQ'iKp¥UÙÍsW¤‘»dÝŽMÑQÑr"¤Ï/Ímcãv8UÕîëq½ Ù|^EVý^U©åT{&:'Õ=ï Þ¸­ÂøŸÂÒåmX­¹=µŒmêÊé7};×§ký_ —Õw‡ªî½ó‘´F@E==]<´•pG41ÑËG1ìTÙZä^ŠŠ‹²¢•[T4-Ó …Ú¡¢sÏ=2º¦zWë”­M•ÈÆÿÎĽwbõDM¶rwZÐkó ¶ÎcDSs…QÆ*Žq=þA´X½ž½5ØÒª*+¢®4×SÉèîÖ&Ñ$l“  ŠX-y>ܽŠîØkÛ ª®Îö±Wg2"í4&¶pÉA—Ìü»O{ >Cºy!;8«$N¨äTÙ#•U=nåUÝÛ.î5=0âjù‡×&­ô5°ÔSIØ¥Îh×¶‰7_áÛÞôö=»®ÛnŽõeŒÎö]\a³OôÜèžþ©þûfKÙ¼ÐÙ«2ÙžqÆ»òèí£ó©êÓW&-8>keÎÝy ‚éi®‚²Ž¥‰$3Âô{$jø¢§E>’EF°çµSUM5F“«ÈãcÞ¥©Ÿ€äý6Kƒÿ°Å7á ¯ÒBöñ±ïRÔÏÀr~› %ÁÿØb›ð…Wé!¢Ú/ÈãéGÚœø>ÿŸ¡W¶n¥ènŸj›|‚Ö°Ü‘ˆÈî4Žìê‰ÜŠ»*=Øä]¼6 øy× ®’ñ¤™_º0½ÈŽŠí†W¦êˆ²A.ñ=6뺯D-ð"Ø|ÊþŸ®õ=SÆ;0Ù¼asÇÌM>‰Ý«ÕÏϪU‹ìï¬u“V0E|Ð*Fù!Ô•©·2º7î×.Ë¿£ÈÞ ¹+ãUhÖH©·ùìÓ*¢6;:Å¿DëÎÞhÓ¿n®NïgRP»Xì·úe¢¾Ùèn4ëß];&gý×"¡dœ)èÆC»á°ÔYæsœçIm©t{ï¿NGó1uÝ6jw"wt2<~]ˆüe¹¢fuD°#´8{ôÞ¦:.DÄúcŸ|ÊN´dXþAœXo¶û”IöôuL™½È½ìUðTþ”2%X¼ð@È^êœGPç‚F¢öqÖÒn»òøË“m×~æw/ŽÝ~èÏx¬šÃ¨¯FÈŽkz•èÿó•• F|¨¾Ï§Àp—?ˆõDÃ×ÝÌ×À«¾Š¢¯W5¶HfaÆ®6öÇpǪnhÕFì¶êyÑvöºŸe_UzïãßÕçÕC¯¸ÿ£•i\Lk{Ö[]]+¿¹Êž-ðÿhûz¯Å×M]Õ)ñÃGãí]·ô¨Ÿ³U¸LŽ;­,•ÏLbWµ¨Žknn‰yºuÙÑ;dø¾>ó'ÖU‘}<­c<\˃©ø•‰þÓÌä˜èùž¸÷®S¶™%_û´ï¦¯åZV¸8áÃõJœ.õv謖'®ÿ"ª´ýþ­í?ÿòèƒýáârŒlëŸRômnK?ÿq‰÷,h+\üpáz%6z‘»uWË‘Ú|“ñÍbkÑ)´ú¾FíÕ_^Æ.ÿ"1ÚV2|tÿëõǽ歯É)ç~={–|2~9®òÇnÓ(™+·jv—WK»—»dH[ãáãñ›¸ª×Ú6³èRv¦«¿’àïWßNìzfV®ï±cð¥MúõAm…QU$«©d-Ù6Ýwr¢tÝ?¥ã'â{F±–=>ŠRë;UÉØÚâYÕÛoÜþ‘õTÙ=>»¢÷u"{Ww ʇÖf‹ÚK'W¥%+¤{Ý·zÉ#“ÇüÞ¿$bü%èî:­–²×Y|™¨¾Æ¥U»ªl¾„h֯ź.ß/R¾'-³òîU\þÌií>´XÎpôYŽºêÞŸE?l#«ÿùCPë>”éýDõ5[µLuDÛ«‘­T‚-úì©Þç'3‘6]½,RèÇÓpmv¤ßßf¶Êç#¡¨•9cb9?ƒ¤‰Q»î‰ë«Uy7U_EV×Xñ¼{¥JvÇAl§DDìé)ÙWeUêDߪªõñUö™!÷NÞòKQOlñŸè¤ìÖ#Ç6ÄÕr?6Ÿ"õËøÛuݪfw©çß †eƒÃàrlMœ5M1n¾³>žõ òhûÑ1¿®®JZB­ù4}蘿ß×?×%-!ÑŸ;€[âsìdž}Æ›õ§«|N}˜ðϸÓ~´à-øåþ£¾E=_ê;äP=¼0cÜEb±IMPÛ&sak§Æ²÷l”³÷¤R«QUÐ=vG7eÛ~dMú,à LDÆ’­5MS:L9]Že9I[¥Ú©¿Ïl¬E­·È¨±U3¢™èª’FäëÑWmû×m͸·ÜHp¹‚ñg¡KÅe]‡&²=e²ävÔD¬¢r÷±{»H•{تžÔV¯R‰ßj5/CrH°>"ìqÛ_U3 ´eTÞÑvۮݧNÆM¶^W#|wFôæƒfùVfoácZzc¦;ºãØíÛ%·–±”ÓƒÍ*ݹÊ*žUwõUêžÉmÀþ1푨ö9×&註¢§´þ‘gN ?+Îki/˜ÕåyÕݶÛ% k#÷éõÙÕ?‚‰¨ªås••ªª­DW'öÍyε‹0~™põc†÷v‰^Ë•ö±$ežÍ²/Y¦kWÛ÷5¨íüÛ*%äá—…œC‡;EC*¾ˆs[Öò_rz¨Q*jÜªŠ±3uUŠTM£Eꨊ»®ÛJ2Œ‚¼DÅìTiGDtϺ=®iµ›ykLá2Ê¢«¼¦®qOwDÕꎞ¦7„Ž©´¬È2Ùèï:“”¹jrÔlUåæTshàWz°G²'Do2µQ¬klêšb˜Šiå]u\ªk®u™ã3× «ÈRÏ(Þ™V[í˜×x¥ æºéüÍ¡¿Ezu–9ßÊä_jÅ$Š­M¶jO#×ÔBéŸ-ÒÛEz¶UÙîPvÔuÐIMQ2·ž7µZæîÕEMÑU7EE<\·MÚ&ŠãXž½‡¿s v›ö§J©˜˜ž©Ž0æí¶ãCx·ÓÝm•QÔÒUÄÙ š5ݯc“tTüGÒjõ˜eº¿yáþöé}Ǩ’K¶W#¤“έ¯sÜ´Ê÷tY DåTM·ås¶DTßh9f?^Ušº9vÇD¾ È³{YæŒe®žqÕTswf“Ò &Ü>;ÍâÝÚjïwj–SÑÐÂéæ‘Ë²5­M×ñø"x¯Cì5¬c¬âs[-º+kj¿Ææ‚óT£‘#u;ކ…:«ä{vTé²"¯Ú*Ùv ¬~"›4ò鞨éþúÚ] ÎmdX ñw9ò¦:êžQöÏdJÃù;ôŽënÅïœEföåƒ"Ô×Ç=¶)6WRXÚˆ´ÌOgh›=}­lKß¹pOÊ––š†š**x©ééãlQEŒMšÖµ:"""""w©Ô袛tÅÆ‘!ó ëÕâ.UzìëUS33×3Æ@éh9›å@÷Ëhó_´#:ds7Êï–Ðÿæ¿hFL€Xð‹üfšÉøC,ýªÓ©Ç,xEþ3Mdü!–~Õh3+œ^RpÓ„ÇgÆ%‚|û!‰ÞåA$}£(àÝZúÉ}Fª*1«ë?½Ö½ ÓTuÒ->¾jF_UØZ¬4«S2§­#•Q±ÄßóŸ#˜Æÿœä8“ z±ÆïòI<½½ï&ªt²É³––Ó@Ïgòa†=šÔUÝËÊ›¹ïëgˆµ„³UûõE4S33Ê"9Ê´Ó5LSÛ7 |4ßø§ÔŠÜƒ/©­Lb†©Õ—û“•É%mCÕ^´ñɶË+Õyž»îÖª¯zµ¯ö=cĬt8Ö5k§¶Úí°¶ž’’ˆØâ©Ñ?óïUÝW©ˆÓ-9Æt›´iþ#DÚ{m¢!fɳ¦{åzø½îW9ËíSh>JÛM®¿µXÙ®5¦Å(§þÓûSꎳ'ÂaiÃQ§Ló5–üêi©ë)夫‚9àŽŽX¤j9c“ek‘z***¢¢œ´ã‹‚·iEF«i} ’a•swÐFÕs¬ò½z*ö»—¢*úЍÕè­:ž|ëŸ'²×c™ºûeÎôµt³7™“Dö«\ÕOb¢©'ÙM¨Ål¶61gZ'H®žŠ£ßÑÝ3 lNœM³Ï¢U3ÉÅÆOÓÕG :•s–\¦Û›a®™ÜιRDÅrÀåDþ(ث̪ªö"ªõj«¯‘ÃŽ%4c1á[ ¸bÕöëlµºbwhe^Ѭc“x•þ2D®F¹½®bªlý޲ð£Ä¯ˆÍ³f쨤mú(’’ÿC“zZænׯ&ê¬dœ½£U}¢nªŠ}u—ãðù¦Þ3 VõƱ?ßLr˜èžÅÊ*·TÑW8L@1à4mkÖ OB´Þï©9…K[Im‰{ d•¬–¶¥Q{:x¹»ÞõOdG9z5MäâÿHÜx…ÖGâ8¼’OŠâuR[-Ó9ÏK…W7$µ<©ë+ÜœŒÙÐDÛ«” #ÈõŸŽ-wl²Ç5uÒé*ÇKJÅU¤³[ÚþäîFE;urõ{—~¯^©hnˆaº ‚Òáx•3\ôkd¸Ü6k…NÛ:Wõ]“¿•»ª5:'Š®‹ÁßZ¦Ð-ÚŽù…ñª¼U#=8‘Q”¨îþXÓ¿nŠþeîÛiôä›MŸU™]œ=™ü3õ§¯»«ÓÝ$À`âÅ;õü©õ*Ø€:ãS‚º}Q§«Õ--·ÇaK…¾4F²îÄOY¾ Pˆíû—®Ê\Pf`1÷òÛñ~Äé1è˜êžÅ«Öh¿Fån]ð Åý^fŸKD»I{[*Ô#î=gTIš›ú¹}Socºr¯7bNOyD¸b‡®~½à¶·2ßr¨räñF­Héê¤{K[ß´¯r£×ùjÕïz“ß“‰ÚDªô_;¿¶|‹lkduDIjí|œ©|^芊«×’HûùUNÕ–f³L58›]<ãªzcûèâŠß±VäÑRó õ›yIø™©Ñí5‡L±*¾Ë'Î –)'ŽEl”6äôe•»uGHª±µ}‰"§V ƒÊƄڭ{­Ñ 6¹m…Ùê»;­dEmê®'¢¢"§|HßGeV½ÍGõDb˜®ø~¢§Ô\Ößÿ¦j[Ïo£ž=Cï´ŽEÿœrl¨›nÔÿ9Uð¢É•Þ~˜Y5½$³[­¡†xÕYWRŸn›ôs#þŽm“íU ¤EsÜÒbg f~”ýžÿG[©l>ÌÅQ¦.>„Oñ{½=@Š:˜jz•¦¸Þ©crã¹?µôµLDíieۣؿíNåNŠm€õnåVªŠè&¯Ø·‰·U›ÔïSW ‰ésò޳U¸FÖ+õй(ï6§,Ô•Õ}5•۵Í{~Ú7¢+\ÞŠ‹Ü¨äG'iø{×ió?J4¶GºI4×sœª®rÙ©•U}«èP=Åë±Ê©ô¬Î W;tú!¯}.ôÿüEÇ¿« ù§ÔÌCŽ<^ÐÖµÔ¢‰<Ñ2à¤Ý®yÕ>—¸ÃX§•è‡ç==3:h#‰ª»«XÔjoíè~€¢"8@ESýòþ õÈ \Š8§ûäÿüëXÊ­}*}°Õç¿áxŸÝ×ü2´Mz&/÷õÏõÉKHU¿&½ûúçú䥤:[æà«|N}˜ðϸÓ~´âÒo‰Ï³÷oÖœ¿<¿Ôwȧ£ËýG|Š ›`Ø~¤cØfyŽPß,·û:š:È‘ìw±Éâ×µvV½ªŽk‘ªŠˆ¦tAu?íPÒ.Òÿà ê\ŸnË.«ÞZv¦ê¾cV÷&É܉öÛe^gª¢$5K«ö: ªâÚjº`9,hÅ–Ó‘Ò¾’DGz®cžˆ×1vèî›÷ìu|ÖuLôÿU±ùqmGÄ-™ ®]×°®Ù»m¹ãw­ýŽb£“ÁM>;$Âã§zcv®¸ûz>Ô»$Û\Ó%ˆµM[öãæÕÇNéçÎÅcÛ#Qìr9®MÑQwEOiý%¬·Éµ‹Ñ:ZÝÕ¬§O&s‘Yn¨»¶µ£[ ê’5U~ÙÒ?oä‘eï‡708;_¡L#Q cUl·U ª]‘7æmKXÅ^Ž]™¾û¦Éö¤g³«|mLU‰õðõºNÂ^WˆˆŒU5[žíèôÇø¿jµ×bÆå|9§ :¡oìÜæ¾j ;®4íTÛo®Åè컢"§Mú&ývÁ?]1úX›=×Í­±ºDWÎÖî½{ÑãéßÑzÊò|u¤ÚŸo±$µµ¹èÖœM>yÓÛ¢Gs¹cÕpÉ=¯Í.Æõg5.?;ÑW§Š¢'r¢ì».Æjßê¶M sa<3ê•Ò9[ÍEU‘ÔTÒ7eTVK"ìäÝ?~麜£\é§Ùí.ínIj5«GšuöjÛôYxvã_:H9p¬3N©eåt²ÞïèT±œÍß‘”­syÕªª~ÝÊŠ­]‰7 òq[nQCWÄ.°d¹ÄÈät–«kÒÓkrm³˜öC´’"·dÝõOKse‡ÙŒ]Î7f)Lú¸zÑÜ„¼«Zj»=Û±éž?ñWzUǪï-ÄðŠjìÓ%šNÊF?ÕʮݭÝïo¡Îj9ÎwMר¨JzcÁ6«ëm3¯¼GÞ+°\n¢Eì°ËDÑ:²¦F9¾wVŠäb*·¬hÎ}œäUzWM´—M4zȸî˜á6¬rîGÊÊ(¯É¾Î–EÝò¹vG=ʨ7ØÛ‰6#ÂàgMêºçìŽok›g{mšgTÍ©«ÅÛŸ›O {çœ÷pŽÆ·§ºqƒéN-M…éÞ5Gb²Ò9•«ËÌåÝÎsœªç9W½ÎU^î½Ù7(xâÿ‡x„Ó”÷O1Ï1nÖá‰Ü›2İU/*¾;»³•#k]¿DTk¾×e¥Ø&].Wm©Šëo[]þÍY5®ùj{·’‚¶«$ߪ¨½}›îŠu £Üoðã~±_!âC±ÞÞíEÍôme£j£¯4;"ùËXhѺ£UÎEkºò*?Mœåq˜ÙÖ—O.ÞÄÃc¶š­žÅéwšôŠ£«ª¨îéëŽØ„z N+•X³K6EŽ×2ªŠ©»µÉÑÌw‹ŸjäîTS,sz©ªŠ¦š£I‡ÑV®Ñzˆ¹nu¦xÄÇ)€y{0¹–]eÁqÚÌšÿRÒÒ3}¾ÚG¯«SÅÎ^‰ý+ÑOTQUÊ¢ŠcY•»·h±n«·gJb5™žQÃêfepÆ­´vlZ…÷,·$¨m··DÎy*jž¨Ô^_µ\Õ_ Õ¨»n^î¸w´ðå¥ÔØÚº*Üšêïtr[¯#{JÚçîç"¿½ÑÆ®sX‹á»º+¼?Á ÷ú:ÔâkYie‡1¾R: šF¹©`¶IÕ湨©PôUæUêv˲¹È—éY>Yu*ùsÏÝæ|åµûIVÐã7­ðµG cÛTöϪ4ްmÑ0æo•ß-¡ÿÍ~ÐŒé‘Ìß*¾[Cÿšý¡29cÂ/ñšk'á ³ö«N§±áøÍ5“ð†YûU tÌ šeV¼½fw©[Ž‚{…CœôjvqF¯TÝ|Wm“ãP9ŸåZ×ߢ ¾Õ Xýo59Ës½ò;¤•Ò3ë1/Üâr»å›ÚÒmòyh$:W£ñçWšÏ%Îl®‘ž Ýi¢D_W™²»m•yÚ‹¿"mAô‡È8°â¦–§ ¥ó´È¯Ò_¯íW9cŠ…%íg½­äÚ{9˜‡h£Ž8cd0ÆÖFÆ£ZÖ¦ÈÔNäDðC‰x`Ú ¬Ù·“Yž5ùUýŸ&<ó>hmò»ÌÝžŽô>oÿ:EÄ‘Ý1&26^éúë$îd{¶±Udj÷"«"ìÇ+Ueß®Û/=¼žzósÑ {¥Â²Zù¨ñœºU´\éj¥X££­UÚ ‡5ʈ׶F¤NUÛfHí÷V¢i9åÒúÍ(â6³)´Ôö4™~Ù °*G%=R¿iÓvì¨ä™«";néÕ\ŽS·øÏê¢õÌ–ôù3ôwÇʈïŽ>iëió[Ä]Žév o :¹ôñЬKQê*)¥¹WФ7Tƒ£Y]¬s§.ÉɻڮFíÑ®nÊäÙË)ù¤Tÿ)¼Õèæ„»ÇëKçr¾ÕK,rrI#Z‹U+v]÷ås#Ý;–d]ÑQ uäßáý¹~aQ­y-d´c­=¥ßë·-šîר­‰Žßý7±SÔSRòŒjånªñ/wÇ(+Uhœ˜ý¾Ñã-ÛÎ×—ÅþqÏéÞ‘0è×Ú[Œhö3§=«e¨µÒ+«eosê¥{¥™Q|[Ú=ÈÝþÕE6»2œ ÄÛ*¹ÃÍÓöG±ËlEÛ»ÓÊŸoBC•$cò ~É•Ù+q¼’×Oq¶\au=U-C9£–7w¢§þ}è»*u8íy¤Ì¸2ây³Úß$•¸eݵtH¼‰p·½7k\äN‰5;Ö7ò÷+žÞô;2Qß)î“û¯‡Xu†×l窰Mî]Ö¡‹é%ÎÞzmê²eV¢î›-Grï»e»!™Nðz§É¹Ãý]ž^xks;2Öüs§Øèf™X5²çXµ_œÚoÔ0×ÒH»#»9ŽDrn¼¯Mös{ÑȨ½PÍ”SÉ7ªíÈô’ý¤ÕÓ7Îðêÿ;£j̪çQU«ž¨Ö*÷6fʪ­éõÖ»¯YÖÀ7&È­8†7uË/Õ>ol²ÐÏq­›mû8!ÒHí¼vkUNfF]Å—µwÚù&mFMqT†79^Û}7åbxrÇ|6ÝQW½ÇG¼©:Áô  ôúyk¯Š;®u\ÚYbï¹Ð§i;ÓÙ¼ƒ:÷£ß·qMx$ÁÕ^µ©±¯h¾åÑ÷+“nWÊï‹}ãDùÂÌ1_ÃUv9ôwËs³ùgÝ|ÆÞ~LεwGôòó¬Æ9Ú±K 7d¦H(mÐ6ž"&ü­NõTïr®ê«Þªª«ÕL8ªf©Öy¾Š¢ŠmÓQDp€Qè*'º_¾¶‡Sl´LŽ×y•Ñ#b"výV9—o'3\½Û±ž.-ÙÎñJ,ç»âuñ1ñ\©_ y—ddñ¿}—ekÑ®EÙzµ:/q›—â爦ïGOsK´U9Ƽ4ü®tÏUQËÓÊ{%!y1µ÷é¢îÓ+íoiÓîÎŽ>wzSÚß¿›97ïìù] ¢&Ílqn»¼¹'¸ÔêÝâŽñ"ÒQ]ëŒÞ"’u‘öîìÚçª/.ÑÌ‘¹y·nÍwwG'oN‘¯|ë14Î’€ VIŠã™…µöŒžËIr¤üÝDhîUöµ{Ú¿*)\óžîšß¢MÈê(êéÝÚÅG=C£’7ìj²¢ø";ñ¸´ ×ã²¼.a†§DÇ :A’m>iUÿ…sÈžtO'¾™áÇ®4žÕEÇø‹ÕÍ%¯‡ÖÇ1»ë½WÛ(b­’:ùhª‹#šŠ9Z¨ªÏF]Ñzn­ßÀÄÇâ㇫U31ODw¶ÙUVy˜ZËè®(šæb&yr™õé¤vÌ'àU %ãX{&«GÚF›5—ŠxW™¯Y£o­àœÌMÿÍUÝKGi¼ZoÔ],—*jú9“xç§•²1ß"§BÎ_šas:7¬UǦ:c¾>ÞL¬ÿf3=›½â±Öô‰åTq¦®éû'IìCÜl{Ôµ3ðŸ¦Â‰pö¦ü!UúH^Þ6=êZ™øOÓaD¸?û S~ªý$0ö‹ò8úQö·>¿Å§èUí„Ú îØGÕ­X³é Š’ÿz¶ÖVÃWV”me/'29Xçî¼Ê‰¶Ì_é"¸øÞÓÕz$¸¦DÖø«[—ú;D3,åøœE2Õ0Ôc3ü·/»â17bšº§^Ÿ2Æ?ÓMsÓíU’JLfá¯.žÛl–yèRj8ûiÙ*Ë´Íb»ª=§:íбfEü-Ì=4W_*£XkðY¦ví›3:ÚÚ¸tñôò;`a2¼×Áèá¸e—Êke=D½ŒOʈ÷쫲m×¹­4Õ\îÓËÅË”Y¦k¹13°~TÕ0VSEYK*I ìl‘½½Îk“tTùQOÔ§'¸˜˜Ö(âŸì“ÿð_®@JäQÅ?Ø'ÿà¿\€ÊÀ~UkéS톯=ÿ Äþî¿á• òhûÑ1¿®®JZB­ù4}蘿ß×?×%-!Òß7[âsìdž}Æ›õ§«|N}˜ðϸÓ~´à-øåþ£¾E=_ê;äP=çï<9\4&«×ý´ÖÖaךœ3Åè¢YŠGï½Ê•‰ÜÎm»F'vû¦Ìë`È,¹Mª æ?r†º†¥cš%Ý«²ì©íEE訽Pé™B8“á#)Ò[åÓ[xk³-}’±î¬É°Jv£[º"¬•tž«¶ÙV¦ÿÉENV6;d‘Žü=Ž=¿×·Òè;¶•d³,g<'œÑ¯W]=q玩ÔÁ®àÙö1¨¶Vßq{‚Oü²ÄïFXü™ÞÕÿR§TUCb 5ÛªÕSEq¤ÇC»Ø¿on›ÖjŠ©ž11Æ$@ w8ά˜¥·+·m4Õ¶žŠŠ™¥Mdî]›Lïs•Uví×v¸¢ˆÖekˆµ…µUëÕE4ÓÌÏ(}™VUbÂìU9E\ÊZ*Vîç/W=Þ j}³—¹ …¾/Z­·ñ¯Öi)í¯Jœ7«gHÛÞÊêÖ/E‘SelkÝÑW¦È}\5ð˜ç=»[¸ž±CC½[SŒàïzJÊ7/VÔ×'s¦Û•R5õW×Fªr%è:M’Ó{Éõ^¹p]±Û*óʧ „™‹æšç®{:£Ïav¤´nˆ›2&«ªdrî‹ÓûÓeÝè©Ü¥¹9åÉ6Q§8s*ËIA]s’.Í6ÞYŽÛu_¬½6ßnïh<”ZýüjM'þ§£[òOPÄ^o½Uwo³eïC¡…sò}ã ÆøXÅetMd÷™k.slÕEr¾¡íb®ýëÙÇ^í¶ïï[|·Y„æ[CŠ»<©ªhŽê<Ÿ^šùÒœ.Å1Ù¯¤&PãZx‚ÒݲÅxÔlƒÍŸV®J: vvÕujýœiàž.r£QUUSz½?•{N[\‘ÓiNI%뼯«’í÷4Ý?ù2C•ìžuœÚñø=UQ×Â"{¦f5ó,\ÄÙµ;µÕ¤¯@!Î8ªÓ$!®eÞ’ák‰’×PÜ(ÕŽ…¯UF¯hÅtNET]‘ÍÑWdÙJË¥Ü|k&kÄ}·H®Ö B;-fA=©òÓÑT¶¥!cžˆ¨å[Íè§^]»ú°»›bkÄÛñ{•X§z¸«„Äi3ï„py«j˜¦u×{’þ€Ã$Òµ«4ºéΑåùåŽ Y® =U}4uLs¡t‘Æ®j=檷tꈨ¿{b¼Uê,[ùULDwÌé U1LLËu6à—Œ]Pâ;>¾âÙÕŸ¤¤¶YÖá ít³Å"ÉÛFÍœ²LôVìõîD]öê\“a中ŸÆN¿ÂuŽ1¬q[³z›ôïÑÈ•Ш>S=ƒ&ÐJlæ8[ç˜mÒ–^Vª¥-S›ŒEUEDY]L½7õ¦Ý[o_ñhsMÎñ‰¤ìüúÁZØßºìÉ[—nôGµª©âˆ¨o6g0«*Î0ظŸ“]:÷LéW¦&agoÆÚªŽÅaòCê-Mv1ieud¯e¦ªšóo‰ê®F²tts£}EÑB»suYQ¨¼Ê½ 8åä¸Êf°ñMKeeG$Y%’¾ÞøÕSg«Ú”è«Þžn½SuÛU;}¢‰±ª|Z¦ÙVu+šÇìµ·4G;•èasÑ»ì½UZˆª÷/q³•ÊK”ÍŒð—“ÓÓTv3_*¨mMr*n­uCd‘©×Æ8ž‹ßÑW§Š6x2ÄëukŠ[uýëpó:ªŒ’é5C‘Εñnö½È¾²º¡Ñoþ’¯ØþJ¬y²ß5,’óSRPÛ¢“wÚWË#ÚîÛë1®ëñmÞ§DK¶X™½™M¾Š"#ÓÇíõ$™]½ËÝsýl@br¼³ÁñúÜ«.½RÚ­6øûZŠª—ò±‰àžÕU]‘›ªª¢"*®ÅFʼ¨ZKk¸KGŠáöÊ•R::Håÿ9ˆîgíþ“Z¿Ø,³˜kðksVžLðY»ˆµgñ•h¹à¬:;åÒ ZÊ(0—Yræé;)¨™QL•Í+»š…\­øÕÍkQ:ª¢o¶Æ:« Z± †Yqzª -õë%Ê’y%íùZ©»&brìÄÙ6ß¿©•k!ÇÜÄühݯMxðáÞñV2Í6üdN°ºÀÀ`êÌ«Æò{ŒpÇUx´Q×ÎÈQR6É,,{‘¨ªªÝË¶ê«·Š™óS]3ESLó†LN±¬È„ý^:ÃõNý&}ÁÄ}Ãú<úí¼Î£Î¼ÓÝ7ææíù{NN»òíÍö»t/±°Çå—òíϧ—Æ“¯›7è¿®ç@5ëÁ§kôÆÒ¬·k9¦½Yê©)úíË;£^ÉÞ³Qv“‘vW".Û/MÍÄíܪÕqržq:Ç™J©Š¢b\ òpgÕúÅe†Ñ#¤Š“)‚ªÁ]³uÝÌYbݪ'†$ߢ¢+¼7Eí!ÂStº7ÅõîëEËMô9œ%ê—–>Æ•M©‰®EÝÕo‚¢íܨ§wŽûbì_µMØåTDúcT6ºw*šg ^@tò¡ê ^YÄÍN&•®’ƒ ¶RÐÅ IÍ'š6ÔJäM“g/k]ÕƒN½9RmÑüU¸^™ã¸òÂÈ炆9*Q»*vò'˜Óº›(Æm×6ª*#ª)Úç³tÙU¯Û™«²'Vª/C85ÑMÊwkcµvÍû¸zâ嚦š£”Äé>˜@9WºswGÉŒÜn6 U•¨ÿ:…tïk×zoöþ&œ2k¦Ú?Oµ5‰W²§®žòz;íÉÕû§W{§…µšöÏe÷*ߢʺé™éêL0žsì5¿vì]£ªå1_¦gÊŸJ¥®cÆ>Ê—|~¢õO7­Cc\ÔÛ«ŸL¼ûußu]ûý?z~42{Lžm–iŒm•æ=#©’™Z¨¨Šœ’1˺uÝ7N¾ÂÖŸœôôõ,Hê`ŽV¢î{QÉ¿·©kîF2Ïäøº¢?j"¯k'ãnQ‹ÿÊ­U=væ«^¨×Ú®¶î6ð™XÕ»a÷Êgn¼ÉNøgDO •ÎfÿþæÑGžŒTÂ’Íu¸Ò;uNÎk|Šï—ÐæOõ’~˜i½Ñ.=:ªªó:Û6껪órî›í×Úkœ5h…|‰$ø;Uá»P³œ¾í·j[ BSPÒõŠz£ΓíבÎNTDDß}×Âàÿì1MøB«ôèªñ·2¨œ|i^ôwé§Oo÷£€å¶r[S]sU¯:ôÄU¬kÌñštÓŒëÇ]&cDÚ#Žˆ®ÜnýŽ,Ÿ†Ùý„Ĥ ô:]KG©”–©oˆú8GÛ¦’¡ÍYȉ#ü¶ÙÉ·ÄHnýŽ,Ÿ†Ùý„Ƨ¡¼7éΤieMuÒ+…\•,|´ÕHÄj2W5ªsU;‘;÷%jíQ–S7ªª#{æóésÊÖ*öÓ]§nŠêñqÂäkNœ=Õ¡ðÇg¬»kµ×£ªŽÓm’ªy^ôß°¦|r26ȽÜËÌÖükº§r’Ÿšï¨ºk¨øþ'q¥‚ŽKd5Nl´Œ‘{GI#UwroÜÔèEC~ºé¶½ÓâxÝþjÛD÷×Z&F?xjáYV$•Z‹Ëºtr9;¶èªŠ»å¸ÓEMZ¢UEMìtêŸ×§3nÙ§™Qãb&™£†¿n½-6s³—~ \Ñr.ùS§8è˜èÒ?¸Ñlõ !¹ãÚe|Éí’±•ô6©já{˜ŽjH‘^‹×À‹¸ZÕìßTåÉY˜ÖÓÔ%±´kOÙS¶.^Ñfæß—¿Ôi¸ë=æßK —ëƒêcì*ìÉ/ߣÖfµ¬ÛÛº¹cŽ~Ó6ìÕÝ¿—~íÿº %‹N[zåTñ‰'«Œ&¸ìuêv‹‡¢äîUES4Äðži3gѪ|Sfu¬¸6Ûá•Ôõ.£J¤§ó™ªçEÙR&z¨Ôr97ÙÜÛoÑ †–çQɨVœk=´Ì¶Ú×9Õ5¶–FÈâkUÎå’kQý6D]úªn„U„Ôk*^•­«’š®8]·ó•o]¿ÎåIñ—²Ià…Ѳi£c¥w$hç"+ݲ®Éí]‘WoˆÉÌfÆ_¦‹Q:Óò§ž¼xµ»=F3?‰Ìïb«§Jôܦt§HÒt˜í×O_QÞ!:ñ6ï¾­ÙÄL\Cq'&VÜ3’ ‹ú=«Y;˜’²‘<#F÷:Eéº}ª|kÒâ‚jÚn nUÕÅæ§äo3»D‚5nÉ×ußn† ©«Ñíb¶ÜõgžI"‘µU-¬ÞIcíSvÕ&ʨ÷µW›®ëº9:9:l©Â[¿bÅË‘½»F±O\éÝy®#ÆaìNä\½¥W8éDoUëž>h:âßéå÷>°éåfu­—xc{iÖ·Í#¥dKIZ«³¹SwHDï܃iuïˆ^½×Á¤–hhé(ùdX¢Š j«ËÚKQè+²ôDNåÙ:*“GU+tÐ,‚ºËSðTAI;%‰ÜÍ’¨‰ÊæªtTVõߨVĵ‡( »¦–gtvVÓÍžSÉY$Oz«W‘ü­Û§G&ý;”×à-Y¹bæ.å4Äë¤DÇ“º#½ ÏqX¼>7”áî\š77¦hŸÂW<~t÷kÕ¤òä˜ôSˆü¶ëœ.˜ê­¶*{¤’>ž–ÅØ½µ Oà¥bz=v]œ›uÙ6]÷H“Šœ·>¾f̳eÖTµ[­¯m·¯oÉÉÛ¹w^ewfžÍ“¦Ýê»åƒ†]f‡RìÙþS”X«g¦ºRVVMç“:iYÚ®DÞE^Flˆª† ä_¦ ‰þLŸÛÈea# …3‡ˆiã§(žÎö³5œÒ¬‚í8ù®7k7´Öªg–÷^“ÇŸ>½.„dDVßìô½™Ðâ©@¨É––&nÔ‹ë>“W›¯¢X£ …=’a¶#r9®¶R«\‹º*vMê†hc/Eû³TSôptŒ£V M\ªæ¼uªuž1; ­˜ESýòþ õÈ \Š8§ûäÿüëXÊ­}*}°Õç¿áxŸÝ×ü2´Mz&/÷õÏõÉKHU¿&½ûúçú䥤:[æà«|N}˜ðϸÓ~´âÒo‰Ï³÷oÖœ¿<¿Ôwȧ£ËýG|Š Sˆî ©³›õN®hmÞ› Ô'µòVƱÿèËû•QyjãOUëé}y©Í»•WuÙͪVm@®¡ÉæÓ-TÇj0Ìî…[öªåDeK¶þšDUd±¹QUª×.éÜ®N§V XtJuâÀ¸ö§b4—V17¥«M⬢~û£à›Iˆ¼®Ûg#‘UW˜å3Ö¾tL}½p“ìöÕã¶z½-Nõ©çDòíôĨØ?š—ÃWÜ7ªÜñGÖêöÅÝìdJ¹ µ›/{¥Dhˆž“wr®û¶6¦ëªáZŸ…çñ¹¸õÝ‹Wé=éÙUB©ÞŽÝz/ETÝ>2 Ê18 Ö¸Öž¸åý<îá‘íf[žÓÙ¯vçæUÂ|Ý~oi¥*@è\ÜJÐç±Ûîu$n~è½Qy•zx)¤èuD5z+§õtïçŠlZÕ#²¦íZH•eëܦì|?™Õ5coUW9®¯l¦øQÀîãYÕROJÙV5š7FNöî›nŸ!…g‹Û‹yåû*â÷‰÷EG\ç»'¼¶×hYvQ[›"¤K˺td[ÈäM·w:÷¸é=À ¶\fz¿Oñ2DÖT\«+ªªw¢u4r5#Uö1ŸÎN «)q,°T¿º(;´öçö®Ù<°Kohö¢|{¤;g„üÓ’^Âe¹mÊ­Y¦ÜLnLÓ¬ë1Î4×HˆôêÔeÖè½\¹ν(³A¸oÓ®ho¶ý?m{£¿Ö¶²w×LÙd­g,pµÈÖªÆÕWªsníävê§0x~÷ñX¿é•_ö’‘8ÝÃ÷¿ŠÅÿLªÿ´”ÅØ f#0ÃæøœUs]uYã3ÆgJkd=ch¦Š­SLiû4âW‰G†¼*,— ¤–åq¸ÊêkU® ÇÕJÖîås—~HÛ»yŸ³¶æj"*ª!C«¼§T6÷v*¿µ,Ú‰Œ5ËsvhÖz&#w]uˆ™˜žzóˆÓ†–£rœ4Ìü¨5ggòšñ/Zù.öüOŠßNîWµ–ª©"nýÈù}Ñ|…˜ƒYs yàCP52Åèl“ÕYn´ôéG+ÝTQD¬Yš×î¬E‘$g/3½M÷êOš!‡c˜fŽbX¾=CO¾+-*ª1ˆ‰;ß]$¯éé9îsœå^õrš÷Ûu£†-F·Z¨)¨©!Æn ñ68Ù¼nUÙ­DDÝUWåR)ŒÏ2lv6Î/ÀSfªoQ¥q3¬ÓiÆ4Ž3ÜΜ»Y4Y»EUuëÂx(ï’¡Q5‡.U]‘1•ýjJâ Ê?|Æõ¸Ö K$¾gS][O=KkkÈÔŽ•°JÅsQ}oKËè¦ÈŽu ÁõG+Ó«>OjÄë<ÆL®¶ªÚ¶*¤Í¤çGÉ=^ukZ«üždñÝ-_“Á¤wmE¼\2Uí³›l)5†ž¥­ì[ÛM4_Ê»¢uõZåVïé+znÔìî ‹Åí6gkÇQE4Åã¦tˆšªì‰ôF³Çƒ]†¿]TÓ‡·:LÏt#G+ubçP]5¦†ÅA“Ö¢Ï5ž nDä…ë$²+åNªåj£w^Tß—™Û°Í؋߻Uئ)ÖuÒ8DvGd7ôÆìhdŽ9£|3Fׯö«\×&èä^ôTñCÐ,½8ÉÁ­C±¾1pè«]EIBÙäEtr2HUª½Û¹¯Vü|Ýåœ0áÑó^¸ÓÃj ƒgOœ²©YÌž‹R¥^î«¶û"/˱Üóî›S5[¦jç¤!³Ì 3år®«‡BqJ§s ©ÊãtÌNˆõe%G.ÿn«·vû/‚˜ ÞWºI¥X%z9½œ9 й7êªúg*mñz þ 1KŠãÑ\žèœ½¥FS-;½»GILäÝ|Së«Óï´¹eDòaϼ>]ãd aË*Ø÷'|‹æ´Žæ^û9ÇÕBÝœOhfg4½¯ç%x.z;€¦e9¥å7Õ{ãQmzEGTöZl‘\jáEÙ%®™­W{y!VòýÕäÁÂßšO˜Ù²ýWÆS Èoô‘Ü©äl0ÊÞhâllr#È­W+·Tvè›"u«^P«]E¿Š\Ž®g¹Ys£·UB‹àÄ¥Ž-“âæ‰ßÒu/KïìƒM±[ݦHßG]f£žwj5еQ?wâ'y¦"î]’á-á*šb¸Öf8NºDóï™ô5z)¿Š¹7#]9#<ƒ= Ó]P£ÕL"Ë[m®¡‚xá¡ZÇMHÉ%o"ÊÔ—™èäj½gò¢9ztByL=ñtßôn‹ûYΩ­ò˜{âé¿èÝö³˜û)н‹Íb»õÍSLk3¬è÷˜Û¢ÞbˆÓ‹¡8^[bÀøwÆó,žµ´–«>#AWU*õTci#]‘<\½:ªª"uR‘æ¾SmT¾ß§¡Ò|ÑEms•)}Ч–²ºF§Û*G#XÕTê­F»oå.Û’77z»ox 29cº·¤¨Ùz$iBé“‹ž~=ÃÉeŒXÙ„fY—™ÄëÄ×Xí«;šŠöS2HŒj÷µéWnþVïê¦ÕÁá0x\ ìÓoÆNüÄDÏj]¹våÚpöêÝá¬Ë¡~RËÛ(¤ÅµÇµÐRÖÌ”í¼ÛZøYJõTDYâ‘Îô7ß™írr§Ú¯U.~¨êv-¤8ÏPòê—¶Ùl‰­…ÒÎ÷*5‘FЍŽsœ¨‰Õ®ê¨ˆªsgÊWY,BRWZ)!¦–ùS\+›Q½¥GoQÈ»x«"fëÞªÕUï7>1ò‹åÏ„ Šäé¤uÒ’’²ªW¯ð’EBÖ±Îö«’W;úKøŒ—¯ ˆÃÓ¹MÙò©îxz&=£Å«¶båγO)c²/)Ž·d7™àÓÌÁCDŽsà†ZYëjû4ñ{šöµzwìÄÛÛâOüq]ª­ñ­ÖYóÍNÇqk&/;;Khhjbª®‘›Ì‹$ïjB›9ÑÝʽ¾•‰?:JJ H(h)¢§¥§±C ,F28Ú›5­jtDDDDDð?c—c/ш½UËtEÏ(Žˆþù¤6¨š)Šjg¬ÏnFùB¨<ÏŠ\’£²äóê;uFüÛóíI{÷ôþmºwoã¹Øí)¸{­¥Ø}ךWyí‚ßQÍ*îõç§c·wUëׯS¾QŠˆfârçoÝÐZ¨#‘6_EÝ—6ßG"þ3®šöÓÿú-jýR#¹d³3—X×ó)ö"X¿Ç×ß-ÜlØàðßjf£²\+)ŸÉ4²É¶EÙÍbª.ËÓ½¸×õ šjÌ%¤¦g<³Ùëc»¢nçBôDÝzw¨)á¦'\õßZ™Gºz™Üù=5s›M+÷]üwNÿoS¡%áJ~Ç]1øù7íã¬}û¿¹evÿüŽßŒ¿ä+i&~L~Ì{eÙüDFWrcô“ü4€>Ÿ"¾%³ºÜJkëmu‚ás•–ÊY[ߤG+܋ཛ$Ù|e+O Z!iÕ+¥Â÷•²Y,–…d~nÇ«<êw"¯*¹ªŽFµ©ºí²ª¹½{É£j)ª4ºÛUª²–õ¤O ÍEþ•Düf?û…$˜NCjcÙçP][Q#wô’9!cZªžÍãúÉ&º°ÙMwlðªgŒú#ûïsœÊÍ–ÕÚÂâã[tÓ¬S<¦t™åßϯM'ƒtÈøUÑ›õ›Óc²ÙæDÙ•4/kÓåkÕÌ_ÆÝþ3ã⎂’Õ öº[ -¨)á½Ì“FÖµ>DDBj!Þ,þÁ÷¾(ÿ·a­Áâo^ÄÚ¦åS1G9צ<ß.Â`òÜ]Ì=ºhš­Õ®‘®‘=Hûù+/ûâôe3úßÅT:{{Ÿí4÷+µ¢UÔU*­4Tß³F±QÏrn›õDNØ?䬿ïŠ?Ñ”„´~–—5×›7Ñ;f޾í5eDR§2=藕Ƚè®j"¢÷÷ªð¶¯cñ¯Æ´Ñ:uðþˆe¬Ó‚ÈðL[µÞªªwº£OmPßh8ÌÕKulSß±Ë5M$¾Ÿb”òÓ¹Ìÿ1êåÛåTqjôßQ,Ÿ‹Så8ûÞ‘HåŠx$Û´§™¾´oÛǪ*/Š*/‰¢qce¶\tVï_YOª-rÓOI*·Òîž8ݲøn×¹?£ØD ^®VìsQ¼ß´|tvø«bbw6dŽ~ïÜ©ÿu KÖ0øìâ¬Ñ¹U3¦ËÞÚá1¹†IœÓ–bïMê+¦j‰˜ÒcHª{6c›iÕî/‹ßê±?³Ñ×Mo•ÐUWVó:‘½ØØÇ"¹wNeTMÑvEN«§ã|[ëÙ¾ÏpŬõ¯¸Ï0Óù¼´òH²9Ôkù•uTê­SJá^Ål¿ë-±—x#¨e3ÖG¨Žk¥c}T^õE^døÚŠ_zŠ*ÇBúº8'u;ÒX–HÑËÓ¹Íß¹~4.c~–LaüNôéÆf¿±’ýØÚJ*Ì>6£{H¦"&4'íé‰íTÞ9·÷SæDEózÍöÿJ"MÒ\ãÓ¾ñü£%«ìii©¦F±:É4‹<¼±±<\¿½WdER3ãŸþUÄ>÷¬ý(ŠõÍo™žËÖOËm°S-=3Qˆ®r¹ò/µîUïö"'—†Àü?/³ngH‰™žíeªÌs¯¸Yþ3Lk\ÓÓլŬöFž~K7¦¼Eë^­fKaÅñ|jšÞÙZŠ™éª$J:nnŠ÷$ÍG¿nˆˆ‰Ì¾›ªZ"3áÞ×Ûô¾×>½¥=[JÉäDIäªÛi]»œÕè‰Ü‰¶Û¢î²aÌkµUé¢Í±Oß;¡lýŒM¼7qw¦íué:ôF¼¢4öô÷¼@üfÒùÆÃ7gÍæ·Šiwßn]ã•›ü~¾ßŒ˜ü­“O5 ÛÛ¹]ê’u‹¯+RHœÉáºöj:ú)¿ñ‡,qèܬ{¶YnT¬bmÞ¾’ÿ±’¼_ÞÞ§ýýkþΠœlôÏÀüóö8„ˆÍø~e?k¢@z„sã[!®¡Ã,xåË«þcz±\é¨ovø–<åØÔB®æF¹ÍEV«U\¨¨‹¿2¢ø*M ·9–&oÆ&jò£ÙÕ¢ülî]NrêménxÏ×^½yëÃìä¨öu.í ¬ÿ>c,´Mw›QRÖMQÈôj£9[#Q‘¦ëÞˆ«¶é²o¹$ðÛ¢^ŽÉ¿&¸ZjRìÚTƒÌ%‘ü½—kÍÍÏ6þ»m¿q7‚åüÛˆ·Uªæ7g£NÝXø•˲ûôblÄïÑ®“33Î4ãÝ•‹UøF¹ß2ªŒ¿MïÔtÖNµrÒU9ñ$3*ó+¢’6¹Swn»*&ËÜ»l‰úégÚ­gÔFm¨Y¥=tvw=ñDµ“ÕÊõsÎTY‰ÕtUîî,À+÷_6¼LÌLi¦ºqÓ½OŠye8¯…ÑLÄïEZES»¬NºéßæVýSá¿8Íõ…uÕu±EnY¨¤ìª'™³í XŽèØ•½yWoKÙÜoZÿ¢k†¶ËMG[½Lû¤oËéÅ"µy~ÙvTö*’°-}ÑÄkn¨ž4pêÉø½€šqULÌ^jÖzxαդÏC¢ºažbuÃOu.²Éy±M£¤e4òÈöG"*I ‘ñ·Ð]÷M—tU_ ¶Š®œ#j.'~–í¤™û)ar*F骥¤ªcU}E|MV½:'_GalÁêÞiˆ·r«”éås8O™jþÌà1-عO‹ù5oNôGV½]ZòW]*Ð]Z³j¯<Ô¬þ;ªZRuŠÕµrÉ ãÛšDDb'>ý7ßmºZ [¬[nv -ÞØ×ĪæHg‰Ê‹²¹¨ªÕj¢ªt]ù•nòh'2¿7éÄDÄU#Há§wrÀÓ‚¯13Es¬ë33¯:ù¡[´KAõƒ Ìí7¬»0‚[-¦9£ŽÝÆy“Ò‰ìj5Žj1¨Šä_ÅÜY 8¬UÌe~2æšöpeåy]Œ¢ÇˆÃ릺ñg”GØ fÄ"Ž)þÀù?ÿúä®ESýòþ õÈ ¬åV¾•>Øjóßð¼OîëþZ&½ûúçú䥤*ß“GÞ‰‹ýýsýrRÒ-ópU¾'>ÌxgÜi¿Zqi ·ÄçÙ û7ëN߀_ê;äSÑåþ£¾EÐë¯U yÊq©m9"°Ê”W&¹;•dF«d_íý¼6&à&5á*ÄÌN°ç~uÂ7ºI^ú½2ºÒêö4÷*¶‚åQ¾ñLÝ»»W*E*&Þ¶üʽÌB(›ZløÝÒwU1œO¯R±”y ²jtvê©»­ÙYÓ×TkU:g1™/f6‰¬v;l¾Zê6í¨®T‘ÔÓÉ·w4r"µl^C‚ÅNöîìõÇW/R_•íÎs•ÄQãµ¥êõFƳbU"ªÿ)vTjoã¿DêYû‹×O>¦_Ç,‹M~O¯ÜÜ€£¶ñ=xZxì|&f–¥Ê֥ʲ "ï·¤éz1:/WlÞÓc´ðýÇ>FÖ¹4ÓÄÕÎÛkÝùj•©º&ëæjþëÓ®Éíè·¨Ùü¿™§|ǽ‰{or <¯oOe5{¢=oÌù.—{MŽ‘kïWJK}3WešªvÅ/³™Ê‰à¤iò}k~B®v£ñ6Ûl /šböTUÊÝ•|âG5é²ÿš¾ÔåRRÂü<2bõIsȬ7¬òâÕUm^Yt}k·W9Ê«8]¾è‹ÌÅõSÅ\«²±²·jãzäGwr;𣅢&0v*ªz꘦=[ßbšÒë=«(»·Ò¼_"Ïîï’(ÒžÃo’V1_̨¯•QÔFµÊ®ê‰²î¨r¶\Âø9â{Uù«u?+·éU†dÞ;ešD­¼+UŽÛžtúÜ~“›ºµwôU9[Þ·ßÅñ¬BØË.'ŽÛ,–ø¶ä¤·RGM vj56dhMšÖ§wsQ< ™¾ÂdX,/Ýéëž>®^¤4ÛŒã4‰¢nxºz¨áëã>½;î†p—¡Ü=Ä•8$Ù¯¯k’£!º¹*î• îŽU™Èš;í›XÅÛunýIˆrˆLëÆ@™¾T|¶‡ÿ5ûB3¦G8<¨{«Ù&¯i¦Y¦:a“e^àоw¾×eª®†9™TÙÉV®Ûò÷nŠ©ÜGÁ˯«+ÊwþM?þwwoœ>¬¯)ßù4\ÿùÝݾpE.¾¬¯)ßù4\ÿùÝݾq‰‡(}Eâ\zŸCÙ-ÖûJa7T3nþhÑüÉ·Æ€ul·ú´|¦ŸäÝpÿç{uùÃêÑòš“uÃÿí×çÔ€rßêÑòš“uÃÿí×ç«GÊiþM×þw·_œRXð‹üfšÉøC,ýªÓöú´|¦ŸäÝpÿç{uùÇÏÀF®oâû(ÕmUÒŒ§\–ßw¯«ª®°UÐÒyÝUTS:6:f¢&ê¯åo2®Éã°59/åkÇæ ×ìs!N´÷\ZÓw"¯k LèôÛÁ9_ãU:ÐsËÊý„2£ÓýHŠ Aqª²O*+}$ž$š&¯]úy´Ê›&Þ“·^¨á"‡(áŸMîp,jØlÖåìÕU9©Íßã¼+¿Ç¹.É“™CáâL]g‘ս榙cz.͆m§bµvÛet’ôß}ÑUz*àøÃjps€ÎñXy4¹VÓ:Ǫa,ÃU¿fš» ÷,xÞá/9ÓíK¸êÞ™ãõÕx½â§Ý7¾ØÇ¾[Eb¯4œÍg¤Æ,›½OE¼Ü½6nø¬{ÊmÄmŽÃš®¼Ïm‰. –¥û&ÜÏì¦cï•>=αŸÙlËTµËi¢Z•ï›°g?ýí·:nµƒÎð4âfÔiMSV“§o“ÊõNƒ\óÛE}‚Ï$— :ŠÔVKt¯]Ñ®k]é+®sÖNåsZˆ«»¹wÿ)? ™žWy¶ëf e«¼EMn÷>ùKJÎÒXœèªÄôžÝ¤{_¶ü¨Æ®Û+•:7|!æ3Ú3¸¢#v7bŽÎ˜×ž½:õéÃHÐŒ ¸³6uçÇ^×$´çÊ/®Ze€Ðiì6\nëî, ¢¢¬¹ÓN³Å•‘½#•ˆþF¢5d]‘7æ^¥«±æºŸ¨œê_«IWîåÂÕz‘žqB”ŸÜÜ‹ÙrFoÖöõWeÝ:î½å¹’Ùm–©+e·Ó>¡:$Î…ªôÿ­¶çÒ3m¯Ë1µQw—Sjä\¦åUEZÌé:îÇ“DÏ==¬-Ê5Šîkhåw“ÇrMbÉ— ±PÜ’“•`J¸*D²MoV£‘QÌsÚ«ü—9;•MK‰ÝË8<×+~c§µ5TvJšµºcUìU_6{Wy)«ëro˳·GÆôß}܉×àl>ù˜»W3/­«”EZšµ‰ˆŽwxq™ù¼¦c§W¹ôø¨·¯btE|6k݃ˆ2¢Ííle-Â%óKŽºÑÖ5\ÔñV9Åñk“~¨äIPœã.ؽˆ®æÊ&fbw·c«]#];™ôDÅ1N²þñKX®7úç5´ÖÊI«&sÊˆÈØ¯rªì»&Ƚv>òã/6úá›=¼3´í«-‹h‡³^W#êÜÚ~d]—nT•Îðõz*.ÅÌ·Va³„§uSO¦b¹VåTô9»À¦l¯ŒLJµçXj«ns¿¢zQRO".È©ß"5:{{•7C·g'|’xeEÛ[²|ÙÔîu=­2ÉÊÕk*j¦bFŠ«Õc†£¹<uNåë÷Fœ! [å`°û§Ãu®îÆúv|¦’g;ù¹ ¨‰SmÓíŸ÷*ôö*©tˆ7ì&lû…]E±ÒÇÍQMj÷Z-šŠíèåeR£~767§UæTñ¦y+ïMŸO3|wÎ塽AZ±n»±'ƒ“™S»eó}¿ê¯Ä^˜þLâ;&®ä=DŽly5¡&‡ÓèêŠW«šÕnÝW³–eß~œ«ÑwÝ:pqÍ«±6s[“ÑV“ˆûbRŒº½ì==€Ž³UÎoºÁh¶ê6Z|û'°ÄêZÊ8ÕZêUsyí¤êåFôW5ïÛuFµj“q‹¯Ü9ÚŸ§ÑÑUPPÈîÎבPÍÚPªª«˜ÎWÆö"ªªò¹UwÙu߯‡ËYj¶\×WÛijUžªÍ ^­ù7N„—´4ØÂF f.ѵ&=SæäÀ½‚šîxÛUnʈð·Å—š÷¯;möšž =Œ¬÷N+ER‘ŽJYk;ûG³ëˆÍ“´MÕQ:ï±ùL=ñtßôn‹ûYΧÇp±#†6±îkSdOÄ{+ch,áqñŒ±‡ŠiŠwwbtéç3§?1^ «–|Uuë:ë¯÷*û™èÚk¯ö£§¹KZjí“JžŒuqSÆæ#½rsF«àUÙv9ÿ¥šÍ®œå7¬v³m2ÜU©]i½ÓÈ‘½ñ«‘³Bö97õ•9Ú®cš¾;5S°GáWCE_c_GLh»òÍ=7ùµ—çß·s ~Ô\µ\ë»3¦“ß§sÕ쌪šè«v¨á«Öüo\¸éÖEÈêíNHê_ —)ݾÓDÕÛ•ªå]Õ^¨Îe{œ®øÕ/oÜ5ÔêOVÌO)%ËJY,´Ž‘­Z˜¡‡°XÎÙËîÛ¹Nˆ¥‘c8ÚkSdj&ȉì=Æmë÷¬Ü±DQM¯“O8óòׇެ 4QTW:Í\åÇÍâ“Y8QKÆ 9JúiêVz‹Mò–h䥪åF9íÙÌsUQ­G"î‹Ê›l»ªÜ~ 8ƒÖ¾ s ¦ý¨‘Óc´Ô²Ý ¹Ðв£´^td®æsßËÞ‹#¶ðD-¥]¾‚½Úê(*‹»RXÚþUö¦éÐý˜ÆFÄŽ65­jlˆÔÙyŽ{…ÇÛ®c Ü«Zëè9¼ØÁܳT~f˜èqÎél·^øä«³]衬¡¯Õy)j©§b>9¡}áZö9«ÑZ­UEEïE,‡”C…ØR“éó€Z[RÇ>EEM#{&¢2:¶µ½Ü¨cöûTkºlõ/ð.ÜÚ›Óˆ³~Õ¾.7f5Ö*ŽôFœ»T§.§rº*w§^\”ÓÉùŵfŒç“$°ÓsZêevfÉÈ«ã,I²{\Í—ªµê\° a‰µŒÄU~Í½È«ŽšëǧNèeØ·Uª"Ч]:@2I1ºYdkÆ«œç.ÈÔNõUðC uǾ9/+’ñQ™%c›Í¦¤·F;´W>:h˜äéÞî~dTNåM»ÑNÛb–8ñœ^ÏÂHí4ô,åîÚ(ÚÄÛdNž±>D8w¦trqƦG@Õ‹-Í]tž/;[Jµ.¨‘ž’µU©\›t]“dMöC»'{ÀÙœ6Ý™ù´Äz!½_Œ¹U]s Ê[ʪšÊihêYÏ ìtr7uMÚäÙStëܧêàF‹$ØW–;uLÌdÔW™mR9È›+ÏN©ÑU7UvÉÕzª (×Xå^Žqw™²äE£ÉRÿGém¼umdh×.ýݪ7~½Z»î¨¥Þ¡¬†ãEOp¦UXjbdѪ¦ËÊäEMÓäR!´¶ô»EθÓÑÿ×\ðoˆŠ°×ðý1TUé?êýÀeÒZΤ`öýFÂÁQ®‡heTß±™¾”r~'"*§Šnž%¤—VønÌ$¨J9­µ`zËÉG]û¦ËÑÞ›¢¢£“â]Ðè‰âH¢™‹ѵì^ö¹7EüFÏ™Nš­WLUE\âQ¬óg(ÍîÑŠµrm^£•QÕÛÆ<Üzgš‘Õq{­y6Õb·Z)jæôXë}¾IgrÿšÙô_ûªMœGË_QÃt“ÝD­’+kê{Fr9%Y#WîÝ“eæß¦Ý ¶žŽ’‘´”°Â‹Þ‘±þÃö=\Ì,ÍËuÙµîμùùô[ÃäÈÃ_±‹ÅÍɹNìk)á4r³NpZæevw\‰ÈúÊ~d^Ƶ͎5TÝÛ9ê¿émàLPRRÒóyµ4Pó®îìØæ_jíÞ~§œVglüÅE:ë=:®å{3V÷C~o]ÓH™"#—-g£Û<õÉq=BáËQ£¼ÑSM(*^ûeÁñsÁUîÝœ©Óuc¶s7EMúx)¿PqW¬9åò׎X¬ôn¨ª'[m“NèùÓŸnw=Ý·ÝywDñ.[š×5Z梢¦ÊŠüथ¥Em-4P¢÷¤lFïýúó‹w鉿f*®#Muû4`ÙÙ F º©Àã*·j©ÖiˆûuŽítåÏULãŸþUÄ>÷¬ý(Ÿ ÑœRøb²Úb¢¥£ºÊÉ«©k[5Þt’½¨¯r&îkšÔbï¿DM½T,ˆ1¾êWNÝ‹q¤Ñ:ë¯>}v¶?,ÜÌqëõoSvÙ§N\)u׳ª9¨f„êßC³Ê¬c-ŠzkMUGšÝi¤ê´“µyRdO‹¹ÛzÍöìÒøÅ,sFÉ¡‘¯ŽF£šæ®èä^åEñCÐ-fÊ1ÕÅØ£v®ž:ëêed9=Ü’Ä᪽ã(×Zu&ž¸×Y×Ñuëz®ülÝ£¥Ó›EŸvvµ×fȈ«×’8ŸÌ¨Ÿ+Ùý?Ñb¼‘v9itK/ÈdG5· i˜‹Ñ°Ò¼ÉÓ»y•7ÝzµS¦Ýi×jò|wÿÉÔrÖH¨«ÕÓ½ˆ©¶ÝÑÎ^ã¤~Ol!˜G ø[gU}d÷º•ݫε¹bwE_ù„…;÷éÕz$ÿ#·âðTëÓ¬úýÎ ¶¸ˆÄgWb'…:Sèˆ××2± lŠ!.6=êZ™øOÓaD¸?û S~ªý$/oõ-Lü'é°¢\ý†)¿U~’-¢üŽ>”}©Ïƒïñiú{a6€;¶QÅ?Ø'ÿà¿\€•È£Š°>OÿÁ~¹•€üª×Ò§Û ^{þ‰ýÝÃ+AäÑ÷¢bÿ\ÿ\”´…[òhûÑ1¿®®JZC¥¾n ·ÄçÙ û7ëN-!Vøœû1áŸq¦ýiÀ[ðËýG|Šz<¿ÔwÈ z*nïÀÉ>Z¿ÐilŠ›‡ûð2O–¯ô— Þ6tÅú±Ã.oŽÒÇÍp¡¡÷fƒÒr*ÍH½·""w«ØÇƈ½7zwlŠ“ÞL]Q¶áÚÉuÀ®õ‚<Ú…‘R9^‰«i•òFÇoâèß:5wõ¶nʯMº¢q‹ˆ=>ÉøA⊪,jGR¶Ór‹!ÆjßBJ'ȯ…ª‰·;Z­|NˆåŽDÛe:祚‹cÕ­;°j>8ïîõ*›¹è$êÙar§Etr5ñ»n›±O<0dua±öókqäÝÚ§ö©ŽštÓèË}•ÞÞ¢mO8ö6 Ç[Pçß•[T!e¿ÑÛ}\n–YŸ¹ÆÕ^xÚÖ¬TÈ»x9_Pª‹ü†/°¿— ¢ßUv¹ÕGMGE ê*'‘vdQ1ªç=Ëàˆˆª¿!ÅÝB¿åhk³;Þ.Öäs—C|•Úbü?‡ºœî¶>Z¼æë-TkÌî”tʰDŠÕè‹Ú6¡Û§{^ψ¹¦ízyƒãø•\´í²š×Nç¢s>8clhçmöË˺¯Šª™ãéÄt>kºŠñm«´\aí©+ ’šxù•¼ñ½ª×7tTTÝStTSép†ÈꞸ°Ž³¤ìð|žJJ—Ç2¹ÒQsº7=ÄEw4UÛ•7æÙZZvVž¢ž²ž*ºIãž ØÙ"–7#˜ö*nŽj§EEEÝ{yXtR¶Á¨–ms¶ÁÍkÊ`ŽÕq{cDìn1{5s‘~Ò¢7}×ûývåDž8ÖhuOC¨ìõ<÷Ü'’ÑZ×=UϧÙ|Ön»®ËV>«Õнz"¡Û|×nŒmò|™îž^¾vã)½¥SjzxÂÊ€nÞ€!Æn¦ÑéwY=|²9+/´î°[ÚÔEWTT±í^ôTÙ±¤¯êy6誄ÞrÿÊE­±æú—I¥vçIiÃZï>Fú’\ßë§E^dŽ>Vn»*9Ò§Æ»½Ëç0Ì(¢cɧʞè÷ÎÄÇ^ñfzg„6$ö•¿&ÖkÞ©ÕEÒaVîÂ^ŽæJÊÄ|mstN²¡¾ûvéÕ:ÈWN4B¯C¸w´[oPº+æK*ä78žÝ“FÄŽñEdL¹êòÅ©rßÊߥÞä縞®QC´7úÚ+—¶ßjŠuæÜ‹Õ9£‘Svª§Öº£Uw{…ìÒ¿HítË2-e…=ʨg7V¤h’íìXÕ‰¿vè©à¥ÑãgE+u߇Œ‡²ÁÛ_-Ü—»jÄâ+Å^®ýÏ•TÌÏ|Πö²„¸Ø÷©jgà9?M…àÿì1MøB«ô½¼l{Ôµ3ðŸ¦Â‰pö¦ü!UúHh¶‹ò8úQö§>¿Å§èUí„Ú îØGÿ`|Ÿÿ‚ýrW"Ž)þÀù?ÿúäVò«_JŸl5yïø^'÷uÿ ­“GÞ‰‹ýýsýrRÒoÉ£ïDÅþþ¹þ¹)i–ù¸*ߟf<3î4ß­8´…[âsìdž}Æ›õ§oÀ/õò)èòÿQß"詸¿$ùjÿA¥²*nïÀÉ>Z¿Ðh\9ò—pë>­i$Z‹ŠÚç¬Êpw,Ý;\ù*­¯]§¬N÷1yeEïF²DMÕÈVÏ&gøíî«@rz™šÿRêÜ~W*rCT‘ªÏ •W¢HØØ¬DéÎŽN«!ÕybŠxŸ ѶHäjµìrn×5z**/zbãÃ…ú¾õJ³O6Ä2Š©k,‹J®k­•«úe_µåW££]÷V¦ÉÕŠ¦“h²;E—\ËïðÞŽùµG)óO>¸Ö:W¬^›"¸u¼£ƒ-mv8Ï.î¿?³½È¶ïhiÅW÷3 :ÓLùS×1Ñæéíî].´FÝÃîŒØtê•úèbJ»¼ír¹'¸Jˆ³=7ûTTF7üÖ7ÇrT’¹¸ãcÞ¥©Ÿ€äý6Kƒÿ°Å7á ¯ÒBöñ±ïRÔÏÀr~› %ÁÿØb›ð…Wé!¢Ú/ÈãéGÚœø>ÿŸ¡W¶hƒ»`ESýòþ õÈ \Š8§ûäÿüëXÊ­}*}°Õç¿áxŸÝ×ü2´Mz&/÷õÏõÉKHU¿&½ûúçú䥤:[æà«|N}˜ðϸÓ~´âÒo‰Ï³÷oÖœ¿<¿Ôwȧ£ËýG|Š ¦áþü “å«ý–È©¸¿$ùjÿA YpVÔÝ2Âõ ¸à9õš+•¢äÎY#wGÄôõeÝì‘«Õ®Nï“t6 5kLucz¦’×s©cè&óÜ~øÈœÈ.t½9šæï²ôwg4J¾+Þ×5Îèï <]á©®4s> ÑžŽejµ'ý쑨åÙz¢÷***¢ñãˆ>u“ƒ|ö“&¶Õ×Íe§«l¶<²‚5‰"ulrì«ØÍÞœŽ]žˆî^dGm Û ‹Áí]/ȽLy5ý•uÓëŽqÓ—…ÅÕ†«‡êv8W†)%&ó\?_–žÍt]ÙC9(§_‰ü —ùIè{y¼ÔÕ4õ”ñUÒOðNÆÉ±¹DZɺ9ª—óÍžÌ6wð|}½ÙèžtÕÛÓ페„ŠÍú/Ó½D¿@¥^*_PM?ÒUbÚm%_—#–H¤lÖº'ólæÏ$oG=é²ýmËÑÎjô]¦Q“c³ÜDap溧Ñ×3Ê#½jíÚ,Ó½\è™õçˆm;áë~GšÜšúÉš©n´A#V²¾Dé´lUèÄÝ9¤_E¨©ÞªÖ¯(2 þ³qÁ®´´ôÔ~{y»H”¶ú(¹’’ÕDŽUꨊ­‰ˆåsÞ¨ªªª½UQ§À8ƒã—Vj.Q¥]Ú²¦TmÂóTÉm´@¼ÎljôElLDæä‰¾“ºìмÊudžÎ´×†LYl¸u3«®õEº_jãoÖ¿§£º'ÖáEOF$]“½UÎUzý7±[ †Ù[~>äïâ*Ž5tGìÓÙ×<ç²8#ؼmX™Ò8Rúxhá×á¯Mé0¼v*.s5³^®É$·*¤N¯vêªÖ7uF3}š›ø¹Ê²Èù„•M55m4´u”ñOO;±JÄs$c“g5Í^ŠŠŠ¨¨§êä?”‚–èmÑu_Lèôv©Hª©ªå³U½UQ½Ý)ß¶Ìr¯¢åä]·g4ŸÁï4y4vÝ+ÖË“iïHß7·ä52#b­ÛddU_Veê‰"ô~È‹é®ïéÊÙm¼ÐOj¼[髨ª˜±OMSeŠV/{\Ç"£‘}Ї*xÏòvßô꾫QtÉ]yÄæí*+­ï5M¡z¹V4õåƒnïYìDô·OHÖf™V6³â¯Çå=1?ß8é_Ãâ+ÃU½C£@æ/ Pœ›O!¢Âµ~*ŒƒŒ¦¦¸Äˆµô,EÙ9÷þˆž ³Ñ¢»£NayÆ#¨˜ý>U„dw›UVéM,œÍæNö¹;Úäñk‘¼»ø¹zk:¯®:ÛÅþokÇ–Ý-S埲³ãVhät)&ÎôùU_'"»šGtF£•9ºàÓÉûè;©µS$¤¿çŠÔ’š65]IeUEEH•…›¯YUÜÄè¯PÙý˜§-˜Äâ¸Ü莊}óÛÑÑÖãs ¿ä[áOµùpÁbh]•š¥©Mvyy¦å†’XØïq)ö^«Û½¾»‘Sd^DûeuË—µ€ ©ÇV^"1ió,FŽ =D³S*ÒNžƒn³¯šÍ².îÛ~ÍÞÙª¼ª»rÿEu«"Ð¼Š®Å~·V>Îú—GtµÉ%E5C}=~ܲ·—•ÍvÛòì»*"§zÊ¥ÆwX¿™³6k6¡Q@îÆ¡¨‘ÁuDêÔìž·z6^ôßgs5–Õûñ6æÝÈÖ%•‚ÆßËïÓ‰ÃU»U?ߣ®N/•X3K%6E\¢®¡ªo3$zµ|Zäïk“Å«Õ ±ÏÛ>E¬¼+æõ˜ÕöÉWg¬c˜ë…šå¤s³í^ÕNS~Yª‹íTè[½(×l'Vi›®§Ìo jºk]KÓ¶DN÷1{¤oÆSŃf9EÜÍtñ£¯«¿ÞíÛ=µ¸\昵vw/utOÑŸ³Ÿ4Ž5 hŽ¿d6,^Û%ã"»Ò[h¢õ§©•#fþнê¾WÀ¬DÕ:G7šë¦Ý3Us¤GL²%wâ+‰Jl:*œ#­dÙ·Š²­YoMºµ«Ü²þTÙ#ÍhâÚé’6§Ó^ÖÝj‘«·'µc«›¯^Ëg}mŠž*œê‹ö½P89òyäÚÑ%¡êÌUxþ­’*'Äø«o-M—fo²ÃøËë9Q‰×´l§+ȧX½ŠŽê}þïK˜m6ÜS4Õ„ÊçŸ ¯ì§ù½l|ÞxŒÌcÏsºZ¨° EZMY4»ó^ªärұʨªÕëÚÈQ7j*9ÜÍì} ®ŠžÙl£‚’Ž’&AOOipÆÔFµŒkvFµ¢"&7Ø0ë /‹Úi­–›d ¦¤¤¦b28cjtj'þ}껪õS$Jܯ˜8â;®ÔÏ0‹Z»Ï®¶*¨é­W+çkñ³f¢ª£žÖµvE]—¢*œÄàË0Ž;-ëLnèú[µªµõqSÎÞGöNÙ²3•Q™’5y·ëõÄO‚9ÍÆ×™‹#—ˆž¨OWNå­»Øí±¯lÉ·ÝÕT±µŽE^ÒOTG#œÔÂÌ0qޱ6µÒz;Ûœ‡6«$ÇS‹ˆÖ#„Ç\O?|vÃlxÒÞ.q«ÔqXu.%°^"T…õnjù¬ÏNŠ®é¼.ß}ÑQZ›zÉÜ–’®’¾š:Ú¨ªiæj>9bz=j÷*9:*|hsüNö­ÛÔéìžéw¼»6ÁæÖün¸«®:c¾9Ãöíˆâi¢§‰óÏ+#Š6«Þ÷¹­j&ꪫ܈€äö@|bæ–ë6š.²£«ò âFÄŽMÛ R6GH©ß·3ÔîÝU}Š~ú¥ÅŽ…#혢3$ºõMá‘’G+U"uU誈ÔTTñN›ì&pUžë¦o¼q1l¬¦±6VUPÙî,rÝU«»ð¹7Ž‘6Mš¨¢*m»U\²,Ÿ)»]Úq£JcŒuÌô9æ×m^Ö¼¨®ºâbf9SÏLÌpÒ9töÜžð;¦p­Xo”ަ¸TQÍtž7¢£š•sÉãMúÓ€·à—úŽùôy¨ï‘@ôTÜ?ß’|µ ÒÙ7÷àdŸ-_è4 .cò zÅ•Ùk1ÌšÑItµÜ"X*¨êál°Í÷µÍwEC æßKùK5áÒáüª…Å+øÕ”µ_èd¿÷ûªÚoÄw\)ߟˆË5Ê’ž…üµ8ÆEO"ÂÄßíc~χ~ôXÕ¨½ë̇sM7RôoK5ŠÒ¶mMÁ-?#£õP'o/c;v–]»ãsWã11Ø .efpøËq]Ñ1¬÷·›ÕÕnw¨%L4Êy¥YD1Pj­’·¸«Ñ‹S]YBäUõ•ÍNÒ?ŽDþQkpíIÓíC§uN ›Y/ñÆÞi=ήŽubs+wsZª­MÚ¨›¢o±SõSÉ!…Ýdžá£ú‡]a•ï|·^#óºf§/£%o,ŒNdõÚ.Ëâ©éUÓÉõÅ®œÍç´˜—¸âõj±ÚÖÔ»ª5hÑ[7Û쾇ڹ}TÜåÙ·‚ «T×€¹U™ž—Oš&b¯ùKek4¹O ã_S°@âßÓ—Œ½rEv˵*ÂŒçÚìu*ÆîîWzmV§¥Ó»¢ªø©˜¤ò„ñkO"¾mM†©ªÝ¹%±[Ñ}¾„ ]ÿÝH]ÿyÅ3øöêŽÙª'Ñ»>Ö]9­©çì`8ëYå âΧ“±ÔšjN]÷ìlt ÍòóÂîï‹nó Qćú£ÛÑÐêqtó§í$VHßëÑ9Q)Ý‘y‘©²/2têRϼæ©ü-ëTÇdÕ3èÝi9­¨åê÷»“æ˜vFÛ†g–Y¬4®ßiîuñRƽZ#‘;ÜÔù\žÔ+F«yHôl”xkë3››XŽk-è°R#•Q¯¨‘¿èî¬cößÚŠ‰Hq¾ ¸ÄÕë’\î:sÃ-C\énMBѽªäôÒ¥É2ªªlˆUô‘}Uæ,ž–y"*ålUÚѪ-¿\¶ãPó9~ŸÝS·d]»Ó±TÝz9Q:Ëò¯¹vb¼ÂõWgª<Š}³W¢a‹s5¹W #OZµëýÄ[æÄ {íö‹ƒ_¸V(^å©f9["¦òJ‰Ù+¼g?§*ìLœ8ù.sÜÎZ,«\ë¾…,ŒŸ™ö8Ú¯¹Õ5Ts½N×"tr+Ü©ö­ÝtSH8wѽ µ¶Û¦x-¾Ù/*$×3¶®¨]º¬•ÞG'U^]ѩ̼­j.ÄŽuL¿,Áå6c‚·Qyç®{g‹[råwgz¹ÖZÞži¾¤ø¥&§˜å5’ÉC̰ÒÀ®w¤åÝÎ{Þª÷¹W½ÎUrø©²g<)ÏÞMÝ:ÖŠÚ¬ÏNk`²º—I5J6}¾á3•\¯–6õ‰êª»½›ïºª±ËÔç=×âW‚½AI* »â7.nVTÄ©-¾ç&èœÉ¼5 ÙwåvêÅ^¨×'Nïûö=`ÊmsY2{¾ïn©j¶j:úfTA#UÇ¢µSeTêž'‹–è»LÑr5‰çÉZjšgXææV–yQ£Wy–²ànjrµ_&ë¾È‹ÏÏN›î»µý;‘«Þ[œˆ½Ô¸éþƒõ6ÃWSUjÊjÛZ"o¾ðH­‘6]ý‰×¹QW@Ö_%Ö„ê•·?«¸`—yÚ®Ž>Yí§zªÓ¿Òj/vÑÈÆ§ƒ| {¨¾L%ðꚇâ´6ŒÊÞǪC-¾µNænÔEt3«yUy—£\ý¹]×»x¦7cp™Þ³3n{8Ç¢~ɆÆÖizß øº4ÈÞ2´bRͬb´lj7‘쯆™ÎW&Ûýour»ªx«¼w2T|yñ[FØØÝTt¬ÛòÍg·½\›î¨®X9•?ɱ»°ØºgðW)žýcì–m9½©ùTÏ÷èv‰¨òƒqS4.Ž<úŽ.ÛI’‰\Þ¾Ñ*JŠž0x´Í*YGO©÷ÚŠ…bÆØ­TP@õG*'«OUWuDEïMÓe-Q°øùŸ*º#Ï?Êõ9µžˆŸW½Ø[…Æßi¤’át®§£¥‹nÒz‰[lÝQw9QuTO•Pƒ5;þôÎc~kIqÎbPØ6¬r¹¿YQR¦êˆ»¿}÷M—•Ûsº‹A8Í×i¡ª¬Áµ"Eäì*ò 'Ž'#‘Q“V¹¬TôUQÛ'MöÝ7žt¿É-ª÷Ùc«Õ\ÚÍŠÑó1]K@Õ¸V9¿lÕÙYm‘UUVôÙvøM†³DÄâ®Í]‘zøýŒk™½SÂÝ:w´íbò‘ê–oö}8µC…Ð>_F­“yÅ{˜×5[éª##UV»tF¯Grî»nºþp/¯\IÝ&¿d+[‹Yö6¦÷ÓNéêQ7j¥4OÙÕ Þ]•Uìbm·>éÊtŸD8áãCbJ«V"ÜŽôæ«_wÈ[dè‹Þ‘±Z‘D›*¦ìb9ZªŽs‹KðYv/£s DS¹ïžrÖ]¿rüëruDœ=ð¿¥<6ØÛY·ºVAwKÍKœúª÷1;ÕUU#nû¯fÍš:*õYl5hëç QÄn>¶}A°µÕÐDèí÷ŠdHë¨UW}ã“n­ßª±È­_fýNXqÀ²ðùT쎫1ÅáÞvÝítÏlô\«º-D-W:=»ûF«™Óªµz£äá–Æ ãÅoÊi`É)X¨‰,Î쪑¾)Ú"*;åsU}ªXl+Š #Ìcse¾ûƒPÍ·†ð¬§EîMÛ'2±SuþR/ŽÈ] mࣇÍs¦žkþMf½Ë»›{²FÊJ¾}¶æ‘ZÞIº"'×*§U<’z‡g’zí!Îí¹ /;ÝÕ¾gTØÑ»µ©"sG#•wnëÙ§rôE]µœ“ ˆã»=žîIn[¶¹®_EUxÊc¢®3éçéÕ,Ñ×Q\iÙWo¬‚ª ’Ã"=ŽEMÑQS¢ôT_Æ~å¾ð¿ÅÖÖJ丹oB±»e«±2Z˜•9öEíiȈªÄïT_SÚÝõökæ¿âRºÝW˜]é¦nüÑ\©#’Dë²ïÛÆ®ïEO‹eCMsf®Çâë‰ïÖ=é~ÂF¨ÿȱTOìÌO·uÐP8¸°×(ãF?*§•S½ï¶Ón¿ÐÄOõ%_:éY‘?9|l—}Ò* V+SØŽHù“åßrÌlæ+_•O¦}ÌÉð‰•Äk\ôSü΃š®Oªšs†±ë’fvº7±\އ·I&Ý»î“7zí²§wNõD)e£ŠÍ[‘(­6HÈcZÇGKKVêdEw*9üˆ‘µ»îŠçl‰×uèJZyäËâ‹5– o¶VC+š®šñ^ÇJ‘øªChþm·Ù¯äÝ{Õ©—gfºo\ôGÛ>æ«á#†˜Kz§ì{ôϸףdrÐéÆ;$²9©_qôZÞ±5U]ÕwôœÝË¿HŸÅx‚â¯-ІÇk¼dSO?"ÈØÜÚ $çMÕïÛ³ŒíÓu^¨×'C¢:?äªÑ|*¦–ñ©·û–u]¤´Žo˜Û•û1Ë+ùztYy]×™Š‹Ê—'Æq¼JÚË6+ÛlÖøö䤷ÒGO vj56dhMšÖ§wsQ< ö.Ã`ÿO¾rƒf{A˜fó¦&äîþlpDsóë*wÓCÒzš|ÃX*ès\žÅQIM$eºÝ+}ÚŽTZ¥ßeGHƵ?‘ºsX5¥WÞ!8ÐÞ"*}¿Z§°ä®jï{²¤pÏPîTFùÃUªÙÑ6jnäçåNT{P¤™apñQ=^ŠäNÍ,(‹4·«"›ÑÙWž†w9Ë¶ÉØºG*téÜut+·EÚwkcµvÍû¸jâ嚦š£¦'IôðñkŸá7°ë“ÕÛká$Ììf žªõ‚tUæF®ûs&û·¹ â«F²EHå¿Ïf™U±ÜéÖ-ú'^vóFûurw{:2Ê0¼;8¢m³4Äì×ú69\Ú{¥UQµUª¨Ù¨Š¨ªŸ"©^3ß&ï YÇ4´¸ev-T÷½ïžÁp|;óoÑ"—´…¨ŠíÑm²'ª›‹ÙïbižÉ÷ê–`öë7ÂéÕ#ö£í'Óª²e¸¶KgÇr;eÍŽîZJ¶K×mö^U]—¢ôøŒ±ªåÞHZÈÚ<ÖºÚEbnÝím™UÈ&…ìåë·üÚ÷÷ôëܼŸœq`Û; Ô{}æÛ#†‹"ž%åOŽ¡¬»wn½§z¢knlÌÿë¹é„“á&™1=5}“jj{ºiŸ”—kßpÁ®WXRDTZX­÷rn©Ñ)ÕÏD]º¢¢*&ËÓs >§ñ¡Œ*ýðýyHØŽGIS‰Ü"EäOIÈôTj§rª¦é·vÛ˜uìî.žSç÷ÃokÂSsåEt÷Ä}“+: š¼aj=¥’;"ÒˆãHY+—·§F;›m—®ÛÙ²øÿAúCÇ_¨“鱿^¥QõoøË‘ã£ækç{:·Èêç{Nújû"V¸sêçµ|ÕÿY7ýØú¹í_5ÖMÿvyû‹Žý®=뿲?ÓÿƯåZ0UÏ«žÕðsWýdß÷gÏ/q$Ši{ÞÏ}嫸’ÿhŒ—?úýqïRvÏ#ýÿñ¯ùV¬B‹Œ=B¿JÖãzJÚÄUVrÀùê®DÝQ9ž.Û|gݯqƒ’Ɖ‹è ÝísÉ%+q©vȪÕT^­ÙSý?vœ‡<éˆóÃæÝä´G æ{©Ÿ·E¡w£À¼¤™žÉkÓ˵µûY©((;¾:¥k“Õ_ í¼vgOÛ.Ô+}šåWÇ]’Læ®ÎÛÑŽ•b»n½vßÛ¹“FÍâ'å×éŸs]Â6ÄÚ®®ý#íŸbZ»dXý‚>Öû}·Û˜ç櫪d)ËíÝÊã$âEñÆ9”-Öv¢ªCmÓ+»ûž»GÞݽ^î¦Õ‹ù!’¦¥× I×*š§È«ÚCkµì÷.é³–y¤vþ2mÙ÷ª.ë¶Ë9aM°÷Å5~/wÊg‡ul—»£ÜŠ¼Ê»º8(ÝÑvÙZ©²'Mú™Ö¶jÍ?®g»‡½£ÅxGÅ×à fš{æjþU¸q‹d—²iF˜ÕÜ«%ß±J†¾¢gõÙ?¹àëÝ·sתíáºì¸Ç¦V? ÇÞß8dw¥J~e^­chaNÓ™«ËÖdb¢*õWn‹Ô¼7Op=; u¯Ã,˜í$œ½¤6º©["·}•éS™z¯UÝz¯´Ø ¾.Âág[tF½|çÖ‰fE™æ‘4ânÌÓÕ#ÑkçÕWøzò{hv„ÍI‘WÓK™åtÛ9·[¬hÀý¶U§¥EVGਯYÕîzw€9¥ ·ÄçÙ û7ëN-!Vøœû1áŸq¦ýiÀ[ðËýG|Šz<¿ÔwÈ z*nïÀÉ>Z¿ÐilŠ›‡ûð2O–¯ô—0•˜6qä÷C²Uv{òvÖø_Ë¿~Û·§rA›kôÚ{€ÑÌÚšL‚VoË$vÈZäÝ6]•¿r©žŠ( ‰ÃcŽ6£XƦÍkS¢""w!è1·g¼vžëãöÚîÛnÓÎi#—Ÿm¶ß™}¶OèC$Öþ–zqðÿUAó í ¾%†‚Ž hÜîed1£®îßdñèŸÐ~àøVPÐÜ"Hkèà©®æFM=¨îíö_«ý'î×eÓ<žGÍ6ŽÉ$ŽW=îµÀªå^ªªªÞª}Ö¼S±¹eÆíV÷#•È´´qĨª›*ú(U:|†P1òãÖ å|ÓXíòI#•Ï{©˜®s—ªªª§U2 oég§øßõT0},ôãàÿþªƒæ [úYéÇÁþ7ýUÌ2TØÎ7EÙyž?mƒ°åì»*HÛÙòú¼»'M¶M¶2@Vøœû1áŸq¦ýiŤ*ߟf<3î4ß­8 ~y¨ï‘OG—úŽù@MÃýø'ËWú -‘Spÿ~IòÕþƒ@²à[âsìdž}Æ›õ§«|N}˜ðϸÓ~´à-øåþ£¾E=_ê;äP=7÷àdŸ-_è4¶EMÃýø'ËWú Ë€o‰Ï³÷oÖœZB­ñ9öcÃ>ãMúÓ€·à—úŽùôy¨ï‘@ôTÜ?ß’|µ ÒÙ7÷àdŸ-_è4 .U¾'>ÌxgÜi¿Zqi ·ÄçÙ û7ëN߀_ê;äSÑåþ£¾EÐSpÿ~IòÕþƒKdS Æ‹Wq wÉs\3O¯5ý­D¬‚u³ÔOØöµÍV""÷wï°ÐwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgïN)þ +6ë?xˆwéÁÅ?ÁeoæÝgï>Ëf­q94¯m^™VFÔn諎շuüj–Ù}ƒeöïé¥ÄoÁÍ_õWïM.#~jÿ¨*¿xeö —ØW¿¦—¿5Ô_¼}4¸ø9«þ ªýàXM—ØUÎ&ã{µ‹ V±Ê‰ 7röÓŒÿÓKˆßƒš¿ê ¯Þk7¨u{<ˬ·œ—»Âê)a‹ž=DlHÒ^eWn‹Ýºõâ€_ê;äSÑåþ£¾EÐ…_qÌY›%%;gó^Ùœ¬k7‰bÙ7]Õ=›î»ô]ý‡ªiÞèò—úŽùôy¨ï‘@ôR̳*Ìn®*JJHdYbí9¤U軪w&ÞÏi€¸jMòWvöÚá¥jì’5r¹~5ßdùúO:©ÿ,R}íÿѸéè©kŽiãówBŒXöôyU:¦Åß&˜‰˜Bj”Ï·±‘ÚÚë‹Ë²*ö_¢z˺ôåßñŸ>¥_©jÑ.”Pº%]Ý1csQ}›¯ûO›L顨Ȟé£kÖ gHÍÓ}ÌÔßúM‹Téâuž–©X«*R4vÝyU®UOéj¦)Š·t5DUtñÔÀô|rµ×"÷¢š¥^kWVÌv*(R5ž8#œªåGmº¢tÛ¼Éá «ŠÛÕUWÐròJi5ßdÖýûûx¦˜ÖbD¢ªEs•ªªš%ëSâ§–J{5'är¢M*¯#¾F§Uëñ§wÆm9;ß;r{¨¾m"nŸè©¥éu¶Š¥õµµì–XU^Ô^]÷ÝS~åéÞ(ˆÒj‘¶a÷ZëÕ•µ÷jJù‰ÊÞTåE鱃Èõ-õŽ ²ÓÅRø×•ò¿ug7±¨‹×å6›íD”–Zú¨UÉ$TÒ=ŠÞôTj쿈Ñ4¶ÝKQUYpš6¾Zdcb߯'76ë··¢&ÿ(¦"uªG„Ô,ªèû•ª.ÍËÜø_÷w"ïÿ’›ÝŠùEP6º\ydc½f;Ø¿¼ý®¶ú[¥ÔU‘±ÑÈÅMÝö«·G"ø*{HûJêdmÖ²{9)ûUMüZäDý%+ªfb9 0ZËýG|Šz<¿ÔwÈ zê§ü±I÷·ÿFâI¦ÿ‹EþƒØg¦§©ggSr·ù/j9?Ö{DF¢5¨ˆ‰ÑSV±"í-þø*>óé°ØuKûß§ûñŸ ómm5;fZ†ÁJ­åY©Ì©¾ûoß¶ç§±’1Y#滢£“tR³^µo &ýêÛÿÐwé¸Ò«¾É­ûöö4“âŠ(#lPDÈØÞkˆ‰ò"É)©å‘’Ëo|k»梫Wâ_i3#•{w/½ŸþÃVÒø½Ëý8¿Øã~?8©©àWº#d]Þ¬j'2ü{w”Š´¦`* ަ )¥EVJÅc‘nŠ›)ST]töý#%§í!“v쫲MýŠËþÍÔ–ÏÊ¢–š®5†®ž)£^ªÉŽOèR´Õ»ÂD{yÔß; }-²…ðË+U®’EEåEïÙ 1 LÂ'Y@IDATxí¼ÅõLJ^¤J|ôÞ‘fAì]b,‰Q£ùG1ÿ‰š¿1ÆhlI,±·Ø+Š * ˆ ]éEé"Eð?ßÑó²<Þ}ïîl¹»÷Îù|öîÞÝ™Ù3gÎoÎÌìÌ™ ßiRŽœœ+ЉåÌ1æ$à$`$à@êÁI áp Mx9öœH8 $\¤ / Çž“€©Ó'„KÀ4áäØsp u:à$p 8&¼€{N•ö”“°8*T¨`΄àâ~ÅŠ»×mÜÛ¹s§¹/ñÃ5$qwìØa®+UªT|ÏHè—É#yh×®]ÅœK¾y.ù-~¨/D>Ä!þ·ß~kä#²(-Ž7~!_WÐÂuÓKhŠ$ÊÄ#HÄÄ™g(÷+W®\ NÂòœûÛ¶m3Ï$¾($q9ªU«F”Ä’ä¹$ƒäŸ §jÕª&Ÿ¥=RYU©R¥8ˆÈ™ØyÈG¥KÀ´t¹˜»¢ŒÄ­[·K” eýæ›o ÷‰Çå”pjyÎ çUà2XÉÉ#©pà“¼Ã;²€„oÀˆ #×C—ûüGœI—0Ü—{^Àæ$³ ~©kî–R8(‘ kÁõ¦M›Ì±`ÁõÙgŸ©%K–¨Í›7›Ø 4Pû***2ç† 0K:’–(²(;Ï“Lð ÏPõêÕÍY*™íÛ·¹²-[¶¨µkת¹sçªÅ‹«5kÖYddÑ¡CÕ¹sgU·n]sp_dC¢òó÷³‡œ%ÝC$ß7YE‰PÀ… ªI“&©>ø@-_¾\}ýõ×ÅÖ+‚2cEQdÛ³gOuàå¬_¿¾±(" ΙðX›RXHÌ-@ˆ,à]Ê=@ºråJ5uêTõþûï«E‹`b9ȧXO®k×®­:uêdäÒ½{wS™a=Å’ÆQép -E.€ˆ%|ñÅÕøñãÕúõë‹›m I»äÿ,^aÄû.*x ¿ðÇ3¹ÇõË/¿¬n¿ýöâ0~_Š Å2Ò¯¾úJ 8Pþù¦)Ìa¤…!€÷ûž$†9Û”s¶|4HQD ‚£y÷ì³Ïª§Ÿ~Ú4M.÷Q”‡k¯°³2áxW“&MÔ5×\£Z´haJ¥Å% VX¬Ÿôƒ„õö«É|@È7ryþùçÕ]wÝeøãaüicyÉw:uL¼›¾êyçgº„á}¼ƒYäyõÆ/H+]­)„$("#µ/¼ð‚zàŒ‘‚Àø¬—” À£4‹ô(0JôÏHW@{ßëM#Êk¼H3¼Ã3²yå•WÔ£>jøÇúKåeÃï"md!ïâΜ9Ó€•¾»È\Î6ïIr¿ºTЖ”æJÇ Š@©Å÷Úk/£ˆ4¡¢°6øD)I«Hƒ”&^ÇŽ‹›¼òy—œmÞç7 ‘¼É™{7n4MÜÇÜ ú`åùEPmˆôi9P1!®!®[µj¥.¼ðBcQ '•‡Í{’y ù-Û‚)ŠÂñꫯªûî»Ï("Ê'#S”–k¬ŒMóK“´é÷’Š~ÖYg©¡C‡šJ@š¹$ê· Eüž ä‹ Š3ü­X±B=ôÐCjòäɦeA?Y*€*2²yà¹ÊYîÑg¿øâ‹Í0| ¯|  -èæ.JðÉ'Ÿ¨Ûn»­¸ʧ¯Õ%E±i Ô(8@E!i^€eÅ¢Óì# Ïã&©)ŸUn¹åõá‡0Z„‘~´ ÈüvòM CÀNú4u—-[¦Ö­[gØøŸ YØäÍO¿:T0–T”Ð+LfÆ\pÁf† ‚ã@‘PT£ ($ÊÂ}¿D0A)IKÞƒÒ÷êÕKqÆf÷9hrû-̲ø*-ÿžÊŠç|Ç|î¹çÔOkt*²Àš’_Ér“|s/Ÿ(orCÁв‰BRˆÜg](«ZøPNsOˆ¥p9sßûLÂDy†WQP®…îÁ“X9”UîK^Å*zÁM!‰Ë=ÞA>ÔÜ'ޤ)áâ:“'ˆ³È¥üàûLþxýõ×Mßyðœ3Ï8È'yH"Á—~ùûoiú™°ð€‚å,…N¡¡Ä¯½öš™Y$ÜO¡„T,ðŽÕäÅ$Ÿ(¯ä•3ùçLŸ@—ÿÄåZ”…&¬(’eŸR®t Ðó«ô#/2á¾X]¹Ÿä<ùå-o@Š2R@œ9Pd io¾ù¦«Œæ Xý +Îðä Ÿl’!òFå ÉK ñD¥%e/yJhV¬ØÊ›O0X ”“f-–7%ŒR `Z E„WQF¬ÿY ~üñÇ«6mÚ˜)r´°XD,­—¸/Ä¢2OwâĉÆËà%.2# $goI»†GxFðOž/ºè"3ÉAÊùq$àYȯ¬ó¤ŒðIáêãßÿþ·,‚¡`“Jð,üQ\K>¸Æ‚}ôÑêÌ3Ï4SiꕘäE…°”¢œ¹OZXÑ>úÈxA´ThAp›—åèG€Ú´iSuíµ×*æø’Gi%䈭Œ¯ ÒäU9³YöjU”—Õ¬‰Ä‚¢ X”4À„_ ¢ ‡d).E˜HÿËJž8s@ÄË‚$CÂrF&¬(Áú°Â„–ï!ž ñŒ#éD¾È·ÈƒµÁ¬ðANiàß|“­Á>rÂh.ΛÕÄjÐìC¹“N( 'Š…u@Ñz÷î­Š4P!Q<Œb*®%aìÜ—kžsH‰Ë` Ç4£yNî•L—´“JäEF«qœFùÓŠ’J*©|ûå+o>Áàvr‘^À\R)ùŸäBƒ?M¾s2ÆânÖŽ2H$Ï©tXÊÀ@fS¨öíÛëH|yåxÌÎÁº° ŸlúôécÞCš„ÇëŸsøœÁ=¹/ õ«Lq†¹Tò‹E}ûí·\¨|¨Øò…RRQ@ŒB¡ è»1ûä½÷Þ+.ÂI!qd‚?±ä‰5ä3Ï}åšÏ'7ÜpƒY°M8, ^ßGŽi€Ê=/ÑÜ¿ñÆ‹×Îb=8àõûßÿÞ  (‹´µö‚€ à¹N2 ßÈ‰Š <øàƒª_¿~fÒ •÷©ø¸Î%Á«-¥®¹‹¡0È4ÍD¬ËÝwßm›ÿœÇCÁÄ``5É• 4åÁdñ6Û3°]}KîÍ™3ÇÄ¥R"-ˆk¼ñ³U#ÊIó?¿Ìc¦ïFºÈŽð2%¤²“g„#¿i¤T”‚@èµ$žès1].­@`¢D4ϰv€ x(Dx±°2ÈÄsi¢’é (%²ƒxÆA8€Šåý–´J×DNÐü‘'x%¯ÜCf€“¹½8÷†Tx ÊBÖ¬¤ ¤5%…A0wS,GÖ9NX@ò"y,ü§)ËÔ=ò†"6nÜØl»Àȵ(@Æý'sWQJE•4ðßË€LšÜçšÉ LI…À.漟ÃKÈ:É$ü’Ñ òHž©ÐÈ+ÝÅ‹’äFJvI”¨ý €æM7QÒÁSóåŒX6%Ãå&gžÑŸd³]<\”¾&3€DIƒg\rÈ!ÆËÝÍ}|ùâ‚Äk}æÏŸ__FXŽ$“€€$ÿœ!äIÞ˜ÜBkA*+ó0e?‰n¤SåCØýë_Íg•ûXi¦Lþ†]‹PJ~Y¹‚5åÓ  0`€É7ý-€Ê¬¡Î; ‰¢#®±0Œä²ÈkR¤GqùÜ"S Lj1ýz*9Þï§È;©ò *7y†à›kdDZ[:tØÃ¾€9©ùóò•HJ-‰ i†òRÔˆwÜq‡š:uªåD)Qj #­„RAä«¡@K—.5³§š5kf,!#”,MÚŠBV@Í5#µBŒC‡h‹ ‘>„,%­¦Ò ½‰pIWbø–<‰ È|#žIî½÷^Ó5 b“8ħ¢â?á%,yФ¬ý¾+‘Í]2@QLiòñŸ»)S¦"\‘á4ƒ4“BÐb`ÏTÎXSQ:)èLñ2Ý÷‚´&Mš´›ß§LñÒxß«R¹_}õÕf2>ÿ‘!–ÙP¹—Ô¼&¤¡Ñ”• â%Žƒ¦­X ,áv¾µ<+éàVæÅ_4ÀGÖùFȈV–È Yò‹V;­syp¦ò‡üZ·8efWârˆ°5‚XOœO­]»Ö(ŠÅA8@Ê9߈üñi‰-1Ø»뀲1PfC¤‡,QJúi ªÐ¼N²rÚäSâ ;*oòÇ'+òÎÄ6ꢒB–è Ïѵ$S"µ›ZŽÁâöƒ$RŠp91÷x>­òxçwšùµA*$dÐY)Ĭ#äÆœóÈy%oÈ ý Á™Á²ýë_f!aÐ1ÂQ‰%• R†P™5âÔþ(™XL©)€¤ ضàÉ/Mz&l`ýh²¡T6„Ìø&ÊG~¾·"c‘©MšICž ä&>–•GºQ´ƒ:vwgÅ VBÖI%_ džƒkHÎeeepr&¼( ÷ä>gFé‹aAP(¤vä¹ð@!ä+H‘5¿È °|ùrnâ>r€¸.팬$>Ï,¢Ÿ‹>ù䓦#·ž#ñŽB$” YPû"/Žì`KÔX¾Æ”7äCs˜ƒÿ(Їg¦R¹-Ò^+DŽ”² û)¿´—yG¦Ry¡ƒÈ01ÂÂÓN;Í8!GyFXâ ȹ.)á8x„®Ó}£|üP¥«5e_ãÆ3/ÅS/ƒÈ\6L£(„ãL¦½±(ùþûïWãÇ7÷PDƒˆßÌd“´„¡å@&ȹ 8и=yàL×€©n¬†áû²l×®™:H··)­ZµRO=õ”éNHšÐ’v!‘è!yF¦È¹Bè5lœ1B„¡YŒ>BÈ‹4ÐMd™‰/i“ÍjðÃÜi ‘ÊÚ’â?BÌúÁÿ“»ñ¦Î|RÀU‘)jnš[|Dçã< 'Mi^aÂ! Ê#‚à$ÿËz_><#Ÿ0²yˆ¹ÏAsV ÷éÏsM­ae‘­´J¨ÅÅ [iqYçƒÜÊ˲âœÈFdÌ=©¸ã˜1cÌñ¶mÛ«Êè;€E^8ÑÒa €ÍÇlF‘i1"S”Œ÷³)ÌH^Œð “v=µ±Ø“·,«L”†inñ &ŸXÊ'5”O2ÎH@)çŒ9ɳÈù!òŽ<¨ ¹/ÙqŸ3á$ á 'áy&²¥Dþ„/4¹J~(×"΢—ÜGWé^ÐÆ™8-<ås°Æ—o¯Rññ½\ˆŽ³òˆ%•¼‡r¤É{ÐA™4üªjÖ -*ú~©`£o ÉË©X>¡Þƒ{0)DÆQ!#Äs!ïµÜ+¤³ÔÔ"+ÎŒ.  ;–´!+Z)È?F<Ç¢rŸ)•”V•4½ Iš^ù’|É«7ï%¯‘è Ïh²ÒòÃ8A<£Æ›Me,²4™3]•òZ&ñ?¾ö‚ŒW^y¥)t˜¤và¥ÔìÔ@(·††iþ“É4)ÀˆÌé†H³–t¸ÇÂA”ƒ(œ([þKÔ>‡ÈH@'©ˆü¤œ-á­œ©4)?0pâ‰'šòã98ñCÿmw– fPÜxˆÉæe0$Ö”$„I2¡8܃äq•/™qˆÌèA¦…м幀{%•в’JÔûfÊÕQÙ@F"?ÎÈ™2Ù!k*AäI™¡÷”U×®]g ʈg~)ëRèŒêwÜq†)šU0-J! Â<áaRjþF%s~™-¤ðÈ ùDHäì•ϹÏ=®!âAR‹Ë7>ÂIQÂJxÉý”*䆜3×ÜGž”‡<ç piÕ >¼ø÷ýRÖ ¥9`ðØcUEz ¦`VE˜‡ OF`Lþs-Êâ—ÙB OÁ#+ÎT†VdÇ=) ‡œ!*E©4 ƒå¥\8¤’$ i‡ûŽÊ–€W^È2FþüÈSÊx|¶Á£>­îÛÈ;k’8¦›1ü| '˜Ú&9„‡B1²…’¾$•v¯d˜|ú/@¢0½…ˆ| ä!r”°„£V‘B†¤bä9Dš¤CÒá¿(Ï GšÜ㌒¡L\KÂOø#Dz<‡©¸WH$•2CÖœ!ä å#-î#G*V>KqÄf ñäh#»ÿ¢‹ÔË! Âß|RæÅ/e¡‰Åì Q¬r’ÍûÇ€BÀƒŒ÷(H)pˆÈPy…üœ( á Ã}Δƒ–tI‹ç¤ƒe%>÷…/);²Ä'DÙs@rÏü)àd øÐsd)ƒxÈÐvïÞݸP¥œ!äj#»¬Gwy/‡)Î0Ä&·LnX¤¿ÂÖ“é‚CäKÎÜg\€ùì¿þõ¯•²Wï¥Õ@‰ç¨¾@j¸*å&(V»°Óòo¼ajqÀ Ìsk)ÈR’Lì-4üs@´$Ø«…ƒÝÌ •hI±÷ ‹h#+ÊšC”;­²‘²&:ò‚•ä?cgŸ}¶:äCL¾¹_’$ ¿z H±¤XW“˜üÍbcú©ô¿`ˆL`ꪦsE†ü2[2Ó¹úÿ è|ðÁf+AÀ6m׃7›ôJ—ͬ Õ<[ô@Ï7Zñ¿ÑMÌmz¤v»n>æ[-{CT„\üP!ÖÖµz]»WÕePUwKªé£ºž”_ƒC¯k¬©£öÒŠU]zDAXV}1Ï›©’ÊÅ;£JpÁ?gÊžk¯îr}ÑE€¢óTNÞçÂWNA isà Í^Ö‹Tˆ“)jÚë’QÎ0-™Hú™Š†š’íé{„Auëc^¼–WÝç[§=VlÐK¢¶è¦d\TK.¨«×JrÔãÐZMôÂþºz³¨0ßL4‹ßzë-3ªFšq¦ž:ùÌÂ5:Q¢/zî¹çªÃ;̬Lbd=IHÖðR2CŸ1ìÆM&0’ŒËÿ$Ÿ™¸1dÈ5xðà@lb WêQÒ/ô Ë*íNãKí|{I¥šz3í#©™n¦?Ìï£ûZA‰Ov¸;vlФb‰/€¤H·†ïÍ€ÃP± ÌÍEÿÑ{â$¤XI˜0X©e, }ôÑGÍ5V•0âX¤lùz³g&Ö•û2Ç‘xü'Xj9;qýà<óÌ3³ì—z_Ðéš7Àé(\ ôÑ[9Ø:zÕO¶ôÄO˜m€(lBßdBðá*èœsÎQEz:Ì`·%‡%ƒ")™K(`•Ú‡¦/Mæ€Ê·3Ö§RÒÞ§Ö" ©¹l„B_‚)[l¹ 1*;M÷‰ r­ºë#½t·£~–eÃŒ¶ûî»ÏLŽ“3ô }DÏ%ß>‡ VìyÆ@`0Ååš8„š")™ãÀ’!2&µ÷!ÀË=>Ñð¹†æ îù(Ÿuˆ _â˜åü°.“Ù ‡zh9!¿¼”‰âz_T>¡8ŠWÝtëÊl§lˆà{î¹Ç8È&|yahµ±ˆ]9r¤j¥÷ÏÁ€@Òeã#: Pó¤d `’12éÍœ×RbEÙ̉)…â RÓÑ!.ÿI ¡yÓ–t>úhuÞy癚ï{2ÿ~¡w¿þPOct–3³ŒâzB¸¯î–ÔÖl6tï½÷šýlK†CG tÄ«gÜ# ‚3þ¤ñGÄtOÀIXÎ蓤%gâú%âB¢Ÿ~âGnIý0CX2PiV,Ò 0+a2©C‰0ùŒC_â;Ö/ùKãÉÜ(ã‡Ï(“ô$‹™®ÏY†”róh=vÐדּÌ"ò8`ó/œ°Ç-$_Ð#*vþ£OTèRÙÓ¿äž0~ô£™)ŸLR@ŸÐ/Z|z…ç… $ %¿@MHÉ„ŠZˉ‡¦²<£Âòœ°bI)š)¿øÅ/²²ž“t¿æ] {…GzI£Š:ÿÌ¡eåJ }®ùÃÙ¬dùá~Uæ’jÅÚ©[œ¿õ\Ëý­Zn›XQ£9'-¯¥ñ3X»!¡Ïš ÝqÇf‹G*tù:€~p ðÿéB<æb3»ŒŠB¯ÐÂC\‹%67üxõ,/@*¢ÖãÁ"dÀ*ËŸðÅCMHPKþêW¿2ýòä8_÷wß»ë.µN§•4Ú[X4ÔÓ9üpk%Jiyõà2[j¥eg5N’¨žÞÅìÀÿù31¢<¾X÷ÏþÓlh™€=Áe MZf–µnÝÚè:†]“ÿœÅ¢–÷Þòž“–PÞ€¡‰àÈÂCà4a(î;d¢SOß³H+xYÄ÷Íwu“ˆYBI ÙR÷ƒšè}/”u“@Xݬ–•:«õ§¨8—Îe’A ¬Aº¬hp•EŒcÜtÓMf4J׈=uûöík®lX¹‚.<ôH€#Àô6s½F%yéø~"û¤ˆ¦.µœ4u¥Vã?D¦tY„gƒ ·Ü¢>×}Ù¸ ¯­´óð¦z"6ë1YD/´C'\¢§ìÖ%úX¯©ÇMLäzÙej/=˜XÉWô…ï›â•œÒBC¿¨ü ‡Þñ?+ëÝÞg¤%” •Ì9ÏÖž&üýïŠ5qRS=a¿^ ÎQÛÇlš8y û]V@»ú‡Ö°ßQZzUt+jøþU_@JE_ZZI¾—HKT`ãôf­4qã"ü 0iÊ2áub¶^€0óå—ÿë)bð©fÐÏ^î[°f~­X¹‰Æ ¯@Ê\Û±Ú›>ë;ã Vw´ýÁjâÔËÑ%°NÔ™£GÇâ"¦Hw-†^~¹b¾QÞ€t–žððÆuשït³&j*ÒÌ9m­ç;*[›õöu–ì†+ÊÂÓãõ‹Ïó‰ò¤ïêØL닚ðë8Ûe98j~Ò”>cÀâb&J¬¿™÷:å”(_kÚ©)³i^½æÅ…( Oy€³£^á(˜hé0^ÀB†(-kOTC.½4³ ‰Z2ì?檫Œk̨dÉgÀÙÅÒ)YT|åCº[ô„ƒ4P«÷óD˜y£Ÿ:BëHTÀÃ䵬´R R>¨¿¢‡ÞéïDA•õD F 9E+Fƒ+ni¢ jzùÙIz¢FíÚE‘|,i¦¤ ôÜÌÑW\¡vé)]QP=ép2]ÏQ|˜«ecU™Ù§§ bYÓH©éœ×^3}Ð(Í4=ÀÙí¸ã¢HÞ¥™…¨x±ªSô¦_ìs6~啾¡…̓Mz©)ŽÀÆ^½MËÓU/W 6¾bËMÜð-šÀŒØãù?l:HÏû퓿߰ß$½T€”Ñ@f…M Û¶UýúS3[(ì´]zÁ$ðž[ P?zì±` •›•4ý~ò“Rž$óVâA:ãùçÕ›7ܺô:¡ÒØÐQr%0O÷U+^4¤45Ñ £}½zõÕa–I pâôÊQ:$À綉¨ag!y_½§KÒ)± ]¬½Á=wÉ%¡Êæ-Í·ic¡ )Á‰1« «&1á‰I¦D‚tµÞ"ðq픘Ea‘kÞ†%ÉܦÃö¯_{­Ùñ<,N†ÿñ ýH*%¤lªûˆÞçk=#%,rÍÛ°$™ŒtXíÄl³0ýT§×³p"‰”8>§'G³â? bæÐzn¯[­†4“•î[˜ÔÂì³0‹'kXIœ™T¶ÿ‘0rï#7õZаŠËËo½ÕÔ‡üÓ”QùSî¼3´òÝ®Ý}bq–4J H?ÔN°g¼ðB(òaöЩÚm'Ž¿å·ŽÑ{X Ö.ZÙŒ¶ ¥â( w›aÐÞûí§N衬÷ ã.ÜJ`˜nö†õ)eÑûï«·ôÂñ$QÎAJçÿ¥ßý.™4îÐA©ç~²òÁQaI€ožÙzº/O2ëõ˜D“Ê9Hqy5ëÑCvÿýa$åÒH©Ø’‚ULa³ÜVêè“@9é¸o etŽhO ù#w Çñà_Gÿå/fgÿ1÷ŒÁ@fTK"÷|[æ;9)«ZØE;(ñ™åìÒ Ê‡‹Ÿ œ Gõ÷íÙ30CøbÂäšrÒÕó燶ììÔ»ïε Ýû(¾yîÓ¹s`Î0&8PË%夯ÿùÏ¡äy˜ö³ÚHÏÇuä$PšŽÔãaLN˜póÍ¡¯Â)ßL÷b)'…±Á€ŸýLuÑ»y;rÈ$v ©gœÕÝwßLA²º—ˆ·t:W+H?çã#hfÙ²:r(Ol1ÉÜí Ä·ü8·.ñò+Hß¹í6ï»­®; ¦†üú×Vq]¤Â”@[ýY&ŒJýíu—ã¦Ø@úþ¿ÿ­Ö/_(õõ.ÍéÖŽœüJÖ Ä–a¯g͆ŸX@º~éR5)„‰ìœUK÷39 ØH€foÐþ)+ãÞï6~pß}62Ý-NïQ£Ü,»IÄýñ+Fÿô½˜?ûEÒ¥}¤¨}‚óf³ÿdw¸¸…!0ú§_-X ¦èEqQä üÀó@+W«8—€“è0thànÓ$Ý: Ó{HY%)Hç½ù¦Â’!Ê–ƒŽœ‚JÀ üè™HjçØAGi¿Õþ·Â0@Ùä©r6lÃm´:à·i’­ð]¼Ý$ðÉÓO«ôàå7ëÖív?ÈŸOžyÆlKÒ°M› É”72KúéK/)æèÚÍÛçžkÝÅs0`$ö1½KÁxíh,L€ŠxãØ¼:2KúÑ£J>¬Î}´ÓâÆíÛ[Åu‘œ¾œ3ÇXÎz–[”„÷žzWñ0&ógâ3K:]¯jân'Ö}‡ùLeæî—!¼Ž×Û>vöÙ*j€ lÙ%EÒq÷n UjÖŒ2ß.í<”MÏûô¼núŠq¤Xî¨(t²þ.µ=äÕ1ÁÞăäÍÅF|‡POvaÊÞ·[·Fó’rRöÔSå„°zŸ”IȶT¡bÅм¾Ùòàâ¥GË?þØô;—~øaΙž5fŒê§¨ê5o:/¡‚tîo¨m›7[3‰[Æ}ºt±Žï"†6¬X¡˜L0ë•W•a–²¬7)›BmîâàÚ–ð—ˈ®#'LÀ)ØûzÞìýºß™4€Â3n@¿Ý¶-ûÖ÷Cé’)S}e»z:Öqó[à>½Eᤦ™F%)f4“)·Ðš»AFÔê6k¦: ^î^Kò¬¢úbæÌTHbæèѪçÉ'‡Êk( e kìÍuŸ\B-×Ô'†;Múaïî`p¹‚N۳옯æ|óPš»A–¢1ýÏYQuÈÏ8Û6m2N¿Ø£6n€22;üPg>öX D³_}5Ô ŒÎ7Κ)vX®§Ý¢8r˜úøãÆzùB`#ÅJU«ªþúóI¿³Î*ŽÞõ˜cÔ³fÿ÷sÑr饪ŠvÜéJÝWÀ=Š-ut}Q[ÑåM<*yš¶,¦Ž›º¼è^ îöêö‡¦ðËe³f”Qèycdž¶%c`é‹¶>ðÀP¶ØMºîOj$À†Hø¾bp(nb$Ö3ÓÄxvþf‡xÛÝÕ˜*Ö¾©A:;ÀegEãVÍd¼׬íü4¤M£ýä ö€“é§åQ› ]ÎŒbÎ/çÎ=SìQ 8ëh+ÕoÙÒ|Ï·éWãsi•v­Ò¤cGkö¬@¤0\S׺¬åœq9üò €þ&à¤ÿµìÛ×zðk™ö ;Hy©-9ÚJ.9ñ°€3ÈòDÛÜì­Gj'[EÄI-4Hß¿ç«W®Ð#Û}´×|[²²¤ø–±!×Ôµ‘Z²âLÑùhÜ¿øÆ 8ùæ™ Âb3{ˆYD~iÅôé~£ìÞ ¤|¤µ!ç¿ÈFjɈÃà âOÙ6'xí 5ô¬¡\­@Ï ßlØ`&D0{Ɇ|ƒ4ÈÖLt”. еœ¹ðÈÇüZÀÉ|Û$PÑ€V …÷/fÏ6S mò᤬\°¥ gÛwºxvذ|¹g.~Q™÷×è[ë•*I¢ “#pžÝåÈ#­²ã¤¶íëÚMš(ÜR8J¶vêµL€k[?¯4öjÐÀ€“5žI¤*5jXÏ> òEÄ7Hv·!×µ‘Z¼qX;IÓÖfp$(§ûk¯tÓ/ I&æÛÌ>ZóÙgÖÙòRÜZ¬Ós2mÈÍÕµ‘Z‡¦mžß£žíàϽýÅ:íÁ¤¾…« _ ¥ŸbKÎ’ÚJ.ºx¹ôÈǤõœœÓD -GhÉãÚ… £鯕+­åéFv­EzÄ­Ú#ýΟx"ô´ËK‹‰åÄ‚¦‘l-)yµý|åË’nZµÊJ®;tP•Þ×°ÊX #åÒ#}Núži¦jµk[Oj°uØ HÙçÅQn%s|Úz2z›„5µ\[oÙ]ôRHÙPݶƒ³á£ã|ºi»èƒbÏ>ß9iÚæ[W²NÔ/ÙvýtÍ¿|™ðõöÝ×*ž‹d/MºBåsJÒ=òÙç0w1ml»‹¾@j;‘ÁYÒx pæÂ#sk™ÆÇ\Û|&ÛÏEßíÚeåæÓHmï,©­äüÅ˹G>Ý´­Z³¦?¦Sºj­ZÖ\ã̯/Þ¬Aj»9*»¥ÕÜ{oëL¹ˆåK —ùX׉õdg¡kP‘ kqýRÖ e¹ 9+j#µìâä‹G¾ìr›œPÕ,ü÷ ÷߬_/—YŸ³é6í?Ô†lÛï6ï*”8¹ôȇ/!,'¾… •‚4wñÃë—²)³Tl¨®Ùµ[Æ8ùê‘/c†ø B… ¦ï½}ËßÜÙlë˜5H·ýµo†ˆ¤ýnõÂ<”K|ø±Åzâ×ÖÑ÷@¯m@jƒ£ìAjQk¤/=JºÒ’G¾¤—…—?ÓäµðwDWÅ/e Òo-‡™ÊUªøåÉ…×È¥G>ÖLb9ÙKÅQé°<Ú¹}{é –q7kîØ¶­Œd2?r–4³l2=)T|™ä‘Äû*U²cK÷gýRÖ µ©`¦’³¤Y—I.=ò±o'Ö“}<•/[} 8Óæ‘/ `kImfàe R›ÄvÜ»>'¥€sê‘Oûv¥Y›V|I)òø°µ¤Õ,Ö¢f R¼¤ÙP!ZÒ©ÿù²™Lm#c‰ƒGF| íæ™rË#]¸];wZ¥lƒ£¬AZ£N+¦ ¤9õÈw Æzæ‹G>+e‹)þ£lÉf²Hö ­_ߊ¯Bhî:|Vª‘ÚH¶^3ɰÍ«YƒÔÖJ>[Òœ{äÓMÛ¶ƒ§VÙÓÊxKZÓÂØe R:¼Œðú]j“¯–4§ù48{ž|rZu<õ|±¤‘ÎÝE²ì1ºvÑ"_BÎ7Kj<òigÓ¶ŽŽ} ¯Dà>§f† Á#_‰¬'ê¯-HkÔ«g•¬-)©³2ß/H‰÷Õ‚Ö[‘? ”s|ÚzºM˜“  JÙ6wmwº÷Һ͚YI)Í Í¹G> Îýúõ³’»‹l-i­Æ­òR[÷œk´%moÅ^î"9|¹“}ÒßlkIé.Ú/ÖoÙÒæ¦¹k1G‘rî‘O[O<Ò9JžØÏÅv>z¦M­2ä ¤¶}"š»i œ{äÓà´­mÓ ß|àqåŒÖÙ°í.ú)>tm>ì_¶L1!9©K¤œG>k½+¸ˆ+€Ôv+_ ¥D¶m«lj¬iãŽU¨Î#_¢Š#̬š5ËŠÏúz#íê–óß}ƒ´Q»vV eð(I uù¬t­ #ÑürÞ<+4íÚÕ*‘|ƒ´I‡V/ûrî\Õùˆ#¬â†Éyä Sš…•M]Û%jñ‚´S'«’a2@.ÉyäË¥ôóãÝ«f϶ÎH³nݬãú¶¤ôI™Çëw­$3•¾Ž{ôÒyä³Ö ±„l›º$Ó uë©eÿ×7HIšZaáûïgÿ–B.™<9¶-óh–8|¾‹ÈE(CtÙl¨Ý¡‡ÚD+ŽcÒ=¬@ºtêÔX@ê<ò—¯»I_èQÝõK—Z¥Ö¼W/«xÉ ¤¶/µùt#Œfsvù²‘’ c#E-GyO‹Þ½åÒêlÒ¦º¹‹¯–m>7Þ°b…¢óÝÄrð)S×|ö™iÚÎ?>SÈî;|‘‰6Q ©í$€H‰Ü²o_e †±Ã©óÈ'ÅèÎQJ€¦.‡ u=öX›h»Å±é~ýû[tåô銼‚RÎ<òémp—é<ò-ÁôÄbEÃXfh Ò¢¬¤Ì¨ð¦/¾°ÞÚÝyä³»‹@@ªYP²) XùãwÂ1ë4i&÷þÑ|ñžS|h¬gXÍt_ws* M]Z›a¸º±)’k}ÐA¾AJ#ÿßaØ0N[ï‘3è^»0¶ÔqÄÛ¨{Ä ÒC‡ª·o»m„Ë»±uãFÓ7íyÒI*§ùôGš¶a •——g÷<=ÀPÌ7Κᶺ+é^z{wú¦øòKóß|SáñÃGñ5pø:Ú‡0;u9ê¨Ài¹òO³F¶Î]@<1„EA #ìƒiRj«¸›¶*V4àÄz:|a©Q~¥³Z{_ÒÔm7dH¨ ¤m9Ĭe½h’©ëÑG€Æ½¦5É2q¼í) ÅÙ^S½\…Rì|ä‘j’ôI"ñQ™¦mÕñIÌ—ã)| àÙrf€¦n÷ãeƒ7g¡+•42 8Ûv˜7ÏîÚI £¨ß½‰Ò°)4Ò„¤o:ûÕWÃæÑwzU÷Úˌز ™#'l%À æ¬ Ÿ]†W¶»<”Åch å%ÝŽ;.ç e… Ö³z:eåÛ=sØC?ñ„úú«¯ö¸Ÿí'ž˜mP_áBi³îÝý¿Å“&ùb"ŒÀ ^ÎFÚQš#'¿ÀÁT R[b{·e½7Tò"&'Ä Ò}:w6MÛV!Í“,KXîYþJ+úÝ®]Ö ct¦—‡RÀÒLÏâYñÔ>&Qð­3ŠŽz&a¹ûù)ᆱæ¼þºuæŠT¸Ñ‰ŠB)Œö5*Rö;ë,Ó´­T¥JTrqé°¢A}’")ë/÷íÙS-Ÿ6-TÞ;i¬g½æÍCM×%V¸ÀýëÒ>²-Ç–ûïo?›ˆ‘€”÷=ýôÐ@ê<òeS”.Œ_ ° CP+ÚW/mŒš")«Ò©eNœh‡z-ZËÉ÷WGNaK€²Ë–Úë`´£¦ŠQ¾ ßO~(ùCó3A"P".²“@)Àx|pï½¥<ÉþÖþgœ‘}à!#iÓ.]T·~ÂÂì¨ fIDATGs±„-€,]Ô”H€ ïÞqG n™¸À^½qP¤ %x_¨\½ºU^ðÔðá£ZÅu‘œ2I`¢(;Ï¡ ­D?¸Gtî¹~xÚ-ì»ÿü§ZðÎ;»Ýsœl%0íé§Õ¬W^±nâpþù»¹ý ”X‘#)<àc—¦¯-M¸åµnÉÛè.ž“€‘¾¸°¢AˆÁ̸w/ˆ¤å€ .°–ÍÆ•+Õ[¨Žœl%°ëÛo @ƒ,Cã݃~þs[¬ãÅÒæzû· 33}ðªu1»ˆ -ûøã@‚À3fû€Û0Haî  /TA\f~üä“júsÏÙäÓÅ)` |¢û¡lð„jh‡éC.¹$HÖqc)Ž¿_|±5³D¤ÙdW —»È©“Àgo½¥Æÿýïù>ôÿWÕÔƒ ¹ XAJYoÊ”A[Ú¹c‡êF½3›#'²$€÷ùÑ—_^V¬ž1ð¶À¬^üC ØAÊ{üÅ/9[óùçjÜ 7¨];wúÉ« [@ÀÊç8ÇøÏ=XwÓrI9)¦ù€\[b iÜßþfÝÅËc |÷Ýwê1½Ö8È"nÏÑù‹\æìl’€,7ÔnN»ì²@©°bÐù—p‘)‡õÊ”-ëÖæmä5×è ÌÀ ä ¤¼7 A7ÒOžy&,y¸tR.§tWjí¢EsÁ„6ñJå¤`È¥—*¾¡¡ñ7ݤæé}e¶ÑÀ ÃÑNŘú—ª ÛïßåšFjéä½fM VN¼ýöH}ÍbÎEŽT4q¿Z¸0”w\ðÚkªZíÚ¡¤F"9·¤d‚ΆÿñóóŒ…ûô¥—§ãH˜î&@GÝsO¢JI$¤0Ò²o_5ìŠ+¸ DcõhÜÛÚ¢:Ê ÐòzT;¥ Ë‚ŽüÓŸ.b“F‰)‚a¯Ð–µ‰p™6檫ä¯;ç¡æ³zöZXåÛ=b'‘R„/]l¥¹o¼¡^ÐßbåŸÖ|ö™zåÊ+ChÏ“O4 .j 'b਴L¾ª¿QÍÑø Ô¼W/5B[ÕZMÊÅO€ØìüCmY»6nØ¥þèë¯%­¨I,HÉðKz²Ãç!xehÜ¡ƒöûß»}b¢Ò¢˜Òœ=öXho£?I§©·|-Í(J4HÉðszyP{˰Ԉ~ý^Gé’Í[ºxòäÐoÔ¾½:áÖ[UºuCK3ª„Òzˆýy Ô°–§±w `eSGÉ—@ØÍ[rܰMuœ^¾V«Q£ä @s˜x"E–§½øÛ߆bQI¯I§N¨Qn²Ã{“@ØÍ[¸¡ìÑ+¨p—JHE˜¯è óÆŽ•¿Î,@?@[Ô8¶ ÄhF¦{3ùÁC™âçÞæ$JÛÓ©)Ç3nTÂ"|Öֺ͚…•¤KÇRßlØ ¦hpN}üqË2GcÛ“£®»NUªZ5s „>IH‘ã‡?ع·<ø<ÓëÔSUo}YãêMÓ]û“ûƒb=׆4ÿÖûvvãþ‡?xo¥ê:• EÂ|Cå[j˜D°v<üð0“ui•!ü)ÎÙcÆ”ÊþQŸÓNSýò—ö $ fjAŠìVLŸ®žŒ`IQë4`uKÑjè´§ž2 kbBInÿêWª×)§”¼ºÿ©)Òfó×þïÿÔ’¿¡I)v;î8Ö½µŸGáI`ÖË/׬8 ‹‚ªÕªeš·¬ ÍJ=H¥&Ü|³¢f›(pÓÖ{¤ÖÛwß°“/¨ôæê~'~“—òIdùÞGogr¸ž]Ä¿sdÌY&œ7 %ÿl­þ¦þUÑ;ÃuÔ@í4|¸jÖ£G¯ÈÛ4çoÀ¹ôÃ#Íc×cŽQC÷»Hß‘‹Äó ¤MyžÓ}‘í[¶D&OšQ€•me–À‚wß5à\ôþû™…ô„ §»ŸpBH©%+™¼)âݹ}»±¨A·¸+¯¨X ÜQƒµ“¶°Ir·QßQ>§ŸÉV•,Œºh6|RC4@›tì˜MðT†ÉKJILöY5îÆåodçÚMš¨6ƒ+>˜ïׯ_dïIj–/7 œA7Eò“Ç|ø¼’M~ó¤`õüù¨+gÌÈFÃìݪ•k«{A ÌL„ |³~½ÂA¹XM| ÅEŒ¶¬½2 ×+súž¼©H÷½»ïV“x@þÆrnÔ®Ý÷€Õ¶i·n±¼3Ê—`1—L™b–Œ1¿6è^Ÿ6¼²/ “˜{](T0 ¥@™r6ñ®»Ôço¿{ùÒwâó³šè?¥åÁêyóÔÂ÷Þ3ƒr¹¢fº’c#j&ÉH¥pLœ¨ÞÖ ~×/[&·b?Ó´^ðVÎñäo¦è1Ø#3º6ô…T°|§xÎ9ªg̲•EA‚T„åwUy‡Ÿ3n^˜0QK×ÖÿÍY_×Ü{o?I•–]è¾Ñ{¤°OÊæÕ«‹Á(×è#Î~e© –¸‰Cºþ?ûY*¼'”`=Ô¿ R‘䔇Rï¼Sþ&ò\±råbÀVªRE™C[^ÎX`ï–cD¤œ·nܘȼ•dŠïÏýô–¸8q”Ï qÔö¯¿6N®&ݯsï(EŒÖöÑÛE¸… » ÇYÒÝå¡°68×fù”£x$8{Uߘ³‘°i)mÛ¼Ùx€ø@ï â( Ьíyâ‰j_íZÓQf 8f–yÂ` ûŸb]7é-Þ“}çnÇ«XØ uë`‰HlR‹/µòÁNª‚2Ôåˆ#T½qt•5RÅ{®™u µ(/fÎT,¿š7nœÚ¤÷VuTºc튦“>\“¶tes×4)•†þ¬ø˜ùâ‹jë¦Me„,œGmõbƒvC†¨v‡¦*VªT8(§¤! –ÉüL¡[¬'žGé} D–CIŠñEz~2¾¡Úèµ¶nw€PÄZœˆi±(½`•~—–ho3G7ñ¤Ö¨m[ÕBoüÌÒ¼ý d5J®Äî@“ä×.ZdÖZbaê¹ÃLžH1e±i×®ÆuLs=É}¯† ÓÄ~ªyu ÍQñ±ìk¥€bjÕìÙjíâÅj[ú´L)l ×IJ©Kí•eåMZG¹‘€inä^ê[™í´qåJµiÕ*3žIð¸,Å/-óoWÍ™Sj>> |\.\.\. |\$ " copybutton_prompt_is_regexp = True # Disable autodoc's built-in type hints, and use sphinx_autodoc_typehints extension instead autodoc_typehints = "none" # Auto-generage module docs with sphinx-apidoc apidoc_module_dir = PACKAGE_DIR apidoc_output_dir = MODULE_DOCS_DIR apidoc_module_first = True apidoc_separate_modules = True apidoc_toc_file = "index" # HTML general settings html_show_sphinx = False pygments_style = "friendly" pygments_dark_style = "material" # HTML theme settings html_logo = "_static/logo.png" html_static_path = ["_static"] html_theme = "furo" html_theme_options = { "sidebar_hide_name": True, } vutran1710-PyrateLimiter-634d166/docs/contributing.md000066400000000000000000000001101513463764300223760ustar00rootroot00000000000000# Contributing Guide ```{include} ../CONTRIBUTING.md :start-line: 1 ``` vutran1710-PyrateLimiter-634d166/docs/index.md000066400000000000000000000006551513463764300210140ustar00rootroot00000000000000# PyrateLimiter ```{include} ../README.md :start-line: 3 :end-before: '> **Upgrading' ``` > **Upgrading from v3.x?** See the [Migration Guide](migrating.md) for breaking changes. ## Features ```{include} ../README.md :start-after: '## Features' ``` # Reference Documentation ```{toctree} :maxdepth: 2 reference migrating changelog contributing modules/index ``` vutran1710-PyrateLimiter-634d166/docs/migrating.md000066400000000000000000000132511513463764300216620ustar00rootroot00000000000000# Migrating to PyrateLimiter 4.0 This guide covers the breaking changes when upgrading from PyrateLimiter 3.x to 4.0. ## Quick Summary Version 4.0 simplifies the API by: - Removing exception-based flow control in favor of blocking behavior - Simplifying the decorator API - Adding proper async support with `try_acquire_async` - Moving clock responsibility from Limiter to Bucket - Adding context manager support ## Breaking Changes ### 1. try_acquire is Now Blocking by Default This is the most significant change. Previously, `try_acquire` would raise `BucketFullException` when the rate limit was exceeded. Now it blocks until a permit is available. **v3.x:** ```python from pyrate_limiter import BucketFullException try: limiter.try_acquire("item") except BucketFullException as e: print(f"Rate limited: {e.meta_info}") ``` **v4.0:** ```python # Blocking (default) - waits until permit is available limiter.try_acquire("item") # blocks until success when called without a timeout # Non-blocking - returns immediately with False if bucket is full success = limiter.try_acquire("item", blocking=False) if not success: print("Rate limited") ``` Base acquire signature (used by both sync `try_acquire` and async `try_acquire_async`): ```python def try_acquire( name: str = "pyrate", weight: int = 1, blocking: bool = True, # NEW: wait for permit timeout: int = -1 # NEW: max wait time (primarily used by try_acquire_async) ) -> bool ``` ### 2. Use try_acquire_async for Async Code For async code, use the new `try_acquire_async` method which uses `asyncio.Lock` and `asyncio.sleep`: **v3.x:** ```python # v3.x used try_acquire for both sync and async result = await limiter.try_acquire("item") ``` **v4.0:** ```python # Use try_acquire_async for proper async behavior success = await limiter.try_acquire_async("item") # With timeout (in seconds) success = await limiter.try_acquire_async("item", timeout=5) if not success: print("Timed out waiting for permit") # Non-blocking async success = await limiter.try_acquire_async("item", blocking=False) ``` ### 3. Decorator API Simplified The decorator no longer requires a mapping function. Pass `name` and `weight` directly. **v3.x:** ```python decorator = limiter.as_decorator() def mapping(*args, **kwargs): return ("item_name", 1) # (name, weight) tuple @decorator(mapping) def my_function(): pass @decorator(mapping) async def my_async_function(): pass ``` **v4.0:** ```python @limiter.as_decorator(name="item_name", weight=1) def my_function(): pass @limiter.as_decorator(name="item_name", weight=1) async def my_async_function(): pass ``` ### 4. Exception Classes Removed `BucketFullException` and `LimiterDelayException` have been removed entirely. Use `blocking=False` to get non-blocking behavior. **v3.x:** ```python from pyrate_limiter import BucketFullException, LimiterDelayException try: limiter.try_acquire("item") except BucketFullException as e: handle_rate_limit(e.meta_info) except LimiterDelayException as e: handle_delay_exceeded(e.meta_info) ``` **v4.0:** ```python success = limiter.try_acquire("item", blocking=False) if not success: handle_rate_limit() ``` ### 5. Limiter Constructor Simplified **v3.x:** ```python limiter = Limiter( bucket, clock=TimeClock(), raise_when_fail=True, max_delay=5000, retry_until_max_delay=True, ) ``` **v4.0:** ```python limiter = Limiter( bucket, buffer_ms=50, # optional, default 50ms ) ``` Removed parameters: - `clock` - each bucket now manages its own clock via `bucket.now()` - `raise_when_fail` - no exceptions are raised; use `blocking=False` - `max_delay` - blocking is controlled per-call via `blocking` parameter - `retry_until_max_delay` - blocking mode retries automatically ### 6. BucketFactory Changes If you implement a custom `BucketFactory`, remove the clock parameter from `schedule_leak` and `create` calls. **v3.x:** ```python class MyFactory(BucketFactory): def __init__(self, clock): self.clock = clock def wrap_item(self, name, weight=1): return RateItem(name, self.clock.now(), weight=weight) bucket = factory.create(clock, InMemoryBucket, rates) factory.schedule_leak(bucket, clock) ``` **v4.0:** ```python class MyFactory(BucketFactory): def wrap_item(self, name, weight=1): return RateItem(name, self.bucket.now(), weight=weight) bucket = factory.create(InMemoryBucket, rates) factory.schedule_leak(bucket) ``` ### 7. Clock Changes *Most users won't need to change anything here - clocks are now managed internally by buckets.* If you explicitly used clock classes: - `TimeClock` removed - buckets use `MonotonicClock` by default - `SQLiteClock` removed - buckets manage their own time - `TimeAsyncClock` renamed to `MonotonicAsyncClock` ## New Features ### Context Manager Support ```python with Limiter(bucket) as limiter: limiter.try_acquire("item") # Resources automatically cleaned up ``` ### limiter_factory Module Convenience functions for common patterns: ```python from pyrate_limiter import limiter_factory, Duration limiter = limiter_factory.create_inmemory_limiter( rate_per_duration=5, duration=Duration.SECOND, ) limiter = limiter_factory.create_sqlite_limiter( rate_per_duration=100, duration=Duration.MINUTE, db_path="/path/to/db.sqlite", ) ``` ### Web Request Helpers ```python from pyrate_limiter.extras.aiohttp_limiter import RateLimitedSession from pyrate_limiter.extras.httpx_limiter import RateLimiterTransport from pyrate_limiter.extras.requests_limiter import RateLimitedRequestsSession ``` ### MultiprocessBucket ```python from pyrate_limiter import MultiprocessBucket bucket = MultiprocessBucket(rates, manager) ``` vutran1710-PyrateLimiter-634d166/docs/reference.md000066400000000000000000000003321513463764300216330ustar00rootroot00000000000000# API Reference This section documents the public interfaces of pyrate-limiter. ```{toctree} :glob: true :maxdepth: 2 modules/pyrate_limiter.* ``` vutran1710-PyrateLimiter-634d166/examples/000077500000000000000000000000001513463764300202435ustar00rootroot00000000000000vutran1710-PyrateLimiter-634d166/examples/aiohttp_ratelimiter.py000066400000000000000000000020451513463764300246670ustar00rootroot00000000000000# ruff: noqa: T201, G004 """ Example of using pyrate_limiter with aiohttp. """ import asyncio import logging import time from pyrate_limiter import Duration, limiter_factory from pyrate_limiter.extras.aiohttp_limiter import RateLimitedSession logger = logging.getLogger(__name__) logging.basicConfig(level=logging.DEBUG, format="%(asctime)s.%(msecs)03d [%(levelname)s] %(message)s", datefmt="%Y-%m-%d %H:%M:%S") logger.setLevel(logging.DEBUG) async def test_aiohttp(): url = "https://httpbin.org/get" limiter = limiter_factory.create_inmemory_limiter( rate_per_duration=3, duration=Duration.SECOND, ) async with RateLimitedSession(limiter) as session: async def wrapped(i): logger.info(f"Request {i} at {round(time.time(), 2)}") resp = await session.get(url) logger.info(f"Response {i} at {round(time.time(), 2)}: {resp.status}") return resp await asyncio.gather(*(wrapped(i) for i in range(10))) if __name__ == "__main__": asyncio.run(test_aiohttp()) vutran1710-PyrateLimiter-634d166/examples/asyncio_decorator.py000066400000000000000000000020431513463764300243230ustar00rootroot00000000000000# ruff: noqa: T201 import asyncio import logging import time from datetime import datetime import pytest from pyrate_limiter.limiter_factory import create_inmemory_limiter logging.basicConfig(level=logging.DEBUG) async def ticker(): for _ in range(10): print(f"[TICK] {datetime.now()}") await asyncio.sleep(0.5) def mapping(name, weight, i): return "mytask", 1 @pytest.mark.asyncio async def test_asyncio_decorator(): print("Running task_async using try_acquire_async and AsyncBucketWrapper") print("Note that the TICKs continue while the tasks are waiting") start = time.time() limiter = create_inmemory_limiter() @limiter.as_decorator(name="asyncio_test", weight=1) async def task_async(name: str, weight: int): print(f"try_acquire_async: {datetime.now()} {name}: {weight}") await asyncio.gather(ticker(), *[task_async("mytask", 1) for i in range(10)]) print(f"Run 10 calls in {time.time() - start:,.2f} sec") if __name__ == "__main__": asyncio.run(test_asyncio_decorator()) vutran1710-PyrateLimiter-634d166/examples/asyncio_ratelimit.py000066400000000000000000000020651513463764300243370ustar00rootroot00000000000000# ruff: noqa: T201 import asyncio import logging import time from datetime import datetime from pyrate_limiter import Limiter from pyrate_limiter.limiter_factory import create_inmemory_limiter logging.basicConfig(level=logging.DEBUG) async def ticker(): for _ in range(10): print(f"[TICK] {datetime.now()}") await asyncio.sleep(0.5) def mapping(name, weight, i): return "mytask", 1 async def test_asyncio_ratelimit(): print("Running task_async using try_acquire_async and BucketAsyncWrapper") print("Note that the TICKs continue while the tasks are waiting") start = time.time() limiter = create_inmemory_limiter() async def task_async(name, weight, i, limiter: Limiter): await limiter.try_acquire_async(name, weight) print(f"try_acquire_async: {datetime.now()} {name}: {weight}") await asyncio.gather(ticker(), *[task_async(str(i), 1, i, limiter) for i in range(10)]) print(f"Run 10 calls in {time.time() - start:,.2f} sec") if __name__ == "__main__": asyncio.run(test_asyncio_ratelimit()) vutran1710-PyrateLimiter-634d166/examples/httpx_ratelimiter.py000066400000000000000000000060201513463764300243630ustar00rootroot00000000000000# ruff: noqa: T201 """ Example of using pyrate_limiter with httpx. """ import logging from pyrate_limiter import limiter_factory from pyrate_limiter.extras.httpx_limiter import AsyncRateLimiterTransport, RateLimiterTransport logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO, format="%(asctime)s.%(msecs)03d [%(levelname)s] %(message)s", datefmt="%Y-%m-%d %H:%M:%S") logger.setLevel(logging.DEBUG) # Example below def fetch(start_time: int): import httpx url = "https://httpbin.org/get" assert limiter_factory.LIMITER is not None with httpx.Client(transport=RateLimiterTransport(limiter=limiter_factory.LIMITER)) as client: client.get(url) def singleprocess_example(): import os import time import httpx from pyrate_limiter import Duration, limiter_factory start_time = time.time() url = "https://httpbin.org/get" limiter = limiter_factory.create_inmemory_limiter(rate_per_duration=1, duration=Duration.SECOND) transport = RateLimiterTransport(limiter=limiter) with httpx.Client(transport=transport) as client: for _ in range(10): response = client.get(url) print(f"{round(time.time() - start_time, 2)}s-{os.getpid()}: {response.json()}") def asyncio_example(): import asyncio import time import httpx from pyrate_limiter import Duration, limiter_factory url = "https://httpbin.org/get" async def ticker(): """loops and prints time, showing the eventloop isn't blocked""" while True: print(f"[TICK] {time.time()}") await asyncio.sleep(1) async def afetch(client: httpx.AsyncClient, start_time: int): await client.get(url) async def example(): limiter = limiter_factory.create_inmemory_limiter(rate_per_duration=1, duration=Duration.SECOND) transport = AsyncRateLimiterTransport(limiter=limiter) client = httpx.AsyncClient(transport=transport) tasks = [afetch(client, url) for _ in range(10)] asyncio.create_task(ticker()) results = await asyncio.gather(*tasks) await client.aclose() return results asyncio.run(example()) def multiprocess_example(): import time from concurrent.futures import ProcessPoolExecutor, wait from pyrate_limiter import Duration, MultiprocessBucket, Rate rate = Rate(1, Duration.SECOND) bucket = MultiprocessBucket.init([rate]) start_time = time.time() with ProcessPoolExecutor(initializer=limiter_factory.init_global_limiter, initargs=(bucket,)) as executor: futures = [executor.submit(fetch, start_time) for _ in range(10)] wait(futures) for f in futures: try: f.result() except Exception: logger.exception("Task raised") if __name__ == "__main__": print("Single Process example: 10 requests") singleprocess_example() print("Multiprocessing example: 10 requests") multiprocess_example() print("Asyncio example: 10 requests") asyncio_example() vutran1710-PyrateLimiter-634d166/examples/in_memory_multiprocess.py000066400000000000000000000040631513463764300254270ustar00rootroot00000000000000# ruff: noqa: T201 """ Demonstrates using a MultiprocessBucket using a ProcessPoolExecutor, running a simple task. A MultiprocessBucket is useful when the rate is to be shared among a multiprocessing pool or ProcessPoolExecutor. The mp_bucket stores its items in a multiprocessing ListProxy, and a multiprocessing lock is shared across Limiter instances. """ import logging import os import time from concurrent.futures import ProcessPoolExecutor, wait from typing import Optional from pyrate_limiter import Duration, Limiter, MultiprocessBucket, Rate LIMITER: Optional[Limiter] = None REQUESTS_PER_SECOND = 100 NUM_REQUESTS = REQUESTS_PER_SECOND * 5 # Run for ~5 seconds logger = logging.getLogger(__name__) def init_process(bucket: MultiprocessBucket): global LIMITER LIMITER = Limiter(bucket) def my_task(): assert LIMITER is not None LIMITER.try_acquire("my_task") result = {"time": time.monotonic(), "pid": os.getpid()} return result def test_in_memory_multiprocess(): rate = Rate(REQUESTS_PER_SECOND, Duration.SECOND) bucket = MultiprocessBucket.init([rate]) # create a limiter and feed it 100 requests to prime it # Otherwise, the test appears to run too fast init_process(bucket) assert LIMITER is not None [LIMITER.try_acquire("test") for _ in range(REQUESTS_PER_SECOND)] start = time.monotonic() with ProcessPoolExecutor(initializer=init_process, initargs=(bucket,)) as executor: futures = [executor.submit(my_task) for _ in range(NUM_REQUESTS)] wait(futures) times = [] for f in futures: try: t = f.result() times.append(t) except Exception as e: print(f"Task raised: {e}") end = time.monotonic() print(f"Completed {NUM_REQUESTS=} in {end - start} seconds, at a rate of {REQUESTS_PER_SECOND=}") if __name__ == "__main__": logging.basicConfig( format="%(asctime)s %(name)s %(levelname)-8s %(message)s", level=logging.INFO, datefmt="%Y-%m-%d %H:%M:%S", ) test_in_memory_multiprocess() vutran1710-PyrateLimiter-634d166/examples/postgres_example.py000066400000000000000000000021371513463764300242010ustar00rootroot00000000000000# ruff: noqa: T201 """ May need to install the psycopg binaries: # uv pip install psycopg[binary] """ import time from datetime import datetime from typing import List from psycopg_pool import ConnectionPool as PgConnectionPool from pyrate_limiter import Duration, Limiter, PostgresBucket, Rate def create_postgres_bucket(rates: List[Rate]): pool = PgConnectionPool("postgresql://postgres:postgres@localhost:5432", open=True) table = f"test_bucket_{int(time.time())}" bucket = PostgresBucket(pool, table, rates) assert bucket.count() == 0 return bucket def test_postgres(): rates = [Rate(3, Duration.SECOND * 3)] def task(name, weight): acquired = limiter.try_acquire(name, weight) print(f"{datetime.now()} {name}: {weight}, {acquired=}") redis_bucket = create_postgres_bucket(rates) limiter = Limiter(redis_bucket) for i in range(10): task(str(i), 1) if __name__ == "__main__": print("To start a postgres container: ") print("# docker run --name postgres -e POSTGRES_PASSWORD=postgres -p 5432:5432 -d postgres") test_postgres() vutran1710-PyrateLimiter-634d166/examples/redis_example.py000066400000000000000000000035421513463764300234420ustar00rootroot00000000000000# ruff: noqa: T201 import asyncio import time from datetime import datetime from typing import List import pytest import redis from pyrate_limiter import Duration, Limiter, Rate, RedisBucket async def ticker(): for _ in range(8): print(f"[TICK] {datetime.now()}") await asyncio.sleep(0.5) def create_redis_bucket(rates: List[Rate]): redis_db = redis.Redis(host="localhost") bucket = RedisBucket.init(rates, redis_db, "test") bucket.flush() assert bucket.count() == 0 return bucket async def create_async_redis_bucket(rates: List[Rate]): redis_db = redis.asyncio.Redis(host="localhost") bucket = await RedisBucket.init(rates, redis_db, "test3") await bucket.flush() assert await bucket.count() == 0 return bucket @pytest.mark.asyncio async def test_redis_async(): rates = [Rate(3, Duration.SECOND)] redis_bucket = await create_async_redis_bucket(rates) limiter = Limiter(redis_bucket) async def task(name, weight): acquired = await limiter.try_acquire_async(name, weight) print(f"{datetime.now()} {name}: {weight}, {acquired=}") start = time.time() await asyncio.gather(ticker(), *[task(str(i), 1) for i in range(10)]) print(f"Run 10 calls in {time.time() - start:,.2f} sec") def test_redis_sync(): rates = [Rate(3, Duration.SECOND)] def task(name, weight): acquired = limiter.try_acquire(name, weight) print(f"{datetime.now()} {name}: {weight}, {acquired=}") redis_bucket = create_redis_bucket(rates) limiter = Limiter(redis_bucket) for i in range(10): task(str(i), 1) if __name__ == "__main__": print("To start a redis container: \n# docker run -d --name redis-test -p 6379:6379 redis:7") print("Redis (non-Async) bucket") test_redis_sync() print("AsyncRedis bucket") asyncio.run(test_redis_async()) vutran1710-PyrateLimiter-634d166/examples/requests_ratelimiter.py000066400000000000000000000022231513463764300250700ustar00rootroot00000000000000# ruff: noqa: T201, G004 """ Example of using pyrate_limiter with requests. """ import logging import time from pyrate_limiter import Duration, limiter_factory from pyrate_limiter.extras.requests_limiter import RateLimitedRequestsSession logger = logging.getLogger(__name__) logging.basicConfig(level=logging.DEBUG, format="%(asctime)s.%(msecs)03d [%(levelname)s] %(message)s", datefmt="%Y-%m-%d %H:%M:%S") logger.setLevel(logging.DEBUG) def test_requests(): """Demonstrates a rate limited sequence of http get requests using the requests library. Rate is limited to 2 requests per second. Some drift occurs because these are synchronous requests and get requests have duration. """ url = "https://httpbin.org/get" limiter = limiter_factory.create_inmemory_limiter(rate_per_duration=2, duration=Duration.SECOND) session = RateLimitedRequestsSession(limiter) start = time.time() for i in range(10): logger.info(f"Request {i} at {round(time.time() - start, 2)}s") resp = session.get(url) logger.info(f"Response {i}: {resp.status_code}") session.close() if __name__ == "__main__": test_requests() vutran1710-PyrateLimiter-634d166/examples/sqlite_filelock_multiprocess.py000066400000000000000000000037501513463764300266040ustar00rootroot00000000000000# ruff: noqa: T201 """ Demonstrates using a SQLite Bucket across multiple processes, using a filelock to enforce synchronization. This is useful in cases where multiple processes are created, possibly at different times or from different applications. The SQLite Bucket uses a .lock file to ensure that only one process is active at a time. """ import logging import os import time from concurrent.futures import ProcessPoolExecutor, wait from typing import Optional from pyrate_limiter import Duration, Limiter, limiter_factory LIMITER: Optional[Limiter] = None REQUESTS_PER_SECOND = 10 NUM_REQUESTS = REQUESTS_PER_SECOND * 5 # Run for ~5 seconds logger = logging.getLogger(__name__) def init_process(): global LIMITER LIMITER = limiter_factory.create_sqlite_limiter( rate_per_duration=REQUESTS_PER_SECOND, duration=Duration.SECOND, db_path="pyrate_limiter.sqlite", use_file_lock=True ) def my_task(): assert LIMITER is not None LIMITER.try_acquire("my_task") result = {"time": time.monotonic(), "pid": os.getpid()} return result def test_sqlite_filelock_multiprocess(): # prime the rates, to show realistic rates init_process() assert LIMITER is not None [LIMITER.try_acquire("test") for _ in range(REQUESTS_PER_SECOND)] start = time.monotonic() with ProcessPoolExecutor(initializer=init_process) as executor: futures = [executor.submit(my_task) for _ in range(NUM_REQUESTS)] wait(futures) times = [] for f in futures: try: t = f.result() times.append(t) except Exception as e: print(f"Task raised: {e}") end = time.monotonic() print(f"Completed {NUM_REQUESTS=} in {end - start} seconds, at a rate of {REQUESTS_PER_SECOND=}") if __name__ == "__main__": logging.basicConfig( format="%(asctime)s %(name)s %(levelname)-8s %(message)s", level=logging.INFO, datefmt="%Y-%m-%d %H:%M:%S", ) test_sqlite_filelock_multiprocess() vutran1710-PyrateLimiter-634d166/noxfile.py000066400000000000000000000052701513463764300204470ustar00rootroot00000000000000import multiprocessing from glob import glob import nox from nox_poetry import session half_cores = max(1, multiprocessing.cpu_count() // 2) eighth_cores = max(1, multiprocessing.cpu_count() // 8) # Reuse virtualenv created by poetry instead of creating new ones nox.options.reuse_existing_virtualenvs = True # Manually select serial tests. TODO: Add a "serial" marker PYTEST_MP_ARGS = [f"-n={eighth_cores}", "--verbose", "--maxfail=1", "tests/test_multiprocessing.py"] COVERAGE_APPEND_ARGS = ["--cov=pyrate_limiter", "--cov-report="] PYTEST_MP2_ARGS = [f"-n={eighth_cores}", "--verbose", "--maxfail=1", "-m", "mpbucket", "--ignore=tests/test_multiprocessing.py"] COVERAGE_APPEND2_ARGS = ["--cov=pyrate_limiter", "--cov-append", "--cov-report="] PYTEST_ARGS = ["--verbose", "--maxfail=1", "-m", "not mpbucket", f"--numprocesses={half_cores}", "--ignore=tests/test_multiprocessing.py"] COVERAGE_REPORT_ARGS = ["--cov=pyrate_limiter", "--cov-append", "--cov-report=term-missing", "--cov-report=xml", "--cov-report=html"] PYTESTSMOKE_ARGS = ["--verbose", "--maxfail=1", "-m", "inmemory", "--numprocesses=auto", "--ignore=tests/test_multiprocessing.py"] PYTEST_NOTLINUX_ARGS = [ "--verbose", "--maxfail=1", "-m", "not postgres and not redis and not asyncredis", "--numprocesses=auto", "--ignore=tests/test_multiprocessing.py", ] def get_examples(): return [f for f in glob("examples/*.py")] @session(python=False) def lint(session) -> None: session.run("pre-commit", "run", "--all-files") @session(python=False) def cover(session) -> None: """Run tests and generate coverage reports in both terminal output and XML (for Codecov)""" # Serial Files session.run("pytest", *PYTEST_MP_ARGS, *COVERAGE_APPEND_ARGS) # Serial Markers session.run("pytest", *PYTEST_MP2_ARGS, *COVERAGE_APPEND2_ARGS) # Everything else - concurrent session.run("pytest", *PYTEST_ARGS, *COVERAGE_REPORT_ARGS, "tests", *get_examples()) @session(python=False) def smoke(session) -> None: """Tests excluding postgres, redis, and asyncredis backends for non-Linux platforms""" session.run("pytest", *PYTESTSMOKE_ARGS, "tests") @session(python=False) def notlinux(session) -> None: """Tests excluding postgres, redis, and asyncredis backends for non-Linux platforms""" session.run("pytest", *PYTEST_NOTLINUX_ARGS, "tests") @session(python=False) def test(session) -> None: session.run("pytest", *PYTEST_MP_ARGS) session.run("pytest", *PYTEST_MP2_ARGS) session.run("pytest", *PYTEST_ARGS, "tests", *get_examples()) @session(python=False) def docs(session): """Build Sphinx documentation""" session.run("sphinx-build", "docs", "docs/_build/html", "-j", "auto") vutran1710-PyrateLimiter-634d166/pyproject.toml000066400000000000000000000071131513463764300213430ustar00rootroot00000000000000[project] name = "pyrate-limiter" dynamic = ["version"] description = "Python Rate-Limiter using Leaky-Bucket Algorithm" authors = [{ name = "vutr", email = "me@vutr.io" }] requires-python = ">=3.10" readme = "README.md" license = "MIT" keywords = [ "rate", "rate-limiter", "rate_limiter", "ratelimiter", "leaky-bucket", "ratelimit", "ratelimiting", "httpx", "aiohttp", "limiter", "rate", "requests", "throttle" ] classifiers = [ "Development Status :: 5 - Production/Stable", "Operating System :: OS Independent", "Topic :: Software Development :: Documentation", "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed", "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", ] [project.urls] Homepage = "https://github.com/vutran1710/PyrateLimiter" Repository = "https://github.com/vutran1710/PyrateLimiter" Documentation = "https://pyrate-limiter.readthedocs.io" [dependency-groups] all = [ "filelock>=3.0", "redis>=6.2.0", "psycopg[pool]>=3.2.9", ] docs = [ "furo", "myst-parser", "sphinx", "sphinx-autodoc-typehints", "sphinx-copybutton", "sphinxcontrib-apidoc", ] dev = [ "coverage>=7.10.1", "flake8_polyfill>=1.0.2,<2", "nox~=2025.5", "nox-poetry>=1.0", "pre-commit-uv", "psycopg[pool]>=3.2.9", "pytest>=8.4.1", "pytest-asyncio>=1.1.0", "pytest-cov>=6.2.1", "pytest-xdist>=3.8.0", "schedule>=1.1.0,<2", "pytest-retry>=1.7.0", "pytest-randomly>=3.16.0", "httpx", "aiohttp", "requests", "psycopg[binary]>=3.2.9; sys_platform == 'win32'" ] [tool.black] line-length = 120 [tool.coverage.run] branch = true source = ['pyrate_limiter'] [tool.coverage.report] exclude_lines = [ "except ImportError:", # Used for missing optional dependencies ] [tool.coverage.xml] output = 'test-reports/coverage.xml' [tool.ipdb] context = 7 [build-system] requires = ["hatchling", "uv-dynamic-versioning"] build-backend = "hatchling.build" [tool.hatch.version] source = "uv-dynamic-versioning" [tool.hatch.build.targets.sdist] include = [ "pyrate_limiter", "docs", "tests", "examples", "benchmarks", "README.md", "CHANGELOG.md", "CONTRIBUTING.md", "LICENSE", "pyproject.toml", "setup.cfg", "noxfile.py", ] [tool.hatch.build.targets.wheel] include = ["pyrate_limiter"] [tool.hatch.build.targets.wheel.sources] "./pyrate_limiter" = "pyrate_limiter" [tool.pytest.ini_options] asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function" retries = 2 retry_delay = 1 cumulative_timing = false retry_outcome = "rerun" markers = [ "inmemory: tests using InMemoryBucket", "redis: tests using RedisBucket", "asyncredis: tests using AsyncRedisBucket", "sqlite: tests using SQLiteBucket", "filelocksqlite: tests using SQLite + file lock", "postgres: tests using PostgresBucket", "mpbucket: tests using MultiprocessBucket", "monotonic: tests using MonotonicClock", "timeclock: tests using TimeClock", "asyncclock: tests using TimeAsyncClock", ] [tool.ruff] line-length = 150 exclude = [ ".git", "__pycache__", "build", "dist", "docs/source/conf.py", "tests", ] extend-include = ["*.ipynb"] [tool.ruff.lint] select = ["F", "E", "W", "S", "B", "G", "N", "I001", "T", "PD", "C90"] ignore = [ "E501", "C901", "S101" ] [tool.ruff.lint.per-file-ignores] "__init__.py" = ["F401"] vutran1710-PyrateLimiter-634d166/pyrate_limiter/000077500000000000000000000000001513463764300214565ustar00rootroot00000000000000vutran1710-PyrateLimiter-634d166/pyrate_limiter/__init__.py000066400000000000000000000003431513463764300235670ustar00rootroot00000000000000# flake8: noqa from ._version import __version__ from .abstracts import * from .buckets import * from .clocks import AbstractClock, MonotonicAsyncClock, MonotonicClock, PostgresClock from .limiter import * from .utils import * vutran1710-PyrateLimiter-634d166/pyrate_limiter/_version.py000066400000000000000000000002601513463764300236520ustar00rootroot00000000000000import importlib.metadata try: __version__ = importlib.metadata.version(__package__ or __name__) except importlib.metadata.PackageNotFoundError: __version__ = "0.0.0" vutran1710-PyrateLimiter-634d166/pyrate_limiter/abstracts/000077500000000000000000000000001513463764300234445ustar00rootroot00000000000000vutran1710-PyrateLimiter-634d166/pyrate_limiter/abstracts/__init__.py000066400000000000000000000002061513463764300255530ustar00rootroot00000000000000from .bucket import AbstractBucket, BucketFactory from .rate import Duration, Rate, RateItem from .wrappers import BucketAsyncWrapper vutran1710-PyrateLimiter-634d166/pyrate_limiter/abstracts/bucket.py000066400000000000000000000250141513463764300252750ustar00rootroot00000000000000"""Implement this class to create a workable bucket for Limiter to use """ import asyncio import logging from abc import ABC, abstractmethod from collections import defaultdict from inspect import isawaitable, iscoroutine from threading import Event, Thread from typing import Any, Awaitable, Dict, List, Optional, Type, Union from ..clocks import AbstractClock, MonotonicClock from .rate import Rate, RateItem logger = logging.getLogger("pyrate_limiter") class AbstractBucket(ABC): """Base bucket interface Assumption: len(rates) always > 0 TODO: allow empty rates """ rates: List[Rate] failing_rate: Optional[Rate] = None _clock: AbstractClock = MonotonicClock() def __init__(self): self._clock: AbstractClock = MonotonicClock() def now(self): return self._clock.now() @abstractmethod def put(self, item: RateItem) -> Union[bool, Awaitable[bool]]: """Put an item (typically the current time) in the bucket return true if successful, otherwise false """ @abstractmethod def leak( self, current_timestamp: Optional[int] = None, ) -> Union[int, Awaitable[int]]: """leaking bucket - removing items that are outdated""" @abstractmethod def flush(self) -> Union[None, Awaitable[None]]: """Flush the whole bucket - Must remove `failing-rate` after flushing """ @abstractmethod def count(self) -> Union[int, Awaitable[int]]: """Count number of items in the bucket""" @abstractmethod def peek(self, index: int) -> Union[Optional[RateItem], Awaitable[Optional[RateItem]]]: """Peek at the rate-item at a specific index in latest-to-earliest order NOTE: The reason we cannot peek from the start of the queue(earliest-to-latest) is we can't really tell how many outdated items are still in the queue """ def waiting(self, item: RateItem) -> Union[int, Awaitable[int]]: """Calculate time until bucket become availabe to consume an item again""" if self.failing_rate is None: return 0 assert item.weight > 0, "Item's weight must > 0" if item.weight > self.failing_rate.limit: return -1 bound_item = self.peek(self.failing_rate.limit - item.weight) if bound_item is None: # NOTE: No waiting, bucket is immediately ready return 0 def _calc_waiting(inner_bound_item: RateItem) -> int: assert self.failing_rate is not None # NOTE: silence mypy lower_time_bound = item.timestamp - self.failing_rate.interval upper_time_bound = inner_bound_item.timestamp return upper_time_bound - lower_time_bound async def _calc_waiting_async() -> int: nonlocal bound_item while isawaitable(bound_item): bound_item = await bound_item if bound_item is None: # NOTE: No waiting, bucket is immediately ready return 0 assert isinstance(bound_item, RateItem) return _calc_waiting(bound_item) if isawaitable(bound_item): return _calc_waiting_async() assert isinstance(bound_item, RateItem) return _calc_waiting(bound_item) def limiter_lock(self) -> Optional[object]: # type: ignore """An additional lock to be used by Limiter in-front of the thread lock. Intended for multiprocessing environments where a thread lock is insufficient. """ return None def close(self) -> None: # noqa: B027 """Release any resources held by the bucket. Subclasses may override this method to perform any necessary cleanup (e.g., closing files, network connections, or releasing locks) when the bucket is no longer needed. """ pass def __enter__(self): return self def __exit__(self, exc_type, exc, tb) -> None: self.close() class Leaker(Thread): """Responsible for scheduling buckets' leaking at the background either through a daemon task(for sync buckets) or a task using asyncio.Task """ daemon = True name = "PyrateLimiter's Leaker" sync_buckets: Dict[int, AbstractBucket] async_buckets: Dict[int, AbstractBucket] leak_interval: int = 10_000 aio_leak_task: Optional[asyncio.Task] = None _stop_event: Any def __init__(self, leak_interval: int): self.sync_buckets = defaultdict() self.async_buckets = defaultdict() self.leak_interval = leak_interval self._stop_event = Event() # <--- add here super().__init__() def register(self, bucket: AbstractBucket): """Register a new bucket with its associated clock""" assert self.sync_buckets is not None assert self.async_buckets is not None try_leak = bucket.leak(0) bucket_id = id(bucket) if iscoroutine(try_leak): try_leak.close() self.async_buckets[bucket_id] = bucket else: self.sync_buckets[bucket_id] = bucket def deregister(self, bucket_id: int) -> bool: """Deregister a bucket""" if self.sync_buckets and bucket_id in self.sync_buckets: del self.sync_buckets[bucket_id] return True if self.async_buckets and bucket_id in self.async_buckets: del self.async_buckets[bucket_id] if not self.async_buckets and self.aio_leak_task: self.aio_leak_task.cancel() self.aio_leak_task = None return True return False async def _leak(self, buckets: Dict[int, AbstractBucket]) -> None: while not self._stop_event.is_set() and buckets: try: for _, bucket in tuple(buckets.items()): now = bucket.now() while isawaitable(now): now = await now assert isinstance(now, int) leak = bucket.leak(now) while isawaitable(leak): leak = await leak assert isinstance(leak, int) await asyncio.sleep(self.leak_interval / 1000) except RuntimeError as e: logger.debug("Leak task stopped due to event loop shutdown. %s", e) return def leak_async(self): if self.async_buckets and not self.aio_leak_task: self.aio_leak_task = asyncio.create_task(self._leak(self.async_buckets)) def run(self) -> None: """Override the original method of Thread Not meant to be called directly """ assert self.sync_buckets asyncio.run(self._leak(self.sync_buckets)) def start(self) -> None: """Override the original method of Thread Call to run leaking sync buckets """ if self.sync_buckets and not self.is_alive(): super().start() def close(self): self._stop_event.set() self.sync_buckets.clear() self.async_buckets.clear() class BucketFactory(ABC): """Asbtract BucketFactory class. It is reserved for user to implement/override this class with his own bucket-routing/creating logic """ _leaker: Optional[Leaker] = None _leak_interval: int = 10_000 @property def leak_interval(self) -> int: """Retrieve leak-interval from inner Leaker task""" if not self._leaker: return self._leak_interval return self._leaker.leak_interval @leak_interval.setter def leak_interval(self, value: int): """Set leak-interval for inner Leaker task""" if self._leaker: self._leaker.leak_interval = value self._leak_interval = value @abstractmethod def wrap_item( self, name: str, weight: int = 1, ) -> Union[RateItem, Awaitable[RateItem]]: """Add the current timestamp to the receiving item using any clock backend - Turn it into a RateItem - Can return either a coroutine or a RateItem instance """ @abstractmethod def get(self, item: RateItem) -> Union[AbstractBucket, Awaitable[AbstractBucket]]: """Get the corresponding bucket to this item""" def create( self, bucket_class: Type[AbstractBucket], *args, **kwargs, ) -> AbstractBucket: """Creating a bucket dynamically""" bucket = bucket_class(*args, **kwargs) self.schedule_leak(bucket) return bucket def schedule_leak(self, new_bucket: AbstractBucket) -> None: """Schedule all the buckets' leak, reset bucket's failing rate""" assert new_bucket.rates, "Bucket rates are not set" if not self._leaker: self._leaker = Leaker(self.leak_interval) self._leaker.register(new_bucket) self._leaker.start() self._leaker.leak_async() def get_buckets(self) -> List[AbstractBucket]: """Iterator over all buckets in the factory""" if not self._leaker: return [] buckets = [] if self._leaker.sync_buckets: for _, bucket in self._leaker.sync_buckets.items(): buckets.append(bucket) if self._leaker.async_buckets: for _, bucket in self._leaker.async_buckets.items(): buckets.append(bucket) return buckets def dispose(self, bucket: Union[int, AbstractBucket]) -> bool: """Delete a bucket from the factory""" if isinstance(bucket, AbstractBucket): bucket = id(bucket) assert isinstance(bucket, int), "not valid bucket id" if not self._leaker: return False return self._leaker.deregister(bucket) def __del__(self): # Make sure all leakers are deregistered for bucket in self.get_buckets(): try: self.dispose(bucket) except Exception as e: logger.debug("Exception %s (%s) deleting bucket %r", type(e).__name__, e, bucket) def close(self) -> None: try: if self._leaker is not None: self._leaker.close() self._leaker = None except Exception as e: logger.info("Exception %s (%s) deleting bucket %r", type(e).__name__, e, self._leaker) for bucket in self.get_buckets(): try: logger.debug("Closing bucket %s", bucket) bucket.close() except Exception as e: logger.info("Exception %s (%s) deleting bucket %r", type(e).__name__, e, bucket) vutran1710-PyrateLimiter-634d166/pyrate_limiter/abstracts/rate.py000066400000000000000000000046271513463764300247620ustar00rootroot00000000000000"""Unit classes that deals with rate, item & duration""" from enum import Enum from typing import Union class Duration(Enum): """Interval helper class""" SECOND = 1000 MINUTE = 1000 * 60 HOUR = 1000 * 60 * 60 DAY = 1000 * 60 * 60 * 24 WEEK = 1000 * 60 * 60 * 24 * 7 def __mul__(self, mutiplier: float) -> int: return int(self.value * mutiplier) def __rmul__(self, multiplier: float) -> int: return self.__mul__(multiplier) def __add__(self, another_duration: Union["Duration", int]) -> int: return self.value + int(another_duration) def __radd__(self, another_duration: Union["Duration", int]) -> int: return self.__add__(another_duration) def __int__(self) -> int: return self.value def __eq__(self, duration: object) -> bool: if not isinstance(duration, (Duration, int)): return NotImplemented return self.value == int(duration) @staticmethod def readable(value: int) -> str: notes = [ (Duration.WEEK, "w"), (Duration.DAY, "d"), (Duration.HOUR, "h"), (Duration.MINUTE, "m"), (Duration.SECOND, "s"), ] for note, shorten in notes: if value >= note.value: decimal_value = value / note.value return f"{decimal_value:0.1f}{shorten}" # noqa: E231 return f"{value}ms" class RateItem: """RateItem is a wrapper for bucket to work with""" name: str weight: int timestamp: int def __init__(self, name: str, timestamp: int, weight: int = 1): self.name = name self.timestamp = timestamp self.weight = weight def __str__(self) -> str: return f"RateItem(name={self.name}, weight={self.weight}, timestamp={self.timestamp})" class Rate: """Rate definition. Args: limit: Number of requests allowed within ``interval`` interval: Time interval, in miliseconds """ limit: int interval: int def __init__( self, limit: int, interval: Union[int, Duration], ): self.limit = limit self.interval = int(interval) assert self.interval assert self.limit def __str__(self) -> str: return f"limit={self.limit}/{Duration.readable(self.interval)}" def __repr__(self) -> str: return f"limit={self.limit}/{self.interval}" vutran1710-PyrateLimiter-634d166/pyrate_limiter/abstracts/wrappers.py000066400000000000000000000036761513463764300256750ustar00rootroot00000000000000"""Wrappers over different abstract types""" from inspect import isawaitable from typing import Optional from .bucket import AbstractBucket from .rate import RateItem class BucketAsyncWrapper(AbstractBucket): """BucketAsyncWrapper is a wrapping over any bucket that turns a async/synchronous bucket into an async one """ def __init__(self, bucket: AbstractBucket): assert isinstance(bucket, AbstractBucket) self.bucket = bucket async def put(self, item: RateItem): result = self.bucket.put(item) while isawaitable(result): result = await result return result async def count(self): result = self.bucket.count() while isawaitable(result): result = await result return result async def leak(self, current_timestamp: Optional[int] = None) -> int: result = self.bucket.leak(current_timestamp) while isawaitable(result): result = await result assert isinstance(result, int) return result async def flush(self) -> None: result = self.bucket.flush() while isawaitable(result): # TODO: AbstractBucket.flush() may not have correct type annotation? result = await result # type: ignore return None async def peek(self, index: int) -> Optional[RateItem]: item = self.bucket.peek(index) while isawaitable(item): item = await item assert item is None or isinstance(item, RateItem) return item async def waiting(self, item: RateItem) -> int: wait = super().waiting(item) if isawaitable(wait): wait = await wait assert isinstance(wait, int) return wait def now(self) -> int: return self.bucket.now() @property def failing_rate(self): return self.bucket.failing_rate @property def rates(self): return self.bucket.rates vutran1710-PyrateLimiter-634d166/pyrate_limiter/buckets/000077500000000000000000000000001513463764300231165ustar00rootroot00000000000000vutran1710-PyrateLimiter-634d166/pyrate_limiter/buckets/__init__.py000066400000000000000000000006051513463764300252300ustar00rootroot00000000000000# flake8: noqa """Conrete bucket implementations""" from .in_memory_bucket import InMemoryBucket from .mp_bucket import MultiprocessBucket from .postgres import PostgresBucket from .postgres import Queries as PgQueries from .redis_bucket import RedisBucket from .sqlite_bucket import Queries as SQLiteQueries from .sqlite_bucket import SQLiteBucket from .sqlite_bucket import SQLiteClock vutran1710-PyrateLimiter-634d166/pyrate_limiter/buckets/in_memory_bucket.py000066400000000000000000000052521513463764300270270ustar00rootroot00000000000000"""Naive bucket implementation using built-in list""" from typing import List, Optional from ..abstracts.bucket import AbstractBucket from ..abstracts.rate import Rate, RateItem from ..utils import binary_search class InMemoryBucket(AbstractBucket): """Simple In-memory Bucket using native list Clock can be either `time.time` or `time.monotonic` When leak, clock is required Pros: fast, safe, and precise Cons: since it resides in local memory, the data is not persistent, nor scalable Usecase: small applications, simple logic """ items: List[RateItem] failing_rate: Optional[Rate] def __init__(self, rates: List[Rate]): super().__init__() self.rates = sorted(rates, key=lambda r: r.interval) self.items = [] def put(self, item: RateItem) -> bool: if item.weight == 0: return True current_length = len(self.items) after_length = item.weight + current_length for rate in self.rates: if after_length < rate.limit: break lower_bound_value = item.timestamp - rate.interval lower_bound_idx = binary_search(self.items, lower_bound_value) if lower_bound_idx >= 0: count_existing_items = len(self.items) - lower_bound_idx space_available = rate.limit - count_existing_items else: space_available = rate.limit if space_available < item.weight: self.failing_rate = rate return False self.failing_rate = None if item.weight > 1: self.items.extend([item for _ in range(item.weight)]) else: self.items.append(item) return True def leak(self, current_timestamp: Optional[int] = None) -> int: assert current_timestamp is not None if self.items: max_interval = self.rates[-1].interval lower_bound = current_timestamp - max_interval if lower_bound > self.items[-1].timestamp: remove_count = len(self.items) del self.items[:] return remove_count if lower_bound < self.items[0].timestamp: return 0 idx = binary_search(self.items, lower_bound) del self.items[:idx] return idx return 0 def flush(self) -> None: self.failing_rate = None del self.items[:] def count(self) -> int: return len(self.items) def peek(self, index: int) -> RateItem | None: if not self.items: return None return self.items[-1 - index] if abs(index) < self.count() else None vutran1710-PyrateLimiter-634d166/pyrate_limiter/buckets/mp_bucket.py000066400000000000000000000030731513463764300254440ustar00rootroot00000000000000"""multiprocessing In-memory Bucket using a multiprocessing.Manager.ListProxy and a multiprocessing.Lock. """ from multiprocessing import Manager, RLock from multiprocessing.managers import ListProxy from multiprocessing.synchronize import RLock as LockType from typing import List, Optional from ..abstracts import Rate, RateItem from ..buckets import InMemoryBucket from ..clocks import MonotonicClock class MultiprocessBucket(InMemoryBucket): items: List[RateItem] # ListProxy mp_lock: LockType def __init__(self, rates: List[Rate], items: List[RateItem], mp_lock: LockType): if not isinstance(items, ListProxy): # pragma: no cover - guard only raise ValueError("items must be a ListProxy") self._clock = MonotonicClock() self.rates = sorted(rates, key=lambda r: r.interval) self.items = items self.mp_lock = mp_lock def put(self, item: RateItem) -> bool: with self.mp_lock: return super().put(item) def leak(self, current_timestamp: Optional[int] = None) -> int: with self.mp_lock: return super().leak(current_timestamp) def limiter_lock(self): return self.mp_lock @classmethod def init( cls, rates: List[Rate], ): """ Creates a single ListProxy so that this bucket can be shared across multiple processes. """ shared_items: List[RateItem] = Manager().list() # type: ignore[assignment] mp_lock: LockType = RLock() return cls(rates=rates, items=shared_items, mp_lock=mp_lock) vutran1710-PyrateLimiter-634d166/pyrate_limiter/buckets/postgres.py000066400000000000000000000155521513463764300253460ustar00rootroot00000000000000"""A bucket using PostgreSQL as backend""" from __future__ import annotations import logging from contextlib import contextmanager from time import time_ns from typing import TYPE_CHECKING, Awaitable, List, Optional, Union from ..abstracts import AbstractBucket, Rate, RateItem logger = logging.getLogger(__name__) if TYPE_CHECKING: from psycopg_pool import ConnectionPool # type: ignore[import-untyped] class Queries: CREATE_BUCKET_TABLE = """ CREATE TABLE IF NOT EXISTS {table} ( name VARCHAR, weight SMALLINT, item_timestamp TIMESTAMP ) """ CREATE_INDEX_ON_TIMESTAMP = """ CREATE INDEX IF NOT EXISTS {index} ON {table} (item_timestamp) """ LOCK_TABLE = """ LOCK TABLE {table} IN EXCLUSIVE MODE NOWAIT """ COUNT = """ SELECT COUNT(*) FROM {table} """ PUT = """ INSERT INTO {table} (name, weight, item_timestamp) VALUES (%s, %s, TO_TIMESTAMP(%s)) """ FLUSH = """ DELETE FROM {table} """ PEEK = """ SELECT name, weight, (extract(EPOCH FROM item_timestamp) * 1000) as item_timestamp FROM {table} ORDER BY item_timestamp DESC LIMIT 1 OFFSET {offset} """ LEAK = """ DELETE FROM {table} WHERE item_timestamp < TO_TIMESTAMP({timestamp}) """ LEAK_COUNT = """ SELECT COUNT(*) FROM {table} WHERE item_timestamp < TO_TIMESTAMP({timestamp}) """ class PostgresBucket(AbstractBucket): table: str pool: ConnectionPool def __init__(self, pool: ConnectionPool, table: str, rates: List[Rate]): self.table = table.lower() self.pool = pool assert rates self.rates = rates self._full_tbl = f"ratelimit___{self.table}" self._create_table() def now(self): # TODO: Use a Postgres time source via SQL return time_ns() // 1000000 @contextmanager def _get_conn(self): with self.pool.connection() as conn: yield conn def _create_table(self): with self._get_conn() as conn: lock_id = hash(self._full_tbl) & 0x7FFFFFFF conn.execute("SELECT pg_advisory_xact_lock(%s)", (lock_id,)) conn.execute(Queries.CREATE_BUCKET_TABLE.format(table=self._full_tbl)) index_name = f"timestampIndex_{self.table}" conn.execute(Queries.CREATE_INDEX_ON_TIMESTAMP.format(table=self._full_tbl, index=index_name)) def put(self, item: RateItem) -> Union[bool, Awaitable[bool]]: """Put an item (typically the current time) in the bucket return true if successful, otherwise false """ from psycopg.errors import LockNotAvailable if item.weight == 0: return True item_ts_seconds = item.timestamp / 1000 with self._get_conn() as conn: # Acquire an EXCLUSIVE MODE lock on the bucket table using NOWAIT. # This ensures the "check current count" + "insert new items" sequence # is atomic with respect to other writers, so rate limits cannot be # exceeded due to concurrent requests interleaving. # # Because we use NOWAIT, if the table is already locked by another # transaction, PostgreSQL raises LockNotAvailable and we immediately # reject this request (return False) instead of blocking or retrying. # This provides predictable, fail-fast behavior but may limit # throughput under high contention since only one writer can perform # the check-and-put at a time. try: conn.execute(Queries.LOCK_TABLE.format(table=self._full_tbl)) except LockNotAvailable: logger.debug("LockNotAvailable") self.failing_rate = self.rates[0] return False for rate in self.rates: cur = conn.execute( f"SELECT COUNT(*) FROM {self._full_tbl} " # noqa: S608 f"WHERE item_timestamp >= TO_TIMESTAMP(%s) - (%s * INTERVAL '1 milliseconds')", (item_ts_seconds, rate.interval), ) count = int(cur.fetchone()[0]) cur.close() if rate.limit - count < item.weight: self.failing_rate = rate return False self.failing_rate = None query = Queries.PUT.format(table=self._full_tbl) for _ in range(item.weight): conn.execute(query, (item.name, item.weight, item_ts_seconds)) return True def leak( self, current_timestamp: Optional[int] = None, ) -> Union[int, Awaitable[int]]: """leaking bucket - removing items that are outdated""" assert current_timestamp is not None, "current-time must be passed on for leak" lower_bound = current_timestamp - self.rates[-1].interval if lower_bound <= 0: return 0 count = 0 with self._get_conn() as conn: conn = conn.execute(Queries.LEAK_COUNT.format(table=self._full_tbl, timestamp=lower_bound / 1000)) result = conn.fetchone() if result: conn.execute(Queries.LEAK.format(table=self._full_tbl, timestamp=lower_bound / 1000)) count = int(result[0]) return count def flush(self) -> Union[None, Awaitable[None]]: """Flush the whole bucket - Must remove `failing-rate` after flushing """ with self._get_conn() as conn: conn.execute(Queries.FLUSH.format(table=self._full_tbl)) self.failing_rate = None return None def count(self) -> Union[int, Awaitable[int]]: """Count number of items in the bucket""" count = 0 with self._get_conn() as conn: conn = conn.execute(Queries.COUNT.format(table=self._full_tbl)) result = conn.fetchone() assert result count = int(result[0]) return count def peek(self, index: int) -> Union[Optional[RateItem], Awaitable[Optional[RateItem]]]: """Peek at the rate-item at a specific index in latest-to-earliest order NOTE: The reason we cannot peek from the start of the queue(earliest-to-latest) is we can't really tell how many outdated items are still in the queue """ item = None with self._get_conn() as conn: conn = conn.execute(Queries.PEEK.format(table=self._full_tbl, offset=index)) result = conn.fetchone() if result: name, weight, timestamp = result[0], int(result[1]), int(result[2]) item = RateItem(name=name, weight=weight, timestamp=timestamp) return item def close(self): if self.pool is not None and not self.pool.closed: try: self.pool.close() except Exception as e: logger.debug("Exception closing pool, %s", e) vutran1710-PyrateLimiter-634d166/pyrate_limiter/buckets/redis_bucket.py000066400000000000000000000126121513463764300261350ustar00rootroot00000000000000"""Bucket implementation using Redis""" from __future__ import annotations from inspect import isawaitable from time import time_ns from typing import TYPE_CHECKING, Awaitable, List, Optional, Tuple, Union from ..abstracts import AbstractBucket, Rate, RateItem from ..utils import id_generator if TYPE_CHECKING: from redis import Redis from redis.asyncio import Redis as AsyncRedis class LuaScript: """Scripts that deal with bucket operations""" PUT_ITEM = """ local bucket = KEYS[1] local now = ARGV[1] local space_required = tonumber(ARGV[2]) local item_name = ARGV[3] local rates_count = tonumber(ARGV[4]) for i=1,rates_count do local offset = (i - 1) * 2 local interval = tonumber(ARGV[5 + offset]) local limit = tonumber(ARGV[5 + offset + 1]) local count = redis.call('ZCOUNT', bucket, now - interval, now) local space_available = limit - tonumber(count) if space_available < space_required then return i - 1 end end for i=1,space_required do redis.call('ZADD', bucket, now, item_name..i) end return -1 """ class RedisBucket(AbstractBucket): """A bucket using redis for storing data - We are not using redis' built-in TIME since it is non-deterministic - In distributed context, use local server time or a remote time server - Each bucket instance use a dedicated connection to avoid race-condition - can be either sync or async """ rates: List[Rate] failing_rate: Optional[Rate] bucket_key: str script_hash: str redis: Union[Redis, AsyncRedis] def __init__( self, rates: List[Rate], redis: Union[Redis, AsyncRedis], bucket_key: str, script_hash: str, ): self.rates = rates self.redis = redis self.bucket_key = bucket_key self.script_hash = script_hash self.failing_rate = None def now(self): # TODO: Use a Redis time source via a Lua script return time_ns() // 1000000 @classmethod def init( cls, rates: List[Rate], redis: Union[Redis, AsyncRedis], bucket_key: str, ): script_hash = redis.script_load(LuaScript.PUT_ITEM) if isawaitable(script_hash): async def _async_init(): nonlocal script_hash script_hash = await script_hash return cls(rates, redis, bucket_key, script_hash) return _async_init() return cls(rates, redis, bucket_key, script_hash) def _check_and_insert(self, item: RateItem) -> Union[Rate, None, Awaitable[Optional[Rate]]]: keys = [self.bucket_key] args = [ item.timestamp, item.weight, # NOTE: this is to avoid key collision since we are using ZSET f"{item.name}:{id_generator()}:", # noqa: E231 len(self.rates), *[value for rate in self.rates for value in (rate.interval, rate.limit)], ] idx = self.redis.evalsha(self.script_hash, len(keys), *keys, *args) def _handle_sync(returned_idx: int): assert isinstance(returned_idx, int), "Not int" if returned_idx < 0: return None return self.rates[returned_idx] async def _handle_async(returned_idx: Awaitable[int]): assert isawaitable(returned_idx), "Not corotine" awaited_idx = await returned_idx return _handle_sync(awaited_idx) return _handle_async(idx) if isawaitable(idx) else _handle_sync(idx) def put(self, item: RateItem) -> Union[bool, Awaitable[bool]]: """Add item to key""" failing_rate = self._check_and_insert(item) if isawaitable(failing_rate): async def _handle_async(): self.failing_rate = await failing_rate return not bool(self.failing_rate) return _handle_async() assert isinstance(failing_rate, Rate) or failing_rate is None self.failing_rate = failing_rate return not bool(self.failing_rate) def leak(self, current_timestamp: Optional[int] = None) -> Union[int, Awaitable[int]]: assert current_timestamp is not None return self.redis.zremrangebyscore( self.bucket_key, 0, current_timestamp - self.rates[-1].interval, ) def flush(self): self.failing_rate = None return self.redis.delete(self.bucket_key) def count(self): return self.redis.zcard(self.bucket_key) def peek(self, index: int) -> Union[RateItem, None, Awaitable[Optional[RateItem]]]: items = self.redis.zrange( self.bucket_key, -1 - index, -1 - index, withscores=True, score_cast_func=int, ) if not items: return None def _handle_items(received_items: List[Tuple[str, int]]): if not received_items: return None item = received_items[0] rate_item = RateItem(name=str(item[0]), timestamp=item[1]) return rate_item if isawaitable(items): async def _awaiting(): nonlocal items items = await items return _handle_items(items) return _awaiting() assert isinstance(items, list) return _handle_items(items) vutran1710-PyrateLimiter-634d166/pyrate_limiter/buckets/sqlite_bucket.py000066400000000000000000000222531513463764300263320ustar00rootroot00000000000000"""Bucket implementation using SQLite""" import logging import sqlite3 from contextlib import nullcontext from pathlib import Path from tempfile import gettempdir from threading import RLock from time import time, time_ns from typing import List, Optional, Tuple, Union from ..abstracts import AbstractBucket, Rate, RateItem from ..clocks import AbstractClock from ..utils import dedicated_sqlite_clock_connection logger = logging.getLogger(__name__) class Queries: CREATE_BUCKET_TABLE = """ CREATE TABLE IF NOT EXISTS '{table}' ( name VARCHAR, item_timestamp INTEGER ) """ CREATE_INDEX_ON_TIMESTAMP = """ CREATE INDEX IF NOT EXISTS '{index_name}' ON '{table_name}' (item_timestamp) """ COUNT_BEFORE_INSERT = """ SELECT :interval{index} as interval, COUNT(*) FROM '{table}' WHERE item_timestamp >= :current_timestamp - :interval{index} """ PUT_ITEM = """ INSERT INTO '{table}' (name, item_timestamp) VALUES %s """ LEAK = """ DELETE FROM "{table}" WHERE rowid IN ( SELECT rowid FROM "{table}" ORDER BY item_timestamp ASC LIMIT {count}); """.strip() COUNT_BEFORE_LEAK = """SELECT COUNT(*) FROM '{table}' WHERE item_timestamp < {current_timestamp} - {interval}""" FLUSH = """DELETE FROM '{table}'""" # The below sqls are for testing only DROP_TABLE = "DROP TABLE IF EXISTS '{table}'" DROP_INDEX = "DROP INDEX IF EXISTS '{index}'" COUNT_ALL = "SELECT COUNT(*) FROM '{table}'" GET_ALL_ITEM = "SELECT * FROM '{table}' ORDER BY item_timestamp ASC" GET_FIRST_ITEM = "SELECT name, item_timestamp FROM '{table}' ORDER BY item_timestamp ASC" GET_LAG = """ SELECT (strftime ('%s', 'now') || substr(strftime ('%f', 'now'), 4)) - ( SELECT item_timestamp FROM '{table}' ORDER BY item_timestamp ASC LIMIT 1 ) """ PEEK = 'SELECT * FROM "{table}" ORDER BY item_timestamp DESC LIMIT 1 OFFSET {count}' class SQLiteBucket(AbstractBucket): """For sqlite bucket, we are using the sql time function as the clock item's timestamp wont matter here """ rates: List[Rate] failing_rate: Optional[Rate] conn: sqlite3.Connection table: str full_count_query: str lock: RLock use_limiter_lock: bool def __init__(self, rates: List[Rate], conn: sqlite3.Connection, table: str, lock=None): self.conn = conn self.table = table self.rates = rates if not lock: self.use_limiter_lock = False self.lock = RLock() else: self.use_limiter_lock = True self.lock = lock def now(self): # TODO: Use Sqlite time source via a Lua script return time_ns() // 1000000 def limiter_lock(self): if self.use_limiter_lock: return self.lock else: return None def _build_full_count_query(self, current_timestamp: int) -> Tuple[str, dict]: full_query: List[str] = [] parameters = {"current_timestamp": current_timestamp} for index, rate in enumerate(self.rates): parameters[f"interval{index}"] = rate.interval query = Queries.COUNT_BEFORE_INSERT.format(table=self.table, index=index) full_query.append(query) join_full_query = " union ".join(full_query) if len(full_query) > 1 else full_query[0] return join_full_query, parameters def put(self, item: RateItem) -> bool: with self.lock: query, parameters = self._build_full_count_query(item.timestamp) cur = self.conn.execute(query, parameters) rate_limit_counts = cur.fetchall() cur.close() for idx, result in enumerate(rate_limit_counts): interval, count = result rate = self.rates[idx] assert interval == rate.interval space_available = rate.limit - count if space_available < item.weight: self.failing_rate = rate return False items = ", ".join([f"('{name}', {item.timestamp})" for name in [item.name] * item.weight]) query = (Queries.PUT_ITEM.format(table=self.table)) % items self.conn.execute(query).close() self.conn.commit() return True def leak(self, current_timestamp: Optional[int] = None) -> int: """Leaking/clean up bucket""" with self.lock: assert current_timestamp is not None query = Queries.COUNT_BEFORE_LEAK.format( table=self.table, interval=self.rates[-1].interval, current_timestamp=current_timestamp, ) cur = self.conn.execute(query) count = cur.fetchone()[0] query = Queries.LEAK.format(table=self.table, count=count) cur.execute(query) cur.close() self.conn.commit() return count def flush(self) -> None: with self.lock: self.conn.execute(Queries.FLUSH.format(table=self.table)).close() self.conn.commit() self.failing_rate = None def count(self) -> int: with self.lock: cur = self.conn.execute(Queries.COUNT_ALL.format(table=self.table)) ret = cur.fetchone()[0] cur.close() return ret def peek(self, index: int) -> Optional[RateItem]: with self.lock: query = Queries.PEEK.format(table=self.table, count=index) cur = self.conn.execute(query) item = cur.fetchone() cur.close() if not item: return None return RateItem(item[0], item[1]) def close(self): with self.lock: if self.conn is not None: try: self.conn.close() self.conn = None except Exception as e: logger.debug("Exception %s closing sql connection", e) @classmethod def init_from_file( cls, rates: List[Rate], table: str = "rate_bucket", db_path: Optional[str] = None, create_new_table: bool = True, use_file_lock: bool = False ) -> "SQLiteBucket": if db_path is None and use_file_lock: raise ValueError("db_path must be specified when using use_file_lock") if db_path is None: temp_dir = Path(gettempdir()) db_path = str(temp_dir / f"pyrate_limiter_{time()}.sqlite") # TBD: FileLock switched to a thread-local FileLock in 3.11.0. # Should we set FileLock's thread_local to False, for cases where user is both multiprocessing & threading? # As is, the file lock should be Multi Process - Single Thread and non-filelock is Single Process - Multi Thread # A hybrid lock may be needed to gracefully handle both cases file_lock = None file_lock_ctx = nullcontext() if use_file_lock: try: from filelock import FileLock # type: ignore[import-untyped] file_lock = FileLock(db_path + ".lock") # type: ignore[no-redef] file_lock_ctx: Union[nullcontext, FileLock] = file_lock # type: ignore[no-redef] except ImportError as e: raise ImportError("filelock is required for file locking. Please install it as optional dependency") from e with file_lock_ctx: assert db_path is not None sqlite_connection = sqlite3.connect( db_path, isolation_level="DEFERRED", check_same_thread=False, ) cur = sqlite_connection.cursor() if use_file_lock: # https://www.sqlite.org/wal.html cur.execute("PRAGMA journal_mode=WAL;") # https://www.sqlite.org/pragma.html#pragma_synchronous cur.execute("PRAGMA synchronous=NORMAL;") if create_new_table: cur.execute(Queries.CREATE_BUCKET_TABLE.format(table=table)) create_idx_query = Queries.CREATE_INDEX_ON_TIMESTAMP.format( index_name=f"idx_{table}_rate_item_timestamp", table_name=table, ) cur.execute(create_idx_query) cur.close() sqlite_connection.commit() return cls(rates, sqlite_connection, table=table, lock=file_lock) class SQLiteClock(AbstractClock): """Get timestamp using SQLite as remote clock backend""" time_query = "SELECT CAST(ROUND((julianday('now') - 2440587.5)*86400000) As INTEGER)" def __init__(self, conn: Union[sqlite3.Connection, SQLiteBucket]): """ In multiprocessing cases, use the bucket, so that a shared lock is used. """ self.lock: Optional[RLock] = None if isinstance(conn, SQLiteBucket): self.conn = conn.conn self.lock = conn.lock else: self.conn = conn @classmethod def default(cls): conn = dedicated_sqlite_clock_connection() return cls(conn) def now(self) -> int: with self.lock if self.lock else nullcontext(): cur = self.conn.execute(self.time_query) now = cur.fetchone()[0] cur.close() return int(now) vutran1710-PyrateLimiter-634d166/pyrate_limiter/clocks.py000066400000000000000000000025101513463764300233040ustar00rootroot00000000000000"""Clock implementation using different backend""" from __future__ import annotations from abc import ABC, abstractmethod from time import monotonic_ns from typing import TYPE_CHECKING, Awaitable, Union if TYPE_CHECKING: from psycopg_pool import ConnectionPool class AbstractClock(ABC): """Clock that return timestamp for `now`""" @abstractmethod def now(self) -> Union[int, Awaitable[int]]: """Get time as of now, in miliseconds""" class MonotonicClock(AbstractClock): def __init__(self): monotonic_ns() def now(self): return monotonic_ns() // 1000000 class MonotonicAsyncClock(AbstractClock): """Monotonic Async Clock, meant for testing only""" async def now(self) -> int: return monotonic_ns() // 1000000 class PostgresClock(AbstractClock): """Get timestamp using Postgres as remote clock backend""" def __init__(self, pool: "ConnectionPool"): self.pool = pool def now(self) -> int: value = 0 with self.pool.connection() as conn: with conn.cursor() as cur: cur.execute("SELECT EXTRACT(epoch FROM current_timestamp) * 1000") result = cur.fetchone() assert result, "unable to get current-timestamp from postgres" value = int(result[0]) return value vutran1710-PyrateLimiter-634d166/pyrate_limiter/extras/000077500000000000000000000000001513463764300227645ustar00rootroot00000000000000vutran1710-PyrateLimiter-634d166/pyrate_limiter/extras/__init__.py000066400000000000000000000000001513463764300250630ustar00rootroot00000000000000vutran1710-PyrateLimiter-634d166/pyrate_limiter/extras/aiohttp_limiter.py000066400000000000000000000047211513463764300265370ustar00rootroot00000000000000import logging import aiohttp from pyrate_limiter import Limiter logger = logging.getLogger(__name__) class RateLimitedSession: """ A thin wrapper around :class:`aiohttp.ClientSession` that enforces rate limits using a provided :class:`~pyrate_limiter.Limiter`. Each request acquires a token from the limiter before delegating to the underlying ``aiohttp`` session. """ def __init__(self, limiter: Limiter, name: str = "pyrate", **kwargs): """ Initialize a new rate-limited session. Parameters ---------- limiter : :class:`~pyrate_limiter.Limiter` Limiter used to control request rate. name : str, optional Token/key used by the limiter to bucket this session's requests. **kwargs Additional keyword arguments passed to :class:`aiohttp.ClientSession`. """ self._limiter = limiter self._session = aiohttp.ClientSession(**kwargs) self.name = name async def get(self, *a, **k): """ Perform a GET request after acquiring from the limiter. Parameters ---------- *a, **k Arguments forwarded to :meth:`aiohttp.ClientSession.get`. Returns ------- :class:`aiohttp.ClientResponse` The response object from the request. """ await self._limiter.try_acquire_async(self.name) return await self._session.get(*a, **k) async def post(self, *a, **k): """ Perform a POST request after acquiring from the limiter. Parameters ---------- *a, **k Arguments forwarded to :meth:`aiohttp.ClientSession.post`. Returns ------- :class:`aiohttp.ClientResponse` The response object from the request. """ await self._limiter.try_acquire_async(self.name) return await self._session.post(*a, **k) async def __aenter__(self): """ Enter the async context manager, returning the session itself. Returns ------- RateLimitedSession The current session instance. """ return self async def __aexit__(self, *exc): """ Exit the async context manager and close the underlying session. Parameters ---------- *exc Exception information, if any, from the context block. """ await self._session.close() vutran1710-PyrateLimiter-634d166/pyrate_limiter/extras/httpx_limiter.py000066400000000000000000000060541513463764300262370ustar00rootroot00000000000000import logging from httpx import AsyncHTTPTransport, HTTPTransport, Request, Response from pyrate_limiter import Limiter logger = logging.getLogger(__name__) class RateLimiterTransport(HTTPTransport): """ A synchronous HTTPX transport that enforces a rate limit via a provided :class:`~pyrate_limiter.Limiter`. All requests share the same limiter item key, so the same rate limit is applied globally across requests. """ def __init__(self, limiter: Limiter, **kwargs): """ Initialize the transport. Parameters ---------- limiter : :class:`~pyrate_limiter.Limiter` Limiter used to control request rate. **kwargs Additional keyword arguments passed to :class:`httpx.HTTPTransport`. """ super().__init__(**kwargs) self.limiter = limiter def handle_request(self, request: Request, **kwargs) -> Response: """ Handle a synchronous HTTP request after acquiring from the limiter. The limiter is polled until a permit is acquired; all requests share the same limiter key. Parameters ---------- request : :class:`httpx.Request` The request to send. **kwargs Forwarded to :meth:`httpx.HTTPTransport.handle_request`. Returns ------- :class:`httpx.Response` The HTTP response. """ self.limiter.try_acquire(__name__) logger.debug("Acquired lock") return super().handle_request(request, **kwargs) class AsyncRateLimiterTransport(AsyncHTTPTransport): """ An asynchronous HTTPX transport that enforces a rate limit via a provided :class:`~pyrate_limiter.Limiter`. All requests share the same limiter item key, so the same rate limit is applied globally across requests. """ def __init__(self, limiter: Limiter, **kwargs): """ Initialize the transport. Parameters ---------- limiter : :class:`~pyrate_limiter.Limiter` Limiter used to control request rate. **kwargs Additional keyword arguments passed to :class:`httpx.AsyncHTTPTransport`. """ super().__init__(**kwargs) self.limiter = limiter async def handle_async_request(self, request: Request, **kwargs) -> Response: """ Handle an asynchronous HTTP request after acquiring from the limiter. The limiter is polled until a permit is acquired; all requests share the same limiter key. Parameters ---------- request : :class:`httpx.Request` The request to send. **kwargs Forwarded to :meth:`httpx.AsyncHTTPTransport.handle_async_request`. Returns ------- :class:`httpx.Response` The HTTP response. """ await self.limiter.try_acquire_async(__name__) logger.debug("Acquired lock") response = await super().handle_async_request(request, **kwargs) return response vutran1710-PyrateLimiter-634d166/pyrate_limiter/extras/requests_limiter.py000066400000000000000000000031211513463764300267330ustar00rootroot00000000000000import logging from typing import Any, Union from requests import Response, Session from pyrate_limiter import Limiter logger = logging.getLogger(__name__) class RateLimitedRequestsSession(Session): """ A requests.Session that enforces a rate limit via a provided Limiter. The limiter's ``try_acquire(name)`` is called before every outbound request. """ def __init__(self, limiter: "Limiter", name: str = __name__, **_: Any) -> None: """ Initialize the rate-limited session. Args: limiter: Object exposing ``try_acquire(str) -> None`` that blocks/raises when over limit. name: Token/key used by the limiter to bucket this session's requests. ``**_``: Ignored; accepted for API compatibility. """ super().__init__() self._limiter = limiter self._name = name def request(self, method: Union[str, bytes], url: Union[str, bytes], *args: Any, **kwargs: Any) -> Response: """ Perform an HTTP request after acquiring from the limiter. Args: method: HTTP method (e.g., "GET", "POST"). url: Request URL. ``*args``, ``**kwargs``: Passed through to ``requests.Session.request``. Returns: :class:`requests.Response` returned by the underlying session. """ self._limiter.try_acquire(self._name) return super().request(method, url, *args, **kwargs) def close(self) -> None: """ Close the underlying HTTP adapters and release resources. """ return super().close() vutran1710-PyrateLimiter-634d166/pyrate_limiter/limiter.py000066400000000000000000000342561513463764300235070ustar00rootroot00000000000000"""Limiter class implementation""" import asyncio import logging from contextlib import contextmanager from functools import wraps from inspect import isawaitable, iscoroutinefunction from threading import RLock, local from time import sleep from typing import Any, Awaitable, Callable, Iterable, List, Protocol, Tuple, Union from .abstracts import AbstractBucket, BucketFactory, Rate, RateItem from .buckets import InMemoryBucket logger = logging.getLogger(__name__) ItemMapping = Callable[[Any], Tuple[str, int]] DecoratorWrapper = Callable[[Callable[[Any], Any]], Callable[[Any], Any]] class LockLike(Protocol): def acquire(self, blocking: bool = ..., timeout: Union[float, int, None] = ...) -> bool: ... def release(self) -> None: ... class SingleBucketFactory(BucketFactory): """Single-bucket factory for quick use with Limiter""" bucket: AbstractBucket def __init__(self, bucket: AbstractBucket, schedule_leak: bool = True): """ Initialize the SingleBucketFactory with a bucket and an optional leak scheduling flag. schedule_leak (bool): If True, the factory will schedule periodic leaks for the bucket. Default is True. Disable only if you plan to handle leaking manually. """ self.bucket = bucket if schedule_leak: self.schedule_leak(bucket) def wrap_item(self, name: str, weight: int = 1): now = self.bucket.now() async def wrap_async(): return RateItem(name, await now, weight=weight) def wrap_sync(): return RateItem(name, now, weight=weight) return wrap_async() if isawaitable(now) else wrap_sync() def get(self, _: RateItem) -> AbstractBucket: return self.bucket @contextmanager def combined_lock(locks: Union[Iterable[LockLike], RLock], blocking: bool, timeout: int | float = -1): if not isinstance(locks, Iterable): acquired_ok = locks.acquire(blocking=blocking, timeout=timeout) if not acquired_ok: raise TimeoutError("acquire failed") try: yield finally: locks.release() else: acquired_locks = [] try: for lock in locks: if not blocking: ok = lock.acquire(False) elif timeout == -1: ok = lock.acquire() else: ok = lock.acquire(timeout=timeout) if not ok: raise TimeoutError("Timeout while acquiring combined lock.") acquired_locks.append(lock) yield finally: for lock in reversed(acquired_locks): lock.release() class Limiter: """This class responsibility is to sum up all underlying logic and make working with async/sync functions easily """ bucket_factory: BucketFactory lock: Union[RLock, Iterable] buffer_ms: int # async_lock is thread local, created on first use _thread_local: local def __init__( self, argument: Union[BucketFactory, AbstractBucket, Rate, List[Rate]], buffer_ms: int = 50, ): """Init Limiter using either a single bucket / multiple-bucket factory / single rate / rate list. Parameters: argument (Union[BucketFactory, AbstractBucket, Rate, List[Rate]]): The bucket or rate configuration. """ self.buffer_ms = buffer_ms self.bucket_factory = self._init_bucket_factory(argument) self.lock = RLock() self._thread_local = local() if isinstance(argument, AbstractBucket): limiter_lock = argument.limiter_lock() if limiter_lock is not None: self.lock = (limiter_lock, self.lock) def buckets(self) -> List[AbstractBucket]: """Get list of active buckets""" return self.bucket_factory.get_buckets() def dispose(self, bucket: Union[int, AbstractBucket]) -> bool: """Dispose/Remove a specific bucket, using bucket-id or bucket object as param """ return self.bucket_factory.dispose(bucket) def _init_bucket_factory( self, argument: Union[BucketFactory, AbstractBucket, Rate, List[Rate]], ) -> BucketFactory: if isinstance(argument, Rate): argument = [argument] if isinstance(argument, list): assert len(argument) > 0, "Rates must not be empty" assert isinstance(argument[0], Rate), "Not valid rates list" rates = argument logger.info("Initializing default bucket(InMemoryBucket) with rates: %s", rates) argument = InMemoryBucket(rates) if isinstance(argument, AbstractBucket): argument = SingleBucketFactory(argument) assert isinstance(argument, BucketFactory), "Not a valid bucket/bucket-factory" return argument def _delay_waiter(self, bucket: AbstractBucket, item: RateItem, blocking: bool, _force_async: bool = False) -> Union[bool, Awaitable[bool]]: """On `try_acquire` failed, handle delay""" assert bucket.failing_rate is not None if not blocking: return False delay = bucket.waiting(item) if _force_async or isawaitable(delay): async def _handle_async(delay): while True: d = await delay if isawaitable(delay) else delay assert isinstance(d, int) and d >= 0 d += self.buffer_ms await asyncio.sleep(d / 1000) item.timestamp += d r = bucket.put(item) r = await r if isawaitable(r) else r if r: return True delay = bucket.waiting(item) return _handle_async(delay) else: total_delay = 0 while True: assert not isawaitable(delay) logger.debug("delay=%d, total_delay=%s", delay, total_delay) delay += self.buffer_ms total_delay += delay sleep(delay / 1000) item.timestamp += delay re_acquire = bucket.put(item) # NOTE: if delay is not Awaitable, then `bucket.put` is not Awaitable assert isinstance(re_acquire, bool) if re_acquire: return True delay = bucket.waiting(item) def handle_bucket_put(self, bucket: AbstractBucket, item: RateItem, blocking: bool, _force_async: bool = False) -> Union[bool, Awaitable[bool]]: """Putting item into bucket""" def _handle_result(is_success: bool): if not is_success: return self._delay_waiter(bucket, item, blocking=blocking, _force_async=_force_async) return True acquire = bucket.put(item) if isawaitable(acquire): async def _put_async(acquire): acquire = await acquire result = _handle_result(acquire) while isawaitable(result): result = await result return result return _put_async(acquire) return _handle_result(acquire) # type: ignore def _get_async_lock(self): """Returns thread_local, loop-specific lock""" loop = asyncio.get_running_loop() try: # The async loop *can* change in a given thread lock = self._thread_local.async_lock if self._thread_local.async_lock_loop is loop: return lock except AttributeError: pass lock = asyncio.Lock() self._thread_local.async_lock = lock self._thread_local.async_lock_loop = loop return lock def try_acquire(self, name: str = "pyrate", weight: int = 1, blocking: bool = True, timeout: int = -1) -> Union[bool, Awaitable[bool]]: """ Attempt to acquire a permit from the limiter. Parameters ---------- name : str, default "pyrate" The bucket key to acquire from. weight : int, default 1 Number of permits to consume. timeout : int, default -1 Maximum time (in seconds) to wait; -1 means wait indefinitely. ** Timeout is not yet implemented for sync path. Use try_acquire_async ** blocking : bool, default True If True, block until a permit is available (subject to timeout); if False, return immediately. Returns ------- bool or Awaitable[bool] True if the permit was acquired, False otherwise. Async limiters return an awaitable resolving to the same. """ try: return self._try_acquire(name=name, weight=weight, timeout=timeout, blocking=blocking) except TimeoutError: logger.debug("Acquisition TimeoutError") return False async def _acquire_async(self, blocking, name, weight): return await self._handle_async_result(self._try_acquire(name, weight, blocking=blocking, _force_async=True)) async def try_acquire_async(self, name: str = "pyrate", weight: int = 1, blocking: bool = True, timeout: int = -1) -> bool: """ Attempt to asynchronously acquire a permit from the limiter. Parameters ---------- name : str, default "pyrate" The bucket key to acquire from. weight : int, default 1 Number of permits to consume. blocking : bool, default True If True, wait until a permit is available (subject to timeout); if False, return immediately. timeout : int, default -1 Maximum time (in seconds) to wait; -1 means wait indefinitely. Returns ------- bool True if the permit was acquired, False otherwise. Notes ----- This is the async variant of ``try_acquire``. A top-level, thread-local async lock is used to prevent blocking the event loop. """ if weight == 0: return True if not blocking and timeout != -1: raise RuntimeError("Can't set timeout with non-blocking") async def run(): lock = self._get_async_lock() async with lock: return await self._acquire_async(blocking=blocking, name=name, weight=weight) if timeout == -1: return await run() try: return await asyncio.wait_for(run(), timeout=timeout) except asyncio.TimeoutError: return False async def _handle_async_acquire( self, item: Awaitable[RateItem], blocking: bool, _force_async: bool = False, ): this_item = await item bucket = self.bucket_factory.get(this_item) if isawaitable(bucket): bucket = await bucket assert isinstance(bucket, AbstractBucket), f"Invalid bucket: item: {this_item.name}" result = self.handle_bucket_put(bucket, this_item, blocking=blocking, _force_async=_force_async) while isawaitable(result): result = await result return result async def _handle_async_bucket( self, bucket: Awaitable[AbstractBucket], item: RateItem, blocking: bool, _force_async: bool = False, ): this_bucket = await bucket assert isinstance(this_bucket, AbstractBucket), f"Invalid bucket: item: {item.name}" result = self.handle_bucket_put(this_bucket, item, blocking=blocking, _force_async=_force_async) while isawaitable(result): result = await result return result async def _handle_async_result(self, result): while isawaitable(result): result = await result return result def _try_acquire(self, name: str, weight: int, blocking: bool, timeout: int = -1, _force_async: bool = False) -> Union[bool, Awaitable[bool]]: """Try acquiring an item with name & weight Return true on success, false on failure """ if timeout != -1: raise NotImplementedError("timeout not implemented for sync try_acquire yet") with combined_lock(self.lock, blocking=blocking, timeout=timeout): assert weight >= 0, "item's weight must be >= 0" if weight == 0: # NOTE: if item is weightless, just let it go through # NOTE: this might change in the future return True item = self.bucket_factory.wrap_item(name, weight) if isawaitable(item): return self._handle_async_acquire(item, blocking=blocking) assert isinstance(item, RateItem) bucket = self.bucket_factory.get(item) if isawaitable(bucket): return self._handle_async_bucket(bucket=bucket, item=item, blocking=blocking, _force_async=_force_async) assert isinstance(bucket, AbstractBucket), f"Invalid bucket: item: {name}" result = self.handle_bucket_put(bucket, item, blocking=blocking, _force_async=_force_async) if isawaitable(result): return self._handle_async_result(result) return result def as_decorator(self, *, name="ratelimiter", weight=1): def deco(func: Callable[..., Any]) -> Callable[..., Any]: if iscoroutinefunction(func): @wraps(func) async def wrapper(*args, **kwargs): r = await self.try_acquire_async(name=name, weight=weight) while isawaitable(r): r = await r return await func(*args, **kwargs) return wrapper else: @wraps(func) def wrapper(*args, **kwargs): r = self.try_acquire(name=name, weight=weight) if isawaitable(r): raise RuntimeError("Can't use async bucket with sync decorator") return func(*args, **kwargs) return wrapper return deco def close(self) -> None: self.bucket_factory.close() def __enter__(self): return self def __exit__(self, exc_type, exc, tb) -> None: self.close() vutran1710-PyrateLimiter-634d166/pyrate_limiter/limiter_factory.py000066400000000000000000000100701513463764300252220ustar00rootroot00000000000000""" A collection of common use cases and patterns for pyrate_limiter """ import logging from typing import List, Optional, Union from pyrate_limiter import AbstractBucket, Duration, InMemoryBucket, Limiter, Rate, SQLiteBucket logger = logging.getLogger(__name__) # Global for convenience in multiprocessing, populated by init_mp_limiter. # Intended to be called by a ProcessPoolExecutor's initializer LIMITER: Optional[Limiter] = None def create_sqlite_bucket( rates: List[Rate], db_path: Optional[str], table_name: str = "pyrate_limiter", use_file_lock: bool = False, ): """ Create and initialize a SQLite bucket for rate limiting. Args: rates: List of rate limit configurations. db_path: Path to the SQLite database file (or in-memory if None). table_name: Name of the table to store rate bucket data. use_file_lock: Enable file locking for multi-process synchronization. Returns: SQLiteBucket: Initialized SQLite-backed bucket. """ logger.info("Table name is %s", table_name) bucket = SQLiteBucket.init_from_file( rates, db_path=str(db_path), table=table_name, create_new_table=True, use_file_lock=use_file_lock, ) return bucket def create_sqlite_limiter( rate_per_duration: int = 3, duration: Union[int, Duration] = Duration.SECOND, db_path: Optional[str] = None, table_name: str = "rate_bucket", buffer_ms: int = 50, use_file_lock: bool = False, ) -> Limiter: """ Create a SQLite-backed rate limiter with configurable rate, persistence, and optional async support. Args: rate_per_duration: Number of allowed requests per duration. duration: Time window for the rate limit. db_path: Path to the SQLite database file (or in-memory if None). table_name: Name of the table used for rate buckets. max_delay: Maximum delay before failing requests. buffer_ms: Extra wait time in milliseconds to account for clock drift. use_file_lock: Enable file locking for multi-process synchronization. async_wrapper: Whether to wrap the bucket for async usage. Returns: Limiter: Configured SQLite-backed limiter instance. """ rate = Rate(rate_per_duration, duration) rate_limits = [rate] bucket: AbstractBucket = SQLiteBucket.init_from_file( rate_limits, db_path=str(db_path), table=table_name, create_new_table=True, use_file_lock=use_file_lock, ) limiter = Limiter(bucket, buffer_ms=buffer_ms) return limiter def create_inmemory_limiter( rate_per_duration: int = 3, duration: Union[int, Duration] = Duration.SECOND, buffer_ms: int = 50, ) -> Limiter: """ Create an in-memory rate limiter with configurable rate, duration, delay, and optional async support. Args: rate_per_duration: Number of allowed requests per duration. duration: Time window for the rate limit. max_delay: Maximum delay before failing requests. buffer_ms: Extra wait time in milliseconds to account for clock drift. async_wrapper: Whether to wrap the bucket for async usage. Returns: Limiter: Configured in-memory limiter instance. """ rate = Rate(rate_per_duration, duration) rate_limits = [rate] bucket: AbstractBucket = InMemoryBucket(rate_limits) limiter = Limiter(bucket, buffer_ms=buffer_ms) return limiter def init_global_limiter( bucket: AbstractBucket, buffer_ms: int = 50, ): """ Initialize a global Limiter instance using the provided bucket. Intended for use as an initializer for ProcessPoolExecutor. Args: bucket: The rate-limiting bucket to be used. max_delay: Maximum delay before failing requests. raise_when_fail: Whether to raise an exception when a request fails. retry_until_max_delay: Retry until the maximum delay is reached. buffer_ms: Additional buffer time in milliseconds for retries. """ global LIMITER LIMITER = Limiter(bucket, buffer_ms=buffer_ms) vutran1710-PyrateLimiter-634d166/pyrate_limiter/py.typed000066400000000000000000000000001513463764300231430ustar00rootroot00000000000000vutran1710-PyrateLimiter-634d166/pyrate_limiter/utils.py000066400000000000000000000036101513463764300231700ustar00rootroot00000000000000import sqlite3 import uuid from pathlib import Path from tempfile import gettempdir from typing import List from .abstracts.rate import Rate, RateItem def binary_search(items: List[RateItem], value: int) -> int: """Find the index of item in list where left.timestamp < value <= right.timestamp this is to determine the current size of some window that stretches from now back to lower-boundary = value and """ if not items: return 0 if value > items[-1].timestamp: return -1 if value <= items[0].timestamp: return 0 if len(items) == 2: return 1 left_pointer, right_pointer, mid = 0, len(items) - 1, -2 while left_pointer <= right_pointer: mid = (left_pointer + right_pointer) // 2 left, right = items[mid - 1].timestamp, items[mid].timestamp if left < value <= right: break if left >= value: right_pointer = mid if right < value: left_pointer = mid + 1 return mid def validate_rate_list(rates: List[Rate]) -> bool: """Raise false if rates are incorrectly ordered.""" if not rates: return False for idx, current_rate in enumerate(rates[1:]): prev_rate = rates[idx] if current_rate.interval <= prev_rate.interval: return False if current_rate.limit <= prev_rate.limit: return False if (current_rate.limit / current_rate.interval) > (prev_rate.limit / prev_rate.interval): return False return True def id_generator( size=10, ) -> str: return uuid.uuid4().hex[:size] def dedicated_sqlite_clock_connection(): temp_dir = Path(gettempdir()) default_db_path = temp_dir / "pyrate_limiter_clock_only.sqlite" conn = sqlite3.connect( default_db_path, isolation_level="EXCLUSIVE", check_same_thread=False, ) return conn vutran1710-PyrateLimiter-634d166/setup.cfg000066400000000000000000000004501513463764300202450ustar00rootroot00000000000000[flake8] max-line-length = 120 ignore = E203, E401 # Code Climate still uses the 'pep8' section; renamed to 'pycodestyle' when used locally [pep8] max-line-length = 120 ignore = E203 [pycodestyle] max-line-length = 120 ignore = E203 [tool.pylint] disable = C0330,C0116,R0903,C0115,C0114,R0801 vutran1710-PyrateLimiter-634d166/tests/000077500000000000000000000000001513463764300175675ustar00rootroot00000000000000vutran1710-PyrateLimiter-634d166/tests/__init__.py000066400000000000000000000000001513463764300216660ustar00rootroot00000000000000vutran1710-PyrateLimiter-634d166/tests/conftest.py000066400000000000000000000072341513463764300217740ustar00rootroot00000000000000"""Pytest config & fixtures""" from logging import basicConfig from logging import getLogger from os import getenv from pathlib import Path from tempfile import gettempdir from typing import List from typing import Union import pytest from pyrate_limiter import Duration from pyrate_limiter import id_generator from pyrate_limiter import InMemoryBucket from pyrate_limiter import limiter_factory from pyrate_limiter import MultiprocessBucket from pyrate_limiter import PostgresBucket from pyrate_limiter import Rate from pyrate_limiter import RedisBucket # Make log messages visible on test failure (or with pytest -s) basicConfig(level="INFO") # Uncomment for more verbose output: logger = getLogger("pyrate_limiter") logger.setLevel(getenv("LOG_LEVEL", "INFO")) DEFAULT_RATES = [Rate(3, 1000), Rate(4, 1500)] async def create_in_memory_bucket(rates: List[Rate]): return InMemoryBucket(rates) async def create_redis_bucket(rates: List[Rate]): from redis import ConnectionPool from redis import Redis pool = ConnectionPool.from_url(getenv("REDIS", "redis://localhost:6379")) redis_db = Redis(connection_pool=pool) bucket_key = f"test-bucket/{id_generator()}" redis_db.delete(bucket_key) bucket = RedisBucket.init(rates, redis_db, bucket_key) assert bucket.count() == 0 return bucket async def create_async_redis_bucket(rates: List[Rate]): from redis.asyncio import ConnectionPool as AsyncConnectionPool from redis.asyncio import Redis as AsyncRedis pool: AsyncConnectionPool = AsyncConnectionPool.from_url( getenv("REDIS", "redis://localhost:6379") ) redis_db: AsyncRedis = AsyncRedis(connection_pool=pool) bucket_key = f"test-bucket/{id_generator()}" await redis_db.delete(bucket_key) bucket = await RedisBucket.init(rates, redis_db, bucket_key) assert await bucket.count() == 0 return bucket async def create_mp_bucket(rates: List[Rate]): bucket = MultiprocessBucket.init(rates) return bucket async def create_sqlite_bucket(rates: List[Rate], file_lock: bool = False): temp_dir = Path(gettempdir()) default_db_path = temp_dir / f"pyrate_limiter_{id_generator(size=5)}.sqlite" table_name = f"pyrate-test-bucket-{id_generator(size=10)}" logger.info("SQLite db path: %s", default_db_path) return limiter_factory.create_sqlite_bucket(rates=rates, db_path=str(default_db_path), table_name=table_name, use_file_lock=file_lock) async def create_filelocksqlite_bucket(rates: List[Rate]): return await create_sqlite_bucket(rates=rates, file_lock=True) async def create_postgres_bucket(rates: List[Rate]): from psycopg_pool import ConnectionPool as PgConnectionPool pool = PgConnectionPool("postgresql://postgres:postgres@localhost:5432", open=True) table = f"test_bucket_{id_generator()}" bucket = PostgresBucket(pool, table, rates) assert bucket.count() == 0 return bucket @pytest.fixture( params=[ pytest.param(create_in_memory_bucket, marks=pytest.mark.inmemory), pytest.param(create_redis_bucket, marks=pytest.mark.redis), pytest.param(create_async_redis_bucket, marks=pytest.mark.asyncredis), pytest.param(create_sqlite_bucket, marks=pytest.mark.sqlite), pytest.param(create_postgres_bucket, marks=pytest.mark.postgres), pytest.param(create_filelocksqlite_bucket, marks=pytest.mark.filelocksqlite), pytest.param(create_mp_bucket, marks=pytest.mark.mpbucket) ] ) def create_bucket(request): """Parametrization for different bucket.""" return request.param vutran1710-PyrateLimiter-634d166/tests/demo_bucket_factory.py000066400000000000000000000075561513463764300241660ustar00rootroot00000000000000from inspect import isawaitable from os import getenv from typing import Dict from typing import Optional from typing import Iterable from redis.asyncio import ConnectionPool as AsyncConnectionPool from redis.asyncio import Redis as AsyncRedis from .conftest import DEFAULT_RATES from .helpers import flushing_bucket from pyrate_limiter import AbstractBucket from pyrate_limiter import AbstractClock from pyrate_limiter import BucketFactory from pyrate_limiter import id_generator from pyrate_limiter import InMemoryBucket from pyrate_limiter import RateItem from pyrate_limiter import RedisBucket class DemoBucketFactory(BucketFactory): """Multi-bucket factory used for testing schedule-leaks""" buckets: Optional[Dict[str, AbstractBucket]] = None auto_leak: bool def __init__(self, auto_leak=False, **buckets: AbstractBucket): self.auto_leak = auto_leak self.buckets = {} self.leak_interval = 300 for item_name_pattern, bucket in buckets.items(): assert isinstance(bucket, AbstractBucket) self.schedule_leak(bucket) self.buckets[item_name_pattern] = bucket def wrap_item(self, name: str, weight: int = 1): assert self.buckets is not None and len(self.buckets) > 0 bucket = self.get(RateItem(name=name, timestamp=0, weight=weight)) now = bucket.now() async def wrap_async(): return RateItem(name, await now, weight=weight) def wrap_sync(): return RateItem(name, now, weight=weight) return wrap_async() if isawaitable(now) else wrap_sync() def get(self, item: RateItem) -> AbstractBucket: assert self.buckets is not None if item.name in self.buckets: bucket = self.buckets[item.name] assert isinstance(bucket, AbstractBucket) return bucket bucket = self.create(InMemoryBucket, DEFAULT_RATES) self.buckets[item.name] = bucket return bucket def schedule_leak(self, *args): if self.auto_leak: super().schedule_leak(*args) class DemoAsyncGetBucketFactory(BucketFactory): """Async multi-bucket factory used for testing schedule-leaks""" buckets: dict[str, AbstractBucket] def __init__(self, auto_leak=False, **buckets: AbstractBucket): self.auto_leak = auto_leak self.buckets = {"test": InMemoryBucket(DEFAULT_RATES)} self.leak_interval = 300 for item_name_pattern, bucket in buckets.items(): assert isinstance(bucket, AbstractBucket) self.schedule_leak(bucket) self.buckets[item_name_pattern] = bucket def wrap_item(self, name: str, weight: int = 1): now = next((b for b in self.buckets.values())).now() async def wrap_async(): return RateItem(name, await now, weight=weight) def wrap_sync(): return RateItem(name, now, weight=weight) return wrap_async() if isawaitable(now) else wrap_sync() async def get(self, item: RateItem) -> AbstractBucket: assert self.buckets is not None if item.name in self.buckets: bucket = self.buckets[item.name] assert isinstance(bucket, AbstractBucket) return bucket pool: AsyncConnectionPool = AsyncConnectionPool.from_url(getenv("REDIS", "redis://localhost:6379")) redis_db: AsyncRedis = AsyncRedis(connection_pool=pool) key = f"test-bucket/{id_generator()}" await redis_db.delete(key) bucket = await RedisBucket.init(DEFAULT_RATES, redis_db, key) self.schedule_leak(bucket) self.buckets.update({item.name: bucket}) return bucket def schedule_leak(self, *args): if self.auto_leak: super().schedule_leak(*args) async def flush(self): for bucket in self.buckets.values(): await flushing_bucket(bucket) vutran1710-PyrateLimiter-634d166/tests/helpers.py000066400000000000000000000056161513463764300216130ustar00rootroot00000000000000"""Duh.... """ from asyncio import sleep from concurrent.futures import ThreadPoolExecutor from inspect import isawaitable from time import time from typing import List from typing import Tuple from .conftest import logger from pyrate_limiter import AbstractBucket from pyrate_limiter import Limiter from pyrate_limiter import RateItem async def inspect_bucket_items(bucket: AbstractBucket, expected_item_count: int): """Inspect items in the bucket - Assert number of item == expected-item-count - Assert that items are ordered by timestamps, from latest to earliest """ collected_items = [] for idx in range(expected_item_count): item = bucket.peek(idx) if isawaitable(item): item = await item assert isinstance(item, RateItem) collected_items.append(item) item_names = [item.name for item in collected_items] for i in range(1, expected_item_count): item = collected_items[i] prev_item = collected_items[i - 1] assert item.timestamp <= prev_item.timestamp return item_names async def concurrent_acquire(limiter: Limiter, items: List[str], blocking: bool = True): with ThreadPoolExecutor() as executor: result = list(executor.map(limiter.try_acquire, items)) for idx, coro in enumerate(result): while isawaitable(coro): coro = await coro result[idx] = coro return result async def async_acquire(limiter: Limiter, item: str, weight: int = 1, blocking: bool = True) -> Tuple[bool, int]: start = time() acquire = await limiter.try_acquire_async(item, weight=weight, blocking = blocking) time_cost_in_ms = int((time() - start) * 1000) assert isinstance(acquire, bool) return acquire, time_cost_in_ms async def async_count(bucket: AbstractBucket) -> int: count = bucket.count() if isawaitable(count): count = await count assert isinstance(count, int) return count async def prefilling_bucket(limiter: Limiter, sleep_interval: float, item: str): """Pre-filling bucket to the limit before testing the time cost might vary depending on the bucket's backend - For in-memory bucket, this should be less than a 1ms - For external bucket's source ie Redis, this mostly depends on the network latency """ acquire_ok, cost = await async_acquire(limiter, item) logger.info("cost = %s", cost) assert cost <= 50 assert acquire_ok await sleep(sleep_interval) acquire_ok, cost = await async_acquire(limiter, item) logger.info("cost = %s", cost) assert cost <= 50 assert acquire_ok await sleep(sleep_interval) acquire_ok, cost = await async_acquire(limiter, item) logger.info("cost = %s", cost) assert cost <= 50 assert acquire_ok async def flushing_bucket(bucket: AbstractBucket): flush = bucket.flush() if isawaitable(flush): await flush vutran1710-PyrateLimiter-634d166/tests/test_blocking_timeouts.py000066400000000000000000000047251513463764300247310ustar00rootroot00000000000000# tests/test_limiter_blocking_behavior.py import asyncio import time import pytest from pyrate_limiter import Rate from pyrate_limiter.buckets import InMemoryBucket from pyrate_limiter.limiter import Limiter RATE = Rate(1, 200) # 1 token per 200ms def make_limiter(): return Limiter(InMemoryBucket([RATE]), buffer_ms=0) # --- sync decorator blocks --- def test_sync_decorator_blocks(): lim = make_limiter() @lim.as_decorator() def work(): return time.perf_counter() t0 = time.perf_counter() work() # consumes the only slot t1 = work() # must block ~200ms waiting for leak elapsed = t1 - t0 assert elapsed >= 0.18 # --- async decorator blocks --- @pytest.mark.asyncio async def test_async_decorator_blocks(): lim = make_limiter() @lim.as_decorator() async def work(): return time.perf_counter() t0 = time.perf_counter() await work() # consumes the only slot t1 = await work() # must block ~200ms elapsed = t1 - t0 assert elapsed >= 0.18 # --- try_acquire: non-blocking fails on contention --- def test_try_acquire_nonblocking_false(): lim = make_limiter() assert lim.try_acquire("k", blocking=False) is True assert lim.try_acquire("k", blocking=False) is False # immediate refusal # --- try_acquire_async: non-blocking fails on contention --- @pytest.mark.asyncio async def test_try_acquire_async_nonblocking_false(): lim = make_limiter() # ensure clean slate for b in lim.buckets(): f = b.flush() if asyncio.iscoroutine(f): await f assert await lim.try_acquire_async("k_async_nb", blocking=False) is True assert await lim.try_acquire_async("k_async_nb", blocking=False) is False # --- try_acquire_async with timeout enforces max wait --- @pytest.mark.asyncio async def test_try_acquire_async_timeout(): lim = make_limiter() assert await lim.try_acquire_async("k", blocking=True) is True # take the only slot t0 = time.perf_counter() ok = await lim.try_acquire_async("k", blocking=True, timeout=0.1) t1 = time.perf_counter() assert ok is False # timed out assert 0.09 <= (t1 - t0) <= 0.25 # waited ~timeout, not full 200ms # --- sync timeout is not implemented --- def test_try_acquire_sync_timeout_not_implemented(): lim = make_limiter() with pytest.raises(NotImplementedError): lim.try_acquire("k", blocking=True, timeout=0.1) vutran1710-PyrateLimiter-634d166/tests/test_bucket_all.py000066400000000000000000000164111513463764300233100ustar00rootroot00000000000000""" Testing buckets of all implementations """ import asyncio from inspect import isawaitable from time import time import pytest from .conftest import logger from pyrate_limiter import AbstractClock from pyrate_limiter import BucketAsyncWrapper from pyrate_limiter import Rate from pyrate_limiter import RateItem from pyrate_limiter import MonotonicClock async def get_now(clock: AbstractClock) -> int: """Util function to get time now""" now = clock.now() if isawaitable(now): now = await now assert isinstance(now, int) return now @pytest.mark.asyncio async def test_bucket_01(create_bucket): rates = [Rate(20, 1000)] bucket = BucketAsyncWrapper(await create_bucket(rates)) assert bucket is not None peek = await bucket.peek(0) assert peek is None await bucket.put(RateItem("my-item", bucket.now())) assert await bucket.count() == 1 await bucket.put(RateItem("my-item", bucket.now(), weight=10)) assert await bucket.count() == 11 assert await bucket.put(RateItem("my-item", bucket.now(), weight=20)) is False assert bucket.failing_rate == rates[0] assert await bucket.put(RateItem("my-item", bucket.now(), weight=9)) is True assert await bucket.count() == 20 assert await bucket.put(RateItem("my-item", bucket.now())) is False await asyncio.sleep(2) assert await bucket.put(RateItem("my-item", bucket.now())) is True await asyncio.sleep(2) assert await bucket.put(RateItem("my-item", bucket.now(), weight=30)) is False @pytest.mark.asyncio async def test_bucket_02(create_bucket): rates = [Rate(30, 1000), Rate(50, 2000)] bucket = BucketAsyncWrapper(await create_bucket(rates)) start = time() while await bucket.count() < 150: await bucket.put(RateItem("item", bucket.now())) if await bucket.count() == 31: cost = time() - start logger.info(">30 items: %s", cost) assert cost > 0.99 if await bucket.count() == 51: cost = time() - start logger.info(">50 items: %s", cost) assert cost > 2 if await bucket.count() == 81: cost = time() - start logger.info(">80 items: %s", cost) assert cost > 3 if await bucket.count() == 101: cost = time() - start logger.info(">100 items: %s", cost) assert cost > 4 @pytest.mark.asyncio async def test_bucket_03(create_bucket): rates = [Rate(30, 1000), Rate(50, 2000)] bucket = BucketAsyncWrapper(await create_bucket(rates)) peek = await bucket.peek(0) await bucket.flush() assert peek is None await bucket.put(RateItem("item1", bucket.now())) peek = await bucket.peek(0) assert isinstance(peek, RateItem) assert "item1" in peek.name await bucket.put(RateItem("item2", bucket.now())) peek = await bucket.peek(0) assert isinstance(peek, RateItem) assert "item2" in peek.name peek = await bucket.peek(1) assert isinstance(peek, RateItem) assert "item1" in peek.name await bucket.put(RateItem("item3", bucket.now())) peek = await bucket.peek(0) assert isinstance(peek, RateItem) assert "item3" in peek.name peek = await bucket.peek(1) assert isinstance(peek, RateItem) assert "item2" in peek.name peek = await bucket.peek(2) assert isinstance(peek, RateItem) assert "item1" in peek.name peek = await bucket.peek(3) assert peek is None @pytest.mark.asyncio async def test_bucket_waiting(create_bucket): rates = [Rate(3, 500)] bucket = await create_bucket(rates) logger.info("Testing `bucket.waiting` with Bucket: %s", bucket) bucket = BucketAsyncWrapper(bucket) async def create_item(weight: int = 1) -> RateItem: now = bucket.now() if isawaitable(now): now = await now assert isinstance(now, int) return RateItem("item", now, weight) start = bucket.now() assert start > 0 assert await bucket.waiting(await create_item()) == 0 for _ in range(3): assert await bucket.put(await create_item()) is True # NOTE: sleep 100ms between each item await asyncio.sleep(0.1) end = bucket.now() assert end > 0 elapsed = end - start assert elapsed > 0 logger.info("Elapsed: %s", elapsed) assert await bucket.put(await create_item()) is False availability = await bucket.waiting(await create_item()) # type: ignore assert isinstance(availability, int) logger.info("1 space available in: %s", availability) await asyncio.sleep(availability / 1000 - 0.03) assert await bucket.put(await create_item()) is False await asyncio.sleep(0.04) assert await bucket.put(await create_item()) is True assert await bucket.put(await create_item(2)) is False availability = await bucket.waiting(await create_item(2)) # type: ignore assert isinstance(availability, int) logger.info("2 space available in: %s", availability) await asyncio.sleep(availability / 1000 - 0.03) assert await bucket.put(await create_item(2)) is False await asyncio.sleep(0.04) assert await bucket.put(await create_item(2)) is True assert await bucket.put(await create_item(3)) is False availability = await bucket.waiting(await create_item(3)) # type: ignore assert isinstance(availability, int) logger.info("3 space available in: %s", availability) await asyncio.sleep(availability / 1000 - 0.03) assert await bucket.put(await create_item(3)) is False await asyncio.sleep(0.04) assert await bucket.put(await create_item(3)) is True @pytest.mark.asyncio async def test_bucket_leak(create_bucket): rates = [Rate(100, 3000)] bucket = BucketAsyncWrapper(await create_bucket(rates)) while await bucket.count() < 200: await bucket.put(RateItem("item", bucket.now())) await bucket.leak(bucket.now()) assert await bucket.count() == 100 assert await bucket.leak(bucket.now()) == 0 assert await bucket.count() == 100 await asyncio.sleep(3.01) assert await bucket.leak(bucket.now()) == 100 assert await bucket.leak(bucket.now()) == 0 assert await bucket.count() == 0 @pytest.mark.asyncio async def test_bucket_flush(create_bucket): """Testing bucket's flush, only need 1 single clock type""" rates = [Rate(50, 1000)] bucket = BucketAsyncWrapper(await create_bucket(rates)) assert isinstance(bucket.rates[0], Rate) while await bucket.put(RateItem("item", bucket.now())): pass assert await bucket.count() == 50 assert bucket.failing_rate is not None await bucket.flush() assert await bucket.count() == 0 assert bucket.failing_rate is None @pytest.mark.asyncio async def test_bucket_performance(create_bucket): """Bucket's performance test Putting a very large number of item into bucket Only need to test with a single clock type """ rates = [Rate(30000, 50000)] bucket = BucketAsyncWrapper(await create_bucket(rates)) before = time() for _ in range(10_000): item = RateItem("item", bucket.now()) assert await bucket.put(item) is True after = time() elapsed = after - before assert await bucket.count() == 10_000 logger.info("Bucket: %s \nPerformance test: insert 10k items %s(secs)", bucket.bucket, elapsed) vutran1710-PyrateLimiter-634d166/tests/test_bucket_factory.py000066400000000000000000000044711513463764300242120ustar00rootroot00000000000000"""Complete Limiter test suite """ import asyncio from inspect import isawaitable from time import sleep import pytest from .conftest import DEFAULT_RATES from .conftest import logger from .demo_bucket_factory import DemoBucketFactory from .helpers import async_count from pyrate_limiter import AbstractBucket from pyrate_limiter import RateItem from pyrate_limiter import BucketAsyncWrapper @pytest.mark.asyncio async def test_factory_01(create_bucket): factory = DemoBucketFactory( hello=await create_bucket(DEFAULT_RATES), ) item = factory.wrap_item("hello", 1) if isawaitable(item): item = await item assert isinstance(item, RateItem) assert item.weight == 1 bucket = factory.get(item) assert isinstance(bucket, AbstractBucket) @pytest.mark.asyncio async def test_factory_leak(create_bucket): bucket1 = await create_bucket([DEFAULT_RATES[0]]) bucket2 = await create_bucket([DEFAULT_RATES[1]]) assert id(bucket1) != id(bucket2) factory = DemoBucketFactory(auto_leak=True, b1=bucket1, b2=bucket2) assert len(factory.buckets) == 2 logger.info("Factory initiated with %s buckets", len(factory.buckets)) for item_name in ["b1", "b2", "a1"]: for _ in range(3): is_async = False item = factory.wrap_item(item_name) if isawaitable(item): is_async = True item = await item bucket = factory.get(item) put_ok = bucket.put(item) if isawaitable(put_ok): is_async = True put_ok = await put_ok assert put_ok sleep(0.1) if item_name == "b1": assert await async_count(bucket1) == 3 if item_name == "b2": assert await async_count(bucket2) == 3 if item_name == "a1": assert await async_count(factory.buckets[item_name]) == 3 await asyncio.sleep(2) assert await async_count(bucket1) == 0 assert await async_count(bucket2) == 0 assert await async_count(factory.buckets[item_name]) == 0 assert len(factory.buckets) == 3 for bucket in factory.get_buckets(): factory.dispose(bucket) sleep(1) assert factory._leaker.is_alive() is False assert factory._leaker.aio_leak_task is None vutran1710-PyrateLimiter-634d166/tests/test_closing.py000066400000000000000000000012411513463764300226340ustar00rootroot00000000000000import pytest from .conftest import DEFAULT_RATES from pyrate_limiter import Limiter @pytest.mark.asyncio async def test_multiple_bucket_closes( create_bucket, ): # Makes sure no exceptions even if close is called multiple times with await create_bucket(DEFAULT_RATES) as bucket: bucket.close() bucket.close() @pytest.mark.asyncio async def test_multiple_bucket_closes_limiter( create_bucket, ): # Makes sure no exceptions even if close is called multiple times with await create_bucket(DEFAULT_RATES) as bucket: with Limiter(bucket) as limiter: limiter.close() bucket.close() bucket.close() vutran1710-PyrateLimiter-634d166/tests/test_combinedlock.py000066400000000000000000000055711513463764300236410ustar00rootroot00000000000000import logging import re from inspect import isawaitable from time import time import pytest from pyrate_limiter import binary_search from pyrate_limiter import Duration from pyrate_limiter import Rate from pyrate_limiter import RateItem from pyrate_limiter import SQLiteClock from pyrate_limiter import MonotonicClock from pyrate_limiter import AbstractClock from pyrate_limiter import validate_rate_list from pyrate_limiter.limiter import combined_lock from multiprocessing import Lock from threading import RLock def test_combined_lock_blocking_ok(): m, r = Lock(), RLock() with combined_lock([m, r], blocking=True): assert m.acquire(False) is False assert m.acquire(False) is True m.release() def test_combined_lock_nonblocking_fails_if_mp_locked(): m, r = Lock(), RLock() m.acquire() try: with pytest.raises(TimeoutError): with combined_lock([m, r], blocking=False): pass finally: m.release() def test_combined_lock_timeout_when_mp_locked(): m, r = Lock(), RLock() m.acquire() try: with pytest.raises(TimeoutError): with combined_lock([m, r], blocking=True, timeout=0.05): pass finally: m.release() def test_zero_timeout_behaves_nonblocking(): m, r = Lock(), RLock() m.acquire() try: with pytest.raises(TimeoutError): with combined_lock([m, r], True, timeout=0): pass finally: m.release() def test_partial_acquire_rolls_back_on_failure(): m1, m2 = Lock(), Lock() m2.acquire() try: with pytest.raises(TimeoutError): with combined_lock([m1, m2], False): pass assert m1.acquire(False) is True # released after failure m1.release() finally: m2.release() def test_exception_inside_context_releases_all(): m, r = Lock(), RLock() with pytest.raises(RuntimeError): with combined_lock([m, r], True): raise RuntimeError assert m.acquire(False) is True; m.release() def test_reentrant_rlock_ok(): r = RLock() with r: with combined_lock([r], True): assert True def test_single_lock_works(): m = Lock() with combined_lock([m], True): assert True assert m.acquire(False) is True; m.release() def test_float_timeout(): m, r = Lock(), RLock() m.acquire() try: with pytest.raises(TimeoutError): with combined_lock([m, r], True, timeout=0.05): pass finally: m.release() def test_nonblocking_when_uncontended(): m, r = Lock(), RLock() with combined_lock([m, r], False): assert True assert m.acquire(False) is True; m.release() def test_order_doesnt_deadlock_when_second_is_locked(): m1, m2 = Lock(), Lock() m2.acquire() try: with pytest.raises(TimeoutError): with combined_lock([m1, m2], True, timeout=0.01): pass finally: m2.release()vutran1710-PyrateLimiter-634d166/tests/test_limiter.py000066400000000000000000000177711513463764300226620ustar00rootroot00000000000000"""Complete Limiter test suite """ import asyncio import time from inspect import isawaitable import pytest import sys from .conftest import DEFAULT_RATES from .conftest import logger from .demo_bucket_factory import DemoAsyncGetBucketFactory from .demo_bucket_factory import DemoBucketFactory from .helpers import async_acquire from .helpers import concurrent_acquire from .helpers import flushing_bucket from .helpers import inspect_bucket_items from .helpers import prefilling_bucket from pyrate_limiter import AbstractBucket from pyrate_limiter import BucketAsyncWrapper from pyrate_limiter import BucketFactory from pyrate_limiter import Duration from pyrate_limiter import InMemoryBucket from pyrate_limiter import Limiter from pyrate_limiter import RedisBucket from pyrate_limiter import Rate from pyrate_limiter import SingleBucketFactory buffer_ms = 10 # Compute a windows specific jitter, due to clock timing # on GHA's Windows runners jitter_adjustment = 0 if sys.platform == "win32": jitter_adjustment = 50 @pytest.mark.asyncio async def test_limiter_constructor_01(): limiter = Limiter(DEFAULT_RATES[0]) assert isinstance(limiter.bucket_factory, BucketFactory) assert isinstance(limiter.bucket_factory.bucket, InMemoryBucket) assert limiter.bucket_factory.bucket.rates == [DEFAULT_RATES[0]] limiter = Limiter(DEFAULT_RATES) assert isinstance(limiter.bucket_factory, BucketFactory) assert isinstance(limiter.bucket_factory.bucket, InMemoryBucket) assert limiter.bucket_factory.bucket.rates == DEFAULT_RATES assert len(limiter.buckets()) == 1 @pytest.mark.asyncio async def test_limiter_constructor_02( create_bucket, ): bucket = await create_bucket(DEFAULT_RATES) limiter = Limiter(bucket) assert isinstance(limiter.bucket_factory, SingleBucketFactory) limiter = Limiter( bucket ) assert isinstance(limiter.bucket_factory, BucketFactory) acquire_ok = limiter.try_acquire("example") if isawaitable(acquire_ok): acquire_ok = await acquire_ok assert acquire_ok factory = DemoBucketFactory(demo=bucket) limiter = Limiter( factory, ) assert limiter.bucket_factory is factory @pytest.mark.asyncio async def test_limiter_01( request, create_bucket, ): if request.node.get_closest_marker("mpbucket"): pytest.skip("Skipped mpbucket test due to erratic performance timing compared to more deterministic buckets") bucket = await create_bucket(DEFAULT_RATES) factory = DemoBucketFactory(demo=bucket) limiter = Limiter( factory, buffer_ms=10 ) bucket = BucketAsyncWrapper(bucket) await bucket.flush() item = "demo" logger.info("If weight = 0, it just passes thru") acquire_ok, cost = await async_acquire(limiter, item, weight=0) assert acquire_ok assert cost <= (10+jitter_adjustment) assert await bucket.count() == 0 logger.info("Limiter Test #1") await prefilling_bucket(limiter, 0.3, item) acquired, cost = await async_acquire(limiter, item, weight=0, blocking=False) assert acquired acquired, cost = await async_acquire(limiter, item, blocking=False) assert not acquired acquired, cost = await async_acquire(limiter, item, blocking=False) assert not acquired @pytest.mark.asyncredis @pytest.mark.asyncio async def test_limiter_async_factory_get_weight0( ): factory = DemoAsyncGetBucketFactory() limiter = Limiter( factory, buffer_ms=5 ) item = "demo" logger.info("If weight = 0, it just passes thru") acquire_ok, cost = await async_acquire(limiter, item, blocking=True, weight=0) assert acquire_ok assert cost <= 10 await prefilling_bucket(limiter, 0.3, item) # Not blocking blocking, if weight is 0 then it's nearly instant acquire_ok, cost = await async_acquire(limiter, item, blocking=True, weight=0) assert acquire_ok assert cost <= 10 # Even if blocking, if weight is 0 then it's nearly instant acquire_ok, cost = await async_acquire(limiter, item, blocking=True, weight=0) assert acquire_ok assert cost <= 10 @pytest.mark.asyncredis @pytest.mark.asyncio async def test_limiter_async_factory_get( ): factory = DemoAsyncGetBucketFactory() limiter = Limiter( factory, buffer_ms=5 ) item = "demo" await prefilling_bucket(limiter, 0.3, item) # A non-blocking request should return immediately and fail acquire_ok, cost = await async_acquire(limiter, item, blocking=False) assert not acquire_ok assert cost <= 50 # A blocking request should wait about 600+ ms acquire_ok, cost = await async_acquire(limiter, item, blocking=True) assert acquire_ok assert 300 <= cost <= 900 # Same as above acquire_ok, cost = await async_acquire(limiter, item) assert acquire_ok assert 300 <= cost <= 900 # # Flush before testing again await factory.flush() logger.info("Limiter Test #2") await prefilling_bucket(limiter, 0, item) # A non-blocking request should return immediately and fail acquire_ok, cost = await async_acquire(limiter, item, blocking=False) assert not acquire_ok assert cost <= 50 # A blocking request should wait about 600+ ms acquire_ok, cost = await async_acquire(limiter, item, blocking=True) assert acquire_ok assert 300 <= cost <= 1200 @pytest.mark.asyncio async def test_limiter_concurrency( create_bucket, ): bucket = await create_bucket(DEFAULT_RATES) factory = DemoBucketFactory(demo=bucket) limiter = Limiter( factory, ) logger.info("Test Limiter Concurrency: inserting 4 items") items = ["demo" for _ in range(4)] result = await concurrent_acquire(limiter, items) item_names = await inspect_bucket_items(bucket, 3) result = await concurrent_acquire(limiter, items) item_names = await inspect_bucket_items(bucket, 3) logger.info( "(No raise, delay is None or delay > max_delay) Result = %s, Item = %s", result, item_names, ) @pytest.mark.asyncio async def test_limiter_decorator( create_bucket, ): bucket = await create_bucket(DEFAULT_RATES) factory = DemoBucketFactory(demo=bucket) limiter = Limiter( factory, ) limiter_wrapper = limiter.as_decorator(name="demo", weight=1) counter = 0 @limiter_wrapper async def async_inc_counter(num: int): nonlocal counter counter += num if isawaitable(bucket.count()): with pytest.raises(RuntimeError): @limiter_wrapper def inc_counter(num: int): nonlocal counter counter += num inc = inc_counter(1) else: @limiter_wrapper def inc_counter(num: int): nonlocal counter counter += num inc = inc_counter(1) if isawaitable(inc): await inc assert counter == 1 await async_inc_counter(1) assert counter == 2 async def test_wait_too_long(): requests_per_second = 10 rate = Rate(requests_per_second, Duration.SECOND) bucket = InMemoryBucket([rate]) limiter = Limiter(bucket) for i in range(500): success = limiter.try_acquire("mytest", weight=1, blocking=False) if not success: break assert not success # retried and then failed time.sleep(1) # raise_when_fail = True limiter = Limiter(bucket) tasks = [limiter.try_acquire_async("mytest", 1, timeout=0.0001) for i in range(500)] r = await asyncio.gather(*tasks) # Not all requests could be satisfied within the timeout assert not all(r) async def test_bucket_no_schedule_leak(): rates = [Rate(100, 1000)] bucket = InMemoryBucket(rates) bucket_factory = SingleBucketFactory(bucket, schedule_leak=False) limiter = Limiter(bucket_factory) acquired = limiter.try_acquire("test", 1) acquired = limiter.try_acquire("test", 1) assert acquired await asyncio.sleep(1.2) assert bucket.count() == 2 vutran1710-PyrateLimiter-634d166/tests/test_multi_bucket.py000066400000000000000000000013531513463764300236710ustar00rootroot00000000000000import logging import time import pytest from pyrate_limiter import Limiter, Rate logging.basicConfig(level=logging.INFO) @pytest.mark.asyncio async def test_delay_waiter_blocks_until_slot_available(create_bucket): bucket = await create_bucket(rates=[Rate(1, 1000), Rate(3, 5000)]) # 1 per sec, 3 per 5s limiter = Limiter(bucket) t0 = time.time() assert await limiter.try_acquire_async("x") # 1st ok assert await limiter.try_acquire_async("x") # 2nd ok assert await limiter.try_acquire_async("x") # 3rd ok start = time.time() ok = await limiter.try_acquire_async("x") elapsed = time.time() - start assert ok assert elapsed >= 2, f"returned too early, elapsed={elapsed:.2f}s" vutran1710-PyrateLimiter-634d166/tests/test_multiprocessing.py000066400000000000000000000170631513463764300244360ustar00rootroot00000000000000"""Rate limiter multiprocessing tests""" import asyncio import time from collections import deque from concurrent.futures import ProcessPoolExecutor from concurrent.futures import wait from pathlib import Path from tempfile import gettempdir from typing import List from typing import Optional import pytest from pyrate_limiter import AbstractBucket from pyrate_limiter import Duration from pyrate_limiter import Limiter from pyrate_limiter import Rate from pyrate_limiter import SQLiteBucket from pyrate_limiter import SQLiteClock from pyrate_limiter.buckets.mp_bucket import MultiprocessBucket from pyrate_limiter import limiter_factory import logging logger = logging.getLogger(__name__) BUCKET: Optional[AbstractBucket] = None def my_task(): assert limiter_factory.LIMITER is not None acquired = limiter_factory.LIMITER.try_acquire("my_task") result = time.time() time.sleep(0.01) assert acquired return result def analyze_times(start: float, requests_per_second: int, times: List[float]): elapsed = sorted(t - start for t in times) w: deque[float] = deque() ops_last_sec: List[int] = [] for t in elapsed: w.append(t) while w and w[0] <= t - 1: w.popleft() ops_last_sec.append(len(w)) print(f"{max(ops_last_sec)=}, {requests_per_second=}") assert ( max(ops_last_sec) <= requests_per_second * 1.05 ) # a small amount of error is observed when multiprocessing def init_process_sqlite(requests_per_second, db_path): rate = Rate(requests_per_second, Duration.SECOND) bucket = SQLiteBucket.init_from_file([rate], db_path=db_path, use_file_lock=True) bucket._clock = SQLiteClock(bucket) limiter_factory.LIMITER = Limiter( bucket ) def my_task_async(num_requests): async def task_async(limiter: Limiter, name="mytask", weight=1): await limiter.try_acquire_async(name, weight) return time.monotonic() async def run_many_async_tasks(): return await asyncio.gather( *(task_async(limiter_factory.LIMITER, str(i), 1) for i in range(num_requests)) ) return asyncio.run(run_many_async_tasks()) def test_mp_bucket(): requests_per_second = 250 num_seconds = 5 num_requests = requests_per_second * num_seconds rate = Rate(requests_per_second, Duration.SECOND) bucket = MultiprocessBucket.init([rate]) def prime_bucket(): # Prime the bucket limiter = Limiter(bucket) [limiter.try_acquire("mytest") for i in range(requests_per_second)] start = time.time() with ProcessPoolExecutor( initializer=limiter_factory.init_global_limiter, initargs=(bucket,) ) as executor: prime_bucket() futures = [executor.submit(my_task) for _ in range(num_requests)] wait(futures) times = [] for f in futures: try: t = f.result() times.append(t) except Exception as e: raise e analyze_times(start, requests_per_second, times) def test_sqlite_filelock_bucket(): requests_per_second = 250 num_seconds = 5 num_requests = requests_per_second * num_seconds # Initialize the table temp_dir = Path(gettempdir()) db_path = str(temp_dir / f"pyrate_limiter_{time.time()}.sqlite") # prime the bucket def prime_bucket(): rate = Rate(requests_per_second, Duration.SECOND) with SQLiteBucket.init_from_file( [rate], db_path=db_path, use_file_lock=True ) as bucket: bucket._clock = SQLiteClock(bucket) limiter = Limiter( bucket, ) [limiter.try_acquire("mytest") for i in range(requests_per_second)] # Start the ProcessPoolExecutor start = time.time() with ProcessPoolExecutor(initializer=init_process_sqlite, initargs=(requests_per_second, db_path)) as executor: prime_bucket() futures = [executor.submit(my_task) for _ in range(num_requests)] wait(futures) times = [] for f in futures: try: t = f.result() times.append(t) except Exception as e: raise e analyze_times(start, requests_per_second, times) @pytest.mark.asyncio async def test_mp_bucket_async(): requests_per_second = 250 num_seconds = 5 num_requests = requests_per_second * num_seconds rate = Rate(requests_per_second, Duration.SECOND) bucket = MultiprocessBucket.init([rate]) async def prime_bucket(): # prime the bucket limiter = Limiter( bucket, ) for i in range(100): await limiter.try_acquire_async("mytest") start = time.time() with ProcessPoolExecutor( initializer=limiter_factory.init_global_limiter, initargs=(bucket,) ) as executor: # make sure requests is divisible by num workers num_workers = executor._max_workers num_requests = num_workers * (num_requests // num_workers) wait([executor.submit(my_task_async, 250)]) futures = [ executor.submit(my_task_async, num_requests // num_workers) for _ in range(num_workers) ] wait(futures) await asyncio.sleep(2) futures = [ executor.submit(my_task_async, num_requests // num_workers) for _ in range(num_workers) ] wait(futures) times = [] for f in futures: try: t = f.result() times += t except Exception as e: raise e analyze_times(start, requests_per_second, times) def test_mp_bucket_failures(): requests_per_second = 1 num_seconds = 5 num_requests = requests_per_second * num_seconds rate = Rate(requests_per_second, Duration.SECOND) bucket = MultiprocessBucket.init([rate]) with ProcessPoolExecutor( initializer=limiter_factory.init_global_limiter, initargs=(bucket,) ) as executor: futures = [executor.submit(my_task) for _ in range(num_requests)] wait(futures) for f in futures: try: f.result() except Exception as e: raise e def test_limiter_delay(): requests_per_second = 1 num_seconds = 5 num_requests = requests_per_second * num_seconds rate = Rate(requests_per_second, Duration.SECOND) bucket = MultiprocessBucket.init([rate]) limiter = Limiter( bucket ) for _ in range(1000): last_success = limiter.try_acquire("mytest", 1, blocking=False) assert not last_success with ProcessPoolExecutor( initializer=limiter_factory.init_global_limiter, initargs=(bucket,), ) as executor: futures = [executor.submit(my_task) for _ in range(num_requests)] wait(futures) for f in futures: try: f.result() except Exception as e: raise e def test_bucket_full(): requests_per_second = 1 num_seconds = 5 num_requests = requests_per_second * num_seconds rate = Rate(requests_per_second, Duration.SECOND) bucket = MultiprocessBucket.init([rate]) limiter = Limiter( bucket ) for _ in range(1000): last_success = limiter.try_acquire("mytest", 1, blocking=False) assert not last_success with ProcessPoolExecutor( initializer=limiter_factory.init_global_limiter, initargs=(bucket,) ) as executor: futures = [executor.submit(my_task) for _ in range(num_requests)] wait(futures) for f in futures: try: f.result() except Exception as e: raise e vutran1710-PyrateLimiter-634d166/tests/test_others.py000066400000000000000000000112121513463764300225010ustar00rootroot00000000000000import logging import re from inspect import isawaitable from time import time import pytest from pyrate_limiter import binary_search from pyrate_limiter import Duration from pyrate_limiter import Rate from pyrate_limiter import RateItem from pyrate_limiter import SQLiteClock from pyrate_limiter import MonotonicClock from pyrate_limiter import AbstractClock from pyrate_limiter import validate_rate_list def test_version(): from pyrate_limiter import _version assert re.match(r'^\d+\.\d+\.\d+(\..*)?', _version.__version__), f"""{_version.__version__=} doesn't match a version pattern (x.y.z)""" def test_duration(): assert int(Duration.SECOND) == 1000 assert Duration.SECOND.value == 1000 assert Duration.SECOND * 60 == 60 * Duration.SECOND == Duration.MINUTE.value == int(Duration.MINUTE) assert Duration.MINUTE * 60 == 60 * Duration.MINUTE == Duration.HOUR.value == int(Duration.HOUR) assert Duration.HOUR * 24 == 24 * Duration.HOUR == Duration.DAY.value == int(Duration.DAY) assert Duration.DAY * 7 == 7 * Duration.DAY == Duration.WEEK.value == int(Duration.WEEK) assert Duration.DAY + Duration.DAY == Duration.DAY * 2 assert Duration.MINUTE + 30000 == 30000 + Duration.MINUTE == 90000 def test_readable_duration(): assert Duration.readable(300) == "300ms" assert Duration.readable(1000) == "1.0s" assert Duration.readable(1300) == "1.3s" assert Duration.readable(Duration.SECOND * 3.5) == "3.5s" assert Duration.readable(Duration.SECOND * 60 * 24 + Duration.SECOND * 30) == "24.5m" assert Duration.readable(Duration.MINUTE * 3.5) == "3.5m" assert Duration.readable(Duration.MINUTE * 60 + Duration.MINUTE * 30) == "1.5h" assert Duration.readable(Duration.HOUR * 3.5) == "3.5h" assert Duration.readable(Duration.DAY * 3.5) == "3.5d" assert Duration.readable(Duration.WEEK * 3.5) == "3.5w" def test_rate(): rate = Rate(1000, Duration.SECOND) assert str(rate) == "limit=1000/1.0s" assert repr(rate) == "limit=1000/1000" rate = Rate(1000, Duration.SECOND * 3) assert str(rate) == "limit=1000/3.0s" assert repr(rate) == "limit=1000/3000" rate = Rate(1000, 3500) assert str(rate) == "limit=1000/3.5s" rate = Rate(1000, Duration.MINUTE * 3.5) assert str(rate) == "limit=1000/3.5m" rate = Rate(1000, Duration.MINUTE * 3) assert str(rate) == "limit=1000/3.0m" def test_binary_search(): """Testing binary-search that find item in array""" # Normal list of items items = [RateItem("item", nth * 2) for nth in range(5)] print([item.timestamp for item in items]) assert binary_search(items, 0) == 0 assert binary_search(items, 1) == 1 assert binary_search(items, 2) == 1 assert binary_search(items, 3) == 2 assert binary_search(items, 9) == -1 assert binary_search(items, 8) == 4 # If the value is larger than the last item, idx would be -1 assert binary_search(items, 11) == -1 # Empty list items = [] assert binary_search(items, 1) == 0 assert binary_search(items, 2) == 0 assert binary_search(items, 3) == 0 def test_rate_validator(): rates = [] assert validate_rate_list(rates) is False rates = [Rate(1, 1)] assert validate_rate_list(rates) is True rates = [Rate(2, 1), Rate(1, 1)] assert validate_rate_list(rates) is False rates = [Rate(1, 1), Rate(2, 1)] assert validate_rate_list(rates) is False rates = [Rate(1, 1), Rate(2, 2)] assert validate_rate_list(rates) is True rates = [Rate(2, 1), Rate(1, 2)] assert validate_rate_list(rates) is False rates = [Rate(2, 1), Rate(3, 2)] assert validate_rate_list(rates) is True rates = [Rate(1, 1), Rate(3, 2), Rate(4, 1)] assert validate_rate_list(rates) is False rates = [Rate(2, 1), Rate(3, 2), Rate(4, 3)] assert validate_rate_list(rates) is True @pytest.mark.asyncio async def test_clock(clock: AbstractClock | None = None): """Testing clock backends """ if clock is None: clock = MonotonicClock() now = clock.now() while isawaitable(now): now = await now logging.info("Testing clock: %s -> %d", clock, now) assert now > 0 if now > 1000: # NOTE: if not MonotonicClock, the time values should be almost equal use_time = time() * 1000 assert int(now) - round(use_time) < 2 @pytest.mark.asyncio async def test_sqlite_clock(): """Testing clock backends """ await test_clock(SQLiteClock.default()) from .conftest import create_sqlite_bucket bucket = await create_sqlite_bucket([Rate(1, Duration.SECOND)]) await test_clock(SQLiteClock(bucket.conn)) await test_clock(SQLiteClock(bucket)) vutran1710-PyrateLimiter-634d166/tests/test_postgres_concurrent.py000066400000000000000000000140771513463764300253210ustar00rootroot00000000000000import threading import pytest from pyrate_limiter import Duration, PostgresBucket, Rate from pyrate_limiter.abstracts import RateItem @pytest.mark.postgres class TestPostgresConcurrent: @pytest.fixture def pg_pool(self): from psycopg_pool import ConnectionPool pool = ConnectionPool( "postgresql://postgres:postgres@localhost:5432", min_size=4, max_size=10, open=True, ) yield pool pool.close() @pytest.fixture def clean_table(self, pg_pool): from pyrate_limiter import id_generator table = f"test_concurrent_{id_generator()}" yield table with pg_pool.connection() as conn: conn.execute(f"DROP TABLE IF EXISTS ratelimit___{table}") def test_concurrent_put(self, pg_pool, clean_table): rate_limit = 5 rates = [Rate(rate_limit, Duration.SECOND)] num_threads = 8 attempts_per_thread = 10 results = [] results_lock = threading.Lock() def worker(thread_id: int): bucket = PostgresBucket(pg_pool, clean_table, rates) thread_results = [] for _ in range(attempts_per_thread): timestamp = bucket.now() item = RateItem(f"thread_{thread_id}", timestamp, weight=1) success = bucket.put(item) thread_results.append((timestamp, success)) with results_lock: results.extend(thread_results) threads = [ threading.Thread(target=worker, args=(i,)) for i in range(num_threads) ] for t in threads: t.start() for t in threads: t.join() # Verify db state full_table = f"ratelimit___{clean_table}" with pg_pool.connection() as conn: cur = conn.execute(f"SELECT COUNT(*) FROM {full_table}") # noqa: S608 total_in_db = cur.fetchone()[0] cur.close() # Check in sliding windows to make sure rate didn't exceed cur = conn.execute( f"SELECT EXTRACT(EPOCH FROM item_timestamp)::bigint as ts FROM {full_table}" # noqa: S608 ) db_timestamps = [row[0] for row in cur.fetchall()] cur.close() for ts in db_timestamps: window_start = ts - 1 # 1 second window count_in_window = sum(1 for t in db_timestamps if t > window_start and t <= ts) assert count_in_window <= rate_limit, ( f"Rate limit exceeded in DB: {count_in_window} items in 1-second window ending at {ts}" ) # Verify anything worked total_success = sum(1 for _, success in results if success) assert total_success > 0, "No successful acquisitions" assert total_success == total_in_db, ( f"Mismatch: {total_success} reported successes but {total_in_db} items in DB" ) # Verify some rejections total_rejected = sum(1 for _, success in results if not success) assert total_rejected > 0, ( "No rejections occurred - rate limiting may not be working" ) def test_concurrent_put_multiple_rates(self, pg_pool, clean_table): rates = [ Rate(3, 500), # 3 per 500ms Rate(5, 1000), # 5 per second ] num_threads = 4 attempts_per_thread = 5 results = [] results_lock = threading.Lock() def worker(thread_id: int): bucket = PostgresBucket(pg_pool, clean_table, rates) thread_results = [] for _ in range(attempts_per_thread): timestamp = bucket.now() item = RateItem(f"thread_{thread_id}", timestamp, weight=1) success = bucket.put(item) thread_results.append((timestamp, success)) with results_lock: results.extend(thread_results) threads = [ threading.Thread(target=worker, args=(i,)) for i in range(num_threads) ] for t in threads: t.start() for t in threads: t.join() successful_timestamps = sorted([ts for ts, success in results if success]) # Check sliding windows for both rates for ts in successful_timestamps: # 1-second sliding window count_1s = sum(1 for t in successful_timestamps if ts - 1000 <= t <= ts) assert count_1s <= 5, f"1-second rate exceeded: {count_1s} items in window ending at {ts}" # 500ms sliding window count_500ms = sum(1 for t in successful_timestamps if ts - 500 <= t <= ts) assert count_500ms <= 3, f"500ms rate exceeded: {count_500ms} items in window ending at {ts}" def test_concurrent_put_weighted(self, pg_pool, clean_table): rate_limit = 10 rates = [Rate(rate_limit, Duration.SECOND)] num_threads = 4 weight = 3 results = [] results_lock = threading.Lock() def worker(thread_id: int): bucket = PostgresBucket(pg_pool, clean_table, rates) thread_results = [] for _ in range(5): timestamp = bucket.now() item = RateItem(f"thread_{thread_id}", timestamp, weight=weight) success = bucket.put(item) thread_results.append((timestamp, success, weight)) with results_lock: results.extend(thread_results) threads = [ threading.Thread(target=worker, args=(i,)) for i in range(num_threads) ] for t in threads: t.start() for t in threads: t.join() successful_results = sorted([(ts, w) for ts, success, w in results if success]) # Check sliding windows for weighted items for ts, _ in successful_results: weight_in_window = sum(w for t, w in successful_results if ts - 1000 <= t <= ts) assert weight_in_window <= rate_limit, ( f"Rate limit exceeded: weight {weight_in_window} in 1-second window ending at {ts}" ) vutran1710-PyrateLimiter-634d166/uv.lock000066400000000000000000012455571513463764300177540ustar00rootroot00000000000000version = 1 revision = 3 requires-python = ">=3.9" resolution-markers = [ "python_full_version >= '3.11'", "python_full_version == '3.10.*'", "python_full_version < '3.10'", ] [[package]] name = "accessible-pygments" version = "0.0.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pygments" }, ] sdist = { url = "https://files.pythonhosted.org/packages/bc/c1/bbac6a50d02774f91572938964c582fff4270eee73ab822a4aeea4d8b11b/accessible_pygments-0.0.5.tar.gz", hash = "sha256:40918d3e6a2b619ad424cb91e556bd3bd8865443d9f22f1dcdf79e33c8046872", size = 1377899, upload-time = "2024-05-10T11:23:10.216Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/8d/3f/95338030883d8c8b91223b4e21744b04d11b161a3ef117295d8241f50ab4/accessible_pygments-0.0.5-py3-none-any.whl", hash = "sha256:88ae3211e68a1d0b011504b2ffc1691feafce124b845bd072ab6f9f66f34d4b7", size = 1395903, upload-time = "2024-05-10T11:23:08.421Z" }, ] [[package]] name = "aiohappyeyeballs" version = "2.6.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760, upload-time = "2025-03-12T01:42:48.764Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265, upload-time = "2025-03-12T01:42:47.083Z" }, ] [[package]] name = "aiohttp" version = "3.12.15" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohappyeyeballs" }, { name = "aiosignal" }, { name = "async-timeout", marker = "python_full_version < '3.11'" }, { name = "attrs" }, { name = "frozenlist" }, { name = "multidict" }, { name = "propcache" }, { name = "yarl" }, ] sdist = { url = "https://files.pythonhosted.org/packages/9b/e7/d92a237d8802ca88483906c388f7c201bbe96cd80a165ffd0ac2f6a8d59f/aiohttp-3.12.15.tar.gz", hash = "sha256:4fc61385e9c98d72fcdf47e6dd81833f47b2f77c114c29cd64a361be57a763a2", size = 7823716, upload-time = "2025-07-29T05:52:32.215Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/47/dc/ef9394bde9080128ad401ac7ede185267ed637df03b51f05d14d1c99ad67/aiohttp-3.12.15-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b6fc902bff74d9b1879ad55f5404153e2b33a82e72a95c89cec5eb6cc9e92fbc", size = 703921, upload-time = "2025-07-29T05:49:43.584Z" }, { url = "https://files.pythonhosted.org/packages/8f/42/63fccfc3a7ed97eb6e1a71722396f409c46b60a0552d8a56d7aad74e0df5/aiohttp-3.12.15-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:098e92835b8119b54c693f2f88a1dec690e20798ca5f5fe5f0520245253ee0af", size = 480288, upload-time = "2025-07-29T05:49:47.851Z" }, { url = "https://files.pythonhosted.org/packages/9c/a2/7b8a020549f66ea2a68129db6960a762d2393248f1994499f8ba9728bbed/aiohttp-3.12.15-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:40b3fee496a47c3b4a39a731954c06f0bd9bd3e8258c059a4beb76ac23f8e421", size = 468063, upload-time = "2025-07-29T05:49:49.789Z" }, { url = "https://files.pythonhosted.org/packages/8f/f5/d11e088da9176e2ad8220338ae0000ed5429a15f3c9dfd983f39105399cd/aiohttp-3.12.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ce13fcfb0bb2f259fb42106cdc63fa5515fb85b7e87177267d89a771a660b79", size = 1650122, upload-time = "2025-07-29T05:49:51.874Z" }, { url = "https://files.pythonhosted.org/packages/b0/6b/b60ce2757e2faed3d70ed45dafee48cee7bfb878785a9423f7e883f0639c/aiohttp-3.12.15-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3beb14f053222b391bf9cf92ae82e0171067cc9c8f52453a0f1ec7c37df12a77", size = 1624176, upload-time = "2025-07-29T05:49:53.805Z" }, { url = "https://files.pythonhosted.org/packages/dd/de/8c9fde2072a1b72c4fadecf4f7d4be7a85b1d9a4ab333d8245694057b4c6/aiohttp-3.12.15-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c39e87afe48aa3e814cac5f535bc6199180a53e38d3f51c5e2530f5aa4ec58c", size = 1696583, upload-time = "2025-07-29T05:49:55.338Z" }, { url = "https://files.pythonhosted.org/packages/0c/ad/07f863ca3d895a1ad958a54006c6dafb4f9310f8c2fdb5f961b8529029d3/aiohttp-3.12.15-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5f1b4ce5bc528a6ee38dbf5f39bbf11dd127048726323b72b8e85769319ffc4", size = 1738896, upload-time = "2025-07-29T05:49:57.045Z" }, { url = "https://files.pythonhosted.org/packages/20/43/2bd482ebe2b126533e8755a49b128ec4e58f1a3af56879a3abdb7b42c54f/aiohttp-3.12.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1004e67962efabbaf3f03b11b4c43b834081c9e3f9b32b16a7d97d4708a9abe6", size = 1643561, upload-time = "2025-07-29T05:49:58.762Z" }, { url = "https://files.pythonhosted.org/packages/23/40/2fa9f514c4cf4cbae8d7911927f81a1901838baf5e09a8b2c299de1acfe5/aiohttp-3.12.15-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8faa08fcc2e411f7ab91d1541d9d597d3a90e9004180edb2072238c085eac8c2", size = 1583685, upload-time = "2025-07-29T05:50:00.375Z" }, { url = "https://files.pythonhosted.org/packages/b8/c3/94dc7357bc421f4fb978ca72a201a6c604ee90148f1181790c129396ceeb/aiohttp-3.12.15-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fe086edf38b2222328cdf89af0dde2439ee173b8ad7cb659b4e4c6f385b2be3d", size = 1627533, upload-time = "2025-07-29T05:50:02.306Z" }, { url = "https://files.pythonhosted.org/packages/bf/3f/1f8911fe1844a07001e26593b5c255a685318943864b27b4e0267e840f95/aiohttp-3.12.15-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:79b26fe467219add81d5e47b4a4ba0f2394e8b7c7c3198ed36609f9ba161aecb", size = 1638319, upload-time = "2025-07-29T05:50:04.282Z" }, { url = "https://files.pythonhosted.org/packages/4e/46/27bf57a99168c4e145ffee6b63d0458b9c66e58bb70687c23ad3d2f0bd17/aiohttp-3.12.15-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b761bac1192ef24e16706d761aefcb581438b34b13a2f069a6d343ec8fb693a5", size = 1613776, upload-time = "2025-07-29T05:50:05.863Z" }, { url = "https://files.pythonhosted.org/packages/0f/7e/1d2d9061a574584bb4ad3dbdba0da90a27fdc795bc227def3a46186a8bc1/aiohttp-3.12.15-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e153e8adacfe2af562861b72f8bc47f8a5c08e010ac94eebbe33dc21d677cd5b", size = 1693359, upload-time = "2025-07-29T05:50:07.563Z" }, { url = "https://files.pythonhosted.org/packages/08/98/bee429b52233c4a391980a5b3b196b060872a13eadd41c3a34be9b1469ed/aiohttp-3.12.15-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:fc49c4de44977aa8601a00edbf157e9a421f227aa7eb477d9e3df48343311065", size = 1716598, upload-time = "2025-07-29T05:50:09.33Z" }, { url = "https://files.pythonhosted.org/packages/57/39/b0314c1ea774df3392751b686104a3938c63ece2b7ce0ba1ed7c0b4a934f/aiohttp-3.12.15-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2776c7ec89c54a47029940177e75c8c07c29c66f73464784971d6a81904ce9d1", size = 1644940, upload-time = "2025-07-29T05:50:11.334Z" }, { url = "https://files.pythonhosted.org/packages/1b/83/3dacb8d3f8f512c8ca43e3fa8a68b20583bd25636ffa4e56ee841ffd79ae/aiohttp-3.12.15-cp310-cp310-win32.whl", hash = "sha256:2c7d81a277fa78b2203ab626ced1487420e8c11a8e373707ab72d189fcdad20a", size = 429239, upload-time = "2025-07-29T05:50:12.803Z" }, { url = "https://files.pythonhosted.org/packages/eb/f9/470b5daba04d558c9673ca2034f28d067f3202a40e17804425f0c331c89f/aiohttp-3.12.15-cp310-cp310-win_amd64.whl", hash = "sha256:83603f881e11f0f710f8e2327817c82e79431ec976448839f3cd05d7afe8f830", size = 452297, upload-time = "2025-07-29T05:50:14.266Z" }, { url = "https://files.pythonhosted.org/packages/20/19/9e86722ec8e835959bd97ce8c1efa78cf361fa4531fca372551abcc9cdd6/aiohttp-3.12.15-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d3ce17ce0220383a0f9ea07175eeaa6aa13ae5a41f30bc61d84df17f0e9b1117", size = 711246, upload-time = "2025-07-29T05:50:15.937Z" }, { url = "https://files.pythonhosted.org/packages/71/f9/0a31fcb1a7d4629ac9d8f01f1cb9242e2f9943f47f5d03215af91c3c1a26/aiohttp-3.12.15-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:010cc9bbd06db80fe234d9003f67e97a10fe003bfbedb40da7d71c1008eda0fe", size = 483515, upload-time = "2025-07-29T05:50:17.442Z" }, { url = "https://files.pythonhosted.org/packages/62/6c/94846f576f1d11df0c2e41d3001000527c0fdf63fce7e69b3927a731325d/aiohttp-3.12.15-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3f9d7c55b41ed687b9d7165b17672340187f87a773c98236c987f08c858145a9", size = 471776, upload-time = "2025-07-29T05:50:19.568Z" }, { url = "https://files.pythonhosted.org/packages/f8/6c/f766d0aaafcee0447fad0328da780d344489c042e25cd58fde566bf40aed/aiohttp-3.12.15-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc4fbc61bb3548d3b482f9ac7ddd0f18c67e4225aaa4e8552b9f1ac7e6bda9e5", size = 1741977, upload-time = "2025-07-29T05:50:21.665Z" }, { url = "https://files.pythonhosted.org/packages/17/e5/fb779a05ba6ff44d7bc1e9d24c644e876bfff5abe5454f7b854cace1b9cc/aiohttp-3.12.15-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7fbc8a7c410bb3ad5d595bb7118147dfbb6449d862cc1125cf8867cb337e8728", size = 1690645, upload-time = "2025-07-29T05:50:23.333Z" }, { url = "https://files.pythonhosted.org/packages/37/4e/a22e799c2035f5d6a4ad2cf8e7c1d1bd0923192871dd6e367dafb158b14c/aiohttp-3.12.15-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:74dad41b3458dbb0511e760fb355bb0b6689e0630de8a22b1b62a98777136e16", size = 1789437, upload-time = "2025-07-29T05:50:25.007Z" }, { url = "https://files.pythonhosted.org/packages/28/e5/55a33b991f6433569babb56018b2fb8fb9146424f8b3a0c8ecca80556762/aiohttp-3.12.15-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b6f0af863cf17e6222b1735a756d664159e58855da99cfe965134a3ff63b0b0", size = 1828482, upload-time = "2025-07-29T05:50:26.693Z" }, { url = "https://files.pythonhosted.org/packages/c6/82/1ddf0ea4f2f3afe79dffed5e8a246737cff6cbe781887a6a170299e33204/aiohttp-3.12.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b5b7fe4972d48a4da367043b8e023fb70a04d1490aa7d68800e465d1b97e493b", size = 1730944, upload-time = "2025-07-29T05:50:28.382Z" }, { url = "https://files.pythonhosted.org/packages/1b/96/784c785674117b4cb3877522a177ba1b5e4db9ce0fd519430b5de76eec90/aiohttp-3.12.15-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6443cca89553b7a5485331bc9bedb2342b08d073fa10b8c7d1c60579c4a7b9bd", size = 1668020, upload-time = "2025-07-29T05:50:30.032Z" }, { url = "https://files.pythonhosted.org/packages/12/8a/8b75f203ea7e5c21c0920d84dd24a5c0e971fe1e9b9ebbf29ae7e8e39790/aiohttp-3.12.15-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6c5f40ec615e5264f44b4282ee27628cea221fcad52f27405b80abb346d9f3f8", size = 1716292, upload-time = "2025-07-29T05:50:31.983Z" }, { url = "https://files.pythonhosted.org/packages/47/0b/a1451543475bb6b86a5cfc27861e52b14085ae232896a2654ff1231c0992/aiohttp-3.12.15-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:2abbb216a1d3a2fe86dbd2edce20cdc5e9ad0be6378455b05ec7f77361b3ab50", size = 1711451, upload-time = "2025-07-29T05:50:33.989Z" }, { url = "https://files.pythonhosted.org/packages/55/fd/793a23a197cc2f0d29188805cfc93aa613407f07e5f9da5cd1366afd9d7c/aiohttp-3.12.15-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:db71ce547012a5420a39c1b744d485cfb823564d01d5d20805977f5ea1345676", size = 1691634, upload-time = "2025-07-29T05:50:35.846Z" }, { url = "https://files.pythonhosted.org/packages/ca/bf/23a335a6670b5f5dfc6d268328e55a22651b440fca341a64fccf1eada0c6/aiohttp-3.12.15-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ced339d7c9b5030abad5854aa5413a77565e5b6e6248ff927d3e174baf3badf7", size = 1785238, upload-time = "2025-07-29T05:50:37.597Z" }, { url = "https://files.pythonhosted.org/packages/57/4f/ed60a591839a9d85d40694aba5cef86dde9ee51ce6cca0bb30d6eb1581e7/aiohttp-3.12.15-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:7c7dd29c7b5bda137464dc9bfc738d7ceea46ff70309859ffde8c022e9b08ba7", size = 1805701, upload-time = "2025-07-29T05:50:39.591Z" }, { url = "https://files.pythonhosted.org/packages/85/e0/444747a9455c5de188c0f4a0173ee701e2e325d4b2550e9af84abb20cdba/aiohttp-3.12.15-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:421da6fd326460517873274875c6c5a18ff225b40da2616083c5a34a7570b685", size = 1718758, upload-time = "2025-07-29T05:50:41.292Z" }, { url = "https://files.pythonhosted.org/packages/36/ab/1006278d1ffd13a698e5dd4bfa01e5878f6bddefc296c8b62649753ff249/aiohttp-3.12.15-cp311-cp311-win32.whl", hash = "sha256:4420cf9d179ec8dfe4be10e7d0fe47d6d606485512ea2265b0d8c5113372771b", size = 428868, upload-time = "2025-07-29T05:50:43.063Z" }, { url = "https://files.pythonhosted.org/packages/10/97/ad2b18700708452400278039272032170246a1bf8ec5d832772372c71f1a/aiohttp-3.12.15-cp311-cp311-win_amd64.whl", hash = "sha256:edd533a07da85baa4b423ee8839e3e91681c7bfa19b04260a469ee94b778bf6d", size = 453273, upload-time = "2025-07-29T05:50:44.613Z" }, { url = "https://files.pythonhosted.org/packages/63/97/77cb2450d9b35f517d6cf506256bf4f5bda3f93a66b4ad64ba7fc917899c/aiohttp-3.12.15-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:802d3868f5776e28f7bf69d349c26fc0efadb81676d0afa88ed00d98a26340b7", size = 702333, upload-time = "2025-07-29T05:50:46.507Z" }, { url = "https://files.pythonhosted.org/packages/83/6d/0544e6b08b748682c30b9f65640d006e51f90763b41d7c546693bc22900d/aiohttp-3.12.15-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2800614cd560287be05e33a679638e586a2d7401f4ddf99e304d98878c29444", size = 476948, upload-time = "2025-07-29T05:50:48.067Z" }, { url = "https://files.pythonhosted.org/packages/3a/1d/c8c40e611e5094330284b1aea8a4b02ca0858f8458614fa35754cab42b9c/aiohttp-3.12.15-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8466151554b593909d30a0a125d638b4e5f3836e5aecde85b66b80ded1cb5b0d", size = 469787, upload-time = "2025-07-29T05:50:49.669Z" }, { url = "https://files.pythonhosted.org/packages/38/7d/b76438e70319796bfff717f325d97ce2e9310f752a267bfdf5192ac6082b/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e5a495cb1be69dae4b08f35a6c4579c539e9b5706f606632102c0f855bcba7c", size = 1716590, upload-time = "2025-07-29T05:50:51.368Z" }, { url = "https://files.pythonhosted.org/packages/79/b1/60370d70cdf8b269ee1444b390cbd72ce514f0d1cd1a715821c784d272c9/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6404dfc8cdde35c69aaa489bb3542fb86ef215fc70277c892be8af540e5e21c0", size = 1699241, upload-time = "2025-07-29T05:50:53.628Z" }, { url = "https://files.pythonhosted.org/packages/a3/2b/4968a7b8792437ebc12186db31523f541943e99bda8f30335c482bea6879/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3ead1c00f8521a5c9070fcb88f02967b1d8a0544e6d85c253f6968b785e1a2ab", size = 1754335, upload-time = "2025-07-29T05:50:55.394Z" }, { url = "https://files.pythonhosted.org/packages/fb/c1/49524ed553f9a0bec1a11fac09e790f49ff669bcd14164f9fab608831c4d/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6990ef617f14450bc6b34941dba4f12d5613cbf4e33805932f853fbd1cf18bfb", size = 1800491, upload-time = "2025-07-29T05:50:57.202Z" }, { url = "https://files.pythonhosted.org/packages/de/5e/3bf5acea47a96a28c121b167f5ef659cf71208b19e52a88cdfa5c37f1fcc/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd736ed420f4db2b8148b52b46b88ed038d0354255f9a73196b7bbce3ea97545", size = 1719929, upload-time = "2025-07-29T05:50:59.192Z" }, { url = "https://files.pythonhosted.org/packages/39/94/8ae30b806835bcd1cba799ba35347dee6961a11bd507db634516210e91d8/aiohttp-3.12.15-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c5092ce14361a73086b90c6efb3948ffa5be2f5b6fbcf52e8d8c8b8848bb97c", size = 1635733, upload-time = "2025-07-29T05:51:01.394Z" }, { url = "https://files.pythonhosted.org/packages/7a/46/06cdef71dd03acd9da7f51ab3a9107318aee12ad38d273f654e4f981583a/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:aaa2234bb60c4dbf82893e934d8ee8dea30446f0647e024074237a56a08c01bd", size = 1696790, upload-time = "2025-07-29T05:51:03.657Z" }, { url = "https://files.pythonhosted.org/packages/02/90/6b4cfaaf92ed98d0ec4d173e78b99b4b1a7551250be8937d9d67ecb356b4/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:6d86a2fbdd14192e2f234a92d3b494dd4457e683ba07e5905a0b3ee25389ac9f", size = 1718245, upload-time = "2025-07-29T05:51:05.911Z" }, { url = "https://files.pythonhosted.org/packages/2e/e6/2593751670fa06f080a846f37f112cbe6f873ba510d070136a6ed46117c6/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a041e7e2612041a6ddf1c6a33b883be6a421247c7afd47e885969ee4cc58bd8d", size = 1658899, upload-time = "2025-07-29T05:51:07.753Z" }, { url = "https://files.pythonhosted.org/packages/8f/28/c15bacbdb8b8eb5bf39b10680d129ea7410b859e379b03190f02fa104ffd/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5015082477abeafad7203757ae44299a610e89ee82a1503e3d4184e6bafdd519", size = 1738459, upload-time = "2025-07-29T05:51:09.56Z" }, { url = "https://files.pythonhosted.org/packages/00/de/c269cbc4faa01fb10f143b1670633a8ddd5b2e1ffd0548f7aa49cb5c70e2/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:56822ff5ddfd1b745534e658faba944012346184fbfe732e0d6134b744516eea", size = 1766434, upload-time = "2025-07-29T05:51:11.423Z" }, { url = "https://files.pythonhosted.org/packages/52/b0/4ff3abd81aa7d929b27d2e1403722a65fc87b763e3a97b3a2a494bfc63bc/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b2acbbfff69019d9014508c4ba0401822e8bae5a5fdc3b6814285b71231b60f3", size = 1726045, upload-time = "2025-07-29T05:51:13.689Z" }, { url = "https://files.pythonhosted.org/packages/71/16/949225a6a2dd6efcbd855fbd90cf476052e648fb011aa538e3b15b89a57a/aiohttp-3.12.15-cp312-cp312-win32.whl", hash = "sha256:d849b0901b50f2185874b9a232f38e26b9b3d4810095a7572eacea939132d4e1", size = 423591, upload-time = "2025-07-29T05:51:15.452Z" }, { url = "https://files.pythonhosted.org/packages/2b/d8/fa65d2a349fe938b76d309db1a56a75c4fb8cc7b17a398b698488a939903/aiohttp-3.12.15-cp312-cp312-win_amd64.whl", hash = "sha256:b390ef5f62bb508a9d67cb3bba9b8356e23b3996da7062f1a57ce1a79d2b3d34", size = 450266, upload-time = "2025-07-29T05:51:17.239Z" }, { url = "https://files.pythonhosted.org/packages/f2/33/918091abcf102e39d15aba2476ad9e7bd35ddb190dcdd43a854000d3da0d/aiohttp-3.12.15-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:9f922ffd05034d439dde1c77a20461cf4a1b0831e6caa26151fe7aa8aaebc315", size = 696741, upload-time = "2025-07-29T05:51:19.021Z" }, { url = "https://files.pythonhosted.org/packages/b5/2a/7495a81e39a998e400f3ecdd44a62107254803d1681d9189be5c2e4530cd/aiohttp-3.12.15-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2ee8a8ac39ce45f3e55663891d4b1d15598c157b4d494a4613e704c8b43112cd", size = 474407, upload-time = "2025-07-29T05:51:21.165Z" }, { url = "https://files.pythonhosted.org/packages/49/fc/a9576ab4be2dcbd0f73ee8675d16c707cfc12d5ee80ccf4015ba543480c9/aiohttp-3.12.15-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3eae49032c29d356b94eee45a3f39fdf4b0814b397638c2f718e96cfadf4c4e4", size = 466703, upload-time = "2025-07-29T05:51:22.948Z" }, { url = "https://files.pythonhosted.org/packages/09/2f/d4bcc8448cf536b2b54eed48f19682031ad182faa3a3fee54ebe5b156387/aiohttp-3.12.15-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b97752ff12cc12f46a9b20327104448042fce5c33a624f88c18f66f9368091c7", size = 1705532, upload-time = "2025-07-29T05:51:25.211Z" }, { url = "https://files.pythonhosted.org/packages/f1/f3/59406396083f8b489261e3c011aa8aee9df360a96ac8fa5c2e7e1b8f0466/aiohttp-3.12.15-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:894261472691d6fe76ebb7fcf2e5870a2ac284c7406ddc95823c8598a1390f0d", size = 1686794, upload-time = "2025-07-29T05:51:27.145Z" }, { url = "https://files.pythonhosted.org/packages/dc/71/164d194993a8d114ee5656c3b7ae9c12ceee7040d076bf7b32fb98a8c5c6/aiohttp-3.12.15-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5fa5d9eb82ce98959fc1031c28198b431b4d9396894f385cb63f1e2f3f20ca6b", size = 1738865, upload-time = "2025-07-29T05:51:29.366Z" }, { url = "https://files.pythonhosted.org/packages/1c/00/d198461b699188a93ead39cb458554d9f0f69879b95078dce416d3209b54/aiohttp-3.12.15-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0fa751efb11a541f57db59c1dd821bec09031e01452b2b6217319b3a1f34f3d", size = 1788238, upload-time = "2025-07-29T05:51:31.285Z" }, { url = "https://files.pythonhosted.org/packages/85/b8/9e7175e1fa0ac8e56baa83bf3c214823ce250d0028955dfb23f43d5e61fd/aiohttp-3.12.15-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5346b93e62ab51ee2a9d68e8f73c7cf96ffb73568a23e683f931e52450e4148d", size = 1710566, upload-time = "2025-07-29T05:51:33.219Z" }, { url = "https://files.pythonhosted.org/packages/59/e4/16a8eac9df39b48ae102ec030fa9f726d3570732e46ba0c592aeeb507b93/aiohttp-3.12.15-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:049ec0360f939cd164ecbfd2873eaa432613d5e77d6b04535e3d1fbae5a9e645", size = 1624270, upload-time = "2025-07-29T05:51:35.195Z" }, { url = "https://files.pythonhosted.org/packages/1f/f8/cd84dee7b6ace0740908fd0af170f9fab50c2a41ccbc3806aabcb1050141/aiohttp-3.12.15-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b52dcf013b57464b6d1e51b627adfd69a8053e84b7103a7cd49c030f9ca44461", size = 1677294, upload-time = "2025-07-29T05:51:37.215Z" }, { url = "https://files.pythonhosted.org/packages/ce/42/d0f1f85e50d401eccd12bf85c46ba84f947a84839c8a1c2c5f6e8ab1eb50/aiohttp-3.12.15-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:9b2af240143dd2765e0fb661fd0361a1b469cab235039ea57663cda087250ea9", size = 1708958, upload-time = "2025-07-29T05:51:39.328Z" }, { url = "https://files.pythonhosted.org/packages/d5/6b/f6fa6c5790fb602538483aa5a1b86fcbad66244997e5230d88f9412ef24c/aiohttp-3.12.15-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ac77f709a2cde2cc71257ab2d8c74dd157c67a0558a0d2799d5d571b4c63d44d", size = 1651553, upload-time = "2025-07-29T05:51:41.356Z" }, { url = "https://files.pythonhosted.org/packages/04/36/a6d36ad545fa12e61d11d1932eef273928b0495e6a576eb2af04297fdd3c/aiohttp-3.12.15-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:47f6b962246f0a774fbd3b6b7be25d59b06fdb2f164cf2513097998fc6a29693", size = 1727688, upload-time = "2025-07-29T05:51:43.452Z" }, { url = "https://files.pythonhosted.org/packages/aa/c8/f195e5e06608a97a4e52c5d41c7927301bf757a8e8bb5bbf8cef6c314961/aiohttp-3.12.15-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:760fb7db442f284996e39cf9915a94492e1896baac44f06ae551974907922b64", size = 1761157, upload-time = "2025-07-29T05:51:45.643Z" }, { url = "https://files.pythonhosted.org/packages/05/6a/ea199e61b67f25ba688d3ce93f63b49b0a4e3b3d380f03971b4646412fc6/aiohttp-3.12.15-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad702e57dc385cae679c39d318def49aef754455f237499d5b99bea4ef582e51", size = 1710050, upload-time = "2025-07-29T05:51:48.203Z" }, { url = "https://files.pythonhosted.org/packages/b4/2e/ffeb7f6256b33635c29dbed29a22a723ff2dd7401fff42ea60cf2060abfb/aiohttp-3.12.15-cp313-cp313-win32.whl", hash = "sha256:f813c3e9032331024de2eb2e32a88d86afb69291fbc37a3a3ae81cc9917fb3d0", size = 422647, upload-time = "2025-07-29T05:51:50.718Z" }, { url = "https://files.pythonhosted.org/packages/1b/8e/78ee35774201f38d5e1ba079c9958f7629b1fd079459aea9467441dbfbf5/aiohttp-3.12.15-cp313-cp313-win_amd64.whl", hash = "sha256:1a649001580bdb37c6fdb1bebbd7e3bc688e8ec2b5c6f52edbb664662b17dc84", size = 449067, upload-time = "2025-07-29T05:51:52.549Z" }, { url = "https://files.pythonhosted.org/packages/18/8d/da08099af8db234d1cd43163e6ffc8e9313d0e988cee1901610f2fa5c764/aiohttp-3.12.15-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:691d203c2bdf4f4637792efbbcdcd157ae11e55eaeb5e9c360c1206fb03d4d98", size = 706829, upload-time = "2025-07-29T05:51:54.434Z" }, { url = "https://files.pythonhosted.org/packages/4e/94/8eed385cfb60cf4fdb5b8a165f6148f3bebeb365f08663d83c35a5f273ef/aiohttp-3.12.15-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8e995e1abc4ed2a454c731385bf4082be06f875822adc4c6d9eaadf96e20d406", size = 481806, upload-time = "2025-07-29T05:51:56.355Z" }, { url = "https://files.pythonhosted.org/packages/38/68/b13e1a34584fbf263151b3a72a084e89f2102afe38df1dce5a05a15b83e9/aiohttp-3.12.15-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bd44d5936ab3193c617bfd6c9a7d8d1085a8dc8c3f44d5f1dcf554d17d04cf7d", size = 469205, upload-time = "2025-07-29T05:51:58.277Z" }, { url = "https://files.pythonhosted.org/packages/38/14/3d7348bf53aa4af54416bc64cbef3a2ac5e8b9bfa97cc45f1cf9a94d9c8d/aiohttp-3.12.15-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46749be6e89cd78d6068cdf7da51dbcfa4321147ab8e4116ee6678d9a056a0cf", size = 1644174, upload-time = "2025-07-29T05:52:00.23Z" }, { url = "https://files.pythonhosted.org/packages/ba/ed/fd9b5b22b0f6ca1a85c33bb4868cbcc6ae5eae070a0f4c9c5cad003c89d7/aiohttp-3.12.15-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0c643f4d75adea39e92c0f01b3fb83d57abdec8c9279b3078b68a3a52b3933b6", size = 1618672, upload-time = "2025-07-29T05:52:02.272Z" }, { url = "https://files.pythonhosted.org/packages/39/f7/f6530ab5f8c8c409e44a63fcad35e839c87aabecdfe5b8e96d671ed12f64/aiohttp-3.12.15-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0a23918fedc05806966a2438489dcffccbdf83e921a1170773b6178d04ade142", size = 1692295, upload-time = "2025-07-29T05:52:04.546Z" }, { url = "https://files.pythonhosted.org/packages/cb/dc/3cf483bb0106566dc97ebaa2bb097f5e44d4bc4ab650a6f107151cd7b193/aiohttp-3.12.15-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:74bdd8c864b36c3673741023343565d95bfbd778ffe1eb4d412c135a28a8dc89", size = 1731609, upload-time = "2025-07-29T05:52:06.552Z" }, { url = "https://files.pythonhosted.org/packages/de/a4/fd04bf807851197077d9cac9381d58f86d91c95c06cbaf9d3a776ac4467a/aiohttp-3.12.15-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a146708808c9b7a988a4af3821379e379e0f0e5e466ca31a73dbdd0325b0263", size = 1637852, upload-time = "2025-07-29T05:52:08.975Z" }, { url = "https://files.pythonhosted.org/packages/98/03/29d626ca3bcdcafbd74b45d77ca42645a5c94d396f2ee3446880ad2405fb/aiohttp-3.12.15-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7011a70b56facde58d6d26da4fec3280cc8e2a78c714c96b7a01a87930a9530", size = 1572852, upload-time = "2025-07-29T05:52:11.508Z" }, { url = "https://files.pythonhosted.org/packages/5f/cd/b4777a9e204f4e01091091027e5d1e2fa86decd0fee5067bc168e4fa1e76/aiohttp-3.12.15-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:3bdd6e17e16e1dbd3db74d7f989e8af29c4d2e025f9828e6ef45fbdee158ec75", size = 1620813, upload-time = "2025-07-29T05:52:13.891Z" }, { url = "https://files.pythonhosted.org/packages/ae/26/1a44a6e8417e84057beaf8c462529b9e05d4b53b8605784f1eb571f0ff68/aiohttp-3.12.15-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:57d16590a351dfc914670bd72530fd78344b885a00b250e992faea565b7fdc05", size = 1630951, upload-time = "2025-07-29T05:52:15.955Z" }, { url = "https://files.pythonhosted.org/packages/dd/7f/10c605dbd01c40e2b27df7ef9004bec75d156f0705141e11047ecdfe264d/aiohttp-3.12.15-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:bc9a0f6569ff990e0bbd75506c8d8fe7214c8f6579cca32f0546e54372a3bb54", size = 1607595, upload-time = "2025-07-29T05:52:18.089Z" }, { url = "https://files.pythonhosted.org/packages/66/f6/2560dcb01731c1d7df1d34b64de95bc4b3ed02bb78830fd82299c1eb314e/aiohttp-3.12.15-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:536ad7234747a37e50e7b6794ea868833d5220b49c92806ae2d7e8a9d6b5de02", size = 1695194, upload-time = "2025-07-29T05:52:20.255Z" }, { url = "https://files.pythonhosted.org/packages/e7/02/ee105ae82dc2b981039fd25b0cf6eaa52b493731960f9bc861375a72b463/aiohttp-3.12.15-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f0adb4177fa748072546fb650d9bd7398caaf0e15b370ed3317280b13f4083b0", size = 1710872, upload-time = "2025-07-29T05:52:22.769Z" }, { url = "https://files.pythonhosted.org/packages/88/16/70c4e42ed6a04f78fb58d1a46500a6ce560741d13afde2a5f33840746a5f/aiohttp-3.12.15-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:14954a2988feae3987f1eb49c706bff39947605f4b6fa4027c1d75743723eb09", size = 1640539, upload-time = "2025-07-29T05:52:25.733Z" }, { url = "https://files.pythonhosted.org/packages/fe/1d/a7eb5fa8a6967117c5c0ad5ab4b1dec0d21e178c89aa08bc442a0b836392/aiohttp-3.12.15-cp39-cp39-win32.whl", hash = "sha256:b784d6ed757f27574dca1c336f968f4e81130b27595e458e69457e6878251f5d", size = 430164, upload-time = "2025-07-29T05:52:27.905Z" }, { url = "https://files.pythonhosted.org/packages/14/25/e0cf8793aedc41c6d7f2aad646a27e27bdacafe3b402bb373d7651c94d73/aiohttp-3.12.15-cp39-cp39-win_amd64.whl", hash = "sha256:86ceded4e78a992f835209e236617bffae649371c4a50d5e5a3987f237db84b8", size = 453370, upload-time = "2025-07-29T05:52:29.936Z" }, ] [[package]] name = "aiosignal" version = "1.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "frozenlist" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload-time = "2025-07-03T22:54:43.528Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, ] [[package]] name = "alabaster" version = "0.7.16" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.10'", ] sdist = { url = "https://files.pythonhosted.org/packages/c9/3e/13dd8e5ed9094e734ac430b5d0eb4f2bb001708a8b7856cbf8e084e001ba/alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65", size = 23776, upload-time = "2024-01-10T00:56:10.189Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/32/34/d4e1c02d3bee589efb5dfa17f88ea08bdb3e3eac12bc475462aec52ed223/alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92", size = 13511, upload-time = "2024-01-10T00:56:08.388Z" }, ] [[package]] name = "alabaster" version = "1.0.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.11'", "python_full_version == '3.10.*'", ] sdist = { url = "https://files.pythonhosted.org/packages/a6/f8/d9c74d0daf3f742840fd818d69cfae176fa332022fd44e3469487d5a9420/alabaster-1.0.0.tar.gz", hash = "sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e", size = 24210, upload-time = "2024-07-26T18:15:03.762Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b", size = 13929, upload-time = "2024-07-26T18:15:02.05Z" }, ] [[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 = "argcomplete" version = "3.6.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/16/0f/861e168fc813c56a78b35f3c30d91c6757d1fd185af1110f1aec784b35d0/argcomplete-3.6.2.tar.gz", hash = "sha256:d0519b1bc867f5f4f4713c41ad0aba73a4a5f007449716b16f385f2166dc6adf", size = 73403, upload-time = "2025-04-03T04:57:03.52Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/31/da/e42d7a9d8dd33fa775f467e4028a47936da2f01e4b0e561f9ba0d74cb0ca/argcomplete-3.6.2-py3-none-any.whl", hash = "sha256:65b3133a29ad53fb42c48cf5114752c7ab66c1c38544fdf6460f450c09b42591", size = 43708, upload-time = "2025-04-03T04:57:01.591Z" }, ] [[package]] name = "async-timeout" version = "5.0.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/a5/ae/136395dfbfe00dfc94da3f3e136d0b13f394cba8f4841120e34226265780/async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3", size = 9274, upload-time = "2024-11-06T16:41:39.6Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/fe/ba/e2081de779ca30d473f21f5b30e0e737c438205440784c7dfc81efc2b029/async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c", size = 6233, upload-time = "2024-11-06T16:41:37.9Z" }, ] [[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-asyncio-runner" version = "1.2.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/8e/ff/70dca7d7cb1cbc0edb2c6cc0c38b65cba36cccc491eca64cabd5fe7f8670/backports_asyncio_runner-1.2.0.tar.gz", hash = "sha256:a5aa7b2b7d8f8bfcaa2b57313f70792df84e32a2a746f585213373f900b42162", size = 69893, upload-time = "2025-07-02T02:27:15.685Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/a0/59/76ab57e3fe74484f48a53f8e337171b4a2349e506eabe136d7e01d059086/backports_asyncio_runner-1.2.0-py3-none-any.whl", hash = "sha256:0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5", size = 12313, upload-time = "2025-07-02T02:27:14.263Z" }, ] [[package]] name = "beautifulsoup4" version = "4.13.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "soupsieve" }, { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/d8/e4/0c4c39e18fd76d6a628d4dd8da40543d136ce2d1752bd6eeeab0791f4d6b/beautifulsoup4-4.13.4.tar.gz", hash = "sha256:dbb3c4e1ceae6aefebdaf2423247260cd062430a410e38c66f2baa50a8437195", size = 621067, upload-time = "2025-04-15T17:05:13.836Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/50/cd/30110dc0ffcf3b131156077b90e9f60ed75711223f306da4db08eff8403b/beautifulsoup4-4.13.4-py3-none-any.whl", hash = "sha256:9bbbb14bfde9d79f38b8cd5f8c7c85f4b8f2523190ebed90e950a8dea4cb1c4b", size = 187285, upload-time = "2025-04-15T17:05:12.221Z" }, ] [[package]] name = "build" version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "os_name == 'nt'" }, { name = "importlib-metadata", marker = "python_full_version < '3.10.2'" }, { name = "packaging" }, { name = "pyproject-hooks" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/25/1c/23e33405a7c9eac261dff640926b8b5adaed6a6eb3e1767d441ed611d0c0/build-1.3.0.tar.gz", hash = "sha256:698edd0ea270bde950f53aed21f3a0135672206f3911e0176261a31e0e07b397", size = 48544, upload-time = "2025-08-01T21:27:09.268Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/cb/8c/2b30c12155ad8de0cf641d76a8b396a16d2c36bc6d50b621a62b7c4567c1/build-1.3.0-py3-none-any.whl", hash = "sha256:7145f0b5061ba90a1500d60bd1b13ca0a8a4cebdd0cc16ed8adf1c0e739f43b4", size = 23382, upload-time = "2025-08-01T21:27:07.844Z" }, ] [[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 = "cfgv" version = "3.4.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114, upload-time = "2023-08-12T20:38:17.776Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249, upload-time = "2023-08-12T20:38:16.269Z" }, ] [[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/c2/ca/9a0983dd5c8e9733565cf3db4df2b0a2e9a82659fd8aa2a868ac6e4a991f/charset_normalizer-3.4.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:70bfc5f2c318afece2f5838ea5e4c3febada0be750fcf4775641052bbba14d05", size = 207520, upload-time = "2025-08-09T07:57:11.026Z" }, { url = "https://files.pythonhosted.org/packages/39/c6/99271dc37243a4f925b09090493fb96c9333d7992c6187f5cfe5312008d2/charset_normalizer-3.4.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:23b6b24d74478dc833444cbd927c338349d6ae852ba53a0d02a2de1fce45b96e", size = 147307, upload-time = "2025-08-09T07:57:12.4Z" }, { url = "https://files.pythonhosted.org/packages/e4/69/132eab043356bba06eb333cc2cc60c6340857d0a2e4ca6dc2b51312886b3/charset_normalizer-3.4.3-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:34a7f768e3f985abdb42841e20e17b330ad3aaf4bb7e7aeeb73db2e70f077b99", size = 160448, upload-time = "2025-08-09T07:57:13.712Z" }, { url = "https://files.pythonhosted.org/packages/04/9a/914d294daa4809c57667b77470533e65def9c0be1ef8b4c1183a99170e9d/charset_normalizer-3.4.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fb731e5deb0c7ef82d698b0f4c5bb724633ee2a489401594c5c88b02e6cb15f7", size = 157758, upload-time = "2025-08-09T07:57:14.979Z" }, { url = "https://files.pythonhosted.org/packages/b0/a8/6f5bcf1bcf63cb45625f7c5cadca026121ff8a6c8a3256d8d8cd59302663/charset_normalizer-3.4.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:257f26fed7d7ff59921b78244f3cd93ed2af1800ff048c33f624c87475819dd7", size = 152487, upload-time = "2025-08-09T07:57:16.332Z" }, { url = "https://files.pythonhosted.org/packages/c4/72/d3d0e9592f4e504f9dea08b8db270821c909558c353dc3b457ed2509f2fb/charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1ef99f0456d3d46a50945c98de1774da86f8e992ab5c77865ea8b8195341fc19", size = 150054, upload-time = "2025-08-09T07:57:17.576Z" }, { url = "https://files.pythonhosted.org/packages/20/30/5f64fe3981677fe63fa987b80e6c01042eb5ff653ff7cec1b7bd9268e54e/charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:2c322db9c8c89009a990ef07c3bcc9f011a3269bc06782f916cd3d9eed7c9312", size = 161703, upload-time = "2025-08-09T07:57:20.012Z" }, { url = "https://files.pythonhosted.org/packages/e1/ef/dd08b2cac9284fd59e70f7d97382c33a3d0a926e45b15fc21b3308324ffd/charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:511729f456829ef86ac41ca78c63a5cb55240ed23b4b737faca0eb1abb1c41bc", size = 159096, upload-time = "2025-08-09T07:57:21.329Z" }, { url = "https://files.pythonhosted.org/packages/45/8c/dcef87cfc2b3f002a6478f38906f9040302c68aebe21468090e39cde1445/charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:88ab34806dea0671532d3f82d82b85e8fc23d7b2dd12fa837978dad9bb392a34", size = 153852, upload-time = "2025-08-09T07:57:22.608Z" }, { url = "https://files.pythonhosted.org/packages/63/86/9cbd533bd37883d467fcd1bd491b3547a3532d0fbb46de2b99feeebf185e/charset_normalizer-3.4.3-cp39-cp39-win32.whl", hash = "sha256:16a8770207946ac75703458e2c743631c79c59c5890c80011d536248f8eaa432", size = 99840, upload-time = "2025-08-09T07:57:23.883Z" }, { url = "https://files.pythonhosted.org/packages/ce/d6/7e805c8e5c46ff9729c49950acc4ee0aeb55efb8b3a56687658ad10c3216/charset_normalizer-3.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:d22dbedd33326a4a5190dd4fe9e9e693ef12160c77382d9e87919bce54f3d4ca", size = 107438, upload-time = "2025-08-09T07:57:25.287Z" }, { 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 = "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 = "colorlog" version = "6.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/d3/7a/359f4d5df2353f26172b3cc39ea32daa39af8de522205f512f458923e677/colorlog-6.9.0.tar.gz", hash = "sha256:bfba54a1b93b94f54e1f4fe48395725a3d92fd2a4af702f6bd70946bdc0c6ac2", size = 16624, upload-time = "2024-10-29T18:34:51.011Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/e3/51/9b208e85196941db2f0654ad0357ca6388ab3ed67efdbfc799f35d1f83aa/colorlog-6.9.0-py3-none-any.whl", hash = "sha256:5906e71acd67cb07a71e779c47c4bcb45fb8c2993eebe9e5adcd6a6f1b283eff", size = 11424, upload-time = "2024-10-29T18:34:49.815Z" }, ] [[package]] name = "coverage" version = "7.10.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f4/2c/253cc41cd0f40b84c1c34c5363e0407d73d4a1cae005fed6db3b823175bd/coverage-7.10.3.tar.gz", hash = "sha256:812ba9250532e4a823b070b0420a36499859542335af3dca8f47fc6aa1a05619", size = 822936, upload-time = "2025-08-10T21:27:39.968Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/2f/44/e14576c34b37764c821866909788ff7463228907ab82bae188dab2b421f1/coverage-7.10.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:53808194afdf948c462215e9403cca27a81cf150d2f9b386aee4dab614ae2ffe", size = 215964, upload-time = "2025-08-10T21:25:22.828Z" }, { url = "https://files.pythonhosted.org/packages/e6/15/f4f92d9b83100903efe06c9396ee8d8bdba133399d37c186fc5b16d03a87/coverage-7.10.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f4d1b837d1abf72187a61645dbf799e0d7705aa9232924946e1f57eb09a3bf00", size = 216361, upload-time = "2025-08-10T21:25:25.603Z" }, { url = "https://files.pythonhosted.org/packages/e9/3a/c92e8cd5e89acc41cfc026dfb7acedf89661ce2ea1ee0ee13aacb6b2c20c/coverage-7.10.3-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:2a90dd4505d3cc68b847ab10c5ee81822a968b5191664e8a0801778fa60459fa", size = 243115, upload-time = "2025-08-10T21:25:27.09Z" }, { url = "https://files.pythonhosted.org/packages/23/53/c1d8c2778823b1d95ca81701bb8f42c87dc341a2f170acdf716567523490/coverage-7.10.3-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d52989685ff5bf909c430e6d7f6550937bc6d6f3e6ecb303c97a86100efd4596", size = 244927, upload-time = "2025-08-10T21:25:28.77Z" }, { url = "https://files.pythonhosted.org/packages/79/41/1e115fd809031f432b4ff8e2ca19999fb6196ab95c35ae7ad5e07c001130/coverage-7.10.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bdb558a1d97345bde3a9f4d3e8d11c9e5611f748646e9bb61d7d612a796671b5", size = 246784, upload-time = "2025-08-10T21:25:30.195Z" }, { url = "https://files.pythonhosted.org/packages/c7/b2/0eba9bdf8f1b327ae2713c74d4b7aa85451bb70622ab4e7b8c000936677c/coverage-7.10.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c9e6331a8f09cb1fc8bda032752af03c366870b48cce908875ba2620d20d0ad4", size = 244828, upload-time = "2025-08-10T21:25:31.785Z" }, { url = "https://files.pythonhosted.org/packages/1f/cc/74c56b6bf71f2a53b9aa3df8bc27163994e0861c065b4fe3a8ac290bed35/coverage-7.10.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:992f48bf35b720e174e7fae916d943599f1a66501a2710d06c5f8104e0756ee1", size = 242844, upload-time = "2025-08-10T21:25:33.37Z" }, { url = "https://files.pythonhosted.org/packages/b6/7b/ac183fbe19ac5596c223cb47af5737f4437e7566100b7e46cc29b66695a5/coverage-7.10.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c5595fc4ad6a39312c786ec3326d7322d0cf10e3ac6a6df70809910026d67cfb", size = 243721, upload-time = "2025-08-10T21:25:34.939Z" }, { url = "https://files.pythonhosted.org/packages/57/96/cb90da3b5a885af48f531905234a1e7376acfc1334242183d23154a1c285/coverage-7.10.3-cp310-cp310-win32.whl", hash = "sha256:9e92fa1f2bd5a57df9d00cf9ce1eb4ef6fccca4ceabec1c984837de55329db34", size = 218481, upload-time = "2025-08-10T21:25:36.935Z" }, { url = "https://files.pythonhosted.org/packages/15/67/1ba4c7d75745c4819c54a85766e0a88cc2bff79e1760c8a2debc34106dc2/coverage-7.10.3-cp310-cp310-win_amd64.whl", hash = "sha256:b96524d6e4a3ce6a75c56bb15dbd08023b0ae2289c254e15b9fbdddf0c577416", size = 219382, upload-time = "2025-08-10T21:25:38.267Z" }, { url = "https://files.pythonhosted.org/packages/87/04/810e506d7a19889c244d35199cbf3239a2f952b55580aa42ca4287409424/coverage-7.10.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f2ff2e2afdf0d51b9b8301e542d9c21a8d084fd23d4c8ea2b3a1b3c96f5f7397", size = 216075, upload-time = "2025-08-10T21:25:39.891Z" }, { url = "https://files.pythonhosted.org/packages/2e/50/6b3fbab034717b4af3060bdaea6b13dfdc6b1fad44b5082e2a95cd378a9a/coverage-7.10.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:18ecc5d1b9a8c570f6c9b808fa9a2b16836b3dd5414a6d467ae942208b095f85", size = 216476, upload-time = "2025-08-10T21:25:41.137Z" }, { url = "https://files.pythonhosted.org/packages/c7/96/4368c624c1ed92659812b63afc76c492be7867ac8e64b7190b88bb26d43c/coverage-7.10.3-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1af4461b25fe92889590d438905e1fc79a95680ec2a1ff69a591bb3fdb6c7157", size = 246865, upload-time = "2025-08-10T21:25:42.408Z" }, { url = "https://files.pythonhosted.org/packages/34/12/5608f76070939395c17053bf16e81fd6c06cf362a537ea9d07e281013a27/coverage-7.10.3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:3966bc9a76b09a40dc6063c8b10375e827ea5dfcaffae402dd65953bef4cba54", size = 248800, upload-time = "2025-08-10T21:25:44.098Z" }, { url = "https://files.pythonhosted.org/packages/ce/52/7cc90c448a0ad724283cbcdfd66b8d23a598861a6a22ac2b7b8696491798/coverage-7.10.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:205a95b87ef4eb303b7bc5118b47b6b6604a644bcbdb33c336a41cfc0a08c06a", size = 250904, upload-time = "2025-08-10T21:25:45.384Z" }, { url = "https://files.pythonhosted.org/packages/e6/70/9967b847063c1c393b4f4d6daab1131558ebb6b51f01e7df7150aa99f11d/coverage-7.10.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5b3801b79fb2ad61e3c7e2554bab754fc5f105626056980a2b9cf3aef4f13f84", size = 248597, upload-time = "2025-08-10T21:25:47.059Z" }, { url = "https://files.pythonhosted.org/packages/2d/fe/263307ce6878b9ed4865af42e784b42bb82d066bcf10f68defa42931c2c7/coverage-7.10.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:b0dc69c60224cda33d384572da945759756e3f06b9cdac27f302f53961e63160", size = 246647, upload-time = "2025-08-10T21:25:48.334Z" }, { url = "https://files.pythonhosted.org/packages/8e/27/d27af83ad162eba62c4eb7844a1de6cf7d9f6b185df50b0a3514a6f80ddd/coverage-7.10.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a83d4f134bab2c7ff758e6bb1541dd72b54ba295ced6a63d93efc2e20cb9b124", size = 247290, upload-time = "2025-08-10T21:25:49.945Z" }, { url = "https://files.pythonhosted.org/packages/28/83/904ff27e15467a5622dbe9ad2ed5831b4a616a62570ec5924d06477dff5a/coverage-7.10.3-cp311-cp311-win32.whl", hash = "sha256:54e409dd64e5302b2a8fdf44ec1c26f47abd1f45a2dcf67bd161873ee05a59b8", size = 218521, upload-time = "2025-08-10T21:25:51.208Z" }, { url = "https://files.pythonhosted.org/packages/b8/29/bc717b8902faaccf0ca486185f0dcab4778561a529dde51cb157acaafa16/coverage-7.10.3-cp311-cp311-win_amd64.whl", hash = "sha256:30c601610a9b23807c5e9e2e442054b795953ab85d525c3de1b1b27cebeb2117", size = 219412, upload-time = "2025-08-10T21:25:52.494Z" }, { url = "https://files.pythonhosted.org/packages/7b/7a/5a1a7028c11bb589268c656c6b3f2bbf06e0aced31bbdf7a4e94e8442cc0/coverage-7.10.3-cp311-cp311-win_arm64.whl", hash = "sha256:dabe662312a97958e932dee056f2659051d822552c0b866823e8ba1c2fe64770", size = 218091, upload-time = "2025-08-10T21:25:54.102Z" }, { url = "https://files.pythonhosted.org/packages/b8/62/13c0b66e966c43d7aa64dadc8cd2afa1f5a2bf9bb863bdabc21fb94e8b63/coverage-7.10.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:449c1e2d3a84d18bd204258a897a87bc57380072eb2aded6a5b5226046207b42", size = 216262, upload-time = "2025-08-10T21:25:55.367Z" }, { url = "https://files.pythonhosted.org/packages/b5/f0/59fdf79be7ac2f0206fc739032f482cfd3f66b18f5248108ff192741beae/coverage-7.10.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1d4f9ce50b9261ad196dc2b2e9f1fbbee21651b54c3097a25ad783679fd18294", size = 216496, upload-time = "2025-08-10T21:25:56.759Z" }, { url = "https://files.pythonhosted.org/packages/34/b1/bc83788ba31bde6a0c02eb96bbc14b2d1eb083ee073beda18753fa2c4c66/coverage-7.10.3-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:4dd4564207b160d0d45c36a10bc0a3d12563028e8b48cd6459ea322302a156d7", size = 247989, upload-time = "2025-08-10T21:25:58.067Z" }, { url = "https://files.pythonhosted.org/packages/0c/29/f8bdf88357956c844bd872e87cb16748a37234f7f48c721dc7e981145eb7/coverage-7.10.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5ca3c9530ee072b7cb6a6ea7b640bcdff0ad3b334ae9687e521e59f79b1d0437", size = 250738, upload-time = "2025-08-10T21:25:59.406Z" }, { url = "https://files.pythonhosted.org/packages/ae/df/6396301d332b71e42bbe624670af9376f63f73a455cc24723656afa95796/coverage-7.10.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b6df359e59fa243c9925ae6507e27f29c46698359f45e568fd51b9315dbbe587", size = 251868, upload-time = "2025-08-10T21:26:00.65Z" }, { url = "https://files.pythonhosted.org/packages/91/21/d760b2df6139b6ef62c9cc03afb9bcdf7d6e36ed4d078baacffa618b4c1c/coverage-7.10.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a181e4c2c896c2ff64c6312db3bda38e9ade2e1aa67f86a5628ae85873786cea", size = 249790, upload-time = "2025-08-10T21:26:02.009Z" }, { url = "https://files.pythonhosted.org/packages/69/91/5dcaa134568202397fa4023d7066d4318dc852b53b428052cd914faa05e1/coverage-7.10.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a374d4e923814e8b72b205ef6b3d3a647bb50e66f3558582eda074c976923613", size = 247907, upload-time = "2025-08-10T21:26:03.757Z" }, { url = "https://files.pythonhosted.org/packages/38/ed/70c0e871cdfef75f27faceada461206c1cc2510c151e1ef8d60a6fedda39/coverage-7.10.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:daeefff05993e5e8c6e7499a8508e7bd94502b6b9a9159c84fd1fe6bce3151cb", size = 249344, upload-time = "2025-08-10T21:26:05.11Z" }, { url = "https://files.pythonhosted.org/packages/5f/55/c8a273ed503cedc07f8a00dcd843daf28e849f0972e4c6be4c027f418ad6/coverage-7.10.3-cp312-cp312-win32.whl", hash = "sha256:187ecdcac21f9636d570e419773df7bd2fda2e7fa040f812e7f95d0bddf5f79a", size = 218693, upload-time = "2025-08-10T21:26:06.534Z" }, { url = "https://files.pythonhosted.org/packages/94/58/dd3cfb2473b85be0b6eb8c5b6d80b6fc3f8f23611e69ef745cef8cf8bad5/coverage-7.10.3-cp312-cp312-win_amd64.whl", hash = "sha256:4a50ad2524ee7e4c2a95e60d2b0b83283bdfc745fe82359d567e4f15d3823eb5", size = 219501, upload-time = "2025-08-10T21:26:08.195Z" }, { url = "https://files.pythonhosted.org/packages/56/af/7cbcbf23d46de6f24246e3f76b30df099d05636b30c53c158a196f7da3ad/coverage-7.10.3-cp312-cp312-win_arm64.whl", hash = "sha256:c112f04e075d3495fa3ed2200f71317da99608cbb2e9345bdb6de8819fc30571", size = 218135, upload-time = "2025-08-10T21:26:09.584Z" }, { url = "https://files.pythonhosted.org/packages/0a/ff/239e4de9cc149c80e9cc359fab60592365b8c4cbfcad58b8a939d18c6898/coverage-7.10.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b99e87304ffe0eb97c5308447328a584258951853807afdc58b16143a530518a", size = 216298, upload-time = "2025-08-10T21:26:10.973Z" }, { url = "https://files.pythonhosted.org/packages/56/da/28717da68f8ba68f14b9f558aaa8f3e39ada8b9a1ae4f4977c8f98b286d5/coverage-7.10.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4af09c7574d09afbc1ea7da9dcea23665c01f3bc1b1feb061dac135f98ffc53a", size = 216546, upload-time = "2025-08-10T21:26:12.616Z" }, { url = "https://files.pythonhosted.org/packages/de/bb/e1ade16b9e3f2d6c323faeb6bee8e6c23f3a72760a5d9af102ef56a656cb/coverage-7.10.3-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:488e9b50dc5d2aa9521053cfa706209e5acf5289e81edc28291a24f4e4488f46", size = 247538, upload-time = "2025-08-10T21:26:14.455Z" }, { url = "https://files.pythonhosted.org/packages/ea/2f/6ae1db51dc34db499bfe340e89f79a63bd115fc32513a7bacdf17d33cd86/coverage-7.10.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:913ceddb4289cbba3a310704a424e3fb7aac2bc0c3a23ea473193cb290cf17d4", size = 250141, upload-time = "2025-08-10T21:26:15.787Z" }, { url = "https://files.pythonhosted.org/packages/4f/ed/33efd8819895b10c66348bf26f011dd621e804866c996ea6893d682218df/coverage-7.10.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b1f91cbc78c7112ab84ed2a8defbccd90f888fcae40a97ddd6466b0bec6ae8a", size = 251415, upload-time = "2025-08-10T21:26:17.535Z" }, { url = "https://files.pythonhosted.org/packages/26/04/cb83826f313d07dc743359c9914d9bc460e0798da9a0e38b4f4fabc207ed/coverage-7.10.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b0bac054d45af7cd938834b43a9878b36ea92781bcb009eab040a5b09e9927e3", size = 249575, upload-time = "2025-08-10T21:26:18.921Z" }, { url = "https://files.pythonhosted.org/packages/2d/fd/ae963c7a8e9581c20fa4355ab8940ca272554d8102e872dbb932a644e410/coverage-7.10.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fe72cbdd12d9e0f4aca873fa6d755e103888a7f9085e4a62d282d9d5b9f7928c", size = 247466, upload-time = "2025-08-10T21:26:20.263Z" }, { url = "https://files.pythonhosted.org/packages/99/e8/b68d1487c6af370b8d5ef223c6d7e250d952c3acfbfcdbf1a773aa0da9d2/coverage-7.10.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c1e2e927ab3eadd7c244023927d646e4c15c65bb2ac7ae3c3e9537c013700d21", size = 249084, upload-time = "2025-08-10T21:26:21.638Z" }, { url = "https://files.pythonhosted.org/packages/66/4d/a0bcb561645c2c1e21758d8200443669d6560d2a2fb03955291110212ec4/coverage-7.10.3-cp313-cp313-win32.whl", hash = "sha256:24d0c13de473b04920ddd6e5da3c08831b1170b8f3b17461d7429b61cad59ae0", size = 218735, upload-time = "2025-08-10T21:26:23.009Z" }, { url = "https://files.pythonhosted.org/packages/6a/c3/78b4adddbc0feb3b223f62761e5f9b4c5a758037aaf76e0a5845e9e35e48/coverage-7.10.3-cp313-cp313-win_amd64.whl", hash = "sha256:3564aae76bce4b96e2345cf53b4c87e938c4985424a9be6a66ee902626edec4c", size = 219531, upload-time = "2025-08-10T21:26:24.474Z" }, { url = "https://files.pythonhosted.org/packages/70/1b/1229c0b2a527fa5390db58d164aa896d513a1fbb85a1b6b6676846f00552/coverage-7.10.3-cp313-cp313-win_arm64.whl", hash = "sha256:f35580f19f297455f44afcd773c9c7a058e52eb6eb170aa31222e635f2e38b87", size = 218162, upload-time = "2025-08-10T21:26:25.847Z" }, { url = "https://files.pythonhosted.org/packages/fc/26/1c1f450e15a3bf3eaecf053ff64538a2612a23f05b21d79ce03be9ff5903/coverage-7.10.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07009152f497a0464ffdf2634586787aea0e69ddd023eafb23fc38267db94b84", size = 217003, upload-time = "2025-08-10T21:26:27.231Z" }, { url = "https://files.pythonhosted.org/packages/29/96/4b40036181d8c2948454b458750960956a3c4785f26a3c29418bbbee1666/coverage-7.10.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8dd2ba5f0c7e7e8cc418be2f0c14c4d9e3f08b8fb8e4c0f83c2fe87d03eb655e", size = 217238, upload-time = "2025-08-10T21:26:28.83Z" }, { url = "https://files.pythonhosted.org/packages/62/23/8dfc52e95da20957293fb94d97397a100e63095ec1e0ef5c09dd8c6f591a/coverage-7.10.3-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1ae22b97003c74186e034a93e4f946c75fad8c0ce8d92fbbc168b5e15ee2841f", size = 258561, upload-time = "2025-08-10T21:26:30.475Z" }, { url = "https://files.pythonhosted.org/packages/59/95/00e7fcbeda3f632232f4c07dde226afe3511a7781a000aa67798feadc535/coverage-7.10.3-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:eb329f1046888a36b1dc35504d3029e1dd5afe2196d94315d18c45ee380f67d5", size = 260735, upload-time = "2025-08-10T21:26:32.333Z" }, { url = "https://files.pythonhosted.org/packages/9e/4c/f4666cbc4571804ba2a65b078ff0de600b0b577dc245389e0bc9b69ae7ca/coverage-7.10.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce01048199a91f07f96ca3074b0c14021f4fe7ffd29a3e6a188ac60a5c3a4af8", size = 262960, upload-time = "2025-08-10T21:26:33.701Z" }, { url = "https://files.pythonhosted.org/packages/c1/a5/8a9e8a7b12a290ed98b60f73d1d3e5e9ced75a4c94a0d1a671ce3ddfff2a/coverage-7.10.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:08b989a06eb9dfacf96d42b7fb4c9a22bafa370d245dc22fa839f2168c6f9fa1", size = 260515, upload-time = "2025-08-10T21:26:35.16Z" }, { url = "https://files.pythonhosted.org/packages/86/11/bb59f7f33b2cac0c5b17db0d9d0abba9c90d9eda51a6e727b43bd5fce4ae/coverage-7.10.3-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:669fe0d4e69c575c52148511029b722ba8d26e8a3129840c2ce0522e1452b256", size = 258278, upload-time = "2025-08-10T21:26:36.539Z" }, { url = "https://files.pythonhosted.org/packages/cc/22/3646f8903743c07b3e53fded0700fed06c580a980482f04bf9536657ac17/coverage-7.10.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:3262d19092771c83f3413831d9904b1ccc5f98da5de4ffa4ad67f5b20c7aaf7b", size = 259408, upload-time = "2025-08-10T21:26:37.954Z" }, { url = "https://files.pythonhosted.org/packages/d2/5c/6375e9d905da22ddea41cd85c30994b8b6f6c02e44e4c5744b76d16b026f/coverage-7.10.3-cp313-cp313t-win32.whl", hash = "sha256:cc0ee4b2ccd42cab7ee6be46d8a67d230cb33a0a7cd47a58b587a7063b6c6b0e", size = 219396, upload-time = "2025-08-10T21:26:39.426Z" }, { url = "https://files.pythonhosted.org/packages/33/3b/7da37fd14412b8c8b6e73c3e7458fef6b1b05a37f990a9776f88e7740c89/coverage-7.10.3-cp313-cp313t-win_amd64.whl", hash = "sha256:03db599f213341e2960430984e04cf35fb179724e052a3ee627a068653cf4a7c", size = 220458, upload-time = "2025-08-10T21:26:40.905Z" }, { url = "https://files.pythonhosted.org/packages/28/cc/59a9a70f17edab513c844ee7a5c63cf1057041a84cc725b46a51c6f8301b/coverage-7.10.3-cp313-cp313t-win_arm64.whl", hash = "sha256:46eae7893ba65f53c71284585a262f083ef71594f05ec5c85baf79c402369098", size = 218722, upload-time = "2025-08-10T21:26:42.362Z" }, { url = "https://files.pythonhosted.org/packages/2d/84/bb773b51a06edbf1231b47dc810a23851f2796e913b335a0fa364773b842/coverage-7.10.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:bce8b8180912914032785850d8f3aacb25ec1810f5f54afc4a8b114e7a9b55de", size = 216280, upload-time = "2025-08-10T21:26:44.132Z" }, { url = "https://files.pythonhosted.org/packages/92/a8/4d8ca9c111d09865f18d56facff64d5fa076a5593c290bd1cfc5dceb8dba/coverage-7.10.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:07790b4b37d56608536f7c1079bd1aa511567ac2966d33d5cec9cf520c50a7c8", size = 216557, upload-time = "2025-08-10T21:26:45.598Z" }, { url = "https://files.pythonhosted.org/packages/fe/b2/eb668bfc5060194bc5e1ccd6f664e8e045881cfee66c42a2aa6e6c5b26e8/coverage-7.10.3-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e79367ef2cd9166acedcbf136a458dfe9a4a2dd4d1ee95738fb2ee581c56f667", size = 247598, upload-time = "2025-08-10T21:26:47.081Z" }, { url = "https://files.pythonhosted.org/packages/fd/b0/9faa4ac62c8822219dd83e5d0e73876398af17d7305968aed8d1606d1830/coverage-7.10.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:419d2a0f769f26cb1d05e9ccbc5eab4cb5d70231604d47150867c07822acbdf4", size = 250131, upload-time = "2025-08-10T21:26:48.65Z" }, { url = "https://files.pythonhosted.org/packages/4e/90/203537e310844d4bf1bdcfab89c1e05c25025c06d8489b9e6f937ad1a9e2/coverage-7.10.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee221cf244757cdc2ac882e3062ab414b8464ad9c884c21e878517ea64b3fa26", size = 251485, upload-time = "2025-08-10T21:26:50.368Z" }, { url = "https://files.pythonhosted.org/packages/b9/b2/9d894b26bc53c70a1fe503d62240ce6564256d6d35600bdb86b80e516e7d/coverage-7.10.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c2079d8cdd6f7373d628e14b3357f24d1db02c9dc22e6a007418ca7a2be0435a", size = 249488, upload-time = "2025-08-10T21:26:52.045Z" }, { url = "https://files.pythonhosted.org/packages/b4/28/af167dbac5281ba6c55c933a0ca6675d68347d5aee39cacc14d44150b922/coverage-7.10.3-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:bd8df1f83c0703fa3ca781b02d36f9ec67ad9cb725b18d486405924f5e4270bd", size = 247419, upload-time = "2025-08-10T21:26:53.533Z" }, { url = "https://files.pythonhosted.org/packages/f4/1c/9a4ddc9f0dcb150d4cd619e1c4bb39bcf694c6129220bdd1e5895d694dda/coverage-7.10.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6b4e25e0fa335c8aa26e42a52053f3786a61cc7622b4d54ae2dad994aa754fec", size = 248917, upload-time = "2025-08-10T21:26:55.11Z" }, { url = "https://files.pythonhosted.org/packages/92/27/c6a60c7cbe10dbcdcd7fc9ee89d531dc04ea4c073800279bb269954c5a9f/coverage-7.10.3-cp314-cp314-win32.whl", hash = "sha256:d7c3d02c2866deb217dce664c71787f4b25420ea3eaf87056f44fb364a3528f5", size = 218999, upload-time = "2025-08-10T21:26:56.637Z" }, { url = "https://files.pythonhosted.org/packages/36/09/a94c1369964ab31273576615d55e7d14619a1c47a662ed3e2a2fe4dee7d4/coverage-7.10.3-cp314-cp314-win_amd64.whl", hash = "sha256:9c8916d44d9e0fe6cdb2227dc6b0edd8bc6c8ef13438bbbf69af7482d9bb9833", size = 219801, upload-time = "2025-08-10T21:26:58.207Z" }, { url = "https://files.pythonhosted.org/packages/23/59/f5cd2a80f401c01cf0f3add64a7b791b7d53fd6090a4e3e9ea52691cf3c4/coverage-7.10.3-cp314-cp314-win_arm64.whl", hash = "sha256:1007d6a2b3cf197c57105cc1ba390d9ff7f0bee215ced4dea530181e49c65ab4", size = 218381, upload-time = "2025-08-10T21:26:59.707Z" }, { url = "https://files.pythonhosted.org/packages/73/3d/89d65baf1ea39e148ee989de6da601469ba93c1d905b17dfb0b83bd39c96/coverage-7.10.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:ebc8791d346410d096818788877d675ca55c91db87d60e8f477bd41c6970ffc6", size = 217019, upload-time = "2025-08-10T21:27:01.242Z" }, { url = "https://files.pythonhosted.org/packages/7d/7d/d9850230cd9c999ce3a1e600f85c2fff61a81c301334d7a1faa1a5ba19c8/coverage-7.10.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1f4e4d8e75f6fd3c6940ebeed29e3d9d632e1f18f6fb65d33086d99d4d073241", size = 217237, upload-time = "2025-08-10T21:27:03.442Z" }, { url = "https://files.pythonhosted.org/packages/36/51/b87002d417202ab27f4a1cd6bd34ee3b78f51b3ddbef51639099661da991/coverage-7.10.3-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:24581ed69f132b6225a31b0228ae4885731cddc966f8a33fe5987288bdbbbd5e", size = 258735, upload-time = "2025-08-10T21:27:05.124Z" }, { url = "https://files.pythonhosted.org/packages/1c/02/1f8612bfcb46fc7ca64a353fff1cd4ed932bb6e0b4e0bb88b699c16794b8/coverage-7.10.3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:ec151569ddfccbf71bac8c422dce15e176167385a00cd86e887f9a80035ce8a5", size = 260901, upload-time = "2025-08-10T21:27:06.68Z" }, { url = "https://files.pythonhosted.org/packages/aa/3a/fe39e624ddcb2373908bd922756384bb70ac1c5009b0d1674eb326a3e428/coverage-7.10.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2ae8e7c56290b908ee817200c0b65929b8050bc28530b131fe7c6dfee3e7d86b", size = 263157, upload-time = "2025-08-10T21:27:08.398Z" }, { url = "https://files.pythonhosted.org/packages/5e/89/496b6d5a10fa0d0691a633bb2b2bcf4f38f0bdfcbde21ad9e32d1af328ed/coverage-7.10.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5fb742309766d7e48e9eb4dc34bc95a424707bc6140c0e7d9726e794f11b92a0", size = 260597, upload-time = "2025-08-10T21:27:10.237Z" }, { url = "https://files.pythonhosted.org/packages/b6/a6/8b5bf6a9e8c6aaeb47d5fe9687014148efc05c3588110246d5fdeef9b492/coverage-7.10.3-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:c65e2a5b32fbe1e499f1036efa6eb9cb4ea2bf6f7168d0e7a5852f3024f471b1", size = 258353, upload-time = "2025-08-10T21:27:11.773Z" }, { url = "https://files.pythonhosted.org/packages/c3/6d/ad131be74f8afd28150a07565dfbdc86592fd61d97e2dc83383d9af219f0/coverage-7.10.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d48d2cb07d50f12f4f18d2bb75d9d19e3506c26d96fffabf56d22936e5ed8f7c", size = 259504, upload-time = "2025-08-10T21:27:13.254Z" }, { url = "https://files.pythonhosted.org/packages/ec/30/fc9b5097092758cba3375a8cc4ff61774f8cd733bcfb6c9d21a60077a8d8/coverage-7.10.3-cp314-cp314t-win32.whl", hash = "sha256:dec0d9bc15ee305e09fe2cd1911d3f0371262d3cfdae05d79515d8cb712b4869", size = 219782, upload-time = "2025-08-10T21:27:14.736Z" }, { url = "https://files.pythonhosted.org/packages/72/9b/27fbf79451b1fac15c4bda6ec6e9deae27cf7c0648c1305aa21a3454f5c4/coverage-7.10.3-cp314-cp314t-win_amd64.whl", hash = "sha256:424ea93a323aa0f7f01174308ea78bde885c3089ec1bef7143a6d93c3e24ef64", size = 220898, upload-time = "2025-08-10T21:27:16.297Z" }, { url = "https://files.pythonhosted.org/packages/d1/cf/a32bbf92869cbf0b7c8b84325327bfc718ad4b6d2c63374fef3d58e39306/coverage-7.10.3-cp314-cp314t-win_arm64.whl", hash = "sha256:f5983c132a62d93d71c9ef896a0b9bf6e6828d8d2ea32611f58684fba60bba35", size = 218922, upload-time = "2025-08-10T21:27:18.22Z" }, { url = "https://files.pythonhosted.org/packages/f1/66/c06f4a93c65b6fc6578ef4f1fe51f83d61fc6f2a74ec0ce434ed288d834a/coverage-7.10.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:da749daa7e141985487e1ff90a68315b0845930ed53dc397f4ae8f8bab25b551", size = 215951, upload-time = "2025-08-10T21:27:19.815Z" }, { url = "https://files.pythonhosted.org/packages/c2/ea/cc18c70a6f72f8e4def212eaebd8388c64f29608da10b3c38c8ec76f5e49/coverage-7.10.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f3126fb6a47d287f461d9b1aa5d1a8c97034d1dffb4f452f2cf211289dae74ef", size = 216335, upload-time = "2025-08-10T21:27:21.737Z" }, { url = "https://files.pythonhosted.org/packages/f2/fb/9c6d1d67c6d54b149f06b9f374bc9ca03e4d7d7784c8cfd12ceda20e3787/coverage-7.10.3-cp39-cp39-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3da794db13cc27ca40e1ec8127945b97fab78ba548040047d54e7bfa6d442dca", size = 242772, upload-time = "2025-08-10T21:27:23.884Z" }, { url = "https://files.pythonhosted.org/packages/5a/e5/4223bdb28b992a19a13ab1410c761e2bfe92ca1e7bba8e85ee2024eeda85/coverage-7.10.3-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:4e27bebbd184ef8d1c1e092b74a2b7109dcbe2618dce6e96b1776d53b14b3fe8", size = 244596, upload-time = "2025-08-10T21:27:25.842Z" }, { url = "https://files.pythonhosted.org/packages/d2/13/d646ba28613669d487c654a760571c10128247d12d9f50e93f69542679a2/coverage-7.10.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8fd4ee2580b9fefbd301b4f8f85b62ac90d1e848bea54f89a5748cf132782118", size = 246370, upload-time = "2025-08-10T21:27:27.503Z" }, { url = "https://files.pythonhosted.org/packages/02/7c/aff99c67d8c383142b0877ee435caf493765356336211c4899257325d6c7/coverage-7.10.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6999920bdd73259ce11cabfc1307484f071ecc6abdb2ca58d98facbcefc70f16", size = 244254, upload-time = "2025-08-10T21:27:29.357Z" }, { url = "https://files.pythonhosted.org/packages/b0/13/a51ea145ed51ddfa8717bb29926d9111aca343fab38f04692a843d50be6b/coverage-7.10.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:c3623f929db885fab100cb88220a5b193321ed37e03af719efdbaf5d10b6e227", size = 242325, upload-time = "2025-08-10T21:27:30.931Z" }, { url = "https://files.pythonhosted.org/packages/d8/4b/6119be0089c89ad49d2e5a508d55a1485c878642b706a7f95b26e299137d/coverage-7.10.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:25b902c5e15dea056485d782e420bb84621cc08ee75d5131ecb3dbef8bd1365f", size = 243281, upload-time = "2025-08-10T21:27:32.815Z" }, { url = "https://files.pythonhosted.org/packages/34/c8/1b2e7e53eee4bc1304e56e10361b08197a77a26ceb07201dcc9e759ef132/coverage-7.10.3-cp39-cp39-win32.whl", hash = "sha256:f930a4d92b004b643183451fe9c8fe398ccf866ed37d172ebaccfd443a097f61", size = 218489, upload-time = "2025-08-10T21:27:34.905Z" }, { url = "https://files.pythonhosted.org/packages/dd/1e/9c0c230a199809c39e2dff0f1f889dfb04dcd07d83c1c26a8ef671660e08/coverage-7.10.3-cp39-cp39-win_amd64.whl", hash = "sha256:08e638a93c8acba13c7842953f92a33d52d73e410329acd472280d2a21a6c0e1", size = 219396, upload-time = "2025-08-10T21:27:36.61Z" }, { url = "https://files.pythonhosted.org/packages/84/19/e67f4ae24e232c7f713337f3f4f7c9c58afd0c02866fb07c7b9255a19ed7/coverage-7.10.3-py3-none-any.whl", hash = "sha256:416a8d74dc0adfd33944ba2f405897bab87b7e9e84a391e09d241956bd953ce1", size = 207921, upload-time = "2025-08-10T21:27:38.254Z" }, ] [package.optional-dependencies] toml = [ { name = "tomli", marker = "python_full_version <= '3.11'" }, ] [[package]] name = "dependency-groups" version = "1.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "packaging" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/62/55/f054de99871e7beb81935dea8a10b90cd5ce42122b1c3081d5282fdb3621/dependency_groups-1.3.1.tar.gz", hash = "sha256:78078301090517fd938c19f64a53ce98c32834dfe0dee6b88004a569a6adfefd", size = 10093, upload-time = "2025-05-02T00:34:29.452Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/99/c7/d1ec24fb280caa5a79b6b950db565dab30210a66259d17d5bb2b3a9f878d/dependency_groups-1.3.1-py3-none-any.whl", hash = "sha256:51aeaa0dfad72430fcfb7bcdbefbd75f3792e5919563077f30bc0d73f4493030", size = 8664, upload-time = "2025-05-02T00:34:27.085Z" }, ] [[package]] name = "distlib" version = "0.4.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/96/8e/709914eb2b5749865801041647dc7f4e6d00b549cfe88b65ca192995f07c/distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d", size = 614605, upload-time = "2025-07-17T16:52:00.465Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", size = 469047, upload-time = "2025-07-17T16:51:58.613Z" }, ] [[package]] name = "docutils" version = "0.21.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/ae/ed/aefcc8cd0ba62a0560c3c18c33925362d46c6075480bfa4df87b28e169a9/docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", size = 2204444, upload-time = "2024-04-23T18:57:18.24Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2", size = 587408, upload-time = "2024-04-23T18:57:14.835Z" }, ] [[package]] name = "exceptiongroup" version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] 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 = "execnet" version = "2.1.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/bb/ff/b4c0dc78fbe20c3e59c0c7334de0c27eb4001a2b2017999af398bf730817/execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3", size = 166524, upload-time = "2024-04-08T09:04:19.245Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/43/09/2aea36ff60d16dd8879bdb2f5b3ee0ba8d08cbbdcdfe870e695ce3784385/execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc", size = 40612, upload-time = "2024-04-08T09:04:17.414Z" }, ] [[package]] name = "filelock" version = "3.18.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/0a/10/c23352565a6544bdc5353e0b15fc1c563352101f30e24bf500207a54df9a/filelock-3.18.0.tar.gz", hash = "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2", size = 18075, upload-time = "2025-03-14T07:11:40.47Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/4d/36/2a115987e2d8c300a974597416d9de88f2444426de9571f4b59b2cca3acc/filelock-3.18.0-py3-none-any.whl", hash = "sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de", size = 16215, upload-time = "2025-03-14T07:11:39.145Z" }, ] [[package]] name = "flake8" version = "7.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mccabe" }, { name = "pycodestyle" }, { name = "pyflakes" }, ] sdist = { url = "https://files.pythonhosted.org/packages/9b/af/fbfe3c4b5a657d79e5c47a2827a362f9e1b763336a52f926126aa6dc7123/flake8-7.3.0.tar.gz", hash = "sha256:fe044858146b9fc69b551a4b490d69cf960fcb78ad1edcb84e7fbb1b4a8e3872", size = 48326, upload-time = "2025-06-20T19:31:35.838Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/9f/56/13ab06b4f93ca7cac71078fbe37fcea175d3216f31f85c3168a6bbd0bb9a/flake8-7.3.0-py2.py3-none-any.whl", hash = "sha256:b9696257b9ce8beb888cdbe31cf885c90d31928fe202be0889a7cdafad32f01e", size = 57922, upload-time = "2025-06-20T19:31:34.425Z" }, ] [[package]] name = "flake8-polyfill" version = "1.0.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "flake8" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e6/67/1c26634a770db5c442e361311bee73cb3a177adb2eb3f7af8953cfd9f553/flake8-polyfill-1.0.2.tar.gz", hash = "sha256:e44b087597f6da52ec6393a709e7108b2905317d0c0b744cdca6208e670d8eda", size = 7591, upload-time = "2017-12-30T13:46:58.138Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/86/b5/a43fed6fd0193585d17d6faa7b85317d4461f694aaed546098c69f856579/flake8_polyfill-1.0.2-py2.py3-none-any.whl", hash = "sha256:12be6a34ee3ab795b19ca73505e7b55826d5f6ad7230d31b18e106400169b9e9", size = 7350, upload-time = "2017-12-30T13:46:54.79Z" }, ] [[package]] name = "frozenlist" version = "1.7.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/79/b1/b64018016eeb087db503b038296fd782586432b9c077fc5c7839e9cb6ef6/frozenlist-1.7.0.tar.gz", hash = "sha256:2e310d81923c2437ea8670467121cc3e9b0f76d3043cc1d2331d56c7fb7a3a8f", size = 45078, upload-time = "2025-06-09T23:02:35.538Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/af/36/0da0a49409f6b47cc2d060dc8c9040b897b5902a8a4e37d9bc1deb11f680/frozenlist-1.7.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cc4df77d638aa2ed703b878dd093725b72a824c3c546c076e8fdf276f78ee84a", size = 81304, upload-time = "2025-06-09T22:59:46.226Z" }, { url = "https://files.pythonhosted.org/packages/77/f0/77c11d13d39513b298e267b22eb6cb559c103d56f155aa9a49097221f0b6/frozenlist-1.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:716a9973a2cc963160394f701964fe25012600f3d311f60c790400b00e568b61", size = 47735, upload-time = "2025-06-09T22:59:48.133Z" }, { url = "https://files.pythonhosted.org/packages/37/12/9d07fa18971a44150593de56b2f2947c46604819976784bcf6ea0d5db43b/frozenlist-1.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0fd1bad056a3600047fb9462cff4c5322cebc59ebf5d0a3725e0ee78955001d", size = 46775, upload-time = "2025-06-09T22:59:49.564Z" }, { url = "https://files.pythonhosted.org/packages/70/34/f73539227e06288fcd1f8a76853e755b2b48bca6747e99e283111c18bcd4/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3789ebc19cb811163e70fe2bd354cea097254ce6e707ae42e56f45e31e96cb8e", size = 224644, upload-time = "2025-06-09T22:59:51.35Z" }, { url = "https://files.pythonhosted.org/packages/fb/68/c1d9c2f4a6e438e14613bad0f2973567586610cc22dcb1e1241da71de9d3/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:af369aa35ee34f132fcfad5be45fbfcde0e3a5f6a1ec0712857f286b7d20cca9", size = 222125, upload-time = "2025-06-09T22:59:52.884Z" }, { url = "https://files.pythonhosted.org/packages/b9/d0/98e8f9a515228d708344d7c6986752be3e3192d1795f748c24bcf154ad99/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac64b6478722eeb7a3313d494f8342ef3478dff539d17002f849101b212ef97c", size = 233455, upload-time = "2025-06-09T22:59:54.74Z" }, { url = "https://files.pythonhosted.org/packages/79/df/8a11bcec5600557f40338407d3e5bea80376ed1c01a6c0910fcfdc4b8993/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f89f65d85774f1797239693cef07ad4c97fdd0639544bad9ac4b869782eb1981", size = 227339, upload-time = "2025-06-09T22:59:56.187Z" }, { url = "https://files.pythonhosted.org/packages/50/82/41cb97d9c9a5ff94438c63cc343eb7980dac4187eb625a51bdfdb7707314/frozenlist-1.7.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1073557c941395fdfcfac13eb2456cb8aad89f9de27bae29fabca8e563b12615", size = 212969, upload-time = "2025-06-09T22:59:57.604Z" }, { url = "https://files.pythonhosted.org/packages/13/47/f9179ee5ee4f55629e4f28c660b3fdf2775c8bfde8f9c53f2de2d93f52a9/frozenlist-1.7.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ed8d2fa095aae4bdc7fdd80351009a48d286635edffee66bf865e37a9125c50", size = 222862, upload-time = "2025-06-09T22:59:59.498Z" }, { url = "https://files.pythonhosted.org/packages/1a/52/df81e41ec6b953902c8b7e3a83bee48b195cb0e5ec2eabae5d8330c78038/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:24c34bea555fe42d9f928ba0a740c553088500377448febecaa82cc3e88aa1fa", size = 222492, upload-time = "2025-06-09T23:00:01.026Z" }, { url = "https://files.pythonhosted.org/packages/84/17/30d6ea87fa95a9408245a948604b82c1a4b8b3e153cea596421a2aef2754/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:69cac419ac6a6baad202c85aaf467b65ac860ac2e7f2ac1686dc40dbb52f6577", size = 238250, upload-time = "2025-06-09T23:00:03.401Z" }, { url = "https://files.pythonhosted.org/packages/8f/00/ecbeb51669e3c3df76cf2ddd66ae3e48345ec213a55e3887d216eb4fbab3/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:960d67d0611f4c87da7e2ae2eacf7ea81a5be967861e0c63cf205215afbfac59", size = 218720, upload-time = "2025-06-09T23:00:05.282Z" }, { url = "https://files.pythonhosted.org/packages/1a/c0/c224ce0e0eb31cc57f67742071bb470ba8246623c1823a7530be0e76164c/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:41be2964bd4b15bf575e5daee5a5ce7ed3115320fb3c2b71fca05582ffa4dc9e", size = 232585, upload-time = "2025-06-09T23:00:07.962Z" }, { url = "https://files.pythonhosted.org/packages/55/3c/34cb694abf532f31f365106deebdeac9e45c19304d83cf7d51ebbb4ca4d1/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:46d84d49e00c9429238a7ce02dc0be8f6d7cd0cd405abd1bebdc991bf27c15bd", size = 234248, upload-time = "2025-06-09T23:00:09.428Z" }, { url = "https://files.pythonhosted.org/packages/98/c0/2052d8b6cecda2e70bd81299e3512fa332abb6dcd2969b9c80dfcdddbf75/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:15900082e886edb37480335d9d518cec978afc69ccbc30bd18610b7c1b22a718", size = 221621, upload-time = "2025-06-09T23:00:11.32Z" }, { url = "https://files.pythonhosted.org/packages/c5/bf/7dcebae315436903b1d98ffb791a09d674c88480c158aa171958a3ac07f0/frozenlist-1.7.0-cp310-cp310-win32.whl", hash = "sha256:400ddd24ab4e55014bba442d917203c73b2846391dd42ca5e38ff52bb18c3c5e", size = 39578, upload-time = "2025-06-09T23:00:13.526Z" }, { url = "https://files.pythonhosted.org/packages/8f/5f/f69818f017fa9a3d24d1ae39763e29b7f60a59e46d5f91b9c6b21622f4cd/frozenlist-1.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:6eb93efb8101ef39d32d50bce242c84bcbddb4f7e9febfa7b524532a239b4464", size = 43830, upload-time = "2025-06-09T23:00:14.98Z" }, { url = "https://files.pythonhosted.org/packages/34/7e/803dde33760128acd393a27eb002f2020ddb8d99d30a44bfbaab31c5f08a/frozenlist-1.7.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:aa51e147a66b2d74de1e6e2cf5921890de6b0f4820b257465101d7f37b49fb5a", size = 82251, upload-time = "2025-06-09T23:00:16.279Z" }, { url = "https://files.pythonhosted.org/packages/75/a9/9c2c5760b6ba45eae11334db454c189d43d34a4c0b489feb2175e5e64277/frozenlist-1.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9b35db7ce1cd71d36ba24f80f0c9e7cff73a28d7a74e91fe83e23d27c7828750", size = 48183, upload-time = "2025-06-09T23:00:17.698Z" }, { url = "https://files.pythonhosted.org/packages/47/be/4038e2d869f8a2da165f35a6befb9158c259819be22eeaf9c9a8f6a87771/frozenlist-1.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:34a69a85e34ff37791e94542065c8416c1afbf820b68f720452f636d5fb990cd", size = 47107, upload-time = "2025-06-09T23:00:18.952Z" }, { url = "https://files.pythonhosted.org/packages/79/26/85314b8a83187c76a37183ceed886381a5f992975786f883472fcb6dc5f2/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a646531fa8d82c87fe4bb2e596f23173caec9185bfbca5d583b4ccfb95183e2", size = 237333, upload-time = "2025-06-09T23:00:20.275Z" }, { url = "https://files.pythonhosted.org/packages/1f/fd/e5b64f7d2c92a41639ffb2ad44a6a82f347787abc0c7df5f49057cf11770/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:79b2ffbba483f4ed36a0f236ccb85fbb16e670c9238313709638167670ba235f", size = 231724, upload-time = "2025-06-09T23:00:21.705Z" }, { url = "https://files.pythonhosted.org/packages/20/fb/03395c0a43a5976af4bf7534759d214405fbbb4c114683f434dfdd3128ef/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a26f205c9ca5829cbf82bb2a84b5c36f7184c4316617d7ef1b271a56720d6b30", size = 245842, upload-time = "2025-06-09T23:00:23.148Z" }, { url = "https://files.pythonhosted.org/packages/d0/15/c01c8e1dffdac5d9803507d824f27aed2ba76b6ed0026fab4d9866e82f1f/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bcacfad3185a623fa11ea0e0634aac7b691aa925d50a440f39b458e41c561d98", size = 239767, upload-time = "2025-06-09T23:00:25.103Z" }, { url = "https://files.pythonhosted.org/packages/14/99/3f4c6fe882c1f5514b6848aa0a69b20cb5e5d8e8f51a339d48c0e9305ed0/frozenlist-1.7.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:72c1b0fe8fe451b34f12dce46445ddf14bd2a5bcad7e324987194dc8e3a74c86", size = 224130, upload-time = "2025-06-09T23:00:27.061Z" }, { url = "https://files.pythonhosted.org/packages/4d/83/220a374bd7b2aeba9d0725130665afe11de347d95c3620b9b82cc2fcab97/frozenlist-1.7.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61d1a5baeaac6c0798ff6edfaeaa00e0e412d49946c53fae8d4b8e8b3566c4ae", size = 235301, upload-time = "2025-06-09T23:00:29.02Z" }, { url = "https://files.pythonhosted.org/packages/03/3c/3e3390d75334a063181625343e8daab61b77e1b8214802cc4e8a1bb678fc/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7edf5c043c062462f09b6820de9854bf28cc6cc5b6714b383149745e287181a8", size = 234606, upload-time = "2025-06-09T23:00:30.514Z" }, { url = "https://files.pythonhosted.org/packages/23/1e/58232c19608b7a549d72d9903005e2d82488f12554a32de2d5fb59b9b1ba/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:d50ac7627b3a1bd2dcef6f9da89a772694ec04d9a61b66cf87f7d9446b4a0c31", size = 248372, upload-time = "2025-06-09T23:00:31.966Z" }, { url = "https://files.pythonhosted.org/packages/c0/a4/e4a567e01702a88a74ce8a324691e62a629bf47d4f8607f24bf1c7216e7f/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ce48b2fece5aeb45265bb7a58259f45027db0abff478e3077e12b05b17fb9da7", size = 229860, upload-time = "2025-06-09T23:00:33.375Z" }, { url = "https://files.pythonhosted.org/packages/73/a6/63b3374f7d22268b41a9db73d68a8233afa30ed164c46107b33c4d18ecdd/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:fe2365ae915a1fafd982c146754e1de6ab3478def8a59c86e1f7242d794f97d5", size = 245893, upload-time = "2025-06-09T23:00:35.002Z" }, { url = "https://files.pythonhosted.org/packages/6d/eb/d18b3f6e64799a79673c4ba0b45e4cfbe49c240edfd03a68be20002eaeaa/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:45a6f2fdbd10e074e8814eb98b05292f27bad7d1883afbe009d96abdcf3bc898", size = 246323, upload-time = "2025-06-09T23:00:36.468Z" }, { url = "https://files.pythonhosted.org/packages/5a/f5/720f3812e3d06cd89a1d5db9ff6450088b8f5c449dae8ffb2971a44da506/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:21884e23cffabb157a9dd7e353779077bf5b8f9a58e9b262c6caad2ef5f80a56", size = 233149, upload-time = "2025-06-09T23:00:37.963Z" }, { url = "https://files.pythonhosted.org/packages/69/68/03efbf545e217d5db8446acfd4c447c15b7c8cf4dbd4a58403111df9322d/frozenlist-1.7.0-cp311-cp311-win32.whl", hash = "sha256:284d233a8953d7b24f9159b8a3496fc1ddc00f4db99c324bd5fb5f22d8698ea7", size = 39565, upload-time = "2025-06-09T23:00:39.753Z" }, { url = "https://files.pythonhosted.org/packages/58/17/fe61124c5c333ae87f09bb67186d65038834a47d974fc10a5fadb4cc5ae1/frozenlist-1.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:387cbfdcde2f2353f19c2f66bbb52406d06ed77519ac7ee21be0232147c2592d", size = 44019, upload-time = "2025-06-09T23:00:40.988Z" }, { url = "https://files.pythonhosted.org/packages/ef/a2/c8131383f1e66adad5f6ecfcce383d584ca94055a34d683bbb24ac5f2f1c/frozenlist-1.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3dbf9952c4bb0e90e98aec1bd992b3318685005702656bc6f67c1a32b76787f2", size = 81424, upload-time = "2025-06-09T23:00:42.24Z" }, { url = "https://files.pythonhosted.org/packages/4c/9d/02754159955088cb52567337d1113f945b9e444c4960771ea90eb73de8db/frozenlist-1.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1f5906d3359300b8a9bb194239491122e6cf1444c2efb88865426f170c262cdb", size = 47952, upload-time = "2025-06-09T23:00:43.481Z" }, { url = "https://files.pythonhosted.org/packages/01/7a/0046ef1bd6699b40acd2067ed6d6670b4db2f425c56980fa21c982c2a9db/frozenlist-1.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3dabd5a8f84573c8d10d8859a50ea2dec01eea372031929871368c09fa103478", size = 46688, upload-time = "2025-06-09T23:00:44.793Z" }, { url = "https://files.pythonhosted.org/packages/d6/a2/a910bafe29c86997363fb4c02069df4ff0b5bc39d33c5198b4e9dd42d8f8/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa57daa5917f1738064f302bf2626281a1cb01920c32f711fbc7bc36111058a8", size = 243084, upload-time = "2025-06-09T23:00:46.125Z" }, { url = "https://files.pythonhosted.org/packages/64/3e/5036af9d5031374c64c387469bfcc3af537fc0f5b1187d83a1cf6fab1639/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c193dda2b6d49f4c4398962810fa7d7c78f032bf45572b3e04dd5249dff27e08", size = 233524, upload-time = "2025-06-09T23:00:47.73Z" }, { url = "https://files.pythonhosted.org/packages/06/39/6a17b7c107a2887e781a48ecf20ad20f1c39d94b2a548c83615b5b879f28/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe2b675cf0aaa6d61bf8fbffd3c274b3c9b7b1623beb3809df8a81399a4a9c4", size = 248493, upload-time = "2025-06-09T23:00:49.742Z" }, { url = "https://files.pythonhosted.org/packages/be/00/711d1337c7327d88c44d91dd0f556a1c47fb99afc060ae0ef66b4d24793d/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8fc5d5cda37f62b262405cf9652cf0856839c4be8ee41be0afe8858f17f4c94b", size = 244116, upload-time = "2025-06-09T23:00:51.352Z" }, { url = "https://files.pythonhosted.org/packages/24/fe/74e6ec0639c115df13d5850e75722750adabdc7de24e37e05a40527ca539/frozenlist-1.7.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0d5ce521d1dd7d620198829b87ea002956e4319002ef0bc8d3e6d045cb4646e", size = 224557, upload-time = "2025-06-09T23:00:52.855Z" }, { url = "https://files.pythonhosted.org/packages/8d/db/48421f62a6f77c553575201e89048e97198046b793f4a089c79a6e3268bd/frozenlist-1.7.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:488d0a7d6a0008ca0db273c542098a0fa9e7dfaa7e57f70acef43f32b3f69dca", size = 241820, upload-time = "2025-06-09T23:00:54.43Z" }, { url = "https://files.pythonhosted.org/packages/1d/fa/cb4a76bea23047c8462976ea7b7a2bf53997a0ca171302deae9d6dd12096/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:15a7eaba63983d22c54d255b854e8108e7e5f3e89f647fc854bd77a237e767df", size = 236542, upload-time = "2025-06-09T23:00:56.409Z" }, { url = "https://files.pythonhosted.org/packages/5d/32/476a4b5cfaa0ec94d3f808f193301debff2ea42288a099afe60757ef6282/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1eaa7e9c6d15df825bf255649e05bd8a74b04a4d2baa1ae46d9c2d00b2ca2cb5", size = 249350, upload-time = "2025-06-09T23:00:58.468Z" }, { url = "https://files.pythonhosted.org/packages/8d/ba/9a28042f84a6bf8ea5dbc81cfff8eaef18d78b2a1ad9d51c7bc5b029ad16/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4389e06714cfa9d47ab87f784a7c5be91d3934cd6e9a7b85beef808297cc025", size = 225093, upload-time = "2025-06-09T23:01:00.015Z" }, { url = "https://files.pythonhosted.org/packages/bc/29/3a32959e68f9cf000b04e79ba574527c17e8842e38c91d68214a37455786/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:73bd45e1488c40b63fe5a7df892baf9e2a4d4bb6409a2b3b78ac1c6236178e01", size = 245482, upload-time = "2025-06-09T23:01:01.474Z" }, { url = "https://files.pythonhosted.org/packages/80/e8/edf2f9e00da553f07f5fa165325cfc302dead715cab6ac8336a5f3d0adc2/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:99886d98e1643269760e5fe0df31e5ae7050788dd288947f7f007209b8c33f08", size = 249590, upload-time = "2025-06-09T23:01:02.961Z" }, { url = "https://files.pythonhosted.org/packages/1c/80/9a0eb48b944050f94cc51ee1c413eb14a39543cc4f760ed12657a5a3c45a/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:290a172aae5a4c278c6da8a96222e6337744cd9c77313efe33d5670b9f65fc43", size = 237785, upload-time = "2025-06-09T23:01:05.095Z" }, { url = "https://files.pythonhosted.org/packages/f3/74/87601e0fb0369b7a2baf404ea921769c53b7ae00dee7dcfe5162c8c6dbf0/frozenlist-1.7.0-cp312-cp312-win32.whl", hash = "sha256:426c7bc70e07cfebc178bc4c2bf2d861d720c4fff172181eeb4a4c41d4ca2ad3", size = 39487, upload-time = "2025-06-09T23:01:06.54Z" }, { url = "https://files.pythonhosted.org/packages/0b/15/c026e9a9fc17585a9d461f65d8593d281fedf55fbf7eb53f16c6df2392f9/frozenlist-1.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:563b72efe5da92e02eb68c59cb37205457c977aa7a449ed1b37e6939e5c47c6a", size = 43874, upload-time = "2025-06-09T23:01:07.752Z" }, { url = "https://files.pythonhosted.org/packages/24/90/6b2cebdabdbd50367273c20ff6b57a3dfa89bd0762de02c3a1eb42cb6462/frozenlist-1.7.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee80eeda5e2a4e660651370ebffd1286542b67e268aa1ac8d6dbe973120ef7ee", size = 79791, upload-time = "2025-06-09T23:01:09.368Z" }, { url = "https://files.pythonhosted.org/packages/83/2e/5b70b6a3325363293fe5fc3ae74cdcbc3e996c2a11dde2fd9f1fb0776d19/frozenlist-1.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d1a81c85417b914139e3a9b995d4a1c84559afc839a93cf2cb7f15e6e5f6ed2d", size = 47165, upload-time = "2025-06-09T23:01:10.653Z" }, { url = "https://files.pythonhosted.org/packages/f4/25/a0895c99270ca6966110f4ad98e87e5662eab416a17e7fd53c364bf8b954/frozenlist-1.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cbb65198a9132ebc334f237d7b0df163e4de83fb4f2bdfe46c1e654bdb0c5d43", size = 45881, upload-time = "2025-06-09T23:01:12.296Z" }, { url = "https://files.pythonhosted.org/packages/19/7c/71bb0bbe0832793c601fff68cd0cf6143753d0c667f9aec93d3c323f4b55/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dab46c723eeb2c255a64f9dc05b8dd601fde66d6b19cdb82b2e09cc6ff8d8b5d", size = 232409, upload-time = "2025-06-09T23:01:13.641Z" }, { url = "https://files.pythonhosted.org/packages/c0/45/ed2798718910fe6eb3ba574082aaceff4528e6323f9a8570be0f7028d8e9/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6aeac207a759d0dedd2e40745575ae32ab30926ff4fa49b1635def65806fddee", size = 225132, upload-time = "2025-06-09T23:01:15.264Z" }, { url = "https://files.pythonhosted.org/packages/ba/e2/8417ae0f8eacb1d071d4950f32f229aa6bf68ab69aab797b72a07ea68d4f/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bd8c4e58ad14b4fa7802b8be49d47993182fdd4023393899632c88fd8cd994eb", size = 237638, upload-time = "2025-06-09T23:01:16.752Z" }, { url = "https://files.pythonhosted.org/packages/f8/b7/2ace5450ce85f2af05a871b8c8719b341294775a0a6c5585d5e6170f2ce7/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04fb24d104f425da3540ed83cbfc31388a586a7696142004c577fa61c6298c3f", size = 233539, upload-time = "2025-06-09T23:01:18.202Z" }, { url = "https://files.pythonhosted.org/packages/46/b9/6989292c5539553dba63f3c83dc4598186ab2888f67c0dc1d917e6887db6/frozenlist-1.7.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a5c505156368e4ea6b53b5ac23c92d7edc864537ff911d2fb24c140bb175e60", size = 215646, upload-time = "2025-06-09T23:01:19.649Z" }, { url = "https://files.pythonhosted.org/packages/72/31/bc8c5c99c7818293458fe745dab4fd5730ff49697ccc82b554eb69f16a24/frozenlist-1.7.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8bd7eb96a675f18aa5c553eb7ddc24a43c8c18f22e1f9925528128c052cdbe00", size = 232233, upload-time = "2025-06-09T23:01:21.175Z" }, { url = "https://files.pythonhosted.org/packages/59/52/460db4d7ba0811b9ccb85af996019f5d70831f2f5f255f7cc61f86199795/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:05579bf020096fe05a764f1f84cd104a12f78eaab68842d036772dc6d4870b4b", size = 227996, upload-time = "2025-06-09T23:01:23.098Z" }, { url = "https://files.pythonhosted.org/packages/ba/c9/f4b39e904c03927b7ecf891804fd3b4df3db29b9e487c6418e37988d6e9d/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:376b6222d114e97eeec13d46c486facd41d4f43bab626b7c3f6a8b4e81a5192c", size = 242280, upload-time = "2025-06-09T23:01:24.808Z" }, { url = "https://files.pythonhosted.org/packages/b8/33/3f8d6ced42f162d743e3517781566b8481322be321b486d9d262adf70bfb/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:0aa7e176ebe115379b5b1c95b4096fb1c17cce0847402e227e712c27bdb5a949", size = 217717, upload-time = "2025-06-09T23:01:26.28Z" }, { url = "https://files.pythonhosted.org/packages/3e/e8/ad683e75da6ccef50d0ab0c2b2324b32f84fc88ceee778ed79b8e2d2fe2e/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3fbba20e662b9c2130dc771e332a99eff5da078b2b2648153a40669a6d0e36ca", size = 236644, upload-time = "2025-06-09T23:01:27.887Z" }, { url = "https://files.pythonhosted.org/packages/b2/14/8d19ccdd3799310722195a72ac94ddc677541fb4bef4091d8e7775752360/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:f3f4410a0a601d349dd406b5713fec59b4cee7e71678d5b17edda7f4655a940b", size = 238879, upload-time = "2025-06-09T23:01:29.524Z" }, { url = "https://files.pythonhosted.org/packages/ce/13/c12bf657494c2fd1079a48b2db49fa4196325909249a52d8f09bc9123fd7/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e2cdfaaec6a2f9327bf43c933c0319a7c429058e8537c508964a133dffee412e", size = 232502, upload-time = "2025-06-09T23:01:31.287Z" }, { url = "https://files.pythonhosted.org/packages/d7/8b/e7f9dfde869825489382bc0d512c15e96d3964180c9499efcec72e85db7e/frozenlist-1.7.0-cp313-cp313-win32.whl", hash = "sha256:5fc4df05a6591c7768459caba1b342d9ec23fa16195e744939ba5914596ae3e1", size = 39169, upload-time = "2025-06-09T23:01:35.503Z" }, { url = "https://files.pythonhosted.org/packages/35/89/a487a98d94205d85745080a37860ff5744b9820a2c9acbcdd9440bfddf98/frozenlist-1.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:52109052b9791a3e6b5d1b65f4b909703984b770694d3eb64fad124c835d7cba", size = 43219, upload-time = "2025-06-09T23:01:36.784Z" }, { url = "https://files.pythonhosted.org/packages/56/d5/5c4cf2319a49eddd9dd7145e66c4866bdc6f3dbc67ca3d59685149c11e0d/frozenlist-1.7.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:a6f86e4193bb0e235ef6ce3dde5cbabed887e0b11f516ce8a0f4d3b33078ec2d", size = 84345, upload-time = "2025-06-09T23:01:38.295Z" }, { url = "https://files.pythonhosted.org/packages/a4/7d/ec2c1e1dc16b85bc9d526009961953df9cec8481b6886debb36ec9107799/frozenlist-1.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:82d664628865abeb32d90ae497fb93df398a69bb3434463d172b80fc25b0dd7d", size = 48880, upload-time = "2025-06-09T23:01:39.887Z" }, { url = "https://files.pythonhosted.org/packages/69/86/f9596807b03de126e11e7d42ac91e3d0b19a6599c714a1989a4e85eeefc4/frozenlist-1.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:912a7e8375a1c9a68325a902f3953191b7b292aa3c3fb0d71a216221deca460b", size = 48498, upload-time = "2025-06-09T23:01:41.318Z" }, { url = "https://files.pythonhosted.org/packages/5e/cb/df6de220f5036001005f2d726b789b2c0b65f2363b104bbc16f5be8084f8/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9537c2777167488d539bc5de2ad262efc44388230e5118868e172dd4a552b146", size = 292296, upload-time = "2025-06-09T23:01:42.685Z" }, { url = "https://files.pythonhosted.org/packages/83/1f/de84c642f17c8f851a2905cee2dae401e5e0daca9b5ef121e120e19aa825/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:f34560fb1b4c3e30ba35fa9a13894ba39e5acfc5f60f57d8accde65f46cc5e74", size = 273103, upload-time = "2025-06-09T23:01:44.166Z" }, { url = "https://files.pythonhosted.org/packages/88/3c/c840bfa474ba3fa13c772b93070893c6e9d5c0350885760376cbe3b6c1b3/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:acd03d224b0175f5a850edc104ac19040d35419eddad04e7cf2d5986d98427f1", size = 292869, upload-time = "2025-06-09T23:01:45.681Z" }, { url = "https://files.pythonhosted.org/packages/a6/1c/3efa6e7d5a39a1d5ef0abeb51c48fb657765794a46cf124e5aca2c7a592c/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2038310bc582f3d6a09b3816ab01737d60bf7b1ec70f5356b09e84fb7408ab1", size = 291467, upload-time = "2025-06-09T23:01:47.234Z" }, { url = "https://files.pythonhosted.org/packages/4f/00/d5c5e09d4922c395e2f2f6b79b9a20dab4b67daaf78ab92e7729341f61f6/frozenlist-1.7.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8c05e4c8e5f36e5e088caa1bf78a687528f83c043706640a92cb76cd6999384", size = 266028, upload-time = "2025-06-09T23:01:48.819Z" }, { url = "https://files.pythonhosted.org/packages/4e/27/72765be905619dfde25a7f33813ac0341eb6b076abede17a2e3fbfade0cb/frozenlist-1.7.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:765bb588c86e47d0b68f23c1bee323d4b703218037765dcf3f25c838c6fecceb", size = 284294, upload-time = "2025-06-09T23:01:50.394Z" }, { url = "https://files.pythonhosted.org/packages/88/67/c94103a23001b17808eb7dd1200c156bb69fb68e63fcf0693dde4cd6228c/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:32dc2e08c67d86d0969714dd484fd60ff08ff81d1a1e40a77dd34a387e6ebc0c", size = 281898, upload-time = "2025-06-09T23:01:52.234Z" }, { url = "https://files.pythonhosted.org/packages/42/34/a3e2c00c00f9e2a9db5653bca3fec306349e71aff14ae45ecc6d0951dd24/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:c0303e597eb5a5321b4de9c68e9845ac8f290d2ab3f3e2c864437d3c5a30cd65", size = 290465, upload-time = "2025-06-09T23:01:53.788Z" }, { url = "https://files.pythonhosted.org/packages/bb/73/f89b7fbce8b0b0c095d82b008afd0590f71ccb3dee6eee41791cf8cd25fd/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:a47f2abb4e29b3a8d0b530f7c3598badc6b134562b1a5caee867f7c62fee51e3", size = 266385, upload-time = "2025-06-09T23:01:55.769Z" }, { url = "https://files.pythonhosted.org/packages/cd/45/e365fdb554159462ca12df54bc59bfa7a9a273ecc21e99e72e597564d1ae/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:3d688126c242a6fabbd92e02633414d40f50bb6002fa4cf995a1d18051525657", size = 288771, upload-time = "2025-06-09T23:01:57.4Z" }, { url = "https://files.pythonhosted.org/packages/00/11/47b6117002a0e904f004d70ec5194fe9144f117c33c851e3d51c765962d0/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:4e7e9652b3d367c7bd449a727dc79d5043f48b88d0cbfd4f9f1060cf2b414104", size = 288206, upload-time = "2025-06-09T23:01:58.936Z" }, { url = "https://files.pythonhosted.org/packages/40/37/5f9f3c3fd7f7746082ec67bcdc204db72dad081f4f83a503d33220a92973/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1a85e345b4c43db8b842cab1feb41be5cc0b10a1830e6295b69d7310f99becaf", size = 282620, upload-time = "2025-06-09T23:02:00.493Z" }, { url = "https://files.pythonhosted.org/packages/0b/31/8fbc5af2d183bff20f21aa743b4088eac4445d2bb1cdece449ae80e4e2d1/frozenlist-1.7.0-cp313-cp313t-win32.whl", hash = "sha256:3a14027124ddb70dfcee5148979998066897e79f89f64b13328595c4bdf77c81", size = 43059, upload-time = "2025-06-09T23:02:02.072Z" }, { url = "https://files.pythonhosted.org/packages/bb/ed/41956f52105b8dbc26e457c5705340c67c8cc2b79f394b79bffc09d0e938/frozenlist-1.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3bf8010d71d4507775f658e9823210b7427be36625b387221642725b515dcf3e", size = 47516, upload-time = "2025-06-09T23:02:03.779Z" }, { url = "https://files.pythonhosted.org/packages/dd/b1/ee59496f51cd244039330015d60f13ce5a54a0f2bd8d79e4a4a375ab7469/frozenlist-1.7.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cea3dbd15aea1341ea2de490574a4a37ca080b2ae24e4b4f4b51b9057b4c3630", size = 82434, upload-time = "2025-06-09T23:02:05.195Z" }, { url = "https://files.pythonhosted.org/packages/75/e1/d518391ce36a6279b3fa5bc14327dde80bcb646bb50d059c6ca0756b8d05/frozenlist-1.7.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7d536ee086b23fecc36c2073c371572374ff50ef4db515e4e503925361c24f71", size = 48232, upload-time = "2025-06-09T23:02:07.728Z" }, { url = "https://files.pythonhosted.org/packages/b7/8d/a0d04f28b6e821a9685c22e67b5fb798a5a7b68752f104bfbc2dccf080c4/frozenlist-1.7.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dfcebf56f703cb2e346315431699f00db126d158455e513bd14089d992101e44", size = 47186, upload-time = "2025-06-09T23:02:09.243Z" }, { url = "https://files.pythonhosted.org/packages/93/3a/a5334c0535c8b7c78eeabda1579179e44fe3d644e07118e59a2276dedaf1/frozenlist-1.7.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:974c5336e61d6e7eb1ea5b929cb645e882aadab0095c5a6974a111e6479f8878", size = 226617, upload-time = "2025-06-09T23:02:10.949Z" }, { url = "https://files.pythonhosted.org/packages/0a/67/8258d971f519dc3f278c55069a775096cda6610a267b53f6248152b72b2f/frozenlist-1.7.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c70db4a0ab5ab20878432c40563573229a7ed9241506181bba12f6b7d0dc41cb", size = 224179, upload-time = "2025-06-09T23:02:12.603Z" }, { url = "https://files.pythonhosted.org/packages/fc/89/8225905bf889b97c6d935dd3aeb45668461e59d415cb019619383a8a7c3b/frozenlist-1.7.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1137b78384eebaf70560a36b7b229f752fb64d463d38d1304939984d5cb887b6", size = 235783, upload-time = "2025-06-09T23:02:14.678Z" }, { url = "https://files.pythonhosted.org/packages/54/6e/ef52375aa93d4bc510d061df06205fa6dcfd94cd631dd22956b09128f0d4/frozenlist-1.7.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e793a9f01b3e8b5c0bc646fb59140ce0efcc580d22a3468d70766091beb81b35", size = 229210, upload-time = "2025-06-09T23:02:16.313Z" }, { url = "https://files.pythonhosted.org/packages/ee/55/62c87d1a6547bfbcd645df10432c129100c5bd0fd92a384de6e3378b07c1/frozenlist-1.7.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:74739ba8e4e38221d2c5c03d90a7e542cb8ad681915f4ca8f68d04f810ee0a87", size = 215994, upload-time = "2025-06-09T23:02:17.9Z" }, { url = "https://files.pythonhosted.org/packages/45/d2/263fea1f658b8ad648c7d94d18a87bca7e8c67bd6a1bbf5445b1bd5b158c/frozenlist-1.7.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e63344c4e929b1a01e29bc184bbb5fd82954869033765bfe8d65d09e336a677", size = 225122, upload-time = "2025-06-09T23:02:19.479Z" }, { url = "https://files.pythonhosted.org/packages/7b/22/7145e35d12fb368d92124f679bea87309495e2e9ddf14c6533990cb69218/frozenlist-1.7.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2ea2a7369eb76de2217a842f22087913cdf75f63cf1307b9024ab82dfb525938", size = 224019, upload-time = "2025-06-09T23:02:20.969Z" }, { url = "https://files.pythonhosted.org/packages/44/1e/7dae8c54301beb87bcafc6144b9a103bfd2c8f38078c7902984c9a0c4e5b/frozenlist-1.7.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:836b42f472a0e006e02499cef9352ce8097f33df43baaba3e0a28a964c26c7d2", size = 239925, upload-time = "2025-06-09T23:02:22.466Z" }, { url = "https://files.pythonhosted.org/packages/4b/1e/99c93e54aa382e949a98976a73b9b20c3aae6d9d893f31bbe4991f64e3a8/frozenlist-1.7.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e22b9a99741294b2571667c07d9f8cceec07cb92aae5ccda39ea1b6052ed4319", size = 220881, upload-time = "2025-06-09T23:02:24.521Z" }, { url = "https://files.pythonhosted.org/packages/5e/9c/ca5105fa7fb5abdfa8837581be790447ae051da75d32f25c8f81082ffc45/frozenlist-1.7.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:9a19e85cc503d958abe5218953df722748d87172f71b73cf3c9257a91b999890", size = 234046, upload-time = "2025-06-09T23:02:26.206Z" }, { url = "https://files.pythonhosted.org/packages/8d/4d/e99014756093b4ddbb67fb8f0df11fe7a415760d69ace98e2ac6d5d43402/frozenlist-1.7.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f22dac33bb3ee8fe3e013aa7b91dc12f60d61d05b7fe32191ffa84c3aafe77bd", size = 235756, upload-time = "2025-06-09T23:02:27.79Z" }, { url = "https://files.pythonhosted.org/packages/8b/72/a19a40bcdaa28a51add2aaa3a1a294ec357f36f27bd836a012e070c5e8a5/frozenlist-1.7.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9ccec739a99e4ccf664ea0775149f2749b8a6418eb5b8384b4dc0a7d15d304cb", size = 222894, upload-time = "2025-06-09T23:02:29.848Z" }, { url = "https://files.pythonhosted.org/packages/08/49/0042469993e023a758af81db68c76907cd29e847d772334d4d201cbe9a42/frozenlist-1.7.0-cp39-cp39-win32.whl", hash = "sha256:b3950f11058310008a87757f3eee16a8e1ca97979833239439586857bc25482e", size = 39848, upload-time = "2025-06-09T23:02:31.413Z" }, { url = "https://files.pythonhosted.org/packages/5a/45/827d86ee475c877f5f766fbc23fb6acb6fada9e52f1c9720e2ba3eae32da/frozenlist-1.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:43a82fce6769c70f2f5a06248b614a7d268080a9d20f7457ef10ecee5af82b63", size = 44102, upload-time = "2025-06-09T23:02:32.808Z" }, { url = "https://files.pythonhosted.org/packages/ee/45/b82e3c16be2182bff01179db177fe144d58b5dc787a7d4492c6ed8b9317f/frozenlist-1.7.0-py3-none-any.whl", hash = "sha256:9a5af342e34f7e97caf8c995864c7a396418ae2859cc6fdf1b1073020d516a7e", size = 13106, upload-time = "2025-06-09T23:02:34.204Z" }, ] [[package]] name = "furo" version = "2025.7.19" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "accessible-pygments" }, { name = "beautifulsoup4" }, { name = "pygments" }, { name = "sphinx", version = "7.4.7", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" }, { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "sphinx-basic-ng" }, ] sdist = { url = "https://files.pythonhosted.org/packages/d0/69/312cd100fa45ddaea5a588334d2defa331ff427bcb61f5fe2ae61bdc3762/furo-2025.7.19.tar.gz", hash = "sha256:4164b2cafcf4023a59bb3c594e935e2516f6b9d35e9a5ea83d8f6b43808fe91f", size = 1662054, upload-time = "2025-07-19T10:52:09.754Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/3a/34/2b07b72bee02a63241d654f5d8af87a2de977c59638eec41ca356ab915cd/furo-2025.7.19-py3-none-any.whl", hash = "sha256:bdea869822dfd2b494ea84c0973937e35d1575af088b6721a29c7f7878adc9e3", size = 342175, upload-time = "2025-07-19T10:52:02.399Z" }, ] [[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 = "identify" version = "2.6.13" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/82/ca/ffbabe3635bb839aa36b3a893c91a9b0d368cb4d8073e03a12896970af82/identify-2.6.13.tar.gz", hash = "sha256:da8d6c828e773620e13bfa86ea601c5a5310ba4bcd65edf378198b56a1f9fb32", size = 99243, upload-time = "2025-08-09T19:35:00.6Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/e7/ce/461b60a3ee109518c055953729bf9ed089a04db895d47e95444071dcdef2/identify-2.6.13-py2.py3-none-any.whl", hash = "sha256:60381139b3ae39447482ecc406944190f690d4a2997f2584062089848361b33b", size = 99153, upload-time = "2025-08-09T19:34:59.1Z" }, ] [[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 = "imagesize" version = "1.4.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/a7/84/62473fb57d61e31fef6e36d64a179c8781605429fd927b5dd608c997be31/imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a", size = 1280026, upload-time = "2022-07-01T12:21:05.687Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b", size = 8769, upload-time = "2022-07-01T12:21:02.467Z" }, ] [[package]] name = "importlib-metadata" version = "8.7.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "zipp", marker = "python_full_version < '3.11'" }, ] 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 = "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 = "markdown-it-py" version = "3.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mdurl" }, ] sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528, upload-time = "2023-06-03T06:41:11.019Z" }, ] [[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" }, { url = "https://files.pythonhosted.org/packages/a7/ea/9b1530c3fdeeca613faeb0fb5cbcf2389d816072fab72a71b45749ef6062/MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a", size = 14344, upload-time = "2024-10-18T15:21:43.721Z" }, { url = "https://files.pythonhosted.org/packages/4b/c2/fbdbfe48848e7112ab05e627e718e854d20192b674952d9042ebd8c9e5de/MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff", size = 12389, upload-time = "2024-10-18T15:21:44.666Z" }, { url = "https://files.pythonhosted.org/packages/f0/25/7a7c6e4dbd4f867d95d94ca15449e91e52856f6ed1905d58ef1de5e211d0/MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13", size = 21607, upload-time = "2024-10-18T15:21:45.452Z" }, { url = "https://files.pythonhosted.org/packages/53/8f/f339c98a178f3c1e545622206b40986a4c3307fe39f70ccd3d9df9a9e425/MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144", size = 20728, upload-time = "2024-10-18T15:21:46.295Z" }, { url = "https://files.pythonhosted.org/packages/1a/03/8496a1a78308456dbd50b23a385c69b41f2e9661c67ea1329849a598a8f9/MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29", size = 20826, upload-time = "2024-10-18T15:21:47.134Z" }, { url = "https://files.pythonhosted.org/packages/e6/cf/0a490a4bd363048c3022f2f475c8c05582179bb179defcee4766fb3dcc18/MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0", size = 21843, upload-time = "2024-10-18T15:21:48.334Z" }, { url = "https://files.pythonhosted.org/packages/19/a3/34187a78613920dfd3cdf68ef6ce5e99c4f3417f035694074beb8848cd77/MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0", size = 21219, upload-time = "2024-10-18T15:21:49.587Z" }, { url = "https://files.pythonhosted.org/packages/17/d8/5811082f85bb88410ad7e452263af048d685669bbbfb7b595e8689152498/MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178", size = 20946, upload-time = "2024-10-18T15:21:50.441Z" }, { url = "https://files.pythonhosted.org/packages/7c/31/bd635fb5989440d9365c5e3c47556cfea121c7803f5034ac843e8f37c2f2/MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f", size = 15063, upload-time = "2024-10-18T15:21:51.385Z" }, { url = "https://files.pythonhosted.org/packages/b3/73/085399401383ce949f727afec55ec3abd76648d04b9f22e1c0e99cb4bec3/MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a", size = 15506, upload-time = "2024-10-18T15:21:52.974Z" }, ] [[package]] name = "mccabe" version = "0.7.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/e7/ff/0ffefdcac38932a54d2b5eed4e0ba8a408f215002cd178ad1df0f2806ff8/mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", size = 9658, upload-time = "2022-01-24T01:14:51.113Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e", size = 7350, upload-time = "2022-01-24T01:14:49.62Z" }, ] [[package]] name = "mdit-py-plugins" version = "0.4.2" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.10'", ] dependencies = [ { name = "markdown-it-py", marker = "python_full_version < '3.10'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/19/03/a2ecab526543b152300717cf232bb4bb8605b6edb946c845016fa9c9c9fd/mdit_py_plugins-0.4.2.tar.gz", hash = "sha256:5f2cd1fdb606ddf152d37ec30e46101a60512bc0e5fa1a7002c36647b09e26b5", size = 43542, upload-time = "2024-09-09T20:27:49.564Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/a7/f7/7782a043553ee469c1ff49cfa1cdace2d6bf99a1f333cf38676b3ddf30da/mdit_py_plugins-0.4.2-py3-none-any.whl", hash = "sha256:0c673c3f889399a33b95e88d2f0d111b4447bdfea7f237dab2d488f459835636", size = 55316, upload-time = "2024-09-09T20:27:48.397Z" }, ] [[package]] name = "mdit-py-plugins" version = "0.5.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.11'", "python_full_version == '3.10.*'", ] dependencies = [ { name = "markdown-it-py", marker = "python_full_version >= '3.10'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b2/fd/a756d36c0bfba5f6e39a1cdbdbfdd448dc02692467d83816dff4592a1ebc/mdit_py_plugins-0.5.0.tar.gz", hash = "sha256:f4918cb50119f50446560513a8e311d574ff6aaed72606ddae6d35716fe809c6", size = 44655, upload-time = "2025-08-11T07:25:49.083Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl", hash = "sha256:07a08422fc1936a5d26d146759e9155ea466e842f5ab2f7d2266dd084c8dab1f", size = 57205, upload-time = "2025-08-11T07:25:47.597Z" }, ] [[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 = "multidict" version = "6.6.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/69/7f/0652e6ed47ab288e3756ea9c0df8b14950781184d4bd7883f4d87dd41245/multidict-6.6.4.tar.gz", hash = "sha256:d2d4e4787672911b48350df02ed3fa3fffdc2f2e8ca06dd6afdf34189b76a9dd", size = 101843, upload-time = "2025-08-11T12:08:48.217Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/eb/6b/86f353088c1358e76fd30b0146947fddecee812703b604ee901e85cd2a80/multidict-6.6.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b8aa6f0bd8125ddd04a6593437bad6a7e70f300ff4180a531654aa2ab3f6d58f", size = 77054, upload-time = "2025-08-11T12:06:02.99Z" }, { url = "https://files.pythonhosted.org/packages/19/5d/c01dc3d3788bb877bd7f5753ea6eb23c1beeca8044902a8f5bfb54430f63/multidict-6.6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b9e5853bbd7264baca42ffc53391b490d65fe62849bf2c690fa3f6273dbcd0cb", size = 44914, upload-time = "2025-08-11T12:06:05.264Z" }, { url = "https://files.pythonhosted.org/packages/46/44/964dae19ea42f7d3e166474d8205f14bb811020e28bc423d46123ddda763/multidict-6.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0af5f9dee472371e36d6ae38bde009bd8ce65ac7335f55dcc240379d7bed1495", size = 44601, upload-time = "2025-08-11T12:06:06.627Z" }, { url = "https://files.pythonhosted.org/packages/31/20/0616348a1dfb36cb2ab33fc9521de1f27235a397bf3f59338e583afadd17/multidict-6.6.4-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:d24f351e4d759f5054b641c81e8291e5d122af0fca5c72454ff77f7cbe492de8", size = 224821, upload-time = "2025-08-11T12:06:08.06Z" }, { url = "https://files.pythonhosted.org/packages/14/26/5d8923c69c110ff51861af05bd27ca6783011b96725d59ccae6d9daeb627/multidict-6.6.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:db6a3810eec08280a172a6cd541ff4a5f6a97b161d93ec94e6c4018917deb6b7", size = 242608, upload-time = "2025-08-11T12:06:09.697Z" }, { url = "https://files.pythonhosted.org/packages/5c/cc/e2ad3ba9459aa34fa65cf1f82a5c4a820a2ce615aacfb5143b8817f76504/multidict-6.6.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a1b20a9d56b2d81e2ff52ecc0670d583eaabaa55f402e8d16dd062373dbbe796", size = 222324, upload-time = "2025-08-11T12:06:10.905Z" }, { url = "https://files.pythonhosted.org/packages/19/db/4ed0f65701afbc2cb0c140d2d02928bb0fe38dd044af76e58ad7c54fd21f/multidict-6.6.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8c9854df0eaa610a23494c32a6f44a3a550fb398b6b51a56e8c6b9b3689578db", size = 253234, upload-time = "2025-08-11T12:06:12.658Z" }, { url = "https://files.pythonhosted.org/packages/94/c1/5160c9813269e39ae14b73debb907bfaaa1beee1762da8c4fb95df4764ed/multidict-6.6.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4bb7627fd7a968f41905a4d6343b0d63244a0623f006e9ed989fa2b78f4438a0", size = 251613, upload-time = "2025-08-11T12:06:13.97Z" }, { url = "https://files.pythonhosted.org/packages/05/a9/48d1bd111fc2f8fb98b2ed7f9a115c55a9355358432a19f53c0b74d8425d/multidict-6.6.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:caebafea30ed049c57c673d0b36238b1748683be2593965614d7b0e99125c877", size = 241649, upload-time = "2025-08-11T12:06:15.204Z" }, { url = "https://files.pythonhosted.org/packages/85/2a/f7d743df0019408768af8a70d2037546a2be7b81fbb65f040d76caafd4c5/multidict-6.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ad887a8250eb47d3ab083d2f98db7f48098d13d42eb7a3b67d8a5c795f224ace", size = 239238, upload-time = "2025-08-11T12:06:16.467Z" }, { url = "https://files.pythonhosted.org/packages/cb/b8/4f4bb13323c2d647323f7919201493cf48ebe7ded971717bfb0f1a79b6bf/multidict-6.6.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:ed8358ae7d94ffb7c397cecb62cbac9578a83ecefc1eba27b9090ee910e2efb6", size = 233517, upload-time = "2025-08-11T12:06:18.107Z" }, { url = "https://files.pythonhosted.org/packages/33/29/4293c26029ebfbba4f574febd2ed01b6f619cfa0d2e344217d53eef34192/multidict-6.6.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:ecab51ad2462197a4c000b6d5701fc8585b80eecb90583635d7e327b7b6923eb", size = 243122, upload-time = "2025-08-11T12:06:19.361Z" }, { url = "https://files.pythonhosted.org/packages/20/60/a1c53628168aa22447bfde3a8730096ac28086704a0d8c590f3b63388d0c/multidict-6.6.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:c5c97aa666cf70e667dfa5af945424ba1329af5dd988a437efeb3a09430389fb", size = 248992, upload-time = "2025-08-11T12:06:20.661Z" }, { url = "https://files.pythonhosted.org/packages/a3/3b/55443a0c372f33cae5d9ec37a6a973802884fa0ab3586659b197cf8cc5e9/multidict-6.6.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:9a950b7cf54099c1209f455ac5970b1ea81410f2af60ed9eb3c3f14f0bfcf987", size = 243708, upload-time = "2025-08-11T12:06:21.891Z" }, { url = "https://files.pythonhosted.org/packages/7c/60/a18c6900086769312560b2626b18e8cca22d9e85b1186ba77f4755b11266/multidict-6.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:163c7ea522ea9365a8a57832dea7618e6cbdc3cd75f8c627663587459a4e328f", size = 237498, upload-time = "2025-08-11T12:06:23.206Z" }, { url = "https://files.pythonhosted.org/packages/11/3d/8bdd8bcaff2951ce2affccca107a404925a2beafedd5aef0b5e4a71120a6/multidict-6.6.4-cp310-cp310-win32.whl", hash = "sha256:17d2cbbfa6ff20821396b25890f155f40c986f9cfbce5667759696d83504954f", size = 41415, upload-time = "2025-08-11T12:06:24.77Z" }, { url = "https://files.pythonhosted.org/packages/c0/53/cab1ad80356a4cd1b685a254b680167059b433b573e53872fab245e9fc95/multidict-6.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:ce9a40fbe52e57e7edf20113a4eaddfacac0561a0879734e636aa6d4bb5e3fb0", size = 46046, upload-time = "2025-08-11T12:06:25.893Z" }, { url = "https://files.pythonhosted.org/packages/cf/9a/874212b6f5c1c2d870d0a7adc5bb4cfe9b0624fa15cdf5cf757c0f5087ae/multidict-6.6.4-cp310-cp310-win_arm64.whl", hash = "sha256:01d0959807a451fe9fdd4da3e139cb5b77f7328baf2140feeaf233e1d777b729", size = 43147, upload-time = "2025-08-11T12:06:27.534Z" }, { url = "https://files.pythonhosted.org/packages/6b/7f/90a7f01e2d005d6653c689039977f6856718c75c5579445effb7e60923d1/multidict-6.6.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c7a0e9b561e6460484318a7612e725df1145d46b0ef57c6b9866441bf6e27e0c", size = 76472, upload-time = "2025-08-11T12:06:29.006Z" }, { url = "https://files.pythonhosted.org/packages/54/a3/bed07bc9e2bb302ce752f1dabc69e884cd6a676da44fb0e501b246031fdd/multidict-6.6.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6bf2f10f70acc7a2446965ffbc726e5fc0b272c97a90b485857e5c70022213eb", size = 44634, upload-time = "2025-08-11T12:06:30.374Z" }, { url = "https://files.pythonhosted.org/packages/a7/4b/ceeb4f8f33cf81277da464307afeaf164fb0297947642585884f5cad4f28/multidict-6.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:66247d72ed62d5dd29752ffc1d3b88f135c6a8de8b5f63b7c14e973ef5bda19e", size = 44282, upload-time = "2025-08-11T12:06:31.958Z" }, { url = "https://files.pythonhosted.org/packages/03/35/436a5da8702b06866189b69f655ffdb8f70796252a8772a77815f1812679/multidict-6.6.4-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:105245cc6b76f51e408451a844a54e6823bbd5a490ebfe5bdfc79798511ceded", size = 229696, upload-time = "2025-08-11T12:06:33.087Z" }, { url = "https://files.pythonhosted.org/packages/b6/0e/915160be8fecf1fca35f790c08fb74ca684d752fcba62c11daaf3d92c216/multidict-6.6.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cbbc54e58b34c3bae389ef00046be0961f30fef7cb0dd9c7756aee376a4f7683", size = 246665, upload-time = "2025-08-11T12:06:34.448Z" }, { url = "https://files.pythonhosted.org/packages/08/ee/2f464330acd83f77dcc346f0b1a0eaae10230291450887f96b204b8ac4d3/multidict-6.6.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:56c6b3652f945c9bc3ac6c8178cd93132b8d82dd581fcbc3a00676c51302bc1a", size = 225485, upload-time = "2025-08-11T12:06:35.672Z" }, { url = "https://files.pythonhosted.org/packages/71/cc/9a117f828b4d7fbaec6adeed2204f211e9caf0a012692a1ee32169f846ae/multidict-6.6.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b95494daf857602eccf4c18ca33337dd2be705bccdb6dddbfc9d513e6addb9d9", size = 257318, upload-time = "2025-08-11T12:06:36.98Z" }, { url = "https://files.pythonhosted.org/packages/25/77/62752d3dbd70e27fdd68e86626c1ae6bccfebe2bb1f84ae226363e112f5a/multidict-6.6.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e5b1413361cef15340ab9dc61523e653d25723e82d488ef7d60a12878227ed50", size = 254689, upload-time = "2025-08-11T12:06:38.233Z" }, { url = "https://files.pythonhosted.org/packages/00/6e/fac58b1072a6fc59af5e7acb245e8754d3e1f97f4f808a6559951f72a0d4/multidict-6.6.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e167bf899c3d724f9662ef00b4f7fef87a19c22b2fead198a6f68b263618df52", size = 246709, upload-time = "2025-08-11T12:06:39.517Z" }, { url = "https://files.pythonhosted.org/packages/01/ef/4698d6842ef5e797c6db7744b0081e36fb5de3d00002cc4c58071097fac3/multidict-6.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:aaea28ba20a9026dfa77f4b80369e51cb767c61e33a2d4043399c67bd95fb7c6", size = 243185, upload-time = "2025-08-11T12:06:40.796Z" }, { url = "https://files.pythonhosted.org/packages/aa/c9/d82e95ae1d6e4ef396934e9b0e942dfc428775f9554acf04393cce66b157/multidict-6.6.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:8c91cdb30809a96d9ecf442ec9bc45e8cfaa0f7f8bdf534e082c2443a196727e", size = 237838, upload-time = "2025-08-11T12:06:42.595Z" }, { url = "https://files.pythonhosted.org/packages/57/cf/f94af5c36baaa75d44fab9f02e2a6bcfa0cd90acb44d4976a80960759dbc/multidict-6.6.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1a0ccbfe93ca114c5d65a2471d52d8829e56d467c97b0e341cf5ee45410033b3", size = 246368, upload-time = "2025-08-11T12:06:44.304Z" }, { url = "https://files.pythonhosted.org/packages/4a/fe/29f23460c3d995f6a4b678cb2e9730e7277231b981f0b234702f0177818a/multidict-6.6.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:55624b3f321d84c403cb7d8e6e982f41ae233d85f85db54ba6286f7295dc8a9c", size = 253339, upload-time = "2025-08-11T12:06:45.597Z" }, { url = "https://files.pythonhosted.org/packages/29/b6/fd59449204426187b82bf8a75f629310f68c6adc9559dc922d5abe34797b/multidict-6.6.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:4a1fb393a2c9d202cb766c76208bd7945bc194eba8ac920ce98c6e458f0b524b", size = 246933, upload-time = "2025-08-11T12:06:46.841Z" }, { url = "https://files.pythonhosted.org/packages/19/52/d5d6b344f176a5ac3606f7a61fb44dc746e04550e1a13834dff722b8d7d6/multidict-6.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:43868297a5759a845fa3a483fb4392973a95fb1de891605a3728130c52b8f40f", size = 242225, upload-time = "2025-08-11T12:06:48.588Z" }, { url = "https://files.pythonhosted.org/packages/ec/d3/5b2281ed89ff4d5318d82478a2a2450fcdfc3300da48ff15c1778280ad26/multidict-6.6.4-cp311-cp311-win32.whl", hash = "sha256:ed3b94c5e362a8a84d69642dbeac615452e8af9b8eb825b7bc9f31a53a1051e2", size = 41306, upload-time = "2025-08-11T12:06:49.95Z" }, { url = "https://files.pythonhosted.org/packages/74/7d/36b045c23a1ab98507aefd44fd8b264ee1dd5e5010543c6fccf82141ccef/multidict-6.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:d8c112f7a90d8ca5d20213aa41eac690bb50a76da153e3afb3886418e61cb22e", size = 46029, upload-time = "2025-08-11T12:06:51.082Z" }, { url = "https://files.pythonhosted.org/packages/0f/5e/553d67d24432c5cd52b49047f2d248821843743ee6d29a704594f656d182/multidict-6.6.4-cp311-cp311-win_arm64.whl", hash = "sha256:3bb0eae408fa1996d87247ca0d6a57b7fc1dcf83e8a5c47ab82c558c250d4adf", size = 43017, upload-time = "2025-08-11T12:06:52.243Z" }, { url = "https://files.pythonhosted.org/packages/05/f6/512ffd8fd8b37fb2680e5ac35d788f1d71bbaf37789d21a820bdc441e565/multidict-6.6.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0ffb87be160942d56d7b87b0fdf098e81ed565add09eaa1294268c7f3caac4c8", size = 76516, upload-time = "2025-08-11T12:06:53.393Z" }, { url = "https://files.pythonhosted.org/packages/99/58/45c3e75deb8855c36bd66cc1658007589662ba584dbf423d01df478dd1c5/multidict-6.6.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d191de6cbab2aff5de6c5723101705fd044b3e4c7cfd587a1929b5028b9714b3", size = 45394, upload-time = "2025-08-11T12:06:54.555Z" }, { url = "https://files.pythonhosted.org/packages/fd/ca/e8c4472a93a26e4507c0b8e1f0762c0d8a32de1328ef72fd704ef9cc5447/multidict-6.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:38a0956dd92d918ad5feff3db8fcb4a5eb7dba114da917e1a88475619781b57b", size = 43591, upload-time = "2025-08-11T12:06:55.672Z" }, { url = "https://files.pythonhosted.org/packages/05/51/edf414f4df058574a7265034d04c935aa84a89e79ce90fcf4df211f47b16/multidict-6.6.4-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:6865f6d3b7900ae020b495d599fcf3765653bc927951c1abb959017f81ae8287", size = 237215, upload-time = "2025-08-11T12:06:57.213Z" }, { url = "https://files.pythonhosted.org/packages/c8/45/8b3d6dbad8cf3252553cc41abea09ad527b33ce47a5e199072620b296902/multidict-6.6.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a2088c126b6f72db6c9212ad827d0ba088c01d951cee25e758c450da732c138", size = 258299, upload-time = "2025-08-11T12:06:58.946Z" }, { url = "https://files.pythonhosted.org/packages/3c/e8/8ca2e9a9f5a435fc6db40438a55730a4bf4956b554e487fa1b9ae920f825/multidict-6.6.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0f37bed7319b848097085d7d48116f545985db988e2256b2e6f00563a3416ee6", size = 242357, upload-time = "2025-08-11T12:07:00.301Z" }, { url = "https://files.pythonhosted.org/packages/0f/84/80c77c99df05a75c28490b2af8f7cba2a12621186e0a8b0865d8e745c104/multidict-6.6.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:01368e3c94032ba6ca0b78e7ccb099643466cf24f8dc8eefcfdc0571d56e58f9", size = 268369, upload-time = "2025-08-11T12:07:01.638Z" }, { url = "https://files.pythonhosted.org/packages/0d/e9/920bfa46c27b05fb3e1ad85121fd49f441492dca2449c5bcfe42e4565d8a/multidict-6.6.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8fe323540c255db0bffee79ad7f048c909f2ab0edb87a597e1c17da6a54e493c", size = 269341, upload-time = "2025-08-11T12:07:02.943Z" }, { url = "https://files.pythonhosted.org/packages/af/65/753a2d8b05daf496f4a9c367fe844e90a1b2cac78e2be2c844200d10cc4c/multidict-6.6.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8eb3025f17b0a4c3cd08cda49acf312a19ad6e8a4edd9dbd591e6506d999402", size = 256100, upload-time = "2025-08-11T12:07:04.564Z" }, { url = "https://files.pythonhosted.org/packages/09/54/655be13ae324212bf0bc15d665a4e34844f34c206f78801be42f7a0a8aaa/multidict-6.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bbc14f0365534d35a06970d6a83478b249752e922d662dc24d489af1aa0d1be7", size = 253584, upload-time = "2025-08-11T12:07:05.914Z" }, { url = "https://files.pythonhosted.org/packages/5c/74/ab2039ecc05264b5cec73eb018ce417af3ebb384ae9c0e9ed42cb33f8151/multidict-6.6.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:75aa52fba2d96bf972e85451b99d8e19cc37ce26fd016f6d4aa60da9ab2b005f", size = 251018, upload-time = "2025-08-11T12:07:08.301Z" }, { url = "https://files.pythonhosted.org/packages/af/0a/ccbb244ac848e56c6427f2392741c06302bbfba49c0042f1eb3c5b606497/multidict-6.6.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4fefd4a815e362d4f011919d97d7b4a1e566f1dde83dc4ad8cfb5b41de1df68d", size = 251477, upload-time = "2025-08-11T12:07:10.248Z" }, { url = "https://files.pythonhosted.org/packages/0e/b0/0ed49bba775b135937f52fe13922bc64a7eaf0a3ead84a36e8e4e446e096/multidict-6.6.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:db9801fe021f59a5b375ab778973127ca0ac52429a26e2fd86aa9508f4d26eb7", size = 263575, upload-time = "2025-08-11T12:07:11.928Z" }, { url = "https://files.pythonhosted.org/packages/3e/d9/7fb85a85e14de2e44dfb6a24f03c41e2af8697a6df83daddb0e9b7569f73/multidict-6.6.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a650629970fa21ac1fb06ba25dabfc5b8a2054fcbf6ae97c758aa956b8dba802", size = 259649, upload-time = "2025-08-11T12:07:13.244Z" }, { url = "https://files.pythonhosted.org/packages/03/9e/b3a459bcf9b6e74fa461a5222a10ff9b544cb1cd52fd482fb1b75ecda2a2/multidict-6.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:452ff5da78d4720d7516a3a2abd804957532dd69296cb77319c193e3ffb87e24", size = 251505, upload-time = "2025-08-11T12:07:14.57Z" }, { url = "https://files.pythonhosted.org/packages/86/a2/8022f78f041dfe6d71e364001a5cf987c30edfc83c8a5fb7a3f0974cff39/multidict-6.6.4-cp312-cp312-win32.whl", hash = "sha256:8c2fcb12136530ed19572bbba61b407f655e3953ba669b96a35036a11a485793", size = 41888, upload-time = "2025-08-11T12:07:15.904Z" }, { url = "https://files.pythonhosted.org/packages/c7/eb/d88b1780d43a56db2cba24289fa744a9d216c1a8546a0dc3956563fd53ea/multidict-6.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:047d9425860a8c9544fed1b9584f0c8bcd31bcde9568b047c5e567a1025ecd6e", size = 46072, upload-time = "2025-08-11T12:07:17.045Z" }, { url = "https://files.pythonhosted.org/packages/9f/16/b929320bf5750e2d9d4931835a4c638a19d2494a5b519caaaa7492ebe105/multidict-6.6.4-cp312-cp312-win_arm64.whl", hash = "sha256:14754eb72feaa1e8ae528468f24250dd997b8e2188c3d2f593f9eba259e4b364", size = 43222, upload-time = "2025-08-11T12:07:18.328Z" }, { url = "https://files.pythonhosted.org/packages/3a/5d/e1db626f64f60008320aab00fbe4f23fc3300d75892a3381275b3d284580/multidict-6.6.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f46a6e8597f9bd71b31cc708195d42b634c8527fecbcf93febf1052cacc1f16e", size = 75848, upload-time = "2025-08-11T12:07:19.912Z" }, { url = "https://files.pythonhosted.org/packages/4c/aa/8b6f548d839b6c13887253af4e29c939af22a18591bfb5d0ee6f1931dae8/multidict-6.6.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:22e38b2bc176c5eb9c0a0e379f9d188ae4cd8b28c0f53b52bce7ab0a9e534657", size = 45060, upload-time = "2025-08-11T12:07:21.163Z" }, { url = "https://files.pythonhosted.org/packages/eb/c6/f5e97e5d99a729bc2aa58eb3ebfa9f1e56a9b517cc38c60537c81834a73f/multidict-6.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5df8afd26f162da59e218ac0eefaa01b01b2e6cd606cffa46608f699539246da", size = 43269, upload-time = "2025-08-11T12:07:22.392Z" }, { url = "https://files.pythonhosted.org/packages/dc/31/d54eb0c62516776f36fe67f84a732f97e0b0e12f98d5685bebcc6d396910/multidict-6.6.4-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:49517449b58d043023720aa58e62b2f74ce9b28f740a0b5d33971149553d72aa", size = 237158, upload-time = "2025-08-11T12:07:23.636Z" }, { url = "https://files.pythonhosted.org/packages/c4/1c/8a10c1c25b23156e63b12165a929d8eb49a6ed769fdbefb06e6f07c1e50d/multidict-6.6.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ae9408439537c5afdca05edd128a63f56a62680f4b3c234301055d7a2000220f", size = 257076, upload-time = "2025-08-11T12:07:25.049Z" }, { url = "https://files.pythonhosted.org/packages/ad/86/90e20b5771d6805a119e483fd3d1e8393e745a11511aebca41f0da38c3e2/multidict-6.6.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:87a32d20759dc52a9e850fe1061b6e41ab28e2998d44168a8a341b99ded1dba0", size = 240694, upload-time = "2025-08-11T12:07:26.458Z" }, { url = "https://files.pythonhosted.org/packages/e7/49/484d3e6b535bc0555b52a0a26ba86e4d8d03fd5587d4936dc59ba7583221/multidict-6.6.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:52e3c8d43cdfff587ceedce9deb25e6ae77daba560b626e97a56ddcad3756879", size = 266350, upload-time = "2025-08-11T12:07:27.94Z" }, { url = "https://files.pythonhosted.org/packages/bf/b4/aa4c5c379b11895083d50021e229e90c408d7d875471cb3abf721e4670d6/multidict-6.6.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ad8850921d3a8d8ff6fbef790e773cecfc260bbfa0566998980d3fa8f520bc4a", size = 267250, upload-time = "2025-08-11T12:07:29.303Z" }, { url = "https://files.pythonhosted.org/packages/80/e5/5e22c5bf96a64bdd43518b1834c6d95a4922cc2066b7d8e467dae9b6cee6/multidict-6.6.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:497a2954adc25c08daff36f795077f63ad33e13f19bfff7736e72c785391534f", size = 254900, upload-time = "2025-08-11T12:07:30.764Z" }, { url = "https://files.pythonhosted.org/packages/17/38/58b27fed927c07035abc02befacab42491e7388ca105e087e6e0215ead64/multidict-6.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:024ce601f92d780ca1617ad4be5ac15b501cc2414970ffa2bb2bbc2bd5a68fa5", size = 252355, upload-time = "2025-08-11T12:07:32.205Z" }, { url = "https://files.pythonhosted.org/packages/d0/a1/dad75d23a90c29c02b5d6f3d7c10ab36c3197613be5d07ec49c7791e186c/multidict-6.6.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:a693fc5ed9bdd1c9e898013e0da4dcc640de7963a371c0bd458e50e046bf6438", size = 250061, upload-time = "2025-08-11T12:07:33.623Z" }, { url = "https://files.pythonhosted.org/packages/b8/1a/ac2216b61c7f116edab6dc3378cca6c70dc019c9a457ff0d754067c58b20/multidict-6.6.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:190766dac95aab54cae5b152a56520fd99298f32a1266d66d27fdd1b5ac00f4e", size = 249675, upload-time = "2025-08-11T12:07:34.958Z" }, { url = "https://files.pythonhosted.org/packages/d4/79/1916af833b800d13883e452e8e0977c065c4ee3ab7a26941fbfdebc11895/multidict-6.6.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:34d8f2a5ffdceab9dcd97c7a016deb2308531d5f0fced2bb0c9e1df45b3363d7", size = 261247, upload-time = "2025-08-11T12:07:36.588Z" }, { url = "https://files.pythonhosted.org/packages/c5/65/d1f84fe08ac44a5fc7391cbc20a7cedc433ea616b266284413fd86062f8c/multidict-6.6.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:59e8d40ab1f5a8597abcef00d04845155a5693b5da00d2c93dbe88f2050f2812", size = 257960, upload-time = "2025-08-11T12:07:39.735Z" }, { url = "https://files.pythonhosted.org/packages/13/b5/29ec78057d377b195ac2c5248c773703a6b602e132a763e20ec0457e7440/multidict-6.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:467fe64138cfac771f0e949b938c2e1ada2b5af22f39692aa9258715e9ea613a", size = 250078, upload-time = "2025-08-11T12:07:41.525Z" }, { url = "https://files.pythonhosted.org/packages/c4/0e/7e79d38f70a872cae32e29b0d77024bef7834b0afb406ddae6558d9e2414/multidict-6.6.4-cp313-cp313-win32.whl", hash = "sha256:14616a30fe6d0a48d0a48d1a633ab3b8bec4cf293aac65f32ed116f620adfd69", size = 41708, upload-time = "2025-08-11T12:07:43.405Z" }, { url = "https://files.pythonhosted.org/packages/9d/34/746696dffff742e97cd6a23da953e55d0ea51fa601fa2ff387b3edcfaa2c/multidict-6.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:40cd05eaeb39e2bc8939451f033e57feaa2ac99e07dbca8afe2be450a4a3b6cf", size = 45912, upload-time = "2025-08-11T12:07:45.082Z" }, { url = "https://files.pythonhosted.org/packages/c7/87/3bac136181e271e29170d8d71929cdeddeb77f3e8b6a0c08da3a8e9da114/multidict-6.6.4-cp313-cp313-win_arm64.whl", hash = "sha256:f6eb37d511bfae9e13e82cb4d1af36b91150466f24d9b2b8a9785816deb16605", size = 43076, upload-time = "2025-08-11T12:07:46.746Z" }, { url = "https://files.pythonhosted.org/packages/64/94/0a8e63e36c049b571c9ae41ee301ada29c3fee9643d9c2548d7d558a1d99/multidict-6.6.4-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:6c84378acd4f37d1b507dfa0d459b449e2321b3ba5f2338f9b085cf7a7ba95eb", size = 82812, upload-time = "2025-08-11T12:07:48.402Z" }, { url = "https://files.pythonhosted.org/packages/25/1a/be8e369dfcd260d2070a67e65dd3990dd635cbd735b98da31e00ea84cd4e/multidict-6.6.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0e0558693063c75f3d952abf645c78f3c5dfdd825a41d8c4d8156fc0b0da6e7e", size = 48313, upload-time = "2025-08-11T12:07:49.679Z" }, { url = "https://files.pythonhosted.org/packages/26/5a/dd4ade298674b2f9a7b06a32c94ffbc0497354df8285f27317c66433ce3b/multidict-6.6.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3f8e2384cb83ebd23fd07e9eada8ba64afc4c759cd94817433ab8c81ee4b403f", size = 46777, upload-time = "2025-08-11T12:07:51.318Z" }, { url = "https://files.pythonhosted.org/packages/89/db/98aa28bc7e071bfba611ac2ae803c24e96dd3a452b4118c587d3d872c64c/multidict-6.6.4-cp313-cp313t-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:f996b87b420995a9174b2a7c1a8daf7db4750be6848b03eb5e639674f7963773", size = 229321, upload-time = "2025-08-11T12:07:52.965Z" }, { url = "https://files.pythonhosted.org/packages/c7/bc/01ddda2a73dd9d167bd85d0e8ef4293836a8f82b786c63fb1a429bc3e678/multidict-6.6.4-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cc356250cffd6e78416cf5b40dc6a74f1edf3be8e834cf8862d9ed5265cf9b0e", size = 249954, upload-time = "2025-08-11T12:07:54.423Z" }, { url = "https://files.pythonhosted.org/packages/06/78/6b7c0f020f9aa0acf66d0ab4eb9f08375bac9a50ff5e3edb1c4ccd59eafc/multidict-6.6.4-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:dadf95aa862714ea468a49ad1e09fe00fcc9ec67d122f6596a8d40caf6cec7d0", size = 228612, upload-time = "2025-08-11T12:07:55.914Z" }, { url = "https://files.pythonhosted.org/packages/00/44/3faa416f89b2d5d76e9d447296a81521e1c832ad6e40b92f990697b43192/multidict-6.6.4-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7dd57515bebffd8ebd714d101d4c434063322e4fe24042e90ced41f18b6d3395", size = 257528, upload-time = "2025-08-11T12:07:57.371Z" }, { url = "https://files.pythonhosted.org/packages/05/5f/77c03b89af0fcb16f018f668207768191fb9dcfb5e3361a5e706a11db2c9/multidict-6.6.4-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:967af5f238ebc2eb1da4e77af5492219fbd9b4b812347da39a7b5f5c72c0fa45", size = 256329, upload-time = "2025-08-11T12:07:58.844Z" }, { url = "https://files.pythonhosted.org/packages/cf/e9/ed750a2a9afb4f8dc6f13dc5b67b514832101b95714f1211cd42e0aafc26/multidict-6.6.4-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2a4c6875c37aae9794308ec43e3530e4aa0d36579ce38d89979bbf89582002bb", size = 247928, upload-time = "2025-08-11T12:08:01.037Z" }, { url = "https://files.pythonhosted.org/packages/1f/b5/e0571bc13cda277db7e6e8a532791d4403dacc9850006cb66d2556e649c0/multidict-6.6.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:7f683a551e92bdb7fac545b9c6f9fa2aebdeefa61d607510b3533286fcab67f5", size = 245228, upload-time = "2025-08-11T12:08:02.96Z" }, { url = "https://files.pythonhosted.org/packages/f3/a3/69a84b0eccb9824491f06368f5b86e72e4af54c3067c37c39099b6687109/multidict-6.6.4-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:3ba5aaf600edaf2a868a391779f7a85d93bed147854925f34edd24cc70a3e141", size = 235869, upload-time = "2025-08-11T12:08:04.746Z" }, { url = "https://files.pythonhosted.org/packages/a9/9d/28802e8f9121a6a0804fa009debf4e753d0a59969ea9f70be5f5fdfcb18f/multidict-6.6.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:580b643b7fd2c295d83cad90d78419081f53fd532d1f1eb67ceb7060f61cff0d", size = 243446, upload-time = "2025-08-11T12:08:06.332Z" }, { url = "https://files.pythonhosted.org/packages/38/ea/6c98add069b4878c1d66428a5f5149ddb6d32b1f9836a826ac764b9940be/multidict-6.6.4-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:37b7187197da6af3ee0b044dbc9625afd0c885f2800815b228a0e70f9a7f473d", size = 252299, upload-time = "2025-08-11T12:08:07.931Z" }, { url = "https://files.pythonhosted.org/packages/3a/09/8fe02d204473e14c0af3affd50af9078839dfca1742f025cca765435d6b4/multidict-6.6.4-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e1b93790ed0bc26feb72e2f08299691ceb6da5e9e14a0d13cc74f1869af327a0", size = 246926, upload-time = "2025-08-11T12:08:09.467Z" }, { url = "https://files.pythonhosted.org/packages/37/3d/7b1e10d774a6df5175ecd3c92bff069e77bed9ec2a927fdd4ff5fe182f67/multidict-6.6.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a506a77ddee1efcca81ecbeae27ade3e09cdf21a8ae854d766c2bb4f14053f92", size = 243383, upload-time = "2025-08-11T12:08:10.981Z" }, { url = "https://files.pythonhosted.org/packages/50/b0/a6fae46071b645ae98786ab738447de1ef53742eaad949f27e960864bb49/multidict-6.6.4-cp313-cp313t-win32.whl", hash = "sha256:f93b2b2279883d1d0a9e1bd01f312d6fc315c5e4c1f09e112e4736e2f650bc4e", size = 47775, upload-time = "2025-08-11T12:08:12.439Z" }, { url = "https://files.pythonhosted.org/packages/b2/0a/2436550b1520091af0600dff547913cb2d66fbac27a8c33bc1b1bccd8d98/multidict-6.6.4-cp313-cp313t-win_amd64.whl", hash = "sha256:6d46a180acdf6e87cc41dc15d8f5c2986e1e8739dc25dbb7dac826731ef381a4", size = 53100, upload-time = "2025-08-11T12:08:13.823Z" }, { url = "https://files.pythonhosted.org/packages/97/ea/43ac51faff934086db9c072a94d327d71b7d8b40cd5dcb47311330929ef0/multidict-6.6.4-cp313-cp313t-win_arm64.whl", hash = "sha256:756989334015e3335d087a27331659820d53ba432befdef6a718398b0a8493ad", size = 45501, upload-time = "2025-08-11T12:08:15.173Z" }, { url = "https://files.pythonhosted.org/packages/d4/d3/f04c5db316caee9b5b2cbba66270b358c922a959855995bedde87134287c/multidict-6.6.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:af7618b591bae552b40dbb6f93f5518328a949dac626ee75927bba1ecdeea9f4", size = 76977, upload-time = "2025-08-11T12:08:16.667Z" }, { url = "https://files.pythonhosted.org/packages/70/39/a6200417d883e510728ab3caec02d3b66ff09e1c85e0aab2ba311abfdf06/multidict-6.6.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b6819f83aef06f560cb15482d619d0e623ce9bf155115150a85ab11b8342a665", size = 44878, upload-time = "2025-08-11T12:08:18.157Z" }, { url = "https://files.pythonhosted.org/packages/6f/7e/815be31ed35571b137d65232816f61513fcd97b2717d6a9d7800b5a0c6e0/multidict-6.6.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4d09384e75788861e046330308e7af54dd306aaf20eb760eb1d0de26b2bea2cb", size = 44546, upload-time = "2025-08-11T12:08:19.694Z" }, { url = "https://files.pythonhosted.org/packages/e2/f1/21b5bff6a8c3e2aff56956c241941ace6b8820e1abe6b12d3c52868a773d/multidict-6.6.4-cp39-cp39-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:a59c63061f1a07b861c004e53869eb1211ffd1a4acbca330e3322efa6dd02978", size = 223020, upload-time = "2025-08-11T12:08:21.554Z" }, { url = "https://files.pythonhosted.org/packages/15/59/37083f1dd3439979a0ffeb1906818d978d88b4cc7f4600a9f89b1cb6713c/multidict-6.6.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:350f6b0fe1ced61e778037fdc7613f4051c8baf64b1ee19371b42a3acdb016a0", size = 240528, upload-time = "2025-08-11T12:08:23.45Z" }, { url = "https://files.pythonhosted.org/packages/d1/f0/f054d123c87784307a27324c829eb55bcfd2e261eb785fcabbd832c8dc4a/multidict-6.6.4-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0c5cbac6b55ad69cb6aa17ee9343dfbba903118fd530348c330211dc7aa756d1", size = 219540, upload-time = "2025-08-11T12:08:24.965Z" }, { url = "https://files.pythonhosted.org/packages/e8/26/8f78ce17b7118149c17f238f28fba2a850b660b860f9b024a34d0191030f/multidict-6.6.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:630f70c32b8066ddfd920350bc236225814ad94dfa493fe1910ee17fe4365cbb", size = 251182, upload-time = "2025-08-11T12:08:26.511Z" }, { url = "https://files.pythonhosted.org/packages/00/c3/a21466322d69f6594fe22d9379200f99194d21c12a5bbf8c2a39a46b83b6/multidict-6.6.4-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f8d4916a81697faec6cb724a273bd5457e4c6c43d82b29f9dc02c5542fd21fc9", size = 249371, upload-time = "2025-08-11T12:08:28.075Z" }, { url = "https://files.pythonhosted.org/packages/c2/8e/2e673124eb05cf8dc82e9265eccde01a36bcbd3193e27799b8377123c976/multidict-6.6.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e42332cf8276bb7645d310cdecca93a16920256a5b01bebf747365f86a1675b", size = 239235, upload-time = "2025-08-11T12:08:29.937Z" }, { url = "https://files.pythonhosted.org/packages/2b/2d/bdd9f05e7c89e30a4b0e4faf0681a30748f8d1310f68cfdc0e3571e75bd5/multidict-6.6.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f3be27440f7644ab9a13a6fc86f09cdd90b347c3c5e30c6d6d860de822d7cb53", size = 237410, upload-time = "2025-08-11T12:08:31.872Z" }, { url = "https://files.pythonhosted.org/packages/46/4c/3237b83f8ca9a2673bb08fc340c15da005a80f5cc49748b587c8ae83823b/multidict-6.6.4-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:21f216669109e02ef3e2415ede07f4f8987f00de8cdfa0cc0b3440d42534f9f0", size = 232979, upload-time = "2025-08-11T12:08:33.399Z" }, { url = "https://files.pythonhosted.org/packages/55/a6/a765decff625ae9bc581aed303cd1837955177dafc558859a69f56f56ba8/multidict-6.6.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:d9890d68c45d1aeac5178ded1d1cccf3bc8d7accf1f976f79bf63099fb16e4bd", size = 240979, upload-time = "2025-08-11T12:08:35.02Z" }, { url = "https://files.pythonhosted.org/packages/6b/2d/9c75975cb0c66ea33cae1443bb265b2b3cd689bffcbc68872565f401da23/multidict-6.6.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:edfdcae97cdc5d1a89477c436b61f472c4d40971774ac4729c613b4b133163cb", size = 246849, upload-time = "2025-08-11T12:08:37.038Z" }, { url = "https://files.pythonhosted.org/packages/3e/71/d21ac0843c1d8751fb5dcf8a1f436625d39d4577bc27829799d09b419af7/multidict-6.6.4-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:0b2e886624be5773e69cf32bcb8534aecdeb38943520b240fed3d5596a430f2f", size = 241798, upload-time = "2025-08-11T12:08:38.669Z" }, { url = "https://files.pythonhosted.org/packages/94/3d/1d8911e53092837bd11b1c99d71de3e2a9a26f8911f864554677663242aa/multidict-6.6.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:be5bf4b3224948032a845d12ab0f69f208293742df96dc14c4ff9b09e508fc17", size = 235315, upload-time = "2025-08-11T12:08:40.266Z" }, { url = "https://files.pythonhosted.org/packages/86/c5/4b758df96376f73e936b1942c6c2dfc17e37ed9d5ff3b01a811496966ca0/multidict-6.6.4-cp39-cp39-win32.whl", hash = "sha256:10a68a9191f284fe9d501fef4efe93226e74df92ce7a24e301371293bd4918ae", size = 41434, upload-time = "2025-08-11T12:08:41.965Z" }, { url = "https://files.pythonhosted.org/packages/58/16/f1dfa2a0f25f2717a5e9e5fe8fd30613f7fe95e3530cec8d11f5de0b709c/multidict-6.6.4-cp39-cp39-win_amd64.whl", hash = "sha256:ee25f82f53262f9ac93bd7e58e47ea1bdcc3393cef815847e397cba17e284210", size = 46186, upload-time = "2025-08-11T12:08:43.367Z" }, { url = "https://files.pythonhosted.org/packages/88/7d/a0568bac65438c494cb6950b29f394d875a796a237536ac724879cf710c9/multidict-6.6.4-cp39-cp39-win_arm64.whl", hash = "sha256:f9867e55590e0855bcec60d4f9a092b69476db64573c9fe17e92b0c50614c16a", size = 43115, upload-time = "2025-08-11T12:08:45.126Z" }, { url = "https://files.pythonhosted.org/packages/fd/69/b547032297c7e63ba2af494edba695d781af8a0c6e89e4d06cf848b21d80/multidict-6.6.4-py3-none-any.whl", hash = "sha256:27d8f8e125c07cb954e54d75d04905a9bba8a439c1d84aca94949d4d03d8601c", size = 12313, upload-time = "2025-08-11T12:08:46.891Z" }, ] [[package]] name = "myst-parser" version = "3.0.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.10'", ] dependencies = [ { name = "docutils", marker = "python_full_version < '3.10'" }, { name = "jinja2", marker = "python_full_version < '3.10'" }, { name = "markdown-it-py", marker = "python_full_version < '3.10'" }, { name = "mdit-py-plugins", version = "0.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, { name = "pyyaml", marker = "python_full_version < '3.10'" }, { name = "sphinx", version = "7.4.7", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/49/64/e2f13dac02f599980798c01156393b781aec983b52a6e4057ee58f07c43a/myst_parser-3.0.1.tar.gz", hash = "sha256:88f0cb406cb363b077d176b51c476f62d60604d68a8dcdf4832e080441301a87", size = 92392, upload-time = "2024-04-28T20:22:42.116Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/e2/de/21aa8394f16add8f7427f0a1326ccd2b3a2a8a3245c9252bc5ac034c6155/myst_parser-3.0.1-py3-none-any.whl", hash = "sha256:6457aaa33a5d474aca678b8ead9b3dc298e89c68e67012e73146ea6fd54babf1", size = 83163, upload-time = "2024-04-28T20:22:39.985Z" }, ] [[package]] name = "myst-parser" version = "4.0.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.11'", "python_full_version == '3.10.*'", ] dependencies = [ { name = "docutils", marker = "python_full_version >= '3.10'" }, { name = "jinja2", marker = "python_full_version >= '3.10'" }, { name = "markdown-it-py", marker = "python_full_version >= '3.10'" }, { name = "mdit-py-plugins", version = "0.5.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, { name = "pyyaml", marker = "python_full_version >= '3.10'" }, { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" }, { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/66/a5/9626ba4f73555b3735ad86247a8077d4603aa8628537687c839ab08bfe44/myst_parser-4.0.1.tar.gz", hash = "sha256:5cfea715e4f3574138aecbf7d54132296bfd72bb614d31168f48c477a830a7c4", size = 93985, upload-time = "2025-02-12T10:53:03.833Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/5f/df/76d0321c3797b54b60fef9ec3bd6f4cfd124b9e422182156a1dd418722cf/myst_parser-4.0.1-py3-none-any.whl", hash = "sha256:9134e88959ec3b5780aedf8a99680ea242869d012e8821db3126d427edc9c95d", size = 84579, upload-time = "2025-02-12T10:53:02.078Z" }, ] [[package]] name = "nodeenv" version = "1.9.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437, upload-time = "2024-06-04T18:44:11.171Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, ] [[package]] name = "nox" version = "2025.5.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "argcomplete" }, { name = "attrs" }, { name = "colorlog" }, { name = "dependency-groups" }, { name = "packaging" }, { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "virtualenv" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b4/80/47712208c410defec169992e57c179f0f4d92f5dd17ba8daca50a8077e23/nox-2025.5.1.tar.gz", hash = "sha256:2a571dfa7a58acc726521ac3cd8184455ebcdcbf26401c7b737b5bc6701427b2", size = 4023334, upload-time = "2025-05-01T16:35:48.056Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/a6/be/7b423b02b09eb856beffe76fe8c4121c99852db74dd12a422dcb72d1134e/nox-2025.5.1-py3-none-any.whl", hash = "sha256:56abd55cf37ff523c254fcec4d152ed51e5fe80e2ab8317221d8b828ac970a31", size = 71753, upload-time = "2025-05-01T16:35:46.037Z" }, ] [[package]] name = "nox-poetry" version = "1.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "build" }, { name = "nox" }, { name = "packaging" }, { name = "tomlkit" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ea/4c/f7c12b83c5fccf41c792fae79b5017eacd82ab9b3b273c1f6a811516b826/nox_poetry-1.2.0.tar.gz", hash = "sha256:2531a404e3a21eb73fc1a587a548506a8e2c4c1e6e7ef0c1d0d8d6453b7e5d26", size = 12555, upload-time = "2025-02-25T15:33:19.617Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/08/a8/e521f42d622b8d01475400558553391b37a528555734e06da4039cca678f/nox_poetry-1.2.0-py3-none-any.whl", hash = "sha256:266eea7a0ab3cad7f4121ecc05b76945036db3b67e6e347557f05010a18e2682", size = 11647, upload-time = "2025-02-25T15:33:18.58Z" }, ] [[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 = "pbr" version = "6.1.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "setuptools" }, ] sdist = { url = "https://files.pythonhosted.org/packages/01/d2/510cc0d218e753ba62a1bc1434651db3cd797a9716a0a66cc714cb4f0935/pbr-6.1.1.tar.gz", hash = "sha256:93ea72ce6989eb2eed99d0f75721474f69ad88128afdef5ac377eb797c4bf76b", size = 125702, upload-time = "2025-02-04T14:28:06.514Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/47/ac/684d71315abc7b1214d59304e23a982472967f6bf4bde5a98f1503f648dc/pbr-6.1.1-py2.py3-none-any.whl", hash = "sha256:38d4daea5d9fa63b3f626131b9d34947fd0c8be9b05a29276870580050a25a76", size = 108997, upload-time = "2025-02-04T14:28:03.168Z" }, ] [[package]] name = "platformdirs" version = "4.3.8" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/fe/8b/3c73abc9c759ecd3f1f7ceff6685840859e8070c4d947c93fae71f6a0bf2/platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc", size = 21362, upload-time = "2025-05-07T22:47:42.121Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4", size = 18567, upload-time = "2025-05-07T22:47:40.376Z" }, ] [[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 = "pre-commit" version = "4.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cfgv" }, { name = "identify" }, { name = "nodeenv" }, { name = "pyyaml" }, { name = "virtualenv" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ff/29/7cf5bbc236333876e4b41f56e06857a87937ce4bf91e117a6991a2dbb02a/pre_commit-4.3.0.tar.gz", hash = "sha256:499fe450cc9d42e9d58e606262795ecb64dd05438943c62b66f6a8673da30b16", size = 193792, upload-time = "2025-08-09T18:56:14.651Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/5b/a5/987a405322d78a73b66e39e4a90e4ef156fd7141bf71df987e50717c321b/pre_commit-4.3.0-py2.py3-none-any.whl", hash = "sha256:2b0747ad7e6e967169136edffee14c16e148a778a54e4f967921aa1ebf2308d8", size = 220965, upload-time = "2025-08-09T18:56:13.192Z" }, ] [[package]] name = "pre-commit-uv" version = "4.1.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pre-commit" }, { name = "uv" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b1/6c/c3c1d01698c8abb0b546defc0304971fa7fb2ba84ad35587b9dad095d73f/pre_commit_uv-4.1.4.tar.gz", hash = "sha256:3db606a79b226127b27dbbd8381b78c0e30de3ac775a8492c576a68e9250535c", size = 6493, upload-time = "2024-10-29T23:07:28.918Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/f1/70/1b65f9118ef64f6ffe5d57a67170bbff25d4f4a3d1cb78e8ed3392e16114/pre_commit_uv-4.1.4-py3-none-any.whl", hash = "sha256:7f01fb494fa1caa5097d20a38f71df7cea0209197b2564699cef9b3f3aa9d135", size = 5578, upload-time = "2024-10-29T23:07:27.128Z" }, ] [[package]] name = "propcache" version = "0.3.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/a6/16/43264e4a779dd8588c21a70f0709665ee8f611211bdd2c87d952cfa7c776/propcache-0.3.2.tar.gz", hash = "sha256:20d7d62e4e7ef05f221e0db2856b979540686342e7dd9973b815599c7057e168", size = 44139, upload-time = "2025-06-09T22:56:06.081Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ab/14/510deed325e262afeb8b360043c5d7c960da7d3ecd6d6f9496c9c56dc7f4/propcache-0.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:22d9962a358aedbb7a2e36187ff273adeaab9743373a272976d2e348d08c7770", size = 73178, upload-time = "2025-06-09T22:53:40.126Z" }, { url = "https://files.pythonhosted.org/packages/cd/4e/ad52a7925ff01c1325653a730c7ec3175a23f948f08626a534133427dcff/propcache-0.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0d0fda578d1dc3f77b6b5a5dce3b9ad69a8250a891760a548df850a5e8da87f3", size = 43133, upload-time = "2025-06-09T22:53:41.965Z" }, { url = "https://files.pythonhosted.org/packages/63/7c/e9399ba5da7780871db4eac178e9c2e204c23dd3e7d32df202092a1ed400/propcache-0.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3def3da3ac3ce41562d85db655d18ebac740cb3fa4367f11a52b3da9d03a5cc3", size = 43039, upload-time = "2025-06-09T22:53:43.268Z" }, { url = "https://files.pythonhosted.org/packages/22/e1/58da211eb8fdc6fc854002387d38f415a6ca5f5c67c1315b204a5d3e9d7a/propcache-0.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bec58347a5a6cebf239daba9bda37dffec5b8d2ce004d9fe4edef3d2815137e", size = 201903, upload-time = "2025-06-09T22:53:44.872Z" }, { url = "https://files.pythonhosted.org/packages/c4/0a/550ea0f52aac455cb90111c8bab995208443e46d925e51e2f6ebdf869525/propcache-0.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55ffda449a507e9fbd4aca1a7d9aa6753b07d6166140e5a18d2ac9bc49eac220", size = 213362, upload-time = "2025-06-09T22:53:46.707Z" }, { url = "https://files.pythonhosted.org/packages/5a/af/9893b7d878deda9bb69fcf54600b247fba7317761b7db11fede6e0f28bd0/propcache-0.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64a67fb39229a8a8491dd42f864e5e263155e729c2e7ff723d6e25f596b1e8cb", size = 210525, upload-time = "2025-06-09T22:53:48.547Z" }, { url = "https://files.pythonhosted.org/packages/7c/bb/38fd08b278ca85cde36d848091ad2b45954bc5f15cce494bb300b9285831/propcache-0.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9da1cf97b92b51253d5b68cf5a2b9e0dafca095e36b7f2da335e27dc6172a614", size = 198283, upload-time = "2025-06-09T22:53:50.067Z" }, { url = "https://files.pythonhosted.org/packages/78/8c/9fe55bd01d362bafb413dfe508c48753111a1e269737fa143ba85693592c/propcache-0.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5f559e127134b07425134b4065be45b166183fdcb433cb6c24c8e4149056ad50", size = 191872, upload-time = "2025-06-09T22:53:51.438Z" }, { url = "https://files.pythonhosted.org/packages/54/14/4701c33852937a22584e08abb531d654c8bcf7948a8f87ad0a4822394147/propcache-0.3.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:aff2e4e06435d61f11a428360a932138d0ec288b0a31dd9bd78d200bd4a2b339", size = 199452, upload-time = "2025-06-09T22:53:53.229Z" }, { url = "https://files.pythonhosted.org/packages/16/44/447f2253d859602095356007657ee535e0093215ea0b3d1d6a41d16e5201/propcache-0.3.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:4927842833830942a5d0a56e6f4839bc484785b8e1ce8d287359794818633ba0", size = 191567, upload-time = "2025-06-09T22:53:54.541Z" }, { url = "https://files.pythonhosted.org/packages/f2/b3/e4756258749bb2d3b46defcff606a2f47410bab82be5824a67e84015b267/propcache-0.3.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6107ddd08b02654a30fb8ad7a132021759d750a82578b94cd55ee2772b6ebea2", size = 193015, upload-time = "2025-06-09T22:53:56.44Z" }, { url = "https://files.pythonhosted.org/packages/1e/df/e6d3c7574233164b6330b9fd697beeac402afd367280e6dc377bb99b43d9/propcache-0.3.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:70bd8b9cd6b519e12859c99f3fc9a93f375ebd22a50296c3a295028bea73b9e7", size = 204660, upload-time = "2025-06-09T22:53:57.839Z" }, { url = "https://files.pythonhosted.org/packages/b2/53/e4d31dd5170b4a0e2e6b730f2385a96410633b4833dc25fe5dffd1f73294/propcache-0.3.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2183111651d710d3097338dd1893fcf09c9f54e27ff1a8795495a16a469cc90b", size = 206105, upload-time = "2025-06-09T22:53:59.638Z" }, { url = "https://files.pythonhosted.org/packages/7f/fe/74d54cf9fbe2a20ff786e5f7afcfde446588f0cf15fb2daacfbc267b866c/propcache-0.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fb075ad271405dcad8e2a7ffc9a750a3bf70e533bd86e89f0603e607b93aa64c", size = 196980, upload-time = "2025-06-09T22:54:01.071Z" }, { url = "https://files.pythonhosted.org/packages/22/ec/c469c9d59dada8a7679625e0440b544fe72e99311a4679c279562051f6fc/propcache-0.3.2-cp310-cp310-win32.whl", hash = "sha256:404d70768080d3d3bdb41d0771037da19d8340d50b08e104ca0e7f9ce55fce70", size = 37679, upload-time = "2025-06-09T22:54:03.003Z" }, { url = "https://files.pythonhosted.org/packages/38/35/07a471371ac89d418f8d0b699c75ea6dca2041fbda360823de21f6a9ce0a/propcache-0.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:7435d766f978b4ede777002e6b3b6641dd229cd1da8d3d3106a45770365f9ad9", size = 41459, upload-time = "2025-06-09T22:54:04.134Z" }, { url = "https://files.pythonhosted.org/packages/80/8d/e8b436717ab9c2cfc23b116d2c297305aa4cd8339172a456d61ebf5669b8/propcache-0.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0b8d2f607bd8f80ddc04088bc2a037fdd17884a6fcadc47a96e334d72f3717be", size = 74207, upload-time = "2025-06-09T22:54:05.399Z" }, { url = "https://files.pythonhosted.org/packages/d6/29/1e34000e9766d112171764b9fa3226fa0153ab565d0c242c70e9945318a7/propcache-0.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06766d8f34733416e2e34f46fea488ad5d60726bb9481d3cddf89a6fa2d9603f", size = 43648, upload-time = "2025-06-09T22:54:08.023Z" }, { url = "https://files.pythonhosted.org/packages/46/92/1ad5af0df781e76988897da39b5f086c2bf0f028b7f9bd1f409bb05b6874/propcache-0.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2dc1f4a1df4fecf4e6f68013575ff4af84ef6f478fe5344317a65d38a8e6dc9", size = 43496, upload-time = "2025-06-09T22:54:09.228Z" }, { url = "https://files.pythonhosted.org/packages/b3/ce/e96392460f9fb68461fabab3e095cb00c8ddf901205be4eae5ce246e5b7e/propcache-0.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be29c4f4810c5789cf10ddf6af80b041c724e629fa51e308a7a0fb19ed1ef7bf", size = 217288, upload-time = "2025-06-09T22:54:10.466Z" }, { url = "https://files.pythonhosted.org/packages/c5/2a/866726ea345299f7ceefc861a5e782b045545ae6940851930a6adaf1fca6/propcache-0.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59d61f6970ecbd8ff2e9360304d5c8876a6abd4530cb752c06586849ac8a9dc9", size = 227456, upload-time = "2025-06-09T22:54:11.828Z" }, { url = "https://files.pythonhosted.org/packages/de/03/07d992ccb6d930398689187e1b3c718339a1c06b8b145a8d9650e4726166/propcache-0.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:62180e0b8dbb6b004baec00a7983e4cc52f5ada9cd11f48c3528d8cfa7b96a66", size = 225429, upload-time = "2025-06-09T22:54:13.823Z" }, { url = "https://files.pythonhosted.org/packages/5d/e6/116ba39448753b1330f48ab8ba927dcd6cf0baea8a0ccbc512dfb49ba670/propcache-0.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c144ca294a204c470f18cf4c9d78887810d04a3e2fbb30eea903575a779159df", size = 213472, upload-time = "2025-06-09T22:54:15.232Z" }, { url = "https://files.pythonhosted.org/packages/a6/85/f01f5d97e54e428885a5497ccf7f54404cbb4f906688a1690cd51bf597dc/propcache-0.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5c2a784234c28854878d68978265617aa6dc0780e53d44b4d67f3651a17a9a2", size = 204480, upload-time = "2025-06-09T22:54:17.104Z" }, { url = "https://files.pythonhosted.org/packages/e3/79/7bf5ab9033b8b8194cc3f7cf1aaa0e9c3256320726f64a3e1f113a812dce/propcache-0.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5745bc7acdafa978ca1642891b82c19238eadc78ba2aaa293c6863b304e552d7", size = 214530, upload-time = "2025-06-09T22:54:18.512Z" }, { url = "https://files.pythonhosted.org/packages/31/0b/bd3e0c00509b609317df4a18e6b05a450ef2d9a963e1d8bc9c9415d86f30/propcache-0.3.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:c0075bf773d66fa8c9d41f66cc132ecc75e5bb9dd7cce3cfd14adc5ca184cb95", size = 205230, upload-time = "2025-06-09T22:54:19.947Z" }, { url = "https://files.pythonhosted.org/packages/7a/23/fae0ff9b54b0de4e819bbe559508da132d5683c32d84d0dc2ccce3563ed4/propcache-0.3.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5f57aa0847730daceff0497f417c9de353c575d8da3579162cc74ac294c5369e", size = 206754, upload-time = "2025-06-09T22:54:21.716Z" }, { url = "https://files.pythonhosted.org/packages/b7/7f/ad6a3c22630aaa5f618b4dc3c3598974a72abb4c18e45a50b3cdd091eb2f/propcache-0.3.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:eef914c014bf72d18efb55619447e0aecd5fb7c2e3fa7441e2e5d6099bddff7e", size = 218430, upload-time = "2025-06-09T22:54:23.17Z" }, { url = "https://files.pythonhosted.org/packages/5b/2c/ba4f1c0e8a4b4c75910742f0d333759d441f65a1c7f34683b4a74c0ee015/propcache-0.3.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2a4092e8549031e82facf3decdbc0883755d5bbcc62d3aea9d9e185549936dcf", size = 223884, upload-time = "2025-06-09T22:54:25.539Z" }, { url = "https://files.pythonhosted.org/packages/88/e4/ebe30fc399e98572019eee82ad0caf512401661985cbd3da5e3140ffa1b0/propcache-0.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:85871b050f174bc0bfb437efbdb68aaf860611953ed12418e4361bc9c392749e", size = 211480, upload-time = "2025-06-09T22:54:26.892Z" }, { url = "https://files.pythonhosted.org/packages/96/0a/7d5260b914e01d1d0906f7f38af101f8d8ed0dc47426219eeaf05e8ea7c2/propcache-0.3.2-cp311-cp311-win32.whl", hash = "sha256:36c8d9b673ec57900c3554264e630d45980fd302458e4ac801802a7fd2ef7897", size = 37757, upload-time = "2025-06-09T22:54:28.241Z" }, { url = "https://files.pythonhosted.org/packages/e1/2d/89fe4489a884bc0da0c3278c552bd4ffe06a1ace559db5ef02ef24ab446b/propcache-0.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:e53af8cb6a781b02d2ea079b5b853ba9430fcbe18a8e3ce647d5982a3ff69f39", size = 41500, upload-time = "2025-06-09T22:54:29.4Z" }, { url = "https://files.pythonhosted.org/packages/a8/42/9ca01b0a6f48e81615dca4765a8f1dd2c057e0540f6116a27dc5ee01dfb6/propcache-0.3.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8de106b6c84506b31c27168582cd3cb3000a6412c16df14a8628e5871ff83c10", size = 73674, upload-time = "2025-06-09T22:54:30.551Z" }, { url = "https://files.pythonhosted.org/packages/af/6e/21293133beb550f9c901bbece755d582bfaf2176bee4774000bd4dd41884/propcache-0.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:28710b0d3975117239c76600ea351934ac7b5ff56e60953474342608dbbb6154", size = 43570, upload-time = "2025-06-09T22:54:32.296Z" }, { url = "https://files.pythonhosted.org/packages/0c/c8/0393a0a3a2b8760eb3bde3c147f62b20044f0ddac81e9d6ed7318ec0d852/propcache-0.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce26862344bdf836650ed2487c3d724b00fbfec4233a1013f597b78c1cb73615", size = 43094, upload-time = "2025-06-09T22:54:33.929Z" }, { url = "https://files.pythonhosted.org/packages/37/2c/489afe311a690399d04a3e03b069225670c1d489eb7b044a566511c1c498/propcache-0.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bca54bd347a253af2cf4544bbec232ab982f4868de0dd684246b67a51bc6b1db", size = 226958, upload-time = "2025-06-09T22:54:35.186Z" }, { url = "https://files.pythonhosted.org/packages/9d/ca/63b520d2f3d418c968bf596839ae26cf7f87bead026b6192d4da6a08c467/propcache-0.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55780d5e9a2ddc59711d727226bb1ba83a22dd32f64ee15594b9392b1f544eb1", size = 234894, upload-time = "2025-06-09T22:54:36.708Z" }, { url = "https://files.pythonhosted.org/packages/11/60/1d0ed6fff455a028d678df30cc28dcee7af77fa2b0e6962ce1df95c9a2a9/propcache-0.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:035e631be25d6975ed87ab23153db6a73426a48db688070d925aa27e996fe93c", size = 233672, upload-time = "2025-06-09T22:54:38.062Z" }, { url = "https://files.pythonhosted.org/packages/37/7c/54fd5301ef38505ab235d98827207176a5c9b2aa61939b10a460ca53e123/propcache-0.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee6f22b6eaa39297c751d0e80c0d3a454f112f5c6481214fcf4c092074cecd67", size = 224395, upload-time = "2025-06-09T22:54:39.634Z" }, { url = "https://files.pythonhosted.org/packages/ee/1a/89a40e0846f5de05fdc6779883bf46ba980e6df4d2ff8fb02643de126592/propcache-0.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ca3aee1aa955438c4dba34fc20a9f390e4c79967257d830f137bd5a8a32ed3b", size = 212510, upload-time = "2025-06-09T22:54:41.565Z" }, { url = "https://files.pythonhosted.org/packages/5e/33/ca98368586c9566a6b8d5ef66e30484f8da84c0aac3f2d9aec6d31a11bd5/propcache-0.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7a4f30862869fa2b68380d677cc1c5fcf1e0f2b9ea0cf665812895c75d0ca3b8", size = 222949, upload-time = "2025-06-09T22:54:43.038Z" }, { url = "https://files.pythonhosted.org/packages/ba/11/ace870d0aafe443b33b2f0b7efdb872b7c3abd505bfb4890716ad7865e9d/propcache-0.3.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b77ec3c257d7816d9f3700013639db7491a434644c906a2578a11daf13176251", size = 217258, upload-time = "2025-06-09T22:54:44.376Z" }, { url = "https://files.pythonhosted.org/packages/5b/d2/86fd6f7adffcfc74b42c10a6b7db721d1d9ca1055c45d39a1a8f2a740a21/propcache-0.3.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:cab90ac9d3f14b2d5050928483d3d3b8fb6b4018893fc75710e6aa361ecb2474", size = 213036, upload-time = "2025-06-09T22:54:46.243Z" }, { url = "https://files.pythonhosted.org/packages/07/94/2d7d1e328f45ff34a0a284cf5a2847013701e24c2a53117e7c280a4316b3/propcache-0.3.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0b504d29f3c47cf6b9e936c1852246c83d450e8e063d50562115a6be6d3a2535", size = 227684, upload-time = "2025-06-09T22:54:47.63Z" }, { url = "https://files.pythonhosted.org/packages/b7/05/37ae63a0087677e90b1d14710e532ff104d44bc1efa3b3970fff99b891dc/propcache-0.3.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:ce2ac2675a6aa41ddb2a0c9cbff53780a617ac3d43e620f8fd77ba1c84dcfc06", size = 234562, upload-time = "2025-06-09T22:54:48.982Z" }, { url = "https://files.pythonhosted.org/packages/a4/7c/3f539fcae630408d0bd8bf3208b9a647ccad10976eda62402a80adf8fc34/propcache-0.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:62b4239611205294cc433845b914131b2a1f03500ff3c1ed093ed216b82621e1", size = 222142, upload-time = "2025-06-09T22:54:50.424Z" }, { url = "https://files.pythonhosted.org/packages/7c/d2/34b9eac8c35f79f8a962546b3e97e9d4b990c420ee66ac8255d5d9611648/propcache-0.3.2-cp312-cp312-win32.whl", hash = "sha256:df4a81b9b53449ebc90cc4deefb052c1dd934ba85012aa912c7ea7b7e38b60c1", size = 37711, upload-time = "2025-06-09T22:54:52.072Z" }, { url = "https://files.pythonhosted.org/packages/19/61/d582be5d226cf79071681d1b46b848d6cb03d7b70af7063e33a2787eaa03/propcache-0.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:7046e79b989d7fe457bb755844019e10f693752d169076138abf17f31380800c", size = 41479, upload-time = "2025-06-09T22:54:53.234Z" }, { url = "https://files.pythonhosted.org/packages/dc/d1/8c747fafa558c603c4ca19d8e20b288aa0c7cda74e9402f50f31eb65267e/propcache-0.3.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ca592ed634a73ca002967458187109265e980422116c0a107cf93d81f95af945", size = 71286, upload-time = "2025-06-09T22:54:54.369Z" }, { url = "https://files.pythonhosted.org/packages/61/99/d606cb7986b60d89c36de8a85d58764323b3a5ff07770a99d8e993b3fa73/propcache-0.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9ecb0aad4020e275652ba3975740f241bd12a61f1a784df044cf7477a02bc252", size = 42425, upload-time = "2025-06-09T22:54:55.642Z" }, { url = "https://files.pythonhosted.org/packages/8c/96/ef98f91bbb42b79e9bb82bdd348b255eb9d65f14dbbe3b1594644c4073f7/propcache-0.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7f08f1cc28bd2eade7a8a3d2954ccc673bb02062e3e7da09bc75d843386b342f", size = 41846, upload-time = "2025-06-09T22:54:57.246Z" }, { url = "https://files.pythonhosted.org/packages/5b/ad/3f0f9a705fb630d175146cd7b1d2bf5555c9beaed54e94132b21aac098a6/propcache-0.3.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1a342c834734edb4be5ecb1e9fb48cb64b1e2320fccbd8c54bf8da8f2a84c33", size = 208871, upload-time = "2025-06-09T22:54:58.975Z" }, { url = "https://files.pythonhosted.org/packages/3a/38/2085cda93d2c8b6ec3e92af2c89489a36a5886b712a34ab25de9fbca7992/propcache-0.3.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a544caaae1ac73f1fecfae70ded3e93728831affebd017d53449e3ac052ac1e", size = 215720, upload-time = "2025-06-09T22:55:00.471Z" }, { url = "https://files.pythonhosted.org/packages/61/c1/d72ea2dc83ac7f2c8e182786ab0fc2c7bd123a1ff9b7975bee671866fe5f/propcache-0.3.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:310d11aa44635298397db47a3ebce7db99a4cc4b9bbdfcf6c98a60c8d5261cf1", size = 215203, upload-time = "2025-06-09T22:55:01.834Z" }, { url = "https://files.pythonhosted.org/packages/af/81/b324c44ae60c56ef12007105f1460d5c304b0626ab0cc6b07c8f2a9aa0b8/propcache-0.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c1396592321ac83157ac03a2023aa6cc4a3cc3cfdecb71090054c09e5a7cce3", size = 206365, upload-time = "2025-06-09T22:55:03.199Z" }, { url = "https://files.pythonhosted.org/packages/09/73/88549128bb89e66d2aff242488f62869014ae092db63ccea53c1cc75a81d/propcache-0.3.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cabf5b5902272565e78197edb682017d21cf3b550ba0460ee473753f28d23c1", size = 196016, upload-time = "2025-06-09T22:55:04.518Z" }, { url = "https://files.pythonhosted.org/packages/b9/3f/3bdd14e737d145114a5eb83cb172903afba7242f67c5877f9909a20d948d/propcache-0.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0a2f2235ac46a7aa25bdeb03a9e7060f6ecbd213b1f9101c43b3090ffb971ef6", size = 205596, upload-time = "2025-06-09T22:55:05.942Z" }, { url = "https://files.pythonhosted.org/packages/0f/ca/2f4aa819c357d3107c3763d7ef42c03980f9ed5c48c82e01e25945d437c1/propcache-0.3.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:92b69e12e34869a6970fd2f3da91669899994b47c98f5d430b781c26f1d9f387", size = 200977, upload-time = "2025-06-09T22:55:07.792Z" }, { url = "https://files.pythonhosted.org/packages/cd/4a/e65276c7477533c59085251ae88505caf6831c0e85ff8b2e31ebcbb949b1/propcache-0.3.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:54e02207c79968ebbdffc169591009f4474dde3b4679e16634d34c9363ff56b4", size = 197220, upload-time = "2025-06-09T22:55:09.173Z" }, { url = "https://files.pythonhosted.org/packages/7c/54/fc7152e517cf5578278b242396ce4d4b36795423988ef39bb8cd5bf274c8/propcache-0.3.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4adfb44cb588001f68c5466579d3f1157ca07f7504fc91ec87862e2b8e556b88", size = 210642, upload-time = "2025-06-09T22:55:10.62Z" }, { url = "https://files.pythonhosted.org/packages/b9/80/abeb4a896d2767bf5f1ea7b92eb7be6a5330645bd7fb844049c0e4045d9d/propcache-0.3.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fd3e6019dc1261cd0291ee8919dd91fbab7b169bb76aeef6c716833a3f65d206", size = 212789, upload-time = "2025-06-09T22:55:12.029Z" }, { url = "https://files.pythonhosted.org/packages/b3/db/ea12a49aa7b2b6d68a5da8293dcf50068d48d088100ac016ad92a6a780e6/propcache-0.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4c181cad81158d71c41a2bce88edce078458e2dd5ffee7eddd6b05da85079f43", size = 205880, upload-time = "2025-06-09T22:55:13.45Z" }, { url = "https://files.pythonhosted.org/packages/d1/e5/9076a0bbbfb65d1198007059c65639dfd56266cf8e477a9707e4b1999ff4/propcache-0.3.2-cp313-cp313-win32.whl", hash = "sha256:8a08154613f2249519e549de2330cf8e2071c2887309a7b07fb56098f5170a02", size = 37220, upload-time = "2025-06-09T22:55:15.284Z" }, { url = "https://files.pythonhosted.org/packages/d3/f5/b369e026b09a26cd77aa88d8fffd69141d2ae00a2abaaf5380d2603f4b7f/propcache-0.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:e41671f1594fc4ab0a6dec1351864713cb3a279910ae8b58f884a88a0a632c05", size = 40678, upload-time = "2025-06-09T22:55:16.445Z" }, { url = "https://files.pythonhosted.org/packages/a4/3a/6ece377b55544941a08d03581c7bc400a3c8cd3c2865900a68d5de79e21f/propcache-0.3.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:9a3cf035bbaf035f109987d9d55dc90e4b0e36e04bbbb95af3055ef17194057b", size = 76560, upload-time = "2025-06-09T22:55:17.598Z" }, { url = "https://files.pythonhosted.org/packages/0c/da/64a2bb16418740fa634b0e9c3d29edff1db07f56d3546ca2d86ddf0305e1/propcache-0.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:156c03d07dc1323d8dacaa221fbe028c5c70d16709cdd63502778e6c3ccca1b0", size = 44676, upload-time = "2025-06-09T22:55:18.922Z" }, { url = "https://files.pythonhosted.org/packages/36/7b/f025e06ea51cb72c52fb87e9b395cced02786610b60a3ed51da8af017170/propcache-0.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74413c0ba02ba86f55cf60d18daab219f7e531620c15f1e23d95563f505efe7e", size = 44701, upload-time = "2025-06-09T22:55:20.106Z" }, { url = "https://files.pythonhosted.org/packages/a4/00/faa1b1b7c3b74fc277f8642f32a4c72ba1d7b2de36d7cdfb676db7f4303e/propcache-0.3.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f066b437bb3fa39c58ff97ab2ca351db465157d68ed0440abecb21715eb24b28", size = 276934, upload-time = "2025-06-09T22:55:21.5Z" }, { url = "https://files.pythonhosted.org/packages/74/ab/935beb6f1756e0476a4d5938ff44bf0d13a055fed880caf93859b4f1baf4/propcache-0.3.2-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1304b085c83067914721e7e9d9917d41ad87696bf70f0bc7dee450e9c71ad0a", size = 278316, upload-time = "2025-06-09T22:55:22.918Z" }, { url = "https://files.pythonhosted.org/packages/f8/9d/994a5c1ce4389610838d1caec74bdf0e98b306c70314d46dbe4fcf21a3e2/propcache-0.3.2-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab50cef01b372763a13333b4e54021bdcb291fc9a8e2ccb9c2df98be51bcde6c", size = 282619, upload-time = "2025-06-09T22:55:24.651Z" }, { url = "https://files.pythonhosted.org/packages/2b/00/a10afce3d1ed0287cef2e09506d3be9822513f2c1e96457ee369adb9a6cd/propcache-0.3.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fad3b2a085ec259ad2c2842666b2a0a49dea8463579c606426128925af1ed725", size = 265896, upload-time = "2025-06-09T22:55:26.049Z" }, { url = "https://files.pythonhosted.org/packages/2e/a8/2aa6716ffa566ca57c749edb909ad27884680887d68517e4be41b02299f3/propcache-0.3.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:261fa020c1c14deafd54c76b014956e2f86991af198c51139faf41c4d5e83892", size = 252111, upload-time = "2025-06-09T22:55:27.381Z" }, { url = "https://files.pythonhosted.org/packages/36/4f/345ca9183b85ac29c8694b0941f7484bf419c7f0fea2d1e386b4f7893eed/propcache-0.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:46d7f8aa79c927e5f987ee3a80205c987717d3659f035c85cf0c3680526bdb44", size = 268334, upload-time = "2025-06-09T22:55:28.747Z" }, { url = "https://files.pythonhosted.org/packages/3e/ca/fcd54f78b59e3f97b3b9715501e3147f5340167733d27db423aa321e7148/propcache-0.3.2-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:6d8f3f0eebf73e3c0ff0e7853f68be638b4043c65a70517bb575eff54edd8dbe", size = 255026, upload-time = "2025-06-09T22:55:30.184Z" }, { url = "https://files.pythonhosted.org/packages/8b/95/8e6a6bbbd78ac89c30c225210a5c687790e532ba4088afb8c0445b77ef37/propcache-0.3.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:03c89c1b14a5452cf15403e291c0ccd7751d5b9736ecb2c5bab977ad6c5bcd81", size = 250724, upload-time = "2025-06-09T22:55:31.646Z" }, { url = "https://files.pythonhosted.org/packages/ee/b0/0dd03616142baba28e8b2d14ce5df6631b4673850a3d4f9c0f9dd714a404/propcache-0.3.2-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:0cc17efde71e12bbaad086d679ce575268d70bc123a5a71ea7ad76f70ba30bba", size = 268868, upload-time = "2025-06-09T22:55:33.209Z" }, { url = "https://files.pythonhosted.org/packages/c5/98/2c12407a7e4fbacd94ddd32f3b1e3d5231e77c30ef7162b12a60e2dd5ce3/propcache-0.3.2-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:acdf05d00696bc0447e278bb53cb04ca72354e562cf88ea6f9107df8e7fd9770", size = 271322, upload-time = "2025-06-09T22:55:35.065Z" }, { url = "https://files.pythonhosted.org/packages/35/91/9cb56efbb428b006bb85db28591e40b7736847b8331d43fe335acf95f6c8/propcache-0.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4445542398bd0b5d32df908031cb1b30d43ac848e20470a878b770ec2dcc6330", size = 265778, upload-time = "2025-06-09T22:55:36.45Z" }, { url = "https://files.pythonhosted.org/packages/9a/4c/b0fe775a2bdd01e176b14b574be679d84fc83958335790f7c9a686c1f468/propcache-0.3.2-cp313-cp313t-win32.whl", hash = "sha256:f86e5d7cd03afb3a1db8e9f9f6eff15794e79e791350ac48a8c924e6f439f394", size = 41175, upload-time = "2025-06-09T22:55:38.436Z" }, { url = "https://files.pythonhosted.org/packages/a4/ff/47f08595e3d9b5e149c150f88d9714574f1a7cbd89fe2817158a952674bf/propcache-0.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:9704bedf6e7cbe3c65eca4379a9b53ee6a83749f047808cbb5044d40d7d72198", size = 44857, upload-time = "2025-06-09T22:55:39.687Z" }, { url = "https://files.pythonhosted.org/packages/6c/39/8ea9bcfaaff16fd0b0fc901ee522e24c9ec44b4ca0229cfffb8066a06959/propcache-0.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a7fad897f14d92086d6b03fdd2eb844777b0c4d7ec5e3bac0fbae2ab0602bbe5", size = 74678, upload-time = "2025-06-09T22:55:41.227Z" }, { url = "https://files.pythonhosted.org/packages/d3/85/cab84c86966e1d354cf90cdc4ba52f32f99a5bca92a1529d666d957d7686/propcache-0.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1f43837d4ca000243fd7fd6301947d7cb93360d03cd08369969450cc6b2ce3b4", size = 43829, upload-time = "2025-06-09T22:55:42.417Z" }, { url = "https://files.pythonhosted.org/packages/23/f7/9cb719749152d8b26d63801b3220ce2d3931312b2744d2b3a088b0ee9947/propcache-0.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:261df2e9474a5949c46e962065d88eb9b96ce0f2bd30e9d3136bcde84befd8f2", size = 43729, upload-time = "2025-06-09T22:55:43.651Z" }, { url = "https://files.pythonhosted.org/packages/a2/a2/0b2b5a210ff311260002a315f6f9531b65a36064dfb804655432b2f7d3e3/propcache-0.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e514326b79e51f0a177daab1052bc164d9d9e54133797a3a58d24c9c87a3fe6d", size = 204483, upload-time = "2025-06-09T22:55:45.327Z" }, { url = "https://files.pythonhosted.org/packages/3f/e0/7aff5de0c535f783b0c8be5bdb750c305c1961d69fbb136939926e155d98/propcache-0.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d4a996adb6904f85894570301939afeee65f072b4fd265ed7e569e8d9058e4ec", size = 217425, upload-time = "2025-06-09T22:55:46.729Z" }, { url = "https://files.pythonhosted.org/packages/92/1d/65fa889eb3b2a7d6e4ed3c2b568a9cb8817547a1450b572de7bf24872800/propcache-0.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:76cace5d6b2a54e55b137669b30f31aa15977eeed390c7cbfb1dafa8dfe9a701", size = 214723, upload-time = "2025-06-09T22:55:48.342Z" }, { url = "https://files.pythonhosted.org/packages/9a/e2/eecf6989870988dfd731de408a6fa366e853d361a06c2133b5878ce821ad/propcache-0.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31248e44b81d59d6addbb182c4720f90b44e1efdc19f58112a3c3a1615fb47ef", size = 200166, upload-time = "2025-06-09T22:55:49.775Z" }, { url = "https://files.pythonhosted.org/packages/12/06/c32be4950967f18f77489268488c7cdc78cbfc65a8ba8101b15e526b83dc/propcache-0.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abb7fa19dbf88d3857363e0493b999b8011eea856b846305d8c0512dfdf8fbb1", size = 194004, upload-time = "2025-06-09T22:55:51.335Z" }, { url = "https://files.pythonhosted.org/packages/46/6c/17b521a6b3b7cbe277a4064ff0aa9129dd8c89f425a5a9b6b4dd51cc3ff4/propcache-0.3.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d81ac3ae39d38588ad0549e321e6f773a4e7cc68e7751524a22885d5bbadf886", size = 203075, upload-time = "2025-06-09T22:55:52.681Z" }, { url = "https://files.pythonhosted.org/packages/62/cb/3bdba2b736b3e45bc0e40f4370f745b3e711d439ffbffe3ae416393eece9/propcache-0.3.2-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:cc2782eb0f7a16462285b6f8394bbbd0e1ee5f928034e941ffc444012224171b", size = 195407, upload-time = "2025-06-09T22:55:54.048Z" }, { url = "https://files.pythonhosted.org/packages/29/bd/760c5c6a60a4a2c55a421bc34a25ba3919d49dee411ddb9d1493bb51d46e/propcache-0.3.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:db429c19a6c7e8a1c320e6a13c99799450f411b02251fb1b75e6217cf4a14fcb", size = 196045, upload-time = "2025-06-09T22:55:55.485Z" }, { url = "https://files.pythonhosted.org/packages/76/58/ced2757a46f55b8c84358d6ab8de4faf57cba831c51e823654da7144b13a/propcache-0.3.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:21d8759141a9e00a681d35a1f160892a36fb6caa715ba0b832f7747da48fb6ea", size = 208432, upload-time = "2025-06-09T22:55:56.884Z" }, { url = "https://files.pythonhosted.org/packages/bb/ec/d98ea8d5a4d8fe0e372033f5254eddf3254344c0c5dc6c49ab84349e4733/propcache-0.3.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2ca6d378f09adb13837614ad2754fa8afaee330254f404299611bce41a8438cb", size = 210100, upload-time = "2025-06-09T22:55:58.498Z" }, { url = "https://files.pythonhosted.org/packages/56/84/b6d8a7ecf3f62d7dd09d9d10bbf89fad6837970ef868b35b5ffa0d24d9de/propcache-0.3.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:34a624af06c048946709f4278b4176470073deda88d91342665d95f7c6270fbe", size = 200712, upload-time = "2025-06-09T22:55:59.906Z" }, { url = "https://files.pythonhosted.org/packages/bf/32/889f4903ddfe4a9dc61da71ee58b763758cf2d608fe1decede06e6467f8d/propcache-0.3.2-cp39-cp39-win32.whl", hash = "sha256:4ba3fef1c30f306b1c274ce0b8baaa2c3cdd91f645c48f06394068f37d3837a1", size = 38187, upload-time = "2025-06-09T22:56:01.212Z" }, { url = "https://files.pythonhosted.org/packages/67/74/d666795fb9ba1dc139d30de64f3b6fd1ff9c9d3d96ccfdb992cd715ce5d2/propcache-0.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:7a2368eed65fc69a7a7a40b27f22e85e7627b74216f0846b04ba5c116e191ec9", size = 42025, upload-time = "2025-06-09T22:56:02.875Z" }, { url = "https://files.pythonhosted.org/packages/cc/35/cc0aaecf278bb4575b8555f2b137de5ab821595ddae9da9d3cd1da4072c7/propcache-0.3.2-py3-none-any.whl", hash = "sha256:98f1ec44fb675f5052cccc8e609c46ed23a35a1cfd18545ad4e29002d858a43f", size = 12663, upload-time = "2025-06-09T22:56:04.484Z" }, ] [[package]] name = "psycopg" version = "3.2.9" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.13'" }, { name = "tzdata", marker = "sys_platform == 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/27/4a/93a6ab570a8d1a4ad171a1f4256e205ce48d828781312c0bbaff36380ecb/psycopg-3.2.9.tar.gz", hash = "sha256:2fbb46fcd17bc81f993f28c47f1ebea38d66ae97cc2dbc3cad73b37cefbff700", size = 158122, upload-time = "2025-05-13T16:11:15.533Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/44/b0/a73c195a56eb6b92e937a5ca58521a5c3346fb233345adc80fd3e2f542e2/psycopg-3.2.9-py3-none-any.whl", hash = "sha256:01a8dadccdaac2123c916208c96e06631641c0566b22005493f09663c7a8d3b6", size = 202705, upload-time = "2025-05-13T16:06:26.584Z" }, ] [package.optional-dependencies] pool = [ { name = "psycopg-pool" }, ] [[package]] name = "psycopg-pool" version = "3.2.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cf/13/1e7850bb2c69a63267c3dbf37387d3f71a00fd0e2fa55c5db14d64ba1af4/psycopg_pool-3.2.6.tar.gz", hash = "sha256:0f92a7817719517212fbfe2fd58b8c35c1850cdd2a80d36b581ba2085d9148e5", size = 29770, upload-time = "2025-02-26T12:03:47.129Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/47/fd/4feb52a55c1a4bd748f2acaed1903ab54a723c47f6d0242780f4d97104d4/psycopg_pool-3.2.6-py3-none-any.whl", hash = "sha256:5887318a9f6af906d041a0b1dc1c60f8f0dda8340c2572b74e10907b51ed5da7", size = 38252, upload-time = "2025-02-26T12:03:45.073Z" }, ] [[package]] name = "pycodestyle" version = "2.14.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/11/e0/abfd2a0d2efe47670df87f3e3a0e2edda42f055053c85361f19c0e2c1ca8/pycodestyle-2.14.0.tar.gz", hash = "sha256:c4b5b517d278089ff9d0abdec919cd97262a3367449ea1c8b49b91529167b783", size = 39472, upload-time = "2025-06-20T18:49:48.75Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl", hash = "sha256:dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d", size = 31594, upload-time = "2025-06-20T18:49:47.491Z" }, ] [[package]] name = "pyflakes" version = "3.4.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/45/dc/fd034dc20b4b264b3d015808458391acbf9df40b1e54750ef175d39180b1/pyflakes-3.4.0.tar.gz", hash = "sha256:b24f96fafb7d2ab0ec5075b7350b3d2d2218eab42003821c06344973d3ea2f58", size = 64669, upload-time = "2025-06-20T18:45:27.834Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/c2/2f/81d580a0fb83baeb066698975cb14a618bdbed7720678566f1b046a95fe8/pyflakes-3.4.0-py2.py3-none-any.whl", hash = "sha256:f742a7dbd0d9cb9ea41e9a24a918996e8170c799fa528688d40dd582c8265f4f", size = 63551, upload-time = "2025-06-20T18:45:26.937Z" }, ] [[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 = "pyproject-hooks" version = "1.2.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/e7/82/28175b2414effca1cdac8dc99f76d660e7a4fb0ceefa4b4ab8f5f6742925/pyproject_hooks-1.2.0.tar.gz", hash = "sha256:1e859bd5c40fae9448642dd871adf459e5e2084186e8d2c2a79a824c970da1f8", size = 19228, upload-time = "2024-09-29T09:24:13.293Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl", hash = "sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913", size = 10216, upload-time = "2024-09-29T09:24:11.978Z" }, ] [[package]] name = "pyrate-limiter" source = { editable = "." } [package.dev-dependencies] all = [ { name = "filelock" }, { name = "psycopg", extra = ["pool"] }, { name = "redis" }, ] dev = [ { name = "aiohttp" }, { name = "coverage" }, { name = "flake8-polyfill" }, { name = "httpx" }, { name = "nox" }, { name = "nox-poetry" }, { name = "pre-commit-uv" }, { name = "psycopg", extra = ["pool"] }, { name = "pytest" }, { name = "pytest-asyncio" }, { name = "pytest-cov" }, { name = "pytest-retry" }, { name = "pytest-xdist" }, { name = "schedule" }, { name = "types-requests" }, ] docs = [ { name = "furo" }, { name = "myst-parser", version = "3.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, { name = "myst-parser", version = "4.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, { name = "sphinx", version = "7.4.7", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" }, { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "sphinx-autodoc-typehints", version = "2.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, { name = "sphinx-autodoc-typehints", version = "3.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" }, { name = "sphinx-autodoc-typehints", version = "3.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "sphinx-copybutton" }, { name = "sphinxcontrib-apidoc" }, ] [package.metadata] [package.metadata.requires-dev] all = [ { name = "filelock", specifier = ">=3.0" }, { name = "psycopg", extras = ["pool"], specifier = ">=3.2.9" }, { name = "redis", specifier = ">=6.2.0" }, ] dev = [ { name = "aiohttp" }, { name = "coverage", specifier = ">=7.10.1" }, { name = "flake8-polyfill", specifier = ">=1.0.2,<2" }, { name = "httpx" }, { name = "nox", specifier = "~=2025.5" }, { name = "nox-poetry", specifier = ">=1.0" }, { name = "pre-commit-uv" }, { name = "psycopg", extras = ["pool"], specifier = ">=3.2.9" }, { name = "pytest", specifier = ">=8.4.1" }, { name = "pytest-asyncio", specifier = ">=1.1.0" }, { name = "pytest-cov", specifier = ">=6.2.1" }, { name = "pytest-retry", specifier = ">=1.7.0" }, { name = "pytest-xdist", specifier = ">=3.8.0" }, { name = "schedule", specifier = ">=1.1.0,<2" }, { name = "types-requests" }, ] docs = [ { name = "furo" }, { name = "myst-parser" }, { name = "sphinx" }, { name = "sphinx-autodoc-typehints" }, { name = "sphinx-copybutton" }, { name = "sphinxcontrib-apidoc" }, ] [[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 = "pytest-asyncio" version = "1.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "backports-asyncio-runner", marker = "python_full_version < '3.11'" }, { name = "pytest" }, { name = "typing-extensions", marker = "python_full_version < '3.10'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/4e/51/f8794af39eeb870e87a8c8068642fc07bce0c854d6865d7dd0f2a9d338c2/pytest_asyncio-1.1.0.tar.gz", hash = "sha256:796aa822981e01b68c12e4827b8697108f7205020f24b5793b3c41555dab68ea", size = 46652, upload-time = "2025-07-16T04:29:26.393Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/c7/9d/bf86eddabf8c6c9cb1ea9a869d6873b46f105a5d292d3a6f7071f5b07935/pytest_asyncio-1.1.0-py3-none-any.whl", hash = "sha256:5fe2d69607b0bd75c656d1211f969cadba035030156745ee09e7d71740e58ecf", size = 15157, upload-time = "2025-07-16T04:29:24.929Z" }, ] [[package]] name = "pytest-cov" version = "6.2.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "coverage", extra = ["toml"] }, { name = "pluggy" }, { name = "pytest" }, ] sdist = { url = "https://files.pythonhosted.org/packages/18/99/668cade231f434aaa59bbfbf49469068d2ddd945000621d3d165d2e7dd7b/pytest_cov-6.2.1.tar.gz", hash = "sha256:25cc6cc0a5358204b8108ecedc51a9b57b34cc6b8c967cc2c01a4e00d8a67da2", size = 69432, upload-time = "2025-06-12T10:47:47.684Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/bc/16/4ea354101abb1287856baa4af2732be351c7bee728065aed451b678153fd/pytest_cov-6.2.1-py3-none-any.whl", hash = "sha256:f5bc4c23f42f1cdd23c70b1dab1bbaef4fc505ba950d53e0081d0730dd7e86d5", size = 24644, upload-time = "2025-06-12T10:47:45.932Z" }, ] [[package]] name = "pytest-retry" version = "1.7.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c5/5b/607b017994cca28de3a1ad22a3eee8418e5d428dcd8ec25b26b18e995a73/pytest_retry-1.7.0.tar.gz", hash = "sha256:f8d52339f01e949df47c11ba9ee8d5b362f5824dff580d3870ec9ae0057df80f", size = 19977, upload-time = "2025-01-19T01:56:13.115Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/7c/ff/3266c8a73b9b93c4b14160a7e2b31d1e1088e28ed29f4c2d93ae34093bfd/pytest_retry-1.7.0-py3-none-any.whl", hash = "sha256:a2dac85b79a4e2375943f1429479c65beb6c69553e7dae6b8332be47a60954f4", size = 13775, upload-time = "2025-01-19T01:56:11.199Z" }, ] [[package]] name = "pytest-xdist" version = "3.8.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "execnet" }, { name = "pytest" }, ] sdist = { url = "https://files.pythonhosted.org/packages/78/b4/439b179d1ff526791eb921115fca8e44e596a13efeda518b9d845a619450/pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1", size = 88069, upload-time = "2025-07-01T13:30:59.346Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88", size = 46396, upload-time = "2025-07-01T13:30:56.632Z" }, ] [[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" }, { url = "https://files.pythonhosted.org/packages/65/d8/b7a1db13636d7fb7d4ff431593c510c8b8fca920ade06ca8ef20015493c5/PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d", size = 184777, upload-time = "2024-08-06T20:33:25.896Z" }, { url = "https://files.pythonhosted.org/packages/0a/02/6ec546cd45143fdf9840b2c6be8d875116a64076218b61d68e12548e5839/PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f", size = 172318, upload-time = "2024-08-06T20:33:27.212Z" }, { url = "https://files.pythonhosted.org/packages/0e/9a/8cc68be846c972bda34f6c2a93abb644fb2476f4dcc924d52175786932c9/PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290", size = 720891, upload-time = "2024-08-06T20:33:28.974Z" }, { url = "https://files.pythonhosted.org/packages/e9/6c/6e1b7f40181bc4805e2e07f4abc10a88ce4648e7e95ff1abe4ae4014a9b2/PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12", size = 722614, upload-time = "2024-08-06T20:33:34.157Z" }, { url = "https://files.pythonhosted.org/packages/3d/32/e7bd8535d22ea2874cef6a81021ba019474ace0d13a4819c2a4bce79bd6a/PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19", size = 737360, upload-time = "2024-08-06T20:33:35.84Z" }, { url = "https://files.pythonhosted.org/packages/d7/12/7322c1e30b9be969670b672573d45479edef72c9a0deac3bb2868f5d7469/PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e", size = 699006, upload-time = "2024-08-06T20:33:37.501Z" }, { url = "https://files.pythonhosted.org/packages/82/72/04fcad41ca56491995076630c3ec1e834be241664c0c09a64c9a2589b507/PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725", size = 723577, upload-time = "2024-08-06T20:33:39.389Z" }, { url = "https://files.pythonhosted.org/packages/ed/5e/46168b1f2757f1fcd442bc3029cd8767d88a98c9c05770d8b420948743bb/PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631", size = 144593, upload-time = "2024-08-06T20:33:46.63Z" }, { url = "https://files.pythonhosted.org/packages/19/87/5124b1c1f2412bb95c59ec481eaf936cd32f0fe2a7b16b97b81c4c017a6a/PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8", size = 162312, upload-time = "2024-08-06T20:33:49.073Z" }, ] [[package]] name = "redis" version = "6.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "async-timeout", marker = "python_full_version < '3.11.3'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0d/d6/e8b92798a5bd67d659d51a18170e91c16ac3b59738d91894651ee255ed49/redis-6.4.0.tar.gz", hash = "sha256:b01bc7282b8444e28ec36b261df5375183bb47a07eb9c603f284e89cbc5ef010", size = 4647399, upload-time = "2025-08-07T08:10:11.441Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/e8/02/89e2ed7e85db6c93dfa9e8f691c5087df4e3551ab39081a4d7c6d1f90e05/redis-6.4.0-py3-none-any.whl", hash = "sha256:f0544fa9604264e9464cdf4814e7d4830f74b165d52f2a330a760a88dd248b7f", size = 279847, upload-time = "2025-08-07T08:10:09.84Z" }, ] [[package]] name = "requests" version = "2.32.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "charset-normalizer" }, { name = "idna" }, { name = "urllib3" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e1/0a/929373653770d8a0d7ea76c37de6e41f11eb07559b103b1c02cafb3f7cf8/requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422", size = 135258, upload-time = "2025-06-09T16:43:07.34Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/7c/e4/56027c4a6b4ae70ca9de302488c5ca95ad4a39e190093d6c1a8ace08341b/requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c", size = 64847, upload-time = "2025-06-09T16:43:05.728Z" }, ] [[package]] name = "roman-numerals-py" version = "3.1.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/30/76/48fd56d17c5bdbdf65609abbc67288728a98ed4c02919428d4f52d23b24b/roman_numerals_py-3.1.0.tar.gz", hash = "sha256:be4bf804f083a4ce001b5eb7e3c0862479d10f94c936f6c4e5f250aa5ff5bd2d", size = 9017, upload-time = "2025-02-22T07:34:54.333Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/53/97/d2cbbaa10c9b826af0e10fdf836e1bf344d9f0abb873ebc34d1f49642d3f/roman_numerals_py-3.1.0-py3-none-any.whl", hash = "sha256:9da2ad2fb670bcf24e81070ceb3be72f6c11c440d73bd579fbeca1e9f330954c", size = 7742, upload-time = "2025-02-22T07:34:52.422Z" }, ] [[package]] name = "schedule" version = "1.2.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/0c/91/b525790063015759f34447d4cf9d2ccb52cdee0f1dd6ff8764e863bcb74c/schedule-1.2.2.tar.gz", hash = "sha256:15fe9c75fe5fd9b9627f3f19cc0ef1420508f9f9a46f45cd0769ef75ede5f0b7", size = 26452, upload-time = "2024-06-18T20:03:14.633Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/20/a7/84c96b61fd13205f2cafbe263cdb2745965974bdf3e0078f121dfeca5f02/schedule-1.2.2-py3-none-any.whl", hash = "sha256:5bef4a2a0183abf44046ae0d164cadcac21b1db011bdd8102e4a0c1e91e06a7d", size = 12220, upload-time = "2024-05-25T18:41:59.121Z" }, ] [[package]] name = "setuptools" version = "80.9.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload-time = "2025-05-27T00:56:51.443Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" }, ] [[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 = "snowballstemmer" version = "3.0.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/75/a7/9810d872919697c9d01295633f5d574fb416d47e535f258272ca1f01f447/snowballstemmer-3.0.1.tar.gz", hash = "sha256:6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895", size = 105575, upload-time = "2025-05-09T16:34:51.843Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/c8/78/3565d011c61f5a43488987ee32b6f3f656e7f107ac2782dd57bdd7d91d9a/snowballstemmer-3.0.1-py3-none-any.whl", hash = "sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064", size = 103274, upload-time = "2025-05-09T16:34:50.371Z" }, ] [[package]] name = "soupsieve" version = "2.7" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/3f/f4/4a80cd6ef364b2e8b65b15816a843c0980f7a5a2b4dc701fc574952aa19f/soupsieve-2.7.tar.gz", hash = "sha256:ad282f9b6926286d2ead4750552c8a6142bc4c783fd66b0293547c8fe6ae126a", size = 103418, upload-time = "2025-04-20T18:50:08.518Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/e7/9c/0e6afc12c269578be5c0c1c9f4b49a8d32770a080260c333ac04cc1c832d/soupsieve-2.7-py3-none-any.whl", hash = "sha256:6e60cc5c1ffaf1cebcc12e8188320b72071e922c2e897f737cadce79ad5d30c4", size = 36677, upload-time = "2025-04-20T18:50:07.196Z" }, ] [[package]] name = "sphinx" version = "7.4.7" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.10'", ] dependencies = [ { name = "alabaster", version = "0.7.16", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, { name = "babel", marker = "python_full_version < '3.10'" }, { name = "colorama", marker = "python_full_version < '3.10' and sys_platform == 'win32'" }, { name = "docutils", marker = "python_full_version < '3.10'" }, { name = "imagesize", marker = "python_full_version < '3.10'" }, { name = "importlib-metadata", marker = "python_full_version < '3.10'" }, { name = "jinja2", marker = "python_full_version < '3.10'" }, { name = "packaging", marker = "python_full_version < '3.10'" }, { name = "pygments", marker = "python_full_version < '3.10'" }, { name = "requests", marker = "python_full_version < '3.10'" }, { name = "snowballstemmer", marker = "python_full_version < '3.10'" }, { name = "sphinxcontrib-applehelp", marker = "python_full_version < '3.10'" }, { name = "sphinxcontrib-devhelp", marker = "python_full_version < '3.10'" }, { name = "sphinxcontrib-htmlhelp", marker = "python_full_version < '3.10'" }, { name = "sphinxcontrib-jsmath", marker = "python_full_version < '3.10'" }, { name = "sphinxcontrib-qthelp", marker = "python_full_version < '3.10'" }, { name = "sphinxcontrib-serializinghtml", marker = "python_full_version < '3.10'" }, { name = "tomli", marker = "python_full_version < '3.10'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/5b/be/50e50cb4f2eff47df05673d361095cafd95521d2a22521b920c67a372dcb/sphinx-7.4.7.tar.gz", hash = "sha256:242f92a7ea7e6c5b406fdc2615413890ba9f699114a9c09192d7dfead2ee9cfe", size = 8067911, upload-time = "2024-07-20T14:46:56.059Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/0d/ef/153f6803c5d5f8917dbb7f7fcf6d34a871ede3296fa89c2c703f5f8a6c8e/sphinx-7.4.7-py3-none-any.whl", hash = "sha256:c2419e2135d11f1951cd994d6eb18a1835bd8fdd8429f9ca375dc1f3281bd239", size = 3401624, upload-time = "2024-07-20T14:46:52.142Z" }, ] [[package]] name = "sphinx" version = "8.1.3" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version == '3.10.*'", ] dependencies = [ { name = "alabaster", version = "1.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" }, { name = "babel", marker = "python_full_version == '3.10.*'" }, { name = "colorama", marker = "python_full_version == '3.10.*' and sys_platform == 'win32'" }, { name = "docutils", marker = "python_full_version == '3.10.*'" }, { name = "imagesize", marker = "python_full_version == '3.10.*'" }, { name = "jinja2", marker = "python_full_version == '3.10.*'" }, { name = "packaging", marker = "python_full_version == '3.10.*'" }, { name = "pygments", marker = "python_full_version == '3.10.*'" }, { name = "requests", marker = "python_full_version == '3.10.*'" }, { name = "snowballstemmer", marker = "python_full_version == '3.10.*'" }, { name = "sphinxcontrib-applehelp", marker = "python_full_version == '3.10.*'" }, { name = "sphinxcontrib-devhelp", marker = "python_full_version == '3.10.*'" }, { name = "sphinxcontrib-htmlhelp", marker = "python_full_version == '3.10.*'" }, { name = "sphinxcontrib-jsmath", marker = "python_full_version == '3.10.*'" }, { name = "sphinxcontrib-qthelp", marker = "python_full_version == '3.10.*'" }, { name = "sphinxcontrib-serializinghtml", marker = "python_full_version == '3.10.*'" }, { name = "tomli", marker = "python_full_version == '3.10.*'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/be0b61178fe2cdcb67e2a92fc9ebb488e3c51c4f74a36a7824c0adf23425/sphinx-8.1.3.tar.gz", hash = "sha256:43c1911eecb0d3e161ad78611bc905d1ad0e523e4ddc202a58a821773dc4c927", size = 8184611, upload-time = "2024-10-13T20:27:13.93Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/26/60/1ddff83a56d33aaf6f10ec8ce84b4c007d9368b21008876fceda7e7381ef/sphinx-8.1.3-py3-none-any.whl", hash = "sha256:09719015511837b76bf6e03e42eb7595ac8c2e41eeb9c29c5b755c6b677992a2", size = 3487125, upload-time = "2024-10-13T20:27:10.448Z" }, ] [[package]] name = "sphinx" version = "8.2.3" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.11'", ] dependencies = [ { name = "alabaster", version = "1.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "babel", marker = "python_full_version >= '3.11'" }, { name = "colorama", marker = "python_full_version >= '3.11' and sys_platform == 'win32'" }, { name = "docutils", marker = "python_full_version >= '3.11'" }, { name = "imagesize", marker = "python_full_version >= '3.11'" }, { name = "jinja2", marker = "python_full_version >= '3.11'" }, { name = "packaging", marker = "python_full_version >= '3.11'" }, { name = "pygments", marker = "python_full_version >= '3.11'" }, { name = "requests", marker = "python_full_version >= '3.11'" }, { name = "roman-numerals-py", marker = "python_full_version >= '3.11'" }, { name = "snowballstemmer", marker = "python_full_version >= '3.11'" }, { name = "sphinxcontrib-applehelp", marker = "python_full_version >= '3.11'" }, { name = "sphinxcontrib-devhelp", marker = "python_full_version >= '3.11'" }, { name = "sphinxcontrib-htmlhelp", marker = "python_full_version >= '3.11'" }, { name = "sphinxcontrib-jsmath", marker = "python_full_version >= '3.11'" }, { name = "sphinxcontrib-qthelp", marker = "python_full_version >= '3.11'" }, { name = "sphinxcontrib-serializinghtml", marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/38/ad/4360e50ed56cb483667b8e6dadf2d3fda62359593faabbe749a27c4eaca6/sphinx-8.2.3.tar.gz", hash = "sha256:398ad29dee7f63a75888314e9424d40f52ce5a6a87ae88e7071e80af296ec348", size = 8321876, upload-time = "2025-03-02T22:31:59.658Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/31/53/136e9eca6e0b9dc0e1962e2c908fbea2e5ac000c2a2fbd9a35797958c48b/sphinx-8.2.3-py3-none-any.whl", hash = "sha256:4405915165f13521d875a8c29c8970800a0141c14cc5416a38feca4ea5d9b9c3", size = 3589741, upload-time = "2025-03-02T22:31:56.836Z" }, ] [[package]] name = "sphinx-autodoc-typehints" version = "2.3.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.10'", ] dependencies = [ { name = "sphinx", version = "7.4.7", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/74/cd/03e7b917230dc057922130a79ba0240df1693bfd76727ea33fae84b39138/sphinx_autodoc_typehints-2.3.0.tar.gz", hash = "sha256:535c78ed2d6a1bad393ba9f3dfa2602cf424e2631ee207263e07874c38fde084", size = 40709, upload-time = "2024-08-29T16:25:48.343Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/a0/f3/e0a4ce49da4b6f4e4ce84b3c39a0677831884cb9d8a87ccbf1e9e56e53ac/sphinx_autodoc_typehints-2.3.0-py3-none-any.whl", hash = "sha256:3098e2c6d0ba99eacd013eb06861acc9b51c6e595be86ab05c08ee5506ac0c67", size = 19836, upload-time = "2024-08-29T16:25:46.707Z" }, ] [[package]] name = "sphinx-autodoc-typehints" version = "3.0.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version == '3.10.*'", ] dependencies = [ { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/26/f0/43c6a5ff3e7b08a8c3b32f81b859f1b518ccc31e45f22e2b41ced38be7b9/sphinx_autodoc_typehints-3.0.1.tar.gz", hash = "sha256:b9b40dd15dee54f6f810c924f863f9cf1c54f9f3265c495140ea01be7f44fa55", size = 36282, upload-time = "2025-01-16T18:25:30.958Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/3c/dc/dc46c5c7c566b7ec5e8f860f9c89533bf03c0e6aadc96fb9b337867e4460/sphinx_autodoc_typehints-3.0.1-py3-none-any.whl", hash = "sha256:4b64b676a14b5b79cefb6628a6dc8070e320d4963e8ff640a2f3e9390ae9045a", size = 20245, upload-time = "2025-01-16T18:25:27.394Z" }, ] [[package]] name = "sphinx-autodoc-typehints" version = "3.2.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.11'", ] dependencies = [ { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/93/68/a388a9b8f066cd865d9daa65af589d097efbfab9a8c302d2cb2daa43b52e/sphinx_autodoc_typehints-3.2.0.tar.gz", hash = "sha256:107ac98bc8b4837202c88c0736d59d6da44076e65a0d7d7d543a78631f662a9b", size = 36724, upload-time = "2025-04-25T16:53:25.872Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/f7/c7/8aab362e86cbf887e58be749a78d20ad743e1eb2c73c2b13d4761f39a104/sphinx_autodoc_typehints-3.2.0-py3-none-any.whl", hash = "sha256:884b39be23b1d884dcc825d4680c9c6357a476936e3b381a67ae80091984eb49", size = 20563, upload-time = "2025-04-25T16:53:24.492Z" }, ] [[package]] name = "sphinx-basic-ng" version = "1.0.0b2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "sphinx", version = "7.4.7", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" }, { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/98/0b/a866924ded68efec7a1759587a4e478aec7559d8165fac8b2ad1c0e774d6/sphinx_basic_ng-1.0.0b2.tar.gz", hash = "sha256:9ec55a47c90c8c002b5960c57492ec3021f5193cb26cebc2dc4ea226848651c9", size = 20736, upload-time = "2023-07-08T18:40:54.166Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/3c/dd/018ce05c532a22007ac58d4f45232514cd9d6dd0ee1dc374e309db830983/sphinx_basic_ng-1.0.0b2-py3-none-any.whl", hash = "sha256:eb09aedbabfb650607e9b4b68c9d240b90b1e1be221d6ad71d61c52e29f7932b", size = 22496, upload-time = "2023-07-08T18:40:52.659Z" }, ] [[package]] name = "sphinx-copybutton" version = "0.5.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "sphinx", version = "7.4.7", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" }, { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/fc/2b/a964715e7f5295f77509e59309959f4125122d648f86b4fe7d70ca1d882c/sphinx-copybutton-0.5.2.tar.gz", hash = "sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd", size = 23039, upload-time = "2023-04-14T08:10:22.998Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/9e/48/1ea60e74949eecb12cdd6ac43987f9fd331156388dcc2319b45e2ebb81bf/sphinx_copybutton-0.5.2-py3-none-any.whl", hash = "sha256:fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e", size = 13343, upload-time = "2023-04-14T08:10:20.844Z" }, ] [[package]] name = "sphinxcontrib-apidoc" version = "0.6.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pbr" }, { name = "sphinx", version = "7.4.7", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" }, { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/1c/8d/161842a1c199c1baed5f5bc0765a59a791324f962fea3b604f105c9493e7/sphinxcontrib_apidoc-0.6.0.tar.gz", hash = "sha256:329b9810d66988f48e127a6bd18cc8efbbd1cd20b8deb4691a35738af49ad88d", size = 16790, upload-time = "2025-05-08T12:55:44.463Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/bf/ac/6b94ecdca590ad0596b83d78277f89d897539a6cfdc997d62f27651540bc/sphinxcontrib_apidoc-0.6.0-py3-none-any.whl", hash = "sha256:668592f933eee858f3bc0d0810d56d50dfa0a70f650a2faaaad501b9a3504633", size = 8765, upload-time = "2025-05-08T12:55:42.733Z" }, ] [[package]] name = "sphinxcontrib-applehelp" version = "2.0.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/ba/6e/b837e84a1a704953c62ef8776d45c3e8d759876b4a84fe14eba2859106fe/sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1", size = 20053, upload-time = "2024-07-29T01:09:00.465Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5", size = 119300, upload-time = "2024-07-29T01:08:58.99Z" }, ] [[package]] name = "sphinxcontrib-devhelp" version = "2.0.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f6/d2/5beee64d3e4e747f316bae86b55943f51e82bb86ecd325883ef65741e7da/sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad", size = 12967, upload-time = "2024-07-29T01:09:23.417Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2", size = 82530, upload-time = "2024-07-29T01:09:21.945Z" }, ] [[package]] name = "sphinxcontrib-htmlhelp" version = "2.1.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/43/93/983afd9aa001e5201eab16b5a444ed5b9b0a7a010541e0ddfbbfd0b2470c/sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9", size = 22617, upload-time = "2024-07-29T01:09:37.889Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8", size = 98705, upload-time = "2024-07-29T01:09:36.407Z" }, ] [[package]] name = "sphinxcontrib-jsmath" version = "1.0.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/b2/e8/9ed3830aeed71f17c026a07a5097edcf44b692850ef215b161b8ad875729/sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8", size = 5787, upload-time = "2019-01-21T16:10:16.347Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", size = 5071, upload-time = "2019-01-21T16:10:14.333Z" }, ] [[package]] name = "sphinxcontrib-qthelp" version = "2.0.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/68/bc/9104308fc285eb3e0b31b67688235db556cd5b0ef31d96f30e45f2e51cae/sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab", size = 17165, upload-time = "2024-07-29T01:09:56.435Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb", size = 88743, upload-time = "2024-07-29T01:09:54.885Z" }, ] [[package]] name = "sphinxcontrib-serializinghtml" version = "2.0.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/3b/44/6716b257b0aa6bfd51a1b31665d1c205fb12cb5ad56de752dfa15657de2f/sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d", size = 16080, upload-time = "2024-07-29T01:10:09.332Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331", size = 92072, upload-time = "2024-07-29T01:10:08.203Z" }, ] [[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 = "tomlkit" version = "0.13.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/cc/18/0bbf3884e9eaa38819ebe46a7bd25dcd56b67434402b66a58c4b8e552575/tomlkit-0.13.3.tar.gz", hash = "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1", size = 185207, upload-time = "2025-06-05T07:13:44.947Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/bd/75/8539d011f6be8e29f339c42e633aae3cb73bffa95dd0f9adec09b9c58e85/tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0", size = 38901, upload-time = "2025-06-05T07:13:43.546Z" }, ] [[package]] name = "types-requests" version = "2.32.4.20250809" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "urllib3" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ed/b0/9355adb86ec84d057fea765e4c49cce592aaf3d5117ce5609a95a7fc3dac/types_requests-2.32.4.20250809.tar.gz", hash = "sha256:d8060de1c8ee599311f56ff58010fb4902f462a1470802cf9f6ed27bc46c4df3", size = 23027, upload-time = "2025-08-09T03:17:10.664Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/2b/6f/ec0012be842b1d888d46884ac5558fd62aeae1f0ec4f7a581433d890d4b5/types_requests-2.32.4.20250809-py3-none-any.whl", hash = "sha256:f73d1832fb519ece02c85b1f09d5f0dd3108938e7d47e7f94bbfa18a6782b163", size = 20644, upload-time = "2025-08-09T03:17:09.716Z" }, ] [[package]] name = "typing-extensions" version = "4.14.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/98/5a/da40306b885cc8c09109dc2e1abd358d5684b1425678151cdaed4731c822/typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36", size = 107673, upload-time = "2025-07-04T13:28:34.16Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76", size = 43906, upload-time = "2025-07-04T13:28:32.743Z" }, ] [[package]] name = "tzdata" version = "2025.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload-time = "2025-03-23T13:54:43.652Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" }, ] [[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 = "uv" version = "0.8.11" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/a8/c1/765112567045a2219979d1a7038e4a2afbddd0637446556b089e77252528/uv-0.8.11.tar.gz", hash = "sha256:d98105244b895c6026e9f3d86f200b70039d39a5f4866022fae664ed935530f3", size = 3504312, upload-time = "2025-08-14T19:48:18.071Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/4a/2f/6703896c45d29b44e5954bb283f00616387cef7ae80188226dac87aff93d/uv-0.8.11-py3-none-linux_armv6l.whl", hash = "sha256:1be7cbc874980dc3e5e0c40fdb3787013a35cce64485f7685fc4b0ee550f7c0c", size = 18497046, upload-time = "2025-08-14T19:47:28.18Z" }, { url = "https://files.pythonhosted.org/packages/61/fe/3ae518ea5a6c2e4fd3d0174486c841bd85e676b3971d9553445ab57319d9/uv-0.8.11-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:84c888cc7b3310aada6058ce964d9b48d4f7801add6f1236548adeb262c637bf", size = 18573000, upload-time = "2025-08-14T19:47:32.156Z" }, { url = "https://files.pythonhosted.org/packages/00/21/6a1cd01103aec916fdf2daa034e3a179a6b835b25db89f4f5e43117ac68c/uv-0.8.11-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3e46395c7f2c7e52bf63f29f3fc1c6b357b011285d1df37d8af9c6f6f7cad36f", size = 17205164, upload-time = "2025-08-14T19:47:34.561Z" }, { url = "https://files.pythonhosted.org/packages/d0/b2/8a9e00d6e5c41a231f59f75c15b04626f7d4561364475962894a31b01fee/uv-0.8.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:d9d35783ac8600cd8e95e9afd007aa281edf3125803c570a4b3246138e2a304d", size = 17822163, upload-time = "2025-08-14T19:47:37.111Z" }, { url = "https://files.pythonhosted.org/packages/d9/e5/230f1ed3cbeae61d10ac8acc3d63b38a81c728161e7671fe3516aec72c76/uv-0.8.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ce267b13f498cebb9690c06461b727718bd11624679ddebb0a3998efe6b80ad7", size = 18152038, upload-time = "2025-08-14T19:47:39.951Z" }, { url = "https://files.pythonhosted.org/packages/95/be/7fd436adedd79c9afad14722135029010a972e17b05312795a976bc08854/uv-0.8.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c03aec1ad898642ae427b763cf5e5f90a678b91254f733ae08d01d15acd3672b", size = 18991855, upload-time = "2025-08-14T19:47:42.664Z" }, { url = "https://files.pythonhosted.org/packages/80/4e/2cca1be92fc3cdfddb5f2fa8d5650098948f357774cbe51810aaa5968da0/uv-0.8.11-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:83aa9c8b0085949542674301268e2b7b541f1108dc95664dedf50fffd1578f97", size = 20248085, upload-time = "2025-08-14T19:47:45.489Z" }, { url = "https://files.pythonhosted.org/packages/a5/9d/c4a5bbccfa45d8573d22da0d753329e572e72cd70796720dc0bc5c74e5c5/uv-0.8.11-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7e9506b3febbce3559290cb10cd1c84dbed32bc4f4b1062bc2fe4f093aa42aea", size = 19961250, upload-time = "2025-08-14T19:47:47.963Z" }, { url = "https://files.pythonhosted.org/packages/a4/f1/c1f9e59110fce261ee67cff854b4f95cae39a523d2a076c7566a704ebbe6/uv-0.8.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ba7bb038f0a263accefde1db68ecba7a756c85e6bcc25af161acef2711d6da19", size = 19314178, upload-time = "2025-08-14T19:47:50.469Z" }, { url = "https://files.pythonhosted.org/packages/fc/47/c398c3a9657a6f8c3a7b1938ae0b7061c4087e1fbb00f83a7a4f79005752/uv-0.8.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36eb184758f18347547045a3aa7cc87c98a75c773e437c8a85878eb004a31c2e", size = 19314121, upload-time = "2025-08-14T19:47:54.17Z" }, { url = "https://files.pythonhosted.org/packages/69/04/7ff94b68c33b93e89ec9920724b2a6d3992051584afd3410bf2604d2b93c/uv-0.8.11-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:0a7fcbe71cc5402b7c3d4c381f9b970a455d8ccc2a43ee2ce5ac2b617ec0534c", size = 18105431, upload-time = "2025-08-14T19:47:56.844Z" }, { url = "https://files.pythonhosted.org/packages/09/5a/aee6041cd0c9ab1c56da61ba1e9ac30b4ea7c1c85471e19cb0cc1e415c0a/uv-0.8.11-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:0da2c794dead209e660cb7df143ea9756c118ffa5874859e8a28a79101b5c760", size = 18984052, upload-time = "2025-08-14T19:47:59.927Z" }, { url = "https://files.pythonhosted.org/packages/05/cd/7b9926b676a3807312bfb91662813305b305c5218a05a9b651763b28267e/uv-0.8.11-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:0a95dc944d62db4ca282f7415c2d3c0fa3ead9e245a47d845515f5ddbd5a80ef", size = 18109344, upload-time = "2025-08-14T19:48:02.607Z" }, { url = "https://files.pythonhosted.org/packages/82/19/1e90e45fd84c4f5512dc9c8ad0ac3a4792677725047d3e7299f9dae41406/uv-0.8.11-py3-none-musllinux_1_1_i686.whl", hash = "sha256:0cd14f319e18a7b278238f0d87b18180282ec4d44d023f8b3ed2c8c091a14277", size = 18493945, upload-time = "2025-08-14T19:48:05.112Z" }, { url = "https://files.pythonhosted.org/packages/68/b8/e6b784ede573d3f1ba6fafe70dd317b4543146a6c2ca88a5f56923518552/uv-0.8.11-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:261d19395a211f980d1ebc861356cf73ba23ceece2392c0b36ade38f89fd16a6", size = 19398023, upload-time = "2025-08-14T19:48:07.993Z" }, { url = "https://files.pythonhosted.org/packages/65/5f/fd61ebec95bb5854c860d5268bc8ecbbca881465340f1e86302cacdd8234/uv-0.8.11-py3-none-win32.whl", hash = "sha256:0b922061f7b5915f224df23a849b6e1bfcace2e6b9fc0ee128868447873edb22", size = 18308608, upload-time = "2025-08-14T19:48:10.847Z" }, { url = "https://files.pythonhosted.org/packages/bb/57/84358ea67cee7ec029ed0d51e801a64c5929b7d647ae31cd5e5aea0c6f61/uv-0.8.11-py3-none-win_amd64.whl", hash = "sha256:fe01737f3ddd533903f31236219c29e09063541f17a060403acc51906ce0cfe8", size = 20214609, upload-time = "2025-08-14T19:48:13.368Z" }, { url = "https://files.pythonhosted.org/packages/e8/72/069a75703693d3297d95657957ea00d2f035896066f00a5692fbdce76d36/uv-0.8.11-py3-none-win_arm64.whl", hash = "sha256:cf3454d3407a5cac0d661b6033e3197643d0a6b5bb0e00869f6877ff7af907c9", size = 18878482, upload-time = "2025-08-14T19:48:15.743Z" }, ] [[package]] name = "virtualenv" version = "20.33.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "distlib" }, { name = "filelock" }, { name = "platformdirs" }, ] sdist = { url = "https://files.pythonhosted.org/packages/8b/60/4f20960df6c7b363a18a55ab034c8f2bcd5d9770d1f94f9370ec104c1855/virtualenv-20.33.1.tar.gz", hash = "sha256:1b44478d9e261b3fb8baa5e74a0ca3bc0e05f21aa36167bf9cbf850e542765b8", size = 6082160, upload-time = "2025-08-05T16:10:55.605Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ca/ff/ded57ac5ff40a09e6e198550bab075d780941e0b0f83cbeabd087c59383a/virtualenv-20.33.1-py3-none-any.whl", hash = "sha256:07c19bc66c11acab6a5958b815cbcee30891cd1c2ccf53785a28651a0d8d8a67", size = 6060362, upload-time = "2025-08-05T16:10:52.81Z" }, ] [[package]] name = "yarl" version = "1.20.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "multidict" }, { name = "propcache" }, ] sdist = { url = "https://files.pythonhosted.org/packages/3c/fb/efaa23fa4e45537b827620f04cf8f3cd658b76642205162e072703a5b963/yarl-1.20.1.tar.gz", hash = "sha256:d017a4997ee50c91fd5466cef416231bb82177b93b029906cefc542ce14c35ac", size = 186428, upload-time = "2025-06-10T00:46:09.923Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/cb/65/7fed0d774abf47487c64be14e9223749468922817b5e8792b8a64792a1bb/yarl-1.20.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6032e6da6abd41e4acda34d75a816012717000fa6839f37124a47fcefc49bec4", size = 132910, upload-time = "2025-06-10T00:42:31.108Z" }, { url = "https://files.pythonhosted.org/packages/8a/7b/988f55a52da99df9e56dc733b8e4e5a6ae2090081dc2754fc8fd34e60aa0/yarl-1.20.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2c7b34d804b8cf9b214f05015c4fee2ebe7ed05cf581e7192c06555c71f4446a", size = 90644, upload-time = "2025-06-10T00:42:33.851Z" }, { url = "https://files.pythonhosted.org/packages/f7/de/30d98f03e95d30c7e3cc093759982d038c8833ec2451001d45ef4854edc1/yarl-1.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0c869f2651cc77465f6cd01d938d91a11d9ea5d798738c1dc077f3de0b5e5fed", size = 89322, upload-time = "2025-06-10T00:42:35.688Z" }, { url = "https://files.pythonhosted.org/packages/e0/7a/f2f314f5ebfe9200724b0b748de2186b927acb334cf964fd312eb86fc286/yarl-1.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62915e6688eb4d180d93840cda4110995ad50c459bf931b8b3775b37c264af1e", size = 323786, upload-time = "2025-06-10T00:42:37.817Z" }, { url = "https://files.pythonhosted.org/packages/15/3f/718d26f189db96d993d14b984ce91de52e76309d0fd1d4296f34039856aa/yarl-1.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:41ebd28167bc6af8abb97fec1a399f412eec5fd61a3ccbe2305a18b84fb4ca73", size = 319627, upload-time = "2025-06-10T00:42:39.937Z" }, { url = "https://files.pythonhosted.org/packages/a5/76/8fcfbf5fa2369157b9898962a4a7d96764b287b085b5b3d9ffae69cdefd1/yarl-1.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:21242b4288a6d56f04ea193adde174b7e347ac46ce6bc84989ff7c1b1ecea84e", size = 339149, upload-time = "2025-06-10T00:42:42.627Z" }, { url = "https://files.pythonhosted.org/packages/3c/95/d7fc301cc4661785967acc04f54a4a42d5124905e27db27bb578aac49b5c/yarl-1.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bea21cdae6c7eb02ba02a475f37463abfe0a01f5d7200121b03e605d6a0439f8", size = 333327, upload-time = "2025-06-10T00:42:44.842Z" }, { url = "https://files.pythonhosted.org/packages/65/94/e21269718349582eee81efc5c1c08ee71c816bfc1585b77d0ec3f58089eb/yarl-1.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f8a891e4a22a89f5dde7862994485e19db246b70bb288d3ce73a34422e55b23", size = 326054, upload-time = "2025-06-10T00:42:47.149Z" }, { url = "https://files.pythonhosted.org/packages/32/ae/8616d1f07853704523519f6131d21f092e567c5af93de7e3e94b38d7f065/yarl-1.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dd803820d44c8853a109a34e3660e5a61beae12970da479cf44aa2954019bf70", size = 315035, upload-time = "2025-06-10T00:42:48.852Z" }, { url = "https://files.pythonhosted.org/packages/48/aa/0ace06280861ef055855333707db5e49c6e3a08840a7ce62682259d0a6c0/yarl-1.20.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b982fa7f74c80d5c0c7b5b38f908971e513380a10fecea528091405f519b9ebb", size = 338962, upload-time = "2025-06-10T00:42:51.024Z" }, { url = "https://files.pythonhosted.org/packages/20/52/1e9d0e6916f45a8fb50e6844f01cb34692455f1acd548606cbda8134cd1e/yarl-1.20.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:33f29ecfe0330c570d997bcf1afd304377f2e48f61447f37e846a6058a4d33b2", size = 335399, upload-time = "2025-06-10T00:42:53.007Z" }, { url = "https://files.pythonhosted.org/packages/f2/65/60452df742952c630e82f394cd409de10610481d9043aa14c61bf846b7b1/yarl-1.20.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:835ab2cfc74d5eb4a6a528c57f05688099da41cf4957cf08cad38647e4a83b30", size = 338649, upload-time = "2025-06-10T00:42:54.964Z" }, { url = "https://files.pythonhosted.org/packages/7b/f5/6cd4ff38dcde57a70f23719a838665ee17079640c77087404c3d34da6727/yarl-1.20.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:46b5e0ccf1943a9a6e766b2c2b8c732c55b34e28be57d8daa2b3c1d1d4009309", size = 358563, upload-time = "2025-06-10T00:42:57.28Z" }, { url = "https://files.pythonhosted.org/packages/d1/90/c42eefd79d0d8222cb3227bdd51b640c0c1d0aa33fe4cc86c36eccba77d3/yarl-1.20.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:df47c55f7d74127d1b11251fe6397d84afdde0d53b90bedb46a23c0e534f9d24", size = 357609, upload-time = "2025-06-10T00:42:59.055Z" }, { url = "https://files.pythonhosted.org/packages/03/c8/cea6b232cb4617514232e0f8a718153a95b5d82b5290711b201545825532/yarl-1.20.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:76d12524d05841276b0e22573f28d5fbcb67589836772ae9244d90dd7d66aa13", size = 350224, upload-time = "2025-06-10T00:43:01.248Z" }, { url = "https://files.pythonhosted.org/packages/ce/a3/eaa0ab9712f1f3d01faf43cf6f1f7210ce4ea4a7e9b28b489a2261ca8db9/yarl-1.20.1-cp310-cp310-win32.whl", hash = "sha256:6c4fbf6b02d70e512d7ade4b1f998f237137f1417ab07ec06358ea04f69134f8", size = 81753, upload-time = "2025-06-10T00:43:03.486Z" }, { url = "https://files.pythonhosted.org/packages/8f/34/e4abde70a9256465fe31c88ed02c3f8502b7b5dead693a4f350a06413f28/yarl-1.20.1-cp310-cp310-win_amd64.whl", hash = "sha256:aef6c4d69554d44b7f9d923245f8ad9a707d971e6209d51279196d8e8fe1ae16", size = 86817, upload-time = "2025-06-10T00:43:05.231Z" }, { url = "https://files.pythonhosted.org/packages/b1/18/893b50efc2350e47a874c5c2d67e55a0ea5df91186b2a6f5ac52eff887cd/yarl-1.20.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:47ee6188fea634bdfaeb2cc420f5b3b17332e6225ce88149a17c413c77ff269e", size = 133833, upload-time = "2025-06-10T00:43:07.393Z" }, { url = "https://files.pythonhosted.org/packages/89/ed/b8773448030e6fc47fa797f099ab9eab151a43a25717f9ac043844ad5ea3/yarl-1.20.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d0f6500f69e8402d513e5eedb77a4e1818691e8f45e6b687147963514d84b44b", size = 91070, upload-time = "2025-06-10T00:43:09.538Z" }, { url = "https://files.pythonhosted.org/packages/e3/e3/409bd17b1e42619bf69f60e4f031ce1ccb29bd7380117a55529e76933464/yarl-1.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7a8900a42fcdaad568de58887c7b2f602962356908eedb7628eaf6021a6e435b", size = 89818, upload-time = "2025-06-10T00:43:11.575Z" }, { url = "https://files.pythonhosted.org/packages/f8/77/64d8431a4d77c856eb2d82aa3de2ad6741365245a29b3a9543cd598ed8c5/yarl-1.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bad6d131fda8ef508b36be3ece16d0902e80b88ea7200f030a0f6c11d9e508d4", size = 347003, upload-time = "2025-06-10T00:43:14.088Z" }, { url = "https://files.pythonhosted.org/packages/8d/d2/0c7e4def093dcef0bd9fa22d4d24b023788b0a33b8d0088b51aa51e21e99/yarl-1.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:df018d92fe22aaebb679a7f89fe0c0f368ec497e3dda6cb81a567610f04501f1", size = 336537, upload-time = "2025-06-10T00:43:16.431Z" }, { url = "https://files.pythonhosted.org/packages/f0/f3/fc514f4b2cf02cb59d10cbfe228691d25929ce8f72a38db07d3febc3f706/yarl-1.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f969afbb0a9b63c18d0feecf0db09d164b7a44a053e78a7d05f5df163e43833", size = 362358, upload-time = "2025-06-10T00:43:18.704Z" }, { url = "https://files.pythonhosted.org/packages/ea/6d/a313ac8d8391381ff9006ac05f1d4331cee3b1efaa833a53d12253733255/yarl-1.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:812303eb4aa98e302886ccda58d6b099e3576b1b9276161469c25803a8db277d", size = 357362, upload-time = "2025-06-10T00:43:20.888Z" }, { url = "https://files.pythonhosted.org/packages/00/70/8f78a95d6935a70263d46caa3dd18e1f223cf2f2ff2037baa01a22bc5b22/yarl-1.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98c4a7d166635147924aa0bf9bfe8d8abad6fffa6102de9c99ea04a1376f91e8", size = 348979, upload-time = "2025-06-10T00:43:23.169Z" }, { url = "https://files.pythonhosted.org/packages/cb/05/42773027968968f4f15143553970ee36ead27038d627f457cc44bbbeecf3/yarl-1.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12e768f966538e81e6e7550f9086a6236b16e26cd964cf4df35349970f3551cf", size = 337274, upload-time = "2025-06-10T00:43:27.111Z" }, { url = "https://files.pythonhosted.org/packages/05/be/665634aa196954156741ea591d2f946f1b78ceee8bb8f28488bf28c0dd62/yarl-1.20.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fe41919b9d899661c5c28a8b4b0acf704510b88f27f0934ac7a7bebdd8938d5e", size = 363294, upload-time = "2025-06-10T00:43:28.96Z" }, { url = "https://files.pythonhosted.org/packages/eb/90/73448401d36fa4e210ece5579895731f190d5119c4b66b43b52182e88cd5/yarl-1.20.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:8601bc010d1d7780592f3fc1bdc6c72e2b6466ea34569778422943e1a1f3c389", size = 358169, upload-time = "2025-06-10T00:43:30.701Z" }, { url = "https://files.pythonhosted.org/packages/c3/b0/fce922d46dc1eb43c811f1889f7daa6001b27a4005587e94878570300881/yarl-1.20.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:daadbdc1f2a9033a2399c42646fbd46da7992e868a5fe9513860122d7fe7a73f", size = 362776, upload-time = "2025-06-10T00:43:32.51Z" }, { url = "https://files.pythonhosted.org/packages/f1/0d/b172628fce039dae8977fd22caeff3eeebffd52e86060413f5673767c427/yarl-1.20.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:03aa1e041727cb438ca762628109ef1333498b122e4c76dd858d186a37cec845", size = 381341, upload-time = "2025-06-10T00:43:34.543Z" }, { url = "https://files.pythonhosted.org/packages/6b/9b/5b886d7671f4580209e855974fe1cecec409aa4a89ea58b8f0560dc529b1/yarl-1.20.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:642980ef5e0fa1de5fa96d905c7e00cb2c47cb468bfcac5a18c58e27dbf8d8d1", size = 379988, upload-time = "2025-06-10T00:43:36.489Z" }, { url = "https://files.pythonhosted.org/packages/73/be/75ef5fd0fcd8f083a5d13f78fd3f009528132a1f2a1d7c925c39fa20aa79/yarl-1.20.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:86971e2795584fe8c002356d3b97ef6c61862720eeff03db2a7c86b678d85b3e", size = 371113, upload-time = "2025-06-10T00:43:38.592Z" }, { url = "https://files.pythonhosted.org/packages/50/4f/62faab3b479dfdcb741fe9e3f0323e2a7d5cd1ab2edc73221d57ad4834b2/yarl-1.20.1-cp311-cp311-win32.whl", hash = "sha256:597f40615b8d25812f14562699e287f0dcc035d25eb74da72cae043bb884d773", size = 81485, upload-time = "2025-06-10T00:43:41.038Z" }, { url = "https://files.pythonhosted.org/packages/f0/09/d9c7942f8f05c32ec72cd5c8e041c8b29b5807328b68b4801ff2511d4d5e/yarl-1.20.1-cp311-cp311-win_amd64.whl", hash = "sha256:26ef53a9e726e61e9cd1cda6b478f17e350fb5800b4bd1cd9fe81c4d91cfeb2e", size = 86686, upload-time = "2025-06-10T00:43:42.692Z" }, { url = "https://files.pythonhosted.org/packages/5f/9a/cb7fad7d73c69f296eda6815e4a2c7ed53fc70c2f136479a91c8e5fbdb6d/yarl-1.20.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdcc4cd244e58593a4379fe60fdee5ac0331f8eb70320a24d591a3be197b94a9", size = 133667, upload-time = "2025-06-10T00:43:44.369Z" }, { url = "https://files.pythonhosted.org/packages/67/38/688577a1cb1e656e3971fb66a3492501c5a5df56d99722e57c98249e5b8a/yarl-1.20.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b29a2c385a5f5b9c7d9347e5812b6f7ab267193c62d282a540b4fc528c8a9d2a", size = 91025, upload-time = "2025-06-10T00:43:46.295Z" }, { url = "https://files.pythonhosted.org/packages/50/ec/72991ae51febeb11a42813fc259f0d4c8e0507f2b74b5514618d8b640365/yarl-1.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1112ae8154186dfe2de4732197f59c05a83dc814849a5ced892b708033f40dc2", size = 89709, upload-time = "2025-06-10T00:43:48.22Z" }, { url = "https://files.pythonhosted.org/packages/99/da/4d798025490e89426e9f976702e5f9482005c548c579bdae792a4c37769e/yarl-1.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90bbd29c4fe234233f7fa2b9b121fb63c321830e5d05b45153a2ca68f7d310ee", size = 352287, upload-time = "2025-06-10T00:43:49.924Z" }, { url = "https://files.pythonhosted.org/packages/1a/26/54a15c6a567aac1c61b18aa0f4b8aa2e285a52d547d1be8bf48abe2b3991/yarl-1.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:680e19c7ce3710ac4cd964e90dad99bf9b5029372ba0c7cbfcd55e54d90ea819", size = 345429, upload-time = "2025-06-10T00:43:51.7Z" }, { url = "https://files.pythonhosted.org/packages/d6/95/9dcf2386cb875b234353b93ec43e40219e14900e046bf6ac118f94b1e353/yarl-1.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a979218c1fdb4246a05efc2cc23859d47c89af463a90b99b7c56094daf25a16", size = 365429, upload-time = "2025-06-10T00:43:53.494Z" }, { url = "https://files.pythonhosted.org/packages/91/b2/33a8750f6a4bc224242a635f5f2cff6d6ad5ba651f6edcccf721992c21a0/yarl-1.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255b468adf57b4a7b65d8aad5b5138dce6a0752c139965711bdcb81bc370e1b6", size = 363862, upload-time = "2025-06-10T00:43:55.766Z" }, { url = "https://files.pythonhosted.org/packages/98/28/3ab7acc5b51f4434b181b0cee8f1f4b77a65919700a355fb3617f9488874/yarl-1.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a97d67108e79cfe22e2b430d80d7571ae57d19f17cda8bb967057ca8a7bf5bfd", size = 355616, upload-time = "2025-06-10T00:43:58.056Z" }, { url = "https://files.pythonhosted.org/packages/36/a3/f666894aa947a371724ec7cd2e5daa78ee8a777b21509b4252dd7bd15e29/yarl-1.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8570d998db4ddbfb9a590b185a0a33dbf8aafb831d07a5257b4ec9948df9cb0a", size = 339954, upload-time = "2025-06-10T00:43:59.773Z" }, { url = "https://files.pythonhosted.org/packages/f1/81/5f466427e09773c04219d3450d7a1256138a010b6c9f0af2d48565e9ad13/yarl-1.20.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:97c75596019baae7c71ccf1d8cc4738bc08134060d0adfcbe5642f778d1dca38", size = 365575, upload-time = "2025-06-10T00:44:02.051Z" }, { url = "https://files.pythonhosted.org/packages/2e/e3/e4b0ad8403e97e6c9972dd587388940a032f030ebec196ab81a3b8e94d31/yarl-1.20.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1c48912653e63aef91ff988c5432832692ac5a1d8f0fb8a33091520b5bbe19ef", size = 365061, upload-time = "2025-06-10T00:44:04.196Z" }, { url = "https://files.pythonhosted.org/packages/ac/99/b8a142e79eb86c926f9f06452eb13ecb1bb5713bd01dc0038faf5452e544/yarl-1.20.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4c3ae28f3ae1563c50f3d37f064ddb1511ecc1d5584e88c6b7c63cf7702a6d5f", size = 364142, upload-time = "2025-06-10T00:44:06.527Z" }, { url = "https://files.pythonhosted.org/packages/34/f2/08ed34a4a506d82a1a3e5bab99ccd930a040f9b6449e9fd050320e45845c/yarl-1.20.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c5e9642f27036283550f5f57dc6156c51084b458570b9d0d96100c8bebb186a8", size = 381894, upload-time = "2025-06-10T00:44:08.379Z" }, { url = "https://files.pythonhosted.org/packages/92/f8/9a3fbf0968eac704f681726eff595dce9b49c8a25cd92bf83df209668285/yarl-1.20.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2c26b0c49220d5799f7b22c6838409ee9bc58ee5c95361a4d7831f03cc225b5a", size = 383378, upload-time = "2025-06-10T00:44:10.51Z" }, { url = "https://files.pythonhosted.org/packages/af/85/9363f77bdfa1e4d690957cd39d192c4cacd1c58965df0470a4905253b54f/yarl-1.20.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:564ab3d517e3d01c408c67f2e5247aad4019dcf1969982aba3974b4093279004", size = 374069, upload-time = "2025-06-10T00:44:12.834Z" }, { url = "https://files.pythonhosted.org/packages/35/99/9918c8739ba271dcd935400cff8b32e3cd319eaf02fcd023d5dcd487a7c8/yarl-1.20.1-cp312-cp312-win32.whl", hash = "sha256:daea0d313868da1cf2fac6b2d3a25c6e3a9e879483244be38c8e6a41f1d876a5", size = 81249, upload-time = "2025-06-10T00:44:14.731Z" }, { url = "https://files.pythonhosted.org/packages/eb/83/5d9092950565481b413b31a23e75dd3418ff0a277d6e0abf3729d4d1ce25/yarl-1.20.1-cp312-cp312-win_amd64.whl", hash = "sha256:48ea7d7f9be0487339828a4de0360d7ce0efc06524a48e1810f945c45b813698", size = 86710, upload-time = "2025-06-10T00:44:16.716Z" }, { url = "https://files.pythonhosted.org/packages/8a/e1/2411b6d7f769a07687acee88a062af5833cf1966b7266f3d8dfb3d3dc7d3/yarl-1.20.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:0b5ff0fbb7c9f1b1b5ab53330acbfc5247893069e7716840c8e7d5bb7355038a", size = 131811, upload-time = "2025-06-10T00:44:18.933Z" }, { url = "https://files.pythonhosted.org/packages/b2/27/584394e1cb76fb771371770eccad35de400e7b434ce3142c2dd27392c968/yarl-1.20.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:14f326acd845c2b2e2eb38fb1346c94f7f3b01a4f5c788f8144f9b630bfff9a3", size = 90078, upload-time = "2025-06-10T00:44:20.635Z" }, { url = "https://files.pythonhosted.org/packages/bf/9a/3246ae92d4049099f52d9b0fe3486e3b500e29b7ea872d0f152966fc209d/yarl-1.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f60e4ad5db23f0b96e49c018596707c3ae89f5d0bd97f0ad3684bcbad899f1e7", size = 88748, upload-time = "2025-06-10T00:44:22.34Z" }, { url = "https://files.pythonhosted.org/packages/a3/25/35afe384e31115a1a801fbcf84012d7a066d89035befae7c5d4284df1e03/yarl-1.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49bdd1b8e00ce57e68ba51916e4bb04461746e794e7c4d4bbc42ba2f18297691", size = 349595, upload-time = "2025-06-10T00:44:24.314Z" }, { url = "https://files.pythonhosted.org/packages/28/2d/8aca6cb2cabc8f12efcb82749b9cefecbccfc7b0384e56cd71058ccee433/yarl-1.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:66252d780b45189975abfed839616e8fd2dbacbdc262105ad7742c6ae58f3e31", size = 342616, upload-time = "2025-06-10T00:44:26.167Z" }, { url = "https://files.pythonhosted.org/packages/0b/e9/1312633d16b31acf0098d30440ca855e3492d66623dafb8e25b03d00c3da/yarl-1.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59174e7332f5d153d8f7452a102b103e2e74035ad085f404df2e40e663a22b28", size = 361324, upload-time = "2025-06-10T00:44:27.915Z" }, { url = "https://files.pythonhosted.org/packages/bc/a0/688cc99463f12f7669eec7c8acc71ef56a1521b99eab7cd3abb75af887b0/yarl-1.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e3968ec7d92a0c0f9ac34d5ecfd03869ec0cab0697c91a45db3fbbd95fe1b653", size = 359676, upload-time = "2025-06-10T00:44:30.041Z" }, { url = "https://files.pythonhosted.org/packages/af/44/46407d7f7a56e9a85a4c207724c9f2c545c060380718eea9088f222ba697/yarl-1.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1a4fbb50e14396ba3d375f68bfe02215d8e7bc3ec49da8341fe3157f59d2ff5", size = 352614, upload-time = "2025-06-10T00:44:32.171Z" }, { url = "https://files.pythonhosted.org/packages/b1/91/31163295e82b8d5485d31d9cf7754d973d41915cadce070491778d9c9825/yarl-1.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11a62c839c3a8eac2410e951301309426f368388ff2f33799052787035793b02", size = 336766, upload-time = "2025-06-10T00:44:34.494Z" }, { url = "https://files.pythonhosted.org/packages/b4/8e/c41a5bc482121f51c083c4c2bcd16b9e01e1cf8729e380273a952513a21f/yarl-1.20.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:041eaa14f73ff5a8986b4388ac6bb43a77f2ea09bf1913df7a35d4646db69e53", size = 364615, upload-time = "2025-06-10T00:44:36.856Z" }, { url = "https://files.pythonhosted.org/packages/e3/5b/61a3b054238d33d70ea06ebba7e58597891b71c699e247df35cc984ab393/yarl-1.20.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:377fae2fef158e8fd9d60b4c8751387b8d1fb121d3d0b8e9b0be07d1b41e83dc", size = 360982, upload-time = "2025-06-10T00:44:39.141Z" }, { url = "https://files.pythonhosted.org/packages/df/a3/6a72fb83f8d478cb201d14927bc8040af901811a88e0ff2da7842dd0ed19/yarl-1.20.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1c92f4390e407513f619d49319023664643d3339bd5e5a56a3bebe01bc67ec04", size = 369792, upload-time = "2025-06-10T00:44:40.934Z" }, { url = "https://files.pythonhosted.org/packages/7c/af/4cc3c36dfc7c077f8dedb561eb21f69e1e9f2456b91b593882b0b18c19dc/yarl-1.20.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d25ddcf954df1754ab0f86bb696af765c5bfaba39b74095f27eececa049ef9a4", size = 382049, upload-time = "2025-06-10T00:44:42.854Z" }, { url = "https://files.pythonhosted.org/packages/19/3a/e54e2c4752160115183a66dc9ee75a153f81f3ab2ba4bf79c3c53b33de34/yarl-1.20.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:909313577e9619dcff8c31a0ea2aa0a2a828341d92673015456b3ae492e7317b", size = 384774, upload-time = "2025-06-10T00:44:45.275Z" }, { url = "https://files.pythonhosted.org/packages/9c/20/200ae86dabfca89060ec6447649f219b4cbd94531e425e50d57e5f5ac330/yarl-1.20.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:793fd0580cb9664548c6b83c63b43c477212c0260891ddf86809e1c06c8b08f1", size = 374252, upload-time = "2025-06-10T00:44:47.31Z" }, { url = "https://files.pythonhosted.org/packages/83/75/11ee332f2f516b3d094e89448da73d557687f7d137d5a0f48c40ff211487/yarl-1.20.1-cp313-cp313-win32.whl", hash = "sha256:468f6e40285de5a5b3c44981ca3a319a4b208ccc07d526b20b12aeedcfa654b7", size = 81198, upload-time = "2025-06-10T00:44:49.164Z" }, { url = "https://files.pythonhosted.org/packages/ba/ba/39b1ecbf51620b40ab402b0fc817f0ff750f6d92712b44689c2c215be89d/yarl-1.20.1-cp313-cp313-win_amd64.whl", hash = "sha256:495b4ef2fea40596bfc0affe3837411d6aa3371abcf31aac0ccc4bdd64d4ef5c", size = 86346, upload-time = "2025-06-10T00:44:51.182Z" }, { url = "https://files.pythonhosted.org/packages/43/c7/669c52519dca4c95153c8ad96dd123c79f354a376346b198f438e56ffeb4/yarl-1.20.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:f60233b98423aab21d249a30eb27c389c14929f47be8430efa7dbd91493a729d", size = 138826, upload-time = "2025-06-10T00:44:52.883Z" }, { url = "https://files.pythonhosted.org/packages/6a/42/fc0053719b44f6ad04a75d7f05e0e9674d45ef62f2d9ad2c1163e5c05827/yarl-1.20.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:6f3eff4cc3f03d650d8755c6eefc844edde99d641d0dcf4da3ab27141a5f8ddf", size = 93217, upload-time = "2025-06-10T00:44:54.658Z" }, { url = "https://files.pythonhosted.org/packages/4f/7f/fa59c4c27e2a076bba0d959386e26eba77eb52ea4a0aac48e3515c186b4c/yarl-1.20.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:69ff8439d8ba832d6bed88af2c2b3445977eba9a4588b787b32945871c2444e3", size = 92700, upload-time = "2025-06-10T00:44:56.784Z" }, { url = "https://files.pythonhosted.org/packages/2f/d4/062b2f48e7c93481e88eff97a6312dca15ea200e959f23e96d8ab898c5b8/yarl-1.20.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cf34efa60eb81dd2645a2e13e00bb98b76c35ab5061a3989c7a70f78c85006d", size = 347644, upload-time = "2025-06-10T00:44:59.071Z" }, { url = "https://files.pythonhosted.org/packages/89/47/78b7f40d13c8f62b499cc702fdf69e090455518ae544c00a3bf4afc9fc77/yarl-1.20.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8e0fe9364ad0fddab2688ce72cb7a8e61ea42eff3c7caeeb83874a5d479c896c", size = 323452, upload-time = "2025-06-10T00:45:01.605Z" }, { url = "https://files.pythonhosted.org/packages/eb/2b/490d3b2dc66f52987d4ee0d3090a147ea67732ce6b4d61e362c1846d0d32/yarl-1.20.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f64fbf81878ba914562c672024089e3401974a39767747691c65080a67b18c1", size = 346378, upload-time = "2025-06-10T00:45:03.946Z" }, { url = "https://files.pythonhosted.org/packages/66/ad/775da9c8a94ce925d1537f939a4f17d782efef1f973039d821cbe4bcc211/yarl-1.20.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6342d643bf9a1de97e512e45e4b9560a043347e779a173250824f8b254bd5ce", size = 353261, upload-time = "2025-06-10T00:45:05.992Z" }, { url = "https://files.pythonhosted.org/packages/4b/23/0ed0922b47a4f5c6eb9065d5ff1e459747226ddce5c6a4c111e728c9f701/yarl-1.20.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56dac5f452ed25eef0f6e3c6a066c6ab68971d96a9fb441791cad0efba6140d3", size = 335987, upload-time = "2025-06-10T00:45:08.227Z" }, { url = "https://files.pythonhosted.org/packages/3e/49/bc728a7fe7d0e9336e2b78f0958a2d6b288ba89f25a1762407a222bf53c3/yarl-1.20.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7d7f497126d65e2cad8dc5f97d34c27b19199b6414a40cb36b52f41b79014be", size = 329361, upload-time = "2025-06-10T00:45:10.11Z" }, { url = "https://files.pythonhosted.org/packages/93/8f/b811b9d1f617c83c907e7082a76e2b92b655400e61730cd61a1f67178393/yarl-1.20.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:67e708dfb8e78d8a19169818eeb5c7a80717562de9051bf2413aca8e3696bf16", size = 346460, upload-time = "2025-06-10T00:45:12.055Z" }, { url = "https://files.pythonhosted.org/packages/70/fd/af94f04f275f95da2c3b8b5e1d49e3e79f1ed8b6ceb0f1664cbd902773ff/yarl-1.20.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:595c07bc79af2494365cc96ddeb772f76272364ef7c80fb892ef9d0649586513", size = 334486, upload-time = "2025-06-10T00:45:13.995Z" }, { url = "https://files.pythonhosted.org/packages/84/65/04c62e82704e7dd0a9b3f61dbaa8447f8507655fd16c51da0637b39b2910/yarl-1.20.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7bdd2f80f4a7df852ab9ab49484a4dee8030023aa536df41f2d922fd57bf023f", size = 342219, upload-time = "2025-06-10T00:45:16.479Z" }, { url = "https://files.pythonhosted.org/packages/91/95/459ca62eb958381b342d94ab9a4b6aec1ddec1f7057c487e926f03c06d30/yarl-1.20.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:c03bfebc4ae8d862f853a9757199677ab74ec25424d0ebd68a0027e9c639a390", size = 350693, upload-time = "2025-06-10T00:45:18.399Z" }, { url = "https://files.pythonhosted.org/packages/a6/00/d393e82dd955ad20617abc546a8f1aee40534d599ff555ea053d0ec9bf03/yarl-1.20.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:344d1103e9c1523f32a5ed704d576172d2cabed3122ea90b1d4e11fe17c66458", size = 355803, upload-time = "2025-06-10T00:45:20.677Z" }, { url = "https://files.pythonhosted.org/packages/9e/ed/c5fb04869b99b717985e244fd93029c7a8e8febdfcffa06093e32d7d44e7/yarl-1.20.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:88cab98aa4e13e1ade8c141daeedd300a4603b7132819c484841bb7af3edce9e", size = 341709, upload-time = "2025-06-10T00:45:23.221Z" }, { url = "https://files.pythonhosted.org/packages/24/fd/725b8e73ac2a50e78a4534ac43c6addf5c1c2d65380dd48a9169cc6739a9/yarl-1.20.1-cp313-cp313t-win32.whl", hash = "sha256:b121ff6a7cbd4abc28985b6028235491941b9fe8fe226e6fdc539c977ea1739d", size = 86591, upload-time = "2025-06-10T00:45:25.793Z" }, { url = "https://files.pythonhosted.org/packages/94/c3/b2e9f38bc3e11191981d57ea08cab2166e74ea770024a646617c9cddd9f6/yarl-1.20.1-cp313-cp313t-win_amd64.whl", hash = "sha256:541d050a355bbbc27e55d906bc91cb6fe42f96c01413dd0f4ed5a5240513874f", size = 93003, upload-time = "2025-06-10T00:45:27.752Z" }, { url = "https://files.pythonhosted.org/packages/01/75/0d37402d208d025afa6b5b8eb80e466d267d3fd1927db8e317d29a94a4cb/yarl-1.20.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e42ba79e2efb6845ebab49c7bf20306c4edf74a0b20fc6b2ccdd1a219d12fad3", size = 134259, upload-time = "2025-06-10T00:45:29.882Z" }, { url = "https://files.pythonhosted.org/packages/73/84/1fb6c85ae0cf9901046f07d0ac9eb162f7ce6d95db541130aa542ed377e6/yarl-1.20.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:41493b9b7c312ac448b7f0a42a089dffe1d6e6e981a2d76205801a023ed26a2b", size = 91269, upload-time = "2025-06-10T00:45:32.917Z" }, { url = "https://files.pythonhosted.org/packages/f3/9c/eae746b24c4ea29a5accba9a06c197a70fa38a49c7df244e0d3951108861/yarl-1.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f5a5928ff5eb13408c62a968ac90d43f8322fd56d87008b8f9dabf3c0f6ee983", size = 89995, upload-time = "2025-06-10T00:45:35.066Z" }, { url = "https://files.pythonhosted.org/packages/fb/30/693e71003ec4bc1daf2e4cf7c478c417d0985e0a8e8f00b2230d517876fc/yarl-1.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30c41ad5d717b3961b2dd785593b67d386b73feca30522048d37298fee981805", size = 325253, upload-time = "2025-06-10T00:45:37.052Z" }, { url = "https://files.pythonhosted.org/packages/0f/a2/5264dbebf90763139aeb0b0b3154763239398400f754ae19a0518b654117/yarl-1.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:59febc3969b0781682b469d4aca1a5cab7505a4f7b85acf6db01fa500fa3f6ba", size = 320897, upload-time = "2025-06-10T00:45:39.962Z" }, { url = "https://files.pythonhosted.org/packages/e7/17/77c7a89b3c05856489777e922f41db79ab4faf58621886df40d812c7facd/yarl-1.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d2b6fb3622b7e5bf7a6e5b679a69326b4279e805ed1699d749739a61d242449e", size = 340696, upload-time = "2025-06-10T00:45:41.915Z" }, { url = "https://files.pythonhosted.org/packages/6d/55/28409330b8ef5f2f681f5b478150496ec9cf3309b149dab7ec8ab5cfa3f0/yarl-1.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:749d73611db8d26a6281086f859ea7ec08f9c4c56cec864e52028c8b328db723", size = 335064, upload-time = "2025-06-10T00:45:43.893Z" }, { url = "https://files.pythonhosted.org/packages/85/58/cb0257cbd4002828ff735f44d3c5b6966c4fd1fc8cc1cd3cd8a143fbc513/yarl-1.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9427925776096e664c39e131447aa20ec738bdd77c049c48ea5200db2237e000", size = 327256, upload-time = "2025-06-10T00:45:46.393Z" }, { url = "https://files.pythonhosted.org/packages/53/f6/c77960370cfa46f6fb3d6a5a79a49d3abfdb9ef92556badc2dcd2748bc2a/yarl-1.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff70f32aa316393eaf8222d518ce9118148eddb8a53073c2403863b41033eed5", size = 316389, upload-time = "2025-06-10T00:45:48.358Z" }, { url = "https://files.pythonhosted.org/packages/64/ab/be0b10b8e029553c10905b6b00c64ecad3ebc8ace44b02293a62579343f6/yarl-1.20.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c7ddf7a09f38667aea38801da8b8d6bfe81df767d9dfc8c88eb45827b195cd1c", size = 340481, upload-time = "2025-06-10T00:45:50.663Z" }, { url = "https://files.pythonhosted.org/packages/c5/c3/3f327bd3905a4916029bf5feb7f86dcf864c7704f099715f62155fb386b2/yarl-1.20.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:57edc88517d7fc62b174fcfb2e939fbc486a68315d648d7e74d07fac42cec240", size = 336941, upload-time = "2025-06-10T00:45:52.554Z" }, { url = "https://files.pythonhosted.org/packages/d1/42/040bdd5d3b3bb02b4a6ace4ed4075e02f85df964d6e6cb321795d2a6496a/yarl-1.20.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:dab096ce479d5894d62c26ff4f699ec9072269d514b4edd630a393223f45a0ee", size = 339936, upload-time = "2025-06-10T00:45:54.919Z" }, { url = "https://files.pythonhosted.org/packages/0d/1c/911867b8e8c7463b84dfdc275e0d99b04b66ad5132b503f184fe76be8ea4/yarl-1.20.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:14a85f3bd2d7bb255be7183e5d7d6e70add151a98edf56a770d6140f5d5f4010", size = 360163, upload-time = "2025-06-10T00:45:56.87Z" }, { url = "https://files.pythonhosted.org/packages/e2/31/8c389f6c6ca0379b57b2da87f1f126c834777b4931c5ee8427dd65d0ff6b/yarl-1.20.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2c89b5c792685dd9cd3fa9761c1b9f46fc240c2a3265483acc1565769996a3f8", size = 359108, upload-time = "2025-06-10T00:45:58.869Z" }, { url = "https://files.pythonhosted.org/packages/7f/09/ae4a649fb3964324c70a3e2b61f45e566d9ffc0affd2b974cbf628957673/yarl-1.20.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:69e9b141de5511021942a6866990aea6d111c9042235de90e08f94cf972ca03d", size = 351875, upload-time = "2025-06-10T00:46:01.45Z" }, { url = "https://files.pythonhosted.org/packages/8d/43/bbb4ed4c34d5bb62b48bf957f68cd43f736f79059d4f85225ab1ef80f4b9/yarl-1.20.1-cp39-cp39-win32.whl", hash = "sha256:b5f307337819cdfdbb40193cad84978a029f847b0a357fbe49f712063cfc4f06", size = 82293, upload-time = "2025-06-10T00:46:03.763Z" }, { url = "https://files.pythonhosted.org/packages/d7/cd/ce185848a7dba68ea69e932674b5c1a42a1852123584bccc5443120f857c/yarl-1.20.1-cp39-cp39-win_amd64.whl", hash = "sha256:eae7bfe2069f9c1c5b05fc7fe5d612e5bbc089a39309904ee8b829e322dcad00", size = 87385, upload-time = "2025-06-10T00:46:05.655Z" }, { url = "https://files.pythonhosted.org/packages/b4/2d/2345fce04cfd4bee161bf1e7d9cdc702e3e16109021035dbb24db654a622/yarl-1.20.1-py3-none-any.whl", hash = "sha256:83b8eb083fe4683c6115795d9fc1cfaf2cbbefb19b3a1cb68f6527460f483a77", size = 46542, upload-time = "2025-06-10T00:46:07.521Z" }, ] [[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" }, ]