From 1676fd10c93275ff0122c0f3123c984eb0a132a9 Mon Sep 17 00:00:00 2001 From: Brian Bjarke Jensen Date: Thu, 30 Oct 2025 00:00:02 +0100 Subject: [PATCH] initial commit --- .gitea/workflows/python-code-quality.yml | 13 + .gitea/workflows/python-pytest.yml | 47 + .gitignore | 1 - .pre-commit-config.yaml | 40 + LICENSE | 18 +- POC.ipynb | 26 + README.md | 274 +++++- pyproject.toml | 51 + src/elprisenligenu/__init__.py | 3 + src/elprisenligenu/api.py | 60 ++ src/elprisenligenu/dto/__init__.py | 3 + src/elprisenligenu/dto/hour_data.py | 14 + src/elprisenligenu/py.typed | 0 tests/__init__.py | 1 + tests/integration/conftest.py | 48 + tests/integration/test_integration.py | 152 +++ tests/unit/__init__.py | 1 + tests/unit/test_api.py | 321 +++++++ tests/unit/test_hour_data.py | 229 +++++ uv.lock | 1095 ++++++++++++++++++++++ 20 files changed, 2385 insertions(+), 12 deletions(-) create mode 100644 .gitea/workflows/python-code-quality.yml create mode 100644 .gitea/workflows/python-pytest.yml create mode 100644 .pre-commit-config.yaml create mode 100644 POC.ipynb create mode 100644 pyproject.toml create mode 100644 src/elprisenligenu/__init__.py create mode 100644 src/elprisenligenu/api.py create mode 100644 src/elprisenligenu/dto/__init__.py create mode 100644 src/elprisenligenu/dto/hour_data.py create mode 100644 src/elprisenligenu/py.typed create mode 100644 tests/__init__.py create mode 100644 tests/integration/conftest.py create mode 100644 tests/integration/test_integration.py create mode 100644 tests/unit/__init__.py create mode 100644 tests/unit/test_api.py create mode 100644 tests/unit/test_hour_data.py create mode 100644 uv.lock diff --git a/.gitea/workflows/python-code-quality.yml b/.gitea/workflows/python-code-quality.yml new file mode 100644 index 0000000..b75fee6 --- /dev/null +++ b/.gitea/workflows/python-code-quality.yml @@ -0,0 +1,13 @@ +name: Python Code Quality + +on: + push: + branches: + - main + pull_request: + +jobs: + python-code-quality: + uses: brian/CI-templates/.gitea/workflows/python/code-quality.yml@v1.0.0 + with: + python-version: ${{ vars.PYTHON_VERSION }} diff --git a/.gitea/workflows/python-pytest.yml b/.gitea/workflows/python-pytest.yml new file mode 100644 index 0000000..a75c48c --- /dev/null +++ b/.gitea/workflows/python-pytest.yml @@ -0,0 +1,47 @@ +name: Test Python Package + +on: + push: + branches: + - main + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ inputs.python-version }} + + - name: Install uv + run: pip install uv + + - name: Install dependencies + env: + UV_LINK_MODE: copy + run: uv sync --all-extras + + - name: Run pytest + env: + PYTHONPATH: . + run: uv run pytest --cov=python_repositories --cov-report=term-missing > coverage.txt + + - name: Post coverage summary to PR + env: + API_URL: ${{ vars.API_URL }} + REPO_OWNER: ${{ github.repository_owner }} + REPO_NAME: ${{ github.event.repository.name }} + PR_NUMBER: ${{ github.event.pull_request.number }} + CI_RUNNER_TOKEN: ${{ secrets.CI_RUNNER_TOKEN }} + run: | + COVERAGE=$(cat coverage.txt) + COMMENT_BODY="**Test Coverage Report:**\n\`\`\`\n$COVERAGE\n\`\`\`" + curl -s -X POST "$API_URL/repos/$REPO_OWNER/$REPO_NAME/issues/$PR_NUMBER/comments" \ + -H "Authorization: token $CI_RUNNER_TOKEN" \ + -H "Content-Type: application/json" \ + -d "{\"body\": \"$COMMENT_BODY\"}" diff --git a/.gitignore b/.gitignore index cac109b..4a78709 100644 --- a/.gitignore +++ b/.gitignore @@ -187,4 +187,3 @@ ipython_config.py # Remove previous ipynb_checkpoints # git rm -r .ipynb_checkpoints/ - diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..b7e0522 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,40 @@ +repos: + # General repository hygiene hooks + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files + - id: debug-statements + - id: name-tests-test + - id: check-merge-conflict + + # Python linting and formatting with Ruff + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.12.8 + hooks: + - id: ruff-check + args: [--fix] + - id: ruff-format + + # Static type checking with mypy + - repo: https://github.com/pre-commit/mirrors-mypy + rev: v1.8.0 + hooks: + - id: mypy + + # Python syntax modernization with pyupgrade + - repo: https://github.com/asottile/pyupgrade + rev: v3.20.0 + hooks: + - id: pyupgrade + args: ["--py312-plus"] + + # Formatting for Markdown, JSON, and YAML with Prettier + - repo: https://github.com/pre-commit/mirrors-prettier + rev: v3.1.0 + hooks: + - id: prettier + files: "\\.(md|json|yaml|yml)$" diff --git a/LICENSE b/LICENSE index f4e7ad7..d6a6398 100644 --- a/LICENSE +++ b/LICENSE @@ -2,17 +2,17 @@ MIT License Copyright (c) 2025 brian -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 +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 +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 +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. diff --git a/POC.ipynb b/POC.ipynb new file mode 100644 index 0000000..4fb6cc7 --- /dev/null +++ b/POC.ipynb @@ -0,0 +1,26 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "258945b9", + "metadata": { + "vscode": { + "languageId": "plaintext" + } + }, + "outputs": [], + "source": [ + "import requests\n", + "\n" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/README.md b/README.md index 56e6aa3..39ca267 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,273 @@ -# elprisenligenu +# ElprisenLigeNu Python API Client -Python module to interface with ElPrisenLigeNu's API. \ No newline at end of file +A Python library for accessing Danish electricity spot prices from the [ElprisenLigeNu.dk](https://www.elprisenligenu.dk) API. + +[![Python Version](https://img.shields.io/badge/python-3.12%2B-blue.svg)](https://python.org) +[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE) + +## Overview + +ElprisenLigeNu provides real-time and historical Danish electricity spot prices for the two Danish price zones: + +- **DK1** (West of Great Belt - Jutland and Funen) +- **DK2** (East of Great Belt - Zealand and Bornholm) + +This library provides a simple Python interface to fetch hourly electricity prices with automatic timezone handling and type-safe data models. + +## Features + +- πŸ”Œ Simple API for fetching electricity prices +- πŸ‡©πŸ‡° Support for both Danish price zones (DK1/DK2) +- ⏰ Automatic timezone handling (Europe/Copenhagen) +- πŸ“Š Type-safe data models using Pydantic +- πŸ’° Prices in both DKK and EUR with exchange rates +- πŸ• Hourly granularity with start/end timestamps + +## Installation + +```bash +pip install elprisenligenu +``` + +Or using uv: + +```bash +uv add elprisenligenu +``` + +## Quick Start + +```python +from datetime import datetime +from elprisenligenu import API + +# Initialize the API client +api = API() + +# Get today's prices for Copenhagen area (DK2) +prices = api.get_daily_prices(zone="DK2") + +# Get prices for Aarhus area (DK1) +prices = api.get_daily_prices(zone="DK1") + +# Get prices for a specific date +from datetime import datetime +from zoneinfo import ZoneInfo + +date = datetime(2024, 10, 29, tzinfo=ZoneInfo("Europe/Copenhagen")) +prices = api.get_daily_prices(zone="DK2", date=date) + +# Work with the price data +for hour_data in prices: + print(f"Time: {hour_data.time_start} - {hour_data.time_end}") + print(f"Price: {hour_data.DKK_per_kWh:.4f} DKK/kWh") + print(f"Price: {hour_data.EUR_per_kWh:.4f} EUR/kWh") + print(f"Exchange rate: {hour_data.EXR:.4f}") + print("---") +``` + +## API Reference + +### API Class + +```python +from elprisenligenu import API + +api = API() +``` + +#### Methods + +##### `get_daily_prices(zone="DK1", date=datetime.now())` + +Fetch hourly electricity prices for a specific day and zone. + +**Parameters:** + +- `zone` (str): Price zone, either "DK1" or "DK2". Default: "DK1" +- `date` (datetime): Date to fetch prices for. Must be timezone-aware. Default: current date + +**Returns:** + +- `list[HourData]`: List of hourly price data objects + +**Raises:** + +- `ValueError`: If zone is not "DK1" or "DK2", or if date is not timezone-aware +- `TypeError`: If date is not a datetime object +- `requests.HTTPError`: If the API request fails + +### HourData Model + +The `HourData` class represents electricity price data for a single hour: + +```python +from elprisenligenu.dto import HourData + +class HourData: + DKK_per_kWh: float # Price in Danish Kroner per kWh + EUR_per_kWh: float # Price in Euros per kWh + EXR: float # Exchange rate EUR to DKK + time_start: datetime # Hour start time + time_end: datetime # Hour end time +``` + +## Examples + +### Find the cheapest and most expensive hours + +```python +from elprisenligenu import API + +api = API() +prices = api.get_daily_prices(zone="DK2") + +# Find cheapest hour +cheapest = min(prices, key=lambda x: x.DKK_per_kWh) +print(f"Cheapest: {cheapest.DKK_per_kWh:.4f} DKK/kWh at {cheapest.time_start.hour}:00") + +# Find most expensive hour +expensive = max(prices, key=lambda x: x.DKK_per_kWh) +print(f"Most expensive: {expensive.DKK_per_kWh:.4f} DKK/kWh at {expensive.time_start.hour}:00") +``` + +### Calculate daily average price + +```python +from elprisenligenu import API + +api = API() +prices = api.get_daily_prices(zone="DK1") + +average_price = sum(hour.DKK_per_kWh for hour in prices) / len(prices) +print(f"Average price today: {average_price:.4f} DKK/kWh") +``` + +### Get price data for multiple days + +```python +from datetime import datetime, timedelta +from zoneinfo import ZoneInfo +from elprisenligenu import API + +api = API() +timezone = ZoneInfo("Europe/Copenhagen") + +# Get prices for the last 7 days +for i in range(7): + date = datetime.now(timezone) - timedelta(days=i) + try: + prices = api.get_daily_prices(zone="DK2", date=date) + avg_price = sum(hour.DKK_per_kWh for hour in prices) / len(prices) + print(f"{date.strftime('%Y-%m-%d')}: {avg_price:.4f} DKK/kWh") + except Exception as e: + print(f"Failed to get data for {date.strftime('%Y-%m-%d')}: {e}") +``` + +## Price Zones + +Denmark is divided into two electricity price zones: + +- **DK1 (West)**: Jutland and Funen (west of the Great Belt) + - Major cities: Aarhus, Aalborg, Odense, Esbjerg +- **DK2 (East)**: Zealand, Lolland, Falster, and Bornholm (east of the Great Belt) + - Major cities: Copenhagen, Roskilde, HelsingΓΈr + +## Data Source + +This library uses the free API provided by [ElprisenLigeNu.dk](https://www.elprisenligenu.dk). The electricity prices are: + +- Spot prices from the Nord Pool electricity market +- Provided without VAT or additional fees +- Updated daily (tomorrow's prices available from 13:00 the day before) +- Historical data available from November 1, 2022 +- Originally sourced from [ENTSO-E](https://transparency.entsoe.eu/) in EUR, converted to DKK + +## Development + +### Requirements + +- Python 3.12+ +- Dependencies: `pydantic>=2.12.3`, `requests>=2.32.5` + +### Setup + +```bash +# Clone the repository +git clone https://github.com/yourusername/elprisenligenu.git +cd elprisenligenu + +# Install with development dependencies +uv sync --dev + +# Run tests (unit tests only) +uv run pytest tests/unit/ + +# Run all tests including integration tests (requires internet) +uv run pytest + +# Run tests with coverage +uv run pytest --cov=src --cov-report=html + +# Type checking +uv run mypy . + +# Linting +uv run ruff check . + +# Formatting +uv run ruff format . +``` + +### Test Structure + +The test suite is organized into: + +- **Unit Tests** (`tests/unit/`): Fast tests that mock external dependencies + + - `test_hour_data.py`: Tests for the HourData model + - `test_api.py`: Tests for the API class with mocked HTTP requests + +- **Integration Tests** (`tests/test_integration.py`): Tests that make real API calls + - Marked with `@pytest.mark.integration` + - Can be skipped with `pytest -m "not integration"` + +### Running Specific Tests + +```bash +# Run only unit tests +uv run pytest tests/unit/ + +# Run only integration tests (requires internet) +uv run pytest -m integration + +# Run tests matching a pattern +uv run pytest -k "test_hour_data" + +# Run with verbose output +uv run pytest -v + +# Run with coverage report +uv run pytest --cov=src --cov-report=term-missing +``` + +## License + +This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. + +## Attribution + +When using this library in public projects, please consider attributing the data source: + +> Electricity prices provided by [ElprisenLigeNu.dk](https://www.elprisenligenu.dk) + +## Support + +- πŸ› [Report issues](https://github.com/yourusername/elprisenligenu/issues) +- πŸ“§ Contact: [schnitzelen@gmail.com](mailto:schnitzelen@gmail.com) +- 🌐 ElprisenLigeNu.dk: [hej@beneficial.no](mailto:hej@beneficial.no) + +## Related Projects + +- [ElprisenLigeNu.dk](https://www.elprisenligenu.dk) - The source website +- [API Documentation](https://www.elprisenligenu.dk/elpris-api) - Official API docs diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..50ea585 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,51 @@ +[project] +name = "elprisenligenu" +version = "0.1.0" +authors = [ + { name = "Brian Bjarke Jensen", email = "schnitzelen@gmail.com" } +] +requires-python = ">=3.12" +dependencies = [ + "pydantic>=2.12.3", + "requests>=2.32.5", +] + +[dependency-groups] +dev = [ + "ipykernel>=7.1.0", + "mypy>=1.18.2", + "pre-commit>=4.3.0", + "pytest>=8.4.2", + "pytest-cov>=7.0.0", + "python-dotenv>=1.2.1", + "pyupgrade>=3.21.0", + "ruff>=0.14.2", + "types-requests>=2.32.4.20250913", +] + +[[tool.uv.index]] +name = "threadripper-proxpi-cache" +url = "http://10.0.0.2:5001/index/" +default = true + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.mypy] +python_version = "3.12" +mypy_path = "src" +warn_return_any = true # nudge to use stricter types +warn_unused_configs = true # nudge to remove unused configs +disallow_untyped_defs = true # disallow untyped function definitions +disallow_incomplete_defs = true # ensure all parts of a function has type annotation +check_untyped_defs = true # dont skip untyped functions +disallow_untyped_decorators = false # allow untyped decorators to keep code more readable +no_implicit_optional = true # disallow implicit optional types leading to None-mess +warn_redundant_casts = true # nudge to use explicit type casts +warn_unused_ignores = true # nudge to remove unused ignores +warn_no_return = true # catch missing return statements +warn_unreachable = true # catch unreachable code +show_error_codes = true # show error codes in output +explicit_package_bases = true # reduce risk of import confusion +namespace_packages = true # enable namespace packages diff --git a/src/elprisenligenu/__init__.py b/src/elprisenligenu/__init__.py new file mode 100644 index 0000000..165f117 --- /dev/null +++ b/src/elprisenligenu/__init__.py @@ -0,0 +1,3 @@ +from .api import API + +__all__ = ["API"] diff --git a/src/elprisenligenu/api.py b/src/elprisenligenu/api.py new file mode 100644 index 0000000..56ee6e5 --- /dev/null +++ b/src/elprisenligenu/api.py @@ -0,0 +1,60 @@ +"""Definition of the API class for interacting with the ElprisenLigeNu service.""" + +import logging +from datetime import datetime +from zoneinfo import ZoneInfo +from typing import Literal +import requests + +from elprisenligenu.dto.hour_data import HourData + + +class API: + """Class for interacting with the ElprisenLigeNu API.""" + + BASE_URL = "https://www.elprisenligenu.dk/api/v1/prices" + TIMEZONE = ZoneInfo("Europe/Copenhagen") + + def __init__(self) -> None: + """Initialize the API class.""" + self.session = requests.Session() + self.logger = logging.getLogger(__name__) + + @classmethod + def _endpoint(cls, date: datetime, zone: str) -> str: + """Construct the API endpoint URL for the given date and zone.""" + year_str = date.strftime("%Y") + date_str = date.strftime("%m-%d") + return f"{cls.BASE_URL}/{year_str}/{date_str}_{zone}.json" + + def get_daily_prices( + self, + zone: Literal["DK1", "DK2"] = "DK1", + date: datetime = datetime.now(tz=TIMEZONE), + ) -> list[HourData]: + """Fetch the daily electricity prices. + + Returns: + list[HourData]: A list of HourData objects containing the daily electricity price data. + """ + + # Check inputs + if zone not in ["DK1", "DK2"]: + raise ValueError("zone must be either 'DK1' or 'DK2'") + if not isinstance(date, datetime): + raise TypeError("date must be a datetime object") + if date.tzinfo is None: + raise ValueError("date must be timezone-aware") + if date.tzinfo != self.TIMEZONE: + self.logger.info("Converting date to %s timezone", self.TIMEZONE) + date = date.astimezone(self.TIMEZONE) + + # Make request + endpoint = self._endpoint(date, zone) + response = self.session.get(endpoint) + response.raise_for_status() + + # Convert response to list of HourData + data = [HourData(**entry) for entry in response.json()] + + return data diff --git a/src/elprisenligenu/dto/__init__.py b/src/elprisenligenu/dto/__init__.py new file mode 100644 index 0000000..e32adc5 --- /dev/null +++ b/src/elprisenligenu/dto/__init__.py @@ -0,0 +1,3 @@ +from .hour_data import HourData + +__all__ = ["HourData"] diff --git a/src/elprisenligenu/dto/hour_data.py b/src/elprisenligenu/dto/hour_data.py new file mode 100644 index 0000000..b304e62 --- /dev/null +++ b/src/elprisenligenu/dto/hour_data.py @@ -0,0 +1,14 @@ +"""Definition of HourData DTO for ElprisenLigeNu service.""" + +from datetime import datetime +from pydantic import BaseModel + + +class HourData(BaseModel): + """Data Transfer Object for hourly electricity price data.""" + + DKK_per_kWh: float + EUR_per_kWh: float + EXR: float + time_start: datetime + time_end: datetime diff --git a/src/elprisenligenu/py.typed b/src/elprisenligenu/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..ee86490 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1 @@ +"""Test package for elprisenligenu.""" diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py new file mode 100644 index 0000000..426e689 --- /dev/null +++ b/tests/integration/conftest.py @@ -0,0 +1,48 @@ +"""Test configuration and fixtures for elprisenligenu tests.""" + +from datetime import datetime +from zoneinfo import ZoneInfo +import pytest + + +def pytest_configure(config: pytest.Config) -> None: + """Configure pytest with custom markers.""" + config.addinivalue_line( + "markers", + "integration: marks tests as integration tests (may require internet)", + ) + + +@pytest.fixture +def mock_api_response() -> list[dict]: + """Fixture providing a mock API response.""" + return [ + { + "DKK_per_kWh": 1.3929, + "EUR_per_kWh": 0.18729, + "EXR": 7.437118, + "time_start": "2024-10-29T00:00:00+01:00", + "time_end": "2024-10-29T01:00:00+01:00", + }, + { + "DKK_per_kWh": 1.30291, + "EUR_per_kWh": 0.17519, + "EXR": 7.437118, + "time_start": "2024-10-29T01:00:00+01:00", + "time_end": "2024-10-29T02:00:00+01:00", + }, + ] + + +@pytest.fixture +def sample_hour_data() -> dict: + """Fixture providing sample HourData for testing.""" + + tz = ZoneInfo("Europe/Copenhagen") + return { + "DKK_per_kWh": 1.2345, + "EUR_per_kWh": 0.1659, + "EXR": 7.4371, + "time_start": datetime(2024, 10, 29, 12, 0, 0, tzinfo=tz), + "time_end": datetime(2024, 10, 29, 13, 0, 0, tzinfo=tz), + } diff --git a/tests/integration/test_integration.py b/tests/integration/test_integration.py new file mode 100644 index 0000000..4ecbeee --- /dev/null +++ b/tests/integration/test_integration.py @@ -0,0 +1,152 @@ +"""Integration tests for the elprisenligenu module.""" + +from datetime import datetime +from zoneinfo import ZoneInfo + +import pytest + +from elprisenligenu.api import API +from elprisenligenu.dto.hour_data import HourData + + +class TestElprisenLigenIntegration: + """Integration tests that make real API calls.""" + + def setup_method(self) -> None: + """Set up test fixtures before each test method.""" + self.api = API() + self.tz = ZoneInfo("Europe/Copenhagen") + + @pytest.mark.integration + def test_get_current_prices_dk1(self) -> None: + """Test fetching current day prices for DK1 (integration test).""" + # Act + result = self.api.get_daily_prices(zone="DK1") + + # Assert + assert isinstance(result, list) + assert all(isinstance(item, HourData) for item in result) + + if result: # If data is available + first_hour = result[0] + assert isinstance(first_hour.DKK_per_kWh, float) + assert isinstance(first_hour.EUR_per_kWh, float) + assert isinstance(first_hour.EXR, float) + assert isinstance(first_hour.time_start, datetime) + assert isinstance(first_hour.time_end, datetime) + + # Basic sanity checks + assert first_hour.EXR > 0 # Exchange rate should be positive + assert first_hour.time_start < first_hour.time_end + + @pytest.mark.integration + def test_get_current_prices_dk2(self) -> None: + """Test fetching current day prices for DK2 (integration test).""" + # Act + result = self.api.get_daily_prices(zone="DK2") + + # Assert + assert isinstance(result, list) + assert all(isinstance(item, HourData) for item in result) + + if result: # If data is available + first_hour = result[0] + assert isinstance(first_hour.DKK_per_kWh, float) + assert isinstance(first_hour.EUR_per_kWh, float) + assert isinstance(first_hour.EXR, float) + assert isinstance(first_hour.time_start, datetime) + assert isinstance(first_hour.time_end, datetime) + + @pytest.mark.integration + def test_get_historical_prices(self) -> None: + """Test fetching historical prices (integration test).""" + # Arrange - Use a date that should have data (not too far back) + historical_date = datetime(2024, 10, 1, tzinfo=self.tz) + + # Act + result = self.api.get_daily_prices(zone="DK1", date=historical_date) + + # Assert + assert isinstance(result, list) + + if result: # If historical data is available + assert len(result) <= 24 # Should be max 24 hours + assert all(isinstance(item, HourData) for item in result) + + # Check that all times are from the requested date + for hour_data in result: + assert hour_data.time_start.date() == historical_date.date() + + @pytest.mark.integration + def test_price_consistency(self) -> None: + """Test that EUR and DKK prices are consistent with exchange rate.""" + # Act + result = self.api.get_daily_prices(zone="DK1") + + # Assert + if result: + for hour_data in result: + # Calculate expected DKK price from EUR price and exchange rate + expected_dkk = hour_data.EUR_per_kWh * hour_data.EXR + + # Allow for small floating point differences + difference = abs(hour_data.DKK_per_kWh - expected_dkk) + assert difference < 0.001, ( + f"Price inconsistency: DKK={hour_data.DKK_per_kWh}, " + f"EUR={hour_data.EUR_per_kWh}, EXR={hour_data.EXR}, " + f"Expected DKK={expected_dkk}" + ) + + @pytest.mark.integration + def test_time_ordering(self) -> None: + """Test that hours are returned in chronological order.""" + # Act + result = self.api.get_daily_prices(zone="DK1") + + # Assert + if len(result) > 1: + for i in range(1, len(result)): + assert result[i - 1].time_start <= result[i].time_start, ( + f"Hours not in chronological order: " + f"{result[i - 1].time_start} > {result[i].time_start}" + ) + + @pytest.mark.integration + def test_hour_duration(self) -> None: + """Test that each hour period is exactly 1 hour long.""" + # Act + result = self.api.get_daily_prices(zone="DK1") + + # Assert + if result: + for hour_data in result: + duration = hour_data.time_end - hour_data.time_start + assert duration.total_seconds() == 3600, ( + f"Hour duration is not 1 hour: {duration}" + ) + + @pytest.mark.integration + def test_both_zones_same_day(self) -> None: + """Test that both zones return data for the same day.""" + # Arrange + test_date = datetime(2024, 10, 15, tzinfo=self.tz) + + # Act + dk1_result = self.api.get_daily_prices(zone="DK1", date=test_date) + dk2_result = self.api.get_daily_prices(zone="DK2", date=test_date) + + # Assert + # Both zones should have data for the same day + if dk1_result and dk2_result: + assert len(dk1_result) == len(dk2_result) + + # Times should be the same + for dk1_hour, dk2_hour in zip(dk1_result, dk2_result): + assert dk1_hour.time_start == dk2_hour.time_start + assert dk1_hour.time_end == dk2_hour.time_end + + # Exchange rates should be the same + assert dk1_hour.EXR == dk2_hour.EXR + + # But prices can be different between zones + # (That's the whole point of having two zones!) diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py new file mode 100644 index 0000000..2afae7a --- /dev/null +++ b/tests/unit/__init__.py @@ -0,0 +1 @@ +"""Unit tests package for elprisenligenu.""" diff --git a/tests/unit/test_api.py b/tests/unit/test_api.py new file mode 100644 index 0000000..91f0bb5 --- /dev/null +++ b/tests/unit/test_api.py @@ -0,0 +1,321 @@ +"""Unit tests for the API class.""" + +import json +from datetime import datetime +import unittest +from unittest.mock import Mock, patch +from zoneinfo import ZoneInfo + +import pytest +import requests + +from elprisenligenu.api import API +from elprisenligenu.dto.hour_data import HourData + + +class TestAPI(unittest.TestCase): + """Test cases for the API class.""" + + api: API + tz: ZoneInfo + + @classmethod + def setUpClass(cls) -> None: + """Set up test fixtures before any tests are run.""" + cls.api = API() + cls.tz = ZoneInfo("Europe/Copenhagen") + + def test_api_initialization(self) -> None: + """Test API class initialization.""" + # Act + api = API() + + # Assert + self.assertIsNotNone(api.session) + self.assertIsInstance(api.session, requests.Session) + self.assertIsNotNone(api.logger) + self.assertEqual(api.BASE_URL, "https://www.elprisenligenu.dk/api/v1/prices") + self.assertEqual(api.TIMEZONE, ZoneInfo("Europe/Copenhagen")) + + def test_endpoint_construction_dk1(self) -> None: + """Test endpoint URL construction for DK1.""" + # Arrange + date = datetime(2024, 10, 29, 12, 0, 0, tzinfo=self.tz) + + # Act + endpoint = API._endpoint(date, "DK1") + + # Assert + expected = "https://www.elprisenligenu.dk/api/v1/prices/2024/10-29_DK1.json" + self.assertEqual(endpoint, expected) + + def test_endpoint_construction_dk2(self) -> None: + """Test endpoint URL construction for DK2.""" + # Arrange + date = datetime(2024, 1, 5, 12, 0, 0, tzinfo=self.tz) + + # Act + endpoint = API._endpoint(date, "DK2") + + # Assert + expected = "https://www.elprisenligenu.dk/api/v1/prices/2024/01-05_DK2.json" + self.assertEqual(endpoint, expected) + + def test_endpoint_construction_edge_dates(self) -> None: + """Test endpoint URL construction for edge case dates.""" + # Test December 31st + date = datetime(2023, 12, 31, 12, 0, 0, tzinfo=self.tz) + endpoint = API._endpoint(date, "DK1") + expected = "https://www.elprisenligenu.dk/api/v1/prices/2023/12-31_DK1.json" + self.assertEqual(endpoint, expected) + + # Test January 1st + date = datetime(2024, 1, 1, 12, 0, 0, tzinfo=self.tz) + endpoint = API._endpoint(date, "DK2") + expected = "https://www.elprisenligenu.dk/api/v1/prices/2024/01-01_DK2.json" + self.assertEqual(endpoint, expected) + + @patch("elprisenligenu.api.requests.Session.get") + def test_get_daily_prices_success_dk1(self, mock_get: Mock) -> None: + """Test successful API call for DK1.""" + # Arrange + mock_response_data = [ + { + "DKK_per_kWh": 1.3929, + "EUR_per_kWh": 0.18729, + "EXR": 7.437118, + "time_start": "2024-10-29T00:00:00+01:00", + "time_end": "2024-10-29T01:00:00+01:00", + }, + { + "DKK_per_kWh": 1.30291, + "EUR_per_kWh": 0.17519, + "EXR": 7.437118, + "time_start": "2024-10-29T01:00:00+01:00", + "time_end": "2024-10-29T02:00:00+01:00", + }, + ] + + mock_response = Mock() + mock_response.json.return_value = mock_response_data + mock_response.raise_for_status.return_value = None + mock_get.return_value = mock_response + + date = datetime(2024, 10, 29, 12, 0, 0, tzinfo=self.tz) + + # Act + result = self.api.get_daily_prices(zone="DK1", date=date) + + # Assert + self.assertEqual(len(result), 2) + self.assertTrue(all(isinstance(item, HourData) for item in result)) + self.assertAlmostEqual(result[0].DKK_per_kWh, 1.3929, places=4) + self.assertAlmostEqual(result[1].DKK_per_kWh, 1.30291, places=4) + + # Verify API was called correctly + expected_url = "https://www.elprisenligenu.dk/api/v1/prices/2024/10-29_DK1.json" + mock_get.assert_called_once_with(expected_url) + + @patch("elprisenligenu.api.requests.Session.get") + def test_get_daily_prices_success_dk2(self, mock_get: Mock) -> None: + """Test successful API call for DK2.""" + # Arrange + mock_response_data = [ + { + "DKK_per_kWh": 1.5000, + "EUR_per_kWh": 0.2000, + "EXR": 7.5, + "time_start": "2024-10-29T00:00:00+01:00", + "time_end": "2024-10-29T01:00:00+01:00", + } + ] + + mock_response = Mock() + mock_response.json.return_value = mock_response_data + mock_response.raise_for_status.return_value = None + mock_get.return_value = mock_response + + date = datetime(2024, 10, 29, 12, 0, 0, tzinfo=self.tz) + + # Act + result = self.api.get_daily_prices(zone="DK2", date=date) + + # Assert + self.assertEqual(len(result), 1) + self.assertAlmostEqual(result[0].DKK_per_kWh, 1.5000, places=4) + + # Verify API was called correctly + expected_url = "https://www.elprisenligenu.dk/api/v1/prices/2024/10-29_DK2.json" + mock_get.assert_called_once_with(expected_url) + + def test_get_daily_prices_invalid_zone(self) -> None: + """Test validation error for invalid zone.""" + # Arrange + date = datetime(2024, 10, 29, 12, 0, 0, tzinfo=self.tz) + + # Act & Assert + with pytest.raises(ValueError, match="zone must be either 'DK1' or 'DK2'"): + self.api.get_daily_prices(zone="DK3", date=date) # type: ignore + + def test_get_daily_prices_invalid_date_type(self) -> None: + """Test validation error for invalid date type.""" + # Act & Assert + with pytest.raises(TypeError, match="date must be a datetime object"): + self.api.get_daily_prices(zone="DK1", date="2024-10-29") # type: ignore + + def test_get_daily_prices_naive_datetime(self) -> None: + """Test validation error for naive datetime.""" + # Arrange + naive_date = datetime(2024, 10, 29, 12, 0, 0) # No timezone + + # Act & Assert + with pytest.raises(ValueError, match="date must be timezone-aware"): + self.api.get_daily_prices(zone="DK1", date=naive_date) + + @patch("elprisenligenu.api.requests.Session.get") + def test_get_daily_prices_timezone_conversion(self, mock_get: Mock) -> None: + """Test automatic timezone conversion.""" + # Arrange + mock_response_data = [ + { + "DKK_per_kWh": 1.0, + "EUR_per_kWh": 0.13, + "EXR": 7.5, + "time_start": "2024-10-29T00:00:00+01:00", + "time_end": "2024-10-29T01:00:00+01:00", + } + ] + + mock_response = Mock() + mock_response.json.return_value = mock_response_data + mock_response.raise_for_status.return_value = None + mock_get.return_value = mock_response + + # Use UTC timezone instead of Copenhagen + utc_date = datetime(2024, 10, 29, 11, 0, 0, tzinfo=ZoneInfo("UTC")) + + # Act + result = self.api.get_daily_prices(zone="DK1", date=utc_date) + + # Assert + self.assertEqual(len(result), 1) + # Should still work, date gets converted internally + + @patch("elprisenligenu.api.requests.Session.get") + def test_get_daily_prices_http_error(self, mock_get: Mock) -> None: + """Test handling of HTTP errors.""" + # Arrange + mock_response = Mock() + mock_response.raise_for_status.side_effect = requests.HTTPError("404 Not Found") + mock_get.return_value = mock_response + + date = datetime(2024, 10, 29, 12, 0, 0, tzinfo=self.tz) + + # Act & Assert + with pytest.raises(requests.HTTPError): + self.api.get_daily_prices(zone="DK1", date=date) + + @patch("elprisenligenu.api.requests.Session.get") + def test_get_daily_prices_invalid_json(self, mock_get: Mock) -> None: + """Test handling of invalid JSON response.""" + # Arrange + mock_response = Mock() + mock_response.raise_for_status.return_value = None + mock_response.json.side_effect = json.JSONDecodeError("Invalid JSON", "", 0) + mock_get.return_value = mock_response + + date = datetime(2024, 10, 29, 12, 0, 0, tzinfo=self.tz) + + # Act & Assert + with pytest.raises(json.JSONDecodeError): + self.api.get_daily_prices(zone="DK1", date=date) + + @patch("elprisenligenu.api.requests.Session.get") + def test_get_daily_prices_empty_response(self, mock_get: Mock) -> None: + """Test handling of empty response.""" + # Arrange + mock_response = Mock() + mock_response.json.return_value = [] + mock_response.raise_for_status.return_value = None + mock_get.return_value = mock_response + + date = datetime(2024, 10, 29, 12, 0, 0, tzinfo=self.tz) + + # Act + result = self.api.get_daily_prices(zone="DK1", date=date) + + # Assert + self.assertEqual(result, []) + + @patch("elprisenligenu.api.requests.Session.get") + def test_get_daily_prices_malformed_data(self, mock_get: Mock) -> None: + """Test handling of malformed response data.""" + # Arrange + mock_response_data = [ + { + "DKK_per_kWh": "not_a_number", # Invalid type + "EUR_per_kWh": 0.18729, + "EXR": 7.437118, + "time_start": "2024-10-29T00:00:00+01:00", + "time_end": "2024-10-29T01:00:00+01:00", + } + ] + + mock_response = Mock() + mock_response.json.return_value = mock_response_data + mock_response.raise_for_status.return_value = None + mock_get.return_value = mock_response + + date = datetime(2024, 10, 29, 12, 0, 0, tzinfo=self.tz) + + # Act & Assert + with pytest.raises(Exception): # Pydantic validation error + self.api.get_daily_prices(zone="DK1", date=date) + + def test_get_daily_prices_default_parameters(self) -> None: + """Test that default parameters work correctly.""" + # This test verifies the method signature but doesn't make real API calls + # We just check that the method can be called without parameters + + # Act & Assert - should not raise an error for the method signature + try: + # We expect this to fail with a network error in tests, but the + # parameter validation should pass + self.api.get_daily_prices() + except (requests.RequestException, requests.ConnectionError): + # Expected in test environment without internet + pass + + @patch("elprisenligenu.api.requests.Session.get") + def test_get_daily_prices_full_day_data(self, mock_get: Mock) -> None: + """Test processing a full day of 24 hours.""" + # Arrange - Create 24 hours of mock data + mock_response_data = [] + for hour in range(24): + mock_response_data.append( + { + "DKK_per_kWh": 1.0 + hour * 0.1, + "EUR_per_kWh": 0.13 + hour * 0.01, + "EXR": 7.5, + "time_start": f"2024-10-29T{hour:02d}:00:00+01:00", + "time_end": f"2024-10-29T{(hour + 1) % 24:02d}:00:00+01:00", + } + ) + + mock_response = Mock() + mock_response.json.return_value = mock_response_data + mock_response.raise_for_status.return_value = None + mock_get.return_value = mock_response + + date = datetime(2024, 10, 29, 12, 0, 0, tzinfo=self.tz) + + # Act + result = self.api.get_daily_prices(zone="DK1", date=date) + + # Assert + self.assertEqual(len(result), 24) + self.assertTrue(all(isinstance(item, HourData) for item in result)) + + # Check that prices increase as expected + self.assertEqual(result[0].DKK_per_kWh, 1.0) + self.assertAlmostEqual(result[23].DKK_per_kWh, 3.3, 3) # 1.0 + 23 * 0.1 diff --git a/tests/unit/test_hour_data.py b/tests/unit/test_hour_data.py new file mode 100644 index 0000000..a23dfcb --- /dev/null +++ b/tests/unit/test_hour_data.py @@ -0,0 +1,229 @@ +"""Unit tests for the HourData DTO model.""" + +from datetime import datetime +from zoneinfo import ZoneInfo +import unittest + +import pytest +from pydantic import ValidationError + +from elprisenligenu.dto.hour_data import HourData + + +class TestHourData(unittest.TestCase): + """Test cases for the HourData model.""" + + def test_valid_hour_data_creation(self) -> None: + """Test creating a valid HourData instance.""" + # Arrange + tz = ZoneInfo("Europe/Copenhagen") + start_time = datetime(2024, 10, 29, 12, 0, 0, tzinfo=tz) + end_time = datetime(2024, 10, 29, 13, 0, 0, tzinfo=tz) + + # Act + hour_data = HourData( + DKK_per_kWh=1.2345, + EUR_per_kWh=0.1659, + EXR=7.4371, + time_start=start_time, + time_end=end_time, + ) + + # Assert + self.assertEqual(hour_data.DKK_per_kWh, 1.2345) + self.assertEqual(hour_data.EUR_per_kWh, 0.1659) + self.assertEqual(hour_data.EXR, 7.4371) + self.assertEqual(hour_data.time_start, start_time) + self.assertEqual(hour_data.time_end, end_time) + + def test_hour_data_from_api_response(self) -> None: + """Test creating HourData from typical API response data.""" + + # Act - Pydantic can parse ISO datetime strings + hour_data = HourData( + DKK_per_kWh=1.3929, + EUR_per_kWh=0.18729, + EXR=7.437118, + time_start=datetime.fromisoformat("2022-11-25T00:00:00+01:00"), + time_end=datetime.fromisoformat("2022-11-25T01:00:00+01:00"), + ) + + # Assert + self.assertEqual(hour_data.DKK_per_kWh, 1.3929) + self.assertEqual(hour_data.EUR_per_kWh, 0.18729) + self.assertEqual(hour_data.EXR, 7.437118) + self.assertEqual(hour_data.time_start.year, 2022) + self.assertEqual(hour_data.time_start.month, 11) + self.assertEqual(hour_data.time_start.day, 25) + self.assertEqual(hour_data.time_start.hour, 0) + self.assertEqual(hour_data.time_end.hour, 1) + + def test_hour_data_validation_missing_fields(self) -> None: + """Test validation fails when required fields are missing.""" + + # Arrange + incomplete_data = { + "DKK_per_kWh": 1.2345, + "EUR_per_kWh": 0.1659, + # Missing EXR, time_start, time_end + } + + # Act & Assert + with pytest.raises(ValidationError) as exc_info: + HourData(**incomplete_data) # type: ignore[arg-type] + + errors = exc_info.value.errors() + missing_fields = {error["loc"][0] for error in errors} + self.assertIn("EXR", missing_fields) + self.assertIn("time_start", missing_fields) + self.assertIn("time_end", missing_fields) + + def test_hour_data_validation_invalid_types(self) -> None: + """Test validation fails with invalid data types.""" + # Arrange + invalid_data = { + "DKK_per_kWh": "not_a_number", # Should be float + "EUR_per_kWh": 0.1659, + "EXR": 7.4371, + "time_start": "2024-10-29T12:00:00+01:00", + "time_end": "2024-10-29T13:00:00+01:00", + } + + # Act & Assert + with pytest.raises(ValidationError) as exc_info: + HourData(**invalid_data) # type: ignore[arg-type] + + errors = exc_info.value.errors() + self.assertTrue(any(error["loc"][0] == "DKK_per_kWh" for error in errors)) + + def test_hour_data_negative_prices(self) -> None: + """Test HourData accepts negative prices (real markets).""" + # Arrange + tz = ZoneInfo("Europe/Copenhagen") + + # Act + hour_data = HourData( + DKK_per_kWh=-0.5, # Negative price + EUR_per_kWh=-0.067, + EXR=7.4371, + time_start=datetime(2024, 10, 29, 12, 0, 0, tzinfo=tz), + time_end=datetime(2024, 10, 29, 13, 0, 0, tzinfo=tz), + ) + + # Assert + self.assertEqual(hour_data.DKK_per_kWh, -0.5) + self.assertEqual(hour_data.EUR_per_kWh, -0.067) + + def test_hour_data_zero_prices(self) -> None: + """Test HourData accepts zero prices.""" + # Arrange + tz = ZoneInfo("Europe/Copenhagen") + + # Act + hour_data = HourData( + DKK_per_kWh=0.0, + EUR_per_kWh=0.0, + EXR=7.4371, + time_start=datetime(2024, 10, 29, 12, 0, 0, tzinfo=tz), + time_end=datetime(2024, 10, 29, 13, 0, 0, tzinfo=tz), + ) + + # Assert + self.assertEqual(hour_data.DKK_per_kWh, 0.0) + self.assertEqual(hour_data.EUR_per_kWh, 0.0) + + def test_hour_data_serialization(self) -> None: + """Test HourData can be serialized to JSON.""" + # Arrange + tz = ZoneInfo("Europe/Copenhagen") + start_time = datetime(2024, 10, 29, 12, 0, 0, tzinfo=tz) + end_time = datetime(2024, 10, 29, 13, 0, 0, tzinfo=tz) + + hour_data = HourData( + DKK_per_kWh=1.2345, + EUR_per_kWh=0.1659, + EXR=7.4371, + time_start=start_time, + time_end=end_time, + ) + + # Act + json_data = hour_data.model_dump() + + # Assert + self.assertEqual(json_data["DKK_per_kWh"], 1.2345) + self.assertEqual(json_data["EUR_per_kWh"], 0.1659) + self.assertEqual(json_data["EXR"], 7.4371) + self.assertEqual(json_data["time_start"], start_time) + self.assertEqual(json_data["time_end"], end_time) + + def test_hour_data_string_representation(self) -> None: + """Test HourData string representation is readable.""" + # Arrange + tz = ZoneInfo("Europe/Copenhagen") + hour_data = HourData( + DKK_per_kWh=1.2345, + EUR_per_kWh=0.1659, + EXR=7.4371, + time_start=datetime(2024, 10, 29, 12, 0, 0, tzinfo=tz), + time_end=datetime(2024, 10, 29, 13, 0, 0, tzinfo=tz), + ) + + # Act + str_repr = str(hour_data) + + # Assert + self.assertIn("DKK_per_kWh=1.2345", str_repr) + self.assertIn("EUR_per_kWh=0.1659", str_repr) + self.assertIn("EXR=7.4371", str_repr) + + def test_hour_data_equality(self) -> None: + """Test HourData equality comparison.""" + # Arrange + tz = ZoneInfo("Europe/Copenhagen") + start_time = datetime(2024, 10, 29, 12, 0, 0, tzinfo=tz) + end_time = datetime(2024, 10, 29, 13, 0, 0, tzinfo=tz) + + hour_data1 = HourData( + DKK_per_kWh=1.2345, + EUR_per_kWh=0.1659, + EXR=7.4371, + time_start=start_time, + time_end=end_time, + ) + hour_data2 = HourData( + DKK_per_kWh=1.2345, + EUR_per_kWh=0.1659, + EXR=7.4371, + time_start=start_time, + time_end=end_time, + ) + + # Act & Assert + self.assertEqual(hour_data1, hour_data2) + + def test_hour_data_inequality(self) -> None: + """Test HourData inequality comparison.""" + # Arrange + tz = ZoneInfo("Europe/Copenhagen") + start_time = datetime(2024, 10, 29, 12, 0, 0, tzinfo=tz) + end_time = datetime(2024, 10, 29, 13, 0, 0, tzinfo=tz) + + hour_data1 = HourData( + DKK_per_kWh=1.2345, + EUR_per_kWh=0.1659, + EXR=7.4371, + time_start=start_time, + time_end=end_time, + ) + + hour_data2 = HourData( + DKK_per_kWh=2.0000, # Different price + EUR_per_kWh=0.1659, + EXR=7.4371, + time_start=start_time, + time_end=end_time, + ) + + # Act & Assert + self.assertNotEqual(hour_data1, hour_data2) diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..fa1687c --- /dev/null +++ b/uv.lock @@ -0,0 +1,1095 @@ +version = 1 +revision = 3 +requires-python = ">=3.12" + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/annotated-types/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89" } +wheels = [ + { url = "http://10.0.0.2:5001/index/annotated-types/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53" }, +] + +[[package]] +name = "appnope" +version = "0.1.4" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/appnope/appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee" } +wheels = [ + { url = "http://10.0.0.2:5001/index/appnope/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c" }, +] + +[[package]] +name = "asttokens" +version = "3.0.0" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/asttokens/asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7" } +wheels = [ + { url = "http://10.0.0.2:5001/index/asttokens/asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2" }, +] + +[[package]] +name = "certifi" +version = "2025.10.5" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/certifi/certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43" } +wheels = [ + { url = "http://10.0.0.2:5001/index/certifi/certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de" }, +] + +[[package]] +name = "cffi" +version = "2.0.0" +source = { registry = "http://10.0.0.2:5001/index/" } +dependencies = [ + { name = "pycparser", marker = "implementation_name != 'PyPy'" }, +] +sdist = { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529" } +wheels = [ + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6" }, + { url = "http://10.0.0.2:5001/index/cffi/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9" }, +] + +[[package]] +name = "cfgv" +version = "3.4.0" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/cfgv/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560" } +wheels = [ + { url = "http://10.0.0.2:5001/index/cfgv/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9" }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.4" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a" } +wheels = [ + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2" }, + { url = "http://10.0.0.2:5001/index/charset-normalizer/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/colorama/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44" } +wheels = [ + { url = "http://10.0.0.2:5001/index/colorama/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" }, +] + +[[package]] +name = "comm" +version = "0.2.3" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/comm/comm-0.2.3.tar.gz", hash = "sha256:2dc8048c10962d55d7ad693be1e7045d891b7ce8d999c97963a5e3e99c055971" } +wheels = [ + { url = "http://10.0.0.2:5001/index/comm/comm-0.2.3-py3-none-any.whl", hash = "sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417" }, +] + +[[package]] +name = "coverage" +version = "7.11.0" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0.tar.gz", hash = "sha256:167bd504ac1ca2af7ff3b81d245dfea0292c5032ebef9d66cc08a7d28c1b8050" } +wheels = [ + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9c49e77811cf9d024b95faf86c3f059b11c0c9be0b0d61bc598f453703bd6fd1" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a61e37a403a778e2cda2a6a39abcc895f1d984071942a41074b5c7ee31642007" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:c79cae102bb3b1801e2ef1511fb50e91ec83a1ce466b2c7c25010d884336de46" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:16ce17ceb5d211f320b62df002fa7016b7442ea0fd260c11cec8ce7730954893" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:80027673e9d0bd6aef86134b0771845e2da85755cf686e7c7c59566cf5a89115" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4d3ffa07a08657306cd2215b0da53761c4d73cb54d9143b9303a6481ec0cd415" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a3b6a5f8b2524fd6c1066bc85bfd97e78709bb5e37b5b94911a6506b65f47186" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fcc0a4aa589de34bc56e1a80a740ee0f8c47611bdfb28cd1849de60660f3799d" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:dba82204769d78c3fd31b35c3d5f46e06511936c5019c39f98320e05b08f794d" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:81b335f03ba67309a95210caf3eb43bd6fe75a4e22ba653ef97b4696c56c7ec2" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp312-cp312-win32.whl", hash = "sha256:037b2d064c2f8cc8716fe4d39cb705779af3fbf1ba318dc96a1af858888c7bb5" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:d66c0104aec3b75e5fd897e7940188ea1892ca1d0235316bf89286d6a22568c0" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:d91ebeac603812a09cf6a886ba6e464f3bbb367411904ae3790dfe28311b15ad" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:cc3f49e65ea6e0d5d9bd60368684fe52a704d46f9e7fc413918f18d046ec40e1" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f39ae2f63f37472c17b4990f794035c9890418b1b8cca75c01193f3c8d3e01be" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7db53b5cdd2917b6eaadd0b1251cf4e7d96f4a8d24e174bdbdf2f65b5ea7994d" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:10ad04ac3a122048688387828b4537bc9cf60c0bf4869c1e9989c46e45690b82" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4036cc9c7983a2b1f2556d574d2eb2154ac6ed55114761685657e38782b23f52" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7ab934dd13b1c5e94b692b1e01bd87e4488cb746e3a50f798cb9464fd128374b" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59a6e5a265f7cfc05f76e3bb53eca2e0dfe90f05e07e849930fecd6abb8f40b4" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:df01d6c4c81e15a7c88337b795bb7595a8596e92310266b5072c7e301168efbd" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:8c934bd088eed6174210942761e38ee81d28c46de0132ebb1801dbe36a390dcc" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5a03eaf7ec24078ad64a07f02e30060aaf22b91dedf31a6b24d0d98d2bba7f48" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313-win32.whl", hash = "sha256:695340f698a5f56f795b2836abe6fb576e7c53d48cd155ad2f80fd24bc63a040" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:2727d47fce3ee2bac648528e41455d1b0c46395a087a229deac75e9f88ba5a05" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:0efa742f431529699712b92ecdf22de8ff198df41e43aeaaadf69973eb93f17a" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:587c38849b853b157706407e9ebdca8fd12f45869edb56defbef2daa5fb0812b" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b971bdefdd75096163dd4261c74be813c4508477e39ff7b92191dea19f24cd37" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:269bfe913b7d5be12ab13a95f3a76da23cf147be7fa043933320ba5625f0a8de" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:dadbcce51a10c07b7c72b0ce4a25e4b6dcb0c0372846afb8e5b6307a121eb99f" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9ed43fa22c6436f7957df036331f8fe4efa7af132054e1844918866cd228af6c" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9516add7256b6713ec08359b7b05aeff8850c98d357784c7205b2e60aa2513fa" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:eb92e47c92fcbcdc692f428da67db33337fa213756f7adb6a011f7b5a7a20740" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:d06f4fc7acf3cabd6d74941d53329e06bab00a8fe10e4df2714f0b134bfc64ef" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:6fbcee1a8f056af07ecd344482f711f563a9eb1c2cad192e87df00338ec3cdb0" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dbbf012be5f32533a490709ad597ad8a8ff80c582a95adc8d62af664e532f9ca" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313t-win32.whl", hash = "sha256:cee6291bb4fed184f1c2b663606a115c743df98a537c969c3c64b49989da96c2" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313t-win_amd64.whl", hash = "sha256:a386c1061bf98e7ea4758e4313c0ab5ecf57af341ef0f43a0bf26c2477b5c268" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp313-cp313t-win_arm64.whl", hash = "sha256:f9ea02ef40bb83823b2b04964459d281688fe173e20643870bb5d2edf68bc836" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c770885b28fb399aaf2a65bbd1c12bf6f307ffd112d6a76c5231a94276f0c497" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a3d0e2087dba64c86a6b254f43e12d264b636a39e88c5cc0a01a7c71bcfdab7e" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:73feb83bb41c32811973b8565f3705caf01d928d972b72042b44e97c71fd70d1" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c6f31f281012235ad08f9a560976cc2fc9c95c17604ff3ab20120fe480169bca" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9570ad567f880ef675673992222746a124b9595506826b210fbe0ce3f0499cd" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8badf70446042553a773547a61fecaa734b55dc738cacf20c56ab04b77425e43" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a09c1211959903a479e389685b7feb8a17f59ec5a4ef9afde7650bd5eabc2777" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:5ef83b107f50db3f9ae40f69e34b3bd9337456c5a7fe3461c7abf8b75dd666a2" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:f91f927a3215b8907e214af77200250bb6aae36eca3f760f89780d13e495388d" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:cdbcd376716d6b7fbfeedd687a6c4be019c5a5671b35f804ba76a4c0a778cba4" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314-win32.whl", hash = "sha256:bab7ec4bb501743edc63609320aaec8cd9188b396354f482f4de4d40a9d10721" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314-win_amd64.whl", hash = "sha256:3d4ba9a449e9364a936a27322b20d32d8b166553bfe63059bd21527e681e2fad" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314-win_arm64.whl", hash = "sha256:ce37f215223af94ef0f75ac68ea096f9f8e8c8ec7d6e8c346ee45c0d363f0479" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:f413ce6e07e0d0dc9c433228727b619871532674b45165abafe201f200cc215f" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:05791e528a18f7072bf5998ba772fe29db4da1234c45c2087866b5ba4dea710e" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cacb29f420cfeb9283b803263c3b9a068924474ff19ca126ba9103e1278dfa44" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:314c24e700d7027ae3ab0d95fbf8d53544fca1f20345fd30cd219b737c6e58d3" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:630d0bd7a293ad2fc8b4b94e5758c8b2536fdf36c05f1681270203e463cbfa9b" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e89641f5175d65e2dbb44db15fe4ea48fade5d5bbb9868fdc2b4fce22f4a469d" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c9f08ea03114a637dab06cedb2e914da9dc67fa52c6015c018ff43fdde25b9c2" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:ce9f3bde4e9b031eaf1eb61df95c1401427029ea1bfddb8621c1161dcb0fa02e" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:e4dc07e95495923d6fd4d6c27bf70769425b71c89053083843fd78f378558996" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:424538266794db2861db4922b05d729ade0940ee69dcf0591ce8f69784db0e11" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314t-win32.whl", hash = "sha256:4c1eeb3fb8eb9e0190bebafd0462936f75717687117339f708f395fe455acc73" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b56efee146c98dbf2cf5cffc61b9829d1e94442df4d7398b26892a53992d3547" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-cp314-cp314t-win_arm64.whl", hash = "sha256:b5c2705afa83f49bd91962a4094b6b082f94aef7626365ab3f8f4bd159c5acf3" }, + { url = "http://10.0.0.2:5001/index/coverage/coverage-7.11.0-py3-none-any.whl", hash = "sha256:4b7589765348d78fb4e5fb6ea35d07564e387da2fc5efff62e0222971f155f68" }, +] + +[[package]] +name = "debugpy" +version = "1.8.17" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/debugpy/debugpy-1.8.17.tar.gz", hash = "sha256:fd723b47a8c08892b1a16b2c6239a8b96637c62a59b94bb5dab4bac592a58a8e" } +wheels = [ + { url = "http://10.0.0.2:5001/index/debugpy/debugpy-1.8.17-cp312-cp312-macosx_15_0_universal2.whl", hash = "sha256:f14467edef672195c6f6b8e27ce5005313cb5d03c9239059bc7182b60c176e2d" }, + { url = "http://10.0.0.2:5001/index/debugpy/debugpy-1.8.17-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:24693179ef9dfa20dca8605905a42b392be56d410c333af82f1c5dff807a64cc" }, + { url = "http://10.0.0.2:5001/index/debugpy/debugpy-1.8.17-cp312-cp312-win32.whl", hash = "sha256:6a4e9dacf2cbb60d2514ff7b04b4534b0139facbf2abdffe0639ddb6088e59cf" }, + { url = "http://10.0.0.2:5001/index/debugpy/debugpy-1.8.17-cp312-cp312-win_amd64.whl", hash = "sha256:e8f8f61c518952fb15f74a302e068b48d9c4691768ade433e4adeea961993464" }, + { url = "http://10.0.0.2:5001/index/debugpy/debugpy-1.8.17-cp313-cp313-macosx_15_0_universal2.whl", hash = "sha256:857c1dd5d70042502aef1c6d1c2801211f3ea7e56f75e9c335f434afb403e464" }, + { url = "http://10.0.0.2:5001/index/debugpy/debugpy-1.8.17-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:3bea3b0b12f3946e098cce9b43c3c46e317b567f79570c3f43f0b96d00788088" }, + { url = "http://10.0.0.2:5001/index/debugpy/debugpy-1.8.17-cp313-cp313-win32.whl", hash = "sha256:e34ee844c2f17b18556b5bbe59e1e2ff4e86a00282d2a46edab73fd7f18f4a83" }, + { url = "http://10.0.0.2:5001/index/debugpy/debugpy-1.8.17-cp313-cp313-win_amd64.whl", hash = "sha256:6c5cd6f009ad4fca8e33e5238210dc1e5f42db07d4b6ab21ac7ffa904a196420" }, + { url = "http://10.0.0.2:5001/index/debugpy/debugpy-1.8.17-cp314-cp314-macosx_15_0_universal2.whl", hash = "sha256:045290c010bcd2d82bc97aa2daf6837443cd52f6328592698809b4549babcee1" }, + { url = "http://10.0.0.2:5001/index/debugpy/debugpy-1.8.17-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:b69b6bd9dba6a03632534cdf67c760625760a215ae289f7489a452af1031fe1f" }, + { url = "http://10.0.0.2:5001/index/debugpy/debugpy-1.8.17-cp314-cp314-win32.whl", hash = "sha256:5c59b74aa5630f3a5194467100c3b3d1c77898f9ab27e3f7dc5d40fc2f122670" }, + { url = "http://10.0.0.2:5001/index/debugpy/debugpy-1.8.17-cp314-cp314-win_amd64.whl", hash = "sha256:893cba7bb0f55161de4365584b025f7064e1f88913551bcd23be3260b231429c" }, + { url = "http://10.0.0.2:5001/index/debugpy/debugpy-1.8.17-py2.py3-none-any.whl", hash = "sha256:60c7dca6571efe660ccb7a9508d73ca14b8796c4ed484c2002abba714226cfef" }, +] + +[[package]] +name = "decorator" +version = "5.2.1" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/decorator/decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360" } +wheels = [ + { url = "http://10.0.0.2:5001/index/decorator/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a" }, +] + +[[package]] +name = "distlib" +version = "0.4.0" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/distlib/distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d" } +wheels = [ + { url = "http://10.0.0.2:5001/index/distlib/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16" }, +] + +[[package]] +name = "elprisenligenu" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "pydantic" }, + { name = "requests" }, +] + +[package.dev-dependencies] +dev = [ + { name = "ipykernel" }, + { name = "mypy" }, + { name = "pre-commit" }, + { name = "pytest" }, + { name = "pytest-cov" }, + { name = "python-dotenv" }, + { name = "pyupgrade" }, + { name = "ruff" }, + { name = "types-requests" }, +] + +[package.metadata] +requires-dist = [ + { name = "pydantic", specifier = ">=2.12.3" }, + { name = "requests", specifier = ">=2.32.5" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "ipykernel", specifier = ">=7.1.0" }, + { name = "mypy", specifier = ">=1.18.2" }, + { name = "pre-commit", specifier = ">=4.3.0" }, + { name = "pytest", specifier = ">=8.4.2" }, + { name = "pytest-cov", specifier = ">=7.0.0" }, + { name = "python-dotenv", specifier = ">=1.2.1" }, + { name = "pyupgrade", specifier = ">=3.21.0" }, + { name = "ruff", specifier = ">=0.14.2" }, + { name = "types-requests", specifier = ">=2.32.4.20250913" }, +] + +[[package]] +name = "executing" +version = "2.2.1" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/executing/executing-2.2.1.tar.gz", hash = "sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4" } +wheels = [ + { url = "http://10.0.0.2:5001/index/executing/executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017" }, +] + +[[package]] +name = "filelock" +version = "3.20.0" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/filelock/filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4" } +wheels = [ + { url = "http://10.0.0.2:5001/index/filelock/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2" }, +] + +[[package]] +name = "identify" +version = "2.6.15" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/identify/identify-2.6.15.tar.gz", hash = "sha256:e4f4864b96c6557ef2a1e1c951771838f4edc9df3a72ec7118b338801b11c7bf" } +wheels = [ + { url = "http://10.0.0.2:5001/index/identify/identify-2.6.15-py2.py3-none-any.whl", hash = "sha256:1181ef7608e00704db228516541eb83a88a9f94433a8c80bb9b5bd54b1d81757" }, +] + +[[package]] +name = "idna" +version = "3.11" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/idna/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902" } +wheels = [ + { url = "http://10.0.0.2:5001/index/idna/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/iniconfig/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730" } +wheels = [ + { url = "http://10.0.0.2:5001/index/iniconfig/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12" }, +] + +[[package]] +name = "ipykernel" +version = "7.1.0" +source = { registry = "http://10.0.0.2:5001/index/" } +dependencies = [ + { name = "appnope", marker = "sys_platform == 'darwin'" }, + { name = "comm" }, + { name = "debugpy" }, + { name = "ipython" }, + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "matplotlib-inline" }, + { name = "nest-asyncio" }, + { name = "packaging" }, + { name = "psutil" }, + { name = "pyzmq" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "http://10.0.0.2:5001/index/ipykernel/ipykernel-7.1.0.tar.gz", hash = "sha256:58a3fc88533d5930c3546dc7eac66c6d288acde4f801e2001e65edc5dc9cf0db" } +wheels = [ + { url = "http://10.0.0.2:5001/index/ipykernel/ipykernel-7.1.0-py3-none-any.whl", hash = "sha256:763b5ec6c5b7776f6a8d7ce09b267693b4e5ce75cb50ae696aaefb3c85e1ea4c" }, +] + +[[package]] +name = "ipython" +version = "9.6.0" +source = { registry = "http://10.0.0.2:5001/index/" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "decorator" }, + { name = "ipython-pygments-lexers" }, + { name = "jedi" }, + { name = "matplotlib-inline" }, + { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, + { name = "prompt-toolkit" }, + { name = "pygments" }, + { name = "stack-data" }, + { name = "traitlets" }, +] +sdist = { url = "http://10.0.0.2:5001/index/ipython/ipython-9.6.0.tar.gz", hash = "sha256:5603d6d5d356378be5043e69441a072b50a5b33b4503428c77b04cb8ce7bc731" } +wheels = [ + { url = "http://10.0.0.2:5001/index/ipython/ipython-9.6.0-py3-none-any.whl", hash = "sha256:5f77efafc886d2f023442479b8149e7d86547ad0a979e9da9f045d252f648196" }, +] + +[[package]] +name = "ipython-pygments-lexers" +version = "1.1.1" +source = { registry = "http://10.0.0.2:5001/index/" } +dependencies = [ + { name = "pygments" }, +] +sdist = { url = "http://10.0.0.2:5001/index/ipython-pygments-lexers/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81" } +wheels = [ + { url = "http://10.0.0.2:5001/index/ipython-pygments-lexers/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c" }, +] + +[[package]] +name = "jedi" +version = "0.19.2" +source = { registry = "http://10.0.0.2:5001/index/" } +dependencies = [ + { name = "parso" }, +] +sdist = { url = "http://10.0.0.2:5001/index/jedi/jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0" } +wheels = [ + { url = "http://10.0.0.2:5001/index/jedi/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9" }, +] + +[[package]] +name = "jupyter-client" +version = "8.6.3" +source = { registry = "http://10.0.0.2:5001/index/" } +dependencies = [ + { name = "jupyter-core" }, + { name = "python-dateutil" }, + { name = "pyzmq" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "http://10.0.0.2:5001/index/jupyter-client/jupyter_client-8.6.3.tar.gz", hash = "sha256:35b3a0947c4a6e9d589eb97d7d4cd5e90f910ee73101611f01283732bd6d9419" } +wheels = [ + { url = "http://10.0.0.2:5001/index/jupyter-client/jupyter_client-8.6.3-py3-none-any.whl", hash = "sha256:e8a19cc986cc45905ac3362915f410f3af85424b4c0905e94fa5f2cb08e8f23f" }, +] + +[[package]] +name = "jupyter-core" +version = "5.9.1" +source = { registry = "http://10.0.0.2:5001/index/" } +dependencies = [ + { name = "platformdirs" }, + { name = "traitlets" }, +] +sdist = { url = "http://10.0.0.2:5001/index/jupyter-core/jupyter_core-5.9.1.tar.gz", hash = "sha256:4d09aaff303b9566c3ce657f580bd089ff5c91f5f89cf7d8846c3cdf465b5508" } +wheels = [ + { url = "http://10.0.0.2:5001/index/jupyter-core/jupyter_core-5.9.1-py3-none-any.whl", hash = "sha256:ebf87fdc6073d142e114c72c9e29a9d7ca03fad818c5d300ce2adc1fb0743407" }, +] + +[[package]] +name = "matplotlib-inline" +version = "0.2.1" +source = { registry = "http://10.0.0.2:5001/index/" } +dependencies = [ + { name = "traitlets" }, +] +sdist = { url = "http://10.0.0.2:5001/index/matplotlib-inline/matplotlib_inline-0.2.1.tar.gz", hash = "sha256:e1ee949c340d771fc39e241ea75683deb94762c8fa5f2927ec57c83c4dffa9fe" } +wheels = [ + { url = "http://10.0.0.2:5001/index/matplotlib-inline/matplotlib_inline-0.2.1-py3-none-any.whl", hash = "sha256:d56ce5156ba6085e00a9d54fead6ed29a9c47e215cd1bba2e976ef39f5710a76" }, +] + +[[package]] +name = "mypy" +version = "1.18.2" +source = { registry = "http://10.0.0.2:5001/index/" } +dependencies = [ + { name = "mypy-extensions" }, + { name = "pathspec" }, + { name = "typing-extensions" }, +] +sdist = { url = "http://10.0.0.2:5001/index/mypy/mypy-1.18.2.tar.gz", hash = "sha256:06a398102a5f203d7477b2923dda3634c36727fa5c237d8f859ef90c42a9924b" } +wheels = [ + { url = "http://10.0.0.2:5001/index/mypy/mypy-1.18.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:33eca32dd124b29400c31d7cf784e795b050ace0e1f91b8dc035672725617e34" }, + { url = "http://10.0.0.2:5001/index/mypy/mypy-1.18.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a3c47adf30d65e89b2dcd2fa32f3aeb5e94ca970d2c15fcb25e297871c8e4764" }, + { url = "http://10.0.0.2:5001/index/mypy/mypy-1.18.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d6c838e831a062f5f29d11c9057c6009f60cb294fea33a98422688181fe2893" }, + { url = "http://10.0.0.2:5001/index/mypy/mypy-1.18.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01199871b6110a2ce984bde85acd481232d17413868c9807e95c1b0739a58914" }, + { url = "http://10.0.0.2:5001/index/mypy/mypy-1.18.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a2afc0fa0b0e91b4599ddfe0f91e2c26c2b5a5ab263737e998d6817874c5f7c8" }, + { url = "http://10.0.0.2:5001/index/mypy/mypy-1.18.2-cp312-cp312-win_amd64.whl", hash = "sha256:d8068d0afe682c7c4897c0f7ce84ea77f6de953262b12d07038f4d296d547074" }, + { url = "http://10.0.0.2:5001/index/mypy/mypy-1.18.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:07b8b0f580ca6d289e69209ec9d3911b4a26e5abfde32228a288eb79df129fcc" }, + { url = "http://10.0.0.2:5001/index/mypy/mypy-1.18.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ed4482847168439651d3feee5833ccedbf6657e964572706a2adb1f7fa4dfe2e" }, + { url = "http://10.0.0.2:5001/index/mypy/mypy-1.18.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3ad2afadd1e9fea5cf99a45a822346971ede8685cc581ed9cd4d42eaf940986" }, + { url = "http://10.0.0.2:5001/index/mypy/mypy-1.18.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a431a6f1ef14cf8c144c6b14793a23ec4eae3db28277c358136e79d7d062f62d" }, + { url = "http://10.0.0.2:5001/index/mypy/mypy-1.18.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7ab28cc197f1dd77a67e1c6f35cd1f8e8b73ed2217e4fc005f9e6a504e46e7ba" }, + { url = "http://10.0.0.2:5001/index/mypy/mypy-1.18.2-cp313-cp313-win_amd64.whl", hash = "sha256:0e2785a84b34a72ba55fb5daf079a1003a34c05b22238da94fcae2bbe46f3544" }, + { url = "http://10.0.0.2:5001/index/mypy/mypy-1.18.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:62f0e1e988ad41c2a110edde6c398383a889d95b36b3e60bcf155f5164c4fdce" }, + { url = "http://10.0.0.2:5001/index/mypy/mypy-1.18.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8795a039bab805ff0c1dfdb8cd3344642c2b99b8e439d057aba30850b8d3423d" }, + { url = "http://10.0.0.2:5001/index/mypy/mypy-1.18.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6ca1e64b24a700ab5ce10133f7ccd956a04715463d30498e64ea8715236f9c9c" }, + { url = "http://10.0.0.2:5001/index/mypy/mypy-1.18.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d924eef3795cc89fecf6bedc6ed32b33ac13e8321344f6ddbf8ee89f706c05cb" }, + { url = "http://10.0.0.2:5001/index/mypy/mypy-1.18.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:20c02215a080e3a2be3aa50506c67242df1c151eaba0dcbc1e4e557922a26075" }, + { url = "http://10.0.0.2:5001/index/mypy/mypy-1.18.2-cp314-cp314-win_amd64.whl", hash = "sha256:749b5f83198f1ca64345603118a6f01a4e99ad4bf9d103ddc5a3200cc4614adf" }, + { url = "http://10.0.0.2:5001/index/mypy/mypy-1.18.2-py3-none-any.whl", hash = "sha256:22a1748707dd62b58d2ae53562ffc4d7f8bcc727e8ac7cbc69c053ddc874d47e" }, +] + +[[package]] +name = "mypy-extensions" +version = "1.1.0" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/mypy-extensions/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558" } +wheels = [ + { url = "http://10.0.0.2:5001/index/mypy-extensions/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505" }, +] + +[[package]] +name = "nest-asyncio" +version = "1.6.0" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/nest-asyncio/nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe" } +wheels = [ + { url = "http://10.0.0.2:5001/index/nest-asyncio/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c" }, +] + +[[package]] +name = "nodeenv" +version = "1.9.1" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/nodeenv/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f" } +wheels = [ + { url = "http://10.0.0.2:5001/index/nodeenv/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9" }, +] + +[[package]] +name = "packaging" +version = "25.0" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/packaging/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f" } +wheels = [ + { url = "http://10.0.0.2:5001/index/packaging/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484" }, +] + +[[package]] +name = "parso" +version = "0.8.5" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/parso/parso-0.8.5.tar.gz", hash = "sha256:034d7354a9a018bdce352f48b2a8a450f05e9d6ee85db84764e9b6bd96dafe5a" } +wheels = [ + { url = "http://10.0.0.2:5001/index/parso/parso-0.8.5-py2.py3-none-any.whl", hash = "sha256:646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887" }, +] + +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/pathspec/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712" } +wheels = [ + { url = "http://10.0.0.2:5001/index/pathspec/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08" }, +] + +[[package]] +name = "pexpect" +version = "4.9.0" +source = { registry = "http://10.0.0.2:5001/index/" } +dependencies = [ + { name = "ptyprocess" }, +] +sdist = { url = "http://10.0.0.2:5001/index/pexpect/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f" } +wheels = [ + { url = "http://10.0.0.2:5001/index/pexpect/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523" }, +] + +[[package]] +name = "platformdirs" +version = "4.5.0" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/platformdirs/platformdirs-4.5.0.tar.gz", hash = "sha256:70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312" } +wheels = [ + { url = "http://10.0.0.2:5001/index/platformdirs/platformdirs-4.5.0-py3-none-any.whl", hash = "sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/pluggy/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3" } +wheels = [ + { url = "http://10.0.0.2:5001/index/pluggy/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746" }, +] + +[[package]] +name = "pre-commit" +version = "4.3.0" +source = { registry = "http://10.0.0.2:5001/index/" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "http://10.0.0.2:5001/index/pre-commit/pre_commit-4.3.0.tar.gz", hash = "sha256:499fe450cc9d42e9d58e606262795ecb64dd05438943c62b66f6a8673da30b16" } +wheels = [ + { url = "http://10.0.0.2:5001/index/pre-commit/pre_commit-4.3.0-py2.py3-none-any.whl", hash = "sha256:2b0747ad7e6e967169136edffee14c16e148a778a54e4f967921aa1ebf2308d8" }, +] + +[[package]] +name = "prompt-toolkit" +version = "3.0.52" +source = { registry = "http://10.0.0.2:5001/index/" } +dependencies = [ + { name = "wcwidth" }, +] +sdist = { url = "http://10.0.0.2:5001/index/prompt-toolkit/prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855" } +wheels = [ + { url = "http://10.0.0.2:5001/index/prompt-toolkit/prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955" }, +] + +[[package]] +name = "psutil" +version = "7.1.2" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/psutil/psutil-7.1.2.tar.gz", hash = "sha256:aa225cdde1335ff9684708ee8c72650f6598d5ed2114b9a7c5802030b1785018" } +wheels = [ + { url = "http://10.0.0.2:5001/index/psutil/psutil-7.1.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0cc5c6889b9871f231ed5455a9a02149e388fffcb30b607fb7a8896a6d95f22e" }, + { url = "http://10.0.0.2:5001/index/psutil/psutil-7.1.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8e9e77a977208d84aa363a4a12e0f72189d58bbf4e46b49aae29a2c6e93ef206" }, + { url = "http://10.0.0.2:5001/index/psutil/psutil-7.1.2-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7d9623a5e4164d2220ecceb071f4b333b3c78866141e8887c072129185f41278" }, + { url = "http://10.0.0.2:5001/index/psutil/psutil-7.1.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:364b1c10fe4ed59c89ec49e5f1a70da353b27986fa8233b4b999df4742a5ee2f" }, + { url = "http://10.0.0.2:5001/index/psutil/psutil-7.1.2-cp313-cp313t-win_amd64.whl", hash = "sha256:f101ef84de7e05d41310e3ccbdd65a6dd1d9eed85e8aaf0758405d022308e204" }, + { url = "http://10.0.0.2:5001/index/psutil/psutil-7.1.2-cp313-cp313t-win_arm64.whl", hash = "sha256:20c00824048a95de67f00afedc7b08b282aa08638585b0206a9fb51f28f1a165" }, + { url = "http://10.0.0.2:5001/index/psutil/psutil-7.1.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:e09cfe92aa8e22b1ec5e2d394820cf86c5dff6367ac3242366485dfa874d43bc" }, + { url = "http://10.0.0.2:5001/index/psutil/psutil-7.1.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:fa6342cf859c48b19df3e4aa170e4cfb64aadc50b11e06bb569c6c777b089c9e" }, + { url = "http://10.0.0.2:5001/index/psutil/psutil-7.1.2-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:625977443498ee7d6c1e63e93bacca893fd759a66c5f635d05e05811d23fb5ee" }, + { url = "http://10.0.0.2:5001/index/psutil/psutil-7.1.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a24bcd7b7f2918d934af0fb91859f621b873d6aa81267575e3655cd387572a7" }, + { url = "http://10.0.0.2:5001/index/psutil/psutil-7.1.2-cp314-cp314t-win_amd64.whl", hash = "sha256:329f05610da6380982e6078b9d0881d9ab1e9a7eb7c02d833bfb7340aa634e31" }, + { url = "http://10.0.0.2:5001/index/psutil/psutil-7.1.2-cp314-cp314t-win_arm64.whl", hash = "sha256:7b04c29e3c0c888e83ed4762b70f31e65c42673ea956cefa8ced0e31e185f582" }, + { url = "http://10.0.0.2:5001/index/psutil/psutil-7.1.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c9ba5c19f2d46203ee8c152c7b01df6eec87d883cfd8ee1af2ef2727f6b0f814" }, + { url = "http://10.0.0.2:5001/index/psutil/psutil-7.1.2-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:2a486030d2fe81bec023f703d3d155f4823a10a47c36784c84f1cc7f8d39bedb" }, + { url = "http://10.0.0.2:5001/index/psutil/psutil-7.1.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3efd8fc791492e7808a51cb2b94889db7578bfaea22df931424f874468e389e3" }, + { url = "http://10.0.0.2:5001/index/psutil/psutil-7.1.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e2aeb9b64f481b8eabfc633bd39e0016d4d8bbcd590d984af764d80bf0851b8a" }, + { url = "http://10.0.0.2:5001/index/psutil/psutil-7.1.2-cp37-abi3-win_amd64.whl", hash = "sha256:8e17852114c4e7996fe9da4745c2bdef001ebbf2f260dec406290e66628bdb91" }, + { url = "http://10.0.0.2:5001/index/psutil/psutil-7.1.2-cp37-abi3-win_arm64.whl", hash = "sha256:3e988455e61c240cc879cb62a008c2699231bf3e3d061d7fce4234463fd2abb4" }, +] + +[[package]] +name = "ptyprocess" +version = "0.7.0" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/ptyprocess/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220" } +wheels = [ + { url = "http://10.0.0.2:5001/index/ptyprocess/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35" }, +] + +[[package]] +name = "pure-eval" +version = "0.2.3" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/pure-eval/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42" } +wheels = [ + { url = "http://10.0.0.2:5001/index/pure-eval/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0" }, +] + +[[package]] +name = "pycparser" +version = "2.23" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/pycparser/pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2" } +wheels = [ + { url = "http://10.0.0.2:5001/index/pycparser/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934" }, +] + +[[package]] +name = "pydantic" +version = "2.12.3" +source = { registry = "http://10.0.0.2:5001/index/" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "http://10.0.0.2:5001/index/pydantic/pydantic-2.12.3.tar.gz", hash = "sha256:1da1c82b0fc140bb0103bc1441ffe062154c8d38491189751ee00fd8ca65ce74" } +wheels = [ + { url = "http://10.0.0.2:5001/index/pydantic/pydantic-2.12.3-py3-none-any.whl", hash = "sha256:6986454a854bc3bc6e5443e1369e06a3a456af9d339eda45510f517d9ea5c6bf" }, +] + +[[package]] +name = "pydantic-core" +version = "2.41.4" +source = { registry = "http://10.0.0.2:5001/index/" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4.tar.gz", hash = "sha256:70e47929a9d4a1905a67e4b687d5946026390568a8e952b92824118063cee4d5" } +wheels = [ + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ab06d77e053d660a6faaf04894446df7b0a7e7aba70c2797465a0a1af00fc887" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c53ff33e603a9c1179a9364b0a24694f183717b2e0da2b5ad43c316c956901b2" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:304c54176af2c143bd181d82e77c15c41cbacea8872a2225dd37e6544dce9999" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:025ba34a4cf4fb32f917d5d188ab5e702223d3ba603be4d8aca2f82bede432a4" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b9f5f30c402ed58f90c70e12eff65547d3ab74685ffe8283c719e6bead8ef53f" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd96e5d15385d301733113bcaa324c8bcf111275b7675a9c6e88bfb19fc05e3b" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98f348cbb44fae6e9653c1055db7e29de67ea6a9ca03a5fa2c2e11a47cff0e47" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec22626a2d14620a83ca583c6f5a4080fa3155282718b6055c2ea48d3ef35970" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3a95d4590b1f1a43bf33ca6d647b990a88f4a3824a8c4572c708f0b45a5290ed" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:f9672ab4d398e1b602feadcffcdd3af44d5f5e6ddc15bc7d15d376d47e8e19f8" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:84d8854db5f55fead3b579f04bda9a36461dab0730c5d570e1526483e7bb8431" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp312-cp312-win32.whl", hash = "sha256:9be1c01adb2ecc4e464392c36d17f97e9110fbbc906bcbe1c943b5b87a74aabd" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp312-cp312-win_amd64.whl", hash = "sha256:d682cf1d22bab22a5be08539dca3d1593488a99998f9f412137bc323179067ff" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp312-cp312-win_arm64.whl", hash = "sha256:833eebfd75a26d17470b58768c1834dfc90141b7afc6eb0429c21fc5a21dcfb8" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:85e050ad9e5f6fe1004eec65c914332e52f429bc0ae12d6fa2092407a462c746" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e7393f1d64792763a48924ba31d1e44c2cfbc05e3b1c2c9abb4ceeadd912cced" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94dab0940b0d1fb28bcab847adf887c66a27a40291eedf0b473be58761c9799a" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:de7c42f897e689ee6f9e93c4bec72b99ae3b32a2ade1c7e4798e690ff5246e02" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:664b3199193262277b8b3cd1e754fb07f2c6023289c815a1e1e8fb415cb247b1" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d95b253b88f7d308b1c0b417c4624f44553ba4762816f94e6986819b9c273fb2" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1351f5bbdbbabc689727cb91649a00cb9ee7203e0a6e54e9f5ba9e22e384b84" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1affa4798520b148d7182da0615d648e752de4ab1a9566b7471bc803d88a062d" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7b74e18052fea4aa8dea2fb7dbc23d15439695da6cbe6cfc1b694af1115df09d" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:285b643d75c0e30abda9dc1077395624f314a37e3c09ca402d4015ef5979f1a2" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:f52679ff4218d713b3b33f88c89ccbf3a5c2c12ba665fb80ccc4192b4608dbab" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp313-cp313-win32.whl", hash = "sha256:ecde6dedd6fff127c273c76821bb754d793be1024bc33314a120f83a3c69460c" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp313-cp313-win_amd64.whl", hash = "sha256:d081a1f3800f05409ed868ebb2d74ac39dd0c1ff6c035b5162356d76030736d4" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp313-cp313-win_arm64.whl", hash = "sha256:f8e49c9c364a7edcbe2a310f12733aad95b022495ef2a8d653f645e5d20c1564" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ed97fd56a561f5eb5706cebe94f1ad7c13b84d98312a05546f2ad036bafe87f4" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a870c307bf1ee91fc58a9a61338ff780d01bfae45922624816878dce784095d2" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d25e97bc1f5f8f7985bdc2335ef9e73843bb561eb1fa6831fdfc295c1c2061cf" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp313-cp313t-win_amd64.whl", hash = "sha256:d405d14bea042f166512add3091c1af40437c2e7f86988f3915fabd27b1e9cd2" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp313-cp313t-win_arm64.whl", hash = "sha256:19f3684868309db5263a11bace3c45d93f6f24afa2ffe75a647583df22a2ff89" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:e9205d97ed08a82ebb9a307e92914bb30e18cdf6f6b12ca4bedadb1588a0bfe1" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:82df1f432b37d832709fbcc0e24394bba04a01b6ecf1ee87578145c19cde12ac" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc3b4cc4539e055cfa39a3763c939f9d409eb40e85813257dcd761985a108554" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b1eb1754fce47c63d2ff57fdb88c351a6c0150995890088b33767a10218eaa4e" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e6ab5ab30ef325b443f379ddb575a34969c333004fca5a1daa0133a6ffaad616" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:31a41030b1d9ca497634092b46481b937ff9397a86f9f51bd41c4767b6fc04af" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a44ac1738591472c3d020f61c6df1e4015180d6262ebd39bf2aeb52571b60f12" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d72f2b5e6e82ab8f94ea7d0d42f83c487dc159c5240d8f83beae684472864e2d" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:c4d1e854aaf044487d31143f541f7aafe7b482ae72a022c664b2de2e466ed0ad" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b568af94267729d76e6ee5ececda4e283d07bbb28e8148bb17adad93d025d25a" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:6d55fb8b1e8929b341cc313a81a26e0d48aa3b519c1dbaadec3a6a2b4fcad025" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp314-cp314-win32.whl", hash = "sha256:5b66584e549e2e32a1398df11da2e0a7eff45d5c2d9db9d5667c5e6ac764d77e" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp314-cp314-win_amd64.whl", hash = "sha256:557a0aab88664cc552285316809cab897716a372afaf8efdbef756f8b890e894" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp314-cp314-win_arm64.whl", hash = "sha256:3f1ea6f48a045745d0d9f325989d8abd3f1eaf47dd00485912d1a3a63c623a8d" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6c1fe4c5404c448b13188dd8bd2ebc2bdd7e6727fa61ff481bcc2cca894018da" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:523e7da4d43b113bf8e7b49fa4ec0c35bf4fe66b2230bfc5c13cc498f12c6c3e" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5729225de81fb65b70fdb1907fcf08c75d498f4a6f15af005aabb1fdadc19dfa" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp314-cp314t-win_amd64.whl", hash = "sha256:de2cfbb09e88f0f795fd90cf955858fc2c691df65b1f21f0aa00b99f3fbc661d" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-cp314-cp314t-win_arm64.whl", hash = "sha256:d34f950ae05a83e0ede899c595f312ca976023ea1db100cd5aa188f7005e3ab0" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:4f5d640aeebb438517150fdeec097739614421900e4a08db4a3ef38898798537" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:4a9ab037b71927babc6d9e7fc01aea9e66dc2a4a34dff06ef0724a4049629f94" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4dab9484ec605c3016df9ad4fd4f9a390bc5d816a3b10c6550f8424bb80b18c" }, + { url = "http://10.0.0.2:5001/index/pydantic-core/pydantic_core-2.41.4-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8a5028425820731d8c6c098ab642d7b8b999758e24acae03ed38a66eca8335" }, +] + +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/pygments/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887" } +wheels = [ + { url = "http://10.0.0.2:5001/index/pygments/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b" }, +] + +[[package]] +name = "pytest" +version = "8.4.2" +source = { registry = "http://10.0.0.2:5001/index/" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, +] +sdist = { url = "http://10.0.0.2:5001/index/pytest/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01" } +wheels = [ + { url = "http://10.0.0.2:5001/index/pytest/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79" }, +] + +[[package]] +name = "pytest-cov" +version = "7.0.0" +source = { registry = "http://10.0.0.2:5001/index/" } +dependencies = [ + { name = "coverage" }, + { name = "pluggy" }, + { name = "pytest" }, +] +sdist = { url = "http://10.0.0.2:5001/index/pytest-cov/pytest_cov-7.0.0.tar.gz", hash = "sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1" } +wheels = [ + { url = "http://10.0.0.2:5001/index/pytest-cov/pytest_cov-7.0.0-py3-none-any.whl", hash = "sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861" }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "http://10.0.0.2:5001/index/" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "http://10.0.0.2:5001/index/python-dateutil/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3" } +wheels = [ + { url = "http://10.0.0.2:5001/index/python-dateutil/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" }, +] + +[[package]] +name = "python-dotenv" +version = "1.2.1" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/python-dotenv/python_dotenv-1.2.1.tar.gz", hash = "sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6" } +wheels = [ + { url = "http://10.0.0.2:5001/index/python-dotenv/python_dotenv-1.2.1-py3-none-any.whl", hash = "sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61" }, +] + +[[package]] +name = "pyupgrade" +version = "3.21.0" +source = { registry = "http://10.0.0.2:5001/index/" } +dependencies = [ + { name = "tokenize-rt" }, +] +sdist = { url = "http://10.0.0.2:5001/index/pyupgrade/pyupgrade-3.21.0.tar.gz", hash = "sha256:3e63a882ec1d16f5621736d938952df3cdc2446501fb049e711415cb8d273960" } +wheels = [ + { url = "http://10.0.0.2:5001/index/pyupgrade/pyupgrade-3.21.0-py2.py3-none-any.whl", hash = "sha256:3a200cdc537980f371b4867f1d662e37166a7869d7713f309c1c3241c310c754" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f" } +wheels = [ + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9" }, + { url = "http://10.0.0.2:5001/index/pyyaml/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b" }, +] + +[[package]] +name = "pyzmq" +version = "27.1.0" +source = { registry = "http://10.0.0.2:5001/index/" } +dependencies = [ + { name = "cffi", marker = "implementation_name == 'pypy'" }, +] +sdist = { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0.tar.gz", hash = "sha256:ac0765e3d44455adb6ddbf4417dcce460fc40a05978c08efdf2948072f6db540" } +wheels = [ + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:452631b640340c928fa343801b0d07eb0c3789a5ffa843f6e1a9cee0ba4eb4fc" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1c179799b118e554b66da67d88ed66cd37a169f1f23b5d9f0a231b4e8d44a113" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3837439b7f99e60312f0c926a6ad437b067356dc2bc2ec96eb395fd0fe804233" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43ad9a73e3da1fab5b0e7e13402f0b2fb934ae1c876c51d0afff0e7c052eca31" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0de3028d69d4cdc475bfe47a6128eb38d8bc0e8f4d69646adfbcd840facbac28" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:cf44a7763aea9298c0aa7dbf859f87ed7012de8bda0f3977b6fb1d96745df856" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f30f395a9e6fbca195400ce833c731e7b64c3919aa481af4d88c3759e0cb7496" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp312-abi3-win32.whl", hash = "sha256:250e5436a4ba13885494412b3da5d518cd0d3a278a1ae640e113c073a5f88edd" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp312-abi3-win_amd64.whl", hash = "sha256:9ce490cf1d2ca2ad84733aa1d69ce6855372cb5ce9223802450c9b2a7cba0ccf" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp312-abi3-win_arm64.whl", hash = "sha256:75a2f36223f0d535a0c919e23615fc85a1e23b71f40c7eb43d7b1dedb4d8f15f" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:93ad4b0855a664229559e45c8d23797ceac03183c7b6f5b4428152a6b06684a5" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp313-cp313-android_24_x86_64.whl", hash = "sha256:fbb4f2400bfda24f12f009cba62ad5734148569ff4949b1b6ec3b519444342e6" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:e343d067f7b151cfe4eb3bb796a7752c9d369eed007b91231e817071d2c2fec7" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp313-cp313t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:08363b2011dec81c354d694bdecaef4770e0ae96b9afea70b3f47b973655cc05" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d54530c8c8b5b8ddb3318f481297441af102517602b569146185fa10b63f4fa9" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f3afa12c392f0a44a2414056d730eebc33ec0926aae92b5ad5cf26ebb6cc128" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c65047adafe573ff023b3187bb93faa583151627bc9c51fc4fb2c561ed689d39" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:90e6e9441c946a8b0a667356f7078d96411391a3b8f80980315455574177ec97" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:add071b2d25f84e8189aaf0882d39a285b42fa3853016ebab234a5e78c7a43db" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp313-cp313t-win32.whl", hash = "sha256:7ccc0700cfdf7bd487bea8d850ec38f204478681ea02a582a8da8171b7f90a1c" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:8085a9fba668216b9b4323be338ee5437a235fe275b9d1610e422ccc279733e2" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:6bb54ca21bcfe361e445256c15eedf083f153811c37be87e0514934d6913061e" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:ce980af330231615756acd5154f29813d553ea555485ae712c491cd483df6b7a" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1779be8c549e54a1c38f805e56d2a2e5c009d26de10921d7d51cfd1c8d4632ea" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7200bb0f03345515df50d99d3db206a0a6bee1955fbb8c453c76f5bf0e08fb96" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01c0e07d558b06a60773744ea6251f769cd79a41a97d11b8bf4ab8f034b0424d" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:80d834abee71f65253c91540445d37c4c561e293ba6e741b992f20a105d69146" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:544b4e3b7198dde4a62b8ff6685e9802a9a1ebf47e77478a5eb88eca2a82f2fd" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cedc4c68178e59a4046f97eca31b148ddcf51e88677de1ef4e78cf06c5376c9a" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp314-cp314t-win32.whl", hash = "sha256:1f0b2a577fd770aa6f053211a55d1c47901f4d537389a034c690291485e5fe92" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:19c9468ae0437f8074af379e986c5d3d7d7bfe033506af442e8c879732bedbe0" }, + { url = "http://10.0.0.2:5001/index/pyzmq/pyzmq-27.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dc5dbf68a7857b59473f7df42650c621d7e8923fb03fa74a526890f4d33cc4d7" }, +] + +[[package]] +name = "requests" +version = "2.32.5" +source = { registry = "http://10.0.0.2:5001/index/" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "http://10.0.0.2:5001/index/requests/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf" } +wheels = [ + { url = "http://10.0.0.2:5001/index/requests/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6" }, +] + +[[package]] +name = "ruff" +version = "0.14.2" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/ruff/ruff-0.14.2.tar.gz", hash = "sha256:98da787668f239313d9c902ca7c523fe11b8ec3f39345553a51b25abc4629c96" } +wheels = [ + { url = "http://10.0.0.2:5001/index/ruff/ruff-0.14.2-py3-none-linux_armv6l.whl", hash = "sha256:7cbe4e593505bdec5884c2d0a4d791a90301bc23e49a6b1eb642dd85ef9c64f1" }, + { url = "http://10.0.0.2:5001/index/ruff/ruff-0.14.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:8d54b561729cee92f8d89c316ad7a3f9705533f5903b042399b6ae0ddfc62e11" }, + { url = "http://10.0.0.2:5001/index/ruff/ruff-0.14.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:5c8753dfa44ebb2cde10ce5b4d2ef55a41fb9d9b16732a2c5df64620dbda44a3" }, + { url = "http://10.0.0.2:5001/index/ruff/ruff-0.14.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d0bbeffb8d9f4fccf7b5198d566d0bad99a9cb622f1fc3467af96cb8773c9e3" }, + { url = "http://10.0.0.2:5001/index/ruff/ruff-0.14.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7047f0c5a713a401e43a88d36843d9c83a19c584e63d664474675620aaa634a8" }, + { url = "http://10.0.0.2:5001/index/ruff/ruff-0.14.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bf8d2f9aa1602599217d82e8e0af7fd33e5878c4d98f37906b7c93f46f9a839" }, + { url = "http://10.0.0.2:5001/index/ruff/ruff-0.14.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:1c505b389e19c57a317cf4b42db824e2fca96ffb3d86766c1c9f8b96d32048a7" }, + { url = "http://10.0.0.2:5001/index/ruff/ruff-0.14.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a307fc45ebd887b3f26b36d9326bb70bf69b01561950cdcc6c0bdf7bb8e0f7cc" }, + { url = "http://10.0.0.2:5001/index/ruff/ruff-0.14.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:61ae91a32c853172f832c2f40bd05fd69f491db7289fb85a9b941ebdd549781a" }, + { url = "http://10.0.0.2:5001/index/ruff/ruff-0.14.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1967e40286f63ee23c615e8e7e98098dedc7301568bd88991f6e544d8ae096" }, + { url = "http://10.0.0.2:5001/index/ruff/ruff-0.14.2-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:2877f02119cdebf52a632d743a2e302dea422bfae152ebe2f193d3285a3a65df" }, + { url = "http://10.0.0.2:5001/index/ruff/ruff-0.14.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e681c5bc777de5af898decdcb6ba3321d0d466f4cb43c3e7cc2c3b4e7b843a05" }, + { url = "http://10.0.0.2:5001/index/ruff/ruff-0.14.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:e21be42d72e224736f0c992cdb9959a2fa53c7e943b97ef5d081e13170e3ffc5" }, + { url = "http://10.0.0.2:5001/index/ruff/ruff-0.14.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:b8264016f6f209fac16262882dbebf3f8be1629777cf0f37e7aff071b3e9b92e" }, + { url = "http://10.0.0.2:5001/index/ruff/ruff-0.14.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5ca36b4cb4db3067a3b24444463ceea5565ea78b95fe9a07ca7cb7fd16948770" }, + { url = "http://10.0.0.2:5001/index/ruff/ruff-0.14.2-py3-none-win32.whl", hash = "sha256:41775927d287685e08f48d8eb3f765625ab0b7042cc9377e20e64f4eb0056ee9" }, + { url = "http://10.0.0.2:5001/index/ruff/ruff-0.14.2-py3-none-win_amd64.whl", hash = "sha256:0df3424aa5c3c08b34ed8ce099df1021e3adaca6e90229273496b839e5a7e1af" }, + { url = "http://10.0.0.2:5001/index/ruff/ruff-0.14.2-py3-none-win_arm64.whl", hash = "sha256:ea9d635e83ba21569fbacda7e78afbfeb94911c9434aff06192d9bc23fd5495a" }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/six/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81" } +wheels = [ + { url = "http://10.0.0.2:5001/index/six/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274" }, +] + +[[package]] +name = "stack-data" +version = "0.6.3" +source = { registry = "http://10.0.0.2:5001/index/" } +dependencies = [ + { name = "asttokens" }, + { name = "executing" }, + { name = "pure-eval" }, +] +sdist = { url = "http://10.0.0.2:5001/index/stack-data/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9" } +wheels = [ + { url = "http://10.0.0.2:5001/index/stack-data/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695" }, +] + +[[package]] +name = "tokenize-rt" +version = "6.2.0" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/tokenize-rt/tokenize_rt-6.2.0.tar.gz", hash = "sha256:8439c042b330c553fdbe1758e4a05c0ed460dbbbb24a606f11f0dee75da4cad6" } +wheels = [ + { url = "http://10.0.0.2:5001/index/tokenize-rt/tokenize_rt-6.2.0-py2.py3-none-any.whl", hash = "sha256:a152bf4f249c847a66497a4a95f63376ed68ac6abf092a2f7cfb29d044ecff44" }, +] + +[[package]] +name = "tornado" +version = "6.5.2" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/tornado/tornado-6.5.2.tar.gz", hash = "sha256:ab53c8f9a0fa351e2c0741284e06c7a45da86afb544133201c5cc8578eb076a0" } +wheels = [ + { url = "http://10.0.0.2:5001/index/tornado/tornado-6.5.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:2436822940d37cde62771cff8774f4f00b3c8024fe482e16ca8387b8a2724db6" }, + { url = "http://10.0.0.2:5001/index/tornado/tornado-6.5.2-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:583a52c7aa94ee046854ba81d9ebb6c81ec0fd30386d96f7640c96dad45a03ef" }, + { url = "http://10.0.0.2:5001/index/tornado/tornado-6.5.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0fe179f28d597deab2842b86ed4060deec7388f1fd9c1b4a41adf8af058907e" }, + { url = "http://10.0.0.2:5001/index/tornado/tornado-6.5.2-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b186e85d1e3536d69583d2298423744740986018e393d0321df7340e71898882" }, + { url = "http://10.0.0.2:5001/index/tornado/tornado-6.5.2-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e792706668c87709709c18b353da1f7662317b563ff69f00bab83595940c7108" }, + { url = "http://10.0.0.2:5001/index/tornado/tornado-6.5.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:06ceb1300fd70cb20e43b1ad8aaee0266e69e7ced38fa910ad2e03285009ce7c" }, + { url = "http://10.0.0.2:5001/index/tornado/tornado-6.5.2-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:74db443e0f5251be86cbf37929f84d8c20c27a355dd452a5cfa2aada0d001ec4" }, + { url = "http://10.0.0.2:5001/index/tornado/tornado-6.5.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b5e735ab2889d7ed33b32a459cac490eda71a1ba6857b0118de476ab6c366c04" }, + { url = "http://10.0.0.2:5001/index/tornado/tornado-6.5.2-cp39-abi3-win32.whl", hash = "sha256:c6f29e94d9b37a95013bb669616352ddb82e3bfe8326fccee50583caebc8a5f0" }, + { url = "http://10.0.0.2:5001/index/tornado/tornado-6.5.2-cp39-abi3-win_amd64.whl", hash = "sha256:e56a5af51cc30dd2cae649429af65ca2f6571da29504a07995175df14c18f35f" }, + { url = "http://10.0.0.2:5001/index/tornado/tornado-6.5.2-cp39-abi3-win_arm64.whl", hash = "sha256:d6c33dc3672e3a1f3618eb63b7ef4683a7688e7b9e6e8f0d9aa5726360a004af" }, +] + +[[package]] +name = "traitlets" +version = "5.14.3" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/traitlets/traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7" } +wheels = [ + { url = "http://10.0.0.2:5001/index/traitlets/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f" }, +] + +[[package]] +name = "types-requests" +version = "2.32.4.20250913" +source = { registry = "http://10.0.0.2:5001/index/" } +dependencies = [ + { name = "urllib3" }, +] +sdist = { url = "http://10.0.0.2:5001/index/types-requests/types_requests-2.32.4.20250913.tar.gz", hash = "sha256:abd6d4f9ce3a9383f269775a9835a4c24e5cd6b9f647d64f88aa4613c33def5d" } +wheels = [ + { url = "http://10.0.0.2:5001/index/types-requests/types_requests-2.32.4.20250913-py3-none-any.whl", hash = "sha256:78c9c1fffebbe0fa487a418e0fa5252017e9c60d1a2da394077f1780f655d7e1" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/typing-extensions/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466" } +wheels = [ + { url = "http://10.0.0.2:5001/index/typing-extensions/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.2" +source = { registry = "http://10.0.0.2:5001/index/" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "http://10.0.0.2:5001/index/typing-inspection/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464" } +wheels = [ + { url = "http://10.0.0.2:5001/index/typing-inspection/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7" }, +] + +[[package]] +name = "urllib3" +version = "2.5.0" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/urllib3/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760" } +wheels = [ + { url = "http://10.0.0.2:5001/index/urllib3/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc" }, +] + +[[package]] +name = "virtualenv" +version = "20.35.3" +source = { registry = "http://10.0.0.2:5001/index/" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, +] +sdist = { url = "http://10.0.0.2:5001/index/virtualenv/virtualenv-20.35.3.tar.gz", hash = "sha256:4f1a845d131133bdff10590489610c98c168ff99dc75d6c96853801f7f67af44" } +wheels = [ + { url = "http://10.0.0.2:5001/index/virtualenv/virtualenv-20.35.3-py3-none-any.whl", hash = "sha256:63d106565078d8c8d0b206d48080f938a8b25361e19432d2c9db40d2899c810a" }, +] + +[[package]] +name = "wcwidth" +version = "0.2.14" +source = { registry = "http://10.0.0.2:5001/index/" } +sdist = { url = "http://10.0.0.2:5001/index/wcwidth/wcwidth-0.2.14.tar.gz", hash = "sha256:4d478375d31bc5395a3c55c40ccdf3354688364cd61c4f6adacaa9215d0b3605" } +wheels = [ + { url = "http://10.0.0.2:5001/index/wcwidth/wcwidth-0.2.14-py2.py3-none-any.whl", hash = "sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1" }, +]